@riverbankcms/sdk 0.143.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 (161) hide show
  1. package/dist/{PreviewEditorSidebar-DROGfMKi.mjs → PreviewEditorSidebar-CQZNnFiM.mjs} +19 -25
  2. package/dist/{PreviewEditorUI-BaRjhFu-.mjs → PreviewEditorUI-DCNxnmI0.mjs} +2 -2
  3. package/dist/{SdkPreviewModeRuntime-OIABYLES.mjs → SdkPreviewModeRuntime-BJolUbr1.mjs} +15 -6
  4. package/dist/{SiteChromeCustomizeContext-ohjTvZbc.mjs → SiteChromeCustomizeContext-CKgEpoxi.mjs} +1915 -1463
  5. package/dist/_dts/api/src/billing.d.ts +1 -1
  6. package/dist/_dts/api/src/billingEndpointTypes.d.ts +8 -2
  7. package/dist/_dts/api/src/bookingConfig.d.ts +3 -1
  8. package/dist/_dts/api/src/index.d.ts +1 -1
  9. package/dist/_dts/api/src/navigation/dashboardBookingsNav.d.ts +4 -4
  10. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +1 -0
  11. package/dist/_dts/api/src/sdkContracts.d.ts +1 -1
  12. package/dist/_dts/api/src/sdkSettingsContracts.d.ts +8 -0
  13. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +2 -8
  14. package/dist/_dts/api/src/siteSettings.d.ts +17 -7
  15. package/dist/_dts/billing/src/membership/index.d.ts +3 -0
  16. package/dist/_dts/block-form/src/backend/types.d.ts +14 -0
  17. package/dist/_dts/block-form/src/client/index.d.ts +1 -0
  18. package/dist/_dts/block-form/src/context/RepeaterHostActionsContext.d.ts +30 -0
  19. package/dist/_dts/block-form/src/context/index.d.ts +1 -0
  20. package/dist/_dts/block-form/src/index.d.ts +1 -0
  21. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterList.d.ts +4 -1
  22. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRow.d.ts +5 -2
  23. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRowActions.d.ts +11 -1
  24. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/index.d.ts +1 -0
  25. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useEmptyStateFocusAfterRemoval.d.ts +8 -0
  26. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/buildSummary.d.ts +15 -1
  27. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterRowActionsDomain.d.ts +5 -2
  28. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +34 -10
  29. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +3 -0
  30. package/dist/_dts/blocks/src/system/constants/events.d.ts +10 -0
  31. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +5 -0
  32. package/dist/_dts/blocks/src/system/runtime/api/context.d.ts +3 -3
  33. package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +10 -0
  34. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +3 -2
  35. package/dist/_dts/blocks/src/system/runtime/api/readAuthority.d.ts +11 -0
  36. package/dist/_dts/blocks/src/system/runtime/api/types/core.d.ts +9 -0
  37. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +7 -13
  38. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +3 -6
  39. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +9 -4
  40. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +0 -1
  41. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +1 -3
  42. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +7 -24
  43. package/dist/_dts/blocks/src/system/runtime/nodes/cart.server.d.ts +1 -0
  44. package/dist/_dts/blocks/src/system/runtime/nodes/checkout.server.d.ts +1 -0
  45. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationBookingLayer.d.ts +2 -1
  46. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +2 -1
  47. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizardActions.d.ts +2 -1
  48. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -0
  49. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.override.d.ts +2 -1
  50. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +2 -2
  51. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +8 -0
  52. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +4 -5
  53. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +7 -2
  54. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +7 -5
  55. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +5 -6
  56. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +3 -1
  57. package/dist/_dts/blocks/src/system/runtime/nodes/header-control.d.ts +10 -0
  58. package/dist/_dts/blocks/src/system/runtime/nodes/layout.d.ts +6 -21
  59. package/dist/_dts/blocks/src/system/runtime/nodes/product-detail.server.d.ts +1 -0
  60. package/dist/_dts/blocks/src/system/runtime/nodes/product-list.server.d.ts +1 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +13 -0
  62. package/dist/_dts/blocks/src/system/runtime/nodes/shop.server.d.ts +1 -0
  63. package/dist/_dts/blocks/src/system/runtime/shared/components/ThemedButton.d.ts +58 -0
  64. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -0
  65. package/dist/_dts/blocks/src/system/transforms/registry/chromeLogo.d.ts +23 -0
  66. package/dist/_dts/blocks/src/system/transforms/registry/index.d.ts +2 -1
  67. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +3 -1
  68. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +4 -1
  69. package/dist/_dts/core/src/event-catalogue.d.ts +27 -0
  70. package/dist/_dts/core/src/event-preset-vocabulary.d.ts +7 -0
  71. package/dist/_dts/core/src/index.d.ts +2 -0
  72. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +13 -0
  73. package/dist/_dts/db/src/schemas/forms.d.ts +286 -2
  74. package/dist/_dts/editor-blocks/src/block-editor/{BlockCardHeader.d.ts → BlockCardFrame.d.ts} +11 -3
  75. package/dist/_dts/logger/src/console.d.ts +3 -0
  76. package/dist/_dts/sdk/src/client/publicEventReadOperations.d.ts +1 -0
  77. package/dist/_dts/sdk/src/client/types.d.ts +3 -0
  78. package/dist/_dts/sdk/src/navigation/index.d.ts +27 -0
  79. package/dist/_dts/sdk/src/public-api/contracts.d.ts +15 -7
  80. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +1 -0
  81. package/dist/_dts/sdk/src/rendering/client.d.ts +1 -0
  82. package/dist/_dts/sdk/src/rendering/components/Block.shared.d.ts +1 -0
  83. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +7 -1
  84. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -0
  85. package/dist/_dts/sdk/src/rendering/islands/enhancers/routeIslandApiConfig.d.ts +3 -2
  86. package/dist/_dts/sdk/src/rendering/islands/enhancers/shopShared.d.ts +2 -0
  87. package/dist/_dts/sdk/src/rendering/overrides.d.ts +1 -0
  88. package/dist/_dts/sdk/src/version.d.ts +1 -1
  89. package/dist/_dts/theme-core/src/buttons/affordanceSuppression.d.ts +1 -1
  90. package/dist/_dts/theme-core/src/buttons/classNames.d.ts +3 -13
  91. package/dist/_dts/theme-core/src/customCss/index.d.ts +1 -1
  92. package/dist/_dts/theme-core/src/customCss/patch.d.ts +0 -5
  93. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  94. package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
  95. package/dist/_dts/theme-core/src/surfaces/logoVariant.d.ts +26 -0
  96. package/dist/_dts/theme-core/src/utils/colorStyles.d.ts +10 -0
  97. package/dist/_dts/ui/src/editor-item-card.d.ts +116 -0
  98. package/dist/_dts/ui/src/index.d.ts +1 -0
  99. package/dist/client/{BookingConsentAgreement-BoCtvzzu.mjs → BookingConsentAgreement-DoAILrkN.mjs} +4 -55
  100. package/dist/client/{DiscountCodeDisclosure-B5S30nZk.mjs → DiscountCodeDisclosure-X528hUTf.mjs} +27 -17
  101. package/dist/client/{EventCombined.client-CeZ2-zSt.mjs → EventCombined.client-DSBVwq5m.mjs} +54 -46
  102. package/dist/client/{EventListing.client-DJN3j8B3.mjs → EventListing.client-DmFAX7Vb.mjs} +3 -4
  103. package/dist/client/{LeafletStaticMap-RjtGzDQT.mjs → LeafletStaticMap-BAqXdfhq.mjs} +1 -1
  104. package/dist/client/ThemedButton-BwNFVwi4.mjs +412 -0
  105. package/dist/client/{accordion-DOmnDoyg.mjs → accordion-DRhMdkbd.mjs} +1 -1
  106. package/dist/client/{bookingForm-C0vk7pgS.mjs → bookingForm-iJ_nCsNF.mjs} +26 -32
  107. package/dist/client/bookings.mjs +201 -118
  108. package/dist/client/{carousel-BZJ7pno3.mjs → carousel-D8zuffZr.mjs} +2 -2
  109. package/dist/client/{carousel.client-DQTjCVQT.mjs → carousel.client-jahpU9Vz.mjs} +1 -1
  110. package/dist/client/{cart-CaeVAHJl.mjs → cart-DeMGJViN.mjs} +3 -3
  111. package/dist/client/{checkout-7wmoNDtG.mjs → checkout-DXc06Km2.mjs} +3 -3
  112. package/dist/client/{checkoutUrls-FL6lRkrt.mjs → checkoutUrls-CW3-78uu.mjs} +1 -1
  113. package/dist/client/client.mjs +2271 -1983
  114. package/dist/client/{colorStyles-3013aRAY.mjs → colorStyles-CuJBiS-1.mjs} +16 -4
  115. package/dist/client/{context-BOimxE3U.mjs → context-CDLCfDep.mjs} +24 -8
  116. package/dist/client/{dates-BnzVksi4.mjs → dates-ClFx7Epy.mjs} +2 -2
  117. package/dist/client/{eventCalendar-l-fpaslC.mjs → eventCalendar-BaGpnOGN.mjs} +39 -50
  118. package/dist/client/{eventCombined-DGGvssK6.mjs → eventCombined-ywONOx2m.mjs} +5 -4
  119. package/dist/client/{eventDetails-DRiCm_hL.mjs → eventDetails-B2LlOTYY.mjs} +4 -4
  120. package/dist/client/{eventListing-dph8loYX.mjs → eventListing-CMgxWpqP.mjs} +5 -4
  121. package/dist/client/{eventRegistration-ClBohmbY.mjs → eventRegistration-BarLDNHR.mjs} +83 -68
  122. package/dist/client/{form-BLVVAnd3.mjs → form-BjqKaBJ7.mjs} +9 -10
  123. package/dist/client/{headerSection-DHy4C8Ix.mjs → headerSection-CP4XDwz1.mjs} +23 -30
  124. package/dist/client/hooks.mjs +257 -63
  125. package/dist/client/{locationMap-6HuS28ck.mjs → locationMap-C5gW-d-w.mjs} +9 -10
  126. package/dist/client/{media-DHpfFwd3.mjs → media-BtJ37tzS.mjs} +1 -1
  127. package/dist/client/{newsletterForm-xOdcOhZP.mjs → newsletterForm-afXlVSA0.mjs} +8 -9
  128. package/dist/client/{pricing-ChinRYFt.mjs → pricing-Bl1CAl28.mjs} +1 -1
  129. package/dist/client/{productDetail-0chA5gbK.mjs → productDetail-CvQ3jWQe.mjs} +3 -3
  130. package/dist/client/{productList-OoINA0h1.mjs → productList-U874PGO7.mjs} +3 -3
  131. package/dist/client/{propsDecoder-CIZ-hbIG.mjs → propsDecoder-DPXtCZWP.mjs} +87 -29
  132. package/dist/client/rendering/client.mjs +1891 -1740
  133. package/dist/client/rendering/islands.mjs +19 -19
  134. package/dist/client/rendering.mjs +2225 -1913
  135. package/dist/client/{routeIslandApiConfig-UNsfPcYq.mjs → routeIslandApiConfig-NGYiUWXu.mjs} +8 -1
  136. package/dist/client/{scrollToBlock-BPZl0gPZ.mjs → scrollToBlock-0-C3DVhK.mjs} +1 -1
  137. package/dist/client/{shop-CLJFqNIq.mjs → shop-BXjXhM9P.mjs} +45 -58
  138. package/dist/client/{shop-commerce-PpANg5wB.mjs → shop-commerce-BZ6UlWJ7.mjs} +42 -55
  139. package/dist/client/{shop-commerce-store-TA_Kz2ku.mjs → shop-commerce-store-DlSBXb3D.mjs} +1 -1
  140. package/dist/client/{shopShared-DzcFcA5g.mjs → shopShared-kkEOiLPA.mjs} +6 -5
  141. package/dist/client/{useEventFilters-CFU21QZo.mjs → useEventFilters-zvnnE1ro.mjs} +66 -355
  142. package/dist/preview-next/client/runtime.mjs +3 -3
  143. package/dist/preview-next/editor-chrome.css +8 -0
  144. package/dist/{sdk-runtime-CDKl0Fr7.mjs → sdk-runtime-DFJlQt3q.mjs} +1 -1
  145. package/dist/{separator-BTp96X32.mjs → separator-o8GHb1xh.mjs} +1 -1
  146. package/dist/server/components.mjs +828 -623
  147. package/dist/server/config-validation.mjs +257 -63
  148. package/dist/server/config.mjs +257 -63
  149. package/dist/server/data.mjs +257 -63
  150. package/dist/server/index.mjs +9 -5
  151. package/dist/server/navigation.mjs +28 -1
  152. package/dist/server/next.mjs +14129 -13947
  153. package/dist/server/page-converter.mjs +110 -59
  154. package/dist/server/prebuild.mjs +1 -1
  155. package/dist/server/rendering/server.mjs +832 -624
  156. package/dist/server/rendering.mjs +830 -624
  157. package/dist/server/routing.mjs +294 -69
  158. package/dist/server/server.mjs +266 -68
  159. package/dist/server/theme-bridge.mjs +40 -1
  160. package/dist/styles/index.css +6 -0
  161. package/package.json +1 -1
@@ -5060,6 +5060,36 @@ function normalizedReference(value) {
5060
5060
  return normalized.length > 0 ? normalized : null;
5061
5061
  }
5062
5062
  //#endregion
5063
+ //#region ../theme-core/src/surfaces/logoVariant.ts
5064
+ /** Concrete hex behind a plain, opaque palette token, or null otherwise. */
5065
+ function opaquePaletteHexForToken(expandedPalette, token) {
5066
+ if (!token) return null;
5067
+ const parts = parseColorTokenParts(token);
5068
+ if (parts.kind !== "token" || parts.opacityPercent !== null) return null;
5069
+ return expandedPalette[parts.token] ?? null;
5070
+ }
5071
+ /**
5072
+ * Tone of the surface a foreground token was resolved for.
5073
+ *
5074
+ * A token with opacity has no known underlay to composite against, and a raw
5075
+ * or unrecognised token has no palette hex, so both are `unknown` rather than
5076
+ * a guess.
5077
+ */
5078
+ function surfaceToneFromForegroundToken(expandedPalette, foregroundToken) {
5079
+ const hex = opaquePaletteHexForToken(expandedPalette, foregroundToken);
5080
+ if (!hex) return "unknown";
5081
+ return featuresFromHex(hex).Y >= .5 ? "dark" : "light";
5082
+ }
5083
+ /**
5084
+ * The logo to draw on a surface of the given tone. A missing variant falls
5085
+ * back to the other one, and an unknown tone uses the light-backgrounds logo,
5086
+ * which is what every site rendered before variants existed.
5087
+ */
5088
+ function selectLogoVariant(tone, variants) {
5089
+ const { forLightBackgrounds, forDarkBackgrounds } = variants;
5090
+ return tone === "dark" ? forDarkBackgrounds ?? forLightBackgrounds : forLightBackgrounds ?? forDarkBackgrounds;
5091
+ }
5092
+ //#endregion
5063
5093
  //#region ../theme-core/src/utils/colorStyles.ts
5064
5094
  const COLOR_VAR_PREFIX = "--tb-";
5065
5095
  function parseToken(source) {
@@ -5126,16 +5156,28 @@ function backgroundColorStyle(token) {
5126
5156
  return { backgroundColor: rgbColorValue(token) };
5127
5157
  }
5128
5158
  /**
5159
+ * Converts a text color token to a CSS color value that follows the enclosing
5160
+ * surface. The semantic text tokens (`text`, `heading`, `mutedText`) resolve
5161
+ * to the surface foreground variables, so text adapts when a section's
5162
+ * background changes; any other token is a fixed theme color.
5163
+ *
5164
+ * @param token - Theme color token
5165
+ * @returns CSS color value
5166
+ */
5167
+ function textColorValue(token) {
5168
+ const parsed = parseToken(token);
5169
+ const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
5170
+ if (!surfaceRole) return rgbColorValue(token);
5171
+ return parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent);
5172
+ }
5173
+ /**
5129
5174
  * Creates a text color style object from a theme token.
5130
5175
  *
5131
5176
  * @param token - Theme color token
5132
5177
  * @returns CSSProperties with color
5133
5178
  */
