@bigz-app/booking-widget 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -291,6 +291,7 @@
291
291
  "events.soldOut": "Ausgebucht",
292
292
  "events.availableFrom": "Freie Plätze ab {{date}}",
293
293
  "events.noAvailableDates": "Keine Termine frei",
294
+ "events.previewSectionTitle": "Specials & nächste Termine",
294
295
  // Event instances
295
296
  "instances.title": "Terminauswahl",
296
297
  "instances.noAvailable": "Keine verfügbaren Termine",
@@ -307,6 +308,15 @@
307
308
  "nextEvents.noUpcomingMessage": "Aktuell sind keine Termine verfügbar. Bitte schaue später noch einmal vorbei oder kontaktiere uns direkt.",
308
309
  "nextEvents.showAll": "Alle Events anzeigen",
309
310
  "nextEvents.priceOnRequest": "Preis auf Anfrage",
311
+ // Specials view
312
+ "specials.title": "Sonderangebote",
313
+ "specials.subtitle": "Unsere aktuellen Angebote auf einen Blick",
314
+ "specials.noSpecials": "Keine Sonderangebote",
315
+ "specials.noSpecialsMessage": "Derzeit sind keine Sonderangebote verfügbar. Bitte schaue später noch einmal vorbei.",
316
+ "specials.save": "Spare {{amount}}",
317
+ "specials.savePercent": "{{percent}}% Rabatt",
318
+ "specials.spotsLeft": "Noch {{count}} Plätze frei",
319
+ "specials.bookNow": "Jetzt buchen",
310
320
  // Booking form
311
321
  "booking.title": "Buchung - {{name}}",
312
322
  "booking.notPossible": "Buchung nicht möglich",
@@ -551,6 +561,7 @@
551
561
  "events.soldOut": "Sold out",
552
562
  "events.availableFrom": "Available from {{date}}",
553
563
  "events.noAvailableDates": "No dates available",
564
+ "events.previewSectionTitle": "Specials & upcoming dates",
554
565
  // Event instances
555
566
  "instances.title": "Select a date",
556
567
  "instances.noAvailable": "No available dates",
@@ -567,6 +578,15 @@
567
578
  "nextEvents.noUpcomingMessage": "There are currently no dates available. Please check back later or contact us directly.",
568
579
  "nextEvents.showAll": "Show all events",
569
580
  "nextEvents.priceOnRequest": "Price on request",
581
+ // Specials view
582
+ "specials.title": "Special Offers",
583
+ "specials.subtitle": "Our current deals at a glance",
584
+ "specials.noSpecials": "No special offers",
585
+ "specials.noSpecialsMessage": "There are currently no special offers available. Please check back later.",
586
+ "specials.save": "Save {{amount}}",
587
+ "specials.savePercent": "{{percent}}% off",
588
+ "specials.spotsLeft": "{{count}} spots left",
589
+ "specials.bookNow": "Book now",
570
590
  // Booking form
571
591
  "booking.title": "Booking - {{name}}",
572
592
  "booking.notPossible": "Booking not possible",
@@ -811,6 +831,7 @@
811
831
  "events.soldOut": "Agotado",
812
832
  "events.availableFrom": "Disponible desde {{date}}",
813
833
  "events.noAvailableDates": "Sin fechas disponibles",
834
+ "events.previewSectionTitle": "Especiales & próximas fechas",
814
835
  // Event instances
815
836
  "instances.title": "Seleccionar fecha",
816
837
  "instances.noAvailable": "Sin fechas disponibles",
@@ -827,6 +848,15 @@
827
848
  "nextEvents.noUpcomingMessage": "Actualmente no hay fechas disponibles. Por favor, vuelve más tarde o contáctanos directamente.",
828
849
  "nextEvents.showAll": "Mostrar todos los eventos",
829
850
  "nextEvents.priceOnRequest": "Precio bajo consulta",
851
+ // Specials view
852
+ "specials.title": "Ofertas especiales",
853
+ "specials.subtitle": "Nuestras ofertas actuales de un vistazo",
854
+ "specials.noSpecials": "Sin ofertas especiales",
855
+ "specials.noSpecialsMessage": "Actualmente no hay ofertas especiales disponibles. Vuelve más tarde.",
856
+ "specials.save": "Ahorra {{amount}}",
857
+ "specials.savePercent": "{{percent}}% de descuento",
858
+ "specials.spotsLeft": "{{count}} plazas disponibles",
859
+ "specials.bookNow": "Reservar ahora",
830
860
  // Booking form
831
861
  "booking.title": "Reserva - {{name}}",
832
862
  "booking.notPossible": "Reserva no posible",
@@ -1071,6 +1101,7 @@
1071
1101
  "events.soldOut": "Esgotado",
1072
1102
  "events.availableFrom": "Disponível a partir de {{date}}",
1073
1103
  "events.noAvailableDates": "Sem datas disponíveis",
1104
+ "events.previewSectionTitle": "Especiais & próximas datas",
1074
1105
  // Event instances
1075
1106
  "instances.title": "Selecionar data",
1076
1107
  "instances.noAvailable": "Sem datas disponíveis",
@@ -1087,6 +1118,15 @@
1087
1118
  "nextEvents.noUpcomingMessage": "Atualmente não há datas disponíveis. Por favor, volte mais tarde ou contacte-nos diretamente.",
1088
1119
  "nextEvents.showAll": "Mostrar todos os eventos",
1089
1120
  "nextEvents.priceOnRequest": "Preço sob consulta",
1121
+ // Specials view
1122
+ "specials.title": "Ofertas especiais",
1123
+ "specials.subtitle": "As nossas ofertas atuais num relance",
1124
+ "specials.noSpecials": "Sem ofertas especiais",
1125
+ "specials.noSpecialsMessage": "Atualmente não há ofertas especiais disponíveis. Por favor, volte mais tarde.",
1126
+ "specials.save": "Poupe {{amount}}",
1127
+ "specials.savePercent": "{{percent}}% de desconto",
1128
+ "specials.spotsLeft": "{{count}} lugares disponíveis",
1129
+ "specials.bookNow": "Reservar agora",
1090
1130
  // Booking form
1091
1131
  "booking.title": "Reserva - {{name}}",
1092
1132
  "booking.notPossible": "Reserva não possível",
@@ -1331,6 +1371,7 @@
1331
1371
  "events.soldOut": "Fullbokat",
1332
1372
  "events.availableFrom": "Lediga platser från {{date}}",
1333
1373
  "events.noAvailableDates": "Inga datum lediga",
1374
+ "events.previewSectionTitle": "Specials & kommande datum",
1334
1375
  // Event instances
1335
1376
  "instances.title": "Välj datum",
1336
1377
  "instances.noAvailable": "Inga tillgängliga datum",
@@ -1347,6 +1388,15 @@
1347
1388
  "nextEvents.noUpcomingMessage": "Det finns för närvarande inga datum tillgängliga. Kom tillbaka senare eller kontakta oss direkt.",
1348
1389
  "nextEvents.showAll": "Visa alla evenemang",
1349
1390
  "nextEvents.priceOnRequest": "Pris på förfrågan",
