@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
@@ -24685,6 +24712,47 @@ const layoutTransforms = [
24685
24712
  footerLogoMediaClassTransform,
24686
24713
  footerLogoTextVisibleTransform
24687
24714
  ];
24715
+ const chromeLogoSchema = z$1.object({ surface: z$1.enum([
24716
+ "header-root",
24717
+ "header-mobile-panel",
24718
+ "footer-root"
24719
+ ]) });
24720
+ /** The brand foreground shares the logo's surface; navigation may own a separate capsule. */
24721
+ function chromeSurfaceTextToken(surface, theme, palette) {
24722
+ switch (surface) {
24723
+ case "header-root": {
24724
+ const header = theme.header;
24725
+ const foreground = resolveHeaderRootForeground(header, palette, resolveHeaderVisualStyles(header).isTransparent);
24726
+ return foreground.kind === "known" ? foreground.roles.text : resolveHeaderLeafTextColor(header);
24727
+ }
24728
+ case "header-mobile-panel": return theme.header?.dropdownStyle?.textColor ?? "text";
24729
+ case "footer-root": {
24730
+ const foreground = resolveFooterRootForeground(theme.footer, palette);
24731
+ return foreground.kind === "known" ? foreground.roles.text : void 0;
24732
+ }
24733
+ }
24734
+ }
24735
+ function readChromeTheme(viewModel) {
24736
+ return asPartialObject(asPartialObject(viewModel?.["$root"])?.theme) ?? {};
24737
+ }
24738
+ function resolveChromeSurfaceTone(surface, context) {
24739
+ return surfaceToneFromForegroundToken(context.theme.palette, chromeSurfaceTextToken(surface, readChromeTheme(context.viewModel), context.theme.palette));
24740
+ }
24741
+ const chromeLogoTransforms = [{
24742
+ id: "layout.chromeLogo",
24743
+ kind: "formatter",
24744
+ summary: "Select the light- or dark-background site logo for a header or footer surface",
24745
+ schema: chromeLogoSchema,
24746
+ run: (value, options, context) => {
24747
+ const content = asPartialObject(value);
24748
+ const variants = asPartialObject(content?.logoVariants);
24749
+ if (!variants) return content?.logo ?? null;
24750
+ return selectLogoVariant(resolveChromeSurfaceTone(options.surface, context), {
24751
+ forLightBackgrounds: variants.forLightBackgrounds ?? null,
24752
+ forDarkBackgrounds: variants.forDarkBackgrounds ?? null
24753
+ });
24754
+ }
24755
+ }];
24688
24756
  //#endregion
24689
24757
  //#region ../blocks/src/system/transforms/registry/ui.ts
24690
24758
  const joinClasses$2 = (parts) => parts.filter((part) => typeof part === "string" && part.trim().length > 0).join(" ").replace(/\s+/g, " ").trim();
@@ -27059,6 +27127,33 @@ function normalizeEventCalendarDisplayMode$1(input) {
27059
27127
  if (isEventCalendarDisplayMode(input.variant)) return input.variant;
27060
27128
  return isEventCalendarDisplayMode(input.displayMode) ? input.displayMode : void 0;
27061
27129
  }
27130
+ /** One closed authority for the projections required by each rendered mode. */
27131
+ function resolveEventCalendarReadPlan(input) {
27132
+ const mode = normalizeEventCalendarDisplayMode$1(input) ?? "combined";
27133
+ switch (mode) {
27134
+ case "combined": return {
27135
+ mode,
27136
+ jobs: "both",
27137
+ readProfile: "listing-card"
27138
+ };
27139
+ case "list": return {
27140
+ mode,
27141
+ jobs: "list",
27142
+ readProfile: "listing-card"
27143
+ };
27144
+ case "calendar": return {
27145
+ mode,
27146
+ jobs: "calendar",
27147
+ readProfile: "listing-card"
27148
+ };
27149
+ case "timetable":
27150
+ case "week-board": return {
27151
+ mode,
27152
+ jobs: "calendar",
27153
+ readProfile: "timetable"
27154
+ };
27155
+ }
27156
+ }
27062
27157
  function isEventCalendarDefaultView(value) {
27063
27158
  return typeof value === "string" && eventCalendarDefaultViewValues.includes(value);
27064
27159
  }