5134
5179
  function textColorStyle(token) {
5135
- const parsed = parseToken(token);
5136
- const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
5137
- if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
5138
- return { color: rgbColorValue(token) };
5180
+ return { color: textColorValue(token) };
5139
5181
  }
5140
5182
  /**
5141
5183
  * Creates a border color style object from a theme token.
@@ -5249,9 +5291,7 @@ function navRow(opts) {
5249
5291
  rel: { $bind: { from: `${childItemName}.rel` } },
5250
5292
  "data-active": { $bind: { from: `${childItemName}.active` } }
5251
5293
  }, [text({ as: "span" }, bind(`${childItemName}.label`))], repeat(`${itemName}.children`, childItemName));
5252
- const dropdown = el("div", { className: "nav-dropdown rb-relative" }, [button({
5253
- type: "button",
5254
- variantId: "",
5294
+ const dropdown = el("div", { className: "nav-dropdown rb-relative" }, [el("headerControl", {
5255
5295
  className: prependClassName("nav-dropdown-trigger", linkClassName),
5256
5296
  "aria-haspopup": "menu",
5257
5297
  "aria-expanded": "false",
@@ -5319,9 +5359,7 @@ function navColumn(opts) {
5319
5359
  const dropdown = el("div", {
5320
5360
  className: "nav-mobile-dropdown",
5321
5361
  "data-nav-mobile-dropdown": "true"
5322
- }, [button({
5323
- type: "button",
5324
- variantId: "",
5362
+ }, [el("headerControl", {
5325
5363
  className: triggerClassName,
5326
5364
  "aria-expanded": "false",
5327
5365
  "aria-controls": childrenId,
@@ -13874,7 +13912,7 @@ function parseThemeForPersistence(value) {
13874
13912
  * overriding the twelve styles that deliberately declare none. Whether a button
13875
13913
  * carries a trailing affordance is the style's decision; the only caller that
13876
13914
  * legitimately opts out is the authored-button renderer, which reaches it
13877
- * through `themeButtonClassNameWithTrailingIcon`.
13915
+ * through `themeButtonExtraClassesWithTrailingIcon`.
13878
13916
  */
13879
13917
  const AFFORDANCE_SUPPRESS_CLASS = "rb-affordance-off";
13880
13918
  //#endregion
@@ -13903,18 +13941,10 @@ function themeButtonSelector(variant, size) {
13903
13941
  if (!size) return baseSelector;
13904
13942
  return `${baseSelector}.${themeButtonSizeClassName(size)}`;
13905
13943
  }
13906
- function themeButtonClassName(spec) {
13907
- return [
13908
- ...themeButtonVariantClassNames(spec.variant),
13909
- themeButtonSizeClassName(spec.size),
13910
- spec.extraClassName
13911
- ].filter(Boolean).join(" ");
13912
- }
13913
13944
  /**
13914
- * Button classes for an authored button that renders its own trailing icon.
13945
+ * Extra classes for an authored button that renders its own trailing icon.
13915
13946
  *
13916
- * A separate function rather than a flag on `themeButtonClassName`, because
13917
- * there is exactly one caller and it should stay visible in a diff. The name
13947
+ * This intent-named function has exactly one caller. The name
13918
13948
  * states what the caller knows to be true of its own markup — that it renders a
13919
13949
  * trailing icon — rather than what the theme does about it. The consequence is
13920
13950
  * the theme's to decide and to change; a caller naming the consequence would be
@@ -13925,11 +13955,8 @@ function themeButtonClassName(spec) {
13925
13955
  * affordance is declared by the button style, and a block overriding that is the
13926
13956
  * defect this replaced.
13927
13957
  */