1391
+ // Specials view
1392
+ "specials.title": "Specialerbjudanden",
1393
+ "specials.subtitle": "Våra aktuella erbjudanden i korthet",
1394
+ "specials.noSpecials": "Inga specialerbjudanden",
1395
+ "specials.noSpecialsMessage": "Det finns för närvarande inga specialerbjudanden tillgängliga. Kom tillbaka senare.",
1396
+ "specials.save": "Spara {{amount}}",
1397
+ "specials.savePercent": "{{percent}}% rabatt",
1398
+ "specials.spotsLeft": "{{count}} platser kvar",
1399
+ "specials.bookNow": "Boka nu",
1350
1400
  // Booking form
1351
1401
  "booking.title": "Bokning - {{name}}",
1352
1402
  "booking.notPossible": "Bokning inte möjlig",
@@ -1752,129 +1802,143 @@
1752
1802
  // If semantic resolution fails, use fallback or return the original value
1753
1803
  return fallbackValue || colorValue;
1754
1804
  };
1755
- // Predefined themes (modern, accessibility-tested)
1805
+ // Predefined themes
1756
1806
  const themes = {
1757
1807
  // --- Light Themes ---
1758
- "light-fresh": {
1759
- highlight: "#00b1aa", // accent-strong
1760
- background: "#f8fdfe", // neutral-strong (background)
1761
- surface: "#ffffff", // card (pure white)
1762
- text: "#0e7490", // Turquoise 800
1763
- border: "#bae6fd", // Blue 200
1764
- success: "#38bdf8", // Blue 400
1765
- warning: "#fbbf24", // Amber 400
1766
- error: "#f43f5e", // Rose 500
1767
- borderRadius: "18px", // Very rounded corners
1808
+ "teal-minimal": {
1809
+ highlight: "#00b1aa",
1810
+ background: "#f8fdfe",
1811
+ surface: "#ffffff",
1812
+ text: "#0e7490",
1813
+ border: "#bae6fd",
1814
+ success: "#38bdf8",
1815
+ warning: "#fbbf24",
1816
+ error: "#f43f5e",
1817
+ borderRadius: "18px",
1768
1818
  fontFamily: "'Inter', system-ui, sans-serif",
1769
1819
  },
1770
- "light-elegant": {
1771
- highlight: "#8b5cf6", // Violet 500
1772
- background: "#f5f3ff", // Violet 50
1773
- surface: "#ffffff", // White
1774
- text: "#4c1d95", // Violet 900
1775
- border: "#ede9fe", // Violet 100
1776
- success: "#16a34a", // Green 600
1777
- warning: "#ca8a04", // Yellow 600
1778
- error: "#dc2626", // Red 600
1779
- borderRadius: "12px",
1780
- fontFamily: "'Playfair Display', serif",
1820
+ "blue-business": {
1821
+ highlight: "#2563eb",
1822
+ background: "#f8fafc",
1823
+ surface: "#ffffff",
1824
+ text: "#0f172a",
1825
+ border: "#cbd5e1",
1826
+ success: "#059669",
1827
+ warning: "#d97706",
1828
+ error: "#b91c1c",
1829
+ borderRadius: "6px",
1830
+ fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
1781
1831
  },
1782
- "light-vibrant": {
1783
- highlight: "#ed702d", // blue-500 - bright blue accent
1784
- background: "#1f2630", // slate-900 - dark background
1785
- surface: "#1f2630", // slate-800 - dark cards
1786
- text: "#f1f5f9", // slate-100 - light text
1787
- border: "#ed702d", // slate-700 - subtle borders
1788
- success: "#22c55e", // green-500
1789
- warning: "#eab308", // yellow-500
1790
- error: "#ef4444", // red-500
1832
+ "orange-raw": {
1833
+ highlight: "#ed702d",
1834
+ background: "#1f2630",
1835
+ surface: "#1f2630",
1836
+ text: "#f1f5f9",
1837
+ border: "#ed702d",
1838
+ success: "#22c55e",
1839
+ warning: "#eab308",
1840
+ error: "#ef4444",
1791
1841
  borderRadius: "0px",
1792
1842
  fontFamily: "Inter, system-ui, sans-serif",
1793
1843
  },
1794
- "light-professional": {
1795
- highlight: "#2563eb", // Blue 600
1796
- background: "#f8fafc", // Slate 50
1797
- surface: "#ffffff", // White
1798
- text: "#1e293b", // Slate 800
1799
- border: "#e2e8f0", // Slate 200
1800
- success: "#059669", // Emerald 600
1801
- warning: "#d97706", // Amber 600
1802
- error: "#b91c1c", // Red 700
1803
- borderRadius: "4px",
1804
- fontFamily: "system-ui, -apple-system, sans-serif",
1805
- },
1806
- "dark-night": {
1807
- highlight: "#3b82f6", // blue-500 - bright blue accent
1808
- background: "#0f172a", // slate-900 - dark background
1809
- surface: "#1e293b", // slate-800 - dark cards
1810
- text: "#f1f5f9", // slate-100 - light text
1811
- border: "#334155", // slate-700 - subtle borders
1812
- success: "#22c55e", // green-500
1813
- warning: "#eab308", // yellow-500
1814
- error: "#ef4444", // red-500
1815
- borderRadius: "8px",
1816
- fontFamily: "Inter, system-ui, sans-serif",
1844
+ // --- Dark Themes ---
1845
+ "navy-night": {
1846
+ highlight: "#60a5fa",
1847
+ background: "#0b1120",
1848
+ surface: "#111827",
1849
+ text: "#e2e8f0",
1850
+ border: "#1e3a5f",
1851
+ success: "#34d399",
1852
+ warning: "#fbbf24",
1853
+ error: "#f87171",
1854
+ borderRadius: "10px",
1855
+ fontFamily: "'Outfit', system-ui, sans-serif",
1817
1856
  },
1818
- "dark-modern": {
1819
- highlight: "#3b82f6", // blue-500 - bright blue accent
1820
- background: "#0f172a", // slate-900 - dark background
1821
- surface: "#1e293b", // slate-800 - dark cards
1822
- text: "#f1f5f9", // slate-100 - light text
1823
- border: "#334155", // slate-700 - subtle borders
1824
- success: "#22c55e", // green-500
1825
- warning: "#eab308", // yellow-500
1826
- error: "#ef4444", // red-500
1827
- borderRadius: "8px",
1828
- fontFamily: "Inter, system-ui, sans-serif",
1829
- },
1830
- "dark-forest": {
1831
- highlight: "#34d399", // Emerald 400
1832
- background: "#05140d",
1833
- surface: "#062215",
1834
- text: "#d1fae5", // Emerald 100
1835
- border: "#043322",
1836
- success: "#4ade80", // Green 400
1837
- warning: "#facc15", // Yellow 400
1838
- error: "#f87171", // Red 400
1857
+ "green-deep": {
1858
+ highlight: "#34d399",
1859
+ background: "#030d07",
1860
+ surface: "#051a0e",
1861
+ text: "#d1fae5",
1862
+ border: "#064e20",
1863
+ success: "#4ade80",
1864
+ warning: "#facc15",
1865
+ error: "#f87171",
1839
1866
  borderRadius: "12px",
1840
- fontFamily: "system-ui, -apple-system, sans-serif",
1867
+ fontFamily: "'Instrument Sans', system-ui, sans-serif",
1841
1868
  },
1842
- "dark-matrix": {
1843
- highlight: "#33ff33",
1869
+ "green-matrix": {
1870
+ highlight: "#39ff14",
1844
1871
  background: "#000000",
1845
- surface: "#0a0a0a",
1846
- text: "#00ff00",
1847
- border: "#1a1a1a",
1848
- success: "#33ff33",
1872
+ surface: "#060f06",
1873
+ text: "#00ff41",
1874
+ border: "#0d2b0d",
1875
+ success: "#39ff14",
1849
1876
  warning: "#ffff00",
1850
1877
  error: "#ff3333",
1851
1878
  borderRadius: "0px",
1852
- fontFamily: "'Courier New', monospace",
1879
+ fontFamily: "'Share Tech Mono', monospace",
1853
1880
  },
1854
- "dark-luxury": {
1855
- highlight: "#fde047", // Yellow 300
1856
- background: "#1c1917", // Stone 900
1857
- surface: "#292524", // Stone 800
1858
- text: "#fafaf9", // Stone 50
1859
- border: "#44403c", // Stone 700
1860
- success: "#a3e635", // Lime 400
1861
- warning: "#f59e0b", // Amber 500
1862
- error: "#fca5a5", // Red 300
1881
+ "gold-luxury": {
1882
+ highlight: "#fde047",
1883
+ background: "#1c1917",
1884
+ surface: "#292524",
1885
+ text: "#fafaf9",
1886
+ border: "#44403c",
1887
+ success: "#a3e635",
1888
+ warning: "#f59e0b",
1889
+ error: "#fca5a5",
1863
1890
  borderRadius: "24px",
1864
- fontFamily: "'Cinzel', serif",
1891
+ fontFamily: "'Bodoni Moda', serif",
1865
1892
  },
1866
- "dark-energetic": {
1867
- highlight: "#d946ef", // Fuchsia 500
1868
- background: "#2e1046",
1869
- surface: "#401561",
1870
- text: "#f3e8ff", // Purple 50
1871
- border: "#581c87", // Purple 900
1872
- success: "#4ade80", // Green 400
1873
- warning: "#facc15", // Yellow 400
1874
- error: "#f87171", // Red 400
1893
+ "purple-electric": {
1894
+ highlight: "#d946ef",
1895
+ background: "#110820",
1896
+ surface: "#1a0d30",
1897
+ text: "#f3e8ff",
1898
+ border: "#3b0764",
1899
+ success: "#4ade80",
1900
+ warning: "#facc15",
1901
+ error: "#f87171",
1875
1902
  borderRadius: "14px",
1876
1903
  fontFamily: "'Geologica', sans-serif",
1877
1904
  },
1905
+ "dark-neon-brutalism": {
1906
+ highlight: "#00e5cc",
1907
+ background: "#0e1420",
1908
+ surface: "#0e1420",
1909
+ text: "#e8eef5",
1910
+ border: "#00e5cc",
1911
+ success: "#00e5cc",
1912
+ warning: "#ffe45e",
1913
+ error: "#ff4d6d",
1914
+ borderRadius: "4px",
1915
+ fontFamily: "'JetBrains Mono', monospace",
1916
+ buttonTextColor: "#0e1420",
1917
+ },
1918
+ "rose-editorial": {
1919
+ highlight: "#be3455",
1920
+ background: "#fdf8f5",
1921
+ surface: "#ffffff",
1922
+ text: "#1a0a0f",
1923
+ border: "#f2d5db",
1924
+ success: "#2d6a4f",
1925
+ warning: "#b5451b",
1926
+ error: "#9b1d20",
1927
+ borderRadius: "0px",
1928
+ fontFamily: "'Cormorant', serif",
1929
+ },
1930
+ "amber-retro": {
1931
+ highlight: "#f59e0b",
1932
+ background: "#1a1008",
1933
+ surface: "#241a0a",
1934
+ text: "#fef3c7",
1935
+ border: "#78350f",
1936
+ success: "#84cc16",
1937
+ warning: "#f59e0b",
1938
+ error: "#ef4444",
1939
+ borderRadius: "6px",
1940
+ fontFamily: "'Syne', sans-serif",
1941
+ },
1878
1942
  };
1879
1943
  const StyleProvider = ({ config, children, }) => {
1880
1944
  // Track hydration state to prevent mismatches
@@ -1884,8 +1948,8 @@
1884
1948
  }, []);
1885
1949
  // PERFORMANCE OPTIMIZATION: Memoize style calculations
1886
1950
  const themedStyles = T$2(() => {
1887
- const themeName = config.theme || "light-fresh";
1888
- const themeDefaults = themes[themeName] || themes["light-fresh"];
1951
+ const themeName = config.theme || "teal-minimal";
1952
+ const themeDefaults = themes[themeName] || themes["teal-minimal"];
1889
1953
  const getCSSValue = (value, fallback) => {
1890
1954
  if (!value)
1891
1955
  return fallback;
@@ -1955,6 +2019,7 @@
1955
2019
  "--bw-surface-color": finalColors.surface,
1956
2020
  "--bw-text-color": finalColors.text,
1957
2021
  "--bw-text-muted": addOpacity(finalColors.text, 0.7),
2022
+ "--bw-button-text-color": themeDefaults.buttonTextColor || "#ffffff",
1958
2023
  "--bw-border-color": finalColors.border,
1959
2024
  "--bw-success-color": finalColors.success,
1960
2025
  "--bw-warning-color": finalColors.warning,
@@ -1972,7 +2037,7 @@
1972
2037
  "--bw-highlight-muted": addOpacity(finalColors.highlight, 0.1),
1973
2038
  "--bw-highlight-subtle": addOpacity(finalColors.highlight, 0.05),
1974
2039
  "--bw-text-subtle": addOpacity(finalColors.text, 0.4),
1975
- colorScheme: themeName.startsWith("dark-") || themeName === "dark-night" ? "dark" : "light",
2040
+ 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",
1976
2041
  };
1977
2042
  }, [
1978
2043
  config.theme,
@@ -4526,6 +4591,7 @@
4526
4591
  "--bw-font-family": computedStyles.getPropertyValue("--bw-font-family").trim() || "system-ui, sans-serif",
4527
4592
  "--bw-shadow-md": computedStyles.getPropertyValue("--bw-shadow-md").trim() ||
4528
4593
  "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
4594
+ "--bw-button-text-color": computedStyles.getPropertyValue("--bw-button-text-color").trim() || "#ffffff",
4529
4595
  };
4530
4596
  setFallbackStyles(fallbacks);
4531
4597
  }
@@ -11303,11 +11369,13 @@
11303
11369
  whiteSpace: "nowrap",
11304
11370
  border: "none",
11305
11371
  };
11372
+ // CSS class name for button hover effects
11373
+ const buttonClassName = "bw-button-hover";
11306
11374
  const buttonStyles = {
11307
11375
  primary: {
11308
11376
  ...buttonBase,
11309
11377
  backgroundColor: "var(--bw-highlight-color)",
11310
- color: "#ffffff",
11378
+ color: "var(--bw-button-text-color, #ffffff)",
11311
11379
  border: "none",
11312
11380
  },
11313
11381
  secondary: {
@@ -13794,8 +13862,48 @@
13794
13862
  const rest = formatted.slice(0, -1).join(", ");
13795
13863
  return `${t("duration.optionally")} ${rest} ${t("duration.or")} ${last} ${unitPlural}`;
13796
13864
  }
13797
- function EventTypeSelection({ eventTypes, onEventTypeSelect, isLoading = false, skeletonCount = 4, showVoucherAttachment = false, onVoucherClick, }) {
13865
+ function InfoBadge({ text }) {
13866
+ const [open, setOpen] = d$1(false);
13867
+ const ref = A$2(null);
13868
+ return (u$2("span", { ref: ref, onClick: (e) => { e.stopPropagation(); setOpen((v) => !v); }, style: {
13869
+ position: "relative",
13870
+ display: "inline-flex",
13871
+ alignItems: "center",
13872
+ justifyContent: "center",
13873
+ width: "16px",
13874
+ height: "16px",
13875
+ borderRadius: "50%",
13876
+ border: "1px solid var(--bw-highlight-color)",
13877
+ color: "var(--bw-highlight-color)",
13878
+ fontSize: "9px",
13879
+ fontWeight: 700,
13880
+ cursor: "pointer",
13881
+ flexShrink: 0,
13882
+ userSelect: "none",
13883
+ }, children: ["i", open && (u$2("span", { style: {
13884
+ position: "absolute",
13885
+ bottom: "calc(100% + 6px)",
13886
+ right: 0,
13887
+ backgroundColor: "var(--bw-surface-color)",
13888
+ border: "1px solid var(--bw-border-color)",
13889
+ borderRadius: "var(--bw-border-radius-small)",
13890
+ boxShadow: "var(--bw-shadow-md)",
13891
+ padding: "6px 10px",
13892
+ fontSize: "14px",
13893
+ color: "var(--bw-text-color)",
13894
+ fontWeight: 400,
13895
+ whiteSpace: "normal",
13896
+ width: "160px",
13897
+ lineHeight: 1.4,
13898
+ zIndex: 100,
13899
+ textAlign: "left",
13900
+ pointerEvents: "none",
13901
+ }, children: text }))] }));
13902
+ }
13903
+ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview, isLoading = false, skeletonCount = 4, showVoucherAttachment = false, onVoucherClick, }) {
13798
13904
  const t = useTranslations();
13905
+ const { locale } = useLocale();
13906
+ const timezone = useTimezone();
13799
13907
  // State for details dialog
13800
13908
  const [detailsDialogOpen, setDetailsDialogOpen] = d$1(false);
13801
13909
  const [selectedEventTypeForDetails, setSelectedEventTypeForDetails] = d$1(null);
@@ -13905,7 +14013,7 @@
13905
14013
  display: "flex",
13906
14014
  flexDirection: "column",
13907
14015
  justifyContent: "space-between",
13908
- height: "400px",
14016
+ height: "490px",
13909
14017
  }, children: [u$2("div", { children: [u$2("h2", { className: "event-type-title", style: {
13910
14018
  fontSize: "clamp(1.1rem, 2.5vw, 24px)",
13911
14019
  fontWeight: 700,
@@ -13986,7 +14094,43 @@
13986
14094
  color: "var(--bw-text-color)",
13987
14095
  fontFamily: "var(--bw-font-family)",
13988
14096
  textAlign: "right",
13989
- }, children: u$2("span", { children: [t("common.from"), " ", formatCurrency(eventType.minPrice)] }) })] }), u$2("div", { style: {
14097
+ }, children: u$2("span", { children: [t("common.from"), " ", formatCurrency(eventType.minPrice)] }) })] }), (() => {
14098
+ const preview = eventType.cardPreview ?? [];
14099
+ return (u$2("div", { style: {
14100
+ marginTop: "12px",
14101
+ borderTop: "1px solid var(--bw-border-color)",
14102
+ paddingTop: "8px",
14103
+ marginBottom: "16px",
14104
+ }, children: [u$2("div", { style: {
14105
+ fontSize: "11px",
14106
+ fontWeight: 700,
14107
+ color: "var(--bw-text-muted)",
14108
+ textTransform: "uppercase",
14109
+ letterSpacing: "0.05em",
14110
+ marginBottom: "4px",
14111
+ }, children: t("events.previewSectionTitle") }), u$2("div", { style: { height: "102px" }, children: Array.from({ length: 3 }).map((_, i) => {
14112
+ const item = preview[i];
14113
+ if (!item)
14114
+ return u$2("div", { style: { height: "34px" } }, i);
14115
+ const hasDiscount = item.basePrice > 0 && item.price < item.basePrice;
14116
+ return (u$2("div", { onClick: (e) => { e.stopPropagation(); onInstancePreview?.(item.id, eventType.id); }, onMouseEnter: (e) => { if (onInstancePreview)
14117
+ e.currentTarget.style.backgroundColor = "var(--bw-border-color)"; }, onMouseLeave: (e) => { e.currentTarget.style.backgroundColor = "transparent"; }, style: {
14118
+ height: "34px",
14119
+ display: "grid",
14120
+ gridTemplateColumns: "auto 1fr auto 20px",
14121
+ alignItems: "center",
14122
+ gap: "8px",
14123
+ width: "100%",
14124
+ fontSize: "13px",
14125
+ color: "var(--bw-text-muted)",
14126
+ cursor: onInstancePreview ? "pointer" : "default",
14127
+ borderRadius: "4px",
14128
+ padding: "0 2px",
14129
+ transition: "background 0.15s",
14130
+ boxSizing: "border-box",
14131
+ }, children: [u$2("span", { style: { whiteSpace: "nowrap", display: "flex", alignItems: "center", gap: "3px" }, children: [item.isSpecial && (u$2("span", { style: { color: "var(--bw-highlight-color)", fontSize: "11px", lineHeight: 1 }, children: "\u2605" })), formatWeekday(item.startTime, timezone, locale), " ", formatDate(item.startTime, timezone, locale)] }), u$2("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", opacity: 0.75 }, children: item.name }), u$2("span", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [hasDiscount && (u$2("span", { style: { textDecoration: "line-through", opacity: 0.55, fontSize: "11px" }, children: formatCurrency(item.basePrice) })), u$2("span", { style: { fontWeight: 700, color: item.isSpecial ? "var(--bw-highlight-color)" : "var(--bw-text-color)" }, children: formatCurrency(item.price) })] }), item.specialDescription ? (u$2(InfoBadge, { text: item.specialDescription })) : (u$2("span", {}))] }, item.id));
14132
+ }) })] }));
14133
+ })(), u$2("div", { style: {
13990
14134
  display: "flex",
13991
14135
  justifyContent: "flex-end",
13992
14136
  alignItems: "center",
@@ -14001,7 +14145,6 @@
14001
14145
  backgroundColor: "var(--bw-surface-color)",
14002
14146
  padding: "12px",
14003
14147
  borderRadius: "var(--bw-border-radius)",
14004
- fontSize: "clamp(0.8rem, 2vw, 16px)",
14005
14148
  fontWeight: 600,
14006
14149
  fontFamily: "var(--bw-font-family)",
14007
14150
  display: "flex",
@@ -14014,7 +14157,7 @@
14014
14157
  }, children: t("button.moreDetails") })), isAvailable && (u$2("div", { style: {
14015
14158
  backgroundColor: "var(--bw-highlight-color)",
14016
14159
  color: "var(--bw-surface-color)",
14017
- padding: "12px 24px",
14160
+ padding: "12px 14px",
14018
14161
  borderRadius: "var(--bw-border-radius)",
14019
14162
  fontSize: "clamp(1rem, 2vw, 16px)",
14020
14163
  fontWeight: 600,
@@ -14672,6 +14815,172 @@
14672
14815
  }, children: "\u27F3" }), t("common.loading")] })) : (showAllButtonText) }) }))] }));