@@ -28116,8 +28211,7 @@ function normalizeEventStaffMemberId(value) {
28116
28211
  //#endregion
28117
28212
  //#region ../blocks/src/system/blocks/events/shared/calendarWindow.ts
28118
28213
  function resolveCalendarReadProfile(content) {
28119
- const mode = normalizeEventCalendarDisplayMode$1(content);
28120
- return mode === "timetable" || mode === "week-board" ? "timetable" : "listing-card";
28214
+ return resolveEventCalendarReadPlan(content).readProfile;
28121
28215
  }
28122
28216
  /** Runtime picker sentinels and bound loader IDs must describe the same query. */
28123
28217
  function normalizeCalendarFilterId(value) {
@@ -28261,8 +28355,8 @@ const defaultTransforms = createTransformRegistry([
28261
28355
  summary: "Choose the read projection required by the calendar display mode",
28262
28356
  schema: z$1.object({ job: z$1.enum(["list", "calendar"]) }),
28263
28357
  run(value, options) {
28264
- const mode = normalizeEventCalendarDisplayMode$1(asPartialObject(value) ?? {}) ?? "combined";
28265
- return options.job === "calendar" ? mode !== "list" : mode === "list" || mode === "combined";
28358
+ const plan = resolveEventCalendarReadPlan(asPartialObject(value) ?? {});
28359
+ return plan.jobs === "both" || plan.jobs === options.job;
28266
28360
  }
28267
28361
  },
28268
28362
  {
@@ -28275,6 +28369,7 @@ const defaultTransforms = createTransformRegistry([
28275
28369
  },
28276
28370
  ...formattingTransforms,
28277
28371
  ...layoutTransforms,
28372
+ ...chromeLogoTransforms,
28278
28373
  ...uiTransforms,
28279
28374
  ...mediaTransforms,
28280
28375
  ...backgroundTransforms,
@@ -28430,12 +28525,12 @@ function Grid({ as: Comp = "div", cols, userColumns, gap = "md", className, styl
28430
28525
  }
28431
28526
  //#endregion
28432
28527
  //#region ../blocks/src/system/runtime/nodes/layout.tsx
28433
- const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Section, { ...props });
28434
- const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
28435
- const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
28436
- const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
28437
- const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
28438
- const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
28528
+ const SectionNode = (props) => /* @__PURE__ */ jsx(Section, { ...props });
28529
+ const StackNode = (props) => /* @__PURE__ */ jsx(Stack, { ...props });
28530
+ const InlineNode = (props) => /* @__PURE__ */ jsx(Inline, { ...props });
28531
+ const GridNode = (props) => /* @__PURE__ */ jsx(Grid, { ...props });
28532
+ const DivNode = (props) => /* @__PURE__ */ jsx("div", { ...props });
28533
+ const FigureNode = (props) => /* @__PURE__ */ jsx("figure", { ...props });
28439
28534
  //#endregion
28440
28535
  //#region ../path-utils/src/index.ts
28441
28536
  const PATH_SEPARATOR_REGEX$1 = /\./g;
@@ -28673,6 +28768,234 @@ function Text$1({ as: Comp = "span", children, className = "", path, maxLength:
28673
28768
  });
28674
28769
  }
28675
28770
  //#endregion
28771
+ //#region ../logger/src/sanitize.ts
28772
+ const DEFAULT_MAX_STRING_LENGTH = 2e3;
28773
+ const STRUCTURED_KEYS = /* @__PURE__ */ new Set([
28774
+ "source",
28775
+ "service",
28776
+ "function",
28777
+ "environment",
28778
+ "deployment",
28779
+ "region",
28780
+ "release",
28781
+ "requestId",
28782
+ "correlationId",
28783
+ "method",
28784
+ "route",
28785
+ "path",
28786
+ "search",
28787
+ "host",
28788
+ "url",
28789
+ "userId",
28790
+ "adminUserId",
28791
+ "orgId",
28792
+ "siteId",
28793
+ "siteDomainId",
28794
+ "domainOperationSubsystem",
28795
+ "domainOperation",
28796
+ "domainOperationStage",
28797
+ "domainOperationOutcome",
28798
+ "domainOperationDomain",
28799
+ "domainOperationProvider",
28800
+ "domainOperationError",
28801
+ "domainOperationMetadata",
28802
+ "durationMs",
28803
+ "duration",
28804
+ "status",
28805
+ "statusCode",
28806
+ "statusText",
28807
+ "errorDetails",
28808
+ "errorName",
28809
+ "errorMessage",
28810
+ "errorStack",
28811
+ "context"
28812
+ ]);
28813
+ function truncate(input, maxLength) {
28814
+ if (input.length <= maxLength) return input;
28815
+ return input.slice(0, maxLength) + "…";
28816
+ }
28817
+ function safeStringify(value, maxLength) {
28818
+ try {
28819
+ return truncate(JSON.stringify(value), maxLength);
28820
+ } catch {
28821
+ return truncate(String(value), maxLength);
28822
+ }
28823
+ }
28824
+ function toScalar(value, maxLength) {
28825
+ if (value == null) return null;
28826
+ if (typeof value === "string") return truncate(value, maxLength);
28827
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
28828
+ if (typeof value === "boolean") return value;
28829
+ if (value instanceof Date) return value.toISOString();
28830
+ if (value instanceof Error) return truncate(`${value.name}: ${value.message}`, maxLength);
28831
+ return safeStringify(value, maxLength);
28832
+ }
28833
+ function sanitizeV2(fields, maxStringLength) {
28834
+ const allowed = {};
28835
+ const extra = {};
28836
+ for (const [key, value] of Object.entries(fields)) {
28837
+ if (value === void 0) continue;
28838
+ if (STRUCTURED_KEYS.has(key)) {
28839
+ allowed[key] = toScalar(value, maxStringLength);
28840
+ continue;
28841
+ }
28842
+ extra[key] = value;
28843
+ }
28844
+ if (Object.keys(extra).length > 0) allowed.context = safeStringify(extra, maxStringLength);
28845
+ return allowed;
28846
+ }
28847
+ function sanitizeLogFields(fields, options) {
28848
+ if (fields === void 0 || Object.keys(fields).length === 0) return void 0;
28849
+ return sanitizeV2(fields, options?.maxStringLength ?? DEFAULT_MAX_STRING_LENGTH);
28850
+ }
28851
+ //#endregion
28852
+ //#region ../logger/src/console.ts
28853
+ function formatLog(level, message, fields) {
28854
+ const entry = {
28855
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
28856
+ level,
28857
+ message,
28858
+ ...sanitizeLogFields(fields)
28859
+ };
28860
+ return JSON.stringify(entry);
28861
+ }
28862
+ function createLogger(baseFields = {}) {
28863
+ return {
28864
+ debug: (msg, fields) => console.debug(formatLog("debug", msg, {
28865
+ ...baseFields,
28866
+ ...fields
28867
+ })),
28868
+ info: (msg, fields) => console.info(formatLog("info", msg, {
28869
+ ...baseFields,
28870
+ ...fields
28871
+ })),
28872
+ warn: (msg, fields) => console.warn(formatLog("warn", msg, {
28873
+ ...baseFields,
28874
+ ...fields
28875
+ })),
28876
+ error: (msg, fields) => console.error(formatLog("error", msg, {
28877
+ ...baseFields,
28878
+ ...fields
28879
+ })),
28880
+ withFields: (fields) => createLogger({
28881
+ ...baseFields,
28882
+ ...fields
28883
+ })
28884
+ };
28885
+ }
28886
+ const logger = createLogger();
28887
+ //#endregion
28888
+ //#region ../blocks/src/system/runtime/nodes/richText-coerce.ts
28889
+ function parseRichTextDoc(value) {
28890
+ const parsed = RichTextDocSchema.safeParse(value);
28891
+ if (parsed.success) return {
28892
+ kind: "valid",
28893
+ doc: parsed.data
28894
+ };
28895
+ return {
28896
+ kind: "invalid",
28897
+ issues: parsed.error.issues.map((issue) => ({
28898
+ path: issue.path.map((segment) => String(segment)),
28899
+ message: issue.message
28900
+ }))
28901
+ };
28902
+ }
28903
+ function coerceRichTextDoc(value, source) {
28904
+ const parsed = parseRichTextDoc(value);
28905
+ if (parsed.kind === "valid") return parsed.doc;
28906
+ if (value !== null && value !== void 0) logger.warn("blocks:rich-text:invalid-document", {
28907
+ source,
28908
+ issues: parsed.issues.slice(0, 3)
28909
+ });
28910
+ return null;
28911
+ }
28912
+ //#endregion
28913
+ //#region ../blocks/src/system/runtime/nodes/renderInlineText.tsx
28914
+ function renderInlineText(value) {
28915
+ return value.map((run, index) => renderRun(run, index));
28916
+ }
28917
+ function renderRun(run, key) {
28918
+ return (run.marks ?? []).reduceRight((child, mark, index) => renderMark(mark, `${String(key)}-${index}`, child), run.text);
28919
+ }
28920
+ function renderMark(mark, key, child) {
28921
+ switch (mark.kind) {
28922
+ case "strong": return /* @__PURE__ */ jsx("strong", { children: child }, key);
28923
+ case "emphasis": return /* @__PURE__ */ jsx("em", { children: child }, key);
28924
+ case "accent": return /* @__PURE__ */ jsx("span", {
28925
+ className: `rb-inline-text-accent rb-inline-text-accent-${mark.tone}`,
28926
+ children: child
28927
+ }, key);
28928
+ case "highlight": return /* @__PURE__ */ jsx("span", {
28929
+ className: `rb-inline-text-highlight rb-inline-text-highlight-${mark.tone}`,
28930
+ children: child
28931
+ }, key);
28932
+ }
28933
+ }
28934
+ //#endregion
28935
+ //#region ../blocks/src/system/runtime/nodes/spinner.tsx
28936
+ function resolveColorStyle(color) {
28937
+ switch (color) {
28938
+ case void 0: return;
28939
+ case "inherit": return { color: "inherit" };
28940
+ case "foreground": return { color: "rgb(var(--tb-foreground))" };
28941
+ case "text": return { color: "rgb(var(--tb-text))" };
28942
+ default: return;
28943
+ }
28944
+ }
28945
+ function SpinnerNode({ className, size = "md", color, strokeWidth = 3, srLabel, style, ...rest }) {
28946
+ const hasExplicitAriaLabel = typeof rest["aria-label"] === "string" && rest["aria-label"].trim().length > 0;
28947
+ const accessibilityProps = srLabel ? {
28948
+ role: "status",
28949
+ "aria-live": "polite"
28950
+ } : hasExplicitAriaLabel ? {} : { "aria-hidden": true };
28951
+ const trackStroke = color === "inherit" ? "currentColor" : "var(--rb-spinner-track-color)";
28952
+ const trackOpacity = color === "inherit" ? .25 : 1;
28953
+ return /* @__PURE__ */ jsxs("span", {
28954
+ ...accessibilityProps,
28955
+ className: clsx("rb-spinner", size ? `rb-spinner--${size}` : null, color === "inherit" ? "rb-spinner--inherit" : null, className),
28956
+ style: {
28957
+ ...resolveColorStyle(color),
28958
+ ...style ?? {}
28959
+ },
28960
+ ...rest,
28961
+ children: [/* @__PURE__ */ jsxs("svg", {
28962
+ viewBox: "0 0 24 24",
28963
+ fill: "none",
28964
+ "aria-hidden": "true",
28965
+ children: [/* @__PURE__ */ jsx("circle", {
28966
+ cx: "12",
28967
+ cy: "12",
28968
+ r: "10",
28969
+ stroke: trackStroke,
28970
+ strokeWidth,
28971
+ opacity: trackOpacity
28972
+ }), /* @__PURE__ */ jsx("path", {
28973
+ d: "M12 2a10 10 0 0 1 10 10",
28974
+ stroke: "currentColor",
28975
+ strokeWidth,
28976
+ strokeLinecap: "round"
28977
+ })]
28978
+ }), srLabel ? /* @__PURE__ */ jsx("span", {
28979
+ className: "rb-sr-only",
28980
+ children: srLabel
28981
+ }) : null]
28982
+ });
28983
+ }
28984
+ //#endregion
28985
+ //#region ../blocks/src/system/runtime/nodes/buttonAffordance.ts
28986
+ function normalize(value) {
28987
+ const trimmed = typeof value === "string" ? value.trim() : "";
28988
+ return trimmed.length > 0 ? trimmed : null;
28989
+ }
28990
+ /**
28991
+ * Resolve the node-authored trailing affordance, or `null` when no icon exists.
28992
+ */
28993
+ function resolveButtonAffordance(input) {
28994
+ const nodeIcon = normalize(input.trailingIcon);
28995
+ if (nodeIcon) return { iconId: nodeIcon };
28996
+ return null;
28997
+ }
28998
+ //#endregion
28676
28999
  //#region ../blocks/src/system/icons/svg.tsx
28677
29000
  function createIcon(displayName, children) {
28678
29001
  const Icon = ({ size = "1em", strokeWidth = 2, title, className, focusable = false, role, ...props }) => /* @__PURE__ */ jsxs("svg", {
@@ -29775,186 +30098,105 @@ function getIconComponent(name) {
29775
30098
  return getCtaIconComponent(name) ?? getSemanticIconComponent(name) ?? getSocialIconComponent(name);
29776
30099
  }
29777
30100
  //#endregion
29778
- //#region ../blocks/src/system/runtime/nodes/buttonAffordance.ts
29779
- function normalize(value) {
29780
- const trimmed = typeof value === "string" ? value.trim() : "";
29781
- return trimmed.length > 0 ? trimmed : null;
29782
- }
29783
- /**
29784
- * Resolve the node-authored trailing affordance, or `null` when no icon exists.
29785
- */
29786
- function resolveButtonAffordance(input) {
29787
- const nodeIcon = normalize(input.trailingIcon);
29788
- if (nodeIcon) return { iconId: nodeIcon };
29789
- return null;
29790
- }
29791
- //#endregion
29792
- //#region ../logger/src/sanitize.ts
29793
- const DEFAULT_MAX_STRING_LENGTH = 2e3;
29794
- const STRUCTURED_KEYS = /* @__PURE__ */ new Set([
29795
- "source",
29796
- "service",
29797
- "function",
29798
- "environment",
29799
- "deployment",
29800
- "region",
29801
- "release",
29802
- "requestId",
29803
- "correlationId",
29804
- "method",
29805
- "route",
29806
- "path",
29807
- "search",
29808
- "host",
29809
- "url",
29810
- "userId",
29811
- "adminUserId",
29812
- "orgId",
29813
- "siteId",
29814
- "siteDomainId",
29815
- "domainOperationSubsystem",
29816
- "domainOperation",
29817
- "domainOperationStage",
29818
- "domainOperationOutcome",
29819
- "domainOperationDomain",
29820
- "domainOperationProvider",
29821
- "domainOperationError",
29822
- "domainOperationMetadata",
29823
- "durationMs",
29824
- "duration",
29825
- "status",
29826
- "statusCode",
29827
- "statusText",
29828
- "errorDetails",
29829
- "errorName",
29830
- "errorMessage",
29831
- "errorStack",
29832
- "context"
29833
- ]);
29834
- function truncate(input, maxLength) {
29835
- if (input.length <= maxLength) return input;
29836
- return input.slice(0, maxLength) + "…";
29837
- }
29838
- function safeStringify(value, maxLength) {
29839
- try {
29840
- return truncate(JSON.stringify(value), maxLength);
29841
- } catch {
29842
- return truncate(String(value), maxLength);
29843
- }
29844
- }
29845
- function toScalar(value, maxLength) {
29846
- if (value == null) return null;
29847
- if (typeof value === "string") return truncate(value, maxLength);
29848
- if (typeof value === "number") return Number.isFinite(value) ? value : null;
29849
- if (typeof value === "boolean") return value;
29850
- if (value instanceof Date) return value.toISOString();
29851
- if (value instanceof Error) return truncate(`${value.name}: ${value.message}`, maxLength);
29852
- return safeStringify(value, maxLength);
29853
- }
29854
- function sanitizeV2(fields, maxStringLength) {
29855
- const allowed = {};
29856
- const extra = {};
29857
- for (const [key, value] of Object.entries(fields)) {
29858
- if (value === void 0) continue;
29859
- if (STRUCTURED_KEYS.has(key)) {
29860
- allowed[key] = toScalar(value, maxStringLength);
29861
- continue;
29862
- }
29863
- extra[key] = value;
29864
- }
29865
- if (Object.keys(extra).length > 0) allowed.context = safeStringify(extra, maxStringLength);
29866
- return allowed;
29867
- }
29868
- function sanitizeLogFields(fields, options) {
29869
- if (fields === void 0 || Object.keys(fields).length === 0) return void 0;
29870
- return sanitizeV2(fields, options?.maxStringLength ?? DEFAULT_MAX_STRING_LENGTH);
30101
+ //#region ../blocks/src/system/runtime/shared/components/ThemedButton.tsx
30102
+ function themedButtonClasses(variant, size, extraClassName) {
30103
+ return [
30104
+ ...themeButtonVariantClassNames(variant),
30105
+ themeButtonSizeClassName(size),
30106
+ extraClassName
30107
+ ].filter(Boolean).join(" ");
29871
30108
  }
29872
- //#endregion
29873
- //#region ../logger/src/console.ts
29874
- function formatLog(level, message, fields) {
29875
- const entry = {
29876
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
29877
- level,
29878
- message,
29879
- ...sanitizeLogFields(fields)
29880
- };
29881
- return JSON.stringify(entry);
30109
+ function ThemedButtonLabel(props) {
30110
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
30111
+ props.pending ? /* @__PURE__ */ jsx(SpinnerNode, {
30112
+ size: props.pending.spinnerSize ?? "sm",
30113
+ color: "inherit",
30114
+ className: props.pending.spinnerClassName ?? "rb-mr-2",
30115
+ srLabel: props.pending.srLabel
30116
+ }) : null,
30117
+ props.labelClassName ? /* @__PURE__ */ jsx("span", {
30118
+ className: props.labelClassName,
30119
+ children: props.pending?.label ?? props.label
30120
+ }) : props.pending?.label ?? props.label,
30121
+ props.screenReaderSuffix ? /* @__PURE__ */ jsx("span", {
30122
+ className: "rb-sr-only",
30123
+ children: props.screenReaderSuffix
30124
+ }) : null
30125
+ ] });
30126
+ return props.pending?.contentClassName ? /* @__PURE__ */ jsx("span", {
30127
+ className: props.pending.contentClassName,
30128
+ children: content
30129
+ }) : content;
29882
30130
  }
29883
- function createLogger(baseFields = {}) {
29884
- return {
29885
- debug: (msg, fields) => console.debug(formatLog("debug", msg, {
29886
- ...baseFields,
29887
- ...fields
29888
- })),
29889
- info: (msg, fields) => console.info(formatLog("info", msg, {
29890
- ...baseFields,
29891
- ...fields
29892
- })),
29893
- warn: (msg, fields) => console.warn(formatLog("warn", msg, {
29894
- ...baseFields,
29895
- ...fields
29896
- })),
29897
- error: (msg, fields) => console.error(formatLog("error", msg, {
29898
- ...baseFields,
29899
- ...fields
29900
- })),
29901
- withFields: (fields) => createLogger({
29902
- ...baseFields,
29903
- ...fields
30131
+ function ThemedButton({ variant, size, extraClassName, screenReaderSuffix, labelClassName, pending, label, ...buttonProps }) {
30132
+ return /* @__PURE__ */ jsx("button", {
30133
+ ...buttonProps,
30134
+ className: themedButtonClasses(variant, size, extraClassName),
30135
+ children: /* @__PURE__ */ jsx(ThemedButtonLabel, {
30136
+ label,
30137
+ pending,
30138
+ screenReaderSuffix,
30139
+ labelClassName
29904
30140
  })
29905
- };
29906
- }
29907
- const logger = createLogger();
29908
- //#endregion
29909
- //#region ../blocks/src/system/runtime/nodes/richText-coerce.ts
29910
- function parseRichTextDoc(value) {
29911
- const parsed = RichTextDocSchema.safeParse(value);
29912
- if (parsed.success) return {
29913
- kind: "valid",
29914
- doc: parsed.data
29915
- };
29916
- return {
29917
- kind: "invalid",
29918
- issues: parsed.error.issues.map((issue) => ({
29919
- path: issue.path.map((segment) => String(segment)),
29920
- message: issue.message
29921
- }))
29922
- };
29923
- }
29924
- function coerceRichTextDoc(value, source) {
29925
- const parsed = parseRichTextDoc(value);
29926
- if (parsed.kind === "valid") return parsed.doc;
29927
- if (value !== null && value !== void 0) logger.warn("blocks:rich-text:invalid-document", {
29928
- source,
29929
- issues: parsed.issues.slice(0, 3)
29930
30141
  });
29931
- return null;
29932
30142
  }
29933
- //#endregion
29934
- //#region ../blocks/src/system/runtime/nodes/renderInlineText.tsx
29935
- function renderInlineText(value) {
29936
- return value.map((run, index) => renderRun(run, index));
30143
+ function ThemedButtonLink({ variant, size, extraClassName, screenReaderSuffix, labelClassName, label, ...anchorProps }) {
30144
+ return /* @__PURE__ */ jsx("a", {
30145
+ ...anchorProps,
30146
+ className: themedButtonClasses(variant, size, extraClassName),
30147
+ children: /* @__PURE__ */ jsx(ThemedButtonLabel, {
30148
+ label,
30149
+ screenReaderSuffix,
30150
+ labelClassName
30151
+ })
30152
+ });
29937
30153
  }
29938
- function renderRun(run, key) {
29939
- return (run.marks ?? []).reduceRight((child, mark, index) => renderMark(mark, `${String(key)}-${index}`, child), run.text);
30154
+ /** Fixed semantic download affordance; callers cannot supply arbitrary icon children. */
30155
+ function ThemedDownloadLink({ variant, size, extraClassName, label, screenReaderSuffix, labelClassName, ...anchorProps }) {
30156
+ return /* @__PURE__ */ jsxs("a", {
30157
+ ...anchorProps,
30158
+ className: themedButtonClasses(variant, size, extraClassName),
30159
+ children: [/* @__PURE__ */ jsx(DownloadIcon, {
30160
+ "aria-hidden": "true",
30161
+ size: 24
30162
+ }), /* @__PURE__ */ jsx(ThemedButtonLabel, {
30163
+ label,
30164
+ screenReaderSuffix,
30165
+ labelClassName
30166
+ })]
30167
+ });
29940
30168
  }
29941
- function renderMark(mark, key, child) {
29942
- switch (mark.kind) {
29943
- case "strong": return /* @__PURE__ */ jsx("strong", { children: child }, key);
29944
- case "emphasis": return /* @__PURE__ */ jsx("em", { children: child }, key);
29945
- case "accent": return /* @__PURE__ */ jsx("span", {
29946
- className: `rb-inline-text-accent rb-inline-text-accent-${mark.tone}`,
29947
- children: child
29948
- }, key);
29949
- case "highlight": return /* @__PURE__ */ jsx("span", {
29950
- className: `rb-inline-text-highlight rb-inline-text-highlight-${mark.tone}`,
29951
- children: child
29952
- }, key);
29953
- }
30169
+ /** Boundary for authored button nodes and their registry-backed trailing icon. */
30170
+ function ThemedAuthoredButton({ label, href, variant, size, extraClassName, disabled, type = "button", target, rel, ariaLabel, dataTestId, trailingIcon, onClick }) {
30171
+ const affordance = resolveButtonAffordance({ trailingIcon });
30172
+ const Icon = affordance ? getIconComponent(affordance.iconId) : null;
30173
+ const className = variant ? themedButtonClasses(variant, size, Icon ? [extraClassName, themeButtonExtraClassesWithTrailingIcon()].filter(Boolean).join(" ") : extraClassName) : extraClassName ?? void 0;
30174
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [label, Icon ? /* @__PURE__ */ jsx(Icon, {
30175
+ "aria-hidden": true,
30176
+ className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
30177
+ }) : null] });
30178
+ return href ? /* @__PURE__ */ jsx("a", {
30179
+ href,
30180
+ target,
30181
+ rel,
30182
+ "aria-label": ariaLabel,
30183
+ "data-testid": dataTestId,
30184
+ className,
30185
+ onClick,
30186
+ children: content
30187
+ }) : /* @__PURE__ */ jsx("button", {
30188
+ type,
30189
+ disabled,
30190
+ "aria-label": ariaLabel,
30191
+ "data-testid": dataTestId,
30192
+ className,
30193
+ onClick,
30194
+ children: content
30195
+ });
29954
30196
  }
29955
30197
  //#endregion
29956
30198
  //#region ../blocks/src/system/runtime/nodes/basic.tsx
29957
- const TextNode = ({ value, children, blockId: _blockId, blockKind: _blockKind, blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, inlineTextFallbackPath, ...rest }) => {
30199
+ const TextNode = ({ value, children, blockContent, inlineTextFallbackPath, ...rest }) => {
29958
30200
  const inlineText = parseInlineTextFromUnknown(value);
29959
30201
  if (inlineText.ok && !isInlineTextEmpty(inlineText.value)) return /* @__PURE__ */ jsx(Text$1, {
29960
30202
  ...rest,
@@ -29975,34 +30217,21 @@ function readStringPath(source, path) {
29975
30217
  const value = getAtPath(source, path);
29976
30218
  return typeof value === "string" ? value : null;
29977
30219
  }
29978
- const RichTextNode = ({ value, blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...rest }) => {
30220
+ const RichTextNode = ({ value, blockKind, ...rest }) => {
29979
30221
  return /* @__PURE__ */ jsx(RichText$2, {
29980
- doc: coerceRichTextDoc(value, `block-runtime:${_blockKind ?? "unknown"}:${rest.path ?? "richText"}`) ?? void 0,
30222
+ doc: coerceRichTextDoc(value, `block-runtime:${blockKind ?? "unknown"}:${rest.path ?? "richText"}`) ?? void 0,
29981
30223
  ...rest
29982
30224
  });
29983
30225
  };
29984
- /**
29985
- * Render the resolved trailing affordance icon using the button's foreground.
29986
- */
29987
- function renderTrailingAffordanceIcon(affordance) {
29988
- if (!affordance) return null;
29989
- const Icon = getIconComponent(affordance.iconId);
29990
- if (!Icon) return null;
29991
- return /* @__PURE__ */ jsx(Icon, {
29992
- "aria-hidden": true,
29993
- className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
29994
- });
29995
- }
29996
30226
  function isMissingRequiredLink(linkRequired, resolvedHref) {
29997
30227
  return linkRequired && resolvedHref.length === 0;
29998
30228
  }
29999
- 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 }) => {
30229
+ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md", disabled, type = "button", target, rel, linkRequired = false, trailingIcon, onClick, className, ...rest }) => {
30000
30230
  const content = value ?? children;
30001
30231
  if (!content) {
30002
30232
  console.warn("[ButtonNode] No content to render - value and children are both empty");
30003
30233
  return null;
30004
30234
  }
30005
- const affordanceIcon = renderTrailingAffordanceIcon(resolveButtonAffordance({ trailingIcon }));
30006
30235
  const resolvedHref = typeof href === "string" ? href.trim() : "";
30007
30236
  if (isMissingRequiredLink(linkRequired, resolvedHref)) {
30008
30237
  if (process.env.NODE_ENV === "development") console.warn("[ButtonNode] Missing href for link-required button");
@@ -30013,28 +30242,23 @@ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md",
30013
30242
  console.error("[ButtonNode] Invalid button variant", { variantId });
30014
30243
  return null;
30015
30244
  }
30016
- const combinedClassName = resolvedVariantId ? (affordanceIcon ? themeButtonClassNameWithTrailingIcon : themeButtonClassName)({
30017
- variant: resolvedVariantId,
30018
- size,
30019
- extraClassName: className
30020
- }) : className;
30021
- if (resolvedHref) return /* @__PURE__ */ jsxs("a", {
30022
- href: resolvedHref,
30245
+ return /* @__PURE__ */ jsx(ThemedAuthoredButton, {
30246
+ label: content,
30247
+ href: resolvedHref || void 0,
30023
30248
  target,
30024
30249
  rel,
30025
- className: combinedClassName,
30026
- ...rest,
30027
- children: [content, affordanceIcon]
30028
- });
30029
- return /* @__PURE__ */ jsxs("button", {
30030
- type,
30250
+ variant: resolvedVariantId ?? null,
30251
+ size,
30031
30252
  disabled,
30032
- className: combinedClassName,
30033
- ...rest,
30034
- children: [content, affordanceIcon]
30253
+ type,
30254
+ trailingIcon,
30255
+ onClick,
30256
+ extraClassName: className,
30257
+ ariaLabel: rest["aria-label"],
30258
+ dataTestId: rest["data-testid"]
30035
30259
  });
30036
30260
  };
30037
- const LinkNode = ({ href, children, className, target, rel, linkRequired = false, blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...rest }) => {
30261
+ const LinkNode = ({ href, children, className, target, rel, linkRequired = false, ...rest }) => {
30038
30262
  if (!children) return null;
30039
30263
  const resolvedHref = typeof href === "string" ? href.trim() : "";
30040
30264
  if (resolvedHref.length === 0) {
@@ -30468,18 +30692,13 @@ function FileDownloadNode({ value, title, description, buttonLabel, buttonVarian
30468
30692
  })
30469
30693
  ]
30470
30694
  })]
30471
- }), /* @__PURE__ */ jsxs("a", {
30695
+ }), /* @__PURE__ */ jsx(ThemedDownloadLink, {
30472
30696
  href,
30473
30697
  download: filename,
30474
- className: themeButtonClassName({
30475
- variant,
30476
- size: "md",
30477
- extraClassName: "rb-inline-flex rb-shrink-0 rb-items-center rb-justify-center rb-gap-2"
30478
- }),
30479
- children: [/* @__PURE__ */ jsx(DownloadIcon, {
30480
- "aria-hidden": "true",
30481
- size: 24
30482
- }), label]
30698
+ variant,
30699
+ size: "md",
30700
+ extraClassName: "rb-inline-flex rb-shrink-0 rb-items-center rb-justify-center rb-gap-2",
30701
+ label
30483
30702
  })]
30484
30703
  })
30485
30704
  })
@@ -31059,53 +31278,19 @@ const HeaderSectionNode = ({ blockId, children, className, runtime, "data-previe
31059
31278
  };
31060
31279
  var header_section_server_default = markEditableSurfaceForwarding(HeaderSectionNode);
31061
31280
  //#endregion
31062
- //#region ../blocks/src/system/runtime/nodes/spinner.tsx
31063
- function resolveColorStyle(color) {
31064
- switch (color) {
31065
- case void 0: return;
31066
- case "inherit": return { color: "inherit" };
31067
- case "foreground": return { color: "rgb(var(--tb-foreground))" };
31068
- case "text": return { color: "rgb(var(--tb-text))" };
31069
- default: return;
31070
- }
31071
- }
31072
- function SpinnerNode({ className, size = "md", color, strokeWidth = 3, srLabel, style, ...rest }) {
31073
- const hasExplicitAriaLabel = typeof rest["aria-label"] === "string" && rest["aria-label"].trim().length > 0;
31074
- const accessibilityProps = srLabel ? {
31075
- role: "status",
31076
- "aria-live": "polite"
31077
- } : hasExplicitAriaLabel ? {} : { "aria-hidden": true };
31078
- const trackStroke = color === "inherit" ? "currentColor" : "var(--rb-spinner-track-color)";
31079
- const trackOpacity = color === "inherit" ? .25 : 1;
31080
- return /* @__PURE__ */ jsxs("span", {
31081
- ...accessibilityProps,
31082
- className: clsx("rb-spinner", size ? `rb-spinner--${size}` : null, color === "inherit" ? "rb-spinner--inherit" : null, className),
31083
- style: {
31084
- ...resolveColorStyle(color),
31085
- ...style ?? {}
31086
- },
31087
- ...rest,
31088
- children: [/* @__PURE__ */ jsxs("svg", {
31089
- viewBox: "0 0 24 24",
31090
- fill: "none",
31091
- "aria-hidden": "true",
31092
- children: [/* @__PURE__ */ jsx("circle", {
31093
- cx: "12",
31094
- cy: "12",
31095
- r: "10",
31096
- stroke: trackStroke,
31097
- strokeWidth,
31098
- opacity: trackOpacity
31099
- }), /* @__PURE__ */ jsx("path", {
31100
- d: "M12 2a10 10 0 0 1 10 10",
31101
- stroke: "currentColor",
31102
- strokeWidth,
31103
- strokeLinecap: "round"
31104
- })]
31105
- }), srLabel ? /* @__PURE__ */ jsx("span", {
31106
- className: "rb-sr-only",
31107
- children: srLabel
31108
- }) : null]
31281
+ //#region ../blocks/src/system/runtime/nodes/header-control.tsx
31282
+ /** System navigation controls retain their runtime hooks independently of authored CTAs. */
31283
+ 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 }) {
31284
+ return /* @__PURE__ */ jsx("button", {
31285
+ type: "button",
31286
+ className,
31287
+ "aria-label": label,
31288
+ "aria-expanded": expanded,
31289
+ "aria-controls": controls,
31290
+ "aria-haspopup": hasPopup,
31291
+ "data-nav-mobile-toggle": mobileToggle,
31292
+ "data-nav-mobile-trigger": mobileTrigger,
31293
+ children
31109
31294
  });
31110
31295
  }
31111
31296
  //#endregion
@@ -31417,11 +31602,6 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePa
31417
31602
  children: view.message
31418
31603
  })
31419
31604
  });
31420
- const actionClassName = themeButtonClassName({
31421
- variant: "secondary",
31422
- size: "sm",
31423
- extraClassName: "appointment-services-row-action"
31424
- });
31425
31605
  return /* @__PURE__ */ jsx("div", {
31426
31606
  className: `${rootClassName} rb-flex rb-flex-col`,
31427
31607
  "data-appointment-services-state": "populated",
@@ -31454,13 +31634,13 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePa
31454
31634
  className: "appointment-services-row-price rb-text-lg",
31455
31635
  children: row.priceLabel
31456
31636
  }) : null,
31457
- /* @__PURE__ */ jsxs("a", {
31458
- className: actionClassName,
31637
+ /* @__PURE__ */ jsx(ThemedButtonLink, {
31638
+ variant: "secondary",
31639
+ size: "sm",
31640
+ extraClassName: "appointment-services-row-action",
31459
31641
  href: row.href,
31460
- children: ["Check times", /* @__PURE__ */ jsxs("span", {
31461
- className: "rb-sr-only",
31462
- children: [" for ", row.title]
31463
- })]
31642
+ label: "Check times",
31643
+ screenReaderSuffix: ` for ${row.title}`
31464
31644
  })
31465
31645
  ]
31466
31646
  }, row.id))
@@ -33478,16 +33658,14 @@ function LocationMapView({ addressText, location, zoom, heightPx, showAddressTex
33478
33658
  style: textColorStyle("mutedText"),
33479
33659
  children: addressText
33480
33660
  }) : null,
33481
- showDirections && directionsUrl ? /* @__PURE__ */ jsx("a", {
33661
+ showDirections && directionsUrl ? /* @__PURE__ */ jsx(ThemedButtonLink, {
33482
33662
  href: directionsUrl,
33483
33663
  target: "_blank",
33484
33664
  rel: "noreferrer",
33485
- className: themeButtonClassName({
33486
- variant: "ghost",
33487
- size: "sm",
33488
- extraClassName: "rb-w-fit"
33489
- }),
33490
- children: directionsLabel
33665
+ variant: "ghost",
33666
+ size: "sm",
33667
+ extraClassName: "rb-w-fit",
33668
+ label: directionsLabel
33491
33669
  }) : null
33492
33670
  ]
33493
33671
  });
@@ -33636,10 +33814,6 @@ const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", but
33636
33814
  const formattedTime = `${formatTime(event.startsAt, { timeZone })} - ${formatTime(event.endsAt, { timeZone })}`;
33637
33815
  const cta = resolveEventCta(event, buttonText);
33638
33816
  const cardClass = boxStyleClassNames({ role: cardRole }, { baseClass: "event-card" });
33639
- const buttonClass = themeButtonClassName({
33640
- variant: buttonVariant,
33641
- size: "md"
33642
- });
33643
33817
  const title = event.title;
33644
33818
  const summary = event.presentation?.summary ?? event.description;
33645
33819
  const image = event.presentation?.image ?? null;
@@ -33669,7 +33843,7 @@ const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", but
33669
33843
  image
33670
33844
  }), /* @__PURE__ */ jsx(EventCardContent, {
33671
33845
  allowMap,
33672
- buttonClass,
33846
+ buttonVariant,
33673
33847
  capacityText,
33674
33848
  categoryBadge,
33675
33849
  categoryId: category?.id,
@@ -33771,7 +33945,7 @@ function EventCardContent(props) {
33771
33945
  children: props.summary
33772
33946
  }),
33773
33947
  /* @__PURE__ */ jsx(EventCardFooter, {
33774
- buttonClass: props.buttonClass,
33948
+ buttonVariant: props.buttonVariant,
33775
33949
  capacityText: props.capacityText,
33776
33950
  cta: props.cta,
33777
33951
  priceText: props.priceText
@@ -33809,12 +33983,14 @@ function EventCardFooter(props) {
33809
33983
  className: "event-card-status rb-caption status-muted rb-text-center",
33810
33984
  children: props.cta.label
33811
33985
  }),
33812
- !props.cta.hidden && /* @__PURE__ */ jsx("a", {
33986
+ !props.cta.hidden && /* @__PURE__ */ jsx(ThemedButtonLink, {
33813
33987
  href: props.cta.href,
33814
33988
  target: props.cta.external ? "_blank" : void 0,
33815
33989
  rel: props.cta.external ? "noopener noreferrer" : void 0,
33816
- className: `${props.buttonClass} event-card-cta`,
33817
- children: props.cta.label
33990
+ variant: props.buttonVariant,
33991
+ size: "md",
33992
+ extraClassName: "event-card-cta",
33993
+ label: props.cta.label
33818
33994
  })
33819
33995
  ]
33820
33996
  });
@@ -33878,10 +34054,6 @@ const EventCompactRow = ({ event, buttonVariant = "primary", buttonText }) => {
33878
34054
  const price = formatEventPrice(event);
33879
34055
  const teacherLine = formatEventTeacherLine(event);
33880
34056
  const cta = resolveEventCta(event, buttonText);
33881
- const buttonClass = themeButtonClassName({
33882
- variant: buttonVariant,
33883
- size: "sm"
33884
- });
33885
34057
  return /* @__PURE__ */ jsxs("article", {
33886
34058
  className: "event-compact-row",
33887
34059
  children: [/* @__PURE__ */ jsxs("time", {
@@ -33945,12 +34117,15 @@ const EventCompactRow = ({ event, buttonVariant = "primary", buttonText }) => {
33945
34117
  }), cta.hidden ? /* @__PURE__ */ jsx("span", {
33946
34118
  className: "event-compact-row-status",
33947
34119
  children: cta.label
33948
- }) : /* @__PURE__ */ jsx("a", {
34120
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
33949
34121
  href: cta.href,
33950
34122
  target: cta.external ? "_blank" : void 0,
33951
34123
  rel: cta.external ? "noopener noreferrer" : void 0,
33952
- className: `${buttonClass} event-compact-row-cta`,
33953
- children: /* @__PURE__ */ jsx("span", { children: cta.label })
34124
+ variant: buttonVariant,
34125
+ size: "sm",
34126
+ extraClassName: "event-compact-row-cta",
34127
+ labelClassName: "event-compact-row-cta-label",
34128
+ label: cta.label
33954
34129
  })]
33955
34130
  })]
33956
34131
  })]
@@ -33992,10 +34167,6 @@ function EventQuickDateCard(props) {
33992
34167
  kind: "event_occurrence",
33993
34168
  occurrenceId: event.occurrenceId
33994
34169
  });
