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