@riverbankcms/sdk 0.109.0 → 0.118.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/dist/{PreviewEditorSidebar-DWqwfy3_.mjs → PreviewEditorSidebar-BBcK1DjD.mjs} +178 -117
  2. package/dist/{PreviewEditorUI-B7OL4sfR.mjs → PreviewEditorUI-CuBFoYes.mjs} +3 -4
  3. package/dist/{PreviewQueryProvider-D0y2l8JN.mjs → PreviewQueryProvider-nKUT4TL-.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-D8Gt9Gbe.mjs → SdkPreviewModeRuntime-BWIO_Dsi.mjs} +2789 -34525
  5. package/dist/{SiteChromeCustomizeContext-DUpalEdL.mjs → SiteChromeCustomizeContext-CciG60M5.mjs} +88526 -57212
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +6939 -727
  7. package/dist/_dts/ai/src/designer/themePatch.d.ts +1 -1
  8. package/dist/_dts/api/src/bookingAdjustments.d.ts +30 -36
  9. package/dist/_dts/api/src/bookingRecords.d.ts +6 -74
  10. package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +3 -3
  11. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +5 -5
  12. package/dist/_dts/api/src/contentRuntime.d.ts +9 -2
  13. package/dist/_dts/api/src/courses.d.ts +30 -15
  14. package/dist/_dts/api/src/customerMembershipOutcomes.d.ts +4 -4
  15. package/dist/_dts/api/src/endpoints.d.ts +49 -4
  16. package/dist/_dts/api/src/event-presentation.d.ts +4 -0
  17. package/dist/_dts/api/src/index.d.ts +3 -3
  18. package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +2 -2
  19. package/dist/_dts/api/src/sdk-event-upsert.d.ts +2 -2
  20. package/dist/_dts/api/src/sdkContracts.d.ts +108 -18
  21. package/dist/_dts/api/src/siteBanner.d.ts +8 -8
  22. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -1
  23. package/dist/_dts/api/src/siteOperations.d.ts +12 -20
  24. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +32 -4
  25. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +6 -6
  26. package/dist/_dts/api/src/webhooks.d.ts +98 -1
  27. package/dist/_dts/billing/src/site-arrangements.d.ts +3 -0
  28. package/dist/_dts/block-form/src/widgets/RichTextField/richTextFieldDefaults.d.ts +3 -12
  29. package/dist/_dts/block-form/src/widgets/RichTextField/richTextFieldSchema.d.ts +1 -5
  30. package/dist/_dts/blocks/src/bindings/index.d.ts +1 -10
  31. package/dist/_dts/blocks/src/client/course-registration.d.ts +4 -1
  32. package/dist/_dts/blocks/src/client.d.ts +4 -1
  33. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -4
  34. package/dist/_dts/blocks/src/index.d.ts +6 -7
  35. package/dist/_dts/blocks/src/primitives/content/primitives.d.ts +2 -2
  36. package/dist/_dts/blocks/src/system/blocks/body-text.d.ts +2 -2
  37. package/dist/_dts/blocks/src/system/blocks/course-registration.d.ts +2 -1
  38. package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +2 -1
  39. package/dist/_dts/blocks/src/system/blocks/cta-full.d.ts +2 -4
  40. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +2 -1
  41. package/dist/_dts/blocks/src/system/blocks/events/event-listing.d.ts +2 -1
  42. package/dist/_dts/blocks/src/system/blocks/events/event-spotlight.d.ts +2 -1
  43. package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule.d.ts +5 -4
  44. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +2 -8
  45. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +2 -1
  46. package/dist/_dts/blocks/src/system/blocks/feature-card-icons.d.ts +2 -2
  47. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +3 -3
  48. package/dist/_dts/blocks/src/system/blocks/file-download.d.ts +2 -1
  49. package/dist/_dts/blocks/src/system/blocks/form.d.ts +2 -15
  50. package/dist/_dts/blocks/src/system/blocks/intro.d.ts +2 -2
  51. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +66 -66
  52. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +4 -17
  53. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +2 -1
  54. package/dist/_dts/blocks/src/system/blocks/single-button.d.ts +2 -1
  55. package/dist/_dts/blocks/src/system/blocks/site-footer.d.ts +0 -3
  56. package/dist/_dts/blocks/src/system/constants/buttonRoles.d.ts +35 -0
  57. package/dist/_dts/blocks/src/system/fields/button.d.ts +10 -21
  58. package/dist/_dts/blocks/src/system/fields/ctas.d.ts +2 -1
  59. package/dist/_dts/blocks/src/system/fragments/index.d.ts +0 -1
  60. package/dist/_dts/blocks/src/system/fragments/library/heroCtaRow.d.ts +9 -5
  61. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +19 -2
  62. package/dist/_dts/blocks/src/system/manifest/richTextSchema.d.ts +8 -70
  63. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +1 -0
  64. package/dist/_dts/blocks/src/system/manifest/validation.d.ts +6 -0
  65. package/dist/_dts/blocks/src/system/node/schema.d.ts +4 -4
  66. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +18 -18
  67. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +9 -9
  68. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessWholeSeriesRegistrationFlow.d.ts +29 -0
  69. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +1 -10
  70. package/dist/_dts/blocks/src/system/runtime/nodes/buttonAffordance.d.ts +5 -21
  71. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/ErrorStep.d.ts +2 -1
  72. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/PaymentFailedStep.d.ts +2 -1
  73. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/VerifyingTimeoutStep.d.ts +2 -1
  74. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/types.d.ts +21 -0
  75. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +4 -4
  76. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/whole-series-registration.headless.contract.d.ts +326 -0
  77. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/whole-series-registration.headless.planning.d.ts +27 -0
  78. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.interactive.d.ts +5 -4
  79. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +3 -2
  80. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +2 -1
  81. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +5 -4
  82. package/dist/_dts/blocks/src/system/runtime/nodes/file-download.d.ts +2 -3
  83. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +2 -1
  84. package/dist/_dts/blocks/src/system/runtime/nodes/richText-coerce.d.ts +14 -2
  85. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +6 -3
  86. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +7 -6
  87. package/dist/_dts/blocks/src/system/runtime/nodes/shop.types.d.ts +2 -1
  88. package/dist/_dts/blocks/src/system/runtime/shared/types.d.ts +2 -1
  89. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +1 -1
  90. package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +4 -2
  91. package/dist/_dts/content-editor/src/controller/seedDraftBaselinesFromBlocks.d.ts +1 -1
  92. package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +17 -1
  93. package/dist/_dts/content-editor/src/hooks/useDebouncedLatestSave.d.ts +1 -1
  94. package/dist/_dts/content-editor/src/hooks/useSimpleAutosave.d.ts +1 -1
  95. package/dist/_dts/content-editor/src/index.d.ts +12 -12
  96. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +3 -2
  97. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +19 -4
  98. package/dist/_dts/content-editor/src/ui/stores/autosaveStore.d.ts +1 -1
  99. package/dist/_dts/content-editor/src/ui/stores/types.d.ts +1 -1
  100. package/dist/_dts/content-model/src/content-types/builtins.d.ts +3 -15
  101. package/dist/_dts/content-model/src/content-types/entryValidation.d.ts +2 -0
  102. package/dist/_dts/content-model/src/content-types/schema.d.ts +1 -1
  103. package/dist/_dts/content-model/src/templates/defaults.d.ts +1 -21
  104. package/dist/_dts/core/src/editor-state.d.ts +14 -1
  105. package/dist/_dts/core/src/footer-composition.d.ts +2 -1
  106. package/dist/_dts/core/src/index.d.ts +1 -0
  107. package/dist/_dts/core/src/rich-text.d.ts +16 -0
  108. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +367 -69
  109. package/dist/_dts/editor/src/index.d.ts +1 -1
  110. package/dist/_dts/editor/src/primitives/rich-text/utils.d.ts +3 -5
  111. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +1 -1
  112. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +2 -1
  113. package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +2 -1
  114. package/dist/_dts/editor-blocks/src/block-editor/blockDraftBaselineSeed.d.ts +15 -0
  115. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockBaselineSync.d.ts +3 -7
  116. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +12 -0
  117. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +1 -0
  118. package/dist/_dts/editor-blocks/src/block-editor/utils.d.ts +1 -1
  119. package/dist/_dts/editor-blocks/src/index.d.ts +6 -5
  120. package/dist/_dts/editor-blocks/src/widgets/button/context.d.ts +3 -2
  121. package/dist/_dts/editor-blocks/src/widgets/rich-text/RichTextField.d.ts +2 -2
  122. package/dist/_dts/media-core/src/contentMediaAudit.d.ts +104 -0
  123. package/dist/_dts/media-core/src/contentMediaAuditFieldAdapter.d.ts +8 -0
  124. package/dist/_dts/media-core/src/contentMediaSnapshotAudit.d.ts +22 -0
  125. package/dist/_dts/media-core/src/index.d.ts +3 -1
  126. package/dist/_dts/preview-next/src/client/index.d.ts +3 -2
  127. package/dist/_dts/preview-next/src/client/preview/ButtonStylePicker.d.ts +16 -0
  128. package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -3
  129. package/dist/_dts/preview-next/src/client/preview/PreviewDesignOpenRequestContext.d.ts +7 -0
  130. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +5 -11
  131. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +5 -6
  132. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +6 -7
  133. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +7 -9
  134. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.d.ts +4 -11
  135. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +7 -7
  136. package/dist/_dts/preview-next/src/client/preview/sidebarTabPreference.d.ts +0 -8
  137. package/dist/_dts/preview-next/src/client/preview/siteChromeLookRows.d.ts +1 -11
  138. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +1 -5
  139. package/dist/_dts/preview-next/src/client/preview/siteChromeSavePlan.d.ts +2 -3
  140. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +3 -4
  141. package/dist/_dts/preview-next/src/client/preview/styleConfiguratorSnapshot.d.ts +3 -5
  142. package/dist/_dts/sdk/src/bookings/index.d.ts +5 -4
  143. package/dist/_dts/sdk/src/bookings/types.d.ts +3 -3
  144. package/dist/_dts/sdk/src/cli/commands/event.d.ts +18 -1
  145. package/dist/_dts/sdk/src/cli/commands/push/execute/theme.d.ts +2 -16
  146. package/dist/_dts/sdk/src/cli/commands/style.d.ts +3 -2
  147. package/dist/_dts/sdk/src/cli/content/reader.d.ts +8 -5
  148. package/dist/_dts/sdk/src/client/management/events.d.ts +2 -1
  149. package/dist/_dts/sdk/src/client/management/index.d.ts +1 -1
  150. package/dist/_dts/sdk/src/client/management/types.d.ts +38 -10
  151. package/dist/_dts/sdk/src/config/typed-entries.d.ts +7 -7
  152. package/dist/_dts/sdk/src/config/validation.d.ts +7 -7
  153. package/dist/_dts/sdk/src/contracts/content.d.ts +5 -15
  154. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  155. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +24 -40
  156. package/dist/_dts/sdk/src/contracts/theme.d.ts +2 -18
  157. package/dist/_dts/sdk/src/manifest/passes/pass1-fields.d.ts +1 -1
  158. package/dist/_dts/sdk/src/manifest/three-pass-converter.d.ts +4 -4
  159. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -1
  160. package/dist/_dts/sdk/src/rendering/helpers/bindings.d.ts +1 -2
  161. package/dist/_dts/sdk/src/rendering/helpers/index.d.ts +1 -1
  162. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +2 -13
  163. package/dist/_dts/sdk/src/theme/index.d.ts +0 -29
  164. package/dist/_dts/sdk/src/version.d.ts +1 -1
  165. package/dist/_dts/sdk/src/webhooks/index.d.ts +1 -1
  166. package/dist/_dts/sdk/src/webhooks/verify.d.ts +3 -3
  167. package/dist/_dts/site-commands/src/commands.d.ts +160 -24
  168. package/dist/_dts/theme-core/src/buttons/affordanceIcons.d.ts +2 -2
  169. package/dist/_dts/theme-core/src/buttons/core.d.ts +0 -1
  170. package/dist/_dts/theme-core/src/buttons/effectClassification.d.ts +22 -9
  171. package/dist/_dts/theme-core/src/buttons/effects/presets/background.d.ts +1 -2
  172. package/dist/_dts/theme-core/src/buttons/effects/presets/border.d.ts +1 -2
  173. package/dist/_dts/theme-core/src/buttons/effects/presets/overlay.d.ts +3 -1
  174. package/dist/_dts/theme-core/src/buttons/effects/presets/shadow.d.ts +2 -2
  175. package/dist/_dts/theme-core/src/buttons/effects/types.d.ts +8 -18
  176. package/dist/_dts/theme-core/src/buttons/generateButtonCss.d.ts +2 -2
  177. package/dist/_dts/theme-core/src/buttons/generateDefaultButtonSystem.d.ts +5 -5
  178. package/dist/_dts/theme-core/src/buttons/index.d.ts +2 -5
  179. package/dist/_dts/theme-core/src/buttons/parseThemeForPersistence.d.ts +36 -0
  180. package/dist/_dts/theme-core/src/buttons/styles/domain.d.ts +80 -0
  181. package/dist/_dts/theme-core/src/buttons/styles/index.d.ts +3 -0
  182. package/dist/_dts/theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.d.ts +49 -0
  183. package/dist/_dts/theme-core/src/buttons/styles/recipes/quietArrow.d.ts +67 -0
  184. package/dist/_dts/theme-core/src/buttons/styles/recipes/staticRecipes.d.ts +649 -0
  185. package/dist/_dts/theme-core/src/buttons/styles/registry.d.ts +753 -0
  186. package/dist/_dts/theme-core/src/buttons/styles/selection.d.ts +69 -0
  187. package/dist/_dts/theme-core/src/buttons/types.d.ts +1638 -93
  188. package/dist/_dts/theme-core/src/cards/types.d.ts +13 -13
  189. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +969 -69
  190. package/dist/_dts/theme-core/src/navigation/types.d.ts +2 -2
  191. package/dist/_dts/theme-core/src/recommend/generateThemes.d.ts +0 -1
  192. package/dist/_dts/theme-core/src/schema.d.ts +1100 -116
  193. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  194. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +26 -24
  195. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +14 -14
  196. package/dist/_dts/theme-core/src/site-styles/footerLooks.d.ts +19 -153
  197. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +2 -2
  198. package/dist/_dts/theme-core/src/site-styles/headerCtaVariants.d.ts +3 -1
  199. package/dist/_dts/theme-core/src/site-styles/pageDesignIntent.d.ts +4 -4
  200. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +8 -9
  201. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +4 -4
  202. package/dist/_dts/ui/src/palette/hex.d.ts +3 -3
  203. package/dist/cli/index.mjs +7368 -6668
  204. package/dist/cli/init-docs/content/cli-reference.md +40 -1
  205. package/dist/cli/init-docs/content/content-management.md +6 -0
  206. package/dist/cli/init-docs/content/workflow-isr-revalidation.md +1 -1
  207. package/dist/client/{DiscountCodeDisclosure-DU1ygxU2.mjs → DiscountCodeDisclosure-DIWj-P9v.mjs} +1 -1
  208. package/dist/client/{EventCombined.client-DB5zagCo.mjs → EventCombined.client-De8YWBSr.mjs} +2 -3
  209. package/dist/client/{EventListing.client-CTX9JHBL.mjs → EventListing.client-seHTjimY.mjs} +2 -2
  210. package/dist/client/{LeafletStaticMap-BYImhgiB.mjs → LeafletStaticMap-BmQxFcJW.mjs} +1 -1
  211. package/dist/client/{MagicLinkForm-CRkw_M3l.mjs → MagicLinkForm-OoJAIUIj.mjs} +1 -2
  212. package/dist/client/{StepIndicator-BnmVBJJh.mjs → StepIndicator-CiZ8kdPk.mjs} +2 -2
  213. package/dist/client/{accordion-CeGreumd.mjs → accordion-6lnN__XJ.mjs} +1 -1
  214. package/dist/client/{bookingForm-CSzFNrpN.mjs → bookingForm-5uyqhONU.mjs} +6 -7
  215. package/dist/client/bookings.mjs +9179 -5865
  216. package/dist/client/{carousel-B2jDtogf.mjs → carousel-Dtnifil_.mjs} +1 -1
  217. package/dist/client/{cart-D-jZ-vaY.mjs → cart-5Tc5S7NV.mjs} +3 -3
  218. package/dist/client/{checkout-Dza-LA7N.mjs → checkout-CYKKN5Hr.mjs} +3 -3
  219. package/dist/client/client.mjs +3252 -3361
  220. package/dist/client/{colorTokenParts-CMugwvX_.mjs → colorStyles-BWpj_h4C.mjs} +118 -1
  221. package/dist/client/{courseRegistration-TYkNychb.mjs → courseRegistration-CxCBybB4.mjs} +100 -37
  222. package/dist/client/{eventCalendar-BI_90SsT.mjs → eventCalendar-Xj2jZS9X.mjs} +4 -5
  223. package/dist/client/{eventCombined-mNrpryE9.mjs → eventCombined-CgcMoOgM.mjs} +2 -2
  224. package/dist/client/{eventDetails-D4GVlCIY.mjs → eventDetails-CEAH8Edc.mjs} +3 -3
  225. package/dist/client/{eventListing-YhKN018y.mjs → eventListing-qyPVQ0wP.mjs} +2 -2
  226. package/dist/client/{eventRegistration-CdHGtilr.mjs → eventRegistration-DDu79CtL.mjs} +6 -7
  227. package/dist/client/{form-AcAL45rA.mjs → form-Bc7JKI7I.mjs} +1 -2
  228. package/dist/client/{headerSection-uEC52ueD.mjs → headerSection-vTku_LEl.mjs} +2 -3
  229. package/dist/client/hooks.mjs +1774 -2273
  230. package/dist/client/{locationMap-_wJDSUYe.mjs → locationMap-Bg7X4Jna.mjs} +8 -5
  231. package/dist/client/{media-BK0O3b-U.mjs → media-CNE1Z-wb.mjs} +1 -2
  232. package/dist/client/{newsletterForm-DrArsb2B.mjs → newsletterForm-lpylVdp5.mjs} +1 -2
  233. package/dist/client/{pricing-BSYVghwo.mjs → pricing-DE8fjJiT.mjs} +1 -1
  234. package/dist/client/{productDetail-Dyk90sMs.mjs → productDetail-D7Bo2RMH.mjs} +3 -3
  235. package/dist/client/{productList-BCKThwAI.mjs → productList-VjnZqiqN.mjs} +3 -3
  236. package/dist/client/{propsDecoder-CkXxkdSR.mjs → propsDecoder-DreFXjNP.mjs} +4256 -443
  237. package/dist/client/rendering/client.mjs +21776 -21970
  238. package/dist/client/rendering/islands.mjs +20 -20
  239. package/dist/client/rendering.mjs +3092 -3322
  240. package/dist/client/{shop-DeltVH10.mjs → shop-IRsHHbf7.mjs} +5 -6
  241. package/dist/client/{shop-commerce-BD9Jsm2Z.mjs → shop-commerce-gnI8PieZ.mjs} +27 -11
  242. package/dist/client/{shop-commerce-store-CmXD6FDS.mjs → shop-commerce-store-BTbrhObn.mjs} +1 -1
  243. package/dist/client/{shopShared-B8v-lH_F.mjs → shopShared-D6KS2_qk.mjs} +3 -3
  244. package/dist/client/{useDiscountCodeUi-DbWJN8ld.mjs → useDiscountCodeUi-DCccGCxV.mjs} +1 -1
  245. package/dist/client/{useEventFilters-EJIMUnqT.mjs → useEventFilters-eGs3rPZQ.mjs} +24 -126
  246. package/dist/client/{usePolling-Cmh14fc7.mjs → usePolling-CvSU2sur.mjs} +2 -2
  247. package/dist/preview-next/before-render.mjs +94 -6
  248. package/dist/preview-next/client/runtime.mjs +4 -4
  249. package/dist/preview-next/middleware.mjs +94 -6
  250. package/dist/{previewAuthStore-CTO7CRPk.mjs → previewAuthStore-DN7vcRsv.mjs} +94 -6
  251. package/dist/{sdk-runtime-Dou0GAav.mjs → sdk-runtime-vW8QbyPN.mjs} +2 -2
  252. package/dist/{separator-CI5wZNXT.mjs → separator-DJ4bkeY3.mjs} +1 -1
  253. package/dist/server/components.mjs +5194 -5568
  254. package/dist/server/config-template-validation.mjs +4 -23
  255. package/dist/server/config-validation.mjs +1774 -2273
  256. package/dist/server/config.mjs +2043 -2508
  257. package/dist/server/data.mjs +1774 -2273
  258. package/dist/server/index.mjs +95 -7
  259. package/dist/server/next/revalidate.mjs +53 -1
  260. package/dist/server/next.mjs +5337 -5632
  261. package/dist/server/page-converter.mjs +1833 -2307
  262. package/dist/server/prebuild.mjs +1 -1
  263. package/dist/server/rendering/server.mjs +6713 -4874
  264. package/dist/server/rendering.mjs +5203 -5586
  265. package/dist/server/routing.mjs +2199 -2698
  266. package/dist/server/server.mjs +1885 -2355
  267. package/dist/server/theme-bridge.mjs +1986 -2222
  268. package/dist/server/theme.mjs +2367 -1581
  269. package/dist/server/webhooks.mjs +54 -2
  270. package/package.json +1 -1
  271. package/dist/_dts/blocks/src/primitives/content/components/Button.d.ts +0 -40
  272. package/dist/_dts/blocks/src/system/fragments/library/footerBottomText.d.ts +0 -19
  273. package/dist/_dts/media-core/src/legacyMediaValue.d.ts +0 -11
  274. package/dist/_dts/theme-core/src/buttons/personalities/brushed-wash.d.ts +0 -16
  275. package/dist/_dts/theme-core/src/buttons/personalities/confident-chip.d.ts +0 -16
  276. package/dist/_dts/theme-core/src/buttons/personalities/earth-pill.d.ts +0 -16
  277. package/dist/_dts/theme-core/src/buttons/personalities/editorial-link.d.ts +0 -16
  278. package/dist/_dts/theme-core/src/buttons/personalities/flat-ink.d.ts +0 -20
  279. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +0 -172
  280. package/dist/_dts/theme-core/src/buttons/personalities/ink-stamp.d.ts +0 -16
  281. package/dist/_dts/theme-core/src/buttons/personalities/joy-stamp.d.ts +0 -22
  282. package/dist/_dts/theme-core/src/buttons/personalities/ornate-ritual.d.ts +0 -16
  283. package/dist/_dts/theme-core/src/buttons/personalities/pebble.d.ts +0 -16
  284. package/dist/_dts/theme-core/src/buttons/personalities/quiet-arrow.d.ts +0 -17
  285. package/dist/_dts/theme-core/src/buttons/personalities/showtime-pill.d.ts +0 -17
  286. package/dist/_dts/theme-core/src/buttons/personalities/soft-pill.d.ts +0 -16
  287. package/dist/_dts/theme-core/src/buttons/personalities/two-tone-pill.d.ts +0 -17
  288. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +0 -285
  289. package/dist/_dts/theme-core/src/styles/buttons.d.ts +0 -27
  290. package/dist/_dts/theme-core/src/styles/buttonsLibrary.d.ts +0 -2
  291. package/dist/_dts/theme-core/src/styles/glow.d.ts +0 -3
  292. package/dist/client/buttons-DoFV7KDL.mjs +0 -2115
  293. package/dist/client/colorStyles-CrgzoXsm.mjs +0 -99
  294. package/dist/client/foregroundContract-xICPq59x.mjs +0 -31
@@ -1,4 +1,4 @@
1
- import { a as parseEventOfferingId, g as ok$1, h as err$1, o as parseEventSeriesId, r as parseAspectRatioValue, t as parseColorTokenParts } from "./colorTokenParts-CMugwvX_.mjs";
1
+ import { a as parseColorTokenParts, b as ok$1, l as parseEventOfferingId, r as rgbColorValue, s as parseAspectRatioValue, u as parseEventSeriesId, y as err$1 } from "./colorStyles-BWpj_h4C.mjs";
2
2
  import z, { z as z$1 } from "zod";
3
3
  //#region ../core/src/assert-never.ts
