@bigz-app/booking-widget 1.4.2 → 1.4.4

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.esm.js CHANGED
@@ -2045,6 +2045,28 @@ const StyleProvider = ({ config, children, }) => {
2045
2045
  c = `0x${c.join("")}`;
2046
2046
  return [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(",");
2047
2047
  };
2048
+ // Pick a readable text color (dark or light) for content sitting on top of
2049
+ // the given background color. Bright/neon highlights (teal, matrix green,
2050
+ // gold, etc.) need dark text — white text on them is unreadable.
2051
+ const getContrastingTextColor = (color, lightColor = "#ffffff", darkColor = "#0e1420") => {
2052
+ let rgb;
2053
+ if (color.startsWith("#")) {
2054
+ rgb = hexToRgb(color);
2055
+ }
2056
+ else if (color.startsWith("rgb")) {
2057
+ rgb = color.replace(/rgba?\(|\)/g, "").split(",").slice(0, 3).join(",");
2058
+ }
2059
+ else {
2060
+ return lightColor; // Can't parse (e.g. hsl/oklch/semantic) — keep existing default
2061
+ }
2062
+ const [r, g, b] = rgb.split(",").map((n) => parseInt(n, 10) / 255);
2063
+ if ([r, g, b].some((n) => Number.isNaN(n)))
2064
+ return lightColor;
2065
+ // Relative luminance (sRGB, WCAG)
2066
+ const toLinear = (n) => (n <= 0.03928 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4));
2067
+ const luminance = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
2068
+ return luminance > 0.45 ? darkColor : lightColor;
2069
+ };
2048
2070
  const colors = config.colors || {};
2049
2071
  const finalColors = {
2050
2072
  highlight: getCSSValue(colors.highlight, themeDefaults.highlight),
@@ -2064,7 +2086,7 @@ const StyleProvider = ({ config, children, }) => {
2064
2086
  "--bw-surface-color": finalColors.surface,
2065
2087
  "--bw-text-color": finalColors.text,
2066
2088
  "--bw-text-muted": addOpacity(finalColors.text, 0.7),
2067
- "--bw-button-text-color": themeDefaults.buttonTextColor || "#ffffff",
2089
+ "--bw-button-text-color": themeDefaults.buttonTextColor || getContrastingTextColor(finalColors.highlight),
2068
2090
  "--bw-border-color": finalColors.border,
2069
2091
  "--bw-success-color": finalColors.success,
2070
2092
  "--bw-warning-color": finalColors.warning,
@@ -2082,6 +2104,9 @@ const StyleProvider = ({ config, children, }) => {
2082
2104
  "--bw-highlight-muted": addOpacity(finalColors.highlight, 0.1),
2083
2105
  "--bw-highlight-subtle": addOpacity(finalColors.highlight, 0.05),
2084
2106
  "--bw-text-subtle": addOpacity(finalColors.text, 0.4),
2107
+ // Some themes (neon-brutalism) call for uppercased titles & buttons
2108
+ "--bw-text-transform": themeName === "dark-neon-brutalism" ? "uppercase" : "none",
2109
+ "--bw-letter-spacing": themeName === "dark-neon-brutalism" ? "0.04em" : "normal",
2085
2110
  colorScheme: (["navy-night", "green-deep", "green-matrix", "gold-luxury", "purple-electric", "dark-neon-brutalism", "amber-retro", "orange-raw"].includes(themeName) || themeName.startsWith("dark-")) ? "dark" : "light",
2086
2111
  };
2087
2112
  }, [
@@ -7241,6 +7266,8 @@ function Sidebar({ isOpen, onClose, title, children, width = "450px", footer, })
7241
7266
  fontSize: "16px",
7242
7267
  color: "var(--bw-text-color)",
7243
7268
  fontFamily: "var(--bw-font-family)",
7269
+ textTransform: "var(--bw-text-transform, none)",
7270
+ letterSpacing: "var(--bw-letter-spacing, normal)",
7244
7271
  flex: 1,
7245
7272
  paddingRight: "12px",
7246
7273
  minWidth: 0,
@@ -11418,6 +11445,8 @@ const buttonBase = {
11418
11445
  transition: "all 0.2s ease",
11419
11446
  whiteSpace: "nowrap",
11420
11447
  border: "none",
11448
+ textTransform: "var(--bw-text-transform, none)",
11449
+ letterSpacing: "var(--bw-letter-spacing, normal)",
11421
11450
  };
11422
11451
  // CSS class name for button hover effects
11423
11452
  const buttonClassName = "bw-button-hover";
@@ -12826,19 +12855,21 @@ function EventTypeDetailsDialog({ isOpen, onClose, eventType, onEventTypeSelect,
12826
12855
  textAlign: "right",
12827
12856
  }, children: jsxs("span", { children: [t("common.from"), " ", formatCurrency(eventType.minPrice)] }) })] }), isAvailable && (jsxs("button", { onClick: handleBookingClick, style: {
12828
12857
  backgroundColor: "var(--bw-highlight-color)",
12829
- color: "#ffffff",
12858
+ color: "var(--bw-button-text-color, #ffffff)",
12830
12859
  padding: "14px 28px",
12831
12860
  border: "none",
12832
12861
  borderRadius: "var(--bw-border-radius)",
12833
12862
  fontSize: "16px",
12834
12863
  fontWeight: 600,
12835
12864
  fontFamily: "var(--bw-font-family)",
12865
+ textTransform: "var(--bw-text-transform, none)",
12866
+ letterSpacing: "var(--bw-letter-spacing, normal)",
12836
12867
  display: "flex",
12837
12868
  alignItems: "center",
12838
12869
  gap: "8px",
12839
12870
  cursor: "pointer",
12840
12871
  transition: "all 0.2s ease",
12841
- }, children: [jsx(IconWave, { size: 20, color: "white" }), t("button.bookNow")] }))] }), !isAvailable && (jsx("div", { style: {
12872
+ }, children: [jsx(IconWave, { size: 20, color: "var(--bw-button-text-color, #ffffff)" }), t("button.bookNow")] }))] }), !isAvailable && (jsx("div", { style: {
12842
12873
  position: "absolute",
12843
12874
  inset: 0,
12844
12875
  backgroundColor: "rgba(0, 0, 0, 0.3)",
@@ -14124,15 +14155,15 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14124
14155
  backgroundColor: isAvailable
14125
14156
  ? "var(--bw-success-color)"
14126
14157
  : "var(--bw-error-color)",
14127
- }, children: isAvailable ? t("events.spotsAvailable") : t("events.soldOut") }) }), jsx("div", { style: { position: "absolute", top: "16px", left: "16px", zIndex: 10 }, children: jsx("div", { style: {
14128
- fontSize: "13px",
14129
- color: "var(--bw-surface-color)",
14130
- fontWeight: 600,
14131
- backgroundColor: "var(--bw-highlight-color)",
14132
- padding: "2px 8px",
14133
- borderRadius: "var(--bw-border-radius)",
14134
- fontFamily: "var(--bw-font-family)",
14135
- }, children: eventType.category.name }) }), jsx("div", { className: "event-type-img", style: { position: "relative", width: "100%", height: "300px" }, children: jsx(ImageCarousel, { images: eventType.images, eventName: eventType.name }) }), jsxs("div", { className: "event-type-content", style: {
14158
+ }, children: isAvailable ? t("events.spotsAvailable") : t("events.soldOut") }) }), eventType.images && eventType.images.length > 0 && (jsxs(Fragment, { children: [jsx("div", { style: { position: "absolute", top: "16px", left: "16px", zIndex: 10 }, children: jsx("div", { style: {
14159
+ fontSize: "13px",
14160
+ color: "var(--bw-surface-color)",
14161
+ fontWeight: 600,
14162
+ backgroundColor: "var(--bw-highlight-color)",
14163
+ padding: "2px 8px",
14164
+ borderRadius: "var(--bw-border-radius)",
14165
+ fontFamily: "var(--bw-font-family)",
14166
+ }, children: eventType.category.name }) }), jsx("div", { className: "event-type-img", style: { position: "relative", width: "100%", height: "300px" }, children: jsx(ImageCarousel, { images: eventType.images, eventName: eventType.name }) })] })), jsxs("div", { className: "event-type-content", style: {
14136
14167
  padding: "12px 18px",
14137
14168
  display: "flex",
14138
14169
  flexDirection: "column",
@@ -14275,8 +14306,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14275
14306
  alignItems: "center",
14276
14307
  marginTop: "10px",
14277
14308
  gap: "12px",
14278
- }, children: [(eventType.description ||
14279
- (eventType.highlights && eventType.highlights.length > 0)) && (jsx("button", { onClick: (e) => {
14309
+ }, children: [eventType.description && (jsx("button", { onClick: (e) => {
14280
14310
  e.stopPropagation();
14281
14311
  handleShowDetails(eventType);
14282
14312
  }, style: {
@@ -14295,12 +14325,14 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14295
14325
  transition: "all 0.2s ease",
14296
14326
  }, children: t("button.moreDetails") })), isAvailable && (jsxs("div", { style: {
14297
14327
  backgroundColor: "var(--bw-highlight-color)",
14298
- color: "var(--bw-surface-color)",
14328
+ color: "var(--bw-button-text-color, #ffffff)",
14299
14329
  padding: "12px 14px",
14300
14330
  borderRadius: "var(--bw-border-radius)",
14301
14331
  fontSize: "clamp(1rem, 2vw, 16px)",
14302
14332
  fontWeight: 600,
14303
14333
  fontFamily: "var(--bw-font-family)",
14334
+ textTransform: "var(--bw-text-transform, none)",
14335
+ letterSpacing: "var(--bw-letter-spacing, normal)",
14304
14336
  display: "flex",
14305
14337
  alignItems: "center",
14306
14338
  justifyContent: "center",
@@ -14309,7 +14341,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14309
14341
  border: "none",
14310
14342
  cursor: "pointer",
14311
14343
  transition: "all 0.2s ease",
14312
- }, children: [jsx(IconWave, { size: 15, color: "var(--bw-surface-color)" }), " ", t("button.bookNow")] }))] })] })] }), showVoucherAttachment && onVoucherClick && (jsx(VoucherAttachment, { onClick: () => onVoucherClick(eventType.id) })), !isAvailable && (jsx("div", { style: {
14344
+ }, children: [jsx(IconWave, { size: 15, color: "var(--bw-button-text-color, #ffffff)" }), " ", t("button.bookNow")] }))] })] })] }), showVoucherAttachment && onVoucherClick && (jsx(VoucherAttachment, { onClick: () => onVoucherClick(eventType.id) })), !isAvailable && (jsx("div", { style: {
14313
14345
  position: "absolute",
14314
14346
  inset: 0,
14315
14347
  backgroundColor: "rgba(0, 0, 0, 0.3)",
@@ -14732,7 +14764,7 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
14732
14764
  }) })] }) }));