13928
- function themeButtonClassNameWithTrailingIcon(spec) {
13929
- return themeButtonClassName({
13930
- ...spec,
13931
- extraClassName: [spec.extraClassName, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ")
13932
- });
13958
+ function themeButtonExtraClassesWithTrailingIcon() {
13959
+ return AFFORDANCE_SUPPRESS_CLASS;
13933
13960
  }
13934
13961
  //#endregion
13935
13962
  //#region ../theme-core/src/interactive/generateBaseCSS.ts
@@ -24822,6 +24849,47 @@ const layoutTransforms = [
24822
24849
  footerLogoMediaClassTransform,
24823
24850
  footerLogoTextVisibleTransform
24824
24851
  ];
24852
+ const chromeLogoSchema = z$1.object({ surface: z$1.enum([
24853
+ "header-root",
24854
+ "header-mobile-panel",
24855
+ "footer-root"
24856
+ ]) });
24857
+ /** The brand foreground shares the logo's surface; navigation may own a separate capsule. */
24858
+ function chromeSurfaceTextToken(surface, theme, palette) {
24859
+ switch (surface) {
24860
+ case "header-root": {
24861
+ const header = theme.header;
24862
+ const foreground = resolveHeaderRootForeground(header, palette, resolveHeaderVisualStyles(header).isTransparent);
24863
+ return foreground.kind === "known" ? foreground.roles.text : resolveHeaderLeafTextColor(header);
24864
+ }
24865
+ case "header-mobile-panel": return theme.header?.dropdownStyle?.textColor ?? "text";
24866
+ case "footer-root": {
24867
+ const foreground = resolveFooterRootForeground(theme.footer, palette);
24868
+ return foreground.kind === "known" ? foreground.roles.text : void 0;
24869
+ }
24870
+ }
24871
+ }
24872
+ function readChromeTheme(viewModel) {
24873
+ return asPartialObject(asPartialObject(viewModel?.["$root"])?.theme) ?? {};
24874
+ }
24875
+ function resolveChromeSurfaceTone(surface, context) {
24876
+ return surfaceToneFromForegroundToken(context.theme.palette, chromeSurfaceTextToken(surface, readChromeTheme(context.viewModel), context.theme.palette));
24877
+ }
24878
+ const chromeLogoTransforms = [{
24879
+ id: "layout.chromeLogo",
24880
+ kind: "formatter",
24881
+ summary: "Select the light- or dark-background site logo for a header or footer surface",
24882
+ schema: chromeLogoSchema,
24883
+ run: (value, options, context) => {
24884
+ const content = asPartialObject(value);
24885
+ const variants = asPartialObject(content?.logoVariants);
24886
+ if (!variants) return content?.logo ?? null;
24887
+ return selectLogoVariant(resolveChromeSurfaceTone(options.surface, context), {
24888
+ forLightBackgrounds: variants.forLightBackgrounds ?? null,
24889
+ forDarkBackgrounds: variants.forDarkBackgrounds ?? null
24890
+ });
24891
+ }
24892
+ }];
24825
24893
  //#endregion
24826
24894
  //#region ../blocks/src/system/transforms/registry/ui.ts
24827
24895
  const joinClasses$2 = (parts) => parts.filter((part) => typeof part === "string" && part.trim().length > 0).join(" ").replace(/\s+/g, " ").trim();
@@ -27196,6 +27264,33 @@ function normalizeEventCalendarDisplayMode$1(input) {
27196
27264
  if (isEventCalendarDisplayMode(input.variant)) return input.variant;
27197
27265
  return isEventCalendarDisplayMode(input.displayMode) ? input.displayMode : void 0;
27198
27266
  }
27267
+ /** One closed authority for the projections required by each rendered mode. */
27268
+ function resolveEventCalendarReadPlan(input) {
27269
+ const mode = normalizeEventCalendarDisplayMode$1(input) ?? "combined";
27270
+ switch (mode) {
27271
+ case "combined": return {
27272
+ mode,
27273
+ jobs: "both",
27274
+ readProfile: "listing-card"
27275
+ };
27276
+ case "list": return {
27277
+ mode,
27278
+ jobs: "list",
27279
+ readProfile: "listing-card"
27280
+ };
27281
+ case "calendar": return {
27282
+ mode,
27283
+ jobs: "calendar",
27284
+ readProfile: "listing-card"
27285
+ };
27286
+ case "timetable":
27287
+ case "week-board": return {
27288
+ mode,
27289
+ jobs: "calendar",
27290
+ readProfile: "timetable"
27291
+ };
27292
+ }
27293
+ }
27199
27294
  function isEventCalendarDefaultView(value) {
27200
27295
  return typeof value === "string" && eventCalendarDefaultViewValues.includes(value);
27201
27296
  }
@@ -28253,8 +28348,7 @@ function normalizeEventStaffMemberId(value) {
28253
28348
  //#endregion
28254
28349
  //#region ../blocks/src/system/blocks/events/shared/calendarWindow.ts
28255
28350
  function resolveCalendarReadProfile(content) {
28256
- const mode = normalizeEventCalendarDisplayMode$1(content);
28257
- return mode === "timetable" || mode === "week-board" ? "timetable" : "listing-card";
28351
+ return resolveEventCalendarReadPlan(content).readProfile;
28258
28352
  }
28259
28353
  /** Runtime picker sentinels and bound loader IDs must describe the same query. */
28260
28354
  function normalizeCalendarFilterId(value) {
@@ -28398,8 +28492,8 @@ const defaultTransforms = createTransformRegistry([
28398
28492
  summary: "Choose the read projection required by the calendar display mode",
28399
28493
  schema: z$1.object({ job: z$1.enum(["list", "calendar"]) }),
28400
28494
  run(value, options) {
28401
- const mode = normalizeEventCalendarDisplayMode$1(asPartialObject(value) ?? {}) ?? "combined";
28402
- return options.job === "calendar" ? mode !== "list" : mode === "list" || mode === "combined";
28495
+ const plan = resolveEventCalendarReadPlan(asPartialObject(value) ?? {});
28496
+ return plan.jobs === "both" || plan.jobs === options.job;
28403
28497
  }
28404
28498
  },
28405
28499
  {
@@ -28412,6 +28506,7 @@ const defaultTransforms = createTransformRegistry([
28412
28506
  },
28413
28507
  ...formattingTransforms,
28414
28508
  ...layoutTransforms,
28509
+ ...chromeLogoTransforms,
28415
28510
  ...uiTransforms,
28416
28511
  ...mediaTransforms,
28417
28512
  ...backgroundTransforms,
@@ -28567,12 +28662,12 @@ function Grid({ as: Comp = "div", cols, userColumns, gap = "md", className, styl
28567
28662
  }
28568
28663
  //#endregion
28569
28664
  //#region ../blocks/src/system/runtime/nodes/layout.tsx
28570
- const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Section, { ...props });
28571
- const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
28572
- const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
28573
- const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
28574
- const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
28575
- const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
28665
+ const SectionNode = (props) => /* @__PURE__ */ jsx(Section, { ...props });
28666
+ const StackNode = (props) => /* @__PURE__ */ jsx(Stack, { ...props });
28667
+ const InlineNode = (props) => /* @__PURE__ */ jsx(Inline, { ...props });
28668
+ const GridNode = (props) => /* @__PURE__ */ jsx(Grid, { ...props });
28669
+ const DivNode = (props) => /* @__PURE__ */ jsx("div", { ...props });
28670
+ const FigureNode = (props) => /* @__PURE__ */ jsx("figure", { ...props });
28576
28671
  //#endregion
28577
28672
  //#region ../path-utils/src/index.ts
28578
28673
  const PATH_SEPARATOR_REGEX$1 = /\./g;
@@ -28810,6 +28905,234 @@ function Text$1({ as: Comp = "span", children, className = "", path, maxLength:
28810
28905
  });
28811
28906
  }
28812
28907
  //#endregion
28908
+ //#region ../logger/src/sanitize.ts
28909
+ const DEFAULT_MAX_STRING_LENGTH = 2e3;
28910
+ const STRUCTURED_KEYS = /* @__PURE__ */ new Set([
28911
+ "source",
28912
+ "service",
28913
+ "function",
28914
+ "environment",
28915
+ "deployment",
28916
+ "region",
28917
+ "release",
28918
+ "requestId",
28919
+ "correlationId",
28920
+ "method",
28921
+ "route",
28922
+ "path",
28923
+ "search",
28924
+ "host",
28925
+ "url",
28926
+ "userId",
28927
+ "adminUserId",
28928
+ "orgId",
28929
+ "siteId",
28930
+ "siteDomainId",
28931
+ "domainOperationSubsystem",
28932
+ "domainOperation",
28933
+ "domainOperationStage",
28934
+ "domainOperationOutcome",
28935
+ "domainOperationDomain",
28936
+ "domainOperationProvider",
28937
+ "domainOperationError",
28938
+ "domainOperationMetadata",
28939
+ "durationMs",
28940
+ "duration",
28941
+ "status",
28942
+ "statusCode",
28943
+ "statusText",
28944
+ "errorDetails",
28945
+ "errorName",
28946
+ "errorMessage",
28947
+ "errorStack",
28948
+ "context"
28949
+ ]);
28950
+ function truncate(input, maxLength) {
28951
+ if (input.length <= maxLength) return input;
28952
+ return input.slice(0, maxLength) + "…";
28953
+ }
28954
+ function safeStringify(value, maxLength) {
28955
+ try {
28956
+ return truncate(JSON.stringify(value), maxLength);
28957
+ } catch {
28958
+ return truncate(String(value), maxLength);
28959
+ }
28960
+ }
28961
+ function toScalar(value, maxLength) {
28962
+ if (value == null) return null;
28963
+ if (typeof value === "string") return truncate(value, maxLength);
28964
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
28965
+ if (typeof value === "boolean") return value;
28966
+ if (value instanceof Date) return value.toISOString();
28967
+ if (value instanceof Error) return truncate(`${value.name}: ${value.message}`, maxLength);
28968
+ return safeStringify(value, maxLength);
28969
+ }
28970
+ function sanitizeV2(fields, maxStringLength) {
28971
+ const allowed = {};
28972
+ const extra = {};
28973
+ for (const [key, value] of Object.entries(fields)) {
28974
+ if (value === void 0) continue;
28975
+ if (STRUCTURED_KEYS.has(key)) {
28976
+ allowed[key] = toScalar(value, maxStringLength);
28977
+ continue;
28978
+ }
28979
+ extra[key] = value;
28980
+ }
28981
+ if (Object.keys(extra).length > 0) allowed.context = safeStringify(extra, maxStringLength);
28982
+ return allowed;
28983
+ }
28984
+ function sanitizeLogFields(fields, options) {
28985
+ if (fields === void 0 || Object.keys(fields).length === 0) return void 0;
28986
+ return sanitizeV2(fields, options?.maxStringLength ?? DEFAULT_MAX_STRING_LENGTH);
28987
+ }
28988
+ //#endregion
28989
+ //#region ../logger/src/console.ts
28990
+ function formatLog(level, message, fields) {
28991
+ const entry = {
28992
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
28993
+ level,
28994
+ message,
28995
+ ...sanitizeLogFields(fields)
28996
+ };
28997
+ return JSON.stringify(entry);
28998
+ }
28999
+ function createLogger(baseFields = {}) {
29000
+ return {
29001
+ debug: (msg, fields) => console.debug(formatLog("debug", msg, {
29002
+ ...baseFields,
29003
+ ...fields
29004
+ })),
29005
+ info: (msg, fields) => console.info(formatLog("info", msg, {
29006
+ ...baseFields,
29007
+ ...fields
29008
+ })),
29009
+ warn: (msg, fields) => console.warn(formatLog("warn", msg, {
29010
+ ...baseFields,
29011
+ ...fields
29012
+ })),
29013
+ error: (msg, fields) => console.error(formatLog("error", msg, {
29014
+ ...baseFields,
29015
+ ...fields
29016
+ })),
29017
+ withFields: (fields) => createLogger({
29018
+ ...baseFields,
29019
+ ...fields
29020
+ })
29021
+ };
29022
+ }
29023
+ const logger = createLogger();
29024
+ //#endregion
29025
+ //#region ../blocks/src/system/runtime/nodes/richText-coerce.ts
29026
+ function parseRichTextDoc(value) {
29027
+ const parsed = RichTextDocSchema.safeParse(value);
29028
+ if (parsed.success) return {
29029
+ kind: "valid",
29030
+ doc: parsed.data
29031
+ };
29032
+ return {
29033
+ kind: "invalid",
29034
+ issues: parsed.error.issues.map((issue) => ({
29035
+ path: issue.path.map((segment) => String(segment)),
29036
+ message: issue.message
29037
+ }))
29038
+ };
29039
+ }
29040
+ function coerceRichTextDoc(value, source) {
29041
+ const parsed = parseRichTextDoc(value);
29042
+ if (parsed.kind === "valid") return parsed.doc;
29043
+ if (value !== null && value !== void 0) logger.warn("blocks:rich-text:invalid-document", {
29044
+ source,
29045
+ issues: parsed.issues.slice(0, 3)
29046
+ });
29047
+ return null;
29048
+ }
29049
+ //#endregion
29050
+ //#region ../blocks/src/system/runtime/nodes/renderInlineText.tsx
29051
+ function renderInlineText(value) {
29052
+ return value.map((run, index) => renderRun(run, index));
29053
+ }
29054
+ function renderRun(run, key) {
29055
+ return (run.marks ?? []).reduceRight((child, mark, index) => renderMark(mark, `${String(key)}-${index}`, child), run.text);
29056
+ }
29057
+ function renderMark(mark, key, child) {
29058
+ switch (mark.kind) {
29059
+ case "strong": return /* @__PURE__ */ jsx("strong", { children: child }, key);
29060
+ case "emphasis": return /* @__PURE__ */ jsx("em", { children: child }, key);
29061
+ case "accent": return /* @__PURE__ */ jsx("span", {
29062
+ className: `rb-inline-text-accent rb-inline-text-accent-${mark.tone}`,
29063
+ children: child
29064
+ }, key);
29065
+ case "highlight": return /* @__PURE__ */ jsx("span", {
29066
+ className: `rb-inline-text-highlight rb-inline-text-highlight-${mark.tone}`,
29067
+ children: child
29068
+ }, key);
29069
+ }
29070
+ }
29071
+ //#endregion
29072
+ //#region ../blocks/src/system/runtime/nodes/spinner.tsx
29073
+ function resolveColorStyle(color) {
29074
+ switch (color) {
29075
+ case void 0: return;
29076
+ case "inherit": return { color: "inherit" };
29077
+ case "foreground": return { color: "rgb(var(--tb-foreground))" };
29078
+ case "text": return { color: "rgb(var(--tb-text))" };
29079
+ default: return;
29080
+ }
29081
+ }
29082
+ function SpinnerNode({ className, size = "md", color, strokeWidth = 3, srLabel, style, ...rest }) {
29083
+ const hasExplicitAriaLabel = typeof rest["aria-label"] === "string" && rest["aria-label"].trim().length > 0;
29084
+ const accessibilityProps = srLabel ? {
29085
+ role: "status",
29086
+ "aria-live": "polite"
29087
+ } : hasExplicitAriaLabel ? {} : { "aria-hidden": true };
29088
+ const trackStroke = color === "inherit" ? "currentColor" : "var(--rb-spinner-track-color)";
29089
+ const trackOpacity = color === "inherit" ? .25 : 1;
29090
+ return /* @__PURE__ */ jsxs("span", {
29091
+ ...accessibilityProps,
29092
+ className: clsx("rb-spinner", size ? `rb-spinner--${size}` : null, color === "inherit" ? "rb-spinner--inherit" : null, className),
29093
+ style: {
29094
+ ...resolveColorStyle(color),
29095
+ ...style ?? {}
29096
+ },
29097
+ ...rest,
29098
+ children: [/* @__PURE__ */ jsxs("svg", {
29099
+ viewBox: "0 0 24 24",
29100
+ fill: "none",
29101
+ "aria-hidden": "true",
29102
+ children: [/* @__PURE__ */ jsx("circle", {
29103
+ cx: "12",
29104
+ cy: "12",
29105
+ r: "10",
29106
+ stroke: trackStroke,
29107
+ strokeWidth,
29108
+ opacity: trackOpacity
29109
+ }), /* @__PURE__ */ jsx("path", {
29110
+ d: "M12 2a10 10 0 0 1 10 10",
29111
+ stroke: "currentColor",
29112
+ strokeWidth,
29113
+ strokeLinecap: "round"
29114
+ })]
29115
+ }), srLabel ? /* @__PURE__ */ jsx("span", {
29116
+ className: "rb-sr-only",
29117
+ children: srLabel
29118
+ }) : null]
29119
+ });
29120
+ }
29121
+ //#endregion
29122
+ //#region ../blocks/src/system/runtime/nodes/buttonAffordance.ts
29123
+ function normalize(value) {
29124
+ const trimmed = typeof value === "string" ? value.trim() : "";
29125
+ return trimmed.length > 0 ? trimmed : null;
29126
+ }
29127
+ /**
29128
+ * Resolve the node-authored trailing affordance, or `null` when no icon exists.
29129
+ */
29130
+ function resolveButtonAffordance(input) {
29131
+ const nodeIcon = normalize(input.trailingIcon);
29132
+ if (nodeIcon) return { iconId: nodeIcon };
29133
+ return null;
29134
+ }
29135
+ //#endregion
28813
29136
  //#region ../blocks/src/system/icons/svg.tsx
28814
29137
  function createIcon(displayName, children) {
28815
29138
  const Icon = ({ size = "1em", strokeWidth = 2, title, className, focusable = false, role, ...props }) => /* @__PURE__ */ jsxs("svg", {
@@ -29912,186 +30235,105 @@ function getIconComponent(name) {
29912
30235
  return getCtaIconComponent(name) ?? getSemanticIconComponent(name) ?? getSocialIconComponent(name);
29913
30236
  }
29914
30237
  //#endregion
29915
- //#region ../blocks/src/system/runtime/nodes/buttonAffordance.ts
29916
- function normalize(value) {
29917
- const trimmed = typeof value === "string" ? value.trim() : "";
29918
- return trimmed.length > 0 ? trimmed : null;
29919
- }
29920
- /**
29921
- * Resolve the node-authored trailing affordance, or `null` when no icon exists.
29922
- */
29923
- function resolveButtonAffordance(input) {
29924
- const nodeIcon = normalize(input.trailingIcon);
29925
- if (nodeIcon) return { iconId: nodeIcon };
29926
- return null;
29927
- }
29928
- //#endregion
29929
- //#region ../logger/src/sanitize.ts
29930
- const DEFAULT_MAX_STRING_LENGTH = 2e3;
29931
- const STRUCTURED_KEYS = /* @__PURE__ */ new Set([
29932
- "source",
29933
- "service",
29934
- "function",
29935
- "environment",
29936
- "deployment",
29937
- "region",
29938
- "release",
29939
- "requestId",
29940
- "correlationId",
29941
- "method",
29942
- "route",
29943
- "path",
29944
- "search",
29945
- "host",
29946
- "url",
29947
- "userId",
29948
- "adminUserId",
29949
- "orgId",
29950
- "siteId",
29951
- "siteDomainId",
29952
- "domainOperationSubsystem",
29953
- "domainOperation",
29954
- "domainOperationStage",
29955
- "domainOperationOutcome",
29956
- "domainOperationDomain",
29957
- "domainOperationProvider",
29958
- "domainOperationError",
29959
- "domainOperationMetadata",
29960
- "durationMs",
29961
- "duration",
29962
- "status",
29963
- "statusCode",
29964
- "statusText",
29965
- "errorDetails",
29966
- "errorName",
29967
- "errorMessage",
29968
- "errorStack",
29969
- "context"
29970
- ]);
29971
- function truncate(input, maxLength) {
29972
- if (input.length <= maxLength) return input;
29973
- return input.slice(0, maxLength) + "…";
29974
- }
29975
- function safeStringify(value, maxLength) {
29976
- try {
29977
- return truncate(JSON.stringify(value), maxLength);
29978
- } catch {
29979
- return truncate(String(value), maxLength);
29980
- }
29981
- }
29982
- function toScalar(value, maxLength) {
29983
- if (value == null) return null;
29984
- if (typeof value === "string") return truncate(value, maxLength);
29985
- if (typeof value === "number") return Number.isFinite(value) ? value : null;
29986
- if (typeof value === "boolean") return value;
29987
- if (value instanceof Date) return value.toISOString();
29988
- if (value instanceof Error) return truncate(`${value.name}: ${value.message}`, maxLength);
29989
- return safeStringify(value, maxLength);
29990
- }
29991
- function sanitizeV2(fields, maxStringLength) {
29992
- const allowed = {};
29993
- const extra = {};
29994
- for (const [key, value] of Object.entries(fields)) {
29995
- if (value === void 0) continue;
29996
- if (STRUCTURED_KEYS.has(key)) {
29997
- allowed[key] = toScalar(value, maxStringLength);
29998
- continue;
29999
- }
30000
- extra[key] = value;
30001
- }
30002
- if (Object.keys(extra).length > 0) allowed.context = safeStringify(extra, maxStringLength);
30003
- return allowed;
30004
- }
30005
- function sanitizeLogFields(fields, options) {
30006
- if (fields === void 0 || Object.keys(fields).length === 0) return void 0;
30007
- return sanitizeV2(fields, options?.maxStringLength ?? DEFAULT_MAX_STRING_LENGTH);
30238
+ //#region ../blocks/src/system/runtime/shared/components/ThemedButton.tsx
30239
+ function themedButtonClasses(variant, size, extraClassName) {
30240
+ return [
30241
+ ...themeButtonVariantClassNames(variant),
30242
+ themeButtonSizeClassName(size),
30243
+ extraClassName
30244
+ ].filter(Boolean).join(" ");
30008
30245
  }
30009
- //#endregion
30010
- //#region ../logger/src/console.ts
30011
- function formatLog(level, message, fields) {
30012
- const entry = {
30013
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
30014
- level,
30015
- message,
30016
- ...sanitizeLogFields(fields)
30017
- };
30018
- return JSON.stringify(entry);
30246
+ function ThemedButtonLabel(props) {
30247
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
30248
+ props.pending ? /* @__PURE__ */ jsx(SpinnerNode, {
30249
+ size: props.pending.spinnerSize ?? "sm",
30250
+ color: "inherit",
30251
+ className: props.pending.spinnerClassName ?? "rb-mr-2",
30252
+ srLabel: props.pending.srLabel
30253
+ }) : null,
30254
+ props.labelClassName ? /* @__PURE__ */ jsx("span", {
30255
+ className: props.labelClassName,
30256
+ children: props.pending?.label ?? props.label
30257
+ }) : props.pending?.label ?? props.label,
30258
+ props.screenReaderSuffix ? /* @__PURE__ */ jsx("span", {
30259
+ className: "rb-sr-only",
30260
+ children: props.screenReaderSuffix
30261
+ }) : null
30262
+ ] });
30263
+ return props.pending?.contentClassName ? /* @__PURE__ */ jsx("span", {
30264
+ className: props.pending.contentClassName,
30265
+ children: content
30266
+ }) : content;
30019
30267
  }
30020
- function createLogger(baseFields = {}) {
30021
- return {
30022
- debug: (msg, fields) => console.debug(formatLog("debug", msg, {
30023
- ...baseFields,
30024
- ...fields
30025
- })),
30026
- info: (msg, fields) => console.info(formatLog("info", msg, {
30027
- ...baseFields,
30028
- ...fields
30029
- })),
30030
- warn: (msg, fields) => console.warn(formatLog("warn", msg, {
30031
- ...baseFields,
30032
- ...fields
30033
- })),
30034
- error: (msg, fields) => console.error(formatLog("error", msg, {
30035
- ...baseFields,
30036
- ...fields
30037
- })),
30038
- withFields: (fields) => createLogger({
30039
- ...baseFields,
30040
- ...fields
30268
+ function ThemedButton({ variant, size, extraClassName, screenReaderSuffix, labelClassName, pending, label, ...buttonProps }) {
30269
+ return /* @__PURE__ */ jsx("button", {
30270
+ ...buttonProps,
30271
+ className: themedButtonClasses(variant, size, extraClassName),
30272
+ children: /* @__PURE__ */ jsx(ThemedButtonLabel, {
30273
+ label,
30274
+ pending,
30275
+ screenReaderSuffix,
30276
+ labelClassName
30041
30277
  })
30042
- };
30043
- }
30044
- const logger = createLogger();
30045
- //#endregion
30046
- //#region ../blocks/src/system/runtime/nodes/richText-coerce.ts
30047
- function parseRichTextDoc(value) {
30048
- const parsed = RichTextDocSchema.safeParse(value);
30049
- if (parsed.success) return {
30050
- kind: "valid",
30051
- doc: parsed.data
30052
- };
30053
- return {
30054
- kind: "invalid",
30055
- issues: parsed.error.issues.map((issue) => ({
30056
- path: issue.path.map((segment) => String(segment)),
30057
- message: issue.message
30058
- }))
30059
- };
30060
- }
30061
- function coerceRichTextDoc(value, source) {
30062
- const parsed = parseRichTextDoc(value);
30063
- if (parsed.kind === "valid") return parsed.doc;
30064
- if (value !== null && value !== void 0) logger.warn("blocks:rich-text:invalid-document", {
30065
- source,
30066
- issues: parsed.issues.slice(0, 3)
30067
30278
  });
30068
- return null;
30069
30279
  }
30070
- //#endregion
30071
- //#region ../blocks/src/system/runtime/nodes/renderInlineText.tsx
30072
- function renderInlineText(value) {
30073
- return value.map((run, index) => renderRun(run, index));
30280
+ function ThemedButtonLink({ variant, size, extraClassName, screenReaderSuffix, labelClassName, label, ...anchorProps }) {
30281
+ return /* @__PURE__ */ jsx("a", {
30282
+ ...anchorProps,
30283
+ className: themedButtonClasses(variant, size, extraClassName),
30284
+ children: /* @__PURE__ */ jsx(ThemedButtonLabel, {
30285
+ label,
30286
+ screenReaderSuffix,
30287
+ labelClassName
30288
+ })
30289
+ });
30074
30290
  }
30075
- function renderRun(run, key) {
30076
- return (run.marks ?? []).reduceRight((child, mark, index) => renderMark(mark, `${String(key)}-${index}`, child), run.text);
30291
+ /** Fixed semantic download affordance; callers cannot supply arbitrary icon children. */
30292
+ function ThemedDownloadLink({ variant, size, extraClassName, label, screenReaderSuffix, labelClassName, ...anchorProps }) {
30293
+ return /* @__PURE__ */ jsxs("a", {
30294
+ ...anchorProps,
30295
+ className: themedButtonClasses(variant, size, extraClassName),
30296
+ children: [/* @__PURE__ */ jsx(DownloadIcon, {
30297
+ "aria-hidden": "true",
30298
+ size: 24
30299
+ }), /* @__PURE__ */ jsx(ThemedButtonLabel, {
30300
+ label,
30301
+ screenReaderSuffix,
30302
+ labelClassName
30303
+ })]
30304
+ });
30077
30305
  }
30078
- function renderMark(mark, key, child) {
30079
- switch (mark.kind) {
30080
- case "strong": return /* @__PURE__ */ jsx("strong", { children: child }, key);
30081
- case "emphasis": return /* @__PURE__ */ jsx("em", { children: child }, key);
30082
- case "accent": return /* @__PURE__ */ jsx("span", {
30083
- className: `rb-inline-text-accent rb-inline-text-accent-${mark.tone}`,
30084
- children: child
30085
- }, key);
30086
- case "highlight": return /* @__PURE__ */ jsx("span", {
30087
- className: `rb-inline-text-highlight rb-inline-text-highlight-${mark.tone}`,
30088
- children: child
30089
- }, key);
30090
- }
30306
+ /** Boundary for authored button nodes and their registry-backed trailing icon. */
30307
+ function ThemedAuthoredButton({ label, href, variant, size, extraClassName, disabled, type = "button", target, rel, ariaLabel, dataTestId, trailingIcon, onClick }) {
30308
+ const affordance = resolveButtonAffordance({ trailingIcon });
30309
+ const Icon = affordance ? getIconComponent(affordance.iconId) : null;
30310
+ const className = variant ? themedButtonClasses(variant, size, Icon ? [extraClassName, themeButtonExtraClassesWithTrailingIcon()].filter(Boolean).join(" ") : extraClassName) : extraClassName ?? void 0;
30311
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [label, Icon ? /* @__PURE__ */ jsx(Icon, {
30312
+ "aria-hidden": true,
30313
+ className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
30314
+ }) : null] });
30315
+ return href ? /* @__PURE__ */ jsx("a", {
30316
+ href,
30317
+ target,
30318
+ rel,
30319
+ "aria-label": ariaLabel,
30320
+ "data-testid": dataTestId,
30321
+ className,
30322
+ onClick,
30323
+ children: content
30324
+ }) : /* @__PURE__ */ jsx("button", {
30325
+ type,
30326
+ disabled,
30327
+ "aria-label": ariaLabel,
30328
+ "data-testid": dataTestId,
30329
+ className,
30330
+ onClick,
30331
+ children: content
30332
+ });
30091
30333
  }
30092
30334
  //#endregion
30093
30335
  //#region ../blocks/src/system/runtime/nodes/basic.tsx
30094
- const TextNode = ({ value, children, blockId: _blockId, blockKind: _blockKind, blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, inlineTextFallbackPath, ...rest }) => {
30336
+ const TextNode = ({ value, children, blockContent, inlineTextFallbackPath, ...rest }) => {
30095
30337
  const inlineText = parseInlineTextFromUnknown(value);
30096
30338
  if (inlineText.ok && !isInlineTextEmpty(inlineText.value)) return /* @__PURE__ */ jsx(Text$1, {
30097
30339
  ...rest,
@@ -30112,34 +30354,21 @@ function readStringPath(source, path) {
30112
30354
  const value = getAtPath(source, path);
30113
30355
  return typeof value === "string" ? value : null;
30114
30356
  }
30115
- const RichTextNode = ({ value, blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...rest }) => {
30357
+ const RichTextNode = ({ value, blockKind, ...rest }) => {
30116
30358
  return /* @__PURE__ */ jsx(RichText$2, {
30117
- doc: coerceRichTextDoc(value, `block-runtime:${_blockKind ?? "unknown"}:${rest.path ?? "richText"}`) ?? void 0,
30359
+ doc: coerceRichTextDoc(value, `block-runtime:${blockKind ?? "unknown"}:${rest.path ?? "richText"}`) ?? void 0,
30118
30360
  ...rest
30119
30361
  });
30120
30362
  };
30121
- /**
30122
- * Render the resolved trailing affordance icon using the button's foreground.
30123
- */
30124
- function renderTrailingAffordanceIcon(affordance) {
30125
- if (!affordance) return null;
30126
- const Icon = getIconComponent(affordance.iconId);
30127
- if (!Icon) return null;
30128
- return /* @__PURE__ */ jsx(Icon, {
30129
- "aria-hidden": true,
30130
- className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
30131
- });
30132
- }
30133
30363
  function isMissingRequiredLink(linkRequired, resolvedHref) {
30134
30364
  return linkRequired && resolvedHref.length === 0;
30135
30365
  }
30136
- 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 }) => {
30366
+ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md", disabled, type = "button", target, rel, linkRequired = false, trailingIcon, onClick, className, ...rest }) => {
30137
30367
  const content = value ?? children;
30138
30368
  if (!content) {
30139
30369
  console.warn("[ButtonNode] No content to render - value and children are both empty");
30140
30370
  return null;
30141
30371
  }
30142
- const affordanceIcon = renderTrailingAffordanceIcon(resolveButtonAffordance({ trailingIcon }));
30143
30372
  const resolvedHref = typeof href === "string" ? href.trim() : "";
30144
30373
  if (isMissingRequiredLink(linkRequired, resolvedHref)) {
30145
30374
  if (process.env.NODE_ENV === "development") console.warn("[ButtonNode] Missing href for link-required button");
@@ -30150,28 +30379,23 @@ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md",
30150
30379
  console.error("[ButtonNode] Invalid button variant", { variantId });
30151
30380
  return null;
30152
30381
  }
30153
- const combinedClassName = resolvedVariantId ? (affordanceIcon ? themeButtonClassNameWithTrailingIcon : themeButtonClassName)({
30154
- variant: resolvedVariantId,
30155
- size,
30156
- extraClassName: className
30157
- }) : className;
30158
- if (resolvedHref) return /* @__PURE__ */ jsxs("a", {
30159
- href: resolvedHref,
30382
+ return /* @__PURE__ */ jsx(ThemedAuthoredButton, {
30383
+ label: content,
30384
+ href: resolvedHref || void 0,
30160
30385
  target,
30161
30386
  rel,
30162
- className: combinedClassName,
30163
- ...rest,
30164
- children: [content, affordanceIcon]
30165
- });
30166
- return /* @__PURE__ */ jsxs("button", {
30167
- type,
30387
+ variant: resolvedVariantId ?? null,
30388
+ size,
30168
30389
  disabled,
30169
- className: combinedClassName,
30170
- ...rest,
30171
- children: [content, affordanceIcon]
30390
+ type,
30391
+ trailingIcon,
30392
+ onClick,
30393
+ extraClassName: className,
30394
+ ariaLabel: rest["aria-label"],
30395
+ dataTestId: rest["data-testid"]
30172
30396
  });
30173
30397
  };
30174
- const LinkNode = ({ href, children, className, target, rel, linkRequired = false, blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...rest }) => {
30398
+ const LinkNode = ({ href, children, className, target, rel, linkRequired = false, ...rest }) => {
30175
30399
  if (!children) return null;
30176
30400
  const resolvedHref = typeof href === "string" ? href.trim() : "";
30177
30401
  if (resolvedHref.length === 0) {
@@ -30605,18 +30829,13 @@ function FileDownloadNode({ value, title, description, buttonLabel, buttonVarian
30605
30829
  })
30606
30830
  ]
30607
30831
  })]
30608
- }), /* @__PURE__ */ jsxs("a", {
30832
+ }), /* @__PURE__ */ jsx(ThemedDownloadLink, {
30609
30833
  href,
30610
30834
  download: filename,
30611
- className: themeButtonClassName({
30612
- variant,
30613
- size: "md",
30614
- extraClassName: "rb-inline-flex rb-shrink-0 rb-items-center rb-justify-center rb-gap-2"
30615
- }),
30616
- children: [/* @__PURE__ */ jsx(DownloadIcon, {
30617
- "aria-hidden": "true",
30618
- size: 24
30619
- }), label]
30835
+ variant,
30836
+ size: "md",
30837
+ extraClassName: "rb-inline-flex rb-shrink-0 rb-items-center rb-justify-center rb-gap-2",
30838
+ label
30620
30839
  })]
30621
30840
  })
30622
30841
  })
@@ -31196,53 +31415,19 @@ const HeaderSectionNode = ({ blockId, children, className, runtime, "data-previe
31196
31415
  };
31197
31416
  var header_section_server_default = markEditableSurfaceForwarding(HeaderSectionNode);
31198
31417
  //#endregion
31199
- //#region ../blocks/src/system/runtime/nodes/spinner.tsx
31200
- function resolveColorStyle(color) {
31201
- switch (color) {
31202
- case void 0: return;
31203
- case "inherit": return { color: "inherit" };
31204
- case "foreground": return { color: "rgb(var(--tb-foreground))" };
31205
- case "text": return { color: "rgb(var(--tb-text))" };
31206
- default: return;
31207
- }
31208
- }
31209
- function SpinnerNode({ className, size = "md", color, strokeWidth = 3, srLabel, style, ...rest }) {
31210
- const hasExplicitAriaLabel = typeof rest["aria-label"] === "string" && rest["aria-label"].trim().length > 0;
31211
- const accessibilityProps = srLabel ? {
31212
- role: "status",
31213
- "aria-live": "polite"
31214
- } : hasExplicitAriaLabel ? {} : { "aria-hidden": true };
31215
- const trackStroke = color === "inherit" ? "currentColor" : "var(--rb-spinner-track-color)";
31216
- const trackOpacity = color === "inherit" ? .25 : 1;
31217
- return /* @__PURE__ */ jsxs("span", {
31218
- ...accessibilityProps,
31219
- className: clsx("rb-spinner", size ? `rb-spinner--${size}` : null, color === "inherit" ? "rb-spinner--inherit" : null, className),
31220
- style: {
31221
- ...resolveColorStyle(color),
31222
- ...style ?? {}
31223
- },
31224
- ...rest,
31225
- children: [/* @__PURE__ */ jsxs("svg", {
31226
- viewBox: "0 0 24 24",
31227
- fill: "none",
31228
- "aria-hidden": "true",
31229
- children: [/* @__PURE__ */ jsx("circle", {
31230
- cx: "12",
31231
- cy: "12",
31232
- r: "10",
31233
- stroke: trackStroke,
31234
- strokeWidth,
31235
- opacity: trackOpacity
31236
- }), /* @__PURE__ */ jsx("path", {
31237
- d: "M12 2a10 10 0 0 1 10 10",
31238
- stroke: "currentColor",
31239
- strokeWidth,
31240
- strokeLinecap: "round"
31241
- })]
31242
- }), srLabel ? /* @__PURE__ */ jsx("span", {
31243
- className: "rb-sr-only",
31244
- children: srLabel
31245
- }) : null]
31418
+ //#region ../blocks/src/system/runtime/nodes/header-control.tsx
31419
+ /** System navigation controls retain their runtime hooks independently of authored CTAs. */
31420
+ 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 }) {
31421
+ return /* @__PURE__ */ jsx("button", {
31422
+ type: "button",
31423
+ className,
31424
+ "aria-label": label,
31425
+ "aria-expanded": expanded,
31426
+ "aria-controls": controls,
31427
+ "aria-haspopup": hasPopup,
31428
+ "data-nav-mobile-toggle": mobileToggle,
31429
+ "data-nav-mobile-trigger": mobileTrigger,
31430
+ children
31246
31431
  });
31247
31432
  }
31248
31433
  //#endregion
@@ -31554,11 +31739,6 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePa
31554
31739
  children: view.message
31555
31740
  })
31556
31741
  });
31557
- const actionClassName = themeButtonClassName({
31558
- variant: "secondary",
31559
- size: "sm",
31560
- extraClassName: "appointment-services-row-action"
31561
- });
31562
31742
  return /* @__PURE__ */ jsx("div", {
31563
31743
  className: `${rootClassName} rb-flex rb-flex-col`,
31564
31744
  "data-appointment-services-state": "populated",
@@ -31591,13 +31771,13 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePa
31591
31771
  className: "appointment-services-row-price rb-text-lg",
31592
31772
  children: row.priceLabel
31593
31773
  }) : null,
31594
- /* @__PURE__ */ jsxs("a", {
31595
- className: actionClassName,
31774
+ /* @__PURE__ */ jsx(ThemedButtonLink, {
31775
+ variant: "secondary",
31776
+ size: "sm",
31777
+ extraClassName: "appointment-services-row-action",
31596
31778
  href: row.href,
31597
- children: ["Check times", /* @__PURE__ */ jsxs("span", {
31598
- className: "rb-sr-only",
31599
- children: [" for ", row.title]
31600
- })]
31779
+ label: "Check times",
31780
+ screenReaderSuffix: ` for ${row.title}`
31601
31781
  })
31602
31782
  ]
31603
31783
  }, row.id))
@@ -33615,16 +33795,14 @@ function LocationMapView({ addressText, location, zoom, heightPx, showAddressTex
33615
33795
  style: textColorStyle("mutedText"),
33616
33796
  children: addressText
33617
33797
  }) : null,
33618
- showDirections && directionsUrl ? /* @__PURE__ */ jsx("a", {
33798
+ showDirections && directionsUrl ? /* @__PURE__ */ jsx(ThemedButtonLink, {
33619
33799
  href: directionsUrl,
33620
33800
  target: "_blank",
33621
33801
  rel: "noreferrer",
33622
- className: themeButtonClassName({
33623
- variant: "ghost",
33624
- size: "sm",
33625
- extraClassName: "rb-w-fit"
33626
- }),
33627
- children: directionsLabel
33802
+ variant: "ghost",
33803
+ size: "sm",
33804
+ extraClassName: "rb-w-fit",
33805
+ label: directionsLabel
33628
33806
  }) : null
33629
33807
  ]
33630
33808
  });
@@ -33773,10 +33951,6 @@ const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", but
33773
33951
  const formattedTime = `${formatTime(event.startsAt, { timeZone })} - ${formatTime(event.endsAt, { timeZone })}`;
33774
33952
  const cta = resolveEventCta(event, buttonText);
33775
33953
  const cardClass = boxStyleClassNames({ role: cardRole }, { baseClass: "event-card" });
33776
- const buttonClass = themeButtonClassName({
33777
- variant: buttonVariant,
33778
- size: "md"
33779
- });
33780
33954
  const title = event.title;
33781
33955
  const summary = event.presentation?.summary ?? event.description;
33782
33956
  const image = event.presentation?.image ?? null;
@@ -33806,7 +33980,7 @@ const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", but
33806
33980
  image
33807
33981
  }), /* @__PURE__ */ jsx(EventCardContent, {
33808
33982
  allowMap,
33809
- buttonClass,
33983
+ buttonVariant,
33810
33984
  capacityText,
33811
33985
  categoryBadge,
33812
33986
  categoryId: category?.id,
@@ -33908,7 +34082,7 @@ function EventCardContent(props) {
33908
34082
  children: props.summary
33909
34083
  }),
33910
34084
  /* @__PURE__ */ jsx(EventCardFooter, {
33911
- buttonClass: props.buttonClass,
34085
+ buttonVariant: props.buttonVariant,
33912
34086
  capacityText: props.capacityText,
33913
34087
  cta: props.cta,
33914
34088
  priceText: props.priceText
@@ -33946,12 +34120,14 @@ function EventCardFooter(props) {
33946
34120
  className: "event-card-status rb-caption status-muted rb-text-center",
33947
34121
  children: props.cta.label
33948
34122
  }),
33949
- !props.cta.hidden && /* @__PURE__ */ jsx("a", {
34123
+ !props.cta.hidden && /* @__PURE__ */ jsx(ThemedButtonLink, {
33950
34124
  href: props.cta.href,
33951
34125
  target: props.cta.external ? "_blank" : void 0,
33952
34126
  rel: props.cta.external ? "noopener noreferrer" : void 0,
33953
- className: `${props.buttonClass} event-card-cta`,
33954
- children: props.cta.label
34127
+ variant: props.buttonVariant,
34128
+ size: "md",
34129
+ extraClassName: "event-card-cta",
34130
+ label: props.cta.label
33955
34131
  })
33956
34132
  ]
33957
34133
  });
@@ -34015,10 +34191,6 @@ const EventCompactRow = ({ event, buttonVariant = "primary", buttonText }) => {
34015
34191
  const price = formatEventPrice(event);
34016
34192
  const teacherLine = formatEventTeacherLine(event);
34017
34193
  const cta = resolveEventCta(event, buttonText);
34018
- const buttonClass = themeButtonClassName({
34019
- variant: buttonVariant,
34020
- size: "sm"
34021
- });
34022
34194
  return /* @__PURE__ */ jsxs("article", {
34023
34195
  className: "event-compact-row",
34024
34196
  children: [/* @__PURE__ */ jsxs("time", {
@@ -34082,12 +34254,15 @@ const EventCompactRow = ({ event, buttonVariant = "primary", buttonText }) => {
34082
34254
  }), cta.hidden ? /* @__PURE__ */ jsx("span", {
34083
34255
  className: "event-compact-row-status",
34084
34256
  children: cta.label
34085
- }) : /* @__PURE__ */ jsx("a", {
34257
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
34086
34258
  href: cta.href,
34087
34259
  target: cta.external ? "_blank" : void 0,
34088
34260
  rel: cta.external ? "noopener noreferrer" : void 0,
34089
- className: `${buttonClass} event-compact-row-cta`,
34090
- children: /* @__PURE__ */ jsx("span", { children: cta.label })
34261
+ variant: buttonVariant,
34262
+ size: "sm",
34263
+ extraClassName: "event-compact-row-cta",
34264
+ labelClassName: "event-compact-row-cta-label",
34265
+ label: cta.label
34091
34266
  })]
34092
34267
  })]
34093
34268
  })]
@@ -34129,10 +34304,6 @@ function EventQuickDateCard(props) {
34129
34304
  kind: "event_occurrence",
34130
34305
  occurrenceId: event.occurrenceId
34131
34306
  });
34132
- const buttonClass = themeButtonClassName({
34133
- variant: props.buttonVariant,
34134
- size: "sm"
34135
- });
34136
34307
  const quickDateLabel = `${event.title}, ${date.label}`;
34137
34308
  return /* @__PURE__ */ jsxs("article", {
34138
34309
  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",
@@ -34164,13 +34335,15 @@ function EventQuickDateCard(props) {
34164
34335
  children: [/* @__PURE__ */ jsx("span", {
34165
34336
  className: "event-quick-date-price",
34166
34337
  children: formatEventPrice(event)
34167
- }), /* @__PURE__ */ jsx("a", {
34168
- className: `${buttonClass} event-quick-date-cta`,
34338
+ }), /* @__PURE__ */ jsx(ThemedButtonLink, {
34339
+ variant: props.buttonVariant,
34340
+ size: "sm",
34341
+ extraClassName: "event-quick-date-cta",
34169
34342
  href: ctaHref,
34170
34343
  target: cta.external ? "_blank" : void 0,
34171
34344
  rel: cta.external ? "noopener noreferrer" : void 0,
34172
34345
  "aria-label": `${cta.label} ${quickDateLabel}`,
34173
- children: cta.label
34346
+ label: cta.label
34174
34347
  })]
34175
34348
  })
34176
34349
  ]
@@ -34243,10 +34416,6 @@ const EventSpotlight = ({ events, layout = "grid", columns = "3", cardRole = "de
34243
34416
  });
34244
34417
  const containerClass = getContainerClass(layout, columns);
34245
34418
  const cardOrientation = getCardOrientation(layout);
34246
- const buttonClass = themeButtonClassName({
34247
- variant: buttonVariant,
34248
- size: "md"
34249
- });
34250
34419
  return /* @__PURE__ */ jsxs("div", {
34251
34420
  className: `event-spotlight-section ${className || ""}`,
34252
34421
  "data-block": "event-spotlight",
@@ -34264,15 +34433,22 @@ const EventSpotlight = ({ events, layout = "grid", columns = "3", cardRole = "de
34264
34433
  }, event.occurrenceId || event.id))
34265
34434
  }), ctaLabel && ctaUrl ? /* @__PURE__ */ jsx("div", {
34266
34435
  className: "rb-mt-8 rb-text-center",
34267
- children: /* @__PURE__ */ jsx("a", {
34436
+ children: /* @__PURE__ */ jsx(ThemedButtonLink, {
34268
34437
  href: ctaUrl,
34269
- className: buttonClass,
34270
- children: ctaLabel
34438
+ variant: buttonVariant,
34439
+ size: "md",
34440
+ label: ctaLabel
34271
34441
  })
34272
34442
  }) : null]
34273
34443
  });
