@bigz-app/booking-widget 1.2.0 → 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.
Files changed (35) hide show
  1. package/dist/booking-widget.js +620 -148
  2. package/dist/booking-widget.js.map +1 -1
  3. package/dist/components/UniversalBookingWidget.d.ts +52 -2
  4. package/dist/components/UniversalBookingWidget.d.ts.map +1 -1
  5. package/dist/components/events/EventTypeSelection.d.ts +14 -1
  6. package/dist/components/events/EventTypeSelection.d.ts.map +1 -1
  7. package/dist/components/events/SpecialsView.d.ts +13 -0
  8. package/dist/components/events/SpecialsView.d.ts.map +1 -0
  9. package/dist/components/events/index.d.ts +1 -0
  10. package/dist/components/events/index.d.ts.map +1 -1
  11. package/dist/components/shared/Button.d.ts.map +1 -1
  12. package/dist/components/shared/DialogPortal.d.ts.map +1 -1
  13. package/dist/components/upsells/UpsellCard.d.ts +2 -0
  14. package/dist/components/upsells/UpsellCard.d.ts.map +1 -1
  15. package/dist/components/upsells/UpsellsStep.d.ts +2 -0
  16. package/dist/components/upsells/UpsellsStep.d.ts.map +1 -1
  17. package/dist/components/voucher/VoucherIntegration.d.ts +23 -0
  18. package/dist/components/voucher/VoucherIntegration.d.ts.map +1 -0
  19. package/dist/components/voucher/index.d.ts +2 -0
  20. package/dist/components/voucher/index.d.ts.map +1 -1
  21. package/dist/components/voucher/useVoucherConfig.d.ts +57 -0
  22. package/dist/components/voucher/useVoucherConfig.d.ts.map +1 -0
  23. package/dist/i18n/locales/de.d.ts.map +1 -1
  24. package/dist/i18n/locales/en.d.ts.map +1 -1
  25. package/dist/i18n/locales/es.d.ts.map +1 -1
  26. package/dist/i18n/locales/pt.d.ts.map +1 -1
  27. package/dist/i18n/locales/sv.d.ts.map +1 -1
  28. package/dist/index.cjs +620 -148
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.esm.js +620 -148
  31. package/dist/index.esm.js.map +1 -1
  32. package/dist/styles/StyleProvider.d.ts.map +1 -1
  33. package/dist/styles/shared-styles.d.ts +1 -0
  34. package/dist/styles/shared-styles.d.ts.map +1 -1
  35. package/package.json +1 -1
@@ -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",
1817
- },
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",
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",
1829
1856
  },
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: {
@@ -12835,8 +12903,8 @@
12835
12903
  const displayPrice = !config.allowMonetaryVouchers && minEventPrice && minEventPrice > 0
12836
12904
  ? minEventPrice
12837
12905
  : minEventPrice && minEventPrice > 0
12838
- ? Math.min(config.monetaryPresets[0] || 2500, minEventPrice)
12839
- : config.monetaryPresets[0] || 2500;
12906
+ ? Math.min(config.monetaryPresets[0] || 2000, minEventPrice)
12907
+ : config.monetaryPresets[0] || 2000;
12840
12908
  const slideshowImages = T$2(() => Array.from(new Set(fallbackImages.filter(Boolean))).slice(0, 5), [fallbackImages]);
12841
12909
  const hasSlideshow = !config.image && slideshowImages.length > 0;
12842
12910
  y$1(() => {
@@ -13490,7 +13558,7 @@
13490
13558
  color: "var(--bw-text-muted)",
13491
13559
  fontFamily: "var(--bw-font-family)",
13492
13560
  }, children: [t("voucher.for"), " ", recipientName] }))] })] }), u$2("div", { style: {
13493
- fontSize: "24px",
13561
+ fontSize: "clamp(18px, 4vw, 22px)",
13494
13562
  fontWeight: 700,
13495
13563
  color: "var(--bw-highlight-color)",
13496
13564
  fontFamily: "var(--bw-font-family)",
@@ -13761,6 +13829,20 @@
13761
13829
  }, children: t("voucher.buyAsGift") })] }));
13762
13830
  }
13763
13831
 
