@riverbankcms/sdk 0.142.0 → 0.144.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 (187) hide show
  1. package/dist/{PreviewEditorSidebar-Dk6Dt11f.mjs → PreviewEditorSidebar-CQZNnFiM.mjs} +20 -26
  2. package/dist/{PreviewEditorUI-D6EQTsCA.mjs → PreviewEditorUI-DCNxnmI0.mjs} +3 -3
  3. package/dist/{PreviewQueryProvider-CC-EPkyQ.mjs → PreviewQueryProvider-BCYICImX.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-DH1n4ytY.mjs → SdkPreviewModeRuntime-BJolUbr1.mjs} +17 -8
  5. package/dist/{SiteChromeCustomizeContext-DunIzY0K.mjs → SiteChromeCustomizeContext-CKgEpoxi.mjs} +2406 -1988
  6. package/dist/_dts/api/src/billing.d.ts +1 -1
  7. package/dist/_dts/api/src/billingEndpointTypes.d.ts +8 -2
  8. package/dist/_dts/api/src/bookingConfig.d.ts +3 -1
  9. package/dist/_dts/api/src/endpoints.d.ts +7 -0
  10. package/dist/_dts/api/src/index.d.ts +1 -1
  11. package/dist/_dts/api/src/navigation/dashboardBookingsNav.d.ts +4 -4
  12. package/dist/_dts/api/src/publicEventEndpointDefinitions.d.ts +7 -0
  13. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +49 -41
  14. package/dist/_dts/api/src/sdkContracts.d.ts +1 -1
  15. package/dist/_dts/api/src/sdkSettingsContracts.d.ts +8 -0
  16. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +2 -8
  17. package/dist/_dts/api/src/siteSettings.d.ts +17 -7
  18. package/dist/_dts/billing/src/membership/index.d.ts +3 -0
  19. package/dist/_dts/block-form/src/backend/types.d.ts +14 -0
  20. package/dist/_dts/block-form/src/client/index.d.ts +1 -0
  21. package/dist/_dts/block-form/src/context/RepeaterHostActionsContext.d.ts +30 -0
  22. package/dist/_dts/block-form/src/context/index.d.ts +1 -0
  23. package/dist/_dts/block-form/src/index.d.ts +1 -0
  24. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterList.d.ts +4 -1
  25. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRow.d.ts +5 -2
  26. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRowActions.d.ts +11 -1
  27. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/index.d.ts +1 -0
  28. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useEmptyStateFocusAfterRemoval.d.ts +8 -0
  29. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/buildSummary.d.ts +15 -1
  30. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterRowActionsDomain.d.ts +5 -2
  31. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +34 -10
  32. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +3 -0
  33. package/dist/_dts/blocks/src/system/constants/events.d.ts +10 -0
  34. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +7 -1
  35. package/dist/_dts/blocks/src/system/runtime/api/context.d.ts +3 -3
  36. package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +18 -0
  37. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +3 -2
  38. package/dist/_dts/blocks/src/system/runtime/api/readAuthority.d.ts +11 -0
  39. package/dist/_dts/blocks/src/system/runtime/api/types/core.d.ts +9 -0
  40. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +95 -35
  41. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +7 -13
  42. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +3 -6
  43. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +9 -4
  44. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +0 -1
  45. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +1 -3
  46. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +7 -24
  47. package/dist/_dts/blocks/src/system/runtime/nodes/cart.server.d.ts +1 -0
  48. package/dist/_dts/blocks/src/system/runtime/nodes/checkout.server.d.ts +1 -0
  49. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationBookingLayer.d.ts +2 -1
  50. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +2 -1
  51. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizardActions.d.ts +2 -1
  52. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentStatusStep.d.ts +10 -0
  53. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +0 -2
  54. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +14 -1
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.override.d.ts +2 -1
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +2 -2
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationCompletion.d.ts +1 -4
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDerivations.d.ts +12 -0
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.d.ts +1 -1
  60. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/sessionStorage.d.ts +1 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.d.ts +4 -5
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +9 -11
  63. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +56 -2
  64. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +12 -6
  65. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.d.ts +23 -0
  66. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +1 -1
  67. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +8 -0
  68. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +4 -5
  69. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +7 -2
  70. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +7 -5
  71. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +5 -6
  72. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +3 -1
  73. package/dist/_dts/blocks/src/system/runtime/nodes/header-control.d.ts +10 -0
  74. package/dist/_dts/blocks/src/system/runtime/nodes/layout.d.ts +6 -21
  75. package/dist/_dts/blocks/src/system/runtime/nodes/product-detail.server.d.ts +1 -0
  76. package/dist/_dts/blocks/src/system/runtime/nodes/product-list.server.d.ts +1 -0
  77. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +13 -0
  78. package/dist/_dts/blocks/src/system/runtime/nodes/shop.server.d.ts +1 -0
  79. package/dist/_dts/blocks/src/system/runtime/shared/components/ThemedButton.d.ts +58 -0
  80. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -0
  81. package/dist/_dts/blocks/src/system/transforms/registry/chromeLogo.d.ts +23 -0
  82. package/dist/_dts/blocks/src/system/transforms/registry/index.d.ts +2 -1
  83. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +3 -1
  84. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +4 -1
  85. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -4
  86. package/dist/_dts/commerce/src/purchase/eventCheckoutRecoveryWindow.d.ts +8 -0
  87. package/dist/_dts/commerce/src/purchase/index.d.ts +2 -1
  88. package/dist/_dts/commerce/src/purchase/stateTransitions.d.ts +1 -13
  89. package/dist/_dts/core/src/event-catalogue.d.ts +27 -0
  90. package/dist/_dts/core/src/event-preset-vocabulary.d.ts +7 -0
  91. package/dist/_dts/core/src/index.d.ts +2 -0
  92. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +3126 -3077
  93. package/dist/_dts/db/src/schemas/forms.d.ts +286 -2
  94. package/dist/_dts/editor-blocks/src/block-editor/{BlockCardHeader.d.ts → BlockCardFrame.d.ts} +11 -3
  95. package/dist/_dts/logger/src/console.d.ts +3 -0
  96. package/dist/_dts/sdk/src/client/publicEventReadOperations.d.ts +1 -0
  97. package/dist/_dts/sdk/src/client/types.d.ts +3 -0
  98. package/dist/_dts/sdk/src/navigation/index.d.ts +27 -0
  99. package/dist/_dts/sdk/src/public-api/contracts.d.ts +15 -7
  100. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +1 -0
  101. package/dist/_dts/sdk/src/rendering/client.d.ts +1 -0
  102. package/dist/_dts/sdk/src/rendering/components/Block.shared.d.ts +1 -0
  103. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +7 -1
  104. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -0
  105. package/dist/_dts/sdk/src/rendering/islands/enhancers/routeIslandApiConfig.d.ts +3 -2
  106. package/dist/_dts/sdk/src/rendering/islands/enhancers/shopShared.d.ts +2 -0
  107. package/dist/_dts/sdk/src/rendering/overrides.d.ts +1 -0
  108. package/dist/_dts/sdk/src/version.d.ts +1 -1
  109. package/dist/_dts/theme-core/src/buttons/affordanceSuppression.d.ts +1 -1
  110. package/dist/_dts/theme-core/src/buttons/classNames.d.ts +3 -13
  111. package/dist/_dts/theme-core/src/customCss/index.d.ts +1 -1
  112. package/dist/_dts/theme-core/src/customCss/patch.d.ts +0 -5
  113. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  114. package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
  115. package/dist/_dts/theme-core/src/surfaces/logoVariant.d.ts +26 -0
  116. package/dist/_dts/theme-core/src/utils/colorStyles.d.ts +10 -0
  117. package/dist/_dts/ui/src/editor-item-card.d.ts +116 -0
  118. package/dist/_dts/ui/src/index.d.ts +1 -0
  119. package/dist/client/{BookingConsentAgreement-CnJeq3_r.mjs → BookingConsentAgreement-DoAILrkN.mjs} +4 -55
  120. package/dist/client/{DiscountCodeDisclosure-BINEO6J9.mjs → DiscountCodeDisclosure-X528hUTf.mjs} +27 -17
  121. package/dist/client/{EventCombined.client-srxNQ6sZ.mjs → EventCombined.client-DSBVwq5m.mjs} +54 -46
  122. package/dist/client/{EventListing.client-DbyVyGkX.mjs → EventListing.client-DmFAX7Vb.mjs} +3 -4
  123. package/dist/client/{LeafletStaticMap-B-wpijzL.mjs → LeafletStaticMap-BAqXdfhq.mjs} +1 -1
  124. package/dist/client/ThemedButton-BwNFVwi4.mjs +412 -0
  125. package/dist/client/{accordion-B-iUXU7n.mjs → accordion-DRhMdkbd.mjs} +1 -1
  126. package/dist/client/{bookingForm-BXYPke5q.mjs → bookingForm-iJ_nCsNF.mjs} +26 -32
  127. package/dist/client/bookings.mjs +657 -650
  128. package/dist/client/{carousel-Cr4aj63H.mjs → carousel-D8zuffZr.mjs} +2 -2
  129. package/dist/client/{carousel.client-DQTjCVQT.mjs → carousel.client-jahpU9Vz.mjs} +1 -1
  130. package/dist/client/{cart-DibP9WWa.mjs → cart-DeMGJViN.mjs} +3 -3
  131. package/dist/client/{checkout-CrSBVnL8.mjs → checkout-DXc06Km2.mjs} +3 -3
  132. package/dist/client/{checkoutUrls-FL6lRkrt.mjs → checkoutUrls-CW3-78uu.mjs} +1 -1
  133. package/dist/client/client.mjs +2714 -2448
  134. package/dist/client/{colorStyles-3013aRAY.mjs → colorStyles-CuJBiS-1.mjs} +16 -4
  135. package/dist/client/{context-Ces-AgdR.mjs → context-CDLCfDep.mjs} +35 -8
  136. package/dist/client/{dates-BXyNeNhB.mjs → dates-ClFx7Epy.mjs} +2 -2
  137. package/dist/client/{eventCalendar-HwpPeqrH.mjs → eventCalendar-BaGpnOGN.mjs} +39 -50
  138. package/dist/client/{eventCombined-BpFUkuEI.mjs → eventCombined-ywONOx2m.mjs} +5 -4
  139. package/dist/client/{eventDetails-DK_agiWy.mjs → eventDetails-B2LlOTYY.mjs} +4 -4
  140. package/dist/client/{eventListing-DhzHqP1c.mjs → eventListing-CMgxWpqP.mjs} +5 -4
  141. package/dist/client/{eventRegistration-BdQ_Dn2d.mjs → eventRegistration-BarLDNHR.mjs} +549 -592
  142. package/dist/client/{form-B1frcuzy.mjs → form-BjqKaBJ7.mjs} +9 -10
  143. package/dist/client/{headerSection-CT5z460s.mjs → headerSection-CP4XDwz1.mjs} +23 -30
  144. package/dist/client/hooks.mjs +269 -63
  145. package/dist/client/{locationMap-CIQXB9i2.mjs → locationMap-C5gW-d-w.mjs} +9 -10
  146. package/dist/client/{media-DHpfFwd3.mjs → media-BtJ37tzS.mjs} +1 -1
  147. package/dist/client/{newsletterForm-BYNYZSes.mjs → newsletterForm-afXlVSA0.mjs} +8 -9
  148. package/dist/client/{pricing-CbTlAsmt.mjs → pricing-Bl1CAl28.mjs} +1 -1
  149. package/dist/client/{productDetail-CR7Z3yjS.mjs → productDetail-CvQ3jWQe.mjs} +3 -3
  150. package/dist/client/{productList-DXj00vzR.mjs → productList-U874PGO7.mjs} +3 -3
  151. package/dist/client/{propsDecoder-DiLiBdek.mjs → propsDecoder-DPXtCZWP.mjs} +100 -29
  152. package/dist/client/rendering/client.mjs +2397 -2279
  153. package/dist/client/rendering/islands.mjs +19 -19
  154. package/dist/client/rendering.mjs +2742 -2452
  155. package/dist/client/{routeIslandApiConfig-UNsfPcYq.mjs → routeIslandApiConfig-NGYiUWXu.mjs} +8 -1
  156. package/dist/client/{scrollToBlock-CrcbBf0h.mjs → scrollToBlock-0-C3DVhK.mjs} +1 -1
  157. package/dist/client/{shop-DgqiB_1b.mjs → shop-BXjXhM9P.mjs} +45 -58
  158. package/dist/client/{shop-commerce-D_J781in.mjs → shop-commerce-BZ6UlWJ7.mjs} +42 -55
  159. package/dist/client/{shop-commerce-store-PGUbDwqe.mjs → shop-commerce-store-DlSBXb3D.mjs} +1 -1
  160. package/dist/client/{shopShared-C_Bb2zwG.mjs → shopShared-kkEOiLPA.mjs} +6 -5
  161. package/dist/client/{useEventFilters-CM17Xpr1.mjs → useEventFilters-zvnnE1ro.mjs} +66 -355
  162. package/dist/preview-next/before-render.mjs +11 -0
  163. package/dist/preview-next/client/runtime.mjs +4 -4
  164. package/dist/preview-next/editor-chrome.css +8 -0
  165. package/dist/preview-next/keepAlive.mjs +11 -0
  166. package/dist/preview-next/middleware.mjs +11 -0
  167. package/dist/{previewAuthStore-oVttoRDO.mjs → previewAuthStore-JA6-I_sL.mjs} +11 -0
  168. package/dist/{sdk-runtime-DhmuRhIX.mjs → sdk-runtime-DFJlQt3q.mjs} +2 -2
  169. package/dist/{separator-C3hlg9LH.mjs → separator-o8GHb1xh.mjs} +1 -1
  170. package/dist/server/components.mjs +840 -625
  171. package/dist/server/config-validation.mjs +269 -63
  172. package/dist/server/config.mjs +269 -63
  173. package/dist/server/data.mjs +269 -63
  174. package/dist/server/index.mjs +20 -5
  175. package/dist/server/navigation.mjs +28 -1
  176. package/dist/server/next.mjs +14129 -13937
  177. package/dist/server/page-converter.mjs +111 -59
  178. package/dist/server/prebuild.mjs +1 -1
  179. package/dist/server/rendering/server.mjs +844 -624
  180. package/dist/server/rendering.mjs +842 -626
  181. package/dist/server/routing.mjs +306 -69
  182. package/dist/server/server.mjs +278 -68
  183. package/dist/server/theme-bridge.mjs +40 -1
  184. package/dist/styles/index.css +6 -0
  185. package/package.json +1 -1
  186. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.d.ts +0 -14
  187. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.d.ts +0 -8
@@ -3764,9 +3764,7 @@ function navRow(opts) {
3764
3764
  rel: { $bind: { from: `${childItemName}.rel` } },
3765
3765
  "data-active": { $bind: { from: `${childItemName}.active` } }
3766
3766
  }, [text({ as: "span" }, bind(`${childItemName}.label`))], repeat(`${itemName}.children`, childItemName));