33995
- const buttonClass = themeButtonClassName({
33996
- variant: props.buttonVariant,
33997
- size: "sm"
33998
- });
33999
34170
  const quickDateLabel = `${event.title}, ${date.label}`;
34000
34171
  return /* @__PURE__ */ jsxs("article", {
34001
34172
  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",
@@ -34027,13 +34198,15 @@ function EventQuickDateCard(props) {
34027
34198
  children: [/* @__PURE__ */ jsx("span", {
34028
34199
  className: "event-quick-date-price",
34029
34200
  children: formatEventPrice(event)
34030
- }), /* @__PURE__ */ jsx("a", {
34031
- className: `${buttonClass} event-quick-date-cta`,
34201
+ }), /* @__PURE__ */ jsx(ThemedButtonLink, {
34202
+ variant: props.buttonVariant,
34203
+ size: "sm",
34204
+ extraClassName: "event-quick-date-cta",
34032
34205
  href: ctaHref,
34033
34206
  target: cta.external ? "_blank" : void 0,
34034
34207
  rel: cta.external ? "noopener noreferrer" : void 0,
34035
34208
  "aria-label": `${cta.label} ${quickDateLabel}`,
34036
- children: cta.label
34209
+ label: cta.label
34037
34210
  })]
34038
34211
  })
34039
34212
  ]