13832
+ function VoucherIntegration({ config, voucherConfig, eventTypes, systemConfig, isFormOpen, isLoadingConfig, preselectedEventTypeId, voucherPurchaseResult, isSuccess, showStandaloneCard, onCardClick, onFormClose, onSuccess, onError, onSuccessModalClose, }) {
13833
+ if (!voucherConfig?.enabled) {
13834
+ return null;
13835
+ }
13836
+ return (u$2(k$3, { children: [showStandaloneCard && (u$2("div", { style: { padding: "0" }, children: u$2("div", { style: {
13837
+ display: "grid",
13838
+ gridTemplateColumns: "minmax(350px, 500px)",
13839
+ gap: "24px",
13840
+ justifyContent: "center",
13841
+ }, children: u$2(VoucherPurchaseCard, { config: voucherConfig, minEventPrice: eventTypes.length > 0
13842
+ ? Math.min(...eventTypes.map((et) => et.maxPrice))
13843
+ : undefined, fallbackImages: eventTypes.flatMap((eventType) => eventType.images || []), onClick: onCardClick, standalone: true }) }) })), u$2(VoucherPurchaseForm, { config: config, voucherConfig: voucherConfig, eventTypes: eventTypes, isOpen: isFormOpen, onClose: onFormClose, onSuccess: onSuccess, onError: onError, systemConfig: systemConfig, preselectedEventTypeId: preselectedEventTypeId, isLoadingEventTypes: isLoadingConfig }), isSuccess && voucherPurchaseResult && (u$2(VoucherSuccessModal, { isOpen: true, onClose: onSuccessModalClose, result: voucherPurchaseResult }))] }));
13844
+ }
13845
+
13764
13846
  // Helper function to preprocess markdown for underline support
13765
13847
  const preprocessMarkdown = (markdown) => {
13766
13848
  // Convert double underscores to HTML underline tags for React Markdown
@@ -13780,8 +13862,48 @@
13780
13862
  const rest = formatted.slice(0, -1).join(", ");
13781
13863
  return `${t("duration.optionally")} ${rest} ${t("duration.or")} ${last} ${unitPlural}`;
13782
13864
  }
13783
- 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, }) {
13784
13904
  const t = useTranslations();
13905
+ const { locale } = useLocale();
13906
+ const timezone = useTimezone();
13785
13907
  // State for details dialog
13786
13908
  const [detailsDialogOpen, setDetailsDialogOpen] = d$1(false);
13787
13909
  const [selectedEventTypeForDetails, setSelectedEventTypeForDetails] = d$1(null);
@@ -13891,7 +14013,7 @@
13891
14013
  display: "flex",
13892
14014
  flexDirection: "column",
13893
14015
  justifyContent: "space-between",
13894
- height: "400px",
14016
+ height: "490px",
13895
14017
  }, children: [u$2("div", { children: [u$2("h2", { className: "event-type-title", style: {
13896
14018
  fontSize: "clamp(1.1rem, 2.5vw, 24px)",
13897
14019
  fontWeight: 700,
@@ -13972,7 +14094,43 @@
13972
14094
  color: "var(--bw-text-color)",
13973
14095
  fontFamily: "var(--bw-font-family)",
13974
14096
  textAlign: "right",
13975
- }, 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: {
13976
14134
  display: "flex",
13977
14135
  justifyContent: "flex-end",
13978
14136
  alignItems: "center",
@@ -13987,7 +14145,6 @@
13987
14145
  backgroundColor: "var(--bw-surface-color)",
13988
14146
  padding: "12px",
13989
14147
  borderRadius: "var(--bw-border-radius)",
13990
- fontSize: "clamp(0.8rem, 2vw, 16px)",
13991
14148
  fontWeight: 600,
13992
14149
  fontFamily: "var(--bw-font-family)",
13993
14150
  display: "flex",
@@ -14000,7 +14157,7 @@
14000
14157
  }, children: t("button.moreDetails") })), isAvailable && (u$2("div", { style: {
14001
14158
  backgroundColor: "var(--bw-highlight-color)",
14002
14159
  color: "var(--bw-surface-color)",
14003
- padding: "12px 24px",
14160
+ padding: "12px 14px",
14004
14161
  borderRadius: "var(--bw-border-radius)",
14005
14162
  fontSize: "clamp(1rem, 2vw, 16px)",
14006
14163
  fontWeight: 600,
@@ -14658,6 +14815,172 @@
14658
14815
  }, children: "\u27F3" }), t("common.loading")] })) : (showAllButtonText) }) }))] }));
14659
14816
  }
