@riverbankcms/sdk 0.104.3 → 0.108.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 (302) hide show
  1. package/README.md +84 -51
  2. package/dist/{PreviewEditorSidebar-CBMhU9p_.mjs → PreviewEditorSidebar-BBT-kZAM.mjs} +1850 -1183
  3. package/dist/{PreviewEditorUI-C5KEw4M8.mjs → PreviewEditorUI-D69xNKT2.mjs} +10 -9
  4. package/dist/{PreviewQueryProvider-CStABBUh.mjs → PreviewQueryProvider-RRu7wyQ5.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-Iq12HjL7.mjs → SdkPreviewModeRuntime-CuDjXH6o.mjs} +2562 -457
  6. package/dist/{SiteChromeCustomizeContext-Cx0NMdyv.mjs → SiteChromeCustomizeContext-BQUY2dEk.mjs} +7689 -3196
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +36493 -1395
  8. package/dist/_dts/api/src/blocks.d.ts +41 -7
  9. package/dist/_dts/api/src/bookingConfig.d.ts +2 -0
  10. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +5 -1
  11. package/dist/_dts/api/src/bookingRecords.d.ts +180 -115
  12. package/dist/_dts/api/src/cache-tags.d.ts +3 -0
  13. package/dist/_dts/api/src/contentRuntime.d.ts +25 -16
  14. package/dist/_dts/api/src/courses.d.ts +68 -10
  15. package/dist/_dts/api/src/endpoints.d.ts +128 -0
  16. package/dist/_dts/api/src/footer-settings.d.ts +1 -0
  17. package/dist/_dts/api/src/footerSettings.d.ts +8 -0
  18. package/dist/_dts/api/src/index.d.ts +127 -124
  19. package/dist/_dts/api/src/navigation/contracts.d.ts +3 -3
  20. package/dist/_dts/api/src/previewContentContract.d.ts +4 -0
  21. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +9 -0
  22. package/dist/_dts/api/src/sdkContracts.d.ts +178 -6
  23. package/dist/_dts/api/src/siteBanner.d.ts +2 -2
  24. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +143 -55
  25. package/dist/_dts/api/src/siteOperations.d.ts +1 -0
  26. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +32 -4
  27. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +72 -47
  28. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +36 -4
  29. package/dist/_dts/blocks/src/definitions.d.ts +1 -1
  30. package/dist/_dts/blocks/src/portal/types.d.ts +25 -7
  31. package/dist/_dts/blocks/src/primitives/layout/Section.d.ts +0 -1
  32. package/dist/_dts/blocks/src/rendering/server.d.ts +1 -0
  33. package/dist/_dts/blocks/src/system/blocks/course-registration.d.ts +2 -2
  34. package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +2 -0
  35. package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +2 -0
  36. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +4 -0
  37. package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule-projection.d.ts +52 -0
  38. package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule.d.ts +22 -0
  39. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +45 -0
  40. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +10 -0
  41. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +4 -1
  42. package/dist/_dts/blocks/src/system/blocks/index.d.ts +1 -0
  43. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +9 -0
  44. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +8 -2
  45. package/dist/_dts/blocks/src/system/blocks/offerings-preview/index.d.ts +8 -8
  46. package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +24 -24
  47. package/dist/_dts/blocks/src/system/blocks/offerings-preview/scheduleSummary.d.ts +29 -0
  48. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +2 -1
  49. package/dist/_dts/blocks/src/system/blocks/site-footer-runtime.d.ts +50 -0
  50. package/dist/_dts/blocks/src/system/blocks/site-footer.d.ts +9 -48
  51. package/dist/_dts/blocks/src/system/constants/background.d.ts +1 -1
  52. package/dist/_dts/blocks/src/system/constants/blockKinds.d.ts +1 -1
  53. package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +2 -5
  54. package/dist/_dts/blocks/src/system/data/loaderEndpoints.d.ts +1 -1
  55. package/dist/_dts/blocks/src/system/designCapabilities.d.ts +1 -0
  56. package/dist/_dts/blocks/src/system/fragments/library/newsletterForm.d.ts +2 -2
  57. package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -1
  58. package/dist/_dts/blocks/src/system/icons/social.d.ts +5 -0
  59. package/dist/_dts/blocks/src/system/icons/svg.d.ts +1 -0
  60. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +2 -2
  61. package/dist/_dts/blocks/src/system/node/fragments/backgroundLayer.d.ts +13 -0
  62. package/dist/_dts/blocks/src/system/node/fragments/footerNav.d.ts +2 -0
  63. package/dist/_dts/blocks/src/system/node/fragments/styledCard.d.ts +3 -0
  64. package/dist/_dts/blocks/src/system/node/fragments/styledContainer.d.ts +4 -4
  65. package/dist/_dts/blocks/src/system/node/fragments/styledSection.d.ts +3 -12
  66. package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
  67. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  68. package/dist/_dts/blocks/src/system/runtime/blockComposition.d.ts +2 -0
  69. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +90 -6
  70. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +45 -3
  71. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +1 -0
  72. package/dist/_dts/blocks/src/system/runtime/nodes/commerce/shared/display.d.ts +2 -2
  73. package/dist/_dts/blocks/src/system/runtime/nodes/course-details/logic.d.ts +2 -1
  74. package/dist/_dts/blocks/src/system/runtime/nodes/course-details/view.d.ts +1 -0
  75. package/dist/_dts/blocks/src/system/runtime/nodes/course-details.server.d.ts +2 -1
  76. package/dist/_dts/blocks/src/system/runtime/nodes/course-page-surface-scope.d.ts +17 -0
  77. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/types.d.ts +3 -0
  78. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.interactive.d.ts +5 -0
  79. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.server.d.ts +1 -1
  80. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventScope.d.ts +9 -18
  81. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +106 -0
  82. package/dist/_dts/blocks/src/system/runtime/nodes/events/RecurringSchedule.d.ts +11 -0
  83. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +7 -3
  84. package/dist/_dts/blocks/src/system/runtime/nodes/media.d.ts +3 -0
  85. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +11 -1
  86. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.server.d.ts +1 -1
  87. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +3 -0
  88. package/dist/_dts/blocks/src/system/runtime/nodes/offerings-preview.d.ts +6 -6
  89. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +1 -1
  90. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +11 -5
  91. package/dist/_dts/blocks/src/system/runtime/nodes/shop.types.d.ts +2 -1
  92. package/dist/_dts/blocks/src/system/runtime/nodes/svg.d.ts +7 -0
  93. package/dist/_dts/blocks/src/system/types/link.d.ts +3 -3
  94. package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +14 -0
  95. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +27 -8
  96. package/dist/_dts/content-editor/src/footerComposer.d.ts +56 -0
  97. package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +1 -1
  98. package/dist/_dts/content-editor/src/hooks/useEntryMutations.d.ts +5 -5
  99. package/dist/_dts/content-editor/src/index.d.ts +2 -0
  100. package/dist/_dts/content-editor/src/primitives/PreviewRichTextEditor.d.ts +3 -1
  101. package/dist/_dts/content-editor/src/services/contentEntryServices.d.ts +20 -36
  102. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +5 -1
  103. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +11 -0
  104. package/dist/_dts/content-model/src/content-types/schema.d.ts +1 -1
  105. package/dist/_dts/content-model/src/definitions/shared.d.ts +3 -0
  106. package/dist/_dts/core/src/branded.d.ts +47 -0
  107. package/dist/_dts/core/src/dated-offering-settlement.d.ts +47 -0
  108. package/dist/_dts/core/src/editor-state.d.ts +4 -0
  109. package/dist/_dts/core/src/event-page-surface-subject.d.ts +44 -0
  110. package/dist/_dts/core/src/footer-composition.d.ts +143 -0
  111. package/dist/_dts/core/src/index.d.ts +51 -47
  112. package/dist/_dts/core/src/public-profile.d.ts +73 -0
  113. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +4398 -2859
  114. package/dist/_dts/db/src/schemas/forms.d.ts +10 -10
  115. package/dist/_dts/editor/src/primitives/rich-text/RichTextEditorSurface.d.ts +5 -0
  116. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +1 -0
  117. package/dist/_dts/editor-blocks/src/block-editor/FeatureCardIconsPanel.d.ts +1 -1
  118. package/dist/_dts/editor-blocks/src/block-editor/GeneratedIconSetDialog.d.ts +4 -1
  119. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockCreation.d.ts +2 -1
  120. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +2 -1
  121. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockReorder.d.ts +2 -1
  122. package/dist/_dts/editor-blocks/src/block-editor/owner.d.ts +10 -0
  123. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +1 -0
  124. package/dist/_dts/media-core/src/index.d.ts +2 -1
  125. package/dist/_dts/media-core/src/storagePathDomain.d.ts +47 -0
  126. package/dist/_dts/media-core/src/url.d.ts +1 -21
  127. package/dist/_dts/path-utils/src/index.d.ts +5 -0
  128. package/dist/_dts/preview-next/src/client/blocks/pageDesignRuntimePreview.d.ts +4 -2
  129. package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -1
  130. package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -1
  131. package/dist/_dts/preview-next/src/client/preview/PreviewChromeLayer.d.ts +5 -0
  132. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +4 -9
  133. package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +1 -0
  134. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +8 -11
  135. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +4 -9
  136. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +2 -6
  137. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.d.ts +5 -9
  138. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +81 -43
  139. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.typography.d.ts +61 -0
  140. package/dist/_dts/preview-next/src/client/preview/previewErrorMessages.d.ts +4 -0
  141. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +7 -17
  142. package/dist/_dts/preview-next/src/client/preview/styleConfiguratorSnapshot.d.ts +15 -8
  143. package/dist/_dts/preview-next/src/client/preview/typographyFontCatalog.d.ts +57 -0
  144. package/dist/_dts/sdk/src/cli/commands/pull.d.ts +1 -1
  145. package/dist/_dts/sdk/src/cli/commands/push/execute/theme.d.ts +4 -7
  146. package/dist/_dts/sdk/src/cli/commands/style.d.ts +24 -10
  147. package/dist/_dts/sdk/src/cli/content/reader.d.ts +1 -0
  148. package/dist/_dts/sdk/src/cli/site-commands/oneOffCommands.d.ts +3 -3
  149. package/dist/_dts/sdk/src/cli/sync/media.d.ts +16 -2
  150. package/dist/_dts/sdk/src/client/management/blocks.d.ts +14 -1
  151. package/dist/_dts/sdk/src/client/management/index.d.ts +2 -1
  152. package/dist/_dts/sdk/src/client/management/types.d.ts +147 -24
  153. package/dist/_dts/sdk/src/client/types.d.ts +2 -0
  154. package/dist/_dts/sdk/src/config/content-types.d.ts +2 -0
  155. package/dist/_dts/sdk/src/config/content-validation.d.ts +4 -0
  156. package/dist/_dts/sdk/src/config/types.d.ts +1 -1
  157. package/dist/_dts/sdk/src/config/validation.d.ts +3 -0
  158. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  159. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +23 -3
  160. package/dist/_dts/sdk/src/data/dataLoaderContext.d.ts +17 -0
  161. package/dist/_dts/sdk/src/data/dataLoaderValue.d.ts +36 -0
  162. package/dist/_dts/sdk/src/data/defineOwnDataProperty.d.ts +2 -0
  163. package/dist/_dts/sdk/src/data/executeCodeLoaders.d.ts +36 -40
  164. package/dist/_dts/sdk/src/data/index.d.ts +3 -3
  165. package/dist/_dts/sdk/src/data/resolveBlockData.d.ts +54 -0
  166. package/dist/_dts/sdk/src/data/types.d.ts +43 -78
  167. package/dist/_dts/sdk/src/navigation/index.d.ts +2 -0
  168. package/dist/_dts/sdk/src/next/index.d.ts +1 -0
  169. package/dist/_dts/sdk/src/next/redirect-destination.d.ts +1 -1
  170. package/dist/_dts/sdk/src/next/resolveTheme.d.ts +2 -1
  171. package/dist/_dts/sdk/src/next/types.d.ts +10 -1
  172. package/dist/_dts/sdk/src/public-api/contracts.d.ts +6 -10
  173. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +2 -1
  174. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +10 -5
  175. package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +6 -10
  176. package/dist/_dts/sdk/src/rendering/index.d.ts +1 -0
  177. package/dist/_dts/sdk/src/server.d.ts +4 -3
  178. package/dist/_dts/sdk/src/types/block-kinds.d.ts +1 -1
  179. package/dist/_dts/sdk/src/version.d.ts +1 -1
  180. package/dist/_dts/site-commands/src/capabilityGaps.d.ts +2 -2
  181. package/dist/_dts/site-commands/src/commands.d.ts +934 -40
  182. package/dist/_dts/theme-core/src/accordions/types.d.ts +2 -2
  183. package/dist/_dts/theme-core/src/buttons/generateDefaultButtonSystem.d.ts +5 -1
  184. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +22 -0
  185. package/dist/_dts/theme-core/src/buttons/personalities/quiet-arrow.d.ts +17 -0
  186. package/dist/_dts/theme-core/src/buttons/personalities/two-tone-pill.d.ts +17 -0
  187. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +3 -3
  188. package/dist/_dts/theme-core/src/buttons/types.d.ts +12 -8
  189. package/dist/_dts/theme-core/src/cards/types.d.ts +3 -3
  190. package/dist/_dts/theme-core/src/data.d.ts +12 -0
  191. package/dist/_dts/theme-core/src/fonts/index.d.ts +1 -1
  192. package/dist/_dts/theme-core/src/fonts/types.d.ts +6 -0
  193. package/dist/_dts/theme-core/src/footer/mode.d.ts +15 -0
  194. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  195. package/dist/_dts/theme-core/src/interactive/baseSchema.d.ts +1 -1
  196. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +72 -54
  197. package/dist/_dts/theme-core/src/navigation/types.d.ts +1 -1
  198. package/dist/_dts/theme-core/src/palette/colors.d.ts +12 -0
  199. package/dist/_dts/theme-core/src/palette/curated/brand-led.d.ts +10 -5
  200. package/dist/_dts/theme-core/src/palette/curated/high-contrast.d.ts +6 -3
  201. package/dist/_dts/theme-core/src/palette/curated/index.d.ts +31 -236
  202. package/dist/_dts/theme-core/src/palette/curated/soft-natural.d.ts +8 -4
  203. package/dist/_dts/theme-core/src/palette/curated/types.d.ts +14 -12
  204. package/dist/_dts/theme-core/src/palette/curated/warm-dark.d.ts +4 -2
  205. package/dist/_dts/theme-core/src/palette/curated/warm-neutral.d.ts +8 -4
  206. package/dist/_dts/theme-core/src/palette/editorState.d.ts +33 -3
  207. package/dist/_dts/theme-core/src/palette/index.d.ts +0 -4
  208. package/dist/_dts/theme-core/src/palette/libraryModel.d.ts +12 -6
  209. package/dist/_dts/theme-core/src/palette/persistenceReadSource.d.ts +20 -72
  210. package/dist/_dts/theme-core/src/palette/resolveSelection.d.ts +29 -4
  211. package/dist/_dts/theme-core/src/palette/selection.d.ts +6 -4
  212. package/dist/_dts/theme-core/src/schema.d.ts +1307 -38
  213. package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +218 -158
  214. package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +5 -6
  215. package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +218 -158
  216. package/dist/_dts/theme-core/src/site-styles/compositionBudget.d.ts +1 -0
  217. package/dist/_dts/theme-core/src/site-styles/contentTemplateRuntimeCompiler.d.ts +2 -1
  218. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +161 -51
  219. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +6 -0
  220. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  221. package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +12 -1
  222. package/dist/_dts/theme-core/src/site-styles/index.d.ts +1 -1
  223. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +24 -1
  224. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +14 -48
  225. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +10 -23
  226. package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +15 -0
  227. package/dist/_dts/theme-core/src/site-styles/siteStyleThemeCompiler.d.ts +1 -2
  228. package/dist/_dts/theme-core/src/site-styles/siteStyleTypography.d.ts +456 -0
  229. package/dist/_dts/theme-core/src/site-styles/types.d.ts +52 -3
  230. package/dist/cli/index.mjs +4118 -2278
  231. package/dist/client/{DiscountCodeDisclosure-BXM73_E5.mjs → DiscountCodeDisclosure-D6TOf6Hi.mjs} +1 -1
  232. package/dist/client/{EventCombined.client-DT5elP7j.mjs → EventCombined.client-Dao3zxRk.mjs} +3 -3
  233. package/dist/client/{EventListing.client-pTYGfV9C.mjs → EventListing.client-B2NNt4y1.mjs} +2 -2
  234. package/dist/client/{LeafletStaticMap-dQrhlUe3.mjs → LeafletStaticMap-BhwFo16w.mjs} +1 -1
  235. package/dist/client/{MagicLinkForm-u6Dul4j5.mjs → MagicLinkForm-BWnB7cMR.mjs} +2 -2
  236. package/dist/client/{StepIndicator-nWqineJ2.mjs → StepIndicator-TzRiQ0BY.mjs} +2 -2
  237. package/dist/client/{accordion-CSJcTUyH.mjs → accordion-BPy-AJ4_.mjs} +1 -1
  238. package/dist/client/{bookingForm-C73wOuVa.mjs → bookingForm-BL4PGZds.mjs} +7 -7
  239. package/dist/client/bookings.mjs +382 -204
  240. package/dist/client/{buttons-DfYyqt8C.mjs → buttons-EBjyslaX.mjs} +265 -152
  241. package/dist/client/{carousel-fMBb0JSc.mjs → carousel-C2b7Cn9-.mjs} +1 -1
  242. package/dist/client/{cart-BtaCwT3S.mjs → cart-BQcbXIVD.mjs} +3 -3
  243. package/dist/client/{checkout-DkTwZSnh.mjs → checkout-DEmpGRJu.mjs} +3 -3
  244. package/dist/client/client.mjs +5019 -1886
  245. package/dist/client/{colorStyles-Wyl6JujD.mjs → colorStyles-jZS6KfkP.mjs} +1 -1
  246. package/dist/client/{colorTokenParts-dT8MISgJ.mjs → colorTokenParts-CMugwvX_.mjs} +3 -1
  247. package/dist/client/{courseRegistration-DnLmapJu.mjs → courseRegistration-BqRZPmsq.mjs} +56 -21
  248. package/dist/client/{eventCalendar-BvLOc9KY.mjs → eventCalendar-B8N_tSl5.mjs} +29 -21
  249. package/dist/client/{eventCombined-kShgJPQr.mjs → eventCombined-Gjn6gtq7.mjs} +2 -2
  250. package/dist/client/{eventDetails-C5NTM0Vo.mjs → eventDetails-M-VCxA-r.mjs} +4 -4
  251. package/dist/client/{eventListing-B82ZdKP6.mjs → eventListing-DR19hqYi.mjs} +2 -2
  252. package/dist/client/{eventRegistration-qJVFqBWo.mjs → eventRegistration-BR02a0k3.mjs} +8 -8
  253. package/dist/client/{form-BvAcKiuu.mjs → form-LY2xIbwg.mjs} +2 -2
  254. package/dist/client/{headerSection-NvAiEHAg.mjs → headerSection-CYwwXJfh.mjs} +3 -3
  255. package/dist/client/hooks.mjs +3335 -2210
  256. package/dist/client/{locationMap-D0j52xfI.mjs → locationMap-DWnBXrFq.mjs} +3 -3
  257. package/dist/client/{media-BCW_g2cQ.mjs → media-DHtSxS5V.mjs} +61 -56
  258. package/dist/client/{newsletterForm-B8_i93qH.mjs → newsletterForm-D9s-fQ2P.mjs} +3 -3
  259. package/dist/client/{pricing-DIYnyHOk.mjs → pricing-DDq80oYc.mjs} +1 -1
  260. package/dist/client/{productDetail-w0eAHkuQ.mjs → productDetail-B0SbWd45.mjs} +3 -3
  261. package/dist/client/{productList-Vsguq5Xt.mjs → productList-PwYlZn0y.mjs} +3 -3
  262. package/dist/client/{propsDecoder-CD2pJ1WB.mjs → propsDecoder-BRWBiH7i.mjs} +225 -68
  263. package/dist/client/rendering/client.mjs +2266 -1267
  264. package/dist/client/rendering/islands.mjs +20 -20
  265. package/dist/client/rendering.mjs +5364 -1979
  266. package/dist/client/{shop-Dgxs-Q8F.mjs → shop-CMwZPYME.mjs} +8 -8
  267. package/dist/client/{shop-commerce-DJAhsTaT.mjs → shop-commerce-BuxsFate.mjs} +6 -6
  268. package/dist/client/{shop-commerce-store-CfCXltXW.mjs → shop-commerce-store-boYlEJ91.mjs} +1 -1
  269. package/dist/client/{shopShared-CmDcPXUt.mjs → shopShared-D2naaOes.mjs} +3 -3
  270. package/dist/client/{useDiscountCodeUi-CirrT2bM.mjs → useDiscountCodeUi-D9RHpVoj.mjs} +1 -1
  271. package/dist/client/{useEventFilters-CNZxlCcO.mjs → useEventFilters-igGiK1re.mjs} +6 -6
  272. package/dist/client/{usePolling-Baks_iBI.mjs → usePolling-CI7MbsFB.mjs} +2 -2
  273. package/dist/preview-next/before-render.mjs +218 -1
  274. package/dist/preview-next/client/runtime.mjs +4 -4
  275. package/dist/preview-next/middleware.mjs +218 -1
  276. package/dist/{previewAuthStore-CfquDtTh.mjs → previewAuthStore-a_cBD28m.mjs} +218 -1
  277. package/dist/{sdk-runtime-BfNiFeNJ.mjs → sdk-runtime-MBzD-GmP.mjs} +2 -2
  278. package/dist/{separator-BhAR_Xmf.mjs → separator-5ahRBC85.mjs} +1 -1
  279. package/dist/server/components.mjs +5218 -2529
  280. package/dist/server/config-validation.mjs +3112 -2210
  281. package/dist/server/config.mjs +3112 -2211
  282. package/dist/server/data.mjs +3758 -2277
  283. package/dist/server/index.mjs +224 -4
  284. package/dist/server/navigation.mjs +9 -3
  285. package/dist/server/next/middleware.mjs +1 -1
  286. package/dist/server/next.mjs +6468 -2749
  287. package/dist/server/page-converter.mjs +3524 -2635
  288. package/dist/server/prebuild.mjs +1 -1
  289. package/dist/server/rendering/server.mjs +5392 -2488
  290. package/dist/server/rendering.mjs +6241 -2851
  291. package/dist/server/routing.mjs +3414 -1826
  292. package/dist/server/server.mjs +4174 -2354
  293. package/dist/server/theme-bridge.mjs +9579 -8132
  294. package/dist/server/theme.mjs +313 -154
  295. package/dist/styles/index.css +1223 -31
  296. package/package.json +1 -1
  297. package/dist/_dts/preview-next/src/client/preview/typographySelectionInput.d.ts +0 -16
  298. package/dist/_dts/theme-core/src/palette/historicalThemePalette.d.ts +0 -44
  299. package/dist/_dts/theme-core/src/palette/legacyRuntimeProjection.d.ts +0 -55
  300. package/dist/_dts/theme-core/src/palette/legacySelection.d.ts +0 -45
  301. package/dist/_dts/theme-core/src/palette/paletteCompatibilityTransition.d.ts +0 -232
  302. 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 beginAutosaveBatch, $a as resolveEventCalendarListPageSize, $c as getImageUrl, $d as RotateCcw, $i as NAV_LINK_LETTER_SPACING_MAP, $l as Input, $n as isInternalResolvedLinkValue, $o as resolveEventLinkProps, $r as augmentManifestWithStyleGroups, $s as resolveIconPickerPreset, $t as evaluateVisibility, $u as clsx, Aa as generateCssVars, Ac as XIcon, Ad as unsafeAsAppointmentServiceId, Af as CircleAlert, Ai as mergeHeaderNavTypographyPreference, Al as hasEmptyOption, An as CSS, Ao as generateCardCss, Ar as normalizeEventRegistrationPageSurfaceSubject, As as getFeatureCardIconCompletion, At as canUndoHistory, Au as DropdownMenuItem, Ba as isOfferingsPreviewSourceKey, Bc as resolveMediaNodeResponsiveImage, Bd as X, Bf as Archive, Bi as componentRuntimeRulesForTheme, Bl as Textarea, Bn as projectRecurringSchedule, Bo as normalizeLocationMapProps, Br as buildCartDisplay, Bs as resolveBlockIconRenderValue, Bt as createSnapshotFromPageRecord, Bu as __spreadArray, C as usePreviewThemeOverlay, Cc as MapPinIcon$1, Cd as publicEventTicketTypes, Cf as Crop, Ci as MQ_SM_UP, Cl as getFieldIntent, Cn as closestCenter, Co as normalizeEventCategoryIdsCsv, Cr as WIZARD_STEPS$1, Cs as ICON_CONFIG, Cu as Card, Dc as PlusIcon, Dd as parseMediaAssetId, Df as CirclePlus, Di as boxStylesTransforms, Dl as useBlockContext, Dn as useDroppable, Do as normalizeEventSurfaceScope, Dr as buildGiftingInteractiveIslandProps, Ds as FEATURE_CARD_GENERATED_ICON_SIZE_PX, Dt as useEditorUiStoreInstance, Ec as PlayIcon, Ed as expectParsedBrandedId, Ef as Clock3, Ei as getAnchorClasses, El as isNonEmptyValue, En as useDraggable, Eo as normalizeEventSurfacePresetsCsv, Er as giftingBlockDefinition, Es as mediaSchema, Et as useEditorUiStore, Eu as CardTitle, Fc as computeMediaTransformStyle, Fd as unsafeAsPositiveByteCount$1, Ff as ChevronDown, Fi as retargetCompiledBoundaryRuntimeForContentAdjacency, Fl as useField, Fn as isSupportedLoaderEndpoint, Fo as resolveOnColorForThemeToken, Fr as buildCheckoutInteractiveIslandProps, Fs as toFeatureCardIconSuggestionInputs, Ft as unsafeAsLinkedContentEntryId, Fu as __awaiter, Ga as resolveOfferingsPreviewGroupOrderEntries, Gc as attachRenderableMediaAssetFields, Gd as Ticket, Gi as isThemeV2NormalEditorRawStyleFieldName, Gl as SelectTrigger, Gn as planSiteOverlayHeaderClearance, Go as formatEventPrice, Gr as EMPTY_COMMERCE_CART_STATE, Gs as unwrapRichTextRoot, Gt as usePalette, Gu as useControllableState, Ha as normalizeOfferingsPreviewItemLimit, Hc as setContextResolveImageUrlContext, Hf as __exportAll, Hi as designRuntimeRulesForTheme, Hl as Select, Hn as siteHeaderManifest, Ho as formatDate$3, Hr as buildProductDetailDisplay, Hs as parseGeneratedIconSetId, Hu as useId$1, Ic as getCurrentResolveImageUrlContext, Id as unsafeAsPositiveSeconds, If as Check, Ii as retargetCompiledRuntimeFieldsForContentAdjacency, Il as Tooltip, In as gradientToCss, Io as resolveTokenOrCssColorValue, Ir as buildProductDetailInteractiveIslandProps, Is as buildGeneratedBlockIconRenderAssetLookupFromUnknown, It as recordsEqual, Iu as __extends, Ja as resolveSpacing, Jc as formatAspectRatioToken, Jd as Sparkles, Ji as getComponentBorderWidthPx, Jl as Badge, Jn as mediaTransforms, Jo as formatTime$3, Jr as deriveCommerceCheckoutState, Js as coerceInlineTextWithFallback, Jt as validateBlockManifestIssues, Ju as Primitive, Ka as resolveOfferingsPreviewGroups, Kc as isRotationDimensionSwap, Ki as isThemeV2NormalEditorRawStylePath, Kl as SelectValue, Kn as visibleHeaderClearancePx, Ko as formatEventPriceDisplay, Kr as buildPassCartItem, Ks as isObjectRecord, Kt as recoveryConflictCopy, Ku as createContextScope, La as OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS, Lc as renderAudio, Ld as err$2, Lf as Box, Li as normalEditorCuratedPromotedFieldPaths, Ll as TooltipContent, Ln as GRADIENT_PRESETS, Lo as getTextColorForBackground, Lr as buildProductListInteractiveIslandProps, Ls as getBlockIconSemanticId, Lu as __generator, Ma as runTransforms, Mc as ImagePresets, Md as unsafeAsFormId, Mf as ChevronUp, Mi as formatSiteChromeBackgroundTokenLabel, Ml as mapOptionValueForSelect, Mn as useCombinedRefs, Mo as normalizeBoxStylesCardVariant, Mr as checkoutBlockDefinition, Ms as resolveFeatureCardGeneratedIconSizePx, Mt as pushHistoryEntry, Mu as DropdownMenuSeparator, Na as ctaButton, Nc as MediaPlaceholder, Nd as unsafeAsMediaAssetId, Nf as ChevronRight, Ni as applyCompiledRuntimeFieldsToContent, Nl as unmapValueFromSelect, Nn as useIsomorphicLayoutEffect, No as normalizeCardVariantRole, Nr as cartBlockDefinition, Ns as shouldReserveFeatureCardIconZone, Nt as redoHistory, Nu as DropdownMenuTrigger, Oc as ShoppingCartIcon, Od as parseSiteId, Of as CircleMinus, Oi as resolveSurfaceForegroundStyles, Ol as SdkConfigProvider, On as useSensor, Oo as normalizeEventVenueId, Or as courseRegistrationBlockDefinition, Os as FEATURE_CARD_ICON_TREATMENTS, Ot as useOptionalEditorUiStoreInstance, Ou as DropdownMenu, Pc as buildResolveImageUrlContext, Pd as unsafeAsPassId, Pf as ChevronLeft, Pi as compileEditorModelRuntime, Pl as FieldFrame, Pn as useUniqueId, Po as isCssColorLiteral, Pr as buildCartInteractiveIslandProps, Ps as suggestSemanticIconForFeatureCard, Pt as undoHistory, Pu as __assign, Qa as getEventRuntimeFiltersKey, Qc as getDirectImageUrlForMediaAsset, Qd as Search, Qi as NAV_LINK_BORDER_RADIUS_MAP, Ql as PopoverTrigger, Qn as createManifestValidator, Qo as resolveEventCta, Qr as augmentManifest, Qs as isIconPickerPreset, Qt as FormRenderer, Qu as cn$1, Ra as buildOfferingsPreviewRenderStates, Rc as renderVideo, Rd as ok$3, Rf as ArrowUp, Ri as planPageDesignLayoutLookCompatibility, Rl as TooltipProvider, Rn as getBlockDefinition, Ro as featuresFromHex, Rr as buildShopInteractiveIslandProps, Rs as getGeneratedBlockIconStyleState, Rt as useDebouncedLatestSave, Ru as __read, S as PreviewThemeOverlayProvider, Sa as defaultThemeTokens, Sc as MailIcon, Sd as publicEventScalarPrice, Sf as EllipsisVertical, Si as MQ_SM_DOWN, Sl as useBackendWatch, Sn as PointerSensor, So as normalizeEventBlockKind, Sr as resolveRegistrationTarget, Ss as ACCORDION_TRIGGER_LETTER_SPACING, St as EntryControllerProvider, Su as createCollapsibleScope, Tc as PhoneIcon, Td as assertNever$5, Tf as Copy, Ti as BACKGROUND_POSITION_PRESET_VALUES, Tl as isHeaderField, Tn as useDndContext, To as normalizeEventStaffMemberId, Tr as getWizardStepsForContext$1, Ts as PUBLIC_DOWNLOAD_MEDIA_TYPES, Tu as CardHeader, Ua as resolveOfferingsPreviewCoursePath, Uc as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, Uf as __toESM, Ui as getCuratedSiteStyle, Ul as SelectContent, Un as SITE_CHROME_VISIBLE_HEADER_SELECTOR, Uo as formatEventCompactDateRail, Ur as formatCommercePrice, Us as parseSiteIconStyleGuideVersionId, Uu as useDirection, Va as normalizeOfferingsPreviewGroupOrder, Vc as resolveMediaStorageUrl, Vd as Upload, Vf as __commonJSMin, Vl as Slider, Vn as siteFooterManifest, Vo as toLocationMapHydrationProps, Vr as buildProductCardDisplay, Vs as parseGeneratedIconAssetId, Vu as __spreadArrays, Wa as resolveOfferingsPreviewGroupCta, Wc as resolveMediaSlotContract, Wd as Trash2, Wi as surfaceResolutionContextFromTheme, Wl as SelectItem, Wn as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Wo as formatEventDateParts, Wr as formatInterval, Ws as createRichTextDocFromMarkdown, Wt as PaletteProvider, Wu as createCollection, Xa as eventListPaginationActionSchema, Xc as resolveMediaTransformForAspect, Xi as parseBlockCustomCssRules, Xl as Popover, Xn as uiTransforms, Xo as getContainerClass, Xr as productItemKey, Xs as isInlineTextEmpty, Xt as createManifestFormAdapter, Xu as cva, Ya as buildEventRuntimeFilters, Yc as parseAspectRatioValue, Yi as getComponentShadowVar, Yn as layoutTransforms, Yo as getCardOrientation, Yr as parseStoredCommerceCartState, Ys as inlineTextToPlainText, Yt as ManifestForm, Yu as Button, Za as eventPageSizeSchema, Zc as asRecord, Zd as Settings, Zi as parseCustomCssRules, Zl as PopoverContent, Zn as formattingTransforms, Zo as groupEventsByDate, Zr as reduceCommerceCart, Zs as parseInlineTextFromUnknown, Zu as useComposedRefs, _a as BACKGROUND_BODY_TEXT_MIN_CONTRAST_RATIO, _c as FileArchiveIcon, _d as parseEventPageSurfaceSubject, _f as FilePlay, _i as PUBLIC_FILE_FIELD_KINDS, _l as rgbColorValue, _n as DEFAULT_LAUNCH_READINESS_INPUT, _o as when, _r as toRegistrationEvents, _s as asDesignBlockId, _t as EditorProvider, _u as CollapsibleContent, aa as INPUT_SPACING_MAP, ac as ArrowRightIcon, ad as unsafeAsEditorBlockValues, ai as blogFeaturedPostFragment, al as generateButtonCss, an as createBlock, ao as columnOptionSchema, ar as newsletterSignupBlockDefinition, as as blockBookingPaymentTermsSchema, au as List, b as PreviewDesignCoordinatorProvider, ba as foregroundTokenForBackgroundAppearanceColorToken, bc as FileTextIcon, bd as publicEventPricingMode, bi as MQ_MD_DOWN, bl as surfaceForegroundDeclarations, bn as DndContext, bo as eventScheduleScopeValues, br as resolveDiscountContext, bs as ACCORDION_SPACING_MAP, bt as useUISelector, bu as Root, cc as ChevronDownIcon, cd as formatBookingDateTime, cf as LoaderCircle, ci as formCopyFragment, cl as generateBaseInteractiveCSS, cn as deleteBlock, co as eventLayoutSchema, cr as buildEventListingInteractiveIslandProps, cs as defineInteractiveIslandMetaKeys, ct as PreviewRichTextEditor, cu as ScrollableDialogContent, dc as ChevronUpIcon, dd as formatLocalScheduleDate, df as ImagePlus, di as ctaCopyFragment, dl as parseThemeButtonVariantId, do as weekStartSchema, dr as buildEventCalendarListingDisplay, ds as defineProgressiveBlockRuntime, dt as useRichTextEditor, du as DialogContent, ea as NAV_LINK_PADDING_MAP, ec as SEMANTIC_ICON_DEFINITIONS, ed as parseFooterModuleId, ei as richTextFragment, el as getAtPath, en as createStoreBackend, eo as resolveEventListPaginationAction, er as ImageResolveContextProvider, es as getEventAvailability, et as confirmAutosaveBatch, eu as Tabs, f as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, fa as boundaryRuntimeMetricsForTransition, fc as CircleMinusIcon, fd as getBookingLocalDateKey, ff as ImageOff, fi as heroCtaRowFragment, fl as themeButtonClassName, fn as mutateBlockContent, fo as eventCalendarListLayoutCompatibleDisplayModeValues, fr as buildEventCalendarListingRender, ft as EMPTY_DOC, fu as DialogDescription, ga as sectionTransitionVariantForBoundaryOptionId, gc as ExternalLinkIcon, gd as toScheduledBookingDateTime, gf as FileSpreadsheet, gi as defineFragment, gl as mergeStyles, gn as decodePublicProductCategorySelectorQuery, go as richText, gr as buildEventRegistrationInteractiveIslandProps, gs as planSiteChromePlacement, gt as InlineTextEditor, gu as Collapsible, ha as sectionTransitionFamilyForBoundaryOptionId, hc as DownloadIcon, hd as toBookingTimeZone, hf as FileText, hi as bodyCopyFragment, hl as cssVarValue, hn as reorderPageSurfaceSlotBlocks, ho as el, hr as eventRegistrationBlockDefinition, hs as splitPositioningClasses, ht as insertOrReplaceRichTextImage, hu as DialogTitle, i as usePreviewDesignHistoryOrder, ia as INPUT_FONT_SIZE_MAP, ic as ArrowLeftIcon, id as unsafeAsEditorBlockId, ii as faqHeadingFragment, il as AFFORDANCE_SUPPRESS_CLASS, in as getPageDesignEditorState, io as calendarTabViewsSchema, ir as productDetailBlockDefinition, is as resolveRuntimeEventPricing, it as rejectAutosaveBatch, iu as Content$1, ja as createTransformRegistry, jc as createIcon, jd as unsafeAsCustomerPassId, jf as ChevronsUpDown, ji as readHeaderNavFontSizePreference, jl as mapCurrentValueForSelect, jn as isKeyboardEvent, jo as generateShadowValue, jr as resolveEventRegistrationScopedEvents, js as parseFeatureCardGeneratedIconSizePx, jt as createHistoryState, ka as expandPalette, kc as UploadIcon, kd as unsafeAsAppointmentResourceId, kf as CircleCheck, ki as resolveBackgroundColorValue, kl as useSdkConfig, kn as useSensors, ko as publicEventSchema, kr as buildCourseRegistrationInteractiveIslandProps, ks as createFeatureCardIconKey, kt as canRedoHistory, ku as DropdownMenuContent, lc as ChevronLeftIcon, ld as formatBookingInstant, lf as Image, li as testimonialsCarouselFragment, ll as generateInteractiveChildInheritanceCSS, ln as deleteEntrySlotBlock, lo as filterAutoShowSchema, lr as eventCalendarBlockDefinition, ls as createZodCodec, lt as PreviewInlineTextEditor, lu as Dialog, ma as sectionTransitionFamilies, mc as ClockIcon$1, md as resolveBookingTimeZoneId, mf as File, mi as heroCopyFragment, ml as borderColorStyle, mn as reorderEntrySlotBlocks, mo as bind, mr as buildFormInteractiveIslandProps, ms as markEditableSurfaceForwarding, mt as getRichTextImagePositionFromTarget, mu as DialogHeader, n as useSiteChromeCustomizeOptional, na as NAV_LINK_TEXT_SIZE_MAP, nc as isSemanticIconId, nd as createEditorRemoveBlockCommand, nf as Pencil, ni as cardFragment, nn as toRoutableLinkPayload, no as normalizeCsvString, nr as shopBlockDefinition, ns as getLocalDateKey, nt as enqueueTransaction, nu as TabsList, oa as LABEL_FONT_SIZE_MAP, oc as CalendarIcon$1, od as addLocalScheduleDays, of as Minus, oi as singleButtonFragment, ol as generateEffectsCSS, on as createEntrySlotBlock, oo as eventButtonVariantSchema, or as buildNewsletterFormInteractiveIslandProps, os as buildInteractiveIslandProps, ot as resolvePreviewSidebarTab, ou as Root2$1, p as reportPreviewDesignError, pa as defaultSectionTransitionVariantForFamily, pc as CirclePlusIcon, pd as parseBookingLocalDate, pf as GripVertical, pi as ctaRowFragment, pl as backgroundColorStyle, pn as reorderBlocks, po as eventCalendarListLayoutOptions, pr as formBlockDefinition, ps as composeHeaderSectionWrapperClassName, pt as RichTextEditorSurface, pu as DialogFooter, qa as isSemanticSpacing, qc as normalizeRightAngle, qd as Star, qi as pageDesignEditorBackgroundOverrideOwner, ql as Label, qn as contentTransforms, qo as formatEventTeacherLine, qr as buildProductCartItem, qs as isRecord$21, qt as unfinishedBlockCopy, qu as composeEventHandlers, r as PreviewDesignHistoryOrderProvider, ra as FONT_WEIGHT_MAP, rc as ArrowDownIcon, rd as createEditorReorderBlocksCommand, ri as faqAccordionFragment, rn as applyPageDesignEditorAction, ro as normalizeOptionalId, rr as productListBlockDefinition, rs as getLocalMinuteOfDay, rt as idleEditorTransactionQueueState, ru as TabsTrigger, sc as CheckIcon$1, sd as formatBookingDate, si as formEmbedFragment, sl as generateShadowValue$1, sn as createPageSurfaceSlotBlock, so as eventCalendarDefaultViewSchema, sr as eventListingBlockDefinition, ss as createInteractiveIslandCodec, su as Trigger$1, t as SiteChromeCustomizeProvider, ta as NAV_LINK_PADDING_X_MAP, tc as getSemanticIconComponent, td as createEditorInsertBlockCommand, tf as Plus, ti as headingFragment, tl as siblingPath$1, tn as listContentTypes, to as normalizeCsvIds, tr as useImageResolveContextOptional, ts as getEventAvailabilityStatus, tt as deriveTransactionCapabilities, tu as TabsContent, u as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, uc as ChevronRightIcon, ud as formatBookingTime, uf as ImageUp, ui as testimonialsHeadingFragment, ul as TokenResolver, un as deletePageSurfaceSlotBlock, uo as previewStageSchema, ur as buildEventCalendarInteractiveIslandProps, us as defineClientOwnedBlockRuntime, ut as PreviewTextEditor, uu as DialogClose, va as backgroundAppearanceColorTokenNames, vc as FileAudioIcon, vd as formatBookingPriceDisplay, vf as FileHeadphone, vi as siteOptionSources, vl as textColorStyle, vn as deriveLaunchReadiness, vo as bindingSchema, vr as findEventByOccurrenceId, vs as assertNever$6, vt as useEditor, wc as MinusIcon, wd as formatCurrencyAmount, wf as CreditCard, wi as MQ_TABLET_ONLY, wl as getModalConfig, wn as getClientRect, wo as normalizeEventScheduleScope, wr as getStepNumber$1, ws as ICON_SIZE_PX, wt as useEntryEditorController, wu as CardContent, xa as parseBackgroundAppearanceColorToken, xc as InfoIcon, xd as publicEventPricingType, xf as EyeOff, xi as MQ_MD_UP, xl as surfaceForegroundValue, xn as KeyboardCode, xo as eventSurfaceScopeValues, xr as resolveEventRequiresPayment, xs as ACCORDION_TRIGGER_FONT_SCALE, xt as EditableBlockProvider, xu as Trigger, ya as backgroundAppearanceQuickColorTokenNames, yc as FileSpreadsheetIcon, yd as publicEventPricingCurrency, yf as FileArchive, yi as MQ_LG_UP, yl as DEFAULT_SURFACE_TEXT_COLOR, yn as AMBIENT_BACKGROUND_ROLES$1, yo as eventBlockKindValues, yr as findPreSelectedEvent, ys as ACCORDION_OPEN_ACCENT_THICKNESS, yu as Content, za as inferLegacyOfferingsPreviewGroupOrder, zc as resolveImageUrlWithContext, zd as lucide_react_exports, zf as ArrowDown, zi as resolveVisiblePromotedFieldPathsForEditorBlock, zl as TooltipTrigger, zn as listBlockDescriptors, zo as buildGoogleMapsDirectionsUrl, zr as getShopDisplayForItems, zs as parseBlockIconValue, zt as createRoutingHelpers, zu as __rest } from "./SiteChromeCustomizeContext-BQUY2dEk.mjs";
