@riverbankcms/sdk 0.139.0 → 0.141.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 (232) hide show
  1. package/README.md +1 -1
  2. package/dist/{PreviewEditorSidebar-BDeenhi3.mjs → PreviewEditorSidebar-Q-fy9GYw.mjs} +4 -4
  3. package/dist/{PreviewEditorUI-DSRhgjF5.mjs → PreviewEditorUI-LYGzgk85.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-D2K8GLUG.mjs → PreviewQueryProvider-CN0ewic5.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-CL7wSnYu.mjs → SdkPreviewModeRuntime-CoPYI5Jq.mjs} +90 -50
  6. package/dist/{SiteChromeCustomizeContext-BhDn-5ir.mjs → SiteChromeCustomizeContext-D8LePX8x.mjs} +2731 -1303
  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 +17 -31
  20. package/dist/_dts/api/src/domainConnection.d.ts +4 -0
  21. package/dist/_dts/api/src/endpoints.d.ts +93 -64
  22. package/dist/_dts/api/src/event-destination-policy.d.ts +2 -1
  23. package/dist/_dts/api/src/footerCompositionContracts.d.ts +25 -0
  24. package/dist/_dts/api/src/footerSettings.d.ts +9 -6
  25. package/dist/_dts/api/src/index.d.ts +6 -7
  26. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
  27. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  28. package/dist/_dts/api/src/launchReadiness.d.ts +1 -0
  29. package/dist/_dts/api/src/mailingListIntegration.d.ts +8 -2
  30. package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +1 -1
  31. package/dist/_dts/api/src/navigation/dashboardSiteNav.d.ts +2 -1
  32. package/dist/_dts/api/src/navigation/types.d.ts +1 -1
  33. package/dist/_dts/api/src/onboarding/confirmationResend.d.ts +25 -0
  34. package/dist/_dts/api/src/onboarding/surfaceData.d.ts +32 -32
  35. package/dist/_dts/api/src/publicBookingAvailabilityEndpointDefinitions.d.ts +8 -0
  36. package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +1 -0
  37. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +11 -3
  38. package/dist/_dts/api/src/publicExperience/sharedTypes.d.ts +3 -29
  39. package/dist/_dts/api/src/publicOnboardingAttemptEndpointDefinitions.d.ts +65 -0
  40. package/dist/_dts/api/src/saveOutcome.d.ts +20 -0
  41. package/dist/_dts/api/src/sdkContracts.d.ts +3 -22
  42. package/dist/_dts/api/src/sdkPushContracts.d.ts +18 -0
  43. package/dist/_dts/api/src/sdkThemeWire.d.ts +44 -44
  44. package/dist/_dts/api/src/settings/permissions.d.ts +12 -0
  45. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +10 -29
  46. package/dist/_dts/api/src/siteOnboarding.d.ts +9 -9
  47. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +2 -4
  48. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +3 -1
  49. package/dist/_dts/api/src/siteSettings.d.ts +20 -7
  50. package/dist/_dts/api/src/types.d.ts +77 -77
  51. package/dist/_dts/api/src/wholeSeriesRuns.d.ts +2 -37
  52. package/dist/_dts/billing/src/membership/index.d.ts +3 -0
  53. package/dist/_dts/billing/src/plans/types.d.ts +3 -0
  54. package/dist/_dts/billing/src/site-arrangements.d.ts +23 -3
  55. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +20 -4
  56. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +2 -0
  57. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +7 -0
  58. package/dist/_dts/blocks/src/portal/types.d.ts +2 -4
  59. package/dist/_dts/blocks/src/portal/waitlist-types.d.ts +35 -0
  60. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +2 -0
  61. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +2 -0
  62. package/dist/_dts/blocks/src/system/blocks/events/eventSelectionFields.d.ts +122 -0
  63. package/dist/_dts/blocks/src/system/blocks/events/shared/calendarWindow.d.ts +2 -1
  64. package/dist/_dts/blocks/src/system/blocks/events/shared/eventSelection.d.ts +11 -0
  65. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +42 -0
  66. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -0
  67. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +2 -2
  68. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +47 -47
  69. package/dist/_dts/blocks/src/system/data/index.d.ts +2 -2
  70. package/dist/_dts/blocks/src/system/data/prefetchBlockData.d.ts +7 -1
  71. package/dist/_dts/blocks/src/system/data/types.d.ts +9 -0
  72. package/dist/_dts/blocks/src/system/data/utils.d.ts +1 -1
  73. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +27 -1
  74. package/dist/_dts/blocks/src/system/registry.d.ts +1 -0
  75. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +0 -28
  76. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  77. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +7 -3
  78. package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +1 -1
  79. package/dist/_dts/blocks/src/system/runtime/api/types/waitlist-claims.d.ts +7 -2
  80. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +42 -186
  81. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +21 -93
  82. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.d.ts +2 -1
  83. package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +48 -1
  84. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +1 -2
  85. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +2 -0
  86. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.d.ts +14 -0
  87. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +56 -0
  88. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +4 -0
  89. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.state.d.ts +5 -0
  90. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +6 -8
  91. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.d.ts +8 -0
  92. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.d.ts +3 -0
  93. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.state.d.ts +10 -3
  94. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventCheckoutHandoffRestore.d.ts +9 -0
  95. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +8 -7
  96. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +14 -7
  97. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.d.ts +18 -0
  98. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useSettledCommerceView.d.ts +37 -0
  99. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.client.d.ts +1 -1
  100. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +24 -6
  101. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +4 -2
  102. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +4 -3
  103. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +3 -0
  104. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +11 -101
  105. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +7 -2
  106. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/listOptions.d.ts +2 -0
  107. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +6 -0
  108. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +1 -0
  109. package/dist/_dts/blocks/src/system/runtime/resolver.d.ts +1 -0
  110. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -6
  111. package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +2 -2
  112. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.d.ts +2 -0
  113. package/dist/_dts/blocks/src/system/transforms/registry/eventCalendar.d.ts +12 -0
  114. package/dist/_dts/commerce/src/purchase/bookingInstalmentSchedule.d.ts +4 -0
  115. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -0
  116. package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +27 -4
  117. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +2 -1
  118. package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +3 -1
  119. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +3 -0
  120. package/dist/_dts/core/src/branded.d.ts +0 -8
  121. package/dist/_dts/core/src/index.d.ts +1 -0
  122. package/dist/_dts/core/src/mailing-list-setup-parser.d.ts +1 -1
  123. package/dist/_dts/core/src/mailing-list-setup.d.ts +14 -1
  124. package/dist/_dts/core/src/mailing-list-submission.d.ts +7 -27
  125. package/dist/_dts/core/src/participants.d.ts +2 -29
  126. package/dist/_dts/core/src/public-experience.d.ts +4 -0
  127. package/dist/_dts/core/src/public-profile.d.ts +27 -1
  128. package/dist/_dts/core/src/site-route-target.d.ts +9 -2
  129. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +296 -606
  130. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListGlobalSettingsSummary.d.ts +10 -0
  131. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListTargetingField.d.ts +3 -2
  132. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/context.d.ts +3 -2
  133. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/loaders.d.ts +3 -2
  134. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/targetingState.d.ts +19 -0
  135. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +27 -1
  136. package/dist/_dts/sdk/src/public-api/contracts.d.ts +14 -20
  137. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -0
  138. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -0
  139. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +7 -1
  140. package/dist/_dts/sdk/src/rendering/helpers/templateContent.d.ts +1 -0
  141. package/dist/_dts/sdk/src/version.d.ts +1 -1
  142. package/dist/_dts/theme-core/src/ThemeFontLoader.d.ts +17 -1
  143. package/dist/_dts/theme-core/src/accordions/types.d.ts +3 -3
  144. package/dist/_dts/theme-core/src/buttons/affordanceSuppression.d.ts +17 -0
  145. package/dist/_dts/theme-core/src/buttons/buttonColourContract.d.ts +1 -1
  146. package/dist/_dts/theme-core/src/buttons/classNames.d.ts +16 -0
  147. package/dist/_dts/theme-core/src/buttons/generateButtonCss.d.ts +0 -6
  148. package/dist/_dts/theme-core/src/buttons/resolvedButtonCss.d.ts +4 -4
  149. package/dist/_dts/theme-core/src/cards/types.d.ts +21 -21
  150. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  151. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +8 -2
  152. package/dist/_dts/theme-core/src/header/legacyHeaderVariant.d.ts +2 -2
  153. package/dist/_dts/theme-core/src/hosted-booking-appearance.d.ts +54 -12
  154. package/dist/_dts/theme-core/src/index.d.ts +1 -1
  155. package/dist/_dts/theme-core/src/inputs/types.d.ts +2 -2
  156. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +54 -54
  157. package/dist/_dts/theme-core/src/runtime/buildThemeRuntimeFromBridge.d.ts +1 -4
  158. package/dist/_dts/theme-core/src/schema.d.ts +84 -84
  159. package/dist/_dts/theme-core/src/shared/componentStyles.d.ts +1 -1
  160. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  161. package/dist/_dts/theme-core/src/surfaces/foregroundInteraction.d.ts +77 -0
  162. package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
  163. package/dist/_dts/theme-core/src/typography/generateTypographyCss.d.ts +2 -2
  164. package/dist/_dts/ui/src/lib/use-delayed-flag.d.ts +9 -0
  165. package/dist/_dts/ui/src/pending-button.d.ts +10 -0
  166. package/dist/client/{BookingConsentAgreement-CZvTDtsK.mjs → BookingConsentAgreement-xJeYNdnb.mjs} +4 -4
  167. package/dist/client/{DiscountCodeDisclosure-D-DsLCMU.mjs → DiscountCodeDisclosure-DdT6uzl9.mjs} +1 -1
  168. package/dist/client/{EventCombined.client-dWqgd5ZO.mjs → EventCombined.client-Cp28uYuM.mjs} +12 -16
  169. package/dist/client/{EventListing.client-BMRa9IYp.mjs → EventListing.client-CD6AJsMr.mjs} +4 -17
  170. package/dist/client/{LeafletStaticMap-D21W9kBZ.mjs → LeafletStaticMap-DBsAi9-e.mjs} +1 -1
  171. package/dist/client/{accordion-FxF_ta47.mjs → accordion-6dwbOKYR.mjs} +1 -1
  172. package/dist/client/{bookingForm-YnwW4TGw.mjs → bookingForm-CZE9_qPQ.mjs} +7 -7
  173. package/dist/client/bookings.mjs +500 -233
  174. package/dist/client/{carousel-vng7fFT5.mjs → carousel-7VHGQARz.mjs} +2 -2
  175. package/dist/client/{carousel.client-59G_WMr4.mjs → carousel.client-DQTjCVQT.mjs} +1 -1
  176. package/dist/client/{cart-DEPDsjNk.mjs → cart-Qg_mvQhh.mjs} +3 -3
  177. package/dist/client/{checkout-CZRWu9rW.mjs → checkout-D84rpgdr.mjs} +3 -3
  178. package/dist/client/{checkoutUrls-BuseL0dw.mjs → checkoutUrls-FL6lRkrt.mjs} +1 -1
  179. package/dist/client/client.mjs +2315 -1017
  180. package/dist/client/{colorStyles-CrxJrPjJ.mjs → colorStyles-3013aRAY.mjs} +3 -1
  181. package/dist/client/{context-DvU_WUmd.mjs → context-Ctp3T0Wr.mjs} +6 -19
  182. package/dist/client/{dates-wnPMiRl5.mjs → dates-DJKFcI_N.mjs} +2 -2
  183. package/dist/client/{eventCalendar-BA3Q5L15.mjs → eventCalendar-CK31z3vs.mjs} +12 -8
  184. package/dist/client/{eventCombined-51wgR-1R.mjs → eventCombined-DiXd-ewn.mjs} +3 -3
  185. package/dist/client/{eventDetails-modaetpm.mjs → eventDetails-CTRgt2DK.mjs} +4 -4
  186. package/dist/client/{eventListing-D8t2J3Kv.mjs → eventListing-Dy9vi_j_.mjs} +3 -3
  187. package/dist/client/{eventRegistration-CYqtkCE_.mjs → eventRegistration-CnalYMr2.mjs} +618 -177
  188. package/dist/client/{form-CBKXN5In.mjs → form-eUiMveTT.mjs} +3 -3
  189. package/dist/client/{headerSection-DylDqNrs.mjs → headerSection-Dy9kQpB1.mjs} +2 -2
  190. package/dist/client/hooks.mjs +692 -212
  191. package/dist/client/{locationMap-CvWrG0vZ.mjs → locationMap-DalCmWU0.mjs} +3 -3
  192. package/dist/client/{media-BOHuueS5.mjs → media-DHpfFwd3.mjs} +1 -1
  193. package/dist/client/{newsletterForm-Btwk70zw.mjs → newsletterForm-SDDPvhS0.mjs} +150 -94
  194. package/dist/client/{pricing-Uzw-GQ6Y.mjs → pricing-OcMz4SnX.mjs} +1 -1
  195. package/dist/client/{productDetail-JLcUYKnd.mjs → productDetail-BQrgHElM.mjs} +3 -3
  196. package/dist/client/{productList-FM0cbUzj.mjs → productList-OnPn_UJj.mjs} +3 -3
  197. package/dist/client/{propsDecoder-DYzafZb2.mjs → propsDecoder-zBdsnS-N.mjs} +168 -32
  198. package/dist/client/rendering/client.mjs +1355 -519
  199. package/dist/client/rendering/islands.mjs +19 -19
  200. package/dist/client/rendering.mjs +2294 -953
  201. package/dist/client/{scrollToBlock-CvXszexS.mjs → scrollToBlock-BNM4Ob2Y.mjs} +28 -11
  202. package/dist/client/{shop-BIcjvy5a.mjs → shop-Bv1fPTwQ.mjs} +6 -6
  203. package/dist/client/{shop-commerce-BZQsy7xw.mjs → shop-commerce-D4KNGaW8.mjs} +7 -7
  204. package/dist/client/{shop-commerce-store-D5V7XAb5.mjs → shop-commerce-store-2N5EV0Rc.mjs} +1 -1
  205. package/dist/client/{shopShared-DowkXevB.mjs → shopShared-DvJGdHTV.mjs} +4 -4
  206. package/dist/client/{useEventFilters-oMoTw_JE.mjs → useEventFilters-BBBvGDHQ.mjs} +19 -13
  207. package/dist/preview-next/before-render.mjs +119 -64
  208. package/dist/preview-next/client/runtime.mjs +4 -4
  209. package/dist/preview-next/editor-chrome.css +4 -8
  210. package/dist/preview-next/keepAlive.mjs +119 -64
  211. package/dist/preview-next/middleware.mjs +119 -64
  212. package/dist/{previewAuthStore-COUyAKaX.mjs → previewAuthStore-Gjb6r6vz.mjs} +119 -64
  213. package/dist/{sdk-runtime-D4k2LSGF.mjs → sdk-runtime-Defnbfzw.mjs} +2 -2
  214. package/dist/{separator-UGtpag4Z.mjs → separator-CZXO3Sb0.mjs} +1 -1
  215. package/dist/server/components.mjs +1170 -384
  216. package/dist/server/config-validation.mjs +560 -105
  217. package/dist/server/config.mjs +564 -109
  218. package/dist/server/data.mjs +688 -212
  219. package/dist/server/index.mjs +126 -66
  220. package/dist/server/next.mjs +1429 -662
  221. package/dist/server/page-converter.mjs +372 -99
  222. package/dist/server/prebuild.mjs +1 -1
  223. package/dist/server/rendering/server.mjs +1624 -817
  224. package/dist/server/rendering.mjs +1200 -391
  225. package/dist/server/routing.mjs +767 -247
  226. package/dist/server/server.mjs +715 -276
  227. package/dist/server/theme-bridge.mjs +475 -110
  228. package/dist/server/theme.mjs +9 -3
  229. package/dist/styles/index.css +265 -45
  230. package/package.json +1 -1
  231. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionCompactRow.d.ts +0 -29
  232. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingOptionList.d.ts +0 -13
@@ -36,10 +36,12 @@ const unsafeAsStorageBucketName = (value) => value;
36
36
  const unsafeAsStoragePath = (value) => value;
37
37
  const unsafeAsPositiveByteCount = (value) => value;
38
38
  const unsafeAsUserId = (id) => id;
39
+ const unsafeAsContentVersionId = (id) => id;
39
40
  const parseSiteId = (value) => parseUuidBrand$1(value, unsafeAsSiteId);
40
41
  const parseApiKeyId = (value) => parseUuidBrand$1(value, unsafeAsApiKeyId);
41
42
  const parseEventOfferingId = (value) => parseUuidBrand$1(value, unsafeAsEventOfferingId);
42
43
  const parseUserId = (value) => parseUuidBrand$1(value, unsafeAsUserId);
44
+ const parseContentVersionId = (value) => parseUuidBrand$1(value, unsafeAsContentVersionId);
43
45
  const parseEventSeriesId = (value) => parseUuidBrand$1(value, unsafeAsEventSeriesId);
44
46
  //#endregion
45
47
  //#region ../core/src/assert-never.ts
@@ -312,7 +314,7 @@ function parseEventPageSurfaceDestinationMode(value) {
312
314
  return value === "cms-managed" || value === "system-managed" ? value : void 0;
313
315
  }
