@riverbankcms/sdk 0.127.0 → 0.128.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 (152) hide show
  1. package/dist/{PreviewEditorSidebar-BXtfF7tp.mjs → PreviewEditorSidebar-Dbvb7GIr.mjs} +9 -33
  2. package/dist/{PreviewEditorUI-Dou73Q0K.mjs → PreviewEditorUI-e9O9l20X.mjs} +3 -3
  3. package/dist/{PreviewQueryProvider-DgFDIwvK.mjs → PreviewQueryProvider-B1kbhaJD.mjs} +1 -1
  4. package/dist/SdkPreviewModeRuntime-BZHt6e9w.mjs +11006 -0
  5. package/dist/{SiteChromeCustomizeContext-DZiDBAYu.mjs → SiteChromeCustomizeContext-CvuGbHJX.mjs} +31619 -1483
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +288 -36
  7. package/dist/_dts/api/src/bookingClosures.d.ts +19 -3
  8. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +4 -3
  9. package/dist/_dts/api/src/bookingRecords.d.ts +0 -13
  10. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +2 -2
  11. package/dist/_dts/api/src/communications.d.ts +2 -1
  12. package/dist/_dts/api/src/contactFormSummary.d.ts +15 -0
  13. package/dist/_dts/api/src/contentRuntime.d.ts +2 -5
  14. package/dist/_dts/api/src/endpoints.d.ts +1 -1
  15. package/dist/_dts/api/src/footerSettings.d.ts +11 -0
  16. package/dist/_dts/api/src/index.d.ts +2 -1
  17. package/dist/_dts/api/src/occurrenceScheduling.d.ts +48 -0
  18. package/dist/_dts/api/src/participantMessaging.d.ts +5 -3
  19. package/dist/_dts/api/src/publicExperience/siteEndpoints.d.ts +7 -0
  20. package/dist/_dts/api/src/sdkContracts.d.ts +7 -5
  21. package/dist/_dts/api/src/siteOperations.d.ts +12 -3
  22. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +3 -2
  23. package/dist/_dts/blocks/src/client/form.d.ts +1 -0
  24. package/dist/_dts/blocks/src/client/newsletter-form.d.ts +1 -0
  25. package/dist/_dts/blocks/src/client/site-chrome.d.ts +1 -0
  26. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -8
  27. package/dist/_dts/blocks/src/rendering/server.d.ts +1 -1
  28. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +41 -0
  29. package/dist/_dts/blocks/src/system/blocks/newsletter-signup-destination.d.ts +14 -23
  30. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +1 -1
  31. package/dist/_dts/blocks/src/system/blocks/site-footer-runtime.d.ts +109 -23
  32. package/dist/_dts/blocks/src/system/data/loaderEndpoints.d.ts +1 -1
  33. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +42 -108
  34. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +21 -54
  35. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +1 -1
  36. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationSurface.d.ts +26 -0
  37. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +8 -0
  38. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +21 -0
  39. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +29 -78
  40. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.server.d.ts +1 -1
  41. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.submission.d.ts +3 -6
  42. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +27 -8
  43. package/dist/_dts/content-editor/src/FooterComposerOverview.d.ts +21 -0
  44. package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +3 -1
  45. package/dist/_dts/content-editor/src/FooterEngagementEditorFields.d.ts +31 -0
  46. package/dist/_dts/content-editor/src/FooterEngagementEditorPanel.d.ts +17 -0
  47. package/dist/_dts/content-editor/src/footerComposer.d.ts +3 -0
  48. package/dist/_dts/content-editor/src/footerEngagementDraft.d.ts +57 -0
  49. package/dist/_dts/content-editor/src/footerEngagementEditor.d.ts +11 -0
  50. package/dist/_dts/content-editor/src/footerPreviewRuntime.d.ts +13 -0
  51. package/dist/_dts/content-editor/src/index.d.ts +1 -0
  52. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +35 -0
  53. package/dist/_dts/core/src/footer-arrangement.d.ts +2 -0
  54. package/dist/_dts/core/src/footer-composition-types.d.ts +118 -0
  55. package/dist/_dts/core/src/footer-composition.d.ts +7 -116
  56. package/dist/_dts/core/src/footer-engagement.d.ts +30 -0
  57. package/dist/_dts/core/src/index.d.ts +4 -0
  58. package/dist/_dts/core/src/newsletter-signup-destination.d.ts +38 -0
  59. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +59 -6
  60. package/dist/_dts/db/src/index.d.ts +1 -0
  61. package/dist/_dts/db/src/schemas/forms.d.ts +72 -2
  62. package/dist/_dts/db/src/schemas/standard-contact.d.ts +114 -0
  63. package/dist/_dts/preview-next/src/client/blocks/previewBatchLoaderParams.d.ts +6 -0
  64. package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +2 -5
  65. package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +2 -5
  66. package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -5
  67. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -4
  68. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +1 -1
  69. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +2 -4
  70. package/dist/_dts/preview-next/src/client/widgets/widgetOverrides.d.ts +6 -5
  71. package/dist/_dts/sdk/src/cli/commands/push/execute/footer.d.ts +9 -0
  72. package/dist/_dts/sdk/src/cli/content/footerFile.d.ts +10 -0
  73. package/dist/_dts/sdk/src/cli/content/reader.d.ts +3 -5
  74. package/dist/_dts/sdk/src/cli/site-commands/footerCommands.d.ts +15 -3
  75. package/dist/_dts/sdk/src/client/combineAbortSignals.d.ts +2 -0
  76. package/dist/_dts/sdk/src/client/management/types.d.ts +6 -15
  77. package/dist/_dts/sdk/src/client/types.d.ts +10 -2
  78. package/dist/_dts/sdk/src/client/wholeSeriesReadOperations.d.ts +11 -0
  79. package/dist/_dts/sdk/src/config/types.d.ts +1 -1
  80. package/dist/_dts/sdk/src/config/validation.d.ts +3 -0
  81. package/dist/_dts/sdk/src/contracts/event-registration-content.d.ts +16 -0
  82. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +4 -15
  83. package/dist/_dts/sdk/src/public-api/contracts.d.ts +4 -18
  84. package/dist/_dts/sdk/src/public-api/teamMemberContracts.d.ts +17 -0
  85. package/dist/_dts/sdk/src/public-api/wholeSeriesContracts.d.ts +2 -0
  86. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +7 -0
  87. package/dist/_dts/sdk/src/rendering/index.d.ts +5 -3
  88. package/dist/_dts/sdk/src/rendering/mediaAssets.d.ts +8 -2
  89. package/dist/_dts/sdk/src/version.d.ts +1 -1
  90. package/dist/_dts/site-commands/src/commandContract.d.ts +8 -1
  91. package/dist/_dts/site-commands/src/commands.d.ts +16 -2
  92. package/dist/_dts/theme-core/src/header/paintTargets.d.ts +10 -4
  93. package/dist/_dts/theme-core/src/header/surfaceRules.d.ts +2 -3
  94. package/dist/cli/index.mjs +5302 -4628
  95. package/dist/client/{courseRegistration-DTEYWL6Z.mjs → CourseRegistrationWizard-xRmA7REV.mjs} +329 -49
  96. package/dist/client/{DiscountCodeDisclosure-BDFRp8Y7.mjs → DiscountCodeDisclosure-B9vriL5C.mjs} +1 -1
  97. package/dist/client/{EventCombined.client-DJgF1_lf.mjs → EventCombined.client-BgVnVTlz.mjs} +2 -2
  98. package/dist/client/{EventListing.client-CnWGNjOr.mjs → EventListing.client-CqdsO7jO.mjs} +2 -2
  99. package/dist/client/{LeafletStaticMap-BISs9Bl7.mjs → LeafletStaticMap-CKPxot9M.mjs} +1 -1
  100. package/dist/client/{StepIndicator-D8gVYkK-.mjs → StepIndicator-DGCYuBJ1.mjs} +2 -2
  101. package/dist/client/{accordion-DFDajgDz.mjs → accordion-BfN5Eqd-.mjs} +1 -1
  102. package/dist/client/{bookingForm-Bdqj9-52.mjs → bookingForm-DOvCpBFP.mjs} +5 -5
  103. package/dist/client/{carousel-Cvqf-kN8.mjs → carousel-DPNmiH0f.mjs} +1 -1
  104. package/dist/client/{cart-CuH2TJXP.mjs → cart--egVXlrR.mjs} +3 -3
  105. package/dist/client/{checkout-CMNPpejZ.mjs → checkout-DywWtMcq.mjs} +3 -3
  106. package/dist/client/client.mjs +4912 -4613
  107. package/dist/client/courseRegistration-Dk9qFVwt.mjs +46 -0
  108. package/dist/client/{eventCalendar-BW-XoxZ0.mjs → eventCalendar-Bkz2HjlS.mjs} +4 -4
  109. package/dist/client/{eventCombined-Bpn7s0y9.mjs → eventCombined-D4kipYWg.mjs} +2 -2
  110. package/dist/client/{eventDetails-D2uUSTMH.mjs → eventDetails-Dz_5ix2Q.mjs} +56 -35
  111. package/dist/client/{eventListing-CVr1c094.mjs → eventListing-D0vm-zST.mjs} +2 -2
  112. package/dist/client/{eventRegistration-Dv4AvkMw.mjs → eventRegistration-Cw1E4Q4p.mjs} +58 -6
  113. package/dist/client/{form-DxdKf9fs.mjs → form-C2Zf1n3K.mjs} +1 -1
  114. package/dist/client/{headerSection-BaXI5Sro.mjs → headerSection-CP05gzdc.mjs} +2 -2
  115. package/dist/client/hooks.mjs +212 -61
  116. package/dist/client/{locationMap-BEtW2fKz.mjs → locationMap-Cl3x9PYJ.mjs} +2 -2
  117. package/dist/client/{newsletterForm-BKKs0S4R.mjs → newsletterForm-DyEJoClm.mjs} +26 -20
  118. package/dist/client/{pricing-ClkqcElA.mjs → pricing-DGuNR1W4.mjs} +1 -1
  119. package/dist/client/{productDetail-H-ru8dyy.mjs → productDetail-Cq-HrGew.mjs} +3 -3
  120. package/dist/client/{productList-Buyi5c0C.mjs → productList-DbB3jwqd.mjs} +3 -3
  121. package/dist/client/{propsDecoder-BF7i6Ijg.mjs → propsDecoder-CiTuhUwY.mjs} +130 -87
  122. package/dist/client/rendering/client.mjs +416 -208
  123. package/dist/client/rendering/islands.mjs +18 -18
  124. package/dist/client/rendering.mjs +5522 -5237
  125. package/dist/client/{scrollToBlock-D_7t8yWb.mjs → scrollToBlock-CShkRqab.mjs} +1 -1
  126. package/dist/client/{shop-CF7SZQNX.mjs → shop-Cu4Ib-ZA.mjs} +5 -5
  127. package/dist/client/{shop-commerce-DA7_Rq5p.mjs → shop-commerce-BzpsOdh7.mjs} +4 -4
  128. package/dist/client/{shop-commerce-store-BmLqW7Gh.mjs → shop-commerce-store-DaE7Fhj8.mjs} +1 -1
  129. package/dist/client/{shopShared-WL-E1znM.mjs → shopShared-cF0c20vB.mjs} +2 -2
  130. package/dist/client/{useEventFilters-rc8VLeLV.mjs → useEventFilters-QZ3HMgaJ.mjs} +2 -2
  131. package/dist/client/{usePolling-1ncrfd4S.mjs → usePolling-BKf0GcE-.mjs} +2 -2
  132. package/dist/preview-next/before-render.mjs +1 -1
  133. package/dist/preview-next/client/runtime.mjs +4 -4
  134. package/dist/preview-next/middleware.mjs +1 -1
  135. package/dist/{previewAuthStore-Dev9CdG9.mjs → previewAuthStore-BesgU5Xu.mjs} +1 -1
  136. package/dist/{sdk-runtime-BnrCCFJq.mjs → sdk-runtime-Cn_QSCOg.mjs} +2 -2
  137. package/dist/{separator-CFvBx2yl.mjs → separator-CEoGABRc.mjs} +1 -1
  138. package/dist/server/components.mjs +473 -289
  139. package/dist/server/config-validation.mjs +209 -61
  140. package/dist/server/config.mjs +209 -61
  141. package/dist/server/data.mjs +212 -61
  142. package/dist/server/index.mjs +40 -16
  143. package/dist/server/next.mjs +513 -307
  144. package/dist/server/page-converter.mjs +211 -64
  145. package/dist/server/prebuild.mjs +1 -1
  146. package/dist/server/rendering/server.mjs +475 -282
  147. package/dist/server/rendering.mjs +482 -290
  148. package/dist/server/routing.mjs +254 -80
  149. package/dist/server/server.mjs +252 -77
  150. package/package.json +1 -1
  151. package/dist/SdkPreviewModeRuntime-B0HPXr-l.mjs +0 -39546
  152. package/dist/client/MagicLinkForm-b5E_HoG9.mjs +0 -327