3
+ import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-RRu7wyQ5.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-a_cBD28m.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
@@ -1973,10 +1973,10 @@ function useBlockApi() {
1973
1973
  }
1974
1974
  //#endregion
1975
1975
  //#region ../blocks/src/primitives/layout/Section.tsx
1976
- const Section = forwardRef(function Section({ as: Comp = "section", children, background, className = "", allowOverflow = false, style, "data-slot": dataSlot }, ref) {
1976
+ const Section = forwardRef(function Section({ as: Comp = "section", children, background, className = "", style, "data-slot": dataSlot }, ref) {
1977
1977
  return /* @__PURE__ */ jsx(Comp, {
1978
1978
  ref,
1979
- className: clsx("rb-relative rb-isolate", allowOverflow ? "rb-overflow-visible" : "rb-overflow-hidden", className),
1979
+ className: clsx("rb-relative rb-isolate rb-overflow-visible", className),
1980
1980
  style: mergeStyles(typeof background === "string" && background.trim().length > 0 ? backgroundColorStyle(background.trim()) : void 0, style),
1981
1981
  "data-slot": dataSlot ?? "section",
1982
1982
  children
@@ -2097,10 +2097,7 @@ function Grid({ as: Comp = "div", cols = {
2097
2097
  }
2098
2098
  //#endregion
2099
2099
  //#region ../blocks/src/system/runtime/nodes/layout.tsx
2100
- const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, allowOverflow, ...props }) => /* @__PURE__ */ jsx(Section, {
2101
- ...props,
2102
- allowOverflow
2103
- });
2100
+ const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Section, { ...props });
2104
2101
  const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
2105
2102
  const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
2106
2103
  const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
@@ -2611,6 +2608,58 @@ function getCtaIconComponent(name) {
2611
2608
  return CTA_ICON_COMPONENTS[name] ?? null;
2612
2609
  }
2613
2610
  //#endregion
2611
+ //#region ../blocks/src/system/icons/social.tsx
2612
+ const SOCIAL_ICON_NAMES = [
2613
+ "SocialFacebook",
2614
+ "SocialInstagram",
2615
+ "SocialLinkedIn",
2616
+ "SocialTikTok",
2617
+ "SocialX",
2618
+ "SocialYouTube"
2619
+ ];
2620
+ const socialIcons = {
2621
+ SocialFacebook: createIcon("SocialFacebookIcon", /* @__PURE__ */ jsx("path", { d: "M14 8h3V4h-3c-3 0-5 2-5 5v3H6v4h3v6h4v-6h3l1-4h-4V9c0-.7.3-1 1-1Z" })),
2622
+ SocialInstagram: createIcon("SocialInstagramIcon", /* @__PURE__ */ jsxs(Fragment$1, { children: [
2623
+ /* @__PURE__ */ jsx("rect", {
2624
+ x: "3",
2625
+ y: "3",
2626
+ width: "18",
2627
+ height: "18",
2628
+ rx: "5"
2629
+ }),
2630
+ /* @__PURE__ */ jsx("circle", {
2631
+ cx: "12",
2632
+ cy: "12",
2633
+ r: "4"
2634
+ }),
2635
+ /* @__PURE__ */ jsx("circle", {
2636
+ cx: "17.5",
2637
+ cy: "6.5",
2638
+ r: ".75",
2639
+ fill: "currentColor",
2640
+ stroke: "none"
2641
+ })
2642
+ ] })),
2643
+ SocialLinkedIn: createIcon("SocialLinkedInIcon", /* @__PURE__ */ jsxs(Fragment$1, { children: [
2644
+ /* @__PURE__ */ jsx("path", { d: "M6 9v10" }),
2645
+ /* @__PURE__ */ jsx("path", {
2646
+ d: "M6 5.5v.01",
2647
+ strokeWidth: "3"
2648
+ }),
2649
+ /* @__PURE__ */ jsx("path", { d: "M10.5 19v-6a4 4 0 0 1 8 0v6" }),
2650
+ /* @__PURE__ */ jsx("path", { d: "M10.5 9v10" })
2651
+ ] })),
2652
+ SocialTikTok: createIcon("SocialTikTokIcon", /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("path", { d: "M14 4v11.5a4.5 4.5 0 1 1-4-4.47" }), /* @__PURE__ */ jsx("path", { d: "M14 4c.7 3 2.4 4.5 5 4.5" })] })),
2653
+ SocialX: createIcon("SocialXIcon", /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("path", { d: "m5 4 14 16" }), /* @__PURE__ */ jsx("path", { d: "M19 4 5 20" })] })),
2654
+ SocialYouTube: createIcon("SocialYouTubeIcon", /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("path", { d: "M21 12c0 3.5-.5 5.5-1.3 6.3S16.5 19.5 12 19.5s-6.9-.4-7.7-1.2S3 15.5 3 12s.5-5.5 1.3-6.3S7.5 4.5 12 4.5s6.9.4 7.7 1.2S21 8.5 21 12Z" }), /* @__PURE__ */ jsx("path", { d: "m10 9 5 3-5 3Z" })] }))
2655
+ };
2656
+ function isSocialIconName(value) {
2657
+ return typeof value === "string" && SOCIAL_ICON_NAMES.includes(value);
2658
+ }
2659
+ function getSocialIconComponent(value) {
2660
+ return isSocialIconName(value) ? socialIcons[value] : null;
2661
+ }
2662
+ //#endregion
2614
2663
  //#region ../blocks/src/system/icons/registry.ts
