@riverbankcms/sdk 0.107.0 → 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 (159) hide show
  1. package/dist/{PreviewEditorSidebar-DpAbAl08.mjs → PreviewEditorSidebar-BBT-kZAM.mjs} +46 -11
  2. package/dist/{PreviewEditorUI-O7cn6Xxv.mjs → PreviewEditorUI-D69xNKT2.mjs} +10 -9
  3. package/dist/{PreviewQueryProvider-D0tnKl0t.mjs → PreviewQueryProvider-RRu7wyQ5.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-CVB7urtl.mjs → SdkPreviewModeRuntime-CuDjXH6o.mjs} +426 -72
  5. package/dist/{SiteChromeCustomizeContext-C_sizso-.mjs → SiteChromeCustomizeContext-BQUY2dEk.mjs} +3865 -544
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +3712 -220
  7. package/dist/_dts/api/src/blocks.d.ts +41 -7
  8. package/dist/_dts/api/src/bookingRecords.d.ts +180 -115
  9. package/dist/_dts/api/src/cache-tags.d.ts +3 -0
  10. package/dist/_dts/api/src/contentRuntime.d.ts +19 -1
  11. package/dist/_dts/api/src/endpoints.d.ts +99 -0
  12. package/dist/_dts/api/src/footer-settings.d.ts +1 -0
  13. package/dist/_dts/api/src/footerSettings.d.ts +8 -0
  14. package/dist/_dts/api/src/index.d.ts +5 -2
  15. package/dist/_dts/api/src/navigation/contracts.d.ts +3 -3
  16. package/dist/_dts/api/src/previewContentContract.d.ts +4 -0
  17. package/dist/_dts/api/src/sdkContracts.d.ts +62 -0
  18. package/dist/_dts/api/src/siteBanner.d.ts +2 -2
  19. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +143 -55
  20. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +7 -1
  21. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +41 -1
  22. package/dist/_dts/blocks/src/primitives/layout/Section.d.ts +0 -1
  23. package/dist/_dts/blocks/src/rendering/server.d.ts +1 -0
  24. package/dist/_dts/blocks/src/system/blocks/site-footer-runtime.d.ts +50 -0
  25. package/dist/_dts/blocks/src/system/blocks/site-footer.d.ts +9 -48
  26. package/dist/_dts/blocks/src/system/constants/background.d.ts +1 -1
  27. package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -1
  28. package/dist/_dts/blocks/src/system/icons/social.d.ts +5 -0
  29. package/dist/_dts/blocks/src/system/icons/svg.d.ts +1 -0
  30. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +2 -2
  31. package/dist/_dts/blocks/src/system/node/fragments/backgroundLayer.d.ts +13 -0
  32. package/dist/_dts/blocks/src/system/node/fragments/footerNav.d.ts +2 -0
  33. package/dist/_dts/blocks/src/system/node/fragments/styledContainer.d.ts +4 -4
  34. package/dist/_dts/blocks/src/system/node/fragments/styledSection.d.ts +3 -12
  35. package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
  36. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +1 -1
  37. package/dist/_dts/blocks/src/system/types/link.d.ts +3 -3
  38. package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +14 -0
  39. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +27 -8
  40. package/dist/_dts/content-editor/src/footerComposer.d.ts +56 -0
  41. package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +1 -1
  42. package/dist/_dts/content-editor/src/hooks/useEntryMutations.d.ts +5 -5
  43. package/dist/_dts/content-editor/src/index.d.ts +2 -0
  44. package/dist/_dts/content-editor/src/primitives/PreviewRichTextEditor.d.ts +3 -1
  45. package/dist/_dts/content-editor/src/services/contentEntryServices.d.ts +20 -36
  46. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +5 -1
  47. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +11 -0
  48. package/dist/_dts/content-model/src/content-types/schema.d.ts +1 -1
  49. package/dist/_dts/content-model/src/definitions/shared.d.ts +3 -0
  50. package/dist/_dts/core/src/branded.d.ts +3 -0
  51. package/dist/_dts/core/src/editor-state.d.ts +4 -0
  52. package/dist/_dts/core/src/footer-composition.d.ts +143 -0
  53. package/dist/_dts/core/src/index.d.ts +2 -0
  54. package/dist/_dts/core/src/public-profile.d.ts +73 -0
  55. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +3043 -2941
  56. package/dist/_dts/db/src/schemas/forms.d.ts +10 -10
  57. package/dist/_dts/editor/src/primitives/rich-text/RichTextEditorSurface.d.ts +5 -0
  58. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +1 -0
  59. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockCreation.d.ts +2 -1
  60. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +2 -1
  61. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockReorder.d.ts +2 -1
  62. package/dist/_dts/editor-blocks/src/block-editor/owner.d.ts +10 -0
  63. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +1 -0
  64. package/dist/_dts/path-utils/src/index.d.ts +5 -0
  65. package/dist/_dts/preview-next/src/client/preview/PreviewChromeLayer.d.ts +5 -0
  66. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -1
  67. package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +1 -0
  68. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +2 -1
  69. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +2 -1
  70. package/dist/_dts/preview-next/src/client/preview/previewErrorMessages.d.ts +4 -0
  71. package/dist/_dts/sdk/src/cli/content/reader.d.ts +1 -0
  72. package/dist/_dts/sdk/src/client/management/blocks.d.ts +14 -1
  73. package/dist/_dts/sdk/src/client/management/index.d.ts +1 -0
  74. package/dist/_dts/sdk/src/client/management/types.d.ts +15 -1
  75. package/dist/_dts/sdk/src/config/content-types.d.ts +2 -0
  76. package/dist/_dts/sdk/src/config/content-validation.d.ts +4 -0
  77. package/dist/_dts/sdk/src/navigation/index.d.ts +2 -0
  78. package/dist/_dts/sdk/src/public-api/contracts.d.ts +3 -2
  79. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +2 -1
  80. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +1 -1
  81. package/dist/_dts/sdk/src/version.d.ts +1 -1
  82. package/dist/_dts/site-commands/src/commands.d.ts +13 -10
  83. package/dist/_dts/theme-core/src/accordions/types.d.ts +2 -2
  84. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +11 -0
  85. package/dist/_dts/theme-core/src/buttons/personalities/two-tone-pill.d.ts +17 -0
  86. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +1 -1
  87. package/dist/_dts/theme-core/src/buttons/types.d.ts +3 -3
  88. package/dist/_dts/theme-core/src/cards/types.d.ts +3 -3
  89. package/dist/_dts/theme-core/src/footer/mode.d.ts +15 -0
  90. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  91. package/dist/_dts/theme-core/src/interactive/baseSchema.d.ts +1 -1
  92. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +36 -30
  93. package/dist/_dts/theme-core/src/navigation/types.d.ts +1 -1
  94. package/dist/_dts/theme-core/src/schema.d.ts +1186 -34
  95. package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +12 -1
  96. package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +15 -0
  97. package/dist/cli/index.mjs +760 -374
  98. package/dist/client/{DiscountCodeDisclosure-BwGkvmVH.mjs → DiscountCodeDisclosure-D6TOf6Hi.mjs} +1 -1
  99. package/dist/client/{EventCombined.client-JnWE6Hzc.mjs → EventCombined.client-Dao3zxRk.mjs} +3 -3
  100. package/dist/client/{EventListing.client-DQewc_kg.mjs → EventListing.client-B2NNt4y1.mjs} +2 -2
  101. package/dist/client/{LeafletStaticMap-DPAU3SFt.mjs → LeafletStaticMap-BhwFo16w.mjs} +1 -1
  102. package/dist/client/{MagicLinkForm-D4kpWCbW.mjs → MagicLinkForm-BWnB7cMR.mjs} +2 -2
  103. package/dist/client/{StepIndicator-CBlkb4rA.mjs → StepIndicator-TzRiQ0BY.mjs} +2 -2
  104. package/dist/client/{accordion-DAIBVpTS.mjs → accordion-BPy-AJ4_.mjs} +1 -1
  105. package/dist/client/{bookingForm-DZ-4l5_1.mjs → bookingForm-BL4PGZds.mjs} +6 -6
  106. package/dist/client/bookings.mjs +143 -94
  107. package/dist/client/{buttons-DJgynGHQ.mjs → buttons-EBjyslaX.mjs} +144 -95
  108. package/dist/client/{carousel-D-SLfX8r.mjs → carousel-C2b7Cn9-.mjs} +1 -1
  109. package/dist/client/{cart-CEgbgJhX.mjs → cart-BQcbXIVD.mjs} +3 -3
  110. package/dist/client/{checkout-CXWrCRAA.mjs → checkout-DEmpGRJu.mjs} +3 -3
  111. package/dist/client/client.mjs +827 -434
  112. package/dist/client/{courseRegistration-DVmLrRVz.mjs → courseRegistration-BqRZPmsq.mjs} +7 -7
  113. package/dist/client/{eventCalendar-DCuyPY_c.mjs → eventCalendar-B8N_tSl5.mjs} +5 -5
  114. package/dist/client/{eventCombined-kP2CA2D4.mjs → eventCombined-Gjn6gtq7.mjs} +2 -2
  115. package/dist/client/{eventDetails-DU0LeF5e.mjs → eventDetails-M-VCxA-r.mjs} +3 -3
  116. package/dist/client/{eventListing-CcHF87BI.mjs → eventListing-DR19hqYi.mjs} +2 -2
  117. package/dist/client/{eventRegistration-DJnR0yFH.mjs → eventRegistration-BR02a0k3.mjs} +7 -7
  118. package/dist/client/{form-CH1lCusH.mjs → form-LY2xIbwg.mjs} +2 -2
  119. package/dist/client/{headerSection-CBPFZoku.mjs → headerSection-CYwwXJfh.mjs} +3 -3
  120. package/dist/client/hooks.mjs +377 -362
  121. package/dist/client/{locationMap-Cx1hBg5n.mjs → locationMap-DWnBXrFq.mjs} +2 -2
  122. package/dist/client/{newsletterForm-1ZL_ti9u.mjs → newsletterForm-D9s-fQ2P.mjs} +2 -2
  123. package/dist/client/{pricing-BIbzmV0G.mjs → pricing-DDq80oYc.mjs} +1 -1
  124. package/dist/client/{productDetail-BTh5gHBV.mjs → productDetail-B0SbWd45.mjs} +3 -3
  125. package/dist/client/{productList-Cc7OMrqN.mjs → productList-PwYlZn0y.mjs} +3 -3
  126. package/dist/client/{propsDecoder-oR-M-ISN.mjs → propsDecoder-BRWBiH7i.mjs} +33 -9
  127. package/dist/client/rendering/client.mjs +247 -40
  128. package/dist/client/rendering/islands.mjs +18 -18
  129. package/dist/client/rendering.mjs +478 -270
  130. package/dist/client/{shop-CQ_YbCnn.mjs → shop-CMwZPYME.mjs} +6 -6
  131. package/dist/client/{shop-commerce-BM-AoD3M.mjs → shop-commerce-BuxsFate.mjs} +5 -5
  132. package/dist/client/{shop-commerce-store-DFMQhU5p.mjs → shop-commerce-store-boYlEJ91.mjs} +1 -1
  133. package/dist/client/{shopShared-D0SKO2Cu.mjs → shopShared-D2naaOes.mjs} +2 -2
  134. package/dist/client/{useDiscountCodeUi-CrG4_ARt.mjs → useDiscountCodeUi-D9RHpVoj.mjs} +1 -1
  135. package/dist/client/{useEventFilters-CxK8Fekl.mjs → useEventFilters-igGiK1re.mjs} +3 -3
  136. package/dist/client/{usePolling-jcVryNgZ.mjs → usePolling-CI7MbsFB.mjs} +2 -2
  137. package/dist/preview-next/before-render.mjs +178 -0
  138. package/dist/preview-next/client/runtime.mjs +4 -4
  139. package/dist/preview-next/middleware.mjs +178 -0
  140. package/dist/{previewAuthStore-BPcJPzdz.mjs → previewAuthStore-a_cBD28m.mjs} +178 -0
  141. package/dist/{sdk-runtime-C39Rsk-x.mjs → sdk-runtime-MBzD-GmP.mjs} +2 -2
  142. package/dist/{separator-BoMSQnsP.mjs → separator-5ahRBC85.mjs} +1 -1
  143. package/dist/server/components.mjs +556 -366
  144. package/dist/server/config-validation.mjs +384 -363
  145. package/dist/server/config.mjs +384 -364
  146. package/dist/server/data.mjs +377 -362
  147. package/dist/server/index.mjs +179 -1
  148. package/dist/server/navigation.mjs +9 -3
  149. package/dist/server/next.mjs +1384 -995
  150. package/dist/server/page-converter.mjs +368 -355
  151. package/dist/server/prebuild.mjs +1 -1
  152. package/dist/server/rendering/server.mjs +539 -360
  153. package/dist/server/rendering.mjs +556 -366
  154. package/dist/server/routing.mjs +613 -543
  155. package/dist/server/server.mjs +554 -361
  156. package/dist/server/theme-bridge.mjs +189 -98
  157. package/dist/server/theme.mjs +161 -95
  158. package/dist/styles/index.css +7 -1
  159. package/package.json +1 -1
@@ -45,6 +45,14 @@ var __exportAll = (all, no_symbols) => {
45
45
  return target;
46
46
  };
47
47
  var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
