@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
@@ -53,7 +53,7 @@ const TAG_TEMPLATES = {
53
53
  blockedDemoMutationPolicy("blocked-hidden", "This action is not available in demo sites.");
54
54
  blockedDemoMutationPolicy("blocked-disabled", "This setting is disabled in demo sites.");
55
55
  blockedDemoMutationPolicy("internal-only", "This internal operation is not available in demo sites.");
56
- TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteBookingSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteBookingSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.routeById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.workflowRunById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.routeById, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.formById, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEventFilters, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicTeamMembers, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicPasses, TAG_TEMPLATES.publicMemberships, TAG_TEMPLATES.publicProducts, TAG_TEMPLATES.publicGifting, TAG_TEMPLATES.publicGifting, TAG_TEMPLATES.publicGifting, TAG_TEMPLATES.publicShop, TAG_TEMPLATES.publicCheckout, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents;
56
+ TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteBookingSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteBookingSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.routeById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.workflowRunById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.routeById, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.formById, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEventFilters, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicTeamMembers, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicCourses, TAG_TEMPLATES.publicPasses, TAG_TEMPLATES.publicMemberships, TAG_TEMPLATES.publicProducts, TAG_TEMPLATES.publicGifting, TAG_TEMPLATES.publicGifting, TAG_TEMPLATES.publicGifting, TAG_TEMPLATES.publicShop, TAG_TEMPLATES.publicCheckout, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents;
57
57
  //#endregion
58
58
  //#region ../core/src/result.ts
59
59
  function ok(value) {
@@ -3254,151 +3254,6 @@ z$1.discriminatedUnion("kind", [
3254
3254
  })
3255
3255
  ]);
3256
3256
  //#endregion
3257
- //#region ../theme-core/src/surfaces/foregroundContract.ts
3258
- const SURFACE_FOREGROUND_CSS_VARS = {
3259
- text: "--rb-surface-text-color",
3260
- heading: "--rb-surface-heading-color",
3261
- link: "--rb-surface-link-color",
3262
- supporting: "--rb-surface-supporting-color"
3263
- };
3264
- const DEFAULT_SURFACE_TEXT_COLOR = "rgb(var(--tb-text, 17 24 39))";
3265
- const DEFAULT_ROLE_FALLBACKS = {
3266
- text: DEFAULT_SURFACE_TEXT_COLOR,
3267
- heading: DEFAULT_SURFACE_TEXT_COLOR,
3268
- link: "rgb(var(--tb-primary, var(--tb-text, 17 24 39)))",
3269
- supporting: "rgb(var(--tb-mutedText, 100 116 139))"
3270
- };
3271
- function requireSurfaceColorValue(role, value) {
3272
- const normalized = value.trim();
3273
- if (normalized.length === 0) throw new RangeError(`Surface foreground ${role} must be a non-empty CSS color.`);
3274
- return normalized;
3275
- }
3276
- function completeSurfaceForegrounds(input) {
3277
- const text = requireSurfaceColorValue("text", input.text);
3278
- return {
3279
- text,
3280
- heading: input.heading === void 0 ? text : requireSurfaceColorValue("heading", input.heading),
3281
- link: input.link === void 0 ? text : requireSurfaceColorValue("link", input.link),
3282
- supporting: input.supporting === void 0 ? text : requireSurfaceColorValue("supporting", input.supporting)
3283
- };
3284
- }
3285
- function surfaceForegroundValue(role, outsideProviderFallback = DEFAULT_ROLE_FALLBACKS[role]) {
3286
- const roleVariable = SURFACE_FOREGROUND_CSS_VARS[role];
3287
- const fallback = requireSurfaceColorValue("fallback", outsideProviderFallback);
3288
- if (role === "text") return `var(${roleVariable}, ${fallback})`;
3289
- return `var(${roleVariable}, var(${SURFACE_FOREGROUND_CSS_VARS.text}, ${fallback}))`;
3290
- }
3291
- function surfaceForegroundValueWithOpacity(role, opacityPercent) {
3292
- if (!Number.isFinite(opacityPercent) || opacityPercent < 0 || opacityPercent > 100) throw new RangeError("Surface foreground opacity must be between 0 and 100.");
3293
- return `color-mix(in srgb, ${surfaceForegroundValue(role)} ${opacityPercent}%, transparent)`;
3294
- }
3295
- function surfaceForegroundStyle(input) {
3296
- const foregrounds = completeSurfaceForegrounds(input);
3297
- return {
3298
- color: foregrounds.text,
3299
- [SURFACE_FOREGROUND_CSS_VARS.text]: foregrounds.text,
3300
- [SURFACE_FOREGROUND_CSS_VARS.heading]: foregrounds.heading,
3301
- [SURFACE_FOREGROUND_CSS_VARS.link]: foregrounds.link,
3302
- [SURFACE_FOREGROUND_CSS_VARS.supporting]: foregrounds.supporting
3303
- };
3304
- }
3305
- //#endregion
3306
- //#region ../theme-core/src/utils/colorStyles.ts
3307
- const COLOR_VAR_PREFIX = "--tb-";
3308
- function parseToken(source) {
3309
- const parts = parseColorTokenParts(source);
3310
- if (parts.kind === "raw") return {
3311
- token: source,
3312
- raw: parts.value
3313
- };
3314
- if (parts.kind === "invalid") return { token: source };
3315
- return {
3316
- token: parts.token,
3317
- opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
3318
- };
3319
- }
3320
- const SURFACE_TEXT_ROLE_BY_TOKEN = {
3321
- text: "text",
3322
- heading: "heading",
3323
- mutedText: "supporting"
3324
- };
3325
- function surfaceRoleForTextToken(token) {
3326
- return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
3327
- }
3328
- /**
3329
- * Converts a theme color token to a CSS rgb value.
3330
- * This is the primary function for applying theme colors to CSS properties.
3331
- *
3332
- * @param token - Theme color token (semantic, with opacity, or raw)
3333
- * @returns CSS color value (rgb with optional alpha, or raw CSS value)
3334
- *
3335
- * @example
3336
- * rgbColorValue('primary') // => 'rgb(var(--tb-primary))'
3337
- * rgbColorValue('surface/95') // => 'rgb(var(--tb-surface) / 0.95)'
3338
- * rgbColorValue('raw:transparent') // => 'transparent'
3339
- */
3340
- function rgbColorValue(token) {
3341
- const { token: baseToken, opacityPercent, raw } = parseToken(token);
3342
- if (raw) return raw;
3343
- const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
3344
- if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
3345
- return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
3346
- }
3347
- /**
3348
- * Creates a backgroundColor style object from a theme token.
3349
- *
3350
- * @param token - Theme color token
3351
- * @returns CSSProperties with backgroundColor
3352
- */
3353
- function backgroundColorStyle(token) {
3354
- return { backgroundColor: rgbColorValue(token) };
3355
- }
3356
- /**
3357
- * Creates a text color style object from a theme token.
3358
- *
3359
- * @param token - Theme color token
3360
- * @returns CSSProperties with color
3361
- */
3362
- function textColorStyle(token) {
3363
- const parsed = parseToken(token);
3364
- const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
3365
- if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
3366
- return { color: rgbColorValue(token) };
3367
- }
3368
- /**
3369
- * Creates a border color style object from a theme token.
3370
- *
3371
- * @param token - Theme color token
3372
- * @returns CSSProperties with borderColor
3373
- */
3374
- function borderColorStyle(token) {
3375
- return { borderColor: rgbColorValue(token) };
3376
- }
3377
- /**
3378
- * Merges multiple CSSProperties objects into a single object.
3379
- * Later styles override earlier ones. Undefined values are filtered out.
3380
- * Returns undefined if the merged result is empty.
3381
- *
3382
- * @param styles - Variable number of CSSProperties objects (can be undefined)
3383
- * @returns Merged CSSProperties object, or undefined if empty
3384
- *
3385
- * @example
3386
- * mergeStyles(
3387
- * backgroundColorStyle('surface'),
3388
- * textColorStyle('text'),
3389
- * borderColorStyle('border')
3390
- * )
3391
- * // => { backgroundColor: '...', color: '...', borderColor: '...' }
3392
- */
3393
- function mergeStyles(...styles) {
3394
- const merged = {};
3395
- for (const style of styles) {
3396
- if (!style) continue;
3397
- Object.assign(merged, style);
3398
- }
3399
- return Object.keys(merged).length ? merged : void 0;
3400
- }
3401
- //#endregion
3402
3257
  //#region ../theme-core/src/lib/media.ts
