@riverbankcms/sdk 0.153.0 → 0.154.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 (216) hide show
  1. package/dist/{EventEmbeddedCheckoutStep-veN-QiAE.mjs → EventEmbeddedCheckoutStep-ba9npQtb.mjs} +1 -1
  2. package/dist/{PreviewEditorSidebar-jI_4DTZY.mjs → PreviewEditorSidebar-C7FiaxlF.mjs} +194 -22
  3. package/dist/{PreviewEditorUI-ORkVZhfu.mjs → PreviewEditorUI-DFst50q1.mjs} +20 -44
  4. package/dist/{SdkPreviewModeRuntime-DaNqevI1.mjs → SdkPreviewModeRuntime-BUNV_YHZ.mjs} +49 -32
  5. package/dist/{SiteChromeCustomizeContext-CgNuBHC0.mjs → SiteChromeCustomizeContext-DEj7qppF.mjs} +3558 -2321
  6. package/dist/{ThemedButton-X2UxhW6F.mjs → ThemedButton-C8kzu0hY.mjs} +400 -81
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +364 -130
  8. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +1035 -477
  9. package/dist/_dts/api/src/billing.d.ts +2 -0
  10. package/dist/_dts/api/src/billingEndpointDefinitions.d.ts +78 -0
  11. package/dist/_dts/api/src/bookingAdjustments.d.ts +3 -2
  12. package/dist/_dts/api/src/bookingOperations.d.ts +7 -2
  13. package/dist/_dts/api/src/bookingPeople.d.ts +19 -0
  14. package/dist/_dts/api/src/bookingPeopleEndpointDefinitions.d.ts +8 -0
  15. package/dist/_dts/api/src/bookingRecords.d.ts +4 -106
  16. package/dist/_dts/api/src/bookings.d.ts +2 -3
  17. package/dist/_dts/api/src/contentRuntime.d.ts +1 -0
  18. package/dist/_dts/api/src/endpoints.d.ts +88 -43
  19. package/dist/_dts/api/src/index.d.ts +4 -2
  20. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -0
  21. package/dist/_dts/api/src/moneyPayments.d.ts +116 -0
  22. package/dist/_dts/api/src/onboarding/surfaceData.d.ts +2 -0
  23. package/dist/_dts/api/src/sdk-event-upsert.d.ts +2 -2
  24. package/dist/_dts/api/src/sdkThemeWire.d.ts +162 -103
  25. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +18 -0
  26. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +17 -16
  27. package/dist/_dts/api/src/siteSettings.d.ts +1 -0
  28. package/dist/_dts/api/src/stripeConnectSetup.d.ts +90 -0
  29. package/dist/_dts/api/src/types.d.ts +11 -31
  30. package/dist/_dts/api/src/wholeSeriesRuns.d.ts +2 -4
  31. package/dist/_dts/blocks/src/client/site-chrome.d.ts +1 -1
  32. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +8 -96
  33. package/dist/_dts/blocks/src/primitives/content/components/RichText.d.ts +1 -1
  34. package/dist/_dts/blocks/src/primitives/content/primitives.d.ts +4 -1
  35. package/dist/_dts/blocks/src/primitives/layout/Section.d.ts +1 -0
  36. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +1 -1
  37. package/dist/_dts/blocks/src/system/blocks/events/eventSelectionFields.d.ts +1 -1
  38. package/dist/_dts/blocks/src/system/blocks/events/shared/fields.d.ts +0 -4
  39. package/dist/_dts/blocks/src/system/blocks/events/shared/index.d.ts +0 -1
  40. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +4 -4
  41. package/dist/_dts/blocks/src/system/blocks/form.d.ts +10 -0
  42. package/dist/_dts/blocks/src/system/blocks/image-gallery/fields.d.ts +1 -0
  43. package/dist/_dts/blocks/src/system/blocks/image-gallery.d.ts +6 -1
  44. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +1 -1
  45. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +47 -45
  46. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +12 -0
  47. package/dist/_dts/blocks/src/system/blocks/site-footer-runtime-layout.d.ts +23 -0
  48. package/dist/_dts/blocks/src/system/blocks/site-footer-runtime-profile.d.ts +20 -0
  49. package/dist/_dts/blocks/src/system/blocks/site-footer-runtime.d.ts +17 -16
  50. package/dist/_dts/blocks/src/system/blocks/site-footer.d.ts +1 -1
  51. package/dist/_dts/blocks/src/system/customize/facets.d.ts +75 -9
  52. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +24 -24
  53. package/dist/_dts/blocks/src/system/node/fragments/index.d.ts +1 -0
  54. package/dist/_dts/blocks/src/system/node/fragments/lookSlot.d.ts +1 -1
  55. package/dist/_dts/blocks/src/system/node/fragments/responsiveTwoColumn.d.ts +3 -1
  56. package/dist/_dts/blocks/src/system/node/fragments/sectionHead.d.ts +15 -0
  57. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +18 -198
  58. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +9 -99
  59. package/dist/_dts/blocks/src/system/runtime/lookSurfaces.d.ts +16 -4
  60. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +2 -1
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/lookPresentation.d.ts +10 -4
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/presentation.d.ts +1 -1
  63. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/dates.d.ts +1 -1
  64. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +29 -17
  65. package/dist/_dts/blocks/src/system/runtime/nodes/form.fields.d.ts +5 -2
  66. package/dist/_dts/blocks/src/system/runtime/nodes/form.interactive.d.ts +11 -79
  67. package/dist/_dts/blocks/src/system/runtime/nodes/form.parts.d.ts +7 -0
  68. package/dist/_dts/blocks/src/system/runtime/nodes/form.server.d.ts +2 -13
  69. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +8 -72
  70. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.parts.d.ts +6 -6
  71. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +3 -2
  72. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +2 -2
  73. package/dist/_dts/blocks/src/system/transforms/registry/_utils/surfaceForegroundStyles.d.ts +3 -0
  74. package/dist/_dts/blocks/src/system/transforms/registry/footerArrangement.d.ts +6 -0
  75. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +0 -11
  76. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +1 -10
  77. package/dist/_dts/commerce/src/purchase/orderConfirmationPlanning.d.ts +1 -0
  78. package/dist/_dts/content-editor/src/FooterComposerOverview.d.ts +5 -2
  79. package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +1 -1
  80. package/dist/_dts/content-editor/src/FooterNavigationLayoutControl.d.ts +6 -3
  81. package/dist/_dts/content-editor/src/controller/editorLeaseParticipation.d.ts +1 -1
  82. package/dist/_dts/content-editor/src/footerComposer.d.ts +2 -1
  83. package/dist/_dts/content-editor/src/footerComposerPanelTypes.d.ts +3 -1
  84. package/dist/_dts/content-editor/src/footerNavigationLayoutState.d.ts +56 -0
  85. package/dist/_dts/content-editor/src/footerPreviewRuntime.d.ts +2 -1
  86. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +3 -4
  87. package/dist/_dts/content-editor/src/useFooterNavigationLayout.d.ts +11 -8
  88. package/dist/_dts/core/src/booking-refunds.d.ts +2 -0
  89. package/dist/_dts/core/src/date-display.d.ts +85 -0
  90. package/dist/_dts/core/src/date-time-formatter.d.ts +2 -0
  91. package/dist/_dts/core/src/footer-arrangement.d.ts +8 -1
  92. package/dist/_dts/core/src/footer-composition-types.d.ts +6 -1
  93. package/dist/_dts/core/src/footer-composition.d.ts +1 -1
  94. package/dist/_dts/core/src/footer-navigation-layout.d.ts +3 -0
  95. package/dist/_dts/core/src/index.d.ts +2 -0
  96. package/dist/_dts/core/src/mailing-list-setup.d.ts +3 -0
  97. package/dist/_dts/core/src/mailing-list-submission.d.ts +6 -1
  98. package/dist/_dts/core/src/public-profile.d.ts +3 -1
  99. package/dist/_dts/core/src/scheduled-date-time.d.ts +69 -0
  100. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +50 -9
  101. package/dist/_dts/db/src/schemas/forms.d.ts +16 -16
  102. package/dist/_dts/preview-next/src/client/blocks/ArrangementBlockToolbar.d.ts +2 -1
  103. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +1 -0
  104. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +1 -0
  105. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +4 -1
  106. package/dist/_dts/preview-next/src/client/preview/siteChromeSavePlan.d.ts +27 -5
  107. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +2 -0
  108. package/dist/_dts/preview-next/src/client/preview/useConfirmedPreferenceRecord.d.ts +12 -0
  109. package/dist/_dts/preview-next/src/client/preview/usePersistedFooterPreferences.d.ts +26 -0
  110. package/dist/_dts/preview-next/src/client/preview/usePersistedHeaderPreferences.d.ts +40 -2
  111. package/dist/_dts/sdk/src/config/validation.d.ts +3 -3
  112. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +4 -46
  113. package/dist/_dts/sdk/src/date-time/index.d.ts +2 -68
  114. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -0
  115. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +1 -1
  116. package/dist/_dts/sdk/src/version.d.ts +1 -1
  117. package/dist/_dts/theme-core/src/buttons/buttonColourContract.d.ts +2 -0
  118. package/dist/_dts/theme-core/src/buttons/resolveButtonColourStates.d.ts +2 -0
  119. package/dist/_dts/theme-core/src/buttons/styles/recipes/lanternRecipes.d.ts +60 -0
  120. package/dist/_dts/theme-core/src/buttons/styles/registry.d.ts +57 -0
  121. package/dist/_dts/theme-core/src/buttons/styles/selection.d.ts +10 -1
  122. package/dist/_dts/theme-core/src/buttons/types.d.ts +358 -46
  123. package/dist/_dts/theme-core/src/buttons/typography.d.ts +24 -0
  124. package/dist/_dts/theme-core/src/cards/types.d.ts +8 -8
  125. package/dist/_dts/theme-core/src/footer/effectiveNavLinkStyle.d.ts +1 -1
  126. package/dist/_dts/theme-core/src/footer/generateFooterCss.d.ts +4 -1
  127. package/dist/_dts/theme-core/src/footer/mode.d.ts +2 -11
  128. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  129. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +234 -147
  130. package/dist/_dts/theme-core/src/navigation/types.d.ts +4 -4
  131. package/dist/_dts/theme-core/src/schema.d.ts +300 -192
  132. package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +23 -7
  133. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  134. package/dist/_dts/theme-core/src/site-styles/compilationPlan.d.ts +4 -6
  135. package/dist/_dts/theme-core/src/site-styles/compileFooterAgainstRow.d.ts +121 -0
  136. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +25 -0
  137. package/dist/_dts/theme-core/src/site-styles/footerLookDefaults.d.ts +45 -0
  138. package/dist/_dts/theme-core/src/site-styles/footerLookRecipe.d.ts +50 -0
  139. package/dist/_dts/theme-core/src/site-styles/footerLooks.d.ts +9 -35
  140. package/dist/_dts/theme-core/src/site-styles/footerPreferences.d.ts +29 -0
  141. package/dist/_dts/theme-core/src/site-styles/headerPreferencesPersistence.d.ts +2 -3
  142. package/dist/_dts/theme-core/src/site-styles/index.d.ts +4 -0
  143. package/dist/_dts/theme-core/src/site-styles/lookResolution.d.ts +2 -2
  144. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +1 -1
  145. package/dist/_dts/theme-core/src/site-styles/siteChromeBackgrounds.d.ts +8 -0
  146. package/dist/_dts/theme-core/src/site-styles/themeParity.d.ts +1 -1
  147. package/dist/_dts/theme-core/src/site-styles/tokenRecipes.d.ts +1 -1
  148. package/dist/_dts/ui/src/card.d.ts +1 -1
  149. package/dist/client/{BookingMailingListNote-DrchYW1m.mjs → BookingMailingListNote-CNoSqFtf.mjs} +2 -2
  150. package/dist/client/{CardListItem-CC_GVmF6.mjs → CardListItem-BkTkqBkh.mjs} +3 -3
  151. package/dist/client/{CheckboxChoice-Dq30m3DO.mjs → CheckboxChoice-CHJpsty4.mjs} +1 -1
  152. package/dist/client/{DemoBookingPortalAccess-ojwbVUmx.mjs → DemoBookingPortalAccess-C7KQKFNt.mjs} +2 -2
  153. package/dist/client/{EventCombined.client-DyN0v0Xk.mjs → EventCombined.client-BgeYMjHJ.mjs} +5 -5
  154. package/dist/client/{EventEmbeddedCheckoutStep-CgfpKc3n.mjs → EventEmbeddedCheckoutStep-BTc_lTkM.mjs} +2 -2
  155. package/dist/client/{EventListing.client-CuOuvYMz.mjs → EventListing.client-ChRs9Hl2.mjs} +2 -2
  156. package/dist/client/{LeafletStaticMap-B0WhRr3j.mjs → LeafletStaticMap-C_dNQgd0.mjs} +1 -1
  157. package/dist/client/{RichText-C1fIXBzA.mjs → RichText-BI9bzbjo.mjs} +75 -42
  158. package/dist/client/{ThemedButton-B7HFqFBg.mjs → ThemedButton-wl3Z3wkH.mjs} +1 -1
  159. package/dist/client/{accordion-DCDVWSye.mjs → accordion-6Yz8Wd83.mjs} +1 -1
  160. package/dist/client/{bookingForm-BJ3C4GlM.mjs → bookingForm-i_pKIGiY.mjs} +8 -8
  161. package/dist/client/bookings.mjs +12565 -11839
  162. package/dist/client/{carousel-BSCBhfHY.mjs → carousel-DNqd_PjC.mjs} +2 -2
  163. package/dist/client/{carousel.client-GEtOGsxo.mjs → carousel.client-BUgjPbb6.mjs} +1 -1
  164. package/dist/client/{cart-Yv-aAtck.mjs → cart-D8OBHuF4.mjs} +3 -3
  165. package/dist/client/{checkout-B9xDkl30.mjs → checkout-F3-9IGLU.mjs} +3 -3
  166. package/dist/client/client.mjs +6109 -4778
  167. package/dist/client/{context-BOGe3rIA.mjs → context-Dg4ZrxDD.mjs} +1 -1
  168. package/dist/client/{eventCalendar-D6M0T9hs.mjs → eventCalendar-BUc7YIBM.mjs} +8 -8
  169. package/dist/client/{eventCombined-NM4UFBq8.mjs → eventCombined-BwfShk2a.mjs} +4 -4
  170. package/dist/client/{eventDetails-f_FhV4O8.mjs → eventDetails-BMOVC3go.mjs} +3 -3
  171. package/dist/client/{eventListing-WLkfAROh.mjs → eventListing-BwE9PM-t.mjs} +4 -4
  172. package/dist/client/{eventRegistration-D3ejfLvW.mjs → eventRegistration-CCWPYDc7.mjs} +9 -9
  173. package/dist/client/{form-D5Or2Jyu.mjs → form-CXFr0Gd5.mjs} +115 -51
  174. package/dist/client/{headerSection-hWgnv27V.mjs → headerSection-BX8qw8kH.mjs} +3 -3
  175. package/dist/client/hooks.mjs +2041 -1193
  176. package/dist/client/{locationMap-Di1K0O2S.mjs → locationMap-B3La71m0.mjs} +3 -3
  177. package/dist/client/{media-D29-F1u_.mjs → media-B1Cbv721.mjs} +1 -1
  178. package/dist/client/{newsletterForm-CwxcwTNO.mjs → newsletterForm-DnGyR0x7.mjs} +50 -14
  179. package/dist/client/{productDetail-BLSnhPdA.mjs → productDetail-BVgTqvkb.mjs} +3 -3
  180. package/dist/client/{productList-oGytONOX.mjs → productList-CcO7kUQw.mjs} +3 -3
  181. package/dist/client/{propsDecoder-lf_dTeZS.mjs → propsDecoder-B1OeWavE.mjs} +706 -229
  182. package/dist/client/rendering/client.mjs +11868 -11098
  183. package/dist/client/rendering/islands.mjs +17 -17
  184. package/dist/client/rendering.mjs +6058 -4676
  185. package/dist/client/{routeIslandApiConfig-Bc_WVPS8.mjs → routeIslandApiConfig-Dl4vglJm.mjs} +1 -1
  186. package/dist/client/{shop-BQ3bR7fA.mjs → shop-P72nX5Fs.mjs} +7 -7
  187. package/dist/client/{shop-commerce-DDPll6ZC.mjs → shop-commerce-Bt7uraDx.mjs} +8 -8
  188. package/dist/client/{shop-commerce-store-DO-e1pTe.mjs → shop-commerce-store-C1-mxSye.mjs} +1 -1
  189. package/dist/client/{shopShared-BylM9jh1.mjs → shopShared-Db-cRGu3.mjs} +4 -4
  190. package/dist/client/{useDiscountCodeUi-B1Puub2v.mjs → useDiscountCodeUi-jvAiUoUX.mjs} +1 -1
  191. package/dist/client/{useEventPagination-BBhkmQaT.mjs → useEventPagination-BdWpCniq.mjs} +6 -6
  192. package/dist/preview-next/before-render.mjs +133 -51
  193. package/dist/preview-next/client/runtime.mjs +3 -3
  194. package/dist/preview-next/editor-chrome.css +5 -2
  195. package/dist/preview-next/keepAlive.mjs +133 -51
  196. package/dist/preview-next/middleware.mjs +133 -51
  197. package/dist/{sdk-runtime-DWCvhJGu.mjs → sdk-runtime-DLhjF2Nw.mjs} +1 -1
  198. package/dist/server/components.mjs +11284 -10014
  199. package/dist/server/config-validation.mjs +2016 -1188
  200. package/dist/server/config.mjs +2016 -1188
  201. package/dist/server/data.mjs +2041 -1193
  202. package/dist/server/date-time.mjs +258 -116
  203. package/dist/server/index.mjs +134 -52
  204. package/dist/server/next.mjs +10571 -9350
  205. package/dist/server/page-converter.mjs +1629 -941
  206. package/dist/server/prebuild.mjs +1 -1
  207. package/dist/server/rendering/server.mjs +11156 -9872
  208. package/dist/server/rendering.mjs +11284 -10014
  209. package/dist/server/routing.mjs +2204 -1283
  210. package/dist/server/server.mjs +2369 -1570
  211. package/dist/server/theme-bridge.mjs +838 -124
  212. package/dist/server/theme.mjs +348 -64
  213. package/dist/{spinner-BYM-Y81w.mjs → spinner-MTooKfck.mjs} +1 -1
  214. package/dist/styles/index.css +254 -1
  215. package/package.json +1 -1
  216. package/dist/_dts/blocks/src/system/blocks/events/shared/layout.d.ts +0 -12
@@ -2115,6 +2115,25 @@ function validateBookingPaymentOptionKinds(kinds) {
2115
2115
  return ok$1(void 0);
2116
2116
  }
2117
2117
  //#endregion
2118
+ //#region ../core/src/date-time-formatter.ts
2119
+ /** Shared Intl engine, internal to core's date presentation owners. */
2120
+ const FORMATTER_CACHE_LIMIT = 100;
2121
+ const dateTimeFormatterCache = /* @__PURE__ */ new Map();
2122
+ function getDateTimeFormatter(locale, timeZone, format) {
2123
+ const key = `${locale}\u0000${timeZone}\u0000${JSON.stringify(Object.entries(format).sort(([left], [right]) => left.localeCompare(right)))}`;
2124
+ const cached = dateTimeFormatterCache.get(key);
2125
+ if (cached !== void 0) return cached;
2126
+ if (typeof locale !== "string" || Intl.DateTimeFormat.supportedLocalesOf([locale]).length === 0) throw new RangeError("An explicit supported locale is required");
2127
+ if (typeof timeZone !== "string" || timeZone.length === 0) throw new RangeError("An explicit time zone is required");
2128
+ const formatter = new Intl.DateTimeFormat(locale, {
2129
+ ...format,
2130
+ timeZone
2131
+ });
2132
+ if (dateTimeFormatterCache.size >= FORMATTER_CACHE_LIMIT) dateTimeFormatterCache.clear();
2133
+ dateTimeFormatterCache.set(key, formatter);
2134
+ return formatter;
2135
+ }
2136
+ //#endregion
2118
2137
  //#region ../core/src/booking-time-zone.ts
2119
2138
  const TIME_ZONE_VALIDITY_CACHE_LIMIT = 100;
2120
2139
  const timeZoneValidityCache = /* @__PURE__ */ new Map();
@@ -2151,8 +2170,6 @@ const START_OF_DAY = {
2151
2170
  second: 0
2152
2171
  };
2153
2172
  const LOCAL_DATE_PATTERN = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/u;
2154
- const DATE_TIME_FORMATTER_CACHE_LIMIT = 100;
2155
- const dateTimeFormatterCache = /* @__PURE__ */ new Map();
2156
2173
  function getSafeTimeZone(timeZone) {
2157
2174
  const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
2158
2175
  return normalized.length > 0 && isValidBookingTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
@@ -2169,19 +2186,7 @@ function formatParseError(error) {
2169
2186
  }
2170
2187
  }
2171
2188
  function formatToPartsLookup(date, locale, timeZone, format) {
2172
- return new Map(getCachedDateTimeFormatter(locale, timeZone, format).formatToParts(date).map((part) => [part.type, part.value]));
2173
- }
2174
- function getCachedDateTimeFormatter(locale, timeZone, format) {
2175
- const key = `${locale}\u0000${timeZone}\u0000${JSON.stringify(Object.entries(format).sort(([left], [right]) => left.localeCompare(right)))}`;
2176
- const cached = dateTimeFormatterCache.get(key);
2177
- if (cached !== void 0) return cached;
2178
- const formatter = new Intl.DateTimeFormat(locale, {
2179
- ...format,
2180
- timeZone
2181
- });
2182
- if (dateTimeFormatterCache.size >= DATE_TIME_FORMATTER_CACHE_LIMIT) dateTimeFormatterCache.clear();
2183
- dateTimeFormatterCache.set(key, formatter);
2184
- return formatter;
2189
+ return new Map(getDateTimeFormatter(locale, timeZone, format).formatToParts(date).map((part) => [part.type, part.value]));
2185
2190
  }
