@riverbankcms/sdk 0.82.0 → 0.84.1

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 (206) hide show
  1. package/README.md +16 -0
  2. package/dist/{PreviewEditorSidebar-LHGK6RIO.mjs → PreviewEditorSidebar-X7RLMEI6.mjs} +330 -11
  3. package/dist/{PreviewEditorUI-AXZG2SDC.mjs → PreviewEditorUI-CT67N4O3.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-EIMQ3S2V.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +200 -0
  6. package/dist/_dts/api/src/blocks.d.ts +36 -0
  7. package/dist/_dts/api/src/contentRuntime.d.ts +46 -0
  8. package/dist/_dts/api/src/endpoints.d.ts +40 -0
  9. package/dist/_dts/api/src/index.d.ts +2 -2
  10. package/dist/_dts/api/src/sdk-event-pricing.d.ts +61 -0
  11. package/dist/_dts/api/src/sdk-event-schedule.d.ts +52 -0
  12. package/dist/_dts/api/src/sdk-event-upsert.d.ts +50 -0
  13. package/dist/_dts/api/src/sdkContracts.d.ts +67 -33
  14. package/dist/_dts/api/src/shared-contracts.d.ts +13 -0
  15. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +22 -36
  16. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +46 -1
  17. package/dist/_dts/block-form/src/backend/useBackendWatch.d.ts +6 -1
  18. package/dist/_dts/block-form/src/utils/evaluateVisibility.d.ts +3 -2
  19. package/dist/_dts/block-form/src/utils/visibleWhen.d.ts +7 -0
  20. package/dist/_dts/blocks/src/PageRenderer.d.ts +11 -0
  21. package/dist/_dts/blocks/src/bindings/index.d.ts +1 -1
  22. package/dist/_dts/blocks/src/client/site-chrome.d.ts +1 -1
  23. package/dist/_dts/blocks/src/client.d.ts +4 -0
  24. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +16 -4
  25. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +288 -2016
  26. package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +288 -2016
  27. package/dist/_dts/blocks/src/system/blocks/cart.d.ts +288 -2016
  28. package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +288 -2016
  29. package/dist/_dts/blocks/src/system/blocks/collection.d.ts +288 -2016
  30. package/dist/_dts/blocks/src/system/blocks/contact-newsletter.d.ts +171 -0
  31. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +288 -2016
  32. package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +288 -2016
  33. package/dist/_dts/blocks/src/system/blocks/hero.d.ts +3 -2
  34. package/dist/_dts/blocks/src/system/blocks/index.d.ts +1 -0
  35. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +1 -7
  36. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +2534 -151
  37. package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +288 -2016
  38. package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +288 -2016
  39. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +288 -2016
  40. package/dist/_dts/blocks/src/system/blocks/site-header.d.ts +36 -3
  41. package/dist/_dts/blocks/src/system/blocks/team-members.d.ts +2 -2
  42. package/dist/_dts/blocks/src/system/constants/blockKinds.d.ts +1 -1
  43. package/dist/_dts/blocks/src/system/fields/aspectRatio.d.ts +4 -1
  44. package/dist/_dts/blocks/src/system/fields/imageShape.d.ts +30 -0
  45. package/dist/_dts/blocks/src/system/fragments/library/heroLayoutControls.d.ts +25 -0
  46. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +35 -161
  47. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +24 -6
  48. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +12 -3
  49. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessEventRegistrationFlow.d.ts +33 -0
  50. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizard.d.ts +0 -2
  51. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/constants.d.ts +1 -0
  52. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +275 -0
  53. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.override.d.ts +10 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +22 -0
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.state.d.ts +3 -0
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +20 -1
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +13 -4
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +1 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +28 -6
  60. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/pricing.d.ts +14 -0
  61. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +1 -1
  62. package/dist/_dts/content-editor/src/controller/buildBlockPublishedBaselines.d.ts +1 -1
  63. package/dist/_dts/content-editor/src/controller/seedDraftBaselinesFromBlocks.d.ts +1 -1
  64. package/dist/_dts/content-editor/src/controller/useBlocksList.d.ts +1 -1
  65. package/dist/_dts/content-editor/src/controller/useInvalidBlockRecovery.d.ts +1 -1
  66. package/dist/_dts/content-editor/src/primitives/PreviewRichTextEditor.d.ts +2 -1
  67. package/dist/_dts/content-editor/src/primitives/PreviewTextEditor.d.ts +1 -0
  68. package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
  69. package/dist/_dts/content-model/src/entry-slots/types.d.ts +356 -0
  70. package/dist/_dts/content-model/src/index.d.ts +1 -0
  71. package/dist/_dts/content-model/src/templates/defaults.d.ts +7 -0
  72. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +100 -5
  73. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +6 -1
  74. package/dist/_dts/editor-blocks/src/BlockForm.d.ts +7 -5
  75. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockCreation.d.ts +3 -2
  76. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +3 -2
  77. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockReorder.d.ts +3 -2
  78. package/dist/_dts/editor-blocks/src/block-editor/owner.d.ts +27 -0
  79. package/dist/_dts/editor-blocks/src/index.d.ts +1 -0
  80. package/dist/_dts/media-core/src/assetsInUseSummary.d.ts +8 -0
  81. package/dist/_dts/media-core/src/mediaUsageProjection.d.ts +37 -3
  82. package/dist/_dts/preview-next/src/client/blocks/pageDesignRuntimePreview.d.ts +4 -2
  83. package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -2
  84. package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +3 -1
  85. package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +19 -0
  86. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeButton.d.ts +8 -0
  87. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +4 -1
  88. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +1 -1
  89. package/dist/_dts/preview-next/src/client/preview/linkedEntryEditEvents.d.ts +9 -0
  90. package/dist/_dts/preview-next/src/client/preview/previewCustomizeControls.d.ts +9 -8
  91. package/dist/_dts/preview-next/src/client/preview/siteChromeLookRows.d.ts +10 -1
  92. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +5 -1
  93. package/dist/_dts/sdk/src/bookings/index.d.ts +5 -4
  94. package/dist/_dts/sdk/src/bookings/types.d.ts +2 -2
  95. package/dist/_dts/sdk/src/cli/content/reader.d.ts +9 -8
  96. package/dist/_dts/sdk/src/cli/content/writer.d.ts +6 -1
  97. package/dist/_dts/sdk/src/cli/helpers.d.ts +10 -5
  98. package/dist/_dts/sdk/src/cli/merge-remote/entryLocal.d.ts +2 -2
  99. package/dist/_dts/sdk/src/cli/merge-remote/entryMerge.d.ts +2 -1
  100. package/dist/_dts/sdk/src/cli/merge-remote/entrySnapshots.d.ts +2 -2
  101. package/dist/_dts/sdk/src/client/management/index.d.ts +1 -1
  102. package/dist/_dts/sdk/src/client/management/types.d.ts +40 -10
  103. package/dist/_dts/sdk/src/config/field-definitions.d.ts +13 -7
  104. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +26 -3
  105. package/dist/_dts/sdk/src/public-api/contracts.d.ts +13 -0
  106. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +1 -0
  107. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +6 -1
  108. package/dist/_dts/sdk/src/rendering/overrides.d.ts +6 -1
  109. package/dist/_dts/sdk/src/types/block-kinds.d.ts +1 -1
  110. package/dist/_dts/sdk/src/version.d.ts +1 -1
  111. package/dist/_dts/site-commands/src/commands.d.ts +15 -0
  112. package/dist/_dts/theme-core/src/accordions/types.d.ts +1 -1
  113. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +11 -0
  114. package/dist/_dts/theme-core/src/buttons/personalities/ornate-ritual.d.ts +16 -0
  115. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +1 -1
  116. package/dist/_dts/theme-core/src/buttons/types.d.ts +3 -3
  117. package/dist/_dts/theme-core/src/cards/types.d.ts +15 -15
  118. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  119. package/dist/_dts/theme-core/src/inputs/types.d.ts +1 -1
  120. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +33 -33
  121. package/dist/_dts/theme-core/src/palette/variants/index.d.ts +15 -0
  122. package/dist/_dts/theme-core/src/palette/variants/warm-dark.d.ts +16 -0
  123. package/dist/_dts/theme-core/src/schema.d.ts +30 -25
  124. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  125. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +141 -1
  126. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -0
  127. package/dist/_dts/theme-core/src/site-styles/footerLooks.d.ts +110 -5
  128. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  129. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +1 -1
  130. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +5 -1
  131. package/dist/_dts/theme-core/src/site-styles/tokenRecipes.d.ts +1 -1
  132. package/dist/_dts/theme-core/src/site-styles/types.d.ts +1 -1
  133. package/dist/_dts/theme-core/src/site-styles/typographyPresets.d.ts +16 -1
  134. package/dist/_dts/theme-core/src/siteChromePlanning.d.ts +1 -0
  135. package/dist/_dts/theme-core/src/utils/colorStyles.d.ts +6 -6
  136. package/dist/{chunk-2BUMISSH.mjs → chunk-3LXFQS7T.mjs} +1 -1
  137. package/dist/{chunk-FIREV57T.mjs → chunk-LBBPD2IW.mjs} +40 -0
  138. package/dist/{chunk-XQR6THQJ.mjs → chunk-O62NDCTI.mjs} +3390 -1331
  139. package/dist/{chunk-6FWNF3DJ.mjs → chunk-QRKJDWT7.mjs} +158 -20
  140. package/dist/{chunk-HKB6XVIP.mjs → chunk-RCTJAZSK.mjs} +2 -2
  141. package/dist/{chunk-G35HOQEN.mjs → chunk-X5ZCSU6F.mjs} +132 -46
  142. package/dist/cli/index.mjs +2925 -577
  143. package/dist/cli/init-docs/content/agents-section.md +5 -0
  144. package/dist/cli/init-docs/content/cli-reference.md +13 -0
  145. package/dist/cli/init-docs/content/content-management.md +31 -0
  146. package/dist/cli/init-docs/content/getting-started.md +14 -0
  147. package/dist/cli/init-docs/content/workflow-add-block.md +3 -1
  148. package/dist/cli/init-docs/content/workflow-agent-safe-sync.md +81 -0
  149. package/dist/cli/init-docs/content/workflow-create-page.md +13 -3
  150. package/dist/cli/init-docs/content/workflow-custom-block.md +9 -0
  151. package/dist/cli/init-docs/content/workflow-templates.md +107 -2
  152. package/dist/client/{accordion-G34C45TW.mjs → accordion-2UZPBMYM.mjs} +2 -2
  153. package/dist/client/{bookingForm-BLBVKSAQ.mjs → bookingForm-DYXT6YB6.mjs} +5 -5
  154. package/dist/client/bookings.mjs +3477 -186
  155. package/dist/client/{carousel-7ZVTBRMD.mjs → carousel-QH77HR6X.mjs} +3 -3
  156. package/dist/client/{cart-Q6S6LZUO.mjs → cart-X4YK4FTW.mjs} +6 -6
  157. package/dist/client/{checkout-5QJLDE4I.mjs → checkout-OM2BEPWD.mjs} +6 -6
  158. package/dist/client/{chunk-ZF4XEWDM.mjs → chunk-3DTWLTXM.mjs} +1 -1
  159. package/dist/client/{chunk-5PQH4Y75.mjs → chunk-4OXKTA3D.mjs} +2 -2
  160. package/dist/client/{chunk-WJFHDTYF.mjs → chunk-52CGCQ7B.mjs} +5 -5
  161. package/dist/client/{chunk-CHAB5ACD.mjs → chunk-7UCLJ5SP.mjs} +2 -2
  162. package/dist/client/{chunk-U2EW7RSR.mjs → chunk-F5VRX5Y6.mjs} +1 -1
  163. package/dist/client/{chunk-SBBSMFFG.mjs → chunk-SYIJ5JO2.mjs} +1 -1
  164. package/dist/client/{chunk-EQKYMX4N.mjs → chunk-UHDWIXVR.mjs} +180 -157
  165. package/dist/client/{chunk-RJHTCTCZ.mjs → chunk-VGDBVNOO.mjs} +429 -15
  166. package/dist/client/{chunk-S3MKFGOG.mjs → chunk-ZE5G642V.mjs} +1 -1
  167. package/dist/client/{chunk-CSZGLBYR.mjs → chunk-ZKUO52W3.mjs} +1 -1
  168. package/dist/client/client.mjs +2685 -847
  169. package/dist/client/{courseRegistration-VUG2JJDB.mjs → courseRegistration-YBOGURTA.mjs} +5 -5
  170. package/dist/client/{eventCalendar-E7D2LD4N.mjs → eventCalendar-K4QJVCMD.mjs} +7 -7
  171. package/dist/client/{eventCombined-FUZ2Z3CS.mjs → eventCombined-MTXGMTCZ.mjs} +7 -7
  172. package/dist/client/{eventDetails-QRITJAOW.mjs → eventDetails-3PC4NL3U.mjs} +7 -7
  173. package/dist/client/{eventListing-INMQMJZ5.mjs → eventListing-TFJET6DN.mjs} +7 -7
  174. package/dist/client/{eventRegistration-TOOJD4WU.mjs → eventRegistration-QGPBGJTW.mjs} +7 -7
  175. package/dist/client/{form-BOWN7ZNQ.mjs → form-MDKR4FNB.mjs} +2 -2
  176. package/dist/client/{headerSection-HFQNZOUU.mjs → headerSection-Y5TMR3TW.mjs} +3 -3
  177. package/dist/client/hooks.mjs +2077 -546
  178. package/dist/client/{locationMap-VUZGC7Y5.mjs → locationMap-RH2LG7FZ.mjs} +2 -2
  179. package/dist/client/{newsletterForm-X2XQTPCB.mjs → newsletterForm-ZR5UDGBT.mjs} +2 -2
  180. package/dist/client/{productDetail-TA7D2G2B.mjs → productDetail-OIGDR4YE.mjs} +6 -6
  181. package/dist/client/{productList-AZOLOZKM.mjs → productList-4MA5S2CX.mjs} +6 -6
  182. package/dist/client/rendering/client.mjs +2560 -1205
  183. package/dist/client/rendering/islands.mjs +19 -19
  184. package/dist/client/rendering.mjs +2932 -1021
  185. package/dist/client/{shop-ZDLO7IIG.mjs → shop-WXSYV5QO.mjs} +6 -6
  186. package/dist/preview-next/before-render.mjs +40 -0
  187. package/dist/preview-next/client/runtime.mjs +5 -5
  188. package/dist/preview-next/middleware.mjs +40 -0
  189. package/dist/{sdk-runtime-CTWKNBDQ.mjs → sdk-runtime-7HJYPRWQ.mjs} +6 -6
  190. package/dist/server/components.mjs +2232 -534
  191. package/dist/server/config-validation.mjs +2068 -536
  192. package/dist/server/config.mjs +2068 -536
  193. package/dist/server/data.mjs +2077 -546
  194. package/dist/server/index.mjs +42 -1
  195. package/dist/server/next.mjs +2345 -574
  196. package/dist/server/page-converter.mjs +2684 -1220
  197. package/dist/server/prebuild.mjs +1 -1
  198. package/dist/server/rendering/server.mjs +2244 -546
  199. package/dist/server/rendering.mjs +2323 -552
  200. package/dist/server/routing.mjs +2012 -420
  201. package/dist/server/server.mjs +2153 -549
  202. package/dist/server/theme-bridge.mjs +1180 -101
  203. package/dist/server/theme.mjs +92 -1
  204. package/dist/styles/index.css +292 -36
  205. package/package.json +1 -1
  206. package/dist/SdkPreviewModeRuntime-RNVRHFFR.mjs +0 -8
@@ -48,6 +48,171 @@ function formatKeyAsLabel(key) {
48
48
  // ../blocks/src/system/manifest/schema.ts
49
49
  import { z as z2 } from "zod";
50
50
 
51
+ // ../core/src/result.ts
52
+ function ok(value) {
53
+ return { ok: true, value };
54
+ }
55
+ function err(error) {
56
+ return { ok: false, error };
57
+ }
58
+
59
+ // ../core/src/event-pricing.ts
60
+ function publicEventPricingType(pricing) {
61
+ switch (pricing.kind) {
62
+ case "drop_in":
63
+ case "free_registration":
64
+ return "free";
65
+ case "single_paid":
66
+ case "ticket_types":
67
+ case "course":
68
+ return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
69
+ }
70
+ }
71
+ function isFreePublicEventPriceDisplay(display) {
72
+ switch (display.kind) {
73
+ case "free":
74
+ return true;
75
+ case "course":
76
+ return display.display.kind === "free";
77
+ case "exact":
78
+ case "from":
79
+ case "mixed":
80
+ case "unavailable":
81
+ return false;
82
+ }
83
+ }
84
+
85
+ // ../core/src/booking-date-time.ts
86
+ var DEFAULT_LOCALE = "en-US";
87
+ var FALLBACK_TIMEZONE = "UTC";
88
+ function isValidTimeZone(timeZone) {
89
+ try {
90
+ new Intl.DateTimeFormat(DEFAULT_LOCALE, { timeZone }).format(/* @__PURE__ */ new Date());
91
+ return true;
92
+ } catch {
93
+ return false;
94
+ }
95
+ }
96
+ function getSafeTimeZone(timeZone) {
97
+ const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
98
+ return normalized && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
99
+ }
100
+ function parseStrictBookingTimeZone(timeZone) {
101
+ const normalized = timeZone.trim();
102
+ if (!normalized || !isValidTimeZone(normalized)) {
103
+ return null;
104
+ }
105
+ return normalized;
106
+ }
107
+ function formatParseError(error) {
108
+ switch (error.reason) {
109
+ case "invalid_starts_at":
110
+ return `Expected a valid UTC/offset-aware ISO datetime in startsAt, received "${error.value}"`;
111
+ case "invalid_ends_at":
112
+ return `Expected a valid UTC/offset-aware ISO datetime in endsAt, received "${error.value ?? ""}"`;
113
+ case "invalid_time_zone":
114
+ return `Expected a valid IANA timezone in timeZone, received "${error.value}"`;
115
+ }
116
+ }
117
+ function formatToPartsLookup(date, locale, timeZone, format) {
118
+ return new Map(
119
+ new Intl.DateTimeFormat(locale, {
120
+ ...format,
121
+ timeZone
122
+ }).formatToParts(date).map((part) => [part.type, part.value])
123
+ );
124
+ }
125
+ function getZonedDateTimeParts(date, timeZone) {
126
+ const parts = formatToPartsLookup(date, "en-GB", timeZone, {
127
+ year: "numeric",
128
+ month: "2-digit",
129
+ day: "2-digit",
130
+ hour: "2-digit",
131
+ minute: "2-digit",
132
+ second: "2-digit",
133
+ hour12: false
134
+ });
135
+ const read = (type) => Number(parts.get(type) ?? "");
136
+ return {
137
+ year: read("year"),
138
+ month: read("month"),
139
+ day: read("day"),
140
+ hour: read("hour"),
141
+ minute: read("minute"),
142
+ second: read("second")
143
+ };
144
+ }
145
+ function formatDateKey(date) {
146
+ const year = String(date.year).padStart(4, "0");
147
+ const month = String(date.month).padStart(2, "0");
148
+ const day = String(date.day).padStart(2, "0");
149
+ return `${year}-${month}-${day}`;
150
+ }
151
+ function parseUtcIsoDateTimeString(value) {
152
+ const normalized = value.trim();
153
+ const hasUtcSuffix = normalized.endsWith("Z");
154
+ const hasExplicitOffset = /[+-]\d{2}:\d{2}$/u.test(normalized);
155
+ if (!hasUtcSuffix && !hasExplicitOffset) {
156
+ return err("missing-timezone-offset");
157
+ }
158
+ const date = new Date(normalized);
159
+ if (Number.isNaN(date.getTime())) {
160
+ return err("invalid-date-time");
161
+ }
162
+ return ok(date.toISOString());
163
+ }
164
+ function toUtcIsoDateTimeString(value) {
165
+ const parsed = parseUtcIsoDateTimeString(value);
166
+ if (!parsed.ok) {
167
+ const message = parsed.error === "missing-timezone-offset" ? `Expected an offset-aware ISO datetime, received "${value}"` : `Expected a valid ISO datetime, received "${value}"`;
168
+ throw new Error(message);
169
+ }
170
+ return parsed.value;
171
+ }
172
+ function parseScheduledBookingDateTime(input) {
173
+ try {
174
+ const startsAt = toUtcIsoDateTimeString(input.startsAt);
175
+ const timeZone = parseStrictBookingTimeZone(input.timeZone);
176
+ if (!timeZone) {
177
+ return {
178
+ ok: false,
179
+ field: "timeZone",
180
+ reason: "invalid_time_zone",
181
+ value: input.timeZone
182
+ };
183
+ }
184
+ return {
185
+ ok: true,
186
+ value: {
187
+ startsAt,
188
+ timeZone,
189
+ locale: input.locale
190
+ }
191
+ };
192
+ } catch {
193
+ return {
194
+ ok: false,
195
+ field: "startsAt",
196
+ reason: "invalid_starts_at",
197
+ value: input.startsAt
198
+ };
199
+ }
200
+ }
201
+ function toScheduledBookingDateTime(input) {
202
+ const result = parseScheduledBookingDateTime(input);
203
+ if (result.ok) {
204
+ return result.value;
205
+ }
206
+ throw new Error(formatParseError(result));
207
+ }
208
+ function getBookingLocalDateKey(input) {
209
+ return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
210
+ }
211
+ function getLocalScheduleDate(date, timeZone) {
212
+ const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
213
+ return { year: parts.year, month: parts.month, day: parts.day };
214
+ }
215
+
51
216
  // ../core/src/location.ts
52
217
  function normalizeLocationAddressText(value) {
53
218
  if (typeof value !== "string") {
@@ -367,6 +532,21 @@ var selectSourceSchema = z2.discriminatedUnion("kind", [
367
532
  function assertNeverSelectSource(value) {
368
533
  throw new Error(`Unhandled select source: ${JSON.stringify(value)}`);
369
534
  }
535
+ var visibleWhenPredicateSchema = z2.object({
536
+ field: z2.string().min(1),
537
+ equals: z2.any().optional(),
538
+ notEquals: z2.any().optional(),
539
+ oneOf: z2.array(z2.any()).optional(),
540
+ notIn: z2.array(z2.any()).optional(),
541
+ minItems: z2.number().int().nonnegative().optional(),
542
+ maxItems: z2.number().int().nonnegative().optional()
543
+ });
544
+ var visibleWhenSchema = z2.union([
545
+ visibleWhenPredicateSchema,
546
+ z2.object({
547
+ allOf: z2.array(visibleWhenPredicateSchema).min(1)
548
+ })
549
+ ]);
370
550
  var uiSchema = z2.object({
371
551
  widget: z2.string().optional(),
372
552
  // Container/widget presets (used by Group/Repeater widgets themselves, not for widget selection)
@@ -399,13 +579,7 @@ var uiSchema = z2.object({
399
579
  showValue: z2.boolean().optional(),
400
580
  pattern: z2.string().optional(),
401
581
  placeholder: z2.string().optional(),
402
- visibleWhen: z2.object({
403
- field: z2.string().min(1),
404
- equals: z2.any().optional(),
405
- notEquals: z2.any().optional(),
406
- oneOf: z2.array(z2.any()).optional(),
407
- notIn: z2.array(z2.any()).optional()
408
- }).optional(),
582
+ visibleWhen: visibleWhenSchema.optional(),
409
583
  // Modal configuration for modal and group fields
410
584
  modalConfig: z2.object({
411
585
  buttonLabel: z2.string().optional(),
@@ -1107,6 +1281,7 @@ var eventListTreatmentValues = [
1107
1281
  ];
1108
1282
  var eyebrowTreatmentValues = [
1109
1283
  "plain",
1284
+ "accent",
1110
1285
  "pill",
1111
1286
  "accent-pill",
1112
1287
  "pill-bounce",
@@ -2698,9 +2873,9 @@ var _Vibrant = class _Vibrant2 {
2698
2873
  }
2699
2874
  image.remove();
2700
2875
  return res;
2701
- } catch (err) {
2876
+ } catch (err2) {
2702
2877
  image.remove();
2703
- return Promise.reject(err);
2878
+ return Promise.reject(err2);
2704
2879
  }
2705
2880
  }
2706
2881
  async getPalettes() {
@@ -2714,9 +2889,9 @@ var _Vibrant = class _Vibrant2 {
2714
2889
  const res = result1.palettes;
2715
2890
  image.remove();
2716
2891
  return res;
2717
- } catch (err) {
2892
+ } catch (err2) {
2718
2893
  image.remove();
2719
- return Promise.reject(err);
2894
+ return Promise.reject(err2);
2720
2895
  }
2721
2896
  }
2722
2897
  };
@@ -4112,6 +4287,95 @@ var joyStamp = defineButtonPersonality({
4112
4287
  }
4113
4288
  });
4114
4289
 
4290
+ // ../theme-core/src/buttons/personalities/ornate-ritual.ts
4291
+ var ornateRitual = defineButtonPersonality({
4292
+ id: "ornate-ritual",
4293
+ name: "Ornate Ritual",
4294
+ description: "Ceremonial framed buttons with jewel-toned fills and quiet color-change hover states.",
4295
+ tags: { tone: "classic", energy: "vibrant", motion: "subtle", era: "organic" },
4296
+ buttonSystem: {
4297
+ global: {
4298
+ cornerStyle: "rounded",
4299
+ shadow: "none",
4300
+ textTransform: "uppercase",
4301
+ fontWeight: 600,
4302
+ borderWidth: 1,
4303
+ hoverTransform: "none",
4304
+ hoverColor: "none",
4305
+ letterSpacing: "loose"
4306
+ },
4307
+ sizes: {
4308
+ sm: { padding: "0.5625rem 1.25rem", fontSize: "text-xs" },
4309
+ md: { padding: "0.75rem 1.75rem", fontSize: "text-xs" },
4310
+ lg: { padding: "0.875rem 2.25rem", fontSize: "text-sm" },
4311
+ xl: { padding: "1rem 2.75rem", fontSize: "text-base" }
4312
+ },
4313
+ variants: [
4314
+ {
4315
+ id: "primary",
4316
+ name: "Primary",
4317
+ enabled: true,
4318
+ priority: 1,
4319
+ background: { type: "solid", colorToken: "primary" },
4320
+ textColorToken: "primaryForeground",
4321
+ borderRadius: "rounded-md",
4322
+ border: { widthClass: "border", colorToken: "primary" },
4323
+ shadow: { elevation: "none", softness: null, position: "bottom" },
4324
+ effects: {
4325
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "primary-100" } }],
4326
+ active: [{ effectId: "scale-down", options: { scale: "0.98" } }]
4327
+ }
4328
+ },
4329
+ {
4330
+ id: "secondary",
4331
+ name: "Secondary",
4332
+ enabled: true,
4333
+ priority: 2,
4334
+ background: { type: "solid", colorToken: "secondary" },
4335
+ textColorToken: "primaryForeground",
4336
+ borderRadius: "rounded-md",
4337
+ border: { widthClass: "border", colorToken: "primary" },
4338
+ shadow: { elevation: "none", softness: null, position: "bottom" },
4339
+ effects: {
4340
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "surface" } }]
4341
+ }
4342
+ },
4343
+ {
4344
+ id: "outline",
4345
+ name: "Outline",
4346
+ enabled: true,
4347
+ priority: 3,
4348
+ background: { type: "transparent" },
4349
+ textColorToken: "primary",
4350
+ borderRadius: "rounded-md",
4351
+ border: { widthClass: "border", colorToken: "primary" },
4352
+ shadow: { elevation: "none", softness: null, position: "bottom" },
4353
+ effects: {
4354
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "muted" } }]
4355
+ }
4356
+ },
4357
+ {
4358
+ id: "ghost",
4359
+ name: "Ghost",
4360
+ enabled: true,
4361
+ priority: 3,
4362
+ background: { type: "transparent" },
4363
+ textColorToken: "accent",
4364
+ borderRadius: "rounded-none",
4365
+ sizes: {
4366
+ sm: { padding: "0.375rem 0", fontSize: "text-xs" },
4367
+ md: { padding: "0.5rem 0", fontSize: "text-sm" },
4368
+ lg: { padding: "0.625rem 0", fontSize: "text-base" },
4369
+ xl: { padding: "0.75rem 0", fontSize: "text-lg" }
4370
+ },
4371
+ effects: {
4372
+ base: [{ effectId: "border-bottom-grow", options: { height: 1, colorToken: "accent", origin: "left" } }]
4373
+ }
4374
+ }
4375
+ ]
4376
+ }
4377
+ });
4378
+
4115
4379
  // ../theme-core/src/buttons/personalities/pebble.ts