14660
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
+
14661
14984
  const getThemeConfig = (theme = "generic") => {
14662
14985
  switch (theme) {
14663
14986
  case "christmas":
@@ -14917,8 +15240,8 @@
14917
15240
  };
14918
15241
  const checkboxContainerStyles = {
14919
15242
  position: "absolute",
14920
- top: "12px",
14921
- right: "12px",
15243
+ bottom: "12px",
15244
+ left: "12px",
14922
15245
  zIndex: 1,
14923
15246
  };
14924
15247
  const checkboxInnerStyles = {
@@ -15013,6 +15336,7 @@
15013
15336
  alignItems: "flex-end",
15014
15337
  marginTop: "8px",
15015
15338
  paddingTop: "8px",
15339
+ paddingBottom: "0px",
15016
15340
  borderTop: "1px solid var(--bw-border-color)",
15017
15341
  };
15018
15342
  const pricePerPersonStyles = {
@@ -15104,7 +15428,7 @@
15104
15428
  };
15105
15429
  const selectedTotal = calculateTotal();
15106
15430
  const selectedCount = selectedUpsells.length;
15107
- 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") })] }));
15108
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)] })] }))] }) }));
15109
15433
  }
15110
15434
 
@@ -15143,7 +15467,6 @@
15143
15467
  // Detect single event type mode and direct instance mode
15144
15468
  const isSingleEventTypeMode = !!config.eventTypeId && !config.categoryId && !config.eventTypeIds;
15145
15469
  const isDirectInstanceMode = !!config.eventInstanceId;
15146
- const isMultiEventListingContext = Boolean(config.categoryId || config.eventTypeIds?.length);
15147
15470
  // Voucher card integration logic:
15148
15471
  // - For standalone voucher mode: always show voucher card (it's the main content)
15149
15472
  // - For event listings (single or multi): show by default unless explicitly disabled
@@ -15153,6 +15476,8 @@
15153
15476
  : (config.voucherIntegration ?? (hasEventSelection && !isDirectInstanceMode));
15154
15477
  // Selection flow state
15155
15478
  const [currentStep, setCurrentStep] = d$1("eventTypes");
15479
+ // Tracks where to return when closing the booking form
15480
+ const bookingReturnStep = A$2("eventInstances");
15156
15481
  const [eventTypes, setEventTypes] = d$1([]);
15157
15482
  const [selectedEventType, setSelectedEventType] = d$1(null);
15158
15483
  const [eventInstances, setEventInstances] = d$1([]);
@@ -15165,6 +15490,9 @@
15165
15490
  // State for upcoming events (next-events view mode)
15166
15491
  const [upcomingEvents, setUpcomingEvents] = d$1([]);
15167
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);
15168
15496
  // New: sidebar open state for single event type mode
15169
15497
  const [sidebarOpen, setSidebarOpen] = d$1(false);
15170
15498
  // Booking flow state
@@ -15200,8 +15528,9 @@
15200
15528
  // Load voucher config if:
15201
15529
  // - Explicit voucher params are set
15202
15530
  // - OR voucherIntegration is explicitly set (even to true/false)
15203
- // - OR it's a multi-event listing context (may want to show voucher card)
15204
- if (!isVoucherModeRequested && !isMultiEventListingContext)
15531
+ // - OR it's an event listing context (single or multi) that may want to show voucher card
15532
+ const shouldLoadVoucherConfig = isVoucherModeRequested || hasEventSelection;
15533
+ if (!shouldLoadVoucherConfig)
15205
15534
  return;
15206
15535
  setIsLoadingVoucherConfig(true);
