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