14673
14816
  }
14674
14817
 
14818
+ function SpecialsView({ specials, onEventSelect, isLoading = false, showSavingsAmount = true, showSavingsPercent = false, emptyStateText, isLoadingEventDetails = false, }) {
14819
+ const t = useTranslations();
14820
+ const { locale } = useLocale();
14821
+ const timezone = useTimezone();
14822
+ const [selectedId, setSelectedId] = d$1(null);
14823
+ const handleSelect = (id) => {
14824
+ setSelectedId(id);
14825
+ onEventSelect(id);
14826
+ };
14827
+ if (isLoading) {
14828
+ return u$2(NextEventsSkeleton, { count: 3 });
14829
+ }
14830
+ if (specials.length === 0) {
14831
+ return (u$2("div", { style: { maxWidth: "500px", margin: "0 auto", padding: "16px" }, children: u$2("div", { style: {
14832
+ display: "flex",
14833
+ flexDirection: "column",
14834
+ alignItems: "center",
14835
+ justifyContent: "center",
14836
+ textAlign: "center",
14837
+ backgroundColor: "var(--bw-surface-color)",
14838
+ border: "1px solid var(--bw-border-color)",
14839
+ borderRadius: "var(--bw-border-radius)",
14840
+ padding: "24px",
14841
+ fontFamily: "var(--bw-font-family)",
14842
+ minHeight: "300px",
14843
+ }, children: [u$2("div", { style: {
14844
+ display: "flex",
14845
+ alignItems: "center",
14846
+ justifyContent: "center",
14847
+ borderRadius: "50%",
14848
+ width: "64px",
14849
+ height: "64px",
14850
+ backgroundColor: "var(--bw-highlight-color)",
14851
+ marginBottom: "16px",
14852
+ fontSize: "32px",
14853
+ color: "#ffffff",
14854
+ opacity: 0.8,
14855
+ }, children: "\uD83C\uDFF7\uFE0F" }), u$2("h3", { style: {
14856
+ fontWeight: 600,
14857
+ margin: "0 0 8px 0",
14858
+ fontSize: "20px",
14859
+ color: "var(--bw-text-color)",
14860
+ fontFamily: "var(--bw-font-family)",
14861
+ }, children: t("specials.noSpecials") }), u$2("p", { style: {
14862
+ margin: 0,
14863
+ color: "var(--bw-text-muted)",
14864
+ fontSize: "16px",
14865
+ lineHeight: 1.6,
14866
+ fontFamily: "var(--bw-font-family)",
14867
+ maxWidth: "400px",
14868
+ }, children: emptyStateText ?? t("specials.noSpecialsMessage") })] }) }));
14869
+ }
14870
+ return (u$2("div", { style: {
14871
+ maxWidth: "500px",
14872
+ margin: "0 auto",
14873
+ padding: "16px",
14874
+ fontFamily: "var(--bw-font-family)",
14875
+ }, children: [u$2("div", { style: { textAlign: "center", marginBottom: "24px" }, children: [u$2("h2", { style: {
14876
+ fontWeight: 600,
14877
+ margin: "0 0 8px 0",
14878
+ fontSize: "18px",
14879
+ color: "var(--bw-text-color)",
14880
+ fontFamily: "var(--bw-font-family)",
14881
+ }, children: t("specials.title") }), u$2("p", { style: {
14882
+ margin: 0,
14883
+ fontSize: "16px",
14884
+ color: "var(--bw-text-muted)",
14885
+ fontFamily: "var(--bw-font-family)",
14886
+ }, children: t("specials.subtitle") })] }), u$2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: specials.map((special) => {
14887
+ const isFullyBooked = special.availableSpots === 0;
14888
+ const isDisabled = isFullyBooked || !special.bookingOpen;
14889
+ const hasDiscount = special.basePrice > 0 && special.price < special.basePrice;
14890
+ return (u$2("div", { style: {
14891
+ position: "relative",
14892
+ backgroundColor: "var(--bw-surface-color)",
14893
+ borderRadius: "var(--bw-border-radius)",
14894
+ border: "1px solid var(--bw-highlight-color)",
14895
+ overflow: "hidden",
14896
+ opacity: isDisabled ? 0.5 : 1,
14897
+ cursor: isDisabled ? "not-allowed" : "pointer",
14898
+ transition: "all 0.2s ease",
14899
+ }, onClick: () => {
14900
+ if (!isDisabled)
14901
+ handleSelect(special.id);
14902
+ }, children: [selectedId === special.id && isLoadingEventDetails && (u$2("div", { style: {
14903
+ position: "absolute",
14904
+ inset: 0,
14905
+ display: "flex",
14906
+ alignItems: "center",
14907
+ justifyContent: "center",
14908
+ backgroundColor: "rgba(15, 23, 42, 0.8)",
14909
+ borderRadius: "var(--bw-border-radius)",
14910
+ zIndex: 10,
14911
+ }, children: u$2("div", { style: { fontSize: "32px", color: "var(--bw-highlight-color)", animation: "spin 1s linear infinite" }, children: "\u27F3" }) })), u$2("div", { style: { display: "flex", gap: "12px", padding: "12px" }, children: [special.images.length > 0 && (u$2("div", { style: {
14912
+ flexShrink: 0,
14913
+ width: "72px",
14914
+ height: "72px",
14915
+ borderRadius: "var(--bw-border-radius-small)",
14916
+ overflow: "hidden",
14917
+ }, children: u$2("img", { src: special.images[0], alt: special.eventTypeName, style: { width: "100%", height: "100%", objectFit: "cover" } }) })), u$2("div", { style: { flex: 1, minWidth: 0 }, children: [u$2("div", { style: { marginBottom: "4px" }, children: u$2("span", { style: {
14918
+ fontSize: "11px",
14919
+ fontWeight: 600,
14920
+ color: "var(--bw-text-muted)",
14921
+ textTransform: "uppercase",
14922
+ letterSpacing: "0.05em",
14923
+ }, children: special.categoryName }) }), u$2("h4", { style: {
14924
+ margin: "0 0 2px 0",
14925
+ fontSize: "15px",
14926
+ fontWeight: 600,
14927
+ color: "var(--bw-text-color)",
14928
+ lineHeight: 1.3,
14929
+ overflow: "hidden",
14930
+ textOverflow: "ellipsis",
14931
+ whiteSpace: "nowrap",
14932
+ }, children: special.eventTypeName }), u$2("div", { style: {
14933
+ fontSize: "13px",
14934
+ fontWeight: 500,
14935
+ color: "var(--bw-highlight-color)",
14936
+ marginBottom: "2px",
14937
+ overflow: "hidden",
14938
+ textOverflow: "ellipsis",
14939
+ whiteSpace: "nowrap",
14940
+ }, children: ["\u2605 ", special.name] }), special.specialDescription && (u$2("div", { style: {
14941
+ fontSize: "12px",
14942
+ color: "var(--bw-text-muted)",
14943
+ marginBottom: "6px",
14944
+ lineHeight: 1.4,
14945
+ }, children: special.specialDescription })), u$2("div", { style: { fontSize: "13px", color: "var(--bw-text-muted)", marginBottom: "8px" }, children: [formatWeekday(special.startTime, timezone, locale), ",", " ", formatDate(special.startTime, timezone, locale)] }), u$2("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap" }, children: [hasDiscount && (u$2("span", { style: {
14946
+ fontSize: "13px",
14947
+ color: "var(--bw-text-muted)",
14948
+ textDecoration: "line-through",
14949
+ }, children: formatCurrency(special.basePrice) })), u$2("span", { style: {
14950
+ fontSize: "16px",
14951
+ fontWeight: 700,
14952
+ color: "var(--bw-highlight-color)",
14953
+ }, children: formatCurrency(special.price) }), hasDiscount && showSavingsAmount && (u$2("span", { style: {
14954
+ fontSize: "12px",
14955
+ fontWeight: 600,
14956
+ color: "#ffffff",
14957
+ backgroundColor: "var(--bw-success-color, #22c55e)",
14958
+ borderRadius: "4px",
14959
+ padding: "2px 6px",
14960
+ }, children: t("specials.save").replace("{{amount}}", formatCurrency(special.savings)) })), hasDiscount && showSavingsPercent && (u$2("span", { style: {
14961
+ fontSize: "12px",
14962
+ fontWeight: 600,
14963
+ color: "#ffffff",
14964
+ backgroundColor: "var(--bw-success-color, #22c55e)",
14965
+ borderRadius: "4px",
14966
+ padding: "2px 6px",
14967
+ }, children: t("specials.savePercent").replace("{{percent}}", String(special.savingsPercent)) }))] })] })] }), u$2("div", { style: {
14968
+ borderTop: "1px solid var(--bw-border-color)",
14969
+ padding: "8px 12px",
14970
+ display: "flex",
14971
+ justifyContent: "space-between",
14972
+ alignItems: "center",
14973
+ backgroundColor: "var(--bw-background-color)",
14974
+ }, children: [u$2("span", { style: { fontSize: "12px", color: "var(--bw-text-muted)" }, children: isFullyBooked
14975
+ ? t("common.fullyBooked")
14976
+ : t("specials.spotsLeft").replace("{{count}}", String(special.availableSpots)) }), u$2("span", { style: {
14977
+ fontSize: "13px",
14978
+ fontWeight: 600,
14979
+ color: "var(--bw-highlight-color)",
14980
+ }, children: [t("specials.bookNow"), " \u2192"] })] })] }, special.id));
14981
+ }) })] }));
14982
+ }
14983
+
14675
14984
  const getThemeConfig = (theme = "generic") => {
14676
14985
  switch (theme) {
14677
14986
  case "christmas":
@@ -14931,8 +15240,8 @@
14931
15240
  };
14932
15241
  const checkboxContainerStyles = {
14933
15242
  position: "absolute",
14934
- top: "12px",
14935
- right: "12px",
15243
+ bottom: "12px",
15244
+ left: "12px",
14936
15245
  zIndex: 1,
14937
15246
  };
14938
15247
  const checkboxInnerStyles = {
@@ -15027,6 +15336,7 @@
15027
15336
  alignItems: "flex-end",
15028
15337
  marginTop: "8px",
15029
15338
  paddingTop: "8px",
15339
+ paddingBottom: "0px",
15030
15340
  borderTop: "1px solid var(--bw-border-color)",
15031
15341
  };
15032
15342
  const pricePerPersonStyles = {
@@ -15118,7 +15428,7 @@
15118
15428
  };
15119
15429
  const selectedTotal = calculateTotal();
15120
15430
  const selectedCount = selectedUpsells.length;
15121
- const footerContent = (u$2(k$3, { children: [u$2("button", { type: "button", onClick: onBack, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: t("common.back") }), u$2("button", { type: "button", onClick: onContinue, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), children: selectedCount === 0 ? t("button.continueWithout") : t("button.continue") })] }));
15431
+ const footerContent = (u$2(k$3, { children: [u$2("button", { type: "button", onClick: onBack, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), className: buttonClassName, children: t("common.back") }), u$2("button", { type: "button", onClick: onContinue, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), className: buttonClassName, children: selectedCount === 0 ? t("button.continueWithout") : t("button.continue") })] }));
15122
15432
  return (u$2(Sidebar, { isOpen: isOpen, onClose: onClose, title: t("upsells.title"), footer: footerContent, children: u$2("div", { style: { display: "flex", flexDirection: "column", height: "100%", padding: "16px 16px" }, children: [isLoading && (u$2("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "12px", padding: "40px 20px", ...textStyles.muted }, children: [spinner(), u$2("span", { children: t("upsells.loading") })] })), !isLoading && upsells.length === 0 && (u$2("div", { style: { textAlign: "center", padding: "40px 20px", ...textStyles.muted }, children: u$2("p", { children: t("upsells.noExtras") }) })), !isLoading && upsells.length > 0 && (u$2("div", { style: { display: "flex", flexDirection: "column", gap: "12px", flex: 1, overflowY: "auto", paddingBottom: "16px" }, children: upsells.map((upsell) => (u$2(UpsellCard, { upsell: upsell, isSelected: isSelected(upsell.id), participantCount: participantCount, onSelect: () => selectUpsell(upsell.id) }, upsell.id))) })), selectedCount > 0 && (u$2("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: "16px", paddingBottom: "16px", paddingTop: "16px", borderTop: "1px solid var(--bw-border-color)", fontSize: "14px" }, children: [u$2("span", { style: textStyles.muted, children: selectedCount === 1 ? t("upsells.selected", { count: selectedCount }) : t("upsells.selectedPlural", { count: selectedCount }) }), u$2("span", { style: { fontWeight: 600, color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+", formatCurrency(selectedTotal)] })] }))] }) }));
15123
15433
  }
15124
15434
 
@@ -15166,6 +15476,8 @@
15166
15476
  : (config.voucherIntegration ?? (hasEventSelection && !isDirectInstanceMode));
15167
15477
  // Selection flow state
15168
15478
  const [currentStep, setCurrentStep] = d$1("eventTypes");
15479
+ // Tracks where to return when closing the booking form
15480
+ const bookingReturnStep = A$2("eventInstances");
15169
15481
  const [eventTypes, setEventTypes] = d$1([]);
15170
15482
  const [selectedEventType, setSelectedEventType] = d$1(null);
15171
15483
  const [eventInstances, setEventInstances] = d$1([]);
@@ -15178,6 +15490,9 @@
15178
15490
  // State for upcoming events (next-events view mode)
15179
15491
  const [upcomingEvents, setUpcomingEvents] = d$1([]);
15180
15492
  const [showingPreview, setShowingPreview] = d$1(true);
15493
+ // State for specials view mode
15494
+ const [specials, setSpecials] = d$1([]);
15495
+ const [isLoadingSpecials, setIsLoadingSpecials] = d$1(false);
15181
15496
  // New: sidebar open state for single event type mode
15182
15497
  const [sidebarOpen, setSidebarOpen] = d$1(false);
15183
15498
  // Booking flow state
@@ -15328,6 +15643,11 @@
15328
15643
  await loadUpcomingEvents();
15329
15644
  return;
15330
15645
  }
15646
+ // Specials view mode: load special offers
15647
+ if (viewMode === "specials") {
15648
+ await loadSpecials();
15649
+ return;
15650
+ }
15331
15651
  // Single event type mode: load event type and instances, but don't open sidebar yet
15332
15652
  if (isSingleEventTypeMode) {
15333
15653
  await loadEventTypes();
@@ -15551,6 +15871,45 @@
15551
15871
  setError(data.error || t("error.loadUpcomingEvents"));
15552
15872
  }
15553
15873
  };
15874
+ const loadSpecials = async () => {
15875
+ setIsLoadingSpecials(true);
15876
+ const specialsSettings = config.specialsSettings ?? {};
15877
+ const requestBody = {
15878
+ organizationId: config.organizationId,
15879
+ limit: specialsSettings.count ?? 20,
15880
+ };
15881
+ if (config.categoryId) {
15882
+ requestBody.categoryId = config.categoryId;
15883
+ }
15884
+ else if (config.eventTypeIds) {
15885
+ requestBody.eventTypeIds = config.eventTypeIds;
15886
+ }
15887
+ else if (config.eventTypeId) {
15888
+ requestBody.eventTypeId = config.eventTypeId;
15889
+ }
15890
+ try {
15891
+ const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/specials"), {
15892
+ method: "POST",
15893
+ headers: createApiHeaders(config, locale),
15894
+ body: JSON.stringify(requestBody),
15895
+ });
15896
+ const data = await response.json();
15897
+ if (response.ok) {
15898
+ const wl = extractWidgetLanguagePayload(data);
15899
+ if (wl) {
15900
+ onWidgetLanguage?.(wl);
15901
+ onTimezone?.(wl.timezone);
15902
+ }
15903
+ setSpecials(data.specials || []);
15904
+ }
15905
+ else {
15906
+ setError(data.error || t("error.loadUpcomingEvents"));
15907
+ }
15908
+ }
15909
+ finally {
15910
+ setIsLoadingSpecials(false);
15911
+ }
15912
+ };
15554
15913
  const loadEventInstances = async (eventTypeId) => {
15555
15914
  const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/event-instances"), {
15556
15915
  method: "POST",
@@ -15735,6 +16094,7 @@
15735
16094
  // Event instance selection handlers
15736
16095
  const handleEventInstanceSelect = async (eventInstance) => {
15737
16096
  setSelectedEventInstance(eventInstance);
16097
+ bookingReturnStep.current = "eventInstances";
15738
16098
  // Set default participant count for upsell calculations
15739
16099
  const defaultParticipantCount = 1;
15740
16100
  setTempParticipantCount(defaultParticipantCount);
@@ -15747,7 +16107,14 @@
15747
16107
  if (availableUpsells.length > 0) {
15748
16108
  // Show upsells step
15749
16109
  setUpsells(availableUpsells);
15750
- setSelectedUpsells([]);
16110
+ // Pre-select default-checked upsells
16111
+ const defaultSelections = availableUpsells
16112
+ .filter((upsell) => upsell.defaultChecked && upsell.available)
16113
+ .map((upsell) => ({
16114
+ upsellPackageId: upsell.id,
16115
+ quantity: defaultParticipantCount,
16116
+ }));
16117
+ setSelectedUpsells(defaultSelections);
15751
16118
  setCurrentStep("upsells");
15752
16119
  setIsLoadingUpsells(false);
15753
16120
  return; // Don't proceed to booking yet
@@ -15778,7 +16145,7 @@
15778
16145
  setEventInstances([]);
15779
16146
  };
15780
16147
  const handleBackToEventInstances = () => {
15781
- setCurrentStep("eventInstances");
16148
+ setCurrentStep(bookingReturnStep.current);
15782
16149
  setSelectedEventInstance(null);
15783
16150
  setEventDetails(null);
15784
16151
  };
@@ -15812,8 +16179,7 @@
15812
16179
  }
15813
16180
  };
15814
16181
  const handleUpsellsBack = () => {
15815
- // Go back to event instance selection
15816
- setCurrentStep("eventInstances");
16182
+ setCurrentStep(bookingReturnStep.current);
15817
16183
  setSelectedUpsells([]);
15818
16184
  setUpsells([]);
15819
16185
  };
@@ -15848,10 +16214,36 @@
15848
16214
  setError(errorMessage);
15849
16215
  config.onError?.(errorMessage);
15850
16216
  };
15851
- const handleUpcomingEventSelect = async (eventInstanceId) => {
16217
+ const handleUpcomingEventSelect = async (eventInstanceId, eventTypeId) => {
16218
+ // Resolve the event type — may come from card preview (eventTypeId provided) or
16219
+ // from the next-events list where selectedEventType is already set
16220
+ const resolvedEventType = eventTypeId != null
16221
+ ? (eventTypes.find((et) => et.id === eventTypeId) ?? selectedEventType)
16222
+ : selectedEventType;
16223
+ if (resolvedEventType && resolvedEventType !== selectedEventType) {
16224
+ setSelectedEventType(resolvedEventType);
16225
+ }
16226
+ // Check if this is coming from a card preview (eventTypeId was provided)
16227
+ // In that case, we need to load event instances so back navigation works properly
16228
+ const isFromCardPreview = eventTypeId != null;
16229
+ if (isFromCardPreview && resolvedEventType) {
16230
+ // Load event instances in background so back navigation shows instances
16231
+ setShouldRenderInstanceSelection(true);
16232
+ void loadEventInstances(resolvedEventType.id);
16233
+ // Record that we should return to instance selection (not event types)
16234
+ bookingReturnStep.current = "eventInstances";
16235
+ }
16236
+ else {
16237
+ // Record where to return when the booking form is closed
16238
+ bookingReturnStep.current = currentStep === "eventInstances" ? "eventInstances" : "eventTypes";
16239
+ }
16240
+ // First try to find the event in upcomingEvents (for next-events view mode)
15852
16241
  const upcomingEvent = upcomingEvents.find((event) => event.id === eventInstanceId);
15853
- if (upcomingEvent) {
15854
- const eventInstance = {
16242
+ // If not found in upcomingEvents, try to find in card preview items
16243
+ const cardPreviewItem = !upcomingEvent && resolvedEventType?.cardPreview?.find((item) => item.id === eventInstanceId);
16244
+ // Build the event instance from either source
16245
+ const eventInstance = upcomingEvent
16246
+ ? {
15855
16247
  id: upcomingEvent.id,
15856
16248
  name: upcomingEvent.name,
15857
16249
  startTime: upcomingEvent.startTime,
@@ -15865,13 +16257,63 @@
15865
16257
  bookingOpen: upcomingEvent.bookingOpen,
15866
16258
  ...(upcomingEvent.deposit !== undefined && { deposit: upcomingEvent.deposit }),
15867
16259
  ...(upcomingEvent.notes !== undefined && { notes: upcomingEvent.notes }),
15868
- };
16260
+ }
16261
+ : cardPreviewItem
16262
+ ? {
16263
+ id: cardPreviewItem.id,
16264
+ name: cardPreviewItem.name,
16265
+ startTime: cardPreviewItem.startTime,
16266
+ endTime: cardPreviewItem.startTime,
16267
+ price: cardPreviewItem.price,
16268
+ maxParticipants: cardPreviewItem.availableSpots + 1,
16269
+ participantCount: 1,
16270
+ availableSpots: cardPreviewItem.availableSpots,
16271
+ durationDays: 1,
16272
+ durationPerDay: 1,
16273
+ bookingOpen: true,
16274
+ }
16275
+ : null;
16276
+ if (eventInstance) {
15869
16277
  setSelectedEventInstance(eventInstance);
15870
16278
  }
16279
+ setError(null);
16280
+ // Check for upsells before going to booking (same as handleEventInstanceSelect)
16281
+ const eventTypeForUpsells = resolvedEventType;
16282
+ if (eventTypeForUpsells) {
16283
+ const defaultParticipantCount = 1;
16284
+ setTempParticipantCount(defaultParticipantCount);
16285
+ setIsLoadingUpsells(true);
16286
+ setShouldRenderUpsells(true);
16287
+ try {
16288
+ const availableUpsells = await loadUpsells(eventTypeForUpsells.id, eventInstanceId, defaultParticipantCount);
16289
+ if (availableUpsells.length > 0) {
16290
+ setUpsells(availableUpsells);
16291
+ // Pre-select default-checked upsells
16292
+ const defaultSelections = availableUpsells
16293
+ .filter((upsell) => upsell.defaultChecked && upsell.available)
16294
+ .map((upsell) => ({
16295
+ upsellPackageId: upsell.id,
16296
+ quantity: defaultParticipantCount,
16297
+ }));
16298
+ setSelectedUpsells(defaultSelections);
16299
+ setCurrentStep("upsells");
16300
+ setIsLoadingUpsells(false);
16301
+ // Load event details in background for when user continues past upsells
16302
+ void loadEventDetails(eventInstanceId);
16303
+ return;
16304
+ }
16305
+ }
16306
+ catch (err) {
16307
+ console.error("Error loading upsells:", err);
16308
+ }
16309
+ finally {
16310
+ setIsLoadingUpsells(false);
16311
+ }
16312
+ }
16313
+ // No upsells — go directly to booking
15871
16314
  setCurrentStep("booking");
15872
16315
  setShouldRenderBookingForm(true);
15873
16316
  setIsLoadingEventDetails(true);
15874
- setError(null);
15875
16317
  try {
15876
16318
  await loadEventDetails(eventInstanceId);
15877
16319
  }
@@ -16028,6 +16470,31 @@
16028
16470
  window.history.replaceState({}, "", url.toString());
16029
16471
  }, config: config, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (u$2(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16030
16472
  }
16473
+ if (viewMode === "specials" && showingPreview) {
16474
+ return (u$2(StyleProvider, { config: config, children: [u$2("div", { ref: setWidgetContainerRef, children: [u$2(SpecialsView, { specials: specials, onEventSelect: handleUpcomingEventSelect, isLoading: isLoadingSpecials, showSavingsAmount: config.specialsSettings?.showSavingsAmount ?? true, showSavingsPercent: config.specialsSettings?.showSavingsPercent ?? false, emptyStateText: config.specialsSettings?.emptyStateText }), shouldRenderBookingForm && eventDetails && (u$2(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, onBackToEventInstances: () => {
16475
+ setCurrentStep("eventTypes");
16476
+ setShowingPreview(true);
16477
+ setEventDetails(null);
16478
+ }, onBackToEventTypes: () => {
16479
+ setCurrentStep("eventTypes");
16480
+ setShowingPreview(true);
16481
+ setEventDetails(null);
16482
+ }, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: () => {
16483
+ setCurrentStep("eventTypes");
16484
+ setShowingPreview(true);
16485
+ setEventDetails(null);
16486
+ }, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), u$2(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16487
+ setIsSuccess(false);
16488
+ setCurrentStep("eventTypes");
16489
+ setShowingPreview(true);
16490
+ setSuccessPaymentId(null);
16491
+ setShouldRenderInstanceSelection(false);
16492
+ setShouldRenderUpsells(false);
16493
+ setShouldRenderBookingForm(false);
16494
+ setSelectedUpsells([]);
16495
+ setUpsells([]);
16496
+ }, config: config, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (u$2(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16497
+ }
16031
16498
  if (viewMode === "next-events" && !showingPreview && currentStep === "eventInstances") {
16032
16499
  return (u$2(StyleProvider, { config: config, children: [u$2("div", { ref: setWidgetContainerRef, children: [shouldRenderInstanceSelection && (u$2(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => {
16033
16500
  setShowingPreview(true);
@@ -16098,7 +16565,7 @@
16098
16565
  }, config: config, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (u$2(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16099
16566
  }
16100
16567
  // Cards mode (default) - show event type selection with optional voucher card
16101
- const cardsView = (u$2(k$3, { children: [hasEventSelection && (u$2(EventTypeSelection, { eventTypes: eventTypes, onEventTypeSelect: handleEventTypeSelect, isLoading: isLoading, skeletonCount: getSkeletonCount(), showVoucherAttachment: Boolean(voucherConfig?.enabled && voucherCardIntegrationEnabled && !isStandaloneVoucherMode), onVoucherClick: handleVoucherAttachmentClick })), isStandaloneVoucherMode && (u$2(VoucherIntegration, { config: config, voucherConfig: voucherConfig, eventTypes: voucherEventTypes, systemConfig: systemConfig, isFormOpen: false, isLoadingConfig: isLoadingVoucherConfig, preselectedEventTypeId: null, voucherPurchaseResult: null, isSuccess: false, showStandaloneCard: Boolean(voucherConfig?.enabled && voucherCardIntegrationEnabled), onCardClick: handleVoucherCardClick, onFormClose: handleVoucherFormClose, onSuccess: handleVoucherSuccess, onError: handleVoucherError, onSuccessModalClose: () => { } })), isStandaloneVoucherMode && isLoading && !voucherConfig && (u$2("div", { style: { padding: "24px", textAlign: "center" }, children: u$2("div", { style: {
16568
+ const cardsView = (u$2(k$3, { children: [hasEventSelection && (u$2(EventTypeSelection, { eventTypes: eventTypes, onEventTypeSelect: handleEventTypeSelect, onInstancePreview: (instanceId, eventTypeId) => void handleUpcomingEventSelect(instanceId, eventTypeId), isLoading: isLoading, skeletonCount: getSkeletonCount(), showVoucherAttachment: Boolean(voucherConfig?.enabled && voucherCardIntegrationEnabled && !isStandaloneVoucherMode), onVoucherClick: handleVoucherAttachmentClick })), isStandaloneVoucherMode && (u$2(VoucherIntegration, { config: config, voucherConfig: voucherConfig, eventTypes: voucherEventTypes, systemConfig: systemConfig, isFormOpen: false, isLoadingConfig: isLoadingVoucherConfig, preselectedEventTypeId: null, voucherPurchaseResult: null, isSuccess: false, showStandaloneCard: Boolean(voucherConfig?.enabled && voucherCardIntegrationEnabled), onCardClick: handleVoucherCardClick, onFormClose: handleVoucherFormClose, onSuccess: handleVoucherSuccess, onError: handleVoucherError, onSuccessModalClose: () => { } })), isStandaloneVoucherMode && isLoading && !voucherConfig && (u$2("div", { style: { padding: "24px", textAlign: "center" }, children: u$2("div", { style: {
16102
16569
  display: "inline-block",
16103
16570
  width: "32px",
16104
16571
  height: "32px",
@@ -16208,7 +16675,7 @@
16208
16675
  }
16209
16676
  }
16210
16677
 
16211
- 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%}@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}}";
16678
+ 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}}";
16212
16679
  styleInject(css_248z);
16213
16680
 
16214
16681
  // Export init function for vanilla JS usage with Preact