2615
2664
  function buildSearchText(parts) {
2616
2665
  return parts.map((part) => part.trim()).filter(Boolean).join(" ");
@@ -2646,10 +2695,10 @@ function getIconPickerOptionsForPreset(preset) {
2646
2695
  return ICON_PICKER_OPTIONS_BY_PRESET[preset];
2647
2696
  }
2648
2697
  function isKnownIconName(value) {
2649
- return isCtaIconName(value) || isSemanticIconId(value);
2698
+ return isCtaIconName(value) || isSemanticIconId(value) || isSocialIconName(value);
2650
2699
  }
2651
2700
  function getIconComponent(name) {
2652
- return getCtaIconComponent(name) ?? getSemanticIconComponent(name);
2701
+ return getCtaIconComponent(name) ?? getSemanticIconComponent(name) ?? getSocialIconComponent(name);
2653
2702
  }
2654
2703
  //#endregion
2655
2704
  //#region ../blocks/src/system/runtime/nodes/buttonAffordance.ts
@@ -2688,7 +2737,7 @@ function resolveButtonAffordance(input) {
2688
2737
  function coerceRichTextDoc(value) {
2689
2738
  const raw = unwrapRichTextRoot(value);
2690
2739
  if (typeof raw === "string") return createRichTextDocFromMarkdown(raw);
2691
- if (isRecord$20(raw) && typeof raw.type === "string") return raw;
2740
+ if (isRecord$21(raw) && typeof raw.type === "string") return raw;
2692
2741
  return null;
2693
2742
  }
2694
2743
  //#endregion
@@ -2832,7 +2881,7 @@ const IconNode = ({ value, title, className, blockId: _blockId, blockKind: _bloc
2832
2881
  };
2833
2882
  //#endregion
2834
2883
  //#region ../blocks/src/system/icons/generatedAssets.ts
2835
- function isRecord$18(value) {
2884
+ function isRecord$19(value) {
2836
2885
  return typeof value === "object" && value !== null && !Array.isArray(value);
2837
2886
  }
2838
2887
  function generatedIconAssetRefKey(ref) {
@@ -2842,11 +2891,11 @@ function collectGeneratedIconAssetRefs(page) {
2842
2891
  const blocks = [];
2843
2892
  for (const block of page.blocks) {
2844
2893
  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;
2894
+ const content = isRecord$19(block.draftContent) ? block.draftContent : isRecord$19(block.content) ? block.content : null;
2846
2895
  const cards = Array.isArray(content?.cards) ? content.cards : [];
2847
2896
  const refs = /* @__PURE__ */ new Map();
2848
2897
  for (const card of cards) {
2849
- if (!isRecord$18(card)) continue;
2898
+ if (!isRecord$19(card)) continue;
2850
2899
  const icon = parseBlockIconValue(card.icon);
2851
2900
  if (icon.kind !== "generated") continue;
2852
2901
  const ref = {
@@ -3537,7 +3586,6 @@ const HeaderSectionNode$1 = ({ blockId, children, className, "data-preview-site-
3537
3586
  const asProp = rest.as;
3538
3587
  const styleProp = rest.style;
3539
3588
  const backgroundProp = typeof rest.background === "string" ? rest.background : void 0;
3540
- const allowOverflowProp = typeof rest.allowOverflow === "boolean" ? rest.allowOverflow : void 0;
3541
3589
  const dataSlotProp = typeof rest["data-slot"] === "string" ? rest["data-slot"] : void 0;
3542
3590
  return /* @__PURE__ */ jsxs("nav", {
3543
3591
  ...getIslandRootProps("headerSection", blockId),
@@ -3552,7 +3600,6 @@ const HeaderSectionNode$1 = ({ blockId, children, className, "data-preview-site-
3552
3600
  as: asProp,
3553
3601
  style: styleProp,
3554
3602
  background: backgroundProp ?? "background",
3555
- allowOverflow: allowOverflowProp,
3556
3603
  "data-slot": dataSlotProp,
3557
3604
  className: sectionClasses || void 0,
3558
3605
  children
@@ -3613,6 +3660,26 @@ function SpinnerNode({ className, size = "md", color, strokeWidth = 3, srLabel,
3613
3660
  //#endregion
3614
3661
  //#region ../blocks/src/system/runtime/nodes/svg.tsx
3615
3662
  /**
3663
+ * Strict SVG-`transform` validator.
3664
+ *
3665
+ * Accepts only a whitespace/comma-separated list of the geometric transform
3666
+ * functions (`translate`/`rotate`/`scale`/`skewX`/`skewY`/`matrix`) whose
3667
+ * arguments are plain numbers. This deliberately rejects anything else —
3668
+ * `url(...)`, CSS functions, `javascript:`, angle/length units, stray letters —
3669
+ * so a persisted custom-block tree can't smuggle an executable or exfiltrating
3670
+ * value into the attribute.
3671
+ */
3672
+ const TRANSFORM_NUMBER = String.raw`-?(?:\d+\.?\d*|\.\d+)(?:e-?\d+)?`;
3673
+ const TRANSFORM_ARGS = String.raw`${TRANSFORM_NUMBER}(?:[\s,]+${TRANSFORM_NUMBER})*`;
3674
+ const TRANSFORM_FN = String.raw`(?:translate|rotate|scale|skewX|skewY|matrix)\(\s*${TRANSFORM_ARGS}\s*\)`;
3675
+ const SAFE_TRANSFORM_RE = new RegExp(String.raw`^\s*${TRANSFORM_FN}(?:[\s,]*${TRANSFORM_FN})*\s*$`);
3676
+ function safeTransform(value) {
3677
+ if (typeof value !== "string") return void 0;
3678
+ const trimmed = value.trim();
3679
+ if (trimmed.length === 0) return void 0;
3680
+ return SAFE_TRANSFORM_RE.test(trimmed) ? trimmed : void 0;
3681
+ }
3682
+ /**
3616
3683
  * Turn paint props into a CSS style object. Colour values pass through as-is so
3617
3684
  * they may reference theme tokens via `var()`, which only resolves in a CSS
3618
3685
  * property context (not in a bare presentation attribute).
@@ -3631,23 +3698,27 @@ function paintStyle(shape) {
3631
3698
  }
3632
3699
  function renderShape(shape, key) {
3633
3700
  const style = paintStyle(shape);
3701
+ const transform = safeTransform(shape.transform);
3634
3702
  switch (shape.kind) {
3635
3703
  case "path": return /* @__PURE__ */ jsx("path", {
3636
3704
  d: shape.d,
3637
- style
3705
+ style,
3706
+ transform
3638
3707
  }, key);
3639
3708
  case "ellipse": return /* @__PURE__ */ jsx("ellipse", {
3640
3709
  cx: shape.cx,
3641
3710
  cy: shape.cy,
3642
3711
  rx: shape.rx,
3643
3712
  ry: shape.ry,
3644
- style
3713
+ style,
3714
+ transform
3645
3715
  }, key);
3646
3716
  case "circle": return /* @__PURE__ */ jsx("circle", {
3647
3717
  cx: shape.cx,
3648
3718
  cy: shape.cy,
3649
3719
  r: shape.r,
3650
- style
3720
+ style,
3721
+ transform
3651
3722
  }, key);
3652
3723
  case "rect": return /* @__PURE__ */ jsx("rect", {
3653
3724
  x: shape.x,
@@ -3656,14 +3727,16 @@ function renderShape(shape, key) {
3656
3727
  height: shape.height,
3657
3728
  rx: shape.rx,
3658
3729
  ry: shape.ry,
3659
- style
3730
+ style,
3731
+ transform
3660
3732
  }, key);
3661
3733
  case "line": return /* @__PURE__ */ jsx("line", {
3662
3734
  x1: shape.x1,
3663
3735
  y1: shape.y1,
3664
3736
  x2: shape.x2,
3665
3737
  y2: shape.y2,
3666
- style
3738
+ style,
3739
+ transform
3667
3740
  }, key);
3668
3741
  default: return null;
3669
3742
  }
@@ -3859,12 +3932,12 @@ function resolveBookingSiteId(siteId, form) {
3859
3932
  return siteId || form?.siteId || "";
3860
3933
  }
3861
3934
  function normalizeBookingFormConfig(form) {
3862
- if (!isRecord$17(form)) return null;
3935
+ if (!isRecord$18(form)) return null;
3863
3936
  const id = readNonEmptyString(form.id);
3864
3937
  const name = readNonEmptyString(form.name);
3865
3938
  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;
3939
+ const schemaSource = isRecord$18(form.schema) ? form.schema : isRecord$18(form.schemaJson) ? form.schemaJson : null;
3940
+ const settingsSource = isRecord$18(form.settings) ? form.settings : isRecord$18(form.settingsJson) ? form.settingsJson : null;
3868
3941
  return {
3869
3942
  id,
3870
3943
  name,
@@ -3884,8 +3957,8 @@ function normalizeBookingServices(services) {
3884
3957
  };
3885
3958
  if (!services) return [];
3886
3959
  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) : [];
3960
+ if (isRecord$18(services) && "services" in services) return Array.isArray(services.services) ? services.services.filter(isBookingFormService).map(normalizeService) : [];
3961
+ return isRecord$18(services) ? Object.values(services).filter(isBookingFormService).map(normalizeService) : [];
3889
3962
  }
3890
3963
  function normalizeBookingSchema(value) {
3891
3964
  if (!value) return void 0;
@@ -3896,7 +3969,7 @@ function normalizeBookingSchema(value) {
3896
3969
  };
3897
3970
  }
3898
3971
  function readBookingFormField(value) {
3899
- if (!isRecord$17(value)) return null;
3972
+ if (!isRecord$18(value)) return null;
3900
3973
  const id = readNonEmptyString(value.id);
3901
3974
  const label = readNonEmptyString(value.label);
3902
3975
  const type = readBookingFieldType(value.type);
@@ -3940,7 +4013,7 @@ function readBookingFieldOptions(value) {
3940
4013
  return options.length > 0 ? options : void 0;
3941
4014
  }
3942
4015
  function readBookingFieldOption(value) {
3943
- if (!isRecord$17(value)) return null;
4016
+ if (!isRecord$18(value)) return null;
3944
4017
  const optionValue = readNonEmptyString(value.value);
3945
4018
  const label = readNonEmptyString(value.label);
3946
4019
  return optionValue && label ? {
@@ -3960,7 +4033,7 @@ function normalizeBookingSettings(value) {
3960
4033
  };
3961
4034
  }
3962
4035
  function isBookingFormService(value) {
3963
- return isRecord$17(value) && typeof value.id === "string" && typeof value.siteId === "string" && typeof value.title === "string";
4036
+ return isRecord$18(value) && typeof value.id === "string" && typeof value.siteId === "string" && typeof value.title === "string";
3964
4037
  }
3965
4038
  function collectBookingCustomFields(data) {
3966
4039
  const customFields = {};
@@ -4010,7 +4083,7 @@ function readStringArray(value) {
4010
4083
  const strings = value.filter((item) => typeof item === "string");
4011
4084
  return strings.length > 0 ? strings : void 0;
4012
4085
  }
4013
- function isRecord$17(value) {
4086
+ function isRecord$18(value) {
4014
4087
  return typeof value === "object" && value !== null;
4015
4088
  }
4016
4089
  function getBookingServicePaymentSelectionMode(service) {
@@ -5407,7 +5480,7 @@ function EventDetailsView({ selection, showVenue, showMap, showOtherDates, showC
5407
5480
  className: "rb-mt-6",
5408
5481
  children: [/* @__PURE__ */ jsx("div", {
5409
5482
  className: "rb-label rb-mb-2",
5410
- children: "Team members"
5483
+ children: "With"
5411
5484
  }), /* @__PURE__ */ jsx("div", {
5412
5485
  className: "rb-flex rb-flex-col rb-gap-3",
5413
5486
  children: teamMembers.map((teamMember) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(TeamMemberName$1, {
@@ -5624,6 +5697,34 @@ function LocationMapSSR(props) {
5624
5697
  });
5625
5698
  }
5626
5699
  //#endregion
5700
+ //#region ../blocks/src/system/runtime/nodes/course-page-surface-scope.ts
5701
+ /**
5702
+ * Resolves native course-page ownership without falling back to entry or slug
5703
+ * coincidence when a page-surface subject is present but invalid.
5704
+ */
5705
+ function resolveCoursePageSurfaceScope(courses, subjectValue) {
5706
+ if (subjectValue === null || subjectValue === void 0) return { kind: "absent" };
5707
+ const parsed = parseEventPageSurfaceSubject(subjectValue);
5708
+ if (!parsed.ok) return {
5709
+ kind: "unsupported",
5710
+ reason: parsed.error.kind
5711
+ };
5712
+ const seriesIds = eventSeriesIdsForSubject(parsed.value);
5713
+ const allowedSeriesIds = new Set(seriesIds);
5714
+ return {
5715
+ kind: "scoped",
5716
+ subject: parsed.value,
5717
+ courses: courses.filter((course) => allowedSeriesIds.has(course.seriesId))
5718
+ };
5719
+ }
5720
+ function eventSeriesIdsForSubject(subject) {
5721
+ switch (subject.kind) {
5722
+ case "eventSeries": return [subject.eventSeriesId];
5723
+ case "eventOffering": return subject.availableEventSeriesIds;
5724
+ default: return assertNever$5(subject);
5725
+ }
5726
+ }
5727
+ //#endregion
5627
5728
  //#region ../blocks/src/system/runtime/nodes/course-details/logic.ts
5628
5729
  function coerceContentEntry(value) {
5629
5730
  if (!value || typeof value !== "object") return null;
@@ -5661,6 +5762,20 @@ function selectCourseDetails(args) {
5661
5762
  scoped: [byCourseId]
5662
5763
  };
5663
5764
  }
5765
+ const pageSurfaceScope = resolveCoursePageSurfaceScope(courses, args.subject);
5766
+ if (pageSurfaceScope.kind === "unsupported") return {
5767
+ mode: "unsupportedPageSurfaceSubject",
5768
+ selected: null,
5769
+ scoped: []
5770
+ };
5771
+ if (pageSurfaceScope.kind === "scoped") {
5772
+ const scoped = [...pageSurfaceScope.courses];
5773
+ return {
5774
+ mode: "pageSurfaceSubject",
5775
+ selected: scoped.length === 1 ? scoped[0] ?? null : null,
5776
+ scoped
5777
+ };
5778
+ }
5664
5779
  if (contentEntry?.id) {
5665
5780
  const scoped = courses.filter((c) => c.contentEntryId === contentEntry.id);
5666
5781
  if (scoped.length === 1) return {
@@ -5775,10 +5890,10 @@ function parseLimit(value, fallback) {
5775
5890
  return Number.isFinite(n) && n > 0 ? n : fallback;
5776
5891
  }
5777
5892
  function CourseDetailsView(props) {
5778
- const { course, showTitle = false, showDescription = false, showSessions = true, sessionsLimit, showVenue = true, showPrice = true, showCapacity = true, showEnrollmentStatus = true, showMembershipNote = true } = props;
5893
+ 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
5894
  if (!course) return /* @__PURE__ */ jsx("p", {
5780
5895
  className: "rb-caption status-muted",
5781
- children: "Course details unavailable."
5896
+ children: emptyMessage
5782
5897
  });
5783
5898
  const pricing = resolveCoursePricingState(course);
5784
5899
  const sessionLimit = parseLimit(sessionsLimit, 10);
@@ -5823,7 +5938,7 @@ function CourseDetailsView(props) {
5823
5938
  })] }),
5824
5939
  teamMembers.length > 0 && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
5825
5940
  className: "rb-label rb-mb-2",
5826
- children: "Team members"
5941
+ children: "With"
5827
5942
  }), /* @__PURE__ */ jsx("div", {
5828
5943
  className: "rb-flex rb-flex-col rb-gap-3",
5829
5944
  children: teamMembers.map((teamMember) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(TeamMemberName, {
@@ -5891,13 +6006,16 @@ function CourseDetailsView(props) {
5891
6006
  }
5892
6007
  //#endregion
5893
6008
  //#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 }) {
6009
+ function CourseDetailsSSR({ courses, contentEntry, entrySubrouteContext, subject, courseSlug, showTitle, showDescription, showSessions, sessionsLimit, showVenue, showPrice, showCapacity, showEnrollmentStatus, showMembershipNote, className, children }) {
5895
6010
  const selection = selectCourseDetails({
5896
6011
  courses: courses ?? null,
5897
6012
  contentEntry,
5898
6013
  entrySubrouteContext,
6014
+ subject,
5899
6015
  courseSlug
5900
6016
  });
6017
+ const parsedSubject = parseEventPageSurfaceSubject(subject);
6018
+ const awaitingOfferingRuns = parsedSubject.ok && parsedSubject.value.kind === "eventOffering" && parsedSubject.value.availableEventSeriesIds.length === 0;
5901
6019
  const basePath = getEntryBasePath(contentEntry);
5902
6020
  const now = /* @__PURE__ */ new Date();
5903
6021
  const scopedWithRange = selection.scoped.map((c) => ({
@@ -5984,6 +6102,7 @@ function CourseDetailsSSR({ courses, contentEntry, entrySubrouteContext, courseS
5984
6102
  ]
5985
6103
  }) : /* @__PURE__ */ jsx(CourseDetailsView, {
5986
6104
  course: null,
6105
+ emptyMessage: awaitingOfferingRuns ? "New dates are coming soon." : "Course details unavailable.",
5987
6106
  showTitle,
5988
6107
  showDescription,
5989
6108
  showSessions,
@@ -6614,6 +6733,102 @@ const EventCombinedSSR = ({ blockId, ...source }) => {
6614
6733
  });
6615
6734
  };
6616
6735
  //#endregion
6736
+ //#region ../blocks/src/system/blocks/offerings-preview/scheduleSummary.ts
6737
+ function deriveEventScheduleSummary(event) {
6738
+ const occurrence = occurrenceFromEvent(event);
6739
+ return localDayNumber(occurrence.endsAt, occurrence.timeZone) > localDayNumber(occurrence.startsAt, occurrence.timeZone) ? {
6740
+ kind: "multi-day-span",
6741
+ occurrence
6742
+ } : {
6743
+ kind: "single-occurrence",
6744
+ occurrence
6745
+ };
6746
+ }
6747
+ function deriveCourseScheduleSummary(course) {
6748
+ const sessions = [...course.sessions].filter(isValidOccurrence).sort((left, right) => left.startsAt.localeCompare(right.startsAt));
6749
+ const first = sessions[0];
6750
+ if (!first) return null;
6751
+ if (sessions.length === 1) return deriveEventScheduleSummary(first);
6752
+ const last = sessions[sessions.length - 1];
6753
+ if (!last) return null;
6754
+ const recurrence = deriveFixedRecurrence(sessions);
6755
+ return recurrence ? {
6756
+ kind: "fixed-recurring-run",
6757
+ first,
6758
+ last,
6759
+ sessionCount: sessions.length,
6760
+ recurrenceLabel: recurrence
6761
+ } : {
6762
+ kind: "irregular-multi-session-run",
6763
+ first,
6764
+ last,
6765
+ sessionCount: sessions.length
6766
+ };
6767
+ }
6768
+ function nextCourseSessionStart(course) {
6769
+ return [...course.sessions].filter(isValidOccurrence).map((session) => session.startsAt).sort((left, right) => left.localeCompare(right))[0] ?? null;
6770
+ }
6771
+ function occurrenceFromEvent(event) {
6772
+ return {
6773
+ startsAt: event.startsAt,
6774
+ endsAt: event.endsAt,
6775
+ timeZone: event.timeZone
6776
+ };
6777
+ }
6778
+ function deriveFixedRecurrence(sessions) {
6779
+ const [first, second] = sessions;
6780
+ if (!first || !second) return null;
6781
+ if (!sessions.every((session) => sameLocalTime(first, session))) return null;
6782
+ const intervalDays = localDayNumber(second.startsAt, second.timeZone) - localDayNumber(first.startsAt, first.timeZone);
6783
+ if (intervalDays <= 0) return null;
6784
+ for (let index = 2; index < sessions.length; index += 1) {
6785
+ const previous = sessions[index - 1];
6786
+ const current = sessions[index];
6787
+ if (!previous || !current) return null;
6788
+ if (localDayNumber(current.startsAt, current.timeZone) - localDayNumber(previous.startsAt, previous.timeZone) !== intervalDays) return null;
6789
+ }
6790
+ if (intervalDays === 1) return "Every day";
6791
+ const weekday = localDateParts(first.startsAt, first.timeZone).weekday;
6792
+ if (intervalDays === 7) return `Every ${weekday}`;
6793
+ if (intervalDays % 7 === 0) return `Every ${intervalDays / 7} weeks on ${weekday}`;
6794
+ return `Every ${intervalDays} days`;
6795
+ }
6796
+ function sameLocalTime(reference, candidate) {
6797
+ const referenceStart = localDateParts(reference.startsAt, reference.timeZone);
6798
+ const candidateStart = localDateParts(candidate.startsAt, candidate.timeZone);
6799
+ const referenceEnd = localDateParts(reference.endsAt, reference.timeZone);
6800
+ const candidateEnd = localDateParts(candidate.endsAt, candidate.timeZone);
6801
+ return referenceStart.hour === candidateStart.hour && referenceStart.minute === candidateStart.minute && referenceEnd.hour === candidateEnd.hour && referenceEnd.minute === candidateEnd.minute;
6802
+ }
6803
+ function isValidOccurrence(value) {
6804
+ return Number.isFinite(Date.parse(value.startsAt)) && Number.isFinite(Date.parse(value.endsAt));
6805
+ }
6806
+ function localDayNumber(isoTimestamp, timeZone) {
6807
+ const parts = localDateParts(isoTimestamp, timeZone);
6808
+ return Math.floor(Date.UTC(parts.year, parts.month - 1, parts.day) / 864e5);
6809
+ }
6810
+ function localDateParts(isoTimestamp, timeZone) {
6811
+ const parts = new Intl.DateTimeFormat("en-GB", {
6812
+ timeZone,
6813
+ year: "numeric",
6814
+ month: "numeric",
6815
+ day: "numeric",
6816
+ hour: "2-digit",
6817
+ minute: "2-digit",
6818
+ hourCycle: "h23",
6819
+ weekday: "long"
6820
+ }).formatToParts(new Date(isoTimestamp));
6821
+ const value = (type) => parts.find((part) => part.type === type)?.value ?? "";
6822
+ return {
6823
+ year: Number(value("year")),
6824
+ month: Number(value("month")),
6825
+ day: Number(value("day")),
6826
+ hour: Number(value("hour")),
6827
+ minute: Number(value("minute")),
6828
+ weekday: value("weekday")
6829
+ };
6830
+ }
6831
+ //#endregion
6617
6832
  //#region ../blocks/src/system/runtime/nodes/offerings-preview.tsx
6618
6833
  function OfferingsPreviewNode(props) {
6619
6834
  const groups = resolveOfferingsPreviewGroups({
@@ -6635,75 +6850,71 @@ function OfferingsPreviewNode(props) {
6635
6850
  if (states.length === 0) return null;
6636
6851
  const buttonVariant = props.buttonVariant ?? "primary";
6637
6852
  const buttonText = props.buttonText ?? "Book";
6638
- const blockCta = resolveOfferingsPreviewBlockCta(states, props.routeCandidates?.routes ?? []);
6639
- const blockLinkClass = themeButtonClassName({
6640
- variant: "link",
6853
+ const routeCandidates = props.routeCandidates?.routes ?? [];
6854
+ const groupLinkClass = themeButtonClassName({
6855
+ variant: buttonVariant,
6641
6856
  size: "md",
6642
- extraClassName: "offerings-preview-link rb-inline-flex rb-items-center rb-gap-2"
6857
+ extraClassName: "offerings-preview-card-link rb-inline-flex rb-items-center rb-gap-2"
6643
6858
  });
6644
6859
  const groupFrame = resolveGroupFrame(props.cardStyles);
6645
- return /* @__PURE__ */ jsxs("div", {
6860
+ return /* @__PURE__ */ jsx("div", {
6646
6861
  className: "offerings-preview rb-flex rb-flex-col rb-gap-6",
6647
6862
  "data-block": "offerings-preview",
6648
- children: [/* @__PURE__ */ jsx("div", {
6863
+ children: /* @__PURE__ */ jsx("div", {
6649
6864
  className: "offerings-preview-grid rb-grid rb-items-stretch rb-gap-6",
6650
6865
  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
- })]
6866
+ children: states.map((state) => {
6867
+ const groupCta = resolveOfferingsPreviewGroupCta({
6868
+ group: state.group,
6869
+ routes: routeCandidates
6870
+ });
6871
+ return /* @__PURE__ */ jsx("section", {
6872
+ className: groupFrame.containerClassName,
6873
+ style: groupFrame.containerStyle,
6874
+ "data-offering-presentation": state.group.presentation,
6875
+ "data-offering-source": state.group.sourceKey,
6876
+ children: /* @__PURE__ */ jsxs("div", {
6877
+ className: groupFrame.contentClassName,
6878
+ children: [
6879
+ /* @__PURE__ */ jsxs("header", {
6880
+ className: "offerings-preview-card-header rb-flex rb-flex-col rb-gap-2 rb-text-center",
6881
+ children: [/* @__PURE__ */ jsx("h3", {
6882
+ className: "offerings-preview-card-title rb-text-xl rb-font-semibold rb-leading-tight",
6883
+ children: state.group.title
6884
+ }), state.group.intro ? /* @__PURE__ */ jsx("p", {
6885
+ className: "offerings-preview-card-intro rb-text-sm rb-leading-6 status-muted",
6886
+ children: state.group.intro
6887
+ }) : null]
6888
+ }),
6889
+ state.kind === "items" ? renderOfferingGroupItems(state.group.presentation, state.items, {
6890
+ buttonVariant,
6891
+ buttonText
6892
+ }) : /* @__PURE__ */ jsx(EmptyState$1, {
6893
+ className: "offerings-preview-card-empty",
6894
+ message: state.message
6895
+ }),
6896
+ groupCta ? /* @__PURE__ */ jsx("footer", {
6897
+ className: "offerings-preview-card-footer rb-mt-auto rb-flex",
6898
+ children: /* @__PURE__ */ jsxs("a", {
6899
+ className: groupLinkClass,
6900
+ href: groupCta.href,
6901
+ children: [/* @__PURE__ */ jsx("span", { children: groupCta.label }), /* @__PURE__ */ jsx(ArrowRightIcon, {
6902
+ "aria-hidden": "true",
6903
+ className: "offerings-preview-link-icon rb-h-4 rb-w-4"
6904
+ })]
6905
+ })
6906
+ }) : null
6907
+ ]
6908
+ })
6909
+ }, state.group.sourceKey);
6683
6910
  })
6684
- }) : null]
6911
+ })
6685
6912
  });
6686
6913
  }
6687
6914
  const OFFERINGS_PREVIEW_GRID_STYLE = {
6688
6915
  gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 20rem), min(24rem, 100%)))",
6689
6916
  justifyContent: "center"
6690
6917
  };
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
6918
  function buildItemDataMap(props) {
6708
6919
  const routeCandidates = props.routeCandidates?.routes ?? [];
6709
6920
  const entries = OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => [definition.sourceKey, eventDataFromMaybeArray(props[definition.dataKey])]);
@@ -6724,7 +6935,7 @@ function eventDataFromMaybeArray(events) {
6724
6935
  function courseDataFromMaybeArray(courses, routes) {
6725
6936
  return courses ? {
6726
6937
  kind: "ready",
6727
- items: courses.map((course) => ({
6938
+ items: [...courses].sort(compareCoursesByNextSession).map((course) => ({
6728
6939
  kind: "course",
6729
6940
  course,
6730
6941
  path: resolveOfferingsPreviewCoursePath(course, routes)
@@ -6735,21 +6946,113 @@ function courseDataFromMaybeArray(courses, routes) {
6735
6946
  };
6736
6947
  }
6737
6948
  function renderOfferingGroupItems(presentation, items, options) {
6738
- if (presentation === "single-card") {
6739
- const item = items[0];
6740
- return /* @__PURE__ */ jsx("div", {
6949
+ switch (presentation) {
6950
+ case "single-card": {
6951
+ const item = items[0];
6952
+ return /* @__PURE__ */ jsx("div", {
6953
+ className: "offerings-preview-card-items rb-flex rb-flex-1 rb-flex-col",
6954
+ children: item ? renderSingleOfferingCard(item, options) : null
6955
+ });
6956
+ }
6957
+ case "featured-summary": {
6958
+ const item = items[0];
6959
+ return /* @__PURE__ */ jsx("div", {
6960
+ className: "offerings-preview-card-items offerings-preview-summary-items rb-flex rb-flex-1 rb-flex-col",
6961
+ children: item ? /* @__PURE__ */ jsx(FeaturedOfferingSummary, { item }) : null
6962
+ });
6963
+ }
6964
+ case "compact-list": return /* @__PURE__ */ jsx("div", {
6741
6965
  className: "offerings-preview-card-items rb-flex rb-flex-1 rb-flex-col",
6742
- children: item ? renderSingleOfferingCard(item, options) : null
6966
+ children: /* @__PURE__ */ jsx("div", {
6967
+ className: "event-listing-compact-container rb-flex rb-flex-1 rb-flex-col",
6968
+ children: items.map((item) => renderOfferingCompactItem(item, options))
6969
+ })
6743
6970
  });
6971
+ default: return assertNever$5(presentation, "Unhandled offerings preview presentation");
6744
6972
  }
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
- })
6973
+ }
6974
+ function compareCoursesByNextSession(left, right) {
6975
+ const leftStart = nextCourseSessionStart(left);
6976
+ const rightStart = nextCourseSessionStart(right);
6977
+ if (leftStart === null) return rightStart === null ? 0 : 1;
6978
+ if (rightStart === null) return -1;
6979
+ return leftStart.localeCompare(rightStart);
6980
+ }
6981
+ function FeaturedOfferingSummary({ item }) {
6982
+ const details = featuredSummaryDetails(item);
6983
+ if (!details) return null;
6984
+ return /* @__PURE__ */ jsxs("article", {
6985
+ className: "offerings-preview-summary rb-flex rb-flex-1 rb-flex-col",
6986
+ children: [/* @__PURE__ */ jsxs("p", {
6987
+ className: "offerings-preview-summary-date",
6988
+ children: [/* @__PURE__ */ jsx("time", {
6989
+ dateTime: details.startDateTime,
6990
+ children: details.startDate
6991
+ }), details.endDate ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
6992
+ "aria-hidden": "true",
6993
+ children: " – "
6994
+ }), /* @__PURE__ */ jsx("time", {
6995
+ dateTime: details.endDateTime,
6996
+ children: details.endDate
6997
+ })] }) : null]
6998
+ }), /* @__PURE__ */ jsxs("dl", {
6999
+ className: "offerings-preview-summary-facts",
7000
+ children: [
7001
+ details.recurrence ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Repeats" }), /* @__PURE__ */ jsx("dd", { children: details.recurrence })] }) : null,
7002
+ details.sessionCount ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Sessions" }), /* @__PURE__ */ jsx("dd", { children: details.sessionCount })] }) : null,
7003
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Time" }), /* @__PURE__ */ jsx("dd", { children: details.timeRange })] }),
7004
+ details.venue ? /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Venue" }), /* @__PURE__ */ jsx("dd", { children: details.venue })] }) : null
7005
+ ]
7006
+ })]
6751
7007
  });
6752
7008
  }
7009
+ function featuredSummaryDetails(item) {
7010
+ switch (item.kind) {
7011
+ case "event": return formatFeaturedSummary(deriveEventScheduleSummary(item.event), item.event.venue?.name ?? null);
7012
+ case "course": {
7013
+ const summary = deriveCourseScheduleSummary(item.course);
7014
+ return summary ? formatFeaturedSummary(summary, item.course.venue?.name ?? null) : null;
7015
+ }
7016
+ default: return assertNever$5(item, "Unhandled offerings preview item");
7017
+ }
7018
+ }
7019
+ function formatFeaturedSummary(summary, venue) {
7020
+ switch (summary.kind) {
7021
+ case "single-occurrence": return detailsFromOccurrences(summary.occurrence, null, venue, null, null);
7022
+ case "multi-day-span": return detailsFromOccurrences(summary.occurrence, summary.occurrence, venue, null, null, true);
7023
+ case "fixed-recurring-run": return detailsFromOccurrences(summary.first, summary.last, venue, summary.recurrenceLabel, null);
7024
+ case "irregular-multi-session-run": return detailsFromOccurrences(summary.first, summary.last, venue, null, `${summary.sessionCount} dates`);
7025
+ default: return assertNever$5(summary, "Unhandled offerings preview schedule summary");
7026
+ }
7027
+ }
7028
+ function detailsFromOccurrences(first, last, venue, recurrence, sessionCount, spanUsesEndDate = false) {
7029
+ const endDateTime = spanUsesEndDate ? first.endsAt : last?.startsAt ?? first.startsAt;
7030
+ return {
7031
+ startDate: formatSummaryDate(first.startsAt, first.timeZone),
7032
+ startDateTime: first.startsAt,
7033
+ endDate: last ? formatSummaryDate(endDateTime, last.timeZone) : null,
7034
+ endDateTime,
7035
+ timeRange: `${formatTime$3(first.startsAt, {
7036
+ timeZone: first.timeZone,
7037
+ locale: "en-GB"
7038
+ })} – ${formatTime$3(first.endsAt, {
7039
+ timeZone: first.timeZone,
7040
+ locale: "en-GB"
7041
+ })}`,
7042
+ recurrence,
7043
+ sessionCount,
7044
+ venue
7045
+ };
7046
+ }
7047
+ function formatSummaryDate(isoTimestamp, timeZone) {
7048
+ return new Intl.DateTimeFormat("en-GB", {
7049
+ timeZone,
7050
+ weekday: "long",
7051
+ day: "numeric",
7052
+ month: "long",
7053
+ year: "numeric"
7054
+ }).format(new Date(isoTimestamp));
7055
+ }
6753
7056
  function renderOfferingCompactItem(item, options) {
6754
7057
  switch (item.kind) {
6755
7058
  case "event": return /* @__PURE__ */ jsx(EventCompactRow, {
@@ -6936,7 +7239,7 @@ function resolveGroupFrame(cardStyles) {
6936
7239
  contentClassName: "offerings-preview-card-content rb-flex rb-h-full rb-min-h-full rb-flex-col rb-gap-5"
6937
7240
  };
6938
7241
  return {
6939
- containerClassName: ["offerings-preview-card offerings-preview-card--framed rb-relative rb-isolate rb-h-full rb-min-h-full rb-overflow-hidden rb-bg-surface rb-border rb-border-border", resolveGroupFrameClasses(cardStyles)].filter(Boolean).join(" "),
7242
+ containerClassName: ["offerings-preview-card offerings-preview-card--framed rb-relative rb-isolate rb-h-full rb-min-h-full rb-overflow-visible rb-bg-surface rb-border rb-border-border", resolveGroupFrameClasses(cardStyles)].filter(Boolean).join(" "),
6940
7243
  containerStyle: resolveGroupFrameStyle(cardStyles),
6941
7244
  contentClassName: "card-content offerings-preview-card-content rb-flex rb-h-full rb-min-h-full rb-flex-col rb-gap-5"
6942
7245
  };
@@ -7089,6 +7392,100 @@ function WeeklySlotAvailabilitySSR(props) {
7089
7392
  return /* @__PURE__ */ jsx(WeeklySlotAvailabilityView, { ...props });
7090
7393
  }
7091
7394
  //#endregion
7395
+ //#region ../blocks/src/system/runtime/nodes/events/RecurringSchedule.tsx
7396
+ function destinationHref(destination) {
7397
+ return destination.kind === "external" ? destination.url : destination.path;
7398
+ }
7399
+ function bookingLinkProps(booking) {
7400
+ return booking.destination.kind === "external" ? {
7401
+ href: destinationHref(booking.destination),
7402
+ target: "_blank",
7403
+ rel: "noopener noreferrer"
7404
+ } : { href: destinationHref(booking.destination) };
7405
+ }
7406
+ function bookingActionContent(input) {
7407
+ switch (input.booking.kind) {
7408
+ case "available": return /* @__PURE__ */ jsx(ButtonNode, {
7409
+ ...bookingLinkProps(input.booking),
7410
+ "aria-label": input.accessibleName,
7411
+ className: "recurring-schedule-book",
7412
+ linkRequired: true,
7413
+ variantId: input.buttonVariant,
7414
+ size: "sm",
7415
+ children: input.buttonText
7416
+ });
7417
+ case "unavailable": return null;
7418
+ default: return assertNever$5(input.booking);
7419
+ }
7420
+ }
7421
+ function RecurringSchedule({ schedule, buttonText = "Book", buttonVariant = "primary", showVenue = true, emptyMessage = "Regular schedule details will be added shortly." }) {
7422
+ const projection = schedule ?? {
7423
+ items: [],
7424
+ diagnostics: []
7425
+ };
7426
+ if (projection.items.length === 0) return /* @__PURE__ */ jsx("p", {
7427
+ className: "recurring-schedule-empty",
7428
+ "data-diagnostic-count": projection.diagnostics.length,
7429
+ children: emptyMessage
7430
+ });
7431
+ const renderRow = (item) => {
7432
+ const rowContent = /* @__PURE__ */ jsxs(Fragment$1, { children: [
7433
+ /* @__PURE__ */ jsx("p", {
7434
+ className: "recurring-schedule-day",
7435
+ children: item.cadence.weekday
7436
+ }),
7437
+ /* @__PURE__ */ jsxs("p", {
7438
+ className: "recurring-schedule-time",
7439
+ children: [
7440
+ /* @__PURE__ */ jsx("time", {
7441
+ dateTime: item.cadence.startTime,
7442
+ children: item.cadence.startTime
7443
+ }),
7444
+ /* @__PURE__ */ jsx("span", {
7445
+ "aria-hidden": "true",
7446
+ children: "–"
7447
+ }),
7448
+ /* @__PURE__ */ jsx("time", {
7449
+ dateTime: item.cadence.endTime,
7450
+ children: item.cadence.endTime
7451
+ })
7452
+ ]
7453
+ }),
7454
+ /* @__PURE__ */ jsxs("div", {
7455
+ className: "recurring-schedule-details",
7456
+ children: [/* @__PURE__ */ jsx("p", {
7457
+ className: "recurring-schedule-title",
7458
+ children: item.title
7459
+ }), showVenue && item.venueName ? /* @__PURE__ */ jsx("p", {
7460
+ className: "recurring-schedule-venue",
7461
+ children: item.venueName
7462
+ }) : null]
7463
+ }),
7464
+ /* @__PURE__ */ jsx("div", {
7465
+ className: "recurring-schedule-action",
7466
+ children: bookingActionContent({
7467
+ booking: item.booking,
7468
+ buttonVariant: buttonVariant ?? "primary",
7469
+ buttonText: buttonText ?? "Book",
7470
+ accessibleName: `${buttonText ?? "Book"} ${item.title}, ${item.cadence.weekday} at ${item.cadence.startTime}`
7471
+ })
7472
+ })
7473
+ ] });
7474
+ return /* @__PURE__ */ jsx("article", {
7475
+ className: "recurring-schedule-row",
7476
+ role: "listitem",
7477
+ "aria-label": `${item.title}, ${item.cadence.weekday} at ${item.cadence.startTime}`,
7478
+ children: rowContent
7479
+ });
7480
+ };
7481
+ return /* @__PURE__ */ jsx("div", {
7482
+ className: "recurring-schedule",
7483
+ "data-diagnostic-count": projection.diagnostics.length,
7484
+ role: "list",
7485
+ children: projection.items.map((item) => /* @__PURE__ */ jsx(React.Fragment, { children: renderRow(item) }, item.seriesId))
7486
+ });
7487
+ }
7488
+ //#endregion
7092
7489
  //#region ../blocks/src/system/node/fragments/headingDecoration.ts
7093
7490
  const defaultBindFrom = "_sectionStyles.headingDecoration";
7094
7491
  function headingDecoration({ bindFrom = defaultBindFrom, className } = {}) {
@@ -7104,6 +7501,39 @@ function headingDecoration({ bindFrom = defaultBindFrom, className } = {}) {
7104
7501
  } } })], when(`${bindFrom}.family`));
7105
7502
  }
7106
7503
  //#endregion
7504
+ //#region ../blocks/src/system/fragments/library/footerBottomText.ts
7505
+ const footerBottomTextFragment = defineFragment({
7506
+ id: "footerBottomText",
7507
+ title: "Footer Text",
7508
+ description: "Rich text content for the main footer body and optional bottom bar.",
7509
+ fields: [{
7510
+ id: "bodyText",
7511
+ type: "richText",
7512
+ label: "Body text",
7513
+ description: "Appears in the main footer area.",
7514
+ ui: { variant: "limited" }
7515
+ }, {
7516
+ id: "bottomText",
7517
+ type: "richText",
7518
+ label: "Bottom bar text",
7519
+ description: "Appears in the optional footer bottom bar.",
7520
+ ui: { variant: "limited" }
7521
+ }],
7522
+ layout: [richText({
7523
+ className: "rb-prose rb-prose-sm rb-mx-auto rb-max-w-3xl rb-text-center",
7524
+ style: textColorStyle("text/80")
7525
+ }, when("bodyText"), bind("bodyText", { transforms: [{
7526
+ id: "content.interpolateRichTextTokens",
7527
+ options: { tokens: ["year", "site_name"] }
7528
+ }] })), richText({
7529
+ className: "rb-prose rb-prose-sm rb-mx-auto rb-max-w-3xl rb-text-center",
7530
+ style: textColorStyle("text/80")
7531
+ }, when("bottomText"), bind("bottomText", { transforms: [{
7532
+ id: "content.interpolateRichTextTokens",
7533
+ options: { tokens: ["year", "site_name"] }
7534
+ }] }))]
7535
+ });
7536
+ //#endregion
7107
7537
  //#region ../blocks/src/system/fragments/library/headerCta.ts
7108
7538
  const headerCtaFragment = defineFragment({
7109
7539
  id: "headerCta",
@@ -7649,13 +8079,14 @@ function CheckoutSSR({ blockId, siteId, apiBaseUrl, stage, children, ...rest })
7649
8079
  * Server-safe placeholder for course registration.
7650
8080
  * Provides a static container for island hydration without importing client hooks.
7651
8081
  */
7652
- function CourseRegistrationSSR({ blockId, siteId, apiBaseUrl, portalToken, contentEntry, entrySubrouteContext, courses, className, showSessions, showPrice, showCapacity, showVenue, successMessage, waitlistMessage, membershipMessage, buttonText, buttonVariant, stage, children }) {
8082
+ function CourseRegistrationSSR({ blockId, siteId, apiBaseUrl, portalToken, contentEntry, entrySubrouteContext, subject, courses, className, showSessions, showPrice, showCapacity, showVenue, successMessage, waitlistMessage, membershipMessage, buttonText, buttonVariant, stage, children }) {
7653
8083
  const islandProps = buildCourseRegistrationInteractiveIslandProps({
7654
8084
  siteId,
7655
8085
  apiBaseUrl,
7656
8086
  portalToken,
7657
8087
  contentEntry,
7658
8088
  entrySubrouteContext,
8089
+ subject,
7659
8090
  courses,
7660
8091
  className,
7661
8092
  showSessions,
@@ -8028,26 +8459,33 @@ const WeekBoardCard = ({ event, showCapacity }) => {
8028
8459
  * to a stacked list on mobile. Repurposes the week-grouped agenda data as a
8029
8460
  * board rather than an hour-positioned timetable grid.
8030
8461
  */
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" }) => {
8462
+ 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
8463
  const eventsByDate = groupEventsByDate(events);
8033
8464
  const hasAnyEvents = days.some((date) => (eventsByDate.get(formatDateKey(date)) ?? []).length > 0);
8034
8465
  const ctaClassName = themeButtonClassName({
8035
8466
  variant: buttonVariant,
8036
8467
  size: "sm"
8037
8468
  });
8469
+ const hasTitle = typeof title === "string" && title.length > 0;
8470
+ const hasFooterNote = typeof footerNote === "string" && footerNote.length > 0;
8471
+ const hasCta = typeof ctaHref === "string" && ctaHref.length > 0;
8472
+ const footerNoteText = hasAnyEvents ? hasFooterNote ? footerNote : null : emptyMessage;
8473
+ const showFooter = hasCta || footerNoteText !== null;
8038
8474
  return /* @__PURE__ */ jsx("div", {
8039
8475
  className: "event-calendar event-calendar--week-board",
8040
8476
  "data-block": "event-calendar",
8477
+ ...banded ? { "data-banded": "" } : {},
8041
8478
  children: /* @__PURE__ */ jsxs("div", {
8042
8479
  className: "event-week-board",
8043
8480
  style: { "--event-week-board-cols": String(days.length) },
8481
+ ...elevated ? { "data-elevated": "" } : {},
8044
8482
  children: [
8045
8483
  /* @__PURE__ */ jsxs("div", {
8046
8484
  className: "event-week-board-top",
8047
- children: [/* @__PURE__ */ jsx("span", {
8485
+ children: [hasTitle ? /* @__PURE__ */ jsx("span", {
8048
8486
  className: "event-week-board-title",
8049
8487
  children: title
8050
- }), /* @__PURE__ */ jsx("div", {
8488
+ }) : null, /* @__PURE__ */ jsx("div", {
8051
8489
  className: "event-week-board-legend",
8052
8490
  "aria-hidden": "true",
8053
8491
  children: LEGEND_ITEMS.map((item) => /* @__PURE__ */ jsxs("span", {
@@ -8086,21 +8524,17 @@ const WeekBoardView = ({ days, events, showCapacity, emptyMessage = "No classes
8086
8524
  }, dateKey);
8087
8525
  })
8088
8526
  }),
8089
- /* @__PURE__ */ jsxs("div", {
8527
+ showFooter ? /* @__PURE__ */ jsxs("div", {
8090
8528
  className: "event-week-board-foot",
8091
- children: [/* @__PURE__ */ jsx("p", {
8529
+ children: [footerNoteText !== null ? /* @__PURE__ */ jsx("p", {
8092
8530
  className: "event-week-board-foot-note",
8093
- children: hasAnyEvents ? footerNote : emptyMessage
8094
- }), ctaHref ? /* @__PURE__ */ jsx("a", {
8095
- className: ctaClassName,
8096
- href: ctaHref,
8097
- children: ctaLabel
8098
- }) : /* @__PURE__ */ jsx("button", {
8099
- type: "button",
8531
+ children: footerNoteText
8532
+ }) : null, hasCta ? /* @__PURE__ */ jsx("a", {
8100
8533
  className: ctaClassName,
8534
+ href: ctaHref ?? void 0,
8101
8535
  children: ctaLabel
8102
- })]
8103
- })
8536
+ }) : null]
8537
+ }) : null
8104
8538
  ]
8105
8539
  })
8106
8540
  });
@@ -8546,8 +8980,13 @@ function renderWeekBoardSsr(display) {
8546
8980
  events: [...display.events],
8547
8981
  showCapacity: display.showCapacity,
8548
8982
  emptyMessage: display.emptyMessage,
8549
- ctaLabel: display.buttonText,
8550
- buttonVariant: display.buttonVariant
8983
+ title: display.boardTitle,
8984
+ footerNote: display.footerNote,
8985
+ ctaLabel: display.loadMoreText ?? display.buttonText,
8986
+ ctaHref: display.seeAllUrl,
8987
+ buttonVariant: display.buttonVariant,
8988
+ elevated: display.elevated,
8989
+ banded: display.banded
8551
8990
  });
8552
8991
  }
8553
8992
  function formatHourLabel$1(hour) {
@@ -8935,7 +9374,7 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
8935
9374
  * Renders the newsletter signup form for SSR with hydration support.
8936
9375
  * Uses the islands architecture pattern to hydrate on the client.
8937
9376
  */
8938
- function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationProvider, preset = "emailOnly", includePhone, buttonLabel = "Subscribe", successMessage, privacyNote, tags, spamProtectionEnabled, className }) {
9377
+ function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationProvider, preset = "emailOnly", includePhone, buttonLabel = "Subscribe", buttonVariant = "primary", successMessage, privacyNote, tags, spamProtectionEnabled, className }) {
8939
9378
  const islandProps = buildNewsletterFormInteractiveIslandProps({
8940
9379
  blockId,
8941
9380
  siteId,
@@ -8945,6 +9384,7 @@ function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationPro
8945
9384
  preset,
8946
9385
  includePhone,
8947
9386
  buttonLabel,
9387
+ buttonVariant,
8948
9388
  successMessage,
8949
9389
  privacyNote,
8950
9390
  tags,
@@ -8998,7 +9438,7 @@ function NewsletterFormSSR({ blockId, siteId, apiBaseUrl, listId, destinationPro
8998
9438
  children: /* @__PURE__ */ jsx("button", {
8999
9439
  type: "submit",
9000
9440
  className: themeButtonClassName({
9001
- variant: "primary",
9441
+ variant: display.buttonVariant,
9002
9442
  size: "md"
9003
9443
  }),
9004
9444
  children: display.buttonLabel
@@ -9085,7 +9525,7 @@ function ShopSSR({ blockId, siteId, apiBaseUrl, stage, children, checkoutEndpoin
9085
9525
  action: /* @__PURE__ */ jsx("button", {
9086
9526
  type: "button",
9087
9527
  className: themeButtonClassName({
9088
- variant: "default",
9528
+ variant: render.hydration.buttonVariant,
9089
9529
  size: "md"
9090
9530
  }),
9091
9531
  disabled: true,
@@ -9098,7 +9538,7 @@ function ShopSSR({ blockId, siteId, apiBaseUrl, stage, children, checkoutEndpoin
9098
9538
  action: /* @__PURE__ */ jsx("button", {
9099
9539
  type: "button",
9100
9540
  className: themeButtonClassName({
9101
- variant: "default",
9541
+ variant: render.hydration.buttonVariant,
9102
9542
  size: "md"
9103
9543
  }),
9104
9544
  disabled: true,
@@ -9191,6 +9631,7 @@ const serverComponentRegistry = {
9191
9631
  "event-combined": EventCombinedSSR,
9192
9632
  "offerings-preview": OfferingsPreviewNode,
9193
9633
  "weekly-slot-availability": WeeklySlotAvailabilitySSR,
9634
+ "recurring-schedule": RecurringSchedule,
9194
9635
  ...buildServerRegistryFromEntries(runtimeBackedBlockServerEntries)
9195
9636
  };
9196
9637
  //#endregion
@@ -16516,7 +16957,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
16516
16957
  registrationEvents,
16517
16958
  options.occurrenceContext?.seriesId,
16518
16959
  options.subject?.kind,
16519
- options.subject?.kind === "eventSeries" ? options.subject.eventSeriesId : options.subject?.reason,
16960
+ options.subject?.kind === "eventSeries" ? options.subject.eventSeriesId : options.subject?.kind === "eventOffering" ? `${options.subject.eventOfferingId}:${options.subject.availableEventSeriesIds.join(",")}` : options.subject?.reason,
16520
16961
  options.contentEntry?.slug,
16521
16962
  options.contentEntry?.contentTypeSlug
16522
16963
  ]);
@@ -18293,13 +18734,16 @@ function resolveHasCoursePayment(pricing) {
18293
18734
  }
18294
18735
  function useCourseRegistrationWizard(props) {
18295
18736
  const api = useBlockApi();
18296
- const { contentEntry, courses, entrySubrouteContext } = props;
18737
+ const { contentEntry, courses, entrySubrouteContext, subject } = props;
18297
18738
  const scopedCourses = useMemo(() => {
18298
18739
  const allCourses = courses ?? [];
18299
18740
  if (entrySubrouteContext?.kind === "course-run") {
18300
18741
  const matched = allCourses.find((c) => c.id === entrySubrouteContext.run.courseId) ?? null;
18301
18742
  if (matched) return [matched];
18302
18743
  }
18744
+ const pageSurfaceScope = resolveCoursePageSurfaceScope(allCourses, subject);
18745
+ if (pageSurfaceScope.kind === "unsupported") return [];
18746
+ if (pageSurfaceScope.kind === "scoped") return [...pageSurfaceScope.courses];
18303
18747
  if (contentEntry?.id) {
18304
18748
  const matchedCourses = allCourses.filter((c) => c.contentEntryId === contentEntry.id);
18305
18749
  if (matchedCourses.length > 0) return matchedCourses;
@@ -18313,7 +18757,8 @@ function useCourseRegistrationWizard(props) {
18313
18757
  courses,
18314
18758
  contentEntry?.id,
18315
18759
  contentEntry?.slug,
18316
- entrySubrouteContext
18760
+ entrySubrouteContext,
18761
+ subject
18317
18762
  ]);
18318
18763
  const [step, setStep] = useState(() => {
18319
18764
  const enrollment = new URLSearchParams(window.location.search).get("enrollment");
@@ -19232,24 +19677,27 @@ function getCourseSlidingScaleMessage(pricing) {
19232
19677
  return null;
19233
19678
  }
19234
19679
  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;
19680
+ 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
19681
  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
19682
  const buttonClass = themeButtonClassName({
19238
19683
  variant: buttonVariant,
19239
19684
  size: "md"
19240
19685
  });
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."
19686
+ if (scopedCourses.length === 0) {
19687
+ const awaitingOfferingRuns = props.subject?.kind === "eventOffering" && props.subject.availableEventSeriesIds.length === 0;
19688
+ return /* @__PURE__ */ jsx("div", {
19689
+ id: COURSE_REGISTRATION_ANCHOR_ID,
19690
+ className: `course-registration ${className || ""}`,
19691
+ "data-block": "course-registration",
19692
+ children: /* @__PURE__ */ jsx("div", {
19693
+ className: "cr-empty",
19694
+ children: /* @__PURE__ */ jsx("p", {
19695
+ className: "cr-empty__text",
19696
+ children: awaitingOfferingRuns ? "New dates are coming soon. Booking will open when the next run is ready." : "No courses available to book."
19697
+ })
19250
19698
  })
19251
- })
19252
- });
19699
+ });
19700
+ }
19253
19701
  const allowedStatuses = api.config.isPreview ? ["active", "draft"] : ["active"];
19254
19702
  if (!scopedCourses.some((c) => !c.status || allowedStatuses.includes(c.status))) return /* @__PURE__ */ jsx("div", {
19255
19703
  id: COURSE_REGISTRATION_ANCHOR_ID,
@@ -19636,7 +20084,7 @@ const LEAFLET_JS_INTEGRITY = "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo
19636
20084
  let leafletLoaded = false;
19637
20085
  let leafletLoadPromise = null;
19638
20086
  function isLeafletApi(value) {
19639
- if (!isRecord$20(value)) return false;
20087
+ if (!isRecord$21(value)) return false;
19640
20088
  return typeof value.map === "function" && typeof value.tileLayer === "function" && typeof value.marker === "function";
19641
20089
  }
19642
20090
  function loadLeaflet() {
@@ -20581,7 +21029,7 @@ function PassesMembershipsController({ render }) {
20581
21029
  action: /* @__PURE__ */ jsx("button", {
20582
21030
  type: "button",
20583
21031
  className: themeButtonClassName({
20584
- variant: "default",
21032
+ variant: hydration.buttonVariant,
20585
21033
  size: "md",
20586
21034
  extraClassName: "shop__cta"
20587
21035
  }),
@@ -20602,7 +21050,7 @@ function PassesMembershipsController({ render }) {
20602
21050
  action: /* @__PURE__ */ jsx("button", {
20603
21051
  type: "button",
20604
21052
  className: themeButtonClassName({
20605
- variant: "default",
21053
+ variant: hydration.buttonVariant,
20606
21054
  size: "md",
20607
21055
  extraClassName: "shop__cta"
20608
21056
  }),
@@ -20958,7 +21406,7 @@ Autoplay.globalOptions = void 0;
20958
21406
  function isObject$2(subject) {
20959
21407
  return Object.prototype.toString.call(subject) === "[object Object]";
20960
21408
  }
20961
- function isRecord$16(subject) {
21409
+ function isRecord$17(subject) {
20962
21410
  return isObject$2(subject) || Array.isArray(subject);
20963
21411
  }
20964
21412
  function canUseDOM() {
@@ -20973,7 +21421,7 @@ function areOptionsEqual(optionsA, optionsB) {
20973
21421
  const valueA = optionsA[key];
20974
21422
  const valueB = optionsB[key];
20975
21423
  if (typeof valueA === "function") return `${valueA}` === `${valueB}`;
20976
- if (!isRecord$16(valueA) || !isRecord$16(valueB)) return valueA === valueB;
21424
+ if (!isRecord$17(valueA) || !isRecord$17(valueB)) return valueA === valueB;
20977
21425
  return areOptionsEqual(valueA, valueB);
20978
21426
  });
20979
21427
  }
@@ -24626,7 +25074,6 @@ const HeaderSectionNode = ({ blockId, blockKind, blockContent, fragmentRegistry,
24626
25074
  const asProp = restProps.as;
24627
25075
  const styleProp = restProps.style;
24628
25076
  const backgroundProp = typeof restProps.background === "string" ? restProps.background : void 0;
24629
- const allowOverflowProp = typeof restProps.allowOverflow === "boolean" ? restProps.allowOverflow : void 0;
24630
25077
  const dataSlotProp = typeof restProps["data-slot"] === "string" ? restProps["data-slot"] : void 0;
24631
25078
  return /* @__PURE__ */ jsx("nav", {
24632
25079
  ref: (el) => {
@@ -24648,7 +25095,6 @@ const HeaderSectionNode = ({ blockId, blockKind, blockContent, fragmentRegistry,
24648
25095
  as: asProp,
24649
25096
  style: styleProp,
24650
25097
  background: backgroundProp ?? "background",
24651
- allowOverflow: allowOverflowProp,
24652
25098
  "data-slot": dataSlotProp,
24653
25099
  className: sectionClasses || void 0,
24654
25100
  children
@@ -26581,8 +27027,13 @@ const EventCalendarWeekBoardClient = ({ display }) => {
26581
27027
  events: [...display.events],
26582
27028
  showCapacity: display.showCapacity,
26583
27029
  emptyMessage: display.emptyMessage,
26584
- ctaLabel: display.buttonText,
26585
- buttonVariant: display.buttonVariant
27030
+ title: display.boardTitle,
27031
+ footerNote: display.footerNote,
27032
+ ctaLabel: display.loadMoreText ?? display.buttonText,
27033
+ ctaHref: display.seeAllUrl,
27034
+ buttonVariant: display.buttonVariant,
27035
+ elevated: display.elevated,
27036
+ banded: display.banded
26586
27037
  });
26587
27038
  };
26588
27039
  const EventCalendarTimetableClient = ({ render }) => {
@@ -27418,7 +27869,7 @@ function NewsletterFormClient({ render }) {
27418
27869
  children: /* @__PURE__ */ jsx("button", {
27419
27870
  type: "submit",
27420
27871
  className: themeButtonClassName({
27421
- variant: "primary",
27872
+ variant: render.display.buttonVariant,
27422
27873
  size: "md"
27423
27874
  }),
27424
27875
  disabled: isNewsletterFormSubmitting(submissionState),
@@ -27527,7 +27978,7 @@ function WeeklySlotAvailabilityClient({ serviceId, resourceId, horizonWeeks, tim
27527
27978
  }
27528
27979
  //#endregion
27529
27980
  //#region ../blocks/src/system/runtime/components/registry.client.tsx
27530
- function isRecord$15(value) {
27981
+ function isRecord$16(value) {
27531
27982
  return typeof value === "object" && value !== null;
27532
27983
  }
27533
27984
  function buildRenderFromLooseProps(runtime, mode, props) {
@@ -27546,12 +27997,12 @@ function withRuntimeBackedEnvelope(source, runtime, render) {
27546
27997
  function normalizeLegacyInteractiveRenderProps(runtime, mode, props) {
27547
27998
  const source = props;
27548
27999
  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, {
28000
+ if (!isRecord$16(render)) return withRuntimeBackedEnvelope(source, runtime, buildRenderFromLooseProps(runtime, mode, props));
28001
+ if (isRecord$16(render["hydration"])) return withRuntimeBackedEnvelope(source, runtime, {
27551
28002
  ...render,
27552
28003
  mode
27553
28004
  });
27554
- if (!isRecord$15(render["display"])) return withRuntimeBackedEnvelope(source, runtime, buildRenderFromLooseProps(runtime, mode, props));
28005
+ if (!isRecord$16(render["display"])) return withRuntimeBackedEnvelope(source, runtime, buildRenderFromLooseProps(runtime, mode, props));
27555
28006
  const { display, mode: _legacyMode, ...legacyHydration } = render;
27556
28007
  return withRuntimeBackedEnvelope(source, runtime, {
27557
28008
  display,
@@ -27809,16 +28260,17 @@ const backgroundTransforms = [
27809
28260
  run: (value, _options, context) => resolveSurfaceForegroundStyles(value, context)
27810
28261
  },
27811
28262
  {
27812
- id: "background.resolveAllowOverflow",
28263
+ id: "background.resolveFrameClassName",
27813
28264
  kind: "formatter",
27814
- summary: "Resolve allowOverflow from background config (explicit overflow or scaled image)",
27815
- run: (value) => {
27816
- if (!value || typeof value !== "object") return false;
28265
+ summary: "Resolve clipping on a decorative background frame without clipping foreground content",
28266
+ run: (value, options) => {
28267
+ const baseClass = options?.baseClass?.trim() ?? "";
28268
+ if (!value || typeof value !== "object") return `${baseClass} rb-overflow-hidden`.trim();
27817
28269
  const input = value;
27818
- if (input.overflow === true) return true;
28270
+ if (input.overflow === true) return `${baseClass} rb-overflow-visible`.trim();
27819
28271
  const objectFit = isString$1(input.objectFit) ? input.objectFit.trim() : null;
27820
28272
  const scale = isString$1(input.scale) ? input.scale.trim() : isNumber$1(input.scale) ? String(input.scale) : null;
27821
- return Boolean((objectFit === "custom" || objectFit === "original") && scale && scale.trim().length > 0);
28273
+ return `${baseClass} ${Boolean((objectFit === "custom" || objectFit === "original") && scale && scale.trim().length > 0) ? "rb-overflow-visible" : "rb-overflow-hidden"}`.trim();
27822
28274
  }
27823
28275
  },
27824
28276
  {
@@ -28097,7 +28549,7 @@ const defaultTransforms = createTransformRegistry([
28097
28549
  //#region ../blocks/src/system/data/linkedContentEntries.ts
28098
28550
  const LINKED_CONTENT_ENTRY_META_KEY = "__rbLinkedContentEntry";
28099
28551
  function coerceLinkedContentEntriesPayload(payload) {
28100
- if (!isRecord$14(payload)) return payload;
28552
+ if (!isRecord$15(payload)) return payload;
28101
28553
  const response = payload;
28102
28554
  if (!Array.isArray(response.entries)) return payload;
28103
28555
  const contentType = parsePublicContentTypeMeta(response.contentType);
@@ -28105,16 +28557,16 @@ function coerceLinkedContentEntriesPayload(payload) {
28105
28557
  return response.entries.map((entry) => enrichLinkedContentEntry(entry, contentType));
28106
28558
  }
28107
28559
  function getLinkedContentEntryMeta(value) {
28108
- if (!isRecord$14(value)) return null;
28560
+ if (!isRecord$15(value)) return null;
28109
28561
  const candidate = value[LINKED_CONTENT_ENTRY_META_KEY];
28110
28562
  return isLinkedContentEntryMeta(candidate) ? candidate : null;
28111
28563
  }
28112
28564
  function buildLinkedContentEditTarget(input) {
28113
28565
  const { entry, sourceBlockId, sourceBlockKind, itemIndex } = input;
28114
- if (!isRecord$14(entry)) return null;
28566
+ if (!isRecord$15(entry)) return null;
28115
28567
  const meta = getLinkedContentEntryMeta(entry);
28116
28568
  if (!meta || meta.support.kind !== "supported") return null;
28117
- const content = isRecord$14(entry.content) ? entry.content : {};
28569
+ const content = isRecord$15(entry.content) ? entry.content : {};
28118
28570
  return {
28119
28571
  kind: "linked-content-entry",
28120
28572
  entryId: meta.entryId,
@@ -28178,12 +28630,12 @@ function resolveLinkedEntryInlineFieldEligibility(input) {
28178
28630
  };
28179
28631
  }
28180
28632
  function enrichLinkedContentEntry(entry, contentType) {
28181
- if (!isRecord$14(entry)) return entry;
28633
+ if (!isRecord$15(entry)) return entry;
28182
28634
  const entryId = typeof entry.id === "string" ? entry.id : null;
28183
28635
  if (!entryId) return entry;
28184
28636
  const title = typeof entry.title === "string" && entry.title.trim().length > 0 ? entry.title : entryId;
28185
28637
  const optimisticHash = typeof entry.optimisticHash === "string" && entry.optimisticHash.length > 0 ? entry.optimisticHash : null;
28186
- const content = isRecord$14(entry.content) ? entry.content : {};
28638
+ const content = isRecord$15(entry.content) ? entry.content : {};
28187
28639
  const meta = {
28188
28640
  kind: "linked-content-entry",
28189
28641
  entryId,
@@ -28279,7 +28731,7 @@ function capitalize(value) {
28279
28731
  return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
28280
28732
  }
28281
28733
  function parsePublicContentTypeMeta(value) {
28282
- if (!isRecord$14(value)) return null;
28734
+ if (!isRecord$15(value)) return null;
28283
28735
  if (typeof value.key !== "string" || value.key.trim().length === 0) return null;
28284
28736
  return {
28285
28737
  key: value.key,
@@ -28289,7 +28741,7 @@ function parsePublicContentTypeMeta(value) {
28289
28741
  };
28290
28742
  }
28291
28743
  function parsePublicContentTypeLinkedEntryEditing(value) {
28292
- if (!isRecord$14(value) || typeof value.kind !== "string") return null;
28744
+ if (!isRecord$15(value) || typeof value.kind !== "string") return null;
28293
28745
  switch (value.kind) {
28294
28746
  case "generic": return { kind: "generic" };
28295
28747
  case "unsupported-domain-backed": return {
@@ -28300,7 +28752,7 @@ function parsePublicContentTypeLinkedEntryEditing(value) {
28300
28752
  }
28301
28753
  }
28302
28754
  function parsePublicContentTypeFieldMeta(value) {
28303
- if (!isRecord$14(value)) return [];
28755
+ if (!isRecord$15(value)) return [];
28304
28756
  if (typeof value.id !== "string" || typeof value.type !== "string") return [];
28305
28757
  return [{
28306
28758
  id: value.id,
@@ -28315,14 +28767,14 @@ function parseStringArray(value) {
28315
28767
  return value.filter((item) => typeof item === "string");
28316
28768
  }
28317
28769
  function isLinkedContentEntryMeta(value) {
28318
- if (!isRecord$14(value)) return false;
28770
+ if (!isRecord$15(value)) return false;
28319
28771
  if (value.kind !== "linked-content-entry") return false;
28320
28772
  if (typeof value.entryId !== "string") return false;
28321
28773
  if (typeof value.contentTypeKey !== "string") return false;
28322
28774
  if (typeof value.contentTypeLabel !== "string") return false;
28323
28775
  if (typeof value.title !== "string") return false;
28324
28776
  if (!(value.optimisticHash === null || typeof value.optimisticHash === "string")) return false;
28325
- if (!isRecord$14(value.contentType)) return false;
28777
+ if (!isRecord$15(value.contentType)) return false;
28326
28778
  if (!isLinkedEntryFieldSourceArray(value.fieldSources)) return false;
28327
28779
  return isLinkedContentEditSupport(value.support);
28328
28780
  }
@@ -28330,7 +28782,7 @@ function isLinkedEntryFieldSourceArray(value) {
28330
28782
  return Array.isArray(value) && value.every(isLinkedEntryFieldSource);
28331
28783
  }
28332
28784
  function isLinkedEntryFieldSource(value) {
28333
- if (!isRecord$14(value)) return false;
28785
+ if (!isRecord$15(value)) return false;
28334
28786
  if (typeof value.displayPath !== "string") return false;
28335
28787
  switch (value.kind) {
28336
28788
  case "content-field": return typeof value.fieldPath === "string" && (value.fieldType === "text" || value.fieldType === "richText");
@@ -28351,7 +28803,7 @@ function isLinkedEntryInlineFieldReadOnlyReason(value) {
28351
28803
  }
28352
28804
  }
28353
28805
  function isLinkedContentEditSupport(value) {
28354
- if (!isRecord$14(value) || typeof value.kind !== "string") return false;
28806
+ if (!isRecord$15(value) || typeof value.kind !== "string") return false;
28355
28807
  switch (value.kind) {
28356
28808
  case "supported": return true;
28357
28809
  case "unsupported-domain-backed":
@@ -28360,7 +28812,7 @@ function isLinkedContentEditSupport(value) {
28360
28812
  default: return false;
28361
28813
  }
28362
28814
  }
28363
- function isRecord$14(value) {
28815
+ function isRecord$15(value) {
28364
28816
  return typeof value === "object" && value !== null && !Array.isArray(value);
28365
28817
  }
28366
28818
  //#endregion
@@ -28414,14 +28866,14 @@ function isDecoratedHeadingBlockKind(blockKind) {
28414
28866
  return blockKind === "block.intro" || blockKind === "block.feature-cards" || blockKind === "block.testimonials" || blockKind === "block.faq";
28415
28867
  }
28416
28868
  function readVariant(blockContent) {
28417
- if (!isRecord$13(blockContent)) return void 0;
28869
+ if (!isRecord$14(blockContent)) return void 0;
28418
28870
  const variant = blockContent.variant;
28419
28871
  return typeof variant === "string" ? variant : void 0;
28420
28872
  }
28421
28873
  function isFaqDecoratedVariant(variant) {
28422
28874
  return variant === "default" || variant === "question-columns";
28423
28875
  }
28424
- function isRecord$13(value) {
28876
+ function isRecord$14(value) {
28425
28877
  return typeof value === "object" && value !== null && !Array.isArray(value);
28426
28878
  }
28427
28879
  function buildHeadingDecorationWrapperClassName(className) {
@@ -29171,9 +29623,9 @@ function isReactNode(value) {
29171
29623
  * Handles conditionals ($when), scopes ($scopes), repeaters ($repeat), bindings ($bind), and children.
29172
29624
  */
29173
29625
  function resolveNode(node, context, indexFallback) {
29174
- if (!shouldRenderNode(node, context)) return null;
29175
29626
  const scopeContext = applyScopes(node, context);
29176
29627
  if (node.$repeat) return resolveRepeater(node, scopeContext);
29628
+ if (!shouldRenderNode(node, scopeContext)) return null;
29177
29629
  const registry = scopeContext.registry ?? serverComponentRegistry;
29178
29630
  const normalizedType = node.type.toLowerCase();
29179
29631
  const component = registry[node.type] ?? registry[normalizedType] ?? (normalizedType === "section" ? SectionNode : void 0);
@@ -29489,6 +29941,25 @@ function applyStyleOverride(target, key, defaults) {
29489
29941
  target[key] = mergeDeep(defaults, target[key]);
29490
29942
  }
29491
29943
  //#endregion
29944
+ //#region ../blocks/src/system/runtime/blockComposition.ts
29945
+ function readBlockComposition(value) {
29946
+ if (!isRecord$13(value) || typeof value.kind !== "string") return null;
29947
+ switch (value.kind) {
29948
+ case "intro": return value.treatment === "editorial-statement" || value.treatment === "portrait-bio" ? {
29949
+ kind: "intro",
29950
+ treatment: value.treatment
29951
+ } : null;
29952
+ case "feature-cards": return value.treatment === "asymmetric-emphasis" || value.treatment === "framed-programme" ? {
29953
+ kind: "feature-cards",
29954
+ treatment: value.treatment
29955
+ } : null;
29956
+ default: return null;
29957
+ }
29958
+ }
29959
+ function isRecord$13(value) {
29960
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29961
+ }
29962
+ //#endregion
29492
29963
  //#region ../blocks/src/system/componentFactory.ts
29493
29964
  /**
29494
29965
  * Resolves the layout definition for a block based on its manifest and content.
@@ -29672,6 +30143,7 @@ function renderBlock(manifest, content, options = {}) {
29672
30143
  if (manifest.behaviours?.managesOwnWrapper) return componentElement;
29673
30144
  const styleGroup = typeof content.styleGroup === "string" ? content.styleGroup : void 0;
29674
30145
  const blockLook = typeof content.blockLook === "string" ? content.blockLook : void 0;
30146
+ const blockComposition = readBlockComposition(content.blockComposition);
29675
30147
  return React.createElement("div", {
29676
30148
  className: `block-${cleanKind}`,
29677
30149
  "data-block": cleanKind,
@@ -29681,6 +30153,10 @@ function renderBlock(manifest, content, options = {}) {
29681
30153
  "data-variant": variantKey
29682
30154
  } : {},
29683
30155
  ...blockLook ? { "data-block-look": blockLook } : {},
30156
+ ...blockComposition ? {
30157
+ "data-block-composition": blockComposition.treatment,
30158
+ "data-block-composition-kind": blockComposition.kind
30159
+ } : {},
29684
30160
  ...styleGroup ? { "data-style-group": styleGroup } : {}
29685
30161
  }, componentElement);
29686
30162
  }
@@ -30516,6 +30992,19 @@ Object.keys(NAV_LINK_PRESETS);
30516
30992
  //#region ../theme-core/src/header/generateHeaderCss.ts
30517
30993
  const HEADER_BLUR = "blur(12px)";
30518
30994
  const FLOATING_BLUR = "blur(16px)";
30995
+ const INSET_SHELL_MARKER_CLASS = "header-bar-frame-inset-shell";
30996
+ const INSET_SHELL_EDGE = "1rem";
30997
+ const INSET_SHELL_INSET_BLOCK = "0.875rem";
30998
+ const INSET_SHELL_RADIUS = "9999px";
30999
+ const INSET_SHELL_CONTAINER_MAX = "80rem";
31000
+ const INSET_SHELL_INTERIOR_PADDING_X = "1.75rem";
31001
+ /**
31002
+ * Whether the classic header should render as an inset "brand capsule" shell.
31003
+ * The facet is only meaningful for the classic layout; other variants ignore it.
31004
+ */
31005
+ function usesInsetShell(header) {
31006
+ return header.barFrame === "inset-shell" && header.variant === "classic";
31007
+ }
30519
31008
  /**
30520
31009
  * Generate complete CSS for header system from theme config
30521
31010
  *
@@ -30615,7 +31104,36 @@ function generateHeaderRootStyles(header, themeId, tokens, _theme) {
30615
31104
  const baseBlock = `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
30616
31105
  const overlayFix = `\n${`${selector}:has([data-nav-mobile-overlay][aria-hidden="false"])`} {\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n}\n`;
30617
31106
  if (isContainedNav || backgroundRules.length === 0) return `${baseBlock}\n${overlayFix}`;
30618
- return `${baseBlock}\n${`\n${backgroundSelector} {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n border-radius: inherit;\n z-index: -1;\n ${backgroundRules.join("\n ")}\n}\n`}\n${overlayFix}`;
31107
+ return `${baseBlock}\n${`\n${backgroundSelector} {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n border-radius: inherit;\n z-index: -1;\n ${backgroundRules.join("\n ")}\n}\n`}\n${overlayFix}${usesInsetShell(header) ? generateInsetShellStyles(header, themeId) : ""}`;
31108
+ }
31109
+ /**
31110
+ * Reshapes the full-bleed header paint layer into a contained brand capsule at
31111
+ * the desktop breakpoint. The capsule is centred, capped to the page container
31112
+ * width, inset from the top, fully rounded, and carries the header depth so it
31113
+ * reads as a floating pill. Root border/shadow are neutralised on desktop so a
31114
+ * bordered style does not leave a full-width hairline around the capsule. Sticky
31115
+ * positioning is unaffected — the root stays full width and sticky while the
31116
+ * ::before paint provides the capsule.
31117
+ */
31118
+ function generateInsetShellStyles(header, themeId) {
31119
+ const scope = `:where([data-theme-scope="${themeId}"])`;
31120
+ const shellRootSelector = `${scope} .header-root.${INSET_SHELL_MARKER_CLASS}`;
31121
+ const shellBeforeSelector = `${scope} .header-root.${INSET_SHELL_MARKER_CLASS}::before`;
31122
+ const layoutSelector = `${scope} .header-root.${INSET_SHELL_MARKER_CLASS} .rb-header-layout`;
31123
+ const widthValue = header.maxWidth === "full" ? `calc(100% - (${INSET_SHELL_EDGE} * 2))` : `min(${INSET_SHELL_CONTAINER_MAX}, calc(100% - (${INSET_SHELL_EDGE} * 2)))`;
31124
+ const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "none");
31125
+ const rootRules = ["border: none;", "box-shadow: none;"];
31126
+ const beforeRules = [
31127
+ `inset: ${INSET_SHELL_INSET_BLOCK} auto;`,
31128
+ "left: 50%;",
31129
+ "right: auto;",
31130
+ "transform: translateX(-50%);",
31131
+ `width: ${widthValue};`,
31132
+ `border-radius: ${INSET_SHELL_RADIUS};`,
31133
+ ...shadowVar ? [`box-shadow: ${shadowVar};`] : []
31134
+ ];
31135
+ const layoutRules = [`padding-inline: ${INSET_SHELL_INTERIOR_PADDING_X};`];
31136
+ return `\n@media ${MQ_MD_UP} {\n${shellRootSelector} {\n ${rootRules.join("\n ")}\n}\n${shellBeforeSelector} {\n ${beforeRules.join("\n ")}\n}\n${layoutSelector} {\n ${layoutRules.join("\n ")}\n}\n}\n`;
30619
31137
  }
30620
31138
  /**
30621
31139
  * Generate logo typography styles
@@ -30693,7 +31211,7 @@ function generateLogoTextBehaviorStyles(logoText, themeId) {
30693
31211
  */
30694
31212
  function generateNavLinkStyles(header, themeId, tokens, theme, contrastTreatment, navTextSize) {
30695
31213
  const navPreferences = {
30696
- typography: header.navTypography ?? "inherit",
31214
+ typography: header.navFontRole ?? header.navTypography ?? "inherit",
30697
31215
  fontSize: readHeaderNavFontSizePreference(header.navTextSize)
30698
31216
  };
30699
31217
  if (header.navLinkStyle) return generateNavLinkCSS({
@@ -31232,7 +31750,7 @@ ${selector} [data-style-group*='-from-muted-band-'] {
31232
31750
  }
31233
31751
 
31234
31752
  ${selector} [data-style-group*='-from-accent-band-'] {
31235
- --site-style-transition-from: rgb(var(--tb-primary));
31753
+ --site-style-transition-from: rgb(var(--tb-accent));
31236
31754
  }
31237
31755
 
31238
31756
  ${selector} [data-style-group*='-from-brand-depth-band-'] {
@@ -31249,7 +31767,7 @@ ${selector} [data-style-group$='-to-muted-band'] {
31249
31767
  }
31250
31768
 
31251
31769
  ${selector} [data-style-group$='-to-accent-band'] {
31252
- --site-style-transition-to: rgb(var(--tb-primary));
31770
+ --site-style-transition-to: rgb(var(--tb-accent));
31253
31771
  }
31254
31772
 
31255
31773
  ${selector} [data-style-group$='-to-brand-depth-band'] {
@@ -32884,6 +33402,10 @@ function buildThemeCssVars(theme) {
32884
33402
  ["--font-heading"]: formatFontFamily(typography.headings.default.family),
32885
33403
  ["--font-body"]: formatFontFamily(typography.body.family),
32886
33404
  ["--font-eyebrow"]: typography.eyebrow?.family ? formatFontFamily(typography.eyebrow.family) : "var(--font-body)",
33405
+ ...typography.eyebrow?.size ? { ["--fs-eyebrow"]: mapEyebrowSize(typography.eyebrow.size) } : {},
33406
+ ...typography.eyebrow?.weight ? { ["--fw-eyebrow"]: mapWeight(typography.eyebrow.weight) } : {},
33407
+ ...typography.eyebrow?.letterSpacing ? { ["--ls-eyebrow"]: mapEyebrowLetterSpacing(typography.eyebrow.letterSpacing) } : {},
33408
+ ...typography.eyebrow?.case ? { ["--tt-eyebrow"]: mapEyebrowCase(typography.eyebrow.case) } : {},
32887
33409
  ["--font-weight-heading"]: mapWeight(typography.headings.default.weight),
32888
33410
  ["--font-weight-body"]: mapWeight(typography.body.weight),
32889
33411
  ...typography.headings.h1.weight ? { ["--fw-h1"]: mapWeight(typography.headings.h1.weight) } : {},
@@ -32900,14 +33422,14 @@ function buildThemeCssVars(theme) {
32900
33422
  ...typography.headings.h4?.letterSpacing ? { ["--ls-h4"]: mapLetterSpacing(typography.headings.h4.letterSpacing) } : {},
32901
33423
  ...typography.headings.h5?.letterSpacing ? { ["--ls-h5"]: mapLetterSpacing(typography.headings.h5.letterSpacing) } : {},
32902
33424
  ...typography.headings.h6?.letterSpacing ? { ["--ls-h6"]: mapLetterSpacing(typography.headings.h6.letterSpacing) } : {},
32903
- ["--lh-heading"]: mapLineHeight(typography.headings.default.lineHeight),
33425
+ ["--lh-heading"]: mapHeadingLineHeight(typography.headings.default.lineHeight),
32904
33426
  ["--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) } : {},
33427
+ ...typography.headings.h1.lineHeight ? { ["--lh-h1"]: mapHeadingLineHeight(typography.headings.h1.lineHeight) } : {},
33428
+ ...typography.headings.h2.lineHeight ? { ["--lh-h2"]: mapHeadingLineHeight(typography.headings.h2.lineHeight) } : {},
33429
+ ...typography.headings.h3.lineHeight ? { ["--lh-h3"]: mapHeadingLineHeight(typography.headings.h3.lineHeight) } : {},
33430
+ ...typography.headings.h4?.lineHeight ? { ["--lh-h4"]: mapHeadingLineHeight(typography.headings.h4.lineHeight) } : {},
33431
+ ...typography.headings.h5?.lineHeight ? { ["--lh-h5"]: mapHeadingLineHeight(typography.headings.h5.lineHeight) } : {},
33432
+ ...typography.headings.h6?.lineHeight ? { ["--lh-h6"]: mapHeadingLineHeight(typography.headings.h6.lineHeight) } : {},
32911
33433
  ["--tt-heading"]: mapTextTransform(typography.headings.default.case),
32912
33434
  ["--fv-heading"]: mapFontVariant(typography.headings.default.case),
32913
33435
  ["--fi-heading"]: mapFontStyle(typography.headings.default.italic),
@@ -33268,6 +33790,24 @@ function mapLetterSpacing(s) {
33268
33790
  loose: "0.02em"
33269
33791
  }[s];
33270
33792
  }
33793
+ function mapEyebrowSize(s) {
33794
+ return {
33795
+ sm: "0.75rem",
33796
+ md: "0.875rem",
33797
+ lg: "1rem"
33798
+ }[s];
33799
+ }
33800
+ function mapEyebrowLetterSpacing(s) {
33801
+ return {
33802
+ tight: "0em",
33803
+ normal: "0.025em",
33804
+ loose: "0.06em",
33805
+ wide: "0.12em"
33806
+ }[s];
33807
+ }
33808
+ function mapEyebrowCase(c) {
33809
+ return c === "uppercase" ? "uppercase" : "none";
33810
+ }
33271
33811
  function mapLineHeight(s) {
33272
33812
  return {
33273
33813
  normal: "1.5",
@@ -33275,6 +33815,22 @@ function mapLineHeight(s) {
33275
33815
  loose: "1.8"
33276
33816
  }[s];
33277
33817
  }
33818
+ /**
33819
+ * Headings get their own line-height scale, decoupled from body. `mapLineHeight`
33820
+ * is floored at 1.5 (a body leading) which reads as too airy on headings — the
33821
+ * more so as size drops. These values sit well under 1.5 and let presets taper
33822
+ * per level (larger headings tighter). `tight`/`snug` extend the token set for
33823
+ * display headings; body keeps `mapLineHeight`.
33824
+ */
33825
+ function mapHeadingLineHeight(s) {
33826
+ return {
33827
+ tight: "1.1",
33828
+ snug: "1.15",
33829
+ normal: "1.2",
33830
+ relaxed: "1.3",
33831
+ loose: "1.4"
33832
+ }[s];
33833
+ }
33278
33834
  function mapTextTransform(c) {
33279
33835
  if (c === "uppercase") return "uppercase";
33280
33836
  return "none";
@@ -33306,7 +33862,7 @@ function hydrateValue(value, context) {
33306
33862
  const resolvedItems = value.map((item) => hydrateValue(item, context));
33307
33863
  return resolvedItems.every((item, index) => item === value[index]) ? value : resolvedItems;
33308
33864
  }
33309
- if (isRecord$20(value)) {
33865
+ if (isRecord$21(value)) {
33310
33866
  if (isInternalLink(value)) return hydrateInternalLink(value, context.routes);
33311
33867
  if (isPageLink(value)) return hydratePageLink(value, context);
33312
33868
  if (isEntryLink(value)) return hydrateEntryLink(value, context);
@@ -33542,7 +34098,7 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
33542
34098
  const cleanKind = block.kind.replace(/^block\./, "");
33543
34099
  const definition = getBlockDefinition(block.kind);
33544
34100
  const managesOwnWrapper = definition?.manifest.behaviours?.managesOwnWrapper;
33545
- const renderableContent = getRenderableContent(block);
34101
+ const renderableContent = getRenderableContent(block, dataContext?.previewStage);
33546
34102
  const variantKey = definition?.manifest ? resolveVariantKey(definition.manifest, renderableContent) : null;
33547
34103
  const shouldUseWrapper = !managesOwnWrapper || Boolean(wrapBlock);
33548
34104
  const blockSectionProps = {
@@ -33568,6 +34124,7 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
33568
34124
  const wrapperClassName = [`block-${cleanKind}`, wrapBlock ? "group relative" : null].filter(Boolean).join(" ");
33569
34125
  const styleGroup = typeof renderableContent.styleGroup === "string" ? renderableContent.styleGroup : void 0;
33570
34126
  const blockLook = typeof renderableContent.blockLook === "string" ? renderableContent.blockLook : void 0;
34127
+ const blockComposition = readBlockComposition(renderableContent.blockComposition);
33571
34128
  const transitionStyle = transitionCssVarsStyle(renderableContent);
33572
34129
  const blockStyle = mergeStyleObjects(transitionStyle, boundaryReserveCssVarsStyle({
33573
34130
  before: boundaryBefore,
@@ -33581,6 +34138,8 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
33581
34138
  "data-variant": variantKey ?? void 0,
33582
34139
  "data-block-variant": variantKey ?? void 0,
33583
34140
  "data-block-look": blockLook,
34141
+ "data-block-composition": blockComposition?.treatment,
34142
+ "data-block-composition-kind": blockComposition?.kind,
33584
34143
  "data-page-block-position": blockPosition,
33585
34144
  "data-site-style-boundary-before": boundaryBefore?.metrics.size,
33586
34145
  "data-site-style-boundary-after": boundaryAfter?.metrics.size,
@@ -33781,7 +34340,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
33781
34340
  if (!definition) {
33782
34341
  if (OverrideComponent) {
33783
34342
  const rendered = /* @__PURE__ */ jsx(OverrideComponent, {
33784
- content: getRenderableContent(block),
34343
+ content: getRenderableContent(block, dataContext?.previewStage),
33785
34344
  theme: themeTokens,
33786
34345
  themeConfig,
33787
34346
  data: void 0,
@@ -33837,7 +34396,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
33837
34396
  override: false
33838
34397
  });
33839
34398
  }
33840
- const content = getRenderableContent(block);
34399
+ const content = getRenderableContent(block, dataContext?.previewStage);
33841
34400
  const parsed = getCachedValidator(definition.manifest, "strict").safeParse(content);
33842
34401
  try {
33843
34402
  if (globalThis.process?.env?.NODE_ENV !== "production" && !parsed.success && !usePlaceholders) console.warn("[blocks:PageRenderer] manifest validation failed", {
@@ -33980,8 +34539,8 @@ function resolveBlockData({ block, definition, dataContext }) {
33980
34539
  * For published: content is the source of truth.
33981
34540
  * Returns empty object if no content exists (validator will handle placeholders if needed).
33982
34541
  */
33983
- function getRenderableContent(block) {
33984
- const source = block.draftContent ?? block.content ?? {};
34542
+ function getRenderableContent(block, previewStage = "published") {
34543
+ const source = previewStage === "preview" && block.draftContent ? block.draftContent : block.content ?? {};
33985
34544
  if (!isObjectRecord(source)) return {};
33986
34545
  return source;
33987
34546
  }
@@ -34068,15 +34627,16 @@ const containerResponsiveThemeCss = `/*
34068
34627
  }
34069
34628
 
34070
34629
  /* 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). */
34630
+ Each property resolves from the optional eyebrow typographic role
34631
+ (--fs/--fw/--ls/--tt-eyebrow, emitted only when the theme sets them),
34632
+ with the historical hardcoded values as fallbacks so existing themes
34633
+ are unchanged. font-family falls back to the body font likewise. */
34074
34634
  .rb-eyebrow {
34075
34635
  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;
34636
+ font-size: var(--fs-eyebrow, 0.875rem);
34637
+ font-weight: var(--fw-eyebrow, 600);
34638
+ letter-spacing: var(--ls-eyebrow, 0.025em);
34639
+ text-transform: var(--tt-eyebrow, uppercase);
34080
34640
  }
34081
34641
  .rb-eyebrow-treatment-accent {
34082
34642
  color: rgb(var(--tb-accent));
@@ -34977,6 +35537,12 @@ const containerResponsiveThemeCss = `/*
34977
35537
  .rb-lg-hidden {
34978
35538
  display: none;
34979
35539
  }
35540
+ .rb-lg-flex-row {
35541
+ flex-direction: row;
35542
+ }
35543
+ .rb-lg-items-center {
35544
+ align-items: center;
35545
+ }
34980
35546
  }
34981
35547
 
34982
35548
  }
@@ -40581,6 +41147,11 @@ const containerResponsiveThemeCss = `/*
40581
41147
  background-color: var(--ec-surface);
40582
41148
  color: var(--ec-text);
40583
41149
  overflow: hidden;
41150
+ }
41151
+
41152
+ /* Opt-in raised look: a soft drop shadow so the board lifts off the page.
41153
+ * Generic default (no [data-elevated]) stays flat. */
41154
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board[data-elevated] {
40584
41155
  box-shadow: 0 14px 34px -24px rgba(var(--tb-text), 0.35);
40585
41156
  }
40586
41157
 
@@ -40592,7 +41163,9 @@ const containerResponsiveThemeCss = `/*
40592
41163
  gap: 1rem;
40593
41164
  flex-wrap: wrap;
40594
41165
  padding: 1.1rem 1.5rem;
40595
- background-color: var(--ec-header-bg);
41166
+ /* surfaceAlt gives the header/footer a legible tint against the white day-grid
41167
+ * body — the faint \`--ec-header-bg\` (5% text) is invisible on light palettes. */
41168
+ background-color: rgb(var(--tb-surfaceAlt));
40596
41169
  border-bottom: 1px solid var(--ec-border-subtle);
40597
41170
  }
40598
41171
 
@@ -40705,7 +41278,10 @@ const containerResponsiveThemeCss = `/*
40705
41278
  flex-direction: column;
40706
41279
  gap: 0.45rem;
40707
41280
  padding: 0.8rem 0.85rem;
40708
- border: 1px solid var(--ec-border-subtle);
41281
+ /* Full hairline border at the site style's border strength (0 on borderless
41282
+ * styles), alongside the exaggerated status stripe on the left. \`--ec-border-subtle\`
41283
+ * (half-strength) reads as no border at all on light palettes. */
41284
+ border: var(--rb-border-width, 1px) solid rgb(var(--tb-border));
40709
41285
  border-left: 3px solid var(--ec-status-available);
40710
41286
  border-radius: calc(var(--rb-block-radius) / 1.5);
40711
41287
  background-color: var(--ec-surface);
@@ -40788,7 +41364,8 @@ const containerResponsiveThemeCss = `/*
40788
41364
  gap: 1rem;
40789
41365
  flex-wrap: wrap;
40790
41366
  padding: 1.1rem 1.5rem;
40791
- background-color: var(--ec-header-bg);
41367
+ /* Matches the header tint (see .event-week-board-top). */
41368
+ background-color: rgb(var(--tb-surfaceAlt));
40792
41369
  border-top: 1px solid var(--ec-border-subtle);
40793
41370
  }
40794
41371
 
@@ -40856,8 +41433,10 @@ const containerResponsiveThemeCss = `/*
40856
41433
  * (z-index -10) but behind the content, so no block-content wiring is needed.
40857
41434
  * Surface + hairline rules are token-referenced: on a borderless site style
40858
41435
  * (--rb-border-width: 0) the band keeps its surface tint but drops the rules.
41436
+ * Opt-in only: the band paints when the board root carries [data-banded];
41437
+ * the generic default is bandless.
40859
41438
  * ----------------------------------------------------------------------------- */
40860
- :where(.theme-scope) [data-slot="section"]:has(.event-calendar--week-board)::before {
41439
+ :where(.theme-scope) [data-slot="section"]:has(.event-calendar--week-board[data-banded])::before {
40861
41440
  content: "";
40862
41441
  position: absolute;
40863
41442
  inset: 0;
@@ -41937,7 +42516,7 @@ const containerResponsiveThemeCss = `/*
41937
42516
  }
41938
42517
 
41939
42518
  :where(.theme-scope) .shop__empty-text {
41940
- color: rgb(var(--tb-mutedText));
42519
+ color: var(--rb-surface-supporting-color, var(--rb-surface-text-color, rgb(var(--tb-mutedText))));
41941
42520
  font-size: var(--fs-body, 1rem);
41942
42521
  }
41943
42522
 
@@ -41963,7 +42542,7 @@ const containerResponsiveThemeCss = `/*
41963
42542
  :where(.theme-scope) .shop__section-heading {
41964
42543
  font-size: var(--fs-h3, 1.25rem);
41965
42544
  font-weight: 600;
41966
- color: rgb(var(--tb-text));
42545
+ color: var(--rb-surface-heading-color, var(--rb-surface-text-color, rgb(var(--tb-text))));
41967
42546
  margin-bottom: 1rem;
41968
42547
  font-family: var(--font-heading);
41969
42548
  }
@@ -41981,6 +42560,124 @@ const containerResponsiveThemeCss = `/*
41981
42560
  gap: 1rem;
41982
42561
  }
41983
42562
 
42563
+ /* Compact product register: useful for small, scannable pass/package sets. */
42564
+ :where(.theme-scope) .shop--register .shop__section {
42565
+ margin-bottom: 0;
42566
+ }
42567
+
42568
+ :where(.theme-scope) .shop--register .shop__section-heading {
42569
+ margin-bottom: 1rem;
42570
+ font-size: clamp(1.4rem, 2.2vw, 1.7rem);
42571
+ }
42572
+
42573
+ :where(.theme-scope) .shop--register .shop__products--register {
42574
+ display: flex;
42575
+ flex-direction: column;
42576
+ border-top: 1px solid color-mix(in oklab, currentColor, transparent 78%);
42577
+ }
42578
+
42579
+ :where(.theme-scope) .shop--register .shop__card {
42580
+ display: grid;
42581
+ grid-template-columns: minmax(8rem, 0.85fr) auto minmax(12rem, 1.5fr) auto;
42582
+ grid-template-rows: auto;
42583
+ align-items: center;
42584
+ column-gap: clamp(1rem, 3vw, 2.5rem);
42585
+ padding: 1rem 0;
42586
+ border: 0;
42587
+ border-bottom: 1px solid color-mix(in oklab, currentColor, transparent 78%);
42588
+ border-radius: 0;
42589
+ background: transparent;
42590
+ color: inherit;
42591
+ --rb-surface-text-color: inherit;
42592
+ --rb-surface-heading-color: inherit;
42593
+ --rb-surface-link-color: inherit;
42594
+ --rb-surface-supporting-color: inherit;
42595
+ }
42596
+
42597
+ :where(.theme-scope) .shop--register .shop__card-header {
42598
+ display: contents;
42599
+ }
42600
+
42601
+ :where(.theme-scope) .shop--register .shop__card-name,
42602
+ :where(.theme-scope) .shop--register .shop__card-price,
42603
+ :where(.theme-scope) .shop--register .shop__card-details,
42604
+ :where(.theme-scope) .shop--register .shop__cta {
42605
+ margin: 0;
42606
+ }
42607
+
42608
+ :where(.theme-scope) .shop--register .shop__card-name {
42609
+ grid-column: 1;
42610
+ grid-row: 1;
42611
+ font-family: var(--font-heading);
42612
+ font-size: 1.15rem;
42613
+ font-weight: 400;
42614
+ }
42615
+
42616
+ :where(.theme-scope) .shop--register .shop__card-price {
42617
+ grid-column: 2;
42618
+ grid-row: 1;
42619
+ font-size: 0.98rem;
42620
+ font-weight: 500;
42621
+ white-space: nowrap;
42622
+ color: var(--rb-surface-link-color, var(--rb-surface-text-color, inherit));
42623
+ }
42624
+
42625
+ :where(.theme-scope) .shop--register .shop__card-description {
42626
+ grid-column: 1 / -1;
42627
+ margin-top: 0.35rem;
42628
+ }
42629
+
42630
+ :where(.theme-scope) .shop--register .shop__card-details {
42631
+ grid-column: 3;
42632
+ grid-row: 1;
42633
+ display: flex;
42634
+ flex-wrap: wrap;
42635
+ gap: 0.35rem 1rem;
42636
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42637
+ font-size: 0.86rem;
42638
+ }
42639
+
42640
+ :where(.theme-scope) .shop--register .shop__cta {
42641
+ grid-column: 4;
42642
+ grid-row: 1;
42643
+ align-self: center;
42644
+ margin-left: auto;
42645
+ }
42646
+
42647
+ :where(.theme-scope) .shop--register .shop__card > [role='status'] {
42648
+ grid-column: 1 / -1;
42649
+ }
42650
+
42651
+ @container rb-site (max-width: 767px) {
42652
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
42653
+ :where(.theme-scope) .shop--register .shop__card {
42654
+ grid-template-columns: minmax(0, 1fr) auto;
42655
+ row-gap: 0.45rem;
42656
+ }
42657
+
42658
+ :where(.theme-scope) .shop--register .shop__card-name {
42659
+ grid-column: 1;
42660
+ }
42661
+
42662
+ :where(.theme-scope) .shop--register .shop__card-price {
42663
+ grid-column: 2;
42664
+ grid-row: 1;
42665
+ }
42666
+
42667
+ :where(.theme-scope) .shop--register .shop__card-details {
42668
+ grid-column: 1 / -1;
42669
+ grid-row: 2;
42670
+ }
42671
+
42672
+ :where(.theme-scope) .shop--register .shop__cta {
42673
+ grid-column: 1 / -1;
42674
+ grid-row: 3;
42675
+ justify-self: start;
42676
+ margin-left: 0;
42677
+ }
42678
+ }
42679
+ }
42680
+
41984
42681
  /* Product card */
41985
42682
  :where(.theme-scope) .shop__card {
41986
42683
  background: rgb(var(--tb-surface));
@@ -42009,7 +42706,7 @@ const containerResponsiveThemeCss = `/*
42009
42706
  :where(.theme-scope) .shop__card-name {
42010
42707
  font-size: 1.125rem;
42011
42708
  font-weight: 600;
42012
- color: rgb(var(--tb-text));
42709
+ color: var(--rb-surface-heading-color, rgb(var(--tb-text)));
42013
42710
  margin: 0;
42014
42711
  font-family: var(--font-heading);
42015
42712
  }
@@ -42017,19 +42714,19 @@ const containerResponsiveThemeCss = `/*
42017
42714
  :where(.theme-scope) .shop__card-price {
42018
42715
  font-size: 1.125rem;
42019
42716
  font-weight: 700;
42020
- color: rgb(var(--tb-primary));
42717
+ color: var(--rb-surface-link-color, rgb(var(--tb-primary)));
42021
42718
  white-space: nowrap;
42022
42719
  }
42023
42720
 
42024
42721
  :where(.theme-scope) .shop__card-interval {
42025
42722
  font-size: 0.875rem;
42026
42723
  font-weight: 400;
42027
- color: rgb(var(--tb-mutedText));
42724
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42028
42725
  }
42029
42726
 
42030
42727
  :where(.theme-scope) .shop__card-description {
42031
42728
  font-size: 0.875rem;
42032
- color: rgb(var(--tb-mutedText));
42729
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42033
42730
  line-height: 1.5;
42034
42731
  margin: 0;
42035
42732
  }
@@ -42039,7 +42736,7 @@ const containerResponsiveThemeCss = `/*
42039
42736
  flex-wrap: wrap;
42040
42737
  gap: 0.5rem 1rem;
42041
42738
  font-size: 0.875rem;
42042
- color: rgb(var(--tb-text));
42739
+ color: var(--rb-surface-text-color, rgb(var(--tb-text)));
42043
42740
  }
42044
42741
 
42045
42742
  :where(.theme-scope) .shop__card-credits {
@@ -42047,16 +42744,16 @@ const containerResponsiveThemeCss = `/*
42047
42744
  }
42048
42745
 
42049
42746
  :where(.theme-scope) .shop__card-per-credit {
42050
- color: rgb(var(--tb-mutedText));
42747
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42051
42748
  }
42052
42749
 
42053
42750
  :where(.theme-scope) .shop__card-validity {
42054
- color: rgb(var(--tb-mutedText));
42751
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
42055
42752
  }
42056
42753
 
42057
42754
  :where(.theme-scope) .shop__card-unlimited {
42058
42755
  font-weight: 500;
42059
- color: rgb(var(--tb-secondary, var(--tb-primary)));
42756
+ color: var(--rb-surface-link-color, rgb(var(--tb-secondary, var(--tb-primary))));
42060
42757
  }
42061
42758
 
42062
42759
  /* CTA layout: use theme button classes for visuals */
@@ -43113,6 +43810,16 @@ const containerResponsiveThemeCss = `/*
43113
43810
  * tokens only. Node structure is built in testimonialsCarousel.ts.
43114
43811
  * ============================================================================= */
43115
43812
 
43813
+ /* Establish an inline-size query container so the head and grid below respond
43814
+ * to the block's own width, not the browser viewport. A viewport @media query
43815
+ * collapses to 1-col in the dashboard's scaled preview canvas (which reads the
43816
+ * dashboard window, not the canvas) and when the block sits in a narrow column;
43817
+ * @container tracks the actual laid-out width — matching the split-grid variant. */
43818
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe {
43819
+ container-type: inline-size;
43820
+ container-name: rb-testimonials-fe;
43821
+ }
43822
+
43116
43823
  /* Section head: heading left, lead-in line to the right; stacks on mobile. */
43117
43824
  :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-head {
43118
43825
  display: flex;
@@ -43125,16 +43832,14 @@ const containerResponsiveThemeCss = `/*
43125
43832
  max-width: 30rem;
43126
43833
  }
43127
43834
 
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 {
43835
+ @container rb-testimonials-fe (min-width: 768px) {
43836
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-head {
43131
43837
  flex-direction: row;
43132
43838
  align-items: flex-end;
43133
43839
  justify-content: space-between;
43134
43840
  gap: 1.5rem;
43135
43841
  }
43136
43842
  }
43137
- }
43138
43843
 
43139
43844
  /* Card grid: featured (wider) beside the stacked column. Single column on
43140
43845
  * small screens. */
@@ -43145,13 +43850,11 @@ const containerResponsiveThemeCss = `/*
43145
43850
  align-items: stretch;
43146
43851
  }
43147
43852
 
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 {
43853
+ @container rb-testimonials-fe (min-width: 1024px) {
43854
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-grid {
43151
43855
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
43152
43856
  }
43153
43857
  }
43154
- }
43155
43858
 
43156
43859
  :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-col {
43157
43860
  display: grid;
@@ -44476,6 +45179,52 @@ const containerResponsiveThemeCss = `/*
44476
45179
  }
44477
45180
  }
44478
45181
 
45182
+ /* =============================================================================
45183
+ * Editorial Split Variant
45184
+ * =============================================================================
45185
+ */
45186
+
45187
+ :where(.theme-scope) .newsletter-editorial-split {
45188
+ display: grid;
45189
+ grid-template-columns: minmax(0, 0.9fr) minmax(20rem, 1.1fr);
45190
+ gap: clamp(2.5rem, 7vw, 7rem);
45191
+ align-items: center;
45192
+ text-align: left;
45193
+ }
45194
+
45195
+ :where(.theme-scope) .newsletter-editorial-split-copy {
45196
+ display: flex;
45197
+ flex-direction: column;
45198
+ gap: var(--rb-gap-sm, 0.75rem);
45199
+ }
45200
+
45201
+ :where(.theme-scope) .newsletter-editorial-split-form {
45202
+ min-width: 0;
45203
+ }
45204
+
45205
+ :where(.theme-scope) .newsletter-editorial-split .newsletter-form {
45206
+ max-width: none;
45207
+ margin-inline: 0;
45208
+ }
45209
+
45210
+ :where(.theme-scope) .newsletter-editorial-split .newsletter-copy-title {
45211
+ font-size: clamp(2rem, 4vw, 3.5rem);
45212
+ font-weight: 500;
45213
+ }
45214
+
45215
+ :where(.theme-scope) .newsletter-editorial-split .newsletter-privacy-note {
45216
+ text-align: left;
45217
+ }
45218
+
45219
+ @container rb-site (max-width: 767px) {
45220
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
45221
+ :where(.theme-scope) .newsletter-editorial-split {
45222
+ grid-template-columns: minmax(0, 1fr);
45223
+ gap: 2rem;
45224
+ }
45225
+ }
45226
+ }
45227
+
44479
45228
  /* =============================================================================
44480
45229
  * Success State
44481
45230
  * =============================================================================
@@ -45491,13 +46240,13 @@ const containerResponsiveThemeCss = `/*
45491
46240
  * bleeds to the card edges and the inner content stack drops its fallback
45492
46241
  * padding so insets don't double up.
45493
46242
  */
45494
- :where(.theme-scope) .rb-feature-card[class*="rb-container-pad-"]:not(.rb-container-pad-none) > .rb-feature-card-media {
46243
+ :where(.theme-scope) .rb-feature-card[class*="rb-container-pad-"]:not(.rb-container-pad-none) > .rb-feature-card-media-frame {
45495
46244
  width: calc(100% + 2 * var(--rb-card-pad, 0rem));
45496
46245
  max-width: none;
45497
46246
  margin: calc(-1 * var(--rb-card-pad, 0rem)) calc(-1 * var(--rb-card-pad, 0rem)) 0;
45498
46247
  }
45499
46248
 
45500
- :where(.theme-scope) .rb-feature-card[class*="rb-container-pad-"]:not(.rb-container-pad-none) > .rb-feature-card-media + .rb-feature-card-content {
46249
+ :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
46250
  margin-top: 1.4rem;
45502
46251
  }
45503
46252
 
@@ -45548,11 +46297,122 @@ const containerResponsiveThemeCss = `/*
45548
46297
  background: rgb(var(--tb-primary, 0 0 0));
45549
46298
  }
45550
46299
 
45551
- :where(.theme-scope) .rb-card-treatment-editorial-rule > .rb-feature-card-media {
46300
+ :where(.theme-scope) .rb-card-treatment-editorial-rule > .rb-feature-card-media-frame {
45552
46301
  margin-top: 1.6rem;
45553
46302
  border-radius: calc(var(--rb-block-radius, 0.75rem) * 0.5);
45554
46303
  }
45555
46304
 
46305
+ :where(.theme-scope) .rb-feature-card > .rb-bg-surface,
46306
+ :where(.theme-scope) .rb-feature-card > .rb-feature-card-media-frame {
46307
+ border-start-start-radius: inherit;
46308
+ border-start-end-radius: inherit;
46309
+ }
46310
+
46311
+ /* --- Editorial diptych + pathways ----------------------------------------- */
46312
+
46313
+ :where(.theme-scope) .rb-feature-cards-heading--editorial {
46314
+ margin-inline: 0;
46315
+ text-align: left;
46316
+ }
46317
+
46318
+ :where(.theme-scope) .rb-feature-cards-eyebrow {
46319
+ margin: 0;
46320
+ color: rgb(var(--tb-accent));
46321
+ font-size: 0.72rem;
46322
+ font-weight: 600;
46323
+ letter-spacing: 0.14em;
46324
+ text-transform: uppercase;
46325
+ }
46326
+
46327
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych {
46328
+ grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
46329
+ align-items: stretch;
46330
+ }
46331
+
46332
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways {
46333
+ grid-template-columns: repeat(2, minmax(0, 1fr));
46334
+ align-items: start;
46335
+ }
46336
+
46337
+ :where(.theme-scope) .rb-feature-cards-grid:is(
46338
+ .rb-feature-cards-grid--editorial-diptych,
46339
+ .rb-feature-cards-grid--editorial-pathways
46340
+ ) .rb-feature-card {
46341
+ border: 0;
46342
+ box-shadow: none;
46343
+ height: auto;
46344
+ min-width: 0;
46345
+ }
46346
+
46347
+ :where(.theme-scope) .rb-feature-cards-grid:is(
46348
+ .rb-feature-cards-grid--editorial-diptych,
46349
+ .rb-feature-cards-grid--editorial-pathways
46350
+ ) .rb-feature-card[data-surface-role="open"] > .rb-bg-surface {
46351
+ background: transparent;
46352
+ }
46353
+
46354
+ :where(.theme-scope) .rb-feature-cards-grid:is(
46355
+ .rb-feature-cards-grid--editorial-diptych,
46356
+ .rb-feature-cards-grid--editorial-pathways
46357
+ ) .rb-feature-card[data-surface-role="open"] > .rb-feature-card-content {
46358
+ padding-inline: 0;
46359
+ }
46360
+
46361
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways .rb-feature-card > .rb-bg-surface {
46362
+ background: transparent;
46363
+ }
46364
+
46365
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways .rb-feature-card > .rb-feature-card-content {
46366
+ padding-inline: 0;
46367
+ }
46368
+
46369
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych .rb-feature-card[data-surface-role="panel"] {
46370
+ color: rgb(var(--tb-onPrimary));
46371
+ --rb-surface-text-color: rgb(var(--tb-onPrimary));
46372
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary));
46373
+ --rb-surface-link-color: rgb(var(--tb-onPrimary));
46374
+ --rb-surface-supporting-color: color-mix(in oklab, rgb(var(--tb-onPrimary)), transparent 18%);
46375
+ }
46376
+
46377
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych .rb-feature-card[data-surface-role="panel"] > .rb-bg-surface {
46378
+ background: rgb(var(--tb-primary));
46379
+ border-radius: inherit;
46380
+ }
46381
+
46382
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych .rb-feature-card[data-surface-role="panel"] > .rb-feature-card-media-frame {
46383
+ width: calc(100% - 2.5rem);
46384
+ margin: 1.25rem 1.25rem 0;
46385
+ border-radius: calc(var(--rb-block-radius, 0.75rem) * 0.55);
46386
+ }
46387
+
46388
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways .rb-feature-card-content {
46389
+ padding-top: 1.35rem;
46390
+ }
46391
+
46392
+ @container rb-site (min-width: 768px) {
46393
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46394
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-diptych .rb-feature-card[data-surface-role="panel"] {
46395
+ margin-top: clamp(2rem, 5vw, 4.5rem);
46396
+ }
46397
+
46398
+ :where(.theme-scope) .rb-feature-cards-grid--editorial-pathways .rb-feature-card + .rb-feature-card {
46399
+ border-left: 1px solid color-mix(in oklab, currentColor, transparent 82%);
46400
+ padding-left: clamp(1.5rem, 4vw, 4rem);
46401
+ }
46402
+ }
46403
+ }
46404
+
46405
+ @container rb-site (max-width: 767px) {
46406
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46407
+ :where(.theme-scope) .rb-feature-cards-grid:is(
46408
+ .rb-feature-cards-grid--editorial-diptych,
46409
+ .rb-feature-cards-grid--editorial-pathways
46410
+ ) {
46411
+ grid-template-columns: minmax(0, 1fr);
46412
+ }
46413
+ }
46414
+ }
46415
+
45556
46416
  :where(.theme-scope) .rb-card-treatment-editorial-rule > .rb-feature-card-content {
45557
46417
  padding: 1.6rem 0 0.25rem;
45558
46418
  }
@@ -45641,12 +46501,12 @@ const containerResponsiveThemeCss = `/*
45641
46501
  }
45642
46502
  }
45643
46503
 
45644
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-portrait-bio"][data-block-variant="media-copy"] .rb-intro-media-wrap {
46504
+ :where(.theme-scope) [data-block="intro"][data-block-composition="portrait-bio"][data-block-variant="media-copy"] .rb-intro-media-wrap {
45645
46505
  max-width: min(100%, 24rem);
45646
46506
  margin-inline: auto;
45647
46507
  }
45648
46508
 
45649
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-portrait-bio"][data-block-variant="media-copy"] .rb-intro-media {
46509
+ :where(.theme-scope) [data-block="intro"][data-block-composition="portrait-bio"][data-block-variant="media-copy"] .rb-intro-media {
45650
46510
  aspect-ratio: 1 / 1 !important;
45651
46511
  border-radius: 9999px;
45652
46512
  }
@@ -45667,18 +46527,914 @@ const containerResponsiveThemeCss = `/*
45667
46527
  }
45668
46528
  }
45669
46529
 
45670
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-editorial-statement"] .rb-intro-title {
46530
+ :where(.theme-scope) [data-block="intro"][data-block-composition="editorial-statement"] .rb-intro-title {
45671
46531
  font-size: clamp(2rem, 1.56rem + 1.4vw, 3rem);
45672
46532
  line-height: 1.14;
45673
46533
  }
45674
46534
 
45675
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-editorial-statement"] .rb-intro-copy {
46535
+ :where(.theme-scope) [data-block="intro"][data-block-composition="editorial-statement"] .rb-intro-copy {
45676
46536
  gap: var(--rb-space-5, 1.25rem);
45677
46537
  }
45678
46538
 
45679
- :where(.theme-scope) [data-block="intro"][data-block-look="intro-editorial-statement"] .rb-intro-copy .rb-prose {
46539
+ :where(.theme-scope) [data-block="intro"][data-block-composition="editorial-statement"] .rb-intro-copy .rb-prose {
45680
46540
  font-size: clamp(1.125rem, 1.02rem + 0.35vw, 1.375rem);
45681
46541
  line-height: 1.65;
46542
+ }
46543
+
46544
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-section {
46545
+ width: min(100%, 66rem);
46546
+ margin-inline: auto;
46547
+ }
46548
+
46549
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-heading {
46550
+ max-width: 44rem;
46551
+ }
46552
+
46553
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-header {
46554
+ display: flex;
46555
+ gap: 2rem;
46556
+ align-items: end;
46557
+ justify-content: space-between;
46558
+ }
46559
+
46560
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-eyebrow {
46561
+ margin: 0;
46562
+ color: rgb(var(--tb-accent));
46563
+ font-size: 0.72rem;
46564
+ font-weight: 600;
46565
+ letter-spacing: 0.14em;
46566
+ text-transform: uppercase;
46567
+ }
46568
+
46569
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-heading-title {
46570
+ margin: 0;
46571
+ font-size: clamp(2rem, 4.6vw, 3.3rem);
46572
+ line-height: 1.08;
46573
+ }
46574
+
46575
+ :where(.theme-scope) .recurring-schedule {
46576
+ border-top: 1px solid color-mix(in oklab, currentColor, transparent 78%);
46577
+ }
46578
+
46579
+ :where(.theme-scope) .recurring-schedule-row {
46580
+ display: grid;
46581
+ grid-template-columns: minmax(9rem, 0.82fr) minmax(16rem, 1.5fr) auto;
46582
+ grid-template-rows: auto auto;
46583
+ column-gap: clamp(1.5rem, 4vw, 2.75rem);
46584
+ row-gap: 0.15rem;
46585
+ align-items: center;
46586
+ padding: 1.4rem 0.75rem;
46587
+ border-bottom: 1px solid color-mix(in oklab, currentColor, transparent 78%);
46588
+ color: inherit;
46589
+ }
46590
+
46591
+ :where(.theme-scope) .recurring-schedule-day,
46592
+ :where(.theme-scope) .recurring-schedule-time,
46593
+ :where(.theme-scope) .recurring-schedule-title,
46594
+ :where(.theme-scope) .recurring-schedule-venue {
46595
+ margin: 0;
46596
+ }
46597
+
46598
+ :where(.theme-scope) .recurring-schedule-day {
46599
+ grid-column: 1;
46600
+ grid-row: 1;
46601
+ font-family: var(--font-heading);
46602
+ font-size: clamp(1.25rem, 2vw, 1.5rem);
46603
+ line-height: 1;
46604
+ }
46605
+
46606
+ :where(.theme-scope) .recurring-schedule-time {
46607
+ grid-column: 1;
46608
+ grid-row: 2;
46609
+ display: flex;
46610
+ gap: 0.35rem;
46611
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
46612
+ font-size: 0.86rem;
46613
+ font-variant-numeric: tabular-nums;
46614
+ }
46615
+
46616
+ :where(.theme-scope) .recurring-schedule-details {
46617
+ grid-column: 2;
46618
+ grid-row: 1 / span 2;
46619
+ align-self: center;
46620
+ }
46621
+
46622
+ :where(.theme-scope) .recurring-schedule-title {
46623
+ font-size: 1.06rem;
46624
+ font-weight: 500;
46625
+ }
46626
+
46627
+ :where(.theme-scope) .recurring-schedule-venue {
46628
+ margin-top: 0.2rem;
46629
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
46630
+ font-size: 0.92rem;
46631
+ }
46632
+
46633
+ :where(.theme-scope) .recurring-schedule-action {
46634
+ grid-column: 3;
46635
+ grid-row: 1 / span 2;
46636
+ min-width: 4.5rem;
46637
+ text-align: right;
46638
+ }
46639
+
46640
+ :where(.theme-scope) .recurring-schedule-see-all {
46641
+ width: fit-content;
46642
+ color: inherit;
46643
+ text-underline-offset: 0.3em;
46644
+ }
46645
+
46646
+ :where(.theme-scope) .recurring-schedule-empty {
46647
+ margin: 0;
46648
+ color: var(--rb-surface-supporting-color, rgb(var(--tb-mutedText)));
46649
+ }
46650
+
46651
+ @container rb-site (max-width: 767px) {
46652
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46653
+ :where(.theme-scope) :where([data-block="recurring-schedule"]) .recurring-schedule-header {
46654
+ align-items: start;
46655
+ flex-direction: column;
46656
+ gap: 1rem;
46657
+ }
46658
+
46659
+ :where(.theme-scope) .recurring-schedule-row {
46660
+ grid-template-columns: 1fr auto;
46661
+ grid-template-rows: auto auto auto;
46662
+ gap: 0.5rem 1rem;
46663
+ align-items: start;
46664
+ }
46665
+
46666
+ :where(.theme-scope) .recurring-schedule-day {
46667
+ grid-column: 1;
46668
+ }
46669
+
46670
+ :where(.theme-scope) .recurring-schedule-time {
46671
+ grid-column: 1;
46672
+ }
46673
+
46674
+ :where(.theme-scope) .recurring-schedule-details {
46675
+ grid-column: 1 / -1;
46676
+ grid-row: 3;
46677
+ margin-top: 0.35rem;
46678
+ }
46679
+
46680
+ :where(.theme-scope) .recurring-schedule-action {
46681
+ grid-column: 2;
46682
+ grid-row: 1 / span 2;
46683
+ }
46684
+ }
46685
+ }
46686
+
46687
+ /* =============================================================================
46688
+ * Event list treatments: registers and dense indexes
46689
+ *
46690
+ * These treatments retain the event list's content and structural layout.
46691
+ * Their contrast relationships come exclusively from the active semantic
46692
+ * section surface and named palette tokens.
46693
+ * ============================================================================= */
46694
+
46695
+ :where(.theme-scope)
46696
+ :where(
46697
+ .rb-event-list-treatment-ruled-register,
46698
+ .rb-event-list-treatment-editorial-register,
46699
+ .rb-event-list-treatment-dense-index
46700
+ )
46701
+ .event-card.event-card {
46702
+ position: relative;
46703
+ overflow: visible;
46704
+ border: 0;
46705
+ border-radius: 0;
46706
+ background: transparent;
46707
+ box-shadow: none;
46708
+ color: inherit;
46709
+ }
46710
+
46711
+ /* Register treatments intentionally prioritise schedule data over imagery. */
46712
+ :where(.theme-scope)
46713
+ :where(
46714
+ .rb-event-list-treatment-ruled-register,
46715
+ .rb-event-list-treatment-editorial-register,
46716
+ .rb-event-list-treatment-dense-index
46717
+ )
46718
+ .event-card.event-card
46719
+ .event-card-media {
46720
+ display: none;
46721
+ }
46722
+
46723
+ :where(.theme-scope)
46724
+ :where(
46725
+ .rb-event-list-treatment-ruled-register,
46726
+ .rb-event-list-treatment-editorial-register,
46727
+ .rb-event-list-treatment-dense-index
46728
+ )
46729
+ .event-card.event-card
46730
+ .card-content {
46731
+ min-width: 0;
46732
+ padding: 1.5rem 0.625rem;
46733
+ }
46734
+
46735
+ :where(.theme-scope)
46736
+ :where(
46737
+ .rb-event-list-treatment-ruled-register,
46738
+ .rb-event-list-treatment-editorial-register,
46739
+ .rb-event-list-treatment-dense-index
46740
+ )
46741
+ .event-card.event-card
46742
+ .card-title {
46743
+ min-width: 0;
46744
+ margin-bottom: 0.25rem;
46745
+ }
46746
+
46747
+ :where(.theme-scope)
46748
+ :where(
46749
+ .rb-event-list-treatment-ruled-register,
46750
+ .rb-event-list-treatment-editorial-register,
46751
+ .rb-event-list-treatment-dense-index
46752
+ )
46753
+ .event-card.event-card
46754
+ .event-card-footer {
46755
+ min-width: 8rem;
46756
+ padding-top: 0;
46757
+ }
46758
+
46759
+ :where(.theme-scope)
46760
+ :where(
46761
+ .rb-event-list-treatment-ruled-register,
46762
+ .rb-event-list-treatment-editorial-register,
46763
+ .rb-event-list-treatment-dense-index
46764
+ )
46765
+ .event-card.event-card
46766
+ .event-card-cta {
46767
+ width: 100%;
46768
+ }
46769
+
46770
+ /* Ruled register: open rows with quiet rules on the current section surface. */
46771
+ :where(.theme-scope)
46772
+ .rb-event-list-treatment-ruled-register
46773
+ .event-card.event-card {
46774
+ border-top: 1px solid color-mix(in oklab, currentColor, transparent 78%);
46775
+ }
46776
+
46777
+ :where(.theme-scope)
46778
+ .rb-event-list-treatment-ruled-register
46779
+ .event-card.event-card:last-child {
46780
+ border-bottom: 1px solid color-mix(in oklab, currentColor, transparent 78%);
46781
+ }
46782
+
46783
+ /* Editorial register: generous rows, an accent marker and display-led titles. */
46784
+ :where(.theme-scope)
46785
+ .rb-event-list-treatment-editorial-register
46786
+ .event-card.event-card {
46787
+ border-top: 1px solid color-mix(in oklab, rgb(var(--tb-border)), transparent 20%);
46788
+ }
46789
+
46790
+ :where(.theme-scope)
46791
+ .rb-event-list-treatment-editorial-register
46792
+ .event-card.event-card:last-child {
46793
+ border-bottom: 1px solid color-mix(in oklab, rgb(var(--tb-border)), transparent 20%);
46794
+ }
46795
+
46796
+ :where(.theme-scope)
46797
+ .rb-event-list-treatment-editorial-register
46798
+ .event-card.event-card::before {
46799
+ content: "";
46800
+ position: absolute;
46801
+ inset-block: 1.75rem;
46802
+ inset-inline-start: 0;
46803
+ width: 0.25rem;
46804
+ border-radius: var(--rb-block-radius, 0.75rem);
46805
+ background: rgb(var(--tb-accent));
46806
+ }
46807
+
46808
+ :where(.theme-scope)
46809
+ .rb-event-list-treatment-editorial-register
46810
+ .event-card.event-card
46811
+ .card-content {
46812
+ padding-block: 1.875rem;
46813
+ padding-inline-start: clamp(1.25rem, 2.5vw, 2rem);
46814
+ }
46815
+
46816
+ :where(.theme-scope)
46817
+ .rb-event-list-treatment-editorial-register
46818
+ .event-card.event-card
46819
+ .card-title {
46820
+ font-family: var(--font-heading, var(--font-body, inherit));
46821
+ font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
46822
+ font-weight: 500;
46823
+ line-height: 1.15;
46824
+ }
46825
+
46826
+ /* Dense index: stronger outside rule and reduced row rhythm, without opting
46827
+ * the block into its structurally different compact-list facet. */
46828
+ :where(.theme-scope)
46829
+ .rb-event-list-treatment-dense-index
46830
+ .event-card.event-card {
46831
+ border-bottom: 1px solid color-mix(in oklab, currentColor, transparent 62%);
46832
+ }
46833
+
46834
+ :where(.theme-scope)
46835
+ .rb-event-list-treatment-dense-index
46836
+ .event-card.event-card:first-child {
46837
+ border-top: 2px solid currentColor;
46838
+ }
46839
+
46840
+ :where(.theme-scope)
46841
+ .rb-event-list-treatment-dense-index
46842
+ .event-card.event-card
46843
+ .card-content {
46844
+ padding-block: 1.125rem;
46845
+ }
46846
+
46847
+ :where(.theme-scope)
46848
+ .rb-event-list-treatment-dense-index
46849
+ .event-card.event-card
46850
+ .card-title {
46851
+ font-size: 1rem;
46852
+ line-height: 1.35;
46853
+ }
46854
+
46855
+ @container rb-site (min-width: 768px) {
46856
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
46857
+ :where(.theme-scope)
46858
+ :where(
46859
+ .rb-event-list-treatment-ruled-register,
46860
+ .rb-event-list-treatment-editorial-register,
46861
+ .rb-event-list-treatment-dense-index
46862
+ )
46863
+ .event-card.event-card.event-card--horizontal {
46864
+ display: block;
46865
+ }
46866
+
46867
+ :where(.theme-scope)
46868
+ :where(
46869
+ .rb-event-list-treatment-ruled-register,
46870
+ .rb-event-list-treatment-editorial-register,
46871
+ .rb-event-list-treatment-dense-index
46872
+ )
46873
+ .event-card.event-card.event-card--horizontal
46874
+ .card-content {
46875
+ display: grid;
46876
+ grid-template-columns: minmax(8.5rem, 0.7fr) minmax(15rem, 1.55fr) auto;
46877
+ grid-template-rows: auto auto auto;
46878
+ align-items: center;
46879
+ column-gap: clamp(1.25rem, 3vw, 2.625rem);
46880
+ }
46881
+
46882
+ :where(.theme-scope)
46883
+ :where(
46884
+ .rb-event-list-treatment-ruled-register,
46885
+ .rb-event-list-treatment-editorial-register,
46886
+ .rb-event-list-treatment-dense-index
46887
+ )
46888
+ .event-card.event-card.event-card--horizontal
46889
+ .card-title {
46890
+ grid-column: 2;
46891
+ }
46892
+
46893
+ :where(.theme-scope)
46894
+ :where(
46895
+ .rb-event-list-treatment-ruled-register,
46896
+ .rb-event-list-treatment-editorial-register,
46897
+ .rb-event-list-treatment-dense-index
46898
+ )
46899
+ .event-card.event-card.event-card--horizontal
46900
+ .card-content > div.rb-caption {
46901
+ grid-column: 1;
46902
+ grid-row: 1 / span 6;
46903
+ margin-bottom: 0;
46904
+ }
46905
+
46906
+ :where(.theme-scope)
46907
+ :where(
46908
+ .rb-event-list-treatment-ruled-register,
46909
+ .rb-event-list-treatment-editorial-register,
46910
+ .rb-event-list-treatment-dense-index
46911
+ )
46912
+ .event-card.event-card.event-card--horizontal
46913
+ .card-content > div.rb-mb-3 {
46914
+ grid-column: 2;
46915
+ margin-bottom: 0;
46916
+ }
46917
+
46918
+ :where(.theme-scope)
46919
+ :where(
46920
+ .rb-event-list-treatment-ruled-register,
46921
+ .rb-event-list-treatment-editorial-register,
46922
+ .rb-event-list-treatment-dense-index
46923
+ )
46924
+ .event-card.event-card.event-card--horizontal
46925
+ .card-content > .event-category-badge {
46926
+ grid-column: 2;
46927
+ }
46928
+
46929
+ :where(.theme-scope)
46930
+ :where(
46931
+ .rb-event-list-treatment-ruled-register,
46932
+ .rb-event-list-treatment-editorial-register,
46933
+ .rb-event-list-treatment-dense-index
46934
+ )
46935
+ .event-card.event-card.event-card--horizontal
46936
+ .card-content > .card-body,
46937
+ :where(.theme-scope)
46938
+ :where(
46939
+ .rb-event-list-treatment-ruled-register,
46940
+ .rb-event-list-treatment-editorial-register,
46941
+ .rb-event-list-treatment-dense-index
46942
+ )
46943
+ .event-card.event-card.event-card--horizontal
46944
+ .card-content > .status-muted:not(.event-card-capacity) {
46945
+ grid-column: 2;
46946
+ }
46947
+
46948
+ :where(.theme-scope)
46949
+ :where(
46950
+ .rb-event-list-treatment-ruled-register,
46951
+ .rb-event-list-treatment-editorial-register,
46952
+ .rb-event-list-treatment-dense-index
46953
+ )
46954
+ .event-card.event-card.event-card--horizontal
46955
+ .event-card-footer {
46956
+ grid-column: 3;
46957
+ grid-row: 1 / span 6;
46958
+ flex-direction: column;
46959
+ justify-content: center;
46960
+ align-items: stretch;
46961
+ }
46962
+ }
46963
+ }
46964
+
46965
+ /* =============================================================================
46966
+ * Feature-card composition Looks promoted from block-treatment studies.
46967
+ * Palette relationships use named semantic tokens; copy and media stay in the
46968
+ * existing feature-card content contract.
46969
+ * ============================================================================= */
46970
+
46971
+ /* Asymmetric emphasis: repeat a 5/7 pair rhythm and give each even card a
46972
+ * semantic secondary surface. This remains useful with more than two cards. */
46973
+ :where(.theme-scope)
46974
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46975
+ .rb-feature-cards-grid {
46976
+ align-items: start;
46977
+ }
46978
+ :where(.theme-scope)
46979
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46980
+ .rb-feature-card {
46981
+ height: auto;
46982
+ overflow: visible;
46983
+ border: 0;
46984
+ border-radius: 0;
46985
+ background: transparent;
46986
+ }
46987
+
46988
+ :where(.theme-scope)
46989
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46990
+ .rb-feature-card > .rb-feature-card-content {
46991
+ padding-inline: 0;
46992
+ }
46993
+
46994
+ :where(.theme-scope)
46995
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
46996
+ .rb-feature-card:nth-child(even) {
46997
+ padding: clamp(1.125rem, 2.5vw, 1.875rem);
46998
+ border-radius: calc(var(--rb-block-radius, 0.75rem) * 1.5);
46999
+ background: rgb(var(--tb-secondary));
47000
+ color: rgb(var(--tb-onSecondary));
47001
+ --rb-surface-text-color: rgb(var(--tb-onSecondary));
47002
+ --rb-surface-heading-color: rgb(var(--tb-onSecondary));
47003
+ --rb-surface-link-color: rgb(var(--tb-onSecondary));
47004
+ --rb-surface-supporting-color: rgb(var(--tb-onSecondary));
47005
+ }
47006
+
47007
+ :where(.theme-scope)
47008
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
47009
+ .rb-feature-card:nth-child(even) > .rb-feature-card-media {
47010
+ border-radius: var(--rb-block-radius, 0.75rem);
47011
+ }
47012
+
47013
+ /* Framed programme: a close-set family of inset cards on a semantic depth
47014
+ * section. The itemSurface recipe supplies each complete surface provider. */
47015
+ :where(.theme-scope)
47016
+ [data-block="feature-cards"][data-block-composition="framed-programme"]
47017
+ .rb-feature-cards-grid {
47018
+ gap: clamp(1rem, 2vw, 1.5rem);
47019
+ }
47020
+
47021
+ :where(.theme-scope)
47022
+ [data-block="feature-cards"][data-block-composition="framed-programme"]
47023
+ .rb-feature-card > .rb-feature-card-media {
47024
+ width: 100%;
47025
+ max-width: 100%;
47026
+ margin: 0;
47027
+ border-radius: var(--rb-block-radius, 0.75rem);
47028
+ }
47029
+
47030
+ :where(.theme-scope)
47031
+ [data-block="feature-cards"][data-block-composition="framed-programme"]
47032
+ .rb-feature-card > .rb-feature-card-content {
47033
+ padding-inline: 0;
47034
+ padding-bottom: 0;
47035
+ }
47036
+
47037
+ @container rb-site (min-width: 768px) {
47038
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
47039
+ :where(.theme-scope)
47040
+ [data-block="feature-cards"][data-block-composition="asymmetric-emphasis"]
47041
+ .rb-feature-cards-grid.rb-grid-cols-2 {
47042
+ grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
47043
+ }
47044
+ }
47045
+ }
47046
+
47047
+ /* =============================================================================
47048
+ * Offerings Preview composition Looks promoted from the Fran André treatment
47049
+ * study. The outer section surface remains independently configurable. These
47050
+ * rules use expanded semantic palette tokens only.
47051
+ * ============================================================================= */
47052
+
47053
+ :where(.theme-scope)
47054
+ [data-block="offerings-preview"]
47055
+ [data-offering-presentation="featured-summary"]
47056
+ .offerings-preview-card-header {
47057
+ text-align: left;
47058
+ }
47059
+
47060
+ :where(.theme-scope)
47061
+ [data-block="offerings-preview"]
47062
+ .offerings-preview-summary-date {
47063
+ margin: 0;
47064
+ font-family: var(--font-heading, inherit);
47065
+ font-size: clamp(1.125rem, 2.2vw, 1.5rem);
47066
+ font-weight: 650;
47067
+ line-height: 1.22;
47068
+ }
47069
+
47070
+ :where(.theme-scope)
47071
+ [data-block="offerings-preview"]
47072
+ .offerings-preview-summary-date time {
47073
+ display: inline-block;
47074
+ }
47075
+
47076
+ :where(.theme-scope)
47077
+ [data-block="offerings-preview"]
47078
+ .offerings-preview-summary-facts {
47079
+ display: grid;
47080
+ gap: 0;
47081
+ margin: clamp(1.25rem, 3vw, 2rem) 0 0;
47082
+ }
47083
+
47084
+ :where(.theme-scope)
47085
+ [data-block="offerings-preview"]
47086
+ .offerings-preview-summary-facts > div {
47087
+ display: grid;
47088
+ grid-template-columns: minmax(5.5rem, 0.65fr) minmax(0, 1.35fr);
47089
+ gap: 1rem;
47090
+ padding-block: 0.6rem;
47091
+ border-top: 1px solid rgba(var(--tb-border), 0.72);
47092
+ }
47093
+
47094
+ :where(.theme-scope)
47095
+ [data-block="offerings-preview"]
47096
+ .offerings-preview-summary-facts dt {
47097
+ font-size: 0.72rem;
47098
+ font-weight: 750;
47099
+ letter-spacing: 0.1em;
47100
+ text-transform: uppercase;
47101
+ }
47102
+
47103
+ :where(.theme-scope)
47104
+ [data-block="offerings-preview"]
47105
+ .offerings-preview-summary-facts dd {
47106
+ min-width: 0;
47107
+ margin: 0;
47108
+ font-weight: 600;
47109
+ }
47110
+
47111
+ :where(.theme-scope)
47112
+ [data-block="offerings-preview"]:is(
47113
+ [data-block-look="offerings-preview-paired-feature-cards"],
47114
+ [data-block-look="offerings-preview-open-editorial-columns"],
47115
+ [data-block-look="offerings-preview-joined-programme-panel"]
47116
+ )
47117
+ .offerings-preview {
47118
+ container: rb-offerings-preview / inline-size;
47119
+ }
47120
+
47121
+ :where(.theme-scope)
47122
+ [data-block="offerings-preview"]:is(
47123
+ [data-block-look="offerings-preview-paired-feature-cards"],
47124
+ [data-block-look="offerings-preview-open-editorial-columns"],
47125
+ [data-block-look="offerings-preview-joined-programme-panel"]
47126
+ )
47127
+ .offerings-preview-card {
47128
+ min-width: 0;
47129
+ }
47130
+
47131
+ :where(.theme-scope)
47132
+ [data-block="offerings-preview"]:is(
47133
+ [data-block-look="offerings-preview-paired-feature-cards"],
47134
+ [data-block-look="offerings-preview-open-editorial-columns"],
47135
+ [data-block-look="offerings-preview-joined-programme-panel"]
47136
+ )
47137
+ .offerings-preview-card-content {
47138
+ padding: clamp(1.4rem, 3.5vw, 2.75rem);
47139
+ }
47140
+
47141
+ :where(.theme-scope)
47142
+ [data-block="offerings-preview"]:is(
47143
+ [data-block-look="offerings-preview-paired-feature-cards"],
47144
+ [data-block-look="offerings-preview-open-editorial-columns"],
47145
+ [data-block-look="offerings-preview-joined-programme-panel"]
47146
+ )
47147
+ .offerings-preview-card-footer {
47148
+ margin-top: auto;
47149
+ padding-top: clamp(1.25rem, 3vw, 2rem);
47150
+ }
47151
+
47152
+ /* Paired feature cards: one editorial lead and one supporting route. With a
47153
+ * third group the grid returns to equal columns rather than implying a new
47154
+ * source hierarchy. */
47155
+ :where(.theme-scope)
47156
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47157
+ .offerings-preview-grid {
47158
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)) !important;
47159
+ gap: clamp(1rem, 2.5vw, 1.5rem);
47160
+ }
47161
+
47162
+ :where(.theme-scope)
47163
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47164
+ .offerings-preview-card {
47165
+ overflow: hidden;
47166
+ border: 1px solid rgb(var(--tb-border));
47167
+ border-radius: calc(var(--rb-block-radius, 0.75rem) * 1.75);
47168
+ background: rgb(var(--tb-accent-200));
47169
+ color: rgb(var(--tb-onAccent200));
47170
+ --rb-surface-text-color: rgb(var(--tb-onAccent200));
47171
+ --rb-surface-heading-color: rgb(var(--tb-onAccent200));
47172
+ --rb-surface-link-color: rgb(var(--tb-onAccent200));
47173
+ --rb-surface-supporting-color: rgb(var(--tb-onAccent200));
47174
+ }
47175
+
47176
+ :where(.theme-scope)
47177
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47178
+ .offerings-preview-card:first-child {
47179
+ border-color: transparent;
47180
+ background: rgb(var(--tb-primary-950));
47181
+ color: rgb(var(--tb-onPrimary950));
47182
+ box-shadow: 0.55rem 0.55rem 0 rgb(var(--tb-secondary-100));
47183
+ --rb-surface-text-color: rgb(var(--tb-onPrimary950));
47184
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary950));
47185
+ --rb-surface-link-color: rgb(var(--tb-onPrimary950));
47186
+ --rb-surface-supporting-color: rgb(var(--tb-onPrimary950));
47187
+ }
47188
+
47189
+ :where(.theme-scope)
47190
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47191
+ .offerings-preview-card:first-child
47192
+ .offerings-preview-card-title {
47193
+ color: rgb(var(--tb-primary-200));
47194
+ }
47195
+
47196
+ @container rb-offerings-preview (min-width: 52rem) {
47197
+ :where(.theme-scope)
47198
+ [data-block="offerings-preview"][data-block-look="offerings-preview-paired-feature-cards"]
47199
+ .offerings-preview-grid:has(> .offerings-preview-card:nth-child(2):last-child) {
47200
+ grid-template-columns: minmax(0, 1.22fr) minmax(18rem, 0.78fr) !important;
47201
+ }
47202
+ }
47203
+
47204
+ /* Open editorial columns: composition and hierarchy without an item fill. */
47205
+ :where(.theme-scope)
47206
+ [data-block="offerings-preview"][data-block-look="offerings-preview-open-editorial-columns"]
47207
+ .offerings-preview-grid {
47208
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)) !important;
47209
+ gap: 0;
47210
+ border-block: 1px solid rgb(var(--tb-border));
47211
+ }
47212
+
47213
+ :where(.theme-scope)
47214
+ [data-block="offerings-preview"][data-block-look="offerings-preview-open-editorial-columns"]
47215
+ .offerings-preview-card {
47216
+ border: 0;
47217
+ border-radius: 0;
47218
+ background: transparent;
47219
+ color: var(--rb-surface-text-color, rgb(var(--tb-text)));
47220
+ }
47221
+
47222
+ :where(.theme-scope)
47223
+ [data-block="offerings-preview"][data-block-look="offerings-preview-open-editorial-columns"]
47224
+ .offerings-preview-card + .offerings-preview-card {
47225
+ border-top: 1px solid rgb(var(--tb-border));
47226
+ }
47227
+
47228
+ @container rb-offerings-preview (min-width: 46rem) {
47229
+ :where(.theme-scope)
47230
+ [data-block="offerings-preview"][data-block-look="offerings-preview-open-editorial-columns"]
47231
+ .offerings-preview-card + .offerings-preview-card {
47232
+ border-top: 0;
47233
+ border-left: 1px solid rgb(var(--tb-border));
47234
+ }
47235
+ }
47236
+
47237
+ /* Joined programme panel: every group remains independently editable but the
47238
+ * close-set bands read as one upcoming programme. */
47239
+ :where(.theme-scope)
47240
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47241
+ .offerings-preview {
47242
+ overflow: hidden;
47243
+ gap: 0;
47244
+ border: 1px solid rgb(var(--tb-border));
47245
+ border-radius: calc(var(--rb-block-radius, 0.75rem) * 1.75);
47246
+ background: rgb(var(--tb-surface));
47247
+ }
47248
+
47249
+ :where(.theme-scope)
47250
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47251
+ .offerings-preview-grid {
47252
+ grid-template-columns: minmax(0, 1fr) !important;
47253
+ gap: 0;
47254
+ }
47255
+
47256
+ :where(.theme-scope)
47257
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47258
+ .offerings-preview-card {
47259
+ border: 0;
47260
+ border-radius: 0;
47261
+ background: rgb(var(--tb-secondary-100));
47262
+ color: rgb(var(--tb-onSecondary100));
47263
+ --rb-surface-text-color: rgb(var(--tb-onSecondary100));
47264
+ --rb-surface-heading-color: rgb(var(--tb-onSecondary100));
47265
+ --rb-surface-link-color: rgb(var(--tb-onSecondary100));
47266
+ --rb-surface-supporting-color: rgb(var(--tb-onSecondary100));
47267
+ }
47268
+
47269
+ :where(.theme-scope)
47270
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47271
+ .offerings-preview-card:nth-child(2) {
47272
+ background: rgb(var(--tb-accent-200));
47273
+ color: rgb(var(--tb-onAccent200));
47274
+ --rb-surface-text-color: rgb(var(--tb-onAccent200));
47275
+ --rb-surface-heading-color: rgb(var(--tb-onAccent200));
47276
+ --rb-surface-link-color: rgb(var(--tb-onAccent200));
47277
+ --rb-surface-supporting-color: rgb(var(--tb-onAccent200));
47278
+ }
47279
+
47280
+ :where(.theme-scope)
47281
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47282
+ .offerings-preview-card:nth-child(3) {
47283
+ background: rgb(var(--tb-primary-100));
47284
+ color: rgb(var(--tb-onPrimary100));
47285
+ --rb-surface-text-color: rgb(var(--tb-onPrimary100));
47286
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary100));
47287
+ --rb-surface-link-color: rgb(var(--tb-onPrimary100));
47288
+ --rb-surface-supporting-color: rgb(var(--tb-onPrimary100));
47289
+ }
47290
+
47291
+ :where(.theme-scope)
47292
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47293
+ .offerings-preview-card + .offerings-preview-card {
47294
+ border-top: 1px solid rgb(var(--tb-border));
47295
+ }
47296
+
47297
+ @container rb-offerings-preview (min-width: 58rem) {
47298
+ :where(.theme-scope)
47299
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47300
+ .offerings-preview-card-content {
47301
+ display: grid;
47302
+ grid-template-columns: minmax(15rem, 1.1fr) minmax(19rem, 1.4fr) minmax(10rem, auto);
47303
+ align-items: center;
47304
+ gap: clamp(1.5rem, 4vw, 4rem);
47305
+ }
47306
+
47307
+ :where(.theme-scope)
47308
+ [data-block="offerings-preview"][data-block-look="offerings-preview-joined-programme-panel"]
47309
+ .offerings-preview-card-footer {
47310
+ margin-top: 0;
47311
+ padding-top: 0;
47312
+ justify-content: flex-end;
47313
+ }
47314
+ }
47315
+
47316
+ /* =============================================================================
47317
+ * Featured-editorial testimonial Looks promoted from the Fran André treatment
47318
+ * study. These rules do not set the outer section background.
47319
+ * ============================================================================= */
47320
+
47321
+ :where(.theme-scope)
47322
+ [data-block="testimonials"]:is(
47323
+ [data-block-look="testimonials-evergreen-lead"],
47324
+ [data-block-look="testimonials-room-and-response"],
47325
+ [data-block-look="testimonials-open-floor"]
47326
+ )
47327
+ .rb-testimonials-fe-card--feature {
47328
+ background: rgb(var(--tb-secondary-900));
47329
+ color: rgb(var(--tb-onSecondary900));
47330
+ --rb-surface-text-color: rgb(var(--tb-onSecondary900));
47331
+ --rb-surface-heading-color: rgb(var(--tb-onSecondary900));
47332
+ --rb-surface-link-color: rgb(var(--tb-onSecondary900));
47333
+ --rb-surface-supporting-color: rgb(var(--tb-onSecondary900));
47334
+ }
47335
+
47336
+ :where(.theme-scope)
47337
+ [data-block="testimonials"]:is(
47338
+ [data-block-look="testimonials-evergreen-lead"],
47339
+ [data-block-look="testimonials-room-and-response"],
47340
+ [data-block-look="testimonials-open-floor"]
47341
+ )
47342
+ .rb-testimonials-fe-card--feature
47343
+ .rb-testimonials-fe-qmark {
47344
+ color: rgb(var(--tb-primary-200));
47345
+ }
47346
+
47347
+ :where(.theme-scope)
47348
+ [data-block="testimonials"]:is(
47349
+ [data-block-look="testimonials-evergreen-lead"],
47350
+ [data-block-look="testimonials-room-and-response"],
47351
+ [data-block-look="testimonials-open-floor"]
47352
+ )
47353
+ .rb-testimonials-fe-card--feature
47354
+ :is(.rb-testimonials-fe-quote p, .rb-testimonials-fe-name, .rb-testimonials-fe-context) {
47355
+ color: rgb(var(--tb-onSecondary900));
47356
+ }
47357
+
47358
+ /* Evergreen lead: the feature remains dominant while the supporting column
47359
+ * opens into two equal compact voices at wider widths. */
47360
+ @container rb-testimonials-fe (min-width: 1024px) {
47361
+ :where(.theme-scope)
47362
+ [data-block="testimonials"][data-block-look="testimonials-evergreen-lead"]
47363
+ .rb-testimonials-fe-grid {
47364
+ grid-template-columns: minmax(0, 1.15fr) minmax(0, 1.55fr);
47365
+ }
47366
+
47367
+ :where(.theme-scope)
47368
+ [data-block="testimonials"][data-block-look="testimonials-evergreen-lead"]
47369
+ .rb-testimonials-fe-col {
47370
+ grid-template-columns: repeat(2, minmax(0, 1fr));
47371
+ }
47372
+ }
47373
+
47374
+ /* Room and response: a tall lead voice with one soft brand response and one
47375
+ * neutral response in the existing stacked support column. */
47376
+ :where(.theme-scope)
47377
+ [data-block="testimonials"][data-block-look="testimonials-room-and-response"]
47378
+ .rb-testimonials-fe-card--feature {
47379
+ min-height: 27rem;
47380
+ }
47381
+
47382
+ :where(.theme-scope)
47383
+ [data-block="testimonials"][data-block-look="testimonials-room-and-response"]
47384
+ .rb-testimonials-fe-col
47385
+ .rb-testimonials-fe-card:first-child {
47386
+ border-color: transparent;
47387
+ background: rgb(var(--tb-primary-100));
47388
+ color: rgb(var(--tb-onPrimary100));
47389
+ --rb-surface-text-color: rgb(var(--tb-onPrimary100));
47390
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary100));
47391
+ --rb-surface-link-color: rgb(var(--tb-onPrimary100));
47392
+ --rb-surface-supporting-color: rgb(var(--tb-onPrimary100));
47393
+ }
47394
+
47395
+ :where(.theme-scope)
47396
+ [data-block="testimonials"][data-block-look="testimonials-room-and-response"]
47397
+ .rb-testimonials-fe-col
47398
+ .rb-testimonials-fe-card:first-child
47399
+ :is(.rb-testimonials-fe-quote p, .rb-testimonials-fe-name, .rb-testimonials-fe-context) {
47400
+ color: rgb(var(--tb-onPrimary100));
47401
+ }
47402
+
47403
+ /* Open floor: the section head becomes an editorial rail while proof occupies
47404
+ * a feature-over-supporting field. */
47405
+ @container rb-testimonials-fe (min-width: 1024px) {
47406
+ :where(.theme-scope)
47407
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47408
+ .rb-testimonials-fe {
47409
+ display: grid;
47410
+ grid-template-columns: minmax(15rem, 0.72fr) minmax(0, 1.6fr);
47411
+ align-items: start;
47412
+ gap: clamp(2rem, 5vw, 5rem);
47413
+ }
47414
+
47415
+ :where(.theme-scope)
47416
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47417
+ .rb-testimonials-fe-head {
47418
+ display: block;
47419
+ }
47420
+
47421
+ :where(.theme-scope)
47422
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47423
+ .rb-testimonials-fe-leadin {
47424
+ margin-top: 1.5rem;
47425
+ }
47426
+
47427
+ :where(.theme-scope)
47428
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47429
+ .rb-testimonials-fe-grid {
47430
+ grid-template-columns: minmax(0, 1fr);
47431
+ }
47432
+
47433
+ :where(.theme-scope)
47434
+ [data-block="testimonials"][data-block-look="testimonials-open-floor"]
47435
+ .rb-testimonials-fe-col {
47436
+ grid-template-columns: repeat(2, minmax(0, 1fr));
47437
+ }
45682
47438
  }`;
45683
47439
  //#endregion
45684
47440
  //#region ../theme-core/src/ThemeScopeCore.tsx
@@ -45843,6 +47599,103 @@ function ThemeScope({ theme, children, themeId = "theme-default", responsiveMode
45843
47599
  });
45844
47600
  }
45845
47601
  //#endregion
47602
+ //#region ../theme-core/src/fonts/types.ts
47603
+ /**
47604
+ * Shared types for custom site fonts
47605
+ *
47606
+ * Used by:
47607
+ * - packages/blocks: ThemeFontLoader
47608
+ * - apps/dashboard: Font settings
47609
+ * - apps/frontend: Font loading
47610
+ */
47611
+ /**
47612
+ * The Supabase storage bucket name for site fonts
47613
+ */
47614
+ const SITE_FONTS_BUCKET = "site-fonts";
47615
+ /**
47616
+ * Construct the storage base URL for site fonts
47617
+ *
47618
+ * @param supabaseUrl - The Supabase project URL (e.g., https://xxx.supabase.co)
47619
+ * @returns The full storage URL for the site-fonts bucket
47620
+ *
47621
+ * @example
47622
+ * ```ts
47623
+ * const storageUrl = getSiteFontsStorageUrl('https://xxx.supabase.co')
47624
+ * // Returns: 'https://xxx.supabase.co/storage/v1/object/public/site-fonts'
47625
+ * ```
47626
+ */
47627
+ function getSiteFontsStorageUrl(supabaseUrl) {
47628
+ return `${supabaseUrl}/storage/v1/object/public/${SITE_FONTS_BUCKET}`;
47629
+ }
47630
+ /**
47631
+ * Build a lightweight Google Fonts stylesheet URL for a family-name preview.
47632
+ * The text subset keeps catalog rows cheap while still rendering the name in
47633
+ * the typeface being chosen.
47634
+ */
47635
+ function buildFontPreviewUrl(family) {
47636
+ return `https://fonts.googleapis.com/css2?family=${encodeURIComponent(family).replace(/%20/gu, "+")}&display=swap&text=${encodeURIComponent(family)}`;
47637
+ }
47638
+ /**
47639
+ * Escape a string for use in CSS font-family declaration
47640
+ * Escapes quotes, backslashes, and newlines
47641
+ */
47642
+ function escapeCssFontFamily(name) {
47643
+ return name.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
47644
+ }
47645
+ /**
47646
+ * Encode storage path segments for use in URLs
47647
+ * Encodes each path segment individually to handle special characters
47648
+ */
47649
+ function encodeStoragePath(storagePath) {
47650
+ return storagePath.split("/").map((segment) => encodeURIComponent(segment)).join("/");
47651
+ }
47652
+ /**
47653
+ * Generate @font-face CSS for a single font file
47654
+ */
47655
+ function generateFontFaceForFile(familyName, file, storageBaseUrl) {
47656
+ return `@font-face {
47657
+ font-family: '${escapeCssFontFamily(familyName)}';
47658
+ src: url('${`${storageBaseUrl}/${encodeStoragePath(file.storagePath)}`}') format('woff2');
47659
+ font-weight: ${file.weight};
47660
+ font-style: ${file.style};
47661
+ font-display: swap;
47662
+ }`;
47663
+ }
47664
+ /**
47665
+ * Generate @font-face CSS for a variable font
47666
+ */
47667
+ function generateFontFaceForVariableFont(familyName, file, weightMin, weightMax, storageBaseUrl) {
47668
+ return `@font-face {
47669
+ font-family: '${escapeCssFontFamily(familyName)}';
47670
+ src: url('${`${storageBaseUrl}/${encodeStoragePath(file.storagePath)}`}') format('woff2');
47671
+ font-weight: ${weightMin} ${weightMax};
47672
+ font-style: ${file.style};
47673
+ font-display: swap;
47674
+ }`;
47675
+ }
47676
+ /**
47677
+ * Generate all @font-face rules for custom fonts
47678
+ *
47679
+ * @param fonts - Array of custom fonts
47680
+ * @param storageBaseUrl - Base URL for storage (e.g., https://xxx.supabase.co/storage/v1/object/public/site-fonts)
47681
+ * @returns CSS string with all @font-face rules
47682
+ */
47683
+ function generateFontFaceCss(fonts, storageBaseUrl) {
47684
+ const rules = [];
47685
+ const seenFamilies = /* @__PURE__ */ new Set();
47686
+ for (const font of fonts) {
47687
+ if (seenFamilies.has(font.familyName)) continue;
47688
+ seenFamilies.add(font.familyName);
47689
+ if (font.isVariable && font.variableWeightMin && font.variableWeightMax) {
47690
+ const normalFile = font.files.find((f) => f.style === "normal");
47691
+ const italicFile = font.files.find((f) => f.style === "italic");
47692
+ if (normalFile) rules.push(generateFontFaceForVariableFont(font.familyName, normalFile, font.variableWeightMin, font.variableWeightMax, storageBaseUrl));
47693
+ if (italicFile) rules.push(generateFontFaceForVariableFont(font.familyName, italicFile, font.variableWeightMin, font.variableWeightMax, storageBaseUrl));
47694
+ } else for (const file of font.files) rules.push(generateFontFaceForFile(font.familyName, file, storageBaseUrl));
47695
+ }
47696
+ return rules.join("\n\n");
47697
+ }
47698
+ //#endregion
45846
47699
  //#region ../theme-core/src/ResponsiveScope.tsx
45847
47700
  /**
45848
47701
  * Structural responsive root for SDK/runtime chrome that opts out of CMS theme
@@ -46462,7 +48315,7 @@ function normalizeLoaderParams(endpoint, params, context) {
46462
48315
  ensureSiteId(out, context);
46463
48316
  return out;
46464
48317
  }
46465
- if (endpoint === "listPublicEvents") {
48318
+ if (endpoint === "listPublicEvents" || endpoint === "listPublicRecurringSchedule") {
46466
48319
  ensureSiteId(out, context);
46467
48320
  return out;
46468
48321
  }
@@ -53960,7 +55813,7 @@ async function resolveVideoPosterReference(picked, context) {
53960
55813
  }
53961
55814
  //#endregion
53962
55815
  //#region ../media-storage-supabase/dist/index.mjs
53963
- function ok$1(value) {
55816
+ function ok(value) {
53964
55817
  return {
53965
55818
  ok: true,
53966
55819
  value
@@ -53981,7 +55834,7 @@ const unsafeAsBookingRequirementId = (id) => id;
53981
55834
  function fromArray(items) {
53982
55835
  const [first, ...rest] = items;
53983
55836
  if (first === void 0) return err("empty_array");
53984
- return ok$1([first, ...rest]);
55837
+ return ok([first, ...rest]);
53985
55838
  }
53986
55839
  /**
53987
55840
  * Narrow nullable values to the present value.
@@ -54088,8 +55941,48 @@ const ACCESS_POLICY_TAGS = [
54088
55941
  ];
54089
55942
  function asPositiveSeconds(value) {
54090
55943
  if (!Number.isSafeInteger(value) || value <= 0) return err("not-positive-seconds");
55944
+ return ok(value);
55945
+ }
55946
+ function ok$1(value) {
55947
+ return {
55948
+ ok: true,
55949
+ value
55950
+ };
55951
+ }
55952
+ function fail(error) {
55953
+ return {
55954
+ ok: false,
55955
+ error
55956
+ };
55957
+ }
55958
+ function normalizeStringInput(value) {
55959
+ if (typeof value !== "string") return fail({ tag: "MISSING" });
55960
+ const trimmed = value.trim();
55961
+ if (!trimmed) return fail({ tag: "EMPTY" });
55962
+ return ok$1(trimmed);
55963
+ }
55964
+ function validateRelativeStoragePath(value) {
55965
+ if (value.startsWith("sites/")) return fail({ tag: "SITE_SCOPED_PATH" });
55966
+ if (value.startsWith("/")) return fail({ tag: "LEADING_SLASH" });
55967
+ if (value.includes("//")) return fail({ tag: "DOUBLE_SLASH" });
55968
+ if (value.split("/").some((segment) => segment === "..")) return fail({ tag: "TRAVERSAL" });
54091
55969
  return ok$1(value);
54092
55970
  }
55971
+ function brandRelativeStoragePath(value) {
55972
+ return value;
55973
+ }
55974
+ function parseRelativeStoragePath(value) {
55975
+ const normalized = normalizeStringInput(value);
55976
+ if (!normalized.ok) return normalized;
55977
+ const validated = validateRelativeStoragePath(normalized.value);
55978
+ if (!validated.ok) return validated;
55979
+ return ok$1(brandRelativeStoragePath(validated.value));
55980
+ }
55981
+ function assertRelativeStoragePath(value) {
55982
+ const parsed = parseRelativeStoragePath(value);
55983
+ if (!parsed.ok) throw new Error(`Expected RelativeStoragePath, got ${parsed.error.tag}`);
55984
+ return parsed.value;
55985
+ }
54093
55986
  function isRecord$12(value) {
54094
55987
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
54095
55988
  }
@@ -54105,7 +55998,7 @@ function parseFileKindJson(value) {
54105
55998
  if (!family.ok || family.value !== "raster") return err("invalid-field");
54106
55999
  const format = parseOneOf(record.format, IMAGE_FILE_FORMATS);
54107
56000
  if (!format.ok) return format;
54108
- return ok$1({
56001
+ return ok({
54109
56002
  tag: "image",
54110
56003
  family: "raster",
54111
56004
  format: format.value
@@ -54114,7 +56007,7 @@ function parseFileKindJson(value) {
54114
56007
  case "video": {
54115
56008
  const format = parseOneOf(record.format, VIDEO_FILE_FORMATS);
54116
56009
  if (!format.ok) return format;
54117
- return ok$1({
56010
+ return ok({
54118
56011
  tag: "video",
54119
56012
  format: format.value
54120
56013
  });
@@ -54122,7 +56015,7 @@ function parseFileKindJson(value) {
54122
56015
  case "audio": {
54123
56016
  const format = parseOneOf(record.format, AUDIO_FILE_FORMATS);
54124
56017
  if (!format.ok) return format;
54125
- return ok$1({
56018
+ return ok({
54126
56019
  tag: "audio",
54127
56020
  format: format.value
54128
56021
  });
@@ -54130,7 +56023,7 @@ function parseFileKindJson(value) {
54130
56023
  case "document": {
54131
56024
  const format = parseOneOf(record.format, DOCUMENT_FILE_FORMATS);
54132
56025
  if (!format.ok) return format;
54133
- return ok$1({
56026
+ return ok({
54134
56027
  tag: "document",
54135
56028
  format: format.value
54136
56029
  });
@@ -54138,7 +56031,7 @@ function parseFileKindJson(value) {
54138
56031
  case "spreadsheet": {
54139
56032
  const format = parseOneOf(record.format, SPREADSHEET_FILE_FORMATS);
54140
56033
  if (!format.ok) return format;
54141
- return ok$1({
56034
+ return ok({
54142
56035
  tag: "spreadsheet",
54143
56036
  format: format.value
54144
56037
  });
@@ -54146,7 +56039,7 @@ function parseFileKindJson(value) {
54146
56039
  case "font": {
54147
56040
  const format = parseOneOf(record.format, FONT_FILE_FORMATS);
54148
56041
  if (!format.ok) return format;
54149
- return ok$1({
56042
+ return ok({
54150
56043
  tag: "font",
54151
56044
  format: format.value
54152
56045
  });
@@ -54154,7 +56047,7 @@ function parseFileKindJson(value) {
54154
56047
  case "archive": {
54155
56048
  const format = parseOneOf(record.format, ARCHIVE_FILE_FORMATS);
54156
56049
  if (!format.ok) return format;
54157
- return ok$1({
56050
+ return ok({
54158
56051
  tag: "archive",
54159
56052
  format: format.value
54160
56053
  });
@@ -54171,16 +56064,16 @@ function parseFileUseJson(value) {
54171
56064
  case "media-library": {
54172
56065
  const renderUse = parseOneOf(record.renderUse, RENDERABLE_FILE_KIND_TAGS);
54173
56066
  if (!renderUse.ok) return renderUse;
54174
- return ok$1({
56067
+ return ok({
54175
56068
  tag: "media-library",
54176
56069
  renderUse: renderUse.value
54177
56070
  });
54178
56071
  }
54179
- case "content-download": return ok$1({ tag: "content-download" });
56072
+ case "content-download": return ok({ tag: "content-download" });
54180
56073
  case "digital-product-file": {
54181
56074
  const fulfillmentVisibility = requireString(record.fulfillmentVisibility);
54182
56075
  if (!fulfillmentVisibility.ok || fulfillmentVisibility.value !== "entitled-customer") return err("invalid-field");
54183
- return ok$1({
56076
+ return ok({
54184
56077
  tag: "digital-product-file",
54185
56078
  fulfillmentVisibility: "entitled-customer"
54186
56079
  });
@@ -54188,7 +56081,7 @@ function parseFileUseJson(value) {
54188
56081
  case "workflow-input": {
54189
56082
  const workflowKind = parseOneOf(record.workflowKind, WORKFLOW_INPUT_KINDS);
54190
56083
  if (!workflowKind.ok) return workflowKind;
54191
- return ok$1({
56084
+ return ok({
54192
56085
  tag: "workflow-input",
54193
56086
  workflowKind: workflowKind.value
54194
56087
  });
@@ -54196,7 +56089,7 @@ function parseFileUseJson(value) {
54196
56089
  case "booking-evidence": {
54197
56090
  const requirementId = requireNonEmptyString(record.requirementId);
54198
56091
  if (!requirementId.ok) return requirementId;
54199
- return ok$1({
56092
+ return ok({
54200
56093
  tag: "booking-evidence",
54201
56094
  requirementId: unsafeAsBookingRequirementId(requirementId.value)
54202
56095
  });
@@ -54204,7 +56097,7 @@ function parseFileUseJson(value) {
54204
56097
  case "site-brand-asset": {
54205
56098
  const brandUse = parseOneOf(record.brandUse, SITE_BRAND_ASSET_USES);
54206
56099
  if (!brandUse.ok) return brandUse;
54207
- return ok$1({
56100
+ return ok({
54208
56101
  tag: "site-brand-asset",
54209
56102
  brandUse: brandUse.value
54210
56103
  });
@@ -54212,7 +56105,7 @@ function parseFileUseJson(value) {
54212
56105
  case "site-background-asset": {
54213
56106
  const backgroundUse = parseOneOf(record.backgroundUse, SITE_BACKGROUND_ASSET_USES);
54214
56107
  if (!backgroundUse.ok) return backgroundUse;
54215
- return ok$1({
56108
+ return ok({
54216
56109
  tag: "site-background-asset",
54217
56110
  backgroundUse: backgroundUse.value
54218
56111
  });
@@ -54220,7 +56113,7 @@ function parseFileUseJson(value) {
54220
56113
  case "site-font-file": {
54221
56114
  const fontId = requireNonEmptyString(record.fontId);
54222
56115
  if (!fontId.ok) return fontId;
54223
- return ok$1({
56116
+ return ok({
54224
56117
  tag: "site-font-file",
54225
56118
  fontId: unsafeAsSiteFontId(fontId.value)
54226
56119
  });
@@ -54228,7 +56121,7 @@ function parseFileUseJson(value) {
54228
56121
  case "temporary-ingestion": {
54229
56122
  const ingestionKind = parseOneOf(record.ingestionKind, TEMPORARY_INGESTION_KINDS);
54230
56123
  if (!ingestionKind.ok) return ingestionKind;
54231
- return ok$1({
56124
+ return ok({
54232
56125
  tag: "temporary-ingestion",
54233
56126
  ingestionKind: ingestionKind.value
54234
56127
  });
@@ -54241,7 +56134,7 @@ function parseFileUsesJson(value) {
54241
56134
  if (!parsed.ok) return parsed;
54242
56135
  const nonEmpty = fromArray(parsed.value);
54243
56136
  if (!nonEmpty.ok) return err("expected-non-empty-array");
54244
- return ok$1(nonEmpty.value);
56137
+ return ok(nonEmpty.value);
54245
56138
  }
54246
56139
  function parseAccessPolicyJson(value) {
54247
56140
  const recordResult = requireRecord(value);
@@ -54250,11 +56143,11 @@ function parseAccessPolicyJson(value) {
54250
56143
  const tag = parseTag(record.tag, ACCESS_POLICY_TAGS);
54251
56144
  if (!tag.ok) return tag;
54252
56145
  switch (tag.value) {
54253
- case "public-read": return ok$1({ tag: "public-read" });
56146
+ case "public-read": return ok({ tag: "public-read" });
54254
56147
  case "site-editor-read": {
54255
56148
  const siteId = requireNonEmptyString(record.siteId);
54256
56149
  if (!siteId.ok) return siteId;
54257
- return ok$1({
56150
+ return ok({
54258
56151
  tag: "site-editor-read",
54259
56152
  siteId: unsafeAsSiteId(siteId.value)
54260
56153
  });
@@ -54262,7 +56155,7 @@ function parseAccessPolicyJson(value) {
54262
56155
  case "signed-public-render": {
54263
56156
  const expiresInSeconds = parsePositiveSeconds$1(record.expiresInSeconds);
54264
56157
  if (!expiresInSeconds.ok) return expiresInSeconds;
54265
- return ok$1({
56158
+ return ok({
54266
56159
  tag: "signed-public-render",
54267
56160
  expiresInSeconds: expiresInSeconds.value
54268
56161
  });
@@ -54272,7 +56165,7 @@ function parseAccessPolicyJson(value) {
54272
56165
  if (!scope.ok) return scope;
54273
56166
  const expiresInSeconds = parseOptionalPositiveSeconds(record.expiresInSeconds);
54274
56167
  if (!expiresInSeconds.ok) return expiresInSeconds;
54275
- return ok$1({
56168
+ return ok({
54276
56169
  tag: "entitled-customer-read",
54277
56170
  scope: scope.value,
54278
56171
  ...expiresInSeconds.value !== void 0 ? { expiresInSeconds: expiresInSeconds.value } : {}
@@ -54283,13 +56176,13 @@ function parseAccessPolicyJson(value) {
54283
56176
  if (!sessionId.ok) return sessionId;
54284
56177
  const expiresInSeconds = parseOptionalPositiveSeconds(record.expiresInSeconds);
54285
56178
  if (!expiresInSeconds.ok) return expiresInSeconds;
54286
- return ok$1({
56179
+ return ok({
54287
56180
  tag: "booking-session-read",
54288
56181
  sessionId: unsafeAsBookingSessionId(sessionId.value),
54289
56182
  ...expiresInSeconds.value !== void 0 ? { expiresInSeconds: expiresInSeconds.value } : {}
54290
56183
  });
54291
56184
  }
54292
- case "management-api-read": return ok$1({ tag: "management-api-read" });
56185
+ case "management-api-read": return ok({ tag: "management-api-read" });
54293
56186
  }
54294
56187
  }
54295
56188
  function parseEntitledCustomerAccessScopeJson(value) {
@@ -54299,11 +56192,11 @@ function parseEntitledCustomerAccessScopeJson(value) {
54299
56192
  const tag = parseTag(record.tag, ["any-entitled-customer", "specific-entitlement"]);
54300
56193
  if (!tag.ok) return tag;
54301
56194
  switch (tag.value) {
54302
- case "any-entitled-customer": return ok$1({ tag: "any-entitled-customer" });
56195
+ case "any-entitled-customer": return ok({ tag: "any-entitled-customer" });
54303
56196
  case "specific-entitlement": {
54304
56197
  const entitlementId = requireNonEmptyString(record.entitlementId);
54305
56198
  if (!entitlementId.ok) return entitlementId;
54306
- return ok$1({
56199
+ return ok({
54307
56200
  tag: "specific-entitlement",
54308
56201
  entitlementId: unsafeAsEntitlementId(entitlementId.value)
54309
56202
  });
@@ -54312,18 +56205,18 @@ function parseEntitledCustomerAccessScopeJson(value) {
54312
56205
  }
54313
56206
  function requireRecord(value) {
54314
56207
  if (!isRecord$12(value)) return err("expected-object");
54315
- return ok$1(value);
56208
+ return ok(value);
54316
56209
  }
54317
56210
  function requireString(value) {
54318
56211
  if (typeof value !== "string") return err("invalid-string");
54319
- return ok$1(value);
56212
+ return ok(value);
54320
56213
  }
54321
56214
  function requireNonEmptyString(value) {
54322
56215
  const string = requireString(value);
54323
56216
  if (!string.ok) return string;
54324
56217
  const trimmed = string.value.trim();
54325
56218
  if (!trimmed || trimmed !== string.value) return err("invalid-string");
54326
- return ok$1(string.value);
56219
+ return ok(string.value);
54327
56220
  }
54328
56221
  function parseOneOf(value, allowed) {
54329
56222
  return parseStringIn(value, allowed, "invalid-field");
@@ -54335,16 +56228,16 @@ function parseStringIn(value, allowed, outOfSetError) {
54335
56228
  const string = requireString(value);
54336
56229
  if (!string.ok) return string;
54337
56230
  if (!isOneOf(string.value, allowed)) return err(outOfSetError);
54338
- return ok$1(string.value);
56231
+ return ok(string.value);
54339
56232
  }
54340
56233
  function parsePositiveSeconds$1(value) {
54341
56234
  if (typeof value !== "number") return err("invalid-number");
54342
56235
  const parsed = asPositiveSeconds(value);
54343
56236
  if (!parsed.ok) return err("invalid-positive-seconds");
54344
- return ok$1(parsed.value);
56237
+ return ok(parsed.value);
54345
56238
  }
54346
56239
  function parseOptionalPositiveSeconds(value) {
54347
- if (value === void 0 || value === null) return ok$1(void 0);
56240
+ if (value === void 0 || value === null) return ok(void 0);
54348
56241
  return parsePositiveSeconds$1(value);
54349
56242
  }
54350
56243
  function traverse(items, parse) {
@@ -54354,7 +56247,7 @@ function traverse(items, parse) {
54354
56247
  if (!parsed.ok) return parsed;
54355
56248
  values.push(parsed.value);
54356
56249
  }
54357
- return ok$1(values);
56250
+ return ok(values);
54358
56251
  }
54359
56252
  function isOneOf(value, allowed) {
54360
56253
  return allowed.includes(value);
@@ -54387,46 +56280,6 @@ var MediaStorageError = class extends Error {
54387
56280
  this.cause = options.cause;
54388
56281
  }
54389
56282
  };
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
56283
  const pad = (value) => value.toString().padStart(2, "0");
54431
56284
  const extractExtension = (filename) => {
54432
56285
  if (!hasText(filename)) return "";
@@ -56694,7 +58547,8 @@ function buildInsertBlockHistoryCommand({ block, index, draftContent, publishedC
56694
58547
  draftContent: toEditorBlockValues(baseline),
56695
58548
  publishedContent: toEditorBlockValues(nextPublishedContent),
56696
58549
  bindings: toEditorBlockValues(block.bindings ?? null),
56697
- purpose
58550
+ purpose,
58551
+ optimisticHash: block.optimisticHash ?? null
56698
58552
  }, {
56699
58553
  id: blockId,
56700
58554
  version: 0,
@@ -56705,7 +58559,8 @@ function buildInsertBlockHistoryCommand({ block, index, draftContent, publishedC
56705
58559
  kind: block.kind,
56706
58560
  purpose,
56707
58561
  orderIndex: index,
56708
- publishedContent: toEditorBlockValues(nextPublishedContent)
58562
+ publishedContent: toEditorBlockValues(nextPublishedContent),
58563
+ optimisticHash: block.optimisticHash ?? null
56709
58564
  }
56710
58565
  }, index);
56711
58566
  }
@@ -56715,6 +58570,8 @@ function blockEditorOwnerKey(owner) {
56715
58570
  switch (owner.kind) {
56716
58571
  case "page": return `page:${owner.pageId}`;
56717
58572
  case "entry-slot": return `entry-slot:${owner.type}:${owner.entryId}:${owner.slotKey}`;
58573
+ case "surface-slot": return `surface-slot:${owner.pageSurfaceId}:${owner.slotKey}`;
58574
+ default: return assertNever$5(owner);
56718
58575
  }
56719
58576
  }
56720
58577
  async function createEditableBlockForOwner(apiClient, siteId, owner, input) {
@@ -56736,6 +58593,16 @@ async function createEditableBlockForOwner(apiClient, siteId, owner, input) {
56736
58593
  position: input.position,
56737
58594
  purpose: input.purpose
56738
58595
  });
58596
+ case "surface-slot": return createPageSurfaceSlotBlock(apiClient, {
58597
+ siteId,
58598
+ pageSurfaceId: owner.pageSurfaceId,
58599
+ slotKey: owner.slotKey,
58600
+ kind: input.kind,
58601
+ position: input.position,
58602
+ purpose: input.purpose,
58603
+ expectedCompositionHash: owner.compositionHash
58604
+ });
58605
+ default: return assertNever$5(owner);
56739
58606
  }
56740
58607
  }
56741
58608
  async function reorderEditableBlocksForOwner(apiClient, siteId, owner, blockIds) {
@@ -56752,6 +58619,14 @@ async function reorderEditableBlocksForOwner(apiClient, siteId, owner, blockIds)
56752
58619
  slotKey: owner.slotKey,
56753
58620
  blockIds
56754
58621
  });
58622
+ case "surface-slot": return reorderPageSurfaceSlotBlocks(apiClient, {
58623
+ siteId,
58624
+ pageSurfaceId: owner.pageSurfaceId,
58625
+ slotKey: owner.slotKey,
58626
+ blockIds,
58627
+ expectedCompositionHash: owner.compositionHash
58628
+ });
58629
+ default: return assertNever$5(owner);
56755
58630
  }
56756
58631
  }
56757
58632
  async function deleteEditableBlockForOwner(apiClient, siteId, owner, blockId) {
@@ -56768,11 +58643,23 @@ async function deleteEditableBlockForOwner(apiClient, siteId, owner, blockId) {
56768
58643
  slotKey: owner.slotKey,
56769
58644
  blockId
56770
58645
  });
58646
+ case "surface-slot": return deletePageSurfaceSlotBlock(apiClient, {
58647
+ siteId,
58648
+ pageSurfaceId: owner.pageSurfaceId,
58649
+ slotKey: owner.slotKey,
58650
+ blockId,
58651
+ expectedCompositionHash: owner.compositionHash
58652
+ });
58653
+ default: return assertNever$5(owner);
56771
58654
  }
56772
58655
  }
58656
+ function surfaceCompositionHashFromResponse(response) {
58657
+ if (typeof response === "object" && response !== null && "compositionHash" in response && typeof response.compositionHash === "string") return response.compositionHash;
58658
+ return null;
58659
+ }
56773
58660
  //#endregion
56774
58661
  //#region ../editor-blocks/src/block-editor/hooks/useBlockCreation.ts
56775
- function useBlockCreation({ allowCreation, apiClient, siteId, owner, blockList, setBlockList, onBlocksChange, triggerFocus, uiStore }) {
58662
+ function useBlockCreation({ allowCreation, apiClient, siteId, owner, blockList, setBlockList, onBlocksChange, triggerFocus, uiStore, onStructuralRevisionChange }) {
56776
58663
  const [pickerOpen, setPickerOpen] = useState(false);
56777
58664
  const [insertPosition, setInsertPosition] = useState(null);
56778
58665
  const [creatingBlockName, setCreatingBlockName] = useState(null);
@@ -56800,11 +58687,14 @@ function useBlockCreation({ allowCreation, apiClient, siteId, owner, blockList,
56800
58687
  setCreatingBlockName(descriptor.name);
56801
58688
  setErrorMessage(null);
56802
58689
  try {
56803
- const newBlock = (await createEditableBlockForOwner(apiClient, siteId, owner, {
58690
+ const response = await createEditableBlockForOwner(apiClient, siteId, owner, {
56804
58691
  kind: descriptor.name,
56805
58692
  position: insertPosition,
56806
58693
  purpose: "content"
56807
- })).block;
58694
+ });
58695
+ const nextCompositionHash = surfaceCompositionHashFromResponse(response);
58696
+ if (nextCompositionHash) onStructuralRevisionChange?.(nextCompositionHash);
58697
+ const newBlock = response.block;
56808
58698
  const updated = [...blockList];
56809
58699
  updated.splice(insertPosition, 0, {
56810
58700
  ...newBlock,
@@ -56850,6 +58740,7 @@ function useBlockCreation({ allowCreation, apiClient, siteId, owner, blockList,
56850
58740
  creatingBlockName,
56851
58741
  insertPosition,
56852
58742
  onBlocksChange,
58743
+ onStructuralRevisionChange,
56853
58744
  owner,
56854
58745
  setBlockList,
56855
58746
  siteId,
@@ -56865,7 +58756,7 @@ function getDuplicateDraftContent(block) {
56865
58756
  if (!source || typeof source !== "object" || Array.isArray(source)) return null;
56866
58757
  return JSON.parse(JSON.stringify(source));
56867
58758
  }
56868
- function useBlockDuplication({ allowCreation, apiClient, siteId, owner, blockList, setBlockList, onBlocksChange, triggerFocus, setErrorMessage, uiStore }) {
58759
+ function useBlockDuplication({ allowCreation, apiClient, siteId, owner, blockList, setBlockList, onBlocksChange, triggerFocus, setErrorMessage, uiStore, onStructuralRevisionChange }) {
56869
58760
  const [duplicatingBlockId, setDuplicatingBlockId] = useState(null);
56870
58761
  return {
56871
58762
  duplicatingBlockId,
@@ -56881,18 +58772,27 @@ function useBlockDuplication({ allowCreation, apiClient, siteId, owner, blockLis
56881
58772
  setDuplicatingBlockId(blockId);
56882
58773
  setErrorMessage(null);
56883
58774
  let createdBlockId = null;
58775
+ let ownerAfterCreate = owner;
56884
58776
  try {
56885
- const createdBlock = (await createEditableBlockForOwner(apiClient, siteId, owner, {
58777
+ const response = await createEditableBlockForOwner(apiClient, siteId, owner, {
56886
58778
  kind: sourceBlock.kind,
56887
58779
  position: insertIndex,
56888
58780
  purpose,
56889
58781
  duplicatedFromBlockId: blockId
56890
- })).block;
58782
+ });
58783
+ const createdCompositionHash = surfaceCompositionHashFromResponse(response);
58784
+ ownerAfterCreate = owner.kind === "surface-slot" && createdCompositionHash ? {
58785
+ ...owner,
58786
+ compositionHash: createdCompositionHash
58787
+ } : owner;
58788
+ if (createdCompositionHash) onStructuralRevisionChange?.(createdCompositionHash);
58789
+ const createdBlock = response.block;
56891
58790
  if (!createdBlock.id) throw new Error("Duplicate block did not return a block id");
56892
58791
  createdBlockId = createdBlock.id;
56893
58792
  if (draftContent) await mutateBlockContent(apiClient, {
56894
58793
  siteId,
56895
58794
  blockId: createdBlock.id,
58795
+ optimisticHash: createdBlock.optimisticHash ?? null,
56896
58796
  data: draftContent
56897
58797
  });
56898
58798
  const insertedBlock = {
@@ -56924,7 +58824,8 @@ function useBlockDuplication({ allowCreation, apiClient, siteId, owner, blockLis
56924
58824
  }
56925
58825
  } catch (error) {
56926
58826
  if (createdBlockId) try {
56927
- await deleteEditableBlockForOwner(apiClient, siteId, owner, createdBlockId);
58827
+ const nextCompositionHash = surfaceCompositionHashFromResponse(await deleteEditableBlockForOwner(apiClient, siteId, ownerAfterCreate, createdBlockId));
58828
+ if (nextCompositionHash) onStructuralRevisionChange?.(nextCompositionHash);
56928
58829
  } catch {}
56929
58830
  const message = error instanceof Error ? error.message : "Failed to duplicate block";
56930
58831
  console.error("[useBlockDuplication] duplicate failed:", message, error);
@@ -56938,6 +58839,7 @@ function useBlockDuplication({ allowCreation, apiClient, siteId, owner, blockLis
56938
58839
  blockList,
56939
58840
  duplicatingBlockId,
56940
58841
  onBlocksChange,
58842
+ onStructuralRevisionChange,
56941
58843
  owner,
56942
58844
  setBlockList,
56943
58845
  setErrorMessage,
@@ -56956,7 +58858,7 @@ function blockIdsEqual(left, right) {
56956
58858
  if (left.length !== right.length) return false;
56957
58859
  return left.every((blockId, index) => blockId === right[index]);
56958
58860
  }
56959
- function useBlockReorder({ allowReordering, apiClient, siteId, owner, blockList, setBlockList, onBlocksChange, setErrorMessage, uiStore }) {
58861
+ function useBlockReorder({ allowReordering, apiClient, siteId, owner, blockList, setBlockList, onBlocksChange, setErrorMessage, uiStore, onStructuralRevisionChange }) {
56960
58862
  const [reorderId, setReorderId] = useState(null);
56961
58863
  const applyReorder = useCallback(async (updated, original) => {
56962
58864
  if (!allowReordering) return;
@@ -56964,7 +58866,8 @@ function useBlockReorder({ allowReordering, apiClient, siteId, owner, blockList,
56964
58866
  const nextBlockIds = getBlockIds(updated);
56965
58867
  uiStore?.getState().history.applyCommand?.({ ...createEditorReorderBlocksCommand(nextBlockIds.map((blockId) => unsafeAsEditorBlockId(blockId))) });
56966
58868
  try {
56967
- await reorderEditableBlocksForOwner(apiClient, siteId, owner, nextBlockIds);
58869
+ const nextCompositionHash = surfaceCompositionHashFromResponse(await reorderEditableBlocksForOwner(apiClient, siteId, owner, nextBlockIds));
58870
+ if (nextCompositionHash) onStructuralRevisionChange?.(nextCompositionHash);
56968
58871
  onBlocksChange?.(updated);
56969
58872
  } catch (error) {
56970
58873
  const message = error instanceof Error ? error.message : "Failed to reorder blocks";
@@ -56981,6 +58884,7 @@ function useBlockReorder({ allowReordering, apiClient, siteId, owner, blockList,
56981
58884
  allowReordering,
56982
58885
  apiClient,
56983
58886
  onBlocksChange,
58887
+ onStructuralRevisionChange,
56984
58888
  owner,
56985
58889
  setBlockList,
56986
58890
  siteId,
@@ -57106,21 +59010,32 @@ function stripTopLevelRoutingUi(field) {
57106
59010
  //#region ../editor-blocks/src/block-editor/preparedManifest.ts
57107
59011
  const showRawStyleFields = { kind: "show-raw-style-fields" };
57108
59012
  const hideThemeV2RawStyleFields = { kind: "hide-theme-v2-raw-style-fields" };
59013
+ const EDITOR_OWNED_FEATURE_CARD_FIELD_IDS = /* @__PURE__ */ new Set(["_generatedIconSizePx"]);
59014
+ function hideEditorOwnedFields(manifest, blockKind) {
59015
+ if (blockKind !== "block.feature-cards") return manifest;
59016
+ return {
59017
+ ...manifest,
59018
+ fields: manifest.fields?.map((field) => EDITOR_OWNED_FEATURE_CARD_FIELD_IDS.has(field.id) ? {
59019
+ ...field,
59020
+ ui: {
59021
+ ...field.ui ?? {},
59022
+ hidden: true
59023
+ }
59024
+ } : field),
59025
+ promotedFields: manifest.promotedFields?.filter((fieldPath) => !EDITOR_OWNED_FEATURE_CARD_FIELD_IDS.has(fieldPath))
59026
+ };
59027
+ }
57109
59028
  function prepareBlockEditorManifest(input) {
57110
59029
  const mergedManifest = mergeManifestWithSdkOptions(input.manifest, input.blockKind, input.blockFieldOptions, input.blockFieldExtensions);
57111
59030
  const validationManifest = augmentManifestWithStyleGroups(mergedManifest, input.styleGroups, input.blockKind);
57112
59031
  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
59032
  return {
57118
59033
  validationManifest,
57119
- renderManifest: {
59034
+ renderManifest: hideEditorOwnedFields(input.visibilityPolicy.kind === "hide-theme-v2-raw-style-fields" ? {
57120
59035
  ...renderManifestBase,
57121
59036
  fields: renderManifestBase.fields ? hideThemeV2NormalEditorRawStyleFieldsInRenderFields(renderManifestBase.fields) : renderManifestBase.fields,
57122
59037
  promotedFields: filterThemeV2NormalEditorRawPromotedFields(renderManifestBase.promotedFields, input.allowedPromotedFieldPaths)
57123
- }
59038
+ } : validationManifest, input.blockKind)
57124
59039
  };
57125
59040
  }
57126
59041
  //#endregion
@@ -57567,7 +59482,7 @@ function formatGeneratedAt(value) {
57567
59482
  const date = new Date(value);
57568
59483
  return Number.isNaN(date.valueOf()) ? "Previously generated" : new Intl.DateTimeFormat(void 0, { dateStyle: "medium" }).format(date);
57569
59484
  }
57570
- function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary, styleGuideEditHref, onGenerate, onApply }) {
59485
+ function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary, styleGuideEditHref, generatedIconSizePx, onGeneratedIconSizeChange, hasStaleGeneratedIcons = false, onGenerate, onApply }) {
57571
59486
  const [state, dispatch] = useReducer(reducer, { kind: "idle" });
57572
59487
  const [styleNote, setStyleNote] = useState("");
57573
59488
  const [view, setView] = useState("create");
@@ -57635,6 +59550,15 @@ function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary,
57635
59550
  setView("create");
57636
59551
  }
57637
59552
  }
59553
+ function commitGeneratedIconSize(input) {
59554
+ if (generatedIconSizePx === void 0 || !onGeneratedIconSizeChange) return;
59555
+ const parsed = parseFeatureCardGeneratedIconSizePx(input.valueAsNumber);
59556
+ if (parsed.ok) {
59557
+ onGeneratedIconSizeChange(parsed.value);
59558
+ return;
59559
+ }
59560
+ input.value = String(generatedIconSizePx);
59561
+ }
57638
59562
  async function apply(preview) {
57639
59563
  if (!onApply) return;
57640
59564
  dispatch({
@@ -57666,7 +59590,7 @@ function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary,
57666
59590
  children: /* @__PURE__ */ jsxs(DialogContent, {
57667
59591
  className: "sm:max-w-2xl",
57668
59592
  children: [
57669
- /* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Choose icon set" }), /* @__PURE__ */ jsx(DialogDescription, { children: activePreview ? activePreview.styleGuideSummary : `${cards.length} cards` })] }),
59593
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Manage icons" }), /* @__PURE__ */ jsx(DialogDescription, { children: activePreview ? activePreview.styleGuideSummary : `${cards.length} cards` })] }),
57670
59594
  /* @__PURE__ */ jsxs("div", {
57671
59595
  className: "space-y-4",
57672
59596
  children: [
@@ -57693,6 +59617,51 @@ function GeneratedIconSetDialog({ open, onOpenChange, cards, styleGuideSummary,
57693
59617
  }), "Previously generated"]
57694
59618
  })]
57695
59619
  }),
59620
+ generatedIconSizePx !== void 0 && onGeneratedIconSizeChange ? /* @__PURE__ */ jsx(FieldFrame, {
59621
+ label: "Generated icon size",
59622
+ description: "Choose how large generated artwork appears. It will shrink to fit narrow cards.",
59623
+ children: ({ id, descriptionId }) => /* @__PURE__ */ jsxs("div", {
59624
+ className: "flex items-center gap-4",
59625
+ children: [/* @__PURE__ */ jsx(Slider, {
59626
+ value: [generatedIconSizePx],
59627
+ min: FEATURE_CARD_GENERATED_ICON_SIZE_PX.min,
59628
+ max: FEATURE_CARD_GENERATED_ICON_SIZE_PX.max,
59629
+ step: FEATURE_CARD_GENERATED_ICON_SIZE_PX.step,
59630
+ "aria-label": "Generated icon size in pixels",
59631
+ "aria-describedby": descriptionId || void 0,
59632
+ className: "flex-1",
59633
+ onValueChange: ([value]) => {
59634
+ if (value !== void 0) onGeneratedIconSizeChange(value);
59635
+ }
59636
+ }), /* @__PURE__ */ jsxs("div", {
59637
+ className: "flex w-24 shrink-0 items-center gap-1",
59638
+ children: [/* @__PURE__ */ jsx(Input, {
59639
+ id,
59640
+ type: "number",
59641
+ defaultValue: generatedIconSizePx,
59642
+ min: FEATURE_CARD_GENERATED_ICON_SIZE_PX.min,
59643
+ max: FEATURE_CARD_GENERATED_ICON_SIZE_PX.max,
59644
+ step: FEATURE_CARD_GENERATED_ICON_SIZE_PX.step,
59645
+ "aria-label": "Generated icon size in pixels",
59646
+ "aria-describedby": descriptionId || void 0,
59647
+ className: "h-8 px-2 text-right tabular-nums",
59648
+ onBlur: (event) => commitGeneratedIconSize(event.currentTarget),
59649
+ onKeyDown: (event) => {
59650
+ if (event.key !== "Enter") return;
59651
+ event.preventDefault();
59652
+ commitGeneratedIconSize(event.currentTarget);
59653
+ }
59654
+ }, generatedIconSizePx), /* @__PURE__ */ jsx("span", {
59655
+ className: "text-sm text-muted-foreground",
59656
+ children: "px"
59657
+ })]
59658
+ })]
59659
+ })
59660
+ }) : null,
59661
+ hasStaleGeneratedIcons ? /* @__PURE__ */ jsx(Callout, {
59662
+ tone: "warning",
59663
+ children: /* @__PURE__ */ jsx(CalloutDescription, { children: "Generated icons are out of date with the current icon style." })
59664
+ }) : null,
57696
59665
  state.kind === "failed" || state.kind === "apply_failed" ? /* @__PURE__ */ jsx("p", {
57697
59666
  role: "alert",
57698
59667
  className: "text-sm text-destructive",
@@ -58003,6 +59972,7 @@ function FeatureCardIconsPanel({ block, uiStore, currentStyleGuideVersionId, ico
58003
59972
  const dialogCards = useMemo(() => getFeatureCardIconDialogCards(content), [content]);
58004
59973
  const styleSummary = useMemo(() => getFeatureCardGeneratedIconStyleSummary(content, currentStyleGuideVersionId), [content, currentStyleGuideVersionId]);
58005
59974
  const hasStaleGeneratedIcons = styleSummary.kind === "available" && styleSummary.staleCount > 0;
59975
+ const generatedIconSizePx = resolveFeatureCardGeneratedIconSizePx(content?._generatedIconSizePx);
58006
59976
  async function applyGeneratedIconSetPreview(preview) {
58007
59977
  if (!blockId) return {
58008
59978
  kind: "failed",
@@ -58021,61 +59991,31 @@ function FeatureCardIconsPanel({ block, uiStore, currentStyleGuideVersionId, ico
58021
59991
  return { kind: "applied" };
58022
59992
  }
58023
59993
  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",
59994
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("section", {
58026
59995
  "aria-label": "Icons",
58027
59996
  "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]
59997
+ children: /* @__PURE__ */ jsxs(Button, {
59998
+ type: "button",
59999
+ variant: "outline",
60000
+ size: "sm",
60001
+ disabled: status.totalCards === 0,
60002
+ onClick: () => setGenerateDialogOpen(true),
60003
+ children: [/* @__PURE__ */ jsx(ImagePlus, {
60004
+ className: "mr-2 h-4 w-4",
60005
+ "aria-hidden": "true"
60006
+ }), "Manage icons"]
60007
+ })
58073
60008
  }), /* @__PURE__ */ jsx(GeneratedIconSetDialog, {
58074
60009
  open: generateDialogOpen,
58075
60010
  onOpenChange: setGenerateDialogOpen,
58076
60011
  cards: dialogCards,
58077
60012
  styleGuideSummary: iconStyleGuideSummary,
58078
60013
  styleGuideEditHref: iconStyleGuideEditHref,
60014
+ generatedIconSizePx,
60015
+ onGeneratedIconSizeChange: (value) => {
60016
+ uiStore.getState().drafts.setAtPath(blockId, "_generatedIconSizePx", value);
60017
+ },
60018
+ hasStaleGeneratedIcons,
58079
60019
  onGenerate: onGenerateIconSet,
58080
60020
  onApply: applyGeneratedIconSetPreview
58081
60021
  })] });
@@ -58413,6 +60353,7 @@ function BlockCardHeader({ block, manifest, isFirst, isLast, isMoving, onMove, o
58413
60353
  const featureCardIconDialogCards = supportsIconActions ? getFeatureCardIconDialogCards(featureCardIconContent) : [];
58414
60354
  const featureCardIconStyleSummary = supportsIconActions ? getFeatureCardGeneratedIconStyleSummary(featureCardIconContent, currentStyleGuideVersionId) : { kind: "unavailable" };
58415
60355
  const hasStaleGeneratedIcons = featureCardIconStyleSummary.kind === "available" && featureCardIconStyleSummary.staleCount > 0;
60356
+ const featureCardGeneratedIconSizePx = resolveFeatureCardGeneratedIconSizePx(featureCardIconContent?._generatedIconSizePx);
58416
60357
  async function applyGeneratedIconSetPreview(preview) {
58417
60358
  if (!blockId) return {
58418
60359
  kind: "failed",
@@ -58619,6 +60560,11 @@ function BlockCardHeader({ block, manifest, isFirst, isLast, isMoving, onMove, o
58619
60560
  cards: featureCardIconDialogCards,
58620
60561
  styleGuideSummary: iconStyleGuideSummary,
58621
60562
  styleGuideEditHref: iconStyleGuideEditHref,
60563
+ generatedIconSizePx: featureCardGeneratedIconSizePx,
60564
+ onGeneratedIconSizeChange: (value) => {
60565
+ if (blockId) uiStore.getState().drafts.setAtPath(blockId, "_generatedIconSizePx", value);
60566
+ },
60567
+ hasStaleGeneratedIcons,
58622
60568
  onGenerate: onGenerateIconSet,
58623
60569
  onApply: applyGeneratedIconSetPreview
58624
60570
  }) : null
@@ -58636,7 +60582,7 @@ function menuActionIcon(action) {
58636
60582
  function menuActionLabel(action) {
58637
60583
  switch (action.kind) {
58638
60584
  case "customize": return "Customize";
58639
- case "generated-icon-set": return action.stale ? "Regenerate icon set" : "Generate icon set";
60585
+ case "generated-icon-set": return "Manage icons";
58640
60586
  case "duplicate": return "Duplicate";
58641
60587
  case "delete": return "Delete";
58642
60588
  default: return assertNever$5(action);
@@ -58741,6 +60687,7 @@ const SortableBlockItem = memo(function SortableBlockItem({ siteId, block, onMov
58741
60687
  })
58742
60688
  });
58743
60689
  return /* @__PURE__ */ jsx("div", {
60690
+ "data-block-editor-client-ready": mounted ? "true" : "false",
58744
60691
  ref: (node) => {
58745
60692
  sortable.setNodeRef(node);
58746
60693
  if (node) blockRef.current = node;
@@ -58808,7 +60755,7 @@ function getGeneratedIconSetErrorMessage(error) {
58808
60755
  const message = getApiRequestErrorMessage(error);
58809
60756
  return message === "Internal server error" || /^Request to .+ failed with status \d+$/u.test(message) ? GENERATED_ICON_SET_FRIENDLY_ERROR : message;
58810
60757
  }
58811
- const BlockEditor = forwardRef(function BlockEditor({ siteId, dashboardBaseUrl, owner, blocks, recoveryConflictBlockIds = [], recoveryConflictReviewRequestId = null, apiClient, uiStore, enableReordering = true, enableCreation = true, enableDeletion = true, onBlockSave, onBlocksChange, theme, widgetOverrides, headerLeftSlot, hideThemeV2RawStyleFields = false, pageDesignEditorModel = null, enabledContentTypes = [], sdkConfig = null, customBlocks = [], allowedBlockKinds = null, emptyUnavailableMessage = "No blocks available for this page.", initialCollapsed = true, reorderControlMode = DEFAULT_REORDER_CONTROL_MODE, actionPresentation = DEFAULT_BLOCK_ACTION_PRESENTATION }, ref) {
60758
+ const BlockEditor = forwardRef(function BlockEditor({ siteId, dashboardBaseUrl, owner, blocks, recoveryConflictBlockIds = [], recoveryConflictReviewRequestId = null, apiClient, uiStore, enableReordering = true, enableCreation = true, enableDeletion = true, onBlockSave, onBlocksChange, onStructuralRevisionChange, theme, widgetOverrides, headerLeftSlot, hideThemeV2RawStyleFields = false, pageDesignEditorModel = null, enabledContentTypes = [], sdkConfig = null, customBlocks = [], allowedBlockKinds = null, emptyUnavailableMessage = "No blocks available for this page.", initialCollapsed = true, reorderControlMode = DEFAULT_REORDER_CONTROL_MODE, actionPresentation = DEFAULT_BLOCK_ACTION_PRESENTATION }, ref) {
58812
60759
  const [blockList, setBlockList] = useState(() => normalizeBlockListInitial(blocks));
58813
60760
  const [errorMessage, setErrorMessage] = useState(null);
58814
60761
  const [highlightedBlockId, setHighlightedBlockId] = useState(null);
@@ -58833,8 +60780,21 @@ const BlockEditor = forwardRef(function BlockEditor({ siteId, dashboardBaseUrl,
58833
60780
  const conflictedBlockIdSet = useMemo(() => new Set(recoveryConflictBlockIds), [recoveryConflictBlockIds]);
58834
60781
  const blockIds = useMemo(() => blockList.map((block) => block.id).filter((blockId) => typeof blockId === "string"), [blockList]);
58835
60782
  const pageDesignBlockById = useMemo(() => new Map((pageDesignEditorModel?.blocks ?? []).map((block) => [String(block.blockId), block])), [pageDesignEditorModel]);
60783
+ const ownerKey = useMemo(() => blockEditorOwnerKey(owner), [owner]);
60784
+ const [surfaceCompositionHash, setSurfaceCompositionHash] = useState(owner.kind === "surface-slot" ? owner.compositionHash : null);
60785
+ const updateStructuralRevision = useCallback((revision) => {
60786
+ setSurfaceCompositionHash(revision);
60787
+ onStructuralRevisionChange?.(revision);
60788
+ }, [onStructuralRevisionChange]);
60789
+ useEffect(() => {
60790
+ setSurfaceCompositionHash(owner.kind === "surface-slot" ? owner.compositionHash : null);
60791
+ }, [ownerKey, owner.kind === "surface-slot" ? owner.compositionHash : null]);
60792
+ const mutationOwner = useMemo(() => owner.kind === "surface-slot" ? {
60793
+ ...owner,
60794
+ compositionHash: surfaceCompositionHash ?? owner.compositionHash
60795
+ } : owner, [owner, surfaceCompositionHash]);
58836
60796
  const { isCollapsed, setCollapsed } = useBlockExpandState({
58837
- pageId: useMemo(() => blockEditorOwnerKey(owner), [owner]),
60797
+ pageId: ownerKey,
58838
60798
  blockIds,
58839
60799
  initialCollapsed
58840
60800
  });
@@ -59065,41 +61025,45 @@ const BlockEditor = forwardRef(function BlockEditor({ siteId, dashboardBaseUrl,
59065
61025
  allowCreation: canCreateBlocks,
59066
61026
  apiClient,
59067
61027
  siteId,
59068
- owner,
61028
+ owner: mutationOwner,
59069
61029
  blockList,
59070
61030
  setBlockList,
59071
61031
  onBlocksChange,
59072
61032
  triggerFocus,
59073
- uiStore
61033
+ uiStore,
61034
+ onStructuralRevisionChange: updateStructuralRevision
59074
61035
  });
59075
61036
  const { reorderId, handleMove, onDragEnd } = useBlockReorder({
59076
61037
  allowReordering,
59077
61038
  apiClient,
59078
61039
  siteId,
59079
- owner,
61040
+ owner: mutationOwner,
59080
61041
  blockList,
59081
61042
  setBlockList,
59082
61043
  onBlocksChange,
59083
61044
  setErrorMessage,
59084
- uiStore
61045
+ uiStore,
61046
+ onStructuralRevisionChange: updateStructuralRevision
59085
61047
  });
59086
61048
  const { duplicatingBlockId, duplicateBlock } = useBlockDuplication({
59087
61049
  allowCreation: canCreateBlocks,
59088
61050
  apiClient,
59089
61051
  siteId,
59090
- owner,
61052
+ owner: mutationOwner,
59091
61053
  blockList,
59092
61054
  setBlockList,
59093
61055
  onBlocksChange,
59094
61056
  triggerFocus,
59095
61057
  setErrorMessage,
59096
- uiStore
61058
+ uiStore,
61059
+ onStructuralRevisionChange: updateStructuralRevision
59097
61060
  });
59098
61061
  const handleDelete = useCallback(async (blockId) => {
59099
61062
  try {
59100
61063
  setErrorMessage(null);
59101
61064
  if (!blockList.find((block) => block.id === blockId)) return;
59102
- await deleteEditableBlockForOwner(apiClient, siteId, owner, blockId);
61065
+ const nextCompositionHash = surfaceCompositionHashFromResponse(await deleteEditableBlockForOwner(apiClient, siteId, mutationOwner, blockId));
61066
+ if (nextCompositionHash) updateStructuralRevision(nextCompositionHash);
59103
61067
  const updatedList = blockList.filter((b) => b.id !== blockId);
59104
61068
  setBlockList(updatedList);
59105
61069
  if (uiStore) uiStore.getState().history.applyCommand?.({ ...createEditorRemoveBlockCommand(unsafeAsEditorBlockId(blockId)) });
@@ -59111,11 +61075,12 @@ const BlockEditor = forwardRef(function BlockEditor({ siteId, dashboardBaseUrl,
59111
61075
  }, [
59112
61076
  apiClient,
59113
61077
  siteId,
59114
- owner,
61078
+ mutationOwner,
59115
61079
  blockList,
59116
61080
  setBlockList,
59117
61081
  onBlocksChange,
59118
- uiStore
61082
+ uiStore,
61083
+ updateStructuralRevision
59119
61084
  ]);
59120
61085
  useEffect(() => {
59121
61086
  return () => {
@@ -62511,20 +64476,7 @@ const BACKGROUND_MODES = [
62511
64476
  "image"
62512
64477
  ];
62513
64478
  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
64479
  const BACKGROUND_RICH_SECTION_SURFACES = ["hero-image"];
62525
- function isBackgroundCustomizableBlockKind(blockKind) {
62526
- return BACKGROUND_CUSTOMIZABLE_BLOCK_KINDS.includes(blockKind);
62527
- }
62528
64480
  const backgroundColorTokenNames = backgroundAppearanceColorTokenNames;
62529
64481
  const backgroundColorTokenNameSet = new Set(backgroundColorTokenNames);
62530
64482
  const backgroundColorTokens = toBackgroundColorTokens(backgroundColorTokenNames);
@@ -62620,7 +64572,7 @@ function defaultBackgroundOverrideForMode(mode, capability) {
62620
64572
  }
62621
64573
  }
62622
64574
  function resolveBackgroundCapability(input) {
62623
- if (!isBackgroundCustomizableBlockKind(input.block.blockKind)) return backgroundCapabilityFromModes([{ kind: "default" }]);
64575
+ if (input.block.backgroundSupport.kind === "unsupported") return backgroundCapabilityFromModes([{ kind: "default" }]);
62624
64576
  const richModesSupported = blockSupportsRichBackgroundModes(input.block);
62625
64577
  const selectableColorTokens = input.palette ? dedupeBackgroundColorTokensByPalette(backgroundColorTokens, input.palette) : backgroundColorTokens;
62626
64578
  const recommendedColorTokens = selectableColorTokens.filter((token) => recommendedBackgroundColorTokens.includes(token));
@@ -62984,13 +64936,8 @@ function overrideValueAllowed(override, capability) {
62984
64936
  }
62985
64937
  }
62986
64938
  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;
64939
+ if (block.backgroundSupport.kind === "unsupported" || block.backgroundSupport.richBackgrounds === "unsupported") return false;
64940
+ return valueInList(effectiveLook(block)?.design.sectionSurface ?? null, BACKGROUND_RICH_SECTION_SURFACES);
62994
64941
  }
62995
64942
  function effectiveLook(block) {
62996
64943
  const effectiveLookId = block.look.effectiveValue;
@@ -63646,7 +65593,7 @@ function applyPreviewCustomizeActionToLoadedState(state, action) {
63646
65593
  effectiveValue: action.appearancePresetId
63647
65594
  } : {
63648
65595
  kind: "auto",
63649
- effectiveValue: block.availableLooks[0]?.id ?? null
65596
+ effectiveValue: block.autoLookId
63650
65597
  }
63651
65598
  };
63652
65599
  })
@@ -63683,11 +65630,15 @@ function optimisticLayoutLookState(block, layoutVariantKey) {
63683
65630
  case "layout-unavailable": return {
63684
65631
  layout: block.layout,
63685
65632
  availableLooks: block.availableLooks,
65633
+ autoLookId: block.autoLookId,
65634
+ lookAvailability: block.lookAvailability,
63686
65635
  look: block.look
63687
65636
  };
63688
65637
  case "layout-supported": return {
63689
65638
  layout: plan.layout,
63690
65639
  availableLooks: plan.availableLooks,
65640
+ autoLookId: plan.autoLookId,
65641
+ lookAvailability: plan.lookAvailability,
63691
65642
  look: plan.look
63692
65643
  };
63693
65644
  default: return assertNever$6(plan, "Unhandled layout/Look compatibility plan");
@@ -63965,7 +65916,8 @@ function localRuntimeDraftForBlock(input) {
63965
65916
  kind: block.blockKind,
63966
65917
  purpose: null,
63967
65918
  orderIndex: null,
63968
- publishedContent: null
65919
+ publishedContent: null,
65920
+ optimisticHash: null
63969
65921
  }
63970
65922
  };
63971
65923
  }
@@ -64020,8 +65972,8 @@ function PreviewPageDesignEditorStateProvider({ apiClient, siteId, pageId, enabl
64020
65972
  if (!cancelled) setWorkflowState(previewCustomizeLoadSucceeded(nextState));
64021
65973
  }).catch((error) => {
64022
65974
  if (cancelled) return;
64023
- if (!(error instanceof ApiRequestError)) console.error("[preview-page-design-editor-state] Unexpected load failure", error);
64024
- setWorkflowState(failedPreviewCustomizeWorkflowState(error instanceof ApiRequestError ? error.message : PAGE_DESIGN_EDITOR_STATE_FETCH_ERROR_MESSAGE));
65975
+ reportPreviewDesignError("Failed to load page design editor state", error);
65976
+ setWorkflowState(failedPreviewCustomizeWorkflowState(PREVIEW_DESIGN_LOAD_ERROR_MESSAGE));
64025
65977
  });
64026
65978
  return () => {
64027
65979
  cancelled = true;
@@ -64308,20 +66260,23 @@ function actionWithCurrentBaseContentId(action, editorModel) {
64308
66260
  }
64309
66261
  }
64310
66262
  function classifyApplyActionError(error) {
64311
- const message = error instanceof Error ? error.message : "Failed to save design change.";
64312
66263
  if (error instanceof ApiRequestError) {
64313
66264
  if (error.status === 409) return {
64314
66265
  kind: "stale",
64315
66266
  message: PREVIEW_CUSTOMIZE_STALE_MESSAGE
64316
66267
  };
64317
- if (error.status === 400 || error.status === 422) return {
64318
- kind: "invalid",
64319
- message
64320
- };
66268
+ if (error.status === 400 || error.status === 422) {
66269
+ reportPreviewDesignError("Failed to apply page design change", error);
66270
+ return {
66271
+ kind: "invalid",
66272
+ message: PREVIEW_DESIGN_SAVE_ERROR_MESSAGE
66273
+ };
66274
+ }
64321
66275
  }
66276
+ reportPreviewDesignError("Failed to apply page design change", error);
64322
66277
  return {
64323
66278
  kind: "failed",
64324
- message
66279
+ message: PREVIEW_DESIGN_SAVE_ERROR_MESSAGE
64325
66280
  };
64326
66281
  }
64327
66282
  function usePreviewPageDesignEditorState() {
@@ -64458,7 +66413,8 @@ function PreviewEntryControllerProvider({ children, siteId, pageId, routeId: pro
64458
66413
  content: b.content ?? null,
64459
66414
  draftContent: b.draftContent ?? null,
64460
66415
  publishedContent: b.publishedContent ?? null,
64461
- bindings: b.bindings ?? null
66416
+ bindings: b.bindings ?? null,
66417
+ optimisticHash: b.optimisticHash ?? null
64462
66418
  }));
64463
66419
  }, [initialBlocks]);
64464
66420
  const entityId = pageId || entryData?.id || "";
@@ -64466,20 +66422,30 @@ function PreviewEntryControllerProvider({ children, siteId, pageId, routeId: pro
64466
66422
  const entityLabel = entryData ? "Entry" : "Page";
64467
66423
  const routeId = providedRouteId ?? void 0;
64468
66424
  const initialContent = entryData ? draftContent ?? entryData.content ?? {} : null;
64469
- return /* @__PURE__ */ jsx(EntryControllerProvider, {
66425
+ const common = {
64470
66426
  apiClient,
64471
- kind: entryData ? "content" : "page",
64472
66427
  type: entityType || "page",
64473
66428
  siteId,
64474
- entryId: entityId,
66429
+ owner: {
66430
+ kind: "contentEntry",
66431
+ contentEntryId: entityId
66432
+ },
64475
66433
  routeId,
64476
66434
  schema,
64477
66435
  entityLabel,
64478
66436
  initialEntry,
66437
+ initialBlocks: normalizedInitialBlocks,
66438
+ historyShortcutsEnabled: isEditingMode
66439
+ };
66440
+ return entryData ? /* @__PURE__ */ jsx(EntryControllerProvider, {
66441
+ ...common,
66442
+ kind: "content",
64479
66443
  initialContent,
66444
+ children
66445
+ }) : /* @__PURE__ */ jsx(EntryControllerProvider, {
66446
+ ...common,
66447
+ kind: "page",
64480
66448
  initialStatus,
64481
- initialBlocks: normalizedInitialBlocks,
64482
- historyShortcutsEnabled: isEditingMode,
64483
66449
  children
64484
66450
  });
64485
66451
  }
@@ -65474,6 +67440,74 @@ function PreviewChromeFloatingControl({ anchorSelector, anchorTargetSelector, pl
65474
67440
  children
65475
67441
  }), layer.portalTarget)] });
65476
67442
  }
67443
+ function PreviewChromeFloatingBar({ anchorSelector, gapPx = 8, children }) {
67444
+ const layer = usePreviewChromeLayerOptional();
67445
+ const probeRef = useRef(null);
67446
+ const [position, setPosition] = useState(null);
67447
+ const [themeCustomProperties, setThemeCustomProperties] = useState({});
67448
+ useEffect(() => {
67449
+ if (!layer?.portalTarget) return;
67450
+ const portalTarget = layer.portalTarget;
67451
+ let resizeObserver = null;
67452
+ let observedAnchor = null;
67453
+ const update = () => {
67454
+ const anchor = probeRef.current?.closest(anchorSelector);
67455
+ if (anchor !== observedAnchor) {
67456
+ resizeObserver?.disconnect();
67457
+ observedAnchor = anchor;
67458
+ if (anchor && typeof ResizeObserver !== "undefined") {
67459
+ resizeObserver = new ResizeObserver(update);
67460
+ resizeObserver.observe(anchor);
67461
+ }
67462
+ }
67463
+ if (!anchor) {
67464
+ setPosition(null);
67465
+ return;
67466
+ }
67467
+ const anchorRect = anchor.getBoundingClientRect();
67468
+ const layerRect = portalTarget.getBoundingClientRect();
67469
+ const placement = anchorRect.top >= 56 ? "above" : "below";
67470
+ setThemeCustomProperties(readThemeCustomProperties(anchor));
67471
+ setPosition({
67472
+ left: anchorRect.left - layerRect.left,
67473
+ top: placement === "above" ? anchorRect.top - layerRect.top - gapPx : anchorRect.bottom - layerRect.top + gapPx,
67474
+ width: anchorRect.width,
67475
+ placement
67476
+ });
67477
+ };
67478
+ update();
67479
+ const unsubscribe = layer.subscribeLayout(update);
67480
+ return () => {
67481
+ resizeObserver?.disconnect();
67482
+ unsubscribe();
67483
+ };
67484
+ }, [
67485
+ anchorSelector,
67486
+ gapPx,
67487
+ layer
67488
+ ]);
67489
+ if (!layer?.portalTarget) return /* @__PURE__ */ jsx("div", {
67490
+ className: "absolute inset-x-0 bottom-full z-20 mb-2",
67491
+ children
67492
+ });
67493
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
67494
+ ref: probeRef,
67495
+ "aria-hidden": "true",
67496
+ style: { display: "contents" }
67497
+ }), position ? createPortal(/* @__PURE__ */ jsx("div", {
67498
+ "data-preview-chrome-floating-bar": "",
67499
+ "data-placement": position.placement,
67500
+ className: "pointer-events-auto absolute z-[80]",
67501
+ style: {
67502
+ ...themeCustomProperties,
67503
+ left: position.left,
67504
+ top: position.top,
67505
+ width: position.width,
67506
+ transform: position.placement === "above" ? "translateY(-100%)" : void 0
67507
+ },
67508
+ children
67509
+ }), layer.portalTarget) : null] });
67510
+ }
65477
67511
  function readThemeCustomProperties(element) {
65478
67512
  if (typeof window === "undefined") return {};
65479
67513
  const computedStyle = window.getComputedStyle(element);
@@ -65892,6 +67926,7 @@ function CustomizeBackgroundControlRows({ modeLabel, valueLabel, valueAriaLabel,
65892
67926
  //#region ../preview-next/src/client/preview/SiteChromeCustomizeButton.tsx
65893
67927
  function SiteChromeCustomizeButton({ surface, containerClassName = "pointer-events-auto absolute right-2 top-2 z-50 opacity-0 transition group-focus-within/site-chrome:opacity-100 group-hover/site-chrome:opacity-100" }) {
65894
67928
  const customize = useSiteChromeCustomizeOptional();
67929
+ const editorUiStore = useOptionalEditorUiStoreInstance();
65895
67930
  const popover = useCustomizePopoverController();
65896
67931
  const [backgroundChooserOpen, setBackgroundChooserOpen] = useState(false);
65897
67932
  const popoverSide = useSiteChromeCustomizePopoverSide({
@@ -66043,13 +68078,18 @@ function SiteChromeCustomizeButton({ surface, containerClassName = "pointer-even
66043
68078
  onClick: (event) => {
66044
68079
  event.preventDefault();
66045
68080
  event.stopPropagation();
66046
- requestPreviewSidebarOpen({
68081
+ if (surfaceState.surface === "footer") {
68082
+ const editorUi = editorUiStore?.getState();
68083
+ editorUi?.inspectFooter();
68084
+ editorUi?.setPreviewSidebarTab("editor");
68085
+ editorUi?.setDrawerOpen(true);
68086
+ } else requestPreviewSidebarOpen({
66047
68087
  tab: "editor",
66048
- designRow: surfaceState.surface === "header" ? "header-style" : "footer"
68088
+ designRow: "header-style"
66049
68089
  });
66050
68090
  popover.close();
66051
68091
  },
66052
- children: "More options"
68092
+ children: surfaceState.surface === "footer" ? "Edit footer" : "More options"
66053
68093
  })
66054
68094
  }),
66055
68095
  surfaceState.diagnostics.length > 0 ? /* @__PURE__ */ jsx("ul", {
@@ -66215,7 +68255,7 @@ function renderEditableSurface(children, surface, options) {
66215
68255
  if (isValidElement(child) && child.type !== Fragment && (isHostElement(child) || options.preserveSingleComponentRoot || isEditableSurfaceForwardingElement(child))) return cloneElement(child, {
66216
68256
  className: joinClassNames(child.props.className, "group/site-chrome relative"),
66217
68257
  "data-preview-site-chrome-surface": surface,
66218
- children: /* @__PURE__ */ jsxs(Fragment$1, { children: [child.props.children, /* @__PURE__ */ jsx(SiteChromeCustomizeButton, { surface })] })
68258
+ children: /* @__PURE__ */ jsxs(Fragment$1, { children: [surface === "footer" ? /* @__PURE__ */ jsx(FooterModuleInspectionSurface, { children: child.props.children }) : child.props.children, /* @__PURE__ */ jsx(SiteChromeCustomizeButton, { surface })] })
66219
68259
  });
66220
68260
  if (surface === "header") return /* @__PURE__ */ jsxs("div", {
66221
68261
  className: "group/site-chrome",
@@ -66229,7 +68269,66 @@ function renderEditableSurface(children, surface, options) {
66229
68269
  return /* @__PURE__ */ jsxs("div", {
66230
68270
  className: "group/site-chrome relative",
66231
68271
  "data-preview-site-chrome-surface": surface,
66232
- children: [children, /* @__PURE__ */ jsx(SiteChromeCustomizeButton, { surface })]
68272
+ children: [/* @__PURE__ */ jsx(FooterModuleInspectionSurface, { children }), /* @__PURE__ */ jsx(SiteChromeCustomizeButton, { surface })]
68273
+ });
68274
+ }
68275
+ function FooterModuleInspectionSurface({ children }) {
68276
+ const uiStore = useOptionalEditorUiStoreInstance();
68277
+ const rootRef = useRef(null);
68278
+ const [active, setActive] = useState(null);
68279
+ const [position, setPosition] = useState(null);
68280
+ useEffect(() => {
68281
+ const root = rootRef.current;
68282
+ if (!root) return;
68283
+ const modules = root.querySelectorAll("[data-preview-footer-module-id]");
68284
+ for (const module of modules) {
68285
+ module.tabIndex = 0;
68286
+ const label = module.dataset.previewFooterModuleId?.replace(/-/gu, " ") ?? "footer section";
68287
+ module.setAttribute("aria-label", `Edit ${label}`);
68288
+ }
68289
+ }, [children]);
68290
+ const activateElement = (element) => {
68291
+ if (!element) return;
68292
+ const parsed = parseFooterModuleId(element.dataset.previewFooterModuleId);
68293
+ if (!parsed.ok) return;
68294
+ const label = element.dataset.previewFooterModuleId?.replace(/-/gu, " ") ?? "footer section";
68295
+ const rect = element.getBoundingClientRect();
68296
+ setActive({
68297
+ moduleId: parsed.value,
68298
+ label
68299
+ });
68300
+ setPosition({
68301
+ top: Math.max(8, rect.top + 8),
68302
+ left: Math.max(8, rect.right - 64)
68303
+ });
68304
+ };
68305
+ const inspect = (moduleId) => {
68306
+ uiStore?.getState().inspectFooterModule(moduleId);
68307
+ uiStore?.getState().setPreviewSidebarTab("editor");
68308
+ uiStore?.getState().setDrawerOpen(true);
68309
+ };
68310
+ return /* @__PURE__ */ jsxs("div", {
68311
+ ref: rootRef,
68312
+ style: { display: "contents" },
68313
+ onMouseOver: (event) => activateElement(event.target.closest("[data-preview-footer-module-id]")),
68314
+ onFocusCapture: (event) => activateElement(event.target.closest("[data-preview-footer-module-id]")),
68315
+ onKeyDown: (event) => {
68316
+ if (event.key !== "Enter" && event.key !== " ") return;
68317
+ const element = event.target.closest("[data-preview-footer-module-id]");
68318
+ if (!element) return;
68319
+ const parsed = parseFooterModuleId(element.dataset.previewFooterModuleId);
68320
+ if (!parsed.ok) return;
68321
+ event.preventDefault();
68322
+ inspect(parsed.value);
68323
+ },
68324
+ children: [children, active && position && uiStore ? /* @__PURE__ */ jsx("button", {
68325
+ type: "button",
68326
+ className: "pointer-events-auto fixed z-[75] rounded-full border bg-background px-3 py-1.5 text-xs font-medium text-foreground shadow-md",
68327
+ style: position,
68328
+ "aria-label": `Edit ${active.label}`,
68329
+ onClick: () => inspect(active.moduleId),
68330
+ children: "Edit"
68331
+ }) : null]
66233
68332
  });
66234
68333
  }
66235
68334
  function isHostElement(child) {
@@ -66470,17 +68569,17 @@ function LinkedEntryEditEventBridge() {
66470
68569
  //#region ../preview-next/src/client/preview/PreviewShellLayout.tsx
66471
68570
  const previewContainerResponsiveEnabled = process.env.NEXT_PUBLIC_ENABLE_PREVIEW_CONTAINER_RESPONSIVE !== "false";
66472
68571
  const PreviewEditorSidebar = React.lazy(async () => {
66473
- return { default: (await import("./PreviewEditorSidebar-CBMhU9p_.mjs")).PreviewEditorSidebar };
68572
+ return { default: (await import("./PreviewEditorSidebar-BBT-kZAM.mjs")).PreviewEditorSidebar };
66474
68573
  });
66475
68574
  const PreviewEditorUI = React.lazy(async () => {
66476
- return { default: (await import("./PreviewEditorUI-C5KEw4M8.mjs")).PreviewEditorUI };
68575
+ return { default: (await import("./PreviewEditorUI-D69xNKT2.mjs")).PreviewEditorUI };
66477
68576
  });
66478
68577
  const previewPaneContainmentStyle = {
66479
68578
  contain: "layout paint",
66480
68579
  isolation: "isolate",
66481
68580
  transform: "translateZ(0)"
66482
68581
  };
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" } }) {
68582
+ 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" }, onFooterSaved }) {
66484
68583
  const layout = useOptionalPreviewLayout();
66485
68584
  const headerNode = layout?.headerNode ?? null;
66486
68585
  const bannerNode = layout?.bannerNode ?? null;
@@ -66671,13 +68770,8 @@ function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseU
66671
68770
  themeSelectionUpdatedAt,
66672
68771
  themeSelectionButtonPersonalityId,
66673
68772
  runtimePaletteState,
66674
- themeSelectionPaletteVariantId,
66675
- themeSelectionPaletteOverrides,
66676
68773
  themeSelectionHeaderLayoutId,
66677
68774
  themeSelectionHeaderStyleId,
66678
- themeSelectionTypographyPresetId,
66679
- themeSelectionTypographyBodyFontOverride,
66680
- themeSelectionTypographyHeadingFontOverride,
66681
68775
  themeSelectionHeaderLookId,
66682
68776
  themeSelectionFooterLookId,
66683
68777
  themeSelectionHeaderContext,
@@ -66690,6 +68784,7 @@ function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseU
66690
68784
  setPreviewSidebarTab(tab);
66691
68785
  setPreviewSidebarActiveTab(tab);
66692
68786
  },
68787
+ onFooterSaved,
66693
68788
  onClose: () => setDrawerOpen(false),
66694
68789
  entrySubrouteContext: entrySubrouteContext ?? null,
66695
68790
  assistantPanel,
@@ -66731,13 +68826,8 @@ function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseU
66731
68826
  selectionUpdatedAt: themeSelectionUpdatedAt,
66732
68827
  buttonPersonalityId: themeSelectionButtonPersonalityId,
66733
68828
  runtimePaletteState,
66734
- paletteVariantId: themeSelectionPaletteVariantId,
66735
- paletteOverrides: themeSelectionPaletteOverrides,
66736
68829
  headerLayoutId: themeSelectionHeaderLayoutId,
66737
68830
  headerStyleId: themeSelectionHeaderStyleId,
66738
- typographyPresetId: themeSelectionTypographyPresetId,
66739
- typographyBodyFontOverride: themeSelectionTypographyBodyFontOverride,
66740
- typographyHeadingFontOverride: themeSelectionTypographyHeadingFontOverride,
66741
68831
  headerLookId: themeSelectionHeaderLookId,
66742
68832
  footerLookId: themeSelectionFooterLookId
66743
68833
  },
@@ -66773,14 +68863,14 @@ function PreviewShellLayout({ children, theme, surfaceId, siteId, dashboardBaseU
66773
68863
  }
66774
68864
  //#endregion
66775
68865
  //#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 }) {
68866
+ 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, onFooterSaved }) {
66777
68867
  const apiClient = useMemo(() => createBearerAPIClient(previewToken, apiBaseUrl), [previewToken, apiBaseUrl]);
66778
68868
  const resolvedDesignEditorEligibility = designEditorEligibility ?? defaultDesignEditorEligibility({
66779
68869
  pageId,
66780
68870
  entryData
66781
68871
  });
66782
68872
  const designEditorEnabled = isPreviewRuntimeSessionEditable(previewSession) && resolvedDesignEditorEligibility.kind === "managed-page" && Boolean(pageId);
66783
- const siteStyleAccess = resolveSiteStyleAccess(previewSession);
68873
+ const siteStyleAccess = hideSiteStyleConfigurator ? { kind: "hidden" } : resolveSiteStyleAccess(previewSession);
66784
68874
  return /* @__PURE__ */ jsx(BlockApiProvider, {
66785
68875
  config: blockApiConfig,
66786
68876
  children: /* @__PURE__ */ jsx(PreviewQueryProvider, { children: /* @__PURE__ */ jsx(PreviewAuthInit, {
@@ -66832,13 +68922,8 @@ function PreviewShell({ children, apiBaseUrl, blockApiConfig, siteId, siteSlug,
66832
68922
  themeSelectionUpdatedAt,
66833
68923
  themeSelectionButtonPersonalityId,
66834
68924
  runtimePaletteState,
66835
- themeSelectionPaletteVariantId,
66836
- themeSelectionPaletteOverrides,
66837
68925
  themeSelectionHeaderLayoutId,
66838
68926
  themeSelectionHeaderStyleId,
66839
- themeSelectionTypographyPresetId,
66840
- themeSelectionTypographyBodyFontOverride,
66841
- themeSelectionTypographyHeadingFontOverride,
66842
68927
  themeSelectionHeaderLookId,
66843
68928
  themeSelectionFooterLookId,
66844
68929
  themeSelectionHeaderContext,
@@ -66853,6 +68938,7 @@ function PreviewShell({ children, apiBaseUrl, blockApiConfig, siteId, siteSlug,
66853
68938
  bookingOfferingPresets,
66854
68939
  themeRuntime,
66855
68940
  siteStyleAccess,
68941
+ onFooterSaved,
66856
68942
  children
66857
68943
  })]
66858
68944
  })
@@ -67027,11 +69113,12 @@ function cloneRecord(value) {
67027
69113
  }
67028
69114
  //#endregion
67029
69115
  //#region ../preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.ts
67030
- function runtimeContentDecorationProjectionFromEditorModel(editorModel, surfaceResolutionContext, designRules) {
69116
+ function runtimeContentDecorationProjectionFromEditorModel(editorModel, surfaceResolutionContext, designRules, componentRules) {
67031
69117
  const compiled = compileEditorModelRuntime({
67032
69118
  editorModel,
67033
69119
  surfaceResolutionContext,
67034
- designRules
69120
+ designRules,
69121
+ componentRules
67035
69122
  });
67036
69123
  return {
67037
69124
  kind: "runtime-content-decoration",
@@ -67365,6 +69452,12 @@ function normalizeTextChildren(input) {
67365
69452
  if (Array.isArray(input)) return input.map((item) => normalizeTextChildren(item)).join("");
67366
69453
  return "";
67367
69454
  }
69455
+ function renderPreviewRichTextToolbarHost(toolbar) {
69456
+ return /* @__PURE__ */ jsx(PreviewChromeFloatingBar, {
69457
+ anchorSelector: "[data-rb-preview-richtext-editor]",
69458
+ children: toolbar
69459
+ });
69460
+ }
67368
69461
  const RichTextWithEditor = ({ value, path, linkedEntryField, ...rest }) => {
67369
69462
  const { isEditingMode } = useEditor();
67370
69463
  if (isEditingMode && (path || linkedEntryField)) return /* @__PURE__ */ jsx(PreviewRichTextEditor, {
@@ -67373,6 +69466,7 @@ const RichTextWithEditor = ({ value, path, linkedEntryField, ...rest }) => {
67373
69466
  linkedEntryField,
67374
69467
  onLinkedEntryFieldFocus: dispatchLinkedEntryFieldFocusEvent,
67375
69468
  onBlockFieldFocus: dispatchBlockFieldFocusEventFromPath,
69469
+ renderToolbarHost: renderPreviewRichTextToolbarHost,
67376
69470
  doc: value
67377
69471
  });
67378
69472
  return /* @__PURE__ */ jsx(RichText, {
@@ -67495,7 +69589,7 @@ function cyclePageDesignBlockLayout(block, direction) {
67495
69589
  };
67496
69590
  }
67497
69591
  function cyclePageDesignBlockLook(block, direction) {
67498
- if (block.availableLooks.length <= 1) return null;
69592
+ if (block.lookAvailability.kind !== "available" || block.availableLooks.length <= 1) return null;
67499
69593
  const values = [null, ...block.availableLooks.map((look) => look.id)];
67500
69594
  const currentIndex = cycleChoiceIndex(block.look, values, direction);
67501
69595
  if (currentIndex === -1) return null;
@@ -67616,7 +69710,7 @@ function BlockToolbar({ blockId, blockKind, content, bookingOfferingPresets, the
67616
69710
  return pageDesignState.editorModel.blocks.find((block) => block.blockId === blockId) ?? null;
67617
69711
  }, [blockId, pageDesignState]);
67618
69712
  const hasLayoutControls = Boolean(designBlock?.layout && designBlock.availableLayouts.length > 1);
67619
- const hasLookControls = Boolean(designBlock && designBlock.availableLooks.length > 0);
69713
+ const hasLookControls = Boolean(designBlock?.lookAvailability.kind === "available");
67620
69714
  const facetControls = useMemo(() => previewCustomizeFacetControlsFor(blockKind, customizeContent, designBlock), [
67621
69715
  blockKind,
67622
69716
  customizeContent,
@@ -67937,7 +70031,7 @@ function renderBlockCustomizeBuiltinRow(row, context) {
67937
70031
  }
67938
70032
  }
67939
70033
  function canCycleLookForRow(block) {
67940
- return block.availableLooks.length > 1;
70034
+ return block.lookAvailability.kind === "available" && block.availableLooks.length > 1;
67941
70035
  }
67942
70036
  function BackgroundChooser({ capability, current, imagePoolStatus, onChoose }) {
67943
70037
  const mediaEditorContext = useMediaEditorOptional();
@@ -68552,14 +70646,15 @@ function formatBlockKindLabel(blockKind) {
68552
70646
  //#region ../preview-next/src/client/blocks/pageDesignRuntimePreview.ts
68553
70647
  function pageDesignRuntimeProjectionFromSource(source) {
68554
70648
  if (source.kind === "preserve-server-runtime") return null;
68555
- return runtimeContentDecorationProjectionFromEditorModel(source.editorModel, source.surfaceResolutionContext, source.designRules);
70649
+ return runtimeContentDecorationProjectionFromEditorModel(source.editorModel, source.surfaceResolutionContext, source.designRules, source.componentRules);
68556
70650
  }
68557
70651
  function resolveRuntimePreviewSource(input) {
68558
70652
  if (input.pageDesignState.kind === "loaded" && input.surfaceResolutionContext) return {
68559
70653
  kind: "apply-editor-model",
68560
70654
  editorModel: input.pageDesignState.editorModel,
68561
70655
  surfaceResolutionContext: input.surfaceResolutionContext,
68562
- designRules: input.designRules
70656
+ designRules: input.designRules,
70657
+ componentRules: input.componentRules
68563
70658
  };
68564
70659
  return { kind: "preserve-server-runtime" };
68565
70660
  }
@@ -68617,7 +70712,8 @@ function EditablePageRenderer(props) {
68617
70712
  const runtimePreviewSource = useMemo(() => resolveRuntimePreviewSource({
68618
70713
  pageDesignState,
68619
70714
  surfaceResolutionContext,
68620
- designRules: designRuntimeRulesForTheme(pageRendererProps.theme)
70715
+ designRules: designRuntimeRulesForTheme(pageRendererProps.theme),
70716
+ componentRules: componentRuntimeRulesForTheme(pageRendererProps.theme)
68621
70717
  }), [
68622
70718
  pageDesignState,
68623
70719
  pageRendererProps.theme,
@@ -68919,6 +71015,10 @@ async function callDirectLoaderApiEndpoint(dashboardApiClient, endpoint, params)
68919
71015
  endpoint,
68920
71016
  params
68921
71017
  }));
71018
+ case "listPublicRecurringSchedule": return projectRecurringSchedule(unwrapResponse(await dashboardApiClient({
71019
+ endpoint: "listPublicEvents",
71020
+ params
71021
+ })));
68922
71022
  }
68923
71023
  }
68924
71024
  function isBatchableEndpoint(endpoint) {
@@ -69187,6 +71287,10 @@ function SdkPreviewModeRuntime(props) {
69187
71287
  mediaAssets: content.mediaAssets
69188
71288
  };
69189
71289
  return /* @__PURE__ */ jsx(PreviewShell, {
71290
+ runtimePaletteState: {
71291
+ kind: "invalid",
71292
+ reason: "missing-active-palette-reference"
71293
+ },
69190
71294
  apiBaseUrl,
69191
71295
  blockApiConfig: useMemo(() => ({
69192
71296
  baseUrl: apiBaseUrl,
@@ -69223,6 +71327,7 @@ function SdkPreviewModeRuntime(props) {
69223
71327
  supabaseUrl: content.supabaseUrl,
69224
71328
  themeRuntime,
69225
71329
  designEditorEligibility: { kind: "sdk-page" },
71330
+ hideSiteStyleConfigurator: true,
69226
71331
  children: /* @__PURE__ */ jsx(EditablePageRenderer, {
69227
71332
  theme,
69228
71333
  page,
@@ -69243,4 +71348,4 @@ function deriveDashboardBaseUrlFromApiBaseUrl(apiBaseUrl) {
69243
71348
  }
69244
71349
  }
69245
71350
  //#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 };
71351
+ 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 };