@@ -34106,10 +34279,6 @@ const EventSpotlight = ({ events, layout = "grid", columns = "3", cardRole = "de
34106
34279
  });
34107
34280
  const containerClass = getContainerClass(layout, columns);
34108
34281
  const cardOrientation = getCardOrientation(layout);
34109
- const buttonClass = themeButtonClassName({
34110
- variant: buttonVariant,
34111
- size: "md"
34112
- });
34113
34282
  return /* @__PURE__ */ jsxs("div", {
34114
34283
  className: `event-spotlight-section ${className || ""}`,
34115
34284
  "data-block": "event-spotlight",
@@ -34127,15 +34296,22 @@ const EventSpotlight = ({ events, layout = "grid", columns = "3", cardRole = "de
34127
34296
  }, event.occurrenceId || event.id))
34128
34297
  }), ctaLabel && ctaUrl ? /* @__PURE__ */ jsx("div", {
34129
34298
  className: "rb-mt-8 rb-text-center",
34130
- children: /* @__PURE__ */ jsx("a", {
34299
+ children: /* @__PURE__ */ jsx(ThemedButtonLink, {
34131
34300
  href: ctaUrl,
34132
- className: buttonClass,
34133
- children: ctaLabel
34301
+ variant: buttonVariant,
34302
+ size: "md",
34303
+ label: ctaLabel
34134
34304
  })
34135
34305
  }) : null]
34136
34306
  });
34137
34307
  };
34138
34308
  //#endregion
34309
+ //#region ../blocks/src/system/runtime/api/readAuthority.ts
34310
+ const browserReadAuthoritySchema = z$1.discriminatedUnion("kind", [z$1.object({ kind: z$1.literal("published") }).strict(), z$1.object({
34311
+ kind: z$1.literal("preview"),
34312
+ token: z$1.string().min(1)
34313
+ }).strict()]);
34314
+ //#endregion
34139
34315
  //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
34140
34316
  const previewStageSchema = z$1.enum(["preview", "published"]);
34141
34317
  const registrationButtonVariantSchema = blockButtonRoleSchema;
