@riverbankcms/sdk 0.104.3 → 0.107.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 (236) hide show
  1. package/README.md +84 -51
  2. package/dist/{PreviewEditorSidebar-CBMhU9p_.mjs → PreviewEditorSidebar-DpAbAl08.mjs} +1811 -1179
  3. package/dist/{PreviewEditorUI-C5KEw4M8.mjs → PreviewEditorUI-O7cn6Xxv.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-CStABBUh.mjs → PreviewQueryProvider-D0tnKl0t.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-Iq12HjL7.mjs → SdkPreviewModeRuntime-CVB7urtl.mjs} +2144 -393
  6. package/dist/{SiteChromeCustomizeContext-Cx0NMdyv.mjs → SiteChromeCustomizeContext-C_sizso-.mjs} +3825 -2653
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +32945 -1339
  8. package/dist/_dts/api/src/bookingConfig.d.ts +2 -0
  9. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +5 -1
  10. package/dist/_dts/api/src/contentRuntime.d.ts +6 -15
  11. package/dist/_dts/api/src/courses.d.ts +68 -10
  12. package/dist/_dts/api/src/endpoints.d.ts +29 -0
  13. package/dist/_dts/api/src/index.d.ts +124 -124
  14. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +9 -0
  15. package/dist/_dts/api/src/sdkContracts.d.ts +116 -6
  16. package/dist/_dts/api/src/siteOperations.d.ts +1 -0
  17. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +26 -4
  18. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +31 -46
  19. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +36 -4
  20. package/dist/_dts/blocks/src/definitions.d.ts +1 -1
  21. package/dist/_dts/blocks/src/portal/types.d.ts +25 -7
  22. package/dist/_dts/blocks/src/system/blocks/course-registration.d.ts +2 -2
  23. package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +2 -0
  24. package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +2 -0
  25. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +4 -0
  26. package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule-projection.d.ts +52 -0
  27. package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule.d.ts +22 -0
  28. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +45 -0
  29. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +10 -0
  30. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +4 -1
  31. package/dist/_dts/blocks/src/system/blocks/index.d.ts +1 -0
  32. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +9 -0
  33. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +8 -2
  34. package/dist/_dts/blocks/src/system/blocks/offerings-preview/index.d.ts +8 -8
  35. package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +24 -24
  36. package/dist/_dts/blocks/src/system/blocks/offerings-preview/scheduleSummary.d.ts +29 -0
  37. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +2 -1
  38. package/dist/_dts/blocks/src/system/constants/blockKinds.d.ts +1 -1
  39. package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +2 -5
  40. package/dist/_dts/blocks/src/system/data/loaderEndpoints.d.ts +1 -1
  41. package/dist/_dts/blocks/src/system/designCapabilities.d.ts +1 -0
  42. package/dist/_dts/blocks/src/system/fragments/library/newsletterForm.d.ts +2 -2
  43. package/dist/_dts/blocks/src/system/node/fragments/styledCard.d.ts +3 -0
  44. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  45. package/dist/_dts/blocks/src/system/runtime/blockComposition.d.ts +2 -0
  46. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +90 -6
  47. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +45 -3
  48. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +1 -0
  49. package/dist/_dts/blocks/src/system/runtime/nodes/commerce/shared/display.d.ts +2 -2
  50. package/dist/_dts/blocks/src/system/runtime/nodes/course-details/logic.d.ts +2 -1
  51. package/dist/_dts/blocks/src/system/runtime/nodes/course-details/view.d.ts +1 -0
  52. package/dist/_dts/blocks/src/system/runtime/nodes/course-details.server.d.ts +2 -1
  53. package/dist/_dts/blocks/src/system/runtime/nodes/course-page-surface-scope.d.ts +17 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/types.d.ts +3 -0
  55. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.interactive.d.ts +5 -0
  56. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.server.d.ts +1 -1
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventScope.d.ts +9 -18
  58. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +106 -0
  59. package/dist/_dts/blocks/src/system/runtime/nodes/events/RecurringSchedule.d.ts +11 -0
  60. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +7 -3
  61. package/dist/_dts/blocks/src/system/runtime/nodes/media.d.ts +3 -0
  62. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +11 -1
  63. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.server.d.ts +1 -1
  64. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +3 -0
  65. package/dist/_dts/blocks/src/system/runtime/nodes/offerings-preview.d.ts +6 -6
  66. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +11 -5
  67. package/dist/_dts/blocks/src/system/runtime/nodes/shop.types.d.ts +2 -1
  68. package/dist/_dts/blocks/src/system/runtime/nodes/svg.d.ts +7 -0
  69. package/dist/_dts/core/src/branded.d.ts +44 -0
  70. package/dist/_dts/core/src/dated-offering-settlement.d.ts +47 -0
  71. package/dist/_dts/core/src/event-page-surface-subject.d.ts +44 -0
  72. package/dist/_dts/core/src/index.d.ts +49 -47
  73. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +1452 -15
  74. package/dist/_dts/editor-blocks/src/block-editor/FeatureCardIconsPanel.d.ts +1 -1
  75. package/dist/_dts/editor-blocks/src/block-editor/GeneratedIconSetDialog.d.ts +4 -1
  76. package/dist/_dts/media-core/src/index.d.ts +2 -1
  77. package/dist/_dts/media-core/src/storagePathDomain.d.ts +47 -0
  78. package/dist/_dts/media-core/src/url.d.ts +1 -21
  79. package/dist/_dts/preview-next/src/client/blocks/pageDesignRuntimePreview.d.ts +4 -2
  80. package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -1
  81. package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -1
  82. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +3 -9
  83. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +7 -11
  84. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +3 -9
  85. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +2 -6
  86. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.d.ts +5 -9
  87. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +81 -43
  88. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.typography.d.ts +61 -0
  89. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +7 -17
  90. package/dist/_dts/preview-next/src/client/preview/styleConfiguratorSnapshot.d.ts +15 -8
  91. package/dist/_dts/preview-next/src/client/preview/typographyFontCatalog.d.ts +57 -0
  92. package/dist/_dts/sdk/src/cli/commands/pull.d.ts +1 -1
  93. package/dist/_dts/sdk/src/cli/commands/push/execute/theme.d.ts +4 -7
  94. package/dist/_dts/sdk/src/cli/commands/style.d.ts +24 -10
  95. package/dist/_dts/sdk/src/cli/site-commands/oneOffCommands.d.ts +3 -3
  96. package/dist/_dts/sdk/src/cli/sync/media.d.ts +16 -2
  97. package/dist/_dts/sdk/src/client/management/blocks.d.ts +1 -1
  98. package/dist/_dts/sdk/src/client/management/index.d.ts +1 -1
  99. package/dist/_dts/sdk/src/client/management/types.d.ts +132 -23
  100. package/dist/_dts/sdk/src/client/types.d.ts +2 -0
  101. package/dist/_dts/sdk/src/config/types.d.ts +1 -1
  102. package/dist/_dts/sdk/src/config/validation.d.ts +3 -0
  103. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  104. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +23 -3
  105. package/dist/_dts/sdk/src/data/dataLoaderContext.d.ts +17 -0
  106. package/dist/_dts/sdk/src/data/dataLoaderValue.d.ts +36 -0
  107. package/dist/_dts/sdk/src/data/defineOwnDataProperty.d.ts +2 -0
  108. package/dist/_dts/sdk/src/data/executeCodeLoaders.d.ts +36 -40
  109. package/dist/_dts/sdk/src/data/index.d.ts +3 -3
  110. package/dist/_dts/sdk/src/data/resolveBlockData.d.ts +54 -0
  111. package/dist/_dts/sdk/src/data/types.d.ts +43 -78
  112. package/dist/_dts/sdk/src/next/index.d.ts +1 -0
  113. package/dist/_dts/sdk/src/next/redirect-destination.d.ts +1 -1
  114. package/dist/_dts/sdk/src/next/resolveTheme.d.ts +2 -1
  115. package/dist/_dts/sdk/src/next/types.d.ts +10 -1
  116. package/dist/_dts/sdk/src/public-api/contracts.d.ts +3 -8
  117. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +9 -4
  118. package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +6 -10
  119. package/dist/_dts/sdk/src/rendering/index.d.ts +1 -0
  120. package/dist/_dts/sdk/src/server.d.ts +4 -3
  121. package/dist/_dts/sdk/src/types/block-kinds.d.ts +1 -1
  122. package/dist/_dts/sdk/src/version.d.ts +1 -1
  123. package/dist/_dts/site-commands/src/capabilityGaps.d.ts +2 -2
  124. package/dist/_dts/site-commands/src/commands.d.ts +921 -30
  125. package/dist/_dts/theme-core/src/buttons/generateDefaultButtonSystem.d.ts +5 -1
  126. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +11 -0
  127. package/dist/_dts/theme-core/src/buttons/personalities/quiet-arrow.d.ts +17 -0
  128. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +2 -2
  129. package/dist/_dts/theme-core/src/buttons/types.d.ts +9 -5
  130. package/dist/_dts/theme-core/src/data.d.ts +12 -0
  131. package/dist/_dts/theme-core/src/fonts/index.d.ts +1 -1
  132. package/dist/_dts/theme-core/src/fonts/types.d.ts +6 -0
  133. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  134. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +36 -24
  135. package/dist/_dts/theme-core/src/palette/colors.d.ts +12 -0
  136. package/dist/_dts/theme-core/src/palette/curated/brand-led.d.ts +10 -5
  137. package/dist/_dts/theme-core/src/palette/curated/high-contrast.d.ts +6 -3
  138. package/dist/_dts/theme-core/src/palette/curated/index.d.ts +31 -236
  139. package/dist/_dts/theme-core/src/palette/curated/soft-natural.d.ts +8 -4
  140. package/dist/_dts/theme-core/src/palette/curated/types.d.ts +14 -12
  141. package/dist/_dts/theme-core/src/palette/curated/warm-dark.d.ts +4 -2
  142. package/dist/_dts/theme-core/src/palette/curated/warm-neutral.d.ts +8 -4
  143. package/dist/_dts/theme-core/src/palette/editorState.d.ts +33 -3
  144. package/dist/_dts/theme-core/src/palette/index.d.ts +0 -4
  145. package/dist/_dts/theme-core/src/palette/libraryModel.d.ts +12 -6
  146. package/dist/_dts/theme-core/src/palette/persistenceReadSource.d.ts +20 -72
  147. package/dist/_dts/theme-core/src/palette/resolveSelection.d.ts +29 -4
  148. package/dist/_dts/theme-core/src/palette/selection.d.ts +6 -4
  149. package/dist/_dts/theme-core/src/schema.d.ts +121 -4
  150. package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +218 -158
  151. package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +5 -6
  152. package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +218 -158
  153. package/dist/_dts/theme-core/src/site-styles/compositionBudget.d.ts +1 -0
  154. package/dist/_dts/theme-core/src/site-styles/contentTemplateRuntimeCompiler.d.ts +2 -1
  155. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +161 -51
  156. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +6 -0
  157. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  158. package/dist/_dts/theme-core/src/site-styles/index.d.ts +1 -1
  159. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +24 -1
  160. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +14 -48
  161. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +10 -23
  162. package/dist/_dts/theme-core/src/site-styles/siteStyleThemeCompiler.d.ts +1 -2
  163. package/dist/_dts/theme-core/src/site-styles/siteStyleTypography.d.ts +456 -0
  164. package/dist/_dts/theme-core/src/site-styles/types.d.ts +52 -3
  165. package/dist/cli/index.mjs +3155 -1701
  166. package/dist/client/{DiscountCodeDisclosure-BXM73_E5.mjs → DiscountCodeDisclosure-BwGkvmVH.mjs} +1 -1
  167. package/dist/client/{EventCombined.client-DT5elP7j.mjs → EventCombined.client-JnWE6Hzc.mjs} +3 -3
  168. package/dist/client/{EventListing.client-pTYGfV9C.mjs → EventListing.client-DQewc_kg.mjs} +2 -2
  169. package/dist/client/{LeafletStaticMap-dQrhlUe3.mjs → LeafletStaticMap-DPAU3SFt.mjs} +1 -1
  170. package/dist/client/{MagicLinkForm-u6Dul4j5.mjs → MagicLinkForm-D4kpWCbW.mjs} +2 -2
  171. package/dist/client/{StepIndicator-nWqineJ2.mjs → StepIndicator-CBlkb4rA.mjs} +2 -2
  172. package/dist/client/{accordion-CSJcTUyH.mjs → accordion-DAIBVpTS.mjs} +1 -1
  173. package/dist/client/{bookingForm-C73wOuVa.mjs → bookingForm-DZ-4l5_1.mjs} +7 -7
  174. package/dist/client/bookings.mjs +239 -110
  175. package/dist/client/{buttons-DfYyqt8C.mjs → buttons-DJgynGHQ.mjs} +122 -58
  176. package/dist/client/{carousel-fMBb0JSc.mjs → carousel-D-SLfX8r.mjs} +1 -1
  177. package/dist/client/{cart-BtaCwT3S.mjs → cart-CEgbgJhX.mjs} +3 -3
  178. package/dist/client/{checkout-DkTwZSnh.mjs → checkout-CXWrCRAA.mjs} +3 -3
  179. package/dist/client/client.mjs +4300 -1560
  180. package/dist/client/{colorStyles-Wyl6JujD.mjs → colorStyles-jZS6KfkP.mjs} +1 -1
  181. package/dist/client/{colorTokenParts-dT8MISgJ.mjs → colorTokenParts-CMugwvX_.mjs} +3 -1
  182. package/dist/client/{courseRegistration-DnLmapJu.mjs → courseRegistration-DVmLrRVz.mjs} +56 -21
  183. package/dist/client/{eventCalendar-BvLOc9KY.mjs → eventCalendar-DCuyPY_c.mjs} +29 -21
  184. package/dist/client/{eventCombined-kShgJPQr.mjs → eventCombined-kP2CA2D4.mjs} +2 -2
  185. package/dist/client/{eventDetails-C5NTM0Vo.mjs → eventDetails-DU0LeF5e.mjs} +4 -4
  186. package/dist/client/{eventListing-B82ZdKP6.mjs → eventListing-CcHF87BI.mjs} +2 -2
  187. package/dist/client/{eventRegistration-qJVFqBWo.mjs → eventRegistration-DJnR0yFH.mjs} +8 -8
  188. package/dist/client/{form-BvAcKiuu.mjs → form-CH1lCusH.mjs} +2 -2
  189. package/dist/client/{headerSection-NvAiEHAg.mjs → headerSection-CBPFZoku.mjs} +3 -3
  190. package/dist/client/hooks.mjs +2958 -1848
  191. package/dist/client/{locationMap-D0j52xfI.mjs → locationMap-Cx1hBg5n.mjs} +3 -3
  192. package/dist/client/{media-BCW_g2cQ.mjs → media-DHtSxS5V.mjs} +61 -56
  193. package/dist/client/{newsletterForm-B8_i93qH.mjs → newsletterForm-1ZL_ti9u.mjs} +3 -3
  194. package/dist/client/{pricing-DIYnyHOk.mjs → pricing-BIbzmV0G.mjs} +1 -1
  195. package/dist/client/{productDetail-w0eAHkuQ.mjs → productDetail-BTh5gHBV.mjs} +3 -3
  196. package/dist/client/{productList-Vsguq5Xt.mjs → productList-Cc7OMrqN.mjs} +3 -3
  197. package/dist/client/{propsDecoder-CD2pJ1WB.mjs → propsDecoder-oR-M-ISN.mjs} +192 -59
  198. package/dist/client/rendering/client.mjs +2031 -1239
  199. package/dist/client/rendering/islands.mjs +20 -20
  200. package/dist/client/rendering.mjs +4889 -1712
  201. package/dist/client/{shop-Dgxs-Q8F.mjs → shop-CQ_YbCnn.mjs} +8 -8
  202. package/dist/client/{shop-commerce-DJAhsTaT.mjs → shop-commerce-BM-AoD3M.mjs} +6 -6
  203. package/dist/client/{shop-commerce-store-CfCXltXW.mjs → shop-commerce-store-DFMQhU5p.mjs} +1 -1
  204. package/dist/client/{shopShared-CmDcPXUt.mjs → shopShared-D0SKO2Cu.mjs} +3 -3
  205. package/dist/client/{useDiscountCodeUi-CirrT2bM.mjs → useDiscountCodeUi-CrG4_ARt.mjs} +1 -1
  206. package/dist/client/{useEventFilters-CNZxlCcO.mjs → useEventFilters-CxK8Fekl.mjs} +6 -6
  207. package/dist/client/{usePolling-Baks_iBI.mjs → usePolling-jcVryNgZ.mjs} +2 -2
  208. package/dist/preview-next/before-render.mjs +40 -1
  209. package/dist/preview-next/client/runtime.mjs +4 -4
  210. package/dist/preview-next/middleware.mjs +40 -1
  211. package/dist/{previewAuthStore-CfquDtTh.mjs → previewAuthStore-BPcJPzdz.mjs} +40 -1
  212. package/dist/{sdk-runtime-BfNiFeNJ.mjs → sdk-runtime-C39Rsk-x.mjs} +2 -2
  213. package/dist/{separator-BhAR_Xmf.mjs → separator-BoMSQnsP.mjs} +1 -1
  214. package/dist/server/components.mjs +4661 -2162
  215. package/dist/server/config-validation.mjs +2728 -1847
  216. package/dist/server/config.mjs +2728 -1847
  217. package/dist/server/data.mjs +3381 -1915
  218. package/dist/server/index.mjs +46 -4
  219. package/dist/server/next/middleware.mjs +1 -1
  220. package/dist/server/next.mjs +5555 -2225
  221. package/dist/server/page-converter.mjs +3058 -2182
  222. package/dist/server/prebuild.mjs +1 -1
  223. package/dist/server/rendering/server.mjs +4850 -2125
  224. package/dist/server/rendering.mjs +5664 -2464
  225. package/dist/server/routing.mjs +3027 -1509
  226. package/dist/server/server.mjs +3844 -2217
  227. package/dist/server/theme-bridge.mjs +9121 -7765
  228. package/dist/server/theme.mjs +152 -59
  229. package/dist/styles/index.css +1217 -31
  230. package/package.json +1 -1
  231. package/dist/_dts/preview-next/src/client/preview/typographySelectionInput.d.ts +0 -16
  232. package/dist/_dts/theme-core/src/palette/historicalThemePalette.d.ts +0 -44
  233. package/dist/_dts/theme-core/src/palette/legacyRuntimeProjection.d.ts +0 -55
  234. package/dist/_dts/theme-core/src/palette/legacySelection.d.ts +0 -45
  235. package/dist/_dts/theme-core/src/palette/paletteCompatibilityTransition.d.ts +0 -232
  236. package/dist/_dts/theme-core/src/site-styles/typographyPresets.d.ts +0 -234
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { $ as PreviewRichTextEditor, $a as previewStageSchema, $c as cssVarValue, $l as CollapsibleContent, $n as buildEventCalendarListingRender, $r as ctaCopyFragment, $s as ClockIcon$1, $t as deleteEntrySlotBlock, $u as publicEventPricingCurrency, Aa as normalizeOfferingsPreviewGroupOrder, Ac as isRotationDimensionSwap, Ad as Settings, Ai as getCuratedSiteStyle, Al as Label, An as SITE_CHROME_VISIBLE_HEADER_SELECTOR, Ao as formatEventCompactDateRail, Ar as formatCommercePrice, As as unwrapRichTextRoot, At as createRoutingHelpers, Au as Primitive, Ba as eventPageSizeSchema, Bi as NAV_LINK_LETTER_SPACING_MAP, Bl as Content$1, Bn as isInternalResolvedLinkValue, Bo as resolveEventLinkProps, Br as augmentManifestWithStyleGroups, Bs as getSemanticIconComponent, Bt as ManifestForm, Bu as unsafeAsEditorBlockValues, Cc as resolveImageUrlWithContext, Ci as retargetCompiledBoundaryRuntimeForContentAdjacency, Cl as TooltipTrigger, Cn as isSupportedLoaderEndpoint, Co as resolveTokenOrCssColorValue, Cr as buildProductDetailInteractiveIslandProps, Cs as getGeneratedBlockIconStyleState, Ct as pushHistoryEntry, Cu as __spreadArrays, Da as buildOfferingsPreviewRenderStates, Dc as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, Dd as Star, Di as resolveVisiblePromotedFieldPathsForEditorBlock, Dl as SelectItem, Dn as listBlockDescriptors, Do as normalizeLocationMapProps, Dr as buildCartDisplay, Ds as parseGeneratedIconSetId, Dt as recordsEqual, Du as useControllableState, Ea as OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS, Ec as setContextResolveImageUrlContext, Ei as planPageDesignLayoutLookCompatibility, El as SelectContent, En as getBlockDefinition, Eo as buildGoogleMapsDirectionsUrl, Er as getShopDisplayForItems, Es as parseGeneratedIconAssetId, Et as unsafeAsLinkedContentEntryId, Eu as createCollection, Fa as resolveOfferingsPreviewGroups, Fc as asRecord, Fd as Pencil, Fi as getComponentBorderWidthPx, Fl as Input, Fn as mediaTransforms, Fo as formatTime$3, Fr as deriveCommerceCheckoutState, Fs as isInlineTextEmpty, Ft as PaletteProvider, Fu as clsx, G as beginAutosaveBatch, Ga as normalizeCsvString, Gc as generateShadowValue$1, Gd as ImageOff, Gi as INPUT_FONT_SIZE_MAP, Gl as Dialog, Gn as productDetailBlockDefinition, Go as resolveRuntimeEventPricing, Gr as faqHeadingFragment, Gs as CalendarIcon$1, Gt as createStoreBackend, Gu as formatBookingTime, Ha as resolveEventCalendarListPageSize, Hc as AFFORDANCE_SUPPRESS_CLASS, Hd as Image, Hi as NAV_LINK_PADDING_X_MAP, Hl as Root2$1, Hn as useImageResolveContextOptional, Ho as getEventAvailabilityStatus, Hr as headingFragment, Hs as ArrowDownIcon, Hu as formatBookingDate, Ia as isSemanticSpacing, Ic as getDirectImageUrlForMediaAsset, Ii as getComponentShadowVar, Il as Tabs, In as layoutTransforms, Io as getCardOrientation, Ir as parseStoredCommerceCartState, Is as parseInlineTextFromUnknown, It as usePalette, Iu as createEditorInsertBlockCommand, J as enqueueTransaction, Ja as columnOptionSchema, Jc as TokenResolver, Jd as FileText, Jl as DialogDescription, Jn as eventListingBlockDefinition, Jo as createInteractiveIslandCodec, Jr as footerBottomTextFragment, Js as ChevronLeftIcon, Jt as applyPageDesignEditorAction, Ju as parseBookingLocalDate, K as confirmAutosaveBatch, Ka as normalizeOptionalId, Kc as generateBaseInteractiveCSS, Kd as GripVertical, Ki as INPUT_SPACING_MAP, Kl as DialogClose, Kn as newsletterSignupBlockDefinition, Ko as blockBookingPaymentTermsSchema, Kr as blogFeaturedPostFragment, Ks as CheckIcon$1, Kt as listContentTypes, Ku as formatLocalScheduleDate, La as resolveSpacing, Lc as getImageUrl, Li as parseBlockCustomCssRules, Ll as TabsContent, Ln as uiTransforms, Lo as getContainerClass, Lr as productItemKey, Ls as isIconPickerPreset, Lt as recoveryConflictCopy, Lu as createEditorRemoveBlockCommand, Ma as resolveOfferingsPreviewCoursePath, Mc as formatAspectRatioToken, Md as RotateCcw, Mi as isThemeV2NormalEditorRawStyleFieldName, Ml as Popover, Mn as planSiteOverlayHeaderClearance, Mo as formatEventPrice, Mr as EMPTY_COMMERCE_CART_STATE, Ms as isRecord$20, Mu as cva, Na as resolveOfferingsPreviewGroupCta, Nc as parseAspectRatioValue, Ni as isThemeV2NormalEditorRawStylePath, Nl as PopoverContent, Nn as visibleHeaderClearancePx, No as formatEventPriceDisplay, Nr as buildPassCartItem, Ns as coerceInlineTextWithFallback, Nu as useComposedRefs, Oa as inferLegacyOfferingsPreviewGroupOrder, Oc as resolveMediaSlotContract, Od as Sparkles, Ol as SelectTrigger, On as siteFooterManifest, Oo as toLocationMapHydrationProps, Or as buildProductCardDisplay, Os as parseSiteIconStyleGuideVersionId, Ou as createContextScope, Pa as resolveOfferingsPreviewGroupOrderEntries, Pc as resolveMediaTransformForAspect, Pd as Plus, Pi as pageDesignEditorBackgroundOverrideOwner, Pl as PopoverTrigger, Pn as contentTransforms, Po as formatEventTeacherLine, Pr as buildProductCartItem, Ps as inlineTextToPlainText, Pu as cn$1, Q as resolvePreviewSidebarTab, Qa as filterAutoShowSchema, Qc as borderColorStyle, Qd as FileArchive, Ql as Collapsible, Qn as buildEventCalendarListingDisplay, Qo as defineProgressiveBlockRuntime, Qr as testimonialsHeadingFragment, Qs as CirclePlusIcon, Qt as deleteBlock, Qu as formatBookingPriceDisplay, Ra as buildEventRuntimeFilters, Rc as getAtPath, Ri as parseCustomCssRules, Rl as TabsList, Rn as formattingTransforms, Ro as groupEventsByDate, Rr as reduceCommerceCart, Rs as resolveIconPickerPreset, Rt as unfinishedBlockCopy, Ru as createEditorReorderBlocksCommand, Sa as ctaButton, Sc as renderVideo, Sf as __toESM, Si as compileEditorModelRuntime, Sl as TooltipProvider, Sn as useUniqueId, So as resolveOnColorForThemeToken, Sr as buildCheckoutInteractiveIslandProps, Ss as getBlockIconSemanticId, St as createHistoryState, Su as __spreadArray, Tc as resolveMediaStorageUrl, Td as Ticket, Ti as normalEditorCuratedPromotedFieldPaths, Tl as Select, Tn as GRADIENT_PRESETS, To as featuresFromHex, Tr as buildShopInteractiveIslandProps, Ts as resolveBlockIconRenderValue, Tt as undoHistory, Tu as useDirection, Ua as resolveEventListPaginationAction, Uc as generateButtonCss, Ud as ImageUp, Ui as NAV_LINK_TEXT_SIZE_MAP, Ul as Trigger$1, Un as shopBlockDefinition, Uo as getLocalDateKey, Ur as cardFragment, Us as ArrowLeftIcon, Ut as FormRenderer, Uu as formatBookingDateTime, Va as getEventRuntimeFiltersKey, Vd as LoaderCircle, Vi as NAV_LINK_PADDING_MAP, Vl as List, Vn as ImageResolveContextProvider, Vo as getEventAvailability, Vr as richTextFragment, Vs as isSemanticIconId, Vt as createManifestFormAdapter, Vu as addLocalScheduleDays, Wa as normalizeCsvIds, Wc as generateEffectsCSS, Wd as ImagePlus, Wi as FONT_WEIGHT_MAP, Wl as ScrollableDialogContent, Wn as productListBlockDefinition, Wo as getLocalMinuteOfDay, Wr as faqAccordionFragment, Ws as ArrowRightIcon, Wt as evaluateVisibility, Wu as formatBookingInstant, X as rejectAutosaveBatch, Xa as eventCalendarDefaultViewSchema, Xc as themeButtonClassName, Xd as FilePlay, Xl as DialogHeader, Xn as eventCalendarBlockDefinition, Xo as createZodCodec, Xr as formCopyFragment, Xs as ChevronUpIcon, Xt as createBlock, Xu as toBookingTimeZone, Y as idleEditorTransactionQueueState, Ya as eventButtonVariantSchema, Yc as parseThemeButtonVariantId, Yd as FileSpreadsheet, Yl as DialogFooter, Yn as buildEventListingInteractiveIslandProps, Yo as defineInteractiveIslandMetaKeys, Yr as formEmbedFragment, Ys as ChevronRightIcon, Yt as getPageDesignEditorState, Yu as resolveBookingTimeZoneId, Za as eventLayoutSchema, Zc as backgroundColorStyle, Zd as FileHeadphone, Zl as DialogTitle, Zn as buildEventCalendarInteractiveIslandProps, Zo as defineClientOwnedBlockRuntime, Zr as testimonialsCarouselFragment, Zs as CircleMinusIcon, Zt as createEntrySlotBlock, Zu as toScheduledBookingDateTime, _c as MediaPlaceholder, _d as err$2, _f as ArrowUp, _i as mergeHeaderNavTypographyPreference, _l as unmapValueFromSelect, _n as useSensors, _o as generateCardCss, _r as courseRegistrationBlockDefinition, _s as resolveFeatureCardGeneratedIconSizePx, _t as useEditorUiStore, _u as __awaiter, aa as sectionTransitionFamilyForBoundaryOptionId, ac as FileTextIcon, ad as assertNever$5, af as Clock3, ai as PUBLIC_FILE_FIELD_KINDS, al as surfaceForegroundValue, an as DEFAULT_LAUNCH_READINESS_INPUT, ao as bindingSchema, ar as findEventByOccurrenceId, as as assertNever$6, at as getRichTextImagePositionFromTarget, au as Card, ba as createTransformRegistry, bc as getCurrentResolveImageUrlContext, bd as X, bf as __commonJSMin, bi as PAGE_DESIGN_EDITOR_STATE_FETCH_ERROR_MESSAGE, bl as Tooltip, bn as useCombinedRefs, bo as normalizeCardVariantRole, br as cartBlockDefinition, bs as toFeatureCardIconSuggestionInputs, bt as canRedoHistory, bu as __read, ca as backgroundAppearanceColorTokenNames, cc as MapPinIcon$1, cd as parseSiteId, cf as CircleCheck, ci as MQ_MD_DOWN, cl as getModalConfig, cn as DndContext, co as eventSurfaceScopeValues, cr as resolveEventRequiresPayment, cs as ACCORDION_TRIGGER_FONT_SCALE, ct as EditorProvider, cu as CardTitle, da as parseBackgroundAppearanceColorToken, dc as PlayIcon, dd as unsafeAsCustomerPassId, df as ChevronUp, di as MQ_TABLET_ONLY, dl as useBlockContext, dn as closestCenter, do as normalizeEventScheduleScope, dr as getStepNumber$1, ds as ICON_SIZE_PX, dt as useUISelector, du as DropdownMenuContent, ec as DownloadIcon, ed as publicEventPricingMode, ef as EyeOff, ei as heroCtaRowFragment, el as mergeStyles, eo as weekStartSchema, er as formBlockDefinition, es as composeHeaderSectionWrapperClassName, et as PreviewInlineTextEditor, fa as defaultThemeTokens, fc as PlusIcon, fd as unsafeAsFormId, ff as ChevronRight, fi as BACKGROUND_POSITION_PRESET_VALUES, fl as SdkConfigProvider, fn as getClientRect, fo as normalizeEventStaffMemberId, fr as getWizardStepsForContext$1, fs as PUBLIC_DOWNLOAD_MEDIA_TYPES, ft as EditableBlockProvider, fu as DropdownMenuItem, g as PreviewDesignCoordinatorProvider, gc as ImagePresets, gd as unsafeAsPositiveSeconds, gf as Box, gi as resolveBackgroundColorValue, gl as mapOptionValueForSelect, gn as useSensor, go as publicEventSchema, gr as buildGiftingInteractiveIslandProps, gs as getFeatureCardIconCompletion, gu as __assign, hc as XIcon, hd as unsafeAsPositiveByteCount$1, hf as Check, hi as resolveSurfaceForegroundStyles, hl as mapCurrentValueForSelect, hn as useDroppable, ho as normalizeEventVenueId, hr as giftingBlockDefinition, hs as createFeatureCardIconKey, ht as useEntryEditorController, hu as DropdownMenuTrigger, i as usePreviewDesignHistoryOrder, ia as sectionTransitionFamilies, ic as FileSpreadsheetIcon, id as formatCurrencyAmount, if as Copy, ii as defineFragment, il as surfaceForegroundDeclarations, in as decodePublicProductCategorySelectorQuery, io as when, ir as toRegistrationEvents, is as asDesignBlockId, it as RichTextEditorSurface, iu as createCollapsibleScope, ja as normalizeOfferingsPreviewItemLimit, jc as normalizeRightAngle, jd as Search, ji as surfaceResolutionContextFromTheme, jl as Badge, jn as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, jo as formatEventDateParts, jr as formatInterval, js as isObjectRecord, jt as createSnapshotFromPageRecord, ju as Button, ka as isOfferingsPreviewSourceKey, kc as attachRenderableMediaAssetFields, ki as designRuntimeRulesForTheme, kl as SelectValue, kn as siteHeaderManifest, ko as formatDate$3, kr as buildProductDetailDisplay, ks as createRichTextDocFromMarkdown, kt as useDebouncedLatestSave, ku as composeEventHandlers, la as backgroundAppearanceQuickColorTokenNames, lc as MinusIcon, ld as unsafeAsAppointmentResourceId, lf as CircleAlert, li as MQ_SM_DOWN, ll as isHeaderField, ln as KeyboardCode, lo as normalizeEventBlockKind, lr as resolveRegistrationTarget, ls as ACCORDION_TRIGGER_LETTER_SPACING, lt as useEditor, mc as UploadIcon, md as unsafeAsPassId, mf as ChevronDown, mi as boxStylesTransforms, ml as hasEmptyOption, mn as useDraggable, mo as normalizeEventSurfaceScope, mr as resolveEventRegistrationScopedEvents, ms as FEATURE_CARD_ICON_TREATMENTS, mu as DropdownMenuSeparator, n as useSiteChromeCustomizeOptional, na as boundaryRuntimeMetricsForTransition, nc as FileArchiveIcon, nd as publicEventScalarPrice, nf as Crop, ni as heroCopyFragment, nl as textColorStyle, nn as reorderBlocks, no as eventCalendarListLayoutOptions, nr as eventRegistrationBlockDefinition, ns as splitPositioningClasses, nt as useRichTextEditor, nu as Root, oa as sectionTransitionVariantForBoundaryOptionId, oc as InfoIcon, od as expectParsedBrandedId, of as CirclePlus, oi as siteOptionSources, ol as useBackendWatch, on as deriveLaunchReadiness, oo as eventBlockKindValues, or as findPreSelectedEvent, os as ACCORDION_OPEN_ACCENT_THICKNESS, ot as insertOrReplaceRichTextImage, ou as CardContent, pc as ShoppingCartIcon, pd as unsafeAsMediaAssetId, pf as ChevronLeft, pi as getAnchorClasses, pl as useSdkConfig, pn as useDndContext, po as normalizeEventSurfacePresetsCsv, pr as normalizeEventRegistrationPageSurfaceSubject, ps as mediaSchema, pt as EntryControllerProvider, q as deriveTransactionCapabilities, qa as calendarTabViewsSchema, qc as generateInteractiveChildInheritanceCSS, qd as File, qi as LABEL_FONT_SIZE_MAP, ql as DialogContent, qn as buildNewsletterFormInteractiveIslandProps, qo as buildInteractiveIslandProps, qr as singleButtonFragment, qs as ChevronDownIcon, qt as toRoutableLinkPayload, qu as getBookingLocalDateKey, r as PreviewDesignHistoryOrderProvider, ra as defaultSectionTransitionVariantForFamily, rc as FileAudioIcon, rd as publicEventTicketTypes, rf as CreditCard, ri as bodyCopyFragment, rl as DEFAULT_SURFACE_TEXT_COLOR, rn as reorderEntrySlotBlocks, ro as el, rr as buildEventRegistrationInteractiveIslandProps, rs as planSiteChromePlacement, rt as EMPTY_DOC, ru as Trigger, sa as BACKGROUND_BODY_TEXT_MIN_CONTRAST_RATIO, sc as MailIcon, sd as parseMediaAssetId, sf as CircleMinus, si as MQ_LG_UP, sl as getFieldIntent, sn as AMBIENT_BACKGROUND_ROLES$1, so as eventScheduleScopeValues, sr as resolveDiscountContext, ss as ACCORDION_SPACING_MAP, st as InlineTextEditor, su as CardHeader, t as SiteChromeCustomizeProvider, tc as ExternalLinkIcon, td as publicEventPricingType, tf as EllipsisVertical, ti as ctaRowFragment, tl as rgbColorValue, tn as mutateBlockContent, to as eventCalendarListLayoutCompatibleDisplayModeValues, tr as buildFormInteractiveIslandProps, ts as markEditableSurfaceForwarding, tt as PreviewTextEditor, tu as Content, ua as foregroundTokenForBackgroundAppearanceColorToken, uc as PhoneIcon, ud as unsafeAsAppointmentServiceId, uf as ChevronsUpDown, ui as MQ_SM_UP, ul as isNonEmptyValue, un as PointerSensor, uo as normalizeEventCategoryIdsCsv, ur as WIZARD_STEPS$1, us as ICON_CONFIG, uu as DropdownMenu, v as PreviewThemeOverlayProvider, va as expandPalette, vc as buildResolveImageUrlContext, vd as ok$3, vf as ArrowDown, vi as readHeaderNavFontSizePreference, vl as FieldFrame, vn as CSS, vo as generateShadowValue, vr as buildCourseRegistrationInteractiveIslandProps, vs as shouldReserveFeatureCardIconZone, vt as useEditorUiStoreInstance, vu as __extends, wc as resolveMediaNodeResponsiveImage, wd as Trash2, wi as retargetCompiledRuntimeFieldsForContentAdjacency, wl as Textarea, wn as gradientToCss, wo as getTextColorForBackground, wr as buildProductListInteractiveIslandProps, ws as parseBlockIconValue, wt as redoHistory, wu as useId$1, xa as runTransforms, xc as renderAudio, xd as Upload, xf as __exportAll, xi as applyCompiledRuntimeFieldsToContent, xl as TooltipContent, xn as useIsomorphicLayoutEffect, xo as isCssColorLiteral, xr as buildCartInteractiveIslandProps, xs as buildGeneratedBlockIconRenderAssetLookupFromUnknown, xt as canUndoHistory, xu as __rest, y as usePreviewThemeOverlay, ya as generateCssVars, yc as computeMediaTransformStyle, yd as lucide_react_exports, yf as Archive, yi as formatSiteChromeBackgroundTokenLabel, yl as useField, yn as isKeyboardEvent, yo as normalizeBoxStylesCardVariant, yr as checkoutBlockDefinition, ys as suggestSemanticIconForFeatureCard, yt as useOptionalEditorUiStoreInstance, yu as __generator, za as eventListPaginationActionSchema, zc as siblingPath$1, zd as Minus, zi as NAV_LINK_BORDER_RADIUS_MAP, zl as TabsTrigger, zn as createManifestValidator, zo as resolveEventCta, zr as augmentManifest, zs as SEMANTIC_ICON_DEFINITIONS, zt as validateBlockManifestIssues, zu as unsafeAsEditorBlockId } from "./SiteChromeCustomizeContext-Cx0NMdyv.mjs";
3
- import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-CStABBUh.mjs";
4
- import { _ as API_ENDPOINTS, a as usePreviewToken, c as createBearerAPIClient, d as unwrapResponse, g as resolveSurfaceDocumentAttributes, h as SURFACE_IDS, i as usePreviewAuthFetch, l as ApiEnvelopeError, m as SURFACE_DOCUMENT_DATA_ATTRIBUTE, n as markPreviewAuthExpired, o as isPreviewRuntimeSessionEditable, r as usePreviewAuth, s as ApiRequestError, t as initPreviewAuth, u as extractApiEnvelopeErrorDetails } from "./previewAuthStore-CfquDtTh.mjs";
2
+ import { $ as idleEditorTransactionQueueState, $a as eventButtonVariantSchema, $c as generateInteractiveChildInheritanceCSS, $d as ImageUp, $i as LABEL_FONT_SIZE_MAP, $l as Dialog, $n as eventListingBlockDefinition, $o as defineInteractiveIslandMetaKeys, $r as footerBottomTextFragment, $s as ChevronDownIcon, $t as getPageDesignEditorState, $u as formatBookingTime, Aa as OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS, Ac as resolveMediaNodeResponsiveImage, Ad as Upload, Af as __commonJSMin, Ai as normalEditorCuratedPromotedFieldPaths, Al as Textarea, An as getBlockDefinition, Ao as buildGoogleMapsDirectionsUrl, Ar as buildShopInteractiveIslandProps, As as parseBlockIconValue, At as unsafeAsLinkedContentEntryId, Au as __spreadArray, Ba as isSemanticSpacing, Bc as resolveMediaTransformForAspect, Bd as Settings, Bi as pageDesignEditorBackgroundOverrideOwner, Bl as Popover, Bn as mediaTransforms, Bo as getCardOrientation, Br as deriveCommerceCheckoutState, Bs as inlineTextToPlainText, Bt as usePalette, Bu as cva, Ca as generateCssVars, Cc as MediaPlaceholder, Cd as unsafeAsPassId, Cf as ChevronLeft, Ci as readHeaderNavFontSizePreference, Cl as unmapValueFromSelect, Cn as isKeyboardEvent, Co as normalizeBoxStylesCardVariant, Cr as resolveEventRegistrationScopedEvents, Cs as resolveFeatureCardGeneratedIconSizePx, Ct as useOptionalEditorUiStoreInstance, Cu as DropdownMenuTrigger, Dc as renderAudio, Dd as ok$3, Df as ArrowUp, Di as compileEditorModelRuntime, Dl as TooltipContent, Dn as isSupportedLoaderEndpoint, Do as resolveTokenOrCssColorValue, Dr as buildCheckoutInteractiveIslandProps, Ds as buildGeneratedBlockIconRenderAssetLookupFromUnknown, Dt as pushHistoryEntry, Du as __generator, Ea as ctaButton, Ec as getCurrentResolveImageUrlContext, Ed as err$2, Ef as Box, Ei as applyCompiledRuntimeFieldsToContent, El as Tooltip, En as useUniqueId, Eo as resolveOnColorForThemeToken, Er as buildCartInteractiveIslandProps, Es as toFeatureCardIconSuggestionInputs, Et as createHistoryState, Eu as __extends, Fa as normalizeOfferingsPreviewItemLimit, Fc as attachRenderableMediaAssetFields, Fi as designRuntimeRulesForTheme, Fl as SelectTrigger, Fn as SITE_CHROME_VISIBLE_HEADER_SELECTOR, Fo as formatEventDateParts, Fr as formatCommercePrice, Fs as createRichTextDocFromMarkdown, Ft as createSnapshotFromPageRecord, Fu as useControllableState, Ga as getEventRuntimeFiltersKey, Gc as siblingPath$1, Gd as Pencil, Gi as NAV_LINK_BORDER_RADIUS_MAP, Gl as TabsContent, Gn as isInternalResolvedLinkValue, Go as getEventAvailability, Gr as augmentManifestWithStyleGroups, Gs as SEMANTIC_ICON_DEFINITIONS, Gt as createManifestFormAdapter, Gu as createEditorRemoveBlockCommand, Ha as buildEventRuntimeFilters, Hc as getDirectImageUrlForMediaAsset, Hd as RotateCcw, Hi as getComponentShadowVar, Hl as PopoverTrigger, Hn as uiTransforms, Ho as groupEventsByDate, Hr as productItemKey, Hs as parseInlineTextFromUnknown, Ht as unfinishedBlockCopy, Hu as cn$1, Ia as resolveOfferingsPreviewCoursePath, Ic as isRotationDimensionSwap, Id as Star, Ii as getCuratedSiteStyle, Il as SelectValue, In as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Io as formatEventPrice, Ir as formatInterval, Is as unwrapRichTextRoot, Iu as createContextScope, Ja as normalizeCsvIds, Jc as AFFORDANCE_SUPPRESS_CLASS, Ji as NAV_LINK_PADDING_X_MAP, Jl as Content$1, Jn as shopBlockDefinition, Jo as getLocalMinuteOfDay, Jr as cardFragment, Js as ArrowDownIcon, Jt as evaluateVisibility, Ju as unsafeAsEditorBlockValues, Ka as resolveEventCalendarListPageSize, Ki as NAV_LINK_LETTER_SPACING_MAP, Kl as TabsList, Kn as ImageResolveContextProvider, Ko as getEventAvailabilityStatus, Kr as richTextFragment, Ks as getSemanticIconComponent, Ku as createEditorReorderBlocksCommand, La as resolveOfferingsPreviewGroupCta, Lc as normalizeRightAngle, Ld as Sparkles, Li as surfaceResolutionContextFromTheme, Ll as Label, Ln as planSiteOverlayHeaderClearance, Lo as formatEventPriceDisplay, Lr as EMPTY_COMMERCE_CART_STATE, Ls as isObjectRecord, Lu as composeEventHandlers, Ma as inferLegacyOfferingsPreviewGroupOrder, Mc as setContextResolveImageUrlContext, Mf as __toESM, Mi as resolveVisiblePromotedFieldPathsForEditorBlock, Ml as Select, Mn as projectRecurringSchedule, Mo as toLocationMapHydrationProps, Mr as buildCartDisplay, Ms as parseGeneratedIconAssetId, Mu as useId$1, Na as isOfferingsPreviewSourceKey, Nc as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, Nd as Trash2, Ni as componentRuntimeRulesForTheme, Nl as SelectContent, Nn as siteFooterManifest, No as formatDate$3, Nr as buildProductCardDisplay, Ns as parseGeneratedIconSetId, Nt as useDebouncedLatestSave, Nu as useDirection, Oc as renderVideo, Od as lucide_react_exports, Of as ArrowDown, Oi as retargetCompiledBoundaryRuntimeForContentAdjacency, Ol as TooltipProvider, On as gradientToCss, Oo as getTextColorForBackground, Or as buildProductDetailInteractiveIslandProps, Os as getBlockIconSemanticId, Ot as redoHistory, Ou as __read, Pa as normalizeOfferingsPreviewGroupOrder, Pc as resolveMediaSlotContract, Pd as Ticket, Pl as SelectItem, Pn as siteHeaderManifest, Po as formatEventCompactDateRail, Pr as buildProductDetailDisplay, Ps as parseSiteIconStyleGuideVersionId, Pt as createRoutingHelpers, Pu as createCollection, Q as enqueueTransaction, Qa as columnOptionSchema, Qc as generateBaseInteractiveCSS, Qd as Image, Qi as INPUT_SPACING_MAP, Ql as ScrollableDialogContent, Qn as buildNewsletterFormInteractiveIslandProps, Qo as createInteractiveIslandCodec, Qr as singleButtonFragment, Qs as CheckIcon$1, Qt as applyPageDesignEditorAction, Qu as formatBookingInstant, Ra as resolveOfferingsPreviewGroupOrderEntries, Rc as formatAspectRatioToken, Ri as isThemeV2NormalEditorRawStyleFieldName, Rl as Badge, Rn as visibleHeaderClearancePx, Ro as formatEventTeacherLine, Rr as buildPassCartItem, Rs as isRecord$21, Ru as Primitive, Sa as expandPalette, Sc as ImagePresets, Sd as unsafeAsMediaAssetId, Sf as ChevronRight, Si as mergeHeaderNavTypographyPreference, Sl as mapOptionValueForSelect, Sn as CSS, So as generateShadowValue, Sr as normalizeEventRegistrationPageSurfaceSubject, Ss as parseFeatureCardGeneratedIconSizePx, St as useEditorUiStoreInstance, Su as DropdownMenuSeparator, Ta as runTransforms, Tc as computeMediaTransformStyle, Td as unsafeAsPositiveSeconds, Tf as Check, Ti as PAGE_DESIGN_EDITOR_STATE_FETCH_ERROR_MESSAGE, Tl as useField, Tn as useIsomorphicLayoutEffect, To as isCssColorLiteral, Tr as cartBlockDefinition, Ts as suggestSemanticIconForFeatureCard, Tt as canUndoHistory, Tu as __awaiter, Ua as eventListPaginationActionSchema, Uc as getImageUrl, Ui as parseBlockCustomCssRules, Ul as Input, Un as formattingTransforms, Uo as resolveEventCta, Ur as reduceCommerceCart, Us as isIconPickerPreset, Ut as validateBlockManifestIssues, Uu as clsx, Va as resolveSpacing, Vc as asRecord, Vd as Search, Vi as getComponentBorderWidthPx, Vl as PopoverContent, Vn as layoutTransforms, Vo as getContainerClass, Vr as parseStoredCommerceCartState, Vs as isInlineTextEmpty, Vt as recoveryConflictCopy, Vu as useComposedRefs, Wa as eventPageSizeSchema, Wc as getAtPath, Wd as Plus, Wi as parseCustomCssRules, Wl as Tabs, Wn as createManifestValidator, Wo as resolveEventLinkProps, Wr as augmentManifest, Ws as resolveIconPickerPreset, Wt as ManifestForm, Wu as createEditorInsertBlockCommand, X as confirmAutosaveBatch, Xa as normalizeOptionalId, Xc as generateEffectsCSS, Xi as FONT_WEIGHT_MAP, Xl as Root2$1, Xn as productDetailBlockDefinition, Xo as blockBookingPaymentTermsSchema, Xr as faqHeadingFragment, Xs as ArrowRightIcon, Xt as listContentTypes, Xu as formatBookingDate, Y as beginAutosaveBatch, Ya as normalizeCsvString, Yc as generateButtonCss, Yd as Minus, Yi as NAV_LINK_TEXT_SIZE_MAP, Yl as List, Yn as productListBlockDefinition, Yo as resolveRuntimeEventPricing, Yr as faqAccordionFragment, Ys as ArrowLeftIcon, Yt as createStoreBackend, Yu as addLocalScheduleDays, Z as deriveTransactionCapabilities, Za as calendarTabViewsSchema, Zc as generateShadowValue$1, Zd as LoaderCircle, Zi as INPUT_FONT_SIZE_MAP, Zl as Trigger$1, Zn as newsletterSignupBlockDefinition, Zo as buildInteractiveIslandProps, Zr as blogFeaturedPostFragment, Zs as CalendarIcon$1, Zt as toRoutableLinkPayload, Zu as formatBookingDateTime, _c as PlayIcon, _d as parseSiteId, _f as CircleMinus, _i as BACKGROUND_POSITION_PRESET_VALUES, _l as useBlockContext, _n as useDndContext, _o as normalizeEventSurfacePresetsCsv, _r as getWizardStepsForContext$1, _s as mediaSchema, _t as EntryControllerProvider, aa as boundaryRuntimeMetricsForTransition, ac as ClockIcon$1, ad as toScheduledBookingDateTime, af as FileSpreadsheet, ai as heroCtaRowFragment, al as cssVarValue, an as mutateBlockContent, ao as eventCalendarListLayoutCompatibleDisplayModeValues, ar as formBlockDefinition, as as markEditableSurfaceForwarding, at as PreviewTextEditor, au as DialogTitle, bc as UploadIcon, bd as unsafeAsCustomerPassId, bf as ChevronsUpDown, bi as resolveSurfaceForegroundStyles, bl as hasEmptyOption, bn as useSensor, bo as publicEventSchema, br as courseRegistrationBlockDefinition, bs as createFeatureCardIconKey, bu as DropdownMenuItem, ca as sectionTransitionFamilyForBoundaryOptionId, cc as FileArchiveIcon, cd as publicEventPricingCurrency, cf as FileArchive, ci as bodyCopyFragment, cl as textColorStyle, cn as decodePublicProductCategorySelectorQuery, co as when, cr as buildEventRegistrationInteractiveIslandProps, cs as asDesignBlockId, ct as RichTextEditorSurface, da as backgroundAppearanceColorTokenNames, dc as FileTextIcon, dd as publicEventScalarPrice, df as EllipsisVertical, di as siteOptionSources, dl as surfaceForegroundValue, dn as AMBIENT_BACKGROUND_ROLES$1, do as eventScheduleScopeValues, dr as findPreSelectedEvent, ds as ACCORDION_SPACING_MAP, dt as InlineTextEditor, du as Trigger, ec as ChevronLeftIcon, ed as formatLocalScheduleDate, ef as ImagePlus, ei as formEmbedFragment, el as TokenResolver, en as createBlock, eo as eventCalendarDefaultViewSchema, er as buildEventListingInteractiveIslandProps, es as createZodCodec, et as rejectAutosaveBatch, eu as DialogClose, fa as backgroundAppearanceQuickColorTokenNames, fc as InfoIcon, fd as publicEventTicketTypes, ff as Crop, fi as MQ_LG_UP, fl as useBackendWatch, fn as DndContext, fo as eventSurfaceScopeValues, fr as resolveDiscountContext, fs as ACCORDION_TRIGGER_FONT_SCALE, ft as EditorProvider, fu as createCollapsibleScope, g as PreviewDesignCoordinatorProvider, gc as PhoneIcon, gd as parseMediaAssetId, gf as CirclePlus, gi as MQ_TABLET_ONLY, gl as isNonEmptyValue, gn as getClientRect, go as normalizeEventStaffMemberId, gr as getStepNumber$1, gs as PUBLIC_DOWNLOAD_MEDIA_TYPES, gt as EditableBlockProvider, gu as CardTitle, ha as defaultThemeTokens, hc as MinusIcon, hd as expectParsedBrandedId, hf as Clock3, hi as MQ_SM_UP, hl as isHeaderField, hn as closestCenter, ho as normalizeEventScheduleScope, hr as WIZARD_STEPS$1, hs as ICON_SIZE_PX, ht as useUISelector, hu as CardHeader, i as usePreviewDesignHistoryOrder, ic as CirclePlusIcon, id as toBookingTimeZone, if as FileText, ii as ctaCopyFragment, il as borderColorStyle, io as weekStartSchema, ir as buildEventCalendarListingRender, is as composeHeaderSectionWrapperClassName, it as PreviewInlineTextEditor, iu as DialogHeader, ja as buildOfferingsPreviewRenderStates, jc as resolveMediaStorageUrl, jf as __exportAll, ji as planPageDesignLayoutLookCompatibility, jl as Slider, jn as listBlockDescriptors, jo as normalizeLocationMapProps, jr as getShopDisplayForItems, js as resolveBlockIconRenderValue, jt as recordsEqual, ju as __spreadArrays, kc as resolveImageUrlWithContext, kd as X, kf as Archive, ki as retargetCompiledRuntimeFieldsForContentAdjacency, kl as TooltipTrigger, kn as GRADIENT_PRESETS, ko as featuresFromHex, kr as buildProductListInteractiveIslandProps, ks as getGeneratedBlockIconStyleState, kt as undoHistory, ku as __rest, la as sectionTransitionVariantForBoundaryOptionId, lc as FileAudioIcon, ld as publicEventPricingMode, li as defineFragment, ll as DEFAULT_SURFACE_TEXT_COLOR, ln as DEFAULT_LAUNCH_READINESS_INPUT, lo as bindingSchema, lr as toRegistrationEvents, ls as assertNever$6, lt as getRichTextImagePositionFromTarget, lu as Content, ma as parseBackgroundAppearanceColorToken, mc as MapPinIcon$1, md as assertNever$5, mf as Copy, mi as MQ_SM_DOWN, ml as getModalConfig, mn as PointerSensor, mo as normalizeEventCategoryIdsCsv, mr as resolveRegistrationTarget, ms as ICON_CONFIG, mu as CardContent, n as useSiteChromeCustomizeOptional, nc as ChevronUpIcon, nd as parseBookingLocalDate, nf as GripVertical, ni as testimonialsCarouselFragment, nl as themeButtonClassName, nn as deleteBlock, no as filterAutoShowSchema, nr as buildEventCalendarInteractiveIslandProps, ns as defineProgressiveBlockRuntime, nt as resolvePreviewSidebarTab, nu as DialogDescription, oa as defaultSectionTransitionVariantForFamily, oc as DownloadIcon, od as parseEventPageSurfaceSubject, of as FilePlay, oi as ctaRowFragment, ol as mergeStyles, on as reorderBlocks, oo as eventCalendarListLayoutOptions, or as buildFormInteractiveIslandProps, os as splitPositioningClasses, ot as useRichTextEditor, ou as Collapsible, pa as foregroundTokenForBackgroundAppearanceColorToken, pc as MailIcon, pd as formatCurrencyAmount, pf as CreditCard, pi as MQ_MD_DOWN, pl as getFieldIntent, pn as KeyboardCode, po as normalizeEventBlockKind, pr as resolveEventRequiresPayment, ps as ACCORDION_TRIGGER_LETTER_SPACING, pt as useEditor, pu as Card, qa as resolveEventListPaginationAction, qi as NAV_LINK_PADDING_MAP, ql as TabsTrigger, qn as useImageResolveContextOptional, qo as getLocalDateKey, qr as headingFragment, qs as isSemanticIconId, qt as FormRenderer, qu as unsafeAsEditorBlockId, r as PreviewDesignHistoryOrderProvider, rc as CircleMinusIcon, rd as resolveBookingTimeZoneId, rf as File, ri as testimonialsHeadingFragment, rl as backgroundColorStyle, rn as deleteEntrySlotBlock, ro as previewStageSchema, rr as buildEventCalendarListingDisplay, rt as PreviewRichTextEditor, ru as DialogFooter, sa as sectionTransitionFamilies, sc as ExternalLinkIcon, sd as formatBookingPriceDisplay, sf as FileHeadphone, si as heroCopyFragment, sl as rgbColorValue, sn as reorderEntrySlotBlocks, so as el, sr as eventRegistrationBlockDefinition, ss as planSiteChromePlacement, st as EMPTY_DOC, su as CollapsibleContent, t as SiteChromeCustomizeProvider, tc as ChevronRightIcon, td as getBookingLocalDateKey, tf as ImageOff, ti as formCopyFragment, tl as parseThemeButtonVariantId, tn as createEntrySlotBlock, to as eventLayoutSchema, tr as eventCalendarBlockDefinition, ts as defineClientOwnedBlockRuntime, tu as DialogContent, ua as BACKGROUND_BODY_TEXT_MIN_CONTRAST_RATIO, uc as FileSpreadsheetIcon, ud as publicEventPricingType, uf as EyeOff, ui as PUBLIC_FILE_FIELD_KINDS, ul as surfaceForegroundDeclarations, un as deriveLaunchReadiness, uo as eventBlockKindValues, ur as findEventByOccurrenceId, us as ACCORDION_OPEN_ACCENT_THICKNESS, ut as insertOrReplaceRichTextImage, uu as Root, v as PreviewThemeOverlayProvider, vc as PlusIcon, vd as unsafeAsAppointmentResourceId, vf as CircleCheck, vi as getAnchorClasses, vl as SdkConfigProvider, vn as useDraggable, vo as normalizeEventSurfaceScope, vr as giftingBlockDefinition, vs as FEATURE_CARD_GENERATED_ICON_SIZE_PX, vu as DropdownMenu, wa as createTransformRegistry, wc as buildResolveImageUrlContext, wd as unsafeAsPositiveByteCount$1, wf as ChevronDown, wi as formatSiteChromeBackgroundTokenLabel, wl as FieldFrame, wn as useCombinedRefs, wo as normalizeCardVariantRole, wr as checkoutBlockDefinition, ws as shouldReserveFeatureCardIconZone, wt as canRedoHistory, wu as __assign, xc as XIcon, xd as unsafeAsFormId, xf as ChevronUp, xi as resolveBackgroundColorValue, xl as mapCurrentValueForSelect, xn as useSensors, xo as generateCardCss, xr as buildCourseRegistrationInteractiveIslandProps, xs as getFeatureCardIconCompletion, xt as useEditorUiStore, y as usePreviewThemeOverlay, yc as ShoppingCartIcon, yd as unsafeAsAppointmentServiceId, yf as CircleAlert, yi as boxStylesTransforms, yl as useSdkConfig, yn as useDroppable, yo as normalizeEventVenueId, yr as buildGiftingInteractiveIslandProps, ys as FEATURE_CARD_ICON_TREATMENTS, yt as useEntryEditorController, yu as DropdownMenuContent, za as resolveOfferingsPreviewGroups, zc as parseAspectRatioValue, zi as isThemeV2NormalEditorRawStylePath, zn as contentTransforms, zo as formatTime$3, zr as buildProductCartItem, zs as coerceInlineTextWithFallback, zt as PaletteProvider, zu as Button } from "./SiteChromeCustomizeContext-C_sizso-.mjs";
3
+ import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-D0tnKl0t.mjs";
4
+ import { _ as API_ENDPOINTS, a as usePreviewToken, c as createBearerAPIClient, d as unwrapResponse, g as resolveSurfaceDocumentAttributes, h as SURFACE_IDS, i as usePreviewAuthFetch, l as ApiEnvelopeError, m as SURFACE_DOCUMENT_DATA_ATTRIBUTE, n as markPreviewAuthExpired, o as isPreviewRuntimeSessionEditable, r as usePreviewAuth, s as ApiRequestError, t as initPreviewAuth, u as extractApiEnvelopeErrorDetails } from "./previewAuthStore-BPcJPzdz.mjs";
5
5
  import * as React$1 from "react";