@@ -68,11 +68,11 @@ var UnsafePathSegmentError = class extends Error {
68
68
  function assertSafePathSegments(segments) {
69
69
  for (const segment of segments) if (typeof segment === "string" && UNSAFE_PATH_SEGMENTS.has(segment)) throw new UnsafePathSegmentError(segment);
70
70
  }
71
- function isRecord$37(value) {
71
+ function isRecord$39(value) {
72
72
  return typeof value === "object" && value !== null && !Array.isArray(value);
73
73
  }
74
74
  function isPathContainer(value) {
75
- return Array.isArray(value) || isRecord$37(value);
75
+ return Array.isArray(value) || isRecord$39(value);
76
76
  }
77
77
  function getContainerValue(container, segment) {
78
78
  if (typeof segment === "number") return Array.isArray(container) ? container[segment] : void 0;
@@ -7857,7 +7857,7 @@ const API_ENDPOINTS$1 = {
7857
7857
  path: "/sites/{siteId}/shop/orders/{orderId}/digital-fulfillment",
7858
7858
  method: "POST",
7859
7859
  auth: "user",
7860
- responseKind: "void",
7860
+ responseKind: "json",
7861
7861
  errors: [
7862
7862
  "resource:not_found",
7863
7863
  "validation:invalid_input",
@@ -7903,20 +7903,20 @@ function isApiError(result) {
7903
7903
  function isApiSuccess(result) {
7904
7904
  return result.success === true;
7905
7905
  }
7906
- function isRecord$36(value) {
7906
+ function isRecord$38(value) {
7907
7907
  return typeof value === "object" && value !== null && !Array.isArray(value);
7908
7908
  }
7909
7909
  function isFieldError(value) {
7910
- return isRecord$36(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
7910
+ return isRecord$38(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
7911
7911
  }
7912
7912
  function fieldErrorsFromUnknown(value) {
7913
7913
  if (!Array.isArray(value)) return null;
7914
7914
  return value.every(isFieldError) ? value : null;
7915
7915
  }
7916
7916
  function extractEnvelopeErrorObject(body) {
7917
- if (!isRecord$36(body)) return null;
7917
+ if (!isRecord$38(body)) return null;
7918
7918
  const error = body.error;
7919
- if (!isRecord$36(error)) return null;
7919
+ if (!isRecord$38(error)) return null;
7920
7920
  if ("success" in body && body.success !== false) return null;
7921
7921
  return error;
7922
7922
  }
@@ -8125,7 +8125,7 @@ function formatEventPricing(pricing, options = {}) {
8125
8125
  //#endregion
8126
8126
  //#region ../core/src/event-page-surface-subject.ts
8127
8127
  function parseEventPageSurfaceSubject(value) {
8128
- if (!isRecord$35(value)) return err$3({ kind: "notObject" });
8128
+ if (!isRecord$37(value)) return err$3({ kind: "notObject" });
8129
8129
  switch (value.kind) {
8130
8130
  case "eventSeries": {
8131
8131
  const eventSeriesId = parseEventSeriesId(value.eventSeriesId);
@@ -8168,7 +8168,7 @@ function parseEventPageSurfaceSubject(value) {
8168
8168
  });
8169
8169
  }
8170
8170
  }
8171
- function isRecord$35(value) {
8171
+ function isRecord$37(value) {
8172
8172
  return typeof value === "object" && value !== null && !Array.isArray(value);
8173
8173
  }
8174
8174
  //#endregion
@@ -8402,7 +8402,7 @@ function toLocationCoordinates(value) {
8402
8402
  }
8403
8403
  //#endregion
8404
8404
  //#region ../core/src/rich-text.ts
8405
- function isRecord$33(value) {
8405
+ function isRecord$35(value) {
8406
8406
  return typeof value === "object" && value !== null && !Array.isArray(value);
8407
8407
  }
8408
8408
  function hasOnlyKeys(value, allowed) {
@@ -8421,13 +8421,16 @@ function isDenseArrayOf(value, predicate) {
8421
8421
  return true;
8422
8422
  }
8423
8423
  function isTipTapMark(value) {
8424
- return isRecord$33(value) && hasOnlyKeys(value, markKeys) && typeof value.type === "string" && value.type.length > 0 && (value.attrs === void 0 || isRecord$33(value.attrs));
8424
+ return isRecord$35(value) && hasOnlyKeys(value, markKeys) && typeof value.type === "string" && value.type.length > 0 && (value.attrs === void 0 || isRecord$35(value.attrs));
8425
8425
  }
8426
8426
  function isTipTapNode(value) {
8427
- if (!isRecord$33(value) || !hasOnlyKeys(value, nodeKeys) || typeof value.type !== "string" || value.type.length === 0 || value.type === "doc" || value.attrs !== void 0 && !isRecord$33(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;
8427
+ if (!isRecord$35(value) || !hasOnlyKeys(value, nodeKeys) || typeof value.type !== "string" || value.type.length === 0 || value.type === "doc" || value.attrs !== void 0 && !isRecord$35(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;
8428
8428
  if (value.type === "text") return typeof value.text === "string" && value.text.length > 0 && value.content === void 0;
8429
8429
  return value.text === void 0;
8430
8430
  }
8431
+ function parseNewsletterSignupDestinationProvider(value) {
8432
+ return value === "riverbank" || value === "mailchimp" ? value : null;
8433
+ }
8431
8434
  new Map([
8432
8435
  "brand",
8433
8436
  "supporting-text",
@@ -8436,6 +8439,7 @@ new Map([
8436
8439
  "business-address",
8437
8440
  "contact",
8438
8441
  "opening-hours",
8442
+ "engagement",
8439
8443
  "legal-navigation",
8440
8444
  "legal"
8441
8445
  ].map((kind, index) => [kind, index]));
@@ -8748,9 +8752,9 @@ function formatKeyAsLabel(key) {
8748
8752
  }
8749
8753
  //#endregion
8750
8754
  //#region ../media-core/src/fileSafety.ts
8751
- const CONTROL_CHARACTER_PATTERN$1 = /[\u0000-\u001f\u007f]/u;
8755
+ const CONTROL_CHARACTER_PATTERN = /[\u0000-\u001f\u007f]/u;
8752
8756
  function containsUnsafePathSegmentCharacter(value) {
8753
- return value.includes("/") || value.includes("\\") || CONTROL_CHARACTER_PATTERN$1.test(value);
8757
+ return value.includes("/") || value.includes("\\") || CONTROL_CHARACTER_PATTERN.test(value);
8754
8758
  }
8755
8759
  function isReservedPathSegment(value) {
8756
8760
  return value === "." || value === "..";
@@ -25462,10 +25466,16 @@ function getHeaderPaintTargets(variant, themeId, state = "base") {
25462
25466
  ownerSelector: desktopOwner,
25463
25467
  selector: `${desktopOwner}::before`,
25464
25468
  mediaQuery: MQ_MD_UP,
25465
- topExtension: {
25466
- customProperty: "--rb-header-floating-top-gap",
25467
- value: "1rem",
25468
- ownerProperty: "top"
25469
+ extent: {
25470
+ top: {
25471
+ customProperty: "--rb-header-floating-top-gap",
25472
+ value: "1rem",
25473
+ ownerProperty: "top"
25474
+ },
25475
+ bottom: {
25476
+ customProperty: "--rb-header-floating-bottom-extension",
25477
+ value: "0.75rem"
25478
+ }
25469
25479
  },
25470
25480
  ownerNeedsPositioning: false
25471
25481
  }, {
@@ -25474,10 +25484,16 @@ function getHeaderPaintTargets(variant, themeId, state = "base") {
25474
25484
  ownerSelector: mobileOwner,
25475
25485
  selector: `${mobileOwner}::before`,
25476
25486
  mediaQuery: MQ_MD_DOWN,
25477
- topExtension: {
25478
- customProperty: "--rb-header-floating-top-gap",
25479
- value: "0.75rem",
25480
- ownerProperty: "margin-top"
25487
+ extent: {
25488
+ top: {
25489
+ customProperty: "--rb-header-floating-top-gap",
25490
+ value: "0.75rem",
25491
+ ownerProperty: "margin-top"
25492
+ },
25493
+ bottom: {
25494
+ customProperty: "--rb-header-floating-bottom-extension",
25495
+ value: "0.75rem"
25496
+ }
25481
25497
  },
25482
25498
  ownerNeedsPositioning: true
25483
25499
  }];
@@ -25518,10 +25534,11 @@ function renderHeaderPaintTargetRule(target, rules) {
25518
25534
  return `${target.selector} {\n ${[...pseudoElementSetup, ...rules].join("\n ")}\n}`;
25519
25535
  }
25520
25536
  case "viewport-band": {
25521
- const gap = target.topExtension;
25537
+ const { top, bottom } = target.extent;
25522
25538
  const ownerRules = [
25523
- `${gap.customProperty}: ${gap.value};`,
25524
- `${gap.ownerProperty}: var(${gap.customProperty});`,
25539
+ `${top.customProperty}: ${top.value};`,
25540
+ `${bottom.customProperty}: ${bottom.value};`,
25541
+ `${top.ownerProperty}: var(${top.customProperty});`,
25525
25542
  ...target.ownerNeedsPositioning ? ["position: relative;"] : [],
25526
25543
  "isolation: isolate;",
25527
25544
  "background: none;",
@@ -25533,8 +25550,8 @@ function renderHeaderPaintTargetRule(target, rules) {
25533
25550
  const bandRules = [
25534
25551
  "content: \"\";",
25535
25552
  "position: absolute;",
25536
- `top: calc(-1 * var(${gap.customProperty}));`,
25537
- "bottom: 0;",
25553
+ `top: calc(-1 * var(${top.customProperty}));`,
25554
+ `bottom: calc(-1 * var(${bottom.customProperty}));`,
25538
25555
  "left: 50%;",
25539
25556
  "width: 100vw;",
25540
25557
  "transform: translateX(-50%);",
@@ -25553,6 +25570,7 @@ const headerScrollTreatmentSchema = z$1.discriminatedUnion("kind", [z$1.object({
25553
25570
  kind: z$1.literal("contrast-glass"),
25554
25571
  backgroundTone: z$1.enum(["light", "dark"])
25555
25572
  })]).optional();
25573
+ const CONTRAST_GLASS_BLUR = "blur(12px)";
25556
25574
  function generateMobileOverlayBackdropFilterFix(themeId, variant) {
25557
25575
  const root = `:where([data-theme-scope="${themeId}"]) .header-root:has([data-nav-mobile-overlay][aria-hidden="false"])`;
25558
25576
  return `\n${(variant === "floating" ? [`${root} .header-mobile-bar`, `${root} .header-mobile-bar::before`] : [`${root}::before`]).join(",\n")} {\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n}\n`;
@@ -25562,7 +25580,12 @@ function generateHeaderScrollTreatmentStyles(treatment, themeId, variant, surfac
25562
25580
  switch (treatment.kind) {
25563
25581
  case "contrast-glass": {
25564
25582
  const backgroundChannels = treatment.backgroundTone === "dark" ? "0 0 0" : "255 255 255";
25565
- return renderHeaderPaintTargetRules(getHeaderPaintTargets(variant, themeId, "scrolled"), [`background-color: rgb(${backgroundChannels} / 0.60);`, ...surfaceRules]);
25583
+ return renderHeaderPaintTargetRules(getHeaderPaintTargets(variant, themeId, "scrolled"), [
25584
+ `background-color: rgb(${backgroundChannels} / 0.60);`,
25585
+ `backdrop-filter: ${CONTRAST_GLASS_BLUR};`,
25586
+ `-webkit-backdrop-filter: ${CONTRAST_GLASS_BLUR};`,
25587
+ ...surfaceRules
25588
+ ]);
25566
25589
  }
25567
25590
  }
25568
25591
  }
@@ -33889,6 +33912,7 @@ const newsletterFormFragment = defineFragment({
33889
33912
  }
33890
33913
  ],
33891
33914
  layout: [el("newsletter-form", withApiBindings({
33915
+ source: "block",
33892
33916
  destinationProvider: { $bind: { from: "destinationProvider" } },
33893
33917
  listId: { $bind: { from: "listId" } },
33894
33918
  preset: { $bind: { from: "preset" } },
@@ -35411,6 +35435,7 @@ const contactNewsletterLayout = styledSection({
35411
35435
  as: "h2",
35412
35436
  className: "newsletter-copy-title"
35413
35437
  }, when("newsletterTitle"), bind("newsletterTitle")), richText({ className: "newsletter-copy-subtitle rb-prose rb-max-w-none" }, when("newsletterSubtitle"), bind("newsletterSubtitle"))]), el("newsletter-form", withApiBindings({
35438
+ source: "block",
35414
35439
  listId: { $bind: { from: "listId" } },
35415
35440
  preset: { $bind: { from: "preset" } },
35416
35441
  includePhone: { $bind: { from: "includePhone" } },
@@ -37408,6 +37433,22 @@ const footerNavGroupsLayout = stack({
37408
37433
  }, [text({ as: "span" }, bind("entry.label"))], repeat("group.children", "entry"))])], repeat("footerMenu.groups", "group"))], whenCollectionHasItems("footerMenu.groups"));
37409
37434
  //#endregion
37410
37435
  //#region ../blocks/src/system/blocks/site-footer.ts
37436
+ const footerStandardContactBindings = {
37437
+ value: { $bind: { from: "module.engagement.runtime.value" } },
37438
+ submitLabel: { $bind: { from: "module.engagement.runtime.submitLabel" } },
37439
+ successMessage: { $bind: { from: "module.engagement.runtime.successMessage" } }
37440
+ };
37441
+ const footerMailingListBindings = {
37442
+ source: { $bind: { from: "module.engagement.runtime.source" } },
37443
+ destinationRef: { $bind: { from: "module.engagement.runtime.destinationRef" } },
37444
+ listId: { $bind: { from: "module.engagement.runtime.listId" } },
37445
+ preset: { $bind: { from: "module.engagement.runtime.preset" } },
37446
+ includePhone: { $bind: { from: "module.engagement.runtime.includePhone" } },
37447
+ buttonLabel: { $bind: { from: "module.engagement.runtime.buttonLabel" } },
37448
+ successMessage: { $bind: { from: "module.engagement.runtime.successMessage" } },
37449
+ privacyNote: { $bind: { from: "module.engagement.runtime.privacyNote" } }
37450
+ };
37451
+ const footerSpamProtectionBinding = { spamProtectionEnabled: { $bind: { from: "$root.spamProtectionEnabled" } } };
37411
37452
  const brandLogo = link({
37412
37453
  href: "/",
37413
37454
  className: { $bind: {
@@ -37485,6 +37526,23 @@ const authoredCopy = richText({
37485
37526
  id: "content.interpolateRichTextTokens",
37486
37527
  options: { tokens: ["year", "site_name"] }
37487
37528
  }] }));
37529
+ const footerEngagement = stack({
37530
+ gap: "md",
37531
+ className: "rb-w-full"
37532
+ }, [
37533
+ text({
37534
+ as: "p",
37535
+ className: "rb-body rb-opacity-80"
37536
+ }, bind("module.engagement.intro"), when("module.engagement.intro")),
37537
+ form(withApiBindings({
37538
+ ...footerStandardContactBindings,
37539
+ ...footerSpamProtectionBinding
37540
+ }), [], when("module.engagement.kind", { equals: "standard-contact" })),
37541
+ el("newsletter-form", withApiBindings({
37542
+ ...footerMailingListBindings,
37543
+ ...footerSpamProtectionBinding
37544
+ }), [], when("module.engagement.kind", { equals: "mailing-list" }))
37545
+ ], when("module.kind", { equals: "engagement" }));
37488
37546
  const footerGroup = stack({
37489
37547
  gap: "md",
37490
37548
  align: "stretch",
@@ -37510,6 +37568,7 @@ const footerGroup = stack({
37510
37568
  contact,
37511
37569
  hours,
37512
37570
  socials,
37571
+ footerEngagement,
37513
37572
  stack({ className: "rb-w-full" }, [authoredCopy], when("module.kind", { equals: "supporting-text" })),
37514
37573
  stack({ className: "rb-w-full rb-lg-col-span-3" }, [authoredCopy], when("module.kind", { equals: "legal" }))
37515
37574
  ], repeat("group.modules", "module"))], repeat("region.groups", "group"));
@@ -37517,6 +37576,10 @@ const footerMainRegion = stack({
37517
37576
  className: { $bind: { from: "region.className" } },
37518
37577
  "data-footer-region": { $bind: { from: "region.kind" } }
37519
37578
  }, [footerGroup], when("region.kind", { equals: "main" }), repeat("content.footerRuntime.regions", "region"));
37579
+ const footerEngagementRegion = stack({
37580
+ className: { $bind: { from: "region.className" } },
37581
+ "data-footer-region": "engagement-row"
37582
+ }, [footerGroup], when("region.kind", { equals: "engagement-row" }), repeat("content.footerRuntime.regions", "region"));
37520
37583
  const footerBottomRegion = stack({ className: { $bind: {
37521
37584
  from: "$root.theme.footer",
37522
37585
  transforms: [{ id: "layout.footerBottomBarContainerClass" }],
@@ -37552,7 +37615,11 @@ const siteFooterBlockDefinition = { manifest: createBlockManifest({
37552
37615
  fallback: mergeStyles(backgroundColorStyle("surface"), surfaceForegroundStyle({ text: "rgb(var(--tb-text))" }), borderColorStyle("border"))
37553
37616
  } },
37554
37617
  "data-footer-membership": { $bind: { from: "content.footerRuntime.membershipKey" } }
37555
- }, [footerMainRegion, footerBottomRegion]),
37618
+ }, [
37619
+ footerEngagementRegion,
37620
+ footerMainRegion,
37621
+ footerBottomRegion
37622
+ ]),
37556
37623
  description: "Site-wide composed footer with canonical shared details.",
37557
37624
  styleTokens: { spacing: "md" },
37558
37625
  paletteHidden: true
@@ -40135,7 +40202,7 @@ const publicMembershipProductCollectionSchema = z$1.object({ memberships: z$1.ar
40135
40202
  * Kept in a shared module so the block definition and runtime contracts can
40136
40203
  * depend on the same schema without creating an initialization cycle.
40137
40204
  */
40138
- const occurrenceContextSchema$1 = z$1.object({
40205
+ const occurrenceContextSchema = z$1.object({
40139
40206
  id: z$1.string(),
40140
40207
  seriesId: z$1.string(),
40141
40208
  startsAt: z$1.string(),
@@ -40535,28 +40602,37 @@ const EVENT_REGISTRATION_SHELL_STEP_LABELS = [
40535
40602
  "Payment"
40536
40603
  ];
40537
40604
  const eventRegistrationPublicEventSchema = z$1.preprocess(normalizeEventRegistrationEventInput, publicEventSchema);
40538
- const eventRegistrationSourceSchema = z$1.object({
40539
- siteId: z$1.string().optional(),
40540
- apiBaseUrl: z$1.string().optional(),
40541
- portalToken: z$1.string().nullable().optional(),
40542
- previewToken: z$1.string().nullable().optional(),
40543
- occurrenceContext: occurrenceContextSchema$1.optional(),
40605
+ const eventRegistrationHydrationSchemaShape = {
40606
+ occurrenceContext: occurrenceContextSchema.optional(),
40544
40607
  subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
40545
40608
  events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
40546
- className: z$1.string().nullable().optional(),
40547
- buttonText: z$1.string().nullable().optional(),
40548
- maxTickets: z$1.string().nullable().optional(),
40609
+ wholeSeriesOfferings: publicCoursesArraySchema.nullable().optional(),
40610
+ wholeSeriesOffering: publicCourseSchema.nullable().optional(),
40611
+ maxTickets: z$1.string().optional(),
40549
40612
  showVenue: z$1.boolean().optional(),
40550
40613
  showCapacity: z$1.boolean().optional(),
40614
+ showSessions: z$1.boolean().optional(),
40615
+ showPrice: z$1.boolean().optional(),
40551
40616
  successMessage: z$1.string().optional(),
40552
40617
  waitlistMessage: z$1.string().optional(),
40618
+ membershipMessage: z$1.string().optional(),
40553
40619
  buttonVariant: registrationButtonVariantSchema.optional(),
40554
40620
  overlayEnabled: z$1.boolean().optional(),
40555
40621
  spamProtectionEnabled: z$1.boolean().optional(),
40556
- stage: previewStageSchema.optional(),
40557
40622
  supportEmail: z$1.string().optional(),
40558
40623
  sitePasses: publicPassProductCollectionSchema.nullable().optional(),
40559
40624
  siteMemberships: publicMembershipProductCollectionSchema.nullable().optional()
40625
+ };
40626
+ const eventRegistrationSourceSchema = z$1.object({
40627
+ siteId: z$1.string().optional(),
40628
+ apiBaseUrl: z$1.string().optional(),
40629
+ portalToken: z$1.string().nullable().optional(),
40630
+ previewToken: z$1.string().nullable().optional(),
40631
+ ...eventRegistrationHydrationSchemaShape,
40632
+ className: z$1.string().nullable().optional(),
40633
+ buttonText: z$1.string().nullable().optional(),
40634
+ maxTickets: z$1.string().nullable().optional(),
40635
+ stage: previewStageSchema.optional()
40560
40636
  });
40561
40637
  const eventRegistrationDisplaySchema = z$1.object({
40562
40638
  kind: z$1.literal("event-registration"),
@@ -40567,22 +40643,7 @@ const eventRegistrationDisplaySchema = z$1.object({
40567
40643
  stepLabels: z$1.array(z$1.enum(EVENT_REGISTRATION_SHELL_STEP_LABELS)).min(1),
40568
40644
  summaryButtonText: z$1.string()
40569
40645
  });
40570
- const eventRegistrationHydrationSchema = z$1.object({
40571
- occurrenceContext: occurrenceContextSchema$1.optional(),
40572
- subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
40573
- events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
40574
- maxTickets: z$1.string().optional(),
40575
- showVenue: z$1.boolean().optional(),
40576
- showCapacity: z$1.boolean().optional(),
40577
- successMessage: z$1.string().optional(),
40578
- waitlistMessage: z$1.string().optional(),
40579
- buttonVariant: registrationButtonVariantSchema.optional(),
40580
- overlayEnabled: z$1.boolean().optional(),
40581
- spamProtectionEnabled: z$1.boolean().optional(),
40582
- supportEmail: z$1.string().optional(),
40583
- sitePasses: publicPassProductCollectionSchema.nullable().optional(),
40584
- siteMemberships: publicMembershipProductCollectionSchema.nullable().optional()
40585
- });
40646
+ const eventRegistrationHydrationSchema = z$1.object(eventRegistrationHydrationSchemaShape);
40586
40647
  const eventRegistrationRenderSchema = z$1.object({
40587
40648
  display: eventRegistrationDisplaySchema,
40588
40649
  hydration: eventRegistrationHydrationSchema
@@ -40662,11 +40723,16 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
40662
40723
  occurrenceContext: source.occurrenceContext ?? null,
40663
40724
  subject: source.subject ?? null,
40664
40725
  events: source.events ?? null,
40726
+ wholeSeriesOfferings: source.wholeSeriesOfferings ?? null,
40727
+ wholeSeriesOffering: source.wholeSeriesOffering ?? null,
40665
40728
  maxTickets: source.maxTickets ?? void 0,
40666
40729
  showVenue: source.showVenue,
40667
40730
  showCapacity: source.showCapacity,
40731
+ showSessions: source.showSessions,
40732
+ showPrice: source.showPrice,
40668
40733
  successMessage: source.successMessage,
40669
40734
  waitlistMessage: source.waitlistMessage,
40735
+ membershipMessage: source.membershipMessage,
40670
40736
  buttonVariant: source.buttonVariant,
40671
40737
  overlayEnabled: source.overlayEnabled,
40672
40738
  spamProtectionEnabled: source.spamProtectionEnabled,
@@ -40701,6 +40767,159 @@ function buildEventRegistrationInteractiveIslandProps(props) {
40701
40767
  source: props
40702
40768
  });
40703
40769
  }
40770
+ //#endregion
40771
+ //#region ../blocks/src/system/blocks/courses/shared/pricing.ts
40772
+ function isSaleWindowOpen(option, now) {
40773
+ if (!option.isActive) return false;
40774
+ if (option.saleStartsAt && new Date(option.saleStartsAt) > now) return false;
40775
+ if (option.saleEndsAt && new Date(option.saleEndsAt) < now) return false;
40776
+ return true;
40777
+ }
40778
+ function toExactOrFreeDisplay(amount, currency) {
40779
+ if (amount <= 0) return {
40780
+ kind: "free",
40781
+ currency
40782
+ };
40783
+ return {
40784
+ kind: "exact",
40785
+ amount,
40786
+ currency
40787
+ };
40788
+ }
40789
+ function getSelectableCoursePricingOptionsForNow(course, now) {
40790
+ if (course.pricing.pricingStrategy !== "tiered") return [];
40791
+ return [...course.pricing.options].filter((option) => isSaleWindowOpen(option, now)).sort((left, right) => {
40792
+ if (left.sortOrder !== right.sortOrder) return left.sortOrder - right.sortOrder;
40793
+ if (left.priceAmount !== right.priceAmount) return left.priceAmount - right.priceAmount;
40794
+ return left.name.localeCompare(right.name);
40795
+ });
40796
+ }
40797
+ function resolveCoursePricingState(course, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
40798
+ const selectedSlidingAmount = typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null;
40799
+ const effectiveNowInput = typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? selectedSlidingAmountOrNowInput : nowInput;
40800
+ const currency = course.pricing.currency;
40801
+ switch (course.pricing.pricingStrategy) {
40802
+ case "free": return {
40803
+ currency,
40804
+ display: {
40805
+ kind: "free",
40806
+ currency
40807
+ },
40808
+ selectableOptions: [],
40809
+ requiresSelection: false,
40810
+ selectedOption: null,
40811
+ slidingScale: null,
40812
+ selectedSlidingAmount: null,
40813
+ selectedPriceAmount: 0,
40814
+ selectedRequiresPayment: false,
40815
+ hasPaidSelection: false,
40816
+ hasFreeSelection: true
40817
+ };
40818
+ case "single": {
40819
+ const amount = course.pricing.singlePriceAmount ?? 0;
40820
+ return {
40821
+ currency,
40822
+ display: toExactOrFreeDisplay(amount, currency),
40823
+ selectableOptions: [],
40824
+ requiresSelection: false,
40825
+ selectedOption: null,
40826
+ slidingScale: null,
40827
+ selectedSlidingAmount: null,
40828
+ selectedPriceAmount: amount,
40829
+ selectedRequiresPayment: amount > 0,
40830
+ hasPaidSelection: amount > 0,
40831
+ hasFreeSelection: amount <= 0
40832
+ };
40833
+ }
40834
+ case "tiered": {
40835
+ const selectableOptions = getSelectableCoursePricingOptionsForNow(course, resolvePlanningDateInput(effectiveNowInput));
40836
+ const selectedOption = (selectedPricingOptionId ? selectableOptions.find((option) => option.id === selectedPricingOptionId) : null) ?? (selectableOptions.length === 1 ? selectableOptions[0] ?? null : null);
40837
+ const lowestAmount = selectableOptions.reduce((lowest, option) => {
40838
+ if (lowest === null || option.priceAmount < lowest) return option.priceAmount;
40839
+ return lowest;
40840
+ }, null);
40841
+ return {
40842
+ currency,
40843
+ display: lowestAmount === null ? {
40844
+ kind: "unavailable",
40845
+ currency
40846
+ } : selectableOptions.length > 1 && lowestAmount > 0 ? {
40847
+ kind: "from",
40848
+ amount: lowestAmount,
40849
+ currency
40850
+ } : toExactOrFreeDisplay(lowestAmount, currency),
40851
+ selectableOptions,
40852
+ requiresSelection: selectableOptions.length > 1,
40853
+ selectedOption,
40854
+ slidingScale: null,
40855
+ selectedSlidingAmount: null,
40856
+ selectedPriceAmount: selectedOption?.priceAmount ?? null,
40857
+ selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
40858
+ hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
40859
+ hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
40860
+ };
40861
+ }
40862
+ case "sliding_scale": {
40863
+ const minAmount = course.pricing.slidingMinAmount ?? null;
40864
+ const maxAmount = course.pricing.slidingMaxAmount ?? null;
40865
+ if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) return {
40866
+ currency,
40867
+ display: {
40868
+ kind: "unavailable",
40869
+ currency
40870
+ },
40871
+ selectableOptions: [],
40872
+ requiresSelection: true,
40873
+ selectedOption: null,
40874
+ slidingScale: null,
40875
+ selectedSlidingAmount: null,
40876
+ selectedPriceAmount: null,
40877
+ selectedRequiresPayment: false,
40878
+ hasPaidSelection: false,
40879
+ hasFreeSelection: false
40880
+ };
40881
+ const normalizedSelectedAmount = typeof selectedSlidingAmount === "number" && Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
40882
+ return {
40883
+ currency,
40884
+ display: {
40885
+ kind: "range",
40886
+ minAmount,
40887
+ maxAmount,
40888
+ currency
40889
+ },
40890
+ selectableOptions: [],
40891
+ requiresSelection: normalizedSelectedAmount === null,
40892
+ selectedOption: null,
40893
+ slidingScale: {
40894
+ minAmount,
40895
+ maxAmount,
40896
+ suggestedAmount: course.pricing.slidingSuggestedAmount ?? null
40897
+ },
40898
+ selectedSlidingAmount: normalizedSelectedAmount,
40899
+ selectedPriceAmount: normalizedSelectedAmount,
40900
+ selectedRequiresPayment: (normalizedSelectedAmount ?? 0) > 0,
40901
+ hasPaidSelection: maxAmount > 0,
40902
+ hasFreeSelection: minAmount === 0
40903
+ };
40904
+ }
40905
+ }
40906
+ }
40907
+ function formatCoursePriceDisplay(display, locale) {
40908
+ return formatBookingPriceDisplay(display, {
40909
+ decimals: "exact",
40910
+ locale
40911
+ });
40912
+ }
40913
+ function formatCoursePriceAmount(amount, currency, locale) {
40914
+ return formatCoursePriceDisplay(amount > 0 ? {
40915
+ kind: "exact",
40916
+ amount,
40917
+ currency
40918
+ } : {
40919
+ kind: "free",
40920
+ currency
40921
+ }, locale);
40922
+ }
40704
40923
  const eventRegistrationBlockDefinition = {
40705
40924
  manifest: createBlockManifest({
40706
40925
  id: "block.event-registration",
@@ -40796,6 +41015,24 @@ const eventRegistrationBlockDefinition = {
40796
41015
  defaultValue: true,
40797
41016
  ui: { intent: "display" }
40798
41017
  },
41018
+ {
41019
+ id: "showSessions",
41020
+ type: "boolean",
41021
+ label: "Show complete schedule",
41022
+ description: "Display every session for whole-series registrations",
41023
+ required: false,
41024
+ defaultValue: true,
41025
+ ui: { intent: "display" }
41026
+ },
41027
+ {
41028
+ id: "showPrice",
41029
+ type: "boolean",
41030
+ label: "Show price",
41031
+ description: "Display the whole-series price",
41032
+ required: false,
41033
+ defaultValue: true,
41034
+ ui: { intent: "display" }
41035
+ },
40799
41036
  {
40800
41037
  id: "successMessage",
40801
41038
  type: "text",
@@ -40806,6 +41043,26 @@ const eventRegistrationBlockDefinition = {
40806
41043
  defaultValue: "Thank you for registering! Check your email for confirmation details.",
40807
41044
  maxLength: 500
40808
41045
  },
41046
+ {
41047
+ id: "waitlistMessage",
41048
+ type: "text",
41049
+ label: "Waitlist message",
41050
+ description: "Message shown after joining a whole-series waitlist",
41051
+ required: false,
41052
+ multiline: true,
41053
+ defaultValue: "You've been added to the waitlist. We'll email you if a place becomes available.",
41054
+ maxLength: 500
41055
+ },
41056
+ {
41057
+ id: "membershipMessage",
41058
+ type: "text",
41059
+ label: "Membership registration message",
41060
+ description: "Message shown when a whole-series place is covered by membership",
41061
+ required: false,
41062
+ multiline: true,
41063
+ defaultValue: "Registered using your membership. Check your email for session details.",
41064
+ maxLength: 500
41065
+ },
40809
41066
  {
40810
41067
  id: "buttonText",
40811
41068
  type: "text",
@@ -40837,8 +41094,11 @@ const eventRegistrationBlockDefinition = {
40837
41094
  } },
40838
41095
  showVenue: { $bind: { from: "content.showVenue" } },
40839
41096
  showCapacity: { $bind: { from: "content.showCapacity" } },
41097
+ showSessions: { $bind: { from: "content.showSessions" } },
41098
+ showPrice: { $bind: { from: "content.showPrice" } },
40840
41099
  successMessage: { $bind: { from: "content.successMessage" } },
40841
41100
  waitlistMessage: { $bind: { from: "content.waitlistMessage" } },
41101
+ membershipMessage: { $bind: { from: "content.membershipMessage" } },
40842
41102
  buttonText: { $bind: {
40843
41103
  from: "content.buttonText",
40844
41104
  fallback: "Complete Registration"
@@ -40852,6 +41112,7 @@ const eventRegistrationBlockDefinition = {
40852
41112
  fallback: false
40853
41113
  } },
40854
41114
  events: { $bind: { from: "data.events" } },
41115
+ wholeSeriesOffering: { $bind: { from: "data.wholeSeriesOffering.offering" } },
40855
41116
  sitePasses: { $bind: { from: "data.sitePasses" } },
40856
41117
  siteMemberships: { $bind: { from: "data.siteMemberships" } },
40857
41118
  stage: { $bind: {
@@ -40865,9 +41126,10 @@ const eventRegistrationBlockDefinition = {
40865
41126
  runtime: eventRegistrationBlockRuntime,
40866
41127
  dataSchemas: {
40867
41128
  events: publicEventsArraySchema.optional(),
41129
+ wholeSeriesOffering: z$1.object({ offering: publicCourseSchema }).optional(),
40868
41130
  sitePasses: publicPassProductCollectionSchema.optional(),
40869
41131
  siteMemberships: publicMembershipProductCollectionSchema.optional(),
40870
- occurrenceContext: occurrenceContextSchema$1.optional()
41132
+ occurrenceContext: occurrenceContextSchema.optional()
40871
41133
  },
40872
41134
  dataLoaders: {
40873
41135
  events: {
@@ -40880,11 +41142,23 @@ const eventRegistrationBlockDefinition = {
40880
41142
  fallback: "published"
40881
41143
  } },
40882
41144
  readProfile: "registration",
40883
- seriesId: { $bind: { from: "$root.occurrenceContext.seriesId" } },
41145
+ seriesId: { $bind: { from: "$root.subject.eventSeriesId" } },
40884
41146
  includeOccurrenceId: { $bind: { from: "$root.occurrenceContext.id" } }
40885
41147
  },
40886
41148
  mode: "server"
40887
41149
  },
41150
+ wholeSeriesOffering: {
41151
+ endpoint: "getPublicWholeSeriesOffering",
41152
+ params: {
41153
+ siteId: { $bind: { from: "$root.siteId" } },
41154
+ eventSeriesId: { $bind: { from: "$root.subject.eventSeriesId" } },
41155
+ stage: { $bind: {
41156
+ from: "$root.previewStage",
41157
+ fallback: "published"
41158
+ } }
41159
+ },
41160
+ mode: "server"
41161
+ },
40888
41162
  sitePasses: {
40889
41163
  endpoint: "listPublicPasses",
40890
41164
  params: { siteId: { $bind: { from: "$root.siteId" } } },
@@ -40898,159 +41172,6 @@ const eventRegistrationBlockDefinition = {
40898
41172
  }
40899
41173
  };
40900
41174
  //#endregion
40901
- //#region ../blocks/src/system/blocks/courses/shared/pricing.ts
40902
- function isSaleWindowOpen(option, now) {
40903
- if (!option.isActive) return false;
40904
- if (option.saleStartsAt && new Date(option.saleStartsAt) > now) return false;
40905
- if (option.saleEndsAt && new Date(option.saleEndsAt) < now) return false;
40906
- return true;
40907
- }
40908
- function toExactOrFreeDisplay(amount, currency) {
40909
- if (amount <= 0) return {
40910
- kind: "free",
40911
- currency
40912
- };
40913
- return {
40914
- kind: "exact",
40915
- amount,
40916
- currency
40917
- };
40918
- }
40919
- function getSelectableCoursePricingOptionsForNow(course, now) {
40920
- if (course.pricing.pricingStrategy !== "tiered") return [];
40921
- return [...course.pricing.options].filter((option) => isSaleWindowOpen(option, now)).sort((left, right) => {
40922
- if (left.sortOrder !== right.sortOrder) return left.sortOrder - right.sortOrder;
40923
- if (left.priceAmount !== right.priceAmount) return left.priceAmount - right.priceAmount;
40924
- return left.name.localeCompare(right.name);
40925
- });
40926
- }
40927
- function resolveCoursePricingState(course, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
40928
- const selectedSlidingAmount = typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null;
40929
- const effectiveNowInput = typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? selectedSlidingAmountOrNowInput : nowInput;
40930
- const currency = course.pricing.currency;
40931
- switch (course.pricing.pricingStrategy) {
40932
- case "free": return {
40933
- currency,
40934
- display: {
40935
- kind: "free",
40936
- currency
40937
- },
40938
- selectableOptions: [],
40939
- requiresSelection: false,
40940
- selectedOption: null,
40941
- slidingScale: null,
40942
- selectedSlidingAmount: null,
40943
- selectedPriceAmount: 0,
40944
- selectedRequiresPayment: false,
40945
- hasPaidSelection: false,
40946
- hasFreeSelection: true
40947
- };
40948
- case "single": {
40949
- const amount = course.pricing.singlePriceAmount ?? 0;
40950
- return {
40951
- currency,
40952
- display: toExactOrFreeDisplay(amount, currency),
40953
- selectableOptions: [],
40954
- requiresSelection: false,
40955
- selectedOption: null,
40956
- slidingScale: null,
40957
- selectedSlidingAmount: null,
40958
- selectedPriceAmount: amount,
40959
- selectedRequiresPayment: amount > 0,
40960
- hasPaidSelection: amount > 0,
40961
- hasFreeSelection: amount <= 0
40962
- };
40963
- }
40964
- case "tiered": {
40965
- const selectableOptions = getSelectableCoursePricingOptionsForNow(course, resolvePlanningDateInput(effectiveNowInput));
40966
- const selectedOption = (selectedPricingOptionId ? selectableOptions.find((option) => option.id === selectedPricingOptionId) : null) ?? (selectableOptions.length === 1 ? selectableOptions[0] ?? null : null);
40967
- const lowestAmount = selectableOptions.reduce((lowest, option) => {
40968
- if (lowest === null || option.priceAmount < lowest) return option.priceAmount;
40969
- return lowest;
40970
- }, null);
40971
- return {
40972
- currency,
40973
- display: lowestAmount === null ? {
40974
- kind: "unavailable",
40975
- currency
40976
- } : selectableOptions.length > 1 && lowestAmount > 0 ? {
40977
- kind: "from",
40978
- amount: lowestAmount,
40979
- currency
40980
- } : toExactOrFreeDisplay(lowestAmount, currency),
40981
- selectableOptions,
40982
- requiresSelection: selectableOptions.length > 1,
40983
- selectedOption,
40984
- slidingScale: null,
40985
- selectedSlidingAmount: null,
40986
- selectedPriceAmount: selectedOption?.priceAmount ?? null,
40987
- selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
40988
- hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
40989
- hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
40990
- };
40991
- }
40992
- case "sliding_scale": {
40993
- const minAmount = course.pricing.slidingMinAmount ?? null;
40994
- const maxAmount = course.pricing.slidingMaxAmount ?? null;
40995
- if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) return {
40996
- currency,
40997
- display: {
40998
- kind: "unavailable",
40999
- currency
41000
- },
41001
- selectableOptions: [],
41002
- requiresSelection: true,
41003
- selectedOption: null,
41004
- slidingScale: null,
41005
- selectedSlidingAmount: null,
41006
- selectedPriceAmount: null,
41007
- selectedRequiresPayment: false,
41008
- hasPaidSelection: false,
41009
- hasFreeSelection: false
41010
- };
41011
- const normalizedSelectedAmount = typeof selectedSlidingAmount === "number" && Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
41012
- return {
41013
- currency,
41014
- display: {
41015
- kind: "range",
41016
- minAmount,
41017
- maxAmount,
41018
- currency
41019
- },
41020
- selectableOptions: [],
41021
- requiresSelection: normalizedSelectedAmount === null,
41022
- selectedOption: null,
41023
- slidingScale: {
41024
- minAmount,
41025
- maxAmount,
41026
- suggestedAmount: course.pricing.slidingSuggestedAmount ?? null
41027
- },
41028
- selectedSlidingAmount: normalizedSelectedAmount,
41029
- selectedPriceAmount: normalizedSelectedAmount,
41030
- selectedRequiresPayment: (normalizedSelectedAmount ?? 0) > 0,
41031
- hasPaidSelection: maxAmount > 0,
41032
- hasFreeSelection: minAmount === 0
41033
- };
41034
- }
41035
- }
41036
- }
41037
- function formatCoursePriceDisplay(display, locale) {
41038
- return formatBookingPriceDisplay(display, {
41039
- decimals: "exact",
41040
- locale
41041
- });
41042
- }
41043
- function formatCoursePriceAmount(amount, currency, locale) {
41044
- return formatCoursePriceDisplay(amount > 0 ? {
41045
- kind: "exact",
41046
- amount,
41047
- currency
41048
- } : {
41049
- kind: "free",
41050
- currency
41051
- }, locale);
41052
- }
41053
- //#endregion
41054
41175
  //#region ../blocks/src/system/runtime/nodes/course-registration.interactive.ts
41055
41176
  const courseRegistrationSourceSchema = z$1.object({
41056
41177
  siteId: z$1.string().optional(),
@@ -41485,15 +41606,6 @@ const eventDetailsManifest = createBlockManifest({
41485
41606
  })], { gap: "lg" })
41486
41607
  })]
41487
41608
  });
41488
- const occurrenceContextSchema = z$1.object({
41489
- id: z$1.string(),
41490
- seriesId: z$1.string(),
41491
- startsAt: z$1.string(),
41492
- endsAt: z$1.string(),
41493
- timeZone: z$1.string(),
41494
- capacityOverride: z$1.number().nullable().optional(),
41495
- overrides: z$1.record(z$1.string(), z$1.unknown()).nullable().optional()
41496
- }).nullable();
41497
41609
  const eventAutoApplyDiscountPreviewBaseSchema = z$1.object({
41498
41610
  id: z$1.string(),
41499
41611
  publicLabel: z$1.string(),
@@ -41528,8 +41640,9 @@ const eventDetailsBlockDefinition = {
41528
41640
  from: "$root.previewStage",
41529
41641
  fallback: "published"
41530
41642
  } },
41531
- limit: "25",
41532
- seriesId: { $bind: { from: "$root.occurrenceContext.seriesId" } },
41643
+ limit: "100",
41644
+ readProfile: "details",
41645
+ seriesId: { $bind: { from: "$root.subject.eventSeriesId" } },
41533
41646
  includeOccurrenceId: { $bind: { from: "$root.occurrenceContext.id" } }
41534
41647
  },
41535
41648
  mode: "server"
@@ -50294,9 +50407,6 @@ function parseSignedNewsletterDestinationRef(value) {
50294
50407
  const trimmed = parseTrimmedString$1(value);
50295
50408
  return trimmed && SIGNED_DESTINATION_REF_PATTERN.test(trimmed) ? trimmed : null;
50296
50409
  }
50297
- function parseNewsletterSignupDestinationProvider(value) {
50298
- return value === "riverbank" || value === "mailchimp" ? value : null;
50299
- }
50300
50410
  function buildNewsletterSignupBlockRef(blockId) {
50301
50411
  const parsed = parseNewsletterSignupBlockId(blockId);
50302
50412
  return parsed ? {
@@ -50463,19 +50573,9 @@ const newsletterFieldSchema = z$1.object({
50463
50573
  });
50464
50574
  const newsletterSignupBlockIdSchema = z$1.string().trim().min(1).transform(parseRequiredNewsletterSignupBlockId);
50465
50575
  const signedNewsletterDestinationRefSchema = z$1.string().trim().min(1).transform(parseRequiredSignedNewsletterDestinationRef);
50466
- const newsletterPublicDestinationRefSchema = z$1.discriminatedUnion("tag", [z$1.object({
50467
- tag: z$1.literal("block_ref"),
50468
- blockId: newsletterSignupBlockIdSchema
50469
- }), z$1.object({
50470
- tag: z$1.literal("signed_destination_ref"),
50471
- token: signedNewsletterDestinationRefSchema
50472
- })]);
50473
- const newsletterSourceSchema = z$1.object({
50474
- blockId: z$1.string().nullable().optional(),
50576
+ const newsletterSourceCommonSchema = z$1.object({
50475
50577
  siteId: z$1.string().optional(),
50476
50578
  apiBaseUrl: z$1.string().optional(),
50477
- listId: z$1.string().nullable().optional(),
50478
- destinationProvider: newsletterDestinationProviderSchema.nullable().optional(),
50479
50579
  preset: newsletterPresetSchema.optional(),
50480
50580
  includePhone: z$1.boolean().optional(),
50481
50581
  buttonLabel: z$1.string().nullable().optional(),
@@ -50486,6 +50586,25 @@ const newsletterSourceSchema = z$1.object({
50486
50586
  spamProtectionEnabled: z$1.boolean().optional(),
50487
50587
  className: z$1.string().nullable().optional()
50488
50588
  });
50589
+ const newsletterSourceSchema = z$1.discriminatedUnion("source", [
50590
+ newsletterSourceCommonSchema.extend({
50591
+ source: z$1.literal("block"),
50592
+ blockId: z$1.string().nullable().optional(),
50593
+ listId: z$1.string().nullable().optional(),
50594
+ destinationProvider: newsletterDestinationProviderSchema.nullable().optional()
50595
+ }),
50596
+ newsletterSourceCommonSchema.extend({
50597
+ source: z$1.literal("signed-footer"),
50598
+ destinationRef: z$1.object({
50599
+ tag: z$1.literal("signed_destination_ref"),
50600
+ token: signedNewsletterDestinationRefSchema
50601
+ })
50602
+ }),
50603
+ newsletterSourceCommonSchema.extend({
50604
+ source: z$1.literal("legacy-direct-list"),
50605
+ listId: z$1.string().nullable()
50606
+ })
50607
+ ]);
50489
50608
  const newsletterDisplaySchema = z$1.object({
50490
50609
  kind: z$1.literal("newsletter-form"),
50491
50610
  className: z$1.string().nullable(),
@@ -50496,8 +50615,26 @@ const newsletterDisplaySchema = z$1.object({
50496
50615
  fields: z$1.array(newsletterFieldSchema)
50497
50616
  });
50498
50617
  const newsletterHydrationSchema = z$1.object({
50499
- destinationRef: newsletterPublicDestinationRefSchema.nullable().optional(),
50500
- listId: z$1.string().nullable().optional(),
50618
+ target: z$1.discriminatedUnion("tag", [
50619
+ z$1.object({
50620
+ tag: z$1.literal("block-source"),
50621
+ destinationRef: z$1.object({
50622
+ tag: z$1.literal("block_ref"),
50623
+ blockId: newsletterSignupBlockIdSchema
50624
+ }).nullable()
50625
+ }),
50626
+ z$1.object({
50627
+ tag: z$1.literal("signed-footer-source"),
50628
+ destinationRef: z$1.object({
50629
+ tag: z$1.literal("signed_destination_ref"),
50630
+ token: signedNewsletterDestinationRefSchema
50631
+ })
50632
+ }),
50633
+ z$1.object({
50634
+ tag: z$1.literal("legacy-direct-list"),
50635
+ listId: z$1.string().nullable()
50636
+ })
50637
+ ]),
50501
50638
  preset: newsletterPresetSchema,
50502
50639
  includePhone: z$1.boolean(),
50503
50640
  tags: z$1.string().nullable().optional(),
@@ -50531,20 +50668,43 @@ const newsletterFormBlockRuntime = defineProgressiveBlockRuntime({
50531
50668
  render: createZodCodec(newsletterRenderSchema)
50532
50669
  },
50533
50670
  buildRender: (source) => {
50534
- const runtimeSource = deriveNewsletterSignupRuntimeSource(source);
50671
+ const runtimeSource = source.source === "block" ? deriveNewsletterSignupRuntimeSource(source) : null;
50535
50672
  return {
50536
50673
  display: buildNewsletterDisplay(source),
50537
50674
  hydration: {
50538
- destinationRef: buildNewsletterSignupBlockRef(source.blockId),
50539
- listId: runtimeSource.listId,
50675
+ target: projectNewsletterFormHydrationTarget(source),
50540
50676
  preset: source.preset ?? "emailOnly",
50541
50677
  includePhone: source.includePhone ?? false,
50542
- tags: runtimeSource.tags,
50678
+ tags: runtimeSource ? runtimeSource.tags : source.tags,
50543
50679
  spamProtectionEnabled: source.spamProtectionEnabled
50544
50680
  }
50545
50681
  };
50546
50682
  }
50547
50683
  });
50684
+ function projectNewsletterFormHydrationTarget(source) {
50685
+ switch (source.source) {
50686
+ case "block": {
50687
+ const destinationRef = buildNewsletterSignupBlockRef(source.blockId);
50688
+ if (destinationRef?.tag === "block_ref") return {
50689
+ tag: "block-source",
50690
+ destinationRef
50691
+ };
50692
+ return {
50693
+ tag: "legacy-direct-list",
50694
+ listId: source.listId ?? null
50695
+ };
50696
+ }
50697
+ case "signed-footer": return {
50698
+ tag: "signed-footer-source",
50699
+ destinationRef: source.destinationRef
50700
+ };
50701
+ case "legacy-direct-list": return {
50702
+ tag: "legacy-direct-list",
50703
+ listId: source.listId
50704
+ };
50705
+ default: return assertNever$24(source);
50706
+ }
50707
+ }
50548
50708
  function buildNewsletterFormInteractiveIslandProps(props) {
50549
50709
  return buildInteractiveIslandProps({
50550
50710
  runtime: newsletterFormBlockRuntime,
@@ -54870,6 +55030,33 @@ function uniqByOccurrenceId(events) {
54870
55030
  }
54871
55031
  return out;
54872
55032
  }
55033
+ function selectFromOccurrenceContext(events, occurrenceContext) {
55034
+ if (!occurrenceContext) return null;
55035
+ const byId = events.find((event) => event.occurrenceId === occurrenceContext.id || event.id === occurrenceContext.id);
55036
+ if (byId) return byId;
55037
+ const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
55038
+ startsAt: occurrenceContext.startsAt,
55039
+ timeZone: occurrenceContext.timeZone
55040
+ }));
55041
+ return events.find((event) => getBookingLocalDateKey(toScheduledBookingDateTime({
55042
+ startsAt: event.startsAt,
55043
+ timeZone: event.timeZone
55044
+ })) === contextDate) ?? null;
55045
+ }
55046
+ function selectNextUpcoming(events, nowIso) {
55047
+ return [...events].filter((event) => isFutureOrNow(event.startsAt, nowIso)).sort((left, right) => Date.parse(left.startsAt) - Date.parse(right.startsAt))[0] ?? null;
55048
+ }
55049
+ function selectCompletedWholeSeries(events) {
55050
+ if (events.length === 0 || !events.every((event) => event.bookingScope === "whole_series")) return null;
55051
+ return [...events].sort((left, right) => Date.parse(right.startsAt) - Date.parse(left.startsAt))[0] ?? null;
55052
+ }
55053
+ function selectRelatedDates(input) {
55054
+ if (!input.seriesId) return [];
55055
+ const isWholeSeries = input.selected?.bookingScope === "whole_series";
55056
+ const selectedOccurrenceId = input.selected ? input.selected.occurrenceId || input.selected.id : null;
55057
+ const dates = input.events.filter((event) => event.seriesId === input.seriesId).filter((event) => isWholeSeries || isFutureOrNow(event.startsAt, input.nowIso)).filter((event) => !selectedOccurrenceId || (event.occurrenceId || event.id) !== selectedOccurrenceId).sort((left, right) => Date.parse(left.startsAt) - Date.parse(right.startsAt));
55058
+ return isWholeSeries ? dates : dates.slice(0, input.limit);
55059
+ }
54873
55060
  function selectEventDetails(args) {
54874
55061
  const all = uniqByOccurrenceId(resolveEventRegistrationScopedEvents((args.events ?? []).filter(Boolean), {
54875
55062
  occurrenceContext: args.occurrenceContext,
@@ -54877,37 +55064,22 @@ function selectEventDetails(args) {
54877
55064
  }));
54878
55065
  const occurrenceContext = args.occurrenceContext ?? null;
54879
55066
  const otherLimit = parseLimit$1(args.otherDatesLimit, 5);
54880
- const selectedFromContext = (() => {
54881
- if (!occurrenceContext) return null;
54882
- const byId = all.find((e) => e.occurrenceId === occurrenceContext.id || e.id === occurrenceContext.id) ?? null;
54883
- if (byId) return byId;
54884
- const ctxDate = getBookingLocalDateKey(toScheduledBookingDateTime({
54885
- startsAt: occurrenceContext.startsAt,
54886
- timeZone: occurrenceContext.timeZone
54887
- }));
54888
- return all.find((e) => getBookingLocalDateKey(toScheduledBookingDateTime({
54889
- startsAt: e.startsAt,
54890
- timeZone: e.timeZone
54891
- })) === ctxDate) ?? null;
54892
- })();
54893
- const nextUpcoming = (() => {
54894
- const upcoming = all.filter((e) => isFutureOrNow(e.startsAt, args.nowIso));
54895
- upcoming.sort((a, b) => Date.parse(a.startsAt) - Date.parse(b.startsAt));
54896
- return upcoming[0] ?? null;
54897
- })();
54898
- const mode = selectedFromContext ? "selected" : "next";
54899
- const selected = selectedFromContext ?? nextUpcoming;
55067
+ const selectedFromContext = selectFromOccurrenceContext(all, occurrenceContext);
55068
+ const nextUpcoming = selectNextUpcoming(all, args.nowIso);
55069
+ const completedWholeSeries = selectCompletedWholeSeries(all);
55070
+ const selected = selectedFromContext ?? nextUpcoming ?? completedWholeSeries;
55071
+ const mode = selectedFromContext ? "selected" : nextUpcoming ? "next" : completedWholeSeries ? "completed" : "next";
54900
55072
  const timeZone = toBookingTimeZone(selected?.timeZone ?? all[0]?.timeZone ?? null);
54901
- const seriesId = occurrenceContext?.seriesId ?? selected?.seriesId ?? all[0]?.seriesId ?? null;
54902
- const selectedOccurrenceId = selected?.occurrenceId ?? null;
54903
55073
  return {
54904
55074
  mode,
54905
55075
  selected,
54906
- otherDates: seriesId ? all.filter((e) => e.seriesId === seriesId).filter((e) => isFutureOrNow(e.startsAt, args.nowIso)).filter((e) => {
54907
- const occId = e.occurrenceId || e.id;
54908
- if (selectedOccurrenceId && occId === selectedOccurrenceId) return false;
54909
- return true;
54910
- }).slice(0, otherLimit) : [],
55076
+ otherDates: selectRelatedDates({
55077
+ events: all,
55078
+ seriesId: occurrenceContext?.seriesId ?? selected?.seriesId ?? all[0]?.seriesId ?? null,
55079
+ selected,
55080
+ nowIso: args.nowIso,
55081
+ limit: otherLimit
55082
+ }),
54911
55083
  timeZone
54912
55084
  };
54913
55085
  }
@@ -55029,7 +55201,7 @@ function EventFacts({ selection, selected, venue, teamMembers, pricing }) {
55029
55201
  /* @__PURE__ */ jsxs("div", { children: [
55030
55202
  /* @__PURE__ */ jsx("div", {
55031
55203
  className: "rb-label rb-mb-2",
55032
- children: selection.mode === "next" ? "Next date" : "Date"
55204
+ children: selected.bookingScope === "whole_series" ? selection.mode === "next" ? "Next session" : "Selected session" : selection.mode === "next" ? "Next date" : "Date"
55033
55205
  }),
55034
55206
  /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("strong", { children: date }) }),
55035
55207
  /* @__PURE__ */ jsx("p", {
@@ -55067,18 +55239,27 @@ function EventFacts({ selection, selected, venue, teamMembers, pricing }) {
55067
55239
  }) : null] }, member.id))
55068
55240
  })]
55069
55241
  }) : null,
55070
- pricing
55242
+ pricing,
55243
+ selected.bookingScope === "whole_series" ? /* @__PURE__ */ jsxs("div", {
55244
+ className: "rb-mt-6",
55245
+ children: [/* @__PURE__ */ jsx("div", {
55246
+ className: "rb-label rb-mb-2",
55247
+ children: "Registration"
55248
+ }), /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("strong", { children: selected.wholeSeries?.enrollmentOpen ? "Open" : "Closed" }) })]
55249
+ }) : null
55071
55250
  ]
55072
55251
  });
55073
55252
  }
55074
55253
  function OtherEventDates({ selection }) {
55075
- if (selection.otherDates.length === 0) return null;
55254
+ const isWholeSeries = selection.selected?.bookingScope === "whole_series";
55255
+ const dates = isWholeSeries && selection.selected ? [selection.selected, ...selection.otherDates].sort((left, right) => Date.parse(left.startsAt) - Date.parse(right.startsAt)) : selection.otherDates;
55256
+ if (dates.length === 0) return null;
55076
55257
  return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
55077
55258
  className: "rb-label",
55078
- children: "Other dates"
55259
+ children: isWholeSeries ? "Session schedule" : "Other dates"
55079
55260
  }), /* @__PURE__ */ jsx("div", {
55080
55261
  className: "rb-mt-2 rb-tiles-grid",
55081
- children: selection.otherDates.map((event) => /* @__PURE__ */ jsx("a", {
55262
+ children: dates.map((event) => /* @__PURE__ */ jsx("a", {
55082
55263
  className: "rb-tile rb-tile--interactive",
55083
55264
  ...resolveEventLinkProps(event),
55084
55265
  children: /* @__PURE__ */ jsx(DateTimeTile, {
@@ -58277,13 +58458,13 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
58277
58458
  * Renders the newsletter signup form for SSR with hydration support.
58278
58459
  * Uses the islands architecture pattern to hydrate on the client.
58279
58460
  */
58280
- function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationProvider, preset = "emailOnly", includePhone, buttonLabel = "Subscribe", buttonVariant = "primary", successMessage, privacyNote, tags, spamProtectionEnabled, className }) {
58461
+ function NewsletterFormSSR(props) {
58462
+ const { siteId, apiBaseUrl, preset = "emailOnly", includePhone, buttonLabel = "Subscribe", buttonVariant = "primary", successMessage, privacyNote, tags, spamProtectionEnabled, className } = props;
58463
+ const blockId = props.source === "block" ? props.blockId : null;
58281
58464
  const islandProps = buildNewsletterFormInteractiveIslandProps({
58282
- blockId,
58465
+ ...props,
58283
58466
  siteId,
58284
58467
  apiBaseUrl,
58285
- listId,
58286
- destinationProvider,
58287
58468
  preset,
58288
58469
  includePhone,
58289
58470
  buttonLabel,
@@ -60585,30 +60766,24 @@ const NAV_DROPDOWN_CONTAINER_RAIL_CSS_RULES = [
60585
60766
  ];
60586
60767
  //#endregion
60587
60768
  //#region ../theme-core/src/header/surfaceRules.ts
60588
- /** Compile the visual surface declarations independently of paint geometry. */
60589
- function buildHeaderSurfaceRules(header, tokens, blur) {
60769
+ /** Compile the at-rest surface independently of scroll treatment and paint geometry. */
60770
+ function buildHeaderSurfaceRules(header, tokens) {
60590
60771
  const base = [];
60591
- const scrolled = [];
60592
60772
  const background = header.background;
60593
60773
  if (background.type === "color") base.push(`background-color: ${tokens.getColor(background.color || "surface")};`);
60594
60774
  else if (background.type === "gradient" && background.gradient) {
60595
60775
  const stops = background.gradient.stops.map((stop) => tokens.getColor(stop.color)).join(", ");
60596
60776
  base.push(`background-image: linear-gradient(${background.gradient.angle ?? 180}deg, ${stops});`);
60597
60777
  }
60598
- const blurRules = [`backdrop-filter: ${blur};`, `-webkit-backdrop-filter: ${blur};`];
60599
- base.push(...blurRules);
60600
- scrolled.push(...blurRules);
60601
60778
  const borderWidth = getComponentBorderWidthPx(header.border?.width ?? "none");
60602
60779
  if (!header.border || borderWidth === "0") return {
60603
60780
  base,
60604
- scrolled,
60605
60781
  border: []
60606
60782
  };
60607
60783
  const color = rgbColorValue(header.border.colorToken?.trim() || "border");
60608
60784
  const style = header.border.style === "dashed" ? "dashed" : "solid";
60609
60785
  return {
60610
60786
  base,
60611
- scrolled,
60612
60787
  border: header.border.position === "both" ? [`border-top: ${borderWidth} ${style} ${color};`, `border-bottom: ${borderWidth} ${style} ${color};`] : [`border-${header.border.position}: ${borderWidth} ${style} ${color};`]
60613
60788
  };
60614
60789
  }
@@ -60918,13 +61093,12 @@ function generateHeaderRootStyles(header, themeId, tokens) {
60918
61093
  rules.push("isolation: isolate;");
60919
61094
  const surfaceRules = isContainedNav ? {
60920
61095
  base: [],
60921
- scrolled: [],
60922
61096
  border: []
60923
- } : buildHeaderSurfaceRules(header, tokens, HEADER_BLUR);
61097
+ } : buildHeaderSurfaceRules(header, tokens);
60924
61098
  const floatingSurfaceBorder = header.variant === "floating";
60925
61099
  if (!floatingSurfaceBorder) rules.push(...surfaceRules.border);
60926
61100
  const basePaintRules = floatingSurfaceBorder ? [...surfaceRules.base, ...surfaceRules.border] : surfaceRules.base;
60927
- const scrolledPaintRules = floatingSurfaceBorder ? [...surfaceRules.scrolled, ...surfaceRules.border] : surfaceRules.scrolled;
61101
+ const scrolledPaintRules = floatingSurfaceBorder ? surfaceRules.border : [];
60928
61102
  if (header.positioning === "sticky" || header.positioning === "fixed") {
60929
61103
  const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "none");
60930
61104
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
@@ -77774,6 +77948,7 @@ const SUPPORTED_LOADER_ENDPOINTS$1 = [
77774
77948
  "listPublicRecurringSchedule",
77775
77949
  "getPublicEventDetails",
77776
77950
  "listPublicWholeSeriesOfferings",
77951
+ "getPublicWholeSeriesOffering",
77777
77952
  "listPublicRouteCandidates",
77778
77953
  "listPublicTeamMembers",
77779
77954
  "listPublicProducts",
@@ -79423,6 +79598,7 @@ const loaderAdapters = {
79423
79598
  listPublicEvents,
79424
79599
  listPublicRecurringSchedule,
79425
79600
  getPublicEventDetails,
79601
+ getPublicWholeSeriesOffering,
79426
79602
  listPublicRouteCandidates,
79427
79603
  listPublicTeamMembers,
79428
79604
  listPublicProducts,
@@ -79517,6 +79693,13 @@ async function listPublicEvents({ client, params }) {
79517
79693
  async function listPublicRecurringSchedule(input) {
79518
79694
  return projectRecurringSchedule(await listPublicEvents(input));
79519
79695
  }
79696
+ async function getPublicWholeSeriesOffering({ client, params }) {
79697
+ return await client.getPublicWholeSeriesOffering({
79698
+ siteId: requireStringParam(params, "siteId", "getPublicWholeSeriesOffering"),
79699
+ eventSeriesId: requireStringParam(params, "eventSeriesId", "getPublicWholeSeriesOffering"),
79700
+ stage: readStringParam(params, "stage")
79701
+ });
79702
+ }
79520
79703
  async function getPublicEventDetails({ client, params }) {
79521
79704
  return await client.getPublicEventDetails({
79522
79705
  siteId: requireStringParam(params, "siteId", "getPublicEventDetails"),
@@ -82850,8 +83033,7 @@ function toBlocksBlockOverrides(overrides) {
82850
83033
  };
82851
83034
  return result;
82852
83035
  }
82853
- function toBlocksDataContext(dataContext) {
82854
- if (!dataContext) return void 0;
83036
+ function toBlocksPageRendererDataContext(dataContext) {
82855
83037
  return {
82856
83038
  ...dataContext,
82857
83039
  mediaAssets: toBlocksMediaAssets(dataContext.mediaAssets),
@@ -82864,7 +83046,7 @@ function PageRenderer(props) {
82864
83046
  const blocksProps = {
82865
83047
  ...props,
82866
83048
  theme: blocksTheme,
82867
- dataContext: toBlocksDataContext(props.dataContext),
83049
+ dataContext: props.dataContext ? toBlocksPageRendererDataContext(props.dataContext) : void 0,
82868
83050
  blockOverrides: toBlocksBlockOverrides(props.blockOverrides),
82869
83051
  sdkConfig: blocksSdkConfig,
82870
83052
  customBlocks: normalizeSdkCustomBlocks(props.customBlocks)
@@ -84124,7 +84306,7 @@ var CircuitOpenError = class extends Error {
84124
84306
  * 1. This constant
84125
84307
  * 2. The "version" field in package.json
84126
84308
  */
84127
- const SDK_VERSION = "0.127.0";
84309
+ const SDK_VERSION = "0.128.0";
84128
84310
  //#endregion
84129
84311
  //#region src/next/content-load-failure.ts
84130
84312
  const SdkContentLoadError = RiverbankContentLoadError;
@@ -85309,6 +85491,39 @@ function createContentReadOperations(input) {
85309
85491
  };
85310
85492
  }
85311
85493
  //#endregion
85494
+ //#region src/client/wholeSeriesReadOperations.ts
85495
+ function createWholeSeriesReadOperations(deps) {
85496
+ return { async getPublicWholeSeriesOffering(params) {
85497
+ const { siteId, eventSeriesId, stage, signal } = params;
85498
+ if (!siteId) throw new Error("getPublicWholeSeriesOffering() requires siteId");
85499
+ if (!eventSeriesId) throw new Error("getPublicWholeSeriesOffering() requires eventSeriesId");
85500
+ const cacheKey = `public-whole-series-offering:${siteId}:${eventSeriesId}:${stage ?? ""}`;
85501
+ return deps.resilientFetchData(cacheKey, (requestSignal) => deps.apiClient({
85502
+ endpoint: "getPublicWholeSeriesOffering",
85503
+ params: {
85504
+ siteId,
85505
+ eventSeriesId,
85506
+ ...stage && { stage }
85507
+ },
85508
+ options: { signal: requestSignal }
85509
+ }), { signal });
85510
+ } };
85511
+ }
85512
+ //#endregion
85513
+ //#region src/client/combineAbortSignals.ts
85514
+ /** Combine signals into one that aborts when any input aborts. */
85515
+ function combineAbortSignals(...signals) {
85516
+ const controller = new AbortController();
85517
+ for (const signal of signals) {
85518
+ if (signal.aborted) {
85519
+ controller.abort(signal.reason);
85520
+ break;
85521
+ }
85522
+ signal.addEventListener("abort", () => controller.abort(signal.reason), { once: true });
85523
+ }
85524
+ return controller.signal;
85525
+ }
85526
+ //#endregion
85312
85527
  //#region src/client/index.ts
85313
85528
  let prebuildModule = null;
85314
85529
  function tryRequire(modulePath) {
@@ -85814,25 +86029,15 @@ function createRiverbankClientWithDeps(deps, config) {
85814
86029
  async function resilientFetchData(cacheKey, fetcher, options) {
85815
86030
  return (await resilientFetch(cacheKey, fetcher, options)).data;
85816
86031
  }
85817
- /**
85818
- * Combine multiple AbortSignals into one that aborts when any input aborts
85819
- */
85820
- function combineAbortSignals(...signals) {
85821
- const controller = new AbortController();
85822
- for (const signal of signals) {
85823
- if (signal.aborted) {
85824
- controller.abort(signal.reason);
85825
- break;
85826
- }
85827
- signal.addEventListener("abort", () => controller.abort(signal.reason), { once: true });
85828
- }
85829
- return controller.signal;
85830
- }
85831
86032
  const contentReads = createContentReadOperations({
85832
86033
  apiClient,
85833
86034
  resilientFetch,
85834
86035
  prebuildLoader
85835
86036
  });
86037
+ const wholeSeriesReads = createWholeSeriesReadOperations({
86038
+ apiClient,
86039
+ resilientFetchData
86040
+ });
85836
86041
  async function getEntriesInternal(params) {
85837
86042
  const { siteId, contentType, limit, offset, order, preview = false, mode, entryIds, includeMeta, signal } = params;
85838
86043
  const entryIdsCacheKey = mode === "manual" && entryIds?.length ? entryIds.join(",") : "";
@@ -85866,6 +86071,7 @@ function createRiverbankClientWithDeps(deps, config) {
85866
86071
  });
85867
86072
  }
85868
86073
  return {
86074
+ ...wholeSeriesReads,
85869
86075
  async getSite(params) {
85870
86076
  return (await contentReads.getSiteWithResilience(params)).data;
85871
86077
  },