@riverbankcms/sdk 0.139.0 → 0.140.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 (196) hide show
  1. package/README.md +1 -1
  2. package/dist/{PreviewEditorSidebar-BDeenhi3.mjs → PreviewEditorSidebar-CUyTzd5z.mjs} +4 -4
  3. package/dist/{PreviewEditorUI-DSRhgjF5.mjs → PreviewEditorUI-Agkw4v5i.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-D2K8GLUG.mjs → PreviewQueryProvider-CN0ewic5.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-CL7wSnYu.mjs → SdkPreviewModeRuntime-DdbeAdS8.mjs} +22 -8
  6. package/dist/{SiteChromeCustomizeContext-BhDn-5ir.mjs → SiteChromeCustomizeContext-CqGOz-Kv.mjs} +2053 -1110
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +165 -165
  8. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +212 -212
  9. package/dist/_dts/api/src/accessAdmin.d.ts +74 -104
  10. package/dist/_dts/api/src/aiEndpoints.d.ts +5 -1
  11. package/dist/_dts/api/src/authSubmission.d.ts +46 -0
  12. package/dist/_dts/api/src/billing.d.ts +8 -4
  13. package/dist/_dts/api/src/billingEndpointDefinitions.d.ts +23 -0
  14. package/dist/_dts/api/src/billingEndpointTypes.d.ts +26 -0
  15. package/dist/_dts/api/src/blocks.d.ts +2 -0
  16. package/dist/_dts/api/src/bookingRecords.d.ts +1 -2
  17. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +8 -1
  18. package/dist/_dts/api/src/communications.d.ts +0 -1
  19. package/dist/_dts/api/src/contentRuntime.d.ts +8 -3
  20. package/dist/_dts/api/src/endpoints.d.ts +93 -64
  21. package/dist/_dts/api/src/event-destination-policy.d.ts +2 -1
  22. package/dist/_dts/api/src/footerSettings.d.ts +9 -6
  23. package/dist/_dts/api/src/index.d.ts +5 -6
  24. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
  25. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  26. package/dist/_dts/api/src/mailingListIntegration.d.ts +8 -2
  27. package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +1 -1
  28. package/dist/_dts/api/src/navigation/types.d.ts +1 -1
  29. package/dist/_dts/api/src/onboarding/confirmationResend.d.ts +25 -0
  30. package/dist/_dts/api/src/onboarding/surfaceData.d.ts +32 -32
  31. package/dist/_dts/api/src/publicBookingAvailabilityEndpointDefinitions.d.ts +8 -0
  32. package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +1 -0
  33. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +11 -3
  34. package/dist/_dts/api/src/publicExperience/sharedTypes.d.ts +3 -29
  35. package/dist/_dts/api/src/publicOnboardingAttemptEndpointDefinitions.d.ts +65 -0
  36. package/dist/_dts/api/src/saveOutcome.d.ts +20 -0
  37. package/dist/_dts/api/src/sdkContracts.d.ts +3 -22
  38. package/dist/_dts/api/src/sdkPushContracts.d.ts +18 -0
  39. package/dist/_dts/api/src/sdkThemeWire.d.ts +44 -44
  40. package/dist/_dts/api/src/settings/permissions.d.ts +12 -0
  41. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +9 -5
  42. package/dist/_dts/api/src/siteOnboarding.d.ts +2 -9
  43. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +2 -4
  44. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +3 -1
  45. package/dist/_dts/api/src/siteSettings.d.ts +20 -7
  46. package/dist/_dts/api/src/types.d.ts +77 -77
  47. package/dist/_dts/api/src/wholeSeriesRuns.d.ts +2 -37
  48. package/dist/_dts/billing/src/membership/index.d.ts +3 -0
  49. package/dist/_dts/billing/src/plans/types.d.ts +3 -0
  50. package/dist/_dts/billing/src/site-arrangements.d.ts +14 -3
  51. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +16 -4
  52. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +2 -0
  53. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +5 -0
  54. package/dist/_dts/blocks/src/portal/types.d.ts +2 -4
  55. package/dist/_dts/blocks/src/portal/waitlist-types.d.ts +35 -0
  56. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +2 -0
  57. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +42 -0
  58. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -0
  59. package/dist/_dts/blocks/src/system/data/index.d.ts +2 -2
  60. package/dist/_dts/blocks/src/system/data/prefetchBlockData.d.ts +2 -1
  61. package/dist/_dts/blocks/src/system/data/types.d.ts +9 -0
  62. package/dist/_dts/blocks/src/system/registry.d.ts +1 -0
  63. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +0 -28
  64. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  65. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +7 -3
  66. package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +1 -1
  67. package/dist/_dts/blocks/src/system/runtime/api/types/waitlist-claims.d.ts +7 -2
  68. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +30 -6
  69. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +15 -3
  70. package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +43 -0
  71. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +1 -2
  72. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +2 -0
  73. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.d.ts +14 -0
  74. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +56 -0
  75. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +6 -8
  76. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.d.ts +8 -0
  77. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +8 -7
  78. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +10 -2
  79. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.d.ts +18 -0
  80. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.client.d.ts +1 -1
  81. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +24 -6
  82. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +4 -2
  83. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +6 -0
  84. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +1 -0
  85. package/dist/_dts/blocks/src/system/runtime/resolver.d.ts +1 -0
  86. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -6
  87. package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +2 -2
  88. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.d.ts +2 -0
  89. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -0
  90. package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +27 -4
  91. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +2 -1
  92. package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +3 -1
  93. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +3 -0
  94. package/dist/_dts/core/src/branded.d.ts +0 -8
  95. package/dist/_dts/core/src/index.d.ts +1 -0
  96. package/dist/_dts/core/src/mailing-list-setup-parser.d.ts +1 -1
  97. package/dist/_dts/core/src/mailing-list-setup.d.ts +14 -1
  98. package/dist/_dts/core/src/mailing-list-submission.d.ts +7 -27
  99. package/dist/_dts/core/src/participants.d.ts +2 -29
  100. package/dist/_dts/core/src/public-experience.d.ts +4 -0
  101. package/dist/_dts/core/src/public-profile.d.ts +27 -1
  102. package/dist/_dts/core/src/site-route-target.d.ts +9 -2
  103. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +293 -606
  104. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListGlobalSettingsSummary.d.ts +10 -0
  105. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListTargetingField.d.ts +3 -2
  106. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/context.d.ts +3 -2
  107. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/loaders.d.ts +3 -2
  108. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/targetingState.d.ts +19 -0
  109. package/dist/_dts/sdk/src/public-api/contracts.d.ts +14 -20
  110. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -0
  111. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -0
  112. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +7 -1
  113. package/dist/_dts/sdk/src/rendering/helpers/templateContent.d.ts +1 -0
  114. package/dist/_dts/sdk/src/version.d.ts +1 -1
  115. package/dist/_dts/theme-core/src/accordions/types.d.ts +3 -3
  116. package/dist/_dts/theme-core/src/cards/types.d.ts +21 -21
  117. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  118. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +8 -2
  119. package/dist/_dts/theme-core/src/header/legacyHeaderVariant.d.ts +2 -2
  120. package/dist/_dts/theme-core/src/inputs/types.d.ts +2 -2
  121. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +54 -54
  122. package/dist/_dts/theme-core/src/runtime/buildThemeRuntimeFromBridge.d.ts +1 -4
  123. package/dist/_dts/theme-core/src/schema.d.ts +84 -84
  124. package/dist/_dts/theme-core/src/shared/componentStyles.d.ts +1 -1
  125. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  126. package/dist/_dts/theme-core/src/surfaces/foregroundInteraction.d.ts +77 -0
  127. package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
  128. package/dist/_dts/theme-core/src/typography/generateTypographyCss.d.ts +2 -2
  129. package/dist/_dts/ui/src/lib/use-delayed-flag.d.ts +9 -0
  130. package/dist/_dts/ui/src/pending-button.d.ts +10 -0
  131. package/dist/client/{BookingConsentAgreement-CZvTDtsK.mjs → BookingConsentAgreement-CuKa82V4.mjs} +4 -4
  132. package/dist/client/{DiscountCodeDisclosure-D-DsLCMU.mjs → DiscountCodeDisclosure-BbYieKWB.mjs} +1 -1
  133. package/dist/client/{EventCombined.client-dWqgd5ZO.mjs → EventCombined.client-LTfR1Aby.mjs} +6 -6
  134. package/dist/client/{EventListing.client-BMRa9IYp.mjs → EventListing.client-DUHpYSuo.mjs} +2 -2
  135. package/dist/client/{LeafletStaticMap-D21W9kBZ.mjs → LeafletStaticMap-CHRupL6m.mjs} +1 -1
  136. package/dist/client/{accordion-FxF_ta47.mjs → accordion-6HiIFxNL.mjs} +1 -1
  137. package/dist/client/{bookingForm-YnwW4TGw.mjs → bookingForm-Dlmid43H.mjs} +7 -7
  138. package/dist/client/bookings.mjs +325 -140
  139. package/dist/client/{carousel-vng7fFT5.mjs → carousel-DmkZRRq_.mjs} +2 -2
  140. package/dist/client/{carousel.client-59G_WMr4.mjs → carousel.client-DQTjCVQT.mjs} +1 -1
  141. package/dist/client/{cart-DEPDsjNk.mjs → cart-CIC24330.mjs} +3 -3
  142. package/dist/client/{checkout-CZRWu9rW.mjs → checkout-D1Zw9imo.mjs} +3 -3
  143. package/dist/client/{checkoutUrls-BuseL0dw.mjs → checkoutUrls-FL6lRkrt.mjs} +1 -1
  144. package/dist/client/client.mjs +1717 -882
  145. package/dist/client/{colorStyles-CrxJrPjJ.mjs → colorStyles-3013aRAY.mjs} +3 -1
  146. package/dist/client/{context-DvU_WUmd.mjs → context-Cy1OayHx.mjs} +6 -19
  147. package/dist/client/{dates-wnPMiRl5.mjs → dates-aDcfoLHr.mjs} +2 -2
  148. package/dist/client/{eventCalendar-BA3Q5L15.mjs → eventCalendar-FQxMPAjf.mjs} +8 -8
  149. package/dist/client/{eventCombined-51wgR-1R.mjs → eventCombined-Dr3ac6Hb.mjs} +3 -3
  150. package/dist/client/{eventDetails-modaetpm.mjs → eventDetails-D-AzUHFQ.mjs} +4 -4
  151. package/dist/client/{eventListing-D8t2J3Kv.mjs → eventListing-B3XxBf3i.mjs} +3 -3
  152. package/dist/client/{eventRegistration-CYqtkCE_.mjs → eventRegistration-I6EaokFD.mjs} +500 -152
  153. package/dist/client/{form-CBKXN5In.mjs → form-BbWckVWY.mjs} +3 -3
  154. package/dist/client/{headerSection-DylDqNrs.mjs → headerSection-C9qU4Y7x.mjs} +2 -2
  155. package/dist/client/hooks.mjs +445 -180
  156. package/dist/client/{locationMap-CvWrG0vZ.mjs → locationMap-CLCShvlG.mjs} +3 -3
  157. package/dist/client/{media-BOHuueS5.mjs → media-DHpfFwd3.mjs} +1 -1
  158. package/dist/client/{newsletterForm-Btwk70zw.mjs → newsletterForm-Briukxzi.mjs} +130 -87
  159. package/dist/client/{pricing-Uzw-GQ6Y.mjs → pricing-Copadu-2.mjs} +1 -1
  160. package/dist/client/{productDetail-JLcUYKnd.mjs → productDetail-oujlRd-r.mjs} +3 -3
  161. package/dist/client/{productList-FM0cbUzj.mjs → productList-BRiIRUcd.mjs} +3 -3
  162. package/dist/client/{propsDecoder-DYzafZb2.mjs → propsDecoder-CB2KS_ko.mjs} +130 -24
  163. package/dist/client/rendering/client.mjs +911 -400
  164. package/dist/client/rendering/islands.mjs +19 -19
  165. package/dist/client/rendering.mjs +1696 -818
  166. package/dist/client/{scrollToBlock-CvXszexS.mjs → scrollToBlock-B1IS1_ua.mjs} +1 -1
  167. package/dist/client/{shop-BIcjvy5a.mjs → shop-Vn6yNFED.mjs} +6 -6
  168. package/dist/client/{shop-commerce-BZQsy7xw.mjs → shop-commerce-BVTqipYp.mjs} +7 -7
  169. package/dist/client/{shop-commerce-store-D5V7XAb5.mjs → shop-commerce-store-BVnJVy7v.mjs} +1 -1
  170. package/dist/client/{shopShared-DowkXevB.mjs → shopShared-COIeK77T.mjs} +4 -4
  171. package/dist/client/{useEventFilters-oMoTw_JE.mjs → useEventFilters-DzIUcS9n.mjs} +7 -7
  172. package/dist/preview-next/before-render.mjs +119 -64
  173. package/dist/preview-next/client/runtime.mjs +4 -4
  174. package/dist/preview-next/keepAlive.mjs +119 -64
  175. package/dist/preview-next/middleware.mjs +119 -64
  176. package/dist/{previewAuthStore-COUyAKaX.mjs → previewAuthStore-Gjb6r6vz.mjs} +119 -64
  177. package/dist/{sdk-runtime-D4k2LSGF.mjs → sdk-runtime-CnCLvZRv.mjs} +2 -2
  178. package/dist/{separator-UGtpag4Z.mjs → separator-DKDRJ1oH.mjs} +1 -1
  179. package/dist/server/components.mjs +787 -323
  180. package/dist/server/config-validation.mjs +328 -79
  181. package/dist/server/config.mjs +332 -83
  182. package/dist/server/data.mjs +441 -180
  183. package/dist/server/index.mjs +126 -66
  184. package/dist/server/next.mjs +1031 -595
  185. package/dist/server/page-converter.mjs +183 -74
  186. package/dist/server/prebuild.mjs +1 -1
  187. package/dist/server/rendering/server.mjs +1068 -592
  188. package/dist/server/rendering.mjs +802 -324
  189. package/dist/server/routing.mjs +506 -214
  190. package/dist/server/server.mjs +468 -244
  191. package/dist/server/theme-bridge.mjs +433 -100
  192. package/dist/server/theme.mjs +8 -2
  193. package/dist/styles/index.css +237 -43
  194. package/package.json +1 -1
  195. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionCompactRow.d.ts +0 -29
  196. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionList.d.ts +0 -13
@@ -634,7 +634,7 @@ function parseUuidBrand$1(value, unsafeConstructor) {
634
634
  if (!UUID_PATTERN$3.test(normalized)) return err$3({ kind: "invalid_uuid" });
635
635
  return ok$3(unsafeConstructor(normalized));
636
636
  }