@@ -35053,6 +35229,7 @@ const eventCollectionSourceSchemaShape = {
35053
35229
  events: z$1.array(publicEventSchema).nullable().optional(),
35054
35230
  siteId: z$1.string(),
35055
35231
  apiBaseUrl: z$1.string().optional(),
35232
+ readAuthority: browserReadAuthoritySchema.optional(),
35056
35233
  stage: previewStageSchema.optional(),
35057
35234
  listLayout: eventLayoutSchema.optional(),
35058
35235
  listColumns: columnOptionSchema.optional(),
@@ -35105,7 +35282,6 @@ const eventCollectionDisplaySchemaShape = {
35105
35282
  const eventCollectionHydrationSchema = z$1.object({
35106
35283
  siteId: z$1.string(),
35107
35284
  calendarWindow: calendarWindowPageSchema.optional(),
35108
- stage: previewStageSchema.optional(),
35109
35285
  prefetchedEvents: z$1.boolean(),
35110
35286
  eventSurface: eventSurfaceScopeSchema$1,
35111
35287
  filterEventPresets: z$1.string().nullable(),
@@ -35180,7 +35356,6 @@ function buildEventCollectionHydration(source, now = /* @__PURE__ */ new Date())
35180
35356
  return {
35181
35357
  calendarWindow: source.calendarWindow ?? void 0,
35182
35358
  siteId: source.siteId,
35183
- stage: source.stage,
35184
35359
  prefetchedEvents: source.events != null,
35185
35360
  eventSurface: selected ? "all" : normalizeEventSurfaceScope(source.eventSurface),
35186
35361
  filterEventPresets: selected ? null : normalizeEventSurfacePresetsCsv(source.filterEventPresets),
@@ -35227,6 +35402,7 @@ const eventCombinedRenderSchema = z$1.object({
35227
35402
  z$1.object({
35228
35403
  siteId: z$1.string(),
35229
35404
  apiBaseUrl: z$1.string().optional(),
35405
+ readAuthority: browserReadAuthoritySchema.optional(),
35230
35406
  stage: previewStageSchema.optional()
35231
35407
  });
35232
35408
  function buildEventCombinedDisplay(source) {
@@ -35257,6 +35433,7 @@ function buildEventCombinedInteractiveIslandProps(props) {
35257
35433
  meta: {
35258
35434
  siteId: props.siteId,
35259
35435
  apiBaseUrl: props.apiBaseUrl,
35436
+ readAuthority: props.readAuthority,
35260
35437
  stage: props.stage
35261
35438
  },
35262
35439
  source: props
@@ -35710,11 +35887,6 @@ function OfferingsCatalogue(props) {
35710
35887
  //#endregion
35711
35888
  //#region ../blocks/src/system/runtime/nodes/offerings-preview-content.tsx
35712
35889
  function OfferingsPreviewContent(props) {
35713
- const groupLinkClass = themeButtonClassName({
35714
- variant: props.buttonVariant,
35715
- size: "md",
35716
- extraClassName: "offerings-preview-card-link rb-inline-flex rb-items-center rb-gap-2"
35717
- });
35718
35890
  return /* @__PURE__ */ jsx("div", {
35719
35891
  className: "offerings-preview rb-flex rb-flex-col rb-gap-6",
35720
35892
  "data-block": "offerings-preview",
@@ -35754,10 +35926,12 @@ function OfferingsPreviewContent(props) {
35754
35926
  }),
35755
35927
  groupCta ? /* @__PURE__ */ jsx("footer", {
35756
35928
  className: "offerings-preview-card-footer rb-mt-auto rb-flex",
35757
- children: /* @__PURE__ */ jsx("a", {
35758
- className: groupLinkClass,
35929
+ children: /* @__PURE__ */ jsx(ThemedButtonLink, {
35930
+ variant: props.buttonVariant,
35931
+ size: "md",
35932
+ extraClassName: "offerings-preview-card-link rb-inline-flex rb-items-center rb-gap-2",
35759
35933
  href: groupCta.href,
35760
- children: /* @__PURE__ */ jsx("span", { children: groupCta.label })
35934
+ label: groupCta.label
35761
35935
  })
35762
35936
  }) : null
35763
35937
  ]
@@ -36080,10 +36254,6 @@ function WholeSeriesRunCompactRow({ group, path, now }) {
36080
36254
  const timeRange = `${formatTime(firstSession.startsAt, { timeZone })} - ${formatTime(firstSession.endsAt, { timeZone })}`;
36081
36255
  const price = formatEventPriceDisplay(group.representative.pricing);
36082
36256
  const statusLabel = resolveWholeSeriesBookingPhase(group.run, now).kind === "open" ? null : "Registration closed";
36083
- const ctaClass = themeButtonClassName({
36084
- variant: "primary",
36085
- size: "sm"
36086
- });
36087
36257
  return /* @__PURE__ */ jsxs("article", {
36088
36258
  className: "event-compact-row offerings-preview-whole-series-row",
36089
36259
  children: [
@@ -36142,10 +36312,13 @@ function WholeSeriesRunCompactRow({ group, path, now }) {
36142
36312
  }), statusLabel || !path ? /* @__PURE__ */ jsx("span", {
36143
36313
  className: "event-compact-row-status",
36144
36314
  children: statusLabel ?? "Details coming soon"
36145
- }) : /* @__PURE__ */ jsx("a", {
36315
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
36146
36316
  href: path,
36147
- className: `${ctaClass} event-compact-row-cta`,
36148
- children: /* @__PURE__ */ jsx("span", { children: "Book now" })
36317
+ variant: "primary",
36318
+ size: "sm",
36319
+ extraClassName: "event-compact-row-cta",
36320
+ labelClassName: "event-compact-row-cta-label",
36321
+ label: "Book now"
36149
36322
  })]
36150
36323
  })
36151
36324
  ]
@@ -36162,10 +36335,6 @@ function WholeSeriesRunFeatureCard({ group, now, path, buttonVariant, buttonText
36162
36335
  const formattedDate = formatEventCompactDateRail(firstSession.startsAt, { timeZone }).label;
36163
36336
  const timeRange = `${formatTime(firstSession.startsAt, { timeZone })} - ${formatTime(firstSession.endsAt, { timeZone })}`;
36164
36337
  const price = formatEventPriceDisplay(group.representative.pricing);
36165
- const ctaClass = themeButtonClassName({
36166
- variant: buttonVariant,
36167
- size: "md"
36168
- });
36169
36338
  const statusLabel = resolveWholeSeriesBookingPhase(group.run, now).kind === "open" ? null : "Registration closed";
36170
36339
  const description = group.representative.description;
36171
36340
  return /* @__PURE__ */ jsx("article", {
@@ -36198,10 +36367,12 @@ function WholeSeriesRunFeatureCard({ group, now, path, buttonVariant, buttonText
36198
36367
  }), statusLabel || !path ? /* @__PURE__ */ jsx("span", {
36199
36368
  className: "event-compact-row-status",
36200
36369
  children: statusLabel ?? "Details coming soon"
36201
- }) : /* @__PURE__ */ jsx("a", {
36370
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
36202
36371
  href: path,
36203
- className: `${ctaClass} event-card-cta`,
36204
- children: buttonText || "Book now"
36372
+ variant: buttonVariant,
36373
+ size: "md",
36374
+ extraClassName: "event-card-cta",
36375
+ label: buttonText || "Book now"
36205
36376
  })]
36206
36377
  })
36207
36378
  ]
@@ -36354,15 +36525,13 @@ function WeeklySlotAvailabilityView({ availability, loading = false, error, empt
36354
36525
  "."
36355
36526
  ]
36356
36527
  }),
36357
- resolvedCtaUrl ? /* @__PURE__ */ jsx("a", {
36358
- className: themeButtonClassName({
36359
- variant: "ghost",
36360
- size: "sm",
36361
- extraClassName: "weekly-slot-availability__cta"
36362
- }),
36528
+ resolvedCtaUrl ? /* @__PURE__ */ jsx(ThemedButtonLink, {
36529
+ variant: "ghost",
36530
+ size: "sm",
36531
+ extraClassName: "weekly-slot-availability__cta",
36363
36532
  href: buildSlotCtaUrl(resolvedCtaUrl, slot),
36364
36533
  "aria-label": buildSlotCtaLabel(resolvedCtaText, slot),
36365
- children: resolvedCtaText
36534
+ label: resolvedCtaText
36366
36535
  }) : null
36367
36536
  ]
36368
36537
  }, slot.id))
@@ -37081,6 +37250,7 @@ const shopSourceSchema = z$1.object({
37081
37250
  products: z$1.array(publicProductSchema).nullable().optional(),
37082
37251
  siteId: z$1.string().optional(),
37083
37252
  apiBaseUrl: z$1.string().optional(),
37253
+ readAuthority: browserReadAuthoritySchema.optional(),
37084
37254
  stage: previewStageSchema.optional()
37085
37255
  });
37086
37256
  const productVariantOptionDisplaySchema = z$1.object({
@@ -37248,6 +37418,7 @@ function resolveShowPricePerCredit(source) {
37248
37418
  z$1.object({
37249
37419
  siteId: z$1.string().optional(),
37250
37420
  apiBaseUrl: z$1.string().optional(),
37421
+ readAuthority: browserReadAuthoritySchema.optional(),
37251
37422
  stage: previewStageSchema.optional()
37252
37423
  });
37253
37424
  const shopBlockRuntime = defineProgressiveBlockRuntime({
@@ -37382,6 +37553,7 @@ function buildShopInteractiveIslandProps(props) {
37382
37553
  meta: {
37383
37554
  siteId: props.siteId,
37384
37555
  apiBaseUrl: props.apiBaseUrl,
37556
+ readAuthority: props.readAuthority,
37385
37557
  stage: props.stage
37386
37558
  },
37387
37559
  source: {
@@ -37397,6 +37569,7 @@ function buildProductListInteractiveIslandProps(props) {
37397
37569
  meta: {
37398
37570
  siteId: props.siteId,
37399
37571
  apiBaseUrl: props.apiBaseUrl,
37572
+ readAuthority: props.readAuthority,
37400
37573
  stage: props.stage
37401
37574
  },
37402
37575
  source: {
@@ -37412,6 +37585,7 @@ function buildProductDetailInteractiveIslandProps(props) {
37412
37585
  meta: {
37413
37586
  siteId: props.siteId,
37414
37587
  apiBaseUrl: props.apiBaseUrl,
37588
+ readAuthority: props.readAuthority,
37415
37589
  stage: props.stage
37416
37590
  },
37417
37591
  source: {
@@ -37427,6 +37601,7 @@ function buildCartInteractiveIslandProps(props) {
37427
37601
  meta: {
37428
37602
  siteId: props.siteId,
37429
37603
  apiBaseUrl: props.apiBaseUrl,
37604
+ readAuthority: props.readAuthority,
37430
37605
  stage: props.stage
37431
37606
  },
37432
37607
  source: {
@@ -37442,6 +37617,7 @@ function buildCheckoutInteractiveIslandProps(props) {
37442
37617
  meta: {
37443
37618
  siteId: props.siteId,
37444
37619
  apiBaseUrl: props.apiBaseUrl,
37620
+ readAuthority: props.readAuthority,
37445
37621
  stage: props.stage
37446
37622
  },
37447
37623
  source: {
@@ -37523,6 +37699,7 @@ const cartBlockDefinition = {
37523
37699
  baseClass: "",
37524
37700
  spacing: "spacious",
37525
37701
  children: sectionContainer([cart(withApiBindings({
37702
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
37526
37703
  mode: "cart",
37527
37704
  heading: { $bind: {
37528
37705
  from: "content.heading",
@@ -37606,6 +37783,7 @@ const checkoutBlockDefinition = {
37606
37783
  baseClass: "",
37607
37784
  spacing: "spacious",
37608
37785
  children: sectionContainer([checkout(withApiBindings({
37786
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
37609
37787
  mode: "checkout",
37610
37788
  heading: { $bind: {
37611
37789
  from: "content.heading",
@@ -38038,6 +38216,7 @@ const eventRegistrationSourceSchema = z$1.object({
38038
38216
  apiBaseUrl: z$1.string().optional(),
38039
38217
  portalToken: z$1.string().nullable().optional(),
38040
38218
  previewToken: z$1.string().nullable().optional(),
38219
+ readAuthority: browserReadAuthoritySchema.optional(),
38041
38220
  ...eventRegistrationHydrationSchemaShape,
38042
38221
  events: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
38043
38222
  wholeSeriesRunEvents: z$1.array(eventRegistrationPublicEventSchema).nullable().optional(),
@@ -38075,6 +38254,7 @@ z$1.object({
38075
38254
  apiBaseUrl: z$1.string().optional(),
38076
38255
  portalToken: z$1.string().nullable().optional(),
38077
38256
  previewToken: z$1.string().nullable().optional(),
38257
+ readAuthority: browserReadAuthoritySchema.optional(),
38078
38258
  stage: previewStageSchema.optional()
38079
38259
  });
38080
38260
  function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents) {
@@ -38218,6 +38398,7 @@ function buildEventRegistrationInteractiveIslandProps(props) {
38218
38398
  apiBaseUrl: props.apiBaseUrl,
38219
38399
  portalToken: props.portalToken,
38220
38400
  previewToken: props.previewToken,
38401
+ readAuthority: props.readAuthority,
38221
38402
  stage: props.stage
38222
38403
  },
38223
38404
  source: props
@@ -38347,6 +38528,7 @@ const eventRegistrationBlockDefinition = {
38347
38528
  text({ as: "h2" }, bind("content.heading"), when("content.heading")),
38348
38529
  richText({ className: "rb-prose rb-max-w-none" }, bind("content.description"), when("content.description")),
38349
38530
  eventRegistration(withApiBindings({
38531
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
38350
38532
  occurrenceContext: { $bind: { from: "$root.occurrenceContext" } },
38351
38533
  subject: { $bind: { from: "$root.subject" } },
38352
38534
  portalToken: { $bind: {
@@ -38792,6 +38974,7 @@ const eventCalendarRenderSchema = z$1.object({
38792
38974
  z$1.object({
38793
38975
  siteId: z$1.string(),
38794
38976
  apiBaseUrl: z$1.string().optional(),
38977
+ readAuthority: browserReadAuthoritySchema.optional(),
38795
38978
  stage: previewStageSchema.optional()
38796
38979
  });
38797
38980
  /**
@@ -38813,7 +38996,7 @@ function buildEventCalendarDisplay(source) {
38813
38996
  listColumns: source.listColumns ?? source.columns
38814
38997
  }),
38815
38998
  kind: "event-calendar",
38816
- displayMode: normalizeEventCalendarDisplayMode$1(source) ?? "combined",
38999
+ displayMode: resolveEventCalendarReadPlan(source).mode,
38817
39000
  className: source.className ?? null,
38818
39001
  events: (source.events ?? []).slice().sort((left, right) => new Date(left.startsAt).getTime() - new Date(right.startsAt).getTime()),
38819
39002
  boardTitle: normalizeOptionalText(source.boardTitle),
@@ -38833,13 +39016,16 @@ const eventCalendarBlockRuntime = defineProgressiveBlockRuntime({
38833
39016
  source: createZodCodec(eventCalendarSourceSchema),
38834
39017
  render: createZodCodec(eventCalendarRenderSchema)
38835
39018
  },
38836
- buildRender: (source) => ({
38837
- display: buildEventCalendarDisplay(source.calendarWindow && (source.variant ?? source.displayMode ?? "combined") !== "combined" && (source.variant ?? source.displayMode) !== "list" ? {
38838
- ...source,
38839
- events: source.calendarWindow.events
38840
- } : source),
38841
- hydration: buildEventCollectionHydration(source)
38842
- })
39019
+ buildRender: (source) => {
39020
+ const plan = resolveEventCalendarReadPlan(source);
39021
+ return {
39022
+ display: buildEventCalendarDisplay(source.calendarWindow && plan.jobs === "calendar" ? {
39023
+ ...source,
39024
+ events: source.calendarWindow.events
39025
+ } : source),
39026
+ hydration: buildEventCollectionHydration(source)
39027
+ };
39028
+ }
38843
39029
  });
38844
39030
  function buildEventCalendarInteractiveIslandProps(props) {
38845
39031
  return buildInteractiveIslandProps({
@@ -38848,6 +39034,7 @@ function buildEventCalendarInteractiveIslandProps(props) {
38848
39034
  meta: {
38849
39035
  siteId: props.siteId,
38850
39036
  apiBaseUrl: props.apiBaseUrl,
39037
+ readAuthority: props.readAuthority,
38851
39038
  stage: props.stage
38852
39039
  },
38853
39040
  source: props
@@ -39001,6 +39188,7 @@ const eventCalendarLayout = [styledSection({
39001
39188
  rootType: "stack",
39002
39189
  rootProps: { gap: "lg" },
39003
39190
  children: [...eventSectionHeaderLayoutNodes({ splitClassName: "event-section-head event-section-head--split" }), el("event-calendar", withApiBindings({
39191
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
39004
39192
  events: { $bind: { from: "data.events" } },
39005
39193
  calendarWindow: { $bind: { from: "data.calendarWindow" } },
39006
39194
  stage: { $bind: {
@@ -39880,6 +40068,7 @@ const eventListingSourceSchema = z$1.object({
39880
40068
  events: z$1.array(publicEventSchema).nullable().optional(),
39881
40069
  siteId: z$1.string(),
39882
40070
  apiBaseUrl: z$1.string().optional(),
40071
+ readAuthority: browserReadAuthoritySchema.optional(),
39883
40072
  stage: previewStageSchema.optional(),
39884
40073
  layout: eventLayoutSchema.optional(),
39885
40074
  columns: columnOptionSchema.optional(),
@@ -39920,7 +40109,6 @@ const eventListingDisplaySchema = z$1.object({
39920
40109
  });
39921
40110
  const eventListingHydrationSchema = z$1.object({
39922
40111
  siteId: z$1.string(),
39923
- stage: previewStageSchema.optional(),
39924
40112
  eventsPerPage: eventPageSizeSchema,
39925
40113
  paginationAction: eventListPaginationActionSchema,
39926
40114
  showFilters: z$1.boolean(),
@@ -39943,6 +40131,7 @@ const eventListingRenderSchema = z$1.object({
39943
40131
  z$1.object({
39944
40132
  siteId: z$1.string(),
39945
40133
  apiBaseUrl: z$1.string().optional(),
40134
+ readAuthority: browserReadAuthoritySchema.optional(),
39946
40135
  stage: previewStageSchema.optional()
39947
40136
  });
39948
40137
  const eventListingBlockRuntime = defineProgressiveBlockRuntime({
@@ -39977,7 +40166,6 @@ const eventListingBlockRuntime = defineProgressiveBlockRuntime({
39977
40166
  },
39978
40167
  hydration: {
39979
40168
  siteId: source.siteId,
39980
- stage: source.stage,
39981
40169
  eventsPerPage: pageSize,
39982
40170
  paginationAction: resolveEventListPaginationAction({
39983
40171
  paginationMode: source.paginationMode,
@@ -40007,6 +40195,7 @@ function buildEventListingInteractiveIslandProps(props) {
40007
40195
  meta: {
40008
40196
  siteId: props.siteId,
40009
40197
  apiBaseUrl: props.apiBaseUrl,
40198
+ readAuthority: props.readAuthority,
40010
40199
  stage: props.stage
40011
40200
  },
40012
40201
  source: props
@@ -40271,6 +40460,7 @@ const eventListingBlockDefinition = {
40271
40460
  rootType: "stack",
40272
40461
  rootProps: { gap: "lg" },
40273
40462
  children: [...eventSectionHeaderLayoutNodes(), el("event-listing", withApiBindings({
40463
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
40274
40464
  events: { $bind: { from: "data.events" } },
40275
40465
  stage: { $bind: {
40276
40466
  from: "$root.previewStage",
@@ -40923,6 +41113,7 @@ const productDetailBlockDefinition = {
40923
41113
  baseClass: "",
40924
41114
  spacing: "spacious",
40925
41115
  children: sectionContainer([productDetail(withApiBindings({
41116
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
40926
41117
  mode: "product-detail",
40927
41118
  heading: { $bind: {
40928
41119
  from: "content.heading",
@@ -41091,6 +41282,7 @@ const productListBlockDefinition = {
41091
41282
  baseClass: "",
41092
41283
  spacing: "spacious",
41093
41284
  children: sectionContainer([productList(withApiBindings({
41285
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
41094
41286
  mode: "product-list",
41095
41287
  heading: { $bind: {
41096
41288
  from: "content.heading",
@@ -41355,6 +41547,7 @@ const shopBlockDefinition = {
41355
41547
  baseClass: "",
41356
41548
  spacing: "spacious",
41357
41549
  children: sectionContainer([shop(withApiBindings({
41550
+ readAuthority: { $bind: { from: "$root.readAuthority" } },
41358
41551
  mode: "passes-memberships",
41359
41552
  showPasses: { $bind: {
41360
41553
  from: "content.showPasses",
@@ -41757,15 +41950,13 @@ function CheckoutShellView(props) {
41757
41950
  //#endregion
41758
41951
  //#region ../blocks/src/system/runtime/nodes/shop-commerce.server.tsx
41759
41952
  function renderServerPendingAction(label, soldOut) {
41760
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
41953
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ThemedButton, {
41761
41954
  type: "button",
41762
- className: themeButtonClassName({
41763
- variant: "default",
41764
- size: "md"
41765
- }),
41955
+ variant: "default",
41956
+ size: "md",
41957
+ label: soldOut ? "Sold out" : label,
41766
41958
  disabled: true,
41767
- "aria-disabled": "true",
41768
- children: soldOut ? "Sold out" : label
41959
+ "aria-disabled": "true"
41769
41960
  }), !soldOut ? /* @__PURE__ */ jsx("p", {
41770
41961
  className: "rb-caption status-muted",
41771
41962
  children: "Cart actions become interactive after page load."
@@ -41782,13 +41973,11 @@ function ProductListServerContent(props) {
41782
41973
  selectedVariantId: card.selectedVariantId,
41783
41974
  disabled: true
41784
41975
  }),
41785
- actions: /* @__PURE__ */ jsxs(Fragment, { children: [renderServerPendingAction(card.actionLabel, card.soldOut), card.path ? /* @__PURE__ */ jsx("a", {
41976
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [renderServerPendingAction(card.actionLabel, card.soldOut), card.path ? /* @__PURE__ */ jsx(ThemedButtonLink, {
41786
41977
  href: card.path,
41787
- className: themeButtonClassName({
41788
- variant: "secondary",
41789
- size: "sm"
41790
- }),
41791
- children: "View details"
41978
+ variant: "secondary",
41979
+ size: "sm",
41980
+ label: "View details"
41792
41981
  }) : null] })
41793
41982
  }, card.productId))
41794
41983
  });
@@ -42084,10 +42273,6 @@ function AgendaLinkCard({ event, showCapacity, showVenue, buttonVariant, buttonT
42084
42273
  const price = formatEventPrice(event);
42085
42274
  const capacity = showCapacity ? formatEventRemainingPlaces(event) : null;
42086
42275
  const cta = resolveEventCta(event, buttonText);
42087
- const buttonClass = themeButtonClassName({
42088
- variant: buttonVariant,
42089
- size: "sm"
42090
- });
42091
42276
  return /* @__PURE__ */ jsxs("article", {
42092
42277
  className: "event-agenda-card event-agenda-card--agenda",
42093
42278
  children: [
@@ -42139,12 +42324,14 @@ function AgendaLinkCard({ event, showCapacity, showVenue, buttonVariant, buttonT
42139
42324
  }), cta.hidden ? /* @__PURE__ */ jsx("span", {
42140
42325
  className: "event-agenda-card-status status-muted",
42141
42326
  children: cta.label
42142
- }) : /* @__PURE__ */ jsx("a", {
42327
+ }) : /* @__PURE__ */ jsx(ThemedButtonLink, {
42143
42328
  href: cta.href,
42144
42329
  target: cta.external ? "_blank" : void 0,
42145
42330
  rel: cta.external ? "noopener noreferrer" : void 0,
42146
- className: `${buttonClass} event-agenda-card-cta`,
42147
- children: cta.label
42331
+ variant: buttonVariant,
42332
+ size: "sm",
42333
+ extraClassName: "event-agenda-card-cta",
42334
+ label: cta.label
42148
42335
  })]
42149
42336
  })
42150
42337
  ]
@@ -42343,7 +42530,7 @@ const WeekBoardCard = ({ event, showCapacity, calendarTimeZone }) => {
42343
42530
  ]
42344
42531
  });
42345
42532
  };
42346
- const WeekBoardNavigationControls = ({ navigation, todayClassName }) => {
42533
+ const WeekBoardNavigationControls = ({ navigation, buttonVariant }) => {
42347
42534
  const handlers = navigation.kind === "interactive" ? navigation : {
42348
42535
  onPrevious: void 0,
42349
42536
  onNext: void 0,
@@ -42376,12 +42563,13 @@ const WeekBoardNavigationControls = ({ navigation, todayClassName }) => {
42376
42563
  onClick: handlers.onNext,
42377
42564
  children: /* @__PURE__ */ jsx(CalendarNavigationChevron, { direction: "next" })
42378
42565
  }),
42379
- /* @__PURE__ */ jsx("button", {
42566
+ /* @__PURE__ */ jsx(ThemedButton, {
42380
42567
  type: "button",
42381
- className: todayClassName,
42568
+ variant: buttonVariant,
42569
+ size: "sm",
42570
+ label: "Today",
42382
42571
  disabled: navigation.isCurrentWeek,
42383
- onClick: handlers.onToday,
42384
- children: "Today"
42572
+ onClick: handlers.onToday
42385
42573
  })
42386
42574
  ]
42387
42575
  });
@@ -42397,16 +42585,17 @@ const WeekBoardLegend = () => /* @__PURE__ */ jsx("div", {
42397
42585
  }), item.label]
42398
42586
  }, item.status))
42399
42587
  });
42400
- const WeekBoardLoadError = ({ navigation, buttonClassName }) => {
42588
+ const WeekBoardLoadError = ({ navigation, buttonVariant }) => {
42401
42589
  if (navigation.kind !== "interactive" || navigation.loadState.kind !== "error") return null;
42402
42590
  return /* @__PURE__ */ jsxs("div", {
42403
42591
  className: "event-week-board-error",
42404
42592
  role: "status",
42405
- children: [/* @__PURE__ */ jsx("p", { children: "Failed to load events" }), /* @__PURE__ */ jsx("button", {
42593
+ children: [/* @__PURE__ */ jsx("p", { children: "Failed to load events" }), /* @__PURE__ */ jsx(ThemedButton, {
42406
42594
  type: "button",
42407
- className: buttonClassName,
42408
- onClick: navigation.loadState.onRetry,
42409
- children: "Try again"
42595
+ variant: buttonVariant,
42596
+ size: "sm",
42597
+ label: "Try again",
42598
+ onClick: navigation.loadState.onRetry
42410
42599
  })]
42411
42600
  });
42412
42601
  };
@@ -42438,17 +42627,18 @@ const WeekBoardGrid = ({ days, eventsByDate, showCapacity, calendarTimeZone, tod
42438
42627
  }, dateKey);
42439
42628
  })
42440
42629
  });
42441
- const WeekBoardFooter = ({ note, ctaHref, ctaLabel, ctaClassName }) => {
42630
+ const WeekBoardFooter = ({ note, ctaHref, ctaLabel, buttonVariant }) => {
42442
42631
  if (note === null && ctaHref === null) return null;
42443
42632
  return /* @__PURE__ */ jsxs("div", {
42444
42633
  className: "event-week-board-foot",
42445
42634
  children: [note === null ? null : /* @__PURE__ */ jsx("p", {
42446
42635
  className: "event-week-board-foot-note",
42447
42636
  children: note
42448
- }), ctaHref === null ? null : /* @__PURE__ */ jsx("a", {
42449
- className: ctaClassName,
42637
+ }), ctaHref === null ? null : /* @__PURE__ */ jsx(ThemedButtonLink, {
42638
+ variant: buttonVariant,
42639
+ size: "sm",
42450
42640
  href: ctaHref,
42451
- children: ctaLabel
42641
+ label: ctaLabel
42452
42642
  })]
42453
42643
  });
42454
42644
  };
@@ -42463,14 +42653,6 @@ const WeekBoardFooter = ({ note, ctaHref, ctaLabel, ctaClassName }) => {
42463
42653
  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 }) => {
42464
42654
  const eventsByDate = groupEventsByDate(events, calendarTimeZone);
42465
42655
  const hasAnyEvents = days.some((date) => (eventsByDate.get(formatDateKey(date)) ?? []).length > 0);
42466
- const ctaClassName = themeButtonClassName({
42467
- variant: buttonVariant,
42468
- size: "sm"
42469
- });
42470
- const todayClassName = themeButtonClassName({
42471
- variant: buttonVariant,
42472
- size: "sm"
42473
- });
42474
42656
  const hasTitle = typeof title === "string" && title.length > 0;
42475
42657
  const hasFooterNote = typeof footerNote === "string" && footerNote.length > 0;
42476
42658
  const footerNoteText = hasAnyEvents ? hasFooterNote ? footerNote : null : emptyMessage;
@@ -42493,14 +42675,14 @@ const WeekBoardView = ({ days, events, navigation, showCapacity, emptyMessage =
42493
42675
  }) : null,
42494
42676
  /* @__PURE__ */ jsx(WeekBoardNavigationControls, {
42495
42677
  navigation,
42496
- todayClassName
42678
+ buttonVariant
42497
42679
  }),
42498
42680
  /* @__PURE__ */ jsx(WeekBoardLegend, {})
42499
42681
  ]
42500
42682
  }),
42501
42683
  /* @__PURE__ */ jsx(WeekBoardLoadError, {
42502
42684
  navigation,
42503
- buttonClassName: todayClassName
42685
+ buttonVariant
42504
42686
  }),
42505
42687
  /* @__PURE__ */ jsx(WeekBoardGrid, {
42506
42688
  days,
@@ -42513,7 +42695,7 @@ const WeekBoardView = ({ days, events, navigation, showCapacity, emptyMessage =
42513
42695
  note: footerNoteText,
42514
42696
  ctaHref: resolvedCtaHref,
42515
42697
  ctaLabel,
42516
- ctaClassName
42698
+ buttonVariant
42517
42699
  })
42518
42700
  ]
42519
42701
  })
@@ -42612,6 +42794,54 @@ function assertNeverDisplayMode(value) {
42612
42794
  function renderEventCard(event, display) {
42613
42795
  return renderEventListItem(event, display);
42614
42796
  }
42797
+ function CalendarSsrHeader(props) {
42798
+ const periodLabel = props.period === "week" ? "week" : "month";
42799
+ return /* @__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": `Previous ${periodLabel}`,
42808
+ children: /* @__PURE__ */ jsx(CalendarSsrChevron, { direction: "previous" })
42809
+ }),
42810
+ /* @__PURE__ */ jsx("h3", {
42811
+ className: "event-calendar-title",
42812
+ children: props.title
42813
+ }),
42814
+ /* @__PURE__ */ jsx("button", {
42815
+ type: "button",
42816
+ className: "event-calendar-nav-btn",
42817
+ "aria-label": `Next ${periodLabel}`,
42818
+ children: /* @__PURE__ */ jsx(CalendarSsrChevron, { direction: "next" })
42819
+ })
42820
+ ]
42821
+ }), /* @__PURE__ */ jsx(ThemedButton, {
42822
+ type: "button",
42823
+ variant: props.buttonVariant,
42824
+ size: "sm",
42825
+ label: "Today"
42826
+ })]
42827
+ });
42828
+ }
42829
+ function CalendarSsrChevron(props) {
42830
+ return /* @__PURE__ */ jsx("svg", {
42831
+ width: "20",
42832
+ height: "20",
42833
+ fill: "none",
42834
+ stroke: "currentColor",
42835
+ strokeWidth: 2,
42836
+ viewBox: "0 0 24 24",
42837
+ children: /* @__PURE__ */ jsx("path", {
42838
+ strokeLinecap: "round",
42839
+ strokeLinejoin: "round",
42840
+ strokeWidth: 2,
42841
+ d: props.direction === "previous" ? "M15 19l-7-7 7-7" : "M9 5l7 7-7 7"
42842
+ })
42843
+ });
42844
+ }
42615
42845
  function renderCombinedSsr(display, prefetchedEvents) {
42616
42846
  const listDisplay = buildEventCalendarListingDisplay(display, prefetchedEvents, "event-combined-content");
42617
42847
  return /* @__PURE__ */ jsxs("div", {
@@ -42659,62 +42889,10 @@ function renderCalendarSsr(display, hydration) {
42659
42889
  return /* @__PURE__ */ jsxs("div", {
42660
42890
  className: clsx("event-calendar", display.className ?? void 0),
42661
42891
  "data-block": "event-calendar",
42662
- children: [/* @__PURE__ */ jsxs("div", {
42663
- className: "event-calendar-header",
42664
- children: [/* @__PURE__ */ jsxs("div", {
42665
- className: "event-calendar-nav",
42666
- children: [
42667
- /* @__PURE__ */ jsx("button", {
42668
- type: "button",
42669
- className: "event-calendar-nav-btn",
42670
- "aria-label": calendarView === "week" ? "Previous week" : "Previous month",
42671
- children: /* @__PURE__ */ jsx("svg", {
42672
- width: "20",
42673
- height: "20",
42674
- fill: "none",
42675
- stroke: "currentColor",
42676
- strokeWidth: 2,
42677
- viewBox: "0 0 24 24",
42678
- children: /* @__PURE__ */ jsx("path", {
42679
- strokeLinecap: "round",
42680
- strokeLinejoin: "round",
42681
- strokeWidth: 2,
42682
- d: "M15 19l-7-7 7-7"
42683
- })
42684
- })
42685
- }),
42686
- /* @__PURE__ */ jsx("h3", {
42687
- className: "event-calendar-title",
42688
- children: viewport.title
42689
- }),
42690
- /* @__PURE__ */ jsx("button", {
42691
- type: "button",
42692
- className: "event-calendar-nav-btn",
42693
- "aria-label": calendarView === "week" ? "Next week" : "Next month",
42694
- children: /* @__PURE__ */ jsx("svg", {
42695
- width: "20",
42696
- height: "20",
42697
- fill: "none",
42698
- stroke: "currentColor",
42699
- strokeWidth: 2,
42700
- viewBox: "0 0 24 24",
42701
- children: /* @__PURE__ */ jsx("path", {
42702
- strokeLinecap: "round",
42703
- strokeLinejoin: "round",
42704
- strokeWidth: 2,
42705
- d: "M9 5l7 7-7 7"
42706
- })
42707
- })
42708
- })
42709
- ]
42710
- }), /* @__PURE__ */ jsx("button", {
42711
- type: "button",
42712
- className: themeButtonClassName({
42713
- variant: display.buttonVariant,
42714
- size: "sm"
42715
- }),
42716
- children: "Today"
42717
- })]
42892
+ children: [/* @__PURE__ */ jsx(CalendarSsrHeader, {
42893
+ title: viewport.title,
42894
+ period: calendarView,
42895
+ buttonVariant: display.buttonVariant
42718
42896
  }), viewport.kind === "week" ? /* @__PURE__ */ jsx(WeekAgendaView, {
42719
42897
  days: viewport.days,
42720
42898
  events: [...display.events],
@@ -42790,62 +42968,10 @@ function renderTimetableSsr(display, hydration) {
42790
42968
  return /* @__PURE__ */ jsxs("div", {
42791
42969
  className: clsx("event-calendar", "event-calendar--timetable", display.className ?? void 0),
42792
42970
  "data-block": "event-calendar",
42793
- children: [/* @__PURE__ */ jsxs("div", {
42794
- className: "event-calendar-header",
42795
- children: [/* @__PURE__ */ jsxs("div", {
42796
- className: "event-calendar-nav",
42797
- children: [
42798
- /* @__PURE__ */ jsx("button", {
42799
- type: "button",
42800
- className: "event-calendar-nav-btn",
42801
- "aria-label": "Previous week",
42802
- children: /* @__PURE__ */ jsx("svg", {
42803
- width: "20",
42804
- height: "20",
42805
- fill: "none",
42806
- stroke: "currentColor",
42807
- strokeWidth: 2,
42808
- viewBox: "0 0 24 24",
42809
- children: /* @__PURE__ */ jsx("path", {
42810
- strokeLinecap: "round",
42811
- strokeLinejoin: "round",
42812
- strokeWidth: 2,
42813
- d: "M15 19l-7-7 7-7"
42814
- })
42815
- })
42816
- }),
42817
- /* @__PURE__ */ jsx("h3", {
42818
- className: "event-calendar-title",
42819
- children: viewport.title
42820
- }),
42821
- /* @__PURE__ */ jsx("button", {
42822
- type: "button",
42823
- className: "event-calendar-nav-btn",
42824
- "aria-label": "Next week",
42825
- children: /* @__PURE__ */ jsx("svg", {
42826
- width: "20",
42827
- height: "20",
42828
- fill: "none",
42829
- stroke: "currentColor",
42830
- strokeWidth: 2,
42831
- viewBox: "0 0 24 24",
42832
- children: /* @__PURE__ */ jsx("path", {
42833
- strokeLinecap: "round",
42834
- strokeLinejoin: "round",
42835
- strokeWidth: 2,
42836
- d: "M9 5l7 7-7 7"
42837
- })
42838
- })
42839
- })
42840
- ]
42841
- }), /* @__PURE__ */ jsx("button", {
42842
- type: "button",
42843
- className: themeButtonClassName({
42844
- variant: display.buttonVariant,
42845
- size: "sm"
42846
- }),
42847
- children: "Today"
42848
- })]
42971
+ children: [/* @__PURE__ */ jsx(CalendarSsrHeader, {
42972
+ title: viewport.title,
42973
+ period: "week",
42974
+ buttonVariant: display.buttonVariant
42849
42975
  }), /* @__PURE__ */ jsxs("div", {
42850
42976
  className: "event-timetable",
42851
42977
  children: [
@@ -43341,14 +43467,12 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
43341
43467
  className: "fb-actions",
43342
43468
  children: /* @__PURE__ */ jsx("div", {
43343
43469
  className: "fb-actions-inner",
43344
- children: /* @__PURE__ */ jsx("button", {
43470
+ children: /* @__PURE__ */ jsx(ThemedButton, {
43345
43471
  type: "submit",
43346
- className: themeButtonClassName({
43347
- variant: "primary",
43348
- size: "md",
43349
- extraClassName: "rb-w-full rb-sm-w-auto"
43350
- }),
43351
- children: display.submitLabel
43472
+ variant: "primary",
43473
+ size: "md",
43474
+ extraClassName: "rb-w-full rb-sm-w-auto",
43475
+ label: display.submitLabel
43352
43476
  })
43353
43477
  })
43354
43478
  })
@@ -43443,13 +43567,11 @@ function NewsletterFormSSR(props) {
43443
43567
  }) : null,
43444
43568
  /* @__PURE__ */ jsx("div", {
43445
43569
  className: "newsletter-submit",
43446
- children: /* @__PURE__ */ jsx("button", {
43570
+ children: /* @__PURE__ */ jsx(ThemedButton, {
43447
43571
  type: "submit",
43448
- className: themeButtonClassName({
43449
- variant: display.buttonVariant,
43450
- size: "md"
43451
- }),
43452
- children: display.buttonLabel
43572
+ variant: display.buttonVariant,
43573
+ size: "md",
43574
+ label: display.buttonLabel
43453
43575
  })
43454
43576
  })
43455
43577
  ]
@@ -43531,28 +43653,24 @@ function ShopSSR({ blockId, siteId, apiBaseUrl, stage, children, checkoutEndpoin
43531
43653
  display: render.display,
43532
43654
  passCards: render.display.passes.map((pass) => /* @__PURE__ */ jsx(PassCardView, {
43533
43655
  display: pass,
43534
- action: pass.action.kind === "unavailable" ? /* @__PURE__ */ jsx(PassPurchaseUnavailable, { label: pass.action.label }) : /* @__PURE__ */ jsx("button", {
43656
+ action: pass.action.kind === "unavailable" ? /* @__PURE__ */ jsx(PassPurchaseUnavailable, { label: pass.action.label }) : /* @__PURE__ */ jsx(ThemedButton, {
43535
43657
  type: "button",
43536
- className: themeButtonClassName({
43537
- variant: render.hydration.buttonVariant,
43538
- size: "md"
43539
- }),
43658
+ variant: render.hydration.buttonVariant,
43659
+ size: "md",
43660
+ label: pass.action.label,
43540
43661
  disabled: true,
43541
- "aria-disabled": "true",
43542
- children: pass.action.label
43662
+ "aria-disabled": "true"
43543
43663
  })
43544
43664
  }, pass.id)),
43545
43665
  membershipCards: render.display.memberships.map((membership) => /* @__PURE__ */ jsx(MembershipCardView, {
43546
43666
  display: membership,
43547
- action: /* @__PURE__ */ jsx("button", {
43667
+ action: /* @__PURE__ */ jsx(ThemedButton, {
43548
43668
  type: "button",
43549
- className: themeButtonClassName({
43550
- variant: render.hydration.buttonVariant,
43551
- size: "md"
43552
- }),
43669
+ variant: render.hydration.buttonVariant,
43670
+ size: "md",
43671
+ label: membership.actionLabel,
43553
43672
  disabled: true,
43554
- "aria-disabled": "true",
43555
- children: membership.actionLabel
43673
+ "aria-disabled": "true"
43556
43674
  })
43557
43675
  }, membership.id))
43558
43676
  }),
@@ -43601,6 +43719,7 @@ const serverComponentRegistry = {
43601
43719
  svg: SvgNode,
43602
43720
  section: SectionNode,
43603
43721
  headerSection: header_section_server_default,
43722
+ headerControl: HeaderControlNode,
43604
43723
  stack: StackNode,
43605
43724
  inline: InlineNode,
43606
43725
  grid: GridNode,
@@ -44427,16 +44546,71 @@ function resolveChildren(nodes, context) {
44427
44546
  function isReactNode(value) {
44428
44547
  return value !== null && value !== void 0;
44429
44548
  }
44549
+ const RENDERER_METADATA_PROP_KEYS = /* @__PURE__ */ new Set([
44550
+ "pathBase",
44551
+ "blockId",
44552
+ "blockKind",
44553
+ "blockContent",
44554
+ "fragmentRegistry",
44555
+ "previewAuthoring",
44556
+ "contentVersionId",
44557
+ "imageResolveContext"
44558
+ ]);
44559
+ function omitRendererMetadataProps(props) {
44560
+ const presentationProps = {};
44561
+ for (const [key, value] of Object.entries(props)) if (!RENDERER_METADATA_PROP_KEYS.has(key)) presentationProps[key] = value;
44562
+ return presentationProps;
44563
+ }
44564
+ const BLOCK_ID_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
44565
+ "accordion",
44566
+ "appointment-services",
44567
+ "booking-form",
44568
+ "carousel",
44569
+ "cart",
44570
+ "checkout",
44571
+ "event-calendar",
44572
+ "event-combined",
44573
+ "event-details",
44574
+ "event-listing",
44575
+ "event-registration",
44576
+ "form",
44577
+ "gifting",
44578
+ "headersection",
44579
+ "location-map",
44580
+ "newsletter-form",
44581
+ "product-detail",
44582
+ "product-list",
44583
+ "shop",
44584
+ "weekly-slot-availability"
44585
+ ]);
44586
+ const BLOCK_CONTENT_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
44587
+ "feature-card-icon",
44588
+ "headersection",
44589
+ "media",
44590
+ "text"
44591
+ ]);
44592
+ const BLOCK_KIND_METADATA_CONSUMERS = /* @__PURE__ */ new Set([
44593
+ "headersection",
44594
+ "media",
44595
+ "richtext"
44596
+ ]);
44597
+ /**
44598
+ * Projects resolver context only to node kinds with an explicit metadata
44599
+ * contract. Presentation props and renderer metadata never share a universal
44600
+ * spread boundary, so adding metadata cannot leak it into DOM-backed nodes.
44601
+ */
44430
44602
  function resolveNodeMetadata(nodeType, context) {
44603
+ const normalizedType = nodeType.toLowerCase();
44431
44604
  return {
44432
- pathBase: context.pathBase,
44433
- blockId: context.blockId,
44434
- blockKind: context.blockKind,
44435
- blockContent: context.blockContent,
44436
- fragmentRegistry: context.fragmentRegistry,
44437
- previewAuthoring: context.previewAuthoring,
44438
- ...nodeType.toLowerCase() === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
44439
- ...nodeType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
44605
+ ...BLOCK_ID_METADATA_CONSUMERS.has(normalizedType) ? { blockId: context.blockId } : {},
44606
+ ...BLOCK_KIND_METADATA_CONSUMERS.has(normalizedType) ? { blockKind: context.blockKind } : {},
44607
+ ...BLOCK_CONTENT_METADATA_CONSUMERS.has(normalizedType) ? { blockContent: context.blockContent } : {},
44608
+ ...normalizedType === "headersection" ? {
44609
+ pathBase: context.pathBase,
44610
+ fragmentRegistry: context.fragmentRegistry
44611
+ } : {},
44612
+ ...normalizedType === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
44613
+ ...normalizedType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
44440
44614
  };
44441
44615
  }
44442
44616
  /**
@@ -44472,7 +44646,7 @@ function resolveNode(node, context, indexFallback) {
44472
44646
  props = omitHeadingDecorationProps(props);
44473
44647
  const children = resolveChildren(node.children, scopeContext);
44474
44648
  const elementProps = {
44475
- ...props,
44649
+ ...omitRendererMetadataProps(props),
44476
44650
  key: node.key ?? indexFallback,
44477
44651
  ...resolveNodeMetadata(node.type, context)
44478
44652
  };
@@ -45100,7 +45274,7 @@ function generateInputCss({ themeId, theme, inputSystem }) {
45100
45274
  baseInputRules.push("transition: border-color 0.2s ease, box-shadow 0.2s ease");
45101
45275
  const labelSelector = `${rootSelector} .form-label`;
45102
45276
  const labelRules = [];
45103
- labelRules.push(`color: ${rgbColorValue(inputSystem.label.textColorToken)}`);
45277
+ labelRules.push(`color: ${textColorValue(inputSystem.label.textColorToken)}`);
45104
45278
  labelRules.push(`font-weight: ${FONT_WEIGHT_MAP[inputSystem.label.fontWeight]}`);
45105
45279
  labelRules.push(`font-size: ${LABEL_FONT_SIZE_MAP[inputSystem.label.fontSize]}`);
45106
45280
  if (inputSystem.label.textTransform && inputSystem.label.textTransform !== "none") labelRules.push(`text-transform: ${inputSystem.label.textTransform}`);
@@ -48531,7 +48705,7 @@ function pageBlockPosition(index, blockCount) {
48531
48705
  //#endregion
48532
48706
  //#region ../blocks/src/pageRendererContracts.ts
48533
48707
  function buildPageRendererRootRuntime(dataContext) {
48534
- 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 ?? {};
48708
+ 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 ?? {};
48535
48709
  return {
48536
48710
  siteId,
48537
48711
  pageId,
@@ -48540,6 +48714,7 @@ function buildPageRendererRootRuntime(dataContext) {
48540
48714
  previewStage,
48541
48715
  apiBaseUrl,
48542
48716
  portalToken,
48717
+ readAuthority,
48543
48718
  bookingOfferingPresets,
48544
48719
  appointmentServicePathPrefix,
48545
48720
  mailingList,
@@ -51263,46 +51438,42 @@ const whenTransformed = (from, transformId, equals = true) => (node) => ({
51263
51438
  equals
51264
51439
  }
51265
51440
  });
51266
- const logoRow = link({
51441
+ /** Draw whichever site logo suits the surface this row sits on. */
51442
+ const bindChromeLogo = (surface) => bind("content", { transforms: [{
51443
+ id: "layout.chromeLogo",
51444
+ options: { surface }
51445
+ }] });
51446
+ /**
51447
+ * The brand link. The logo is chosen per surface because the open mobile menu
51448
+ * paints its own background, which may be the opposite tone to the header.
51449
+ */
51450
+ const createLogoRow = (surface) => link({
51267
51451
  href: "/",
51268
51452
  className: bindProp("$root.theme.header.logo", {
51269
51453
  transforms: pipe(tx("layout.headerLogoClass")),
51270
51454
  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"
51271
51455
  })
51272
- }, [
51273
- media({ className: bindProp("$root.theme.header.logo", {
51274
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
51275
- fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
51276
- }) }, when("content.logo"), bind("content.logo")),
51277
- stack({ className: "rb-contents" }, [media({ className: bindProp("$root.theme.header.logo", {
51278
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
51279
- fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
51280
- }) }, when("site.logo"), bind("site.logo"))], when("content.logo", { not: true })),
51281
- text({
51282
- as: "strong",
51283
- className: "header-logo-text rb-truncate"
51284
- }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
51285
- ]);
51456
+ }, [media({ className: bindProp("$root.theme.header.logo", {
51457
+ transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300" })),
51458
+ fallback: "rb-header-logo-sm rb-w-auto rb-transition-all rb-duration-300"
51459
+ }) }, when("content.logo"), bindChromeLogo(surface)), text({
51460
+ as: "strong",
51461
+ className: "header-logo-text rb-truncate"
51462
+ }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))]);
51463
+ const logoRow = createLogoRow("header-root");
51286
51464
  const centeredLogoRow = link({
51287
51465
  href: "/",
51288
51466
  className: bindProp("$root.theme.header.logo", {
51289
51467
  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" })),
51290
51468
  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"
51291
51469
  })
51292
- }, [
51293
- media({ className: bindProp("$root.theme.header.logo", {
51294
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
51295
- fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
51296
- }) }, when("content.logo"), bind("content.logo")),
51297
- stack({ className: "rb-contents" }, [media({ className: bindProp("$root.theme.header.logo", {
51298
- transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
51299
- fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
51300
- }) }, when("site.logo"), bind("site.logo"))], when("content.logo", { not: true })),
51301
- text({
51302
- as: "strong",
51303
- className: "header-logo-text"
51304
- }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
51305
- ]);
51470
+ }, [media({ className: bindProp("$root.theme.header.logo", {
51471
+ transforms: pipe(tx("layout.headerLogoMediaClass", { base: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300" })),
51472
+ fallback: "rb-header-logo-lg rb-w-auto rb-transition-all rb-duration-300"
51473
+ }) }, when("content.logo"), bindChromeLogo("header-root")), text({
51474
+ as: "strong",
51475
+ className: "header-logo-text"
51476
+ }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))]);
51306
51477
  const createNavRow = (className, align = "end") => navRow({
51307
51478
  className: `${className} header-nav-row`,
51308
51479
  align,
@@ -51342,10 +51513,8 @@ const mobileToggleIcon = stack({
51342
51513
  }
51343
51514
  ]);
51344
51515
  const mobileToggleButton = {
51345
- type: "button",
51516
+ type: "headerControl",
51346
51517
  props: {
51347
- type: "button",
51348
- variantId: "",
51349
51518
  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`,
51350
51519
  "aria-label": "Open menu",
51351
51520
  "aria-expanded": "false",
@@ -51355,10 +51524,8 @@ const mobileToggleButton = {
51355
51524
  children: [mobileToggleIcon]
51356
51525
  };
51357
51526
  const mobileOverlayToggleButton = {
51358
- type: "button",
51527
+ type: "headerControl",
51359
51528
  props: {
51360
- type: "button",
51361
- variantId: "",
51362
51529
  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",
51363
51530
  "aria-label": "Open menu",
51364
51531
  "aria-expanded": "false",
@@ -51382,7 +51549,7 @@ const mobileOverlayHeader = inline({
51382
51549
  align: "center",
51383
51550
  justify: "between",
51384
51551
  style: borderColorStyle("border")
51385
- }, [logoRow, mobileOverlayToggleButton]);
51552
+ }, [createLogoRow("header-mobile-panel"), mobileOverlayToggleButton]);
51386
51553
  const mobileOverlayBody = stack({
51387
51554
  className: "rb-flex-1 rb-px-6 rb-py-6",
51388
51555
  gap: "md",
@@ -51570,7 +51737,10 @@ const brandLogo = link({
51570
51737
  options: { base: "rb-h-10 rb-w-auto" }
51571
51738
  }],
51572
51739
  fallback: "rb-h-10 rb-w-auto"
51573
- } } }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content.logo")), text({
51740
+ } } }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content", { transforms: [{
51741
+ id: "layout.chromeLogo",
51742
+ options: { surface: "footer-root" }
51743
+ }] })), text({
51574
51744
  as: "strong",
51575
51745
  className: "footer-logo-text rb-nav-text"
51576
51746
  }, when("module.showTitle", { equals: true }), bind("site.title", { fallback: "Your Site" }))], when("module.kind", { equals: "brand" }));
@@ -58418,6 +58588,7 @@ function blockSessionProps(dataContext) {
58418
58588
  supabaseUrl: dataContext?.supabaseUrl,
58419
58589
  portalToken: dataContext?.portalToken ?? null,
58420
58590
  previewToken: dataContext?.previewToken ?? null,
58591
+ readAuthority: dataContext?.readAuthority,
58421
58592
  stage: dataContext?.previewStage
58422
58593
  };
58423
58594
  }
@@ -61075,6 +61246,12 @@ const containerResponsiveThemeCss = `/*
61075
61246
  :where(.theme-scope) .rb-prose p {
61076
61247
  margin: var(--rt-space-y) 0;
61077
61248
  }
61249
+ :where(.theme-scope) .rb-prose li > p:first-child {
61250
+ margin-top: 0;
61251
+ }
61252
+ :where(.theme-scope) .rb-prose li > p:last-child {
61253
+ margin-bottom: 0;
61254
+ }
61078
61255
  :where(.theme-scope) .rb-prose img {
61079
61256
  display: block;
61080
61257
  max-width: 100%;
@@ -72636,7 +72813,7 @@ function buildPageRouteRenderContext(dataContext) {
72636
72813
  };
72637
72814
  }
72638
72815
  function PageContent(props) {
72639
- const { page, runtimeBoundaries, siteId, resolvedData, bookingOfferingPresets, mailingList, bookingTimeZone, routeMap, pagesByIdentifier, entriesByIdentifier, wrapBlock, registry, blockOverrides, sdkConfig, customBlocks, supabaseUrl, mediaAssets, apiBaseUrl, portalToken, previewToken, dataContext } = props;
72816
+ const { page, runtimeBoundaries, siteId, resolvedData, bookingOfferingPresets, mailingList, bookingTimeZone, routeMap, pagesByIdentifier, entriesByIdentifier, wrapBlock, registry, blockOverrides, sdkConfig, customBlocks, supabaseUrl, mediaAssets, apiBaseUrl, portalToken, previewToken, readAuthority, dataContext } = props;
72640
72817
  const rendererCommonProps = {
72641
72818
  page,
72642
72819
  runtimeBoundaries,
@@ -72646,6 +72823,7 @@ function PageContent(props) {
72646
72823
  apiBaseUrl,
72647
72824
  portalToken,
72648
72825
  previewToken,
72826
+ readAuthority: readAuthority ?? dataContext?.readAuthority,
72649
72827
  resolvedData,
72650
72828
  bookingOfferingPresets: bookingOfferingPresets ?? [],
72651
72829
  mailingList: mailingList ?? dataContext?.mailingList,
@@ -73195,6 +73373,33 @@ function buildLogo(logo, fallbackAlt) {
73195
73373
  if (logo.height != null) result.height = logo.height;
73196
73374
  return result;
73197
73375
  }
73376
+ /**
73377
+ * Build both site logos from layout data. The default header and footer choose
73378
+ * between them by the surface they sit on; custom chrome can do the same.
73379
+ *
73380
+ * @example
73381
+ * ```ts
73382
+ * const logoVariants = buildLogoVariants(siteData.layout, siteData.site.title);
73383
+ * ```
73384
+ */
73385
+ function buildLogoVariants(layout, fallbackAlt) {
73386
+ return {
73387
+ forLightBackgrounds: buildLogo(layout?.logo ?? null, fallbackAlt),
73388
+ forDarkBackgrounds: buildLogo(layout?.logoForDarkBackgrounds ?? null, fallbackAlt)
73389
+ };
73390
+ }
73391
+ /**
73392
+ * Header/footer block content for the site logos. `logo` stays populated with
73393
+ * whichever logo exists so presence checks keep working; `logoVariants` is
73394
+ * what the blocks select from at render.
73395
+ */
73396
+ function buildChromeLogoContent(layout, fallbackAlt) {
73397
+ const logoVariants = buildLogoVariants(layout, fallbackAlt);
73398
+ return {
73399
+ logo: logoVariants.forLightBackgrounds ?? logoVariants.forDarkBackgrounds,
73400
+ logoVariants
73401
+ };
73402
+ }
73198
73403
  //#endregion
73199
73404
  //#region src/rendering/themeAdmission.ts
73200
73405
  const MISSING_SDK_THEME_ERROR_CODE = "missing_sdk_theme";
@@ -74700,10 +74905,10 @@ async function Layout(props) {
74700
74905
  const menuViewModel = buildMenu(navigation, routes, navigationOptions);
74701
74906
  const footerMenuViewModel = buildFooterMenu(navigation, routes, navigationOptions);
74702
74907
  const legalFooterMenuViewModel = buildFooterMenuForRole(navigation, routes, "legal-policy", navigationOptions);
74703
- const logoViewModel = buildLogo(layout.logo ?? null, site.title);
74908
+ const chromeLogoContent = buildChromeLogoContent(layout, site.title);
74704
74909
  const customHeaderData = {
74705
74910
  menu: menuViewModel,
74706
- logo: logoViewModel,
74911
+ ...chromeLogoContent,
74707
74912
  site,
74708
74913
  routes
74709
74914
  };
@@ -74711,7 +74916,7 @@ async function Layout(props) {
74711
74916
  menu: menuViewModel,
74712
74917
  footerMenu: footerMenuViewModel,
74713
74918
  legalFooterMenu: legalFooterMenuViewModel,
74714
- logo: logoViewModel,
74919
+ ...chromeLogoContent,
74715
74920
  site,
74716
74921
  routes
74717
74922
  };
@@ -74768,13 +74973,13 @@ async function Layout(props) {
74768
74973
  };
74769
74974
  const headerViewModelOverrides = {
74770
74975
  ...sharedViewModelOverrides,
74771
- content: { logo: logoViewModel }
74976
+ content: chromeLogoContent
74772
74977
  };
74773
74978
  const footerViewModelOverrides = {
74774
74979
  ...sharedViewModelOverrides,
74775
74980
  content: {
74776
74981
  ...layout.footer,
74777
- logo: logoViewModel
74982
+ ...chromeLogoContent
74778
74983
  }
74779
74984
  };
74780
74985
  let headerElement = null;