314
316
  function parseEventPageSurfaceSubject(value) {
315
- if (!isRecord$39(value)) return err$3({ kind: "notObject" });
317
+ if (!isRecord$40(value)) return err$3({ kind: "notObject" });
316
318
  switch (value.kind) {
317
319
  case "eventSeries": {
318
320
  const eventSeriesId = parseEventSeriesId(value.eventSeriesId);
@@ -367,7 +369,7 @@ function parseEventSeriesIdList(values) {
367
369
  }
368
370
  return ok$3(parsed);
369
371
  }
370
- function isRecord$39(value) {
372
+ function isRecord$40(value) {
371
373
  return typeof value === "object" && value !== null && !Array.isArray(value);
372
374
  }
373
375
  //#endregion
@@ -611,7 +613,7 @@ function toLocationCoordinates(value) {
611
613
  }
612
614
  //#endregion
613
615
  //#region ../core/src/rich-text.ts
614
- function isRecord$37(value) {
616
+ function isRecord$38(value) {
615
617
  return typeof value === "object" && value !== null && !Array.isArray(value);
616
618
  }
617
619
  function hasOnlyKeys(value, allowed) {
@@ -630,10 +632,10 @@ function isDenseArrayOf(value, predicate) {
630
632
  return true;
631
633
  }
632
634
  function isTipTapMark(value) {
633
- return isRecord$37(value) && hasOnlyKeys(value, markKeys) && typeof value.type === "string" && value.type.length > 0 && (value.attrs === void 0 || isRecord$37(value.attrs));
635
+ return isRecord$38(value) && hasOnlyKeys(value, markKeys) && typeof value.type === "string" && value.type.length > 0 && (value.attrs === void 0 || isRecord$38(value.attrs));
634
636
  }
635
637
  function isTipTapNode(value) {
636
- if (!isRecord$37(value) || !hasOnlyKeys(value, nodeKeys) || typeof value.type !== "string" || value.type.length === 0 || value.type === "doc" || value.attrs !== void 0 && !isRecord$37(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;
638
+ if (!isRecord$38(value) || !hasOnlyKeys(value, nodeKeys) || typeof value.type !== "string" || value.type.length === 0 || value.type === "doc" || value.attrs !== void 0 && !isRecord$38(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;
637
639
  if (value.type === "text") return typeof value.text === "string" && value.text.length > 0 && value.content === void 0;
638
640
  return value.text === void 0;
639
641
  }
@@ -652,22 +654,28 @@ function parsePositiveInteger(value) {
652
654
  function parseNewsletterListId(value) {
653
655
  return parseTrimmedMatchingString(value, UUID_PATTERN$2);
654
656
  }
657
+ function parseMailchimpAccountId(value) {
658
+ return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
659
+ }
655
660
  function parseMailchimpAudienceId$1(value) {
656
661
  return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
657
662
  }
658
663
  function parseMailchimpInterestId(value) {
659
664
  return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
660
665
  }
666
+ function parseBrevoAccountId(value) {
667
+ return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
668
+ }
661
669
  function parseBrevoListId(value) {
662
670
  return parsePositiveInteger(value);
663
671
  }
664
672
  //#endregion
665
673
  //#region ../core/src/mailing-list-targeting-parser.ts
666
674
  function parseMailingListPlacementTargeting(value) {
667
- if (!isRecord$36(value)) return targetingError("shape");
675
+ if (!isRecord$37(value)) return targetingError("shape");
668
676
  if (value.mode === "default") return ok$3({ mode: "default" });
669
677
  if (value.mode !== "custom") return targetingError("mode");
670
- if (!isRecord$36(value.selection)) return targetingError("selection");
678
+ if (!isRecord$37(value.selection)) return targetingError("selection");
671
679
  switch (value.provider) {
672
680
  case "native": return parseNativeTargeting(value.selection);
673
681
  case "brevo": return parseBrevoTargeting(value.selection);
@@ -771,7 +779,7 @@ function parseUniqueIds(value, parseId) {
771
779
  }
772
780
  return ok$3(parsed);
773
781
  }
774
- function isRecord$36(value) {
782
+ function isRecord$37(value) {
775
783
  return typeof value === "object" && value !== null && !Array.isArray(value);
776
784
  }
777
785
  function targetingError(field) {
@@ -793,6 +801,31 @@ new Map([
793
801
  "legal"
794
802
  ].map((kind, index) => [kind, index]));
795
803
  //#endregion
804
+ //#region ../core/src/mailing-list-setup.ts
805
+ function isRecord$34(value) {
806
+ return typeof value === "object" && value !== null && !Array.isArray(value);
807
+ }
808
+ const DEFAULT_MAILING_LIST_SUCCESS_MESSAGE = "Thanks — you're on the list.";
809
+ function parseMailingListProviderScope(value) {
810
+ if (!isRecord$34(value)) return err$3("invalid_mailing_list_provider_scope");
811
+ if (value.provider === "native") return ok$3({ provider: "native" });
812
+ if (value.provider === "brevo") {
813
+ const accountId = parseBrevoAccountId(value.accountId);
814
+ return accountId !== null ? ok$3({
815
+ provider: "brevo",
816
+ accountId
817
+ }) : err$3("invalid_mailing_list_provider_scope");
818
+ }
819
+ if (value.provider === "mailchimp") {
820
+ const accountId = parseMailchimpAccountId(value.accountId);
821
+ return accountId !== null ? ok$3({
822
+ provider: "mailchimp",
823
+ accountId
824
+ }) : err$3("invalid_mailing_list_provider_scope");
825
+ }
826
+ return err$3("invalid_mailing_list_provider_scope");
827
+ }
828
+ //#endregion
796
829
  //#region ../core/src/mailing-list-setup-parser.ts
797
830
  function parseMailingListGlobalForm(value) {
798
831
  if (!isRecord$33(value)) return formError("shape");
@@ -801,12 +834,15 @@ function parseMailingListGlobalForm(value) {
801
834
  if (typeof value.includeOptionalPhone !== "boolean") return formError("includeOptionalPhone");
802
835
  const buttonLabel = parseRequiredString(value.buttonLabel);
803
836
  if (buttonLabel === null) return formError("buttonLabel");
837
+ const successMessage = parseRequiredString(value.successMessage);
838
+ if (successMessage === null) return formError("successMessage");
804
839
  const privacyNote = parseOptionalString(value.privacyNote);
805
840
  if (privacyNote === void 0) return formError("privacyNote");
806
841
  return ok$3({
807
842
  fields,
808
843
  includeOptionalPhone: value.includeOptionalPhone,
809
844
  buttonLabel,
845
+ successMessage,
810
846
  privacyNote
811
847
  });
812
848
  }
@@ -1013,11 +1049,17 @@ function parseMailingListSignedSourceToken(value) {
1013
1049
  const parsed = typeof value === "string" ? value.trim() : "";
1014
1050
  return /^[A-Za-z0-9._~-]{16,1000}$/u.test(parsed) ? parsed : null;
1015
1051
  }
1016
- function buildMailingListSignupBlockSourceRef(blockId) {
1017
- const parsed = parseMailingListBlockId(blockId);
1018
- return parsed !== null ? {
1052
+ function parseMailingListContentVersionId(value) {
1053
+ const parsed = parseContentVersionId(value);
1054
+ return parsed.ok ? parsed.value : null;
1055
+ }
1056
+ function buildMailingListSignupBlockSourceRef(blockId, contentVersionId) {
1057
+ const parsedBlockId = parseMailingListBlockId(blockId);
1058
+ const parsedContentVersionId = parseMailingListContentVersionId(contentVersionId);
1059
+ return parsedBlockId !== null && parsedContentVersionId !== null ? {
1019
1060
  tag: "block_ref",
1020
- blockId: parsed
1061
+ blockId: parsedBlockId,
1062
+ contentVersionId: parsedContentVersionId
1021
1063
  } : null;
1022
1064
  }
1023
1065
  function sortStableJsonValue(value) {
@@ -2419,6 +2461,7 @@ function isDisplayMediaKind$2(kind) {
2419
2461
  }
2420
2462
  const siteOptionSources = [
2421
2463
  "eventCategories",
2464
+ "eventSeries",
2422
2465
  "venues",
2423
2466
  "staffMembers"
2424
2467
  ];
@@ -4309,29 +4352,6 @@ function contrastRatio(hex1, hex2) {
4309
4352
  return (hi + .05) / (lo + .05);
4310
4353
  }
4311
4354
  //#endregion
4312
- //#region ../theme-core/src/palette/utils/onColor.ts
4313
- const BACKGROUND_ROLE_NAMES = /* @__PURE__ */ new Set([
4314
- "primary",
4315
- "secondary",
4316
- "accent",
4317
- "success",
4318
- "warning",
4319
- "destructive",
4320
- "info",
4321
- "background",
4322
- "surface",
4323
- "surfaceAlt",
4324
- "muted",
4325
- "neutral"
4326
- ]);
4327
- function onColorTokenName(backgroundToken) {
4328
- return `on${backgroundToken.split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}`;
4329
- }
4330
- function isOnColorBackgroundCandidateToken(token) {
4331
- const role = token.match(/^(.*?)(?:-\d{2,3})?$/)?.[1] ?? token;
4332
- return BACKGROUND_ROLE_NAMES.has(role);
4333
- }
4334
- //#endregion
4335
4355
  //#region ../theme-core/src/tokens/colorTokenParts.ts
4336
4356
  function parseOpacityPercent(source) {
4337
4357
  const trimmed = source.trim();
@@ -4369,6 +4389,141 @@ function parseColorTokenParts(source) {
4369
4389
  opacityPercent
4370
4390
  };
4371
4391
  }
4392
+ const defaultThemeTokens = {
4393
+ color: {
4394
+ "background/base": "#ffffff",
4395
+ "background/elevated": "#f5f5f5",
4396
+ "surface/base": "#ffffff",
4397
+ "surface/subtle": "#f9f9fb",
4398
+ "surface/inverted": "#111111",
4399
+ "content/primary": "#111111",
4400
+ "content/secondary": "#3f3f46",
4401
+ "accent/primary": "#2563eb",
4402
+ "accent/secondary": "#1d4ed8",
4403
+ "border/base": "#e5e7eb"
4404
+ },
4405
+ typography: {
4406
+ "display/hero": {
4407
+ fontSize: "clamp(48px, 8vw, 96px)",
4408
+ lineHeight: "1.05",
4409
+ fontWeight: "700"
4410
+ },
4411
+ "display/section": {
4412
+ fontSize: "clamp(40px, 6vw, 72px)",
4413
+ lineHeight: "1.1",
4414
+ fontWeight: "700"
4415
+ },
4416
+ "heading/large": {
4417
+ fontSize: "clamp(32px, 4vw, 48px)",
4418
+ lineHeight: "1.2",
4419
+ fontWeight: "600"
4420
+ },
4421
+ "heading/medium": {
4422
+ fontSize: "clamp(24px, 3vw, 32px)",
4423
+ lineHeight: "1.25",
4424
+ fontWeight: "600"
4425
+ },
4426
+ "heading/small": {
4427
+ fontSize: "20px",
4428
+ lineHeight: "1.3",
4429
+ fontWeight: "600"
4430
+ },
4431
+ "body/normal": {
4432
+ fontSize: "16px",
4433
+ lineHeight: "1.6",
4434
+ fontWeight: "400"
4435
+ },
4436
+ "body/small": {
4437
+ fontSize: "14px",
4438
+ lineHeight: "1.5",
4439
+ fontWeight: "400"
4440
+ },
4441
+ caption: {
4442
+ fontSize: "12px",
4443
+ lineHeight: "1.4",
4444
+ fontWeight: "500"
4445
+ }
4446
+ },
4447
+ spacing: {
4448
+ none: "0px",
4449
+ "3xs": "4px",
4450
+ "2xs": "8px",
4451
+ xs: "12px",
4452
+ sm: "16px",
4453
+ md: "24px",
4454
+ lg: "32px",
4455
+ xl: "40px",
4456
+ "2xl": "56px",
4457
+ "3xl": "72px"
4458
+ },
4459
+ radius: {
4460
+ none: "0px",
4461
+ xs: "2px",
4462
+ sm: "4px",
4463
+ md: "8px",
4464
+ lg: "12px",
4465
+ pill: "999px",
4466
+ full: "9999px"
4467
+ },
4468
+ shadow: {
4469
+ none: "none",
4470
+ soft: "0px 2px 8px rgba(15, 23, 42, 0.08)",
4471
+ medium: "0px 6px 18px rgba(15, 23, 42, 0.12)",
4472
+ strong: "0px 12px 36px rgba(15, 23, 42, 0.16)"
4473
+ },
4474
+ palette: {
4475
+ surface: "#ffffff",
4476
+ "neutral-50": "#f9fafb",
4477
+ "neutral-900": "#111827",
4478
+ primary: "#2563eb",
4479
+ "primary-50": "#eff6ff",
4480
+ "primary-500": "#2563eb",
4481
+ "primary-900": "#1d4ed8",
4482
+ secondary: "#9333ea",
4483
+ "secondary-50": "#f3e8ff",
4484
+ "secondary-500": "#9333ea",
4485
+ "secondary-900": "#4c1d95",
4486
+ accent: "#f97316",
4487
+ "accent-50": "#fff7ed",
4488
+ "accent-500": "#f97316",
4489
+ "accent-900": "#7c2d12"
4490
+ }
4491
+ };
4492
+ /**
4493
+ * Project the expanded semantic palette into the token buckets consumed by
4494
+ * runtime transforms. Keep this mapping shared by full themes and the
4495
+ * tokens-only hosted-booking runtime so the two paths cannot drift.
4496
+ */
4497
+ function buildThemeTokens(palette) {
4498
+ const tokens = cloneThemeTokens(defaultThemeTokens);
4499
+ const paletteStrings = {};
4500
+ for (const [key, value] of Object.entries(palette)) if (typeof value === "string" && value.trim().length > 0) paletteStrings[key] = value;
4501
+ tokens.palette = paletteStrings;
4502
+ const resolveColor = (...keys) => {
4503
+ for (const key of keys) {
4504
+ const value = paletteStrings[key];
4505
+ if (value) return value;
4506
+ }
4507
+ };
4508
+ const assignColor = (token, ...keys) => {
4509
+ const value = resolveColor(...keys);
4510
+ if (value) tokens.color[token] = value;
4511
+ };
4512
+ assignColor("background/base", "background", "surface", "primary-50");
4513
+ assignColor("background/elevated", "surface", "background");
4514
+ assignColor("surface/base", "surface", "background");
4515
+ assignColor("surface/subtle", "neutral-100", "surface", "background");
4516
+ assignColor("surface/inverted", "neutral-900", "text", "primary-900");
4517
+ assignColor("content/primary", "text", "body", "neutral-900");
4518
+ assignColor("content/secondary", "mutedText", "secondary", "neutral-600");
4519
+ assignColor("accent/primary", "primary", "accent");
4520
+ assignColor("accent/secondary", "accent", "secondary", "primary-400");
4521
+ assignColor("border/base", "border", "neutral-300");
4522
+ return tokens;
4523
+ }
4524
+ function cloneThemeTokens(source) {
4525
+ return JSON.parse(JSON.stringify(source));
4526
+ }
4372
4527
  //#endregion
4373
4528
  //#region ../theme-core/src/tokens/blockColorTokens.ts
4374
4529
  const blockColorTokenNames = [
@@ -4479,6 +4634,101 @@ function parseThemeColorToken(value) {
4479
4634
  }
4480
4635
  const themeColorTokenSchema = z$1.string().min(1).refine((value) => Boolean(isThemeColorToken(value)), "Expected a known Theme V2 color token");
4481
4636
  //#endregion
4637
+ //#region ../theme-core/src/tokens/resolver.ts
4638
+ /**
4639
+ * Resolves theme tokens to CSS variables
4640
+ *
4641
+ * This resolver ensures all button styles use theme tokens (not hardcoded colors)
4642
+ * so that changing the palette automatically updates all buttons.
4643
+ */
4644
+ var TokenResolver = class {
4645
+ constructor(theme) {
4646
+ this.theme = theme;
4647
+ }
4648
+ /**
4649
+ * Resolve a color token to a CSS variable reference wrapped in rgb()
4650
+ *
4651
+ * @param token - Token name (e.g., 'primary-500', 'white', 'text-900')
4652
+ * @returns CSS rgb() function with var reference (e.g., 'rgb(var(--tb-primary-500))')
4653
+ *
4654
+ * Note: CSS variables are stored as RGB channels (e.g., "37 99 235") following Tailwind convention,
4655
+ * so we must wrap them with rgb() to create a valid color value.
4656
+ *
4657
+ * @example
4658
+ * resolver.getColor('primary-500') // => 'rgb(var(--tb-primary-500))'
4659
+ * resolver.getColor('white') // => 'rgb(var(--tb-white))'
4660
+ */
4661
+ getColor(token) {
4662
+ if (!this.tokenExists(token)) console.warn(`[TokenResolver] Color token "${token}" not found in theme palette. Button may render incorrectly.`);
4663
+ return rgbColorValue(token);
4664
+ }
4665
+ /**
4666
+ * Adjust a color token's shade by a given amount
4667
+ *
4668
+ * @param token - Base token (e.g., 'primary-500')
4669
+ * @param amount - Shade adjustment (+100 = darker, -100 = lighter)
4670
+ * @returns Adjusted token name (e.g., 'primary-600')
4671
+ *
4672
+ * @example
4673
+ * resolver.adjustShade('primary-500', 100) // => 'primary-600' (darker)
4674
+ * resolver.adjustShade('primary-500', -100) // => 'primary-400' (lighter)
4675
+ */
4676
+ adjustShade(token, amount) {
4677
+ const parts = token.split("-");
4678
+ if (parts.length < 2) return `${token}-${Math.max(100, Math.min(900, 500 + amount))}`;
4679
+ const base = parts.slice(0, -1).join("-");
4680
+ const shade = parseInt(parts[parts.length - 1] ?? "", 10);
4681
+ if (isNaN(shade)) {
4682
+ console.warn(`[TokenResolver] Cannot adjust shade for non-shade token "${token}". Returning original token.`);
4683
+ return token;
4684
+ }
4685
+ return `${base}-${Math.max(100, Math.min(900, shade + amount))}`;
4686
+ }
4687
+ /**
4688
+ * Check if a token exists in the theme palette
4689
+ *
4690
+ * @param token - Token name to check
4691
+ * @returns True if token exists in theme
4692
+ */
4693
+ tokenExists(token) {
4694
+ if ([
4695
+ "white",
4696
+ "black",
4697
+ "transparent"
4698
+ ].includes(token)) return true;
4699
+ const parts = token.split("-");
4700
+ if (parts.length >= 2) {
4701
+ const lastPart = parts[parts.length - 1] ?? "";
4702
+ const shade = parseInt(lastPart, 10);
4703
+ if (!isNaN(shade) && shade >= 100 && shade <= 900 && shade % 100 === 0) return true;
4704
+ }
4705
+ return true;
4706
+ }
4707
+ };
4708
+ //#endregion
4709
+ //#region ../theme-core/src/palette/utils/onColor.ts
4710
+ const BACKGROUND_ROLE_NAMES = /* @__PURE__ */ new Set([
4711
+ "primary",
4712
+ "secondary",
4713
+ "accent",
4714
+ "success",
4715
+ "warning",
4716
+ "destructive",
4717
+ "info",
4718
+ "background",
4719
+ "surface",
4720
+ "surfaceAlt",
4721
+ "muted",
4722
+ "neutral"
4723
+ ]);
4724
+ function onColorTokenName(backgroundToken) {
4725
+ return `on${backgroundToken.split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}`;
4726
+ }
4727
+ function isOnColorBackgroundCandidateToken(token) {
4728
+ const role = token.match(/^(.*?)(?:-\d{2,3})?$/)?.[1] ?? token;
4729
+ return BACKGROUND_ROLE_NAMES.has(role);
4730
+ }
4731
+ //#endregion
4482
4732
  //#region ../theme-core/src/palette/colors.ts
4483
4733
  const HEX_COLOR_REGEX = /^#[0-9a-f]{6}$/;
4484
4734
  const NORMALIZABLE_HEX_REGEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
@@ -6152,213 +6402,6 @@ function assertUniqueLayoutProfileKeys(profiles) {
6152
6402
  });
6153
6403
  if (duplicates.length > 0) throw new Error(`Duplicate block layout design profiles: ${duplicates.join(", ")}`);
6154
6404
  }
6155
- const defaultThemeTokens = {
6156
- color: {
6157
- "background/base": "#ffffff",
6158
- "background/elevated": "#f5f5f5",
6159
- "surface/base": "#ffffff",
6160
- "surface/subtle": "#f9f9fb",
6161
- "surface/inverted": "#111111",
6162
- "content/primary": "#111111",
6163
- "content/secondary": "#3f3f46",
6164
- "accent/primary": "#2563eb",
6165
- "accent/secondary": "#1d4ed8",
6166
- "border/base": "#e5e7eb"
6167
- },
6168
- typography: {
6169
- "display/hero": {
6170
- fontSize: "clamp(48px, 8vw, 96px)",
6171
- lineHeight: "1.05",
6172
- fontWeight: "700"
6173
- },
6174
- "display/section": {
6175
- fontSize: "clamp(40px, 6vw, 72px)",
6176
- lineHeight: "1.1",
6177
- fontWeight: "700"
6178
- },
6179
- "heading/large": {
6180
- fontSize: "clamp(32px, 4vw, 48px)",
6181
- lineHeight: "1.2",
6182
- fontWeight: "600"
6183
- },
6184
- "heading/medium": {
6185
- fontSize: "clamp(24px, 3vw, 32px)",
6186
- lineHeight: "1.25",
6187
- fontWeight: "600"
6188
- },
6189
- "heading/small": {
6190
- fontSize: "20px",
6191
- lineHeight: "1.3",
6192
- fontWeight: "600"
6193
- },
6194
- "body/normal": {
6195
- fontSize: "16px",
6196
- lineHeight: "1.6",
6197
- fontWeight: "400"
6198
- },
6199
- "body/small": {
6200
- fontSize: "14px",
6201
- lineHeight: "1.5",
6202
- fontWeight: "400"
6203
- },
6204
- caption: {
6205
- fontSize: "12px",
6206
- lineHeight: "1.4",
6207
- fontWeight: "500"
6208
- }
6209
- },
6210
- spacing: {
6211
- none: "0px",
6212
- "3xs": "4px",
6213
- "2xs": "8px",
6214
- xs: "12px",
6215
- sm: "16px",
6216
- md: "24px",
6217
- lg: "32px",
6218
- xl: "40px",
6219
- "2xl": "56px",
6220
- "3xl": "72px"
6221
- },
6222
- radius: {
6223
- none: "0px",
6224
- xs: "2px",
6225
- sm: "4px",
6226
- md: "8px",
6227
- lg: "12px",
6228
- pill: "999px",
6229
- full: "9999px"
6230
- },
6231
- shadow: {
6232
- none: "none",
6233
- soft: "0px 2px 8px rgba(15, 23, 42, 0.08)",
6234
- medium: "0px 6px 18px rgba(15, 23, 42, 0.12)",
6235
- strong: "0px 12px 36px rgba(15, 23, 42, 0.16)"
6236
- },
6237
- palette: {
6238
- surface: "#ffffff",
6239
- "neutral-50": "#f9fafb",
6240
- "neutral-900": "#111827",
6241
- primary: "#2563eb",
6242
- "primary-50": "#eff6ff",
6243
- "primary-500": "#2563eb",
6244
- "primary-900": "#1d4ed8",
6245
- secondary: "#9333ea",
6246
- "secondary-50": "#f3e8ff",
6247
- "secondary-500": "#9333ea",
6248
- "secondary-900": "#4c1d95",
6249
- accent: "#f97316",
6250
- "accent-50": "#fff7ed",
6251
- "accent-500": "#f97316",
6252
- "accent-900": "#7c2d12"
6253
- }
6254
- };
6255
- /**
6256
- * Project the expanded semantic palette into the token buckets consumed by
6257
- * runtime transforms. Keep this mapping shared by full themes and the
6258
- * tokens-only hosted-booking runtime so the two paths cannot drift.
6259
- */
6260
- function buildThemeTokens(palette) {
6261
- const tokens = cloneThemeTokens(defaultThemeTokens);
6262
- const paletteStrings = {};
6263
- for (const [key, value] of Object.entries(palette)) if (typeof value === "string" && value.trim().length > 0) paletteStrings[key] = value;
6264
- tokens.palette = paletteStrings;
6265
- const resolveColor = (...keys) => {
6266
- for (const key of keys) {
6267
- const value = paletteStrings[key];
6268
- if (value) return value;
6269
- }
6270
- };
6271
- const assignColor = (token, ...keys) => {
6272
- const value = resolveColor(...keys);
6273
- if (value) tokens.color[token] = value;
6274
- };
6275
- assignColor("background/base", "background", "surface", "primary-50");
6276
- assignColor("background/elevated", "surface", "background");
6277
- assignColor("surface/base", "surface", "background");
6278
- assignColor("surface/subtle", "neutral-100", "surface", "background");
6279
- assignColor("surface/inverted", "neutral-900", "text", "primary-900");
6280
- assignColor("content/primary", "text", "body", "neutral-900");
6281
- assignColor("content/secondary", "mutedText", "secondary", "neutral-600");
6282
- assignColor("accent/primary", "primary", "accent");
6283
- assignColor("accent/secondary", "accent", "secondary", "primary-400");
6284
- assignColor("border/base", "border", "neutral-300");
6285
- return tokens;
6286
- }
6287
- function cloneThemeTokens(source) {
6288
- return JSON.parse(JSON.stringify(source));
6289
- }
6290
- //#endregion
6291
- //#region ../theme-core/src/tokens/resolver.ts
6292
- /**
6293
- * Resolves theme tokens to CSS variables
6294
- *
6295
- * This resolver ensures all button styles use theme tokens (not hardcoded colors)
6296
- * so that changing the palette automatically updates all buttons.
6297
- */
6298
- var TokenResolver = class {
6299
- constructor(theme) {
6300
- this.theme = theme;
6301
- }
6302
- /**
6303
- * Resolve a color token to a CSS variable reference wrapped in rgb()
6304
- *
6305
- * @param token - Token name (e.g., 'primary-500', 'white', 'text-900')
6306
- * @returns CSS rgb() function with var reference (e.g., 'rgb(var(--tb-primary-500))')
6307
- *
6308
- * Note: CSS variables are stored as RGB channels (e.g., "37 99 235") following Tailwind convention,
6309
- * so we must wrap them with rgb() to create a valid color value.
6310
- *
6311
- * @example
6312
- * resolver.getColor('primary-500') // => 'rgb(var(--tb-primary-500))'
6313
- * resolver.getColor('white') // => 'rgb(var(--tb-white))'
6314
- */
6315
- getColor(token) {
6316
- if (!this.tokenExists(token)) console.warn(`[TokenResolver] Color token "${token}" not found in theme palette. Button may render incorrectly.`);
6317
- return `rgb(var(--tb-${token}))`;
6318
- }
6319
- /**
6320
- * Adjust a color token's shade by a given amount
6321
- *
6322
- * @param token - Base token (e.g., 'primary-500')
6323
- * @param amount - Shade adjustment (+100 = darker, -100 = lighter)
6324
- * @returns Adjusted token name (e.g., 'primary-600')
6325
- *
6326
- * @example
6327
- * resolver.adjustShade('primary-500', 100) // => 'primary-600' (darker)
6328
- * resolver.adjustShade('primary-500', -100) // => 'primary-400' (lighter)
6329
- */
6330
- adjustShade(token, amount) {
6331
- const parts = token.split("-");
6332
- if (parts.length < 2) return `${token}-${Math.max(100, Math.min(900, 500 + amount))}`;
6333
- const base = parts.slice(0, -1).join("-");
6334
- const shade = parseInt(parts[parts.length - 1] ?? "", 10);
6335
- if (isNaN(shade)) {
6336
- console.warn(`[TokenResolver] Cannot adjust shade for non-shade token "${token}". Returning original token.`);
6337
- return token;
6338
- }
6339
- return `${base}-${Math.max(100, Math.min(900, shade + amount))}`;
6340
- }
6341
- /**
6342
- * Check if a token exists in the theme palette
6343
- *
6344
- * @param token - Token name to check
6345
- * @returns True if token exists in theme
6346
- */
6347
- tokenExists(token) {
6348
- if ([
6349
- "white",
6350
- "black",
6351
- "transparent"
6352
- ].includes(token)) return true;
6353
- const parts = token.split("-");
6354
- if (parts.length >= 2) {
6355
- const lastPart = parts[parts.length - 1] ?? "";
6356
- const shade = parseInt(lastPart, 10);
6357
- if (!isNaN(shade) && shade >= 100 && shade <= 900 && shade % 100 === 0) return true;
6358
- }
6359
- return true;
6360
- }
6361
- };
6362
6405
  //#endregion
6363
6406
  //#region ../theme-core/src/site-styles/backgroundAppearance.ts
6364
6407
  const backgroundAppearanceQuickColorTokenNames = [
@@ -7144,14 +7187,12 @@ function generateVariantCSS(variant, themeId, cardClasses, tokens, theme) {
7144
7187
  const shadowValue = generateShadowValue$1(shadow);
7145
7188
  rules.push(`box-shadow: ${shadowValue}`);
7146
7189
  }
7147
- rules.push(`display: flex`);
7148
- rules.push(`flex-direction: column`);
7149
- rules.push(`position: relative`);
7150
- rules.push(`overflow: visible`);
7190
+ const structureSelector = cardClasses.map((cardClass) => `:where([data-theme-scope="${themeId}"]) :where(.${cardClass})`).join(",\n");
7151
7191
  const mediaRadius = MEDIA_CORNER_MAP[corners];
7152
7192
  const mediaRules = [`border-top-left-radius: ${mediaRadius}`, `border-top-right-radius: ${mediaRadius}`];
7153
7193
  const contentRules = [`padding: ${resolveContentPadding(variant)}`];
7154
7194
  return [
7195
+ `${structureSelector} {\n display: flex;\n flex-direction: column;\n position: relative;\n overflow: visible;\n}`,
7155
7196
  `${containerSelector} {\n ${rules.join(";\n ")};\n}`,
7156
7197
  ...cardDecorationPseudoRules(containerSelectors, variant.decorations, resolveColor),
7157
7198
  `${fallbackBackgroundSelector} {\n background: transparent;\n}`,
@@ -11980,8 +12021,14 @@ const headerInteractionPillPaletteValues = [
11980
12021
  "accent"
11981
12022
  ];
11982
12023
  /**
11983
- * "No pill": the nav link keeps whatever hover treatment its recipe compiled,
11984
- * and the palette step writes nothing at all (#1318 Phase 4c decision 2).
12024
+ * "No pill": a colour change on hover rather than a filled background.
12025
+ *
12026
+ * The palette step writes nothing (#1318 Phase 4c decision 2), but on a
12027
+ * foreground-adaptive style that is not the end of the story: the hover colour
12028
+ * is derived from the resolved opening foreground at render time, paired with
12029
+ * the resting colour, so `quiet` resolves to a definite colour rather than to
12030
+ * whatever brand token the recipe happened to name. See
12031
+ * `applyOpeningForeground`.
11985
12032
  *
11986
12033
  * It exists because "a colour change on hover, no filled background" was not
11987
12034
  * expressible in the vocabulary, and it is what
@@ -13176,7 +13223,7 @@ const BUTTON_CONTRAST_POLICY = {
13176
13223
  nonTextMinimumRatio: 3,
13177
13224
  gradientSamplesPerSegment: 20,
13178
13225
  alphaBackgrounds: "reject-without-known-surface",
13179
- disabled: "retain-full-colour-contract"
13226
+ disabled: "validated-colour-pair-with-muted-control-opacity"
13180
13227
  };
13181
13228
  function formatButtonColourContractError(error) {
13182
13229
  switch (error.tag) {
@@ -13764,6 +13811,25 @@ function parseThemeForPersistence(value) {
13764
13811
  };
13765
13812
  }
13766
13813
  //#endregion
13814
+ //#region ../theme-core/src/buttons/affordanceSuppression.ts
13815
+ /**
13816
+ * Internal: the opt-out the generated affordance rule is written against.
13817
+ *
13818
+ * A button style may declare a trailing `affordance`, which the theme renders as
13819
+ * a CSS `::after` on every button of that variant. An authored button that
13820
+ * renders its own trailing icon must not also receive the theme's, or it shows
13821
+ * two.
13822
+ *
13823
+ * Deliberately not exported from `./index`. This used to be public, and two
13824
+ * block components reached past the theme to draw arrows of their own — one of
13825
+ * them doubling up on the styles that declare an affordance, both of them
13826
+ * overriding the twelve styles that deliberately declare none. Whether a button
13827
+ * carries a trailing affordance is the style's decision; the only caller that
13828
+ * legitimately opts out is the authored-button renderer, which reaches it
13829
+ * through `themeButtonClassNameWithTrailingIcon`.
13830
+ */
13831
+ const AFFORDANCE_SUPPRESS_CLASS = "rb-affordance-off";
13832
+ //#endregion
13767
13833
  //#region ../theme-core/src/buttons/classNames.ts
13768
13834
  /**
13769
13835
  * Parse content/runtime variant identifiers into the closed theme-button class
@@ -13796,6 +13862,27 @@ function themeButtonClassName(spec) {
13796
13862
  spec.extraClassName
13797
13863
  ].filter(Boolean).join(" ");
13798
13864
  }
13865
+ /**
13866
+ * Button classes for an authored button that renders its own trailing icon.
13867
+ *
13868
+ * A separate function rather than a flag on `themeButtonClassName`, because
13869
+ * there is exactly one caller and it should stay visible in a diff. The name
13870
+ * states what the caller knows to be true of its own markup — that it renders a
13871
+ * trailing icon — rather than what the theme does about it. The consequence is
13872
+ * the theme's to decide and to change; a caller naming the consequence would be
13873
+ * asserting a policy it does not own, and would quietly become a lie the moment
13874
+ * that policy moved.
13875
+ *
13876
+ * Do not reach for this to remove an arrow you simply do not want. A trailing
13877
+ * affordance is declared by the button style, and a block overriding that is the
13878
+ * defect this replaced.
13879
+ */
13880
+ function themeButtonClassNameWithTrailingIcon(spec) {
13881
+ return themeButtonClassName({
13882
+ ...spec,
13883
+ extraClassName: [spec.extraClassName, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ")
13884
+ });
13885
+ }
13799
13886
  //#endregion
13800
13887
  //#region ../theme-core/src/interactive/generateBaseCSS.ts
13801
13888
  /**
@@ -15708,26 +15795,19 @@ function resolvedButtonFocusDeclarations(indicator, role) {
15708
15795
  ] : [["outline", value("outline", `3px solid ${indicator.colorCss}`)], ["outline-offset", value("outline-offset", "3px")]];
15709
15796
  }
15710
15797
  /**
15711
- * Disabled buttons retain their validated colour pair and add a non-layout
15712
- * visual affordance. `currentColor` keeps the cue inside the same contrast
15713
- * relationship, while retaining pointer events lets the not-allowed cursor
15714
- * remain observable.
15798
+ * Disabled buttons are deliberately muted as unavailable controls. Native
15799
+ * disabled controls are exempt from active-control contrast requirements;
15800
+ * opacity distinguishes the state without introducing a focus-like outline.
15801
+ * Retaining pointer events lets the not-allowed cursor remain observable.
15715
15802
  */
15716
15803
  const RESOLVED_BUTTON_DISABLED_DECLARATIONS = [
15717
15804
  ["cursor", "not-allowed"],
15718
15805
  ["transform", "none"],
15719
15806
  ["box-shadow", "none"],
15720
- ["outline", "2px dashed currentColor"],
15721
- ["outline-offset", "-4px"]
15807
+ ["opacity", "0.55"]
15722
15808
  ];
15723
15809
  //#endregion
15724
15810
  //#region ../theme-core/src/buttons/generateButtonCss.ts
15725
- /**
15726
- * Class the `button` runtime node adds when it renders its own trailing icon,
15727
- * so a node-level icon suppresses the theme's CSS `::after` affordance.
15728
- * Shared so generator and renderer can't drift.
15729
- */
15730
- const AFFORDANCE_SUPPRESS_CLASS = "rb-affordance-off";
15731
15811
  const BUTTON_SIZE_NAMES = buttonSizeNameSchema.options;
15732
15812
  /**
15733
15813
  * Letter spacing token → CSS value.
@@ -27772,6 +27852,28 @@ const bookingRequirementConsentFieldSchema = z$1.object({
27772
27852
  const bookingConsentCarrierSchema = z$1.union([blockBookingConsentSchema, bookingRequirementConsentFieldSchema]);
27773
27853
  //#endregion
27774
27854
  //#region ../blocks/src/system/blocks/events/shared/schemas.ts
27855
+ const publicEventLoaderQuerySchemaShape = {
27856
+ limit: z$1.string().optional(),
27857
+ from: z$1.string().optional(),
27858
+ to: z$1.string().optional(),
27859
+ afterStartsAt: z$1.string().optional(),
27860
+ afterId: z$1.string().optional(),
27861
+ categoryIds: z$1.string().optional(),
27862
+ venueId: z$1.string().optional(),
27863
+ staffMemberId: z$1.string().optional(),
27864
+ eventSurface: z$1.string().optional(),
27865
+ eventPresets: z$1.string().optional(),
27866
+ scheduleScope: z$1.string().optional(),
27867
+ seriesId: z$1.string().optional(),
27868
+ seriesIds: z$1.string().optional(),
27869
+ runSeriesId: z$1.string().optional(),
27870
+ seriesSlug: z$1.string().optional(),
27871
+ includeOccurrenceId: z$1.string().optional(),
27872
+ readIntent: z$1.string().optional(),
27873
+ detailLevel: z$1.string().optional(),
27874
+ readProfile: z$1.string().optional()
27875
+ };
27876
+ z$1.object(publicEventLoaderQuerySchemaShape);
27775
27877
  const eventPresetSchema = z$1.enum([
27776
27878
  "event",
27777
27879
  "class",
@@ -28138,6 +28240,7 @@ const calendarWindowQuerySchema = z$1.object({
28138
28240
  eventSurface: z$1.enum(eventSurfaceScopeValues).optional(),
28139
28241
  eventPresets: z$1.string().optional(),
28140
28242
  scheduleScope: z$1.enum(eventScheduleScopeValues).optional(),
28243
+ seriesIds: z$1.string().optional(),
28141
28244
  categoryIds: z$1.string().optional(),
28142
28245
  venueId: z$1.string().transform(normalizeCalendarFilterId).optional(),
28143
28246
  staffMemberId: z$1.string().transform(normalizeCalendarFilterId).optional()
@@ -28188,7 +28291,56 @@ const calendarWindowPageSchema = z$1.discriminatedUnion("kind", [z$1.object({
28188
28291
  kind: z$1.literal("partial"),
28189
28292
  nextCursor: calendarSourceCursorSchema
28190
28293
  })]);
28294
+ //#endregion
28295
+ //#region ../blocks/src/system/blocks/events/shared/eventSelection.ts
28296
+ /** Invalid saved selections fail closed rather than widening discovery. */
28297
+ function resolveEventSelection(mode, value) {
28298
+ if (mode !== "selected") return { kind: "matching" };
28299
+ const candidates = Array.isArray(value) ? value : typeof value === "string" ? value.split(",").filter(Boolean) : [];
28300
+ const ids = [];
28301
+ for (const candidate of candidates) {
28302
+ if (typeof candidate !== "string") return {
28303
+ kind: "selected",
28304
+ seriesIds: []
28305
+ };
28306
+ const parsed = parseEventSeriesId(candidate.trim());
28307
+ if (!parsed.ok) return {
28308
+ kind: "selected",
28309
+ seriesIds: []
28310
+ };
28311
+ ids.push(parsed.value);
28312
+ }
28313
+ return {
28314
+ kind: "selected",
28315
+ seriesIds: [...new Set(ids)].sort()
28316
+ };
28317
+ }
28318
+ /** Undefined means discovery; an empty string is an explicitly empty selection. */
28319
+ function eventSeriesScopeCsv(value) {
28320
+ if (value == null) return void 0;
28321
+ return typeof value === "string" ? value : value.join(",");
28322
+ }
28191
28323
  const defaultTransforms = createTransformRegistry([
28324
+ {
28325
+ id: "events.calendarSelectionParam",
28326
+ kind: "formatter",
28327
+ summary: "Resolve selected events instead of discovery filters",
28328
+ schema: z$1.object({ key: z$1.enum([
28329
+ "seriesIds",
28330
+ "eventSurface",
28331
+ "filterEventPresets",
28332
+ "scheduleScope",
28333
+ "filterCategoryIds",
28334
+ "filterStaffMemberId",
28335
+ "filterVenueId"
28336
+ ]) }),
28337
+ run(value, { key }) {
28338
+ const content = asPartialObject(value) ?? {};
28339
+ const selection = resolveEventSelection(content.eventSelection, content.selectedEventSeriesIds);
28340
+ if (selection.kind === "selected") return key === "seriesIds" ? selection.seriesIds : void 0;
28341
+ return key === "seriesIds" ? void 0 : content[key];
28342
+ }
28343
+ },
28192
28344
  {
28193
28345
  id: "events.calendarReadEnabled",
28194
28346
  kind: "formatter",
@@ -29942,17 +30094,16 @@ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md",
29942
30094
  if (process.env.NODE_ENV === "development") console.warn("[ButtonNode] Missing href for link-required button");
29943
30095
  return null;
29944
30096
  }
29945
- const extraClassName = affordanceIcon ? [className, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ") : className;
29946
30097
  const resolvedVariantId = parseThemeButtonVariantId(variantId);
29947
30098
  if (variantId && !resolvedVariantId) {
29948
30099
  console.error("[ButtonNode] Invalid button variant", { variantId });
29949
30100
  return null;
29950
30101
  }
29951
- const combinedClassName = resolvedVariantId ? themeButtonClassName({
30102
+ const combinedClassName = resolvedVariantId ? (affordanceIcon ? themeButtonClassNameWithTrailingIcon : themeButtonClassName)({
29952
30103
  variant: resolvedVariantId,
29953
30104
  size,
29954
- extraClassName
29955
- }) : extraClassName;
30105
+ extraClassName: className
30106
+ }) : className;
29956
30107
  if (resolvedHref) return /* @__PURE__ */ jsxs("a", {
29957
30108
  href: resolvedHref,
29958
30109
  target,
@@ -31220,10 +31371,11 @@ const publicPricingSchema = z$1.object({
31220
31371
  singlePriceAmount: z$1.number().nullable(),
31221
31372
  slidingMinAmount: z$1.number().nullable(),
31222
31373
  slidingMaxAmount: z$1.number().nullable(),
31223
- options: z$1.array(publicPricingOptionSchema)
31374
+ options: z$1.array(publicPricingOptionSchema).readonly()
31224
31375
  });
31225
31376
  const publicAppointmentServiceSchema = z$1.object({
31226
31377
  id: z$1.string().min(1),
31378
+ slug: z$1.string().min(1).optional(),
31227
31379
  title: z$1.string(),
31228
31380
  description: z$1.string().nullable().optional(),
31229
31381
  durationMinutes: z$1.number().int().positive(),
@@ -31300,7 +31452,7 @@ function formatAmountOrFree(amount, currency) {
31300
31452
  currency
31301
31453
  }, { decimals: "auto" });
31302
31454
  }
31303
- function buildRows(services, pathname) {
31455
+ function buildRows(services, pathname, servicePathPrefix) {
31304
31456
  return services.map((service) => ({
31305
31457
  id: service.id,
31306
31458
  title: service.title,
@@ -31311,7 +31463,8 @@ function buildRows(services, pathname) {
31311
31463
  href: resolveDedicatedBookingHref(pathname, {
31312
31464
  kind: "appointment_service",
31313
31465
  serviceId: service.id
31314
- })
31466
+ }),
31467
+ detailsHref: servicePathPrefix && service.slug ? `${servicePathPrefix.replace(/\/$/, "")}/${encodeURIComponent(service.slug)}` : null
31315
31468
  }));
31316
31469
  }
31317
31470
  function buildAppointmentServicesView(input) {
@@ -31330,13 +31483,14 @@ function buildAppointmentServicesView(input) {
31330
31483
  };
31331
31484
  return {
31332
31485
  kind: "items",
31333
- rows: buildRows(parsed.services, input.pathname)
31486
+ rows: buildRows(parsed.services, input.pathname, input.servicePathPrefix ?? null)
31334
31487
  };
31335
31488
  }
31336
- function AppointmentServicesNode({ sectionHeading, services, pathname, className }) {
31489
+ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePathPrefix, className }) {
31337
31490
  const view = buildAppointmentServicesView({
31338
31491
  services,
31339
- pathname: typeof pathname === "string" ? pathname : void 0
31492
+ pathname: typeof pathname === "string" ? pathname : void 0,
31493
+ servicePathPrefix: typeof servicePathPrefix === "string" ? servicePathPrefix : null
31340
31494
  });
31341
31495
  const rootClassName = `appointment-services ${className ?? ""}`.trim();
31342
31496
  const RowTitle = sectionHeading ? "h3" : "h2";
@@ -31367,7 +31521,10 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, className
31367
31521
  children: [
31368
31522
  /* @__PURE__ */ jsx(RowTitle, {
31369
31523
  className: "appointment-services-row-title rb-text-lg rb-font-medium rb-leading-tight",
31370
- children: row.title
31524
+ children: row.detailsHref ? /* @__PURE__ */ jsx("a", {
31525
+ href: row.detailsHref,
31526
+ children: row.title
31527
+ }) : row.title
31371
31528
  }),
31372
31529
  row.description ? /* @__PURE__ */ jsx("p", {
31373
31530
  className: "appointment-services-row-description rb-text-sm rb-leading-6 status-muted",
@@ -33874,12 +34031,12 @@ const EventCompactRow = ({ event, buttonVariant = "primary", buttonText }) => {
33874
34031
  }), cta.hidden ? /* @__PURE__ */ jsx("span", {
33875
34032
  className: "event-compact-row-status",
33876
34033
  children: cta.label
33877
- }) : /* @__PURE__ */ jsxs("a", {
34034
+ }) : /* @__PURE__ */ jsx("a", {
33878
34035
  href: cta.href,
33879
34036
  target: cta.external ? "_blank" : void 0,
33880
34037
  rel: cta.external ? "noopener noreferrer" : void 0,
33881
34038
  className: `${buttonClass} event-compact-row-cta`,
33882
- children: [/* @__PURE__ */ jsx("span", { children: cta.label }), /* @__PURE__ */ jsx(ArrowRightIcon, { "aria-hidden": "true" })]
34039
+ children: /* @__PURE__ */ jsx("span", { children: cta.label })
33883
34040
  })]
33884
34041
  })]
33885
34042
  })]
@@ -34972,6 +35129,7 @@ const eventCollectionFilterSourceSchemaShape = {
34972
35129
  eventSurface: eventSurfaceScopeSchema$1.nullable().optional(),
34973
35130
  filterEventPresets: z$1.union([z$1.string(), z$1.array(z$1.string())]).nullable().optional(),
34974
35131
  scheduleScope: eventScheduleScopeSchema$1.nullable().optional(),
35132
+ seriesIds: z$1.union([z$1.string(), z$1.array(z$1.string())]).nullable().optional(),
34975
35133
  filterCategoryIds: z$1.union([z$1.string(), z$1.array(z$1.string())]).nullable().optional(),
34976
35134
  filterStaffMemberId: z$1.string().nullable().optional(),
34977
35135
  filterVenueId: z$1.string().nullable().optional()
@@ -35018,6 +35176,7 @@ const eventCollectionDisplaySchemaShape = {
35018
35176
  eventSurface: eventSurfaceScopeSchema$1,
35019
35177
  filterEventPresets: z$1.string().nullable(),
35020
35178
  scheduleScope: eventScheduleScopeSchema$1,
35179
+ seriesIds: z$1.string().nullable().optional(),
35021
35180
  filterCategoryIds: z$1.string().nullable(),
35022
35181
  filterStaffMemberId: z$1.string().nullable(),
35023
35182
  filterVenueId: z$1.string().nullable(),
@@ -35065,11 +35224,15 @@ function buildEventCollectionDisplay(source) {
35065
35224
  };
35066
35225
  }
35067
35226
  function buildEventCollectionFilterDisplay(source) {
35068
- return {
35069
- showFilters: source.showFilters ?? true,
35070
- showCategoryFilter: source.showCategoryFilter ?? "auto",
35071
- showVenueFilter: source.showVenueFilter ?? false,
35072
- showStaffFilter: source.showStaffFilter ?? true,
35227
+ const selected = source.seriesIds != null;
35228
+ const matchingFilters = selected ? {
35229
+ eventSurface: "all",
35230
+ filterEventPresets: null,
35231
+ scheduleScope: "any",
35232
+ filterCategoryIds: null,
35233
+ filterStaffMemberId: null,
35234
+ filterVenueId: null
35235
+ } : {
35073
35236
  eventSurface: normalizeEventSurfaceScope(source.eventSurface),
35074
35237
  filterEventPresets: normalizeEventSurfacePresetsCsv(source.filterEventPresets),
35075
35238
  scheduleScope: normalizeEventScheduleScope(source.scheduleScope),
@@ -35077,6 +35240,14 @@ function buildEventCollectionFilterDisplay(source) {
35077
35240
  filterStaffMemberId: normalizeEventStaffMemberId(source.filterStaffMemberId),
35078
35241
  filterVenueId: normalizeEventVenueId(source.filterVenueId)
35079
35242
  };
35243
+ return {
35244
+ seriesIds: eventSeriesScopeCsv(source.seriesIds),
35245
+ showFilters: selected ? false : source.showFilters ?? true,
35246
+ showCategoryFilter: source.showCategoryFilter ?? "auto",
35247
+ showVenueFilter: source.showVenueFilter ?? false,
35248
+ showStaffFilter: source.showStaffFilter ?? true,
35249
+ ...matchingFilters
35250
+ };
35080
35251
  }
35081
35252
  function buildEventCollectionPresentationDisplay(source) {
35082
35253
  return {
@@ -35091,14 +35262,15 @@ function buildEventCollectionPresentationDisplay(source) {
35091
35262
  }
35092
35263
  function buildEventCollectionHydration(source, now = /* @__PURE__ */ new Date()) {
35093
35264
  const timeZone = source.calendarWindow?.scope.timeZone ?? toBookingTimeZone(source.bookingTimeZone);
35265
+ const selected = source.seriesIds != null;
35094
35266
  return {
35095
35267
  calendarWindow: source.calendarWindow ?? void 0,
35096
35268
  siteId: source.siteId,
35097
35269
  stage: source.stage,
35098
35270
  prefetchedEvents: source.events != null,
35099
- eventSurface: normalizeEventSurfaceScope(source.eventSurface),
35100
- filterEventPresets: normalizeEventSurfacePresetsCsv(source.filterEventPresets),
35101
- scheduleScope: normalizeEventScheduleScope(source.scheduleScope),
35271
+ eventSurface: selected ? "all" : normalizeEventSurfaceScope(source.eventSurface),
35272
+ filterEventPresets: selected ? null : normalizeEventSurfacePresetsCsv(source.filterEventPresets),
35273
+ scheduleScope: selected ? "any" : normalizeEventScheduleScope(source.scheduleScope),
35102
35274
  calendarContext: {
35103
35275
  timeZone,
35104
35276
  initialToday: source.calendarWindow?.initialToday ?? getLocalScheduleDate(now, timeZone)
@@ -35668,13 +35840,10 @@ function OfferingsPreviewContent(props) {
35668
35840
  }),
35669
35841
  groupCta ? /* @__PURE__ */ jsx("footer", {
35670
35842
  className: "offerings-preview-card-footer rb-mt-auto rb-flex",
35671
- children: /* @__PURE__ */ jsxs("a", {
35843
+ children: /* @__PURE__ */ jsx("a", {
35672
35844
  className: groupLinkClass,
35673
35845
  href: groupCta.href,
35674
- children: [/* @__PURE__ */ jsx("span", { children: groupCta.label }), /* @__PURE__ */ jsx(ArrowRightIcon, {
35675
- "aria-hidden": "true",
35676
- className: "offerings-preview-link-icon rb-h-4 rb-w-4"
35677
- })]
35846
+ children: /* @__PURE__ */ jsx("span", { children: groupCta.label })
35678
35847
  })
35679
35848
  }) : null
35680
35849
  ]
@@ -37879,6 +38048,44 @@ function toWholeSeriesRegistrationEvents(events) {
37879
38048
  return groupPublicEventsByRun(events).map(toWholeSeriesRegistrationEvent).filter((event) => event !== null);
37880
38049
  }
37881
38050
  //#endregion
38051
+ //#region ../blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.ts
38052
+ const { limit: _rawLimit, eventSurface: _rawEventSurface, scheduleScope: _rawScheduleScope, detailLevel: _rawDetailLevel, ...stringEventQueryShape } = publicEventLoaderQuerySchemaShape;
38053
+ const eventRecoveryRequestSchema = z$1.object({
38054
+ ...stringEventQueryShape,
38055
+ limit: z$1.coerce.number().int().positive().optional(),
38056
+ eventSurface: z$1.enum(eventSurfaceScopeValues).optional(),
38057
+ scheduleScope: z$1.enum(eventScheduleScopeValues).optional(),
38058
+ detailLevel: z$1.enum(["full", "listing"]).optional(),
38059
+ stage: z$1.enum(["preview", "published"]).optional()
38060
+ });
38061
+ function resolveEventRegistrationEventSource(input) {
38062
+ if (input.wholeSeriesRunEvents != null) return {
38063
+ kind: "loaded",
38064
+ events: input.wholeSeriesRunEvents
38065
+ };
38066
+ if (input.events != null) return {
38067
+ kind: "loaded",
38068
+ events: input.events
38069
+ };
38070
+ return {
38071
+ kind: "unresolved",
38072
+ request: parseEventLoaderRecoveryRequest(input.failures?.wholeSeriesRunEvents ?? input.failures?.events)
38073
+ };
38074
+ }
38075
+ const eventLoaderFailureSchema = z$1.object({
38076
+ endpoint: z$1.literal("listPublicEvents"),
38077
+ params: eventRecoveryRequestSchema.extend({ siteId: z$1.string().optional() })
38078
+ });
38079
+ function parseEventLoaderRecoveryRequest(value) {
38080
+ const parsed = eventLoaderFailureSchema.safeParse(value);
38081
+ if (!parsed.success) return null;
38082
+ const { siteId: _siteId, stage, ...params } = parsed.data.params;
38083
+ return {
38084
+ ...params,
38085
+ stage: stage ?? "published"
38086
+ };
38087
+ }
38088
+ //#endregion
37882
38089
  //#region ../blocks/src/system/runtime/nodes/event-registration.interactive.ts
37883
38090
  const EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS = [
37884
38091
  "Date",
@@ -37896,8 +38103,6 @@ const eventRegistrationPublicEventSchema = z$1.preprocess(normalizeEventRegistra
37896
38103
  const eventRegistrationHydrationSchemaShape = {
37897
38104
  occurrenceContext: occurrenceContextSchema.optional(),
37898
38105
  subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
37899
- events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
37900
- wholeSeriesRunEvents: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
37901
38106
  maxTickets: z$1.string().optional(),
37902
38107
  showVenue: z$1.boolean().optional(),
37903
38108
  showCapacity: z$1.boolean().optional(),
@@ -37909,12 +38114,22 @@ const eventRegistrationHydrationSchemaShape = {
37909
38114
  sitePasses: publicPassProductCollectionSchema.nullable().optional(),
37910
38115
  siteMemberships: publicMembershipProductCollectionSchema.nullable().optional()
37911
38116
  };
38117
+ const eventRegistrationEventSourceSchema = z$1.discriminatedUnion("kind", [z$1.object({
38118
+ kind: z$1.literal("loaded"),
38119
+ events: z$1.array(eventRegistrationPublicEventSchema)
38120
+ }), z$1.object({
38121
+ kind: z$1.literal("unresolved"),
38122
+ request: eventRecoveryRequestSchema.nullable()
38123
+ })]);
37912
38124
  const eventRegistrationSourceSchema = z$1.object({
37913
38125
  siteId: z$1.string().optional(),
37914
38126
  apiBaseUrl: z$1.string().optional(),
37915
38127
  portalToken: z$1.string().nullable().optional(),
37916
38128
  previewToken: z$1.string().nullable().optional(),
37917
38129
  ...eventRegistrationHydrationSchemaShape,
38130
+ events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
38131
+ wholeSeriesRunEvents: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
38132
+ eventLoaderFailures: z$1.record(z$1.string(), z$1.unknown()).nullable().optional(),
37918
38133
  className: z$1.string().nullable().optional(),
37919
38134
  buttonText: z$1.string().nullable().optional(),
37920
38135
  maxTickets: z$1.string().nullable().optional(),
@@ -37935,7 +38150,10 @@ const eventRegistrationDisplaySchema = z$1.discriminatedUnion("state", [z$1.obje
37935
38150
  titleText: z$1.string(),
37936
38151
  bodyText: z$1.string()
37937
38152
  })]);
37938
- const eventRegistrationHydrationSchema = z$1.object(eventRegistrationHydrationSchemaShape);
38153
+ const eventRegistrationHydrationSchema = z$1.object({
38154
+ ...eventRegistrationHydrationSchemaShape,
38155
+ eventSource: eventRegistrationEventSourceSchema
38156
+ });
37939
38157
  const eventRegistrationRenderSchema = z$1.object({
37940
38158
  display: eventRegistrationDisplaySchema,
37941
38159
  hydration: eventRegistrationHydrationSchema
@@ -37994,16 +38212,12 @@ function buildEventRegistrationShellStepLabels(source, scopedSourceEvents) {
37994
38212
  function toScopedEventRegistrationEvents(scopedSourceEvents) {
37995
38213
  return [...toRegistrationEvents(scopedSourceEvents), ...toWholeSeriesRegistrationEvents(scopedSourceEvents)];
37996
38214
  }
37997
- function scopeEventRegistrationSourceEvents(source) {
37998
- return resolveEventRegistrationScopedEvents(source.wholeSeriesRunEvents ?? source.events ?? [], {
38215
+ function scopeEventRegistrationSourceEvents(source, eventSource) {
38216
+ return resolveEventRegistrationScopedEvents(eventSource.kind === "loaded" ? eventSource.events : [], {
37999
38217
  occurrenceContext: source.occurrenceContext,
38000
38218
  subject: source.subject
38001
38219
  });
38002
38220
  }
38003
- function resolveLoadedEventRegistrationSourceEvents(source, scopedSourceEvents) {
38004
- if (source.events == null && source.wholeSeriesRunEvents == null) return null;
38005
- return [...scopedSourceEvents];
38006
- }
38007
38221
  /**
38008
38222
  * The one run this surface is registering for, when the scoped events describe
38009
38223
  * exactly one. More than one run means the visitor still has to choose.
@@ -38043,14 +38257,21 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
38043
38257
  render: createZodCodec(eventRegistrationRenderSchema)
38044
38258
  },
38045
38259
  buildRender: (source) => {
38046
- const scopedSourceEvents = scopeEventRegistrationSourceEvents(source);
38047
- const events = resolveLoadedEventRegistrationSourceEvents(source, scopedSourceEvents);
38260
+ const eventSource = resolveEventRegistrationEventSource({
38261
+ events: source.events,
38262
+ wholeSeriesRunEvents: source.wholeSeriesRunEvents,
38263
+ failures: source.eventLoaderFailures
38264
+ });
38265
+ const scopedSourceEvents = scopeEventRegistrationSourceEvents(source, eventSource);
38048
38266
  return {
38049
38267
  display: buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents),
38050
38268
  hydration: {
38051
38269
  occurrenceContext: source.occurrenceContext ?? null,
38052
38270
  subject: source.subject ?? null,
38053
- events,
38271
+ eventSource: eventSource.kind === "loaded" ? {
38272
+ ...eventSource,
38273
+ events: [...scopedSourceEvents]
38274
+ } : eventSource,
38054
38275
  maxTickets: source.maxTickets ?? void 0,
38055
38276
  showVenue: source.showVenue,
38056
38277
  showCapacity: source.showCapacity,
@@ -38240,6 +38461,7 @@ const eventRegistrationBlockDefinition = {
38240
38461
  } },
38241
38462
  events: { $bind: { from: "data.events" } },
38242
38463
  wholeSeriesRunEvents: { $bind: { from: "data.wholeSeriesRunEvents" } },
38464
+ loaderFailures: { $bind: { from: "$root.loaderFailures" } },
38243
38465
  sitePasses: { $bind: { from: "data.sitePasses" } },
38244
38466
  siteMemberships: { $bind: { from: "data.siteMemberships" } },
38245
38467
  stage: { $bind: {
@@ -38566,6 +38788,65 @@ const formBlockDefinition = {
38566
38788
  runtime: formBlockRuntime
38567
38789
  };
38568
38790
  //#endregion
38791
+ //#region ../blocks/src/system/blocks/events/eventSelectionFields.ts
38792
+ const eventSelectionFields = [{
38793
+ id: "eventSelection",
38794
+ type: "select",
38795
+ label: "Events to show",
38796
+ required: false,
38797
+ multiple: false,
38798
+ defaultValue: "matching",
38799
+ options: [{
38800
+ value: "matching",
38801
+ label: "All matching events"
38802
+ }, {
38803
+ value: "selected",
38804
+ label: "Selected events"
38805
+ }],
38806
+ ui: { intent: "behavior" }
38807
+ }, createSiteOptionSelectField({
38808
+ id: "selectedEventSeriesIds",
38809
+ label: "Selected events",
38810
+ description: "Show upcoming dates for these events. Other event filters do not apply.",
38811
+ required: false,
38812
+ multiple: true,
38813
+ defaultValue: [],
38814
+ optionSource: "eventSeries",
38815
+ ui: {
38816
+ intent: "behavior",
38817
+ searchThreshold: 1,
38818
+ visibleWhen: {
38819
+ field: "eventSelection",
38820
+ equals: "selected"
38821
+ }
38822
+ }
38823
+ })];
38824
+ function withEventSelectionVisibility(field) {
38825
+ if (![
38826
+ "eventSurface",
38827
+ "filterEventPresets",
38828
+ "scheduleScope",
38829
+ "filterCategoryIds",
38830
+ "filterStaffMemberId",
38831
+ "filterVenueId",
38832
+ "showFilters",
38833
+ "showCategoryFilter",
38834
+ "showVenueFilter",
38835
+ "showStaffFilter"
38836
+ ].includes(field.id)) return field;
38837
+ const visibleWhen = field.ui?.visibleWhen;
38838
+ return {
38839
+ ...field,
38840
+ ui: {
38841
+ ...field.ui,
38842
+ visibleWhen: { allOf: [{
38843
+ field: "eventSelection",
38844
+ notEquals: "selected"
38845
+ }, ...visibleWhen ? [visibleWhen] : []] }
38846
+ }
38847
+ };
38848
+ }
38849
+ //#endregion
38569
38850
  //#region ../blocks/src/system/runtime/nodes/events/EventCalendar.interactive.ts
38570
38851
  const eventCalendarSourceSchema = z$1.object({
38571
38852
  ...eventCollectionSourceSchemaShape,
@@ -38663,19 +38944,59 @@ function buildEventCalendarInteractiveIslandProps(props) {
38663
38944
  //#region ../blocks/src/system/blocks/events/eventCalendarDataLoaders.ts
38664
38945
  const scopeParams = {
38665
38946
  siteId: { $bind: { from: "$root.siteId" } },
38947
+ seriesIds: { $bind: {
38948
+ from: "content",
38949
+ transforms: [{
38950
+ id: "events.calendarSelectionParam",
38951
+ options: { key: "seriesIds" }
38952
+ }]
38953
+ } },
38666
38954
  stage: { $bind: {
38667
38955
  from: "$root.previewStage",
38668
38956
  fallback: "published"
38669
38957
  } },
38670
- eventSurface: { $bind: { from: "content.eventSurface" } },
38958
+ eventSurface: { $bind: {
38959
+ from: "content",
38960
+ transforms: [{
38961
+ id: "events.calendarSelectionParam",
38962
+ options: { key: "eventSurface" }
38963
+ }, { id: "value.csv" }]
38964
+ } },
38671
38965
  eventPresets: { $bind: {
38672
- from: "content.filterEventPresets",
38673
- transforms: [{ id: "value.csv" }]
38966
+ from: "content",
38967
+ transforms: [{
38968
+ id: "events.calendarSelectionParam",
38969
+ options: { key: "filterEventPresets" }
38970
+ }, { id: "value.csv" }]
38971
+ } },
38972
+ scheduleScope: { $bind: {
38973
+ from: "content",
38974
+ transforms: [{
38975
+ id: "events.calendarSelectionParam",
38976
+ options: { key: "scheduleScope" }
38977
+ }, { id: "value.csv" }]
38978
+ } },
38979
+ categoryIds: { $bind: {
38980
+ from: "content",
38981
+ transforms: [{
38982
+ id: "events.calendarSelectionParam",
38983
+ options: { key: "filterCategoryIds" }
38984
+ }, { id: "value.csv" }]
38674
38985
  } },
38675
- scheduleScope: { $bind: { from: "content.scheduleScope" } },
38676
- categoryIds: { $bind: { from: "content.filterCategoryIds" } },
38677
- staffMemberId: { $bind: { from: "content.filterStaffMemberId" } },
38678
- venueId: { $bind: { from: "content.filterVenueId" } }
38986
+ staffMemberId: { $bind: {
38987
+ from: "content",
38988
+ transforms: [{
38989
+ id: "events.calendarSelectionParam",
38990
+ options: { key: "filterStaffMemberId" }
38991
+ }, { id: "value.csv" }]
38992
+ } },
38993
+ venueId: { $bind: {
38994
+ from: "content",
38995
+ transforms: [{
38996
+ id: "events.calendarSelectionParam",
38997
+ options: { key: "filterVenueId" }
38998
+ }, { id: "value.csv" }]
38999
+ } }
38679
39000
  };
38680
39001
  /** Combined renders two jobs; calendar-only variants never pay for the list seed. */
38681
39002
  const eventCalendarDataLoaders = {
@@ -38805,6 +39126,13 @@ const eventCalendarLayout = [styledSection({
38805
39126
  from: "content.defaultCalendarView",
38806
39127
  fallback: "month"
38807
39128
  } },
39129
+ seriesIds: { $bind: {
39130
+ from: "content",
39131
+ transforms: [{
39132
+ id: "events.calendarSelectionParam",
39133
+ options: { key: "seriesIds" }
39134
+ }]
39135
+ } },
38808
39136
  showFilters: { $bind: {
38809
39137
  from: "content.showFilters",
38810
39138
  fallback: true
@@ -38826,17 +39154,47 @@ const eventCalendarLayout = [styledSection({
38826
39154
  fallback: true
38827
39155
  } },
38828
39156
  eventSurface: { $bind: {
38829
- from: "content.eventSurface",
38830
- fallback: "all"
39157
+ from: "content",
39158
+ transforms: [{
39159
+ id: "events.calendarSelectionParam",
39160
+ options: { key: "eventSurface" }
39161
+ }]
39162
+ } },
39163
+ filterEventPresets: { $bind: {
39164
+ from: "content",
39165
+ transforms: [{
39166
+ id: "events.calendarSelectionParam",
39167
+ options: { key: "filterEventPresets" }
39168
+ }]
38831
39169
  } },
38832
- filterEventPresets: { $bind: { from: "content.filterEventPresets" } },
38833
39170
  scheduleScope: { $bind: {
38834
- from: "content.scheduleScope",
38835
- fallback: "any"
39171
+ from: "content",
39172
+ transforms: [{
39173
+ id: "events.calendarSelectionParam",
39174
+ options: { key: "scheduleScope" }
39175
+ }]
39176
+ } },
39177
+ filterCategoryIds: { $bind: {
39178
+ from: "content",
39179
+ transforms: [{
39180
+ id: "events.calendarSelectionParam",
39181
+ options: { key: "filterCategoryIds" }
39182
+ }]
39183
+ } },
39184
+ filterStaffMemberId: { $bind: {
39185
+ from: "content",
39186
+ transforms: [{
39187
+ id: "events.calendarSelectionParam",
39188
+ options: { key: "filterStaffMemberId" }
39189
+ }]
39190
+ } },
39191
+ filterVenueId: { $bind: {
39192
+ from: "content",
39193
+ transforms: [{
39194
+ id: "events.calendarSelectionParam",
39195
+ options: { key: "filterVenueId" }
39196
+ }]
38836
39197
  } },
38837
- filterCategoryIds: { $bind: { from: "content.filterCategoryIds" } },
38838
- filterStaffMemberId: { $bind: { from: "content.filterStaffMemberId" } },
38839
- filterVenueId: { $bind: { from: "content.filterVenueId" } },
38840
39198
  cardRole: { $bind: {
38841
39199
  from: "content._cardStyles.role",
38842
39200
  fallback: "default"
@@ -39340,6 +39698,7 @@ const eventCalendarAdditionalFields = [
39340
39698
  }
39341
39699
  }
39342
39700
  },
39701
+ ...eventSelectionFields,
39343
39702
  {
39344
39703
  id: "eventSurface",
39345
39704
  type: "select",
@@ -39549,7 +39908,7 @@ const eventCalendarBlockDefinition = {
39549
39908
  titleSource: "heading",
39550
39909
  description: "Display events with calendar, list, or combined views with filtering",
39551
39910
  skipSectionStyles: true,
39552
- additionalFields: eventCalendarAdditionalFields,
39911
+ additionalFields: eventCalendarAdditionalFields.map(withEventSelectionVisibility),
39553
39912
  styleTokens: {
39554
39913
  background: "surface",
39555
39914
  typography: "body",
@@ -39658,6 +40017,7 @@ const eventListingHydrationSchema = z$1.object({
39658
40017
  eventSurface: eventSurfaceScopeSchema,
39659
40018
  filterEventPresets: z$1.string().nullable(),
39660
40019
  scheduleScope: eventScheduleScopeSchema,
40020
+ seriesIds: z$1.string().nullable().optional(),
39661
40021
  filterCategoryIds: z$1.string().nullable().optional(),
39662
40022
  filterStaffMemberId: z$1.string().nullable().optional(),
39663
40023
  filterVenueId: z$1.string().nullable().optional(),
@@ -39718,6 +40078,7 @@ const eventListingBlockRuntime = defineProgressiveBlockRuntime({
39718
40078
  eventSurface: normalizeEventSurfaceScope(source.eventSurface),
39719
40079
  filterEventPresets: normalizeEventSurfacePresetsCsv(source.filterEventPresets),
39720
40080
  scheduleScope: normalizeEventScheduleScope(source.scheduleScope),
40081
+ seriesIds: eventSeriesScopeCsv(source.seriesIds),
39721
40082
  filterCategoryIds: normalizeEventCategoryIdsCsv(source.filterCategoryIds),
39722
40083
  filterStaffMemberId: normalizeEventStaffMemberId(source.filterStaffMemberId),
39723
40084
  filterVenueId: normalizeEventVenueId(source.filterVenueId),
@@ -40222,6 +40583,15 @@ const newsletterFieldSchema = z$1.object({
40222
40583
  placeholder: z$1.string().optional()
40223
40584
  });
40224
40585
  const mailingListSignupBlockIdSchema = z$1.string().trim().min(1).transform(parseRequiredMailingListSignupBlockId);
40586
+ const mailingListContentVersionIdSchema = z$1.string().transform((value, ctx) => {
40587
+ const parsed = parseMailingListContentVersionId(value);
40588
+ if (parsed) return parsed;
40589
+ ctx.addIssue({
40590
+ code: z$1.ZodIssueCode.custom,
40591
+ message: "Invalid mailing-list content version ID"
40592
+ });
40593
+ return z$1.NEVER;
40594
+ });
40225
40595
  const signedMailingListSourceTokenSchema = z$1.string().trim().min(1).transform(parseRequiredMailingListSignedSourceToken);
40226
40596
  const newsletterSourceCommonSchema = z$1.object({
40227
40597
  siteId: z$1.string().optional(),
@@ -40235,7 +40605,8 @@ const newsletterSourceCommonSchema = z$1.object({
40235
40605
  const newsletterSourceSchema = z$1.discriminatedUnion("source", [
40236
40606
  newsletterSourceCommonSchema.extend({
40237
40607
  source: z$1.literal("block"),
40238
- blockId: z$1.string().nullable().optional()
40608
+ blockId: z$1.string().nullable().optional(),
40609
+ contentVersionId: z$1.string().nullable().optional()
40239
40610
  }),
40240
40611
  newsletterSourceCommonSchema.extend({
40241
40612
  source: z$1.literal("signed-footer"),
@@ -40251,6 +40622,7 @@ const newsletterDisplaySchema = z$1.object({
40251
40622
  availability: z$1.enum(["ready", "unavailable"]),
40252
40623
  className: z$1.string().nullable(),
40253
40624
  buttonLabel: z$1.string(),
40625
+ successMessage: z$1.string(),
40254
40626
  buttonVariant: newsletterButtonVariantSchema,
40255
40627
  privacyNote: z$1.string().nullable(),
40256
40628
  fields: z$1.array(newsletterFieldSchema),
@@ -40265,7 +40637,8 @@ const newsletterHydrationSchema = z$1.object({
40265
40637
  tag: z$1.literal("block-source"),
40266
40638
  sourceRef: z$1.object({
40267
40639
  tag: z$1.literal("block_ref"),
40268
- blockId: mailingListSignupBlockIdSchema
40640
+ blockId: mailingListSignupBlockIdSchema,
40641
+ contentVersionId: mailingListContentVersionIdSchema
40269
40642
  }).nullable()
40270
40643
  }),
40271
40644
  z$1.object({
@@ -40304,6 +40677,7 @@ function buildNewsletterDisplay(source) {
40304
40677
  fields: { preset: "emailOnly" },
40305
40678
  includeOptionalPhone: false,
40306
40679
  buttonLabel: "Subscribe",
40680
+ successMessage: DEFAULT_MAILING_LIST_SUCCESS_MESSAGE,
40307
40681
  privacyNote: null
40308
40682
  };
40309
40683
  const targeting = source.targeting ?? { mode: "default" };
@@ -40313,6 +40687,7 @@ function buildNewsletterDisplay(source) {
40313
40687
  availability: runtimeTargetingIsAvailable(context, targeting, choices) ? "ready" : "unavailable",
40314
40688
  className: source.className ?? null,
40315
40689
  buttonLabel: form.buttonLabel,
40690
+ successMessage: form.successMessage,
40316
40691
  buttonVariant: source.buttonVariant ?? "primary",
40317
40692
  privacyNote: form.privacyNote,
40318
40693
  fields: getGlobalFormFields(form),
@@ -40343,7 +40718,7 @@ const newsletterFormBlockRuntime = defineProgressiveBlockRuntime({
40343
40718
  function projectNewsletterFormHydrationTarget(source) {
40344
40719
  switch (source.source) {
40345
40720
  case "block": {
40346
- const sourceRef = buildMailingListSignupBlockSourceRef(source.blockId);
40721
+ const sourceRef = buildMailingListSignupBlockSourceRef(source.blockId, source.contentVersionId);
40347
40722
  if (sourceRef?.tag === "block_ref") return {
40348
40723
  tag: "block-source",
40349
40724
  sourceRef
@@ -42757,9 +43132,10 @@ function cx(...classes) {
42757
43132
  * Server-safe placeholder for event registration.
42758
43133
  * Provides a static container for island hydration without importing client hooks.
42759
43134
  */
42760
- function EventRegistrationSSR({ blockId, subject, children, ...sourceProps }) {
43135
+ function EventRegistrationSSR({ blockId, subject, loaderFailures, children, ...sourceProps }) {
42761
43136
  const islandProps = buildEventRegistrationInteractiveIslandProps({
42762
43137
  ...sourceProps,
43138
+ eventLoaderFailures: blockId ? loaderFailures?.[blockId] : void 0,
42763
43139
  subject: normalizeEventRegistrationPageSurfaceSubject(subject)
42764
43140
  });
42765
43141
  const display = islandProps.render.display;
@@ -43092,7 +43468,7 @@ function NewsletterFormSSR(props) {
43092
43468
  className: clsx("newsletter-form-ssr", className),
43093
43469
  children: /* @__PURE__ */ jsx("p", {
43094
43470
  role: "status",
43095
- children: "Mailing-list signup is not available right now."
43471
+ children: "We can’t accept signups right now. Please try again later."
43096
43472
  })
43097
43473
  });
43098
43474
  const renderField = (field) => {
@@ -43138,14 +43514,18 @@ function NewsletterFormSSR(props) {
43138
43514
  children: [
43139
43515
  fields.map(renderField),
43140
43516
  islandProps.render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsxs("fieldset", {
43141
- className: "newsletter-topics",
43142
- children: [/* @__PURE__ */ jsx("legend", { children: "What would you like to hear about?" }), display.choices.map((choice) => /* @__PURE__ */ jsxs("label", {
43143
- className: "newsletter-topic-choice",
43517
+ className: "fb-fieldset newsletter-topics",
43518
+ children: [/* @__PURE__ */ jsx("legend", {
43519
+ className: "form-label",
43520
+ children: "What would you like to hear about?"
43521
+ }), display.choices.map((choice) => /* @__PURE__ */ jsxs("label", {
43522
+ className: "fb-inline form-label newsletter-topic-choice",
43144
43523
  children: [/* @__PURE__ */ jsx("input", {
43145
43524
  type: "checkbox",
43146
43525
  name: "mailingListChoice",
43147
- value: choice.id
43148
- }), choice.label]
43526
+ value: choice.id,
43527
+ className: "form-checkbox"
43528
+ }), /* @__PURE__ */ jsx("span", { children: choice.label })]
43149
43529
  }, choice.id))]
43150
43530
  }) : null,
43151
43531
  /* @__PURE__ */ jsx("div", {
@@ -44134,6 +44514,18 @@ function resolveChildren(nodes, context) {
44134
44514
  function isReactNode(value) {
44135
44515
  return value !== null && value !== void 0;
44136
44516
  }
44517
+ function resolveNodeMetadata(nodeType, context) {
44518
+ return {
44519
+ pathBase: context.pathBase,
44520
+ blockId: context.blockId,
44521
+ blockKind: context.blockKind,
44522
+ blockContent: context.blockContent,
44523
+ fragmentRegistry: context.fragmentRegistry,
44524
+ previewAuthoring: context.previewAuthoring,
44525
+ ...nodeType.toLowerCase() === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
44526
+ ...nodeType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
44527
+ };
44528
+ }
44137
44529
  /**
44138
44530
  * Resolves a node definition into a React element.
44139
44531
  * Handles conditionals ($when), scopes ($scopes), repeaters ($repeat), bindings ($bind), and children.
@@ -44169,13 +44561,7 @@ function resolveNode(node, context, indexFallback) {
44169
44561
  const elementProps = {
44170
44562
  ...props,
44171
44563
  key: node.key ?? indexFallback,
44172
- pathBase: context.pathBase,
44173
- blockId: context.blockId,
44174
- blockKind: context.blockKind,
44175
- blockContent: context.blockContent,
44176
- ...node.type === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {},
44177
- fragmentRegistry: context.fragmentRegistry,
44178
- previewAuthoring: context.previewAuthoring
44564
+ ...resolveNodeMetadata(node.type, context)
44179
44565
  };
44180
44566
  const element = React.createElement(component, elementProps, ...children);
44181
44567
  if (headingDecorationPlan.kind === "skip") return element;
@@ -45050,9 +45436,56 @@ function generateNavLinkCSS(options) {
45050
45436
  if (baseRules.length > 0) cssChunks.unshift(`\n${selector} {\n ${baseRules.join("\n ")}\n}\n`);
45051
45437
  if (hoverRules.length > 0) cssChunks.push(`\n${hoverSelector} {\n ${hoverRules.join("\n ")}\n}\n`);
45052
45438
  if (activeRules.length > 0) cssChunks.push(`\n${activeSelector} {\n ${activeRules.join("\n ")}\n}\n`);
45439
+ cssChunks.push(navLinkFocusVisibleCss(selector, style, theme, tokens));
45053
45440
  cssChunks.push(generateInteractiveChildInheritanceCSS(selector));
45054
45441
  return cssChunks.join("");
45055
45442
  }
45443
+ /**
45444
+ * Keyboard focus indicator for nav links, in the header, the footer and header
45445
+ * dropdown menus — the three surfaces `generateNavLinkCSS` serves.
45446
+ *
45447
+ * Emitted unconditionally rather than as an effect, because focus visibility is
45448
+ * a floor rather than a style choice. Only the interaction-palette pill ever
45449
+ * wrote an `effects.focus` group, so every other nav — every `quiet` palette,
45450
+ * every footer, every dropdown — previously fell back to whatever outline the
45451
+ * browser drew.
45452
+ *
45453
+ * The outline takes the link's own resolved colour, so on a header that adapts
45454
+ * to the section it floats over it moves with the adaptation instead of
45455
+ * asserting a brand colour against an unknown backdrop.
45456
+ *
45457
+ * Where the style asks for `soft-glow`, the same halo goes on the outline. That
45458
+ * treatment exists because the theme has already conceded the resolved colour
45459
+ * alone is not reliable over an unpredictable backdrop — a hero photograph with
45460
+ * mixed luminance. Without it the text would stay legible by its halo while the
45461
+ * focus ring, which is the part with a contrast requirement of its own, would
45462
+ * not.
45463
+ *
45464
+ * A style that also paints a focus pill keeps it: this adds an outline around
45465
+ * that pill rather than replacing it.
45466
+ */
45467
+ function navLinkFocusVisibleCss(selector, style, theme, tokens) {
45468
+ const color = tokens.getColor(style.colorToken);
45469
+ const halo = buildTextContrastShadow({
45470
+ theme,
45471
+ colorToken: style.colorToken,
45472
+ treatment: style.contrastTreatment
45473
+ });
45474
+ return `
45475
+ ${selector}:focus-visible {
45476
+ outline: 2px solid ${color};
45477
+ outline-offset: ${focusOutlineOffset(selector)};${halo ? `\n box-shadow: ${halo};` : ""}
45478
+ }
45479
+ `;
45480
+ }
45481
+ /**
45482
+ * Dropdown items are full-width inside a panel with no horizontal padding, so
45483
+ * an outset outline would paint over and past the panel's own border. Keeping
45484
+ * it flush is the only way it reads as belonging to the item.
45485
+ */
45486
+ function focusOutlineOffset(selector) {
45487
+ return selector.includes("nav-dropdown-link") ? "-2px" : "3px";
45488
+ }
45056
45489
  function buildTextContrastShadow(input) {
45057
45490
  if (input.treatment !== "soft-glow") return null;
45058
45491
  return isLikelyLightColorToken(input.theme, input.colorToken) ? "0 1px 3px rgb(0 0 0 / 0.55), 0 0 18px rgb(0 0 0 / 0.38)" : "0 1px 3px rgb(255 255 255 / 0.72), 0 0 18px rgb(255 255 255 / 0.5)";
@@ -48185,7 +48618,7 @@ function pageBlockPosition(index, blockCount) {
48185
48618
  //#endregion
48186
48619
  //#region ../blocks/src/pageRendererContracts.ts
48187
48620
  function buildPageRendererRootRuntime(dataContext) {
48188
- const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, bookingOfferingPresets = [], mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false } = dataContext ?? {};
48621
+ const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, bookingOfferingPresets = [], appointmentServicePathPrefix = null, mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
48189
48622
  return {
48190
48623
  siteId,
48191
48624
  pageId,
@@ -48195,8 +48628,10 @@ function buildPageRendererRootRuntime(dataContext) {
48195
48628
  apiBaseUrl,
48196
48629
  portalToken,
48197
48630
  bookingOfferingPresets,
48631
+ appointmentServicePathPrefix,
48198
48632
  mailingList,
48199
- eventRegistrationOverlayEnabled
48633
+ eventRegistrationOverlayEnabled,
48634
+ loaderFailures
48200
48635
  };
48201
48636
  }
48202
48637
  //#endregion
@@ -52936,7 +53371,8 @@ const appointmentServicesBlockDefinition = {
52936
53371
  el("appointment-services", {
52937
53372
  sectionHeading: { $bind: { from: "content.heading" } },
52938
53373
  services: { $bind: { from: "data.services" } },
52939
- pathname: { $bind: { from: "$root.pathname" } }
53374
+ pathname: { $bind: { from: "$root.pathname" } },
53375
+ servicePathPrefix: { $bind: { from: "$root.appointmentServicePathPrefix" } }
52940
53376
  })
52941
53377
  ], { gap: "lg" })
52942
53378
  })]
@@ -57466,7 +57902,7 @@ function collectNestedPreviewFieldConstraintEntries(field, path) {
57466
57902
  }
57467
57903
  function makeDefaultBlockComponent(args) {
57468
57904
  const { manifest } = args;
57469
- return function DefaultBlockComponent({ content, data, registry, theme, themeConfig, transforms, viewModelOverrides, pathBase, blockId, blockKind, blockBindings, editableRouteMetadataFieldIds, fragmentRegistry, imageResolveContext, previewAuthoring }) {
57905
+ return function DefaultBlockComponent({ content, data, registry, theme, themeConfig, transforms, viewModelOverrides, pathBase, blockId, contentVersionId, blockKind, blockBindings, editableRouteMetadataFieldIds, fragmentRegistry, imageResolveContext, previewAuthoring }) {
57470
57906
  const perf = beginBlockRenderMeasurement();
57471
57907
  if (!theme) throw new Error("Block rendering requires theme tokens; none were provided to makeDefaultBlockComponent");
57472
57908
  if (!registry) throw new Error("Block rendering requires a component registry; none was provided");
@@ -57486,6 +57922,7 @@ function makeDefaultBlockComponent(args) {
57486
57922
  theme: withButtonSystem(theme, themeConfig),
57487
57923
  pathBase,
57488
57924
  blockId,
57925
+ contentVersionId,
57489
57926
  blockKind,
57490
57927
  blockContent: mergedContent,
57491
57928
  blockBindings,
@@ -58279,6 +58716,7 @@ function buildBlockOverrideProps(input) {
58279
58716
  ...blockSubjectProps(dataContext),
58280
58717
  imageResolveContext: input.imageResolveContext,
58281
58718
  blockId: block.id ?? null,
58719
+ contentVersionId: block.contentVersionId ?? null,
58282
58720
  blockKind: block.kind
58283
58721
  };
58284
58722
  }
@@ -58379,6 +58817,7 @@ function toPresentationPage(page) {
58379
58817
  id: block.id,
58380
58818
  kind: block.kind,
58381
58819
  purpose: block.purpose,
58820
+ ...block.contentVersionId ? { contentVersionId: block.contentVersionId } : {},
58382
58821
  ...block.bindings ? { bindings: block.bindings } : {}
58383
58822
  };
58384
58823
  return block.admission.kind === "renderable" ? {
@@ -59627,10 +60066,19 @@ const containerResponsiveThemeCss = `/*
59627
60066
  padding-top: 2.5rem;
59628
60067
  padding-bottom: 2.5rem;
59629
60068
  }
60069
+ /* Clearance for a surface that is not an authored block page.
60070
+ An authored page gets this through its opening block's container (see the
60071
+ overlay-clearance rule in styles.css). A reserved surface or a system
60072
+ destination page has no such block, so it consumes the same variable here.
60073
+ Marked with one class rather than per-surface selectors, because the last
60074
+ two additions to this family were both missed and shipped overlapping. */
59630
60075
  :where(.theme-scope)
59631
60076
  [data-site-document-layout-mode="header-overlay"]
59632
- [data-rb-reserved-surface].rb-reserved-surface-main {
59633
- padding-top: calc(var(--rb-reserved-surface-header-offset, 5.5rem) + 2.5rem);
60077
+ .rb-overlay-clearance-surface {
60078
+ padding-top: calc(
60079
+ var(--site-overlay-header-clearance, 5.5rem) +
60080
+ var(--site-overlay-opening-content-extra-pad, clamp(1rem, 2vw, 1.75rem))
60081
+ );
59634
60082
  }
59635
60083
  .rb-preview-editor-offset {
59636
60084
  padding-bottom: calc(
@@ -68632,7 +69080,9 @@ const containerResponsiveThemeCss = `/*
68632
69080
  text-align: left;
68633
69081
  }
68634
69082
 
68635
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-login__subtitle {
69083
+ :where(.theme-scope)
69084
+ :where([data-block="customer-portal"])
69085
+ .cp-login__subtitle {
68636
69086
  color: var(--cp-muted);
68637
69087
  font-size: 0.9375rem;
68638
69088
  text-align: left;
@@ -68659,7 +69109,9 @@ const containerResponsiveThemeCss = `/*
68659
69109
  text-align: left;
68660
69110
  }
68661
69111
 
68662
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-login__reset-link {
69112
+ :where(.theme-scope)
69113
+ :where([data-block="customer-portal"])
69114
+ .cp-login__reset-link {
68663
69115
  appearance: none;
68664
69116
  background: none;
68665
69117
  border: 0;
@@ -68673,11 +69125,15 @@ const containerResponsiveThemeCss = `/*
68673
69125
  text-underline-offset: 0.15em;
68674
69126
  }
68675
69127
 
68676
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-login__reset-link:hover {
69128
+ :where(.theme-scope)
69129
+ :where([data-block="customer-portal"])
69130
+ .cp-login__reset-link:hover {
68677
69131
  color: var(--cp-text);
68678
69132
  }
68679
69133
 
68680
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-login__reset-link:focus-visible {
69134
+ :where(.theme-scope)
69135
+ :where([data-block="customer-portal"])
69136
+ .cp-login__reset-link:focus-visible {
68681
69137
  outline: 2px solid currentColor;
68682
69138
  outline-offset: 3px;
68683
69139
  }
@@ -68722,7 +69178,9 @@ const containerResponsiveThemeCss = `/*
68722
69178
  border-bottom: none;
68723
69179
  }
68724
69180
 
68725
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-header__welcome {
69181
+ :where(.theme-scope)
69182
+ :where([data-block="customer-portal"])
69183
+ .cp-header__welcome {
68726
69184
  font-size: 1.125rem;
68727
69185
  font-weight: 500;
68728
69186
  }
@@ -68738,8 +69196,14 @@ const containerResponsiveThemeCss = `/*
68738
69196
  }
68739
69197
 
68740
69198
  @keyframes cp-fade-in {
68741
- from { opacity: 0; transform: translateY(4px); }
68742
- to { opacity: 1; transform: translateY(0); }
69199
+ from {
69200
+ opacity: 0;
69201
+ transform: translateY(4px);
69202
+ }
69203
+ to {
69204
+ opacity: 1;
69205
+ transform: translateY(0);
69206
+ }
68743
69207
  }
68744
69208
 
68745
69209
  /* Empty state */
@@ -68828,6 +69292,77 @@ const containerResponsiveThemeCss = `/*
68828
69292
  margin-top: 1rem;
68829
69293
  }
68830
69294
 
69295
+ /* Event waitlists */
69296
+ :where(.theme-scope) :where([data-block="customer-portal"]) .cp-waitlist-list {
69297
+ display: grid;
69298
+ gap: 1rem;
69299
+ }
69300
+
69301
+ :where(.theme-scope)
69302
+ :where([data-block="customer-portal"])
69303
+ .cp-waitlists
69304
+ > .cp-alert {
69305
+ margin-bottom: 1rem;
69306
+ }
69307
+
69308
+ :where(.theme-scope) :where([data-block="customer-portal"]) .cp-waitlist-card {
69309
+ transition:
69310
+ border-color 180ms ease,
69311
+ box-shadow 180ms ease;
69312
+ }
69313
+
69314
+ :where(.theme-scope)
69315
+ :where([data-block="customer-portal"])
69316
+ .cp-waitlist-card--focused {
69317
+ border-color: var(--cp-primary);
69318
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--cp-primary) 22%, transparent);
69319
+ }
69320
+
69321
+ :where(.theme-scope)
69322
+ :where([data-block="customer-portal"])
69323
+ .cp-waitlist-card__summary,
69324
+ :where(.theme-scope)
69325
+ :where([data-block="customer-portal"])
69326
+ .cp-waitlist-card__position {
69327
+ font-weight: 600;
69328
+ }
69329
+
69330
+ :where(.theme-scope)
69331
+ :where([data-block="customer-portal"])
69332
+ .cp-waitlist-card
69333
+ .cp-card-body
69334
+ p {
69335
+ margin: 0.4rem 0;
69336
+ }
69337
+
69338
+ @container rb-site (max-width: 640px) {
69339
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
69340
+ :where(.theme-scope)
69341
+ :where([data-block="customer-portal"])
69342
+ .cp-waitlist-card
69343
+ .cp-card-header {
69344
+ flex-direction: column-reverse;
69345
+ }
69346
+
69347
+ :where(.theme-scope)
69348
+ :where([data-block="customer-portal"])
69349
+ .cp-waitlist-card
69350
+ .cp-card-actions {
69351
+ align-items: stretch;
69352
+ flex-direction: column;
69353
+ }
69354
+
69355
+ :where(.theme-scope)
69356
+ :where([data-block="customer-portal"])
69357
+ .cp-waitlist-card
69358
+ .cp-card-actions
69359
+ > * {
69360
+ justify-content: center;
69361
+ text-align: center;
69362
+ }
69363
+ }
69364
+ }
69365
+
68831
69366
  /* Badge */
68832
69367
  :where(.theme-scope) :where([data-block="customer-portal"]) .cp-badge {
68833
69368
  display: inline-flex;
@@ -68964,11 +69499,18 @@ const containerResponsiveThemeCss = `/*
68964
69499
  background: rgba(var(--tb-border), 0.2);
68965
69500
  }
68966
69501
 
68967
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table tbody tr:last-child td {
69502
+ :where(.theme-scope)
69503
+ :where([data-block="customer-portal"])
69504
+ .cp-table
69505
+ tbody
69506
+ tr:last-child
69507
+ td {
68968
69508
  border-bottom: none;
68969
69509
  }
68970
69510
 
68971
- :where(.theme-scope) :where([data-block="customer-portal"]) :is(.cp-row--past, .cp-row--muted) {
69511
+ :where(.theme-scope)
69512
+ :where([data-block="customer-portal"])
69513
+ :is(.cp-row--past, .cp-row--muted) {
68972
69514
  opacity: 0.65;
68973
69515
  }
68974
69516
 
@@ -68981,7 +69523,9 @@ const containerResponsiveThemeCss = `/*
68981
69523
  line-height: 1.2;
68982
69524
  }
68983
69525
 
68984
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-title__badges {
69526
+ :where(.theme-scope)
69527
+ :where([data-block="customer-portal"])
69528
+ .cp-row-title__badges {
68985
69529
  margin-left: auto;
68986
69530
  display: flex;
68987
69531
  flex-wrap: wrap;
@@ -68989,7 +69533,9 @@ const containerResponsiveThemeCss = `/*
68989
69533
  gap: 0.375rem;
68990
69534
  }
68991
69535
 
68992
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-title__text {
69536
+ :where(.theme-scope)
69537
+ :where([data-block="customer-portal"])
69538
+ .cp-row-title__text {
68993
69539
  min-width: 0;
68994
69540
  }
68995
69541
 
@@ -69009,12 +69555,16 @@ const containerResponsiveThemeCss = `/*
69009
69555
  line-height: 1.35;
69010
69556
  }
69011
69557
 
69012
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-note--success {
69558
+ :where(.theme-scope)
69559
+ :where([data-block="customer-portal"])
69560
+ .cp-row-note--success {
69013
69561
  border-left-color: rgb(var(--tb-success));
69014
69562
  color: rgb(var(--tb-success));
69015
69563
  }
69016
69564
 
69017
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-note--error {
69565
+ :where(.theme-scope)
69566
+ :where([data-block="customer-portal"])
69567
+ .cp-row-note--error {
69018
69568
  border-left-color: rgb(var(--tb-destructive));
69019
69569
  color: rgb(var(--tb-destructive));
69020
69570
  }
@@ -69033,16 +69583,23 @@ const containerResponsiveThemeCss = `/*
69033
69583
  white-space: nowrap;
69034
69584
  }
69035
69585
 
69036
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-col-actions .btn-sm {
69586
+ :where(.theme-scope)
69587
+ :where([data-block="customer-portal"])
69588
+ .cp-col-actions
69589
+ .btn-sm {
69037
69590
  white-space: nowrap;
69038
69591
  }
69039
69592
 
69040
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-title__link {
69593
+ :where(.theme-scope)
69594
+ :where([data-block="customer-portal"])
69595
+ .cp-row-title__link {
69041
69596
  color: inherit;
69042
69597
  text-decoration: none;
69043
69598
  }
69044
69599
 
69045
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-title__link:hover {
69600
+ :where(.theme-scope)
69601
+ :where([data-block="customer-portal"])
69602
+ .cp-row-title__link:hover {
69046
69603
  text-decoration: underline;
69047
69604
  text-decoration-thickness: 2px;
69048
69605
  text-underline-offset: 2px;
@@ -69064,7 +69621,9 @@ const containerResponsiveThemeCss = `/*
69064
69621
  }
69065
69622
 
69066
69623
  /* Profile actions */
69067
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-profile__actions {
69624
+ :where(.theme-scope)
69625
+ :where([data-block="customer-portal"])
69626
+ .cp-profile__actions {
69068
69627
  display: flex;
69069
69628
  gap: 0.75rem;
69070
69629
  margin-top: 1rem;
@@ -69131,28 +69690,39 @@ const containerResponsiveThemeCss = `/*
69131
69690
  gap: 0.375rem;
69132
69691
  }
69133
69692
 
69134
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guest-edit-row__index {
69693
+ :where(.theme-scope)
69694
+ :where([data-block="customer-portal"])
69695
+ .cp-guest-edit-row__index {
69135
69696
  font-size: 0.75rem;
69136
69697
  font-weight: 500;
69137
69698
  color: var(--cp-muted);
69138
69699
  }
69139
69700
 
69140
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guest-edit-row__fields {
69701
+ :where(.theme-scope)
69702
+ :where([data-block="customer-portal"])
69703
+ .cp-guest-edit-row__fields {
69141
69704
  display: flex;
69142
69705
  gap: 0.5rem;
69143
69706
  }
69144
69707
 
69145
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guest-edit-row__fields input {
69708
+ :where(.theme-scope)
69709
+ :where([data-block="customer-portal"])
69710
+ .cp-guest-edit-row__fields
69711
+ input {
69146
69712
  flex: 1;
69147
69713
  min-width: 0;
69148
69714
  }
69149
69715
 
69150
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guest-edit-row__error {
69716
+ :where(.theme-scope)
69717
+ :where([data-block="customer-portal"])
69718
+ .cp-guest-edit-row__error {
69151
69719
  font-size: 0.75rem;
69152
69720
  color: var(--cp-error);
69153
69721
  }
69154
69722
 
69155
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-guests__actions {
69723
+ :where(.theme-scope)
69724
+ :where([data-block="customer-portal"])
69725
+ .cp-guests__actions {
69156
69726
  display: flex;
69157
69727
  gap: 0.5rem;
69158
69728
  margin-top: 0.5rem;
@@ -69166,13 +69736,18 @@ const containerResponsiveThemeCss = `/*
69166
69736
  }
69167
69737
 
69168
69738
  /* In the actions modal, tiles sit on a surface modal, so use "background" for contrast. */
69169
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-actions-list :where(.rb-tile) {
69739
+ :where(.theme-scope)
69740
+ :where([data-block="customer-portal"])
69741
+ .cp-actions-list
69742
+ :where(.rb-tile) {
69170
69743
  --rb-event-tile-bg: rgb(var(--tb-background));
69171
69744
  --rb-event-tile-border: rgb(var(--tb-border));
69172
69745
  }
69173
69746
 
69174
69747
  /* Actions trigger: icon-only kebab button */
69175
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-actions-trigger.btn-sm {
69748
+ :where(.theme-scope)
69749
+ :where([data-block="customer-portal"])
69750
+ .cp-actions-trigger.btn-sm {
69176
69751
  padding: 0.35rem !important;
69177
69752
  line-height: 1 !important;
69178
69753
  min-width: 32px;
@@ -69196,17 +69771,24 @@ const containerResponsiveThemeCss = `/*
69196
69771
  gap: 0.25rem;
69197
69772
  }
69198
69773
 
69199
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-action-tile__title {
69774
+ :where(.theme-scope)
69775
+ :where([data-block="customer-portal"])
69776
+ .cp-action-tile__title {
69200
69777
  font-weight: 600;
69201
69778
  font-size: 0.9375rem;
69202
69779
  }
69203
69780
 
69204
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-action-tile__desc {
69781
+ :where(.theme-scope)
69782
+ :where([data-block="customer-portal"])
69783
+ .cp-action-tile__desc {
69205
69784
  font-size: 0.875rem;
69206
69785
  line-height: 1.35;
69207
69786
  }
69208
69787
 
69209
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-action-tile--danger .cp-action-tile__title {
69788
+ :where(.theme-scope)
69789
+ :where([data-block="customer-portal"])
69790
+ .cp-action-tile--danger
69791
+ .cp-action-tile__title {
69210
69792
  color: rgb(var(--tb-destructive));
69211
69793
  }
69212
69794
 
@@ -69228,7 +69810,9 @@ const containerResponsiveThemeCss = `/*
69228
69810
  text-decoration: underline;
69229
69811
  }
69230
69812
 
69231
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-btn--link:hover {
69813
+ :where(.theme-scope)
69814
+ :where([data-block="customer-portal"])
69815
+ .cp-btn--link:hover {
69232
69816
  color: var(--cp-primary-hover);
69233
69817
  }
69234
69818
 
@@ -69267,34 +69851,48 @@ const containerResponsiveThemeCss = `/*
69267
69851
  margin-top: 0.75rem;
69268
69852
  }
69269
69853
 
69270
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-cancel-confirm__title {
69854
+ :where(.theme-scope)
69855
+ :where([data-block="customer-portal"])
69856
+ .cp-cancel-confirm__title {
69271
69857
  font-weight: 600;
69272
69858
  margin-bottom: 0.5rem;
69273
69859
  }
69274
69860
 
69275
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-cancel-confirm__message {
69861
+ :where(.theme-scope)
69862
+ :where([data-block="customer-portal"])
69863
+ .cp-cancel-confirm__message {
69276
69864
  margin-bottom: 0.25rem;
69277
69865
  }
69278
69866
 
69279
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-cancel-confirm__warning {
69867
+ :where(.theme-scope)
69868
+ :where([data-block="customer-portal"])
69869
+ .cp-cancel-confirm__warning {
69280
69870
  margin-bottom: 0.75rem;
69281
69871
  }
69282
69872
 
69283
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-cancel-confirm__actions {
69873
+ :where(.theme-scope)
69874
+ :where([data-block="customer-portal"])
69875
+ .cp-cancel-confirm__actions {
69284
69876
  display: flex;
69285
69877
  gap: 0.75rem;
69286
69878
  }
69287
69879
 
69288
69880
  /* Membership actions */
69289
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-membership-actions {
69881
+ :where(.theme-scope)
69882
+ :where([data-block="customer-portal"])
69883
+ .cp-membership-actions {
69290
69884
  margin-top: 0.75rem;
69291
69885
  }
69292
69886
 
69293
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-section-actions {
69887
+ :where(.theme-scope)
69888
+ :where([data-block="customer-portal"])
69889
+ .cp-section-actions {
69294
69890
  margin-top: 1rem;
69295
69891
  }
69296
69892
 
69297
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-card-subtitle--spaced {
69893
+ :where(.theme-scope)
69894
+ :where([data-block="customer-portal"])
69895
+ .cp-card-subtitle--spaced {
69298
69896
  margin-top: 0.75rem;
69299
69897
  }
69300
69898
 
@@ -69318,9 +69916,18 @@ const containerResponsiveThemeCss = `/*
69318
69916
  display: none;
69319
69917
  }
69320
69918
 
69321
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table :is(th, td).cp-col-guests,
69322
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table :is(th, td).cp-col-tickets,
69323
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table :is(th, td).cp-col-actions {
69919
+ :where(.theme-scope)
69920
+ :where([data-block="customer-portal"])
69921
+ .cp-table
69922
+ :is(th, td).cp-col-guests,
69923
+ :where(.theme-scope)
69924
+ :where([data-block="customer-portal"])
69925
+ .cp-table
69926
+ :is(th, td).cp-col-tickets,
69927
+ :where(.theme-scope)
69928
+ :where([data-block="customer-portal"])
69929
+ .cp-table
69930
+ :is(th, td).cp-col-actions {
69324
69931
  display: none;
69325
69932
  }
69326
69933
 
@@ -69329,24 +69936,34 @@ const containerResponsiveThemeCss = `/*
69329
69936
  }
69330
69937
 
69331
69938
  /* Make the cell a positioning context for the kebab */
69332
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row > td:first-child {
69939
+ :where(.theme-scope)
69940
+ :where([data-block="customer-portal"])
69941
+ .cp-row
69942
+ > td:first-child {
69333
69943
  position: relative;
69334
69944
  padding-right: 2.5rem;
69335
69945
  }
69336
69946
 
69337
69947
  /* Position kebab in top-right of the cell */
69338
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-mobile-actions {
69948
+ :where(.theme-scope)
69949
+ :where([data-block="customer-portal"])
69950
+ .cp-row-mobile-actions {
69339
69951
  position: absolute;
69340
69952
  top: 0.5rem;
69341
69953
  right: 0.5rem;
69342
69954
  margin-top: 0;
69343
69955
  }
69344
69956
 
69345
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-row-mobile-actions .btn-sm {
69957
+ :where(.theme-scope)
69958
+ :where([data-block="customer-portal"])
69959
+ .cp-row-mobile-actions
69960
+ .btn-sm {
69346
69961
  width: auto;
69347
69962
  }
69348
69963
 
69349
- :where(.theme-scope) :where([data-block="customer-portal"]) .cp-profile__edit {
69964
+ :where(.theme-scope)
69965
+ :where([data-block="customer-portal"])
69966
+ .cp-profile__edit {
69350
69967
  align-self: stretch;
69351
69968
  }
69352
69969
  }
@@ -69794,6 +70411,47 @@ const containerResponsiveThemeCss = `/*
69794
70411
  gap: 0.25rem;
69795
70412
  }
69796
70413
 
70414
+ /* Topic choices (visitor picks what to hear about). Same treatment as the
70415
+ form block's .fb-fieldset / .fb-inline, defined here because the newsletter
70416
+ form also renders inside contact-newsletter and the site footer. */
70417
+ :where(.theme-scope) .newsletter-topics {
70418
+ display: flex;
70419
+ flex-direction: column;
70420
+ gap: 0.5rem;
70421
+ border: none;
70422
+ padding: 0;
70423
+ margin: 0;
70424
+ min-width: 0;
70425
+ }
70426
+
70427
+ :where(.theme-scope) .newsletter-topics > legend {
70428
+ padding: 0;
70429
+ margin-bottom: 0.25rem;
70430
+ }
70431
+
70432
+ :where(.theme-scope) .newsletter-topic-choice {
70433
+ display: flex;
70434
+ align-items: center;
70435
+ gap: 0.5rem;
70436
+ }
70437
+
70438
+ /* Error panel and field notes. The form block scopes these to its own
70439
+ data-block, so the newsletter form (which also renders in the footer)
70440
+ needs its own copy of the treatment. */
70441
+ :where(.theme-scope) .newsletter-form .fb-error:not([data-field-validation-message]) {
70442
+ background-color: var(--fb-error-bg);
70443
+ color: var(--fb-error-text);
70444
+ border: 1px solid var(--fb-error-border);
70445
+ border-radius: var(--rb-block-radius);
70446
+ padding: 1rem;
70447
+ font-size: 0.875rem;
70448
+ }
70449
+
70450
+ :where(.theme-scope) .newsletter-form [data-field-validation-message] {
70451
+ font-size: 0.875rem;
70452
+ color: var(--fb-error-text);
70453
+ }
70454
+
69797
70455
  /* Required indicator */
69798
70456
  :where(.theme-scope) .newsletter-required {
69799
70457
  color: rgb(var(--tb-primary));
@@ -69843,6 +70501,10 @@ const containerResponsiveThemeCss = `/*
69843
70501
  flex-shrink: 0;
69844
70502
  }
69845
70503
 
70504
+ :where(.theme-scope) .newsletter-inline .newsletter-topics {
70505
+ flex-basis: 100%;
70506
+ }
70507
+
69846
70508
  /* Mobile fallback for inline variant */
69847
70509
  @container rb-site (max-width: 640px) {
69848
70510
  @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
@@ -72158,6 +72820,15 @@ z$1.object({
72158
72820
  }).optional(),
72159
72821
  overrides: z$1.record(z$1.string(), z$1.string()).optional()
72160
72822
  }).passthrough();
72823
+ z$1.object({
72824
+ palette: paletteColorsSchema,
72825
+ paletteMode: paletteModeSchema,
72826
+ typography: z$1.object({
72827
+ headingFamily: z$1.string().trim().min(1),
72828
+ bodyFamily: z$1.string().trim().min(1)
72829
+ }).strict(),
72830
+ corners
72831
+ }).strict();
72161
72832
  //#endregion
72162
72833
  //#region src/rendering/blocks-theme-runtime.ts
72163
72834
  function parseBlocksTheme(theme) {
@@ -72359,7 +73030,7 @@ function PageContent(props) {
72359
73030
  previewToken,
72360
73031
  resolvedData,
72361
73032
  bookingOfferingPresets: bookingOfferingPresets ?? [],
72362
- mailingList,
73033
+ mailingList: mailingList ?? dataContext?.mailingList,
72363
73034
  bookingTimeZone: resolveSdkBookingTimeZone(bookingTimeZone),
72364
73035
  routes: routeMap,
72365
73036
  pagesByIdentifier,
@@ -74112,12 +74783,12 @@ function normalizeContent(block) {
74112
74783
  }
74113
74784
  /**
74114
74785
  * Normalize params for API calls.
74115
- * Converts all values to strings.
74786
+ * Converts supplied values to strings, preserving absent versus explicitly empty params.
74116
74787
  */
74117
74788
  function normalizeParams(input) {
74118
74789
  if (!input || typeof input !== "object") return {};
74119
74790
  const output = {};
74120
- for (const [key, value] of Object.entries(input)) output[key] = coerceToString(value);
74791
+ for (const [key, value] of Object.entries(input)) if (value !== void 0 && value !== null) output[key] = coerceToString(value);
74121
74792
  return output;
74122
74793
  }
74123
74794
  function isNonArrayObject(value) {
@@ -74181,6 +74852,14 @@ function coercePayload(payload) {
74181
74852
  * - Frontend: provide internal API client
74182
74853
  * - SDK: provide SDK client with endpoint mapping
74183
74854
  */
74855
+ function projectDataLoaders(loaders, shouldLoad, blockId, blockKind) {
74856
+ if (!shouldLoad) return [...loaders];
74857
+ return loaders.filter(({ key }) => shouldLoad({
74858
+ blockId,
74859
+ blockKind,
74860
+ loaderKey: key
74861
+ }));
74862
+ }
74184
74863
  function shouldSkipResolvedLoader(input) {
74185
74864
  if (input.loader.requiredParams?.some((param) => !input.params[param]?.trim())) return true;
74186
74865
  return Boolean(input.isValidEndpoint && !input.isValidEndpoint(input.endpoint));
@@ -74206,8 +74885,12 @@ function shouldSkipResolvedLoader(input) {
74206
74885
  * ```
74207
74886
  */
74208
74887
  async function prefetchBlockData$1(page, context, options) {
74209
- const { apiClient, isValidEndpoint, onError, getCustomBlockLoaders, getBlockDefinition: getBlockDefinition$1 = getBlockDefinition, resolveParamsBindings: resolveParamsBindings$1 = resolveParamsBindings } = options;
74888
+ return (await prefetchBlockDataWithFailures(page, context, options)).resolvedData;
74889
+ }
74890
+ async function prefetchBlockDataWithFailures(page, context, options) {
74891
+ const { apiClient, isValidEndpoint, onError, getCustomBlockLoaders, getBlockDefinition: getBlockDefinition$1 = getBlockDefinition, resolveParamsBindings: resolveParamsBindings$1 = resolveParamsBindings, shouldLoad } = options;
74210
74892
  const results = {};
74893
+ const loaderFailures = {};
74211
74894
  const tasks = [];
74212
74895
  for (const block of page.blocks) {
74213
74896
  const blockId = block.id;
@@ -74222,6 +74905,7 @@ async function prefetchBlockData$1(page, context, options) {
74222
74905
  loader
74223
74906
  })) : [];
74224
74907
  } else loaders = [];
74908
+ loaders = projectDataLoaders(loaders, shouldLoad, blockId, block.kind);
74225
74909
  if (loaders.length === 0) continue;
74226
74910
  const root = {
74227
74911
  ...context.root ?? {},
@@ -74255,6 +74939,11 @@ async function prefetchBlockData$1(page, context, options) {
74255
74939
  const blockResults = results[blockId] ?? (results[blockId] = {});
74256
74940
  blockResults[key] = data;
74257
74941
  } catch (error) {
74942
+ const blockFailures = loaderFailures[blockId] ?? (loaderFailures[blockId] = {});
74943
+ blockFailures[key] = {
74944
+ endpoint,
74945
+ params
74946
+ };
74258
74947
  if (onError) onError(error, {
74259
74948
  block: block.kind,
74260
74949
  loader: key
@@ -74264,7 +74953,10 @@ async function prefetchBlockData$1(page, context, options) {
74264
74953
  }
74265
74954
  }
74266
74955
  if (tasks.length > 0) await Promise.all(tasks);
74267
- return results;
74956
+ return {
74957
+ resolvedData: results,
74958
+ loaderFailures
74959
+ };
74268
74960
  }
74269
74961
  //#endregion
74270
74962
  //#region ../blocks/src/system/data/loaderEndpoints.ts
@@ -74311,8 +75003,8 @@ function toStringParams(value) {
74311
75003
  for (const [k, v] of Object.entries(value)) if (typeof v === "string") out[k] = v;
74312
75004
  return out;
74313
75005
  }
74314
- function stripEmptyStringValues(params) {
74315
- for (const [key, value] of Object.entries(params)) if (value === "") delete params[key];
75006
+ function stripEmptyStringValues(params, endpoint) {
75007
+ for (const [key, value] of Object.entries(params)) if (value === "" && !(key === "seriesIds" && (endpoint === "listPublicEvents" || endpoint === "listPublicEventCalendarWindow"))) delete params[key];
74316
75008
  }
74317
75009
  function ensureSiteId(params, context) {
74318
75010
  if (!params.siteId && typeof context.siteId === "string" && context.siteId) params.siteId = context.siteId;
@@ -74325,7 +75017,7 @@ function ensureSiteId(params, context) {
74325
75017
  */
74326
75018
  function normalizeLoaderParams(endpoint, params, context) {
74327
75019
  const out = toStringParams(params);
74328
- stripEmptyStringValues(out);
75020
+ stripEmptyStringValues(out, endpoint);
74329
75021
  if (endpoint === "getPublicFormById") {
74330
75022
  ensureSiteId(out, context);
74331
75023
  if (!out.formId && out.formSlug) {
@@ -74451,9 +75143,11 @@ function convertPageResponseBlock(block) {
74451
75143
  if (typeof block.id !== "string" && block.id !== null) throw new Error(`Invalid block id in page: expected string or null, got ${typeof block.id}`);
74452
75144
  if (typeof block.kind !== "string") throw new Error(`Invalid block kind in page: expected string, got ${typeof block.kind}`);
74453
75145
  if (typeof block.purpose !== "string") throw new Error(`Invalid block purpose in page: expected string, got ${typeof block.purpose}`);
75146
+ 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}`);
74454
75147
  const admission = readInvalidBlockAdmission(block.admission);
74455
75148
  return {
74456
75149
  id: block.id,
75150
+ ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
74457
75151
  kind: block.kind,
74458
75152
  purpose: block.purpose,
74459
75153
  content: sanitizeSdkRuntimeBlockContent(block.kind, readContentRecord(block.content) ?? {}),
@@ -74486,6 +75180,7 @@ function projectRenderablePageOutline(page) {
74486
75180
  ...page,
74487
75181
  blocks: page.blocks.flatMap((block) => block.admission.kind === "renderable" ? [{
74488
75182
  id: block.id,
75183
+ ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
74489
75184
  kind: block.kind,
74490
75185
  purpose: block.purpose,
74491
75186
  content: block.admission.content,
@@ -74496,6 +75191,7 @@ function projectRenderablePageOutline(page) {
74496
75191
  function admitSdkRuntimePageBlock(block, customBlocks) {
74497
75192
  const base = {
74498
75193
  id: block.id,
75194
+ ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
74499
75195
  kind: block.kind,
74500
75196
  purpose: block.purpose,
74501
75197
  ...block.bindings ? { bindings: block.bindings } : {}
@@ -76241,6 +76937,14 @@ const PUBLIC_BOOKING_AVAILABILITY_ENDPOINT_DEFINITIONS = defineEndpointDefinitio
76241
76937
  auth: "public",
76242
76938
  responseKind: "json"
76243
76939
  },
76940
+ getPublicBookingServiceBySlug: {
76941
+ path: "/public/bookings/services/by-slug/{slug}",
76942
+ method: "GET",
76943
+ revalidate: publicReadFreshnessSeconds("getPublicBookingService"),
76944
+ tags: [TAG_TEMPLATES.publicBookingServices],
76945
+ auth: "public",
76946
+ responseKind: "json"
76947
+ },
76244
76948
  getPublicBookingResourcesReference: {
76245
76949
  path: "/public/bookings/resources/reference",
76246
76950
  method: "GET",
@@ -76793,16 +77497,110 @@ const PUBLIC_READ_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
76793
77497
  responseKind: "json"
76794
77498
  }
76795
77499
  });
77500
+ //#endregion
77501
+ //#region ../api/src/publicOnboardingAttemptEndpointDefinitions.ts
77502
+ /**
77503
+ * The anonymous onboarding attempt, addressed by its opaque resume token.
77504
+ *
77505
+ * Every route here is reached before there is an account, so none of them can
77506
+ * be scoped to a site or a user: the token is the whole credential. They are
77507
+ * kept together so that stays obvious.
77508
+ */
77509
+ const PUBLIC_ONBOARDING_ATTEMPT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
77510
+ createPublicOnboardingAttempt: {
77511
+ path: "/public/onboarding/attempts",
77512
+ method: "POST",
77513
+ auth: "public",
77514
+ errors: [],
77515
+ responseKind: "json"
77516
+ },
77517
+ createPublicOnboardingLogoUploadUrl: {
77518
+ path: "/public/onboarding/attempts/{attemptToken}/logo-upload-url",
77519
+ method: "POST",
77520
+ auth: "public",
77521
+ errors: [],
77522
+ responseKind: "json"
77523
+ },
77524
+ uploadPublicOnboardingLogo: {
77525
+ path: "/public/onboarding/attempts/{attemptToken}/logo",
77526
+ method: "POST",
77527
+ auth: "public",
77528
+ errors: [],
77529
+ responseKind: "json"
77530
+ },
77531
+ getPublicOnboardingAttempt: {
77532
+ path: "/public/onboarding/attempts/{attemptToken}",
77533
+ method: "GET",
77534
+ auth: "public",
77535
+ errors: [],
77536
+ responseKind: "json"
77537
+ },
77538
+ getPublicOnboardingAttemptProgress: {
77539
+ path: "/public/onboarding/attempts/{attemptToken}/status",
77540
+ method: "GET",
77541
+ auth: "public",
77542
+ errors: [],
77543
+ responseKind: "json"
77544
+ },
77545
+ updatePublicOnboardingAttempt: {
77546
+ path: "/public/onboarding/attempts/{attemptToken}",
77547
+ method: "PATCH",
77548
+ auth: "public",
77549
+ errors: [],
77550
+ responseKind: "json"
77551
+ },
77552
+ runPublicOnboardingAttempt: {
77553
+ path: "/public/onboarding/attempts/{attemptToken}/run",
77554
+ method: "POST",
77555
+ auth: "public",
77556
+ errors: [],
77557
+ responseKind: "json"
77558
+ },
77559
+ resendPublicOnboardingAttemptConfirmation: {
77560
+ path: "/public/onboarding/attempts/{attemptToken}/resend-confirmation",
77561
+ method: "POST",
77562
+ auth: "public",
77563
+ errors: [],
77564
+ responseKind: "json"
77565
+ }
77566
+ });
77567
+ //#endregion
77568
+ //#region ../api/src/billingEndpointDefinitions.ts
77569
+ const BILLING_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
77570
+ adminChangePlan: {
77571
+ path: "/admin/billing/plan",
77572
+ method: "POST",
77573
+ tags: ["admin", "billing"],
77574
+ auth: "admin",
77575
+ responseKind: "json"
77576
+ },
77577
+ changePlan: {
77578
+ path: "/billing/plan/change",
77579
+ method: "POST",
77580
+ tags: ["billing"],
77581
+ auth: "user",
77582
+ responseKind: "json"
77583
+ },
77584
+ createBillingPortalSession: {
77585
+ path: "/billing/portal/session",
77586
+ method: "POST",
77587
+ tags: ["billing"],
77588
+ auth: "user",
77589
+ responseKind: "json"
77590
+ }
77591
+ });
76796
77592
  ({
76797
77593
  ...ACCOUNT_ENDPOINT_DEFINITIONS,
77594
+ ...PUBLIC_ONBOARDING_ATTEMPT_ENDPOINT_DEFINITIONS,
76798
77595
  ...PUBLIC_EVENT_ENDPOINT_DEFINITIONS,
76799
77596
  ...GIFTING_ENDPOINT_DEFINITIONS,
76800
- ...PUBLIC_READ_ENDPOINT_DEFINITIONS
77597
+ ...PUBLIC_READ_ENDPOINT_DEFINITIONS,
77598
+ ...BILLING_ENDPOINT_DEFINITIONS
76801
77599
  }), 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, {
76802
77600
  ...NEWSLETTER_ENDPOINT_DEFINITIONS,
76803
77601
  ...APPOINTMENT_ENDPOINT_DEFINITIONS,
76804
77602
  ...EVENT_SERIES_REGISTRATION_ENDPOINT_DEFINITIONS
76805
- }, 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 };
77603
+ }, 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 };
76806
77604
  z$1.object({ refreshToken: z$1.string().min(1).max(4096) }).strict();
76807
77605
  z$1.object({
76808
77606
  accessToken: z$1.string().min(1).max(4096),
@@ -77359,7 +78157,17 @@ const riverbankSiteConfigInputSchema = z$1.object({
77359
78157
  z$1.object({
77360
78158
  config: riverbankSiteConfigInputSchema,
77361
78159
  forceContentTypes: z$1.boolean().optional(),
77362
- mode: z$1.enum(["apply", "preview"]).optional()
78160
+ mode: z$1.enum(["apply", "preview"]).optional(),
78161
+ expectedMailingListProviderScope: z$1.unknown().transform((value, ctx) => {
78162
+ if (value === void 0) return void 0;
78163
+ const parsed = parseMailingListProviderScope(value);
78164
+ if (parsed.ok) return parsed.value;
78165
+ ctx.addIssue({
78166
+ code: "custom",
78167
+ message: "Invalid mailing-list provider scope"
78168
+ });
78169
+ return z$1.NEVER;
78170
+ }).optional()
77363
78171
  }).strict();
77364
78172
  //#endregion
77365
78173
  //#region ../api/src/sdkThemeWire.ts
@@ -81988,6 +82796,7 @@ function readEntrySlotKey(block) {
81988
82796
  function admitEntrySlotBlock(block, customBlocks) {
81989
82797
  const base = {
81990
82798
  id: block.id ?? block.blockId ?? null,
82799
+ contentVersionId: block.contentVersionId,
81991
82800
  kind: block.kind,
81992
82801
  purpose: block.purpose,
81993
82802
  ...isRecord(block.bindings) ? { bindings: block.bindings } : {}