@riverbankcms/sdk 0.126.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 (212) hide show
  1. package/dist/{PreviewEditorSidebar-DcYJxTgc.mjs → PreviewEditorSidebar-Dbvb7GIr.mjs} +64 -68
  2. package/dist/{PreviewEditorUI-Ctt1yTJr.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-C87qlKWw.mjs → SiteChromeCustomizeContext-CvuGbHJX.mjs} +51247 -20733
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +486 -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 +3 -10
  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/block-form/src/backend/store-backend.d.ts +2 -1
  24. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +1 -0
  25. package/dist/_dts/blocks/src/client/form.d.ts +1 -0
  26. package/dist/_dts/blocks/src/client/newsletter-form.d.ts +1 -0
  27. package/dist/_dts/blocks/src/client/site-chrome.d.ts +1 -0
  28. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -8
  29. package/dist/_dts/blocks/src/index.d.ts +3 -2
  30. package/dist/_dts/blocks/src/lib/media.d.ts +267 -0
  31. package/dist/_dts/blocks/src/rendering/server.d.ts +1 -1
  32. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +41 -0
  33. package/dist/_dts/blocks/src/system/blocks/newsletter-signup-destination.d.ts +14 -23
  34. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +1 -1
  35. package/dist/_dts/blocks/src/system/blocks/site-footer-runtime.d.ts +109 -23
  36. package/dist/_dts/blocks/src/system/constants/buttonRoles.d.ts +0 -13
  37. package/dist/_dts/blocks/src/system/data/loaderEndpoints.d.ts +1 -1
  38. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +42 -108
  39. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +21 -54
  40. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +1 -1
  41. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationSurface.d.ts +26 -0
  42. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +8 -0
  43. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +21 -0
  44. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +4 -4
  45. package/dist/_dts/blocks/src/system/runtime/nodes/mergeResolveImageUrlContexts.d.ts +7 -0
  46. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +29 -78
  47. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.server.d.ts +1 -1
  48. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.submission.d.ts +3 -6
  49. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +27 -8
  50. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +2 -2
  51. package/dist/_dts/content-editor/src/FooterComposerOverview.d.ts +21 -0
  52. package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +3 -1
  53. package/dist/_dts/content-editor/src/FooterEngagementEditorFields.d.ts +31 -0
  54. package/dist/_dts/content-editor/src/FooterEngagementEditorPanel.d.ts +17 -0
  55. package/dist/_dts/content-editor/src/footerComposer.d.ts +3 -0
  56. package/dist/_dts/content-editor/src/footerEngagementDraft.d.ts +57 -0
  57. package/dist/_dts/content-editor/src/footerEngagementEditor.d.ts +11 -0
  58. package/dist/_dts/content-editor/src/footerPreviewRuntime.d.ts +13 -0
  59. package/dist/_dts/content-editor/src/index.d.ts +1 -0
  60. package/dist/_dts/content-editor/src/ui/blockValidationManifestRegistry.d.ts +17 -0
  61. package/dist/_dts/content-editor/src/ui/blockValidationView.d.ts +1 -1
  62. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +4 -0
  63. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +35 -0
  64. package/dist/_dts/core/src/footer-arrangement.d.ts +2 -0
  65. package/dist/_dts/core/src/footer-composition-types.d.ts +118 -0
  66. package/dist/_dts/core/src/footer-composition.d.ts +7 -116
  67. package/dist/_dts/core/src/footer-engagement.d.ts +30 -0
  68. package/dist/_dts/core/src/index.d.ts +4 -0
  69. package/dist/_dts/core/src/newsletter-signup-destination.d.ts +38 -0
  70. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +200 -159
  71. package/dist/_dts/db/src/index.d.ts +1 -0
  72. package/dist/_dts/db/src/schemas/forms.d.ts +72 -2
  73. package/dist/_dts/db/src/schemas/standard-contact.d.ts +114 -0
  74. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +4 -0
  75. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockValidationManifests.d.ts +26 -0
  76. package/dist/_dts/editor-blocks/src/widgets/rich-text/imageInsert.d.ts +3 -3
  77. package/dist/_dts/media-editor/src/MediaEditor.d.ts +2 -2
  78. package/dist/_dts/media-editor/src/context.d.ts +1 -2
  79. package/dist/_dts/media-editor/src/index.d.ts +3 -1
  80. package/dist/_dts/media-editor/src/mediaSelection.d.ts +32 -0
  81. package/dist/_dts/media-editor/src/types.d.ts +3 -1
  82. package/dist/_dts/media-editor/src/useMediaSelection.d.ts +26 -0
  83. package/dist/_dts/preview-next/src/client/blocks/previewBatchLoaderParams.d.ts +6 -0
  84. package/dist/_dts/preview-next/src/client/index.d.ts +2 -0
  85. package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +2 -5
  86. package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +2 -5
  87. package/dist/_dts/preview-next/src/client/preview/HeaderMenuControls.d.ts +12 -0
  88. package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -5
  89. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -4
  90. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +13 -2
  91. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +8 -4
  92. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +4 -49
  93. package/dist/_dts/preview-next/src/client/preview/headerInteractionPaletteSurfaceState.d.ts +8 -0
  94. package/dist/_dts/preview-next/src/client/preview/previewThemeRoles.d.ts +15 -0
  95. package/dist/_dts/preview-next/src/client/preview/siteChromeCustomizeTypes.d.ts +54 -0
  96. package/dist/_dts/preview-next/src/client/preview/siteChromeLookRows.d.ts +13 -3
  97. package/dist/_dts/preview-next/src/client/preview/siteChromeNavQuickControlHistory.d.ts +3 -0
  98. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +6 -3
  99. package/dist/_dts/preview-next/src/client/widgets/widgetOverrides.d.ts +6 -5
  100. package/dist/_dts/sdk/src/cli/commands/push/execute/footer.d.ts +9 -0
  101. package/dist/_dts/sdk/src/cli/content/footerFile.d.ts +10 -0
  102. package/dist/_dts/sdk/src/cli/content/reader.d.ts +3 -5
  103. package/dist/_dts/sdk/src/cli/site-commands/footerCommands.d.ts +15 -3
  104. package/dist/_dts/sdk/src/client/combineAbortSignals.d.ts +2 -0
  105. package/dist/_dts/sdk/src/client/management/types.d.ts +6 -15
  106. package/dist/_dts/sdk/src/client/types.d.ts +10 -2
  107. package/dist/_dts/sdk/src/client/wholeSeriesReadOperations.d.ts +11 -0
  108. package/dist/_dts/sdk/src/config/types.d.ts +1 -1
  109. package/dist/_dts/sdk/src/config/validation.d.ts +3 -0
  110. package/dist/_dts/sdk/src/contracts/event-registration-content.d.ts +16 -0
  111. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +4 -15
  112. package/dist/_dts/sdk/src/public-api/contracts.d.ts +4 -18
  113. package/dist/_dts/sdk/src/public-api/teamMemberContracts.d.ts +17 -0
  114. package/dist/_dts/sdk/src/public-api/wholeSeriesContracts.d.ts +2 -0
  115. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +7 -0
  116. package/dist/_dts/sdk/src/rendering/index.d.ts +5 -3
  117. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +2 -2
  118. package/dist/_dts/sdk/src/rendering/mediaAssets.d.ts +8 -2
  119. package/dist/_dts/sdk/src/version.d.ts +1 -1
  120. package/dist/_dts/site-commands/src/commandContract.d.ts +8 -1
  121. package/dist/_dts/site-commands/src/commands.d.ts +16 -2
  122. package/dist/_dts/theme-core/src/buttons/effects/presets/background.d.ts +1 -1
  123. package/dist/_dts/theme-core/src/buttons/styles/registry.d.ts +0 -18
  124. package/dist/_dts/theme-core/src/buttons/types.d.ts +1 -3
  125. package/dist/_dts/theme-core/src/header/containerSchema.d.ts +20 -0
  126. package/dist/_dts/theme-core/src/header/generateHeaderCss.d.ts +1 -1
  127. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +14 -0
  128. package/dist/_dts/theme-core/src/header/legacyNavLinkStyle.d.ts +3 -0
  129. package/dist/_dts/theme-core/src/header/paintTargets.d.ts +31 -0
  130. package/dist/_dts/theme-core/src/header/scrollTreatment.d.ts +11 -0
  131. package/dist/_dts/theme-core/src/header/surfaceRules.d.ts +8 -0
  132. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +15 -0
  133. package/dist/_dts/theme-core/src/palette/colors.d.ts +1 -1
  134. package/dist/_dts/theme-core/src/schema.d.ts +67 -19
  135. package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +3 -51
  136. package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +4 -11
  137. package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +3 -51
  138. package/dist/_dts/theme-core/src/site-styles/headerInteractionPalette.d.ts +32 -0
  139. package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +19 -106
  140. package/dist/_dts/theme-core/src/site-styles/headerOpeningForeground.d.ts +22 -0
  141. package/dist/_dts/theme-core/src/site-styles/headerOpeningSection.d.ts +2 -0
  142. package/dist/_dts/theme-core/src/site-styles/headerStyleParts.d.ts +4 -0
  143. package/dist/_dts/theme-core/src/site-styles/index.d.ts +3 -0
  144. package/dist/_dts/theme-core/src/site-styles/lookOptionGroups.d.ts +24 -0
  145. package/dist/_dts/theme-core/src/site-styles/lookResolution.d.ts +1 -2
  146. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +4 -22
  147. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorOptions.d.ts +21 -0
  148. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +1 -1
  149. package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +4 -1
  150. package/dist/cli/index.mjs +6272 -5706
  151. package/dist/client/{courseRegistration-BcemLAdN.mjs → CourseRegistrationWizard-xRmA7REV.mjs} +329 -49
  152. package/dist/client/{DiscountCodeDisclosure-DS0AuFWW.mjs → DiscountCodeDisclosure-B9vriL5C.mjs} +1 -1
  153. package/dist/client/{EventCombined.client-DtMxLr7q.mjs → EventCombined.client-BgVnVTlz.mjs} +2 -2
  154. package/dist/client/{EventListing.client-BdLSRNg1.mjs → EventListing.client-CqdsO7jO.mjs} +2 -2
  155. package/dist/client/{LeafletStaticMap-BrpC6vsT.mjs → LeafletStaticMap-CKPxot9M.mjs} +1 -1
  156. package/dist/client/{StepIndicator-CBYPFVoy.mjs → StepIndicator-DGCYuBJ1.mjs} +2 -2
  157. package/dist/client/{accordion-BqqwPJWM.mjs → accordion-BfN5Eqd-.mjs} +1 -1
  158. package/dist/client/{bookingForm-SneP3yxC.mjs → bookingForm-DOvCpBFP.mjs} +5 -5
  159. package/dist/client/bookings.mjs +126 -23
  160. package/dist/client/{carousel-BTIR9L3I.mjs → carousel-DPNmiH0f.mjs} +1 -1
  161. package/dist/client/{cart-bqiqd8SX.mjs → cart--egVXlrR.mjs} +3 -3
  162. package/dist/client/{checkout-WbTFV5v4.mjs → checkout-DywWtMcq.mjs} +3 -3
  163. package/dist/client/client.mjs +6111 -5794
  164. package/dist/client/courseRegistration-Dk9qFVwt.mjs +46 -0
  165. package/dist/client/{eventCalendar-CsxIw0V_.mjs → eventCalendar-Bkz2HjlS.mjs} +4 -4
  166. package/dist/client/{eventCombined-B6XMoHfa.mjs → eventCombined-D4kipYWg.mjs} +2 -2
  167. package/dist/client/{eventDetails-BJaoPPfo.mjs → eventDetails-Dz_5ix2Q.mjs} +56 -35
  168. package/dist/client/{eventListing-DgwdYHRT.mjs → eventListing-D0vm-zST.mjs} +2 -2
  169. package/dist/client/{eventRegistration-C0O3folu.mjs → eventRegistration-Cw1E4Q4p.mjs} +58 -6
  170. package/dist/client/{form-Bk9txGFt.mjs → form-C2Zf1n3K.mjs} +1 -1
  171. package/dist/client/{headerSection-yIBt0yTv.mjs → headerSection-CP05gzdc.mjs} +2 -2
  172. package/dist/client/hooks.mjs +1013 -935
  173. package/dist/client/{locationMap-C-3KIpv-.mjs → locationMap-Cl3x9PYJ.mjs} +2 -2
  174. package/dist/client/{newsletterForm-CzB8g8h2.mjs → newsletterForm-DyEJoClm.mjs} +26 -20
  175. package/dist/client/{pricing-C1QeDes_.mjs → pricing-DGuNR1W4.mjs} +1 -1
  176. package/dist/client/{productDetail-w7SBp5uc.mjs → productDetail-Cq-HrGew.mjs} +3 -3
  177. package/dist/client/{productList-D0tGKHGf.mjs → productList-DbB3jwqd.mjs} +3 -3
  178. package/dist/client/{propsDecoder-Bcin2DB3.mjs → propsDecoder-CiTuhUwY.mjs} +257 -142
  179. package/dist/client/rendering/client.mjs +1342 -1122
  180. package/dist/client/rendering/islands.mjs +18 -18
  181. package/dist/client/rendering.mjs +6622 -6321
  182. package/dist/client/{scrollToBlock-h-o_STf_.mjs → scrollToBlock-CShkRqab.mjs} +1 -1
  183. package/dist/client/{shop-BGzmL8O_.mjs → shop-Cu4Ib-ZA.mjs} +5 -5
  184. package/dist/client/{shop-commerce-lX8QxjX-.mjs → shop-commerce-BzpsOdh7.mjs} +4 -4
  185. package/dist/client/{shop-commerce-store-CEurARtu.mjs → shop-commerce-store-DaE7Fhj8.mjs} +1 -1
  186. package/dist/client/{shopShared-DXxH8xxw.mjs → shopShared-cF0c20vB.mjs} +2 -2
  187. package/dist/client/{useEventFilters-B591g9vd.mjs → useEventFilters-QZ3HMgaJ.mjs} +2 -2
  188. package/dist/client/{usePolling-BvnChV4m.mjs → usePolling-BKf0GcE-.mjs} +2 -2
  189. package/dist/preview-next/before-render.mjs +1 -1
  190. package/dist/preview-next/client/runtime.mjs +4 -4
  191. package/dist/preview-next/middleware.mjs +1 -1
  192. package/dist/{previewAuthStore-Dev9CdG9.mjs → previewAuthStore-BesgU5Xu.mjs} +1 -1
  193. package/dist/{sdk-runtime-M__i3Jce.mjs → sdk-runtime-Cn_QSCOg.mjs} +2 -2
  194. package/dist/{separator-VSlnI9bc.mjs → separator-CEoGABRc.mjs} +1 -1
  195. package/dist/server/components.mjs +1750 -1614
  196. package/dist/server/config-validation.mjs +1010 -935
  197. package/dist/server/config.mjs +1010 -935
  198. package/dist/server/data.mjs +1013 -935
  199. package/dist/server/index.mjs +40 -16
  200. package/dist/server/next.mjs +1790 -1632
  201. package/dist/server/page-converter.mjs +1012 -938
  202. package/dist/server/prebuild.mjs +1 -1
  203. package/dist/server/rendering/server.mjs +1746 -1601
  204. package/dist/server/rendering.mjs +1759 -1615
  205. package/dist/server/routing.mjs +1123 -975
  206. package/dist/server/server.mjs +1053 -951
  207. package/dist/server/theme-bridge.mjs +151 -118
  208. package/dist/server/theme.mjs +111 -23
  209. package/package.json +1 -1
  210. package/dist/SdkPreviewModeRuntime-CvW1vdQ4.mjs +0 -39468
  211. package/dist/_dts/editor-blocks/src/widgets/rich-text/ensureRichTextImageAssetIdentifier.d.ts +0 -8
  212. package/dist/client/MagicLinkForm-Bt3IuLMy.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 === "..";
@@ -11774,6 +11778,99 @@ function createRichTextDoc(paragraphs) {
11774
11778
  } : { type: "paragraph" })
11775
11779
  };
11776
11780
  }
11781
+ const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
11782
+ "document",
11783
+ "spreadsheet",
11784
+ "archive",
11785
+ "audio"
11786
+ ];
11787
+ const hotspotSchema$1 = z.object({
11788
+ x: z.number().min(0).max(1),
11789
+ y: z.number().min(0).max(1),
11790
+ radius: z.number().optional()
11791
+ });
11792
+ const rotationSchema$1 = z.union([
11793
+ z.literal(0),
11794
+ z.literal(90),
11795
+ z.literal(180),
11796
+ z.literal(270)
11797
+ ]);
11798
+ const rectSchema$1 = z.tuple([
11799
+ z.number(),
11800
+ z.number(),
11801
+ z.number(),
11802
+ z.number()
11803
+ ]);
11804
+ const aspectCropSchema$1 = z.object({
11805
+ aspect: z.preprocess((value) => value == null ? void 0 : value, z.string().optional()),
11806
+ rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema$1.optional()),
11807
+ hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema$1.optional()),
11808
+ rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema$1.optional())
11809
+ });
11810
+ const transformSchema$1 = z.object({
11811
+ aspectCrops: z.preprocess((value) => {
11812
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
11813
+ return value;
11814
+ }, z.record(z.string(), aspectCropSchema$1.catch({}))).optional(),
11815
+ rect: rectSchema$1.optional(),
11816
+ hotspot: hotspotSchema$1.optional(),
11817
+ rotation: rotationSchema$1.optional()
11818
+ });
11819
+ const mediaPosterSchema = z.discriminatedUnion("tag", [z.object({
11820
+ tag: z.literal("storage"),
11821
+ assetId: z.string().optional(),
11822
+ storageBucket: z.string().min(1),
11823
+ storagePath: z.string().min(1)
11824
+ }), z.object({
11825
+ tag: z.literal("external-src"),
11826
+ assetId: z.string().optional(),
11827
+ src: z.string().url()
11828
+ })]);
11829
+ const mediaBaseSchema = z.object({
11830
+ purpose: z.string().optional(),
11831
+ placeholder: z.boolean().default(true).optional(),
11832
+ assetId: z.string().optional(),
11833
+ identifier: z.string().optional(),
11834
+ src: z.string().optional(),
11835
+ alt: z.string().optional(),
11836
+ filename: z.string().optional(),
11837
+ mimeType: z.string().optional(),
11838
+ width: z.number().optional(),
11839
+ height: z.number().optional(),
11840
+ storageBucket: z.string().optional(),
11841
+ storagePath: z.string().optional(),
11842
+ poster: mediaPosterSchema.optional(),
11843
+ transform: transformSchema$1.optional()
11844
+ });
11845
+ /**
11846
+ * Canonical identifier carried by media values that are safe to persist.
11847
+ * Parsing trims boundary input so downstream writers cannot retain whitespace-only
11848
+ * identifiers or independently disagree about normalization.
11849
+ */
11850
+ const mediaIdentifierSchema = z.string().trim().min(1).brand();
11851
+ const imageMediaSchema = mediaBaseSchema.extend({ type: z.literal("image") });
11852
+ const videoMediaSchema = mediaBaseSchema.extend({ type: z.literal("video") });
11853
+ const audioMediaSchema = mediaBaseSchema.extend({ type: z.literal("audio") });
11854
+ const documentMediaSchema = mediaBaseSchema.extend({ type: z.literal("document") });
11855
+ const spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z.literal("spreadsheet") });
11856
+ const archiveMediaSchema = mediaBaseSchema.extend({ type: z.literal("archive") });
11857
+ const mediaSchema$1 = z.discriminatedUnion("type", [
11858
+ imageMediaSchema,
11859
+ videoMediaSchema,
11860
+ audioMediaSchema,
11861
+ documentMediaSchema,
11862
+ spreadsheetMediaSchema,
11863
+ archiveMediaSchema
11864
+ ]);
11865
+ const persistableMediaBaseSchema = mediaBaseSchema.extend({ identifier: mediaIdentifierSchema });
11866
+ z.discriminatedUnion("type", [
11867
+ persistableMediaBaseSchema.extend({ type: z.literal("image") }),
11868
+ persistableMediaBaseSchema.extend({ type: z.literal("video") }),
11869
+ persistableMediaBaseSchema.extend({ type: z.literal("audio") }),
11870
+ persistableMediaBaseSchema.extend({ type: z.literal("document") }),
11871
+ persistableMediaBaseSchema.extend({ type: z.literal("spreadsheet") }),
11872
+ persistableMediaBaseSchema.extend({ type: z.literal("archive") })
11873
+ ]);
11777
11874
  //#endregion
11778
11875
  //#region ../blocks/src/system/manifest/fieldValidation/index.ts
11779
11876
  const TEL_RE = /^[+()0-9\s-]{3,}$/;