4
4
  function assertNever$2(value, message = "Unexpected variant") {
@@ -1498,214 +1498,6 @@ function isEventContentType(slug) {
1498
1498
  return EVENT_CONTENT_TYPE_SLUGS.includes(slug);
1499
1499
  }
1500
1500
  //#endregion
1501
- //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
1502
- const previewStageSchema = z$1.enum(["preview", "published"]);
1503
- const registrationButtonVariantSchema = z$1.enum([
1504
- "primary",
1505
- "secondary",
1506
- "outline"
1507
- ]);
1508
- const eventButtonVariantSchema = z$1.enum([
1509
- "primary",
1510
- "secondary",
1511
- "outline",
1512
- "link"
1513
- ]);
1514
- const eventLayoutSchema = z$1.enum(eventCalendarListLayoutValues);
1515
- const eventCalendarDisplayModeSchema = z$1.enum(eventCalendarDisplayModeValues);
1516
- const eventCalendarDefaultViewSchema = z$1.enum(eventCalendarDefaultViewValues);
1517
- const columnOptionSchema = z$1.enum([
1518
- "2",
1519
- "3",
1520
- "4"
1521
- ]);
1522
- const weekStartSchema = z$1.enum(["sunday", "monday"]);
1523
- const filterAutoShowSchema = z$1.enum([
1524
- "auto",
1525
- "always",
1526
- "never"
1527
- ]);
1528
- const calendarTabViewsSchema = z$1.enum([
1529
- "both",
1530
- "month",
1531
- "week"
1532
- ]);
1533
- const unsupportedEventRegistrationPageSurfaceSubjectSchema = z$1.object({
1534
- kind: z$1.literal("unsupported"),
1535
- reason: z$1.enum([
1536
- "unsupportedSubject",
1537
- "invalidEventSeriesId",
1538
- "invalidEventOfferingId"
1539
- ])
1540
- });
1541
- const eventRegistrationPageSurfaceSubjectSchema = z$1.unknown().transform((value, ctx) => {
1542
- const unsupported = unsupportedEventRegistrationPageSurfaceSubjectSchema.safeParse(value);
1543
- if (unsupported.success) return unsupported.data;
1544
- const parsed = parseEventPageSurfaceSubject(value);
1545
- if (parsed.ok) return parsed.value;
1546
- ctx.addIssue({
1547
- code: z$1.ZodIssueCode.custom,
1548
- message: `Invalid event page-surface subject (${parsed.error.kind})`
1549
- });
1550
- return z$1.NEVER;
1551
- });
1552
- function resolveEventRegistrationScope(context) {
1553
- const occurrenceSeriesId = context.occurrenceContext?.seriesId;
1554
- if (occurrenceSeriesId) return {
1555
- kind: "occurrenceSeries",
1556
- seriesId: occurrenceSeriesId
1557
- };
1558
- if (context.subject?.kind === "eventSeries") return {
1559
- kind: "pageSurfaceSeries",
1560
- seriesId: context.subject.eventSeriesId
1561
- };
1562
- if (context.subject?.kind === "eventOffering") return {
1563
- kind: "pageSurfaceOffering",
1564
- offeringId: context.subject.eventOfferingId,
1565
- seriesIds: context.subject.availableEventSeriesIds
1566
- };
1567
- if (context.subject?.kind === "unsupported") return {
1568
- kind: "unsupportedPageSurfaceSubject",
1569
- reason: context.subject.reason
1570
- };
1571
- const entrySlug = context.contentEntry?.slug;
1572
- const entryContentType = context.contentEntry?.contentTypeSlug;
1573
- if (entrySlug && entryContentType && isEventContentType(entryContentType)) return {
1574
- kind: "legacyEventSlug",
1575
- slug: entrySlug
1576
- };
1577
- return { kind: "unscoped" };
1578
- }
1579
- function applyEventRegistrationScope(events, scope) {
1580
- switch (scope.kind) {
1581
- case "occurrenceSeries":
1582
- case "pageSurfaceSeries": return events.filter((event) => event.seriesId === scope.seriesId);
1583
- case "pageSurfaceOffering": {
1584
- const seriesIds = new Set(scope.seriesIds);
1585
- return events.filter((event) => seriesIds.has(event.seriesId));
1586
- }
1587
- case "legacyEventSlug": return events.filter((event) => event.slug === scope.slug);
1588
- case "unsupportedPageSurfaceSubject": return [];
1589
- case "unscoped": return [...events];
1590
- }
1591
- }
1592
- function resolveEventRegistrationScopedEvents(events, context) {
1593
- return applyEventRegistrationScope(events, resolveEventRegistrationScope(context));
1594
- }
1595
- //#endregion
1596
- //#region ../blocks/src/system/runtime/nodes/course-registration.interactive.ts
1597
- const contentEntrySchema$2 = z$1.object({
1598
- id: z$1.string(),
1599
- slug: z$1.string(),
1600
- contentTypeSlug: z$1.string()
1601
- });
1602
- const courseEntrySubrouteContextSchema = z$1.union([z$1.object({
1603
- kind: z$1.literal("course-run"),
1604
- run: z$1.object({
1605
- courseId: z$1.string(),
1606
- seriesId: z$1.string(),
1607
- runSlug: z$1.string(),
1608
- runName: z$1.string().nullable()
1609
- })
1610
- }), z$1.object({
1611
- kind: z$1.literal("event-occurrence"),
1612
- occurrence: occurrenceContextSchema$1
1613
- })]);
1614
- const courseRegistrationSourceSchema = z$1.object({
1615
- siteId: z$1.string().optional(),
1616
- apiBaseUrl: z$1.string().optional(),
1617
- portalToken: z$1.string().nullable().optional(),
1618
- contentEntry: contentEntrySchema$2.nullable().optional(),
1619
- entrySubrouteContext: courseEntrySubrouteContextSchema.nullable().optional(),
1620
- subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
1621
- courses: z$1.array(publicCourseSchema).nullable().optional(),
1622
- className: z$1.string().nullable().optional(),
1623
- showSessions: z$1.boolean().optional(),
1624
- showPrice: z$1.boolean().optional(),
1625
- showCapacity: z$1.boolean().optional(),
1626
- showVenue: z$1.boolean().optional(),
1627
- successMessage: z$1.string().optional(),
1628
- waitlistMessage: z$1.string().optional(),
1629
- membershipMessage: z$1.string().optional(),
1630
- buttonText: z$1.string().nullable().optional(),
1631
- buttonVariant: registrationButtonVariantSchema.optional(),
1632
- stage: previewStageSchema.optional()
1633
- });
1634
- const courseRegistrationDisplaySchema = z$1.object({
1635
- kind: z$1.literal("course-registration"),
1636
- state: z$1.literal("shell"),
1637
- className: z$1.string().nullable(),
1638
- summaryButtonText: z$1.string()
1639
- });
1640
- const courseRegistrationHydrationSchema = z$1.object({
1641
- contentEntry: contentEntrySchema$2.nullable().optional(),
1642
- entrySubrouteContext: courseEntrySubrouteContextSchema.nullable().optional(),
1643
- subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
1644
- courses: z$1.array(publicCourseSchema).nullable().optional(),
1645
- showSessions: z$1.boolean().optional(),
1646
- showPrice: z$1.boolean().optional(),
1647
- showCapacity: z$1.boolean().optional(),
1648
- showVenue: z$1.boolean().optional(),
1649
- successMessage: z$1.string().optional(),
1650
- waitlistMessage: z$1.string().optional(),
1651
- membershipMessage: z$1.string().optional(),
1652
- buttonVariant: registrationButtonVariantSchema.optional()
1653
- });
1654
- const courseRegistrationRenderSchema = z$1.object({
1655
- display: courseRegistrationDisplaySchema,
1656
- hydration: courseRegistrationHydrationSchema
1657
- });
1658
- const courseRegistrationIslandMetaCodec = createZodCodec(z$1.object({
1659
- siteId: z$1.string().optional(),
1660
- apiBaseUrl: z$1.string().optional(),
1661
- portalToken: z$1.string().nullable().optional(),
1662
- stage: previewStageSchema.optional()
1663
- }));
1664
- const courseRegistrationIslandMetaKeys = defineInteractiveIslandMetaKeys("siteId", "apiBaseUrl", "portalToken", "stage");
1665
- function buildCourseRegistrationDisplay(source) {
1666
- return {
1667
- kind: "course-registration",
1668
- state: "shell",
1669
- className: source.className ?? null,
1670
- summaryButtonText: source.buttonText?.trim() || "Sign up"
1671
- };
1672
- }
1673
- const courseRegistrationInteractiveIslandPropsCodec = createInteractiveIslandCodec({
1674
- runtime: defineClientOwnedBlockRuntime({
1675
- kind: "client-owned",
1676
- contracts: {
1677
- source: createZodCodec(courseRegistrationSourceSchema),
1678
- render: createZodCodec(courseRegistrationRenderSchema)
1679
- },
1680
- buildRender: (source) => ({
1681
- display: buildCourseRegistrationDisplay(source),
1682
- hydration: {
1683
- contentEntry: source.contentEntry ?? null,
1684
- entrySubrouteContext: source.entrySubrouteContext ?? null,
1685
- subject: source.subject ?? null,
1686
- courses: source.courses ?? null,
1687
- showSessions: source.showSessions,
1688
- showPrice: source.showPrice,
1689
- showCapacity: source.showCapacity,
1690
- showVenue: source.showVenue,
1691
- successMessage: source.successMessage,
1692
- waitlistMessage: source.waitlistMessage,
1693
- membershipMessage: source.membershipMessage,
1694
- buttonVariant: source.buttonVariant
1695
- }
1696
- })
1697
- }),
1698
- mode: "course-registration",
1699
- meta: courseRegistrationIslandMetaCodec,
1700
- metaKeys: courseRegistrationIslandMetaKeys,
1701
- selectMeta: (value) => ({
1702
- siteId: value.siteId,
1703
- apiBaseUrl: value.apiBaseUrl,
1704
- portalToken: value.portalToken,
1705
- stage: value.stage
1706
- })
1707
- });
1708
- //#endregion
1709
1501
  //#region ../theme-core/src/tokens/blockColorTokens.ts
1710
1502
  const blockColorTokenNames = [
1711
1503
  "text",
@@ -1805,23 +1597,457 @@ function parseThemeColorToken(value) {
1805
1597
  }
1806
1598
  const themeColorTokenSchema = z$1.string().min(1).refine((value) => Boolean(isThemeColorToken(value)), "Expected a known Theme V2 color token");
1807
1599
  //#endregion
1808
- //#region ../theme-core/src/cards/types.ts
1809
- const cardVariantRoleValues = ["default", "alternative"];
1810
- const boxlessCardVariantValue = "none";
1811
- const legacyCardVariantRoleAliases = {
1812
- variant1: "alternative",
1813
- variant2: "alternative"
1814
- };
1815
- const cardSpacingSchema = z$1.enum([
1600
+ //#region ../theme-core/src/buttons/types.ts
1601
+ /**
1602
+ * Standard semantic variant roles a theme exposes.
1603
+ *
1604
+ * Block content references variants by role; the active theme determines
1605
+ * what each role looks like.
1606
+ */
1607
+ const VARIANT_ROLES = [
1608
+ "primary",
1609
+ "secondary",
1610
+ "outline",
1611
+ "ghost",
1612
+ "link",
1613
+ "tertiary",
1614
+ "accent"
1615
+ ];
1616
+ /**
1617
+ * Canonical persisted/CSS-safe button variant identifier.
1618
+ *
1619
+ * IDs become class selectors, so keep the contract deliberately narrower than
1620
+ * an arbitrary string and shared with every authoring/runtime boundary.
1621
+ */
1622
+ const buttonVariantIdSchema = z$1.string().min(1).max(50).regex(/^[a-z0-9-]+$/, "Button variant IDs may contain lowercase letters, numbers, and hyphens only");
1623
+ function parseOpaqueButtonColourToken(value) {
1624
+ const token = parseThemeColorToken(value);
1625
+ if (token === null) return null;
1626
+ const parts = parseColorTokenParts(token);
1627
+ return parts.kind === "token" && parts.opacityPercent === null ? token : null;
1628
+ }
1629
+ function unsafeAsOpaqueButtonColourToken(value) {
1630
+ return value;
1631
+ }
1632
+ const opaqueButtonColourTokenSchema = themeColorTokenSchema.refine((value) => parseOpaqueButtonColourToken(value) !== null, "Button colour tokens must be opaque").transform((value) => {
1633
+ const token = parseOpaqueButtonColourToken(value);
1634
+ if (token === null) throw new Error("Invariant: opaque button token passed its schema");
1635
+ return token;
1636
+ });
1637
+ const buttonShadeAmountSchema = z$1.number().finite().min(0).max(900).multipleOf(100);
1638
+ const buttonShadowIntensitySchema = z$1.enum([
1639
+ "subtle",
1640
+ "medium",
1641
+ "strong"
1642
+ ]);
1643
+ /**
1644
+ * The complete persisted button-effect contract.
1645
+ *
1646
+ * Navigation has its own generic interactive-effect model. Button variants use
1647
+ * this closed union so unsupported effect IDs, unknown option keys, and unsafe
1648
+ * CSS values cannot become representable after the schema boundary.
1649
+ */
1650
+ const buttonEffectApplicationSchema = z$1.discriminatedUnion("effectId", [
1651
+ z$1.strictObject({
1652
+ effectId: z$1.literal("darken-background"),
1653
+ options: z$1.strictObject({ amount: buttonShadeAmountSchema.optional() }).optional()
1654
+ }),
1655
+ z$1.strictObject({
1656
+ effectId: z$1.literal("lighten-background"),
1657
+ options: z$1.strictObject({ amount: buttonShadeAmountSchema.optional() }).optional()
1658
+ }),
1659
+ z$1.strictObject({
1660
+ effectId: z$1.literal("background-on-hover"),
1661
+ options: z$1.strictObject({ colorToken: opaqueButtonColourTokenSchema.optional() }).optional()
1662
+ }),
1663
+ z$1.strictObject({
1664
+ effectId: z$1.literal("animated-gradient"),
1665
+ options: z$1.strictObject({ direction: z$1.enum(["horizontal", "vertical"]).optional() }).optional()
1666
+ }),
1667
+ z$1.strictObject({
1668
+ effectId: z$1.literal("drop-shadow"),
1669
+ options: z$1.strictObject({ intensity: buttonShadowIntensitySchema.optional() }).optional()
1670
+ }),
1671
+ z$1.strictObject({
1672
+ effectId: z$1.literal("inner-shadow"),
1673
+ options: z$1.strictObject({}).optional()
1674
+ }),
1675
+ z$1.strictObject({
1676
+ effectId: z$1.literal("neumorphic-shadow"),
1677
+ options: z$1.strictObject({
1678
+ mode: z$1.enum(["raised", "pressed"]).optional(),
1679
+ intensity: buttonShadowIntensitySchema.optional()
1680
+ }).optional()
1681
+ }),
1682
+ z$1.strictObject({
1683
+ effectId: z$1.literal("retro-3d-shadow"),
1684
+ options: z$1.strictObject({}).optional()
1685
+ }),
1686
+ z$1.strictObject({
1687
+ effectId: z$1.literal("scale-up"),
1688
+ options: z$1.strictObject({ scale: z$1.enum([
1689
+ "1.02",
1690
+ "1.03",
1691
+ "1.05",
1692
+ "1.10"
1693
+ ]).optional() }).optional()
1694
+ }),
1695
+ z$1.strictObject({
1696
+ effectId: z$1.literal("scale-down"),
1697
+ options: z$1.strictObject({ scale: z$1.enum([
1698
+ "0.90",
1699
+ "0.95",
1700
+ "0.97",
1701
+ "0.98"
1702
+ ]).optional() }).optional()
1703
+ }),
1704
+ z$1.strictObject({
1705
+ effectId: z$1.literal("lift"),
1706
+ options: z$1.strictObject({ amount: z$1.enum([
1707
+ "0.25",
1708
+ "0.5",
1709
+ "1"
1710
+ ]).optional() }).optional()
1711
+ }),
1712
+ z$1.strictObject({
1713
+ effectId: z$1.literal("press-down"),
1714
+ options: z$1.strictObject({}).optional()
1715
+ }),
1716
+ z$1.strictObject({
1717
+ effectId: z$1.literal("pop"),
1718
+ options: z$1.strictObject({ intensity: z$1.enum([
1719
+ "subtle",
1720
+ "medium",
1721
+ "dramatic"
1722
+ ]).optional() }).optional()
1723
+ }),
1724
+ z$1.strictObject({
1725
+ effectId: z$1.literal("border-bottom-grow"),
1726
+ options: z$1.strictObject({
1727
+ height: z$1.union([z$1.literal(1), z$1.literal(2)]).optional(),
1728
+ origin: z$1.enum([
1729
+ "left",
1730
+ "center",
1731
+ "right"
1732
+ ]).optional()
1733
+ }).optional()
1734
+ }),
1735
+ z$1.strictObject({
1736
+ effectId: z$1.literal("sketchy-border"),
1737
+ options: z$1.strictObject({ intensity: buttonShadowIntensitySchema.optional() }).optional()
1738
+ })
1739
+ ]);
1740
+ const cornerStyleSchema = z$1.enum([
1741
+ "square",
1742
+ "rounded",
1743
+ "pill"
1744
+ ]);
1745
+ const shadowSizeSchema = z$1.enum([
1816
1746
  "none",
1817
- "compact",
1818
- "cozy",
1747
+ "low",
1819
1748
  "medium",
1820
- "comfortable",
1821
- "spacious"
1749
+ "high"
1822
1750
  ]);
1823
- const gradientDirectionSchema = z$1.enum([
1824
- "to-r",
1751
+ const textTransformSchema = z$1.enum([
1752
+ "none",
1753
+ "uppercase",
1754
+ "lowercase",
1755
+ "capitalize"
1756
+ ]);
1757
+ const fontWeightSchema = z$1.union([
1758
+ z$1.literal(500),
1759
+ z$1.literal(600),
1760
+ z$1.literal(700)
1761
+ ]);
1762
+ const buttonTypographySchema = z$1.enum(["body", "heading"]);
1763
+ const letterSpacingSchema = z$1.enum([
1764
+ "tight",
1765
+ "normal",
1766
+ "loose"
1767
+ ]);
1768
+ const hoverTransformSchema = z$1.enum([
1769
+ "none",
1770
+ "lift",
1771
+ "scale",
1772
+ "press"
1773
+ ]);
1774
+ z$1.enum(["none", "token"]);
1775
+ const buttonPaddingPresetSchema = z$1.enum([
1776
+ "compact",
1777
+ "default",
1778
+ "spacious"
1779
+ ]);
1780
+ const gradientStyleSchema = z$1.enum([
1781
+ "linear",
1782
+ "radial",
1783
+ "conic"
1784
+ ]);
1785
+ const gradientSharpnessSchema = z$1.enum([
1786
+ "smooth",
1787
+ "medium",
1788
+ "hard"
1789
+ ]);
1790
+ const prioritySchema = z$1.union([
1791
+ z$1.literal(1),
1792
+ z$1.literal(2),
1793
+ z$1.literal(3)
1794
+ ]);
1795
+ z$1.enum(VARIANT_ROLES);
1796
+ const buttonSizeNameSchema = z$1.enum([
1797
+ "sm",
1798
+ "md",
1799
+ "lg",
1800
+ "xl"
1801
+ ]);
1802
+ /**
1803
+ * CSS padding string in `"<vertical> <horizontal>"` shorthand form.
1804
+ *
1805
+ * Exactly two space-separated CSS length tokens. Each token is either the
1806
+ * literal `0` or a number followed by `rem`/`em`/`px`/`%`. This lets the
1807
+ * generator trust the shape rather than defensively defaulting downstream.
1808
+ */
1809
+ const PADDING_TOKEN_PATTERN = /^(?:0|\d+(?:\.\d+)?(?:rem|em|px|%))$/;
1810
+ const paddingShorthandSchema = z$1.string().refine((value) => {
1811
+ const parts = value.split(/\s+/).filter(Boolean);
1812
+ return parts.length === 2 && parts.every((token) => PADDING_TOKEN_PATTERN.test(token));
1813
+ }, { message: "Padding must be two space-separated CSS length tokens (e.g. \"0.5rem 1rem\"). Use `0` for zero." });
1814
+ const buttonSizeConfigSchema = z$1.object({
1815
+ padding: paddingShorthandSchema,
1816
+ fontSize: z$1.string().optional()
1817
+ });
1818
+ /**
1819
+ * `xl` is optional on the wire so themes persisted before the `xl` size was
1820
+ * added (e.g. SWTS) continue to parse. When `xl` is missing the schema
1821
+ * backfills it from `lg`, keeping `ButtonSizes` a complete `sm/md/lg/xl` map
1822
+ * downstream — generators never need to deal with an undefined `xl`.
1823
+ */
1824
+ const buttonSizesSchema = z$1.object({
1825
+ sm: buttonSizeConfigSchema,
1826
+ md: buttonSizeConfigSchema,
1827
+ lg: buttonSizeConfigSchema,
1828
+ xl: buttonSizeConfigSchema.optional()
1829
+ }).transform(({ sm, md, lg, xl }) => ({
1830
+ sm,
1831
+ md,
1832
+ lg,
1833
+ xl: xl ?? lg
1834
+ }));
1835
+ const buttonGlobalSettingsBaseSchema = z$1.strictObject({
1836
+ cornerStyle: cornerStyleSchema,
1837
+ cornerRadius: z$1.number().min(0).max(24).optional(),
1838
+ /**
1839
+ * Family-level shadow inherited by variants that don't set their own.
1840
+ * Optional and flat-by-default: when omitted, buttons carry no drop shadow
1841
+ * (`elevation: 'none'`). A personality opts the whole family into a shadow by
1842
+ * setting this; individual variants still override. There is no system-level
1843
+ * shadow-by-default — shadows only appear when explicitly declared.
1844
+ */
1845
+ shadow: shadowSizeSchema.optional(),
1846
+ textTransform: textTransformSchema,
1847
+ fontWeight: fontWeightSchema,
1848
+ typography: buttonTypographySchema.optional(),
1849
+ fontSize: z$1.string().optional(),
1850
+ letterSpacing: letterSpacingSchema.optional(),
1851
+ italic: z$1.boolean().optional(),
1852
+ paddingPreset: buttonPaddingPresetSchema.optional(),
1853
+ hoverTransform: hoverTransformSchema,
1854
+ gradientStyle: gradientStyleSchema.optional(),
1855
+ gradientAngle: z$1.number().min(0).max(360).optional(),
1856
+ gradientSharpness: gradientSharpnessSchema.optional()
1857
+ });
1858
+ const buttonGlobalSettingsSchema = z$1.discriminatedUnion("hoverColor", [buttonGlobalSettingsBaseSchema.extend({
1859
+ hoverColor: z$1.literal("none"),
1860
+ hoverColorToken: z$1.never().optional()
1861
+ }), buttonGlobalSettingsBaseSchema.extend({
1862
+ hoverColor: z$1.literal("token"),
1863
+ hoverColorToken: opaqueButtonColourTokenSchema
1864
+ })]);
1865
+ const gradientDirectionSchema$1 = z$1.enum([
1866
+ "to-r",
1867
+ "to-l",
1868
+ "to-t",
1869
+ "to-b",
1870
+ "to-tr",
1871
+ "to-tl",
1872
+ "to-br",
1873
+ "to-bl"
1874
+ ]);
1875
+ const buttonColourTreatmentSchema = z$1.discriminatedUnion("type", [
1876
+ z$1.strictObject({
1877
+ type: z$1.literal("solid"),
1878
+ colorToken: opaqueButtonColourTokenSchema
1879
+ }),
1880
+ z$1.strictObject({
1881
+ type: z$1.literal("gradient"),
1882
+ stops: z$1.array(opaqueButtonColourTokenSchema).min(2).transform((stops) => {
1883
+ const [first, second, ...rest] = stops;
1884
+ if (first === void 0 || second === void 0) throw new Error("Invariant: gradient stops passed the minimum length schema");
1885
+ return [
1886
+ first,
1887
+ second,
1888
+ ...rest
1889
+ ];
1890
+ }),
1891
+ direction: gradientDirectionSchema$1,
1892
+ foregroundToken: opaqueButtonColourTokenSchema
1893
+ }),
1894
+ z$1.strictObject({
1895
+ type: z$1.literal("surface"),
1896
+ role: z$1.literal("link")
1897
+ })
1898
+ ]);
1899
+ const buttonBackgroundSchema = buttonColourTreatmentSchema;
1900
+ const buttonBorderSchema = z$1.strictObject({ widthClass: z$1.string() });
1901
+ const buttonVariantAffordanceSchema = z$1.strictObject({ iconId: z$1.string().min(1) });
1902
+ const variantShadowSchema = z$1.strictObject({
1903
+ elevation: z$1.enum([
1904
+ "none",
1905
+ "low",
1906
+ "medium",
1907
+ "high"
1908
+ ]),
1909
+ softness: z$1.enum([
1910
+ "crisp",
1911
+ "soft",
1912
+ "hard"
1913
+ ]).nullable(),
1914
+ position: z$1.enum(["bottom", "bottom-right"]).default("bottom"),
1915
+ colorToken: opaqueButtonColourTokenSchema.optional()
1916
+ });
1917
+ const variantEffectsSchema = z$1.strictObject({
1918
+ base: z$1.array(buttonEffectApplicationSchema).optional(),
1919
+ hover: z$1.array(buttonEffectApplicationSchema).optional(),
1920
+ active: z$1.array(buttonEffectApplicationSchema).optional(),
1921
+ focus: z$1.array(buttonEffectApplicationSchema).optional()
1922
+ });
1923
+ /**
1924
+ * Per-variant size overrides schema — every entry is optional.
1925
+ *
1926
+ * For each size key present, the values override the theme's `sizes` config
1927
+ * for that size on this variant. Missing sizes fall through to theme.sizes,
1928
+ * then system defaults.
1929
+ */
1930
+ const variantSizeOverridesSchema = z$1.object({
1931
+ sm: buttonSizeConfigSchema.optional(),
1932
+ md: buttonSizeConfigSchema.optional(),
1933
+ lg: buttonSizeConfigSchema.optional(),
1934
+ xl: buttonSizeConfigSchema.optional()
1935
+ });
1936
+ /**
1937
+ * Unified variant schema. Every variant participates in the size system; the
1938
+ * optional `sizes` field lets a variant scale differently than the theme
1939
+ * default (e.g. link-style variants declaring zero horizontal padding at
1940
+ * every size).
1941
+ */
1942
+ const buttonVariantSchema = z$1.strictObject({
1943
+ id: buttonVariantIdSchema,
1944
+ name: z$1.string().min(1).max(20),
1945
+ enabled: z$1.boolean(),
1946
+ priority: prioritySchema,
1947
+ background: buttonBackgroundSchema,
1948
+ /** Tailwind radius token (e.g. `'rounded-md'`). Omit to inherit from `global.cornerStyle`. */
1949
+ borderRadius: z$1.string().optional(),
1950
+ shadow: variantShadowSchema.optional(),
1951
+ border: buttonBorderSchema.optional(),
1952
+ hoverBackgroundToken: opaqueButtonColourTokenSchema.optional(),
1953
+ effects: variantEffectsSchema.optional(),
1954
+ sizes: variantSizeOverridesSchema.optional(),
1955
+ affordance: buttonVariantAffordanceSchema.optional()
1956
+ });
1957
+ const buttonSystemSchema = z$1.strictObject({
1958
+ global: buttonGlobalSettingsSchema,
1959
+ variants: z$1.array(buttonVariantSchema).min(1).max(6),
1960
+ sizes: buttonSizesSchema.optional()
1961
+ }).superRefine((system, ctx) => {
1962
+ const seen = /* @__PURE__ */ new Set();
1963
+ system.variants.forEach((variant, index) => {
1964
+ if (seen.has(variant.id)) ctx.addIssue({
1965
+ code: "custom",
1966
+ path: [
1967
+ "variants",
1968
+ index,
1969
+ "id"
1970
+ ],
1971
+ message: `Duplicate button variant ID: ${variant.id}`
1972
+ });
1973
+ seen.add(variant.id);
1974
+ });
1975
+ });
1976
+ //#endregion
1977
+ //#region ../theme-core/src/lib/media.ts
1978
+ const hotspotSchema$1 = z.object({
1979
+ x: z.number().min(0).max(1),
1980
+ y: z.number().min(0).max(1),
1981
+ radius: z.number().optional()
1982
+ });
1983
+ const rotationSchema$1 = z.union([
1984
+ z.literal(0),
1985
+ z.literal(90),
1986
+ z.literal(180),
1987
+ z.literal(270)
1988
+ ]);
1989
+ const rectSchema$1 = z.tuple([
1990
+ z.number(),
1991
+ z.number(),
1992
+ z.number(),
1993
+ z.number()
1994
+ ]);
1995
+ const aspectCropSchema$1 = z.object({
1996
+ aspect: z.preprocess((value) => value == null ? void 0 : value, z.string().optional()),
1997
+ rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema$1.optional()),
1998
+ hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema$1.optional()),
1999
+ rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema$1.optional())
2000
+ });
2001
+ const transformSchema$1 = z.object({
2002
+ aspectCrops: z.preprocess((value) => {
2003
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
2004
+ return value;
2005
+ }, z.record(z.string(), aspectCropSchema$1.catch({}))).optional(),
2006
+ rect: rectSchema$1.optional(),
2007
+ hotspot: hotspotSchema$1.optional(),
2008
+ rotation: rotationSchema$1.optional()
2009
+ });
2010
+ const mediaSchema$1 = z.object({
2011
+ type: z.enum([
2012
+ "image",
2013
+ "video",
2014
+ "audio",
2015
+ "document",
2016
+ "spreadsheet",
2017
+ "archive"
2018
+ ]),
2019
+ purpose: z.string().optional(),
2020
+ placeholder: z.boolean().default(true).optional(),
2021
+ assetId: z.string().optional(),
2022
+ identifier: z.string().optional(),
2023
+ src: z.string().optional(),
2024
+ alt: z.string().optional(),
2025
+ filename: z.string().optional(),
2026
+ mimeType: z.string().optional(),
2027
+ width: z.number().optional(),
2028
+ height: z.number().optional(),
2029
+ storageBucket: z.string().optional(),
2030
+ storagePath: z.string().optional(),
2031
+ transform: transformSchema$1.optional()
2032
+ });
2033
+ //#endregion
2034
+ //#region ../theme-core/src/cards/types.ts
2035
+ const cardVariantRoleValues = ["default", "alternative"];
2036
+ const boxlessCardVariantValue = "none";
2037
+ const legacyCardVariantRoleAliases = {
2038
+ variant1: "alternative",
2039
+ variant2: "alternative"
2040
+ };
2041
+ const cardSpacingSchema = z$1.enum([
2042
+ "none",
2043
+ "compact",
2044
+ "cozy",
2045
+ "medium",
2046
+ "comfortable",
2047
+ "spacious"
2048
+ ]);
2049
+ const gradientDirectionSchema = z$1.enum([
2050
+ "to-r",
1825
2051
  "to-l",
1826
2052
  "to-t",
1827
2053
  "to-b",
@@ -1831,102 +2057,3772 @@ const gradientDirectionSchema = z$1.enum([
1831
2057
  "to-bl"
1832
2058
  ]);
1833
2059
  const cardVariantRoleSchema = z$1.enum(cardVariantRoleValues);
1834
- z$1.enum([...cardVariantRoleValues, boxlessCardVariantValue]);
2060
+ const boxStylesCardVariantSchema = z$1.enum([...cardVariantRoleValues, boxlessCardVariantValue]);
1835
2061
  function isCardVariantRole(value) {
1836
2062
  return typeof value === "string" && cardVariantRoleValues.includes(value);
1837
2063
  }
1838
- function normalizeCardVariantRole(value) {
1839
- if (isCardVariantRole(value)) return value;
1840
- if (typeof value !== "string") return null;
1841
- return legacyCardVariantRoleAliases[value] ?? null;
2064
+ function normalizeCardVariantRole(value) {
2065
+ if (isCardVariantRole(value)) return value;
2066
+ if (typeof value !== "string") return null;
2067
+ return legacyCardVariantRoleAliases[value] ?? null;
2068
+ }
2069
+ const cardBackgroundSchema = z$1.discriminatedUnion("type", [
2070
+ z$1.object({
2071
+ type: z$1.literal("solid"),
2072
+ colorToken: themeColorTokenSchema
2073
+ }),
2074
+ z$1.object({
2075
+ type: z$1.literal("gradient"),
2076
+ fromToken: themeColorTokenSchema,
2077
+ toToken: themeColorTokenSchema,
2078
+ direction: gradientDirectionSchema
2079
+ }),
2080
+ z$1.object({ type: z$1.literal("transparent") })
2081
+ ]);
2082
+ const cardBorderSchema = z$1.object({
2083
+ widthClass: z$1.string(),
2084
+ colorToken: themeColorTokenSchema
2085
+ });
2086
+ /** Per-corner radius value. `expressive` is a large block-radius multiple. */
2087
+ const cardCornerValueSchema = z$1.enum([
2088
+ "square",
2089
+ "soft",
2090
+ "rounded",
2091
+ "pill",
2092
+ "expressive"
2093
+ ]);
2094
+ /**
2095
+ * A single accented card edge (e.g. a left accent bar). When set, it replaces
2096
+ * the full `border` so the card reads as edge-accented rather than outlined.
2097
+ */
2098
+ const cardAccentEdgeSchema = z$1.object({
2099
+ edge: z$1.enum([
2100
+ "left",
2101
+ "top",
2102
+ "right",
2103
+ "bottom"
2104
+ ]),
2105
+ colorToken: themeColorTokenSchema,
2106
+ width: z$1.enum([
2107
+ "thin",
2108
+ "medium",
2109
+ "thick",
2110
+ "heavy"
2111
+ ])
2112
+ });
2113
+ const cardCornerRadiiSchema = z$1.object({
2114
+ topLeft: cardCornerValueSchema.optional(),
2115
+ topRight: cardCornerValueSchema.optional(),
2116
+ bottomLeft: cardCornerValueSchema.optional(),
2117
+ bottomRight: cardCornerValueSchema.optional()
2118
+ });
2119
+ const cardVariantSchema = z$1.object({
2120
+ id: z$1.string(),
2121
+ name: z$1.string().min(1).max(20),
2122
+ enabled: z$1.boolean(),
2123
+ priority: z$1.union([
2124
+ z$1.literal(1),
2125
+ z$1.literal(2),
2126
+ z$1.literal(3)
2127
+ ]),
2128
+ background: cardBackgroundSchema,
2129
+ spacing: cardSpacingSchema,
2130
+ foregroundToken: themeColorTokenSchema.optional(),
2131
+ shadow: z$1.object({
2132
+ elevation: z$1.enum([
2133
+ "none",
2134
+ "low",
2135
+ "medium",
2136
+ "high"
2137
+ ]),
2138
+ softness: z$1.enum([
2139
+ "crisp",
2140
+ "soft",
2141
+ "hard"
2142
+ ]).nullable(),
2143
+ position: z$1.enum(["bottom", "bottom-right"]).default("bottom")
2144
+ }).optional(),
2145
+ corners: z$1.enum([
2146
+ "square",
2147
+ "soft",
2148
+ "rounded",
2149
+ "pill"
2150
+ ]).optional(),
2151
+ cornerRadii: cardCornerRadiiSchema.optional(),
2152
+ border: cardBorderSchema.optional(),
2153
+ accentEdge: cardAccentEdgeSchema.optional()
2154
+ });
2155
+ const cardSystemSchema = z$1.object({ variants: z$1.array(cardVariantSchema).min(1).max(3) });
2156
+ //#endregion
2157
+ //#region ../theme-core/src/accordions/types.ts
2158
+ /**
2159
+ * Accordion icon styles for expand/collapse indicators
2160
+ */
2161
+ const accordionIconSchema = z$1.enum([
2162
+ "plus-minus",
2163
+ "chevron",
2164
+ "caret",
2165
+ "arrow",
2166
+ "circle-plus-minus"
2167
+ ]);
2168
+ /**
2169
+ * Accordion configuration for a theme
2170
+ * Single style per theme (no variants needed)
2171
+ */
2172
+ const accordionSystemSchema = z$1.object({
2173
+ background: z$1.object({
2174
+ type: z$1.literal("solid"),
2175
+ colorToken: themeColorTokenSchema
2176
+ }).nullable(),
2177
+ spacing: z$1.enum([
2178
+ "none",
2179
+ "compact",
2180
+ "cozy",
2181
+ "medium",
2182
+ "comfortable",
2183
+ "spacious"
2184
+ ]),
2185
+ corners: z$1.enum([
2186
+ "square",
2187
+ "soft",
2188
+ "rounded",
2189
+ "pill"
2190
+ ]).nullable(),
2191
+ border: z$1.object({
2192
+ widthClass: z$1.string(),
2193
+ colorToken: themeColorTokenSchema
2194
+ }).nullable(),
2195
+ shadow: z$1.object({
2196
+ elevation: z$1.enum([
2197
+ "none",
2198
+ "low",
2199
+ "medium",
2200
+ "high"
2201
+ ]),
2202
+ softness: z$1.enum([
2203
+ "soft",
2204
+ "crisp",
2205
+ "hard"
2206
+ ]).nullable(),
2207
+ position: z$1.enum(["bottom", "bottom-right"])
2208
+ }).nullable(),
2209
+ icon: z$1.object({
2210
+ style: accordionIconSchema,
2211
+ position: z$1.enum(["left", "right"]),
2212
+ size: z$1.enum([
2213
+ "sm",
2214
+ "md",
2215
+ "lg"
2216
+ ]),
2217
+ colorToken: themeColorTokenSchema.optional()
2218
+ }),
2219
+ trigger: z$1.object({
2220
+ textColorToken: themeColorTokenSchema,
2221
+ fontWeight: z$1.enum([
2222
+ "regular",
2223
+ "medium",
2224
+ "semibold",
2225
+ "bold"
2226
+ ]).nullable(),
2227
+ fontFamily: z$1.enum(["body", "heading"]).optional(),
2228
+ fontScale: z$1.enum([
2229
+ "body",
2230
+ "md",
2231
+ "lg"
2232
+ ]).optional(),
2233
+ letterSpacing: z$1.enum([
2234
+ "normal",
2235
+ "tight",
2236
+ "wide"
2237
+ ]).optional(),
2238
+ textTransform: z$1.enum(["none", "uppercase"]).optional()
2239
+ }),
2240
+ hover: z$1.object({
2241
+ backgroundColorToken: themeColorTokenSchema.optional(),
2242
+ textColorToken: themeColorTokenSchema.optional(),
2243
+ borderColorToken: themeColorTokenSchema.optional()
2244
+ }),
2245
+ openState: z$1.object({
2246
+ backgroundColorToken: themeColorTokenSchema.optional(),
2247
+ triggerColorToken: themeColorTokenSchema.optional(),
2248
+ accent: z$1.object({
2249
+ edge: z$1.enum([
2250
+ "left",
2251
+ "top",
2252
+ "bottom"
2253
+ ]),
2254
+ colorToken: themeColorTokenSchema,
2255
+ thickness: z$1.enum([
2256
+ "thin",
2257
+ "medium",
2258
+ "thick"
2259
+ ])
2260
+ }).optional()
2261
+ }).optional(),
2262
+ content: z$1.object({ textColorToken: themeColorTokenSchema })
2263
+ });
2264
+ //#endregion
2265
+ //#region ../theme-core/src/inputs/types.ts
2266
+ /**
2267
+ * Input styling configuration for a theme
2268
+ *
2269
+ * Provides comprehensive control over form input appearance including:
2270
+ * - Base styling (background, borders, spacing)
2271
+ * - Label styling
2272
+ * - Focus, error, and disabled states
2273
+ *
2274
+ * Single configuration per theme (no variants needed for inputs)
2275
+ */
2276
+ const inputSystemSchema = z$1.object({
2277
+ base: z$1.object({
2278
+ background: z$1.union([z$1.object({
2279
+ type: z$1.literal("solid"),
2280
+ colorToken: themeColorTokenSchema
2281
+ }), z$1.object({ type: z$1.literal("transparent") })]),
2282
+ textColorToken: themeColorTokenSchema,
2283
+ border: z$1.object({
2284
+ widthClass: z$1.string(),
2285
+ colorToken: themeColorTokenSchema,
2286
+ style: z$1.enum(["all", "underline"]).optional()
2287
+ }),
2288
+ corners: z$1.enum([
2289
+ "square",
2290
+ "soft",
2291
+ "rounded",
2292
+ "pill"
2293
+ ]).nullable(),
2294
+ shadow: z$1.object({
2295
+ elevation: z$1.enum([
2296
+ "none",
2297
+ "low",
2298
+ "medium"
2299
+ ]),
2300
+ softness: z$1.enum([
2301
+ "soft",
2302
+ "crisp",
2303
+ "hard"
2304
+ ]).nullable()
2305
+ }).nullable(),
2306
+ spacing: z$1.enum([
2307
+ "compact",
2308
+ "cozy",
2309
+ "medium",
2310
+ "comfortable"
2311
+ ]),
2312
+ fontSize: z$1.enum([
2313
+ "sm",
2314
+ "base",
2315
+ "lg"
2316
+ ])
2317
+ }),
2318
+ label: z$1.object({
2319
+ textColorToken: themeColorTokenSchema,
2320
+ fontWeight: z$1.enum([
2321
+ "regular",
2322
+ "medium",
2323
+ "semibold",
2324
+ "bold",
2325
+ "black"
2326
+ ]),
2327
+ fontSize: z$1.enum([
2328
+ "2xs",
2329
+ "xs",
2330
+ "sm",
2331
+ "base"
2332
+ ]),
2333
+ textTransform: z$1.enum([
2334
+ "none",
2335
+ "uppercase",
2336
+ "lowercase",
2337
+ "capitalize"
2338
+ ]).optional(),
2339
+ letterSpacing: z$1.enum([
2340
+ "normal",
2341
+ "wide",
2342
+ "wider",
2343
+ "widest"
2344
+ ]).optional(),
2345
+ opacity: z$1.number().min(.2).max(1).optional()
2346
+ }),
2347
+ focus: z$1.object({
2348
+ ringColorToken: themeColorTokenSchema,
2349
+ ringWidth: z$1.enum([
2350
+ "0",
2351
+ "1",
2352
+ "2",
2353
+ "3"
2354
+ ]),
2355
+ borderColorToken: themeColorTokenSchema.optional()
2356
+ }),
2357
+ error: z$1.object({
2358
+ borderColorToken: themeColorTokenSchema,
2359
+ textColorToken: themeColorTokenSchema
2360
+ }),
2361
+ disabled: z$1.object({
2362
+ backgroundColorToken: themeColorTokenSchema,
2363
+ textColorToken: themeColorTokenSchema,
2364
+ opacity: z$1.number().min(.3).max(.7)
2365
+ })
2366
+ });
2367
+ //#endregion
2368
+ //#region ../theme-core/src/gradients/types.ts
2369
+ /**
2370
+ * Gradient configuration types and schemas
2371
+ */
2372
+ /**
2373
+ * Gradient color stop
2374
+ */
2375
+ const gradientStopSchema = z$1.object({
2376
+ color: themeColorTokenSchema,
2377
+ position: z$1.number().min(0).max(100)
2378
+ });
2379
+ /**
2380
+ * Radial gradient shape. Optional; defaults to `circle` (the historical shape)
2381
+ * so existing radial gradients are byte-identical.
2382
+ *
2383
+ * Named `RadialGradientShape` to avoid clashing with `styles/gradients.ts`'s
2384
+ * `GradientShape` (which names the gradient *kind*: linear/radial/conic).
2385
+ */
2386
+ const radialGradientShapeSchema = z$1.enum(["circle", "ellipse"]);
2387
+ /**
2388
+ * Gradient configuration.
2389
+ *
2390
+ * `type` is optional and defaults to `'linear'` so gradients persisted without a
2391
+ * type (or with an explicit `'linear'`) render exactly as before. `'radial'` and
2392
+ * `'conic'` are additive kinds:
2393
+ * - linear: `angle` (degrees)
2394
+ * - radial: optional `shape` (circle/ellipse) + `position`
2395
+ * - conic: optional `angle` (from-angle, degrees) + `position`
2396
+ */
2397
+ const gradientConfigSchema = z$1.object({
2398
+ type: z$1.enum([
2399
+ "linear",
2400
+ "radial",
2401
+ "conic"
2402
+ ]).default("linear"),
2403
+ angle: z$1.number().min(0).max(360).optional(),
2404
+ shape: radialGradientShapeSchema.optional(),
2405
+ position: z$1.string().optional(),
2406
+ stops: z$1.array(gradientStopSchema).min(2)
2407
+ });
2408
+ //#endregion
2409
+ //#region ../theme-core/src/interactive/baseSchema.ts
2410
+ /**
2411
+ * Shared Base Schemas for Interactive Elements
2412
+ *
2413
+ * These Zod schemas are shared by buttons and nav links for DRY architecture.
2414
+ */
2415
+ /**
2416
+ * Typography settings shared by buttons and nav links
2417
+ */
2418
+ const interactiveTypographySchema = z$1.object({
2419
+ /** Font family source */
2420
+ typography: z$1.enum(["body", "heading"]).default("body"),
2421
+ /** Font weight */
2422
+ fontWeight: z$1.enum([
2423
+ "regular",
2424
+ "medium",
2425
+ "semibold",
2426
+ "bold"
2427
+ ]).default("medium"),
2428
+ /** Text transform */
2429
+ textTransform: z$1.enum([
2430
+ "none",
2431
+ "uppercase",
2432
+ "capitalize"
2433
+ ]).default("none"),
2434
+ /** Italic style */
2435
+ italic: z$1.boolean().default(false)
2436
+ });
2437
+ /**
2438
+ * Effect application reference (shared between buttons and nav)
2439
+ */
2440
+ const effectApplicationSchema = z$1.object({
2441
+ /** Effect preset ID */
2442
+ effectId: z$1.string(),
2443
+ /** User-provided customization options */
2444
+ options: z$1.record(z$1.string(), z$1.any()).optional()
2445
+ });
2446
+ /**
2447
+ * Effect composition by state (shared pattern)
2448
+ */
2449
+ const effectCompositionSchema = z$1.object({
2450
+ /** Effects always applied */
2451
+ base: z$1.array(effectApplicationSchema).optional(),
2452
+ /** Effects applied on hover */
2453
+ hover: z$1.array(effectApplicationSchema).optional(),
2454
+ /** Effects applied on active/pressed */
2455
+ active: z$1.array(effectApplicationSchema).optional(),
2456
+ /** Effects applied on focus */
2457
+ focus: z$1.array(effectApplicationSchema).optional()
2458
+ });
2459
+ //#endregion
2460
+ //#region ../theme-core/src/navigation/types.ts
2461
+ /**
2462
+ * Navigation Link Style Types
2463
+ *
2464
+ * Schema and types for composable nav link styling used by header and footer.
2465
+ */
2466
+ /**
2467
+ * Padding preset options for nav links
2468
+ */
2469
+ const navLinkPaddingSchema = z$1.enum([
2470
+ "none",
2471
+ "compact",
2472
+ "default"
2473
+ ]);
2474
+ /**
2475
+ * Horizontal padding override for nav links.
2476
+ * When set, overrides only the horizontal component of the `padding` preset.
2477
+ */
2478
+ const navLinkPaddingXSchema = z$1.enum([
2479
+ "none",
2480
+ "tight",
2481
+ "compact",
2482
+ "default",
2483
+ "relaxed",
2484
+ "spacious"
2485
+ ]);
2486
+ /**
2487
+ * Border radius options for nav links
2488
+ */
2489
+ const navLinkBorderRadiusSchema = z$1.enum([
2490
+ "none",
2491
+ "sm",
2492
+ "md",
2493
+ "full"
2494
+ ]);
2495
+ /**
2496
+ * Typography size options for nav links.
2497
+ */
2498
+ const navLinkTextSizeSchema = z$1.enum([
2499
+ "xs",
2500
+ "sm",
2501
+ "base",
2502
+ "lg",
2503
+ "xl"
2504
+ ]);
2505
+ /**
2506
+ * Letter spacing options for nav links.
2507
+ */
2508
+ const navLinkLetterSpacingSchema = z$1.enum([
2509
+ "normal",
2510
+ "wide",
2511
+ "wider",
2512
+ "widest"
2513
+ ]);
2514
+ /**
2515
+ * Optional legibility aid for nav text that floats over uncertain imagery or color.
2516
+ */
2517
+ const navLinkContrastTreatmentSchema = z$1.enum(["none", "soft-glow"]);
2518
+ /**
2519
+ * Nav link style schema
2520
+ *
2521
+ * Extends interactive typography base with nav-specific settings.
2522
+ */
2523
+ const navLinkStyleSchema = z$1.object({
2524
+ /** Display name for the style */
2525
+ name: z$1.string().min(1).max(30).optional(),
2526
+ /** Typography settings (inherited from interactive base) */
2527
+ ...interactiveTypographySchema.shape,
2528
+ /** Text color token */
2529
+ colorToken: themeColorTokenSchema.default("text"),
2530
+ /** Optional text size override */
2531
+ textSize: navLinkTextSizeSchema.optional(),
2532
+ /** Optional letter spacing override */
2533
+ letterSpacing: navLinkLetterSpacingSchema.optional(),
2534
+ /** Optional text-only contrast treatment for transparent/overlay navigation */
2535
+ contrastTreatment: navLinkContrastTreatmentSchema.optional(),
2536
+ /** Hover/active color token (for color-change effects) */
2537
+ hoverColorToken: themeColorTokenSchema.nullable().optional(),
2538
+ /** Padding preset */
2539
+ padding: navLinkPaddingSchema.default("compact"),
2540
+ /** Horizontal padding override (overrides horizontal component of padding preset) */
2541
+ paddingX: navLinkPaddingXSchema.optional(),
2542
+ /** Border radius (for capsule/pill styles) */
2543
+ borderRadius: navLinkBorderRadiusSchema.default("none"),
2544
+ /** Composable effects */
2545
+ effects: effectCompositionSchema.optional()
2546
+ });
2547
+ //#endregion
2548
+ //#region ../theme-core/src/customCss/validation.ts
2549
+ /**
2550
+ * Custom CSS Validation Schemas
2551
+ *
2552
+ * Zod schemas for validating custom CSS rules.
2553
+ * Enforces security constraints by construction.
2554
+ */
2555
+ /** Global selectors that could affect elements outside theme scope */
2556
+ const FORBIDDEN_SELECTORS = [
2557
+ ":root",
2558
+ "html",
2559
+ "body"
2560
+ ];
2561
+ /** Universal selector - forbidden because it affects everything */
2562
+ const UNIVERSAL_SELECTOR = "*";
2563
+ /** Pattern to detect remote URL references (http://, https://, //) */
2564
+ const REMOTE_URL_PATTERN = /url\s*\(\s*['"]?(https?:|\/\/)/i;
2565
+ /** Pattern to detect javascript: URLs */
2566
+ const JAVASCRIPT_URL_PATTERN = /javascript\s*:/i;
2567
+ /**
2568
+ * Check if a single selector part (no commas) is forbidden.
2569
+ */
2570
+ function isForbiddenSelectorPart(part) {
2571
+ const normalized = part.toLowerCase().trim();
2572
+ if (!normalized) return true;
2573
+ if (normalized === UNIVERSAL_SELECTOR || normalized.startsWith("* ") || normalized.endsWith(" *") || normalized.includes(" * ")) return true;
2574
+ for (const forbidden of FORBIDDEN_SELECTORS) {
2575
+ if (normalized === forbidden) return true;
2576
+ if (normalized.startsWith(forbidden + " ")) return true;
2577
+ if (normalized.startsWith(forbidden + ">")) return true;
2578
+ if (normalized.startsWith(forbidden + "+")) return true;
2579
+ if (normalized.startsWith(forbidden + "~")) return true;
2580
+ if (normalized.startsWith(forbidden + ".")) return true;
2581
+ if (normalized.startsWith(forbidden + "#")) return true;
2582
+ if (normalized.startsWith(forbidden + "[")) return true;
2583
+ if (normalized.startsWith(forbidden + ":") && !normalized.startsWith(forbidden + "::")) return true;
2584
+ }
2585
+ return false;
2586
+ }
2587
+ /**
2588
+ * Check if a selector uses sibling combinators with & that could escape scope.
2589
+ * Patterns like "& ~ .outside" or "& + .sibling" can select elements outside the scope.
2590
+ */
2591
+ function hasScopeEscapingSiblingCombinator(selector) {
2592
+ const normalized = selector.trim();
2593
+ return /&\s*[+~]/.test(normalized);
2594
+ }
2595
+ /**
2596
+ * Check if a selector contains forbidden global selectors.
2597
+ * Handles selectors like ":root", "html body", "body.class", "body, .x", etc.
2598
+ */
2599
+ function containsForbiddenSelector(selector) {
2600
+ const normalized = selector.toLowerCase().trim();
2601
+ if (!normalized) return true;
2602
+ if (hasScopeEscapingSiblingCombinator(selector)) return true;
2603
+ const parts = normalized.split(",");
2604
+ for (const part of parts) if (isForbiddenSelectorPart(part)) return true;
2605
+ return false;
2606
+ }
2607
+ /**
2608
+ * Validates a CSS selector for safety.
2609
+ */
2610
+ const selectorSchema = z$1.string().min(1, "Selector cannot be empty").max(200, "Selector too long (max 200 characters)").refine((s) => !containsForbiddenSelector(s), { message: "Global selectors (:root, html, body, *) are not allowed" });
2611
+ /**
2612
+ * Check if a CSS value contains a remote URL.
2613
+ */
2614
+ function containsRemoteUrl(value) {
2615
+ return REMOTE_URL_PATTERN.test(value);
2616
+ }
2617
+ /**
2618
+ * Check if a CSS value contains a javascript: URL.
2619
+ */
2620
+ function containsJavascriptUrl(value) {
2621
+ return JAVASCRIPT_URL_PATTERN.test(value);
2622
+ }
2623
+ /**
2624
+ * Validates a CSS declaration value for safety.
2625
+ * Allows: url(#id), url(data:...), url(/path), var(--)
2626
+ * Forbids: url(http...), url(//...), javascript:
2627
+ */
2628
+ const declarationValueSchema = z$1.string().max(500, "Declaration value too long (max 500 characters)").refine((v) => !containsRemoteUrl(v), { message: "Remote url() references are not allowed. Use local paths, data URIs, or fragment IDs." }).refine((v) => !containsJavascriptUrl(v), { message: "javascript: URLs are not allowed" });
2629
+ /**
2630
+ * Schema for CSS declarations object (property -> value map).
2631
+ */
2632
+ const declarationsSchema = z$1.record(z$1.string().min(1).max(100), declarationValueSchema);
2633
+ /**
2634
+ * Schema for a single custom CSS rule.
2635
+ */
2636
+ const customCssRuleSchema = z$1.object({
2637
+ id: z$1.string().min(1, "Rule ID is required").max(50, "Rule ID too long"),
2638
+ selector: selectorSchema,
2639
+ declarations: declarationsSchema
2640
+ });
2641
+ /**
2642
+ * Schema for block-specific CSS rule.
2643
+ */
2644
+ const blockCustomCssRuleSchema = customCssRuleSchema.extend({ blockKind: z$1.string().min(1, "Block kind is required").max(50, "Block kind too long") });
2645
+ /**
2646
+ * Array of custom CSS rules for theme-level styling.
2647
+ */
2648
+ const customCssRulesSchema = z$1.array(customCssRuleSchema).optional();
2649
+ /**
2650
+ * Array of block-specific CSS rules.
2651
+ */
2652
+ const blockCustomCssRulesSchema = z$1.array(blockCustomCssRuleSchema).optional();
2653
+ //#endregion
2654
+ //#region ../theme-core/src/customCss/atRuleValidation.ts
2655
+ /**
2656
+ * CSS At-Rule Validation Schemas
2657
+ *
2658
+ * Zod schemas for validating CSS at-rules.
2659
+ * Blocks @import for security.
2660
+ */
2661
+ /** Valid keyframe offset values - requires % for numeric values */
2662
+ const KEYFRAME_OFFSET_PATTERN = /^(from|to|\d{1,3}%)$/i;
2663
+ /** Valid animation name (CSS identifier) */
2664
+ const ANIMATION_NAME_PATTERN = /^[a-zA-Z_-][a-zA-Z0-9_-]*$/;
2665
+ /** Blocked at-rules in raw CSS */
2666
+ const BLOCKED_AT_RULES = ["@import", "@charset"];
2667
+ /** Pattern to detect blocked at-rules */
2668
+ const BLOCKED_AT_RULE_PATTERN = /@(?:import|charset)\b/i;
2669
+ /** Rule ID schema - reused from main validation */
2670
+ const ruleIdSchema = z$1.string().min(1, "Rule ID is required").max(50, "Rule ID too long");
2671
+ /** Nested rule schema for @media and @supports */
2672
+ const nestedRuleSchema = z$1.object({
2673
+ selector: selectorSchema,
2674
+ declarations: declarationsSchema
2675
+ });
2676
+ /**
2677
+ * Validate keyframe offset is in valid range (0-100%).
2678
+ * Returns true for 'from', 'to', or numeric values 0-100.
2679
+ */
2680
+ function isValidKeyframeOffset(offset) {
2681
+ const trimmed = offset.trim().toLowerCase();
2682
+ if (trimmed === "from" || trimmed === "to") return true;
2683
+ const match = trimmed.match(/^(\d{1,3})%$/);
2684
+ if (!match || match[1] === void 0) return false;
2685
+ const value = parseInt(match[1], 10);
2686
+ return value >= 0 && value <= 100;
2687
+ }
2688
+ /** Keyframe offset validation (0%, 50%, 100%, from, to) */
2689
+ const keyframeOffsetSchema = z$1.string().transform((offset) => offset.trim()).refine((offset) => KEYFRAME_OFFSET_PATTERN.test(offset), { message: "Invalid keyframe offset. Use percentages (0%, 50%, 100%) or \"from\"/\"to\"" }).refine(isValidKeyframeOffset, { message: "Keyframe offset must be between 0% and 100%" });
2690
+ /** Animation name validation (CSS identifier) */
2691
+ const animationNameSchema = z$1.string().min(1, "Animation name is required").max(50, "Animation name too long").refine((name) => ANIMATION_NAME_PATTERN.test(name), { message: "Invalid animation name. Use letters, numbers, dashes, underscores (start with letter, dash, or underscore)" });
2692
+ /** Single keyframe (offset + declarations) */
2693
+ const keyframeSchema = z$1.object({
2694
+ offset: keyframeOffsetSchema,
2695
+ declarations: declarationsSchema
2696
+ });
2697
+ /** @keyframes rule schema */
2698
+ const keyframesAtRuleSchema = z$1.object({
2699
+ id: ruleIdSchema,
2700
+ type: z$1.literal("keyframes"),
2701
+ name: animationNameSchema,
2702
+ frames: z$1.array(keyframeSchema).min(1, "At least one keyframe is required")
2703
+ });
2704
+ /** Font-face declarations - uses standard declarations but with font-specific validation */
2705
+ const fontFaceDeclarationsSchema = z$1.record(z$1.string().min(1).max(100), declarationValueSchema).refine((decls) => "fontFamily" in decls || "font-family" in decls, { message: "font-family is required in @font-face" });
2706
+ /** @font-face rule schema */
2707
+ const fontFaceAtRuleSchema = z$1.object({
2708
+ id: ruleIdSchema,
2709
+ type: z$1.literal("font-face"),
2710
+ declarations: fontFaceDeclarationsSchema
2711
+ });
2712
+ /** Media query string validation */
2713
+ const mediaQuerySchema = z$1.string().min(1, "Media query is required").max(200, "Media query too long");
2714
+ /** @media rule schema */
2715
+ const mediaAtRuleSchema = z$1.object({
2716
+ id: ruleIdSchema,
2717
+ type: z$1.literal("media"),
2718
+ query: mediaQuerySchema,
2719
+ rules: z$1.array(nestedRuleSchema).min(1, "At least one rule is required")
2720
+ });
2721
+ /** Supports condition string validation */
2722
+ const supportsConditionSchema = z$1.string().min(1, "Supports condition is required").max(200, "Supports condition too long");
2723
+ /** @supports rule schema */
2724
+ const supportsAtRuleSchema = z$1.object({
2725
+ id: ruleIdSchema,
2726
+ type: z$1.literal("supports"),
2727
+ condition: supportsConditionSchema,
2728
+ rules: z$1.array(nestedRuleSchema).min(1, "At least one rule is required")
2729
+ });
2730
+ /**
2731
+ * Check if raw CSS contains blocked at-rules.
2732
+ */
2733
+ function containsBlockedAtRule(css) {
2734
+ return BLOCKED_AT_RULE_PATTERN.test(css);
2735
+ }
2736
+ /** Raw CSS validation - blocks @import, @charset, must start with @ */
2737
+ const rawCssSchema = z$1.string().min(1, "CSS is required").max(5e3, "Raw CSS too long (max 5000 characters)").refine((css) => css.trim().startsWith("@"), { message: "Raw at-rule must start with @" }).refine((css) => !containsBlockedAtRule(css), { message: `Blocked at-rules: ${BLOCKED_AT_RULES.join(", ")}. Use typed at-rules or local assets instead.` });
2738
+ /** Raw at-rule schema */
2739
+ const rawAtRuleSchema = z$1.object({
2740
+ id: ruleIdSchema,
2741
+ type: z$1.literal("raw"),
2742
+ css: rawCssSchema
2743
+ });
2744
+ /**
2745
+ * Discriminated union schema for all at-rule types.
2746
+ */
2747
+ const customCssAtRuleSchema = z$1.discriminatedUnion("type", [
2748
+ keyframesAtRuleSchema,
2749
+ fontFaceAtRuleSchema,
2750
+ mediaAtRuleSchema,
2751
+ supportsAtRuleSchema,
2752
+ rawAtRuleSchema
2753
+ ]);
2754
+ /**
2755
+ * Array of at-rules for theme-level styling.
2756
+ */
2757
+ const customCssAtRulesSchema = z$1.array(customCssAtRuleSchema).optional();
2758
+ //#endregion
2759
+ //#region ../theme-core/src/shared/componentStyles.ts
2760
+ /**
2761
+ * Shared Component Style Schemas
2762
+ *
2763
+ * Reusable schemas for border and shadow styling that can be shared across
2764
+ * themed components (header, buttons, cards, accordions, inputs).
2765
+ *
2766
+ * Design decisions:
2767
+ * - Shadow elevation uses CSS-aligned names (none/sm/md/lg/xl/2xl)
2768
+ * - Shadow softness is controlled globally, not per-component
2769
+ * - Border position is component-specific, not in shared schema
2770
+ */
2771
+ /**
2772
+ * Shared border schema for themed components.
2773
+ * Position is excluded - each component determines its own border position.
2774
+ */
2775
+ const componentBorderSchema = z$1.object({
2776
+ width: z$1.enum([
2777
+ "none",
2778
+ "hairline",
2779
+ "thin",
2780
+ "medium",
2781
+ "thick"
2782
+ ]).default("none"),
2783
+ style: z$1.enum(["solid", "dashed"]).default("solid"),
2784
+ colorToken: themeColorTokenSchema.optional()
2785
+ });
2786
+ /**
2787
+ * Shared shadow schema for themed components.
2788
+ * Softness is inherited from global theme, not configurable per-component.
2789
+ */
2790
+ const componentShadowSchema = z$1.object({ elevation: z$1.enum([
2791
+ "none",
2792
+ "sm",
2793
+ "md",
2794
+ "lg",
2795
+ "xl",
2796
+ "2xl"
2797
+ ]).default("sm") });
2798
+ //#endregion
2799
+ //#region ../theme-core/src/site-styles/types.ts
2800
+ function asSiteStyleId(value) {
2801
+ const siteStyleId = brandNonEmptyString(value, "SiteStyleId");
2802
+ if (!siteStyleId.startsWith("site-style:")) throw new Error(`SiteStyleId must start with "site-style:". Received: ${value}`);
2803
+ return siteStyleId;
2804
+ }
2805
+ function brandNonEmptyString(value, label) {
2806
+ if (value.length === 0) throw new Error(`${label} must be a non-empty string.`);
2807
+ return value;
2808
+ }
2809
+ const tileTreatmentValues = [
2810
+ "default",
2811
+ "quiet",
2812
+ "brand-depth"
2813
+ ];
2814
+ const eventListTreatmentValues = [
2815
+ "plain",
2816
+ "lined-panel",
2817
+ "ruled-register",
2818
+ "editorial-register",
2819
+ "dense-index"
2820
+ ];
2821
+ const eyebrowTreatmentValues = [
2822
+ "plain",
2823
+ "accent",
2824
+ "pill",
2825
+ "accent-pill",
2826
+ "pill-bounce",
2827
+ "accent-pill-bounce"
2828
+ ];
2829
+ const visibleHeadingDecorationFamilyValues = ["organic-squiggle", "short-center-rule"];
2830
+ const headingDecorationOverrideValues = ["site-default", "off"];
2831
+ const headingDecorationColorTokenValues = [
2832
+ "text",
2833
+ "primary",
2834
+ "secondary",
2835
+ "accent",
2836
+ "border",
2837
+ "muted"
2838
+ ];
2839
+ const accordionIconSetValues = [
2840
+ "plus",
2841
+ "chevron",
2842
+ "caret",
2843
+ "minimal-cross"
2844
+ ];
2845
+ const accordionIconColorTokenValues = [
2846
+ "text",
2847
+ "muted",
2848
+ "primary",
2849
+ "secondary",
2850
+ "accent",
2851
+ "current"
2852
+ ];
2853
+ const accordionIconMotionValues = [
2854
+ "none",
2855
+ "rotate",
2856
+ "swap"
2857
+ ];
2858
+ //#endregion
2859
+ //#region ../theme-core/src/site-styles/logoBranding.ts
2860
+ const logoTextConfidenceValues = [
2861
+ "low",
2862
+ "medium",
2863
+ "high"
2864
+ ];
2865
+ const logoAssetShapeValues = [
2866
+ "none",
2867
+ "horizontal",
2868
+ "square",
2869
+ "portrait",
2870
+ "tall"
2871
+ ];
2872
+ const logoKindValues = [
2873
+ "mark",
2874
+ "wordmark",
2875
+ "lockup",
2876
+ "badge",
2877
+ "stacked-wordmark",
2878
+ "unknown"
2879
+ ];
2880
+ const logoDensityValues = [
2881
+ "simple",
2882
+ "detailed",
2883
+ "unknown"
2884
+ ];
2885
+ const logoContainsTextSchema = z$1.discriminatedUnion("kind", [
2886
+ z$1.object({
2887
+ kind: z$1.literal("contains-text"),
2888
+ confidence: z$1.enum(logoTextConfidenceValues),
2889
+ text: z$1.string().trim().min(1).max(200).optional()
2890
+ }),
2891
+ z$1.object({
2892
+ kind: z$1.literal("no-text"),
2893
+ confidence: z$1.enum(logoTextConfidenceValues)
2894
+ }),
2895
+ z$1.object({
2896
+ kind: z$1.literal("unknown"),
2897
+ reason: z$1.enum([
2898
+ "analysis-unavailable",
2899
+ "unsupported-file",
2900
+ "low-confidence"
2901
+ ])
2902
+ })
2903
+ ]);
2904
+ const logoAnalysisSourceSchema = z$1.discriminatedUnion("kind", [
2905
+ z$1.object({ kind: z$1.literal("none") }),
2906
+ z$1.object({
2907
+ kind: z$1.literal("deterministic"),
2908
+ reason: z$1.enum(["dimensions", "fallback"])
2909
+ }),
2910
+ z$1.object({
2911
+ kind: z$1.literal("llm"),
2912
+ model: z$1.literal("gpt-5.4-mini"),
2913
+ analyzedAt: z$1.string().trim().min(1).max(80).optional()
2914
+ }),
2915
+ z$1.object({ kind: z$1.literal("manual-override") })
2916
+ ]);
2917
+ z$1.object({
2918
+ shape: z$1.enum(logoAssetShapeValues),
2919
+ containsText: logoContainsTextSchema,
2920
+ kind: z$1.enum(logoKindValues),
2921
+ density: z$1.enum(logoDensityValues),
2922
+ source: logoAnalysisSourceSchema
2923
+ });
2924
+ const brandDisplayModeValues = [
2925
+ "auto",
2926
+ "logo-only",
2927
+ "logo-plus-title",
2928
+ "title-only"
2929
+ ];
2930
+ const logoAccommodationPatternValues = [
2931
+ "title-only",
2932
+ "inline-logo-only",
2933
+ "inline-wordmark",
2934
+ "inline-mark-with-title",
2935
+ "logo-plate",
2936
+ "centered-badge",
2937
+ "popout-badge",
2938
+ "centered-masthead",
2939
+ "hero-badge"
2940
+ ];
2941
+ const logoSizePolicyValues = [
2942
+ "auto",
2943
+ "compact",
2944
+ "standard",
2945
+ "generous",
2946
+ "display"
2947
+ ];
2948
+ //#endregion
2949
+ //#region ../theme-core/src/site-styles/rawStyleFields.ts
2950
+ const themeV2RuntimeStyleFieldNames = [
2951
+ "_frameStyles",
2952
+ "_sectionStyles",
2953
+ "_containerStyles",
2954
+ "_cardStyles",
2955
+ "_transitionStyles",
2956
+ "styleGroup"
2957
+ ];
2958
+ const themeV2BlockSpecificRawStyleFieldNames = [
2959
+ "_contentCardStyles",
2960
+ "_heroLayoutStyles",
2961
+ "_textCardStyles"
2962
+ ];
2963
+ const themeV2NormalEditorRawStyleFieldNames = [...themeV2RuntimeStyleFieldNames, ...themeV2BlockSpecificRawStyleFieldNames];
2964
+ new Set(themeV2NormalEditorRawStyleFieldNames);
2965
+ [...themeV2RuntimeStyleFieldNames, ...themeV2BlockSpecificRawStyleFieldNames];
2966
+ const pageDesignEditorBackgroundOverrideOwner = "page-design-editor";
2967
+ const siteChromeBackgroundOverrideOwner = "site-chrome-editor";
2968
+ //#endregion
2969
+ //#region ../theme-core/src/utils/tokenOrColor.ts
2970
+ /**
2971
+ * Runtime color-reference fields intentionally accept any string, including
2972
+ * the legacy empty-string "no color" sentinel. Semantic validation needs
2973
+ * palette context and happens in `parseThemeColorReference`.
2974
+ */
2975
+ const tokenOrCssColorValueSchema = z$1.string();
2976
+ const CSS_COLOR_FUNCTION_PATTERN = /^(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color|color-mix|light-dark)\(/i;
2977
+ const CSS_HEX_COLOR_PATTERN = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
2978
+ const CSS_COLOR_KEYWORDS = /* @__PURE__ */ new Set([
2979
+ "transparent",
2980
+ "currentcolor",
2981
+ "inherit",
2982
+ "initial",
2983
+ "revert",
2984
+ "revert-layer",
2985
+ "unset"
2986
+ ]);
2987
+ const COMMON_CSS_NAMED_COLORS = /* @__PURE__ */ new Set([
2988
+ "black",
2989
+ "blue",
2990
+ "gray",
2991
+ "green",
2992
+ "grey",
2993
+ "orange",
2994
+ "pink",
2995
+ "purple",
2996
+ "red",
2997
+ "white",
2998
+ "yellow"
2999
+ ]);
3000
+ function isCssColorLiteral(value) {
3001
+ const trimmed = value.trim();
3002
+ if (!trimmed) return false;
3003
+ return CSS_HEX_COLOR_PATTERN.test(trimmed) || CSS_COLOR_FUNCTION_PATTERN.test(trimmed) || /^var\(/i.test(trimmed) || CSS_COLOR_KEYWORDS.has(trimmed.toLowerCase());
3004
+ }
3005
+ function parseThemeToken(token) {
3006
+ const trimmed = token.trim();
3007
+ const match = trimmed.match(/^(.*?)-(\d{2,3})$/);
3008
+ if (!match) return {
3009
+ role: trimmed,
3010
+ shade: null
3011
+ };
3012
+ const role = match[1] ?? trimmed;
3013
+ const shade = match[2] ? Number(match[2]) : null;
3014
+ return {
3015
+ role,
3016
+ shade: Number.isFinite(shade) ? shade : null
3017
+ };
3018
+ }
3019
+ function parseContextThemeColorToken(value, context) {
3020
+ const parts = parseColorTokenParts(value);
3021
+ if (parts.kind !== "token") return null;
3022
+ if (!(Boolean(context?.palette?.[value.trim()]) || parts.opacityPercent !== null && Boolean(context?.palette?.[parts.token]))) return null;
3023
+ return value.trim();
3024
+ }
3025
+ function isTokenShapedTypo(value) {
3026
+ if (COMMON_CSS_NAMED_COLORS.has(value.toLowerCase())) return false;
3027
+ if (!/^[a-zA-Z][a-zA-Z0-9]*(?:-[a-zA-Z0-9]+)*(?:\/[^/]+)?$/.test(value)) return false;
3028
+ return !isCssColorLiteral(value);
3029
+ }
3030
+ function warnUnknownThemeColorReference(value) {
3031
+ if (!isTokenShapedTypo(value)) return;
3032
+ console.warn(`[theme-core] Unknown Theme V2 color token "${value}" treated as literal CSS. Use raw:* for deliberate custom CSS values.`);
3033
+ }
3034
+ function parseThemeColorReference(input, context) {
3035
+ const trimmed = input.trim();
3036
+ if (trimmed.startsWith("raw:")) return {
3037
+ kind: "literal-css",
3038
+ value: trimmed.slice(4)
3039
+ };
3040
+ const contextToken = parseContextThemeColorToken(trimmed, context);
3041
+ if (contextToken) return {
3042
+ kind: "palette-context-token",
3043
+ token: contextToken
3044
+ };
3045
+ const knownToken = parseThemeColorToken(trimmed);
3046
+ if (knownToken) return {
3047
+ kind: "theme-token",
3048
+ token: knownToken
3049
+ };
3050
+ warnUnknownThemeColorReference(trimmed);
3051
+ return {
3052
+ kind: "literal-css",
3053
+ value: trimmed
3054
+ };
3055
+ }
3056
+ function resolveThemeColorReferenceValue(input, context) {
3057
+ const reference = parseThemeColorReference(input, context);
3058
+ return reference.kind === "literal-css" ? reference.value : rgbColorValue(reference.token);
3059
+ }
3060
+ function resolveTokenOrCssColorValue(input, context) {
3061
+ return resolveThemeColorReferenceValue(input, context);
3062
+ }
3063
+ function resolveOnColorForThemeToken(token) {
3064
+ if (!parseThemeColorToken(token)) return null;
3065
+ const parts = parseColorTokenParts(token);
3066
+ if (parts.kind !== "token") return null;
3067
+ const { role, shade } = parseThemeToken(parts.token);
3068
+ const normalizedRole = role.trim();
3069
+ if (!normalizedRole) return null;
3070
+ if (!shade) return rgbColorValue(`on${normalizedRole.charAt(0).toUpperCase() + normalizedRole.slice(1)}`);
3071
+ return shade <= 400 ? "#000000" : "#FFFFFF";
3072
+ }
3073
+ //#endregion
3074
+ //#region ../theme-core/src/schema.ts
3075
+ const axesSchema = z$1.object({
3076
+ tone: z$1.enum([
3077
+ "minimal",
3078
+ "classic",
3079
+ "bold"
3080
+ ]),
3081
+ energy: z$1.enum(["calm", "vibrant"]),
3082
+ density: z$1.enum([
3083
+ "airy",
3084
+ "regular",
3085
+ "compact"
3086
+ ]),
3087
+ mediaBias: z$1.enum([
3088
+ "text",
3089
+ "media",
3090
+ "mixed"
3091
+ ]),
3092
+ conversionBias: z$1.enum([
3093
+ "low",
3094
+ "med",
3095
+ "high"
3096
+ ]),
3097
+ motion: z$1.enum([
3098
+ "subtle",
3099
+ "standard",
3100
+ "expressive"
3101
+ ])
3102
+ });
3103
+ const colourHexString = z$1.string().regex(/^#([0-9A-Fa-f]{3}){1,2}$/);
3104
+ const paletteColorSchema = z$1.object({
3105
+ name: z$1.string().min(1),
3106
+ hex: colourHexString
3107
+ });
3108
+ const paletteMetaSchema = z$1.object({ mode: z$1.enum(["light", "dark"]) });
3109
+ const paletteSchema = z$1.object({
3110
+ colors: z$1.array(paletteColorSchema),
3111
+ meta: paletteMetaSchema
3112
+ });
3113
+ const typographyStyleSchema = z$1.object({
3114
+ family: z$1.string().min(1),
3115
+ weight: z$1.enum([
3116
+ "light",
3117
+ "regular",
3118
+ "medium",
3119
+ "semibold",
3120
+ "bold"
3121
+ ]),
3122
+ letterSpacing: z$1.enum([
3123
+ "tight",
3124
+ "normal",
3125
+ "loose"
3126
+ ]),
3127
+ lineHeight: z$1.enum([
3128
+ "normal",
3129
+ "relaxed",
3130
+ "loose"
3131
+ ])
3132
+ });
3133
+ const bodyTypographyStyleSchema = typographyStyleSchema.extend({ size: z$1.enum([
3134
+ "md",
3135
+ "lg",
3136
+ "xl"
3137
+ ]) });
3138
+ const headingSizeSchema = z$1.enum([
3139
+ "xs",
3140
+ "sm",
3141
+ "md",
3142
+ "lg",
3143
+ "xl",
3144
+ "2xl"
3145
+ ]);
3146
+ const headingTypographyOverridesSchema = z$1.object({
3147
+ weight: z$1.enum([
3148
+ "light",
3149
+ "regular",
3150
+ "medium",
3151
+ "semibold",
3152
+ "bold"
3153
+ ]).nullable().optional(),
3154
+ letterSpacing: z$1.enum([
3155
+ "tight",
3156
+ "normal",
3157
+ "loose"
3158
+ ]).nullable().optional(),
3159
+ size: headingSizeSchema.nullable().optional(),
3160
+ lineHeight: z$1.enum([
3161
+ "tight",
3162
+ "snug",
3163
+ "normal",
3164
+ "relaxed",
3165
+ "loose"
3166
+ ]).nullable().optional(),
3167
+ italic: z$1.boolean().nullable().optional(),
3168
+ colorToken: themeColorTokenSchema.nullable().optional()
3169
+ });
3170
+ const headingTypographyStyleSchema = typographyStyleSchema.extend({
3171
+ case: z$1.enum([
3172
+ "uppercase",
3173
+ "normal",
3174
+ "smallCaps"
3175
+ ]).nullable(),
3176
+ italic: z$1.boolean().nullable(),
3177
+ colorToken: themeColorTokenSchema.nullable().optional()
3178
+ });
3179
+ const proseLinkUnderlineStyleSchema = z$1.enum([
3180
+ "solid",
3181
+ "dotted",
3182
+ "dashed"
3183
+ ]);
3184
+ const proseLinkUnderlineThicknessSchema = z$1.enum([
3185
+ "auto",
3186
+ "fromFont",
3187
+ "thin",
3188
+ "medium",
3189
+ "thick"
3190
+ ]);
3191
+ const proseLinkUnderlineOffsetSchema = z$1.enum([
3192
+ "auto",
3193
+ "tight",
3194
+ "normal",
3195
+ "loose"
3196
+ ]);
3197
+ const proseLinkStyleSchema = z$1.object({
3198
+ colorToken: themeColorTokenSchema.optional(),
3199
+ hoverColorToken: themeColorTokenSchema.optional(),
3200
+ underline: z$1.boolean().optional(),
3201
+ decorationColorToken: themeColorTokenSchema.optional(),
3202
+ hoverDecorationColorToken: themeColorTokenSchema.optional(),
3203
+ underlineStyle: proseLinkUnderlineStyleSchema.optional(),
3204
+ underlineThickness: proseLinkUnderlineThicknessSchema.optional(),
3205
+ underlineOffset: proseLinkUnderlineOffsetSchema.optional()
3206
+ });
3207
+ const semanticSpacingSchema = z$1.enum([
3208
+ "none",
3209
+ "compact",
3210
+ "cozy",
3211
+ "medium",
3212
+ "comfortable",
3213
+ "spacious"
3214
+ ]);
3215
+ const boxRoundedSchema = z$1.enum([
3216
+ "none",
3217
+ "sm",
3218
+ "md",
3219
+ "lg",
3220
+ "xl",
3221
+ "2xl",
3222
+ "full"
3223
+ ]);
3224
+ const boxBackgroundOverlaySchema = z$1.object({
3225
+ type: z$1.enum([
3226
+ "none",
3227
+ "color",
3228
+ "gradient"
3229
+ ]).nullable().optional(),
3230
+ color: tokenOrCssColorValueSchema.nullable().optional(),
3231
+ gradient: z$1.string().nullable().optional(),
3232
+ opacity: z$1.number().min(0).max(1).nullable().optional()
3233
+ });
3234
+ const boxBackgroundSchema = z$1.object({
3235
+ type: z$1.enum([
3236
+ "color",
3237
+ "gradient",
3238
+ "image"
3239
+ ]).optional(),
3240
+ contentOwner: z$1.literal(pageDesignEditorBackgroundOverrideOwner).optional(),
3241
+ color: tokenOrCssColorValueSchema.nullable().optional(),
3242
+ gradient: z$1.string().nullable().optional(),
3243
+ gradientPresetId: z$1.string().min(1).nullable().optional(),
3244
+ image: mediaSchema$1.nullable().optional(),
3245
+ objectFit: z$1.enum([
3246
+ "fill",
3247
+ "fit",
3248
+ "original",
3249
+ "custom"
3250
+ ]).nullable().optional(),
3251
+ scale: z$1.string().nullable().optional(),
3252
+ position: z$1.string().nullable().optional(),
3253
+ opacity: z$1.number().min(0).max(1).nullable().optional(),
3254
+ motion: z$1.enum(["static", "fixed-frame"]).nullable().optional(),
3255
+ overlay: boxBackgroundOverlaySchema.nullable().optional(),
3256
+ textColor: tokenOrCssColorValueSchema.nullable().optional(),
3257
+ headingColor: tokenOrCssColorValueSchema.nullable().optional(),
3258
+ linkColor: tokenOrCssColorValueSchema.nullable().optional(),
3259
+ supportingColor: tokenOrCssColorValueSchema.nullable().optional()
3260
+ });
3261
+ const noHeadingDecorationSchema = z$1.object({ family: z$1.literal("none") });
3262
+ const visibleHeadingDecorationSchema = z$1.object({
3263
+ family: z$1.enum(visibleHeadingDecorationFamilyValues),
3264
+ colorToken: z$1.enum(headingDecorationColorTokenValues).optional()
3265
+ });
3266
+ const headingDecorationSchema = z$1.union([noHeadingDecorationSchema, visibleHeadingDecorationSchema]);
3267
+ const headingDecorationOverrideSchema = z$1.union([z$1.enum(headingDecorationOverrideValues), z$1.literal("on").transform(() => "site-default")]);
3268
+ const accordionIconTreatmentSchema = z$1.object({
3269
+ iconSet: z$1.enum(accordionIconSetValues),
3270
+ colorToken: z$1.enum(accordionIconColorTokenValues),
3271
+ openColorToken: z$1.enum(accordionIconColorTokenValues).optional(),
3272
+ motion: z$1.enum(accordionIconMotionValues)
3273
+ });
3274
+ const sectionStylesOverrideSchema = z$1.object({
3275
+ background: boxBackgroundSchema.nullable().optional(),
3276
+ spacing: semanticSpacingSchema.nullable().optional(),
3277
+ minHeight: z$1.enum([
3278
+ "none",
3279
+ "banner",
3280
+ "hero",
3281
+ "immersive"
3282
+ ]).nullable().optional(),
3283
+ tileTreatment: z$1.enum(tileTreatmentValues).nullable().optional(),
3284
+ eventListTreatment: z$1.enum(eventListTreatmentValues).nullable().optional(),
3285
+ eyebrowTreatment: z$1.enum(eyebrowTreatmentValues).nullable().optional(),
3286
+ headingDecoration: headingDecorationSchema.nullable().optional(),
3287
+ headingDecorationOverride: headingDecorationOverrideSchema.nullable().optional(),
3288
+ accordionIconTreatment: accordionIconTreatmentSchema.nullable().optional()
3289
+ });
3290
+ const containerStylesOverrideSchema = z$1.object({
3291
+ background: boxBackgroundSchema.nullable().optional(),
3292
+ spacing: semanticSpacingSchema.nullable().optional(),
3293
+ raised: z$1.boolean().nullable().optional(),
3294
+ rounded: boxRoundedSchema.nullable().optional(),
3295
+ fullWidth: z$1.boolean().nullable().optional()
3296
+ });
3297
+ const cardBorderOverrideSchema = z$1.object({
3298
+ enabled: z$1.boolean().nullable().optional(),
3299
+ width: z$1.enum([
3300
+ "none",
3301
+ "1",
3302
+ "2",
3303
+ "3"
3304
+ ]).nullable().optional(),
3305
+ colorToken: themeColorTokenSchema.nullable().optional()
3306
+ });
3307
+ const cardStylesOverrideSchema = z$1.object({
3308
+ background: boxBackgroundSchema.nullable().optional(),
3309
+ border: cardBorderOverrideSchema.nullable().optional(),
3310
+ spacing: semanticSpacingSchema.nullable().optional(),
3311
+ raised: z$1.boolean().nullable().optional(),
3312
+ rounded: boxRoundedSchema.nullable().optional(),
3313
+ treatment: z$1.enum([
3314
+ "accent-quote",
3315
+ "editorial-rule",
3316
+ "soft-panel",
3317
+ "editorial-serif-quote",
3318
+ "editorial-open",
3319
+ "color-blocked"
3320
+ ]).nullable().optional(),
3321
+ cardVariant: boxStylesCardVariantSchema.nullable().optional()
3322
+ });
3323
+ const blockStyleOverridesSchema = z$1.object({
3324
+ sectionStyles: sectionStylesOverrideSchema.nullable().optional(),
3325
+ containerStyles: containerStylesOverrideSchema.nullable().optional(),
3326
+ cardStyles: cardStylesOverrideSchema.nullable().optional()
3327
+ });
3328
+ const blockThemeOverrideSchema = z$1.object({
3329
+ typography: z$1.object({ proseLinkStyle: proseLinkStyleSchema.optional() }).optional(),
3330
+ styles: blockStyleOverridesSchema.optional()
3331
+ });
3332
+ const typographyScaleSchema = z$1.enum([
3333
+ "compact",
3334
+ "balanced",
3335
+ "spacious",
3336
+ "minorThird",
3337
+ "majorThird",
3338
+ "perfectFourth"
3339
+ ]);
3340
+ const eyebrowTypographyStyleSchema = z$1.object({
3341
+ family: z$1.string().min(1),
3342
+ size: z$1.enum([
3343
+ "sm",
3344
+ "md",
3345
+ "lg"
3346
+ ]).optional(),
3347
+ weight: z$1.enum([
3348
+ "light",
3349
+ "regular",
3350
+ "medium",
3351
+ "semibold",
3352
+ "bold"
3353
+ ]).optional(),
3354
+ letterSpacing: z$1.enum([
3355
+ "tight",
3356
+ "normal",
3357
+ "loose",
3358
+ "wide"
3359
+ ]).optional(),
3360
+ case: z$1.enum(["uppercase", "normal"]).optional()
3361
+ });
3362
+ const typographySchema = z$1.object({
3363
+ body: bodyTypographyStyleSchema,
3364
+ headings: z$1.object({
3365
+ default: headingTypographyStyleSchema,
3366
+ h1: headingTypographyOverridesSchema,
3367
+ h2: headingTypographyOverridesSchema,
3368
+ h3: headingTypographyOverridesSchema,
3369
+ h4: headingTypographyOverridesSchema.optional(),
3370
+ h5: headingTypographyOverridesSchema.optional(),
3371
+ h6: headingTypographyOverridesSchema.optional()
3372
+ }),
3373
+ scale: typographyScaleSchema,
3374
+ proseLinkStyle: proseLinkStyleSchema.optional(),
3375
+ eyebrow: eyebrowTypographyStyleSchema.optional()
3376
+ });
3377
+ const spaceSchema = z$1.enum([
3378
+ "comfortable",
3379
+ "standard",
3380
+ "dense"
3381
+ ]);
3382
+ const corners = z$1.enum([
3383
+ "square",
3384
+ "soft",
3385
+ "rounded",
3386
+ "pill"
3387
+ ]);
3388
+ const shadow = z$1.object({
3389
+ elevation: z$1.enum([
3390
+ "none",
3391
+ "low",
3392
+ "medium",
3393
+ "high"
3394
+ ]),
3395
+ softness: z$1.enum([
3396
+ "crisp",
3397
+ "soft",
3398
+ "hard"
3399
+ ]).nullable(),
3400
+ position: z$1.enum(["bottom", "bottom-right"]).default("bottom"),
3401
+ colorToken: themeColorTokenSchema.optional()
3402
+ });
3403
+ const border = z$1.object({
3404
+ width: z$1.enum([
3405
+ "none",
3406
+ "hairline",
3407
+ "thin",
3408
+ "thick"
3409
+ ]),
3410
+ style: z$1.enum(["solid", "dashed"])
3411
+ });
3412
+ const motion = z$1.object({
3413
+ level: z$1.enum([
3414
+ "off",
3415
+ "low",
3416
+ "medium",
3417
+ "high"
3418
+ ]),
3419
+ easing: z$1.enum([
3420
+ "standard",
3421
+ "snappy",
3422
+ "gentle"
3423
+ ]).nullable()
3424
+ });
3425
+ z$1.object({ shape: corners });
3426
+ z$1.object({
3427
+ elevation: z$1.enum([
3428
+ "none",
3429
+ "low",
3430
+ "medium",
3431
+ "high"
3432
+ ]),
3433
+ border: z$1.enum([
3434
+ "none",
3435
+ "subtle",
3436
+ "defined"
3437
+ ]),
3438
+ shape: corners,
3439
+ headerStyle: z$1.enum([
3440
+ "plain",
3441
+ "accentBar",
3442
+ "subtleBg"
3443
+ ]).nullable(),
3444
+ mediaTreatment: z$1.enum([
3445
+ "square",
3446
+ "rounded",
3447
+ "bleed"
3448
+ ]).nullable()
3449
+ });
3450
+ const inputStyle = z$1.object({
3451
+ shape: corners,
3452
+ border: z$1.enum([
3453
+ "subtle",
3454
+ "defined",
3455
+ "underline"
3456
+ ]),
3457
+ focus: z$1.enum([
3458
+ "glow",
3459
+ "ring",
3460
+ "underline"
3461
+ ]),
3462
+ label: z$1.enum(["inside", "above"])
3463
+ });
3464
+ const headerVariant = z$1.enum([
3465
+ "classic",
3466
+ "centered",
3467
+ "transparent",
3468
+ "floating"
3469
+ ]);
3470
+ const headerPositioning = z$1.enum([
3471
+ "static",
3472
+ "sticky",
3473
+ "fixed"
3474
+ ]);
3475
+ const headerNavStyle = z$1.enum([
3476
+ "minimal",
3477
+ "underline",
3478
+ "underline-grow",
3479
+ "capsule",
3480
+ "scale",
3481
+ "frosted",
3482
+ "solid"
3483
+ ]);
3484
+ const navFontWeight = z$1.enum([
3485
+ "regular",
3486
+ "medium",
3487
+ "semibold",
3488
+ "bold"
3489
+ ]);
3490
+ const headerMaxWidth = z$1.enum(["container", "full"]);
3491
+ const headerBarFrame = z$1.enum(["full-bleed", "inset-shell"]);
3492
+ const headerContainerSchema = z$1.object({
3493
+ rounded: z$1.enum([
3494
+ "none",
3495
+ "sm",
3496
+ "md",
3497
+ "lg",
3498
+ "xl",
3499
+ "2xl"
3500
+ ]).default("xl"),
3501
+ border: z$1.boolean().default(true),
3502
+ shadow: z$1.boolean().default(true),
3503
+ padding: z$1.enum([
3504
+ "sm",
3505
+ "md",
3506
+ "lg"
3507
+ ]).default("md"),
3508
+ tint: z$1.string().nullable().optional(),
3509
+ opacity: z$1.number().min(0).max(1).default(.12)
3510
+ }).optional();
3511
+ const headerBorderSchema = componentBorderSchema.extend({ position: z$1.enum([
3512
+ "bottom",
3513
+ "top",
3514
+ "both",
3515
+ "none"
3516
+ ]).default("bottom") }).optional();
3517
+ const logoStyleSchema = z$1.object({
3518
+ fontFamily: z$1.enum(["heading", "body"]).default("heading"),
3519
+ letterSpacing: z$1.enum([
3520
+ "normal",
3521
+ "wide",
3522
+ "wider",
3523
+ "widest"
3524
+ ]).default("normal"),
3525
+ gradient: z$1.boolean().default(false),
3526
+ brandDisplay: z$1.enum(brandDisplayModeValues).optional(),
3527
+ size: z$1.enum(logoSizePolicyValues).optional(),
3528
+ accommodation: z$1.enum(logoAccommodationPatternValues).optional()
3529
+ }).optional();
3530
+ const headerLogoTextSchema = z$1.object({
3531
+ mobileWrapLines: z$1.union([z$1.literal(1), z$1.literal(2)]).optional(),
3532
+ mobileMaxWidth: z$1.enum([
3533
+ "xs",
3534
+ "sm",
3535
+ "md"
3536
+ ]).optional(),
3537
+ hideOnShrink: z$1.boolean().optional()
3538
+ }).optional();
3539
+ const navEffectsSchema = z$1.object({
3540
+ underlineGradient: z$1.boolean().default(false),
3541
+ glow: z$1.boolean().default(false),
3542
+ glowColor: z$1.string().optional(),
3543
+ neumorphic: z$1.boolean().default(false)
3544
+ }).optional();
3545
+ const dropdownStyleSchema = z$1.object({
3546
+ background: themeColorTokenSchema.default("surface"),
3547
+ textColor: themeColorTokenSchema.default("text"),
3548
+ borderColor: themeColorTokenSchema.nullable().default("border"),
3549
+ shadow: z$1.enum([
3550
+ "none",
3551
+ "sm",
3552
+ "md",
3553
+ "lg"
3554
+ ]).default("md"),
3555
+ borderRadius: z$1.enum([
3556
+ "none",
3557
+ "sm",
3558
+ "md",
3559
+ "lg"
3560
+ ]).default("md"),
3561
+ hoverBackground: themeColorTokenSchema.nullable().optional(),
3562
+ hoverTextColor: themeColorTokenSchema.nullable().optional(),
3563
+ textTransform: z$1.enum([
3564
+ "none",
3565
+ "uppercase",
3566
+ "capitalize"
3567
+ ]).default("none"),
3568
+ letterSpacing: z$1.enum([
3569
+ "normal",
3570
+ "wide",
3571
+ "wider"
3572
+ ]).default("normal"),
3573
+ fontWeight: z$1.enum([
3574
+ "regular",
3575
+ "medium",
3576
+ "semibold",
3577
+ "bold"
3578
+ ]).optional(),
3579
+ textSize: z$1.enum([
3580
+ "xs",
3581
+ "sm",
3582
+ "base",
3583
+ "lg"
3584
+ ]).optional()
3585
+ }).optional();
3586
+ /**
3587
+ * CTA button gap (left margin) for desktop header.
3588
+ * Controls the spacing between nav links and the CTA button.
3589
+ */
3590
+ const headerCtaGapSchema = z$1.enum([
3591
+ "none",
3592
+ "tight",
3593
+ "compact",
3594
+ "default",
3595
+ "relaxed",
3596
+ "spacious"
3597
+ ]);
3598
+ const headerCtaTreatmentSchema = z$1.enum([
3599
+ "default",
3600
+ "primary",
3601
+ "secondary",
3602
+ "inverted",
3603
+ "outline",
3604
+ "ghost"
3605
+ ]);
3606
+ const navContainerSchema = z$1.object({
3607
+ type: z$1.enum([
3608
+ "none",
3609
+ "pill",
3610
+ "glass"
3611
+ ]).default("none"),
3612
+ tint: z$1.string().nullable().optional(),
3613
+ opacity: z$1.number().min(0).max(1).default(.15)
3614
+ }).default({
3615
+ type: "none",
3616
+ tint: null,
3617
+ opacity: .15
3618
+ });
3619
+ const headerBackgroundSchema = z$1.object({
3620
+ type: z$1.enum([
3621
+ "color",
3622
+ "gradient",
3623
+ "image"
3624
+ ]),
3625
+ contentOwner: z$1.literal(siteChromeBackgroundOverrideOwner).optional(),
3626
+ color: tokenOrCssColorValueSchema.nullable().optional(),
3627
+ gradient: gradientConfigSchema.nullable().optional(),
3628
+ image: mediaSchema$1.nullable().optional(),
3629
+ textColor: tokenOrCssColorValueSchema.nullable().optional()
3630
+ });
3631
+ const headerSchema = z$1.object({
3632
+ variant: headerVariant,
3633
+ positioning: headerPositioning,
3634
+ shrinkOnScroll: z$1.boolean(),
3635
+ maxWidth: headerMaxWidth,
3636
+ barFrame: headerBarFrame.optional(),
3637
+ logoOverride: mediaSchema$1.nullable().optional(),
3638
+ background: headerBackgroundSchema.default({
3639
+ type: "color",
3640
+ color: "surface"
3641
+ }),
3642
+ textColor: themeColorTokenSchema.nullable().optional(),
3643
+ navStyle: headerNavStyle,
3644
+ navColor: themeColorTokenSchema.nullable().optional(),
3645
+ navWeight: navFontWeight.default("medium"),
3646
+ navFontRole: z$1.enum(["body", "heading"]).optional(),
3647
+ navTypography: z$1.enum(["body", "heading"]).optional(),
3648
+ navTextSize: navLinkStyleSchema.shape.textSize,
3649
+ navPlacement: z$1.enum(["end", "center"]).optional(),
3650
+ container: headerContainerSchema,
3651
+ border: headerBorderSchema,
3652
+ shadow: componentShadowSchema.optional(),
3653
+ logo: logoStyleSchema,
3654
+ logoText: headerLogoTextSchema,
3655
+ navEffects: navEffectsSchema,
3656
+ navContainer: navContainerSchema,
3657
+ navLinkStyle: navLinkStyleSchema.optional(),
3658
+ ctaGap: headerCtaGapSchema.optional(),
3659
+ ctaTreatment: headerCtaTreatmentSchema.optional(),
3660
+ ctaVariant: z$1.string().min(1).optional(),
3661
+ dropdownStyle: dropdownStyleSchema
3662
+ }).transform(normaliseHeaderNavFontRole);
3663
+ /**
3664
+ * Normalises the legacy `navTypography` font-role alias into the canonical
3665
+ * `navFontRole` field so persisted themes migrate at the parse boundary without
3666
+ * a data migration. `navFontRole` always wins when both are present; the legacy
3667
+ * field is dropped so we never carry a dual write forward.
3668
+ */
3669
+ function normaliseHeaderNavFontRole(header) {
3670
+ if (header.navTypography === void 0) return header;
3671
+ const { navTypography, ...rest } = header;
3672
+ return header.navFontRole === void 0 ? {
3673
+ ...rest,
3674
+ navFontRole: navTypography
3675
+ } : rest;
3676
+ }
3677
+ const footerVariant = z$1.enum([
3678
+ "simple",
3679
+ "columns",
3680
+ "split"
3681
+ ]);
3682
+ const footerMaxWidth = z$1.enum(["container", "full"]);
3683
+ const footerMode = z$1.enum([
3684
+ "default",
3685
+ "blocks",
3686
+ "default+blocks",
3687
+ "none"
3688
+ ]);
3689
+ const footerNavLayoutMode = z$1.enum([
3690
+ "stack",
3691
+ "inline",
3692
+ "inline-wrap"
3693
+ ]);
3694
+ const footerNavLayoutAlign = z$1.enum([
3695
+ "start",
3696
+ "center",
3697
+ "end",
3698
+ "space-between"
3699
+ ]);
3700
+ const footerSpacing = z$1.enum([
3701
+ "none",
3702
+ "tight",
3703
+ "compact",
3704
+ "default",
3705
+ "relaxed",
3706
+ "spacious"
3707
+ ]);
3708
+ const footerLogoPlacement = z$1.enum([
3709
+ "left",
3710
+ "right",
3711
+ "above",
3712
+ "below"
3713
+ ]);
3714
+ const footerLogoSize = z$1.enum([
3715
+ "sm",
3716
+ "md",
3717
+ "lg",
3718
+ "xl"
3719
+ ]);
3720
+ const footerLogoMaxHeight = z$1.enum([
3721
+ "sm",
3722
+ "md",
3723
+ "lg",
3724
+ "xl"
3725
+ ]);
3726
+ const footerBottomTextLinkStyleSchema = z$1.object({
3727
+ colorToken: themeColorTokenSchema.optional(),
3728
+ hoverColorToken: themeColorTokenSchema.nullable().optional(),
3729
+ decorationColorToken: themeColorTokenSchema.nullable().optional(),
3730
+ underline: z$1.boolean().optional()
3731
+ });
3732
+ const footerBottomBarSchema = z$1.object({
3733
+ enabled: z$1.boolean().optional(),
3734
+ fullBleed: z$1.boolean().optional(),
3735
+ background: headerBackgroundSchema.optional(),
3736
+ textColor: themeColorTokenSchema.nullable().optional(),
3737
+ textAlign: z$1.enum([
3738
+ "left",
3739
+ "center",
3740
+ "right"
3741
+ ]).optional(),
3742
+ paddingY: footerSpacing.optional(),
3743
+ paddingX: footerSpacing.optional(),
3744
+ borderTop: z$1.object({
3745
+ colorToken: themeColorTokenSchema.nullable().optional(),
3746
+ width: z$1.enum([
3747
+ "none",
3748
+ "thin",
3749
+ "medium",
3750
+ "thick"
3751
+ ]).optional()
3752
+ }).optional()
3753
+ });
3754
+ const footerNavLayoutSchema = z$1.object({
3755
+ layout: footerNavLayoutMode.optional(),
3756
+ align: footerNavLayoutAlign.optional(),
3757
+ gapX: footerSpacing.optional(),
3758
+ gapY: footerSpacing.optional(),
3759
+ columns: z$1.number().int().min(1).max(6).optional()
3760
+ });
3761
+ const footerLogoSchema = z$1.object({
3762
+ showLogo: z$1.boolean().default(true),
3763
+ showLogoText: z$1.boolean().optional(),
3764
+ placement: footerLogoPlacement.optional(),
3765
+ size: footerLogoSize.optional(),
3766
+ maxHeight: footerLogoMaxHeight.optional(),
3767
+ align: z$1.enum([
3768
+ "start",
3769
+ "center",
3770
+ "end"
3771
+ ]).optional()
3772
+ });
3773
+ const footerSchema = z$1.object({
3774
+ /**
3775
+ * SDK-only footer rendering mode.
3776
+ *
3777
+ * Backwards compatible: missing/undefined behaves as 'default'.
3778
+ */
3779
+ mode: footerMode.optional(),
3780
+ variant: footerVariant,
3781
+ maxWidth: footerMaxWidth,
3782
+ showLogoText: z$1.boolean().optional(),
3783
+ background: headerBackgroundSchema.default({
3784
+ type: "color",
3785
+ color: "surface"
3786
+ }),
3787
+ navStyle: headerNavStyle.default("minimal"),
3788
+ navColor: themeColorTokenSchema.nullable().optional(),
3789
+ navWeight: navFontWeight.default("medium"),
3790
+ navLinkStyle: navLinkStyleSchema.optional(),
3791
+ bottomTextLinkStyle: footerBottomTextLinkStyleSchema.optional(),
3792
+ navLayout: footerNavLayoutSchema.optional(),
3793
+ logo: footerLogoSchema.optional(),
3794
+ bottomBar: footerBottomBarSchema.optional()
3795
+ });
3796
+ const containerPaddingPresetSchema = z$1.enum([
3797
+ "tight",
3798
+ "compact",
3799
+ "default",
3800
+ "relaxed"
3801
+ ]);
3802
+ const layoutSchema = z$1.object({ containerPadding: z$1.object({
3803
+ mobile: containerPaddingPresetSchema.optional(),
3804
+ tablet: containerPaddingPresetSchema.optional(),
3805
+ desktop: containerPaddingPresetSchema.optional()
3806
+ }).optional() }).optional();
3807
+ const heroTypographySizeSchema = z$1.enum([
3808
+ "sm",
3809
+ "base",
3810
+ "lg",
3811
+ "xl",
3812
+ "2xl",
3813
+ "3xl",
3814
+ "4xl",
3815
+ "5xl",
3816
+ "6xl",
3817
+ "editorial"
3818
+ ]);
3819
+ const heroTypographyLineHeightSchema = z$1.enum([
3820
+ "tight",
3821
+ "snug",
3822
+ "normal",
3823
+ "relaxed"
3824
+ ]);
3825
+ const heroResponsiveTypographySchema = z$1.object({
3826
+ headlineSize: heroTypographySizeSchema.optional(),
3827
+ headlineLineHeight: heroTypographyLineHeightSchema.optional(),
3828
+ subheadlineSize: heroTypographySizeSchema.optional(),
3829
+ subheadlineLineHeight: heroTypographyLineHeightSchema.optional()
3830
+ });
3831
+ const heroTypographySchema = z$1.object({
3832
+ headlineSize: heroTypographySizeSchema.optional(),
3833
+ headlineLineHeight: heroTypographyLineHeightSchema.optional(),
3834
+ subheadlineSize: heroTypographySizeSchema.optional(),
3835
+ subheadlineLineHeight: heroTypographyLineHeightSchema.optional(),
3836
+ microHeadlineSize: heroTypographySizeSchema.optional(),
3837
+ microHeadlineLineHeight: heroTypographyLineHeightSchema.optional(),
3838
+ microSubheadlineSize: heroTypographySizeSchema.optional(),
3839
+ microSubheadlineLineHeight: heroTypographyLineHeightSchema.optional(),
3840
+ responsive: z$1.object({
3841
+ tablet: heroResponsiveTypographySchema.optional(),
3842
+ mobile: heroResponsiveTypographySchema.optional()
3843
+ }).optional()
3844
+ });
3845
+ const heroSchema = z$1.object({ typography: heroTypographySchema.optional() }).optional();
3846
+ const bodyTextIntroTypographySizeSchema = z$1.enum(["default", "editorial"]);
3847
+ const bodyTextSchema = z$1.object({ intro: z$1.object({
3848
+ paragraphSize: bodyTextIntroTypographySizeSchema.optional(),
3849
+ headingSize: bodyTextIntroTypographySizeSchema.optional()
3850
+ }).optional() }).optional();
3851
+ const gradientsSchema = z$1.object({
3852
+ button: z$1.string().min(1).nullable().optional(),
3853
+ hero: z$1.string().min(1).nullable().optional(),
3854
+ background: z$1.string().min(1).nullable().optional()
3855
+ });
3856
+ /**
3857
+ * Testimonial quote-mark treatment, owned by the site style (analogous to the
3858
+ * accordion icon). `style` is the coarse selector; the optional fields fine-tune
3859
+ * it. `none` hides the mark. The block renders the mark; the site style decides
3860
+ * its character; a look may still hide it.
3861
+ */
3862
+ const testimonialQuoteTreatmentSchema = z$1.object({
3863
+ style: z$1.enum([
3864
+ "serif-display",
3865
+ "accent-glyph",
3866
+ "none"
3867
+ ]),
3868
+ fontFamily: z$1.enum(["heading", "body"]).optional(),
3869
+ scale: z$1.enum([
3870
+ "sm",
3871
+ "md",
3872
+ "lg",
3873
+ "xl"
3874
+ ]).optional(),
3875
+ colorToken: themeColorTokenSchema.optional(),
3876
+ opacity: z$1.number().min(0).max(1).optional()
3877
+ });
3878
+ const themeSchema = z$1.object({
3879
+ name: z$1.string().min(1).max(30),
3880
+ description: z$1.string().min(1).max(400),
3881
+ rationale: z$1.string().min(1).max(400),
3882
+ siteStyleId: z$1.string().min(1).transform((value) => asSiteStyleId(value)).optional(),
3883
+ axes: axesSchema,
3884
+ palette: paletteSchema,
3885
+ typography: typographySchema,
3886
+ space: spaceSchema,
3887
+ border,
3888
+ shadow,
3889
+ motion,
3890
+ corners,
3891
+ gradients: gradientsSchema.optional(),
3892
+ layout: layoutSchema,
3893
+ hero: heroSchema,
3894
+ bodyText: bodyTextSchema,
3895
+ header: headerSchema,
3896
+ footer: footerSchema,
3897
+ buttons: buttonSystemSchema.optional(),
3898
+ cards: cardSystemSchema.optional(),
3899
+ accordions: accordionSystemSchema.optional(),
3900
+ testimonialQuote: testimonialQuoteTreatmentSchema.optional(),
3901
+ inputs: inputSystemSchema.optional(),
3902
+ inputStyle: inputStyle.optional(),
3903
+ blockCustomVars: z$1.record(z$1.string(), z$1.record(z$1.string(), z$1.string())).optional(),
3904
+ blockOverrides: z$1.record(z$1.string(), blockThemeOverrideSchema).optional(),
3905
+ headingDecoration: headingDecorationSchema.optional(),
3906
+ customCssRules: customCssRulesSchema,
3907
+ blockCustomCssRules: blockCustomCssRulesSchema,
3908
+ customCssAtRules: customCssAtRulesSchema,
3909
+ /**
3910
+ * Style groups define named visual presets that content authors can apply to blocks.
3911
+ *
3912
+ * Unlike variants (which change block structure/layout), style groups only affect
3913
+ * CSS styling. The selected style group is rendered as a `data-style-group` attribute
3914
+ * on the block wrapper, which can be targeted in `blockCustomCssRules`.
3915
+ *
3916
+ * @example
3917
+ * ```typescript
3918
+ * {
3919
+ * styleGroups: {
3920
+ * hero: ['bold', 'minimal', 'featured'],
3921
+ * 'body-text': ['intro', 'compact'],
3922
+ * },
3923
+ * blockCustomCssRules: [
3924
+ * {
3925
+ * id: 'hero-bold-headline',
3926
+ * blockKind: 'hero',
3927
+ * selector: '&[data-style-group="bold"] .hero-headline',
3928
+ * declarations: { fontWeight: '800', fontSize: '3rem' }
3929
+ * }
3930
+ * ]
3931
+ * }
3932
+ * ```
3933
+ */
3934
+ styleGroups: z$1.record(z$1.string(), z$1.array(z$1.string())).optional()
3935
+ });
3936
+ z$1.object({
3937
+ message: z$1.string().min(1),
3938
+ themes: z$1.array(themeSchema).length(3)
3939
+ });
3940
+ //#endregion
3941
+ //#region ../theme-core/src/palette/utils/colorConversion.ts
3942
+ function hexToRgb(hex) {
3943
+ const h = hex.replace(/^#/, "");
3944
+ const m = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
3945
+ if (m.length !== 6) throw new Error("Bad hex");
3946
+ const int = parseInt(m, 16);
3947
+ return {
3948
+ r: int >> 16 & 255,
3949
+ g: int >> 8 & 255,
3950
+ b: int & 255
3951
+ };
3952
+ }
3953
+ function srgbToLinear(u) {
3954
+ const x = u / 255;
3955
+ return x <= .04045 ? x / 12.92 : Math.pow((x + .055) / 1.055, 2.4);
3956
+ }
3957
+ //#endregion
3958
+ //#region ../theme-core/src/palette/utils/contrast.ts
3959
+ function relativeLuminance(r, g, b) {
3960
+ const R = srgbToLinear(r), G = srgbToLinear(g), B = srgbToLinear(b);
3961
+ return .2126 * R + .7152 * G + .0722 * B;
3962
+ }
3963
+ //#endregion
3964
+ //#region ../theme-core/src/buttons/classNames.ts
3965
+ function themeButtonVariantClassNames(variant) {
3966
+ if (variant === "default") return [variant];
3967
+ return [variant, `button-${variant}`];
3968
+ }
3969
+ function themeButtonSizeClassName(size) {
3970
+ return `btn-${size}`;
3971
+ }
3972
+ function themeButtonClassName(spec) {
3973
+ return [
3974
+ ...themeButtonVariantClassNames(spec.variant),
3975
+ themeButtonSizeClassName(spec.size),
3976
+ spec.extraClassName
3977
+ ].filter(Boolean).join(" ");
3978
+ }
3979
+ buttonSizeNameSchema.options;
3980
+ //#endregion
3981
+ //#region ../theme-core/src/buttons/styles/domain.ts
3982
+ const PUBLIC_BUTTON_ROLES = [
3983
+ "primary",
3984
+ "secondary",
3985
+ "outline",
3986
+ "ghost",
3987
+ "accent"
3988
+ ];
3989
+ function defineButtonStyleRecipe(recipe) {
3990
+ return recipe;
3991
+ }
3992
+ function materializeButtonRoles(definitions) {
3993
+ const primary = materializeCompleteRole("primary", definitions.primary.appearance);
3994
+ const secondary = materializeCompleteRole("secondary", definitions.secondary.appearance);
3995
+ const completeRoles = {
3996
+ primary,
3997
+ secondary
3998
+ };
3999
+ return {
4000
+ primary,
4001
+ secondary,
4002
+ outline: materializeSupportingRole("outline", definitions.outline, completeRoles),
4003
+ ghost: materializeSupportingRole("ghost", definitions.ghost, completeRoles),
4004
+ accent: materializeSupportingRole("accent", definitions.accent, completeRoles)
4005
+ };
4006
+ }
4007
+ function resolveButtonStyleRecipe(recipe, parameters) {
4008
+ const parsedParameters = recipe.parameterSchema.safeParse(parameters);
4009
+ if (!parsedParameters.success) return {
4010
+ kind: "error",
4011
+ error: {
4012
+ kind: "invalid-parameters",
4013
+ styleId: recipe.id,
4014
+ issues: parsedParameters.error.issues.map((issue) => issue.message)
4015
+ }
4016
+ };
4017
+ const definition = recipe.defineSystem(parsedParameters.data);
4018
+ const roles = materializeButtonRoles(definition.roles);
4019
+ const buttonSystem = {
4020
+ global: definition.global,
4021
+ variants: PUBLIC_BUTTON_ROLES.map((role) => roles[role]),
4022
+ ...definition.sizes ? { sizes: definition.sizes } : {}
4023
+ };
4024
+ const parsedButtonSystem = buttonSystemSchema.safeParse(buttonSystem);
4025
+ if (!parsedButtonSystem.success) return {
4026
+ kind: "error",
4027
+ error: {
4028
+ kind: "invalid-button-system",
4029
+ styleId: recipe.id,
4030
+ issues: parsedButtonSystem.error.issues.map((issue) => issue.message)
4031
+ }
4032
+ };
4033
+ return {
4034
+ kind: "resolved",
4035
+ buttonSystem: parsedButtonSystem.data
4036
+ };
4037
+ }
4038
+ function materializeSupportingRole(role, definition, completeRoles) {
4039
+ if (definition.kind === "complete") return materializeCompleteRole(role, definition.appearance);
4040
+ return {
4041
+ ...completeRoles[definition.from],
4042
+ ...definition.overrides,
4043
+ id: role,
4044
+ name: roleName(role),
4045
+ enabled: true,
4046
+ priority: 3
4047
+ };
4048
+ }
4049
+ function materializeCompleteRole(role, appearance) {
4050
+ return {
4051
+ ...appearance,
4052
+ id: role,
4053
+ name: roleName(role),
4054
+ enabled: true,
4055
+ priority: rolePriority(role)
4056
+ };
4057
+ }
4058
+ function roleName(role) {
4059
+ return role.charAt(0).toUpperCase() + role.slice(1);
4060
+ }
4061
+ function rolePriority(role) {
4062
+ if (role === "primary") return 1;
4063
+ if (role === "secondary") return 2;
4064
+ return 3;
4065
+ }
4066
+ //#endregion
4067
+ //#region ../theme-core/src/buttons/styles/selection.ts
4068
+ const BUTTON_STYLE_IDS = [
4069
+ "soft-pill",
4070
+ "earth-pill",
4071
+ "confident-chip",
4072
+ "editorial-link",
4073
+ "pebble",
4074
+ "ink-stamp",
4075
+ "flat-ink",
4076
+ "brushed-wash",
4077
+ "showtime-pill",
4078
+ "joy-stamp",
4079
+ "ornate-ritual",
4080
+ "quiet-arrow"
4081
+ ];
4082
+ const quietArrowParametersSchema = z$1.object({ secondaryTreatment: z$1.enum(["outlined", "solid-accent"]) }).strict();
4083
+ const emptyParametersSchema$1 = z$1.object({}).strict();
4084
+ function selectionBranch(styleId, parameters) {
4085
+ return z$1.object({
4086
+ styleId: z$1.literal(styleId),
4087
+ parameters
4088
+ }).strict();
4089
+ }
4090
+ z$1.discriminatedUnion("styleId", [
4091
+ selectionBranch("soft-pill", emptyParametersSchema$1),
4092
+ selectionBranch("earth-pill", emptyParametersSchema$1),
4093
+ selectionBranch("confident-chip", emptyParametersSchema$1),
4094
+ selectionBranch("editorial-link", emptyParametersSchema$1),
4095
+ selectionBranch("pebble", emptyParametersSchema$1),
4096
+ selectionBranch("ink-stamp", emptyParametersSchema$1),
4097
+ selectionBranch("flat-ink", emptyParametersSchema$1),
4098
+ selectionBranch("brushed-wash", emptyParametersSchema$1),
4099
+ selectionBranch("showtime-pill", emptyParametersSchema$1),
4100
+ selectionBranch("joy-stamp", emptyParametersSchema$1),
4101
+ selectionBranch("ornate-ritual", emptyParametersSchema$1),
4102
+ selectionBranch("quiet-arrow", quietArrowParametersSchema)
4103
+ ]);
4104
+ //#endregion
4105
+ //#region ../theme-core/src/buttons/styles/recipes/quietArrow.ts
4106
+ const quietArrowRecipe = defineButtonStyleRecipe({
4107
+ id: "quiet-arrow",
4108
+ accessibilityLabel: "Wide uppercase buttons with trailing arrows",
4109
+ tags: {
4110
+ tone: "classic",
4111
+ energy: "calm",
4112
+ motion: "subtle",
4113
+ era: "editorial"
4114
+ },
4115
+ parameterSchema: quietArrowParametersSchema,
4116
+ defaultParameters: { secondaryTreatment: "outlined" },
4117
+ controls: [{
4118
+ kind: "choice",
4119
+ parameter: "secondaryTreatment",
4120
+ label: "Secondary button treatment",
4121
+ options: [{
4122
+ value: "outlined",
4123
+ label: "Outlined"
4124
+ }, {
4125
+ value: "solid-accent",
4126
+ label: "Solid accent"
4127
+ }]
4128
+ }],
4129
+ defineSystem: (parameters) => ({
4130
+ global: {
4131
+ cornerStyle: "rounded",
4132
+ textTransform: "uppercase",
4133
+ fontWeight: 500,
4134
+ typography: "body",
4135
+ fontSize: "text-sm",
4136
+ letterSpacing: "loose",
4137
+ hoverTransform: "none",
4138
+ hoverColor: "none"
4139
+ },
4140
+ sizes: {
4141
+ sm: {
4142
+ padding: "0.625rem 1.25rem",
4143
+ fontSize: "text-xs"
4144
+ },
4145
+ md: {
4146
+ padding: "0.8125rem 1.75rem",
4147
+ fontSize: "text-sm"
4148
+ },
4149
+ lg: {
4150
+ padding: "0.9375rem 2.125rem",
4151
+ fontSize: "text-sm"
4152
+ },
4153
+ xl: {
4154
+ padding: "1.0625rem 2.5rem",
4155
+ fontSize: "text-base"
4156
+ }
4157
+ },
4158
+ roles: {
4159
+ primary: {
4160
+ kind: "complete",
4161
+ appearance: {
4162
+ background: {
4163
+ type: "solid",
4164
+ colorToken: unsafeAsOpaqueButtonColourToken("primary")
4165
+ },
4166
+ borderRadius: "rounded-xl",
4167
+ affordance: { iconId: "ArrowRight" },
4168
+ effects: { hover: [{
4169
+ effectId: "darken-background",
4170
+ options: { amount: 100 }
4171
+ }] }
4172
+ }
4173
+ },
4174
+ secondary: {
4175
+ kind: "complete",
4176
+ appearance: parameters.secondaryTreatment === "solid-accent" ? {
4177
+ background: {
4178
+ type: "solid",
4179
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
4180
+ },
4181
+ borderRadius: "rounded-xl",
4182
+ affordance: { iconId: "ArrowRight" },
4183
+ effects: { hover: [{
4184
+ effectId: "darken-background",
4185
+ options: { amount: 100 }
4186
+ }] }
4187
+ } : {
4188
+ background: {
4189
+ type: "surface",
4190
+ role: "link"
4191
+ },
4192
+ borderRadius: "rounded-xl",
4193
+ border: { widthClass: "border" },
4194
+ affordance: { iconId: "ArrowRight" },
4195
+ effects: { hover: [{
4196
+ effectId: "background-on-hover",
4197
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
4198
+ }] }
4199
+ }
4200
+ },
4201
+ outline: {
4202
+ kind: "complete",
4203
+ appearance: {
4204
+ background: {
4205
+ type: "surface",
4206
+ role: "link"
4207
+ },
4208
+ borderRadius: "rounded-xl",
4209
+ border: { widthClass: "border" }
4210
+ }
4211
+ },
4212
+ ghost: {
4213
+ kind: "complete",
4214
+ appearance: {
4215
+ background: {
4216
+ type: "surface",
4217
+ role: "link"
4218
+ },
4219
+ borderRadius: "rounded-xl"
4220
+ }
4221
+ },
4222
+ accent: {
4223
+ kind: "derive",
4224
+ from: "primary",
4225
+ overrides: { background: {
4226
+ type: "solid",
4227
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
4228
+ } }
4229
+ }
4230
+ }
4231
+ })
4232
+ });
4233
+ //#endregion
4234
+ //#region ../theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.ts
4235
+ const emptyParametersSchema = z$1.object({}).strict();
4236
+ function defineStaticButtonStyleRecipe(input) {
4237
+ const system = normalizeSystem(input.system);
4238
+ return defineButtonStyleRecipe({
4239
+ id: input.id,
4240
+ accessibilityLabel: input.accessibilityLabel,
4241
+ tags: input.tags,
4242
+ parameterSchema: emptyParametersSchema,
4243
+ defaultParameters: {},
4244
+ controls: [],
4245
+ defineSystem: () => system
4246
+ });
4247
+ }
4248
+ function normalizeSystem(input) {
4249
+ return {
4250
+ global: buttonGlobalSettingsSchema.parse(input.global),
4251
+ ...input.sizes ? { sizes: input.sizes } : {},
4252
+ roles: {
4253
+ primary: normalizeCompleteRole(input.roles.primary),
4254
+ secondary: normalizeCompleteRole(input.roles.secondary),
4255
+ outline: normalizeSupportingRole(input.roles.outline),
4256
+ ghost: normalizeSupportingRole(input.roles.ghost),
4257
+ accent: normalizeSupportingRole(input.roles.accent)
4258
+ }
4259
+ };
4260
+ }
4261
+ function normalizeCompleteRole(role) {
4262
+ return {
4263
+ kind: "complete",
4264
+ appearance: normalizeAppearance(role.appearance)
4265
+ };
4266
+ }
4267
+ function normalizeSupportingRole(role) {
4268
+ if (role.kind === "complete") return normalizeCompleteRole(role);
4269
+ return {
4270
+ kind: "derive",
4271
+ from: role.from,
4272
+ ...role.overrides ? { overrides: normalizeAppearanceOverrides(role.overrides) } : {}
4273
+ };
4274
+ }
4275
+ function normalizeAppearance(appearance) {
4276
+ const { background, hoverBackgroundToken, ...rest } = appearance;
4277
+ return {
4278
+ ...rest,
4279
+ background: buttonColourTreatmentSchema.parse(background),
4280
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
4281
+ };
4282
+ }
4283
+ function normalizeAppearanceOverrides(overrides) {
4284
+ const { background, hoverBackgroundToken, ...rest } = overrides;
4285
+ return {
4286
+ ...rest,
4287
+ ...background ? { background: buttonColourTreatmentSchema.parse(background) } : {},
4288
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
4289
+ };
4290
+ }
4291
+ //#endregion
4292
+ //#region ../theme-core/src/buttons/styles/recipes/staticRecipes.ts
4293
+ const softPillRecipe = defineStaticButtonStyleRecipe({
4294
+ id: "soft-pill",
4295
+ accessibilityLabel: "Rounded pill buttons with a gentle hover lift",
4296
+ tags: {
4297
+ tone: "classic",
4298
+ energy: "calm",
4299
+ motion: "subtle",
4300
+ era: "organic"
4301
+ },
4302
+ system: {
4303
+ global: {
4304
+ cornerStyle: "pill",
4305
+ shadow: "low",
4306
+ textTransform: "none",
4307
+ fontWeight: 500,
4308
+ hoverTransform: "lift",
4309
+ hoverColor: "none"
4310
+ },
4311
+ roles: {
4312
+ primary: {
4313
+ kind: "complete",
4314
+ appearance: {
4315
+ background: {
4316
+ type: "solid",
4317
+ colorToken: "primary"
4318
+ },
4319
+ borderRadius: "rounded-full",
4320
+ shadow: {
4321
+ elevation: "low",
4322
+ softness: "soft",
4323
+ position: "bottom"
4324
+ },
4325
+ effects: {
4326
+ hover: [{ effectId: "lift" }],
4327
+ active: [{
4328
+ effectId: "scale-down",
4329
+ options: { scale: "0.98" }
4330
+ }]
4331
+ }
4332
+ }
4333
+ },
4334
+ secondary: {
4335
+ kind: "complete",
4336
+ appearance: {
4337
+ background: {
4338
+ type: "surface",
4339
+ role: "link"
4340
+ },
4341
+ borderRadius: "rounded-full",
4342
+ border: { widthClass: "border-2" },
4343
+ effects: { hover: [{
4344
+ effectId: "background-on-hover",
4345
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4346
+ }] }
4347
+ }
4348
+ },
4349
+ outline: {
4350
+ kind: "complete",
4351
+ appearance: {
4352
+ background: {
4353
+ type: "surface",
4354
+ role: "link"
4355
+ },
4356
+ borderRadius: "rounded-full",
4357
+ border: { widthClass: "border" },
4358
+ effects: { hover: [{
4359
+ effectId: "background-on-hover",
4360
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4361
+ }] }
4362
+ }
4363
+ },
4364
+ ghost: {
4365
+ kind: "complete",
4366
+ appearance: {
4367
+ background: {
4368
+ type: "surface",
4369
+ role: "link"
4370
+ },
4371
+ borderRadius: "rounded-full",
4372
+ effects: { hover: [{
4373
+ effectId: "background-on-hover",
4374
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4375
+ }] }
4376
+ }
4377
+ },
4378
+ accent: {
4379
+ kind: "derive",
4380
+ from: "primary",
4381
+ overrides: { background: {
4382
+ type: "solid",
4383
+ colorToken: "accent"
4384
+ } }
4385
+ }
4386
+ }
4387
+ }
4388
+ });
4389
+ const earthPillRecipe = defineStaticButtonStyleRecipe({
4390
+ id: "earth-pill",
4391
+ accessibilityLabel: "Compact rounded buttons with a quiet hover lift",
4392
+ tags: {
4393
+ tone: "classic",
4394
+ energy: "calm",
4395
+ motion: "subtle",
4396
+ era: "organic"
4397
+ },
4398
+ system: {
4399
+ global: {
4400
+ cornerStyle: "pill",
4401
+ shadow: "low",
4402
+ textTransform: "none",
4403
+ fontWeight: 500,
4404
+ hoverTransform: "lift",
4405
+ hoverColor: "none",
4406
+ typography: "body",
4407
+ paddingPreset: "default"
4408
+ },
4409
+ sizes: {
4410
+ sm: {
4411
+ padding: "0.5rem 1rem",
4412
+ fontSize: "text-sm"
4413
+ },
4414
+ md: { padding: "0.625rem 1.35rem" },
4415
+ lg: {
4416
+ padding: "0.75rem 1.65rem",
4417
+ fontSize: "text-lg"
4418
+ },
4419
+ xl: {
4420
+ padding: "0.875rem 2rem",
4421
+ fontSize: "text-xl"
4422
+ }
4423
+ },
4424
+ roles: {
4425
+ primary: {
4426
+ kind: "complete",
4427
+ appearance: {
4428
+ background: {
4429
+ type: "solid",
4430
+ colorToken: "primary"
4431
+ },
4432
+ borderRadius: "rounded-full",
4433
+ shadow: {
4434
+ elevation: "low",
4435
+ softness: "soft",
4436
+ position: "bottom"
4437
+ },
4438
+ effects: {
4439
+ hover: [{ effectId: "lift" }, {
4440
+ effectId: "background-on-hover",
4441
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
4442
+ }],
4443
+ active: [{
4444
+ effectId: "scale-down",
4445
+ options: { scale: "0.98" }
4446
+ }]
4447
+ }
4448
+ }
4449
+ },
4450
+ secondary: {
4451
+ kind: "complete",
4452
+ appearance: {
4453
+ background: {
4454
+ type: "surface",
4455
+ role: "link"
4456
+ },
4457
+ borderRadius: "rounded-full",
4458
+ border: { widthClass: "border" },
4459
+ effects: { hover: [{
4460
+ effectId: "background-on-hover",
4461
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
4462
+ }] }
4463
+ }
4464
+ },
4465
+ outline: {
4466
+ kind: "complete",
4467
+ appearance: {
4468
+ background: {
4469
+ type: "surface",
4470
+ role: "link"
4471
+ },
4472
+ borderRadius: "rounded-full",
4473
+ border: { widthClass: "border" },
4474
+ effects: { hover: [{
4475
+ effectId: "background-on-hover",
4476
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
4477
+ }] }
4478
+ }
4479
+ },
4480
+ ghost: {
4481
+ kind: "complete",
4482
+ appearance: {
4483
+ background: {
4484
+ type: "surface",
4485
+ role: "link"
4486
+ },
4487
+ borderRadius: "rounded-full",
4488
+ shadow: {
4489
+ elevation: "none",
4490
+ softness: null,
4491
+ position: "bottom"
4492
+ },
4493
+ sizes: {
4494
+ sm: {
4495
+ padding: "0.25rem 0",
4496
+ fontSize: "text-sm"
4497
+ },
4498
+ md: { padding: "0.375rem 0" },
4499
+ lg: {
4500
+ padding: "0.5rem 0",
4501
+ fontSize: "text-lg"
4502
+ },
4503
+ xl: {
4504
+ padding: "0.625rem 0",
4505
+ fontSize: "text-xl"
4506
+ }
4507
+ }
4508
+ }
4509
+ },
4510
+ accent: {
4511
+ kind: "derive",
4512
+ from: "primary",
4513
+ overrides: { background: {
4514
+ type: "solid",
4515
+ colorToken: "accent"
4516
+ } }
4517
+ }
4518
+ }
4519
+ }
4520
+ });
4521
+ const confidentChipRecipe = defineStaticButtonStyleRecipe({
4522
+ id: "confident-chip",
4523
+ accessibilityLabel: "Moderately rounded solid buttons with a crisp hover",
4524
+ tags: {
4525
+ tone: "classic",
4526
+ energy: "calm",
4527
+ motion: "standard",
4528
+ era: "modern"
4529
+ },
4530
+ system: {
4531
+ global: {
4532
+ cornerStyle: "rounded",
4533
+ shadow: "medium",
4534
+ textTransform: "none",
4535
+ fontWeight: 600,
4536
+ hoverTransform: "none",
4537
+ hoverColor: "none"
4538
+ },
4539
+ roles: {
4540
+ primary: {
4541
+ kind: "complete",
4542
+ appearance: {
4543
+ background: {
4544
+ type: "solid",
4545
+ colorToken: "primary"
4546
+ },
4547
+ borderRadius: "rounded-md",
4548
+ shadow: {
4549
+ elevation: "medium",
4550
+ softness: "soft",
4551
+ position: "bottom"
4552
+ },
4553
+ effects: {
4554
+ hover: [{
4555
+ effectId: "darken-background",
4556
+ options: { amount: 100 }
4557
+ }],
4558
+ active: [{
4559
+ effectId: "scale-down",
4560
+ options: { scale: "0.97" }
4561
+ }]
4562
+ }
4563
+ }
4564
+ },
4565
+ secondary: {
4566
+ kind: "complete",
4567
+ appearance: {
4568
+ background: {
4569
+ type: "solid",
4570
+ colorToken: "surface"
4571
+ },
4572
+ borderRadius: "rounded-md",
4573
+ border: { widthClass: "border" },
4574
+ effects: { hover: [{
4575
+ effectId: "background-on-hover",
4576
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
4577
+ }] }
4578
+ }
4579
+ },
4580
+ outline: {
4581
+ kind: "complete",
4582
+ appearance: {
4583
+ background: {
4584
+ type: "surface",
4585
+ role: "link"
4586
+ },
4587
+ borderRadius: "rounded-md",
4588
+ border: { widthClass: "border" },
4589
+ effects: { hover: [{
4590
+ effectId: "background-on-hover",
4591
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4592
+ }] }
4593
+ }
4594
+ },
4595
+ ghost: {
4596
+ kind: "complete",
4597
+ appearance: {
4598
+ background: {
4599
+ type: "surface",
4600
+ role: "link"
4601
+ },
4602
+ borderRadius: "rounded-md",
4603
+ effects: { hover: [{
4604
+ effectId: "background-on-hover",
4605
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4606
+ }] }
4607
+ }
4608
+ },
4609
+ accent: {
4610
+ kind: "derive",
4611
+ from: "primary",
4612
+ overrides: { background: {
4613
+ type: "solid",
4614
+ colorToken: "accent"
4615
+ } }
4616
+ }
4617
+ }
4618
+ }
4619
+ });
4620
+ const editorialSizes = {
4621
+ sm: { padding: "0.25rem 0" },
4622
+ md: { padding: "0.5rem 0" },
4623
+ lg: { padding: "0.625rem 0" },
4624
+ xl: { padding: "0.75rem 0" }
4625
+ };
4626
+ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
4627
+ id: "editorial-link",
4628
+ accessibilityLabel: "Flat typographic buttons with an underline treatment",
4629
+ tags: {
4630
+ tone: "minimal",
4631
+ energy: "calm",
4632
+ motion: "subtle",
4633
+ era: "editorial"
4634
+ },
4635
+ system: {
4636
+ global: {
4637
+ cornerStyle: "square",
4638
+ textTransform: "none",
4639
+ fontWeight: 500,
4640
+ hoverTransform: "none",
4641
+ hoverColor: "none"
4642
+ },
4643
+ roles: {
4644
+ primary: {
4645
+ kind: "complete",
4646
+ appearance: {
4647
+ background: {
4648
+ type: "surface",
4649
+ role: "link"
4650
+ },
4651
+ borderRadius: "rounded-none",
4652
+ sizes: editorialSizes,
4653
+ effects: { base: [{
4654
+ effectId: "border-bottom-grow",
4655
+ options: {
4656
+ height: 2,
4657
+ origin: "left"
4658
+ }
4659
+ }] }
4660
+ }
4661
+ },
4662
+ secondary: {
4663
+ kind: "complete",
4664
+ appearance: {
4665
+ background: {
4666
+ type: "surface",
4667
+ role: "link"
4668
+ },
4669
+ borderRadius: "rounded-none",
4670
+ sizes: editorialSizes,
4671
+ effects: { base: [{
4672
+ effectId: "border-bottom-grow",
4673
+ options: {
4674
+ height: 1,
4675
+ origin: "left"
4676
+ }
4677
+ }] }
4678
+ }
4679
+ },
4680
+ outline: {
4681
+ kind: "complete",
4682
+ appearance: {
4683
+ background: {
4684
+ type: "surface",
4685
+ role: "link"
4686
+ },
4687
+ borderRadius: "rounded-none",
4688
+ sizes: editorialSizes,
4689
+ effects: { base: [{
4690
+ effectId: "border-bottom-grow",
4691
+ options: {
4692
+ height: 1,
4693
+ origin: "left"
4694
+ }
4695
+ }] }
4696
+ }
4697
+ },
4698
+ ghost: {
4699
+ kind: "complete",
4700
+ appearance: {
4701
+ background: {
4702
+ type: "surface",
4703
+ role: "link"
4704
+ },
4705
+ borderRadius: "rounded-none",
4706
+ sizes: editorialSizes
4707
+ }
4708
+ },
4709
+ accent: {
4710
+ kind: "derive",
4711
+ from: "primary",
4712
+ overrides: { effects: { base: [{
4713
+ effectId: "border-bottom-grow",
4714
+ options: {
4715
+ height: 2,
4716
+ origin: "left"
4717
+ }
4718
+ }] } }
4719
+ }
4720
+ }
4721
+ }
4722
+ });
4723
+ const pebbleRecipe = defineStaticButtonStyleRecipe({
4724
+ id: "pebble",
4725
+ accessibilityLabel: "Generously padded pill buttons",
4726
+ tags: {
4727
+ tone: "classic",
4728
+ energy: "calm",
4729
+ motion: "standard",
4730
+ era: "organic"
4731
+ },
4732
+ system: {
4733
+ global: {
4734
+ cornerStyle: "pill",
4735
+ textTransform: "none",
4736
+ fontWeight: 500,
4737
+ hoverTransform: "none",
4738
+ hoverColor: "none"
4739
+ },
4740
+ sizes: {
4741
+ sm: {
4742
+ padding: "0.625rem 1.75rem",
4743
+ fontSize: "text-sm"
4744
+ },
4745
+ md: { padding: "0.875rem 2.25rem" },
4746
+ lg: {
4747
+ padding: "1.125rem 2.75rem",
4748
+ fontSize: "text-lg"
4749
+ },
4750
+ xl: {
4751
+ padding: "1.5rem 3.5rem",
4752
+ fontSize: "text-xl"
4753
+ }
4754
+ },
4755
+ roles: {
4756
+ primary: {
4757
+ kind: "complete",
4758
+ appearance: {
4759
+ background: {
4760
+ type: "solid",
4761
+ colorToken: "primary"
4762
+ },
4763
+ borderRadius: "rounded-full",
4764
+ effects: { hover: [{
4765
+ effectId: "darken-background",
4766
+ options: { amount: 100 }
4767
+ }] }
4768
+ }
4769
+ },
4770
+ secondary: {
4771
+ kind: "complete",
4772
+ appearance: {
4773
+ background: {
4774
+ type: "surface",
4775
+ role: "link"
4776
+ },
4777
+ borderRadius: "rounded-full",
4778
+ border: { widthClass: "border-2" },
4779
+ effects: { hover: [{
4780
+ effectId: "background-on-hover",
4781
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
4782
+ }] }
4783
+ }
4784
+ },
4785
+ outline: {
4786
+ kind: "complete",
4787
+ appearance: {
4788
+ background: {
4789
+ type: "surface",
4790
+ role: "link"
4791
+ },
4792
+ borderRadius: "rounded-full",
4793
+ border: { widthClass: "border" },
4794
+ effects: { hover: [{
4795
+ effectId: "background-on-hover",
4796
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4797
+ }] }
4798
+ }
4799
+ },
4800
+ ghost: {
4801
+ kind: "complete",
4802
+ appearance: {
4803
+ background: {
4804
+ type: "surface",
4805
+ role: "link"
4806
+ },
4807
+ borderRadius: "rounded-full",
4808
+ sizes: {
4809
+ sm: {
4810
+ padding: "0.375rem 0.875rem",
4811
+ fontSize: "text-sm"
4812
+ },
4813
+ md: { padding: "0.5rem 1rem" },
4814
+ lg: {
4815
+ padding: "0.625rem 1.25rem",
4816
+ fontSize: "text-lg"
4817
+ },
4818
+ xl: {
4819
+ padding: "0.75rem 1.5rem",
4820
+ fontSize: "text-xl"
4821
+ }
4822
+ }
4823
+ }
4824
+ },
4825
+ accent: {
4826
+ kind: "derive",
4827
+ from: "primary",
4828
+ overrides: { background: {
4829
+ type: "solid",
4830
+ colorToken: "accent"
4831
+ } }
4832
+ }
4833
+ }
4834
+ }
4835
+ });
4836
+ const brushedWashRecipe = defineStaticButtonStyleRecipe({
4837
+ id: "brushed-wash",
4838
+ accessibilityLabel: "Generously padded gradient buttons with soft shadows",
4839
+ tags: {
4840
+ tone: "classic",
4841
+ energy: "vibrant",
4842
+ motion: "standard",
4843
+ era: "organic"
4844
+ },
4845
+ system: {
4846
+ global: {
4847
+ cornerStyle: "rounded",
4848
+ shadow: "low",
4849
+ textTransform: "none",
4850
+ fontWeight: 500,
4851
+ hoverTransform: "none",
4852
+ hoverColor: "none"
4853
+ },
4854
+ sizes: {
4855
+ sm: {
4856
+ padding: "0.75rem 2rem",
4857
+ fontSize: "text-sm"
4858
+ },
4859
+ md: { padding: "1rem 2.5rem" },
4860
+ lg: {
4861
+ padding: "1.25rem 3rem",
4862
+ fontSize: "text-lg"
4863
+ },
4864
+ xl: {
4865
+ padding: "1.625rem 3.75rem",
4866
+ fontSize: "text-xl"
4867
+ }
4868
+ },
4869
+ roles: {
4870
+ primary: {
4871
+ kind: "complete",
4872
+ appearance: {
4873
+ background: {
4874
+ type: "gradient",
4875
+ stops: ["primary", "accent"],
4876
+ direction: "to-r",
4877
+ foregroundToken: "primaryForeground"
4878
+ },
4879
+ borderRadius: "rounded-lg",
4880
+ shadow: {
4881
+ elevation: "low",
4882
+ softness: "soft",
4883
+ position: "bottom"
4884
+ }
4885
+ }
4886
+ },
4887
+ secondary: {
4888
+ kind: "complete",
4889
+ appearance: {
4890
+ background: {
4891
+ type: "gradient",
4892
+ stops: ["secondary", "accent"],
4893
+ direction: "to-br",
4894
+ foregroundToken: "primaryForeground"
4895
+ },
4896
+ borderRadius: "rounded-lg",
4897
+ shadow: {
4898
+ elevation: "low",
4899
+ softness: "soft",
4900
+ position: "bottom"
4901
+ }
4902
+ }
4903
+ },
4904
+ outline: {
4905
+ kind: "complete",
4906
+ appearance: {
4907
+ background: {
4908
+ type: "surface",
4909
+ role: "link"
4910
+ },
4911
+ borderRadius: "rounded-lg",
4912
+ border: { widthClass: "border" },
4913
+ effects: { hover: [{
4914
+ effectId: "background-on-hover",
4915
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4916
+ }] }
4917
+ }
4918
+ },
4919
+ ghost: {
4920
+ kind: "complete",
4921
+ appearance: {
4922
+ background: {
4923
+ type: "surface",
4924
+ role: "link"
4925
+ },
4926
+ borderRadius: "rounded-lg",
4927
+ effects: { hover: [{
4928
+ effectId: "background-on-hover",
4929
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4930
+ }] }
4931
+ }
4932
+ },
4933
+ accent: {
4934
+ kind: "derive",
4935
+ from: "primary",
4936
+ overrides: { background: {
4937
+ type: "solid",
4938
+ colorToken: "accent"
4939
+ } }
4940
+ }
4941
+ }
4942
+ }
4943
+ });
4944
+ const inkStampRecipe = defineStaticButtonStyleRecipe({
4945
+ id: "ink-stamp",
4946
+ accessibilityLabel: "Uppercase block-print buttons with a playful hover",
4947
+ tags: {
4948
+ tone: "bold",
4949
+ energy: "vibrant",
4950
+ motion: "standard",
4951
+ era: "organic"
4952
+ },
4953
+ system: {
4954
+ global: {
4955
+ cornerStyle: "rounded",
4956
+ textTransform: "uppercase",
4957
+ fontWeight: 600,
4958
+ hoverTransform: "none",
4959
+ hoverColor: "none",
4960
+ letterSpacing: "loose"
4961
+ },
4962
+ sizes: {
4963
+ sm: {
4964
+ padding: "0.5rem 1.25rem",
4965
+ fontSize: "text-xs"
4966
+ },
4967
+ md: {
4968
+ padding: "0.75rem 1.75rem",
4969
+ fontSize: "text-sm"
4970
+ },
4971
+ lg: {
4972
+ padding: "0.875rem 2.25rem",
4973
+ fontSize: "text-base"
4974
+ },
4975
+ xl: {
4976
+ padding: "1.125rem 2.75rem",
4977
+ fontSize: "text-lg"
4978
+ }
4979
+ },
4980
+ roles: {
4981
+ primary: {
4982
+ kind: "complete",
4983
+ appearance: {
4984
+ background: {
4985
+ type: "solid",
4986
+ colorToken: "primary"
4987
+ },
4988
+ borderRadius: "rounded-md",
4989
+ effects: {
4990
+ hover: [{
4991
+ effectId: "drop-shadow",
4992
+ options: { intensity: "medium" }
4993
+ }, {
4994
+ effectId: "scale-up",
4995
+ options: { scale: "1.02" }
4996
+ }],
4997
+ active: [{
4998
+ effectId: "scale-down",
4999
+ options: { scale: "0.98" }
5000
+ }]
5001
+ }
5002
+ }
5003
+ },
5004
+ secondary: {
5005
+ kind: "complete",
5006
+ appearance: {
5007
+ background: {
5008
+ type: "surface",
5009
+ role: "link"
5010
+ },
5011
+ borderRadius: "rounded-md",
5012
+ border: { widthClass: "border-2" },
5013
+ effects: { hover: [{
5014
+ effectId: "background-on-hover",
5015
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
5016
+ }] }
5017
+ }
5018
+ },
5019
+ outline: {
5020
+ kind: "complete",
5021
+ appearance: {
5022
+ background: {
5023
+ type: "surface",
5024
+ role: "link"
5025
+ },
5026
+ borderRadius: "rounded-md",
5027
+ border: { widthClass: "border-2" },
5028
+ effects: { hover: [{
5029
+ effectId: "background-on-hover",
5030
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
5031
+ }] }
5032
+ }
5033
+ },
5034
+ ghost: {
5035
+ kind: "complete",
5036
+ appearance: {
5037
+ background: {
5038
+ type: "surface",
5039
+ role: "link"
5040
+ },
5041
+ borderRadius: "rounded-none",
5042
+ sizes: {
5043
+ sm: {
5044
+ padding: "0.375rem 0",
5045
+ fontSize: "text-xs"
5046
+ },
5047
+ md: {
5048
+ padding: "0.5rem 0",
5049
+ fontSize: "text-sm"
5050
+ },
5051
+ lg: {
5052
+ padding: "0.625rem 0",
5053
+ fontSize: "text-base"
5054
+ },
5055
+ xl: {
5056
+ padding: "0.75rem 0",
5057
+ fontSize: "text-lg"
5058
+ }
5059
+ },
5060
+ effects: { base: [{
5061
+ effectId: "border-bottom-grow",
5062
+ options: {
5063
+ height: 1,
5064
+ origin: "left"
5065
+ }
5066
+ }] }
5067
+ }
5068
+ },
5069
+ accent: {
5070
+ kind: "derive",
5071
+ from: "primary",
5072
+ overrides: { background: {
5073
+ type: "solid",
5074
+ colorToken: "accent"
5075
+ } }
5076
+ }
5077
+ }
5078
+ }
5079
+ });
5080
+ const flatInkRecipe = defineStaticButtonStyleRecipe({
5081
+ id: "flat-ink",
5082
+ accessibilityLabel: "Flat rounded buttons with arrow affordances",
5083
+ tags: {
5084
+ tone: "classic",
5085
+ energy: "calm",
5086
+ motion: "subtle",
5087
+ era: "editorial"
5088
+ },
5089
+ system: {
5090
+ global: {
5091
+ cornerStyle: "rounded",
5092
+ textTransform: "none",
5093
+ fontWeight: 600,
5094
+ typography: "body",
5095
+ letterSpacing: "tight",
5096
+ paddingPreset: "default",
5097
+ hoverTransform: "lift",
5098
+ hoverColor: "none"
5099
+ },
5100
+ sizes: {
5101
+ sm: {
5102
+ padding: "0.625rem 1.125rem",
5103
+ fontSize: "text-sm"
5104
+ },
5105
+ md: { padding: "0.8125rem 1.375rem" },
5106
+ lg: {
5107
+ padding: "0.9375rem 1.625rem",
5108
+ fontSize: "text-lg"
5109
+ },
5110
+ xl: {
5111
+ padding: "1.0625rem 2rem",
5112
+ fontSize: "text-xl"
5113
+ }
5114
+ },
5115
+ roles: {
5116
+ primary: {
5117
+ kind: "complete",
5118
+ appearance: {
5119
+ background: {
5120
+ type: "solid",
5121
+ colorToken: "primary"
5122
+ },
5123
+ borderRadius: "rounded-lg",
5124
+ affordance: { iconId: "ArrowRight" },
5125
+ effects: { hover: [{ effectId: "lift" }, {
5126
+ effectId: "background-on-hover",
5127
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("secondary") }
5128
+ }] }
5129
+ }
5130
+ },
5131
+ secondary: {
5132
+ kind: "complete",
5133
+ appearance: {
5134
+ background: {
5135
+ type: "surface",
5136
+ role: "link"
5137
+ },
5138
+ borderRadius: "rounded-lg",
5139
+ border: { widthClass: "border" },
5140
+ effects: { hover: [{ effectId: "lift" }, {
5141
+ effectId: "background-on-hover",
5142
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
5143
+ }] }
5144
+ }
5145
+ },
5146
+ outline: {
5147
+ kind: "complete",
5148
+ appearance: {
5149
+ background: {
5150
+ type: "surface",
5151
+ role: "link"
5152
+ },
5153
+ borderRadius: "rounded-lg",
5154
+ border: { widthClass: "border" },
5155
+ effects: { hover: [{ effectId: "lift" }, {
5156
+ effectId: "background-on-hover",
5157
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
5158
+ }] }
5159
+ }
5160
+ },
5161
+ ghost: {
5162
+ kind: "complete",
5163
+ appearance: {
5164
+ background: {
5165
+ type: "surface",
5166
+ role: "link"
5167
+ },
5168
+ borderRadius: "rounded-lg",
5169
+ effects: { hover: [{ effectId: "lift" }] }
5170
+ }
5171
+ },
5172
+ accent: {
5173
+ kind: "complete",
5174
+ appearance: {
5175
+ background: {
5176
+ type: "solid",
5177
+ colorToken: "accent"
5178
+ },
5179
+ borderRadius: "rounded-lg",
5180
+ affordance: { iconId: "ArrowRight" },
5181
+ effects: { hover: [{ effectId: "lift" }] }
5182
+ }
5183
+ }
5184
+ }
5185
+ }
5186
+ });
5187
+ const showtimePillRecipe = defineStaticButtonStyleRecipe({
5188
+ id: "showtime-pill",
5189
+ accessibilityLabel: "Bold uppercase pill buttons with playful movement",
5190
+ tags: {
5191
+ tone: "bold",
5192
+ energy: "vibrant",
5193
+ motion: "expressive",
5194
+ era: "modern"
5195
+ },
5196
+ system: {
5197
+ global: {
5198
+ cornerStyle: "pill",
5199
+ shadow: "low",
5200
+ textTransform: "uppercase",
5201
+ fontWeight: 700,
5202
+ hoverTransform: "lift",
5203
+ hoverColor: "none",
5204
+ typography: "body",
5205
+ paddingPreset: "spacious",
5206
+ italic: false
5207
+ },
5208
+ sizes: {
5209
+ sm: {
5210
+ padding: "0.625rem 1.25rem",
5211
+ fontSize: "0.875rem"
5212
+ },
5213
+ md: {
5214
+ padding: "0.875rem 1.75rem",
5215
+ fontSize: "1rem"
5216
+ },
5217
+ lg: {
5218
+ padding: "1.125rem 2.25rem",
5219
+ fontSize: "1.125rem"
5220
+ },
5221
+ xl: {
5222
+ padding: "1.125rem 2.25rem",
5223
+ fontSize: "1.125rem"
5224
+ }
5225
+ },
5226
+ roles: {
5227
+ primary: {
5228
+ kind: "complete",
5229
+ appearance: {
5230
+ background: {
5231
+ type: "solid",
5232
+ colorToken: "primary"
5233
+ },
5234
+ borderRadius: "rounded-full",
5235
+ effects: { hover: [{ effectId: "pop" }] }
5236
+ }
5237
+ },
5238
+ secondary: {
5239
+ kind: "complete",
5240
+ appearance: {
5241
+ background: {
5242
+ type: "surface",
5243
+ role: "link"
5244
+ },
5245
+ borderRadius: "rounded-full",
5246
+ border: { widthClass: "border-2" },
5247
+ effects: { hover: [{ effectId: "pop" }] }
5248
+ }
5249
+ },
5250
+ outline: {
5251
+ kind: "complete",
5252
+ appearance: {
5253
+ background: {
5254
+ type: "surface",
5255
+ role: "link"
5256
+ },
5257
+ borderRadius: "rounded-full",
5258
+ border: { widthClass: "border-2" },
5259
+ effects: { hover: [{
5260
+ effectId: "background-on-hover",
5261
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
5262
+ }] }
5263
+ }
5264
+ },
5265
+ ghost: {
5266
+ kind: "complete",
5267
+ appearance: {
5268
+ background: {
5269
+ type: "surface",
5270
+ role: "link"
5271
+ },
5272
+ borderRadius: "rounded-full",
5273
+ effects: { hover: [{
5274
+ effectId: "background-on-hover",
5275
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
5276
+ }] }
5277
+ }
5278
+ },
5279
+ accent: {
5280
+ kind: "complete",
5281
+ appearance: {
5282
+ background: {
5283
+ type: "solid",
5284
+ colorToken: "secondary"
5285
+ },
5286
+ borderRadius: "rounded-full",
5287
+ effects: { hover: [{ effectId: "pop" }] }
5288
+ }
5289
+ }
5290
+ }
5291
+ }
5292
+ });
5293
+ const joyStampRecipe = defineStaticButtonStyleRecipe({
5294
+ id: "joy-stamp",
5295
+ accessibilityLabel: "Bold pill buttons with a hard offset shadow",
5296
+ tags: {
5297
+ tone: "bold",
5298
+ energy: "vibrant",
5299
+ motion: "expressive",
5300
+ era: "organic"
5301
+ },
5302
+ system: {
5303
+ global: {
5304
+ cornerStyle: "pill",
5305
+ shadow: "high",
5306
+ textTransform: "none",
5307
+ typography: "heading",
5308
+ fontWeight: 700,
5309
+ fontSize: "text-lg",
5310
+ hoverTransform: "none",
5311
+ hoverColor: "none"
5312
+ },
5313
+ sizes: {
5314
+ sm: {
5315
+ padding: "0.625rem 1.25rem",
5316
+ fontSize: "text-base"
5317
+ },
5318
+ md: {
5319
+ padding: "0.875rem 1.75rem",
5320
+ fontSize: "text-lg"
5321
+ },
5322
+ lg: {
5323
+ padding: "1.125rem 2.25rem",
5324
+ fontSize: "text-xl"
5325
+ },
5326
+ xl: {
5327
+ padding: "1.25rem 2.75rem",
5328
+ fontSize: "text-2xl"
5329
+ }
5330
+ },
5331
+ roles: {
5332
+ primary: {
5333
+ kind: "complete",
5334
+ appearance: {
5335
+ background: {
5336
+ type: "solid",
5337
+ colorToken: "primary"
5338
+ },
5339
+ borderRadius: "rounded-full",
5340
+ shadow: {
5341
+ elevation: "high",
5342
+ softness: "hard",
5343
+ position: "bottom-right",
5344
+ colorToken: unsafeAsOpaqueButtonColourToken("text")
5345
+ },
5346
+ effects: { hover: [{ effectId: "press-down" }] }
5347
+ }
5348
+ },
5349
+ secondary: {
5350
+ kind: "complete",
5351
+ appearance: {
5352
+ background: {
5353
+ type: "surface",
5354
+ role: "link"
5355
+ },
5356
+ borderRadius: "rounded-full",
5357
+ border: { widthClass: "border-2" },
5358
+ shadow: {
5359
+ elevation: "high",
5360
+ softness: "hard",
5361
+ position: "bottom-right",
5362
+ colorToken: unsafeAsOpaqueButtonColourToken("secondary")
5363
+ },
5364
+ effects: { hover: [{ effectId: "press-down" }] }
5365
+ }
5366
+ },
5367
+ outline: {
5368
+ kind: "derive",
5369
+ from: "secondary"
5370
+ },
5371
+ ghost: {
5372
+ kind: "complete",
5373
+ appearance: {
5374
+ background: {
5375
+ type: "surface",
5376
+ role: "link"
5377
+ },
5378
+ borderRadius: "rounded-full",
5379
+ effects: { hover: [{ effectId: "press-down" }] }
5380
+ }
5381
+ },
5382
+ accent: {
5383
+ kind: "derive",
5384
+ from: "primary",
5385
+ overrides: { background: {
5386
+ type: "solid",
5387
+ colorToken: "accent"
5388
+ } }
5389
+ }
5390
+ }
5391
+ }
5392
+ });
5393
+ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
5394
+ id: "ornate-ritual",
5395
+ accessibilityLabel: "Uppercase framed buttons with restrained movement",
5396
+ tags: {
5397
+ tone: "classic",
5398
+ energy: "vibrant",
5399
+ motion: "subtle",
5400
+ era: "organic"
5401
+ },
5402
+ system: {
5403
+ global: {
5404
+ cornerStyle: "rounded",
5405
+ textTransform: "uppercase",
5406
+ fontWeight: 600,
5407
+ hoverTransform: "none",
5408
+ hoverColor: "none",
5409
+ letterSpacing: "loose"
5410
+ },
5411
+ sizes: {
5412
+ sm: {
5413
+ padding: "0.5625rem 1.25rem",
5414
+ fontSize: "text-xs"
5415
+ },
5416
+ md: {
5417
+ padding: "0.75rem 1.75rem",
5418
+ fontSize: "text-xs"
5419
+ },
5420
+ lg: {
5421
+ padding: "0.875rem 2.25rem",
5422
+ fontSize: "text-sm"
5423
+ },
5424
+ xl: {
5425
+ padding: "1rem 2.75rem",
5426
+ fontSize: "text-base"
5427
+ }
5428
+ },
5429
+ roles: {
5430
+ primary: {
5431
+ kind: "complete",
5432
+ appearance: {
5433
+ background: {
5434
+ type: "solid",
5435
+ colorToken: "primary"
5436
+ },
5437
+ borderRadius: "rounded-md",
5438
+ border: { widthClass: "border" },
5439
+ effects: {
5440
+ hover: [{
5441
+ effectId: "background-on-hover",
5442
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("primary-100") }
5443
+ }],
5444
+ active: [{
5445
+ effectId: "scale-down",
5446
+ options: { scale: "0.98" }
5447
+ }]
5448
+ }
5449
+ }
5450
+ },
5451
+ secondary: {
5452
+ kind: "complete",
5453
+ appearance: {
5454
+ background: {
5455
+ type: "solid",
5456
+ colorToken: "secondary"
5457
+ },
5458
+ borderRadius: "rounded-md",
5459
+ border: { widthClass: "border" },
5460
+ effects: { hover: [{
5461
+ effectId: "background-on-hover",
5462
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
5463
+ }] }
5464
+ }
5465
+ },
5466
+ outline: {
5467
+ kind: "complete",
5468
+ appearance: {
5469
+ background: {
5470
+ type: "surface",
5471
+ role: "link"
5472
+ },
5473
+ borderRadius: "rounded-md",
5474
+ border: { widthClass: "border" },
5475
+ effects: { hover: [{
5476
+ effectId: "background-on-hover",
5477
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
5478
+ }] }
5479
+ }
5480
+ },
5481
+ ghost: {
5482
+ kind: "complete",
5483
+ appearance: {
5484
+ background: {
5485
+ type: "surface",
5486
+ role: "link"
5487
+ },
5488
+ borderRadius: "rounded-none",
5489
+ sizes: {
5490
+ sm: {
5491
+ padding: "0.375rem 0",
5492
+ fontSize: "text-xs"
5493
+ },
5494
+ md: {
5495
+ padding: "0.5rem 0",
5496
+ fontSize: "text-sm"
5497
+ },
5498
+ lg: {
5499
+ padding: "0.625rem 0",
5500
+ fontSize: "text-base"
5501
+ },
5502
+ xl: {
5503
+ padding: "0.75rem 0",
5504
+ fontSize: "text-lg"
5505
+ }
5506
+ },
5507
+ effects: { base: [{
5508
+ effectId: "border-bottom-grow",
5509
+ options: {
5510
+ height: 1,
5511
+ origin: "left"
5512
+ }
5513
+ }] }
5514
+ }
5515
+ },
5516
+ accent: {
5517
+ kind: "derive",
5518
+ from: "primary",
5519
+ overrides: { background: {
5520
+ type: "solid",
5521
+ colorToken: "accent"
5522
+ } }
5523
+ }
5524
+ }
5525
+ }
5526
+ });
5527
+ //#endregion
5528
+ //#region ../theme-core/src/buttons/styles/registry.ts
5529
+ const buttonStyleRecipes = [
5530
+ softPillRecipe,
5531
+ earthPillRecipe,
5532
+ confidentChipRecipe,
5533
+ editorialLinkRecipe,
5534
+ pebbleRecipe,
5535
+ inkStampRecipe,
5536
+ flatInkRecipe,
5537
+ brushedWashRecipe,
5538
+ showtimePillRecipe,
5539
+ joyStampRecipe,
5540
+ ornateRitualRecipe,
5541
+ quietArrowRecipe
5542
+ ];
5543
+ const recipesById = new Map(buttonStyleRecipes.map((recipe) => [recipe.id, recipe]));
5544
+ function findButtonStyleRecipe(id) {
5545
+ const recipe = recipesById.get(id);
5546
+ if (recipe === void 0) throw new Error(`Button style registry is missing known style ${id}`);
5547
+ return recipe;
5548
+ }
5549
+ function resolveButtonStyleSelection(selection) {
5550
+ switch (selection.styleId) {
5551
+ case "soft-pill": return resolveButtonStyleRecipe(softPillRecipe, selection.parameters);
5552
+ case "earth-pill": return resolveButtonStyleRecipe(earthPillRecipe, selection.parameters);
5553
+ case "confident-chip": return resolveButtonStyleRecipe(confidentChipRecipe, selection.parameters);
5554
+ case "editorial-link": return resolveButtonStyleRecipe(editorialLinkRecipe, selection.parameters);
5555
+ case "pebble": return resolveButtonStyleRecipe(pebbleRecipe, selection.parameters);
5556
+ case "ink-stamp": return resolveButtonStyleRecipe(inkStampRecipe, selection.parameters);
5557
+ case "flat-ink": return resolveButtonStyleRecipe(flatInkRecipe, selection.parameters);
5558
+ case "brushed-wash": return resolveButtonStyleRecipe(brushedWashRecipe, selection.parameters);
5559
+ case "showtime-pill": return resolveButtonStyleRecipe(showtimePillRecipe, selection.parameters);
5560
+ case "joy-stamp": return resolveButtonStyleRecipe(joyStampRecipe, selection.parameters);
5561
+ case "ornate-ritual": return resolveButtonStyleRecipe(ornateRitualRecipe, selection.parameters);
5562
+ case "quiet-arrow": return resolveButtonStyleRecipe(quietArrowRecipe, selection.parameters);
5563
+ }
5564
+ }
5565
+ function defaultButtonStyleSelectionFor(styleId) {
5566
+ return {
5567
+ styleId,
5568
+ parameters: findButtonStyleRecipe(styleId).defaultParameters
5569
+ };
5570
+ }
5571
+ if (buttonStyleRecipes.map((recipe) => recipe.id).length !== BUTTON_STYLE_IDS.length || BUTTON_STYLE_IDS.some((id) => !recipesById.has(id))) throw new Error("Button style registry and ButtonStyleId catalog are out of sync");
5572
+ buttonStyleRecipes.map((recipe) => {
5573
+ const resolved = resolveButtonStyleSelection(defaultButtonStyleSelectionFor(recipe.id));
5574
+ if (resolved.kind === "error") throw new Error(`Invalid registered button style ${recipe.id}: ${resolved.error.issues.join(", ")}`);
5575
+ return {
5576
+ id: recipe.id,
5577
+ name: recipe.accessibilityLabel,
5578
+ description: recipe.accessibilityLabel,
5579
+ category: presetCategory(recipe),
5580
+ buttonSystem: resolved.buttonSystem,
5581
+ compatibility: {
5582
+ ...recipe.tags.tone ? { tones: [recipe.tags.tone] } : {},
5583
+ ...recipe.tags.energy ? { energies: [recipe.tags.energy] } : {}
5584
+ }
5585
+ };
5586
+ });
5587
+ function presetCategory(recipe) {
5588
+ switch (recipe.tags.era) {
5589
+ case "retro": return "retro";
5590
+ case "editorial": return "minimal";
5591
+ case "organic": return "artistic";
5592
+ case "modern": return recipe.tags.tone === "bold" ? "modern" : "technical";
5593
+ case "technical": return "technical";
5594
+ case void 0: return "modern";
5595
+ }
5596
+ }
5597
+ //#endregion
5598
+ //#region ../blocks/src/system/constants/buttonRoles.ts
5599
+ /**
5600
+ * Semantic button roles available to block authors.
5601
+ *
5602
+ * These roles are deliberately independent of a site's visual button style:
5603
+ * the active theme owns how each role looks.
5604
+ */
5605
+ const BLOCK_BUTTON_ROLES = PUBLIC_BUTTON_ROLES;
5606
+ const blockButtonRoleSchema = z$1.enum(BLOCK_BUTTON_ROLES);
5607
+ /**
5608
+ * Temporary rollout boundary for persisted content written before issue #1220.
5609
+ * Authoring remains strict through `blockButtonRoleSchema`; this parser exists
5610
+ * only until the post-deploy role rewrite has been audited in production.
5611
+ */
5612
+ function canonicalizePersistedBlockButtonRole(value) {
5613
+ return value === "link" || value === "tertiary" ? "ghost" : value;
5614
+ }
5615
+ const persistedBlockButtonRoleSchema = z$1.preprocess((value) => typeof value === "string" ? canonicalizePersistedBlockButtonRole(value) : value, blockButtonRoleSchema);
5616
+ const BLOCK_BUTTON_ROLE_LABELS = {
5617
+ primary: "Primary",
5618
+ secondary: "Secondary",
5619
+ outline: "Outline",
5620
+ ghost: "Ghost",
5621
+ accent: "Accent"
5622
+ };
5623
+ BLOCK_BUTTON_ROLES.map((value) => ({
5624
+ value,
5625
+ label: BLOCK_BUTTON_ROLE_LABELS[value]
5626
+ }));
5627
+ //#endregion
5628
+ //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
5629
+ const previewStageSchema = z$1.enum(["preview", "published"]);
5630
+ const registrationButtonVariantSchema = blockButtonRoleSchema;
5631
+ const eventButtonVariantSchema = persistedBlockButtonRoleSchema;
5632
+ const eventLayoutSchema = z$1.enum(eventCalendarListLayoutValues);
5633
+ const eventCalendarDisplayModeSchema = z$1.enum(eventCalendarDisplayModeValues);
5634
+ const eventCalendarDefaultViewSchema = z$1.enum(eventCalendarDefaultViewValues);
5635
+ const columnOptionSchema = z$1.enum([
5636
+ "2",
5637
+ "3",
5638
+ "4"
5639
+ ]);
5640
+ const weekStartSchema = z$1.enum(["sunday", "monday"]);
5641
+ const filterAutoShowSchema = z$1.enum([
5642
+ "auto",
5643
+ "always",
5644
+ "never"
5645
+ ]);
5646
+ const calendarTabViewsSchema = z$1.enum([
5647
+ "both",
5648
+ "month",
5649
+ "week"
5650
+ ]);
5651
+ const unsupportedEventRegistrationPageSurfaceSubjectSchema = z$1.object({
5652
+ kind: z$1.literal("unsupported"),
5653
+ reason: z$1.enum([
5654
+ "unsupportedSubject",
5655
+ "invalidEventSeriesId",
5656
+ "invalidEventOfferingId"
5657
+ ])
5658
+ });
5659
+ const eventRegistrationPageSurfaceSubjectSchema = z$1.unknown().transform((value, ctx) => {
5660
+ const unsupported = unsupportedEventRegistrationPageSurfaceSubjectSchema.safeParse(value);
5661
+ if (unsupported.success) return unsupported.data;
5662
+ const parsed = parseEventPageSurfaceSubject(value);
5663
+ if (parsed.ok) return parsed.value;
5664
+ ctx.addIssue({
5665
+ code: z$1.ZodIssueCode.custom,
5666
+ message: `Invalid event page-surface subject (${parsed.error.kind})`
5667
+ });
5668
+ return z$1.NEVER;
5669
+ });
5670
+ function resolveEventRegistrationScope(context) {
5671
+ const occurrenceSeriesId = context.occurrenceContext?.seriesId;
5672
+ if (occurrenceSeriesId) return {
5673
+ kind: "occurrenceSeries",
5674
+ seriesId: occurrenceSeriesId
5675
+ };
5676
+ if (context.subject?.kind === "eventSeries") return {
5677
+ kind: "pageSurfaceSeries",
5678
+ seriesId: context.subject.eventSeriesId
5679
+ };
5680
+ if (context.subject?.kind === "eventOffering") return {
5681
+ kind: "pageSurfaceOffering",
5682
+ offeringId: context.subject.eventOfferingId,
5683
+ seriesIds: context.subject.availableEventSeriesIds
5684
+ };
5685
+ if (context.subject?.kind === "unsupported") return {
5686
+ kind: "unsupportedPageSurfaceSubject",
5687
+ reason: context.subject.reason
5688
+ };
5689
+ const entrySlug = context.contentEntry?.slug;
5690
+ const entryContentType = context.contentEntry?.contentTypeSlug;
5691
+ if (entrySlug && entryContentType && isEventContentType(entryContentType)) return {
5692
+ kind: "legacyEventSlug",
5693
+ slug: entrySlug
5694
+ };
5695
+ return { kind: "unscoped" };
5696
+ }
5697
+ function applyEventRegistrationScope(events, scope) {
5698
+ switch (scope.kind) {
5699
+ case "occurrenceSeries":
5700
+ case "pageSurfaceSeries": return events.filter((event) => event.seriesId === scope.seriesId);
5701
+ case "pageSurfaceOffering": {
5702
+ const seriesIds = new Set(scope.seriesIds);
5703
+ return events.filter((event) => seriesIds.has(event.seriesId));
5704
+ }
5705
+ case "legacyEventSlug": return events.filter((event) => event.slug === scope.slug);
5706
+ case "unsupportedPageSurfaceSubject": return [];
5707
+ case "unscoped": return [...events];
5708
+ }
5709
+ }
5710
+ function resolveEventRegistrationScopedEvents(events, context) {
5711
+ return applyEventRegistrationScope(events, resolveEventRegistrationScope(context));
1842
5712
  }
1843
- const cardBackgroundSchema = z$1.discriminatedUnion("type", [
1844
- z$1.object({
1845
- type: z$1.literal("solid"),
1846
- colorToken: themeColorTokenSchema
1847
- }),
1848
- z$1.object({
1849
- type: z$1.literal("gradient"),
1850
- fromToken: themeColorTokenSchema,
1851
- toToken: themeColorTokenSchema,
1852
- direction: gradientDirectionSchema
1853
- }),
1854
- z$1.object({ type: z$1.literal("transparent") })
1855
- ]);
1856
- const cardBorderSchema = z$1.object({
1857
- widthClass: z$1.string(),
1858
- colorToken: themeColorTokenSchema
5713
+ //#endregion
5714
+ //#region ../blocks/src/system/runtime/nodes/course-registration.interactive.ts
5715
+ const contentEntrySchema$2 = z$1.object({
5716
+ id: z$1.string(),
5717
+ slug: z$1.string(),
5718
+ contentTypeSlug: z$1.string()
1859
5719
  });
1860
- /** Per-corner radius value. `expressive` is a large block-radius multiple. */
1861
- const cardCornerValueSchema = z$1.enum([
1862
- "square",
1863
- "soft",
1864
- "rounded",
1865
- "pill",
1866
- "expressive"
1867
- ]);
1868
- /**
1869
- * A single accented card edge (e.g. a left accent bar). When set, it replaces
1870
- * the full `border` so the card reads as edge-accented rather than outlined.
1871
- */
1872
- const cardAccentEdgeSchema = z$1.object({
1873
- edge: z$1.enum([
1874
- "left",
1875
- "top",
1876
- "right",
1877
- "bottom"
1878
- ]),
1879
- colorToken: themeColorTokenSchema,
1880
- width: z$1.enum([
1881
- "thin",
1882
- "medium",
1883
- "thick",
1884
- "heavy"
1885
- ])
5720
+ const courseEntrySubrouteContextSchema = z$1.union([z$1.object({
5721
+ kind: z$1.literal("course-run"),
5722
+ run: z$1.object({
5723
+ courseId: z$1.string(),
5724
+ seriesId: z$1.string(),
5725
+ runSlug: z$1.string(),
5726
+ runName: z$1.string().nullable()
5727
+ })
5728
+ }), z$1.object({
5729
+ kind: z$1.literal("event-occurrence"),
5730
+ occurrence: occurrenceContextSchema$1
5731
+ })]);
5732
+ const courseRegistrationSourceSchema = z$1.object({
5733
+ siteId: z$1.string().optional(),
5734
+ apiBaseUrl: z$1.string().optional(),
5735
+ portalToken: z$1.string().nullable().optional(),
5736
+ contentEntry: contentEntrySchema$2.nullable().optional(),
5737
+ entrySubrouteContext: courseEntrySubrouteContextSchema.nullable().optional(),
5738
+ subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
5739
+ courses: z$1.array(publicCourseSchema).nullable().optional(),
5740
+ className: z$1.string().nullable().optional(),
5741
+ showSessions: z$1.boolean().optional(),
5742
+ showPrice: z$1.boolean().optional(),
5743
+ showCapacity: z$1.boolean().optional(),
5744
+ showVenue: z$1.boolean().optional(),
5745
+ successMessage: z$1.string().optional(),
5746
+ waitlistMessage: z$1.string().optional(),
5747
+ membershipMessage: z$1.string().optional(),
5748
+ buttonText: z$1.string().nullable().optional(),
5749
+ buttonVariant: registrationButtonVariantSchema.optional(),
5750
+ stage: previewStageSchema.optional()
1886
5751
  });
1887
- const cardCornerRadiiSchema = z$1.object({
1888
- topLeft: cardCornerValueSchema.optional(),
1889
- topRight: cardCornerValueSchema.optional(),
1890
- bottomLeft: cardCornerValueSchema.optional(),
1891
- bottomRight: cardCornerValueSchema.optional()
5752
+ const courseRegistrationDisplaySchema = z$1.object({
5753
+ kind: z$1.literal("course-registration"),
5754
+ state: z$1.literal("shell"),
5755
+ className: z$1.string().nullable(),
5756
+ summaryButtonText: z$1.string()
1892
5757
  });
1893
- const cardVariantSchema = z$1.object({
1894
- id: z$1.string(),
1895
- name: z$1.string().min(1).max(20),
1896
- enabled: z$1.boolean(),
1897
- priority: z$1.union([
1898
- z$1.literal(1),
1899
- z$1.literal(2),
1900
- z$1.literal(3)
1901
- ]),
1902
- background: cardBackgroundSchema,
1903
- spacing: cardSpacingSchema,
1904
- foregroundToken: themeColorTokenSchema.optional(),
1905
- shadow: z$1.object({
1906
- elevation: z$1.enum([
1907
- "none",
1908
- "low",
1909
- "medium",
1910
- "high"
1911
- ]),
1912
- softness: z$1.enum([
1913
- "crisp",
1914
- "soft",
1915
- "hard"
1916
- ]).nullable(),
1917
- position: z$1.enum(["bottom", "bottom-right"]).default("bottom")
1918
- }).optional(),
1919
- corners: z$1.enum([
1920
- "square",
1921
- "soft",
1922
- "rounded",
1923
- "pill"
1924
- ]).optional(),
1925
- cornerRadii: cardCornerRadiiSchema.optional(),
1926
- border: cardBorderSchema.optional(),
1927
- accentEdge: cardAccentEdgeSchema.optional()
5758
+ const courseRegistrationHydrationSchema = z$1.object({
5759
+ contentEntry: contentEntrySchema$2.nullable().optional(),
5760
+ entrySubrouteContext: courseEntrySubrouteContextSchema.nullable().optional(),
5761
+ subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
5762
+ courses: z$1.array(publicCourseSchema).nullable().optional(),
5763
+ showSessions: z$1.boolean().optional(),
5764
+ showPrice: z$1.boolean().optional(),
5765
+ showCapacity: z$1.boolean().optional(),
5766
+ showVenue: z$1.boolean().optional(),
5767
+ successMessage: z$1.string().optional(),
5768
+ waitlistMessage: z$1.string().optional(),
5769
+ membershipMessage: z$1.string().optional(),
5770
+ buttonVariant: registrationButtonVariantSchema.optional()
5771
+ });
5772
+ const courseRegistrationRenderSchema = z$1.object({
5773
+ display: courseRegistrationDisplaySchema,
5774
+ hydration: courseRegistrationHydrationSchema
5775
+ });
5776
+ const courseRegistrationIslandMetaCodec = createZodCodec(z$1.object({
5777
+ siteId: z$1.string().optional(),
5778
+ apiBaseUrl: z$1.string().optional(),
5779
+ portalToken: z$1.string().nullable().optional(),
5780
+ stage: previewStageSchema.optional()
5781
+ }));
5782
+ const courseRegistrationIslandMetaKeys = defineInteractiveIslandMetaKeys("siteId", "apiBaseUrl", "portalToken", "stage");
5783
+ function buildCourseRegistrationDisplay(source) {
5784
+ return {
5785
+ kind: "course-registration",
5786
+ state: "shell",
5787
+ className: source.className ?? null,
5788
+ summaryButtonText: source.buttonText?.trim() || "Sign up"
5789
+ };
5790
+ }
5791
+ const courseRegistrationInteractiveIslandPropsCodec = createInteractiveIslandCodec({
5792
+ runtime: defineClientOwnedBlockRuntime({
5793
+ kind: "client-owned",
5794
+ contracts: {
5795
+ source: createZodCodec(courseRegistrationSourceSchema),
5796
+ render: createZodCodec(courseRegistrationRenderSchema)
5797
+ },
5798
+ buildRender: (source) => ({
5799
+ display: buildCourseRegistrationDisplay(source),
5800
+ hydration: {
5801
+ contentEntry: source.contentEntry ?? null,
5802
+ entrySubrouteContext: source.entrySubrouteContext ?? null,
5803
+ subject: source.subject ?? null,
5804
+ courses: source.courses ?? null,
5805
+ showSessions: source.showSessions,
5806
+ showPrice: source.showPrice,
5807
+ showCapacity: source.showCapacity,
5808
+ showVenue: source.showVenue,
5809
+ successMessage: source.successMessage,
5810
+ waitlistMessage: source.waitlistMessage,
5811
+ membershipMessage: source.membershipMessage,
5812
+ buttonVariant: source.buttonVariant
5813
+ }
5814
+ })
5815
+ }),
5816
+ mode: "course-registration",
5817
+ meta: courseRegistrationIslandMetaCodec,
5818
+ metaKeys: courseRegistrationIslandMetaKeys,
5819
+ selectMeta: (value) => ({
5820
+ siteId: value.siteId,
5821
+ apiBaseUrl: value.apiBaseUrl,
5822
+ portalToken: value.portalToken,
5823
+ stage: value.stage
5824
+ })
1928
5825
  });
1929
- z$1.object({ variants: z$1.array(cardVariantSchema).min(1).max(3) });
1930
5826
  //#endregion
1931
5827
  //#region ../blocks/src/lib/media.ts
1932
5828
  const hotspotSchema = z.object({
@@ -2017,11 +5913,8 @@ function isRecord$3(value) {
2017
5913
  * This module provides a single source of truth for TipTap rich text validation
2018
5914
  * across both the block-form editor and the block rendering system.
2019
5915
  *
2020
- * Format compatibility:
2021
- * - Unwrapped format (new): { type: 'doc', content: [...] }
2022
- * - Wrapped format (legacy): { doc: { type: 'doc', content: [...] } }
2023
- *
2024
- * Both formats are supported for backward compatibility during migration.
5916
+ * Rich-text fields use one canonical root shape:
5917
+ * `{ type: 'doc', content: [...] }`.
2025
5918
  */
2026
5919
  /**
2027
5920
  * TipTap document node schema (recursive structure)
@@ -2034,17 +5927,40 @@ function isRecord$3(value) {
2034
5927
  * - marks: Text formatting marks (e.g., bold, italic)
2035
5928
  */
2036
5929
  const TipTapMarkSchema = z$1.object({
2037
- type: z$1.string(),
5930
+ type: z$1.string().min(1),
2038
5931
  attrs: z$1.record(z$1.string(), z$1.unknown()).optional()
2039
- });
5932
+ }).strict();
2040
5933
  const TipTapNodeSchema = z$1.lazy(() => z$1.object({
2041
- type: z$1.string(),
5934
+ type: z$1.string().min(1),
2042
5935
  content: z$1.array(TipTapNodeSchema).optional(),
2043
5936
  text: z$1.string().optional(),
2044
5937
  attrs: z$1.record(z$1.string(), z$1.unknown()).optional(),
2045
5938
  marks: z$1.array(TipTapMarkSchema).optional()
5939
+ }).strict().superRefine((node, ctx) => {
5940
+ if (node.type === "doc") ctx.addIssue({
5941
+ code: "custom",
5942
+ path: ["type"],
5943
+ message: "Document nodes are only valid at the rich-text root"
5944
+ });
5945
+ if (node.type === "text") {
5946
+ if (node.text === void 0 || node.text.length === 0) ctx.addIssue({
5947
+ code: "custom",
5948
+ path: ["text"],
5949
+ message: "Text nodes require a non-empty text value"
5950
+ });
5951
+ if (node.content !== void 0) ctx.addIssue({
5952
+ code: "custom",
5953
+ path: ["content"],
5954
+ message: "Text nodes cannot contain child nodes"
5955
+ });
5956
+ return;
5957
+ }
5958
+ if (node.text !== void 0) ctx.addIssue({
5959
+ code: "custom",
5960
+ path: ["text"],
5961
+ message: "Only text nodes can contain a text value"
5962
+ });
2046
5963
  }));
2047
- z$1.union([TipTapNodeSchema, z$1.object({ doc: TipTapNodeSchema })]);
2048
5964
  /**
2049
5965
  * Canonical schema for a TipTap rich-text document root.
2050
5966
  *
@@ -2053,111 +5969,11 @@ z$1.union([TipTapNodeSchema, z$1.object({ doc: TipTapNodeSchema })]);
2053
5969
  * (dummy content, editor output, migrations) must emit, and the shape every
2054
5970
  * non-legacy consumer can rely on.
2055
5971
  *
2056
- * Legacy envelopes are read-tolerated by {@link RichTextValueSchema} but
2057
- * normalised before reaching anywhere typed as `RichTextDoc`.
2058
5972
  */
2059
5973
  const RichTextDocSchema = z$1.object({
2060
5974
  type: z$1.literal("doc"),
2061
5975
  content: z$1.array(TipTapNodeSchema)
2062
- });
2063
- /**
2064
- * Permissive unwrap for a value known to be the root of a rich-text field.
2065
- *
2066
- * Producers should emit the canonical unwrapped form `{ type: 'doc', content: [...] }`,
2067
- * but two legacy shapes still appear in older data and pre-Phase-1 fixtures:
2068
- *
2069
- * - `{ doc: <typed-doc> }` — pre-migration DB storage.
2070
- * - `{ doc: <typed-doc>, html, plain }` — pre-Phase-1 dummy-content output.
2071
- *
2072
- * This helper is the single right place to tolerate either shape at a known
2073
- * rich-text root (transforms, coercion, validators that operate on rich text).
2074
- * The strictness sits on the inner node's `type === 'doc'`, which prevents
2075
- * misidentifying random objects that happen to carry a field named `doc`.
2076
- *
2077
- * Returns the inner doc node when the input matches a legacy shape, otherwise
2078
- * returns the input unchanged.
2079
- *
2080
- * For deep structural traversal where any nested key might be named `doc`
2081
- * (and unwrapping would be incorrect), use the strict `isDocWrapper` private
2082
- * helper inside `@riverbankcms/blocks/bindings`.
2083
- */
2084
- function unwrapRichTextRoot(value) {
2085
- if (!isRecord$3(value)) return value;
2086
- if (!("doc" in value)) return value;
2087
- const inner = value.doc;
2088
- if (isRecord$3(inner) && inner.type === "doc") return inner;
2089
- return value;
2090
- }
2091
- function createHardBreakNode() {
2092
- return { type: "hardBreak" };
2093
- }
2094
- /**
2095
- * Parse a small markdown subset into TipTap inline nodes.
2096
- *
2097
- * This intentionally supports only bold (`**text**`) because the SDK/content
2098
- * import paths use it for lightweight default content, not full markdown.
2099
- */
2100
- function parseRichTextInlineMarkdown(text) {
2101
- const out = [];
2102
- const pushText = (value, marks) => {
2103
- if (!value) return;
2104
- out.push(marks && marks.length > 0 ? {
2105
- type: "text",
2106
- text: value,
2107
- marks
2108
- } : {
2109
- type: "text",
2110
- text: value
2111
- });
2112
- };
2113
- let rest = text;
2114
- while (rest.length > 0) {
2115
- const start = rest.indexOf("**");
2116
- if (start === -1) {
2117
- pushText(rest);
2118
- break;
2119
- }
2120
- const end = rest.indexOf("**", start + 2);
2121
- if (end === -1) {
2122
- pushText(rest);
2123
- break;
2124
- }
2125
- pushText(rest.slice(0, start));
2126
- pushText(rest.slice(start + 2, end), [{ type: "bold" }]);
2127
- rest = rest.slice(end + 2);
2128
- }
2129
- return out;
2130
- }
2131
- function parseRichTextParagraphInlineMarkdown(text) {
2132
- return text.split("\n").flatMap((line, index) => {
2133
- const lineNodes = parseRichTextInlineMarkdown(line.trim());
2134
- return index === 0 ? lineNodes : [createHardBreakNode(), ...lineNodes];
2135
- });
2136
- }
2137
- /**
2138
- * Convert a plain string with a tiny markdown subset to canonical TipTap JSON.
2139
- *
2140
- * Double newlines create semantic paragraphs. Single newlines remain inside the
2141
- * current paragraph as TipTap `hardBreak` nodes for line-oriented content such
2142
- * as addresses, opening hours, and contact details.
2143
- */
2144
- function createRichTextDocFromMarkdown(markdown) {
2145
- const normalized = markdown.replace(/\r\n/g, "\n").trim();
2146
- if (!normalized) return {
2147
- type: "doc",
2148
- content: []
2149
- };
2150
- return {
2151
- type: "doc",
2152
- content: normalized.split(/\n{2,}/).map((paragraph) => paragraph.trim()).filter(Boolean).map((paragraph) => {
2153
- const inline = parseRichTextParagraphInlineMarkdown(paragraph);
2154
- return inline.length > 0 ? {
2155
- type: "paragraph",
2156
- content: inline
2157
- } : { type: "paragraph" };
2158
- })
2159
- };
2160
- }
5976
+ }).strict();
2161
5977
  //#endregion
2162
5978
  //#region ../blocks/src/system/blocks/events/shared/schemas.ts
2163
5979
  const eventPresetSchema = z$1.enum([
@@ -3911,6 +7727,7 @@ const DISPLAY_MEDIA_KINDS = [
3911
7727
  "video",
3912
7728
  "audio"
3913
7729
  ];
7730
+ const DEFAULT_MEDIA_FIELD_KINDS = ["image"];
3914
7731
  const PUBLIC_FILE_FIELD_KINDS = [
3915
7732
  "document",
3916
7733
  "spreadsheet",
@@ -4111,18 +7928,28 @@ const inlineTextFieldSchema = baseFieldSchema.extend({
4111
7928
  maxLength: z$1.number().int().positive().optional(),
4112
7929
  plainTextField: z$1.string().min(1).optional()
4113
7930
  });
7931
+ function hasMediaDefaultIdentifier(value) {
7932
+ return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.identifier === "string" && value.identifier.trim().length > 0;
7933
+ }
7934
+ function validateMediaFieldDefault(field, ctx) {
7935
+ if (field.defaultValue !== void 0 && field.defaultValue !== null && !hasMediaDefaultIdentifier(field.defaultValue)) ctx.addIssue({
7936
+ code: z$1.ZodIssueCode.custom,
7937
+ path: ["defaultValue"],
7938
+ message: `${field.type} defaultValue must be null or an object with a non-empty identifier`
7939
+ });
7940
+ }
4114
7941
  const mediaFieldSchema = baseFieldSchema.extend({
4115
7942
  type: z$1.literal("media"),
4116
- mediaKinds: z$1.array(z$1.enum(MEDIA_KINDS)).default(["image"]).transform((kinds) => {
7943
+ mediaKinds: z$1.array(z$1.enum(MEDIA_KINDS)).default([...DEFAULT_MEDIA_FIELD_KINDS]).transform((kinds) => {
4117
7944
  const displayKinds = kinds.filter(isDisplayMediaKind);
4118
- return displayKinds.length > 0 ? displayKinds : ["image"];
7945
+ return displayKinds.length > 0 ? displayKinds : [...DEFAULT_MEDIA_FIELD_KINDS];
4119
7946
  }),
4120
7947
  aspectRatio: z$1.string().optional()
4121
- });
7948
+ }).superRefine(validateMediaFieldDefault);
4122
7949
  const fileFieldSchema = baseFieldSchema.extend({
4123
7950
  type: z$1.literal("file"),
4124
7951
  fileKinds: z$1.array(z$1.enum(PUBLIC_FILE_FIELD_KINDS)).default([...PUBLIC_FILE_FIELD_KINDS])
4125
- });
7952
+ }).superRefine(validateMediaFieldDefault);
4126
7953
  const booleanFieldSchema = baseFieldSchema.extend({ type: z$1.literal("boolean") });
4127
7954
  const dateFieldSchema = baseFieldSchema.extend({ type: z$1.literal("date") });
4128
7955
  const timeFieldSchema = baseFieldSchema.extend({ type: z$1.literal("time") });
@@ -6902,11 +10729,7 @@ const newsletterPresetSchema = z$1.enum([
6902
10729
  "emailNameCompany"
6903
10730
  ]);
6904
10731
  const newsletterDestinationProviderSchema = z$1.enum(["riverbank", "mailchimp"]);
6905
- const newsletterButtonVariantSchema = z$1.enum([
6906
- "primary",
6907
- "secondary",
6908
- "outline"
6909
- ]);
10732
+ const newsletterButtonVariantSchema = blockButtonRoleSchema;
6910
10733
  const newsletterFieldSchema = z$1.object({
6911
10734
  id: z$1.string(),
6912
10735
  type: z$1.enum(["email", "text"]),
@@ -7483,12 +11306,7 @@ const shopSourceSchema = z$1.object({
7483
11306
  showPrices: z$1.boolean().optional(),
7484
11307
  showValidityPeriod: z$1.boolean().optional(),
7485
11308
  showPricePerCredit: z$1.boolean().nullable().optional(),
7486
- buttonVariant: z$1.enum([
7487
- "primary",
7488
- "secondary",
7489
- "outline",
7490
- "link"
7491
- ]).optional(),
11309
+ buttonVariant: blockButtonRoleSchema.optional(),
7492
11310
  passesHeading: z$1.string().optional(),
7493
11311
  membershipsHeading: z$1.string().optional(),
7494
11312
  buyButtonText: z$1.string().optional(),
@@ -7633,12 +11451,7 @@ const passesMembershipsHydrationSchema = z$1.object({
7633
11451
  passes: z$1.array(publicPassProductSchema),
7634
11452
  memberships: z$1.array(publicMembershipProductSchema),
7635
11453
  passPurchaseMode: z$1.enum(["add_to_cart", "buy_now"]),
7636
- buttonVariant: z$1.enum([
7637
- "primary",
7638
- "secondary",
7639
- "outline",
7640
- "link"
7641
- ])
11454
+ buttonVariant: blockButtonRoleSchema
7642
11455
  });
7643
11456
  const productListHydrationSchema = z$1.object({
7644
11457
  products: z$1.array(publicProductSchema),
@@ -7919,4 +11732,4 @@ function defineIslandPropsDecoder(kind) {
7919
11732
  };
7920
11733
  }
7921
11734
  //#endregion
7922
- export { themeColorTokenSchema as $, formatDate as A, getBookingLocalDateKey as At, resolveEventCta as B, publicEventScalarPrice as Bt, getWizardStepsForContext as C, reportWorkflowSuccess as Ct, normalizeCsvIds as D, formatBookingInstant as Dt, getEventRuntimeFiltersKey as E, formatBookingDateTime as Et, formatEventTeacherLine as F, parseEventPageSurfaceSubject as Ft, getLocalDateKey as G, resolveRuntimeEventPricing as H, formatCurrencyAmount as Ht, formatTime as I, formatBookingPriceDisplay as It, createRichTextDocFromMarkdown as J, getLocalMinuteOfDay as K, getCardOrientation as L, publicEventPricingCurrency as Lt, formatEventDateParts as M, resolveBookingTimeZoneId as Mt, formatEventPrice as N, toBookingTimeZone as Nt, normalizeCsvString as O, formatBookingTime as Ot, formatEventPriceDisplay as P, toScheduledBookingDateTime as Pt, parseThemeColorToken as Q, getContainerClass as R, publicEventPricingMode as Rt, getStepNumber as S, reportWorkflowError as St, buildEventRuntimeFilters as T, formatBookingDate as Tt, getEventAvailability as U, assertNever$2 as Ut, resolveEventLinkProps as V, publicEventTicketTypes as Vt, getEventAvailabilityStatus as W, isRecord$3 as X, unwrapRichTextRoot as Y, normalizeCardVariantRole as Z, findPreSelectedEvent as _, assertNever$1 as _t, buildProductDetailDisplay as a, getBookingRedirectStateFromLocation as at, resolveRegistrationTarget as b, ok as bt, EMPTY_COMMERCE_CART_STATE as c, isBookingServiceSlidingAmountInRange as ct, deriveCommerceCheckoutState as d, resolveAppointmentCheckoutVerificationState as dt, resolveEventRegistrationScopedEvents as et, parseStoredCommerceCartState as f, resolveBookingPaymentStep as ft, findEventByOccurrenceId as g, BOOKING_FORM_DATA_RESERVED_KEYS as gt, toRegistrationEvents as h, toSelectedCollectionOptionKind as ht, buildProductCardDisplay as i, formatBookingSubmissionPreparationError as it, formatEventCompactDateRail as j, parseBookingLocalDate as jt, normalizeOptionalId as k, formatLocalScheduleDate as kt, buildPassCartItem as l, parseBookingCurrencyInputToCents as lt, reduceCommerceCart as m, resolveDefaultBookingServiceId as mt, getShopDisplayForItems as n, deriveBookingFormViewState as nt, formatCommercePrice as o, getBookingServiceSlidingScale as ot, productItemKey as p, resolveBookingSiteId as pt, normalizeEventBlockKind as q, buildCartDisplay as r, formatBookingCentsAsCurrencyInput as rt, formatInterval as s, getBookingSuccessMessage as st, defineIslandPropsDecoder as t, logger as tt, buildProductCartItem as u, prepareBookingSubmission as ut, resolveDiscountContext as v, clearWorkflowFeedback as vt, buildEventCalendarListingRender as w, addLocalScheduleDays as wt, WIZARD_STEPS as x, okWith as xt, resolveEventRequiresPayment as y, err as yt, groupEventsByDate as z, publicEventPricingType as zt };
11735
+ export { hexToRgb as $, formatDate as A, formatBookingInstant as At, resolveEventCta as B, publicEventPricingCurrency as Bt, getWizardStepsForContext as C, ok as Ct, normalizeCsvIds as D, addLocalScheduleDays as Dt, getEventRuntimeFiltersKey as E, reportWorkflowSuccess as Et, formatEventTeacherLine as F, resolveBookingTimeZoneId as Ft, getLocalDateKey as G, formatCurrencyAmount as Gt, resolveRuntimeEventPricing as H, publicEventPricingType as Ht, formatTime as I, toBookingTimeZone as It, RichTextDocSchema as J, getLocalMinuteOfDay as K, assertNever$2 as Kt, getCardOrientation as L, toScheduledBookingDateTime as Lt, formatEventDateParts as M, formatLocalScheduleDate as Mt, formatEventPrice as N, getBookingLocalDateKey as Nt, normalizeCsvString as O, formatBookingDate as Ot, formatEventPriceDisplay as P, parseBookingLocalDate as Pt, relativeLuminance as Q, getContainerClass as R, parseEventPageSurfaceSubject as Rt, getStepNumber as S, err as St, buildEventRuntimeFilters as T, reportWorkflowError as Tt, getEventAvailability as U, publicEventScalarPrice as Ut, resolveEventLinkProps as V, publicEventPricingMode as Vt, getEventAvailabilityStatus as W, publicEventTicketTypes as Wt, resolveEventRegistrationScopedEvents as X, isRecord$3 as Y, themeButtonClassName as Z, findPreSelectedEvent as _, resolveDefaultBookingServiceId as _t, buildProductDetailDisplay as a, deriveBookingFormViewState as at, resolveRegistrationTarget as b, assertNever$1 as bt, EMPTY_COMMERCE_CART_STATE as c, getBookingRedirectStateFromLocation as ct, deriveCommerceCheckoutState as d, isBookingServiceSlidingAmountInRange as dt, isCssColorLiteral as et, parseStoredCommerceCartState as f, parseBookingCurrencyInputToCents as ft, findEventByOccurrenceId as g, resolveBookingSiteId as gt, toRegistrationEvents as h, resolveBookingPaymentStep as ht, buildProductCardDisplay as i, logger as it, formatEventCompactDateRail as j, formatBookingTime as jt, normalizeOptionalId as k, formatBookingDateTime as kt, buildPassCartItem as l, getBookingServiceSlidingScale as lt, reduceCommerceCart as m, resolveAppointmentCheckoutVerificationState as mt, getShopDisplayForItems as n, resolveTokenOrCssColorValue as nt, formatCommercePrice as o, formatBookingCentsAsCurrencyInput as ot, productItemKey as p, prepareBookingSubmission as pt, normalizeEventBlockKind as q, buildCartDisplay as r, normalizeCardVariantRole as rt, formatInterval as s, formatBookingSubmissionPreparationError as st, defineIslandPropsDecoder as t, resolveOnColorForThemeToken as tt, buildProductCartItem as u, getBookingSuccessMessage as ut, resolveDiscountContext as v, toSelectedCollectionOptionKind as vt, buildEventCalendarListingRender as w, okWith as wt, WIZARD_STEPS as x, clearWorkflowFeedback as xt, resolveEventRequiresPayment as y, BOOKING_FORM_DATA_RESERVED_KEYS as yt, groupEventsByDate as z, formatBookingPriceDisplay as zt };