2186
2191
  function getZonedDateTimeParts(date, timeZone) {
2187
2192
  const parts = formatToPartsLookup(date, "en-GB", timeZone, {
@@ -2269,7 +2274,7 @@ function toScheduledBookingDateTime(input) {
2269
2274
  function formatBookingInstant(isoString, options) {
2270
2275
  const date = new Date(isoString);
2271
2276
  if (Number.isNaN(date.getTime())) return isoString;
2272
- return getCachedDateTimeFormatter(options.locale ?? DEFAULT_LOCALE, getSafeTimeZone(options.timeZone), options.format).format(date);
2277
+ return getDateTimeFormatter(options.locale ?? DEFAULT_LOCALE, getSafeTimeZone(options.timeZone), options.format).format(date);
2273
2278
  }
2274
2279
  function formatBookingDate(input, format = {
2275
2280
  weekday: "long",
@@ -2394,6 +2399,17 @@ function localScheduleDateTimeToUtcDate(localDate, localTime, timeZone) {
2394
2399
  return new Date(guess);
2395
2400
  }
2396
2401
  //#endregion
2402
+ //#region ../core/src/date-display.ts
2403
+ /** Site-language policy, shared by customer emails and public event adapters. */
2404
+ function inferSiteDateLocale(siteTimeZone) {
2405
+ if (siteTimeZone === null || siteTimeZone === void 0 || siteTimeZone === "") return "en-US";
2406
+ if (siteTimeZone === "Europe/Dublin") return "en-IE";
2407
+ if (siteTimeZone.startsWith("Europe/")) return "en-GB";
2408
+ if (siteTimeZone.startsWith("Australia/")) return "en-AU";
2409
+ if (siteTimeZone === "Pacific/Auckland" || siteTimeZone === "Pacific/Chatham") return "en-NZ";
2410
+ return "en-US";
2411
+ }
2412
+ //#endregion
2397
2413
  //#region ../core/src/location.ts
2398
2414
  function normalizeLocationAddressText(value) {
2399
2415
  if (typeof value !== "string") return null;
@@ -2531,6 +2547,10 @@ function parseGlobalFields(value) {
2531
2547
  preset: "emailName",
2532
2548
  name: value.name
2533
2549
  } : null;
2550
+ case "emailFirstName": return isRequirement(value.firstName) ? {
2551
+ preset: "emailFirstName",
2552
+ firstName: value.firstName
2553
+ } : null;
2534
2554
  case "emailFirstLast": return isRequirement(value.firstName) && isRequirement(value.lastName) ? {
2535
2555
  preset: "emailFirstLast",
2536
2556
  firstName: value.firstName,
@@ -4270,6 +4290,129 @@ const BILLING_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
4270
4290
  tags: ["billing"],
4271
4291
  auth: "user",
4272
4292
  responseKind: "json"
4293
+ },
4294
+ stripeConnectSetupStart: {
4295
+ path: "/sites/{siteId}/billing/connect/setup",
4296
+ method: "POST",
4297
+ tags: ["site-{siteId}", "stripe-connect"],
4298
+ auth: "user",
4299
+ responseKind: "json",
4300
+ errors: [
4301
+ "validation:invalid_input",
4302
+ "auth:forbidden",
4303
+ "resource:conflict",
4304
+ "server:internal_error"
4305
+ ]
4306
+ },
4307
+ stripeConnectSetupDiscard: {
4308
+ path: "/sites/{siteId}/billing/connect/setup",
4309
+ method: "DELETE",
4310
+ tags: ["site-{siteId}", "stripe-connect"],
4311
+ auth: "user",
4312
+ responseKind: "json",
4313
+ errors: [
4314
+ "validation:invalid_input",
4315
+ "auth:forbidden",
4316
+ "resource:conflict",
4317
+ "server:internal_error"
4318
+ ]
4319
+ },
4320
+ stripeConnectSetupSave: {
4321
+ path: "/sites/{siteId}/billing/connect/setup/save",
4322
+ method: "POST",
4323
+ tags: ["site-{siteId}", "stripe-connect"],
4324
+ auth: "user",
4325
+ responseKind: "json",
4326
+ errors: [
4327
+ "validation:invalid_input",
4328
+ "auth:forbidden",
4329
+ "resource:conflict",
4330
+ "server:internal_error"
4331
+ ]
4332
+ },
4333
+ stripeConnectAccountSession: {
4334
+ path: "/sites/{siteId}/billing/connect/session",
4335
+ method: "POST",
4336
+ tags: ["site-{siteId}", "stripe-connect"],
4337
+ auth: "user",
4338
+ responseKind: "json",
4339
+ errors: [
4340
+ "validation:invalid_input",
4341
+ "auth:forbidden",
4342
+ "resource:conflict",
4343
+ "server:internal_error"
4344
+ ]
4345
+ },
4346
+ stripeConnectStart: {
4347
+ path: "/sites/{siteId}/billing/connect/start",
4348
+ method: "POST",
4349
+ tags: ["site-{siteId}", "stripe-connect"],
4350
+ auth: "user",
4351
+ responseKind: "json",
4352
+ errors: [
4353
+ "validation:invalid_input",
4354
+ "auth:forbidden",
4355
+ "resource:conflict",
4356
+ "server:internal_error"
4357
+ ]
4358
+ },
4359
+ stripeConnectStatus: {
4360
+ path: "/sites/{siteId}/billing/connect/status",
4361
+ method: "GET",
4362
+ tags: ["site-{siteId}", "stripe-connect"],
4363
+ auth: "user",
4364
+ responseKind: "json",
4365
+ errors: [
4366
+ "validation:invalid_input",
4367
+ "auth:forbidden",
4368
+ "resource:conflict",
4369
+ "server:internal_error"
4370
+ ]
4371
+ },
4372
+ stripeAutomaticTaxUpdate: {
4373
+ path: "/sites/{siteId}/billing/automatic-tax",
4374
+ method: "POST",
4375
+ tags: [
4376
+ "site-{siteId}",
4377
+ "billing",
4378
+ "stripe-tax"
4379
+ ],
4380
+ auth: "user",
4381
+ responseKind: "json",
4382
+ errors: [
4383
+ "validation:invalid_input",
4384
+ "auth:forbidden",
4385
+ "resource:not_found",
4386
+ "server:unavailable",
4387
+ "server:internal_error"
4388
+ ]
4389
+ },
4390
+ stripeConnectDisconnect: {
4391
+ path: "/sites/{siteId}/billing/connect/disconnect",
4392
+ method: "DELETE",
4393
+ tags: ["site-{siteId}", "stripe-connect"],
4394
+ auth: "user",
4395
+ responseKind: "json",
4396
+ errors: [
4397
+ "validation:invalid_input",
4398
+ "auth:forbidden",
4399
+ "resource:conflict",
4400
+ "server:internal_error"
4401
+ ]
4402
+ },
4403
+ billingConnectReturn: {
4404
+ path: "/billing/connect/return",
4405
+ method: "GET",
4406
+ auth: "user",
4407
+ responseKind: "void",
4408
+ errors: []
4409
+ },
4410
+ billingConnectRefresh: {
4411
+ path: "/billing/connect/refresh",
4412
+ method: "GET",
4413
+ auth: "user",
4414
+ responseKind: "void",
4415
+ errors: []
4273
4416
  }
4274
4417
  });
4275
4418
  //#endregion
@@ -4434,6 +4577,14 @@ const PAGE_SURFACE_EDITOR_ENDPOINT_DEFINITIONS = {
4434
4577
  * person when nothing is attached to them.
4435
4578
  */
4436
4579
  const BOOKING_PEOPLE_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
4580
+ getBookingPerson: {
4581
+ path: "/sites/{siteId}/bookings/people/{personId}",
4582
+ method: "GET",
4583
+ tags: ["site-{siteId}", "customers-{siteId}"],
4584
+ auth: "user",
4585
+ responseKind: "json",
4586
+ errors: ["resource:not_found", "server:internal_error"]
4587
+ },
4437
4588
  listPeople: {
4438
4589
  path: "/sites/{siteId}/bookings/people",
4439
4590
  method: "GET",
@@ -7669,57 +7820,6 @@ const API_ENDPOINTS$1 = {
7669
7820
  errors: [],
7670
7821
  responseKind: "json"
7671
7822
  },
7672
- stripeConnectStart: {
7673
- path: "/sites/{siteId}/billing/connect/start",
7674
- method: "POST",
7675
- tags: ["site-{siteId}", "stripe-connect"],
7676
- auth: "user",
7677
- responseKind: "json"
7678
- },
7679
- stripeConnectStatus: {
7680
- path: "/sites/{siteId}/billing/connect/status",
7681
- method: "GET",
7682
- tags: ["site-{siteId}", "stripe-connect"],
7683
- auth: "user",
7684
- responseKind: "json"
7685
- },
7686
- stripeAutomaticTaxUpdate: {
7687
- path: "/sites/{siteId}/billing/automatic-tax",
7688
- method: "POST",
7689
- tags: [
7690
- "site-{siteId}",
7691
- "billing",
7692
- "stripe-tax"
7693
- ],
7694
- auth: "user",
7695
- responseKind: "json",
7696
- errors: [
7697
- "validation:invalid_input",
7698
- "auth:forbidden",
7699
- "resource:not_found",
7700
- "server:unavailable",
7701
- "server:internal_error"
7702
- ]
7703
- },
7704
- stripeConnectDisconnect: {
7705
- path: "/sites/{siteId}/billing/connect/disconnect",
7706
- method: "DELETE",
7707
- tags: ["site-{siteId}", "stripe-connect"],
7708
- auth: "user",
7709
- responseKind: "json"
7710
- },
7711
- billingConnectReturn: {
7712
- path: "/billing/connect/return",
7713
- method: "GET",
7714
- auth: "user",
7715
- responseKind: "void"
7716
- },
7717
- billingConnectRefresh: {
7718
- path: "/billing/connect/refresh",
7719
- method: "GET",
7720
- auth: "user",
7721
- responseKind: "void"
7722
- },
7723
7823
  importSiteBackup: {
7724
7824
  path: "/sites/{siteId}/backup/import",
7725
7825
  method: "POST",
@@ -8625,6 +8725,7 @@ const API_ENDPOINTS$1 = {
8625
8725
  errors: [
8626
8726
  "validation:invalid_input",
8627
8727
  "resource:not_found",
8728
+ "resource:conflict",
8628
8729
  "server:internal_error"
8629
8730
  ]
8630
8731
  },
@@ -8650,6 +8751,7 @@ const API_ENDPOINTS$1 = {
8650
8751
  errors: [
8651
8752
  "validation:invalid_input",
8652
8753
  "resource:not_found",
8754
+ "resource:conflict",
8653
8755
  "server:internal_error"
8654
8756
  ]
8655
8757
  },
@@ -10573,7 +10675,7 @@ var SimpleCache = class {
10573
10675
  * 1. This constant
10574
10676
  * 2. The "version" field in package.json
10575
10677
  */
10576
- const SDK_VERSION = "0.153.0";
10678
+ const SDK_VERSION = "0.154.0";
10577
10679
  //#endregion
10578
10680
  //#region src/client/error.ts
10579
10681
  let _Symbol$for;
@@ -11528,6 +11630,29 @@ function selectLogoVariant(tone, variants) {
11528
11630
  return tone === "dark" ? forDarkBackgrounds ?? forLightBackgrounds : forLightBackgrounds ?? forDarkBackgrounds;
11529
11631
  }
11530
11632
  //#endregion
11633
+ //#region ../theme-core/src/buttons/typography.ts
11634
+ const textTransformSchema = z.enum([
11635
+ "none",
11636
+ "uppercase",
11637
+ "lowercase",
11638
+ "capitalize"
11639
+ ]);
11640
+ const fontWeightSchema = z.union([
11641
+ z.literal(400),
11642
+ z.literal(500),
11643
+ z.literal(600),
11644
+ z.literal(700),
11645
+ z.literal(800)
11646
+ ]);
11647
+ const buttonTypographySchema = z.enum(["body", "heading"]);
11648
+ const letterSpacingSchema = z.enum([
11649
+ "tight",
11650
+ "normal",
11651
+ "slight",
11652
+ "loose",
11653
+ "wide"
11654
+ ]);
11655
+ //#endregion
11531
11656
  //#region ../theme-core/src/buttons/types.ts
11532
11657
  /**
11533
11658
  * Standard semantic variant roles a theme exposes.
@@ -11643,6 +11768,7 @@ const buttonEffectApplicationSchema = z.discriminatedUnion("effectId", [
11643
11768
  z.strictObject({
11644
11769
  effectId: z.literal("lift"),
11645
11770
  options: z.strictObject({ amount: z.enum([
11771
+ "0.125",
11646
11772
  "0.25",
11647
11773
  "0.5",
11648
11774
  "1"
@@ -11689,24 +11815,6 @@ const shadowSizeSchema = z.enum([
11689
11815
  "medium",
11690
11816
  "high"
11691
11817
  ]);
11692
- const textTransformSchema = z.enum([
11693
- "none",
11694
- "uppercase",
11695
- "lowercase",
11696
- "capitalize"
11697
- ]);
11698
- const fontWeightSchema = z.union([
11699
- z.literal(500),
11700
- z.literal(600),
11701
- z.literal(700),
11702
- z.literal(800)
11703
- ]);
11704
- const buttonTypographySchema = z.enum(["body", "heading"]);
11705
- const letterSpacingSchema = z.enum([
11706
- "tight",
11707
- "normal",
11708
- "loose"
11709
- ]);
11710
11818
  const hoverTransformSchema = z.enum([
11711
11819
  "none",
11712
11820
  "lift",
@@ -11778,7 +11886,8 @@ const paddingShorthandSchema = z.string().refine((value) => {
11778
11886
  }, { message: "Padding must be two space-separated CSS length tokens (e.g. \"0.5rem 1rem\"). Use `0` for zero." });
11779
11887
  const buttonSizeConfigSchema = z.object({
11780
11888
  padding: paddingShorthandSchema,
11781
- fontSize: z.string().optional()
11889
+ fontSize: z.string().optional(),
11890
+ borderRadius: z.string().optional()
11782
11891
  });
11783
11892
  /**
11784
11893
  * `xl` is optional on the wire so themes persisted before the `xl` size was
@@ -11901,12 +12010,20 @@ const buttonVisualAppearanceSchema = z.strictObject({
11901
12010
  textTransform: textTransformSchema
11902
12011
  }),
11903
12012
  effects: z.array(buttonEffectApplicationSchema),
12013
+ transform: z.literal("none").optional(),
11904
12014
  contextualHover: contextualButtonHoverSchema.optional()
11905
12015
  });
11906
12016
  const buttonVisualStatesSchema = z.strictObject({
11907
12017
  base: buttonVisualAppearanceSchema.extend({ shadow: variantShadowSchema }),
11908
12018
  hover: buttonVisualAppearanceSchema.extend({ shadow: variantShadowSchema }),
11909
- focus: buttonVisualAppearanceSchema.extend({ shadow: z.literal("focus-indicator") }),
12019
+ focus: buttonVisualAppearanceSchema.extend({
12020
+ shadow: z.literal("focus-indicator"),
12021
+ indicator: z.strictObject({
12022
+ kind: z.literal("surface-ink"),
12023
+ width: z.union([z.literal(2), z.literal(3)]),
12024
+ offset: z.union([z.literal(3), z.literal(4)])
12025
+ }).optional()
12026
+ }),
11910
12027
  active: buttonVisualAppearanceSchema.extend({ shadow: variantShadowSchema }),
11911
12028
  disabled: buttonVisualAppearanceSchema.extend({ shadow: variantShadowSchema })
11912
12029
  });
@@ -12526,6 +12643,10 @@ function validateButtonTextContrast(input) {
12526
12643
  }
12527
12644
  };
12528
12645
  }
12646
+ /** A text-token slab inverts the palette's text/background pair, including text shades. */
12647
+ function solidForegroundToken(backgroundToken) {
12648
+ return /^text(?:-\d+)?$/.test(backgroundToken) ? "background" : onColorTokenName(backgroundToken);
12649
+ }
12529
12650
  //#endregion
12530
12651
  //#region ../theme-core/src/buttons/contextualHover.ts
12531
12652
  function resolveContextualHoverPreference(input) {
@@ -12623,7 +12744,7 @@ function candidate(family, shade, currentShade, direction, seedHex, palette) {
12623
12744
  }
12624
12745
  function hasSafeTextContrast(token, palette) {
12625
12746
  const background = palette[token];
12626
- const foreground = palette[onColorTokenName(token)];
12747
+ const foreground = palette[solidForegroundToken(token)];
12627
12748
  return typeof background === "string" && typeof foreground === "string" && contrastRatio(background, foreground) >= BUTTON_CONTRAST_POLICY.textMinimumRatio;
12628
12749
  }
12629
12750
  function isSafeCandidate(token, palette, surface) {
@@ -12718,6 +12839,13 @@ function compileDeclaredVisualStates(input, states) {
12718
12839
  const colours = collectStateColours(mapVisualStates((state) => compileDeclaredVisualState(input, states, state, state === "hover" ? hover.treatment : states[state].background)));
12719
12840
  return colours.ok ? {
12720
12841
  ...colours,
12842
+ focusIndicator: states.focus.indicator ? {
12843
+ kind: "surface-role",
12844
+ colorCss: input.surface?.foregroundCss ?? surfaceForegroundValue("text"),
12845
+ width: states.focus.indicator.width,
12846
+ offset: states.focus.indicator.offset,
12847
+ minimumSurfaceContrast: BUTTON_CONTRAST_POLICY.nonTextMinimumRatio
12848
+ } : colours.focusIndicator,
12721
12849
  contextualHoverRepair: hover.repair
12722
12850
  } : colours;
12723
12851
  }
@@ -12855,7 +12983,7 @@ function resolveFocusIndicator(colour) {
12855
12983
  function resolveSolid(input, backgroundToken, edge) {
12856
12984
  const backgroundHex = paletteHex(input, backgroundToken);
12857
12985
  if (!backgroundHex.ok) return backgroundHex;
12858
- const foregroundToken = unsafeAsOpaqueButtonColourToken(onColorTokenName(backgroundToken));
12986
+ const foregroundToken = unsafeAsOpaqueButtonColourToken(solidForegroundToken(backgroundToken));
12859
12987
  const foregroundHex = input.palette[foregroundToken];
12860
12988
  if (typeof foregroundHex !== "string") return {
12861
12989
  ok: false,
@@ -14433,7 +14561,9 @@ const cardListKnobBlocks = [...cardListFamilyBlocks, "block.event-calendar"];
14433
14561
  const lookKnobBlocks = {
14434
14562
  actionStyle: cardListKnobBlocks,
14435
14563
  titleSize: "block.hero",
14436
- imagePosition: "block.hero",
14564
+ imagePosition: ["block.hero", "block.media-text"],
14565
+ imageShape: "block.media-text",
14566
+ aspectRatio: "block.media-text",
14437
14567
  stickerLine: "block.hero",
14438
14568
  smallCaption: "block.hero",
14439
14569
  candleGlow: "block.hero",
@@ -14443,7 +14573,11 @@ const lookKnobBlocks = {
14443
14573
  dates: "block.offerings-preview",
14444
14574
  showCapacity: "block.event-calendar",
14445
14575
  quoteCount: "block.testimonials",
14446
- archFrame: "block.testimonials",
14576
+ archFrame: [
14577
+ "block.testimonials",
14578
+ "block.newsletter-signup",
14579
+ "block.form"
14580
+ ],
14447
14581
  tilt: "block.testimonials"
14448
14582
  };
14449
14583
  function isArrangementAppearancePreset(preset) {
@@ -14470,13 +14604,25 @@ function cardListKnobDefaults(block, arrangement, knobs, defaults) {
14470
14604
  }
14471
14605
  };
14472
14606
  }
14607
+ const arrangementLookTargets = {
14608
+ hero: "hero",
14609
+ "feature-cards": "feature-cards",
14610
+ "event-calendar": "events",
14611
+ testimonials: "testimonials",
14612
+ "event-details": "events",
14613
+ "media-text": "media-text",
14614
+ "image-gallery": "image-gallery",
14615
+ "newsletter-signup": "newsletter",
14616
+ form: "contact-form",
14617
+ "body-text": "body-text"
14618
+ };
14473
14619
  function defineArrangementLook(id, block, name, arrangement, knobs, input = {}) {
14474
14620
  const mode = block === "event-calendar" ? "list" : null;
14475
14621
  return {
14476
14622
  id: asAppearancePresetId(id),
14477
14623
  blockKinds: [`block.${block}`],
14478
14624
  label: name,
14479
- target: block === "event-calendar" || block === "event-details" ? "events" : block === "hero" ? "hero" : block === "testimonials" ? "testimonials" : "feature-cards",
14625
+ target: arrangementLookTargets[block],
14480
14626
  structure: {
14481
14627
  kind: "arrangement",
14482
14628
  byMode: { [mode ?? "default"]: arrangement },
@@ -15365,6 +15511,15 @@ const appearancePresets = [
15365
15511
  eyebrowTreatment: "accent"
15366
15512
  }
15367
15513
  }),
15514
+ defineArrangementLook("body-text-reading-column", "body-text", "Reading column", "prose", []),
15515
+ defineArrangementLook("form-beside-introduction-arched-panel", "form", "Introduction beside an arched form", "two-column", [], { slotRoles: { panel: "card" } }),
15516
+ defineArrangementLook("newsletter-signup-in-arch", "newsletter-signup", "Signup in an arch", "arch", []),
15517
+ defineArrangementLook("image-gallery-square-tiles", "image-gallery", "Square tiles", "tiles", []),
15518
+ defineArrangementLook("image-gallery-arched-captions", "image-gallery", "Arched photos with captions", "tiles", [], { styleFallback: [id$1("image-gallery-square-tiles")] }),
15519
+ defineArrangementLook("media-text-circle-beside-text", "media-text", "Circle beside the text", "circle-beside", ["imagePosition"], { forcedKnobs: {
15520
+ imageShape: "circle",
15521
+ aspectRatio: "1/1"
15522
+ } }),
15368
15523
  defineArrangementLook("hero-photo-beside-text", "hero", "Photo beside the text", "split", heroKnobs, { slotRoles: { sticker: "highlight" } }),
15369
15524
  defineArrangementLook("hero-headline-row", "hero", "Big headline, then text and photo", "headline-row", heroKnobs, {
15370
15525
  slotRoles: { sticker: "highlight" },
@@ -16655,6 +16810,49 @@ function requireThemeColorToken$1(value) {
16655
16810
  return token;
16656
16811
  }
16657
16812
  //#endregion
16813
+ //#region ../theme-core/src/header/rootPaint.ts
16814
+ /** The nav container takes precedence when a floating header also has one. */
16815
+ function headerRootPaint(header) {
16816
+ const navContainerType = header?.navContainer?.type ?? "none";
16817
+ if (navContainerType === "glass" || navContainerType === "pill") return "contained-nav";
16818
+ return header?.variant === "floating" ? "overlay" : "own-surface";
16819
+ }
16820
+ //#endregion
16821
+ //#region ../theme-core/src/site-styles/siteChromeBackgrounds.ts
16822
+ const siteChromeBackgroundColorTokens = toSiteChromeBackgroundColorTokens(backgroundAppearanceColorTokenNames);
16823
+ const quickSiteChromeBackgroundColorTokens = toSiteChromeBackgroundColorTokens(backgroundAppearanceQuickColorTokenNames);
16824
+ siteChromeBackgroundColorTokens.filter((token) => !quickSiteChromeBackgroundColorTokens.includes(token));
16825
+ function parseSiteChromeBackgroundColorToken(value) {
16826
+ const token = parseBackgroundAppearanceColorToken(value);
16827
+ return token ? token : null;
16828
+ }
16829
+ function toSiteChromeBackgroundColorTokens(tokenNames) {
16830
+ return tokenNames.flatMap((name) => {
16831
+ const token = parseSiteChromeBackgroundColorToken(name);
16832
+ return token ? [token] : [];
16833
+ });
16834
+ }
16835
+ const backgroundColorTokenSchema = z.unknown().transform((value, ctx) => {
16836
+ const token = parseSiteChromeBackgroundColorToken(value);
16837
+ if (token === null) {
16838
+ ctx.addIssue({
16839
+ code: "custom",
16840
+ message: "Unknown site chrome background colour token"
16841
+ });
16842
+ return z.NEVER;
16843
+ }
16844
+ return token;
16845
+ });
16846
+ const siteChromeBackgroundOverrideSchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("default") }).strict(), z.object({
16847
+ kind: z.literal("color"),
16848
+ token: backgroundColorTokenSchema
16849
+ }).strict()]);
16850
+ z.object({
16851
+ background: siteChromeBackgroundOverrideSchema,
16852
+ navigationLayout: z.enum(["inline-wrap", "stack"])
16853
+ }).strict();
16854
+ z.object({ background: siteChromeBackgroundOverrideSchema }).strict();
16855
+ //#endregion
16658
16856
  //#region ../theme-core/src/site-styles/compilationPlan.ts
16659
16857
  const defaultHeaderBrandPreferences = {
16660
16858
  brandDisplay: "auto",
@@ -16815,6 +17013,9 @@ function fallbackEndsAtOffer(entry, mode, style, catalogue, visited) {
16815
17013
  appearancePresets.filter(isArrangementAppearancePreset);
16816
17014
  /** Closed structural hooks shared by block arrangements and bounded skins. */
16817
17015
  const arrangementSlotNames = [
17016
+ "contact",
17017
+ "social",
17018
+ "base",
16818
17019
  "section",
16819
17020
  "stack",
16820
17021
  "inline",
@@ -16901,6 +17102,477 @@ function validateOfferKnobs(style, catalogue) {
16901
17102
  });
16902
17103
  }
16903
17104
  //#endregion
17105
+ //#region ../theme-core/src/site-styles/footerLookDefaults.ts
17106
+ const defaultFooterLookRecipes = {
17107
+ "footer-centred-name": {
17108
+ arrangement: "centred",
17109
+ ground: {
17110
+ kind: "token",
17111
+ token: "surface"
17112
+ },
17113
+ nav: {
17114
+ weight: "regular",
17115
+ colorToken: "text",
17116
+ hoverColorToken: "primary",
17117
+ typography: "body"
17118
+ },
17119
+ legal: {
17120
+ kind: "separate",
17121
+ bar: null
17122
+ },
17123
+ brandAlign: "center"
17124
+ },
17125
+ "footer-links-row": {
17126
+ arrangement: "simple",
17127
+ ground: {
17128
+ kind: "token",
17129
+ token: "surface"
17130
+ },
17131
+ nav: {
17132
+ weight: "regular",
17133
+ colorToken: "text",
17134
+ hoverColorToken: "primary",
17135
+ typography: "body"
17136
+ },
17137
+ legal: { kind: "integrated" },
17138
+ brandAlign: "start"
17139
+ }
17140
+ };
17141
+ /** A whole authored recipe replaces the default; facets are never deep-merged. */
17142
+ function resolveFooterLookRecipe(style, id) {
17143
+ return style?.footerLookRecipes?.[id] ?? defaultFooterLookRecipes[id];
17144
+ }
17145
+ //#endregion
17146
+ //#region ../theme-core/src/interactive/baseSchema.ts
17147
+ /**
17148
+ * Shared Base Schemas for Interactive Elements
17149
+ *
17150
+ * These Zod schemas are shared by buttons and nav links for DRY architecture.
17151
+ */
17152
+ /**
17153
+ * Typography settings shared by buttons and nav links
17154
+ */
17155
+ const interactiveTypographySchema = z.object({
17156
+ /** Font family source */
17157
+ typography: z.enum(["body", "heading"]).default("body"),
17158
+ /** Font weight */
17159
+ fontWeight: z.enum([
17160
+ "regular",
17161
+ "medium",
17162
+ "semibold",
17163
+ "bold"
17164
+ ]).default("medium"),
17165
+ /** Text transform */
17166
+ textTransform: z.enum([
17167
+ "none",
17168
+ "uppercase",
17169
+ "capitalize"
17170
+ ]).default("none"),
17171
+ /** Italic style */
17172
+ italic: z.boolean().default(false)
17173
+ });
17174
+ /**
17175
+ * Effect application reference (shared between buttons and nav)
17176
+ */
17177
+ const effectApplicationSchema = z.object({
17178
+ /** Effect preset ID */
17179
+ effectId: z.string(),
17180
+ /** User-provided customization options */
17181
+ options: z.record(z.string(), z.any()).optional()
17182
+ });
17183
+ /**
17184
+ * Effect composition by state (shared pattern)
17185
+ */
17186
+ const effectCompositionSchema = z.object({
17187
+ /** Effects always applied */
17188
+ base: z.array(effectApplicationSchema).optional(),
17189
+ /** Effects applied on hover */
17190
+ hover: z.array(effectApplicationSchema).optional(),
17191
+ /** Effects applied on active/pressed */
17192
+ active: z.array(effectApplicationSchema).optional(),
17193
+ /** Effects applied on focus */
17194
+ focus: z.array(effectApplicationSchema).optional()
17195
+ });
17196
+ const policiesById = {
17197
+ "darken-background": "other",
17198
+ "lighten-background": "other",
17199
+ "fade-background": "other",
17200
+ "opacity-reduce": "other",
17201
+ "animated-gradient": "other",
17202
+ "background-on-hover": "paired-hover",
17203
+ "background-on-hover-alpha": "paired-hover",
17204
+ "border-glow": "other",
17205
+ "drop-shadow": "other",
17206
+ "inner-shadow": "other",
17207
+ "neumorphic-shadow": "other",
17208
+ "outer-glow": "other",
17209
+ "retro-3d-shadow": "other",
17210
+ "scale-up": "other",
17211
+ "scale-down": "other",
17212
+ lift: "other",
17213
+ "press-down": "other",
17214
+ pop: "other",
17215
+ "aurora-glow": "other",
17216
+ "cosmic-stardust": "other",
17217
+ "gradient-border-fill": "other",
17218
+ "animated-gradient-border-fill": "other",
17219
+ "border-bottom-grow": "other",
17220
+ "gradient-text": "other",
17221
+ "text-color-change": "text-colour",
17222
+ "border-color-change": "other",
17223
+ "sketchy-border": "other",
17224
+ "pulse-animation": "other",
17225
+ "nav-underline": "underline",
17226
+ "nav-frosted-base": "other",
17227
+ "nav-frosted-hover": "other",
17228
+ "nav-frosted-active": "other"
17229
+ };
17230
+ function navEffectPolicy(effectId) {
17231
+ return policiesById[effectId] ?? null;
17232
+ }
17233
+ //#endregion
17234
+ //#region ../theme-core/src/navigation/types.ts
17235
+ /**
17236
+ * Navigation Link Style Types
17237
+ *
17238
+ * Schema and types for composable nav link styling used by header and footer.
17239
+ */
17240
+ /**
17241
+ * Padding preset options for nav links
17242
+ */
17243
+ const navLinkPaddingSchema = z.enum([
17244
+ "none",
17245
+ "compact",
17246
+ "default"
17247
+ ]);
17248
+ /**
17249
+ * Horizontal padding override for nav links.
17250
+ * When set, overrides only the horizontal component of the `padding` preset.
17251
+ */
17252
+ const navLinkPaddingXSchema = z.enum([
17253
+ "none",
17254
+ "tight",
17255
+ "compact",
17256
+ "default",
17257
+ "relaxed",
17258
+ "spacious"
17259
+ ]);
17260
+ /**
17261
+ * Border radius options for nav links
17262
+ */
17263
+ const navLinkBorderRadiusSchema = z.enum([
17264
+ "none",
17265
+ "sm",
17266
+ "md",
17267
+ "full"
17268
+ ]);
17269
+ /**
17270
+ * Typography size options for nav links.
17271
+ */
17272
+ const navLinkTextSizeSchema = z.enum([
17273
+ "xs",
17274
+ "sm",
17275
+ "base",
17276
+ "lg",
17277
+ "xl"
17278
+ ]);
17279
+ /**
17280
+ * Letter spacing options for nav links.
17281
+ */
17282
+ const navLinkLetterSpacingSchema = z.enum([
17283
+ "normal",
17284
+ "wide",
17285
+ "wider",
17286
+ "widest"
17287
+ ]);
17288
+ /**
17289
+ * Optional legibility aid for nav text that floats over uncertain imagery or color.
17290
+ */
17291
+ const navLinkContrastTreatmentSchema = z.enum(["none", "soft-glow"]);
17292
+ /**
17293
+ * Nav link style schema
17294
+ *
17295
+ * Extends interactive typography base with nav-specific settings.
17296
+ */
17297
+ const navLinkStyleSchema = z.object({
17298
+ /** Display name for the style */
17299
+ name: z.string().min(1).max(30).optional(),
17300
+ /** Typography settings (inherited from interactive base) */
17301
+ ...interactiveTypographySchema.shape,
17302
+ /** Text color token */
17303
+ colorToken: themeColorTokenSchema.default("text"),
17304
+ /** Optional text size override */
17305
+ textSize: navLinkTextSizeSchema.optional(),
17306
+ /** Optional letter spacing override */
17307
+ letterSpacing: navLinkLetterSpacingSchema.optional(),
17308
+ /** Optional text-only contrast treatment for transparent/overlay navigation */
17309
+ contrastTreatment: navLinkContrastTreatmentSchema.optional(),
17310
+ /** Hover/active color token (for color-change effects) */
17311
+ hoverColorToken: themeColorTokenSchema.nullable().optional(),
17312
+ /** Padding preset */
17313
+ padding: navLinkPaddingSchema.default("compact"),
17314
+ /** Horizontal padding override (overrides horizontal component of padding preset) */
17315
+ paddingX: navLinkPaddingXSchema.optional(),
17316
+ /** Border radius (for capsule/pill styles) */
17317
+ borderRadius: navLinkBorderRadiusSchema.default("none"),
17318
+ /** Composable effects */
17319
+ effects: effectCompositionSchema.optional()
17320
+ });
17321
+ function navLinkHoverColorCandidate(style) {
17322
+ const effect = style?.effects?.hover?.find((item) => navEffectPolicy(item.effectId) === "text-colour");
17323
+ return parseThemeColorToken(effect?.options?.hoverColorToken ?? style?.hoverColorToken);
17324
+ }
17325
+ function navLinkOwnsHoverForeground(style) {
17326
+ return style?.effects?.hover?.some((effect) => navEffectPolicy(effect.effectId) === "paired-hover") ?? false;
17327
+ }
17328
+ function navLinkOwnsUnderline(style) {
17329
+ return style?.effects?.hover?.some((effect) => navEffectPolicy(effect.effectId) === "underline") ?? false;
17330
+ }
17331
+ shadeBackgroundEffect({
17332
+ id: "darken-background",
17333
+ name: "Darken on Hover",
17334
+ description: "Darkens the background color on hover",
17335
+ label: "Darken Amount (shade step)",
17336
+ shadeDirection: 1
17337
+ });
17338
+ shadeBackgroundEffect({
17339
+ id: "lighten-background",
17340
+ name: "Lighten on Hover",
17341
+ description: "Lightens the background color on hover",
17342
+ label: "Lighten Amount (shade step)",
17343
+ shadeDirection: -1
17344
+ });
17345
+ function shadeBackgroundEffect(config) {
17346
+ return {
17347
+ id: config.id,
17348
+ name: config.name,
17349
+ description: config.description,
17350
+ category: "background",
17351
+ pseudoElement: "none",
17352
+ applicableTo: ["button"],
17353
+ customizableOption: {
17354
+ name: "amount",
17355
+ type: "select",
17356
+ label: config.label,
17357
+ default: 100,
17358
+ options: [
17359
+ 0,
17360
+ 100,
17361
+ 200,
17362
+ 300,
17363
+ 400,
17364
+ 500,
17365
+ 600,
17366
+ 700,
17367
+ 800,
17368
+ 900
17369
+ ]
17370
+ },
17371
+ isApplicable: (buttonConfig) => buttonConfig.background.type === "solid",
17372
+ generateCSS: ({ themeId, variantId, options, tokens, buttonConfig }) => {
17373
+ if (buttonConfig.background.type !== "solid") return "";
17374
+ const amount = (options.amount || 100) * config.shadeDirection;
17375
+ const baseToken = buttonConfig.background.colorToken ?? "primary-500";
17376
+ return `
17377
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
17378
+ background-color: ${tokens.getColor(tokens.adjustShade(baseToken, amount))};
17379
+ }
17380
+ `;
17381
+ }
17382
+ };
17383
+ }
17384
+ //#endregion
17385
+ //#region ../theme-core/src/navigation/presets.ts
17386
+ /**
17387
+ * Built-in nav link style presets
17388
+ *
17389
+ * Each preset uses composable effects to achieve its look.
17390
+ */
17391
+ const NAV_LINK_PRESETS = {
17392
+ /**
17393
+ * Minimal - subtle color change on hover
17394
+ */
17395
+ minimal: {
17396
+ name: "Minimal",
17397
+ typography: "body",
17398
+ fontWeight: "medium",
17399
+ textTransform: "none",
17400
+ italic: false,
17401
+ colorToken: "text",
17402
+ hoverColorToken: "primary",
17403
+ padding: "none",
17404
+ borderRadius: "none",
17405
+ effects: { hover: [{
17406
+ effectId: "text-color-change",
17407
+ options: { hoverColorToken: "primary" }
17408
+ }] }
17409
+ },
17410
+ /**
17411
+ * Underline - static underline appears on hover
17412
+ */
17413
+ underline: {
17414
+ name: "Underline",
17415
+ typography: "body",
17416
+ fontWeight: "medium",
17417
+ textTransform: "none",
17418
+ italic: false,
17419
+ colorToken: "text",
17420
+ padding: "none",
17421
+ borderRadius: "none",
17422
+ effects: { hover: [{
17423
+ effectId: "nav-underline",
17424
+ options: { style: "static" }
17425
+ }] }
17426
+ },
17427
+ /**
17428
+ * Underline Grow - animated underline grows from center on hover
17429
+ */
17430
+ "underline-grow": {
17431
+ name: "Underline Grow",
17432
+ typography: "body",
17433
+ fontWeight: "medium",
17434
+ textTransform: "none",
17435
+ italic: false,
17436
+ colorToken: "text",
17437
+ padding: "none",
17438
+ borderRadius: "none",
17439
+ effects: { hover: [{
17440
+ effectId: "nav-underline",
17441
+ options: { style: "grow" }
17442
+ }] }
17443
+ },
17444
+ /**
17445
+ * Capsule - pill-shaped background on hover
17446
+ */
17447
+ capsule: {
17448
+ name: "Capsule",
17449
+ typography: "body",
17450
+ fontWeight: "medium",
17451
+ textTransform: "none",
17452
+ italic: false,
17453
+ colorToken: "text",
17454
+ padding: "compact",
17455
+ borderRadius: "full",
17456
+ effects: {
17457
+ hover: [{
17458
+ effectId: "background-on-hover-alpha",
17459
+ options: {
17460
+ colorToken: "primary",
17461
+ opacity: 10
17462
+ }
17463
+ }],
17464
+ active: [{
17465
+ effectId: "background-on-hover-alpha",
17466
+ options: {
17467
+ colorToken: "primary",
17468
+ opacity: 15
17469
+ }
17470
+ }]
17471
+ }
17472
+ },
17473
+ /**
17474
+ * Solid - solid background color on hover
17475
+ */
17476
+ solid: {
17477
+ name: "Solid",
17478
+ typography: "body",
17479
+ fontWeight: "medium",
17480
+ textTransform: "none",
17481
+ italic: false,
17482
+ colorToken: "text",
17483
+ padding: "compact",
17484
+ borderRadius: "none",
17485
+ effects: {
17486
+ hover: [{
17487
+ effectId: "background-on-hover",
17488
+ options: {
17489
+ colorToken: "primary",
17490
+ textColorToken: "primaryForeground"
17491
+ }
17492
+ }],
17493
+ active: [{
17494
+ effectId: "background-on-hover",
17495
+ options: {
17496
+ colorToken: "primary",
17497
+ textColorToken: "primaryForeground"
17498
+ }
17499
+ }]
17500
+ }
17501
+ },
17502
+ /**
17503
+ * Scale - gentle scale-up on hover
17504
+ */
17505
+ scale: {
17506
+ name: "Scale",
17507
+ typography: "body",
17508
+ fontWeight: "medium",
17509
+ textTransform: "none",
17510
+ italic: false,
17511
+ colorToken: "text",
17512
+ padding: "none",
17513
+ borderRadius: "none",
17514
+ effects: { hover: [{
17515
+ effectId: "scale-up",
17516
+ options: { scale: 1.05 }
17517
+ }] }
17518
+ },
17519
+ /**
17520
+ * Frosted - semi-transparent glass-like background
17521
+ */
17522
+ frosted: {
17523
+ name: "Frosted",
17524
+ typography: "body",
17525
+ fontWeight: "medium",
17526
+ textTransform: "none",
17527
+ italic: false,
17528
+ colorToken: "text",
17529
+ padding: "compact",
17530
+ borderRadius: "md",
17531
+ effects: {
17532
+ base: [{ effectId: "nav-frosted-base" }],
17533
+ hover: [{ effectId: "nav-frosted-hover" }],
17534
+ active: [{ effectId: "nav-frosted-active" }]
17535
+ }
17536
+ }
17537
+ };
17538
+ /**
17539
+ * Get a nav link style preset by ID
17540
+ */
17541
+ function getNavLinkPreset(presetId) {
17542
+ return NAV_LINK_PRESETS[presetId];
17543
+ }
17544
+ Object.keys(NAV_LINK_PRESETS);
17545
+ //#endregion
17546
+ //#region ../theme-core/src/footer/effectiveNavLinkStyle.ts
17547
+ function effectiveFooterNavLinkStyle(footer) {
17548
+ if (!footer) return null;
17549
+ if (footer.navLinkStyle) return footer.navLinkStyle;
17550
+ const basePreset = getNavLinkPreset(footer.navStyle ?? "minimal");
17551
+ if (!basePreset) return null;
17552
+ return {
17553
+ ...basePreset,
17554
+ fontWeight: footer.navWeight ?? basePreset.fontWeight,
17555
+ colorToken: footer.navColor?.trim() || basePreset.colorToken
17556
+ };
17557
+ }
17558
+ function footerForegroundCandidates(footer, proseHoverCandidate) {
17559
+ if (!footer) return {};
17560
+ const style = effectiveFooterNavLinkStyle(footer);
17561
+ return {
17562
+ text: footer.background?.textColor ?? (footer.variant === "centred" ? "text" : void 0),
17563
+ link: style?.colorToken ?? footer.navColor ?? footer.background?.textColor,
17564
+ linkHover: navLinkOwnsHoverForeground(style) ? proseHoverCandidate : navLinkHoverColorCandidate(style)
17565
+ };
17566
+ }
17567
+ //#endregion
17568
+ //#region ../theme-core/src/site-styles/footerLookRecipe.ts
17569
+ /** Reject undeclared references when the curated catalogue is loaded, before rendering. */
17570
+ function validateFooterRecipeSurfaces(style, recipe) {
17571
+ [recipe.ground, ...recipe.legal.kind === "separate" && recipe.legal.bar ? [recipe.legal.bar.background] : []].forEach((ground) => {
17572
+ if (ground.kind === "style-surface" && (style.looks.kind !== "offers" || !style.looks.surfaces[ground.surface])) throw new Error(`Undeclared footer surface: ${ground.surface}`);
17573
+ });
17574
+ }
17575
+ //#endregion
16904
17576
  //#region ../theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.ts
16905
17577
  const emptyParametersSchema$1 = z.object({}).strict();
16906
17578
  function defineStaticButtonStyleRecipe(input) {
@@ -16928,6 +17600,287 @@ function normalizeAppearance(appearance) {
16928
17600
  };
16929
17601
  }
16930
17602
  //#endregion
17603
+ //#region ../theme-core/src/buttons/styles/recipes/lanternRecipes.ts
17604
+ const flatShadow = {
17605
+ elevation: "none",
17606
+ softness: null,
17607
+ position: "bottom"
17608
+ };
17609
+ const lift$1 = {
17610
+ effectId: "lift",
17611
+ options: { amount: "0.125" }
17612
+ };
17613
+ const tags = {
17614
+ tone: "classic",
17615
+ energy: "calm",
17616
+ motion: "subtle",
17617
+ era: "editorial"
17618
+ };
17619
+ /** Each role supplies complete states, including a flat surface-ink focus ring. */
17620
+ function states(base, hover, offset = 4, width = 2) {
17621
+ return {
17622
+ base,
17623
+ hover,
17624
+ focus: {
17625
+ ...base,
17626
+ shadow: "focus-indicator",
17627
+ indicator: {
17628
+ kind: "surface-ink",
17629
+ width,
17630
+ offset
17631
+ }
17632
+ },
17633
+ active: {
17634
+ ...base,
17635
+ transform: "none"
17636
+ },
17637
+ disabled: {
17638
+ ...base,
17639
+ effects: []
17640
+ }
17641
+ };
17642
+ }
17643
+ const gilt = {
17644
+ text: "treatment",
17645
+ border: "none",
17646
+ borderRadius: "rounded-10px",
17647
+ shadow: flatShadow,
17648
+ sizes: {
17649
+ sm: {
17650
+ padding: "10px 20px",
17651
+ fontSize: "text-base",
17652
+ borderRadius: "rounded-lg"
17653
+ },
17654
+ md: {
17655
+ padding: "18px 36px",
17656
+ fontSize: "text-19px"
17657
+ },
17658
+ lg: {
17659
+ padding: "18px 36px",
17660
+ fontSize: "text-19px"
17661
+ },
17662
+ xl: {
17663
+ padding: "18px 36px",
17664
+ fontSize: "text-19px"
17665
+ }
17666
+ },
17667
+ typography: {
17668
+ fontWeight: 400,
17669
+ typography: "heading",
17670
+ fontSize: "text-19px",
17671
+ letterSpacing: "slight",
17672
+ italic: false,
17673
+ textTransform: "none"
17674
+ },
17675
+ effects: []
17676
+ };
17677
+ const giltPrimary = {
17678
+ ...gilt,
17679
+ background: {
17680
+ type: "gradient",
17681
+ stops: ["accent", "primary"],
17682
+ direction: "to-br",
17683
+ foregroundToken: "onAccent"
17684
+ }
17685
+ };
17686
+ const giltPrimaryHover = {
17687
+ ...giltPrimary,
17688
+ background: {
17689
+ ...giltPrimary.background,
17690
+ stops: ["accent-400", "primary-400"],
17691
+ foregroundToken: "secondary-950"
17692
+ },
17693
+ effects: [lift$1]
17694
+ };
17695
+ const giltSecondary = {
17696
+ ...gilt,
17697
+ background: {
17698
+ type: "solid",
17699
+ colorToken: "text"
17700
+ }
17701
+ };
17702
+ const giltSecondaryHover = {
17703
+ ...giltSecondary,
17704
+ effects: [lift$1],
17705
+ contextualHover: {
17706
+ kind: "shade-shift",
17707
+ seedToken: unsafeAsOpaqueButtonColourToken("text"),
17708
+ fallbackDirection: "lighter"
17709
+ }
17710
+ };
17711
+ const giltPrimaryStates = states(giltPrimary, giltPrimaryHover);
17712
+ const giltSecondaryStates = states(giltSecondary, giltSecondaryHover);
17713
+ const giltSlabRecipe = defineStaticButtonStyleRecipe({
17714
+ id: "gilt-slab",
17715
+ accessibilityLabel: "Gilt slab",
17716
+ tags,
17717
+ system: { roles: {
17718
+ primary: { states: giltPrimaryStates },
17719
+ secondary: { states: giltSecondaryStates },
17720
+ outline: { states: giltSecondaryStates },
17721
+ ghost: { states: giltSecondaryStates },
17722
+ accent: { states: giltPrimaryStates }
17723
+ } }
17724
+ });
17725
+ const hairline = {
17726
+ text: "treatment",
17727
+ borderRadius: "rounded-3px",
17728
+ shadow: flatShadow,
17729
+ sizes: {
17730
+ sm: {
17731
+ padding: "9px 16px",
17732
+ fontSize: "text-xs"
17733
+ },
17734
+ md: {
17735
+ padding: "15px 28px",
17736
+ fontSize: "text-13px"
17737
+ },
17738
+ lg: {
17739
+ padding: "15px 28px",
17740
+ fontSize: "text-13px"
17741
+ },
17742
+ xl: {
17743
+ padding: "15px 28px",
17744
+ fontSize: "text-13px"
17745
+ }
17746
+ },
17747
+ typography: {
17748
+ fontWeight: 700,
17749
+ typography: "body",
17750
+ fontSize: "text-13px",
17751
+ letterSpacing: "wide",
17752
+ italic: false,
17753
+ textTransform: "uppercase"
17754
+ },
17755
+ effects: []
17756
+ };
17757
+ const hairlinePrimary = {
17758
+ ...hairline,
17759
+ background: {
17760
+ type: "solid",
17761
+ colorToken: "primary"
17762
+ },
17763
+ border: {
17764
+ widthClass: "border",
17765
+ boundaryInk: unsafeAsOpaqueButtonColourToken("primary")
17766
+ }
17767
+ };
17768
+ const hairlineOutline = {
17769
+ ...hairline,
17770
+ background: {
17771
+ type: "surface",
17772
+ role: "link"
17773
+ },
17774
+ border: {
17775
+ widthClass: "border",
17776
+ boundaryInk: unsafeAsOpaqueButtonColourToken("primary")
17777
+ }
17778
+ };
17779
+ const hairlineSecondary = {
17780
+ ...hairlineOutline,
17781
+ border: {
17782
+ widthClass: "border",
17783
+ boundaryInk: unsafeAsOpaqueButtonColourToken("accent")
17784
+ }
17785
+ };
17786
+ const hairlineFilled = {
17787
+ ...hairlineSecondary,
17788
+ background: {
17789
+ type: "solid",
17790
+ colorToken: "accent"
17791
+ }
17792
+ };
17793
+ const hairlinePrimaryStates = states(hairlinePrimary, hairlineOutline, 3);
17794
+ const hairlineSecondaryStates = states(hairlineSecondary, hairlineFilled, 3);
17795
+ const hairlineTabRecipe = defineStaticButtonStyleRecipe({
17796
+ id: "hairline-tab",
17797
+ accessibilityLabel: "Hairline tab",
17798
+ tags,
17799
+ system: { roles: {
17800
+ primary: { states: hairlinePrimaryStates },
17801
+ secondary: { states: hairlineSecondaryStates },
17802
+ outline: { states: hairlineSecondaryStates },
17803
+ ghost: { states: hairlineSecondaryStates },
17804
+ accent: { states: states(hairlineFilled, hairlineSecondary, 3) }
17805
+ } }
17806
+ });
17807
+ const marqueeAccent = {
17808
+ text: "treatment",
17809
+ borderRadius: "rounded-none",
17810
+ shadow: flatShadow,
17811
+ sizes: {
17812
+ sm: {
17813
+ padding: "8px 17px",
17814
+ fontSize: "text-15px"
17815
+ },
17816
+ md: {
17817
+ padding: "14px 25px",
17818
+ fontSize: "text-17px"
17819
+ },
17820
+ lg: {
17821
+ padding: "14px 25px",
17822
+ fontSize: "text-17px"
17823
+ },
17824
+ xl: {
17825
+ padding: "14px 25px",
17826
+ fontSize: "text-17px"
17827
+ }
17828
+ },
17829
+ typography: {
17830
+ fontWeight: 800,
17831
+ typography: "body",
17832
+ fontSize: "text-17px",
17833
+ letterSpacing: "loose",
17834
+ italic: false,
17835
+ textTransform: "uppercase"
17836
+ },
17837
+ effects: [],
17838
+ background: {
17839
+ type: "solid",
17840
+ colorToken: "accent"
17841
+ },
17842
+ border: {
17843
+ widthClass: "border-2",
17844
+ boundaryInk: unsafeAsOpaqueButtonColourToken("accent")
17845
+ }
17846
+ };
17847
+ const marqueePrimary = {
17848
+ ...marqueeAccent,
17849
+ background: {
17850
+ type: "solid",
17851
+ colorToken: "primary"
17852
+ },
17853
+ border: {
17854
+ widthClass: "border-2",
17855
+ boundaryInk: unsafeAsOpaqueButtonColourToken("primary")
17856
+ }
17857
+ };
17858
+ const marqueeSecondary = {
17859
+ ...marqueeAccent,
17860
+ background: {
17861
+ type: "solid",
17862
+ colorToken: "text"
17863
+ },
17864
+ border: {
17865
+ widthClass: "border-2",
17866
+ boundaryInk: unsafeAsOpaqueButtonColourToken("text")
17867
+ }
17868
+ };
17869
+ const marqueePrimaryStates = states(marqueeAccent, marqueePrimary, 4, 3);
17870
+ const marqueeSecondaryStates = states(marqueeSecondary, marqueeAccent, 4, 3);
17871
+ const marqueeRecipe = defineStaticButtonStyleRecipe({
17872
+ id: "marquee",
17873
+ accessibilityLabel: "Marquee",
17874
+ tags,
17875
+ system: { roles: {
17876
+ primary: { states: marqueePrimaryStates },
17877
+ secondary: { states: marqueeSecondaryStates },
17878
+ outline: { states: marqueeSecondaryStates },
17879
+ ghost: { states: marqueeSecondaryStates },
17880
+ accent: { states: marqueePrimaryStates }
17881
+ } }
17882
+ });
17883
+ //#endregion
16931
17884
  //#region ../theme-core/src/buttons/styles/recipes/fulcrumRecipe.ts
16932
17885
  const fulcrumSizes = {
16933
17886
  sm: {
@@ -17669,7 +18622,10 @@ const BUTTON_STYLE_IDS = [
17669
18622
  "offset-block",
17670
18623
  "ringed-pill",
17671
18624
  "square-outline",
17672
- "fulcrum"
18625
+ "fulcrum",
18626
+ "gilt-slab",
18627
+ "hairline-tab",
18628
+ "marquee"
17673
18629
  ];
17674
18630
  const quietArrowParametersSchema = z.object({ secondaryTreatment: z.enum(["outlined", "solid-accent"]) }).strict();
17675
18631
  const flatInkHoverTreatmentSchema = z.enum([
@@ -17706,7 +18662,10 @@ const buttonStyleSelectionSchema = z.discriminatedUnion("styleId", [
17706
18662
  selectionBranch("offset-block", emptyParametersSchema),
17707
18663
  selectionBranch("ringed-pill", emptyParametersSchema),
17708
18664
  selectionBranch("square-outline", emptyParametersSchema),
17709
- selectionBranch("fulcrum", emptyParametersSchema)
18665
+ selectionBranch("fulcrum", emptyParametersSchema),
18666
+ selectionBranch("gilt-slab", emptyParametersSchema),
18667
+ selectionBranch("hairline-tab", emptyParametersSchema),
18668
+ selectionBranch("marquee", emptyParametersSchema)
17710
18669
  ]);
17711
18670
  //#endregion
17712
18671
  //#region ../theme-core/src/buttons/styles/recipes/quietArrow.ts
@@ -21222,7 +22181,10 @@ const buttonStyleRecipes = [
21222
22181
  offsetBlockRecipe,
21223
22182
  ringedPillRecipe,
21224
22183
  squareOutlineRecipe,
21225
- fulcrumRecipe
22184
+ fulcrumRecipe,
22185
+ giltSlabRecipe,
22186
+ hairlineTabRecipe,
22187
+ marqueeRecipe
21226
22188
  ];
21227
22189
  const recipesById = new Map(buttonStyleRecipes.map((recipe) => [recipe.id, recipe]));
21228
22190
  function findButtonStyleRecipe(id) {
@@ -21238,6 +22200,9 @@ function resolveButtonStyleSelection(selection) {
21238
22200
  case "editorial-link": return resolveButtonStyleRecipe(editorialLinkRecipe, selection.parameters);
21239
22201
  case "pebble": return resolveButtonStyleRecipe(pebbleRecipe, selection.parameters);
21240
22202
  case "ink-stamp": return resolveButtonStyleRecipe(inkStampRecipe, selection.parameters);
22203
+ case "gilt-slab": return resolveButtonStyleRecipe(giltSlabRecipe, selection.parameters);
22204
+ case "hairline-tab": return resolveButtonStyleRecipe(hairlineTabRecipe, selection.parameters);
22205
+ case "marquee": return resolveButtonStyleRecipe(marqueeRecipe, selection.parameters);
21241
22206
  case "fulcrum": return resolveButtonStyleRecipe(fulcrumRecipe, selection.parameters);
21242
22207
  case "flat-ink": return resolveButtonStyleRecipe(flatInkRecipe, selection.parameters);
21243
22208
  case "brushed-wash": return resolveButtonStyleRecipe(brushedWashRecipe, selection.parameters);
@@ -24284,52 +25249,14 @@ defineLookOptionGroup({
24284
25249
  function asFooterLookId(value) {
24285
25250
  return value;
24286
25251
  }
24287
- function quietFooterLinks(theme) {
24288
- return {
24289
- ...theme.footer,
24290
- navStyle: "minimal",
24291
- navWeight: "regular",
24292
- navColor: "text",
24293
- navLinkStyle: {
24294
- typography: "body",
24295
- fontWeight: "regular",
24296
- textTransform: "none",
24297
- italic: false,
24298
- colorToken: "text",
24299
- hoverColorToken: "primary",
24300
- padding: "none",
24301
- borderRadius: "none"
24302
- }
24303
- };
24304
- }
24305
- function emphasizedFooterLinks(theme) {
24306
- return {
24307
- ...theme.footer,
24308
- navStyle: "minimal",
24309
- navWeight: "medium",
24310
- navColor: "text",
24311
- navLinkStyle: {
24312
- typography: "body",
24313
- fontWeight: "medium",
24314
- textTransform: "none",
24315
- italic: false,
24316
- colorToken: "text",
24317
- hoverColorToken: "primary",
24318
- padding: "none",
24319
- borderRadius: "none"
24320
- }
24321
- };
24322
- }
24323
25252
  const footerLookCatalog = defineExactCatalog()([{
24324
- id: asFooterLookId("footer-links-quiet"),
24325
- label: "Quiet links",
24326
- description: "Regular-weight footer navigation with a restrained hover.",
24327
- compile: quietFooterLinks
25253
+ id: asFooterLookId("footer-links-row"),
25254
+ label: "Links in a row",
25255
+ description: "Your links in a row, with the other footer sections in columns beside them."
24328
25256
  }, {
24329
- id: asFooterLookId("footer-links-emphasized"),
24330
- label: "Emphasized links",
24331
- description: "Medium-weight footer navigation with a clearer emphasis.",
24332
- compile: emphasizedFooterLinks
25257
+ id: asFooterLookId("footer-centred-name"),
25258
+ label: "Centred name, links beneath",
25259
+ description: "Your site name centred, with your links, contact details and social links beneath it."
24333
25260
  }]);
24334
25261
  new Map(footerLookCatalog.map((look) => [look.id, look]));
24335
25262
  //#endregion
@@ -25223,14 +26150,6 @@ const themeLookMetadataSchema = z.object({
25223
26150
  skinMarks: skinMarksSchema.optional()
25224
26151
  });
25225
26152
  //#endregion
25226
- //#region ../theme-core/src/footer/mode.ts
25227
- const footerModeSchema = z.enum([
25228
- "default",
25229
- "blocks",
25230
- "default+blocks",
25231
- "none"
25232
- ]);
25233
- //#endregion
25234
26153
  //#region ../theme-core/src/palette/schema.ts
25235
26154
  const colourHexString = z.string().regex(/^#([0-9A-Fa-f]{3}){1,2}$/);
25236
26155
  const paletteColorSchema = z.object({
@@ -25258,59 +26177,6 @@ const paletteSchema = z.object({
25258
26177
  meta: palette.meta
25259
26178
  };
25260
26179
  });
25261
- shadeBackgroundEffect({
25262
- id: "darken-background",
25263
- name: "Darken on Hover",
25264
- description: "Darkens the background color on hover",
25265
- label: "Darken Amount (shade step)",
25266
- shadeDirection: 1
25267
- });
25268
- shadeBackgroundEffect({
25269
- id: "lighten-background",
25270
- name: "Lighten on Hover",
25271
- description: "Lightens the background color on hover",
25272
- label: "Lighten Amount (shade step)",
25273
- shadeDirection: -1
25274
- });
25275
- function shadeBackgroundEffect(config) {
25276
- return {
25277
- id: config.id,
25278
- name: config.name,
25279
- description: config.description,
25280
- category: "background",
25281
- pseudoElement: "none",
25282
- applicableTo: ["button"],
25283
- customizableOption: {
25284
- name: "amount",
25285
- type: "select",
25286
- label: config.label,
25287
- default: 100,
25288
- options: [
25289
- 0,
25290
- 100,
25291
- 200,
25292
- 300,
25293
- 400,
25294
- 500,
25295
- 600,
25296
- 700,
25297
- 800,
25298
- 900
25299
- ]
25300
- },
25301
- isApplicable: (buttonConfig) => buttonConfig.background.type === "solid",
25302
- generateCSS: ({ themeId, variantId, options, tokens, buttonConfig }) => {
25303
- if (buttonConfig.background.type !== "solid") return "";
25304
- const amount = (options.amount || 100) * config.shadeDirection;
25305
- const baseToken = buttonConfig.background.colorToken ?? "primary-500";
25306
- return `
25307
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
25308
- background-color: ${tokens.getColor(tokens.adjustShade(baseToken, amount))};
25309
- }
25310
- `;
25311
- }
25312
- };
25313
- }
25314
26180
  buttonSizeNameSchema.options;
25315
26181
  buttonStyleRecipes.map((recipe) => {
25316
26182
  const resolved = resolveButtonStyleSelection(defaultButtonStyleSelectionFor(recipe.id));
@@ -25595,192 +26461,6 @@ const gradientsSchema = z.object({
25595
26461
  background: z.string().min(1).nullable().optional()
25596
26462
  });
25597
26463
  //#endregion
25598
- //#region ../theme-core/src/interactive/baseSchema.ts
25599
- /**
25600
- * Shared Base Schemas for Interactive Elements
25601
- *
25602
- * These Zod schemas are shared by buttons and nav links for DRY architecture.
25603
- */
25604
- /**
25605
- * Typography settings shared by buttons and nav links
25606
- */
25607
- const interactiveTypographySchema = z.object({
25608
- /** Font family source */
25609
- typography: z.enum(["body", "heading"]).default("body"),
25610
- /** Font weight */
25611
- fontWeight: z.enum([
25612
- "regular",
25613
- "medium",
25614
- "semibold",
25615
- "bold"
25616
- ]).default("medium"),
25617
- /** Text transform */
25618
- textTransform: z.enum([
25619
- "none",
25620
- "uppercase",
25621
- "capitalize"
25622
- ]).default("none"),
25623
- /** Italic style */
25624
- italic: z.boolean().default(false)
25625
- });
25626
- /**
25627
- * Effect application reference (shared between buttons and nav)
25628
- */
25629
- const effectApplicationSchema = z.object({
25630
- /** Effect preset ID */
25631
- effectId: z.string(),
25632
- /** User-provided customization options */
25633
- options: z.record(z.string(), z.any()).optional()
25634
- });
25635
- /**
25636
- * Effect composition by state (shared pattern)
25637
- */
25638
- const effectCompositionSchema = z.object({
25639
- /** Effects always applied */
25640
- base: z.array(effectApplicationSchema).optional(),
25641
- /** Effects applied on hover */
25642
- hover: z.array(effectApplicationSchema).optional(),
25643
- /** Effects applied on active/pressed */
25644
- active: z.array(effectApplicationSchema).optional(),
25645
- /** Effects applied on focus */
25646
- focus: z.array(effectApplicationSchema).optional()
25647
- });
25648
- const policiesById = {
25649
- "darken-background": "other",
25650
- "lighten-background": "other",
25651
- "fade-background": "other",
25652
- "opacity-reduce": "other",
25653
- "animated-gradient": "other",
25654
- "background-on-hover": "paired-hover",
25655
- "background-on-hover-alpha": "paired-hover",
25656
- "border-glow": "other",
25657
- "drop-shadow": "other",
25658
- "inner-shadow": "other",
25659
- "neumorphic-shadow": "other",
25660
- "outer-glow": "other",
25661
- "retro-3d-shadow": "other",
25662
- "scale-up": "other",
25663
- "scale-down": "other",
25664
- lift: "other",
25665
- "press-down": "other",
25666
- pop: "other",
25667
- "aurora-glow": "other",
25668
- "cosmic-stardust": "other",
25669
- "gradient-border-fill": "other",
25670
- "animated-gradient-border-fill": "other",
25671
- "border-bottom-grow": "other",
25672
- "gradient-text": "other",
25673
- "text-color-change": "text-colour",
25674
- "border-color-change": "other",
25675
- "sketchy-border": "other",
25676
- "pulse-animation": "other",
25677
- "nav-underline": "underline",
25678
- "nav-frosted-base": "other",
25679
- "nav-frosted-hover": "other",
25680
- "nav-frosted-active": "other"
25681
- };
25682
- function navEffectPolicy(effectId) {
25683
- return policiesById[effectId] ?? null;
25684
- }
25685
- //#endregion
25686
- //#region ../theme-core/src/navigation/types.ts
25687
- /**
25688
- * Navigation Link Style Types
25689
- *
25690
- * Schema and types for composable nav link styling used by header and footer.
25691
- */
25692
- /**
25693
- * Padding preset options for nav links
25694
- */
25695
- const navLinkPaddingSchema = z.enum([
25696
- "none",
25697
- "compact",
25698
- "default"
25699
- ]);
25700
- /**
25701
- * Horizontal padding override for nav links.
25702
- * When set, overrides only the horizontal component of the `padding` preset.
25703
- */
25704
- const navLinkPaddingXSchema = z.enum([
25705
- "none",
25706
- "tight",
25707
- "compact",
25708
- "default",
25709
- "relaxed",
25710
- "spacious"
25711
- ]);
25712
- /**
25713
- * Border radius options for nav links
25714
- */
25715
- const navLinkBorderRadiusSchema = z.enum([
25716
- "none",
25717
- "sm",
25718
- "md",
25719
- "full"
25720
- ]);
25721
- /**
25722
- * Typography size options for nav links.
25723
- */
25724
- const navLinkTextSizeSchema = z.enum([
25725
- "xs",
25726
- "sm",
25727
- "base",
25728
- "lg",
25729
- "xl"
25730
- ]);
25731
- /**
25732
- * Letter spacing options for nav links.
25733
- */
25734
- const navLinkLetterSpacingSchema = z.enum([
25735
- "normal",
25736
- "wide",
25737
- "wider",
25738
- "widest"
25739
- ]);
25740
- /**
25741
- * Optional legibility aid for nav text that floats over uncertain imagery or color.
25742
- */
25743
- const navLinkContrastTreatmentSchema = z.enum(["none", "soft-glow"]);
25744
- /**
25745
- * Nav link style schema
25746
- *
25747
- * Extends interactive typography base with nav-specific settings.
25748
- */
25749
- const navLinkStyleSchema = z.object({
25750
- /** Display name for the style */
25751
- name: z.string().min(1).max(30).optional(),
25752
- /** Typography settings (inherited from interactive base) */
25753
- ...interactiveTypographySchema.shape,
25754
- /** Text color token */
25755
- colorToken: themeColorTokenSchema.default("text"),
25756
- /** Optional text size override */
25757
- textSize: navLinkTextSizeSchema.optional(),
25758
- /** Optional letter spacing override */
25759
- letterSpacing: navLinkLetterSpacingSchema.optional(),
25760
- /** Optional text-only contrast treatment for transparent/overlay navigation */
25761
- contrastTreatment: navLinkContrastTreatmentSchema.optional(),
25762
- /** Hover/active color token (for color-change effects) */
25763
- hoverColorToken: themeColorTokenSchema.nullable().optional(),
25764
- /** Padding preset */
25765
- padding: navLinkPaddingSchema.default("compact"),
25766
- /** Horizontal padding override (overrides horizontal component of padding preset) */
25767
- paddingX: navLinkPaddingXSchema.optional(),
25768
- /** Border radius (for capsule/pill styles) */
25769
- borderRadius: navLinkBorderRadiusSchema.default("none"),
25770
- /** Composable effects */
25771
- effects: effectCompositionSchema.optional()
25772
- });
25773
- function navLinkHoverColorCandidate(style) {
25774
- const effect = style?.effects?.hover?.find((item) => navEffectPolicy(item.effectId) === "text-colour");
25775
- return parseThemeColorToken(effect?.options?.hoverColorToken ?? style?.hoverColorToken);
25776
- }
25777
- function navLinkOwnsHoverForeground(style) {
25778
- return style?.effects?.hover?.some((effect) => navEffectPolicy(effect.effectId) === "paired-hover") ?? false;
25779
- }
25780
- function navLinkOwnsUnderline(style) {
25781
- return style?.effects?.hover?.some((effect) => navEffectPolicy(effect.effectId) === "underline") ?? false;
25782
- }
25783
- //#endregion
25784
26464
  //#region ../theme-core/src/customCss/validation.ts
25785
26465
  /**
25786
26466
  * Custom CSS Validation Schemas
@@ -26469,20 +27149,15 @@ const headerSchema = z.object({
26469
27149
  const footerVariant = z.enum([
26470
27150
  "simple",
26471
27151
  "columns",
26472
- "split"
26473
- ]);
27152
+ "split",
27153
+ "centred"
27154
+ ]).transform((value) => value === "columns" ? "simple" : value);
26474
27155
  const footerMaxWidth = z.enum(["container", "full"]);
26475
27156
  const footerNavLayoutMode = z.enum([
26476
27157
  "stack",
26477
27158
  "inline",
26478
27159
  "inline-wrap"
26479
27160
  ]);
26480
- const footerNavLayoutAlign = z.enum([
26481
- "start",
26482
- "center",
26483
- "end",
26484
- "space-between"
26485
- ]);
26486
27161
  const footerSpacing = z.enum([
26487
27162
  "none",
26488
27163
  "tight",
@@ -26491,12 +27166,6 @@ const footerSpacing = z.enum([
26491
27166
  "relaxed",
26492
27167
  "spacious"
26493
27168
  ]);
26494
- const footerLogoPlacement = z.enum([
26495
- "left",
26496
- "right",
26497
- "above",
26498
- "below"
26499
- ]);
26500
27169
  const footerLogoSize = z.enum([
26501
27170
  "sm",
26502
27171
  "md",
@@ -26537,17 +27206,8 @@ const footerBottomBarSchema = z.object({
26537
27206
  ]).optional()
26538
27207
  }).optional()
26539
27208
  });
26540
- const footerNavLayoutSchema = z.object({
26541
- layout: footerNavLayoutMode.optional(),
26542
- align: footerNavLayoutAlign.optional(),
26543
- gapX: footerSpacing.optional(),
26544
- gapY: footerSpacing.optional(),
26545
- columns: z.number().int().min(1).max(6).optional()
26546
- });
27209
+ const footerNavLayoutSchema = z.object({ layout: footerNavLayoutMode.optional() });
26547
27210
  const footerLogoSchema = z.object({
26548
- showLogo: z.boolean().default(true),
26549
- showLogoText: z.boolean().optional(),
26550
- placement: footerLogoPlacement.optional(),
26551
27211
  size: footerLogoSize.optional(),
26552
27212
  maxHeight: footerLogoMaxHeight.optional(),
26553
27213
  align: z.enum([
@@ -26557,15 +27217,8 @@ const footerLogoSchema = z.object({
26557
27217
  ]).optional()
26558
27218
  });
26559
27219
  const footerSchema = z.object({
26560
- /**
26561
- * SDK-only footer rendering mode.
26562
- *
26563
- * Historical persisted field; SDK rendering mode now lives in layout.footerMode.
26564
- */
26565
- mode: footerModeSchema.optional(),
26566
27220
  variant: footerVariant,
26567
27221
  maxWidth: footerMaxWidth,
26568
- showLogoText: z.boolean().optional(),
26569
27222
  background: headerBackgroundSchema.default({
26570
27223
  type: "color",
26571
27224
  color: "surface"
@@ -27489,6 +28142,7 @@ function defineCuratedSiteStyle(input) {
27489
28142
  recommendedAppearancePresetIds
27490
28143
  },
27491
28144
  headerCuration: headerCurationBySiteStyle[input.id],
28145
+ footerLookRecipes: input.footerLookRecipes,
27492
28146
  recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(asFooterLookId),
27493
28147
  buttonStyleChoices: input.buttonStyleChoices,
27494
28148
  paletteRecommendations: input.paletteRecommendations,
@@ -27974,7 +28628,11 @@ const lanternLooks = {
27974
28628
  margin: "40px"
27975
28629
  },
27976
28630
  fontLoading: {
27977
- extraBodyFontWeights: [500, 700],
28631
+ extraBodyFontWeights: [
28632
+ 500,
28633
+ 700,
28634
+ 800
28635
+ ],
27978
28636
  italicBodyFontWeights: [400]
27979
28637
  },
27980
28638
  surfaces: {
@@ -28024,6 +28682,38 @@ const lanternLooks = {
28024
28682
  ]
28025
28683
  },
28026
28684
  offers: [
28685
+ {
28686
+ id: id("body-text-reading-column"),
28687
+ treatment: "reading-column",
28688
+ roleMap: lanternRoles
28689
+ },
28690
+ {
28691
+ id: id("form-beside-introduction-arched-panel"),
28692
+ treatment: "arched-panel",
28693
+ addKnobs: ["archFrame"],
28694
+ roleMap: lanternRoles
28695
+ },
28696
+ {
28697
+ id: id("newsletter-signup-in-arch"),
28698
+ treatment: "signup-arch",
28699
+ addKnobs: ["archFrame"],
28700
+ roleMap: lanternRoles
28701
+ },
28702
+ {
28703
+ id: id("image-gallery-square-tiles"),
28704
+ treatment: "square-tiles",
28705
+ roleMap: lanternRoles
28706
+ },
28707
+ {
28708
+ id: id("image-gallery-arched-captions"),
28709
+ treatment: "arched-captions",
28710
+ roleMap: lanternRoles
28711
+ },
28712
+ {
28713
+ id: id("media-text-circle-beside-text"),
28714
+ treatment: "circle-beside",
28715
+ roleMap: lanternRoles
28716
+ },
28027
28717
  {
28028
28718
  id: id("event-details-panel"),
28029
28719
  treatment: "quiet",
@@ -28462,7 +29152,7 @@ const curatedSiteStyles = [
28462
29152
  "faq-contained-help",
28463
29153
  "contact-form-panel"
28464
29154
  ],
28465
- recommendedFooterLookIds: ["footer-links-quiet"],
29155
+ recommendedFooterLookIds: ["footer-links-row"],
28466
29156
  buttonStyleChoices: [
28467
29157
  buttonChoice("soft-pill"),
28468
29158
  buttonChoice("pebble"),
@@ -28581,7 +29271,7 @@ const curatedSiteStyles = [
28581
29271
  "testimonials-non-carded",
28582
29272
  "contact-form-panel"
28583
29273
  ],
28584
- recommendedFooterLookIds: ["footer-links-quiet", "footer-links-emphasized"],
29274
+ recommendedFooterLookIds: ["footer-links-row"],
28585
29275
  buttonStyleChoices: [
28586
29276
  buttonChoice("earth-pill"),
28587
29277
  buttonChoice("soft-pill"),
@@ -28636,7 +29326,41 @@ const curatedSiteStyles = [
28636
29326
  "testimonials-brand-statement-cards",
28637
29327
  "contact-form-panel"
28638
29328
  ],
28639
- recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
29329
+ footerLookRecipes: { "footer-links-row": {
29330
+ arrangement: "split",
29331
+ ground: {
29332
+ kind: "token",
29333
+ token: "primary-800"
29334
+ },
29335
+ nav: {
29336
+ weight: "medium",
29337
+ colorToken: "primaryForeground",
29338
+ hoverColorToken: "secondary",
29339
+ typography: "body"
29340
+ },
29341
+ legal: {
29342
+ kind: "separate",
29343
+ bar: {
29344
+ fullBleed: true,
29345
+ background: {
29346
+ kind: "token",
29347
+ token: "primary-900"
29348
+ },
29349
+ textColor: "primaryForeground",
29350
+ textAlign: "center",
29351
+ paddingY: "compact",
29352
+ paddingX: "default",
29353
+ borderTop: { width: "none" }
29354
+ },
29355
+ linkStyle: {
29356
+ colorToken: "secondary",
29357
+ decorationColorToken: "secondary"
29358
+ }
29359
+ },
29360
+ brandAlign: "start",
29361
+ brandLogoSize: "sm"
29362
+ } },
29363
+ recommendedFooterLookIds: ["footer-links-row"],
28640
29364
  buttonStyleChoices: [
28641
29365
  buttonChoice("showtime-pill"),
28642
29366
  buttonChoice("confident-chip"),
@@ -28707,7 +29431,7 @@ const curatedSiteStyles = [
28707
29431
  "testimonials-statement-cards",
28708
29432
  "contact-form-panel"
28709
29433
  ],
28710
- recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
29434
+ recommendedFooterLookIds: ["footer-links-row"],
28711
29435
  buttonStyleChoices: [
28712
29436
  buttonChoice("ornate-ritual"),
28713
29437
  buttonChoice("joy-stamp"),
@@ -28754,7 +29478,22 @@ const curatedSiteStyles = [
28754
29478
  } }
28755
29479
  },
28756
29480
  recommendedAppearancePresetIds: ["feature-cards-bold-colors", "testimonials-statement-cards"],
28757
- recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
29481
+ footerLookRecipes: { "footer-links-row": {
29482
+ arrangement: "simple",
29483
+ ground: {
29484
+ kind: "token",
29485
+ token: "surface"
29486
+ },
29487
+ nav: {
29488
+ weight: "medium",
29489
+ colorToken: "text",
29490
+ hoverColorToken: "primary",
29491
+ typography: "body"
29492
+ },
29493
+ legal: { kind: "integrated" },
29494
+ brandAlign: "start"
29495
+ } },
29496
+ recommendedFooterLookIds: ["footer-links-row"],
28758
29497
  buttonStyleChoices: [
28759
29498
  buttonChoice("joy-stamp"),
28760
29499
  buttonChoice("ink-stamp"),
@@ -28806,7 +29545,7 @@ const curatedSiteStyles = [
28806
29545
  },
28807
29546
  testimonialQuote: serifDisplayQuote
28808
29547
  },
28809
- recommendedFooterLookIds: ["footer-links-quiet"],
29548
+ recommendedFooterLookIds: ["footer-links-row"],
28810
29549
  buttonStyleChoices: [
28811
29550
  buttonChoice("fulcrum"),
28812
29551
  buttonChoice("editorial-link"),
@@ -28883,7 +29622,7 @@ const curatedSiteStyles = [
28883
29622
  "faq-base-accordion",
28884
29623
  "booking-brand-band"
28885
29624
  ],
28886
- recommendedFooterLookIds: ["footer-links-quiet"],
29625
+ recommendedFooterLookIds: ["footer-links-row"],
28887
29626
  buttonStyleChoices: [
28888
29627
  buttonChoice("quiet-arrow", void 0, { secondaryTreatment: "solid-accent" }),
28889
29628
  buttonChoice("flat-ink"),
@@ -28921,7 +29660,22 @@ const curatedSiteStyles = [
28921
29660
  accordions: boldBorderedAccordionSystem,
28922
29661
  testimonialQuote: accentGlyphQuote
28923
29662
  },
28924
- recommendedFooterLookIds: ["footer-links-emphasized"],
29663
+ footerLookRecipes: { "footer-links-row": {
29664
+ arrangement: "simple",
29665
+ ground: {
29666
+ kind: "token",
29667
+ token: "surface"
29668
+ },
29669
+ nav: {
29670
+ weight: "medium",
29671
+ colorToken: "text",
29672
+ hoverColorToken: "primary",
29673
+ typography: "body"
29674
+ },
29675
+ legal: { kind: "integrated" },
29676
+ brandAlign: "start"
29677
+ } },
29678
+ recommendedFooterLookIds: ["footer-links-row"],
28925
29679
  buttonStyleChoices: [
28926
29680
  buttonChoice("offset-block"),
28927
29681
  buttonChoice("ink-stamp"),
@@ -28960,8 +29714,29 @@ const curatedSiteStyles = [
28960
29714
  accordions: warmInsetAccordionSystem,
28961
29715
  testimonialQuote: serifDisplayQuote
28962
29716
  },
28963
- recommendedFooterLookIds: ["footer-links-quiet"],
29717
+ footerLookRecipes: { "footer-centred-name": {
29718
+ arrangement: "centred",
29719
+ ground: {
29720
+ kind: "style-surface",
29721
+ surface: "deep"
29722
+ },
29723
+ nav: {
29724
+ weight: "regular",
29725
+ colorToken: "text",
29726
+ hoverColorToken: "primary",
29727
+ typography: "heading"
29728
+ },
29729
+ legal: {
29730
+ kind: "separate",
29731
+ bar: null
29732
+ },
29733
+ brandAlign: "center"
29734
+ } },
29735
+ recommendedFooterLookIds: ["footer-centred-name", "footer-links-row"],
28964
29736
  buttonStyleChoices: [
29737
+ buttonChoice("gilt-slab"),
29738
+ buttonChoice("hairline-tab"),
29739
+ buttonChoice("marquee"),
28965
29740
  buttonChoice("ringed-pill"),
28966
29741
  buttonChoice("earth-pill"),
28967
29742
  buttonChoice("editorial-link")
@@ -28996,7 +29771,7 @@ const curatedSiteStyles = [
28996
29771
  accordions: editorialDividedAccordionSystem,
28997
29772
  testimonialQuote: serifDisplayQuote
28998
29773
  },
28999
- recommendedFooterLookIds: ["footer-links-quiet"],
29774
+ recommendedFooterLookIds: ["footer-links-row"],
29000
29775
  buttonStyleChoices: [
29001
29776
  buttonChoice("flat-ink", void 0, { corners: "square" }),
29002
29777
  buttonChoice("editorial-link"),
@@ -29024,6 +29799,7 @@ function curatedStyleTemplate(input) {
29024
29799
  }
29025
29800
  curatedSiteStyles.forEach((style) => {
29026
29801
  if (style.looks.kind === "offers") validateLookFallbacks(style.looks);
29802
+ (/* @__PURE__ */ new Set([...Object.values(style.footerLookRecipes ?? {}), ...style.recommendedFooterLookIds.map((id) => resolveFooterLookRecipe(style, id))])).forEach((recipe) => validateFooterRecipeSurfaces(style, recipe));
29027
29803
  });
29028
29804
  //#endregion
29029
29805
  //#region ../theme-core/src/site-styles/effectiveArrangement.ts
@@ -29121,29 +29897,6 @@ const blockDesignFallback = {
29121
29897
  };
29122
29898
  blockDesignFallback.sectionSurface, blockDesignFallback.contentFrame, blockDesignFallback.sectionHeight, blockDesignFallback.heroLegibility, blockDesignFallback.imageSurfaceTreatment, blockDesignFallback.imageSurfaceMotion, blockDesignFallback.tileTreatment, blockDesignFallback.eventListTreatment, blockDesignFallback.eyebrowTreatment, blockDesignFallback.accordionIconTreatment, blockDesignFallback.composition;
29123
29899
  //#endregion
29124
- //#region ../theme-core/src/header/rootPaint.ts
29125
- /** The nav container takes precedence when a floating header also has one. */
29126
- function headerRootPaint(header) {
29127
- const navContainerType = header?.navContainer?.type ?? "none";
29128
- if (navContainerType === "glass" || navContainerType === "pill") return "contained-nav";
29129
- return header?.variant === "floating" ? "overlay" : "own-surface";
29130
- }
29131
- //#endregion
29132
- //#region ../theme-core/src/site-styles/siteChromeBackgrounds.ts
29133
- const siteChromeBackgroundColorTokens = toSiteChromeBackgroundColorTokens(backgroundAppearanceColorTokenNames);
29134
- const quickSiteChromeBackgroundColorTokens = toSiteChromeBackgroundColorTokens(backgroundAppearanceQuickColorTokenNames);
29135
- siteChromeBackgroundColorTokens.filter((token) => !quickSiteChromeBackgroundColorTokens.includes(token));
29136
- function parseSiteChromeBackgroundColorToken(value) {
29137
- const token = parseBackgroundAppearanceColorToken(value);
29138
- return token ? token : null;
29139
- }
29140
- function toSiteChromeBackgroundColorTokens(tokenNames) {
29141
- return tokenNames.flatMap((name) => {
29142
- const token = parseSiteChromeBackgroundColorToken(name);
29143
- return token ? [token] : [];
29144
- });
29145
- }
29146
- //#endregion
29147
29900
  //#region ../theme-core/src/site-styles/siteChromeNavPreferences.ts
29148
29901
  const headerNavTypographyPreferenceValues = [
29149
29902
  "inherit",
@@ -29259,21 +30012,6 @@ z.object({
29259
30012
  }).strict();
29260
30013
  //#endregion
29261
30014
  //#region ../theme-core/src/site-styles/headerPreferencesPersistence.ts
29262
- const backgroundColorTokenSchema = z.unknown().transform((value, ctx) => {
29263
- const token = parseSiteChromeBackgroundColorToken(value);
29264
- if (token === null) {
29265
- ctx.addIssue({
29266
- code: "custom",
29267
- message: "Unknown site chrome background colour token"
29268
- });
29269
- return z.NEVER;
29270
- }
29271
- return token;
29272
- });
29273
- const backgroundOverrideSchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("default") }).strict(), z.object({
29274
- kind: z.literal("color"),
29275
- token: backgroundColorTokenSchema
29276
- }).strict()]);
29277
30015
  const logoTextIntentSchema = z.object({
29278
30016
  mobileMaxWidth: z.enum([
29279
30017
  "xs",
@@ -29299,7 +30037,7 @@ const headerPreferencesShape = {
29299
30037
  navFontRole: z.enum(headerNavTypographyPreferenceValues),
29300
30038
  navTextSize: z.enum(headerNavFontSizePreferenceValues),
29301
30039
  interactionPalette: z.union([z.literal("recommended"), z.enum(headerInteractionPaletteValues)]),
29302
- background: backgroundOverrideSchema,
30040
+ background: siteChromeBackgroundOverrideSchema,
29303
30041
  structure: structureSchema
29304
30042
  };
29305
30043
  z.object(headerPreferencesShape).strict();
@@ -29308,167 +30046,6 @@ z.object(headerPreferencesShape).omit({
29308
30046
  structure: true
29309
30047
  }).strict();
29310
30048
  //#endregion
29311
- //#region ../theme-core/src/navigation/presets.ts
29312
- /**
29313
- * Built-in nav link style presets
29314
- *
29315
- * Each preset uses composable effects to achieve its look.
29316
- */
29317
- const NAV_LINK_PRESETS = {
29318
- /**
29319
- * Minimal - subtle color change on hover
29320
- */
29321
- minimal: {
29322
- name: "Minimal",
29323
- typography: "body",
29324
- fontWeight: "medium",
29325
- textTransform: "none",
29326
- italic: false,
29327
- colorToken: "text",
29328
- hoverColorToken: "primary",
29329
- padding: "none",
29330
- borderRadius: "none",
29331
- effects: { hover: [{
29332
- effectId: "text-color-change",
29333
- options: { hoverColorToken: "primary" }
29334
- }] }
29335
- },
29336
- /**
29337
- * Underline - static underline appears on hover
29338
- */
29339
- underline: {
29340
- name: "Underline",
29341
- typography: "body",
29342
- fontWeight: "medium",
29343
- textTransform: "none",
29344
- italic: false,
29345
- colorToken: "text",
29346
- padding: "none",
29347
- borderRadius: "none",
29348
- effects: { hover: [{
29349
- effectId: "nav-underline",
29350
- options: { style: "static" }
29351
- }] }
29352
- },
29353
- /**
29354
- * Underline Grow - animated underline grows from center on hover
29355
- */
29356
- "underline-grow": {
29357
- name: "Underline Grow",
29358
- typography: "body",
29359
- fontWeight: "medium",
29360
- textTransform: "none",
29361
- italic: false,
29362
- colorToken: "text",
29363
- padding: "none",
29364
- borderRadius: "none",
29365
- effects: { hover: [{
29366
- effectId: "nav-underline",
29367
- options: { style: "grow" }
29368
- }] }
29369
- },
29370
- /**
29371
- * Capsule - pill-shaped background on hover
29372
- */
29373
- capsule: {
29374
- name: "Capsule",
29375
- typography: "body",
29376
- fontWeight: "medium",
29377
- textTransform: "none",
29378
- italic: false,
29379
- colorToken: "text",
29380
- padding: "compact",
29381
- borderRadius: "full",
29382
- effects: {
29383
- hover: [{
29384
- effectId: "background-on-hover-alpha",
29385
- options: {
29386
- colorToken: "primary",
29387
- opacity: 10
29388
- }
29389
- }],
29390
- active: [{
29391
- effectId: "background-on-hover-alpha",
29392
- options: {
29393
- colorToken: "primary",
29394
- opacity: 15
29395
- }
29396
- }]
29397
- }
29398
- },
29399
- /**
29400
- * Solid - solid background color on hover
29401
- */
29402
- solid: {
29403
- name: "Solid",
29404
- typography: "body",
29405
- fontWeight: "medium",
29406
- textTransform: "none",
29407
- italic: false,
29408
- colorToken: "text",
29409
- padding: "compact",
29410
- borderRadius: "none",
29411
- effects: {
29412
- hover: [{
29413
- effectId: "background-on-hover",
29414
- options: {
29415
- colorToken: "primary",
29416
- textColorToken: "primaryForeground"
29417
- }
29418
- }],
29419
- active: [{
29420
- effectId: "background-on-hover",
29421
- options: {
29422
- colorToken: "primary",
29423
- textColorToken: "primaryForeground"
29424
- }
29425
- }]
29426
- }
29427
- },
29428
- /**
29429
- * Scale - gentle scale-up on hover
29430
- */
29431
- scale: {
29432
- name: "Scale",
29433
- typography: "body",
29434
- fontWeight: "medium",
29435
- textTransform: "none",
29436
- italic: false,
29437
- colorToken: "text",
29438
- padding: "none",
29439
- borderRadius: "none",
29440
- effects: { hover: [{
29441
- effectId: "scale-up",
29442
- options: { scale: 1.05 }
29443
- }] }
29444
- },
29445
- /**
29446
- * Frosted - semi-transparent glass-like background
29447
- */
29448
- frosted: {
29449
- name: "Frosted",
29450
- typography: "body",
29451
- fontWeight: "medium",
29452
- textTransform: "none",
29453
- italic: false,
29454
- colorToken: "text",
29455
- padding: "compact",
29456
- borderRadius: "md",
29457
- effects: {
29458
- base: [{ effectId: "nav-frosted-base" }],
29459
- hover: [{ effectId: "nav-frosted-hover" }],
29460
- active: [{ effectId: "nav-frosted-active" }]
29461
- }
29462
- }
29463
- };
29464
- /**
29465
- * Get a nav link style preset by ID
29466
- */
29467
- function getNavLinkPreset(presetId) {
29468
- return NAV_LINK_PRESETS[presetId];
29469
- }
29470
- Object.keys(NAV_LINK_PRESETS);
29471
- //#endregion
29472
30049
  //#region ../theme-core/src/header/legacyNavLinkStyle.ts
29473
30050
  function buildLegacyHeaderNavLinkStyle(header, contrastTreatment, navTextSize) {
29474
30051
  const navStyle = header.navStyle ?? "minimal";
@@ -29713,6 +30290,90 @@ z.object({
29713
30290
  motion: z.enum(themeTokenRecipeOptions.motion)
29714
30291
  });
29715
30292
  //#endregion
30293
+ //#region ../blocks/src/system/fields/imageShape.ts
30294
+ const standardImageShapeOptions = [
30295
+ {
30296
+ value: "default",
30297
+ label: "Default"
30298
+ },
30299
+ {
30300
+ value: "square",
30301
+ label: "Square corners"
30302
+ },
30303
+ {
30304
+ value: "rounded",
30305
+ label: "Rounded corners"
30306
+ },
30307
+ {
30308
+ value: "circle",
30309
+ label: "Circle"
30310
+ },
30311
+ {
30312
+ value: "arch",
30313
+ label: "Arch"
30314
+ }
30315
+ ];
30316
+ function createImageShapeField(options = {}) {
30317
+ return {
30318
+ id: options.id ?? "imageShape",
30319
+ type: "select",
30320
+ label: options.label ?? "Image shape",
30321
+ ...options.description ? { description: options.description } : {},
30322
+ required: false,
30323
+ defaultValue: options.defaultValue ?? "default",
30324
+ multiple: false,
30325
+ options: [...standardImageShapeOptions],
30326
+ ui: {
30327
+ intent: options.uiIntent ?? "display",
30328
+ ...options.visibleWhen ? { visibleWhen: options.visibleWhen } : {}
30329
+ }
30330
+ };
30331
+ }
30332
+ //#endregion
30333
+ //#region ../blocks/src/system/fields/aspectRatio.ts
30334
+ const standardAspectRatioOptions = [
30335
+ {
30336
+ value: "auto",
30337
+ label: "Auto (original)"
30338
+ },
30339
+ {
30340
+ value: "16/9",
30341
+ label: "16:9 (Landscape)"
30342
+ },
30343
+ {
30344
+ value: "4/3",
30345
+ label: "4:3 (Standard)"
30346
+ },
30347
+ {
30348
+ value: "1/1",
30349
+ label: "1:1 (Square)"
30350
+ },
30351
+ {
30352
+ value: "3/4",
30353
+ label: "3:4 (Portrait)"
30354
+ },
30355
+ {
30356
+ value: "9/16",
30357
+ label: "9:16 (Tall portrait)"
30358
+ }
30359
+ ];
30360
+ function createAspectRatioField(options = {}) {
30361
+ return {
30362
+ id: options.id ?? "aspectRatio",
30363
+ type: "select",
30364
+ label: options.label ?? "Aspect ratio",
30365
+ ...options.description ? { description: options.description } : {},
30366
+ required: false,
30367
+ defaultValue: options.defaultValue ?? "auto",
30368
+ multiple: false,
30369
+ options: [...standardAspectRatioOptions],
30370
+ ui: {
30371
+ intent: options.uiIntent ?? "display",
30372
+ ...options.visibleWhen ? { visibleWhen: options.visibleWhen } : {}
30373
+ }
30374
+ };
30375
+ }
30376
+ //#endregion
29716
30377
  //#region ../blocks/src/system/constants/events.ts
29717
30378
  const eventCalendarDisplayModeValues = [
29718
30379
  "combined",
@@ -29905,7 +30566,14 @@ const systemCustomizeFacetDefinitions = [
29905
30566
  }
29906
30567
  ], "3", true),
29907
30568
  fixedKnob("block.testimonials", "tilt", "Tilt the small cards", onOff, "true", false, true),
29908
- fixedKnob("block.testimonials", "archFrame", "Arch frame", onOff, "true", false, true),
30569
+ {
30570
+ ...fixedKnob("block.testimonials", "archFrame", "Arch frame", onOff, "true", false, true),
30571
+ blockKinds: [
30572
+ "block.testimonials",
30573
+ "block.newsletter-signup",
30574
+ "block.form"
30575
+ ]
30576
+ },
29909
30577
  fixedKnob("block.hero", "candleGlow", "Candle glow", onOff, "true", false, true),
29910
30578
  fixedKnob("block.hero", "columnGuides", "Column guides", onOff, "true", false, true),
29911
30579
  fixedKnob("block.hero", "titleSize", "Headline size", [
@@ -29929,6 +30597,15 @@ const systemCustomizeFacetDefinitions = [
29929
30597
  value: "right",
29930
30598
  label: "Right"
29931
30599
  }], "right"),
30600
+ fixedKnob("block.media-text", "imagePosition", "Photo side", [{
30601
+ value: "left",
30602
+ label: "Left"
30603
+ }, {
30604
+ value: "right",
30605
+ label: "Right"
30606
+ }], "left"),
30607
+ fixedKnob("block.media-text", "imageShape", "Media shape", standardImageShapeOptions, "default"),
30608
+ fixedKnob("block.media-text", "aspectRatio", "Media aspect ratio", standardAspectRatioOptions, "auto"),
29932
30609
  textKnob("stickerLine", "Sticker line", 32),
29933
30610
  textKnob("smallCaption", "Small caption", 24),
29934
30611
  {
@@ -34419,46 +35096,6 @@ function createRoleOnlyCardStylesField(options) {
34419
35096
  };
34420
35097
  }
34421
35098
  //#endregion
34422
- //#region ../blocks/src/system/fields/imageShape.ts
34423
- const standardImageShapeOptions = [
34424
- {
34425
- value: "default",
34426
- label: "Default"
34427
- },
34428
- {
34429
- value: "square",
34430
- label: "Square corners"
34431
- },
34432
- {
34433
- value: "rounded",
34434
- label: "Rounded corners"
34435
- },
34436
- {
34437
- value: "circle",
34438
- label: "Circle"
34439
- },
34440
- {
34441
- value: "arch",
34442
- label: "Arch"
34443
- }
34444
- ];
34445
- function createImageShapeField(options = {}) {
34446
- return {
34447
- id: options.id ?? "imageShape",
34448
- type: "select",
34449
- label: options.label ?? "Image shape",
34450
- ...options.description ? { description: options.description } : {},
34451
- required: false,
34452
- defaultValue: options.defaultValue ?? "default",
34453
- multiple: false,
34454
- options: [...standardImageShapeOptions],
34455
- ui: {
34456
- intent: options.uiIntent ?? "display",
34457
- ...options.visibleWhen ? { visibleWhen: options.visibleWhen } : {}
34458
- }
34459
- };
34460
- }
34461
- //#endregion
34462
35099
  //#region ../blocks/src/utils/env.ts
34463
35100
  /**
34464
35101
  * Environment detection utilities
@@ -35479,28 +36116,6 @@ function footerNav(opts) {
35479
36116
  return buildFooterNavAll(common);
35480
36117
  }
35481
36118
  //#endregion
35482
- //#region ../theme-core/src/footer/effectiveNavLinkStyle.ts
35483
- function effectiveFooterNavLinkStyle(footer) {
35484
- if (!footer) return null;
35485
- if (footer.navLinkStyle) return footer.navLinkStyle;
35486
- const basePreset = getNavLinkPreset(footer.navStyle ?? "minimal");
35487
- if (!basePreset) return null;
35488
- return {
35489
- ...basePreset,
35490
- fontWeight: footer.navWeight ?? basePreset.fontWeight,
35491
- colorToken: footer.navColor?.trim() || basePreset.colorToken
35492
- };
35493
- }
35494
- function footerForegroundCandidates(footer, proseHoverCandidate) {
35495
- if (!footer) return {};
35496
- const style = effectiveFooterNavLinkStyle(footer);
35497
- return {
35498
- text: footer.background?.textColor,
35499
- link: style?.colorToken ?? footer.navColor ?? footer.background?.textColor,
35500
- linkHover: navLinkOwnsHoverForeground(style) ? proseHoverCandidate : navLinkHoverColorCandidate(style)
35501
- };
35502
- }
35503
- //#endregion
35504
36119
  //#region ../blocks/src/system/fields/backgroundContent.ts
35505
36120
  function parseBackgroundContent(value) {
35506
36121
  const result = boxBackgroundSchema.safeParse(value);
@@ -35571,7 +36186,12 @@ function resolveRuntimeSectionSurface(value, context, options) {
35571
36186
  }
35572
36187
  function arrangementSurfaceInk(foreground, context) {
35573
36188
  if (context.data?._lookSlots === void 0) return {};
35574
- const decorations = surfaceDecorationColors(foreground, context.theme.palette);
36189
+ return surfaceInkStyles(foreground, context.theme.palette);
36190
+ }
36191
+ /** Decoration roles already resolved by the surface owner, shared with footer arrangements. */
36192
+ function surfaceInkStyles(foreground, palette) {
36193
+ if (foreground.kind === "unknown") return {};
36194
+ const decorations = surfaceDecorationColors(foreground, palette);
35575
36195
  return {
35576
36196
  "--rb-surface-muted-color": foreground.roles.muted ?? foreground.roles.text,
35577
36197
  ...decorations ? {
@@ -36182,48 +36802,50 @@ const boxStylesTransforms = [
36182
36802
  ];
36183
36803
  //#endregion
36184
36804
  //#region ../blocks/src/system/node/fragments/responsiveTwoColumn.ts
36185
- function responsiveTwoColumn({ image, text, ratioFrom, imagePositionFrom, gapClassName = "rb-gap-6", gapFrom, gapFallback = "comfortable", containerClassName = "rb-flex rb-flex-col rb-md-flex-row", imageWrapperClassName = "rb-w-full rb-shrink-0", textWrapperClassName = "rb-w-full rb-min-w-0 rb-flex-1" }) {
36186
- const baseClass = !gapFrom ? `${containerClassName} ${gapClassName}`.trim() : containerClassName;
36187
- const props = { className: { $bind: {
36188
- from: imagePositionFrom,
36189
- transforms: [{
36190
- id: "ui.twoColumnContainerClass",
36191
- options: {
36192
- base: baseClass,
36193
- reverseClass: "rb-md-flex-row-reverse"
36194
- }
36195
- }],
36196
- fallback: baseClass
36197
- } } };
36198
- if (gapFrom) props.style = { gap: { $bind: {
36199
- from: gapFrom,
36200
- transforms: [{
36201
- id: "boxStyles.semanticGapValue",
36202
- options: { fallback: gapFallback }
36203
- }],
36204
- fallback: GAP_VALUE_MAP[gapFallback]
36205
- } } };
36206
- return el("div", props, [el("div", {
36207
- className: imageWrapperClassName,
36208
- style: { flexBasis: { $bind: {
36209
- from: ratioFrom,
36805
+ /** The shared two-column shell keeps Look hooks opt-in and absent for legacy content. */
36806
+ function responsiveTwoColumn(config) {
36807
+ return el("div", twoColumnProps(config), [twoColumnWrapper(config, "image", config.image), twoColumnWrapper(config, "text", config.text)]);
36808
+ }
36809
+ function twoColumnProps(config) {
36810
+ const base = `${config.containerClassName ?? "rb-flex rb-flex-col rb-md-flex-row"} ${config.gapFrom ? "" : config.gapClassName ?? "rb-gap-6"}`.trim();
36811
+ const fallback = config.gapFallback ?? "comfortable";
36812
+ return {
36813
+ ...config.lookSlots ? lookSlot("frame") : {},
36814
+ className: { $bind: {
36815
+ from: config.imagePositionFrom,
36210
36816
  transforms: [{
36211
- id: "ui.twoColumnFlexBasis",
36212
- options: { side: "image" }
36817
+ id: "ui.twoColumnContainerClass",
36818
+ options: {
36819
+ base,
36820
+ reverseClass: "rb-md-flex-row-reverse"
36821
+ }
36213
36822
  }],
36214
- fallback: "50%"
36215
- } } }
36216
- }, [image]), el("div", {
36217
- className: textWrapperClassName,
36823
+ fallback: base
36824
+ } },
36825
+ ...config.gapFrom ? { style: { gap: { $bind: {
36826
+ from: config.gapFrom,
36827
+ transforms: [{
36828
+ id: "boxStyles.semanticGapValue",
36829
+ options: { fallback }
36830
+ }],
36831
+ fallback: GAP_VALUE_MAP[fallback]
36832
+ } } } } : {}
36833
+ };
36834
+ }
36835
+ function twoColumnWrapper(config, side, child) {
36836
+ const className = side === "image" ? config.imageWrapperClassName ?? "rb-w-full rb-shrink-0" : config.textWrapperClassName ?? "rb-w-full rb-min-w-0 rb-flex-1";
36837
+ return el("div", {
36838
+ ...config.lookSlots ? lookSlot(side === "image" ? "media" : "copy") : {},
36839
+ className,
36218
36840
  style: { flexBasis: { $bind: {
36219
- from: ratioFrom,
36841
+ from: config.ratioFrom,
36220
36842
  transforms: [{
36221
36843
  id: "ui.twoColumnFlexBasis",
36222
- options: { side: "text" }
36844
+ options: { side }
36223
36845
  }],
36224
36846
  fallback: "50%"
36225
36847
  } } }
36226
- }, [text])]);
36848
+ }, [child]);
36227
36849
  }
36228
36850
  //#endregion
36229
36851
  //#region ../blocks/src/system/node/fragments/styledCard.ts
@@ -36387,6 +37009,47 @@ function sectionState(opts) {
36387
37009
  })]);
36388
37010
  }
36389
37011
  //#endregion
37012
+ //#region ../blocks/src/system/node/fragments/sectionHead.ts
37013
+ const recoverEmptyHeadingWhenActive = {
37014
+ kind: "recover-empty-when-active",
37015
+ placeholder: "Add heading"
37016
+ };
37017
+ const recoverEmptyDescriptionWhenActive = {
37018
+ kind: "recover-empty-when-active",
37019
+ placeholder: "Add description"
37020
+ };
37021
+ function sectionHeaderLayoutNodes(options = {}) {
37022
+ const headingNode = text({
37023
+ as: "h2",
37024
+ ...lookSlot("heading")
37025
+ }, bind("content.heading"), when("content.heading", { authoringPresence: recoverEmptyHeadingWhenActive }));
37026
+ const descriptionNode = richText({
37027
+ className: "rb-prose rb-max-w-none",
37028
+ ...lookSlot("intro")
37029
+ }, bind("content.description"), when("content.description", { authoringPresence: recoverEmptyDescriptionWhenActive }));
37030
+ if (options.splitClassName) return [el("div", {
37031
+ className: options.splitClassName,
37032
+ ...lookSlot("head")
37033
+ }, [headingNode, descriptionNode])];
37034
+ return [headingNode, descriptionNode];
37035
+ }
37036
+ /** Shared optional section copy. Existing consumers keep their description ID. */
37037
+ const sectionHeaderFields = (defaultHeading, introLabel = "Description") => [{
37038
+ id: "heading",
37039
+ type: "text",
37040
+ label: "Heading",
37041
+ description: "Main heading for the section",
37042
+ required: false,
37043
+ multiline: false,
37044
+ ...defaultHeading === void 0 ? {} : { defaultValue: defaultHeading }
37045
+ }, {
37046
+ id: "description",
37047
+ type: "richText",
37048
+ label: introLabel,
37049
+ description: "Optional introductory text",
37050
+ required: false
37051
+ }];
37052
+ //#endregion
36390
37053
  //#region ../blocks/src/system/fragments/types.ts
36391
37054
  const FRAGMENT_ID_PATTERN = /^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$/i;
36392
37055
  const FIELD_ID_PATTERN = /^[a-z][a-zA-Z0-9_-]*$/;
@@ -36719,6 +37382,7 @@ const bodyCopyFragment = defineFragment({
36719
37382
  ],
36720
37383
  layout: stack({
36721
37384
  gap: "md",
37385
+ ...lookSlot("copy"),
36722
37386
  className: "body-copy-container",
36723
37387
  align: { $bind: {
36724
37388
  from: "content.alignment",
@@ -36727,6 +37391,7 @@ const bodyCopyFragment = defineFragment({
36727
37391
  } }
36728
37392
  }, [text({
36729
37393
  as: "h2",
37394
+ ...lookSlot("heading"),
36730
37395
  className: { $bind: {
36731
37396
  from: "content.alignment",
36732
37397
  transforms: [{
@@ -36735,14 +37400,22 @@ const bodyCopyFragment = defineFragment({
36735
37400
  }],
36736
37401
  fallback: "body-copy-heading"
36737
37402
  } }
36738
- }, when("content.heading"), bind("content.heading")), richText({ className: { $bind: {
36739
- from: "content.alignment",
36740
- transforms: [{
36741
- id: "ui.bodyClassFromAlignment",
36742
- options: { base: "body-copy-body rb-prose rb-max-w-none" }
36743
- }],
36744
- fallback: "body-copy-body rb-prose rb-max-w-none"
36745
- } } }, bind("content.body"))])
37403
+ }, when("content.heading", { authoringPresence: {
37404
+ kind: "recover-empty-when-active",
37405
+ placeholder: "Add heading"
37406
+ } }), bind("content.heading")), richText({
37407
+ ...lookSlot("item-body"),
37408
+ leadParagraphSlot: { $bind: { from: "content._lookSlots.lede" } },
37409
+ lookSlots: { $bind: { from: "content._lookSlots" } },
37410
+ className: { $bind: {
37411
+ from: "content.alignment",
37412
+ transforms: [{
37413
+ id: "ui.bodyClassFromAlignment",
37414
+ options: { base: "body-copy-body rb-prose rb-max-w-none" }
37415
+ }],
37416
+ fallback: "body-copy-body rb-prose rb-max-w-none"
37417
+ } }
37418
+ }, bind("content.body"))])
36746
37419
  });
36747
37420
  //#endregion
36748
37421
  //#region ../blocks/src/system/fragments/library/heroCopy.ts
@@ -37758,8 +38431,19 @@ const formCopyFragment = defineFragment({
37758
38431
  }],
37759
38432
  layout: [text({
37760
38433
  as: "h2",
38434
+ ...lookSlot("heading"),
37761
38435
  className: "form-copy-title"
37762
- }, when("content.title"), bind("content.title")), richText({ className: "form-copy-intro rb-prose rb-max-w-none" }, when("content.intro"), bind("content.intro"))]
38436
+ }, when("content.title", { authoringPresence: {
38437
+ kind: "recover-empty-when-active",
38438
+ placeholder: "Add heading"
38439
+ } }), bind("content.title")), richText({
38440
+ className: "form-copy-intro rb-prose rb-max-w-none",
38441
+ ...lookSlot("intro"),
38442
+ leadParagraphSlot: { $bind: { from: "content._lookSlots.lede" } }
38443
+ }, when("content.intro", { authoringPresence: {
38444
+ kind: "recover-empty-when-active",
38445
+ placeholder: "Add introduction"
38446
+ } }), bind("content.intro"))]
37763
38447
  });
37764
38448
  //#endregion
37765
38449
  //#region ../blocks/src/system/helpers/api-bindings.ts
@@ -37808,6 +38492,7 @@ const formEmbedFragment = defineFragment({
37808
38492
  }
37809
38493
  ],
37810
38494
  layout: [form(withApiBindings({
38495
+ lookSlots: { $bind: { from: "content._lookSlots" } },
37811
38496
  spamProtectionEnabled: { $bind: { from: "$root.spamProtectionEnabled" } },
37812
38497
  submitLabel: { $bind: { from: "submitLabel" } },
37813
38498
  successMessage: { $bind: { from: "successMessage" } }
@@ -38061,8 +38746,18 @@ const newsletterCopyFragment = defineFragment({
38061
38746
  }],
38062
38747
  layout: [text({
38063
38748
  as: "h2",
38064
- className: "newsletter-copy-title"
38065
- }, when("content.title"), bind("content.title")), richText({ className: "newsletter-copy-subtitle rb-prose rb-max-w-none" }, when("content.subtitle"), bind("content.subtitle"))]
38749
+ className: "newsletter-copy-title",
38750
+ ...lookSlot("heading")
38751
+ }, when("content.title", { authoringPresence: {
38752
+ kind: "recover-empty-when-active",
38753
+ placeholder: "Add heading"
38754
+ } }), bind("content.title")), richText({
38755
+ className: "newsletter-copy-subtitle rb-prose rb-max-w-none",
38756
+ ...lookSlot("intro")
38757
+ }, when("content.subtitle", { authoringPresence: {
38758
+ kind: "recover-empty-when-active",
38759
+ placeholder: "Add introduction"
38760
+ } }), bind("content.subtitle"))]
38066
38761
  });
38067
38762
  //#endregion
38068
38763
  //#region ../blocks/src/system/fragments/library/newsletterForm.ts
@@ -38130,6 +38825,7 @@ const newsletterFormFragment = defineFragment({
38130
38825
  }
38131
38826
  ],
38132
38827
  layout: [el("newsletter-form", withApiBindings({
38828
+ lookSlots: { $bind: { from: "content._lookSlots" } },
38133
38829
  source: { $bind: {
38134
38830
  from: "mailingListSource",
38135
38831
  fallback: "block"
@@ -39348,50 +40044,6 @@ function gapSelectField(options = {}) {
39348
40044
  });
39349
40045
  }
39350
40046
  //#endregion
39351
- //#region ../blocks/src/system/fields/aspectRatio.ts
39352
- const standardAspectRatioOptions = [
39353
- {
39354
- value: "auto",
39355
- label: "Auto (original)"
39356
- },
39357
- {
39358
- value: "16/9",
39359
- label: "16:9 (Landscape)"
39360
- },
39361
- {
39362
- value: "4/3",
39363
- label: "4:3 (Standard)"
39364
- },
39365
- {
39366
- value: "1/1",
39367
- label: "1:1 (Square)"
39368
- },
39369
- {
39370
- value: "3/4",
39371
- label: "3:4 (Portrait)"
39372
- },
39373
- {
39374
- value: "9/16",
39375
- label: "9:16 (Tall portrait)"
39376
- }
39377
- ];
39378
- function createAspectRatioField(options = {}) {
39379
- return {
39380
- id: options.id ?? "aspectRatio",
39381
- type: "select",
39382
- label: options.label ?? "Aspect ratio",
39383
- ...options.description ? { description: options.description } : {},
39384
- required: false,
39385
- defaultValue: options.defaultValue ?? "auto",
39386
- multiple: false,
39387
- options: [...standardAspectRatioOptions],
39388
- ui: {
39389
- intent: options.uiIntent ?? "display",
39390
- ...options.visibleWhen ? { visibleWhen: options.visibleWhen } : {}
39391
- }
39392
- };
39393
- }
39394
- //#endregion
39395
40047
  //#region ../blocks/src/system/blocks/intro.ts
39396
40048
  function introHeading(className) {
39397
40049
  return text({
@@ -39622,18 +40274,11 @@ const introBlockDefinition = { manifest: createBlockManifest({
39622
40274
  //#endregion
39623
40275
  //#region ../blocks/src/system/blocks/body-text.ts
39624
40276
  const bodyCopyComposition = composeFragments([{ fragment: bodyCopyFragment }]);
39625
- const proseLayout = styledSection({
39626
- children: stack({ className: "rb-container" }, bodyCopyComposition.layout),
39627
- spacing: "medium",
39628
- baseClass: ""
39629
- });
39630
- const introLayout = styledSection({
39631
- children: stack({ className: "rb-container" }, bodyCopyComposition.layout),
39632
- spacing: "medium",
39633
- baseClass: ""
39634
- });
39635
- const narrowLayout = styledSection({
39636
- children: stack({ className: "rb-container" }, bodyCopyComposition.layout),
40277
+ const bodyTextLayout = styledSection({
40278
+ children: stack({
40279
+ className: "rb-container",
40280
+ ...lookSlot("frame")
40281
+ }, bodyCopyComposition.layout),
39637
40282
  spacing: "medium",
39638
40283
  baseClass: ""
39639
40284
  });
@@ -39647,11 +40292,11 @@ const bodyTextBlockDefinition = { manifest: createBlockManifest({
39647
40292
  fragment: bodyCopyFragment,
39648
40293
  fieldPriority: 0
39649
40294
  }],
39650
- layout: proseLayout,
40295
+ layout: bodyTextLayout,
39651
40296
  variants: {
39652
- prose: proseLayout,
39653
- intro: introLayout,
39654
- narrow: narrowLayout
40297
+ prose: bodyTextLayout,
40298
+ intro: bodyTextLayout,
40299
+ narrow: bodyTextLayout
39655
40300
  },
39656
40301
  variantMeaning: { kind: "arrangement" },
39657
40302
  defaultVariant: "prose",
@@ -40099,6 +40744,52 @@ const singleButtonBlockDefinition = { manifest: createBlockManifest({
40099
40744
  styleTokens: { spacing: "md" }
40100
40745
  }) };
40101
40746
  //#endregion
40747
+ //#region ../blocks/src/system/runtime/lookSurfaces.ts
40748
+ const isPlainObject$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
40749
+ const lookListPresentationSchemaShape = {
40750
+ sectionAction: z.object({
40751
+ label: z.string(),
40752
+ href: z.string()
40753
+ }).optional(),
40754
+ actionSize: z.enum([
40755
+ "sm",
40756
+ "md",
40757
+ "lg"
40758
+ ]).optional(),
40759
+ itemActionStyle: z.enum(["button", "link"]).optional(),
40760
+ itemRoles: z.object({
40761
+ container: z.enum([
40762
+ "card",
40763
+ "statement",
40764
+ "highlight"
40765
+ ]).optional(),
40766
+ items: z.enum([
40767
+ "card",
40768
+ "statement",
40769
+ "highlight"
40770
+ ]).optional(),
40771
+ at: z.partialRecord(z.enum([
40772
+ "first",
40773
+ "last",
40774
+ "middle",
40775
+ "odd",
40776
+ "even"
40777
+ ]), z.enum([
40778
+ "card",
40779
+ "statement",
40780
+ "highlight"
40781
+ ])).optional()
40782
+ }).optional(),
40783
+ roleSurfaces: z.record(z.enum([
40784
+ "card",
40785
+ "statement",
40786
+ "highlight"
40787
+ ]), z.custom((value) => isPlainObject$1(value) && (value.kind === "inherit" || value.kind === "owned"))).optional(),
40788
+ panelHeading: z.string().optional(),
40789
+ lookSlots: z.partialRecord(z.enum(arrangementSlotNames), z.enum(arrangementSlotNames)).optional(),
40790
+ itemSurfaces: z.record(z.string(), z.custom((value) => isPlainObject$1(value) && (value.kind === "inherit" || value.kind === "owned"))).optional()
40791
+ };
40792
+ //#endregion
40102
40793
  //#region ../blocks/src/contracts/runtime.ts
40103
40794
  function decodeSuccess(value) {
40104
40795
  return {
@@ -40205,6 +40896,7 @@ const formFieldGroupSchema = z.discriminatedUnion("type", [z.object({
40205
40896
  fields: z.tuple([formFieldSchema, formFieldSchema])
40206
40897
  })]);
40207
40898
  const formSourceSchema = z.object({
40899
+ lookSlots: lookListPresentationSchemaShape.lookSlots,
40208
40900
  value: formRecordSchema.optional(),
40209
40901
  siteId: z.string().optional(),
40210
40902
  apiBaseUrl: z.string().optional(),
@@ -40214,6 +40906,7 @@ const formSourceSchema = z.object({
40214
40906
  spamProtectionEnabled: z.boolean().optional()
40215
40907
  });
40216
40908
  const formDisplaySchema = z.object({
40909
+ lookSlots: lookListPresentationSchemaShape.lookSlots,
40217
40910
  kind: z.literal("form"),
40218
40911
  state: z.enum(["missing", "ready"]),
40219
40912
  className: z.string().nullable(),
@@ -40234,17 +40927,30 @@ z.object({
40234
40927
  });
40235
40928
  function buildFormDisplay(source) {
40236
40929
  const form = source.value ?? null;
40237
- const fields = form?.schemaJson?.fields;
40238
- const groups = Array.isArray(fields) ? groupFormFields(fields) : [];
40930
+ const fields = formDisplayFields(form);
40239
40931
  return {
40240
40932
  kind: "form",
40241
- state: form ? "ready" : "missing",
40933
+ ...source.lookSlots ? { lookSlots: source.lookSlots } : {},
40934
+ state: fields.state,
40242
40935
  className: source.className ?? null,
40243
- formId: form?.id ?? null,
40936
+ formId: fields.formId,
40244
40937
  submitLabel: source.submitLabel?.trim() || "Submit",
40245
40938
  successMessage: source.successMessage ?? null,
40246
40939
  form,
40247
- groups
40940
+ groups: fields.groups
40941
+ };
40942
+ }
40943
+ function formDisplayFields(form) {
40944
+ if (!form) return {
40945
+ state: "missing",
40946
+ formId: null,
40947
+ groups: []
40948
+ };
40949
+ const fields = form.schemaJson?.fields;
40950
+ return {
40951
+ state: "ready",
40952
+ formId: form.id,
40953
+ groups: Array.isArray(fields) ? groupFormFields(fields) : []
40248
40954
  };
40249
40955
  }
40250
40956
  const formBlockRuntime = defineProgressiveBlockRuntime({
@@ -40267,18 +40973,27 @@ function fragmentLayoutNode$1(layout) {
40267
40973
  function isNodeDefinitionArray$1(layout) {
40268
40974
  return Array.isArray(layout);
40269
40975
  }
40270
- const copyLayout = fragmentLayoutNode$1(formCopyFragment.layout);
40976
+ const copyLayout = props(lookSlot("head"))(fragmentLayoutNode$1(formCopyFragment.layout));
40977
+ const embedLayout$1 = fragmentLayoutNode$1(formEmbedFragment.layout);
40271
40978
  const formSurface = styledContainer({
40979
+ rootProps: lookSlot("panel"),
40272
40980
  bindFrom: "_containerStyles",
40273
40981
  constrainWidth: false,
40274
40982
  baseClassName: "rb-form-surface rb-relative rb-isolate rb-overflow-visible",
40275
- children: fragmentLayoutNode$1(formEmbedFragment.layout)
40983
+ children: embedLayout$1
40276
40984
  });
40277
40985
  function createFormLayout(variant) {
40278
40986
  if (variant === "two-column") return styledSection({
40279
- children: el("div", { className: "rb-container" }, [el("div", { className: "rb-form-two-column rb-grid rb-grid-cols-1 rb-gap-8 rb-lg-grid-cols-2 rb-lg-items-start" }, [stack({
40987
+ children: el("div", {
40988
+ className: "rb-container",
40989
+ ...lookSlot("layout")
40990
+ }, [el("div", {
40991
+ className: "rb-form-two-column rb-grid rb-grid-cols-1 rb-gap-8 rb-lg-grid-cols-2 rb-lg-items-start",
40992
+ ...lookSlot("frame")
40993
+ }, [stack({
40280
40994
  gap: "md",
40281
- className: "rb-form-copy-column"
40995
+ className: "rb-form-copy-column",
40996
+ ...lookSlot("copy")
40282
40997
  }, [copyLayout]), formSurface])]),
40283
40998
  baseClass: "",
40284
40999
  spacing: "medium",
@@ -40306,6 +41021,15 @@ const formManifest = createBlockManifest({
40306
41021
  description: "Renders a saved form definition with server-side submit.",
40307
41022
  includeContainerStyles: true,
40308
41023
  fragments: [{ fragment: formCopyFragment }, { fragment: formEmbedFragment }],
41024
+ additionalFields: [{
41025
+ id: "archFrame",
41026
+ type: "boolean",
41027
+ label: "Arch frame",
41028
+ ui: {
41029
+ intent: "display",
41030
+ hidden: true
41031
+ }
41032
+ }],
40309
41033
  layout: formLayout,
40310
41034
  variants: {
40311
41035
  default: formLayout,
@@ -40794,6 +41518,25 @@ const formattingTransforms = [
40794
41518
  mapTokenTransform
40795
41519
  ];
40796
41520
  //#endregion
41521
+ //#region ../blocks/src/system/transforms/registry/footerArrangement.ts
41522
+ const footerBrandArrangementTransform = {
41523
+ id: "layout.footerBrandArrangement",
41524
+ kind: "string",
41525
+ run: (value) => {
41526
+ const module = asPartialObject(value);
41527
+ return module?.kind === "brand" ? module.slots ? "centred" : "row" : void 0;
41528
+ }
41529
+ };
41530
+ const footerModuleInkStyleTransform = {
41531
+ id: "layout.footerModuleInkStyle",
41532
+ kind: "formatter",
41533
+ run: (value, options) => value === "centred" ? void 0 : textColorStyle(asPartialObject(options)?.opacity === 70 ? "text/70" : "text/80")
41534
+ };
41535
+ /** A centred base without authored bar paint inherits its measured surface line. */
41536
+ function footerBottomBarBorderColorStyle(footer) {
41537
+ return footer?.variant === "centred" && !footer.bottomBar ? { borderColor: "var(--rb-surface-line-color)" } : borderColorStyle(footer?.bottomBar?.borderTop?.colorToken ?? "border");
41538
+ }
41539
+ //#endregion
40797
41540
  //#region ../theme-core/src/siteChromePlacement.ts
40798
41541
  const HEADER_POSITIONINGS = [
40799
41542
  "static",
@@ -41058,6 +41801,7 @@ const footerRootStyleTransform = {
41058
41801
  }
41059
41802
  }
41060
41803
  styleParts.push(resolvedForegroundStyle(resolveFooterRootForeground(footer, context.theme.palette, context.proseHoverCandidate)));
41804
+ if (footer?.variant === "centred") styleParts.push(surfaceInkStyles(resolveFooterRootForeground(footer, context.theme.palette, context.proseHoverCandidate), context.theme.palette));
41061
41805
  styleParts.push(borderColorStyle("border"));
41062
41806
  return mergeStyles(...styleParts);
41063
41807
  }
@@ -41119,7 +41863,7 @@ const footerBottomBarStyleTransform = {
41119
41863
  run: (value, _options, context) => {
41120
41864
  const footer = asPartialObject(value);
41121
41865
  const bottomBar = footer?.bottomBar;
41122
- return mergeStyles(bottomBar?.background?.type === "color" ? backgroundColorStyle(bottomBar.background.color ?? "surface") : void 0, borderColorStyle(bottomBar?.borderTop?.colorToken ?? "border"), footerBottomBarBorderWidthStyle(bottomBar?.borderTop?.width), footerBottomBarForegroundStyle(footer, context.theme.palette));
41866
+ return mergeStyles(bottomBar?.background?.type === "color" ? backgroundColorStyle(bottomBar.background.color ?? "surface") : void 0, footerBottomBarBorderColorStyle(footer), footerBottomBarBorderWidthStyle(bottomBar?.borderTop?.width), footerBottomBarForegroundStyle(footer, context.theme.palette));
41123
41867
  }
41124
41868
  };
41125
41869
  function footerBottomBarForegroundStyle(footer, palette) {
@@ -41141,62 +41885,15 @@ function measuredFooterBackdrop(footer, palette) {
41141
41885
  const foreground = resolveFooterRootForeground(footer, palette);
41142
41886
  return foreground.kind === "known" && foreground.provenance.kind === "measured" ? foreground.provenance.backdropHex : null;
41143
41887
  }
41144
- const footerSplitMainClassTransform = {
41145
- id: "layout.footerSplitMainClass",
41146
- kind: "string",
41147
- summary: "Compose split-footer main row classes from footer logo placement",
41148
- schema: z.object({
41149
- base: z.string().optional(),
41150
- reverseClass: z.string().optional()
41151
- }),
41152
- run: (value, options) => {
41153
- const placement = asPartialObject(value)?.placement ?? "right";
41154
- const shouldPlaceLogoFirst = placement === "left" || placement === "above";
41155
- const baseClass = shouldPlaceLogoFirst ? "rb-flex rb-w-full rb-flex-col rb-items-start rb-justify-end rb-gap-8 rb-md-flex-row rb-md-items-end" : "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";
41156
- return joinClasses([options.base ?? baseClass, shouldPlaceLogoFirst ? options.reverseClass ?? "rb-md-flex-row-reverse" : null]);
41157
- }
41158
- };
41159
41888
  const footerLogoClassTransform = {
41160
41889
  id: "layout.footerLogoClass",
41161
41890
  kind: "string",
41162
41891
  summary: "Compose split-footer logo wrapper classes from footer.logo controls",
41163
- schema: z.object({
41164
- base: z.string().optional(),
41165
- requireExplicitShow: z.boolean().optional()
41166
- }),
41892
+ schema: z.object({ base: z.string().optional() }),
41167
41893
  run: (value, options) => {
41168
- const logo = asPartialObject(value);
41169
- const align = logo?.align ?? "end";
41170
- const hiddenClass = options.requireExplicitShow ? logo?.showLogo === true ? null : "rb-hidden" : logo?.showLogo === false ? "rb-hidden" : null;
41894
+ const align = asPartialObject(value)?.align ?? "end";
41171
41895
  const selfAlignClass = align === "start" ? "rb-self-start rb-text-left" : align === "center" ? "rb-self-center rb-text-center" : "rb-self-end rb-text-right";
41172
- return joinClasses([
41173
- options.base ?? "footer-logo rb-inline-flex rb-items-center rb-justify-end rb-gap-3 rb-no-underline rb-transition-opacity rb-hover-opacity-80",
41174
- selfAlignClass,
41175
- hiddenClass
41176
- ]);
41177
- }
41178
- };
41179
- const footerLogoMediaClassTransform = {
41180
- id: "layout.footerLogoMediaClass",
41181
- kind: "string",
41182
- summary: "Compose footer logo image classes from size controls",
41183
- schema: z.object({ base: z.string().optional() }),
41184
- run: (_value, options) => {
41185
- return joinClasses([options.base ?? "rb-w-auto"]);
41186
- }
41187
- };
41188
- function shouldShowFooterLogoText(footer) {
41189
- if (!footer) return false;
41190
- const explicit = footer.logo?.showLogoText;
41191
- const legacy = footer.showLogoText === true;
41192
- return explicit === true || explicit === void 0 && legacy;
41193
- }
41194
- const footerLogoTextVisibleTransform = {
41195
- id: "layout.footerLogoTextVisible",
41196
- kind: "formatter",
41197
- summary: "Return whether footer logo text should render",
41198
- run: (value) => {
41199
- return shouldShowFooterLogoText(asPartialObject(value));
41896
+ return joinClasses([options.base ?? "footer-logo rb-inline-flex rb-items-center rb-justify-end rb-gap-3 rb-no-underline rb-transition-opacity rb-hover-opacity-80", selfAlignClass]);
41200
41897
  }
41201
41898
  };
41202
41899
  function extractBackgroundColorToken(background, fallback) {
@@ -41215,13 +41912,12 @@ const layoutTransforms = [
41215
41912
  headerRootStyleTransform,
41216
41913
  headerSectionBackgroundTransform,
41217
41914
  footerRootStyleTransform,
41915
+ footerModuleInkStyleTransform,
41916
+ footerBrandArrangementTransform,
41218
41917
  footerBottomBarClassTransform,
41219
41918
  footerBottomBarContainerClassTransform,
41220
41919
  footerBottomBarStyleTransform,
41221
- footerSplitMainClassTransform,
41222
- footerLogoClassTransform,
41223
- footerLogoMediaClassTransform,
41224
- footerLogoTextVisibleTransform
41920
+ footerLogoClassTransform
41225
41921
  ];
41226
41922
  //#endregion
41227
41923
  //#region ../blocks/src/system/transforms/registry/chromeLogo.ts
@@ -41720,7 +42416,14 @@ const footerNavGroupsLayout = stack({
41720
42416
  }, [text({
41721
42417
  as: "h3",
41722
42418
  className: "rb-label",
41723
- style: textColorStyle("text/70")
42419
+ "data-slot": { $bind: { from: "content.footerRuntime.slots.group-label" } },
42420
+ style: { $bind: {
42421
+ from: "content.footerRuntime.arrangement",
42422
+ transforms: [{
42423
+ id: "layout.footerModuleInkStyle",
42424
+ options: { opacity: 70 }
42425
+ }]
42426
+ } }
41724
42427
  }, when("group.label"), bind("group.label")), stack({
41725
42428
  gap: "sm",
41726
42429
  align: "start",
@@ -41750,6 +42453,14 @@ const footerMailingListBindings = {
41750
42453
  targeting: { $bind: { from: "module.engagement.runtime.targeting" } }
41751
42454
  };
41752
42455
  const footerSpamProtectionBinding = { spamProtectionEnabled: { $bind: { from: "$root.spamProtectionEnabled" } } };
42456
+ const brandMedia = media({ className: "rb-h-10 rb-w-auto" }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content", { transforms: [{
42457
+ id: "layout.chromeLogo",
42458
+ options: { surface: "footer-root" }
42459
+ }] }));
42460
+ const brandTitle = text({
42461
+ as: "strong",
42462
+ className: "footer-logo-text rb-nav-text"
42463
+ }, when("module.showTitle", { equals: true }), bind("site.title", { fallback: "Your Site" }));
41753
42464
  const brandLogo = link({
41754
42465
  href: "/",
41755
42466
  className: { $bind: {
@@ -41760,20 +42471,39 @@ const brandLogo = link({
41760
42471
  }],
41761
42472
  fallback: "footer-logo rb-inline-flex rb-items-center rb-gap-3 rb-no-underline"
41762
42473
  } }
41763
- }, [media({ className: { $bind: {
41764
- from: "$root.theme.footer.logo",
41765
- transforms: [{
41766
- id: "layout.footerLogoMediaClass",
41767
- options: { base: "rb-h-10 rb-w-auto" }
41768
- }],
41769
- fallback: "rb-h-10 rb-w-auto"
41770
- } } }, when("module.showLogo", { equals: true }), when("content.logo"), bind("content", { transforms: [{
41771
- id: "layout.chromeLogo",
41772
- options: { surface: "footer-root" }
41773
- }] })), text({
41774
- as: "strong",
41775
- className: "footer-logo-text rb-nav-text"
41776
- }, when("module.showTitle", { equals: true }), bind("site.title", { fallback: "Your Site" }))], when("module.kind", { equals: "brand" }));
42474
+ }, [brandMedia, brandTitle], (node) => ({
42475
+ ...node,
42476
+ $when: {
42477
+ when: {
42478
+ from: "module",
42479
+ transforms: [{ id: "layout.footerBrandArrangement" }]
42480
+ },
42481
+ equals: "row"
42482
+ }
42483
+ }));
42484
+ const centredBrand = stack({
42485
+ gap: "md",
42486
+ align: "center"
42487
+ }, [link({
42488
+ href: "/",
42489
+ "data-slot": { $bind: { from: "module.slots.media" } },
42490
+ className: "footer-logo rb-inline-flex rb-items-center rb-no-underline"
42491
+ }, [brandMedia], when("module.slots.media")), {
42492
+ ...brandTitle,
42493
+ props: {
42494
+ ...brandTitle.props,
42495
+ "data-slot": { $bind: { from: "module.slots.heading" } }
42496
+ }
42497
+ }], (node) => ({
42498
+ ...node,
42499
+ $when: {
42500
+ when: {
42501
+ from: "module",
42502
+ transforms: [{ id: "layout.footerBrandArrangement" }]
42503
+ },
42504
+ equals: "centred"
42505
+ }
42506
+ }));
41777
42507
  const navigation = stack({
41778
42508
  gap: "md",
41779
42509
  className: "rb-w-full"
@@ -41798,14 +42528,18 @@ const address = text({
41798
42528
  }, when("module.kind", { equals: "business-address" }), bind("module.address"));
41799
42529
  const contact = stack({
41800
42530
  gap: "sm",
41801
- className: "rb-items-start"
42531
+ className: { $bind: {
42532
+ from: "module.contactClassName",
42533
+ fallback: "rb-items-start"
42534
+ } }
41802
42535
  }, [link({
41803
42536
  href: { $bind: { from: "contactLink.href" } },
41804
42537
  className: "rb-nav-text rb-break-words transition-theme-standard"
41805
42538
  }, [text({ as: "span" }, bind("contactLink.label"))], repeat("module.contactLinks", "contactLink"))], when("module.kind", { equals: "contact" }));
41806
42539
  const hours = stack({
41807
42540
  gap: "sm",
41808
- className: "rb-w-full"
42541
+ className: "rb-w-full",
42542
+ "data-slot": { $bind: { from: "module.slots.schedule" } }
41809
42543
  }, [inline({ className: "rb-flex rb-w-full rb-justify-between rb-gap-4" }, [text({
41810
42544
  as: "span",
41811
42545
  className: "rb-label"
@@ -41816,7 +42550,10 @@ const hours = stack({
41816
42550
  as: "p",
41817
42551
  className: "rb-caption rb-opacity-70"
41818
42552
  }, bind("module.timeZone"), when("module.timeZone"))], when("module.kind", { equals: "opening-hours" }));
41819
- const socials = inline({ className: "rb-footer-socials" }, [link({
42553
+ const socials = inline({
42554
+ className: "rb-footer-socials",
42555
+ "data-slot": { $bind: { from: "module.slots.social" } }
42556
+ }, [link({
41820
42557
  href: { $bind: { from: "social.href" } },
41821
42558
  target: "_blank",
41822
42559
  rel: "noreferrer noopener",
@@ -41825,7 +42562,14 @@ const socials = inline({ className: "rb-footer-socials" }, [link({
41825
42562
  }, [icon({ className: "rb-footer-social-icon" }, 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" }));
41826
42563
  const authoredCopy = richText({
41827
42564
  className: "rb-prose rb-prose-sm rb-max-w-none",
41828
- style: textColorStyle("text/80")
42565
+ "data-slot": { $bind: { from: "module.slots.copy" } },
42566
+ style: { $bind: {
42567
+ from: "content.footerRuntime.arrangement",
42568
+ transforms: [{
42569
+ id: "layout.footerModuleInkStyle",
42570
+ options: { opacity: 80 }
42571
+ }]
42572
+ } }
41829
42573
  }, when("module.content"), bind("module.content", { transforms: [{
41830
42574
  id: "content.interpolateRichTextTokens",
41831
42575
  options: { tokens: ["year", "site_name"] }
@@ -41863,27 +42607,44 @@ const platformAttribution = el("div", {
41863
42607
  ], when("module.kind", { equals: "attribution" }));
41864
42608
  const footerGroup = stack({
41865
42609
  gap: "md",
41866
- align: "stretch",
42610
+ align: { $bind: {
42611
+ from: "group.align",
42612
+ fallback: "stretch"
42613
+ } },
41867
42614
  className: { $bind: {
41868
42615
  from: "group.className",
41869
42616
  fallback: "rb-min-w-0"
41870
42617
  } },
42618
+ "data-slot": { $bind: { from: "group.slot" } },
41871
42619
  "data-footer-group": { $bind: { from: "group.kind" } }
41872
42620
  }, [stack({
41873
42621
  gap: "md",
41874
- align: "start",
42622
+ align: { $bind: {
42623
+ from: "module.align",
42624
+ fallback: "start"
42625
+ } },
42626
+ className: { $bind: { from: "module.className" } },
41875
42627
  "data-preview-footer-module-id": { $bind: { from: "module.id" } }
41876
42628
  }, [
41877
42629
  text({
41878
42630
  as: "h2",
41879
42631
  className: "rb-label",
41880
- style: textColorStyle("text/70")
42632
+ "data-slot": { $bind: { from: "module.slots.group-label" } },
42633
+ style: { $bind: {
42634
+ from: "content.footerRuntime.arrangement",
42635
+ transforms: [{
42636
+ id: "layout.footerModuleInkStyle",
42637
+ options: { opacity: 70 }
42638
+ }]
42639
+ } }
41881
42640
  }, bind("module.heading"), when("module.heading")),
41882
42641
  brandLogo,
42642
+ centredBrand,
41883
42643
  navigation,
41884
42644
  stack({
41885
42645
  gap: "sm",
41886
- className: "rb-w-full"
42646
+ className: "rb-w-full",
42647
+ "data-slot": { $bind: { from: "module.slots.navigation" } }
41887
42648
  }, [legalNavigation], when("module.kind", { equals: "legal-navigation" })),
41888
42649
  address,
41889
42650
  contact,
@@ -41896,10 +42657,12 @@ const footerGroup = stack({
41896
42657
  ], repeat("group.modules", "module"))], repeat("region.groups", "group"));
41897
42658
  const footerMainRegion = stack({
41898
42659
  className: { $bind: { from: "region.className" } },
42660
+ "data-slot": { $bind: { from: "region.slot" } },
41899
42661
  "data-footer-region": { $bind: { from: "region.kind" } }
41900
42662
  }, [footerGroup], when("region.kind", { equals: "main" }), repeat("content.footerRuntime.regions", "region"));
41901
42663
  const footerEngagementRegion = stack({
41902
42664
  className: { $bind: { from: "region.className" } },
42665
+ "data-slot": { $bind: { from: "region.slot" } },
41903
42666
  "data-footer-region": "engagement-row"
41904
42667
  }, [footerGroup], when("region.kind", { equals: "engagement-row" }), repeat("content.footerRuntime.regions", "region"));
41905
42668
  const footerBottomRegion = stack({ className: { $bind: {
@@ -41916,6 +42679,7 @@ const footerBottomRegion = stack({ className: { $bind: {
41916
42679
  from: "$root.theme.footer",
41917
42680
  transforms: [{ id: "layout.footerBottomBarStyle" }]
41918
42681
  } },
42682
+ "data-slot": { $bind: { from: "region.slot" } },
41919
42683
  "data-footer-region": "bottom"
41920
42684
  }, [footerGroup])], when("region.kind", { equals: "bottom" }), repeat("content.footerRuntime.regions", "region"));
41921
42685
  const siteFooterBlockDefinition = { manifest: createBlockManifest({
@@ -41937,6 +42701,7 @@ const siteFooterBlockDefinition = { manifest: createBlockManifest({
41937
42701
  transforms: [{ id: "layout.footerRootStyle" }],
41938
42702
  fallback: mergeStyles(backgroundColorStyle("surface"), surfaceForegroundStyle({ text: "rgb(var(--tb-text))" }), borderColorStyle("border"))
41939
42703
  } },
42704
+ "data-arrangement": { $bind: { from: "content.footerRuntime.arrangementHook" } },
41940
42705
  "data-footer-membership": { $bind: { from: "content.footerRuntime.membershipKey" } }
41941
42706
  }, [
41942
42707
  footerEngagementRegion,
@@ -43538,17 +44303,30 @@ const mediaTextBlockDefinition = { manifest: createBlockManifest({
43538
44303
  }],
43539
44304
  fallback: ""
43540
44305
  } };
43541
- const copyHeading = el("div", { className: titleClassNameFromAlignment }, [text({
44306
+ const copyHeading = el("div", {
44307
+ className: titleClassNameFromAlignment,
44308
+ ...lookSlot("head")
44309
+ }, [text({
43542
44310
  as: "p",
43543
- className: eyebrowClassName("rb-eyebrow heading-eyebrow")
43544
- }, when("content.eyebrow"), bind("content.eyebrow")), text({ as: "h2" }, bind("content.title"))], when("content.title"));
43545
- const defaultTextColumn = el("div", {}, [styledCard([richText({ className: "rb-prose rb-max-w-none" }, bind("content.text"))], mediaTextCardOptions, when("content.wrapTextInCard")), richText({ className: "rb-prose rb-max-w-none" }, when("content.wrapTextInCard", { not: true }), bind("content.text"))]);
43546
- const bioTextColumn = el("div", { className: "rb-flex rb-h-full rb-w-full rb-max-w-prose rb-flex-col rb-justify-center rb-gap-5" }, [
43547
- copyHeading,
43548
- styledCard([richText({ className: bodyClassNameFromAlignment }, bind("content.text"))], mediaTextCardOptions, when("content.wrapTextInCard")),
43549
- richText({ className: bodyClassNameFromAlignment }, when("content.wrapTextInCard", { not: true }), bind("content.text"))
43550
- ]);
44311
+ className: eyebrowClassName("rb-eyebrow heading-eyebrow"),
44312
+ ...lookSlot("eyebrow")
44313
+ }, when("content.eyebrow"), bind("content.eyebrow")), text({
44314
+ as: "h2",
44315
+ ...lookSlot("heading")
44316
+ }, bind("content.title"))], when("content.title"));
44317
+ const textContentNodes = (className) => {
44318
+ const props = {
44319
+ className,
44320
+ ...lookSlot("intro"),
44321
+ leadParagraphSlot: { $bind: { from: "content._lookSlots.lede" } },
44322
+ lookSlots: { $bind: { from: "content._lookSlots" } }
44323
+ };
44324
+ return [styledCard([richText(props, bind("content.text"))], mediaTextCardOptions, when("content.wrapTextInCard")), richText(props, when("content.wrapTextInCard", { not: true }), bind("content.text"))];
44325
+ };
44326
+ const defaultTextColumn = el("div", {}, textContentNodes("rb-prose rb-max-w-none"));
44327
+ const bioTextColumn = el("div", { className: "rb-flex rb-h-full rb-w-full rb-max-w-prose rb-flex-col rb-justify-center rb-gap-5" }, [copyHeading, ...textContentNodes(bodyClassNameFromAlignment)]);
43551
44328
  const defaultImageCommonProps = {
44329
+ ...lookSlot("photo"),
43552
44330
  className: { $bind: {
43553
44331
  from: "content.imageShape",
43554
44332
  transforms: [{
@@ -43588,6 +44366,7 @@ const mediaTextBlockDefinition = { manifest: createBlockManifest({
43588
44366
  slidesToShow: 1
43589
44367
  }, [media(defaultImageCommonProps, bind("item.image"), repeat("content.images", "item"))]);
43590
44368
  const defaultImagesLayout = el("div", {}, [responsiveTwoColumn({
44369
+ lookSlots: true,
43591
44370
  image: el("div", {}, [el("div", {}, [defaultSingleImage], whenImagesLength(1)), el("div", {}, [defaultCarouselImages], whenImagesLength(1, { not: true }))]),
43592
44371
  text: defaultTextColumn,
43593
44372
  ratioFrom: "content.ratio",
@@ -43599,6 +44378,7 @@ const mediaTextBlockDefinition = { manifest: createBlockManifest({
43599
44378
  textWrapperClassName: "rb-w-full rb-min-w-0 rb-flex-1"
43600
44379
  })], whenImagesLength(0, { not: true }));
43601
44380
  const bioImagesLayout = el("div", {}, [responsiveTwoColumn({
44381
+ lookSlots: true,
43602
44382
  image: el("div", {}, [el("div", {}, [defaultSingleImage], whenImagesLength(1)), el("div", {}, [defaultCarouselImages], whenImagesLength(1, { not: true }))]),
43603
44383
  text: bioTextColumn,
43604
44384
  ratioFrom: "content.ratio",
@@ -43609,15 +44389,15 @@ const mediaTextBlockDefinition = { manifest: createBlockManifest({
43609
44389
  imageWrapperClassName: "rb-w-full rb-shrink-0",
43610
44390
  textWrapperClassName: "rb-w-full rb-min-w-0 rb-flex-1 rb-self-stretch"
43611
44391
  })], whenImagesLength(0, { not: true }));
43612
- const defaultTextOnlyLayout = el("div", {}, [styledCard([richText({ className: "rb-prose rb-max-w-none" }, bind("content.text"))], mediaTextCardOptions, when("content.wrapTextInCard")), richText({ className: "rb-prose rb-max-w-none" }, when("content.wrapTextInCard", { not: true }), bind("content.text"))], whenImagesLength(0));
43613
- const bioTextOnlyLayout = el("div", { className: "rb-flex rb-w-full rb-max-w-prose rb-flex-col rb-gap-5" }, [
43614
- text({
43615
- as: "h2",
43616
- className: titleClassNameFromAlignment
43617
- }, when("content.title"), bind("content.title")),
43618
- styledCard([richText({ className: bodyClassNameFromAlignment }, bind("content.text"))], mediaTextCardOptions, when("content.wrapTextInCard")),
43619
- richText({ className: bodyClassNameFromAlignment }, when("content.wrapTextInCard", { not: true }), bind("content.text"))
43620
- ], whenImagesLength(0));
44392
+ const defaultTextOnlyLayout = el("div", lookSlot("copy"), textContentNodes("rb-prose rb-max-w-none"), whenImagesLength(0));
44393
+ const bioTextOnlyLayout = el("div", {
44394
+ className: "rb-flex rb-w-full rb-max-w-prose rb-flex-col rb-gap-5",
44395
+ ...lookSlot("copy")
44396
+ }, [text({
44397
+ as: "h2",
44398
+ className: titleClassNameFromAlignment,
44399
+ ...lookSlot("heading")
44400
+ }, when("content.title"), bind("content.title")), ...textContentNodes(bodyClassNameFromAlignment)], whenImagesLength(0));
43621
44401
  const defaultInner = el("div", {}, [defaultImagesLayout, defaultTextOnlyLayout]);
43622
44402
  const bioInner = el("div", {}, [bioImagesLayout, bioTextOnlyLayout]);
43623
44403
  const defaultLayout = styledSection({
@@ -43641,9 +44421,31 @@ const mediaTextBlockDefinition = { manifest: createBlockManifest({
43641
44421
  }),
43642
44422
  baseClass: "",
43643
44423
  spacing: "medium"
44424
+ }),
44425
+ "circle-beside": styledSection({
44426
+ baseClass: "",
44427
+ spacing: "medium",
44428
+ children: styledContainer({ children: el("div", lookSlot("frame"), [el("div", lookSlot("media"), [
44429
+ el("div", {}, [when("content.images[0].image")(defaultSingleImage)], whenImagesLength(1)),
44430
+ el("div", {}, [el("div", {}, [defaultCarouselImages], whenImagesLength(1, { not: true }))], whenImagesLength(0, { not: true })),
44431
+ el("div", {}, [when("content.images[0].image")(defaultSingleImage)], whenImagesLength(0))
44432
+ ]), el("div", lookSlot("copy"), [el("div", lookSlot("head"), [text({
44433
+ as: "p",
44434
+ className: eyebrowClassName("rb-eyebrow heading-eyebrow"),
44435
+ ...lookSlot("eyebrow")
44436
+ }, when("content.eyebrow"), bind("content.eyebrow")), text({
44437
+ as: "h2",
44438
+ ...lookSlot("heading")
44439
+ }, bind("content.title"), when("content.title", { authoringPresence: {
44440
+ kind: "recover-empty-when-active",
44441
+ placeholder: "Add heading"
44442
+ } }))]), defaultTextColumn])]) })
43644
44443
  })
43645
44444
  },
43646
- variantMeaning: { kind: "arrangement" },
44445
+ variantMeaning: {
44446
+ kind: "arrangement",
44447
+ lookOnlyKeys: ["circle-beside"]
44448
+ },
43647
44449
  defaultVariant: "default",
43648
44450
  variantOptions: {
43649
44451
  default: { label: "Default" },
@@ -44670,24 +45472,6 @@ const emptyStateField = {
44670
45472
  ui: { intent: "display" }
44671
45473
  };
44672
45474
  /**
44673
- * Section heading and description fields
44674
- */
44675
- const sectionHeaderFields = (defaultHeading) => [{
44676
- id: "heading",
44677
- type: "text",
44678
- label: "Heading",
44679
- description: "Main heading for the events section",
44680
- required: false,
44681
- multiline: false,
44682
- defaultValue: defaultHeading
44683
- }, {
44684
- id: "description",
44685
- type: "richText",
44686
- label: "Description",
44687
- description: "Optional introductory text",
44688
- required: false
44689
- }];
44690
- /**
44691
45475
  * Layout selection field with grid/stack options
44692
45476
  */
44693
45477
  const layoutField = {
@@ -44800,31 +45584,6 @@ function normalizeEventStaffMemberId(value) {
44800
45584
  return trimmed ? trimmed : null;
44801
45585
  }
44802
45586
  //#endregion
44803
- //#region ../blocks/src/system/blocks/events/shared/layout.ts
44804
- const recoverEmptyHeadingWhenActive = {
44805
- kind: "recover-empty-when-active",
44806
- placeholder: "Add heading"
44807
- };
44808
- const recoverEmptyDescriptionWhenActive = {
44809
- kind: "recover-empty-when-active",
44810
- placeholder: "Add description"
44811
- };
44812
- function eventSectionHeaderLayoutNodes(options = {}) {
44813
- const headingNode = text({
44814
- as: "h2",
44815
- ...lookSlot("heading")
44816
- }, bind("content.heading"), when("content.heading", { authoringPresence: recoverEmptyHeadingWhenActive }));
44817
- const descriptionNode = richText({
44818
- className: "rb-prose rb-max-w-none",
44819
- ...lookSlot("intro")
44820
- }, bind("content.description"), when("content.description", { authoringPresence: recoverEmptyDescriptionWhenActive }));
44821
- if (options.splitClassName) return [el("div", {
44822
- className: options.splitClassName,
44823
- ...lookSlot("head")
44824
- }, [headingNode, descriptionNode])];
44825
- return [headingNode, descriptionNode];
44826
- }
44827
- //#endregion
44828
45587
  //#region ../blocks/src/system/blocks/shop.shared.ts
44829
45588
  /**
44830
45589
  * Public pass product for shop display
@@ -45249,19 +46008,14 @@ function buildCalendarViewport(input) {
45249
46008
  *
45250
46009
  * Sites don't store a locale, and every public word around a date is English,
45251
46010
  * so the only open question is which English conventions to follow: day or
45252
- * month first, and a 24 or 12-hour clock. The site's time zone is the one
46011
+ * month first. The site's time zone is the one
45253
46012
  * fact every site carries about where it is. It is the site's, never an
45254
46013
  * event's: a venue left at UTC must not turn a UK site's dates American.
45255
46014
  * Anywhere this can't place (UTC, the Americas, Asia) keeps US English, which
45256
46015
  * is what these helpers wrote before sites were placed at all.
45257
46016
  */
45258
46017
  function eventDateLocale(siteTimeZone) {
45259
- if (!siteTimeZone) return "en-US";
45260
- if (siteTimeZone === "Europe/Dublin") return "en-IE";
45261
- if (siteTimeZone.startsWith("Europe/")) return "en-GB";
45262
- if (siteTimeZone.startsWith("Australia/")) return "en-AU";
45263
- if (siteTimeZone === "Pacific/Auckland" || siteTimeZone === "Pacific/Chatham") return "en-NZ";
45264
- return "en-US";
46018
+ return inferSiteDateLocale(siteTimeZone);
45265
46019
  }
45266
46020
  function formatEventCompactDateRail(isoTimestamp, options, letterCase = "capitals") {
45267
46021
  const locale = options?.locale ?? "en-US";
@@ -46871,7 +47625,7 @@ const eventSpotlightBlockDefinition = {
46871
47625
  ],
46872
47626
  icon: "Star",
46873
47627
  layout: [styledSection({
46874
- children: sectionContainer([...eventSectionHeaderLayoutNodes(), el("event-spotlight", {
47628
+ children: sectionContainer([...sectionHeaderLayoutNodes(), el("event-spotlight", {
46875
47629
  events: { $bind: { from: "data.events" } },
46876
47630
  layout: { $bind: {
46877
47631
  from: "content.layout",
@@ -46927,52 +47681,6 @@ const eventSpotlightBlockDefinition = {
46927
47681
  } }
46928
47682
  };
46929
47683
  //#endregion
46930
- //#region ../blocks/src/system/runtime/lookSurfaces.ts
46931
- const isPlainObject$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
46932
- const lookListPresentationSchemaShape = {
46933
- sectionAction: z.object({
46934
- label: z.string(),
46935
- href: z.string()
46936
- }).optional(),
46937
- actionSize: z.enum([
46938
- "sm",
46939
- "md",
46940
- "lg"
46941
- ]).optional(),
46942
- itemActionStyle: z.enum(["button", "link"]).optional(),
46943
- itemRoles: z.object({
46944
- container: z.enum([
46945
- "card",
46946
- "statement",
46947
- "highlight"
46948
- ]).optional(),
46949
- items: z.enum([
46950
- "card",
46951
- "statement",
46952
- "highlight"
46953
- ]).optional(),
46954
- at: z.partialRecord(z.enum([
46955
- "first",
46956
- "last",
46957
- "middle",
46958
- "odd",
46959
- "even"
46960
- ]), z.enum([
46961
- "card",
46962
- "statement",
46963
- "highlight"
46964
- ])).optional()
46965
- }).optional(),
46966
- roleSurfaces: z.record(z.enum([
46967
- "card",
46968
- "statement",
46969
- "highlight"
46970
- ]), z.custom((value) => isPlainObject$1(value) && (value.kind === "inherit" || value.kind === "owned"))).optional(),
46971
- panelHeading: z.string().optional(),
46972
- lookSlots: z.partialRecord(z.enum(arrangementSlotNames), z.enum(arrangementSlotNames)).optional(),
46973
- itemSurfaces: z.record(z.string(), z.custom((value) => isPlainObject$1(value) && (value.kind === "inherit" || value.kind === "owned"))).optional()
46974
- };
46975
- //#endregion
46976
47684
  //#region ../blocks/src/system/blocks/events/shared/eventSelection.ts
46977
47685
  /** Invalid saved selections fail closed rather than widening discovery. */
46978
47686
  function resolveEventSelection(mode, value) {
@@ -47747,7 +48455,7 @@ const eventListingBlockDefinition = {
47747
48455
  children: styledContainer({
47748
48456
  rootType: "stack",
47749
48457
  rootProps: { gap: "lg" },
47750
- children: [...eventSectionHeaderLayoutNodes(), el("event-listing", withApiBindings({
48458
+ children: [...sectionHeaderLayoutNodes(), el("event-listing", withApiBindings({
47751
48459
  readAuthority: { $bind: { from: "$root.readAuthority" } },
47752
48460
  events: { $bind: { from: "data.events" } },
47753
48461
  stage: { $bind: {
@@ -48187,7 +48895,7 @@ const eventCalendarLayout = [styledSection({
48187
48895
  gap: "lg",
48188
48896
  ...lookSlot("layout")
48189
48897
  },
48190
- children: [...eventSectionHeaderLayoutNodes({ splitClassName: "event-section-head event-section-head--split" }), el("event-calendar", withApiBindings({
48898
+ children: [...sectionHeaderLayoutNodes({ splitClassName: "event-section-head event-section-head--split" }), el("event-calendar", withApiBindings({
48191
48899
  readAuthority: { $bind: { from: "$root.readAuthority" } },
48192
48900
  events: { $bind: { from: "data.events" } },
48193
48901
  effectiveListArrangementKey: { $bind: { from: "$root.effectiveListArrangementKey" } },
@@ -50367,6 +51075,511 @@ const embedBlockDefinition = {
50367
51075
  } }
50368
51076
  };
50369
51077
  //#endregion
51078
+ //#region ../blocks/src/system/blocks/image-gallery/fields.ts
51079
+ const imageGalleryFields = parseFieldDefinitions([
51080
+ ...sectionHeaderFields(void 0, "Intro"),
51081
+ {
51082
+ id: "images",
51083
+ type: "repeater",
51084
+ label: "Images",
51085
+ itemLabel: "Image",
51086
+ minItems: 0,
51087
+ maxItems: 24,
51088
+ ui: {
51089
+ repeaterPreset: "thumbnailGrid",
51090
+ thumbnailField: "image",
51091
+ thumbnailAltField: "caption",
51092
+ thumbnailLabelField: "caption",
51093
+ thumbnailCardDensity: "compact"
51094
+ },
51095
+ schema: { fields: [{
51096
+ id: "image",
51097
+ type: "media",
51098
+ label: "Image",
51099
+ required: true,
51100
+ mediaKinds: ["image"]
51101
+ }, {
51102
+ id: "caption",
51103
+ type: "text",
51104
+ label: "Caption",
51105
+ description: "Optional caption displayed below the image and used as the editor card label",
51106
+ maxLength: 200
51107
+ }] }
51108
+ },
51109
+ {
51110
+ id: "fullBleed",
51111
+ type: "boolean",
51112
+ label: "Full bleed",
51113
+ description: "Extend the gallery edge-to-edge by removing section side padding and container max-width.",
51114
+ defaultValue: false,
51115
+ ui: {
51116
+ intent: "display",
51117
+ visibleWhen: {
51118
+ field: "variant",
51119
+ notIn: ["marquee"]
51120
+ }
51121
+ }
51122
+ },
51123
+ {
51124
+ id: "aspectRatio",
51125
+ type: "select",
51126
+ label: "Aspect ratio",
51127
+ description: "Crop images to a consistent aspect ratio.",
51128
+ defaultValue: "1/1",
51129
+ options: [
51130
+ {
51131
+ value: "auto",
51132
+ label: "Original"
51133
+ },
51134
+ {
51135
+ value: "1/1",
51136
+ label: "1:1 (Square)"
51137
+ },
51138
+ {
51139
+ value: "4/3",
51140
+ label: "4:3 (Standard)"
51141
+ },
51142
+ {
51143
+ value: "16/9",
51144
+ label: "16:9 (Widescreen)"
51145
+ },
51146
+ {
51147
+ value: "3/2",
51148
+ label: "3:2 (Classic)"
51149
+ },
51150
+ {
51151
+ value: "3/4",
51152
+ label: "3:4 (Portrait)"
51153
+ }
51154
+ ],
51155
+ ui: {
51156
+ intent: "display",
51157
+ visibleWhen: {
51158
+ field: "variant",
51159
+ notIn: ["masonry", "marquee"]
51160
+ }
51161
+ }
51162
+ },
51163
+ {
51164
+ id: "slidesToShow",
51165
+ type: "select",
51166
+ label: "Images per view (mobile)",
51167
+ description: "Number of images visible at once on small screens.",
51168
+ defaultValue: "1",
51169
+ options: [
51170
+ {
51171
+ value: "1",
51172
+ label: "One at a time"
51173
+ },
51174
+ {
51175
+ value: "2",
51176
+ label: "Two at a time"
51177
+ },
51178
+ {
51179
+ value: "3",
51180
+ label: "Three at a time"
51181
+ }
51182
+ ],
51183
+ ui: {
51184
+ intent: "display",
51185
+ visibleWhen: {
51186
+ field: "variant",
51187
+ equals: "carousel"
51188
+ }
51189
+ }
51190
+ },
51191
+ {
51192
+ id: "slidesToShowTablet",
51193
+ type: "select",
51194
+ label: "Images per view (tablet)",
51195
+ description: "Number of images visible on medium screens.",
51196
+ options: [
51197
+ {
51198
+ value: "",
51199
+ label: "Same as mobile"
51200
+ },
51201
+ {
51202
+ value: "1",
51203
+ label: "One at a time"
51204
+ },
51205
+ {
51206
+ value: "2",
51207
+ label: "Two at a time"
51208
+ },
51209
+ {
51210
+ value: "3",
51211
+ label: "Three at a time"
51212
+ }
51213
+ ],
51214
+ ui: {
51215
+ intent: "display",
51216
+ visibleWhen: {
51217
+ field: "variant",
51218
+ equals: "carousel"
51219
+ }
51220
+ }
51221
+ },
51222
+ {
51223
+ id: "slidesToShowDesktop",
51224
+ type: "select",
51225
+ label: "Images per view (desktop)",
51226
+ description: "Number of images visible on large screens.",
51227
+ options: [
51228
+ {
51229
+ value: "",
51230
+ label: "Same as tablet"
51231
+ },
51232
+ {
51233
+ value: "1",
51234
+ label: "One at a time"
51235
+ },
51236
+ {
51237
+ value: "2",
51238
+ label: "Two at a time"
51239
+ },
51240
+ {
51241
+ value: "3",
51242
+ label: "Three at a time"
51243
+ }
51244
+ ],
51245
+ ui: {
51246
+ intent: "display",
51247
+ visibleWhen: {
51248
+ field: "variant",
51249
+ equals: "carousel"
51250
+ }
51251
+ }
51252
+ },
51253
+ {
51254
+ id: "transition",
51255
+ type: "select",
51256
+ label: "Transition",
51257
+ description: "Animation style between slides.",
51258
+ defaultValue: "slide",
51259
+ options: [{
51260
+ value: "slide",
51261
+ label: "Slide"
51262
+ }, {
51263
+ value: "fade",
51264
+ label: "Fade"
51265
+ }],
51266
+ ui: {
51267
+ intent: "display",
51268
+ visibleWhen: {
51269
+ field: "variant",
51270
+ equals: "carousel"
51271
+ }
51272
+ }
51273
+ },
51274
+ {
51275
+ id: "showControls",
51276
+ type: "boolean",
51277
+ label: "Show arrows",
51278
+ defaultValue: true,
51279
+ ui: {
51280
+ intent: "behavior",
51281
+ visibleWhen: {
51282
+ field: "variant",
51283
+ equals: "carousel"
51284
+ }
51285
+ }
51286
+ },
51287
+ {
51288
+ id: "showDots",
51289
+ type: "boolean",
51290
+ label: "Show dots",
51291
+ defaultValue: false,
51292
+ ui: {
51293
+ intent: "behavior",
51294
+ visibleWhen: {
51295
+ field: "variant",
51296
+ equals: "carousel"
51297
+ }
51298
+ }
51299
+ },
51300
+ {
51301
+ id: "autoplay",
51302
+ type: "boolean",
51303
+ label: "Autoplay",
51304
+ defaultValue: false,
51305
+ ui: {
51306
+ intent: "behavior",
51307
+ visibleWhen: {
51308
+ field: "variant",
51309
+ equals: "carousel"
51310
+ }
51311
+ }
51312
+ },
51313
+ {
51314
+ id: "autoplayDelay",
51315
+ type: "select",
51316
+ label: "Autoplay delay",
51317
+ defaultValue: "5000",
51318
+ options: [
51319
+ {
51320
+ value: "3000",
51321
+ label: "3 seconds"
51322
+ },
51323
+ {
51324
+ value: "5000",
51325
+ label: "5 seconds"
51326
+ },
51327
+ {
51328
+ value: "7000",
51329
+ label: "7 seconds"
51330
+ },
51331
+ {
51332
+ value: "10000",
51333
+ label: "10 seconds"
51334
+ }
51335
+ ],
51336
+ ui: {
51337
+ intent: "behavior",
51338
+ visibleWhen: {
51339
+ field: "variant",
51340
+ equals: "carousel"
51341
+ }
51342
+ }
51343
+ },
51344
+ {
51345
+ id: "arrowVisibility",
51346
+ type: "select",
51347
+ label: "Arrow visibility",
51348
+ defaultValue: "always",
51349
+ options: [{
51350
+ value: "always",
51351
+ label: "Always visible"
51352
+ }, {
51353
+ value: "hover",
51354
+ label: "Show on hover"
51355
+ }],
51356
+ ui: {
51357
+ intent: "behavior",
51358
+ visibleWhen: {
51359
+ field: "variant",
51360
+ equals: "carousel"
51361
+ }
51362
+ }
51363
+ },
51364
+ {
51365
+ id: "loop",
51366
+ type: "boolean",
51367
+ label: "Loop slides",
51368
+ defaultValue: true,
51369
+ ui: {
51370
+ intent: "behavior",
51371
+ visibleWhen: {
51372
+ field: "variant",
51373
+ equals: "carousel"
51374
+ }
51375
+ }
51376
+ },
51377
+ {
51378
+ id: "marqueeDirection",
51379
+ type: "select",
51380
+ label: "Scroll direction",
51381
+ options: [{
51382
+ value: "left",
51383
+ label: "Left"
51384
+ }, {
51385
+ value: "right",
51386
+ label: "Right"
51387
+ }],
51388
+ defaultValue: "left",
51389
+ ui: {
51390
+ intent: "display",
51391
+ visibleWhen: {
51392
+ field: "variant",
51393
+ equals: "marquee"
51394
+ }
51395
+ }
51396
+ },
51397
+ {
51398
+ id: "marqueeSpeed",
51399
+ type: "select",
51400
+ label: "Scroll speed",
51401
+ options: [
51402
+ {
51403
+ value: "slow",
51404
+ label: "Slow (60s)"
51405
+ },
51406
+ {
51407
+ value: "medium",
51408
+ label: "Medium (40s)"
51409
+ },
51410
+ {
51411
+ value: "fast",
51412
+ label: "Fast (20s)"
51413
+ }
51414
+ ],
51415
+ defaultValue: "medium",
51416
+ ui: {
51417
+ intent: "display",
51418
+ visibleWhen: {
51419
+ field: "variant",
51420
+ equals: "marquee"
51421
+ }
51422
+ }
51423
+ },
51424
+ {
51425
+ id: "marqueePauseOnHover",
51426
+ type: "boolean",
51427
+ label: "Pause on hover",
51428
+ defaultValue: true,
51429
+ ui: {
51430
+ intent: "behavior",
51431
+ visibleWhen: {
51432
+ field: "variant",
51433
+ equals: "marquee"
51434
+ }
51435
+ }
51436
+ },
51437
+ {
51438
+ id: "marqueeImageSize",
51439
+ type: "select",
51440
+ label: "Image size",
51441
+ options: [
51442
+ {
51443
+ value: "sm",
51444
+ label: "Small (200px)"
51445
+ },
51446
+ {
51447
+ value: "md",
51448
+ label: "Medium (256px)"
51449
+ },
51450
+ {
51451
+ value: "lg",
51452
+ label: "Large (320px)"
51453
+ },
51454
+ {
51455
+ value: "xl",
51456
+ label: "Extra large (400px)"
51457
+ }
51458
+ ],
51459
+ defaultValue: "md",
51460
+ ui: {
51461
+ intent: "display",
51462
+ visibleWhen: {
51463
+ field: "variant",
51464
+ equals: "marquee"
51465
+ }
51466
+ }
51467
+ },
51468
+ {
51469
+ id: "imageFilter",
51470
+ type: "select",
51471
+ label: "Image filter",
51472
+ options: [
51473
+ {
51474
+ value: "none",
51475
+ label: "None"
51476
+ },
51477
+ {
51478
+ value: "grayscale",
51479
+ label: "Grayscale"
51480
+ },
51481
+ {
51482
+ value: "grayscale-hover-reveal",
51483
+ label: "Grayscale (color on hover)"
51484
+ },
51485
+ {
51486
+ value: "sepia",
51487
+ label: "Sepia"
51488
+ }
51489
+ ],
51490
+ defaultValue: "grayscale-hover-reveal",
51491
+ ui: { intent: "style" }
51492
+ },
51493
+ {
51494
+ id: "imageBorder",
51495
+ type: "group",
51496
+ label: "Image border",
51497
+ schema: { fields: [
51498
+ {
51499
+ id: "enabled",
51500
+ type: "boolean",
51501
+ label: "Show border",
51502
+ defaultValue: true
51503
+ },
51504
+ {
51505
+ id: "colorToken",
51506
+ type: "text",
51507
+ label: "Border color",
51508
+ defaultValue: "accent",
51509
+ ui: { widget: "backgroundColor" }
51510
+ },
51511
+ {
51512
+ id: "opacity",
51513
+ type: "number",
51514
+ label: "Border opacity",
51515
+ defaultValue: 30,
51516
+ ui: {
51517
+ min: 0,
51518
+ max: 100
51519
+ }
51520
+ },
51521
+ {
51522
+ id: "width",
51523
+ type: "select",
51524
+ label: "Border width",
51525
+ options: [
51526
+ {
51527
+ value: "1",
51528
+ label: "Thin (1px)"
51529
+ },
51530
+ {
51531
+ value: "2",
51532
+ label: "Medium (2px)"
51533
+ },
51534
+ {
51535
+ value: "3",
51536
+ label: "Thick (3px)"
51537
+ }
51538
+ ],
51539
+ defaultValue: "2"
51540
+ }
51541
+ ] },
51542
+ ui: { intent: "style" }
51543
+ },
51544
+ {
51545
+ id: "imageCorners",
51546
+ type: "select",
51547
+ label: "Image corners",
51548
+ options: [
51549
+ {
51550
+ value: "none",
51551
+ label: "Square"
51552
+ },
51553
+ {
51554
+ value: "sm",
51555
+ label: "Slightly rounded"
51556
+ },
51557
+ {
51558
+ value: "md",
51559
+ label: "Rounded"
51560
+ },
51561
+ {
51562
+ value: "lg",
51563
+ label: "More rounded"
51564
+ },
51565
+ {
51566
+ value: "xl",
51567
+ label: "Very rounded"
51568
+ },
51569
+ {
51570
+ value: "2xl",
51571
+ label: "Extra rounded"
51572
+ },
51573
+ {
51574
+ value: "3xl",
51575
+ label: "Maximum rounded"
51576
+ }
51577
+ ],
51578
+ defaultValue: "3xl",
51579
+ ui: { intent: "style" }
51580
+ }
51581
+ ]);
51582
+ //#endregion
50370
51583
  //#region ../blocks/src/system/blocks/image-gallery.ts
50371
51584
  const grid$1 = (props, children, ...mods) => el("grid", props ?? void 0, children ?? void 0, ...mods);
50372
51585
  const galleryContainer = (children, opts) => {
@@ -50581,7 +51794,11 @@ const emptyState$1 = {
50581
51794
  }
50582
51795
  };
50583
51796
  const wrapVariant$1 = (layout, opts) => styledSection({
50584
- children: galleryContainer([layout, emptyState$1], {
51797
+ children: galleryContainer([
51798
+ ...sectionHeaderLayoutNodes(),
51799
+ layout,
51800
+ emptyState$1
51801
+ ], {
50585
51802
  gap: "md",
50586
51803
  fullWidth: opts?.fullWidth,
50587
51804
  className: opts?.className
@@ -50590,6 +51807,28 @@ const wrapVariant$1 = (layout, opts) => styledSection({
50590
51807
  spacing: "medium",
50591
51808
  background: "background"
50592
51809
  });
51810
+ const lookGalleryTile = (imageFrom, captionFrom, ...mods) => el("li", lookSlot("item"), [el("figure", lookSlot("figure"), [el("div", lookSlot("media"), [media(lookSlot("photo"), bind(imageFrom), when(imageFrom))]), text({
51811
+ as: "figcaption",
51812
+ ...lookSlot("caption")
51813
+ }, bind(captionFrom), when(captionFrom))])], ...mods);
51814
+ const tilesLayout = styledSection({
51815
+ children: el("div", {
51816
+ className: "rb-container",
51817
+ ...lookSlot("layout")
51818
+ }, [...sectionHeaderLayoutNodes({ splitClassName: "rb-grid" }), el("ol", lookSlot("items"), [lookGalleryTile("item.image", "item.caption", repeat("content.images", "item")), lookGalleryTile("content.images.0.image", "content.images.0.caption", (node) => ({
51819
+ ...node,
51820
+ $when: {
51821
+ when: {
51822
+ from: "content.images",
51823
+ transforms: [{ id: "array.length" }]
51824
+ },
51825
+ equals: 0
51826
+ }
51827
+ }))])]),
51828
+ baseClass: "",
51829
+ spacing: "medium",
51830
+ background: "background"
51831
+ });
50593
51832
  const imageGalleryBlockDefinition = { manifest: createBlockManifest({
50594
51833
  id: "block.image-gallery",
50595
51834
  title: "Image Gallery",
@@ -50602,510 +51841,10 @@ const imageGalleryBlockDefinition = { manifest: createBlockManifest({
50602
51841
  "marqueeSpeed",
50603
51842
  "marqueePauseOnHover"
50604
51843
  ] },
50605
- additionalFields: parseFieldDefinitions([
50606
- {
50607
- id: "images",
50608
- type: "repeater",
50609
- label: "Images",
50610
- itemLabel: "Image",
50611
- minItems: 0,
50612
- maxItems: 24,
50613
- ui: {
50614
- repeaterPreset: "thumbnailGrid",
50615
- thumbnailField: "image",
50616
- thumbnailAltField: "caption",
50617
- thumbnailLabelField: "caption",
50618
- thumbnailCardDensity: "compact"
50619
- },
50620
- schema: { fields: [{
50621
- id: "image",
50622
- type: "media",
50623
- label: "Image",
50624
- required: true,
50625
- mediaKinds: ["image"]
50626
- }, {
50627
- id: "caption",
50628
- type: "text",
50629
- label: "Caption",
50630
- description: "Optional caption displayed below the image and used as the editor card label",
50631
- maxLength: 200
50632
- }] }
50633
- },
50634
- {
50635
- id: "fullBleed",
50636
- type: "boolean",
50637
- label: "Full bleed",
50638
- description: "Extend the gallery edge-to-edge by removing section side padding and container max-width.",
50639
- defaultValue: false,
50640
- ui: {
50641
- intent: "display",
50642
- visibleWhen: {
50643
- field: "variant",
50644
- notIn: ["marquee"]
50645
- }
50646
- }
50647
- },
50648
- {
50649
- id: "aspectRatio",
50650
- type: "select",
50651
- label: "Aspect ratio",
50652
- description: "Crop images to a consistent aspect ratio.",
50653
- defaultValue: "1/1",
50654
- options: [
50655
- {
50656
- value: "auto",
50657
- label: "Original"
50658
- },
50659
- {
50660
- value: "1/1",
50661
- label: "1:1 (Square)"
50662
- },
50663
- {
50664
- value: "4/3",
50665
- label: "4:3 (Standard)"
50666
- },
50667
- {
50668
- value: "16/9",
50669
- label: "16:9 (Widescreen)"
50670
- },
50671
- {
50672
- value: "3/2",
50673
- label: "3:2 (Classic)"
50674
- },
50675
- {
50676
- value: "3/4",
50677
- label: "3:4 (Portrait)"
50678
- }
50679
- ],
50680
- ui: {
50681
- intent: "display",
50682
- visibleWhen: {
50683
- field: "variant",
50684
- notIn: ["masonry", "marquee"]
50685
- }
50686
- }
50687
- },
50688
- {
50689
- id: "slidesToShow",
50690
- type: "select",
50691
- label: "Images per view (mobile)",
50692
- description: "Number of images visible at once on small screens.",
50693
- defaultValue: "1",
50694
- options: [
50695
- {
50696
- value: "1",
50697
- label: "One at a time"
50698
- },
50699
- {
50700
- value: "2",
50701
- label: "Two at a time"
50702
- },
50703
- {
50704
- value: "3",
50705
- label: "Three at a time"
50706
- }
50707
- ],
50708
- ui: {
50709
- intent: "display",
50710
- visibleWhen: {
50711
- field: "variant",
50712
- equals: "carousel"
50713
- }
50714
- }
50715
- },
50716
- {
50717
- id: "slidesToShowTablet",
50718
- type: "select",
50719
- label: "Images per view (tablet)",
50720
- description: "Number of images visible on medium screens.",
50721
- options: [
50722
- {
50723
- value: "",
50724
- label: "Same as mobile"
50725
- },
50726
- {
50727
- value: "1",
50728
- label: "One at a time"
50729
- },
50730
- {
50731
- value: "2",
50732
- label: "Two at a time"
50733
- },
50734
- {
50735
- value: "3",
50736
- label: "Three at a time"
50737
- }
50738
- ],
50739
- ui: {
50740
- intent: "display",
50741
- visibleWhen: {
50742
- field: "variant",
50743
- equals: "carousel"
50744
- }
50745
- }
50746
- },
50747
- {
50748
- id: "slidesToShowDesktop",
50749
- type: "select",
50750
- label: "Images per view (desktop)",
50751
- description: "Number of images visible on large screens.",
50752
- options: [
50753
- {
50754
- value: "",
50755
- label: "Same as tablet"
50756
- },
50757
- {
50758
- value: "1",
50759
- label: "One at a time"
50760
- },
50761
- {
50762
- value: "2",
50763
- label: "Two at a time"
50764
- },
50765
- {
50766
- value: "3",
50767
- label: "Three at a time"
50768
- }
50769
- ],
50770
- ui: {
50771
- intent: "display",
50772
- visibleWhen: {
50773
- field: "variant",
50774
- equals: "carousel"
50775
- }
50776
- }
50777
- },
50778
- {
50779
- id: "transition",
50780
- type: "select",
50781
- label: "Transition",
50782
- description: "Animation style between slides.",
50783
- defaultValue: "slide",
50784
- options: [{
50785
- value: "slide",
50786
- label: "Slide"
50787
- }, {
50788
- value: "fade",
50789
- label: "Fade"
50790
- }],
50791
- ui: {
50792
- intent: "display",
50793
- visibleWhen: {
50794
- field: "variant",
50795
- equals: "carousel"
50796
- }
50797
- }
50798
- },
50799
- {
50800
- id: "showControls",
50801
- type: "boolean",
50802
- label: "Show arrows",
50803
- defaultValue: true,
50804
- ui: {
50805
- intent: "behavior",
50806
- visibleWhen: {
50807
- field: "variant",
50808
- equals: "carousel"
50809
- }
50810
- }
50811
- },
50812
- {
50813
- id: "showDots",
50814
- type: "boolean",
50815
- label: "Show dots",
50816
- defaultValue: false,
50817
- ui: {
50818
- intent: "behavior",
50819
- visibleWhen: {
50820
- field: "variant",
50821
- equals: "carousel"
50822
- }
50823
- }
50824
- },
50825
- {
50826
- id: "autoplay",
50827
- type: "boolean",
50828
- label: "Autoplay",
50829
- defaultValue: false,
50830
- ui: {
50831
- intent: "behavior",
50832
- visibleWhen: {
50833
- field: "variant",
50834
- equals: "carousel"
50835
- }
50836
- }
50837
- },
50838
- {
50839
- id: "autoplayDelay",
50840
- type: "select",
50841
- label: "Autoplay delay",
50842
- defaultValue: "5000",
50843
- options: [
50844
- {
50845
- value: "3000",
50846
- label: "3 seconds"
50847
- },
50848
- {
50849
- value: "5000",
50850
- label: "5 seconds"
50851
- },
50852
- {
50853
- value: "7000",
50854
- label: "7 seconds"
50855
- },
50856
- {
50857
- value: "10000",
50858
- label: "10 seconds"
50859
- }
50860
- ],
50861
- ui: {
50862
- intent: "behavior",
50863
- visibleWhen: {
50864
- field: "variant",
50865
- equals: "carousel"
50866
- }
50867
- }
50868
- },
50869
- {
50870
- id: "arrowVisibility",
50871
- type: "select",
50872
- label: "Arrow visibility",
50873
- defaultValue: "always",
50874
- options: [{
50875
- value: "always",
50876
- label: "Always visible"
50877
- }, {
50878
- value: "hover",
50879
- label: "Show on hover"
50880
- }],
50881
- ui: {
50882
- intent: "behavior",
50883
- visibleWhen: {
50884
- field: "variant",
50885
- equals: "carousel"
50886
- }
50887
- }
50888
- },
50889
- {
50890
- id: "loop",
50891
- type: "boolean",
50892
- label: "Loop slides",
50893
- defaultValue: true,
50894
- ui: {
50895
- intent: "behavior",
50896
- visibleWhen: {
50897
- field: "variant",
50898
- equals: "carousel"
50899
- }
50900
- }
50901
- },
50902
- {
50903
- id: "marqueeDirection",
50904
- type: "select",
50905
- label: "Scroll direction",
50906
- options: [{
50907
- value: "left",
50908
- label: "Left"
50909
- }, {
50910
- value: "right",
50911
- label: "Right"
50912
- }],
50913
- defaultValue: "left",
50914
- ui: {
50915
- intent: "display",
50916
- visibleWhen: {
50917
- field: "variant",
50918
- equals: "marquee"
50919
- }
50920
- }
50921
- },
50922
- {
50923
- id: "marqueeSpeed",
50924
- type: "select",
50925
- label: "Scroll speed",
50926
- options: [
50927
- {
50928
- value: "slow",
50929
- label: "Slow (60s)"
50930
- },
50931
- {
50932
- value: "medium",
50933
- label: "Medium (40s)"
50934
- },
50935
- {
50936
- value: "fast",
50937
- label: "Fast (20s)"
50938
- }
50939
- ],
50940
- defaultValue: "medium",
50941
- ui: {
50942
- intent: "display",
50943
- visibleWhen: {
50944
- field: "variant",
50945
- equals: "marquee"
50946
- }
50947
- }
50948
- },
50949
- {
50950
- id: "marqueePauseOnHover",
50951
- type: "boolean",
50952
- label: "Pause on hover",
50953
- defaultValue: true,
50954
- ui: {
50955
- intent: "behavior",
50956
- visibleWhen: {
50957
- field: "variant",
50958
- equals: "marquee"
50959
- }
50960
- }
50961
- },
50962
- {
50963
- id: "marqueeImageSize",
50964
- type: "select",
50965
- label: "Image size",
50966
- options: [
50967
- {
50968
- value: "sm",
50969
- label: "Small (200px)"
50970
- },
50971
- {
50972
- value: "md",
50973
- label: "Medium (256px)"
50974
- },
50975
- {
50976
- value: "lg",
50977
- label: "Large (320px)"
50978
- },
50979
- {
50980
- value: "xl",
50981
- label: "Extra large (400px)"
50982
- }
50983
- ],
50984
- defaultValue: "md",
50985
- ui: {
50986
- intent: "display",
50987
- visibleWhen: {
50988
- field: "variant",
50989
- equals: "marquee"
50990
- }
50991
- }
50992
- },
50993
- {
50994
- id: "imageFilter",
50995
- type: "select",
50996
- label: "Image filter",
50997
- options: [
50998
- {
50999
- value: "none",
51000
- label: "None"
51001
- },
51002
- {
51003
- value: "grayscale",
51004
- label: "Grayscale"
51005
- },
51006
- {
51007
- value: "grayscale-hover-reveal",
51008
- label: "Grayscale (color on hover)"
51009
- },
51010
- {
51011
- value: "sepia",
51012
- label: "Sepia"
51013
- }
51014
- ],
51015
- defaultValue: "grayscale-hover-reveal",
51016
- ui: { intent: "style" }
51017
- },
51018
- {
51019
- id: "imageBorder",
51020
- type: "group",
51021
- label: "Image border",
51022
- schema: { fields: [
51023
- {
51024
- id: "enabled",
51025
- type: "boolean",
51026
- label: "Show border",
51027
- defaultValue: true
51028
- },
51029
- {
51030
- id: "colorToken",
51031
- type: "text",
51032
- label: "Border color",
51033
- defaultValue: "accent",
51034
- ui: { widget: "backgroundColor" }
51035
- },
51036
- {
51037
- id: "opacity",
51038
- type: "number",
51039
- label: "Border opacity",
51040
- defaultValue: 30,
51041
- ui: {
51042
- min: 0,
51043
- max: 100
51044
- }
51045
- },
51046
- {
51047
- id: "width",
51048
- type: "select",
51049
- label: "Border width",
51050
- options: [
51051
- {
51052
- value: "1",
51053
- label: "Thin (1px)"
51054
- },
51055
- {
51056
- value: "2",
51057
- label: "Medium (2px)"
51058
- },
51059
- {
51060
- value: "3",
51061
- label: "Thick (3px)"
51062
- }
51063
- ],
51064
- defaultValue: "2"
51065
- }
51066
- ] },
51067
- ui: { intent: "style" }
51068
- },
51069
- {
51070
- id: "imageCorners",
51071
- type: "select",
51072
- label: "Image corners",
51073
- options: [
51074
- {
51075
- value: "none",
51076
- label: "Square"
51077
- },
51078
- {
51079
- value: "sm",
51080
- label: "Slightly rounded"
51081
- },
51082
- {
51083
- value: "md",
51084
- label: "Rounded"
51085
- },
51086
- {
51087
- value: "lg",
51088
- label: "More rounded"
51089
- },
51090
- {
51091
- value: "xl",
51092
- label: "Very rounded"
51093
- },
51094
- {
51095
- value: "2xl",
51096
- label: "Extra rounded"
51097
- },
51098
- {
51099
- value: "3xl",
51100
- label: "Maximum rounded"
51101
- }
51102
- ],
51103
- defaultValue: "3xl",
51104
- ui: { intent: "style" }
51105
- }
51106
- ]),
51844
+ additionalFields: imageGalleryFields,
51107
51845
  layout: wrapVariant$1(gridLayout),
51108
51846
  variants: {
51847
+ tiles: tilesLayout,
51109
51848
  grid: wrapVariant$1(gridLayout),
51110
51849
  carousel: wrapVariant$1(carouselLayout),
51111
51850
  masonry: wrapVariant$1(masonryLayout),
@@ -51114,7 +51853,10 @@ const imageGalleryBlockDefinition = { manifest: createBlockManifest({
51114
51853
  className: "rb-image-gallery-marquee-container"
51115
51854
  })
51116
51855
  },
51117
- variantMeaning: { kind: "arrangement" },
51856
+ variantMeaning: {
51857
+ kind: "arrangement",
51858
+ lookOnlyKeys: ["tiles"]
51859
+ },
51118
51860
  defaultVariant: "grid",
51119
51861
  variantOptions: {
51120
51862
  grid: {
@@ -53326,76 +54068,74 @@ const giftingBlockDefinition = {
53326
54068
  /**
53327
54069
  * Get form fields based on preset configuration.
53328
54070
  */
53329
- function getGlobalFormFields(form) {
53330
- const includePhone = form.includeOptionalPhone;
53331
- switch (form.fields.preset) {
53332
- case "emailOnly": return withOptionalPhone([{
53333
- id: "email",
53334
- type: "email",
53335
- label: "Email",
53336
- required: true,
53337
- placeholder: "your@email.com"
53338
- }], includePhone);
53339
- case "emailName": return withOptionalPhone([{
53340
- id: "email",
53341
- type: "email",
53342
- label: "Email",
53343
- required: true,
53344
- placeholder: "your@email.com"
53345
- }, {
54071
+ function getGlobalFormFields(form, presentation = {}) {
54072
+ const fields = withOptionalPhone(newsletterPresetFields(form.fields), form.includeOptionalPhone);
54073
+ return presentation.lookSlots ? fields.map((field) => ({
54074
+ ...field,
54075
+ label: lookFieldLabel(field)
54076
+ })) : fields;
54077
+ }
54078
+ function lookFieldLabel(field) {
54079
+ switch (field.id) {
54080
+ case "firstName": return "First name";
54081
+ case "lastName": return "Last name";
54082
+ default: return field.label;
54083
+ }
54084
+ }
54085
+ const emailField = {
54086
+ id: "email",
54087
+ type: "email",
54088
+ label: "Email",
54089
+ required: true,
54090
+ placeholder: "your@email.com"
54091
+ };
54092
+ const firstNameField = (required) => ({
54093
+ id: "firstName",
54094
+ type: "text",
54095
+ label: "First Name",
54096
+ required,
54097
+ placeholder: "First name"
54098
+ });
54099
+ function newsletterPresetFields(fields) {
54100
+ switch (fields.preset) {
54101
+ case "emailOnly": return [emailField];
54102
+ case "emailName": return [emailField, {
53346
54103
  id: "name",
53347
54104
  type: "text",
53348
54105
  label: "Name",
53349
- required: form.fields.name === "required",
54106
+ required: fields.name === "required",
53350
54107
  placeholder: "Your name"
53351
- }], includePhone);
53352
- case "emailFirstLast": return withOptionalPhone([
53353
- {
53354
- id: "email",
53355
- type: "email",
53356
- label: "Email",
53357
- required: true,
53358
- placeholder: "your@email.com"
53359
- },
53360
- {
53361
- id: "firstName",
53362
- type: "text",
53363
- label: "First Name",
53364
- required: form.fields.firstName === "required",
53365
- placeholder: "First name"
53366
- },
54108
+ }];
54109
+ case "emailFirstName": return [emailField, firstNameField(fields.firstName === "required")];
54110
+ case "emailFirstLast": return [
54111
+ emailField,
54112
+ firstNameField(fields.firstName === "required"),
53367
54113
  {
53368
54114
  id: "lastName",
53369
54115
  type: "text",
53370
54116
  label: "Last Name",
53371
- required: form.fields.lastName === "required",
54117
+ required: fields.lastName === "required",
53372
54118
  placeholder: "Last name"
53373
54119
  }
53374
- ], includePhone);
53375
- case "emailNameCompany": return withOptionalPhone([
53376
- {
53377
- id: "email",
53378
- type: "email",
53379
- label: "Email",
53380
- required: true,
53381
- placeholder: "your@email.com"
53382
- },
54120
+ ];
54121
+ case "emailNameCompany": return [
54122
+ emailField,
53383
54123
  {
53384
54124
  id: "name",
53385
54125
  type: "text",
53386
54126
  label: "Name",
53387
- required: form.fields.name === "required",
54127
+ required: fields.name === "required",
53388
54128
  placeholder: "Your name"
53389
54129
  },
53390
54130
  {
53391
54131
  id: "company",
53392
54132
  type: "text",
53393
54133
  label: "Company",
53394
- required: form.fields.company === "required",
54134
+ required: fields.company === "required",
53395
54135
  placeholder: "Company name"
53396
54136
  }
53397
- ], includePhone);
53398
- default: throw new Error("Unknown newsletter preset");
54137
+ ];
54138
+ default: return assertNever$6(fields);
53399
54139
  }
53400
54140
  }
53401
54141
  function withOptionalPhone(fields, includePhone) {
@@ -53457,6 +54197,7 @@ const mailingListSignupBlockSourceRefSchema = z.object({
53457
54197
  });
53458
54198
  const signedMailingListSourceTokenSchema = z.string().trim().min(1).transform(parseRequiredMailingListSignedSourceToken);
53459
54199
  const newsletterSourceCommonSchema = z.object({
54200
+ lookSlots: lookListPresentationSchemaShape.lookSlots,
53460
54201
  siteId: z.string().optional(),
53461
54202
  apiBaseUrl: z.string().optional(),
53462
54203
  mailingList: mailingListContextSchema.optional(),
@@ -53489,6 +54230,7 @@ const newsletterSourceSchema = z.discriminatedUnion("source", [
53489
54230
  newsletterSourceCommonSchema.extend({ source: z.literal("preview") })
53490
54231
  ]);
53491
54232
  const newsletterDisplaySchema = z.object({
54233
+ lookSlots: lookListPresentationSchemaShape.lookSlots,
53492
54234
  kind: z.literal("newsletter-form"),
53493
54235
  availability: z.enum(["ready", "unavailable"]),
53494
54236
  className: z.string().nullable(),
@@ -53555,13 +54297,14 @@ function buildNewsletterDisplay(source) {
53555
54297
  const choices = resolveRuntimeChoices(assessment);
53556
54298
  return {
53557
54299
  kind: "newsletter-form",
54300
+ ...source.lookSlots ? { lookSlots: source.lookSlots } : {},
53558
54301
  availability: assessment.tag === "available" ? "ready" : "unavailable",
53559
54302
  className: source.className ?? null,
53560
54303
  buttonLabel: form.buttonLabel,
53561
54304
  successMessage: form.successMessage,
53562
54305
  buttonVariant: source.buttonVariant ?? "primary",
53563
54306
  privacyNote: form.privacyNote,
53564
- fields: getGlobalFormFields(form),
54307
+ fields: getGlobalFormFields(form, source),
53565
54308
  choices
53566
54309
  };
53567
54310
  }
@@ -53633,32 +54376,50 @@ function parseRequiredMailingListSignedSourceToken(value) {
53633
54376
  //#region ../blocks/src/system/blocks/newsletter-signup.ts
53634
54377
  const stackedComposition = composeFragments([{ fragment: newsletterCopyFragment }, { fragment: newsletterFormFragment }]);
53635
54378
  const stackedLayout = styledSection({
53636
- children: sectionContainer(stackedComposition.layout, {
54379
+ children: props(lookSlot("layout"))(sectionContainer(stackedComposition.layout, {
53637
54380
  gap: "md",
53638
54381
  className: "rb-text-center newsletter-stacked"
53639
- }),
54382
+ })),
53640
54383
  baseClass: "",
53641
54384
  spacing: "medium",
53642
54385
  background: "surface"
53643
54386
  });
53644
54387
  const inlineLayout = styledSection({
53645
- children: sectionContainer(stackedComposition.layout, {
54388
+ children: props(lookSlot("layout"))(sectionContainer(stackedComposition.layout, {
53646
54389
  gap: "md",
53647
54390
  className: "newsletter-inline"
53648
- }),
54391
+ })),
53649
54392
  baseClass: "",
53650
54393
  spacing: "medium",
53651
54394
  background: "surface"
53652
54395
  });
53653
54396
  const editorialSplitLayout = styledSection({
53654
- children: sectionContainer([el("div", { className: "newsletter-editorial-split-copy" }, newsletterCopyFragment.layout), el("div", { className: "newsletter-editorial-split-form" }, newsletterFormFragment.layout)], {
54397
+ children: props(lookSlot("layout"))(sectionContainer([el("div", {
54398
+ className: "newsletter-editorial-split-copy",
54399
+ ...lookSlot("head")
54400
+ }, newsletterCopyFragment.layout), el("div", {
54401
+ className: "newsletter-editorial-split-form",
54402
+ ...lookSlot("panel")
54403
+ }, newsletterFormFragment.layout)], {
53655
54404
  gap: "lg",
53656
54405
  className: "newsletter-editorial-split"
53657
- }),
54406
+ })),
53658
54407
  baseClass: "",
53659
54408
  spacing: "comfortable",
53660
54409
  background: "surface"
53661
54410
  });
54411
+ const archLayout = styledSection({
54412
+ children: el("div", {
54413
+ className: "rb-container",
54414
+ ...lookSlot("layout")
54415
+ }, [el("div", lookSlot("frame"), [el("div", {
54416
+ className: "rb-grid",
54417
+ ...lookSlot("head")
54418
+ }, newsletterCopyFragment.layout), ...newsletterFormFragment.layout])]),
54419
+ baseClass: "",
54420
+ spacing: "medium",
54421
+ background: "surface"
54422
+ });
53662
54423
  const newsletterSignupManifest = createBlockManifest({
53663
54424
  id: "block.newsletter-signup",
53664
54425
  title: "Newsletter Signup",
@@ -53673,13 +54434,26 @@ const newsletterSignupManifest = createBlockManifest({
53673
54434
  fragment: newsletterFormFragment,
53674
54435
  fieldPriority: 1
53675
54436
  }],
54437
+ additionalFields: [{
54438
+ id: "archFrame",
54439
+ type: "boolean",
54440
+ label: "Arch frame",
54441
+ ui: {
54442
+ intent: "display",
54443
+ hidden: true
54444
+ }
54445
+ }],
53676
54446
  layout: stackedLayout,
53677
54447
  variants: {
54448
+ arch: archLayout,
53678
54449
  stacked: stackedLayout,
53679
54450
  inline: inlineLayout,
53680
54451
  "editorial-split": editorialSplitLayout
53681
54452
  },
53682
- variantMeaning: { kind: "arrangement" },
54453
+ variantMeaning: {
54454
+ kind: "arrangement",
54455
+ lookOnlyKeys: ["arch"]
54456
+ },
53683
54457
  defaultVariant: "stacked",
53684
54458
  variantOptions: {
53685
54459
  stacked: {
@@ -54771,7 +55545,7 @@ const systemBlockDefinitions = [
54771
55545
  })
54772
55546
  ]
54773
55547
  })),
54774
- withDesignCapability("block.body-text", bodyTextBlockDefinition, sectionOnly(), defineBlockDesignMetadata({
55548
+ withDesignCapability("block.body-text", bodyTextBlockDefinition, withLookCapability(sectionOnly()), defineBlockDesignMetadata({
54775
55549
  flow: bodyFlow,
54776
55550
  layoutProfiles: [
54777
55551
  layoutProfile({
@@ -55146,7 +55920,7 @@ const systemBlockDefinitions = [
55146
55920
  weight: "quiet"
55147
55921
  })]
55148
55922
  })),
55149
- withDesignCapability("block.image-gallery", imageGalleryBlockDefinition, sectionOnly(), defineBlockDesignMetadata({
55923
+ withDesignCapability("block.image-gallery", imageGalleryBlockDefinition, withLookCapability(sectionOnly()), defineBlockDesignMetadata({
55150
55924
  flow: mediaFlow,
55151
55925
  layoutProfiles: [
55152
55926
  layoutProfile({
@@ -55235,7 +56009,7 @@ const systemBlockDefinitions = [
55235
56009
  weight: "standard"
55236
56010
  })]
55237
56011
  })),
55238
- withDesignCapability("block.newsletter-signup", newsletterSignupBlockDefinition, sectionOnly(), defineBlockDesignMetadata({
56012
+ withDesignCapability("block.newsletter-signup", newsletterSignupBlockDefinition, withLookCapability(sectionOnly()), defineBlockDesignMetadata({
55239
56013
  flow: conversionFlow,
55240
56014
  layoutProfiles: [
55241
56015
  layoutProfile({
@@ -56004,10 +56778,7 @@ function arrangementPhotoContent(content, knobs) {
56004
56778
  }) };
56005
56779
  }
56006
56780
  function arrangementContentFacts(content) {
56007
- const section = isObjectRecord$1(content._sectionStyles) ? content._sectionStyles : {};
56008
- const background = isObjectRecord$1(section.background) ? section.background : {};
56009
- const itemPhotos = Array.isArray(content.cards) ? content.cards.filter((card) => isObjectRecord$1(card) && isObjectRecord$1(card.media)).length : 0;
56010
- const photoCount = Array.isArray(content.cards) ? itemPhotos : isObjectRecord$1(background.image) ? 1 : 0;
56781
+ const photoCount = arrangementPhotoCount(content);
56011
56782
  return {
56012
56783
  photoCount,
56013
56784
  facts: {
@@ -56018,6 +56789,13 @@ function arrangementContentFacts(content) {
56018
56789
  }
56019
56790
  };
56020
56791
  }
56792
+ /** The content stage owns media presence for every arrangement consumer. */
56793
+ function arrangementPhotoCount(content) {
56794
+ if (Array.isArray(content.cards)) return content.cards.filter((card) => isObjectRecord$1(card) && isObjectRecord$1(card.media)).length;
56795
+ if (Array.isArray(content.images)) return content.images.filter((item) => isObjectRecord$1(item) && isObjectRecord$1(item.image)).length;
56796
+ const section = isObjectRecord$1(content._sectionStyles) ? content._sectionStyles : {};
56797
+ return isObjectRecord$1((isObjectRecord$1(section.background) ? section.background : {}).image) ? 1 : 0;
56798
+ }
56021
56799
  function effectiveContentKnobValue(blockKind, key, value) {
56022
56800
  const facet = systemCustomizeFacetDefinitionsForBlock(blockKind).find((entry) => entry.target.kind === "content-field" && entry.target.field === key);
56023
56801
  return facet?.target.kind === "content-field" && facet.target.boolean ? value === "true" : value;
@@ -59088,6 +59866,27 @@ const navigationLinkInputSchemaOptions = [
59088
59866
  ];
59089
59867
  z.discriminatedUnion("kind", navigationLinkInputSchemaOptions);
59090
59868
  //#endregion
59869
+ //#region ../theme-core/src/footer/mode.ts
59870
+ const footerModeSchema = z.enum([
59871
+ "default",
59872
+ "blocks",
59873
+ "default+blocks",
59874
+ "none"
59875
+ ]);
59876
+ z.object({
59877
+ variant: z.enum([
59878
+ "simple",
59879
+ "columns",
59880
+ "split",
59881
+ "centred"
59882
+ ]),
59883
+ showLogoText: z.boolean().optional(),
59884
+ logo: z.object({
59885
+ showLogo: z.boolean().optional(),
59886
+ showLogoText: z.boolean().optional()
59887
+ }).optional()
59888
+ });
59889
+ //#endregion
59091
59890
  //#region ../api/src/sdkConfig/contracts.ts
59092
59891
  /**
59093
59892
  * Canonical SDK config Zod contracts.