3403
3258
  const hotspotSchema$1 = z.object({
3404
3259
  x: z.number().min(0).max(1),
@@ -3456,111 +3311,6 @@ const mediaSchema$1 = z.object({
3456
3311
  transform: transformSchema$1.optional()
3457
3312
  });
3458
3313
  //#endregion
3459
- //#region ../theme-core/src/buttons/effectClassification.ts
3460
- /**
3461
- * Exhaustive live policy for every registered effect id.
3462
- *
3463
- * The resolver consumes the transition payload directly, so adding an effect
3464
- * cannot update classification without also defining its runtime behavior.
3465
- */
3466
- const BUTTON_EFFECT_POLICIES = {
3467
- "darken-background": {
3468
- classification: "colour-transition",
3469
- transition: {
3470
- kind: "adjust-shade",
3471
- direction: "darker"
3472
- }
3473
- },
3474
- "lighten-background": {
3475
- classification: "colour-transition",
3476
- transition: {
3477
- kind: "adjust-shade",
3478
- direction: "lighter"
3479
- }
3480
- },
3481
- "background-on-hover": {
3482
- classification: "colour-transition",
3483
- transition: { kind: "replace-background" }
3484
- },
3485
- "background-on-hover-alpha": {
3486
- classification: "unsupported-colour",
3487
- reason: "alpha_requires_surface"
3488
- },
3489
- "fade-background": {
3490
- classification: "unsupported-colour",
3491
- reason: "changes_element_opacity"
3492
- },
3493
- "opacity-reduce": {
3494
- classification: "unsupported-colour",
3495
- reason: "changes_element_opacity"
3496
- },
3497
- "gradient-text": {
3498
- classification: "unsupported-colour",
3499
- reason: "changes_foreground"
3500
- },
3501
- "text-color-change": {
3502
- classification: "unsupported-colour",
3503
- reason: "changes_foreground"
3504
- },
3505
- "border-color-change": {
3506
- classification: "unsupported-colour",
3507
- reason: "changes_border"
3508
- },
3509
- "aurora-glow": {
3510
- classification: "unsupported-background-overlay",
3511
- reason: "unresolved_background_overlay"
3512
- },
3513
- "cosmic-stardust": {
3514
- classification: "unsupported-background-overlay",
3515
- reason: "unresolved_background_overlay"
3516
- },
3517
- "gradient-border-fill": {
3518
- classification: "unsupported-background-overlay",
3519
- reason: "unresolved_background_overlay"
3520
- },
3521
- "animated-gradient-border-fill": {
3522
- classification: "unsupported-background-overlay",
3523
- reason: "unresolved_background_overlay"
3524
- },
3525
- "nav-underline": {
3526
- classification: "not-button",
3527
- reason: "not_button_effect"
3528
- },
3529
- "nav-frosted-base": {
3530
- classification: "not-button",
3531
- reason: "not_button_effect"
3532
- },
3533
- "nav-frosted-hover": {
3534
- classification: "not-button",
3535
- reason: "not_button_effect"
3536
- },
3537
- "nav-frosted-active": {
3538
- classification: "not-button",
3539
- reason: "not_button_effect"
3540
- },
3541
- "animated-gradient": { classification: "non-colour" },
3542
- "border-glow": { classification: "non-colour" },
3543
- "drop-shadow": { classification: "non-colour" },
3544
- "inner-shadow": { classification: "non-colour" },
3545
- "neumorphic-shadow": { classification: "non-colour" },
3546
- "outer-glow": { classification: "non-colour" },
3547
- "retro-3d-shadow": { classification: "non-colour" },
3548
- "scale-up": { classification: "non-colour" },
3549
- "scale-down": { classification: "non-colour" },
3550
- lift: { classification: "non-colour" },
3551
- "press-down": { classification: "non-colour" },
3552
- pop: { classification: "non-colour" },
3553
- "border-bottom-grow": { classification: "non-colour" },
3554
- "sketchy-border": { classification: "non-colour" },
3555
- "pulse-animation": { classification: "non-colour" }
3556
- };
3557
- function getButtonEffectPolicy(effectId) {
3558
- return Object.prototype.hasOwnProperty.call(BUTTON_EFFECT_POLICIES, effectId) ? BUTTON_EFFECT_POLICIES[effectId] : null;
3559
- }
3560
- function classifyButtonEffectId(effectId) {
3561
- return getButtonEffectPolicy(effectId)?.classification ?? "unknown";
3562
- }
3563
- //#endregion
3564
3314
  //#region ../theme-core/src/buttons/types.ts
3565
3315
  /**
3566
3316
  * Standard semantic variant roles a theme exposes.
@@ -3577,6 +3327,13 @@ const VARIANT_ROLES = [
3577
3327
  "tertiary",
3578
3328
  "accent"
3579
3329
  ];
3330
+ /**
3331
+ * Canonical persisted/CSS-safe button variant identifier.
3332
+ *
3333
+ * IDs become class selectors, so keep the contract deliberately narrower than
3334
+ * an arbitrary string and shared with every authoring/runtime boundary.
3335
+ */
3336
+ const buttonVariantIdSchema = z$1.string().min(1).max(50).regex(/^[a-z0-9-]+$/, "Button variant IDs may contain lowercase letters, numbers, and hyphens only");
3580
3337
  function parseOpaqueButtonColourToken(value) {
3581
3338
  const token = parseThemeColorToken(value);
3582
3339
  if (token === null) return null;
@@ -3591,6 +3348,109 @@ const opaqueButtonColourTokenSchema = themeColorTokenSchema.refine((value) => pa
3591
3348
  if (token === null) throw new Error("Invariant: opaque button token passed its schema");
3592
3349
  return token;
3593
3350
  });
3351
+ const buttonShadeAmountSchema = z$1.number().finite().min(0).max(900).multipleOf(100);
3352
+ const buttonShadowIntensitySchema = z$1.enum([
3353
+ "subtle",
3354
+ "medium",
3355
+ "strong"
3356
+ ]);
3357
+ /**
3358
+ * The complete persisted button-effect contract.
3359
+ *
3360
+ * Navigation has its own generic interactive-effect model. Button variants use
3361
+ * this closed union so unsupported effect IDs, unknown option keys, and unsafe
3362
+ * CSS values cannot become representable after the schema boundary.
3363
+ */
3364
+ const buttonEffectApplicationSchema = z$1.discriminatedUnion("effectId", [
3365
+ z$1.strictObject({
3366
+ effectId: z$1.literal("darken-background"),
3367
+ options: z$1.strictObject({ amount: buttonShadeAmountSchema.optional() }).optional()
3368
+ }),
3369
+ z$1.strictObject({
3370
+ effectId: z$1.literal("lighten-background"),
3371
+ options: z$1.strictObject({ amount: buttonShadeAmountSchema.optional() }).optional()
3372
+ }),
3373
+ z$1.strictObject({
3374
+ effectId: z$1.literal("background-on-hover"),
3375
+ options: z$1.strictObject({ colorToken: opaqueButtonColourTokenSchema.optional() }).optional()
3376
+ }),
3377
+ z$1.strictObject({
3378
+ effectId: z$1.literal("animated-gradient"),
3379
+ options: z$1.strictObject({ direction: z$1.enum(["horizontal", "vertical"]).optional() }).optional()
3380
+ }),
3381
+ z$1.strictObject({
3382
+ effectId: z$1.literal("drop-shadow"),
3383
+ options: z$1.strictObject({ intensity: buttonShadowIntensitySchema.optional() }).optional()
3384
+ }),
3385
+ z$1.strictObject({
3386
+ effectId: z$1.literal("inner-shadow"),
3387
+ options: z$1.strictObject({}).optional()
3388
+ }),
3389
+ z$1.strictObject({
3390
+ effectId: z$1.literal("neumorphic-shadow"),
3391
+ options: z$1.strictObject({
3392
+ mode: z$1.enum(["raised", "pressed"]).optional(),
3393
+ intensity: buttonShadowIntensitySchema.optional()
3394
+ }).optional()
3395
+ }),
3396
+ z$1.strictObject({
3397
+ effectId: z$1.literal("retro-3d-shadow"),
3398
+ options: z$1.strictObject({}).optional()
3399
+ }),
3400
+ z$1.strictObject({
3401
+ effectId: z$1.literal("scale-up"),
3402
+ options: z$1.strictObject({ scale: z$1.enum([
3403
+ "1.02",
3404
+ "1.03",
3405
+ "1.05",
3406
+ "1.10"
3407
+ ]).optional() }).optional()
3408
+ }),
3409
+ z$1.strictObject({
3410
+ effectId: z$1.literal("scale-down"),
3411
+ options: z$1.strictObject({ scale: z$1.enum([
3412
+ "0.90",
3413
+ "0.95",
3414
+ "0.97",
3415
+ "0.98"
3416
+ ]).optional() }).optional()
3417
+ }),
3418
+ z$1.strictObject({
3419
+ effectId: z$1.literal("lift"),
3420
+ options: z$1.strictObject({ amount: z$1.enum([
3421
+ "0.25",
3422
+ "0.5",
3423
+ "1"
3424
+ ]).optional() }).optional()
3425
+ }),
3426
+ z$1.strictObject({
3427
+ effectId: z$1.literal("press-down"),
3428
+ options: z$1.strictObject({}).optional()
3429
+ }),
3430
+ z$1.strictObject({
3431
+ effectId: z$1.literal("pop"),
3432
+ options: z$1.strictObject({ intensity: z$1.enum([
3433
+ "subtle",
3434
+ "medium",
3435
+ "dramatic"
3436
+ ]).optional() }).optional()
3437
+ }),
3438
+ z$1.strictObject({
3439
+ effectId: z$1.literal("border-bottom-grow"),
3440
+ options: z$1.strictObject({
3441
+ height: z$1.union([z$1.literal(1), z$1.literal(2)]).optional(),
3442
+ origin: z$1.enum([
3443
+ "left",
3444
+ "center",
3445
+ "right"
3446
+ ]).optional()
3447
+ }).optional()
3448
+ }),
3449
+ z$1.strictObject({
3450
+ effectId: z$1.literal("sketchy-border"),
3451
+ options: z$1.strictObject({ intensity: buttonShadowIntensitySchema.optional() }).optional()
3452
+ })
3453
+ ]);
3594
3454
  const cornerStyleSchema = z$1.enum([
3595
3455
  "square",
3596
3456
  "rounded",
@@ -3625,13 +3485,7 @@ const hoverTransformSchema = z$1.enum([
3625
3485
  "scale",
3626
3486
  "press"
3627
3487
  ]);
3628
- const hoverColorSchema = z$1.enum([
3629
- "none",
3630
- "brighten",
3631
- "darken",
3632
- "saturate",
3633
- "token"
3634
- ]);
3488
+ z$1.enum(["none", "token"]);
3635
3489
  const buttonPaddingPresetSchema = z$1.enum([
3636
3490
  "compact",
3637
3491
  "default",
@@ -3692,7 +3546,7 @@ const buttonSizesSchema = z$1.object({
3692
3546
  lg,
3693
3547
  xl: xl ?? lg
3694
3548
  }));
3695
- const canonicalButtonGlobalSettingsSchema = z$1.object({
3549
+ const buttonGlobalSettingsBaseSchema = z$1.strictObject({
3696
3550
  cornerStyle: cornerStyleSchema,
3697
3551
  cornerRadius: z$1.number().min(0).max(24).optional(),
3698
3552
  /**
@@ -3705,30 +3559,23 @@ const canonicalButtonGlobalSettingsSchema = z$1.object({
3705
3559
  shadow: shadowSizeSchema.optional(),
3706
3560
  textTransform: textTransformSchema,
3707
3561
  fontWeight: fontWeightSchema,
3708
- /**
3709
- * @deprecated Set per-variant via `variant.border.widthClass` instead.
3710
- * Schema field is preserved so existing presets parse; the value is unread
3711
- * by the current generator and will be removed once the legacy
3712
- * `primitives/content/components/Button.tsx` slot exports are deleted.
3713
- */
3714
- borderWidth: z$1.union([
3715
- z$1.literal(1),
3716
- z$1.literal(2),
3717
- z$1.literal(3)
3718
- ]),
3719
3562
  typography: buttonTypographySchema.optional(),
3720
3563
  fontSize: z$1.string().optional(),
3721
3564
  letterSpacing: letterSpacingSchema.optional(),
3722
3565
  italic: z$1.boolean().optional(),
3723
3566
  paddingPreset: buttonPaddingPresetSchema.optional(),
3724
3567
  hoverTransform: hoverTransformSchema,
3725
- hoverColor: hoverColorSchema,
3726
- hoverColorToken: opaqueButtonColourTokenSchema.optional(),
3727
3568
  gradientStyle: gradientStyleSchema.optional(),
3728
3569
  gradientAngle: z$1.number().min(0).max(360).optional(),
3729
3570
  gradientSharpness: gradientSharpnessSchema.optional()
3730
3571
  });
3731
- const buttonGlobalSettingsSchema = z$1.preprocess(normalizeLegacyButtonGlobalInput, canonicalButtonGlobalSettingsSchema);
3572
+ const buttonGlobalSettingsSchema = z$1.discriminatedUnion("hoverColor", [buttonGlobalSettingsBaseSchema.extend({
3573
+ hoverColor: z$1.literal("none"),
3574
+ hoverColorToken: z$1.never().optional()
3575
+ }), buttonGlobalSettingsBaseSchema.extend({
3576
+ hoverColor: z$1.literal("token"),
3577
+ hoverColorToken: opaqueButtonColourTokenSchema
3578
+ })]);
3732
3579
  const gradientDirectionSchema$1 = z$1.enum([
3733
3580
  "to-r",
3734
3581
  "to-l",
@@ -3739,12 +3586,12 @@ const gradientDirectionSchema$1 = z$1.enum([
3739
3586
  "to-br",
3740
3587
  "to-bl"
3741
3588
  ]);
3742
- const buttonBackgroundSchema = z$1.discriminatedUnion("type", [
3743
- z$1.object({
3589
+ const buttonColourTreatmentSchema = z$1.discriminatedUnion("type", [
3590
+ z$1.strictObject({
3744
3591
  type: z$1.literal("solid"),
3745
3592
  colorToken: opaqueButtonColourTokenSchema
3746
3593
  }),
3747
- z$1.object({
3594
+ z$1.strictObject({
3748
3595
  type: z$1.literal("gradient"),
3749
3596
  stops: z$1.array(opaqueButtonColourTokenSchema).min(2).transform((stops) => {
3750
3597
  const [first, second, ...rest] = stops;
@@ -3758,18 +3605,15 @@ const buttonBackgroundSchema = z$1.discriminatedUnion("type", [
3758
3605
  direction: gradientDirectionSchema$1,
3759
3606
  foregroundToken: opaqueButtonColourTokenSchema
3760
3607
  }),
3761
- z$1.object({
3608
+ z$1.strictObject({
3762
3609
  type: z$1.literal("surface"),
3763
3610
  role: z$1.literal("link")
3764
3611
  })
3765
3612
  ]);
3766
- const effectApplicationSchema$1 = z$1.object({
3767
- effectId: z$1.string(),
3768
- options: z$1.record(z$1.string(), z$1.json()).optional()
3769
- });
3770
- const buttonBorderSchema = z$1.object({ widthClass: z$1.string() });
3771
- const buttonVariantAffordanceSchema = z$1.object({ iconId: z$1.string().min(1) });
3772
- const variantShadowSchema = z$1.object({
3613
+ const buttonBackgroundSchema = buttonColourTreatmentSchema;
3614
+ const buttonBorderSchema = z$1.strictObject({ widthClass: z$1.string() });
3615
+ const buttonVariantAffordanceSchema = z$1.strictObject({ iconId: z$1.string().min(1) });
3616
+ const variantShadowSchema = z$1.strictObject({
3773
3617
  elevation: z$1.enum([
3774
3618
  "none",
3775
3619
  "low",
@@ -3782,13 +3626,13 @@ const variantShadowSchema = z$1.object({
3782
3626
  "hard"
3783
3627
  ]).nullable(),
3784
3628
  position: z$1.enum(["bottom", "bottom-right"]).default("bottom"),
3785
- colorToken: themeColorTokenSchema.optional()
3629
+ colorToken: opaqueButtonColourTokenSchema.optional()
3786
3630
  });
3787
- const variantEffectsSchema = z$1.object({
3788
- base: z$1.array(effectApplicationSchema$1).optional(),
3789
- hover: z$1.array(effectApplicationSchema$1).optional(),
3790
- active: z$1.array(effectApplicationSchema$1).optional(),
3791
- focus: z$1.array(effectApplicationSchema$1).optional()
3631
+ const variantEffectsSchema = z$1.strictObject({
3632
+ base: z$1.array(buttonEffectApplicationSchema).optional(),
3633
+ hover: z$1.array(buttonEffectApplicationSchema).optional(),
3634
+ active: z$1.array(buttonEffectApplicationSchema).optional(),
3635
+ focus: z$1.array(buttonEffectApplicationSchema).optional()
3792
3636
  });
3793
3637
  /**
3794
3638
  * Per-variant size overrides schema — every entry is optional.
@@ -3809,8 +3653,8 @@ const variantSizeOverridesSchema = z$1.object({
3809
3653
  * default (e.g. link-style variants declaring zero horizontal padding at
3810
3654
  * every size).
3811
3655
  */
3812
- const canonicalButtonVariantSchema = z$1.object({
3813
- id: z$1.string(),
3656
+ const buttonVariantSchema = z$1.strictObject({
3657
+ id: buttonVariantIdSchema,
3814
3658
  name: z$1.string().min(1).max(20),
3815
3659
  enabled: z$1.boolean(),
3816
3660
  priority: prioritySchema,
@@ -3824,422 +3668,499 @@ const canonicalButtonVariantSchema = z$1.object({
3824
3668
  sizes: variantSizeOverridesSchema.optional(),
3825
3669
  affordance: buttonVariantAffordanceSchema.optional()
3826
3670
  });
3827
- /**
3828
- * Temporary persisted-theme admission boundary for issue #1206.
3829
- *
3830
- * Production inventory on 2026-07-22 found 22 rows using the old independent
3831
- * `textColorToken`/border colour shape. New source and all downstream code use
3832
- * only the canonical relationship. Delete this preprocessor after the reviewed
3833
- * production rewrite reports zero legacy rows.
3834
- */
3835
- const buttonVariantSchema = z$1.preprocess(normalizeLegacyButtonVariantInput, canonicalButtonVariantSchema);
3836
- const buttonSystemSchema = z$1.object({
3671
+ const buttonSystemSchema = z$1.strictObject({
3837
3672
  global: buttonGlobalSettingsSchema,
3838
3673
  variants: z$1.array(buttonVariantSchema).min(1).max(6),
3839
3674
  sizes: buttonSizesSchema.optional()
3675
+ }).superRefine((system, ctx) => {
3676
+ const seen = /* @__PURE__ */ new Set();
3677
+ system.variants.forEach((variant, index) => {
3678
+ if (seen.has(variant.id)) ctx.addIssue({
3679
+ code: "custom",
3680
+ path: [
3681
+ "variants",
3682
+ index,
3683
+ "id"
3684
+ ],
3685
+ message: `Duplicate button variant ID: ${variant.id}`
3686
+ });
3687
+ seen.add(variant.id);
3688
+ });
3840
3689
  });
3841
- function normalizeLegacyButtonVariantInput(input) {
3842
- if (!isUnknownRecord(input)) return input;
3843
- const background = input.background;
3844
- if (!isUnknownRecord(background)) return input;
3845
- if (!(background.type === "transparent" || Object.prototype.hasOwnProperty.call(input, "textColorToken") || isUnknownRecord(input.border) && Object.prototype.hasOwnProperty.call(input.border, "colorToken") || hasLegacyButtonEffects(input.effects) || hasLegacyAlphaToken(input, background))) return input;
3846
- const { textColorToken, ...withoutLegacyText } = input;
3847
- const normalizedBorder = isUnknownRecord(input.border) && typeof input.border.widthClass === "string" ? { widthClass: input.border.widthClass } : input.border;
3848
- const normalizedAffordance = isUnknownRecord(input.affordance) && typeof input.affordance.iconId === "string" ? { iconId: input.affordance.iconId } : input.affordance;
3849
- const normalizedEffects = normalizeLegacyButtonEffects(input.effects, background.type);
3850
- const hoverBackgroundToken = stripLegacyTokenAlpha(input.hoverBackgroundToken);
3851
- if (background.type === "transparent") return {
3852
- ...withoutLegacyText,
3853
- background: {
3854
- type: "surface",
3855
- role: "link"
3856
- },
3857
- border: normalizedBorder,
3858
- affordance: normalizedAffordance,
3859
- effects: normalizedEffects,
3860
- hoverBackgroundToken
3861
- };
3862
- if (background.type === "gradient") {
3863
- const stops = Array.isArray(background.stops) ? background.stops.map(stripLegacyTokenAlpha) : background.stops;
3864
- return {
3865
- ...withoutLegacyText,
3866
- background: {
3867
- ...background,
3868
- stops,
3869
- foregroundToken: stripLegacyTokenAlpha(background.foregroundToken ?? textColorToken)
3870
- },
3871
- border: normalizedBorder,
3872
- affordance: normalizedAffordance,
3873
- effects: normalizedEffects,
3874
- hoverBackgroundToken
3875
- };
3876
- }
3877
- return {
3878
- ...withoutLegacyText,
3879
- background: background.type === "solid" ? {
3880
- ...background,
3881
- colorToken: stripLegacyTokenAlpha(background.colorToken)
3882
- } : background,
3883
- border: normalizedBorder,
3884
- affordance: normalizedAffordance,
3885
- effects: normalizedEffects,
3886
- hoverBackgroundToken
3887
- };
3690
+ //#endregion
3691
+ //#region ../theme-core/src/surfaces/foregroundContract.ts
3692
+ const SURFACE_FOREGROUND_CSS_VARS = {
3693
+ text: "--rb-surface-text-color",
3694
+ heading: "--rb-surface-heading-color",
3695
+ link: "--rb-surface-link-color",
3696
+ supporting: "--rb-surface-supporting-color"
3697
+ };
3698
+ const DEFAULT_SURFACE_TEXT_COLOR = "rgb(var(--tb-text, 17 24 39))";
3699
+ const DEFAULT_ROLE_FALLBACKS = {
3700
+ text: DEFAULT_SURFACE_TEXT_COLOR,
3701
+ heading: DEFAULT_SURFACE_TEXT_COLOR,
3702
+ link: "rgb(var(--tb-primary, var(--tb-text, 17 24 39)))",
3703
+ supporting: "rgb(var(--tb-mutedText, 100 116 139))"
3704
+ };
3705
+ function requireSurfaceColorValue(role, value) {
3706
+ const normalized = value.trim();
3707
+ if (normalized.length === 0) throw new RangeError(`Surface foreground ${role} must be a non-empty CSS color.`);
3708
+ return normalized;
3888
3709
  }
3889
- function normalizeLegacyButtonGlobalInput(input) {
3890
- if (!isUnknownRecord(input)) return input;
3891
- const hoverColorToken = stripLegacyTokenAlpha(input.hoverColorToken);
3892
- return hoverColorToken === input.hoverColorToken ? input : {
3893
- ...input,
3894
- hoverColorToken
3710
+ function completeSurfaceForegrounds(input) {
3711
+ const text = requireSurfaceColorValue("text", input.text);
3712
+ return {
3713
+ text,
3714
+ heading: input.heading === void 0 ? text : requireSurfaceColorValue("heading", input.heading),
3715
+ link: input.link === void 0 ? text : requireSurfaceColorValue("link", input.link),
3716
+ supporting: input.supporting === void 0 ? text : requireSurfaceColorValue("supporting", input.supporting)
3895
3717
  };
3896
3718
  }
3897
- function hasLegacyAlphaToken(input, background) {
3898
- const stops = isUnknownArray(background.stops) ? background.stops : [];
3899
- return [
3900
- input.hoverBackgroundToken,
3901
- background.colorToken,
3902
- background.foregroundToken,
3903
- ...stops
3904
- ].some((token) => stripLegacyTokenAlpha(token) !== token);
3905
- }
3906
- function stripLegacyTokenAlpha(value) {
3907
- if (typeof value !== "string") return value;
3908
- const slashIndex = value.indexOf("/");
3909
- return slashIndex < 0 ? value : value.slice(0, slashIndex);
3910
- }
3911
- function hasLegacyButtonEffects(input) {
3912
- if (!isUnknownRecord(input)) return false;
3913
- return [
3914
- "base",
3915
- "hover",
3916
- "active",
3917
- "focus"
3918
- ].some((state) => {
3919
- const effects = input[state];
3920
- return Array.isArray(effects) && effects.some((effect) => {
3921
- if (!isUnknownRecord(effect) || typeof effect.effectId !== "string") return true;
3922
- const classification = classifyButtonEffectId(effect.effectId);
3923
- if (classification !== "colour-transition" && classification !== "non-colour") return true;
3924
- return effect.effectId === "background-on-hover" && isUnknownRecord(effect.options) && stripLegacyTokenAlpha(effect.options.colorToken) !== effect.options.colorToken;
3925
- });
3926
- });
3927
- }
3928
- function normalizeLegacyButtonEffects(input, backgroundType) {
3929
- if (!isUnknownRecord(input)) return input;
3930
- const normalized = {};
3931
- for (const state of [
3932
- "base",
3933
- "hover",
3934
- "active",
3935
- "focus"
3936
- ]) {
3937
- const effects = input[state];
3938
- if (!Array.isArray(effects)) continue;
3939
- const safeEffects = effects.flatMap((effect) => {
3940
- if (!isUnknownRecord(effect) || typeof effect.effectId !== "string") return [];
3941
- const classification = classifyButtonEffectId(effect.effectId);
3942
- if (classification === "non-colour") return [effect];
3943
- if (classification !== "colour-transition") return [];
3944
- if (effect.effectId === "background-on-hover") {
3945
- const options = isUnknownRecord(effect.options) ? effect.options : null;
3946
- const colorToken = options === null ? null : parseOpaqueButtonColourToken(stripLegacyTokenAlpha(options.colorToken));
3947
- return colorToken === null ? [] : [{
3948
- ...effect,
3949
- options: {
3950
- ...options,
3951
- colorToken
3952
- }
3953
- }];
3954
- }
3955
- if (backgroundType !== "solid") return [];
3956
- const rawAmount = isUnknownRecord(effect.options) ? effect.options.amount : void 0;
3957
- const amount = typeof rawAmount === "number" && rawAmount > 0 ? Math.max(100, Math.round(rawAmount / 100) * 100) : 100;
3958
- return [{
3959
- ...effect,
3960
- options: {
3961
- ...isUnknownRecord(effect.options) ? effect.options : {},
3962
- amount
3963
- }
3964
- }];
3965
- });
3966
- if (safeEffects.length > 0) normalized[state] = safeEffects;
3967
- }
3968
- return Object.keys(normalized).length === 0 ? void 0 : normalized;
3719
+ function surfaceForegroundValue(role, outsideProviderFallback = DEFAULT_ROLE_FALLBACKS[role]) {
3720
+ const roleVariable = SURFACE_FOREGROUND_CSS_VARS[role];
3721
+ const fallback = requireSurfaceColorValue("fallback", outsideProviderFallback);
3722
+ if (role === "text") return `var(${roleVariable}, ${fallback})`;
3723
+ return `var(${roleVariable}, var(${SURFACE_FOREGROUND_CSS_VARS.text}, ${fallback}))`;
3969
3724
  }
3970
- function isUnknownRecord(value) {
3971
- return typeof value === "object" && value !== null && !Array.isArray(value);
3725
+ function surfaceForegroundValueWithOpacity(role, opacityPercent) {
3726
+ if (!Number.isFinite(opacityPercent) || opacityPercent < 0 || opacityPercent > 100) throw new RangeError("Surface foreground opacity must be between 0 and 100.");
3727
+ return `color-mix(in srgb, ${surfaceForegroundValue(role)} ${opacityPercent}%, transparent)`;
3972
3728
  }
3973
- function isUnknownArray(value) {
3974
- return Array.isArray(value);
3729
+ function surfaceForegroundStyle(input) {
3730
+ const foregrounds = completeSurfaceForegrounds(input);
3731
+ return {
3732
+ color: foregrounds.text,
3733
+ [SURFACE_FOREGROUND_CSS_VARS.text]: foregrounds.text,
3734
+ [SURFACE_FOREGROUND_CSS_VARS.heading]: foregrounds.heading,
3735
+ [SURFACE_FOREGROUND_CSS_VARS.link]: foregrounds.link,
3736
+ [SURFACE_FOREGROUND_CSS_VARS.supporting]: foregrounds.supporting
3737
+ };
3975
3738
  }
3976
3739
  buttonSizeNameSchema.options;
3977
3740
  //#endregion
3978
- //#region ../theme-core/src/buttons/personalities/types.ts
3979
- function asButtonPersonalityId(value) {
3980
- if (value.length === 0) throw new Error("ButtonPersonalityId must be a non-empty string");
3981
- return value;
3741
+ //#region ../theme-core/src/buttons/styles/domain.ts
3742
+ const PUBLIC_BUTTON_ROLES = [
3743
+ "primary",
3744
+ "secondary",
3745
+ "outline",
3746
+ "ghost",
3747
+ "accent"
3748
+ ];
3749
+ function defineButtonStyleRecipe(recipe) {
3750
+ return recipe;
3751
+ }
3752
+ function materializeButtonRoles(definitions) {
3753
+ const primary = materializeCompleteRole("primary", definitions.primary.appearance);
3754
+ const secondary = materializeCompleteRole("secondary", definitions.secondary.appearance);
3755
+ const completeRoles = {
3756
+ primary,
3757
+ secondary
3758
+ };
3759
+ return {
3760
+ primary,
3761
+ secondary,
3762
+ outline: materializeSupportingRole("outline", definitions.outline, completeRoles),
3763
+ ghost: materializeSupportingRole("ghost", definitions.ghost, completeRoles),
3764
+ accent: materializeSupportingRole("accent", definitions.accent, completeRoles)
3765
+ };
3982
3766
  }
3983
- const buttonPersonalityIdSchema = z$1.string().min(1).transform((value) => asButtonPersonalityId(value));
3984
- z$1.object({
3985
- id: buttonPersonalityIdSchema,
3986
- name: z$1.string().min(1),
3987
- description: z$1.string().min(1),
3988
- tags: styleTagsSchema,
3989
- buttonSystem: buttonSystemSchema
3990
- });
3991
- /**
3992
- * Helper for personality file modules to keep the call site short and
3993
- * type-safe. `as const satisfies ...` would also work but produces wider
3994
- * types at use sites.
3995
- */
3996
- function defineButtonPersonality(input) {
3767
+ function resolveButtonStyleRecipe(recipe, parameters) {
3768
+ const parsedParameters = recipe.parameterSchema.safeParse(parameters);
3769
+ if (!parsedParameters.success) return {
3770
+ kind: "error",
3771
+ error: {
3772
+ kind: "invalid-parameters",
3773
+ styleId: recipe.id,
3774
+ issues: parsedParameters.error.issues.map((issue) => issue.message)
3775
+ }
3776
+ };
3777
+ const definition = recipe.defineSystem(parsedParameters.data);
3778
+ const roles = materializeButtonRoles(definition.roles);
3779
+ const buttonSystem = {
3780
+ global: definition.global,
3781
+ variants: PUBLIC_BUTTON_ROLES.map((role) => roles[role]),
3782
+ ...definition.sizes ? { sizes: definition.sizes } : {}
3783
+ };
3784
+ const parsedButtonSystem = buttonSystemSchema.safeParse(buttonSystem);
3785
+ if (!parsedButtonSystem.success) return {
3786
+ kind: "error",
3787
+ error: {
3788
+ kind: "invalid-button-system",
3789
+ styleId: recipe.id,
3790
+ issues: parsedButtonSystem.error.issues.map((issue) => issue.message)
3791
+ }
3792
+ };
3997
3793
  return {
3998
- id: asButtonPersonalityId(input.id),
3999
- name: input.name,
4000
- description: input.description,
4001
- tags: input.tags,
4002
- buttonSystem: buttonSystemSchema.parse(input.buttonSystem)
3794
+ kind: "resolved",
3795
+ buttonSystem: parsedButtonSystem.data
4003
3796
  };
4004
3797
  }
3798
+ function materializeSupportingRole(role, definition, completeRoles) {
3799
+ if (definition.kind === "complete") return materializeCompleteRole(role, definition.appearance);
3800
+ return {
3801
+ ...completeRoles[definition.from],
3802
+ ...definition.overrides,
3803
+ id: role,
3804
+ name: roleName(role),
3805
+ enabled: true,
3806
+ priority: 3
3807
+ };
3808
+ }
3809
+ function materializeCompleteRole(role, appearance) {
3810
+ return {
3811
+ ...appearance,
3812
+ id: role,
3813
+ name: roleName(role),
3814
+ enabled: true,
3815
+ priority: rolePriority(role)
3816
+ };
3817
+ }
3818
+ function roleName(role) {
3819
+ return role.charAt(0).toUpperCase() + role.slice(1);
3820
+ }
3821
+ function rolePriority(role) {
3822
+ if (role === "primary") return 1;
3823
+ if (role === "secondary") return 2;
3824
+ return 3;
3825
+ }
3826
+ //#endregion
3827
+ //#region ../theme-core/src/buttons/styles/selection.ts
3828
+ const BUTTON_STYLE_IDS = [
3829
+ "soft-pill",
3830
+ "earth-pill",
3831
+ "confident-chip",
3832
+ "editorial-link",
3833
+ "pebble",
3834
+ "ink-stamp",
3835
+ "flat-ink",
3836
+ "brushed-wash",
3837
+ "showtime-pill",
3838
+ "joy-stamp",
3839
+ "ornate-ritual",
3840
+ "quiet-arrow"
3841
+ ];
3842
+ const quietArrowParametersSchema = z$1.object({ secondaryTreatment: z$1.enum(["outlined", "solid-accent"]) }).strict();
3843
+ const emptyParametersSchema$1 = z$1.object({}).strict();
3844
+ function selectionBranch(styleId, parameters) {
3845
+ return z$1.object({
3846
+ styleId: z$1.literal(styleId),
3847
+ parameters
3848
+ }).strict();
3849
+ }
3850
+ const buttonStyleSelectionSchema = z$1.discriminatedUnion("styleId", [
3851
+ selectionBranch("soft-pill", emptyParametersSchema$1),
3852
+ selectionBranch("earth-pill", emptyParametersSchema$1),
3853
+ selectionBranch("confident-chip", emptyParametersSchema$1),
3854
+ selectionBranch("editorial-link", emptyParametersSchema$1),
3855
+ selectionBranch("pebble", emptyParametersSchema$1),
3856
+ selectionBranch("ink-stamp", emptyParametersSchema$1),
3857
+ selectionBranch("flat-ink", emptyParametersSchema$1),
3858
+ selectionBranch("brushed-wash", emptyParametersSchema$1),
3859
+ selectionBranch("showtime-pill", emptyParametersSchema$1),
3860
+ selectionBranch("joy-stamp", emptyParametersSchema$1),
3861
+ selectionBranch("ornate-ritual", emptyParametersSchema$1),
3862
+ selectionBranch("quiet-arrow", quietArrowParametersSchema)
3863
+ ]);
4005
3864
  //#endregion
4006
- //#region ../theme-core/src/buttons/personalities/brushed-wash.ts
4007
- /**
4008
- * Brushed Wash — gradient backgrounds that read as watercolour washes.
4009
- * Generous padding, soft shadows; pairs with vibrant organic brands.
4010
- */
4011
- const brushedWash = defineButtonPersonality({
4012
- id: "brushed-wash",
4013
- name: "Brushed Wash",
4014
- description: "Watercolour-gradient buttons with soft shadows and generous padding.",
3865
+ //#region ../theme-core/src/buttons/styles/recipes/quietArrow.ts
3866
+ const quietArrowRecipe = defineButtonStyleRecipe({
3867
+ id: "quiet-arrow",
3868
+ accessibilityLabel: "Wide uppercase buttons with trailing arrows",
4015
3869
  tags: {
4016
3870
  tone: "classic",
4017
- energy: "vibrant",
4018
- motion: "standard",
4019
- era: "organic"
3871
+ energy: "calm",
3872
+ motion: "subtle",
3873
+ era: "editorial"
4020
3874
  },
4021
- buttonSystem: {
3875
+ parameterSchema: quietArrowParametersSchema,
3876
+ defaultParameters: { secondaryTreatment: "outlined" },
3877
+ controls: [{
3878
+ kind: "choice",
3879
+ parameter: "secondaryTreatment",
3880
+ label: "Secondary button treatment",
3881
+ options: [{
3882
+ value: "outlined",
3883
+ label: "Outlined"
3884
+ }, {
3885
+ value: "solid-accent",
3886
+ label: "Solid accent"
3887
+ }]
3888
+ }],
3889
+ defineSystem: (parameters) => ({
4022
3890
  global: {
4023
3891
  cornerStyle: "rounded",
4024
- shadow: "low",
4025
- textTransform: "none",
3892
+ textTransform: "uppercase",
4026
3893
  fontWeight: 500,
4027
- borderWidth: 1,
3894
+ typography: "body",
3895
+ fontSize: "text-sm",
3896
+ letterSpacing: "loose",
4028
3897
  hoverTransform: "none",
4029
3898
  hoverColor: "none"
4030
3899
  },
4031
3900
  sizes: {
4032
3901
  sm: {
4033
- padding: "0.75rem 2rem",
3902
+ padding: "0.625rem 1.25rem",
3903
+ fontSize: "text-xs"
3904
+ },
3905
+ md: {
3906
+ padding: "0.8125rem 1.75rem",
4034
3907
  fontSize: "text-sm"
4035
3908
  },
4036
- md: { padding: "1rem 2.5rem" },
4037
3909
  lg: {
4038
- padding: "1.25rem 3rem",
4039
- fontSize: "text-lg"
3910
+ padding: "0.9375rem 2.125rem",
3911
+ fontSize: "text-sm"
4040
3912
  },
4041
3913
  xl: {
4042
- padding: "1.625rem 3.75rem",
4043
- fontSize: "text-xl"
3914
+ padding: "1.0625rem 2.5rem",
3915
+ fontSize: "text-base"
4044
3916
  }
4045
3917
  },
4046
- variants: [
4047
- {
4048
- id: "primary",
4049
- name: "Primary",
4050
- enabled: true,
4051
- priority: 1,
4052
- background: {
4053
- type: "gradient",
4054
- stops: ["primary", "accent"],
4055
- direction: "to-r",
4056
- foregroundToken: "primaryForeground"
4057
- },
4058
- borderRadius: "rounded-lg",
4059
- shadow: {
4060
- elevation: "low",
4061
- softness: "soft",
4062
- position: "bottom"
3918
+ roles: {
3919
+ primary: {
3920
+ kind: "complete",
3921
+ appearance: {
3922
+ background: {
3923
+ type: "solid",
3924
+ colorToken: unsafeAsOpaqueButtonColourToken("primary")
3925
+ },
3926
+ borderRadius: "rounded-xl",
3927
+ affordance: { iconId: "ArrowRight" },
3928
+ effects: { hover: [{
3929
+ effectId: "darken-background",
3930
+ options: { amount: 100 }
3931
+ }] }
4063
3932
  }
4064
3933
  },
4065
- {
4066
- id: "secondary",
4067
- name: "Secondary",
4068
- enabled: true,
4069
- priority: 2,
4070
- background: {
4071
- type: "gradient",
4072
- stops: ["secondary", "accent"],
4073
- direction: "to-br",
4074
- foregroundToken: "primaryForeground"
4075
- },
4076
- borderRadius: "rounded-lg",
4077
- shadow: {
4078
- elevation: "low",
4079
- softness: "soft",
4080
- position: "bottom"
3934
+ secondary: {
3935
+ kind: "complete",
3936
+ appearance: parameters.secondaryTreatment === "solid-accent" ? {
3937
+ background: {
3938
+ type: "solid",
3939
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
3940
+ },
3941
+ borderRadius: "rounded-xl",
3942
+ affordance: { iconId: "ArrowRight" },
3943
+ effects: { hover: [{
3944
+ effectId: "darken-background",
3945
+ options: { amount: 100 }
3946
+ }] }
3947
+ } : {
3948
+ background: {
3949
+ type: "surface",
3950
+ role: "link"
3951
+ },
3952
+ borderRadius: "rounded-xl",
3953
+ border: { widthClass: "border" },
3954
+ affordance: { iconId: "ArrowRight" },
3955
+ effects: { hover: [{
3956
+ effectId: "background-on-hover",
3957
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
3958
+ }] }
4081
3959
  }
4082
3960
  },
4083
- {
4084
- id: "outline",
4085
- name: "Outline",
4086
- enabled: true,
4087
- priority: 3,
4088
- background: {
4089
- type: "surface",
4090
- role: "link"
4091
- },
4092
- borderRadius: "rounded-lg",
4093
- border: { widthClass: "border" },
4094
- effects: { hover: [{
4095
- effectId: "background-on-hover",
4096
- options: { colorToken: "surface" }
4097
- }] }
3961
+ outline: {
3962
+ kind: "complete",
3963
+ appearance: {
3964
+ background: {
3965
+ type: "surface",
3966
+ role: "link"
3967
+ },
3968
+ borderRadius: "rounded-xl",
3969
+ border: { widthClass: "border" }
3970
+ }
4098
3971
  },
4099
- {
4100
- id: "ghost",
4101
- name: "Ghost",
4102
- enabled: true,
4103
- priority: 3,
4104
- background: {
4105
- type: "surface",
4106
- role: "link"
4107
- },
4108
- borderRadius: "rounded-lg",
4109
- effects: { hover: [{
4110
- effectId: "background-on-hover",
4111
- options: { colorToken: "surface" }
4112
- }] }
3972
+ ghost: {
3973
+ kind: "complete",
3974
+ appearance: {
3975
+ background: {
3976
+ type: "surface",
3977
+ role: "link"
3978
+ },
3979
+ borderRadius: "rounded-xl"
3980
+ }
3981
+ },
3982
+ accent: {
3983
+ kind: "derive",
3984
+ from: "primary",
3985
+ overrides: { background: {
3986
+ type: "solid",
3987
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
3988
+ } }
4113
3989
  }
4114
- ]
4115
- }
3990
+ }
3991
+ })
4116
3992
  });
4117
3993
  //#endregion
4118
- //#region ../theme-core/src/buttons/personalities/confident-chip.ts
4119
- /**
4120
- * Confident Chip — moderate-radius solid buttons that read as competent and
4121
- * direct. Default for Clear Professional; works for any modern brand voice.
4122
- */
4123
- const confidentChip = defineButtonPersonality({
4124
- id: "confident-chip",
4125
- name: "Confident Chip",
4126
- description: "Mid-radius solid buttons with a crisp hover.",
3994
+ //#region ../theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.ts
3995
+ const emptyParametersSchema = z$1.object({}).strict();
3996
+ function defineStaticButtonStyleRecipe(input) {
3997
+ const system = normalizeSystem(input.system);
3998
+ return defineButtonStyleRecipe({
3999
+ id: input.id,
4000
+ accessibilityLabel: input.accessibilityLabel,
4001
+ tags: input.tags,
4002
+ parameterSchema: emptyParametersSchema,
4003
+ defaultParameters: {},
4004
+ controls: [],
4005
+ defineSystem: () => system
4006
+ });
4007
+ }
4008
+ function normalizeSystem(input) {
4009
+ return {
4010
+ global: buttonGlobalSettingsSchema.parse(input.global),
4011
+ ...input.sizes ? { sizes: input.sizes } : {},
4012
+ roles: {
4013
+ primary: normalizeCompleteRole(input.roles.primary),
4014
+ secondary: normalizeCompleteRole(input.roles.secondary),
4015
+ outline: normalizeSupportingRole(input.roles.outline),
4016
+ ghost: normalizeSupportingRole(input.roles.ghost),
4017
+ accent: normalizeSupportingRole(input.roles.accent)
4018
+ }
4019
+ };
4020
+ }
4021
+ function normalizeCompleteRole(role) {
4022
+ return {
4023
+ kind: "complete",
4024
+ appearance: normalizeAppearance(role.appearance)
4025
+ };
4026
+ }
4027
+ function normalizeSupportingRole(role) {
4028
+ if (role.kind === "complete") return normalizeCompleteRole(role);
4029
+ return {
4030
+ kind: "derive",
4031
+ from: role.from,
4032
+ ...role.overrides ? { overrides: normalizeAppearanceOverrides(role.overrides) } : {}
4033
+ };
4034
+ }
4035
+ function normalizeAppearance(appearance) {
4036
+ const { background, hoverBackgroundToken, ...rest } = appearance;
4037
+ return {
4038
+ ...rest,
4039
+ background: buttonColourTreatmentSchema.parse(background),
4040
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
4041
+ };
4042
+ }
4043
+ function normalizeAppearanceOverrides(overrides) {
4044
+ const { background, hoverBackgroundToken, ...rest } = overrides;
4045
+ return {
4046
+ ...rest,
4047
+ ...background ? { background: buttonColourTreatmentSchema.parse(background) } : {},
4048
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
4049
+ };
4050
+ }
4051
+ //#endregion
4052
+ //#region ../theme-core/src/buttons/styles/recipes/staticRecipes.ts
4053
+ const softPillRecipe = defineStaticButtonStyleRecipe({
4054
+ id: "soft-pill",
4055
+ accessibilityLabel: "Rounded pill buttons with a gentle hover lift",
4127
4056
  tags: {
4128
4057
  tone: "classic",
4129
4058
  energy: "calm",
4130
- motion: "standard",
4131
- era: "modern"
4059
+ motion: "subtle",
4060
+ era: "organic"
4132
4061
  },
4133
- buttonSystem: {
4062
+ system: {
4134
4063
  global: {
4135
- cornerStyle: "rounded",
4136
- shadow: "medium",
4064
+ cornerStyle: "pill",
4065
+ shadow: "low",
4137
4066
  textTransform: "none",
4138
- fontWeight: 600,
4139
- borderWidth: 1,
4140
- hoverTransform: "none",
4067
+ fontWeight: 500,
4068
+ hoverTransform: "lift",
4141
4069
  hoverColor: "none"
4142
4070
  },
4143
- variants: [
4144
- {
4145
- id: "primary",
4146
- name: "Primary",
4147
- enabled: true,
4148
- priority: 1,
4149
- background: {
4150
- type: "solid",
4151
- colorToken: "primary"
4152
- },
4153
- borderRadius: "rounded-md",
4154
- shadow: {
4155
- elevation: "medium",
4156
- softness: "soft",
4157
- position: "bottom"
4158
- },
4159
- effects: {
4160
- hover: [{
4161
- effectId: "darken-background",
4162
- options: { amount: 100 }
4163
- }],
4164
- active: [{
4165
- effectId: "scale-down",
4166
- options: { scale: "0.97" }
4167
- }]
4071
+ roles: {
4072
+ primary: {
4073
+ kind: "complete",
4074
+ appearance: {
4075
+ background: {
4076
+ type: "solid",
4077
+ colorToken: "primary"
4078
+ },
4079
+ borderRadius: "rounded-full",
4080
+ shadow: {
4081
+ elevation: "low",
4082
+ softness: "soft",
4083
+ position: "bottom"
4084
+ },
4085
+ effects: {
4086
+ hover: [{ effectId: "lift" }],
4087
+ active: [{
4088
+ effectId: "scale-down",
4089
+ options: { scale: "0.98" }
4090
+ }]
4091
+ }
4168
4092
  }
4169
4093
  },
4170
- {
4171
- id: "secondary",
4172
- name: "Secondary",
4173
- enabled: true,
4174
- priority: 2,
4175
- background: {
4176
- type: "solid",
4177
- colorToken: "surface"
4178
- },
4179
- borderRadius: "rounded-md",
4180
- border: { widthClass: "border" },
4181
- effects: { hover: [{
4182
- effectId: "background-on-hover",
4183
- options: { colorToken: "background" }
4184
- }] }
4094
+ secondary: {
4095
+ kind: "complete",
4096
+ appearance: {
4097
+ background: {
4098
+ type: "surface",
4099
+ role: "link"
4100
+ },
4101
+ borderRadius: "rounded-full",
4102
+ border: { widthClass: "border-2" },
4103
+ effects: { hover: [{
4104
+ effectId: "background-on-hover",
4105
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4106
+ }] }
4107
+ }
4185
4108
  },
4186
- {
4187
- id: "outline",
4188
- name: "Outline",
4189
- enabled: true,
4190
- priority: 3,
4191
- background: {
4192
- type: "surface",
4193
- role: "link"
4194
- },
4195
- borderRadius: "rounded-md",
4196
- border: { widthClass: "border" },
4197
- effects: { hover: [{
4198
- effectId: "background-on-hover",
4199
- options: { colorToken: "surface" }
4200
- }] }
4109
+ outline: {
4110
+ kind: "complete",
4111
+ appearance: {
4112
+ background: {
4113
+ type: "surface",
4114
+ role: "link"
4115
+ },
4116
+ borderRadius: "rounded-full",
4117
+ border: { widthClass: "border" },
4118
+ effects: { hover: [{
4119
+ effectId: "background-on-hover",
4120
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4121
+ }] }
4122
+ }
4201
4123
  },
4202
- {
4203
- id: "ghost",
4204
- name: "Ghost",
4205
- enabled: true,
4206
- priority: 3,
4207
- background: {
4208
- type: "surface",
4209
- role: "link"
4210
- },
4211
- borderRadius: "rounded-md",
4212
- effects: { hover: [{
4213
- effectId: "background-on-hover",
4214
- options: { colorToken: "surface" }
4215
- }] }
4124
+ ghost: {
4125
+ kind: "complete",
4126
+ appearance: {
4127
+ background: {
4128
+ type: "surface",
4129
+ role: "link"
4130
+ },
4131
+ borderRadius: "rounded-full",
4132
+ effects: { hover: [{
4133
+ effectId: "background-on-hover",
4134
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4135
+ }] }
4136
+ }
4137
+ },
4138
+ accent: {
4139
+ kind: "derive",
4140
+ from: "primary",
4141
+ overrides: { background: {
4142
+ type: "solid",
4143
+ colorToken: "accent"
4144
+ } }
4216
4145
  }
4217
- ]
4146
+ }
4218
4147
  }
4219
4148
  });
4220
- //#endregion
4221
- //#region ../theme-core/src/buttons/personalities/earth-pill.ts
4222
- /**
4223
- * Earth Pill - warm studio pills with compact, primary-coloured ghost CTAs.
4224
- * Built for grounded editorial wellness styles such as Soft Earth.
4225
- */
4226
- const earthPill = defineButtonPersonality({
4149
+ const earthPillRecipe = defineStaticButtonStyleRecipe({
4227
4150
  id: "earth-pill",
4228
- name: "Earth Pill",
4229
- description: "Compact terracotta pills with quiet primary-coloured ghost CTAs.",
4151
+ accessibilityLabel: "Compact rounded buttons with a quiet hover lift",
4230
4152
  tags: {
4231
4153
  tone: "classic",
4232
4154
  energy: "calm",
4233
4155
  motion: "subtle",
4234
4156
  era: "organic"
4235
4157
  },
4236
- buttonSystem: {
4158
+ system: {
4237
4159
  global: {
4238
4160
  cornerStyle: "pill",
4239
4161
  shadow: "low",
4240
4162
  textTransform: "none",
4241
4163
  fontWeight: 500,
4242
- borderWidth: 1,
4243
4164
  hoverTransform: "lift",
4244
4165
  hoverColor: "none",
4245
4166
  typography: "body",
@@ -4260,948 +4181,786 @@ const earthPill = defineButtonPersonality({
4260
4181
  fontSize: "text-xl"
4261
4182
  }
4262
4183
  },
4263
- variants: [
4264
- {
4265
- id: "primary",
4266
- name: "Primary",
4267
- enabled: true,
4268
- priority: 1,
4269
- background: {
4270
- type: "solid",
4271
- colorToken: "primary"
4272
- },
4273
- borderRadius: "rounded-full",
4274
- shadow: {
4275
- elevation: "low",
4276
- softness: "soft",
4277
- position: "bottom"
4278
- },
4279
- effects: {
4280
- hover: [{
4281
- effectId: "lift",
4282
- options: { translateY: "-1px" }
4283
- }, {
4284
- effectId: "background-on-hover",
4285
- options: { colorToken: "accent" }
4286
- }],
4287
- active: [{
4288
- effectId: "scale-down",
4289
- options: { scale: "0.98" }
4290
- }]
4184
+ roles: {
4185
+ primary: {
4186
+ kind: "complete",
4187
+ appearance: {
4188
+ background: {
4189
+ type: "solid",
4190
+ colorToken: "primary"
4191
+ },
4192
+ borderRadius: "rounded-full",
4193
+ shadow: {
4194
+ elevation: "low",
4195
+ softness: "soft",
4196
+ position: "bottom"
4197
+ },
4198
+ effects: {
4199
+ hover: [{ effectId: "lift" }, {
4200
+ effectId: "background-on-hover",
4201
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
4202
+ }],
4203
+ active: [{
4204
+ effectId: "scale-down",
4205
+ options: { scale: "0.98" }
4206
+ }]
4207
+ }
4291
4208
  }
4292
4209
  },
4293
- {
4294
- id: "secondary",
4295
- name: "Secondary",
4296
- enabled: true,
4297
- priority: 2,
4298
- background: {
4299
- type: "surface",
4300
- role: "link"
4301
- },
4302
- borderRadius: "rounded-full",
4303
- border: { widthClass: "border" },
4304
- effects: { hover: [{
4305
- effectId: "background-on-hover",
4306
- options: { colorToken: "muted" }
4307
- }] }
4210
+ secondary: {
4211
+ kind: "complete",
4212
+ appearance: {
4213
+ background: {
4214
+ type: "surface",
4215
+ role: "link"
4216
+ },
4217
+ borderRadius: "rounded-full",
4218
+ border: { widthClass: "border" },
4219
+ effects: { hover: [{
4220
+ effectId: "background-on-hover",
4221
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
4222
+ }] }
4223
+ }
4308
4224
  },
4309
- {
4310
- id: "outline",
4311
- name: "Outline",
4312
- enabled: true,
4313
- priority: 3,
4314
- background: {
4315
- type: "surface",
4316
- role: "link"
4317
- },
4318
- borderRadius: "rounded-full",
4319
- border: { widthClass: "border" },
4320
- effects: { hover: [{
4321
- effectId: "background-on-hover",
4322
- options: { colorToken: "surfaceAlt" }
4323
- }] }
4225
+ outline: {
4226
+ kind: "complete",
4227
+ appearance: {
4228
+ background: {
4229
+ type: "surface",
4230
+ role: "link"
4231
+ },
4232
+ borderRadius: "rounded-full",
4233
+ border: { widthClass: "border" },
4234
+ effects: { hover: [{
4235
+ effectId: "background-on-hover",
4236
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
4237
+ }] }
4238
+ }
4324
4239
  },
4325
- {
4326
- id: "ghost",
4327
- name: "Ghost",
4328
- enabled: true,
4329
- priority: 3,
4330
- background: {
4331
- type: "surface",
4332
- role: "link"
4333
- },
4334
- borderRadius: "rounded-full",
4335
- shadow: {
4336
- elevation: "none",
4337
- softness: null,
4338
- position: "bottom"
4339
- },
4340
- sizes: {
4341
- sm: {
4342
- padding: "0.25rem 0",
4343
- fontSize: "text-sm"
4240
+ ghost: {
4241
+ kind: "complete",
4242
+ appearance: {
4243
+ background: {
4244
+ type: "surface",
4245
+ role: "link"
4344
4246
  },
4345
- md: { padding: "0.375rem 0" },
4346
- lg: {
4347
- padding: "0.5rem 0",
4348
- fontSize: "text-lg"
4247
+ borderRadius: "rounded-full",
4248
+ shadow: {
4249
+ elevation: "none",
4250
+ softness: null,
4251
+ position: "bottom"
4349
4252
  },
4350
- xl: {
4351
- padding: "0.625rem 0",
4352
- fontSize: "text-xl"
4253
+ sizes: {
4254
+ sm: {
4255
+ padding: "0.25rem 0",
4256
+ fontSize: "text-sm"
4257
+ },
4258
+ md: { padding: "0.375rem 0" },
4259
+ lg: {
4260
+ padding: "0.5rem 0",
4261
+ fontSize: "text-lg"
4262
+ },
4263
+ xl: {
4264
+ padding: "0.625rem 0",
4265
+ fontSize: "text-xl"
4266
+ }
4353
4267
  }
4354
4268
  }
4269
+ },
4270
+ accent: {
4271
+ kind: "derive",
4272
+ from: "primary",
4273
+ overrides: { background: {
4274
+ type: "solid",
4275
+ colorToken: "accent"
4276
+ } }
4355
4277
  }
4356
- ]
4278
+ }
4357
4279
  }
4358
4280
  });
4359
- //#endregion
4360
- //#region ../theme-core/src/buttons/personalities/editorial-link.ts
4361
- /**
4362
- * Editorial Link — all variants are link-style with a growing underline.
4363
- * Default for Warm Editorial and Quiet Luxury; reads as refined and quiet.
4364
- */
4365
- const editorialLink = defineButtonPersonality({
4366
- id: "editorial-link",
4367
- name: "Editorial Link",
4368
- description: "Link-style with a growing underline. Refined, typographic.",
4281
+ const confidentChipRecipe = defineStaticButtonStyleRecipe({
4282
+ id: "confident-chip",
4283
+ accessibilityLabel: "Moderately rounded solid buttons with a crisp hover",
4369
4284
  tags: {
4370
- tone: "minimal",
4285
+ tone: "classic",
4371
4286
  energy: "calm",
4372
- motion: "subtle",
4373
- era: "editorial"
4287
+ motion: "standard",
4288
+ era: "modern"
4374
4289
  },
4375
- buttonSystem: {
4290
+ system: {
4376
4291
  global: {
4377
- cornerStyle: "square",
4292
+ cornerStyle: "rounded",
4293
+ shadow: "medium",
4378
4294
  textTransform: "none",
4379
- fontWeight: 500,
4380
- borderWidth: 1,
4295
+ fontWeight: 600,
4381
4296
  hoverTransform: "none",
4382
4297
  hoverColor: "none"
4383
4298
  },
4384
- variants: [
4385
- {
4386
- id: "primary",
4387
- name: "Primary",
4388
- enabled: true,
4389
- priority: 1,
4390
- background: {
4391
- type: "surface",
4392
- role: "link"
4393
- },
4394
- borderRadius: "rounded-none",
4395
- sizes: {
4396
- sm: { padding: "0.25rem 0" },
4397
- md: { padding: "0.5rem 0" },
4398
- lg: { padding: "0.625rem 0" },
4399
- xl: { padding: "0.75rem 0" }
4400
- },
4401
- effects: { base: [{
4402
- effectId: "border-bottom-grow",
4403
- options: {
4404
- height: 2,
4405
- colorToken: "text",
4406
- origin: "left"
4299
+ roles: {
4300
+ primary: {
4301
+ kind: "complete",
4302
+ appearance: {
4303
+ background: {
4304
+ type: "solid",
4305
+ colorToken: "primary"
4306
+ },
4307
+ borderRadius: "rounded-md",
4308
+ shadow: {
4309
+ elevation: "medium",
4310
+ softness: "soft",
4311
+ position: "bottom"
4312
+ },
4313
+ effects: {
4314
+ hover: [{
4315
+ effectId: "darken-background",
4316
+ options: { amount: 100 }
4317
+ }],
4318
+ active: [{
4319
+ effectId: "scale-down",
4320
+ options: { scale: "0.97" }
4321
+ }]
4407
4322
  }
4408
- }] }
4323
+ }
4409
4324
  },
4410
- {
4411
- id: "secondary",
4412
- name: "Secondary",
4413
- enabled: true,
4414
- priority: 2,
4415
- background: {
4416
- type: "surface",
4417
- role: "link"
4418
- },
4419
- borderRadius: "rounded-none",
4420
- sizes: {
4421
- sm: { padding: "0.25rem 0" },
4422
- md: { padding: "0.5rem 0" },
4423
- lg: { padding: "0.625rem 0" },
4424
- xl: { padding: "0.75rem 0" }
4425
- },
4426
- effects: { base: [{
4427
- effectId: "border-bottom-grow",
4428
- options: {
4429
- height: 1,
4430
- colorToken: "mutedText",
4431
- origin: "left"
4432
- }
4433
- }] }
4325
+ secondary: {
4326
+ kind: "complete",
4327
+ appearance: {
4328
+ background: {
4329
+ type: "solid",
4330
+ colorToken: "surface"
4331
+ },
4332
+ borderRadius: "rounded-md",
4333
+ border: { widthClass: "border" },
4334
+ effects: { hover: [{
4335
+ effectId: "background-on-hover",
4336
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
4337
+ }] }
4338
+ }
4434
4339
  },
4435
- {
4436
- id: "outline",
4437
- name: "Outline",
4438
- enabled: true,
4439
- priority: 3,
4440
- background: {
4441
- type: "surface",
4442
- role: "link"
4443
- },
4444
- borderRadius: "rounded-none",
4445
- sizes: {
4446
- sm: { padding: "0.25rem 0" },
4447
- md: { padding: "0.5rem 0" },
4448
- lg: { padding: "0.625rem 0" },
4449
- xl: { padding: "0.75rem 0" }
4450
- },
4451
- effects: { base: [{
4452
- effectId: "border-bottom-grow",
4453
- options: {
4454
- height: 1,
4455
- colorToken: "accent",
4456
- origin: "left"
4457
- }
4458
- }] }
4340
+ outline: {
4341
+ kind: "complete",
4342
+ appearance: {
4343
+ background: {
4344
+ type: "surface",
4345
+ role: "link"
4346
+ },
4347
+ borderRadius: "rounded-md",
4348
+ border: { widthClass: "border" },
4349
+ effects: { hover: [{
4350
+ effectId: "background-on-hover",
4351
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4352
+ }] }
4353
+ }
4459
4354
  },
4460
- {
4461
- id: "ghost",
4462
- name: "Ghost",
4463
- enabled: true,
4464
- priority: 3,
4465
- background: {
4466
- type: "surface",
4467
- role: "link"
4468
- },
4469
- borderRadius: "rounded-none",
4470
- sizes: {
4471
- sm: { padding: "0.25rem 0" },
4472
- md: { padding: "0.5rem 0" },
4473
- lg: { padding: "0.625rem 0" },
4474
- xl: { padding: "0.75rem 0" }
4355
+ ghost: {
4356
+ kind: "complete",
4357
+ appearance: {
4358
+ background: {
4359
+ type: "surface",
4360
+ role: "link"
4361
+ },
4362
+ borderRadius: "rounded-md",
4363
+ effects: { hover: [{
4364
+ effectId: "background-on-hover",
4365
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4366
+ }] }
4475
4367
  }
4368
+ },
4369
+ accent: {
4370
+ kind: "derive",
4371
+ from: "primary",
4372
+ overrides: { background: {
4373
+ type: "solid",
4374
+ colorToken: "accent"
4375
+ } }
4476
4376
  }
4477
- ]
4377
+ }
4478
4378
  }
4479
4379
  });
4480
- //#endregion
4481
- //#region ../theme-core/src/buttons/personalities/flat-ink.ts
4482
- /**
4483
- * Flat Ink — a solid ink primary, a hairline ghost secondary, and a single
4484
- * amber accent climax, all completely flat (no drop shadow) with a modest
4485
- * radius. Reads as grounded, editorial and clinician-precise: the Fulcrum
4486
- * physiotherapy voice. The primary shifts to the secondary (moss) on hover and
4487
- * every variant lifts 2px; the amber accent is meant to be used sparingly as
4488
- * the page's one conversion climax.
4489
- */
4490
- const flatInk = defineButtonPersonality({
4491
- id: "flat-ink",
4492
- name: "Flat Ink",
4493
- description: "Flat solid-ink primary, hairline ghost secondary, and a single amber accent climax — modest radius, no shadow.",
4380
+ const editorialSizes = {
4381
+ sm: { padding: "0.25rem 0" },
4382
+ md: { padding: "0.5rem 0" },
4383
+ lg: { padding: "0.625rem 0" },
4384
+ xl: { padding: "0.75rem 0" }
4385
+ };
4386
+ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
4387
+ id: "editorial-link",
4388
+ accessibilityLabel: "Flat typographic buttons with an underline treatment",
4494
4389
  tags: {
4495
- tone: "classic",
4390
+ tone: "minimal",
4496
4391
  energy: "calm",
4497
4392
  motion: "subtle",
4498
4393
  era: "editorial"
4499
4394
  },
4500
- buttonSystem: {
4395
+ system: {
4501
4396
  global: {
4502
- cornerStyle: "rounded",
4397
+ cornerStyle: "square",
4503
4398
  textTransform: "none",
4504
- fontWeight: 600,
4505
- borderWidth: 1,
4506
- typography: "body",
4507
- letterSpacing: "tight",
4508
- paddingPreset: "default",
4509
- hoverTransform: "lift",
4399
+ fontWeight: 500,
4400
+ hoverTransform: "none",
4510
4401
  hoverColor: "none"
4511
4402
  },
4512
- sizes: {
4513
- sm: {
4514
- padding: "0.625rem 1.125rem",
4515
- fontSize: "text-sm"
4403
+ roles: {
4404
+ primary: {
4405
+ kind: "complete",
4406
+ appearance: {
4407
+ background: {
4408
+ type: "surface",
4409
+ role: "link"
4410
+ },
4411
+ borderRadius: "rounded-none",
4412
+ sizes: editorialSizes,
4413
+ effects: { base: [{
4414
+ effectId: "border-bottom-grow",
4415
+ options: {
4416
+ height: 2,
4417
+ origin: "left"
4418
+ }
4419
+ }] }
4420
+ }
4516
4421
  },
4517
- md: { padding: "0.8125rem 1.375rem" },
4518
- lg: {
4519
- padding: "0.9375rem 1.625rem",
4520
- fontSize: "text-lg"
4422
+ secondary: {
4423
+ kind: "complete",
4424
+ appearance: {
4425
+ background: {
4426
+ type: "surface",
4427
+ role: "link"
4428
+ },
4429
+ borderRadius: "rounded-none",
4430
+ sizes: editorialSizes,
4431
+ effects: { base: [{
4432
+ effectId: "border-bottom-grow",
4433
+ options: {
4434
+ height: 1,
4435
+ origin: "left"
4436
+ }
4437
+ }] }
4438
+ }
4521
4439
  },
4522
- xl: {
4523
- padding: "1.0625rem 2rem",
4524
- fontSize: "text-xl"
4525
- }
4526
- },
4527
- variants: [
4528
- {
4529
- id: "primary",
4530
- name: "Primary",
4531
- enabled: true,
4532
- priority: 1,
4533
- background: {
4534
- type: "solid",
4535
- colorToken: "primary"
4536
- },
4537
- borderRadius: "rounded-lg",
4538
- affordance: { iconId: "ArrowRight" },
4539
- effects: { hover: [{
4540
- effectId: "lift",
4541
- options: { translateY: "-2px" }
4542
- }, {
4543
- effectId: "background-on-hover",
4544
- options: { colorToken: "secondary" }
4545
- }] }
4440
+ outline: {
4441
+ kind: "complete",
4442
+ appearance: {
4443
+ background: {
4444
+ type: "surface",
4445
+ role: "link"
4446
+ },
4447
+ borderRadius: "rounded-none",
4448
+ sizes: editorialSizes,
4449
+ effects: { base: [{
4450
+ effectId: "border-bottom-grow",
4451
+ options: {
4452
+ height: 1,
4453
+ origin: "left"
4454
+ }
4455
+ }] }
4456
+ }
4546
4457
  },
4547
- {
4548
- id: "secondary",
4549
- name: "Secondary",
4550
- enabled: true,
4551
- priority: 2,
4552
- background: {
4553
- type: "surface",
4554
- role: "link"
4555
- },
4556
- borderRadius: "rounded-lg",
4557
- border: { widthClass: "border" },
4558
- effects: { hover: [{
4559
- effectId: "lift",
4560
- options: { translateY: "-2px" }
4561
- }, {
4562
- effectId: "background-on-hover",
4563
- options: { colorToken: "surfaceAlt" }
4564
- }] }
4458
+ ghost: {
4459
+ kind: "complete",
4460
+ appearance: {
4461
+ background: {
4462
+ type: "surface",
4463
+ role: "link"
4464
+ },
4465
+ borderRadius: "rounded-none",
4466
+ sizes: editorialSizes
4467
+ }
4565
4468
  },
4566
- {
4567
- id: "accent",
4568
- name: "Accent",
4569
- enabled: true,
4570
- priority: 3,
4571
- background: {
4572
- type: "solid",
4573
- colorToken: "accent"
4574
- },
4575
- borderRadius: "rounded-lg",
4576
- affordance: { iconId: "ArrowRight" },
4577
- effects: { hover: [{
4578
- effectId: "lift",
4579
- options: { translateY: "-2px" }
4580
- }] }
4469
+ accent: {
4470
+ kind: "derive",
4471
+ from: "primary",
4472
+ overrides: { effects: { base: [{
4473
+ effectId: "border-bottom-grow",
4474
+ options: {
4475
+ height: 2,
4476
+ origin: "left"
4477
+ }
4478
+ }] } }
4581
4479
  }
4582
- ]
4480
+ }
4583
4481
  }
4584
4482
  });
4585
- //#endregion
4586
- //#region ../theme-core/src/buttons/personalities/ink-stamp.ts
4587
- /**
4588
- * Ink Stamp — solid earthy fills with a bordered, hand-stamped block-print
4589
- * feel. Reads as bold and handmade; suits expressive craft brands.
4590
- */
4591
- const inkStamp = defineButtonPersonality({
4592
- id: "ink-stamp",
4593
- name: "Ink Stamp",
4594
- description: "Hand-stamped block-print buttons with a slight lift on hover.",
4483
+ const pebbleRecipe = defineStaticButtonStyleRecipe({
4484
+ id: "pebble",
4485
+ accessibilityLabel: "Generously padded pill buttons",
4595
4486
  tags: {
4596
- tone: "bold",
4597
- energy: "vibrant",
4487
+ tone: "classic",
4488
+ energy: "calm",
4598
4489
  motion: "standard",
4599
4490
  era: "organic"
4600
4491
  },
4601
- buttonSystem: {
4492
+ system: {
4602
4493
  global: {
4603
- cornerStyle: "rounded",
4604
- textTransform: "uppercase",
4605
- fontWeight: 600,
4606
- borderWidth: 1,
4494
+ cornerStyle: "pill",
4495
+ textTransform: "none",
4496
+ fontWeight: 500,
4607
4497
  hoverTransform: "none",
4608
- hoverColor: "none",
4609
- letterSpacing: "loose"
4498
+ hoverColor: "none"
4610
4499
  },
4611
4500
  sizes: {
4612
4501
  sm: {
4613
- padding: "0.5rem 1.25rem",
4614
- fontSize: "text-xs"
4615
- },
4616
- md: {
4617
- padding: "0.75rem 1.75rem",
4502
+ padding: "0.625rem 1.75rem",
4618
4503
  fontSize: "text-sm"
4619
4504
  },
4505
+ md: { padding: "0.875rem 2.25rem" },
4620
4506
  lg: {
4621
- padding: "0.875rem 2.25rem",
4622
- fontSize: "text-base"
4623
- },
4624
- xl: {
4625
4507
  padding: "1.125rem 2.75rem",
4626
4508
  fontSize: "text-lg"
4509
+ },
4510
+ xl: {
4511
+ padding: "1.5rem 3.5rem",
4512
+ fontSize: "text-xl"
4627
4513
  }
4628
4514
  },
4629
- variants: [
4630
- {
4631
- id: "primary",
4632
- name: "Primary",
4633
- enabled: true,
4634
- priority: 1,
4635
- background: {
4636
- type: "solid",
4637
- colorToken: "primary"
4638
- },
4639
- borderRadius: "rounded-md",
4640
- effects: {
4641
- hover: [{
4642
- effectId: "drop-shadow",
4643
- options: { intensity: "medium" }
4644
- }, {
4645
- effectId: "scale-up",
4646
- options: { scale: "1.02" }
4647
- }],
4648
- active: [{
4649
- effectId: "scale-down",
4650
- options: { scale: "0.98" }
4651
- }]
4515
+ roles: {
4516
+ primary: {
4517
+ kind: "complete",
4518
+ appearance: {
4519
+ background: {
4520
+ type: "solid",
4521
+ colorToken: "primary"
4522
+ },
4523
+ borderRadius: "rounded-full",
4524
+ effects: { hover: [{
4525
+ effectId: "darken-background",
4526
+ options: { amount: 100 }
4527
+ }] }
4652
4528
  }
4653
4529
  },
4654
- {
4655
- id: "secondary",
4656
- name: "Secondary",
4657
- enabled: true,
4658
- priority: 2,
4659
- background: {
4660
- type: "surface",
4661
- role: "link"
4662
- },
4663
- borderRadius: "rounded-md",
4664
- border: { widthClass: "border-2" },
4665
- effects: { hover: [{
4666
- effectId: "background-on-hover",
4667
- options: { colorToken: "surface" }
4668
- }] }
4669
- },
4670
- {
4671
- id: "outline",
4672
- name: "Outline",
4673
- enabled: true,
4674
- priority: 3,
4675
- background: {
4676
- type: "surface",
4677
- role: "link"
4678
- },
4679
- borderRadius: "rounded-md",
4680
- border: { widthClass: "border-2" },
4681
- effects: { hover: [{
4682
- effectId: "background-on-hover",
4683
- options: { colorToken: "surface" }
4684
- }] }
4685
- },
4686
- {
4687
- id: "ghost",
4688
- name: "Ghost",
4689
- enabled: true,
4690
- priority: 3,
4691
- background: {
4692
- type: "surface",
4693
- role: "link"
4694
- },
4695
- borderRadius: "rounded-none",
4696
- sizes: {
4697
- sm: {
4698
- padding: "0.375rem 0",
4699
- fontSize: "text-xs"
4530
+ secondary: {
4531
+ kind: "complete",
4532
+ appearance: {
4533
+ background: {
4534
+ type: "surface",
4535
+ role: "link"
4700
4536
  },
4701
- md: {
4702
- padding: "0.5rem 0",
4703
- fontSize: "text-sm"
4537
+ borderRadius: "rounded-full",
4538
+ border: { widthClass: "border-2" },
4539
+ effects: { hover: [{
4540
+ effectId: "background-on-hover",
4541
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
4542
+ }] }
4543
+ }
4544
+ },
4545
+ outline: {
4546
+ kind: "complete",
4547
+ appearance: {
4548
+ background: {
4549
+ type: "surface",
4550
+ role: "link"
4704
4551
  },
4705
- lg: {
4706
- padding: "0.625rem 0",
4707
- fontSize: "text-base"
4552
+ borderRadius: "rounded-full",
4553
+ border: { widthClass: "border" },
4554
+ effects: { hover: [{
4555
+ effectId: "background-on-hover",
4556
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4557
+ }] }
4558
+ }
4559
+ },
4560
+ ghost: {
4561
+ kind: "complete",
4562
+ appearance: {
4563
+ background: {
4564
+ type: "surface",
4565
+ role: "link"
4708
4566
  },
4709
- xl: {
4710
- padding: "0.75rem 0",
4711
- fontSize: "text-lg"
4712
- }
4713
- },
4714
- effects: { base: [{
4715
- effectId: "border-bottom-grow",
4716
- options: {
4717
- height: 1,
4718
- colorToken: "accent",
4719
- origin: "left"
4567
+ borderRadius: "rounded-full",
4568
+ sizes: {
4569
+ sm: {
4570
+ padding: "0.375rem 0.875rem",
4571
+ fontSize: "text-sm"
4572
+ },
4573
+ md: { padding: "0.5rem 1rem" },
4574
+ lg: {
4575
+ padding: "0.625rem 1.25rem",
4576
+ fontSize: "text-lg"
4577
+ },
4578
+ xl: {
4579
+ padding: "0.75rem 1.5rem",
4580
+ fontSize: "text-xl"
4581
+ }
4720
4582
  }
4721
- }] }
4583
+ }
4584
+ },
4585
+ accent: {
4586
+ kind: "derive",
4587
+ from: "primary",
4588
+ overrides: { background: {
4589
+ type: "solid",
4590
+ colorToken: "accent"
4591
+ } }
4722
4592
  }
4723
- ]
4593
+ }
4724
4594
  }
4725
4595
  });
4726
- //#endregion
4727
- //#region ../theme-core/src/buttons/personalities/joy-stamp.ts
4728
- /**
4729
- * Joy Stamp — neo-brutalist pills with a hard, brand-coloured offset shadow
4730
- * that collapses as the button presses into it on hover. Authored for the
4731
- * Original Joy site style: a cream "stamp" shadow under the solid primary, and
4732
- * a brown shadow under the cream outline. Reads as bold, warm, and handmade.
4733
- *
4734
- * The coloured offset shadow relies on the per-variant `shadow.colorToken`
4735
- * extension; the press is the shared `press-down` effect, which matches its
4736
- * translate to each variant's own shadow offset.
4737
- */
4738
- const joyStamp = defineButtonPersonality({
4739
- id: "joy-stamp",
4740
- name: "Joy Stamp",
4741
- description: "Pill buttons with a hard, brand-coloured offset shadow that presses in on hover.",
4596
+ const brushedWashRecipe = defineStaticButtonStyleRecipe({
4597
+ id: "brushed-wash",
4598
+ accessibilityLabel: "Generously padded gradient buttons with soft shadows",
4742
4599
  tags: {
4743
- tone: "bold",
4600
+ tone: "classic",
4744
4601
  energy: "vibrant",
4745
- motion: "expressive",
4602
+ motion: "standard",
4746
4603
  era: "organic"
4747
4604
  },
4748
- buttonSystem: {
4605
+ system: {
4749
4606
  global: {
4750
- cornerStyle: "pill",
4751
- shadow: "high",
4607
+ cornerStyle: "rounded",
4608
+ shadow: "low",
4752
4609
  textTransform: "none",
4753
- typography: "heading",
4754
- fontWeight: 700,
4755
- fontSize: "text-lg",
4756
- borderWidth: 2,
4610
+ fontWeight: 500,
4757
4611
  hoverTransform: "none",
4758
4612
  hoverColor: "none"
4759
4613
  },
4760
4614
  sizes: {
4761
4615
  sm: {
4762
- padding: "0.625rem 1.25rem",
4763
- fontSize: "text-base"
4764
- },
4765
- md: {
4766
- padding: "0.875rem 1.75rem",
4767
- fontSize: "text-lg"
4616
+ padding: "0.75rem 2rem",
4617
+ fontSize: "text-sm"
4768
4618
  },
4619
+ md: { padding: "1rem 2.5rem" },
4769
4620
  lg: {
4770
- padding: "1.125rem 2.25rem",
4771
- fontSize: "text-xl"
4621
+ padding: "1.25rem 3rem",
4622
+ fontSize: "text-lg"
4772
4623
  },
4773
4624
  xl: {
4774
- padding: "1.25rem 2.75rem",
4775
- fontSize: "text-2xl"
4625
+ padding: "1.625rem 3.75rem",
4626
+ fontSize: "text-xl"
4776
4627
  }
4777
4628
  },
4778
- variants: [{
4779
- id: "primary",
4780
- name: "Primary",
4781
- enabled: true,
4782
- priority: 1,
4783
- background: {
4784
- type: "solid",
4785
- colorToken: "primary"
4629
+ roles: {
4630
+ primary: {
4631
+ kind: "complete",
4632
+ appearance: {
4633
+ background: {
4634
+ type: "gradient",
4635
+ stops: ["primary", "accent"],
4636
+ direction: "to-r",
4637
+ foregroundToken: "primaryForeground"
4638
+ },
4639
+ borderRadius: "rounded-lg",
4640
+ shadow: {
4641
+ elevation: "low",
4642
+ softness: "soft",
4643
+ position: "bottom"
4644
+ }
4645
+ }
4786
4646
  },
4787
- borderRadius: "rounded-full",
4788
- shadow: {
4789
- elevation: "high",
4790
- softness: "hard",
4791
- position: "bottom-right",
4792
- colorToken: "text"
4647
+ secondary: {
4648
+ kind: "complete",
4649
+ appearance: {
4650
+ background: {
4651
+ type: "gradient",
4652
+ stops: ["secondary", "accent"],
4653
+ direction: "to-br",
4654
+ foregroundToken: "primaryForeground"
4655
+ },
4656
+ borderRadius: "rounded-lg",
4657
+ shadow: {
4658
+ elevation: "low",
4659
+ softness: "soft",
4660
+ position: "bottom"
4661
+ }
4662
+ }
4793
4663
  },
4794
- effects: { hover: [{ effectId: "press-down" }] }
4795
- }, {
4796
- id: "secondary",
4797
- name: "Secondary",
4798
- enabled: true,
4799
- priority: 2,
4800
- background: {
4801
- type: "surface",
4802
- role: "link"
4803
- },
4804
- borderRadius: "rounded-full",
4805
- border: { widthClass: "border-2" },
4806
- shadow: {
4807
- elevation: "high",
4808
- softness: "hard",
4809
- position: "bottom-right",
4810
- colorToken: "secondary"
4811
- },
4812
- effects: { hover: [{ effectId: "press-down" }] }
4813
- }]
4664
+ outline: {
4665
+ kind: "complete",
4666
+ appearance: {
4667
+ background: {
4668
+ type: "surface",
4669
+ role: "link"
4670
+ },
4671
+ borderRadius: "rounded-lg",
4672
+ border: { widthClass: "border" },
4673
+ effects: { hover: [{
4674
+ effectId: "background-on-hover",
4675
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4676
+ }] }
4677
+ }
4678
+ },
4679
+ ghost: {
4680
+ kind: "complete",
4681
+ appearance: {
4682
+ background: {
4683
+ type: "surface",
4684
+ role: "link"
4685
+ },
4686
+ borderRadius: "rounded-lg",
4687
+ effects: { hover: [{
4688
+ effectId: "background-on-hover",
4689
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4690
+ }] }
4691
+ }
4692
+ },
4693
+ accent: {
4694
+ kind: "derive",
4695
+ from: "primary",
4696
+ overrides: { background: {
4697
+ type: "solid",
4698
+ colorToken: "accent"
4699
+ } }
4700
+ }
4701
+ }
4814
4702
  }
4815
4703
  });
4816
- //#endregion
4817
- //#region ../theme-core/src/buttons/personalities/ornate-ritual.ts
4818
- /**
4819
- * Ornate Ritual — framed, ceremonial buttons with jewel-toned fills and
4820
- * deliberate spacing. Designed for music, ceremony, and soulful event sites.
4821
- */
4822
- const ornateRitual = defineButtonPersonality({
4823
- id: "ornate-ritual",
4824
- name: "Ornate Ritual",
4825
- description: "Ceremonial framed buttons with jewel-toned fills and quiet color-change hover states.",
4704
+ const inkStampRecipe = defineStaticButtonStyleRecipe({
4705
+ id: "ink-stamp",
4706
+ accessibilityLabel: "Uppercase block-print buttons with a playful hover",
4826
4707
  tags: {
4827
- tone: "classic",
4708
+ tone: "bold",
4828
4709
  energy: "vibrant",
4829
- motion: "subtle",
4710
+ motion: "standard",
4830
4711
  era: "organic"
4831
4712
  },
4832
- buttonSystem: {
4713
+ system: {
4833
4714
  global: {
4834
4715
  cornerStyle: "rounded",
4835
4716
  textTransform: "uppercase",
4836
4717
  fontWeight: 600,
4837
- borderWidth: 1,
4838
4718
  hoverTransform: "none",
4839
4719
  hoverColor: "none",
4840
4720
  letterSpacing: "loose"
4841
4721
  },
4842
4722
  sizes: {
4843
4723
  sm: {
4844
- padding: "0.5625rem 1.25rem",
4724
+ padding: "0.5rem 1.25rem",
4845
4725
  fontSize: "text-xs"
4846
4726
  },
4847
4727
  md: {
4848
4728
  padding: "0.75rem 1.75rem",
4849
- fontSize: "text-xs"
4729
+ fontSize: "text-sm"
4850
4730
  },
4851
4731
  lg: {
4852
4732
  padding: "0.875rem 2.25rem",
4853
- fontSize: "text-sm"
4854
- },
4855
- xl: {
4856
- padding: "1rem 2.75rem",
4857
4733
  fontSize: "text-base"
4858
- }
4859
- },
4860
- variants: [
4861
- {
4862
- id: "primary",
4863
- name: "Primary",
4864
- enabled: true,
4865
- priority: 1,
4866
- background: {
4867
- type: "solid",
4868
- colorToken: "primary"
4869
- },
4870
- borderRadius: "rounded-md",
4871
- border: { widthClass: "border" },
4872
- effects: {
4873
- hover: [{
4874
- effectId: "background-on-hover",
4875
- options: { colorToken: "primary-100" }
4876
- }],
4877
- active: [{
4878
- effectId: "scale-down",
4879
- options: { scale: "0.98" }
4880
- }]
4881
- }
4882
- },
4883
- {
4884
- id: "secondary",
4885
- name: "Secondary",
4886
- enabled: true,
4887
- priority: 2,
4888
- background: {
4889
- type: "solid",
4890
- colorToken: "secondary"
4891
- },
4892
- borderRadius: "rounded-md",
4893
- border: { widthClass: "border" },
4894
- effects: { hover: [{
4895
- effectId: "background-on-hover",
4896
- options: { colorToken: "surface" }
4897
- }] }
4898
- },
4899
- {
4900
- id: "outline",
4901
- name: "Outline",
4902
- enabled: true,
4903
- priority: 3,
4904
- background: {
4905
- type: "surface",
4906
- role: "link"
4907
- },
4908
- borderRadius: "rounded-md",
4909
- border: { widthClass: "border" },
4910
- effects: { hover: [{
4911
- effectId: "background-on-hover",
4912
- options: { colorToken: "muted" }
4913
- }] }
4914
- },
4915
- {
4916
- id: "ghost",
4917
- name: "Ghost",
4918
- enabled: true,
4919
- priority: 3,
4920
- background: {
4921
- type: "surface",
4922
- role: "link"
4923
- },
4924
- borderRadius: "rounded-none",
4925
- sizes: {
4926
- sm: {
4927
- padding: "0.375rem 0",
4928
- fontSize: "text-xs"
4929
- },
4930
- md: {
4931
- padding: "0.5rem 0",
4932
- fontSize: "text-sm"
4933
- },
4934
- lg: {
4935
- padding: "0.625rem 0",
4936
- fontSize: "text-base"
4937
- },
4938
- xl: {
4939
- padding: "0.75rem 0",
4940
- fontSize: "text-lg"
4941
- }
4942
- },
4943
- effects: { base: [{
4944
- effectId: "border-bottom-grow",
4945
- options: {
4946
- height: 1,
4947
- colorToken: "accent",
4948
- origin: "left"
4949
- }
4950
- }] }
4951
- }
4952
- ]
4953
- }
4954
- });
4955
- //#endregion
4956
- //#region ../theme-core/src/buttons/personalities/pebble.ts
4957
- /**
4958
- * Pebble — large pill primaries with generous padding. Reads as spa-luxurious
4959
- * and natural; pairs well with wellness/yoga/dance brands.
4960
- */
4961
- const pebble = defineButtonPersonality({
4962
- id: "pebble",
4963
- name: "Pebble",
4964
- description: "Generous pill buttons with a quiet colour-softening hover.",
4965
- tags: {
4966
- tone: "classic",
4967
- energy: "calm",
4968
- motion: "standard",
4969
- era: "organic"
4970
- },
4971
- buttonSystem: {
4972
- global: {
4973
- cornerStyle: "pill",
4974
- textTransform: "none",
4975
- fontWeight: 500,
4976
- borderWidth: 2,
4977
- hoverTransform: "none",
4978
- hoverColor: "none"
4979
- },
4980
- sizes: {
4981
- sm: {
4982
- padding: "0.625rem 1.75rem",
4983
- fontSize: "text-sm"
4984
4734
  },
4985
- md: { padding: "0.875rem 2.25rem" },
4986
- lg: {
4735
+ xl: {
4987
4736
  padding: "1.125rem 2.75rem",
4988
4737
  fontSize: "text-lg"
4989
- },
4990
- xl: {
4991
- padding: "1.5rem 3.5rem",
4992
- fontSize: "text-xl"
4993
4738
  }
4994
4739
  },
4995
- variants: [
4996
- {
4997
- id: "primary",
4998
- name: "Primary",
4999
- enabled: true,
5000
- priority: 1,
5001
- background: {
5002
- type: "solid",
5003
- colorToken: "primary"
5004
- },
5005
- borderRadius: "rounded-full",
5006
- effects: { hover: [{
5007
- effectId: "darken-background",
5008
- options: { amount: 100 }
5009
- }] }
4740
+ roles: {
4741
+ primary: {
4742
+ kind: "complete",
4743
+ appearance: {
4744
+ background: {
4745
+ type: "solid",
4746
+ colorToken: "primary"
4747
+ },
4748
+ borderRadius: "rounded-md",
4749
+ effects: {
4750
+ hover: [{
4751
+ effectId: "drop-shadow",
4752
+ options: { intensity: "medium" }
4753
+ }, {
4754
+ effectId: "scale-up",
4755
+ options: { scale: "1.02" }
4756
+ }],
4757
+ active: [{
4758
+ effectId: "scale-down",
4759
+ options: { scale: "0.98" }
4760
+ }]
4761
+ }
4762
+ }
5010
4763
  },
5011
- {
5012
- id: "secondary",
5013
- name: "Secondary",
5014
- enabled: true,
5015
- priority: 2,
5016
- background: {
5017
- type: "surface",
5018
- role: "link"
5019
- },
5020
- borderRadius: "rounded-full",
5021
- border: { widthClass: "border-2" },
5022
- effects: { hover: [{
5023
- effectId: "background-on-hover",
5024
- options: { colorToken: "accent" }
5025
- }] }
4764
+ secondary: {
4765
+ kind: "complete",
4766
+ appearance: {
4767
+ background: {
4768
+ type: "surface",
4769
+ role: "link"
4770
+ },
4771
+ borderRadius: "rounded-md",
4772
+ border: { widthClass: "border-2" },
4773
+ effects: { hover: [{
4774
+ effectId: "background-on-hover",
4775
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4776
+ }] }
4777
+ }
5026
4778
  },
5027
- {
5028
- id: "outline",
5029
- name: "Outline",
5030
- enabled: true,
5031
- priority: 3,
5032
- background: {
5033
- type: "surface",
5034
- role: "link"
5035
- },
5036
- borderRadius: "rounded-full",
5037
- border: { widthClass: "border" },
5038
- effects: { hover: [{
5039
- effectId: "background-on-hover",
5040
- options: { colorToken: "surface" }
5041
- }] }
4779
+ outline: {
4780
+ kind: "complete",
4781
+ appearance: {
4782
+ background: {
4783
+ type: "surface",
4784
+ role: "link"
4785
+ },
4786
+ borderRadius: "rounded-md",
4787
+ border: { widthClass: "border-2" },
4788
+ effects: { hover: [{
4789
+ effectId: "background-on-hover",
4790
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4791
+ }] }
4792
+ }
5042
4793
  },
5043
- {
5044
- id: "ghost",
5045
- name: "Ghost",
5046
- enabled: true,
5047
- priority: 3,
5048
- background: {
5049
- type: "surface",
5050
- role: "link"
5051
- },
5052
- borderRadius: "rounded-full",
5053
- sizes: {
5054
- sm: {
5055
- padding: "0.375rem 0.875rem",
5056
- fontSize: "text-sm"
4794
+ ghost: {
4795
+ kind: "complete",
4796
+ appearance: {
4797
+ background: {
4798
+ type: "surface",
4799
+ role: "link"
5057
4800
  },
5058
- md: { padding: "0.5rem 1rem" },
5059
- lg: {
5060
- padding: "0.625rem 1.25rem",
5061
- fontSize: "text-lg"
4801
+ borderRadius: "rounded-none",
4802
+ sizes: {
4803
+ sm: {
4804
+ padding: "0.375rem 0",
4805
+ fontSize: "text-xs"
4806
+ },
4807
+ md: {
4808
+ padding: "0.5rem 0",
4809
+ fontSize: "text-sm"
4810
+ },
4811
+ lg: {
4812
+ padding: "0.625rem 0",
4813
+ fontSize: "text-base"
4814
+ },
4815
+ xl: {
4816
+ padding: "0.75rem 0",
4817
+ fontSize: "text-lg"
4818
+ }
5062
4819
  },
5063
- xl: {
5064
- padding: "0.75rem 1.5rem",
5065
- fontSize: "text-xl"
5066
- }
4820
+ effects: { base: [{
4821
+ effectId: "border-bottom-grow",
4822
+ options: {
4823
+ height: 1,
4824
+ origin: "left"
4825
+ }
4826
+ }] }
5067
4827
  }
4828
+ },
4829
+ accent: {
4830
+ kind: "derive",
4831
+ from: "primary",
4832
+ overrides: { background: {
4833
+ type: "solid",
4834
+ colorToken: "accent"
4835
+ } }
5068
4836
  }
5069
- ]
4837
+ }
5070
4838
  }
5071
4839
  });
5072
- //#endregion
5073
- //#region ../theme-core/src/buttons/personalities/quiet-arrow.ts
5074
- /**
5075
- * Quiet Arrow — wide, flat editorial buttons for grounded service businesses.
5076
- * Primary and secondary keep stable semantic colours; surrounding surfaces are
5077
- * responsible for contrast rather than reversing the button roles.
5078
- */
5079
- const quietArrow = defineButtonPersonality({
5080
- id: "quiet-arrow",
5081
- name: "Quiet Arrow",
5082
- description: "Wide, flat arrow buttons with a solid primary and a primary-colour outlined secondary.",
4840
+ const flatInkRecipe = defineStaticButtonStyleRecipe({
4841
+ id: "flat-ink",
4842
+ accessibilityLabel: "Flat rounded buttons with arrow affordances",
5083
4843
  tags: {
5084
4844
  tone: "classic",
5085
4845
  energy: "calm",
5086
4846
  motion: "subtle",
5087
4847
  era: "editorial"
5088
4848
  },
5089
- buttonSystem: {
4849
+ system: {
5090
4850
  global: {
5091
4851
  cornerStyle: "rounded",
5092
- textTransform: "uppercase",
5093
- fontWeight: 500,
5094
- borderWidth: 1,
4852
+ textTransform: "none",
4853
+ fontWeight: 600,
5095
4854
  typography: "body",
5096
- fontSize: "text-sm",
5097
- letterSpacing: "loose",
5098
- hoverTransform: "none",
4855
+ letterSpacing: "tight",
4856
+ paddingPreset: "default",
4857
+ hoverTransform: "lift",
5099
4858
  hoverColor: "none"
5100
4859
  },
5101
4860
  sizes: {
5102
4861
  sm: {
5103
- padding: "0.625rem 1.25rem",
5104
- fontSize: "text-xs"
5105
- },
5106
- md: {
5107
- padding: "0.8125rem 1.75rem",
4862
+ padding: "0.625rem 1.125rem",
5108
4863
  fontSize: "text-sm"
5109
4864
  },
4865
+ md: { padding: "0.8125rem 1.375rem" },
5110
4866
  lg: {
5111
- padding: "0.9375rem 2.125rem",
5112
- fontSize: "text-sm"
4867
+ padding: "0.9375rem 1.625rem",
4868
+ fontSize: "text-lg"
5113
4869
  },
5114
4870
  xl: {
5115
- padding: "1.0625rem 2.5rem",
5116
- fontSize: "text-base"
4871
+ padding: "1.0625rem 2rem",
4872
+ fontSize: "text-xl"
5117
4873
  }
5118
4874
  },
5119
- variants: [
5120
- {
5121
- id: "primary",
5122
- name: "Primary",
5123
- enabled: true,
5124
- priority: 1,
5125
- background: {
5126
- type: "solid",
5127
- colorToken: "primary"
5128
- },
5129
- borderRadius: "rounded-xl",
5130
- affordance: { iconId: "ArrowRight" },
5131
- effects: { hover: [{
5132
- effectId: "darken-background",
5133
- options: { amount: 100 }
5134
- }] }
4875
+ roles: {
4876
+ primary: {
4877
+ kind: "complete",
4878
+ appearance: {
4879
+ background: {
4880
+ type: "solid",
4881
+ colorToken: "primary"
4882
+ },
4883
+ borderRadius: "rounded-lg",
4884
+ affordance: { iconId: "ArrowRight" },
4885
+ effects: { hover: [{ effectId: "lift" }, {
4886
+ effectId: "background-on-hover",
4887
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("secondary") }
4888
+ }] }
4889
+ }
5135
4890
  },
5136
- {
5137
- id: "secondary",
5138
- name: "Secondary",
5139
- enabled: true,
5140
- priority: 2,
5141
- background: {
5142
- type: "surface",
5143
- role: "link"
5144
- },
5145
- borderRadius: "rounded-xl",
5146
- border: { widthClass: "border" },
5147
- affordance: { iconId: "ArrowRight" },
5148
- effects: { hover: [{
5149
- effectId: "background-on-hover",
5150
- options: { colorToken: "surfaceAlt" }
5151
- }] }
4891
+ secondary: {
4892
+ kind: "complete",
4893
+ appearance: {
4894
+ background: {
4895
+ type: "surface",
4896
+ role: "link"
4897
+ },
4898
+ borderRadius: "rounded-lg",
4899
+ border: { widthClass: "border" },
4900
+ effects: { hover: [{ effectId: "lift" }, {
4901
+ effectId: "background-on-hover",
4902
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
4903
+ }] }
4904
+ }
5152
4905
  },
5153
- {
5154
- id: "outline",
5155
- name: "Outline",
5156
- enabled: true,
5157
- priority: 3,
5158
- background: {
5159
- type: "surface",
5160
- role: "link"
5161
- },
5162
- borderRadius: "rounded-xl",
5163
- border: { widthClass: "border" }
4906
+ outline: {
4907
+ kind: "complete",
4908
+ appearance: {
4909
+ background: {
4910
+ type: "surface",
4911
+ role: "link"
4912
+ },
4913
+ borderRadius: "rounded-lg",
4914
+ border: { widthClass: "border" },
4915
+ effects: { hover: [{ effectId: "lift" }, {
4916
+ effectId: "background-on-hover",
4917
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
4918
+ }] }
4919
+ }
5164
4920
  },
5165
- {
5166
- id: "ghost",
5167
- name: "Ghost",
5168
- enabled: true,
5169
- priority: 3,
5170
- background: {
5171
- type: "surface",
5172
- role: "link"
5173
- },
5174
- borderRadius: "rounded-xl"
4921
+ ghost: {
4922
+ kind: "complete",
4923
+ appearance: {
4924
+ background: {
4925
+ type: "surface",
4926
+ role: "link"
4927
+ },
4928
+ borderRadius: "rounded-lg",
4929
+ effects: { hover: [{ effectId: "lift" }] }
4930
+ }
4931
+ },
4932
+ accent: {
4933
+ kind: "complete",
4934
+ appearance: {
4935
+ background: {
4936
+ type: "solid",
4937
+ colorToken: "accent"
4938
+ },
4939
+ borderRadius: "rounded-lg",
4940
+ affordance: { iconId: "ArrowRight" },
4941
+ effects: { hover: [{ effectId: "lift" }] }
4942
+ }
5175
4943
  }
5176
- ]
4944
+ }
5177
4945
  }
5178
4946
  });
5179
- //#endregion
5180
- //#region ../theme-core/src/buttons/personalities/showtime-pill.ts
5181
- /**
5182
- * Showtime Pill — bold, spacious, fully rounded buttons with playful pop
5183
- * motion. Suits energetic schools, performers, festivals, and community brands
5184
- * that need calls to action to feel loud without becoming visually chaotic.
5185
- */
5186
- const showtimePill = defineButtonPersonality({
4947
+ const showtimePillRecipe = defineStaticButtonStyleRecipe({
5187
4948
  id: "showtime-pill",
5188
- name: "Showtime Pill",
5189
- description: "Bold pill buttons with uppercase labels, generous padding, and a playful pop.",
4949
+ accessibilityLabel: "Bold uppercase pill buttons with playful movement",
5190
4950
  tags: {
5191
4951
  tone: "bold",
5192
4952
  energy: "vibrant",
5193
4953
  motion: "expressive",
5194
4954
  era: "modern"
5195
4955
  },
5196
- buttonSystem: {
4956
+ system: {
5197
4957
  global: {
5198
4958
  cornerStyle: "pill",
5199
4959
  shadow: "low",
5200
4960
  textTransform: "uppercase",
5201
4961
  fontWeight: 700,
5202
- borderWidth: 2,
5203
4962
  hoverTransform: "lift",
5204
- hoverColor: "darken",
4963
+ hoverColor: "none",
5205
4964
  typography: "body",
5206
4965
  paddingPreset: "spacious",
5207
4966
  italic: false
@@ -5224,272 +4983,373 @@ const showtimePill = defineButtonPersonality({
5224
4983
  fontSize: "1.125rem"
5225
4984
  }
5226
4985
  },
5227
- variants: [
5228
- {
5229
- id: "primary",
5230
- name: "Primary",
5231
- enabled: true,
5232
- priority: 1,
5233
- background: {
5234
- type: "solid",
5235
- colorToken: "primary"
5236
- },
5237
- borderRadius: "rounded-full",
5238
- effects: { hover: [{ effectId: "pop" }] }
5239
- },
5240
- {
5241
- id: "secondary",
5242
- name: "Secondary",
5243
- enabled: true,
5244
- priority: 2,
5245
- background: {
5246
- type: "surface",
5247
- role: "link"
5248
- },
5249
- borderRadius: "rounded-full",
5250
- border: { widthClass: "border-2" },
5251
- effects: { hover: [{ effectId: "pop" }] }
4986
+ roles: {
4987
+ primary: {
4988
+ kind: "complete",
4989
+ appearance: {
4990
+ background: {
4991
+ type: "solid",
4992
+ colorToken: "primary"
4993
+ },
4994
+ borderRadius: "rounded-full",
4995
+ effects: { hover: [{ effectId: "pop" }] }
4996
+ }
5252
4997
  },
5253
- {
5254
- id: "hero",
5255
- name: "Hero",
5256
- enabled: true,
5257
- priority: 1,
5258
- background: {
5259
- type: "solid",
5260
- colorToken: "secondary"
5261
- },
5262
- borderRadius: "rounded-full",
5263
- effects: { hover: [{ effectId: "pop" }] }
4998
+ secondary: {
4999
+ kind: "complete",
5000
+ appearance: {
5001
+ background: {
5002
+ type: "surface",
5003
+ role: "link"
5004
+ },
5005
+ borderRadius: "rounded-full",
5006
+ border: { widthClass: "border-2" },
5007
+ effects: { hover: [{ effectId: "pop" }] }
5008
+ }
5264
5009
  },
5265
- {
5266
- id: "header",
5267
- name: "Header",
5268
- enabled: true,
5269
- priority: 2,
5270
- background: {
5271
- type: "solid",
5272
- colorToken: "background"
5273
- },
5274
- borderRadius: "rounded-full",
5275
- border: { widthClass: "border-2" },
5276
- effects: { hover: [{
5277
- effectId: "background-on-hover",
5278
- options: { colorToken: "surface" }
5279
- }] }
5010
+ outline: {
5011
+ kind: "complete",
5012
+ appearance: {
5013
+ background: {
5014
+ type: "surface",
5015
+ role: "link"
5016
+ },
5017
+ borderRadius: "rounded-full",
5018
+ border: { widthClass: "border-2" },
5019
+ effects: { hover: [{
5020
+ effectId: "background-on-hover",
5021
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
5022
+ }] }
5023
+ }
5280
5024
  },
5281
- {
5282
- id: "outline",
5283
- name: "Outline",
5284
- enabled: true,
5285
- priority: 3,
5286
- background: {
5287
- type: "surface",
5288
- role: "link"
5289
- },
5290
- borderRadius: "rounded-full",
5291
- border: { widthClass: "border-2" },
5292
- effects: { hover: [{
5293
- effectId: "background-on-hover",
5294
- options: { colorToken: "background" }
5295
- }] }
5025
+ ghost: {
5026
+ kind: "complete",
5027
+ appearance: {
5028
+ background: {
5029
+ type: "surface",
5030
+ role: "link"
5031
+ },
5032
+ borderRadius: "rounded-full",
5033
+ effects: { hover: [{
5034
+ effectId: "background-on-hover",
5035
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
5036
+ }] }
5037
+ }
5296
5038
  },
5297
- {
5298
- id: "ghost",
5299
- name: "Ghost",
5300
- enabled: true,
5301
- priority: 3,
5302
- background: {
5303
- type: "surface",
5304
- role: "link"
5305
- },
5306
- borderRadius: "rounded-full",
5307
- effects: { hover: [{
5308
- effectId: "background-on-hover",
5309
- options: { colorToken: "surface" }
5310
- }] }
5039
+ accent: {
5040
+ kind: "complete",
5041
+ appearance: {
5042
+ background: {
5043
+ type: "solid",
5044
+ colorToken: "secondary"
5045
+ },
5046
+ borderRadius: "rounded-full",
5047
+ effects: { hover: [{ effectId: "pop" }] }
5048
+ }
5311
5049
  }
5312
- ]
5050
+ }
5313
5051
  }
5314
5052
  });
5315
- //#endregion
5316
- //#region ../theme-core/src/buttons/personalities/soft-pill.ts
5317
- /**
5318
- * Soft Pill — rounded-full pill buttons with a hover lift. The default for
5319
- * Calm Studio and Modern Wellness; reads as quietly modern and welcoming.
5320
- */
5321
- const softPill = defineButtonPersonality({
5322
- id: "soft-pill",
5323
- name: "Soft Pill",
5324
- description: "Rounded pills with a gentle lift on hover. Quietly modern.",
5053
+ const joyStampRecipe = defineStaticButtonStyleRecipe({
5054
+ id: "joy-stamp",
5055
+ accessibilityLabel: "Bold pill buttons with a hard offset shadow",
5325
5056
  tags: {
5326
- tone: "classic",
5327
- energy: "calm",
5328
- motion: "subtle",
5057
+ tone: "bold",
5058
+ energy: "vibrant",
5059
+ motion: "expressive",
5329
5060
  era: "organic"
5330
5061
  },
5331
- buttonSystem: {
5062
+ system: {
5332
5063
  global: {
5333
5064
  cornerStyle: "pill",
5334
- shadow: "low",
5065
+ shadow: "high",
5335
5066
  textTransform: "none",
5336
- fontWeight: 500,
5337
- borderWidth: 2,
5338
- hoverTransform: "lift",
5067
+ typography: "heading",
5068
+ fontWeight: 700,
5069
+ fontSize: "text-lg",
5070
+ hoverTransform: "none",
5339
5071
  hoverColor: "none"
5340
5072
  },
5341
- variants: [
5342
- {
5343
- id: "primary",
5344
- name: "Primary",
5345
- enabled: true,
5346
- priority: 1,
5347
- background: {
5348
- type: "solid",
5349
- colorToken: "primary"
5350
- },
5351
- borderRadius: "rounded-full",
5352
- shadow: {
5353
- elevation: "low",
5354
- softness: "soft",
5355
- position: "bottom"
5356
- },
5357
- effects: {
5358
- hover: [{
5359
- effectId: "lift",
5360
- options: { translateY: "-1px" }
5361
- }],
5362
- active: [{
5363
- effectId: "scale-down",
5364
- options: { scale: "0.98" }
5365
- }]
5073
+ sizes: {
5074
+ sm: {
5075
+ padding: "0.625rem 1.25rem",
5076
+ fontSize: "text-base"
5077
+ },
5078
+ md: {
5079
+ padding: "0.875rem 1.75rem",
5080
+ fontSize: "text-lg"
5081
+ },
5082
+ lg: {
5083
+ padding: "1.125rem 2.25rem",
5084
+ fontSize: "text-xl"
5085
+ },
5086
+ xl: {
5087
+ padding: "1.25rem 2.75rem",
5088
+ fontSize: "text-2xl"
5089
+ }
5090
+ },
5091
+ roles: {
5092
+ primary: {
5093
+ kind: "complete",
5094
+ appearance: {
5095
+ background: {
5096
+ type: "solid",
5097
+ colorToken: "primary"
5098
+ },
5099
+ borderRadius: "rounded-full",
5100
+ shadow: {
5101
+ elevation: "high",
5102
+ softness: "hard",
5103
+ position: "bottom-right",
5104
+ colorToken: unsafeAsOpaqueButtonColourToken("text")
5105
+ },
5106
+ effects: { hover: [{ effectId: "press-down" }] }
5366
5107
  }
5367
5108
  },
5368
- {
5369
- id: "secondary",
5370
- name: "Secondary",
5371
- enabled: true,
5372
- priority: 2,
5373
- background: {
5374
- type: "surface",
5375
- role: "link"
5376
- },
5377
- borderRadius: "rounded-full",
5378
- border: { widthClass: "border-2" },
5379
- effects: { hover: [{
5380
- effectId: "background-on-hover",
5381
- options: { colorToken: "surface" }
5382
- }] }
5109
+ secondary: {
5110
+ kind: "complete",
5111
+ appearance: {
5112
+ background: {
5113
+ type: "surface",
5114
+ role: "link"
5115
+ },
5116
+ borderRadius: "rounded-full",
5117
+ border: { widthClass: "border-2" },
5118
+ shadow: {
5119
+ elevation: "high",
5120
+ softness: "hard",
5121
+ position: "bottom-right",
5122
+ colorToken: unsafeAsOpaqueButtonColourToken("secondary")
5123
+ },
5124
+ effects: { hover: [{ effectId: "press-down" }] }
5125
+ }
5383
5126
  },
5384
- {
5385
- id: "outline",
5386
- name: "Outline",
5387
- enabled: true,
5388
- priority: 3,
5389
- background: {
5390
- type: "surface",
5391
- role: "link"
5392
- },
5393
- borderRadius: "rounded-full",
5394
- border: { widthClass: "border" },
5395
- effects: { hover: [{
5396
- effectId: "background-on-hover",
5397
- options: { colorToken: "surface" }
5398
- }] }
5127
+ outline: {
5128
+ kind: "derive",
5129
+ from: "secondary"
5399
5130
  },
5400
- {
5401
- id: "ghost",
5402
- name: "Ghost",
5403
- enabled: true,
5404
- priority: 3,
5405
- background: {
5406
- type: "surface",
5407
- role: "link"
5408
- },
5409
- borderRadius: "rounded-full",
5410
- effects: { hover: [{
5411
- effectId: "background-on-hover",
5412
- options: { colorToken: "surface" }
5413
- }] }
5131
+ ghost: {
5132
+ kind: "complete",
5133
+ appearance: {
5134
+ background: {
5135
+ type: "surface",
5136
+ role: "link"
5137
+ },
5138
+ borderRadius: "rounded-full",
5139
+ effects: { hover: [{ effectId: "press-down" }] }
5140
+ }
5141
+ },
5142
+ accent: {
5143
+ kind: "derive",
5144
+ from: "primary",
5145
+ overrides: { background: {
5146
+ type: "solid",
5147
+ colorToken: "accent"
5148
+ } }
5414
5149
  }
5415
- ]
5150
+ }
5416
5151
  }
5417
5152
  });
5418
- //#endregion
5419
- //#region ../theme-core/src/buttons/personalities/two-tone-pill.ts
5420
- const solidSecondary = {
5421
- id: "secondary",
5422
- name: "Secondary",
5423
- enabled: true,
5424
- priority: 2,
5425
- background: {
5426
- type: "solid",
5427
- colorToken: unsafeAsOpaqueButtonColourToken("secondary")
5428
- },
5429
- borderRadius: "rounded-full",
5430
- shadow: {
5431
- elevation: "none",
5432
- softness: null,
5433
- position: "bottom"
5153
+ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
5154
+ id: "ornate-ritual",
5155
+ accessibilityLabel: "Uppercase framed buttons with restrained movement",
5156
+ tags: {
5157
+ tone: "classic",
5158
+ energy: "vibrant",
5159
+ motion: "subtle",
5160
+ era: "organic"
5434
5161
  },
5435
- effects: {
5436
- hover: [{
5437
- effectId: "background-on-hover-alpha",
5438
- options: {
5439
- colorToken: "secondary",
5440
- opacity: 88
5162
+ system: {
5163
+ global: {
5164
+ cornerStyle: "rounded",
5165
+ textTransform: "uppercase",
5166
+ fontWeight: 600,
5167
+ hoverTransform: "none",
5168
+ hoverColor: "none",
5169
+ letterSpacing: "loose"
5170
+ },
5171
+ sizes: {
5172
+ sm: {
5173
+ padding: "0.5625rem 1.25rem",
5174
+ fontSize: "text-xs"
5175
+ },
5176
+ md: {
5177
+ padding: "0.75rem 1.75rem",
5178
+ fontSize: "text-xs"
5179
+ },
5180
+ lg: {
5181
+ padding: "0.875rem 2.25rem",
5182
+ fontSize: "text-sm"
5183
+ },
5184
+ xl: {
5185
+ padding: "1rem 2.75rem",
5186
+ fontSize: "text-base"
5441
5187
  }
5442
- }],
5443
- active: [{
5444
- effectId: "scale-down",
5445
- options: { scale: "0.98" }
5446
- }]
5188
+ },
5189
+ roles: {
5190
+ primary: {
5191
+ kind: "complete",
5192
+ appearance: {
5193
+ background: {
5194
+ type: "solid",
5195
+ colorToken: "primary"
5196
+ },
5197
+ borderRadius: "rounded-md",
5198
+ border: { widthClass: "border" },
5199
+ effects: {
5200
+ hover: [{
5201
+ effectId: "background-on-hover",
5202
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("primary-100") }
5203
+ }],
5204
+ active: [{
5205
+ effectId: "scale-down",
5206
+ options: { scale: "0.98" }
5207
+ }]
5208
+ }
5209
+ }
5210
+ },
5211
+ secondary: {
5212
+ kind: "complete",
5213
+ appearance: {
5214
+ background: {
5215
+ type: "solid",
5216
+ colorToken: "secondary"
5217
+ },
5218
+ borderRadius: "rounded-md",
5219
+ border: { widthClass: "border" },
5220
+ effects: { hover: [{
5221
+ effectId: "background-on-hover",
5222
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
5223
+ }] }
5224
+ }
5225
+ },
5226
+ outline: {
5227
+ kind: "complete",
5228
+ appearance: {
5229
+ background: {
5230
+ type: "surface",
5231
+ role: "link"
5232
+ },
5233
+ borderRadius: "rounded-md",
5234
+ border: { widthClass: "border" },
5235
+ effects: { hover: [{
5236
+ effectId: "background-on-hover",
5237
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
5238
+ }] }
5239
+ }
5240
+ },
5241
+ ghost: {
5242
+ kind: "complete",
5243
+ appearance: {
5244
+ background: {
5245
+ type: "surface",
5246
+ role: "link"
5247
+ },
5248
+ borderRadius: "rounded-none",
5249
+ sizes: {
5250
+ sm: {
5251
+ padding: "0.375rem 0",
5252
+ fontSize: "text-xs"
5253
+ },
5254
+ md: {
5255
+ padding: "0.5rem 0",
5256
+ fontSize: "text-sm"
5257
+ },
5258
+ lg: {
5259
+ padding: "0.625rem 0",
5260
+ fontSize: "text-base"
5261
+ },
5262
+ xl: {
5263
+ padding: "0.75rem 0",
5264
+ fontSize: "text-lg"
5265
+ }
5266
+ },
5267
+ effects: { base: [{
5268
+ effectId: "border-bottom-grow",
5269
+ options: {
5270
+ height: 1,
5271
+ origin: "left"
5272
+ }
5273
+ }] }
5274
+ }
5275
+ },
5276
+ accent: {
5277
+ kind: "derive",
5278
+ from: "primary",
5279
+ overrides: { background: {
5280
+ type: "solid",
5281
+ colorToken: "accent"
5282
+ } }
5283
+ }
5284
+ }
5447
5285
  }
5448
- };
5286
+ });
5449
5287
  //#endregion
5450
- //#region ../theme-core/src/buttons/personalities/index.ts
5451
- const buttonPersonalities = [
5452
- softPill,
5453
- defineButtonPersonality({
5454
- id: "two-tone-pill",
5455
- name: "Two-tone Pill",
5456
- description: "Rounded pills with distinct solid primary and secondary brand colours.",
5457
- tags: softPill.tags,
5458
- buttonSystem: {
5459
- ...softPill.buttonSystem,
5460
- variants: softPill.buttonSystem.variants.map((variant) => variant.id === "secondary" ? solidSecondary : variant)
5461
- }
5462
- }),
5463
- earthPill,
5464
- confidentChip,
5465
- editorialLink,
5466
- pebble,
5467
- inkStamp,
5468
- flatInk,
5469
- brushedWash,
5470
- showtimePill,
5471
- joyStamp,
5472
- ornateRitual,
5473
- quietArrow
5288
+ //#region ../theme-core/src/buttons/styles/registry.ts
5289
+ const buttonStyleRecipes = [
5290
+ softPillRecipe,
5291
+ earthPillRecipe,
5292
+ confidentChipRecipe,
5293
+ editorialLinkRecipe,
5294
+ pebbleRecipe,
5295
+ inkStampRecipe,
5296
+ flatInkRecipe,
5297
+ brushedWashRecipe,
5298
+ showtimePillRecipe,
5299
+ joyStampRecipe,
5300
+ ornateRitualRecipe,
5301
+ quietArrowRecipe
5474
5302
  ];
5475
- new Map(buttonPersonalities.map((p) => [p.id, p]));
5476
- buttonPersonalities.map((personality) => ({
5477
- id: personality.id,
5478
- name: personality.name,
5479
- description: personality.description,
5480
- category: presetCategory(personality),
5481
- buttonSystem: personality.buttonSystem,
5482
- compatibility: {
5483
- ...personality.tags.tone ? { tones: [personality.tags.tone] } : {},
5484
- ...personality.tags.energy ? { energies: [personality.tags.energy] } : {}
5485
- }
5486
- }));
5487
- function presetCategory(personality) {
5488
- switch (personality.tags.era) {
5303
+ const recipesById = new Map(buttonStyleRecipes.map((recipe) => [recipe.id, recipe]));
5304
+ function findButtonStyleRecipe(id) {
5305
+ const recipe = recipesById.get(id);
5306
+ if (recipe === void 0) throw new Error(`Button style registry is missing known style ${id}`);
5307
+ return recipe;
5308
+ }
5309
+ function resolveButtonStyleSelection(selection) {
5310
+ switch (selection.styleId) {
5311
+ case "soft-pill": return resolveButtonStyleRecipe(softPillRecipe, selection.parameters);
5312
+ case "earth-pill": return resolveButtonStyleRecipe(earthPillRecipe, selection.parameters);
5313
+ case "confident-chip": return resolveButtonStyleRecipe(confidentChipRecipe, selection.parameters);
5314
+ case "editorial-link": return resolveButtonStyleRecipe(editorialLinkRecipe, selection.parameters);
5315
+ case "pebble": return resolveButtonStyleRecipe(pebbleRecipe, selection.parameters);
5316
+ case "ink-stamp": return resolveButtonStyleRecipe(inkStampRecipe, selection.parameters);
5317
+ case "flat-ink": return resolveButtonStyleRecipe(flatInkRecipe, selection.parameters);
5318
+ case "brushed-wash": return resolveButtonStyleRecipe(brushedWashRecipe, selection.parameters);
5319
+ case "showtime-pill": return resolveButtonStyleRecipe(showtimePillRecipe, selection.parameters);
5320
+ case "joy-stamp": return resolveButtonStyleRecipe(joyStampRecipe, selection.parameters);
5321
+ case "ornate-ritual": return resolveButtonStyleRecipe(ornateRitualRecipe, selection.parameters);
5322
+ case "quiet-arrow": return resolveButtonStyleRecipe(quietArrowRecipe, selection.parameters);
5323
+ }
5324
+ }
5325
+ function defaultButtonStyleSelectionFor(styleId) {
5326
+ return {
5327
+ styleId,
5328
+ parameters: findButtonStyleRecipe(styleId).defaultParameters
5329
+ };
5330
+ }
5331
+ 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");
5332
+ buttonStyleRecipes.map((recipe) => {
5333
+ const resolved = resolveButtonStyleSelection(defaultButtonStyleSelectionFor(recipe.id));
5334
+ if (resolved.kind === "error") throw new Error(`Invalid registered button style ${recipe.id}: ${resolved.error.issues.join(", ")}`);
5335
+ return {
5336
+ id: recipe.id,
5337
+ name: recipe.accessibilityLabel,
5338
+ description: recipe.accessibilityLabel,
5339
+ category: presetCategory(recipe),
5340
+ buttonSystem: resolved.buttonSystem,
5341
+ compatibility: {
5342
+ ...recipe.tags.tone ? { tones: [recipe.tags.tone] } : {},
5343
+ ...recipe.tags.energy ? { energies: [recipe.tags.energy] } : {}
5344
+ }
5345
+ };
5346
+ });
5347
+ function presetCategory(recipe) {
5348
+ switch (recipe.tags.era) {
5489
5349
  case "retro": return "retro";
5490
5350
  case "editorial": return "minimal";
5491
5351
  case "organic": return "artistic";
5492
- case "modern": return personality.tags.tone === "bold" ? "modern" : "technical";
5352
+ case "modern": return recipe.tags.tone === "bold" ? "modern" : "technical";
5493
5353
  case "technical": return "technical";
5494
5354
  case void 0: return "modern";
5495
5355
  }
@@ -6516,6 +6376,102 @@ new Set(themeV2NormalEditorRawStyleFieldNames);
6516
6376
  const pageDesignEditorBackgroundOverrideOwner = "page-design-editor";
6517
6377
  const siteChromeBackgroundOverrideOwner = "site-chrome-editor";
6518
6378
  //#endregion
6379
+ //#region ../theme-core/src/utils/colorStyles.ts
6380
+ const COLOR_VAR_PREFIX = "--tb-";
6381
+ function parseToken(source) {
6382
+ const parts = parseColorTokenParts(source);
6383
+ if (parts.kind === "raw") return {
6384
+ token: source,
6385
+ raw: parts.value
6386
+ };
6387
+ if (parts.kind === "invalid") return { token: source };
6388
+ return {
6389
+ token: parts.token,
6390
+ opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
6391
+ };
6392
+ }
6393
+ const SURFACE_TEXT_ROLE_BY_TOKEN = {
6394
+ text: "text",
6395
+ heading: "heading",
6396
+ mutedText: "supporting"
6397
+ };
6398
+ function surfaceRoleForTextToken(token) {
6399
+ return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
6400
+ }
6401
+ /**
6402
+ * Converts a theme color token to a CSS rgb value.
6403
+ * This is the primary function for applying theme colors to CSS properties.
6404
+ *
6405
+ * @param token - Theme color token (semantic, with opacity, or raw)
6406
+ * @returns CSS color value (rgb with optional alpha, or raw CSS value)
6407
+ *
6408
+ * @example
6409
+ * rgbColorValue('primary') // => 'rgb(var(--tb-primary))'
6410
+ * rgbColorValue('surface/95') // => 'rgb(var(--tb-surface) / 0.95)'
6411
+ * rgbColorValue('raw:transparent') // => 'transparent'
6412
+ */
6413
+ function rgbColorValue(token) {
6414
+ const { token: baseToken, opacityPercent, raw } = parseToken(token);
6415
+ if (raw) return raw;
6416
+ const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
6417
+ if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
6418
+ return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
6419
+ }
6420
+ /**
6421
+ * Creates a backgroundColor style object from a theme token.
6422
+ *
6423
+ * @param token - Theme color token
6424
+ * @returns CSSProperties with backgroundColor
6425
+ */
6426
+ function backgroundColorStyle(token) {
6427
+ return { backgroundColor: rgbColorValue(token) };
6428
+ }
6429
+ /**
6430
+ * Creates a text color style object from a theme token.
6431
+ *
6432
+ * @param token - Theme color token
6433
+ * @returns CSSProperties with color
6434
+ */
6435
+ function textColorStyle(token) {
6436
+ const parsed = parseToken(token);
6437
+ const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
6438
+ if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
6439
+ return { color: rgbColorValue(token) };
6440
+ }
6441
+ /**
6442
+ * Creates a border color style object from a theme token.
6443
+ *
6444
+ * @param token - Theme color token
6445
+ * @returns CSSProperties with borderColor
6446
+ */
6447
+ function borderColorStyle(token) {
6448
+ return { borderColor: rgbColorValue(token) };
6449
+ }
6450
+ /**
6451
+ * Merges multiple CSSProperties objects into a single object.
6452
+ * Later styles override earlier ones. Undefined values are filtered out.
6453
+ * Returns undefined if the merged result is empty.
6454
+ *
6455
+ * @param styles - Variable number of CSSProperties objects (can be undefined)
6456
+ * @returns Merged CSSProperties object, or undefined if empty
6457
+ *
6458
+ * @example
6459
+ * mergeStyles(
6460
+ * backgroundColorStyle('surface'),
6461
+ * textColorStyle('text'),
6462
+ * borderColorStyle('border')
6463
+ * )
6464
+ * // => { backgroundColor: '...', color: '...', borderColor: '...' }
6465
+ */
6466
+ function mergeStyles(...styles) {
6467
+ const merged = {};
6468
+ for (const style of styles) {
6469
+ if (!style) continue;
6470
+ Object.assign(merged, style);
6471
+ }
6472
+ return Object.keys(merged).length ? merged : void 0;
6473
+ }
6474
+ //#endregion
6519
6475
  //#region ../theme-core/src/utils/tokenOrColor.ts
6520
6476
  /**
6521
6477
  * Runtime color-reference fields intentionally accept any string, including
@@ -10219,76 +10175,9 @@ function headerConfigurationKey(configuration) {
10219
10175
  function asFooterLookId(value) {
10220
10176
  return value;
10221
10177
  }
10222
- function asFooterLayoutId(value) {
10223
- return value;
10224
- }
10225
- function asFooterStyleId(value) {
10226
- return value;
10227
- }
10228
- const footerLayoutCatalog = defineExactCatalog()([
10229
- {
10230
- id: asFooterLayoutId("identity"),
10231
- label: "Identity",
10232
- description: "Logo, site text, address, and legal copy without relying on footer navigation."
10233
- },
10234
- {
10235
- id: asFooterLayoutId("centered"),
10236
- label: "Centered",
10237
- description: "A calm centered stack for identity, short copy, and optional compact navigation.",
10238
- maxRecommendedNavDensity: "sparse"
10239
- },
10240
- {
10241
- id: asFooterLayoutId("split"),
10242
- label: "Split",
10243
- description: "Navigation and brand signoff separated into a wider split footer.",
10244
- requiresFooterNav: true,
10245
- maxRecommendedNavDensity: "balanced"
10246
- },
10247
- {
10248
- id: asFooterLayoutId("columns"),
10249
- label: "Columns",
10250
- description: "Grouped footer navigation columns with a supporting bottom line.",
10251
- requiresFooterNav: true,
10252
- requiresFooterNavGroups: true
10253
- }
10254
- ]);
10255
- const footerStyleCatalog = defineExactCatalog()([
10256
- {
10257
- id: asFooterStyleId("quiet"),
10258
- label: "Quiet",
10259
- description: "Lightweight, practical footer treatment."
10260
- },
10261
- {
10262
- id: asFooterStyleId("calm"),
10263
- label: "Calm",
10264
- description: "Soft centered treatment with restrained dividers."
10265
- },
10266
- {
10267
- id: asFooterStyleId("editorial"),
10268
- label: "Editorial",
10269
- description: "Text-forward treatment with fine-line structure."
10270
- },
10271
- {
10272
- id: asFooterStyleId("brand-band"),
10273
- label: "Brand band",
10274
- description: "High-contrast brand treatment with a stronger bottom bar."
10275
- }
10276
- ]);
10277
- new Map(footerLayoutCatalog.map((layout) => [layout.id, layout]));
10278
- new Map(footerStyleCatalog.map((style) => [style.id, style]));
10279
- /**
10280
- * No-nav-safe identity footer: brand and legal/supporting copy carry the
10281
- * footer without implying missing navigation.
10282
- */
10283
- function identityQuietFooter(theme) {
10178
+ function quietFooterLinks(theme) {
10284
10179
  return {
10285
10180
  ...theme.footer,
10286
- variant: "simple",
10287
- maxWidth: "container",
10288
- background: {
10289
- type: "color",
10290
- color: "surface"
10291
- },
10292
10181
  navStyle: "minimal",
10293
10182
  navWeight: "regular",
10294
10183
  navColor: "text",
@@ -10301,285 +10190,38 @@ function identityQuietFooter(theme) {
10301
10190
  hoverColorToken: "primary",
10302
10191
  padding: "none",
10303
10192
  borderRadius: "none"
10304
- },
10305
- navLayout: {
10306
- layout: "inline-wrap",
10307
- align: "start",
10308
- gapX: "default",
10309
- gapY: "tight"
10310
- },
10311
- logo: {
10312
- showLogo: true,
10313
- showLogoText: true,
10314
- placement: "left",
10315
- size: "sm",
10316
- align: "start"
10317
- },
10318
- bottomBar: {
10319
- enabled: false,
10320
- fullBleed: false,
10321
- textAlign: "left",
10322
- paddingX: "default",
10323
- paddingY: "compact",
10324
- borderTop: { width: "none" }
10325
10193
  }
10326
10194
  };
10327
10195
  }
10328
- /**
10329
- * Back-compat alias for the previous default footer Look. It keeps existing
10330
- * persisted selections valid while staying hidden from the new layout/style UI.
10331
- */
10332
- function mutedGroundingFooter(theme) {
10333
- return {
10334
- ...identityQuietFooter(theme),
10335
- background: theme.footer.background,
10336
- navStyle: theme.footer.navStyle,
10337
- navColor: theme.footer.navColor,
10338
- navWeight: theme.footer.navWeight,
10339
- navLinkStyle: theme.footer.navLinkStyle,
10340
- bottomTextLinkStyle: theme.footer.bottomTextLinkStyle
10341
- };
10342
- }
10343
- /** Applies a high-contrast brand band with a darker full-bleed bottom bar. */
10344
- function brandTwoBandFooter(theme) {
10196
+ function emphasizedFooterLinks(theme) {
10345
10197
  return {
10346
10198
  ...theme.footer,
10347
- variant: "split",
10348
- maxWidth: "container",
10349
- background: {
10350
- type: "color",
10351
- color: "primary-800"
10352
- },
10353
10199
  navStyle: "minimal",
10354
10200
  navWeight: "medium",
10355
- navColor: "primaryForeground",
10356
- navLinkStyle: {
10357
- typography: "body",
10358
- fontWeight: "medium",
10359
- textTransform: "none",
10360
- italic: false,
10361
- colorToken: "primaryForeground",
10362
- hoverColorToken: "secondary",
10363
- padding: "none",
10364
- borderRadius: "none"
10365
- },
10366
- bottomTextLinkStyle: {
10367
- colorToken: "secondary",
10368
- decorationColorToken: "secondary"
10369
- },
10370
- navLayout: {
10371
- layout: "inline-wrap",
10372
- align: "start",
10373
- gapX: "default",
10374
- gapY: "tight"
10375
- },
10376
- logo: {
10377
- showLogo: true,
10378
- showLogoText: false,
10379
- placement: "left",
10380
- size: "sm",
10381
- align: "start"
10382
- },
10383
- bottomBar: {
10384
- enabled: true,
10385
- fullBleed: true,
10386
- background: {
10387
- type: "color",
10388
- color: "primary-900"
10389
- },
10390
- textColor: "primaryForeground",
10391
- textAlign: "center",
10392
- paddingX: "default",
10393
- paddingY: "compact",
10394
- borderTop: { width: "none" }
10395
- }
10396
- };
10397
- }
10398
- /**
10399
- * Centered stack on a softly tinted band: logo, inline nav, address, and a
10400
- * hairline-topped copyright line, all centered.
10401
- */
10402
- function centeredCalmFooter(theme) {
10403
- return {
10404
- ...theme.footer,
10405
- variant: "simple",
10406
- maxWidth: "container",
10407
- background: {
10408
- type: "color",
10409
- color: "surfaceAlt"
10410
- },
10411
- navStyle: "minimal",
10412
- navWeight: "regular",
10413
10201
  navColor: "text",
10414
10202
  navLinkStyle: {
10415
10203
  typography: "body",
10416
- fontWeight: "regular",
10417
- textTransform: "none",
10418
- italic: false,
10419
- colorToken: "text",
10420
- hoverColorToken: "primary",
10421
- padding: "none",
10422
- borderRadius: "none"
10423
- },
10424
- navLayout: {
10425
- layout: "inline-wrap",
10426
- align: "center",
10427
- gapX: "relaxed",
10428
- gapY: "tight"
10429
- },
10430
- logo: {
10431
- showLogo: true,
10432
- showLogoText: false,
10433
- placement: "above",
10434
- size: "sm",
10435
- align: "center"
10436
- },
10437
- bottomBar: {
10438
- enabled: true,
10439
- fullBleed: false,
10440
- textAlign: "center",
10441
- paddingX: "default",
10442
- paddingY: "compact",
10443
- borderTop: { width: "thin" }
10444
- }
10445
- };
10446
- }
10447
- /** Editorial split footer: compact nav on one side, brand signoff on the other. */
10448
- function splitEditorialFooter(theme) {
10449
- return {
10450
- ...theme.footer,
10451
- variant: "split",
10452
- maxWidth: "container",
10453
- background: {
10454
- type: "color",
10455
- color: "surface"
10456
- },
10457
- navStyle: "minimal",
10458
- navWeight: "regular",
10459
- navColor: "text",
10460
- navLinkStyle: {
10461
- typography: "body",
10462
- fontWeight: "regular",
10463
- textTransform: "none",
10464
- italic: false,
10465
- colorToken: "text",
10466
- hoverColorToken: "primary",
10467
- padding: "none",
10468
- borderRadius: "none"
10469
- },
10470
- navLayout: {
10471
- layout: "inline-wrap",
10472
- align: "start",
10473
- gapX: "relaxed",
10474
- gapY: "tight"
10475
- },
10476
- logo: {
10477
- showLogo: true,
10478
- showLogoText: true,
10479
- placement: "right",
10480
- size: "sm",
10481
- align: "end"
10482
- },
10483
- bottomBar: {
10484
- enabled: true,
10485
- fullBleed: false,
10486
- textAlign: "left",
10487
- paddingX: "default",
10488
- paddingY: "compact",
10489
- borderTop: { width: "thin" }
10490
- }
10491
- };
10492
- }
10493
- /**
10494
- * Editorial columns: site name and supporting copy on the left, inline nav on
10495
- * the right, with a hairline-topped bottom line. Uses the footer block's
10496
- * columns layout.
10497
- */
10498
- function editorialColumnsFooter(theme) {
10499
- return {
10500
- ...theme.footer,
10501
- variant: "columns",
10502
- maxWidth: "container",
10503
- background: {
10504
- type: "color",
10505
- color: "surface"
10506
- },
10507
- navStyle: "minimal",
10508
- navWeight: "regular",
10509
- navColor: "text",
10510
- navLinkStyle: {
10511
- typography: "body",
10512
- fontWeight: "regular",
10204
+ fontWeight: "medium",
10513
10205
  textTransform: "none",
10514
10206
  italic: false,
10515
10207
  colorToken: "text",
10516
10208
  hoverColorToken: "primary",
10517
10209
  padding: "none",
10518
10210
  borderRadius: "none"
10519
- },
10520
- logo: {
10521
- showLogo: true,
10522
- showLogoText: true,
10523
- placement: "left",
10524
- size: "sm",
10525
- align: "start"
10526
- },
10527
- bottomBar: {
10528
- enabled: true,
10529
- fullBleed: false,
10530
- textAlign: "center",
10531
- paddingX: "default",
10532
- paddingY: "compact",
10533
- borderTop: { width: "thin" }
10534
10211
  }
10535
10212
  };
10536
10213
  }
10537
- const footerLookCatalog = defineExactCatalog()([
10538
- {
10539
- id: asFooterLookId("footer-identity-quiet"),
10540
- label: "Identity footer",
10541
- layoutId: asFooterLayoutId("identity"),
10542
- styleId: asFooterStyleId("quiet"),
10543
- compile: identityQuietFooter
10544
- },
10545
- {
10546
- id: asFooterLookId("footer-muted-grounding"),
10547
- label: "Muted grounding footer",
10548
- layoutId: asFooterLayoutId("identity"),
10549
- styleId: asFooterStyleId("quiet"),
10550
- hiddenFromLayoutStyleControls: true,
10551
- compile: mutedGroundingFooter
10552
- },
10553
- {
10554
- id: asFooterLookId("footer-centered-calm"),
10555
- label: "Centered calm footer",
10556
- layoutId: asFooterLayoutId("centered"),
10557
- styleId: asFooterStyleId("calm"),
10558
- compile: centeredCalmFooter
10559
- },
10560
- {
10561
- id: asFooterLookId("footer-split-editorial"),
10562
- label: "Split editorial footer",
10563
- layoutId: asFooterLayoutId("split"),
10564
- styleId: asFooterStyleId("editorial"),
10565
- compile: splitEditorialFooter
10566
- },
10567
- {
10568
- id: asFooterLookId("footer-editorial-columns"),
10569
- label: "Editorial columns footer",
10570
- layoutId: asFooterLayoutId("columns"),
10571
- styleId: asFooterStyleId("editorial"),
10572
- compile: editorialColumnsFooter
10573
- },
10574
- {
10575
- id: asFooterLookId("site-footer-brand-two-band"),
10576
- label: "Two-band brand footer",
10577
- layoutId: asFooterLayoutId("split"),
10578
- styleId: asFooterStyleId("brand-band"),
10579
- allowedContentPresence: ["default-footer", "default-and-blocks"],
10580
- compile: brandTwoBandFooter
10581
- }
10582
- ]);
10214
+ const footerLookCatalog = defineExactCatalog()([{
10215
+ id: asFooterLookId("footer-links-quiet"),
10216
+ label: "Quiet links",
10217
+ description: "Regular-weight footer navigation with a restrained hover.",
10218
+ compile: quietFooterLinks
10219
+ }, {
10220
+ id: asFooterLookId("footer-links-emphasized"),
10221
+ label: "Emphasized links",
10222
+ description: "Medium-weight footer navigation with a clearer emphasis.",
10223
+ compile: emphasizedFooterLinks
10224
+ }]);
10583
10225
  new Map(footerLookCatalog.map((look) => [look.id, look]));
10584
10226
  //#endregion
10585
10227
  //#region ../theme-core/src/site-styles/sourceCatalogs.ts
@@ -11708,17 +11350,21 @@ function defineCuratedSiteStyle(input) {
11708
11350
  })),
11709
11351
  recommendedHeaderLookIds: legacyHeaderLookIds.map(asHeaderLookId),
11710
11352
  recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(asFooterLookId),
11711
- buttonPersonalityChoices: input.buttonPersonalityChoices,
11353
+ buttonStyleChoices: input.buttonStyleChoices,
11712
11354
  paletteRecommendations: input.paletteRecommendations,
11713
11355
  typography: input.typography ?? defaultTypographyForRecipe(input.tokenRecipes.typography),
11714
11356
  ...input.heroTypography ? { heroTypography: input.heroTypography } : {}
11715
11357
  };
11716
11358
  }
11717
- function buttonChoice(id, note) {
11359
+ function buttonChoice(styleId, note, parameters) {
11360
+ const selection = parameters === void 0 ? defaultButtonStyleSelectionFor(styleId) : buttonStyleSelectionSchema.parse({
11361
+ styleId,
11362
+ parameters
11363
+ });
11718
11364
  return note ? {
11719
- id: asButtonPersonalityId(id),
11365
+ ...selection,
11720
11366
  note
11721
- } : { id: asButtonPersonalityId(id) };
11367
+ } : selection;
11722
11368
  }
11723
11369
  function paletteRecommendation(authoringKey, note) {
11724
11370
  const valueKey = requireCuratedPaletteValueKey(asCuratedPaletteAuthoringKey(authoringKey));
@@ -11903,9 +11549,8 @@ const curatedSiteStyles = [
11903
11549
  "minimal-transparent",
11904
11550
  "clean-base"
11905
11551
  ],
11906
- buttonPersonalityChoices: [
11552
+ buttonStyleChoices: [
11907
11553
  buttonChoice("soft-pill"),
11908
- buttonChoice("two-tone-pill"),
11909
11554
  buttonChoice("pebble"),
11910
11555
  buttonChoice("editorial-link"),
11911
11556
  buttonChoice("brushed-wash")
@@ -11941,7 +11586,7 @@ const curatedSiteStyles = [
11941
11586
  "brand-solid",
11942
11587
  "clean-base"
11943
11588
  ],
11944
- buttonPersonalityChoices: [
11589
+ buttonStyleChoices: [
11945
11590
  buttonChoice("confident-chip"),
11946
11591
  buttonChoice("soft-pill"),
11947
11592
  buttonChoice("editorial-link")
@@ -11980,7 +11625,7 @@ const curatedSiteStyles = [
11980
11625
  "minimal-transparent",
11981
11626
  "centered-calm"
11982
11627
  ],
11983
- buttonPersonalityChoices: [
11628
+ buttonStyleChoices: [
11984
11629
  buttonChoice("editorial-link"),
11985
11630
  buttonChoice("soft-pill"),
11986
11631
  buttonChoice("brushed-wash")
@@ -12020,7 +11665,7 @@ const curatedSiteStyles = [
12020
11665
  "practical-utility",
12021
11666
  "clean-base"
12022
11667
  ],
12023
- buttonPersonalityChoices: [
11668
+ buttonStyleChoices: [
12024
11669
  buttonChoice("pebble"),
12025
11670
  buttonChoice("brushed-wash"),
12026
11671
  buttonChoice("confident-chip")
@@ -12081,7 +11726,7 @@ const curatedSiteStyles = [
12081
11726
  "serif-line",
12082
11727
  "clean-base"
12083
11728
  ],
12084
- buttonPersonalityChoices: [
11729
+ buttonStyleChoices: [
12085
11730
  buttonChoice("editorial-link"),
12086
11731
  buttonChoice("confident-chip"),
12087
11732
  buttonChoice("soft-pill")
@@ -12143,7 +11788,7 @@ const curatedSiteStyles = [
12143
11788
  "brand-solid",
12144
11789
  "clean-base"
12145
11790
  ],
12146
- buttonPersonalityChoices: [
11791
+ buttonStyleChoices: [
12147
11792
  buttonChoice("confident-chip"),
12148
11793
  buttonChoice("pebble"),
12149
11794
  buttonChoice("ink-stamp")
@@ -12182,7 +11827,7 @@ const curatedSiteStyles = [
12182
11827
  "minimal-transparent",
12183
11828
  "clean-base"
12184
11829
  ],
12185
- buttonPersonalityChoices: [
11830
+ buttonStyleChoices: [
12186
11831
  buttonChoice("soft-pill"),
12187
11832
  buttonChoice("pebble"),
12188
11833
  buttonChoice("confident-chip")
@@ -12255,7 +11900,7 @@ const curatedSiteStyles = [
12255
11900
  "clean-base",
12256
11901
  "centered-calm"
12257
11902
  ],
12258
- buttonPersonalityChoices: [
11903
+ buttonStyleChoices: [
12259
11904
  buttonChoice("pebble"),
12260
11905
  buttonChoice("soft-pill"),
12261
11906
  buttonChoice("editorial-link")
@@ -12374,12 +12019,8 @@ const curatedSiteStyles = [
12374
12019
  "serif-line",
12375
12020
  "minimal-transparent"
12376
12021
  ],
12377
- recommendedFooterLookIds: [
12378
- "footer-centered-calm",
12379
- "footer-editorial-columns",
12380
- "footer-muted-grounding"
12381
- ],
12382
- buttonPersonalityChoices: [
12022
+ recommendedFooterLookIds: ["footer-links-quiet"],
12023
+ buttonStyleChoices: [
12383
12024
  buttonChoice("soft-pill"),
12384
12025
  buttonChoice("pebble"),
12385
12026
  buttonChoice("editorial-link")
@@ -12453,7 +12094,7 @@ const curatedSiteStyles = [
12453
12094
  "centered-calm",
12454
12095
  "minimal-transparent"
12455
12096
  ],
12456
- buttonPersonalityChoices: [
12097
+ buttonStyleChoices: [
12457
12098
  buttonChoice("editorial-link"),
12458
12099
  buttonChoice("soft-pill"),
12459
12100
  buttonChoice("brushed-wash")
@@ -12526,8 +12167,8 @@ const curatedSiteStyles = [
12526
12167
  "practical-utility",
12527
12168
  "clean-base"
12528
12169
  ],
12529
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12530
- buttonPersonalityChoices: [
12170
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
12171
+ buttonStyleChoices: [
12531
12172
  buttonChoice("pebble"),
12532
12173
  buttonChoice("confident-chip"),
12533
12174
  buttonChoice("ink-stamp"),
@@ -12648,8 +12289,8 @@ const curatedSiteStyles = [
12648
12289
  "minimal-transparent",
12649
12290
  "serif-line"
12650
12291
  ],
12651
- recommendedFooterLookIds: ["footer-muted-grounding", "site-footer-brand-two-band"],
12652
- buttonPersonalityChoices: [
12292
+ recommendedFooterLookIds: ["footer-links-quiet", "footer-links-emphasized"],
12293
+ buttonStyleChoices: [
12653
12294
  buttonChoice("earth-pill"),
12654
12295
  buttonChoice("soft-pill"),
12655
12296
  buttonChoice("pebble"),
@@ -12720,7 +12361,7 @@ const curatedSiteStyles = [
12720
12361
  "floating-glass",
12721
12362
  "brand-solid"
12722
12363
  ],
12723
- buttonPersonalityChoices: [
12364
+ buttonStyleChoices: [
12724
12365
  buttonChoice("ink-stamp"),
12725
12366
  buttonChoice("confident-chip"),
12726
12367
  buttonChoice("brushed-wash"),
@@ -12775,8 +12416,8 @@ const curatedSiteStyles = [
12775
12416
  "transparent-overlay",
12776
12417
  "practical-utility"
12777
12418
  ],
12778
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12779
- buttonPersonalityChoices: [
12419
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
12420
+ buttonStyleChoices: [
12780
12421
  buttonChoice("showtime-pill"),
12781
12422
  buttonChoice("confident-chip"),
12782
12423
  buttonChoice("ink-stamp"),
@@ -12857,8 +12498,8 @@ const curatedSiteStyles = [
12857
12498
  headerStyleChoice("glass")
12858
12499
  ] },
12859
12500
  recommendedHeaderLookIds: ["minimal-transparent"],
12860
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12861
- buttonPersonalityChoices: [
12501
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
12502
+ buttonStyleChoices: [
12862
12503
  buttonChoice("ornate-ritual"),
12863
12504
  buttonChoice("joy-stamp"),
12864
12505
  buttonChoice("ink-stamp")
@@ -12911,8 +12552,8 @@ const curatedSiteStyles = [
12911
12552
  headerStyleChoice("glass")
12912
12553
  ] },
12913
12554
  recommendedHeaderLookIds: ["minimal-transparent"],
12914
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12915
- buttonPersonalityChoices: [
12555
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
12556
+ buttonStyleChoices: [
12916
12557
  buttonChoice("joy-stamp"),
12917
12558
  buttonChoice("ink-stamp"),
12918
12559
  buttonChoice("showtime-pill")
@@ -13002,8 +12643,8 @@ const curatedSiteStyles = [
13002
12643
  "centered-calm",
13003
12644
  "clean-base"
13004
12645
  ],
13005
- recommendedFooterLookIds: ["footer-editorial-columns", "footer-muted-grounding"],
13006
- buttonPersonalityChoices: [
12646
+ recommendedFooterLookIds: ["footer-links-quiet"],
12647
+ buttonStyleChoices: [
13007
12648
  buttonChoice("flat-ink"),
13008
12649
  buttonChoice("confident-chip"),
13009
12650
  buttonChoice("editorial-link")
@@ -13080,14 +12721,9 @@ const curatedSiteStyles = [
13080
12721
  "serif-line",
13081
12722
  "clean-base"
13082
12723
  ],
13083
- recommendedFooterLookIds: [
13084
- "footer-editorial-columns",
13085
- "footer-muted-grounding",
13086
- "footer-identity-quiet"
13087
- ],
13088
- buttonPersonalityChoices: [
13089
- buttonChoice("quiet-arrow"),
13090
- buttonChoice("two-tone-pill"),
12724
+ recommendedFooterLookIds: ["footer-links-quiet"],
12725
+ buttonStyleChoices: [
12726
+ buttonChoice("quiet-arrow", void 0, { secondaryTreatment: "solid-accent" }),
13091
12727
  buttonChoice("flat-ink"),
13092
12728
  buttonChoice("editorial-link")
13093
12729
  ],
@@ -13716,6 +13352,7 @@ const DISPLAY_MEDIA_KINDS = [
13716
13352
  "video",
13717
13353
  "audio"
13718
13354
  ];
13355
+ const DEFAULT_MEDIA_FIELD_KINDS = ["image"];
13719
13356
  const PUBLIC_FILE_FIELD_KINDS = [
13720
13357
  "document",
13721
13358
  "spreadsheet",
@@ -13916,18 +13553,28 @@ const inlineTextFieldSchema = baseFieldSchema.extend({
13916
13553
  maxLength: z$1.number().int().positive().optional(),
13917
13554
  plainTextField: z$1.string().min(1).optional()
13918
13555
  });
13556
+ function hasMediaDefaultIdentifier(value) {
13557
+ return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.identifier === "string" && value.identifier.trim().length > 0;
13558
+ }
13559
+ function validateMediaFieldDefault(field, ctx) {
13560
+ if (field.defaultValue !== void 0 && field.defaultValue !== null && !hasMediaDefaultIdentifier(field.defaultValue)) ctx.addIssue({
13561
+ code: z$1.ZodIssueCode.custom,
13562
+ path: ["defaultValue"],
13563
+ message: `${field.type} defaultValue must be null or an object with a non-empty identifier`
13564
+ });
13565
+ }
13919
13566
  const mediaFieldSchema = baseFieldSchema.extend({
13920
13567
  type: z$1.literal("media"),
13921
- mediaKinds: z$1.array(z$1.enum(MEDIA_KINDS)).default(["image"]).transform((kinds) => {
13568
+ mediaKinds: z$1.array(z$1.enum(MEDIA_KINDS)).default([...DEFAULT_MEDIA_FIELD_KINDS]).transform((kinds) => {
13922
13569
  const displayKinds = kinds.filter(isDisplayMediaKind);
13923
- return displayKinds.length > 0 ? displayKinds : ["image"];
13570
+ return displayKinds.length > 0 ? displayKinds : [...DEFAULT_MEDIA_FIELD_KINDS];
13924
13571
  }),
13925
13572
  aspectRatio: z$1.string().optional()
13926
- });
13573
+ }).superRefine(validateMediaFieldDefault);
13927
13574
  const fileFieldSchema = baseFieldSchema.extend({
13928
13575
  type: z$1.literal("file"),
13929
13576
  fileKinds: z$1.array(z$1.enum(PUBLIC_FILE_FIELD_KINDS)).default([...PUBLIC_FILE_FIELD_KINDS])
13930
- });
13577
+ }).superRefine(validateMediaFieldDefault);
13931
13578
  const booleanFieldSchema = baseFieldSchema.extend({ type: z$1.literal("boolean") });
13932
13579
  const dateFieldSchema = baseFieldSchema.extend({ type: z$1.literal("date") });
13933
13580
  const timeFieldSchema = baseFieldSchema.extend({ type: z$1.literal("time") });
@@ -17322,25 +16969,41 @@ const heroLayoutControlsFragment = defineFragment({
17322
16969
  layout: []
17323
16970
  });
17324
16971
  //#endregion
16972
+ //#region ../blocks/src/system/constants/buttonRoles.ts
16973
+ /**
16974
+ * Semantic button roles available to block authors.
16975
+ *
16976
+ * These roles are deliberately independent of a site's visual button style:
16977
+ * the active theme owns how each role looks.
16978
+ */
16979
+ const BLOCK_BUTTON_ROLES = PUBLIC_BUTTON_ROLES;
16980
+ const blockButtonRoleSchema = z$1.enum(BLOCK_BUTTON_ROLES);
16981
+ /**
16982
+ * Temporary rollout boundary for persisted content written before issue #1220.
16983
+ * Authoring remains strict through `blockButtonRoleSchema`; this parser exists
16984
+ * only until the post-deploy role rewrite has been audited in production.
16985
+ */
16986
+ function canonicalizePersistedBlockButtonRole(value) {
16987
+ return value === "link" || value === "tertiary" ? "ghost" : value;
16988
+ }
16989
+ const persistedBlockButtonRoleSchema = z$1.preprocess((value) => typeof value === "string" ? canonicalizePersistedBlockButtonRole(value) : value, blockButtonRoleSchema);
16990
+ const BLOCK_BUTTON_ROLE_LABELS = {
16991
+ primary: "Primary",
16992
+ secondary: "Secondary",
16993
+ outline: "Outline",
16994
+ ghost: "Ghost",
16995
+ accent: "Accent"
16996
+ };
16997
+ const BLOCK_BUTTON_ROLE_OPTIONS = BLOCK_BUTTON_ROLES.map((value) => ({
16998
+ value,
16999
+ label: BLOCK_BUTTON_ROLE_LABELS[value]
17000
+ }));
17001
+ function isBlockButtonRole(value) {
17002
+ return blockButtonRoleSchema.safeParse(value).success;
17003
+ }
17004
+ //#endregion
17325
17005
  //#region ../blocks/src/system/fields/button.ts
17326
- const DEFAULT_THEME_BUTTON_VARIANTS = [
17327
- {
17328
- value: "primary",
17329
- label: "Primary"
17330
- },
17331
- {
17332
- value: "secondary",
17333
- label: "Secondary"
17334
- },
17335
- {
17336
- value: "outline",
17337
- label: "Outline"
17338
- },
17339
- {
17340
- value: "link",
17341
- label: "Link"
17342
- }
17343
- ];
17006
+ const DEFAULT_THEME_BUTTON_VARIANTS = BLOCK_BUTTON_ROLE_OPTIONS;
17344
17007
  function createButtonVariantField(options = {}) {
17345
17008
  return {
17346
17009
  id: options.id ?? "buttonVariant",
@@ -17358,20 +17021,7 @@ function createButtonVariantField(options = {}) {
17358
17021
  };
17359
17022
  }
17360
17023
  function createButtonGroup(options = {}) {
17361
- const { variants = [
17362
- {
17363
- value: "primary",
17364
- label: "Primary"
17365
- },
17366
- {
17367
- value: "secondary",
17368
- label: "Secondary"
17369
- },
17370
- {
17371
- value: "outline",
17372
- label: "Outline"
17373
- }
17374
- ], defaultVariant, includeSize = true, defaultSize = "md", showGroupLabel = false, groupId = "button", groupLabel = "Button", flattenInRepeater = true } = options;
17024
+ const { variants = BLOCK_BUTTON_ROLE_OPTIONS, defaultVariant, includeSize = true, defaultSize = "md", showGroupLabel = false, groupId = "button", groupLabel = "Button", flattenInRepeater = true } = options;
17375
17025
  const mainFields = [
17376
17026
  {
17377
17027
  id: "label",
@@ -17507,29 +17157,7 @@ const ctaRowFragment = defineFragment({
17507
17157
  fields: [createCtasRepeater({
17508
17158
  label: "Calls to action",
17509
17159
  itemLabel: "CTA",
17510
- maxItems: 3,
17511
- button: { variants: [
17512
- {
17513
- value: "primary",
17514
- label: "Primary"
17515
- },
17516
- {
17517
- value: "secondary",
17518
- label: "Secondary"
17519
- },
17520
- {
17521
- value: "outline",
17522
- label: "Outline"
17523
- },
17524
- {
17525
- value: "link",
17526
- label: "Link"
17527
- },
17528
- {
17529
- value: "accent",
17530
- label: "Accent"
17531
- }
17532
- ] }
17160
+ maxItems: 3
17533
17161
  })],
17534
17162
  layout: [ctaRow({
17535
17163
  collectionPath: "content.ctas",
@@ -17548,10 +17176,6 @@ const heroCtaRowFragment = defineFragment({
17548
17176
  defaultValue: [],
17549
17177
  button: {
17550
17178
  variants: [
17551
- {
17552
- value: "default",
17553
- label: "Default"
17554
- },
17555
17179
  {
17556
17180
  value: "primary",
17557
17181
  label: "Primary"
@@ -17563,9 +17187,17 @@ const heroCtaRowFragment = defineFragment({
17563
17187
  {
17564
17188
  value: "outline",
17565
17189
  label: "Outline"
17190
+ },
17191
+ {
17192
+ value: "ghost",
17193
+ label: "Ghost"
17194
+ },
17195
+ {
17196
+ value: "accent",
17197
+ label: "Accent"
17566
17198
  }
17567
17199
  ],
17568
- defaultVariant: "default",
17200
+ defaultVariant: "primary",
17569
17201
  includeSize: true,
17570
17202
  defaultSize: "lg"
17571
17203
  }
@@ -18256,11 +17888,13 @@ const blogFeaturedPostFragment = defineFragment({
18256
17888
  as: "p",
18257
17889
  style: textColorStyle("text/80")
18258
17890
  }, bind("post.excerpt", { fallback: "Select a blog post to display its preview." })),
18259
- link({
18260
- className: "rb-inline-flex rb-items-center rb-caption rb-hover-opacity-80",
18261
- style: textColorStyle("primary"),
18262
- href: { $bind: { from: "post.path" } }
18263
- }, [text({ as: "strong" }, props({ value: "Read more →" }))])
17891
+ button({
17892
+ className: "rb-self-start",
17893
+ href: { $bind: { from: "post.path" } },
17894
+ variantId: "ghost",
17895
+ size: "sm",
17896
+ linkRequired: true
17897
+ }, [text({ as: "span" }, props({ value: "Read more" }))])
18264
17898
  ])], when("post")), stack({
18265
17899
  gap: "sm",
18266
17900
  className: "rb-rounded-xl rb-border rb-border-dashed rb-p-6",
@@ -18531,21 +18165,7 @@ const newsletterFormFragment = defineFragment({
18531
18165
  createButtonVariantField({
18532
18166
  id: "buttonVariant",
18533
18167
  label: "Button style",
18534
- defaultValue: "primary",
18535
- variants: [
18536
- {
18537
- value: "primary",
18538
- label: "Primary"
18539
- },
18540
- {
18541
- value: "secondary",
18542
- label: "Secondary"
18543
- },
18544
- {
18545
- value: "outline",
18546
- label: "Outline"
18547
- }
18548
- ]
18168
+ defaultValue: "primary"
18549
18169
  }),
18550
18170
  {
18551
18171
  id: "successMessage",
@@ -20094,7 +19714,8 @@ function postExcerpt(className) {
20094
19714
  function postReadMore() {
20095
19715
  return button({
20096
19716
  href: { $bind: { from: "post.path" } },
20097
- className: "rb-self-start"
19717
+ className: "rb-self-start",
19718
+ variantId: "ghost"
20098
19719
  }, [text({ as: "span" }, bind("content.readMoreText", { fallback: "Read more" }), when("content.readMoreText")), text({
20099
19720
  as: "span",
20100
19721
  value: "Read more"
@@ -22253,20 +21874,10 @@ function visitRichTextNode(node, allowedTokens, tokenValues) {
22253
21874
  }
22254
21875
  function interpolateRichTextTokens(value, options, context) {
22255
21876
  if (!isRecord$8(value)) return value;
22256
- const allowedTokens = new Set(options.tokens);
22257
- const tokenValues = {
21877
+ return visitRichTextNode(value, new Set(options.tokens), {
22258
21878
  year: String((/* @__PURE__ */ new Date()).getFullYear()),
22259
21879
  site_name: getSiteName(context)
22260
- };
22261
- if (isRecord$8(value.doc)) {
22262
- const nextDoc = visitRichTextNode(value.doc, allowedTokens, tokenValues);
22263
- if (nextDoc === value.doc) return value;
22264
- return {
22265
- ...value,
22266
- doc: nextDoc
22267
- };
22268
- }
22269
- return visitRichTextNode(value, allowedTokens, tokenValues);
21880
+ });
22270
21881
  }
22271
21882
  const contentTransforms = [{
22272
21883
  id: "content.interpolateRichTextTokens",
@@ -23676,31 +23287,7 @@ const featureCardsBlockDefinition = { manifest: createBlockManifest({
23676
23287
  label: "Calls to action",
23677
23288
  itemLabel: "CTA",
23678
23289
  maxItems: 1,
23679
- button: {
23680
- variants: [
23681
- {
23682
- value: "primary",
23683
- label: "Primary"
23684
- },
23685
- {
23686
- value: "secondary",
23687
- label: "Secondary"
23688
- },
23689
- {
23690
- value: "outline",
23691
- label: "Outline"
23692
- },
23693
- {
23694
- value: "ghost",
23695
- label: "Ghost"
23696
- },
23697
- {
23698
- value: "link",
23699
- label: "Link"
23700
- }
23701
- ],
23702
- defaultVariant: "ghost"
23703
- }
23290
+ button: { defaultVariant: "ghost" }
23704
23291
  })
23705
23292
  ] }
23706
23293
  },
@@ -24673,11 +24260,8 @@ const mediaSchema = z.discriminatedUnion("type", [
24673
24260
  * This module provides a single source of truth for TipTap rich text validation
24674
24261
  * across both the block-form editor and the block rendering system.
24675
24262
  *
24676
- * Format compatibility:
24677
- * - Unwrapped format (new): { type: 'doc', content: [...] }
24678
- * - Wrapped format (legacy): { doc: { type: 'doc', content: [...] } }
24679
- *
24680
- * Both formats are supported for backward compatibility during migration.
24263
+ * Rich-text fields use one canonical root shape:
24264
+ * `{ type: 'doc', content: [...] }`.
24681
24265
  */
24682
24266
  /**
24683
24267
  * TipTap document node schema (recursive structure)
@@ -24690,17 +24274,40 @@ const mediaSchema = z.discriminatedUnion("type", [
24690
24274
  * - marks: Text formatting marks (e.g., bold, italic)
24691
24275
  */
24692
24276
  const TipTapMarkSchema = z$1.object({
24693
- type: z$1.string(),
24277
+ type: z$1.string().min(1),
24694
24278
  attrs: z$1.record(z$1.string(), z$1.unknown()).optional()
24695
- });
24279
+ }).strict();
24696
24280
  const TipTapNodeSchema = z$1.lazy(() => z$1.object({
24697
- type: z$1.string(),
24281
+ type: z$1.string().min(1),
24698
24282
  content: z$1.array(TipTapNodeSchema).optional(),
24699
24283
  text: z$1.string().optional(),
24700
24284
  attrs: z$1.record(z$1.string(), z$1.unknown()).optional(),
24701
24285
  marks: z$1.array(TipTapMarkSchema).optional()
24286
+ }).strict().superRefine((node, ctx) => {
24287
+ if (node.type === "doc") ctx.addIssue({
24288
+ code: "custom",
24289
+ path: ["type"],
24290
+ message: "Document nodes are only valid at the rich-text root"
24291
+ });
24292
+ if (node.type === "text") {
24293
+ if (node.text === void 0 || node.text.length === 0) ctx.addIssue({
24294
+ code: "custom",
24295
+ path: ["text"],
24296
+ message: "Text nodes require a non-empty text value"
24297
+ });
24298
+ if (node.content !== void 0) ctx.addIssue({
24299
+ code: "custom",
24300
+ path: ["content"],
24301
+ message: "Text nodes cannot contain child nodes"
24302
+ });
24303
+ return;
24304
+ }
24305
+ if (node.text !== void 0) ctx.addIssue({
24306
+ code: "custom",
24307
+ path: ["text"],
24308
+ message: "Only text nodes can contain a text value"
24309
+ });
24702
24310
  }));
24703
- z$1.union([TipTapNodeSchema, z$1.object({ doc: TipTapNodeSchema })]);
24704
24311
  /**
24705
24312
  * Canonical schema for a TipTap rich-text document root.
24706
24313
  *
@@ -24709,13 +24316,11 @@ z$1.union([TipTapNodeSchema, z$1.object({ doc: TipTapNodeSchema })]);
24709
24316
  * (dummy content, editor output, migrations) must emit, and the shape every
24710
24317
  * non-legacy consumer can rely on.
24711
24318
  *
24712
- * Legacy envelopes are read-tolerated by {@link RichTextValueSchema} but
24713
- * normalised before reaching anywhere typed as `RichTextDoc`.
24714
24319
  */
24715
24320
  const RichTextDocSchema = z$1.object({
24716
24321
  type: z$1.literal("doc"),
24717
24322
  content: z$1.array(TipTapNodeSchema)
24718
- });
24323
+ }).strict();
24719
24324
  //#endregion
24720
24325
  //#region ../blocks/src/system/blocks/shared/bookingPaymentTerms.ts
24721
24326
  const bookingDepositRefundPolicySchema = z$1.enum(["refundable", "non_refundable"]);
@@ -25793,17 +25398,8 @@ function readAmount(value) {
25793
25398
  //#endregion
25794
25399
  //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
25795
25400
  const previewStageSchema = z$1.enum(["preview", "published"]);
25796
- const registrationButtonVariantSchema = z$1.enum([
25797
- "primary",
25798
- "secondary",
25799
- "outline"
25800
- ]);
25801
- const eventButtonVariantSchema = z$1.enum([
25802
- "primary",
25803
- "secondary",
25804
- "outline",
25805
- "link"
25806
- ]);
25401
+ const registrationButtonVariantSchema = blockButtonRoleSchema;
25402
+ const eventButtonVariantSchema = persistedBlockButtonRoleSchema;
25807
25403
  const eventLayoutSchema = z$1.enum(eventCalendarListLayoutValues);
25808
25404
  const eventCalendarDisplayModeSchema = z$1.enum(eventCalendarDisplayModeValues);
25809
25405
  const eventCalendarDefaultViewSchema = z$1.enum(eventCalendarDefaultViewValues);
@@ -26168,23 +25764,7 @@ const eventRegistrationBlockDefinition = {
26168
25764
  defaultValue: "Complete Registration",
26169
25765
  maxLength: 40
26170
25766
  },
26171
- createButtonVariantField({
26172
- description: "Choose a button style from your theme",
26173
- variants: [
26174
- {
26175
- value: "primary",
26176
- label: "Primary"
26177
- },
26178
- {
26179
- value: "secondary",
26180
- label: "Secondary"
26181
- },
26182
- {
26183
- value: "outline",
26184
- label: "Outline"
26185
- }
26186
- ]
26187
- })
25767
+ createButtonVariantField()
26188
25768
  ],
26189
25769
  layout: [styledSection({
26190
25770
  baseClass: "",
@@ -26491,23 +26071,7 @@ const courseRegistrationBlockDefinition = {
26491
26071
  defaultValue: "Sign up",
26492
26072
  maxLength: 40
26493
26073
  },
26494
- createButtonVariantField({
26495
- description: "Choose a button style from your theme",
26496
- variants: [
26497
- {
26498
- value: "primary",
26499
- label: "Primary"
26500
- },
26501
- {
26502
- value: "secondary",
26503
- label: "Secondary"
26504
- },
26505
- {
26506
- value: "outline",
26507
- label: "Outline"
26508
- }
26509
- ]
26510
- })
26074
+ createButtonVariantField()
26511
26075
  ],
26512
26076
  layout: [styledSection({
26513
26077
  baseClass: "",
@@ -29596,36 +29160,7 @@ const offeringsPreviewFields = [
29596
29160
  ui: { intent: "content" },
29597
29161
  schema: { fields: groupOverrideFields }
29598
29162
  },
29599
- {
29600
- id: "buttonVariant",
29601
- type: "select",
29602
- label: "Button style",
29603
- required: false,
29604
- multiple: false,
29605
- defaultValue: "primary",
29606
- options: [
29607
- {
29608
- value: "primary",
29609
- label: "Primary"
29610
- },
29611
- {
29612
- value: "secondary",
29613
- label: "Secondary"
29614
- },
29615
- {
29616
- value: "outline",
29617
- label: "Outline"
29618
- },
29619
- {
29620
- value: "link",
29621
- label: "Link"
29622
- }
29623
- ],
29624
- ui: {
29625
- intent: "display",
29626
- widget: "buttonVariant"
29627
- }
29628
- },
29163
+ createButtonVariantField(),
29629
29164
  {
29630
29165
  id: "buttonText",
29631
29166
  type: "text",
@@ -29831,7 +29366,7 @@ function normalizeOfferingsPreviewGroupOverride(value) {
29831
29366
  return [override];
29832
29367
  }
29833
29368
  function isButtonVariant(value) {
29834
- return value === "primary" || value === "secondary" || value === "outline" || value === "link" || value === null;
29369
+ return value === null || isBlockButtonRole(value);
29835
29370
  }
29836
29371
  function normalizeCardStylesContent(value) {
29837
29372
  return isRecord$3(value) || value === null ? value : void 0;
@@ -31683,12 +31218,7 @@ const shopSourceSchema = z$1.object({
31683
31218
  showPrices: z$1.boolean().optional(),
31684
31219
  showValidityPeriod: z$1.boolean().optional(),
31685
31220
  showPricePerCredit: z$1.boolean().nullable().optional(),
31686
- buttonVariant: z$1.enum([
31687
- "primary",
31688
- "secondary",
31689
- "outline",
31690
- "link"
31691
- ]).optional(),
31221
+ buttonVariant: blockButtonRoleSchema.optional(),
31692
31222
  passesHeading: z$1.string().optional(),
31693
31223
  membershipsHeading: z$1.string().optional(),
31694
31224
  buyButtonText: z$1.string().optional(),
@@ -31833,12 +31363,7 @@ const passesMembershipsHydrationSchema = z$1.object({
31833
31363
  passes: z$1.array(publicPassProductSchema),
31834
31364
  memberships: z$1.array(publicMembershipProductSchema),
31835
31365
  passPurchaseMode: z$1.enum(["add_to_cart", "buy_now"]),
31836
- buttonVariant: z$1.enum([
31837
- "primary",
31838
- "secondary",
31839
- "outline",
31840
- "link"
31841
- ])
31366
+ buttonVariant: blockButtonRoleSchema
31842
31367
  });
31843
31368
  const productListHydrationSchema = z$1.object({
31844
31369
  products: z$1.array(publicProductSchema),
@@ -33162,11 +32687,7 @@ const newsletterPresetSchema = z$1.enum([
33162
32687
  "emailNameCompany"
33163
32688
  ]);
33164
32689
  const newsletterDestinationProviderSchema = z$1.enum(["riverbank", "mailchimp"]);
33165
- const newsletterButtonVariantSchema = z$1.enum([
33166
- "primary",
33167
- "secondary",
33168
- "outline"
33169
- ]);
32690
+ const newsletterButtonVariantSchema = blockButtonRoleSchema;
33170
32691
  const newsletterFieldSchema = z$1.object({
33171
32692
  id: z$1.string(),
33172
32693
  type: z$1.enum(["email", "text"]),
@@ -36149,6 +35670,7 @@ const CANONICAL_REFUND_PLANNER_ERROR_CODES = [
36149
35670
  "idempotency_amount_mismatch",
36150
35671
  "idempotency_method_mismatch",
36151
35672
  "idempotency_receipt_mismatch",
35673
+ "idempotency_scope_mismatch",
36152
35674
  "refund_in_progress"
36153
35675
  ],
36154
35676
  "invalid_amount",
@@ -36535,7 +36057,7 @@ const SITE_BANNER_TONE_VALUES = [
36535
36057
  ];
36536
36058
  const siteBannerScopeSchema = z$1.enum(SITE_BANNER_SCOPE_VALUES);
36537
36059
  const siteBannerToneSchema = z$1.enum(SITE_BANNER_TONE_VALUES);
36538
- const siteBannerBodySchema = z$1.unknown().transform(unwrapRichTextValue);
36060
+ const siteBannerBodySchema = RichTextDocSchema;
36539
36061
  const siteBannerCtaSchema = z$1.object({
36540
36062
  label: z$1.string().trim().min(1),
36541
36063
  link: linkPayloadSchema
@@ -36563,7 +36085,8 @@ const EMPTY_SITE_BANNER_BODY = {
36563
36085
  }]
36564
36086
  };
36565
36087
  function analyzeSiteBannerBody(body) {
36566
- const sanitizedBody = sanitizeSiteBannerBodyInternal(body, { limitParagraphs: false });
36088
+ const parsed = RichTextDocSchema.safeParse(body);
36089
+ const sanitizedBody = parsed.success ? sanitizeSiteBannerBodyInternal(parsed.data, { limitParagraphs: false }) : EMPTY_SITE_BANNER_BODY;
36567
36090
  const paragraphs = collectParagraphs(sanitizedBody);
36568
36091
  const textLength = paragraphs.reduce((total, paragraph) => total + paragraphTextLength(paragraph), 0);
36569
36092
  const issues = [];
@@ -36585,7 +36108,7 @@ function siteBannerBodyIssueMessage(issue) {
36585
36108
  }
36586
36109
  }
36587
36110
  function sanitizeSiteBannerBodyInternal(input, options) {
36588
- const content = normalizeTopLevelNodes(unwrapRichTextValue(input).content ?? [], options);
36111
+ const content = normalizeTopLevelNodes(input.content, options);
36589
36112
  return {
36590
36113
  type: "doc",
36591
36114
  content: content.length > 0 ? content : EMPTY_SITE_BANNER_BODY.content
@@ -36666,28 +36189,6 @@ function sanitizeMarks(marks) {
36666
36189
  });
36667
36190
  return sanitized.length > 0 ? sanitized : void 0;
36668
36191
  }
36669
- function unwrapRichTextValue(value) {
36670
- if (isRecord$1(value) && isRecord$1(value.doc)) return unwrapRichTextValue(value.doc);
36671
- if (isRecord$1(value) && value.type === "doc") return {
36672
- type: "doc",
36673
- content: Array.isArray(value.content) ? value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) : []
36674
- };
36675
- return EMPTY_SITE_BANNER_BODY;
36676
- }
36677
- function isTipTapNodeLike(value) {
36678
- return isRecord$1(value) && typeof value.type === "string";
36679
- }
36680
- function coerceTipTapNode(value) {
36681
- return {
36682
- type: value.type,
36683
- ...Array.isArray(value.content) ? { content: value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) } : {},
36684
- ...typeof value.text === "string" ? { text: value.text } : {},
36685
- ...Array.isArray(value.marks) ? { marks: value.marks.filter((mark) => isRecord$1(mark) && typeof mark.type === "string").map((mark) => ({
36686
- type: mark.type,
36687
- ...isRecord$1(mark.attrs) ? { attrs: mark.attrs } : {}
36688
- })) } : {}
36689
- };
36690
- }
36691
36192
  function paragraphTextLength(paragraph) {
36692
36193
  return collectText(paragraph).length;
36693
36194
  }