14733
14765
  }
14734
14766
 
14735
- function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText, showAllButton, isLoadingEventDetails = false, isLoadingShowAll = false, isLoading = false, }) {
14767
+ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText, showAllButton, isLoadingEventDetails = false, isLoadingShowAll = false, isLoading = false, count = 3, }) {
14736
14768
  const t = useTranslations();
14737
14769
  const { locale } = useLocale();
14738
14770
  const timezone = useTimezone();
@@ -14784,7 +14816,7 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
14784
14816
  };
14785
14817
  // Show loading skeleton
14786
14818
  if (isLoading) {
14787
- return jsx(NextEventsSkeleton, { count: 3 });
14819
+ return jsx(NextEventsSkeleton, { count: count });
14788
14820
  }
14789
14821
  if (events.length === 0) {
14790
14822
  return (jsx("div", { style: { maxWidth: "500px", margin: "0 auto", padding: "16px" }, children: jsxs("div", { style: {
@@ -14840,55 +14872,44 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
14840
14872
  gap: "8px",
14841
14873
  }, children: [jsx("span", { style: { fontSize: "16px" }, children: "\uD83D\uDD04" }), t("common.reload")] })] }) }));
14842
14874
  }
14875
+ const today = new Date();
14843
14876
  return (jsxs("div", { style: {
14844
14877
  maxWidth: "500px",
14845
14878
  margin: "0 auto",
14846
14879
  padding: "12px 16px",
14847
14880
  fontFamily: "var(--bw-font-family)",
14848
- }, children: [jsx("div", { style: { display: "flex", flexDirection: "column", gap: "4px", marginBottom: "10px" }, children: events.map((event) => {
14881
+ }, children: [jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", marginBottom: "10px" }, children: events.map((event) => {
14849
14882
  const availableSpots = event.maxParticipants - event.participantCount;
14850
14883
  const isFullyBooked = availableSpots === 0;
14851
14884
  const startDate = new Date(event.startTime);
14852
- const today = new Date();
14853
14885
  const isPastEvent = today.toISOString() >= startDate.toISOString();
14854
- const isFullAvailability = availableSpots / event.maxParticipants >= 0.8;
14855
- const isHighAvailability = availableSpots / event.maxParticipants >= 0.5;
14856
- const isMediumAvailability = availableSpots / event.maxParticipants >= 0.3;
14857
- const isLowAvailability = availableSpots / event.maxParticipants >= 0.15;
14858
- const getAvailabilityColor = () => {
14859
- if (isFullAvailability)
14860
- return "var(--bw-success-color)";
14861
- if (isHighAvailability)
14862
- return "var(--bw-warning-color)";
14863
- if (isMediumAvailability)
14864
- return "var(--bw-availability-medium-color, #f97316)";
14865
- if (isLowAvailability)
14866
- return "var(--bw-availability-low-color, #8b5cf6)";
14867
- return "var(--bw-highlight-color)";
14868
- };
14869
14886
  const isDisabled = isFullyBooked || isPastEvent || !event.bookingOpen;
14887
+ const availabilityRatio = availableSpots / event.maxParticipants;
14888
+ const allocationBadge = (() => {
14889
+ if (availabilityRatio >= 0.6)
14890
+ return null;
14891
+ if (availabilityRatio === 0)
14892
+ return { text: t("events.soldOut"), backgroundColor: "#7f1d1d", textColor: "#fca5a5" };
14893
+ if (availabilityRatio <= 0.3)
14894
+ return { text: t("instances.almostSoldOut"), backgroundColor: "#7f1d1d", textColor: "#fca5a5" };
14895
+ return { text: t("instances.popularDate"), backgroundColor: "#b45309", textColor: "#fbbf24" };
14896
+ })();
14897
+ const sameDay = formatWeekday(event.startTime, timezone, locale) === formatWeekday(event.endTime, timezone, locale);
14870
14898
  return (jsxs("div", { style: {
14871
14899
  position: "relative",
14872
- borderRadius: "var(--bw-border-radius-small)",
14873
- padding: "0 4px",
14900
+ border: "1px solid var(--bw-border-color)",
14901
+ backgroundColor: "var(--bw-surface-color)",
14902
+ borderRadius: "var(--bw-border-radius)",
14903
+ padding: "16px 10px",
14874
14904
  transition: "all 0.2s ease",
14875
- border: "1px solid transparent",
14876
14905
  fontFamily: "var(--bw-font-family)",
14877
14906
  opacity: isDisabled ? 0.3 : 1,
14878
- filter: isDisabled ? "grayscale(100%)" : "none",
14907
+ filter: isDisabled ? "grayscale(40%)" : "none",
14879
14908
  cursor: isDisabled ? "not-allowed" : "pointer",
14880
14909
  }, onClick: () => {
14881
14910
  if (!isDisabled) {
14882
14911
  handleEventSelect(event.id);
14883
14912
  }
14884
- }, onMouseEnter: (hoverEvent) => {
14885
- if (!isDisabled) {
14886
- hoverEvent.currentTarget.style.backgroundColor = "var(--bw-surface-color)";
14887
- hoverEvent.currentTarget.style.borderColor = getAvailabilityColor();
14888
- }
14889
- }, onMouseLeave: (hoverEvent) => {
14890
- hoverEvent.currentTarget.style.backgroundColor = "transparent";
14891
- hoverEvent.currentTarget.style.borderColor = "transparent";
14892
14913
  }, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsx("div", { style: {
14893
14914
  position: "absolute",
14894
14915
  inset: 0,
@@ -14897,37 +14918,71 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
14897
14918
  justifyContent: "center",
14898
14919
  backgroundColor: "rgba(15, 23, 42, 0.8)",
14899
14920
  borderRadius: "var(--bw-border-radius)",
14900
- }, children: jsx("div", { style: {
14901
- width: "32px",
14902
- height: "32px",
14903
- color: "var(--bw-highlight-color)",
14904
- fontSize: "32px",
14905
- animation: "spin 1s linear infinite",
14906
- }, children: "\u27F3" }) })), jsxs("div", { style: {
14907
- minHeight: "32px",
14908
- display: "grid",
14909
- gridTemplateColumns: "1fr auto 20px",
14910
- alignItems: "center",
14911
- gap: "8px",
14921
+ }, children: jsx("div", { style: { width: "32px", height: "32px", color: "var(--bw-highlight-color)", opacity: 0.8, fontSize: "32px" }, children: "\u27F3" }) })), jsx("div", { style: {
14922
+ display: "flex",
14923
+ marginLeft: "auto",
14924
+ marginTop: "-20px",
14925
+ marginBottom: "4px",
14926
+ borderRadius: "var(--bw-border-radius-small)",
14927
+ fontFamily: "var(--bw-font-family)",
14928
+ zIndex: 50,
14929
+ whiteSpace: "nowrap",
14930
+ width: "fit-content",
14931
+ fontSize: "11px",
14932
+ fontWeight: 700,
14933
+ padding: "2px 8px",
14934
+ backgroundColor: allocationBadge?.backgroundColor || "transparent",
14935
+ color: allocationBadge?.textColor || "transparent",
14936
+ }, children: allocationBadge?.text || " - " }), jsxs("div", { style: {
14937
+ display: "flex",
14938
+ justifyContent: "space-between",
14912
14939
  width: "100%",
14913
- fontSize: "13px",
14914
- color: "var(--bw-text-muted)",
14915
- }, children: [jsxs("span", { style: {
14916
- whiteSpace: "nowrap",
14917
- display: "flex",
14918
- alignItems: "center",
14919
- gap: "3px",
14920
- overflow: "hidden",
14921
- textOverflow: "ellipsis",
14922
- textTransform: "capitalize",
14923
- }, children: [formatWeekday(event.startTime, timezone, locale), " ", formatDate(event.startTime, timezone, locale)] }), jsx("span", { style: {
14924
- display: "flex",
14925
- alignItems: "center",
14926
- gap: "4px",
14927
- whiteSpace: "nowrap",
14928
- fontWeight: 700,
14929
- color: "var(--bw-text-color)",
14930
- }, children: event.price !== null ? formatCurrency(event.price) : t("nextEvents.priceOnRequest") }), event.notes ? jsx(InfoBadge, { text: event.notes }) : jsx("span", {})] })] }, event.id));
14940
+ alignItems: "flex-start",
14941
+ gap: "12px",
14942
+ marginBottom: "4px",
14943
+ }, children: [jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsx("div", { style: {
14944
+ fontSize: "16px",
14945
+ transition: "all 0.2s ease",
14946
+ borderRadius: "var(--bw-border-radius-small)",
14947
+ borderTop: "4px solid var(--bw-border-color)",
14948
+ border: "1px solid var(--bw-border-color)",
14949
+ width: "40px",
14950
+ height: "40px",
14951
+ display: "flex",
14952
+ alignItems: "center",
14953
+ justifyContent: "center",
14954
+ fontWeight: 700,
14955
+ color: "var(--bw-text-color)",
14956
+ backgroundColor: "var(--bw-background-color)",
14957
+ }, children: startDate.getDate() }), jsxs("div", { style: {
14958
+ fontSize: "16px",
14959
+ color: "var(--bw-text-color)",
14960
+ display: "flex",
14961
+ flexDirection: "column",
14962
+ alignItems: "flex-start",
14963
+ justifyContent: "flex-start",
14964
+ lineHeight: 1.25,
14965
+ }, children: [jsxs("div", { children: [jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.startTime, timezone, locale) }), !sameDay && (jsxs(Fragment, { children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.endTime, timezone, locale) })] }))] }), jsx("div", { children: sameDay ? (jsxs(Fragment, { children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.startTime, timezone, locale) }), jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.endTime, timezone, locale) })] })) : (jsxs("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: [formatTime(event.startTime, timezone, locale), " ", t("instances.oclock")] })) })] }), jsxs("span", { style: {
14966
+ fontSize: "12px",
14967
+ fontWeight: 400,
14968
+ color: "var(--bw-text-muted)",
14969
+ marginLeft: "6px",
14970
+ backgroundColor: "rgba(0, 0, 0, 0.05)",
14971
+ whiteSpace: "nowrap",
14972
+ padding: "2px 6px",
14973
+ borderRadius: "var(--bw-border-radius-small)",
14974
+ }, children: [event.durationDays, " ", event.durationDays > 1 ? t("common.days") : t("common.day")] })] }), jsxs("div", { style: { textAlign: "right", display: "flex", flexDirection: "column", alignItems: "flex-end", gap: "4px" }, children: [jsx("span", { style: {
14975
+ display: "inline-flex",
14976
+ alignItems: "center",
14977
+ fontSize: "16px",
14978
+ fontWeight: 600,
14979
+ padding: "2px 8px",
14980
+ borderRadius: "var(--bw-border-radius-small)",
14981
+ fontFamily: "var(--bw-font-family)",
14982
+ backgroundColor: "var(--bw-background-color)",
14983
+ color: "var(--bw-text-color)",
14984
+ border: "1px solid var(--bw-border-color)",
14985
+ }, children: event.price !== null ? formatCurrency(event.price) : t("nextEvents.priceOnRequest") }), event.notes && jsx(InfoBadge, { text: event.notes })] })] })] }, event.id));
14931
14986
  }) }), showAllButton && (jsx("div", { style: { textAlign: "center" }, children: jsx("button", { type: "button", disabled: isLoadingShowAll, style: {
14932
14987
  display: "inline-flex",
14933
14988
  alignItems: "center",
@@ -15748,6 +15803,8 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
15748
15803
  const [isSuccess, setIsSuccess] = useState(false);
15749
15804
  const [successPaymentId, setSuccessPaymentId] = useState(null);
15750
15805
  const [systemConfig, setSystemConfig] = useState(null);
15806
+ // When true, loadEventInstances skips the single-instance auto-select (used by handleShowAllEvents)
15807
+ const skipInstanceAutoSelectRef = useRef(false);
15751
15808
  // PERFORMANCE OPTIMIZATION: Lazy component loading
15752
15809
  const [shouldRenderInstanceSelection, setShouldRenderInstanceSelection] = useState(false);
15753
15810
  const [shouldRenderUpsells, setShouldRenderUpsells] = useState(false);
@@ -16243,7 +16300,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16243
16300
  }
16244
16301
  setStripePromise(loadStripe(data.stripePublishableKey, stripeOptions));
16245
16302
  }
16246
- if (data.eventInstances.length === 1) {
16303
+ if (!skipInstanceAutoSelectRef.current && data.eventInstances.length === 1) {
16247
16304
  setSelectedEventInstance(data.eventInstances[0]);
16248
16305
  setCurrentStep("booking");
16249
16306
  await loadEventDetails(data.eventInstances[0].id);
@@ -16638,12 +16695,30 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16638
16695
  const handleShowAllEvents = async () => {
16639
16696
  setIsLoadingShowAll(true);
16640
16697
  try {
16641
- if (isSingleEventTypeMode && selectedEventType) {
16698
+ if (isSingleEventTypeMode) {
16699
+ // Lock in the correct render branch before any async work so no
16700
+ // intermediate state can accidentally show the cards view.
16642
16701
  setShouldRenderInstanceSelection(true);
16643
- setIsLoadingEventInstances(true);
16644
- await loadEventInstances(selectedEventType.id);
16645
16702
  setCurrentStep("eventInstances");
16646
16703
  setShowingPreview(false);
16704
+ setIsLoadingEventInstances(true);
16705
+ // Suppress the single-instance auto-select inside loadEventInstances
16706
+ // so it doesn't override currentStep to "booking" mid-flight.
16707
+ skipInstanceAutoSelectRef.current = true;
16708
+ try {
16709
+ if (selectedEventType) {
16710
+ await loadEventInstances(selectedEventType.id);
16711
+ }
16712
+ else {
16713
+ // next-events mode skips event type loading on init.
16714
+ // loadEventTypes sets selectedEventType (for the sidebar title)
16715
+ // and internally calls loadEventInstances (auto-select suppressed).
16716
+ await loadEventTypes();
16717
+ }
16718
+ }
16719
+ finally {
16720
+ skipInstanceAutoSelectRef.current = false;
16721
+ }
16647
16722
  setIsLoadingEventInstances(false);
16648
16723
  }
16649
16724
  else {
@@ -16748,7 +16823,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16748
16823
  }
16749
16824
  // Main view based on view mode
16750
16825
  if (viewMode === "next-events" && showingPreview) {
16751
- return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading }), shouldRenderBookingForm && eventDetails && (jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16826
+ return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading, count: nextEventsSettings.count }), shouldRenderBookingForm && eventDetails && (jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16752
16827
  setIsSuccess(false);
16753
16828
  setCurrentStep("eventTypes");
16754
16829
  setShowingPreview(true);
@@ -16783,7 +16858,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16783
16858
  }, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16784
16859
  }
16785
16860
  if (viewMode === "next-events" && !showingPreview && currentStep === "eventInstances") {
16786
- return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => {
16861
+ return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading, count: nextEventsSettings.count }), shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => {
16787
16862
  setShowingPreview(true);
16788
16863
  setCurrentStep("eventTypes");
16789
16864
  }, isOpen: currentStep === "eventInstances", onClose: () => {
@@ -16806,22 +16881,34 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16806
16881
  }, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16807
16882
  }
16808
16883
  if (viewMode === "button" && (isSingleEventTypeMode || isDirectInstanceMode)) {
16884
+ // Busy only while genuinely loading. Note: we intentionally do NOT key off
16885
+ // `shouldRenderInstanceSelection && !sidebarOpen` — that flag stays true after the
16886
+ // sidebar is closed (only `sidebarOpen` resets), which left the spinner stuck on.
16887
+ const isButtonBusy = (isDirectInstanceMode && isLoadingEventDetails) ||
16888
+ (!isDirectInstanceMode && isLoadingEventInstances);
16809
16889
  return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, style: {
16810
16890
  display: "flex",
16811
16891
  justifyContent: "center",
16812
16892
  alignItems: "center",
16813
16893
  minHeight: "120px",
16814
- }, children: [jsx("button", { type: "button", style: {
16894
+ }, children: [jsxs("button", { type: "button", disabled: isButtonBusy, style: {
16895
+ display: "inline-flex",
16896
+ alignItems: "center",
16897
+ gap: "10px",
16815
16898
  backgroundColor: "var(--bw-highlight-color)",
16816
- color: "white",
16899
+ color: "var(--bw-button-text-color, #ffffff)",
16817
16900
  padding: "16px 32px",
16818
16901
  border: "none",
16819
16902
  borderRadius: "var(--bw-border-radius)",
16820
16903
  fontSize: "18px",
16821
16904
  fontWeight: 600,
16822
16905
  fontFamily: "var(--bw-font-family)",
16906
+ textTransform: "var(--bw-text-transform, none)",
16907
+ letterSpacing: "var(--bw-letter-spacing, normal)",
16823
16908
  boxShadow: "var(--bw-shadow-md)",
16824
- cursor: "pointer",
16909
+ cursor: isButtonBusy ? "default" : "pointer",
16910
+ opacity: isButtonBusy ? 0.85 : 1,
16911
+ transition: "opacity 0.2s ease",
16825
16912
  }, onClick: () => {
16826
16913
  if (isDirectInstanceMode) {
16827
16914
  setCurrentStep("booking");
@@ -16832,8 +16919,8 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16832
16919
  setSidebarOpen(true);
16833
16920
  setShouldRenderInstanceSelection(true);
16834
16921
  }
16835
- }, children: config.buttonText ||
16836
- (isDirectInstanceMode ? t("button.bookNow") : t("button.viewDates")) }), shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep })), shouldRenderUpsells && (jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16922
+ }, children: [isButtonBusy && jsx(Spinner, { size: 20, borderColor: "var(--bw-button-text-color, #ffffff)" }), config.buttonText ||
16923
+ (isDirectInstanceMode ? t("button.bookNow") : t("button.viewDates"))] }), shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep })), shouldRenderUpsells && (jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16837
16924
  setIsSuccess(false);
16838
16925
  setCurrentStep("eventTypes");
16839
16926
  setSidebarOpen(false);
@@ -16958,7 +17045,7 @@ function styleInject(css, ref) {
16958
17045
  }
16959
17046
  }
16960
17047
 
16961
- var css_248z = ".booking-widget-container{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box;color:var(--bw-text-color,#1e293b);direction:ltr;display:block;font-family:var(--bw-font-family,system-ui,-apple-system,sans-serif);font-size:var(--bw-font-size,14px);isolation:isolate;line-height:1.5;position:relative;text-align:left}.booking-widget-container *,.booking-widget-container :after,.booking-widget-container :before{box-sizing:border-box;margin:0;padding:0}.booking-widget-container input,.booking-widget-container select,.booking-widget-container textarea{font-family:inherit;font-size:inherit;line-height:inherit}.booking-widget-container button{background:none;border:none;cursor:pointer;font-family:inherit;font-size:inherit}.booking-widget-container a{color:inherit;text-decoration:none}.booking-widget-container img{display:block;height:auto;max-width:100%;vertical-align:middle}.booking-widget-container ol,.booking-widget-container ul{list-style:none}.booking-widget-container h1,.booking-widget-container h2,.booking-widget-container h3,.booking-widget-container h4,.booking-widget-container h5,.booking-widget-container h6{font-size:inherit;font-weight:inherit}#booking-widget-portal{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:var(--bw-text-color,#1e293b);direction:ltr;font-family:var(--bw-font-family,system-ui,-apple-system,sans-serif);font-size:var(--bw-font-size,14px);isolation:isolate;line-height:1.5;text-align:left}#booking-widget-portal *,#booking-widget-portal :after,#booking-widget-portal :before{box-sizing:border-box}#booking-widget-portal-root{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:var(--bw-text-color,#1e293b);font-family:var(--bw-font-family,system-ui,-apple-system,sans-serif);font-size:var(--bw-font-size,14px);line-height:1.5}:root{--bw-highlight-color:#00b1aa;--bw-highlight-color-rgb:0,177,170;--bw-background-color:#f8fdfe;--bw-surface-color:#fff;--bw-text-color:#0e7490;--bw-text-muted:rgba(14,116,144,.7);--bw-border-color:#bae6fd;--bw-success-color:#38bdf8;--bw-warning-color:#fbbf24;--bw-error-color:#f43f5e;--bw-border-radius:18px;--bw-border-radius-small:calc(var(--bw-border-radius)*0.8);--bw-spacing:16px;--bw-spacing-large:24px;--bw-font-family:\"Inter\",system-ui,sans-serif;--bw-font-size:14px;--bw-font-size-large:18px;--bw-font-size-small:12px;--bw-shadow-md:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);--bw-shadow-lg:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);--bw-highlight-muted:rgba(0,177,170,.1);--bw-highlight-subtle:rgba(0,177,170,.05);--bw-text-subtle:rgba(14,116,144,.4)}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes shimmer{0%{transform:translateX(-100%)}to{transform:translateX(100%)}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-out{0%{opacity:1}to{opacity:0}}@keyframes slide-in-right{0%{opacity:0;transform:translateX(100%)}to{opacity:1;transform:translateX(0)}}@keyframes slide-out-right{0%{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(100%)}}@keyframes slide-in-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes scale-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.animate-spin{animation:spin 1s linear infinite}.animate-shimmer{animation:shimmer 2s infinite}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-in-up{animation:slide-in-up .3s ease-out}.animate-scale-in{animation:scale-in .2s ease-out}.skeleton-shimmer{overflow:hidden;position:relative}.skeleton-shimmer:after{animation:shimmer 1.5s infinite;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.3),transparent);content:\"\";height:100%;left:0;position:absolute;top:0;width:100%}.bw-btn{transition:all .2s ease!important}.bw-btn:hover:not(:disabled):not([disabled]){box-shadow:0 4px 12px rgba(0,0,0,.15);transform:translateY(-1px)}.bw-btn:active:not(:disabled):not([disabled]){box-shadow:0 2px 4px rgba(0,0,0,.1)}.bw-btn-primary:hover:not(:disabled):not([disabled]){background-color:var(--bw-highlight-color);filter:brightness(1.1)}.bw-btn-secondary:hover:not(:disabled):not([disabled]){background-color:var(--bw-surface-color);border-color:var(--bw-highlight-color);color:var(--bw-highlight-color)}.bw-btn-ghost:hover:not(:disabled):not([disabled]){background-color:var(--bw-highlight-muted)}.bw-btn-outline:hover:not(:disabled):not([disabled]){background-color:var(--bw-highlight-color);color:var(--bw-button-text-color,#fff)}.bw-btn:disabled,.bw-btn[disabled]{cursor:not-allowed!important;opacity:.5!important}button[class*=bw-btn],button[style*=transition]{transition:all .2s ease!important}button[data-variant=primary]:hover:not(:disabled),button[style*=\"--bw-highlight-color\"]:hover:not(:disabled){box-shadow:0 4px 12px rgba(0,0,0,.15);filter:brightness(1.1);transform:translateY(-1px)}button[data-variant=secondary]:hover:not(:disabled){border-color:var(--bw-highlight-color)!important;color:var(--bw-highlight-color)!important}button[data-variant=ghost]:hover:not(:disabled){background-color:var(--bw-highlight-muted)!important}button[data-variant=outline]:hover:not(:disabled){background-color:var(--bw-highlight-color)!important;color:var(--bw-button-text-color,#fff)!important}.bw-button-hover:hover:not(:disabled){box-shadow:0 4px 12px rgba(0,0,0,.15);transform:translateY(-1px)}.bw-button-hover:active:not(:disabled){box-shadow:0 2px 4px rgba(0,0,0,.1);transform:translateY(0)}@media (max-width:768px){.sidebar-mobile{border-radius:0!important;max-width:100%!important;width:100%!important}}@media (max-width:600px){.event-type-list{gap:12px!important;padding:8px!important}.event-type-card{flex:1 1 100%!important;max-width:100%!important;padding:0!important}.event-type-img{height:160px!important}.event-type-title{font-size:1.1rem!important}.event-type-desc{font-size:.8rem!important;max-height:100px!important;min-height:100px!important}.event-type-content{padding:16px 24px!important}}.event-type-markdown{overflow:visible!important}.event-type-markdown p{color:var(--bw-text-muted);font-family:var(--bw-font-family);line-height:1.6;margin:0 0 8px}.event-type-markdown p:last-child{margin-bottom:0}.event-type-markdown h2{font-size:18px!important;font-weight:700!important;margin:12px 0 6px!important}.event-type-markdown h2,.event-type-markdown h3{color:var(--bw-text-color)!important;line-height:1.3!important}.event-type-markdown h3{font-size:16px!important;font-weight:600!important;margin:10px 0 4px!important}.event-type-markdown strong{color:var(--bw-text-color);font-weight:600}.event-type-markdown em{font-style:italic}.event-type-markdown u{text-decoration:underline}.event-type-markdown ul{list-style:none!important;margin:6px 0!important;padding:0 0 0 24px!important;position:relative!important}.event-type-markdown ul li{color:var(--bw-text-muted)!important;font-family:var(--bw-font-family)!important;margin-bottom:2px!important;padding-left:0!important;position:relative!important}.event-type-markdown ul li:before{color:var(--bw-text-color)!important;content:\"•\"!important;font-weight:700!important;left:-16px!important;position:absolute!important;top:0!important}.event-type-markdown ol{counter-reset:list-counter!important;list-style:none!important;margin:6px 0!important;padding:0 0 0 24px!important;position:relative!important}.event-type-markdown ol li{color:var(--bw-text-muted)!important;counter-increment:list-counter!important;font-family:var(--bw-font-family)!important;margin-bottom:2px!important;padding-left:0!important;position:relative!important}.event-type-markdown ol li:before{color:var(--bw-text-color)!important;content:counter(list-counter) \".\"!important;font-weight:700!important;left:-20px!important;position:absolute!important;top:0!important}.event-type-markdown blockquote{border-left:2px solid var(--bw-border-color);color:var(--bw-text-muted);font-style:italic;margin:4px 0;padding-left:12px}.event-type-markdown a{color:var(--bw-highlight-color);text-decoration:underline}.markdown-content h1,.markdown-content h2,.markdown-content h3,.markdown-content h4,.markdown-content h5,.markdown-content h6{color:var(--bw-text-color);font-weight:600;margin-bottom:.5em}.markdown-content h1{font-size:1.5em}.markdown-content h2{font-size:1.25em}.markdown-content h3{font-size:1.1em}.markdown-content p{line-height:1.6;margin-bottom:1em}.markdown-content ol,.markdown-content ul{margin-bottom:1em;padding-left:1.5em}.markdown-content ul{list-style-type:disc}.markdown-content ol{list-style-type:decimal}.markdown-content li{margin-bottom:.25em}.markdown-content a{color:var(--bw-highlight-color);text-decoration:underline}.markdown-content a:hover{opacity:.8}.markdown-content strong{font-weight:600}.markdown-content em{font-style:italic}.markdown-content code{background:var(--bw-highlight-subtle);border-radius:4px;font-family:monospace;font-size:.9em;padding:.125em .25em}.markdown-content blockquote{border-left:3px solid var(--bw-highlight-color);color:var(--bw-text-muted);margin:1em 0;padding-left:1em}.print-only{display:none}.print-hidden{display:block}@media print{.print-only{display:block}.print-hidden{display:none!important}.print-booking-header{border-bottom:2px solid #000;display:block;margin-bottom:24px;padding-bottom:16px;text-align:center}.print-booking-header h1{font-size:24px;margin:0 0 8px}.print-booking-header .subtitle{color:#666;font-size:14px}.print-booking-card{border:1px solid #ccc;border-radius:8px;margin-bottom:16px;padding:16px;page-break-inside:avoid}.print-section-title{border-bottom:1px solid #ddd;display:block;font-size:16px;font-weight:600;margin-bottom:12px;padding-bottom:8px}.print-detail-grid{display:grid;gap:12px;grid-template-columns:1fr 1fr}.print-detail-item{margin-bottom:8px}.print-detail-label{color:#666;font-size:12px;margin-bottom:4px}.print-detail-value{font-size:14px;font-weight:600}.print-status-badge{border-radius:9999px;display:inline-block;font-size:12px;font-weight:600;padding:4px 12px}.print-status-paid{background-color:#dcfce7;color:#166534;display:inline-block}.print-participant{align-items:center;background-color:#f9fafb;border-radius:4px;display:flex;justify-content:space-between;margin-bottom:8px;padding:8px}.print-participant-name{font-weight:600}.print-participant-age{color:#666;font-size:12px}.print-payment-summary{display:block}.print-payment-row{border-bottom:1px solid #eee;display:flex;justify-content:space-between;padding:4px 0}.print-payment-row:last-child{border-bottom:none;font-weight:600}.print-footer{border-top:1px solid #ddd;color:#666;display:block;font-size:12px;margin-top:24px;padding-top:16px;text-align:center}.print-footer p{margin:4px 0}}";
17048
+ var css_248z = ".booking-widget-container{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box;color:var(--bw-text-color,#1e293b);direction:ltr;display:block;font-family:var(--bw-font-family,system-ui,-apple-system,sans-serif);font-size:var(--bw-font-size,14px);isolation:isolate;line-height:1.5;position:relative;text-align:left}.booking-widget-container *,.booking-widget-container :after,.booking-widget-container :before{box-sizing:border-box;margin:0;padding:0}.booking-widget-container input,.booking-widget-container select,.booking-widget-container textarea{font-family:inherit;font-size:inherit;line-height:inherit}.booking-widget-container button{background:none;border:none;cursor:pointer;font-family:inherit;font-size:inherit}.booking-widget-container a{color:inherit;text-decoration:none}.booking-widget-container img{display:block;height:auto;max-width:100%;vertical-align:middle}.booking-widget-container ol,.booking-widget-container ul{list-style:none}.booking-widget-container h1,.booking-widget-container h2,.booking-widget-container h3,.booking-widget-container h4,.booking-widget-container h5,.booking-widget-container h6{font-size:inherit;font-weight:inherit}#booking-widget-portal{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:var(--bw-text-color,#1e293b);direction:ltr;font-family:var(--bw-font-family,system-ui,-apple-system,sans-serif);font-size:var(--bw-font-size,14px);isolation:isolate;line-height:1.5;text-align:left}#booking-widget-portal *,#booking-widget-portal :after,#booking-widget-portal :before{box-sizing:border-box}#booking-widget-portal-root{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:var(--bw-text-color,#1e293b);font-family:var(--bw-font-family,system-ui,-apple-system,sans-serif);font-size:var(--bw-font-size,14px);line-height:1.5}:root{--bw-highlight-color:#00b1aa;--bw-highlight-color-rgb:0,177,170;--bw-background-color:#f8fdfe;--bw-surface-color:#fff;--bw-text-color:#0e7490;--bw-text-muted:rgba(14,116,144,.7);--bw-border-color:#bae6fd;--bw-success-color:#38bdf8;--bw-warning-color:#fbbf24;--bw-error-color:#f43f5e;--bw-border-radius:18px;--bw-border-radius-small:calc(var(--bw-border-radius)*0.8);--bw-spacing:16px;--bw-spacing-large:24px;--bw-font-family:\"Inter\",system-ui,sans-serif;--bw-font-size:14px;--bw-font-size-large:18px;--bw-font-size-small:12px;--bw-shadow-md:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);--bw-shadow-lg:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);--bw-highlight-muted:rgba(0,177,170,.1);--bw-highlight-subtle:rgba(0,177,170,.05);--bw-text-subtle:rgba(14,116,144,.4)}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes shimmer{0%{transform:translateX(-100%)}to{transform:translateX(100%)}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-out{0%{opacity:1}to{opacity:0}}@keyframes slide-in-right{0%{opacity:0;transform:translateX(100%)}to{opacity:1;transform:translateX(0)}}@keyframes slide-out-right{0%{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(100%)}}@keyframes slide-in-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes scale-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.animate-spin{animation:spin 1s linear infinite}.animate-shimmer{animation:shimmer 2s infinite}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.animate-fade-in{animation:fade-in .2s ease-out}.animate-slide-in-up{animation:slide-in-up .3s ease-out}.animate-scale-in{animation:scale-in .2s ease-out}.skeleton-shimmer{overflow:hidden;position:relative}.skeleton-shimmer:after{animation:shimmer 1.5s infinite;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.3),transparent);content:\"\";height:100%;left:0;position:absolute;top:0;width:100%}.bw-btn{letter-spacing:var(--bw-letter-spacing,normal);text-transform:var(--bw-text-transform,none);transition:all .2s ease!important}.bw-btn:hover:not(:disabled):not([disabled]){box-shadow:0 4px 12px rgba(0,0,0,.15);transform:translateY(-1px)}.bw-btn:active:not(:disabled):not([disabled]){box-shadow:0 2px 4px rgba(0,0,0,.1)}.bw-btn-primary:hover:not(:disabled):not([disabled]){background-color:var(--bw-highlight-color);filter:brightness(1.1)}.bw-btn-secondary:hover:not(:disabled):not([disabled]){background-color:var(--bw-surface-color);border-color:var(--bw-highlight-color);color:var(--bw-highlight-color)}.bw-btn-ghost:hover:not(:disabled):not([disabled]){background-color:var(--bw-highlight-muted)}.bw-btn-outline:hover:not(:disabled):not([disabled]){background-color:var(--bw-highlight-color);color:var(--bw-button-text-color,#fff)}.bw-btn:disabled,.bw-btn[disabled]{cursor:not-allowed!important;opacity:.5!important}button[class*=bw-btn],button[style*=transition]{transition:all .2s ease!important}button[data-variant=primary]:hover:not(:disabled),button[style*=\"--bw-highlight-color\"]:hover:not(:disabled){box-shadow:0 4px 12px rgba(0,0,0,.15);filter:brightness(1.1);transform:translateY(-1px)}button[data-variant=secondary]:hover:not(:disabled){border-color:var(--bw-highlight-color)!important;color:var(--bw-highlight-color)!important}button[data-variant=ghost]:hover:not(:disabled){background-color:var(--bw-highlight-muted)!important}button[data-variant=outline]:hover:not(:disabled){background-color:var(--bw-highlight-color)!important;color:var(--bw-button-text-color,#fff)!important}.bw-button-hover:hover:not(:disabled){box-shadow:0 4px 12px rgba(0,0,0,.15);transform:translateY(-1px)}.bw-button-hover:active:not(:disabled){box-shadow:0 2px 4px rgba(0,0,0,.1);transform:translateY(0)}@media (max-width:768px){.sidebar-mobile{border-radius:0!important;max-width:100%!important;width:100%!important}}@media (max-width:600px){.event-type-list{gap:12px!important;padding:8px!important}.event-type-card{flex:1 1 100%!important;max-width:100%!important;padding:0!important}.event-type-img{height:160px!important}.event-type-title{font-size:1.1rem!important}.event-type-desc{font-size:.8rem!important;max-height:100px!important;min-height:100px!important}.event-type-content{padding:16px 24px!important}}.event-type-markdown{overflow:visible!important}.event-type-markdown p{color:var(--bw-text-muted);font-family:var(--bw-font-family);line-height:1.6;margin:0 0 8px}.event-type-markdown p:last-child{margin-bottom:0}.event-type-markdown h2{font-size:18px!important;font-weight:700!important;margin:12px 0 6px!important}.event-type-markdown h2,.event-type-markdown h3{color:var(--bw-text-color)!important;line-height:1.3!important}.event-type-markdown h3{font-size:16px!important;font-weight:600!important;margin:10px 0 4px!important}.event-type-markdown strong{color:var(--bw-text-color);font-weight:600}.event-type-markdown em{font-style:italic}.event-type-markdown u{text-decoration:underline}.event-type-markdown ul{list-style:none!important;margin:6px 0!important;padding:0 0 0 24px!important;position:relative!important}.event-type-markdown ul li{color:var(--bw-text-muted)!important;font-family:var(--bw-font-family)!important;margin-bottom:2px!important;padding-left:0!important;position:relative!important}.event-type-markdown ul li:before{color:var(--bw-text-color)!important;content:\"•\"!important;font-weight:700!important;left:-16px!important;position:absolute!important;top:0!important}.event-type-markdown ol{counter-reset:list-counter!important;list-style:none!important;margin:6px 0!important;padding:0 0 0 24px!important;position:relative!important}.event-type-markdown ol li{color:var(--bw-text-muted)!important;counter-increment:list-counter!important;font-family:var(--bw-font-family)!important;margin-bottom:2px!important;padding-left:0!important;position:relative!important}.event-type-markdown ol li:before{color:var(--bw-text-color)!important;content:counter(list-counter) \".\"!important;font-weight:700!important;left:-20px!important;position:absolute!important;top:0!important}.event-type-markdown blockquote{border-left:2px solid var(--bw-border-color);color:var(--bw-text-muted);font-style:italic;margin:4px 0;padding-left:12px}.event-type-markdown a{color:var(--bw-highlight-color);text-decoration:underline}.markdown-content h1,.markdown-content h2,.markdown-content h3,.markdown-content h4,.markdown-content h5,.markdown-content h6{color:var(--bw-text-color);font-weight:600;margin-bottom:.5em}.markdown-content h1{font-size:1.5em}.markdown-content h2{font-size:1.25em}.markdown-content h3{font-size:1.1em}.markdown-content p{line-height:1.6;margin-bottom:1em}.markdown-content ol,.markdown-content ul{margin-bottom:1em;padding-left:1.5em}.markdown-content ul{list-style-type:disc}.markdown-content ol{list-style-type:decimal}.markdown-content li{margin-bottom:.25em}.markdown-content a{color:var(--bw-highlight-color);text-decoration:underline}.markdown-content a:hover{opacity:.8}.markdown-content strong{font-weight:600}.markdown-content em{font-style:italic}.markdown-content code{background:var(--bw-highlight-subtle);border-radius:4px;font-family:monospace;font-size:.9em;padding:.125em .25em}.markdown-content blockquote{border-left:3px solid var(--bw-highlight-color);color:var(--bw-text-muted);margin:1em 0;padding-left:1em}.print-only{display:none}.print-hidden{display:block}@media print{.print-only{display:block}.print-hidden{display:none!important}.print-booking-header{border-bottom:2px solid #000;display:block;margin-bottom:24px;padding-bottom:16px;text-align:center}.print-booking-header h1{font-size:24px;margin:0 0 8px}.print-booking-header .subtitle{color:#666;font-size:14px}.print-booking-card{border:1px solid #ccc;border-radius:8px;margin-bottom:16px;padding:16px;page-break-inside:avoid}.print-section-title{border-bottom:1px solid #ddd;display:block;font-size:16px;font-weight:600;margin-bottom:12px;padding-bottom:8px}.print-detail-grid{display:grid;gap:12px;grid-template-columns:1fr 1fr}.print-detail-item{margin-bottom:8px}.print-detail-label{color:#666;font-size:12px;margin-bottom:4px}.print-detail-value{font-size:14px;font-weight:600}.print-status-badge{border-radius:9999px;display:inline-block;font-size:12px;font-weight:600;padding:4px 12px}.print-status-paid{background-color:#dcfce7;color:#166534;display:inline-block}.print-participant{align-items:center;background-color:#f9fafb;border-radius:4px;display:flex;justify-content:space-between;margin-bottom:8px;padding:8px}.print-participant-name{font-weight:600}.print-participant-age{color:#666;font-size:12px}.print-payment-summary{display:block}.print-payment-row{border-bottom:1px solid #eee;display:flex;justify-content:space-between;padding:4px 0}.print-payment-row:last-child{border-bottom:none;font-weight:600}.print-footer{border-top:1px solid #ddd;color:#666;display:block;font-size:12px;margin-top:24px;padding-top:16px;text-align:center}.print-footer p{margin:4px 0}}";
16962
17049
  styleInject(css_248z);
16963
17050
 
16964
17051
  // Export init function for vanilla JS usage