6
6
  import React, { Children, Component, Fragment, cloneElement, createContext, createElement, createRef, forwardRef, isValidElement, memo, startTransition, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -1280,7 +1280,7 @@ var BlockApiError = class extends Error {
1280
1280
  this.name = "BlockApiError";
1281
1281
  }
1282
1282
  };
1283
- function isRecord$19(value) {
1283
+ function isRecord$20(value) {
1284
1284
  return typeof value === "object" && value !== null;
1285
1285
  }
1286
1286
  function isJsonResponseContentType(contentType) {
@@ -1304,8 +1304,8 @@ async function parseJsonBody(response) {
1304
1304
  }
1305
1305
  }
1306
1306
  function getBlockApiErrorDetails(data) {
1307
- if (!isRecord$19(data)) return {};
1308
- const nestedError = isRecord$19(data.error) ? data.error : void 0;
1307
+ if (!isRecord$20(data)) return {};
1308
+ const nestedError = isRecord$20(data.error) ? data.error : void 0;
1309
1309
  return {
1310
1310
  message: typeof nestedError?.message === "string" ? nestedError.message : typeof data.message === "string" ? data.message : void 0,
1311
1311
  code: typeof nestedError?.code === "string" ? nestedError.code : typeof data.code === "string" ? data.code : void 0
@@ -2688,7 +2688,7 @@ function resolveButtonAffordance(input) {
2688
2688
  function coerceRichTextDoc(value) {
2689
2689
  const raw = unwrapRichTextRoot(value);
2690
2690
  if (typeof raw === "string") return createRichTextDocFromMarkdown(raw);
2691
- if (isRecord$20(raw) && typeof raw.type === "string") return raw;
2691
+ if (isRecord$21(raw) && typeof raw.type === "string") return raw;
2692
2692
  return null;
2693
2693
  }
2694
2694
  //#endregion
@@ -2832,7 +2832,7 @@ const IconNode = ({ value, title, className, blockId: _blockId, blockKind: _bloc
2832
2832
  };
2833
2833
  //#endregion
2834
2834
  //#region ../blocks/src/system/icons/generatedAssets.ts
2835
- function isRecord$18(value) {
2835
+ function isRecord$19(value) {
2836
2836
  return typeof value === "object" && value !== null && !Array.isArray(value);
2837
2837
  }
2838
2838
  function generatedIconAssetRefKey(ref) {
@@ -2842,11 +2842,11 @@ function collectGeneratedIconAssetRefs(page) {
2842
2842
  const blocks = [];
2843
2843
  for (const block of page.blocks) {
2844
2844
  if (block.kind !== "block.feature-cards" || typeof block.id !== "string") continue;
2845
- const content = isRecord$18(block.draftContent) ? block.draftContent : isRecord$18(block.content) ? block.content : null;
2845
+ const content = isRecord$19(block.draftContent) ? block.draftContent : isRecord$19(block.content) ? block.content : null;
2846
2846
  const cards = Array.isArray(content?.cards) ? content.cards : [];
2847
2847
  const refs = /* @__PURE__ */ new Map();
2848
2848
  for (const card of cards) {
2849
- if (!isRecord$18(card)) continue;
2849
+ if (!isRecord$19(card)) continue;
2850
2850
  const icon = parseBlockIconValue(card.icon);
2851
2851
  if (icon.kind !== "generated") continue;
2852
2852
  const ref = {
@@ -3613,6 +3613,26 @@ function SpinnerNode({ className, size = "md", color, strokeWidth = 3, srLabel,
3613
3613
  //#endregion
3614
3614
  //#region ../blocks/src/system/runtime/nodes/svg.tsx
3615
3615
  /**
3616
+ * Strict SVG-`transform` validator.
3617
+ *
3618
+ * Accepts only a whitespace/comma-separated list of the geometric transform
3619
+ * functions (`translate`/`rotate`/`scale`/`skewX`/`skewY`/`matrix`) whose
3620
+ * arguments are plain numbers. This deliberately rejects anything else —
3621
+ * `url(...)`, CSS functions, `javascript:`, angle/length units, stray letters —
3622
+ * so a persisted custom-block tree can't smuggle an executable or exfiltrating
3623
+ * value into the attribute.
3624
+ */
3625
+ const TRANSFORM_NUMBER = String.raw`-?(?:\d+\.?\d*|\.\d+)(?:e-?\d+)?`;
3626
+ const TRANSFORM_ARGS = String.raw`${TRANSFORM_NUMBER}(?:[\s,]+${TRANSFORM_NUMBER})*`;
3627
+ const TRANSFORM_FN = String.raw`(?:translate|rotate|scale|skewX|skewY|matrix)\(\s*${TRANSFORM_ARGS}\s*\)`;
3628
+ const SAFE_TRANSFORM_RE = new RegExp(String.raw`^\s*${TRANSFORM_FN}(?:[\s,]*${TRANSFORM_FN})*\s*$`);
3629
+ function safeTransform(value) {
3630
+ if (typeof value !== "string") return void 0;
3631
+ const trimmed = value.trim();
3632
+ if (trimmed.length === 0) return void 0;
3633
+ return SAFE_TRANSFORM_RE.test(trimmed) ? trimmed : void 0;
3634
+ }
3635
+ /**
3616
3636
  * Turn paint props into a CSS style object. Colour values pass through as-is so
3617
3637
  * they may reference theme tokens via `var()`, which only resolves in a CSS
3618
3638
  * property context (not in a bare presentation attribute).
@@ -3631,23 +3651,27 @@ function paintStyle(shape) {
3631
3651
  }
3632
3652
  function renderShape(shape, key) {
3633
3653
  const style = paintStyle(shape);
3654
+ const transform = safeTransform(shape.transform);
3634
3655
  switch (shape.kind) {
3635
3656
  case "path": return /* @__PURE__ */ jsx("path", {
3636
3657
  d: shape.d,
3637
- style
3658
+ style,
3659
+ transform
3638
3660
  }, key);
3639
3661
  case "ellipse": return /* @__PURE__ */ jsx("ellipse", {
3640
3662
  cx: shape.cx,
3641
3663
  cy: shape.cy,
3642
3664
  rx: shape.rx,
3643
3665
  ry: shape.ry,
3644
- style
3666
+ style,
3667
+ transform
3645
3668
  }, key);
3646
3669
  case "circle": return /* @__PURE__ */ jsx("circle", {
3647
3670
  cx: shape.cx,
3648
3671
  cy: shape.cy,
3649
3672
  r: shape.r,
3650
- style
3673
+ style,
3674
+ transform
3651
3675
  }, key);
3652
3676
  case "rect": return /* @__PURE__ */ jsx("rect", {
3653
3677
  x: shape.x,
@@ -3656,14 +3680,16 @@ function renderShape(shape, key) {
3656
3680
  height: shape.height,
3657
3681
  rx: shape.rx,
3658
3682
  ry: shape.ry,
3659
- style
3683
+ style,
3684
+ transform
3660
3685
  }, key);
3661
3686
  case "line": return /* @__PURE__ */ jsx("line", {
3662
3687
  x1: shape.x1,
3663
3688
  y1: shape.y1,
3664
3689
  x2: shape.x2,
3665
3690
  y2: shape.y2,
3666
- style
3691
+ style,
3692
+ transform
3667
3693
  }, key);
3668
3694
  default: return null;
3669
3695
  }
@@ -3859,12 +3885,12 @@ function resolveBookingSiteId(siteId, form) {
3859
3885
  return siteId || form?.siteId || "";
3860
3886
  }
3861
3887
  function normalizeBookingFormConfig(form) {
3862
- if (!isRecord$17(form)) return null;
3888
+ if (!isRecord$18(form)) return null;
3863
3889
  const id = readNonEmptyString(form.id);
3864
3890
  const name = readNonEmptyString(form.name);
3865
3891
  if (!id || !name) return null;
3866
- const schemaSource = isRecord$17(form.schema) ? form.schema : isRecord$17(form.schemaJson) ? form.schemaJson : null;
3867
- const settingsSource = isRecord$17(form.settings) ? form.settings : isRecord$17(form.settingsJson) ? form.settingsJson : null;
3892
+ const schemaSource = isRecord$18(form.schema) ? form.schema : isRecord$18(form.schemaJson) ? form.schemaJson : null;
3893
+ const settingsSource = isRecord$18(form.settings) ? form.settings : isRecord$18(form.settingsJson) ? form.settingsJson : null;
3868
3894
  return {
3869
3895
  id,
3870
3896
  name,
@@ -3884,8 +3910,8 @@ function normalizeBookingServices(services) {
3884
3910
  };
3885
3911
  if (!services) return [];
3886
3912
  if (Array.isArray(services)) return services.filter(isBookingFormService).map(normalizeService);
3887
- if (isRecord$17(services) && "services" in services) return Array.isArray(services.services) ? services.services.filter(isBookingFormService).map(normalizeService) : [];
3888
- return isRecord$17(services) ? Object.values(services).filter(isBookingFormService).map(normalizeService) : [];
3913
+ if (isRecord$18(services) && "services" in services) return Array.isArray(services.services) ? services.services.filter(isBookingFormService).map(normalizeService) : [];
3914
+ return isRecord$18(services) ? Object.values(services).filter(isBookingFormService).map(normalizeService) : [];
3889
3915
  }
3890
3916
  function normalizeBookingSchema(value) {
3891
3917
  if (!value) return void 0;
@@ -3896,7 +3922,7 @@ function normalizeBookingSchema(value) {
3896
3922
  };
3897
3923
  }
3898
3924
  function readBookingFormField(value) {
3899
- if (!isRecord$17(value)) return null;
3925
+ if (!isRecord$18(value)) return null;
3900
3926
  const id = readNonEmptyString(value.id);
3901
3927
  const label = readNonEmptyString(value.label);
3902
3928
  const type = readBookingFieldType(value.type);
@@ -3940,7 +3966,7 @@ function readBookingFieldOptions(value) {
3940
3966
  return options.length > 0 ? options : void 0;
3941
3967
  }
3942
3968
  function readBookingFieldOption(value) {
3943
- if (!isRecord$17(value)) return null;
3969
+ if (!isRecord$18(value)) return null;
3944
3970
  const optionValue = readNonEmptyString(value.value);
3945
3971
  const label = readNonEmptyString(value.label);
3946
3972
  return optionValue && label ? {
@@ -3960,7 +3986,7 @@ function normalizeBookingSettings(value) {
3960
3986
  };
3961
3987
  }
3962
3988
  function isBookingFormService(value) {
3963
- return isRecord$17(value) && typeof value.id === "string" && typeof value.siteId === "string" && typeof value.title === "string";
3989
+ return isRecord$18(value) && typeof value.id === "string" && typeof value.siteId === "string" && typeof value.title === "string";
3964
3990
  }
3965
3991
  function collectBookingCustomFields(data) {
3966
3992
  const customFields = {};
@@ -4010,7 +4036,7 @@ function readStringArray(value) {
4010
4036
  const strings = value.filter((item) => typeof item === "string");
4011
4037
  return strings.length > 0 ? strings : void 0;
4012
4038
  }
4013
- function isRecord$17(value) {
4039
+ function isRecord$18(value) {
4014
4040
  return typeof value === "object" && value !== null;
4015
4041
  }
4016
4042
  function getBookingServicePaymentSelectionMode(service) {
@@ -5407,7 +5433,7 @@ function EventDetailsView({ selection, showVenue, showMap, showOtherDates, showC
5407
5433
  className: "rb-mt-6",
5408
5434
  children: [/* @__PURE__ */ jsx("div", {
5409
5435
  className: "rb-label rb-mb-2",
5410
- children: "Team members"
5436
+ children: "With"
5411
5437
  }), /* @__PURE__ */ jsx("div", {
5412
5438
  className: "rb-flex rb-flex-col rb-gap-3",
5413
5439
  children: teamMembers.map((teamMember) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(TeamMemberName$1, {
@@ -5624,6 +5650,34 @@ function LocationMapSSR(props) {
5624
5650
  });
5625
5651
  }
5626
5652
  //#endregion
5653
+ //#region ../blocks/src/system/runtime/nodes/course-page-surface-scope.ts
5654
+ /**
5655
+ * Resolves native course-page ownership without falling back to entry or slug
5656
+ * coincidence when a page-surface subject is present but invalid.
5657
+ */
5658
+ function resolveCoursePageSurfaceScope(courses, subjectValue) {
5659
+ if (subjectValue === null || subjectValue === void 0) return { kind: "absent" };
5660
+ const parsed = parseEventPageSurfaceSubject(subjectValue);
5661
+ if (!parsed.ok) return {
5662
+ kind: "unsupported",
5663
+ reason: parsed.error.kind
5664
+ };
5665
+ const seriesIds = eventSeriesIdsForSubject(parsed.value);
5666
+ const allowedSeriesIds = new Set(seriesIds);
5667
+ return {
5668
+ kind: "scoped",
5669
+ subject: parsed.value,
5670
+ courses: courses.filter((course) => allowedSeriesIds.has(course.seriesId))
5671
+ };
5672
+ }
5673
+ function eventSeriesIdsForSubject(subject) {
5674
+ switch (subject.kind) {
5675
+ case "eventSeries": return [subject.eventSeriesId];
5676
+ case "eventOffering": return subject.availableEventSeriesIds;
5677
+ default: return assertNever$5(subject);
5678
+ }
5679
+ }
5680
+ //#endregion
5627
5681
  //#region ../blocks/src/system/runtime/nodes/course-details/logic.ts
5628
5682
  function coerceContentEntry(value) {
5629
5683
  if (!value || typeof value !== "object") return null;
@@ -5661,6 +5715,20 @@ function selectCourseDetails(args) {
5661
5715
  scoped: [byCourseId]
5662
5716
  };
5663
5717
  }
5718
+ const pageSurfaceScope = resolveCoursePageSurfaceScope(courses, args.subject);
5719
+ if (pageSurfaceScope.kind === "unsupported") return {
5720
+ mode: "unsupportedPageSurfaceSubject",
5721
+ selected: null,
5722
+ scoped: []
5723
+ };
5724
+ if (pageSurfaceScope.kind === "scoped") {
5725
+ const scoped = [...pageSurfaceScope.courses];
5726
+ return {
5727
+ mode: "pageSurfaceSubject",
5728
+ selected: scoped.length === 1 ? scoped[0] ?? null : null,
5729
+ scoped
5730
+ };
5731
+ }
5664
5732
  if (contentEntry?.id) {
5665
5733
  const scoped = courses.filter((c) => c.contentEntryId === contentEntry.id);
5666
5734
  if (scoped.length === 1) return {
@@ -5775,10 +5843,10 @@ function parseLimit(value, fallback) {
5775
5843
  return Number.isFinite(n) && n > 0 ? n : fallback;
5776
5844
  }
5777
5845
  function CourseDetailsView(props) {
5778
- const { course, showTitle = false, showDescription = false, showSessions = true, sessionsLimit, showVenue = true, showPrice = true, showCapacity = true, showEnrollmentStatus = true, showMembershipNote = true } = props;
5846
+ const { course, showTitle = false, showDescription = false, showSessions = true, sessionsLimit, showVenue = true, showPrice = true, showCapacity = true, showEnrollmentStatus = true, showMembershipNote = true, emptyMessage = "Course details unavailable." } = props;
5779
5847
  if (!course) return /* @__PURE__ */ jsx("p", {
5780
5848
  className: "rb-caption status-muted",
5781
- children: "Course details unavailable."
5849
+ children: emptyMessage
5782
5850
  });
5783
5851
  const pricing = resolveCoursePricingState(course);
5784
5852
  const sessionLimit = parseLimit(sessionsLimit, 10);
@@ -5823,7 +5891,7 @@ function CourseDetailsView(props) {
5823
5891
  })] }),
5824
5892
  teamMembers.length > 0 && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
5825
5893
  className: "rb-label rb-mb-2",
5826
- children: "Team members"
5894
+ children: "With"
5827
5895
  }), /* @__PURE__ */ jsx("div", {
5828
5896
  className: "rb-flex rb-flex-col rb-gap-3",
5829
5897
  children: teamMembers.map((teamMember) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(TeamMemberName, {
@@ -5891,13 +5959,16 @@ function CourseDetailsView(props) {
5891
5959
  }
5892
5960
  //#endregion
5893
5961
  //#region ../blocks/src/system/runtime/nodes/course-details.server.tsx
5894
- function CourseDetailsSSR({ courses, contentEntry, entrySubrouteContext, courseSlug, showTitle, showDescription, showSessions, sessionsLimit, showVenue, showPrice, showCapacity, showEnrollmentStatus, showMembershipNote, className, children }) {
5962
+ function CourseDetailsSSR({ courses, contentEntry, entrySubrouteContext, subject, courseSlug, showTitle, showDescription, showSessions, sessionsLimit, showVenue, showPrice, showCapacity, showEnrollmentStatus, showMembershipNote, className, children }) {
5895
5963
  const selection = selectCourseDetails({
5896
5964
  courses: courses ?? null,
5897
5965
  contentEntry,
5898
5966
  entrySubrouteContext,
5967
+ subject,
5899
5968
  courseSlug
5900
5969
  });
5970
+ const parsedSubject = parseEventPageSurfaceSubject(subject);
5971
+ const awaitingOfferingRuns = parsedSubject.ok && parsedSubject.value.kind === "eventOffering" && parsedSubject.value.availableEventSeriesIds.length === 0;
5901
5972
  const basePath = getEntryBasePath(contentEntry);
5902
5973
  const now = /* @__PURE__ */ new Date();
5903
5974
  const scopedWithRange = selection.scoped.map((c) => ({
@@ -5984,6 +6055,7 @@ function CourseDetailsSSR({ courses, contentEntry, entrySubrouteContext, courseS
5984
6055
  ]
5985
6056
  }) : /* @__PURE__ */ jsx(CourseDetailsView, {
5986
6057
  course: null,
6058
+ emptyMessage: awaitingOfferingRuns ? "New dates are coming soon." : "Course details unavailable.",
5987
6059
  showTitle,
5988
6060
  showDescription,
5989
6061
  showSessions,
@@ -6614,6 +6686,102 @@ const EventCombinedSSR = ({ blockId, ...source }) => {
6614
6686
  });
6615
6687
  };
6616
6688
  //#endregion
6689
+ //#region ../blocks/src/system/blocks/offerings-preview/scheduleSummary.ts
6690
+ function deriveEventScheduleSummary(event) {
6691
+ const occurrence = occurrenceFromEvent(event);
6692
+ return localDayNumber(occurrence.endsAt, occurrence.timeZone) > localDayNumber(occurrence.startsAt, occurrence.timeZone) ? {
6693
+ kind: "multi-day-span",
6694
+ occurrence
6695
+ } : {
6696
+ kind: "single-occurrence",
6697
+ occurrence
6698
+ };
6699
+ }
6700
+ function deriveCourseScheduleSummary(course) {
6701
+ const sessions = [...course.sessions].filter(isValidOccurrence).sort((left, right) => left.startsAt.localeCompare(right.startsAt));
6702
+ const first = sessions[0];
6703
+ if (!first) return null;
6704
+ if (sessions.length === 1) return deriveEventScheduleSummary(first);
6705
+ const last = sessions[sessions.length - 1];
6706
+ if (!last) return null;
6707
+ const recurrence = deriveFixedRecurrence(sessions);
6708
+ return recurrence ? {
6709
+ kind: "fixed-recurring-run",
6710
+ first,
6711
+ last,
6712
+ sessionCount: sessions.length,
6713
+ recurrenceLabel: recurrence
6714
+ } : {
6715
+ kind: "irregular-multi-session-run",
6716
+ first,
6717
+ last,
6718
+ sessionCount: sessions.length
6719
+ };
6720
+ }
6721
+ function nextCourseSessionStart(course) {
6722
+ return [...course.sessions].filter(isValidOccurrence).map((session) => session.startsAt).sort((left, right) => left.localeCompare(right))[0] ?? null;
6723
+ }
6724
+ function occurrenceFromEvent(event) {
6725
+ return {
6726
+ startsAt: event.startsAt,
6727
+ endsAt: event.endsAt,
6728
+ timeZone: event.timeZone
6729
+ };
6730
+ }
6731
+ function deriveFixedRecurrence(sessions) {
6732
+ const [first, second] = sessions;
6733
+ if (!first || !second) return null;
6734
+ if (!sessions.every((session) => sameLocalTime(first, session))) return null;
6735
+ const intervalDays = localDayNumber(second.startsAt, second.timeZone) - localDayNumber(first.startsAt, first.timeZone);
6736
+ if (intervalDays <= 0) return null;
6737
+ for (let index = 2; index < sessions.length; index += 1) {
6738
+ const previous = sessions[index - 1];
6739
+ const current = sessions[index];
6740
+ if (!previous || !current) return null;
6741
+ if (localDayNumber(current.startsAt, current.timeZone) - localDayNumber(previous.startsAt, previous.timeZone) !== intervalDays) return null;
6742
+ }
6743
+ if (intervalDays === 1) return "Every day";
6744
+ const weekday = localDateParts(first.startsAt, first.timeZone).weekday;
6745
+ if (intervalDays === 7) return `Every ${weekday}`;
6746
+ if (intervalDays % 7 === 0) return `Every ${intervalDays / 7} weeks on ${weekday}`;
6747
+ return `Every ${intervalDays} days`;
6748
+ }
6749
+ function sameLocalTime(reference, candidate) {
6750
+ const referenceStart = localDateParts(reference.startsAt, reference.timeZone);
6751
+ const candidateStart = localDateParts(candidate.startsAt, candidate.timeZone);
6752
+ const referenceEnd = localDateParts(reference.endsAt, reference.timeZone);
6753
+ const candidateEnd = localDateParts(candidate.endsAt, candidate.timeZone);
6754
+ return referenceStart.hour === candidateStart.hour && referenceStart.minute === candidateStart.minute && referenceEnd.hour === candidateEnd.hour && referenceEnd.minute === candidateEnd.minute;
6755
+ }
6756
+ function isValidOccurrence(value) {
6757
+ return Number.isFinite(Date.parse(value.startsAt)) && Number.isFinite(Date.parse(value.endsAt));
6758
+ }
6759
+ function localDayNumber(isoTimestamp, timeZone) {
6760
+ const parts = localDateParts(isoTimestamp, timeZone);
6761
+ return Math.floor(Date.UTC(parts.year, parts.month - 1, parts.day) / 864e5);
6762
+ }
6763
+ function localDateParts(isoTimestamp, timeZone) {
6764
+ const parts = new Intl.DateTimeFormat("en-GB", {
6765
+ timeZone,
6766
+ year: "numeric",
6767
+ month: "numeric",
6768
+ day: "numeric",
6769
+ hour: "2-digit",
6770
+ minute: "2-digit",
6771
+ hourCycle: "h23",
6772
+ weekday: "long"
6773
+ }).formatToParts(new Date(isoTimestamp));
6774
+ const value = (type) => parts.find((part) => part.type === type)?.value ?? "";
6775
+ return {
6776
+ year: Number(value("year")),
6777
+ month: Number(value("month")),
6778
+ day: Number(value("day")),
6779
+ hour: Number(value("hour")),
6780
+ minute: Number(value("minute")),
6781
+ weekday: value("weekday")
6782
+ };
6783
+ }
6784
+ //#endregion
6617
6785
  //#region ../blocks/src/system/runtime/nodes/offerings-preview.tsx
6618
6786
  function OfferingsPreviewNode(props) {
6619
6787
  const groups = resolveOfferingsPreviewGroups({
@@ -6635,75 +6803,71 @@ function OfferingsPreviewNode(props) {
6635
6803
  if (states.length === 0) return null;
6636
6804
  const buttonVariant = props.buttonVariant ?? "primary";
6637
6805
  const buttonText = props.buttonText ?? "Book";
6638
- const blockCta = resolveOfferingsPreviewBlockCta(states, props.routeCandidates?.routes ?? []);
6639
- const blockLinkClass = themeButtonClassName({
6640
- variant: "link",
6806
+ const routeCandidates = props.routeCandidates?.routes ?? [];
6807
+ const groupLinkClass = themeButtonClassName({
6808
+ variant: buttonVariant,
6641
6809
  size: "md",
6642
- extraClassName: "offerings-preview-link rb-inline-flex rb-items-center rb-gap-2"
6810
+ extraClassName: "offerings-preview-card-link rb-inline-flex rb-items-center rb-gap-2"
6643
6811
  });
6644
6812
  const groupFrame = resolveGroupFrame(props.cardStyles);
6645
- return /* @__PURE__ */ jsxs("div", {
6813
+ return /* @__PURE__ */ jsx("div", {
6646
6814
  className: "offerings-preview rb-flex rb-flex-col rb-gap-6",
6647
6815
  "data-block": "offerings-preview",
6648
- children: [/* @__PURE__ */ jsx("div", {
6816
+ children: /* @__PURE__ */ jsx("div", {
6649
6817
  className: "offerings-preview-grid rb-grid rb-items-stretch rb-gap-6",
6650
6818
  style: OFFERINGS_PREVIEW_GRID_STYLE,
6651
- children: states.map((state) => /* @__PURE__ */ jsx("section", {
6652
- className: groupFrame.containerClassName,
6653
- style: groupFrame.containerStyle,
6654
- children: /* @__PURE__ */ jsxs("div", {
6655
- className: groupFrame.contentClassName,
6656
- children: [/* @__PURE__ */ jsxs("header", {
6657
- className: "offerings-preview-card-header rb-flex rb-flex-col rb-gap-2 rb-text-center",
6658
- children: [/* @__PURE__ */ jsx("h3", {
6659
- className: "offerings-preview-card-title rb-text-xl rb-font-semibold rb-leading-tight",
6660
- children: state.group.title
6661
- }), state.group.intro ? /* @__PURE__ */ jsx("p", {
6662
- className: "offerings-preview-card-intro rb-text-sm rb-leading-6 status-muted",
6663
- children: state.group.intro
6664
- }) : null]
6665
- }), state.kind === "items" ? renderOfferingGroupItems(state.group.presentation, state.items, {
6666
- buttonVariant,
6667
- buttonText
6668
- }) : /* @__PURE__ */ jsx(EmptyState$1, {
6669
- className: "offerings-preview-card-empty",
6670
- message: state.message
6671
- })]
6672
- })
6673
- }, state.group.sourceKey))
6674
- }), blockCta ? /* @__PURE__ */ jsx("footer", {
6675
- className: "offerings-preview-footer rb-flex rb-justify-center",
6676
- children: /* @__PURE__ */ jsxs("a", {
6677
- className: blockLinkClass,
6678
- href: blockCta.href,
6679
- children: [/* @__PURE__ */ jsx("span", { children: blockCta.label }), /* @__PURE__ */ jsx(ArrowRightIcon, {
6680
- "aria-hidden": "true",
6681
- className: "offerings-preview-link-icon rb-h-4 rb-w-4"
6682
- })]
6819
+ children: states.map((state) => {
6820
+ const groupCta = resolveOfferingsPreviewGroupCta({
6821
+ group: state.group,
6822
+ routes: routeCandidates
6823
+ });
6824
+ return /* @__PURE__ */ jsx("section", {
6825
+ className: groupFrame.containerClassName,
6826
+ style: groupFrame.containerStyle,
6827
+ "data-offering-presentation": state.group.presentation,
6828
+ "data-offering-source": state.group.sourceKey,
6829
+ children: /* @__PURE__ */ jsxs("div", {
6830
+ className: groupFrame.contentClassName,
6831
+ children: [
6832
+ /* @__PURE__ */ jsxs("header", {
6833
+ className: "offerings-preview-card-header rb-flex rb-flex-col rb-gap-2 rb-text-center",
6834
+ children: [/* @__PURE__ */ jsx("h3", {
6835
+ className: "offerings-preview-card-title rb-text-xl rb-font-semibold rb-leading-tight",
6836
+ children: state.group.title
6837
+ }), state.group.intro ? /* @__PURE__ */ jsx("p", {
6838
+ className: "offerings-preview-card-intro rb-text-sm rb-leading-6 status-muted",
6839
+ children: state.group.intro
6840
+ }) : null]
6841
+ }),
6842
+ state.kind === "items" ? renderOfferingGroupItems(state.group.presentation, state.items, {
6843
+ buttonVariant,
6844
+ buttonText
6845
+ }) : /* @__PURE__ */ jsx(EmptyState$1, {
6846
+ className: "offerings-preview-card-empty",
6847
+ message: state.message
6848
+ }),
6849
+ groupCta ? /* @__PURE__ */ jsx("footer", {
6850
+ className: "offerings-preview-card-footer rb-mt-auto rb-flex",
6851
+ children: /* @__PURE__ */ jsxs("a", {
6852
+ className: groupLinkClass,
6853
+ href: groupCta.href,
6854
+ children: [/* @__PURE__ */ jsx("span", { children: groupCta.label }), /* @__PURE__ */ jsx(ArrowRightIcon, {
6855
+ "aria-hidden": "true",
6856
+ className: "offerings-preview-link-icon rb-h-4 rb-w-4"
6857
+ })]
6858
+ })
6859
+ }) : null
6860
+ ]
6861
+ })
6862
+ }, state.group.sourceKey);
6683
6863
  })
6684
- }) : null]
6864
+ })
6685
6865
  });
6686
6866
  }
6687
6867
  const OFFERINGS_PREVIEW_GRID_STYLE = {
6688
6868
  gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 20rem), min(24rem, 100%)))",
6689
6869
  justifyContent: "center"
6690
6870
  };
6691
- function resolveOfferingsPreviewBlockCta(states, routes) {
6692
- const ctas = states.flatMap((state) => {
6693
- const cta = resolveOfferingsPreviewGroupCta({
6694
- group: state.group,
6695
- routes
6696
- });
6697
- return cta ? [cta] : [];
6698
- });
6699
- return ctas.find((cta) => normalizeHrefForComparison(cta.href) === "/offerings") ?? ctas[0] ?? null;
6700
- }
6701
- function normalizeHrefForComparison(href) {
6702
- const trimmed = href.trim();
6703
- if (trimmed.length === 0) return "/";
6704
- const withoutQuery = (trimmed.split("#")[0] ?? "").split("?")[0] ?? "";
6705
- return (withoutQuery.startsWith("/") ? withoutQuery : `/${withoutQuery}`).replace(/\/+$/, "") || "/";
6706
- }
6707
6871
  function buildItemDataMap(props) {
6708
6872
  const routeCandidates = props.routeCandidates?.routes ?? [];
6709
6873
  const entries = OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => [definition.sourceKey, eventDataFromMaybeArray(props[definition.dataKey])]);
@@ -6724,7 +6888,7 @@ function eventDataFromMaybeArray(events) {
6724
6888
  function courseDataFromMaybeArray(courses, routes) {
6725
6889
  return courses ? {
6726
6890
  kind: "ready",
6727
- items: courses.map((course) => ({
6891
+ items: [...courses].sort(compareCoursesByNextSession).map((course) => ({
6728
6892
  kind: "course",
6729
6893
  course,
6730
6894
  path: resolveOfferingsPreviewCoursePath(course, routes)
@@ -6735,21 +6899,113 @@ function courseDataFromMaybeArray(courses, routes) {
6735
6899
  };
6736
6900
  }
6737
6901
  function renderOfferingGroupItems(presentation, items, options) {
6738
- if (presentation === "single-card") {
6739
- const item = items[0];
6740
- return /* @__PURE__ */ jsx("div", {
6902
+ switch (presentation) {
6903
+ case "single-card": {
6904
+ const item = items[0];
6905
+ return /* @__PURE__ */ jsx("div", {
6906
+ className: "offerings-preview-card-items rb-flex rb-flex-1 rb-flex-col",
6907
+ children: item ? renderSingleOfferingCard(item, options) : null
6908
+ });
6909
+ }
6910
+ case "featured-summary": {
6911
+ const item = items[0];
6912
+ return /* @__PURE__ */ jsx("div", {
6913
+ className: "offerings-preview-card-items offerings-preview-summary-items rb-flex rb-flex-1 rb-flex-col",
6914
+ children: item ? /* @__PURE__ */ jsx(FeaturedOfferingSummary, { item }) : null
6915
+ });
6916
+ }
6917
+ case "compact-list": return /* @__PURE__ */ jsx("div", {
6741
6918
  className: "offerings-preview-card-items rb-flex rb-flex-1 rb-flex-col",
6742
- children: item ? renderSingleOfferingCard(item, options) : null
6919
+ children: /* @__PURE__ */ jsx("div", {
6920
+ className: "event-listing-compact-container rb-flex rb-flex-1 rb-flex-col",
6921
+ children: items.map((item) => renderOfferingCompactItem(item, options))
6922
+ })
6743
6923
  });
6924
+ default: return assertNever$5(presentation, "Unhandled offerings preview presentation");
6744
6925
  }
6745
- return /* @__PURE__ */ jsx("div", {
6746
- className: "offerings-preview-card-items rb-flex rb-flex-1 rb-flex-col",
6747
- children: /* @__PURE__ */ jsx("div", {
6748
- className: "event-listing-compact-container rb-flex rb-flex-1 rb-flex-col",
6749
- children: items.map((item) => renderOfferingCompactItem(item, options))
6750
- })
6926
+ }
6927
+ function compareCoursesByNextSession(left, right) {
6928
+ const leftStart = nextCourseSessionStart(left);
6929
+ const rightStart = nextCourseSessionStart(right);
6930
+ if (leftStart === null) return rightStart === null ? 0 : 1;
6931
+ if (rightStart === null) return -1;
6932
+ return leftStart.localeCompare(rightStart);
6933
+ }
6934
+ function FeaturedOfferingSummary({ item }) {
6935
+ const details = featuredSummaryDetails(item);
6936
+ if (!details) return null;
6937
+ return /* @__PURE__ */ jsxs("article", {
6938
+ className: "offerings-preview-summary rb-flex rb-flex-1 rb-flex-col",
6939
+ children: [/* @__PURE__ */ jsxs("p", {
6940
+ className: "offerings-preview-summary-date",
6941
+ children: [/* @__PURE__ */ jsx("time", {
6942
+ dateTime: details.startDateTime,
6943
+ children: details.startDate
6944
+ }), details.endDate ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
6945
+ "aria-hidden": "true",
6946
+ children: " – "
6947
+ }), /* @__PURE__ */ jsx("time", {
6948
+ dateTime: details.endDateTime,
6949
+ children: details.endDate
6950
+ })] }) : null]
6951
+ }), /* @__PURE__ */ jsxs("dl", {
6952
+ className: "offerings-preview-summary-facts",
6953
+ children: [
6954
+ details.recurrence ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Repeats" }), /* @__PURE__ */ jsx("dd", { children: details.recurrence })] }) : null,
6955
+ details.sessionCount ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Sessions" }), /* @__PURE__ */ jsx("dd", { children: details.sessionCount })] }) : null,
6956
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Time" }), /* @__PURE__ */ jsx("dd", { children: details.timeRange })] }),
6957
+ details.venue ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Venue" }), /* @__PURE__ */ jsx("dd", { children: details.venue })] }) : null
6958
+ ]
6959
+ })]
6751
6960
  });
6752
6961
  }
6962
+ function featuredSummaryDetails(item) {
6963
+ switch (item.kind) {
6964
+ case "event": return formatFeaturedSummary(deriveEventScheduleSummary(item.event), item.event.venue?.name ?? null);
6965
+ case "course": {
6966
+ const summary = deriveCourseScheduleSummary(item.course);
6967
+ return summary ? formatFeaturedSummary(summary, item.course.venue?.name ?? null) : null;
6968
+ }
6969
+ default: return assertNever$5(item, "Unhandled offerings preview item");
6970
+ }
6971
+ }
6972
+ function formatFeaturedSummary(summary, venue) {
6973
+ switch (summary.kind) {
6974
+ case "single-occurrence": return detailsFromOccurrences(summary.occurrence, null, venue, null, null);
6975
+ case "multi-day-span": return detailsFromOccurrences(summary.occurrence, summary.occurrence, venue, null, null, true);
6976
+ case "fixed-recurring-run": return detailsFromOccurrences(summary.first, summary.last, venue, summary.recurrenceLabel, null);
6977
+ case "irregular-multi-session-run": return detailsFromOccurrences(summary.first, summary.last, venue, null, `${summary.sessionCount} dates`);
6978
+ default: return assertNever$5(summary, "Unhandled offerings preview schedule summary");
6979
+ }
6980
+ }
6981
+ function detailsFromOccurrences(first, last, venue, recurrence, sessionCount, spanUsesEndDate = false) {
6982
+ const endDateTime = spanUsesEndDate ? first.endsAt : last?.startsAt ?? first.startsAt;
6983
+ return {
6984
+ startDate: formatSummaryDate(first.startsAt, first.timeZone),
6985
+ startDateTime: first.startsAt,
6986
+ endDate: last ? formatSummaryDate(endDateTime, last.timeZone) : null,
6987
+ endDateTime,
6988
+ timeRange: `${formatTime$3(first.startsAt, {
6989
+ timeZone: first.timeZone,
6990
+ locale: "en-GB"
6991
+ })} – ${formatTime$3(first.endsAt, {
6992
+ timeZone: first.timeZone,
6993
+ locale: "en-GB"
6994
+ })}`,
6995
+ recurrence,
6996
+ sessionCount,
6997
+ venue
6998
+ };
6999
+ }
7000
+ function formatSummaryDate(isoTimestamp, timeZone) {
7001
+ return new Intl.DateTimeFormat("en-GB", {
7002
+ timeZone,
7003
+ weekday: "long",
7004
+ day: "numeric",
7005
+ month: "long",
7006
+ year: "numeric"
7007
+ }).format(new Date(isoTimestamp));
7008
+ }
6753
7009
  function renderOfferingCompactItem(item, options) {
6754
7010
  switch (item.kind) {
6755
7011
  case "event": return /* @__PURE__ */ jsx(EventCompactRow, {
@@ -7089,6 +7345,100 @@ function WeeklySlotAvailabilitySSR(props) {
7089
7345
  return /* @__PURE__ */ jsx(WeeklySlotAvailabilityView, { ...props });
7090
7346
  }
7091
7347
  //#endregion
7348
+ //#region ../blocks/src/system/runtime/nodes/events/RecurringSchedule.tsx
7349
+ function destinationHref(destination) {
7350
+ return destination.kind === "external" ? destination.url : destination.path;
7351
+ }
7352
+ function bookingLinkProps(booking) {
7353
+ return booking.destination.kind === "external" ? {
7354
+ href: destinationHref(booking.destination),
7355
+ target: "_blank",
7356
+ rel: "noopener noreferrer"
7357
+ } : { href: destinationHref(booking.destination) };
7358
+ }
7359
+ function bookingActionContent(input) {
7360
+ switch (input.booking.kind) {
7361
+ case "available": return /* @__PURE__ */ jsx(ButtonNode, {
7362
+ ...bookingLinkProps(input.booking),
7363
+ "aria-label": input.accessibleName,
7364
+ className: "recurring-schedule-book",
7365
+ linkRequired: true,
7366
+ variantId: input.buttonVariant,
7367
+ size: "sm",
7368
+ children: input.buttonText
7369
+ });
7370
+ case "unavailable": return null;
7371
+ default: return assertNever$5(input.booking);
7372
+ }
7373
+ }
7374
+ function RecurringSchedule({ schedule, buttonText = "Book", buttonVariant = "primary", showVenue = true, emptyMessage = "Regular schedule details will be added shortly." }) {
7375
+ const projection = schedule ?? {
7376
+ items: [],
7377
+ diagnostics: []
7378
+ };
7379
+ if (projection.items.length === 0) return /* @__PURE__ */ jsx("p", {
7380
+ className: "recurring-schedule-empty",
7381
+ "data-diagnostic-count": projection.diagnostics.length,
7382
+ children: emptyMessage
7383
+ });
7384
+ const renderRow = (item) => {
7385
+ const rowContent = /* @__PURE__ */ jsxs(Fragment$1, { children: [
7386
+ /* @__PURE__ */ jsx("p", {
7387
+ className: "recurring-schedule-day",
7388
+ children: item.cadence.weekday
7389
+ }),
7390
+ /* @__PURE__ */ jsxs("p", {
7391
+ className: "recurring-schedule-time",
7392
+ children: [
7393
+ /* @__PURE__ */ jsx("time", {
7394
+ dateTime: item.cadence.startTime,
7395
+ children: item.cadence.startTime
7396
+ }),
7397
+ /* @__PURE__ */ jsx("span", {
7398
+ "aria-hidden": "true",
7399
+ children: "–"
7400
+ }),
7401
+ /* @__PURE__ */ jsx("time", {
7402
+ dateTime: item.cadence.endTime,
7403
+ children: item.cadence.endTime
7404
+ })
7405
+ ]
7406
+ }),
7407
+ /* @__PURE__ */ jsxs("div", {
7408
+ className: "recurring-schedule-details",
7409
+ children: [/* @__PURE__ */ jsx("p", {
7410
+ className: "recurring-schedule-title",
7411
+ children: item.title
7412
+ }), showVenue && item.venueName ? /* @__PURE__ */ jsx("p", {
7413
+ className: "recurring-schedule-venue",
7414
+ children: item.venueName
7415
+ }) : null]
7416
+ }),
7417
+ /* @__PURE__ */ jsx("div", {
7418
+ className: "recurring-schedule-action",
7419
+ children: bookingActionContent({
7420
+ booking: item.booking,
7421
+ buttonVariant: buttonVariant ?? "primary",
7422
+ buttonText: buttonText ?? "Book",
7423
+ accessibleName: `${buttonText ?? "Book"} ${item.title}, ${item.cadence.weekday} at ${item.cadence.startTime}`
7424
+ })
7425
+ })
7426
+ ] });
7427
+ return /* @__PURE__ */ jsx("article", {
7428
+ className: "recurring-schedule-row",
7429
+ role: "listitem",
7430
+ "aria-label": `${item.title}, ${item.cadence.weekday} at ${item.cadence.startTime}`,
7431
+ children: rowContent
7432
+ });
7433
+ };
7434
+ return /* @__PURE__ */ jsx("div", {
7435
+ className: "recurring-schedule",
7436
+ "data-diagnostic-count": projection.diagnostics.length,
7437
+ role: "list",
7438
+ children: projection.items.map((item) => /* @__PURE__ */ jsx(React.Fragment, { children: renderRow(item) }, item.seriesId))
7439
+ });
7440
+ }
7441
+ //#endregion
7092
7442
  //#region ../blocks/src/system/node/fragments/headingDecoration.ts
7093
7443
  const defaultBindFrom = "_sectionStyles.headingDecoration";
7094
7444
  function headingDecoration({ bindFrom = defaultBindFrom, className } = {}) {
@@ -7649,13 +7999,14 @@ function CheckoutSSR({ blockId, siteId, apiBaseUrl, stage, children, ...rest })
7649
7999
  * Server-safe placeholder for course registration.
7650
8000
  * Provides a static container for island hydration without importing client hooks.
7651
8001
  */
7652
- function CourseRegistrationSSR({ blockId, siteId, apiBaseUrl, portalToken, contentEntry, entrySubrouteContext, courses, className, showSessions, showPrice, showCapacity, showVenue, successMessage, waitlistMessage, membershipMessage, buttonText, buttonVariant, stage, children }) {
8002
+ function CourseRegistrationSSR({ blockId, siteId, apiBaseUrl, portalToken, contentEntry, entrySubrouteContext, subject, courses, className, showSessions, showPrice, showCapacity, showVenue, successMessage, waitlistMessage, membershipMessage, buttonText, buttonVariant, stage, children }) {
7653
8003
  const islandProps = buildCourseRegistrationInteractiveIslandProps({
7654
8004
  siteId,
7655
8005
  apiBaseUrl,
7656
8006
  portalToken,
7657
8007
  contentEntry,
7658
8008
  entrySubrouteContext,
8009
+ subject,
7659
8010
  courses,
7660
8011
  className,
7661
8012
  showSessions,
@@ -8028,26 +8379,33 @@ const WeekBoardCard = ({ event, showCapacity }) => {
8028
8379
  * to a stacked list on mobile. Repurposes the week-grouped agenda data as a
8029
8380
  * board rather than an hour-positioned timetable grid.
8030
8381
  */
8031
- const WeekBoardView = ({ days, events, showCapacity, emptyMessage = "No classes scheduled this week", title = "The week ahead", footerNote = "New to a class? We'll check it's right for you first.", ctaLabel = "Reserve a place", ctaHref = null, buttonVariant = "outline" }) => {
8382
+ const WeekBoardView = ({ days, events, showCapacity, emptyMessage = "No classes scheduled this week", title, footerNote, ctaLabel = "Reserve a place", ctaHref = null, buttonVariant = "outline", elevated = false, banded = false }) => {
8032
8383
  const eventsByDate = groupEventsByDate(events);
8033
8384
  const hasAnyEvents = days.some((date) => (eventsByDate.get(formatDateKey(date)) ?? []).length > 0);
8034
8385
  const ctaClassName = themeButtonClassName({
8035
8386
  variant: buttonVariant,
8036
8387
  size: "sm"
8037
8388
  });
8389
+ const hasTitle = typeof title === "string" && title.length > 0;
8390
+ const hasFooterNote = typeof footerNote === "string" && footerNote.length > 0;
8391
+ const hasCta = typeof ctaHref === "string" && ctaHref.length > 0;
8392
+ const footerNoteText = hasAnyEvents ? hasFooterNote ? footerNote : null : emptyMessage;
8393
+ const showFooter = hasCta || footerNoteText !== null;
8038
8394
  return /* @__PURE__ */ jsx("div", {
8039
8395
  className: "event-calendar event-calendar--week-board",
8040
8396
  "data-block": "event-calendar",
8397
+ ...banded ? { "data-banded": "" } : {},
8041
8398
  children: /* @__PURE__ */ jsxs("div", {
8042
8399
  className: "event-week-board",
8043
8400
  style: { "--event-week-board-cols": String(days.length) },
8401
+ ...elevated ? { "data-elevated": "" } : {},
8044
8402
  children: [
8045
8403
  /* @__PURE__ */ jsxs("div", {
8046
8404
  className: "event-week-board-top",
8047
- children: [/* @__PURE__ */ jsx("span", {
8405
+ children: [hasTitle ? /* @__PURE__ */ jsx("span", {
8048
8406
  className: "event-week-board-title",
8049
8407
  children: title
8050
- }), /* @__PURE__ */ jsx("div", {
8408
+ }) : null, /* @__PURE__ */ jsx("div", {
8051
8409
  className: "event-week-board-legend",
8052
8410
  "aria-hidden": "true",
8053
8411
  children: LEGEND_ITEMS.map((item) => /* @__PURE__ */ jsxs("span", {
@@ -8086,21 +8444,17 @@ const WeekBoardView = ({ days, events, showCapacity, emptyMessage = "No classes
8086
8444
  }, dateKey);
8087
8445
  })
8088
8446
  }),
8089
- /* @__PURE__ */ jsxs("div", {
8447
+ showFooter ? /* @__PURE__ */ jsxs("div", {
8090
8448
  className: "event-week-board-foot",
8091
- children: [/* @__PURE__ */ jsx("p", {
8449
+ children: [footerNoteText !== null ? /* @__PURE__ */ jsx("p", {
8092
8450
  className: "event-week-board-foot-note",
8093
- children: hasAnyEvents ? footerNote : emptyMessage
8094
- }), ctaHref ? /* @__PURE__ */ jsx("a", {
8451
+ children: footerNoteText
8452
+ }) : null, hasCta ? /* @__PURE__ */ jsx("a", {
8095
8453
  className: ctaClassName,
8096
- href: ctaHref,
8454
+ href: ctaHref ?? void 0,
8097
8455
  children: ctaLabel
8098
- }) : /* @__PURE__ */ jsx("button", {
8099
- type: "button",
8100
- className: ctaClassName,
8101
- children: ctaLabel
8102
- })]
8103
- })
8456
+ }) : null]
8457
+ }) : null
8104
8458
  ]
8105
8459
  })
8106
8460
  });
@@ -8546,8 +8900,13 @@ function renderWeekBoardSsr(display) {
8546
8900
  events: [...display.events],
8547
8901
  showCapacity: display.showCapacity,
8548
8902
  emptyMessage: display.emptyMessage,
8549
- ctaLabel: display.buttonText,
8550
- buttonVariant: display.buttonVariant
8903
+ title: display.boardTitle,
8904
+ footerNote: display.footerNote,
8905
+ ctaLabel: display.loadMoreText ?? display.buttonText,
8906
+ ctaHref: display.seeAllUrl,
8907
+ buttonVariant: display.buttonVariant,
8908
+ elevated: display.elevated,
8909
+ banded: display.banded
8551
8910
  });
8552
8911
  }
8553
8912
  function formatHourLabel$1(hour) {
@@ -8935,7 +9294,7 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
8935
9294
  * Renders the newsletter signup form for SSR with hydration support.
8936
9295
  * Uses the islands architecture pattern to hydrate on the client.
8937
9296
  */
8938
- function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationProvider, preset = "emailOnly", includePhone, buttonLabel = "Subscribe", successMessage, privacyNote, tags, spamProtectionEnabled, className }) {
9297
+ function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationProvider, preset = "emailOnly", includePhone, buttonLabel = "Subscribe", buttonVariant = "primary", successMessage, privacyNote, tags, spamProtectionEnabled, className }) {
8939
9298
  const islandProps = buildNewsletterFormInteractiveIslandProps({
8940
9299
  blockId,
8941
9300
  siteId,
@@ -8945,6 +9304,7 @@ function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationPro
8945
9304
  preset,
8946
9305
  includePhone,
8947
9306
  buttonLabel,
9307
+ buttonVariant,
8948
9308
  successMessage,
8949
9309
  privacyNote,
8950
9310
  tags,
@@ -8998,7 +9358,7 @@ function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationPro
8998
9358
  children: /* @__PURE__ */ jsx("button", {
8999
9359
  type: "submit",
9000
9360
  className: themeButtonClassName({
9001
- variant: "primary",
9361
+ variant: display.buttonVariant,
9002
9362
  size: "md"
9003
9363
  }),
9004
9364
  children: display.buttonLabel
@@ -9085,7 +9445,7 @@ function ShopSSR({ blockId, siteId, apiBaseUrl, stage, children, checkoutEndpoin
9085
9445
  action: /* @__PURE__ */ jsx("button", {
9086
9446
  type: "button",
9087
9447
  className: themeButtonClassName({
9088
- variant: "default",
9448
+ variant: render.hydration.buttonVariant,
9089
9449
  size: "md"
9090
9450
  }),
9091
9451
  disabled: true,
@@ -9098,7 +9458,7 @@ function ShopSSR({ blockId, siteId, apiBaseUrl, stage, children, checkoutEndpoin
9098
9458
  action: /* @__PURE__ */ jsx("button", {
9099
9459
  type: "button",
9100
9460
  className: themeButtonClassName({
9101
- variant: "default",
9461
+ variant: render.hydration.buttonVariant,
9102
9462
  size: "md"
9103
9463
  }),
9104
9464
  disabled: true,
@@ -9191,6 +9551,7 @@ const serverComponentRegistry = {
9191
9551
  "event-combined": EventCombinedSSR,
9192
9552
  "offerings-preview": OfferingsPreviewNode,
9193
9553
  "weekly-slot-availability": WeeklySlotAvailabilitySSR,
9554
+ "recurring-schedule": RecurringSchedule,
9194
9555
  ...buildServerRegistryFromEntries(runtimeBackedBlockServerEntries)
9195
9556
  };
9196
9557
  //#endregion
@@ -16516,7 +16877,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
16516
16877
  registrationEvents,
16517
16878
  options.occurrenceContext?.seriesId,
16518
16879
  options.subject?.kind,
16519
- options.subject?.kind === "eventSeries" ? options.subject.eventSeriesId : options.subject?.reason,
16880
+ options.subject?.kind === "eventSeries" ? options.subject.eventSeriesId : options.subject?.kind === "eventOffering" ? `${options.subject.eventOfferingId}:${options.subject.availableEventSeriesIds.join(",")}` : options.subject?.reason,
16520
16881
  options.contentEntry?.slug,
16521
16882
  options.contentEntry?.contentTypeSlug
16522
16883
  ]);
@@ -18293,13 +18654,16 @@ function resolveHasCoursePayment(pricing) {
18293
18654
  }
18294
18655
  function useCourseRegistrationWizard(props) {
18295
18656
  const api = useBlockApi();
18296
- const { contentEntry, courses, entrySubrouteContext } = props;
18657
+ const { contentEntry, courses, entrySubrouteContext, subject } = props;
18297
18658
  const scopedCourses = useMemo(() => {
18298
18659
  const allCourses = courses ?? [];
18299
18660
  if (entrySubrouteContext?.kind === "course-run") {
18300
18661
  const matched = allCourses.find((c) => c.id === entrySubrouteContext.run.courseId) ?? null;
18301
18662
  if (matched) return [matched];
18302
18663
  }
18664
+ const pageSurfaceScope = resolveCoursePageSurfaceScope(allCourses, subject);
18665
+ if (pageSurfaceScope.kind === "unsupported") return [];
18666
+ if (pageSurfaceScope.kind === "scoped") return [...pageSurfaceScope.courses];
18303
18667
  if (contentEntry?.id) {
18304
18668
  const matchedCourses = allCourses.filter((c) => c.contentEntryId === contentEntry.id);
18305
18669
  if (matchedCourses.length > 0) return matchedCourses;
@@ -18313,7 +18677,8 @@ function useCourseRegistrationWizard(props) {
18313
18677
  courses,
18314
18678
  contentEntry?.id,
18315
18679
  contentEntry?.slug,
18316
- entrySubrouteContext
18680
+ entrySubrouteContext,
18681
+ subject
18317
18682
  ]);
18318
18683
  const [step, setStep] = useState(() => {
18319
18684
  const enrollment = new URLSearchParams(window.location.search).get("enrollment");
@@ -19232,24 +19597,27 @@ function getCourseSlidingScaleMessage(pricing) {
19232
19597
  return null;
19233
19598
  }
19234
19599
  function CourseRegistrationWizard(props) {
19235
- const { showSessions = true, showPrice = true, showCapacity = true, showVenue = true, successMessage = "You're booked in! Check your email for confirmation and session details.", waitlistMessage = "You've been added to the waitlist. We'll email you a claim link if a spot opens up.", membershipMessage = "Booked using your membership! Check your email for session details.", buttonText = "Book course", buttonVariant = "primary", className } = props;
19600
+ const { showSessions = true, showPrice = true, showCapacity = true, showVenue = true, successMessage = "You're booked in! Check your email for confirmation and session details.", waitlistMessage = "You've been added to the waitlist. We'll email you a claim link if a spot opens up.", membershipMessage = "Booked using your membership! Check your email for session details.", buttonText = "Sign up", buttonVariant = "primary", className } = props;
19236
19601
  const { api, scopedCourses, step, setStep, selectedCourse, selectedPricingOptionId, setSelectedPricingOptionId, selectedSlidingAmountInput, setSelectedSlidingAmountInput, selectedCoursePricing, formData, setFormData, errors, enrollmentResult, errorMessage, portalAuthState, handleLogout, altchaSolution: _altchaSolution, setAltchaSolution, showSpamProtection, eligibilityLoading, eligibilityError, courseEligibility, eligibleMemberships, paymentChoice, setPaymentChoice, selectedMembershipId, setSelectedMembershipId, discountUiOpen, setDiscountUiOpen, discountCode, setDiscountCode, discountsAvailable, manualCodeEntryAllowed, discountsAvailableLoading, waitlistClaim, canUseMembership: _canUseMembership, bookingMode, currentStepNumber, totalSteps, stepLabels, showPortalAuthSidebar, hasPreSelectedCourse: _hasPreSelectedCourse, hasCoursePayment: _hasCoursePayment, handleCourseSelect, handleSubmit, handlePaymentContinue, handleRetry, handleBookingModeChange } = useCourseRegistrationWizard(props);
19237
19602
  const buttonClass = themeButtonClassName({
19238
19603
  variant: buttonVariant,
19239
19604
  size: "md"
19240
19605
  });
19241
- if (scopedCourses.length === 0) return /* @__PURE__ */ jsx("div", {
19242
- id: COURSE_REGISTRATION_ANCHOR_ID,
19243
- className: `course-registration ${className || ""}`,
19244
- "data-block": "course-registration",
19245
- children: /* @__PURE__ */ jsx("div", {
19246
- className: "cr-empty",
19247
- children: /* @__PURE__ */ jsx("p", {
19248
- className: "cr-empty__text",
19249
- children: "No courses available to book."
19606
+ if (scopedCourses.length === 0) {
19607
+ const awaitingOfferingRuns = props.subject?.kind === "eventOffering" && props.subject.availableEventSeriesIds.length === 0;
19608
+ return /* @__PURE__ */ jsx("div", {
19609
+ id: COURSE_REGISTRATION_ANCHOR_ID,
19610
+ className: `course-registration ${className || ""}`,
19611
+ "data-block": "course-registration",
19612
+ children: /* @__PURE__ */ jsx("div", {
19613
+ className: "cr-empty",
19614
+ children: /* @__PURE__ */ jsx("p", {
19615
+ className: "cr-empty__text",
19616
+ children: awaitingOfferingRuns ? "New dates are coming soon. Booking will open when the next run is ready." : "No courses available to book."
19617
+ })
19250
19618
  })
19251
- })
19252
- });
19619
+ });
19620
+ }
19253
19621
  const allowedStatuses = api.config.isPreview ? ["active", "draft"] : ["active"];
19254
19622
  if (!scopedCourses.some((c) => !c.status || allowedStatuses.includes(c.status))) return /* @__PURE__ */ jsx("div", {
19255
19623
  id: COURSE_REGISTRATION_ANCHOR_ID,
@@ -19636,7 +20004,7 @@ const LEAFLET_JS_INTEGRITY = "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo
19636
20004
  let leafletLoaded = false;
19637
20005
  let leafletLoadPromise = null;
19638
20006
  function isLeafletApi(value) {
19639
- if (!isRecord$20(value)) return false;
20007
+ if (!isRecord$21(value)) return false;
19640
20008
  return typeof value.map === "function" && typeof value.tileLayer === "function" && typeof value.marker === "function";
19641
20009
  }
19642
20010
  function loadLeaflet() {
@@ -20581,7 +20949,7 @@ function PassesMembershipsController({ render }) {
20581
20949
  action: /* @__PURE__ */ jsx("button", {
20582
20950
  type: "button",
20583
20951
  className: themeButtonClassName({
20584
- variant: "default",
20952
+ variant: hydration.buttonVariant,
20585
20953
  size: "md",
20586
20954
  extraClassName: "shop__cta"
20587
20955
  }),
@@ -20602,7 +20970,7 @@ function PassesMembershipsController({ render }) {
20602
20970
  action: /* @__PURE__ */ jsx("button", {
20603
20971
  type: "button",
20604
20972
  className: themeButtonClassName({
20605
- variant: "default",
20973
+ variant: hydration.buttonVariant,
20606
20974
  size: "md",
20607
20975
  extraClassName: "shop__cta"
20608
20976
  }),
@@ -20958,7 +21326,7 @@ Autoplay.globalOptions = void 0;
20958
21326
  function isObject$2(subject) {
20959
21327
  return Object.prototype.toString.call(subject) === "[object Object]";
20960
21328
  }
20961
- function isRecord$16(subject) {
21329
+ function isRecord$17(subject) {
20962
21330
  return isObject$2(subject) || Array.isArray(subject);
20963
21331
  }
20964
21332
  function canUseDOM() {
@@ -20973,7 +21341,7 @@ function areOptionsEqual(optionsA, optionsB) {
20973
21341
  const valueA = optionsA[key];
20974
21342
  const valueB = optionsB[key];
20975
21343
  if (typeof valueA === "function") return `${valueA}` === `${valueB}`;
20976
- if (!isRecord$16(valueA) || !isRecord$16(valueB)) return valueA === valueB;
21344
+ if (!isRecord$17(valueA) || !isRecord$17(valueB)) return valueA === valueB;
20977
21345
  return areOptionsEqual(valueA, valueB);
20978
21346
  });
20979
21347
  }
@@ -26581,8 +26949,13 @@ const EventCalendarWeekBoardClient = ({ display }) => {
26581
26949
  events: [...display.events],
26582
26950
  showCapacity: display.showCapacity,
26583
26951
  emptyMessage: display.emptyMessage,
26584
- ctaLabel: display.buttonText,
26585
- buttonVariant: display.buttonVariant
26952
+ title: display.boardTitle,
26953
+ footerNote: display.footerNote,
26954
+ ctaLabel: display.loadMoreText ?? display.buttonText,
26955
+ ctaHref: display.seeAllUrl,
26956
+ buttonVariant: display.buttonVariant,
26957
+ elevated: display.elevated,
26958
+ banded: display.banded
26586
26959
  });
26587
26960
  };
26588
26961
  const EventCalendarTimetableClient = ({ render }) => {
@@ -27418,7 +27791,7 @@ function NewsletterFormClient({ render }) {
27418
27791
  children: /* @__PURE__ */ jsx("button", {
27419
27792
  type: "submit",
27420
27793
  className: themeButtonClassName({
27421
- variant: "primary",
27794
+ variant: render.display.buttonVariant,
27422
27795
  size: "md"
27423
27796
  }),
27424
27797
  disabled: isNewsletterFormSubmitting(submissionState),
@@ -27527,7 +27900,7 @@ function WeeklySlotAvailabilityClient({ serviceId, resourceId, horizonWeeks, tim
27527
27900
  }
27528
27901
  //#endregion
27529
27902
  //#region ../blocks/src/system/runtime/components/registry.client.tsx
27530
- function isRecord$15(value) {
27903
+ function isRecord$16(value) {
27531
27904
  return typeof value === "object" && value !== null;
27532
27905
  }
27533
27906
  function buildRenderFromLooseProps(runtime, mode, props) {
@@ -27546,12 +27919,12 @@ function withRuntimeBackedEnvelope(source, runtime, render) {
27546
27919
  function normalizeLegacyInteractiveRenderProps(runtime, mode, props) {
27547
27920
  const source = props;
27548
27921
  const render = props["render"];
27549
- if (!isRecord$15(render)) return withRuntimeBackedEnvelope(source, runtime, buildRenderFromLooseProps(runtime, mode, props));
27550
- if (isRecord$15(render["hydration"])) return withRuntimeBackedEnvelope(source, runtime, {
27922
+ if (!isRecord$16(render)) return withRuntimeBackedEnvelope(source, runtime, buildRenderFromLooseProps(runtime, mode, props));
27923
+ if (isRecord$16(render["hydration"])) return withRuntimeBackedEnvelope(source, runtime, {
27551
27924
  ...render,
27552
27925
  mode
27553
27926
  });
27554
- if (!isRecord$15(render["display"])) return withRuntimeBackedEnvelope(source, runtime, buildRenderFromLooseProps(runtime, mode, props));
27927
+ if (!isRecord$16(render["display"])) return withRuntimeBackedEnvelope(source, runtime, buildRenderFromLooseProps(runtime, mode, props));
27555
27928
  const { display, mode: _legacyMode, ...legacyHydration } = render;
27556
27929
  return withRuntimeBackedEnvelope(source, runtime, {
27557
27930
  display,
@@ -28097,7 +28470,7 @@ const defaultTransforms = createTransformRegistry([
28097
28470
  //#region ../blocks/src/system/data/linkedContentEntries.ts
28098
28471
  const LINKED_CONTENT_ENTRY_META_KEY = "__rbLinkedContentEntry";
28099
28472
  function coerceLinkedContentEntriesPayload(payload) {
28100
- if (!isRecord$14(payload)) return payload;
28473
+ if (!isRecord$15(payload)) return payload;
28101
28474
  const response = payload;
28102
28475
  if (!Array.isArray(response.entries)) return payload;
28103
28476
  const contentType = parsePublicContentTypeMeta(response.contentType);
@@ -28105,16 +28478,16 @@ function coerceLinkedContentEntriesPayload(payload) {
28105
28478
  return response.entries.map((entry) => enrichLinkedContentEntry(entry, contentType));
28106
28479
  }
28107
28480
  function getLinkedContentEntryMeta(value) {
28108
- if (!isRecord$14(value)) return null;
28481
+ if (!isRecord$15(value)) return null;
28109
28482
  const candidate = value[LINKED_CONTENT_ENTRY_META_KEY];
28110
28483
  return isLinkedContentEntryMeta(candidate) ? candidate : null;
28111
28484
  }
28112
28485
  function buildLinkedContentEditTarget(input) {
28113
28486
  const { entry, sourceBlockId, sourceBlockKind, itemIndex } = input;
28114
- if (!isRecord$14(entry)) return null;
28487
+ if (!isRecord$15(entry)) return null;
28115
28488
  const meta = getLinkedContentEntryMeta(entry);
28116
28489
  if (!meta || meta.support.kind !== "supported") return null;
28117
- const content = isRecord$14(entry.content) ? entry.content : {};
28490
+ const content = isRecord$15(entry.content) ? entry.content : {};
28118
28491
  return {
28119
28492
  kind: "linked-content-entry",
28120
28493
  entryId: meta.entryId,
@@ -28178,12 +28551,12 @@ function resolveLinkedEntryInlineFieldEligibility(input) {
28178
28551
  };
28179
28552
  }
28180
28553
  function enrichLinkedContentEntry(entry, contentType) {
28181
- if (!isRecord$14(entry)) return entry;
28554
+ if (!isRecord$15(entry)) return entry;
28182
28555
  const entryId = typeof entry.id === "string" ? entry.id : null;
28183
28556
  if (!entryId) return entry;
28184
28557
  const title = typeof entry.title === "string" && entry.title.trim().length > 0 ? entry.title : entryId;
28185
28558
  const optimisticHash = typeof entry.optimisticHash === "string" && entry.optimisticHash.length > 0 ? entry.optimisticHash : null;
28186
- const content = isRecord$14(entry.content) ? entry.content : {};
28559
+ const content = isRecord$15(entry.content) ? entry.content : {};
28187
28560
  const meta = {
28188
28561
  kind: "linked-content-entry",
28189
28562
  entryId,
@@ -28279,7 +28652,7 @@ function capitalize(value) {
28279
28652
  return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
28280
28653
  }
28281
28654
  function parsePublicContentTypeMeta(value) {
28282
- if (!isRecord$14(value)) return null;
28655
+ if (!isRecord$15(value)) return null;
28283
28656
  if (typeof value.key !== "string" || value.key.trim().length === 0) return null;
28284
28657
  return {
28285
28658
  key: value.key,
@@ -28289,7 +28662,7 @@ function parsePublicContentTypeMeta(value) {
28289
28662
  };
28290
28663
  }
28291
28664
  function parsePublicContentTypeLinkedEntryEditing(value) {
28292
- if (!isRecord$14(value) || typeof value.kind !== "string") return null;
28665
+ if (!isRecord$15(value) || typeof value.kind !== "string") return null;
28293
28666
  switch (value.kind) {
28294
28667
  case "generic": return { kind: "generic" };
28295
28668
  case "unsupported-domain-backed": return {
@@ -28300,7 +28673,7 @@ function parsePublicContentTypeLinkedEntryEditing(value) {
28300
28673
  }
28301
28674
  }
28302
28675
  function parsePublicContentTypeFieldMeta(value) {
28303
- if (!isRecord$14(value)) return [];
28676
+ if (!isRecord$15(value)) return [];
28304
28677
  if (typeof value.id !== "string" || typeof value.type !== "string") return [];
28305
28678
  return [{
28306
28679
  id: value.id,
@@ -28315,14 +28688,14 @@ function parseStringArray(value) {
28315
28688
  return value.filter((item) => typeof item === "string");
28316
28689
  }
28317
28690
  function isLinkedContentEntryMeta(value) {
28318
- if (!isRecord$14(value)) return false;
28691
+ if (!isRecord$15(value)) return false;
28319
28692
  if (value.kind !== "linked-content-entry") return false;
28320
28693
  if (typeof value.entryId !== "string") return false;
28321
28694
  if (typeof value.contentTypeKey !== "string") return false;
28322
28695
  if (typeof value.contentTypeLabel !== "string") return false;
28323
28696
  if (typeof value.title !== "string") return false;
28324
28697
  if (!(value.optimisticHash === null || typeof value.optimisticHash === "string")) return false;
28325
- if (!isRecord$14(value.contentType)) return false;
28698
+ if (!isRecord$15(value.contentType)) return false;
28326
28699
  if (!isLinkedEntryFieldSourceArray(value.fieldSources)) return false;
28327
28700
  return isLinkedContentEditSupport(value.support);
28328
28701
  }
@@ -28330,7 +28703,7 @@ function isLinkedEntryFieldSourceArray(value) {
28330
28703
  return Array.isArray(value) && value.every(isLinkedEntryFieldSource);
28331
28704
  }
28332
28705
  function isLinkedEntryFieldSource(value) {
28333
- if (!isRecord$14(value)) return false;
28706
+ if (!isRecord$15(value)) return false;
28334
28707
  if (typeof value.displayPath !== "string") return false;
28335
28708
  switch (value.kind) {
28336
28709
  case "content-field": return typeof value.fieldPath === "string" && (value.fieldType === "text" || value.fieldType === "richText");
@@ -28351,7 +28724,7 @@ function isLinkedEntryInlineFieldReadOnlyReason(value) {
28351
28724
  }
28352
28725
  }
28353
28726
  function isLinkedContentEditSupport(value) {
28354
- if (!isRecord$14(value) || typeof value.kind !== "string") return false;
28727
+ if (!isRecord$15(value) || typeof value.kind !== "string") return false;
28355
28728
  switch (value.kind) {
28356
28729
  case "supported": return true;
28357
28730
  case "unsupported-domain-backed":
@@ -28360,7 +28733,7 @@ function isLinkedContentEditSupport(value) {
28360
28733
  default: return false;
28361
28734
  }
28362
28735
  }
28363
- function isRecord$14(value) {
28736
+ function isRecord$15(value) {
28364
28737
  return typeof value === "object" && value !== null && !Array.isArray(value);
28365
28738
  }
28366
28739
  //#endregion
@@ -28414,14 +28787,14 @@ function isDecoratedHeadingBlockKind(blockKind) {
28414
28787
  return blockKind === "block.intro" || blockKind === "block.feature-cards" || blockKind === "block.testimonials" || blockKind === "block.faq";
28415
28788
  }
28416
28789
  function readVariant(blockContent) {
28417
- if (!isRecord$13(blockContent)) return void 0;
28790
+ if (!isRecord$14(blockContent)) return void 0;
28418
28791
  const variant = blockContent.variant;
28419
28792
  return typeof variant === "string" ? variant : void 0;
28420
28793
  }
28421
28794
  function isFaqDecoratedVariant(variant) {
28422
28795
  return variant === "default" || variant === "question-columns";
28423
28796
  }
28424
- function isRecord$13(value) {
28797
+ function isRecord$14(value) {
28425
28798
  return typeof value === "object" && value !== null && !Array.isArray(value);
28426
28799
  }
28427
28800
  function buildHeadingDecorationWrapperClassName(className) {
@@ -29489,6 +29862,25 @@ function applyStyleOverride(target, key, defaults) {
29489
29862
  target[key] = mergeDeep(defaults, target[key]);
29490
29863
  }
29491
29864
  //#endregion
29865
+ //#region ../blocks/src/system/runtime/blockComposition.ts
29866
+ function readBlockComposition(value) {
29867
+ if (!isRecord$13(value) || typeof value.kind !== "string") return null;
29868
+ switch (value.kind) {
29869
+ case "intro": return value.treatment === "editorial-statement" || value.treatment === "portrait-bio" ? {
29870
+ kind: "intro",
29871
+ treatment: value.treatment
29872
+ } : null;
29873
+ case "feature-cards": return value.treatment === "asymmetric-emphasis" || value.treatment === "framed-programme" ? {
29874
+ kind: "feature-cards",
29875
+ treatment: value.treatment
29876
+ } : null;
29877
+ default: return null;
29878
+ }
29879
+ }
29880
+ function isRecord$13(value) {
29881
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29882
+ }
29883
+ //#endregion
29492
29884
  //#region ../blocks/src/system/componentFactory.ts
29493
29885
  /**
29494
29886
  * Resolves the layout definition for a block based on its manifest and content.
@@ -29672,6 +30064,7 @@ function renderBlock(manifest, content, options = {}) {
29672
30064
  if (manifest.behaviours?.managesOwnWrapper) return componentElement;
29673
30065
  const styleGroup = typeof content.styleGroup === "string" ? content.styleGroup : void 0;
29674
30066
  const blockLook = typeof content.blockLook === "string" ? content.blockLook : void 0;
30067
+ const blockComposition = readBlockComposition(content.blockComposition);
29675
30068
  return React.createElement("div", {
29676
30069
  className: `block-${cleanKind}`,
29677
30070
  "data-block": cleanKind,
@@ -29681,6 +30074,10 @@ function renderBlock(manifest, content, options = {}) {
29681
30074
  "data-variant": variantKey
29682
30075
  } : {},
29683
30076
  ...blockLook ? { "data-block-look": blockLook } : {},
30077
+ ...blockComposition ? {
30078
+ "data-block-composition": blockComposition.treatment,
30079
+ "data-block-composition-kind": blockComposition.kind
30080
+ } : {},
29684
30081
  ...styleGroup ? { "data-style-group": styleGroup } : {}
29685
30082
  }, componentElement);
29686
30083
  }
@@ -31232,7 +31629,7 @@ ${selector} [data-style-group*='-from-muted-band-'] {
31232
31629
  }
31233
31630
 
31234
31631
  ${selector} [data-style-group*='-from-accent-band-'] {
31235
- --site-style-transition-from: rgb(var(--tb-primary));
31632
+ --site-style-transition-from: rgb(var(--tb-accent));
31236
31633
  }
31237
31634
 
31238
31635
  ${selector} [data-style-group*='-from-brand-depth-band-'] {
@@ -31249,7 +31646,7 @@ ${selector} [data-style-group$='-to-muted-band'] {
31249
31646
  }
31250
31647
 
31251
31648
  ${selector} [data-style-group$='-to-accent-band'] {
31252
- --site-style-transition-to: rgb(var(--tb-primary));
31649
+ --site-style-transition-to: rgb(var(--tb-accent));
31253
31650
  }
31254
31651
 
31255
31652
  ${selector} [data-style-group$='-to-brand-depth-band'] {
@@ -32884,6 +33281,10 @@ function buildThemeCssVars(theme) {
32884
33281
  ["--font-heading"]: formatFontFamily(typography.headings.default.family),
32885
33282
  ["--font-body"]: formatFontFamily(typography.body.family),
32886
33283
  ["--font-eyebrow"]: typography.eyebrow?.family ? formatFontFamily(typography.eyebrow.family) : "var(--font-body)",
33284
+ ...typography.eyebrow?.size ? { ["--fs-eyebrow"]: mapEyebrowSize(typography.eyebrow.size) } : {},
33285
+ ...typography.eyebrow?.weight ? { ["--fw-eyebrow"]: mapWeight(typography.eyebrow.weight) } : {},
33286
+ ...typography.eyebrow?.letterSpacing ? { ["--ls-eyebrow"]: mapEyebrowLetterSpacing(typography.eyebrow.letterSpacing) } : {},
33287
+ ...typography.eyebrow?.case ? { ["--tt-eyebrow"]: mapEyebrowCase(typography.eyebrow.case) } : {},
32887
33288
  ["--font-weight-heading"]: mapWeight(typography.headings.default.weight),
32888
33289
  ["--font-weight-body"]: mapWeight(typography.body.weight),
32889
33290
  ...typography.headings.h1.weight ? { ["--fw-h1"]: mapWeight(typography.headings.h1.weight) } : {},
@@ -32900,14 +33301,14 @@ function buildThemeCssVars(theme) {
32900
33301
  ...typography.headings.h4?.letterSpacing ? { ["--ls-h4"]: mapLetterSpacing(typography.headings.h4.letterSpacing) } : {},
32901
33302
  ...typography.headings.h5?.letterSpacing ? { ["--ls-h5"]: mapLetterSpacing(typography.headings.h5.letterSpacing) } : {},
32902
33303
  ...typography.headings.h6?.letterSpacing ? { ["--ls-h6"]: mapLetterSpacing(typography.headings.h6.letterSpacing) } : {},
32903
- ["--lh-heading"]: mapLineHeight(typography.headings.default.lineHeight),
33304
+ ["--lh-heading"]: mapHeadingLineHeight(typography.headings.default.lineHeight),
32904
33305
  ["--lh-body"]: mapLineHeight(typography.body.lineHeight),
32905
- ...typography.headings.h1.lineHeight ? { ["--lh-h1"]: mapLineHeight(typography.headings.h1.lineHeight) } : {},
32906
- ...typography.headings.h2.lineHeight ? { ["--lh-h2"]: mapLineHeight(typography.headings.h2.lineHeight) } : {},
32907
- ...typography.headings.h3.lineHeight ? { ["--lh-h3"]: mapLineHeight(typography.headings.h3.lineHeight) } : {},
32908
- ...typography.headings.h4?.lineHeight ? { ["--lh-h4"]: mapLineHeight(typography.headings.h4.lineHeight) } : {},
32909
- ...typography.headings.h5?.lineHeight ? { ["--lh-h5"]: mapLineHeight(typography.headings.h5.lineHeight) } : {},
32910
- ...typography.headings.h6?.lineHeight ? { ["--lh-h6"]: mapLineHeight(typography.headings.h6.lineHeight) } : {},
33306
+ ...typography.headings.h1.lineHeight ? { ["--lh-h1"]: mapHeadingLineHeight(typography.headings.h1.lineHeight) } : {},
33307
+ ...typography.headings.h2.lineHeight ? { ["--lh-h2"]: mapHeadingLineHeight(typography.headings.h2.lineHeight) } : {},
33308
+ ...typography.headings.h3.lineHeight ? { ["--lh-h3"]: mapHeadingLineHeight(typography.headings.h3.lineHeight) } : {},
33309
+ ...typography.headings.h4?.lineHeight ? { ["--lh-h4"]: mapHeadingLineHeight(typography.headings.h4.lineHeight) } : {},
33310
+ ...typography.headings.h5?.lineHeight ? { ["--lh-h5"]: mapHeadingLineHeight(typography.headings.h5.lineHeight) } : {},
33311
+ ...typography.headings.h6?.lineHeight ? { ["--lh-h6"]: mapHeadingLineHeight(typography.headings.h6.lineHeight) } : {},
32911
33312
  ["--tt-heading"]: mapTextTransform(typography.headings.default.case),
32912
33313
  ["--fv-heading"]: mapFontVariant(typography.headings.default.case),
32913
33314
  ["--fi-heading"]: mapFontStyle(typography.headings.default.italic),
@@ -33268,6 +33669,24 @@ function mapLetterSpacing(s) {
33268
33669
  loose: "0.02em"
33269
33670
  }[s];
33270
33671
  }
33672
+ function mapEyebrowSize(s) {
33673
+ return {
33674
+ sm: "0.75rem",
33675
+ md: "0.875rem",
33676
+ lg: "1rem"
33677
+ }[s];
33678
+ }
33679
+ function mapEyebrowLetterSpacing(s) {
33680
+ return {
33681
+ tight: "0em",
33682
+ normal: "0.025em",
33683
+ loose: "0.06em",
33684
+ wide: "0.12em"
33685
+ }[s];
33686
+ }
33687
+ function mapEyebrowCase(c) {
33688
+ return c === "uppercase" ? "uppercase" : "none";
33689
+ }
33271
33690
  function mapLineHeight(s) {
33272
33691
  return {
33273
33692
  normal: "1.5",
@@ -33275,6 +33694,22 @@ function mapLineHeight(s) {
33275
33694
  loose: "1.8"
33276
33695
  }[s];
33277
33696
  }
33697
+ /**
33698
+ * Headings get their own line-height scale, decoupled from body. `mapLineHeight`
33699
+ * is floored at 1.5 (a body leading) which reads as too airy on headings — the
33700
+ * more so as size drops. These values sit well under 1.5 and let presets taper
33701
+ * per level (larger headings tighter). `tight`/`snug` extend the token set for
33702
+ * display headings; body keeps `mapLineHeight`.
33703
+ */
33704
+ function mapHeadingLineHeight(s) {
33705
+ return {
33706
+ tight: "1.1",
33707
+ snug: "1.15",
33708
+ normal: "1.2",
33709
+ relaxed: "1.3",
33710
+ loose: "1.4"
33711
+ }[s];
33712
+ }
33278
33713
  function mapTextTransform(c) {
33279
33714
  if (c === "uppercase") return "uppercase";
33280
33715
  return "none";
@@ -33306,7 +33741,7 @@ function hydrateValue(value, context) {
33306
33741
  const resolvedItems = value.map((item) => hydrateValue(item, context));
33307
33742
  return resolvedItems.every((item, index) => item === value[index]) ? value : resolvedItems;
33308
33743
  }
33309
- if (isRecord$20(value)) {
33744
+ if (isRecord$21(value)) {
33310
33745
  if (isInternalLink(value)) return hydrateInternalLink(value, context.routes);
33311
33746
  if (isPageLink(value)) return hydratePageLink(value, context);
33312
33747
  if (isEntryLink(value)) return hydrateEntryLink(value, context);
@@ -33542,7 +33977,7 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
33542
33977
  const cleanKind = block.kind.replace(/^block\./, "");
33543
33978
  const definition = getBlockDefinition(block.kind);
33544
33979
  const managesOwnWrapper = definition?.manifest.behaviours?.managesOwnWrapper;
33545
- const renderableContent = getRenderableContent(block);
33980
+ const renderableContent = getRenderableContent(block, dataContext?.previewStage);
33546
33981
  const variantKey = definition?.manifest ? resolveVariantKey(definition.manifest, renderableContent) : null;
33547
33982
  const shouldUseWrapper = !managesOwnWrapper || Boolean(wrapBlock);
33548
33983
  const blockSectionProps = {
@@ -33568,6 +34003,7 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
33568
34003
  const wrapperClassName = [`block-${cleanKind}`, wrapBlock ? "group relative" : null].filter(Boolean).join(" ");
33569
34004
  const styleGroup = typeof renderableContent.styleGroup === "string" ? renderableContent.styleGroup : void 0;
33570
34005
  const blockLook = typeof renderableContent.blockLook === "string" ? renderableContent.blockLook : void 0;
34006
+ const blockComposition = readBlockComposition(renderableContent.blockComposition);
33571
34007
  const transitionStyle = transitionCssVarsStyle(renderableContent);
33572
34008
  const blockStyle = mergeStyleObjects(transitionStyle, boundaryReserveCssVarsStyle({
33573
34009
  before: boundaryBefore,
@@ -33581,6 +34017,8 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
33581
34017
  "data-variant": variantKey ?? void 0,
33582
34018
  "data-block-variant": variantKey ?? void 0,
33583
34019
  "data-block-look": blockLook,
34020
+ "data-block-composition": blockComposition?.treatment,
34021
+ "data-block-composition-kind": blockComposition?.kind,
33584
34022
  "data-page-block-position": blockPosition,
33585
34023
  "data-site-style-boundary-before": boundaryBefore?.metrics.size,
33586
34024
  "data-site-style-boundary-after": boundaryAfter?.metrics.size,
@@ -33781,7 +34219,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
33781
34219
  if (!definition) {
33782
34220
  if (OverrideComponent) {
33783
34221
  const rendered = /* @__PURE__ */ jsx(OverrideComponent, {
33784
- content: getRenderableContent(block),
34222
+ content: getRenderableContent(block, dataContext?.previewStage),
33785
34223
  theme: themeTokens,
33786
34224
  themeConfig,
33787
34225
  data: void 0,
@@ -33837,7 +34275,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
33837
34275
  override: false
33838
34276
  });
33839
34277
  }
33840
- const content = getRenderableContent(block);
34278
+ const content = getRenderableContent(block, dataContext?.previewStage);
33841
34279
  const parsed = getCachedValidator(definition.manifest, "strict").safeParse(content);
33842
34280
  try {
33843
34281
  if (globalThis.process?.env?.NODE_ENV !== "production" && !parsed.success && !usePlaceholders) console.warn("[blocks:PageRenderer] manifest validation failed", {
@@ -33980,8 +34418,8 @@ function resolveBlockData({ block, definition, dataContext }) {
33980
34418
  * For published: content is the source of truth.
33981
34419
  * Returns empty object if no content exists (validator will handle placeholders if needed).
33982
34420
  */
33983
- function getRenderableContent(block) {
33984
- const source = block.draftContent ?? block.content ?? {};
34421
+ function getRenderableContent(block, previewStage = "published") {
34422
+ const source = previewStage === "preview" && block.draftContent ? block.draftContent : block.content ?? {};
33985
34423
  if (!isObjectRecord(source)) return {};
33986
34424
  return source;
33987
34425
  }
@@ -34068,15 +34506,16 @@ const containerResponsiveThemeCss = `/*
34068
34506
  }
34069
34507
 
34070
34508
  /* Eyebrow text - small uppercase labels for section introductions.
34071
- font-family resolves to the optional eyebrow/mono font role, falling back
34072
- to the body font when the theme sets none (so existing themes are
34073
- unchanged). */
34509
+ Each property resolves from the optional eyebrow typographic role
34510
+ (--fs/--fw/--ls/--tt-eyebrow, emitted only when the theme sets them),
34511
+ with the historical hardcoded values as fallbacks so existing themes
34512
+ are unchanged. font-family falls back to the body font likewise. */
34074
34513
  .rb-eyebrow {
34075
34514
  font-family: var(--font-eyebrow, var(--font-body));
34076
- font-size: 0.875rem;
34077
- font-weight: 600;
34078
- letter-spacing: 0.025em;
34079
- text-transform: uppercase;
34515
+ font-size: var(--fs-eyebrow, 0.875rem);
34516
+ font-weight: var(--fw-eyebrow, 600);
34517
+ letter-spacing: var(--ls-eyebrow, 0.025em);
34518
+ text-transform: var(--tt-eyebrow, uppercase);
34080
34519
  }
34081
34520
  .rb-eyebrow-treatment-accent {
34082
34521
  color: rgb(var(--tb-accent));
@@ -40581,6 +41020,11 @@ const containerResponsiveThemeCss = `/*
40581
41020
  background-color: var(--ec-surface);
40582
41021
  color: var(--ec-text);
40583
41022
  overflow: hidden;
41023
+ }
41024
+
41025
+ /* Opt-in raised look: a soft drop shadow so the board lifts off the page.
41026
+ * Generic default (no [data-elevated]) stays flat. */
41027
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board[data-elevated] {
40584
41028
  box-shadow: 0 14px 34px -24px rgba(var(--tb-text), 0.35);
40585
41029
  }
40586
41030
 
@@ -40592,7 +41036,9 @@ const containerResponsiveThemeCss = `/*
40592
41036
  gap: 1rem;
40593
41037
  flex-wrap: wrap;
40594
41038
  padding: 1.1rem 1.5rem;
40595
- background-color: var(--ec-header-bg);
41039
+ /* surfaceAlt gives the header/footer a legible tint against the white day-grid
41040
+ * body — the faint \`--ec-header-bg\` (5% text) is invisible on light palettes. */
41041
+ background-color: rgb(var(--tb-surfaceAlt));
40596
41042
  border-bottom: 1px solid var(--ec-border-subtle);
40597
41043
  }
40598
41044
 
@@ -40705,7 +41151,10 @@ const containerResponsiveThemeCss = `/*
40705
41151
  flex-direction: column;
40706
41152
  gap: 0.45rem;
40707
41153
  padding: 0.8rem 0.85rem;
40708
- border: 1px solid var(--ec-border-subtle);
41154
+ /* Full hairline border at the site style's border strength (0 on borderless
41155
+ * styles), alongside the exaggerated status stripe on the left. \`--ec-border-subtle\`
41156
+ * (half-strength) reads as no border at all on light palettes. */
41157
+ border: var(--rb-border-width, 1px) solid rgb(var(--tb-border));
40709
41158
  border-left: 3px solid var(--ec-status-available);
40710
41159
  border-radius: calc(var(--rb-block-radius) / 1.5);
40711
41160
  background-color: var(--ec-surface);
@@ -40788,7 +41237,8 @@ const containerResponsiveThemeCss = `/*
40788
41237
  gap: 1rem;
40789
41238
  flex-wrap: wrap;
40790
41239
  padding: 1.1rem 1.5rem;
40791
- background-color: var(--ec-header-bg);
41240
+ /* Matches the header tint (see .event-week-board-top). */
41241
+ background-color: rgb(var(--tb-surfaceAlt));
40792
41242
  border-top: 1px solid var(--ec-border-subtle);
40793
41243
  }
40794
41244
 
@@ -40856,8 +41306,10 @@ const containerResponsiveThemeCss = `/*
40856
41306
  * (z-index -10) but behind the content, so no block-content wiring is needed.
40857
41307
  * Surface + hairline rules are token-referenced: on a borderless site style
40858
41308
  * (--rb-border-width: 0) the band keeps its surface tint but drops the rules.
41309
+ * Opt-in only: the band paints when the board root carries [data-banded];
41310
+ * the generic default is bandless.
40859
41311
  * ----------------------------------------------------------------------------- */
40860
- :where(.theme-scope) [data-slot="section"]:has(.event-calendar--week-board)::before {
41312
+ :where(.theme-scope) [data-slot="section"]:has(.event-calendar--week-board[data-banded])::before {
40861
41313
  content: "";
40862
41314
  position: absolute;
40863
41315
  inset: 0;
@@ -41937,7 +42389,7 @@ const containerResponsiveThemeCss = `/*
41937
42389
  }
41938
42390
 
41939
42391
  :where(.theme-scope) .shop__empty-text {
41940
- color: rgb(var(--tb-mutedText));
42392
+ color: var(--rb-surface-supporting-color, var(--rb-surface-text-color, rgb(var(--tb-mutedText))));
41941
42393
  font-size: var(--fs-body, 1rem);
41942
42394
  }
41943
42395
 
@@ -41963,7 +42415,7 @@ const containerResponsiveThemeCss = `/*
41963
42415
  :where(.theme-scope) .shop__section-heading {
41964
42416
  font-size: var(--fs-h3, 1.25rem);
41965
42417
  font-weight: 600;
41966
- color: rgb(var(--tb-text));
42418
+ color: var(--rb-surface-heading-color, var(--rb-surface-text-color, rgb(var(--tb-text))));
41967
42419
  margin-bottom: 1rem;
41968
42420
  font-family: var(--font-heading);
41969
42421
  }
@@ -41981,6 +42433,124 @@ const containerResponsiveThemeCss = `/*
41981
42433
  gap: 1rem;
41982
42434
  }
41983
42435
 
42436
+ /* Compact product register: useful for small, scannable pass/package sets. */
42437
+ :where(.theme-scope) .shop--register .shop__section {
42438
+ margin-bottom: 0;
42439
+ }
42440
+
42441
+ :where(.theme-scope) .shop--register .shop__section-heading {
42442
+ margin-bottom: 1rem;
42443
+ font-size: clamp(1.4rem, 2.2vw, 1.7rem);
42444
+ }
42445
+
42446
+ :where(.theme-scope) .shop--register .shop__products--register {
42447
+ display: flex;
42448
+ flex-direction: column;
42449
+ border-top: 1px solid color-mix(in oklab, currentColor, transparent 78%);
42450
+ }
42451
+
42452
+ :where(.theme-scope) .shop--register .shop__card {
42453
+ display: grid;
42454
+ grid-template-columns: minmax(8rem, 0.85fr) auto minmax(12rem, 1.5fr) auto;
42455
+ grid-template-rows: auto;
42456
+ align-items: center;
42457
+ column-gap: clamp(1rem, 3vw, 2.5rem);
42458
+ padding: 1rem 0;
42459
+ border: 0;
42460
+ border-bottom: 1px solid color-mix(in oklab, currentColor, transparent 78%);
42461
+ border-radius: 0;
42462
+ background: transparent;
42463
+ color: inherit;
42464
+ --rb-surface-text-color: inherit;
42465
+ --rb-surface-heading-color: inherit;
42466
+ --rb-surface-link-color: inherit;
42467
+ --rb-surface-supporting-color: inherit;
42468
+ }
42469
+
42470
+ :where(.theme-scope) .shop--register .shop__card-header {
42471
+ display: contents;
42472
+ }
42473
+
42474
+ :where(.theme-scope) .shop--register .shop__card-name,
42475
+ :where(.theme-scope) .shop--register .shop__card-price,
42476
+ :where(.theme-scope) .shop--register .shop__card-details,
42477
+ :where(.theme-scope) .shop--register .shop__cta {
42478
+ margin: 0;
42479
+ }
42480
+
42481
+ :where(.theme-scope) .shop--register .shop__card-name {
42482
+ grid-column: 1;
42483
+ grid-row: 1;
42484
+ font-family: var(--font-heading);
42485
+ font-size: 1.15rem;
42486
+ font-weight: 400;
42487
+ }
42488
+
42489
+ :where(.theme-scope) .shop--register .shop__card-price {
42490
+ grid-column: 2;
42491
+ grid-row: 1;
42492
+ font-size: 0.98rem;
42493
+ font-weight: 500;
42494
+ white-space: nowrap;
42495
+ color: var(--rb-surface-link-color, var(--rb-surface-text-color, inherit));
42496
+ }
42497
+
42498
+ :where(.theme-scope) .shop--register .shop__card-description {
42499
+ grid-column: 1 / -1;
42500
+ margin-top: 0.35rem;
42501
+ }
42502
+
42503
+ :where(.theme-scope) .shop--register .shop__card-details {
42504
+ grid-column: 3;
42505
+ grid-row: 1;
42506
+ display: flex;
42507
+ flex-wrap: wrap;
42508
+ gap: 0.35rem 1rem;
42509
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42510
+ font-size: 0.86rem;
42511
+ }
42512
+
42513
+ :where(.theme-scope) .shop--register .shop__cta {
42514
+ grid-column: 4;
42515
+ grid-row: 1;
42516
+ align-self: center;
42517
+ margin-left: auto;
42518
+ }
42519
+
42520
+ :where(.theme-scope) .shop--register .shop__card > [role='status'] {
42521
+ grid-column: 1 / -1;
42522
+ }
42523
+
42524
+ @container rb-site (max-width: 767px) {
42525
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
42526
+ :where(.theme-scope) .shop--register .shop__card {
42527
+ grid-template-columns: minmax(0, 1fr) auto;
42528
+ row-gap: 0.45rem;
42529
+ }
42530
+
42531
+ :where(.theme-scope) .shop--register .shop__card-name {
42532
+ grid-column: 1;
42533
+ }
42534
+
42535
+ :where(.theme-scope) .shop--register .shop__card-price {
42536
+ grid-column: 2;
42537
+ grid-row: 1;
42538
+ }
42539
+
42540
+ :where(.theme-scope) .shop--register .shop__card-details {
42541
+ grid-column: 1 / -1;
42542
+ grid-row: 2;
42543
+ }
42544
+
42545
+ :where(.theme-scope) .shop--register .shop__cta {
42546
+ grid-column: 1 / -1;
42547
+ grid-row: 3;
42548
+ justify-self: start;
42549
+ margin-left: 0;
42550
+ }
42551
+ }
42552
+ }
42553
+
41984
42554
  /* Product card */
41985
42555
  :where(.theme-scope) .shop__card {
41986
42556
  background: rgb(var(--tb-surface));
@@ -42009,7 +42579,7 @@ const containerResponsiveThemeCss = `/*
42009
42579
  :where(.theme-scope) .shop__card-name {
42010
42580
  font-size: 1.125rem;
42011
42581
  font-weight: 600;
42012
- color: rgb(var(--tb-text));
42582
+ color: var(--rb-surface-heading-color, rgb(var(--tb-text)));
42013
42583
  margin: 0;
42014
42584
  font-family: var(--font-heading);
42015
42585
  }
@@ -42017,19 +42587,19 @@ const containerResponsiveThemeCss = `/*
42017
42587
  :where(.theme-scope) .shop__card-price {
42018
42588
  font-size: 1.125rem;
42019
42589
  font-weight: 700;
42020
- color: rgb(var(--tb-primary));
42590
+ color: var(--rb-surface-link-color, rgb(var(--tb-primary)));
42021
42591
  white-space: nowrap;
42022
42592
  }
42023
42593
 
42024
42594
  :where(.theme-scope) .shop__card-interval {
42025
42595
  font-size: 0.875rem;
42026
42596
  font-weight: 400;
42027
- color: rgb(var(--tb-mutedText));
42597
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42028
42598
  }
42029
42599
 
42030
42600
  :where(.theme-scope) .shop__card-description {
42031
42601
  font-size: 0.875rem;
42032
- color: rgb(var(--tb-mutedText));
42602
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42033
42603
  line-height: 1.5;
42034
42604
  margin: 0;
42035
42605
  }
@@ -42039,7 +42609,7 @@ const containerResponsiveThemeCss = `/*
42039
42609
  flex-wrap: wrap;
42040
42610
  gap: 0.5rem 1rem;
42041
42611
  font-size: 0.875rem;
42042
- color: rgb(var(--tb-text));
42612
+ color: var(--rb-surface-text-color, rgb(var(--tb-text)));
42043
42613
  }
42044
42614
 
42045
42615
  :where(.theme-scope) .shop__card-credits {
@@ -42047,16 +42617,16 @@ const containerResponsiveThemeCss = `/*
42047
42617
  }
42048
42618
 
42049
42619
  :where(.theme-scope) .shop__card-per-credit {
42050
- color: rgb(var(--tb-mutedText));
42620
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42051
42621
  }
42052
42622
 
42053
42623
  :where(.theme-scope) .shop__card-validity {
42054
- color: rgb(var(--tb-mutedText));
42624
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42055
42625
  }
42056
42626
 
42057
42627
  :where(.theme-scope) .shop__card-unlimited {
42058
42628
  font-weight: 500;
42059
- color: rgb(var(--tb-secondary, var(--tb-primary)));
42629
+ color: var(--rb-surface-link-color, rgb(var(--tb-secondary, var(--tb-primary))));
42060
42630
  }
42061
42631
 
42062
42632
  /* CTA layout: use theme button classes for visuals */
@@ -43113,6 +43683,16 @@ const containerResponsiveThemeCss = `/*
43113
43683
  * tokens only. Node structure is built in testimonialsCarousel.ts.
43114
43684
  * ============================================================================= */
43115
43685
 
43686
+ /* Establish an inline-size query container so the head and grid below respond
43687
+ * to the block's own width, not the browser viewport. A viewport @media query
43688
+ * collapses to 1-col in the dashboard's scaled preview canvas (which reads the
43689
+ * dashboard window, not the canvas) and when the block sits in a narrow column;
43690
+ * @container tracks the actual laid-out width — matching the split-grid variant. */
43691
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe {
43692
+ container-type: inline-size;
43693
+ container-name: rb-testimonials-fe;
43694
+ }
43695
+
43116
43696
  /* Section head: heading left, lead-in line to the right; stacks on mobile. */
43117
43697
  :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-head {
43118
43698
  display: flex;
@@ -43125,16 +43705,14 @@ const containerResponsiveThemeCss = `/*
43125
43705
  max-width: 30rem;
43126
43706
  }
43127
43707
 
43128
- @container rb-site (min-width: 768px) {
43129
- @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
43130
- :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-head {
43708
+ @container rb-testimonials-fe (min-width: 768px) {
43709
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-head {
43131
43710
  flex-direction: row;
43132
43711
  align-items: flex-end;
43133
43712
  justify-content: space-between;
43134
43713
  gap: 1.5rem;
43135
43714
  }
43136
43715
  }
43137
- }
43138
43716
 
43139
43717
  /* Card grid: featured (wider) beside the stacked column. Single column on
43140
43718
  * small screens. */
@@ -43145,13 +43723,11 @@ const containerResponsiveThemeCss = `/*
43145
43723
  align-items: stretch;
43146
43724
  }
43147
43725
 
43148
- @container rb-site (min-width: 1024px) {
43149
- @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
43150
- :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-grid {
43726
+ @container rb-testimonials-fe (min-width: 1024px) {
43727
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-grid {
43151
43728
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
43152
43729
  }
43153
43730
  }
43154
- }
43155
43731
 
43156
43732
  :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-col {
43157
43733
  display: grid;
@@ -44476,6 +45052,52 @@ const containerResponsiveThemeCss = `/*
44476
45052
  }
44477
45053
  }
44478
45054
 
45055
+ /* =============================================================================
45056
+ * Editorial Split Variant
45057
+ * =============================================================================
45058
+ */
45059
+
45060
+ :where(.theme-scope) .newsletter-editorial-split {
45061
+ display: grid;
45062
+ grid-template-columns: minmax(0, 0.9fr) minmax(20rem, 1.1fr);
45063
+ gap: clamp(2.5rem, 7vw, 7rem);
45064
+ align-items: center;
45065
+ text-align: left;
45066
+ }
45067
+
45068
+ :where(.theme-scope) .newsletter-editorial-split-copy {
45069
+ display: flex;
45070
+ flex-direction: column;
45071
+ gap: var(--rb-gap-sm, 0.75rem);
45072
+ }
45073
+
45074
+ :where(.theme-scope) .newsletter-editorial-split-form {
45075
+ min-width: 0;
45076
+ }
45077
+
45078
+ :where(.theme-scope) .newsletter-editorial-split .newsletter-form {
45079
+ max-width: none;
45080
+ margin-inline: 0;
45081
+ }
45082
+
45083
+ :where(.theme-scope) .newsletter-editorial-split .newsletter-copy-title {
45084
+ font-size: clamp(2rem, 4vw, 3.5rem);
45085
+ font-weight: 500;
45086
+ }
45087
+
45088
+ :where(.theme-scope) .newsletter-editorial-split .newsletter-privacy-note {
45089
+ text-align: left;
45090
+ }
45091
+
45092
+ @container rb-site (max-width: 767px) {
45093
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
45094
+ :where(.theme-scope) .newsletter-editorial-split {
45095
+ grid-template-columns: minmax(0, 1fr);
45096
+ gap: 2rem;
45097
+ }
45098
+ }
45099
+ }
45100
+
44479
45101
  /* =============================================================================
44480
45102
  * Success State
44481
45103
  * =============================================================================
@@ -45491,13 +46113,13 @@ const containerResponsiveThemeCss = `/*
45491
46113
  * bleeds to the card edges and the inner content stack drops its fallback
45492
46114
  * padding so insets don't double up.
45493
46115
  */
45494
- :where(.theme-scope) .rb-feature-card[class*="rb-container-pad-"]:not(.rb-container-pad-none) > .rb-feature-card-media {
46116
+ :where(.theme-scope) .rb-feature-card[class*="rb-container-pad-"]:not(.rb-container-pad-none) > .rb-feature-card-media-frame {
45495
46117
  width: calc(100% + 2 * var(--rb-card-pad, 0rem));
45496
46118
  max-width: none;
45497
46119
  margin: calc(-1 * var(--rb-card-pad, 0rem)) calc(-1 * var(--rb-card-pad, 0rem)) 0;
45498
46120
  }
45499
46121
 
45500
- :where(.theme-scope) .rb-feature-card[class*="rb-container-pad-"]:not(.rb-container-pad-none) > .rb-feature-card-media + .rb-feature-card-content {
46122
+ :where(.theme-scope) .rb-feature-card[class*="rb-container-pad-"]:not(.rb-container-pad-none) > .rb-feature-card-media-frame + .rb-feature-card-content {
45501
46123
  margin-top: 1.4rem;
45502
46124
  }
45503
46125
 
@@ -45548,11 +46170,122 @@ const containerResponsiveThemeCss = `/*
45548
46170
  background: rgb(var(--tb-primary, 0 0 0));
45549
46171
  }
45550
46172
 
45551
- :where(.theme-scope) .rb-card-treatment-editorial-rule > .rb-feature-card-media {
46173
+ :where(.theme-scope) .rb-card-treatment-editorial-rule > .rb-feature-card-media-frame {
45552
46174
  margin-top: 1.6rem;
45553
46175
  border-radius: calc(var(--rb-block-radius, 0.75rem) * 0.5);
45554
46176
  }
45555
46177
 
46178
+ :where(.theme-scope) .rb-feature-card > .rb-bg-surface,
46179
+ :where(.theme-scope) .rb-feature-card > .rb-feature-card-media-frame {
46180
+ border-start-start-radius: inherit;
46181
+ border-start-end-radius: inherit;
46182
+ }
46183
+
46184
+ /* --- Editorial diptych + pathways ----------------------------------------- */
46185
+
46186
+ :where(.theme-scope) .rb-feature-cards-heading--editorial {
46187
+ margin-inline: 0;
46188
+ text-align: left;
46189
+ }
46190
+
46191
+ :where(.theme-scope) .rb-feature-cards-eyebrow {
46192
+ margin: 0;
46193
+ color: rgb(var(--tb-accent));
46194
+ font-size: 0.72rem;
46195
+ font-weight: 600;
46196
+ letter-spacing: 0.14em;
46197
+ text-transform: uppercase;
46198
+ }
46199
+
46200
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych {
46201
+ grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
46202
+ align-items: stretch;
46203
+ }
46204
+
46205
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways {
46206
+ grid-template-columns: repeat(2, minmax(0, 1fr));
46207
+ align-items: start;
46208
+ }
46209
+
46210
+ :where(.theme-scope) .rb-feature-cards-grid:is(
46211
+ .rb-feature-cards-grid--editorial-diptych,
46212
+ .rb-feature-cards-grid--editorial-pathways
46213
+ ) .rb-feature-card {
46214
+ border: 0;
46215
+ box-shadow: none;
46216
+ height: auto;
46217
+ min-width: 0;
46218
+ }
46219
+
46220
+ :where(.theme-scope) .rb-feature-cards-grid:is(
46221
+ .rb-feature-cards-grid--editorial-diptych,
46222
+ .rb-feature-cards-grid--editorial-pathways
46223
+ ) .rb-feature-card[data-surface-role="open"] > .rb-bg-surface {
46224
+ background: transparent;
46225
+ }
46226
+
46227
+ :where(.theme-scope) .rb-feature-cards-grid:is(
46228
+ .rb-feature-cards-grid--editorial-diptych,
46229
+ .rb-feature-cards-grid--editorial-pathways
46230
+ ) .rb-feature-card[data-surface-role="open"] > .rb-feature-card-content {
46231
+ padding-inline: 0;
46232
+ }
46233
+
46234
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways .rb-feature-card > .rb-bg-surface {
46235
+ background: transparent;
46236
+ }
46237
+
46238
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways .rb-feature-card > .rb-feature-card-content {
46239
+ padding-inline: 0;
46240
+ }
46241
+
46242
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych .rb-feature-card[data-surface-role="panel"] {
46243
+ color: rgb(var(--tb-onPrimary));
46244
+ --rb-surface-text-color: rgb(var(--tb-onPrimary));
46245
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary));
46246
+ --rb-surface-link-color: rgb(var(--tb-onPrimary));
46247
+ --rb-surface-supporting-color: color-mix(in oklab, rgb(var(--tb-onPrimary)), transparent 18%);
46248
+ }
46249
+
46250
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych .rb-feature-card[data-surface-role="panel"] > .rb-bg-surface {
46251
+ background: rgb(var(--tb-primary));
46252
+ border-radius: inherit;
46253
+ }
46254
+
46255
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych .rb-feature-card[data-surface-role="panel"] > .rb-feature-card-media-frame {
46256
+ width: calc(100% - 2.5rem);
46257
+ margin: 1.25rem 1.25rem 0;
46258
+ border-radius: calc(var(--rb-block-radius, 0.75rem) * 0.55);
46259
+ }
46260
+
46261
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways .rb-feature-card-content {
46262
+ padding-top: 1.35rem;
46263
+ }
46264
+
46265
+ @container rb-site (min-width: 768px) {
46266
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46267
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych .rb-feature-card[data-surface-role="panel"] {
46268
+ margin-top: clamp(2rem, 5vw, 4.5rem);
46269
+ }
46270
+
46271
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways .rb-feature-card + .rb-feature-card {
46272
+ border-left: 1px solid color-mix(in oklab, currentColor, transparent 82%);
46273
+ padding-left: clamp(1.5rem, 4vw, 4rem);
46274
+ }
46275
+ }
46276
+ }
46277
+
46278
+ @container rb-site (max-width: 767px) {
46279
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46280
+ :where(.theme-scope) .rb-feature-cards-grid:is(
46281
+ .rb-feature-cards-grid--editorial-diptych,
46282
+ .rb-feature-cards-grid--editorial-pathways
46283
+ ) {
46284
+ grid-template-columns: minmax(0, 1fr);
46285
+ }
46286
+ }
46287
+ }
46288
+
45556
46289
  :where(.theme-scope) .rb-card-treatment-editorial-rule > .rb-feature-card-content {
45557
46290
  padding: 1.6rem 0 0.25rem;
45558
46291
  }
@@ -45641,12 +46374,12 @@ const containerResponsiveThemeCss = `/*
45641
46374
  }
45642
46375
  }
45643
46376
 
45644
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-portrait-bio"][data-block-variant="media-copy"] .rb-intro-media-wrap {
46377
+ :where(.theme-scope) [data-block="intro"][data-block-composition="portrait-bio"][data-block-variant="media-copy"] .rb-intro-media-wrap {
45645
46378
  max-width: min(100%, 24rem);
45646
46379
  margin-inline: auto;
45647
46380
  }
45648
46381
 
45649
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-portrait-bio"][data-block-variant="media-copy"] .rb-intro-media {
46382
+ :where(.theme-scope) [data-block="intro"][data-block-composition="portrait-bio"][data-block-variant="media-copy"] .rb-intro-media {
45650
46383
  aspect-ratio: 1 / 1 !important;
45651
46384
  border-radius: 9999px;
45652
46385
  }
@@ -45667,18 +46400,914 @@ const containerResponsiveThemeCss = `/*
45667
46400
  }
45668
46401
  }
45669
46402
 
45670
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-editorial-statement"] .rb-intro-title {
46403
+ :where(.theme-scope) [data-block="intro"][data-block-composition="editorial-statement"] .rb-intro-title {
45671
46404
  font-size: clamp(2rem, 1.56rem + 1.4vw, 3rem);
45672
46405
  line-height: 1.14;
45673
46406
  }
45674
46407
 
45675
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-editorial-statement"] .rb-intro-copy {
46408
+ :where(.theme-scope) [data-block="intro"][data-block-composition="editorial-statement"] .rb-intro-copy {
45676
46409
  gap: var(--rb-space-5, 1.25rem);
45677
46410
  }
45678
46411
 
45679
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-editorial-statement"] .rb-intro-copy .rb-prose {
46412
+ :where(.theme-scope) [data-block="intro"][data-block-composition="editorial-statement"] .rb-intro-copy .rb-prose {
45680
46413
  font-size: clamp(1.125rem, 1.02rem + 0.35vw, 1.375rem);
45681
46414
  line-height: 1.65;
46415
+ }
46416
+
46417
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-section {
46418
+ width: min(100%, 66rem);
46419
+ margin-inline: auto;
46420
+ }
46421
+
46422
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-heading {
46423
+ max-width: 44rem;
46424
+ }
46425
+
46426
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-header {
46427
+ display: flex;
46428
+ gap: 2rem;
46429
+ align-items: end;
46430
+ justify-content: space-between;
46431
+ }
46432
+
46433
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-eyebrow {
46434
+ margin: 0;
46435
+ color: rgb(var(--tb-accent));
46436
+ font-size: 0.72rem;
46437
+ font-weight: 600;
46438
+ letter-spacing: 0.14em;
46439
+ text-transform: uppercase;
46440
+ }
46441
+
46442
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-heading-title {
46443
+ margin: 0;
46444
+ font-size: clamp(2rem, 4.6vw, 3.3rem);
46445
+ line-height: 1.08;
46446
+ }
46447
+
46448
+ :where(.theme-scope) .recurring-schedule {
46449
+ border-top: 1px solid color-mix(in oklab, currentColor, transparent 78%);
46450
+ }
46451
+
46452
+ :where(.theme-scope) .recurring-schedule-row {
46453
+ display: grid;
46454
+ grid-template-columns: minmax(9rem, 0.82fr) minmax(16rem, 1.5fr) auto;
46455
+ grid-template-rows: auto auto;
46456
+ column-gap: clamp(1.5rem, 4vw, 2.75rem);
46457
+ row-gap: 0.15rem;
46458
+ align-items: center;
46459
+ padding: 1.4rem 0.75rem;
46460
+ border-bottom: 1px solid color-mix(in oklab, currentColor, transparent 78%);
46461
+ color: inherit;
46462
+ }
46463
+
46464
+ :where(.theme-scope) .recurring-schedule-day,
46465
+ :where(.theme-scope) .recurring-schedule-time,
46466
+ :where(.theme-scope) .recurring-schedule-title,
46467
+ :where(.theme-scope) .recurring-schedule-venue {
46468
+ margin: 0;
46469
+ }
46470
+
46471
+ :where(.theme-scope) .recurring-schedule-day {
46472
+ grid-column: 1;
46473
+ grid-row: 1;
46474
+ font-family: var(--font-heading);
46475
+ font-size: clamp(1.25rem, 2vw, 1.5rem);
46476
+ line-height: 1;
46477
+ }
46478
+
46479
+ :where(.theme-scope) .recurring-schedule-time {
46480
+ grid-column: 1;
46481
+ grid-row: 2;
46482
+ display: flex;
46483
+ gap: 0.35rem;
46484
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
46485
+ font-size: 0.86rem;
46486
+ font-variant-numeric: tabular-nums;
46487
+ }
46488
+
46489
+ :where(.theme-scope) .recurring-schedule-details {
46490
+ grid-column: 2;
46491
+ grid-row: 1 / span 2;
46492
+ align-self: center;
46493
+ }
46494
+
46495
+ :where(.theme-scope) .recurring-schedule-title {
46496
+ font-size: 1.06rem;
46497
+ font-weight: 500;
46498
+ }
46499
+
46500
+ :where(.theme-scope) .recurring-schedule-venue {
46501
+ margin-top: 0.2rem;
46502
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
46503
+ font-size: 0.92rem;
46504
+ }
46505
+
46506
+ :where(.theme-scope) .recurring-schedule-action {
46507
+ grid-column: 3;
46508
+ grid-row: 1 / span 2;
46509
+ min-width: 4.5rem;
46510
+ text-align: right;
46511
+ }
46512
+
46513
+ :where(.theme-scope) .recurring-schedule-see-all {
46514
+ width: fit-content;
46515
+ color: inherit;
46516
+ text-underline-offset: 0.3em;
46517
+ }
46518
+
46519
+ :where(.theme-scope) .recurring-schedule-empty {
46520
+ margin: 0;
46521
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
46522
+ }
46523
+
46524
+ @container rb-site (max-width: 767px) {
46525
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46526
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-header {
46527
+ align-items: start;
46528
+ flex-direction: column;
46529
+ gap: 1rem;
46530
+ }
46531
+
46532
+ :where(.theme-scope) .recurring-schedule-row {
46533
+ grid-template-columns: 1fr auto;
46534
+ grid-template-rows: auto auto auto;
46535
+ gap: 0.5rem 1rem;
46536
+ align-items: start;
46537
+ }
46538
+
46539
+ :where(.theme-scope) .recurring-schedule-day {
46540
+ grid-column: 1;
46541
+ }
46542
+
46543
+ :where(.theme-scope) .recurring-schedule-time {
46544
+ grid-column: 1;
46545
+ }
46546
+
46547
+ :where(.theme-scope) .recurring-schedule-details {
46548
+ grid-column: 1 / -1;
46549
+ grid-row: 3;
46550
+ margin-top: 0.35rem;
46551
+ }
46552
+
46553
+ :where(.theme-scope) .recurring-schedule-action {
46554
+ grid-column: 2;
46555
+ grid-row: 1 / span 2;
46556
+ }
46557
+ }
46558
+ }
46559
+
46560
+ /* =============================================================================
46561
+ * Event list treatments: registers and dense indexes
46562
+ *
46563
+ * These treatments retain the event list's content and structural layout.
46564
+ * Their contrast relationships come exclusively from the active semantic
46565
+ * section surface and named palette tokens.
46566
+ * ============================================================================= */
46567
+
46568
+ :where(.theme-scope)
46569
+ :where(
46570
+ .rb-event-list-treatment-ruled-register,
46571
+ .rb-event-list-treatment-editorial-register,
46572
+ .rb-event-list-treatment-dense-index
46573
+ )
46574
+ .event-card.event-card {
46575
+ position: relative;
46576
+ overflow: visible;
46577
+ border: 0;
46578
+ border-radius: 0;
46579
+ background: transparent;
46580
+ box-shadow: none;
46581
+ color: inherit;
46582
+ }
46583
+
46584
+ /* Register treatments intentionally prioritise schedule data over imagery. */
46585
+ :where(.theme-scope)
46586
+ :where(
46587
+ .rb-event-list-treatment-ruled-register,
46588
+ .rb-event-list-treatment-editorial-register,
46589
+ .rb-event-list-treatment-dense-index
46590
+ )
46591
+ .event-card.event-card
46592
+ .event-card-media {
46593
+ display: none;
46594
+ }
46595
+
46596
+ :where(.theme-scope)
46597
+ :where(
46598
+ .rb-event-list-treatment-ruled-register,
46599
+ .rb-event-list-treatment-editorial-register,
46600
+ .rb-event-list-treatment-dense-index
46601
+ )
46602
+ .event-card.event-card
46603
+ .card-content {
46604
+ min-width: 0;
46605
+ padding: 1.5rem 0.625rem;
46606
+ }
46607
+
46608
+ :where(.theme-scope)
46609
+ :where(
46610
+ .rb-event-list-treatment-ruled-register,
46611
+ .rb-event-list-treatment-editorial-register,
46612
+ .rb-event-list-treatment-dense-index
46613
+ )
46614
+ .event-card.event-card
46615
+ .card-title {
46616
+ min-width: 0;
46617
+ margin-bottom: 0.25rem;
46618
+ }
46619
+
46620
+ :where(.theme-scope)
46621
+ :where(
46622
+ .rb-event-list-treatment-ruled-register,
46623
+ .rb-event-list-treatment-editorial-register,
46624
+ .rb-event-list-treatment-dense-index
46625
+ )
46626
+ .event-card.event-card
46627
+ .event-card-footer {
46628
+ min-width: 8rem;
46629
+ padding-top: 0;
46630
+ }
46631
+
46632
+ :where(.theme-scope)
46633
+ :where(
46634
+ .rb-event-list-treatment-ruled-register,
46635
+ .rb-event-list-treatment-editorial-register,
46636
+ .rb-event-list-treatment-dense-index
46637
+ )
46638
+ .event-card.event-card
46639
+ .event-card-cta {
46640
+ width: 100%;
46641
+ }
46642
+
46643
+ /* Ruled register: open rows with quiet rules on the current section surface. */
46644
+ :where(.theme-scope)
46645
+ .rb-event-list-treatment-ruled-register
46646
+ .event-card.event-card {
46647
+ border-top: 1px solid color-mix(in oklab, currentColor, transparent 78%);
46648
+ }
46649
+
46650
+ :where(.theme-scope)
46651
+ .rb-event-list-treatment-ruled-register
46652
+ .event-card.event-card:last-child {
46653
+ border-bottom: 1px solid color-mix(in oklab, currentColor, transparent 78%);
46654
+ }
46655
+
46656
+ /* Editorial register: generous rows, an accent marker and display-led titles. */
46657
+ :where(.theme-scope)
46658
+ .rb-event-list-treatment-editorial-register
46659
+ .event-card.event-card {
46660
+ border-top: 1px solid color-mix(in oklab, rgb(var(--tb-border)), transparent 20%);
46661
+ }
46662
+
46663
+ :where(.theme-scope)
46664
+ .rb-event-list-treatment-editorial-register
46665
+ .event-card.event-card:last-child {
46666
+ border-bottom: 1px solid color-mix(in oklab, rgb(var(--tb-border)), transparent 20%);
46667
+ }
46668
+
46669
+ :where(.theme-scope)
46670
+ .rb-event-list-treatment-editorial-register
46671
+ .event-card.event-card::before {
46672
+ content: "";
46673
+ position: absolute;
46674
+ inset-block: 1.75rem;
46675
+ inset-inline-start: 0;
46676
+ width: 0.25rem;
46677
+ border-radius: var(--rb-block-radius, 0.75rem);
46678
+ background: rgb(var(--tb-accent));
46679
+ }
46680
+
46681
+ :where(.theme-scope)
46682
+ .rb-event-list-treatment-editorial-register
46683
+ .event-card.event-card
46684
+ .card-content {
46685
+ padding-block: 1.875rem;
46686
+ padding-inline-start: clamp(1.25rem, 2.5vw, 2rem);
46687
+ }
46688
+
46689
+ :where(.theme-scope)
46690
+ .rb-event-list-treatment-editorial-register
46691
+ .event-card.event-card
46692
+ .card-title {
46693
+ font-family: var(--font-heading, var(--font-body, inherit));
46694
+ font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
46695
+ font-weight: 500;
46696
+ line-height: 1.15;
46697
+ }
46698
+
46699
+ /* Dense index: stronger outside rule and reduced row rhythm, without opting
46700
+ * the block into its structurally different compact-list facet. */
46701
+ :where(.theme-scope)
46702
+ .rb-event-list-treatment-dense-index
46703
+ .event-card.event-card {
46704
+ border-bottom: 1px solid color-mix(in oklab, currentColor, transparent 62%);
46705
+ }
46706
+
46707
+ :where(.theme-scope)
46708
+ .rb-event-list-treatment-dense-index
46709
+ .event-card.event-card:first-child {
46710
+ border-top: 2px solid currentColor;
46711
+ }
46712
+
46713
+ :where(.theme-scope)
46714
+ .rb-event-list-treatment-dense-index
46715
+ .event-card.event-card
46716
+ .card-content {
46717
+ padding-block: 1.125rem;
46718
+ }
46719
+
46720
+ :where(.theme-scope)
46721
+ .rb-event-list-treatment-dense-index
46722
+ .event-card.event-card
46723
+ .card-title {
46724
+ font-size: 1rem;
46725
+ line-height: 1.35;
46726
+ }
46727
+
46728
+ @container rb-site (min-width: 768px) {
46729
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46730
+ :where(.theme-scope)
46731
+ :where(
46732
+ .rb-event-list-treatment-ruled-register,
46733
+ .rb-event-list-treatment-editorial-register,
46734
+ .rb-event-list-treatment-dense-index
46735
+ )
46736
+ .event-card.event-card.event-card--horizontal {
46737
+ display: block;
46738
+ }
46739
+
46740
+ :where(.theme-scope)
46741
+ :where(
46742
+ .rb-event-list-treatment-ruled-register,
46743
+ .rb-event-list-treatment-editorial-register,
46744
+ .rb-event-list-treatment-dense-index
46745
+ )
46746
+ .event-card.event-card.event-card--horizontal
46747
+ .card-content {
46748
+ display: grid;
46749
+ grid-template-columns: minmax(8.5rem, 0.7fr) minmax(15rem, 1.55fr) auto;
46750
+ grid-template-rows: auto auto auto;
46751
+ align-items: center;
46752
+ column-gap: clamp(1.25rem, 3vw, 2.625rem);
46753
+ }
46754
+
46755
+ :where(.theme-scope)
46756
+ :where(
46757
+ .rb-event-list-treatment-ruled-register,
46758
+ .rb-event-list-treatment-editorial-register,
46759
+ .rb-event-list-treatment-dense-index
46760
+ )
46761
+ .event-card.event-card.event-card--horizontal
46762
+ .card-title {
46763
+ grid-column: 2;
46764
+ }
46765
+
46766
+ :where(.theme-scope)
46767
+ :where(
46768
+ .rb-event-list-treatment-ruled-register,
46769
+ .rb-event-list-treatment-editorial-register,
46770
+ .rb-event-list-treatment-dense-index
46771
+ )
46772
+ .event-card.event-card.event-card--horizontal
46773
+ .card-content > div.rb-caption {
46774
+ grid-column: 1;
46775
+ grid-row: 1 / span 6;
46776
+ margin-bottom: 0;
46777
+ }
46778
+
46779
+ :where(.theme-scope)
46780
+ :where(
46781
+ .rb-event-list-treatment-ruled-register,
46782
+ .rb-event-list-treatment-editorial-register,
46783
+ .rb-event-list-treatment-dense-index
46784
+ )
46785
+ .event-card.event-card.event-card--horizontal
46786
+ .card-content > div.rb-mb-3 {
46787
+ grid-column: 2;
46788
+ margin-bottom: 0;
46789
+ }
46790
+
46791
+ :where(.theme-scope)
46792
+ :where(
46793
+ .rb-event-list-treatment-ruled-register,
46794
+ .rb-event-list-treatment-editorial-register,
46795
+ .rb-event-list-treatment-dense-index
46796
+ )
46797
+ .event-card.event-card.event-card--horizontal
46798
+ .card-content > .event-category-badge {
46799
+ grid-column: 2;
46800
+ }
46801
+
46802
+ :where(.theme-scope)
46803
+ :where(
46804
+ .rb-event-list-treatment-ruled-register,
46805
+ .rb-event-list-treatment-editorial-register,
46806
+ .rb-event-list-treatment-dense-index
46807
+ )
46808
+ .event-card.event-card.event-card--horizontal
46809
+ .card-content > .card-body,
46810
+ :where(.theme-scope)
46811
+ :where(
46812
+ .rb-event-list-treatment-ruled-register,
46813
+ .rb-event-list-treatment-editorial-register,
46814
+ .rb-event-list-treatment-dense-index
46815
+ )
46816
+ .event-card.event-card.event-card--horizontal
46817
+ .card-content > .status-muted:not(.event-card-capacity) {
46818
+ grid-column: 2;
46819
+ }
46820
+
46821
+ :where(.theme-scope)
46822
+ :where(
46823
+ .rb-event-list-treatment-ruled-register,
46824
+ .rb-event-list-treatment-editorial-register,
46825
+ .rb-event-list-treatment-dense-index
46826
+ )
46827
+ .event-card.event-card.event-card--horizontal
46828
+ .event-card-footer {
46829
+ grid-column: 3;
46830
+ grid-row: 1 / span 6;
46831
+ flex-direction: column;
46832
+ justify-content: center;
46833
+ align-items: stretch;
46834
+ }
46835
+ }
46836
+ }
46837
+
46838
+ /* =============================================================================
46839
+ * Feature-card composition Looks promoted from block-treatment studies.
46840
+ * Palette relationships use named semantic tokens; copy and media stay in the
46841
+ * existing feature-card content contract.
46842
+ * ============================================================================= */
46843
+
46844
+ /* Asymmetric emphasis: repeat a 5/7 pair rhythm and give each even card a
46845
+ * semantic secondary surface. This remains useful with more than two cards. */
46846
+ :where(.theme-scope)
46847
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46848
+ .rb-feature-cards-grid {
46849
+ align-items: start;
46850
+ }
46851
+ :where(.theme-scope)
46852
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46853
+ .rb-feature-card {
46854
+ height: auto;
46855
+ overflow: hidden;
46856
+ border: 0;
46857
+ border-radius: 0;
46858
+ background: transparent;
46859
+ }
46860
+
46861
+ :where(.theme-scope)
46862
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46863
+ .rb-feature-card > .rb-feature-card-content {
46864
+ padding-inline: 0;
46865
+ }
46866
+
46867
+ :where(.theme-scope)
46868
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46869
+ .rb-feature-card:nth-child(even) {
46870
+ padding: clamp(1.125rem, 2.5vw, 1.875rem);
46871
+ border-radius: calc(var(--rb-block-radius, 0.75rem) * 1.5);
46872
+ background: rgb(var(--tb-secondary));
46873
+ color: rgb(var(--tb-onSecondary));
46874
+ --rb-surface-text-color: rgb(var(--tb-onSecondary));
46875
+ --rb-surface-heading-color: rgb(var(--tb-onSecondary));
46876
+ --rb-surface-link-color: rgb(var(--tb-onSecondary));
46877
+ --rb-surface-supporting-color: rgb(var(--tb-onSecondary));
46878
+ }
46879
+
46880
+ :where(.theme-scope)
46881
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46882
+ .rb-feature-card:nth-child(even) > .rb-feature-card-media {
46883
+ border-radius: var(--rb-block-radius, 0.75rem);
46884
+ }
46885
+
46886
+ /* Framed programme: a close-set family of inset cards on a semantic depth
46887
+ * section. The itemSurface recipe supplies each complete surface provider. */
46888
+ :where(.theme-scope)
46889
+ [data-block="feature-cards"][data-block-composition="framed-programme"]
46890
+ .rb-feature-cards-grid {
46891
+ gap: clamp(1rem, 2vw, 1.5rem);
46892
+ }
46893
+
46894
+ :where(.theme-scope)
46895
+ [data-block="feature-cards"][data-block-composition="framed-programme"]
46896
+ .rb-feature-card > .rb-feature-card-media {
46897
+ width: 100%;
46898
+ max-width: 100%;
46899
+ margin: 0;
46900
+ border-radius: var(--rb-block-radius, 0.75rem);
46901
+ }
46902
+
46903
+ :where(.theme-scope)
46904
+ [data-block="feature-cards"][data-block-composition="framed-programme"]
46905
+ .rb-feature-card > .rb-feature-card-content {
46906
+ padding-inline: 0;
46907
+ padding-bottom: 0;
46908
+ }
46909
+
46910
+ @container rb-site (min-width: 768px) {
46911
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46912
+ :where(.theme-scope)
46913
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46914
+ .rb-feature-cards-grid.rb-grid-cols-2 {
46915
+ grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
46916
+ }
46917
+ }
46918
+ }
46919
+
46920
+ /* =============================================================================
46921
+ * Offerings Preview composition Looks promoted from the Fran André treatment
46922
+ * study. The outer section surface remains independently configurable. These
46923
+ * rules use expanded semantic palette tokens only.
46924
+ * ============================================================================= */
46925
+
46926
+ :where(.theme-scope)
46927
+ [data-block="offerings-preview"]
46928
+ [data-offering-presentation="featured-summary"]
46929
+ .offerings-preview-card-header {
46930
+ text-align: left;
46931
+ }
46932
+
46933
+ :where(.theme-scope)
46934
+ [data-block="offerings-preview"]
46935
+ .offerings-preview-summary-date {
46936
+ margin: 0;
46937
+ font-family: var(--font-heading, inherit);
46938
+ font-size: clamp(1.125rem, 2.2vw, 1.5rem);
46939
+ font-weight: 650;
46940
+ line-height: 1.22;
46941
+ }
46942
+
46943
+ :where(.theme-scope)
46944
+ [data-block="offerings-preview"]
46945
+ .offerings-preview-summary-date time {
46946
+ display: inline-block;
46947
+ }
46948
+
46949
+ :where(.theme-scope)
46950
+ [data-block="offerings-preview"]
46951
+ .offerings-preview-summary-facts {
46952
+ display: grid;
46953
+ gap: 0;
46954
+ margin: clamp(1.25rem, 3vw, 2rem) 0 0;
46955
+ }
46956
+
46957
+ :where(.theme-scope)
46958
+ [data-block="offerings-preview"]
46959
+ .offerings-preview-summary-facts > div {
46960
+ display: grid;
46961
+ grid-template-columns: minmax(5.5rem, 0.65fr) minmax(0, 1.35fr);
46962
+ gap: 1rem;
46963
+ padding-block: 0.6rem;
46964
+ border-top: 1px solid rgba(var(--tb-border), 0.72);
46965
+ }
46966
+
46967
+ :where(.theme-scope)
46968
+ [data-block="offerings-preview"]
46969
+ .offerings-preview-summary-facts dt {
46970
+ font-size: 0.72rem;
46971
+ font-weight: 750;
46972
+ letter-spacing: 0.1em;
46973
+ text-transform: uppercase;
46974
+ }
46975
+
46976
+ :where(.theme-scope)
46977
+ [data-block="offerings-preview"]
46978
+ .offerings-preview-summary-facts dd {
46979
+ min-width: 0;
46980
+ margin: 0;
46981
+ font-weight: 600;
46982
+ }
46983
+
46984
+ :where(.theme-scope)
46985
+ [data-block="offerings-preview"]:is(
46986
+ [data-block-look="offerings-preview-paired-feature-cards"],
46987
+ [data-block-look="offerings-preview-open-editorial-columns"],
46988
+ [data-block-look="offerings-preview-joined-programme-panel"]
46989
+ )
46990
+ .offerings-preview {
46991
+ container: rb-offerings-preview / inline-size;
46992
+ }
46993
+
46994
+ :where(.theme-scope)
46995
+ [data-block="offerings-preview"]:is(
46996
+ [data-block-look="offerings-preview-paired-feature-cards"],
46997
+ [data-block-look="offerings-preview-open-editorial-columns"],
46998
+ [data-block-look="offerings-preview-joined-programme-panel"]
46999
+ )
47000
+ .offerings-preview-card {
47001
+ min-width: 0;
47002
+ }
47003
+
47004
+ :where(.theme-scope)
47005
+ [data-block="offerings-preview"]:is(
47006
+ [data-block-look="offerings-preview-paired-feature-cards"],
47007
+ [data-block-look="offerings-preview-open-editorial-columns"],
47008
+ [data-block-look="offerings-preview-joined-programme-panel"]
47009
+ )
47010
+ .offerings-preview-card-content {
47011
+ padding: clamp(1.4rem, 3.5vw, 2.75rem);
47012
+ }
47013
+
47014
+ :where(.theme-scope)
47015
+ [data-block="offerings-preview"]:is(
47016
+ [data-block-look="offerings-preview-paired-feature-cards"],
47017
+ [data-block-look="offerings-preview-open-editorial-columns"],
47018
+ [data-block-look="offerings-preview-joined-programme-panel"]
47019
+ )
47020
+ .offerings-preview-card-footer {
47021
+ margin-top: auto;
47022
+ padding-top: clamp(1.25rem, 3vw, 2rem);
47023
+ }
47024
+
47025
+ /* Paired feature cards: one editorial lead and one supporting route. With a
47026
+ * third group the grid returns to equal columns rather than implying a new
47027
+ * source hierarchy. */
47028
+ :where(.theme-scope)
47029
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47030
+ .offerings-preview-grid {
47031
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)) !important;
47032
+ gap: clamp(1rem, 2.5vw, 1.5rem);
47033
+ }
47034
+
47035
+ :where(.theme-scope)
47036
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47037
+ .offerings-preview-card {
47038
+ overflow: hidden;
47039
+ border: 1px solid rgb(var(--tb-border));
47040
+ border-radius: calc(var(--rb-block-radius, 0.75rem) * 1.75);
47041
+ background: rgb(var(--tb-accent-200));
47042
+ color: rgb(var(--tb-onAccent200));
47043
+ --rb-surface-text-color: rgb(var(--tb-onAccent200));
47044
+ --rb-surface-heading-color: rgb(var(--tb-onAccent200));
47045
+ --rb-surface-link-color: rgb(var(--tb-onAccent200));
47046
+ --rb-surface-supporting-color: rgb(var(--tb-onAccent200));
47047
+ }
47048
+
47049
+ :where(.theme-scope)
47050
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47051
+ .offerings-preview-card:first-child {
47052
+ border-color: transparent;
47053
+ background: rgb(var(--tb-primary-950));
47054
+ color: rgb(var(--tb-onPrimary950));
47055
+ box-shadow: 0.55rem 0.55rem 0 rgb(var(--tb-secondary-100));
47056
+ --rb-surface-text-color: rgb(var(--tb-onPrimary950));
47057
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary950));
47058
+ --rb-surface-link-color: rgb(var(--tb-onPrimary950));
47059
+ --rb-surface-supporting-color: rgb(var(--tb-onPrimary950));
47060
+ }
47061
+
47062
+ :where(.theme-scope)
47063
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47064
+ .offerings-preview-card:first-child
47065
+ .offerings-preview-card-title {
47066
+ color: rgb(var(--tb-primary-200));
47067
+ }
47068
+
47069
+ @container rb-offerings-preview (min-width: 52rem) {
47070
+ :where(.theme-scope)
47071
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47072
+ .offerings-preview-grid:has(> .offerings-preview-card:nth-child(2):last-child) {
47073
+ grid-template-columns: minmax(0, 1.22fr) minmax(18rem, 0.78fr) !important;
47074
+ }
47075
+ }
47076
+
47077
+ /* Open editorial columns: composition and hierarchy without an item fill. */
47078
+ :where(.theme-scope)
47079
+ [data-block="offerings-preview"][data-block-look="offerings-preview-open-editorial-columns"]
47080
+ .offerings-preview-grid {
47081
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)) !important;
47082
+ gap: 0;
47083
+ border-block: 1px solid rgb(var(--tb-border));
47084
+ }
47085
+
47086
+ :where(.theme-scope)
47087
+ [data-block="offerings-preview"][data-block-look="offerings-preview-open-editorial-columns"]
47088
+ .offerings-preview-card {
47089
+ border: 0;
47090
+ border-radius: 0;
47091
+ background: transparent;
47092
+ color: var(--rb-surface-text-color, rgb(var(--tb-text)));
47093
+ }
47094
+
47095
+ :where(.theme-scope)
47096
+ [data-block="offerings-preview"][data-block-look="offerings-preview-open-editorial-columns"]
47097
+ .offerings-preview-card + .offerings-preview-card {
47098
+ border-top: 1px solid rgb(var(--tb-border));
47099
+ }
47100
+
47101
+ @container rb-offerings-preview (min-width: 46rem) {
47102
+ :where(.theme-scope)
47103
+ [data-block="offerings-preview"][data-block-look="offerings-preview-open-editorial-columns"]
47104
+ .offerings-preview-card + .offerings-preview-card {
47105
+ border-top: 0;
47106
+ border-left: 1px solid rgb(var(--tb-border));
47107
+ }
47108
+ }
47109
+
47110
+ /* Joined programme panel: every group remains independently editable but the
47111
+ * close-set bands read as one upcoming programme. */
47112
+ :where(.theme-scope)
47113
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47114
+ .offerings-preview {
47115
+ overflow: hidden;
47116
+ gap: 0;
47117
+ border: 1px solid rgb(var(--tb-border));
47118
+ border-radius: calc(var(--rb-block-radius, 0.75rem) * 1.75);
47119
+ background: rgb(var(--tb-surface));
47120
+ }
47121
+
47122
+ :where(.theme-scope)
47123
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47124
+ .offerings-preview-grid {
47125
+ grid-template-columns: minmax(0, 1fr) !important;
47126
+ gap: 0;
47127
+ }
47128
+
47129
+ :where(.theme-scope)
47130
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47131
+ .offerings-preview-card {
47132
+ border: 0;
47133
+ border-radius: 0;
47134
+ background: rgb(var(--tb-secondary-100));
47135
+ color: rgb(var(--tb-onSecondary100));
47136
+ --rb-surface-text-color: rgb(var(--tb-onSecondary100));
47137
+ --rb-surface-heading-color: rgb(var(--tb-onSecondary100));
47138
+ --rb-surface-link-color: rgb(var(--tb-onSecondary100));
47139
+ --rb-surface-supporting-color: rgb(var(--tb-onSecondary100));
47140
+ }
47141
+
47142
+ :where(.theme-scope)
47143
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47144
+ .offerings-preview-card:nth-child(2) {
47145
+ background: rgb(var(--tb-accent-200));
47146
+ color: rgb(var(--tb-onAccent200));
47147
+ --rb-surface-text-color: rgb(var(--tb-onAccent200));
47148
+ --rb-surface-heading-color: rgb(var(--tb-onAccent200));
47149
+ --rb-surface-link-color: rgb(var(--tb-onAccent200));
47150
+ --rb-surface-supporting-color: rgb(var(--tb-onAccent200));
47151
+ }
47152
+
47153
+ :where(.theme-scope)
47154
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47155
+ .offerings-preview-card:nth-child(3) {
47156
+ background: rgb(var(--tb-primary-100));
47157
+ color: rgb(var(--tb-onPrimary100));
47158
+ --rb-surface-text-color: rgb(var(--tb-onPrimary100));
47159
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary100));
47160
+ --rb-surface-link-color: rgb(var(--tb-onPrimary100));
47161
+ --rb-surface-supporting-color: rgb(var(--tb-onPrimary100));
47162
+ }
47163
+
47164
+ :where(.theme-scope)
47165
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47166
+ .offerings-preview-card + .offerings-preview-card {
47167
+ border-top: 1px solid rgb(var(--tb-border));
47168
+ }
47169
+
47170
+ @container rb-offerings-preview (min-width: 58rem) {
47171
+ :where(.theme-scope)
47172
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47173
+ .offerings-preview-card-content {
47174
+ display: grid;
47175
+ grid-template-columns: minmax(15rem, 1.1fr) minmax(19rem, 1.4fr) minmax(10rem, auto);
47176
+ align-items: center;
47177
+ gap: clamp(1.5rem, 4vw, 4rem);
47178
+ }
47179
+
47180
+ :where(.theme-scope)
47181
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47182
+ .offerings-preview-card-footer {
47183
+ margin-top: 0;
47184
+ padding-top: 0;
47185
+ justify-content: flex-end;
47186
+ }
47187
+ }
47188
+
47189
+ /* =============================================================================
47190
+ * Featured-editorial testimonial Looks promoted from the Fran André treatment
47191
+ * study. These rules do not set the outer section background.
47192
+ * ============================================================================= */
47193
+
47194
+ :where(.theme-scope)
47195
+ [data-block="testimonials"]:is(
47196
+ [data-block-look="testimonials-evergreen-lead"],
47197
+ [data-block-look="testimonials-room-and-response"],
47198
+ [data-block-look="testimonials-open-floor"]
47199
+ )
47200
+ .rb-testimonials-fe-card--feature {
47201
+ background: rgb(var(--tb-secondary-900));
47202
+ color: rgb(var(--tb-onSecondary900));
47203
+ --rb-surface-text-color: rgb(var(--tb-onSecondary900));
47204
+ --rb-surface-heading-color: rgb(var(--tb-onSecondary900));
47205
+ --rb-surface-link-color: rgb(var(--tb-onSecondary900));
47206
+ --rb-surface-supporting-color: rgb(var(--tb-onSecondary900));
47207
+ }
47208
+
47209
+ :where(.theme-scope)
47210
+ [data-block="testimonials"]:is(
47211
+ [data-block-look="testimonials-evergreen-lead"],
47212
+ [data-block-look="testimonials-room-and-response"],
47213
+ [data-block-look="testimonials-open-floor"]
47214
+ )
47215
+ .rb-testimonials-fe-card--feature
47216
+ .rb-testimonials-fe-qmark {
47217
+ color: rgb(var(--tb-primary-200));
47218
+ }
47219
+
47220
+ :where(.theme-scope)
47221
+ [data-block="testimonials"]:is(
47222
+ [data-block-look="testimonials-evergreen-lead"],
47223
+ [data-block-look="testimonials-room-and-response"],
47224
+ [data-block-look="testimonials-open-floor"]
47225
+ )
47226
+ .rb-testimonials-fe-card--feature
47227
+ :is(.rb-testimonials-fe-quote p, .rb-testimonials-fe-name, .rb-testimonials-fe-context) {
47228
+ color: rgb(var(--tb-onSecondary900));
47229
+ }
47230
+
47231
+ /* Evergreen lead: the feature remains dominant while the supporting column
47232
+ * opens into two equal compact voices at wider widths. */
47233
+ @container rb-testimonials-fe (min-width: 1024px) {
47234
+ :where(.theme-scope)
47235
+ [data-block="testimonials"][data-block-look="testimonials-evergreen-lead"]
47236
+ .rb-testimonials-fe-grid {
47237
+ grid-template-columns: minmax(0, 1.15fr) minmax(0, 1.55fr);
47238
+ }
47239
+
47240
+ :where(.theme-scope)
47241
+ [data-block="testimonials"][data-block-look="testimonials-evergreen-lead"]
47242
+ .rb-testimonials-fe-col {
47243
+ grid-template-columns: repeat(2, minmax(0, 1fr));
47244
+ }
47245
+ }
47246
+
47247
+ /* Room and response: a tall lead voice with one soft brand response and one
47248
+ * neutral response in the existing stacked support column. */
47249
+ :where(.theme-scope)
47250
+ [data-block="testimonials"][data-block-look="testimonials-room-and-response"]
47251
+ .rb-testimonials-fe-card--feature {
47252
+ min-height: 27rem;
47253
+ }
47254
+
47255
+ :where(.theme-scope)
47256
+ [data-block="testimonials"][data-block-look="testimonials-room-and-response"]
47257
+ .rb-testimonials-fe-col
47258
+ .rb-testimonials-fe-card:first-child {
47259
+ border-color: transparent;
47260
+ background: rgb(var(--tb-primary-100));
47261
+ color: rgb(var(--tb-onPrimary100));
47262
+ --rb-surface-text-color: rgb(var(--tb-onPrimary100));
47263
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary100));
47264
+ --rb-surface-link-color: rgb(var(--tb-onPrimary100));
47265
+ --rb-surface-supporting-color: rgb(var(--tb-onPrimary100));
47266
+ }
47267
+
47268
+ :where(.theme-scope)
47269
+ [data-block="testimonials"][data-block-look="testimonials-room-and-response"]
47270
+ .rb-testimonials-fe-col
47271
+ .rb-testimonials-fe-card:first-child
47272
+ :is(.rb-testimonials-fe-quote p, .rb-testimonials-fe-name, .rb-testimonials-fe-context) {
47273
+ color: rgb(var(--tb-onPrimary100));
47274
+ }
47275
+
47276
+ /* Open floor: the section head becomes an editorial rail while proof occupies
47277
+ * a feature-over-supporting field. */
47278
+ @container rb-testimonials-fe (min-width: 1024px) {
47279
+ :where(.theme-scope)
47280
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47281
+ .rb-testimonials-fe {
47282
+ display: grid;
47283
+ grid-template-columns: minmax(15rem, 0.72fr) minmax(0, 1.6fr);
47284
+ align-items: start;
47285
+ gap: clamp(2rem, 5vw, 5rem);
47286
+ }
47287
+
47288
+ :where(.theme-scope)
47289
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47290
+ .rb-testimonials-fe-head {
47291
+ display: block;
47292
+ }
47293
+
47294
+ :where(.theme-scope)
47295
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47296
+ .rb-testimonials-fe-leadin {
47297
+ margin-top: 1.5rem;
47298
+ }
47299
+
47300
+ :where(.theme-scope)
47301
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47302
+ .rb-testimonials-fe-grid {
47303
+ grid-template-columns: minmax(0, 1fr);
47304
+ }
47305
+
47306
+ :where(.theme-scope)
47307
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47308
+ .rb-testimonials-fe-col {
47309
+ grid-template-columns: repeat(2, minmax(0, 1fr));
47310
+ }
45682
47311
  }`;
45683
47312
  //#endregion
45684
47313
  //#region ../theme-core/src/ThemeScopeCore.tsx
@@ -45843,6 +47472,103 @@ function ThemeScope({ theme, children, themeId = "theme-default", responsiveMode
45843
47472
  });
45844
47473
  }
45845
47474
  //#endregion
47475
+ //#region ../theme-core/src/fonts/types.ts
47476
+ /**
47477
+ * Shared types for custom site fonts
47478
+ *
47479
+ * Used by:
47480
+ * - packages/blocks: ThemeFontLoader
47481
+ * - apps/dashboard: Font settings
47482
+ * - apps/frontend: Font loading
47483
+ */
47484
+ /**
47485
+ * The Supabase storage bucket name for site fonts
47486
+ */
47487
+ const SITE_FONTS_BUCKET = "site-fonts";
47488
+ /**
47489
+ * Construct the storage base URL for site fonts
47490
+ *
47491
+ * @param supabaseUrl - The Supabase project URL (e.g., https://xxx.supabase.co)
47492
+ * @returns The full storage URL for the site-fonts bucket
47493
+ *
47494
+ * @example
47495
+ * ```ts
47496
+ * const storageUrl = getSiteFontsStorageUrl('https://xxx.supabase.co')
47497
+ * // Returns: 'https://xxx.supabase.co/storage/v1/object/public/site-fonts'
47498
+ * ```
47499
+ */
47500
+ function getSiteFontsStorageUrl(supabaseUrl) {
47501
+ return `${supabaseUrl}/storage/v1/object/public/${SITE_FONTS_BUCKET}`;
47502
+ }
47503
+ /**
47504
+ * Build a lightweight Google Fonts stylesheet URL for a family-name preview.
47505
+ * The text subset keeps catalog rows cheap while still rendering the name in
47506
+ * the typeface being chosen.
47507
+ */
47508
+ function buildFontPreviewUrl(family) {
47509
+ return `https://fonts.googleapis.com/css2?family=${encodeURIComponent(family).replace(/%20/gu, "+")}&display=swap&text=${encodeURIComponent(family)}`;
47510
+ }
47511
+ /**
47512
+ * Escape a string for use in CSS font-family declaration
47513
+ * Escapes quotes, backslashes, and newlines
47514
+ */
47515
+ function escapeCssFontFamily(name) {
47516
+ return name.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
47517
+ }
47518
+ /**
47519
+ * Encode storage path segments for use in URLs
47520
+ * Encodes each path segment individually to handle special characters
47521
+ */
47522
+ function encodeStoragePath(storagePath) {
47523
+ return storagePath.split("/").map((segment) => encodeURIComponent(segment)).join("/");
47524
+ }
47525
+ /**
47526
+ * Generate @font-face CSS for a single font file
47527
+ */
47528
+ function generateFontFaceForFile(familyName, file, storageBaseUrl) {
47529
+ return `@font-face {
47530
+ font-family: '${escapeCssFontFamily(familyName)}';
47531
+ src: url('${`${storageBaseUrl}/${encodeStoragePath(file.storagePath)}`}') format('woff2');
47532
+ font-weight: ${file.weight};
47533
+ font-style: ${file.style};
47534
+ font-display: swap;
47535
+ }`;
47536
+ }
47537
+ /**
47538
+ * Generate @font-face CSS for a variable font
47539
+ */
47540
+ function generateFontFaceForVariableFont(familyName, file, weightMin, weightMax, storageBaseUrl) {
47541
+ return `@font-face {
47542
+ font-family: '${escapeCssFontFamily(familyName)}';
47543
+ src: url('${`${storageBaseUrl}/${encodeStoragePath(file.storagePath)}`}') format('woff2');
47544
+ font-weight: ${weightMin} ${weightMax};
47545
+ font-style: ${file.style};
47546
+ font-display: swap;
47547
+ }`;
47548
+ }
47549
+ /**
47550
+ * Generate all @font-face rules for custom fonts
47551
+ *
47552
+ * @param fonts - Array of custom fonts
47553
+ * @param storageBaseUrl - Base URL for storage (e.g., https://xxx.supabase.co/storage/v1/object/public/site-fonts)
47554
+ * @returns CSS string with all @font-face rules
47555
+ */
47556
+ function generateFontFaceCss(fonts, storageBaseUrl) {
47557
+ const rules = [];
47558
+ const seenFamilies = /* @__PURE__ */ new Set();
47559
+ for (const font of fonts) {
47560
+ if (seenFamilies.has(font.familyName)) continue;
47561
+ seenFamilies.add(font.familyName);
47562
+ if (font.isVariable && font.variableWeightMin && font.variableWeightMax) {
47563
+ const normalFile = font.files.find((f) => f.style === "normal");
47564
+ const italicFile = font.files.find((f) => f.style === "italic");
47565
+ if (normalFile) rules.push(generateFontFaceForVariableFont(font.familyName, normalFile, font.variableWeightMin, font.variableWeightMax, storageBaseUrl));
47566
+ if (italicFile) rules.push(generateFontFaceForVariableFont(font.familyName, italicFile, font.variableWeightMin, font.variableWeightMax, storageBaseUrl));
47567
+ } else for (const file of font.files) rules.push(generateFontFaceForFile(font.familyName, file, storageBaseUrl));
47568
+ }
47569
+ return rules.join("\n\n");
47570
+ }
47571
+ //#endregion
45846
47572
  //#region ../theme-core/src/ResponsiveScope.tsx
45847
47573
  /**
45848
47574
  * Structural responsive root for SDK/runtime chrome that opts out of CMS theme
@@ -46462,7 +48188,7 @@ function normalizeLoaderParams(endpoint, params, context) {
46462
48188
  ensureSiteId(out, context);
46463
48189
  return out;
46464
48190
  }
46465
- if (endpoint === "listPublicEvents") {
48191
+ if (endpoint === "listPublicEvents" || endpoint === "listPublicRecurringSchedule") {
46466
48192
  ensureSiteId(out, context);
46467
48193
  return out;
46468
48194
  }
@@ -53960,7 +55686,7 @@ async function resolveVideoPosterReference(picked, context) {
53960
55686
  }
53961
55687
  //#endregion
53962
55688
  //#region ../media-storage-supabase/dist/index.mjs
53963
- function ok$1(value) {
55689
+ function ok(value) {
53964
55690
  return {
53965
55691
  ok: true,
53966
55692
  value
@@ -53981,7 +55707,7 @@ const unsafeAsBookingRequirementId = (id) => id;
53981
55707
  function fromArray(items) {
53982
55708
  const [first, ...rest] = items;
53983
55709
  if (first === void 0) return err("empty_array");
53984
- return ok$1([first, ...rest]);
55710
+ return ok([first, ...rest]);
53985
55711
  }
53986
55712
  /**
53987
55713
  * Narrow nullable values to the present value.
@@ -54088,8 +55814,48 @@ const ACCESS_POLICY_TAGS = [
54088
55814
  ];
54089
55815
  function asPositiveSeconds(value) {
54090
55816
  if (!Number.isSafeInteger(value) || value <= 0) return err("not-positive-seconds");
55817
+ return ok(value);
55818
+ }
55819
+ function ok$1(value) {
55820
+ return {
55821
+ ok: true,
55822
+ value
55823
+ };
55824
+ }
55825
+ function fail(error) {
55826
+ return {
55827
+ ok: false,
55828
+ error
55829
+ };
55830
+ }
55831
+ function normalizeStringInput(value) {
55832
+ if (typeof value !== "string") return fail({ tag: "MISSING" });
55833
+ const trimmed = value.trim();
55834
+ if (!trimmed) return fail({ tag: "EMPTY" });
55835
+ return ok$1(trimmed);
55836
+ }
55837
+ function validateRelativeStoragePath(value) {
55838
+ if (value.startsWith("sites/")) return fail({ tag: "SITE_SCOPED_PATH" });
55839
+ if (value.startsWith("/")) return fail({ tag: "LEADING_SLASH" });
55840
+ if (value.includes("//")) return fail({ tag: "DOUBLE_SLASH" });
55841
+ if (value.split("/").some((segment) => segment === "..")) return fail({ tag: "TRAVERSAL" });
54091
55842
  return ok$1(value);
54092
55843
  }
55844
+ function brandRelativeStoragePath(value) {
55845
+ return value;
55846
+ }
55847
+ function parseRelativeStoragePath(value) {
55848
+ const normalized = normalizeStringInput(value);
55849
+ if (!normalized.ok) return normalized;
55850
+ const validated = validateRelativeStoragePath(normalized.value);
55851
+ if (!validated.ok) return validated;
55852
+ return ok$1(brandRelativeStoragePath(validated.value));
55853
+ }
55854
+ function assertRelativeStoragePath(value) {
55855
+ const parsed = parseRelativeStoragePath(value);
55856
+ if (!parsed.ok) throw new Error(`Expected RelativeStoragePath, got ${parsed.error.tag}`);
55857
+ return parsed.value;
55858
+ }
54093
55859
  function isRecord$12(value) {
54094
55860
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
54095
55861
  }
@@ -54105,7 +55871,7 @@ function parseFileKindJson(value) {
54105
55871
  if (!family.ok || family.value !== "raster") return err("invalid-field");
54106
55872
  const format = parseOneOf(record.format, IMAGE_FILE_FORMATS);
54107
55873
  if (!format.ok) return format;
54108
- return ok$1({
55874
+ return ok({
54109
55875
  tag: "image",
54110
55876
  family: "raster",
54111
55877
  format: format.value
@@ -54114,7 +55880,7 @@ function parseFileKindJson(value) {
54114
55880
  case "video": {
54115
55881
  const format = parseOneOf(record.format, VIDEO_FILE_FORMATS);
54116
55882
  if (!format.ok) return format;
54117
- return ok$1({
55883
+ return ok({
54118
55884
  tag: "video",
54119
55885
  format: format.value
54120
55886
  });
@@ -54122,7 +55888,7 @@ function parseFileKindJson(value) {
54122
55888
  case "audio": {
54123
55889
  const format = parseOneOf(record.format, AUDIO_FILE_FORMATS);
54124
55890
  if (!format.ok) return format;
54125
- return ok$1({
55891
+ return ok({
54126
55892
  tag: "audio",
54127
55893
  format: format.value
54128
55894
  });
@@ -54130,7 +55896,7 @@ function parseFileKindJson(value) {
54130
55896
  case "document": {
54131
55897
  const format = parseOneOf(record.format, DOCUMENT_FILE_FORMATS);
54132
55898
  if (!format.ok) return format;
54133
- return ok$1({
55899
+ return ok({
54134
55900
  tag: "document",
54135
55901
  format: format.value
54136
55902
  });
@@ -54138,7 +55904,7 @@ function parseFileKindJson(value) {
54138
55904
  case "spreadsheet": {
54139
55905
  const format = parseOneOf(record.format, SPREADSHEET_FILE_FORMATS);
54140
55906
  if (!format.ok) return format;
54141
- return ok$1({
55907
+ return ok({
54142
55908
  tag: "spreadsheet",
54143
55909
  format: format.value
54144
55910
  });
@@ -54146,7 +55912,7 @@ function parseFileKindJson(value) {
54146
55912
  case "font": {
54147
55913
  const format = parseOneOf(record.format, FONT_FILE_FORMATS);
54148
55914
  if (!format.ok) return format;
54149
- return ok$1({
55915
+ return ok({
54150
55916
  tag: "font",
54151
55917
  format: format.value
54152
55918
  });
@@ -54154,7 +55920,7 @@ function parseFileKindJson(value) {
54154
55920
  case "archive": {
54155
55921
  const format = parseOneOf(record.format, ARCHIVE_FILE_FORMATS);
54156
55922
  if (!format.ok) return format;
54157
- return ok$1({
55923
+ return ok({
54158
55924
  tag: "archive",
54159
55925
  format: format.value
54160
55926
  });
@@ -54171,16 +55937,16 @@ function parseFileUseJson(value) {
54171
55937
  case "media-library": {
54172
55938
  const renderUse = parseOneOf(record.renderUse, RENDERABLE_FILE_KIND_TAGS);
54173
55939
  if (!renderUse.ok) return renderUse;
54174
- return ok$1({
55940
+ return ok({
54175
55941
  tag: "media-library",
54176
55942
  renderUse: renderUse.value
54177
55943
  });
54178
55944
  }
54179
- case "content-download": return ok$1({ tag: "content-download" });
55945
+ case "content-download": return ok({ tag: "content-download" });
54180
55946
  case "digital-product-file": {
54181
55947
  const fulfillmentVisibility = requireString(record.fulfillmentVisibility);
54182
55948
  if (!fulfillmentVisibility.ok || fulfillmentVisibility.value !== "entitled-customer") return err("invalid-field");
54183
- return ok$1({
55949
+ return ok({
54184
55950
  tag: "digital-product-file",
54185
55951
  fulfillmentVisibility: "entitled-customer"
54186
55952
  });
@@ -54188,7 +55954,7 @@ function parseFileUseJson(value) {
54188
55954
  case "workflow-input": {
54189
55955
  const workflowKind = parseOneOf(record.workflowKind, WORKFLOW_INPUT_KINDS);
54190
55956
  if (!workflowKind.ok) return workflowKind;
54191
- return ok$1({
55957
+ return ok({
54192
55958
  tag: "workflow-input",
54193
55959
  workflowKind: workflowKind.value
54194
55960
  });
@@ -54196,7 +55962,7 @@ function parseFileUseJson(value) {
54196
55962
  case "booking-evidence": {
54197
55963
  const requirementId = requireNonEmptyString(record.requirementId);
54198
55964
  if (!requirementId.ok) return requirementId;
54199
- return ok$1({
55965
+ return ok({
54200
55966
  tag: "booking-evidence",
54201
55967
  requirementId: unsafeAsBookingRequirementId(requirementId.value)
54202
55968
  });
@@ -54204,7 +55970,7 @@ function parseFileUseJson(value) {
54204
55970
  case "site-brand-asset": {
54205
55971
  const brandUse = parseOneOf(record.brandUse, SITE_BRAND_ASSET_USES);
54206
55972
  if (!brandUse.ok) return brandUse;
54207
- return ok$1({
55973
+ return ok({
54208
55974
  tag: "site-brand-asset",
54209
55975
  brandUse: brandUse.value
54210
55976
  });
@@ -54212,7 +55978,7 @@ function parseFileUseJson(value) {
54212
55978
  case "site-background-asset": {
54213
55979
  const backgroundUse = parseOneOf(record.backgroundUse, SITE_BACKGROUND_ASSET_USES);
54214
55980
  if (!backgroundUse.ok) return backgroundUse;
54215
- return ok$1({
55981
+ return ok({
54216
55982
  tag: "site-background-asset",
54217
55983
  backgroundUse: backgroundUse.value
54218
55984
  });
@@ -54220,7 +55986,7 @@ function parseFileUseJson(value) {
54220
55986
  case "site-font-file": {
54221
55987
  const fontId = requireNonEmptyString(record.fontId);
54222
55988
  if (!fontId.ok) return fontId;
54223
- return ok$1({
55989
+ return ok({
54224
55990
  tag: "site-font-file",
54225
55991
  fontId: unsafeAsSiteFontId(fontId.value)
54226
55992
  });
@@ -54228,7 +55994,7 @@ function parseFileUseJson(value) {
54228
55994
  case "temporary-ingestion": {
54229
55995
  const ingestionKind = parseOneOf(record.ingestionKind, TEMPORARY_INGESTION_KINDS);
54230
55996
  if (!ingestionKind.ok) return ingestionKind;
54231
- return ok$1({
55997
+ return ok({
54232
55998
  tag: "temporary-ingestion",
54233
55999
  ingestionKind: ingestionKind.value
54234
56000
  });
@@ -54241,7 +56007,7 @@ function parseFileUsesJson(value) {
54241
56007
  if (!parsed.ok) return parsed;
54242
56008
  const nonEmpty = fromArray(parsed.value);
54243
56009
  if (!nonEmpty.ok) return err("expected-non-empty-array");
54244
- return ok$1(nonEmpty.value);
56010
+ return ok(nonEmpty.value);
54245
56011
  }
54246
56012
  function parseAccessPolicyJson(value) {
54247
56013
  const recordResult = requireRecord(value);
@@ -54250,11 +56016,11 @@ function parseAccessPolicyJson(value) {
54250
56016
  const tag = parseTag(record.tag, ACCESS_POLICY_TAGS);
54251
56017
  if (!tag.ok) return tag;
54252
56018
  switch (tag.value) {
54253
- case "public-read": return ok$1({ tag: "public-read" });
56019
+ case "public-read": return ok({ tag: "public-read" });
54254
56020
  case "site-editor-read": {
54255
56021
  const siteId = requireNonEmptyString(record.siteId);
54256
56022
  if (!siteId.ok) return siteId;
54257
- return ok$1({
56023
+ return ok({
54258
56024
  tag: "site-editor-read",
54259
56025
  siteId: unsafeAsSiteId(siteId.value)
54260
56026
  });
@@ -54262,7 +56028,7 @@ function parseAccessPolicyJson(value) {
54262
56028
  case "signed-public-render": {
54263
56029
  const expiresInSeconds = parsePositiveSeconds$1(record.expiresInSeconds);
54264
56030
  if (!expiresInSeconds.ok) return expiresInSeconds;
54265
- return ok$1({
56031
+ return ok({
54266
56032
  tag: "signed-public-render",
54267
56033
  expiresInSeconds: expiresInSeconds.value
54268
56034
  });
@@ -54272,7 +56038,7 @@ function parseAccessPolicyJson(value) {
54272
56038
  if (!scope.ok) return scope;
54273
56039
  const expiresInSeconds = parseOptionalPositiveSeconds(record.expiresInSeconds);
54274
56040
  if (!expiresInSeconds.ok) return expiresInSeconds;
54275
- return ok$1({
56041
+ return ok({
54276
56042
  tag: "entitled-customer-read",
54277
56043
  scope: scope.value,
54278
56044
  ...expiresInSeconds.value !== void 0 ? { expiresInSeconds: expiresInSeconds.value } : {}
@@ -54283,13 +56049,13 @@ function parseAccessPolicyJson(value) {
54283
56049
  if (!sessionId.ok) return sessionId;
54284
56050
  const expiresInSeconds = parseOptionalPositiveSeconds(record.expiresInSeconds);
54285
56051
  if (!expiresInSeconds.ok) return expiresInSeconds;
54286
- return ok$1({
56052
+ return ok({
54287
56053
  tag: "booking-session-read",
54288
56054
  sessionId: unsafeAsBookingSessionId(sessionId.value),
54289
56055
  ...expiresInSeconds.value !== void 0 ? { expiresInSeconds: expiresInSeconds.value } : {}
54290
56056
  });
54291
56057
  }
54292
- case "management-api-read": return ok$1({ tag: "management-api-read" });
56058
+ case "management-api-read": return ok({ tag: "management-api-read" });
54293
56059
  }
54294
56060
  }
54295
56061
  function parseEntitledCustomerAccessScopeJson(value) {
@@ -54299,11 +56065,11 @@ function parseEntitledCustomerAccessScopeJson(value) {
54299
56065
  const tag = parseTag(record.tag, ["any-entitled-customer", "specific-entitlement"]);
54300
56066
  if (!tag.ok) return tag;
54301
56067
  switch (tag.value) {
54302
- case "any-entitled-customer": return ok$1({ tag: "any-entitled-customer" });
56068
+ case "any-entitled-customer": return ok({ tag: "any-entitled-customer" });
54303
56069
  case "specific-entitlement": {
54304
56070
  const entitlementId = requireNonEmptyString(record.entitlementId);
54305
56071
  if (!entitlementId.ok) return entitlementId;
54306
- return ok$1({
56072
+ return ok({
54307
56073
  tag: "specific-entitlement",
54308
56074
  entitlementId: unsafeAsEntitlementId(entitlementId.value)
54309
56075
  });
@@ -54312,18 +56078,18 @@ function parseEntitledCustomerAccessScopeJson(value) {
54312
56078
  }
54313
56079
  function requireRecord(value) {
54314
56080
  if (!isRecord$12(value)) return err("expected-object");
54315
- return ok$1(value);
56081
+ return ok(value);
54316
56082
  }
54317
56083
  function requireString(value) {
54318
56084
  if (typeof value !== "string") return err("invalid-string");
54319
- return ok$1(value);
56085
+ return ok(value);
54320
56086
  }
54321
56087
  function requireNonEmptyString(value) {
54322
56088
  const string = requireString(value);
54323
56089
  if (!string.ok) return string;
54324
56090
  const trimmed = string.value.trim();
54325
56091
  if (!trimmed || trimmed !== string.value) return err("invalid-string");
54326
- return ok$1(string.value);
56092
+ return ok(string.value);
54327
56093
  }
54328
56094
  function parseOneOf(value, allowed) {
54329
56095
  return parseStringIn(value, allowed, "invalid-field");
@@ -54335,16 +56101,16 @@ function parseStringIn(value, allowed, outOfSetError) {
54335
56101
  const string = requireString(value);
54336
56102
  if (!string.ok) return string;
54337
56103
  if (!isOneOf(string.value, allowed)) return err(outOfSetError);
54338
- return ok$1(string.value);
56104
+ return ok(string.value);
54339
56105
  }
54340
56106
  function parsePositiveSeconds$1(value) {
54341
56107
  if (typeof value !== "number") return err("invalid-number");
54342
56108
  const parsed = asPositiveSeconds(value);
54343
56109
  if (!parsed.ok) return err("invalid-positive-seconds");
54344
- return ok$1(parsed.value);
56110
+ return ok(parsed.value);
54345
56111
  }
54346
56112
  function parseOptionalPositiveSeconds(value) {
54347
- if (value === void 0 || value === null) return ok$1(void 0);
56113
+ if (value === void 0 || value === null) return ok(void 0);
54348
56114
  return parsePositiveSeconds$1(value);
54349
56115
  }
54350
56116
  function traverse(items, parse) {
@@ -54354,7 +56120,7 @@ function traverse(items, parse) {
54354
56120
  if (!parsed.ok) return parsed;
54355
56121
  values.push(parsed.value);
54356
56122
  }
54357
- return ok$1(values);
56123
+ return ok(values);
54358
56124
  }
54359
56125
  function isOneOf(value, allowed) {
54360
56126
  return allowed.includes(value);
@@ -54387,46 +56153,6 @@ var MediaStorageError = class extends Error {
54387
56153
  this.cause = options.cause;
54388
56154
  }
54389
56155
  };
54390
- function ok(value) {
54391
- return {
54392
- ok: true,
54393
- value
54394
- };
54395
- }
54396
- function fail(error) {
54397
- return {
54398
- ok: false,
54399
- error
54400
- };
54401
- }
54402
- function normalizeStringInput(value) {
54403
- if (typeof value !== "string") return fail({ tag: "MISSING" });
54404
- const trimmed = value.trim();
54405
- if (!trimmed) return fail({ tag: "EMPTY" });
54406
- return ok(trimmed);
54407
- }
54408
- function validateRelativeStoragePath(value) {
54409
- if (value.startsWith("sites/")) return fail({ tag: "SITE_SCOPED_PATH" });
54410
- if (value.startsWith("/")) return fail({ tag: "LEADING_SLASH" });
54411
- if (value.includes("//")) return fail({ tag: "DOUBLE_SLASH" });
54412
- if (value.includes("..")) return fail({ tag: "TRAVERSAL" });
54413
- return ok(value);
54414
- }
54415
- function brandRelativeStoragePath(value) {
54416
- return value;
54417
- }
54418
- function parseRelativeStoragePath(value) {
54419
- const normalized = normalizeStringInput(value);
54420
- if (!normalized.ok) return normalized;
54421
- const validated = validateRelativeStoragePath(normalized.value);
54422
- if (!validated.ok) return validated;
54423
- return ok(brandRelativeStoragePath(validated.value));
54424
- }
54425
- function assertRelativeStoragePath(value) {
54426
- const parsed = parseRelativeStoragePath(value);
54427
- if (!parsed.ok) throw new Error(`Expected RelativeStoragePath, got ${parsed.error.tag}`);
54428
- return parsed.value;
54429
- }
54430
56156
  const pad = (value) => value.toString().padStart(2, "0");
54431
56157
  const extractExtension = (filename) => {
54432
56158
  if (!hasText(filename)) return "";
@@ -57106,21 +58832,32 @@ function stripTopLevelRoutingUi(field) {
57106
58832
  //#region ../editor-blocks/src/block-editor/preparedManifest.ts
57107
58833
  const showRawStyleFields = { kind: "show-raw-style-fields" };
57108
58834
  const hideThemeV2RawStyleFields = { kind: "hide-theme-v2-raw-style-fields" };
58835
+ const EDITOR_OWNED_FEATURE_CARD_FIELD_IDS = /* @__PURE__ */ new Set(["_generatedIconSizePx"]);
58836
+ function hideEditorOwnedFields(manifest, blockKind) {
58837
+ if (blockKind !== "block.feature-cards") return manifest;
58838
+ return {
58839
+ ...manifest,
58840
+ fields: manifest.fields?.map((field) => EDITOR_OWNED_FEATURE_CARD_FIELD_IDS.has(field.id) ? {
58841
+ ...field,
58842
+ ui: {
58843
+ ...field.ui ?? {},
58844
+ hidden: true
58845
+ }
58846
+ } : field),
58847
+ promotedFields: manifest.promotedFields?.filter((fieldPath) => !EDITOR_OWNED_FEATURE_CARD_FIELD_IDS.has(fieldPath))
58848
+ };
58849
+ }
57109
58850
  function prepareBlockEditorManifest(input) {
57110
58851
  const mergedManifest = mergeManifestWithSdkOptions(input.manifest, input.blockKind, input.blockFieldOptions, input.blockFieldExtensions);
57111
58852
  const validationManifest = augmentManifestWithStyleGroups(mergedManifest, input.styleGroups, input.blockKind);
57112
58853
  const renderManifestBase = input.visibilityPolicy.kind === "hide-theme-v2-raw-style-fields" ? mergedManifest : validationManifest;
57113
- if (input.visibilityPolicy.kind !== "hide-theme-v2-raw-style-fields") return {
57114
- validationManifest,
57115
- renderManifest: validationManifest
57116
- };
57117
58854
  return {
57118
58855
  validationManifest,
57119
- renderManifest: {
58856
+ renderManifest: hideEditorOwnedFields(input.visibilityPolicy.kind === "hide-theme-v2-raw-style-fields" ? {
57120
58857
  ...renderManifestBase,
57121
58858
  fields: renderManifestBase.fields ? hideThemeV2NormalEditorRawStyleFieldsInRenderFields(renderManifestBase.fields) : renderManifestBase.fields,
57122
58859
  promotedFields: filterThemeV2NormalEditorRawPromotedFields(renderManifestBase.promotedFields, input.allowedPromotedFieldPaths)
57123
- }
58860
+ } : validationManifest, input.blockKind)
57124
58861
  };
57125
58862
  }
57126
58863
  //#endregion
@@ -57567,7 +59304,7 @@ function formatGeneratedAt(value) {
57567
59304
  const date = new Date(value);
57568
59305
  return Number.isNaN(date.valueOf()) ? "Previously generated" : new Intl.DateTimeFormat(void 0, { dateStyle: "medium" }).format(date);
57569
59306
  }
57570
- function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary, styleGuideEditHref, onGenerate, onApply }) {
59307
+ function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary, styleGuideEditHref, generatedIconSizePx, onGeneratedIconSizeChange, hasStaleGeneratedIcons = false, onGenerate, onApply }) {
57571
59308
  const [state, dispatch] = useReducer(reducer, { kind: "idle" });
57572
59309
  const [styleNote, setStyleNote] = useState("");
57573
59310
  const [view, setView] = useState("create");
@@ -57635,6 +59372,15 @@ function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary,
57635
59372
  setView("create");
57636
59373
  }
57637
59374
  }
59375
+ function commitGeneratedIconSize(input) {
59376
+ if (generatedIconSizePx === void 0 || !onGeneratedIconSizeChange) return;
59377
+ const parsed = parseFeatureCardGeneratedIconSizePx(input.valueAsNumber);
59378
+ if (parsed.ok) {
59379
+ onGeneratedIconSizeChange(parsed.value);
59380
+ return;
59381
+ }
59382
+ input.value = String(generatedIconSizePx);
59383
+ }
57638
59384
  async function apply(preview) {
57639
59385
  if (!onApply) return;
57640
59386
  dispatch({
@@ -57666,7 +59412,7 @@ function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary,
57666
59412
  children: /* @__PURE__ */ jsxs(DialogContent, {
57667
59413
  className: "sm:max-w-2xl",
57668
59414
  children: [
57669
- /* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Choose icon set" }), /* @__PURE__ */ jsx(DialogDescription, { children: activePreview ? activePreview.styleGuideSummary : `${cards.length} cards` })] }),
59415
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Manage icons" }), /* @__PURE__ */ jsx(DialogDescription, { children: activePreview ? activePreview.styleGuideSummary : `${cards.length} cards` })] }),
57670
59416
  /* @__PURE__ */ jsxs("div", {
57671
59417
  className: "space-y-4",
57672
59418
  children: [
@@ -57693,6 +59439,51 @@ function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary,
57693
59439
  }), "Previously generated"]
57694
59440
  })]
57695
59441
  }),
59442
+ generatedIconSizePx !== void 0 && onGeneratedIconSizeChange ? /* @__PURE__ */ jsx(FieldFrame, {
59443
+ label: "Generated icon size",
59444
+ description: "Choose how large generated artwork appears. It will shrink to fit narrow cards.",
59445
+ children: ({ id, descriptionId }) => /* @__PURE__ */ jsxs("div", {
59446
+ className: "flex items-center gap-4",
59447
+ children: [/* @__PURE__ */ jsx(Slider, {
59448
+ value: [generatedIconSizePx],
59449
+ min: FEATURE_CARD_GENERATED_ICON_SIZE_PX.min,
59450
+ max: FEATURE_CARD_GENERATED_ICON_SIZE_PX.max,
59451
+ step: FEATURE_CARD_GENERATED_ICON_SIZE_PX.step,
59452
+ "aria-label": "Generated icon size in pixels",
59453
+ "aria-describedby": descriptionId || void 0,
59454
+ className: "flex-1",
59455
+ onValueChange: ([value]) => {
59456
+ if (value !== void 0) onGeneratedIconSizeChange(value);
59457
+ }
59458
+ }), /* @__PURE__ */ jsxs("div", {
59459
+ className: "flex w-24 shrink-0 items-center gap-1",
59460
+ children: [/* @__PURE__ */ jsx(Input, {
59461
+ id,
59462
+ type: "number",
59463
+ defaultValue: generatedIconSizePx,
59464
+ min: FEATURE_CARD_GENERATED_ICON_SIZE_PX.min,
59465
+ max: FEATURE_CARD_GENERATED_ICON_SIZE_PX.max,
59466
+ step: FEATURE_CARD_GENERATED_ICON_SIZE_PX.step,
59467
+ "aria-label": "Generated icon size in pixels",
59468
+ "aria-describedby": descriptionId || void 0,
59469
+ className: "h-8 px-2 text-right tabular-nums",
59470
+ onBlur: (event) => commitGeneratedIconSize(event.currentTarget),
59471
+ onKeyDown: (event) => {
59472
+ if (event.key !== "Enter") return;
59473
+ event.preventDefault();
59474
+ commitGeneratedIconSize(event.currentTarget);
59475
+ }
59476
+ }, generatedIconSizePx), /* @__PURE__ */ jsx("span", {
59477
+ className: "text-sm text-muted-foreground",
59478
+ children: "px"
59479
+ })]
59480
+ })]
59481
+ })
59482
+ }) : null,
59483
+ hasStaleGeneratedIcons ? /* @__PURE__ */ jsx(Callout, {
59484
+ tone: "warning",
59485
+ children: /* @__PURE__ */ jsx(CalloutDescription, { children: "Generated icons are out of date with the current icon style." })
59486
+ }) : null,
57696
59487
  state.kind === "failed" || state.kind === "apply_failed" ? /* @__PURE__ */ jsx("p", {
57697
59488
  role: "alert",
57698
59489
  className: "text-sm text-destructive",
@@ -58003,6 +59794,7 @@ function FeatureCardIconsPanel({ block, uiStore, currentStyleGuideVersionId, ico
58003
59794
  const dialogCards = useMemo(() => getFeatureCardIconDialogCards(content), [content]);
58004
59795
  const styleSummary = useMemo(() => getFeatureCardGeneratedIconStyleSummary(content, currentStyleGuideVersionId), [content, currentStyleGuideVersionId]);
58005
59796
  const hasStaleGeneratedIcons = styleSummary.kind === "available" && styleSummary.staleCount > 0;
59797
+ const generatedIconSizePx = resolveFeatureCardGeneratedIconSizePx(content?._generatedIconSizePx);
58006
59798
  async function applyGeneratedIconSetPreview(preview) {
58007
59799
  if (!blockId) return {
58008
59800
  kind: "failed",
@@ -58021,61 +59813,31 @@ function FeatureCardIconsPanel({ block, uiStore, currentStyleGuideVersionId, ico
58021
59813
  return { kind: "applied" };
58022
59814
  }
58023
59815
  if (!supportsFeatureCardIconActions(block.kind) || !blockId) return null;
58024
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("section", {
58025
- className: "rounded-md border bg-muted/20 px-3 py-3",
59816
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("section", {
58026
59817
  "aria-label": "Icons",
58027
59818
  "data-testid": "feature-card-icons-panel",
58028
- children: [/* @__PURE__ */ jsxs("div", {
58029
- className: "flex flex-wrap items-center gap-2",
58030
- children: [/* @__PURE__ */ jsxs("div", {
58031
- className: "min-w-0 flex-1",
58032
- children: [/* @__PURE__ */ jsx("h3", {
58033
- className: "text-sm font-medium",
58034
- children: "Icons"
58035
- }), /* @__PURE__ */ jsxs("p", {
58036
- className: "text-xs text-muted-foreground",
58037
- children: [
58038
- status.cardsWithIcons,
58039
- " of ",
58040
- status.totalCards,
58041
- " cards"
58042
- ]
58043
- })]
58044
- }), /* @__PURE__ */ jsxs(Button, {
58045
- type: "button",
58046
- variant: "outline",
58047
- size: "sm",
58048
- disabled: status.totalCards === 0,
58049
- onClick: () => setGenerateDialogOpen(true),
58050
- children: [/* @__PURE__ */ jsx(ImagePlus, {
58051
- className: "mr-2 h-4 w-4",
58052
- "aria-hidden": "true"
58053
- }), "Generate icon set"]
58054
- })]
58055
- }), hasStaleGeneratedIcons ? /* @__PURE__ */ jsxs(Callout, {
58056
- tone: "warning",
58057
- className: "mt-3 flex flex-wrap items-center gap-2",
58058
- children: [/* @__PURE__ */ jsx(CalloutDescription, {
58059
- className: "mt-0 min-w-0 flex-1 text-xs",
58060
- children: "Generated icons are out of date with the current icon style."
58061
- }), /* @__PURE__ */ jsxs(Button, {
58062
- type: "button",
58063
- variant: "outline",
58064
- size: "sm",
58065
- disabled: status.totalCards === 0 || !onGenerateIconSet,
58066
- onClick: () => setGenerateDialogOpen(true),
58067
- children: [/* @__PURE__ */ jsx(RotateCcw, {
58068
- className: "mr-2 h-4 w-4",
58069
- "aria-hidden": "true"
58070
- }), "Regenerate set"]
58071
- })]
58072
- }) : null]
59819
+ children: /* @__PURE__ */ jsxs(Button, {
59820
+ type: "button",
59821
+ variant: "outline",
59822
+ size: "sm",
59823
+ disabled: status.totalCards === 0,
59824
+ onClick: () => setGenerateDialogOpen(true),
59825
+ children: [/* @__PURE__ */ jsx(ImagePlus, {
59826
+ className: "mr-2 h-4 w-4",
59827
+ "aria-hidden": "true"
59828
+ }), "Manage icons"]
59829
+ })
58073
59830
  }), /* @__PURE__ */ jsx(GeneratedIconSetDialog, {
58074
59831
  open: generateDialogOpen,
58075
59832
  onOpenChange: setGenerateDialogOpen,
58076
59833
  cards: dialogCards,
58077
59834
  styleGuideSummary: iconStyleGuideSummary,
58078
59835
  styleGuideEditHref: iconStyleGuideEditHref,
59836
+ generatedIconSizePx,
59837
+ onGeneratedIconSizeChange: (value) => {
59838
+ uiStore.getState().drafts.setAtPath(blockId, "_generatedIconSizePx", value);
59839
+ },
59840
+ hasStaleGeneratedIcons,
58079
59841
  onGenerate: onGenerateIconSet,
58080
59842
  onApply: applyGeneratedIconSetPreview
58081
59843
  })] });
@@ -58413,6 +60175,7 @@ function BlockCardHeader({ block, manifest, isFirst, isLast, isMoving, onMove, o
58413
60175
  const featureCardIconDialogCards = supportsIconActions ? getFeatureCardIconDialogCards(featureCardIconContent) : [];
58414
60176
  const featureCardIconStyleSummary = supportsIconActions ? getFeatureCardGeneratedIconStyleSummary(featureCardIconContent, currentStyleGuideVersionId) : { kind: "unavailable" };
58415
60177
  const hasStaleGeneratedIcons = featureCardIconStyleSummary.kind === "available" && featureCardIconStyleSummary.staleCount > 0;
60178
+ const featureCardGeneratedIconSizePx = resolveFeatureCardGeneratedIconSizePx(featureCardIconContent?._generatedIconSizePx);
58416
60179
  async function applyGeneratedIconSetPreview(preview) {
58417
60180
  if (!blockId) return {
58418
60181
  kind: "failed",
@@ -58619,6 +60382,11 @@ function BlockCardHeader({ block, manifest, isFirst, isLast, isMoving, onMove, o
58619
60382
  cards: featureCardIconDialogCards,
58620
60383
  styleGuideSummary: iconStyleGuideSummary,
58621
60384
  styleGuideEditHref: iconStyleGuideEditHref,
60385
+ generatedIconSizePx: featureCardGeneratedIconSizePx,
60386
+ onGeneratedIconSizeChange: (value) => {
60387
+ if (blockId) uiStore.getState().drafts.setAtPath(blockId, "_generatedIconSizePx", value);
60388
+ },
60389
+ hasStaleGeneratedIcons,
58622
60390
  onGenerate: onGenerateIconSet,
58623
60391
  onApply: applyGeneratedIconSetPreview
58624
60392
  }) : null
@@ -58636,7 +60404,7 @@ function menuActionIcon(action) {
58636
60404
  function menuActionLabel(action) {
58637
60405
  switch (action.kind) {
58638
60406
  case "customize": return "Customize";
58639
- case "generated-icon-set": return action.stale ? "Regenerate icon set" : "Generate icon set";
60407
+ case "generated-icon-set": return "Manage icons";
58640
60408
  case "duplicate": return "Duplicate";
58641
60409
  case "delete": return "Delete";
58642
60410
  default: return assertNever$5(action);
@@ -62511,20 +64279,7 @@ const BACKGROUND_MODES = [
62511
64279
  "image"
62512
64280
  ];
62513
64281
  const DEFAULT_BACKGROUND_OVERRIDE = { kind: "default" };
62514
- const BACKGROUND_CUSTOMIZABLE_BLOCK_KINDS = [
62515
- "block.hero",
62516
- "block.intro",
62517
- "block.event-calendar",
62518
- "block.testimonials",
62519
- "block.cta-full",
62520
- "block.form"
62521
- ];
62522
- const BACKGROUND_COLOR_ONLY_BLOCK_KINDS = ["block.intro", "block.event-calendar"];
62523
- const BACKGROUND_RICH_LAYOUT_FAMILIES = ["split"];
62524
64282
  const BACKGROUND_RICH_SECTION_SURFACES = ["hero-image"];
62525
- function isBackgroundCustomizableBlockKind(blockKind) {
62526
- return BACKGROUND_CUSTOMIZABLE_BLOCK_KINDS.includes(blockKind);
62527
- }
62528
64283
  const backgroundColorTokenNames = backgroundAppearanceColorTokenNames;
62529
64284
  const backgroundColorTokenNameSet = new Set(backgroundColorTokenNames);
62530
64285
  const backgroundColorTokens = toBackgroundColorTokens(backgroundColorTokenNames);
@@ -62620,7 +64375,7 @@ function defaultBackgroundOverrideForMode(mode, capability) {
62620
64375
  }
62621
64376
  }
62622
64377
  function resolveBackgroundCapability(input) {
62623
- if (!isBackgroundCustomizableBlockKind(input.block.blockKind)) return backgroundCapabilityFromModes([{ kind: "default" }]);
64378
+ if (input.block.backgroundSupport.kind === "unsupported") return backgroundCapabilityFromModes([{ kind: "default" }]);
62624
64379
  const richModesSupported = blockSupportsRichBackgroundModes(input.block);
62625
64380
  const selectableColorTokens = input.palette ? dedupeBackgroundColorTokensByPalette(backgroundColorTokens, input.palette) : backgroundColorTokens;
62626
64381
  const recommendedColorTokens = selectableColorTokens.filter((token) => recommendedBackgroundColorTokens.includes(token));
@@ -62984,13 +64739,8 @@ function overrideValueAllowed(override, capability) {
62984
64739
  }
62985
64740
  }
62986
64741
  function blockSupportsRichBackgroundModes(block) {
62987
- if (BACKGROUND_COLOR_ONLY_BLOCK_KINDS.includes(block.blockKind)) return false;
62988
- return valueInList(effectiveLayoutFamily(block), BACKGROUND_RICH_LAYOUT_FAMILIES) || valueInList(effectiveLook(block)?.design.sectionSurface ?? null, BACKGROUND_RICH_SECTION_SURFACES);
62989
- }
62990
- function effectiveLayoutFamily(block) {
62991
- const effectiveLayout = block.layout?.effectiveValue;
62992
- if (!effectiveLayout) return null;
62993
- return block.availableLayouts.find((layout) => layout.id === effectiveLayout)?.profile.layoutFamily ?? null;
64742
+ if (block.backgroundSupport.kind === "unsupported" || block.backgroundSupport.richBackgrounds === "unsupported") return false;
64743
+ return valueInList(effectiveLook(block)?.design.sectionSurface ?? null, BACKGROUND_RICH_SECTION_SURFACES);
62994
64744
  }
62995
64745
  function effectiveLook(block) {
62996
64746
  const effectiveLookId = block.look.effectiveValue;
@@ -63646,7 +65396,7 @@ function applyPreviewCustomizeActionToLoadedState(state, action) {
63646
65396
  effectiveValue: action.appearancePresetId
63647
65397
  } : {
63648
65398
  kind: "auto",
63649
- effectiveValue: block.availableLooks[0]?.id ?? null
65399
+ effectiveValue: block.autoLookId
63650
65400
  }
63651
65401
  };
63652
65402
  })
@@ -63683,11 +65433,15 @@ function optimisticLayoutLookState(block, layoutVariantKey) {
63683
65433
  case "layout-unavailable": return {
63684
65434
  layout: block.layout,
63685
65435
  availableLooks: block.availableLooks,
65436
+ autoLookId: block.autoLookId,
65437
+ lookAvailability: block.lookAvailability,
63686
65438
  look: block.look
63687
65439
  };
63688
65440
  case "layout-supported": return {
63689
65441
  layout: plan.layout,
63690
65442
  availableLooks: plan.availableLooks,
65443
+ autoLookId: plan.autoLookId,
65444
+ lookAvailability: plan.lookAvailability,
63691
65445
  look: plan.look
63692
65446
  };
63693
65447
  default: return assertNever$6(plan, "Unhandled layout/Look compatibility plan");
@@ -66470,17 +68224,17 @@ function LinkedEntryEditEventBridge() {
66470
68224
  //#region ../preview-next/src/client/preview/PreviewShellLayout.tsx
66471
68225
  const previewContainerResponsiveEnabled = process.env.NEXT_PUBLIC_ENABLE_PREVIEW_CONTAINER_RESPONSIVE !== "false";
66472
68226
  const PreviewEditorSidebar = React.lazy(async () => {
66473
- return { default: (await import("./PreviewEditorSidebar-CBMhU9p_.mjs")).PreviewEditorSidebar };
68227
+ return { default: (await import("./PreviewEditorSidebar-DpAbAl08.mjs")).PreviewEditorSidebar };
66474
68228
  });
66475
68229
  const PreviewEditorUI = React.lazy(async () => {
66476
- return { default: (await import("./PreviewEditorUI-C5KEw4M8.mjs")).PreviewEditorUI };
68230
+ return { default: (await import("./PreviewEditorUI-O7cn6Xxv.mjs")).PreviewEditorUI };
66477
68231
  });
66478
68232
  const previewPaneContainmentStyle = {
66479
68233
  contain: "layout paint",
66480
68234
  isolation: "isolate",
66481
68235
  transform: "translateZ(0)"
66482
68236
  };
66483
- function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseUrl = null, pageId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, apiClient, bearerToken, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonPersonalityId = null, runtimePaletteState = null, themeSelectionPaletteVariantId = null, themeSelectionPaletteOverrides = null, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionTypographyPresetId = null, themeSelectionTypographyBodyFontOverride = null, themeSelectionTypographyHeadingFontOverride = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, themeSelectionFooterContext, supabaseUrl, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, mediaAssets, bookingOfferingPresets, themeRuntime = defaultPreviewThemeRuntime, siteStyleAccess = { kind: "hidden" } }) {
68237
+ function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseUrl = null, pageId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, apiClient, bearerToken, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonPersonalityId = null, runtimePaletteState, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, themeSelectionFooterContext, supabaseUrl, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, mediaAssets, bookingOfferingPresets, themeRuntime = defaultPreviewThemeRuntime, siteStyleAccess = { kind: "hidden" } }) {
66484
68238
  const layout = useOptionalPreviewLayout();
66485
68239
  const headerNode = layout?.headerNode ?? null;
66486
68240
  const bannerNode = layout?.bannerNode ?? null;
@@ -66671,13 +68425,8 @@ function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseU
66671
68425
  themeSelectionUpdatedAt,
66672
68426
  themeSelectionButtonPersonalityId,
66673
68427
  runtimePaletteState,
66674
- themeSelectionPaletteVariantId,
66675
- themeSelectionPaletteOverrides,
66676
68428
  themeSelectionHeaderLayoutId,
66677
68429
  themeSelectionHeaderStyleId,
66678
- themeSelectionTypographyPresetId,
66679
- themeSelectionTypographyBodyFontOverride,
66680
- themeSelectionTypographyHeadingFontOverride,
66681
68430
  themeSelectionHeaderLookId,
66682
68431
  themeSelectionFooterLookId,
66683
68432
  themeSelectionHeaderContext,
@@ -66731,13 +68480,8 @@ function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseU
66731
68480
  selectionUpdatedAt: themeSelectionUpdatedAt,
66732
68481
  buttonPersonalityId: themeSelectionButtonPersonalityId,
66733
68482
  runtimePaletteState,
66734
- paletteVariantId: themeSelectionPaletteVariantId,
66735
- paletteOverrides: themeSelectionPaletteOverrides,
66736
68483
  headerLayoutId: themeSelectionHeaderLayoutId,
66737
68484
  headerStyleId: themeSelectionHeaderStyleId,
66738
- typographyPresetId: themeSelectionTypographyPresetId,
66739
- typographyBodyFontOverride: themeSelectionTypographyBodyFontOverride,
66740
- typographyHeadingFontOverride: themeSelectionTypographyHeadingFontOverride,
66741
68485
  headerLookId: themeSelectionHeaderLookId,
66742
68486
  footerLookId: themeSelectionFooterLookId
66743
68487
  },
@@ -66773,14 +68517,14 @@ function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseU
66773
68517
  }
66774
68518
  //#endregion
66775
68519
  //#region ../preview-next/src/client/preview/PreviewShell.tsx
66776
- function PreviewShell({ children, apiBaseUrl, blockApiConfig, siteId, siteSlug, editableId, previewSession, previewToken, dashboardBaseUrl = null, surfaceId, theme, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonPersonalityId = null, runtimePaletteState = null, themeSelectionPaletteVariantId = null, themeSelectionPaletteOverrides = null, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionTypographyPresetId = null, themeSelectionTypographyBodyFontOverride = null, themeSelectionTypographyHeadingFontOverride = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, themeSelectionFooterContext, pageId, routeId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, initialStatus, initialBlocks, pageMetadata, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, mediaAssets, bookingOfferingPresets, supabaseUrl, themeRuntime = defaultPreviewThemeRuntime, designEditorEligibility, baseFetch }) {
68520
+ function PreviewShell({ children, apiBaseUrl, blockApiConfig, siteId, siteSlug, editableId, previewSession, previewToken, dashboardBaseUrl = null, surfaceId, theme, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonPersonalityId = null, runtimePaletteState, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, themeSelectionFooterContext, pageId, routeId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, initialStatus, initialBlocks, pageMetadata, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, mediaAssets, bookingOfferingPresets, supabaseUrl, themeRuntime = defaultPreviewThemeRuntime, designEditorEligibility, hideSiteStyleConfigurator = false, baseFetch }) {
66777
68521
  const apiClient = useMemo(() => createBearerAPIClient(previewToken, apiBaseUrl), [previewToken, apiBaseUrl]);
66778
68522
  const resolvedDesignEditorEligibility = designEditorEligibility ?? defaultDesignEditorEligibility({
66779
68523
  pageId,
66780
68524
  entryData
66781
68525
  });
66782
68526
  const designEditorEnabled = isPreviewRuntimeSessionEditable(previewSession) && resolvedDesignEditorEligibility.kind === "managed-page" && Boolean(pageId);
66783
- const siteStyleAccess = resolveSiteStyleAccess(previewSession);
68527
+ const siteStyleAccess = hideSiteStyleConfigurator ? { kind: "hidden" } : resolveSiteStyleAccess(previewSession);
66784
68528
  return /* @__PURE__ */ jsx(BlockApiProvider, {
66785
68529
  config: blockApiConfig,
66786
68530
  children: /* @__PURE__ */ jsx(PreviewQueryProvider, { children: /* @__PURE__ */ jsx(PreviewAuthInit, {
@@ -66832,13 +68576,8 @@ function PreviewShell({ children, apiBaseUrl, blockApiConfig, siteId, siteSlug,
66832
68576
  themeSelectionUpdatedAt,
66833
68577
  themeSelectionButtonPersonalityId,
66834
68578
  runtimePaletteState,
66835
- themeSelectionPaletteVariantId,
66836
- themeSelectionPaletteOverrides,
66837
68579
  themeSelectionHeaderLayoutId,
66838
68580
  themeSelectionHeaderStyleId,
66839
- themeSelectionTypographyPresetId,
66840
- themeSelectionTypographyBodyFontOverride,
66841
- themeSelectionTypographyHeadingFontOverride,
66842
68581
  themeSelectionHeaderLookId,
66843
68582
  themeSelectionFooterLookId,
66844
68583
  themeSelectionHeaderContext,
@@ -67027,11 +68766,12 @@ function cloneRecord(value) {
67027
68766
  }
67028
68767
  //#endregion
67029
68768
  //#region ../preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.ts
67030
- function runtimeContentDecorationProjectionFromEditorModel(editorModel, surfaceResolutionContext, designRules) {
68769
+ function runtimeContentDecorationProjectionFromEditorModel(editorModel, surfaceResolutionContext, designRules, componentRules) {
67031
68770
  const compiled = compileEditorModelRuntime({
67032
68771
  editorModel,
67033
68772
  surfaceResolutionContext,
67034
- designRules
68773
+ designRules,
68774
+ componentRules
67035
68775
  });
67036
68776
  return {
67037
68777
  kind: "runtime-content-decoration",
@@ -67495,7 +69235,7 @@ function cyclePageDesignBlockLayout(block, direction) {
67495
69235
  };
67496
69236
  }
67497
69237
  function cyclePageDesignBlockLook(block, direction) {
67498
- if (block.availableLooks.length <= 1) return null;
69238
+ if (block.lookAvailability.kind !== "available" || block.availableLooks.length <= 1) return null;
67499
69239
  const values = [null, ...block.availableLooks.map((look) => look.id)];
67500
69240
  const currentIndex = cycleChoiceIndex(block.look, values, direction);
67501
69241
  if (currentIndex === -1) return null;
@@ -67616,7 +69356,7 @@ function BlockToolbar({ blockId, blockKind, content, bookingOfferingPresets, the
67616
69356
  return pageDesignState.editorModel.blocks.find((block) => block.blockId === blockId) ?? null;
67617
69357
  }, [blockId, pageDesignState]);
67618
69358
  const hasLayoutControls = Boolean(designBlock?.layout && designBlock.availableLayouts.length > 1);
67619
- const hasLookControls = Boolean(designBlock && designBlock.availableLooks.length > 0);
69359
+ const hasLookControls = Boolean(designBlock?.lookAvailability.kind === "available");
67620
69360
  const facetControls = useMemo(() => previewCustomizeFacetControlsFor(blockKind, customizeContent, designBlock), [
67621
69361
  blockKind,
67622
69362
  customizeContent,
@@ -67937,7 +69677,7 @@ function renderBlockCustomizeBuiltinRow(row, context) {
67937
69677
  }
67938
69678
  }
67939
69679
  function canCycleLookForRow(block) {
67940
- return block.availableLooks.length > 1;
69680
+ return block.lookAvailability.kind === "available" && block.availableLooks.length > 1;
67941
69681
  }
67942
69682
  function BackgroundChooser({ capability, current, imagePoolStatus, onChoose }) {
67943
69683
  const mediaEditorContext = useMediaEditorOptional();
@@ -68552,14 +70292,15 @@ function formatBlockKindLabel(blockKind) {
68552
70292
  //#region ../preview-next/src/client/blocks/pageDesignRuntimePreview.ts
68553
70293
  function pageDesignRuntimeProjectionFromSource(source) {
68554
70294
  if (source.kind === "preserve-server-runtime") return null;
68555
- return runtimeContentDecorationProjectionFromEditorModel(source.editorModel, source.surfaceResolutionContext, source.designRules);
70295
+ return runtimeContentDecorationProjectionFromEditorModel(source.editorModel, source.surfaceResolutionContext, source.designRules, source.componentRules);
68556
70296
  }
68557
70297
  function resolveRuntimePreviewSource(input) {
68558
70298
  if (input.pageDesignState.kind === "loaded" && input.surfaceResolutionContext) return {
68559
70299
  kind: "apply-editor-model",
68560
70300
  editorModel: input.pageDesignState.editorModel,
68561
70301
  surfaceResolutionContext: input.surfaceResolutionContext,
68562
- designRules: input.designRules
70302
+ designRules: input.designRules,
70303
+ componentRules: input.componentRules
68563
70304
  };
68564
70305
  return { kind: "preserve-server-runtime" };
68565
70306
  }
@@ -68617,7 +70358,8 @@ function EditablePageRenderer(props) {
68617
70358
  const runtimePreviewSource = useMemo(() => resolveRuntimePreviewSource({
68618
70359
  pageDesignState,
68619
70360
  surfaceResolutionContext,
68620
- designRules: designRuntimeRulesForTheme(pageRendererProps.theme)
70361
+ designRules: designRuntimeRulesForTheme(pageRendererProps.theme),
70362
+ componentRules: componentRuntimeRulesForTheme(pageRendererProps.theme)
68621
70363
  }), [
68622
70364
  pageDesignState,
68623
70365
  pageRendererProps.theme,
@@ -68919,6 +70661,10 @@ async function callDirectLoaderApiEndpoint(dashboardApiClient, endpoint, params)
68919
70661
  endpoint,
68920
70662
  params
68921
70663
  }));
70664
+ case "listPublicRecurringSchedule": return projectRecurringSchedule(unwrapResponse(await dashboardApiClient({
70665
+ endpoint: "listPublicEvents",
70666
+ params
70667
+ })));
68922
70668
  }
68923
70669
  }
68924
70670
  function isBatchableEndpoint(endpoint) {
@@ -69187,6 +70933,10 @@ function SdkPreviewModeRuntime(props) {
69187
70933
  mediaAssets: content.mediaAssets
69188
70934
  };
69189
70935
  return /* @__PURE__ */ jsx(PreviewShell, {
70936
+ runtimePaletteState: {
70937
+ kind: "invalid",
70938
+ reason: "missing-active-palette-reference"
70939
+ },
69190
70940
  apiBaseUrl,
69191
70941
  blockApiConfig: useMemo(() => ({
69192
70942
  baseUrl: apiBaseUrl,
@@ -69223,6 +70973,7 @@ function SdkPreviewModeRuntime(props) {
69223
70973
  supabaseUrl: content.supabaseUrl,
69224
70974
  themeRuntime,
69225
70975
  designEditorEligibility: { kind: "sdk-page" },
70976
+ hideSiteStyleConfigurator: true,
69226
70977
  children: /* @__PURE__ */ jsx(EditablePageRenderer, {
69227
70978
  theme,
69228
70979
  page,
@@ -69243,4 +70994,4 @@ function deriveDashboardBaseUrlFromApiBaseUrl(apiBaseUrl) {
69243
70994
  }
69244
70995
  }
69245
70996
  //#endregion
69246
- export { FixedBottomSurface as C, isAdapterReferenceKind as S, CalloutDescription as T, usePreviewBlockCustomizeSelectionOptional as _, usePreviewPageDesignEditorState as a, previewWidgetOverrides as b, applyPreviewChromeSurfaceToElement as c, buildPreviewDashboardSetupUrl as d, resolvePreviewDashboardSetupHandoff as f, canInspectSiteStyle as g, canApplySiteStyle as h, PreviewShellLayout as i, resolvePreviewChromeSurface as l, resolvePreviewSidebarChromeModel as m, SdkPreviewModeRuntime_exports as n, PREVIEW_CHROME_PORTAL_CLASS_NAME as o, resolvePreviewEditorGuidanceModel as p, PreviewShell as r, PREVIEW_CHROME_THEME_CLASS_NAME as s, SdkPreviewModeRuntime as t, setPreviewSidebarTab as u, useBlockCustomizeControls as v, Callout as w, BlockEditor as x, PreviewFormProvider as y };
70997
+ export { buildFontPreviewUrl as C, Callout as D, FixedBottomSurface as E, CalloutDescription as O, isAdapterReferenceKind as S, getSiteFontsStorageUrl as T, usePreviewBlockCustomizeSelectionOptional as _, usePreviewPageDesignEditorState as a, previewWidgetOverrides as b, applyPreviewChromeSurfaceToElement as c, buildPreviewDashboardSetupUrl as d, resolvePreviewDashboardSetupHandoff as f, canInspectSiteStyle as g, canApplySiteStyle as h, PreviewShellLayout as i, resolvePreviewChromeSurface as l, resolvePreviewSidebarChromeModel as m, SdkPreviewModeRuntime_exports as n, PREVIEW_CHROME_PORTAL_CLASS_NAME as o, resolvePreviewEditorGuidanceModel as p, PreviewShell as r, PREVIEW_CHROME_THEME_CLASS_NAME as s, SdkPreviewModeRuntime as t, setPreviewSidebarTab as u, useBlockCustomizeControls as v, generateFontFaceCss as w, BlockEditor as x, PreviewFormProvider as y };