3767
- const dropdown = el("div", { className: "nav-dropdown rb-relative" }, [button({
3768
- type: "button",
3769
- variantId: "",
3767
+ const dropdown = el("div", { className: "nav-dropdown rb-relative" }, [el("headerControl", {
3770
3768
  className: prependClassName("nav-dropdown-trigger", linkClassName),
3771
3769
  "aria-haspopup": "menu",
3772
3770
  "aria-expanded": "false",
@@ -3834,9 +3832,7 @@ function navColumn(opts) {
3834
3832
  const dropdown = el("div", {
3835
3833
  className: "nav-mobile-dropdown",
3836
3834
  "data-nav-mobile-dropdown": "true"
3837
- }, [button({
3838
- type: "button",
3839
- variantId: "",
3835
+ }, [el("headerControl", {
3840
3836
  className: triggerClassName,
3841
3837
  "aria-expanded": "false",
3842
3838
  "aria-controls": childrenId,
@@ -5721,6 +5717,36 @@ function normalizedReference(value) {
5721
5717
  return normalized.length > 0 ? normalized : null;
5722
5718
  }
5723
5719
  //#endregion
5720
+ //#region ../theme-core/src/surfaces/logoVariant.ts
5721
+ /** Concrete hex behind a plain, opaque palette token, or null otherwise. */
5722
+ function opaquePaletteHexForToken(expandedPalette, token) {
5723
+ if (!token) return null;
5724
+ const parts = parseColorTokenParts(token);
5725
+ if (parts.kind !== "token" || parts.opacityPercent !== null) return null;
5726
+ return expandedPalette[parts.token] ?? null;
5727
+ }
5728
+ /**
5729
+ * Tone of the surface a foreground token was resolved for.
5730
+ *
5731
+ * A token with opacity has no known underlay to composite against, and a raw
5732
+ * or unrecognised token has no palette hex, so both are `unknown` rather than
5733
+ * a guess.
5734
+ */
5735
+ function surfaceToneFromForegroundToken(expandedPalette, foregroundToken) {
5736
+ const hex = opaquePaletteHexForToken(expandedPalette, foregroundToken);
5737
+ if (!hex) return "unknown";
5738
+ return featuresFromHex(hex).Y >= .5 ? "dark" : "light";
5739
+ }
5740
+ /**
5741
+ * The logo to draw on a surface of the given tone. A missing variant falls
5742
+ * back to the other one, and an unknown tone uses the light-backgrounds logo,
5743
+ * which is what every site rendered before variants existed.
5744
+ */
5745
+ function selectLogoVariant(tone, variants) {
5746
+ const { forLightBackgrounds, forDarkBackgrounds } = variants;
5747
+ return tone === "dark" ? forDarkBackgrounds ?? forLightBackgrounds : forLightBackgrounds ?? forDarkBackgrounds;
5748
+ }
5749
+ //#endregion
5724
5750
  //#region ../theme-core/src/utils/colorStyles.ts
5725
5751
  const COLOR_VAR_PREFIX = "--tb-";
5726
5752
  function parseToken(source) {
@@ -5787,16 +5813,28 @@ function backgroundColorStyle(token) {
5787
5813
  return { backgroundColor: rgbColorValue(token) };
5788
5814
  }
5789
5815
  /**
5816
+ * Converts a text color token to a CSS color value that follows the enclosing
5817
+ * surface. The semantic text tokens (`text`, `heading`, `mutedText`) resolve
5818
+ * to the surface foreground variables, so text adapts when a section's
5819
+ * background changes; any other token is a fixed theme color.
5820
+ *
5821
+ * @param token - Theme color token
5822
+ * @returns CSS color value
5823
+ */
5824
+ function textColorValue(token) {
5825
+ const parsed = parseToken(token);
5826
+ const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
5827
+ if (!surfaceRole) return rgbColorValue(token);
5828
+ return parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent);
5829
+ }
5830
+ /**
5790
5831
  * Creates a text color style object from a theme token.
5791
5832
  *
5792
5833
  * @param token - Theme color token
5793
5834
  * @returns CSSProperties with color
5794
5835
  */
5795
5836
  function textColorStyle(token) {
5796
- const parsed = parseToken(token);
5797
- const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
5798
- if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
5799
- return { color: rgbColorValue(token) };
5837
+ return { color: textColorValue(token) };
5800
5838
  }
5801
5839
  /**
5802
5840
  * Creates a border color style object from a theme token.
@@ -13350,7 +13388,7 @@ function parseThemeForPersistence(value) {
13350
13388
  * overriding the twelve styles that deliberately declare none. Whether a button
13351
13389
  * carries a trailing affordance is the style's decision; the only caller that
13352
13390
  * legitimately opts out is the authored-button renderer, which reaches it
13353
- * through `themeButtonClassNameWithTrailingIcon`.
13391
+ * through `themeButtonExtraClassesWithTrailingIcon`.
13354
13392
  */
13355
13393
  const AFFORDANCE_SUPPRESS_CLASS = "rb-affordance-off";
13356
13394
  //#endregion
@@ -13379,18 +13417,10 @@ function themeButtonSelector(variant, size) {
13379
13417
  if (!size) return baseSelector;
13380
13418
  return `${baseSelector}.${themeButtonSizeClassName(size)}`;
13381
13419
  }
13382
- function themeButtonClassName(spec) {
13383
- return [
13384
- ...themeButtonVariantClassNames(spec.variant),
13385
- themeButtonSizeClassName(spec.size),
13386
- spec.extraClassName
13387
- ].filter(Boolean).join(" ");
13388
- }
13389
13420
  /**
13390
- * Button classes for an authored button that renders its own trailing icon.
13421
+ * Extra classes for an authored button that renders its own trailing icon.
13391
13422
  *
13392
- * A separate function rather than a flag on `themeButtonClassName`, because
13393
- * there is exactly one caller and it should stay visible in a diff. The name
13423
+ * This intent-named function has exactly one caller. The name
13394
13424
  * states what the caller knows to be true of its own markup — that it renders a
13395
13425
  * trailing icon — rather than what the theme does about it. The consequence is
13396
13426
  * the theme's to decide and to change; a caller naming the consequence would be
@@ -13401,11 +13431,8 @@ function themeButtonClassName(spec) {
13401
13431
  * affordance is declared by the button style, and a block overriding that is the
13402
13432
  * defect this replaced.
13403
13433
  */
13404
- function themeButtonClassNameWithTrailingIcon(spec) {
13405
- return themeButtonClassName({
13406
- ...spec,
13407
- extraClassName: [spec.extraClassName, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ")
13408
- });
13434
+ function themeButtonExtraClassesWithTrailingIcon() {
13435
+ return AFFORDANCE_SUPPRESS_CLASS;
13409
13436
  }
13410
13437
  //#endregion
13411
13438
  //#region ../theme-core/src/interactive/generateBaseCSS.ts
@@ -23990,6 +24017,49 @@ const layoutTransforms = [
23990
24017
  footerLogoTextVisibleTransform
23991
24018
  ];
23992
24019
  //#endregion
24020
+ //#region ../blocks/src/system/transforms/registry/chromeLogo.ts
24021
+ const chromeLogoSchema = z.object({ surface: z.enum([
24022
+ "header-root",
24023
+ "header-mobile-panel",
24024
+ "footer-root"
24025
+ ]) });
24026
+ /** The brand foreground shares the logo's surface; navigation may own a separate capsule. */
24027
+ function chromeSurfaceTextToken(surface, theme, palette) {
24028
+ switch (surface) {
24029
+ case "header-root": {
24030
+ const header = theme.header;
24031
+ const foreground = resolveHeaderRootForeground(header, palette, resolveHeaderVisualStyles(header).isTransparent);
24032
+ return foreground.kind === "known" ? foreground.roles.text : resolveHeaderLeafTextColor(header);
24033
+ }
24034
+ case "header-mobile-panel": return theme.header?.dropdownStyle?.textColor ?? "text";
24035
+ case "footer-root": {
24036
+ const foreground = resolveFooterRootForeground(theme.footer, palette);
24037
+ return foreground.kind === "known" ? foreground.roles.text : void 0;
24038
+ }
24039
+ }
24040
+ }
24041
+ function readChromeTheme(viewModel) {
24042
+ return asPartialObject(asPartialObject(viewModel?.["$root"])?.theme) ?? {};
24043
+ }
24044
+ function resolveChromeSurfaceTone(surface, context) {
24045
+ return surfaceToneFromForegroundToken(context.theme.palette, chromeSurfaceTextToken(surface, readChromeTheme(context.viewModel), context.theme.palette));
24046
+ }
24047
+ const chromeLogoTransforms = [{
24048
+ id: "layout.chromeLogo",
24049
+ kind: "formatter",
24050
+ summary: "Select the light- or dark-background site logo for a header or footer surface",
24051
+ schema: chromeLogoSchema,
24052
+ run: (value, options, context) => {
24053
+ const content = asPartialObject(value);
24054
+ const variants = asPartialObject(content?.logoVariants);
24055
+ if (!variants) return content?.logo ?? null;
24056
+ return selectLogoVariant(resolveChromeSurfaceTone(options.surface, context), {
24057
+ forLightBackgrounds: variants.forLightBackgrounds ?? null,
24058
+ forDarkBackgrounds: variants.forDarkBackgrounds ?? null
24059
+ });
24060
+ }
24061
+ }];
24062
+ //#endregion
23993
24063
  //#region ../blocks/src/system/transforms/registry/ui.ts
23994
24064
  const joinClasses$2 = (parts) => parts.filter((part) => typeof part === "string" && part.trim().length > 0).join(" ").replace(/\s+/g, " ").trim();
23995
24065
  const eyebrowTreatmentClassMap = {
@@ -26343,6 +26413,33 @@ function normalizeEventCalendarDisplayMode$1(input) {
26343
26413
  if (isEventCalendarDisplayMode(input.variant)) return input.variant;
26344
26414
  return isEventCalendarDisplayMode(input.displayMode) ? input.displayMode : void 0;
26345
26415
  }
26416
+ /** One closed authority for the projections required by each rendered mode. */
26417
+ function resolveEventCalendarReadPlan(input) {
26418
+ const mode = normalizeEventCalendarDisplayMode$1(input) ?? "combined";
26419
+ switch (mode) {
26420
+ case "combined": return {
26421
+ mode,
26422
+ jobs: "both",
26423
+ readProfile: "listing-card"
26424
+ };
26425
+ case "list": return {
26426
+ mode,
26427
+ jobs: "list",
26428
+ readProfile: "listing-card"
26429
+ };
26430
+ case "calendar": return {
26431
+ mode,
26432
+ jobs: "calendar",
26433
+ readProfile: "listing-card"
26434
+ };
26435
+ case "timetable":
26436
+ case "week-board": return {
26437
+ mode,
26438
+ jobs: "calendar",
26439
+ readProfile: "timetable"
26440
+ };
26441
+ }
26442
+ }
26346
26443
  function isEventCalendarDefaultView(value) {
26347
26444
  return typeof value === "string" && eventCalendarDefaultViewValues.includes(value);
26348
26445
  }
@@ -27377,8 +27474,7 @@ function normalizeEventStaffMemberId(value) {
27377
27474
  //#endregion
27378
27475
  //#region ../blocks/src/system/blocks/events/shared/calendarWindow.ts
27379
27476
  function resolveCalendarReadProfile(content) {
27380
- const mode = normalizeEventCalendarDisplayMode$1(content);
27381
- return mode === "timetable" || mode === "week-board" ? "timetable" : "listing-card";
27477
+ return resolveEventCalendarReadPlan(content).readProfile;
27382
27478
  }
27383
27479
  /** Runtime picker sentinels and bound loader IDs must describe the same query. */
27384
27480
  function normalizeCalendarFilterId(value) {
@@ -27522,8 +27618,8 @@ const defaultTransforms = createTransformRegistry([
27522
27618
  summary: "Choose the read projection required by the calendar display mode",
27523
27619
  schema: z.object({ job: z.enum(["list", "calendar"]) }),
27524
27620
  run(value, options) {
27525
- const mode = normalizeEventCalendarDisplayMode$1(asPartialObject(value) ?? {}) ?? "combined";
27526
- return options.job === "calendar" ? mode !== "list" : mode === "list" || mode === "combined";
27621
+ const plan = resolveEventCalendarReadPlan(asPartialObject(value) ?? {});
27622
+ return plan.jobs === "both" || plan.jobs === options.job;
27527
27623
  }
27528
27624
  },
27529
27625
  {
@@ -27536,6 +27632,7 @@ const defaultTransforms = createTransformRegistry([
27536
27632
  },
27537
27633
  ...formattingTransforms,
27538
27634
  ...layoutTransforms,
27635
+ ...chromeLogoTransforms,
27539
27636
  ...uiTransforms,
27540
27637
  ...mediaTransforms,
27541
27638
  ...backgroundTransforms,
@@ -27691,12 +27788,12 @@ function Grid({ as: Comp = "div", cols, userColumns, gap = "md", className, styl
27691
27788
  }
27692
27789
  //#endregion
27693
27790
  //#region ../blocks/src/system/runtime/nodes/layout.tsx
27694
- const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Section, { ...props });
27695
- const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
27696
- const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
27697
- const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
27698
- const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
27699
- const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
27791
+ const SectionNode = (props) => /* @__PURE__ */ jsx(Section, { ...props });
27792
+ const StackNode = (props) => /* @__PURE__ */ jsx(Stack, { ...props });
27793
+ const InlineNode = (props) => /* @__PURE__ */ jsx(Inline, { ...props });
27794
+ const GridNode = (props) => /* @__PURE__ */ jsx(Grid, { ...props });
27795
+ const DivNode = (props) => /* @__PURE__ */ jsx("div", { ...props });
27796
+ const FigureNode = (props) => /* @__PURE__ */ jsx("figure", { ...props });
27700
27797
  //#endregion
27701
27798
  //#region ../path-utils/src/index.ts
27702
27799
  const PATH_SEPARATOR_REGEX$1 = /\./g;
@@ -27934,6 +28031,234 @@ function Text({ as: Comp = "span", children, className = "", path, maxLength: _m
27934
28031
  });
27935
28032
  }
27936
28033
  //#endregion
28034
+ //#region ../logger/src/sanitize.ts
28035
+ const DEFAULT_MAX_STRING_LENGTH = 2e3;
28036
+ const STRUCTURED_KEYS = /* @__PURE__ */ new Set([
28037
+ "source",
28038
+ "service",
28039
+ "function",
28040
+ "environment",
28041
+ "deployment",
28042
+ "region",
28043
+ "release",
28044
+ "requestId",
28045
+ "correlationId",
28046
+ "method",
28047
+ "route",
28048
+ "path",
28049
+ "search",
28050
+ "host",
28051
+ "url",
28052
+ "userId",
28053
+ "adminUserId",
28054
+ "orgId",
28055
+ "siteId",
28056
+ "siteDomainId",
28057
+ "domainOperationSubsystem",
28058
+ "domainOperation",
28059
+ "domainOperationStage",
28060
+ "domainOperationOutcome",
28061
+ "domainOperationDomain",
28062
+ "domainOperationProvider",
28063
+ "domainOperationError",
28064
+ "domainOperationMetadata",
28065
+ "durationMs",
28066
+ "duration",
28067
+ "status",
28068
+ "statusCode",
28069
+ "statusText",
28070
+ "errorDetails",
28071
+ "errorName",
28072
+ "errorMessage",
28073
+ "errorStack",
28074
+ "context"
28075
+ ]);
28076
+ function truncate(input, maxLength) {
28077
+ if (input.length <= maxLength) return input;
28078
+ return input.slice(0, maxLength) + "…";
28079
+ }
28080
+ function safeStringify(value, maxLength) {
28081
+ try {
28082
+ return truncate(JSON.stringify(value), maxLength);
28083
+ } catch {
28084
+ return truncate(String(value), maxLength);
28085
+ }
28086
+ }
28087
+ function toScalar(value, maxLength) {
28088
+ if (value == null) return null;
28089
+ if (typeof value === "string") return truncate(value, maxLength);
28090
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
28091
+ if (typeof value === "boolean") return value;
28092
+ if (value instanceof Date) return value.toISOString();
28093
+ if (value instanceof Error) return truncate(`${value.name}: ${value.message}`, maxLength);
28094
+ return safeStringify(value, maxLength);
28095
+ }
28096
+ function sanitizeV2(fields, maxStringLength) {
28097
+ const allowed = {};
28098
+ const extra = {};
28099
+ for (const [key, value] of Object.entries(fields)) {
28100
+ if (value === void 0) continue;
28101
+ if (STRUCTURED_KEYS.has(key)) {
28102
+ allowed[key] = toScalar(value, maxStringLength);
28103
+ continue;
28104
+ }
28105
+ extra[key] = value;
28106
+ }
28107
+ if (Object.keys(extra).length > 0) allowed.context = safeStringify(extra, maxStringLength);
28108
+ return allowed;
28109
+ }
28110
+ function sanitizeLogFields(fields, options) {
28111
+ if (fields === void 0 || Object.keys(fields).length === 0) return void 0;
28112
+ return sanitizeV2(fields, options?.maxStringLength ?? DEFAULT_MAX_STRING_LENGTH);
28113
+ }
28114
+ //#endregion
28115
+ //#region ../logger/src/console.ts
28116
+ function formatLog(level, message, fields) {
28117
+ const entry = {
28118
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
28119
+ level,
28120
+ message,
28121
+ ...sanitizeLogFields(fields)
28122
+ };
28123
+ return JSON.stringify(entry);
28124
+ }
28125
+ function createLogger(baseFields = {}) {
28126
+ return {
28127
+ debug: (msg, fields) => console.debug(formatLog("debug", msg, {
28128
+ ...baseFields,
28129
+ ...fields
28130
+ })),
28131
+ info: (msg, fields) => console.info(formatLog("info", msg, {
28132
+ ...baseFields,
28133
+ ...fields
28134
+ })),
28135
+ warn: (msg, fields) => console.warn(formatLog("warn", msg, {
28136
+ ...baseFields,
28137
+ ...fields
28138
+ })),
28139
+ error: (msg, fields) => console.error(formatLog("error", msg, {
28140
+ ...baseFields,
28141
+ ...fields
28142
+ })),
28143
+ withFields: (fields) => createLogger({
28144
+ ...baseFields,
28145
+ ...fields
28146
+ })
28147
+ };
28148
+ }
28149
+ const logger = createLogger();
28150
+ //#endregion
28151
+ //#region ../blocks/src/system/runtime/nodes/richText-coerce.ts
28152
+ function parseRichTextDoc(value) {
28153
+ const parsed = RichTextDocSchema.safeParse(value);
28154
+ if (parsed.success) return {
28155
+ kind: "valid",
28156
+ doc: parsed.data
28157
+ };
28158
+ return {
28159
+ kind: "invalid",
28160
+ issues: parsed.error.issues.map((issue) => ({
28161
+ path: issue.path.map((segment) => String(segment)),
28162
+ message: issue.message
28163
+ }))
28164
+ };
28165
+ }
28166
+ function coerceRichTextDoc(value, source) {
28167
+ const parsed = parseRichTextDoc(value);
28168
+ if (parsed.kind === "valid") return parsed.doc;
28169
+ if (value !== null && value !== void 0) logger.warn("blocks:rich-text:invalid-document", {
28170
+ source,
28171
+ issues: parsed.issues.slice(0, 3)
28172
+ });
28173
+ return null;
28174
+ }
28175
+ //#endregion
28176
+ //#region ../blocks/src/system/runtime/nodes/renderInlineText.tsx
28177
+ function renderInlineText(value) {
28178
+ return value.map((run, index) => renderRun(run, index));
28179
+ }
28180
+ function renderRun(run, key) {
28181
+ return (run.marks ?? []).reduceRight((child, mark, index) => renderMark(mark, `${String(key)}-${index}`, child), run.text);
28182
+ }
28183
+ function renderMark(mark, key, child) {
28184
+ switch (mark.kind) {
28185
+ case "strong": return /* @__PURE__ */ jsx("strong", { children: child }, key);
28186
+ case "emphasis": return /* @__PURE__ */ jsx("em", { children: child }, key);
28187
+ case "accent": return /* @__PURE__ */ jsx("span", {
28188
+ className: `rb-inline-text-accent rb-inline-text-accent-${mark.tone}`,
28189
+ children: child
28190
+ }, key);
28191
+ case "highlight": return /* @__PURE__ */ jsx("span", {
28192
+ className: `rb-inline-text-highlight rb-inline-text-highlight-${mark.tone}`,
28193
+ children: child
28194
+ }, key);
28195
+ }
28196
+ }
28197
+ //#endregion
28198
+ //#region ../blocks/src/system/runtime/nodes/spinner.tsx
28199
+ function resolveColorStyle(color) {
28200
+ switch (color) {
28201
+ case void 0: return;
28202
+ case "inherit": return { color: "inherit" };
28203
+ case "foreground": return { color: "rgb(var(--tb-foreground))" };
28204
+ case "text": return { color: "rgb(var(--tb-text))" };
28205
+ default: return;
28206
+ }
28207
+ }
28208
+ function SpinnerNode({ className, size = "md", color, strokeWidth = 3, srLabel, style, ...rest }) {
28209
+ const hasExplicitAriaLabel = typeof rest["aria-label"] === "string" && rest["aria-label"].trim().length > 0;
28210
+ const accessibilityProps = srLabel ? {
28211
+ role: "status",
28212
+ "aria-live": "polite"
28213
+ } : hasExplicitAriaLabel ? {} : { "aria-hidden": true };
28214
+ const trackStroke = color === "inherit" ? "currentColor" : "var(--rb-spinner-track-color)";
28215
+ const trackOpacity = color === "inherit" ? .25 : 1;
28216
+ return /* @__PURE__ */ jsxs("span", {
28217
+ ...accessibilityProps,
28218
+ className: clsx("rb-spinner", size ? `rb-spinner--${size}` : null, color === "inherit" ? "rb-spinner--inherit" : null, className),
28219
+ style: {
28220
+ ...resolveColorStyle(color),
28221
+ ...style ?? {}
28222
+ },
28223
+ ...rest,
28224
+ children: [/* @__PURE__ */ jsxs("svg", {
28225
+ viewBox: "0 0 24 24",
28226
+ fill: "none",
28227
+ "aria-hidden": "true",
28228
+ children: [/* @__PURE__ */ jsx("circle", {
28229
+ cx: "12",
28230
+ cy: "12",
28231
+ r: "10",
28232
+ stroke: trackStroke,
28233
+ strokeWidth,
28234
+ opacity: trackOpacity
28235
+ }), /* @__PURE__ */ jsx("path", {
28236
+ d: "M12 2a10 10 0 0 1 10 10",
28237
+ stroke: "currentColor",
28238
+ strokeWidth,
28239
+ strokeLinecap: "round"
28240
+ })]
28241
+ }), srLabel ? /* @__PURE__ */ jsx("span", {
28242
+ className: "rb-sr-only",
28243
+ children: srLabel
28244
+ }) : null]
28245
+ });
28246
+ }
28247
+ //#endregion
28248
+ //#region ../blocks/src/system/runtime/nodes/buttonAffordance.ts
28249
+ function normalize(value) {
28250
+ const trimmed = typeof value === "string" ? value.trim() : "";
28251
+ return trimmed.length > 0 ? trimmed : null;
28252
+ }
28253
+ /**
28254
+ * Resolve the node-authored trailing affordance, or `null` when no icon exists.
28255
+ */
28256
+ function resolveButtonAffordance(input) {
28257
+ const nodeIcon = normalize(input.trailingIcon);
28258
+ if (nodeIcon) return { iconId: nodeIcon };
28259
+ return null;
28260
+ }
28261
+ //#endregion
27937
28262
  //#region ../blocks/src/system/icons/svg.tsx
27938
28263
  function createIcon(displayName, children) {
27939
28264
  const Icon = ({ size = "1em", strokeWidth = 2, title, className, focusable = false, role, ...props }) => /* @__PURE__ */ jsxs("svg", {
@@ -29038,186 +29363,105 @@ function getIconComponent(name) {
29038
29363
  return getCtaIconComponent(name) ?? getSemanticIconComponent(name) ?? getSocialIconComponent(name);
29039
29364
  }
29040
29365
  //#endregion
29041
- //#region ../blocks/src/system/runtime/nodes/buttonAffordance.ts
29042
- function normalize(value) {
29043
- const trimmed = typeof value === "string" ? value.trim() : "";
29044
- return trimmed.length > 0 ? trimmed : null;
29045
- }
29046
- /**
29047
- * Resolve the node-authored trailing affordance, or `null` when no icon exists.
29048
- */
29049
- function resolveButtonAffordance(input) {
29050
- const nodeIcon = normalize(input.trailingIcon);
29051
- if (nodeIcon) return { iconId: nodeIcon };
29052
- return null;
29053
- }
29054
- //#endregion
29055
- //#region ../logger/src/sanitize.ts
29056
- const DEFAULT_MAX_STRING_LENGTH = 2e3;
29057
- const STRUCTURED_KEYS = /* @__PURE__ */ new Set([
29058
- "source",
29059
- "service",
29060
- "function",
29061
- "environment",
29062
- "deployment",
29063
- "region",
29064
- "release",
29065
- "requestId",
29066
- "correlationId",
29067
- "method",
29068
- "route",
29069
- "path",
29070
- "search",
29071
- "host",
29072
- "url",
29073
- "userId",
29074
- "adminUserId",
29075
- "orgId",
29076
- "siteId",
29077
- "siteDomainId",
29078
- "domainOperationSubsystem",
29079
- "domainOperation",
29080
- "domainOperationStage",
29081
- "domainOperationOutcome",
29082
- "domainOperationDomain",
29083
- "domainOperationProvider",
29084
- "domainOperationError",
29085
- "domainOperationMetadata",
29086
- "durationMs",
29087
- "duration",
29088
- "status",
29089
- "statusCode",
29090
- "statusText",
29091
- "errorDetails",
29092
- "errorName",
29093
- "errorMessage",
29094
- "errorStack",
29095
- "context"
29096
- ]);
29097
- function truncate(input, maxLength) {
29098
- if (input.length <= maxLength) return input;
29099
- return input.slice(0, maxLength) + "…";
29100
- }
29101
- function safeStringify(value, maxLength) {
29102
- try {
29103
- return truncate(JSON.stringify(value), maxLength);
29104
- } catch {
29105
- return truncate(String(value), maxLength);
29106
- }
29107
- }
29108
- function toScalar(value, maxLength) {
29109
- if (value == null) return null;
29110
- if (typeof value === "string") return truncate(value, maxLength);
29111
- if (typeof value === "number") return Number.isFinite(value) ? value : null;
29112
- if (typeof value === "boolean") return value;
29113
- if (value instanceof Date) return value.toISOString();
29114
- if (value instanceof Error) return truncate(`${value.name}: ${value.message}`, maxLength);
29115
- return safeStringify(value, maxLength);
29116
- }
29117
- function sanitizeV2(fields, maxStringLength) {
29118
- const allowed = {};
29119
- const extra = {};
29120
- for (const [key, value] of Object.entries(fields)) {
29121
- if (value === void 0) continue;
29122
- if (STRUCTURED_KEYS.has(key)) {
29123
- allowed[key] = toScalar(value, maxStringLength);
29124
- continue;
29125
- }
29126
- extra[key] = value;
29127
- }
29128
- if (Object.keys(extra).length > 0) allowed.context = safeStringify(extra, maxStringLength);
29129
- return allowed;
29130
- }
29131
- function sanitizeLogFields(fields, options) {
29132
- if (fields === void 0 || Object.keys(fields).length === 0) return void 0;
29133
- return sanitizeV2(fields, options?.maxStringLength ?? DEFAULT_MAX_STRING_LENGTH);
29366
+ //#region ../blocks/src/system/runtime/shared/components/ThemedButton.tsx
29367
+ function themedButtonClasses(variant, size, extraClassName) {
29368
+ return [
29369
+ ...themeButtonVariantClassNames(variant),
29370
+ themeButtonSizeClassName(size),
29371
+ extraClassName
29372
+ ].filter(Boolean).join(" ");
29134
29373
  }
29135
- //#endregion
29136
- //#region ../logger/src/console.ts
29137
- function formatLog(level, message, fields) {
29138
- const entry = {
29139
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
29140
- level,
29141
- message,
29142
- ...sanitizeLogFields(fields)
29143
- };
29144
- return JSON.stringify(entry);
29374
+ function ThemedButtonLabel(props) {
29375
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
29376
+ props.pending ? /* @__PURE__ */ jsx(SpinnerNode, {
29377
+ size: props.pending.spinnerSize ?? "sm",
29378
+ color: "inherit",
29379
+ className: props.pending.spinnerClassName ?? "rb-mr-2",
29380
+ srLabel: props.pending.srLabel
29381
+ }) : null,
29382
+ props.labelClassName ? /* @__PURE__ */ jsx("span", {
29383
+ className: props.labelClassName,
29384
+ children: props.pending?.label ?? props.label
29385
+ }) : props.pending?.label ?? props.label,
29386
+ props.screenReaderSuffix ? /* @__PURE__ */ jsx("span", {
29387
+ className: "rb-sr-only",
29388
+ children: props.screenReaderSuffix
29389
+ }) : null
29390
+ ] });
29391
+ return props.pending?.contentClassName ? /* @__PURE__ */ jsx("span", {
29392
+ className: props.pending.contentClassName,
29393
+ children: content
29394
+ }) : content;
29145
29395
  }
29146
- function createLogger(baseFields = {}) {
29147
- return {
29148
- debug: (msg, fields) => console.debug(formatLog("debug", msg, {
29149
- ...baseFields,
29150
- ...fields
29151
- })),
29152
- info: (msg, fields) => console.info(formatLog("info", msg, {
29153
- ...baseFields,
29154
- ...fields
29155
- })),
29156
- warn: (msg, fields) => console.warn(formatLog("warn", msg, {
29157
- ...baseFields,
29158
- ...fields
29159
- })),
29160
- error: (msg, fields) => console.error(formatLog("error", msg, {
29161
- ...baseFields,
29162
- ...fields
29163
- })),
29164
- withFields: (fields) => createLogger({
29165
- ...baseFields,
29166
- ...fields
29396
+ function ThemedButton({ variant, size, extraClassName, screenReaderSuffix, labelClassName, pending, label, ...buttonProps }) {
29397
+ return /* @__PURE__ */ jsx("button", {
29398
+ ...buttonProps,
29399
+ className: themedButtonClasses(variant, size, extraClassName),
29400
+ children: /* @__PURE__ */ jsx(ThemedButtonLabel, {
29401
+ label,
29402
+ pending,
29403
+ screenReaderSuffix,
29404
+ labelClassName
29167
29405
  })
29168
- };
29169
- }
29170
- const logger = createLogger();
29171
- //#endregion
29172
- //#region ../blocks/src/system/runtime/nodes/richText-coerce.ts
29173
- function parseRichTextDoc(value) {
29174
- const parsed = RichTextDocSchema.safeParse(value);
29175
- if (parsed.success) return {
29176
- kind: "valid",
29177
- doc: parsed.data
29178
- };
29179
- return {
29180
- kind: "invalid",
29181
- issues: parsed.error.issues.map((issue) => ({
29182
- path: issue.path.map((segment) => String(segment)),
29183
- message: issue.message
29184
- }))
29185
- };
29186
- }
29187
- function coerceRichTextDoc(value, source) {
29188
- const parsed = parseRichTextDoc(value);
29189
- if (parsed.kind === "valid") return parsed.doc;
29190
- if (value !== null && value !== void 0) logger.warn("blocks:rich-text:invalid-document", {
29191
- source,
29192
- issues: parsed.issues.slice(0, 3)
29193
29406
  });
29194
- return null;
29195
29407
  }
29196
- //#endregion
29197
- //#region ../blocks/src/system/runtime/nodes/renderInlineText.tsx
29198
- function renderInlineText(value) {
29199
- return value.map((run, index) => renderRun(run, index));
29408
+ function ThemedButtonLink({ variant, size, extraClassName, screenReaderSuffix, labelClassName, label, ...anchorProps }) {
29409
+ return /* @__PURE__ */ jsx("a", {
29410
+ ...anchorProps,
29411
+ className: themedButtonClasses(variant, size, extraClassName),
29412
+ children: /* @__PURE__ */ jsx(ThemedButtonLabel, {
29413
+ label,
29414
+ screenReaderSuffix,
29415
+ labelClassName
29416
+ })
29417
+ });
29200
29418
  }
29201
- function renderRun(run, key) {
29202
- return (run.marks ?? []).reduceRight((child, mark, index) => renderMark(mark, `${String(key)}-${index}`, child), run.text);
29419
+ /** Fixed semantic download affordance; callers cannot supply arbitrary icon children. */
29420
+ function ThemedDownloadLink({ variant, size, extraClassName, label, screenReaderSuffix, labelClassName, ...anchorProps }) {
29421
+ return /* @__PURE__ */ jsxs("a", {
29422
+ ...anchorProps,
29423
+ className: themedButtonClasses(variant, size, extraClassName),
29424
+ children: [/* @__PURE__ */ jsx(DownloadIcon, {
29425
+ "aria-hidden": "true",
29426
+ size: 24
29427
+ }), /* @__PURE__ */ jsx(ThemedButtonLabel, {
29428
+ label,
29429
+ screenReaderSuffix,
29430
+ labelClassName
29431
+ })]
29432
+ });
29203
29433
  }
29204
- function renderMark(mark, key, child) {
29205
- switch (mark.kind) {
29206
- case "strong": return /* @__PURE__ */ jsx("strong", { children: child }, key);
29207
- case "emphasis": return /* @__PURE__ */ jsx("em", { children: child }, key);
29208
- case "accent": return /* @__PURE__ */ jsx("span", {
29209
- className: `rb-inline-text-accent rb-inline-text-accent-${mark.tone}`,
29210
- children: child
29211
- }, key);
29212
- case "highlight": return /* @__PURE__ */ jsx("span", {
29213
- className: `rb-inline-text-highlight rb-inline-text-highlight-${mark.tone}`,
29214
- children: child
29215
- }, key);
29216
- }
29434
+ /** Boundary for authored button nodes and their registry-backed trailing icon. */
29435
+ function ThemedAuthoredButton({ label, href, variant, size, extraClassName, disabled, type = "button", target, rel, ariaLabel, dataTestId, trailingIcon, onClick }) {
29436
+ const affordance = resolveButtonAffordance({ trailingIcon });
29437
+ const Icon = affordance ? getIconComponent(affordance.iconId) : null;
29438
+ const className = variant ? themedButtonClasses(variant, size, Icon ? [extraClassName, themeButtonExtraClassesWithTrailingIcon()].filter(Boolean).join(" ") : extraClassName) : extraClassName ?? void 0;
29439
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [label, Icon ? /* @__PURE__ */ jsx(Icon, {
29440
+ "aria-hidden": true,
29441
+ className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
29442
+ }) : null] });
29443
+ return href ? /* @__PURE__ */ jsx("a", {
29444
+ href,
29445
+ target,
29446
+ rel,
29447
+ "aria-label": ariaLabel,
29448
+ "data-testid": dataTestId,
29449
+ className,
29450
+ onClick,
29451
+ children: content
29452
+ }) : /* @__PURE__ */ jsx("button", {
29453
+ type,
29454
+ disabled,
29455
+ "aria-label": ariaLabel,
29456
+ "data-testid": dataTestId,
29457
+ className,
29458
+ onClick,
29459
+ children: content
29460
+ });
29217
29461
  }
29218
29462
  //#endregion
29219
29463
  //#region ../blocks/src/system/runtime/nodes/basic.tsx
29220
- const TextNode = ({ value, children, blockId: _blockId, blockKind: _blockKind, blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, inlineTextFallbackPath, ...rest }) => {
29464
+ const TextNode = ({ value, children, blockContent, inlineTextFallbackPath, ...rest }) => {
29221
29465
  const inlineText = parseInlineTextFromUnknown(value);
29222
29466
  if (inlineText.ok && !isInlineTextEmpty(inlineText.value)) return /* @__PURE__ */ jsx(Text, {
29223
29467
  ...rest,
@@ -29238,34 +29482,21 @@ function readStringPath(source, path) {
29238
29482
  const value = getAtPath(source, path);
29239
29483
  return typeof value === "string" ? value : null;
29240
29484
  }
29241
- const RichTextNode = ({ value, blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...rest }) => {
29485
+ const RichTextNode = ({ value, blockKind, ...rest }) => {
29242
29486
  return /* @__PURE__ */ jsx(RichText, {
29243
- doc: coerceRichTextDoc(value, `block-runtime:${_blockKind ?? "unknown"}:${rest.path ?? "richText"}`) ?? void 0,
29487
+ doc: coerceRichTextDoc(value, `block-runtime:${blockKind ?? "unknown"}:${rest.path ?? "richText"}`) ?? void 0,
29244
29488
  ...rest
29245
29489
  });
29246
29490
  };
29247
- /**
29248
- * Render the resolved trailing affordance icon using the button's foreground.
29249
- */
29250
- function renderTrailingAffordanceIcon(affordance) {
29251
- if (!affordance) return null;
29252
- const Icon = getIconComponent(affordance.iconId);
29253
- if (!Icon) return null;
29254
- return /* @__PURE__ */ jsx(Icon, {
29255
- "aria-hidden": true,
29256
- className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
29257
- });
29258
- }
29259
29491
  function isMissingRequiredLink(linkRequired, resolvedHref) {
29260
29492
  return linkRequired && resolvedHref.length === 0;
29261
29493
  }
29262
- 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 }) => {
29494
+ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md", disabled, type = "button", target, rel, linkRequired = false, trailingIcon, onClick, className, ...rest }) => {
29263
29495
  const content = value ?? children;
29264
29496
  if (!content) {
29265
29497
  console.warn("[ButtonNode] No content to render - value and children are both empty");
29266
29498
  return null;
29267
29499
  }
29268
- const affordanceIcon = renderTrailingAffordanceIcon(resolveButtonAffordance({ trailingIcon }));
29269
29500
  const resolvedHref = typeof href === "string" ? href.trim() : "";
29270
29501
  if (isMissingRequiredLink(linkRequired, resolvedHref)) {
29271
29502
  if (process.env.NODE_ENV === "development") console.warn("[ButtonNode] Missing href for link-required button");
@@ -29276,28 +29507,23 @@ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md",
29276
29507
  console.error("[ButtonNode] Invalid button variant", { variantId });
29277
29508
  return null;
29278
29509
  }
29279
- const combinedClassName = resolvedVariantId ? (affordanceIcon ? themeButtonClassNameWithTrailingIcon : themeButtonClassName)({
29280
- variant: resolvedVariantId,
29281
- size,
29282
- extraClassName: className
29283
- }) : className;
29284
- if (resolvedHref) return /* @__PURE__ */ jsxs("a", {
29285
- href: resolvedHref,
29510
+ return /* @__PURE__ */ jsx(ThemedAuthoredButton, {
29511
+ label: content,
29512
+ href: resolvedHref || void 0,
29286
29513
  target,
29287
29514
  rel,
29288
- className: combinedClassName,
29289
- ...rest,
29290
- children: [content, affordanceIcon]
29291
- });
29292
- return /* @__PURE__ */ jsxs("button", {
29293
- type,
29515
+ variant: resolvedVariantId ?? null,
29516
+ size,
29294
29517
  disabled,
29295
- className: combinedClassName,
29296
- ...rest,
29297
- children: [content, affordanceIcon]
29518
+ type,
29519
+ trailingIcon,
29520
+ onClick,
29521
+ extraClassName: className,
29522
+ ariaLabel: rest["aria-label"],
29523
+ dataTestId: rest["data-testid"]
29298
29524
  });
29299
29525
  };
29300
- const LinkNode = ({ href, children, className, target, rel, linkRequired = false, blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...rest }) => {
29526
+ const LinkNode = ({ href, children, className, target, rel, linkRequired = false, ...rest }) => {
29301
29527
  if (!children) return null;
29302
29528
  const resolvedHref = typeof href === "string" ? href.trim() : "";
29303
29529
  if (resolvedHref.length === 0) {
@@ -29714,18 +29940,13 @@ function FileDownloadNode({ value, title, description, buttonLabel, buttonVarian
29714
29940
  })
29715
29941
  ]
29716
29942
  })]
29717
- }), /* @__PURE__ */ jsxs("a", {
29943
+ }), /* @__PURE__ */ jsx(ThemedDownloadLink, {
29718
29944
  href,
29719
29945
  download: filename,
29720
- className: themeButtonClassName({
29721
- variant,
29722
- size: "md",
29723
- extraClassName: "rb-inline-flex rb-shrink-0 rb-items-center rb-justify-center rb-gap-2"
29724
- }),
29725
- children: [/* @__PURE__ */ jsx(DownloadIcon, {
29726
- "aria-hidden": "true",
29727
- size: 24
29728
- }), label]
29946
+ variant,
29947
+ size: "md",
29948
+ extraClassName: "rb-inline-flex rb-shrink-0 rb-items-center rb-justify-center rb-gap-2",
29949
+ label
29729
29950
  })]
29730
29951
  })
29731
29952
  })
@@ -30313,53 +30534,19 @@ const HeaderSectionNode = ({ blockId, children, className, runtime, "data-previe
30313
30534
  };
30314
30535
  var header_section_server_default = markEditableSurfaceForwarding(HeaderSectionNode);
30315
30536
  //#endregion
30316
- //#region ../blocks/src/system/runtime/nodes/spinner.tsx
30317
- function resolveColorStyle(color) {
30318
- switch (color) {
30319
- case void 0: return;
30320
- case "inherit": return { color: "inherit" };
30321
- case "foreground": return { color: "rgb(var(--tb-foreground))" };
30322
- case "text": return { color: "rgb(var(--tb-text))" };
30323
- default: return;
30324
- }
30325
- }
30326
- function SpinnerNode({ className, size = "md", color, strokeWidth = 3, srLabel, style, ...rest }) {
30327
- const hasExplicitAriaLabel = typeof rest["aria-label"] === "string" && rest["aria-label"].trim().length > 0;
30328
- const accessibilityProps = srLabel ? {
30329
- role: "status",
30330
- "aria-live": "polite"
30331
- } : hasExplicitAriaLabel ? {} : { "aria-hidden": true };
30332
- const trackStroke = color === "inherit" ? "currentColor" : "var(--rb-spinner-track-color)";
30333
- const trackOpacity = color === "inherit" ? .25 : 1;
30334
- return /* @__PURE__ */ jsxs("span", {
30335
- ...accessibilityProps,
30336
- className: clsx("rb-spinner", size ? `rb-spinner--${size}` : null, color === "inherit" ? "rb-spinner--inherit" : null, className),
30337
- style: {
30338
- ...resolveColorStyle(color),
30339
- ...style ?? {}
30340
- },
30341
- ...rest,
30342
- children: [/* @__PURE__ */ jsxs("svg", {
30343
- viewBox: "0 0 24 24",
30344
- fill: "none",
30345
- "aria-hidden": "true",
30346
- children: [/* @__PURE__ */ jsx("circle", {
30347
- cx: "12",
30348
- cy: "12",
30349
- r: "10",
30350
- stroke: trackStroke,
30351
- strokeWidth,
30352
- opacity: trackOpacity
30353
- }), /* @__PURE__ */ jsx("path", {
30354
- d: "M12 2a10 10 0 0 1 10 10",
30355
- stroke: "currentColor",
30356
- strokeWidth,
30357
- strokeLinecap: "round"
30358
- })]
30359
- }), srLabel ? /* @__PURE__ */ jsx("span", {
30360
- className: "rb-sr-only",
30361
- children: srLabel
30362
- }) : null]
30537
+ //#region ../blocks/src/system/runtime/nodes/header-control.tsx
30538
+ /** System navigation controls retain their runtime hooks independently of authored CTAs. */
30539
+ function HeaderControlNode({ className, children, "aria-label": label, "aria-expanded": expanded, "aria-controls": controls, "aria-haspopup": hasPopup, "data-nav-mobile-toggle": mobileToggle, "data-nav-mobile-trigger": mobileTrigger }) {
30540
+ return /* @__PURE__ */ jsx("button", {
30541
+ type: "button",
30542
+ className,
30543
+ "aria-label": label,
30544
+ "aria-expanded": expanded,
30545
+ "aria-controls": controls,
30546
+ "aria-haspopup": hasPopup,
30547
+ "data-nav-mobile-toggle": mobileToggle,
30548
+ "data-nav-mobile-trigger": mobileTrigger,
30549
+ children
30363
30550
  });
30364
30551
  }
30365
30552
  //#endregion
@@ -30671,11 +30858,6 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePa
30671
30858
  children: view.message
30672
30859
  })
30673
30860
  });
30674
- const actionClassName = themeButtonClassName({
30675
- variant: "secondary",
30676
- size: "sm",
30677
- extraClassName: "appointment-services-row-action"
30678
- });
30679
30861
  return /* @__PURE__ */ jsx("div", {
30680
30862
  className: `${rootClassName} rb-flex rb-flex-col`,
30681
30863
  "data-appointment-services-state": "populated",
@@ -30708,13 +30890,13 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePa
30708
30890
  className: "appointment-services-row-price rb-text-lg",
30709
30891
  children: row.priceLabel
30710
30892
  }) : null,
30711
- /* @__PURE__ */ jsxs("a", {
30712
- className: actionClassName,
30893
+ /* @__PURE__ */ jsx(ThemedButtonLink, {
30894
+ variant: "secondary",
30895
+ size: "sm",
30896
+ extraClassName: "appointment-services-row-action",
30713
30897
  href: row.href,
30714
- children: ["Check times", /* @__PURE__ */ jsxs("span", {
30715
- className: "rb-sr-only",
30716
- children: [" for ", row.title]
30717
- })]
30898
+ label: "Check times",
30899
+ screenReaderSuffix: ` for ${row.title}`
30718
30900
  })
30719
30901
  ]
30720
30902
  }, row.id))
@@ -32716,16 +32898,14 @@ function LocationMapView({ addressText, location, zoom, heightPx, showAddressTex
32716
32898
  style: textColorStyle("mutedText"),
32717
32899
  children: addressText
32718
32900
  }) : null,
32719
- showDirections && directionsUrl ? /* @__PURE__ */ jsx("a", {
32901
+ showDirections && directionsUrl ? /* @__PURE__ */ jsx(ThemedButtonLink, {
32720
32902
  href: directionsUrl,
32721
32903
  target: "_blank",
32722
32904
  rel: "noreferrer",
32723
- className: themeButtonClassName({
32724
- variant: "ghost",
32725
- size: "sm",
32726
- extraClassName: "rb-w-fit"
32727
- }),
32728
- children: directionsLabel
32905
+ variant: "ghost",
32906
+ size: "sm",
32907
+ extraClassName: "rb-w-fit",
32908
+ label: directionsLabel
32729
32909
  }) : null
32730
32910
  ]
32731
32911
  });
@@ -32874,10 +33054,6 @@ const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", but
32874
33054
  const formattedTime = `${formatTime(event.startsAt, { timeZone })} - ${formatTime(event.endsAt, { timeZone })}`;
32875
33055
  const cta = resolveEventCta(event, buttonText);
32876
33056
  const cardClass = boxStyleClassNames({ role: cardRole }, { baseClass: "event-card" });
32877
- const buttonClass = themeButtonClassName({
32878
- variant: buttonVariant,
32879
- size: "md"
32880
- });
32881
33057
  const title = event.title;
32882
33058
  const summary = event.presentation?.summary ?? event.description;
32883
33059
  const image = event.presentation?.image ?? null;
@@ -32907,7 +33083,7 @@ const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", but
32907
33083
  image
32908
33084
  }), /* @__PURE__ */ jsx(EventCardContent, {
32909
33085
  allowMap,
32910
- buttonClass,
33086
+ buttonVariant,
32911
33087
  capacityText,
32912
33088
  categoryBadge,
32913
33089
  categoryId: category?.id,
@@ -33009,7 +33185,7 @@ function EventCardContent(props) {
33009
33185
  children: props.summary
33010
33186
  }),
33011
33187
  /* @__PURE__ */ jsx(EventCardFooter, {
33012
- buttonClass: props.buttonClass,
33188
+ buttonVariant: props.buttonVariant,
33013
33189
  capacityText: props.capacityText,
33014
33190
  cta: props.cta,
33015
33191
  priceText: props.priceText
@@ -33047,12 +33223,14 @@ function EventCardFooter(props) {
33047
33223
  className: "event-card-status rb-caption status-muted rb-text-center",
33048
33224
  children: props.cta.label
33049
33225
  }),
33050
- !props.cta.hidden && /* @__PURE__ */ jsx("a", {
33226
+ !props.cta.hidden && /* @__PURE__ */ jsx(ThemedButtonLink, {
33051
33227
  href: props.cta.href,
33052
33228
  target: props.cta.external ? "_blank" : void 0,
33053
33229
  rel: props.cta.external ? "noopener noreferrer" : void 0,
33054
- className: `${props.buttonClass} event-card-cta`,
33055
- children: props.cta.label
33230
+ variant: props.buttonVariant,
33231
+ size: "md",
33232
+ extraClassName: "event-card-cta",
33233
+ label: props.cta.label
33056
33234
  })
33057
33235
  ]
33058
33236
  });
@@ -33116,10 +33294,6 @@ const EventCompactRow = ({ event, buttonVariant = "primary", buttonText }) => {
33116
33294
  const price = formatEventPrice(event);
33117
33295
  const teacherLine = formatEventTeacherLine(event);
33118
33296
  const cta = resolveEventCta(event, buttonText);
33119
- const buttonClass = themeButtonClassName({
33120
- variant: buttonVariant,
33121
- size: "sm"
33122
- });
33123
33297
  return /* @__PURE__ */ jsxs("article", {
33124
33298
  className: "event-compact-row",
33125
33299
  children: [/* @__PURE__ */ jsxs("time", {
@@ -33183,12 +33357,15 @@ const EventCompactRow = ({ event, buttonVariant = "primary", buttonText }) => {
33183
33357
  }), cta.hidden ? /* @__PURE__ */ jsx("span", {
33184
33358
  className: "event-compact-row-status",
33185
33359
  children: cta.label
33186
- }) : /* @__PURE__ */ jsx("a", {
33360
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
33187
33361
  href: cta.href,
33188
33362
  target: cta.external ? "_blank" : void 0,
33189
33363
  rel: cta.external ? "noopener noreferrer" : void 0,
33190
- className: `${buttonClass} event-compact-row-cta`,
33191
- children: /* @__PURE__ */ jsx("span", { children: cta.label })
33364
+ variant: buttonVariant,
33365
+ size: "sm",
33366
+ extraClassName: "event-compact-row-cta",
33367
+ labelClassName: "event-compact-row-cta-label",
33368
+ label: cta.label
33192
33369
  })]
33193
33370
  })]
33194
33371
  })]
@@ -33230,10 +33407,6 @@ function EventQuickDateCard(props) {
33230
33407
  kind: "event_occurrence",
33231
33408
  occurrenceId: event.occurrenceId
33232
33409
  });
33233
- const buttonClass = themeButtonClassName({
33234
- variant: props.buttonVariant,
33235
- size: "sm"
33236
- });
33237
33410
  const quickDateLabel = `${event.title}, ${date.label}`;
33238
33411
  return /* @__PURE__ */ jsxs("article", {
33239
33412
  className: "event-quick-date rb-flex rb-min-w-12rem rb-shrink-0 rb-flex-col rb-gap-3 rb-rounded-lg rb-border rb-bg-surface rb-p-4",
@@ -33265,13 +33438,15 @@ function EventQuickDateCard(props) {
33265
33438
  children: [/* @__PURE__ */ jsx("span", {
33266
33439
  className: "event-quick-date-price",
33267
33440
  children: formatEventPrice(event)
33268
- }), /* @__PURE__ */ jsx("a", {
33269
- className: `${buttonClass} event-quick-date-cta`,
33441
+ }), /* @__PURE__ */ jsx(ThemedButtonLink, {
33442
+ variant: props.buttonVariant,
33443
+ size: "sm",
33444
+ extraClassName: "event-quick-date-cta",
33270
33445
  href: ctaHref,
33271
33446
  target: cta.external ? "_blank" : void 0,
33272
33447
  rel: cta.external ? "noopener noreferrer" : void 0,
33273
33448
  "aria-label": `${cta.label} ${quickDateLabel}`,
33274
- children: cta.label
33449
+ label: cta.label
33275
33450
  })]
33276
33451
  })
33277
33452
  ]
@@ -33333,10 +33508,6 @@ const EventSpotlight = ({ events, layout = "grid", columns = "3", cardRole = "de
33333
33508
  });
33334
33509
  const containerClass = getContainerClass(layout, columns);
33335
33510
  const cardOrientation = getCardOrientation(layout);
33336
- const buttonClass = themeButtonClassName({
33337
- variant: buttonVariant,
33338
- size: "md"
33339
- });
33340
33511
  return /* @__PURE__ */ jsxs("div", {
33341
33512
  className: `event-spotlight-section ${className || ""}`,
33342
33513
  "data-block": "event-spotlight",
@@ -33354,15 +33525,22 @@ const EventSpotlight = ({ events, layout = "grid", columns = "3", cardRole = "de
33354
33525
  }, event.occurrenceId || event.id))
33355
33526
  }), ctaLabel && ctaUrl ? /* @__PURE__ */ jsx("div", {
33356
33527
  className: "rb-mt-8 rb-text-center",
33357
- children: /* @__PURE__ */ jsx("a", {
33528
+ children: /* @__PURE__ */ jsx(ThemedButtonLink, {
33358
33529
  href: ctaUrl,
33359
- className: buttonClass,
33360
- children: ctaLabel
33530
+ variant: buttonVariant,
33531
+ size: "md",
33532
+ label: ctaLabel
33361
33533
  })
33362
33534
  }) : null]
33363
33535
  });
33364
33536
  };
33365
33537
  //#endregion
33538
+ //#region ../blocks/src/system/runtime/api/readAuthority.ts
33539
+ const browserReadAuthoritySchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("published") }).strict(), z.object({
33540
+ kind: z.literal("preview"),
33541
+ token: z.string().min(1)
33542
+ }).strict()]);
33543
+ //#endregion
33366
33544
  //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
33367
33545
  const previewStageSchema = z.enum(["preview", "published"]);
33368
33546
  const registrationButtonVariantSchema = blockButtonRoleSchema;
@@ -34280,6 +34458,7 @@ const eventCollectionSourceSchemaShape = {
34280
34458
  events: z.array(publicEventSchema).nullable().optional(),
34281
34459
  siteId: z.string(),
34282
34460
  apiBaseUrl: z.string().optional(),
34461
+ readAuthority: browserReadAuthoritySchema.optional(),
34283
34462
  stage: previewStageSchema.optional(),
34284
34463
  listLayout: eventLayoutSchema.optional(),
34285
34464
  listColumns: columnOptionSchema.optional(),
@@ -34332,7 +34511,6 @@ const eventCollectionDisplaySchemaShape = {
34332
34511
  const eventCollectionHydrationSchema = z.object({
34333
34512
  siteId: z.string(),
34334
34513
  calendarWindow: calendarWindowPageSchema.optional(),
34335
- stage: previewStageSchema.optional(),
34336
34514
  prefetchedEvents: z.boolean(),
34337
34515
  eventSurface: eventSurfaceScopeSchema$1,
34338
34516
  filterEventPresets: z.string().nullable(),
@@ -34407,7 +34585,6 @@ function buildEventCollectionHydration(source, now = /* @__PURE__ */ new Date())
34407
34585
  return {
34408
34586
  calendarWindow: source.calendarWindow ?? void 0,
34409
34587
  siteId: source.siteId,
34410
- stage: source.stage,
34411
34588
  prefetchedEvents: source.events != null,
34412
34589
  eventSurface: selected ? "all" : normalizeEventSurfaceScope(source.eventSurface),
34413
34590
  filterEventPresets: selected ? null : normalizeEventSurfacePresetsCsv(source.filterEventPresets),
@@ -34454,6 +34631,7 @@ const eventCombinedRenderSchema = z.object({
34454
34631
  z.object({
34455
34632
  siteId: z.string(),
34456
34633
  apiBaseUrl: z.string().optional(),
34634
+ readAuthority: browserReadAuthoritySchema.optional(),
34457
34635
  stage: previewStageSchema.optional()
34458
34636
  });
34459
34637
  function buildEventCombinedDisplay(source) {
@@ -34484,6 +34662,7 @@ function buildEventCombinedInteractiveIslandProps(props) {
34484
34662
  meta: {
34485
34663
  siteId: props.siteId,
34486
34664
  apiBaseUrl: props.apiBaseUrl,
34665
+ readAuthority: props.readAuthority,
34487
34666
  stage: props.stage
34488
34667
  },
34489
34668
  source: props
@@ -34937,11 +35116,6 @@ function OfferingsCatalogue(props) {
34937
35116
  //#endregion
34938
35117
  //#region ../blocks/src/system/runtime/nodes/offerings-preview-content.tsx
34939
35118
  function OfferingsPreviewContent(props) {
34940
- const groupLinkClass = themeButtonClassName({
34941
- variant: props.buttonVariant,
34942
- size: "md",
34943
- extraClassName: "offerings-preview-card-link rb-inline-flex rb-items-center rb-gap-2"
34944
- });
34945
35119
  return /* @__PURE__ */ jsx("div", {
34946
35120
  className: "offerings-preview rb-flex rb-flex-col rb-gap-6",
34947
35121
  "data-block": "offerings-preview",
@@ -34981,10 +35155,12 @@ function OfferingsPreviewContent(props) {
34981
35155
  }),
34982
35156
  groupCta ? /* @__PURE__ */ jsx("footer", {
34983
35157
  className: "offerings-preview-card-footer rb-mt-auto rb-flex",
34984
- children: /* @__PURE__ */ jsx("a", {
34985
- className: groupLinkClass,
35158
+ children: /* @__PURE__ */ jsx(ThemedButtonLink, {
35159
+ variant: props.buttonVariant,
35160
+ size: "md",
35161
+ extraClassName: "offerings-preview-card-link rb-inline-flex rb-items-center rb-gap-2",
34986
35162
  href: groupCta.href,
34987
- children: /* @__PURE__ */ jsx("span", { children: groupCta.label })
35163
+ label: groupCta.label
34988
35164
  })
34989
35165
  }) : null
34990
35166
  ]
@@ -35307,10 +35483,6 @@ function WholeSeriesRunCompactRow({ group, path, now }) {
35307
35483
  const timeRange = `${formatTime(firstSession.startsAt, { timeZone })} - ${formatTime(firstSession.endsAt, { timeZone })}`;
35308
35484
  const price = formatEventPriceDisplay(group.representative.pricing);
35309
35485
  const statusLabel = resolveWholeSeriesBookingPhase(group.run, now).kind === "open" ? null : "Registration closed";
35310
- const ctaClass = themeButtonClassName({
35311
- variant: "primary",
35312
- size: "sm"
35313
- });
35314
35486
  return /* @__PURE__ */ jsxs("article", {
35315
35487
  className: "event-compact-row offerings-preview-whole-series-row",
35316
35488
  children: [
@@ -35369,10 +35541,13 @@ function WholeSeriesRunCompactRow({ group, path, now }) {
35369
35541
  }), statusLabel || !path ? /* @__PURE__ */ jsx("span", {
35370
35542
  className: "event-compact-row-status",
35371
35543
  children: statusLabel ?? "Details coming soon"
35372
- }) : /* @__PURE__ */ jsx("a", {
35544
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
35373
35545
  href: path,
35374
- className: `${ctaClass} event-compact-row-cta`,
35375
- children: /* @__PURE__ */ jsx("span", { children: "Book now" })
35546
+ variant: "primary",
35547
+ size: "sm",
35548
+ extraClassName: "event-compact-row-cta",
35549
+ labelClassName: "event-compact-row-cta-label",
35550
+ label: "Book now"
35376
35551
  })]
35377
35552
  })
35378
35553
  ]
@@ -35389,10 +35564,6 @@ function WholeSeriesRunFeatureCard({ group, now, path, buttonVariant, buttonText
35389
35564
  const formattedDate = formatEventCompactDateRail(firstSession.startsAt, { timeZone }).label;
35390
35565
  const timeRange = `${formatTime(firstSession.startsAt, { timeZone })} - ${formatTime(firstSession.endsAt, { timeZone })}`;
35391
35566
  const price = formatEventPriceDisplay(group.representative.pricing);
35392
- const ctaClass = themeButtonClassName({
35393
- variant: buttonVariant,
35394
- size: "md"
35395
- });
35396
35567
  const statusLabel = resolveWholeSeriesBookingPhase(group.run, now).kind === "open" ? null : "Registration closed";
35397
35568
  const description = group.representative.description;
35398
35569
  return /* @__PURE__ */ jsx("article", {
@@ -35425,10 +35596,12 @@ function WholeSeriesRunFeatureCard({ group, now, path, buttonVariant, buttonText
35425
35596
  }), statusLabel || !path ? /* @__PURE__ */ jsx("span", {
35426
35597
  className: "event-compact-row-status",
35427
35598
  children: statusLabel ?? "Details coming soon"
35428
- }) : /* @__PURE__ */ jsx("a", {
35599
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
35429
35600
  href: path,
35430
- className: `${ctaClass} event-card-cta`,
35431
- children: buttonText || "Book now"
35601
+ variant: buttonVariant,
35602
+ size: "md",
35603
+ extraClassName: "event-card-cta",
35604
+ label: buttonText || "Book now"
35432
35605
  })]
35433
35606
  })
35434
35607
  ]
@@ -35581,15 +35754,13 @@ function WeeklySlotAvailabilityView({ availability, loading = false, error, empt
35581
35754
  "."
35582
35755
  ]
35583
35756
  }),
35584
- resolvedCtaUrl ? /* @__PURE__ */ jsx("a", {
35585
- className: themeButtonClassName({
35586
- variant: "ghost",
35587
- size: "sm",
35588
- extraClassName: "weekly-slot-availability__cta"
35589
- }),
35757
+ resolvedCtaUrl ? /* @__PURE__ */ jsx(ThemedButtonLink, {
35758
+ variant: "ghost",
35759
+ size: "sm",
35760
+ extraClassName: "weekly-slot-availability__cta",
35590
35761
  href: buildSlotCtaUrl(resolvedCtaUrl, slot),
35591
35762
  "aria-label": buildSlotCtaLabel(resolvedCtaText, slot),
35592
- children: resolvedCtaText
35763
+ label: resolvedCtaText
35593
35764
  }) : null
35594
35765
  ]
35595
35766
  }, slot.id))
@@ -36308,6 +36479,7 @@ const shopSourceSchema = z.object({
36308
36479
  products: z.array(publicProductSchema).nullable().optional(),
36309
36480
  siteId: z.string().optional(),
36310
36481
  apiBaseUrl: z.string().optional(),
36482
+ readAuthority: browserReadAuthoritySchema.optional(),
36311
36483
  stage: previewStageSchema.optional()
36312
36484
  });
36313
36485
  const productVariantOptionDisplaySchema = z.object({
@@ -36475,6 +36647,7 @@ function resolveShowPricePerCredit(source) {
36475
36647
  z.object({
36476
36648
  siteId: z.string().optional(),
36477
36649
  apiBaseUrl: z.string().optional(),
36650
+ readAuthority: browserReadAuthoritySchema.optional(),
36478
36651
  stage: previewStageSchema.optional()
36479
36652
  });
36480
36653
  const shopBlockRuntime = defineProgressiveBlockRuntime({
@@ -36609,6 +36782,7 @@ function buildShopInteractiveIslandProps(props) {
36609
36782
  meta: {
36610
36783
  siteId: props.siteId,
36611
36784
  apiBaseUrl: props.apiBaseUrl,
36785
+ readAuthority: props.readAuthority,
36612
36786
  stage: props.stage
36613
36787
  },
36614
36788
  source: {
@@ -36624,6 +36798,7 @@ function buildProductListInteractiveIslandProps(props) {
36624
36798
  meta: {
36625
36799
  siteId: props.siteId,
36626
36800
  apiBaseUrl: props.apiBaseUrl,
36801
+ readAuthority: props.readAuthority,
36627
36802
  stage: props.stage
36628
36803
  },
36629
36804
  source: {
@@ -36639,6 +36814,7 @@ function buildProductDetailInteractiveIslandProps(props) {
36639
36814
  meta: {
36640
36815
  siteId: props.siteId,
36641
36816
  apiBaseUrl: props.apiBaseUrl,
36817
+ readAuthority: props.readAuthority,
36642
36818
  stage: props.stage
36643
36819
  },
36644
36820
  source: {
@@ -36654,6 +36830,7 @@ function buildCartInteractiveIslandProps(props) {
36654
36830
  meta: {
36655
36831
  siteId: props.siteId,
36656
36832
  apiBaseUrl: props.apiBaseUrl,
36833
+ readAuthority: props.readAuthority,
36657
36834
  stage: props.stage
36658
36835
  },
36659
36836
  source: {
@@ -36669,6 +36846,7 @@ function buildCheckoutInteractiveIslandProps(props) {
36669
36846
  meta: {
36670
36847
  siteId: props.siteId,
36671
36848
  apiBaseUrl: props.apiBaseUrl,
36849
+ readAuthority: props.readAuthority,
36672
36850
  stage: props.stage
36673
36851
  },
36674
36852
  source: {
@@ -36750,6 +36928,7 @@ const cartBlockDefinition = {
36750
36928
  baseClass: "",
36751
36929
  spacing: "spacious",
36752
36930
  children: sectionContainer([cart(withApiBindings({
36931
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
36753
36932
  mode: "cart",
36754
36933
  heading: { $bind: {
36755
36934
  from: "content.heading",
@@ -36833,6 +37012,7 @@ const checkoutBlockDefinition = {
36833
37012
  baseClass: "",
36834
37013
  spacing: "spacious",
36835
37014
  children: sectionContainer([checkout(withApiBindings({
37015
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
36836
37016
  mode: "checkout",
36837
37017
  heading: { $bind: {
36838
37018
  from: "content.heading",
@@ -37269,6 +37449,7 @@ const eventRegistrationSourceSchema = z.object({
37269
37449
  apiBaseUrl: z.string().optional(),
37270
37450
  portalToken: z.string().nullable().optional(),
37271
37451
  previewToken: z.string().nullable().optional(),
37452
+ readAuthority: browserReadAuthoritySchema.optional(),
37272
37453
  ...eventRegistrationHydrationSchemaShape,
37273
37454
  events: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
37274
37455
  wholeSeriesRunEvents: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
@@ -37306,6 +37487,7 @@ z.object({
37306
37487
  apiBaseUrl: z.string().optional(),
37307
37488
  portalToken: z.string().nullable().optional(),
37308
37489
  previewToken: z.string().nullable().optional(),
37490
+ readAuthority: browserReadAuthoritySchema.optional(),
37309
37491
  stage: previewStageSchema.optional()
37310
37492
  });
37311
37493
  function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents) {
@@ -37381,6 +37563,7 @@ function shellLabelForRegistrationStep(step, events) {
37381
37563
  case "redirecting":
37382
37564
  case "verifying-payment":
37383
37565
  case "verifying-timeout":
37566
+ case "payment-status":
37384
37567
  case "payment-failed": return "Details";
37385
37568
  }
37386
37569
  }
@@ -37448,6 +37631,7 @@ function buildEventRegistrationInteractiveIslandProps(props) {
37448
37631
  apiBaseUrl: props.apiBaseUrl,
37449
37632
  portalToken: props.portalToken,
37450
37633
  previewToken: props.previewToken,
37634
+ readAuthority: props.readAuthority,
37451
37635
  stage: props.stage
37452
37636
  },
37453
37637
  source: props
@@ -37577,6 +37761,7 @@ const eventRegistrationBlockDefinition = {
37577
37761
  text({ as: "h2" }, bind("content.heading"), when("content.heading")),
37578
37762
  richText({ className: "rb-prose rb-max-w-none" }, bind("content.description"), when("content.description")),
37579
37763
  eventRegistration(withApiBindings({
37764
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
37580
37765
  occurrenceContext: { $bind: { from: "$root.occurrenceContext" } },
37581
37766
  subject: { $bind: { from: "$root.subject" } },
37582
37767
  portalToken: { $bind: {
@@ -38022,6 +38207,7 @@ const eventCalendarRenderSchema = z.object({
38022
38207
  z.object({
38023
38208
  siteId: z.string(),
38024
38209
  apiBaseUrl: z.string().optional(),
38210
+ readAuthority: browserReadAuthoritySchema.optional(),
38025
38211
  stage: previewStageSchema.optional()
38026
38212
  });
38027
38213
  /**
@@ -38043,7 +38229,7 @@ function buildEventCalendarDisplay(source) {
38043
38229
  listColumns: source.listColumns ?? source.columns
38044
38230
  }),
38045
38231
  kind: "event-calendar",
38046
- displayMode: normalizeEventCalendarDisplayMode$1(source) ?? "combined",
38232
+ displayMode: resolveEventCalendarReadPlan(source).mode,
38047
38233
  className: source.className ?? null,
38048
38234
  events: (source.events ?? []).slice().sort((left, right) => new Date(left.startsAt).getTime() - new Date(right.startsAt).getTime()),
38049
38235
  boardTitle: normalizeOptionalText(source.boardTitle),
@@ -38063,13 +38249,16 @@ const eventCalendarBlockRuntime = defineProgressiveBlockRuntime({
38063
38249
  source: createZodCodec(eventCalendarSourceSchema),
38064
38250
  render: createZodCodec(eventCalendarRenderSchema)
38065
38251
  },
38066
- buildRender: (source) => ({
38067
- display: buildEventCalendarDisplay(source.calendarWindow && (source.variant ?? source.displayMode ?? "combined") !== "combined" && (source.variant ?? source.displayMode) !== "list" ? {
38068
- ...source,
38069
- events: source.calendarWindow.events
38070
- } : source),
38071
- hydration: buildEventCollectionHydration(source)
38072
- })
38252
+ buildRender: (source) => {
38253
+ const plan = resolveEventCalendarReadPlan(source);
38254
+ return {
38255
+ display: buildEventCalendarDisplay(source.calendarWindow && plan.jobs === "calendar" ? {
38256
+ ...source,
38257
+ events: source.calendarWindow.events
38258
+ } : source),
38259
+ hydration: buildEventCollectionHydration(source)
38260
+ };
38261
+ }
38073
38262
  });
38074
38263
  function buildEventCalendarInteractiveIslandProps(props) {
38075
38264
  return buildInteractiveIslandProps({
@@ -38078,6 +38267,7 @@ function buildEventCalendarInteractiveIslandProps(props) {
38078
38267
  meta: {
38079
38268
  siteId: props.siteId,
38080
38269
  apiBaseUrl: props.apiBaseUrl,
38270
+ readAuthority: props.readAuthority,
38081
38271
  stage: props.stage
38082
38272
  },
38083
38273
  source: props
@@ -38231,6 +38421,7 @@ const eventCalendarLayout = [styledSection({
38231
38421
  rootType: "stack",
38232
38422
  rootProps: { gap: "lg" },
38233
38423
  children: [...eventSectionHeaderLayoutNodes({ splitClassName: "event-section-head event-section-head--split" }), el("event-calendar", withApiBindings({
38424
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
38234
38425
  events: { $bind: { from: "data.events" } },
38235
38426
  calendarWindow: { $bind: { from: "data.calendarWindow" } },
38236
38427
  stage: { $bind: {
@@ -39110,6 +39301,7 @@ const eventListingSourceSchema = z.object({
39110
39301
  events: z.array(publicEventSchema).nullable().optional(),
39111
39302
  siteId: z.string(),
39112
39303
  apiBaseUrl: z.string().optional(),
39304
+ readAuthority: browserReadAuthoritySchema.optional(),
39113
39305
  stage: previewStageSchema.optional(),
39114
39306
  layout: eventLayoutSchema.optional(),
39115
39307
  columns: columnOptionSchema.optional(),
@@ -39150,7 +39342,6 @@ const eventListingDisplaySchema = z.object({
39150
39342
  });
39151
39343
  const eventListingHydrationSchema = z.object({
39152
39344
  siteId: z.string(),
39153
- stage: previewStageSchema.optional(),
39154
39345
  eventsPerPage: eventPageSizeSchema,
39155
39346
  paginationAction: eventListPaginationActionSchema,
39156
39347
  showFilters: z.boolean(),
@@ -39173,6 +39364,7 @@ const eventListingRenderSchema = z.object({
39173
39364
  z.object({
39174
39365
  siteId: z.string(),
39175
39366
  apiBaseUrl: z.string().optional(),
39367
+ readAuthority: browserReadAuthoritySchema.optional(),
39176
39368
  stage: previewStageSchema.optional()
39177
39369
  });
39178
39370
  const eventListingBlockRuntime = defineProgressiveBlockRuntime({
@@ -39207,7 +39399,6 @@ const eventListingBlockRuntime = defineProgressiveBlockRuntime({
39207
39399
  },
39208
39400
  hydration: {
39209
39401
  siteId: source.siteId,
39210
- stage: source.stage,
39211
39402
  eventsPerPage: pageSize,
39212
39403
  paginationAction: resolveEventListPaginationAction({
39213
39404
  paginationMode: source.paginationMode,
@@ -39237,6 +39428,7 @@ function buildEventListingInteractiveIslandProps(props) {
39237
39428
  meta: {
39238
39429
  siteId: props.siteId,
39239
39430
  apiBaseUrl: props.apiBaseUrl,
39431
+ readAuthority: props.readAuthority,
39240
39432
  stage: props.stage
39241
39433
  },
39242
39434
  source: props
@@ -39501,6 +39693,7 @@ const eventListingBlockDefinition = {
39501
39693
  rootType: "stack",
39502
39694
  rootProps: { gap: "lg" },
39503
39695
  children: [...eventSectionHeaderLayoutNodes(), el("event-listing", withApiBindings({
39696
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
39504
39697
  events: { $bind: { from: "data.events" } },
39505
39698
  stage: { $bind: {
39506
39699
  from: "$root.previewStage",
@@ -40153,6 +40346,7 @@ const productDetailBlockDefinition = {
40153
40346
  baseClass: "",
40154
40347
  spacing: "spacious",
40155
40348
  children: sectionContainer([productDetail(withApiBindings({
40349
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
40156
40350
  mode: "product-detail",
40157
40351
  heading: { $bind: {
40158
40352
  from: "content.heading",
@@ -40321,6 +40515,7 @@ const productListBlockDefinition = {
40321
40515
  baseClass: "",
40322
40516
  spacing: "spacious",
40323
40517
  children: sectionContainer([productList(withApiBindings({
40518
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
40324
40519
  mode: "product-list",
40325
40520
  heading: { $bind: {
40326
40521
  from: "content.heading",
@@ -40585,6 +40780,7 @@ const shopBlockDefinition = {
40585
40780
  baseClass: "",
40586
40781
  spacing: "spacious",
40587
40782
  children: sectionContainer([shop(withApiBindings({
40783
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
40588
40784
  mode: "passes-memberships",
40589
40785
  showPasses: { $bind: {
40590
40786
  from: "content.showPasses",
@@ -40987,15 +41183,13 @@ function CheckoutShellView(props) {
40987
41183
  //#endregion
40988
41184
  //#region ../blocks/src/system/runtime/nodes/shop-commerce.server.tsx
40989
41185
  function renderServerPendingAction(label, soldOut) {
40990
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
41186
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ThemedButton, {
40991
41187
  type: "button",
40992
- className: themeButtonClassName({
40993
- variant: "default",
40994
- size: "md"
40995
- }),
41188
+ variant: "default",
41189
+ size: "md",
41190
+ label: soldOut ? "Sold out" : label,
40996
41191
  disabled: true,
40997
- "aria-disabled": "true",
40998
- children: soldOut ? "Sold out" : label
41192
+ "aria-disabled": "true"
40999
41193
  }), !soldOut ? /* @__PURE__ */ jsx("p", {
41000
41194
  className: "rb-caption status-muted",
41001
41195
  children: "Cart actions become interactive after page load."
@@ -41012,13 +41206,11 @@ function ProductListServerContent(props) {
41012
41206
  selectedVariantId: card.selectedVariantId,
41013
41207
  disabled: true
41014
41208
  }),
41015
- actions: /* @__PURE__ */ jsxs(Fragment, { children: [renderServerPendingAction(card.actionLabel, card.soldOut), card.path ? /* @__PURE__ */ jsx("a", {
41209
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [renderServerPendingAction(card.actionLabel, card.soldOut), card.path ? /* @__PURE__ */ jsx(ThemedButtonLink, {
41016
41210
  href: card.path,
41017
- className: themeButtonClassName({
41018
- variant: "secondary",
41019
- size: "sm"
41020
- }),
41021
- children: "View details"
41211
+ variant: "secondary",
41212
+ size: "sm",
41213
+ label: "View details"
41022
41214
  }) : null] })
41023
41215
  }, card.productId))
41024
41216
  });
@@ -41314,10 +41506,6 @@ function AgendaLinkCard({ event, showCapacity, showVenue, buttonVariant, buttonT
41314
41506
  const price = formatEventPrice(event);
41315
41507
  const capacity = showCapacity ? formatEventRemainingPlaces(event) : null;
41316
41508
  const cta = resolveEventCta(event, buttonText);
41317
- const buttonClass = themeButtonClassName({
41318
- variant: buttonVariant,
41319
- size: "sm"
41320
- });
41321
41509
  return /* @__PURE__ */ jsxs("article", {
41322
41510
  className: "event-agenda-card event-agenda-card--agenda",
41323
41511
  children: [
@@ -41369,12 +41557,14 @@ function AgendaLinkCard({ event, showCapacity, showVenue, buttonVariant, buttonT
41369
41557
  }), cta.hidden ? /* @__PURE__ */ jsx("span", {
41370
41558
  className: "event-agenda-card-status status-muted",
41371
41559
  children: cta.label
41372
- }) : /* @__PURE__ */ jsx("a", {
41560
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
41373
41561
  href: cta.href,
41374
41562
  target: cta.external ? "_blank" : void 0,
41375
41563
  rel: cta.external ? "noopener noreferrer" : void 0,
41376
- className: `${buttonClass} event-agenda-card-cta`,
41377
- children: cta.label
41564
+ variant: buttonVariant,
41565
+ size: "sm",
41566
+ extraClassName: "event-agenda-card-cta",
41567
+ label: cta.label
41378
41568
  })]
41379
41569
  })
41380
41570
  ]
@@ -41573,7 +41763,7 @@ const WeekBoardCard = ({ event, showCapacity, calendarTimeZone }) => {
41573
41763
  ]
41574
41764
  });
41575
41765
  };
41576
- const WeekBoardNavigationControls = ({ navigation, todayClassName }) => {
41766
+ const WeekBoardNavigationControls = ({ navigation, buttonVariant }) => {
41577
41767
  const handlers = navigation.kind === "interactive" ? navigation : {
41578
41768
  onPrevious: void 0,
41579
41769
  onNext: void 0,
@@ -41606,12 +41796,13 @@ const WeekBoardNavigationControls = ({ navigation, todayClassName }) => {
41606
41796
  onClick: handlers.onNext,
41607
41797
  children: /* @__PURE__ */ jsx(CalendarNavigationChevron, { direction: "next" })
41608
41798
  }),
41609
- /* @__PURE__ */ jsx("button", {
41799
+ /* @__PURE__ */ jsx(ThemedButton, {
41610
41800
  type: "button",
41611
- className: todayClassName,
41801
+ variant: buttonVariant,
41802
+ size: "sm",
41803
+ label: "Today",
41612
41804
  disabled: navigation.isCurrentWeek,
41613
- onClick: handlers.onToday,
41614
- children: "Today"
41805
+ onClick: handlers.onToday
41615
41806
  })
41616
41807
  ]
41617
41808
  });
@@ -41627,16 +41818,17 @@ const WeekBoardLegend = () => /* @__PURE__ */ jsx("div", {
41627
41818
  }), item.label]
41628
41819
  }, item.status))
41629
41820
  });
41630
- const WeekBoardLoadError = ({ navigation, buttonClassName }) => {
41821
+ const WeekBoardLoadError = ({ navigation, buttonVariant }) => {
41631
41822
  if (navigation.kind !== "interactive" || navigation.loadState.kind !== "error") return null;
41632
41823
  return /* @__PURE__ */ jsxs("div", {
41633
41824
  className: "event-week-board-error",
41634
41825
  role: "status",
41635
- children: [/* @__PURE__ */ jsx("p", { children: "Failed to load events" }), /* @__PURE__ */ jsx("button", {
41826
+ children: [/* @__PURE__ */ jsx("p", { children: "Failed to load events" }), /* @__PURE__ */ jsx(ThemedButton, {
41636
41827
  type: "button",
41637
- className: buttonClassName,
41638
- onClick: navigation.loadState.onRetry,
41639
- children: "Try again"
41828
+ variant: buttonVariant,
41829
+ size: "sm",
41830
+ label: "Try again",
41831
+ onClick: navigation.loadState.onRetry
41640
41832
  })]
41641
41833
  });
41642
41834
  };
@@ -41668,17 +41860,18 @@ const WeekBoardGrid = ({ days, eventsByDate, showCapacity, calendarTimeZone, tod
41668
41860
  }, dateKey);
41669
41861
  })
41670
41862
  });
41671
- const WeekBoardFooter = ({ note, ctaHref, ctaLabel, ctaClassName }) => {
41863
+ const WeekBoardFooter = ({ note, ctaHref, ctaLabel, buttonVariant }) => {
41672
41864
  if (note === null && ctaHref === null) return null;
41673
41865
  return /* @__PURE__ */ jsxs("div", {
41674
41866
  className: "event-week-board-foot",
41675
41867
  children: [note === null ? null : /* @__PURE__ */ jsx("p", {
41676
41868
  className: "event-week-board-foot-note",
41677
41869
  children: note
41678
- }), ctaHref === null ? null : /* @__PURE__ */ jsx("a", {
41679
- className: ctaClassName,
41870
+ }), ctaHref === null ? null : /* @__PURE__ */ jsx(ThemedButtonLink, {
41871
+ variant: buttonVariant,
41872
+ size: "sm",
41680
41873
  href: ctaHref,
41681
- children: ctaLabel
41874
+ label: ctaLabel
41682
41875
  })]
41683
41876
  });
41684
41877
  };
@@ -41693,14 +41886,6 @@ const WeekBoardFooter = ({ note, ctaHref, ctaLabel, ctaClassName }) => {
41693
41886
  const WeekBoardView = ({ days, events, navigation, showCapacity, emptyMessage = "No classes scheduled this week", title, footerNote, ctaLabel = "Reserve a place", ctaHref = null, buttonVariant = "outline", elevated = false, banded = false, calendarTimeZone, today }) => {
41694
41887
  const eventsByDate = groupEventsByDate(events, calendarTimeZone);
41695
41888
  const hasAnyEvents = days.some((date) => (eventsByDate.get(formatDateKey(date)) ?? []).length > 0);
41696
- const ctaClassName = themeButtonClassName({
41697
- variant: buttonVariant,
41698
- size: "sm"
41699
- });
41700
- const todayClassName = themeButtonClassName({
41701
- variant: buttonVariant,
41702
- size: "sm"
41703
- });
41704
41889
  const hasTitle = typeof title === "string" && title.length > 0;
41705
41890
  const hasFooterNote = typeof footerNote === "string" && footerNote.length > 0;
41706
41891
  const footerNoteText = hasAnyEvents ? hasFooterNote ? footerNote : null : emptyMessage;
@@ -41723,14 +41908,14 @@ const WeekBoardView = ({ days, events, navigation, showCapacity, emptyMessage =
41723
41908
  }) : null,
41724
41909
  /* @__PURE__ */ jsx(WeekBoardNavigationControls, {
41725
41910
  navigation,
41726
- todayClassName
41911
+ buttonVariant
41727
41912
  }),
41728
41913
  /* @__PURE__ */ jsx(WeekBoardLegend, {})
41729
41914
  ]
41730
41915
  }),
41731
41916
  /* @__PURE__ */ jsx(WeekBoardLoadError, {
41732
41917
  navigation,
41733
- buttonClassName: todayClassName
41918
+ buttonVariant
41734
41919
  }),
41735
41920
  /* @__PURE__ */ jsx(WeekBoardGrid, {
41736
41921
  days,
@@ -41743,7 +41928,7 @@ const WeekBoardView = ({ days, events, navigation, showCapacity, emptyMessage =
41743
41928
  note: footerNoteText,
41744
41929
  ctaHref: resolvedCtaHref,
41745
41930
  ctaLabel,
41746
- ctaClassName
41931
+ buttonVariant
41747
41932
  })
41748
41933
  ]
41749
41934
  })
@@ -41853,6 +42038,54 @@ function assertNeverDisplayMode(value) {
41853
42038
  function renderEventCard(event, display) {
41854
42039
  return renderEventListItem(event, display);
41855
42040
  }
42041
+ function CalendarSsrHeader(props) {
42042
+ const periodLabel = props.period === "week" ? "week" : "month";
42043
+ return /* @__PURE__ */ jsxs("div", {
42044
+ className: "event-calendar-header",
42045
+ children: [/* @__PURE__ */ jsxs("div", {
42046
+ className: "event-calendar-nav",
42047
+ children: [
42048
+ /* @__PURE__ */ jsx("button", {
42049
+ type: "button",
42050
+ className: "event-calendar-nav-btn",
42051
+ "aria-label": `Previous ${periodLabel}`,
42052
+ children: /* @__PURE__ */ jsx(CalendarSsrChevron, { direction: "previous" })
42053
+ }),
42054
+ /* @__PURE__ */ jsx("h3", {
42055
+ className: "event-calendar-title",
42056
+ children: props.title
42057
+ }),
42058
+ /* @__PURE__ */ jsx("button", {
42059
+ type: "button",
42060
+ className: "event-calendar-nav-btn",
42061
+ "aria-label": `Next ${periodLabel}`,
42062
+ children: /* @__PURE__ */ jsx(CalendarSsrChevron, { direction: "next" })
42063
+ })
42064
+ ]
42065
+ }), /* @__PURE__ */ jsx(ThemedButton, {
42066
+ type: "button",
42067
+ variant: props.buttonVariant,
42068
+ size: "sm",
42069
+ label: "Today"
42070
+ })]
42071
+ });
42072
+ }
42073
+ function CalendarSsrChevron(props) {
42074
+ return /* @__PURE__ */ jsx("svg", {
42075
+ width: "20",
42076
+ height: "20",
42077
+ fill: "none",
42078
+ stroke: "currentColor",
42079
+ strokeWidth: 2,
42080
+ viewBox: "0 0 24 24",
42081
+ children: /* @__PURE__ */ jsx("path", {
42082
+ strokeLinecap: "round",
42083
+ strokeLinejoin: "round",
42084
+ strokeWidth: 2,
42085
+ d: props.direction === "previous" ? "M15 19l-7-7 7-7" : "M9 5l7 7-7 7"
42086
+ })
42087
+ });
42088
+ }
41856
42089
  function renderCombinedSsr(display, prefetchedEvents) {
41857
42090
  const listDisplay = buildEventCalendarListingDisplay(display, prefetchedEvents, "event-combined-content");
41858
42091
  return /* @__PURE__ */ jsxs("div", {
@@ -41900,62 +42133,10 @@ function renderCalendarSsr(display, hydration) {
41900
42133
  return /* @__PURE__ */ jsxs("div", {
41901
42134
  className: clsx("event-calendar", display.className ?? void 0),
41902
42135
  "data-block": "event-calendar",
41903
- children: [/* @__PURE__ */ jsxs("div", {
41904
- className: "event-calendar-header",
41905
- children: [/* @__PURE__ */ jsxs("div", {
41906
- className: "event-calendar-nav",
41907
- children: [
41908
- /* @__PURE__ */ jsx("button", {
41909
- type: "button",
41910
- className: "event-calendar-nav-btn",
41911
- "aria-label": calendarView === "week" ? "Previous week" : "Previous month",
41912
- children: /* @__PURE__ */ jsx("svg", {
41913
- width: "20",
41914
- height: "20",
41915
- fill: "none",
41916
- stroke: "currentColor",
41917
- strokeWidth: 2,
41918
- viewBox: "0 0 24 24",
41919
- children: /* @__PURE__ */ jsx("path", {
41920
- strokeLinecap: "round",
41921
- strokeLinejoin: "round",
41922
- strokeWidth: 2,
41923
- d: "M15 19l-7-7 7-7"
41924
- })
41925
- })
41926
- }),
41927
- /* @__PURE__ */ jsx("h3", {
41928
- className: "event-calendar-title",
41929
- children: viewport.title
41930
- }),
41931
- /* @__PURE__ */ jsx("button", {
41932
- type: "button",
41933
- className: "event-calendar-nav-btn",
41934
- "aria-label": calendarView === "week" ? "Next week" : "Next month",
41935
- children: /* @__PURE__ */ jsx("svg", {
41936
- width: "20",
41937
- height: "20",
41938
- fill: "none",
41939
- stroke: "currentColor",
41940
- strokeWidth: 2,
41941
- viewBox: "0 0 24 24",
41942
- children: /* @__PURE__ */ jsx("path", {
41943
- strokeLinecap: "round",
41944
- strokeLinejoin: "round",
41945
- strokeWidth: 2,
41946
- d: "M9 5l7 7-7 7"
41947
- })
41948
- })
41949
- })
41950
- ]
41951
- }), /* @__PURE__ */ jsx("button", {
41952
- type: "button",
41953
- className: themeButtonClassName({
41954
- variant: display.buttonVariant,
41955
- size: "sm"
41956
- }),
41957
- children: "Today"
41958
- })]
42136
+ children: [/* @__PURE__ */ jsx(CalendarSsrHeader, {
42137
+ title: viewport.title,
42138
+ period: calendarView,
42139
+ buttonVariant: display.buttonVariant
41959
42140
  }), viewport.kind === "week" ? /* @__PURE__ */ jsx(WeekAgendaView, {
41960
42141
  days: viewport.days,
41961
42142
  events: [...display.events],
@@ -42031,62 +42212,10 @@ function renderTimetableSsr(display, hydration) {
42031
42212
  return /* @__PURE__ */ jsxs("div", {
42032
42213
  className: clsx("event-calendar", "event-calendar--timetable", display.className ?? void 0),
42033
42214
  "data-block": "event-calendar",
42034
- children: [/* @__PURE__ */ jsxs("div", {
42035
- className: "event-calendar-header",
42036
- children: [/* @__PURE__ */ jsxs("div", {
42037
- className: "event-calendar-nav",
42038
- children: [
42039
- /* @__PURE__ */ jsx("button", {
42040
- type: "button",
42041
- className: "event-calendar-nav-btn",
42042
- "aria-label": "Previous week",
42043
- children: /* @__PURE__ */ jsx("svg", {
42044
- width: "20",
42045
- height: "20",
42046
- fill: "none",
42047
- stroke: "currentColor",
42048
- strokeWidth: 2,
42049
- viewBox: "0 0 24 24",
42050
- children: /* @__PURE__ */ jsx("path", {
42051
- strokeLinecap: "round",
42052
- strokeLinejoin: "round",
42053
- strokeWidth: 2,
42054
- d: "M15 19l-7-7 7-7"
42055
- })
42056
- })
42057
- }),
42058
- /* @__PURE__ */ jsx("h3", {
42059
- className: "event-calendar-title",
42060
- children: viewport.title
42061
- }),
42062
- /* @__PURE__ */ jsx("button", {
42063
- type: "button",
42064
- className: "event-calendar-nav-btn",
42065
- "aria-label": "Next week",
42066
- children: /* @__PURE__ */ jsx("svg", {
42067
- width: "20",
42068
- height: "20",
42069
- fill: "none",
42070
- stroke: "currentColor",
42071
- strokeWidth: 2,
42072
- viewBox: "0 0 24 24",
42073
- children: /* @__PURE__ */ jsx("path", {
42074
- strokeLinecap: "round",
42075
- strokeLinejoin: "round",
42076
- strokeWidth: 2,
42077
- d: "M9 5l7 7-7 7"
42078
- })
42079
- })
42080
- })
42081
- ]
42082
- }), /* @__PURE__ */ jsx("button", {
42083
- type: "button",
42084
- className: themeButtonClassName({
42085
- variant: display.buttonVariant,
42086
- size: "sm"
42087
- }),
42088
- children: "Today"
42089
- })]
42215
+ children: [/* @__PURE__ */ jsx(CalendarSsrHeader, {
42216
+ title: viewport.title,
42217
+ period: "week",
42218
+ buttonVariant: display.buttonVariant
42090
42219
  }), /* @__PURE__ */ jsxs("div", {
42091
42220
  className: "event-timetable",
42092
42221
  children: [
@@ -42582,14 +42711,12 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
42582
42711
  className: "fb-actions",
42583
42712
  children: /* @__PURE__ */ jsx("div", {
42584
42713
  className: "fb-actions-inner",
42585
- children: /* @__PURE__ */ jsx("button", {
42714
+ children: /* @__PURE__ */ jsx(ThemedButton, {
42586
42715
  type: "submit",
42587
- className: themeButtonClassName({
42588
- variant: "primary",
42589
- size: "md",
42590
- extraClassName: "rb-w-full rb-sm-w-auto"
42591
- }),
42592
- children: display.submitLabel
42716
+ variant: "primary",
42717
+ size: "md",
42718
+ extraClassName: "rb-w-full rb-sm-w-auto",
42719
+ label: display.submitLabel
42593
42720
  })
42594
42721
  })
42595
42722
  })
@@ -42684,13 +42811,11 @@ function NewsletterFormSSR(props) {
42684
42811
  }) : null,
42685
42812
  /* @__PURE__ */ jsx("div", {
42686
42813
  className: "newsletter-submit",
42687
- children: /* @__PURE__ */ jsx("button", {
42814
+ children: /* @__PURE__ */ jsx(ThemedButton, {
42688
42815
  type: "submit",
42689
- className: themeButtonClassName({
42690
- variant: display.buttonVariant,
42691
- size: "md"
42692
- }),
42693
- children: display.buttonLabel
42816
+ variant: display.buttonVariant,
42817
+ size: "md",
42818
+ label: display.buttonLabel
42694
42819
  })
42695
42820
  })
42696
42821
  ]
@@ -42772,28 +42897,24 @@ function ShopSSR({ blockId, siteId, apiBaseUrl, stage, children, checkoutEndpoin
42772
42897
  display: render.display,
42773
42898
  passCards: render.display.passes.map((pass) => /* @__PURE__ */ jsx(PassCardView, {
42774
42899
  display: pass,
42775
- action: pass.action.kind === "unavailable" ? /* @__PURE__ */ jsx(PassPurchaseUnavailable, { label: pass.action.label }) : /* @__PURE__ */ jsx("button", {
42900
+ action: pass.action.kind === "unavailable" ? /* @__PURE__ */ jsx(PassPurchaseUnavailable, { label: pass.action.label }) : /* @__PURE__ */ jsx(ThemedButton, {
42776
42901
  type: "button",
42777
- className: themeButtonClassName({
42778
- variant: render.hydration.buttonVariant,
42779
- size: "md"
42780
- }),
42902
+ variant: render.hydration.buttonVariant,
42903
+ size: "md",
42904
+ label: pass.action.label,
42781
42905
  disabled: true,
42782
- "aria-disabled": "true",
42783
- children: pass.action.label
42906
+ "aria-disabled": "true"
42784
42907
  })
42785
42908
  }, pass.id)),
42786
42909
  membershipCards: render.display.memberships.map((membership) => /* @__PURE__ */ jsx(MembershipCardView, {
42787
42910
  display: membership,
42788
- action: /* @__PURE__ */ jsx("button", {
42911
+ action: /* @__PURE__ */ jsx(ThemedButton, {
42789
42912
  type: "button",
42790
- className: themeButtonClassName({
42791
- variant: render.hydration.buttonVariant,
42792
- size: "md"
42793
- }),
42913
+ variant: render.hydration.buttonVariant,
42914
+ size: "md",
42915
+ label: membership.actionLabel,
42794
42916
  disabled: true,
42795
- "aria-disabled": "true",
42796
- children: membership.actionLabel
42917
+ "aria-disabled": "true"
42797
42918
  })
42798
42919
  }, membership.id))
42799
42920
  }),
@@ -42842,6 +42963,7 @@ const serverComponentRegistry = {
42842
42963
  svg: SvgNode,
42843
42964
  section: SectionNode,
42844
42965
  headerSection: header_section_server_default,
42966
+ headerControl: HeaderControlNode,
42845
42967
  stack: StackNode,
42846
42968
  inline: InlineNode,
42847
42969
  grid: GridNode,
@@ -43668,16 +43790,71 @@ function resolveChildren(nodes, context) {
43668
43790
  function isReactNode(value) {
43669
43791
  return value !== null && value !== void 0;
43670
43792
  }
43793
+ const RENDERER_METADATA_PROP_KEYS = /* @__PURE__ */ new Set([
43794
+ "pathBase",
43795
+ "blockId",
43796
+ "blockKind",
43797
+ "blockContent",
43798
+ "fragmentRegistry",
43799
+ "previewAuthoring",
43800
+ "contentVersionId",
43801
+ "imageResolveContext"
43802
+ ]);
43803
+ function omitRendererMetadataProps(props) {
43804
+ const presentationProps = {};
43805
+ for (const [key, value] of Object.entries(props)) if (!RENDERER_METADATA_PROP_KEYS.has(key)) presentationProps[key] = value;
43806
+ return presentationProps;
43807
+ }
43808
+ const BLOCK_ID_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
43809
+ "accordion",
43810
+ "appointment-services",
43811
+ "booking-form",
43812
+ "carousel",
43813
+ "cart",
43814
+ "checkout",
43815
+ "event-calendar",
43816
+ "event-combined",
43817
+ "event-details",
43818
+ "event-listing",
43819
+ "event-registration",
43820
+ "form",
43821
+ "gifting",
43822
+ "headersection",
43823
+ "location-map",
43824
+ "newsletter-form",
43825
+ "product-detail",
43826
+ "product-list",
43827
+ "shop",
43828
+ "weekly-slot-availability"
43829
+ ]);
43830
+ const BLOCK_CONTENT_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
43831
+ "feature-card-icon",
43832
+ "headersection",
43833
+ "media",
43834
+ "text"
43835
+ ]);
43836
+ const BLOCK_KIND_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
43837
+ "headersection",
43838
+ "media",
43839
+ "richtext"
43840
+ ]);
43841
+ /**
43842
+ * Projects resolver context only to node kinds with an explicit metadata
43843
+ * contract. Presentation props and renderer metadata never share a universal
43844
+ * spread boundary, so adding metadata cannot leak it into DOM-backed nodes.
43845
+ */
43671
43846
  function resolveNodeMetadata(nodeType, context) {
43847
+ const normalizedType = nodeType.toLowerCase();
43672
43848
  return {
43673
- pathBase: context.pathBase,
43674
- blockId: context.blockId,
43675
- blockKind: context.blockKind,
43676
- blockContent: context.blockContent,
43677
- fragmentRegistry: context.fragmentRegistry,
43678
- previewAuthoring: context.previewAuthoring,
43679
- ...nodeType.toLowerCase() === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
43680
- ...nodeType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
43849
+ ...BLOCK_ID_METADATA_CONSUMERS.has(normalizedType) ? { blockId: context.blockId } : {},
43850
+ ...BLOCK_KIND_METADATA_CONSUMERS.has(normalizedType) ? { blockKind: context.blockKind } : {},
43851
+ ...BLOCK_CONTENT_METADATA_CONSUMERS.has(normalizedType) ? { blockContent: context.blockContent } : {},
43852
+ ...normalizedType === "headersection" ? {
43853
+ pathBase: context.pathBase,
43854
+ fragmentRegistry: context.fragmentRegistry
43855
+ } : {},
43856
+ ...normalizedType === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
43857
+ ...normalizedType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
43681
43858
  };
43682
43859
  }
43683
43860
  /**
@@ -43713,7 +43890,7 @@ function resolveNode(node, context, indexFallback) {
43713
43890
  props = omitHeadingDecorationProps(props);
43714
43891
  const children = resolveChildren(node.children, scopeContext);
43715
43892
  const elementProps = {
43716
- ...props,
43893
+ ...omitRendererMetadataProps(props),
43717
43894
  key: node.key ?? indexFallback,
43718
43895
  ...resolveNodeMetadata(node.type, context)
43719
43896
  };
@@ -44341,7 +44518,7 @@ function generateInputCss({ themeId, theme, inputSystem }) {
44341
44518
  baseInputRules.push("transition: border-color 0.2s ease, box-shadow 0.2s ease");
44342
44519
  const labelSelector = `${rootSelector} .form-label`;
44343
44520
  const labelRules = [];
44344
- labelRules.push(`color: ${rgbColorValue(inputSystem.label.textColorToken)}`);
44521
+ labelRules.push(`color: ${textColorValue(inputSystem.label.textColorToken)}`);
44345
44522
  labelRules.push(`font-weight: ${FONT_WEIGHT_MAP[inputSystem.label.fontWeight]}`);
44346
44523
  labelRules.push(`font-size: ${LABEL_FONT_SIZE_MAP[inputSystem.label.fontSize]}`);
44347
44524
  if (inputSystem.label.textTransform && inputSystem.label.textTransform !== "none") labelRules.push(`text-transform: ${inputSystem.label.textTransform}`);
@@ -47772,7 +47949,7 @@ function pageBlockPosition(index, blockCount) {
47772
47949
  //#endregion
47773
47950
  //#region ../blocks/src/pageRendererContracts.ts
47774
47951
  function buildPageRendererRootRuntime(dataContext) {
47775
- const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, bookingOfferingPresets = [], appointmentServicePathPrefix = null, mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
47952
+ const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, readAuthority, bookingOfferingPresets = [], appointmentServicePathPrefix = null, mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
47776
47953
  return {
47777
47954
  siteId,
47778
47955
  pageId,
@@ -47781,6 +47958,7 @@ function buildPageRendererRootRuntime(dataContext) {
47781
47958
  previewStage,
47782
47959
  apiBaseUrl,
47783
47960
  portalToken,
47961
+ readAuthority,
47784
47962
  bookingOfferingPresets,
47785
47963
  appointmentServicePathPrefix,
47786
47964
  mailingList,
@@ -50476,46 +50654,42 @@ const whenTransformed = (from, transformId, equals = true) => (node) => ({
50476
50654
  equals
50477
50655
  }
50478
50656
  });
50479
- const logoRow = link({
50657
+ /** Draw whichever site logo suits the surface this row sits on. */
50658
+ const bindChromeLogo = (surface) => bind("content", { transforms: [{
50659
+ id: "layout.chromeLogo",
50660
+ options: { surface }
50661
+ }] });
50662
+ /**
50663
+ * The brand link. The logo is chosen per surface because the open mobile menu
50664
+ * paints its own background, which may be the opposite tone to the header.
50665
+ */
50666
+ const createLogoRow = (surface) => link({
50480
50667
  href: "/",
50481
50668
  className: bindProp("$root.theme.header.logo", {
50482
50669
  transforms: pipe(tx("layout.headerLogoClass")),
50483
50670
  fallback: "header-logo rb-flex rb-min-w-0 rb-items-center rb-gap-3 rb-no-underline rb-transition-opacity rb-hover-opacity-80"
50484
50671
  })
50485
- }, [
50486
- media({ className: bindProp("$root.theme.header.logo", {
50487
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
50488
- fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
50489
- }) }, when("content.logo"), bind("content.logo")),
50490
- stack({ className: "rb-contents" }, [media({ className: bindProp("$root.theme.header.logo", {
50491
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
50492
- fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
50493
- }) }, when("site.logo"), bind("site.logo"))], when("content.logo", { not: true })),
50494
- text({
50495
- as: "strong",
50496
- className: "header-logo-text rb-truncate"
50497
- }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
50498
- ]);
50672
+ }, [media({ className: bindProp("$root.theme.header.logo", {
50673
+ transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
50674
+ fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
50675
+ }) }, when("content.logo"), bindChromeLogo(surface)), text({
50676
+ as: "strong",
50677
+ className: "header-logo-text rb-truncate"
50678
+ }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))]);
50679
+ const logoRow = createLogoRow("header-root");
50499
50680
  const centeredLogoRow = link({
50500
50681
  href: "/",
50501
50682
  className: bindProp("$root.theme.header.logo", {
50502
50683
  transforms: pipe(tx("layout.headerLogoClass", { base: "header-logo rb-flex rb-items-center rb-justify-center rb-gap-3 rb-text-center rb-no-underline rb-transition-opacity rb-hover-opacity-80" })),
50503
50684
  fallback: "header-logo rb-flex rb-items-center rb-justify-center rb-gap-3 rb-text-center rb-no-underline rb-transition-opacity rb-hover-opacity-80"
50504
50685
  })
50505
- }, [
50506
- media({ className: bindProp("$root.theme.header.logo", {
50507
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
50508
- fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
50509
- }) }, when("content.logo"), bind("content.logo")),
50510
- stack({ className: "rb-contents" }, [media({ className: bindProp("$root.theme.header.logo", {
50511
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
50512
- fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
50513
- }) }, when("site.logo"), bind("site.logo"))], when("content.logo", { not: true })),
50514
- text({
50515
- as: "strong",
50516
- className: "header-logo-text"
50517
- }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
50518
- ]);
50686
+ }, [media({ className: bindProp("$root.theme.header.logo", {
50687
+ transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
50688
+ fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
50689
+ }) }, when("content.logo"), bindChromeLogo("header-root")), text({
50690
+ as: "strong",
50691
+ className: "header-logo-text"
50692
+ }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))]);
50519
50693
  const createNavRow = (className, align = "end") => navRow({
50520
50694
  className: `${className} header-nav-row`,
50521
50695
  align,
@@ -50555,10 +50729,8 @@ const mobileToggleIcon = stack({
50555
50729
  }
50556
50730
  ]);
50557
50731
  const mobileToggleButton = {
50558
- type: "button",
50732
+ type: "headerControl",
50559
50733
  props: {
50560
- type: "button",
50561
- variantId: "",
50562
50734
  className: `nav-mobile-toggle ${mobileOnlyDisplay("inline-flex")} rb-h-10 rb-w-10 rb-items-center rb-justify-center rb-rounded-md transition-theme-standard`,
50563
50735
  "aria-label": "Open menu",
50564
50736
  "aria-expanded": "false",
@@ -50568,10 +50740,8 @@ const mobileToggleButton = {
50568
50740
  children: [mobileToggleIcon]
50569
50741
  };
50570
50742
  const mobileOverlayToggleButton = {
50571
- type: "button",
50743
+ type: "headerControl",
50572
50744
  props: {
50573
- type: "button",
50574
- variantId: "",
50575
50745
  className: "nav-mobile-toggle rb-inline-flex rb-h-10 rb-w-10 rb-items-center rb-justify-center rb-rounded-md transition-theme-standard",
50576
50746
  "aria-label": "Open menu",
50577
50747
  "aria-expanded": "false",
@@ -50595,7 +50765,7 @@ const mobileOverlayHeader = inline({
50595
50765
  align: "center",
50596
50766
  justify: "between",
50597
50767
  style: borderColorStyle("border")
50598
- }, [logoRow, mobileOverlayToggleButton]);
50768
+ }, [createLogoRow("header-mobile-panel"), mobileOverlayToggleButton]);
50599
50769
  const mobileOverlayBody = stack({
50600
50770
  className: "rb-flex-1 rb-px-6 rb-py-6",
50601
50771
  gap: "md",
@@ -50783,7 +50953,10 @@ const brandLogo = link({
50783
50953
  options: { base: "rb-h-10 rb-w-auto" }
50784
50954
  }],
50785
50955
  fallback: "rb-h-10 rb-w-auto"
50786
- } } }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content.logo")), text({
50956
+ } } }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content", { transforms: [{
50957
+ id: "layout.chromeLogo",
50958
+ options: { surface: "footer-root" }
50959
+ }] })), text({
50787
50960
  as: "strong",
50788
50961
  className: "footer-logo-text rb-nav-text"
50789
50962
  }, when("module.showTitle", { equals: true }), bind("site.title", { fallback: "Your Site" }))], when("module.kind", { equals: "brand" }));
@@ -57771,6 +57944,7 @@ function blockSessionProps(dataContext) {
57771
57944
  supabaseUrl: dataContext?.supabaseUrl,
57772
57945
  portalToken: dataContext?.portalToken ?? null,
57773
57946
  previewToken: dataContext?.previewToken ?? null,
57947
+ readAuthority: dataContext?.readAuthority,
57774
57948
  stage: dataContext?.previewStage
57775
57949
  };
57776
57950
  }
@@ -60428,6 +60602,12 @@ const containerResponsiveThemeCss = `/*
60428
60602
  :where(.theme-scope) .rb-prose p {
60429
60603
  margin: var(--rt-space-y) 0;
60430
60604
  }
60605
+ :where(.theme-scope) .rb-prose li > p:first-child {
60606
+ margin-top: 0;
60607
+ }
60608
+ :where(.theme-scope) .rb-prose li > p:last-child {
60609
+ margin-bottom: 0;
60610
+ }
60431
60611
  :where(.theme-scope) .rb-prose img {
60432
60612
  display: block;
60433
60613
  max-width: 100%;
@@ -71985,7 +72165,7 @@ function buildPageRouteRenderContext(dataContext) {
71985
72165
  };
71986
72166
  }
71987
72167
  function PageContent(props) {
71988
- const { page, runtimeBoundaries, siteId, resolvedData, bookingOfferingPresets, mailingList, bookingTimeZone, routeMap, pagesByIdentifier, entriesByIdentifier, wrapBlock, registry, blockOverrides, sdkConfig, customBlocks, supabaseUrl, mediaAssets, apiBaseUrl, portalToken, previewToken, dataContext } = props;
72168
+ const { page, runtimeBoundaries, siteId, resolvedData, bookingOfferingPresets, mailingList, bookingTimeZone, routeMap, pagesByIdentifier, entriesByIdentifier, wrapBlock, registry, blockOverrides, sdkConfig, customBlocks, supabaseUrl, mediaAssets, apiBaseUrl, portalToken, previewToken, readAuthority, dataContext } = props;
71989
72169
  const rendererCommonProps = {
71990
72170
  page,
71991
72171
  runtimeBoundaries,
@@ -71995,6 +72175,7 @@ function PageContent(props) {
71995
72175
  apiBaseUrl,
71996
72176
  portalToken,
71997
72177
  previewToken,
72178
+ readAuthority: readAuthority ?? dataContext?.readAuthority,
71998
72179
  resolvedData,
71999
72180
  bookingOfferingPresets: bookingOfferingPresets ?? [],
72000
72181
  mailingList: mailingList ?? dataContext?.mailingList,
@@ -72500,6 +72681,33 @@ function buildLogo(logo, fallbackAlt) {
72500
72681
  if (logo.height != null) result.height = logo.height;
72501
72682
  return result;
72502
72683
  }
72684
+ /**
72685
+ * Build both site logos from layout data. The default header and footer choose
72686
+ * between them by the surface they sit on; custom chrome can do the same.
72687
+ *
72688
+ * @example
72689
+ * ```ts
72690
+ * const logoVariants = buildLogoVariants(siteData.layout, siteData.site.title);
72691
+ * ```
72692
+ */
72693
+ function buildLogoVariants(layout, fallbackAlt) {
72694
+ return {
72695
+ forLightBackgrounds: buildLogo(layout?.logo ?? null, fallbackAlt),
72696
+ forDarkBackgrounds: buildLogo(layout?.logoForDarkBackgrounds ?? null, fallbackAlt)
72697
+ };
72698
+ }
72699
+ /**
72700
+ * Header/footer block content for the site logos. `logo` stays populated with
72701
+ * whichever logo exists so presence checks keep working; `logoVariants` is
72702
+ * what the blocks select from at render.
72703
+ */
72704
+ function buildChromeLogoContent(layout, fallbackAlt) {
72705
+ const logoVariants = buildLogoVariants(layout, fallbackAlt);
72706
+ return {
72707
+ logo: logoVariants.forLightBackgrounds ?? logoVariants.forDarkBackgrounds,
72708
+ logoVariants
72709
+ };
72710
+ }
72503
72711
  //#endregion
72504
72712
  //#region src/rendering/themeAdmission.ts
72505
72713
  const MISSING_SDK_THEME_ERROR_CODE = "missing_sdk_theme";
@@ -73140,10 +73348,10 @@ async function Layout(props) {
73140
73348
  const menuViewModel = buildMenu(navigation, routes, navigationOptions);
73141
73349
  const footerMenuViewModel = buildFooterMenu(navigation, routes, navigationOptions);
73142
73350
  const legalFooterMenuViewModel = buildFooterMenuForRole(navigation, routes, "legal-policy", navigationOptions);
73143
- const logoViewModel = buildLogo(layout.logo ?? null, site.title);
73351
+ const chromeLogoContent = buildChromeLogoContent(layout, site.title);
73144
73352
  const customHeaderData = {
73145
73353
  menu: menuViewModel,
73146
- logo: logoViewModel,
73354
+ ...chromeLogoContent,
73147
73355
  site,
73148
73356
  routes
73149
73357
  };
@@ -73151,7 +73359,7 @@ async function Layout(props) {
73151
73359
  menu: menuViewModel,
73152
73360
  footerMenu: footerMenuViewModel,
73153
73361
  legalFooterMenu: legalFooterMenuViewModel,
73154
- logo: logoViewModel,
73362
+ ...chromeLogoContent,
73155
73363
  site,
73156
73364
  routes
73157
73365
  };
@@ -73208,13 +73416,13 @@ async function Layout(props) {
73208
73416
  };
73209
73417
  const headerViewModelOverrides = {
73210
73418
  ...sharedViewModelOverrides,
73211
- content: { logo: logoViewModel }
73419
+ content: chromeLogoContent
73212
73420
  };
73213
73421
  const footerViewModelOverrides = {
73214
73422
  ...sharedViewModelOverrides,
73215
73423
  content: {
73216
73424
  ...layout.footer,
73217
- logo: logoViewModel
73425
+ ...chromeLogoContent
73218
73426
  }
73219
73427
  };
73220
73428
  let headerElement = null;
@@ -74557,6 +74765,17 @@ const NEWSLETTER_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
74557
74765
  //#endregion
74558
74766
  //#region ../api/src/publicEventEndpointDefinitions.ts
74559
74767
  const PUBLIC_EVENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
74768
+ checkPublicEventRegistrationNextStep: {
74769
+ path: "/public/sites/{siteId}/events/registration-next-step",
74770
+ method: "POST",
74771
+ auth: "public",
74772
+ responseKind: "json",
74773
+ errors: [
74774
+ "validation:invalid_input",
74775
+ "auth:forbidden",
74776
+ "server:internal_error"
74777
+ ]
74778
+ },
74560
74779
  listPublicEventCalendarWindow: {
74561
74780
  path: "/public/sites/{siteId}/events/calendar-window",
74562
74781
  method: "GET",
@@ -76912,13 +77131,14 @@ async function loadStandaloneBlockData({ blockKind, blockId, siteId, pageId, pre
76912
77131
  previewStage
76913
77132
  }, client))[blockId];
76914
77133
  }
76915
- function buildStandaloneBlockViewModel({ siteId, pageId, previewStage, apiBaseUrl, portalToken, routeMap, pagesByIdentifier, entriesByIdentifier }) {
77134
+ function buildStandaloneBlockViewModel({ siteId, pageId, previewStage, apiBaseUrl, portalToken, readAuthority, routeMap, pagesByIdentifier, entriesByIdentifier }) {
76916
77135
  return { $root: {
76917
77136
  siteId: siteId ?? null,
76918
77137
  pageId: pageId ?? null,
76919
77138
  previewStage: previewStage ?? "published",
76920
77139
  apiBaseUrl: apiBaseUrl ?? null,
76921
77140
  portalToken: portalToken ?? null,
77141
+ readAuthority,
76922
77142
  ...routeMap ? { routes: routeMap } : {},
76923
77143
  ...pagesByIdentifier ? { pagesByIdentifier } : {},
76924
77144
  ...entriesByIdentifier ? { entriesByIdentifier } : {}