@@ -12063,7 +12160,7 @@ function canonicalizeFieldValueForWrite(plan, value) {
12063
12160
  case "media": {
12064
12161
  if (!isPlainObject$5(value)) return value;
12065
12162
  const canonical = { ...value };
12066
- if (typeof canonical.identifier === "string" && canonical.identifier.trim().length > 0) deleteEnvSpecificKeys(canonical);
12163
+ if (mediaIdentifierSchema.safeParse(canonical.identifier).success) deleteEnvSpecificKeys(canonical);
12067
12164
  return canonical;
12068
12165
  }
12069
12166
  case "group": return canonicalizeObjectForWrite(selectedGroupChildPlans(plan, value), value);
@@ -12158,7 +12255,7 @@ function normalizeObjectChildren(children, value, ctx) {
12158
12255
  function normalizeInlineTextFallbacks(plans, values, ctx) {
12159
12256
  for (const plan of plans) {
12160
12257
  if (plan.kind !== "inlineText" || !plan.plainTextFallbackPath) continue;
12161
- if (!isMissingForPlan(plan, values[plan.fieldId])) continue;
12258
+ if (!isMissingForPlan(plan, values[plan.fieldId]) && !(ctx.allowIncomplete && !parseInlineTextFromUnknown(values[plan.fieldId]).ok)) continue;
12162
12259
  const fallback = getAtFieldPath(values, plan.plainTextFallbackPath);
12163
12260
  if (typeof fallback !== "string" || fallback.trim().length === 0) continue;
12164
12261
  values[plan.fieldId] = normalizeFieldValue(plan, plainTextToInlineText(fallback), ctx);
@@ -12199,7 +12296,7 @@ function validateNormalizedFieldValue(plan, value, ctx) {
12199
12296
  case "select": return validateSelectPlan(plan, value);
12200
12297
  case "richText": return isValidRichTextDoc(value) ? [] : [issue(plan, "invalidRichText")];
12201
12298
  case "inlineText": return validateInlineTextPlan(plan, value);
12202
- case "media": return isPlainObject$5(value) && typeof value.identifier === "string" && value.identifier.trim().length > 0 && (value.type === void 0 || typeof value.type === "string" && plan.allowedMediaTypes.includes(value.type)) ? [] : [issue(plan, "invalidMedia")];
12299
+ case "media": return isPlainObject$5(value) && mediaIdentifierSchema.safeParse(value.identifier).success && (value.type === void 0 || typeof value.type === "string" && plan.allowedMediaTypes.includes(value.type)) ? [] : [issue(plan, "invalidMedia")];
12203
12300
  case "link": return linkSchema.safeParse(value).success ? [] : [issue(plan, "invalidLink")];
12204
12301
  case "repeater": return validateRepeaterPlan(plan, value, ctx);
12205
12302
  case "group": return validateGroupPlan(plan, value, ctx);
@@ -12918,6 +13015,17 @@ function asAccessibleSurfaceToken(token) {
12918
13015
  return token;
12919
13016
  }
12920
13017
  //#endregion
13018
+ //#region ../theme-core/src/site-styles/lookOptionGroups.ts
13019
+ function defineLookOptionGroup(group) {
13020
+ defaultOption(group);
13021
+ return group;
13022
+ }
13023
+ function defaultOption(group) {
13024
+ const option = group.options.find((candidate) => candidate.id === group.defaultOptionId);
13025
+ if (option) return option;
13026
+ throw new Error(`Look option group "${group.id}" defaults to missing option "${group.defaultOptionId}".`);
13027
+ }
13028
+ //#endregion
12921
13029
  //#region ../theme-core/src/site-styles/types.ts
12922
13030
  /**
12923
13031
  * Defines a literal-preserving catalog while rejecting top-level extra keys on
@@ -13063,767 +13171,655 @@ function defineBlockDesignCapability(capability) {
13063
13171
  //#region ../theme-core/src/site-styles/appearancePresetResolution.ts
13064
13172
  function assertValidOptionGroups(preset) {
13065
13173
  preset.optionGroups?.forEach((group) => {
13066
- if (!group.options.find((option) => option.id === group.selectedOptionId)) throw new Error(`Appearance preset "${preset.id}" option group "${group.id}" selects missing option "${group.selectedOptionId}".`);
13174
+ defineLookOptionGroup(group);
13067
13175
  });
13068
13176
  }
13069
13177
  function defineBlockAppearancePreset(preset) {
13070
13178
  assertValidOptionGroups(preset);
13071
13179
  return preset;
13072
13180
  }
13073
- [...[
13074
- defineBlockAppearancePreset({
13075
- kind: "block-design",
13076
- id: "hero-immersive-image",
13077
- target: "hero",
13078
- label: "Immersive image hero",
13079
- blockKinds: ["block.hero"],
13080
- constraints: { layoutFamilies: ["centered", "compact"] },
13081
- layoutPatches: [{
13082
- constraints: { layoutVariantKeys: ["micro"] },
13083
- designPatch: {
13084
- sectionHeight: "banner",
13085
- heroTypographyScale: "display"
13086
- }
13087
- }],
13088
- design: {
13089
- sectionSurface: "hero-image",
13090
- contentFrame: plainFrame,
13091
- itemSurface: "none",
13092
- sectionHeight: "hero",
13093
- heroComposition: "center",
13094
- heroTypographyScale: "display",
13095
- imageSurfaceTreatment: { kind: "neutral-wash" }
13181
+ //#endregion
13182
+ //#region ../theme-core/src/site-styles/blockAppearancePresets.ts
13183
+ const brandScrimOptionGroups = [{
13184
+ id: "image-surface-treatment",
13185
+ label: "Treatment",
13186
+ defaultOptionId: "brand-scrim-primary",
13187
+ options: [{
13188
+ id: "brand-scrim-primary",
13189
+ label: "Brand scrim",
13190
+ designPatch: { imageSurfaceTreatment: {
13191
+ kind: "brand-scrim",
13192
+ token: "primary"
13193
+ } }
13194
+ }, {
13195
+ id: "neutral-scrim",
13196
+ label: "Neutral scrim",
13197
+ designPatch: { imageSurfaceTreatment: { kind: "neutral-scrim" } }
13198
+ }]
13199
+ }];
13200
+ const microBannerLayoutPatches = [{
13201
+ constraints: { layoutVariantKeys: ["micro"] },
13202
+ designPatch: { sectionHeight: "banner" }
13203
+ }];
13204
+ defineBlockAppearancePreset({
13205
+ id: "hero-immersive-image",
13206
+ target: "hero",
13207
+ label: "Immersive image hero",
13208
+ blockKinds: ["block.hero"],
13209
+ constraints: { layoutFamilies: ["centered", "compact"] },
13210
+ layoutPatches: [{
13211
+ constraints: { layoutVariantKeys: ["micro"] },
13212
+ designPatch: {
13213
+ sectionHeight: "banner",
13214
+ heroTypographyScale: "display"
13096
13215
  }
13097
- }),
13098
- defineBlockAppearancePreset({
13099
- kind: "block-design",
13100
- id: "hero-bottom-left-panel",
13101
- target: "hero",
13102
- label: "Bottom-left panel hero",
13103
- blockKinds: ["block.hero"],
13104
- constraints: { layoutFamilies: ["centered", "compact"] },
13105
- optionGroups: [{
13106
- id: "image-surface-treatment",
13107
- label: "Treatment",
13108
- selectedOptionId: "neutral-scrim",
13109
- options: [{
13110
- id: "neutral-scrim",
13111
- label: "Neutral scrim",
13112
- designPatch: { imageSurfaceTreatment: {
13113
- kind: "neutral-scrim",
13114
- intensity: "balanced"
13115
- } }
13116
- }, {
13117
- id: "brand-scrim-primary",
13118
- label: "Brand scrim",
13119
- designPatch: { imageSurfaceTreatment: {
13120
- kind: "brand-scrim",
13121
- token: "primary",
13122
- intensity: "balanced"
13123
- } }
13124
- }]
13125
- }],
13126
- layoutPatches: [{
13127
- constraints: { layoutVariantKeys: ["micro"] },
13128
- designPatch: {
13129
- sectionHeight: "banner",
13130
- heroTypographyScale: "editorial"
13131
- }
13132
- }],
13133
- design: {
13134
- sectionSurface: "hero-image",
13135
- contentFrame: panelFrame("raised"),
13136
- itemSurface: "none",
13137
- sectionHeight: "immersive",
13138
- heroComposition: "bottom-left",
13139
- heroTypographyScale: "display",
13140
- imageSurfaceTreatment: {
13216
+ }],
13217
+ design: {
13218
+ sectionSurface: "hero-image",
13219
+ contentFrame: plainFrame,
13220
+ itemSurface: "none",
13221
+ sectionHeight: "hero",
13222
+ heroComposition: "center",
13223
+ heroTypographyScale: "display",
13224
+ imageSurfaceTreatment: { kind: "neutral-wash" }
13225
+ }
13226
+ }), defineBlockAppearancePreset({
13227
+ id: "hero-bottom-left-panel",
13228
+ target: "hero",
13229
+ label: "Bottom-left panel hero",
13230
+ blockKinds: ["block.hero"],
13231
+ constraints: { layoutFamilies: ["centered", "compact"] },
13232
+ optionGroups: [{
13233
+ id: "image-surface-treatment",
13234
+ label: "Treatment",
13235
+ defaultOptionId: "neutral-scrim",
13236
+ options: [{
13237
+ id: "neutral-scrim",
13238
+ label: "Neutral scrim",
13239
+ designPatch: { imageSurfaceTreatment: {
13141
13240
  kind: "neutral-scrim",
13142
13241
  intensity: "balanced"
13143
- }
13144
- }
13145
- }),
13146
- defineBlockAppearancePreset({
13147
- kind: "block-design",
13148
- id: "hero-poster-image",
13149
- target: "hero",
13150
- label: "Poster image hero",
13151
- blockKinds: ["block.hero"],
13152
- constraints: { layoutFamilies: ["centered", "compact"] },
13153
- layoutPatches: [{
13154
- constraints: { layoutVariantKeys: ["micro"] },
13155
- designPatch: {
13156
- sectionHeight: "banner",
13157
- heroTypographyScale: "display"
13158
- }
13159
- }],
13160
- design: {
13161
- sectionSurface: "hero-image",
13162
- contentFrame: plainFrame,
13163
- itemSurface: "none",
13164
- sectionHeight: "immersive",
13165
- heroComposition: "center",
13166
- heroTypographyScale: "poster",
13167
- imageSurfaceTreatment: {
13242
+ } }
13243
+ }, {
13244
+ id: "brand-scrim-primary",
13245
+ label: "Brand scrim",
13246
+ designPatch: { imageSurfaceTreatment: {
13168
13247
  kind: "brand-scrim",
13169
13248
  token: "primary",
13170
- intensity: "strong"
13171
- }
13172
- }
13173
- }),
13174
- defineBlockAppearancePreset({
13175
- kind: "block-design",
13176
- id: "hero-brand-scrim",
13177
- target: "hero",
13178
- label: "Brand scrim image hero",
13179
- blockKinds: ["block.hero"],
13180
- constraints: { layoutFamilies: ["centered", "compact"] },
13181
- optionGroups: [{
13182
- id: "image-surface-treatment",
13183
- label: "Treatment",
13184
- selectedOptionId: "brand-scrim-primary",
13185
- options: [{
13186
- id: "brand-scrim-primary",
13187
- label: "Brand scrim",
13188
- designPatch: { imageSurfaceTreatment: {
13189
- kind: "brand-scrim",
13190
- token: "primary"
13191
- } }
13192
- }, {
13193
- id: "neutral-scrim",
13194
- label: "Neutral scrim",
13195
- designPatch: { imageSurfaceTreatment: { kind: "neutral-scrim" } }
13196
- }]
13197
- }],
13198
- layoutPatches: [{
13199
- constraints: { layoutVariantKeys: ["micro"] },
13200
- designPatch: { sectionHeight: "banner" }
13201
- }],
13202
- design: {
13203
- sectionSurface: "hero-image",
13204
- contentFrame: plainFrame,
13205
- itemSurface: "none",
13206
- sectionHeight: "immersive",
13207
- heroComposition: "center",
13208
- heroTypographyScale: "display",
13209
- imageSurfaceTreatment: {
13210
- kind: "brand-scrim",
13211
- token: "primary"
13212
- }
13213
- }
13214
- }),
13215
- defineBlockAppearancePreset({
13216
- kind: "block-design",
13217
- id: "hero-brand-scrim-fixed-frame",
13218
- target: "hero",
13219
- label: "Fixed-frame brand scrim hero",
13220
- blockKinds: ["block.hero"],
13221
- constraints: { layoutFamilies: ["centered", "compact"] },
13222
- optionGroups: [{
13223
- id: "image-surface-treatment",
13224
- label: "Treatment",
13225
- selectedOptionId: "brand-scrim-primary",
13226
- options: [{
13227
- id: "brand-scrim-primary",
13228
- label: "Brand scrim",
13229
- designPatch: { imageSurfaceTreatment: {
13230
- kind: "brand-scrim",
13231
- token: "primary"
13232
- } }
13233
- }, {
13234
- id: "neutral-scrim",
13235
- label: "Neutral scrim",
13236
- designPatch: { imageSurfaceTreatment: { kind: "neutral-scrim" } }
13237
- }]
13238
- }],
13239
- layoutPatches: [{
13240
- constraints: { layoutVariantKeys: ["micro"] },
13241
- designPatch: { sectionHeight: "banner" }
13242
- }],
13243
- design: {
13244
- sectionSurface: "hero-image",
13245
- contentFrame: plainFrame,
13246
- itemSurface: "none",
13247
- sectionHeight: "immersive",
13248
- heroComposition: "center",
13249
- heroTypographyScale: "display",
13250
- imageSurfaceTreatment: {
13251
- kind: "brand-scrim",
13252
- token: "primary"
13253
- },
13254
- imageSurfaceMotion: "fixed-frame",
13255
- eyebrowTreatment: "accent-pill-bounce"
13256
- }
13257
- }),
13258
- defineBlockAppearancePreset({
13259
- kind: "block-design",
13260
- id: "hero-brand-depth-expressive",
13261
- target: "hero",
13262
- label: "Expressive brand-depth hero",
13263
- blockKinds: ["block.hero"],
13264
- constraints: { layoutFamilies: ["centered", "compact"] },
13265
- design: {
13266
- sectionSurface: "brand-depth-band",
13267
- contentFrame: plainFrame,
13268
- itemSurface: "none",
13269
- heroComposition: "center",
13270
- heroTypographyScale: "editorial",
13271
- eyebrowTreatment: "accent-pill-bounce"
13272
- }
13273
- }),
13274
- defineBlockAppearancePreset({
13275
- kind: "block-design",
13276
- id: "hero-contained-intro",
13277
- target: "hero",
13278
- label: "Contained intro hero",
13279
- blockKinds: ["block.hero"],
13280
- design: {
13281
- sectionSurface: "muted-band",
13282
- contentFrame: panelFrame("inset"),
13283
- itemSurface: "none",
13284
- heroComposition: "center",
13285
- heroTypographyScale: "editorial"
13286
- }
13287
- }),
13288
- defineBlockAppearancePreset({
13289
- kind: "block-design",
13290
- id: "hero-split-editorial",
13291
- target: "hero",
13292
- label: "Editorial split hero",
13293
- blockKinds: ["block.hero"],
13294
- constraints: { layoutFamilies: ["split"] },
13295
- design: {
13296
- sectionSurface: "base",
13297
- contentFrame: plainFrame,
13298
- itemSurface: "none",
13299
- heroTypographyScale: "editorial"
13300
- }
13301
- }),
13302
- defineBlockAppearancePreset({
13303
- kind: "block-design",
13304
- id: "hero-split-brand",
13305
- target: "hero",
13306
- label: "Brand split hero",
13307
- blockKinds: ["block.hero"],
13308
- constraints: { layoutFamilies: ["split"] },
13309
- design: {
13310
- sectionSurface: "brand-depth-band",
13311
- contentFrame: plainFrame,
13312
- itemSurface: "none",
13313
- heroTypographyScale: "display",
13314
- eyebrowTreatment: "accent-pill-bounce"
13315
- }
13316
- }),
13317
- defineBlockAppearancePreset({
13318
- kind: "block-design",
13319
- id: "hero-split-soft-panel",
13320
- target: "hero",
13321
- label: "Soft panel split hero",
13322
- blockKinds: ["block.hero"],
13323
- constraints: { layoutFamilies: ["split"] },
13324
- design: {
13325
- sectionSurface: "muted-band",
13326
- contentFrame: panelFrame("raised"),
13327
- itemSurface: "none",
13249
+ intensity: "balanced"
13250
+ } }
13251
+ }]
13252
+ }],
13253
+ layoutPatches: [{
13254
+ constraints: { layoutVariantKeys: ["micro"] },
13255
+ designPatch: {
13256
+ sectionHeight: "banner",
13328
13257
  heroTypographyScale: "editorial"
13329
13258
  }
13330
- }),
13331
- defineBlockAppearancePreset({
13332
- kind: "block-design",
13333
- id: "hero-split-accent",
13334
- target: "hero",
13335
- label: "Accent split hero",
13336
- blockKinds: ["block.hero"],
13337
- constraints: { layoutFamilies: ["split"] },
13338
- design: {
13339
- sectionSurface: "accent-band",
13340
- contentFrame: panelFrame("raised"),
13341
- itemSurface: "none",
13259
+ }],
13260
+ design: {
13261
+ sectionSurface: "hero-image",
13262
+ contentFrame: panelFrame("raised"),
13263
+ itemSurface: "none",
13264
+ sectionHeight: "immersive",
13265
+ heroComposition: "bottom-left",
13266
+ heroTypographyScale: "display",
13267
+ imageSurfaceTreatment: {
13268
+ kind: "neutral-scrim",
13269
+ intensity: "balanced"
13270
+ }
13271
+ }
13272
+ }), defineBlockAppearancePreset({
13273
+ id: "hero-poster-image",
13274
+ target: "hero",
13275
+ label: "Poster image hero",
13276
+ blockKinds: ["block.hero"],
13277
+ constraints: { layoutFamilies: ["centered", "compact"] },
13278
+ layoutPatches: [{
13279
+ constraints: { layoutVariantKeys: ["micro"] },
13280
+ designPatch: {
13281
+ sectionHeight: "banner",
13342
13282
  heroTypographyScale: "display"
13343
13283
  }
13344
- }),
13345
- defineBlockAppearancePreset({
13346
- kind: "block-design",
13347
- id: "intro-editorial-statement",
13348
- target: "intro",
13349
- label: "Editorial intro statement",
13350
- blockKinds: ["block.intro"],
13351
- constraints: { layoutVariantKeys: ["centered-copy", "statement-copy"] },
13352
- design: {
13353
- sectionSurface: "base",
13354
- contentFrame: plainFrame,
13355
- itemSurface: "none",
13356
- composition: {
13357
- kind: "intro",
13358
- treatment: "editorial-statement"
13359
- }
13360
- }
13361
- }),
13362
- defineBlockAppearancePreset({
13363
- kind: "block-design",
13364
- id: "intro-portrait-bio",
13365
- target: "intro",
13366
- label: "Portrait and bio",
13367
- blockKinds: ["block.intro"],
13368
- constraints: { layoutVariantKeys: ["media-copy"] },
13369
- design: {
13370
- sectionSurface: "base",
13371
- contentFrame: plainFrame,
13372
- itemSurface: "none",
13373
- composition: {
13374
- kind: "intro",
13375
- treatment: "portrait-bio"
13376
- }
13377
- }
13378
- }),
13379
- defineBlockAppearancePreset({
13380
- kind: "block-design",
13381
- id: "offerings-preview-default-cards",
13382
- target: "offerings",
13383
- label: "Default offering cards",
13384
- blockKinds: ["block.offerings-preview"],
13385
- design: {
13386
- sectionSurface: "base",
13387
- contentFrame: plainFrame,
13388
- itemSurface: "default"
13389
- }
13390
- }),
13391
- defineBlockAppearancePreset({
13392
- kind: "block-design",
13393
- id: "offerings-preview-secondary-cards",
13394
- target: "offerings",
13395
- label: "Secondary offering cards",
13396
- blockKinds: ["block.offerings-preview"],
13397
- design: {
13398
- sectionSurface: "muted-band",
13399
- contentFrame: plainFrame,
13400
- itemSurface: "inset"
13401
- }
13402
- }),
13403
- defineBlockAppearancePreset({
13404
- kind: "block-design",
13405
- id: "offerings-preview-non-carded",
13406
- target: "offerings",
13407
- label: "Non-carded offerings",
13408
- blockKinds: ["block.offerings-preview"],
13409
- design: {
13410
- sectionSurface: "muted-band",
13411
- contentFrame: plainFrame,
13412
- itemSurface: "editorial"
13413
- }
13414
- }),
13415
- defineBlockAppearancePreset({
13416
- kind: "block-design",
13417
- id: "offerings-preview-paired-feature-cards",
13418
- target: "offerings",
13419
- label: "Paired feature cards",
13420
- blockKinds: ["block.offerings-preview"],
13421
- constraints: { layoutVariantKeys: ["cards"] },
13422
- design: {
13423
- sectionSurface: "base",
13424
- contentFrame: plainFrame,
13425
- itemSurface: "none"
13426
- }
13427
- }),
13428
- defineBlockAppearancePreset({
13429
- kind: "block-design",
13430
- id: "offerings-preview-open-editorial-columns",
13431
- target: "offerings",
13432
- label: "Open editorial columns",
13433
- blockKinds: ["block.offerings-preview"],
13434
- constraints: { layoutVariantKeys: ["cards"] },
13435
- design: {
13436
- sectionSurface: "base",
13437
- contentFrame: plainFrame,
13438
- itemSurface: "none"
13439
- }
13440
- }),
13441
- defineBlockAppearancePreset({
13442
- kind: "block-design",
13443
- id: "offerings-preview-joined-programme-panel",
13444
- target: "offerings",
13445
- label: "Joined programme panel",
13446
- blockKinds: ["block.offerings-preview"],
13447
- constraints: { layoutVariantKeys: ["cards"] },
13448
- design: {
13449
- sectionSurface: "base",
13450
- contentFrame: plainFrame,
13451
- itemSurface: "none"
13452
- }
13453
- }),
13454
- defineBlockAppearancePreset({
13455
- kind: "block-design",
13456
- id: "feature-cards-raised-rule",
13457
- target: "feature-cards",
13458
- label: "Raised cards with rule",
13459
- blockKinds: ["block.feature-cards"],
13460
- design: {
13461
- sectionSurface: "base",
13462
- contentFrame: plainFrame,
13463
- itemSurface: "raised"
13464
- }
13465
- }),
13466
- defineBlockAppearancePreset({
13467
- kind: "block-design",
13468
- id: "feature-cards-bold-colors",
13469
- target: "feature-cards",
13470
- label: "Bold colour-blocked cards",
13471
- blockKinds: ["block.feature-cards"],
13472
- design: {
13473
- sectionSurface: "base",
13474
- contentFrame: plainFrame,
13475
- itemSurface: "color-blocked"
13476
- }
13477
- }),
13478
- defineBlockAppearancePreset({
13479
- kind: "block-design",
13480
- id: "feature-cards-editorial-columns",
13481
- target: "feature-cards",
13482
- label: "Editorial open columns",
13483
- blockKinds: ["block.feature-cards"],
13484
- design: {
13485
- sectionSurface: "base",
13486
- contentFrame: plainFrame,
13487
- itemSurface: "editorial"
13488
- }
13489
- }),
13490
- defineBlockAppearancePreset({
13491
- kind: "block-design",
13492
- id: "feature-cards-asymmetric-emphasis",
13493
- target: "feature-cards",
13494
- label: "Asymmetric emphasis pair",
13495
- blockKinds: ["block.feature-cards"],
13496
- constraints: { layoutFamilies: ["grid"] },
13497
- design: {
13498
- sectionSurface: "base",
13499
- contentFrame: plainFrame,
13500
- itemSurface: "none",
13501
- composition: {
13502
- kind: "feature-cards",
13503
- treatment: "asymmetric-emphasis"
13504
- }
13505
- }
13506
- }),
13507
- defineBlockAppearancePreset({
13508
- kind: "block-design",
13509
- id: "feature-cards-framed-programme",
13510
- target: "feature-cards",
13511
- label: "Framed programme cards",
13512
- blockKinds: ["block.feature-cards"],
13513
- constraints: { layoutFamilies: ["grid"] },
13514
- design: {
13515
- sectionSurface: "brand-depth-band",
13516
- contentFrame: plainFrame,
13517
- itemSurface: "inset",
13518
- composition: {
13519
- kind: "feature-cards",
13520
- treatment: "framed-programme"
13521
- }
13522
- }
13523
- }),
13524
- defineBlockAppearancePreset({
13525
- kind: "block-design",
13526
- id: "feature-cards-soft-panels",
13527
- target: "feature-cards",
13528
- label: "Soft tinted panels",
13529
- blockKinds: ["block.feature-cards"],
13530
- design: {
13531
- sectionSurface: "base",
13532
- contentFrame: plainFrame,
13533
- itemSurface: "inset"
13534
- }
13535
- }),
13536
- defineBlockAppearancePreset({
13537
- kind: "block-design",
13538
- id: "feature-cards-editorial-diptych",
13539
- target: "feature-cards",
13540
- label: "Editorial diptych",
13541
- blockKinds: ["block.feature-cards"],
13542
- constraints: { layoutVariantKeys: ["editorial-diptych"] },
13543
- design: {
13544
- sectionSurface: "base",
13545
- contentFrame: plainFrame,
13546
- itemSurface: "flat"
13547
- }
13548
- }),
13549
- defineBlockAppearancePreset({
13550
- kind: "block-design",
13551
- id: "feature-cards-editorial-pathways",
13552
- target: "feature-cards",
13553
- label: "Editorial pathways",
13554
- blockKinds: ["block.feature-cards"],
13555
- constraints: { layoutVariantKeys: ["editorial-pathways"] },
13556
- design: {
13557
- sectionSurface: "base",
13558
- contentFrame: plainFrame,
13559
- itemSurface: "flat"
13560
- }
13561
- }),
13562
- defineBlockAppearancePreset({
13563
- kind: "block-design",
13564
- id: "feature-cards-photo-tiles",
13565
- target: "feature-cards",
13566
- label: "Photo tiles",
13567
- blockKinds: ["block.feature-cards"],
13568
- design: {
13569
- sectionSurface: "base",
13570
- contentFrame: plainFrame,
13571
- itemSurface: "raised"
13572
- }
13573
- }),
13574
- defineBlockAppearancePreset({
13575
- kind: "block-design",
13576
- id: "events-lined-panel",
13577
- target: "events",
13578
- label: "Raised event panel",
13579
- blockKinds: ["block.event-calendar", "block.event-listing"],
13580
- design: {
13581
- sectionSurface: "base",
13582
- contentFrame: panelFrame("raised"),
13583
- itemSurface: "none"
13584
- }
13585
- }),
13586
- defineBlockAppearancePreset({
13587
- kind: "block-design",
13588
- id: "events-ruled-register",
13589
- target: "events",
13590
- label: "Ruled event register",
13591
- blockKinds: ["block.event-calendar", "block.event-listing"],
13592
- design: {
13593
- sectionSurface: "brand-depth-band",
13594
- contentFrame: plainFrame,
13595
- itemSurface: "none",
13596
- eventListTreatment: "ruled-register"
13597
- }
13598
- }),
13599
- defineBlockAppearancePreset({
13600
- kind: "block-design",
13601
- id: "events-editorial-register",
13602
- target: "events",
13603
- label: "Editorial event register",
13604
- blockKinds: ["block.event-calendar", "block.event-listing"],
13605
- design: {
13606
- sectionSurface: "base",
13607
- contentFrame: plainFrame,
13608
- itemSurface: "none",
13609
- eventListTreatment: "editorial-register"
13610
- }
13611
- }),
13612
- defineBlockAppearancePreset({
13613
- kind: "block-design",
13614
- id: "events-dense-index",
13615
- target: "events",
13616
- label: "Dense event index",
13617
- blockKinds: ["block.event-calendar", "block.event-listing"],
13618
- design: {
13619
- sectionSurface: "accent-band",
13620
- contentFrame: plainFrame,
13621
- itemSurface: "none",
13622
- eventListTreatment: "dense-index"
13623
- }
13624
- }),
13625
- defineBlockAppearancePreset({
13626
- kind: "block-design",
13627
- id: "schedule-details-brand-depth",
13628
- target: "events",
13629
- label: "Brand-depth schedule details",
13630
- blockKinds: ["block.event-details", "block.course-details"],
13631
- design: {
13632
- sectionSurface: "brand-depth-band",
13633
- contentFrame: plainFrame,
13634
- itemSurface: "none",
13635
- tileTreatment: "brand-depth"
13636
- }
13637
- }),
13638
- defineBlockAppearancePreset({
13639
- kind: "block-design",
13640
- id: "media-text-flush-feature",
13641
- target: "media-text",
13642
- label: "Flush media feature",
13643
- blockKinds: ["block.media-text"],
13644
- design: {
13645
- sectionSurface: "muted-band",
13646
- contentFrame: flushPanelFrame({ bleed: "start" }),
13647
- itemSurface: "none"
13648
- }
13649
- }),
13650
- defineBlockAppearancePreset({
13651
- kind: "block-design",
13652
- id: "testimonials-simple-cards",
13653
- target: "testimonials",
13654
- label: "Simple testimonial cards",
13655
- blockKinds: ["block.testimonials"],
13656
- design: {
13657
- sectionSurface: "base",
13658
- contentFrame: plainFrame,
13659
- itemSurface: "default"
13660
- }
13661
- }),
13662
- defineBlockAppearancePreset({
13663
- kind: "block-design",
13664
- id: "testimonials-raised-panel",
13665
- target: "testimonials",
13666
- label: "Raised testimonial panel",
13667
- blockKinds: ["block.testimonials"],
13668
- design: {
13669
- sectionSurface: "muted-band",
13670
- contentFrame: panelFrame("raised"),
13671
- itemSurface: "raised"
13672
- }
13673
- }),
13674
- defineBlockAppearancePreset({
13675
- kind: "block-design",
13676
- id: "testimonials-accent-panel",
13677
- target: "testimonials",
13678
- label: "Accent testimonial panel",
13679
- blockKinds: ["block.testimonials"],
13680
- design: {
13681
- sectionSurface: "accent-band",
13682
- contentFrame: panelFrame("raised"),
13683
- itemSurface: "raised"
13684
- }
13685
- }),
13686
- defineBlockAppearancePreset({
13687
- kind: "block-design",
13688
- id: "testimonials-default-cards",
13689
- target: "testimonials",
13690
- label: "Default cards",
13691
- blockKinds: ["block.testimonials"],
13692
- design: {
13693
- sectionSurface: "base",
13694
- contentFrame: plainFrame,
13695
- itemSurface: "none",
13696
- testimonialCardTreatment: "default"
13697
- }
13698
- }),
13699
- defineBlockAppearancePreset({
13700
- kind: "block-design",
13701
- id: "testimonials-statement-cards",
13702
- target: "testimonials",
13703
- label: "Statement cards",
13704
- blockKinds: ["block.testimonials"],
13705
- design: {
13706
- sectionSurface: "accent-band",
13707
- contentFrame: plainFrame,
13708
- itemSurface: "raised",
13709
- testimonialCardTreatment: "statement"
13710
- }
13711
- }),
13712
- defineBlockAppearancePreset({
13713
- kind: "block-design",
13714
- id: "testimonials-brand-statement-cards",
13715
- target: "testimonials",
13716
- label: "Brand statement cards",
13717
- blockKinds: ["block.testimonials"],
13718
- design: {
13719
- sectionSurface: "brand-depth-band",
13720
- contentFrame: plainFrame,
13721
- itemSurface: "raised",
13722
- testimonialCardTreatment: "statement"
13723
- }
13724
- }),
13725
- defineBlockAppearancePreset({
13726
- kind: "block-design",
13727
- id: "testimonials-non-carded",
13728
- target: "testimonials",
13729
- label: "Non-carded",
13730
- blockKinds: ["block.testimonials"],
13731
- design: {
13732
- sectionSurface: "muted-band",
13733
- contentFrame: plainFrame,
13734
- itemSurface: "none",
13735
- testimonialCardTreatment: "non-carded"
13736
- }
13737
- }),
13738
- defineBlockAppearancePreset({
13739
- kind: "block-design",
13740
- id: "testimonials-evergreen-lead",
13741
- target: "testimonials",
13742
- label: "Evergreen lead",
13743
- blockKinds: ["block.testimonials"],
13744
- constraints: { layoutVariantKeys: ["featured-editorial"] },
13745
- design: {
13746
- sectionSurface: "base",
13747
- contentFrame: plainFrame,
13748
- itemSurface: "none"
13749
- }
13750
- }),
13751
- defineBlockAppearancePreset({
13752
- kind: "block-design",
13753
- id: "testimonials-room-and-response",
13754
- target: "testimonials",
13755
- label: "Room and response",
13756
- blockKinds: ["block.testimonials"],
13757
- constraints: { layoutVariantKeys: ["featured-editorial"] },
13758
- design: {
13759
- sectionSurface: "base",
13760
- contentFrame: plainFrame,
13761
- itemSurface: "none"
13762
- }
13763
- }),
13764
- defineBlockAppearancePreset({
13765
- kind: "block-design",
13766
- id: "testimonials-open-floor",
13767
- target: "testimonials",
13768
- label: "Open floor",
13769
- blockKinds: ["block.testimonials"],
13770
- constraints: { layoutVariantKeys: ["featured-editorial"] },
13771
- design: {
13772
- sectionSurface: "base",
13773
- contentFrame: plainFrame,
13774
- itemSurface: "none"
13775
- }
13776
- }),
13777
- defineBlockAppearancePreset({
13778
- kind: "block-design",
13779
- id: "faq-base-accordion",
13780
- target: "faq",
13781
- label: "Base accordion FAQ",
13782
- blockKinds: ["block.faq"],
13783
- design: {
13784
- sectionSurface: "base",
13785
- contentFrame: plainFrame,
13786
- itemSurface: "default"
13787
- }
13788
- }),
13789
- defineBlockAppearancePreset({
13790
- kind: "block-design",
13791
- id: "faq-contained-help",
13792
- target: "faq",
13793
- label: "Contained help panel",
13794
- blockKinds: ["block.faq"],
13795
- design: {
13796
- sectionSurface: "muted-band",
13797
- contentFrame: panelFrame("inset"),
13798
- itemSurface: "default"
13799
- }
13800
- }),
13801
- defineBlockAppearancePreset({
13802
- kind: "block-design",
13803
- id: "contact-form-panel",
13804
- target: "contact-form",
13805
- label: "Raised form panel",
13806
- blockKinds: ["block.form"],
13807
- design: {
13808
- sectionSurface: "muted-band",
13809
- contentFrame: panelFrame("raised"),
13810
- itemSurface: "none"
13811
- }
13812
- }),
13813
- defineBlockAppearancePreset({
13814
- kind: "block-design",
13815
- id: "cta-accent-band",
13816
- target: "cta",
13817
- label: "Accent CTA band",
13818
- blockKinds: ["block.cta-full"],
13819
- design: {
13820
- sectionSurface: "accent-band",
13821
- contentFrame: plainFrame,
13822
- itemSurface: "none",
13823
- eyebrowTreatment: "accent"
13824
- }
13825
- })
13826
- ]];
13284
+ }],
13285
+ design: {
13286
+ sectionSurface: "hero-image",
13287
+ contentFrame: plainFrame,
13288
+ itemSurface: "none",
13289
+ sectionHeight: "immersive",
13290
+ heroComposition: "center",
13291
+ heroTypographyScale: "poster",
13292
+ imageSurfaceTreatment: {
13293
+ kind: "brand-scrim",
13294
+ token: "primary",
13295
+ intensity: "strong"
13296
+ }
13297
+ }
13298
+ }), defineBlockAppearancePreset({
13299
+ id: "hero-brand-scrim",
13300
+ target: "hero",
13301
+ label: "Brand scrim image hero",
13302
+ blockKinds: ["block.hero"],
13303
+ constraints: { layoutFamilies: ["centered", "compact"] },
13304
+ optionGroups: brandScrimOptionGroups,
13305
+ layoutPatches: microBannerLayoutPatches,
13306
+ design: {
13307
+ sectionSurface: "hero-image",
13308
+ contentFrame: plainFrame,
13309
+ itemSurface: "none",
13310
+ sectionHeight: "immersive",
13311
+ heroComposition: "center",
13312
+ heroTypographyScale: "display",
13313
+ imageSurfaceTreatment: {
13314
+ kind: "brand-scrim",
13315
+ token: "primary"
13316
+ }
13317
+ }
13318
+ }), defineBlockAppearancePreset({
13319
+ id: "hero-brand-scrim-fixed-frame",
13320
+ target: "hero",
13321
+ label: "Fixed-frame brand scrim hero",
13322
+ blockKinds: ["block.hero"],
13323
+ constraints: { layoutFamilies: ["centered", "compact"] },
13324
+ optionGroups: brandScrimOptionGroups,
13325
+ layoutPatches: microBannerLayoutPatches,
13326
+ design: {
13327
+ sectionSurface: "hero-image",
13328
+ contentFrame: plainFrame,
13329
+ itemSurface: "none",
13330
+ sectionHeight: "immersive",
13331
+ heroComposition: "center",
13332
+ heroTypographyScale: "display",
13333
+ imageSurfaceTreatment: {
13334
+ kind: "brand-scrim",
13335
+ token: "primary"
13336
+ },
13337
+ imageSurfaceMotion: "fixed-frame",
13338
+ eyebrowTreatment: "accent-pill-bounce"
13339
+ }
13340
+ }), defineBlockAppearancePreset({
13341
+ id: "hero-brand-depth-expressive",
13342
+ target: "hero",
13343
+ label: "Expressive brand-depth hero",
13344
+ blockKinds: ["block.hero"],
13345
+ constraints: { layoutFamilies: ["centered", "compact"] },
13346
+ design: {
13347
+ sectionSurface: "brand-depth-band",
13348
+ contentFrame: plainFrame,
13349
+ itemSurface: "none",
13350
+ heroComposition: "center",
13351
+ heroTypographyScale: "editorial",
13352
+ eyebrowTreatment: "accent-pill-bounce"
13353
+ }
13354
+ }), defineBlockAppearancePreset({
13355
+ id: "hero-contained-intro",
13356
+ target: "hero",
13357
+ label: "Contained intro hero",
13358
+ blockKinds: ["block.hero"],
13359
+ design: {
13360
+ sectionSurface: "muted-band",
13361
+ contentFrame: panelFrame("inset"),
13362
+ itemSurface: "none",
13363
+ heroComposition: "center",
13364
+ heroTypographyScale: "editorial"
13365
+ }
13366
+ }), defineBlockAppearancePreset({
13367
+ id: "hero-split-editorial",
13368
+ target: "hero",
13369
+ label: "Editorial split hero",
13370
+ blockKinds: ["block.hero"],
13371
+ constraints: { layoutFamilies: ["split"] },
13372
+ design: {
13373
+ sectionSurface: "base",
13374
+ contentFrame: plainFrame,
13375
+ itemSurface: "none",
13376
+ heroTypographyScale: "editorial"
13377
+ }
13378
+ }), defineBlockAppearancePreset({
13379
+ id: "hero-split-brand",
13380
+ target: "hero",
13381
+ label: "Brand split hero",
13382
+ blockKinds: ["block.hero"],
13383
+ constraints: { layoutFamilies: ["split"] },
13384
+ design: {
13385
+ sectionSurface: "brand-depth-band",
13386
+ contentFrame: plainFrame,
13387
+ itemSurface: "none",
13388
+ heroTypographyScale: "display",
13389
+ eyebrowTreatment: "accent-pill-bounce"
13390
+ }
13391
+ }), defineBlockAppearancePreset({
13392
+ id: "hero-split-soft-panel",
13393
+ target: "hero",
13394
+ label: "Soft panel split hero",
13395
+ blockKinds: ["block.hero"],
13396
+ constraints: { layoutFamilies: ["split"] },
13397
+ design: {
13398
+ sectionSurface: "muted-band",
13399
+ contentFrame: panelFrame("raised"),
13400
+ itemSurface: "none",
13401
+ heroTypographyScale: "editorial"
13402
+ }
13403
+ }), defineBlockAppearancePreset({
13404
+ id: "hero-split-accent",
13405
+ target: "hero",
13406
+ label: "Accent split hero",
13407
+ blockKinds: ["block.hero"],
13408
+ constraints: { layoutFamilies: ["split"] },
13409
+ design: {
13410
+ sectionSurface: "accent-band",
13411
+ contentFrame: panelFrame("raised"),
13412
+ itemSurface: "none",
13413
+ heroTypographyScale: "display"
13414
+ }
13415
+ }), defineBlockAppearancePreset({
13416
+ id: "intro-editorial-statement",
13417
+ target: "intro",
13418
+ label: "Editorial intro statement",
13419
+ blockKinds: ["block.intro"],
13420
+ constraints: { layoutVariantKeys: ["centered-copy", "statement-copy"] },
13421
+ design: {
13422
+ sectionSurface: "base",
13423
+ contentFrame: plainFrame,
13424
+ itemSurface: "none",
13425
+ composition: {
13426
+ kind: "intro",
13427
+ treatment: "editorial-statement"
13428
+ }
13429
+ }
13430
+ }), defineBlockAppearancePreset({
13431
+ id: "intro-portrait-bio",
13432
+ target: "intro",
13433
+ label: "Portrait and bio",
13434
+ blockKinds: ["block.intro"],
13435
+ constraints: { layoutVariantKeys: ["media-copy"] },
13436
+ design: {
13437
+ sectionSurface: "base",
13438
+ contentFrame: plainFrame,
13439
+ itemSurface: "none",
13440
+ composition: {
13441
+ kind: "intro",
13442
+ treatment: "portrait-bio"
13443
+ }
13444
+ }
13445
+ }), defineBlockAppearancePreset({
13446
+ id: "offerings-preview-default-cards",
13447
+ target: "offerings",
13448
+ label: "Default offering cards",
13449
+ blockKinds: ["block.offerings-preview"],
13450
+ design: {
13451
+ sectionSurface: "base",
13452
+ contentFrame: plainFrame,
13453
+ itemSurface: "default"
13454
+ }
13455
+ }), defineBlockAppearancePreset({
13456
+ id: "offerings-preview-secondary-cards",
13457
+ target: "offerings",
13458
+ label: "Secondary offering cards",
13459
+ blockKinds: ["block.offerings-preview"],
13460
+ design: {
13461
+ sectionSurface: "muted-band",
13462
+ contentFrame: plainFrame,
13463
+ itemSurface: "inset"
13464
+ }
13465
+ }), defineBlockAppearancePreset({
13466
+ id: "offerings-preview-non-carded",
13467
+ target: "offerings",
13468
+ label: "Non-carded offerings",
13469
+ blockKinds: ["block.offerings-preview"],
13470
+ design: {
13471
+ sectionSurface: "muted-band",
13472
+ contentFrame: plainFrame,
13473
+ itemSurface: "editorial"
13474
+ }
13475
+ }), defineBlockAppearancePreset({
13476
+ id: "offerings-preview-paired-feature-cards",
13477
+ target: "offerings",
13478
+ label: "Paired feature cards",
13479
+ blockKinds: ["block.offerings-preview"],
13480
+ constraints: { layoutVariantKeys: ["cards"] },
13481
+ design: {
13482
+ sectionSurface: "base",
13483
+ contentFrame: plainFrame,
13484
+ itemSurface: "none"
13485
+ }
13486
+ }), defineBlockAppearancePreset({
13487
+ id: "offerings-preview-open-editorial-columns",
13488
+ target: "offerings",
13489
+ label: "Open editorial columns",
13490
+ blockKinds: ["block.offerings-preview"],
13491
+ constraints: { layoutVariantKeys: ["cards"] },
13492
+ design: {
13493
+ sectionSurface: "base",
13494
+ contentFrame: plainFrame,
13495
+ itemSurface: "none"
13496
+ }
13497
+ }), defineBlockAppearancePreset({
13498
+ id: "offerings-preview-joined-programme-panel",
13499
+ target: "offerings",
13500
+ label: "Joined programme panel",
13501
+ blockKinds: ["block.offerings-preview"],
13502
+ constraints: { layoutVariantKeys: ["cards"] },
13503
+ design: {
13504
+ sectionSurface: "base",
13505
+ contentFrame: plainFrame,
13506
+ itemSurface: "none"
13507
+ }
13508
+ }), defineBlockAppearancePreset({
13509
+ id: "feature-cards-raised-rule",
13510
+ target: "feature-cards",
13511
+ label: "Raised cards with rule",
13512
+ blockKinds: ["block.feature-cards"],
13513
+ design: {
13514
+ sectionSurface: "base",
13515
+ contentFrame: plainFrame,
13516
+ itemSurface: "raised"
13517
+ }
13518
+ }), defineBlockAppearancePreset({
13519
+ id: "feature-cards-bold-colors",
13520
+ target: "feature-cards",
13521
+ label: "Bold colour-blocked cards",
13522
+ blockKinds: ["block.feature-cards"],
13523
+ design: {
13524
+ sectionSurface: "base",
13525
+ contentFrame: plainFrame,
13526
+ itemSurface: "color-blocked"
13527
+ }
13528
+ }), defineBlockAppearancePreset({
13529
+ id: "feature-cards-editorial-columns",
13530
+ target: "feature-cards",
13531
+ label: "Editorial open columns",
13532
+ blockKinds: ["block.feature-cards"],
13533
+ design: {
13534
+ sectionSurface: "base",
13535
+ contentFrame: plainFrame,
13536
+ itemSurface: "editorial"
13537
+ }
13538
+ }), defineBlockAppearancePreset({
13539
+ id: "feature-cards-asymmetric-emphasis",
13540
+ target: "feature-cards",
13541
+ label: "Asymmetric emphasis pair",
13542
+ blockKinds: ["block.feature-cards"],
13543
+ constraints: { layoutFamilies: ["grid"] },
13544
+ design: {
13545
+ sectionSurface: "base",
13546
+ contentFrame: plainFrame,
13547
+ itemSurface: "none",
13548
+ composition: {
13549
+ kind: "feature-cards",
13550
+ treatment: "asymmetric-emphasis"
13551
+ }
13552
+ }
13553
+ }), defineBlockAppearancePreset({
13554
+ id: "feature-cards-framed-programme",
13555
+ target: "feature-cards",
13556
+ label: "Framed programme cards",
13557
+ blockKinds: ["block.feature-cards"],
13558
+ constraints: { layoutFamilies: ["grid"] },
13559
+ design: {
13560
+ sectionSurface: "brand-depth-band",
13561
+ contentFrame: plainFrame,
13562
+ itemSurface: "inset",
13563
+ composition: {
13564
+ kind: "feature-cards",
13565
+ treatment: "framed-programme"
13566
+ }
13567
+ }
13568
+ }), defineBlockAppearancePreset({
13569
+ id: "feature-cards-soft-panels",
13570
+ target: "feature-cards",
13571
+ label: "Soft tinted panels",
13572
+ blockKinds: ["block.feature-cards"],
13573
+ design: {
13574
+ sectionSurface: "base",
13575
+ contentFrame: plainFrame,
13576
+ itemSurface: "inset"
13577
+ }
13578
+ }), defineBlockAppearancePreset({
13579
+ id: "feature-cards-editorial-diptych",
13580
+ target: "feature-cards",
13581
+ label: "Editorial diptych",
13582
+ blockKinds: ["block.feature-cards"],
13583
+ constraints: { layoutVariantKeys: ["editorial-diptych"] },
13584
+ design: {
13585
+ sectionSurface: "base",
13586
+ contentFrame: plainFrame,
13587
+ itemSurface: "flat"
13588
+ }
13589
+ }), defineBlockAppearancePreset({
13590
+ id: "feature-cards-editorial-pathways",
13591
+ target: "feature-cards",
13592
+ label: "Editorial pathways",
13593
+ blockKinds: ["block.feature-cards"],
13594
+ constraints: { layoutVariantKeys: ["editorial-pathways"] },
13595
+ design: {
13596
+ sectionSurface: "base",
13597
+ contentFrame: plainFrame,
13598
+ itemSurface: "flat"
13599
+ }
13600
+ }), defineBlockAppearancePreset({
13601
+ id: "feature-cards-photo-tiles",
13602
+ target: "feature-cards",
13603
+ label: "Photo tiles",
13604
+ blockKinds: ["block.feature-cards"],
13605
+ design: {
13606
+ sectionSurface: "base",
13607
+ contentFrame: plainFrame,
13608
+ itemSurface: "raised"
13609
+ }
13610
+ }), defineBlockAppearancePreset({
13611
+ id: "events-lined-panel",
13612
+ target: "events",
13613
+ label: "Raised event panel",
13614
+ blockKinds: ["block.event-calendar", "block.event-listing"],
13615
+ design: {
13616
+ sectionSurface: "base",
13617
+ contentFrame: panelFrame("raised"),
13618
+ itemSurface: "none"
13619
+ }
13620
+ }), defineBlockAppearancePreset({
13621
+ id: "events-ruled-register",
13622
+ target: "events",
13623
+ label: "Ruled event register",
13624
+ blockKinds: ["block.event-calendar", "block.event-listing"],
13625
+ design: {
13626
+ sectionSurface: "brand-depth-band",
13627
+ contentFrame: plainFrame,
13628
+ itemSurface: "none",
13629
+ eventListTreatment: "ruled-register"
13630
+ }
13631
+ }), defineBlockAppearancePreset({
13632
+ id: "events-editorial-register",
13633
+ target: "events",
13634
+ label: "Editorial event register",
13635
+ blockKinds: ["block.event-calendar", "block.event-listing"],
13636
+ design: {
13637
+ sectionSurface: "base",
13638
+ contentFrame: plainFrame,
13639
+ itemSurface: "none",
13640
+ eventListTreatment: "editorial-register"
13641
+ }
13642
+ }), defineBlockAppearancePreset({
13643
+ id: "events-dense-index",
13644
+ target: "events",
13645
+ label: "Dense event index",
13646
+ blockKinds: ["block.event-calendar", "block.event-listing"],
13647
+ design: {
13648
+ sectionSurface: "accent-band",
13649
+ contentFrame: plainFrame,
13650
+ itemSurface: "none",
13651
+ eventListTreatment: "dense-index"
13652
+ }
13653
+ }), defineBlockAppearancePreset({
13654
+ id: "schedule-details-brand-depth",
13655
+ target: "events",
13656
+ label: "Brand-depth schedule details",
13657
+ blockKinds: ["block.event-details", "block.course-details"],
13658
+ design: {
13659
+ sectionSurface: "brand-depth-band",
13660
+ contentFrame: plainFrame,
13661
+ itemSurface: "none",
13662
+ tileTreatment: "brand-depth"
13663
+ }
13664
+ }), defineBlockAppearancePreset({
13665
+ id: "media-text-flush-feature",
13666
+ target: "media-text",
13667
+ label: "Flush media feature",
13668
+ blockKinds: ["block.media-text"],
13669
+ design: {
13670
+ sectionSurface: "muted-band",
13671
+ contentFrame: flushPanelFrame({ bleed: "start" }),
13672
+ itemSurface: "none"
13673
+ }
13674
+ }), defineBlockAppearancePreset({
13675
+ id: "testimonials-simple-cards",
13676
+ target: "testimonials",
13677
+ label: "Simple testimonial cards",
13678
+ blockKinds: ["block.testimonials"],
13679
+ design: {
13680
+ sectionSurface: "base",
13681
+ contentFrame: plainFrame,
13682
+ itemSurface: "default"
13683
+ }
13684
+ }), defineBlockAppearancePreset({
13685
+ id: "testimonials-raised-panel",
13686
+ target: "testimonials",
13687
+ label: "Raised testimonial panel",
13688
+ blockKinds: ["block.testimonials"],
13689
+ design: {
13690
+ sectionSurface: "muted-band",
13691
+ contentFrame: panelFrame("raised"),
13692
+ itemSurface: "raised"
13693
+ }
13694
+ }), defineBlockAppearancePreset({
13695
+ id: "testimonials-accent-panel",
13696
+ target: "testimonials",
13697
+ label: "Accent testimonial panel",
13698
+ blockKinds: ["block.testimonials"],
13699
+ design: {
13700
+ sectionSurface: "accent-band",
13701
+ contentFrame: panelFrame("raised"),
13702
+ itemSurface: "raised"
13703
+ }
13704
+ }), defineBlockAppearancePreset({
13705
+ id: "testimonials-default-cards",
13706
+ target: "testimonials",
13707
+ label: "Default cards",
13708
+ blockKinds: ["block.testimonials"],
13709
+ design: {
13710
+ sectionSurface: "base",
13711
+ contentFrame: plainFrame,
13712
+ itemSurface: "none",
13713
+ testimonialCardTreatment: "default"
13714
+ }
13715
+ }), defineBlockAppearancePreset({
13716
+ id: "testimonials-statement-cards",
13717
+ target: "testimonials",
13718
+ label: "Statement cards",
13719
+ blockKinds: ["block.testimonials"],
13720
+ design: {
13721
+ sectionSurface: "accent-band",
13722
+ contentFrame: plainFrame,
13723
+ itemSurface: "raised",
13724
+ testimonialCardTreatment: "statement"
13725
+ }
13726
+ }), defineBlockAppearancePreset({
13727
+ id: "testimonials-brand-statement-cards",
13728
+ target: "testimonials",
13729
+ label: "Brand statement cards",
13730
+ blockKinds: ["block.testimonials"],
13731
+ design: {
13732
+ sectionSurface: "brand-depth-band",
13733
+ contentFrame: plainFrame,
13734
+ itemSurface: "raised",
13735
+ testimonialCardTreatment: "statement"
13736
+ }
13737
+ }), defineBlockAppearancePreset({
13738
+ id: "testimonials-non-carded",
13739
+ target: "testimonials",
13740
+ label: "Non-carded",
13741
+ blockKinds: ["block.testimonials"],
13742
+ design: {
13743
+ sectionSurface: "muted-band",
13744
+ contentFrame: plainFrame,
13745
+ itemSurface: "none",
13746
+ testimonialCardTreatment: "non-carded"
13747
+ }
13748
+ }), defineBlockAppearancePreset({
13749
+ id: "testimonials-evergreen-lead",
13750
+ target: "testimonials",
13751
+ label: "Evergreen lead",
13752
+ blockKinds: ["block.testimonials"],
13753
+ constraints: { layoutVariantKeys: ["featured-editorial"] },
13754
+ design: {
13755
+ sectionSurface: "base",
13756
+ contentFrame: plainFrame,
13757
+ itemSurface: "none"
13758
+ }
13759
+ }), defineBlockAppearancePreset({
13760
+ id: "testimonials-room-and-response",
13761
+ target: "testimonials",
13762
+ label: "Room and response",
13763
+ blockKinds: ["block.testimonials"],
13764
+ constraints: { layoutVariantKeys: ["featured-editorial"] },
13765
+ design: {
13766
+ sectionSurface: "base",
13767
+ contentFrame: plainFrame,
13768
+ itemSurface: "none"
13769
+ }
13770
+ }), defineBlockAppearancePreset({
13771
+ id: "testimonials-open-floor",
13772
+ target: "testimonials",
13773
+ label: "Open floor",
13774
+ blockKinds: ["block.testimonials"],
13775
+ constraints: { layoutVariantKeys: ["featured-editorial"] },
13776
+ design: {
13777
+ sectionSurface: "base",
13778
+ contentFrame: plainFrame,
13779
+ itemSurface: "none"
13780
+ }
13781
+ }), defineBlockAppearancePreset({
13782
+ id: "faq-base-accordion",
13783
+ target: "faq",
13784
+ label: "Base accordion FAQ",
13785
+ blockKinds: ["block.faq"],
13786
+ design: {
13787
+ sectionSurface: "base",
13788
+ contentFrame: plainFrame,
13789
+ itemSurface: "default"
13790
+ }
13791
+ }), defineBlockAppearancePreset({
13792
+ id: "faq-contained-help",
13793
+ target: "faq",
13794
+ label: "Contained help panel",
13795
+ blockKinds: ["block.faq"],
13796
+ design: {
13797
+ sectionSurface: "muted-band",
13798
+ contentFrame: panelFrame("inset"),
13799
+ itemSurface: "default"
13800
+ }
13801
+ }), defineBlockAppearancePreset({
13802
+ id: "contact-form-panel",
13803
+ target: "contact-form",
13804
+ label: "Raised form panel",
13805
+ blockKinds: ["block.form"],
13806
+ design: {
13807
+ sectionSurface: "muted-band",
13808
+ contentFrame: panelFrame("raised"),
13809
+ itemSurface: "none"
13810
+ }
13811
+ }), defineBlockAppearancePreset({
13812
+ id: "cta-accent-band",
13813
+ target: "cta",
13814
+ label: "Accent CTA band",
13815
+ blockKinds: ["block.cta-full"],
13816
+ design: {
13817
+ sectionSurface: "accent-band",
13818
+ contentFrame: plainFrame,
13819
+ itemSurface: "none",
13820
+ eyebrowTreatment: "accent"
13821
+ }
13822
+ });
13827
13823
  //#endregion
13828
13824
  //#region ../theme-core/src/site-styles/headerCtaVariants.ts
13829
13825
  function hasButtonVariant(theme, variantId) {
@@ -15337,7 +15333,7 @@ function canonicalPaletteHashInput(colors, mode) {
15337
15333
  return `${mode}|${paletteColorFingerprint(colors)}`;
15338
15334
  }
15339
15335
  /**
15340
- * The shared TypeScript/SQL protocol. Do not reorder roles: the order comes
15336
+ * Stable curated-catalogue identity. Do not reorder roles: the order comes
15341
15337
  * from PALETTE_TOKEN_NAMES through canonicalPaletteHashInput.
15342
15338
  */
15343
15339
  function paletteValueKey(colors, mode) {
@@ -16907,6 +16903,32 @@ function parseBackgroundAppearanceColorToken(value) {
16907
16903
  function uniqueStrings(values) {
16908
16904
  return Array.from(new Set(values));
16909
16905
  }
16906
+ const headerInteractionPaletteSchema = z$1.enum([
16907
+ "primary",
16908
+ "secondary",
16909
+ "accent"
16910
+ ]);
16911
+ //#endregion
16912
+ //#region ../theme-core/src/site-styles/headerInteractionPalette.ts
16913
+ const clearSplitInteractionPalette = defineLookOptionGroup({
16914
+ id: "interaction-palette",
16915
+ label: "Hover colour",
16916
+ defaultOptionId: "accent",
16917
+ options: [
16918
+ {
16919
+ id: "accent",
16920
+ label: "Accent"
16921
+ },
16922
+ {
16923
+ id: "primary",
16924
+ label: "Primary"
16925
+ },
16926
+ {
16927
+ id: "secondary",
16928
+ label: "Secondary"
16929
+ }
16930
+ ]
16931
+ });
16910
16932
  //#endregion
16911
16933
  //#region ../theme-core/src/site-styles/logoBranding.ts
16912
16934
  const logoTextConfidenceValues = [
@@ -17129,7 +17151,7 @@ const overlayLogoAccommodations = [
17129
17151
  * optional nested styling fields that would otherwise leak from another Look.
17130
17152
  */
17131
17153
  function baseHeader(theme) {
17132
- const { navLinkStyle: _navLinkStyle, navFontRole: _navFontRole, navTypography: _navTypography, navTextSize: _navTextSize, dropdownStyle: _dropdownStyle, ctaVariant: _ctaVariant, navContainer: _navContainer, container: _container, shadow: _shadow, logo: _logo, logoText: _logoText, border: _border, ...header } = theme.header;
17154
+ const { navLinkStyle: _navLinkStyle, navFontRole: _navFontRole, navTypography: _navTypography, navTextSize: _navTextSize, interactionPalette: _interactionPalette, dropdownStyle: _dropdownStyle, ctaVariant: _ctaVariant, navContainer: _navContainer, container: _container, shadow: _shadow, logo: _logo, logoText: _logoText, border: _border, ...header } = theme.header;
17133
17155
  return {
17134
17156
  ...header,
17135
17157
  navContainer: {
@@ -17144,7 +17166,6 @@ const headerLayoutCatalog = defineExactCatalog()([
17144
17166
  id: asHeaderLayoutId("classic"),
17145
17167
  label: "Classic",
17146
17168
  description: "Logo and navigation in one practical horizontal row.",
17147
- structure: "inline-classic",
17148
17169
  variant: "classic",
17149
17170
  defaultPositioning: "sticky",
17150
17171
  shrinkOnScroll: false
@@ -17153,7 +17174,6 @@ const headerLayoutCatalog = defineExactCatalog()([
17153
17174
  id: asHeaderLayoutId("centered"),
17154
17175
  label: "Centered",
17155
17176
  description: "Logo centered above a balanced navigation row.",
17156
- structure: "centered-stack",
17157
17177
  variant: "centered",
17158
17178
  defaultPositioning: "static",
17159
17179
  shrinkOnScroll: false,
@@ -17169,7 +17189,6 @@ const headerLayoutCatalog = defineExactCatalog()([
17169
17189
  id: asHeaderLayoutId("floating"),
17170
17190
  label: "Floating",
17171
17191
  description: "Detached header chrome that sits over the opening section.",
17172
- structure: "floating-shell",
17173
17192
  variant: "floating",
17174
17193
  defaultPositioning: "sticky",
17175
17194
  shrinkOnScroll: true,
@@ -17331,10 +17350,13 @@ const headerStyleCatalog = defineExactCatalog()([
17331
17350
  label: "Clear Split",
17332
17351
  description: "Floating logo with transparent navigation and no shared shell.",
17333
17352
  supportedLayoutIds: supportedLayouts(["floating"]),
17334
- navInteraction: "color-change",
17353
+ navInteraction: "pill-background",
17335
17354
  surface: "floating",
17336
- defaultDepth: "none",
17355
+ defaultDepth: "line",
17337
17356
  navTypography: "plain",
17357
+ openingForegroundTarget: "all",
17358
+ scrollTreatment: "contrast-glass",
17359
+ interactionPalette: clearSplitInteractionPalette,
17338
17360
  moods: ["editorial", "calm"]
17339
17361
  },
17340
17362
  {
@@ -17357,6 +17379,7 @@ const headerStyleCatalog = defineExactCatalog()([
17357
17379
  surface: "floating",
17358
17380
  defaultDepth: "shadow",
17359
17381
  navTypography: "quiet-caps",
17382
+ openingForegroundTarget: "brand-only",
17360
17383
  moods: ["expressive"]
17361
17384
  },
17362
17385
  {
@@ -17368,6 +17391,7 @@ const headerStyleCatalog = defineExactCatalog()([
17368
17391
  surface: "floating",
17369
17392
  defaultDepth: "shadow",
17370
17393
  navTypography: "heading",
17394
+ openingForegroundTarget: "brand-only",
17371
17395
  moods: ["calm", "editorial"]
17372
17396
  }
17373
17397
  ]);
@@ -17869,13 +17893,6 @@ const headerLookCatalog = defineExactCatalog()([
17869
17893
  {
17870
17894
  id: asHeaderLookId("clean-base"),
17871
17895
  label: "Clean base",
17872
- visualTreatment: "solid-neutral",
17873
- layoutBehavior: "sticky",
17874
- configuration: {
17875
- structure: "inline-classic",
17876
- treatment: "solid-neutral",
17877
- behavior: "sticky"
17878
- },
17879
17896
  openingRequirement: "none",
17880
17897
  logoAccommodations: inlineClassicLogoAccommodations,
17881
17898
  compile: cleanBaseHeader
@@ -17883,13 +17900,6 @@ const headerLookCatalog = defineExactCatalog()([
17883
17900
  {
17884
17901
  id: asHeaderLookId("classic-centered-nav"),
17885
17902
  label: "Centered nav",
17886
- visualTreatment: "solid-neutral",
17887
- layoutBehavior: "sticky",
17888
- configuration: {
17889
- structure: "inline-classic",
17890
- treatment: "solid-neutral",
17891
- behavior: "sticky"
17892
- },
17893
17903
  openingRequirement: "none",
17894
17904
  maxRecommendedNavItems: 6,
17895
17905
  logoAccommodations: inlineClassicLogoAccommodations,
@@ -17898,13 +17908,6 @@ const headerLookCatalog = defineExactCatalog()([
17898
17908
  {
17899
17909
  id: asHeaderLookId("brand-solid"),
17900
17910
  label: "Brand solid",
17901
- visualTreatment: "solid-brand",
17902
- layoutBehavior: "sticky-shrink",
17903
- configuration: {
17904
- structure: "inline-classic",
17905
- treatment: "solid-brand",
17906
- behavior: "sticky-shrink"
17907
- },
17908
17911
  openingRequirement: "none",
17909
17912
  logoAccommodations: inlineClassicLogoAccommodations,
17910
17913
  compile: solidBrandHeader
@@ -17912,13 +17915,6 @@ const headerLookCatalog = defineExactCatalog()([
17912
17915
  {
17913
17916
  id: asHeaderLookId("serif-line"),
17914
17917
  label: "Serif line",
17915
- visualTreatment: "light-serif",
17916
- layoutBehavior: "sticky",
17917
- configuration: {
17918
- structure: "centered-stack",
17919
- treatment: "light-serif",
17920
- behavior: "sticky"
17921
- },
17922
17918
  openingRequirement: "none",
17923
17919
  maxRecommendedNavItems: 6,
17924
17920
  logoAccommodations: centeredLogoAccommodations,
@@ -17927,13 +17923,6 @@ const headerLookCatalog = defineExactCatalog()([
17927
17923
  {
17928
17924
  id: asHeaderLookId("centered-calm"),
17929
17925
  label: "Centered calm",
17930
- visualTreatment: "light-serif",
17931
- layoutBehavior: "normal-flow",
17932
- configuration: {
17933
- structure: "centered-stack",
17934
- treatment: "light-serif",
17935
- behavior: "normal-flow"
17936
- },
17937
17926
  openingRequirement: "none",
17938
17927
  maxRecommendedNavItems: 5,
17939
17928
  logoAccommodations: centeredLogoAccommodations,
@@ -17942,13 +17931,6 @@ const headerLookCatalog = defineExactCatalog()([
17942
17931
  {
17943
17932
  id: asHeaderLookId("practical-utility"),
17944
17933
  label: "Practical utility",
17945
- visualTreatment: "solid-neutral",
17946
- layoutBehavior: "sticky-shrink",
17947
- configuration: {
17948
- structure: "inline-classic",
17949
- treatment: "solid-neutral",
17950
- behavior: "sticky-shrink"
17951
- },
17952
17934
  openingRequirement: "none",
17953
17935
  requiresProminentCta: true,
17954
17936
  logoAccommodations: inlineClassicLogoAccommodations,
@@ -17957,13 +17939,6 @@ const headerLookCatalog = defineExactCatalog()([
17957
17939
  {
17958
17940
  id: asHeaderLookId("minimal-transparent"),
17959
17941
  label: "Minimal transparent",
17960
- visualTreatment: "minimal-transparent",
17961
- layoutBehavior: "normal-flow",
17962
- configuration: {
17963
- structure: "inline-classic",
17964
- treatment: "minimal-transparent",
17965
- behavior: "normal-flow"
17966
- },
17967
17942
  openingRequirement: "reserved-space-ok",
17968
17943
  logoAccommodations: inlineClassicLogoAccommodations,
17969
17944
  compile: minimalTransparentHeader
@@ -17971,13 +17946,6 @@ const headerLookCatalog = defineExactCatalog()([
17971
17946
  {
17972
17947
  id: asHeaderLookId("transparent-overlay"),
17973
17948
  label: "Transparent overlay",
17974
- visualTreatment: "transparent-overlay",
17975
- layoutBehavior: "fixed-overlay",
17976
- configuration: {
17977
- structure: "inline-classic",
17978
- treatment: "transparent-overlay",
17979
- behavior: "fixed-overlay"
17980
- },
17981
17949
  openingRequirement: "requires-image-hero-with-contrast-overlay",
17982
17950
  maxRecommendedNavItems: 5,
17983
17951
  logoAccommodations: overlayLogoAccommodations,
@@ -17986,24 +17954,13 @@ const headerLookCatalog = defineExactCatalog()([
17986
17954
  {
17987
17955
  id: asHeaderLookId("floating-glass"),
17988
17956
  label: "Floating glass",
17989
- visualTreatment: "floating-glass",
17990
- layoutBehavior: "fixed-floating",
17991
- configuration: {
17992
- structure: "floating-shell",
17993
- treatment: "floating-glass",
17994
- behavior: "fixed-floating"
17995
- },
17996
17957
  openingRequirement: "requires-image-hero-with-contrast-overlay",
17997
17958
  maxRecommendedNavItems: 5,
17998
17959
  logoAccommodations: overlayLogoAccommodations,
17999
17960
  compile: floatingGlassHeader
18000
17961
  }
18001
17962
  ]);
18002
- new Set(headerLookCatalog.map((look) => headerConfigurationKey(look.configuration)));
18003
17963
  new Map(headerLookCatalog.map((look) => [look.id, look]));
18004
- function headerConfigurationKey(configuration) {
18005
- return `${configuration.structure}:${configuration.treatment}:${configuration.behavior}`;
18006
- }
18007
17964
  //#endregion
18008
17965
  //#region ../theme-core/src/site-styles/sectionTransitions.ts
18009
17966
  function boundaryRuntimeMetrics(family, size, heightExpression) {
@@ -18207,8 +18164,6 @@ const VARIANT_ROLES = [
18207
18164
  "secondary",
18208
18165
  "outline",
18209
18166
  "ghost",
18210
- "link",
18211
- "tertiary",
18212
18167
  "accent"
18213
18168
  ];
18214
18169
  function isVariantRole(value) {
@@ -18220,7 +18175,7 @@ function isVariantRole(value) {
18220
18175
  * IDs become class selectors, so keep the contract deliberately narrower than
18221
18176
  * an arbitrary string and shared with every authoring/runtime boundary.
18222
18177
  */
18223
- const buttonVariantIdSchema = z$1.string().min(1).max(50).regex(/^[a-z0-9-]+$/, "Button variant IDs may contain lowercase letters, numbers, and hyphens only");
18178
+ const buttonVariantIdSchema = z$1.string().min(1).max(50).regex(/^[a-z0-9-]+$/, "Button variant IDs may contain lowercase letters, numbers, and hyphens only").refine((value) => value !== "link" && value !== "tertiary", { message: "Retired button role IDs are not valid variant IDs" });
18224
18179
  function asSpecialVariantId(value) {
18225
18180
  const parsed = buttonVariantIdSchema.safeParse(value);
18226
18181
  if (!parsed.success) throw new Error("SpecialVariantId must be a CSS-safe button variant ID");
@@ -21411,39 +21366,39 @@ function defaultTypographyForRecipe(recipe) {
21411
21366
  }
21412
21367
  //#endregion
21413
21368
  //#region ../theme-core/src/lib/media.ts
21414
- const hotspotSchema$1 = z.object({
21369
+ const hotspotSchema = z.object({
21415
21370
  x: z.number().min(0).max(1),
21416
21371
  y: z.number().min(0).max(1),
21417
21372
  radius: z.number().optional()
21418
21373
  });
21419
- const rotationSchema$1 = z.union([
21374
+ const rotationSchema = z.union([
21420
21375
  z.literal(0),
21421
21376
  z.literal(90),
21422
21377
  z.literal(180),
21423
21378
  z.literal(270)
21424
21379
  ]);
21425
- const rectSchema$1 = z.tuple([
21380
+ const rectSchema = z.tuple([
21426
21381
  z.number(),
21427
21382
  z.number(),
21428
21383
  z.number(),
21429
21384
  z.number()
21430
21385
  ]);
21431
- const aspectCropSchema$1 = z.object({
21386
+ const aspectCropSchema = z.object({
21432
21387
  aspect: z.preprocess((value) => value == null ? void 0 : value, z.string().optional()),
21433
- rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema$1.optional()),
21434
- hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema$1.optional()),
21435
- rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema$1.optional())
21388
+ rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema.optional()),
21389
+ hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema.optional()),
21390
+ rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema.optional())
21436
21391
  });
21437
- const transformSchema$1 = z.object({
21392
+ const transformSchema = z.object({
21438
21393
  aspectCrops: z.preprocess((value) => {
21439
21394
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
21440
21395
  return value;
21441
- }, z.record(z.string(), aspectCropSchema$1.catch({}))).optional(),
21442
- rect: rectSchema$1.optional(),
21443
- hotspot: hotspotSchema$1.optional(),
21444
- rotation: rotationSchema$1.optional()
21396
+ }, z.record(z.string(), aspectCropSchema.catch({}))).optional(),
21397
+ rect: rectSchema.optional(),
21398
+ hotspot: hotspotSchema.optional(),
21399
+ rotation: rotationSchema.optional()
21445
21400
  });
21446
- const mediaSchema$1 = z.object({
21401
+ const mediaSchema = z.object({
21447
21402
  type: z.enum([
21448
21403
  "image",
21449
21404
  "video",
@@ -21464,7 +21419,7 @@ const mediaSchema$1 = z.object({
21464
21419
  height: z.number().optional(),
21465
21420
  storageBucket: z.string().optional(),
21466
21421
  storagePath: z.string().optional(),
21467
- transform: transformSchema$1.optional()
21422
+ transform: transformSchema.optional()
21468
21423
  });
21469
21424
  //#endregion
21470
21425
  //#region ../theme-core/src/palette/schema.ts
@@ -22297,264 +22252,6 @@ function generateInteractiveChildInheritanceCSS(selector) {
22297
22252
  return `\n${selector} * {\n font-family: inherit;\n font-weight: inherit;\n font-style: inherit;\n letter-spacing: inherit;\n text-transform: inherit;\n color: inherit;\n}\n`;
22298
22253
  }
22299
22254
  //#endregion
22300
- //#region ../theme-core/src/buttons/effects/presets/background.ts
22301
- /**
22302
- * Darken background on hover
22303
- *
22304
- * Works with solid backgrounds only. Darkens the background color by adjusting the shade.
22305
- */
22306
- const darkenBackgroundEffect = {
22307
- id: "darken-background",
22308
- name: "Darken on Hover",
22309
- description: "Darkens the background color on hover",
22310
- category: "background",
22311
- pseudoElement: "none",
22312
- applicableTo: ["button"],
22313
- customizableOption: {
22314
- name: "amount",
22315
- type: "select",
22316
- label: "Darken Amount (shade step)",
22317
- default: 100,
22318
- options: [
22319
- 0,
22320
- 100,
22321
- 200,
22322
- 300,
22323
- 400,
22324
- 500,
22325
- 600,
22326
- 700,
22327
- 800,
22328
- 900
22329
- ]
22330
- },
22331
- isApplicable: (buttonConfig) => {
22332
- return buttonConfig.background.type === "solid";
22333
- },
22334
- generateCSS: (ctx) => {
22335
- const { themeId, variantId, options, tokens, buttonConfig } = ctx;
22336
- if (buttonConfig.background.type !== "solid") return "";
22337
- const amount = options.amount || 100;
22338
- const baseToken = buttonConfig.background.colorToken ?? "primary-500";
22339
- const darkerToken = tokens.adjustShade(baseToken, amount);
22340
- return `
22341
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22342
- background-color: ${tokens.getColor(darkerToken)};
22343
- }
22344
- `;
22345
- }
22346
- };
22347
- /**
22348
- * Lighten background on hover
22349
- *
22350
- * Works with solid backgrounds only. Lightens the background color by adjusting the shade.
22351
- */
22352
- const lightenBackgroundEffect = {
22353
- id: "lighten-background",
22354
- name: "Lighten on Hover",
22355
- description: "Lightens the background color on hover",
22356
- category: "background",
22357
- pseudoElement: "none",
22358
- applicableTo: ["button"],
22359
- customizableOption: {
22360
- name: "amount",
22361
- type: "select",
22362
- label: "Lighten Amount (shade step)",
22363
- default: 100,
22364
- options: [
22365
- 0,
22366
- 100,
22367
- 200,
22368
- 300,
22369
- 400,
22370
- 500,
22371
- 600,
22372
- 700,
22373
- 800,
22374
- 900
22375
- ]
22376
- },
22377
- isApplicable: (buttonConfig) => {
22378
- return buttonConfig.background.type === "solid";
22379
- },
22380
- generateCSS: (ctx) => {
22381
- const { themeId, variantId, options, tokens, buttonConfig } = ctx;
22382
- if (buttonConfig.background.type !== "solid") return "";
22383
- const amount = options.amount || 100;
22384
- const baseToken = buttonConfig.background.colorToken ?? "primary-500";
22385
- const lighterToken = tokens.adjustShade(baseToken, -amount);
22386
- return `
22387
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22388
- background-color: ${tokens.getColor(lighterToken)};
22389
- }
22390
- `;
22391
- }
22392
- };
22393
- /**
22394
- * Fade background on hover (reduce opacity)
22395
- *
22396
- * Works with all background types.
22397
- */
22398
- const fadeBackgroundEffect = {
22399
- id: "fade-background",
22400
- name: "Fade on Hover",
22401
- description: "Reduces background opacity on hover",
22402
- category: "background",
22403
- pseudoElement: "none",
22404
- applicableTo: ["nav-link"],
22405
- customizableOption: {
22406
- name: "opacity",
22407
- type: "percentage",
22408
- label: "Hover Opacity",
22409
- default: 80
22410
- },
22411
- generateCSS: (ctx) => {
22412
- const { themeId, variantId, options } = ctx;
22413
- return `
22414
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22415
- opacity: ${(options.opacity || 80) / 100};
22416
- }
22417
- `;
22418
- }
22419
- };
22420
- /**
22421
- * Reduce opacity on hover (simple opacity reduction)
22422
- *
22423
- * Navigation-link effect that reduces opacity by a percentage (default 15%).
22424
- */
22425
- const opacityReduceEffect = {
22426
- id: "opacity-reduce",
22427
- name: "Reduce Opacity",
22428
- description: "Reduces navigation-link opacity on hover by a percentage",
22429
- category: "background",
22430
- pseudoElement: "none",
22431
- applicableTo: ["nav-link"],
22432
- customizableOption: {
22433
- name: "reduction",
22434
- type: "percentage",
22435
- label: "Opacity Reduction",
22436
- default: 15
22437
- },
22438
- generateCSS: (ctx) => {
22439
- const { themeId, variantId, options } = ctx;
22440
- return `
22441
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22442
- opacity: ${1 - (options.reduction || 15) / 100};
22443
- }
22444
- `;
22445
- }
22446
- };
22447
- /**
22448
- * Animated gradient background
22449
- *
22450
- * Animates a gradient background by shifting its position on hover.
22451
- * Works with gradient backgrounds only.
22452
- *
22453
- * Sets background-size to 200% and animates background-position from left to right.
22454
- */
22455
- const animatedGradientEffect = {
22456
- id: "animated-gradient",
22457
- name: "Animated Gradient",
22458
- description: "Animates gradient position on hover",
22459
- category: "background",
22460
- pseudoElement: "none",
22461
- applicableTo: ["button"],
22462
- customizableOption: {
22463
- name: "direction",
22464
- type: "select",
22465
- label: "Animation Direction",
22466
- default: "horizontal",
22467
- options: ["horizontal", "vertical"]
22468
- },
22469
- isApplicable: (buttonConfig) => {
22470
- return buttonConfig.background.type === "gradient";
22471
- },
22472
- generateCSS: (ctx) => {
22473
- const { themeId, variantId, options, buttonConfig } = ctx;
22474
- if (buttonConfig.background.type !== "gradient") return "";
22475
- const direction = options.direction || "horizontal";
22476
- return `
22477
- /* Setup animated gradient */
22478
- :where([data-theme-scope="${themeId}"]) .${variantId} {
22479
- background-size: ${direction === "horizontal" ? "200% auto" : "auto 200%"};
22480
- background-position: left center;
22481
- transition: background-position 0.3s ease;
22482
- }
22483
-
22484
- /* Animate gradient on hover */
22485
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22486
- background-position: ${direction === "horizontal" ? "right center" : "center bottom"};
22487
- }
22488
- `;
22489
- }
22490
- };
22491
- /**
22492
- * Add background color on hover
22493
- *
22494
- * Works best with transparent backgrounds. Adds a solid background color on hover.
22495
- */
22496
- const backgroundOnHoverEffect = {
22497
- id: "background-on-hover",
22498
- name: "Background on Hover",
22499
- description: "Adds background color on hover",
22500
- category: "background",
22501
- pseudoElement: "none",
22502
- applicableTo: ["button", "nav-link"],
22503
- customizableOption: {
22504
- name: "colorToken",
22505
- type: "select",
22506
- label: "Background Color",
22507
- default: "neutral-800",
22508
- options: [
22509
- "neutral-700",
22510
- "neutral-800",
22511
- "neutral-900",
22512
- "primary"
22513
- ]
22514
- },
22515
- generateCSS: (ctx) => {
22516
- const { themeId, variantId, options, tokens, buttonConfig } = ctx;
22517
- const colorToken = options.colorToken || "neutral-800";
22518
- return `
22519
- /* Add background on hover */
22520
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22521
- background-color: ${tokens.getColor(colorToken)};${"textColorToken" in buttonConfig && typeof options.textColorToken === "string" ? `\n color: ${tokens.getColor(options.textColorToken)};` : ""}
22522
- }
22523
- `;
22524
- }
22525
- };
22526
- /**
22527
- * Add semi-transparent background color on hover
22528
- *
22529
- * Adds a background with opacity/alpha channel. Perfect for retro/arcade styles.
22530
- */
22531
- const backgroundOnHoverAlphaEffect = {
22532
- id: "background-on-hover-alpha",
22533
- name: "Background on Hover (Transparent)",
22534
- description: "Adds semi-transparent background on hover",
22535
- category: "background",
22536
- pseudoElement: "none",
22537
- applicableTo: ["nav-link"],
22538
- customizableOption: {
22539
- name: "opacity",
22540
- type: "percentage",
22541
- label: "Opacity",
22542
- default: 50
22543
- },
22544
- generateCSS: (ctx) => {
22545
- const { themeId, variantId, stateGroup, options } = ctx;
22546
- const rawOpacity = options.opacity;
22547
- const clampedOpacity = Math.max(0, Math.min(100, typeof rawOpacity === "number" && !Number.isNaN(rawOpacity) ? rawOpacity : 50));
22548
- const cssVar = `var(--tb-${options.colorToken || "neutral-800"})`;
22549
- return `
22550
- /* Add semi-transparent background (${stateGroup}) */
22551
- :where([data-theme-scope="${themeId}"]) .${variantId}${stateGroup === "base" ? "" : `:${stateGroup}`} {
22552
- background-color: rgb(${cssVar} / ${clampedOpacity}%);
22553
- }
22554
- `;
22555
- }
22556
- };
22557
- //#endregion
22558
22255
  //#region ../theme-core/src/buttons/effects/cssUtils.ts
22559
22256
  /**
22560
22257
  * CSS Utilities for Effect Presets
@@ -22606,6 +22303,71 @@ function generateStateCSS(themeId, variantId, state, cssProperties) {
22606
22303
  `;
22607
22304
  }
22608
22305
  //#endregion
22306
+ //#region ../theme-core/src/buttons/effects/presets/background.ts
22307
+ /**
22308
+ * Darken background on hover
22309
+ *
22310
+ * Works with solid backgrounds only. Darkens the background color by adjusting the shade.
22311
+ */
22312
+ const darkenBackgroundEffect = shadeBackgroundEffect({
22313
+ id: "darken-background",
22314
+ name: "Darken on Hover",
22315
+ description: "Darkens the background color on hover",
22316
+ label: "Darken Amount (shade step)",
22317
+ shadeDirection: 1
22318
+ });
22319
+ /**
22320
+ * Lighten background on hover
22321
+ *
22322
+ * Works with solid backgrounds only. Lightens the background color by adjusting the shade.
22323
+ */
22324
+ const lightenBackgroundEffect = shadeBackgroundEffect({
22325
+ id: "lighten-background",
22326
+ name: "Lighten on Hover",
22327
+ description: "Lightens the background color on hover",
22328
+ label: "Lighten Amount (shade step)",
22329
+ shadeDirection: -1
22330
+ });
22331
+ function shadeBackgroundEffect(config) {
22332
+ return {
22333
+ id: config.id,
22334
+ name: config.name,
22335
+ description: config.description,
22336
+ category: "background",
22337
+ pseudoElement: "none",
22338
+ applicableTo: ["button"],
22339
+ customizableOption: {
22340
+ name: "amount",
22341
+ type: "select",
22342
+ label: config.label,
22343
+ default: 100,
22344
+ options: [
22345
+ 0,
22346
+ 100,
22347
+ 200,
22348
+ 300,
22349
+ 400,
22350
+ 500,
22351
+ 600,
22352
+ 700,
22353
+ 800,
22354
+ 900
22355
+ ]
22356
+ },
22357
+ isApplicable: (buttonConfig) => buttonConfig.background.type === "solid",
22358
+ generateCSS: ({ themeId, variantId, options, tokens, buttonConfig }) => {
22359
+ if (buttonConfig.background.type !== "solid") return "";
22360
+ const amount = (options.amount || 100) * config.shadeDirection;
22361
+ const baseToken = buttonConfig.background.colorToken ?? "primary-500";
22362
+ return `
22363
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22364
+ background-color: ${tokens.getColor(tokens.adjustShade(baseToken, amount))};
22365
+ }
22366
+ `;
22367
+ }
22368
+ };
22369
+ }
22370
+ //#endregion
22609
22371
  //#region ../theme-core/src/buttons/effects/registry.ts
22610
22372
  /**
22611
22373
  * Registry of all available effect presets
@@ -22613,11 +22375,144 @@ function generateStateCSS(themeId, variantId, state, cssProperties) {
22613
22375
  const EFFECT_PRESETS = [
22614
22376
  darkenBackgroundEffect,
22615
22377
  lightenBackgroundEffect,
22616
- fadeBackgroundEffect,
22617
- opacityReduceEffect,
22618
- animatedGradientEffect,
22619
- backgroundOnHoverEffect,
22620
- backgroundOnHoverAlphaEffect,
22378
+ {
22379
+ id: "fade-background",
22380
+ name: "Fade on Hover",
22381
+ description: "Reduces background opacity on hover",
22382
+ category: "background",
22383
+ pseudoElement: "none",
22384
+ applicableTo: ["nav-link"],
22385
+ customizableOption: {
22386
+ name: "opacity",
22387
+ type: "percentage",
22388
+ label: "Hover Opacity",
22389
+ default: 80
22390
+ },
22391
+ generateCSS: (ctx) => {
22392
+ const { themeId, variantId, options } = ctx;
22393
+ return `
22394
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22395
+ opacity: ${(options.opacity || 80) / 100};
22396
+ }
22397
+ `;
22398
+ }
22399
+ },
22400
+ {
22401
+ id: "opacity-reduce",
22402
+ name: "Reduce Opacity",
22403
+ description: "Reduces navigation-link opacity on hover by a percentage",
22404
+ category: "background",
22405
+ pseudoElement: "none",
22406
+ applicableTo: ["nav-link"],
22407
+ customizableOption: {
22408
+ name: "reduction",
22409
+ type: "percentage",
22410
+ label: "Opacity Reduction",
22411
+ default: 15
22412
+ },
22413
+ generateCSS: (ctx) => {
22414
+ const { themeId, variantId, options } = ctx;
22415
+ return `
22416
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22417
+ opacity: ${1 - (options.reduction || 15) / 100};
22418
+ }
22419
+ `;
22420
+ }
22421
+ },
22422
+ {
22423
+ id: "animated-gradient",
22424
+ name: "Animated Gradient",
22425
+ description: "Animates gradient position on hover",
22426
+ category: "background",
22427
+ pseudoElement: "none",
22428
+ applicableTo: ["button"],
22429
+ customizableOption: {
22430
+ name: "direction",
22431
+ type: "select",
22432
+ label: "Animation Direction",
22433
+ default: "horizontal",
22434
+ options: ["horizontal", "vertical"]
22435
+ },
22436
+ isApplicable: (buttonConfig) => {
22437
+ return buttonConfig.background.type === "gradient";
22438
+ },
22439
+ generateCSS: (ctx) => {
22440
+ const { themeId, variantId, options, buttonConfig } = ctx;
22441
+ if (buttonConfig.background.type !== "gradient") return "";
22442
+ const direction = options.direction || "horizontal";
22443
+ return `
22444
+ /* Setup animated gradient */
22445
+ :where([data-theme-scope="${themeId}"]) .${variantId} {
22446
+ background-size: ${direction === "horizontal" ? "200% auto" : "auto 200%"};
22447
+ background-position: left center;
22448
+ transition: background-position 0.3s ease;
22449
+ }
22450
+
22451
+ /* Animate gradient on hover */
22452
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
22453
+ background-position: ${direction === "horizontal" ? "right center" : "center bottom"};
22454
+ }
22455
+ `;
22456
+ }
22457
+ },
22458
+ {
22459
+ id: "background-on-hover",
22460
+ name: "Background on Hover",
22461
+ description: "Adds background color on hover",
22462
+ category: "background",
22463
+ pseudoElement: "none",
22464
+ applicableTo: ["button", "nav-link"],
22465
+ customizableOption: {
22466
+ name: "colorToken",
22467
+ type: "select",
22468
+ label: "Background Color",
22469
+ default: "neutral-800",
22470
+ options: [
22471
+ "neutral-700",
22472
+ "neutral-800",
22473
+ "neutral-900",
22474
+ "primary"
22475
+ ]
22476
+ },
22477
+ generateCSS: (ctx) => {
22478
+ const { themeId, variantId, stateGroup, options, tokens, buttonConfig } = ctx;
22479
+ const colorToken = options.colorToken || "neutral-800";
22480
+ const color = tokens.getColor(colorToken);
22481
+ const navForeground = "textColorToken" in buttonConfig && typeof options.textColorToken === "string" ? `\n color: ${tokens.getColor(options.textColorToken)};` : "";
22482
+ return `
22483
+ /* Add background on hover */
22484
+ ${getStateSelector(themeId, variantId, stateGroup)} {
22485
+ background-color: ${color};${navForeground}
22486
+ }
22487
+ `;
22488
+ }
22489
+ },
22490
+ {
22491
+ id: "background-on-hover-alpha",
22492
+ name: "Background on Hover (Transparent)",
22493
+ description: "Adds semi-transparent background on hover",
22494
+ category: "background",
22495
+ pseudoElement: "none",
22496
+ applicableTo: ["nav-link"],
22497
+ customizableOption: {
22498
+ name: "opacity",
22499
+ type: "percentage",
22500
+ label: "Opacity",
22501
+ default: 50
22502
+ },
22503
+ generateCSS: (ctx) => {
22504
+ const { themeId, variantId, stateGroup, options } = ctx;
22505
+ const rawOpacity = options.opacity;
22506
+ const clampedOpacity = Math.max(0, Math.min(100, typeof rawOpacity === "number" && !Number.isNaN(rawOpacity) ? rawOpacity : 50));
22507
+ const cssVar = `var(--tb-${options.colorToken || "neutral-800"})`;
22508
+ return `
22509
+ /* Add semi-transparent background (${stateGroup}) */
22510
+ :where([data-theme-scope="${themeId}"]) .${variantId}${stateGroup === "base" ? "" : `:${stateGroup}`} {
22511
+ background-color: rgb(${cssVar} / ${clampedOpacity}%);
22512
+ }
22513
+ `;
22514
+ }
22515
+ },
22621
22516
  {
22622
22517
  id: "border-glow",
22623
22518
  name: "Border Glow",
@@ -25556,6 +25451,166 @@ function resolveOnColorForThemeToken(token) {
25556
25451
  return shade <= 400 ? "#000000" : "#FFFFFF";
25557
25452
  }
25558
25453
  //#endregion
25454
+ //#region ../theme-core/src/header/paintTargets.ts
25455
+ /** Resolve the element that owns the visible header surface for each layout. */
25456
+ function getHeaderPaintTargets(variant, themeId, state = "base") {
25457
+ const scope = `:where([data-theme-scope="${themeId}"])`;
25458
+ const scrolledRoot = state === "scrolled" ? ".header-root.header-scrolled " : "";
25459
+ if (variant === "floating") {
25460
+ if (state === "scrolled") {
25461
+ const desktopOwner = `${scope} ${scrolledRoot}.header-floating-container`;
25462
+ const mobileOwner = `${scope} ${scrolledRoot}.header-mobile-bar`;
25463
+ return [{
25464
+ kind: "viewport-band",
25465
+ clipSelector: `${scope}:has(.header-root.header-scrolled)`,
25466
+ ownerSelector: desktopOwner,
25467
+ selector: `${desktopOwner}::before`,
25468
+ mediaQuery: MQ_MD_UP,
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
+ }
25479
+ },
25480
+ ownerNeedsPositioning: false
25481
+ }, {
25482
+ kind: "viewport-band",
25483
+ clipSelector: `${scope}:has(.header-root.header-scrolled)`,
25484
+ ownerSelector: mobileOwner,
25485
+ selector: `${mobileOwner}::before`,
25486
+ mediaQuery: MQ_MD_DOWN,
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
+ }
25497
+ },
25498
+ ownerNeedsPositioning: true
25499
+ }];
25500
+ }
25501
+ return [{
25502
+ kind: "element-box",
25503
+ selector: `${scope} ${scrolledRoot}.header-floating-container`,
25504
+ mediaQuery: MQ_MD_UP
25505
+ }, {
25506
+ kind: "element-box",
25507
+ selector: `${scope} ${scrolledRoot}.header-mobile-bar`,
25508
+ mediaQuery: MQ_MD_DOWN
25509
+ }];
25510
+ }
25511
+ return [{
25512
+ kind: "element-box",
25513
+ selector: `${scope} .header-root${state === "scrolled" ? ".header-scrolled" : ""}::before`,
25514
+ pseudoElement: "inset"
25515
+ }];
25516
+ }
25517
+ function renderHeaderPaintTargetRules(targets, rules) {
25518
+ return targets.map((target) => {
25519
+ const block = renderHeaderPaintTargetRule(target, rules);
25520
+ return target.mediaQuery ? `@media ${target.mediaQuery} {\n${block}\n}` : block;
25521
+ }).join("\n");
25522
+ }
25523
+ function renderHeaderPaintTargetRule(target, rules) {
25524
+ switch (target.kind) {
25525
+ case "element-box": {
25526
+ const pseudoElementSetup = target.pseudoElement === "inset" ? [
25527
+ "content: \"\";",
25528
+ "position: absolute;",
25529
+ "inset: 0;",
25530
+ "pointer-events: none;",
25531
+ "border-radius: inherit;",
25532
+ "z-index: -1;"
25533
+ ] : [];
25534
+ return `${target.selector} {\n ${[...pseudoElementSetup, ...rules].join("\n ")}\n}`;
25535
+ }
25536
+ case "viewport-band": {
25537
+ const { top, bottom } = target.extent;
25538
+ const ownerRules = [
25539
+ `${top.customProperty}: ${top.value};`,
25540
+ `${bottom.customProperty}: ${bottom.value};`,
25541
+ `${top.ownerProperty}: var(${top.customProperty});`,
25542
+ ...target.ownerNeedsPositioning ? ["position: relative;"] : [],
25543
+ "isolation: isolate;",
25544
+ "background: none;",
25545
+ "backdrop-filter: none;",
25546
+ "-webkit-backdrop-filter: none;",
25547
+ "border: 0;",
25548
+ "box-shadow: none;"
25549
+ ];
25550
+ const bandRules = [
25551
+ "content: \"\";",
25552
+ "position: absolute;",
25553
+ `top: calc(-1 * var(${top.customProperty}));`,
25554
+ `bottom: calc(-1 * var(${bottom.customProperty}));`,
25555
+ "left: 50%;",
25556
+ "width: 100vw;",
25557
+ "transform: translateX(-50%);",
25558
+ "pointer-events: none;",
25559
+ "border-radius: 0;",
25560
+ "z-index: -1;",
25561
+ ...rules
25562
+ ];
25563
+ return `${target.clipSelector} {\n overflow-x: clip;\n}\n${target.ownerSelector} {\n ${ownerRules.join("\n ")}\n}\n${target.selector} {\n ${bandRules.join("\n ")}\n}`;
25564
+ }
25565
+ }
25566
+ }
25567
+ //#endregion
25568
+ //#region ../theme-core/src/header/scrollTreatment.ts
25569
+ const headerScrollTreatmentSchema = z$1.discriminatedUnion("kind", [z$1.object({
25570
+ kind: z$1.literal("contrast-glass"),
25571
+ backgroundTone: z$1.enum(["light", "dark"])
25572
+ })]).optional();
25573
+ const CONTRAST_GLASS_BLUR = "blur(12px)";
25574
+ function generateMobileOverlayBackdropFilterFix(themeId, variant) {
25575
+ const root = `:where([data-theme-scope="${themeId}"]) .header-root:has([data-nav-mobile-overlay][aria-hidden="false"])`;
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`;
25577
+ }
25578
+ function generateHeaderScrollTreatmentStyles(treatment, themeId, variant, surfaceRules = []) {
25579
+ if (!treatment) return "";
25580
+ switch (treatment.kind) {
25581
+ case "contrast-glass": {
25582
+ const backgroundChannels = treatment.backgroundTone === "dark" ? "0 0 0" : "255 255 255";
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
+ ]);
25589
+ }
25590
+ }
25591
+ }
25592
+ //#endregion
25593
+ //#region ../theme-core/src/header/containerSchema.ts
25594
+ const headerContainerSchema = z$1.object({
25595
+ rounded: z$1.enum([
25596
+ "none",
25597
+ "sm",
25598
+ "md",
25599
+ "lg",
25600
+ "xl",
25601
+ "2xl"
25602
+ ]).default("xl"),
25603
+ border: z$1.boolean().default(true),
25604
+ shadow: z$1.boolean().default(true),
25605
+ padding: z$1.enum([
25606
+ "sm",
25607
+ "md",
25608
+ "lg"
25609
+ ]).default("md"),
25610
+ tint: z$1.string().nullable().optional(),
25611
+ opacity: z$1.number().min(0).max(1).default(.12)
25612
+ }).optional();
25613
+ //#endregion
25559
25614
  //#region ../theme-core/src/schema.ts
25560
25615
  const axesSchema = z$1.object({
25561
25616
  tone: z$1.enum([
@@ -25716,7 +25771,7 @@ const boxBackgroundSchema = z$1.object({
25716
25771
  color: tokenOrCssColorValueSchema.nullable().optional(),
25717
25772
  gradient: z$1.string().nullable().optional(),
25718
25773
  gradientPresetId: z$1.string().min(1).nullable().optional(),
25719
- image: mediaSchema$1.nullable().optional(),
25774
+ image: mediaSchema.nullable().optional(),
25720
25775
  objectFit: z$1.enum([
25721
25776
  "fill",
25722
25777
  "fit",
@@ -25964,25 +26019,6 @@ const navFontWeight = z$1.enum([
25964
26019
  ]);
25965
26020
  const headerMaxWidth = z$1.enum(["container", "full"]);
25966
26021
  const headerBarFrame = z$1.enum(["full-bleed", "inset-shell"]);
25967
- const headerContainerSchema = z$1.object({
25968
- rounded: z$1.enum([
25969
- "none",
25970
- "sm",
25971
- "md",
25972
- "lg",
25973
- "xl",
25974
- "2xl"
25975
- ]).default("xl"),
25976
- border: z$1.boolean().default(true),
25977
- shadow: z$1.boolean().default(true),
25978
- padding: z$1.enum([
25979
- "sm",
25980
- "md",
25981
- "lg"
25982
- ]).default("md"),
25983
- tint: z$1.string().nullable().optional(),
25984
- opacity: z$1.number().min(0).max(1).default(.12)
25985
- }).optional();
25986
26022
  const headerBorderSchema = componentBorderSchema.extend({ position: z$1.enum([
25987
26023
  "bottom",
25988
26024
  "top",
@@ -26100,7 +26136,7 @@ const headerBackgroundSchema = z$1.object({
26100
26136
  contentOwner: z$1.literal(siteChromeBackgroundOverrideOwner).optional(),
26101
26137
  color: tokenOrCssColorValueSchema.nullable().optional(),
26102
26138
  gradient: gradientConfigSchema.nullable().optional(),
26103
- image: mediaSchema$1.nullable().optional(),
26139
+ image: mediaSchema.nullable().optional(),
26104
26140
  textColor: tokenOrCssColorValueSchema.nullable().optional()
26105
26141
  });
26106
26142
  const headerSchema = z$1.object({
@@ -26109,7 +26145,8 @@ const headerSchema = z$1.object({
26109
26145
  shrinkOnScroll: z$1.boolean(),
26110
26146
  maxWidth: headerMaxWidth,
26111
26147
  barFrame: headerBarFrame.optional(),
26112
- logoOverride: mediaSchema$1.nullable().optional(),
26148
+ scrollTreatment: headerScrollTreatmentSchema,
26149
+ logoOverride: mediaSchema.nullable().optional(),
26113
26150
  background: headerBackgroundSchema.default({
26114
26151
  type: "color",
26115
26152
  color: "surface"
@@ -26121,6 +26158,7 @@ const headerSchema = z$1.object({
26121
26158
  navFontRole: z$1.enum(["body", "heading"]).optional(),
26122
26159
  navTypography: z$1.enum(["body", "heading"]).optional(),
26123
26160
  navTextSize: navLinkStyleSchema.shape.textSize,
26161
+ interactionPalette: headerInteractionPaletteSchema.optional(),
26124
26162
  navPlacement: z$1.enum(["end", "center"]).optional(),
26125
26163
  container: headerContainerSchema,
26126
26164
  border: headerBorderSchema,
@@ -31597,15 +31635,6 @@ const heroCopyFragment = defineFragment({
31597
31635
  */
31598
31636
  const BLOCK_BUTTON_ROLES = PUBLIC_BUTTON_ROLES;
31599
31637
  const blockButtonRoleSchema = z$1.enum(BLOCK_BUTTON_ROLES);
31600
- /**
31601
- * Temporary rollout boundary for persisted content written before issue #1220.
31602
- * Authoring remains strict through `blockButtonRoleSchema`; this parser exists
31603
- * only until the post-deploy role rewrite has been audited in production.
31604
- */
31605
- function canonicalizePersistedBlockButtonRole(value) {
31606
- return value === "link" || value === "tertiary" ? "ghost" : value;
31607
- }
31608
- const persistedBlockButtonRoleSchema = z$1.preprocess((value) => typeof value === "string" ? canonicalizePersistedBlockButtonRole(value) : value, blockButtonRoleSchema);
31609
31638
  const BLOCK_BUTTON_ROLE_LABELS = {
31610
31639
  primary: "Primary",
31611
31640
  secondary: "Secondary",
@@ -33883,6 +33912,7 @@ const newsletterFormFragment = defineFragment({
33883
33912
  }
33884
33913
  ],
33885
33914
  layout: [el("newsletter-form", withApiBindings({
33915
+ source: "block",
33886
33916
  destinationProvider: { $bind: { from: "destinationProvider" } },
33887
33917
  listId: { $bind: { from: "listId" } },
33888
33918
  preset: { $bind: { from: "preset" } },
@@ -35405,6 +35435,7 @@ const contactNewsletterLayout = styledSection({
35405
35435
  as: "h2",
35406
35436
  className: "newsletter-copy-title"
35407
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",
35408
35439
  listId: { $bind: { from: "listId" } },
35409
35440
  preset: { $bind: { from: "preset" } },
35410
35441
  includePhone: { $bind: { from: "includePhone" } },
@@ -37402,6 +37433,22 @@ const footerNavGroupsLayout = stack({
37402
37433
  }, [text({ as: "span" }, bind("entry.label"))], repeat("group.children", "entry"))])], repeat("footerMenu.groups", "group"))], whenCollectionHasItems("footerMenu.groups"));
37403
37434
  //#endregion
37404
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" } } };
37405
37452
  const brandLogo = link({
37406
37453
  href: "/",
37407
37454
  className: { $bind: {
@@ -37479,6 +37526,23 @@ const authoredCopy = richText({
37479
37526
  id: "content.interpolateRichTextTokens",
37480
37527
  options: { tokens: ["year", "site_name"] }
37481
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" }));
37482
37546
  const footerGroup = stack({
37483
37547
  gap: "md",
37484
37548
  align: "stretch",
@@ -37504,6 +37568,7 @@ const footerGroup = stack({
37504
37568
  contact,
37505
37569
  hours,
37506
37570
  socials,
37571
+ footerEngagement,
37507
37572
  stack({ className: "rb-w-full" }, [authoredCopy], when("module.kind", { equals: "supporting-text" })),
37508
37573
  stack({ className: "rb-w-full rb-lg-col-span-3" }, [authoredCopy], when("module.kind", { equals: "legal" }))
37509
37574
  ], repeat("group.modules", "module"))], repeat("region.groups", "group"));
@@ -37511,6 +37576,10 @@ const footerMainRegion = stack({
37511
37576
  className: { $bind: { from: "region.className" } },
37512
37577
  "data-footer-region": { $bind: { from: "region.kind" } }
37513
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"));
37514
37583
  const footerBottomRegion = stack({ className: { $bind: {
37515
37584
  from: "$root.theme.footer",
37516
37585
  transforms: [{ id: "layout.footerBottomBarContainerClass" }],
@@ -37546,7 +37615,11 @@ const siteFooterBlockDefinition = { manifest: createBlockManifest({
37546
37615
  fallback: mergeStyles(backgroundColorStyle("surface"), surfaceForegroundStyle({ text: "rgb(var(--tb-text))" }), borderColorStyle("border"))
37547
37616
  } },
37548
37617
  "data-footer-membership": { $bind: { from: "content.footerRuntime.membershipKey" } }
37549
- }, [footerMainRegion, footerBottomRegion]),
37618
+ }, [
37619
+ footerEngagementRegion,
37620
+ footerMainRegion,
37621
+ footerBottomRegion
37622
+ ]),
37550
37623
  description: "Site-wide composed footer with canonical shared details.",
37551
37624
  styleTokens: { spacing: "md" },
37552
37625
  paletteHidden: true
@@ -39377,84 +39450,6 @@ const weeklySlotAvailabilityBlockDefinition = {
39377
39450
  mode: "server"
39378
39451
  } }
39379
39452
  };
39380
- const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
39381
- "document",
39382
- "spreadsheet",
39383
- "archive",
39384
- "audio"
39385
- ];
39386
- const hotspotSchema = z.object({
39387
- x: z.number().min(0).max(1),
39388
- y: z.number().min(0).max(1),
39389
- radius: z.number().optional()
39390
- });
39391
- const rotationSchema = z.union([
39392
- z.literal(0),
39393
- z.literal(90),
39394
- z.literal(180),
39395
- z.literal(270)
39396
- ]);
39397
- const rectSchema = z.tuple([
39398
- z.number(),
39399
- z.number(),
39400
- z.number(),
39401
- z.number()
39402
- ]);
39403
- const aspectCropSchema = z.object({
39404
- aspect: z.preprocess((value) => value == null ? void 0 : value, z.string().optional()),
39405
- rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema.optional()),
39406
- hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema.optional()),
39407
- rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema.optional())
39408
- });
39409
- const transformSchema = z.object({
39410
- aspectCrops: z.preprocess((value) => {
39411
- if (!value || typeof value !== "object" || Array.isArray(value)) return;
39412
- return value;
39413
- }, z.record(z.string(), aspectCropSchema.catch({}))).optional(),
39414
- rect: rectSchema.optional(),
39415
- hotspot: hotspotSchema.optional(),
39416
- rotation: rotationSchema.optional()
39417
- });
39418
- const mediaPosterSchema = z.discriminatedUnion("tag", [z.object({
39419
- tag: z.literal("storage"),
39420
- assetId: z.string().optional(),
39421
- storageBucket: z.string().min(1),
39422
- storagePath: z.string().min(1)
39423
- }), z.object({
39424
- tag: z.literal("external-src"),
39425
- assetId: z.string().optional(),
39426
- src: z.string().url()
39427
- })]);
39428
- const mediaBaseSchema = z.object({
39429
- purpose: z.string().optional(),
39430
- placeholder: z.boolean().default(true).optional(),
39431
- assetId: z.string().optional(),
39432
- identifier: z.string().optional(),
39433
- src: z.string().optional(),
39434
- alt: z.string().optional(),
39435
- filename: z.string().optional(),
39436
- mimeType: z.string().optional(),
39437
- width: z.number().optional(),
39438
- height: z.number().optional(),
39439
- storageBucket: z.string().optional(),
39440
- storagePath: z.string().optional(),
39441
- poster: mediaPosterSchema.optional(),
39442
- transform: transformSchema.optional()
39443
- });
39444
- const imageMediaSchema = mediaBaseSchema.extend({ type: z.literal("image") });
39445
- const videoMediaSchema = mediaBaseSchema.extend({ type: z.literal("video") });
39446
- const audioMediaSchema = mediaBaseSchema.extend({ type: z.literal("audio") });
39447
- const documentMediaSchema = mediaBaseSchema.extend({ type: z.literal("document") });
39448
- const spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z.literal("spreadsheet") });
39449
- const archiveMediaSchema = mediaBaseSchema.extend({ type: z.literal("archive") });
39450
- const mediaSchema = z.discriminatedUnion("type", [
39451
- imageMediaSchema,
39452
- videoMediaSchema,
39453
- audioMediaSchema,
39454
- documentMediaSchema,
39455
- spreadsheetMediaSchema,
39456
- archiveMediaSchema
39457
- ]);
39458
39453
  //#endregion
39459
39454
  //#region ../blocks/src/system/blocks/shared/bookingPaymentTerms.ts
39460
39455
  const bookingDepositRefundPolicySchema = z$1.enum(["refundable", "non_refundable"]);
@@ -39894,7 +39889,7 @@ const publicEventSchema = z$1.object({
39894
39889
  presentation: z$1.object({
39895
39890
  cardTitleOverride: z$1.string().nullable().optional(),
39896
39891
  summary: z$1.string().nullable().optional(),
39897
- image: mediaSchema.nullable().optional()
39892
+ image: mediaSchema$1.nullable().optional()
39898
39893
  }).optional(),
39899
39894
  slug: z$1.string(),
39900
39895
  path: z$1.string().nullable(),
@@ -40207,7 +40202,7 @@ const publicMembershipProductCollectionSchema = z$1.object({ memberships: z$1.ar
40207
40202
  * Kept in a shared module so the block definition and runtime contracts can
40208
40203
  * depend on the same schema without creating an initialization cycle.
40209
40204
  */
40210
- const occurrenceContextSchema$1 = z$1.object({
40205
+ const occurrenceContextSchema = z$1.object({
40211
40206
  id: z$1.string(),
40212
40207
  seriesId: z$1.string(),
40213
40208
  startsAt: z$1.string(),
@@ -40520,7 +40515,7 @@ function isEventCalendarListLayout(value) {
40520
40515
  //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
40521
40516
  const previewStageSchema = z$1.enum(["preview", "published"]);
40522
40517
  const registrationButtonVariantSchema = blockButtonRoleSchema;
40523
- const eventButtonVariantSchema = persistedBlockButtonRoleSchema;
40518
+ const eventButtonVariantSchema = blockButtonRoleSchema;
40524
40519
  const eventLayoutSchema = z$1.enum(eventCalendarListLayoutValues);
40525
40520
  const eventCalendarDisplayModeSchema = z$1.enum(eventCalendarDisplayModeValues);
40526
40521
  const eventCalendarDefaultViewSchema = z$1.enum(eventCalendarDefaultViewValues);
@@ -40607,28 +40602,37 @@ const EVENT_REGISTRATION_SHELL_STEP_LABELS = [
40607
40602
  "Payment"
40608
40603
  ];
40609
40604
  const eventRegistrationPublicEventSchema = z$1.preprocess(normalizeEventRegistrationEventInput, publicEventSchema);
40610
- const eventRegistrationSourceSchema = z$1.object({
40611
- siteId: z$1.string().optional(),
40612
- apiBaseUrl: z$1.string().optional(),
40613
- portalToken: z$1.string().nullable().optional(),
40614
- previewToken: z$1.string().nullable().optional(),
40615
- occurrenceContext: occurrenceContextSchema$1.optional(),
40605
+ const eventRegistrationHydrationSchemaShape = {
40606
+ occurrenceContext: occurrenceContextSchema.optional(),
40616
40607
  subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
40617
40608
  events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
40618
- className: z$1.string().nullable().optional(),
40619
- buttonText: z$1.string().nullable().optional(),
40620
- maxTickets: z$1.string().nullable().optional(),
40609
+ wholeSeriesOfferings: publicCoursesArraySchema.nullable().optional(),
40610
+ wholeSeriesOffering: publicCourseSchema.nullable().optional(),
40611
+ maxTickets: z$1.string().optional(),
40621
40612
  showVenue: z$1.boolean().optional(),
40622
40613
  showCapacity: z$1.boolean().optional(),
40614
+ showSessions: z$1.boolean().optional(),
40615
+ showPrice: z$1.boolean().optional(),
40623
40616
  successMessage: z$1.string().optional(),
40624
40617
  waitlistMessage: z$1.string().optional(),
40618
+ membershipMessage: z$1.string().optional(),
40625
40619
  buttonVariant: registrationButtonVariantSchema.optional(),
40626
40620
  overlayEnabled: z$1.boolean().optional(),
40627
40621
  spamProtectionEnabled: z$1.boolean().optional(),
40628
- stage: previewStageSchema.optional(),
40629
40622
  supportEmail: z$1.string().optional(),
40630
40623
  sitePasses: publicPassProductCollectionSchema.nullable().optional(),
40631
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()
40632
40636
  });
40633
40637
  const eventRegistrationDisplaySchema = z$1.object({
40634
40638
  kind: z$1.literal("event-registration"),
@@ -40639,22 +40643,7 @@ const eventRegistrationDisplaySchema = z$1.object({
40639
40643
  stepLabels: z$1.array(z$1.enum(EVENT_REGISTRATION_SHELL_STEP_LABELS)).min(1),
40640
40644
  summaryButtonText: z$1.string()
40641
40645
  });
40642
- const eventRegistrationHydrationSchema = z$1.object({
40643
- occurrenceContext: occurrenceContextSchema$1.optional(),
40644
- subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
40645
- events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
40646
- maxTickets: z$1.string().optional(),
40647
- showVenue: z$1.boolean().optional(),
40648
- showCapacity: z$1.boolean().optional(),
40649
- successMessage: z$1.string().optional(),
40650
- waitlistMessage: z$1.string().optional(),
40651
- buttonVariant: registrationButtonVariantSchema.optional(),
40652
- overlayEnabled: z$1.boolean().optional(),
40653
- spamProtectionEnabled: z$1.boolean().optional(),
40654
- supportEmail: z$1.string().optional(),
40655
- sitePasses: publicPassProductCollectionSchema.nullable().optional(),
40656
- siteMemberships: publicMembershipProductCollectionSchema.nullable().optional()
40657
- });
40646
+ const eventRegistrationHydrationSchema = z$1.object(eventRegistrationHydrationSchemaShape);
40658
40647
  const eventRegistrationRenderSchema = z$1.object({
40659
40648
  display: eventRegistrationDisplaySchema,
40660
40649
  hydration: eventRegistrationHydrationSchema
@@ -40734,11 +40723,16 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
40734
40723
  occurrenceContext: source.occurrenceContext ?? null,
40735
40724
  subject: source.subject ?? null,
40736
40725
  events: source.events ?? null,
40726
+ wholeSeriesOfferings: source.wholeSeriesOfferings ?? null,
40727
+ wholeSeriesOffering: source.wholeSeriesOffering ?? null,
40737
40728
  maxTickets: source.maxTickets ?? void 0,
40738
40729
  showVenue: source.showVenue,
40739
40730
  showCapacity: source.showCapacity,
40731
+ showSessions: source.showSessions,
40732
+ showPrice: source.showPrice,
40740
40733
  successMessage: source.successMessage,
40741
40734
  waitlistMessage: source.waitlistMessage,
40735
+ membershipMessage: source.membershipMessage,
40742
40736
  buttonVariant: source.buttonVariant,
40743
40737
  overlayEnabled: source.overlayEnabled,
40744
40738
  spamProtectionEnabled: source.spamProtectionEnabled,
@@ -40773,6 +40767,159 @@ function buildEventRegistrationInteractiveIslandProps(props) {
40773
40767
  source: props
40774
40768
  });
40775
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
+ }
40776
40923
  const eventRegistrationBlockDefinition = {
40777
40924
  manifest: createBlockManifest({
40778
40925
  id: "block.event-registration",
@@ -40868,6 +41015,24 @@ const eventRegistrationBlockDefinition = {
40868
41015
  defaultValue: true,
40869
41016
  ui: { intent: "display" }
40870
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
+ },
40871
41036
  {
40872
41037
  id: "successMessage",
40873
41038
  type: "text",
@@ -40878,6 +41043,26 @@ const eventRegistrationBlockDefinition = {
40878
41043
  defaultValue: "Thank you for registering! Check your email for confirmation details.",
40879
41044
  maxLength: 500
40880
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
+ },
40881
41066
  {
40882
41067
  id: "buttonText",
40883
41068
  type: "text",
@@ -40909,8 +41094,11 @@ const eventRegistrationBlockDefinition = {
40909
41094
  } },
40910
41095
  showVenue: { $bind: { from: "content.showVenue" } },
40911
41096
  showCapacity: { $bind: { from: "content.showCapacity" } },
41097
+ showSessions: { $bind: { from: "content.showSessions" } },
41098
+ showPrice: { $bind: { from: "content.showPrice" } },
40912
41099
  successMessage: { $bind: { from: "content.successMessage" } },
40913
41100
  waitlistMessage: { $bind: { from: "content.waitlistMessage" } },
41101
+ membershipMessage: { $bind: { from: "content.membershipMessage" } },
40914
41102
  buttonText: { $bind: {
40915
41103
  from: "content.buttonText",
40916
41104
  fallback: "Complete Registration"
@@ -40924,6 +41112,7 @@ const eventRegistrationBlockDefinition = {
40924
41112
  fallback: false
40925
41113
  } },
40926
41114
  events: { $bind: { from: "data.events" } },
41115
+ wholeSeriesOffering: { $bind: { from: "data.wholeSeriesOffering.offering" } },
40927
41116
  sitePasses: { $bind: { from: "data.sitePasses" } },
40928
41117
  siteMemberships: { $bind: { from: "data.siteMemberships" } },
40929
41118
  stage: { $bind: {
@@ -40937,9 +41126,10 @@ const eventRegistrationBlockDefinition = {
40937
41126
  runtime: eventRegistrationBlockRuntime,
40938
41127
  dataSchemas: {
40939
41128
  events: publicEventsArraySchema.optional(),
41129
+ wholeSeriesOffering: z$1.object({ offering: publicCourseSchema }).optional(),
40940
41130
  sitePasses: publicPassProductCollectionSchema.optional(),
40941
41131
  siteMemberships: publicMembershipProductCollectionSchema.optional(),
40942
- occurrenceContext: occurrenceContextSchema$1.optional()
41132
+ occurrenceContext: occurrenceContextSchema.optional()
40943
41133
  },
40944
41134
  dataLoaders: {
40945
41135
  events: {
@@ -40952,11 +41142,23 @@ const eventRegistrationBlockDefinition = {
40952
41142
  fallback: "published"
40953
41143
  } },
40954
41144
  readProfile: "registration",
40955
- seriesId: { $bind: { from: "$root.occurrenceContext.seriesId" } },
41145
+ seriesId: { $bind: { from: "$root.subject.eventSeriesId" } },
40956
41146
  includeOccurrenceId: { $bind: { from: "$root.occurrenceContext.id" } }
40957
41147
  },
40958
41148
  mode: "server"
40959
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
+ },
40960
41162
  sitePasses: {
40961
41163
  endpoint: "listPublicPasses",
40962
41164
  params: { siteId: { $bind: { from: "$root.siteId" } } },
@@ -40970,159 +41172,6 @@ const eventRegistrationBlockDefinition = {
40970
41172
  }
40971
41173
  };
40972
41174
  //#endregion
40973
- //#region ../blocks/src/system/blocks/courses/shared/pricing.ts
40974
- function isSaleWindowOpen(option, now) {
40975
- if (!option.isActive) return false;
40976
- if (option.saleStartsAt && new Date(option.saleStartsAt) > now) return false;
40977
- if (option.saleEndsAt && new Date(option.saleEndsAt) < now) return false;
40978
- return true;
40979
- }
40980
- function toExactOrFreeDisplay(amount, currency) {
40981
- if (amount <= 0) return {
40982
- kind: "free",
40983
- currency
40984
- };
40985
- return {
40986
- kind: "exact",
40987
- amount,
40988
- currency
40989
- };
40990
- }
40991
- function getSelectableCoursePricingOptionsForNow(course, now) {
40992
- if (course.pricing.pricingStrategy !== "tiered") return [];
40993
- return [...course.pricing.options].filter((option) => isSaleWindowOpen(option, now)).sort((left, right) => {
40994
- if (left.sortOrder !== right.sortOrder) return left.sortOrder - right.sortOrder;
40995
- if (left.priceAmount !== right.priceAmount) return left.priceAmount - right.priceAmount;
40996
- return left.name.localeCompare(right.name);
40997
- });
40998
- }
40999
- function resolveCoursePricingState(course, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
41000
- const selectedSlidingAmount = typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null;
41001
- const effectiveNowInput = typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? selectedSlidingAmountOrNowInput : nowInput;
41002
- const currency = course.pricing.currency;
41003
- switch (course.pricing.pricingStrategy) {
41004
- case "free": return {
41005
- currency,
41006
- display: {
41007
- kind: "free",
41008
- currency
41009
- },
41010
- selectableOptions: [],
41011
- requiresSelection: false,
41012
- selectedOption: null,
41013
- slidingScale: null,
41014
- selectedSlidingAmount: null,
41015
- selectedPriceAmount: 0,
41016
- selectedRequiresPayment: false,
41017
- hasPaidSelection: false,
41018
- hasFreeSelection: true
41019
- };
41020
- case "single": {
41021
- const amount = course.pricing.singlePriceAmount ?? 0;
41022
- return {
41023
- currency,
41024
- display: toExactOrFreeDisplay(amount, currency),
41025
- selectableOptions: [],
41026
- requiresSelection: false,
41027
- selectedOption: null,
41028
- slidingScale: null,
41029
- selectedSlidingAmount: null,
41030
- selectedPriceAmount: amount,
41031
- selectedRequiresPayment: amount > 0,
41032
- hasPaidSelection: amount > 0,
41033
- hasFreeSelection: amount <= 0
41034
- };
41035
- }
41036
- case "tiered": {
41037
- const selectableOptions = getSelectableCoursePricingOptionsForNow(course, resolvePlanningDateInput(effectiveNowInput));
41038
- const selectedOption = (selectedPricingOptionId ? selectableOptions.find((option) => option.id === selectedPricingOptionId) : null) ?? (selectableOptions.length === 1 ? selectableOptions[0] ?? null : null);
41039
- const lowestAmount = selectableOptions.reduce((lowest, option) => {
41040
- if (lowest === null || option.priceAmount < lowest) return option.priceAmount;
41041
- return lowest;
41042
- }, null);
41043
- return {
41044
- currency,
41045
- display: lowestAmount === null ? {
41046
- kind: "unavailable",
41047
- currency
41048
- } : selectableOptions.length > 1 && lowestAmount > 0 ? {
41049
- kind: "from",
41050
- amount: lowestAmount,
41051
- currency
41052
- } : toExactOrFreeDisplay(lowestAmount, currency),
41053
- selectableOptions,
41054
- requiresSelection: selectableOptions.length > 1,
41055
- selectedOption,
41056
- slidingScale: null,
41057
- selectedSlidingAmount: null,
41058
- selectedPriceAmount: selectedOption?.priceAmount ?? null,
41059
- selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
41060
- hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
41061
- hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
41062
- };
41063
- }
41064
- case "sliding_scale": {
41065
- const minAmount = course.pricing.slidingMinAmount ?? null;
41066
- const maxAmount = course.pricing.slidingMaxAmount ?? null;
41067
- if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) return {
41068
- currency,
41069
- display: {
41070
- kind: "unavailable",
41071
- currency
41072
- },
41073
- selectableOptions: [],
41074
- requiresSelection: true,
41075
- selectedOption: null,
41076
- slidingScale: null,
41077
- selectedSlidingAmount: null,
41078
- selectedPriceAmount: null,
41079
- selectedRequiresPayment: false,
41080
- hasPaidSelection: false,
41081
- hasFreeSelection: false
41082
- };
41083
- const normalizedSelectedAmount = typeof selectedSlidingAmount === "number" && Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
41084
- return {
41085
- currency,
41086
- display: {
41087
- kind: "range",
41088
- minAmount,
41089
- maxAmount,
41090
- currency
41091
- },
41092
- selectableOptions: [],
41093
- requiresSelection: normalizedSelectedAmount === null,
41094
- selectedOption: null,
41095
- slidingScale: {
41096
- minAmount,
41097
- maxAmount,
41098
- suggestedAmount: course.pricing.slidingSuggestedAmount ?? null
41099
- },
41100
- selectedSlidingAmount: normalizedSelectedAmount,
41101
- selectedPriceAmount: normalizedSelectedAmount,
41102
- selectedRequiresPayment: (normalizedSelectedAmount ?? 0) > 0,
41103
- hasPaidSelection: maxAmount > 0,
41104
- hasFreeSelection: minAmount === 0
41105
- };
41106
- }
41107
- }
41108
- }
41109
- function formatCoursePriceDisplay(display, locale) {
41110
- return formatBookingPriceDisplay(display, {
41111
- decimals: "exact",
41112
- locale
41113
- });
41114
- }
41115
- function formatCoursePriceAmount(amount, currency, locale) {
41116
- return formatCoursePriceDisplay(amount > 0 ? {
41117
- kind: "exact",
41118
- amount,
41119
- currency
41120
- } : {
41121
- kind: "free",
41122
- currency
41123
- }, locale);
41124
- }
41125
- //#endregion
41126
41175
  //#region ../blocks/src/system/runtime/nodes/course-registration.interactive.ts
41127
41176
  const courseRegistrationSourceSchema = z$1.object({
41128
41177
  siteId: z$1.string().optional(),
@@ -41557,15 +41606,6 @@ const eventDetailsManifest = createBlockManifest({
41557
41606
  })], { gap: "lg" })
41558
41607
  })]
41559
41608
  });
41560
- const occurrenceContextSchema = z$1.object({
41561
- id: z$1.string(),
41562
- seriesId: z$1.string(),
41563
- startsAt: z$1.string(),
41564
- endsAt: z$1.string(),
41565
- timeZone: z$1.string(),
41566
- capacityOverride: z$1.number().nullable().optional(),
41567
- overrides: z$1.record(z$1.string(), z$1.unknown()).nullable().optional()
41568
- }).nullable();
41569
41609
  const eventAutoApplyDiscountPreviewBaseSchema = z$1.object({
41570
41610
  id: z$1.string(),
41571
41611
  publicLabel: z$1.string(),
@@ -41600,8 +41640,9 @@ const eventDetailsBlockDefinition = {
41600
41640
  from: "$root.previewStage",
41601
41641
  fallback: "published"
41602
41642
  } },
41603
- limit: "25",
41604
- seriesId: { $bind: { from: "$root.occurrenceContext.seriesId" } },
41643
+ limit: "100",
41644
+ readProfile: "details",
41645
+ seriesId: { $bind: { from: "$root.subject.eventSeriesId" } },
41605
41646
  includeOccurrenceId: { $bind: { from: "$root.occurrenceContext.id" } }
41606
41647
  },
41607
41648
  mode: "server"
@@ -50366,9 +50407,6 @@ function parseSignedNewsletterDestinationRef(value) {
50366
50407
  const trimmed = parseTrimmedString$1(value);
50367
50408
  return trimmed && SIGNED_DESTINATION_REF_PATTERN.test(trimmed) ? trimmed : null;
50368
50409
  }
50369
- function parseNewsletterSignupDestinationProvider(value) {
50370
- return value === "riverbank" || value === "mailchimp" ? value : null;
50371
- }
50372
50410
  function buildNewsletterSignupBlockRef(blockId) {
50373
50411
  const parsed = parseNewsletterSignupBlockId(blockId);
50374
50412
  return parsed ? {
@@ -50535,19 +50573,9 @@ const newsletterFieldSchema = z$1.object({
50535
50573
  });
50536
50574
  const newsletterSignupBlockIdSchema = z$1.string().trim().min(1).transform(parseRequiredNewsletterSignupBlockId);
50537
50575
  const signedNewsletterDestinationRefSchema = z$1.string().trim().min(1).transform(parseRequiredSignedNewsletterDestinationRef);
50538
- const newsletterPublicDestinationRefSchema = z$1.discriminatedUnion("tag", [z$1.object({
50539
- tag: z$1.literal("block_ref"),
50540
- blockId: newsletterSignupBlockIdSchema
50541
- }), z$1.object({
50542
- tag: z$1.literal("signed_destination_ref"),
50543
- token: signedNewsletterDestinationRefSchema
50544
- })]);
50545
- const newsletterSourceSchema = z$1.object({
50546
- blockId: z$1.string().nullable().optional(),
50576
+ const newsletterSourceCommonSchema = z$1.object({
50547
50577
  siteId: z$1.string().optional(),
50548
50578
  apiBaseUrl: z$1.string().optional(),
50549
- listId: z$1.string().nullable().optional(),
50550
- destinationProvider: newsletterDestinationProviderSchema.nullable().optional(),
50551
50579
  preset: newsletterPresetSchema.optional(),
50552
50580
  includePhone: z$1.boolean().optional(),
50553
50581
  buttonLabel: z$1.string().nullable().optional(),
@@ -50558,6 +50586,25 @@ const newsletterSourceSchema = z$1.object({
50558
50586
  spamProtectionEnabled: z$1.boolean().optional(),
50559
50587
  className: z$1.string().nullable().optional()
50560
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
+ ]);
50561
50608
  const newsletterDisplaySchema = z$1.object({
50562
50609
  kind: z$1.literal("newsletter-form"),
50563
50610
  className: z$1.string().nullable(),
@@ -50568,8 +50615,26 @@ const newsletterDisplaySchema = z$1.object({
50568
50615
  fields: z$1.array(newsletterFieldSchema)
50569
50616
  });
50570
50617
  const newsletterHydrationSchema = z$1.object({
50571
- destinationRef: newsletterPublicDestinationRefSchema.nullable().optional(),
50572
- 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
+ ]),
50573
50638
  preset: newsletterPresetSchema,
50574
50639
  includePhone: z$1.boolean(),
50575
50640
  tags: z$1.string().nullable().optional(),
@@ -50603,20 +50668,43 @@ const newsletterFormBlockRuntime = defineProgressiveBlockRuntime({
50603
50668
  render: createZodCodec(newsletterRenderSchema)
50604
50669
  },
50605
50670
  buildRender: (source) => {
50606
- const runtimeSource = deriveNewsletterSignupRuntimeSource(source);
50671
+ const runtimeSource = source.source === "block" ? deriveNewsletterSignupRuntimeSource(source) : null;
50607
50672
  return {
50608
50673
  display: buildNewsletterDisplay(source),
50609
50674
  hydration: {
50610
- destinationRef: buildNewsletterSignupBlockRef(source.blockId),
50611
- listId: runtimeSource.listId,
50675
+ target: projectNewsletterFormHydrationTarget(source),
50612
50676
  preset: source.preset ?? "emailOnly",
50613
50677
  includePhone: source.includePhone ?? false,
50614
- tags: runtimeSource.tags,
50678
+ tags: runtimeSource ? runtimeSource.tags : source.tags,
50615
50679
  spamProtectionEnabled: source.spamProtectionEnabled
50616
50680
  }
50617
50681
  };
50618
50682
  }
50619
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
+ }
50620
50708
  function buildNewsletterFormInteractiveIslandProps(props) {
50621
50709
  return buildInteractiveIslandProps({
50622
50710
  runtime: newsletterFormBlockRuntime,
@@ -50732,7 +50820,7 @@ const newsletterSignupBlockDefinition = {
50732
50820
  //#endregion
50733
50821
  //#region ../blocks/src/system/blocks/team-members.ts
50734
50822
  const ITEM_NAME = "member";
50735
- const teamMemberPhotoSchema = mediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
50823
+ const teamMemberPhotoSchema = mediaSchema$1.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
50736
50824
  const teamMemberDataSchema = z$1.object({
50737
50825
  _type: z$1.literal("teamMember"),
50738
50826
  id: z$1.string(),
@@ -52307,7 +52395,7 @@ function getBlockDefinition(name) {
52307
52395
  //#endregion
52308
52396
  //#region ../blocks/src/system/helpers/backgroundMedia.ts
52309
52397
  function resolveBackgroundMedia(input) {
52310
- const parsedMedia = mediaSchema.safeParse(input.image);
52398
+ const parsedMedia = mediaSchema$1.safeParse(input.image);
52311
52399
  if (!parsedMedia.success) return null;
52312
52400
  switch (parsedMedia.data.type) {
52313
52401
  case "image":
@@ -53602,6 +53690,9 @@ function renderTrailingAffordanceIcon(affordance) {
53602
53690
  className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
53603
53691
  });
53604
53692
  }
53693
+ function isMissingRequiredLink(linkRequired, resolvedHref) {
53694
+ return linkRequired && resolvedHref.length === 0;
53695
+ }
53605
53696
  const ButtonNode = ({ value, children, href, variantId = "primary", size = "md", disabled, type = "button", target, rel, linkRequired = false, trailingIcon, blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, className, ...rest }) => {
53606
53697
  const content = value ?? children;
53607
53698
  if (!content) {
@@ -53610,12 +53701,16 @@ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md",
53610
53701
  }
53611
53702
  const affordanceIcon = renderTrailingAffordanceIcon(resolveButtonAffordance({ trailingIcon }));
53612
53703
  const resolvedHref = typeof href === "string" ? href.trim() : "";
53613
- if (linkRequired && resolvedHref.length === 0) {
53704
+ if (isMissingRequiredLink(linkRequired, resolvedHref)) {
53614
53705
  if (process.env.NODE_ENV === "development") console.warn("[ButtonNode] Missing href for link-required button");
53615
53706
  return null;
53616
53707
  }
53617
53708
  const extraClassName = affordanceIcon ? [className, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ") : className;
53618
- const resolvedVariantId = parseThemeButtonVariantId(canonicalizePersistedBlockButtonRole(variantId));
53709
+ const resolvedVariantId = parseThemeButtonVariantId(variantId);
53710
+ if (variantId && !resolvedVariantId) {
53711
+ console.error("[ButtonNode] Invalid button variant", { variantId });
53712
+ return null;
53713
+ }
53619
53714
  const combinedClassName = resolvedVariantId ? themeButtonClassName({
53620
53715
  variant: resolvedVariantId,
53621
53716
  size,
@@ -53744,8 +53839,9 @@ function iconForMediaType(type) {
53744
53839
  });
53745
53840
  }
53746
53841
  }
53747
- function normalizeButtonVariant(value) {
53748
- return isBlockButtonRole(value) ? value : "primary";
53842
+ function parseButtonVariant(value) {
53843
+ if (value === null || value === void 0) return "primary";
53844
+ return isBlockButtonRole(value) ? value : null;
53749
53845
  }
53750
53846
  function FileDownloadNode({ value, title, description, buttonLabel, buttonVariant, className }) {
53751
53847
  if (!value || !isDownloadableMediaType(value.type)) return null;
@@ -53755,7 +53851,11 @@ function FileDownloadNode({ value, title, description, buttonLabel, buttonVarian
53755
53851
  const heading = title?.trim() || filename;
53756
53852
  const body = description?.trim();
53757
53853
  const label = buttonLabel?.trim() || "Download";
53758
- const variant = normalizeButtonVariant(buttonVariant);
53854
+ const variant = parseButtonVariant(buttonVariant);
53855
+ if (!variant) {
53856
+ console.error("[FileDownloadNode] Invalid button variant", { buttonVariant });
53857
+ return null;
53858
+ }
53759
53859
  return /* @__PURE__ */ jsx("div", {
53760
53860
  className,
53761
53861
  children: /* @__PURE__ */ jsxs("div", {
@@ -54930,6 +55030,33 @@ function uniqByOccurrenceId(events) {
54930
55030
  }
54931
55031
  return out;
54932
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
+ }
54933
55060
  function selectEventDetails(args) {
54934
55061
  const all = uniqByOccurrenceId(resolveEventRegistrationScopedEvents((args.events ?? []).filter(Boolean), {
54935
55062
  occurrenceContext: args.occurrenceContext,
@@ -54937,37 +55064,22 @@ function selectEventDetails(args) {
54937
55064
  }));
54938
55065
  const occurrenceContext = args.occurrenceContext ?? null;
54939
55066
  const otherLimit = parseLimit$1(args.otherDatesLimit, 5);
54940
- const selectedFromContext = (() => {
54941
- if (!occurrenceContext) return null;
54942
- const byId = all.find((e) => e.occurrenceId === occurrenceContext.id || e.id === occurrenceContext.id) ?? null;
54943
- if (byId) return byId;
54944
- const ctxDate = getBookingLocalDateKey(toScheduledBookingDateTime({
54945
- startsAt: occurrenceContext.startsAt,
54946
- timeZone: occurrenceContext.timeZone
54947
- }));
54948
- return all.find((e) => getBookingLocalDateKey(toScheduledBookingDateTime({
54949
- startsAt: e.startsAt,
54950
- timeZone: e.timeZone
54951
- })) === ctxDate) ?? null;
54952
- })();
54953
- const nextUpcoming = (() => {
54954
- const upcoming = all.filter((e) => isFutureOrNow(e.startsAt, args.nowIso));
54955
- upcoming.sort((a, b) => Date.parse(a.startsAt) - Date.parse(b.startsAt));
54956
- return upcoming[0] ?? null;
54957
- })();
54958
- const mode = selectedFromContext ? "selected" : "next";
54959
- 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";
54960
55072
  const timeZone = toBookingTimeZone(selected?.timeZone ?? all[0]?.timeZone ?? null);
54961
- const seriesId = occurrenceContext?.seriesId ?? selected?.seriesId ?? all[0]?.seriesId ?? null;
54962
- const selectedOccurrenceId = selected?.occurrenceId ?? null;
54963
55073
  return {
54964
55074
  mode,
54965
55075
  selected,
54966
- otherDates: seriesId ? all.filter((e) => e.seriesId === seriesId).filter((e) => isFutureOrNow(e.startsAt, args.nowIso)).filter((e) => {
54967
- const occId = e.occurrenceId || e.id;
54968
- if (selectedOccurrenceId && occId === selectedOccurrenceId) return false;
54969
- return true;
54970
- }).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
+ }),
54971
55083
  timeZone
54972
55084
  };
54973
55085
  }
@@ -55089,7 +55201,7 @@ function EventFacts({ selection, selected, venue, teamMembers, pricing }) {
55089
55201
  /* @__PURE__ */ jsxs("div", { children: [
55090
55202
  /* @__PURE__ */ jsx("div", {
55091
55203
  className: "rb-label rb-mb-2",
55092
- 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"
55093
55205
  }),
55094
55206
  /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("strong", { children: date }) }),
55095
55207
  /* @__PURE__ */ jsx("p", {
@@ -55127,18 +55239,27 @@ function EventFacts({ selection, selected, venue, teamMembers, pricing }) {
55127
55239
  }) : null] }, member.id))
55128
55240
  })]
55129
55241
  }) : null,
55130
- 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
55131
55250
  ]
55132
55251
  });
55133
55252
  }
55134
55253
  function OtherEventDates({ selection }) {
55135
- 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;
55136
55257
  return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
55137
55258
  className: "rb-label",
55138
- children: "Other dates"
55259
+ children: isWholeSeries ? "Session schedule" : "Other dates"
55139
55260
  }), /* @__PURE__ */ jsx("div", {
55140
55261
  className: "rb-mt-2 rb-tiles-grid",
55141
- children: selection.otherDates.map((event) => /* @__PURE__ */ jsx("a", {
55262
+ children: dates.map((event) => /* @__PURE__ */ jsx("a", {
55142
55263
  className: "rb-tile rb-tile--interactive",
55143
55264
  ...resolveEventLinkProps(event),
55144
55265
  children: /* @__PURE__ */ jsx(DateTimeTile, {
@@ -58337,13 +58458,13 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
58337
58458
  * Renders the newsletter signup form for SSR with hydration support.
58338
58459
  * Uses the islands architecture pattern to hydrate on the client.
58339
58460
  */
58340
- 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;
58341
58464
  const islandProps = buildNewsletterFormInteractiveIslandProps({
58342
- blockId,
58465
+ ...props,
58343
58466
  siteId,
58344
58467
  apiBaseUrl,
58345
- listId,
58346
- destinationProvider,
58347
58468
  preset,
58348
58469
  includePhone,
58349
58470
  buttonLabel,
@@ -60637,6 +60758,35 @@ function resolveColorTokenHex(theme, colorToken) {
60637
60758
  if (colorToken === "transparent") return null;
60638
60759
  return expandPalette(theme.palette)[colorToken] ?? null;
60639
60760
  }
60761
+ const NAV_DROPDOWN_CONTAINER_RAIL_CSS_RULES = [
60762
+ `min-width: 12rem;`,
60763
+ `width: max-content;`,
60764
+ `max-width: min(22rem, calc(100vw - 2rem));`,
60765
+ `transform: translateX(var(--nav-dropdown-shift-x, 0px));`
60766
+ ];
60767
+ //#endregion
60768
+ //#region ../theme-core/src/header/surfaceRules.ts
60769
+ /** Compile the at-rest surface independently of scroll treatment and paint geometry. */
60770
+ function buildHeaderSurfaceRules(header, tokens) {
60771
+ const base = [];
60772
+ const background = header.background;
60773
+ if (background.type === "color") base.push(`background-color: ${tokens.getColor(background.color || "surface")};`);
60774
+ else if (background.type === "gradient" && background.gradient) {
60775
+ const stops = background.gradient.stops.map((stop) => tokens.getColor(stop.color)).join(", ");
60776
+ base.push(`background-image: linear-gradient(${background.gradient.angle ?? 180}deg, ${stops});`);
60777
+ }
60778
+ const borderWidth = getComponentBorderWidthPx(header.border?.width ?? "none");
60779
+ if (!header.border || borderWidth === "0") return {
60780
+ base,
60781
+ border: []
60782
+ };
60783
+ const color = rgbColorValue(header.border.colorToken?.trim() || "border");
60784
+ const style = header.border.style === "dashed" ? "dashed" : "solid";
60785
+ return {
60786
+ base,
60787
+ border: header.border.position === "both" ? [`border-top: ${borderWidth} ${style} ${color};`, `border-bottom: ${borderWidth} ${style} ${color};`] : [`border-${header.border.position}: ${borderWidth} ${style} ${color};`]
60788
+ };
60789
+ }
60640
60790
  //#endregion
60641
60791
  //#region ../theme-core/src/navigation/presets.ts
60642
60792
  /**
@@ -60798,12 +60948,71 @@ function getNavLinkPreset(presetId) {
60798
60948
  return NAV_LINK_PRESETS[presetId];
60799
60949
  }
60800
60950
  Object.keys(NAV_LINK_PRESETS);
60801
- const NAV_DROPDOWN_CONTAINER_RAIL_CSS_RULES = [
60802
- `min-width: 12rem;`,
60803
- `width: max-content;`,
60804
- `max-width: min(22rem, calc(100vw - 2rem));`,
60805
- `transform: translateX(var(--nav-dropdown-shift-x, 0px));`
60806
- ];
60951
+ //#endregion
60952
+ //#region ../theme-core/src/header/legacyNavLinkStyle.ts
60953
+ function buildLegacyHeaderNavLinkStyle(header, contrastTreatment, navTextSize) {
60954
+ const navStyle = header.navStyle ?? "minimal";
60955
+ const basePreset = getNavLinkPreset(navStyle);
60956
+ if (!basePreset) return null;
60957
+ const style = {
60958
+ ...basePreset,
60959
+ fontWeight: header.navWeight ?? basePreset.fontWeight,
60960
+ colorToken: (header.navColor ?? header.textColor)?.trim() || basePreset.colorToken,
60961
+ ...contrastTreatment ? { contrastTreatment } : {},
60962
+ ...navTextSize ? { textSize: navTextSize } : {}
60963
+ };
60964
+ if (header.navWeight === "bold" && navStyle === "solid") style.textTransform = "uppercase";
60965
+ applyLegacyNavEffects(style, header);
60966
+ applyLegacyGlassTreatment(style, header, navStyle);
60967
+ return style;
60968
+ }
60969
+ function applyLegacyNavEffects(style, header) {
60970
+ if (!header.navEffects) return;
60971
+ const effects = style.effects = {
60972
+ ...style.effects,
60973
+ hover: [...style.effects?.hover ?? []],
60974
+ active: [...style.effects?.active ?? []]
60975
+ };
60976
+ if (header.navEffects.glow) effects.hover.push({
60977
+ effectId: "outer-glow",
60978
+ options: { spread: 5 }
60979
+ });
60980
+ if (header.navEffects.neumorphic) {
60981
+ effects.hover.push({
60982
+ effectId: "neumorphic-shadow",
60983
+ options: { mode: "pressed" }
60984
+ });
60985
+ effects.hover.push({
60986
+ effectId: "text-color-change",
60987
+ options: { hoverColorToken: "primary" }
60988
+ });
60989
+ }
60990
+ if (header.navEffects.underlineGradient) effects.hover.push({
60991
+ effectId: "border-bottom-grow",
60992
+ options: { origin: "center" }
60993
+ });
60994
+ }
60995
+ function applyLegacyGlassTreatment(style, header, navStyle) {
60996
+ if (header.navContainer?.type !== "glass" || navStyle !== "minimal") return;
60997
+ style.borderRadius = "full";
60998
+ style.effects = {
60999
+ ...style.effects,
61000
+ hover: glassStateEffects(10),
61001
+ active: glassStateEffects(18)
61002
+ };
61003
+ }
61004
+ function glassStateEffects(opacity) {
61005
+ return [{
61006
+ effectId: "background-on-hover-alpha",
61007
+ options: {
61008
+ colorToken: "neutral-50",
61009
+ opacity
61010
+ }
61011
+ }, {
61012
+ effectId: "text-color-change",
61013
+ options: { hoverColorToken: "neutral-50" }
61014
+ }];
61015
+ }
60807
61016
  //#endregion
60808
61017
  //#region ../theme-core/src/header/generateHeaderCss.ts
60809
61018
  const HEADER_BLUR = "blur(12px)";
@@ -60833,8 +61042,8 @@ function generateHeaderCss(options) {
60833
61042
  const cssChunks = [];
60834
61043
  const headerContrastTreatment = resolveHeaderContrastTreatment(header);
60835
61044
  const headerNavTextSize = resolveHeaderNavTextSize(header);
60836
- cssChunks.push(generateHeaderRootStyles(header, themeId, tokens, theme));
60837
- cssChunks.push(generateMobileOverlayBackdropFilterFix(themeId));
61045
+ cssChunks.push(generateHeaderRootStyles(header, themeId, tokens));
61046
+ cssChunks.push(generateMobileOverlayBackdropFilterFix(themeId, header.variant));
60838
61047
  cssChunks.push(generateLogoStyles({
60839
61048
  logo: header.logo,
60840
61049
  themeId,
@@ -60872,56 +61081,33 @@ function isClearSplitHeaderShape(header) {
60872
61081
  function isDetachedFloatingHeaderShape(header) {
60873
61082
  return header.variant === "floating" && !header.container;
60874
61083
  }
60875
- function generateMobileOverlayBackdropFilterFix(themeId) {
60876
- return `\n${`:where([data-theme-scope="${themeId}"]) .header-root:has([data-nav-mobile-overlay][aria-hidden="false"])::before`} {\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n}\n`;
60877
- }
60878
61084
  /**
60879
61085
  * Generate root header container styles
60880
61086
  */
60881
- function generateHeaderRootStyles(header, themeId, tokens, _theme) {
61087
+ function generateHeaderRootStyles(header, themeId, tokens) {
60882
61088
  const selector = `:where([data-theme-scope="${themeId}"]) .header-root`;
60883
- const backgroundSelector = `:where([data-theme-scope="${themeId}"]) .header-root::before`;
60884
61089
  const rules = [];
60885
- const backgroundRules = [];
60886
61090
  const navContainerType = header.navContainer?.type ?? "none";
60887
61091
  const isContainedNav = navContainerType === "pill" || navContainerType === "glass";
60888
61092
  rules.push("position: relative;");
60889
61093
  rules.push("isolation: isolate;");
60890
- if (!isContainedNav) {
60891
- const bg = header.background;
60892
- if (bg.type === "color") {
60893
- const bgColor = tokens.getColor(bg.color || "surface");
60894
- backgroundRules.push(`background-color: ${bgColor};`);
60895
- } else if (bg.type === "gradient" && bg.gradient) {
60896
- const stops = bg.gradient.stops.map((s) => tokens.getColor(s.color)).join(", ");
60897
- const angle = bg.gradient.angle ?? 180;
60898
- backgroundRules.push(`background-image: linear-gradient(${angle}deg, ${stops});`);
60899
- }
60900
- backgroundRules.push(`backdrop-filter: ${HEADER_BLUR};`);
60901
- backgroundRules.push(`-webkit-backdrop-filter: ${HEADER_BLUR};`);
60902
- if (header.border) {
60903
- const borderWidth = getComponentBorderWidthPx(header.border.width);
60904
- if (borderWidth !== "0") {
60905
- const borderToken = header.border?.colorToken?.trim() || "border";
60906
- const borderColor = tokens.getColor(borderToken);
60907
- const borderStyle = header.border.style === "dashed" ? "dashed" : "solid";
60908
- if (header.border.position === "bottom") rules.push(`border-bottom: ${borderWidth} ${borderStyle} ${borderColor};`);
60909
- else if (header.border.position === "top") rules.push(`border-top: ${borderWidth} ${borderStyle} ${borderColor};`);
60910
- else if (header.border.position === "both") {
60911
- rules.push(`border-top: ${borderWidth} ${borderStyle} ${borderColor};`);
60912
- rules.push(`border-bottom: ${borderWidth} ${borderStyle} ${borderColor};`);
60913
- }
60914
- }
60915
- }
60916
- }
61094
+ const surfaceRules = isContainedNav ? {
61095
+ base: [],
61096
+ border: []
61097
+ } : buildHeaderSurfaceRules(header, tokens);
61098
+ const floatingSurfaceBorder = header.variant === "floating";
61099
+ if (!floatingSurfaceBorder) rules.push(...surfaceRules.border);
61100
+ const basePaintRules = floatingSurfaceBorder ? [...surfaceRules.base, ...surfaceRules.border] : surfaceRules.base;
61101
+ const scrolledPaintRules = floatingSurfaceBorder ? surfaceRules.border : [];
60917
61102
  if (header.positioning === "sticky" || header.positioning === "fixed") {
60918
61103
  const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "none");
60919
61104
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
60920
61105
  }
60921
61106
  const baseBlock = `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
60922
61107
  const overlayFix = `\n${`${selector}:has([data-nav-mobile-overlay][aria-hidden="false"])`} {\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n}\n`;
60923
- if (isContainedNav || backgroundRules.length === 0) return `${baseBlock}\n${overlayFix}`;
60924
- return `${baseBlock}\n${`\n${backgroundSelector} {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n border-radius: inherit;\n z-index: -1;\n ${backgroundRules.join("\n ")}\n}\n`}\n${overlayFix}${usesInsetShell(header) ? generateInsetShellStyles(header, themeId) : ""}`;
61108
+ const scrollTreatmentStyles = generateHeaderScrollTreatmentStyles(header.scrollTreatment, themeId, header.variant, scrolledPaintRules);
61109
+ if (isContainedNav || basePaintRules.length === 0) return `${baseBlock}\n${overlayFix}${scrollTreatmentStyles}`;
61110
+ return `${baseBlock}\n${renderHeaderPaintTargetRules(getHeaderPaintTargets(header.variant, themeId), basePaintRules)}\n${overlayFix}${usesInsetShell(header) ? generateInsetShellStyles(header, themeId) : ""}${scrollTreatmentStyles}`;
60925
61111
  }
60926
61112
  /**
60927
61113
  * Reshapes the full-bleed header paint layer into a contained brand capsule at
@@ -60966,10 +61152,10 @@ function generateLogoStyles(input) {
60966
61152
  else rules.push(`font-family: var(--font-heading);`);
60967
61153
  if (logo) {
60968
61154
  if (logo.letterSpacing && logo.letterSpacing !== "normal") rules.push(`letter-spacing: ${{
60969
- "normal": "0em",
60970
- "wide": "0.05em",
60971
- "wider": "0.1em",
60972
- "widest": "0.15em"
61155
+ normal: "0em",
61156
+ wide: "0.05em",
61157
+ wider: "0.1em",
61158
+ widest: "0.15em"
60973
61159
  }[logo.letterSpacing]};`);
60974
61160
  if (logo.gradient) {
60975
61161
  rules.push(`background: linear-gradient(to right, ${primaryColor}, ${accentColor});`);
@@ -61042,71 +61228,11 @@ function generateNavLinkStyles(header, themeId, tokens, theme, contrastTreatment
61042
61228
  } : header.navLinkStyle, navPreferences),
61043
61229
  className: "header-nav-link"
61044
61230
  });
61045
- const navStyle = header.navStyle ?? "minimal";
61046
- const basePreset = getNavLinkPreset(navStyle);
61047
- if (!basePreset) {
61048
- console.warn(`[generateHeaderCss] Nav link preset not found: ${navStyle}`);
61231
+ const mergedStyle = buildLegacyHeaderNavLinkStyle(header, contrastTreatment, navTextSize);
61232
+ if (!mergedStyle) {
61233
+ console.warn(`[generateHeaderCss] Nav link preset not found: ${header.navStyle}`);
61049
61234
  return "";
61050
61235
  }
61051
- const mergedStyle = {
61052
- ...basePreset,
61053
- fontWeight: header.navWeight ?? basePreset.fontWeight,
61054
- colorToken: (header.navColor ?? header.textColor)?.trim() || basePreset.colorToken,
61055
- ...contrastTreatment ? { contrastTreatment } : {},
61056
- ...navTextSize ? { textSize: navTextSize } : {}
61057
- };
61058
- if (header.navWeight === "bold" && navStyle === "solid") mergedStyle.textTransform = "uppercase";
61059
- if (header.navEffects) {
61060
- const effects = mergedStyle.effects = {
61061
- ...mergedStyle.effects,
61062
- hover: [...mergedStyle.effects?.hover || []],
61063
- active: [...mergedStyle.effects?.active || []]
61064
- };
61065
- if (header.navEffects.glow) effects.hover.push({
61066
- effectId: "outer-glow",
61067
- options: { spread: 5 }
61068
- });
61069
- if (header.navEffects.neumorphic) {
61070
- effects.hover.push({
61071
- effectId: "neumorphic-shadow",
61072
- options: { mode: "pressed" }
61073
- });
61074
- effects.hover.push({
61075
- effectId: "text-color-change",
61076
- options: { hoverColorToken: "primary" }
61077
- });
61078
- }
61079
- if (header.navEffects.underlineGradient) effects.hover.push({
61080
- effectId: "border-bottom-grow",
61081
- options: { origin: "center" }
61082
- });
61083
- }
61084
- if ((header.navContainer?.type ?? "none") === "glass" && navStyle === "minimal") {
61085
- mergedStyle.borderRadius = "full";
61086
- mergedStyle.effects = {
61087
- ...mergedStyle.effects,
61088
- hover: [{
61089
- effectId: "background-on-hover-alpha",
61090
- options: {
61091
- colorToken: "neutral-50",
61092
- opacity: 10
61093
- }
61094
- }, {
61095
- effectId: "text-color-change",
61096
- options: { hoverColorToken: "neutral-50" }
61097
- }],
61098
- active: [{
61099
- effectId: "background-on-hover-alpha",
61100
- options: {
61101
- colorToken: "neutral-50",
61102
- opacity: 18
61103
- }
61104
- }, {
61105
- effectId: "text-color-change",
61106
- options: { hoverColorToken: "neutral-50" }
61107
- }]
61108
- };
61109
- }
61110
61236
  return generateNavLinkCSS({
61111
61237
  themeId,
61112
61238
  tokens,
@@ -61134,10 +61260,10 @@ function generateDropdownContainerStyles(header, themeId, tokens) {
61134
61260
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
61135
61261
  const borderRadius = dropdownStyle?.borderRadius ?? "md";
61136
61262
  rules.push(`border-radius: ${{
61137
- "none": "0",
61138
- "sm": "0.25rem",
61139
- "md": "0.5rem",
61140
- "lg": "0.75rem"
61263
+ none: "0",
61264
+ sm: "0.25rem",
61265
+ md: "0.5rem",
61266
+ lg: "0.75rem"
61141
61267
  }[borderRadius]};`);
61142
61268
  rules.push(`padding: 0.5rem 0;`);
61143
61269
  return `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
@@ -61192,16 +61318,16 @@ function generateDropdownLinkStyles(header, themeId, tokens, theme) {
61192
61318
  const additionalRules = [];
61193
61319
  const letterSpacing = configuredDropdownStyle?.letterSpacing ?? "normal";
61194
61320
  if (letterSpacing !== "normal") additionalRules.push(`letter-spacing: ${{
61195
- "normal": "0em",
61196
- "wide": "0.05em",
61197
- "wider": "0.1em"
61321
+ normal: "0em",
61322
+ wide: "0.05em",
61323
+ wider: "0.1em"
61198
61324
  }[letterSpacing]};`);
61199
61325
  const textSize = configuredDropdownStyle?.textSize ?? "sm";
61200
61326
  additionalRules.push(`font-size: ${{
61201
- "xs": "0.75rem",
61202
- "sm": "0.875rem",
61203
- "base": "1rem",
61204
- "lg": "1.125rem"
61327
+ xs: "0.75rem",
61328
+ sm: "0.875rem",
61329
+ base: "1rem",
61330
+ lg: "1.125rem"
61205
61331
  }[textSize]};`);
61206
61332
  if (additionalRules.length > 0) return baseCSS + `\n${`:where([data-theme-scope="${themeId}"]) .nav-dropdown-link`} {\n ${additionalRules.join("\n ")}\n}\n`;
61207
61333
  return baseCSS;
@@ -61297,18 +61423,18 @@ function generateFloatingContainerStyles(header, themeId, tokens) {
61297
61423
  rules.push(`-webkit-backdrop-filter: ${FLOATING_BLUR};`);
61298
61424
  if (container.border) rules.push(`border: 1px solid rgb(255 255 255 / 0.2);`);
61299
61425
  rules.push(`border-radius: ${{
61300
- "none": "0",
61301
- "sm": "0.375rem",
61302
- "md": "0.5rem",
61303
- "lg": "0.75rem",
61304
- "xl": "1rem",
61426
+ none: "0",
61427
+ sm: "0.375rem",
61428
+ md: "0.5rem",
61429
+ lg: "0.75rem",
61430
+ xl: "1rem",
61305
61431
  "2xl": "1.5rem"
61306
61432
  }[container.rounded]};`);
61307
61433
  if (container.shadow) rules.push(`box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);`);
61308
61434
  rules.push(`padding: ${{
61309
- "sm": "1rem 1.5rem",
61310
- "md": "1.5rem 2rem",
61311
- "lg": "2rem 2.5rem"
61435
+ sm: "1rem 1.5rem",
61436
+ md: "1.5rem 2rem",
61437
+ lg: "2rem 2.5rem"
61312
61438
  }[container.padding]};`);
61313
61439
  return `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
61314
61440
  }
@@ -77822,6 +77948,7 @@ const SUPPORTED_LOADER_ENDPOINTS$1 = [
77822
77948
  "listPublicRecurringSchedule",
77823
77949
  "getPublicEventDetails",
77824
77950
  "listPublicWholeSeriesOfferings",
77951
+ "getPublicWholeSeriesOffering",
77825
77952
  "listPublicRouteCandidates",
77826
77953
  "listPublicTeamMembers",
77827
77954
  "listPublicProducts",
@@ -79471,6 +79598,7 @@ const loaderAdapters = {
79471
79598
  listPublicEvents,
79472
79599
  listPublicRecurringSchedule,
79473
79600
  getPublicEventDetails,
79601
+ getPublicWholeSeriesOffering,
79474
79602
  listPublicRouteCandidates,
79475
79603
  listPublicTeamMembers,
79476
79604
  listPublicProducts,
@@ -79565,6 +79693,13 @@ async function listPublicEvents({ client, params }) {
79565
79693
  async function listPublicRecurringSchedule(input) {
79566
79694
  return projectRecurringSchedule(await listPublicEvents(input));
79567
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
+ }
79568
79703
  async function getPublicEventDetails({ client, params }) {
79569
79704
  return await client.getPublicEventDetails({
79570
79705
  siteId: requireStringParam(params, "siteId", "getPublicEventDetails"),
@@ -82898,8 +83033,7 @@ function toBlocksBlockOverrides(overrides) {
82898
83033
  };
82899
83034
  return result;
82900
83035
  }
82901
- function toBlocksDataContext(dataContext) {
82902
- if (!dataContext) return void 0;
83036
+ function toBlocksPageRendererDataContext(dataContext) {
82903
83037
  return {
82904
83038
  ...dataContext,
82905
83039
  mediaAssets: toBlocksMediaAssets(dataContext.mediaAssets),
@@ -82912,7 +83046,7 @@ function PageRenderer(props) {
82912
83046
  const blocksProps = {
82913
83047
  ...props,
82914
83048
  theme: blocksTheme,
82915
- dataContext: toBlocksDataContext(props.dataContext),
83049
+ dataContext: props.dataContext ? toBlocksPageRendererDataContext(props.dataContext) : void 0,
82916
83050
  blockOverrides: toBlocksBlockOverrides(props.blockOverrides),
82917
83051
  sdkConfig: blocksSdkConfig,
82918
83052
  customBlocks: normalizeSdkCustomBlocks(props.customBlocks)
@@ -84172,7 +84306,7 @@ var CircuitOpenError = class extends Error {
84172
84306
  * 1. This constant
84173
84307
  * 2. The "version" field in package.json
84174
84308
  */
84175
- const SDK_VERSION = "0.126.0";
84309
+ const SDK_VERSION = "0.128.0";
84176
84310
  //#endregion
84177
84311
  //#region src/next/content-load-failure.ts
84178
84312
  const SdkContentLoadError = RiverbankContentLoadError;
@@ -85357,6 +85491,39 @@ function createContentReadOperations(input) {
85357
85491
  };
85358
85492
  }
85359
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
85360
85527
  //#region src/client/index.ts
85361
85528
  let prebuildModule = null;
85362
85529
  function tryRequire(modulePath) {
@@ -85862,25 +86029,15 @@ function createRiverbankClientWithDeps(deps, config) {
85862
86029
  async function resilientFetchData(cacheKey, fetcher, options) {
85863
86030
  return (await resilientFetch(cacheKey, fetcher, options)).data;
85864
86031
  }
85865
- /**
85866
- * Combine multiple AbortSignals into one that aborts when any input aborts
85867
- */
85868
- function combineAbortSignals(...signals) {
85869
- const controller = new AbortController();
85870
- for (const signal of signals) {
85871
- if (signal.aborted) {
85872
- controller.abort(signal.reason);
85873
- break;
85874
- }
85875
- signal.addEventListener("abort", () => controller.abort(signal.reason), { once: true });
85876
- }
85877
- return controller.signal;
85878
- }
85879
86032
  const contentReads = createContentReadOperations({
85880
86033
  apiClient,
85881
86034
  resilientFetch,
85882
86035
  prebuildLoader
85883
86036
  });
86037
+ const wholeSeriesReads = createWholeSeriesReadOperations({
86038
+ apiClient,
86039
+ resilientFetchData
86040
+ });
85884
86041
  async function getEntriesInternal(params) {
85885
86042
  const { siteId, contentType, limit, offset, order, preview = false, mode, entryIds, includeMeta, signal } = params;
85886
86043
  const entryIdsCacheKey = mode === "manual" && entryIds?.length ? entryIds.join(",") : "";
@@ -85914,6 +86071,7 @@ function createRiverbankClientWithDeps(deps, config) {
85914
86071
  });
85915
86072
  }
85916
86073
  return {
86074
+ ...wholeSeriesReads,
85917
86075
  async getSite(params) {
85918
86076
  return (await contentReads.getSiteWithResilience(params)).data;
85919
86077
  },