48
+ //#endregion
49
+ //#region ../api/src/apiEndpointTypes.ts
50
+ function allowedDemoMutationPolicy() {
51
+ return {
52
+ classification: "allowed",
53
+ publicMessage: ""
54
+ };
55
+ }
48
56
  function blockedDemoMutationPolicy(classification, publicMessage) {
49
57
  if (publicMessage.trim() === "") throw new Error(`Demo mutation policy ${classification} requires publicMessage.`);
50
58
  return {
@@ -70,6 +78,7 @@ const TAG_TEMPLATES = {
70
78
  siteRouteOutcomes: "riverbank:site:{siteId}:route-outcomes",
71
79
  routeById: "riverbank:route:{routeId}",
72
80
  pageById: "riverbank:page:{pageId}",
81
+ pageSurfaceById: "riverbank:page-surface:{pageSurfaceId}",
73
82
  workflowRunById: "riverbank:workflow-run:{runId}",
74
83
  siteForms: "riverbank:site:{siteId}:forms",
75
84
  formById: "riverbank:form:{formId}",
@@ -95,6 +104,7 @@ const TAG_TEMPLATES = {
95
104
  const DEMO_MUTATION_BLOCKED_HIDDEN = blockedDemoMutationPolicy("blocked-hidden", "This action is not available in demo sites.");
96
105
  const DEMO_MUTATION_BLOCKED_DISABLED = blockedDemoMutationPolicy("blocked-disabled", "This setting is disabled in demo sites.");
97
106
  const DEMO_MUTATION_INTERNAL_ONLY = blockedDemoMutationPolicy("internal-only", "This internal operation is not available in demo sites.");
107
+ const DEMO_MUTATION_ALLOWED = allowedDemoMutationPolicy();
98
108
  const API_ENDPOINTS$1 = {
99
109
  aiContentUpdateChat: {
100
110
  path: "/ai/content-update-chat",
@@ -2233,6 +2243,49 @@ const API_ENDPOINTS$1 = {
2233
2243
  auth: "user",
2234
2244
  responseKind: "json"
2235
2245
  },
2246
+ updatePageSurfaceDraftContent: {
2247
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/content",
2248
+ method: "PUT",
2249
+ errors: [
2250
+ "validation:invalid_input",
2251
+ "resource:not_found",
2252
+ "resource:conflict",
2253
+ "server:internal_error"
2254
+ ],
2255
+ tags: [TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById],
2256
+ auth: "user",
2257
+ responseKind: "json"
2258
+ },
2259
+ discardPageSurfaceDraftContent: {
2260
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/content/draft",
2261
+ method: "DELETE",
2262
+ errors: [
2263
+ "validation:invalid_input",
2264
+ "resource:not_found",
2265
+ "resource:conflict",
2266
+ "server:internal_error"
2267
+ ],
2268
+ tags: [TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById],
2269
+ auth: "user",
2270
+ responseKind: "json"
2271
+ },
2272
+ updatePageSurfaceRouteMetadata: {
2273
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/metadata",
2274
+ method: "PATCH",
2275
+ errors: [
2276
+ "validation:invalid_input",
2277
+ "resource:not_found",
2278
+ "resource:conflict",
2279
+ "server:internal_error"
2280
+ ],
2281
+ tags: [
2282
+ TAG_TEMPLATES.siteCollection,
2283
+ TAG_TEMPLATES.siteRoutableContent,
2284
+ TAG_TEMPLATES.pageSurfaceById
2285
+ ],
2286
+ auth: "user",
2287
+ responseKind: "json"
2288
+ },
2236
2289
  runSdkWorkflow: {
2237
2290
  path: "/sites/{siteId}/content/{type}/{entryId}/workflows/{workflowId}/run",
2238
2291
  method: "POST",
@@ -2613,6 +2666,50 @@ const API_ENDPOINTS$1 = {
2613
2666
  errors: [],
2614
2667
  responseKind: "json"
2615
2668
  },
2669
+ getFooterComposition: {
2670
+ path: "/sites/{siteId}/settings/footer-composition",
2671
+ method: "GET",
2672
+ revalidate: 120,
2673
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings],
2674
+ auth: "user",
2675
+ errors: ["resource:not_found", "server:internal_error"],
2676
+ responseKind: "json"
2677
+ },
2678
+ updateFooterComposition: {
2679
+ path: "/sites/{siteId}/settings/footer-composition",
2680
+ method: "POST",
2681
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings],
2682
+ auth: "user",
2683
+ demoMutation: DEMO_MUTATION_ALLOWED,
2684
+ errors: [
2685
+ "validation:invalid_input",
2686
+ "resource:not_found",
2687
+ "server:internal_error"
2688
+ ],
2689
+ responseKind: "json"
2690
+ },
2691
+ getPublicProfile: {
2692
+ path: "/sites/{siteId}/settings/public-profile",
2693
+ method: "GET",
2694
+ revalidate: 120,
2695
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings],
2696
+ auth: "user",
2697
+ errors: ["resource:not_found", "server:internal_error"],
2698
+ responseKind: "json"
2699
+ },
2700
+ updatePublicProfile: {
2701
+ path: "/sites/{siteId}/settings/public-profile",
2702
+ method: "POST",
2703
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings],
2704
+ auth: "user",
2705
+ demoMutation: DEMO_MUTATION_ALLOWED,
2706
+ errors: [
2707
+ "validation:invalid_input",
2708
+ "resource:not_found",
2709
+ "server:internal_error"
2710
+ ],
2711
+ responseKind: "json"
2712
+ },
2616
2713
  updateSiteLayoutSettings: {
2617
2714
  path: "/sites/{siteId}/settings/layout",
2618
2715
  method: "POST",
@@ -3685,6 +3782,76 @@ const API_ENDPOINTS$1 = {
3685
3782
  responseKind: "json",
3686
3783
  errors: ["resource:not_found"]
3687
3784
  },
3785
+ listPageSurfaceContentSlots: {
3786
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/slots",
3787
+ method: "GET",
3788
+ tags: [
3789
+ TAG_TEMPLATES.siteCollection,
3790
+ TAG_TEMPLATES.pageSurfaceById,
3791
+ "surface-slots",
3792
+ "blocks"
3793
+ ],
3794
+ auth: "user",
3795
+ responseKind: "json",
3796
+ errors: [
3797
+ "resource:not_found",
3798
+ "resource:conflict",
3799
+ "server:internal_error"
3800
+ ]
3801
+ },
3802
+ createPageSurfaceSlotBlock: {
3803
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/slots/{slotKey}/blocks",
3804
+ method: "POST",
3805
+ tags: [
3806
+ TAG_TEMPLATES.siteCollection,
3807
+ TAG_TEMPLATES.pageSurfaceById,
3808
+ "surface-slot-{slotKey}",
3809
+ "blocks"
3810
+ ],
3811
+ auth: "user",
3812
+ responseKind: "json",
3813
+ errors: [
3814
+ "validation:invalid_input",
3815
+ "resource:not_found",
3816
+ "resource:conflict",
3817
+ "server:internal_error"
3818
+ ]
3819
+ },
3820
+ reorderPageSurfaceSlotBlocks: {
3821
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/slots/{slotKey}/blocks/reorder",
3822
+ method: "POST",
3823
+ tags: [
3824
+ TAG_TEMPLATES.siteCollection,
3825
+ TAG_TEMPLATES.pageSurfaceById,
3826
+ "surface-slot-{slotKey}",
3827
+ "blocks"
3828
+ ],
3829
+ auth: "user",
3830
+ responseKind: "json",
3831
+ errors: [
3832
+ "validation:invalid_input",
3833
+ "resource:not_found",
3834
+ "resource:conflict",
3835
+ "server:internal_error"
3836
+ ]
3837
+ },
3838
+ deletePageSurfaceSlotBlock: {
3839
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/slots/{slotKey}/blocks/{blockId}",
3840
+ method: "DELETE",
3841
+ tags: [
3842
+ TAG_TEMPLATES.siteCollection,
3843
+ TAG_TEMPLATES.pageSurfaceById,
3844
+ "surface-slot-{slotKey}",
3845
+ "blocks"
3846
+ ],
3847
+ auth: "user",
3848
+ responseKind: "json",
3849
+ errors: [
3850
+ "resource:not_found",
3851
+ "resource:conflict",
3852
+ "server:internal_error"
3853
+ ]
3854
+ },
3688
3855
  createBlock: {
3689
3856
  path: "/sites/{siteId}/pages/{pageId}/blocks",
3690
3857
  method: "POST",
@@ -6297,6 +6464,19 @@ const API_ENDPOINTS$1 = {
6297
6464
  auth: "service",
6298
6465
  responseKind: "json"
6299
6466
  },
6467
+ sdkPatchPageBlock: {
6468
+ path: "/sdk/{siteId}/pages/{identifier}/blocks/{blockIdentifier}",
6469
+ method: "PATCH",
6470
+ errors: [
6471
+ "validation:invalid_input",
6472
+ "resource:not_found",
6473
+ "resource:conflict",
6474
+ "billing:plan_limit_exceeded",
6475
+ "server:internal_error"
6476
+ ],
6477
+ auth: "service",
6478
+ responseKind: "json"
6479
+ },
6300
6480
  sdkReorderPageBlocks: {
6301
6481
  path: "/sdk/{siteId}/pages/{identifier}/blocks/reorder",
6302
6482
  method: "POST",
@@ -6959,6 +7139,108 @@ const API_ENDPOINTS$1 = {
6959
7139
  ]
6960
7140
  }
6961
7141
  };
7142
+ const API_ERROR_CODE_SET = /* @__PURE__ */ new Set([
7143
+ "auth:unauthenticated",
7144
+ "auth:token_expired",
7145
+ "auth:token_invalid",
7146
+ "auth:forbidden",
7147
+ "auth:mfa_required",
7148
+ "auth:sudo_required",
7149
+ "auth:insufficient_permissions",
7150
+ "auth:impersonation_restricted",
7151
+ "validation:invalid_input",
7152
+ "validation:missing_field",
7153
+ "validation:invalid_format",
7154
+ "validation:payload_too_large",
7155
+ "resource:not_found",
7156
+ "resource:already_exists",
7157
+ "resource:conflict",
7158
+ "resource:gone",
7159
+ "rate_limit:exceeded",
7160
+ "billing:payment_required",
7161
+ "billing:plan_limit_exceeded",
7162
+ "billing:pass_redemption_failed",
7163
+ "server:internal_error",
7164
+ "server:unavailable",
7165
+ "external:service_error",
7166
+ "external:registrar_orphaned_contact_profile",
7167
+ "network:connection_error",
7168
+ "network:timeout",
7169
+ "network:dns_error"
7170
+ ]);
7171
+ function isApiErrorCode(value) {
7172
+ return typeof value === "string" && API_ERROR_CODE_SET.has(value);
7173
+ }
7174
+ function isApiError(result) {
7175
+ return result.success === false;
7176
+ }
7177
+ function isApiSuccess(result) {
7178
+ return result.success === true;
7179
+ }
7180
+ function isRecord$54(value) {
7181
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7182
+ }
7183
+ function isFieldError$1(value) {
7184
+ return isRecord$54(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
7185
+ }
7186
+ function fieldErrorsFromUnknown(value) {
7187
+ if (!Array.isArray(value)) return null;
7188
+ return value.every(isFieldError$1) ? value : null;
7189
+ }
7190
+ function extractEnvelopeErrorObject(body) {
7191
+ if (!isRecord$54(body)) return null;
7192
+ const error = body.error;
7193
+ if (!isRecord$54(error)) return null;
7194
+ if ("success" in body && body.success !== false) return null;
7195
+ return error;
7196
+ }
7197
+ function extractApiEnvelopeErrorDetails(body) {
7198
+ const error = extractEnvelopeErrorObject(body);
7199
+ if (!error) return {
7200
+ rawCode: null,
7201
+ code: null,
7202
+ message: null,
7203
+ status: null,
7204
+ fieldErrors: null
7205
+ };
7206
+ const rawCode = typeof error.code === "string" ? error.code : null;
7207
+ const message = typeof error.message === "string" && error.message.trim().length > 0 ? error.message : null;
7208
+ return {
7209
+ rawCode,
7210
+ code: isApiErrorCode(rawCode) ? rawCode : null,
7211
+ message,
7212
+ status: typeof error.status === "number" && Number.isFinite(error.status) ? error.status : null,
7213
+ fieldErrors: fieldErrorsFromUnknown(error.fieldErrors)
7214
+ };
7215
+ }
7216
+ /**
7217
+ * Error class for API failures that can be thrown from unwrapResponse.
7218
+ * Preserves all error metadata from the envelope.
7219
+ */
7220
+ var ApiEnvelopeError = class extends Error {
7221
+ constructor(error) {
7222
+ super(error.message);
7223
+ this.name = "ApiEnvelopeError";
7224
+ this.code = error.code;
7225
+ this.requestId = error.requestId;
7226
+ this.timestamp = error.timestamp;
7227
+ this.status = error.status;
7228
+ this.fieldErrors = error.fieldErrors;
7229
+ }
7230
+ };
7231
+ /**
7232
+ * Unwrap a successful API response or throw on error.
7233
+ *
7234
+ * @example
7235
+ * ```typescript
7236
+ * const response = await apiClient({ endpoint: 'getUser', params: { id } });
7237
+ * const user = unwrapResponse(response); // Throws if not success
7238
+ * ```
7239
+ */
7240
+ function unwrapResponse(result) {
7241
+ if (isApiSuccess(result)) return result.data;
7242
+ throw new ApiEnvelopeError(result.error);
7243
+ }
6962
7244
  //#endregion
6963
7245
  //#region ../core/src/result.ts
6964
7246
  function ok$3(value) {
@@ -7174,7 +7456,7 @@ var init_event_pricing = __esmMin((() => {
7174
7456
  //#endregion
7175
7457
  //#region ../core/src/event-page-surface-subject.ts
7176
7458
  function parseEventPageSurfaceSubject(value) {
7177
- if (!isRecord$51(value)) return err$3({ kind: "notObject" });
7459
+ if (!isRecord$53(value)) return err$3({ kind: "notObject" });
7178
7460
  switch (value.kind) {
7179
7461
  case "eventSeries": {
7180
7462
  const eventSeriesId = parseEventSeriesId(value.eventSeriesId);
@@ -7217,7 +7499,7 @@ function parseEventPageSurfaceSubject(value) {
7217
7499
  });
7218
7500
  }
7219
7501
  }
7220
- function isRecord$51(value) {
7502
+ function isRecord$53(value) {
7221
7503
  return typeof value === "object" && value !== null && !Array.isArray(value);
7222
7504
  }
7223
7505
  var init_event_page_surface_subject = __esmMin((() => {
@@ -7623,6 +7905,25 @@ var init_participant_identity = __esmMin((() => {
7623
7905
  init_assertNever();
7624
7906
  }));
7625
7907
  var init_public_url_validation = __esmMin((() => {}));
7908
+ var init_public_profile = __esmMin((() => {
7909
+ init_public_url_validation();
7910
+ init_result();
7911
+ })), sectionKinds;
7912
+ var init_footer_composition = __esmMin((() => {
7913
+ init_result();
7914
+ sectionKinds = [
7915
+ "brand",
7916
+ "supporting-text",
7917
+ "social-links",
7918
+ "navigation",
7919
+ "business-address",
7920
+ "contact",
7921
+ "opening-hours",
7922
+ "legal-navigation",
7923
+ "legal"
7924
+ ];
7925
+ new Map(sectionKinds.map((kind, index) => [kind, index]));
7926
+ }));
7626
7927
  var init_number_input = __esmMin((() => {}));
7627
7928
  var init_field_errors = __esmMin((() => {})), init_form_submission_preview = __esmMin((() => {
7628
7929
  init_string();
@@ -7657,7 +7958,7 @@ function sortStableJsonValue(value) {
7657
7958
  if (typeof value === "object") {
7658
7959
  const prototype = Object.getPrototypeOf(value);
7659
7960
  if (prototype !== Object.prototype && prototype !== null) throw new TypeError("Stable JSON only supports plain objects");
7660
- return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => [key, sortStableJsonValue(child)]));
7961
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, child]) => [key, sortStableJsonValue(child)]));
7661
7962
  }
7662
7963
  throw new TypeError(`Stable JSON does not support ${typeof value}`);
7663
7964
  }
@@ -7720,6 +8021,8 @@ var init_src$4 = __esmMin((() => {
7720
8021
  init_participants();
7721
8022
  init_participant_identity();
7722
8023
  init_public_url_validation();
8024
+ init_public_profile();
8025
+ init_footer_composition();
7723
8026
  init_number_input();
7724
8027
  init_field_errors();
7725
8028
  init_form_submission_preview();
@@ -8027,7 +8330,7 @@ function containsUnsafePathSegmentCharacter(value) {
8027
8330
  function isReservedPathSegment(value) {
8028
8331
  return value === "." || value === "..";
8029
8332
  }
8030
- function isUnsafePathSegment(segment) {
8333
+ function isUnsafePathSegment$1(segment) {
8031
8334
  return segment.trim().length === 0 || segment !== segment.trim() || isReservedPathSegment(segment) || containsUnsafePathSegmentCharacter(segment);
8032
8335
  }
8033
8336
  var CONTROL_CHARACTER_PATTERN$1, init_fileSafety = __esmMin((() => {
@@ -8056,7 +8359,7 @@ function parseStoragePath(value) {
8056
8359
  * that every tenant/site identifier remains one segment, never a nested path.
8057
8360
  */
8058
8361
  function joinStoragePathSegments(segments) {
8059
- if (segments.some(isUnsafePathSegment)) return err$3("unsafe-path-segment");
8362
+ if (segments.some(isUnsafePathSegment$1)) return err$3("unsafe-path-segment");
8060
8363
  return ok$3(unsafeAsStoragePath(segments.join("/")));
8061
8364
  }
8062
8365
  var FILE_STORAGE_BUCKETS, PRIVATE_SITE_FILE_BUCKET_MIME_TYPES;
@@ -8972,7 +9275,7 @@ var init_validation_constants = __esmMin((() => {
8972
9275
  "media.fromUrl",
8973
9276
  "background.resolveStyle",
8974
9277
  "background.resolveColorsStyle",
8975
- "background.resolveAllowOverflow",
9278
+ "background.resolveFrameClassName",
8976
9279
  "background.resolveImageStyle",
8977
9280
  "background.resolveImageClassName",
8978
9281
  "background.resolveOverlayStyle",
@@ -18309,6 +18612,53 @@ var init_soft_pill = __esmMin((() => {
18309
18612
  });
18310
18613
  }));
18311
18614
  //#endregion
18615
+ //#region ../theme-core/src/buttons/personalities/two-tone-pill.ts
18616
+ var solidSecondary, twoTonePill;
18617
+ var init_two_tone_pill = __esmMin((() => {
18618
+ init_soft_pill();
18619
+ init_types$13();
18620
+ solidSecondary = {
18621
+ id: "secondary",
18622
+ name: "Secondary",
18623
+ enabled: true,
18624
+ priority: 2,
18625
+ background: {
18626
+ type: "solid",
18627
+ colorToken: "secondary"
18628
+ },
18629
+ textColorToken: "onSecondary",
18630
+ borderRadius: "rounded-full",
18631
+ shadow: {
18632
+ elevation: "none",
18633
+ softness: null,
18634
+ position: "bottom"
18635
+ },
18636
+ effects: {
18637
+ hover: [{
18638
+ effectId: "background-on-hover-alpha",
18639
+ options: {
18640
+ colorToken: "secondary",
18641
+ opacity: 88
18642
+ }
18643
+ }],
18644
+ active: [{
18645
+ effectId: "scale-down",
18646
+ options: { scale: "0.98" }
18647
+ }]
18648
+ }
18649
+ };
18650
+ twoTonePill = defineButtonPersonality({
18651
+ id: "two-tone-pill",
18652
+ name: "Two-tone Pill",
18653
+ description: "Rounded pills with distinct solid primary and secondary brand colours.",
18654
+ tags: softPill.tags,
18655
+ buttonSystem: {
18656
+ ...softPill.buttonSystem,
18657
+ variants: softPill.buttonSystem.variants.map((variant) => variant.id === "secondary" ? solidSecondary : variant)
18658
+ }
18659
+ });
18660
+ }));
18661
+ //#endregion
18312
18662
  //#region ../theme-core/src/buttons/personalities/index.ts
18313
18663
  function findButtonPersonality(id) {
18314
18664
  return personalitiesById.get(id);
@@ -18327,9 +18677,11 @@ var init_personalities = __esmMin((() => {
18327
18677
  init_quiet_arrow();
18328
18678
  init_showtime_pill();
18329
18679
  init_soft_pill();
18680
+ init_two_tone_pill();
18330
18681
  init_types$13();
18331
18682
  buttonPersonalities = [
18332
18683
  softPill,
18684
+ twoTonePill,
18333
18685
  earthPill,
18334
18686
  confidentChip,
18335
18687
  editorialLink,
@@ -18771,7 +19123,7 @@ function asHeaderStyleId(value) {
18771
19123
  * optional nested styling fields that would otherwise leak from another Look.
18772
19124
  */
18773
19125
  function baseHeader(theme) {
18774
- const { navLinkStyle: _navLinkStyle, navTypography: _navTypography, navTextSize: _navTextSize, dropdownStyle: _dropdownStyle, ctaVariant: _ctaVariant, navContainer: _navContainer, container: _container, shadow: _shadow, logo: _logo, logoText: _logoText, border: _border, ...header } = theme.header;
19126
+ const { navLinkStyle: _navLinkStyle, navFontRole: _navFontRole, navTypography: _navTypography, navTextSize: _navTextSize, dropdownStyle: _dropdownStyle, ctaVariant: _ctaVariant, navContainer: _navContainer, container: _container, shadow: _shadow, logo: _logo, logoText: _logoText, border: _border, ...header } = theme.header;
18775
19127
  return {
18776
19128
  ...header,
18777
19129
  navContainer: {
@@ -19402,6 +19754,17 @@ var init_headerLooks = __esmMin((() => {
19402
19754
  navTypography: "brand-caps",
19403
19755
  moods: ["expressive"]
19404
19756
  },
19757
+ {
19758
+ id: asHeaderStyleId("brand-capsule"),
19759
+ label: "Brand Capsule",
19760
+ description: "Solid brand chrome designed as a floating capsule, with quiet-caps nav, a soft pill active state, and an inverted CTA pill.",
19761
+ supportedLayoutIds: supportedLayouts(["classic"]),
19762
+ navInteraction: "pill-background",
19763
+ surface: "brand-solid",
19764
+ defaultDepth: "shadow",
19765
+ navTypography: "quiet-caps",
19766
+ moods: ["expressive", "professional"]
19767
+ },
19405
19768
  {
19406
19769
  id: asHeaderStyleId("serif-line"),
19407
19770
  label: "Serif Line",
@@ -19495,6 +19858,7 @@ var init_headerLooks = __esmMin((() => {
19495
19858
  "brand-bar",
19496
19859
  "brand-underline",
19497
19860
  "brand-pill",
19861
+ "brand-capsule",
19498
19862
  "serif-line",
19499
19863
  "flat-tabs"
19500
19864
  ])],
@@ -19529,6 +19893,11 @@ var init_headerLooks = __esmMin((() => {
19529
19893
  "brand-pill",
19530
19894
  "brand-bar",
19531
19895
  "minimal"
19896
+ ]), headerStyleRepairChain([
19897
+ "brand-capsule",
19898
+ "brand-pill",
19899
+ "brand-bar",
19900
+ "minimal"
19532
19901
  ]), headerStyleRepairChain([
19533
19902
  "pill-nav",
19534
19903
  "soft-bar",
@@ -23018,7 +23387,24 @@ var init_tokenOrColor = __esmMin((() => {
23018
23387
  "white",
23019
23388
  "yellow"
23020
23389
  ]);
23021
- })), axesSchema, colourHexString, paletteColorSchema, paletteMetaSchema, paletteSchema, typographyStyleSchema, bodyTypographyStyleSchema, headingSizeSchema, headingTypographyOverridesSchema, headingTypographyStyleSchema, proseLinkUnderlineStyleSchema, proseLinkUnderlineThicknessSchema, proseLinkUnderlineOffsetSchema, proseLinkStyleSchema, semanticSpacingSchema, boxRoundedSchema, boxBackgroundOverlaySchema, boxBackgroundSchema, noHeadingDecorationSchema, visibleHeadingDecorationSchema, headingDecorationSchema, headingDecorationOverrideSchema, accordionIconTreatmentSchema, sectionStylesOverrideSchema, containerStylesOverrideSchema, cardBorderOverrideSchema, cardStylesOverrideSchema, blockStyleOverridesSchema, blockThemeOverrideSchema, typographyScaleSchema, eyebrowTypographyStyleSchema, typographySchema, spaceSchema, corners, shadow, border, motion, inputStyle, headerVariant, headerPositioning, headerNavStyle, navFontWeight, headerMaxWidth, headerContainerSchema, headerBorderSchema, logoStyleSchema, headerLogoTextSchema, navEffectsSchema, dropdownStyleSchema, headerCtaGapSchema, headerCtaTreatmentSchema, navContainerSchema, headerBackgroundSchema, headerSchema, footerVariant, footerMaxWidth, footerMode, footerNavLayoutMode, footerNavLayoutAlign, footerSpacing, footerLogoPlacement, footerLogoSize, footerLogoMaxHeight, footerBottomTextLinkStyleSchema, footerBottomBarSchema, footerNavLayoutSchema, footerLogoSchema, footerSchema, containerPaddingPresetSchema, layoutSchema, heroTypographySizeSchema, heroTypographyLineHeightSchema, heroResponsiveTypographySchema, heroTypographySchema, heroSchema, bodyTextIntroTypographySizeSchema, bodyTextSchema, gradientsSchema, testimonialQuoteTreatmentSchema, themeSchema;
23390
+ }));
23391
+ //#endregion
23392
+ //#region ../theme-core/src/schema.ts
23393
+ /**
23394
+ * Normalises the legacy `navTypography` font-role alias into the canonical
23395
+ * `navFontRole` field so persisted themes migrate at the parse boundary without
23396
+ * a data migration. `navFontRole` always wins when both are present; the legacy
23397
+ * field is dropped so we never carry a dual write forward.
23398
+ */
23399
+ function normaliseHeaderNavFontRole(header) {
23400
+ if (header.navTypography === void 0) return header;
23401
+ const { navTypography, ...rest } = header;
23402
+ return header.navFontRole === void 0 ? {
23403
+ ...rest,
23404
+ navFontRole: navTypography
23405
+ } : rest;
23406
+ }
23407
+ var axesSchema, colourHexString, paletteColorSchema, paletteMetaSchema, paletteSchema, typographyStyleSchema, bodyTypographyStyleSchema, headingSizeSchema, headingTypographyOverridesSchema, headingTypographyStyleSchema, proseLinkUnderlineStyleSchema, proseLinkUnderlineThicknessSchema, proseLinkUnderlineOffsetSchema, proseLinkStyleSchema, semanticSpacingSchema, boxRoundedSchema, boxBackgroundOverlaySchema, boxBackgroundSchema, noHeadingDecorationSchema, visibleHeadingDecorationSchema, headingDecorationSchema, headingDecorationOverrideSchema, accordionIconTreatmentSchema, sectionStylesOverrideSchema, containerStylesOverrideSchema, cardBorderOverrideSchema, cardStylesOverrideSchema, blockStyleOverridesSchema, blockThemeOverrideSchema, typographyScaleSchema, eyebrowTypographyStyleSchema, typographySchema, spaceSchema, corners, shadow, border, motion, inputStyle, headerVariant, headerPositioning, headerNavStyle, navFontWeight, headerMaxWidth, headerBarFrame, headerContainerSchema, headerBorderSchema, logoStyleSchema, headerLogoTextSchema, navEffectsSchema, dropdownStyleSchema, headerCtaGapSchema, headerCtaTreatmentSchema, navContainerSchema, headerBackgroundSchema, headerSchema, footerVariant, footerMaxWidth, footerMode, footerNavLayoutMode, footerNavLayoutAlign, footerSpacing, footerLogoPlacement, footerLogoSize, footerLogoMaxHeight, footerBottomTextLinkStyleSchema, footerBottomBarSchema, footerNavLayoutSchema, footerLogoSchema, footerSchema, containerPaddingPresetSchema, layoutSchema, heroTypographySizeSchema, heroTypographyLineHeightSchema, heroResponsiveTypographySchema, heroTypographySchema, heroSchema, bodyTextIntroTypographySizeSchema, bodyTextSchema, gradientsSchema, testimonialQuoteTreatmentSchema, themeSchema;
23022
23408
  var init_schema = __esmMin((() => {
23023
23409
  init_media$2();
23024
23410
  init_buttons();
@@ -23451,6 +23837,7 @@ var init_schema = __esmMin((() => {
23451
23837
  "bold"
23452
23838
  ]);
23453
23839
  headerMaxWidth = z$1.enum(["container", "full"]);
23840
+ headerBarFrame = z$1.enum(["full-bleed", "inset-shell"]);
23454
23841
  headerContainerSchema = z$1.object({
23455
23842
  rounded: z$1.enum([
23456
23843
  "none",
@@ -23591,6 +23978,7 @@ var init_schema = __esmMin((() => {
23591
23978
  positioning: headerPositioning,
23592
23979
  shrinkOnScroll: z$1.boolean(),
23593
23980
  maxWidth: headerMaxWidth,
23981
+ barFrame: headerBarFrame.optional(),
23594
23982
  logoOverride: mediaSchema$1.nullable().optional(),
23595
23983
  background: headerBackgroundSchema.default({
23596
23984
  type: "color",
@@ -23600,6 +23988,7 @@ var init_schema = __esmMin((() => {
23600
23988
  navStyle: headerNavStyle,
23601
23989
  navColor: themeColorTokenSchema.nullable().optional(),
23602
23990
  navWeight: navFontWeight.default("medium"),
23991
+ navFontRole: z$1.enum(["body", "heading"]).optional(),
23603
23992
  navTypography: z$1.enum(["body", "heading"]).optional(),
23604
23993
  navTextSize: navLinkStyleSchema.shape.textSize,
23605
23994
  navPlacement: z$1.enum(["end", "center"]).optional(),
@@ -23615,7 +24004,7 @@ var init_schema = __esmMin((() => {
23615
24004
  ctaTreatment: headerCtaTreatmentSchema.optional(),
23616
24005
  ctaVariant: z$1.string().min(1).optional(),
23617
24006
  dropdownStyle: dropdownStyleSchema
23618
- });
24007
+ }).transform(normaliseHeaderNavFontRole);
23619
24008
  footerVariant = z$1.enum([
23620
24009
  "simple",
23621
24010
  "columns",
@@ -24673,6 +25062,7 @@ var init_curatedSiteStyles = __esmMin((() => {
24673
25062
  ],
24674
25063
  buttonPersonalityChoices: [
24675
25064
  buttonChoice("soft-pill"),
25065
+ buttonChoice("two-tone-pill"),
24676
25066
  buttonChoice("pebble"),
24677
25067
  buttonChoice("editorial-link"),
24678
25068
  buttonChoice("brushed-wash")
@@ -25852,6 +26242,7 @@ var init_curatedSiteStyles = __esmMin((() => {
25852
26242
  ],
25853
26243
  buttonPersonalityChoices: [
25854
26244
  buttonChoice("quiet-arrow"),
26245
+ buttonChoice("two-tone-pill"),
25855
26246
  buttonChoice("flat-ink"),
25856
26247
  buttonChoice("editorial-link")
25857
26248
  ],
@@ -27366,6 +27757,34 @@ function backgroundLayer(path, options = {}) {
27366
27757
  ];
27367
27758
  }
27368
27759
  /**
27760
+ * Wrap decorative background layers in their own clipping frame.
27761
+ *
27762
+ * Foreground content remains outside this frame, so editor outlines, focus
27763
+ * rings, and floating controls are never clipped by a visual background.
27764
+ * Backgrounds that explicitly opt into overflow keep that behavior within
27765
+ * the decorative layer rather than changing the content root.
27766
+ */
27767
+ function backgroundFrame(path, options = {}) {
27768
+ const { leadingNodes = [], ...layerOptions } = options;
27769
+ const framedLayerOptions = {
27770
+ ...layerOptions,
27771
+ styleClassName: layerOptions.styleClassName ?? "background-style rb-absolute rb-inset-0 rb-z-0 rb-h-full rb-w-full rb-pointer-events-none",
27772
+ imageClassName: layerOptions.imageClassName ?? "rb-absolute rb-z-0",
27773
+ overlayClassName: layerOptions.overlayClassName ?? "background-overlay rb-absolute rb-inset-0 rb-z-0 rb-h-full rb-w-full rb-pointer-events-none"
27774
+ };
27775
+ return el("div", {
27776
+ className: { $bind: {
27777
+ from: path,
27778
+ transforms: [{
27779
+ id: "background.resolveFrameClassName",
27780
+ options: { baseClass: BACKGROUND_FRAME_BASE_CLASS }
27781
+ }],
27782
+ fallback: `${BACKGROUND_FRAME_BASE_CLASS} rb-overflow-hidden`
27783
+ } },
27784
+ style: { borderRadius: "inherit" }
27785
+ }, [...leadingNodes, ...backgroundLayer(path, framedLayerOptions)]);
27786
+ }
27787
+ /**
27369
27788
  * Creates a media node for rendering background image/video media with conditional rendering.
27370
27789
  *
27371
27790
  * This helper creates a media element that:
@@ -27440,8 +27859,10 @@ function createBackgroundOverlayNode(path, className = "background-overlay rb-ab
27440
27859
  } }
27441
27860
  });
27442
27861
  }
27862
+ var BACKGROUND_FRAME_BASE_CLASS;
27443
27863
  var init_backgroundLayer = __esmMin((() => {
27444
27864
  init_builder$1();
27865
+ BACKGROUND_FRAME_BASE_CLASS = "rb-background-frame rb-absolute rb-inset-0 rb-z-neg-10 rb-h-full rb-w-full rb-isolate rb-pointer-events-none";
27445
27866
  }));
27446
27867
  //#endregion
27447
27868
  //#region ../blocks/src/system/node/fragments/eyebrow.ts
@@ -27542,8 +27963,8 @@ var init_sectionContainer = __esmMin((() => {
27542
27963
  * - content
27543
27964
  */
27544
27965
  function styledContainer(config) {
27545
- const { children, rootType = "div", rootProps, bindFrom = "_containerStyles", baseClassName = "rb-relative rb-isolate rb-overflow-hidden", imageClassName = "rb-absolute rb-z-neg-10", constrainWidth = true } = config;
27546
- const backgroundNodes = backgroundLayer(`${bindFrom}.background`, { imageClassName });
27966
+ const { children, rootType = "div", rootProps, bindFrom = "_containerStyles", baseClassName = "rb-relative rb-isolate rb-overflow-visible", imageClassName = "rb-absolute rb-z-0", constrainWidth = true } = config;
27967
+ const backgroundNode = backgroundFrame(`${bindFrom}.background`, { imageClassName });
27547
27968
  const childrenArray = Array.isArray(children) ? children : [children];
27548
27969
  const { className: _ignoredClassName, style: _ignoredStyle, ...safeRootProps } = rootProps ?? {};
27549
27970
  return el(rootType, {
@@ -27566,7 +27987,7 @@ function styledContainer(config) {
27566
27987
  }],
27567
27988
  fallback: constrainWidth ? `${baseClassName} rb-container` : baseClassName
27568
27989
  } }
27569
- }, [...backgroundNodes, ...childrenArray]);
27990
+ }, [backgroundNode, ...childrenArray]);
27570
27991
  }
27571
27992
  var init_styledContainer = __esmMin((() => {
27572
27993
  init_builder$1();
@@ -27664,7 +28085,7 @@ var init_spacing = __esmMin((() => {
27664
28085
  * - Creating a section wrapper with background theme
27665
28086
  * - Adding background color/gradient/image layers
27666
28087
  * - Binding className to section styles with transform
27667
- * - Binding allowOverflow for background positioning
28088
+ * - Keeping foreground overflow visible while decorative backgrounds clip independently
27668
28089
  * - Wrapping content children
27669
28090
  *
27670
28091
  * Use this helper to eliminate 25+ lines of boilerplate section setup code.
@@ -27700,8 +28121,8 @@ var init_spacing = __esmMin((() => {
27700
28121
  * });
27701
28122
  */
27702
28123
  function styledSection(config) {
27703
- const { children, baseClass = "rb-px-6", spacing = DEFAULT_SECTION_SPACING, background = "background", bindFrom = "_sectionStyles", imageClassName = "rb-absolute rb-z-neg-10", renderBackgroundImage = true, backgroundImageLoading, backgroundImageFetchPriority, allowOverflow = false, fullWidthPath } = config;
27704
- const renderedBackgroundNodes = backgroundLayer(`${bindFrom}.background`, {
28124
+ const { children, baseClass = "rb-px-6", spacing = DEFAULT_SECTION_SPACING, background = "background", bindFrom = "_sectionStyles", imageClassName = "rb-absolute rb-z-0", renderBackgroundImage = true, backgroundImageLoading, backgroundImageFetchPriority, fullWidthPath } = config;
28125
+ const renderedBackgroundNode = backgroundFrame(`${bindFrom}.background`, {
27705
28126
  imageClassName,
27706
28127
  fallbackToken: background,
27707
28128
  omitImageLayer: !renderBackgroundImage,
@@ -27724,13 +28145,8 @@ function styledSection(config) {
27724
28145
  fullWidthPath
27725
28146
  }
27726
28147
  }]
27727
- } },
27728
- allowOverflow: allowOverflow ? true : { $bind: {
27729
- from: `${bindFrom}.background`,
27730
- transforms: [{ id: "background.resolveAllowOverflow" }],
27731
- fallback: false
27732
28148
  } }
27733
- }, [...renderedBackgroundNodes, ...childrenArray]);
28149
+ }, [renderedBackgroundNode, ...childrenArray]);
27734
28150
  }
27735
28151
  var init_styledSection = __esmMin((() => {
27736
28152
  init_builder$1();
@@ -28546,9 +28962,12 @@ var init_responsiveTwoColumn = __esmMin((() => {
28546
28962
  //#endregion
28547
28963
  //#region ../blocks/src/system/node/fragments/styledCard.ts
28548
28964
  function styledCard(children, opts, ...mods) {
28549
- const baseClassName = opts.baseClassName ?? "rb-relative rb-isolate rb-overflow-hidden rb-border";
28550
- const defaultBackgroundLayer = el("div", { className: "rb-absolute rb-inset-0 rb-z-neg-10 rb-h-full rb-w-full rb-pointer-events-none rb-bg-surface" });
28551
- const backgroundNodes = backgroundLayer(opts.backgroundFrom);
28965
+ const baseClassName = opts.baseClassName ?? "rb-relative rb-isolate rb-overflow-visible rb-border";
28966
+ const defaultBackgroundLayer = el("div", {
28967
+ className: "rb-absolute rb-inset-0 rb-z-neg-10 rb-h-full rb-w-full rb-pointer-events-none rb-bg-surface",
28968
+ style: { borderRadius: "inherit" }
28969
+ });
28970
+ const backgroundNode = backgroundFrame(opts.backgroundFrom);
28552
28971
  const style = {
28553
28972
  ...opts.style ?? {},
28554
28973
  borderColor: { $bind: {
@@ -28575,7 +28994,7 @@ function styledCard(children, opts, ...mods) {
28575
28994
  ...style ? { style } : {}
28576
28995
  }, [
28577
28996
  defaultBackgroundLayer,
28578
- ...backgroundNodes,
28997
+ backgroundNode,
28579
28998
  ...children
28580
28999
  ], ...mods);
28581
29000
  }
@@ -29550,7 +29969,7 @@ function buildTestimonialCard(...mods) {
29550
29969
  }, [stack({ gap: "md" }, [quoteMark, body]), el("div", { className: "rb-testimonial-attribution" }, buildAttributionNodes())])], {
29551
29970
  stylesFrom: "content._cardStyles",
29552
29971
  backgroundFrom: "content._cardStyles.background",
29553
- baseClassName: "rb-testimonial-card rb-relative rb-isolate rb-flex rb-h-full rb-flex-col rb-overflow-hidden rb-p-8"
29972
+ baseClassName: "rb-testimonial-card rb-relative rb-isolate rb-flex rb-h-full rb-flex-col rb-overflow-visible rb-p-8"
29554
29973
  }, ...mods);
29555
29974
  }
29556
29975
  /**
@@ -30320,7 +30739,7 @@ function createFaqAccordionLayout(options = {}) {
30320
30739
  options: {
30321
30740
  axis: "all",
30322
30741
  includeSpacing: false,
30323
- baseClass: "rb-faq-item rb-relative rb-isolate rb-overflow-hidden"
30742
+ baseClass: "rb-faq-item rb-relative rb-isolate rb-overflow-visible"
30324
30743
  }
30325
30744
  }]
30326
30745
  },
@@ -31991,7 +32410,6 @@ function splitLayoutWith(children) {
31991
32410
  }
31992
32411
  }),
31993
32412
  renderBackgroundImage: false,
31994
- allowOverflow: true,
31995
32413
  baseClass: ""
31996
32414
  });
31997
32415
  }
@@ -32636,7 +33054,7 @@ function postCard(children, ...mods) {
32636
33054
  return styledCard(children, {
32637
33055
  stylesFrom: "content._cardStyles",
32638
33056
  backgroundFrom: "content._cardStyles.background",
32639
- baseClassName: "rb-relative rb-isolate rb-overflow-hidden rb-border rb-flex rb-flex-col rb-h-full"
33057
+ baseClassName: "rb-relative rb-isolate rb-overflow-visible rb-border rb-flex rb-flex-col rb-h-full"
32640
33058
  }, ...mods);
32641
33059
  }
32642
33060
  const gridPostCard = postCard([postImageLink("rb-h-48 rb-w-full rb-object-cover rb-transition-transform rb-hover-scale-105", {
@@ -32672,7 +33090,7 @@ const stackPostCard = styledCard([inline({
32672
33090
  ])])], {
32673
33091
  stylesFrom: "content._cardStyles",
32674
33092
  backgroundFrom: "content._cardStyles.background",
32675
- baseClassName: "rb-relative rb-isolate rb-overflow-hidden rb-border"
33093
+ baseClassName: "rb-relative rb-isolate rb-overflow-visible rb-border"
32676
33094
  }, repeat("data.posts", "post"));
32677
33095
  const emptyState$2 = {
32678
33096
  ...styledCard([text({
@@ -32681,7 +33099,7 @@ const emptyState$2 = {
32681
33099
  }, bind("content.emptyMessage", { fallback: "No posts published yet." }))], {
32682
33100
  stylesFrom: "content._cardStyles",
32683
33101
  backgroundFrom: "content._cardStyles.background",
32684
- baseClassName: "rb-relative rb-isolate rb-overflow-hidden rb-border rb-border-dashed rb-p-8 rb-text-center"
33102
+ baseClassName: "rb-relative rb-isolate rb-overflow-visible rb-border rb-border-dashed rb-p-8 rb-text-center"
32685
33103
  }),
32686
33104
  $when: {
32687
33105
  when: { from: "data.posts[0]" },
@@ -32691,7 +33109,7 @@ const emptyState$2 = {
32691
33109
  function blogListingShell(children) {
32692
33110
  return styledSection({
32693
33111
  children: styledContainer({
32694
- baseClassName: "rb-relative rb-isolate rb-overflow-hidden",
33112
+ baseClassName: "rb-relative rb-isolate rb-overflow-visible",
32695
33113
  children
32696
33114
  }),
32697
33115
  baseClass: ""
@@ -33241,7 +33659,7 @@ const copyLayout = fragmentLayoutNode$1(formCopyFragment.layout);
33241
33659
  const formSurface = styledContainer({
33242
33660
  bindFrom: "_containerStyles",
33243
33661
  constrainWidth: false,
33244
- baseClassName: "rb-form-surface rb-relative rb-isolate rb-overflow-hidden",
33662
+ baseClassName: "rb-form-surface rb-relative rb-isolate rb-overflow-visible",
33245
33663
  children: fragmentLayoutNode$1(formEmbedFragment.layout)
33246
33664
  });
33247
33665
  function createFormLayout(variant) {
@@ -34540,6 +34958,7 @@ const headerRootClassTransform = {
34540
34958
  ];
34541
34959
  const variant = header?.variant;
34542
34960
  if (variant && VALID_VARIANTS.includes(variant)) classes.push(`header-variant-${variant}`);
34961
+ if (header?.barFrame === "inset-shell" && variant === "classic") classes.push("header-bar-frame-inset-shell");
34543
34962
  return joinClasses$4(classes);
34544
34963
  }
34545
34964
  };
@@ -35093,7 +35512,7 @@ init_builder$1();
35093
35512
  init_fragments$1();
35094
35513
  init_defineBlock();
35095
35514
  init_colorStyles();
35096
- const whenTransformed$1 = (from, transformId, equals = true) => (node) => ({
35515
+ const whenTransformed = (from, transformId, equals = true) => (node) => ({
35097
35516
  ...node,
35098
35517
  $when: {
35099
35518
  when: {
@@ -35121,7 +35540,7 @@ const logoRow = link({
35121
35540
  text({
35122
35541
  as: "strong",
35123
35542
  className: "header-logo-text rb-truncate"
35124
- }, whenTransformed$1("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
35543
+ }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
35125
35544
  ]);
35126
35545
  const centeredLogoRow = link({
35127
35546
  href: "/",
@@ -35141,7 +35560,7 @@ const centeredLogoRow = link({
35141
35560
  text({
35142
35561
  as: "strong",
35143
35562
  className: "header-logo-text"
35144
- }, whenTransformed$1("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
35563
+ }, whenTransformed("$root.theme.header.logo", "layout.headerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
35145
35564
  ]);
35146
35565
  const createNavRow = (className, align = "end") => navRow({
35147
35566
  className: `${className} header-nav-row`,
@@ -35273,7 +35692,7 @@ const classicLayout = inline({
35273
35692
  logoRow,
35274
35693
  createNavRow(`rb-ml-auto ${desktopOnlyDisplay("flex")} rb-gap-6`),
35275
35694
  headerCta
35276
- ], whenTransformed$1("$root.theme.header", "layout.classicNavMode", "inline"));
35695
+ ], whenTransformed("$root.theme.header", "layout.classicNavMode", "inline"));
35277
35696
  const classicCenteredNavLayout = inline({
35278
35697
  className: bindProp("$root.theme.header.maxWidth", {
35279
35698
  transforms: pipe(tx("layout.maxWidthClass", { base: `rb-header-layout ${desktopOnlyDisplay("flex")} rb-w-full rb-items-center rb-gap-6` })),
@@ -35284,7 +35703,7 @@ const classicCenteredNavLayout = inline({
35284
35703
  logoRow,
35285
35704
  createNavRow(`rb-flex-1 rb-justify-center ${desktopOnlyDisplay("flex")} rb-gap-6`, "center"),
35286
35705
  headerCta
35287
- ], whenTransformed$1("$root.theme.header", "layout.classicNavMode", "centered"));
35706
+ ], whenTransformed("$root.theme.header", "layout.classicNavMode", "centered"));
35288
35707
  const centeredLayout = stack({
35289
35708
  gap: "md",
35290
35709
  align: "center",
@@ -35347,7 +35766,6 @@ const siteHeaderBlockDefinition = { manifest: createBlockManifest({
35347
35766
  transforms: pipe(tx("layout.headerSectionBackground")),
35348
35767
  fallback: "background"
35349
35768
  }),
35350
- allowOverflow: true,
35351
35769
  className: bindProp("$root.theme.header", {
35352
35770
  transforms: pipe(tx("layout.headerRootClass")),
35353
35771
  fallback: "header-root rb-z-40 rb-w-full transition-theme"
@@ -35373,6 +35791,7 @@ const siteHeaderBlockDefinition = { manifest: createBlockManifest({
35373
35791
  //#region ../blocks/src/system/blocks/site-footer-nav-groups-layout.ts
35374
35792
  init_builder$1();
35375
35793
  init_colorStyles();
35794
+ init_footerNav();
35376
35795
  const footerNavGroupsLayout = stack({
35377
35796
  gap: "lg",
35378
35797
  align: "start",
@@ -35399,225 +35818,160 @@ const footerNavGroupsLayout = stack({
35399
35818
  linkRequired: true,
35400
35819
  target: { $bind: { from: "entry.target" } },
35401
35820
  rel: { $bind: { from: "entry.rel" } }
35402
- }, [text({ as: "span" }, bind("entry.label"))], repeat("group.children", "entry"))])], repeat("footerMenu.groups", "group"))], when("footerMenu.groups"));
35821
+ }, [text({ as: "span" }, bind("entry.label"))], repeat("group.children", "entry"))])], repeat("footerMenu.groups", "group"))], whenCollectionHasItems("footerMenu.groups"));
35403
35822
  //#endregion
35404
35823
  //#region ../blocks/src/system/blocks/site-footer.ts
35405
35824
  init_fragments$1();
35406
35825
  init_builder$1();
35407
- init_fragments();
35408
35826
  init_defineBlock();
35409
35827
  init_colorStyles();
35410
35828
  init_surfaces();
35411
- const footerTextLayout = () => materializeFragment({ fragment: footerBottomTextFragment }).layout;
35412
- const whenTransformed = (from, transformId, equals = true) => (node) => ({
35413
- ...node,
35414
- $when: {
35415
- when: {
35416
- from,
35417
- transforms: [{ id: transformId }]
35418
- },
35419
- equals
35420
- }
35421
- });
35422
- const bottomBarTextLayout = () => {
35423
- const bottomTextNode = footerTextLayout()[1];
35424
- return bottomTextNode ? [bottomTextNode] : [];
35425
- };
35426
- const bodyTextLayout = () => {
35427
- const bodyTextNode = footerTextLayout()[0];
35428
- return bodyTextNode ? [bodyTextNode] : [];
35429
- };
35430
- const businessAddressLayout = () => [text({
35431
- as: "p",
35432
- className: "rb-caption rb-opacity-80"
35433
- }, bind("site.businessAddress.displayAddress"), when("content.showBusinessAddress", { equals: true }))];
35434
- const inlineBottomTextLayout = () => {
35435
- const bottomTextNode = footerTextLayout()[1];
35436
- if (!bottomTextNode) return [];
35437
- return [when("$root.theme.footer.bottomBar.enabled", {
35438
- equals: true,
35439
- not: true
35440
- })(bottomTextNode)];
35441
- };
35442
- const simpleFooterLogo = link({
35829
+ const brandLogo = link({
35443
35830
  href: "/",
35444
35831
  className: { $bind: {
35445
35832
  from: "$root.theme.footer.logo",
35446
35833
  transforms: [{
35447
35834
  id: "layout.footerLogoClass",
35448
- options: { requireExplicitShow: true }
35835
+ options: { base: "footer-logo rb-inline-flex rb-items-center rb-gap-3 rb-no-underline" }
35449
35836
  }],
35450
- fallback: "rb-hidden"
35837
+ fallback: "footer-logo rb-inline-flex rb-items-center rb-gap-3 rb-no-underline"
35451
35838
  } }
35452
- }, [
35453
- media({ className: { $bind: {
35454
- from: "$root.theme.footer.logo",
35455
- transforms: [{ id: "layout.footerLogoMediaClass" }],
35456
- fallback: "rb-w-auto"
35457
- } } }, when("content.logo"), bind("content.logo")),
35458
- stack({ className: "rb-contents" }, [media({ className: { $bind: {
35459
- from: "$root.theme.footer.logo",
35460
- transforms: [{ id: "layout.footerLogoMediaClass" }],
35461
- fallback: "rb-w-auto"
35462
- } } }, when("site.logo"), bind("site.logo"))], when("content.logo", { not: true })),
35463
- text({
35464
- as: "strong",
35465
- className: "footer-logo-text rb-nav-text"
35466
- }, whenTransformed("$root.theme.footer", "layout.footerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
35467
- ]);
35468
- const simpleFooterLayout = stack({
35839
+ }, [media({ className: { $bind: {
35840
+ from: "$root.theme.footer.logo",
35841
+ transforms: [{
35842
+ id: "layout.footerLogoMediaClass",
35843
+ options: { base: "rb-h-10 rb-w-auto" }
35844
+ }],
35845
+ fallback: "rb-h-10 rb-w-auto"
35846
+ } } }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content.logo")), text({
35847
+ as: "strong",
35848
+ className: "footer-logo-text rb-nav-text"
35849
+ }, when("module.showTitle", { equals: true }), bind("site.title", { fallback: "Your Site" }))], when("module.kind", { equals: "brand" }));
35850
+ const navigation = stack({
35469
35851
  gap: "md",
35470
- align: "start",
35852
+ className: "rb-w-full"
35853
+ }, [footerNavGroupsLayout, footerNav({
35854
+ collectionPath: "footerMenu.items",
35855
+ mode: "links-only",
35471
35856
  className: { $bind: {
35472
- from: "$root.theme.footer",
35473
- transforms: [{ id: "layout.footerSimpleRootClass" }],
35474
- fallback: "rb-container rb-flex rb-w-full rb-flex-col rb-items-start rb-gap-4 rb-py-10 rb-text-left"
35475
- } }
35476
- }, [
35477
- simpleFooterLogo,
35478
- footerNav({
35479
- collectionPath: "footerMenu.items",
35480
- mode: "flatten",
35481
- className: { $bind: {
35482
- from: "$root.theme.footer.navLayout",
35483
- transforms: [{ id: "layout.footerSimpleNavClass" }],
35484
- fallback: "footer-nav rb-flex rb-flex-wrap rb-justify-start rb-gap-x-6 rb-gap-y-3"
35485
- } },
35486
- linkClassName: "footer-nav-link rb-inline-flex rb-items-center rb-px-4 rb-py-2 rb-nav-text transition-theme-standard"
35487
- }),
35488
- ...bodyTextLayout(),
35489
- ...businessAddressLayout(),
35490
- ...inlineBottomTextLayout()
35491
- ], when("$root.theme.footer.variant", { equals: "simple" }));
35492
- const columnsFooterLayout = stack({
35493
- gap: "xl",
35857
+ from: "module.navigationClassName",
35858
+ fallback: "footer-nav rb-flex rb-flex-wrap rb-gap-x-6 rb-gap-y-3"
35859
+ } },
35860
+ linkClassName: "footer-nav-link rb-nav-text transition-theme-standard"
35861
+ })], when("module.kind", { equals: "navigation" }));
35862
+ const legalNavigation = footerNav({
35863
+ collectionPath: "legalFooterMenu.items",
35864
+ mode: "links-only",
35865
+ className: "rb-flex rb-flex-wrap rb-gap-x-4 rb-gap-y-2",
35866
+ linkClassName: "footer-nav-link rb-caption transition-theme-standard"
35867
+ });
35868
+ const address = text({
35869
+ as: "address",
35870
+ className: "rb-not-italic rb-opacity-80"
35871
+ }, when("module.kind", { equals: "business-address" }), bind("module.address"));
35872
+ const contact = stack({
35873
+ gap: "sm",
35874
+ className: "rb-items-start"
35875
+ }, [link({
35876
+ href: { $bind: { from: "contactLink.href" } },
35877
+ className: "rb-nav-text rb-break-words transition-theme-standard"
35878
+ }, [text({ as: "span" }, bind("contactLink.label"))], repeat("module.contactLinks", "contactLink"))], when("module.kind", { equals: "contact" }));
35879
+ const hours = stack({
35880
+ gap: "sm",
35881
+ className: "rb-w-full"
35882
+ }, [inline({ className: "rb-flex rb-w-full rb-justify-between rb-gap-4" }, [text({
35883
+ as: "span",
35884
+ className: "rb-label"
35885
+ }, bind("hoursDay.weekday")), text({
35886
+ as: "span",
35887
+ className: "rb-caption rb-opacity-80"
35888
+ }, bind("hoursDay.hours"))], repeat("module.openingHours", "hoursDay")), text({
35889
+ as: "p",
35890
+ className: "rb-caption rb-opacity-70"
35891
+ }, bind("module.timeZone"), when("module.timeZone"))], when("module.kind", { equals: "opening-hours" }));
35892
+ const socials = inline({ className: "rb-flex rb-flex-wrap rb-gap-x-5 rb-gap-y-3" }, [link({
35893
+ href: { $bind: { from: "social.href" } },
35894
+ target: "_blank",
35895
+ rel: "noreferrer noopener",
35896
+ "aria-label": { $bind: { from: "social.label" } },
35897
+ className: "rb-nav-text transition-theme-standard"
35898
+ }, [icon({ className: "rb-h-5 rb-w-5" }, bind("social.icon"), when("social.icon")), text({ as: "span" }, bind("social.label"), when("social.icon", { equals: null }))], repeat("module.socialLinks", "social"))], when("module.kind", { equals: "social-links" }));
35899
+ const authoredCopy = richText({
35900
+ className: "rb-prose rb-prose-sm rb-max-w-none",
35901
+ style: textColorStyle("text/80")
35902
+ }, when("module.content"), bind("module.content", { transforms: [{
35903
+ id: "content.interpolateRichTextTokens",
35904
+ options: { tokens: ["year", "site_name"] }
35905
+ }] }));
35906
+ const footerModule = stack({
35907
+ gap: "md",
35494
35908
  align: "start",
35495
- className: { $bind: {
35496
- from: "$root.theme.footer.maxWidth",
35497
- transforms: [{
35498
- id: "layout.maxWidthClass",
35499
- options: { base: "rb-flex rb-w-full rb-flex-col rb-gap-10 rb-py-12" }
35500
- }],
35501
- fallback: "rb-container rb-flex rb-w-full rb-flex-col rb-gap-10 rb-py-12"
35502
- } }
35909
+ "data-preview-footer-module-id": { $bind: { from: "module.id" } }
35503
35910
  }, [
35504
- footerNavGroupsLayout,
35505
- inline({ className: "rb-flex rb-w-full rb-flex-wrap rb-items-center rb-justify-between rb-gap-4" }, [text({
35506
- as: "strong",
35507
- className: "rb-block rb-nav-text",
35508
- style: textColorStyle("text")
35509
- }, whenTransformed("$root.theme.footer", "layout.footerLogoTextVisible"), bind("site.title", { fallback: "Your Site" })), footerNav({
35510
- collectionPath: "footerMenu.items",
35511
- mode: "links-only",
35512
- className: "rb-flex rb-flex-wrap rb-justify-end rb-gap-x-6 rb-gap-y-3",
35513
- linkClassName: "footer-nav-link rb-inline-flex rb-items-center rb-px-4 rb-py-2 rb-nav-text transition-theme-standard"
35514
- })]),
35515
- ...bodyTextLayout(),
35516
- ...businessAddressLayout(),
35517
- ...inlineBottomTextLayout()
35518
- ], when("$root.theme.footer.variant", { equals: "columns" }));
35519
- const splitFooterLayout = stack({
35520
- gap: "xl",
35521
- align: "start",
35522
- className: { $bind: {
35523
- from: "$root.theme.footer.maxWidth",
35524
- transforms: [{
35525
- id: "layout.maxWidthClass",
35526
- options: { base: "rb-flex rb-w-full rb-flex-col rb-gap-10 rb-py-12" }
35527
- }],
35528
- fallback: "rb-container rb-flex rb-w-full rb-flex-col rb-gap-10 rb-py-12"
35529
- } }
35530
- }, [
35531
- inline({ className: { $bind: {
35532
- from: "$root.theme.footer.logo",
35533
- transforms: [{ id: "layout.footerSplitMainClass" }],
35534
- fallback: "rb-flex rb-w-full rb-flex-col rb-items-start rb-justify-between rb-gap-8 rb-md-flex-row rb-md-items-end"
35535
- } } }, [stack({}, [footerNav({
35536
- collectionPath: "footerMenu.items",
35537
- mode: "flatten",
35538
- className: { $bind: {
35539
- from: "$root.theme.footer.navLayout",
35540
- transforms: [{ id: "layout.footerSplitNavSingleClass" }],
35541
- fallback: "rb-w-full rb-space-y-3 rb-text-left"
35542
- } },
35543
- linkClassName: "footer-nav-link rb-inline-flex rb-items-center rb-whitespace-nowrap rb-nav-text transition-theme-standard"
35544
- })]), link({
35545
- href: "/",
35546
- className: { $bind: {
35547
- from: "$root.theme.footer.logo",
35548
- transforms: [{ id: "layout.footerLogoClass" }],
35549
- fallback: "footer-logo rb-inline-flex rb-items-center rb-justify-end rb-gap-3 rb-self-end rb-no-underline rb-text-right rb-transition-opacity rb-hover-opacity-80"
35550
- } }
35551
- }, [
35552
- media({ className: { $bind: {
35553
- from: "$root.theme.footer.logo",
35554
- transforms: [{ id: "layout.footerLogoMediaClass" }],
35555
- fallback: "rb-w-auto"
35556
- } } }, when("content.logo"), bind("content.logo")),
35557
- stack({ className: "rb-contents" }, [media({ className: { $bind: {
35558
- from: "$root.theme.footer.logo",
35559
- transforms: [{ id: "layout.footerLogoMediaClass" }],
35560
- fallback: "rb-w-auto"
35561
- } } }, when("site.logo"), bind("site.logo"))], when("content.logo", { not: true })),
35562
- text({
35563
- as: "strong",
35564
- className: "footer-logo-text rb-nav-text"
35565
- }, whenTransformed("$root.theme.footer", "layout.footerLogoTextVisible"), bind("site.title", { fallback: "Your Site" }))
35566
- ])]),
35567
- ...businessAddressLayout(),
35568
- ...inlineBottomTextLayout()
35569
- ], when("$root.theme.footer.variant", { equals: "split" }));
35570
- const footerLayout = section$1({
35571
- background: "background",
35911
+ text({
35912
+ as: "h2",
35913
+ className: "rb-label",
35914
+ style: textColorStyle("text/70")
35915
+ }, bind("module.heading"), when("module.heading")),
35916
+ brandLogo,
35917
+ navigation,
35918
+ stack({
35919
+ gap: "sm",
35920
+ className: "rb-w-full"
35921
+ }, [legalNavigation], when("module.kind", { equals: "legal-navigation" })),
35922
+ address,
35923
+ contact,
35924
+ hours,
35925
+ socials,
35926
+ stack({ className: "rb-w-full" }, [authoredCopy], when("module.kind", { equals: "supporting-text" })),
35927
+ stack({ className: "rb-w-full rb-lg-col-span-3" }, [authoredCopy], when("module.kind", { equals: "legal" }))
35928
+ ], repeat("group.modules", "module"));
35929
+ const footerGroup = stack({
35930
+ gap: "md",
35931
+ align: "stretch",
35932
+ className: "rb-min-w-0",
35933
+ "data-footer-group": { $bind: { from: "group.kind" } }
35934
+ }, [footerModule], repeat("region.groups", "group"));
35935
+ const footerMainRegion = stack({
35936
+ className: { $bind: { from: "region.className" } },
35937
+ "data-footer-region": { $bind: { from: "region.kind" } }
35938
+ }, [footerGroup], when("region.kind", { equals: "main" }), repeat("content.footerRuntime.regions", "region"));
35939
+ const footerBottomRegion = stack({ className: { $bind: {
35940
+ from: "$root.theme.footer",
35941
+ transforms: [{ id: "layout.footerBottomBarContainerClass" }],
35942
+ fallback: "rb-w-full"
35943
+ } } }, [stack({
35572
35944
  className: { $bind: {
35573
35945
  from: "$root.theme.footer",
35574
- transforms: [{ id: "layout.footerRootClass" }],
35575
- fallback: "rb-w-full rb-border-t transition-theme"
35946
+ transforms: [{ id: "layout.footerBottomBarClass" }],
35947
+ fallback: "rb-w-full rb-border-t rb-px-6 rb-py-6 rb-text-center"
35576
35948
  } },
35577
35949
  style: { $bind: {
35578
35950
  from: "$root.theme.footer",
35579
- transforms: [{ id: "layout.footerRootStyle" }],
35580
- fallback: mergeStyles(backgroundColorStyle("surface"), surfaceForegroundStyle({ text: "rgb(var(--tb-text))" }), borderColorStyle("border"))
35581
- } }
35582
- }, [
35583
- simpleFooterLayout,
35584
- columnsFooterLayout,
35585
- splitFooterLayout,
35586
- stack({
35587
- className: { $bind: {
35588
- from: "$root.theme.footer",
35589
- transforms: [{ id: "layout.footerBottomBarClass" }],
35590
- fallback: "rb-w-full rb-border-t rb-py-5"
35591
- } },
35592
- style: { $bind: {
35593
- from: "$root.theme.footer",
35594
- transforms: [{ id: "layout.footerBottomBarStyle" }]
35595
- } }
35596
- }, [stack({ className: { $bind: {
35597
- from: "$root.theme.footer",
35598
- transforms: [{ id: "layout.footerBottomBarContainerClass" }],
35599
- fallback: "rb-container"
35600
- } } }, [...bottomBarTextLayout()])], when("$root.theme.footer.bottomBar.enabled", { equals: true }))
35601
- ]);
35951
+ transforms: [{ id: "layout.footerBottomBarStyle" }]
35952
+ } },
35953
+ "data-footer-region": "bottom"
35954
+ }, [footerGroup])], when("region.kind", { equals: "bottom" }), repeat("content.footerRuntime.regions", "region"));
35602
35955
  const siteFooterBlockDefinition = { manifest: createBlockManifest({
35603
35956
  id: "block.site-footer",
35604
35957
  title: "Site Footer",
35605
35958
  category: "layout",
35606
- fragments: [{
35607
- fragment: footerBottomTextFragment,
35608
- fieldPriority: 0
35609
- }],
35610
35959
  skipSectionStyles: true,
35611
- additionalFields: [{
35612
- id: "showBusinessAddress",
35613
- type: "boolean",
35614
- label: "Add business address to site footer?",
35615
- required: false,
35616
- defaultValue: false,
35617
- ui: { intent: "content" }
35618
- }],
35619
- layout: footerLayout,
35620
- description: "Site-wide footer with navigation links and optional columns.",
35960
+ layout: section$1({
35961
+ background: "background",
35962
+ className: { $bind: {
35963
+ from: "$root.theme.footer",
35964
+ transforms: [{ id: "layout.footerRootClass" }],
35965
+ fallback: "rb-w-full rb-border-t transition-theme"
35966
+ } },
35967
+ style: { $bind: {
35968
+ from: "$root.theme.footer",
35969
+ transforms: [{ id: "layout.footerRootStyle" }],
35970
+ fallback: mergeStyles(backgroundColorStyle("surface"), surfaceForegroundStyle({ text: "rgb(var(--tb-text))" }), borderColorStyle("border"))
35971
+ } },
35972
+ "data-footer-membership": { $bind: { from: "content.footerRuntime.membershipKey" } }
35973
+ }, [footerMainRegion, footerBottomRegion]),
35974
+ description: "Site-wide composed footer with canonical shared details.",
35621
35975
  styleTokens: { spacing: "md" },
35622
35976
  paletteHidden: true
35623
35977
  }) };
@@ -36117,7 +36471,7 @@ const repeatedItemsNode = repeaterFragmentLayout({
36117
36471
  id: "boxStyles.all",
36118
36472
  options: {
36119
36473
  axis: "all",
36120
- baseClass: "rb-collection-item rb-relative rb-isolate rb-overflow-hidden rb-border"
36474
+ baseClass: "rb-collection-item rb-relative rb-isolate rb-overflow-visible rb-border"
36121
36475
  }
36122
36476
  }]
36123
36477
  },
@@ -51517,16 +51871,17 @@ const backgroundTransforms = [
51517
51871
  run: (value, _options, context) => resolveSurfaceForegroundStyles(value, context)
51518
51872
  },
51519
51873
  {
51520
- id: "background.resolveAllowOverflow",
51874
+ id: "background.resolveFrameClassName",
51521
51875
  kind: "formatter",
51522
- summary: "Resolve allowOverflow from background config (explicit overflow or scaled image)",
51523
- run: (value) => {
51524
- if (!value || typeof value !== "object") return false;
51876
+ summary: "Resolve clipping on a decorative background frame without clipping foreground content",
51877
+ run: (value, options) => {
51878
+ const baseClass = options?.baseClass?.trim() ?? "";
51879
+ if (!value || typeof value !== "object") return `${baseClass} rb-overflow-hidden`.trim();
51525
51880
  const input = value;
51526
- if (input.overflow === true) return true;
51881
+ if (input.overflow === true) return `${baseClass} rb-overflow-visible`.trim();
51527
51882
  const objectFit = isString$2(input.objectFit) ? input.objectFit.trim() : null;
51528
51883
  const scale = isString$2(input.scale) ? input.scale.trim() : isNumber$2(input.scale) ? String(input.scale) : null;
51529
- return Boolean((objectFit === "custom" || objectFit === "original") && scale && scale.trim().length > 0);
51884
+ return `${baseClass} ${Boolean((objectFit === "custom" || objectFit === "original") && scale && scale.trim().length > 0) ? "rb-overflow-visible" : "rb-overflow-hidden"}`.trim();
51530
51885
  }
51531
51886
  },
51532
51887
  {
@@ -51948,10 +52303,10 @@ function isRecord$37(value) {
51948
52303
  //#region ../blocks/src/primitives/layout/Section.tsx
51949
52304
  init_clsx();
51950
52305
  init_colorStyles();
51951
- const Section = forwardRef(function Section({ as: Comp = "section", children, background, className = "", allowOverflow = false, style, "data-slot": dataSlot }, ref) {
52306
+ const Section = forwardRef(function Section({ as: Comp = "section", children, background, className = "", style, "data-slot": dataSlot }, ref) {
51952
52307
  return /* @__PURE__ */ jsx(Comp, {
51953
52308
  ref,
51954
- className: clsx("rb-relative rb-isolate", allowOverflow ? "rb-overflow-visible" : "rb-overflow-hidden", className),
52309
+ className: clsx("rb-relative rb-isolate rb-overflow-visible", className),
51955
52310
  style: mergeStyles(typeof background === "string" && background.trim().length > 0 ? backgroundColorStyle(background.trim()) : void 0, style),
51956
52311
  "data-slot": dataSlot ?? "section",
51957
52312
  children
@@ -52075,10 +52430,7 @@ function Grid({ as: Comp = "div", cols = {
52075
52430
  }
52076
52431
  //#endregion
52077
52432
  //#region ../blocks/src/system/runtime/nodes/layout.tsx
52078
- const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, allowOverflow, ...props }) => /* @__PURE__ */ jsx(Section, {
52079
- ...props,
52080
- allowOverflow
52081
- });
52433
+ const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Section, { ...props });
52082
52434
  const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
52083
52435
  const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
52084
52436
  const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
@@ -52088,6 +52440,28 @@ const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _b
52088
52440
  //#region ../path-utils/src/index.ts
52089
52441
  const PATH_SEPARATOR_REGEX$1 = /\./g;
52090
52442
  const BRACKET_ACCESS_REGEX$1 = /\[([^\]]+)\]/g;
52443
+ /**
52444
+ * Segments that would traverse or mutate the prototype chain.
52445
+ *
52446
+ * `setAtPath` creates nested objects along the path, so allowing these
52447
+ * segments is a prototype-pollution vector. They are rejected everywhere a
52448
+ * path is parsed (string or pre-parsed array form) — fail closed.
52449
+ */
52450
+ const UNSAFE_PATH_SEGMENTS = /* @__PURE__ */ new Set([
52451
+ "__proto__",
52452
+ "constructor",
52453
+ "prototype"
52454
+ ]);
52455
+ var UnsafePathSegmentError = class extends Error {
52456
+ constructor(segment) {
52457
+ super(`Unsafe path segment: "${segment}"`);
52458
+ this.name = "UnsafePathSegmentError";
52459
+ this.segment = segment;
52460
+ }
52461
+ };
52462
+ function assertSafePathSegments(segments) {
52463
+ for (const segment of segments) if (typeof segment === "string" && UNSAFE_PATH_SEGMENTS.has(segment)) throw new UnsafePathSegmentError(segment);
52464
+ }
52091
52465
  function isRecord$36(value) {
52092
52466
  return typeof value === "object" && value !== null && !Array.isArray(value);
52093
52467
  }
@@ -52099,7 +52473,10 @@ function getContainerValue(container, segment) {
52099
52473
  if (segment in container) return Reflect.get(container, segment);
52100
52474
  }
52101
52475
  function parsePath(path) {
52102
- if (Array.isArray(path)) return path;
52476
+ if (Array.isArray(path)) {
52477
+ assertSafePathSegments(path);
52478
+ return path;
52479
+ }
52103
52480
  const segments = [];
52104
52481
  const parts = path.split(PATH_SEPARATOR_REGEX$1);
52105
52482
  for (const raw of parts) {
@@ -52119,6 +52496,7 @@ function parsePath(path) {
52119
52496
  }
52120
52497
  if (baseMatch === null && !raw.includes("[")) segments.push(raw);
52121
52498
  }
52499
+ assertSafePathSegments(segments);
52122
52500
  return segments;
52123
52501
  }
52124
52502
  function getAtPath(source, path) {
@@ -52370,6 +52748,59 @@ function getCtaIconComponent(name) {
52370
52748
  return CTA_ICON_COMPONENTS[name] ?? null;
52371
52749
  }
52372
52750
  //#endregion
52751
+ //#region ../blocks/src/system/icons/social.tsx
52752
+ init_svg();
52753
+ const SOCIAL_ICON_NAMES = [
52754
+ "SocialFacebook",
52755
+ "SocialInstagram",
52756
+ "SocialLinkedIn",
52757
+ "SocialTikTok",
52758
+ "SocialX",
52759
+ "SocialYouTube"
52760
+ ];
52761
+ const socialIcons = {
52762
+ SocialFacebook: createIcon("SocialFacebookIcon", /* @__PURE__ */ jsx("path", { d: "M14 8h3V4h-3c-3 0-5 2-5 5v3H6v4h3v6h4v-6h3l1-4h-4V9c0-.7.3-1 1-1Z" })),
52763
+ SocialInstagram: createIcon("SocialInstagramIcon", /* @__PURE__ */ jsxs(Fragment, { children: [
52764
+ /* @__PURE__ */ jsx("rect", {
52765
+ x: "3",
52766
+ y: "3",
52767
+ width: "18",
52768
+ height: "18",
52769
+ rx: "5"
52770
+ }),
52771
+ /* @__PURE__ */ jsx("circle", {
52772
+ cx: "12",
52773
+ cy: "12",
52774
+ r: "4"
52775
+ }),
52776
+ /* @__PURE__ */ jsx("circle", {
52777
+ cx: "17.5",
52778
+ cy: "6.5",
52779
+ r: ".75",
52780
+ fill: "currentColor",
52781
+ stroke: "none"
52782
+ })
52783
+ ] })),
52784
+ SocialLinkedIn: createIcon("SocialLinkedInIcon", /* @__PURE__ */ jsxs(Fragment, { children: [
52785
+ /* @__PURE__ */ jsx("path", { d: "M6 9v10" }),
52786
+ /* @__PURE__ */ jsx("path", {
52787
+ d: "M6 5.5v.01",
52788
+ strokeWidth: "3"
52789
+ }),
52790
+ /* @__PURE__ */ jsx("path", { d: "M10.5 19v-6a4 4 0 0 1 8 0v6" }),
52791
+ /* @__PURE__ */ jsx("path", { d: "M10.5 9v10" })
52792
+ ] })),
52793
+ SocialTikTok: createIcon("SocialTikTokIcon", /* @__PURE__ */ jsxs(Fragment, { 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" })] })),
52794
+ SocialX: createIcon("SocialXIcon", /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "m5 4 14 16" }), /* @__PURE__ */ jsx("path", { d: "M19 4 5 20" })] })),
52795
+ SocialYouTube: createIcon("SocialYouTubeIcon", /* @__PURE__ */ jsxs(Fragment, { 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" })] }))
52796
+ };
52797
+ function isSocialIconName(value) {
52798
+ return typeof value === "string" && SOCIAL_ICON_NAMES.includes(value);
52799
+ }
52800
+ function getSocialIconComponent(value) {
52801
+ return isSocialIconName(value) ? socialIcons[value] : null;
52802
+ }
52803
+ //#endregion
52373
52804
  //#region ../blocks/src/system/icons/registry.ts
52374
52805
  init_presets$1();
52375
52806
  function buildSearchText(parts) {
@@ -52400,7 +52831,7 @@ function semanticOptionsForPreset(preset) {
52400
52831
  }
52401
52832
  semanticOptionsForPreset("feature");
52402
52833
  function getIconComponent(name) {
52403
- return getCtaIconComponent(name) ?? getSemanticIconComponent(name);
52834
+ return getCtaIconComponent(name) ?? getSemanticIconComponent(name) ?? getSocialIconComponent(name);
52404
52835
  }
52405
52836
  //#endregion
52406
52837
  //#region ../blocks/src/system/runtime/nodes/buttonAffordance.ts
@@ -53219,7 +53650,6 @@ const HeaderSectionNode = ({ blockId, children, className, "data-preview-site-ch
53219
53650
  const asProp = rest.as;
53220
53651
  const styleProp = rest.style;
53221
53652
  const backgroundProp = typeof rest.background === "string" ? rest.background : void 0;
53222
- const allowOverflowProp = typeof rest.allowOverflow === "boolean" ? rest.allowOverflow : void 0;
53223
53653
  const dataSlotProp = typeof rest["data-slot"] === "string" ? rest["data-slot"] : void 0;
53224
53654
  return /* @__PURE__ */ jsxs("nav", {
53225
53655
  ...getIslandRootProps("headerSection", blockId),
@@ -53234,7 +53664,6 @@ const HeaderSectionNode = ({ blockId, children, className, "data-preview-site-ch
53234
53664
  as: asProp,
53235
53665
  style: styleProp,
53236
53666
  background: backgroundProp ?? "background",
53237
- allowOverflow: allowOverflowProp,
53238
53667
  "data-slot": dataSlotProp,
53239
53668
  className: sectionClasses || void 0,
53240
53669
  children
@@ -58506,7 +58935,7 @@ function resolveGroupFrame(cardStyles) {
58506
58935
  contentClassName: "offerings-preview-card-content rb-flex rb-h-full rb-min-h-full rb-flex-col rb-gap-5"
58507
58936
  };
58508
58937
  return {
58509
- 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(" "),
58938
+ 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(" "),
58510
58939
  containerStyle: resolveGroupFrameStyle(cardStyles),
58511
58940
  contentClassName: "card-content offerings-preview-card-content rb-flex rb-h-full rb-min-h-full rb-flex-col rb-gap-5"
58512
58941
  };
@@ -61582,9 +62011,9 @@ function isReactNode(value) {
61582
62011
  * Handles conditionals ($when), scopes ($scopes), repeaters ($repeat), bindings ($bind), and children.
61583
62012
  */
61584
62013
  function resolveNode(node, context, indexFallback) {
61585
- if (!shouldRenderNode(node, context)) return null;
61586
62014
  const scopeContext = applyScopes(node, context);
61587
62015
  if (node.$repeat) return resolveRepeater(node, scopeContext);
62016
+ if (!shouldRenderNode(node, scopeContext)) return null;
61588
62017
  const registry = scopeContext.registry ?? serverComponentRegistry;
61589
62018
  const normalizedType = node.type.toLowerCase();
61590
62019
  const component = registry[node.type] ?? registry[normalizedType] ?? (normalizedType === "section" ? SectionNode : void 0);
@@ -64149,108 +64578,6 @@ function getCmsApiUrl$1() {
64149
64578
  function resolveApiBaseUrl() {
64150
64579
  return getCmsApiUrl$1();
64151
64580
  }
64152
- const API_ERROR_CODE_SET = /* @__PURE__ */ new Set([
64153
- "auth:unauthenticated",
64154
- "auth:token_expired",
64155
- "auth:token_invalid",
64156
- "auth:forbidden",
64157
- "auth:mfa_required",
64158
- "auth:sudo_required",
64159
- "auth:insufficient_permissions",
64160
- "auth:impersonation_restricted",
64161
- "validation:invalid_input",
64162
- "validation:missing_field",
64163
- "validation:invalid_format",
64164
- "validation:payload_too_large",
64165
- "resource:not_found",
64166
- "resource:already_exists",
64167
- "resource:conflict",
64168
- "resource:gone",
64169
- "rate_limit:exceeded",
64170
- "billing:payment_required",
64171
- "billing:plan_limit_exceeded",
64172
- "billing:pass_redemption_failed",
64173
- "server:internal_error",
64174
- "server:unavailable",
64175
- "external:service_error",
64176
- "external:registrar_orphaned_contact_profile",
64177
- "network:connection_error",
64178
- "network:timeout",
64179
- "network:dns_error"
64180
- ]);
64181
- function isApiErrorCode(value) {
64182
- return typeof value === "string" && API_ERROR_CODE_SET.has(value);
64183
- }
64184
- function isApiError(result) {
64185
- return result.success === false;
64186
- }
64187
- function isApiSuccess(result) {
64188
- return result.success === true;
64189
- }
64190
- function isRecord$28(value) {
64191
- return typeof value === "object" && value !== null && !Array.isArray(value);
64192
- }
64193
- function isFieldError$1(value) {
64194
- return isRecord$28(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
64195
- }
64196
- function fieldErrorsFromUnknown(value) {
64197
- if (!Array.isArray(value)) return null;
64198
- return value.every(isFieldError$1) ? value : null;
64199
- }
64200
- function extractEnvelopeErrorObject(body) {
64201
- if (!isRecord$28(body)) return null;
64202
- const error = body.error;
64203
- if (!isRecord$28(error)) return null;
64204
- if ("success" in body && body.success !== false) return null;
64205
- return error;
64206
- }
64207
- function extractApiEnvelopeErrorDetails(body) {
64208
- const error = extractEnvelopeErrorObject(body);
64209
- if (!error) return {
64210
- rawCode: null,
64211
- code: null,
64212
- message: null,
64213
- status: null,
64214
- fieldErrors: null
64215
- };
64216
- const rawCode = typeof error.code === "string" ? error.code : null;
64217
- const message = typeof error.message === "string" && error.message.trim().length > 0 ? error.message : null;
64218
- return {
64219
- rawCode,
64220
- code: isApiErrorCode(rawCode) ? rawCode : null,
64221
- message,
64222
- status: typeof error.status === "number" && Number.isFinite(error.status) ? error.status : null,
64223
- fieldErrors: fieldErrorsFromUnknown(error.fieldErrors)
64224
- };
64225
- }
64226
- /**
64227
- * Error class for API failures that can be thrown from unwrapResponse.
64228
- * Preserves all error metadata from the envelope.
64229
- */
64230
- var ApiEnvelopeError = class extends Error {
64231
- constructor(error) {
64232
- super(error.message);
64233
- this.name = "ApiEnvelopeError";
64234
- this.code = error.code;
64235
- this.requestId = error.requestId;
64236
- this.timestamp = error.timestamp;
64237
- this.status = error.status;
64238
- this.fieldErrors = error.fieldErrors;
64239
- }
64240
- };
64241
- /**
64242
- * Unwrap a successful API response or throw on error.
64243
- *
64244
- * @example
64245
- * ```typescript
64246
- * const response = await apiClient({ endpoint: 'getUser', params: { id } });
64247
- * const user = unwrapResponse(response); // Throws if not success
64248
- * ```
64249
- */
64250
- function unwrapResponse(result) {
64251
- if (isApiSuccess(result)) return result.data;
64252
- throw new ApiEnvelopeError(result.error);
64253
- }
64254
64581
  //#endregion
64255
64582
  //#region ../api/src/request.ts
64256
64583
  let revalidateTag = null;
@@ -64851,7 +65178,7 @@ function preset(id, verticalId, canonicalBehaviour, label, pluralLabel, descript
64851
65178
  init_src$4();
64852
65179
  //#endregion
64853
65180
  //#region ../api/src/utils/isRecord.ts
64854
- function isRecord$26(value) {
65181
+ function isRecord$27(value) {
64855
65182
  return typeof value === "object" && value !== null && !Array.isArray(value);
64856
65183
  }
64857
65184
  //#endregion
@@ -65097,7 +65424,7 @@ function sanitizeMarks(marks) {
65097
65424
  if (!Array.isArray(marks) || marks.length === 0) return;
65098
65425
  const sanitized = marks.flatMap((mark) => {
65099
65426
  if (mark.type === "bold" || mark.type === "strong" || mark.type === "italic" || mark.type === "em") return [{ type: mark.type }];
65100
- if (mark.type === "link" && isRecord$26(mark.attrs) && typeof mark.attrs.href === "string") {
65427
+ if (mark.type === "link" && isRecord$27(mark.attrs) && typeof mark.attrs.href === "string") {
65101
65428
  const attrs = { href: mark.attrs.href };
65102
65429
  if (typeof mark.attrs.target === "string" && mark.attrs.target.trim().length > 0) attrs.target = mark.attrs.target;
65103
65430
  if (typeof mark.attrs.rel === "string" && mark.attrs.rel.trim().length > 0) attrs.rel = mark.attrs.rel;
@@ -65111,24 +65438,24 @@ function sanitizeMarks(marks) {
65111
65438
  return sanitized.length > 0 ? sanitized : void 0;
65112
65439
  }
65113
65440
  function unwrapRichTextValue(value) {
65114
- if (isRecord$26(value) && isRecord$26(value.doc)) return unwrapRichTextValue(value.doc);
65115
- if (isRecord$26(value) && value.type === "doc") return {
65441
+ if (isRecord$27(value) && isRecord$27(value.doc)) return unwrapRichTextValue(value.doc);
65442
+ if (isRecord$27(value) && value.type === "doc") return {
65116
65443
  type: "doc",
65117
65444
  content: Array.isArray(value.content) ? value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) : []
65118
65445
  };
65119
65446
  return EMPTY_SITE_BANNER_BODY;
65120
65447
  }
65121
65448
  function isTipTapNodeLike(value) {
65122
- return isRecord$26(value) && typeof value.type === "string";
65449
+ return isRecord$27(value) && typeof value.type === "string";
65123
65450
  }
65124
65451
  function coerceTipTapNode(value) {
65125
65452
  return {
65126
65453
  type: value.type,
65127
65454
  ...Array.isArray(value.content) ? { content: value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) } : {},
65128
65455
  ...typeof value.text === "string" ? { text: value.text } : {},
65129
- ...Array.isArray(value.marks) ? { marks: value.marks.filter((mark) => isRecord$26(mark) && typeof mark.type === "string").map((mark) => ({
65456
+ ...Array.isArray(value.marks) ? { marks: value.marks.filter((mark) => isRecord$27(mark) && typeof mark.type === "string").map((mark) => ({
65130
65457
  type: mark.type,
65131
- ...isRecord$26(mark.attrs) ? { attrs: mark.attrs } : {}
65458
+ ...isRecord$27(mark.attrs) ? { attrs: mark.attrs } : {}
65132
65459
  })) } : {}
65133
65460
  };
65134
65461
  }
@@ -65144,7 +65471,7 @@ function collectText(node) {
65144
65471
  }
65145
65472
  function stableSerialize(value) {
65146
65473
  if (Array.isArray(value)) return `[${value.map(stableSerialize).join(",")}]`;
65147
- if (isRecord$26(value)) return `{${Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, entryValue]) => `${JSON.stringify(key)}:${stableSerialize(entryValue)}`).join(",")}}`;
65474
+ if (isRecord$27(value)) return `{${Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, entryValue]) => `${JSON.stringify(key)}:${stableSerialize(entryValue)}`).join(",")}}`;
65148
65475
  return JSON.stringify(value);
65149
65476
  }
65150
65477
  function encodePublicProductCategorySelector$1(selector) {
@@ -65234,7 +65561,7 @@ function collectCartLinkStats(items, depth = 0) {
65234
65561
  return result;
65235
65562
  }
65236
65563
  function isNavigationMenuValidationItem(value) {
65237
- if (!isRecord$26(value)) return false;
65564
+ if (!isRecord$27(value)) return false;
65238
65565
  return typeof value.label === "string";
65239
65566
  }
65240
65567
  //#endregion
@@ -65252,7 +65579,7 @@ function normalizeIdList(value) {
65252
65579
  return result.length > 0 ? result : null;
65253
65580
  }
65254
65581
  function extractNavVisibilityConfig(raw) {
65255
- if (!isRecord$26(raw)) return null;
65582
+ if (!isRecord$27(raw)) return null;
65256
65583
  const modeRaw = raw.mode;
65257
65584
  const mode = modeRaw === "augment" || modeRaw === "restrict" ? modeRaw : null;
65258
65585
  const allowIds = normalizeIdList(raw.allowIds);
@@ -65265,7 +65592,7 @@ function extractNavVisibilityConfig(raw) {
65265
65592
  };
65266
65593
  }
65267
65594
  function asRecord$1(value) {
65268
- return isRecord$26(value) ? value : null;
65595
+ return isRecord$27(value) ? value : null;
65269
65596
  }
65270
65597
  /**
65271
65598
  * Check if a raw config object has any nav visibility values defined.
@@ -67157,11 +67484,11 @@ function getTransformIO(name) {
67157
67484
  function resolveMetaPathType(path) {
67158
67485
  return resolveMetaFieldType(path);
67159
67486
  }
67160
- function isRecord$24(value) {
67487
+ function isRecord$25(value) {
67161
67488
  return typeof value === "object" && value !== null && !Array.isArray(value);
67162
67489
  }
67163
67490
  function isBindingDescriptor(value) {
67164
- if (!isRecord$24(value)) return false;
67491
+ if (!isRecord$25(value)) return false;
67165
67492
  const source = value.source;
67166
67493
  return source === "field" || source === "meta" || source === "literal" || source === "transform" || source === "fallback";
67167
67494
  }
@@ -67314,7 +67641,7 @@ function validateBinding$1(binding, context) {
67314
67641
  const mismatch = checkDirectCompatibility(resolved, context, false);
67315
67642
  return mismatch ? [mismatch] : [];
67316
67643
  }
67317
- if (!isRecord$24(binding)) return [{
67644
+ if (!isRecord$25(binding)) return [{
67318
67645
  kind: "typeIncompatible",
67319
67646
  blockIdentifier: context.blockIdentifier,
67320
67647
  fieldKey: context.fieldKey,
@@ -67737,8 +68064,14 @@ const navigationMenuConfigSchema = z$1.object({
67737
68064
  name: z$1.string().min(1, "Name is required"),
67738
68065
  isPrimary: z$1.boolean().optional(),
67739
68066
  isFooter: z$1.boolean().optional(),
68067
+ footerRole: z$1.enum(["main", "legal-policy"]).nullable().optional(),
67740
68068
  items: z$1.array(navigationItemConfigSchema)
67741
68069
  }).superRefine((menu, ctx) => {
68070
+ if (menu.footerRole !== void 0 && menu.isFooter !== void 0 && menu.isFooter !== (menu.footerRole === "main")) ctx.addIssue({
68071
+ code: "custom",
68072
+ message: "footerRole and isFooter disagree",
68073
+ path: ["footerRole"]
68074
+ });
67742
68075
  const portalStats = collectPortalLinkStats(menu.items);
67743
68076
  if (portalStats.count > 1) ctx.addIssue({
67744
68077
  code: z$1.ZodIssueCode.custom,
@@ -68555,21 +68888,21 @@ var ManagementApiError = class extends Error {
68555
68888
  function is404Error(error) {
68556
68889
  return error instanceof ManagementApiError && error.statusCode === 404;
68557
68890
  }
68558
- function isRecord$21(value) {
68891
+ function isRecord$22(value) {
68559
68892
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
68560
68893
  }
68561
68894
  function isFieldError(value) {
68562
- return isRecord$21(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
68895
+ return isRecord$22(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
68563
68896
  }
68564
68897
  function parseApiResponse(value) {
68565
- if (!isRecord$21(value)) return null;
68898
+ if (!isRecord$22(value)) return null;
68566
68899
  if (value.success === true) return {
68567
68900
  success: true,
68568
68901
  data: value.data
68569
68902
  };
68570
68903
  if (value.success === false) {
68571
68904
  const error = value.error;
68572
- if (!isRecord$21(error) || typeof error.code !== "string" || typeof error.message !== "string") return {
68905
+ if (!isRecord$22(error) || typeof error.code !== "string" || typeof error.message !== "string") return {
68573
68906
  success: false,
68574
68907
  error: {
68575
68908
  code: "sdk:http-error",
@@ -68816,6 +69149,32 @@ function createPageOperations(http) {
68816
69149
  /**
68817
69150
  * Block Operations for Management Client
68818
69151
  */
69152
+ /**
69153
+ * Discriminated stale-conflict error for `blocks.patch`: the block's draft
69154
+ * changed since the caller's read. `currentHash` is the server's current
69155
+ * draft content hash — retry the patch with it as `baseContentHash`.
69156
+ * Extracted from the typed `SdkPatchPageBlockStaleContentFieldError` wire
69157
+ * contract, so callers never parse prose.
69158
+ */
69159
+ var BlockPatchStaleContentError = class extends ManagementApiError {
69160
+ constructor(source, currentHash) {
69161
+ super(source.message, source.code, source.details, source.statusCode, source.request);
69162
+ this.kind = "stale-content";
69163
+ this.name = "BlockPatchStaleContentError";
69164
+ this.currentHash = currentHash;
69165
+ }
69166
+ };
69167
+ function isRecord$21(value) {
69168
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
69169
+ }
69170
+ function extractStaleContentCurrentHash(error) {
69171
+ if (error.statusCode !== 409) return null;
69172
+ if (!isRecord$21(error.details)) return null;
69173
+ const fieldErrors = error.details.fieldErrors;
69174
+ if (!Array.isArray(fieldErrors)) return null;
69175
+ for (const fieldError of fieldErrors) if (isRecord$21(fieldError) && fieldError.field === "baseContentHash" && fieldError.code === "STALE_CONTENT" && typeof fieldError.message === "string") return fieldError.message;
69176
+ return null;
69177
+ }
68819
69178
  function mapPulledBlock(block) {
68820
69179
  return {
68821
69180
  id: block.id,
@@ -68844,6 +69203,17 @@ function createBlockOperations(http) {
68844
69203
  async upsert(pageIdentifier, input) {
68845
69204
  return (await http.post(`/pages/${encodeURIComponent(pageIdentifier)}/blocks`, input)).block;
68846
69205
  },
69206
+ async patch(pageIdentifier, blockIdentifier, input) {
69207
+ try {
69208
+ return (await http.patch(`/pages/${encodeURIComponent(pageIdentifier)}/blocks/${encodeURIComponent(blockIdentifier)}`, input)).block;
69209
+ } catch (error) {
69210
+ if (error instanceof ManagementApiError) {
69211
+ const currentHash = extractStaleContentCurrentHash(error);
69212
+ if (currentHash !== null) throw new BlockPatchStaleContentError(error, currentHash);
69213
+ }
69214
+ throw error;
69215
+ }
69216
+ },
68847
69217
  async reorder(pageIdentifier, blockIdentifiers) {
68848
69218
  await http.post(`/pages/${encodeURIComponent(pageIdentifier)}/blocks/reorder`, { identifiers: blockIdentifiers });
68849
69219
  },
@@ -68873,6 +69243,7 @@ function mapPulledNavigationMenu(menu) {
68873
69243
  name: menu.name,
68874
69244
  isPrimary: menu.isPrimary,
68875
69245
  isFooter: menu.isFooter,
69246
+ footerRole: menu.footerRole,
68876
69247
  items: menu.items.map(mapPulledNavigationItem),
68877
69248
  createdAt: menu.createdAt,
68878
69249
  updatedAt: menu.updatedAt
@@ -70659,6 +71030,7 @@ function convertPulledNavigationToLocal(remoteMenus) {
70659
71030
  };
70660
71031
  if (menu.isPrimary) localMenu.isPrimary = true;
70661
71032
  if (menu.isFooter) localMenu.isFooter = true;
71033
+ if (menu.footerRole !== null) localMenu.footerRole = menu.footerRole;
70662
71034
  return localMenu;
70663
71035
  }) };
70664
71036
  }
@@ -74546,6 +74918,7 @@ function calculateNavigationDiffs(localNavigation, remoteNavigation) {
74546
74918
  if (!equal(localMenu.items, stripNavigationItemIds(remoteMenu.items))) changes.push("items");
74547
74919
  if (localMenu.isPrimary !== void 0 && localMenu.isPrimary !== (remoteMenu.isPrimary ?? false)) changes.push("isPrimary");
74548
74920
  if (localMenu.isFooter !== void 0 && localMenu.isFooter !== (remoteMenu.isFooter ?? false)) changes.push("isFooter");
74921
+ if (localMenu.footerRole !== void 0 && localMenu.footerRole !== remoteMenu.footerRole) changes.push("footerRole");
74549
74922
  if (changes.length > 0) {
74550
74923
  diffs.push({
74551
74924
  type: "update",
@@ -74954,6 +75327,7 @@ function calculatePullDiff(remote, local) {
74954
75327
  if (!equal(stripNavigationItemIds(remoteMenu.items), localMenu.items)) changes.push("items");
74955
75328
  if ((localMenu.isPrimary ?? false) !== (remoteMenu.isPrimary ?? false)) changes.push("isPrimary");
74956
75329
  if ((localMenu.isFooter ?? false) !== (remoteMenu.isFooter ?? false)) changes.push("isFooter");
75330
+ if ((localMenu.footerRole ?? null) !== (remoteMenu.footerRole ?? null)) changes.push("footerRole");
74957
75331
  if (changes.length > 0) {
74958
75332
  navDiffs.push({
74959
75333
  type: "update",
@@ -78637,7 +79011,11 @@ const navigationLocations = [
78637
79011
  "header",
78638
79012
  "footer"
78639
79013
  ];
78640
- const navigationMenuRoles = ["primary", "footer"];
79014
+ const navigationMenuRoles = [
79015
+ "primary",
79016
+ "footer",
79017
+ "legal-policy"
79018
+ ];
78641
79019
  const offeringArchetypes = [
78642
79020
  "class",
78643
79021
  "workshop",
@@ -83141,7 +83519,8 @@ async function executeNavigationCommandPlan(input) {
83141
83519
  name: navigationCommandMenuName$1(command),
83142
83520
  items: command.input.items.map(navigationItemInput$1),
83143
83521
  ...role === "primary" ? { isPrimary: true } : {},
83144
- ...role === "footer" ? { isFooter: true } : {}
83522
+ ...role === "footer" ? { isFooter: true } : {},
83523
+ ...role === "legal-policy" ? { footerRole: "legal-policy" } : {}
83145
83524
  });
83146
83525
  return;
83147
83526
  }
@@ -83192,7 +83571,9 @@ function navigationCommandReportToSyncResult(report) {
83192
83571
  }
83193
83572
  function navigationRole(menu) {
83194
83573
  if (menu.isPrimary) return "primary";
83574
+ if (menu.footerRole === "legal-policy") return "legal-policy";
83195
83575
  if (menu.isFooter) return "footer";
83576
+ if (menu.footerRole === "main") return "footer";
83196
83577
  }
83197
83578
  function navigationItemForCommand$1(item) {
83198
83579
  return normalizeNavigationConfigItemForCommand(item);
@@ -88356,7 +88737,8 @@ async function applyOneOffNavigationCommand(command, client) {
88356
88737
  name: navigationCommandMenuName(command),
88357
88738
  items: command.input.items.map(navigationItemInput),
88358
88739
  ...role === "primary" ? { isPrimary: true } : {},
88359
- ...role === "footer" ? { isFooter: true } : {}
88740
+ ...role === "footer" ? { isFooter: true } : {},
88741
+ ...role === "legal-policy" ? { footerRole: "legal-policy" } : {}
88360
88742
  });
88361
88743
  }
88362
88744
  function oneOffEntryCommandBinding(mutation) {
@@ -89309,7 +89691,7 @@ const deleteCommand$3 = new Command("delete").description("Delete a navigation m
89309
89691
  const { client, isRemote, output, targetEnv } = ctx;
89310
89692
  const menu = resolveNavigationMenuForDelete(await client.navigation.list(), selector);
89311
89693
  const itemCount = countItems(menu.items);
89312
- const flags = [menu.isPrimary ? "primary" : null, menu.isFooter ? "footer" : null].filter((flag) => Boolean(flag));
89694
+ const flags = [menu.isPrimary ? "primary" : null, menu.footerRole === "legal-policy" ? "legal & policy footer" : menu.footerRole === "main" || menu.isFooter ? "main footer" : null].filter((flag) => Boolean(flag));
89313
89695
  const flagText = flags.length > 0 ? flags.join(", ") : "none";
89314
89696
  if (!await confirmAction(`Delete navigation menu "${menu.name}" (${menu.id}) from ${targetEnv}? flags: ${flagText}; items: ${itemCount}`, options, isRemote)) {
89315
89697
  output.info("Operation cancelled");
@@ -89323,6 +89705,7 @@ const deleteCommand$3 = new Command("delete").description("Delete a navigation m
89323
89705
  identifier: menu.identifier,
89324
89706
  isPrimary: menu.isPrimary,
89325
89707
  isFooter: menu.isFooter,
89708
+ footerRole: menu.footerRole,
89326
89709
  itemCount,
89327
89710
  environment: targetEnv
89328
89711
  });
@@ -154175,6 +154558,9 @@ init_src$4();
154175
154558
  //#region src/rendering/islands/BlocksIslandsHydrator.tsx
154176
154559
  init_media();
154177
154560
  //#endregion
154561
+ //#region ../blocks/src/system/blocks/site-footer-runtime.ts
154562
+ init_src$4();
154563
+ //#endregion
154178
154564
  //#region ../blocks/src/rendering/server.ts
154179
154565
  init_schema$1();
154180
154566
  //#endregion
@@ -154309,7 +154695,7 @@ var SimpleCache = class {
154309
154695
  * 1. This constant
154310
154696
  * 2. The "version" field in package.json
154311
154697
  */
154312
- const SDK_VERSION = "0.107.0";
154698
+ const SDK_VERSION = "0.108.0";
154313
154699
  //#endregion
154314
154700
  //#region src/client/error.ts
154315
154701
  /**