637
- var UUID_PATTERN$3, unsafeAsSiteId, unsafeAsApiKeyId, unsafeAsEventOfferingId, unsafeAsEventSeriesId, unsafeAsMediaAssetId, unsafeAsStorageBucketName, unsafeAsStoragePath, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, unsafeAsUserId, unsafeAsFormId, unsafeAsPassId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, unsafeAsAppointmentResourceId, parseSiteId, parseApiKeyId, parseEventOfferingId, parseUserId, parseEventSeriesId;
637
+ var UUID_PATTERN$3, unsafeAsSiteId, unsafeAsApiKeyId, unsafeAsEventOfferingId, unsafeAsEventSeriesId, unsafeAsMediaAssetId, unsafeAsStorageBucketName, unsafeAsStoragePath, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, unsafeAsUserId, unsafeAsFormId, unsafeAsPassId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, unsafeAsAppointmentResourceId, unsafeAsContentVersionId, parseSiteId, parseApiKeyId, parseEventOfferingId, parseUserId, parseContentVersionId, parseEventSeriesId;
638
638
  var init_branded = __esmMin((() => {
639
639
  init_result$1();
640
640
  UUID_PATTERN$3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -653,10 +653,12 @@ var init_branded = __esmMin((() => {
653
653
  unsafeAsCustomerPassId = (id) => id;
654
654
  unsafeAsAppointmentServiceId = (id) => id;
655
655
  unsafeAsAppointmentResourceId = (id) => id;
656
+ unsafeAsContentVersionId = (id) => id;
656
657
  parseSiteId = (value) => parseUuidBrand$1(value, unsafeAsSiteId);
657
658
  parseApiKeyId = (value) => parseUuidBrand$1(value, unsafeAsApiKeyId);
658
659
  parseEventOfferingId = (value) => parseUuidBrand$1(value, unsafeAsEventOfferingId);
659
660
  parseUserId = (value) => parseUuidBrand$1(value, unsafeAsUserId);
661
+ parseContentVersionId = (value) => parseUuidBrand$1(value, unsafeAsContentVersionId);
660
662
  parseEventSeriesId = (value) => parseUuidBrand$1(value, unsafeAsEventSeriesId);
661
663
  }));
662
664
  //#endregion
@@ -1009,7 +1011,7 @@ function parseEventPageSurfaceDestinationMode(value) {
1009
1011
  return value === "cms-managed" || value === "system-managed" ? value : void 0;
1010
1012
  }
1011
1013
  function parseEventPageSurfaceSubject(value) {
1012
- if (!isRecord$43(value)) return err$3({ kind: "notObject" });
1014
+ if (!isRecord$44(value)) return err$3({ kind: "notObject" });
1013
1015
  switch (value.kind) {
1014
1016
  case "eventSeries": {
1015
1017
  const eventSeriesId = parseEventSeriesId(value.eventSeriesId);
@@ -1064,7 +1066,7 @@ function parseEventSeriesIdList(values) {
1064
1066
  }
1065
1067
  return ok$3(parsed);
1066
1068
  }
1067
- function isRecord$43(value) {
1069
+ function isRecord$44(value) {
1068
1070
  return typeof value === "object" && value !== null && !Array.isArray(value);
1069
1071
  }
1070
1072
  var init_event_page_surface_subject = __esmMin((() => {
@@ -1556,7 +1558,6 @@ var init_assertNever$1 = __esmMin((() => {
1556
1558
  init_assert_never();
1557
1559
  }));
1558
1560
  var init_participants = __esmMin((() => {
1559
- init_branded();
1560
1561
  init_result$1();
1561
1562
  init_string();
1562
1563
  }));
@@ -1568,9 +1569,10 @@ var init_public_profile = __esmMin((() => {
1568
1569
  init_public_url_validation();
1569
1570
  init_result$1();
1570
1571
  }));
1572
+ var init_public_experience = __esmMin((() => {}));
1571
1573
  //#endregion
1572
1574
  //#region ../core/src/rich-text.ts
1573
- function isRecord$41(value) {
1575
+ function isRecord$42(value) {
1574
1576
  return typeof value === "object" && value !== null && !Array.isArray(value);
1575
1577
  }
1576
1578
  function hasOnlyKeys(value, allowed) {
@@ -1581,10 +1583,10 @@ function isDenseArrayOf(value, predicate) {
1581
1583
  return true;
1582
1584
  }
1583
1585
  function isTipTapMark(value) {
1584
- return isRecord$41(value) && hasOnlyKeys(value, markKeys) && typeof value.type === "string" && value.type.length > 0 && (value.attrs === void 0 || isRecord$41(value.attrs));
1586
+ return isRecord$42(value) && hasOnlyKeys(value, markKeys) && typeof value.type === "string" && value.type.length > 0 && (value.attrs === void 0 || isRecord$42(value.attrs));
1585
1587
  }
1586
1588
  function isTipTapNode(value) {
1587
- if (!isRecord$41(value) || !hasOnlyKeys(value, nodeKeys) || typeof value.type !== "string" || value.type.length === 0 || value.type === "doc" || value.attrs !== void 0 && !isRecord$41(value.attrs) || value.marks !== void 0 && (!Array.isArray(value.marks) || !isDenseArrayOf(value.marks, isTipTapMark)) || value.content !== void 0 && (!Array.isArray(value.content) || !isDenseArrayOf(value.content, isTipTapNode))) return false;
1589
+ if (!isRecord$42(value) || !hasOnlyKeys(value, nodeKeys) || typeof value.type !== "string" || value.type.length === 0 || value.type === "doc" || value.attrs !== void 0 && !isRecord$42(value.attrs) || value.marks !== void 0 && (!Array.isArray(value.marks) || !isDenseArrayOf(value.marks, isTipTapMark)) || value.content !== void 0 && (!Array.isArray(value.content) || !isDenseArrayOf(value.content, isTipTapNode))) return false;
1588
1590
  if (value.type === "text") return typeof value.text === "string" && value.text.length > 0 && value.content === void 0;
1589
1591
  return value.text === void 0;
1590
1592
  }
@@ -1612,12 +1614,18 @@ function parsePositiveInteger(value) {
1612
1614
  function parseNewsletterListId(value) {
1613
1615
  return parseTrimmedMatchingString(value, UUID_PATTERN$2);
1614
1616
  }
1617
+ function parseMailchimpAccountId(value) {
1618
+ return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
1619
+ }
1615
1620
  function parseMailchimpAudienceId$1(value) {
1616
1621
  return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
1617
1622
  }
1618
1623
  function parseMailchimpInterestId(value) {
1619
1624
  return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
1620
1625
  }
1626
+ function parseBrevoAccountId(value) {
1627
+ return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
1628
+ }
1621
1629
  function parseBrevoListId(value) {
1622
1630
  return parsePositiveInteger(value);
1623
1631
  }
@@ -1629,10 +1637,10 @@ var init_mailing_list_identifiers = __esmMin((() => {
1629
1637
  //#endregion
1630
1638
  //#region ../core/src/mailing-list-targeting-parser.ts
1631
1639
  function parseMailingListPlacementTargeting(value) {
1632
- if (!isRecord$40(value)) return targetingError("shape");
1640
+ if (!isRecord$41(value)) return targetingError("shape");
1633
1641
  if (value.mode === "default") return ok$3({ mode: "default" });
1634
1642
  if (value.mode !== "custom") return targetingError("mode");
1635
- if (!isRecord$40(value.selection)) return targetingError("selection");
1643
+ if (!isRecord$41(value.selection)) return targetingError("selection");
1636
1644
  switch (value.provider) {
1637
1645
  case "native": return parseNativeTargeting(value.selection);
1638
1646
  case "brevo": return parseBrevoTargeting(value.selection);
@@ -1641,7 +1649,7 @@ function parseMailingListPlacementTargeting(value) {
1641
1649
  }
1642
1650
  }
1643
1651
  function parseMailingListVisitorSelection(value) {
1644
- if (!isRecord$40(value)) return visitorSelectionError("shape");
1652
+ if (!isRecord$41(value)) return visitorSelectionError("shape");
1645
1653
  switch (value.provider) {
1646
1654
  case "native": {
1647
1655
  const topicIds = parseVisitorIds(value.topicIds, parseNewsletterListId);
@@ -1774,7 +1782,7 @@ function parseVisitorIds(value, parseId) {
1774
1782
  }
1775
1783
  return parsed;
1776
1784
  }
1777
- function isRecord$40(value) {
1785
+ function isRecord$41(value) {
1778
1786
  return typeof value === "object" && value !== null && !Array.isArray(value);
1779
1787
  }
1780
1788
  function targetingError(field) {
@@ -1823,7 +1831,36 @@ var init_footer_navigation_layout = __esmMin((() => {}));
1823
1831
  //#endregion
1824
1832
  //#region ../core/src/footer-composition-types.ts
1825
1833
  var init_footer_composition_types = __esmMin((() => {}));
1826
- var init_mailing_list_setup = __esmMin((() => {}));
1834
+ //#endregion
1835
+ //#region ../core/src/mailing-list-setup.ts
1836
+ function isRecord$38(value) {
1837
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1838
+ }
1839
+ function parseMailingListProviderScope(value) {
1840
+ if (!isRecord$38(value)) return err$3("invalid_mailing_list_provider_scope");
1841
+ if (value.provider === "native") return ok$3({ provider: "native" });
1842
+ if (value.provider === "brevo") {
1843
+ const accountId = parseBrevoAccountId(value.accountId);
1844
+ return accountId !== null ? ok$3({
1845
+ provider: "brevo",
1846
+ accountId
1847
+ }) : err$3("invalid_mailing_list_provider_scope");
1848
+ }
1849
+ if (value.provider === "mailchimp") {
1850
+ const accountId = parseMailchimpAccountId(value.accountId);
1851
+ return accountId !== null ? ok$3({
1852
+ provider: "mailchimp",
1853
+ accountId
1854
+ }) : err$3("invalid_mailing_list_provider_scope");
1855
+ }
1856
+ return err$3("invalid_mailing_list_provider_scope");
1857
+ }
1858
+ var DEFAULT_MAILING_LIST_SUCCESS_MESSAGE;
1859
+ var init_mailing_list_setup = __esmMin((() => {
1860
+ init_mailing_list_identifiers();
1861
+ init_result$1();
1862
+ DEFAULT_MAILING_LIST_SUCCESS_MESSAGE = "Thanks — you're on the list.";
1863
+ }));
1827
1864
  //#endregion
1828
1865
  //#region ../core/src/mailing-list-setup-parser.ts
1829
1866
  function parseMailingListGlobalForm(value) {
@@ -1833,12 +1870,15 @@ function parseMailingListGlobalForm(value) {
1833
1870
  if (typeof value.includeOptionalPhone !== "boolean") return formError("includeOptionalPhone");
1834
1871
  const buttonLabel = parseRequiredString(value.buttonLabel);
1835
1872
  if (buttonLabel === null) return formError("buttonLabel");
1873
+ const successMessage = parseRequiredString(value.successMessage);
1874
+ if (successMessage === null) return formError("successMessage");
1836
1875
  const privacyNote = parseOptionalString(value.privacyNote);
1837
1876
  if (privacyNote === void 0) return formError("privacyNote");
1838
1877
  return ok$3({
1839
1878
  fields,
1840
1879
  includeOptionalPhone: value.includeOptionalPhone,
1841
1880
  buttonLabel,
1881
+ successMessage,
1842
1882
  privacyNote
1843
1883
  });
1844
1884
  }
@@ -2060,11 +2100,17 @@ function parseMailingListSignedSourceToken(value) {
2060
2100
  const parsed = typeof value === "string" ? value.trim() : "";
2061
2101
  return /^[A-Za-z0-9._~-]{16,1000}$/u.test(parsed) ? parsed : null;
2062
2102
  }
2063
- function buildMailingListSignupBlockSourceRef(blockId) {
2064
- const parsed = parseMailingListBlockId(blockId);
2065
- return parsed !== null ? {
2103
+ function parseMailingListContentVersionId(value) {
2104
+ const parsed = parseContentVersionId(value);
2105
+ return parsed.ok ? parsed.value : null;
2106
+ }
2107
+ function buildMailingListSignupBlockSourceRef(blockId, contentVersionId) {
2108
+ const parsedBlockId = parseMailingListBlockId(blockId);
2109
+ const parsedContentVersionId = parseMailingListContentVersionId(contentVersionId);
2110
+ return parsedBlockId !== null && parsedContentVersionId !== null ? {
2066
2111
  tag: "block_ref",
2067
- blockId: parsed
2112
+ blockId: parsedBlockId,
2113
+ contentVersionId: parsedContentVersionId
2068
2114
  } : null;
2069
2115
  }
2070
2116
  var init_mailing_list_submission = __esmMin((() => {
@@ -2635,6 +2681,7 @@ var init_src$2 = __esmMin((() => {
2635
2681
  init_participant_identity();
2636
2682
  init_public_url_validation();
2637
2683
  init_public_profile();
2684
+ init_public_experience();
2638
2685
  init_rich_text();
2639
2686
  init_footer_composition();
2640
2687
  init_footer_navigation_layout();
@@ -5707,9 +5754,490 @@ var init_classNames = __esmMin((() => {
5707
5754
  init_types$14();
5708
5755
  }));
5709
5756
  //#endregion
5757
+ //#region ../theme-core/src/tokens/tokens.ts
5758
+ /**
5759
+ * Project the expanded semantic palette into the token buckets consumed by
5760
+ * runtime transforms. Keep this mapping shared by full themes and the
5761
+ * tokens-only hosted-booking runtime so the two paths cannot drift.
5762
+ */
5763
+ function buildThemeTokens(palette) {
5764
+ const tokens = cloneThemeTokens(defaultThemeTokens);
5765
+ const paletteStrings = {};
5766
+ for (const [key, value] of Object.entries(palette)) if (typeof value === "string" && value.trim().length > 0) paletteStrings[key] = value;
5767
+ tokens.palette = paletteStrings;
5768
+ const resolveColor = (...keys) => {
5769
+ for (const key of keys) {
5770
+ const value = paletteStrings[key];
5771
+ if (value) return value;
5772
+ }
5773
+ };
5774
+ const assignColor = (token, ...keys) => {
5775
+ const value = resolveColor(...keys);
5776
+ if (value) tokens.color[token] = value;
5777
+ };
5778
+ assignColor("background/base", "background", "surface", "primary-50");
5779
+ assignColor("background/elevated", "surface", "background");
5780
+ assignColor("surface/base", "surface", "background");
5781
+ assignColor("surface/subtle", "neutral-100", "surface", "background");
5782
+ assignColor("surface/inverted", "neutral-900", "text", "primary-900");
5783
+ assignColor("content/primary", "text", "body", "neutral-900");
5784
+ assignColor("content/secondary", "mutedText", "secondary", "neutral-600");
5785
+ assignColor("accent/primary", "primary", "accent");
5786
+ assignColor("accent/secondary", "accent", "secondary", "primary-400");
5787
+ assignColor("border/base", "border", "neutral-300");
5788
+ return tokens;
5789
+ }
5790
+ function cloneThemeTokens(source) {
5791
+ return JSON.parse(JSON.stringify(source));
5792
+ }
5793
+ var defaultThemeTokens;
5794
+ var init_tokens$1 = __esmMin((() => {
5795
+ defaultThemeTokens = {
5796
+ color: {
5797
+ "background/base": "#ffffff",
5798
+ "background/elevated": "#f5f5f5",
5799
+ "surface/base": "#ffffff",
5800
+ "surface/subtle": "#f9f9fb",
5801
+ "surface/inverted": "#111111",
5802
+ "content/primary": "#111111",
5803
+ "content/secondary": "#3f3f46",
5804
+ "accent/primary": "#2563eb",
5805
+ "accent/secondary": "#1d4ed8",
5806
+ "border/base": "#e5e7eb"
5807
+ },
5808
+ typography: {
5809
+ "display/hero": {
5810
+ fontSize: "clamp(48px, 8vw, 96px)",
5811
+ lineHeight: "1.05",
5812
+ fontWeight: "700"
5813
+ },
5814
+ "display/section": {
5815
+ fontSize: "clamp(40px, 6vw, 72px)",
5816
+ lineHeight: "1.1",
5817
+ fontWeight: "700"
5818
+ },
5819
+ "heading/large": {
5820
+ fontSize: "clamp(32px, 4vw, 48px)",
5821
+ lineHeight: "1.2",
5822
+ fontWeight: "600"
5823
+ },
5824
+ "heading/medium": {
5825
+ fontSize: "clamp(24px, 3vw, 32px)",
5826
+ lineHeight: "1.25",
5827
+ fontWeight: "600"
5828
+ },
5829
+ "heading/small": {
5830
+ fontSize: "20px",
5831
+ lineHeight: "1.3",
5832
+ fontWeight: "600"
5833
+ },
5834
+ "body/normal": {
5835
+ fontSize: "16px",
5836
+ lineHeight: "1.6",
5837
+ fontWeight: "400"
5838
+ },
5839
+ "body/small": {
5840
+ fontSize: "14px",
5841
+ lineHeight: "1.5",
5842
+ fontWeight: "400"
5843
+ },
5844
+ caption: {
5845
+ fontSize: "12px",
5846
+ lineHeight: "1.4",
5847
+ fontWeight: "500"
5848
+ }
5849
+ },
5850
+ spacing: {
5851
+ none: "0px",
5852
+ "3xs": "4px",
5853
+ "2xs": "8px",
5854
+ xs: "12px",
5855
+ sm: "16px",
5856
+ md: "24px",
5857
+ lg: "32px",
5858
+ xl: "40px",
5859
+ "2xl": "56px",
5860
+ "3xl": "72px"
5861
+ },
5862
+ radius: {
5863
+ none: "0px",
5864
+ xs: "2px",
5865
+ sm: "4px",
5866
+ md: "8px",
5867
+ lg: "12px",
5868
+ pill: "999px",
5869
+ full: "9999px"
5870
+ },
5871
+ shadow: {
5872
+ none: "none",
5873
+ soft: "0px 2px 8px rgba(15, 23, 42, 0.08)",
5874
+ medium: "0px 6px 18px rgba(15, 23, 42, 0.12)",
5875
+ strong: "0px 12px 36px rgba(15, 23, 42, 0.16)"
5876
+ },
5877
+ palette: {
5878
+ surface: "#ffffff",
5879
+ "neutral-50": "#f9fafb",
5880
+ "neutral-900": "#111827",
5881
+ primary: "#2563eb",
5882
+ "primary-50": "#eff6ff",
5883
+ "primary-500": "#2563eb",
5884
+ "primary-900": "#1d4ed8",
5885
+ secondary: "#9333ea",
5886
+ "secondary-50": "#f3e8ff",
5887
+ "secondary-500": "#9333ea",
5888
+ "secondary-900": "#4c1d95",
5889
+ accent: "#f97316",
5890
+ "accent-50": "#fff7ed",
5891
+ "accent-500": "#f97316",
5892
+ "accent-900": "#7c2d12"
5893
+ }
5894
+ };
5895
+ }));
5896
+ //#endregion
5897
+ //#region ../theme-core/src/tokens/index.ts
5898
+ var init_tokens = __esmMin((() => {
5899
+ init_tokens$1();
5900
+ init_blockColorTokens();
5901
+ init_themeColorTokens();
5902
+ init_colorTokenParts();
5903
+ init_resolver$1();
5904
+ }));
5905
+ var init_foregroundInteraction = __esmMin((() => {
5906
+ init_contrast$1();
5907
+ init_colorConversion();
5908
+ init_colorTokenParts();
5909
+ init_tokens();
5910
+ }));
5911
+ //#endregion
5912
+ //#region ../theme-core/src/palette/utils/opaqueSurfaceColor.ts
5913
+ /** Resolve an opaque colour, compositing alpha against an explicit underlay. */
5914
+ function resolveOpaqueSurfaceHex(reference, palette, underlayReference) {
5915
+ const opaque = resolveConcreteColorHex(reference, palette);
5916
+ if (opaque) return opaque;
5917
+ if (!underlayReference) return null;
5918
+ const underlayHex = resolveConcreteColorHex(underlayReference, palette);
5919
+ if (!underlayHex) return null;
5920
+ const parts = parseColorTokenParts(reference);
5921
+ if (parts.kind === "token" && parts.opacityPercent !== null) {
5922
+ const foregroundHex = normalizePaletteHex(palette[parts.token] ?? "");
5923
+ return foregroundHex ? compositeHex(foregroundHex, underlayHex, parts.opacityPercent / 100) : null;
5924
+ }
5925
+ const rgba = parseRgba(parts.kind === "raw" ? parts.value : reference);
5926
+ return rgba ? compositeHex(rgbToHex$1(rgba.r, rgba.g, rgba.b), underlayHex, rgba.alpha) : null;
5927
+ }
5928
+ /** Resolve a colour reference only when it is already fully opaque. */
5929
+ function resolveConcreteColorHex(reference, palette) {
5930
+ const literalHex = normalizePaletteHex(reference);
5931
+ if (literalHex) return literalHex;
5932
+ const parts = parseColorTokenParts(reference);
5933
+ if (parts.kind === "token") {
5934
+ if (parts.opacityPercent !== null) return null;
5935
+ return normalizePaletteHex(palette[parts.token] ?? "");
5936
+ }
5937
+ const literal = parts.kind === "raw" ? parts.value : reference;
5938
+ if (literal.toLowerCase() === "black") return "#000000";
5939
+ if (literal.toLowerCase() === "white") return "#ffffff";
5940
+ return normalizePaletteHex(literal);
5941
+ }
5942
+ function compositeHex(foregroundHex, underlayHex, alpha) {
5943
+ const foreground = hexToRgb$1(foregroundHex);
5944
+ const underlay = hexToRgb$1(underlayHex);
5945
+ const channel = (foregroundValue, underlayValue) => Math.round(foregroundValue * alpha + underlayValue * (1 - alpha));
5946
+ return rgbToHex$1(channel(foreground.r, underlay.r), channel(foreground.g, underlay.g), channel(foreground.b, underlay.b));
5947
+ }
5948
+ function parseRgba(value) {
5949
+ const match = value.trim().match(/^rgba?\(\s*([\d.]+)(?:\s*,\s*|\s+)([\d.]+)(?:\s*,\s*|\s+)([\d.]+)(?:\s*(?:,|\/)\s*([\d.]+%?))?\s*\)$/i);
5950
+ if (!match) return null;
5951
+ const [, rSource, gSource, bSource] = match;
5952
+ if (!rSource || !gSource || !bSource) return null;
5953
+ const r = Number(rSource);
5954
+ const g = Number(gSource);
5955
+ const b = Number(bSource);
5956
+ const alpha = parseAlpha(match[4]);
5957
+ if (alpha === null || !isRgbChannel(r) || !isRgbChannel(g) || !isRgbChannel(b)) return null;
5958
+ return {
5959
+ r,
5960
+ g,
5961
+ b,
5962
+ alpha
5963
+ };
5964
+ }
5965
+ function parseAlpha(source) {
5966
+ if (!source) return 1;
5967
+ const value = source.endsWith("%") ? Number(source.slice(0, -1)) / 100 : Number(source);
5968
+ return Number.isFinite(value) && value >= 0 && value <= 1 ? value : null;
5969
+ }
5970
+ function isRgbChannel(value) {
5971
+ return Number.isFinite(value) && value >= 0 && value <= 255;
5972
+ }
5973
+ var init_opaqueSurfaceColor = __esmMin((() => {
5974
+ init_colors();
5975
+ init_colorTokenParts();
5976
+ init_colorConversion();
5977
+ }));
5978
+ //#endregion
5979
+ //#region ../theme-core/src/surfaces/resolveSurfaceForeground.ts
5980
+ /**
5981
+ * Resolve the complete foreground contract for an effective page/section or
5982
+ * site-chrome background.
5983
+ *
5984
+ * Deterministic colour backgrounds are validated at ordinary-text WCAG AA.
5985
+ * Existing image/video/gradient treatments are trusted only when they already
5986
+ * carry a usable foreground token; this function deliberately does not claim
5987
+ * pixel-level contrast proof for media.
5988
+ */
5989
+ function resolveSurfaceForeground(background, palette, candidates = {}, options = {}) {
5990
+ const authored = foregroundCandidates(background, candidates);
5991
+ if (background === null) return resolveDeterministicForeground("background", {
5992
+ ...authored,
5993
+ text: authored.text ?? "text"
5994
+ }, palette);
5995
+ if (background.type === "color") {
5996
+ const backgroundReference = normalizedReference(background.color);
5997
+ if (!backgroundReference || backgroundReference === "transparent") return { kind: "unknown" };
5998
+ return resolveDeterministicForeground(backgroundReference, authored, palette, options.compositeBase);
5999
+ }
6000
+ return resolveTrustedTreatmentForeground(authored, palette);
6001
+ }
6002
+ function foregroundCandidates(background, overrides) {
6003
+ return {
6004
+ text: overrides.text ?? background?.textColor ?? null,
6005
+ heading: overrides.heading ?? background?.headingColor ?? null,
6006
+ link: overrides.link ?? background?.linkColor ?? null,
6007
+ supporting: overrides.supporting ?? background?.supportingColor ?? null
6008
+ };
6009
+ }
6010
+ function resolveDeterministicForeground(backgroundReference, candidates, palette, compositeBase) {
6011
+ const backgroundHex = resolveOpaqueSurfaceHex(backgroundReference, palette, compositeBase);
6012
+ if (!backgroundHex) return resolveTrustedTreatmentForeground(candidates, palette);
6013
+ const backgroundToken = paletteToken(backgroundReference);
6014
+ const derivedOnToken = backgroundToken ? onColorTokenName(backgroundToken) : null;
6015
+ const text = firstSafeToken([
6016
+ candidates.text,
6017
+ derivedOnToken,
6018
+ ...FALLBACK_TEXT_TOKENS
6019
+ ], backgroundHex, palette, derivedOnToken ? [derivedOnToken] : []);
6020
+ if (!text) return { kind: "unknown" };
6021
+ return {
6022
+ kind: "known",
6023
+ roles: {
6024
+ text,
6025
+ heading: safeTokenOr(candidates.heading, text, backgroundHex, palette),
6026
+ link: safeTokenOr(candidates.link, text, backgroundHex, palette),
6027
+ supporting: safeTokenOr(candidates.supporting, text, backgroundHex, palette)
6028
+ }
6029
+ };
6030
+ }
6031
+ function resolveTrustedTreatmentForeground(candidates, palette) {
6032
+ const text = canonicalToken(candidates.text, palette);
6033
+ if (!text) return { kind: "unknown" };
6034
+ return {
6035
+ kind: "known",
6036
+ roles: {
6037
+ text,
6038
+ heading: canonicalToken(candidates.heading, palette) ?? text,
6039
+ link: canonicalToken(candidates.link, palette) ?? text,
6040
+ supporting: canonicalToken(candidates.supporting, palette) ?? text
6041
+ }
6042
+ };
6043
+ }
6044
+ function safeTokenOr(candidate, fallback, backgroundHex, palette) {
6045
+ return firstSafeToken([candidate], backgroundHex, palette) ?? fallback;
6046
+ }
6047
+ function firstSafeToken(candidates, backgroundHex, palette, preferredEquivalentTokens = []) {
6048
+ const seen = /* @__PURE__ */ new Set();
6049
+ for (const candidate of candidates) {
6050
+ const token = canonicalToken(candidate, palette, preferredEquivalentTokens);
6051
+ if (!token || seen.has(token)) continue;
6052
+ seen.add(token);
6053
+ const foregroundHex = resolveConcreteColorHex(token, palette);
6054
+ if (foregroundHex && contrastRatio(backgroundHex, foregroundHex) >= 4.5) return token;
6055
+ }
6056
+ return null;
6057
+ }
6058
+ function canonicalToken(reference, palette, preferredEquivalentTokens = []) {
6059
+ const normalized = normalizedReference(reference);
6060
+ if (!normalized || normalized === "transparent") return null;
6061
+ const direct = parseThemeColorToken(normalized);
6062
+ if (direct && resolveConcreteColorHex(direct, palette)) return direct;
6063
+ const referenceHex = resolveConcreteColorHex(normalized, palette);
6064
+ if (!referenceHex) return null;
6065
+ const equivalent = [
6066
+ ...preferredEquivalentTokens,
6067
+ ...CANONICAL_EQUIVALENT_TOKEN_ORDER,
6068
+ ...Object.keys(palette).sort()
6069
+ ].find((token) => {
6070
+ const parsed = parseThemeColorToken(token);
6071
+ return parsed !== null && resolveConcreteColorHex(parsed, palette)?.toLowerCase() === referenceHex.toLowerCase();
6072
+ });
6073
+ return equivalent ? parseThemeColorToken(equivalent) : null;
6074
+ }
6075
+ function paletteToken(reference) {
6076
+ const parts = parseColorTokenParts(reference);
6077
+ return parts.kind === "token" && parts.opacityPercent === null ? parts.token : null;
6078
+ }
6079
+ function normalizedReference(value) {
6080
+ if (typeof value !== "string") return null;
6081
+ const normalized = value.trim();
6082
+ return normalized.length > 0 ? normalized : null;
6083
+ }
6084
+ var FALLBACK_TEXT_TOKENS, CANONICAL_EQUIVALENT_TOKEN_ORDER;
6085
+ var init_resolveSurfaceForeground = __esmMin((() => {
6086
+ init_contrast$1();
6087
+ init_onColor();
6088
+ init_opaqueSurfaceColor();
6089
+ init_colorTokenParts();
6090
+ init_themeColorTokens();
6091
+ FALLBACK_TEXT_TOKENS = [
6092
+ "text",
6093
+ "primaryForeground",
6094
+ "secondaryForeground",
6095
+ "accentForeground",
6096
+ "neutral-950",
6097
+ "neutral-50"
6098
+ ];
6099
+ CANONICAL_EQUIVALENT_TOKEN_ORDER = [
6100
+ "text",
6101
+ "primaryForeground",
6102
+ "secondaryForeground",
6103
+ "accentForeground",
6104
+ "onPrimary",
6105
+ "onSecondary",
6106
+ "onAccent",
6107
+ "onSurface",
6108
+ "neutral-950",
6109
+ "neutral-50"
6110
+ ];
6111
+ }));
6112
+ //#endregion
6113
+ //#region ../theme-core/src/surfaces/index.ts
6114
+ var init_surfaces = __esmMin((() => {
6115
+ init_foregroundContract();
6116
+ init_foregroundInteraction();
6117
+ init_foregroundRoles();
6118
+ init_resolveSurfaceForeground();
6119
+ }));
6120
+ //#endregion
6121
+ //#region ../theme-core/src/utils/colorStyles.ts
6122
+ function parseToken(source) {
6123
+ const parts = parseColorTokenParts(source);
6124
+ if (parts.kind === "raw") return {
6125
+ token: source,
6126
+ raw: parts.value
6127
+ };
6128
+ if (parts.kind === "invalid") return { token: source };
6129
+ return {
6130
+ token: parts.token,
6131
+ opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
6132
+ };
6133
+ }
6134
+ function surfaceRoleForTextToken(token) {
6135
+ return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
6136
+ }
6137
+ /**
6138
+ * Converts a theme color token to a CSS rgb value.
6139
+ * This is the primary function for applying theme colors to CSS properties.
6140
+ *
6141
+ * @param token - Theme color token (semantic, with opacity, or raw)
6142
+ * @returns CSS color value (rgb with optional alpha, or raw CSS value)
6143
+ *
6144
+ * @example
6145
+ * rgbColorValue('primary') // => 'rgb(var(--tb-primary))'
6146
+ * rgbColorValue('surface/95') // => 'rgb(var(--tb-surface) / 0.95)'
6147
+ * rgbColorValue('raw:transparent') // => 'transparent'
6148
+ */
6149
+ function rgbColorValue(token) {
6150
+ const { token: baseToken, opacityPercent, raw } = parseToken(token);
6151
+ if (raw) return raw;
6152
+ const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
6153
+ if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
6154
+ return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
6155
+ }
6156
+ /**
6157
+ * Converts a theme color token to a CSS variable reference.
6158
+ * Note: This returns the base variable without rgb() wrapper, ignoring opacity.
6159
+ *
6160
+ * @param token - Theme color token
6161
+ * @returns CSS variable reference
6162
+ *
6163
+ * @example
6164
+ * cssVarValue('primary') // => 'var(--tb-primary)'
6165
+ * cssVarValue('surface/95') // => 'var(--tb-surface)' (opacity ignored)
6166
+ */
6167
+ function cssVarValue(token) {
6168
+ const { token: baseToken } = parseToken(token);
6169
+ return `var(${COLOR_VAR_PREFIX}${baseToken})`;
6170
+ }
6171
+ /**
6172
+ * Creates a backgroundColor style object from a theme token.
6173
+ *
6174
+ * @param token - Theme color token
6175
+ * @returns CSSProperties with backgroundColor
6176
+ */
6177
+ function backgroundColorStyle(token) {
6178
+ return { backgroundColor: rgbColorValue(token) };
6179
+ }
6180
+ /**
6181
+ * Creates a text color style object from a theme token.
6182
+ *
6183
+ * @param token - Theme color token
6184
+ * @returns CSSProperties with color
6185
+ */
6186
+ function textColorStyle(token) {
6187
+ const parsed = parseToken(token);
6188
+ const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
6189
+ if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
6190
+ return { color: rgbColorValue(token) };
6191
+ }
6192
+ /**
6193
+ * Creates a border color style object from a theme token.
6194
+ *
6195
+ * @param token - Theme color token
6196
+ * @returns CSSProperties with borderColor
6197
+ */
6198
+ function borderColorStyle(token) {
6199
+ return { borderColor: rgbColorValue(token) };
6200
+ }
6201
+ /**
6202
+ * Merges multiple CSSProperties objects into a single object.
6203
+ * Later styles override earlier ones. Undefined values are filtered out.
6204
+ * Returns undefined if the merged result is empty.
6205
+ *
6206
+ * @param styles - Variable number of CSSProperties objects (can be undefined)
6207
+ * @returns Merged CSSProperties object, or undefined if empty
6208
+ *
6209
+ * @example
6210
+ * mergeStyles(
6211
+ * backgroundColorStyle('surface'),
6212
+ * textColorStyle('text'),
6213
+ * borderColorStyle('border')
6214
+ * )
6215
+ * // => { backgroundColor: '...', color: '...', borderColor: '...' }
6216
+ */
6217
+ function mergeStyles(...styles) {
6218
+ const merged = {};
6219
+ for (const style of styles) {
6220
+ if (!style) continue;
6221
+ Object.assign(merged, style);
6222
+ }
6223
+ return Object.keys(merged).length ? merged : void 0;
6224
+ }
6225
+ var COLOR_VAR_PREFIX, SURFACE_TEXT_ROLE_BY_TOKEN;
6226
+ var init_colorStyles = __esmMin((() => {
6227
+ init_surfaces();
6228
+ init_colorTokenParts();
6229
+ COLOR_VAR_PREFIX = "--tb-";
6230
+ SURFACE_TEXT_ROLE_BY_TOKEN = {
6231
+ text: "text",
6232
+ heading: "heading",
6233
+ mutedText: "supporting"
6234
+ };
6235
+ }));
6236
+ //#endregion
5710
6237
  //#region ../theme-core/src/tokens/resolver.ts
5711
6238
  var TokenResolver;
5712
6239
  var init_resolver$1 = __esmMin((() => {
6240
+ init_colorStyles();
5713
6241
  TokenResolver = class {
5714
6242
  constructor(theme) {
5715
6243
  this.theme = theme;
@@ -5729,7 +6257,7 @@ var init_resolver$1 = __esmMin((() => {
5729
6257
  */
5730
6258
  getColor(token) {
5731
6259
  if (!this.tokenExists(token)) console.warn(`[TokenResolver] Color token "${token}" not found in theme palette. Button may render incorrectly.`);
5732
- return `rgb(var(--tb-${token}))`;
6260
+ return rgbColorValue(token);
5733
6261
  }
5734
6262
  /**
5735
6263
  * Adjust a color token's shade by a given amount
@@ -7261,330 +7789,6 @@ var init_affordanceIcons = __esmMin((() => {
7261
7789
  };
7262
7790
  }));
7263
7791
  //#endregion
7264
- //#region ../theme-core/src/palette/utils/opaqueSurfaceColor.ts
7265
- /** Resolve an opaque colour, compositing alpha against an explicit underlay. */
7266
- function resolveOpaqueSurfaceHex(reference, palette, underlayReference) {
7267
- const opaque = resolveConcreteColorHex(reference, palette);
7268
- if (opaque) return opaque;
7269
- if (!underlayReference) return null;
7270
- const underlayHex = resolveConcreteColorHex(underlayReference, palette);
7271
- if (!underlayHex) return null;
7272
- const parts = parseColorTokenParts(reference);
7273
- if (parts.kind === "token" && parts.opacityPercent !== null) {
7274
- const foregroundHex = normalizePaletteHex(palette[parts.token] ?? "");
7275
- return foregroundHex ? compositeHex(foregroundHex, underlayHex, parts.opacityPercent / 100) : null;
7276
- }
7277
- const rgba = parseRgba(parts.kind === "raw" ? parts.value : reference);
7278
- return rgba ? compositeHex(rgbToHex$1(rgba.r, rgba.g, rgba.b), underlayHex, rgba.alpha) : null;
7279
- }
7280
- /** Resolve a colour reference only when it is already fully opaque. */
7281
- function resolveConcreteColorHex(reference, palette) {
7282
- const literalHex = normalizePaletteHex(reference);
7283
- if (literalHex) return literalHex;
7284
- const parts = parseColorTokenParts(reference);
7285
- if (parts.kind === "token") {
7286
- if (parts.opacityPercent !== null) return null;
7287
- return normalizePaletteHex(palette[parts.token] ?? "");
7288
- }
7289
- const literal = parts.kind === "raw" ? parts.value : reference;
7290
- if (literal.toLowerCase() === "black") return "#000000";
7291
- if (literal.toLowerCase() === "white") return "#ffffff";
7292
- return normalizePaletteHex(literal);
7293
- }
7294
- function compositeHex(foregroundHex, underlayHex, alpha) {
7295
- const foreground = hexToRgb$1(foregroundHex);
7296
- const underlay = hexToRgb$1(underlayHex);
7297
- const channel = (foregroundValue, underlayValue) => Math.round(foregroundValue * alpha + underlayValue * (1 - alpha));
7298
- return rgbToHex$1(channel(foreground.r, underlay.r), channel(foreground.g, underlay.g), channel(foreground.b, underlay.b));
7299
- }
7300
- function parseRgba(value) {
7301
- const match = value.trim().match(/^rgba?\(\s*([\d.]+)(?:\s*,\s*|\s+)([\d.]+)(?:\s*,\s*|\s+)([\d.]+)(?:\s*(?:,|\/)\s*([\d.]+%?))?\s*\)$/i);
7302
- if (!match) return null;
7303
- const [, rSource, gSource, bSource] = match;
7304
- if (!rSource || !gSource || !bSource) return null;
7305
- const r = Number(rSource);
7306
- const g = Number(gSource);
7307
- const b = Number(bSource);
7308
- const alpha = parseAlpha(match[4]);
7309
- if (alpha === null || !isRgbChannel(r) || !isRgbChannel(g) || !isRgbChannel(b)) return null;
7310
- return {
7311
- r,
7312
- g,
7313
- b,
7314
- alpha
7315
- };
7316
- }
7317
- function parseAlpha(source) {
7318
- if (!source) return 1;
7319
- const value = source.endsWith("%") ? Number(source.slice(0, -1)) / 100 : Number(source);
7320
- return Number.isFinite(value) && value >= 0 && value <= 1 ? value : null;
7321
- }
7322
- function isRgbChannel(value) {
7323
- return Number.isFinite(value) && value >= 0 && value <= 255;
7324
- }
7325
- var init_opaqueSurfaceColor = __esmMin((() => {
7326
- init_colors();
7327
- init_colorTokenParts();
7328
- init_colorConversion();
7329
- }));
7330
- //#endregion
7331
- //#region ../theme-core/src/surfaces/resolveSurfaceForeground.ts
7332
- /**
7333
- * Resolve the complete foreground contract for an effective page/section or
7334
- * site-chrome background.
7335
- *
7336
- * Deterministic colour backgrounds are validated at ordinary-text WCAG AA.
7337
- * Existing image/video/gradient treatments are trusted only when they already
7338
- * carry a usable foreground token; this function deliberately does not claim
7339
- * pixel-level contrast proof for media.
7340
- */
7341
- function resolveSurfaceForeground(background, palette, candidates = {}, options = {}) {
7342
- const authored = foregroundCandidates(background, candidates);
7343
- if (background === null) return resolveDeterministicForeground("background", {
7344
- ...authored,
7345
- text: authored.text ?? "text"
7346
- }, palette);
7347
- if (background.type === "color") {
7348
- const backgroundReference = normalizedReference(background.color);
7349
- if (!backgroundReference || backgroundReference === "transparent") return { kind: "unknown" };
7350
- return resolveDeterministicForeground(backgroundReference, authored, palette, options.compositeBase);
7351
- }
7352
- return resolveTrustedTreatmentForeground(authored, palette);
7353
- }
7354
- function foregroundCandidates(background, overrides) {
7355
- return {
7356
- text: overrides.text ?? background?.textColor ?? null,
7357
- heading: overrides.heading ?? background?.headingColor ?? null,
7358
- link: overrides.link ?? background?.linkColor ?? null,
7359
- supporting: overrides.supporting ?? background?.supportingColor ?? null
7360
- };
7361
- }
7362
- function resolveDeterministicForeground(backgroundReference, candidates, palette, compositeBase) {
7363
- const backgroundHex = resolveOpaqueSurfaceHex(backgroundReference, palette, compositeBase);
7364
- if (!backgroundHex) return resolveTrustedTreatmentForeground(candidates, palette);
7365
- const backgroundToken = paletteToken(backgroundReference);
7366
- const derivedOnToken = backgroundToken ? onColorTokenName(backgroundToken) : null;
7367
- const text = firstSafeToken([
7368
- candidates.text,
7369
- derivedOnToken,
7370
- ...FALLBACK_TEXT_TOKENS
7371
- ], backgroundHex, palette, derivedOnToken ? [derivedOnToken] : []);
7372
- if (!text) return { kind: "unknown" };
7373
- return {
7374
- kind: "known",
7375
- roles: {
7376
- text,
7377
- heading: safeTokenOr(candidates.heading, text, backgroundHex, palette),
7378
- link: safeTokenOr(candidates.link, text, backgroundHex, palette),
7379
- supporting: safeTokenOr(candidates.supporting, text, backgroundHex, palette)
7380
- }
7381
- };
7382
- }
7383
- function resolveTrustedTreatmentForeground(candidates, palette) {
7384
- const text = canonicalToken(candidates.text, palette);
7385
- if (!text) return { kind: "unknown" };
7386
- return {
7387
- kind: "known",
7388
- roles: {
7389
- text,
7390
- heading: canonicalToken(candidates.heading, palette) ?? text,
7391
- link: canonicalToken(candidates.link, palette) ?? text,
7392
- supporting: canonicalToken(candidates.supporting, palette) ?? text
7393
- }
7394
- };
7395
- }
7396
- function safeTokenOr(candidate, fallback, backgroundHex, palette) {
7397
- return firstSafeToken([candidate], backgroundHex, palette) ?? fallback;
7398
- }
7399
- function firstSafeToken(candidates, backgroundHex, palette, preferredEquivalentTokens = []) {
7400
- const seen = /* @__PURE__ */ new Set();
7401
- for (const candidate of candidates) {
7402
- const token = canonicalToken(candidate, palette, preferredEquivalentTokens);
7403
- if (!token || seen.has(token)) continue;
7404
- seen.add(token);
7405
- const foregroundHex = resolveConcreteColorHex(token, palette);
7406
- if (foregroundHex && contrastRatio(backgroundHex, foregroundHex) >= 4.5) return token;
7407
- }
7408
- return null;
7409
- }
7410
- function canonicalToken(reference, palette, preferredEquivalentTokens = []) {
7411
- const normalized = normalizedReference(reference);
7412
- if (!normalized || normalized === "transparent") return null;
7413
- const direct = parseThemeColorToken(normalized);
7414
- if (direct && resolveConcreteColorHex(direct, palette)) return direct;
7415
- const referenceHex = resolveConcreteColorHex(normalized, palette);
7416
- if (!referenceHex) return null;
7417
- const equivalent = [
7418
- ...preferredEquivalentTokens,
7419
- ...CANONICAL_EQUIVALENT_TOKEN_ORDER,
7420
- ...Object.keys(palette).sort()
7421
- ].find((token) => {
7422
- const parsed = parseThemeColorToken(token);
7423
- return parsed !== null && resolveConcreteColorHex(parsed, palette)?.toLowerCase() === referenceHex.toLowerCase();
7424
- });
7425
- return equivalent ? parseThemeColorToken(equivalent) : null;
7426
- }
7427
- function paletteToken(reference) {
7428
- const parts = parseColorTokenParts(reference);
7429
- return parts.kind === "token" && parts.opacityPercent === null ? parts.token : null;
7430
- }
7431
- function normalizedReference(value) {
7432
- if (typeof value !== "string") return null;
7433
- const normalized = value.trim();
7434
- return normalized.length > 0 ? normalized : null;
7435
- }
7436
- var FALLBACK_TEXT_TOKENS, CANONICAL_EQUIVALENT_TOKEN_ORDER;
7437
- var init_resolveSurfaceForeground = __esmMin((() => {
7438
- init_contrast$1();
7439
- init_onColor();
7440
- init_opaqueSurfaceColor();
7441
- init_colorTokenParts();
7442
- init_themeColorTokens();
7443
- FALLBACK_TEXT_TOKENS = [
7444
- "text",
7445
- "primaryForeground",
7446
- "secondaryForeground",
7447
- "accentForeground",
7448
- "neutral-950",
7449
- "neutral-50"
7450
- ];
7451
- CANONICAL_EQUIVALENT_TOKEN_ORDER = [
7452
- "text",
7453
- "primaryForeground",
7454
- "secondaryForeground",
7455
- "accentForeground",
7456
- "onPrimary",
7457
- "onSecondary",
7458
- "onAccent",
7459
- "onSurface",
7460
- "neutral-950",
7461
- "neutral-50"
7462
- ];
7463
- }));
7464
- //#endregion
7465
- //#region ../theme-core/src/surfaces/index.ts
7466
- var init_surfaces = __esmMin((() => {
7467
- init_foregroundContract();
7468
- init_foregroundRoles();
7469
- init_resolveSurfaceForeground();
7470
- }));
7471
- //#endregion
7472
- //#region ../theme-core/src/utils/colorStyles.ts
7473
- function parseToken(source) {
7474
- const parts = parseColorTokenParts(source);
7475
- if (parts.kind === "raw") return {
7476
- token: source,
7477
- raw: parts.value
7478
- };
7479
- if (parts.kind === "invalid") return { token: source };
7480
- return {
7481
- token: parts.token,
7482
- opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
7483
- };
7484
- }
7485
- function surfaceRoleForTextToken(token) {
7486
- return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
7487
- }
7488
- /**
7489
- * Converts a theme color token to a CSS rgb value.
7490
- * This is the primary function for applying theme colors to CSS properties.
7491
- *
7492
- * @param token - Theme color token (semantic, with opacity, or raw)
7493
- * @returns CSS color value (rgb with optional alpha, or raw CSS value)
7494
- *
7495
- * @example
7496
- * rgbColorValue('primary') // => 'rgb(var(--tb-primary))'
7497
- * rgbColorValue('surface/95') // => 'rgb(var(--tb-surface) / 0.95)'
7498
- * rgbColorValue('raw:transparent') // => 'transparent'
7499
- */
7500
- function rgbColorValue(token) {
7501
- const { token: baseToken, opacityPercent, raw } = parseToken(token);
7502
- if (raw) return raw;
7503
- const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
7504
- if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
7505
- return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
7506
- }
7507
- /**
7508
- * Converts a theme color token to a CSS variable reference.
7509
- * Note: This returns the base variable without rgb() wrapper, ignoring opacity.
7510
- *
7511
- * @param token - Theme color token
7512
- * @returns CSS variable reference
7513
- *
7514
- * @example
7515
- * cssVarValue('primary') // => 'var(--tb-primary)'
7516
- * cssVarValue('surface/95') // => 'var(--tb-surface)' (opacity ignored)
7517
- */
7518
- function cssVarValue(token) {
7519
- const { token: baseToken } = parseToken(token);
7520
- return `var(${COLOR_VAR_PREFIX}${baseToken})`;
7521
- }
7522
- /**
7523
- * Creates a backgroundColor style object from a theme token.
7524
- *
7525
- * @param token - Theme color token
7526
- * @returns CSSProperties with backgroundColor
7527
- */
7528
- function backgroundColorStyle(token) {
7529
- return { backgroundColor: rgbColorValue(token) };
7530
- }
7531
- /**
7532
- * Creates a text color style object from a theme token.
7533
- *
7534
- * @param token - Theme color token
7535
- * @returns CSSProperties with color
7536
- */
7537
- function textColorStyle(token) {
7538
- const parsed = parseToken(token);
7539
- const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
7540
- if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
7541
- return { color: rgbColorValue(token) };
7542
- }
7543
- /**
7544
- * Creates a border color style object from a theme token.
7545
- *
7546
- * @param token - Theme color token
7547
- * @returns CSSProperties with borderColor
7548
- */
7549
- function borderColorStyle(token) {
7550
- return { borderColor: rgbColorValue(token) };
7551
- }
7552
- /**
7553
- * Merges multiple CSSProperties objects into a single object.
7554
- * Later styles override earlier ones. Undefined values are filtered out.
7555
- * Returns undefined if the merged result is empty.
7556
- *
7557
- * @param styles - Variable number of CSSProperties objects (can be undefined)
7558
- * @returns Merged CSSProperties object, or undefined if empty
7559
- *
7560
- * @example
7561
- * mergeStyles(
7562
- * backgroundColorStyle('surface'),
7563
- * textColorStyle('text'),
7564
- * borderColorStyle('border')
7565
- * )
7566
- * // => { backgroundColor: '...', color: '...', borderColor: '...' }
7567
- */
7568
- function mergeStyles(...styles) {
7569
- const merged = {};
7570
- for (const style of styles) {
7571
- if (!style) continue;
7572
- Object.assign(merged, style);
7573
- }
7574
- return Object.keys(merged).length ? merged : void 0;
7575
- }
7576
- var COLOR_VAR_PREFIX, SURFACE_TEXT_ROLE_BY_TOKEN;
7577
- var init_colorStyles = __esmMin((() => {
7578
- init_surfaces();
7579
- init_colorTokenParts();
7580
- COLOR_VAR_PREFIX = "--tb-";
7581
- SURFACE_TEXT_ROLE_BY_TOKEN = {
7582
- text: "text",
7583
- heading: "heading",
7584
- mutedText: "supporting"
7585
- };
7586
- }));
7587
- //#endregion
7588
7792
  //#region ../theme-core/src/utils/tokenOrColor.ts
7589
7793
  function isCssColorLiteral(value) {
7590
7794
  const trimmed = value.trim();
@@ -13217,15 +13421,34 @@ var init_bookingConsent = __esmMin((() => {
13217
13421
  checkboxLabel: z$1.string().min(1)
13218
13422
  });
13219
13423
  bookingConsentCarrierSchema = z$1.union([blockBookingConsentSchema, bookingRequirementConsentFieldSchema]);
13220
- }));
13221
- //#endregion
13222
- //#region ../blocks/src/system/blocks/events/shared/schemas.ts
13223
- var eventPresetSchema, eventScheduleScopeSchema$2, publicEventRecurrenceSchema, eventDestinationModeSchema, publicEventDestinationSchema, eventVenueSchema, eventCategorySchema, accessRestrictionSchema, publicCurrencySchema, publicCentsSchema, publicPositiveCentsSchema, publicIsoDateTimeSchema, publicEventAttendanceModeSchema, publicEventAttendanceModeAvailabilitySchema, publicEventPricingOptionAvailabilitySchema, publicEventPricingOptionSchema, publicEventPricingSchema, publicTeamMemberSummarySchema, publicEventBookingAvailabilitySchema, publicRunSessionSchema, publicWholeSeriesRunSchema, publicEventBaseSchema, publicEventSchema, publicEventsArraySchema;
13424
+ })), publicEventLoaderQuerySchemaShape, eventPresetSchema, eventScheduleScopeSchema$2, publicEventRecurrenceSchema, eventDestinationModeSchema, publicEventDestinationSchema, eventVenueSchema, eventCategorySchema, accessRestrictionSchema, publicCurrencySchema, publicCentsSchema, publicPositiveCentsSchema, publicIsoDateTimeSchema, publicEventAttendanceModeSchema, publicEventAttendanceModeAvailabilitySchema, publicEventPricingOptionAvailabilitySchema, publicEventPricingOptionSchema, publicEventPricingSchema, publicTeamMemberSummarySchema, publicEventBookingAvailabilitySchema, publicRunSessionSchema, publicWholeSeriesRunSchema, publicEventBaseSchema, publicEventSchema, publicEventsArraySchema;
13224
13425
  var init_schemas = __esmMin((() => {
13225
13426
  init_media$1();
13226
13427
  init_richTextSchema();
13227
13428
  init_bookingPaymentTerms();
13228
13429
  init_bookingConsent();
13430
+ publicEventLoaderQuerySchemaShape = {
13431
+ limit: z$1.string().optional(),
13432
+ from: z$1.string().optional(),
13433
+ to: z$1.string().optional(),
13434
+ afterStartsAt: z$1.string().optional(),
13435
+ afterId: z$1.string().optional(),
13436
+ categoryIds: z$1.string().optional(),
13437
+ venueId: z$1.string().optional(),
13438
+ staffMemberId: z$1.string().optional(),
13439
+ eventSurface: z$1.string().optional(),
13440
+ eventPresets: z$1.string().optional(),
13441
+ scheduleScope: z$1.string().optional(),
13442
+ seriesId: z$1.string().optional(),
13443
+ seriesIds: z$1.string().optional(),
13444
+ runSeriesId: z$1.string().optional(),
13445
+ seriesSlug: z$1.string().optional(),
13446
+ includeOccurrenceId: z$1.string().optional(),
13447
+ readIntent: z$1.string().optional(),
13448
+ detailLevel: z$1.string().optional(),
13449
+ readProfile: z$1.string().optional()
13450
+ };
13451
+ z$1.object(publicEventLoaderQuerySchemaShape);
13229
13452
  eventPresetSchema = z$1.enum([
13230
13453
  "event",
13231
13454
  "class",
@@ -13652,7 +13875,7 @@ function planCalendarMonthRanges(months) {
13652
13875
  const sorted = [...new Set(months)].sort();
13653
13876
  const ranges = [];
13654
13877
  for (const month of sorted) {
13655
- const previous = ranges.at(-1);
13878
+ const previous = ranges[ranges.length - 1];
13656
13879
  const end = calendarMonthKey$1(addMonths(calendarMonthDate(month), 1));
13657
13880
  if (previous?.endMonthExclusive === month && monthNumber(end) - monthNumber(previous.startMonth) <= 3) previous.endMonthExclusive = end;
13658
13881
  else ranges.push({
@@ -15711,155 +15934,6 @@ var init_blockFlow = __esmMin((() => {
15711
15934
  init_types$8();
15712
15935
  }));
15713
15936
  //#endregion
15714
- //#region ../theme-core/src/tokens/tokens.ts
15715
- /**
15716
- * Project the expanded semantic palette into the token buckets consumed by
15717
- * runtime transforms. Keep this mapping shared by full themes and the
15718
- * tokens-only hosted-booking runtime so the two paths cannot drift.
15719
- */
15720
- function buildThemeTokens(palette) {
15721
- const tokens = cloneThemeTokens(defaultThemeTokens);
15722
- const paletteStrings = {};
15723
- for (const [key, value] of Object.entries(palette)) if (typeof value === "string" && value.trim().length > 0) paletteStrings[key] = value;
15724
- tokens.palette = paletteStrings;
15725
- const resolveColor = (...keys) => {
15726
- for (const key of keys) {
15727
- const value = paletteStrings[key];
15728
- if (value) return value;
15729
- }
15730
- };
15731
- const assignColor = (token, ...keys) => {
15732
- const value = resolveColor(...keys);
15733
- if (value) tokens.color[token] = value;
15734
- };
15735
- assignColor("background/base", "background", "surface", "primary-50");
15736
- assignColor("background/elevated", "surface", "background");
15737
- assignColor("surface/base", "surface", "background");
15738
- assignColor("surface/subtle", "neutral-100", "surface", "background");
15739
- assignColor("surface/inverted", "neutral-900", "text", "primary-900");
15740
- assignColor("content/primary", "text", "body", "neutral-900");
15741
- assignColor("content/secondary", "mutedText", "secondary", "neutral-600");
15742
- assignColor("accent/primary", "primary", "accent");
15743
- assignColor("accent/secondary", "accent", "secondary", "primary-400");
15744
- assignColor("border/base", "border", "neutral-300");
15745
- return tokens;
15746
- }
15747
- function cloneThemeTokens(source) {
15748
- return JSON.parse(JSON.stringify(source));
15749
- }
15750
- var defaultThemeTokens;
15751
- var init_tokens$1 = __esmMin((() => {
15752
- defaultThemeTokens = {
15753
- color: {
15754
- "background/base": "#ffffff",
15755
- "background/elevated": "#f5f5f5",
15756
- "surface/base": "#ffffff",
15757
- "surface/subtle": "#f9f9fb",
15758
- "surface/inverted": "#111111",
15759
- "content/primary": "#111111",
15760
- "content/secondary": "#3f3f46",
15761
- "accent/primary": "#2563eb",
15762
- "accent/secondary": "#1d4ed8",
15763
- "border/base": "#e5e7eb"
15764
- },
15765
- typography: {
15766
- "display/hero": {
15767
- fontSize: "clamp(48px, 8vw, 96px)",
15768
- lineHeight: "1.05",
15769
- fontWeight: "700"
15770
- },
15771
- "display/section": {
15772
- fontSize: "clamp(40px, 6vw, 72px)",
15773
- lineHeight: "1.1",
15774
- fontWeight: "700"
15775
- },
15776
- "heading/large": {
15777
- fontSize: "clamp(32px, 4vw, 48px)",
15778
- lineHeight: "1.2",
15779
- fontWeight: "600"
15780
- },
15781
- "heading/medium": {
15782
- fontSize: "clamp(24px, 3vw, 32px)",
15783
- lineHeight: "1.25",
15784
- fontWeight: "600"
15785
- },
15786
- "heading/small": {
15787
- fontSize: "20px",
15788
- lineHeight: "1.3",
15789
- fontWeight: "600"
15790
- },
15791
- "body/normal": {
15792
- fontSize: "16px",
15793
- lineHeight: "1.6",
15794
- fontWeight: "400"
15795
- },
15796
- "body/small": {
15797
- fontSize: "14px",
15798
- lineHeight: "1.5",
15799
- fontWeight: "400"
15800
- },
15801
- caption: {
15802
- fontSize: "12px",
15803
- lineHeight: "1.4",
15804
- fontWeight: "500"
15805
- }
15806
- },
15807
- spacing: {
15808
- none: "0px",
15809
- "3xs": "4px",
15810
- "2xs": "8px",
15811
- xs: "12px",
15812
- sm: "16px",
15813
- md: "24px",
15814
- lg: "32px",
15815
- xl: "40px",
15816
- "2xl": "56px",
15817
- "3xl": "72px"
15818
- },
15819
- radius: {
15820
- none: "0px",
15821
- xs: "2px",
15822
- sm: "4px",
15823
- md: "8px",
15824
- lg: "12px",
15825
- pill: "999px",
15826
- full: "9999px"
15827
- },
15828
- shadow: {
15829
- none: "none",
15830
- soft: "0px 2px 8px rgba(15, 23, 42, 0.08)",
15831
- medium: "0px 6px 18px rgba(15, 23, 42, 0.12)",
15832
- strong: "0px 12px 36px rgba(15, 23, 42, 0.16)"
15833
- },
15834
- palette: {
15835
- surface: "#ffffff",
15836
- "neutral-50": "#f9fafb",
15837
- "neutral-900": "#111827",
15838
- primary: "#2563eb",
15839
- "primary-50": "#eff6ff",
15840
- "primary-500": "#2563eb",
15841
- "primary-900": "#1d4ed8",
15842
- secondary: "#9333ea",
15843
- "secondary-50": "#f3e8ff",
15844
- "secondary-500": "#9333ea",
15845
- "secondary-900": "#4c1d95",
15846
- accent: "#f97316",
15847
- "accent-50": "#fff7ed",
15848
- "accent-500": "#f97316",
15849
- "accent-900": "#7c2d12"
15850
- }
15851
- };
15852
- }));
15853
- //#endregion
15854
- //#region ../theme-core/src/tokens/index.ts
15855
- var init_tokens = __esmMin((() => {
15856
- init_tokens$1();
15857
- init_blockColorTokens();
15858
- init_themeColorTokens();
15859
- init_colorTokenParts();
15860
- init_resolver$1();
15861
- }));
15862
- //#endregion
15863
15937
  //#region ../theme-core/src/site-styles/backgroundAppearance.ts
15864
15938
  function parseBackgroundAppearanceColorToken(value) {
15865
15939
  if (typeof value !== "string") return null;
@@ -21374,6 +21448,7 @@ function diffJsonPaths(left, right, path = "") {
21374
21448
  }
21375
21449
  var init_headerBytesComparison = __esmMin((() => {}));
21376
21450
  var init_headerOpeningForeground = __esmMin((() => {
21451
+ init_foregroundInteraction();
21377
21452
  init_expandPalette();
21378
21453
  init_colorConversion();
21379
21454
  init_tokens();
@@ -32644,6 +32719,49 @@ var init_registrationEventAdapter = __esmMin((() => {
32644
32719
  init_runGrouping();
32645
32720
  }));
32646
32721
  //#endregion
32722
+ //#region ../blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.ts
32723
+ function resolveEventRegistrationEventSource(input) {
32724
+ if (input.wholeSeriesRunEvents != null) return {
32725
+ kind: "loaded",
32726
+ events: input.wholeSeriesRunEvents
32727
+ };
32728
+ if (input.events != null) return {
32729
+ kind: "loaded",
32730
+ events: input.events
32731
+ };
32732
+ return {
32733
+ kind: "unresolved",
32734
+ request: parseEventLoaderRecoveryRequest(input.failures?.wholeSeriesRunEvents ?? input.failures?.events)
32735
+ };
32736
+ }
32737
+ function parseEventLoaderRecoveryRequest(value) {
32738
+ const parsed = eventLoaderFailureSchema.safeParse(value);
32739
+ if (!parsed.success) return null;
32740
+ const { siteId: _siteId, stage, ...params } = parsed.data.params;
32741
+ return {
32742
+ ...params,
32743
+ stage: stage ?? "published"
32744
+ };
32745
+ }
32746
+ var _rawLimit, _rawEventSurface, _rawScheduleScope, _rawDetailLevel, stringEventQueryShape, eventRecoveryRequestSchema, eventLoaderFailureSchema;
32747
+ var init_eventSourceRecovery = __esmMin((() => {
32748
+ init_schemas();
32749
+ init_filtering();
32750
+ ({limit: _rawLimit, eventSurface: _rawEventSurface, scheduleScope: _rawScheduleScope, detailLevel: _rawDetailLevel, ...stringEventQueryShape} = publicEventLoaderQuerySchemaShape);
32751
+ eventRecoveryRequestSchema = z$1.object({
32752
+ ...stringEventQueryShape,
32753
+ limit: z$1.coerce.number().int().positive().optional(),
32754
+ eventSurface: z$1.enum(eventSurfaceScopeValues).optional(),
32755
+ scheduleScope: z$1.enum(eventScheduleScopeValues).optional(),
32756
+ detailLevel: z$1.enum(["full", "listing"]).optional(),
32757
+ stage: z$1.enum(["preview", "published"]).optional()
32758
+ });
32759
+ eventLoaderFailureSchema = z$1.object({
32760
+ endpoint: z$1.literal("listPublicEvents"),
32761
+ params: eventRecoveryRequestSchema.extend({ siteId: z$1.string().optional() })
32762
+ });
32763
+ }));
32764
+ //#endregion
32647
32765
  //#region ../blocks/src/system/runtime/nodes/event-registration.interactive.ts
32648
32766
  function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents) {
32649
32767
  const selectedRun = resolveSelectedWholeSeriesRun(scopedSourceEvents);
@@ -32692,16 +32810,12 @@ function buildEventRegistrationShellStepLabels(source, scopedSourceEvents) {
32692
32810
  function toScopedEventRegistrationEvents(scopedSourceEvents) {
32693
32811
  return [...toRegistrationEvents(scopedSourceEvents), ...toWholeSeriesRegistrationEvents(scopedSourceEvents)];
32694
32812
  }
32695
- function scopeEventRegistrationSourceEvents(source) {
32696
- return resolveEventRegistrationScopedEvents(source.wholeSeriesRunEvents ?? source.events ?? [], {
32813
+ function scopeEventRegistrationSourceEvents(source, eventSource) {
32814
+ return resolveEventRegistrationScopedEvents(eventSource.kind === "loaded" ? eventSource.events : [], {
32697
32815
  occurrenceContext: source.occurrenceContext,
32698
32816
  subject: source.subject
32699
32817
  });
32700
32818
  }
32701
- function resolveLoadedEventRegistrationSourceEvents(source, scopedSourceEvents) {
32702
- if (source.events == null && source.wholeSeriesRunEvents == null) return null;
32703
- return [...scopedSourceEvents];
32704
- }
32705
32819
  /**
32706
32820
  * The one run this surface is registering for, when the scoped events describe
32707
32821
  * exactly one. More than one run means the visitor still has to choose.
@@ -32758,7 +32872,7 @@ function buildEventRegistrationInteractiveIslandProps(props) {
32758
32872
  source: props
32759
32873
  });
32760
32874
  }
32761
- var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS, EVENT_REGISTRATION_SHELL_STEP_LABELS, eventRegistrationPublicEventSchema, eventRegistrationHydrationSchemaShape, eventRegistrationSourceSchema, eventRegistrationDisplaySchema, eventRegistrationHydrationSchema, eventRegistrationRenderSchema, eventRegistrationIslandMetaCodec, eventRegistrationIslandMetaKeys, eventRegistrationBlockRuntime, eventRegistrationInteractiveIslandPropsCodec;
32875
+ var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS, EVENT_REGISTRATION_SHELL_STEP_LABELS, eventRegistrationPublicEventSchema, eventRegistrationHydrationSchemaShape, eventRegistrationEventSourceSchema, eventRegistrationSourceSchema, eventRegistrationDisplaySchema, eventRegistrationHydrationSchema, eventRegistrationRenderSchema, eventRegistrationIslandMetaCodec, eventRegistrationIslandMetaKeys, eventRegistrationBlockRuntime, eventRegistrationInteractiveIslandPropsCodec;
32762
32876
  var init_event_registration_interactive = __esmMin((() => {
32763
32877
  init_schemas();
32764
32878
  init_runGrouping();
@@ -32772,6 +32886,7 @@ var init_event_registration_interactive = __esmMin((() => {
32772
32886
  init_wizardSteps$1();
32773
32887
  init_registrationDerivations();
32774
32888
  init_registrationEventAdapter();
32889
+ init_eventSourceRecovery();
32775
32890
  EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS = [
32776
32891
  "Date",
32777
32892
  "Tickets",
@@ -32788,8 +32903,6 @@ var init_event_registration_interactive = __esmMin((() => {
32788
32903
  eventRegistrationHydrationSchemaShape = {
32789
32904
  occurrenceContext: occurrenceContextSchema.optional(),
32790
32905
  subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
32791
- events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
32792
- wholeSeriesRunEvents: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
32793
32906
  maxTickets: z$1.string().optional(),
32794
32907
  showVenue: z$1.boolean().optional(),
32795
32908
  showCapacity: z$1.boolean().optional(),
@@ -32801,12 +32914,22 @@ var init_event_registration_interactive = __esmMin((() => {
32801
32914
  sitePasses: publicPassProductCollectionSchema.nullable().optional(),
32802
32915
  siteMemberships: publicMembershipProductCollectionSchema.nullable().optional()
32803
32916
  };
32917
+ eventRegistrationEventSourceSchema = z$1.discriminatedUnion("kind", [z$1.object({
32918
+ kind: z$1.literal("loaded"),
32919
+ events: z$1.array(eventRegistrationPublicEventSchema)
32920
+ }), z$1.object({
32921
+ kind: z$1.literal("unresolved"),
32922
+ request: eventRecoveryRequestSchema.nullable()
32923
+ })]);
32804
32924
  eventRegistrationSourceSchema = z$1.object({
32805
32925
  siteId: z$1.string().optional(),
32806
32926
  apiBaseUrl: z$1.string().optional(),
32807
32927
  portalToken: z$1.string().nullable().optional(),
32808
32928
  previewToken: z$1.string().nullable().optional(),
32809
32929
  ...eventRegistrationHydrationSchemaShape,
32930
+ events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
32931
+ wholeSeriesRunEvents: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
32932
+ eventLoaderFailures: z$1.record(z$1.string(), z$1.unknown()).nullable().optional(),
32810
32933
  className: z$1.string().nullable().optional(),
32811
32934
  buttonText: z$1.string().nullable().optional(),
32812
32935
  maxTickets: z$1.string().nullable().optional(),
@@ -32827,7 +32950,10 @@ var init_event_registration_interactive = __esmMin((() => {
32827
32950
  titleText: z$1.string(),
32828
32951
  bodyText: z$1.string()
32829
32952
  })]);
32830
- eventRegistrationHydrationSchema = z$1.object(eventRegistrationHydrationSchemaShape);
32953
+ eventRegistrationHydrationSchema = z$1.object({
32954
+ ...eventRegistrationHydrationSchemaShape,
32955
+ eventSource: eventRegistrationEventSourceSchema
32956
+ });
32831
32957
  eventRegistrationRenderSchema = z$1.object({
32832
32958
  display: eventRegistrationDisplaySchema,
32833
32959
  hydration: eventRegistrationHydrationSchema
@@ -32847,14 +32973,21 @@ var init_event_registration_interactive = __esmMin((() => {
32847
32973
  render: createZodCodec(eventRegistrationRenderSchema)
32848
32974
  },
32849
32975
  buildRender: (source) => {
32850
- const scopedSourceEvents = scopeEventRegistrationSourceEvents(source);
32851
- const events = resolveLoadedEventRegistrationSourceEvents(source, scopedSourceEvents);
32976
+ const eventSource = resolveEventRegistrationEventSource({
32977
+ events: source.events,
32978
+ wholeSeriesRunEvents: source.wholeSeriesRunEvents,
32979
+ failures: source.eventLoaderFailures
32980
+ });
32981
+ const scopedSourceEvents = scopeEventRegistrationSourceEvents(source, eventSource);
32852
32982
  return {
32853
32983
  display: buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents),
32854
32984
  hydration: {
32855
32985
  occurrenceContext: source.occurrenceContext ?? null,
32856
32986
  subject: source.subject ?? null,
32857
- events,
32987
+ eventSource: eventSource.kind === "loaded" ? {
32988
+ ...eventSource,
32989
+ events: [...scopedSourceEvents]
32990
+ } : eventSource,
32858
32991
  maxTickets: source.maxTickets ?? void 0,
32859
32992
  showVenue: source.showVenue,
32860
32993
  showCapacity: source.showCapacity,
@@ -33249,6 +33382,7 @@ function buildNewsletterDisplay(source) {
33249
33382
  fields: { preset: "emailOnly" },
33250
33383
  includeOptionalPhone: false,
33251
33384
  buttonLabel: "Subscribe",
33385
+ successMessage: DEFAULT_MAILING_LIST_SUCCESS_MESSAGE,
33252
33386
  privacyNote: null
33253
33387
  };
33254
33388
  const targeting = source.targeting ?? { mode: "default" };
@@ -33258,6 +33392,7 @@ function buildNewsletterDisplay(source) {
33258
33392
  availability: runtimeTargetingIsAvailable(context, targeting, choices) ? "ready" : "unavailable",
33259
33393
  className: source.className ?? null,
33260
33394
  buttonLabel: form.buttonLabel,
33395
+ successMessage: form.successMessage,
33261
33396
  buttonVariant: source.buttonVariant ?? "primary",
33262
33397
  privacyNote: form.privacyNote,
33263
33398
  fields: getGlobalFormFields(form),
@@ -33267,7 +33402,7 @@ function buildNewsletterDisplay(source) {
33267
33402
  function projectNewsletterFormHydrationTarget(source) {
33268
33403
  switch (source.source) {
33269
33404
  case "block": {
33270
- const sourceRef = buildMailingListSignupBlockSourceRef(source.blockId);
33405
+ const sourceRef = buildMailingListSignupBlockSourceRef(source.blockId, source.contentVersionId);
33271
33406
  if (sourceRef?.tag === "block_ref") return {
33272
33407
  tag: "block-source",
33273
33408
  sourceRef
@@ -33367,7 +33502,7 @@ function parseRequiredMailingListSignedSourceToken(value) {
33367
33502
  if (!parsed) throw new Error("Mailing-list signup signed source ref requires token");
33368
33503
  return parsed;
33369
33504
  }
33370
- var newsletterButtonVariantSchema, mailingListContextSchema, mailingListTargetingSchema, newsletterFieldSchema, mailingListSignupBlockIdSchema, signedMailingListSourceTokenSchema, newsletterSourceCommonSchema, newsletterSourceSchema, newsletterDisplaySchema, newsletterHydrationSchema, newsletterRenderSchema, newsletterIslandMetaCodec, newsletterIslandMetaKeys, newsletterFormBlockRuntime, newsletterFormInteractiveIslandPropsCodec;
33505
+ var newsletterButtonVariantSchema, mailingListContextSchema, mailingListTargetingSchema, newsletterFieldSchema, mailingListSignupBlockIdSchema, mailingListContentVersionIdSchema, signedMailingListSourceTokenSchema, newsletterSourceCommonSchema, newsletterSourceSchema, newsletterDisplaySchema, newsletterHydrationSchema, newsletterRenderSchema, newsletterIslandMetaCodec, newsletterIslandMetaKeys, newsletterFormBlockRuntime, newsletterFormInteractiveIslandPropsCodec;
33371
33506
  var init_newsletter_form_interactive = __esmMin((() => {
33372
33507
  init_src$2();
33373
33508
  init_islands();
@@ -33405,6 +33540,15 @@ var init_newsletter_form_interactive = __esmMin((() => {
33405
33540
  placeholder: z$1.string().optional()
33406
33541
  });
33407
33542
  mailingListSignupBlockIdSchema = z$1.string().trim().min(1).transform(parseRequiredMailingListSignupBlockId);
33543
+ mailingListContentVersionIdSchema = z$1.string().transform((value, ctx) => {
33544
+ const parsed = parseMailingListContentVersionId(value);
33545
+ if (parsed) return parsed;
33546
+ ctx.addIssue({
33547
+ code: z$1.ZodIssueCode.custom,
33548
+ message: "Invalid mailing-list content version ID"
33549
+ });
33550
+ return z$1.NEVER;
33551
+ });
33408
33552
  signedMailingListSourceTokenSchema = z$1.string().trim().min(1).transform(parseRequiredMailingListSignedSourceToken);
33409
33553
  newsletterSourceCommonSchema = z$1.object({
33410
33554
  siteId: z$1.string().optional(),
@@ -33418,7 +33562,8 @@ var init_newsletter_form_interactive = __esmMin((() => {
33418
33562
  newsletterSourceSchema = z$1.discriminatedUnion("source", [
33419
33563
  newsletterSourceCommonSchema.extend({
33420
33564
  source: z$1.literal("block"),
33421
- blockId: z$1.string().nullable().optional()
33565
+ blockId: z$1.string().nullable().optional(),
33566
+ contentVersionId: z$1.string().nullable().optional()
33422
33567
  }),
33423
33568
  newsletterSourceCommonSchema.extend({
33424
33569
  source: z$1.literal("signed-footer"),
@@ -33434,6 +33579,7 @@ var init_newsletter_form_interactive = __esmMin((() => {
33434
33579
  availability: z$1.enum(["ready", "unavailable"]),
33435
33580
  className: z$1.string().nullable(),
33436
33581
  buttonLabel: z$1.string(),
33582
+ successMessage: z$1.string(),
33437
33583
  buttonVariant: newsletterButtonVariantSchema,
33438
33584
  privacyNote: z$1.string().nullable(),
33439
33585
  fields: z$1.array(newsletterFieldSchema),
@@ -33448,7 +33594,8 @@ var init_newsletter_form_interactive = __esmMin((() => {
33448
33594
  tag: z$1.literal("block-source"),
33449
33595
  sourceRef: z$1.object({
33450
33596
  tag: z$1.literal("block_ref"),
33451
- blockId: mailingListSignupBlockIdSchema
33597
+ blockId: mailingListSignupBlockIdSchema,
33598
+ contentVersionId: mailingListContentVersionIdSchema
33452
33599
  }).nullable()
33453
33600
  }),
33454
33601
  z$1.object({
@@ -92565,6 +92712,9 @@ function isApiSuccessResponse(json) {
92565
92712
  * });
92566
92713
  * ```
92567
92714
  */
92715
+ function publicEventsQuery(params) {
92716
+ return { ...params ?? {} };
92717
+ }
92568
92718
  function createBlockApi(config) {
92569
92719
  const { baseUrl, auth, authOverrides, siteId, isPreview } = config;
92570
92720
  const dedup = createDeduplicationCache({ ttl: 100 });
@@ -92717,23 +92867,7 @@ function createBlockApi(config) {
92717
92867
  const path = buildPath(EVENTS.list.path, { siteId: sid });
92718
92868
  return request(EVENTS.list, {
92719
92869
  path,
92720
- query: {
92721
- from: params?.from,
92722
- to: params?.to,
92723
- afterStartsAt: params?.afterStartsAt,
92724
- afterId: params?.afterId,
92725
- limit: params?.limit,
92726
- stage: params?.stage,
92727
- eventSurface: params?.eventSurface,
92728
- eventPresets: params?.eventPresets,
92729
- scheduleScope: params?.scheduleScope,
92730
- categoryIds: params?.categoryIds,
92731
- venueId: params?.venueId,
92732
- staffMemberId: params?.staffMemberId,
92733
- seriesId: params?.seriesId,
92734
- includeOccurrenceId: params?.includeOccurrenceId,
92735
- detailLevel: params?.detailLevel
92736
- }
92870
+ query: publicEventsQuery(params)
92737
92871
  });
92738
92872
  },
92739
92873
  async getEventFilters(params) {
@@ -92797,7 +92931,7 @@ function createBlockApi(config) {
92797
92931
  const path = buildPath(WHOLE_SERIES.waitlistClaimResolve.path, { siteId: sid });
92798
92932
  return request(WHOLE_SERIES.waitlistClaimResolve, {
92799
92933
  path,
92800
- body: { claimToken: data.claimToken }
92934
+ body: data
92801
92935
  });
92802
92936
  },
92803
92937
  async getDiscountsAvailable(data) {
@@ -100427,12 +100561,6 @@ var init_ActionRow = __esmMin((() => {
100427
100561
  between: "rb-justify-between"
100428
100562
  };
100429
100563
  }));
100430
- var init_BookingOptionCompactRow = __esmMin((() => {
100431
- init_buttons();
100432
- }));
100433
- var init_BookingOptionList = __esmMin((() => {
100434
- init_BookingOptionCompactRow();
100435
- }));
100436
100564
  //#endregion
100437
100565
  //#region ../blocks/src/system/runtime/shared/components/LoggedInAsUser.tsx
100438
100566
  /**
@@ -100557,8 +100685,6 @@ var init_components = __esmMin((() => {
100557
100685
  init_CrossIcon();
100558
100686
  init_DiscountCodeDisclosure();
100559
100687
  init_ActionRow();
100560
- init_BookingOptionCompactRow();
100561
- init_BookingOptionList();
100562
100688
  init_FieldValidationMessage();
100563
100689
  init_FeedbackMessage();
100564
100690
  init_LoggedInAsUser();
@@ -101176,6 +101302,93 @@ var init_event_registration_headless_state = __esmMin((() => {
101176
101302
  init_event_registration_headless_planning();
101177
101303
  }));
101178
101304
  //#endregion
101305
+ //#region ../blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.ts
101306
+ /** Recovery may select held places; checkout still owns admission and payment validation. */
101307
+ function checkoutRecoveryOptionAvailability(availability) {
101308
+ if (availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable") return {
101309
+ kind: "available",
101310
+ remainingPlaces: null
101311
+ };
101312
+ return availability;
101313
+ }
101314
+ /**
101315
+ * A form-only projection for the explicit existing-checkout path. It permits
101316
+ * collecting the original selection without claiming a new place is available.
101317
+ * The public checkout service identifies the customer and remains the admission
101318
+ * authority; no reservation/customer data is exposed through this projection.
101319
+ */
101320
+ function getCheckoutRecoveryFormEligibility(eligibility) {
101321
+ if (!eligibility || eligibility.registration.kind !== "none" && eligibility.registration.kind !== "pending_payment" || eligibility.availability.kind === "unavailable" && eligibility.availability.reason !== "full" && eligibility.availability.reason !== "selectionRequired") return eligibility;
101322
+ const amountCents = eligibility.price ?? 0;
101323
+ if (amountCents <= 0 || !eligibility.currency || eligibility.availability.kind === "unavailable" && eligibility.availability.reason === "selectionRequired") return eligibility.registration.kind === "pending_payment" ? {
101324
+ ...eligibility,
101325
+ registration: { kind: "none" },
101326
+ ticketTypes: eligibility.ticketTypes.map((option) => ({
101327
+ ...option,
101328
+ availability: checkoutRecoveryOptionAvailability(option.availability)
101329
+ }))
101330
+ } : eligibility;
101331
+ const currency = eligibility.currency;
101332
+ const paymentOptions = eligibility.paymentTerms.allowedOptions.map((option) => {
101333
+ switch (option.kind) {
101334
+ case "upfront": return {
101335
+ kind: "payInFull",
101336
+ amountCents,
101337
+ currency
101338
+ };
101339
+ case "deferred_manual": return {
101340
+ kind: "deferredManual",
101341
+ amountCents,
101342
+ currency
101343
+ };
101344
+ case "instalment_plan": return {
101345
+ kind: "instalmentPlan",
101346
+ amountCents,
101347
+ currency
101348
+ };
101349
+ case "flexible_balance": return {
101350
+ kind: "flexibleBalance",
101351
+ amountCents,
101352
+ currency
101353
+ };
101354
+ }
101355
+ });
101356
+ return {
101357
+ ...eligibility,
101358
+ registration: { kind: "none" },
101359
+ availability: {
101360
+ kind: "available",
101361
+ remainingPlaces: null,
101362
+ waitlistEnabled: eligibility.waitlistEnabled
101363
+ },
101364
+ eligible: paymentOptions.length > 0,
101365
+ isFull: false,
101366
+ canJoinWaitlist: false,
101367
+ isFree: false,
101368
+ requiresPayment: true,
101369
+ canPayDirectly: paymentOptions.length > 0,
101370
+ paymentOptions,
101371
+ eligiblePasses: [],
101372
+ eligibleMemberships: [],
101373
+ ticketTypes: eligibility.ticketTypes.map((option) => ({
101374
+ ...option,
101375
+ availability: checkoutRecoveryOptionAvailability(option.availability)
101376
+ }))
101377
+ };
101378
+ }
101379
+ function isSoldOutEventSelectable(event, waitlistAvailable) {
101380
+ return waitlistAvailable || canRecoverEventCheckout(event);
101381
+ }
101382
+ function canJoinWaitlistOutsideRecovery(event, attendanceMode, checkoutRecovery) {
101383
+ return !checkoutRecovery && event !== null && canJoinEventWaitlist(event, { attendanceMode });
101384
+ }
101385
+ function canRecoverEventCheckout(event) {
101386
+ return event !== null && (event.registrationSubject.kind === "wholeSeries" || event.pricing.kind !== "free" && event.pricing.kind !== "external");
101387
+ }
101388
+ var init_checkoutRecovery = __esmMin((() => {
101389
+ init_domain();
101390
+ }));
101391
+ //#endregion
101179
101392
  //#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
101180
101393
  function getPortalSubjectEmail(profile) {
101181
101394
  return profile?.email ?? null;
@@ -101347,6 +101560,7 @@ function getEventSelectionMode(events) {
101347
101560
  }
101348
101561
  var EventSelectionStep;
101349
101562
  var init_EventSelectionStep = __esmMin((() => {
101563
+ init_checkoutRecovery();
101350
101564
  init_utils();
101351
101565
  init_domain();
101352
101566
  EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCapacity }) => {
@@ -101363,7 +101577,7 @@ var init_EventSelectionStep = __esmMin((() => {
101363
101577
  const remaining = getRemainingPlaces(selectMostOpenCapacitySource(event));
101364
101578
  const isSoldOut = isEventFull(event);
101365
101579
  const canJoinWaitlist = canJoinEventWaitlistOnAnyMode(event);
101366
- const isUnavailable = isSoldOut && !canJoinWaitlist;
101580
+ const isUnavailable = isSoldOut && !isSoldOutEventSelectable(event, canJoinWaitlist);
101367
101581
  const isLowCapacity = remaining.kind === "low";
101368
101582
  const capacityLabel = formatEventRemainingPlaces(event, { full: "Sold out" });
101369
101583
  const timeZone = event.timeZone ?? null;
@@ -101409,6 +101623,36 @@ var init_EventSelectionStep = __esmMin((() => {
101409
101623
  };
101410
101624
  }));
101411
101625
  //#endregion
101626
+ //#region ../blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.ts
101627
+ /** Recovery belongs to the selected booking subject; changing events resets its scope. */
101628
+ function useCheckoutRecovery(event, setStep) {
101629
+ const [recoveryEventId, setRecoveryEventId] = useState(null);
101630
+ return {
101631
+ checkoutRecovery: event !== null && recoveryEventId === event.selectionId,
101632
+ startCheckoutRecovery: useCallback(() => {
101633
+ if (!event) return;
101634
+ setRecoveryEventId(event.selectionId);
101635
+ setStep("select-tickets");
101636
+ }, [event, setStep])
101637
+ };
101638
+ }
101639
+ /** Authenticated pending bookings enter the same form-only recovery path as guests. */
101640
+ function useCheckoutRecoveryEligibility(eligibility, step, checkoutRecovery, startCheckoutRecovery) {
101641
+ const registrationKind = eligibility?.registration.kind;
101642
+ useEffect(() => {
101643
+ if ((step === "select-event" || step === "select-tickets" || step === "enter-details" || step === "select-payment") && registrationKind === "pending_payment" && !checkoutRecovery) startCheckoutRecovery();
101644
+ }, [
101645
+ registrationKind,
101646
+ step,
101647
+ checkoutRecovery,
101648
+ startCheckoutRecovery
101649
+ ]);
101650
+ return useMemo(() => checkoutRecovery ? getCheckoutRecoveryFormEligibility(eligibility) : eligibility, [checkoutRecovery, eligibility]);
101651
+ }
101652
+ var init_useCheckoutRecovery = __esmMin((() => {
101653
+ init_checkoutRecovery();
101654
+ }));
101655
+ //#endregion
101412
101656
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
101413
101657
  function resolveRegistrationRecoveryAction(step, action) {
101414
101658
  if (step === "payment-failed") return "payment-options";
@@ -102281,6 +102525,10 @@ var init_event_registration_errors = __esmMin((() => {
102281
102525
  message: "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.",
102282
102526
  action: "payment-status"
102283
102527
  },
102528
+ paymentProviderUnavailable: {
102529
+ message: "We couldn’t reach the payment provider. Please try again in a minute.",
102530
+ action: "retry"
102531
+ },
102284
102532
  paymentPageUnavailable: {
102285
102533
  message: "We couldn’t open the payment page. Please refresh this page and try again. If this keeps happening, contact the organiser for help.",
102286
102534
  action: "retry"
@@ -102466,11 +102714,6 @@ function ensureWaitlistClaimLocationTracking() {
102466
102714
  } catch {}
102467
102715
  window.addEventListener("popstate", emitWaitlistClaimLocationChange);
102468
102716
  }
102469
- function getWaitlistClaimTokenFromUrl() {
102470
- if (typeof window === "undefined") return null;
102471
- const token = new URLSearchParams(window.location.search).get("waitlist_claim")?.trim() ?? "";
102472
- return token.length > 0 ? token : null;
102473
- }
102474
102717
  function subscribeToWaitlistClaimToken(callback) {
102475
102718
  if (typeof window === "undefined") return () => {};
102476
102719
  ensureWaitlistClaimLocationTracking();
@@ -102479,28 +102722,42 @@ function subscribeToWaitlistClaimToken(callback) {
102479
102722
  window.removeEventListener(WAITLIST_CLAIM_LOCATION_EVENT, callback);
102480
102723
  };
102481
102724
  }
102482
- function getWaitlistClaimTokenSnapshot() {
102483
- return getWaitlistClaimTokenFromUrl();
102725
+ function getWaitlistClaimLocationSnapshot() {
102726
+ return typeof window === "undefined" ? "" : window.location.search;
102727
+ }
102728
+ function parseWaitlistClaimCredential(search) {
102729
+ const params = new URLSearchParams(search);
102730
+ const token = params.get("waitlist_claim")?.trim();
102731
+ if (token) return {
102732
+ kind: "emailedToken",
102733
+ token
102734
+ };
102735
+ const entryId = params.get("waitlistEntry")?.trim();
102736
+ return entryId ? {
102737
+ kind: "portalOwnedEntry",
102738
+ entryId
102739
+ } : null;
102484
102740
  }
102485
102741
  function useWaitlistClaim() {
102486
102742
  return useWaitlistClaimWithDeps(useWaitlistClaimDeps);
102487
102743
  }
102488
102744
  function useWaitlistClaimWithDeps(deps) {
102489
- return useResolvedWaitlistClaim(deps, useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimTokenSnapshot, () => null));
102745
+ const locationSearch = useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimLocationSnapshot, () => "");
102746
+ return useResolvedWaitlistClaim(deps, useMemo(() => parseWaitlistClaimCredential(locationSearch), [locationSearch]));
102490
102747
  }
102491
- function useResolvedWaitlistClaim(deps, token) {
102748
+ function useResolvedWaitlistClaim(deps, credential) {
102492
102749
  const api = deps.useBlockApi();
102493
- const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(token), createInitialWaitlistClaimState);
102750
+ const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(credential), createInitialWaitlistClaimState);
102494
102751
  useEffect(() => {
102495
102752
  let cancelled = false;
102496
102753
  async function resolveClaim() {
102497
- if (!token) {
102754
+ if (!credential) {
102498
102755
  dispatch({ type: "cleared" });
102499
102756
  return;
102500
102757
  }
102501
102758
  dispatch({ type: "started" });
102502
102759
  try {
102503
- const result = await api.resolveWaitlistClaim({ claimToken: token });
102760
+ const result = credential.kind === "portalOwnedEntry" ? await api.resolveWaitlistClaim({ waitlistEntryId: credential.entryId }) : await api.resolveWaitlistClaim({ claimToken: credential.token });
102504
102761
  if (cancelled) return;
102505
102762
  dispatch({
102506
102763
  type: "resolved",
@@ -102518,9 +102775,10 @@ function useResolvedWaitlistClaim(deps, token) {
102518
102775
  return () => {
102519
102776
  cancelled = true;
102520
102777
  };
102521
- }, [api, token]);
102778
+ }, [api, credential]);
102522
102779
  return {
102523
- token,
102780
+ token: credential?.kind === "emailedToken" ? credential.token : null,
102781
+ entryId: credential?.kind === "portalOwnedEntry" ? credential.entryId : null,
102524
102782
  claim: getWaitlistClaim(state),
102525
102783
  error: getWaitlistClaimError(state),
102526
102784
  loginMessage: getWaitlistClaimLoginMessage(state),
@@ -103030,15 +103288,12 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
103030
103288
  * landed — a success, or a hand-off to checkout — because until then nobody
103031
103289
  * knows whether the first one committed.
103032
103290
  *
103033
- * Reusing it after a failure is safe even if the customer edits their
103034
- * details. The server consults the command record before it re-checks
103035
- * anything, so a submission that already booked is answered with the booking
103036
- * that exists — not refused for spending a credit or a claim that this very
103037
- * command already spent, and not treated as a second booking because a name
103038
- * or a note changed in between.
103291
+ * Identical retries retain the command after a lost response. Changed form
103292
+ * details get a new command so the server applies the new booking intent.
103039
103293
  */
103040
- const commandIdRef = useRef(null);
103041
- return async (method, passId, membershipId, selection, submitOptions) => {
103294
+ const commandRef = useRef(null);
103295
+ const inFlightRef = useRef(null);
103296
+ const submit = async (method, passId, membershipId, selection, submitOptions) => {
103042
103297
  const target = options.registrationTarget;
103043
103298
  if (!target) return {
103044
103299
  ok: false,
@@ -103046,44 +103301,34 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
103046
103301
  message: "Select an event to continue."
103047
103302
  };
103048
103303
  options.setStep("submitting");
103049
- const registrationCommandId = commandIdRef.current ?? deps.createClientCommandId();
103050
- commandIdRef.current = registrationCommandId;
103304
+ const registrationCommandId = commandRef.current?.id ?? deps.createClientCommandId();
103051
103305
  try {
103052
- const prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
103306
+ let prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
103053
103307
  if (prepared.subject.kind === "wholeSeries" && method === "stripe") {
103054
- commandIdRef.current = null;
103308
+ commandRef.current = null;
103055
103309
  return await submitWholeSeriesCheckout(options, deps, {
103056
103310
  ...prepared,
103057
103311
  subject: prepared.subject
103058
103312
  }, submitOptions);
103059
103313
  }
103314
+ const request = buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId);
103315
+ const intentKey = registrationRequestIntentKey(request);
103316
+ if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) prepared = {
103317
+ ...prepared,
103318
+ registrationCommandId: deps.createClientCommandId()
103319
+ };
103320
+ commandRef.current = {
103321
+ id: prepared.registrationCommandId,
103322
+ intentKey
103323
+ };
103060
103324
  const result = await options.api.registerForEvent({
103061
- registrationCommandId: prepared.registrationCommandId,
103062
- subject: prepared.subject,
103063
- ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
103064
- selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
103065
- email: options.formData.email.trim().toLowerCase(),
103066
- name: options.formData.name.trim(),
103067
- phone: options.formData.phone.trim() || void 0,
103068
- notes: options.formData.notes.trim() || void 0,
103069
- consentAccepted: options.formData.consentAccepted,
103070
- altchaSolution: options.altchaSolution,
103071
- paymentMethod: method,
103072
- customerPassId: method === "pass" ? passId : void 0,
103073
- customerMembershipId: method === "membership" ? membershipId : void 0,
103074
- bundleProductId: prepared.bundleProductId,
103075
- claimToken: options.claimToken ?? void 0,
103076
- guests: prepared.guestsPayload
103325
+ ...request,
103326
+ registrationCommandId: prepared.registrationCommandId
103077
103327
  });
103078
- commandIdRef.current = null;
103079
- if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
103080
- options.setRegistrationResult(toRegistrationResult(result));
103081
- options.setStep("success");
103082
- return {
103083
- ok: true,
103084
- outcome: { kind: "completed" }
103085
- };
103328
+ commandRef.current = null;
103329
+ return await completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions);
103086
103330
  } catch (error) {
103331
+ if (error instanceof BlockApiError && error.tag === "registrationPreparationChanged") commandRef.current = null;
103087
103332
  const { message, action } = registrationErrorPresentation(error);
103088
103333
  options.setErrorAction?.(action);
103089
103334
  options.setErrorMessage(message);
@@ -103095,6 +103340,24 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
103095
103340
  };
103096
103341
  }
103097
103342
  };
103343
+ return (...args) => {
103344
+ if (inFlightRef.current) return inFlightRef.current;
103345
+ const pending = Promise.resolve().then(() => submit(...args));
103346
+ inFlightRef.current = pending;
103347
+ pending.finally(() => {
103348
+ if (inFlightRef.current === pending) inFlightRef.current = null;
103349
+ });
103350
+ return pending;
103351
+ };
103352
+ }
103353
+ async function completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions) {
103354
+ if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
103355
+ options.setRegistrationResult(toRegistrationResult(result));
103356
+ options.setStep("success");
103357
+ return {
103358
+ ok: true,
103359
+ outcome: { kind: "completed" }
103360
+ };
103098
103361
  }
103099
103362
  function toTicketSelectionRequests(lines) {
103100
103363
  return lines.map((line) => ({
@@ -103169,6 +103432,7 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
103169
103432
  altchaSolution: options.altchaSolution,
103170
103433
  guests: prepared.guestsPayload,
103171
103434
  claimToken: options.claimToken ?? void 0,
103435
+ waitlistEntryId: options.waitlistEntryId ?? void 0,
103172
103436
  discountCode: options.discountCode.trim() || void 0,
103173
103437
  collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
103174
103438
  checkoutAttemptId,
@@ -103190,14 +103454,14 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
103190
103454
  }
103191
103455
  if (result.bypassed) return completeBypassedCheckout(options);
103192
103456
  if (!result.checkoutUrl) throw new Error("Checkout URL missing");
103193
- savePendingCheckout(options, deps, prepared, checkoutAttemptId, {
103457
+ savePendingCheckout(options, deps, prepared, result.checkoutAttemptId, {
103194
103458
  scope: "wholeSeries",
103195
103459
  registrationId: result.registrationId
103196
103460
  });
103197
103461
  return redirectToCheckout(result.checkoutUrl, submitOptions);
103198
103462
  }
103199
103463
  function needsOccurrenceCheckout(result, method) {
103200
- return result.scope === "occurrence" && !result.alreadyRegistered && result.status === "confirmed" && result.pendingPayment && [
103464
+ return result.scope === "occurrence" && result.status === "confirmed" && result.pendingPayment && [
103201
103465
  "stripe",
103202
103466
  "pass_bundle",
103203
103467
  "membership_bundle"
@@ -103217,6 +103481,7 @@ async function submitOccurrenceCheckout(options, deps, prepared, registration, m
103217
103481
  kind: "occurrence",
103218
103482
  attendeeId: registration.attendeeId
103219
103483
  },
103484
+ registrationCommandId: prepared.registrationCommandId,
103220
103485
  checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
103221
103486
  productId: prepared.bundleProductId,
103222
103487
  discountCode: options.discountCode.trim() || void 0,
@@ -103259,10 +103524,36 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
103259
103524
  }
103260
103525
  };
103261
103526
  }
103527
+ function registrationRequestIntentKey(request) {
103528
+ const { registrationCommandId: _command, altchaSolution: _proof, ...intent } = request;
103529
+ return JSON.stringify(intent);
103530
+ }
103531
+ function buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId) {
103532
+ return {
103533
+ registrationCommandId: prepared.registrationCommandId,
103534
+ subject: prepared.subject,
103535
+ ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
103536
+ selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
103537
+ email: options.formData.email.trim().toLowerCase(),
103538
+ name: options.formData.name.trim(),
103539
+ phone: options.formData.phone.trim() || void 0,
103540
+ notes: options.formData.notes.trim() || void 0,
103541
+ consentAccepted: options.formData.consentAccepted,
103542
+ altchaSolution: options.altchaSolution,
103543
+ paymentMethod: method,
103544
+ customerPassId: method === "pass" ? passId : void 0,
103545
+ customerMembershipId: method === "membership" ? membershipId : void 0,
103546
+ bundleProductId: prepared.bundleProductId,
103547
+ claimToken: options.claimToken ?? void 0,
103548
+ waitlistEntryId: options.waitlistEntryId ?? void 0,
103549
+ guests: prepared.guestsPayload
103550
+ };
103551
+ }
103262
103552
  var eventRegistrationSubmitDeps;
103263
103553
  var init_useEventRegistrationSubmit = __esmMin((() => {
103264
- init_registrationErrorPresentation();
103554
+ init_client$1();
103265
103555
  init_shared();
103556
+ init_registrationErrorPresentation();
103266
103557
  init_constants();
103267
103558
  init_sessionStorage();
103268
103559
  init_ticketSelectionLines();
@@ -103509,14 +103800,28 @@ function useEventRegistrationWizardWithDeps(options, deps) {
103509
103800
  }), [options.occurrenceContext, selectedEvent]);
103510
103801
  const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
103511
103802
  const currentEvent = selectedEvent ?? preSelectedEvent;
103803
+ const setStep = useCallback((nextStep) => {
103804
+ dispatchFlow({
103805
+ type: "set-step",
103806
+ step: nextStep
103807
+ });
103808
+ }, []);
103809
+ const { checkoutRecovery, startCheckoutRecovery } = useCheckoutRecovery(currentEvent, setStep);
103512
103810
  const currentEventUsesTicketTypes = usesTieredPricing(currentEvent);
103513
- const currentCanJoinWaitlist = currentEvent ? canJoinEventWaitlist(currentEvent, { attendanceMode: selectedAttendanceMode }) : false;
103811
+ const currentCanJoinWaitlist = canJoinWaitlistOutsideRecovery(currentEvent, selectedAttendanceMode, checkoutRecovery);
103514
103812
  const usesTicketTypeSelections = currentEventUsesTicketTypes && !currentCanJoinWaitlist;
103515
103813
  const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
103516
103814
  event: currentEvent,
103517
103815
  eligibility: null,
103518
103816
  selectedAttendanceMode
103519
- }), [currentEvent, selectedAttendanceMode]);
103817
+ }).map((option) => checkoutRecovery ? {
103818
+ ...option,
103819
+ availability: checkoutRecoveryOptionAvailability(option.availability)
103820
+ } : option), [
103821
+ currentEvent,
103822
+ selectedAttendanceMode,
103823
+ checkoutRecovery
103824
+ ]);
103520
103825
  const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
103521
103826
  const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
103522
103827
  const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
@@ -103554,17 +103859,11 @@ function useEventRegistrationWizardWithDeps(options, deps) {
103554
103859
  isAuthenticated: portalAuthState === "authenticated",
103555
103860
  occurrenceId: registrationOccurrenceId
103556
103861
  });
103557
- const eligibility = eligibilityResult.eligibility;
103862
+ const eligibility = useCheckoutRecoveryEligibility(eligibilityResult.eligibility, step, checkoutRecovery, startCheckoutRecovery);
103558
103863
  const eligibilityLoading = eligibilityResult.isLoading;
103559
103864
  const eligibilityError = eligibilityResult.error;
103560
103865
  const portalCreditState = eligibilityResult.creditState;
103561
103866
  const registrationState = eligibility?.registration ?? { kind: "none" };
103562
- const setStep = useCallback((nextStep) => {
103563
- dispatchFlow({
103564
- type: "set-step",
103565
- step: nextStep
103566
- });
103567
- }, []);
103568
103867
  const setTicketsCount = useCallback((nextTicketsCount) => {
103569
103868
  dispatchFlow({
103570
103869
  type: "set-tickets-count",
@@ -103672,10 +103971,14 @@ function useEventRegistrationWizardWithDeps(options, deps) {
103672
103971
  event: currentEvent,
103673
103972
  eligibility,
103674
103973
  selectedAttendanceMode
103675
- }), [
103974
+ }).map((option) => checkoutRecovery ? {
103975
+ ...option,
103976
+ availability: checkoutRecoveryOptionAvailability(option.availability)
103977
+ } : option), [
103676
103978
  currentEvent,
103677
103979
  selectedAttendanceMode,
103678
- eligibility
103980
+ eligibility,
103981
+ checkoutRecovery
103679
103982
  ]);
103680
103983
  const singleSelectedPricingOptionId = getSingleSelectedPricingOptionId(normalizedSelectedTicketLines);
103681
103984
  const selectedTicketType = useMemo(() => findSelectedTicketType({
@@ -103699,8 +104002,12 @@ function useEventRegistrationWizardWithDeps(options, deps) {
103699
104002
  const event = currentEvent;
103700
104003
  if (!usesTieredPricing(event)) return false;
103701
104004
  if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
103702
- return !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
103703
- }, [currentEvent, selectedAttendanceMode]);
104005
+ return checkoutRecovery || !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
104006
+ }, [
104007
+ currentEvent,
104008
+ selectedAttendanceMode,
104009
+ checkoutRecovery
104010
+ ]);
103704
104011
  const hasValidTicketSelection = hasValidPricingOptionSelection({
103705
104012
  selectionRequired: ticketTypeSelectionRequired,
103706
104013
  lines: normalizedSelectedTicketLines,
@@ -103904,6 +104211,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
103904
104211
  guests,
103905
104212
  discountCode: discountUi.discountCode,
103906
104213
  claimToken: waitlistClaim.token,
104214
+ waitlistEntryId: waitlistClaim.entryId,
103907
104215
  setPendingRegistrationReference,
103908
104216
  setStep,
103909
104217
  setRegistrationResult: (result) => setRegistrationResult(result),
@@ -103966,6 +104274,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
103966
104274
  scopedEvents,
103967
104275
  preSelectedEvent,
103968
104276
  hasPreSelectedContext,
104277
+ checkoutRecovery,
104278
+ startCheckoutRecovery,
103969
104279
  step,
103970
104280
  setStep,
103971
104281
  selectedEvent,
@@ -104050,6 +104360,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
104050
104360
  }
104051
104361
  var eventRegistrationWizardDeps;
104052
104362
  var init_useEventRegistrationWizard = __esmMin((() => {
104363
+ init_checkoutRecovery();
104364
+ init_useCheckoutRecovery();
104053
104365
  init_src$2();
104054
104366
  init_registrationErrorRecovery();
104055
104367
  init_api();
@@ -104212,6 +104524,50 @@ var init_MagicLinkForm = __esmMin((() => {
104212
104524
  init_MagicLinkForm_state();
104213
104525
  }));
104214
104526
  //#endregion
104527
+ //#region ../blocks/src/system/runtime/nodes/event-registration/ErrorStep.tsx
104528
+ var labels, ErrorStep;
104529
+ var init_ErrorStep = __esmMin((() => {
104530
+ init_shared();
104531
+ labels = {
104532
+ none: "",
104533
+ retry: "Try again",
104534
+ places: "Choose places",
104535
+ start: "Start again",
104536
+ details: "Check my details",
104537
+ "payment-options": "View payment options",
104538
+ "payment-status": "Check payment status",
104539
+ portal: "View my bookings",
104540
+ event: "View event"
104541
+ };
104542
+ ErrorStep = ({ message, onRetry, action = "retry", canJoinWaitlist = false }) => {
104543
+ const offerWaitlist = action === "places" && canJoinWaitlist;
104544
+ return /* @__PURE__ */ jsx(TerminalPanel, {
104545
+ tone: "error",
104546
+ className: "er-center",
104547
+ titleClassName: "er-title--lg er-message",
104548
+ icon: /* @__PURE__ */ jsx(StateIcon, {
104549
+ variant: "error",
104550
+ children: /* @__PURE__ */ jsx(CrossIcon, {})
104551
+ }),
104552
+ title: "We couldn’t complete your booking",
104553
+ body: /* @__PURE__ */ jsx("p", {
104554
+ className: "er-text--muted er-message",
104555
+ children: offerWaitlist ? "Sorry, this event is now full. You can join the waiting list, and we’ll email you if a place becomes available." : message
104556
+ }),
104557
+ actions: action === "none" ? void 0 : action === "portal" || action === "payment-status" ? /* @__PURE__ */ jsx("a", {
104558
+ href: "/portal",
104559
+ className: "er-retry-btn",
104560
+ children: labels[action]
104561
+ }) : /* @__PURE__ */ jsx("button", {
104562
+ type: "button",
104563
+ onClick: onRetry,
104564
+ className: "er-retry-btn",
104565
+ children: offerWaitlist ? "Join the waiting list" : labels[action]
104566
+ })
104567
+ });
104568
+ };
104569
+ }));
104570
+ //#endregion
104215
104571
  //#region ../blocks/src/system/runtime/nodes/event-registration/EventRegistrationSummaryBar.tsx
104216
104572
  function getScheduleSummary(wizard, summaryEvent) {
104217
104573
  if (summaryEvent.registrationSubject.kind !== "wholeSeries") {
@@ -104501,7 +104857,7 @@ function SelectTicketsActions(props) {
104501
104857
  const currentEvent = wizard.selectedEvent ?? wizard.preSelectedEvent;
104502
104858
  const registrationOptionsPending = wizard.registrationOptionsState.tag === "idle" || wizard.registrationOptionsState.tag === "loading";
104503
104859
  const registrationOptionsFailed = wizard.registrationOptionsState.tag === "failed";
104504
- const isSoldOutWithoutWaitlist = !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
104860
+ const isSoldOutWithoutWaitlist = !wizard.checkoutRecovery && !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
104505
104861
  const isCheckingExistingRegistration = wizard.portalAuthState === "authenticated" && wizard.existingRegistrationLoading;
104506
104862
  const hasExistingRegistration = isExistingRegistrationBlocking$1(wizard);
104507
104863
  const ticketTypeSelectionBlocked = wizard.ticketTypeSelectionRequired && !wizard.hasValidTicketSelection;
@@ -105106,21 +105462,42 @@ function resolveTicketSelectionPricing(event) {
105106
105462
  currency: event ? publicEventPricingCurrency(event.pricing) : null
105107
105463
  };
105108
105464
  }
105465
+ function CheckoutRecoveryEntry(props) {
105466
+ return props.onContinue ? /* @__PURE__ */ jsx("button", {
105467
+ type: "button",
105468
+ className: "er-back-btn",
105469
+ onClick: props.onContinue,
105470
+ children: "Continue an existing booking"
105471
+ }) : null;
105472
+ }
105473
+ function getTicketSelectionCapacity(event, attendanceMode, checkoutRecovery) {
105474
+ if (checkoutRecovery) return {
105475
+ availableSpots: null,
105476
+ isSoldOut: false,
105477
+ canJoinWaitlist: false,
105478
+ eventAvailabilityLabel: null
105479
+ };
105480
+ const source = event ? selectEventCapacitySource(event, attendanceMode) : null;
105481
+ const availability = source ? getEventAvailability(source) : null;
105482
+ const canJoinWaitlist = source ? canJoinEventWaitlist(source) : false;
105483
+ return {
105484
+ availableSpots: availability?.available,
105485
+ isSoldOut: availability?.isFull ?? false,
105486
+ canJoinWaitlist,
105487
+ eventAvailabilityLabel: !canJoinWaitlist && source ? formatRemainingPlaces(source) : null
105488
+ };
105489
+ }
105109
105490
  var TicketSelectionStep;
105110
105491
  var init_TicketSelectionStep = __esmMin((() => {
105111
105492
  init_src$2();
105112
105493
  init_domain();
105113
105494
  init_utils();
105114
105495
  init_ticketSelectionLines();
105115
- TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" } }) => {
105496
+ TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" }, checkoutRecovery = false, onCheckoutRecovery }) => {
105116
105497
  const unit = bookingUnit.kind;
105117
105498
  const deliveryMode = event?.deliveryMode ?? "in_person";
105118
105499
  const attendanceModes = event?.attendanceModes ?? [];
105119
- const capacitySource = event ? selectEventCapacitySource(event, selectedAttendanceMode) : null;
105120
- const availability = capacitySource ? getEventAvailability(capacitySource) : null;
105121
- const availableSpots = availability?.available;
105122
- const isSoldOut = availability?.isFull ?? false;
105123
- const canJoinWaitlist = capacitySource ? canJoinEventWaitlist(capacitySource) : false;
105500
+ const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode, checkoutRecovery);
105124
105501
  const { mode: eventPricingMode, currency: eventPricingCurrency } = resolveTicketSelectionPricing(event);
105125
105502
  const usesTicketTypes = eventPricingMode === "tiered" && !canJoinWaitlist;
105126
105503
  const visibleTicketTypes = usesTicketTypes ? visibleTicketTypesOverride ?? getVisibleTicketTypes({
@@ -105139,7 +105516,6 @@ var init_TicketSelectionStep = __esmMin((() => {
105139
105516
  selectedTicketTypeRemainingCapacity: implicitTicketType?.availability.remainingPlaces ?? null,
105140
105517
  hasSelectedTicketType: implicitTicketType !== null
105141
105518
  });
105142
- const eventAvailabilityLabel = !canJoinWaitlist && capacitySource ? formatRemainingPlaces(capacitySource) : null;
105143
105519
  if (deliveryMode === "hybrid" && !selectedAttendanceMode) return /* @__PURE__ */ jsxs("div", {
105144
105520
  className: "rb-reg-stack er-stack",
105145
105521
  children: [
@@ -105160,13 +105536,17 @@ var init_TicketSelectionStep = __esmMin((() => {
105160
105536
  });
105161
105537
  if (isSoldOut && !canJoinWaitlist) return /* @__PURE__ */ jsxs("div", {
105162
105538
  className: "rb-reg-stack er-stack",
105163
- children: [/* @__PURE__ */ jsx("h3", {
105164
- className: "er-title",
105165
- children: "Sold out"
105166
- }), /* @__PURE__ */ jsx("p", {
105167
- className: "er-text er-text--muted",
105168
- children: "Sorry you missed out! This event is fully booked."
105169
- })]
105539
+ children: [
105540
+ /* @__PURE__ */ jsx("h3", {
105541
+ className: "er-title",
105542
+ children: "Sold out"
105543
+ }),
105544
+ /* @__PURE__ */ jsx("p", {
105545
+ className: "er-text er-text--muted",
105546
+ children: "Sorry you missed out! This event is fully booked."
105547
+ }),
105548
+ /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })
105549
+ ]
105170
105550
  });
105171
105551
  if (!eventPricingCurrency) return /* @__PURE__ */ jsx("div", {
105172
105552
  className: "rb-reg-stack er-stack",
@@ -105234,9 +105614,13 @@ var init_TicketSelectionStep = __esmMin((() => {
105234
105614
  })]
105235
105615
  })
105236
105616
  ] }),
105237
- canJoinWaitlist && /* @__PURE__ */ jsx("p", {
105617
+ canJoinWaitlist && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
105238
105618
  className: "er-text er-text--muted",
105239
105619
  children: "This event is currently full. Continue to join the waitlist if a place opens up."
105620
+ }), /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })] }),
105621
+ checkoutRecovery && /* @__PURE__ */ jsx("p", {
105622
+ className: "er-text er-text--muted",
105623
+ children: "Enter the details from your earlier booking. We’ll check your checkout before continuing to payment."
105240
105624
  })
105241
105625
  ]
105242
105626
  });
@@ -106038,50 +106422,6 @@ var init_SuccessStep = __esmMin((() => {
106038
106422
  };
106039
106423
  }));
106040
106424
  //#endregion
106041
- //#region ../blocks/src/system/runtime/nodes/event-registration/ErrorStep.tsx
106042
- var labels, ErrorStep;
106043
- var init_ErrorStep = __esmMin((() => {
106044
- init_shared();
106045
- labels = {
106046
- none: "",
106047
- retry: "Try again",
106048
- places: "Choose places",
106049
- start: "Start again",
106050
- details: "Check my details",
106051
- "payment-options": "View payment options",
106052
- "payment-status": "Check payment status",
106053
- portal: "View my bookings",
106054
- event: "View event"
106055
- };
106056
- ErrorStep = ({ message, onRetry, action = "retry", canJoinWaitlist = false }) => {
106057
- const offerWaitlist = action === "places" && canJoinWaitlist;
106058
- return /* @__PURE__ */ jsx(TerminalPanel, {
106059
- tone: "error",
106060
- className: "er-center",
106061
- titleClassName: "er-title--lg er-message",
106062
- icon: /* @__PURE__ */ jsx(StateIcon, {
106063
- variant: "error",
106064
- children: /* @__PURE__ */ jsx(CrossIcon, {})
106065
- }),
106066
- title: "We couldn’t complete your booking",
106067
- body: /* @__PURE__ */ jsx("p", {
106068
- className: "er-text--muted er-message",
106069
- children: offerWaitlist ? "Sorry, this event is now full. You can join the waiting list, and we’ll email you if a place becomes available." : message
106070
- }),
106071
- actions: action === "none" ? void 0 : action === "portal" || action === "payment-status" ? /* @__PURE__ */ jsx("a", {
106072
- href: "/portal",
106073
- className: "er-retry-btn",
106074
- children: labels[action]
106075
- }) : /* @__PURE__ */ jsx("button", {
106076
- type: "button",
106077
- onClick: onRetry,
106078
- className: "er-retry-btn",
106079
- children: offerWaitlist ? "Join the waiting list" : labels[action]
106080
- })
106081
- });
106082
- };
106083
- }));
106084
- //#endregion
106085
106425
  //#region ../blocks/src/system/runtime/nodes/event-registration/VerifyingPaymentStep.tsx
106086
106426
  var VerifyingPaymentStep;
106087
106427
  var init_VerifyingPaymentStep = __esmMin((() => {
@@ -106368,12 +106708,14 @@ function EventRegistrationWizardContent(props) {
106368
106708
  onBookForSomeoneElse: wizard.handleBookForSomeoneElse
106369
106709
  }), /* @__PURE__ */ jsx(TicketSelectionStep, {
106370
106710
  event: wizard.selectedEvent,
106711
+ checkoutRecovery: wizard.checkoutRecovery,
106712
+ onCheckoutRecovery: canRecoverEventCheckout(wizard.selectedEvent) ? wizard.startCheckoutRecovery : void 0,
106371
106713
  occurrenceContext: wizard.occurrenceContext,
106372
106714
  selectedAttendanceMode: wizard.selectedAttendanceMode,
106373
106715
  onAttendanceModeChange: wizard.setSelectedAttendanceMode,
106374
106716
  ticketsCount: wizard.ticketsCount,
106375
106717
  maxTickets: wizard.maxTicketsNum,
106376
- visibleTicketTypes: wizard.eligibility ? wizard.visibleTicketTypes : void 0,
106718
+ visibleTicketTypes: wizard.visibleTicketTypes,
106377
106719
  ticketSelections: wizard.selectedTicketLines,
106378
106720
  onTicketSelectionsChange: wizard.setSelectedTicketLines,
106379
106721
  slidingScale: wizard.selectedEventSlidingScale,
@@ -106395,6 +106737,7 @@ var init_EventRegistrationWizardContent = __esmMin((() => {
106395
106737
  init_client();
106396
106738
  init_src();
106397
106739
  init_shared();
106740
+ init_checkoutRecovery();
106398
106741
  init_registrationStateMachine();
106399
106742
  init_siteCreditPreview();
106400
106743
  init_PaymentBlockingPanel();
@@ -106542,19 +106885,20 @@ function EventRegistrationSurface(props) {
106542
106885
  }), /* @__PURE__ */ jsx(EventRegistrationTerminalState, {
106543
106886
  wizard,
106544
106887
  supportEmail: props.supportEmail,
106545
- successMessage: props.successMessage
106888
+ successMessage: props.successMessage,
106889
+ buttonClass: props.buttonClass
106546
106890
  })]
106547
106891
  });
106548
106892
  }
106549
106893
  var init_EventRegistrationSurface = __esmMin((() => {
106550
- init_spinner();
106551
106894
  init_MagicLinkForm();
106895
+ init_spinner();
106896
+ init_ErrorStep();
106552
106897
  init_EventRegistrationSummaryBar();
106553
106898
  init_EventRegistrationWizardActions();
106554
106899
  init_EventRegistrationWizardContent();
106555
- init_StepIndicator();
106556
- init_ErrorStep();
106557
106900
  init_PaymentFailedStep();
106901
+ init_StepIndicator();
106558
106902
  init_SuccessStep();
106559
106903
  init_VerifyingPaymentStep();
106560
106904
  init_VerifyingTimeoutStep();
@@ -106982,6 +107326,88 @@ var init_RegistrationClosedState = __esmMin((() => {
106982
107326
  init_constants();
106983
107327
  }));
106984
107328
  //#endregion
107329
+ //#region ../blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.ts
107330
+ function useEventSourceRecovery(source, deps = defaultRecoveryDeps) {
107331
+ const api = deps.useApi();
107332
+ const wait = deps.wait;
107333
+ const [cycle, setCycle] = useState(0);
107334
+ const [state, setState] = useState(() => source.kind === "loaded" ? {
107335
+ kind: "ready",
107336
+ events: source.events
107337
+ } : { kind: "loading" });
107338
+ const retry = useCallback(() => {
107339
+ setState({ kind: "loading" });
107340
+ setCycle((value) => value + 1);
107341
+ }, []);
107342
+ useEffect(() => {
107343
+ if (source.kind === "loaded") {
107344
+ setState({
107345
+ kind: "ready",
107346
+ events: source.events
107347
+ });
107348
+ return;
107349
+ }
107350
+ if (!source.request) {
107351
+ setState({
107352
+ kind: "exhausted",
107353
+ retry
107354
+ });
107355
+ return;
107356
+ }
107357
+ const controller = new AbortController();
107358
+ const isCurrent = () => !controller.signal.aborted;
107359
+ (async () => {
107360
+ for (const delayMs of RECOVERY_DELAYS_MS) try {
107361
+ await wait(delayMs, controller.signal);
107362
+ const events = await api.getPublicEvents(source.request ?? void 0);
107363
+ if (isCurrent()) setState({
107364
+ kind: "ready",
107365
+ events
107366
+ });
107367
+ return;
107368
+ } catch {
107369
+ if (!isCurrent()) return;
107370
+ }
107371
+ if (isCurrent()) setState({
107372
+ kind: "exhausted",
107373
+ retry
107374
+ });
107375
+ })();
107376
+ return () => controller.abort();
107377
+ }, [
107378
+ api,
107379
+ cycle,
107380
+ retry,
107381
+ source,
107382
+ wait
107383
+ ]);
107384
+ return state;
107385
+ }
107386
+ function waitForRetry(milliseconds, signal) {
107387
+ if (signal.aborted) return Promise.reject(/* @__PURE__ */ new Error("Recovery aborted"));
107388
+ if (milliseconds === 0) return Promise.resolve();
107389
+ return new Promise((resolve, reject) => {
107390
+ const timeout = setTimeout(resolve, milliseconds);
107391
+ signal.addEventListener("abort", () => {
107392
+ clearTimeout(timeout);
107393
+ reject(/* @__PURE__ */ new Error("Recovery aborted"));
107394
+ }, { once: true });
107395
+ });
107396
+ }
107397
+ var RECOVERY_DELAYS_MS, defaultRecoveryDeps;
107398
+ var init_useEventSourceRecovery = __esmMin((() => {
107399
+ init_api();
107400
+ RECOVERY_DELAYS_MS = [
107401
+ 0,
107402
+ 250,
107403
+ 750
107404
+ ];
107405
+ defaultRecoveryDeps = {
107406
+ useApi: useBlockApi,
107407
+ wait: waitForRetry
107408
+ };
107409
+ }));
107410
+ //#endregion
106985
107411
  //#region ../blocks/src/system/runtime/nodes/event-registration.client.tsx
106986
107412
  function toEventRegistrationClientProps(props, display) {
106987
107413
  return {
@@ -106990,13 +107416,77 @@ function toEventRegistrationClientProps(props, display) {
106990
107416
  className: display.className ?? void 0
106991
107417
  };
106992
107418
  }
107419
+ function RecoverableEventRegistrationClient({ props, display }) {
107420
+ const recovery = useEventSourceRecovery(props.render.hydration.eventSource);
107421
+ if (recovery.kind === "loading") return /* @__PURE__ */ jsxs("div", {
107422
+ id: EVENT_REGISTRATION_ANCHOR_ID,
107423
+ className: "rb-reg-surface er-container er-registration-shell",
107424
+ "aria-busy": "true",
107425
+ role: "status",
107426
+ children: [
107427
+ /* @__PURE__ */ jsx("p", {
107428
+ className: "er-registration-shell__eyebrow",
107429
+ children: "Registration"
107430
+ }),
107431
+ /* @__PURE__ */ jsx("h3", {
107432
+ className: "er-title er-registration-shell__title",
107433
+ children: display.titleText
107434
+ }),
107435
+ /* @__PURE__ */ jsx("p", {
107436
+ className: "er-text er-text--muted",
107437
+ children: "Loading event dates…"
107438
+ }),
107439
+ /* @__PURE__ */ jsxs("div", {
107440
+ className: "er-event-grid er-registration-shell__cards",
107441
+ "aria-hidden": "true",
107442
+ children: [/* @__PURE__ */ jsx("div", { className: "er-event-card er-registration-shell__card" }), /* @__PURE__ */ jsx("div", { className: "er-event-card er-registration-shell__card" })]
107443
+ })
107444
+ ]
107445
+ });
107446
+ if (recovery.kind === "exhausted") return /* @__PURE__ */ jsxs("div", {
107447
+ id: EVENT_REGISTRATION_ANCHOR_ID,
107448
+ className: "rb-reg-surface er-container er-registration-shell",
107449
+ role: "alert",
107450
+ children: [/* @__PURE__ */ jsx("p", { children: "We couldn’t load the event dates. Please try again." }), /* @__PURE__ */ jsx("button", {
107451
+ type: "button",
107452
+ className: themeButtonClassName({
107453
+ variant: props.render.hydration.buttonVariant ?? "primary",
107454
+ size: "md"
107455
+ }),
107456
+ onClick: recovery.retry,
107457
+ children: "Try again"
107458
+ })]
107459
+ });
107460
+ const events = resolveEventRegistrationScopedEvents(recovery.events, {
107461
+ occurrenceContext: props.render.hydration.occurrenceContext,
107462
+ subject: props.render.hydration.subject
107463
+ });
107464
+ const recoveredDisplay = buildEventRegistrationDisplayFromScopedEvents({
107465
+ ...props.render.hydration,
107466
+ events,
107467
+ className: display.className,
107468
+ buttonText: display.summaryButtonText
107469
+ }, events);
107470
+ if (recoveredDisplay.state === "registration-closed") return /* @__PURE__ */ jsx(RegistrationClosedState, {
107471
+ title: recoveredDisplay.titleText,
107472
+ body: recoveredDisplay.bodyText
107473
+ });
107474
+ return /* @__PURE__ */ jsx(EventRegistrationClient, {
107475
+ ...toEventRegistrationClientProps(props, display),
107476
+ events
107477
+ });
107478
+ }
106993
107479
  var EventRegistrationClient, EventRegistrationIslandClient;
106994
107480
  var init_event_registration_client = __esmMin((() => {
106995
107481
  init_EventRegistrationWizard();
106996
107482
  init_registrationSurface();
106997
107483
  init_constants();
106998
107484
  init_PastOccurrenceNotice();
107485
+ init_event_registration_interactive();
106999
107486
  init_RegistrationClosedState();
107487
+ init_useEventSourceRecovery();
107488
+ init_eventScope();
107489
+ init_buttons();
107000
107490
  EventRegistrationClient = (clientProps) => {
107001
107491
  const surface = planEventRegistrationSurface({
107002
107492
  events: clientProps.events ?? [],
@@ -107022,7 +107512,10 @@ var init_event_registration_client = __esmMin((() => {
107022
107512
  title: props.render.display.titleText,
107023
107513
  body: props.render.display.bodyText
107024
107514
  });
107025
- return /* @__PURE__ */ jsx(EventRegistrationClient, { ...toEventRegistrationClientProps(props, props.render.display) });
107515
+ return /* @__PURE__ */ jsx(RecoverableEventRegistrationClient, {
107516
+ props,
107517
+ display: props.render.display
107518
+ });
107026
107519
  };
107027
107520
  }));
107028
107521
  //#endregion
@@ -113147,6 +113640,11 @@ function NewsletterFormClient({ render }) {
113147
113640
  const api = useBlockApi();
113148
113641
  const [submissionState, dispatchSubmission] = useReducer(newsletterFormSubmissionReducer, initialNewsletterFormSubmissionState);
113149
113642
  const [altchaSolution, setAltchaSolution] = useState(null);
113643
+ const successRef = useRef(null);
113644
+ const succeeded = isNewsletterFormSuccess(submissionState);
113645
+ useEffect(() => {
113646
+ if (succeeded) successRef.current?.focus();
113647
+ }, [succeeded]);
113150
113648
  const showSpamProtection = render.hydration.spamProtectionEnabled ?? isSpamProtectionEnabled();
113151
113649
  const fields = render.display.fields;
113152
113650
  const handleSubmit = async (e) => {
@@ -113186,7 +113684,7 @@ function NewsletterFormClient({ render }) {
113186
113684
  if (render.hydration.setupRevision === null || render.display.availability === "unavailable") {
113187
113685
  dispatchSubmission({
113188
113686
  type: "failed",
113189
- error: newsletterFormError("Mailing-list signup is not available right now.")
113687
+ error: newsletterFormError(SIGNUPS_PAUSED_MESSAGE)
113190
113688
  });
113191
113689
  return;
113192
113690
  }
@@ -113194,7 +113692,7 @@ function NewsletterFormClient({ render }) {
113194
113692
  if (visitorSelection === null) {
113195
113693
  dispatchSubmission({
113196
113694
  type: "failed",
113197
- error: newsletterFormError("Choose at least one email topic.")
113695
+ error: newsletterFieldError(TOPIC_CHOICE_FIELD_ID, "Choose at least one email topic.")
113198
113696
  });
113199
113697
  return;
113200
113698
  }
@@ -113226,71 +113724,27 @@ function NewsletterFormClient({ render }) {
113226
113724
  } catch (err) {
113227
113725
  dispatchSubmission({
113228
113726
  type: "failed",
113229
- error: newsletterFormError(err instanceof Error ? err.message : "Subscription failed. Please try again.")
113727
+ error: newsletterFormError(transportFailureMessage(err))
113230
113728
  });
113231
113729
  }
113232
113730
  };
113233
- const renderField = (field) => {
113234
- const inputId = `newsletter_${field.id}`;
113235
- const fieldError = getNewsletterSubmissionFieldError(submissionState, field.id);
113236
- const fieldErrorId = `${inputId}-error`;
113237
- const validationProps = getFieldValidationControlProps({
113238
- message: fieldError,
113239
- messageId: fieldErrorId
113240
- });
113241
- return /* @__PURE__ */ jsxs("div", {
113242
- className: "fb-field newsletter-field",
113243
- children: [
113244
- /* @__PURE__ */ jsxs("label", {
113245
- htmlFor: inputId,
113246
- className: "form-label",
113247
- children: [field.label, field.required && /* @__PURE__ */ jsx("span", {
113248
- className: "newsletter-required",
113249
- "aria-hidden": "true",
113250
- children: "*"
113251
- })]
113252
- }),
113253
- /* @__PURE__ */ jsx("input", {
113254
- id: inputId,
113255
- name: field.id,
113256
- type: field.type,
113257
- required: field.required,
113258
- placeholder: field.placeholder,
113259
- className: "form-input",
113260
- autoComplete: field.type === "email" ? "email" : void 0,
113261
- disabled: isNewsletterFormSubmitting(submissionState),
113262
- ...validationProps
113263
- }),
113264
- fieldError && /* @__PURE__ */ jsx(FieldValidationMessage, {
113265
- id: fieldErrorId,
113266
- className: "fb-error",
113267
- children: fieldError
113268
- })
113269
- ]
113270
- }, field.id);
113271
- };
113731
+ const submitting = isNewsletterFormSubmitting(submissionState);
113272
113732
  const formError = getNewsletterSubmissionFormError(submissionState);
113273
- if (isNewsletterFormSuccess(submissionState)) {
113274
- const outcome = getNewsletterSuccessOutcome(submissionState);
113275
- return /* @__PURE__ */ jsx("div", {
113276
- className: clsx("newsletter-form", "newsletter-success", render.display.className ?? void 0),
113277
- children: /* @__PURE__ */ jsx(FeedbackMessage, {
113278
- tone: "success",
113279
- className: "fb-success",
113280
- role: "status",
113281
- children: outcome === "confirmation_required" ? "Please check your inbox to confirm your signup." : "Thanks — you’re on the list."
113282
- })
113283
- });
113284
- }
113733
+ if (succeeded) return /* @__PURE__ */ jsx("div", {
113734
+ ref: successRef,
113735
+ tabIndex: -1,
113736
+ className: clsx("newsletter-form", "newsletter-success", render.display.className ?? void 0),
113737
+ children: /* @__PURE__ */ jsx(FeedbackMessage, {
113738
+ tone: "success",
113739
+ className: "fb-success",
113740
+ role: "status",
113741
+ children: getNewsletterSuccessOutcome(submissionState) === "confirmation_required" ? "Please check your inbox to confirm your signup." : render.display.successMessage
113742
+ })
113743
+ });
113285
113744
  if (render.display.availability === "unavailable") return /* @__PURE__ */ jsx(UnavailableNewsletterForm, { className: render.display.className });
113286
- return /* @__PURE__ */ jsxs("div", {
113745
+ return /* @__PURE__ */ jsx("div", {
113287
113746
  className: clsx("newsletter-form", render.display.className ?? void 0),
113288
- children: [formError && /* @__PURE__ */ jsx(FeedbackMessage, {
113289
- tone: "error",
113290
- className: "fb-error",
113291
- role: "alert",
113292
- children: formError
113293
- }), /* @__PURE__ */ jsxs("form", {
113747
+ children: /* @__PURE__ */ jsxs("form", {
113294
113748
  onSubmit: handleSubmit,
113295
113749
  className: "fb-form",
113296
113750
  children: [
@@ -113305,18 +113759,15 @@ function NewsletterFormClient({ render }) {
113305
113759
  /* @__PURE__ */ jsxs("div", {
113306
113760
  className: "newsletter-form-fields",
113307
113761
  children: [
113308
- fields.map(renderField),
113309
- render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsxs("fieldset", {
113310
- className: "newsletter-topics",
113311
- children: [/* @__PURE__ */ jsx("legend", { children: "What would you like to hear about?" }), render.display.choices.map((choice) => /* @__PURE__ */ jsxs("label", {
113312
- className: "newsletter-topic-choice",
113313
- children: [/* @__PURE__ */ jsx("input", {
113314
- type: "checkbox",
113315
- name: "mailingListChoice",
113316
- value: choice.id,
113317
- disabled: isNewsletterFormSubmitting(submissionState)
113318
- }), choice.label]
113319
- }, choice.id))]
113762
+ fields.map((field) => /* @__PURE__ */ jsx(NewsletterField, {
113763
+ field,
113764
+ submitting,
113765
+ error: getNewsletterSubmissionFieldError(submissionState, field.id)
113766
+ }, field.id)),
113767
+ render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsx(NewsletterTopicChoices, {
113768
+ choices: render.display.choices,
113769
+ submitting,
113770
+ error: getNewsletterSubmissionFieldError(submissionState, TOPIC_CHOICE_FIELD_ID)
113320
113771
  }) : null,
113321
113772
  showSpamProtection && /* @__PURE__ */ jsx("div", {
113322
113773
  className: "newsletter-altcha",
@@ -113325,6 +113776,12 @@ function NewsletterFormClient({ render }) {
113325
113776
  onSolutionChange: setAltchaSolution
113326
113777
  })
113327
113778
  }),
113779
+ formError && /* @__PURE__ */ jsx(FeedbackMessage, {
113780
+ tone: "error",
113781
+ className: "fb-error",
113782
+ role: "alert",
113783
+ children: formError
113784
+ }),
113328
113785
  /* @__PURE__ */ jsx("div", {
113329
113786
  className: "newsletter-submit",
113330
113787
  children: /* @__PURE__ */ jsx("button", {
@@ -113333,8 +113790,8 @@ function NewsletterFormClient({ render }) {
113333
113790
  variant: render.display.buttonVariant,
113334
113791
  size: "md"
113335
113792
  }),
113336
- disabled: isNewsletterFormSubmitting(submissionState),
113337
- children: isNewsletterFormSubmitting(submissionState) ? "Subscribing..." : render.display.buttonLabel
113793
+ disabled: submitting,
113794
+ children: submitting ? "Subscribing..." : render.display.buttonLabel
113338
113795
  })
113339
113796
  })
113340
113797
  ]
@@ -113344,9 +113801,70 @@ function NewsletterFormClient({ render }) {
113344
113801
  children: render.display.privacyNote
113345
113802
  })
113346
113803
  ]
113347
- })]
113804
+ })
113348
113805
  });
113349
113806
  }
113807
+ function NewsletterField({ field, submitting, error }) {
113808
+ const inputId = `newsletter_${field.id}`;
113809
+ const errorId = `${inputId}-error`;
113810
+ return /* @__PURE__ */ jsxs("div", {
113811
+ className: "fb-field newsletter-field",
113812
+ children: [
113813
+ /* @__PURE__ */ jsxs("label", {
113814
+ htmlFor: inputId,
113815
+ className: "form-label",
113816
+ children: [field.label, field.required && /* @__PURE__ */ jsx("span", {
113817
+ className: "newsletter-required",
113818
+ "aria-hidden": "true",
113819
+ children: "*"
113820
+ })]
113821
+ }),
113822
+ /* @__PURE__ */ jsx("input", {
113823
+ id: inputId,
113824
+ name: field.id,
113825
+ type: field.type,
113826
+ required: field.required,
113827
+ placeholder: field.placeholder,
113828
+ className: "form-input",
113829
+ autoComplete: field.type === "email" ? "email" : void 0,
113830
+ disabled: submitting,
113831
+ ...getFieldValidationControlProps({
113832
+ message: error,
113833
+ messageId: errorId
113834
+ })
113835
+ }),
113836
+ error && /* @__PURE__ */ jsx(FieldValidationMessage, {
113837
+ id: errorId,
113838
+ className: "fb-error",
113839
+ children: error
113840
+ })
113841
+ ]
113842
+ });
113843
+ }
113844
+ function NewsletterTopicChoices({ choices, submitting, error }) {
113845
+ const errorId = `newsletter_${TOPIC_CHOICE_FIELD_ID}-error`;
113846
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("fieldset", {
113847
+ className: "fb-fieldset newsletter-topics",
113848
+ "aria-describedby": error ? errorId : void 0,
113849
+ children: [/* @__PURE__ */ jsx("legend", {
113850
+ className: "form-label",
113851
+ children: "What would you like to hear about?"
113852
+ }), choices.map((choice) => /* @__PURE__ */ jsxs("label", {
113853
+ className: "fb-inline form-label newsletter-topic-choice",
113854
+ children: [/* @__PURE__ */ jsx("input", {
113855
+ type: "checkbox",
113856
+ name: TOPIC_CHOICE_FIELD_ID,
113857
+ value: choice.id,
113858
+ className: "form-checkbox",
113859
+ disabled: submitting
113860
+ }), /* @__PURE__ */ jsx("span", { children: choice.label })]
113861
+ }, choice.id))]
113862
+ }), error && /* @__PURE__ */ jsx(FieldValidationMessage, {
113863
+ id: errorId,
113864
+ className: "fb-error",
113865
+ children: error
113866
+ })] });
113867
+ }
113350
113868
  function UnavailableNewsletterForm({ className }) {
113351
113869
  return /* @__PURE__ */ jsx("div", {
113352
113870
  className: clsx("newsletter-form", className ?? void 0),
@@ -113354,13 +113872,26 @@ function UnavailableNewsletterForm({ className }) {
113354
113872
  tone: "error",
113355
113873
  className: "fb-error",
113356
113874
  role: "status",
113357
- children: "Mailing-list signup is not available right now."
113875
+ children: SIGNUPS_PAUSED_MESSAGE
113358
113876
  })
113359
113877
  });
113360
113878
  }
113879
+ /**
113880
+ * Vetted copy for a request that never produced a signup response. The raw
113881
+ * error text ("Failed to fetch", "received invalid JSON") is for logs, not
113882
+ * visitors.
113883
+ */
113884
+ function transportFailureMessage(err) {
113885
+ if (err instanceof BlockApiError) {
113886
+ if (err.status === 429) return TOO_MANY_ATTEMPTS_MESSAGE;
113887
+ if (err.status === 403) return "We couldn’t verify this submission. Please try again.";
113888
+ if (err.status === 400 || err.status === 422) return "Please check your details and try again.";
113889
+ }
113890
+ return RETRY_SHORTLY_MESSAGE;
113891
+ }
113361
113892
  function readVisitorSelection(formData, hydration) {
113362
113893
  if (hydration.choicePresentation !== "visitor_choice") return void 0;
113363
- const ids = formData.getAll("mailingListChoice").flatMap((value) => typeof value === "string" ? [value] : []);
113894
+ const ids = formData.getAll(TOPIC_CHOICE_FIELD_ID).flatMap((value) => typeof value === "string" ? [value] : []);
113364
113895
  if (ids.length === 0) return null;
113365
113896
  const raw = hydration.choiceProvider === "native" ? {
113366
113897
  provider: "native",
@@ -113382,15 +113913,15 @@ function publicSignupError(outcome) {
113382
113913
  case "unavailable": switch (outcome.reason) {
113383
113914
  case "configuration_unavailable":
113384
113915
  case "authentication_failed":
113385
- case "target_unavailable": return "Mailing-list signup is not available right now.";
113916
+ case "target_unavailable": return SIGNUPS_PAUSED_MESSAGE;
113386
113917
  case "stale_configuration": return "This signup form has changed. Refresh the page, then try again.";
113387
- case "subscriber_suppressed": return "This address cannot be added. Please contact the site if you would like help.";
113388
- case "rate_limited": return "There have been too many signup attempts. Please wait a moment and try again.";
113389
- case "temporarily_unavailable": return "We could not sign you up just now. Please try again shortly.";
113918
+ case "rate_limited": return TOO_MANY_ATTEMPTS_MESSAGE;
113919
+ case "temporarily_unavailable": return RETRY_SHORTLY_MESSAGE;
113390
113920
  }
113391
113921
  case "uncertain": return "We could not confirm whether your signup completed. Please wait a moment, then try again.";
113392
113922
  }
113393
113923
  }
113924
+ var TOPIC_CHOICE_FIELD_ID, SIGNUPS_PAUSED_MESSAGE, RETRY_SHORTLY_MESSAGE, TOO_MANY_ATTEMPTS_MESSAGE;
113394
113925
  var init_newsletter_form_client = __esmMin((() => {
113395
113926
  init_clsx();
113396
113927
  init_client();
@@ -113402,6 +113933,10 @@ var init_newsletter_form_client = __esmMin((() => {
113402
113933
  init_FieldValidationMessage();
113403
113934
  init_newsletter_form_client_state();
113404
113935
  init_newsletter_form_submission();
113936
+ TOPIC_CHOICE_FIELD_ID = "mailingListChoice";
113937
+ SIGNUPS_PAUSED_MESSAGE = "We can’t accept signups right now. Please try again later.";
113938
+ RETRY_SHORTLY_MESSAGE = "We couldn’t confirm your signup. Please try again in a little while.";
113939
+ TOO_MANY_ATTEMPTS_MESSAGE = "There have been too many signup attempts. Please wait a moment and try again.";
113405
113940
  }));
113406
113941
  //#endregion
113407
113942
  //#region ../blocks/src/client/newsletter-form.ts
@@ -117886,7 +118421,7 @@ const publicPricingSchema = z$1.object({
117886
118421
  singlePriceAmount: z$1.number().nullable(),
117887
118422
  slidingMinAmount: z$1.number().nullable(),
117888
118423
  slidingMaxAmount: z$1.number().nullable(),
117889
- options: z$1.array(publicPricingOptionSchema)
118424
+ options: z$1.array(publicPricingOptionSchema).readonly()
117890
118425
  });
117891
118426
  const publicAppointmentServiceSchema = z$1.object({
117892
118427
  id: z$1.string().min(1),
@@ -120035,6 +120570,7 @@ const eventRegistrationBlockDefinition = {
120035
120570
  } },
120036
120571
  events: { $bind: { from: "data.events" } },
120037
120572
  wholeSeriesRunEvents: { $bind: { from: "data.wholeSeriesRunEvents" } },
120573
+ loaderFailures: { $bind: { from: "$root.loaderFailures" } },
120038
120574
  sitePasses: { $bind: { from: "data.sitePasses" } },
120039
120575
  siteMemberships: { $bind: { from: "data.siteMemberships" } },
120040
120576
  stage: { $bind: {
@@ -122963,9 +123499,10 @@ function cx(...classes) {
122963
123499
  * Server-safe placeholder for event registration.
122964
123500
  * Provides a static container for island hydration without importing client hooks.
122965
123501
  */
122966
- function EventRegistrationSSR({ blockId, subject, children, ...sourceProps }) {
123502
+ function EventRegistrationSSR({ blockId, subject, loaderFailures, children, ...sourceProps }) {
122967
123503
  const islandProps = buildEventRegistrationInteractiveIslandProps({
122968
123504
  ...sourceProps,
123505
+ eventLoaderFailures: blockId ? loaderFailures?.[blockId] : void 0,
122969
123506
  subject: normalizeEventRegistrationPageSurfaceSubject(subject)
122970
123507
  });
122971
123508
  const display = islandProps.render.display;
@@ -123268,7 +123805,7 @@ function NewsletterFormSSR(props) {
123268
123805
  className: clsx("newsletter-form-ssr", className),
123269
123806
  children: /* @__PURE__ */ jsx("p", {
123270
123807
  role: "status",
123271
- children: "Mailing-list signup is not available right now."
123808
+ children: "We can’t accept signups right now. Please try again later."
123272
123809
  })
123273
123810
  });
123274
123811
  const renderField = (field) => {
@@ -123314,14 +123851,18 @@ function NewsletterFormSSR(props) {
123314
123851
  children: [
123315
123852
  fields.map(renderField),
123316
123853
  islandProps.render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsxs("fieldset", {
123317
- className: "newsletter-topics",
123318
- children: [/* @__PURE__ */ jsx("legend", { children: "What would you like to hear about?" }), display.choices.map((choice) => /* @__PURE__ */ jsxs("label", {
123319
- className: "newsletter-topic-choice",
123854
+ className: "fb-fieldset newsletter-topics",
123855
+ children: [/* @__PURE__ */ jsx("legend", {
123856
+ className: "form-label",
123857
+ children: "What would you like to hear about?"
123858
+ }), display.choices.map((choice) => /* @__PURE__ */ jsxs("label", {
123859
+ className: "fb-inline form-label newsletter-topic-choice",
123320
123860
  children: [/* @__PURE__ */ jsx("input", {
123321
123861
  type: "checkbox",
123322
123862
  name: "mailingListChoice",
123323
- value: choice.id
123324
- }), choice.label]
123863
+ value: choice.id,
123864
+ className: "form-checkbox"
123865
+ }), /* @__PURE__ */ jsx("span", { children: choice.label })]
123325
123866
  }, choice.id))]
123326
123867
  }) : null,
123327
123868
  /* @__PURE__ */ jsx("div", {
@@ -124322,6 +124863,18 @@ function resolveChildren(nodes, context) {
124322
124863
  function isReactNode(value) {
124323
124864
  return value !== null && value !== void 0;
124324
124865
  }
124866
+ function resolveNodeMetadata(nodeType, context) {
124867
+ return {
124868
+ pathBase: context.pathBase,
124869
+ blockId: context.blockId,
124870
+ blockKind: context.blockKind,
124871
+ blockContent: context.blockContent,
124872
+ fragmentRegistry: context.fragmentRegistry,
124873
+ previewAuthoring: context.previewAuthoring,
124874
+ ...nodeType.toLowerCase() === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
124875
+ ...nodeType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
124876
+ };
124877
+ }
124325
124878
  /**
124326
124879
  * Resolves a node definition into a React element.
124327
124880
  * Handles conditionals ($when), scopes ($scopes), repeaters ($repeat), bindings ($bind), and children.
@@ -124357,13 +124910,7 @@ function resolveNode(node, context, indexFallback) {
124357
124910
  const elementProps = {
124358
124911
  ...props,
124359
124912
  key: node.key ?? indexFallback,
124360
- pathBase: context.pathBase,
124361
- blockId: context.blockId,
124362
- blockKind: context.blockKind,
124363
- blockContent: context.blockContent,
124364
- ...node.type === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {},
124365
- fragmentRegistry: context.fragmentRegistry,
124366
- previewAuthoring: context.previewAuthoring
124913
+ ...resolveNodeMetadata(node.type, context)
124367
124914
  };
124368
124915
  const element = React.createElement(component, elementProps, ...children);
124369
124916
  if (headingDecorationPlan.kind === "skip") return element;
@@ -128409,7 +128956,7 @@ function pageBlockPosition(index, blockCount) {
128409
128956
  //#endregion
128410
128957
  //#region ../blocks/src/pageRendererContracts.ts
128411
128958
  function buildPageRendererRootRuntime(dataContext) {
128412
- const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, bookingOfferingPresets = [], mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false } = dataContext ?? {};
128959
+ const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, bookingOfferingPresets = [], mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
128413
128960
  return {
128414
128961
  siteId,
128415
128962
  pageId,
@@ -128420,7 +128967,8 @@ function buildPageRendererRootRuntime(dataContext) {
128420
128967
  portalToken,
128421
128968
  bookingOfferingPresets,
128422
128969
  mailingList,
128423
- eventRegistrationOverlayEnabled
128970
+ eventRegistrationOverlayEnabled,
128971
+ loaderFailures
128424
128972
  };
128425
128973
  }
128426
128974
  //#endregion
@@ -137672,7 +138220,7 @@ function collectNestedPreviewFieldConstraintEntries(field, path) {
137672
138220
  }
137673
138221
  function makeDefaultBlockComponent(args) {
137674
138222
  const { manifest } = args;
137675
- return function DefaultBlockComponent({ content, data, registry, theme, themeConfig, transforms, viewModelOverrides, pathBase, blockId, blockKind, blockBindings, editableRouteMetadataFieldIds, fragmentRegistry, imageResolveContext, previewAuthoring }) {
138223
+ return function DefaultBlockComponent({ content, data, registry, theme, themeConfig, transforms, viewModelOverrides, pathBase, blockId, contentVersionId, blockKind, blockBindings, editableRouteMetadataFieldIds, fragmentRegistry, imageResolveContext, previewAuthoring }) {
137676
138224
  const perf = beginBlockRenderMeasurement();
137677
138225
  if (!theme) throw new Error("Block rendering requires theme tokens; none were provided to makeDefaultBlockComponent");
137678
138226
  if (!registry) throw new Error("Block rendering requires a component registry; none was provided");
@@ -137692,6 +138240,7 @@ function makeDefaultBlockComponent(args) {
137692
138240
  theme: withButtonSystem(theme, themeConfig),
137693
138241
  pathBase,
137694
138242
  blockId,
138243
+ contentVersionId,
137695
138244
  blockKind,
137696
138245
  blockContent: mergedContent,
137697
138246
  blockBindings,
@@ -138502,6 +139051,7 @@ function buildBlockOverrideProps(input) {
138502
139051
  ...blockSubjectProps(dataContext),
138503
139052
  imageResolveContext: input.imageResolveContext,
138504
139053
  blockId: block.id ?? null,
139054
+ contentVersionId: block.contentVersionId ?? null,
138505
139055
  blockKind: block.kind
138506
139056
  };
138507
139057
  }
@@ -138602,6 +139152,7 @@ function toPresentationPage(page) {
138602
139152
  id: block.id,
138603
139153
  kind: block.kind,
138604
139154
  purpose: block.purpose,
139155
+ ...block.contentVersionId ? { contentVersionId: block.contentVersionId } : {},
138605
139156
  ...block.bindings ? { bindings: block.bindings } : {}
138606
139157
  };
138607
139158
  return block.admission.kind === "renderable" ? {
@@ -148857,7 +149408,9 @@ const containerResponsiveThemeCss = `/*
148857
149408
  text-align: left;
148858
149409
  }
148859
149410
 
148860
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-login__subtitle {
149411
+ :where(.theme-scope)
149412
+ :where([data-block="customer-portal"])
149413
+ .cp-login__subtitle {
148861
149414
  color: var(--cp-muted);
148862
149415
  font-size: 0.9375rem;
148863
149416
  text-align: left;
@@ -148884,7 +149437,9 @@ const containerResponsiveThemeCss = `/*
148884
149437
  text-align: left;
148885
149438
  }
148886
149439
 
148887
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-login__reset-link {
149440
+ :where(.theme-scope)
149441
+ :where([data-block="customer-portal"])
149442
+ .cp-login__reset-link {
148888
149443
  appearance: none;
148889
149444
  background: none;
148890
149445
  border: 0;
@@ -148898,11 +149453,15 @@ const containerResponsiveThemeCss = `/*
148898
149453
  text-underline-offset: 0.15em;
148899
149454
  }
148900
149455
 
148901
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-login__reset-link:hover {
149456
+ :where(.theme-scope)
149457
+ :where([data-block="customer-portal"])
149458
+ .cp-login__reset-link:hover {
148902
149459
  color: var(--cp-text);
148903
149460
  }
148904
149461
 
148905
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-login__reset-link:focus-visible {
149462
+ :where(.theme-scope)
149463
+ :where([data-block="customer-portal"])
149464
+ .cp-login__reset-link:focus-visible {
148906
149465
  outline: 2px solid currentColor;
148907
149466
  outline-offset: 3px;
148908
149467
  }
@@ -148947,7 +149506,9 @@ const containerResponsiveThemeCss = `/*
148947
149506
  border-bottom: none;
148948
149507
  }
148949
149508
 
148950
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-header__welcome {
149509
+ :where(.theme-scope)
149510
+ :where([data-block="customer-portal"])
149511
+ .cp-header__welcome {
148951
149512
  font-size: 1.125rem;
148952
149513
  font-weight: 500;
148953
149514
  }
@@ -148963,8 +149524,14 @@ const containerResponsiveThemeCss = `/*
148963
149524
  }
148964
149525
 
148965
149526
  @keyframes cp-fade-in {
148966
- from { opacity: 0; transform: translateY(4px); }
148967
- to { opacity: 1; transform: translateY(0); }
149527
+ from {
149528
+ opacity: 0;
149529
+ transform: translateY(4px);
149530
+ }
149531
+ to {
149532
+ opacity: 1;
149533
+ transform: translateY(0);
149534
+ }
148968
149535
  }
148969
149536
 
148970
149537
  /* Empty state */
@@ -149053,6 +149620,77 @@ const containerResponsiveThemeCss = `/*
149053
149620
  margin-top: 1rem;
149054
149621
  }
149055
149622
 
149623
+ /* Event waitlists */
149624
+ :where(.theme-scope) :where([data-block="customer-portal"]) .cp-waitlist-list {
149625
+ display: grid;
149626
+ gap: 1rem;
149627
+ }
149628
+
149629
+ :where(.theme-scope)
149630
+ :where([data-block="customer-portal"])
149631
+ .cp-waitlists
149632
+ > .cp-alert {
149633
+ margin-bottom: 1rem;
149634
+ }
149635
+
149636
+ :where(.theme-scope) :where([data-block="customer-portal"]) .cp-waitlist-card {
149637
+ transition:
149638
+ border-color 180ms ease,
149639
+ box-shadow 180ms ease;
149640
+ }
149641
+
149642
+ :where(.theme-scope)
149643
+ :where([data-block="customer-portal"])
149644
+ .cp-waitlist-card--focused {
149645
+ border-color: var(--cp-primary);
149646
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--cp-primary) 22%, transparent);
149647
+ }
149648
+
149649
+ :where(.theme-scope)
149650
+ :where([data-block="customer-portal"])
149651
+ .cp-waitlist-card__summary,
149652
+ :where(.theme-scope)
149653
+ :where([data-block="customer-portal"])
149654
+ .cp-waitlist-card__position {
149655
+ font-weight: 600;
149656
+ }
149657
+
149658
+ :where(.theme-scope)
149659
+ :where([data-block="customer-portal"])
149660
+ .cp-waitlist-card
149661
+ .cp-card-body
149662
+ p {
149663
+ margin: 0.4rem 0;
149664
+ }
149665
+
149666
+ @container rb-site (max-width: 640px) {
149667
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
149668
+ :where(.theme-scope)
149669
+ :where([data-block="customer-portal"])
149670
+ .cp-waitlist-card
149671
+ .cp-card-header {
149672
+ flex-direction: column-reverse;
149673
+ }
149674
+
149675
+ :where(.theme-scope)
149676
+ :where([data-block="customer-portal"])
149677
+ .cp-waitlist-card
149678
+ .cp-card-actions {
149679
+ align-items: stretch;
149680
+ flex-direction: column;
149681
+ }
149682
+
149683
+ :where(.theme-scope)
149684
+ :where([data-block="customer-portal"])
149685
+ .cp-waitlist-card
149686
+ .cp-card-actions
149687
+ > * {
149688
+ justify-content: center;
149689
+ text-align: center;
149690
+ }
149691
+ }
149692
+ }
149693
+
149056
149694
  /* Badge */
149057
149695
  :where(.theme-scope) :where([data-block="customer-portal"]) .cp-badge {
149058
149696
  display: inline-flex;
@@ -149189,11 +149827,18 @@ const containerResponsiveThemeCss = `/*
149189
149827
  background: rgba(var(--tb-border), 0.2);
149190
149828
  }
149191
149829
 
149192
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table tbody tr:last-child td {
149830
+ :where(.theme-scope)
149831
+ :where([data-block="customer-portal"])
149832
+ .cp-table
149833
+ tbody
149834
+ tr:last-child
149835
+ td {
149193
149836
  border-bottom: none;
149194
149837
  }
149195
149838
 
149196
- :where(.theme-scope) :where([data-block="customer-portal"]) :is(.cp-row--past, .cp-row--muted) {
149839
+ :where(.theme-scope)
149840
+ :where([data-block="customer-portal"])
149841
+ :is(.cp-row--past, .cp-row--muted) {
149197
149842
  opacity: 0.65;
149198
149843
  }
149199
149844
 
@@ -149206,7 +149851,9 @@ const containerResponsiveThemeCss = `/*
149206
149851
  line-height: 1.2;
149207
149852
  }
149208
149853
 
149209
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-title__badges {
149854
+ :where(.theme-scope)
149855
+ :where([data-block="customer-portal"])
149856
+ .cp-row-title__badges {
149210
149857
  margin-left: auto;
149211
149858
  display: flex;
149212
149859
  flex-wrap: wrap;
@@ -149214,7 +149861,9 @@ const containerResponsiveThemeCss = `/*
149214
149861
  gap: 0.375rem;
149215
149862
  }
149216
149863
 
149217
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-title__text {
149864
+ :where(.theme-scope)
149865
+ :where([data-block="customer-portal"])
149866
+ .cp-row-title__text {
149218
149867
  min-width: 0;
149219
149868
  }
149220
149869
 
@@ -149234,12 +149883,16 @@ const containerResponsiveThemeCss = `/*
149234
149883
  line-height: 1.35;
149235
149884
  }
149236
149885
 
149237
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-note--success {
149886
+ :where(.theme-scope)
149887
+ :where([data-block="customer-portal"])
149888
+ .cp-row-note--success {
149238
149889
  border-left-color: rgb(var(--tb-success));
149239
149890
  color: rgb(var(--tb-success));
149240
149891
  }
149241
149892
 
149242
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-note--error {
149893
+ :where(.theme-scope)
149894
+ :where([data-block="customer-portal"])
149895
+ .cp-row-note--error {
149243
149896
  border-left-color: rgb(var(--tb-destructive));
149244
149897
  color: rgb(var(--tb-destructive));
149245
149898
  }
@@ -149258,16 +149911,23 @@ const containerResponsiveThemeCss = `/*
149258
149911
  white-space: nowrap;
149259
149912
  }
149260
149913
 
149261
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-col-actions .btn-sm {
149914
+ :where(.theme-scope)
149915
+ :where([data-block="customer-portal"])
149916
+ .cp-col-actions
149917
+ .btn-sm {
149262
149918
  white-space: nowrap;
149263
149919
  }
149264
149920
 
149265
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-title__link {
149921
+ :where(.theme-scope)
149922
+ :where([data-block="customer-portal"])
149923
+ .cp-row-title__link {
149266
149924
  color: inherit;
149267
149925
  text-decoration: none;
149268
149926
  }
149269
149927
 
149270
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-title__link:hover {
149928
+ :where(.theme-scope)
149929
+ :where([data-block="customer-portal"])
149930
+ .cp-row-title__link:hover {
149271
149931
  text-decoration: underline;
149272
149932
  text-decoration-thickness: 2px;
149273
149933
  text-underline-offset: 2px;
@@ -149289,7 +149949,9 @@ const containerResponsiveThemeCss = `/*
149289
149949
  }
149290
149950
 
149291
149951
  /* Profile actions */
149292
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-profile__actions {
149952
+ :where(.theme-scope)
149953
+ :where([data-block="customer-portal"])
149954
+ .cp-profile__actions {
149293
149955
  display: flex;
149294
149956
  gap: 0.75rem;
149295
149957
  margin-top: 1rem;
@@ -149356,28 +150018,39 @@ const containerResponsiveThemeCss = `/*
149356
150018
  gap: 0.375rem;
149357
150019
  }
149358
150020
 
149359
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guest-edit-row__index {
150021
+ :where(.theme-scope)
150022
+ :where([data-block="customer-portal"])
150023
+ .cp-guest-edit-row__index {
149360
150024
  font-size: 0.75rem;
149361
150025
  font-weight: 500;
149362
150026
  color: var(--cp-muted);
149363
150027
  }
149364
150028
 
149365
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guest-edit-row__fields {
150029
+ :where(.theme-scope)
150030
+ :where([data-block="customer-portal"])
150031
+ .cp-guest-edit-row__fields {
149366
150032
  display: flex;
149367
150033
  gap: 0.5rem;
149368
150034
  }
149369
150035
 
149370
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guest-edit-row__fields input {
150036
+ :where(.theme-scope)
150037
+ :where([data-block="customer-portal"])
150038
+ .cp-guest-edit-row__fields
150039
+ input {
149371
150040
  flex: 1;
149372
150041
  min-width: 0;
149373
150042
  }
149374
150043
 
149375
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guest-edit-row__error {
150044
+ :where(.theme-scope)
150045
+ :where([data-block="customer-portal"])
150046
+ .cp-guest-edit-row__error {
149376
150047
  font-size: 0.75rem;
149377
150048
  color: var(--cp-error);
149378
150049
  }
149379
150050
 
149380
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guests__actions {
150051
+ :where(.theme-scope)
150052
+ :where([data-block="customer-portal"])
150053
+ .cp-guests__actions {
149381
150054
  display: flex;
149382
150055
  gap: 0.5rem;
149383
150056
  margin-top: 0.5rem;
@@ -149391,13 +150064,18 @@ const containerResponsiveThemeCss = `/*
149391
150064
  }
149392
150065
 
149393
150066
  /* In the actions modal, tiles sit on a surface modal, so use "background" for contrast. */
149394
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-actions-list :where(.rb-tile) {
150067
+ :where(.theme-scope)
150068
+ :where([data-block="customer-portal"])
150069
+ .cp-actions-list
150070
+ :where(.rb-tile) {
149395
150071
  --rb-event-tile-bg: rgb(var(--tb-background));
149396
150072
  --rb-event-tile-border: rgb(var(--tb-border));
149397
150073
  }
149398
150074
 
149399
150075
  /* Actions trigger: icon-only kebab button */
149400
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-actions-trigger.btn-sm {
150076
+ :where(.theme-scope)
150077
+ :where([data-block="customer-portal"])
150078
+ .cp-actions-trigger.btn-sm {
149401
150079
  padding: 0.35rem !important;
149402
150080
  line-height: 1 !important;
149403
150081
  min-width: 32px;
@@ -149421,17 +150099,24 @@ const containerResponsiveThemeCss = `/*
149421
150099
  gap: 0.25rem;
149422
150100
  }
149423
150101
 
149424
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-action-tile__title {
150102
+ :where(.theme-scope)
150103
+ :where([data-block="customer-portal"])
150104
+ .cp-action-tile__title {
149425
150105
  font-weight: 600;
149426
150106
  font-size: 0.9375rem;
149427
150107
  }
149428
150108
 
149429
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-action-tile__desc {
150109
+ :where(.theme-scope)
150110
+ :where([data-block="customer-portal"])
150111
+ .cp-action-tile__desc {
149430
150112
  font-size: 0.875rem;
149431
150113
  line-height: 1.35;
149432
150114
  }
149433
150115
 
149434
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-action-tile--danger .cp-action-tile__title {
150116
+ :where(.theme-scope)
150117
+ :where([data-block="customer-portal"])
150118
+ .cp-action-tile--danger
150119
+ .cp-action-tile__title {
149435
150120
  color: rgb(var(--tb-destructive));
149436
150121
  }
149437
150122
 
@@ -149453,7 +150138,9 @@ const containerResponsiveThemeCss = `/*
149453
150138
  text-decoration: underline;
149454
150139
  }
149455
150140
 
149456
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-btn--link:hover {
150141
+ :where(.theme-scope)
150142
+ :where([data-block="customer-portal"])
150143
+ .cp-btn--link:hover {
149457
150144
  color: var(--cp-primary-hover);
149458
150145
  }
149459
150146
 
@@ -149492,34 +150179,48 @@ const containerResponsiveThemeCss = `/*
149492
150179
  margin-top: 0.75rem;
149493
150180
  }
149494
150181
 
149495
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-cancel-confirm__title {
150182
+ :where(.theme-scope)
150183
+ :where([data-block="customer-portal"])
150184
+ .cp-cancel-confirm__title {
149496
150185
  font-weight: 600;
149497
150186
  margin-bottom: 0.5rem;
149498
150187
  }
149499
150188
 
149500
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-cancel-confirm__message {
150189
+ :where(.theme-scope)
150190
+ :where([data-block="customer-portal"])
150191
+ .cp-cancel-confirm__message {
149501
150192
  margin-bottom: 0.25rem;
149502
150193
  }
149503
150194
 
149504
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-cancel-confirm__warning {
150195
+ :where(.theme-scope)
150196
+ :where([data-block="customer-portal"])
150197
+ .cp-cancel-confirm__warning {
149505
150198
  margin-bottom: 0.75rem;
149506
150199
  }
149507
150200
 
149508
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-cancel-confirm__actions {
150201
+ :where(.theme-scope)
150202
+ :where([data-block="customer-portal"])
150203
+ .cp-cancel-confirm__actions {
149509
150204
  display: flex;
149510
150205
  gap: 0.75rem;
149511
150206
  }
149512
150207
 
149513
150208
  /* Membership actions */
149514
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-membership-actions {
150209
+ :where(.theme-scope)
150210
+ :where([data-block="customer-portal"])
150211
+ .cp-membership-actions {
149515
150212
  margin-top: 0.75rem;
149516
150213
  }
149517
150214
 
149518
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-section-actions {
150215
+ :where(.theme-scope)
150216
+ :where([data-block="customer-portal"])
150217
+ .cp-section-actions {
149519
150218
  margin-top: 1rem;
149520
150219
  }
149521
150220
 
149522
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-card-subtitle--spaced {
150221
+ :where(.theme-scope)
150222
+ :where([data-block="customer-portal"])
150223
+ .cp-card-subtitle--spaced {
149523
150224
  margin-top: 0.75rem;
149524
150225
  }
149525
150226
 
@@ -149543,9 +150244,18 @@ const containerResponsiveThemeCss = `/*
149543
150244
  display: none;
149544
150245
  }
149545
150246
 
149546
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table :is(th, td).cp-col-guests,
149547
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table :is(th, td).cp-col-tickets,
149548
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table :is(th, td).cp-col-actions {
150247
+ :where(.theme-scope)
150248
+ :where([data-block="customer-portal"])
150249
+ .cp-table
150250
+ :is(th, td).cp-col-guests,
150251
+ :where(.theme-scope)
150252
+ :where([data-block="customer-portal"])
150253
+ .cp-table
150254
+ :is(th, td).cp-col-tickets,
150255
+ :where(.theme-scope)
150256
+ :where([data-block="customer-portal"])
150257
+ .cp-table
150258
+ :is(th, td).cp-col-actions {
149549
150259
  display: none;
149550
150260
  }
149551
150261
 
@@ -149554,24 +150264,34 @@ const containerResponsiveThemeCss = `/*
149554
150264
  }
149555
150265
 
149556
150266
  /* Make the cell a positioning context for the kebab */
149557
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row > td:first-child {
150267
+ :where(.theme-scope)
150268
+ :where([data-block="customer-portal"])
150269
+ .cp-row
150270
+ > td:first-child {
149558
150271
  position: relative;
149559
150272
  padding-right: 2.5rem;
149560
150273
  }
149561
150274
 
149562
150275
  /* Position kebab in top-right of the cell */
149563
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-mobile-actions {
150276
+ :where(.theme-scope)
150277
+ :where([data-block="customer-portal"])
150278
+ .cp-row-mobile-actions {
149564
150279
  position: absolute;
149565
150280
  top: 0.5rem;
149566
150281
  right: 0.5rem;
149567
150282
  margin-top: 0;
149568
150283
  }
149569
150284
 
149570
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-mobile-actions .btn-sm {
150285
+ :where(.theme-scope)
150286
+ :where([data-block="customer-portal"])
150287
+ .cp-row-mobile-actions
150288
+ .btn-sm {
149571
150289
  width: auto;
149572
150290
  }
149573
150291
 
149574
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-profile__edit {
150292
+ :where(.theme-scope)
150293
+ :where([data-block="customer-portal"])
150294
+ .cp-profile__edit {
149575
150295
  align-self: stretch;
149576
150296
  }
149577
150297
  }
@@ -150019,6 +150739,30 @@ const containerResponsiveThemeCss = `/*
150019
150739
  gap: 0.25rem;
150020
150740
  }
150021
150741
 
150742
+ /* Topic choices (visitor picks what to hear about). Same treatment as the
150743
+ form block's .fb-fieldset / .fb-inline, defined here because the newsletter
150744
+ form also renders inside contact-newsletter and the site footer. */
150745
+ :where(.theme-scope) .newsletter-topics {
150746
+ display: flex;
150747
+ flex-direction: column;
150748
+ gap: 0.5rem;
150749
+ border: none;
150750
+ padding: 0;
150751
+ margin: 0;
150752
+ min-width: 0;
150753
+ }
150754
+
150755
+ :where(.theme-scope) .newsletter-topics > legend {
150756
+ padding: 0;
150757
+ margin-bottom: 0.25rem;
150758
+ }
150759
+
150760
+ :where(.theme-scope) .newsletter-topic-choice {
150761
+ display: flex;
150762
+ align-items: center;
150763
+ gap: 0.5rem;
150764
+ }
150765
+
150022
150766
  /* Required indicator */
150023
150767
  :where(.theme-scope) .newsletter-required {
150024
150768
  color: rgb(var(--tb-primary));
@@ -150068,6 +150812,10 @@ const containerResponsiveThemeCss = `/*
150068
150812
  flex-shrink: 0;
150069
150813
  }
150070
150814
 
150815
+ :where(.theme-scope) .newsletter-inline .newsletter-topics {
150816
+ flex-basis: 100%;
150817
+ }
150818
+
150071
150819
  /* Mobile fallback for inline variant */
150072
150820
  @container rb-site (max-width: 640px) {
150073
150821
  @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
@@ -152670,7 +153418,7 @@ function PageContent(props) {
152670
153418
  previewToken,
152671
153419
  resolvedData,
152672
153420
  bookingOfferingPresets: bookingOfferingPresets ?? [],
152673
- mailingList,
153421
+ mailingList: mailingList ?? dataContext?.mailingList,
152674
153422
  bookingTimeZone: resolveSdkBookingTimeZone(bookingTimeZone),
152675
153423
  routes: routeMap,
152676
153424
  pagesByIdentifier,
@@ -154531,8 +155279,12 @@ function shouldSkipResolvedLoader(input) {
154531
155279
  * ```
154532
155280
  */
154533
155281
  async function prefetchBlockData$1(page, context, options) {
155282
+ return (await prefetchBlockDataWithFailures(page, context, options)).resolvedData;
155283
+ }
155284
+ async function prefetchBlockDataWithFailures(page, context, options) {
154534
155285
  const { apiClient, isValidEndpoint, onError, getCustomBlockLoaders, getBlockDefinition: getBlockDefinition$1 = getBlockDefinition, resolveParamsBindings: resolveParamsBindings$1 = resolveParamsBindings } = options;
154535
155286
  const results = {};
155287
+ const loaderFailures = {};
154536
155288
  const tasks = [];
154537
155289
  for (const block of page.blocks) {
154538
155290
  const blockId = block.id;
@@ -154580,6 +155332,11 @@ async function prefetchBlockData$1(page, context, options) {
154580
155332
  const blockResults = results[blockId] ?? (results[blockId] = {});
154581
155333
  blockResults[key] = data;
154582
155334
  } catch (error) {
155335
+ const blockFailures = loaderFailures[blockId] ?? (loaderFailures[blockId] = {});
155336
+ blockFailures[key] = {
155337
+ endpoint,
155338
+ params
155339
+ };
154583
155340
  if (onError) onError(error, {
154584
155341
  block: block.kind,
154585
155342
  loader: key
@@ -154589,7 +155346,10 @@ async function prefetchBlockData$1(page, context, options) {
154589
155346
  }
154590
155347
  }
154591
155348
  if (tasks.length > 0) await Promise.all(tasks);
154592
- return results;
155349
+ return {
155350
+ resolvedData: results,
155351
+ loaderFailures
155352
+ };
154593
155353
  }
154594
155354
  //#endregion
154595
155355
  //#region ../blocks/src/system/data/loaderEndpoints.ts
@@ -154835,9 +155595,11 @@ function convertPageResponseBlock(block) {
154835
155595
  if (typeof block.id !== "string" && block.id !== null) throw new Error(`Invalid block id in page: expected string or null, got ${typeof block.id}`);
154836
155596
  if (typeof block.kind !== "string") throw new Error(`Invalid block kind in page: expected string, got ${typeof block.kind}`);
154837
155597
  if (typeof block.purpose !== "string") throw new Error(`Invalid block purpose in page: expected string, got ${typeof block.purpose}`);
155598
+ if (block.contentVersionId !== void 0 && block.contentVersionId !== null && typeof block.contentVersionId !== "string") throw new Error(`Invalid content version id in page: expected string or null, got ${typeof block.contentVersionId}`);
154838
155599
  const admission = readInvalidBlockAdmission(block.admission);
154839
155600
  return {
154840
155601
  id: block.id,
155602
+ ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
154841
155603
  kind: block.kind,
154842
155604
  purpose: block.purpose,
154843
155605
  content: sanitizeSdkRuntimeBlockContent(block.kind, readContentRecord(block.content) ?? {}),
@@ -154870,6 +155632,7 @@ function projectRenderablePageOutline(page) {
154870
155632
  ...page,
154871
155633
  blocks: page.blocks.flatMap((block) => block.admission.kind === "renderable" ? [{
154872
155634
  id: block.id,
155635
+ ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
154873
155636
  kind: block.kind,
154874
155637
  purpose: block.purpose,
154875
155638
  content: block.admission.content,
@@ -154880,6 +155643,7 @@ function projectRenderablePageOutline(page) {
154880
155643
  function admitSdkRuntimePageBlock(block, customBlocks) {
154881
155644
  const base = {
154882
155645
  id: block.id,
155646
+ ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
154883
155647
  kind: block.kind,
154884
155648
  purpose: block.purpose,
154885
155649
  ...block.bindings ? { bindings: block.bindings } : {}
@@ -156558,6 +157322,14 @@ const PUBLIC_BOOKING_AVAILABILITY_ENDPOINT_DEFINITIONS = defineEndpointDefinitio
156558
157322
  auth: "public",
156559
157323
  responseKind: "json"
156560
157324
  },
157325
+ getPublicBookingServiceBySlug: {
157326
+ path: "/public/bookings/services/by-slug/{slug}",
157327
+ method: "GET",
157328
+ revalidate: publicReadFreshnessSeconds("getPublicBookingService"),
157329
+ tags: [TAG_TEMPLATES.publicBookingServices],
157330
+ auth: "public",
157331
+ responseKind: "json"
157332
+ },
156561
157333
  getPublicBookingResourcesReference: {
156562
157334
  path: "/public/bookings/resources/reference",
156563
157335
  method: "GET",
@@ -157111,16 +157883,110 @@ const PUBLIC_READ_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
157111
157883
  responseKind: "json"
157112
157884
  }
157113
157885
  });
157886
+ //#endregion
157887
+ //#region ../api/src/publicOnboardingAttemptEndpointDefinitions.ts
157888
+ /**
157889
+ * The anonymous onboarding attempt, addressed by its opaque resume token.
157890
+ *
157891
+ * Every route here is reached before there is an account, so none of them can
157892
+ * be scoped to a site or a user: the token is the whole credential. They are
157893
+ * kept together so that stays obvious.
157894
+ */
157895
+ const PUBLIC_ONBOARDING_ATTEMPT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
157896
+ createPublicOnboardingAttempt: {
157897
+ path: "/public/onboarding/attempts",
157898
+ method: "POST",
157899
+ auth: "public",
157900
+ errors: [],
157901
+ responseKind: "json"
157902
+ },
157903
+ createPublicOnboardingLogoUploadUrl: {
157904
+ path: "/public/onboarding/attempts/{attemptToken}/logo-upload-url",
157905
+ method: "POST",
157906
+ auth: "public",
157907
+ errors: [],
157908
+ responseKind: "json"
157909
+ },
157910
+ uploadPublicOnboardingLogo: {
157911
+ path: "/public/onboarding/attempts/{attemptToken}/logo",
157912
+ method: "POST",
157913
+ auth: "public",
157914
+ errors: [],
157915
+ responseKind: "json"
157916
+ },
157917
+ getPublicOnboardingAttempt: {
157918
+ path: "/public/onboarding/attempts/{attemptToken}",
157919
+ method: "GET",
157920
+ auth: "public",
157921
+ errors: [],
157922
+ responseKind: "json"
157923
+ },
157924
+ getPublicOnboardingAttemptProgress: {
157925
+ path: "/public/onboarding/attempts/{attemptToken}/status",
157926
+ method: "GET",
157927
+ auth: "public",
157928
+ errors: [],
157929
+ responseKind: "json"
157930
+ },
157931
+ updatePublicOnboardingAttempt: {
157932
+ path: "/public/onboarding/attempts/{attemptToken}",
157933
+ method: "PATCH",
157934
+ auth: "public",
157935
+ errors: [],
157936
+ responseKind: "json"
157937
+ },
157938
+ runPublicOnboardingAttempt: {
157939
+ path: "/public/onboarding/attempts/{attemptToken}/run",
157940
+ method: "POST",
157941
+ auth: "public",
157942
+ errors: [],
157943
+ responseKind: "json"
157944
+ },
157945
+ resendPublicOnboardingAttemptConfirmation: {
157946
+ path: "/public/onboarding/attempts/{attemptToken}/resend-confirmation",
157947
+ method: "POST",
157948
+ auth: "public",
157949
+ errors: [],
157950
+ responseKind: "json"
157951
+ }
157952
+ });
157953
+ //#endregion
157954
+ //#region ../api/src/billingEndpointDefinitions.ts
157955
+ const BILLING_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
157956
+ adminChangePlan: {
157957
+ path: "/admin/billing/plan",
157958
+ method: "POST",
157959
+ tags: ["admin", "billing"],
157960
+ auth: "admin",
157961
+ responseKind: "json"
157962
+ },
157963
+ changePlan: {
157964
+ path: "/billing/plan/change",
157965
+ method: "POST",
157966
+ tags: ["billing"],
157967
+ auth: "user",
157968
+ responseKind: "json"
157969
+ },
157970
+ createBillingPortalSession: {
157971
+ path: "/billing/portal/session",
157972
+ method: "POST",
157973
+ tags: ["billing"],
157974
+ auth: "user",
157975
+ responseKind: "json"
157976
+ }
157977
+ });
157114
157978
  ({
157115
157979
  ...ACCOUNT_ENDPOINT_DEFINITIONS,
157980
+ ...PUBLIC_ONBOARDING_ATTEMPT_ENDPOINT_DEFINITIONS,
157116
157981
  ...PUBLIC_EVENT_ENDPOINT_DEFINITIONS,
157117
157982
  ...GIFTING_ENDPOINT_DEFINITIONS,
157118
- ...PUBLIC_READ_ENDPOINT_DEFINITIONS
157983
+ ...PUBLIC_READ_ENDPOINT_DEFINITIONS,
157984
+ ...BILLING_ENDPOINT_DEFINITIONS
157119
157985
  }), TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, { ...SITE_API_KEY_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.site, TAG_TEMPLATES.siteBookingSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteBookingSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, {
157120
157986
  ...NEWSLETTER_ENDPOINT_DEFINITIONS,
157121
157987
  ...APPOINTMENT_ENDPOINT_DEFINITIONS,
157122
157988
  ...EVENT_SERIES_REGISTRATION_ENDPOINT_DEFINITIONS
157123
- }, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.workflowRunById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.routeById, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, { ...PUBLIC_BOOKING_AVAILABILITY_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.publicEventFilters, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicShop, TAG_TEMPLATES.publicCheckout, TAG_TEMPLATES.siteRoutableContent, { ...PUBLIC_EVENT_CHECKOUT_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, { ...EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS }, { ...SDK_MEDIA_ENDPOINT_DEFINITIONS }, { ...SDK_ENDPOINT_DEFINITIONS }, { ...SDK_ENTRY_READ_ENDPOINTS };
157989
+ }, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.workflowRunById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.routeById, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicBookingServices, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, { ...PUBLIC_BOOKING_AVAILABILITY_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.publicEventFilters, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicShop, TAG_TEMPLATES.publicCheckout, TAG_TEMPLATES.siteRoutableContent, { ...PUBLIC_EVENT_CHECKOUT_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, { ...EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS }, { ...SDK_MEDIA_ENDPOINT_DEFINITIONS }, { ...SDK_ENDPOINT_DEFINITIONS }, { ...SDK_ENTRY_READ_ENDPOINTS };
157124
157990
  z$1.object({ refreshToken: z$1.string().min(1).max(4096) }).strict();
157125
157991
  z$1.object({
157126
157992
  accessToken: z$1.string().min(1).max(4096),
@@ -157419,6 +158285,7 @@ function internalNavigationLinkToLocalLink(item) {
157419
158285
  }
157420
158286
  //#endregion
157421
158287
  //#region ../api/src/sdkConfig/contracts.ts
158288
+ init_src$2();
157422
158289
  /**
157423
158290
  * Canonical SDK config Zod contracts.
157424
158291
  *
@@ -157681,7 +158548,17 @@ const riverbankSiteConfigInputSchema = z$1.object({
157681
158548
  z$1.object({
157682
158549
  config: riverbankSiteConfigInputSchema,
157683
158550
  forceContentTypes: z$1.boolean().optional(),
157684
- mode: z$1.enum(["apply", "preview"]).optional()
158551
+ mode: z$1.enum(["apply", "preview"]).optional(),
158552
+ expectedMailingListProviderScope: z$1.unknown().transform((value, ctx) => {
158553
+ if (value === void 0) return void 0;
158554
+ const parsed = parseMailingListProviderScope(value);
158555
+ if (parsed.ok) return parsed.value;
158556
+ ctx.addIssue({
158557
+ code: "custom",
158558
+ message: "Invalid mailing-list provider scope"
158559
+ });
158560
+ return z$1.NEVER;
158561
+ }).optional()
157685
158562
  }).strict();
157686
158563
  //#endregion
157687
158564
  //#region ../api/src/sdkThemeWire.ts
@@ -162352,6 +163229,7 @@ function readEntrySlotKey(block) {
162352
163229
  function admitEntrySlotBlock(block, customBlocks) {
162353
163230
  const base = {
162354
163231
  id: block.id ?? block.blockId ?? null,
163232
+ contentVersionId: block.contentVersionId,
162355
163233
  kind: block.kind,
162356
163234
  purpose: block.purpose,
162357
163235
  ...isRecord(block.bindings) ? { bindings: block.bindings } : {}