4116
4380
  var pebble = defineButtonPersonality({
4117
4381
  id: "pebble",
@@ -4385,7 +4649,8 @@ var buttonPersonalities = [
4385
4649
  inkStamp,
4386
4650
  brushedWash,
4387
4651
  showtimePill,
4388
- joyStamp
4652
+ joyStamp,
4653
+ ornateRitual
4389
4654
  ];
4390
4655
  var personalitiesById = new Map(
4391
4656
  buttonPersonalities.map((p) => [p.id, p])
@@ -5011,7 +5276,7 @@ function rgbColorValue(token) {
5011
5276
  if (alpha === void 0) {
5012
5277
  return `rgb(var(${cssVar}))`;
5013
5278
  }
5014
- return `rgba(var(${cssVar}), ${alpha})`;
5279
+ return `rgb(var(${cssVar}) / ${alpha})`;
5015
5280
  }
5016
5281
  function backgroundColorStyle(token) {
5017
5282
  return { backgroundColor: rgbColorValue(token) };
@@ -6046,6 +6311,28 @@ var warmDarkEmber = definePaletteVariant({
6046
6311
  { name: "border", hex: "#894e31" }
6047
6312
  ]
6048
6313
  });
6314
+ var warmDarkKirtanGold = definePaletteVariant({
6315
+ id: "warm-dark-kirtan-gold",
6316
+ name: "Warm Dark \u2014 Kirtan Gold",
6317
+ description: "Deep plum ground with pale gold primary, rose accent, and soft devotional text.",
6318
+ tags: { tone: "bold", energy: "calm", era: "editorial" },
6319
+ mode: "dark",
6320
+ colors: [
6321
+ { name: "primary", hex: "#ffcdb2" },
6322
+ { name: "secondary", hex: "#b5838d" },
6323
+ { name: "accent", hex: "#e5989b" },
6324
+ { name: "success", hex: "#8fbf8f" },
6325
+ { name: "warning", hex: "#f2b86b" },
6326
+ { name: "destructive", hex: "#d96b6b" },
6327
+ { name: "background", hex: "#403944" },
6328
+ { name: "surface", hex: "#403944" },
6329
+ { name: "surfaceAlt", hex: "#372f3b" },
6330
+ { name: "muted", hex: "#4d4550" },
6331
+ { name: "text", hex: "#e6d2d5" },
6332
+ { name: "primaryForeground", hex: "#403944" },
6333
+ { name: "border", hex: "#8d747a" }
6334
+ ]
6335
+ });
6049
6336
 
6050
6337
  // ../theme-core/src/palette/variants/index.ts
6051
6338
  var paletteVariants = [
@@ -6069,7 +6356,8 @@ var paletteVariants = [
6069
6356
  softNaturalWatercolor,
6070
6357
  softNaturalLilac,
6071
6358
  // Warm-dark family (dark mode)
6072
- warmDarkEmber
6359
+ warmDarkEmber,
6360
+ warmDarkKirtanGold
6073
6361
  ];
6074
6362
  var paletteVariantsById = new Map(
6075
6363
  paletteVariants.map((v) => [v.id, v])
@@ -7568,9 +7856,125 @@ function headerConfigurationKey(configuration) {
7568
7856
  function asFooterLookId(value) {
7569
7857
  return value;
7570
7858
  }
7571
- var guaranteedFallbackFooterLookId = asFooterLookId("footer-muted-grounding");
7859
+ function asFooterLayoutId(value) {
7860
+ return value;
7861
+ }
7862
+ function asFooterStyleId(value) {
7863
+ return value;
7864
+ }
7865
+ var guaranteedFallbackFooterLookId = asFooterLookId("footer-identity-quiet");
7866
+ var footerLayoutCatalog = defineExactCatalog()([
7867
+ {
7868
+ id: asFooterLayoutId("identity"),
7869
+ label: "Identity",
7870
+ description: "Logo, site text, address, and legal copy without relying on footer navigation."
7871
+ },
7872
+ {
7873
+ id: asFooterLayoutId("centered"),
7874
+ label: "Centered",
7875
+ description: "A calm centered stack for identity, short copy, and optional compact navigation.",
7876
+ maxRecommendedNavDensity: "sparse"
7877
+ },
7878
+ {
7879
+ id: asFooterLayoutId("split"),
7880
+ label: "Split",
7881
+ description: "Navigation and brand signoff separated into a wider split footer.",
7882
+ requiresFooterNav: true,
7883
+ maxRecommendedNavDensity: "balanced"
7884
+ },
7885
+ {
7886
+ id: asFooterLayoutId("columns"),
7887
+ label: "Columns",
7888
+ description: "Grouped footer navigation columns with a supporting bottom line.",
7889
+ requiresFooterNav: true,
7890
+ requiresFooterNavGroups: true
7891
+ }
7892
+ ]);
7893
+ var footerStyleCatalog = defineExactCatalog()([
7894
+ {
7895
+ id: asFooterStyleId("quiet"),
7896
+ label: "Quiet",
7897
+ description: "Lightweight, practical footer treatment."
7898
+ },
7899
+ {
7900
+ id: asFooterStyleId("calm"),
7901
+ label: "Calm",
7902
+ description: "Soft centered treatment with restrained dividers."
7903
+ },
7904
+ {
7905
+ id: asFooterStyleId("editorial"),
7906
+ label: "Editorial",
7907
+ description: "Text-forward treatment with fine-line structure."
7908
+ },
7909
+ {
7910
+ id: asFooterStyleId("brand-band"),
7911
+ label: "Brand band",
7912
+ description: "High-contrast brand treatment with a stronger bottom bar."
7913
+ }
7914
+ ]);
7915
+ var footerLayoutsById = new Map(
7916
+ footerLayoutCatalog.map((layout) => [layout.id, layout])
7917
+ );
7918
+ var footerStylesById = new Map(
7919
+ footerStyleCatalog.map((style) => [style.id, style])
7920
+ );
7921
+ function identityQuietFooter(theme) {
7922
+ return {
7923
+ ...theme.footer,
7924
+ variant: "simple",
7925
+ maxWidth: "container",
7926
+ background: {
7927
+ type: "color",
7928
+ color: "surface"
7929
+ },
7930
+ navStyle: "minimal",
7931
+ navWeight: "regular",
7932
+ navColor: "text",
7933
+ navLinkStyle: {
7934
+ typography: "body",
7935
+ fontWeight: "regular",
7936
+ textTransform: "none",
7937
+ italic: false,
7938
+ colorToken: "text",
7939
+ hoverColorToken: "primary",
7940
+ padding: "none",
7941
+ borderRadius: "none"
7942
+ },
7943
+ navLayout: {
7944
+ layout: "inline-wrap",
7945
+ align: "start",
7946
+ gapX: "default",
7947
+ gapY: "tight"
7948
+ },
7949
+ logo: {
7950
+ showLogo: true,
7951
+ showLogoText: true,
7952
+ placement: "left",
7953
+ size: "sm",
7954
+ align: "start"
7955
+ },
7956
+ bottomBar: {
7957
+ enabled: false,
7958
+ fullBleed: false,
7959
+ textAlign: "left",
7960
+ paddingX: "default",
7961
+ paddingY: "compact",
7962
+ borderTop: {
7963
+ width: "none"
7964
+ }
7965
+ }
7966
+ };
7967
+ }
7572
7968
  function mutedGroundingFooter(theme) {
7573
- return theme.footer;
7969
+ return {
7970
+ ...identityQuietFooter(theme),
7971
+ background: theme.footer.background,
7972
+ navStyle: theme.footer.navStyle,
7973
+ navColor: theme.footer.navColor,
7974
+ navWeight: theme.footer.navWeight,
7975
+ navLinkStyle: theme.footer.navLinkStyle,
7976
+ bottomTextLinkStyle: theme.footer.bottomTextLinkStyle
7977
+ };
7574
7978
  }
7575
7979
  function brandTwoBandFooter(theme) {
7576
7980
  return {
@@ -7675,6 +8079,53 @@ function centeredCalmFooter(theme) {
7675
8079
  }
7676
8080
  };
7677
8081
  }
8082
+ function splitEditorialFooter(theme) {
8083
+ return {
8084
+ ...theme.footer,
8085
+ variant: "split",
8086
+ maxWidth: "container",
8087
+ background: {
8088
+ type: "color",
8089
+ color: "surface"
8090
+ },
8091
+ navStyle: "minimal",
8092
+ navWeight: "regular",
8093
+ navColor: "text",
8094
+ navLinkStyle: {
8095
+ typography: "body",
8096
+ fontWeight: "regular",
8097
+ textTransform: "none",
8098
+ italic: false,
8099
+ colorToken: "text",
8100
+ hoverColorToken: "primary",
8101
+ padding: "none",
8102
+ borderRadius: "none"
8103
+ },
8104
+ navLayout: {
8105
+ layout: "inline-wrap",
8106
+ align: "start",
8107
+ gapX: "relaxed",
8108
+ gapY: "tight"
8109
+ },
8110
+ logo: {
8111
+ showLogo: true,
8112
+ showLogoText: true,
8113
+ placement: "right",
8114
+ size: "sm",
8115
+ align: "end"
8116
+ },
8117
+ bottomBar: {
8118
+ enabled: true,
8119
+ fullBleed: false,
8120
+ textAlign: "left",
8121
+ paddingX: "default",
8122
+ paddingY: "compact",
8123
+ borderTop: {
8124
+ width: "thin"
8125
+ }
8126
+ }
8127
+ };
8128
+ }
7678
8129
  function editorialColumnsFooter(theme) {
7679
8130
  return {
7680
8131
  ...theme.footer,
@@ -7717,25 +8168,47 @@ function editorialColumnsFooter(theme) {
7717
8168
  };
7718
8169
  }
7719
8170
  var footerLookCatalog = defineExactCatalog()([
8171
+ {
8172
+ id: asFooterLookId("footer-identity-quiet"),
8173
+ label: "Identity footer",
8174
+ layoutId: asFooterLayoutId("identity"),
8175
+ styleId: asFooterStyleId("quiet"),
8176
+ compile: identityQuietFooter
8177
+ },
7720
8178
  {
7721
8179
  id: asFooterLookId("footer-muted-grounding"),
7722
8180
  label: "Muted grounding footer",
8181
+ layoutId: asFooterLayoutId("identity"),
8182
+ styleId: asFooterStyleId("quiet"),
8183
+ hiddenFromLayoutStyleControls: true,
7723
8184
  compile: mutedGroundingFooter
7724
8185
  },
7725
8186
  {
7726
8187
  id: asFooterLookId("footer-centered-calm"),
7727
8188
  label: "Centered calm footer",
8189
+ layoutId: asFooterLayoutId("centered"),
8190
+ styleId: asFooterStyleId("calm"),
7728
8191
  compile: centeredCalmFooter
7729
8192
  },
8193
+ {
8194
+ id: asFooterLookId("footer-split-editorial"),
8195
+ label: "Split editorial footer",
8196
+ layoutId: asFooterLayoutId("split"),
8197
+ styleId: asFooterStyleId("editorial"),
8198
+ compile: splitEditorialFooter
8199
+ },
7730
8200
  {
7731
8201
  id: asFooterLookId("footer-editorial-columns"),
7732
8202
  label: "Editorial columns footer",
8203
+ layoutId: asFooterLayoutId("columns"),
8204
+ styleId: asFooterStyleId("editorial"),
7733
8205
  compile: editorialColumnsFooter
7734
8206
  },
7735
8207
  {
7736
8208
  id: asFooterLookId("site-footer-brand-two-band"),
7737
8209
  label: "Two-band brand footer",
7738
- maxRecommendedNavDensity: "balanced",
8210
+ layoutId: asFooterLayoutId("split"),
8211
+ styleId: asFooterStyleId("brand-band"),
7739
8212
  allowedContentPresence: ["default-footer", "default-and-blocks"],
7740
8213
  compile: brandTwoBandFooter
7741
8214
  }
@@ -7938,6 +8411,30 @@ var luxeContrastTypography = {
7938
8411
  },
7939
8412
  scale: "spacious"
7940
8413
  };
8414
+ var kirtanOrnateTypography = {
8415
+ body: {
8416
+ family: "Jost, system-ui, sans-serif",
8417
+ size: "md",
8418
+ weight: "regular",
8419
+ lineHeight: "relaxed",
8420
+ letterSpacing: "normal"
8421
+ },
8422
+ headings: {
8423
+ default: {
8424
+ family: "Marcellus, Georgia, serif",
8425
+ weight: "regular",
8426
+ lineHeight: "normal",
8427
+ letterSpacing: "normal",
8428
+ colorToken: "primary",
8429
+ italic: null,
8430
+ case: null
8431
+ },
8432
+ h1: { size: "2xl", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null },
8433
+ h2: { size: "xl", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null },
8434
+ h3: { size: "md", weight: "regular", lineHeight: "relaxed", letterSpacing: "normal", italic: null }
8435
+ },
8436
+ scale: "spacious"
8437
+ };
7941
8438
  var boldDisplayTypography = {
7942
8439
  body: {
7943
8440
  family: "Manrope, system-ui, sans-serif",
@@ -7972,16 +8469,16 @@ var originalJoyTypography = {
7972
8469
  },
7973
8470
  headings: {
7974
8471
  default: {
7975
- family: "Bricolage Grotesque, system-ui, sans-serif",
7976
- weight: "bold",
8472
+ family: "Lobster, cursive",
8473
+ weight: "regular",
7977
8474
  lineHeight: "normal",
7978
- letterSpacing: "tight",
8475
+ letterSpacing: "normal",
7979
8476
  italic: null,
7980
8477
  case: null
7981
8478
  },
7982
- h1: { size: "2xl", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null },
7983
- h2: { size: "xl", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null },
7984
- h3: { size: "lg", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null }
8479
+ h1: { size: "2xl", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null },
8480
+ h2: { size: "xl", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null },
8481
+ h3: { size: "lg", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null }
7985
8482
  },
7986
8483
  scale: "balanced"
7987
8484
  };
@@ -8046,6 +8543,32 @@ var typographyPresets = [
8046
8543
  slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
8047
8544
  typography: luxeContrastTypography
8048
8545
  }),
8546
+ defineTypographyPreset({
8547
+ id: "typography-preset:kirtan-ornate",
8548
+ name: "Kirtan Ornate",
8549
+ description: "Marcellus devotional headings over a refined Jost body, matching dark ceremonial layouts.",
8550
+ defaultFonts: { body: "Jost, system-ui, sans-serif", heading: "Marcellus, Georgia, serif" },
8551
+ recommendedFonts: {
8552
+ body: ["Jost", "Manrope", "Inter"],
8553
+ heading: ["Marcellus", "Cormorant Garamond", "Playfair Display"]
8554
+ },
8555
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
8556
+ typography: kirtanOrnateTypography,
8557
+ heroTypography: {
8558
+ headlineSize: "6xl",
8559
+ headlineLineHeight: "normal",
8560
+ subheadlineSize: "xl",
8561
+ subheadlineLineHeight: "relaxed",
8562
+ microHeadlineSize: "5xl",
8563
+ microHeadlineLineHeight: "normal",
8564
+ microSubheadlineSize: "lg",
8565
+ microSubheadlineLineHeight: "relaxed",
8566
+ responsive: {
8567
+ tablet: { headlineSize: "5xl" },
8568
+ mobile: { headlineSize: "4xl", subheadlineSize: "lg" }
8569
+ }
8570
+ }
8571
+ }),
8049
8572
  defineTypographyPreset({
8050
8573
  id: "typography-preset:bold-display",
8051
8574
  name: "Bold Display",
@@ -8075,11 +8598,11 @@ var typographyPresets = [
8075
8598
  defineTypographyPreset({
8076
8599
  id: "typography-preset:original-joy",
8077
8600
  name: "Original Joy",
8078
- description: "Bold Bricolage Grotesque display headings over a clean DM Sans body, editorial and warm.",
8079
- defaultFonts: { body: "DM Sans, system-ui, sans-serif", heading: "Bricolage Grotesque, system-ui, sans-serif" },
8601
+ description: "Lobster display headings over a clean DM Sans body, expressive and warm.",
8602
+ defaultFonts: { body: "DM Sans, system-ui, sans-serif", heading: "Lobster, cursive" },
8080
8603
  recommendedFonts: {
8081
8604
  body: ["DM Sans", "Inter", "Manrope"],
8082
- heading: ["Bricolage Grotesque", "Space Grotesk", "Archivo"]
8605
+ heading: ["Lobster", "Bricolage Grotesque", "Space Grotesk"]
8083
8606
  },
8084
8607
  slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
8085
8608
  typography: originalJoyTypography,
@@ -8103,384 +8626,780 @@ var typographyPresetsById = new Map(
8103
8626
  typographyPresets.map((preset) => [preset.id, preset])
8104
8627
  );
8105
8628
 
8106
- // ../theme-core/src/site-styles/curatedSiteStyles.ts
8107
- var SOFT_EARTH_SITE_STYLE_ID_VALUE = "site-style:soft-earth";
8108
- var SOFT_EARTH_SITE_STYLE_ID = asSiteStyleId(SOFT_EARTH_SITE_STYLE_ID_VALUE);
8109
- var curatedSiteStyleIdValues = [
8110
- "site-style:calm-studio",
8111
- "site-style:clear-professional",
8112
- "site-style:warm-editorial",
8113
- "site-style:bright-community",
8114
- "site-style:quiet-luxury",
8115
- "site-style:practical-services",
8116
- "site-style:quiet-practice",
8117
- "site-style:personal-retreat-journal",
8118
- "site-style:tactile-workshop",
8119
- "site-style:modern-wellness",
8120
- "site-style:clarity-zen-blue",
8121
- SOFT_EARTH_SITE_STYLE_ID_VALUE,
8122
- "site-style:bold-launch",
8123
- "site-style:south-west-twerk-school",
8124
- "site-style:original-joy"
8125
- ];
8126
- var quietBudget = {
8127
- accentDensity: "low",
8128
- panelDensity: "medium",
8129
- transitionMix: "quiet",
8130
- primaryCtaLimit: 2,
8131
- mediaDensity: "medium",
8132
- decorativeRepetition: "low"
8133
- };
8134
- var balancedBudget = {
8135
- accentDensity: "medium",
8136
- panelDensity: "medium",
8137
- transitionMix: "balanced",
8138
- primaryCtaLimit: 3,
8139
- mediaDensity: "medium",
8140
- decorativeRepetition: "medium"
8141
- };
8142
- var expressiveBudget = {
8143
- accentDensity: "high",
8144
- panelDensity: "high",
8145
- transitionMix: "expressive",
8146
- primaryCtaLimit: 3,
8147
- mediaDensity: "high",
8148
- decorativeRepetition: "medium"
8149
- };
8150
- var expressiveUnderlineInputs = {
8151
- base: {
8152
- background: { type: "transparent" },
8153
- textColorToken: "text",
8154
- border: {
8155
- widthClass: "border-2",
8156
- colorToken: "border",
8157
- style: "underline"
8158
- },
8159
- corners: "square",
8160
- shadow: null,
8161
- spacing: "compact",
8162
- fontSize: "base"
8163
- },
8164
- label: {
8165
- textColorToken: "primary",
8166
- fontWeight: "black",
8167
- fontSize: "xs",
8168
- textTransform: "uppercase",
8169
- letterSpacing: "widest",
8170
- opacity: 1
8171
- },
8172
- focus: {
8173
- ringColorToken: "secondary",
8174
- ringWidth: "0",
8175
- borderColorToken: "secondary"
8176
- },
8177
- error: {
8178
- borderColorToken: "destructive",
8179
- textColorToken: "destructive"
8180
- },
8181
- disabled: {
8182
- backgroundColorToken: "surface",
8183
- textColorToken: "text",
8184
- opacity: 0.6
8185
- }
8186
- };
8187
- function uniqueContentFrameKinds() {
8188
- const kinds = [
8189
- ...new Set(
8190
- generatedDesignOptionCatalog.contentFrames.map((frame) => frame.kind)
8191
- )
8192
- ];
8193
- const firstKind = kinds[0];
8194
- if (!firstKind) {
8195
- throw new Error(
8196
- "Expected generated design option catalog to expose at least one content frame kind."
8197
- );
8629
+ // ../theme-core/src/site-styles/designState.ts
8630
+ import { z as z22 } from "zod";
8631
+ var themeV2DesignStateSchemaVersion = 1;
8632
+ var designResolutionPolicySchema = z22.enum(["generated", "user", "admin", "sdk"]);
8633
+ var runtimeStyleFieldNameSchema = z22.enum(themeV2RuntimeStyleFieldNames);
8634
+ var nonEmptyRuntimeStyleFieldNamesSchema = z22.array(runtimeStyleFieldNameSchema).min(1).transform((fields3) => [
8635
+ fields3[0],
8636
+ ...fields3.slice(1)
8637
+ ]);
8638
+ var heroLegibilityStrategySchema = z22.enum([
8639
+ "none",
8640
+ "scrim-gradient",
8641
+ "solid-panel"
8642
+ ]);
8643
+ var heroCompositionIntentSchema = z22.enum([
8644
+ "center",
8645
+ "bottom-left"
8646
+ ]);
8647
+ var heroTypographyScaleIntentSchema = z22.enum([
8648
+ "quiet",
8649
+ "editorial",
8650
+ "display",
8651
+ "poster"
8652
+ ]);
8653
+ var sectionHeightIntentSchema = z22.enum([
8654
+ "default",
8655
+ "banner",
8656
+ "hero",
8657
+ "immersive"
8658
+ ]);
8659
+ var imageSurfaceTreatmentIntensitySchema = z22.enum(["soft", "balanced", "strong"]);
8660
+ var imageSurfaceMotionSchema = z22.enum(["static", "fixed-frame"]);
8661
+ var imageSurfaceTreatmentSchema = z22.discriminatedUnion("kind", [
8662
+ z22.object({ kind: z22.literal("none") }).strict(),
8663
+ z22.object({
8664
+ kind: z22.literal("brand-scrim"),
8665
+ token: z22.enum(["primary", "secondary", "accent"]),
8666
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
8667
+ }).strict(),
8668
+ z22.object({
8669
+ kind: z22.literal("brand-wash"),
8670
+ token: z22.enum(["primary", "secondary", "accent"]),
8671
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
8672
+ }).strict(),
8673
+ z22.object({
8674
+ kind: z22.literal("neutral-scrim"),
8675
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
8676
+ }).strict(),
8677
+ z22.object({
8678
+ kind: z22.literal("neutral-wash"),
8679
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
8680
+ }).strict(),
8681
+ z22.object({
8682
+ kind: z22.literal("solid-panel"),
8683
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
8684
+ }).strict()
8685
+ ]);
8686
+ var testimonialCardTreatmentSchema = z22.enum(["default", "accent-quote"]);
8687
+ var tileTreatmentSchema = z22.enum(tileTreatmentValues);
8688
+ var eventListTreatmentSchema = z22.enum(eventListTreatmentValues);
8689
+ var eyebrowTreatmentSchema = z22.enum(eyebrowTreatmentValues);
8690
+ function uniqueNonEmpty(values) {
8691
+ const uniqueValues = [...new Set(values)];
8692
+ const firstValue = uniqueValues[0];
8693
+ if (!firstValue) {
8694
+ throw new Error("Expected at least one Theme V2 design state option.");
8198
8695
  }
8199
- return [firstKind, ...kinds.slice(1)];
8696
+ return [firstValue, ...uniqueValues.slice(1)];
8200
8697
  }
8201
- var generatedContentFrameKinds = uniqueContentFrameKinds();
8202
- function defineCuratedSiteStyle(input) {
8203
- const legacyHeaderLookIds = input.recommendedHeaderLookIds ?? ["clean-base"];
8204
- const inferredHeaderCuration = inferHeaderCurationFromLegacyLooks(
8205
- legacyHeaderLookIds,
8206
- input.tokenRecipes
8207
- );
8208
- const typographyPresetChoices = input.typographyPresetChoices ?? defaultTypographyPresetChoicesForRecipe(input.tokenRecipes.typography);
8209
- const defaultTypographyPresetId = input.defaultTypographyPresetId ? asTypographyPresetId(input.defaultTypographyPresetId) : typographyPresetChoices[0].id;
8210
- if (!typographyPresetChoices.some(
8211
- (choice) => choice.id === defaultTypographyPresetId
8212
- )) {
8213
- throw new Error(
8214
- `Default typography preset ${defaultTypographyPresetId} is not curated for site style ${input.id}.`
8215
- );
8216
- }
8217
- return {
8218
- id: asSiteStyleId(input.id),
8219
- name: input.name,
8220
- description: input.description,
8221
- generationBrief: input.generationBrief,
8222
- selectionKeywordRules: input.selectionKeywordRules ?? [],
8223
- siteCreatorSelection: input.siteCreatorSelection ?? {
8224
- kind: "explicit_only"
8225
- },
8226
- template: {
8227
- id: asDesignSystemTemplateId(
8228
- `template:${input.id.replace("site-style:", "")}`
8229
- ),
8230
- name: input.name,
8231
- version: 1,
8232
- tokenRecipes: input.tokenRecipes,
8233
- compositionBudget: input.compositionBudget,
8234
- supportedSectionSurfaces: generatedDesignOptionCatalog.sectionSurfaces,
8235
- supportedContentFrames: generatedContentFrameKinds,
8236
- supportedItemSurfaces: generatedDesignOptionCatalog.itemSurfaces,
8237
- supportedTransitions: generatedDesignOptionCatalog.transitions
8238
- },
8239
- // Decoration is opt-in per style so it stays a distinguishing feature, not
8240
- // wallpaper. Styles that want a mark set `headingDecoration` explicitly;
8241
- // clean/minimal styles default to none.
8242
- headingDecoration: input.headingDecoration ?? noHeadingDecoration,
8243
- ...input.themeOverrides ? { themeOverrides: input.themeOverrides } : {},
8244
- ...input.defaultBlockVariants ? { defaultBlockVariants: input.defaultBlockVariants } : {},
8245
- recommendedAppearancePresetIds: (input.recommendedAppearancePresetIds ?? []).map(asAppearancePresetId),
8246
- defaultHeaderSelection: input.defaultHeaderSelection ? {
8247
- layoutId: asHeaderLayoutId(input.defaultHeaderSelection.layoutId),
8248
- styleId: asHeaderStyleId(input.defaultHeaderSelection.styleId)
8249
- } : inferredHeaderCuration.defaultHeaderSelection,
8250
- recommendedHeaderLayoutChoices: input.recommendedHeaderLayoutChoices ?? inferredHeaderCuration.recommendedHeaderLayoutChoices,
8251
- recommendedHeaderStyleChoicesByLayout: input.recommendedHeaderStyleChoicesByLayout ?? inferredHeaderCuration.recommendedHeaderStyleChoicesByLayout,
8252
- discouragedHeaderSelections: input.discouragedHeaderSelections?.map(
8253
- (selection) => ({
8254
- layoutId: asHeaderLayoutId(selection.layoutId),
8255
- styleId: asHeaderStyleId(selection.styleId)
8256
- })
8257
- ),
8258
- recommendedHeaderLookIds: legacyHeaderLookIds.map(asHeaderLookId),
8259
- // Empty is intentional: resolveFooterLook always appends its guaranteed fallback.
8260
- recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(
8261
- asFooterLookId
8262
- ),
8263
- buttonPersonalityChoices: input.buttonPersonalityChoices,
8264
- paletteVariantChoices: input.paletteVariantChoices,
8265
- typographyPresetChoices,
8266
- defaultTypographyPresetId
8267
- };
8268
- }
8269
- function buttonChoice(id, note) {
8270
- return note ? { id: asButtonPersonalityId(id), note } : { id: asButtonPersonalityId(id) };
8271
- }
8272
- function paletteChoice(id, note) {
8273
- return note ? { id: asPaletteVariantId(id), note } : { id: asPaletteVariantId(id) };
8274
- }
8275
- function headerLayoutChoice(id, note) {
8276
- return note ? { id: asHeaderLayoutId(id), note } : { id: asHeaderLayoutId(id) };
8277
- }
8278
- function headerStyleChoice(id, note) {
8279
- return note ? { id: asHeaderStyleId(id), note } : { id: asHeaderStyleId(id) };
8280
- }
8281
- function unbrandHeaderLayoutId(id) {
8282
- return id;
8283
- }
8284
- function uniqueHeaderLayoutChoices(choices) {
8285
- const seen = /* @__PURE__ */ new Set();
8286
- const unique = choices.filter((choice) => {
8287
- if (seen.has(choice.id)) return false;
8288
- seen.add(choice.id);
8289
- return true;
8290
- });
8291
- const first = unique[0];
8292
- if (!first) {
8293
- throw new Error("Expected at least one curated header layout choice.");
8294
- }
8295
- return [first, ...unique.slice(1)];
8296
- }
8297
- function nonEmptyHeaderStyleChoices(choices, fallbackLayoutId) {
8298
- const first = choices[0] ?? {
8299
- id: getCompatibleHeaderStyleIds(fallbackLayoutId)[0] ?? asHeaderStyleId("minimal")
8300
- };
8301
- return [first, ...choices.slice(1)];
8698
+ var userPanelTreatments = uniqueNonEmpty(
8699
+ userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "panel").map((frame) => frame.treatment)
8700
+ );
8701
+ var userFlushTreatments = uniqueNonEmpty(
8702
+ userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "flush-panel").map((frame) => frame.treatment)
8703
+ );
8704
+ var userFlushBleeds = uniqueNonEmpty(
8705
+ userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "flush-panel").map((frame) => frame.bleed)
8706
+ );
8707
+ var contentFrameIntentSchema = z22.discriminatedUnion("kind", [
8708
+ z22.object({ kind: z22.literal("plain") }).strict(),
8709
+ z22.object({
8710
+ kind: z22.literal("panel"),
8711
+ treatment: z22.enum(userPanelTreatments)
8712
+ }).strict(),
8713
+ z22.object({
8714
+ kind: z22.literal("flush-panel"),
8715
+ treatment: z22.enum(userFlushTreatments),
8716
+ bleed: z22.enum(userFlushBleeds)
8717
+ }).strict()
8718
+ ]);
8719
+ var blockDesignPlanSchema = z22.object({
8720
+ blockId: z22.string().min(1).transform(asDesignBlockId),
8721
+ blockKind: z22.string().min(1),
8722
+ purpose: z22.string().min(1),
8723
+ sectionSurface: z22.enum(userDesignOptionCatalog.sectionSurfaces),
8724
+ contentFrame: contentFrameIntentSchema,
8725
+ itemSurface: z22.enum(userDesignOptionCatalog.itemSurfaces),
8726
+ transitionAfter: z22.enum(userDesignOptionCatalog.transitions),
8727
+ emphasis: z22.enum(userDesignOptionCatalog.emphases),
8728
+ sectionHeight: sectionHeightIntentSchema.optional(),
8729
+ heroLegibility: heroLegibilityStrategySchema.optional(),
8730
+ heroComposition: heroCompositionIntentSchema.optional(),
8731
+ heroTypographyScale: heroTypographyScaleIntentSchema.optional(),
8732
+ imageSurfaceTreatment: imageSurfaceTreatmentSchema.optional(),
8733
+ imageSurfaceMotion: imageSurfaceMotionSchema.optional(),
8734
+ testimonialCardTreatment: testimonialCardTreatmentSchema.optional(),
8735
+ tileTreatment: tileTreatmentSchema.optional(),
8736
+ eventListTreatment: eventListTreatmentSchema.optional(),
8737
+ eyebrowTreatment: eyebrowTreatmentSchema.optional()
8738
+ }).strict();
8739
+ var styleAuthoritySchema = z22.discriminatedUnion("kind", [
8740
+ z22.object({
8741
+ kind: z22.literal("theme-v2"),
8742
+ source: designResolutionPolicySchema,
8743
+ siteStyleId: z22.string().min(1).transform(asSiteStyleId),
8744
+ templateId: z22.string().min(1).transform(asDesignSystemTemplateId),
8745
+ templateVersion: z22.number().int().nonnegative(),
8746
+ resolverVersion: z22.number().int().nonnegative()
8747
+ }).strict(),
8748
+ z22.object({
8749
+ kind: z22.literal("legacy-raw"),
8750
+ reason: z22.enum(["pre-theme-v2", "manual-runtime-fields"])
8751
+ }).strict(),
8752
+ z22.object({
8753
+ kind: z22.literal("advanced-detached"),
8754
+ reason: z22.literal("detached-custom-runtime-fields")
8755
+ }).strict()
8756
+ ]);
8757
+ var blockRuntimeStyleAuthoritySchema = z22.object({
8758
+ unit: z22.literal("block-runtime-fields"),
8759
+ blockId: z22.string().min(1).transform(asDesignBlockId),
8760
+ fields: nonEmptyRuntimeStyleFieldNamesSchema,
8761
+ authority: styleAuthoritySchema
8762
+ }).strict();
8763
+ var persistedPageDesignStateV1Schema = z22.object({
8764
+ schemaVersion: z22.literal(themeV2DesignStateSchemaVersion),
8765
+ siteStyleId: z22.string().min(1).transform(asSiteStyleId),
8766
+ templateId: z22.string().min(1).transform(asDesignSystemTemplateId),
8767
+ templateVersion: z22.number().int().nonnegative(),
8768
+ resolverVersion: z22.number().int().nonnegative(),
8769
+ rhythmPresetId: z22.string().min(1),
8770
+ blocks: z22.array(blockDesignPlanSchema),
8771
+ styleAuthorities: z22.array(blockRuntimeStyleAuthoritySchema)
8772
+ }).strict();
8773
+
8774
+ // ../theme-core/src/site-styles/runtimeCompiler.ts
8775
+ function defineDesignRuntimeRules(rules) {
8776
+ return rules;
8302
8777
  }
8303
- function uniqueCompatibleHeaderStyleChoices(choices, fallbackLayoutId) {
8304
- const compatible = new Set(getCompatibleHeaderStyleIds(fallbackLayoutId));
8305
- const seen = /* @__PURE__ */ new Set();
8306
- const unique = choices.filter((choice) => {
8307
- if (!compatible.has(choice.id)) return false;
8308
- if (seen.has(choice.id)) return false;
8309
- seen.add(choice.id);
8310
- return true;
8311
- });
8312
- return nonEmptyHeaderStyleChoices(unique, fallbackLayoutId);
8778
+ function defineComponentRuntimeRules(rules) {
8779
+ return rules;
8313
8780
  }
8314
- function inferredHeaderStyleValuesForRecipes(layoutId, recipes) {
8315
- switch (layoutId) {
8316
- case "classic":
8317
- if (isExpressiveRecipe(recipes)) {
8318
- return [
8319
- "brand-bar",
8320
- "brand-underline",
8321
- "flat-tabs",
8322
- "brand-pill",
8323
- "fine-line"
8324
- ];
8325
- }
8326
- if (recipes.spacing === "compact") {
8327
- return ["flat-tabs", "fine-line", "minimal", "brand-bar"];
8328
- }
8329
- if (isSerifTypographyRecipe(recipes)) {
8330
- return ["serif-line", "fine-line", "minimal", "soft-bar"];
8781
+ var defaultDesignRuntimeRules = defineDesignRuntimeRules({
8782
+ sectionSurfaces: {
8783
+ base: {},
8784
+ "muted-band": {
8785
+ background: {
8786
+ type: "color",
8787
+ color: "muted"
8331
8788
  }
8332
- if (recipes.radius === "rounded" || recipes.radius === "pill") {
8333
- return ["soft-bar", "pill-nav", "fine-line", "minimal"];
8789
+ },
8790
+ "accent-band": {
8791
+ background: {
8792
+ type: "color",
8793
+ color: "primary"
8334
8794
  }
8335
- return ["fine-line", "minimal", "soft-bar", "brand-bar"];
8336
- case "centered":
8337
- if (isSerifTypographyRecipe(recipes)) {
8338
- return ["serif-line", "fine-line", "minimal", "soft-bar"];
8795
+ },
8796
+ "brand-depth-band": {
8797
+ background: {
8798
+ type: "color",
8799
+ color: "primary-800"
8339
8800
  }
8340
- if (isExpressiveRecipe(recipes)) {
8341
- return ["brand-pill", "flat-tabs", "brand-bar", "fine-line"];
8801
+ },
8802
+ "hero-image": {
8803
+ background: {
8804
+ type: "image",
8805
+ opacity: 1,
8806
+ position: "center center",
8807
+ ...uniformSectionForeground("text")
8342
8808
  }
8343
- if (recipes.radius === "rounded" || recipes.radius === "pill") {
8344
- return ["soft-bar", "pill-nav", "fine-line", "minimal"];
8809
+ }
8810
+ },
8811
+ heroLegibility: {
8812
+ "scrim-gradient": {
8813
+ type: "gradient",
8814
+ gradient: "linear-gradient(180deg, rgba(255,255,255,0.38) 0%, rgba(244,241,234,0.62) 90%)",
8815
+ opacity: 1
8816
+ },
8817
+ "solid-panel": {
8818
+ type: "color",
8819
+ color: "surface",
8820
+ opacity: 0.88
8821
+ }
8822
+ },
8823
+ transitionClassName: (transition, fromSurface, toSurface) => transition === "none" ? null : `site-style-transition-${transition}-from-${fromSurface}-to-${toSurface}`
8824
+ });
8825
+ var defaultComponentRuntimeRules = defineComponentRuntimeRules({
8826
+ panelFrames: {
8827
+ inset: {
8828
+ spacing: "comfortable",
8829
+ rounded: "xl",
8830
+ raised: false,
8831
+ background: {
8832
+ type: "color",
8833
+ color: "surfaceAlt",
8834
+ textColor: "text"
8345
8835
  }
8346
- return ["minimal", "fine-line", "soft-bar"];
8347
- case "floating":
8348
- if (isExpressiveRecipe(recipes)) {
8349
- return ["glass", "split-glass", "brand-pill", "soft-shell"];
8836
+ },
8837
+ raised: {
8838
+ spacing: "comfortable",
8839
+ rounded: "xl",
8840
+ raised: true,
8841
+ background: {
8842
+ type: "color",
8843
+ color: "surfaceAlt",
8844
+ textColor: "text"
8350
8845
  }
8351
- if (isSerifTypographyRecipe(recipes)) {
8352
- return ["split-pill", "minimal-surface", "soft-shell"];
8846
+ },
8847
+ editorial: {
8848
+ spacing: "medium",
8849
+ rounded: "xl",
8850
+ raised: false,
8851
+ background: {
8852
+ type: "color",
8853
+ color: "surface",
8854
+ textColor: "text"
8353
8855
  }
8354
- return ["soft-shell", "minimal-surface", "glass"];
8355
- default:
8356
- return [];
8357
- }
8358
- }
8359
- function isExpressiveRecipe(recipes) {
8360
- return recipes.contrast === "maximum" || recipes.shadow === "layered" || recipes.motion === "expressive";
8361
- }
8362
- function isSerifTypographyRecipe(recipes) {
8363
- return recipes.typography === "serif-editorial" || recipes.typography === "classic-serif";
8364
- }
8365
- function inferHeaderCurationFromLegacyLooks(lookIds, recipes) {
8366
- const selections = lookIds.map((lookId) => resolveLegacyHeaderLookAlias(asHeaderLookId(lookId))).filter(
8367
- (selection) => Boolean(selection)
8368
- );
8369
- const defaultHeaderSelection = selections[0] ?? {
8370
- layoutId: asHeaderLayoutId("classic"),
8371
- styleId: asHeaderStyleId("minimal")
8372
- };
8373
- const layoutChoices = uniqueHeaderLayoutChoices(
8374
- selections.map((selection) => headerLayoutChoice(selection.layoutId))
8375
- );
8376
- const stylesByLayout = {};
8377
- for (const layoutChoice of layoutChoices) {
8378
- const legacyStyleChoices = selections.filter((selection) => selection.layoutId === layoutChoice.id).map((selection) => headerStyleChoice(selection.styleId));
8379
- const inferredStyleChoices = inferredHeaderStyleValuesForRecipes(
8380
- layoutChoice.id,
8381
- recipes
8382
- ).map((styleId) => headerStyleChoice(styleId));
8383
- stylesByLayout[unbrandHeaderLayoutId(layoutChoice.id)] = uniqueCompatibleHeaderStyleChoices(
8384
- [...legacyStyleChoices, ...inferredStyleChoices],
8385
- layoutChoice.id
8386
- );
8856
+ }
8857
+ },
8858
+ flushFrames: {
8859
+ "media-panel": {
8860
+ fullWidth: true,
8861
+ spacing: "none",
8862
+ rounded: "none",
8863
+ raised: false
8864
+ }
8865
+ },
8866
+ itemSurfaces: {
8867
+ none: null,
8868
+ default: {
8869
+ spacing: "medium",
8870
+ rounded: "lg",
8871
+ raised: false
8872
+ },
8873
+ flat: {
8874
+ spacing: "medium",
8875
+ rounded: "lg",
8876
+ raised: false
8877
+ },
8878
+ outlined: {
8879
+ spacing: "medium",
8880
+ rounded: "lg",
8881
+ raised: false,
8882
+ border: {
8883
+ enabled: true,
8884
+ width: "1",
8885
+ colorToken: "border"
8886
+ }
8887
+ },
8888
+ raised: {
8889
+ spacing: "medium",
8890
+ rounded: "xl",
8891
+ raised: true
8892
+ },
8893
+ inset: {
8894
+ treatment: "soft-panel",
8895
+ spacing: "comfortable",
8896
+ rounded: "xl",
8897
+ raised: false,
8898
+ border: {
8899
+ enabled: false
8900
+ },
8901
+ background: {
8902
+ type: "color",
8903
+ color: "surfaceAlt",
8904
+ textColor: "text"
8905
+ }
8906
+ },
8907
+ editorial: {
8908
+ // Boxless open column with a short rule on top; the visual treatment
8909
+ // lives in blocks-static/card-treatments.css.
8910
+ treatment: "editorial-rule",
8911
+ spacing: "none",
8912
+ rounded: "none",
8913
+ raised: false,
8914
+ border: {
8915
+ enabled: false
8916
+ }
8917
+ },
8918
+ "color-blocked": {
8919
+ // Bold, flat colour-blocked cards. The per-card background colour cycle
8920
+ // (by position) and staggered offset live in
8921
+ // blocks-static/card-treatments.css; here we set the shared shape:
8922
+ // generous padding, large radius, no border, flat (no shadow).
8923
+ treatment: "color-blocked",
8924
+ spacing: "spacious",
8925
+ rounded: "2xl",
8926
+ raised: false,
8927
+ border: {
8928
+ enabled: false
8929
+ }
8930
+ }
8387
8931
  }
8932
+ });
8933
+ function uniformSectionForeground(token) {
8388
8934
  return {
8389
- defaultHeaderSelection,
8390
- recommendedHeaderLayoutChoices: layoutChoices,
8391
- recommendedHeaderStyleChoicesByLayout: stylesByLayout
8935
+ textColor: token,
8936
+ headingColor: token,
8937
+ linkColor: token,
8938
+ supportingColor: token
8392
8939
  };
8393
8940
  }
8394
- function typographyChoice(id, note) {
8395
- return note ? { id: asTypographyPresetId(id), note } : { id: asTypographyPresetId(id) };
8396
- }
8397
- function defaultTypographyPresetChoicesForRecipe(recipe) {
8398
- switch (recipe) {
8399
- case "clean-sans":
8400
- return [
8401
- typographyChoice("typography-preset:modern-sans"),
8402
- typographyChoice("typography-preset:luxe-contrast"),
8403
- typographyChoice("typography-preset:bold-display")
8404
- ];
8405
- case "friendly-sans":
8406
- return [
8407
- typographyChoice("typography-preset:warm-rounded"),
8408
- typographyChoice("typography-preset:modern-sans"),
8409
- typographyChoice("typography-preset:editorial-serif")
8410
- ];
8411
- case "serif-editorial":
8412
- return [
8413
- typographyChoice("typography-preset:editorial-serif"),
8414
- typographyChoice("typography-preset:classic-serif"),
8415
- typographyChoice("typography-preset:warm-rounded")
8416
- ];
8417
- case "classic-serif":
8418
- return [
8419
- typographyChoice("typography-preset:classic-serif"),
8420
- typographyChoice("typography-preset:luxe-contrast"),
8421
- typographyChoice("typography-preset:editorial-serif")
8422
- ];
8423
- }
8424
- }
8425
- var curatedSiteStyles = [
8426
- defineCuratedSiteStyle({
8427
- id: "site-style:calm-studio",
8428
- name: "Calm Studio",
8429
- themeOverrides: {
8430
- accordions: calmPanelAccordionSystem,
8431
- testimonialQuote: serifDisplayQuote
8432
- },
8433
- headingDecoration: { family: "short-center-rule", colorToken: "primary" },
8434
- description: "Soft, measured, and spacious for intimate appointment or class businesses.",
8435
- generationBrief: "Use calm pacing, concise copy, generous breathing room, and natural imagery. Keep calls to action steady rather than urgent.",
8436
- tokenRecipes: {
8437
- palette: "soft-natural",
8438
- contrast: "standard",
8439
- radius: "soft",
8440
- shadow: "subtle",
8441
- typography: "friendly-sans",
8442
- spacing: "airy",
8443
- motion: "subtle"
8941
+
8942
+ // ../theme-core/src/site-styles/curatedSiteStyles.ts
8943
+ var SOFT_EARTH_SITE_STYLE_ID_VALUE = "site-style:soft-earth";
8944
+ var SOFT_EARTH_SITE_STYLE_ID = asSiteStyleId(SOFT_EARTH_SITE_STYLE_ID_VALUE);
8945
+ var curatedSiteStyleIdValues = [
8946
+ "site-style:calm-studio",
8947
+ "site-style:clear-professional",
8948
+ "site-style:warm-editorial",
8949
+ "site-style:bright-community",
8950
+ "site-style:quiet-luxury",
8951
+ "site-style:practical-services",
8952
+ "site-style:quiet-practice",
8953
+ "site-style:personal-retreat-journal",
8954
+ "site-style:tactile-workshop",
8955
+ "site-style:modern-wellness",
8956
+ "site-style:clarity-zen-blue",
8957
+ SOFT_EARTH_SITE_STYLE_ID_VALUE,
8958
+ "site-style:bold-launch",
8959
+ "site-style:south-west-twerk-school",
8960
+ "site-style:kirtan-ornate",
8961
+ "site-style:original-joy"
8962
+ ];
8963
+ var quietBudget = {
8964
+ accentDensity: "low",
8965
+ panelDensity: "medium",
8966
+ transitionMix: "quiet",
8967
+ primaryCtaLimit: 2,
8968
+ mediaDensity: "medium",
8969
+ decorativeRepetition: "low"
8970
+ };
8971
+ var balancedBudget = {
8972
+ accentDensity: "medium",
8973
+ panelDensity: "medium",
8974
+ transitionMix: "balanced",
8975
+ primaryCtaLimit: 3,
8976
+ mediaDensity: "medium",
8977
+ decorativeRepetition: "medium"
8978
+ };
8979
+ var expressiveBudget = {
8980
+ accentDensity: "high",
8981
+ panelDensity: "high",
8982
+ transitionMix: "expressive",
8983
+ primaryCtaLimit: 3,
8984
+ mediaDensity: "high",
8985
+ decorativeRepetition: "medium"
8986
+ };
8987
+ var kirtanOrnateDesignRuntimeRules = defineDesignRuntimeRules({
8988
+ ...defaultDesignRuntimeRules,
8989
+ defaultEyebrowTreatment: "accent",
8990
+ sectionSurfaces: {
8991
+ ...defaultDesignRuntimeRules.sectionSurfaces,
8992
+ "muted-band": {
8993
+ background: {
8994
+ type: "color",
8995
+ color: "muted"
8996
+ },
8997
+ foreground: {
8998
+ textColor: "text",
8999
+ headingColor: "primary",
9000
+ linkColor: "primary",
9001
+ supportingColor: "text"
9002
+ }
8444
9003
  },
8445
- compositionBudget: quietBudget,
8446
- recommendedHeaderLookIds: [
8447
- "centered-calm",
8448
- "minimal-transparent",
8449
- "clean-base"
8450
- ],
8451
- buttonPersonalityChoices: [
8452
- buttonChoice("soft-pill"),
8453
- buttonChoice("pebble"),
8454
- buttonChoice("editorial-link"),
8455
- buttonChoice("brushed-wash")
8456
- ],
8457
- paletteVariantChoices: [
8458
- paletteChoice("soft-natural-sage"),
8459
- paletteChoice("soft-natural-stone"),
8460
- paletteChoice("warm-neutral-clay"),
8461
- paletteChoice("soft-natural-watercolor")
8462
- ]
8463
- }),
8464
- defineCuratedSiteStyle({
8465
- id: "site-style:clear-professional",
8466
- name: "Clear Professional",
8467
- themeOverrides: {
8468
- accordions: calmPanelAccordionSystem,
8469
- testimonialQuote: accentGlyphQuote
9004
+ "brand-depth-band": {
9005
+ background: {
9006
+ type: "color",
9007
+ color: "primary-800"
9008
+ },
9009
+ foreground: {
9010
+ textColor: "text",
9011
+ headingColor: "primary",
9012
+ linkColor: "primary",
9013
+ supportingColor: "text"
9014
+ }
8470
9015
  },
8471
- description: "Crisp, trustworthy, and direct for local services and consultancies.",
8472
- generationBrief: "Prioritize clarity, proof, service detail, and easy next steps. Keep visuals polished and specific, with restrained decorative treatment.",
8473
- tokenRecipes: {
8474
- palette: "brand-led",
8475
- contrast: "strong",
8476
- radius: "soft",
8477
- shadow: "subtle",
8478
- typography: "clean-sans",
8479
- spacing: "regular",
8480
- motion: "subtle"
9016
+ "hero-image": {
9017
+ background: {
9018
+ type: "image",
9019
+ opacity: 1,
9020
+ position: "center center"
9021
+ },
9022
+ foreground: {
9023
+ textColor: "text",
9024
+ headingColor: "primary",
9025
+ linkColor: "primary",
9026
+ supportingColor: "text"
9027
+ }
9028
+ }
9029
+ }
9030
+ });
9031
+ var expressiveUnderlineInputs = {
9032
+ base: {
9033
+ background: { type: "transparent" },
9034
+ textColorToken: "text",
9035
+ border: {
9036
+ widthClass: "border-2",
9037
+ colorToken: "border",
9038
+ style: "underline"
8481
9039
  },
8482
- compositionBudget: balancedBudget,
8483
- recommendedHeaderLookIds: [
9040
+ corners: "square",
9041
+ shadow: null,
9042
+ spacing: "compact",
9043
+ fontSize: "base"
9044
+ },
9045
+ label: {
9046
+ textColorToken: "primary",
9047
+ fontWeight: "black",
9048
+ fontSize: "xs",
9049
+ textTransform: "uppercase",
9050
+ letterSpacing: "widest",
9051
+ opacity: 1
9052
+ },
9053
+ focus: {
9054
+ ringColorToken: "secondary",
9055
+ ringWidth: "0",
9056
+ borderColorToken: "secondary"
9057
+ },
9058
+ error: {
9059
+ borderColorToken: "destructive",
9060
+ textColorToken: "destructive"
9061
+ },
9062
+ disabled: {
9063
+ backgroundColorToken: "surface",
9064
+ textColorToken: "text",
9065
+ opacity: 0.6
9066
+ }
9067
+ };
9068
+ var ornateDarkInputs = {
9069
+ base: {
9070
+ background: { type: "solid", colorToken: "surfaceAlt" },
9071
+ textColorToken: "text",
9072
+ border: {
9073
+ widthClass: "border",
9074
+ colorToken: "primary/45",
9075
+ style: "all"
9076
+ },
9077
+ corners: "square",
9078
+ shadow: null,
9079
+ spacing: "medium",
9080
+ fontSize: "base"
9081
+ },
9082
+ label: {
9083
+ textColorToken: "primary",
9084
+ fontWeight: "semibold",
9085
+ fontSize: "xs",
9086
+ textTransform: "uppercase",
9087
+ letterSpacing: "wider",
9088
+ opacity: 1
9089
+ },
9090
+ focus: {
9091
+ ringColorToken: "primary/18",
9092
+ ringWidth: "2",
9093
+ borderColorToken: "primary/70"
9094
+ },
9095
+ error: {
9096
+ borderColorToken: "destructive",
9097
+ textColorToken: "destructive"
9098
+ },
9099
+ disabled: {
9100
+ backgroundColorToken: "muted",
9101
+ textColorToken: "mutedText",
9102
+ opacity: 0.6
9103
+ }
9104
+ };
9105
+ function uniqueContentFrameKinds() {
9106
+ const kinds = [
9107
+ ...new Set(
9108
+ generatedDesignOptionCatalog.contentFrames.map((frame) => frame.kind)
9109
+ )
9110
+ ];
9111
+ const firstKind = kinds[0];
9112
+ if (!firstKind) {
9113
+ throw new Error(
9114
+ "Expected generated design option catalog to expose at least one content frame kind."
9115
+ );
9116
+ }
9117
+ return [firstKind, ...kinds.slice(1)];
9118
+ }
9119
+ var generatedContentFrameKinds = uniqueContentFrameKinds();
9120
+ function defineCuratedSiteStyle(input) {
9121
+ const legacyHeaderLookIds = input.recommendedHeaderLookIds ?? ["clean-base"];
9122
+ const inferredHeaderCuration = inferHeaderCurationFromLegacyLooks(
9123
+ legacyHeaderLookIds,
9124
+ input.tokenRecipes
9125
+ );
9126
+ const typographyPresetChoices = input.typographyPresetChoices ?? defaultTypographyPresetChoicesForRecipe(input.tokenRecipes.typography);
9127
+ const defaultTypographyPresetId = input.defaultTypographyPresetId ? asTypographyPresetId(input.defaultTypographyPresetId) : typographyPresetChoices[0].id;
9128
+ if (!typographyPresetChoices.some(
9129
+ (choice) => choice.id === defaultTypographyPresetId
9130
+ )) {
9131
+ throw new Error(
9132
+ `Default typography preset ${defaultTypographyPresetId} is not curated for site style ${input.id}.`
9133
+ );
9134
+ }
9135
+ return {
9136
+ id: asSiteStyleId(input.id),
9137
+ name: input.name,
9138
+ description: input.description,
9139
+ generationBrief: input.generationBrief,
9140
+ selectionKeywordRules: input.selectionKeywordRules ?? [],
9141
+ siteCreatorSelection: input.siteCreatorSelection ?? {
9142
+ kind: "explicit_only"
9143
+ },
9144
+ template: {
9145
+ id: asDesignSystemTemplateId(
9146
+ `template:${input.id.replace("site-style:", "")}`
9147
+ ),
9148
+ name: input.name,
9149
+ version: 1,
9150
+ tokenRecipes: input.tokenRecipes,
9151
+ compositionBudget: input.compositionBudget,
9152
+ supportedSectionSurfaces: generatedDesignOptionCatalog.sectionSurfaces,
9153
+ supportedContentFrames: generatedContentFrameKinds,
9154
+ supportedItemSurfaces: generatedDesignOptionCatalog.itemSurfaces,
9155
+ supportedTransitions: generatedDesignOptionCatalog.transitions
9156
+ },
9157
+ // Decoration is opt-in per style so it stays a distinguishing feature, not
9158
+ // wallpaper. Styles that want a mark set `headingDecoration` explicitly;
9159
+ // clean/minimal styles default to none.
9160
+ headingDecoration: input.headingDecoration ?? noHeadingDecoration,
9161
+ ...input.themeOverrides ? { themeOverrides: input.themeOverrides } : {},
9162
+ ...input.designRuntimeRules ? { designRuntimeRules: input.designRuntimeRules } : {},
9163
+ ...input.defaultBlockVariants ? { defaultBlockVariants: input.defaultBlockVariants } : {},
9164
+ recommendedAppearancePresetIds: (input.recommendedAppearancePresetIds ?? []).map(asAppearancePresetId),
9165
+ defaultHeaderSelection: input.defaultHeaderSelection ? {
9166
+ layoutId: asHeaderLayoutId(input.defaultHeaderSelection.layoutId),
9167
+ styleId: asHeaderStyleId(input.defaultHeaderSelection.styleId)
9168
+ } : inferredHeaderCuration.defaultHeaderSelection,
9169
+ recommendedHeaderLayoutChoices: input.recommendedHeaderLayoutChoices ?? inferredHeaderCuration.recommendedHeaderLayoutChoices,
9170
+ recommendedHeaderStyleChoicesByLayout: input.recommendedHeaderStyleChoicesByLayout ?? inferredHeaderCuration.recommendedHeaderStyleChoicesByLayout,
9171
+ discouragedHeaderSelections: input.discouragedHeaderSelections?.map(
9172
+ (selection) => ({
9173
+ layoutId: asHeaderLayoutId(selection.layoutId),
9174
+ styleId: asHeaderStyleId(selection.styleId)
9175
+ })
9176
+ ),
9177
+ recommendedHeaderLookIds: legacyHeaderLookIds.map(asHeaderLookId),
9178
+ // Empty is intentional: resolveFooterLook always appends its guaranteed fallback.
9179
+ recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(
9180
+ asFooterLookId
9181
+ ),
9182
+ buttonPersonalityChoices: input.buttonPersonalityChoices,
9183
+ paletteVariantChoices: input.paletteVariantChoices,
9184
+ typographyPresetChoices,
9185
+ defaultTypographyPresetId
9186
+ };
9187
+ }
9188
+ function buttonChoice(id, note) {
9189
+ return note ? { id: asButtonPersonalityId(id), note } : { id: asButtonPersonalityId(id) };
9190
+ }
9191
+ function paletteChoice(id, note) {
9192
+ return note ? { id: asPaletteVariantId(id), note } : { id: asPaletteVariantId(id) };
9193
+ }
9194
+ function headerLayoutChoice(id, note) {
9195
+ return note ? { id: asHeaderLayoutId(id), note } : { id: asHeaderLayoutId(id) };
9196
+ }
9197
+ function headerStyleChoice(id, note) {
9198
+ return note ? { id: asHeaderStyleId(id), note } : { id: asHeaderStyleId(id) };
9199
+ }
9200
+ function unbrandHeaderLayoutId(id) {
9201
+ return id;
9202
+ }
9203
+ function uniqueHeaderLayoutChoices(choices) {
9204
+ const seen = /* @__PURE__ */ new Set();
9205
+ const unique = choices.filter((choice) => {
9206
+ if (seen.has(choice.id)) return false;
9207
+ seen.add(choice.id);
9208
+ return true;
9209
+ });
9210
+ const first = unique[0];
9211
+ if (!first) {
9212
+ throw new Error("Expected at least one curated header layout choice.");
9213
+ }
9214
+ return [first, ...unique.slice(1)];
9215
+ }
9216
+ function nonEmptyHeaderStyleChoices(choices, fallbackLayoutId) {
9217
+ const first = choices[0] ?? {
9218
+ id: getCompatibleHeaderStyleIds(fallbackLayoutId)[0] ?? asHeaderStyleId("minimal")
9219
+ };
9220
+ return [first, ...choices.slice(1)];
9221
+ }
9222
+ function uniqueCompatibleHeaderStyleChoices(choices, fallbackLayoutId) {
9223
+ const compatible = new Set(getCompatibleHeaderStyleIds(fallbackLayoutId));
9224
+ const seen = /* @__PURE__ */ new Set();
9225
+ const unique = choices.filter((choice) => {
9226
+ if (!compatible.has(choice.id)) return false;
9227
+ if (seen.has(choice.id)) return false;
9228
+ seen.add(choice.id);
9229
+ return true;
9230
+ });
9231
+ return nonEmptyHeaderStyleChoices(unique, fallbackLayoutId);
9232
+ }
9233
+ function inferredHeaderStyleValuesForRecipes(layoutId, recipes) {
9234
+ switch (layoutId) {
9235
+ case "classic":
9236
+ if (isExpressiveRecipe(recipes)) {
9237
+ return [
9238
+ "brand-bar",
9239
+ "brand-underline",
9240
+ "flat-tabs",
9241
+ "brand-pill",
9242
+ "fine-line"
9243
+ ];
9244
+ }
9245
+ if (recipes.spacing === "compact") {
9246
+ return ["flat-tabs", "fine-line", "minimal", "brand-bar"];
9247
+ }
9248
+ if (isSerifTypographyRecipe(recipes)) {
9249
+ return ["serif-line", "fine-line", "minimal", "soft-bar"];
9250
+ }
9251
+ if (recipes.radius === "rounded" || recipes.radius === "pill") {
9252
+ return ["soft-bar", "pill-nav", "fine-line", "minimal"];
9253
+ }
9254
+ return ["fine-line", "minimal", "soft-bar", "brand-bar"];
9255
+ case "centered":
9256
+ if (isSerifTypographyRecipe(recipes)) {
9257
+ return ["serif-line", "fine-line", "minimal", "soft-bar"];
9258
+ }
9259
+ if (isExpressiveRecipe(recipes)) {
9260
+ return ["brand-pill", "flat-tabs", "brand-bar", "fine-line"];
9261
+ }
9262
+ if (recipes.radius === "rounded" || recipes.radius === "pill") {
9263
+ return ["soft-bar", "pill-nav", "fine-line", "minimal"];
9264
+ }
9265
+ return ["minimal", "fine-line", "soft-bar"];
9266
+ case "floating":
9267
+ if (isExpressiveRecipe(recipes)) {
9268
+ return ["glass", "split-glass", "brand-pill", "soft-shell"];
9269
+ }
9270
+ if (isSerifTypographyRecipe(recipes)) {
9271
+ return ["split-pill", "minimal-surface", "soft-shell"];
9272
+ }
9273
+ return ["soft-shell", "minimal-surface", "glass"];
9274
+ default:
9275
+ return [];
9276
+ }
9277
+ }
9278
+ function isExpressiveRecipe(recipes) {
9279
+ return recipes.contrast === "maximum" || recipes.shadow === "layered" || recipes.motion === "expressive";
9280
+ }
9281
+ function isSerifTypographyRecipe(recipes) {
9282
+ return recipes.typography === "serif-editorial" || recipes.typography === "classic-serif";
9283
+ }
9284
+ function inferHeaderCurationFromLegacyLooks(lookIds, recipes) {
9285
+ const selections = lookIds.map((lookId) => resolveLegacyHeaderLookAlias(asHeaderLookId(lookId))).filter(
9286
+ (selection) => Boolean(selection)
9287
+ );
9288
+ const defaultHeaderSelection = selections[0] ?? {
9289
+ layoutId: asHeaderLayoutId("classic"),
9290
+ styleId: asHeaderStyleId("minimal")
9291
+ };
9292
+ const layoutChoices = uniqueHeaderLayoutChoices(
9293
+ selections.map((selection) => headerLayoutChoice(selection.layoutId))
9294
+ );
9295
+ const stylesByLayout = {};
9296
+ for (const layoutChoice of layoutChoices) {
9297
+ const legacyStyleChoices = selections.filter((selection) => selection.layoutId === layoutChoice.id).map((selection) => headerStyleChoice(selection.styleId));
9298
+ const inferredStyleChoices = inferredHeaderStyleValuesForRecipes(
9299
+ layoutChoice.id,
9300
+ recipes
9301
+ ).map((styleId) => headerStyleChoice(styleId));
9302
+ stylesByLayout[unbrandHeaderLayoutId(layoutChoice.id)] = uniqueCompatibleHeaderStyleChoices(
9303
+ [...legacyStyleChoices, ...inferredStyleChoices],
9304
+ layoutChoice.id
9305
+ );
9306
+ }
9307
+ return {
9308
+ defaultHeaderSelection,
9309
+ recommendedHeaderLayoutChoices: layoutChoices,
9310
+ recommendedHeaderStyleChoicesByLayout: stylesByLayout
9311
+ };
9312
+ }
9313
+ function typographyChoice(id, note) {
9314
+ return note ? { id: asTypographyPresetId(id), note } : { id: asTypographyPresetId(id) };
9315
+ }
9316
+ function defaultTypographyPresetChoicesForRecipe(recipe) {
9317
+ switch (recipe) {
9318
+ case "clean-sans":
9319
+ return [
9320
+ typographyChoice("typography-preset:modern-sans"),
9321
+ typographyChoice("typography-preset:luxe-contrast"),
9322
+ typographyChoice("typography-preset:bold-display")
9323
+ ];
9324
+ case "friendly-sans":
9325
+ return [
9326
+ typographyChoice("typography-preset:warm-rounded"),
9327
+ typographyChoice("typography-preset:modern-sans"),
9328
+ typographyChoice("typography-preset:editorial-serif")
9329
+ ];
9330
+ case "serif-editorial":
9331
+ return [
9332
+ typographyChoice("typography-preset:editorial-serif"),
9333
+ typographyChoice("typography-preset:classic-serif"),
9334
+ typographyChoice("typography-preset:warm-rounded")
9335
+ ];
9336
+ case "classic-serif":
9337
+ return [
9338
+ typographyChoice("typography-preset:classic-serif"),
9339
+ typographyChoice("typography-preset:luxe-contrast"),
9340
+ typographyChoice("typography-preset:editorial-serif")
9341
+ ];
9342
+ }
9343
+ }
9344
+ var curatedSiteStyles = [
9345
+ defineCuratedSiteStyle({
9346
+ id: "site-style:calm-studio",
9347
+ name: "Calm Studio",
9348
+ themeOverrides: {
9349
+ accordions: calmPanelAccordionSystem,
9350
+ testimonialQuote: serifDisplayQuote
9351
+ },
9352
+ headingDecoration: { family: "short-center-rule", colorToken: "primary" },
9353
+ description: "Soft, measured, and spacious for intimate appointment or class businesses.",
9354
+ generationBrief: "Use calm pacing, concise copy, generous breathing room, and natural imagery. Keep calls to action steady rather than urgent.",
9355
+ tokenRecipes: {
9356
+ palette: "soft-natural",
9357
+ contrast: "standard",
9358
+ radius: "soft",
9359
+ shadow: "subtle",
9360
+ typography: "friendly-sans",
9361
+ spacing: "airy",
9362
+ motion: "subtle"
9363
+ },
9364
+ compositionBudget: quietBudget,
9365
+ recommendedHeaderLookIds: [
9366
+ "centered-calm",
9367
+ "minimal-transparent",
9368
+ "clean-base"
9369
+ ],
9370
+ buttonPersonalityChoices: [
9371
+ buttonChoice("soft-pill"),
9372
+ buttonChoice("pebble"),
9373
+ buttonChoice("editorial-link"),
9374
+ buttonChoice("brushed-wash")
9375
+ ],
9376
+ paletteVariantChoices: [
9377
+ paletteChoice("soft-natural-sage"),
9378
+ paletteChoice("soft-natural-stone"),
9379
+ paletteChoice("warm-neutral-clay"),
9380
+ paletteChoice("soft-natural-watercolor")
9381
+ ]
9382
+ }),
9383
+ defineCuratedSiteStyle({
9384
+ id: "site-style:clear-professional",
9385
+ name: "Clear Professional",
9386
+ themeOverrides: {
9387
+ accordions: calmPanelAccordionSystem,
9388
+ testimonialQuote: accentGlyphQuote
9389
+ },
9390
+ description: "Crisp, trustworthy, and direct for local services and consultancies.",
9391
+ generationBrief: "Prioritize clarity, proof, service detail, and easy next steps. Keep visuals polished and specific, with restrained decorative treatment.",
9392
+ tokenRecipes: {
9393
+ palette: "brand-led",
9394
+ contrast: "strong",
9395
+ radius: "soft",
9396
+ shadow: "subtle",
9397
+ typography: "clean-sans",
9398
+ spacing: "regular",
9399
+ motion: "subtle"
9400
+ },
9401
+ compositionBudget: balancedBudget,
9402
+ recommendedHeaderLookIds: [
8484
9403
  "practical-utility",
8485
9404
  "brand-solid",
8486
9405
  "clean-base"
@@ -8727,266 +9646,43 @@ var curatedSiteStyles = [
8727
9646
  spacing: "regular",
8728
9647
  motion: "subtle"
8729
9648
  },
8730
- compositionBudget: quietBudget,
8731
- recommendedHeaderLookIds: [
8732
- "practical-utility",
8733
- "clean-base",
8734
- "centered-calm"
8735
- ],
8736
- buttonPersonalityChoices: [
8737
- buttonChoice("pebble"),
8738
- buttonChoice("soft-pill"),
8739
- buttonChoice("editorial-link")
8740
- ],
8741
- paletteVariantChoices: [
8742
- paletteChoice("soft-natural-stone"),
8743
- paletteChoice("soft-natural-sage"),
8744
- paletteChoice("warm-neutral-clay")
8745
- ]
8746
- }),
8747
- defineCuratedSiteStyle({
8748
- id: "site-style:clarity-zen-blue",
8749
- name: "Clarity Zen",
8750
- headingDecoration: { family: "short-center-rule", colorToken: "primary" },
8751
- description: "Calm, editorial, and reassuring for therapy, counselling, and wellbeing support practices.",
8752
- generationBrief: "Use a calm, soft palette, editorial serif headings, warm grounded copy, rounded cards, calm proof sections, and clear booking routes. Keep the tone compassionate and straightforward, with professional trust rather than hard-sell wellness language.",
8753
- siteCreatorSelection: {
8754
- kind: "site_creator_keyword_heuristic",
8755
- priority: 25
8756
- },
8757
- selectionKeywordRules: [
8758
- { kind: "substring", value: "psychotherap" },
8759
- { kind: "phrase", value: "mental health" },
8760
- { kind: "phrase", value: "talk therapy" },
8761
- { kind: "phrase", value: "therapy and wellbeing" }
8762
- ],
8763
- tokenRecipes: {
8764
- palette: "brand-led",
8765
- contrast: "standard",
8766
- radius: "rounded",
8767
- shadow: "subtle",
8768
- typography: "serif-editorial",
8769
- spacing: "airy",
8770
- motion: "subtle"
8771
- },
8772
- compositionBudget: balancedBudget,
8773
- themeOverrides: {
8774
- accordions: editorialDividedAccordionSystem,
8775
- cards: clarityZenCardSystem,
8776
- testimonialQuote: serifDisplayQuote,
8777
- typography: {
8778
- body: {
8779
- family: "Roboto, system-ui, sans-serif",
8780
- size: "md",
8781
- weight: "regular",
8782
- lineHeight: "relaxed",
8783
- letterSpacing: "normal"
8784
- },
8785
- headings: {
8786
- // Forum ships a single 400 weight; keep every heading weight
8787
- // 'regular' so the Google Fonts request stays valid.
8788
- default: {
8789
- family: "Forum, Georgia, serif",
8790
- weight: "regular",
8791
- lineHeight: "normal",
8792
- letterSpacing: "normal",
8793
- colorToken: "text",
8794
- italic: null,
8795
- case: null
8796
- },
8797
- h1: {
8798
- size: "xl",
8799
- weight: "regular",
8800
- lineHeight: "normal",
8801
- letterSpacing: "normal",
8802
- italic: null
8803
- },
8804
- h2: {
8805
- size: "xl",
8806
- weight: "regular",
8807
- lineHeight: "normal",
8808
- letterSpacing: "normal",
8809
- italic: null
8810
- },
8811
- h3: {
8812
- size: "md",
8813
- weight: "regular",
8814
- lineHeight: "normal",
8815
- letterSpacing: "normal",
8816
- italic: null
8817
- }
8818
- },
8819
- scale: "majorThird"
8820
- },
8821
- bodyText: {
8822
- intro: {
8823
- paragraphSize: "default",
8824
- headingSize: "editorial"
8825
- }
8826
- }
8827
- },
8828
- defaultBlockVariants: {
8829
- "block.faq": "split-heading-columns"
8830
- },
8831
- recommendedAppearancePresetIds: [
8832
- "hero-split-editorial",
8833
- "intro-portrait-bio",
8834
- "intro-organic-statement",
8835
- "feature-cards-soft-panels",
8836
- "feature-cards-editorial-columns",
8837
- "feature-cards-photo-tiles",
8838
- "media-text-quiet-story",
8839
- "testimonials-non-carded",
8840
- "faq-contained-help",
8841
- "contact-form-panel"
8842
- ],
8843
- recommendedHeaderLookIds: [
8844
- "centered-calm",
8845
- "serif-line",
8846
- "minimal-transparent"
8847
- ],
8848
- recommendedFooterLookIds: [
8849
- "footer-centered-calm",
8850
- "footer-editorial-columns",
8851
- "footer-muted-grounding"
8852
- ],
8853
- buttonPersonalityChoices: [
8854
- buttonChoice("soft-pill"),
8855
- buttonChoice("pebble"),
8856
- buttonChoice("editorial-link")
8857
- ],
8858
- paletteVariantChoices: [
8859
- paletteChoice("soft-natural-lilac"),
8860
- paletteChoice("soft-natural-watercolor"),
8861
- paletteChoice("soft-natural-stone"),
8862
- paletteChoice("warm-neutral-cream")
8863
- ]
8864
- }),
8865
- defineCuratedSiteStyle({
8866
- id: "site-style:personal-retreat-journal",
8867
- name: "Personal Retreat Journal",
8868
- themeOverrides: {
8869
- accordions: editorialDividedAccordionSystem,
8870
- testimonialQuote: serifDisplayQuote
8871
- },
8872
- headingDecoration: { family: "short-center-rule", colorToken: "primary" },
8873
- description: "Warm, story-led, and readable for solo practitioners with mixed offers.",
8874
- generationBrief: "Center the practitioner as the guide, then make private sessions, classes, retreats, and resources feel like clear pathways. Keep retreat copy grounded and practical, with enough editorial warmth for longer reading.",
8875
- siteCreatorSelection: {
8876
- kind: "site_creator_keyword_heuristic",
8877
- priority: 40
8878
- },
8879
- selectionKeywordRules: [
8880
- { kind: "substring", value: "retreat" },
8881
- { kind: "phrase", value: "solo practitioner" },
8882
- { kind: "phrase", value: "personal brand" },
8883
- { kind: "substring", value: "teacher" },
8884
- { kind: "substring", value: "coach" },
8885
- { kind: "phrase", value: "retreat resources" },
8886
- { kind: "substring", value: "journal" }
8887
- ],
8888
- tokenRecipes: {
8889
- palette: "warm-neutral",
8890
- contrast: "standard",
8891
- radius: "soft",
8892
- shadow: "subtle",
8893
- typography: "serif-editorial",
8894
- spacing: "airy",
8895
- motion: "subtle"
8896
- },
8897
- compositionBudget: balancedBudget,
8898
- recommendedHeaderLookIds: [
8899
- "serif-line",
8900
- "centered-calm",
8901
- "minimal-transparent"
8902
- ],
8903
- buttonPersonalityChoices: [
8904
- buttonChoice("editorial-link"),
8905
- buttonChoice("soft-pill"),
8906
- buttonChoice("brushed-wash")
8907
- ],
8908
- paletteVariantChoices: [
8909
- paletteChoice("warm-neutral-forest"),
8910
- paletteChoice("warm-neutral-clay"),
8911
- paletteChoice("soft-natural-stone")
8912
- ]
8913
- }),
8914
- defineCuratedSiteStyle({
8915
- id: "site-style:tactile-workshop",
8916
- name: "Tactile Workshop",
8917
- themeOverrides: {
8918
- accordions: warmInsetAccordionSystem,
8919
- testimonialQuote: accentGlyphQuote
8920
- },
8921
- headingDecoration: { family: "organic-squiggle", colorToken: "primary" },
8922
- description: "Bright, hands-on, and image-led for maker studios, workshops, and creative classes.",
8923
- generationBrief: "Lead with objects, materials, studio process, and practical booking detail. Keep the tone warm and direct, with useful mess, clear dates, and enough gallery rhythm to feel like a real creative studio.",
8924
- siteCreatorSelection: {
8925
- kind: "site_creator_keyword_heuristic",
8926
- priority: 50
8927
- },
8928
- selectionKeywordRules: [
8929
- { kind: "substring", value: "ceramic" },
8930
- { kind: "word", value: "pottery" },
8931
- { kind: "phrase", value: "maker studio" },
8932
- { kind: "phrase", value: "craft class" },
8933
- { kind: "phrase", value: "craft workshop" },
8934
- { kind: "word", value: "clay" },
8935
- { kind: "word", value: "kiln" }
8936
- ],
8937
- tokenRecipes: {
8938
- palette: "brand-led",
8939
- contrast: "standard",
8940
- radius: "soft",
8941
- shadow: "subtle",
8942
- typography: "friendly-sans",
8943
- spacing: "regular",
8944
- motion: "subtle"
8945
- },
8946
- compositionBudget: balancedBudget,
9649
+ compositionBudget: quietBudget,
8947
9650
  recommendedHeaderLookIds: [
8948
- "brand-solid",
8949
9651
  "practical-utility",
8950
- "clean-base"
8951
- ],
8952
- recommendedFooterLookIds: [
8953
- "site-footer-brand-two-band",
8954
- "footer-muted-grounding"
9652
+ "clean-base",
9653
+ "centered-calm"
8955
9654
  ],
8956
9655
  buttonPersonalityChoices: [
8957
9656
  buttonChoice("pebble"),
8958
- buttonChoice("confident-chip"),
8959
- buttonChoice("ink-stamp"),
9657
+ buttonChoice("soft-pill"),
8960
9658
  buttonChoice("editorial-link")
8961
9659
  ],
8962
9660
  paletteVariantChoices: [
8963
- paletteChoice("brand-led-warm"),
8964
- paletteChoice("brand-led-cool"),
8965
- paletteChoice("soft-natural-watercolor"),
9661
+ paletteChoice("soft-natural-stone"),
9662
+ paletteChoice("soft-natural-sage"),
8966
9663
  paletteChoice("warm-neutral-clay")
8967
9664
  ]
8968
9665
  }),
8969
9666
  defineCuratedSiteStyle({
8970
- id: SOFT_EARTH_SITE_STYLE_ID,
8971
- name: "Soft Earth",
8972
- headingDecoration: { family: "organic-squiggle", colorToken: "primary" },
8973
- description: "Warm, grounded, and editorial for yoga studios, retreats, and wellbeing communities.",
8974
- generationBrief: "Use cream space, terracotta CTAs, olive quote bands, natural imagery, generous but composed spacing, and editorial serif headings. Prefer a real intro section, image-led offering cards, warm community quotes, and an FAQ with a full-width intro above two columns of questions when content allows.",
9667
+ id: "site-style:clarity-zen-blue",
9668
+ name: "Clarity Zen",
9669
+ headingDecoration: { family: "short-center-rule", colorToken: "primary" },
9670
+ description: "Calm, editorial, and reassuring for therapy, counselling, and wellbeing support practices.",
9671
+ generationBrief: "Use a calm, soft palette, editorial serif headings, warm grounded copy, rounded cards, calm proof sections, and clear booking routes. Keep the tone compassionate and straightforward, with professional trust rather than hard-sell wellness language.",
8975
9672
  siteCreatorSelection: {
8976
9673
  kind: "site_creator_keyword_heuristic",
8977
- priority: 45
9674
+ priority: 25
8978
9675
  },
8979
9676
  selectionKeywordRules: [
8980
- { kind: "word", value: "meditation" },
8981
- { kind: "word", value: "wellbeing" },
8982
- { kind: "substring", value: "retreat" },
8983
- { kind: "phrase", value: "yoga studio" },
8984
- { kind: "phrase", value: "mindful movement" }
9677
+ { kind: "substring", value: "psychotherap" },
9678
+ { kind: "phrase", value: "mental health" },
9679
+ { kind: "phrase", value: "talk therapy" },
9680
+ { kind: "phrase", value: "therapy and wellbeing" }
8985
9681
  ],
8986
9682
  tokenRecipes: {
8987
- palette: "warm-neutral",
9683
+ palette: "brand-led",
8988
9684
  contrast: "standard",
8989
- radius: "soft",
9685
+ radius: "rounded",
8990
9686
  shadow: "subtle",
8991
9687
  typography: "serif-editorial",
8992
9688
  spacing: "airy",
@@ -8994,17 +9690,22 @@ var curatedSiteStyles = [
8994
9690
  },
8995
9691
  compositionBudget: balancedBudget,
8996
9692
  themeOverrides: {
9693
+ accordions: editorialDividedAccordionSystem,
9694
+ cards: clarityZenCardSystem,
9695
+ testimonialQuote: serifDisplayQuote,
8997
9696
  typography: {
8998
9697
  body: {
8999
- family: "Inter, system-ui, sans-serif",
9698
+ family: "Roboto, system-ui, sans-serif",
9000
9699
  size: "md",
9001
9700
  weight: "regular",
9002
9701
  lineHeight: "relaxed",
9003
9702
  letterSpacing: "normal"
9004
9703
  },
9005
9704
  headings: {
9705
+ // Forum ships a single 400 weight; keep every heading weight
9706
+ // 'regular' so the Google Fonts request stays valid.
9006
9707
  default: {
9007
- family: '"Cormorant Garamond", Georgia, serif',
9708
+ family: "Forum, Georgia, serif",
9008
9709
  weight: "regular",
9009
9710
  lineHeight: "normal",
9010
9711
  letterSpacing: "normal",
@@ -9020,7 +9721,7 @@ var curatedSiteStyles = [
9020
9721
  italic: null
9021
9722
  },
9022
9723
  h2: {
9023
- size: "lg",
9724
+ size: "xl",
9024
9725
  weight: "regular",
9025
9726
  lineHeight: "normal",
9026
9727
  letterSpacing: "normal",
@@ -9040,572 +9741,551 @@ var curatedSiteStyles = [
9040
9741
  intro: {
9041
9742
  paragraphSize: "default",
9042
9743
  headingSize: "editorial"
9043
- }
9044
- },
9045
- accordions: softEarthAccordionSystem,
9046
- testimonialQuote: accentGlyphQuote
9047
- },
9048
- defaultBlockVariants: {
9049
- "block.faq": "question-columns"
9050
- },
9051
- recommendedAppearancePresetIds: [
9052
- "hero-brand-scrim",
9053
- "intro-organic-statement",
9054
- "feature-cards-raised-rule",
9055
- "events-lined-panel",
9056
- "testimonials-non-carded",
9057
- "contact-form-panel"
9058
- ],
9059
- recommendedHeaderLookIds: [
9060
- "centered-calm",
9061
- "minimal-transparent",
9062
- "serif-line"
9063
- ],
9064
- recommendedFooterLookIds: [
9065
- "footer-muted-grounding",
9066
- "site-footer-brand-two-band"
9067
- ],
9068
- buttonPersonalityChoices: [
9069
- buttonChoice("earth-pill"),
9070
- buttonChoice("soft-pill"),
9071
- buttonChoice("pebble"),
9072
- buttonChoice("editorial-link")
9073
- ],
9074
- paletteVariantChoices: [
9075
- paletteChoice("warm-neutral-soft-earth"),
9076
- paletteChoice("warm-neutral-clay"),
9077
- paletteChoice("warm-neutral-forest"),
9078
- paletteChoice("soft-natural-sage")
9079
- ]
9080
- }),
9081
- defineCuratedSiteStyle({
9082
- id: "site-style:bold-launch",
9083
- name: "Bold Launch",
9084
- themeOverrides: {
9085
- accordions: boldBorderedAccordionSystem,
9086
- testimonialQuote: accentGlyphQuote
9087
- },
9088
- headingDecoration: { family: "short-center-rule", colorToken: "primary" },
9089
- description: "High-energy and punchy for launches, campaigns, and creative offers.",
9090
- generationBrief: "Use crisp positioning, bold hero structure, strong calls to action, and confident visual rhythm. Keep it precise, not shouty.",
9091
- siteCreatorSelection: {
9092
- kind: "site_creator_keyword_heuristic",
9093
- priority: 10
9094
- },
9095
- selectionKeywordRules: [
9096
- { kind: "substring", value: "launch" },
9097
- { kind: "substring", value: "campaign" },
9098
- { kind: "word", value: "preorder" },
9099
- { kind: "phrase", value: "pre-order" },
9100
- { kind: "substring", value: "waitlist" },
9101
- { kind: "word", value: "drop" }
9102
- ],
9103
- tokenRecipes: {
9104
- palette: "high-contrast",
9105
- contrast: "maximum",
9106
- radius: "pill",
9107
- shadow: "layered",
9108
- typography: "clean-sans",
9109
- spacing: "regular",
9110
- motion: "expressive"
9111
- },
9112
- compositionBudget: expressiveBudget,
9113
- recommendedHeaderLookIds: [
9114
- "transparent-overlay",
9115
- "floating-glass",
9116
- "brand-solid"
9117
- ],
9118
- buttonPersonalityChoices: [
9119
- buttonChoice("ink-stamp"),
9120
- buttonChoice("confident-chip"),
9121
- buttonChoice("brushed-wash"),
9122
- buttonChoice("pebble")
9123
- ],
9124
- paletteVariantChoices: [
9125
- paletteChoice("high-contrast-monochrome"),
9126
- paletteChoice("high-contrast-ink"),
9127
- paletteChoice("brand-led-jewel"),
9128
- paletteChoice("brand-led-warm")
9129
- ]
9130
- }),
9131
- defineCuratedSiteStyle({
9132
- id: "site-style:south-west-twerk-school",
9133
- name: "South West Twerk School",
9134
- headingDecoration: { family: "organic-squiggle", colorToken: "primary" },
9135
- description: "Energetic, editorial, and high-contrast for a branded dance school presence.",
9136
- generationBrief: "Use confident rhythm, bold burgundy-and-gold accents, large editorial intro copy, strong booking routes, and dark feature sections where proof or forms need emphasis.",
9137
- tokenRecipes: {
9138
- palette: "brand-led",
9139
- contrast: "maximum",
9140
- radius: "soft",
9141
- shadow: "layered",
9142
- typography: "clean-sans",
9143
- spacing: "airy",
9144
- motion: "expressive"
9145
- },
9146
- compositionBudget: expressiveBudget,
9147
- typographyPresetChoices: [
9148
- typographyChoice("typography-preset:bold-display"),
9149
- typographyChoice("typography-preset:modern-sans"),
9150
- typographyChoice("typography-preset:luxe-contrast")
9151
- ],
9152
- defaultTypographyPresetId: "typography-preset:bold-display",
9153
- themeOverrides: {
9154
- accordions: boldBorderedAccordionSystem,
9155
- cards: southWestCardSystem,
9156
- testimonialQuote: accentGlyphQuote,
9157
- bodyText: {
9158
- intro: {
9159
- paragraphSize: "editorial",
9160
- headingSize: "editorial"
9161
- }
9162
- },
9163
- inputs: expressiveUnderlineInputs
9164
- },
9165
- recommendedAppearancePresetIds: [
9166
- "hero-brand-scrim-fixed-frame",
9167
- "body-text-editorial-intro",
9168
- "schedule-details-brand-depth",
9169
- "testimonials-statement-cards",
9170
- "contact-form-panel"
9171
- ],
9172
- recommendedHeaderLookIds: [
9173
- "brand-solid",
9174
- "transparent-overlay",
9175
- "practical-utility"
9176
- ],
9177
- recommendedFooterLookIds: [
9178
- "site-footer-brand-two-band",
9179
- "footer-muted-grounding"
9180
- ],
9181
- buttonPersonalityChoices: [
9182
- buttonChoice("showtime-pill"),
9183
- buttonChoice("confident-chip"),
9184
- buttonChoice("ink-stamp"),
9185
- buttonChoice("brushed-wash")
9186
- ],
9187
- paletteVariantChoices: [
9188
- paletteChoice("brand-led-burgundy-gold"),
9189
- paletteChoice("brand-led-jewel"),
9190
- paletteChoice("brand-led-warm"),
9191
- paletteChoice("high-contrast-ink")
9192
- ]
9193
- }),
9194
- defineCuratedSiteStyle({
9195
- id: "site-style:original-joy",
9196
- name: "Original Joy",
9197
- headingDecoration: { family: "organic-squiggle", colorToken: "primary" },
9198
- description: "Warm, dark, and editorial: deep clay grounds, cream type, and bold burnt-orange accents for soulful community brands.",
9199
- generationBrief: "Use a deep brown ground with cream text and burnt-orange accents, large display headings, generous spacing, organic rounded shapes, and bold colour-blocked feature sections. Lead with warmth and belonging; calls to action should feel strong but unhurried.",
9200
- tokenRecipes: {
9201
- palette: "brand-led",
9202
- contrast: "maximum",
9203
- radius: "rounded",
9204
- shadow: "subtle",
9205
- typography: "clean-sans",
9206
- spacing: "airy",
9207
- motion: "expressive"
9208
- },
9209
- compositionBudget: expressiveBudget,
9210
- typographyPresetChoices: [
9211
- typographyChoice("typography-preset:original-joy"),
9212
- typographyChoice("typography-preset:bold-display"),
9213
- typographyChoice("typography-preset:modern-sans")
9214
- ],
9215
- defaultTypographyPresetId: "typography-preset:original-joy",
9216
- themeOverrides: {
9217
- accordions: boldBorderedAccordionSystem,
9218
- // Shared card system: warm rounded brown cards (event + testimonial cards
9219
- // pick this up automatically) with a burnt-orange statement variant.
9220
- cards: originalJoyCardSystem,
9221
- testimonialQuote: accentGlyphQuote,
9222
- bodyText: {
9223
- intro: {
9224
- paragraphSize: "editorial",
9225
- headingSize: "editorial"
9226
- }
9227
- }
9228
- },
9229
- // Recommended block looks: the bold colour-blocked feature cards, a calm
9230
- // band for the events spotlight, and statement testimonial cards.
9231
- recommendedAppearancePresetIds: [
9232
- "feature-cards-bold-colors",
9233
- "offerings-calm-list",
9234
- "testimonials-statement-cards"
9235
- ],
9236
- // Floating, transparent "Clear Split" header (no fill behind the nav links).
9237
- defaultHeaderSelection: { layoutId: "floating", styleId: "minimal-surface" },
9238
- recommendedHeaderLayoutChoices: [headerLayoutChoice("floating")],
9239
- recommendedHeaderStyleChoicesByLayout: {
9240
- floating: [
9241
- headerStyleChoice("minimal-surface"),
9242
- headerStyleChoice("split-glass"),
9243
- headerStyleChoice("glass")
9244
- ]
9744
+ }
9745
+ }
9245
9746
  },
9246
- // Legacy bridge only (the real curation is the explicit selection above).
9247
- // Kept to a reserved-space, non-overlay look on purpose: the split hero
9248
- // flows below the Clear Split header, so we must NOT trigger the immersive
9249
- // overlay-hero promotion that looks like `floating-glass` would force.
9250
- recommendedHeaderLookIds: ["minimal-transparent"],
9747
+ defaultBlockVariants: {
9748
+ "block.faq": "split-heading-columns"
9749
+ },
9750
+ recommendedAppearancePresetIds: [
9751
+ "hero-split-editorial",
9752
+ "intro-portrait-bio",
9753
+ "intro-organic-statement",
9754
+ "feature-cards-soft-panels",
9755
+ "feature-cards-editorial-columns",
9756
+ "feature-cards-photo-tiles",
9757
+ "media-text-quiet-story",
9758
+ "testimonials-non-carded",
9759
+ "faq-contained-help",
9760
+ "contact-form-panel"
9761
+ ],
9762
+ recommendedHeaderLookIds: [
9763
+ "centered-calm",
9764
+ "serif-line",
9765
+ "minimal-transparent"
9766
+ ],
9251
9767
  recommendedFooterLookIds: [
9252
- "site-footer-brand-two-band",
9768
+ "footer-centered-calm",
9769
+ "footer-editorial-columns",
9253
9770
  "footer-muted-grounding"
9254
9771
  ],
9255
9772
  buttonPersonalityChoices: [
9256
- buttonChoice("joy-stamp"),
9257
- buttonChoice("ink-stamp"),
9258
- buttonChoice("showtime-pill")
9773
+ buttonChoice("soft-pill"),
9774
+ buttonChoice("pebble"),
9775
+ buttonChoice("editorial-link")
9259
9776
  ],
9260
- paletteVariantChoices: [paletteChoice("warm-dark-ember")]
9261
- })
9262
- ];
9263
- var curatedSiteStylesById = new Map(
9264
- curatedSiteStyles.map((style) => [style.id, style])
9265
- );
9266
-
9267
- // ../theme-core/src/site-styles/siteStyleBlockPolicies.ts
9268
- var defaultPolicyPageFlowPresetId = asPageFlowPresetId("generated-default");
9269
- var southWestTwerkSchoolSiteStyleId = asSiteStyleId("site-style:south-west-twerk-school");
9270
- var heroBrandScrimFixedFrameLookId = asAppearancePresetId("hero-brand-scrim-fixed-frame");
9271
- var classicHeroLayoutVariantKey = asLayoutVariantKey("classic");
9272
- var microHeroLayoutVariantKey = asLayoutVariantKey("micro");
9273
- var waveBoundaryOptionId = asBoundaryOptionId("break:wave");
9274
-
9275
- // ../theme-core/src/site-styles/pageDesignEditorModel.ts
9276
- var pageFlowPresets = [
9277
- {
9278
- id: asPageFlowPresetId("flow:quiet"),
9279
- label: "Quiet",
9280
- boundaryStrategy: "quiet",
9281
- defaultBoundaryOptionId: noneBoundaryOption.id
9282
- },
9283
- {
9284
- id: asPageFlowPresetId("flow:balanced"),
9285
- label: "Balanced",
9286
- boundaryStrategy: "balanced",
9287
- defaultBoundaryOptionId: softBoundaryOption.id
9288
- },
9289
- {
9290
- id: asPageFlowPresetId("flow:expressive"),
9291
- label: "Expressive",
9292
- boundaryStrategy: "expressive",
9293
- defaultBoundaryOptionId: spaciousBoundaryOption.id
9294
- }
9295
- ];
9296
-
9297
- // ../theme-core/src/site-styles/designState.ts
9298
- import { z as z22 } from "zod";
9299
- var themeV2DesignStateSchemaVersion = 1;
9300
- var designResolutionPolicySchema = z22.enum(["generated", "user", "admin", "sdk"]);
9301
- var runtimeStyleFieldNameSchema = z22.enum(themeV2RuntimeStyleFieldNames);
9302
- var nonEmptyRuntimeStyleFieldNamesSchema = z22.array(runtimeStyleFieldNameSchema).min(1).transform((fields3) => [
9303
- fields3[0],
9304
- ...fields3.slice(1)
9305
- ]);
9306
- var heroLegibilityStrategySchema = z22.enum([
9307
- "none",
9308
- "scrim-gradient",
9309
- "solid-panel"
9310
- ]);
9311
- var heroCompositionIntentSchema = z22.enum([
9312
- "center",
9313
- "bottom-left"
9314
- ]);
9315
- var heroTypographyScaleIntentSchema = z22.enum([
9316
- "quiet",
9317
- "editorial",
9318
- "display",
9319
- "poster"
9320
- ]);
9321
- var sectionHeightIntentSchema = z22.enum([
9322
- "default",
9323
- "banner",
9324
- "hero",
9325
- "immersive"
9326
- ]);
9327
- var imageSurfaceTreatmentIntensitySchema = z22.enum(["soft", "balanced", "strong"]);
9328
- var imageSurfaceMotionSchema = z22.enum(["static", "fixed-frame"]);
9329
- var imageSurfaceTreatmentSchema = z22.discriminatedUnion("kind", [
9330
- z22.object({ kind: z22.literal("none") }).strict(),
9331
- z22.object({
9332
- kind: z22.literal("brand-scrim"),
9333
- token: z22.enum(["primary", "secondary", "accent"]),
9334
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
9335
- }).strict(),
9336
- z22.object({
9337
- kind: z22.literal("brand-wash"),
9338
- token: z22.enum(["primary", "secondary", "accent"]),
9339
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
9340
- }).strict(),
9341
- z22.object({
9342
- kind: z22.literal("neutral-scrim"),
9343
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
9344
- }).strict(),
9345
- z22.object({
9346
- kind: z22.literal("neutral-wash"),
9347
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
9348
- }).strict(),
9349
- z22.object({
9350
- kind: z22.literal("solid-panel"),
9351
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
9352
- }).strict()
9353
- ]);
9354
- var testimonialCardTreatmentSchema = z22.enum(["default", "accent-quote"]);
9355
- var tileTreatmentSchema = z22.enum(tileTreatmentValues);
9356
- var eventListTreatmentSchema = z22.enum(eventListTreatmentValues);
9357
- var eyebrowTreatmentSchema = z22.enum(eyebrowTreatmentValues);
9358
- function uniqueNonEmpty(values) {
9359
- const uniqueValues = [...new Set(values)];
9360
- const firstValue = uniqueValues[0];
9361
- if (!firstValue) {
9362
- throw new Error("Expected at least one Theme V2 design state option.");
9363
- }
9364
- return [firstValue, ...uniqueValues.slice(1)];
9365
- }
9366
- var userPanelTreatments = uniqueNonEmpty(
9367
- userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "panel").map((frame) => frame.treatment)
9368
- );
9369
- var userFlushTreatments = uniqueNonEmpty(
9370
- userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "flush-panel").map((frame) => frame.treatment)
9371
- );
9372
- var userFlushBleeds = uniqueNonEmpty(
9373
- userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "flush-panel").map((frame) => frame.bleed)
9374
- );
9375
- var contentFrameIntentSchema = z22.discriminatedUnion("kind", [
9376
- z22.object({ kind: z22.literal("plain") }).strict(),
9377
- z22.object({
9378
- kind: z22.literal("panel"),
9379
- treatment: z22.enum(userPanelTreatments)
9380
- }).strict(),
9381
- z22.object({
9382
- kind: z22.literal("flush-panel"),
9383
- treatment: z22.enum(userFlushTreatments),
9384
- bleed: z22.enum(userFlushBleeds)
9385
- }).strict()
9386
- ]);
9387
- var blockDesignPlanSchema = z22.object({
9388
- blockId: z22.string().min(1).transform(asDesignBlockId),
9389
- blockKind: z22.string().min(1),
9390
- purpose: z22.string().min(1),
9391
- sectionSurface: z22.enum(userDesignOptionCatalog.sectionSurfaces),
9392
- contentFrame: contentFrameIntentSchema,
9393
- itemSurface: z22.enum(userDesignOptionCatalog.itemSurfaces),
9394
- transitionAfter: z22.enum(userDesignOptionCatalog.transitions),
9395
- emphasis: z22.enum(userDesignOptionCatalog.emphases),
9396
- sectionHeight: sectionHeightIntentSchema.optional(),
9397
- heroLegibility: heroLegibilityStrategySchema.optional(),
9398
- heroComposition: heroCompositionIntentSchema.optional(),
9399
- heroTypographyScale: heroTypographyScaleIntentSchema.optional(),
9400
- imageSurfaceTreatment: imageSurfaceTreatmentSchema.optional(),
9401
- imageSurfaceMotion: imageSurfaceMotionSchema.optional(),
9402
- testimonialCardTreatment: testimonialCardTreatmentSchema.optional(),
9403
- tileTreatment: tileTreatmentSchema.optional(),
9404
- eventListTreatment: eventListTreatmentSchema.optional(),
9405
- eyebrowTreatment: eyebrowTreatmentSchema.optional()
9406
- }).strict();
9407
- var styleAuthoritySchema = z22.discriminatedUnion("kind", [
9408
- z22.object({
9409
- kind: z22.literal("theme-v2"),
9410
- source: designResolutionPolicySchema,
9411
- siteStyleId: z22.string().min(1).transform(asSiteStyleId),
9412
- templateId: z22.string().min(1).transform(asDesignSystemTemplateId),
9413
- templateVersion: z22.number().int().nonnegative(),
9414
- resolverVersion: z22.number().int().nonnegative()
9415
- }).strict(),
9416
- z22.object({
9417
- kind: z22.literal("legacy-raw"),
9418
- reason: z22.enum(["pre-theme-v2", "manual-runtime-fields"])
9419
- }).strict(),
9420
- z22.object({
9421
- kind: z22.literal("advanced-detached"),
9422
- reason: z22.literal("detached-custom-runtime-fields")
9423
- }).strict()
9424
- ]);
9425
- var blockRuntimeStyleAuthoritySchema = z22.object({
9426
- unit: z22.literal("block-runtime-fields"),
9427
- blockId: z22.string().min(1).transform(asDesignBlockId),
9428
- fields: nonEmptyRuntimeStyleFieldNamesSchema,
9429
- authority: styleAuthoritySchema
9430
- }).strict();
9431
- var persistedPageDesignStateV1Schema = z22.object({
9432
- schemaVersion: z22.literal(themeV2DesignStateSchemaVersion),
9433
- siteStyleId: z22.string().min(1).transform(asSiteStyleId),
9434
- templateId: z22.string().min(1).transform(asDesignSystemTemplateId),
9435
- templateVersion: z22.number().int().nonnegative(),
9436
- resolverVersion: z22.number().int().nonnegative(),
9437
- rhythmPresetId: z22.string().min(1),
9438
- blocks: z22.array(blockDesignPlanSchema),
9439
- styleAuthorities: z22.array(blockRuntimeStyleAuthoritySchema)
9440
- }).strict();
9441
-
9442
- // ../theme-core/src/site-styles/runtimeCompiler.ts
9443
- function defineDesignRuntimeRules(rules) {
9444
- return rules;
9445
- }
9446
- function defineComponentRuntimeRules(rules) {
9447
- return rules;
9448
- }
9449
- var defaultDesignRuntimeRules = defineDesignRuntimeRules({
9450
- sectionSurfaces: {
9451
- base: {},
9452
- "muted-band": {
9453
- background: {
9454
- type: "color",
9455
- color: "muted"
9456
- }
9777
+ paletteVariantChoices: [
9778
+ paletteChoice("soft-natural-lilac"),
9779
+ paletteChoice("soft-natural-watercolor"),
9780
+ paletteChoice("soft-natural-stone"),
9781
+ paletteChoice("warm-neutral-cream")
9782
+ ]
9783
+ }),
9784
+ defineCuratedSiteStyle({
9785
+ id: "site-style:personal-retreat-journal",
9786
+ name: "Personal Retreat Journal",
9787
+ themeOverrides: {
9788
+ accordions: editorialDividedAccordionSystem,
9789
+ testimonialQuote: serifDisplayQuote
9790
+ },
9791
+ headingDecoration: { family: "short-center-rule", colorToken: "primary" },
9792
+ description: "Warm, story-led, and readable for solo practitioners with mixed offers.",
9793
+ generationBrief: "Center the practitioner as the guide, then make private sessions, classes, retreats, and resources feel like clear pathways. Keep retreat copy grounded and practical, with enough editorial warmth for longer reading.",
9794
+ siteCreatorSelection: {
9795
+ kind: "site_creator_keyword_heuristic",
9796
+ priority: 40
9797
+ },
9798
+ selectionKeywordRules: [
9799
+ { kind: "substring", value: "retreat" },
9800
+ { kind: "phrase", value: "solo practitioner" },
9801
+ { kind: "phrase", value: "personal brand" },
9802
+ { kind: "substring", value: "teacher" },
9803
+ { kind: "substring", value: "coach" },
9804
+ { kind: "phrase", value: "retreat resources" },
9805
+ { kind: "substring", value: "journal" }
9806
+ ],
9807
+ tokenRecipes: {
9808
+ palette: "warm-neutral",
9809
+ contrast: "standard",
9810
+ radius: "soft",
9811
+ shadow: "subtle",
9812
+ typography: "serif-editorial",
9813
+ spacing: "airy",
9814
+ motion: "subtle"
9457
9815
  },
9458
- "accent-band": {
9459
- background: {
9460
- type: "color",
9461
- color: "primary"
9462
- }
9816
+ compositionBudget: balancedBudget,
9817
+ recommendedHeaderLookIds: [
9818
+ "serif-line",
9819
+ "centered-calm",
9820
+ "minimal-transparent"
9821
+ ],
9822
+ buttonPersonalityChoices: [
9823
+ buttonChoice("editorial-link"),
9824
+ buttonChoice("soft-pill"),
9825
+ buttonChoice("brushed-wash")
9826
+ ],
9827
+ paletteVariantChoices: [
9828
+ paletteChoice("warm-neutral-forest"),
9829
+ paletteChoice("warm-neutral-clay"),
9830
+ paletteChoice("soft-natural-stone")
9831
+ ]
9832
+ }),
9833
+ defineCuratedSiteStyle({
9834
+ id: "site-style:tactile-workshop",
9835
+ name: "Tactile Workshop",
9836
+ themeOverrides: {
9837
+ accordions: warmInsetAccordionSystem,
9838
+ testimonialQuote: accentGlyphQuote
9463
9839
  },
9464
- "brand-depth-band": {
9465
- background: {
9466
- type: "color",
9467
- color: "primary-800"
9468
- }
9840
+ headingDecoration: { family: "organic-squiggle", colorToken: "primary" },
9841
+ description: "Bright, hands-on, and image-led for maker studios, workshops, and creative classes.",
9842
+ generationBrief: "Lead with objects, materials, studio process, and practical booking detail. Keep the tone warm and direct, with useful mess, clear dates, and enough gallery rhythm to feel like a real creative studio.",
9843
+ siteCreatorSelection: {
9844
+ kind: "site_creator_keyword_heuristic",
9845
+ priority: 50
9469
9846
  },
9470
- "hero-image": {
9471
- background: {
9472
- type: "image",
9473
- opacity: 1,
9474
- position: "center center",
9475
- ...uniformSectionForeground("text")
9476
- }
9477
- }
9478
- },
9479
- heroLegibility: {
9480
- "scrim-gradient": {
9481
- type: "gradient",
9482
- gradient: "linear-gradient(180deg, rgba(255,255,255,0.38) 0%, rgba(244,241,234,0.62) 90%)",
9483
- opacity: 1
9847
+ selectionKeywordRules: [
9848
+ { kind: "substring", value: "ceramic" },
9849
+ { kind: "word", value: "pottery" },
9850
+ { kind: "phrase", value: "maker studio" },
9851
+ { kind: "phrase", value: "craft class" },
9852
+ { kind: "phrase", value: "craft workshop" },
9853
+ { kind: "word", value: "clay" },
9854
+ { kind: "word", value: "kiln" }
9855
+ ],
9856
+ tokenRecipes: {
9857
+ palette: "brand-led",
9858
+ contrast: "standard",
9859
+ radius: "soft",
9860
+ shadow: "subtle",
9861
+ typography: "friendly-sans",
9862
+ spacing: "regular",
9863
+ motion: "subtle"
9484
9864
  },
9485
- "solid-panel": {
9486
- type: "color",
9487
- color: "surface",
9488
- opacity: 0.88
9489
- }
9490
- },
9491
- transitionClassName: (transition, fromSurface, toSurface) => transition === "none" ? null : `site-style-transition-${transition}-from-${fromSurface}-to-${toSurface}`
9492
- });
9493
- var defaultComponentRuntimeRules = defineComponentRuntimeRules({
9494
- panelFrames: {
9495
- inset: {
9496
- spacing: "comfortable",
9497
- rounded: "xl",
9498
- raised: false,
9499
- background: {
9500
- type: "color",
9501
- color: "surfaceAlt",
9502
- textColor: "text"
9503
- }
9865
+ compositionBudget: balancedBudget,
9866
+ recommendedHeaderLookIds: [
9867
+ "brand-solid",
9868
+ "practical-utility",
9869
+ "clean-base"
9870
+ ],
9871
+ recommendedFooterLookIds: [
9872
+ "site-footer-brand-two-band",
9873
+ "footer-muted-grounding"
9874
+ ],
9875
+ buttonPersonalityChoices: [
9876
+ buttonChoice("pebble"),
9877
+ buttonChoice("confident-chip"),
9878
+ buttonChoice("ink-stamp"),
9879
+ buttonChoice("editorial-link")
9880
+ ],
9881
+ paletteVariantChoices: [
9882
+ paletteChoice("brand-led-warm"),
9883
+ paletteChoice("brand-led-cool"),
9884
+ paletteChoice("soft-natural-watercolor"),
9885
+ paletteChoice("warm-neutral-clay")
9886
+ ]
9887
+ }),
9888
+ defineCuratedSiteStyle({
9889
+ id: SOFT_EARTH_SITE_STYLE_ID,
9890
+ name: "Soft Earth",
9891
+ headingDecoration: { family: "organic-squiggle", colorToken: "primary" },
9892
+ description: "Warm, grounded, and editorial for yoga studios, retreats, and wellbeing communities.",
9893
+ generationBrief: "Use cream space, terracotta CTAs, olive quote bands, natural imagery, generous but composed spacing, and editorial serif headings. Prefer a real intro section, image-led offering cards, warm community quotes, and an FAQ with a full-width intro above two columns of questions when content allows.",
9894
+ siteCreatorSelection: {
9895
+ kind: "site_creator_keyword_heuristic",
9896
+ priority: 45
9504
9897
  },
9505
- raised: {
9506
- spacing: "comfortable",
9507
- rounded: "xl",
9508
- raised: true,
9509
- background: {
9510
- type: "color",
9511
- color: "surfaceAlt",
9512
- textColor: "text"
9513
- }
9898
+ selectionKeywordRules: [
9899
+ { kind: "word", value: "meditation" },
9900
+ { kind: "word", value: "wellbeing" },
9901
+ { kind: "substring", value: "retreat" },
9902
+ { kind: "phrase", value: "yoga studio" },
9903
+ { kind: "phrase", value: "mindful movement" }
9904
+ ],
9905
+ tokenRecipes: {
9906
+ palette: "warm-neutral",
9907
+ contrast: "standard",
9908
+ radius: "soft",
9909
+ shadow: "subtle",
9910
+ typography: "serif-editorial",
9911
+ spacing: "airy",
9912
+ motion: "subtle"
9913
+ },
9914
+ compositionBudget: balancedBudget,
9915
+ themeOverrides: {
9916
+ typography: {
9917
+ body: {
9918
+ family: "Inter, system-ui, sans-serif",
9919
+ size: "md",
9920
+ weight: "regular",
9921
+ lineHeight: "relaxed",
9922
+ letterSpacing: "normal"
9923
+ },
9924
+ headings: {
9925
+ default: {
9926
+ family: '"Cormorant Garamond", Georgia, serif',
9927
+ weight: "regular",
9928
+ lineHeight: "normal",
9929
+ letterSpacing: "normal",
9930
+ colorToken: "text",
9931
+ italic: null,
9932
+ case: null
9933
+ },
9934
+ h1: {
9935
+ size: "xl",
9936
+ weight: "regular",
9937
+ lineHeight: "normal",
9938
+ letterSpacing: "normal",
9939
+ italic: null
9940
+ },
9941
+ h2: {
9942
+ size: "lg",
9943
+ weight: "regular",
9944
+ lineHeight: "normal",
9945
+ letterSpacing: "normal",
9946
+ italic: null
9947
+ },
9948
+ h3: {
9949
+ size: "md",
9950
+ weight: "regular",
9951
+ lineHeight: "normal",
9952
+ letterSpacing: "normal",
9953
+ italic: null
9954
+ }
9955
+ },
9956
+ scale: "majorThird"
9957
+ },
9958
+ bodyText: {
9959
+ intro: {
9960
+ paragraphSize: "default",
9961
+ headingSize: "editorial"
9962
+ }
9963
+ },
9964
+ accordions: softEarthAccordionSystem,
9965
+ testimonialQuote: accentGlyphQuote
9966
+ },
9967
+ defaultBlockVariants: {
9968
+ "block.faq": "question-columns"
9969
+ },
9970
+ recommendedAppearancePresetIds: [
9971
+ "hero-brand-scrim",
9972
+ "intro-organic-statement",
9973
+ "feature-cards-raised-rule",
9974
+ "events-lined-panel",
9975
+ "testimonials-non-carded",
9976
+ "contact-form-panel"
9977
+ ],
9978
+ recommendedHeaderLookIds: [
9979
+ "centered-calm",
9980
+ "minimal-transparent",
9981
+ "serif-line"
9982
+ ],
9983
+ recommendedFooterLookIds: [
9984
+ "footer-muted-grounding",
9985
+ "site-footer-brand-two-band"
9986
+ ],
9987
+ buttonPersonalityChoices: [
9988
+ buttonChoice("earth-pill"),
9989
+ buttonChoice("soft-pill"),
9990
+ buttonChoice("pebble"),
9991
+ buttonChoice("editorial-link")
9992
+ ],
9993
+ paletteVariantChoices: [
9994
+ paletteChoice("warm-neutral-soft-earth"),
9995
+ paletteChoice("warm-neutral-clay"),
9996
+ paletteChoice("warm-neutral-forest"),
9997
+ paletteChoice("soft-natural-sage")
9998
+ ]
9999
+ }),
10000
+ defineCuratedSiteStyle({
10001
+ id: "site-style:bold-launch",
10002
+ name: "Bold Launch",
10003
+ themeOverrides: {
10004
+ accordions: boldBorderedAccordionSystem,
10005
+ testimonialQuote: accentGlyphQuote
10006
+ },
10007
+ headingDecoration: { family: "short-center-rule", colorToken: "primary" },
10008
+ description: "High-energy and punchy for launches, campaigns, and creative offers.",
10009
+ generationBrief: "Use crisp positioning, bold hero structure, strong calls to action, and confident visual rhythm. Keep it precise, not shouty.",
10010
+ siteCreatorSelection: {
10011
+ kind: "site_creator_keyword_heuristic",
10012
+ priority: 10
9514
10013
  },
9515
- editorial: {
9516
- spacing: "medium",
9517
- rounded: "xl",
9518
- raised: false,
9519
- background: {
9520
- type: "color",
9521
- color: "surface",
9522
- textColor: "text"
9523
- }
9524
- }
9525
- },
9526
- flushFrames: {
9527
- "media-panel": {
9528
- fullWidth: true,
9529
- spacing: "none",
9530
- rounded: "none",
9531
- raised: false
9532
- }
9533
- },
9534
- itemSurfaces: {
9535
- none: null,
9536
- default: {
9537
- spacing: "medium",
9538
- rounded: "lg",
9539
- raised: false
10014
+ selectionKeywordRules: [
10015
+ { kind: "substring", value: "launch" },
10016
+ { kind: "substring", value: "campaign" },
10017
+ { kind: "word", value: "preorder" },
10018
+ { kind: "phrase", value: "pre-order" },
10019
+ { kind: "substring", value: "waitlist" },
10020
+ { kind: "word", value: "drop" }
10021
+ ],
10022
+ tokenRecipes: {
10023
+ palette: "high-contrast",
10024
+ contrast: "maximum",
10025
+ radius: "pill",
10026
+ shadow: "layered",
10027
+ typography: "clean-sans",
10028
+ spacing: "regular",
10029
+ motion: "expressive"
9540
10030
  },
9541
- flat: {
9542
- spacing: "medium",
9543
- rounded: "lg",
9544
- raised: false
10031
+ compositionBudget: expressiveBudget,
10032
+ recommendedHeaderLookIds: [
10033
+ "transparent-overlay",
10034
+ "floating-glass",
10035
+ "brand-solid"
10036
+ ],
10037
+ buttonPersonalityChoices: [
10038
+ buttonChoice("ink-stamp"),
10039
+ buttonChoice("confident-chip"),
10040
+ buttonChoice("brushed-wash"),
10041
+ buttonChoice("pebble")
10042
+ ],
10043
+ paletteVariantChoices: [
10044
+ paletteChoice("high-contrast-monochrome"),
10045
+ paletteChoice("high-contrast-ink"),
10046
+ paletteChoice("brand-led-jewel"),
10047
+ paletteChoice("brand-led-warm")
10048
+ ]
10049
+ }),
10050
+ defineCuratedSiteStyle({
10051
+ id: "site-style:south-west-twerk-school",
10052
+ name: "South West Twerk School",
10053
+ headingDecoration: { family: "organic-squiggle", colorToken: "primary" },
10054
+ description: "Energetic, editorial, and high-contrast for a branded dance school presence.",
10055
+ generationBrief: "Use confident rhythm, bold burgundy-and-gold accents, large editorial intro copy, strong booking routes, and dark feature sections where proof or forms need emphasis.",
10056
+ tokenRecipes: {
10057
+ palette: "brand-led",
10058
+ contrast: "maximum",
10059
+ radius: "soft",
10060
+ shadow: "layered",
10061
+ typography: "clean-sans",
10062
+ spacing: "airy",
10063
+ motion: "expressive"
9545
10064
  },
9546
- outlined: {
9547
- spacing: "medium",
9548
- rounded: "lg",
9549
- raised: false,
9550
- border: {
9551
- enabled: true,
9552
- width: "1",
9553
- colorToken: "border"
9554
- }
10065
+ compositionBudget: expressiveBudget,
10066
+ typographyPresetChoices: [
10067
+ typographyChoice("typography-preset:bold-display"),
10068
+ typographyChoice("typography-preset:modern-sans"),
10069
+ typographyChoice("typography-preset:luxe-contrast")
10070
+ ],
10071
+ defaultTypographyPresetId: "typography-preset:bold-display",
10072
+ themeOverrides: {
10073
+ accordions: boldBorderedAccordionSystem,
10074
+ cards: southWestCardSystem,
10075
+ testimonialQuote: accentGlyphQuote,
10076
+ bodyText: {
10077
+ intro: {
10078
+ paragraphSize: "editorial",
10079
+ headingSize: "editorial"
10080
+ }
10081
+ },
10082
+ inputs: expressiveUnderlineInputs
9555
10083
  },
9556
- raised: {
9557
- spacing: "medium",
9558
- rounded: "xl",
9559
- raised: true
10084
+ recommendedAppearancePresetIds: [
10085
+ "hero-brand-scrim-fixed-frame",
10086
+ "body-text-editorial-intro",
10087
+ "schedule-details-brand-depth",
10088
+ "testimonials-statement-cards",
10089
+ "contact-form-panel"
10090
+ ],
10091
+ recommendedHeaderLookIds: [
10092
+ "brand-solid",
10093
+ "transparent-overlay",
10094
+ "practical-utility"
10095
+ ],
10096
+ recommendedFooterLookIds: [
10097
+ "site-footer-brand-two-band",
10098
+ "footer-muted-grounding"
10099
+ ],
10100
+ buttonPersonalityChoices: [
10101
+ buttonChoice("showtime-pill"),
10102
+ buttonChoice("confident-chip"),
10103
+ buttonChoice("ink-stamp"),
10104
+ buttonChoice("brushed-wash")
10105
+ ],
10106
+ paletteVariantChoices: [
10107
+ paletteChoice("brand-led-burgundy-gold"),
10108
+ paletteChoice("brand-led-jewel"),
10109
+ paletteChoice("brand-led-warm"),
10110
+ paletteChoice("high-contrast-ink")
10111
+ ]
10112
+ }),
10113
+ defineCuratedSiteStyle({
10114
+ id: "site-style:kirtan-ornate",
10115
+ name: "Kirtan Ornate",
10116
+ headingDecoration: { family: "short-center-rule", colorToken: "accent" },
10117
+ description: "Ceremonial, jewel-toned, and devotional: ornate frames, warm contrast, and composed rhythm for intimate music gatherings.",
10118
+ generationBrief: "Use a deep plum ground with pale gold as the main brand color, rose accent details, cream text, spacious split hero sections, devotional editorial headings, compact event lists, and framed conversion sections. The mood should feel soulful and ceremonial, not gothic or theatrical.",
10119
+ selectionKeywordRules: [
10120
+ { kind: "word", value: "kirtan" },
10121
+ { kind: "word", value: "chanting" },
10122
+ { kind: "word", value: "ceremony" },
10123
+ { kind: "word", value: "devotional" }
10124
+ ],
10125
+ tokenRecipes: {
10126
+ palette: "brand-led",
10127
+ contrast: "strong",
10128
+ radius: "soft",
10129
+ shadow: "subtle",
10130
+ typography: "serif-editorial",
10131
+ spacing: "airy",
10132
+ motion: "subtle"
9560
10133
  },
9561
- inset: {
9562
- treatment: "soft-panel",
9563
- spacing: "comfortable",
9564
- rounded: "xl",
9565
- raised: false,
9566
- border: {
9567
- enabled: false
10134
+ compositionBudget: expressiveBudget,
10135
+ typographyPresetChoices: [
10136
+ typographyChoice("typography-preset:kirtan-ornate"),
10137
+ typographyChoice("typography-preset:luxe-contrast"),
10138
+ typographyChoice("typography-preset:editorial-serif")
10139
+ ],
10140
+ defaultTypographyPresetId: "typography-preset:kirtan-ornate",
10141
+ themeOverrides: {
10142
+ accordions: warmInsetAccordionSystem,
10143
+ cards: originalJoyCardSystem,
10144
+ testimonialQuote: serifDisplayQuote,
10145
+ bodyText: {
10146
+ intro: {
10147
+ paragraphSize: "editorial",
10148
+ headingSize: "editorial"
10149
+ }
9568
10150
  },
9569
- background: {
9570
- type: "color",
9571
- color: "surfaceAlt",
9572
- textColor: "text"
9573
- }
10151
+ inputs: ornateDarkInputs
9574
10152
  },
9575
- editorial: {
9576
- // Boxless open column with a short rule on top; the visual treatment
9577
- // lives in blocks-static/card-treatments.css.
9578
- treatment: "editorial-rule",
9579
- spacing: "none",
9580
- rounded: "none",
9581
- raised: false,
9582
- border: {
9583
- enabled: false
9584
- }
10153
+ designRuntimeRules: kirtanOrnateDesignRuntimeRules,
10154
+ recommendedAppearancePresetIds: [
10155
+ "hero-brand-scrim-fixed-frame",
10156
+ "media-text-quiet-story",
10157
+ "events-lined-panel",
10158
+ "schedule-details-brand-depth",
10159
+ "testimonials-statement-cards",
10160
+ "contact-form-panel"
10161
+ ],
10162
+ defaultHeaderSelection: { layoutId: "floating", styleId: "minimal-surface" },
10163
+ recommendedHeaderLayoutChoices: [headerLayoutChoice("floating")],
10164
+ recommendedHeaderStyleChoicesByLayout: {
10165
+ floating: [
10166
+ headerStyleChoice("minimal-surface"),
10167
+ headerStyleChoice("split-glass"),
10168
+ headerStyleChoice("glass")
10169
+ ]
9585
10170
  },
9586
- "color-blocked": {
9587
- // Bold, flat colour-blocked cards. The per-card background colour cycle
9588
- // (by position) and staggered offset live in
9589
- // blocks-static/card-treatments.css; here we set the shared shape:
9590
- // generous padding, large radius, no border, flat (no shadow).
9591
- treatment: "color-blocked",
9592
- spacing: "spacious",
9593
- rounded: "2xl",
9594
- raised: false,
9595
- border: {
9596
- enabled: false
10171
+ recommendedHeaderLookIds: ["minimal-transparent"],
10172
+ recommendedFooterLookIds: [
10173
+ "site-footer-brand-two-band",
10174
+ "footer-muted-grounding"
10175
+ ],
10176
+ buttonPersonalityChoices: [
10177
+ buttonChoice("ornate-ritual"),
10178
+ buttonChoice("joy-stamp"),
10179
+ buttonChoice("ink-stamp")
10180
+ ],
10181
+ paletteVariantChoices: [
10182
+ paletteChoice("warm-dark-kirtan-gold"),
10183
+ paletteChoice("warm-dark-ember"),
10184
+ paletteChoice("brand-led-burgundy-gold")
10185
+ ]
10186
+ }),
10187
+ defineCuratedSiteStyle({
10188
+ id: "site-style:original-joy",
10189
+ name: "Original Joy",
10190
+ headingDecoration: { family: "organic-squiggle", colorToken: "primary" },
10191
+ description: "Warm, dark, and editorial: deep clay grounds, cream type, and bold burnt-orange accents for soulful community brands.",
10192
+ generationBrief: "Use a deep brown ground with cream text and burnt-orange accents, large display headings, generous spacing, organic rounded shapes, and bold colour-blocked feature sections. Lead with warmth and belonging; calls to action should feel strong but unhurried.",
10193
+ tokenRecipes: {
10194
+ palette: "brand-led",
10195
+ contrast: "maximum",
10196
+ radius: "rounded",
10197
+ shadow: "subtle",
10198
+ typography: "clean-sans",
10199
+ spacing: "airy",
10200
+ motion: "expressive"
10201
+ },
10202
+ compositionBudget: expressiveBudget,
10203
+ typographyPresetChoices: [
10204
+ typographyChoice("typography-preset:original-joy"),
10205
+ typographyChoice("typography-preset:bold-display"),
10206
+ typographyChoice("typography-preset:modern-sans")
10207
+ ],
10208
+ defaultTypographyPresetId: "typography-preset:original-joy",
10209
+ themeOverrides: {
10210
+ accordions: boldBorderedAccordionSystem,
10211
+ // Shared card system: warm rounded brown cards (event + testimonial cards
10212
+ // pick this up automatically) with a burnt-orange statement variant.
10213
+ cards: originalJoyCardSystem,
10214
+ testimonialQuote: accentGlyphQuote,
10215
+ bodyText: {
10216
+ intro: {
10217
+ paragraphSize: "editorial",
10218
+ headingSize: "editorial"
10219
+ }
9597
10220
  }
9598
- }
10221
+ },
10222
+ // Recommended block looks: the bold colour-blocked feature cards, a calm
10223
+ // band for the events spotlight, and statement testimonial cards.
10224
+ recommendedAppearancePresetIds: [
10225
+ "feature-cards-bold-colors",
10226
+ "offerings-calm-list",
10227
+ "testimonials-statement-cards"
10228
+ ],
10229
+ // Floating, transparent "Clear Split" header (no fill behind the nav links).
10230
+ defaultHeaderSelection: { layoutId: "floating", styleId: "minimal-surface" },
10231
+ recommendedHeaderLayoutChoices: [headerLayoutChoice("floating")],
10232
+ recommendedHeaderStyleChoicesByLayout: {
10233
+ floating: [
10234
+ headerStyleChoice("minimal-surface"),
10235
+ headerStyleChoice("split-glass"),
10236
+ headerStyleChoice("glass")
10237
+ ]
10238
+ },
10239
+ // Legacy bridge only (the real curation is the explicit selection above).
10240
+ // Kept to a reserved-space, non-overlay look on purpose: the split hero
10241
+ // flows below the Clear Split header, so we must NOT trigger the immersive
10242
+ // overlay-hero promotion that looks like `floating-glass` would force.
10243
+ recommendedHeaderLookIds: ["minimal-transparent"],
10244
+ recommendedFooterLookIds: [
10245
+ "site-footer-brand-two-band",
10246
+ "footer-muted-grounding"
10247
+ ],
10248
+ buttonPersonalityChoices: [
10249
+ buttonChoice("joy-stamp"),
10250
+ buttonChoice("ink-stamp"),
10251
+ buttonChoice("showtime-pill")
10252
+ ],
10253
+ paletteVariantChoices: [paletteChoice("warm-dark-ember")]
10254
+ })
10255
+ ];
10256
+ var curatedSiteStylesById = new Map(
10257
+ curatedSiteStyles.map((style) => [style.id, style])
10258
+ );
10259
+
10260
+ // ../theme-core/src/site-styles/siteStyleBlockPolicies.ts
10261
+ var defaultPolicyPageFlowPresetId = asPageFlowPresetId("generated-default");
10262
+ var southWestTwerkSchoolSiteStyleId = asSiteStyleId("site-style:south-west-twerk-school");
10263
+ var heroBrandScrimFixedFrameLookId = asAppearancePresetId("hero-brand-scrim-fixed-frame");
10264
+ var classicHeroLayoutVariantKey = asLayoutVariantKey("classic");
10265
+ var microHeroLayoutVariantKey = asLayoutVariantKey("micro");
10266
+ var waveBoundaryOptionId = asBoundaryOptionId("break:wave");
10267
+
10268
+ // ../theme-core/src/site-styles/pageDesignEditorModel.ts
10269
+ var pageFlowPresets = [
10270
+ {
10271
+ id: asPageFlowPresetId("flow:quiet"),
10272
+ label: "Quiet",
10273
+ boundaryStrategy: "quiet",
10274
+ defaultBoundaryOptionId: noneBoundaryOption.id
10275
+ },
10276
+ {
10277
+ id: asPageFlowPresetId("flow:balanced"),
10278
+ label: "Balanced",
10279
+ boundaryStrategy: "balanced",
10280
+ defaultBoundaryOptionId: softBoundaryOption.id
10281
+ },
10282
+ {
10283
+ id: asPageFlowPresetId("flow:expressive"),
10284
+ label: "Expressive",
10285
+ boundaryStrategy: "expressive",
10286
+ defaultBoundaryOptionId: spaciousBoundaryOption.id
9599
10287
  }
9600
- });
9601
- function uniformSectionForeground(token) {
9602
- return {
9603
- textColor: token,
9604
- headingColor: token,
9605
- linkColor: token,
9606
- supportingColor: token
9607
- };
9608
- }
10288
+ ];
9609
10289
 
9610
10290
  // ../theme-core/src/site-styles/generatedSchemas.ts
9611
10291
  import { z as z23 } from "zod";
@@ -10393,6 +11073,31 @@ function cardStylesField(options = {}) {
10393
11073
  return createBoxStylesFieldWithDepth("card", options);
10394
11074
  }
10395
11075
 
11076
+ // ../blocks/src/system/fields/imageShape.ts
11077
+ var standardImageShapeOptions = [
11078
+ { value: "default", label: "Default" },
11079
+ { value: "square", label: "Square corners" },
11080
+ { value: "rounded", label: "Rounded corners" },
11081
+ { value: "circle", label: "Circle" },
11082
+ { value: "arch", label: "Arch" }
11083
+ ];
11084
+ function createImageShapeField(options = {}) {
11085
+ return {
11086
+ id: options.id ?? "imageShape",
11087
+ type: "select",
11088
+ label: options.label ?? "Image shape",
11089
+ ...options.description ? { description: options.description } : {},
11090
+ required: false,
11091
+ defaultValue: options.defaultValue ?? "default",
11092
+ multiple: false,
11093
+ options: [...standardImageShapeOptions],
11094
+ ui: {
11095
+ intent: options.uiIntent ?? "display",
11096
+ ...options.visibleWhen ? { visibleWhen: options.visibleWhen } : {}
11097
+ }
11098
+ };
11099
+ }
11100
+
10396
11101
  // ../blocks/src/utils/env.ts
10397
11102
  function isDevEnvironment() {
10398
11103
  try {
@@ -11152,7 +11857,7 @@ function buildFooterNavAll(common) {
11152
11857
  return stack(
11153
11858
  { className: common.className, gap: common.gap, align: "stretch" },
11154
11859
  [item],
11155
- when(collectionPath)
11860
+ whenCollectionHasItems(collectionPath)
11156
11861
  );
11157
11862
  }
11158
11863
  function buildFooterNavLinksOnly(common) {
@@ -11185,7 +11890,7 @@ function buildFooterNavLinksOnly(common) {
11185
11890
  return stack(
11186
11891
  { className: common.className, gap: common.gap, align: "stretch" },
11187
11892
  [item],
11188
- when(collectionPath)
11893
+ whenCollectionHasItems(collectionPath)
11189
11894
  );
11190
11895
  }
11191
11896
  function buildFooterNavFlatten(common) {
@@ -11234,9 +11939,20 @@ function buildFooterNavFlatten(common) {
11234
11939
  return stack(
11235
11940
  { className: common.className, gap: common.gap, align: "stretch" },
11236
11941
  [item],
11237
- when(collectionPath)
11942
+ whenCollectionHasItems(collectionPath)
11238
11943
  );
11239
11944
  }
11945
+ var whenCollectionHasItems = (collectionPath) => (node) => ({
11946
+ ...node,
11947
+ $when: {
11948
+ when: {
11949
+ from: collectionPath,
11950
+ transforms: [{ id: "array.length" }]
11951
+ },
11952
+ equals: 0,
11953
+ not: true
11954
+ }
11955
+ });
11240
11956
  function footerNav(opts) {
11241
11957
  const mode = opts?.mode ?? "all";
11242
11958
  const collectionPath = opts?.collectionPath ?? "footerMenu.items";
@@ -13293,8 +14009,23 @@ function fragmentsToRepeaterField(id, label, fragments, options = {}) {
13293
14009
  var heroLayoutControlsFragment = defineFragment({
13294
14010
  id: "heroLayoutControls",
13295
14011
  title: "Hero Layout",
13296
- description: "Alignment and content width controls for hero layouts.",
14012
+ description: "Title scale, alignment, and content width controls for hero layouts.",
13297
14013
  fields: [
14014
+ {
14015
+ id: "titleSize",
14016
+ type: "select",
14017
+ label: "Title size",
14018
+ description: "Adjust the visual scale of the hero title.",
14019
+ required: false,
14020
+ ui: { intent: "display" },
14021
+ options: [
14022
+ { value: "auto", label: "Auto" },
14023
+ { value: "quiet", label: "Normal" },
14024
+ { value: "editorial", label: "Large" },
14025
+ { value: "display", label: "Huge" },
14026
+ { value: "poster", label: "Poster" }
14027
+ ]
14028
+ },
13298
14029
  {
13299
14030
  id: "contentAlignment",
13300
14031
  type: "select",
@@ -14089,7 +14820,18 @@ function heroSplitImagePane() {
14089
14820
  return stack(
14090
14821
  {
14091
14822
  gap: "none",
14092
- className: "rb-relative rb-overflow-hidden rb-rounded-3xl",
14823
+ className: {
14824
+ $bind: {
14825
+ from: "content.imageShape",
14826
+ transforms: [
14827
+ {
14828
+ id: "ui.imageShapeClassName",
14829
+ options: { baseClass: "rb-relative rb-overflow-hidden rb-rounded-3xl" }
14830
+ }
14831
+ ],
14832
+ fallback: "rb-relative rb-overflow-hidden rb-rounded-3xl"
14833
+ }
14834
+ },
14093
14835
  style: {
14094
14836
  minHeight: "clamp(18rem, 36vw, 34rem)"
14095
14837
  }
@@ -14207,6 +14949,12 @@ var heroConfig = {
14207
14949
  label: "Content card",
14208
14950
  renderInHeader: true,
14209
14951
  intent: "style"
14952
+ }),
14953
+ createImageShapeField({
14954
+ id: "imageShape",
14955
+ label: "Image shape",
14956
+ defaultValue: "default",
14957
+ uiIntent: "display"
14210
14958
  })
14211
14959
  ],
14212
14960
  layout: classicLayout,
@@ -14221,6 +14969,15 @@ var heroConfig = {
14221
14969
  description: "Hero section with headline, subtitle, and repeatable CTAs.",
14222
14970
  tags: ["header", "banner", "landing", "introduction", "welcome", "splash", "headline"],
14223
14971
  icon: "Sparkles",
14972
+ previewCustomize: {
14973
+ quickFieldPriority: [
14974
+ "titleSize",
14975
+ "contentAlignment",
14976
+ "contentMaxWidth",
14977
+ "verticalAlignment",
14978
+ "imageShape"
14979
+ ]
14980
+ },
14224
14981
  styleTokens: {
14225
14982
  typography: "display",
14226
14983
  spacing: "xl"
@@ -14237,7 +14994,8 @@ var standardAspectRatioOptions = [
14237
14994
  { value: "16/9", label: "16:9 (Landscape)" },
14238
14995
  { value: "4/3", label: "4:3 (Standard)" },
14239
14996
  { value: "1/1", label: "1:1 (Square)" },
14240
- { value: "3/4", label: "3:4 (Portrait)" }
14997
+ { value: "3/4", label: "3:4 (Portrait)" },
14998
+ { value: "9/16", label: "9:16 (Tall portrait)" }
14241
14999
  ];
14242
15000
  function createAspectRatioField(options = {}) {
14243
15001
  return {
@@ -15450,11 +16208,263 @@ var formDataSchema = z30.object({
15450
16208
  createdAt: z30.string(),
15451
16209
  updatedAt: z30.string()
15452
16210
  });
15453
- var formBlockDefinition = {
15454
- manifest: formManifest,
16211
+ var formBlockDefinition = {
16212
+ manifest: formManifest,
16213
+ dataSchemas: { form: formDataSchema.optional() },
16214
+ dataLoaders,
16215
+ runtime: formBlockRuntime
16216
+ };
16217
+
16218
+ // ../blocks/src/system/blocks/contact-newsletter.ts
16219
+ var contactNewsletterLayout = styledSection({
16220
+ children: sectionContainer([
16221
+ el(
16222
+ "div",
16223
+ { className: "contact-newsletter-grid" },
16224
+ [
16225
+ el(
16226
+ "div",
16227
+ { className: "contact-newsletter-column contact-newsletter-contact" },
16228
+ [
16229
+ el(
16230
+ "div",
16231
+ { className: "contact-newsletter-copy" },
16232
+ [
16233
+ text(
16234
+ {
16235
+ as: "h2",
16236
+ className: "form-copy-title"
16237
+ },
16238
+ when("contactTitle"),
16239
+ bind("contactTitle")
16240
+ ),
16241
+ richText(
16242
+ {
16243
+ className: "form-copy-intro rb-prose rb-max-w-none"
16244
+ },
16245
+ when("contactIntro"),
16246
+ bind("contactIntro")
16247
+ )
16248
+ ]
16249
+ ),
16250
+ el(
16251
+ "form",
16252
+ withApiBindings({
16253
+ spamProtectionEnabled: { $bind: { from: "$root.spamProtectionEnabled" } },
16254
+ submitLabel: { $bind: { from: "contactSubmitLabel" } },
16255
+ successMessage: { $bind: { from: "contactSuccessMessage" } }
16256
+ }),
16257
+ [],
16258
+ bind("data.form")
16259
+ )
16260
+ ]
16261
+ ),
16262
+ el(
16263
+ "div",
16264
+ { className: "contact-newsletter-column contact-newsletter-info contact-newsletter-newsletter" },
16265
+ [
16266
+ el(
16267
+ "div",
16268
+ { className: "contact-newsletter-copy" },
16269
+ [
16270
+ text(
16271
+ {
16272
+ as: "h2",
16273
+ className: "newsletter-copy-title"
16274
+ },
16275
+ when("newsletterTitle"),
16276
+ bind("newsletterTitle")
16277
+ ),
16278
+ richText(
16279
+ {
16280
+ className: "newsletter-copy-subtitle rb-prose rb-max-w-none"
16281
+ },
16282
+ when("newsletterSubtitle"),
16283
+ bind("newsletterSubtitle")
16284
+ )
16285
+ ]
16286
+ ),
16287
+ el(
16288
+ "newsletter-form",
16289
+ withApiBindings({
16290
+ listId: { $bind: { from: "listId" } },
16291
+ preset: { $bind: { from: "preset" } },
16292
+ includePhone: { $bind: { from: "includePhone" } },
16293
+ buttonLabel: { $bind: { from: "newsletterButtonLabel" } },
16294
+ successMessage: { $bind: { from: "newsletterSuccessMessage" } },
16295
+ privacyNote: { $bind: { from: "newsletterPrivacyNote" } },
16296
+ tags: { $bind: { from: "newsletterTags" } },
16297
+ spamProtectionEnabled: { $bind: { from: "$root.spamProtectionEnabled" } }
16298
+ }),
16299
+ []
16300
+ )
16301
+ ]
16302
+ )
16303
+ ]
16304
+ )
16305
+ ], {
16306
+ className: "contact-newsletter-container"
16307
+ }),
16308
+ baseClass: "",
16309
+ spacing: "medium",
16310
+ background: "surface"
16311
+ });
16312
+ var contactNewsletterManifest = createBlockManifest({
16313
+ id: "block.contact-newsletter",
16314
+ title: "Contact + Newsletter",
16315
+ titleSource: "contactTitle",
16316
+ description: "Two-column newsletter signup and contact form section.",
16317
+ category: "interactive",
16318
+ layout: contactNewsletterLayout,
16319
+ defaultVariant: "default",
16320
+ variants: {
16321
+ default: contactNewsletterLayout
16322
+ },
16323
+ variantOptions: {
16324
+ default: {
16325
+ label: "Two column",
16326
+ description: "Newsletter and contact form side by side.",
16327
+ icon: "Columns2"
16328
+ }
16329
+ },
16330
+ additionalFields: [
16331
+ {
16332
+ id: "newsletterTitle",
16333
+ type: "text",
16334
+ label: "Newsletter title",
16335
+ defaultValue: "Stay connected"
16336
+ },
16337
+ {
16338
+ id: "newsletterSubtitle",
16339
+ type: "richText",
16340
+ label: "Newsletter intro"
16341
+ },
16342
+ {
16343
+ id: "listId",
16344
+ type: "reference",
16345
+ label: "Newsletter list",
16346
+ description: "Select the list new subscribers should be added to.",
16347
+ required: true,
16348
+ referenceKind: "newsletterList",
16349
+ allowManualEntry: false,
16350
+ ui: { intent: "behavior" }
16351
+ },
16352
+ {
16353
+ id: "preset",
16354
+ type: "select",
16355
+ label: "Newsletter fields",
16356
+ defaultValue: "emailOnly",
16357
+ ui: { intent: "display" },
16358
+ options: [
16359
+ { value: "emailOnly", label: "Email only" },
16360
+ { value: "emailName", label: "Email + Name" },
16361
+ { value: "emailFirstLast", label: "Email + First/Last Name" },
16362
+ { value: "emailNameCompany", label: "Email + Name + Company (B2B)" }
16363
+ ]
16364
+ },
16365
+ {
16366
+ id: "includePhone",
16367
+ type: "boolean",
16368
+ label: "Include phone field",
16369
+ defaultValue: false,
16370
+ ui: { intent: "display" }
16371
+ },
16372
+ {
16373
+ id: "newsletterButtonLabel",
16374
+ type: "text",
16375
+ label: "Newsletter button label",
16376
+ defaultValue: "Subscribe",
16377
+ ui: { intent: "display" }
16378
+ },
16379
+ {
16380
+ id: "newsletterSuccessMessage",
16381
+ type: "text",
16382
+ label: "Newsletter success message",
16383
+ defaultValue: "Thanks for subscribing!",
16384
+ ui: { intent: "behavior" }
16385
+ },
16386
+ {
16387
+ id: "newsletterPrivacyNote",
16388
+ type: "text",
16389
+ label: "Privacy note",
16390
+ ui: { intent: "display" }
16391
+ },
16392
+ {
16393
+ id: "newsletterTags",
16394
+ type: "text",
16395
+ label: "Newsletter tags",
16396
+ description: "Optional tags to apply on subscribe, separated by comma or semicolon.",
16397
+ ui: { intent: "behavior" }
16398
+ },
16399
+ {
16400
+ id: "contactTitle",
16401
+ type: "text",
16402
+ label: "Contact title",
16403
+ defaultValue: "Get in touch"
16404
+ },
16405
+ {
16406
+ id: "contactIntro",
16407
+ type: "richText",
16408
+ label: "Contact intro"
16409
+ },
16410
+ {
16411
+ id: "formSlug",
16412
+ type: "reference",
16413
+ label: "Contact form",
16414
+ description: "Pick a saved form to render.",
16415
+ required: true,
16416
+ referenceKind: "form",
16417
+ allowManualEntry: false,
16418
+ ui: { intent: "behavior" }
16419
+ },
16420
+ {
16421
+ id: "contactSubmitLabel",
16422
+ type: "text",
16423
+ label: "Contact button label",
16424
+ defaultValue: "Send message",
16425
+ ui: { intent: "display" }
16426
+ },
16427
+ {
16428
+ id: "contactSuccessMessage",
16429
+ type: "text",
16430
+ label: "Contact success message",
16431
+ defaultValue: "Thanks - we received your message.",
16432
+ ui: { intent: "behavior" }
16433
+ }
16434
+ ],
16435
+ styleTokens: {
16436
+ background: "surface",
16437
+ typography: "body",
16438
+ spacing: "md"
16439
+ },
16440
+ behaviours: {
16441
+ supportsThemeSwitching: true,
16442
+ inlineEditing: true,
16443
+ animation: false,
16444
+ paletteHidden: false
16445
+ },
16446
+ tags: [
16447
+ "contact",
16448
+ "newsletter",
16449
+ "signup",
16450
+ "email",
16451
+ "form",
16452
+ "lead-capture"
16453
+ ],
16454
+ icon: "MailPlus"
16455
+ });
16456
+ var contactNewsletterBlockDefinition = {
16457
+ manifest: contactNewsletterManifest,
15455
16458
  dataSchemas: { form: formDataSchema.optional() },
15456
- dataLoaders,
15457
- runtime: formBlockRuntime
16459
+ dataLoaders: {
16460
+ form: {
16461
+ endpoint: "getPublicFormById",
16462
+ params: {
16463
+ formSlug: { $bind: { from: "formSlug" } }
16464
+ },
16465
+ mode: "server"
16466
+ }
16467
+ }
15458
16468
  };
15459
16469
 
15460
16470
  // ../blocks/src/system/blocks/faq.ts
@@ -16000,6 +17010,21 @@ var siteHeaderManifest = createBlockManifest({
16000
17010
  id: "block.site-header",
16001
17011
  title: "Site Header",
16002
17012
  category: "layout",
17013
+ additionalFields: [
17014
+ {
17015
+ id: "mode",
17016
+ type: "select",
17017
+ label: "Header display",
17018
+ required: false,
17019
+ multiple: false,
17020
+ defaultValue: "default",
17021
+ options: [
17022
+ { value: "default", label: "Show header" },
17023
+ { value: "hidden", label: "Hide header" }
17024
+ ],
17025
+ ui: { intent: "display" }
17026
+ }
17027
+ ],
16003
17028
  // Skip section styles - this block uses theme-based styling
16004
17029
  skipSectionStyles: true,
16005
17030
  // Block manages its own wrapper - enables sticky positioning
@@ -17402,6 +18427,9 @@ var mediaTextManifest = createBlockManifest({
17402
18427
  category: "layout",
17403
18428
  includeContainerStyles: true,
17404
18429
  titleSource: "title",
18430
+ previewCustomize: {
18431
+ quickFieldPriority: ["imagePosition", "ratio", "imageShape", "titleAlignment", "aspectRatio"]
18432
+ },
17405
18433
  additionalFields: [
17406
18434
  {
17407
18435
  id: "images",
@@ -17440,7 +18468,7 @@ var mediaTextManifest = createBlockManifest({
17440
18468
  {
17441
18469
  id: "titleAlignment",
17442
18470
  type: "select",
17443
- label: "Title alignment",
18471
+ label: "Content alignment",
17444
18472
  required: false,
17445
18473
  defaultValue: "left",
17446
18474
  multiple: false,
@@ -17498,7 +18526,18 @@ var mediaTextManifest = createBlockManifest({
17498
18526
  transition: "slide"
17499
18527
  },
17500
18528
  ui: { intent: "behavior" }
17501
- }),
18529
+ }).map((field) => ({
18530
+ ...field,
18531
+ ui: {
18532
+ ...field.ui ?? {},
18533
+ visibleWhen: field.id === "carouselAutoplayDelay" ? {
18534
+ allOf: [
18535
+ { field: "images", minItems: 2 },
18536
+ { field: "carouselAutoplay", equals: true }
18537
+ ]
18538
+ } : { field: "images", minItems: 2 }
18539
+ }
18540
+ })),
17502
18541
  createAspectRatioField({
17503
18542
  id: "aspectRatio",
17504
18543
  label: "Media aspect ratio",
@@ -17506,6 +18545,12 @@ var mediaTextManifest = createBlockManifest({
17506
18545
  defaultValue: "auto",
17507
18546
  visibleWhen: { field: "images", notEquals: null }
17508
18547
  }),
18548
+ createImageShapeField({
18549
+ id: "imageShape",
18550
+ label: "Media shape",
18551
+ defaultValue: "default",
18552
+ visibleWhen: { field: "images", notEquals: null }
18553
+ }),
17509
18554
  {
17510
18555
  id: "text",
17511
18556
  type: "richText",
@@ -17539,6 +18584,30 @@ var mediaTextManifest = createBlockManifest({
17539
18584
  ...options?.not ? { not: true } : {}
17540
18585
  }
17541
18586
  });
18587
+ const bodyClassNameFromAlignment = {
18588
+ $bind: {
18589
+ from: "content.titleAlignment",
18590
+ transforms: [
18591
+ {
18592
+ id: "ui.bodyClassFromAlignment",
18593
+ options: { base: "rb-prose rb-max-w-none" }
18594
+ }
18595
+ ],
18596
+ fallback: "rb-prose rb-max-w-none"
18597
+ }
18598
+ };
18599
+ const titleClassNameFromAlignment = {
18600
+ $bind: {
18601
+ from: "content.titleAlignment",
18602
+ transforms: [
18603
+ {
18604
+ id: "ui.headingClassFromAlignment",
18605
+ options: { base: "" }
18606
+ }
18607
+ ],
18608
+ fallback: ""
18609
+ }
18610
+ };
17542
18611
  const defaultTextColumn = el("div", {}, [
17543
18612
  styledCard(
17544
18613
  [
@@ -17563,8 +18632,55 @@ var mediaTextManifest = createBlockManifest({
17563
18632
  bind("content.text")
17564
18633
  )
17565
18634
  ]);
18635
+ const bioTextColumn = el(
18636
+ "div",
18637
+ { className: "rb-flex rb-h-full rb-w-full rb-max-w-prose rb-flex-col rb-justify-center rb-gap-5" },
18638
+ [
18639
+ text(
18640
+ {
18641
+ as: "h2",
18642
+ className: titleClassNameFromAlignment
18643
+ },
18644
+ when("content.title"),
18645
+ bind("content.title")
18646
+ ),
18647
+ styledCard(
18648
+ [
18649
+ richText(
18650
+ {
18651
+ className: bodyClassNameFromAlignment
18652
+ },
18653
+ bind("content.text")
18654
+ )
18655
+ ],
18656
+ {
18657
+ stylesFrom: "content._textCardStyles",
18658
+ backgroundFrom: "content._textCardStyles.background"
18659
+ },
18660
+ when("content.wrapTextInCard")
18661
+ ),
18662
+ richText(
18663
+ {
18664
+ className: bodyClassNameFromAlignment
18665
+ },
18666
+ when("content.wrapTextInCard", { not: true }),
18667
+ bind("content.text")
18668
+ )
18669
+ ]
18670
+ );
17566
18671
  const defaultImageCommonProps = {
17567
- className: "rb-w-full rb-h-auto rb-object-cover",
18672
+ className: {
18673
+ $bind: {
18674
+ from: "content.imageShape",
18675
+ transforms: [
18676
+ {
18677
+ id: "ui.imageShapeClassName",
18678
+ options: { baseClass: "rb-w-full rb-h-auto rb-object-cover" }
18679
+ }
18680
+ ],
18681
+ fallback: "rb-w-full rb-h-auto rb-object-cover"
18682
+ }
18683
+ },
17568
18684
  style: {
17569
18685
  aspectRatio: { $bind: { from: "content.aspectRatio" } }
17570
18686
  }
@@ -17605,6 +18721,27 @@ var mediaTextManifest = createBlockManifest({
17605
18721
  ],
17606
18722
  whenImagesLength(0, { not: true })
17607
18723
  );
18724
+ const bioImagesLayout = el(
18725
+ "div",
18726
+ {},
18727
+ [
18728
+ responsiveTwoColumn({
18729
+ image: el("div", {}, [
18730
+ el("div", {}, [defaultSingleImage], whenImagesLength(1)),
18731
+ el("div", {}, [defaultCarouselImages], whenImagesLength(1, { not: true }))
18732
+ ]),
18733
+ text: bioTextColumn,
18734
+ ratioFrom: "content.ratio",
18735
+ imagePositionFrom: "content.imagePosition",
18736
+ containerClassName: "rb-flex rb-flex-col rb-md-flex-row rb-md-items-center",
18737
+ gapFrom: "content.gap",
18738
+ gapFallback: "comfortable",
18739
+ imageWrapperClassName: "rb-w-full rb-shrink-0",
18740
+ textWrapperClassName: "rb-w-full rb-min-w-0 rb-flex-1 rb-self-stretch"
18741
+ })
18742
+ ],
18743
+ whenImagesLength(0, { not: true })
18744
+ );
17608
18745
  const defaultTextOnlyLayout = el(
17609
18746
  "div",
17610
18747
  {},
@@ -17634,7 +18771,45 @@ var mediaTextManifest = createBlockManifest({
17634
18771
  ],
17635
18772
  whenImagesLength(0)
17636
18773
  );
18774
+ const bioTextOnlyLayout = el(
18775
+ "div",
18776
+ { className: "rb-flex rb-w-full rb-max-w-prose rb-flex-col rb-gap-5" },
18777
+ [
18778
+ text(
18779
+ {
18780
+ as: "h2",
18781
+ className: titleClassNameFromAlignment
18782
+ },
18783
+ when("content.title"),
18784
+ bind("content.title")
18785
+ ),
18786
+ styledCard(
18787
+ [
18788
+ richText(
18789
+ {
18790
+ className: bodyClassNameFromAlignment
18791
+ },
18792
+ bind("content.text")
18793
+ )
18794
+ ],
18795
+ {
18796
+ stylesFrom: "content._textCardStyles",
18797
+ backgroundFrom: "content._textCardStyles.background"
18798
+ },
18799
+ when("content.wrapTextInCard")
18800
+ ),
18801
+ richText(
18802
+ {
18803
+ className: bodyClassNameFromAlignment
18804
+ },
18805
+ when("content.wrapTextInCard", { not: true }),
18806
+ bind("content.text")
18807
+ )
18808
+ ],
18809
+ whenImagesLength(0)
18810
+ );
17637
18811
  const defaultInner = el("div", {}, [defaultImagesLayout, defaultTextOnlyLayout]);
18812
+ const bioInner = el("div", {}, [bioImagesLayout, bioTextOnlyLayout]);
17638
18813
  const defaultLayout2 = styledSection({
17639
18814
  children: styledContainer({
17640
18815
  rootType: "stack",
@@ -17643,18 +18818,7 @@ var mediaTextManifest = createBlockManifest({
17643
18818
  text(
17644
18819
  {
17645
18820
  as: "h2",
17646
- className: {
17647
- $bind: {
17648
- from: "content.titleAlignment",
17649
- transforms: [
17650
- {
17651
- id: "ui.headingClassFromAlignment",
17652
- options: { base: "" }
17653
- }
17654
- ],
17655
- fallback: ""
17656
- }
17657
- }
18821
+ className: titleClassNameFromAlignment
17658
18822
  },
17659
18823
  when("content.title"),
17660
18824
  bind("content.title")
@@ -17666,14 +18830,28 @@ var mediaTextManifest = createBlockManifest({
17666
18830
  baseClass: "",
17667
18831
  spacing: "medium"
17668
18832
  });
18833
+ const bioLayout = styledSection({
18834
+ children: styledContainer({
18835
+ rootType: "stack",
18836
+ rootProps: { gap: "lg" },
18837
+ children: [bioInner]
18838
+ }),
18839
+ baseClass: "",
18840
+ spacing: "medium"
18841
+ });
17669
18842
  return {
17670
18843
  layout: defaultLayout2,
17671
18844
  variants: {
17672
- default: defaultLayout2
18845
+ default: defaultLayout2,
18846
+ bio: bioLayout
17673
18847
  },
17674
18848
  defaultVariant: "default",
17675
18849
  variantOptions: {
17676
- default: { label: "Default" }
18850
+ default: { label: "Default" },
18851
+ bio: {
18852
+ label: "Bio",
18853
+ description: "Vertically centered title and copy beside media."
18854
+ }
17677
18855
  }
17678
18856
  };
17679
18857
  })(),
@@ -18379,10 +19557,8 @@ var occurrenceContextSchema = z36.object({
18379
19557
  // ../blocks/src/system/runtime/nodes/event-registration.interactive.ts
18380
19558
  import { z as z38 } from "zod";
18381
19559
 
18382
- // ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
18383
- import { z as z37 } from "zod";
18384
-
18385
19560
  // ../blocks/src/system/constants/events.ts
19561
+ var EVENT_CONTENT_TYPE_SLUGS = ["event", "events"];
18386
19562
  var eventCalendarDisplayModeValues = ["combined", "month", "week", "list", "timetable"];
18387
19563
  var eventCalendarListLayoutValues = ["stack", "grid", "compact"];
18388
19564
  var eventCalendarListLayoutOptions = [
@@ -18396,8 +19572,133 @@ function isEventCalendarDisplayMode(value) {
18396
19572
  function isEventCalendarListLayout(value) {
18397
19573
  return typeof value === "string" && eventCalendarListLayoutValues.includes(value);
18398
19574
  }
19575
+ function isEventContentType(slug) {
19576
+ if (!slug) return false;
19577
+ return EVENT_CONTENT_TYPE_SLUGS.includes(slug);
19578
+ }
19579
+
19580
+ // ../blocks/src/system/runtime/nodes/events/shared/pricing.ts
19581
+ var DEFAULT_EVENT_CURRENCY = "USD";
19582
+ function resolveRuntimeEventPricing(event) {
19583
+ if (isPublicEventPricing(event.pricing)) {
19584
+ return event.pricing;
19585
+ }
19586
+ const legacy = event;
19587
+ const currency = readCurrency(legacy.currency);
19588
+ if (event.requiresRegistration === false) {
19589
+ return {
19590
+ kind: "drop_in",
19591
+ currency,
19592
+ display: { kind: "free", currency }
19593
+ };
19594
+ }
19595
+ if (legacy.pricingMode === "ticket_types") {
19596
+ const ticketTypes = Array.isArray(legacy.ticketTypes) ? legacy.ticketTypes.filter(isPublicEventTicketType) : [];
19597
+ return {
19598
+ kind: "ticket_types",
19599
+ currency,
19600
+ ticketTypes,
19601
+ display: readTicketTypePriceDisplay(legacy.priceDisplay, currency)
19602
+ };
19603
+ }
19604
+ const amount = typeof legacy.price === "number" ? legacy.price : 0;
19605
+ if (legacy.pricingType === "paid" && amount > 0) {
19606
+ return {
19607
+ kind: "single_paid",
19608
+ amount,
19609
+ currency,
19610
+ display: { kind: "exact", amount, currency }
19611
+ };
19612
+ }
19613
+ return {
19614
+ kind: "free_registration",
19615
+ currency,
19616
+ display: { kind: "free", currency }
19617
+ };
19618
+ }
19619
+ function readCurrency(value) {
19620
+ return typeof value === "string" && value.trim().length > 0 ? value : DEFAULT_EVENT_CURRENCY;
19621
+ }
19622
+ function isRecord2(value) {
19623
+ return typeof value === "object" && value !== null && !Array.isArray(value);
19624
+ }
19625
+ function isPublicEventPricing(value) {
19626
+ if (!isRecord2(value) || typeof value.kind !== "string") return false;
19627
+ return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "ticket_types" || value.kind === "course";
19628
+ }
19629
+ function isPublicEventTicketType(value) {
19630
+ return isRecord2(value) && typeof value.id === "string";
19631
+ }
19632
+ function readTicketTypePriceDisplay(value, currency) {
19633
+ const display = readLegacyPriceDisplay(value, currency);
19634
+ return display.kind === "course" ? { kind: "unavailable", currency } : display;
19635
+ }
19636
+ function readLegacyPriceDisplay(value, currency) {
19637
+ if (!isRecord2(value) || typeof value.kind !== "string") {
19638
+ return { kind: "unavailable", currency };
19639
+ }
19640
+ const displayCurrency = readCurrency(value.currency);
19641
+ switch (value.kind) {
19642
+ case "free":
19643
+ return { kind: "free", currency: displayCurrency };
19644
+ case "exact":
19645
+ return readAmount(value.amount) !== null ? {
19646
+ kind: "exact",
19647
+ amount: readAmount(value.amount) ?? 0,
19648
+ currency: displayCurrency
19649
+ } : { kind: "unavailable", currency };
19650
+ case "from":
19651
+ return readAmount(value.amount) !== null ? {
19652
+ kind: "from",
19653
+ amount: readAmount(value.amount) ?? 0,
19654
+ currency: displayCurrency
19655
+ } : { kind: "unavailable", currency };
19656
+ case "mixed":
19657
+ return readAmount(value.paidFromAmount) !== null ? {
19658
+ kind: "mixed",
19659
+ paidFromAmount: readAmount(value.paidFromAmount) ?? 0,
19660
+ currency: displayCurrency
19661
+ } : { kind: "unavailable", currency };
19662
+ case "unavailable":
19663
+ return { kind: "unavailable", currency: displayCurrency };
19664
+ case "course":
19665
+ return isRecord2(value.display) ? {
19666
+ kind: "course",
19667
+ display: readCoursePriceDisplay(value.display, displayCurrency)
19668
+ } : {
19669
+ kind: "course",
19670
+ display: { kind: "unavailable", currency: displayCurrency }
19671
+ };
19672
+ default:
19673
+ return { kind: "unavailable", currency };
19674
+ }
19675
+ }
19676
+ function readCoursePriceDisplay(value, currency) {
19677
+ switch (value.kind) {
19678
+ case "free":
19679
+ return { kind: "free", currency: readCurrency(value.currency) };
19680
+ case "exact":
19681
+ return readAmount(value.amount) !== null ? {
19682
+ kind: "exact",
19683
+ amount: readAmount(value.amount) ?? 0,
19684
+ currency: readCurrency(value.currency)
19685
+ } : { kind: "unavailable", currency };
19686
+ case "from":
19687
+ return readAmount(value.amount) !== null ? {
19688
+ kind: "from",
19689
+ amount: readAmount(value.amount) ?? 0,
19690
+ currency: readCurrency(value.currency)
19691
+ } : { kind: "unavailable", currency };
19692
+ default:
19693
+ return { kind: "unavailable", currency };
19694
+ }
19695
+ }
19696
+ function readAmount(value) {
19697
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
19698
+ }
18399
19699
 
18400
19700
  // ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
19701
+ import { z as z37 } from "zod";
18401
19702
  var previewStageSchema = z37.enum(["preview", "published"]);
18402
19703
  var registrationButtonVariantSchema = z37.enum(["primary", "secondary", "outline"]);
18403
19704
  var eventButtonVariantSchema = z37.enum(["primary", "secondary", "outline", "link"]);
@@ -18408,12 +19709,73 @@ var weekStartSchema = z37.enum(["sunday", "monday"]);
18408
19709
  var filterAutoShowSchema = z37.enum(["auto", "always", "never"]);
18409
19710
  var calendarTabViewsSchema = z37.enum(["both", "month", "week"]);
18410
19711
 
19712
+ // ../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts
19713
+ function getWizardStepsForContext(hasPreSelectedContext, needsPaymentStep) {
19714
+ const baseSteps = hasPreSelectedContext ? ["select-tickets", "enter-details"] : ["select-event", "select-tickets", "enter-details"];
19715
+ if (!needsPaymentStep) {
19716
+ return baseSteps;
19717
+ }
19718
+ return [...baseSteps, "select-payment"];
19719
+ }
19720
+
19721
+ // ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
19722
+ function eventMatchesOccurrenceId(event, occurrenceId) {
19723
+ return event.registrationOccurrenceId === occurrenceId || event.publicEventId === occurrenceId;
19724
+ }
19725
+ function findPreSelectedEvent(input) {
19726
+ const occurrenceContext = input.occurrenceContext;
19727
+ if (!occurrenceContext) {
19728
+ return null;
19729
+ }
19730
+ const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
19731
+ startsAt: occurrenceContext.startsAt,
19732
+ timeZone: occurrenceContext.timeZone
19733
+ }));
19734
+ return input.scopedEvents.find(
19735
+ (event) => eventMatchesOccurrenceId(event, occurrenceContext.id) || getBookingLocalDateKey(toScheduledBookingDateTime({
19736
+ startsAt: event.startsAt,
19737
+ timeZone: event.timeZone
19738
+ })) === contextDate
19739
+ ) ?? null;
19740
+ }
19741
+ function resolveEventRequiresPayment(input) {
19742
+ if (input.eligibility) {
19743
+ return input.eligibility.requiresPayment;
19744
+ }
19745
+ if (input.selectedTicketType) {
19746
+ return input.selectedTicketType.priceAmount > 0;
19747
+ }
19748
+ if (!input.event) {
19749
+ return false;
19750
+ }
19751
+ return publicEventPricingType(resolveRuntimeEventPricing(input.event)) !== "free";
19752
+ }
19753
+
19754
+ // ../blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.ts
19755
+ function toRegistrationEvent(event) {
19756
+ return {
19757
+ ...event,
19758
+ pricing: resolveRuntimeEventPricing(event),
19759
+ publicEventId: event.id,
19760
+ registrationOccurrenceId: event.occurrenceId
19761
+ };
19762
+ }
19763
+ function toRegistrationEvents(events) {
19764
+ return events.map(toRegistrationEvent);
19765
+ }
19766
+
18411
19767
  // ../blocks/src/system/runtime/nodes/event-registration.interactive.ts
19768
+ var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS = ["Date", "Tickets", "Details"];
19769
+ var EVENT_REGISTRATION_SHELL_STEP_LABELS = ["Event", "Date", "Tickets", "Details", "Payment"];
18412
19770
  var contentEntrySchema = z38.object({
18413
19771
  id: z38.string(),
18414
19772
  slug: z38.string(),
18415
19773
  contentTypeSlug: z38.string()
18416
19774
  });
19775
+ var eventRegistrationPublicEventSchema = z38.preprocess(
19776
+ normalizeEventRegistrationEventInput,
19777
+ publicEventSchema
19778
+ );
18417
19779
  var eventRegistrationSourceSchema = z38.object({
18418
19780
  siteId: z38.string().optional(),
18419
19781
  apiBaseUrl: z38.string().optional(),
@@ -18421,7 +19783,7 @@ var eventRegistrationSourceSchema = z38.object({
18421
19783
  previewToken: z38.string().nullable().optional(),
18422
19784
  occurrenceContext: occurrenceContextSchema.optional(),
18423
19785
  contentEntry: contentEntrySchema.nullable().optional(),
18424
- events: z38.array(publicEventSchema).nullable().optional(),
19786
+ events: z38.array(eventRegistrationPublicEventSchema).nullable().optional(),
18425
19787
  className: z38.string().nullable().optional(),
18426
19788
  buttonText: z38.string().nullable().optional(),
18427
19789
  maxTickets: z38.string().nullable().optional(),
@@ -18436,14 +19798,17 @@ var eventRegistrationSourceSchema = z38.object({
18436
19798
  });
18437
19799
  var eventRegistrationDisplaySchema = z38.object({
18438
19800
  kind: z38.literal("event-registration"),
18439
- state: z38.literal("shell"),
19801
+ state: z38.literal("generic-shell"),
18440
19802
  className: z38.string().nullable(),
19803
+ titleText: z38.string(),
19804
+ bodyText: z38.string(),
19805
+ stepLabels: z38.array(z38.enum(EVENT_REGISTRATION_SHELL_STEP_LABELS)).min(1),
18441
19806
  summaryButtonText: z38.string()
18442
19807
  });
18443
19808
  var eventRegistrationHydrationSchema = z38.object({
18444
19809
  occurrenceContext: occurrenceContextSchema.optional(),
18445
19810
  contentEntry: contentEntrySchema.nullable().optional(),
18446
- events: z38.array(publicEventSchema).nullable().optional(),
19811
+ events: z38.array(eventRegistrationPublicEventSchema).nullable().optional(),
18447
19812
  maxTickets: z38.string().optional(),
18448
19813
  showVenue: z38.boolean().optional(),
18449
19814
  showCapacity: z38.boolean().optional(),
@@ -18472,13 +19837,81 @@ var eventRegistrationIslandMetaKeys = defineInteractiveIslandMetaKeys(
18472
19837
  "stage"
18473
19838
  );
18474
19839
  function buildEventRegistrationDisplay(source) {
19840
+ const stepLabels = buildEventRegistrationShellStepLabels(source);
18475
19841
  return {
18476
19842
  kind: "event-registration",
18477
- state: "shell",
19843
+ state: "generic-shell",
18478
19844
  className: source.className ?? null,
19845
+ titleText: "Event registration",
19846
+ bodyText: buildEventRegistrationShellBodyText(stepLabels),
19847
+ stepLabels,
18479
19848
  summaryButtonText: source.buttonText?.trim() || "Register"
18480
19849
  };
18481
19850
  }
19851
+ function buildEventRegistrationShellStepLabels(source) {
19852
+ const scopedEvents = scopeEventRegistrationEvents(source);
19853
+ if (scopedEvents.length === 0) {
19854
+ return EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
19855
+ }
19856
+ const preSelectedEvent = findPreSelectedEvent({
19857
+ scopedEvents,
19858
+ occurrenceContext: source.occurrenceContext
19859
+ });
19860
+ const hasPreSelectedContext = Boolean(source.occurrenceContext || preSelectedEvent);
19861
+ const needsPaymentStep = hasPreSelectedContext && preSelectedEvent ? resolveEventRequiresPayment({
19862
+ eligibility: null,
19863
+ selectedTicketType: null,
19864
+ event: preSelectedEvent
19865
+ }) : false;
19866
+ return getWizardStepsForContext(hasPreSelectedContext, needsPaymentStep).map((step) => shellLabelForRegistrationStep(step, scopedEvents));
19867
+ }
19868
+ function scopeEventRegistrationEvents(source) {
19869
+ const events = toRegistrationEvents(source.events ?? []);
19870
+ if (source.occurrenceContext?.seriesId) {
19871
+ return events.filter((event) => event.seriesId === source.occurrenceContext?.seriesId);
19872
+ }
19873
+ const entrySlug = source.contentEntry?.slug;
19874
+ const entryContentType = source.contentEntry?.contentTypeSlug;
19875
+ if (entrySlug && entryContentType && isEventContentType(entryContentType)) {
19876
+ return events.filter((event) => event.slug === entrySlug);
19877
+ }
19878
+ return events;
19879
+ }
19880
+ function shellLabelForRegistrationStep(step, events) {
19881
+ switch (step) {
19882
+ case "select-event":
19883
+ return isDateSelection(events) ? "Date" : "Event";
19884
+ case "select-tickets":
19885
+ return "Tickets";
19886
+ case "enter-details":
19887
+ return "Details";
19888
+ case "select-payment":
19889
+ return "Payment";
19890
+ case "error":
19891
+ case "success":
19892
+ case "submitting":
19893
+ case "redirecting":
19894
+ case "verifying-payment":
19895
+ case "verifying-timeout":
19896
+ case "payment-failed":
19897
+ return "Details";
19898
+ }
19899
+ }
19900
+ function isDateSelection(events) {
19901
+ const firstSeriesId = events[0]?.seriesId;
19902
+ return Boolean(
19903
+ events.length > 1 && firstSeriesId && events.every((event) => event.seriesId === firstSeriesId)
19904
+ );
19905
+ }
19906
+ function buildEventRegistrationShellBodyText(stepLabels) {
19907
+ if (stepLabels.includes("Payment")) {
19908
+ return "Preparing tickets, details, and payment options.";
19909
+ }
19910
+ if (stepLabels[0] === "Tickets") {
19911
+ return "Preparing tickets and booking details.";
19912
+ }
19913
+ return "Preparing dates, tickets, and booking details.";
19914
+ }
18482
19915
  var eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
18483
19916
  kind: "client-owned",
18484
19917
  contracts: {
@@ -18502,6 +19935,18 @@ var eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
18502
19935
  }
18503
19936
  })
18504
19937
  });
19938
+ function normalizeEventRegistrationEventInput(value) {
19939
+ if (!isRecord3(value)) {
19940
+ return value;
19941
+ }
19942
+ return {
19943
+ ...value,
19944
+ pricing: resolveRuntimeEventPricing(value)
19945
+ };
19946
+ }
19947
+ function isRecord3(value) {
19948
+ return typeof value === "object" && value !== null && !Array.isArray(value);
19949
+ }
18505
19950
  var eventRegistrationInteractiveIslandPropsCodec = createInteractiveIslandCodec({
18506
19951
  runtime: eventRegistrationBlockRuntime,
18507
19952
  mode: "event-registration",
@@ -20924,7 +22369,7 @@ function inferLegacyOfferingsPreviewGroupOrder(overrides) {
20924
22369
  return keys.length >= 2 ? keys : [];
20925
22370
  }
20926
22371
  function normalizeOfferingsPreviewContentForWrite(value) {
20927
- if (!isRecord2(value)) return null;
22372
+ if (!isRecord4(value)) return null;
20928
22373
  const groupOrderValue = value.groupOrder;
20929
22374
  if (Array.isArray(groupOrderValue)) {
20930
22375
  const normalized = normalizeOfferingsPreviewGroupOrder(groupOrderValue);
@@ -20937,7 +22382,7 @@ function normalizeOfferingsPreviewContentForWrite(value) {
20937
22382
  return { ...value, groupOrder: [] };
20938
22383
  }
20939
22384
  const legacyOrder = inferLegacyOfferingsPreviewGroupOrder(
20940
- Array.isArray(value.groupOverrides) ? value.groupOverrides.filter(isRecord2) : []
22385
+ Array.isArray(value.groupOverrides) ? value.groupOverrides.filter(isRecord4) : []
20941
22386
  );
20942
22387
  return legacyOrder.length > 0 ? { ...value, groupOrder: legacyOrder } : value;
20943
22388
  }
@@ -20951,7 +22396,7 @@ function uniqueOfferingsPreviewSourceKeys(values) {
20951
22396
  }
20952
22397
  return keys;
20953
22398
  }
20954
- function isRecord2(value) {
22399
+ function isRecord4(value) {
20955
22400
  return typeof value === "object" && value !== null && !Array.isArray(value);
20956
22401
  }
20957
22402
 
@@ -21318,7 +22763,7 @@ function isOfferingsPreviewItemLimit(value) {
21318
22763
  return value === "1" || value === "2" || value === "3" || value === "4" || value === "5" || value === "6" || value === null;
21319
22764
  }
21320
22765
  function normalizeOfferingsPreviewGroupOverride(value) {
21321
- if (!isRecord3(value)) return [];
22766
+ if (!isRecord5(value)) return [];
21322
22767
  const override = {};
21323
22768
  if (isOfferingsPreviewSourceKey(value.sourceKey) || value.sourceKey === null) {
21324
22769
  override.sourceKey = value.sourceKey;
@@ -21350,12 +22795,12 @@ function isButtonVariant(value) {
21350
22795
  return value === "primary" || value === "secondary" || value === "outline" || value === "link" || value === null;
21351
22796
  }
21352
22797
  function normalizeCardStylesContent(value) {
21353
- return isRecord3(value) || value === null ? value : void 0;
22798
+ return isRecord5(value) || value === null ? value : void 0;
21354
22799
  }
21355
22800
  function normalizeSectionStylesContent(value) {
21356
- return isRecord3(value) || value === null ? value : void 0;
22801
+ return isRecord5(value) || value === null ? value : void 0;
21357
22802
  }
21358
- function isRecord3(value) {
22803
+ function isRecord5(value) {
21359
22804
  return typeof value === "object" && value !== null && !Array.isArray(value);
21360
22805
  }
21361
22806
 
@@ -25315,11 +26760,13 @@ var heroImageSurfaceMotions = [
25315
26760
  ];
25316
26761
  var standardEyebrowTreatments = [
25317
26762
  "plain",
26763
+ "accent",
25318
26764
  "pill",
25319
26765
  "accent-pill"
25320
26766
  ];
25321
26767
  var animatedEyebrowTreatments = [
25322
26768
  "plain",
26769
+ "accent",
25323
26770
  "pill",
25324
26771
  "accent-pill",
25325
26772
  "pill-bounce",
@@ -25620,6 +27067,17 @@ var systemBlockDefinitionsRaw = [
25620
27067
  layoutProfile({ variantKey: "two-column", family: "split", weight: "standard" })
25621
27068
  ]
25622
27069
  })),
27070
+ withDesignCapability("block.contact-newsletter", contactNewsletterBlockDefinition, sectionOnly(), defineBlockDesignMetadata({
27071
+ flow: conversionFlow,
27072
+ layoutProfiles: [
27073
+ layoutProfile({
27074
+ variantKey: "default",
27075
+ family: "split",
27076
+ weight: "featured",
27077
+ bias: "soft"
27078
+ })
27079
+ ]
27080
+ })),
25623
27081
  withDesignCapability("block.faq", faqBlockDefinition, withEyebrowCapability(declareBlockDesignCapability({
25624
27082
  sectionSurfaces: "supported",
25625
27083
  contentFrames: ["plain", "panel"],
@@ -25711,6 +27169,12 @@ var systemBlockDefinitionsRaw = [
25711
27169
  family: "media-text",
25712
27170
  weight: "featured",
25713
27171
  bias: "soft"
27172
+ }),
27173
+ layoutProfile({
27174
+ variantKey: "bio",
27175
+ family: "media-text",
27176
+ weight: "featured",
27177
+ bias: "soft"
25714
27178
  })
25715
27179
  ]
25716
27180
  })),
@@ -26470,8 +27934,8 @@ async function getJsonFromAiText(ai, config, userMessage, schema) {
26470
27934
  let json;
26471
27935
  try {
26472
27936
  json = JSON.parse(textToParse);
26473
- } catch (err) {
26474
- const msg = err instanceof Error ? err.message : String(err);
27937
+ } catch (err2) {
27938
+ const msg = err2 instanceof Error ? err2.message : String(err2);
26475
27939
  throw new AiValidationError(`NON_JSON_RESPONSE: ${msg}`, rawText, null);
26476
27940
  }
26477
27941
  const result = schema.safeParse(json);
@@ -29550,7 +31014,7 @@ function sanitizeExtractedContent(content) {
29550
31014
  }
29551
31015
  return result;
29552
31016
  }
29553
- function isRecord4(value) {
31017
+ function isRecord6(value) {
29554
31018
  return typeof value === "object" && value !== null && !Array.isArray(value);
29555
31019
  }
29556
31020
  function isBoxStylesField(fieldId) {
@@ -29659,7 +31123,7 @@ async function populateBuiltinBlock(sectionIndex, section2, blockInfo, ctx) {
29659
31123
  await ctx.debug.writeText(`pass2-builtin-${sectionIndex}-raw.txt`, rawText);
29660
31124
  await ctx.debug.writeJson(`pass2-builtin-${sectionIndex}-output.json`, result);
29661
31125
  const rawContent = result.content;
29662
- const sanitizedContent = isRecord4(rawContent) ? sanitizeExtractedContent(rawContent) : {};
31126
+ const sanitizedContent = isRecord6(rawContent) ? sanitizeExtractedContent(rawContent) : {};
29663
31127
  return {
29664
31128
  success: true,
29665
31129
  block: {