34274
34444
  };
34275
34445
  //#endregion
34446
+ //#region ../blocks/src/system/runtime/api/readAuthority.ts
34447
+ const browserReadAuthoritySchema = z$1.discriminatedUnion("kind", [z$1.object({ kind: z$1.literal("published") }).strict(), z$1.object({
34448
+ kind: z$1.literal("preview"),
34449
+ token: z$1.string().min(1)
34450
+ }).strict()]);
34451
+ //#endregion
34276
34452
  //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
34277
34453
  const previewStageSchema = z$1.enum(["preview", "published"]);
34278
34454
  const registrationButtonVariantSchema = blockButtonRoleSchema;
@@ -35190,6 +35366,7 @@ const eventCollectionSourceSchemaShape = {
35190
35366
  events: z$1.array(publicEventSchema).nullable().optional(),
35191
35367
  siteId: z$1.string(),
35192
35368
  apiBaseUrl: z$1.string().optional(),
35369
+ readAuthority: browserReadAuthoritySchema.optional(),
35193
35370
  stage: previewStageSchema.optional(),
35194
35371
  listLayout: eventLayoutSchema.optional(),
35195
35372
  listColumns: columnOptionSchema.optional(),
@@ -35242,7 +35419,6 @@ const eventCollectionDisplaySchemaShape = {
35242
35419
  const eventCollectionHydrationSchema = z$1.object({
35243
35420
  siteId: z$1.string(),
35244
35421
  calendarWindow: calendarWindowPageSchema.optional(),
35245
- stage: previewStageSchema.optional(),
35246
35422
  prefetchedEvents: z$1.boolean(),
35247
35423
  eventSurface: eventSurfaceScopeSchema$1,
35248
35424
  filterEventPresets: z$1.string().nullable(),
@@ -35317,7 +35493,6 @@ function buildEventCollectionHydration(source, now = /* @__PURE__ */ new Date())
35317
35493
  return {
35318
35494
  calendarWindow: source.calendarWindow ?? void 0,
35319
35495
  siteId: source.siteId,
35320
- stage: source.stage,
35321
35496
  prefetchedEvents: source.events != null,
35322
35497
  eventSurface: selected ? "all" : normalizeEventSurfaceScope(source.eventSurface),
35323
35498
  filterEventPresets: selected ? null : normalizeEventSurfacePresetsCsv(source.filterEventPresets),
@@ -35364,6 +35539,7 @@ const eventCombinedRenderSchema = z$1.object({
35364
35539
  z$1.object({
35365
35540
  siteId: z$1.string(),
35366
35541
  apiBaseUrl: z$1.string().optional(),
35542
+ readAuthority: browserReadAuthoritySchema.optional(),
35367
35543
  stage: previewStageSchema.optional()
35368
35544
  });
35369
35545
  function buildEventCombinedDisplay(source) {
@@ -35394,6 +35570,7 @@ function buildEventCombinedInteractiveIslandProps(props) {
35394
35570
  meta: {
35395
35571
  siteId: props.siteId,
35396
35572
  apiBaseUrl: props.apiBaseUrl,
35573
+ readAuthority: props.readAuthority,
35397
35574
  stage: props.stage
35398
35575
  },
35399
35576
  source: props
@@ -35847,11 +36024,6 @@ function OfferingsCatalogue(props) {
35847
36024
  //#endregion
35848
36025
  //#region ../blocks/src/system/runtime/nodes/offerings-preview-content.tsx
35849
36026
  function OfferingsPreviewContent(props) {
35850
- const groupLinkClass = themeButtonClassName({
35851
- variant: props.buttonVariant,
35852
- size: "md",
35853
- extraClassName: "offerings-preview-card-link rb-inline-flex rb-items-center rb-gap-2"
35854
- });
35855
36027
  return /* @__PURE__ */ jsx("div", {
35856
36028
  className: "offerings-preview rb-flex rb-flex-col rb-gap-6",
35857
36029
  "data-block": "offerings-preview",
@@ -35891,10 +36063,12 @@ function OfferingsPreviewContent(props) {
35891
36063
  }),
35892
36064
  groupCta ? /* @__PURE__ */ jsx("footer", {
35893
36065
  className: "offerings-preview-card-footer rb-mt-auto rb-flex",
35894
- children: /* @__PURE__ */ jsx("a", {
35895
- className: groupLinkClass,
36066
+ children: /* @__PURE__ */ jsx(ThemedButtonLink, {
36067
+ variant: props.buttonVariant,
36068
+ size: "md",
36069
+ extraClassName: "offerings-preview-card-link rb-inline-flex rb-items-center rb-gap-2",
35896
36070
  href: groupCta.href,
35897
- children: /* @__PURE__ */ jsx("span", { children: groupCta.label })
36071
+ label: groupCta.label
35898
36072
  })
35899
36073
  }) : null
35900
36074
  ]
@@ -36217,10 +36391,6 @@ function WholeSeriesRunCompactRow({ group, path, now }) {
36217
36391
  const timeRange = `${formatTime(firstSession.startsAt, { timeZone })} - ${formatTime(firstSession.endsAt, { timeZone })}`;
36218
36392
  const price = formatEventPriceDisplay(group.representative.pricing);
36219
36393
  const statusLabel = resolveWholeSeriesBookingPhase(group.run, now).kind === "open" ? null : "Registration closed";
36220
- const ctaClass = themeButtonClassName({
36221
- variant: "primary",
36222
- size: "sm"
36223
- });
36224
36394
  return /* @__PURE__ */ jsxs("article", {
36225
36395
  className: "event-compact-row offerings-preview-whole-series-row",
36226
36396
  children: [
@@ -36279,10 +36449,13 @@ function WholeSeriesRunCompactRow({ group, path, now }) {
36279
36449
  }), statusLabel || !path ? /* @__PURE__ */ jsx("span", {
36280
36450
  className: "event-compact-row-status",
36281
36451
  children: statusLabel ?? "Details coming soon"
36282
- }) : /* @__PURE__ */ jsx("a", {
36452
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
36283
36453
  href: path,
36284
- className: `${ctaClass} event-compact-row-cta`,
36285
- children: /* @__PURE__ */ jsx("span", { children: "Book now" })
36454
+ variant: "primary",
36455
+ size: "sm",
36456
+ extraClassName: "event-compact-row-cta",
36457
+ labelClassName: "event-compact-row-cta-label",
36458
+ label: "Book now"
36286
36459
  })]
36287
36460
  })
36288
36461
  ]
@@ -36299,10 +36472,6 @@ function WholeSeriesRunFeatureCard({ group, now, path, buttonVariant, buttonText
36299
36472
  const formattedDate = formatEventCompactDateRail(firstSession.startsAt, { timeZone }).label;
36300
36473
  const timeRange = `${formatTime(firstSession.startsAt, { timeZone })} - ${formatTime(firstSession.endsAt, { timeZone })}`;
36301
36474
  const price = formatEventPriceDisplay(group.representative.pricing);
36302
- const ctaClass = themeButtonClassName({
36303
- variant: buttonVariant,
36304
- size: "md"
36305
- });
36306
36475
  const statusLabel = resolveWholeSeriesBookingPhase(group.run, now).kind === "open" ? null : "Registration closed";
36307
36476
  const description = group.representative.description;
36308
36477
  return /* @__PURE__ */ jsx("article", {
@@ -36335,10 +36504,12 @@ function WholeSeriesRunFeatureCard({ group, now, path, buttonVariant, buttonText
36335
36504
  }), statusLabel || !path ? /* @__PURE__ */ jsx("span", {
36336
36505
  className: "event-compact-row-status",
36337
36506
  children: statusLabel ?? "Details coming soon"
36338
- }) : /* @__PURE__ */ jsx("a", {
36507
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
36339
36508
  href: path,
36340
- className: `${ctaClass} event-card-cta`,
36341
- children: buttonText || "Book now"
36509
+ variant: buttonVariant,
36510
+ size: "md",
36511
+ extraClassName: "event-card-cta",
36512
+ label: buttonText || "Book now"
36342
36513
  })]
36343
36514
  })
36344
36515
  ]
@@ -36491,15 +36662,13 @@ function WeeklySlotAvailabilityView({ availability, loading = false, error, empt
36491
36662
  "."
36492
36663
  ]
36493
36664
  }),
36494
- resolvedCtaUrl ? /* @__PURE__ */ jsx("a", {
36495
- className: themeButtonClassName({
36496
- variant: "ghost",
36497
- size: "sm",
36498
- extraClassName: "weekly-slot-availability__cta"
36499
- }),
36665
+ resolvedCtaUrl ? /* @__PURE__ */ jsx(ThemedButtonLink, {
36666
+ variant: "ghost",
36667
+ size: "sm",
36668
+ extraClassName: "weekly-slot-availability__cta",
36500
36669
  href: buildSlotCtaUrl(resolvedCtaUrl, slot),
36501
36670
  "aria-label": buildSlotCtaLabel(resolvedCtaText, slot),
36502
- children: resolvedCtaText
36671
+ label: resolvedCtaText
36503
36672
  }) : null
36504
36673
  ]
36505
36674
  }, slot.id))
@@ -37218,6 +37387,7 @@ const shopSourceSchema = z$1.object({
37218
37387
  products: z$1.array(publicProductSchema).nullable().optional(),
37219
37388
  siteId: z$1.string().optional(),
37220
37389
  apiBaseUrl: z$1.string().optional(),
37390
+ readAuthority: browserReadAuthoritySchema.optional(),
37221
37391
  stage: previewStageSchema.optional()
37222
37392
  });
37223
37393
  const productVariantOptionDisplaySchema = z$1.object({
@@ -37385,6 +37555,7 @@ function resolveShowPricePerCredit(source) {
37385
37555
  z$1.object({
37386
37556
  siteId: z$1.string().optional(),
37387
37557
  apiBaseUrl: z$1.string().optional(),
37558
+ readAuthority: browserReadAuthoritySchema.optional(),
37388
37559
  stage: previewStageSchema.optional()
37389
37560
  });
37390
37561
  const shopBlockRuntime = defineProgressiveBlockRuntime({
@@ -37519,6 +37690,7 @@ function buildShopInteractiveIslandProps(props) {
37519
37690
  meta: {
37520
37691
  siteId: props.siteId,
37521
37692
  apiBaseUrl: props.apiBaseUrl,
37693
+ readAuthority: props.readAuthority,
37522
37694
  stage: props.stage
37523
37695
  },
37524
37696
  source: {
@@ -37534,6 +37706,7 @@ function buildProductListInteractiveIslandProps(props) {
37534
37706
  meta: {
37535
37707
  siteId: props.siteId,
37536
37708
  apiBaseUrl: props.apiBaseUrl,
37709
+ readAuthority: props.readAuthority,
37537
37710
  stage: props.stage
37538
37711
  },
37539
37712
  source: {
@@ -37549,6 +37722,7 @@ function buildProductDetailInteractiveIslandProps(props) {
37549
37722
  meta: {
37550
37723
  siteId: props.siteId,
37551
37724
  apiBaseUrl: props.apiBaseUrl,
37725
+ readAuthority: props.readAuthority,
37552
37726
  stage: props.stage
37553
37727
  },
37554
37728
  source: {
@@ -37564,6 +37738,7 @@ function buildCartInteractiveIslandProps(props) {
37564
37738
  meta: {
37565
37739
  siteId: props.siteId,
37566
37740
  apiBaseUrl: props.apiBaseUrl,
37741
+ readAuthority: props.readAuthority,
37567
37742
  stage: props.stage
37568
37743
  },
37569
37744
  source: {
@@ -37579,6 +37754,7 @@ function buildCheckoutInteractiveIslandProps(props) {
37579
37754
  meta: {
37580
37755
  siteId: props.siteId,
37581
37756
  apiBaseUrl: props.apiBaseUrl,
37757
+ readAuthority: props.readAuthority,
37582
37758
  stage: props.stage
37583
37759
  },
37584
37760
  source: {
@@ -37660,6 +37836,7 @@ const cartBlockDefinition = {
37660
37836
  baseClass: "",
37661
37837
  spacing: "spacious",
37662
37838
  children: sectionContainer([cart(withApiBindings({
37839
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
37663
37840
  mode: "cart",
37664
37841
  heading: { $bind: {
37665
37842
  from: "content.heading",
@@ -37743,6 +37920,7 @@ const checkoutBlockDefinition = {
37743
37920
  baseClass: "",
37744
37921
  spacing: "spacious",
37745
37922
  children: sectionContainer([checkout(withApiBindings({
37923
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
37746
37924
  mode: "checkout",
37747
37925
  heading: { $bind: {
37748
37926
  from: "content.heading",
@@ -38175,6 +38353,7 @@ const eventRegistrationSourceSchema = z$1.object({
38175
38353
  apiBaseUrl: z$1.string().optional(),
38176
38354
  portalToken: z$1.string().nullable().optional(),
38177
38355
  previewToken: z$1.string().nullable().optional(),
38356
+ readAuthority: browserReadAuthoritySchema.optional(),
38178
38357
  ...eventRegistrationHydrationSchemaShape,
38179
38358
  events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
38180
38359
  wholeSeriesRunEvents: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
@@ -38212,6 +38391,7 @@ z$1.object({
38212
38391
  apiBaseUrl: z$1.string().optional(),
38213
38392
  portalToken: z$1.string().nullable().optional(),
38214
38393
  previewToken: z$1.string().nullable().optional(),
38394
+ readAuthority: browserReadAuthoritySchema.optional(),
38215
38395
  stage: previewStageSchema.optional()
38216
38396
  });
38217
38397
  function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents) {
@@ -38355,6 +38535,7 @@ function buildEventRegistrationInteractiveIslandProps(props) {
38355
38535
  apiBaseUrl: props.apiBaseUrl,
38356
38536
  portalToken: props.portalToken,
38357
38537
  previewToken: props.previewToken,
38538
+ readAuthority: props.readAuthority,
38358
38539
  stage: props.stage
38359
38540
  },
38360
38541
  source: props
@@ -38484,6 +38665,7 @@ const eventRegistrationBlockDefinition = {
38484
38665
  text({ as: "h2" }, bind("content.heading"), when("content.heading")),
38485
38666
  richText({ className: "rb-prose rb-max-w-none" }, bind("content.description"), when("content.description")),
38486
38667
  eventRegistration(withApiBindings({
38668
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
38487
38669
  occurrenceContext: { $bind: { from: "$root.occurrenceContext" } },
38488
38670
  subject: { $bind: { from: "$root.subject" } },
38489
38671
  portalToken: { $bind: {
@@ -38929,6 +39111,7 @@ const eventCalendarRenderSchema = z$1.object({
38929
39111
  z$1.object({
38930
39112
  siteId: z$1.string(),
38931
39113
  apiBaseUrl: z$1.string().optional(),
39114
+ readAuthority: browserReadAuthoritySchema.optional(),
38932
39115
  stage: previewStageSchema.optional()
38933
39116
  });
38934
39117
  /**
@@ -38950,7 +39133,7 @@ function buildEventCalendarDisplay(source) {
38950
39133
  listColumns: source.listColumns ?? source.columns
38951
39134
  }),
38952
39135
  kind: "event-calendar",
38953
- displayMode: normalizeEventCalendarDisplayMode$1(source) ?? "combined",
39136
+ displayMode: resolveEventCalendarReadPlan(source).mode,
38954
39137
  className: source.className ?? null,
38955
39138
  events: (source.events ?? []).slice().sort((left, right) => new Date(left.startsAt).getTime() - new Date(right.startsAt).getTime()),
38956
39139
  boardTitle: normalizeOptionalText(source.boardTitle),
@@ -38970,13 +39153,16 @@ const eventCalendarBlockRuntime = defineProgressiveBlockRuntime({
38970
39153
  source: createZodCodec(eventCalendarSourceSchema),
38971
39154
  render: createZodCodec(eventCalendarRenderSchema)
38972
39155
  },
38973
- buildRender: (source) => ({
38974
- display: buildEventCalendarDisplay(source.calendarWindow && (source.variant ?? source.displayMode ?? "combined") !== "combined" && (source.variant ?? source.displayMode) !== "list" ? {
38975
- ...source,
38976
- events: source.calendarWindow.events
38977
- } : source),
38978
- hydration: buildEventCollectionHydration(source)
38979
- })
39156
+ buildRender: (source) => {
39157
+ const plan = resolveEventCalendarReadPlan(source);
39158
+ return {
39159
+ display: buildEventCalendarDisplay(source.calendarWindow && plan.jobs === "calendar" ? {
39160
+ ...source,
39161
+ events: source.calendarWindow.events
39162
+ } : source),
39163
+ hydration: buildEventCollectionHydration(source)
39164
+ };
39165
+ }
38980
39166
  });
38981
39167
  function buildEventCalendarInteractiveIslandProps(props) {
38982
39168
  return buildInteractiveIslandProps({
@@ -38985,6 +39171,7 @@ function buildEventCalendarInteractiveIslandProps(props) {
38985
39171
  meta: {
38986
39172
  siteId: props.siteId,
38987
39173
  apiBaseUrl: props.apiBaseUrl,
39174
+ readAuthority: props.readAuthority,
38988
39175
  stage: props.stage
38989
39176
  },
38990
39177
  source: props
@@ -39138,6 +39325,7 @@ const eventCalendarLayout = [styledSection({
39138
39325
  rootType: "stack",
39139
39326
  rootProps: { gap: "lg" },
39140
39327
  children: [...eventSectionHeaderLayoutNodes({ splitClassName: "event-section-head event-section-head--split" }), el("event-calendar", withApiBindings({
39328
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
39141
39329
  events: { $bind: { from: "data.events" } },
39142
39330
  calendarWindow: { $bind: { from: "data.calendarWindow" } },
39143
39331
  stage: { $bind: {
@@ -40017,6 +40205,7 @@ const eventListingSourceSchema = z$1.object({
40017
40205
  events: z$1.array(publicEventSchema).nullable().optional(),
40018
40206
  siteId: z$1.string(),
40019
40207
  apiBaseUrl: z$1.string().optional(),
40208
+ readAuthority: browserReadAuthoritySchema.optional(),
40020
40209
  stage: previewStageSchema.optional(),
40021
40210
  layout: eventLayoutSchema.optional(),
40022
40211
  columns: columnOptionSchema.optional(),
@@ -40057,7 +40246,6 @@ const eventListingDisplaySchema = z$1.object({
40057
40246
  });
40058
40247
  const eventListingHydrationSchema = z$1.object({
40059
40248
  siteId: z$1.string(),
40060
- stage: previewStageSchema.optional(),
40061
40249
  eventsPerPage: eventPageSizeSchema,
40062
40250
  paginationAction: eventListPaginationActionSchema,
40063
40251
  showFilters: z$1.boolean(),
@@ -40080,6 +40268,7 @@ const eventListingRenderSchema = z$1.object({
40080
40268
  z$1.object({
40081
40269
  siteId: z$1.string(),
40082
40270
  apiBaseUrl: z$1.string().optional(),
40271
+ readAuthority: browserReadAuthoritySchema.optional(),
40083
40272
  stage: previewStageSchema.optional()
40084
40273
  });
40085
40274
  const eventListingBlockRuntime = defineProgressiveBlockRuntime({
@@ -40114,7 +40303,6 @@ const eventListingBlockRuntime = defineProgressiveBlockRuntime({
40114
40303
  },
40115
40304
  hydration: {
40116
40305
  siteId: source.siteId,
40117
- stage: source.stage,
40118
40306
  eventsPerPage: pageSize,
40119
40307
  paginationAction: resolveEventListPaginationAction({
40120
40308
  paginationMode: source.paginationMode,
@@ -40144,6 +40332,7 @@ function buildEventListingInteractiveIslandProps(props) {
40144
40332
  meta: {
40145
40333
  siteId: props.siteId,
40146
40334
  apiBaseUrl: props.apiBaseUrl,
40335
+ readAuthority: props.readAuthority,
40147
40336
  stage: props.stage
40148
40337
  },
40149
40338
  source: props
@@ -40408,6 +40597,7 @@ const eventListingBlockDefinition = {
40408
40597
  rootType: "stack",
40409
40598
  rootProps: { gap: "lg" },
40410
40599
  children: [...eventSectionHeaderLayoutNodes(), el("event-listing", withApiBindings({
40600
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
40411
40601
  events: { $bind: { from: "data.events" } },
40412
40602
  stage: { $bind: {
40413
40603
  from: "$root.previewStage",
@@ -41060,6 +41250,7 @@ const productDetailBlockDefinition = {
41060
41250
  baseClass: "",
41061
41251
  spacing: "spacious",
41062
41252
  children: sectionContainer([productDetail(withApiBindings({
41253
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
41063
41254
  mode: "product-detail",
41064
41255
  heading: { $bind: {
41065
41256
  from: "content.heading",
@@ -41228,6 +41419,7 @@ const productListBlockDefinition = {
41228
41419
  baseClass: "",
41229
41420
  spacing: "spacious",
41230
41421
  children: sectionContainer([productList(withApiBindings({
41422
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
41231
41423
  mode: "product-list",
41232
41424
  heading: { $bind: {
41233
41425
  from: "content.heading",
@@ -41492,6 +41684,7 @@ const shopBlockDefinition = {
41492
41684
  baseClass: "",
41493
41685
  spacing: "spacious",
41494
41686
  children: sectionContainer([shop(withApiBindings({
41687
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
41495
41688
  mode: "passes-memberships",
41496
41689
  showPasses: { $bind: {
41497
41690
  from: "content.showPasses",
@@ -41894,15 +42087,13 @@ function CheckoutShellView(props) {
41894
42087
  //#endregion
41895
42088
  //#region ../blocks/src/system/runtime/nodes/shop-commerce.server.tsx
41896
42089
  function renderServerPendingAction(label, soldOut) {
41897
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
42090
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ThemedButton, {
41898
42091
  type: "button",
41899
- className: themeButtonClassName({
41900
- variant: "default",
41901
- size: "md"
41902
- }),
42092
+ variant: "default",
42093
+ size: "md",
42094
+ label: soldOut ? "Sold out" : label,
41903
42095
  disabled: true,
41904
- "aria-disabled": "true",
41905
- children: soldOut ? "Sold out" : label
42096
+ "aria-disabled": "true"
41906
42097
  }), !soldOut ? /* @__PURE__ */ jsx("p", {
41907
42098
  className: "rb-caption status-muted",
41908
42099
  children: "Cart actions become interactive after page load."
@@ -41919,13 +42110,11 @@ function ProductListServerContent(props) {
41919
42110
  selectedVariantId: card.selectedVariantId,
41920
42111
  disabled: true
41921
42112
  }),
41922
- actions: /* @__PURE__ */ jsxs(Fragment, { children: [renderServerPendingAction(card.actionLabel, card.soldOut), card.path ? /* @__PURE__ */ jsx("a", {
42113
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [renderServerPendingAction(card.actionLabel, card.soldOut), card.path ? /* @__PURE__ */ jsx(ThemedButtonLink, {
41923
42114
  href: card.path,
41924
- className: themeButtonClassName({
41925
- variant: "secondary",
41926
- size: "sm"
41927
- }),
41928
- children: "View details"
42115
+ variant: "secondary",
42116
+ size: "sm",
42117
+ label: "View details"
41929
42118
  }) : null] })
41930
42119
  }, card.productId))
41931
42120
  });
@@ -42221,10 +42410,6 @@ function AgendaLinkCard({ event, showCapacity, showVenue, buttonVariant, buttonT
42221
42410
  const price = formatEventPrice(event);
42222
42411
  const capacity = showCapacity ? formatEventRemainingPlaces(event) : null;
42223
42412
  const cta = resolveEventCta(event, buttonText);
42224
- const buttonClass = themeButtonClassName({
42225
- variant: buttonVariant,
42226
- size: "sm"
42227
- });
42228
42413
  return /* @__PURE__ */ jsxs("article", {
42229
42414
  className: "event-agenda-card event-agenda-card--agenda",
42230
42415
  children: [
@@ -42276,12 +42461,14 @@ function AgendaLinkCard({ event, showCapacity, showVenue, buttonVariant, buttonT
42276
42461
  }), cta.hidden ? /* @__PURE__ */ jsx("span", {
42277
42462
  className: "event-agenda-card-status status-muted",
42278
42463
  children: cta.label
42279
- }) : /* @__PURE__ */ jsx("a", {
42464
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
42280
42465
  href: cta.href,
42281
42466
  target: cta.external ? "_blank" : void 0,
42282
42467
  rel: cta.external ? "noopener noreferrer" : void 0,
42283
- className: `${buttonClass} event-agenda-card-cta`,
42284
- children: cta.label
42468
+ variant: buttonVariant,
42469
+ size: "sm",
42470
+ extraClassName: "event-agenda-card-cta",
42471
+ label: cta.label
42285
42472
  })]
42286
42473
  })
42287
42474
  ]
@@ -42480,7 +42667,7 @@ const WeekBoardCard = ({ event, showCapacity, calendarTimeZone }) => {
42480
42667
  ]
42481
42668
  });
42482
42669
  };
42483
- const WeekBoardNavigationControls = ({ navigation, todayClassName }) => {
42670
+ const WeekBoardNavigationControls = ({ navigation, buttonVariant }) => {
42484
42671
  const handlers = navigation.kind === "interactive" ? navigation : {
42485
42672
  onPrevious: void 0,
42486
42673
  onNext: void 0,
@@ -42513,12 +42700,13 @@ const WeekBoardNavigationControls = ({ navigation, todayClassName }) => {
42513
42700
  onClick: handlers.onNext,
42514
42701
  children: /* @__PURE__ */ jsx(CalendarNavigationChevron, { direction: "next" })
42515
42702
  }),
42516
- /* @__PURE__ */ jsx("button", {
42703
+ /* @__PURE__ */ jsx(ThemedButton, {
42517
42704
  type: "button",
42518
- className: todayClassName,
42705
+ variant: buttonVariant,
42706
+ size: "sm",
42707
+ label: "Today",
42519
42708
  disabled: navigation.isCurrentWeek,
42520
- onClick: handlers.onToday,
42521
- children: "Today"
42709
+ onClick: handlers.onToday
42522
42710
  })
42523
42711
  ]
42524
42712
  });
@@ -42534,16 +42722,17 @@ const WeekBoardLegend = () => /* @__PURE__ */ jsx("div", {
42534
42722
  }), item.label]
42535
42723
  }, item.status))
42536
42724
  });
42537
- const WeekBoardLoadError = ({ navigation, buttonClassName }) => {
42725
+ const WeekBoardLoadError = ({ navigation, buttonVariant }) => {
42538
42726
  if (navigation.kind !== "interactive" || navigation.loadState.kind !== "error") return null;
42539
42727
  return /* @__PURE__ */ jsxs("div", {
42540
42728
  className: "event-week-board-error",
42541
42729
  role: "status",
42542
- children: [/* @__PURE__ */ jsx("p", { children: "Failed to load events" }), /* @__PURE__ */ jsx("button", {
42730
+ children: [/* @__PURE__ */ jsx("p", { children: "Failed to load events" }), /* @__PURE__ */ jsx(ThemedButton, {
42543
42731
  type: "button",
42544
- className: buttonClassName,
42545
- onClick: navigation.loadState.onRetry,
42546
- children: "Try again"
42732
+ variant: buttonVariant,
42733
+ size: "sm",
42734
+ label: "Try again",
42735
+ onClick: navigation.loadState.onRetry
42547
42736
  })]
42548
42737
  });
42549
42738
  };
@@ -42575,17 +42764,18 @@ const WeekBoardGrid = ({ days, eventsByDate, showCapacity, calendarTimeZone, tod
42575
42764
  }, dateKey);
42576
42765
  })
42577
42766
  });
42578
- const WeekBoardFooter = ({ note, ctaHref, ctaLabel, ctaClassName }) => {
42767
+ const WeekBoardFooter = ({ note, ctaHref, ctaLabel, buttonVariant }) => {
42579
42768
  if (note === null && ctaHref === null) return null;
42580
42769
  return /* @__PURE__ */ jsxs("div", {
42581
42770
  className: "event-week-board-foot",
42582
42771
  children: [note === null ? null : /* @__PURE__ */ jsx("p", {
42583
42772
  className: "event-week-board-foot-note",
42584
42773
  children: note
42585
- }), ctaHref === null ? null : /* @__PURE__ */ jsx("a", {
42586
- className: ctaClassName,
42774
+ }), ctaHref === null ? null : /* @__PURE__ */ jsx(ThemedButtonLink, {
42775
+ variant: buttonVariant,
42776
+ size: "sm",
42587
42777
  href: ctaHref,
42588
- children: ctaLabel
42778
+ label: ctaLabel
42589
42779
  })]
42590
42780
  });
42591
42781
  };
@@ -42600,14 +42790,6 @@ const WeekBoardFooter = ({ note, ctaHref, ctaLabel, ctaClassName }) => {
42600
42790
  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 }) => {
42601
42791
  const eventsByDate = groupEventsByDate(events, calendarTimeZone);
42602
42792
  const hasAnyEvents = days.some((date) => (eventsByDate.get(formatDateKey(date)) ?? []).length > 0);
42603
- const ctaClassName = themeButtonClassName({
42604
- variant: buttonVariant,
42605
- size: "sm"
42606
- });
42607
- const todayClassName = themeButtonClassName({
42608
- variant: buttonVariant,
42609
- size: "sm"
42610
- });
42611
42793
  const hasTitle = typeof title === "string" && title.length > 0;
42612
42794
  const hasFooterNote = typeof footerNote === "string" && footerNote.length > 0;
42613
42795
  const footerNoteText = hasAnyEvents ? hasFooterNote ? footerNote : null : emptyMessage;
@@ -42630,14 +42812,14 @@ const WeekBoardView = ({ days, events, navigation, showCapacity, emptyMessage =
42630
42812
  }) : null,
42631
42813
  /* @__PURE__ */ jsx(WeekBoardNavigationControls, {
42632
42814
  navigation,
42633
- todayClassName
42815
+ buttonVariant
42634
42816
  }),
42635
42817
  /* @__PURE__ */ jsx(WeekBoardLegend, {})
42636
42818
  ]
42637
42819
  }),
42638
42820
  /* @__PURE__ */ jsx(WeekBoardLoadError, {
42639
42821
  navigation,
42640
- buttonClassName: todayClassName
42822
+ buttonVariant
42641
42823
  }),
42642
42824
  /* @__PURE__ */ jsx(WeekBoardGrid, {
42643
42825
  days,
@@ -42650,7 +42832,7 @@ const WeekBoardView = ({ days, events, navigation, showCapacity, emptyMessage =
42650
42832
  note: footerNoteText,
42651
42833
  ctaHref: resolvedCtaHref,
42652
42834
  ctaLabel,
42653
- ctaClassName
42835
+ buttonVariant
42654
42836
  })
42655
42837
  ]
42656
42838
  })
@@ -42749,6 +42931,54 @@ function assertNeverDisplayMode(value) {
42749
42931
  function renderEventCard(event, display) {
42750
42932
  return renderEventListItem(event, display);
42751
42933
  }
42934
+ function CalendarSsrHeader(props) {
42935
+ const periodLabel = props.period === "week" ? "week" : "month";
42936
+ return /* @__PURE__ */ jsxs("div", {
42937
+ className: "event-calendar-header",
42938
+ children: [/* @__PURE__ */ jsxs("div", {
42939
+ className: "event-calendar-nav",
42940
+ children: [
42941
+ /* @__PURE__ */ jsx("button", {
42942
+ type: "button",
42943
+ className: "event-calendar-nav-btn",
42944
+ "aria-label": `Previous ${periodLabel}`,
42945
+ children: /* @__PURE__ */ jsx(CalendarSsrChevron, { direction: "previous" })
42946
+ }),
42947
+ /* @__PURE__ */ jsx("h3", {
42948
+ className: "event-calendar-title",
42949
+ children: props.title
42950
+ }),
42951
+ /* @__PURE__ */ jsx("button", {
42952
+ type: "button",
42953
+ className: "event-calendar-nav-btn",
42954
+ "aria-label": `Next ${periodLabel}`,
42955
+ children: /* @__PURE__ */ jsx(CalendarSsrChevron, { direction: "next" })
42956
+ })
42957
+ ]
42958
+ }), /* @__PURE__ */ jsx(ThemedButton, {
42959
+ type: "button",
42960
+ variant: props.buttonVariant,
42961
+ size: "sm",
42962
+ label: "Today"
42963
+ })]
42964
+ });
42965
+ }
42966
+ function CalendarSsrChevron(props) {
42967
+ return /* @__PURE__ */ jsx("svg", {
42968
+ width: "20",
42969
+ height: "20",
42970
+ fill: "none",
42971
+ stroke: "currentColor",
42972
+ strokeWidth: 2,
42973
+ viewBox: "0 0 24 24",
42974
+ children: /* @__PURE__ */ jsx("path", {
42975
+ strokeLinecap: "round",
42976
+ strokeLinejoin: "round",
42977
+ strokeWidth: 2,
42978
+ d: props.direction === "previous" ? "M15 19l-7-7 7-7" : "M9 5l7 7-7 7"
42979
+ })
42980
+ });
42981
+ }
42752
42982
  function renderCombinedSsr(display, prefetchedEvents) {
42753
42983
  const listDisplay = buildEventCalendarListingDisplay(display, prefetchedEvents, "event-combined-content");
42754
42984
  return /* @__PURE__ */ jsxs("div", {
@@ -42796,62 +43026,10 @@ function renderCalendarSsr(display, hydration) {
42796
43026
  return /* @__PURE__ */ jsxs("div", {
42797
43027
  className: clsx("event-calendar", display.className ?? void 0),
42798
43028
  "data-block": "event-calendar",
42799
- children: [/* @__PURE__ */ jsxs("div", {
42800
- className: "event-calendar-header",
42801
- children: [/* @__PURE__ */ jsxs("div", {
42802
- className: "event-calendar-nav",
42803
- children: [
42804
- /* @__PURE__ */ jsx("button", {
42805
- type: "button",
42806
- className: "event-calendar-nav-btn",
42807
- "aria-label": calendarView === "week" ? "Previous week" : "Previous month",
42808
- children: /* @__PURE__ */ jsx("svg", {
42809
- width: "20",
42810
- height: "20",
42811
- fill: "none",
42812
- stroke: "currentColor",
42813
- strokeWidth: 2,
42814
- viewBox: "0 0 24 24",
42815
- children: /* @__PURE__ */ jsx("path", {
42816
- strokeLinecap: "round",
42817
- strokeLinejoin: "round",
42818
- strokeWidth: 2,
42819
- d: "M15 19l-7-7 7-7"
42820
- })
42821
- })
42822
- }),
42823
- /* @__PURE__ */ jsx("h3", {
42824
- className: "event-calendar-title",
42825
- children: viewport.title
42826
- }),
42827
- /* @__PURE__ */ jsx("button", {
42828
- type: "button",
42829
- className: "event-calendar-nav-btn",
42830
- "aria-label": calendarView === "week" ? "Next week" : "Next month",
42831
- children: /* @__PURE__ */ jsx("svg", {
42832
- width: "20",
42833
- height: "20",
42834
- fill: "none",
42835
- stroke: "currentColor",
42836
- strokeWidth: 2,
42837
- viewBox: "0 0 24 24",
42838
- children: /* @__PURE__ */ jsx("path", {
42839
- strokeLinecap: "round",
42840
- strokeLinejoin: "round",
42841
- strokeWidth: 2,
42842
- d: "M9 5l7 7-7 7"
42843
- })
42844
- })
42845
- })
42846
- ]
42847
- }), /* @__PURE__ */ jsx("button", {
42848
- type: "button",
42849
- className: themeButtonClassName({
42850
- variant: display.buttonVariant,
42851
- size: "sm"
42852
- }),
42853
- children: "Today"
42854
- })]
43029
+ children: [/* @__PURE__ */ jsx(CalendarSsrHeader, {
43030
+ title: viewport.title,
43031
+ period: calendarView,
43032
+ buttonVariant: display.buttonVariant
42855
43033
  }), viewport.kind === "week" ? /* @__PURE__ */ jsx(WeekAgendaView, {
42856
43034
  days: viewport.days,
42857
43035
  events: [...display.events],
@@ -42927,62 +43105,10 @@ function renderTimetableSsr(display, hydration) {
42927
43105
  return /* @__PURE__ */ jsxs("div", {
42928
43106
  className: clsx("event-calendar", "event-calendar--timetable", display.className ?? void 0),
42929
43107
  "data-block": "event-calendar",
42930
- children: [/* @__PURE__ */ jsxs("div", {
42931
- className: "event-calendar-header",
42932
- children: [/* @__PURE__ */ jsxs("div", {
42933
- className: "event-calendar-nav",
42934
- children: [
42935
- /* @__PURE__ */ jsx("button", {
42936
- type: "button",
42937
- className: "event-calendar-nav-btn",
42938
- "aria-label": "Previous week",
42939
- children: /* @__PURE__ */ jsx("svg", {
42940
- width: "20",
42941
- height: "20",
42942
- fill: "none",
42943
- stroke: "currentColor",
42944
- strokeWidth: 2,
42945
- viewBox: "0 0 24 24",
42946
- children: /* @__PURE__ */ jsx("path", {
42947
- strokeLinecap: "round",
42948
- strokeLinejoin: "round",
42949
- strokeWidth: 2,
42950
- d: "M15 19l-7-7 7-7"
42951
- })
42952
- })
42953
- }),
42954
- /* @__PURE__ */ jsx("h3", {
42955
- className: "event-calendar-title",
42956
- children: viewport.title
42957
- }),
42958
- /* @__PURE__ */ jsx("button", {
42959
- type: "button",
42960
- className: "event-calendar-nav-btn",
42961
- "aria-label": "Next week",
42962
- children: /* @__PURE__ */ jsx("svg", {
42963
- width: "20",
42964
- height: "20",
42965
- fill: "none",
42966
- stroke: "currentColor",
42967
- strokeWidth: 2,
42968
- viewBox: "0 0 24 24",
42969
- children: /* @__PURE__ */ jsx("path", {
42970
- strokeLinecap: "round",
42971
- strokeLinejoin: "round",
42972
- strokeWidth: 2,
42973
- d: "M9 5l7 7-7 7"
42974
- })
42975
- })
42976
- })
42977
- ]
42978
- }), /* @__PURE__ */ jsx("button", {
42979
- type: "button",
42980
- className: themeButtonClassName({
42981
- variant: display.buttonVariant,
42982
- size: "sm"
42983
- }),
42984
- children: "Today"
42985
- })]
43108
+ children: [/* @__PURE__ */ jsx(CalendarSsrHeader, {
43109
+ title: viewport.title,
43110
+ period: "week",
43111
+ buttonVariant: display.buttonVariant
42986
43112
  }), /* @__PURE__ */ jsxs("div", {
42987
43113
  className: "event-timetable",
42988
43114
  children: [
@@ -43478,14 +43604,12 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
43478
43604
  className: "fb-actions",
43479
43605
  children: /* @__PURE__ */ jsx("div", {
43480
43606
  className: "fb-actions-inner",
43481
- children: /* @__PURE__ */ jsx("button", {
43607
+ children: /* @__PURE__ */ jsx(ThemedButton, {
43482
43608
  type: "submit",
43483
- className: themeButtonClassName({
43484
- variant: "primary",
43485
- size: "md",
43486
- extraClassName: "rb-w-full rb-sm-w-auto"
43487
- }),
43488
- children: display.submitLabel
43609
+ variant: "primary",
43610
+ size: "md",
43611
+ extraClassName: "rb-w-full rb-sm-w-auto",
43612
+ label: display.submitLabel
43489
43613
  })
43490
43614
  })
43491
43615
  })
@@ -43580,13 +43704,11 @@ function NewsletterFormSSR(props) {
43580
43704
  }) : null,
43581
43705
  /* @__PURE__ */ jsx("div", {
43582
43706
  className: "newsletter-submit",
43583
- children: /* @__PURE__ */ jsx("button", {
43707
+ children: /* @__PURE__ */ jsx(ThemedButton, {
43584
43708
  type: "submit",
43585
- className: themeButtonClassName({
43586
- variant: display.buttonVariant,
43587
- size: "md"
43588
- }),
43589
- children: display.buttonLabel
43709
+ variant: display.buttonVariant,
43710
+ size: "md",
43711
+ label: display.buttonLabel
43590
43712
  })
43591
43713
  })
43592
43714
  ]
@@ -43668,28 +43790,24 @@ function ShopSSR({ blockId, siteId, apiBaseUrl, stage, children, checkoutEndpoin
43668
43790
  display: render.display,
43669
43791
  passCards: render.display.passes.map((pass) => /* @__PURE__ */ jsx(PassCardView, {
43670
43792
  display: pass,
43671
- action: pass.action.kind === "unavailable" ? /* @__PURE__ */ jsx(PassPurchaseUnavailable, { label: pass.action.label }) : /* @__PURE__ */ jsx("button", {
43793
+ action: pass.action.kind === "unavailable" ? /* @__PURE__ */ jsx(PassPurchaseUnavailable, { label: pass.action.label }) : /* @__PURE__ */ jsx(ThemedButton, {
43672
43794
  type: "button",
43673
- className: themeButtonClassName({
43674
- variant: render.hydration.buttonVariant,
43675
- size: "md"
43676
- }),
43795
+ variant: render.hydration.buttonVariant,
43796
+ size: "md",
43797
+ label: pass.action.label,
43677
43798
  disabled: true,
43678
- "aria-disabled": "true",
43679
- children: pass.action.label
43799
+ "aria-disabled": "true"
43680
43800
  })
43681
43801
  }, pass.id)),
43682
43802
  membershipCards: render.display.memberships.map((membership) => /* @__PURE__ */ jsx(MembershipCardView, {
43683
43803
  display: membership,
43684
- action: /* @__PURE__ */ jsx("button", {
43804
+ action: /* @__PURE__ */ jsx(ThemedButton, {
43685
43805
  type: "button",
43686
- className: themeButtonClassName({
43687
- variant: render.hydration.buttonVariant,
43688
- size: "md"
43689
- }),
43806
+ variant: render.hydration.buttonVariant,
43807
+ size: "md",
43808
+ label: membership.actionLabel,
43690
43809
  disabled: true,
43691
- "aria-disabled": "true",
43692
- children: membership.actionLabel
43810
+ "aria-disabled": "true"
43693
43811
  })
43694
43812
  }, membership.id))
43695
43813
  }),
@@ -43738,6 +43856,7 @@ const serverComponentRegistry = {
43738
43856
  svg: SvgNode,
43739
43857
  section: SectionNode,
43740
43858
  headerSection: header_section_server_default,
43859
+ headerControl: HeaderControlNode,
43741
43860
  stack: StackNode,
43742
43861
  inline: InlineNode,
43743
43862
  grid: GridNode,
@@ -44564,16 +44683,71 @@ function resolveChildren(nodes, context) {
44564
44683
  function isReactNode(value) {
44565
44684
  return value !== null && value !== void 0;
44566
44685
  }
44686
+ const RENDERER_METADATA_PROP_KEYS = /* @__PURE__ */ new Set([
44687
+ "pathBase",
44688
+ "blockId",
44689
+ "blockKind",
44690
+ "blockContent",
44691
+ "fragmentRegistry",
44692
+ "previewAuthoring",
44693
+ "contentVersionId",
44694
+ "imageResolveContext"
44695
+ ]);
44696
+ function omitRendererMetadataProps(props) {
44697
+ const presentationProps = {};
44698
+ for (const [key, value] of Object.entries(props)) if (!RENDERER_METADATA_PROP_KEYS.has(key)) presentationProps[key] = value;
44699
+ return presentationProps;
44700
+ }
44701
+ const BLOCK_ID_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
44702
+ "accordion",
44703
+ "appointment-services",
44704
+ "booking-form",
44705
+ "carousel",
44706
+ "cart",
44707
+ "checkout",
44708
+ "event-calendar",
44709
+ "event-combined",
44710
+ "event-details",
44711
+ "event-listing",
44712
+ "event-registration",
44713
+ "form",
44714
+ "gifting",
44715
+ "headersection",
44716
+ "location-map",
44717
+ "newsletter-form",
44718
+ "product-detail",
44719
+ "product-list",
44720
+ "shop",
44721
+ "weekly-slot-availability"
44722
+ ]);
44723
+ const BLOCK_CONTENT_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
44724
+ "feature-card-icon",
44725
+ "headersection",
44726
+ "media",
44727
+ "text"
44728
+ ]);
44729
+ const BLOCK_KIND_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
44730
+ "headersection",
44731
+ "media",
44732
+ "richtext"
44733
+ ]);
44734
+ /**
44735
+ * Projects resolver context only to node kinds with an explicit metadata
44736
+ * contract. Presentation props and renderer metadata never share a universal
44737
+ * spread boundary, so adding metadata cannot leak it into DOM-backed nodes.
44738
+ */
44567
44739
  function resolveNodeMetadata(nodeType, context) {
44740
+ const normalizedType = nodeType.toLowerCase();
44568
44741
  return {
44569
- pathBase: context.pathBase,
44570
- blockId: context.blockId,
44571
- blockKind: context.blockKind,
44572
- blockContent: context.blockContent,
44573
- fragmentRegistry: context.fragmentRegistry,
44574
- previewAuthoring: context.previewAuthoring,
44575
- ...nodeType.toLowerCase() === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
44576
- ...nodeType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
44742
+ ...BLOCK_ID_METADATA_CONSUMERS.has(normalizedType) ? { blockId: context.blockId } : {},
44743
+ ...BLOCK_KIND_METADATA_CONSUMERS.has(normalizedType) ? { blockKind: context.blockKind } : {},
44744
+ ...BLOCK_CONTENT_METADATA_CONSUMERS.has(normalizedType) ? { blockContent: context.blockContent } : {},
44745
+ ...normalizedType === "headersection" ? {
44746
+ pathBase: context.pathBase,
44747
+ fragmentRegistry: context.fragmentRegistry
44748
+ } : {},
44749
+ ...normalizedType === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
44750
+ ...normalizedType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
44577
44751
  };
44578
44752
  }
44579
44753
  /**
@@ -44609,7 +44783,7 @@ function resolveNode(node, context, indexFallback) {
44609
44783
  props = omitHeadingDecorationProps(props);
44610
44784
  const children = resolveChildren(node.children, scopeContext);
44611
44785
  const elementProps = {
44612
- ...props,
44786
+ ...omitRendererMetadataProps(props),
44613
44787
  key: node.key ?? indexFallback,
44614
44788
  ...resolveNodeMetadata(node.type, context)
44615
44789
  };
@@ -45237,7 +45411,7 @@ function generateInputCss({ themeId, theme, inputSystem }) {
45237
45411
  baseInputRules.push("transition: border-color 0.2s ease, box-shadow 0.2s ease");
45238
45412
  const labelSelector = `${rootSelector} .form-label`;
45239
45413
  const labelRules = [];
45240
- labelRules.push(`color: ${rgbColorValue(inputSystem.label.textColorToken)}`);
45414
+ labelRules.push(`color: ${textColorValue(inputSystem.label.textColorToken)}`);
45241
45415
  labelRules.push(`font-weight: ${FONT_WEIGHT_MAP[inputSystem.label.fontWeight]}`);
45242
45416
  labelRules.push(`font-size: ${LABEL_FONT_SIZE_MAP[inputSystem.label.fontSize]}`);
45243
45417
  if (inputSystem.label.textTransform && inputSystem.label.textTransform !== "none") labelRules.push(`text-transform: ${inputSystem.label.textTransform}`);
@@ -48668,7 +48842,7 @@ function pageBlockPosition(index, blockCount) {
48668
48842
  //#endregion
48669
48843
  //#region ../blocks/src/pageRendererContracts.ts
48670
48844
  function buildPageRendererRootRuntime(dataContext) {
48671
- 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 ?? {};
48845
+ 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 ?? {};
48672
48846
  return {
48673
48847
  siteId,
48674
48848
  pageId,
@@ -48677,6 +48851,7 @@ function buildPageRendererRootRuntime(dataContext) {
48677
48851
  previewStage,
48678
48852
  apiBaseUrl,
48679
48853
  portalToken,
48854
+ readAuthority,
48680
48855
  bookingOfferingPresets,
48681
48856
  appointmentServicePathPrefix,
48682
48857
  mailingList,
@@ -51400,46 +51575,42 @@ const whenTransformed = (from, transformId, equals = true) => (node) => ({
51400
51575
  equals
51401
51576
  }
51402
51577
  });
51403
- const logoRow = link({
51578
+ /** Draw whichever site logo suits the surface this row sits on. */
51579
+ const bindChromeLogo = (surface) => bind("content", { transforms: [{
51580
+ id: "layout.chromeLogo",
51581
+ options: { surface }
51582
+ }] });
51583
+ /**
51584
+ * The brand link. The logo is chosen per surface because the open mobile menu
51585
+ * paints its own background, which may be the opposite tone to the header.
51586
+ */
51587
+ const createLogoRow = (surface) => link({
51404
51588
  href: "/",
51405
51589
  className: bindProp("$root.theme.header.logo", {
51406
51590
  transforms: pipe(tx("layout.headerLogoClass")),
51407
51591
  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"
51408
51592
  })
51409
- }, [
51410
- media({ className: bindProp("$root.theme.header.logo", {
51411
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
51412
- fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
51413
- }) }, when("content.logo"), bind("content.logo")),
51414
- stack({ className: "rb-contents" }, [media({ className: bindProp("$root.theme.header.logo", {
51415
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
51416
- fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
51417
- }) }, when("site.logo"), bind("site.logo"))], when("content.logo", { not: true })),
51418
- text({
51419
- as: "strong",
51420
- className: "header-logo-text rb-truncate"
51421
- }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
51422
- ]);
51593
+ }, [media({ className: bindProp("$root.theme.header.logo", {
51594
+ transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
51595
+ fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
51596
+ }) }, when("content.logo"), bindChromeLogo(surface)), text({
51597
+ as: "strong",
51598
+ className: "header-logo-text rb-truncate"
51599
+ }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))]);
51600
+ const logoRow = createLogoRow("header-root");
51423
51601
  const centeredLogoRow = link({
51424
51602
  href: "/",
51425
51603
  className: bindProp("$root.theme.header.logo", {
51426
51604
  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" })),
51427
51605
  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"
51428
51606
  })
51429
- }, [
51430
- media({ className: bindProp("$root.theme.header.logo", {
51431
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
51432
- fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
51433
- }) }, when("content.logo"), bind("content.logo")),
51434
- stack({ className: "rb-contents" }, [media({ className: bindProp("$root.theme.header.logo", {
51435
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
51436
- fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
51437
- }) }, when("site.logo"), bind("site.logo"))], when("content.logo", { not: true })),
51438
- text({
51439
- as: "strong",
51440
- className: "header-logo-text"
51441
- }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
51442
- ]);
51607
+ }, [media({ className: bindProp("$root.theme.header.logo", {
51608
+ transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
51609
+ fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
51610
+ }) }, when("content.logo"), bindChromeLogo("header-root")), text({
51611
+ as: "strong",
51612
+ className: "header-logo-text"
51613
+ }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))]);
51443
51614
  const createNavRow = (className, align = "end") => navRow({
51444
51615
  className: `${className} header-nav-row`,
51445
51616
  align,
@@ -51479,10 +51650,8 @@ const mobileToggleIcon = stack({
51479
51650
  }
51480
51651
  ]);
51481
51652
  const mobileToggleButton = {
51482
- type: "button",
51653
+ type: "headerControl",
51483
51654
  props: {
51484
- type: "button",
51485
- variantId: "",
51486
51655
  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`,
51487
51656
  "aria-label": "Open menu",
51488
51657
  "aria-expanded": "false",
@@ -51492,10 +51661,8 @@ const mobileToggleButton = {
51492
51661
  children: [mobileToggleIcon]
51493
51662
  };
51494
51663
  const mobileOverlayToggleButton = {
51495
- type: "button",
51664
+ type: "headerControl",
51496
51665
  props: {
51497
- type: "button",
51498
- variantId: "",
51499
51666
  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",
51500
51667
  "aria-label": "Open menu",
51501
51668
  "aria-expanded": "false",
@@ -51519,7 +51686,7 @@ const mobileOverlayHeader = inline({
51519
51686
  align: "center",
51520
51687
  justify: "between",
51521
51688
  style: borderColorStyle("border")
51522
- }, [logoRow, mobileOverlayToggleButton]);
51689
+ }, [createLogoRow("header-mobile-panel"), mobileOverlayToggleButton]);
51523
51690
  const mobileOverlayBody = stack({
51524
51691
  className: "rb-flex-1 rb-px-6 rb-py-6",
51525
51692
  gap: "md",
@@ -51707,7 +51874,10 @@ const brandLogo = link({
51707
51874
  options: { base: "rb-h-10 rb-w-auto" }
51708
51875
  }],
51709
51876
  fallback: "rb-h-10 rb-w-auto"
51710
- } } }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content.logo")), text({
51877
+ } } }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content", { transforms: [{
51878
+ id: "layout.chromeLogo",
51879
+ options: { surface: "footer-root" }
51880
+ }] })), text({
51711
51881
  as: "strong",
51712
51882
  className: "footer-logo-text rb-nav-text"
51713
51883
  }, when("module.showTitle", { equals: true }), bind("site.title", { fallback: "Your Site" }))], when("module.kind", { equals: "brand" }));
@@ -58778,6 +58948,7 @@ function blockSessionProps(dataContext) {
58778
58948
  supabaseUrl: dataContext?.supabaseUrl,
58779
58949
  portalToken: dataContext?.portalToken ?? null,
58780
58950
  previewToken: dataContext?.previewToken ?? null,
58951
+ readAuthority: dataContext?.readAuthority,
58781
58952
  stage: dataContext?.previewStage
58782
58953
  };
58783
58954
  }
@@ -61453,6 +61624,12 @@ const containerResponsiveThemeCss = `/*
61453
61624
  :where(.theme-scope) .rb-prose p {
61454
61625
  margin: var(--rt-space-y) 0;
61455
61626
  }
61627
+ :where(.theme-scope) .rb-prose li > p:first-child {
61628
+ margin-top: 0;
61629
+ }
61630
+ :where(.theme-scope) .rb-prose li > p:last-child {
61631
+ margin-bottom: 0;
61632
+ }
61456
61633
  :where(.theme-scope) .rb-prose img {
61457
61634
  display: block;
61458
61635
  max-width: 100%;
@@ -73033,7 +73210,7 @@ function buildPageRouteRenderContext(dataContext) {
73033
73210
  };
73034
73211
  }
73035
73212
  function PageContent(props) {
73036
- const { page, runtimeBoundaries, siteId, resolvedData, bookingOfferingPresets, mailingList, bookingTimeZone, routeMap, pagesByIdentifier, entriesByIdentifier, wrapBlock, registry, blockOverrides, sdkConfig, customBlocks, supabaseUrl, mediaAssets, apiBaseUrl, portalToken, previewToken, dataContext } = props;
73213
+ const { page, runtimeBoundaries, siteId, resolvedData, bookingOfferingPresets, mailingList, bookingTimeZone, routeMap, pagesByIdentifier, entriesByIdentifier, wrapBlock, registry, blockOverrides, sdkConfig, customBlocks, supabaseUrl, mediaAssets, apiBaseUrl, portalToken, previewToken, readAuthority, dataContext } = props;
73037
73214
  const rendererCommonProps = {
73038
73215
  page,
73039
73216
  runtimeBoundaries,
@@ -73043,6 +73220,7 @@ function PageContent(props) {
73043
73220
  apiBaseUrl,
73044
73221
  portalToken,
73045
73222
  previewToken,
73223
+ readAuthority: readAuthority ?? dataContext?.readAuthority,
73046
73224
  resolvedData,
73047
73225
  bookingOfferingPresets: bookingOfferingPresets ?? [],
73048
73226
  mailingList: mailingList ?? dataContext?.mailingList,
@@ -73592,6 +73770,33 @@ function buildLogo(logo, fallbackAlt) {
73592
73770
  if (logo.height != null) result.height = logo.height;
73593
73771
  return result;
73594
73772
  }
73773
+ /**
73774
+ * Build both site logos from layout data. The default header and footer choose
73775
+ * between them by the surface they sit on; custom chrome can do the same.
73776
+ *
73777
+ * @example
73778
+ * ```ts
73779
+ * const logoVariants = buildLogoVariants(siteData.layout, siteData.site.title);
73780
+ * ```
73781
+ */
73782
+ function buildLogoVariants(layout, fallbackAlt) {
73783
+ return {
73784
+ forLightBackgrounds: buildLogo(layout?.logo ?? null, fallbackAlt),
73785
+ forDarkBackgrounds: buildLogo(layout?.logoForDarkBackgrounds ?? null, fallbackAlt)
73786
+ };
73787
+ }
73788
+ /**
73789
+ * Header/footer block content for the site logos. `logo` stays populated with
73790
+ * whichever logo exists so presence checks keep working; `logoVariants` is
73791
+ * what the blocks select from at render.
73792
+ */
73793
+ function buildChromeLogoContent(layout, fallbackAlt) {
73794
+ const logoVariants = buildLogoVariants(layout, fallbackAlt);
73795
+ return {
73796
+ logo: logoVariants.forLightBackgrounds ?? logoVariants.forDarkBackgrounds,
73797
+ logoVariants
73798
+ };
73799
+ }
73595
73800
  //#endregion
73596
73801
  //#region src/rendering/themeAdmission.ts
73597
73802
  const MISSING_SDK_THEME_ERROR_CODE = "missing_sdk_theme";
@@ -75372,10 +75577,10 @@ async function Layout(props) {
75372
75577
  const menuViewModel = buildMenu(navigation, routes, navigationOptions);
75373
75578
  const footerMenuViewModel = buildFooterMenu(navigation, routes, navigationOptions);
75374
75579
  const legalFooterMenuViewModel = buildFooterMenuForRole(navigation, routes, "legal-policy", navigationOptions);
75375
- const logoViewModel = buildLogo(layout.logo ?? null, site.title);
75580
+ const chromeLogoContent = buildChromeLogoContent(layout, site.title);
75376
75581
  const customHeaderData = {
75377
75582
  menu: menuViewModel,
75378
- logo: logoViewModel,
75583
+ ...chromeLogoContent,
75379
75584
  site,
75380
75585
  routes
75381
75586
  };
@@ -75383,7 +75588,7 @@ async function Layout(props) {
75383
75588
  menu: menuViewModel,
75384
75589
  footerMenu: footerMenuViewModel,
75385
75590
  legalFooterMenu: legalFooterMenuViewModel,
75386
- logo: logoViewModel,
75591
+ ...chromeLogoContent,
75387
75592
  site,
75388
75593
  routes
75389
75594
  };
@@ -75440,13 +75645,13 @@ async function Layout(props) {
75440
75645
  };
75441
75646
  const headerViewModelOverrides = {
75442
75647
  ...sharedViewModelOverrides,
75443
- content: { logo: logoViewModel }
75648
+ content: chromeLogoContent
75444
75649
  };
75445
75650
  const footerViewModelOverrides = {
75446
75651
  ...sharedViewModelOverrides,
75447
75652
  content: {
75448
75653
  ...layout.footer,
75449
- logo: logoViewModel
75654
+ ...chromeLogoContent
75450
75655
  }
75451
75656
  };
75452
75657
  let headerElement = null;
@@ -79491,13 +79696,14 @@ async function loadStandaloneBlockData({ blockKind, blockId, siteId, pageId, pre
79491
79696
  previewStage
79492
79697
  }, client))[blockId];
79493
79698
  }
79494
- function buildStandaloneBlockViewModel({ siteId, pageId, previewStage, apiBaseUrl, portalToken, routeMap, pagesByIdentifier, entriesByIdentifier }) {
79699
+ function buildStandaloneBlockViewModel({ siteId, pageId, previewStage, apiBaseUrl, portalToken, readAuthority, routeMap, pagesByIdentifier, entriesByIdentifier }) {
79495
79700
  return { $root: {
79496
79701
  siteId: siteId ?? null,
79497
79702
  pageId: pageId ?? null,
79498
79703
  previewStage: previewStage ?? "published",
79499
79704
  apiBaseUrl: apiBaseUrl ?? null,
79500
79705
  portalToken: portalToken ?? null,
79706
+ readAuthority,
79501
79707
  ...routeMap ? { routes: routeMap } : {},
79502
79708
  ...pagesByIdentifier ? { pagesByIdentifier } : {},
79503
79709
  ...entriesByIdentifier ? { entriesByIdentifier } : {}