15207
15536
  try {
@@ -15254,10 +15583,10 @@
15254
15583
  const mergedConfig = {
15255
15584
  enabled: true,
15256
15585
  monetaryPresets: allowMonetaryVouchers
15257
- ? (presetFromValue ?? serverConfig.monetaryPresets ?? [2500, 5000, 10000, 15000, 20000])
15586
+ ? (presetFromValue ?? serverConfig.monetaryPresets ?? [2000, 5000, 10000, 15000, 20000, 25000, 30000, 40000, 50000])
15258
15587
  : [],
15259
- minAmount: serverConfig.minAmount || 1000,
15260
- maxAmount: serverConfig.maxAmount || 100000,
15588
+ minAmount: serverConfig.minAmount || 500,
15589
+ maxAmount: serverConfig.maxAmount || 1000000,
15261
15590
  allowMonetaryVouchers,
15262
15591
  allowEventVouchers,
15263
15592
  title: serverConfig.title,
@@ -15292,8 +15621,8 @@
15292
15621
  const initializeWidget = async () => {
15293
15622
  try {
15294
15623
  setIsLoading(true);
15295
- // Load voucher config in parallel if voucher mode is requested or it's a multi-event context
15296
- if (isVoucherModeRequested || isMultiEventListingContext) {
15624
+ // Load voucher config in parallel if voucher mode is requested or there's event selection
15625
+ if (isVoucherModeRequested || hasEventSelection) {
15297
15626
  void loadVoucherConfig();
15298
15627
  }
15299
15628
  // Direct instance selection (old behavior)
@@ -15314,6 +15643,11 @@
15314
15643
  await loadUpcomingEvents();
15315
15644
  return;
15316
15645
  }
15646
+ // Specials view mode: load special offers
15647
+ if (viewMode === "specials") {
15648
+ await loadSpecials();
15649
+ return;
15650
+ }
15317
15651
  // Single event type mode: load event type and instances, but don't open sidebar yet
15318
15652
  if (isSingleEventTypeMode) {
15319
15653
  await loadEventTypes();
@@ -15339,7 +15673,7 @@
15339
15673
  }
15340
15674
  };
15341
15675
  void initializeWidget();
15342
- }, [config, isVoucherModeRequested, hasEventSelection, isStandaloneVoucherMode, isMultiEventListingContext]);
15676
+ }, [config, isVoucherModeRequested, hasEventSelection, isStandaloneVoucherMode]);
15343
15677
  // Re-fetch translated content when locale changes (skip initial mount)
15344
15678
  const prevLocaleRef = A$2(locale);
15345
15679
  y$1(() => {
@@ -15537,6 +15871,45 @@
15537
15871
  setError(data.error || t("error.loadUpcomingEvents"));
15538
15872
  }
15539
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
+ };
15540
15913
  const loadEventInstances = async (eventTypeId) => {
15541
15914
  const response = await fetch(getApiUrl(config.apiBaseUrl, "/booking/event-instances"), {
15542
15915
  method: "POST",
@@ -15721,6 +16094,7 @@
15721
16094
  // Event instance selection handlers
15722
16095
  const handleEventInstanceSelect = async (eventInstance) => {
15723
16096
  setSelectedEventInstance(eventInstance);
16097
+ bookingReturnStep.current = "eventInstances";
15724
16098
  // Set default participant count for upsell calculations
15725
16099
  const defaultParticipantCount = 1;
15726
16100
  setTempParticipantCount(defaultParticipantCount);
@@ -15733,7 +16107,14 @@
15733
16107
  if (availableUpsells.length > 0) {
15734
16108
  // Show upsells step
15735
16109
  setUpsells(availableUpsells);
15736
- 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);
15737
16118
  setCurrentStep("upsells");
15738
16119
  setIsLoadingUpsells(false);
15739
16120
  return; // Don't proceed to booking yet
@@ -15764,7 +16145,7 @@
15764
16145
  setEventInstances([]);
15765
16146
  };
15766
16147
  const handleBackToEventInstances = () => {
15767
- setCurrentStep("eventInstances");
16148
+ setCurrentStep(bookingReturnStep.current);
15768
16149
  setSelectedEventInstance(null);
15769
16150
  setEventDetails(null);
15770
16151
  };
@@ -15798,8 +16179,7 @@
15798
16179
  }
15799
16180
  };
15800
16181
  const handleUpsellsBack = () => {
15801
- // Go back to event instance selection
15802
- setCurrentStep("eventInstances");
16182
+ setCurrentStep(bookingReturnStep.current);
15803
16183
  setSelectedUpsells([]);
15804
16184
  setUpsells([]);
15805
16185
  };
@@ -15834,10 +16214,36 @@
15834
16214
  setError(errorMessage);
15835
16215
  config.onError?.(errorMessage);
15836
16216
  };
15837
- 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)
15838
16241
  const upcomingEvent = upcomingEvents.find((event) => event.id === eventInstanceId);
