@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
@@ -52,7 +52,7 @@ const TAG_TEMPLATES = {
52
52
  blockedDemoMutationPolicy("blocked-hidden", "This action is not available in demo sites.");
53
53
  blockedDemoMutationPolicy("blocked-disabled", "This setting is disabled in demo sites.");
54
54
  blockedDemoMutationPolicy("internal-only", "This internal operation is not available in demo sites.");
55
- 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;
55
+ 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;
56
56
  //#endregion
57
57
  //#region ../core/src/result.ts
58
58
  function ok(value) {
@@ -3248,151 +3248,6 @@ z$1.discriminatedUnion("kind", [
3248
3248
  })
3249
3249
  ]);
3250
3250
  //#endregion
3251
- //#region ../theme-core/src/surfaces/foregroundContract.ts
3252
- const SURFACE_FOREGROUND_CSS_VARS = {
3253
- text: "--rb-surface-text-color",
3254
- heading: "--rb-surface-heading-color",
3255
- link: "--rb-surface-link-color",
3256
- supporting: "--rb-surface-supporting-color"
3257
- };
3258
- const DEFAULT_SURFACE_TEXT_COLOR = "rgb(var(--tb-text, 17 24 39))";
3259
- const DEFAULT_ROLE_FALLBACKS = {
3260
- text: DEFAULT_SURFACE_TEXT_COLOR,
3261
- heading: DEFAULT_SURFACE_TEXT_COLOR,
3262
- link: "rgb(var(--tb-primary, var(--tb-text, 17 24 39)))",
3263
- supporting: "rgb(var(--tb-mutedText, 100 116 139))"
3264
- };
3265
- function requireSurfaceColorValue(role, value) {
3266
- const normalized = value.trim();
3267
- if (normalized.length === 0) throw new RangeError(`Surface foreground ${role} must be a non-empty CSS color.`);
3268
- return normalized;
3269
- }
3270
- function completeSurfaceForegrounds(input) {
3271
- const text = requireSurfaceColorValue("text", input.text);
3272
- return {
3273
- text,
3274
- heading: input.heading === void 0 ? text : requireSurfaceColorValue("heading", input.heading),
3275
- link: input.link === void 0 ? text : requireSurfaceColorValue("link", input.link),
3276
- supporting: input.supporting === void 0 ? text : requireSurfaceColorValue("supporting", input.supporting)
3277
- };
3278
- }
3279
- function surfaceForegroundValue(role, outsideProviderFallback = DEFAULT_ROLE_FALLBACKS[role]) {
3280
- const roleVariable = SURFACE_FOREGROUND_CSS_VARS[role];
3281
- const fallback = requireSurfaceColorValue("fallback", outsideProviderFallback);
3282
- if (role === "text") return `var(${roleVariable}, ${fallback})`;
3283
- return `var(${roleVariable}, var(${SURFACE_FOREGROUND_CSS_VARS.text}, ${fallback}))`;
3284
- }
3285
- function surfaceForegroundValueWithOpacity(role, opacityPercent) {
3286
- if (!Number.isFinite(opacityPercent) || opacityPercent < 0 || opacityPercent > 100) throw new RangeError("Surface foreground opacity must be between 0 and 100.");
3287
- return `color-mix(in srgb, ${surfaceForegroundValue(role)} ${opacityPercent}%, transparent)`;
3288
- }
3289
- function surfaceForegroundStyle(input) {
3290
- const foregrounds = completeSurfaceForegrounds(input);
3291
- return {
3292
- color: foregrounds.text,
3293
- [SURFACE_FOREGROUND_CSS_VARS.text]: foregrounds.text,
3294
- [SURFACE_FOREGROUND_CSS_VARS.heading]: foregrounds.heading,
3295
- [SURFACE_FOREGROUND_CSS_VARS.link]: foregrounds.link,
3296
- [SURFACE_FOREGROUND_CSS_VARS.supporting]: foregrounds.supporting
3297
- };
3298
- }
3299
- //#endregion
3300
- //#region ../theme-core/src/utils/colorStyles.ts
3301
- const COLOR_VAR_PREFIX = "--tb-";
3302
- function parseToken(source) {
3303
- const parts = parseColorTokenParts(source);
3304
- if (parts.kind === "raw") return {
3305
- token: source,
3306
- raw: parts.value
3307
- };
3308
- if (parts.kind === "invalid") return { token: source };
3309
- return {
3310
- token: parts.token,
3311
- opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
3312
- };
3313
- }
3314
- const SURFACE_TEXT_ROLE_BY_TOKEN = {
3315
- text: "text",
3316
- heading: "heading",
3317
- mutedText: "supporting"
3318
- };
3319
- function surfaceRoleForTextToken(token) {
3320
- return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
3321
- }
3322
- /**
3323
- * Converts a theme color token to a CSS rgb value.
3324
- * This is the primary function for applying theme colors to CSS properties.
3325
- *
3326
- * @param token - Theme color token (semantic, with opacity, or raw)
3327
- * @returns CSS color value (rgb with optional alpha, or raw CSS value)
3328
- *
3329
- * @example
3330
- * rgbColorValue('primary') // => 'rgb(var(--tb-primary))'
3331
- * rgbColorValue('surface/95') // => 'rgb(var(--tb-surface) / 0.95)'
3332
- * rgbColorValue('raw:transparent') // => 'transparent'
3333
- */
3334
- function rgbColorValue(token) {
3335
- const { token: baseToken, opacityPercent, raw } = parseToken(token);
3336
- if (raw) return raw;
3337
- const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
3338
- if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
3339
- return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
3340
- }
3341
- /**
3342
- * Creates a backgroundColor style object from a theme token.
3343
- *
3344
- * @param token - Theme color token
3345
- * @returns CSSProperties with backgroundColor
3346
- */
3347
- function backgroundColorStyle(token) {
3348
- return { backgroundColor: rgbColorValue(token) };
3349
- }
3350
- /**
3351
- * Creates a text color style object from a theme token.
3352
- *
3353
- * @param token - Theme color token
3354
- * @returns CSSProperties with color
3355
- */
3356
- function textColorStyle(token) {
3357
- const parsed = parseToken(token);
3358
- const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
3359
- if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
3360
- return { color: rgbColorValue(token) };
3361
- }
3362
- /**
3363
- * Creates a border color style object from a theme token.
3364
- *
3365
- * @param token - Theme color token
3366
- * @returns CSSProperties with borderColor
3367
- */
3368
- function borderColorStyle(token) {
3369
- return { borderColor: rgbColorValue(token) };
3370
- }
3371
- /**
3372
- * Merges multiple CSSProperties objects into a single object.
3373
- * Later styles override earlier ones. Undefined values are filtered out.
3374
- * Returns undefined if the merged result is empty.
3375
- *
3376
- * @param styles - Variable number of CSSProperties objects (can be undefined)
3377
- * @returns Merged CSSProperties object, or undefined if empty
3378
- *
3379
- * @example
3380
- * mergeStyles(
3381
- * backgroundColorStyle('surface'),
3382
- * textColorStyle('text'),
3383
- * borderColorStyle('border')
3384
- * )
3385
- * // => { backgroundColor: '...', color: '...', borderColor: '...' }
3386
- */
3387
- function mergeStyles(...styles) {
3388
- const merged = {};
3389
- for (const style of styles) {
3390
- if (!style) continue;
3391
- Object.assign(merged, style);
3392
- }
3393
- return Object.keys(merged).length ? merged : void 0;
3394
- }
3395
- //#endregion
3396
3251
  //#region ../theme-core/src/lib/media.ts