15839
- if (upcomingEvent) {
15840
- 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
+ ? {
15841
16247
  id: upcomingEvent.id,
15842
16248
  name: upcomingEvent.name,
15843
16249
  startTime: upcomingEvent.startTime,
@@ -15851,13 +16257,63 @@
15851
16257
  bookingOpen: upcomingEvent.bookingOpen,
15852
16258
  ...(upcomingEvent.deposit !== undefined && { deposit: upcomingEvent.deposit }),
15853
16259
  ...(upcomingEvent.notes !== undefined && { notes: upcomingEvent.notes }),
15854
- };
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) {
15855
16277
  setSelectedEventInstance(eventInstance);
15856
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
15857
16314
  setCurrentStep("booking");
15858
16315
  setShouldRenderBookingForm(true);
15859
16316
  setIsLoadingEventDetails(true);
15860
- setError(null);
15861
16317
  try {
15862
16318
  await loadEventDetails(eventInstanceId);
15863
16319
  }
@@ -16014,6 +16470,31 @@
16014
16470
  window.history.replaceState({}, "", url.toString());
16015
16471
  }, config: config, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (u$2(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16016
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
+ }
16017
16498
  if (viewMode === "next-events" && !showingPreview && currentStep === "eventInstances") {
16018
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: () => {
16019
16500
  setShowingPreview(true);
@@ -16084,14 +16565,7 @@
16084
16565
  }, config: config, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (u$2(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16085
16566
  }
16086
16567
  // Cards mode (default) - show event type selection with optional voucher card
16087
- 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 })), voucherConfig?.enabled && voucherCardIntegrationEnabled && isStandaloneVoucherMode && (u$2("div", { style: { padding: hasEventSelection ? "0 0 24px 0" : "0" }, children: u$2("div", { style: {
16088
- display: "grid",
16089
- gridTemplateColumns: "minmax(350px, 500px)",
16090
- gap: "24px",
16091
- justifyContent: "center",
16092
- }, children: u$2(VoucherPurchaseCard, { config: voucherConfig, minEventPrice: voucherEventTypes.length > 0
16093
- ? Math.min(...voucherEventTypes.map((et) => et.maxPrice))
16094
- : undefined, fallbackImages: voucherEventTypes.flatMap((eventType) => eventType.images || []), onClick: handleVoucherCardClick, standalone: true }) }) })), 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: {
16095
16569
  display: "inline-block",
16096
16570
  width: "32px",
16097
16571
  height: "32px",
@@ -16144,19 +16618,17 @@
16144
16618
  url.searchParams.delete("mollie_payment_id");
16145
16619
  url.searchParams.delete("mollie_status");
16146
16620
  window.history.replaceState({}, "", url.toString());
16147
- }, config: config, onError: setError, paymentIntentId: successPaymentId }), isSuccess && voucherPurchaseResult && (u$2(VoucherSuccessModal, { isOpen: true, onClose: () => {
16621
+ }, config: config, onError: setError, paymentIntentId: successPaymentId }), u$2(VoucherIntegration, { config: config, voucherConfig: voucherConfig, eventTypes: voucherEventTypes, systemConfig: systemConfig, isFormOpen: isVoucherFormOpen, isLoadingConfig: isLoadingVoucherConfig, preselectedEventTypeId: preselectedVoucherEventTypeId, voucherPurchaseResult: voucherPurchaseResult, isSuccess: isSuccess, showStandaloneCard: false, onCardClick: handleVoucherCardClick, onFormClose: handleVoucherFormClose, onSuccess: handleVoucherSuccess, onError: handleVoucherError, onSuccessModalClose: () => {
16148
16622
  setIsSuccess(false);
16149
16623
  setVoucherPurchaseResult(null);
16150
16624
  const url = new URL(window.location.href);
16151
- // Clean up Stripe params
16152
16625
  url.searchParams.delete("payment_intent");
16153
16626
  url.searchParams.delete("payment_intent_client_secret");
16154
16627
  url.searchParams.delete("redirect_status");
16155
- // Clean up Mollie params
16156
16628
  url.searchParams.delete("mollie_payment_id");
16157
16629
  url.searchParams.delete("mollie_status");
16158
16630
  window.history.replaceState({}, "", url.toString());
16159
- }, result: voucherPurchaseResult })), voucherConfig?.enabled && (u$2(VoucherPurchaseForm, { config: config, voucherConfig: voucherConfig, eventTypes: voucherEventTypes, isOpen: isVoucherFormOpen, onClose: handleVoucherFormClose, onSuccess: handleVoucherSuccess, onError: handleVoucherError, systemConfig: systemConfig, preselectedEventTypeId: preselectedVoucherEventTypeId, isLoadingEventTypes: isLoadingVoucherConfig }))] }), showPromoDialog && config.promo && (u$2(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16631
+ } })] }), showPromoDialog && config.promo && (u$2(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16160
16632
  }
16161
16633
  function UniversalBookingWidget(props) {
16162
16634
  const [languagePolicy, setLanguagePolicy] = d$1(null);
@@ -16203,7 +16675,7 @@
16203
16675
  }
16204
16676
  }
16205
16677
 
16206
- 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}}";
16207
16679
  styleInject(css_248z);
16208
16680
 
16209
16681
  // Export init function for vanilla JS usage with Preact