3397
3252
  const hotspotSchema$1 = z.object({
3398
3253
  x: z.number().min(0).max(1),
@@ -3450,111 +3305,6 @@ const mediaSchema$1 = z.object({
3450
3305
  transform: transformSchema$1.optional()
3451
3306
  });
3452
3307
  //#endregion
3453
- //#region ../theme-core/src/buttons/effectClassification.ts
3454
- /**
3455
- * Exhaustive live policy for every registered effect id.
3456
- *
3457
- * The resolver consumes the transition payload directly, so adding an effect
3458
- * cannot update classification without also defining its runtime behavior.
3459
- */
3460
- const BUTTON_EFFECT_POLICIES = {
3461
- "darken-background": {
3462
- classification: "colour-transition",
3463
- transition: {
3464
- kind: "adjust-shade",
3465
- direction: "darker"
3466
- }
3467
- },
3468
- "lighten-background": {
3469
- classification: "colour-transition",
3470
- transition: {
3471
- kind: "adjust-shade",
3472
- direction: "lighter"
3473
- }
3474
- },
3475
- "background-on-hover": {
3476
- classification: "colour-transition",
3477
- transition: { kind: "replace-background" }
3478
- },
3479
- "background-on-hover-alpha": {
3480
- classification: "unsupported-colour",
3481
- reason: "alpha_requires_surface"
3482
- },
3483
- "fade-background": {
3484
- classification: "unsupported-colour",
3485
- reason: "changes_element_opacity"
3486
- },
3487
- "opacity-reduce": {
3488
- classification: "unsupported-colour",
3489
- reason: "changes_element_opacity"
3490
- },
3491
- "gradient-text": {
3492
- classification: "unsupported-colour",
3493
- reason: "changes_foreground"
3494
- },
3495
- "text-color-change": {
3496
- classification: "unsupported-colour",
3497
- reason: "changes_foreground"
3498
- },
3499
- "border-color-change": {
3500
- classification: "unsupported-colour",
3501
- reason: "changes_border"
3502
- },
3503
- "aurora-glow": {
3504
- classification: "unsupported-background-overlay",
3505
- reason: "unresolved_background_overlay"
3506
- },
3507
- "cosmic-stardust": {
3508
- classification: "unsupported-background-overlay",
3509
- reason: "unresolved_background_overlay"
3510
- },
3511
- "gradient-border-fill": {
3512
- classification: "unsupported-background-overlay",
3513
- reason: "unresolved_background_overlay"
3514
- },
3515
- "animated-gradient-border-fill": {
3516
- classification: "unsupported-background-overlay",
3517
- reason: "unresolved_background_overlay"
3518
- },
3519
- "nav-underline": {
3520
- classification: "not-button",
3521
- reason: "not_button_effect"
3522
- },
3523
- "nav-frosted-base": {
3524
- classification: "not-button",
3525
- reason: "not_button_effect"
3526
- },
3527
- "nav-frosted-hover": {
3528
- classification: "not-button",
3529
- reason: "not_button_effect"
3530
- },
3531
- "nav-frosted-active": {
3532
- classification: "not-button",
3533
- reason: "not_button_effect"
3534
- },
3535
- "animated-gradient": { classification: "non-colour" },
3536
- "border-glow": { classification: "non-colour" },
3537
- "drop-shadow": { classification: "non-colour" },
3538
- "inner-shadow": { classification: "non-colour" },
3539
- "neumorphic-shadow": { classification: "non-colour" },
3540
- "outer-glow": { classification: "non-colour" },
3541
- "retro-3d-shadow": { classification: "non-colour" },
3542
- "scale-up": { classification: "non-colour" },
3543
- "scale-down": { classification: "non-colour" },
3544
- lift: { classification: "non-colour" },
3545
- "press-down": { classification: "non-colour" },
3546
- pop: { classification: "non-colour" },
3547
- "border-bottom-grow": { classification: "non-colour" },
3548
- "sketchy-border": { classification: "non-colour" },
3549
- "pulse-animation": { classification: "non-colour" }
3550
- };
3551
- function getButtonEffectPolicy(effectId) {
3552
- return Object.prototype.hasOwnProperty.call(BUTTON_EFFECT_POLICIES, effectId) ? BUTTON_EFFECT_POLICIES[effectId] : null;
3553
- }
3554
- function classifyButtonEffectId(effectId) {
3555
- return getButtonEffectPolicy(effectId)?.classification ?? "unknown";
3556
- }
3557
- //#endregion
3558
3308
  //#region ../theme-core/src/buttons/types.ts
3559
3309
  /**
3560
3310
  * Standard semantic variant roles a theme exposes.
@@ -3571,6 +3321,13 @@ const VARIANT_ROLES = [
3571
3321
  "tertiary",
3572
3322
  "accent"
3573
3323
  ];
3324
+ /**
3325
+ * Canonical persisted/CSS-safe button variant identifier.
3326
+ *
3327
+ * IDs become class selectors, so keep the contract deliberately narrower than
3328
+ * an arbitrary string and shared with every authoring/runtime boundary.
3329
+ */
3330
+ const buttonVariantIdSchema = z$1.string().min(1).max(50).regex(/^[a-z0-9-]+$/, "Button variant IDs may contain lowercase letters, numbers, and hyphens only");
3574
3331
  function parseOpaqueButtonColourToken(value) {
3575
3332
  const token = parseThemeColorToken(value);
3576
3333
  if (token === null) return null;
@@ -3585,6 +3342,109 @@ const opaqueButtonColourTokenSchema = themeColorTokenSchema.refine((value) => pa
3585
3342
  if (token === null) throw new Error("Invariant: opaque button token passed its schema");
3586
3343
  return token;
3587
3344
  });
3345
+ const buttonShadeAmountSchema = z$1.number().finite().min(0).max(900).multipleOf(100);
3346
+ const buttonShadowIntensitySchema = z$1.enum([
3347
+ "subtle",
3348
+ "medium",
3349
+ "strong"
3350
+ ]);
3351
+ /**
3352
+ * The complete persisted button-effect contract.
3353
+ *
3354
+ * Navigation has its own generic interactive-effect model. Button variants use
3355
+ * this closed union so unsupported effect IDs, unknown option keys, and unsafe
3356
+ * CSS values cannot become representable after the schema boundary.
3357
+ */
3358
+ const buttonEffectApplicationSchema = z$1.discriminatedUnion("effectId", [
3359
+ z$1.strictObject({
3360
+ effectId: z$1.literal("darken-background"),
3361
+ options: z$1.strictObject({ amount: buttonShadeAmountSchema.optional() }).optional()
3362
+ }),
3363
+ z$1.strictObject({
3364
+ effectId: z$1.literal("lighten-background"),
3365
+ options: z$1.strictObject({ amount: buttonShadeAmountSchema.optional() }).optional()
3366
+ }),
3367
+ z$1.strictObject({
3368
+ effectId: z$1.literal("background-on-hover"),
3369
+ options: z$1.strictObject({ colorToken: opaqueButtonColourTokenSchema.optional() }).optional()
3370
+ }),
3371
+ z$1.strictObject({
3372
+ effectId: z$1.literal("animated-gradient"),
3373
+ options: z$1.strictObject({ direction: z$1.enum(["horizontal", "vertical"]).optional() }).optional()
3374
+ }),
3375
+ z$1.strictObject({
3376
+ effectId: z$1.literal("drop-shadow"),
3377
+ options: z$1.strictObject({ intensity: buttonShadowIntensitySchema.optional() }).optional()
3378
+ }),
3379
+ z$1.strictObject({
3380
+ effectId: z$1.literal("inner-shadow"),
3381
+ options: z$1.strictObject({}).optional()
3382
+ }),
3383
+ z$1.strictObject({
3384
+ effectId: z$1.literal("neumorphic-shadow"),
3385
+ options: z$1.strictObject({
3386
+ mode: z$1.enum(["raised", "pressed"]).optional(),
3387
+ intensity: buttonShadowIntensitySchema.optional()
3388
+ }).optional()
3389
+ }),
3390
+ z$1.strictObject({
3391
+ effectId: z$1.literal("retro-3d-shadow"),
3392
+ options: z$1.strictObject({}).optional()
3393
+ }),
3394
+ z$1.strictObject({
3395
+ effectId: z$1.literal("scale-up"),
3396
+ options: z$1.strictObject({ scale: z$1.enum([
3397
+ "1.02",
3398
+ "1.03",
3399
+ "1.05",
3400
+ "1.10"
3401
+ ]).optional() }).optional()
3402
+ }),
3403
+ z$1.strictObject({
3404
+ effectId: z$1.literal("scale-down"),
3405
+ options: z$1.strictObject({ scale: z$1.enum([
3406
+ "0.90",
3407
+ "0.95",
3408
+ "0.97",
3409
+ "0.98"
3410
+ ]).optional() }).optional()
3411
+ }),
3412
+ z$1.strictObject({
3413
+ effectId: z$1.literal("lift"),
3414
+ options: z$1.strictObject({ amount: z$1.enum([
3415
+ "0.25",
3416
+ "0.5",
3417
+ "1"
3418
+ ]).optional() }).optional()
3419
+ }),
3420
+ z$1.strictObject({
3421
+ effectId: z$1.literal("press-down"),
3422
+ options: z$1.strictObject({}).optional()
3423
+ }),
3424
+ z$1.strictObject({
3425
+ effectId: z$1.literal("pop"),
3426
+ options: z$1.strictObject({ intensity: z$1.enum([
3427
+ "subtle",
3428
+ "medium",
3429
+ "dramatic"
3430
+ ]).optional() }).optional()
3431
+ }),
3432
+ z$1.strictObject({
3433
+ effectId: z$1.literal("border-bottom-grow"),
3434
+ options: z$1.strictObject({
3435
+ height: z$1.union([z$1.literal(1), z$1.literal(2)]).optional(),
3436
+ origin: z$1.enum([
3437
+ "left",
3438
+ "center",
3439
+ "right"
3440
+ ]).optional()
3441
+ }).optional()
3442
+ }),
3443
+ z$1.strictObject({
3444
+ effectId: z$1.literal("sketchy-border"),
3445
+ options: z$1.strictObject({ intensity: buttonShadowIntensitySchema.optional() }).optional()
3446
+ })
3447
+ ]);
3588
3448
  const cornerStyleSchema = z$1.enum([
3589
3449
  "square",
3590
3450
  "rounded",
@@ -3619,13 +3479,7 @@ const hoverTransformSchema = z$1.enum([
3619
3479
  "scale",
3620
3480
  "press"
3621
3481
  ]);
3622
- const hoverColorSchema = z$1.enum([
3623
- "none",
3624
- "brighten",
3625
- "darken",
3626
- "saturate",
3627
- "token"
3628
- ]);
3482
+ z$1.enum(["none", "token"]);
3629
3483
  const buttonPaddingPresetSchema = z$1.enum([
3630
3484
  "compact",
3631
3485
  "default",
@@ -3686,7 +3540,7 @@ const buttonSizesSchema = z$1.object({
3686
3540
  lg,
3687
3541
  xl: xl ?? lg
3688
3542
  }));
3689
- const canonicalButtonGlobalSettingsSchema = z$1.object({
3543
+ const buttonGlobalSettingsBaseSchema = z$1.strictObject({
3690
3544
  cornerStyle: cornerStyleSchema,
3691
3545
  cornerRadius: z$1.number().min(0).max(24).optional(),
3692
3546
  /**
@@ -3699,30 +3553,23 @@ const canonicalButtonGlobalSettingsSchema = z$1.object({
3699
3553
  shadow: shadowSizeSchema.optional(),
3700
3554
  textTransform: textTransformSchema,
3701
3555
  fontWeight: fontWeightSchema,
3702
- /**
3703
- * @deprecated Set per-variant via `variant.border.widthClass` instead.
3704
- * Schema field is preserved so existing presets parse; the value is unread
3705
- * by the current generator and will be removed once the legacy
3706
- * `primitives/content/components/Button.tsx` slot exports are deleted.
3707
- */
3708
- borderWidth: z$1.union([
3709
- z$1.literal(1),
3710
- z$1.literal(2),
3711
- z$1.literal(3)
3712
- ]),
3713
3556
  typography: buttonTypographySchema.optional(),
3714
3557
  fontSize: z$1.string().optional(),
3715
3558
  letterSpacing: letterSpacingSchema.optional(),
3716
3559
  italic: z$1.boolean().optional(),
3717
3560
  paddingPreset: buttonPaddingPresetSchema.optional(),
3718
3561
  hoverTransform: hoverTransformSchema,
3719
- hoverColor: hoverColorSchema,
3720
- hoverColorToken: opaqueButtonColourTokenSchema.optional(),
3721
3562
  gradientStyle: gradientStyleSchema.optional(),
3722
3563
  gradientAngle: z$1.number().min(0).max(360).optional(),
3723
3564
  gradientSharpness: gradientSharpnessSchema.optional()
3724
3565
  });
3725
- const buttonGlobalSettingsSchema = z$1.preprocess(normalizeLegacyButtonGlobalInput, canonicalButtonGlobalSettingsSchema);
3566
+ const buttonGlobalSettingsSchema = z$1.discriminatedUnion("hoverColor", [buttonGlobalSettingsBaseSchema.extend({
3567
+ hoverColor: z$1.literal("none"),
3568
+ hoverColorToken: z$1.never().optional()
3569
+ }), buttonGlobalSettingsBaseSchema.extend({
3570
+ hoverColor: z$1.literal("token"),
3571
+ hoverColorToken: opaqueButtonColourTokenSchema
3572
+ })]);
3726
3573
  const gradientDirectionSchema$1 = z$1.enum([
3727
3574
  "to-r",
3728
3575
  "to-l",
@@ -3733,12 +3580,12 @@ const gradientDirectionSchema$1 = z$1.enum([
3733
3580
  "to-br",
3734
3581
  "to-bl"
3735
3582
  ]);
3736
- const buttonBackgroundSchema = z$1.discriminatedUnion("type", [
3737
- z$1.object({
3583
+ const buttonColourTreatmentSchema = z$1.discriminatedUnion("type", [
3584
+ z$1.strictObject({
3738
3585
  type: z$1.literal("solid"),
3739
3586
  colorToken: opaqueButtonColourTokenSchema
3740
3587
  }),
3741
- z$1.object({
3588
+ z$1.strictObject({
3742
3589
  type: z$1.literal("gradient"),
3743
3590
  stops: z$1.array(opaqueButtonColourTokenSchema).min(2).transform((stops) => {
3744
3591
  const [first, second, ...rest] = stops;
@@ -3752,18 +3599,15 @@ const buttonBackgroundSchema = z$1.discriminatedUnion("type", [
3752
3599
  direction: gradientDirectionSchema$1,
3753
3600
  foregroundToken: opaqueButtonColourTokenSchema
3754
3601
  }),
3755
- z$1.object({
3602
+ z$1.strictObject({
3756
3603
  type: z$1.literal("surface"),
3757
3604
  role: z$1.literal("link")
3758
3605
  })
3759
3606
  ]);
3760
- const effectApplicationSchema$1 = z$1.object({
3761
- effectId: z$1.string(),
3762
- options: z$1.record(z$1.string(), z$1.json()).optional()
3763
- });
3764
- const buttonBorderSchema = z$1.object({ widthClass: z$1.string() });
3765
- const buttonVariantAffordanceSchema = z$1.object({ iconId: z$1.string().min(1) });
3766
- const variantShadowSchema = z$1.object({
3607
+ const buttonBackgroundSchema = buttonColourTreatmentSchema;
3608
+ const buttonBorderSchema = z$1.strictObject({ widthClass: z$1.string() });
3609
+ const buttonVariantAffordanceSchema = z$1.strictObject({ iconId: z$1.string().min(1) });
3610
+ const variantShadowSchema = z$1.strictObject({
3767
3611
  elevation: z$1.enum([
3768
3612
  "none",
3769
3613
  "low",
@@ -3776,13 +3620,13 @@ const variantShadowSchema = z$1.object({
3776
3620
  "hard"
3777
3621
  ]).nullable(),
3778
3622
  position: z$1.enum(["bottom", "bottom-right"]).default("bottom"),
3779
- colorToken: themeColorTokenSchema.optional()
3623
+ colorToken: opaqueButtonColourTokenSchema.optional()
3780
3624
  });
3781
- const variantEffectsSchema = z$1.object({
3782
- base: z$1.array(effectApplicationSchema$1).optional(),
3783
- hover: z$1.array(effectApplicationSchema$1).optional(),
3784
- active: z$1.array(effectApplicationSchema$1).optional(),
3785
- focus: z$1.array(effectApplicationSchema$1).optional()
3625
+ const variantEffectsSchema = z$1.strictObject({
3626
+ base: z$1.array(buttonEffectApplicationSchema).optional(),
3627
+ hover: z$1.array(buttonEffectApplicationSchema).optional(),
3628
+ active: z$1.array(buttonEffectApplicationSchema).optional(),
3629
+ focus: z$1.array(buttonEffectApplicationSchema).optional()
3786
3630
  });
3787
3631
  /**
3788
3632
  * Per-variant size overrides schema — every entry is optional.
@@ -3803,8 +3647,8 @@ const variantSizeOverridesSchema = z$1.object({
3803
3647
  * default (e.g. link-style variants declaring zero horizontal padding at
3804
3648
  * every size).
3805
3649
  */
3806
- const canonicalButtonVariantSchema = z$1.object({
3807
- id: z$1.string(),
3650
+ const buttonVariantSchema = z$1.strictObject({
3651
+ id: buttonVariantIdSchema,
3808
3652
  name: z$1.string().min(1).max(20),
3809
3653
  enabled: z$1.boolean(),
3810
3654
  priority: prioritySchema,
@@ -3818,422 +3662,499 @@ const canonicalButtonVariantSchema = z$1.object({
3818
3662
  sizes: variantSizeOverridesSchema.optional(),
3819
3663
  affordance: buttonVariantAffordanceSchema.optional()
3820
3664
  });
3821
- /**
3822
- * Temporary persisted-theme admission boundary for issue #1206.
3823
- *
3824
- * Production inventory on 2026-07-22 found 22 rows using the old independent
3825
- * `textColorToken`/border colour shape. New source and all downstream code use
3826
- * only the canonical relationship. Delete this preprocessor after the reviewed
3827
- * production rewrite reports zero legacy rows.
3828
- */
3829
- const buttonVariantSchema = z$1.preprocess(normalizeLegacyButtonVariantInput, canonicalButtonVariantSchema);
3830
- const buttonSystemSchema = z$1.object({
3665
+ const buttonSystemSchema = z$1.strictObject({
3831
3666
  global: buttonGlobalSettingsSchema,
3832
3667
  variants: z$1.array(buttonVariantSchema).min(1).max(6),
3833
3668
  sizes: buttonSizesSchema.optional()
3669
+ }).superRefine((system, ctx) => {
3670
+ const seen = /* @__PURE__ */ new Set();
3671
+ system.variants.forEach((variant, index) => {
3672
+ if (seen.has(variant.id)) ctx.addIssue({
3673
+ code: "custom",
3674
+ path: [
3675
+ "variants",
3676
+ index,
3677
+ "id"
3678
+ ],
3679
+ message: `Duplicate button variant ID: ${variant.id}`
3680
+ });
3681
+ seen.add(variant.id);
3682
+ });
3834
3683
  });
3835
- function normalizeLegacyButtonVariantInput(input) {
3836
- if (!isUnknownRecord(input)) return input;
3837
- const background = input.background;
3838
- if (!isUnknownRecord(background)) return input;
3839
- 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;
3840
- const { textColorToken, ...withoutLegacyText } = input;
3841
- const normalizedBorder = isUnknownRecord(input.border) && typeof input.border.widthClass === "string" ? { widthClass: input.border.widthClass } : input.border;
3842
- const normalizedAffordance = isUnknownRecord(input.affordance) && typeof input.affordance.iconId === "string" ? { iconId: input.affordance.iconId } : input.affordance;
3843
- const normalizedEffects = normalizeLegacyButtonEffects(input.effects, background.type);
3844
- const hoverBackgroundToken = stripLegacyTokenAlpha(input.hoverBackgroundToken);
3845
- if (background.type === "transparent") return {
3846
- ...withoutLegacyText,
3847
- background: {
3848
- type: "surface",
3849
- role: "link"
3850
- },
3851
- border: normalizedBorder,
3852
- affordance: normalizedAffordance,
3853
- effects: normalizedEffects,
3854
- hoverBackgroundToken
3855
- };
3856
- if (background.type === "gradient") {
3857
- const stops = Array.isArray(background.stops) ? background.stops.map(stripLegacyTokenAlpha) : background.stops;
3858
- return {
3859
- ...withoutLegacyText,
3860
- background: {
3861
- ...background,
3862
- stops,
3863
- foregroundToken: stripLegacyTokenAlpha(background.foregroundToken ?? textColorToken)
3864
- },
3865
- border: normalizedBorder,
3866
- affordance: normalizedAffordance,
3867
- effects: normalizedEffects,
3868
- hoverBackgroundToken
3869
- };
3870
- }
3871
- return {
3872
- ...withoutLegacyText,
3873
- background: background.type === "solid" ? {
3874
- ...background,
3875
- colorToken: stripLegacyTokenAlpha(background.colorToken)
3876
- } : background,
3877
- border: normalizedBorder,
3878
- affordance: normalizedAffordance,
3879
- effects: normalizedEffects,
3880
- hoverBackgroundToken
3881
- };
3684
+ //#endregion
3685
+ //#region ../theme-core/src/surfaces/foregroundContract.ts
3686
+ const SURFACE_FOREGROUND_CSS_VARS = {
3687
+ text: "--rb-surface-text-color",
3688
+ heading: "--rb-surface-heading-color",
3689
+ link: "--rb-surface-link-color",
3690
+ supporting: "--rb-surface-supporting-color"
3691
+ };
3692
+ const DEFAULT_SURFACE_TEXT_COLOR = "rgb(var(--tb-text, 17 24 39))";
3693
+ const DEFAULT_ROLE_FALLBACKS = {
3694
+ text: DEFAULT_SURFACE_TEXT_COLOR,
3695
+ heading: DEFAULT_SURFACE_TEXT_COLOR,
3696
+ link: "rgb(var(--tb-primary, var(--tb-text, 17 24 39)))",
3697
+ supporting: "rgb(var(--tb-mutedText, 100 116 139))"
3698
+ };
3699
+ function requireSurfaceColorValue(role, value) {
3700
+ const normalized = value.trim();
3701
+ if (normalized.length === 0) throw new RangeError(`Surface foreground ${role} must be a non-empty CSS color.`);
3702
+ return normalized;
3882
3703
  }
3883
- function normalizeLegacyButtonGlobalInput(input) {
3884
- if (!isUnknownRecord(input)) return input;
3885
- const hoverColorToken = stripLegacyTokenAlpha(input.hoverColorToken);
3886
- return hoverColorToken === input.hoverColorToken ? input : {
3887
- ...input,
3888
- hoverColorToken
3704
+ function completeSurfaceForegrounds(input) {
3705
+ const text = requireSurfaceColorValue("text", input.text);
3706
+ return {
3707
+ text,
3708
+ heading: input.heading === void 0 ? text : requireSurfaceColorValue("heading", input.heading),
3709
+ link: input.link === void 0 ? text : requireSurfaceColorValue("link", input.link),
3710
+ supporting: input.supporting === void 0 ? text : requireSurfaceColorValue("supporting", input.supporting)
3889
3711
  };
3890
3712
  }
3891
- function hasLegacyAlphaToken(input, background) {
3892
- const stops = isUnknownArray(background.stops) ? background.stops : [];
3893
- return [
3894
- input.hoverBackgroundToken,
3895
- background.colorToken,
3896
- background.foregroundToken,
3897
- ...stops
3898
- ].some((token) => stripLegacyTokenAlpha(token) !== token);
3899
- }
3900
- function stripLegacyTokenAlpha(value) {
3901
- if (typeof value !== "string") return value;
3902
- const slashIndex = value.indexOf("/");
3903
- return slashIndex < 0 ? value : value.slice(0, slashIndex);
3904
- }
3905
- function hasLegacyButtonEffects(input) {
3906
- if (!isUnknownRecord(input)) return false;
3907
- return [
3908
- "base",
3909
- "hover",
3910
- "active",
3911
- "focus"
3912
- ].some((state) => {
3913
- const effects = input[state];
3914
- return Array.isArray(effects) && effects.some((effect) => {
3915
- if (!isUnknownRecord(effect) || typeof effect.effectId !== "string") return true;
3916
- const classification = classifyButtonEffectId(effect.effectId);
3917
- if (classification !== "colour-transition" && classification !== "non-colour") return true;
3918
- return effect.effectId === "background-on-hover" && isUnknownRecord(effect.options) && stripLegacyTokenAlpha(effect.options.colorToken) !== effect.options.colorToken;
3919
- });
3920
- });
3921
- }
3922
- function normalizeLegacyButtonEffects(input, backgroundType) {
3923
- if (!isUnknownRecord(input)) return input;
3924
- const normalized = {};
3925
- for (const state of [
3926
- "base",
3927
- "hover",
3928
- "active",
3929
- "focus"
3930
- ]) {
3931
- const effects = input[state];
3932
- if (!Array.isArray(effects)) continue;
3933
- const safeEffects = effects.flatMap((effect) => {
3934
- if (!isUnknownRecord(effect) || typeof effect.effectId !== "string") return [];
3935
- const classification = classifyButtonEffectId(effect.effectId);
3936
- if (classification === "non-colour") return [effect];
3937
- if (classification !== "colour-transition") return [];
3938
- if (effect.effectId === "background-on-hover") {
3939
- const options = isUnknownRecord(effect.options) ? effect.options : null;
3940
- const colorToken = options === null ? null : parseOpaqueButtonColourToken(stripLegacyTokenAlpha(options.colorToken));
3941
- return colorToken === null ? [] : [{
3942
- ...effect,
3943
- options: {
3944
- ...options,
3945
- colorToken
3946
- }
3947
- }];
3948
- }
3949
- if (backgroundType !== "solid") return [];
3950
- const rawAmount = isUnknownRecord(effect.options) ? effect.options.amount : void 0;
3951
- const amount = typeof rawAmount === "number" && rawAmount > 0 ? Math.max(100, Math.round(rawAmount / 100) * 100) : 100;
3952
- return [{
3953
- ...effect,
3954
- options: {
3955
- ...isUnknownRecord(effect.options) ? effect.options : {},
3956
- amount
3957
- }
3958
- }];
3959
- });
3960
- if (safeEffects.length > 0) normalized[state] = safeEffects;
3961
- }
3962
- return Object.keys(normalized).length === 0 ? void 0 : normalized;
3713
+ function surfaceForegroundValue(role, outsideProviderFallback = DEFAULT_ROLE_FALLBACKS[role]) {
3714
+ const roleVariable = SURFACE_FOREGROUND_CSS_VARS[role];
3715
+ const fallback = requireSurfaceColorValue("fallback", outsideProviderFallback);
3716
+ if (role === "text") return `var(${roleVariable}, ${fallback})`;
3717
+ return `var(${roleVariable}, var(${SURFACE_FOREGROUND_CSS_VARS.text}, ${fallback}))`;
3963
3718
  }
3964
- function isUnknownRecord(value) {
3965
- return typeof value === "object" && value !== null && !Array.isArray(value);
3719
+ function surfaceForegroundValueWithOpacity(role, opacityPercent) {
3720
+ if (!Number.isFinite(opacityPercent) || opacityPercent < 0 || opacityPercent > 100) throw new RangeError("Surface foreground opacity must be between 0 and 100.");
3721
+ return `color-mix(in srgb, ${surfaceForegroundValue(role)} ${opacityPercent}%, transparent)`;
3966
3722
  }
3967
- function isUnknownArray(value) {
3968
- return Array.isArray(value);
3723
+ function surfaceForegroundStyle(input) {
3724
+ const foregrounds = completeSurfaceForegrounds(input);
3725
+ return {
3726
+ color: foregrounds.text,
3727
+ [SURFACE_FOREGROUND_CSS_VARS.text]: foregrounds.text,
3728
+ [SURFACE_FOREGROUND_CSS_VARS.heading]: foregrounds.heading,
3729
+ [SURFACE_FOREGROUND_CSS_VARS.link]: foregrounds.link,
3730
+ [SURFACE_FOREGROUND_CSS_VARS.supporting]: foregrounds.supporting
3731
+ };
3969
3732
  }
3970
3733
  buttonSizeNameSchema.options;
3971
3734
  //#endregion
3972
- //#region ../theme-core/src/buttons/personalities/types.ts
3973
- function asButtonPersonalityId(value) {
3974
- if (value.length === 0) throw new Error("ButtonPersonalityId must be a non-empty string");
3975
- return value;
3735
+ //#region ../theme-core/src/buttons/styles/domain.ts
3736
+ const PUBLIC_BUTTON_ROLES = [
3737
+ "primary",
3738
+ "secondary",
3739
+ "outline",
3740
+ "ghost",
3741
+ "accent"
3742
+ ];
3743
+ function defineButtonStyleRecipe(recipe) {
3744
+ return recipe;
3745
+ }
3746
+ function materializeButtonRoles(definitions) {
3747
+ const primary = materializeCompleteRole("primary", definitions.primary.appearance);
3748
+ const secondary = materializeCompleteRole("secondary", definitions.secondary.appearance);
3749
+ const completeRoles = {
3750
+ primary,
3751
+ secondary
3752
+ };
3753
+ return {
3754
+ primary,
3755
+ secondary,
3756
+ outline: materializeSupportingRole("outline", definitions.outline, completeRoles),
3757
+ ghost: materializeSupportingRole("ghost", definitions.ghost, completeRoles),
3758
+ accent: materializeSupportingRole("accent", definitions.accent, completeRoles)
3759
+ };
3976
3760
  }
3977
- const buttonPersonalityIdSchema = z$1.string().min(1).transform((value) => asButtonPersonalityId(value));
3978
- z$1.object({
3979
- id: buttonPersonalityIdSchema,
3980
- name: z$1.string().min(1),
3981
- description: z$1.string().min(1),
3982
- tags: styleTagsSchema,
3983
- buttonSystem: buttonSystemSchema
3984
- });
3985
- /**
3986
- * Helper for personality file modules to keep the call site short and
3987
- * type-safe. `as const satisfies ...` would also work but produces wider
3988
- * types at use sites.
3989
- */
3990
- function defineButtonPersonality(input) {
3761
+ function resolveButtonStyleRecipe(recipe, parameters) {
3762
+ const parsedParameters = recipe.parameterSchema.safeParse(parameters);
3763
+ if (!parsedParameters.success) return {
3764
+ kind: "error",
3765
+ error: {
3766
+ kind: "invalid-parameters",
3767
+ styleId: recipe.id,
3768
+ issues: parsedParameters.error.issues.map((issue) => issue.message)
3769
+ }
3770
+ };
3771
+ const definition = recipe.defineSystem(parsedParameters.data);
3772
+ const roles = materializeButtonRoles(definition.roles);
3773
+ const buttonSystem = {
3774
+ global: definition.global,
3775
+ variants: PUBLIC_BUTTON_ROLES.map((role) => roles[role]),
3776
+ ...definition.sizes ? { sizes: definition.sizes } : {}
3777
+ };
3778
+ const parsedButtonSystem = buttonSystemSchema.safeParse(buttonSystem);
3779
+ if (!parsedButtonSystem.success) return {
3780
+ kind: "error",
3781
+ error: {
3782
+ kind: "invalid-button-system",
3783
+ styleId: recipe.id,
3784
+ issues: parsedButtonSystem.error.issues.map((issue) => issue.message)
3785
+ }
3786
+ };
3991
3787
  return {
3992
- id: asButtonPersonalityId(input.id),
3993
- name: input.name,
3994
- description: input.description,
3995
- tags: input.tags,
3996
- buttonSystem: buttonSystemSchema.parse(input.buttonSystem)
3788
+ kind: "resolved",
3789
+ buttonSystem: parsedButtonSystem.data
3997
3790
  };
3998
3791
  }
3792
+ function materializeSupportingRole(role, definition, completeRoles) {
3793
+ if (definition.kind === "complete") return materializeCompleteRole(role, definition.appearance);
3794
+ return {
3795
+ ...completeRoles[definition.from],
3796
+ ...definition.overrides,
3797
+ id: role,
3798
+ name: roleName(role),
3799
+ enabled: true,
3800
+ priority: 3
3801
+ };
3802
+ }
3803
+ function materializeCompleteRole(role, appearance) {
3804
+ return {
3805
+ ...appearance,
3806
+ id: role,
3807
+ name: roleName(role),
3808
+ enabled: true,
3809
+ priority: rolePriority(role)
3810
+ };
3811
+ }
3812
+ function roleName(role) {
3813
+ return role.charAt(0).toUpperCase() + role.slice(1);
3814
+ }
3815
+ function rolePriority(role) {
3816
+ if (role === "primary") return 1;
3817
+ if (role === "secondary") return 2;
3818
+ return 3;
3819
+ }
3820
+ //#endregion
3821
+ //#region ../theme-core/src/buttons/styles/selection.ts
3822
+ const BUTTON_STYLE_IDS = [
3823
+ "soft-pill",
3824
+ "earth-pill",
3825
+ "confident-chip",
3826
+ "editorial-link",
3827
+ "pebble",
3828
+ "ink-stamp",
3829
+ "flat-ink",
3830
+ "brushed-wash",
3831
+ "showtime-pill",
3832
+ "joy-stamp",
3833
+ "ornate-ritual",
3834
+ "quiet-arrow"
3835
+ ];
3836
+ const quietArrowParametersSchema = z$1.object({ secondaryTreatment: z$1.enum(["outlined", "solid-accent"]) }).strict();
3837
+ const emptyParametersSchema$1 = z$1.object({}).strict();
3838
+ function selectionBranch(styleId, parameters) {
3839
+ return z$1.object({
3840
+ styleId: z$1.literal(styleId),
3841
+ parameters
3842
+ }).strict();
3843
+ }
3844
+ const buttonStyleSelectionSchema = z$1.discriminatedUnion("styleId", [
3845
+ selectionBranch("soft-pill", emptyParametersSchema$1),
3846
+ selectionBranch("earth-pill", emptyParametersSchema$1),
3847
+ selectionBranch("confident-chip", emptyParametersSchema$1),
3848
+ selectionBranch("editorial-link", emptyParametersSchema$1),
3849
+ selectionBranch("pebble", emptyParametersSchema$1),
3850
+ selectionBranch("ink-stamp", emptyParametersSchema$1),
3851
+ selectionBranch("flat-ink", emptyParametersSchema$1),
3852
+ selectionBranch("brushed-wash", emptyParametersSchema$1),
3853
+ selectionBranch("showtime-pill", emptyParametersSchema$1),
3854
+ selectionBranch("joy-stamp", emptyParametersSchema$1),
3855
+ selectionBranch("ornate-ritual", emptyParametersSchema$1),
3856
+ selectionBranch("quiet-arrow", quietArrowParametersSchema)
3857
+ ]);
3999
3858
  //#endregion
4000
- //#region ../theme-core/src/buttons/personalities/brushed-wash.ts
4001
- /**
4002
- * Brushed Wash — gradient backgrounds that read as watercolour washes.
4003
- * Generous padding, soft shadows; pairs with vibrant organic brands.
4004
- */
4005
- const brushedWash = defineButtonPersonality({
4006
- id: "brushed-wash",
4007
- name: "Brushed Wash",
4008
- description: "Watercolour-gradient buttons with soft shadows and generous padding.",
3859
+ //#region ../theme-core/src/buttons/styles/recipes/quietArrow.ts
3860
+ const quietArrowRecipe = defineButtonStyleRecipe({
3861
+ id: "quiet-arrow",
3862
+ accessibilityLabel: "Wide uppercase buttons with trailing arrows",
4009
3863
  tags: {
4010
3864
  tone: "classic",
4011
- energy: "vibrant",
4012
- motion: "standard",
4013
- era: "organic"
3865
+ energy: "calm",
3866
+ motion: "subtle",
3867
+ era: "editorial"
4014
3868
  },
4015
- buttonSystem: {
3869
+ parameterSchema: quietArrowParametersSchema,
3870
+ defaultParameters: { secondaryTreatment: "outlined" },
3871
+ controls: [{
3872
+ kind: "choice",
3873
+ parameter: "secondaryTreatment",
3874
+ label: "Secondary button treatment",
3875
+ options: [{
3876
+ value: "outlined",
3877
+ label: "Outlined"
3878
+ }, {
3879
+ value: "solid-accent",
3880
+ label: "Solid accent"
3881
+ }]
3882
+ }],
3883
+ defineSystem: (parameters) => ({
4016
3884
  global: {
4017
3885
  cornerStyle: "rounded",
4018
- shadow: "low",
4019
- textTransform: "none",
3886
+ textTransform: "uppercase",
4020
3887
  fontWeight: 500,
4021
- borderWidth: 1,
3888
+ typography: "body",
3889
+ fontSize: "text-sm",
3890
+ letterSpacing: "loose",
4022
3891
  hoverTransform: "none",
4023
3892
  hoverColor: "none"
4024
3893
  },
4025
3894
  sizes: {
4026
3895
  sm: {
4027
- padding: "0.75rem 2rem",
3896
+ padding: "0.625rem 1.25rem",
3897
+ fontSize: "text-xs"
3898
+ },
3899
+ md: {
3900
+ padding: "0.8125rem 1.75rem",
4028
3901
  fontSize: "text-sm"
4029
3902
  },
4030
- md: { padding: "1rem 2.5rem" },
4031
3903
  lg: {
4032
- padding: "1.25rem 3rem",
4033
- fontSize: "text-lg"
3904
+ padding: "0.9375rem 2.125rem",
3905
+ fontSize: "text-sm"
4034
3906
  },
4035
3907
  xl: {
4036
- padding: "1.625rem 3.75rem",
4037
- fontSize: "text-xl"
3908
+ padding: "1.0625rem 2.5rem",
3909
+ fontSize: "text-base"
4038
3910
  }
4039
3911
  },
4040
- variants: [
4041
- {
4042
- id: "primary",
4043
- name: "Primary",
4044
- enabled: true,
4045
- priority: 1,
4046
- background: {
4047
- type: "gradient",
4048
- stops: ["primary", "accent"],
4049
- direction: "to-r",
4050
- foregroundToken: "primaryForeground"
4051
- },
4052
- borderRadius: "rounded-lg",
4053
- shadow: {
4054
- elevation: "low",
4055
- softness: "soft",
4056
- position: "bottom"
3912
+ roles: {
3913
+ primary: {
3914
+ kind: "complete",
3915
+ appearance: {
3916
+ background: {
3917
+ type: "solid",
3918
+ colorToken: unsafeAsOpaqueButtonColourToken("primary")
3919
+ },
3920
+ borderRadius: "rounded-xl",
3921
+ affordance: { iconId: "ArrowRight" },
3922
+ effects: { hover: [{
3923
+ effectId: "darken-background",
3924
+ options: { amount: 100 }
3925
+ }] }
4057
3926
  }
4058
3927
  },
4059
- {
4060
- id: "secondary",
4061
- name: "Secondary",
4062
- enabled: true,
4063
- priority: 2,
4064
- background: {
4065
- type: "gradient",
4066
- stops: ["secondary", "accent"],
4067
- direction: "to-br",
4068
- foregroundToken: "primaryForeground"
4069
- },
4070
- borderRadius: "rounded-lg",
4071
- shadow: {
4072
- elevation: "low",
4073
- softness: "soft",
4074
- position: "bottom"
3928
+ secondary: {
3929
+ kind: "complete",
3930
+ appearance: parameters.secondaryTreatment === "solid-accent" ? {
3931
+ background: {
3932
+ type: "solid",
3933
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
3934
+ },
3935
+ borderRadius: "rounded-xl",
3936
+ affordance: { iconId: "ArrowRight" },
3937
+ effects: { hover: [{
3938
+ effectId: "darken-background",
3939
+ options: { amount: 100 }
3940
+ }] }
3941
+ } : {
3942
+ background: {
3943
+ type: "surface",
3944
+ role: "link"
3945
+ },
3946
+ borderRadius: "rounded-xl",
3947
+ border: { widthClass: "border" },
3948
+ affordance: { iconId: "ArrowRight" },
3949
+ effects: { hover: [{
3950
+ effectId: "background-on-hover",
3951
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
3952
+ }] }
4075
3953
  }
4076
3954
  },
4077
- {
4078
- id: "outline",
4079
- name: "Outline",
4080
- enabled: true,
4081
- priority: 3,
4082
- background: {
4083
- type: "surface",
4084
- role: "link"
4085
- },
4086
- borderRadius: "rounded-lg",
4087
- border: { widthClass: "border" },
4088
- effects: { hover: [{
4089
- effectId: "background-on-hover",
4090
- options: { colorToken: "surface" }
4091
- }] }
3955
+ outline: {
3956
+ kind: "complete",
3957
+ appearance: {
3958
+ background: {
3959
+ type: "surface",
3960
+ role: "link"
3961
+ },
3962
+ borderRadius: "rounded-xl",
3963
+ border: { widthClass: "border" }
3964
+ }
4092
3965
  },
4093
- {
4094
- id: "ghost",
4095
- name: "Ghost",
4096
- enabled: true,
4097
- priority: 3,
4098
- background: {
4099
- type: "surface",
4100
- role: "link"
4101
- },
4102
- borderRadius: "rounded-lg",
4103
- effects: { hover: [{
4104
- effectId: "background-on-hover",
4105
- options: { colorToken: "surface" }
4106
- }] }
3966
+ ghost: {
3967
+ kind: "complete",
3968
+ appearance: {
3969
+ background: {
3970
+ type: "surface",
3971
+ role: "link"
3972
+ },
3973
+ borderRadius: "rounded-xl"
3974
+ }
3975
+ },
3976
+ accent: {
3977
+ kind: "derive",
3978
+ from: "primary",
3979
+ overrides: { background: {
3980
+ type: "solid",
3981
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
3982
+ } }
4107
3983
  }
4108
- ]
4109
- }
3984
+ }
3985
+ })
4110
3986
  });
4111
3987
  //#endregion
4112
- //#region ../theme-core/src/buttons/personalities/confident-chip.ts
4113
- /**
4114
- * Confident Chip — moderate-radius solid buttons that read as competent and
4115
- * direct. Default for Clear Professional; works for any modern brand voice.
4116
- */
4117
- const confidentChip = defineButtonPersonality({
4118
- id: "confident-chip",
4119
- name: "Confident Chip",
4120
- description: "Mid-radius solid buttons with a crisp hover.",
3988
+ //#region ../theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.ts
3989
+ const emptyParametersSchema = z$1.object({}).strict();
3990
+ function defineStaticButtonStyleRecipe(input) {
3991
+ const system = normalizeSystem(input.system);
3992
+ return defineButtonStyleRecipe({
3993
+ id: input.id,
3994
+ accessibilityLabel: input.accessibilityLabel,
3995
+ tags: input.tags,
3996
+ parameterSchema: emptyParametersSchema,
3997
+ defaultParameters: {},
3998
+ controls: [],
3999
+ defineSystem: () => system
4000
+ });
4001
+ }
4002
+ function normalizeSystem(input) {
4003
+ return {
4004
+ global: buttonGlobalSettingsSchema.parse(input.global),
4005
+ ...input.sizes ? { sizes: input.sizes } : {},
4006
+ roles: {
4007
+ primary: normalizeCompleteRole(input.roles.primary),
4008
+ secondary: normalizeCompleteRole(input.roles.secondary),
4009
+ outline: normalizeSupportingRole(input.roles.outline),
4010
+ ghost: normalizeSupportingRole(input.roles.ghost),
4011
+ accent: normalizeSupportingRole(input.roles.accent)
4012
+ }
4013
+ };
4014
+ }
4015
+ function normalizeCompleteRole(role) {
4016
+ return {
4017
+ kind: "complete",
4018
+ appearance: normalizeAppearance(role.appearance)
4019
+ };
4020
+ }
4021
+ function normalizeSupportingRole(role) {
4022
+ if (role.kind === "complete") return normalizeCompleteRole(role);
4023
+ return {
4024
+ kind: "derive",
4025
+ from: role.from,
4026
+ ...role.overrides ? { overrides: normalizeAppearanceOverrides(role.overrides) } : {}
4027
+ };
4028
+ }
4029
+ function normalizeAppearance(appearance) {
4030
+ const { background, hoverBackgroundToken, ...rest } = appearance;
4031
+ return {
4032
+ ...rest,
4033
+ background: buttonColourTreatmentSchema.parse(background),
4034
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
4035
+ };
4036
+ }
4037
+ function normalizeAppearanceOverrides(overrides) {
4038
+ const { background, hoverBackgroundToken, ...rest } = overrides;
4039
+ return {
4040
+ ...rest,
4041
+ ...background ? { background: buttonColourTreatmentSchema.parse(background) } : {},
4042
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
4043
+ };
4044
+ }
4045
+ //#endregion
4046
+ //#region ../theme-core/src/buttons/styles/recipes/staticRecipes.ts
4047
+ const softPillRecipe = defineStaticButtonStyleRecipe({
4048
+ id: "soft-pill",
4049
+ accessibilityLabel: "Rounded pill buttons with a gentle hover lift",
4121
4050
  tags: {
4122
4051
  tone: "classic",
4123
4052
  energy: "calm",
4124
- motion: "standard",
4125
- era: "modern"
4053
+ motion: "subtle",
4054
+ era: "organic"
4126
4055
  },
4127
- buttonSystem: {
4056
+ system: {
4128
4057
  global: {
4129
- cornerStyle: "rounded",
4130
- shadow: "medium",
4058
+ cornerStyle: "pill",
4059
+ shadow: "low",
4131
4060
  textTransform: "none",
4132
- fontWeight: 600,
4133
- borderWidth: 1,
4134
- hoverTransform: "none",
4061
+ fontWeight: 500,
4062
+ hoverTransform: "lift",
4135
4063
  hoverColor: "none"
4136
4064
  },
4137
- variants: [
4138
- {
4139
- id: "primary",
4140
- name: "Primary",
4141
- enabled: true,
4142
- priority: 1,
4143
- background: {
4144
- type: "solid",
4145
- colorToken: "primary"
4146
- },
4147
- borderRadius: "rounded-md",
4148
- shadow: {
4149
- elevation: "medium",
4150
- softness: "soft",
4151
- position: "bottom"
4152
- },
4153
- effects: {
4154
- hover: [{
4155
- effectId: "darken-background",
4156
- options: { amount: 100 }
4157
- }],
4158
- active: [{
4159
- effectId: "scale-down",
4160
- options: { scale: "0.97" }
4161
- }]
4065
+ roles: {
4066
+ primary: {
4067
+ kind: "complete",
4068
+ appearance: {
4069
+ background: {
4070
+ type: "solid",
4071
+ colorToken: "primary"
4072
+ },
4073
+ borderRadius: "rounded-full",
4074
+ shadow: {
4075
+ elevation: "low",
4076
+ softness: "soft",
4077
+ position: "bottom"
4078
+ },
4079
+ effects: {
4080
+ hover: [{ effectId: "lift" }],
4081
+ active: [{
4082
+ effectId: "scale-down",
4083
+ options: { scale: "0.98" }
4084
+ }]
4085
+ }
4162
4086
  }
4163
4087
  },
4164
- {
4165
- id: "secondary",
4166
- name: "Secondary",
4167
- enabled: true,
4168
- priority: 2,
4169
- background: {
4170
- type: "solid",
4171
- colorToken: "surface"
4172
- },
4173
- borderRadius: "rounded-md",
4174
- border: { widthClass: "border" },
4175
- effects: { hover: [{
4176
- effectId: "background-on-hover",
4177
- options: { colorToken: "background" }
4178
- }] }
4088
+ secondary: {
4089
+ kind: "complete",
4090
+ appearance: {
4091
+ background: {
4092
+ type: "surface",
4093
+ role: "link"
4094
+ },
4095
+ borderRadius: "rounded-full",
4096
+ border: { widthClass: "border-2" },
4097
+ effects: { hover: [{
4098
+ effectId: "background-on-hover",
4099
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4100
+ }] }
4101
+ }
4179
4102
  },
4180
- {
4181
- id: "outline",
4182
- name: "Outline",
4183
- enabled: true,
4184
- priority: 3,
4185
- background: {
4186
- type: "surface",
4187
- role: "link"
4188
- },
4189
- borderRadius: "rounded-md",
4190
- border: { widthClass: "border" },
4191
- effects: { hover: [{
4192
- effectId: "background-on-hover",
4193
- options: { colorToken: "surface" }
4194
- }] }
4103
+ outline: {
4104
+ kind: "complete",
4105
+ appearance: {
4106
+ background: {
4107
+ type: "surface",
4108
+ role: "link"
4109
+ },
4110
+ borderRadius: "rounded-full",
4111
+ border: { widthClass: "border" },
4112
+ effects: { hover: [{
4113
+ effectId: "background-on-hover",
4114
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4115
+ }] }
4116
+ }
4195
4117
  },
4196
- {
4197
- id: "ghost",
4198
- name: "Ghost",
4199
- enabled: true,
4200
- priority: 3,
4201
- background: {
4202
- type: "surface",
4203
- role: "link"
4204
- },
4205
- borderRadius: "rounded-md",
4206
- effects: { hover: [{
4207
- effectId: "background-on-hover",
4208
- options: { colorToken: "surface" }
4209
- }] }
4118
+ ghost: {
4119
+ kind: "complete",
4120
+ appearance: {
4121
+ background: {
4122
+ type: "surface",
4123
+ role: "link"
4124
+ },
4125
+ borderRadius: "rounded-full",
4126
+ effects: { hover: [{
4127
+ effectId: "background-on-hover",
4128
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4129
+ }] }
4130
+ }
4131
+ },
4132
+ accent: {
4133
+ kind: "derive",
4134
+ from: "primary",
4135
+ overrides: { background: {
4136
+ type: "solid",
4137
+ colorToken: "accent"
4138
+ } }
4210
4139
  }
4211
- ]
4140
+ }
4212
4141
  }
4213
4142
  });
4214
- //#endregion
4215
- //#region ../theme-core/src/buttons/personalities/earth-pill.ts
4216
- /**
4217
- * Earth Pill - warm studio pills with compact, primary-coloured ghost CTAs.
4218
- * Built for grounded editorial wellness styles such as Soft Earth.
4219
- */
4220
- const earthPill = defineButtonPersonality({
4143
+ const earthPillRecipe = defineStaticButtonStyleRecipe({
4221
4144
  id: "earth-pill",
4222
- name: "Earth Pill",
4223
- description: "Compact terracotta pills with quiet primary-coloured ghost CTAs.",
4145
+ accessibilityLabel: "Compact rounded buttons with a quiet hover lift",
4224
4146
  tags: {
4225
4147
  tone: "classic",
4226
4148
  energy: "calm",
4227
4149
  motion: "subtle",
4228
4150
  era: "organic"
4229
4151
  },
4230
- buttonSystem: {
4152
+ system: {
4231
4153
  global: {
4232
4154
  cornerStyle: "pill",
4233
4155
  shadow: "low",
4234
4156
  textTransform: "none",
4235
4157
  fontWeight: 500,
4236
- borderWidth: 1,
4237
4158
  hoverTransform: "lift",
4238
4159
  hoverColor: "none",
4239
4160
  typography: "body",
@@ -4254,948 +4175,786 @@ const earthPill = defineButtonPersonality({
4254
4175
  fontSize: "text-xl"
4255
4176
  }
4256
4177
  },
4257
- variants: [
4258
- {
4259
- id: "primary",
4260
- name: "Primary",
4261
- enabled: true,
4262
- priority: 1,
4263
- background: {
4264
- type: "solid",
4265
- colorToken: "primary"
4266
- },
4267
- borderRadius: "rounded-full",
4268
- shadow: {
4269
- elevation: "low",
4270
- softness: "soft",
4271
- position: "bottom"
4272
- },
4273
- effects: {
4274
- hover: [{
4275
- effectId: "lift",
4276
- options: { translateY: "-1px" }
4277
- }, {
4278
- effectId: "background-on-hover",
4279
- options: { colorToken: "accent" }
4280
- }],
4281
- active: [{
4282
- effectId: "scale-down",
4283
- options: { scale: "0.98" }
4284
- }]
4178
+ roles: {
4179
+ primary: {
4180
+ kind: "complete",
4181
+ appearance: {
4182
+ background: {
4183
+ type: "solid",
4184
+ colorToken: "primary"
4185
+ },
4186
+ borderRadius: "rounded-full",
4187
+ shadow: {
4188
+ elevation: "low",
4189
+ softness: "soft",
4190
+ position: "bottom"
4191
+ },
4192
+ effects: {
4193
+ hover: [{ effectId: "lift" }, {
4194
+ effectId: "background-on-hover",
4195
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
4196
+ }],
4197
+ active: [{
4198
+ effectId: "scale-down",
4199
+ options: { scale: "0.98" }
4200
+ }]
4201
+ }
4285
4202
  }
4286
4203
  },
4287
- {
4288
- id: "secondary",
4289
- name: "Secondary",
4290
- enabled: true,
4291
- priority: 2,
4292
- background: {
4293
- type: "surface",
4294
- role: "link"
4295
- },
4296
- borderRadius: "rounded-full",
4297
- border: { widthClass: "border" },
4298
- effects: { hover: [{
4299
- effectId: "background-on-hover",
4300
- options: { colorToken: "muted" }
4301
- }] }
4204
+ secondary: {
4205
+ kind: "complete",
4206
+ appearance: {
4207
+ background: {
4208
+ type: "surface",
4209
+ role: "link"
4210
+ },
4211
+ borderRadius: "rounded-full",
4212
+ border: { widthClass: "border" },
4213
+ effects: { hover: [{
4214
+ effectId: "background-on-hover",
4215
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
4216
+ }] }
4217
+ }
4302
4218
  },
4303
- {
4304
- id: "outline",
4305
- name: "Outline",
4306
- enabled: true,
4307
- priority: 3,
4308
- background: {
4309
- type: "surface",
4310
- role: "link"
4311
- },
4312
- borderRadius: "rounded-full",
4313
- border: { widthClass: "border" },
4314
- effects: { hover: [{
4315
- effectId: "background-on-hover",
4316
- options: { colorToken: "surfaceAlt" }
4317
- }] }
4219
+ outline: {
4220
+ kind: "complete",
4221
+ appearance: {
4222
+ background: {
4223
+ type: "surface",
4224
+ role: "link"
4225
+ },
4226
+ borderRadius: "rounded-full",
4227
+ border: { widthClass: "border" },
4228
+ effects: { hover: [{
4229
+ effectId: "background-on-hover",
4230
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
4231
+ }] }
4232
+ }
4318
4233
  },
4319
- {
4320
- id: "ghost",
4321
- name: "Ghost",
4322
- enabled: true,
4323
- priority: 3,
4324
- background: {
4325
- type: "surface",
4326
- role: "link"
4327
- },
4328
- borderRadius: "rounded-full",
4329
- shadow: {
4330
- elevation: "none",
4331
- softness: null,
4332
- position: "bottom"
4333
- },
4334
- sizes: {
4335
- sm: {
4336
- padding: "0.25rem 0",
4337
- fontSize: "text-sm"
4234
+ ghost: {
4235
+ kind: "complete",
4236
+ appearance: {
4237
+ background: {
4238
+ type: "surface",
4239
+ role: "link"
4338
4240
  },
4339
- md: { padding: "0.375rem 0" },
4340
- lg: {
4341
- padding: "0.5rem 0",
4342
- fontSize: "text-lg"
4241
+ borderRadius: "rounded-full",
4242
+ shadow: {
4243
+ elevation: "none",
4244
+ softness: null,
4245
+ position: "bottom"
4343
4246
  },
4344
- xl: {
4345
- padding: "0.625rem 0",
4346
- fontSize: "text-xl"
4247
+ sizes: {
4248
+ sm: {
4249
+ padding: "0.25rem 0",
4250
+ fontSize: "text-sm"
4251
+ },
4252
+ md: { padding: "0.375rem 0" },
4253
+ lg: {
4254
+ padding: "0.5rem 0",
4255
+ fontSize: "text-lg"
4256
+ },
4257
+ xl: {
4258
+ padding: "0.625rem 0",
4259
+ fontSize: "text-xl"
4260
+ }
4347
4261
  }
4348
4262
  }
4263
+ },
4264
+ accent: {
4265
+ kind: "derive",
4266
+ from: "primary",
4267
+ overrides: { background: {
4268
+ type: "solid",
4269
+ colorToken: "accent"
4270
+ } }
4349
4271
  }
4350
- ]
4272
+ }
4351
4273
  }
4352
4274
  });
4353
- //#endregion
4354
- //#region ../theme-core/src/buttons/personalities/editorial-link.ts
4355
- /**
4356
- * Editorial Link — all variants are link-style with a growing underline.
4357
- * Default for Warm Editorial and Quiet Luxury; reads as refined and quiet.
4358
- */
4359
- const editorialLink = defineButtonPersonality({
4360
- id: "editorial-link",
4361
- name: "Editorial Link",
4362
- description: "Link-style with a growing underline. Refined, typographic.",
4275
+ const confidentChipRecipe = defineStaticButtonStyleRecipe({
4276
+ id: "confident-chip",
4277
+ accessibilityLabel: "Moderately rounded solid buttons with a crisp hover",
4363
4278
  tags: {
4364
- tone: "minimal",
4279
+ tone: "classic",
4365
4280
  energy: "calm",
4366
- motion: "subtle",
4367
- era: "editorial"
4281
+ motion: "standard",
4282
+ era: "modern"
4368
4283
  },
4369
- buttonSystem: {
4284
+ system: {
4370
4285
  global: {
4371
- cornerStyle: "square",
4286
+ cornerStyle: "rounded",
4287
+ shadow: "medium",
4372
4288
  textTransform: "none",
4373
- fontWeight: 500,
4374
- borderWidth: 1,
4289
+ fontWeight: 600,
4375
4290
  hoverTransform: "none",
4376
4291
  hoverColor: "none"
4377
4292
  },
4378
- variants: [
4379
- {
4380
- id: "primary",
4381
- name: "Primary",
4382
- enabled: true,
4383
- priority: 1,
4384
- background: {
4385
- type: "surface",
4386
- role: "link"
4387
- },
4388
- borderRadius: "rounded-none",
4389
- sizes: {
4390
- sm: { padding: "0.25rem 0" },
4391
- md: { padding: "0.5rem 0" },
4392
- lg: { padding: "0.625rem 0" },
4393
- xl: { padding: "0.75rem 0" }
4394
- },
4395
- effects: { base: [{
4396
- effectId: "border-bottom-grow",
4397
- options: {
4398
- height: 2,
4399
- colorToken: "text",
4400
- origin: "left"
4293
+ roles: {
4294
+ primary: {
4295
+ kind: "complete",
4296
+ appearance: {
4297
+ background: {
4298
+ type: "solid",
4299
+ colorToken: "primary"
4300
+ },
4301
+ borderRadius: "rounded-md",
4302
+ shadow: {
4303
+ elevation: "medium",
4304
+ softness: "soft",
4305
+ position: "bottom"
4306
+ },
4307
+ effects: {
4308
+ hover: [{
4309
+ effectId: "darken-background",
4310
+ options: { amount: 100 }
4311
+ }],
4312
+ active: [{
4313
+ effectId: "scale-down",
4314
+ options: { scale: "0.97" }
4315
+ }]
4401
4316
  }
4402
- }] }
4317
+ }
4403
4318
  },
4404
- {
4405
- id: "secondary",
4406
- name: "Secondary",
4407
- enabled: true,
4408
- priority: 2,
4409
- background: {
4410
- type: "surface",
4411
- role: "link"
4412
- },
4413
- borderRadius: "rounded-none",
4414
- sizes: {
4415
- sm: { padding: "0.25rem 0" },
4416
- md: { padding: "0.5rem 0" },
4417
- lg: { padding: "0.625rem 0" },
4418
- xl: { padding: "0.75rem 0" }
4419
- },
4420
- effects: { base: [{
4421
- effectId: "border-bottom-grow",
4422
- options: {
4423
- height: 1,
4424
- colorToken: "mutedText",
4425
- origin: "left"
4426
- }
4427
- }] }
4319
+ secondary: {
4320
+ kind: "complete",
4321
+ appearance: {
4322
+ background: {
4323
+ type: "solid",
4324
+ colorToken: "surface"
4325
+ },
4326
+ borderRadius: "rounded-md",
4327
+ border: { widthClass: "border" },
4328
+ effects: { hover: [{
4329
+ effectId: "background-on-hover",
4330
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
4331
+ }] }
4332
+ }
4428
4333
  },
4429
- {
4430
- id: "outline",
4431
- name: "Outline",
4432
- enabled: true,
4433
- priority: 3,
4434
- background: {
4435
- type: "surface",
4436
- role: "link"
4437
- },
4438
- borderRadius: "rounded-none",
4439
- sizes: {
4440
- sm: { padding: "0.25rem 0" },
4441
- md: { padding: "0.5rem 0" },
4442
- lg: { padding: "0.625rem 0" },
4443
- xl: { padding: "0.75rem 0" }
4444
- },
4445
- effects: { base: [{
4446
- effectId: "border-bottom-grow",
4447
- options: {
4448
- height: 1,
4449
- colorToken: "accent",
4450
- origin: "left"
4451
- }
4452
- }] }
4334
+ outline: {
4335
+ kind: "complete",
4336
+ appearance: {
4337
+ background: {
4338
+ type: "surface",
4339
+ role: "link"
4340
+ },
4341
+ borderRadius: "rounded-md",
4342
+ border: { widthClass: "border" },
4343
+ effects: { hover: [{
4344
+ effectId: "background-on-hover",
4345
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4346
+ }] }
4347
+ }
4453
4348
  },
4454
- {
4455
- id: "ghost",
4456
- name: "Ghost",
4457
- enabled: true,
4458
- priority: 3,
4459
- background: {
4460
- type: "surface",
4461
- role: "link"
4462
- },
4463
- borderRadius: "rounded-none",
4464
- sizes: {
4465
- sm: { padding: "0.25rem 0" },
4466
- md: { padding: "0.5rem 0" },
4467
- lg: { padding: "0.625rem 0" },
4468
- xl: { padding: "0.75rem 0" }
4349
+ ghost: {
4350
+ kind: "complete",
4351
+ appearance: {
4352
+ background: {
4353
+ type: "surface",
4354
+ role: "link"
4355
+ },
4356
+ borderRadius: "rounded-md",
4357
+ effects: { hover: [{
4358
+ effectId: "background-on-hover",
4359
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4360
+ }] }
4469
4361
  }
4362
+ },
4363
+ accent: {
4364
+ kind: "derive",
4365
+ from: "primary",
4366
+ overrides: { background: {
4367
+ type: "solid",
4368
+ colorToken: "accent"
4369
+ } }
4470
4370
  }
4471
- ]
4371
+ }
4472
4372
  }
4473
4373
  });
4474
- //#endregion
4475
- //#region ../theme-core/src/buttons/personalities/flat-ink.ts
4476
- /**
4477
- * Flat Ink — a solid ink primary, a hairline ghost secondary, and a single
4478
- * amber accent climax, all completely flat (no drop shadow) with a modest
4479
- * radius. Reads as grounded, editorial and clinician-precise: the Fulcrum
4480
- * physiotherapy voice. The primary shifts to the secondary (moss) on hover and
4481
- * every variant lifts 2px; the amber accent is meant to be used sparingly as
4482
- * the page's one conversion climax.
4483
- */
4484
- const flatInk = defineButtonPersonality({
4485
- id: "flat-ink",
4486
- name: "Flat Ink",
4487
- description: "Flat solid-ink primary, hairline ghost secondary, and a single amber accent climax — modest radius, no shadow.",
4374
+ const editorialSizes = {
4375
+ sm: { padding: "0.25rem 0" },
4376
+ md: { padding: "0.5rem 0" },
4377
+ lg: { padding: "0.625rem 0" },
4378
+ xl: { padding: "0.75rem 0" }
4379
+ };
4380
+ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
4381
+ id: "editorial-link",
4382
+ accessibilityLabel: "Flat typographic buttons with an underline treatment",
4488
4383
  tags: {
4489
- tone: "classic",
4384
+ tone: "minimal",
4490
4385
  energy: "calm",
4491
4386
  motion: "subtle",
4492
4387
  era: "editorial"
4493
4388
  },
4494
- buttonSystem: {
4389
+ system: {
4495
4390
  global: {
4496
- cornerStyle: "rounded",
4391
+ cornerStyle: "square",
4497
4392
  textTransform: "none",
4498
- fontWeight: 600,
4499
- borderWidth: 1,
4500
- typography: "body",
4501
- letterSpacing: "tight",
4502
- paddingPreset: "default",
4503
- hoverTransform: "lift",
4393
+ fontWeight: 500,
4394
+ hoverTransform: "none",
4504
4395
  hoverColor: "none"
4505
4396
  },
4506
- sizes: {
4507
- sm: {
4508
- padding: "0.625rem 1.125rem",
4509
- fontSize: "text-sm"
4397
+ roles: {
4398
+ primary: {
4399
+ kind: "complete",
4400
+ appearance: {
4401
+ background: {
4402
+ type: "surface",
4403
+ role: "link"
4404
+ },
4405
+ borderRadius: "rounded-none",
4406
+ sizes: editorialSizes,
4407
+ effects: { base: [{
4408
+ effectId: "border-bottom-grow",
4409
+ options: {
4410
+ height: 2,
4411
+ origin: "left"
4412
+ }
4413
+ }] }
4414
+ }
4510
4415
  },
4511
- md: { padding: "0.8125rem 1.375rem" },
4512
- lg: {
4513
- padding: "0.9375rem 1.625rem",
4514
- fontSize: "text-lg"
4416
+ secondary: {
4417
+ kind: "complete",
4418
+ appearance: {
4419
+ background: {
4420
+ type: "surface",
4421
+ role: "link"
4422
+ },
4423
+ borderRadius: "rounded-none",
4424
+ sizes: editorialSizes,
4425
+ effects: { base: [{
4426
+ effectId: "border-bottom-grow",
4427
+ options: {
4428
+ height: 1,
4429
+ origin: "left"
4430
+ }
4431
+ }] }
4432
+ }
4515
4433
  },
4516
- xl: {
4517
- padding: "1.0625rem 2rem",
4518
- fontSize: "text-xl"
4519
- }
4520
- },
4521
- variants: [
4522
- {
4523
- id: "primary",
4524
- name: "Primary",
4525
- enabled: true,
4526
- priority: 1,
4527
- background: {
4528
- type: "solid",
4529
- colorToken: "primary"
4530
- },
4531
- borderRadius: "rounded-lg",
4532
- affordance: { iconId: "ArrowRight" },
4533
- effects: { hover: [{
4534
- effectId: "lift",
4535
- options: { translateY: "-2px" }
4536
- }, {
4537
- effectId: "background-on-hover",
4538
- options: { colorToken: "secondary" }
4539
- }] }
4434
+ outline: {
4435
+ kind: "complete",
4436
+ appearance: {
4437
+ background: {
4438
+ type: "surface",
4439
+ role: "link"
4440
+ },
4441
+ borderRadius: "rounded-none",
4442
+ sizes: editorialSizes,
4443
+ effects: { base: [{
4444
+ effectId: "border-bottom-grow",
4445
+ options: {
4446
+ height: 1,
4447
+ origin: "left"
4448
+ }
4449
+ }] }
4450
+ }
4540
4451
  },
4541
- {
4542
- id: "secondary",
4543
- name: "Secondary",
4544
- enabled: true,
4545
- priority: 2,
4546
- background: {
4547
- type: "surface",
4548
- role: "link"
4549
- },
4550
- borderRadius: "rounded-lg",
4551
- border: { widthClass: "border" },
4552
- effects: { hover: [{
4553
- effectId: "lift",
4554
- options: { translateY: "-2px" }
4555
- }, {
4556
- effectId: "background-on-hover",
4557
- options: { colorToken: "surfaceAlt" }
4558
- }] }
4452
+ ghost: {
4453
+ kind: "complete",
4454
+ appearance: {
4455
+ background: {
4456
+ type: "surface",
4457
+ role: "link"
4458
+ },
4459
+ borderRadius: "rounded-none",
4460
+ sizes: editorialSizes
4461
+ }
4559
4462
  },
4560
- {
4561
- id: "accent",
4562
- name: "Accent",
4563
- enabled: true,
4564
- priority: 3,
4565
- background: {
4566
- type: "solid",
4567
- colorToken: "accent"
4568
- },
4569
- borderRadius: "rounded-lg",
4570
- affordance: { iconId: "ArrowRight" },
4571
- effects: { hover: [{
4572
- effectId: "lift",
4573
- options: { translateY: "-2px" }
4574
- }] }
4463
+ accent: {
4464
+ kind: "derive",
4465
+ from: "primary",
4466
+ overrides: { effects: { base: [{
4467
+ effectId: "border-bottom-grow",
4468
+ options: {
4469
+ height: 2,
4470
+ origin: "left"
4471
+ }
4472
+ }] } }
4575
4473
  }
4576
- ]
4474
+ }
4577
4475
  }
4578
4476
  });
4579
- //#endregion
4580
- //#region ../theme-core/src/buttons/personalities/ink-stamp.ts
4581
- /**
4582
- * Ink Stamp — solid earthy fills with a bordered, hand-stamped block-print
4583
- * feel. Reads as bold and handmade; suits expressive craft brands.
4584
- */
4585
- const inkStamp = defineButtonPersonality({
4586
- id: "ink-stamp",
4587
- name: "Ink Stamp",
4588
- description: "Hand-stamped block-print buttons with a slight lift on hover.",
4477
+ const pebbleRecipe = defineStaticButtonStyleRecipe({
4478
+ id: "pebble",
4479
+ accessibilityLabel: "Generously padded pill buttons",
4589
4480
  tags: {
4590
- tone: "bold",
4591
- energy: "vibrant",
4481
+ tone: "classic",
4482
+ energy: "calm",
4592
4483
  motion: "standard",
4593
4484
  era: "organic"
4594
4485
  },
4595
- buttonSystem: {
4486
+ system: {
4596
4487
  global: {
4597
- cornerStyle: "rounded",
4598
- textTransform: "uppercase",
4599
- fontWeight: 600,
4600
- borderWidth: 1,
4488
+ cornerStyle: "pill",
4489
+ textTransform: "none",
4490
+ fontWeight: 500,
4601
4491
  hoverTransform: "none",
4602
- hoverColor: "none",
4603
- letterSpacing: "loose"
4492
+ hoverColor: "none"
4604
4493
  },
4605
4494
  sizes: {
4606
4495
  sm: {
4607
- padding: "0.5rem 1.25rem",
4608
- fontSize: "text-xs"
4609
- },
4610
- md: {
4611
- padding: "0.75rem 1.75rem",
4496
+ padding: "0.625rem 1.75rem",
4612
4497
  fontSize: "text-sm"
4613
4498
  },
4499
+ md: { padding: "0.875rem 2.25rem" },
4614
4500
  lg: {
4615
- padding: "0.875rem 2.25rem",
4616
- fontSize: "text-base"
4617
- },
4618
- xl: {
4619
4501
  padding: "1.125rem 2.75rem",
4620
4502
  fontSize: "text-lg"
4503
+ },
4504
+ xl: {
4505
+ padding: "1.5rem 3.5rem",
4506
+ fontSize: "text-xl"
4621
4507
  }
4622
4508
  },
4623
- variants: [
4624
- {
4625
- id: "primary",
4626
- name: "Primary",
4627
- enabled: true,
4628
- priority: 1,
4629
- background: {
4630
- type: "solid",
4631
- colorToken: "primary"
4632
- },
4633
- borderRadius: "rounded-md",
4634
- effects: {
4635
- hover: [{
4636
- effectId: "drop-shadow",
4637
- options: { intensity: "medium" }
4638
- }, {
4639
- effectId: "scale-up",
4640
- options: { scale: "1.02" }
4641
- }],
4642
- active: [{
4643
- effectId: "scale-down",
4644
- options: { scale: "0.98" }
4645
- }]
4509
+ roles: {
4510
+ primary: {
4511
+ kind: "complete",
4512
+ appearance: {
4513
+ background: {
4514
+ type: "solid",
4515
+ colorToken: "primary"
4516
+ },
4517
+ borderRadius: "rounded-full",
4518
+ effects: { hover: [{
4519
+ effectId: "darken-background",
4520
+ options: { amount: 100 }
4521
+ }] }
4646
4522
  }
4647
4523
  },
4648
- {
4649
- id: "secondary",
4650
- name: "Secondary",
4651
- enabled: true,
4652
- priority: 2,
4653
- background: {
4654
- type: "surface",
4655
- role: "link"
4656
- },
4657
- borderRadius: "rounded-md",
4658
- border: { widthClass: "border-2" },
4659
- effects: { hover: [{
4660
- effectId: "background-on-hover",
4661
- options: { colorToken: "surface" }
4662
- }] }
4663
- },
4664
- {
4665
- id: "outline",
4666
- name: "Outline",
4667
- enabled: true,
4668
- priority: 3,
4669
- background: {
4670
- type: "surface",
4671
- role: "link"
4672
- },
4673
- borderRadius: "rounded-md",
4674
- border: { widthClass: "border-2" },
4675
- effects: { hover: [{
4676
- effectId: "background-on-hover",
4677
- options: { colorToken: "surface" }
4678
- }] }
4679
- },
4680
- {
4681
- id: "ghost",
4682
- name: "Ghost",
4683
- enabled: true,
4684
- priority: 3,
4685
- background: {
4686
- type: "surface",
4687
- role: "link"
4688
- },
4689
- borderRadius: "rounded-none",
4690
- sizes: {
4691
- sm: {
4692
- padding: "0.375rem 0",
4693
- fontSize: "text-xs"
4524
+ secondary: {
4525
+ kind: "complete",
4526
+ appearance: {
4527
+ background: {
4528
+ type: "surface",
4529
+ role: "link"
4694
4530
  },
4695
- md: {
4696
- padding: "0.5rem 0",
4697
- fontSize: "text-sm"
4531
+ borderRadius: "rounded-full",
4532
+ border: { widthClass: "border-2" },
4533
+ effects: { hover: [{
4534
+ effectId: "background-on-hover",
4535
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
4536
+ }] }
4537
+ }
4538
+ },
4539
+ outline: {
4540
+ kind: "complete",
4541
+ appearance: {
4542
+ background: {
4543
+ type: "surface",
4544
+ role: "link"
4698
4545
  },
4699
- lg: {
4700
- padding: "0.625rem 0",
4701
- fontSize: "text-base"
4546
+ borderRadius: "rounded-full",
4547
+ border: { widthClass: "border" },
4548
+ effects: { hover: [{
4549
+ effectId: "background-on-hover",
4550
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4551
+ }] }
4552
+ }
4553
+ },
4554
+ ghost: {
4555
+ kind: "complete",
4556
+ appearance: {
4557
+ background: {
4558
+ type: "surface",
4559
+ role: "link"
4702
4560
  },
4703
- xl: {
4704
- padding: "0.75rem 0",
4705
- fontSize: "text-lg"
4706
- }
4707
- },
4708
- effects: { base: [{
4709
- effectId: "border-bottom-grow",
4710
- options: {
4711
- height: 1,
4712
- colorToken: "accent",
4713
- origin: "left"
4561
+ borderRadius: "rounded-full",
4562
+ sizes: {
4563
+ sm: {
4564
+ padding: "0.375rem 0.875rem",
4565
+ fontSize: "text-sm"
4566
+ },
4567
+ md: { padding: "0.5rem 1rem" },
4568
+ lg: {
4569
+ padding: "0.625rem 1.25rem",
4570
+ fontSize: "text-lg"
4571
+ },
4572
+ xl: {
4573
+ padding: "0.75rem 1.5rem",
4574
+ fontSize: "text-xl"
4575
+ }
4714
4576
  }
4715
- }] }
4577
+ }
4578
+ },
4579
+ accent: {
4580
+ kind: "derive",
4581
+ from: "primary",
4582
+ overrides: { background: {
4583
+ type: "solid",
4584
+ colorToken: "accent"
4585
+ } }
4716
4586
  }
4717
- ]
4587
+ }
4718
4588
  }
4719
4589
  });
4720
- //#endregion
4721
- //#region ../theme-core/src/buttons/personalities/joy-stamp.ts
4722
- /**
4723
- * Joy Stamp — neo-brutalist pills with a hard, brand-coloured offset shadow
4724
- * that collapses as the button presses into it on hover. Authored for the
4725
- * Original Joy site style: a cream "stamp" shadow under the solid primary, and
4726
- * a brown shadow under the cream outline. Reads as bold, warm, and handmade.
4727
- *
4728
- * The coloured offset shadow relies on the per-variant `shadow.colorToken`
4729
- * extension; the press is the shared `press-down` effect, which matches its
4730
- * translate to each variant's own shadow offset.
4731
- */
4732
- const joyStamp = defineButtonPersonality({
4733
- id: "joy-stamp",
4734
- name: "Joy Stamp",
4735
- description: "Pill buttons with a hard, brand-coloured offset shadow that presses in on hover.",
4590
+ const brushedWashRecipe = defineStaticButtonStyleRecipe({
4591
+ id: "brushed-wash",
4592
+ accessibilityLabel: "Generously padded gradient buttons with soft shadows",
4736
4593
  tags: {
4737
- tone: "bold",
4594
+ tone: "classic",
4738
4595
  energy: "vibrant",
4739
- motion: "expressive",
4596
+ motion: "standard",
4740
4597
  era: "organic"
4741
4598
  },
4742
- buttonSystem: {
4599
+ system: {
4743
4600
  global: {
4744
- cornerStyle: "pill",
4745
- shadow: "high",
4601
+ cornerStyle: "rounded",
4602
+ shadow: "low",
4746
4603
  textTransform: "none",
4747
- typography: "heading",
4748
- fontWeight: 700,
4749
- fontSize: "text-lg",
4750
- borderWidth: 2,
4604
+ fontWeight: 500,
4751
4605
  hoverTransform: "none",
4752
4606
  hoverColor: "none"
4753
4607
  },
4754
4608
  sizes: {
4755
4609
  sm: {
4756
- padding: "0.625rem 1.25rem",
4757
- fontSize: "text-base"
4758
- },
4759
- md: {
4760
- padding: "0.875rem 1.75rem",
4761
- fontSize: "text-lg"
4610
+ padding: "0.75rem 2rem",
4611
+ fontSize: "text-sm"
4762
4612
  },
4613
+ md: { padding: "1rem 2.5rem" },
4763
4614
  lg: {
4764
- padding: "1.125rem 2.25rem",
4765
- fontSize: "text-xl"
4615
+ padding: "1.25rem 3rem",
4616
+ fontSize: "text-lg"
4766
4617
  },
4767
4618
  xl: {
4768
- padding: "1.25rem 2.75rem",
4769
- fontSize: "text-2xl"
4619
+ padding: "1.625rem 3.75rem",
4620
+ fontSize: "text-xl"
4770
4621
  }
4771
4622
  },
4772
- variants: [{
4773
- id: "primary",
4774
- name: "Primary",
4775
- enabled: true,
4776
- priority: 1,
4777
- background: {
4778
- type: "solid",
4779
- colorToken: "primary"
4623
+ roles: {
4624
+ primary: {
4625
+ kind: "complete",
4626
+ appearance: {
4627
+ background: {
4628
+ type: "gradient",
4629
+ stops: ["primary", "accent"],
4630
+ direction: "to-r",
4631
+ foregroundToken: "primaryForeground"
4632
+ },
4633
+ borderRadius: "rounded-lg",
4634
+ shadow: {
4635
+ elevation: "low",
4636
+ softness: "soft",
4637
+ position: "bottom"
4638
+ }
4639
+ }
4780
4640
  },
4781
- borderRadius: "rounded-full",
4782
- shadow: {
4783
- elevation: "high",
4784
- softness: "hard",
4785
- position: "bottom-right",
4786
- colorToken: "text"
4641
+ secondary: {
4642
+ kind: "complete",
4643
+ appearance: {
4644
+ background: {
4645
+ type: "gradient",
4646
+ stops: ["secondary", "accent"],
4647
+ direction: "to-br",
4648
+ foregroundToken: "primaryForeground"
4649
+ },
4650
+ borderRadius: "rounded-lg",
4651
+ shadow: {
4652
+ elevation: "low",
4653
+ softness: "soft",
4654
+ position: "bottom"
4655
+ }
4656
+ }
4787
4657
  },
4788
- effects: { hover: [{ effectId: "press-down" }] }
4789
- }, {
4790
- id: "secondary",
4791
- name: "Secondary",
4792
- enabled: true,
4793
- priority: 2,
4794
- background: {
4795
- type: "surface",
4796
- role: "link"
4797
- },
4798
- borderRadius: "rounded-full",
4799
- border: { widthClass: "border-2" },
4800
- shadow: {
4801
- elevation: "high",
4802
- softness: "hard",
4803
- position: "bottom-right",
4804
- colorToken: "secondary"
4805
- },
4806
- effects: { hover: [{ effectId: "press-down" }] }
4807
- }]
4658
+ outline: {
4659
+ kind: "complete",
4660
+ appearance: {
4661
+ background: {
4662
+ type: "surface",
4663
+ role: "link"
4664
+ },
4665
+ borderRadius: "rounded-lg",
4666
+ border: { widthClass: "border" },
4667
+ effects: { hover: [{
4668
+ effectId: "background-on-hover",
4669
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4670
+ }] }
4671
+ }
4672
+ },
4673
+ ghost: {
4674
+ kind: "complete",
4675
+ appearance: {
4676
+ background: {
4677
+ type: "surface",
4678
+ role: "link"
4679
+ },
4680
+ borderRadius: "rounded-lg",
4681
+ effects: { hover: [{
4682
+ effectId: "background-on-hover",
4683
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4684
+ }] }
4685
+ }
4686
+ },
4687
+ accent: {
4688
+ kind: "derive",
4689
+ from: "primary",
4690
+ overrides: { background: {
4691
+ type: "solid",
4692
+ colorToken: "accent"
4693
+ } }
4694
+ }
4695
+ }
4808
4696
  }
4809
4697
  });
4810
- //#endregion
4811
- //#region ../theme-core/src/buttons/personalities/ornate-ritual.ts
4812
- /**
4813
- * Ornate Ritual — framed, ceremonial buttons with jewel-toned fills and
4814
- * deliberate spacing. Designed for music, ceremony, and soulful event sites.
4815
- */
4816
- const ornateRitual = defineButtonPersonality({
4817
- id: "ornate-ritual",
4818
- name: "Ornate Ritual",
4819
- description: "Ceremonial framed buttons with jewel-toned fills and quiet color-change hover states.",
4698
+ const inkStampRecipe = defineStaticButtonStyleRecipe({
4699
+ id: "ink-stamp",
4700
+ accessibilityLabel: "Uppercase block-print buttons with a playful hover",
4820
4701
  tags: {
4821
- tone: "classic",
4702
+ tone: "bold",
4822
4703
  energy: "vibrant",
4823
- motion: "subtle",
4704
+ motion: "standard",
4824
4705
  era: "organic"
4825
4706
  },
4826
- buttonSystem: {
4707
+ system: {
4827
4708
  global: {
4828
4709
  cornerStyle: "rounded",
4829
4710
  textTransform: "uppercase",
4830
4711
  fontWeight: 600,
4831
- borderWidth: 1,
4832
4712
  hoverTransform: "none",
4833
4713
  hoverColor: "none",
4834
4714
  letterSpacing: "loose"
4835
4715
  },
4836
4716
  sizes: {
4837
4717
  sm: {
4838
- padding: "0.5625rem 1.25rem",
4718
+ padding: "0.5rem 1.25rem",
4839
4719
  fontSize: "text-xs"
4840
4720
  },
4841
4721
  md: {
4842
4722
  padding: "0.75rem 1.75rem",
4843
- fontSize: "text-xs"
4723
+ fontSize: "text-sm"
4844
4724
  },
4845
4725
  lg: {
4846
4726
  padding: "0.875rem 2.25rem",
4847
- fontSize: "text-sm"
4848
- },
4849
- xl: {
4850
- padding: "1rem 2.75rem",
4851
4727
  fontSize: "text-base"
4852
- }
4853
- },
4854
- variants: [
4855
- {
4856
- id: "primary",
4857
- name: "Primary",
4858
- enabled: true,
4859
- priority: 1,
4860
- background: {
4861
- type: "solid",
4862
- colorToken: "primary"
4863
- },
4864
- borderRadius: "rounded-md",
4865
- border: { widthClass: "border" },
4866
- effects: {
4867
- hover: [{
4868
- effectId: "background-on-hover",
4869
- options: { colorToken: "primary-100" }
4870
- }],
4871
- active: [{
4872
- effectId: "scale-down",
4873
- options: { scale: "0.98" }
4874
- }]
4875
- }
4876
- },
4877
- {
4878
- id: "secondary",
4879
- name: "Secondary",
4880
- enabled: true,
4881
- priority: 2,
4882
- background: {
4883
- type: "solid",
4884
- colorToken: "secondary"
4885
- },
4886
- borderRadius: "rounded-md",
4887
- border: { widthClass: "border" },
4888
- effects: { hover: [{
4889
- effectId: "background-on-hover",
4890
- options: { colorToken: "surface" }
4891
- }] }
4892
- },
4893
- {
4894
- id: "outline",
4895
- name: "Outline",
4896
- enabled: true,
4897
- priority: 3,
4898
- background: {
4899
- type: "surface",
4900
- role: "link"
4901
- },
4902
- borderRadius: "rounded-md",
4903
- border: { widthClass: "border" },
4904
- effects: { hover: [{
4905
- effectId: "background-on-hover",
4906
- options: { colorToken: "muted" }
4907
- }] }
4908
- },
4909
- {
4910
- id: "ghost",
4911
- name: "Ghost",
4912
- enabled: true,
4913
- priority: 3,
4914
- background: {
4915
- type: "surface",
4916
- role: "link"
4917
- },
4918
- borderRadius: "rounded-none",
4919
- sizes: {
4920
- sm: {
4921
- padding: "0.375rem 0",
4922
- fontSize: "text-xs"
4923
- },
4924
- md: {
4925
- padding: "0.5rem 0",
4926
- fontSize: "text-sm"
4927
- },
4928
- lg: {
4929
- padding: "0.625rem 0",
4930
- fontSize: "text-base"
4931
- },
4932
- xl: {
4933
- padding: "0.75rem 0",
4934
- fontSize: "text-lg"
4935
- }
4936
- },
4937
- effects: { base: [{
4938
- effectId: "border-bottom-grow",
4939
- options: {
4940
- height: 1,
4941
- colorToken: "accent",
4942
- origin: "left"
4943
- }
4944
- }] }
4945
- }
4946
- ]
4947
- }
4948
- });
4949
- //#endregion
4950
- //#region ../theme-core/src/buttons/personalities/pebble.ts
4951
- /**
4952
- * Pebble — large pill primaries with generous padding. Reads as spa-luxurious
4953
- * and natural; pairs well with wellness/yoga/dance brands.
4954
- */
4955
- const pebble = defineButtonPersonality({
4956
- id: "pebble",
4957
- name: "Pebble",
4958
- description: "Generous pill buttons with a quiet colour-softening hover.",
4959
- tags: {
4960
- tone: "classic",
4961
- energy: "calm",
4962
- motion: "standard",
4963
- era: "organic"
4964
- },
4965
- buttonSystem: {
4966
- global: {
4967
- cornerStyle: "pill",
4968
- textTransform: "none",
4969
- fontWeight: 500,
4970
- borderWidth: 2,
4971
- hoverTransform: "none",
4972
- hoverColor: "none"
4973
- },
4974
- sizes: {
4975
- sm: {
4976
- padding: "0.625rem 1.75rem",
4977
- fontSize: "text-sm"
4978
4728
  },
4979
- md: { padding: "0.875rem 2.25rem" },
4980
- lg: {
4729
+ xl: {
4981
4730
  padding: "1.125rem 2.75rem",
4982
4731
  fontSize: "text-lg"
4983
- },
4984
- xl: {
4985
- padding: "1.5rem 3.5rem",
4986
- fontSize: "text-xl"
4987
4732
  }
4988
4733
  },
4989
- variants: [
4990
- {
4991
- id: "primary",
4992
- name: "Primary",
4993
- enabled: true,
4994
- priority: 1,
4995
- background: {
4996
- type: "solid",
4997
- colorToken: "primary"
4998
- },
4999
- borderRadius: "rounded-full",
5000
- effects: { hover: [{
5001
- effectId: "darken-background",
5002
- options: { amount: 100 }
5003
- }] }
4734
+ roles: {
4735
+ primary: {
4736
+ kind: "complete",
4737
+ appearance: {
4738
+ background: {
4739
+ type: "solid",
4740
+ colorToken: "primary"
4741
+ },
4742
+ borderRadius: "rounded-md",
4743
+ effects: {
4744
+ hover: [{
4745
+ effectId: "drop-shadow",
4746
+ options: { intensity: "medium" }
4747
+ }, {
4748
+ effectId: "scale-up",
4749
+ options: { scale: "1.02" }
4750
+ }],
4751
+ active: [{
4752
+ effectId: "scale-down",
4753
+ options: { scale: "0.98" }
4754
+ }]
4755
+ }
4756
+ }
5004
4757
  },
5005
- {
5006
- id: "secondary",
5007
- name: "Secondary",
5008
- enabled: true,
5009
- priority: 2,
5010
- background: {
5011
- type: "surface",
5012
- role: "link"
5013
- },
5014
- borderRadius: "rounded-full",
5015
- border: { widthClass: "border-2" },
5016
- effects: { hover: [{
5017
- effectId: "background-on-hover",
5018
- options: { colorToken: "accent" }
5019
- }] }
4758
+ secondary: {
4759
+ kind: "complete",
4760
+ appearance: {
4761
+ background: {
4762
+ type: "surface",
4763
+ role: "link"
4764
+ },
4765
+ borderRadius: "rounded-md",
4766
+ border: { widthClass: "border-2" },
4767
+ effects: { hover: [{
4768
+ effectId: "background-on-hover",
4769
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4770
+ }] }
4771
+ }
5020
4772
  },
5021
- {
5022
- id: "outline",
5023
- name: "Outline",
5024
- enabled: true,
5025
- priority: 3,
5026
- background: {
5027
- type: "surface",
5028
- role: "link"
5029
- },
5030
- borderRadius: "rounded-full",
5031
- border: { widthClass: "border" },
5032
- effects: { hover: [{
5033
- effectId: "background-on-hover",
5034
- options: { colorToken: "surface" }
5035
- }] }
4773
+ outline: {
4774
+ kind: "complete",
4775
+ appearance: {
4776
+ background: {
4777
+ type: "surface",
4778
+ role: "link"
4779
+ },
4780
+ borderRadius: "rounded-md",
4781
+ border: { widthClass: "border-2" },
4782
+ effects: { hover: [{
4783
+ effectId: "background-on-hover",
4784
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
4785
+ }] }
4786
+ }
5036
4787
  },
5037
- {
5038
- id: "ghost",
5039
- name: "Ghost",
5040
- enabled: true,
5041
- priority: 3,
5042
- background: {
5043
- type: "surface",
5044
- role: "link"
5045
- },
5046
- borderRadius: "rounded-full",
5047
- sizes: {
5048
- sm: {
5049
- padding: "0.375rem 0.875rem",
5050
- fontSize: "text-sm"
4788
+ ghost: {
4789
+ kind: "complete",
4790
+ appearance: {
4791
+ background: {
4792
+ type: "surface",
4793
+ role: "link"
5051
4794
  },
5052
- md: { padding: "0.5rem 1rem" },
5053
- lg: {
5054
- padding: "0.625rem 1.25rem",
5055
- fontSize: "text-lg"
4795
+ borderRadius: "rounded-none",
4796
+ sizes: {
4797
+ sm: {
4798
+ padding: "0.375rem 0",
4799
+ fontSize: "text-xs"
4800
+ },
4801
+ md: {
4802
+ padding: "0.5rem 0",
4803
+ fontSize: "text-sm"
4804
+ },
4805
+ lg: {
4806
+ padding: "0.625rem 0",
4807
+ fontSize: "text-base"
4808
+ },
4809
+ xl: {
4810
+ padding: "0.75rem 0",
4811
+ fontSize: "text-lg"
4812
+ }
5056
4813
  },
5057
- xl: {
5058
- padding: "0.75rem 1.5rem",
5059
- fontSize: "text-xl"
5060
- }
4814
+ effects: { base: [{
4815
+ effectId: "border-bottom-grow",
4816
+ options: {
4817
+ height: 1,
4818
+ origin: "left"
4819
+ }
4820
+ }] }
5061
4821
  }
4822
+ },
4823
+ accent: {
4824
+ kind: "derive",
4825
+ from: "primary",
4826
+ overrides: { background: {
4827
+ type: "solid",
4828
+ colorToken: "accent"
4829
+ } }
5062
4830
  }
5063
- ]
4831
+ }
5064
4832
  }
5065
4833
  });
5066
- //#endregion
5067
- //#region ../theme-core/src/buttons/personalities/quiet-arrow.ts
5068
- /**
5069
- * Quiet Arrow — wide, flat editorial buttons for grounded service businesses.
5070
- * Primary and secondary keep stable semantic colours; surrounding surfaces are
5071
- * responsible for contrast rather than reversing the button roles.
5072
- */
5073
- const quietArrow = defineButtonPersonality({
5074
- id: "quiet-arrow",
5075
- name: "Quiet Arrow",
5076
- description: "Wide, flat arrow buttons with a solid primary and a primary-colour outlined secondary.",
4834
+ const flatInkRecipe = defineStaticButtonStyleRecipe({
4835
+ id: "flat-ink",
4836
+ accessibilityLabel: "Flat rounded buttons with arrow affordances",
5077
4837
  tags: {
5078
4838
  tone: "classic",
5079
4839
  energy: "calm",
5080
4840
  motion: "subtle",
5081
4841
  era: "editorial"
5082
4842
  },
5083
- buttonSystem: {
4843
+ system: {
5084
4844
  global: {
5085
4845
  cornerStyle: "rounded",
5086
- textTransform: "uppercase",
5087
- fontWeight: 500,
5088
- borderWidth: 1,
4846
+ textTransform: "none",
4847
+ fontWeight: 600,
5089
4848
  typography: "body",
5090
- fontSize: "text-sm",
5091
- letterSpacing: "loose",
5092
- hoverTransform: "none",
4849
+ letterSpacing: "tight",
4850
+ paddingPreset: "default",
4851
+ hoverTransform: "lift",
5093
4852
  hoverColor: "none"
5094
4853
  },
5095
4854
  sizes: {
5096
4855
  sm: {
5097
- padding: "0.625rem 1.25rem",
5098
- fontSize: "text-xs"
5099
- },
5100
- md: {
5101
- padding: "0.8125rem 1.75rem",
4856
+ padding: "0.625rem 1.125rem",
5102
4857
  fontSize: "text-sm"
5103
4858
  },
4859
+ md: { padding: "0.8125rem 1.375rem" },
5104
4860
  lg: {
5105
- padding: "0.9375rem 2.125rem",
5106
- fontSize: "text-sm"
4861
+ padding: "0.9375rem 1.625rem",
4862
+ fontSize: "text-lg"
5107
4863
  },
5108
4864
  xl: {
5109
- padding: "1.0625rem 2.5rem",
5110
- fontSize: "text-base"
4865
+ padding: "1.0625rem 2rem",
4866
+ fontSize: "text-xl"
5111
4867
  }
5112
4868
  },
5113
- variants: [
5114
- {
5115
- id: "primary",
5116
- name: "Primary",
5117
- enabled: true,
5118
- priority: 1,
5119
- background: {
5120
- type: "solid",
5121
- colorToken: "primary"
5122
- },
5123
- borderRadius: "rounded-xl",
5124
- affordance: { iconId: "ArrowRight" },
5125
- effects: { hover: [{
5126
- effectId: "darken-background",
5127
- options: { amount: 100 }
5128
- }] }
4869
+ roles: {
4870
+ primary: {
4871
+ kind: "complete",
4872
+ appearance: {
4873
+ background: {
4874
+ type: "solid",
4875
+ colorToken: "primary"
4876
+ },
4877
+ borderRadius: "rounded-lg",
4878
+ affordance: { iconId: "ArrowRight" },
4879
+ effects: { hover: [{ effectId: "lift" }, {
4880
+ effectId: "background-on-hover",
4881
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("secondary") }
4882
+ }] }
4883
+ }
5129
4884
  },
5130
- {
5131
- id: "secondary",
5132
- name: "Secondary",
5133
- enabled: true,
5134
- priority: 2,
5135
- background: {
5136
- type: "surface",
5137
- role: "link"
5138
- },
5139
- borderRadius: "rounded-xl",
5140
- border: { widthClass: "border" },
5141
- affordance: { iconId: "ArrowRight" },
5142
- effects: { hover: [{
5143
- effectId: "background-on-hover",
5144
- options: { colorToken: "surfaceAlt" }
5145
- }] }
4885
+ secondary: {
4886
+ kind: "complete",
4887
+ appearance: {
4888
+ background: {
4889
+ type: "surface",
4890
+ role: "link"
4891
+ },
4892
+ borderRadius: "rounded-lg",
4893
+ border: { widthClass: "border" },
4894
+ effects: { hover: [{ effectId: "lift" }, {
4895
+ effectId: "background-on-hover",
4896
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
4897
+ }] }
4898
+ }
5146
4899
  },
5147
- {
5148
- id: "outline",
5149
- name: "Outline",
5150
- enabled: true,
5151
- priority: 3,
5152
- background: {
5153
- type: "surface",
5154
- role: "link"
5155
- },
5156
- borderRadius: "rounded-xl",
5157
- border: { widthClass: "border" }
4900
+ outline: {
4901
+ kind: "complete",
4902
+ appearance: {
4903
+ background: {
4904
+ type: "surface",
4905
+ role: "link"
4906
+ },
4907
+ borderRadius: "rounded-lg",
4908
+ border: { widthClass: "border" },
4909
+ effects: { hover: [{ effectId: "lift" }, {
4910
+ effectId: "background-on-hover",
4911
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
4912
+ }] }
4913
+ }
5158
4914
  },
5159
- {
5160
- id: "ghost",
5161
- name: "Ghost",
5162
- enabled: true,
5163
- priority: 3,
5164
- background: {
5165
- type: "surface",
5166
- role: "link"
5167
- },
5168
- borderRadius: "rounded-xl"
4915
+ ghost: {
4916
+ kind: "complete",
4917
+ appearance: {
4918
+ background: {
4919
+ type: "surface",
4920
+ role: "link"
4921
+ },
4922
+ borderRadius: "rounded-lg",
4923
+ effects: { hover: [{ effectId: "lift" }] }
4924
+ }
4925
+ },
4926
+ accent: {
4927
+ kind: "complete",
4928
+ appearance: {
4929
+ background: {
4930
+ type: "solid",
4931
+ colorToken: "accent"
4932
+ },
4933
+ borderRadius: "rounded-lg",
4934
+ affordance: { iconId: "ArrowRight" },
4935
+ effects: { hover: [{ effectId: "lift" }] }
4936
+ }
5169
4937
  }
5170
- ]
4938
+ }
5171
4939
  }
5172
4940
  });
5173
- //#endregion
5174
- //#region ../theme-core/src/buttons/personalities/showtime-pill.ts
5175
- /**
5176
- * Showtime Pill — bold, spacious, fully rounded buttons with playful pop
5177
- * motion. Suits energetic schools, performers, festivals, and community brands
5178
- * that need calls to action to feel loud without becoming visually chaotic.
5179
- */
5180
- const showtimePill = defineButtonPersonality({
4941
+ const showtimePillRecipe = defineStaticButtonStyleRecipe({
5181
4942
  id: "showtime-pill",
5182
- name: "Showtime Pill",
5183
- description: "Bold pill buttons with uppercase labels, generous padding, and a playful pop.",
4943
+ accessibilityLabel: "Bold uppercase pill buttons with playful movement",
5184
4944
  tags: {
5185
4945
  tone: "bold",
5186
4946
  energy: "vibrant",
5187
4947
  motion: "expressive",
5188
4948
  era: "modern"
5189
4949
  },
5190
- buttonSystem: {
4950
+ system: {
5191
4951
  global: {
5192
4952
  cornerStyle: "pill",
5193
4953
  shadow: "low",
5194
4954
  textTransform: "uppercase",
5195
4955
  fontWeight: 700,
5196
- borderWidth: 2,
5197
4956
  hoverTransform: "lift",
5198
- hoverColor: "darken",
4957
+ hoverColor: "none",
5199
4958
  typography: "body",
5200
4959
  paddingPreset: "spacious",
5201
4960
  italic: false
@@ -5218,272 +4977,373 @@ const showtimePill = defineButtonPersonality({
5218
4977
  fontSize: "1.125rem"
5219
4978
  }
5220
4979
  },
5221
- variants: [
5222
- {
5223
- id: "primary",
5224
- name: "Primary",
5225
- enabled: true,
5226
- priority: 1,
5227
- background: {
5228
- type: "solid",
5229
- colorToken: "primary"
5230
- },
5231
- borderRadius: "rounded-full",
5232
- effects: { hover: [{ effectId: "pop" }] }
5233
- },
5234
- {
5235
- id: "secondary",
5236
- name: "Secondary",
5237
- enabled: true,
5238
- priority: 2,
5239
- background: {
5240
- type: "surface",
5241
- role: "link"
5242
- },
5243
- borderRadius: "rounded-full",
5244
- border: { widthClass: "border-2" },
5245
- effects: { hover: [{ effectId: "pop" }] }
4980
+ roles: {
4981
+ primary: {
4982
+ kind: "complete",
4983
+ appearance: {
4984
+ background: {
4985
+ type: "solid",
4986
+ colorToken: "primary"
4987
+ },
4988
+ borderRadius: "rounded-full",
4989
+ effects: { hover: [{ effectId: "pop" }] }
4990
+ }
5246
4991
  },
5247
- {
5248
- id: "hero",
5249
- name: "Hero",
5250
- enabled: true,
5251
- priority: 1,
5252
- background: {
5253
- type: "solid",
5254
- colorToken: "secondary"
5255
- },
5256
- borderRadius: "rounded-full",
5257
- effects: { hover: [{ effectId: "pop" }] }
4992
+ secondary: {
4993
+ kind: "complete",
4994
+ appearance: {
4995
+ background: {
4996
+ type: "surface",
4997
+ role: "link"
4998
+ },
4999
+ borderRadius: "rounded-full",
5000
+ border: { widthClass: "border-2" },
5001
+ effects: { hover: [{ effectId: "pop" }] }
5002
+ }
5258
5003
  },
5259
- {
5260
- id: "header",
5261
- name: "Header",
5262
- enabled: true,
5263
- priority: 2,
5264
- background: {
5265
- type: "solid",
5266
- colorToken: "background"
5267
- },
5268
- borderRadius: "rounded-full",
5269
- border: { widthClass: "border-2" },
5270
- effects: { hover: [{
5271
- effectId: "background-on-hover",
5272
- options: { colorToken: "surface" }
5273
- }] }
5004
+ outline: {
5005
+ kind: "complete",
5006
+ appearance: {
5007
+ background: {
5008
+ type: "surface",
5009
+ role: "link"
5010
+ },
5011
+ borderRadius: "rounded-full",
5012
+ border: { widthClass: "border-2" },
5013
+ effects: { hover: [{
5014
+ effectId: "background-on-hover",
5015
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
5016
+ }] }
5017
+ }
5274
5018
  },
5275
- {
5276
- id: "outline",
5277
- name: "Outline",
5278
- enabled: true,
5279
- priority: 3,
5280
- background: {
5281
- type: "surface",
5282
- role: "link"
5283
- },
5284
- borderRadius: "rounded-full",
5285
- border: { widthClass: "border-2" },
5286
- effects: { hover: [{
5287
- effectId: "background-on-hover",
5288
- options: { colorToken: "background" }
5289
- }] }
5019
+ ghost: {
5020
+ kind: "complete",
5021
+ appearance: {
5022
+ background: {
5023
+ type: "surface",
5024
+ role: "link"
5025
+ },
5026
+ borderRadius: "rounded-full",
5027
+ effects: { hover: [{
5028
+ effectId: "background-on-hover",
5029
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
5030
+ }] }
5031
+ }
5290
5032
  },
5291
- {
5292
- id: "ghost",
5293
- name: "Ghost",
5294
- enabled: true,
5295
- priority: 3,
5296
- background: {
5297
- type: "surface",
5298
- role: "link"
5299
- },
5300
- borderRadius: "rounded-full",
5301
- effects: { hover: [{
5302
- effectId: "background-on-hover",
5303
- options: { colorToken: "surface" }
5304
- }] }
5033
+ accent: {
5034
+ kind: "complete",
5035
+ appearance: {
5036
+ background: {
5037
+ type: "solid",
5038
+ colorToken: "secondary"
5039
+ },
5040
+ borderRadius: "rounded-full",
5041
+ effects: { hover: [{ effectId: "pop" }] }
5042
+ }
5305
5043
  }
5306
- ]
5044
+ }
5307
5045
  }
5308
5046
  });
5309
- //#endregion
5310
- //#region ../theme-core/src/buttons/personalities/soft-pill.ts
5311
- /**
5312
- * Soft Pill — rounded-full pill buttons with a hover lift. The default for
5313
- * Calm Studio and Modern Wellness; reads as quietly modern and welcoming.
5314
- */
5315
- const softPill = defineButtonPersonality({
5316
- id: "soft-pill",
5317
- name: "Soft Pill",
5318
- description: "Rounded pills with a gentle lift on hover. Quietly modern.",
5047
+ const joyStampRecipe = defineStaticButtonStyleRecipe({
5048
+ id: "joy-stamp",
5049
+ accessibilityLabel: "Bold pill buttons with a hard offset shadow",
5319
5050
  tags: {
5320
- tone: "classic",
5321
- energy: "calm",
5322
- motion: "subtle",
5051
+ tone: "bold",
5052
+ energy: "vibrant",
5053
+ motion: "expressive",
5323
5054
  era: "organic"
5324
5055
  },
5325
- buttonSystem: {
5056
+ system: {
5326
5057
  global: {
5327
5058
  cornerStyle: "pill",
5328
- shadow: "low",
5059
+ shadow: "high",
5329
5060
  textTransform: "none",
5330
- fontWeight: 500,
5331
- borderWidth: 2,
5332
- hoverTransform: "lift",
5061
+ typography: "heading",
5062
+ fontWeight: 700,
5063
+ fontSize: "text-lg",
5064
+ hoverTransform: "none",
5333
5065
  hoverColor: "none"
5334
5066
  },
5335
- variants: [
5336
- {
5337
- id: "primary",
5338
- name: "Primary",
5339
- enabled: true,
5340
- priority: 1,
5341
- background: {
5342
- type: "solid",
5343
- colorToken: "primary"
5344
- },
5345
- borderRadius: "rounded-full",
5346
- shadow: {
5347
- elevation: "low",
5348
- softness: "soft",
5349
- position: "bottom"
5350
- },
5351
- effects: {
5352
- hover: [{
5353
- effectId: "lift",
5354
- options: { translateY: "-1px" }
5355
- }],
5356
- active: [{
5357
- effectId: "scale-down",
5358
- options: { scale: "0.98" }
5359
- }]
5067
+ sizes: {
5068
+ sm: {
5069
+ padding: "0.625rem 1.25rem",
5070
+ fontSize: "text-base"
5071
+ },
5072
+ md: {
5073
+ padding: "0.875rem 1.75rem",
5074
+ fontSize: "text-lg"
5075
+ },
5076
+ lg: {
5077
+ padding: "1.125rem 2.25rem",
5078
+ fontSize: "text-xl"
5079
+ },
5080
+ xl: {
5081
+ padding: "1.25rem 2.75rem",
5082
+ fontSize: "text-2xl"
5083
+ }
5084
+ },
5085
+ roles: {
5086
+ primary: {
5087
+ kind: "complete",
5088
+ appearance: {
5089
+ background: {
5090
+ type: "solid",
5091
+ colorToken: "primary"
5092
+ },
5093
+ borderRadius: "rounded-full",
5094
+ shadow: {
5095
+ elevation: "high",
5096
+ softness: "hard",
5097
+ position: "bottom-right",
5098
+ colorToken: unsafeAsOpaqueButtonColourToken("text")
5099
+ },
5100
+ effects: { hover: [{ effectId: "press-down" }] }
5360
5101
  }
5361
5102
  },
5362
- {
5363
- id: "secondary",
5364
- name: "Secondary",
5365
- enabled: true,
5366
- priority: 2,
5367
- background: {
5368
- type: "surface",
5369
- role: "link"
5370
- },
5371
- borderRadius: "rounded-full",
5372
- border: { widthClass: "border-2" },
5373
- effects: { hover: [{
5374
- effectId: "background-on-hover",
5375
- options: { colorToken: "surface" }
5376
- }] }
5103
+ secondary: {
5104
+ kind: "complete",
5105
+ appearance: {
5106
+ background: {
5107
+ type: "surface",
5108
+ role: "link"
5109
+ },
5110
+ borderRadius: "rounded-full",
5111
+ border: { widthClass: "border-2" },
5112
+ shadow: {
5113
+ elevation: "high",
5114
+ softness: "hard",
5115
+ position: "bottom-right",
5116
+ colorToken: unsafeAsOpaqueButtonColourToken("secondary")
5117
+ },
5118
+ effects: { hover: [{ effectId: "press-down" }] }
5119
+ }
5377
5120
  },
5378
- {
5379
- id: "outline",
5380
- name: "Outline",
5381
- enabled: true,
5382
- priority: 3,
5383
- background: {
5384
- type: "surface",
5385
- role: "link"
5386
- },
5387
- borderRadius: "rounded-full",
5388
- border: { widthClass: "border" },
5389
- effects: { hover: [{
5390
- effectId: "background-on-hover",
5391
- options: { colorToken: "surface" }
5392
- }] }
5121
+ outline: {
5122
+ kind: "derive",
5123
+ from: "secondary"
5393
5124
  },
5394
- {
5395
- id: "ghost",
5396
- name: "Ghost",
5397
- enabled: true,
5398
- priority: 3,
5399
- background: {
5400
- type: "surface",
5401
- role: "link"
5402
- },
5403
- borderRadius: "rounded-full",
5404
- effects: { hover: [{
5405
- effectId: "background-on-hover",
5406
- options: { colorToken: "surface" }
5407
- }] }
5125
+ ghost: {
5126
+ kind: "complete",
5127
+ appearance: {
5128
+ background: {
5129
+ type: "surface",
5130
+ role: "link"
5131
+ },
5132
+ borderRadius: "rounded-full",
5133
+ effects: { hover: [{ effectId: "press-down" }] }
5134
+ }
5135
+ },
5136
+ accent: {
5137
+ kind: "derive",
5138
+ from: "primary",
5139
+ overrides: { background: {
5140
+ type: "solid",
5141
+ colorToken: "accent"
5142
+ } }
5408
5143
  }
5409
- ]
5144
+ }
5410
5145
  }
5411
5146
  });
5412
- //#endregion
5413
- //#region ../theme-core/src/buttons/personalities/two-tone-pill.ts
5414
- const solidSecondary = {
5415
- id: "secondary",
5416
- name: "Secondary",
5417
- enabled: true,
5418
- priority: 2,
5419
- background: {
5420
- type: "solid",
5421
- colorToken: unsafeAsOpaqueButtonColourToken("secondary")
5422
- },
5423
- borderRadius: "rounded-full",
5424
- shadow: {
5425
- elevation: "none",
5426
- softness: null,
5427
- position: "bottom"
5147
+ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
5148
+ id: "ornate-ritual",
5149
+ accessibilityLabel: "Uppercase framed buttons with restrained movement",
5150
+ tags: {
5151
+ tone: "classic",
5152
+ energy: "vibrant",
5153
+ motion: "subtle",
5154
+ era: "organic"
5428
5155
  },
5429
- effects: {
5430
- hover: [{
5431
- effectId: "background-on-hover-alpha",
5432
- options: {
5433
- colorToken: "secondary",
5434
- opacity: 88
5156
+ system: {
5157
+ global: {
5158
+ cornerStyle: "rounded",
5159
+ textTransform: "uppercase",
5160
+ fontWeight: 600,
5161
+ hoverTransform: "none",
5162
+ hoverColor: "none",
5163
+ letterSpacing: "loose"
5164
+ },
5165
+ sizes: {
5166
+ sm: {
5167
+ padding: "0.5625rem 1.25rem",
5168
+ fontSize: "text-xs"
5169
+ },
5170
+ md: {
5171
+ padding: "0.75rem 1.75rem",
5172
+ fontSize: "text-xs"
5173
+ },
5174
+ lg: {
5175
+ padding: "0.875rem 2.25rem",
5176
+ fontSize: "text-sm"
5177
+ },
5178
+ xl: {
5179
+ padding: "1rem 2.75rem",
5180
+ fontSize: "text-base"
5435
5181
  }
5436
- }],
5437
- active: [{
5438
- effectId: "scale-down",
5439
- options: { scale: "0.98" }
5440
- }]
5182
+ },
5183
+ roles: {
5184
+ primary: {
5185
+ kind: "complete",
5186
+ appearance: {
5187
+ background: {
5188
+ type: "solid",
5189
+ colorToken: "primary"
5190
+ },
5191
+ borderRadius: "rounded-md",
5192
+ border: { widthClass: "border" },
5193
+ effects: {
5194
+ hover: [{
5195
+ effectId: "background-on-hover",
5196
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("primary-100") }
5197
+ }],
5198
+ active: [{
5199
+ effectId: "scale-down",
5200
+ options: { scale: "0.98" }
5201
+ }]
5202
+ }
5203
+ }
5204
+ },
5205
+ secondary: {
5206
+ kind: "complete",
5207
+ appearance: {
5208
+ background: {
5209
+ type: "solid",
5210
+ colorToken: "secondary"
5211
+ },
5212
+ borderRadius: "rounded-md",
5213
+ border: { widthClass: "border" },
5214
+ effects: { hover: [{
5215
+ effectId: "background-on-hover",
5216
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
5217
+ }] }
5218
+ }
5219
+ },
5220
+ outline: {
5221
+ kind: "complete",
5222
+ appearance: {
5223
+ background: {
5224
+ type: "surface",
5225
+ role: "link"
5226
+ },
5227
+ borderRadius: "rounded-md",
5228
+ border: { widthClass: "border" },
5229
+ effects: { hover: [{
5230
+ effectId: "background-on-hover",
5231
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
5232
+ }] }
5233
+ }
5234
+ },
5235
+ ghost: {
5236
+ kind: "complete",
5237
+ appearance: {
5238
+ background: {
5239
+ type: "surface",
5240
+ role: "link"
5241
+ },
5242
+ borderRadius: "rounded-none",
5243
+ sizes: {
5244
+ sm: {
5245
+ padding: "0.375rem 0",
5246
+ fontSize: "text-xs"
5247
+ },
5248
+ md: {
5249
+ padding: "0.5rem 0",
5250
+ fontSize: "text-sm"
5251
+ },
5252
+ lg: {
5253
+ padding: "0.625rem 0",
5254
+ fontSize: "text-base"
5255
+ },
5256
+ xl: {
5257
+ padding: "0.75rem 0",
5258
+ fontSize: "text-lg"
5259
+ }
5260
+ },
5261
+ effects: { base: [{
5262
+ effectId: "border-bottom-grow",
5263
+ options: {
5264
+ height: 1,
5265
+ origin: "left"
5266
+ }
5267
+ }] }
5268
+ }
5269
+ },
5270
+ accent: {
5271
+ kind: "derive",
5272
+ from: "primary",
5273
+ overrides: { background: {
5274
+ type: "solid",
5275
+ colorToken: "accent"
5276
+ } }
5277
+ }
5278
+ }
5441
5279
  }
5442
- };
5280
+ });
5443
5281
  //#endregion
5444
- //#region ../theme-core/src/buttons/personalities/index.ts
5445
- const buttonPersonalities = [
5446
- softPill,
5447
- defineButtonPersonality({
5448
- id: "two-tone-pill",
5449
- name: "Two-tone Pill",
5450
- description: "Rounded pills with distinct solid primary and secondary brand colours.",
5451
- tags: softPill.tags,
5452
- buttonSystem: {
5453
- ...softPill.buttonSystem,
5454
- variants: softPill.buttonSystem.variants.map((variant) => variant.id === "secondary" ? solidSecondary : variant)
5455
- }
5456
- }),
5457
- earthPill,
5458
- confidentChip,
5459
- editorialLink,
5460
- pebble,
5461
- inkStamp,
5462
- flatInk,
5463
- brushedWash,
5464
- showtimePill,
5465
- joyStamp,
5466
- ornateRitual,
5467
- quietArrow
5282
+ //#region ../theme-core/src/buttons/styles/registry.ts
5283
+ const buttonStyleRecipes = [
5284
+ softPillRecipe,
5285
+ earthPillRecipe,
5286
+ confidentChipRecipe,
5287
+ editorialLinkRecipe,
5288
+ pebbleRecipe,
5289
+ inkStampRecipe,
5290
+ flatInkRecipe,
5291
+ brushedWashRecipe,
5292
+ showtimePillRecipe,
5293
+ joyStampRecipe,
5294
+ ornateRitualRecipe,
5295
+ quietArrowRecipe
5468
5296
  ];
5469
- new Map(buttonPersonalities.map((p) => [p.id, p]));
5470
- buttonPersonalities.map((personality) => ({
5471
- id: personality.id,
5472
- name: personality.name,
5473
- description: personality.description,
5474
- category: presetCategory(personality),
5475
- buttonSystem: personality.buttonSystem,
5476
- compatibility: {
5477
- ...personality.tags.tone ? { tones: [personality.tags.tone] } : {},
5478
- ...personality.tags.energy ? { energies: [personality.tags.energy] } : {}
5479
- }
5480
- }));
5481
- function presetCategory(personality) {
5482
- switch (personality.tags.era) {
5297
+ const recipesById = new Map(buttonStyleRecipes.map((recipe) => [recipe.id, recipe]));
5298
+ function findButtonStyleRecipe(id) {
5299
+ const recipe = recipesById.get(id);
5300
+ if (recipe === void 0) throw new Error(`Button style registry is missing known style ${id}`);
5301
+ return recipe;
5302
+ }
5303
+ function resolveButtonStyleSelection(selection) {
5304
+ switch (selection.styleId) {
5305
+ case "soft-pill": return resolveButtonStyleRecipe(softPillRecipe, selection.parameters);
5306
+ case "earth-pill": return resolveButtonStyleRecipe(earthPillRecipe, selection.parameters);
5307
+ case "confident-chip": return resolveButtonStyleRecipe(confidentChipRecipe, selection.parameters);
5308
+ case "editorial-link": return resolveButtonStyleRecipe(editorialLinkRecipe, selection.parameters);
5309
+ case "pebble": return resolveButtonStyleRecipe(pebbleRecipe, selection.parameters);
5310
+ case "ink-stamp": return resolveButtonStyleRecipe(inkStampRecipe, selection.parameters);
5311
+ case "flat-ink": return resolveButtonStyleRecipe(flatInkRecipe, selection.parameters);
5312
+ case "brushed-wash": return resolveButtonStyleRecipe(brushedWashRecipe, selection.parameters);
5313
+ case "showtime-pill": return resolveButtonStyleRecipe(showtimePillRecipe, selection.parameters);
5314
+ case "joy-stamp": return resolveButtonStyleRecipe(joyStampRecipe, selection.parameters);
5315
+ case "ornate-ritual": return resolveButtonStyleRecipe(ornateRitualRecipe, selection.parameters);
5316
+ case "quiet-arrow": return resolveButtonStyleRecipe(quietArrowRecipe, selection.parameters);
5317
+ }
5318
+ }
5319
+ function defaultButtonStyleSelectionFor(styleId) {
5320
+ return {
5321
+ styleId,
5322
+ parameters: findButtonStyleRecipe(styleId).defaultParameters
5323
+ };
5324
+ }
5325
+ 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");
5326
+ buttonStyleRecipes.map((recipe) => {
5327
+ const resolved = resolveButtonStyleSelection(defaultButtonStyleSelectionFor(recipe.id));
5328
+ if (resolved.kind === "error") throw new Error(`Invalid registered button style ${recipe.id}: ${resolved.error.issues.join(", ")}`);
5329
+ return {
5330
+ id: recipe.id,
5331
+ name: recipe.accessibilityLabel,
5332
+ description: recipe.accessibilityLabel,
5333
+ category: presetCategory(recipe),
5334
+ buttonSystem: resolved.buttonSystem,
5335
+ compatibility: {
5336
+ ...recipe.tags.tone ? { tones: [recipe.tags.tone] } : {},
5337
+ ...recipe.tags.energy ? { energies: [recipe.tags.energy] } : {}
5338
+ }
5339
+ };
5340
+ });
5341
+ function presetCategory(recipe) {
5342
+ switch (recipe.tags.era) {
5483
5343
  case "retro": return "retro";
5484
5344
  case "editorial": return "minimal";
5485
5345
  case "organic": return "artistic";
5486
- case "modern": return personality.tags.tone === "bold" ? "modern" : "technical";
5346
+ case "modern": return recipe.tags.tone === "bold" ? "modern" : "technical";
5487
5347
  case "technical": return "technical";
5488
5348
  case void 0: return "modern";
5489
5349
  }
@@ -6510,6 +6370,102 @@ new Set(themeV2NormalEditorRawStyleFieldNames);
6510
6370
  const pageDesignEditorBackgroundOverrideOwner = "page-design-editor";
6511
6371
  const siteChromeBackgroundOverrideOwner = "site-chrome-editor";
6512
6372
  //#endregion
6373
+ //#region ../theme-core/src/utils/colorStyles.ts
6374
+ const COLOR_VAR_PREFIX = "--tb-";
6375
+ function parseToken(source) {
6376
+ const parts = parseColorTokenParts(source);
6377
+ if (parts.kind === "raw") return {
6378
+ token: source,
6379
+ raw: parts.value
6380
+ };
6381
+ if (parts.kind === "invalid") return { token: source };
6382
+ return {
6383
+ token: parts.token,
6384
+ opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
6385
+ };
6386
+ }
6387
+ const SURFACE_TEXT_ROLE_BY_TOKEN = {
6388
+ text: "text",
6389
+ heading: "heading",
6390
+ mutedText: "supporting"
6391
+ };
6392
+ function surfaceRoleForTextToken(token) {
6393
+ return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
6394
+ }
6395
+ /**
6396
+ * Converts a theme color token to a CSS rgb value.
6397
+ * This is the primary function for applying theme colors to CSS properties.
6398
+ *
6399
+ * @param token - Theme color token (semantic, with opacity, or raw)
6400
+ * @returns CSS color value (rgb with optional alpha, or raw CSS value)
6401
+ *
6402
+ * @example
6403
+ * rgbColorValue('primary') // => 'rgb(var(--tb-primary))'
6404
+ * rgbColorValue('surface/95') // => 'rgb(var(--tb-surface) / 0.95)'
6405
+ * rgbColorValue('raw:transparent') // => 'transparent'
6406
+ */
6407
+ function rgbColorValue(token) {
6408
+ const { token: baseToken, opacityPercent, raw } = parseToken(token);
6409
+ if (raw) return raw;
6410
+ const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
6411
+ if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
6412
+ return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
6413
+ }
6414
+ /**
6415
+ * Creates a backgroundColor style object from a theme token.
6416
+ *
6417
+ * @param token - Theme color token
6418
+ * @returns CSSProperties with backgroundColor
6419
+ */
6420
+ function backgroundColorStyle(token) {
6421
+ return { backgroundColor: rgbColorValue(token) };
6422
+ }
6423
+ /**
6424
+ * Creates a text color style object from a theme token.
6425
+ *
6426
+ * @param token - Theme color token
6427
+ * @returns CSSProperties with color
6428
+ */
6429
+ function textColorStyle(token) {
6430
+ const parsed = parseToken(token);
6431
+ const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
6432
+ if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
6433
+ return { color: rgbColorValue(token) };
6434
+ }
6435
+ /**
6436
+ * Creates a border color style object from a theme token.
6437
+ *
6438
+ * @param token - Theme color token
6439
+ * @returns CSSProperties with borderColor
6440
+ */
6441
+ function borderColorStyle(token) {
6442
+ return { borderColor: rgbColorValue(token) };
6443
+ }
6444
+ /**
6445
+ * Merges multiple CSSProperties objects into a single object.
6446
+ * Later styles override earlier ones. Undefined values are filtered out.
6447
+ * Returns undefined if the merged result is empty.
6448
+ *
6449
+ * @param styles - Variable number of CSSProperties objects (can be undefined)
6450
+ * @returns Merged CSSProperties object, or undefined if empty
6451
+ *
6452
+ * @example
6453
+ * mergeStyles(
6454
+ * backgroundColorStyle('surface'),
6455
+ * textColorStyle('text'),
6456
+ * borderColorStyle('border')
6457
+ * )
6458
+ * // => { backgroundColor: '...', color: '...', borderColor: '...' }
6459
+ */
6460
+ function mergeStyles(...styles) {
6461
+ const merged = {};
6462
+ for (const style of styles) {
6463
+ if (!style) continue;
6464
+ Object.assign(merged, style);
6465
+ }
6466
+ return Object.keys(merged).length ? merged : void 0;
6467
+ }
6468
+ //#endregion
6513
6469
  //#region ../theme-core/src/utils/tokenOrColor.ts
6514
6470
  /**
6515
6471
  * Runtime color-reference fields intentionally accept any string, including
@@ -10112,76 +10068,9 @@ function headerConfigurationKey(configuration) {
10112
10068
  function asFooterLookId(value) {
10113
10069
  return value;
10114
10070
  }
10115
- function asFooterLayoutId(value) {
10116
- return value;
10117
- }
10118
- function asFooterStyleId(value) {
10119
- return value;
10120
- }
10121
- const footerLayoutCatalog = defineExactCatalog()([
10122
- {
10123
- id: asFooterLayoutId("identity"),
10124
- label: "Identity",
10125
- description: "Logo, site text, address, and legal copy without relying on footer navigation."
10126
- },
10127
- {
10128
- id: asFooterLayoutId("centered"),
10129
- label: "Centered",
10130
- description: "A calm centered stack for identity, short copy, and optional compact navigation.",
10131
- maxRecommendedNavDensity: "sparse"
10132
- },
10133
- {
10134
- id: asFooterLayoutId("split"),
10135
- label: "Split",
10136
- description: "Navigation and brand signoff separated into a wider split footer.",
10137
- requiresFooterNav: true,
10138
- maxRecommendedNavDensity: "balanced"
10139
- },
10140
- {
10141
- id: asFooterLayoutId("columns"),
10142
- label: "Columns",
10143
- description: "Grouped footer navigation columns with a supporting bottom line.",
10144
- requiresFooterNav: true,
10145
- requiresFooterNavGroups: true
10146
- }
10147
- ]);
10148
- const footerStyleCatalog = defineExactCatalog()([
10149
- {
10150
- id: asFooterStyleId("quiet"),
10151
- label: "Quiet",
10152
- description: "Lightweight, practical footer treatment."
10153
- },
10154
- {
10155
- id: asFooterStyleId("calm"),
10156
- label: "Calm",
10157
- description: "Soft centered treatment with restrained dividers."
10158
- },
10159
- {
10160
- id: asFooterStyleId("editorial"),
10161
- label: "Editorial",
10162
- description: "Text-forward treatment with fine-line structure."
10163
- },
10164
- {
10165
- id: asFooterStyleId("brand-band"),
10166
- label: "Brand band",
10167
- description: "High-contrast brand treatment with a stronger bottom bar."
10168
- }
10169
- ]);
10170
- new Map(footerLayoutCatalog.map((layout) => [layout.id, layout]));
10171
- new Map(footerStyleCatalog.map((style) => [style.id, style]));
10172
- /**
10173
- * No-nav-safe identity footer: brand and legal/supporting copy carry the
10174
- * footer without implying missing navigation.
10175
- */
10176
- function identityQuietFooter(theme) {
10071
+ function quietFooterLinks(theme) {
10177
10072
  return {
10178
10073
  ...theme.footer,
10179
- variant: "simple",
10180
- maxWidth: "container",
10181
- background: {
10182
- type: "color",
10183
- color: "surface"
10184
- },
10185
10074
  navStyle: "minimal",
10186
10075
  navWeight: "regular",
10187
10076
  navColor: "text",
@@ -10194,285 +10083,38 @@ function identityQuietFooter(theme) {
10194
10083
  hoverColorToken: "primary",
10195
10084
  padding: "none",
10196
10085
  borderRadius: "none"
10197
- },
10198
- navLayout: {
10199
- layout: "inline-wrap",
10200
- align: "start",
10201
- gapX: "default",
10202
- gapY: "tight"
10203
- },
10204
- logo: {
10205
- showLogo: true,
10206
- showLogoText: true,
10207
- placement: "left",
10208
- size: "sm",
10209
- align: "start"
10210
- },
10211
- bottomBar: {
10212
- enabled: false,
10213
- fullBleed: false,
10214
- textAlign: "left",
10215
- paddingX: "default",
10216
- paddingY: "compact",
10217
- borderTop: { width: "none" }
10218
10086
  }
10219
10087
  };
10220
10088
  }
10221
- /**
10222
- * Back-compat alias for the previous default footer Look. It keeps existing
10223
- * persisted selections valid while staying hidden from the new layout/style UI.
10224
- */
10225
- function mutedGroundingFooter(theme) {
10226
- return {
10227
- ...identityQuietFooter(theme),
10228
- background: theme.footer.background,
10229
- navStyle: theme.footer.navStyle,
10230
- navColor: theme.footer.navColor,
10231
- navWeight: theme.footer.navWeight,
10232
- navLinkStyle: theme.footer.navLinkStyle,
10233
- bottomTextLinkStyle: theme.footer.bottomTextLinkStyle
10234
- };
10235
- }
10236
- /** Applies a high-contrast brand band with a darker full-bleed bottom bar. */
10237
- function brandTwoBandFooter(theme) {
10089
+ function emphasizedFooterLinks(theme) {
10238
10090
  return {
10239
10091
  ...theme.footer,
10240
- variant: "split",
10241
- maxWidth: "container",
10242
- background: {
10243
- type: "color",
10244
- color: "primary-800"
10245
- },
10246
10092
  navStyle: "minimal",
10247
10093
  navWeight: "medium",
10248
- navColor: "primaryForeground",
10249
- navLinkStyle: {
10250
- typography: "body",
10251
- fontWeight: "medium",
10252
- textTransform: "none",
10253
- italic: false,
10254
- colorToken: "primaryForeground",
10255
- hoverColorToken: "secondary",
10256
- padding: "none",
10257
- borderRadius: "none"
10258
- },
10259
- bottomTextLinkStyle: {
10260
- colorToken: "secondary",
10261
- decorationColorToken: "secondary"
10262
- },
10263
- navLayout: {
10264
- layout: "inline-wrap",
10265
- align: "start",
10266
- gapX: "default",
10267
- gapY: "tight"
10268
- },
10269
- logo: {
10270
- showLogo: true,
10271
- showLogoText: false,
10272
- placement: "left",
10273
- size: "sm",
10274
- align: "start"
10275
- },
10276
- bottomBar: {
10277
- enabled: true,
10278
- fullBleed: true,
10279
- background: {
10280
- type: "color",
10281
- color: "primary-900"
10282
- },
10283
- textColor: "primaryForeground",
10284
- textAlign: "center",
10285
- paddingX: "default",
10286
- paddingY: "compact",
10287
- borderTop: { width: "none" }
10288
- }
10289
- };
10290
- }
10291
- /**
10292
- * Centered stack on a softly tinted band: logo, inline nav, address, and a
10293
- * hairline-topped copyright line, all centered.
10294
- */
10295
- function centeredCalmFooter(theme) {
10296
- return {
10297
- ...theme.footer,
10298
- variant: "simple",
10299
- maxWidth: "container",
10300
- background: {
10301
- type: "color",
10302
- color: "surfaceAlt"
10303
- },
10304
- navStyle: "minimal",
10305
- navWeight: "regular",
10306
10094
  navColor: "text",
10307
10095
  navLinkStyle: {
10308
10096
  typography: "body",
10309
- fontWeight: "regular",
10310
- textTransform: "none",
10311
- italic: false,
10312
- colorToken: "text",
10313
- hoverColorToken: "primary",
10314
- padding: "none",
10315
- borderRadius: "none"
10316
- },
10317
- navLayout: {
10318
- layout: "inline-wrap",
10319
- align: "center",
10320
- gapX: "relaxed",
10321
- gapY: "tight"
10322
- },
10323
- logo: {
10324
- showLogo: true,
10325
- showLogoText: false,
10326
- placement: "above",
10327
- size: "sm",
10328
- align: "center"
10329
- },
10330
- bottomBar: {
10331
- enabled: true,
10332
- fullBleed: false,
10333
- textAlign: "center",
10334
- paddingX: "default",
10335
- paddingY: "compact",
10336
- borderTop: { width: "thin" }
10337
- }
10338
- };
10339
- }
10340
- /** Editorial split footer: compact nav on one side, brand signoff on the other. */
10341
- function splitEditorialFooter(theme) {
10342
- return {
10343
- ...theme.footer,
10344
- variant: "split",
10345
- maxWidth: "container",
10346
- background: {
10347
- type: "color",
10348
- color: "surface"
10349
- },
10350
- navStyle: "minimal",
10351
- navWeight: "regular",
10352
- navColor: "text",
10353
- navLinkStyle: {
10354
- typography: "body",
10355
- fontWeight: "regular",
10356
- textTransform: "none",
10357
- italic: false,
10358
- colorToken: "text",
10359
- hoverColorToken: "primary",
10360
- padding: "none",
10361
- borderRadius: "none"
10362
- },
10363
- navLayout: {
10364
- layout: "inline-wrap",
10365
- align: "start",
10366
- gapX: "relaxed",
10367
- gapY: "tight"
10368
- },
10369
- logo: {
10370
- showLogo: true,
10371
- showLogoText: true,
10372
- placement: "right",
10373
- size: "sm",
10374
- align: "end"
10375
- },
10376
- bottomBar: {
10377
- enabled: true,
10378
- fullBleed: false,
10379
- textAlign: "left",
10380
- paddingX: "default",
10381
- paddingY: "compact",
10382
- borderTop: { width: "thin" }
10383
- }
10384
- };
10385
- }
10386
- /**
10387
- * Editorial columns: site name and supporting copy on the left, inline nav on
10388
- * the right, with a hairline-topped bottom line. Uses the footer block's
10389
- * columns layout.
10390
- */
10391
- function editorialColumnsFooter(theme) {
10392
- return {
10393
- ...theme.footer,
10394
- variant: "columns",
10395
- maxWidth: "container",
10396
- background: {
10397
- type: "color",
10398
- color: "surface"
10399
- },
10400
- navStyle: "minimal",
10401
- navWeight: "regular",
10402
- navColor: "text",
10403
- navLinkStyle: {
10404
- typography: "body",
10405
- fontWeight: "regular",
10097
+ fontWeight: "medium",
10406
10098
  textTransform: "none",
10407
10099
  italic: false,
10408
10100
  colorToken: "text",
10409
10101
  hoverColorToken: "primary",
10410
10102
  padding: "none",
10411
10103
  borderRadius: "none"
10412
- },
10413
- logo: {
10414
- showLogo: true,
10415
- showLogoText: true,
10416
- placement: "left",
10417
- size: "sm",
10418
- align: "start"
10419
- },
10420
- bottomBar: {
10421
- enabled: true,
10422
- fullBleed: false,
10423
- textAlign: "center",
10424
- paddingX: "default",
10425
- paddingY: "compact",
10426
- borderTop: { width: "thin" }
10427
10104
  }
10428
10105
  };
10429
10106
  }
10430
- const footerLookCatalog = defineExactCatalog()([
10431
- {
10432
- id: asFooterLookId("footer-identity-quiet"),
10433
- label: "Identity footer",
10434
- layoutId: asFooterLayoutId("identity"),
10435
- styleId: asFooterStyleId("quiet"),
10436
- compile: identityQuietFooter
10437
- },
10438
- {
10439
- id: asFooterLookId("footer-muted-grounding"),
10440
- label: "Muted grounding footer",
10441
- layoutId: asFooterLayoutId("identity"),
10442
- styleId: asFooterStyleId("quiet"),
10443
- hiddenFromLayoutStyleControls: true,
10444
- compile: mutedGroundingFooter
10445
- },
10446
- {
10447
- id: asFooterLookId("footer-centered-calm"),
10448
- label: "Centered calm footer",
10449
- layoutId: asFooterLayoutId("centered"),
10450
- styleId: asFooterStyleId("calm"),
10451
- compile: centeredCalmFooter
10452
- },
10453
- {
10454
- id: asFooterLookId("footer-split-editorial"),
10455
- label: "Split editorial footer",
10456
- layoutId: asFooterLayoutId("split"),
10457
- styleId: asFooterStyleId("editorial"),
10458
- compile: splitEditorialFooter
10459
- },
10460
- {
10461
- id: asFooterLookId("footer-editorial-columns"),
10462
- label: "Editorial columns footer",
10463
- layoutId: asFooterLayoutId("columns"),
10464
- styleId: asFooterStyleId("editorial"),
10465
- compile: editorialColumnsFooter
10466
- },
10467
- {
10468
- id: asFooterLookId("site-footer-brand-two-band"),
10469
- label: "Two-band brand footer",
10470
- layoutId: asFooterLayoutId("split"),
10471
- styleId: asFooterStyleId("brand-band"),
10472
- allowedContentPresence: ["default-footer", "default-and-blocks"],
10473
- compile: brandTwoBandFooter
10474
- }
10475
- ]);
10107
+ const footerLookCatalog = defineExactCatalog()([{
10108
+ id: asFooterLookId("footer-links-quiet"),
10109
+ label: "Quiet links",
10110
+ description: "Regular-weight footer navigation with a restrained hover.",
10111
+ compile: quietFooterLinks
10112
+ }, {
10113
+ id: asFooterLookId("footer-links-emphasized"),
10114
+ label: "Emphasized links",
10115
+ description: "Medium-weight footer navigation with a clearer emphasis.",
10116
+ compile: emphasizedFooterLinks
10117
+ }]);
10476
10118
  new Map(footerLookCatalog.map((look) => [look.id, look]));
10477
10119
  //#endregion
10478
10120
  //#region ../theme-core/src/site-styles/sourceCatalogs.ts
@@ -11601,17 +11243,21 @@ function defineCuratedSiteStyle(input) {
11601
11243
  })),
11602
11244
  recommendedHeaderLookIds: legacyHeaderLookIds.map(asHeaderLookId),
11603
11245
  recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(asFooterLookId),
11604
- buttonPersonalityChoices: input.buttonPersonalityChoices,
11246
+ buttonStyleChoices: input.buttonStyleChoices,
11605
11247
  paletteRecommendations: input.paletteRecommendations,
11606
11248
  typography: input.typography ?? defaultTypographyForRecipe(input.tokenRecipes.typography),
11607
11249
  ...input.heroTypography ? { heroTypography: input.heroTypography } : {}
11608
11250
  };
11609
11251
  }
11610
- function buttonChoice(id, note) {
11252
+ function buttonChoice(styleId, note, parameters) {
11253
+ const selection = parameters === void 0 ? defaultButtonStyleSelectionFor(styleId) : buttonStyleSelectionSchema.parse({
11254
+ styleId,
11255
+ parameters
11256
+ });
11611
11257
  return note ? {
11612
- id: asButtonPersonalityId(id),
11258
+ ...selection,
11613
11259
  note
11614
- } : { id: asButtonPersonalityId(id) };
11260
+ } : selection;
11615
11261
  }
11616
11262
  function paletteRecommendation(authoringKey, note) {
11617
11263
  const valueKey = requireCuratedPaletteValueKey(asCuratedPaletteAuthoringKey(authoringKey));
@@ -11796,9 +11442,8 @@ const curatedSiteStyles = [
11796
11442
  "minimal-transparent",
11797
11443
  "clean-base"
11798
11444
  ],
11799
- buttonPersonalityChoices: [
11445
+ buttonStyleChoices: [
11800
11446
  buttonChoice("soft-pill"),
11801
- buttonChoice("two-tone-pill"),
11802
11447
  buttonChoice("pebble"),
11803
11448
  buttonChoice("editorial-link"),
11804
11449
  buttonChoice("brushed-wash")
@@ -11834,7 +11479,7 @@ const curatedSiteStyles = [
11834
11479
  "brand-solid",
11835
11480
  "clean-base"
11836
11481
  ],
11837
- buttonPersonalityChoices: [
11482
+ buttonStyleChoices: [
11838
11483
  buttonChoice("confident-chip"),
11839
11484
  buttonChoice("soft-pill"),
11840
11485
  buttonChoice("editorial-link")
@@ -11873,7 +11518,7 @@ const curatedSiteStyles = [
11873
11518
  "minimal-transparent",
11874
11519
  "centered-calm"
11875
11520
  ],
11876
- buttonPersonalityChoices: [
11521
+ buttonStyleChoices: [
11877
11522
  buttonChoice("editorial-link"),
11878
11523
  buttonChoice("soft-pill"),
11879
11524
  buttonChoice("brushed-wash")
@@ -11913,7 +11558,7 @@ const curatedSiteStyles = [
11913
11558
  "practical-utility",
11914
11559
  "clean-base"
11915
11560
  ],
11916
- buttonPersonalityChoices: [
11561
+ buttonStyleChoices: [
11917
11562
  buttonChoice("pebble"),
11918
11563
  buttonChoice("brushed-wash"),
11919
11564
  buttonChoice("confident-chip")
@@ -11974,7 +11619,7 @@ const curatedSiteStyles = [
11974
11619
  "serif-line",
11975
11620
  "clean-base"
11976
11621
  ],
11977
- buttonPersonalityChoices: [
11622
+ buttonStyleChoices: [
11978
11623
  buttonChoice("editorial-link"),
11979
11624
  buttonChoice("confident-chip"),
11980
11625
  buttonChoice("soft-pill")
@@ -12036,7 +11681,7 @@ const curatedSiteStyles = [
12036
11681
  "brand-solid",
12037
11682
  "clean-base"
12038
11683
  ],
12039
- buttonPersonalityChoices: [
11684
+ buttonStyleChoices: [
12040
11685
  buttonChoice("confident-chip"),
12041
11686
  buttonChoice("pebble"),
12042
11687
  buttonChoice("ink-stamp")
@@ -12075,7 +11720,7 @@ const curatedSiteStyles = [
12075
11720
  "minimal-transparent",
12076
11721
  "clean-base"
12077
11722
  ],
12078
- buttonPersonalityChoices: [
11723
+ buttonStyleChoices: [
12079
11724
  buttonChoice("soft-pill"),
12080
11725
  buttonChoice("pebble"),
12081
11726
  buttonChoice("confident-chip")
@@ -12148,7 +11793,7 @@ const curatedSiteStyles = [
12148
11793
  "clean-base",
12149
11794
  "centered-calm"
12150
11795
  ],
12151
- buttonPersonalityChoices: [
11796
+ buttonStyleChoices: [
12152
11797
  buttonChoice("pebble"),
12153
11798
  buttonChoice("soft-pill"),
12154
11799
  buttonChoice("editorial-link")
@@ -12267,12 +11912,8 @@ const curatedSiteStyles = [
12267
11912
  "serif-line",
12268
11913
  "minimal-transparent"
12269
11914
  ],
12270
- recommendedFooterLookIds: [
12271
- "footer-centered-calm",
12272
- "footer-editorial-columns",
12273
- "footer-muted-grounding"
12274
- ],
12275
- buttonPersonalityChoices: [
11915
+ recommendedFooterLookIds: ["footer-links-quiet"],
11916
+ buttonStyleChoices: [
12276
11917
  buttonChoice("soft-pill"),
12277
11918
  buttonChoice("pebble"),
12278
11919
  buttonChoice("editorial-link")
@@ -12346,7 +11987,7 @@ const curatedSiteStyles = [
12346
11987
  "centered-calm",
12347
11988
  "minimal-transparent"
12348
11989
  ],
12349
- buttonPersonalityChoices: [
11990
+ buttonStyleChoices: [
12350
11991
  buttonChoice("editorial-link"),
12351
11992
  buttonChoice("soft-pill"),
12352
11993
  buttonChoice("brushed-wash")
@@ -12419,8 +12060,8 @@ const curatedSiteStyles = [
12419
12060
  "practical-utility",
12420
12061
  "clean-base"
12421
12062
  ],
12422
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12423
- buttonPersonalityChoices: [
12063
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
12064
+ buttonStyleChoices: [
12424
12065
  buttonChoice("pebble"),
12425
12066
  buttonChoice("confident-chip"),
12426
12067
  buttonChoice("ink-stamp"),
@@ -12541,8 +12182,8 @@ const curatedSiteStyles = [
12541
12182
  "minimal-transparent",
12542
12183
  "serif-line"
12543
12184
  ],
12544
- recommendedFooterLookIds: ["footer-muted-grounding", "site-footer-brand-two-band"],
12545
- buttonPersonalityChoices: [
12185
+ recommendedFooterLookIds: ["footer-links-quiet", "footer-links-emphasized"],
12186
+ buttonStyleChoices: [
12546
12187
  buttonChoice("earth-pill"),
12547
12188
  buttonChoice("soft-pill"),
12548
12189
  buttonChoice("pebble"),
@@ -12613,7 +12254,7 @@ const curatedSiteStyles = [
12613
12254
  "floating-glass",
12614
12255
  "brand-solid"
12615
12256
  ],
12616
- buttonPersonalityChoices: [
12257
+ buttonStyleChoices: [
12617
12258
  buttonChoice("ink-stamp"),
12618
12259
  buttonChoice("confident-chip"),
12619
12260
  buttonChoice("brushed-wash"),
@@ -12668,8 +12309,8 @@ const curatedSiteStyles = [
12668
12309
  "transparent-overlay",
12669
12310
  "practical-utility"
12670
12311
  ],
12671
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12672
- buttonPersonalityChoices: [
12312
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
12313
+ buttonStyleChoices: [
12673
12314
  buttonChoice("showtime-pill"),
12674
12315
  buttonChoice("confident-chip"),
12675
12316
  buttonChoice("ink-stamp"),
@@ -12750,8 +12391,8 @@ const curatedSiteStyles = [
12750
12391
  headerStyleChoice("glass")
12751
12392
  ] },
12752
12393
  recommendedHeaderLookIds: ["minimal-transparent"],
12753
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12754
- buttonPersonalityChoices: [
12394
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
12395
+ buttonStyleChoices: [
12755
12396
  buttonChoice("ornate-ritual"),
12756
12397
  buttonChoice("joy-stamp"),
12757
12398
  buttonChoice("ink-stamp")
@@ -12804,8 +12445,8 @@ const curatedSiteStyles = [
12804
12445
  headerStyleChoice("glass")
12805
12446
  ] },
12806
12447
  recommendedHeaderLookIds: ["minimal-transparent"],
12807
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12808
- buttonPersonalityChoices: [
12448
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
12449
+ buttonStyleChoices: [
12809
12450
  buttonChoice("joy-stamp"),
12810
12451
  buttonChoice("ink-stamp"),
12811
12452
  buttonChoice("showtime-pill")
@@ -12895,8 +12536,8 @@ const curatedSiteStyles = [
12895
12536
  "centered-calm",
12896
12537
  "clean-base"
12897
12538
  ],
12898
- recommendedFooterLookIds: ["footer-editorial-columns", "footer-muted-grounding"],
12899
- buttonPersonalityChoices: [
12539
+ recommendedFooterLookIds: ["footer-links-quiet"],
12540
+ buttonStyleChoices: [
12900
12541
  buttonChoice("flat-ink"),
12901
12542
  buttonChoice("confident-chip"),
12902
12543
  buttonChoice("editorial-link")
@@ -12973,14 +12614,9 @@ const curatedSiteStyles = [
12973
12614
  "serif-line",
12974
12615
  "clean-base"
12975
12616
  ],
12976
- recommendedFooterLookIds: [
12977
- "footer-editorial-columns",
12978
- "footer-muted-grounding",
12979
- "footer-identity-quiet"
12980
- ],
12981
- buttonPersonalityChoices: [
12982
- buttonChoice("quiet-arrow"),
12983
- buttonChoice("two-tone-pill"),
12617
+ recommendedFooterLookIds: ["footer-links-quiet"],
12618
+ buttonStyleChoices: [
12619
+ buttonChoice("quiet-arrow", void 0, { secondaryTreatment: "solid-accent" }),
12984
12620
  buttonChoice("flat-ink"),
12985
12621
  buttonChoice("editorial-link")
12986
12622
  ],
@@ -13729,6 +13365,7 @@ const DISPLAY_MEDIA_KINDS = [
13729
13365
  "video",
13730
13366
  "audio"
13731
13367
  ];
13368
+ const DEFAULT_MEDIA_FIELD_KINDS = ["image"];
13732
13369
  const PUBLIC_FILE_FIELD_KINDS = [
13733
13370
  "document",
13734
13371
  "spreadsheet",
@@ -13929,18 +13566,28 @@ const inlineTextFieldSchema = baseFieldSchema.extend({
13929
13566
  maxLength: z$1.number().int().positive().optional(),
13930
13567
  plainTextField: z$1.string().min(1).optional()
13931
13568
  });
13569
+ function hasMediaDefaultIdentifier(value) {
13570
+ return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.identifier === "string" && value.identifier.trim().length > 0;
13571
+ }
13572
+ function validateMediaFieldDefault(field, ctx) {
13573
+ if (field.defaultValue !== void 0 && field.defaultValue !== null && !hasMediaDefaultIdentifier(field.defaultValue)) ctx.addIssue({
13574
+ code: z$1.ZodIssueCode.custom,
13575
+ path: ["defaultValue"],
13576
+ message: `${field.type} defaultValue must be null or an object with a non-empty identifier`
13577
+ });
13578
+ }
13932
13579
  const mediaFieldSchema = baseFieldSchema.extend({
13933
13580
  type: z$1.literal("media"),
13934
- mediaKinds: z$1.array(z$1.enum(MEDIA_KINDS)).default(["image"]).transform((kinds) => {
13581
+ mediaKinds: z$1.array(z$1.enum(MEDIA_KINDS)).default([...DEFAULT_MEDIA_FIELD_KINDS]).transform((kinds) => {
13935
13582
  const displayKinds = kinds.filter(isDisplayMediaKind);
13936
- return displayKinds.length > 0 ? displayKinds : ["image"];
13583
+ return displayKinds.length > 0 ? displayKinds : [...DEFAULT_MEDIA_FIELD_KINDS];
13937
13584
  }),
13938
13585
  aspectRatio: z$1.string().optional()
13939
- });
13586
+ }).superRefine(validateMediaFieldDefault);
13940
13587
  const fileFieldSchema = baseFieldSchema.extend({
13941
13588
  type: z$1.literal("file"),
13942
13589
  fileKinds: z$1.array(z$1.enum(PUBLIC_FILE_FIELD_KINDS)).default([...PUBLIC_FILE_FIELD_KINDS])
13943
- });
13590
+ }).superRefine(validateMediaFieldDefault);
13944
13591
  const booleanFieldSchema = baseFieldSchema.extend({ type: z$1.literal("boolean") });
13945
13592
  const dateFieldSchema = baseFieldSchema.extend({ type: z$1.literal("date") });
13946
13593
  const timeFieldSchema = baseFieldSchema.extend({ type: z$1.literal("time") });
@@ -17330,25 +16977,41 @@ const heroLayoutControlsFragment = defineFragment({
17330
16977
  layout: []
17331
16978
  });
17332
16979
  //#endregion
16980
+ //#region ../blocks/src/system/constants/buttonRoles.ts
16981
+ /**
16982
+ * Semantic button roles available to block authors.
16983
+ *
16984
+ * These roles are deliberately independent of a site's visual button style:
16985
+ * the active theme owns how each role looks.
16986
+ */
16987
+ const BLOCK_BUTTON_ROLES = PUBLIC_BUTTON_ROLES;
16988
+ const blockButtonRoleSchema = z$1.enum(BLOCK_BUTTON_ROLES);
16989
+ /**
16990
+ * Temporary rollout boundary for persisted content written before issue #1220.
16991
+ * Authoring remains strict through `blockButtonRoleSchema`; this parser exists
16992
+ * only until the post-deploy role rewrite has been audited in production.
16993
+ */
16994
+ function canonicalizePersistedBlockButtonRole(value) {
16995
+ return value === "link" || value === "tertiary" ? "ghost" : value;
16996
+ }
16997
+ const persistedBlockButtonRoleSchema = z$1.preprocess((value) => typeof value === "string" ? canonicalizePersistedBlockButtonRole(value) : value, blockButtonRoleSchema);
16998
+ const BLOCK_BUTTON_ROLE_LABELS = {
16999
+ primary: "Primary",
17000
+ secondary: "Secondary",
17001
+ outline: "Outline",
17002
+ ghost: "Ghost",
17003
+ accent: "Accent"
17004
+ };
17005
+ const BLOCK_BUTTON_ROLE_OPTIONS = BLOCK_BUTTON_ROLES.map((value) => ({
17006
+ value,
17007
+ label: BLOCK_BUTTON_ROLE_LABELS[value]
17008
+ }));
17009
+ function isBlockButtonRole(value) {
17010
+ return blockButtonRoleSchema.safeParse(value).success;
17011
+ }
17012
+ //#endregion
17333
17013
  //#region ../blocks/src/system/fields/button.ts
17334
- const DEFAULT_THEME_BUTTON_VARIANTS = [
17335
- {
17336
- value: "primary",
17337
- label: "Primary"
17338
- },
17339
- {
17340
- value: "secondary",
17341
- label: "Secondary"
17342
- },
17343
- {
17344
- value: "outline",
17345
- label: "Outline"
17346
- },
17347
- {
17348
- value: "link",
17349
- label: "Link"
17350
- }
17351
- ];
17014
+ const DEFAULT_THEME_BUTTON_VARIANTS = BLOCK_BUTTON_ROLE_OPTIONS;
17352
17015
  function createButtonVariantField(options = {}) {
17353
17016
  return {
17354
17017
  id: options.id ?? "buttonVariant",
@@ -17366,20 +17029,7 @@ function createButtonVariantField(options = {}) {
17366
17029
  };
17367
17030
  }
17368
17031
  function createButtonGroup(options = {}) {
17369
- const { variants = [
17370
- {
17371
- value: "primary",
17372
- label: "Primary"
17373
- },
17374
- {
17375
- value: "secondary",
17376
- label: "Secondary"
17377
- },
17378
- {
17379
- value: "outline",
17380
- label: "Outline"
17381
- }
17382
- ], defaultVariant, includeSize = true, defaultSize = "md", showGroupLabel = false, groupId = "button", groupLabel = "Button", flattenInRepeater = true } = options;
17032
+ const { variants = BLOCK_BUTTON_ROLE_OPTIONS, defaultVariant, includeSize = true, defaultSize = "md", showGroupLabel = false, groupId = "button", groupLabel = "Button", flattenInRepeater = true } = options;
17383
17033
  const mainFields = [
17384
17034
  {
17385
17035
  id: "label",
@@ -17515,29 +17165,7 @@ const ctaRowFragment = defineFragment({
17515
17165
  fields: [createCtasRepeater({
17516
17166
  label: "Calls to action",
17517
17167
  itemLabel: "CTA",
17518
- maxItems: 3,
17519
- button: { variants: [
17520
- {
17521
- value: "primary",
17522
- label: "Primary"
17523
- },
17524
- {
17525
- value: "secondary",
17526
- label: "Secondary"
17527
- },
17528
- {
17529
- value: "outline",
17530
- label: "Outline"
17531
- },
17532
- {
17533
- value: "link",
17534
- label: "Link"
17535
- },
17536
- {
17537
- value: "accent",
17538
- label: "Accent"
17539
- }
17540
- ] }
17168
+ maxItems: 3
17541
17169
  })],
17542
17170
  layout: [ctaRow({
17543
17171
  collectionPath: "content.ctas",
@@ -17556,10 +17184,6 @@ const heroCtaRowFragment = defineFragment({
17556
17184
  defaultValue: [],
17557
17185
  button: {
17558
17186
  variants: [
17559
- {
17560
- value: "default",
17561
- label: "Default"
17562
- },
17563
17187
  {
17564
17188
  value: "primary",
17565
17189
  label: "Primary"
@@ -17571,9 +17195,17 @@ const heroCtaRowFragment = defineFragment({
17571
17195
  {
17572
17196
  value: "outline",
17573
17197
  label: "Outline"
17198
+ },
17199
+ {
17200
+ value: "ghost",
17201
+ label: "Ghost"
17202
+ },
17203
+ {
17204
+ value: "accent",
17205
+ label: "Accent"
17574
17206
  }
17575
17207
  ],
17576
- defaultVariant: "default",
17208
+ defaultVariant: "primary",
17577
17209
  includeSize: true,
17578
17210
  defaultSize: "lg"
17579
17211
  }
@@ -18264,11 +17896,13 @@ const blogFeaturedPostFragment = defineFragment({
18264
17896
  as: "p",
18265
17897
  style: textColorStyle("text/80")
18266
17898
  }, bind("post.excerpt", { fallback: "Select a blog post to display its preview." })),
18267
- link({
18268
- className: "rb-inline-flex rb-items-center rb-caption rb-hover-opacity-80",
18269
- style: textColorStyle("primary"),
18270
- href: { $bind: { from: "post.path" } }
18271
- }, [text({ as: "strong" }, props({ value: "Read more →" }))])
17899
+ button({
17900
+ className: "rb-self-start",
17901
+ href: { $bind: { from: "post.path" } },
17902
+ variantId: "ghost",
17903
+ size: "sm",
17904
+ linkRequired: true
17905
+ }, [text({ as: "span" }, props({ value: "Read more" }))])
18272
17906
  ])], when("post")), stack({
18273
17907
  gap: "sm",
18274
17908
  className: "rb-rounded-xl rb-border rb-border-dashed rb-p-6",
@@ -18539,21 +18173,7 @@ const newsletterFormFragment = defineFragment({
18539
18173
  createButtonVariantField({
18540
18174
  id: "buttonVariant",
18541
18175
  label: "Button style",
18542
- defaultValue: "primary",
18543
- variants: [
18544
- {
18545
- value: "primary",
18546
- label: "Primary"
18547
- },
18548
- {
18549
- value: "secondary",
18550
- label: "Secondary"
18551
- },
18552
- {
18553
- value: "outline",
18554
- label: "Outline"
18555
- }
18556
- ]
18176
+ defaultValue: "primary"
18557
18177
  }),
18558
18178
  {
18559
18179
  id: "successMessage",
@@ -20102,7 +19722,8 @@ function postExcerpt(className) {
20102
19722
  function postReadMore() {
20103
19723
  return button({
20104
19724
  href: { $bind: { from: "post.path" } },
20105
- className: "rb-self-start"
19725
+ className: "rb-self-start",
19726
+ variantId: "ghost"
20106
19727
  }, [text({ as: "span" }, bind("content.readMoreText", { fallback: "Read more" }), when("content.readMoreText")), text({
20107
19728
  as: "span",
20108
19729
  value: "Read more"
@@ -22251,20 +21872,10 @@ function visitRichTextNode(node, allowedTokens, tokenValues) {
22251
21872
  }
22252
21873
  function interpolateRichTextTokens(value, options, context) {
22253
21874
  if (!isRecord$6(value)) return value;
22254
- const allowedTokens = new Set(options.tokens);
22255
- const tokenValues = {
21875
+ return visitRichTextNode(value, new Set(options.tokens), {
22256
21876
  year: String((/* @__PURE__ */ new Date()).getFullYear()),
22257
21877
  site_name: getSiteName(context)
22258
- };
22259
- if (isRecord$6(value.doc)) {
22260
- const nextDoc = visitRichTextNode(value.doc, allowedTokens, tokenValues);
22261
- if (nextDoc === value.doc) return value;
22262
- return {
22263
- ...value,
22264
- doc: nextDoc
22265
- };
22266
- }
22267
- return visitRichTextNode(value, allowedTokens, tokenValues);
21878
+ });
22268
21879
  }
22269
21880
  const contentTransforms = [{
22270
21881
  id: "content.interpolateRichTextTokens",
@@ -23674,31 +23285,7 @@ const featureCardsBlockDefinition = { manifest: createBlockManifest({
23674
23285
  label: "Calls to action",
23675
23286
  itemLabel: "CTA",
23676
23287
  maxItems: 1,
23677
- button: {
23678
- variants: [
23679
- {
23680
- value: "primary",
23681
- label: "Primary"
23682
- },
23683
- {
23684
- value: "secondary",
23685
- label: "Secondary"
23686
- },
23687
- {
23688
- value: "outline",
23689
- label: "Outline"
23690
- },
23691
- {
23692
- value: "ghost",
23693
- label: "Ghost"
23694
- },
23695
- {
23696
- value: "link",
23697
- label: "Link"
23698
- }
23699
- ],
23700
- defaultVariant: "ghost"
23701
- }
23288
+ button: { defaultVariant: "ghost" }
23702
23289
  })
23703
23290
  ] }
23704
23291
  },
@@ -24671,11 +24258,8 @@ const mediaSchema = z.discriminatedUnion("type", [
24671
24258
  * This module provides a single source of truth for TipTap rich text validation
24672
24259
  * across both the block-form editor and the block rendering system.
24673
24260
  *
24674
- * Format compatibility:
24675
- * - Unwrapped format (new): { type: 'doc', content: [...] }
24676
- * - Wrapped format (legacy): { doc: { type: 'doc', content: [...] } }
24677
- *
24678
- * Both formats are supported for backward compatibility during migration.
24261
+ * Rich-text fields use one canonical root shape:
24262
+ * `{ type: 'doc', content: [...] }`.
24679
24263
  */
24680
24264
  /**
24681
24265
  * TipTap document node schema (recursive structure)
@@ -24688,17 +24272,40 @@ const mediaSchema = z.discriminatedUnion("type", [
24688
24272
  * - marks: Text formatting marks (e.g., bold, italic)
24689
24273
  */
24690
24274
  const TipTapMarkSchema = z$1.object({
24691
- type: z$1.string(),
24275
+ type: z$1.string().min(1),
24692
24276
  attrs: z$1.record(z$1.string(), z$1.unknown()).optional()
24693
- });
24277
+ }).strict();
24694
24278
  const TipTapNodeSchema = z$1.lazy(() => z$1.object({
24695
- type: z$1.string(),
24279
+ type: z$1.string().min(1),
24696
24280
  content: z$1.array(TipTapNodeSchema).optional(),
24697
24281
  text: z$1.string().optional(),
24698
24282
  attrs: z$1.record(z$1.string(), z$1.unknown()).optional(),
24699
24283
  marks: z$1.array(TipTapMarkSchema).optional()
24284
+ }).strict().superRefine((node, ctx) => {
24285
+ if (node.type === "doc") ctx.addIssue({
24286
+ code: "custom",
24287
+ path: ["type"],
24288
+ message: "Document nodes are only valid at the rich-text root"
24289
+ });
24290
+ if (node.type === "text") {
24291
+ if (node.text === void 0 || node.text.length === 0) ctx.addIssue({
24292
+ code: "custom",
24293
+ path: ["text"],
24294
+ message: "Text nodes require a non-empty text value"
24295
+ });
24296
+ if (node.content !== void 0) ctx.addIssue({
24297
+ code: "custom",
24298
+ path: ["content"],
24299
+ message: "Text nodes cannot contain child nodes"
24300
+ });
24301
+ return;
24302
+ }
24303
+ if (node.text !== void 0) ctx.addIssue({
24304
+ code: "custom",
24305
+ path: ["text"],
24306
+ message: "Only text nodes can contain a text value"
24307
+ });
24700
24308
  }));
24701
- z$1.union([TipTapNodeSchema, z$1.object({ doc: TipTapNodeSchema })]);
24702
24309
  /**
24703
24310
  * Canonical schema for a TipTap rich-text document root.
24704
24311
  *
@@ -24707,13 +24314,11 @@ z$1.union([TipTapNodeSchema, z$1.object({ doc: TipTapNodeSchema })]);
24707
24314
  * (dummy content, editor output, migrations) must emit, and the shape every
24708
24315
  * non-legacy consumer can rely on.
24709
24316
  *
24710
- * Legacy envelopes are read-tolerated by {@link RichTextValueSchema} but
24711
- * normalised before reaching anywhere typed as `RichTextDoc`.
24712
24317
  */
24713
24318
  const RichTextDocSchema = z$1.object({
24714
24319
  type: z$1.literal("doc"),
24715
24320
  content: z$1.array(TipTapNodeSchema)
24716
- });
24321
+ }).strict();
24717
24322
  //#endregion
24718
24323
  //#region ../blocks/src/system/blocks/shared/bookingPaymentTerms.ts
24719
24324
  const bookingDepositRefundPolicySchema = z$1.enum(["refundable", "non_refundable"]);
@@ -25791,17 +25396,8 @@ function readAmount(value) {
25791
25396
  //#endregion
25792
25397
  //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
25793
25398
  const previewStageSchema = z$1.enum(["preview", "published"]);
25794
- const registrationButtonVariantSchema = z$1.enum([
25795
- "primary",
25796
- "secondary",
25797
- "outline"
25798
- ]);
25799
- const eventButtonVariantSchema = z$1.enum([
25800
- "primary",
25801
- "secondary",
25802
- "outline",
25803
- "link"
25804
- ]);
25399
+ const registrationButtonVariantSchema = blockButtonRoleSchema;
25400
+ const eventButtonVariantSchema = persistedBlockButtonRoleSchema;
25805
25401
  const eventLayoutSchema = z$1.enum(eventCalendarListLayoutValues);
25806
25402
  const eventCalendarDisplayModeSchema = z$1.enum(eventCalendarDisplayModeValues);
25807
25403
  const eventCalendarDefaultViewSchema = z$1.enum(eventCalendarDefaultViewValues);
@@ -26166,23 +25762,7 @@ const eventRegistrationBlockDefinition = {
26166
25762
  defaultValue: "Complete Registration",
26167
25763
  maxLength: 40
26168
25764
  },
26169
- createButtonVariantField({
26170
- description: "Choose a button style from your theme",
26171
- variants: [
26172
- {
26173
- value: "primary",
26174
- label: "Primary"
26175
- },
26176
- {
26177
- value: "secondary",
26178
- label: "Secondary"
26179
- },
26180
- {
26181
- value: "outline",
26182
- label: "Outline"
26183
- }
26184
- ]
26185
- })
25765
+ createButtonVariantField()
26186
25766
  ],
26187
25767
  layout: [styledSection({
26188
25768
  baseClass: "",
@@ -26489,23 +26069,7 @@ const courseRegistrationBlockDefinition = {
26489
26069
  defaultValue: "Sign up",
26490
26070
  maxLength: 40
26491
26071
  },
26492
- createButtonVariantField({
26493
- description: "Choose a button style from your theme",
26494
- variants: [
26495
- {
26496
- value: "primary",
26497
- label: "Primary"
26498
- },
26499
- {
26500
- value: "secondary",
26501
- label: "Secondary"
26502
- },
26503
- {
26504
- value: "outline",
26505
- label: "Outline"
26506
- }
26507
- ]
26508
- })
26072
+ createButtonVariantField()
26509
26073
  ],
26510
26074
  layout: [styledSection({
26511
26075
  baseClass: "",
@@ -29370,36 +28934,7 @@ const offeringsPreviewFields = [
29370
28934
  ui: { intent: "content" },
29371
28935
  schema: { fields: groupOverrideFields }
29372
28936
  },
29373
- {
29374
- id: "buttonVariant",
29375
- type: "select",
29376
- label: "Button style",
29377
- required: false,
29378
- multiple: false,
29379
- defaultValue: "primary",
29380
- options: [
29381
- {
29382
- value: "primary",
29383
- label: "Primary"
29384
- },
29385
- {
29386
- value: "secondary",
29387
- label: "Secondary"
29388
- },
29389
- {
29390
- value: "outline",
29391
- label: "Outline"
29392
- },
29393
- {
29394
- value: "link",
29395
- label: "Link"
29396
- }
29397
- ],
29398
- ui: {
29399
- intent: "display",
29400
- widget: "buttonVariant"
29401
- }
29402
- },
28937
+ createButtonVariantField(),
29403
28938
  {
29404
28939
  id: "buttonText",
29405
28940
  type: "text",
@@ -29605,7 +29140,7 @@ function normalizeOfferingsPreviewGroupOverride(value) {
29605
29140
  return [override];
29606
29141
  }
29607
29142
  function isButtonVariant(value) {
29608
- return value === "primary" || value === "secondary" || value === "outline" || value === "link" || value === null;
29143
+ return value === null || isBlockButtonRole(value);
29609
29144
  }
29610
29145
  function normalizeCardStylesContent(value) {
29611
29146
  return isRecord$1(value) || value === null ? value : void 0;
@@ -31457,12 +30992,7 @@ const shopSourceSchema = z$1.object({
31457
30992
  showPrices: z$1.boolean().optional(),
31458
30993
  showValidityPeriod: z$1.boolean().optional(),
31459
30994
  showPricePerCredit: z$1.boolean().nullable().optional(),
31460
- buttonVariant: z$1.enum([
31461
- "primary",
31462
- "secondary",
31463
- "outline",
31464
- "link"
31465
- ]).optional(),
30995
+ buttonVariant: blockButtonRoleSchema.optional(),
31466
30996
  passesHeading: z$1.string().optional(),
31467
30997
  membershipsHeading: z$1.string().optional(),
31468
30998
  buyButtonText: z$1.string().optional(),
@@ -31607,12 +31137,7 @@ const passesMembershipsHydrationSchema = z$1.object({
31607
31137
  passes: z$1.array(publicPassProductSchema),
31608
31138
  memberships: z$1.array(publicMembershipProductSchema),
31609
31139
  passPurchaseMode: z$1.enum(["add_to_cart", "buy_now"]),
31610
- buttonVariant: z$1.enum([
31611
- "primary",
31612
- "secondary",
31613
- "outline",
31614
- "link"
31615
- ])
31140
+ buttonVariant: blockButtonRoleSchema
31616
31141
  });
31617
31142
  const productListHydrationSchema = z$1.object({
31618
31143
  products: z$1.array(publicProductSchema),
@@ -32936,11 +32461,7 @@ const newsletterPresetSchema = z$1.enum([
32936
32461
  "emailNameCompany"
32937
32462
  ]);
32938
32463
  const newsletterDestinationProviderSchema = z$1.enum(["riverbank", "mailchimp"]);
32939
- const newsletterButtonVariantSchema = z$1.enum([
32940
- "primary",
32941
- "secondary",
32942
- "outline"
32943
- ]);
32464
+ const newsletterButtonVariantSchema = blockButtonRoleSchema;
32944
32465
  const newsletterFieldSchema = z$1.object({
32945
32466
  id: z$1.string(),
32946
32467
  type: z$1.enum(["email", "text"]),
@@ -35475,6 +34996,7 @@ const CANONICAL_REFUND_PLANNER_ERROR_CODES = [
35475
34996
  "idempotency_amount_mismatch",
35476
34997
  "idempotency_method_mismatch",
35477
34998
  "idempotency_receipt_mismatch",
34999
+ "idempotency_scope_mismatch",
35478
35000
  "refund_in_progress"
35479
35001
  ],
35480
35002
  "invalid_amount",
@@ -35861,7 +35383,7 @@ const SITE_BANNER_TONE_VALUES = [
35861
35383
  ];
35862
35384
  const siteBannerScopeSchema = z$1.enum(SITE_BANNER_SCOPE_VALUES);
35863
35385
  const siteBannerToneSchema = z$1.enum(SITE_BANNER_TONE_VALUES);
35864
- const siteBannerBodySchema = z$1.unknown().transform(unwrapRichTextValue);
35386
+ const siteBannerBodySchema = RichTextDocSchema;
35865
35387
  const siteBannerCtaSchema = z$1.object({
35866
35388
  label: z$1.string().trim().min(1),
35867
35389
  link: linkPayloadSchema
@@ -35889,7 +35411,8 @@ const EMPTY_SITE_BANNER_BODY = {
35889
35411
  }]
35890
35412
  };
35891
35413
  function analyzeSiteBannerBody(body) {
35892
- const sanitizedBody = sanitizeSiteBannerBodyInternal(body, { limitParagraphs: false });
35414
+ const parsed = RichTextDocSchema.safeParse(body);
35415
+ const sanitizedBody = parsed.success ? sanitizeSiteBannerBodyInternal(parsed.data, { limitParagraphs: false }) : EMPTY_SITE_BANNER_BODY;
35893
35416
  const paragraphs = collectParagraphs(sanitizedBody);
35894
35417
  const textLength = paragraphs.reduce((total, paragraph) => total + paragraphTextLength(paragraph), 0);
35895
35418
  const issues = [];
@@ -35911,7 +35434,7 @@ function siteBannerBodyIssueMessage(issue) {
35911
35434
  }
35912
35435
  }
35913
35436
  function sanitizeSiteBannerBodyInternal(input, options) {
35914
- const content = normalizeTopLevelNodes(unwrapRichTextValue(input).content ?? [], options);
35437
+ const content = normalizeTopLevelNodes(input.content, options);
35915
35438
  return {
35916
35439
  type: "doc",
35917
35440
  content: content.length > 0 ? content : EMPTY_SITE_BANNER_BODY.content
@@ -35992,28 +35515,6 @@ function sanitizeMarks(marks) {
35992
35515
  });
35993
35516
  return sanitized.length > 0 ? sanitized : void 0;
35994
35517
  }
35995
- function unwrapRichTextValue(value) {
35996
- if (isRecord(value) && isRecord(value.doc)) return unwrapRichTextValue(value.doc);
35997
- if (isRecord(value) && value.type === "doc") return {
35998
- type: "doc",
35999
- content: Array.isArray(value.content) ? value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) : []
36000
- };
36001
- return EMPTY_SITE_BANNER_BODY;
36002
- }
36003
- function isTipTapNodeLike(value) {
36004
- return isRecord(value) && typeof value.type === "string";
36005
- }
36006
- function coerceTipTapNode(value) {
36007
- return {
36008
- type: value.type,
36009
- ...Array.isArray(value.content) ? { content: value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) } : {},
36010
- ...typeof value.text === "string" ? { text: value.text } : {},
36011
- ...Array.isArray(value.marks) ? { marks: value.marks.filter((mark) => isRecord(mark) && typeof mark.type === "string").map((mark) => ({
36012
- type: mark.type,
36013
- ...isRecord(mark.attrs) ? { attrs: mark.attrs } : {}
36014
- })) } : {}
36015
- };
36016
- }
36017
35518
  function paragraphTextLength(paragraph) {
36018
35519
  return collectText(paragraph).length;
36019
35520
  }