@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
@@ -58,111 +58,6 @@ const mediaSchema = z.object({
58
58
  transform: transformSchema.optional()
59
59
  });
60
60
  //#endregion
61
- //#region ../theme-core/src/buttons/effectClassification.ts
62
- /**
63
- * Exhaustive live policy for every registered effect id.
64
- *
65
- * The resolver consumes the transition payload directly, so adding an effect
66
- * cannot update classification without also defining its runtime behavior.
67
- */
68
- const BUTTON_EFFECT_POLICIES = {
69
- "darken-background": {
70
- classification: "colour-transition",
71
- transition: {
72
- kind: "adjust-shade",
73
- direction: "darker"
74
- }
75
- },
76
- "lighten-background": {
77
- classification: "colour-transition",
78
- transition: {
79
- kind: "adjust-shade",
80
- direction: "lighter"
81
- }
82
- },
83
- "background-on-hover": {
84
- classification: "colour-transition",
85
- transition: { kind: "replace-background" }
86
- },
87
- "background-on-hover-alpha": {
88
- classification: "unsupported-colour",
89
- reason: "alpha_requires_surface"
90
- },
91
- "fade-background": {
92
- classification: "unsupported-colour",
93
- reason: "changes_element_opacity"
94
- },
95
- "opacity-reduce": {
96
- classification: "unsupported-colour",
97
- reason: "changes_element_opacity"
98
- },
99
- "gradient-text": {
100
- classification: "unsupported-colour",
101
- reason: "changes_foreground"
102
- },
103
- "text-color-change": {
104
- classification: "unsupported-colour",
105
- reason: "changes_foreground"
106
- },
107
- "border-color-change": {
108
- classification: "unsupported-colour",
109
- reason: "changes_border"
110
- },
111
- "aurora-glow": {
112
- classification: "unsupported-background-overlay",
113
- reason: "unresolved_background_overlay"
114
- },
115
- "cosmic-stardust": {
116
- classification: "unsupported-background-overlay",
117
- reason: "unresolved_background_overlay"
118
- },
119
- "gradient-border-fill": {
120
- classification: "unsupported-background-overlay",
121
- reason: "unresolved_background_overlay"
122
- },
123
- "animated-gradient-border-fill": {
124
- classification: "unsupported-background-overlay",
125
- reason: "unresolved_background_overlay"
126
- },
127
- "nav-underline": {
128
- classification: "not-button",
129
- reason: "not_button_effect"
130
- },
131
- "nav-frosted-base": {
132
- classification: "not-button",
133
- reason: "not_button_effect"
134
- },
135
- "nav-frosted-hover": {
136
- classification: "not-button",
137
- reason: "not_button_effect"
138
- },
139
- "nav-frosted-active": {
140
- classification: "not-button",
141
- reason: "not_button_effect"
142
- },
143
- "animated-gradient": { classification: "non-colour" },
144
- "border-glow": { classification: "non-colour" },
145
- "drop-shadow": { classification: "non-colour" },
146
- "inner-shadow": { classification: "non-colour" },
147
- "neumorphic-shadow": { classification: "non-colour" },
148
- "outer-glow": { classification: "non-colour" },
149
- "retro-3d-shadow": { classification: "non-colour" },
150
- "scale-up": { classification: "non-colour" },
151
- "scale-down": { classification: "non-colour" },
152
- lift: { classification: "non-colour" },
153
- "press-down": { classification: "non-colour" },
154
- pop: { classification: "non-colour" },
155
- "border-bottom-grow": { classification: "non-colour" },
156
- "sketchy-border": { classification: "non-colour" },
157
- "pulse-animation": { classification: "non-colour" }
158
- };
159
- function getButtonEffectPolicy(effectId) {
160
- return Object.prototype.hasOwnProperty.call(BUTTON_EFFECT_POLICIES, effectId) ? BUTTON_EFFECT_POLICIES[effectId] : null;
161
- }
162
- function classifyButtonEffectId(effectId) {
163
- return getButtonEffectPolicy(effectId)?.classification ?? "unknown";
164
- }
165
- //#endregion
166
61
  //#region ../theme-core/src/tokens/colorTokenParts.ts
167
62
  function parseOpacityPercent(source) {
168
63
  const trimmed = source.trim();
@@ -316,6 +211,13 @@ const VARIANT_ROLES = [
316
211
  "tertiary",
317
212
  "accent"
318
213
  ];
214
+ /**
215
+ * Canonical persisted/CSS-safe button variant identifier.
216
+ *
217
+ * IDs become class selectors, so keep the contract deliberately narrower than
218
+ * an arbitrary string and shared with every authoring/runtime boundary.
219
+ */
220
+ const buttonVariantIdSchema = z$1.string().min(1).max(50).regex(/^[a-z0-9-]+$/, "Button variant IDs may contain lowercase letters, numbers, and hyphens only");
319
221
  function parseOpaqueButtonColourToken(value) {
320
222
  const token = parseThemeColorToken(value);
321
223
  if (token === null) return null;
@@ -330,6 +232,109 @@ const opaqueButtonColourTokenSchema = themeColorTokenSchema.refine((value) => pa
330
232
  if (token === null) throw new Error("Invariant: opaque button token passed its schema");
331
233
  return token;
332
234
  });
235
+ const buttonShadeAmountSchema = z$1.number().finite().min(0).max(900).multipleOf(100);
236
+ const buttonShadowIntensitySchema = z$1.enum([
237
+ "subtle",
238
+ "medium",
239
+ "strong"
240
+ ]);
241
+ /**
242
+ * The complete persisted button-effect contract.
243
+ *
244
+ * Navigation has its own generic interactive-effect model. Button variants use
245
+ * this closed union so unsupported effect IDs, unknown option keys, and unsafe
246
+ * CSS values cannot become representable after the schema boundary.
247
+ */
248
+ const buttonEffectApplicationSchema = z$1.discriminatedUnion("effectId", [
249
+ z$1.strictObject({
250
+ effectId: z$1.literal("darken-background"),
251
+ options: z$1.strictObject({ amount: buttonShadeAmountSchema.optional() }).optional()
252
+ }),
253
+ z$1.strictObject({
254
+ effectId: z$1.literal("lighten-background"),
255
+ options: z$1.strictObject({ amount: buttonShadeAmountSchema.optional() }).optional()
256
+ }),
257
+ z$1.strictObject({
258
+ effectId: z$1.literal("background-on-hover"),
259
+ options: z$1.strictObject({ colorToken: opaqueButtonColourTokenSchema.optional() }).optional()
260
+ }),
261
+ z$1.strictObject({
262
+ effectId: z$1.literal("animated-gradient"),
263
+ options: z$1.strictObject({ direction: z$1.enum(["horizontal", "vertical"]).optional() }).optional()
264
+ }),
265
+ z$1.strictObject({
266
+ effectId: z$1.literal("drop-shadow"),
267
+ options: z$1.strictObject({ intensity: buttonShadowIntensitySchema.optional() }).optional()
268
+ }),
269
+ z$1.strictObject({
270
+ effectId: z$1.literal("inner-shadow"),
271
+ options: z$1.strictObject({}).optional()
272
+ }),
273
+ z$1.strictObject({
274
+ effectId: z$1.literal("neumorphic-shadow"),
275
+ options: z$1.strictObject({
276
+ mode: z$1.enum(["raised", "pressed"]).optional(),
277
+ intensity: buttonShadowIntensitySchema.optional()
278
+ }).optional()
279
+ }),
280
+ z$1.strictObject({
281
+ effectId: z$1.literal("retro-3d-shadow"),
282
+ options: z$1.strictObject({}).optional()
283
+ }),
284
+ z$1.strictObject({
285
+ effectId: z$1.literal("scale-up"),
286
+ options: z$1.strictObject({ scale: z$1.enum([
287
+ "1.02",
288
+ "1.03",
289
+ "1.05",
290
+ "1.10"
291
+ ]).optional() }).optional()
292
+ }),
293
+ z$1.strictObject({
294
+ effectId: z$1.literal("scale-down"),
295
+ options: z$1.strictObject({ scale: z$1.enum([
296
+ "0.90",
297
+ "0.95",
298
+ "0.97",
299
+ "0.98"
300
+ ]).optional() }).optional()
301
+ }),
302
+ z$1.strictObject({
303
+ effectId: z$1.literal("lift"),
304
+ options: z$1.strictObject({ amount: z$1.enum([
305
+ "0.25",
306
+ "0.5",
307
+ "1"
308
+ ]).optional() }).optional()
309
+ }),
310
+ z$1.strictObject({
311
+ effectId: z$1.literal("press-down"),
312
+ options: z$1.strictObject({}).optional()
313
+ }),
314
+ z$1.strictObject({
315
+ effectId: z$1.literal("pop"),
316
+ options: z$1.strictObject({ intensity: z$1.enum([
317
+ "subtle",
318
+ "medium",
319
+ "dramatic"
320
+ ]).optional() }).optional()
321
+ }),
322
+ z$1.strictObject({
323
+ effectId: z$1.literal("border-bottom-grow"),
324
+ options: z$1.strictObject({
325
+ height: z$1.union([z$1.literal(1), z$1.literal(2)]).optional(),
326
+ origin: z$1.enum([
327
+ "left",
328
+ "center",
329
+ "right"
330
+ ]).optional()
331
+ }).optional()
332
+ }),
333
+ z$1.strictObject({
334
+ effectId: z$1.literal("sketchy-border"),
335
+ options: z$1.strictObject({ intensity: buttonShadowIntensitySchema.optional() }).optional()
336
+ })
337
+ ]);
333
338
  const cornerStyleSchema = z$1.enum([
334
339
  "square",
335
340
  "rounded",
@@ -364,13 +369,7 @@ const hoverTransformSchema = z$1.enum([
364
369
  "scale",
365
370
  "press"
366
371
  ]);
367
- const hoverColorSchema = z$1.enum([
368
- "none",
369
- "brighten",
370
- "darken",
371
- "saturate",
372
- "token"
373
- ]);
372
+ z$1.enum(["none", "token"]);
374
373
  const buttonPaddingPresetSchema = z$1.enum([
375
374
  "compact",
376
375
  "default",
@@ -431,7 +430,7 @@ const buttonSizesSchema = z$1.object({
431
430
  lg,
432
431
  xl: xl ?? lg
433
432
  }));
434
- const canonicalButtonGlobalSettingsSchema = z$1.object({
433
+ const buttonGlobalSettingsBaseSchema = z$1.strictObject({
435
434
  cornerStyle: cornerStyleSchema,
436
435
  cornerRadius: z$1.number().min(0).max(24).optional(),
437
436
  /**
@@ -444,30 +443,23 @@ const canonicalButtonGlobalSettingsSchema = z$1.object({
444
443
  shadow: shadowSizeSchema.optional(),
445
444
  textTransform: textTransformSchema,
446
445
  fontWeight: fontWeightSchema,
447
- /**
448
- * @deprecated Set per-variant via `variant.border.widthClass` instead.
449
- * Schema field is preserved so existing presets parse; the value is unread
450
- * by the current generator and will be removed once the legacy
451
- * `primitives/content/components/Button.tsx` slot exports are deleted.
452
- */
453
- borderWidth: z$1.union([
454
- z$1.literal(1),
455
- z$1.literal(2),
456
- z$1.literal(3)
457
- ]),
458
446
  typography: buttonTypographySchema.optional(),
459
447
  fontSize: z$1.string().optional(),
460
448
  letterSpacing: letterSpacingSchema.optional(),
461
449
  italic: z$1.boolean().optional(),
462
450
  paddingPreset: buttonPaddingPresetSchema.optional(),
463
451
  hoverTransform: hoverTransformSchema,
464
- hoverColor: hoverColorSchema,
465
- hoverColorToken: opaqueButtonColourTokenSchema.optional(),
466
452
  gradientStyle: gradientStyleSchema.optional(),
467
453
  gradientAngle: z$1.number().min(0).max(360).optional(),
468
454
  gradientSharpness: gradientSharpnessSchema.optional()
469
455
  });
470
- const buttonGlobalSettingsSchema = z$1.preprocess(normalizeLegacyButtonGlobalInput, canonicalButtonGlobalSettingsSchema);
456
+ const buttonGlobalSettingsSchema = z$1.discriminatedUnion("hoverColor", [buttonGlobalSettingsBaseSchema.extend({
457
+ hoverColor: z$1.literal("none"),
458
+ hoverColorToken: z$1.never().optional()
459
+ }), buttonGlobalSettingsBaseSchema.extend({
460
+ hoverColor: z$1.literal("token"),
461
+ hoverColorToken: opaqueButtonColourTokenSchema
462
+ })]);
471
463
  const gradientDirectionSchema$1 = z$1.enum([
472
464
  "to-r",
473
465
  "to-l",
@@ -478,12 +470,12 @@ const gradientDirectionSchema$1 = z$1.enum([
478
470
  "to-br",
479
471
  "to-bl"
480
472
  ]);
481
- const buttonBackgroundSchema = z$1.discriminatedUnion("type", [
482
- z$1.object({
473
+ const buttonColourTreatmentSchema = z$1.discriminatedUnion("type", [
474
+ z$1.strictObject({
483
475
  type: z$1.literal("solid"),
484
476
  colorToken: opaqueButtonColourTokenSchema
485
477
  }),
486
- z$1.object({
478
+ z$1.strictObject({
487
479
  type: z$1.literal("gradient"),
488
480
  stops: z$1.array(opaqueButtonColourTokenSchema).min(2).transform((stops) => {
489
481
  const [first, second, ...rest] = stops;
@@ -497,18 +489,15 @@ const buttonBackgroundSchema = z$1.discriminatedUnion("type", [
497
489
  direction: gradientDirectionSchema$1,
498
490
  foregroundToken: opaqueButtonColourTokenSchema
499
491
  }),
500
- z$1.object({
492
+ z$1.strictObject({
501
493
  type: z$1.literal("surface"),
502
494
  role: z$1.literal("link")
503
495
  })
504
496
  ]);
505
- const effectApplicationSchema$1 = z$1.object({
506
- effectId: z$1.string(),
507
- options: z$1.record(z$1.string(), z$1.json()).optional()
508
- });
509
- const buttonBorderSchema = z$1.object({ widthClass: z$1.string() });
510
- const buttonVariantAffordanceSchema = z$1.object({ iconId: z$1.string().min(1) });
511
- const variantShadowSchema = z$1.object({
497
+ const buttonBackgroundSchema = buttonColourTreatmentSchema;
498
+ const buttonBorderSchema = z$1.strictObject({ widthClass: z$1.string() });
499
+ const buttonVariantAffordanceSchema = z$1.strictObject({ iconId: z$1.string().min(1) });
500
+ const variantShadowSchema = z$1.strictObject({
512
501
  elevation: z$1.enum([
513
502
  "none",
514
503
  "low",
@@ -521,13 +510,13 @@ const variantShadowSchema = z$1.object({
521
510
  "hard"
522
511
  ]).nullable(),
523
512
  position: z$1.enum(["bottom", "bottom-right"]).default("bottom"),
524
- colorToken: themeColorTokenSchema.optional()
513
+ colorToken: opaqueButtonColourTokenSchema.optional()
525
514
  });
526
- const variantEffectsSchema = z$1.object({
527
- base: z$1.array(effectApplicationSchema$1).optional(),
528
- hover: z$1.array(effectApplicationSchema$1).optional(),
529
- active: z$1.array(effectApplicationSchema$1).optional(),
530
- focus: z$1.array(effectApplicationSchema$1).optional()
515
+ const variantEffectsSchema = z$1.strictObject({
516
+ base: z$1.array(buttonEffectApplicationSchema).optional(),
517
+ hover: z$1.array(buttonEffectApplicationSchema).optional(),
518
+ active: z$1.array(buttonEffectApplicationSchema).optional(),
519
+ focus: z$1.array(buttonEffectApplicationSchema).optional()
531
520
  });
532
521
  /**
533
522
  * Per-variant size overrides schema — every entry is optional.
@@ -548,8 +537,8 @@ const variantSizeOverridesSchema = z$1.object({
548
537
  * default (e.g. link-style variants declaring zero horizontal padding at
549
538
  * every size).
550
539
  */
551
- const canonicalButtonVariantSchema = z$1.object({
552
- id: z$1.string(),
540
+ const buttonVariantSchema = z$1.strictObject({
541
+ id: buttonVariantIdSchema,
553
542
  name: z$1.string().min(1).max(20),
554
543
  enabled: z$1.boolean(),
555
544
  priority: prioritySchema,
@@ -563,176 +552,25 @@ const canonicalButtonVariantSchema = z$1.object({
563
552
  sizes: variantSizeOverridesSchema.optional(),
564
553
  affordance: buttonVariantAffordanceSchema.optional()
565
554
  });
566
- /**
567
- * Temporary persisted-theme admission boundary for issue #1206.
568
- *
569
- * Production inventory on 2026-07-22 found 22 rows using the old independent
570
- * `textColorToken`/border colour shape. New source and all downstream code use
571
- * only the canonical relationship. Delete this preprocessor after the reviewed
572
- * production rewrite reports zero legacy rows.
573
- */
574
- const buttonVariantSchema = z$1.preprocess(normalizeLegacyButtonVariantInput, canonicalButtonVariantSchema);
575
- const buttonSystemSchema = z$1.object({
555
+ const buttonSystemSchema = z$1.strictObject({
576
556
  global: buttonGlobalSettingsSchema,
577
557
  variants: z$1.array(buttonVariantSchema).min(1).max(6),
578
558
  sizes: buttonSizesSchema.optional()
579
- });
580
- function normalizeLegacyButtonVariantInput(input) {
581
- if (!isUnknownRecord(input)) return input;
582
- const background = input.background;
583
- if (!isUnknownRecord(background)) return input;
584
- 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;
585
- const { textColorToken, ...withoutLegacyText } = input;
586
- const normalizedBorder = isUnknownRecord(input.border) && typeof input.border.widthClass === "string" ? { widthClass: input.border.widthClass } : input.border;
587
- const normalizedAffordance = isUnknownRecord(input.affordance) && typeof input.affordance.iconId === "string" ? { iconId: input.affordance.iconId } : input.affordance;
588
- const normalizedEffects = normalizeLegacyButtonEffects(input.effects, background.type);
589
- const hoverBackgroundToken = stripLegacyTokenAlpha(input.hoverBackgroundToken);
590
- if (background.type === "transparent") return {
591
- ...withoutLegacyText,
592
- background: {
593
- type: "surface",
594
- role: "link"
595
- },
596
- border: normalizedBorder,
597
- affordance: normalizedAffordance,
598
- effects: normalizedEffects,
599
- hoverBackgroundToken
600
- };
601
- if (background.type === "gradient") {
602
- const stops = Array.isArray(background.stops) ? background.stops.map(stripLegacyTokenAlpha) : background.stops;
603
- return {
604
- ...withoutLegacyText,
605
- background: {
606
- ...background,
607
- stops,
608
- foregroundToken: stripLegacyTokenAlpha(background.foregroundToken ?? textColorToken)
609
- },
610
- border: normalizedBorder,
611
- affordance: normalizedAffordance,
612
- effects: normalizedEffects,
613
- hoverBackgroundToken
614
- };
615
- }
616
- return {
617
- ...withoutLegacyText,
618
- background: background.type === "solid" ? {
619
- ...background,
620
- colorToken: stripLegacyTokenAlpha(background.colorToken)
621
- } : background,
622
- border: normalizedBorder,
623
- affordance: normalizedAffordance,
624
- effects: normalizedEffects,
625
- hoverBackgroundToken
626
- };
627
- }
628
- function normalizeLegacyButtonGlobalInput(input) {
629
- if (!isUnknownRecord(input)) return input;
630
- const hoverColorToken = stripLegacyTokenAlpha(input.hoverColorToken);
631
- return hoverColorToken === input.hoverColorToken ? input : {
632
- ...input,
633
- hoverColorToken
634
- };
635
- }
636
- function hasLegacyAlphaToken(input, background) {
637
- const stops = isUnknownArray(background.stops) ? background.stops : [];
638
- return [
639
- input.hoverBackgroundToken,
640
- background.colorToken,
641
- background.foregroundToken,
642
- ...stops
643
- ].some((token) => stripLegacyTokenAlpha(token) !== token);
644
- }
645
- function stripLegacyTokenAlpha(value) {
646
- if (typeof value !== "string") return value;
647
- const slashIndex = value.indexOf("/");
648
- return slashIndex < 0 ? value : value.slice(0, slashIndex);
649
- }
650
- function hasLegacyButtonEffects(input) {
651
- if (!isUnknownRecord(input)) return false;
652
- return [
653
- "base",
654
- "hover",
655
- "active",
656
- "focus"
657
- ].some((state) => {
658
- const effects = input[state];
659
- return Array.isArray(effects) && effects.some((effect) => {
660
- if (!isUnknownRecord(effect) || typeof effect.effectId !== "string") return true;
661
- const classification = classifyButtonEffectId(effect.effectId);
662
- if (classification !== "colour-transition" && classification !== "non-colour") return true;
663
- return effect.effectId === "background-on-hover" && isUnknownRecord(effect.options) && stripLegacyTokenAlpha(effect.options.colorToken) !== effect.options.colorToken;
559
+ }).superRefine((system, ctx) => {
560
+ const seen = /* @__PURE__ */ new Set();
561
+ system.variants.forEach((variant, index) => {
562
+ if (seen.has(variant.id)) ctx.addIssue({
563
+ code: "custom",
564
+ path: [
565
+ "variants",
566
+ index,
567
+ "id"
568
+ ],
569
+ message: `Duplicate button variant ID: ${variant.id}`
664
570
  });
571
+ seen.add(variant.id);
665
572
  });
666
- }
667
- function normalizeLegacyButtonEffects(input, backgroundType) {
668
- if (!isUnknownRecord(input)) return input;
669
- const normalized = {};
670
- for (const state of [
671
- "base",
672
- "hover",
673
- "active",
674
- "focus"
675
- ]) {
676
- const effects = input[state];
677
- if (!Array.isArray(effects)) continue;
678
- const safeEffects = effects.flatMap((effect) => {
679
- if (!isUnknownRecord(effect) || typeof effect.effectId !== "string") return [];
680
- const classification = classifyButtonEffectId(effect.effectId);
681
- if (classification === "non-colour") return [effect];
682
- if (classification !== "colour-transition") return [];
683
- if (effect.effectId === "background-on-hover") {
684
- const options = isUnknownRecord(effect.options) ? effect.options : null;
685
- const colorToken = options === null ? null : parseOpaqueButtonColourToken(stripLegacyTokenAlpha(options.colorToken));
686
- return colorToken === null ? [] : [{
687
- ...effect,
688
- options: {
689
- ...options,
690
- colorToken
691
- }
692
- }];
693
- }
694
- if (backgroundType !== "solid") return [];
695
- const rawAmount = isUnknownRecord(effect.options) ? effect.options.amount : void 0;
696
- const amount = typeof rawAmount === "number" && rawAmount > 0 ? Math.max(100, Math.round(rawAmount / 100) * 100) : 100;
697
- return [{
698
- ...effect,
699
- options: {
700
- ...isUnknownRecord(effect.options) ? effect.options : {},
701
- amount
702
- }
703
- }];
704
- });
705
- if (safeEffects.length > 0) normalized[state] = safeEffects;
706
- }
707
- return Object.keys(normalized).length === 0 ? void 0 : normalized;
708
- }
709
- function isUnknownRecord(value) {
710
- return typeof value === "object" && value !== null && !Array.isArray(value);
711
- }
712
- function isUnknownArray(value) {
713
- return Array.isArray(value);
714
- }
715
- //#endregion
716
- //#region ../theme-core/src/buttons/constants.ts
717
- /**
718
- * Shared constants for button CSS generation
719
- *
720
- * These mappings convert Tailwind-style tokens to actual CSS values.
721
- * Centralized here to eliminate duplication across multiple files.
722
- */
723
- /**
724
- * Map Tailwind-style gradient direction tokens to CSS gradient directions
725
- */
726
- const GRADIENT_DIRECTION_MAP$1 = {
727
- "to-r": "to right",
728
- "to-l": "to left",
729
- "to-t": "to top",
730
- "to-b": "to bottom",
731
- "to-br": "to bottom right",
732
- "to-bl": "to bottom left",
733
- "to-tr": "to top right",
734
- "to-tl": "to top left"
735
- };
573
+ });
736
574
  //#endregion
737
575
  //#region ../theme-core/src/palette/utils/colorConversion.ts
738
576
  function hexToRgb(hex) {
@@ -876,42 +714,184 @@ function surfaceForegroundDeclarations(input) {
876
714
  return [`color: ${foregrounds.text}`, ...SURFACE_FOREGROUND_ROLES.map((role) => `${SURFACE_FOREGROUND_CSS_VARS[role]}: ${foregrounds[role]}`)];
877
715
  }
878
716
  //#endregion
879
- //#region ../theme-core/src/buttons/resolveButtonColourStates.ts
880
- const BUTTON_VISUAL_STATES = [
881
- "base",
882
- "hover",
883
- "focus",
884
- "active",
885
- "disabled"
886
- ];
887
- const BUTTON_CONTRAST_POLICY = {
888
- textMinimumRatio: 4.5,
889
- nonTextMinimumRatio: 3,
890
- gradientSamplesPerSegment: 20,
891
- alphaBackgrounds: "reject-without-known-surface",
892
- disabled: "retain-full-colour-contract"
717
+ //#region ../theme-core/src/buttons/constants.ts
718
+ /**
719
+ * Shared constants for button CSS generation
720
+ *
721
+ * These mappings convert Tailwind-style tokens to actual CSS values.
722
+ * Centralized here to eliminate duplication across multiple files.
723
+ */
724
+ /**
725
+ * Map Tailwind-style gradient direction tokens to CSS gradient directions
726
+ */
727
+ const GRADIENT_DIRECTION_MAP$1 = {
728
+ "to-r": "to right",
729
+ "to-l": "to left",
730
+ "to-t": "to top",
731
+ "to-b": "to bottom",
732
+ "to-br": "to bottom right",
733
+ "to-bl": "to bottom left",
734
+ "to-tr": "to top right",
735
+ "to-tl": "to top left"
893
736
  };
894
- function compileButtonColourStates(input) {
895
- const baseTransition = applyColourEffects({
896
- variantId: input.variant.id,
897
- state: "base",
898
- treatment: input.variant.background,
899
- effects: input.variant.effects?.base,
900
- palette: input.palette
901
- });
902
- if (!baseTransition.ok) return baseTransition;
903
- const stateTreatments = {
904
- base: baseTransition.treatment,
905
- hover: hoverTreatment(input.variant, input.global, baseTransition.treatment),
906
- focus: baseTransition.treatment,
907
- active: baseTransition.treatment,
908
- disabled: baseTransition.treatment
909
- };
910
- const nonColourEffects = { ...baseTransition.nonColourEffects.length > 0 ? { base: [...baseTransition.nonColourEffects] } : {} };
911
- for (const state of [
912
- "hover",
913
- "focus",
914
- "active"
737
+ //#endregion
738
+ //#region ../theme-core/src/buttons/effectClassification.ts
739
+ /**
740
+ * Exhaustive live policy for every registered effect id.
741
+ *
742
+ * The resolver consumes the transition payload directly, so adding an effect
743
+ * cannot update classification without also defining its runtime behavior.
744
+ */
745
+ const BUTTON_EFFECT_POLICIES = {
746
+ "darken-background": {
747
+ classification: "colour-transition",
748
+ transition: {
749
+ kind: "adjust-shade",
750
+ direction: "darker"
751
+ }
752
+ },
753
+ "lighten-background": {
754
+ classification: "colour-transition",
755
+ transition: {
756
+ kind: "adjust-shade",
757
+ direction: "lighter"
758
+ }
759
+ },
760
+ "background-on-hover": {
761
+ classification: "colour-transition",
762
+ transition: { kind: "replace-background" }
763
+ },
764
+ "background-on-hover-alpha": {
765
+ classification: "unsupported-colour",
766
+ reason: "alpha_requires_surface"
767
+ },
768
+ "fade-background": {
769
+ classification: "unsupported-colour",
770
+ reason: "changes_element_opacity"
771
+ },
772
+ "opacity-reduce": {
773
+ classification: "unsupported-colour",
774
+ reason: "changes_element_opacity"
775
+ },
776
+ "gradient-text": {
777
+ classification: "unsupported-colour",
778
+ reason: "changes_foreground"
779
+ },
780
+ "text-color-change": {
781
+ classification: "unsupported-colour",
782
+ reason: "changes_foreground"
783
+ },
784
+ "border-color-change": {
785
+ classification: "unsupported-colour",
786
+ reason: "changes_border"
787
+ },
788
+ "aurora-glow": {
789
+ classification: "unsupported-background-overlay",
790
+ reason: "unresolved_background_overlay"
791
+ },
792
+ "cosmic-stardust": {
793
+ classification: "unsupported-background-overlay",
794
+ reason: "unresolved_background_overlay"
795
+ },
796
+ "gradient-border-fill": {
797
+ classification: "unsupported-background-overlay",
798
+ reason: "unresolved_background_overlay"
799
+ },
800
+ "animated-gradient-border-fill": {
801
+ classification: "unsupported-background-overlay",
802
+ reason: "unresolved_background_overlay"
803
+ },
804
+ "nav-underline": {
805
+ classification: "not-button",
806
+ reason: "not_button_effect"
807
+ },
808
+ "nav-frosted-base": {
809
+ classification: "not-button",
810
+ reason: "not_button_effect"
811
+ },
812
+ "nav-frosted-hover": {
813
+ classification: "not-button",
814
+ reason: "not_button_effect"
815
+ },
816
+ "nav-frosted-active": {
817
+ classification: "not-button",
818
+ reason: "not_button_effect"
819
+ },
820
+ "animated-gradient": { classification: "non-colour" },
821
+ "border-glow": {
822
+ classification: "unsupported-colour",
823
+ reason: "changes_shadow_colour"
824
+ },
825
+ "drop-shadow": { classification: "decorative-colour" },
826
+ "inner-shadow": { classification: "decorative-colour" },
827
+ "neumorphic-shadow": { classification: "decorative-colour" },
828
+ "outer-glow": {
829
+ classification: "unsupported-colour",
830
+ reason: "changes_shadow_colour"
831
+ },
832
+ "retro-3d-shadow": { classification: "decorative-colour" },
833
+ "scale-up": { classification: "non-colour" },
834
+ "scale-down": { classification: "non-colour" },
835
+ lift: { classification: "non-colour" },
836
+ "press-down": { classification: "non-colour" },
837
+ pop: { classification: "non-colour" },
838
+ "border-bottom-grow": { classification: "non-colour" },
839
+ "sketchy-border": { classification: "decorative-colour" },
840
+ "pulse-animation": {
841
+ classification: "unsupported-colour",
842
+ reason: "changes_element_opacity"
843
+ }
844
+ };
845
+ function validateButtonEffectOptions(effect) {
846
+ const parsed = buttonEffectApplicationSchema.safeParse(effect);
847
+ if (parsed.success) return { ok: true };
848
+ const firstIssue = parsed.error.issues[0];
849
+ const firstPathPart = firstIssue?.path[firstIssue.path.length - 1];
850
+ return {
851
+ ok: false,
852
+ option: (firstIssue?.code === "unrecognized_keys" ? firstIssue.keys[0] : void 0) ?? (typeof firstPathPart === "string" ? firstPathPart : "options")
853
+ };
854
+ }
855
+ function getButtonEffectPolicy(effectId) {
856
+ return Object.prototype.hasOwnProperty.call(BUTTON_EFFECT_POLICIES, effectId) ? BUTTON_EFFECT_POLICIES[effectId] : null;
857
+ }
858
+ //#endregion
859
+ //#region ../theme-core/src/buttons/resolveButtonColourStates.ts
860
+ const BUTTON_VISUAL_STATES = [
861
+ "base",
862
+ "hover",
863
+ "focus",
864
+ "active",
865
+ "disabled"
866
+ ];
867
+ const BUTTON_CONTRAST_POLICY = {
868
+ textMinimumRatio: 4.5,
869
+ nonTextMinimumRatio: 3,
870
+ gradientSamplesPerSegment: 20,
871
+ alphaBackgrounds: "reject-without-known-surface",
872
+ disabled: "retain-full-colour-contract"
873
+ };
874
+ function compileButtonColourStates(input) {
875
+ const baseTransition = applyColourEffects({
876
+ variantId: input.variant.id,
877
+ state: "base",
878
+ treatment: input.variant.background,
879
+ effects: input.variant.effects?.base,
880
+ palette: input.palette
881
+ });
882
+ if (!baseTransition.ok) return baseTransition;
883
+ const stateTreatments = {
884
+ base: baseTransition.treatment,
885
+ hover: hoverTreatment(input.variant, input.global, baseTransition.treatment),
886
+ focus: baseTransition.treatment,
887
+ active: baseTransition.treatment,
888
+ disabled: baseTransition.treatment
889
+ };
890
+ const nonColourEffects = { ...baseTransition.nonColourEffects.length > 0 ? { base: [...baseTransition.nonColourEffects] } : {} };
891
+ for (const state of [
892
+ "hover",
893
+ "focus",
894
+ "active"
915
895
  ]) {
916
896
  const transition = applyColourEffects({
917
897
  variantId: input.variant.id,
@@ -966,15 +946,17 @@ function applyColourEffects(input) {
966
946
  for (const effect of input.effects ?? []) {
967
947
  const policy = getButtonEffectPolicy(effect.effectId);
968
948
  if (policy === null) return unknownEffect(input, effect);
949
+ if (policy.classification === "unsupported-colour" || policy.classification === "unsupported-background-overlay" || policy.classification === "not-button") return unsupportedEffect(input, effect, policy.reason);
950
+ const options = validateButtonEffectOptions(effect);
951
+ if (!options.ok) return invalidEffectOption(input, effect, options.option);
969
952
  switch (policy.classification) {
970
953
  case "non-colour":
954
+ case "decorative-colour":
971
955
  nonColourEffects.push(effect);
972
956
  break;
973
- case "unsupported-colour":
974
- case "unsupported-background-overlay":
975
- case "not-button": return unsupportedEffect(input, effect, policy.reason);
976
957
  case "colour-transition":
977
958
  if (policy.transition.kind === "adjust-shade") {
959
+ if (effect.effectId !== "darken-background" && effect.effectId !== "lighten-background") return unknownEffect(input, effect);
978
960
  if (treatment.type !== "solid") return inapplicableEffect(input, effect, treatment);
979
961
  const amount = readShadeAmount(effect);
980
962
  if (amount === null) return invalidEffectOption(input, effect, "amount");
@@ -986,7 +968,8 @@ function applyColourEffects(input) {
986
968
  break;
987
969
  }
988
970
  if (policy.transition.kind === "replace-background") {
989
- const colorToken = readOpaqueToken(effect, "colorToken", "neutral-800");
971
+ if (effect.effectId !== "background-on-hover") return unknownEffect(input, effect);
972
+ const colorToken = readOpaqueToken(effect);
990
973
  if (colorToken === null) return invalidEffectOption(input, effect, "colorToken");
991
974
  treatment = {
992
975
  type: "solid",
@@ -1178,8 +1161,8 @@ function readShadeAmount(effect) {
1178
1161
  const value = effect.options?.amount ?? 100;
1179
1162
  return typeof value === "number" && Number.isFinite(value) && value >= 0 && value % 100 === 0 ? value : null;
1180
1163
  }
1181
- function readOpaqueToken(effect, key, fallback) {
1182
- return parseOpaqueButtonColourToken(effect.options?.[key] ?? fallback);
1164
+ function readOpaqueToken(effect) {
1165
+ return parseOpaqueButtonColourToken(effect.options?.colorToken ?? "neutral-800");
1183
1166
  }
1184
1167
  function unsupportedEffect(input, effect, reason) {
1185
1168
  return {
@@ -1282,304 +1265,429 @@ const RESOLVED_BUTTON_DISABLED_DECLARATIONS = [
1282
1265
  ];
1283
1266
  buttonSizeNameSchema.options;
1284
1267
  //#endregion
1285
- //#region ../theme-core/src/site-styles/styleTags.ts
1286
- /**
1287
- * Descriptive style-axis metadata for button personalities and palette
1288
- * variants. Site Style picker shape is curated explicitly; these tags remain
1289
- * for catalog audit, docs, and future discovery tooling.
1290
- */
1291
- const STYLE_AXIS_VALUES = {
1292
- tone: [
1293
- "minimal",
1294
- "classic",
1295
- "bold"
1296
- ],
1297
- energy: ["calm", "vibrant"],
1298
- motion: [
1299
- "subtle",
1300
- "standard",
1301
- "expressive"
1302
- ],
1303
- era: [
1304
- "editorial",
1305
- "modern",
1306
- "organic",
1307
- "technical",
1308
- "retro"
1309
- ]
1310
- };
1311
- const styleTagsSchema = z$1.object({
1312
- tone: z$1.enum(STYLE_AXIS_VALUES.tone).optional(),
1313
- energy: z$1.enum(STYLE_AXIS_VALUES.energy).optional(),
1314
- motion: z$1.enum(STYLE_AXIS_VALUES.motion).optional(),
1315
- era: z$1.enum(STYLE_AXIS_VALUES.era).optional()
1316
- });
1317
- //#endregion
1318
- //#region ../theme-core/src/buttons/personalities/types.ts
1319
- function asButtonPersonalityId(value) {
1320
- if (value.length === 0) throw new Error("ButtonPersonalityId must be a non-empty string");
1321
- return value;
1268
+ //#region ../theme-core/src/buttons/styles/domain.ts
1269
+ const PUBLIC_BUTTON_ROLES = [
1270
+ "primary",
1271
+ "secondary",
1272
+ "outline",
1273
+ "ghost",
1274
+ "accent"
1275
+ ];
1276
+ function defineButtonStyleRecipe(recipe) {
1277
+ return recipe;
1278
+ }
1279
+ function materializeButtonRoles(definitions) {
1280
+ const primary = materializeCompleteRole("primary", definitions.primary.appearance);
1281
+ const secondary = materializeCompleteRole("secondary", definitions.secondary.appearance);
1282
+ const completeRoles = {
1283
+ primary,
1284
+ secondary
1285
+ };
1286
+ return {
1287
+ primary,
1288
+ secondary,
1289
+ outline: materializeSupportingRole("outline", definitions.outline, completeRoles),
1290
+ ghost: materializeSupportingRole("ghost", definitions.ghost, completeRoles),
1291
+ accent: materializeSupportingRole("accent", definitions.accent, completeRoles)
1292
+ };
1322
1293
  }
1323
- const buttonPersonalityIdSchema = z$1.string().min(1).transform((value) => asButtonPersonalityId(value));
1324
- z$1.object({
1325
- id: buttonPersonalityIdSchema,
1326
- name: z$1.string().min(1),
1327
- description: z$1.string().min(1),
1328
- tags: styleTagsSchema,
1329
- buttonSystem: buttonSystemSchema
1330
- });
1331
- /**
1332
- * Helper for personality file modules to keep the call site short and
1333
- * type-safe. `as const satisfies ...` would also work but produces wider
1334
- * types at use sites.
1335
- */
1336
- function defineButtonPersonality(input) {
1294
+ function resolveButtonStyleRecipe(recipe, parameters) {
1295
+ const parsedParameters = recipe.parameterSchema.safeParse(parameters);
1296
+ if (!parsedParameters.success) return {
1297
+ kind: "error",
1298
+ error: {
1299
+ kind: "invalid-parameters",
1300
+ styleId: recipe.id,
1301
+ issues: parsedParameters.error.issues.map((issue) => issue.message)
1302
+ }
1303
+ };
1304
+ const definition = recipe.defineSystem(parsedParameters.data);
1305
+ const roles = materializeButtonRoles(definition.roles);
1306
+ const buttonSystem = {
1307
+ global: definition.global,
1308
+ variants: PUBLIC_BUTTON_ROLES.map((role) => roles[role]),
1309
+ ...definition.sizes ? { sizes: definition.sizes } : {}
1310
+ };
1311
+ const parsedButtonSystem = buttonSystemSchema.safeParse(buttonSystem);
1312
+ if (!parsedButtonSystem.success) return {
1313
+ kind: "error",
1314
+ error: {
1315
+ kind: "invalid-button-system",
1316
+ styleId: recipe.id,
1317
+ issues: parsedButtonSystem.error.issues.map((issue) => issue.message)
1318
+ }
1319
+ };
1337
1320
  return {
1338
- id: asButtonPersonalityId(input.id),
1339
- name: input.name,
1340
- description: input.description,
1341
- tags: input.tags,
1342
- buttonSystem: buttonSystemSchema.parse(input.buttonSystem)
1321
+ kind: "resolved",
1322
+ buttonSystem: parsedButtonSystem.data
1323
+ };
1324
+ }
1325
+ function materializeSupportingRole(role, definition, completeRoles) {
1326
+ if (definition.kind === "complete") return materializeCompleteRole(role, definition.appearance);
1327
+ return {
1328
+ ...completeRoles[definition.from],
1329
+ ...definition.overrides,
1330
+ id: role,
1331
+ name: roleName(role),
1332
+ enabled: true,
1333
+ priority: 3
1334
+ };
1335
+ }
1336
+ function materializeCompleteRole(role, appearance) {
1337
+ return {
1338
+ ...appearance,
1339
+ id: role,
1340
+ name: roleName(role),
1341
+ enabled: true,
1342
+ priority: rolePriority(role)
1343
1343
  };
1344
1344
  }
1345
+ function roleName(role) {
1346
+ return role.charAt(0).toUpperCase() + role.slice(1);
1347
+ }
1348
+ function rolePriority(role) {
1349
+ if (role === "primary") return 1;
1350
+ if (role === "secondary") return 2;
1351
+ return 3;
1352
+ }
1345
1353
  //#endregion
1346
- //#region ../theme-core/src/buttons/personalities/brushed-wash.ts
1347
- /**
1348
- * Brushed Wash — gradient backgrounds that read as watercolour washes.
1349
- * Generous padding, soft shadows; pairs with vibrant organic brands.
1350
- */
1351
- const brushedWash = defineButtonPersonality({
1352
- id: "brushed-wash",
1353
- name: "Brushed Wash",
1354
- description: "Watercolour-gradient buttons with soft shadows and generous padding.",
1354
+ //#region ../theme-core/src/buttons/styles/selection.ts
1355
+ const BUTTON_STYLE_IDS = [
1356
+ "soft-pill",
1357
+ "earth-pill",
1358
+ "confident-chip",
1359
+ "editorial-link",
1360
+ "pebble",
1361
+ "ink-stamp",
1362
+ "flat-ink",
1363
+ "brushed-wash",
1364
+ "showtime-pill",
1365
+ "joy-stamp",
1366
+ "ornate-ritual",
1367
+ "quiet-arrow"
1368
+ ];
1369
+ const quietArrowParametersSchema = z$1.object({ secondaryTreatment: z$1.enum(["outlined", "solid-accent"]) }).strict();
1370
+ const emptyParametersSchema$1 = z$1.object({}).strict();
1371
+ function selectionBranch(styleId, parameters) {
1372
+ return z$1.object({
1373
+ styleId: z$1.literal(styleId),
1374
+ parameters
1375
+ }).strict();
1376
+ }
1377
+ const buttonStyleSelectionSchema = z$1.discriminatedUnion("styleId", [
1378
+ selectionBranch("soft-pill", emptyParametersSchema$1),
1379
+ selectionBranch("earth-pill", emptyParametersSchema$1),
1380
+ selectionBranch("confident-chip", emptyParametersSchema$1),
1381
+ selectionBranch("editorial-link", emptyParametersSchema$1),
1382
+ selectionBranch("pebble", emptyParametersSchema$1),
1383
+ selectionBranch("ink-stamp", emptyParametersSchema$1),
1384
+ selectionBranch("flat-ink", emptyParametersSchema$1),
1385
+ selectionBranch("brushed-wash", emptyParametersSchema$1),
1386
+ selectionBranch("showtime-pill", emptyParametersSchema$1),
1387
+ selectionBranch("joy-stamp", emptyParametersSchema$1),
1388
+ selectionBranch("ornate-ritual", emptyParametersSchema$1),
1389
+ selectionBranch("quiet-arrow", quietArrowParametersSchema)
1390
+ ]);
1391
+ //#endregion
1392
+ //#region ../theme-core/src/buttons/styles/recipes/quietArrow.ts
1393
+ const quietArrowRecipe = defineButtonStyleRecipe({
1394
+ id: "quiet-arrow",
1395
+ accessibilityLabel: "Wide uppercase buttons with trailing arrows",
1355
1396
  tags: {
1356
1397
  tone: "classic",
1357
- energy: "vibrant",
1358
- motion: "standard",
1359
- era: "organic"
1398
+ energy: "calm",
1399
+ motion: "subtle",
1400
+ era: "editorial"
1360
1401
  },
1361
- buttonSystem: {
1402
+ parameterSchema: quietArrowParametersSchema,
1403
+ defaultParameters: { secondaryTreatment: "outlined" },
1404
+ controls: [{
1405
+ kind: "choice",
1406
+ parameter: "secondaryTreatment",
1407
+ label: "Secondary button treatment",
1408
+ options: [{
1409
+ value: "outlined",
1410
+ label: "Outlined"
1411
+ }, {
1412
+ value: "solid-accent",
1413
+ label: "Solid accent"
1414
+ }]
1415
+ }],
1416
+ defineSystem: (parameters) => ({
1362
1417
  global: {
1363
1418
  cornerStyle: "rounded",
1364
- shadow: "low",
1365
- textTransform: "none",
1419
+ textTransform: "uppercase",
1366
1420
  fontWeight: 500,
1367
- borderWidth: 1,
1421
+ typography: "body",
1422
+ fontSize: "text-sm",
1423
+ letterSpacing: "loose",
1368
1424
  hoverTransform: "none",
1369
1425
  hoverColor: "none"
1370
1426
  },
1371
1427
  sizes: {
1372
1428
  sm: {
1373
- padding: "0.75rem 2rem",
1429
+ padding: "0.625rem 1.25rem",
1430
+ fontSize: "text-xs"
1431
+ },
1432
+ md: {
1433
+ padding: "0.8125rem 1.75rem",
1374
1434
  fontSize: "text-sm"
1375
1435
  },
1376
- md: { padding: "1rem 2.5rem" },
1377
1436
  lg: {
1378
- padding: "1.25rem 3rem",
1379
- fontSize: "text-lg"
1437
+ padding: "0.9375rem 2.125rem",
1438
+ fontSize: "text-sm"
1380
1439
  },
1381
1440
  xl: {
1382
- padding: "1.625rem 3.75rem",
1383
- fontSize: "text-xl"
1441
+ padding: "1.0625rem 2.5rem",
1442
+ fontSize: "text-base"
1384
1443
  }
1385
1444
  },
1386
- variants: [
1387
- {
1388
- id: "primary",
1389
- name: "Primary",
1390
- enabled: true,
1391
- priority: 1,
1392
- background: {
1393
- type: "gradient",
1394
- stops: ["primary", "accent"],
1395
- direction: "to-r",
1396
- foregroundToken: "primaryForeground"
1397
- },
1398
- borderRadius: "rounded-lg",
1399
- shadow: {
1400
- elevation: "low",
1401
- softness: "soft",
1402
- position: "bottom"
1445
+ roles: {
1446
+ primary: {
1447
+ kind: "complete",
1448
+ appearance: {
1449
+ background: {
1450
+ type: "solid",
1451
+ colorToken: unsafeAsOpaqueButtonColourToken("primary")
1452
+ },
1453
+ borderRadius: "rounded-xl",
1454
+ affordance: { iconId: "ArrowRight" },
1455
+ effects: { hover: [{
1456
+ effectId: "darken-background",
1457
+ options: { amount: 100 }
1458
+ }] }
1403
1459
  }
1404
1460
  },
1405
- {
1406
- id: "secondary",
1407
- name: "Secondary",
1408
- enabled: true,
1409
- priority: 2,
1410
- background: {
1411
- type: "gradient",
1412
- stops: ["secondary", "accent"],
1413
- direction: "to-br",
1414
- foregroundToken: "primaryForeground"
1415
- },
1416
- borderRadius: "rounded-lg",
1417
- shadow: {
1418
- elevation: "low",
1419
- softness: "soft",
1420
- position: "bottom"
1461
+ secondary: {
1462
+ kind: "complete",
1463
+ appearance: parameters.secondaryTreatment === "solid-accent" ? {
1464
+ background: {
1465
+ type: "solid",
1466
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
1467
+ },
1468
+ borderRadius: "rounded-xl",
1469
+ affordance: { iconId: "ArrowRight" },
1470
+ effects: { hover: [{
1471
+ effectId: "darken-background",
1472
+ options: { amount: 100 }
1473
+ }] }
1474
+ } : {
1475
+ background: {
1476
+ type: "surface",
1477
+ role: "link"
1478
+ },
1479
+ borderRadius: "rounded-xl",
1480
+ border: { widthClass: "border" },
1481
+ affordance: { iconId: "ArrowRight" },
1482
+ effects: { hover: [{
1483
+ effectId: "background-on-hover",
1484
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
1485
+ }] }
1421
1486
  }
1422
1487
  },
1423
- {
1424
- id: "outline",
1425
- name: "Outline",
1426
- enabled: true,
1427
- priority: 3,
1428
- background: {
1429
- type: "surface",
1430
- role: "link"
1431
- },
1432
- borderRadius: "rounded-lg",
1433
- border: { widthClass: "border" },
1434
- effects: { hover: [{
1435
- effectId: "background-on-hover",
1436
- options: { colorToken: "surface" }
1437
- }] }
1488
+ outline: {
1489
+ kind: "complete",
1490
+ appearance: {
1491
+ background: {
1492
+ type: "surface",
1493
+ role: "link"
1494
+ },
1495
+ borderRadius: "rounded-xl",
1496
+ border: { widthClass: "border" }
1497
+ }
1438
1498
  },
1439
- {
1440
- id: "ghost",
1441
- name: "Ghost",
1442
- enabled: true,
1443
- priority: 3,
1444
- background: {
1445
- type: "surface",
1446
- role: "link"
1447
- },
1448
- borderRadius: "rounded-lg",
1449
- effects: { hover: [{
1450
- effectId: "background-on-hover",
1451
- options: { colorToken: "surface" }
1452
- }] }
1499
+ ghost: {
1500
+ kind: "complete",
1501
+ appearance: {
1502
+ background: {
1503
+ type: "surface",
1504
+ role: "link"
1505
+ },
1506
+ borderRadius: "rounded-xl"
1507
+ }
1508
+ },
1509
+ accent: {
1510
+ kind: "derive",
1511
+ from: "primary",
1512
+ overrides: { background: {
1513
+ type: "solid",
1514
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
1515
+ } }
1453
1516
  }
1454
- ]
1455
- }
1517
+ }
1518
+ })
1456
1519
  });
1457
1520
  //#endregion
1458
- //#region ../theme-core/src/buttons/personalities/confident-chip.ts
1459
- /**
1460
- * Confident Chip — moderate-radius solid buttons that read as competent and
1461
- * direct. Default for Clear Professional; works for any modern brand voice.
1462
- */
1463
- const confidentChip = defineButtonPersonality({
1464
- id: "confident-chip",
1465
- name: "Confident Chip",
1466
- description: "Mid-radius solid buttons with a crisp hover.",
1521
+ //#region ../theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.ts
1522
+ const emptyParametersSchema = z$1.object({}).strict();
1523
+ function defineStaticButtonStyleRecipe(input) {
1524
+ const system = normalizeSystem(input.system);
1525
+ return defineButtonStyleRecipe({
1526
+ id: input.id,
1527
+ accessibilityLabel: input.accessibilityLabel,
1528
+ tags: input.tags,
1529
+ parameterSchema: emptyParametersSchema,
1530
+ defaultParameters: {},
1531
+ controls: [],
1532
+ defineSystem: () => system
1533
+ });
1534
+ }
1535
+ function normalizeSystem(input) {
1536
+ return {
1537
+ global: buttonGlobalSettingsSchema.parse(input.global),
1538
+ ...input.sizes ? { sizes: input.sizes } : {},
1539
+ roles: {
1540
+ primary: normalizeCompleteRole(input.roles.primary),
1541
+ secondary: normalizeCompleteRole(input.roles.secondary),
1542
+ outline: normalizeSupportingRole(input.roles.outline),
1543
+ ghost: normalizeSupportingRole(input.roles.ghost),
1544
+ accent: normalizeSupportingRole(input.roles.accent)
1545
+ }
1546
+ };
1547
+ }
1548
+ function normalizeCompleteRole(role) {
1549
+ return {
1550
+ kind: "complete",
1551
+ appearance: normalizeAppearance(role.appearance)
1552
+ };
1553
+ }
1554
+ function normalizeSupportingRole(role) {
1555
+ if (role.kind === "complete") return normalizeCompleteRole(role);
1556
+ return {
1557
+ kind: "derive",
1558
+ from: role.from,
1559
+ ...role.overrides ? { overrides: normalizeAppearanceOverrides(role.overrides) } : {}
1560
+ };
1561
+ }
1562
+ function normalizeAppearance(appearance) {
1563
+ const { background, hoverBackgroundToken, ...rest } = appearance;
1564
+ return {
1565
+ ...rest,
1566
+ background: buttonColourTreatmentSchema.parse(background),
1567
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
1568
+ };
1569
+ }
1570
+ function normalizeAppearanceOverrides(overrides) {
1571
+ const { background, hoverBackgroundToken, ...rest } = overrides;
1572
+ return {
1573
+ ...rest,
1574
+ ...background ? { background: buttonColourTreatmentSchema.parse(background) } : {},
1575
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
1576
+ };
1577
+ }
1578
+ //#endregion
1579
+ //#region ../theme-core/src/buttons/styles/recipes/staticRecipes.ts
1580
+ const softPillRecipe = defineStaticButtonStyleRecipe({
1581
+ id: "soft-pill",
1582
+ accessibilityLabel: "Rounded pill buttons with a gentle hover lift",
1467
1583
  tags: {
1468
1584
  tone: "classic",
1469
1585
  energy: "calm",
1470
- motion: "standard",
1471
- era: "modern"
1586
+ motion: "subtle",
1587
+ era: "organic"
1472
1588
  },
1473
- buttonSystem: {
1589
+ system: {
1474
1590
  global: {
1475
- cornerStyle: "rounded",
1476
- shadow: "medium",
1591
+ cornerStyle: "pill",
1592
+ shadow: "low",
1477
1593
  textTransform: "none",
1478
- fontWeight: 600,
1479
- borderWidth: 1,
1480
- hoverTransform: "none",
1594
+ fontWeight: 500,
1595
+ hoverTransform: "lift",
1481
1596
  hoverColor: "none"
1482
1597
  },
1483
- variants: [
1484
- {
1485
- id: "primary",
1486
- name: "Primary",
1487
- enabled: true,
1488
- priority: 1,
1489
- background: {
1490
- type: "solid",
1491
- colorToken: "primary"
1492
- },
1493
- borderRadius: "rounded-md",
1494
- shadow: {
1495
- elevation: "medium",
1496
- softness: "soft",
1497
- position: "bottom"
1498
- },
1499
- effects: {
1500
- hover: [{
1501
- effectId: "darken-background",
1502
- options: { amount: 100 }
1503
- }],
1504
- active: [{
1505
- effectId: "scale-down",
1506
- options: { scale: "0.97" }
1507
- }]
1598
+ roles: {
1599
+ primary: {
1600
+ kind: "complete",
1601
+ appearance: {
1602
+ background: {
1603
+ type: "solid",
1604
+ colorToken: "primary"
1605
+ },
1606
+ borderRadius: "rounded-full",
1607
+ shadow: {
1608
+ elevation: "low",
1609
+ softness: "soft",
1610
+ position: "bottom"
1611
+ },
1612
+ effects: {
1613
+ hover: [{ effectId: "lift" }],
1614
+ active: [{
1615
+ effectId: "scale-down",
1616
+ options: { scale: "0.98" }
1617
+ }]
1618
+ }
1508
1619
  }
1509
1620
  },
1510
- {
1511
- id: "secondary",
1512
- name: "Secondary",
1513
- enabled: true,
1514
- priority: 2,
1515
- background: {
1516
- type: "solid",
1517
- colorToken: "surface"
1518
- },
1519
- borderRadius: "rounded-md",
1520
- border: { widthClass: "border" },
1521
- effects: { hover: [{
1522
- effectId: "background-on-hover",
1523
- options: { colorToken: "background" }
1524
- }] }
1621
+ secondary: {
1622
+ kind: "complete",
1623
+ appearance: {
1624
+ background: {
1625
+ type: "surface",
1626
+ role: "link"
1627
+ },
1628
+ borderRadius: "rounded-full",
1629
+ border: { widthClass: "border-2" },
1630
+ effects: { hover: [{
1631
+ effectId: "background-on-hover",
1632
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1633
+ }] }
1634
+ }
1525
1635
  },
1526
- {
1527
- id: "outline",
1528
- name: "Outline",
1529
- enabled: true,
1530
- priority: 3,
1531
- background: {
1532
- type: "surface",
1533
- role: "link"
1534
- },
1535
- borderRadius: "rounded-md",
1536
- border: { widthClass: "border" },
1537
- effects: { hover: [{
1538
- effectId: "background-on-hover",
1539
- options: { colorToken: "surface" }
1540
- }] }
1636
+ outline: {
1637
+ kind: "complete",
1638
+ appearance: {
1639
+ background: {
1640
+ type: "surface",
1641
+ role: "link"
1642
+ },
1643
+ borderRadius: "rounded-full",
1644
+ border: { widthClass: "border" },
1645
+ effects: { hover: [{
1646
+ effectId: "background-on-hover",
1647
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1648
+ }] }
1649
+ }
1541
1650
  },
1542
- {
1543
- id: "ghost",
1544
- name: "Ghost",
1545
- enabled: true,
1546
- priority: 3,
1547
- background: {
1548
- type: "surface",
1549
- role: "link"
1550
- },
1551
- borderRadius: "rounded-md",
1552
- effects: { hover: [{
1553
- effectId: "background-on-hover",
1554
- options: { colorToken: "surface" }
1555
- }] }
1651
+ ghost: {
1652
+ kind: "complete",
1653
+ appearance: {
1654
+ background: {
1655
+ type: "surface",
1656
+ role: "link"
1657
+ },
1658
+ borderRadius: "rounded-full",
1659
+ effects: { hover: [{
1660
+ effectId: "background-on-hover",
1661
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1662
+ }] }
1663
+ }
1664
+ },
1665
+ accent: {
1666
+ kind: "derive",
1667
+ from: "primary",
1668
+ overrides: { background: {
1669
+ type: "solid",
1670
+ colorToken: "accent"
1671
+ } }
1556
1672
  }
1557
- ]
1673
+ }
1558
1674
  }
1559
1675
  });
1560
- //#endregion
1561
- //#region ../theme-core/src/buttons/personalities/earth-pill.ts
1562
- /**
1563
- * Earth Pill - warm studio pills with compact, primary-coloured ghost CTAs.
1564
- * Built for grounded editorial wellness styles such as Soft Earth.
1565
- */
1566
- const earthPill = defineButtonPersonality({
1676
+ const earthPillRecipe = defineStaticButtonStyleRecipe({
1567
1677
  id: "earth-pill",
1568
- name: "Earth Pill",
1569
- description: "Compact terracotta pills with quiet primary-coloured ghost CTAs.",
1678
+ accessibilityLabel: "Compact rounded buttons with a quiet hover lift",
1570
1679
  tags: {
1571
1680
  tone: "classic",
1572
1681
  energy: "calm",
1573
1682
  motion: "subtle",
1574
1683
  era: "organic"
1575
1684
  },
1576
- buttonSystem: {
1685
+ system: {
1577
1686
  global: {
1578
1687
  cornerStyle: "pill",
1579
1688
  shadow: "low",
1580
1689
  textTransform: "none",
1581
1690
  fontWeight: 500,
1582
- borderWidth: 1,
1583
1691
  hoverTransform: "lift",
1584
1692
  hoverColor: "none",
1585
1693
  typography: "body",
@@ -1600,350 +1708,540 @@ const earthPill = defineButtonPersonality({
1600
1708
  fontSize: "text-xl"
1601
1709
  }
1602
1710
  },
1603
- variants: [
1604
- {
1605
- id: "primary",
1606
- name: "Primary",
1607
- enabled: true,
1608
- priority: 1,
1609
- background: {
1610
- type: "solid",
1611
- colorToken: "primary"
1612
- },
1613
- borderRadius: "rounded-full",
1614
- shadow: {
1615
- elevation: "low",
1616
- softness: "soft",
1617
- position: "bottom"
1618
- },
1619
- effects: {
1620
- hover: [{
1621
- effectId: "lift",
1622
- options: { translateY: "-1px" }
1623
- }, {
1711
+ roles: {
1712
+ primary: {
1713
+ kind: "complete",
1714
+ appearance: {
1715
+ background: {
1716
+ type: "solid",
1717
+ colorToken: "primary"
1718
+ },
1719
+ borderRadius: "rounded-full",
1720
+ shadow: {
1721
+ elevation: "low",
1722
+ softness: "soft",
1723
+ position: "bottom"
1724
+ },
1725
+ effects: {
1726
+ hover: [{ effectId: "lift" }, {
1727
+ effectId: "background-on-hover",
1728
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
1729
+ }],
1730
+ active: [{
1731
+ effectId: "scale-down",
1732
+ options: { scale: "0.98" }
1733
+ }]
1734
+ }
1735
+ }
1736
+ },
1737
+ secondary: {
1738
+ kind: "complete",
1739
+ appearance: {
1740
+ background: {
1741
+ type: "surface",
1742
+ role: "link"
1743
+ },
1744
+ borderRadius: "rounded-full",
1745
+ border: { widthClass: "border" },
1746
+ effects: { hover: [{
1624
1747
  effectId: "background-on-hover",
1625
- options: { colorToken: "accent" }
1626
- }],
1627
- active: [{
1628
- effectId: "scale-down",
1629
- options: { scale: "0.98" }
1630
- }]
1748
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
1749
+ }] }
1631
1750
  }
1632
1751
  },
1633
- {
1634
- id: "secondary",
1635
- name: "Secondary",
1636
- enabled: true,
1637
- priority: 2,
1638
- background: {
1639
- type: "surface",
1640
- role: "link"
1641
- },
1642
- borderRadius: "rounded-full",
1643
- border: { widthClass: "border" },
1644
- effects: { hover: [{
1645
- effectId: "background-on-hover",
1646
- options: { colorToken: "muted" }
1647
- }] }
1752
+ outline: {
1753
+ kind: "complete",
1754
+ appearance: {
1755
+ background: {
1756
+ type: "surface",
1757
+ role: "link"
1758
+ },
1759
+ borderRadius: "rounded-full",
1760
+ border: { widthClass: "border" },
1761
+ effects: { hover: [{
1762
+ effectId: "background-on-hover",
1763
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
1764
+ }] }
1765
+ }
1648
1766
  },
1649
- {
1650
- id: "outline",
1651
- name: "Outline",
1652
- enabled: true,
1653
- priority: 3,
1654
- background: {
1655
- type: "surface",
1656
- role: "link"
1657
- },
1658
- borderRadius: "rounded-full",
1659
- border: { widthClass: "border" },
1660
- effects: { hover: [{
1661
- effectId: "background-on-hover",
1662
- options: { colorToken: "surfaceAlt" }
1663
- }] }
1767
+ ghost: {
1768
+ kind: "complete",
1769
+ appearance: {
1770
+ background: {
1771
+ type: "surface",
1772
+ role: "link"
1773
+ },
1774
+ borderRadius: "rounded-full",
1775
+ shadow: {
1776
+ elevation: "none",
1777
+ softness: null,
1778
+ position: "bottom"
1779
+ },
1780
+ sizes: {
1781
+ sm: {
1782
+ padding: "0.25rem 0",
1783
+ fontSize: "text-sm"
1784
+ },
1785
+ md: { padding: "0.375rem 0" },
1786
+ lg: {
1787
+ padding: "0.5rem 0",
1788
+ fontSize: "text-lg"
1789
+ },
1790
+ xl: {
1791
+ padding: "0.625rem 0",
1792
+ fontSize: "text-xl"
1793
+ }
1794
+ }
1795
+ }
1664
1796
  },
1665
- {
1666
- id: "ghost",
1667
- name: "Ghost",
1668
- enabled: true,
1669
- priority: 3,
1670
- background: {
1671
- type: "surface",
1672
- role: "link"
1673
- },
1674
- borderRadius: "rounded-full",
1675
- shadow: {
1676
- elevation: "none",
1677
- softness: null,
1678
- position: "bottom"
1679
- },
1680
- sizes: {
1681
- sm: {
1682
- padding: "0.25rem 0",
1683
- fontSize: "text-sm"
1797
+ accent: {
1798
+ kind: "derive",
1799
+ from: "primary",
1800
+ overrides: { background: {
1801
+ type: "solid",
1802
+ colorToken: "accent"
1803
+ } }
1804
+ }
1805
+ }
1806
+ }
1807
+ });
1808
+ const confidentChipRecipe = defineStaticButtonStyleRecipe({
1809
+ id: "confident-chip",
1810
+ accessibilityLabel: "Moderately rounded solid buttons with a crisp hover",
1811
+ tags: {
1812
+ tone: "classic",
1813
+ energy: "calm",
1814
+ motion: "standard",
1815
+ era: "modern"
1816
+ },
1817
+ system: {
1818
+ global: {
1819
+ cornerStyle: "rounded",
1820
+ shadow: "medium",
1821
+ textTransform: "none",
1822
+ fontWeight: 600,
1823
+ hoverTransform: "none",
1824
+ hoverColor: "none"
1825
+ },
1826
+ roles: {
1827
+ primary: {
1828
+ kind: "complete",
1829
+ appearance: {
1830
+ background: {
1831
+ type: "solid",
1832
+ colorToken: "primary"
1684
1833
  },
1685
- md: { padding: "0.375rem 0" },
1686
- lg: {
1687
- padding: "0.5rem 0",
1688
- fontSize: "text-lg"
1834
+ borderRadius: "rounded-md",
1835
+ shadow: {
1836
+ elevation: "medium",
1837
+ softness: "soft",
1838
+ position: "bottom"
1689
1839
  },
1690
- xl: {
1691
- padding: "0.625rem 0",
1692
- fontSize: "text-xl"
1840
+ effects: {
1841
+ hover: [{
1842
+ effectId: "darken-background",
1843
+ options: { amount: 100 }
1844
+ }],
1845
+ active: [{
1846
+ effectId: "scale-down",
1847
+ options: { scale: "0.97" }
1848
+ }]
1693
1849
  }
1694
1850
  }
1851
+ },
1852
+ secondary: {
1853
+ kind: "complete",
1854
+ appearance: {
1855
+ background: {
1856
+ type: "solid",
1857
+ colorToken: "surface"
1858
+ },
1859
+ borderRadius: "rounded-md",
1860
+ border: { widthClass: "border" },
1861
+ effects: { hover: [{
1862
+ effectId: "background-on-hover",
1863
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
1864
+ }] }
1865
+ }
1866
+ },
1867
+ outline: {
1868
+ kind: "complete",
1869
+ appearance: {
1870
+ background: {
1871
+ type: "surface",
1872
+ role: "link"
1873
+ },
1874
+ borderRadius: "rounded-md",
1875
+ border: { widthClass: "border" },
1876
+ effects: { hover: [{
1877
+ effectId: "background-on-hover",
1878
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1879
+ }] }
1880
+ }
1881
+ },
1882
+ ghost: {
1883
+ kind: "complete",
1884
+ appearance: {
1885
+ background: {
1886
+ type: "surface",
1887
+ role: "link"
1888
+ },
1889
+ borderRadius: "rounded-md",
1890
+ effects: { hover: [{
1891
+ effectId: "background-on-hover",
1892
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1893
+ }] }
1894
+ }
1895
+ },
1896
+ accent: {
1897
+ kind: "derive",
1898
+ from: "primary",
1899
+ overrides: { background: {
1900
+ type: "solid",
1901
+ colorToken: "accent"
1902
+ } }
1695
1903
  }
1696
- ]
1904
+ }
1697
1905
  }
1698
1906
  });
1699
- //#endregion
1700
- //#region ../theme-core/src/buttons/personalities/editorial-link.ts
1701
- /**
1702
- * Editorial Link — all variants are link-style with a growing underline.
1703
- * Default for Warm Editorial and Quiet Luxury; reads as refined and quiet.
1704
- */
1705
- const editorialLink = defineButtonPersonality({
1907
+ const editorialSizes = {
1908
+ sm: { padding: "0.25rem 0" },
1909
+ md: { padding: "0.5rem 0" },
1910
+ lg: { padding: "0.625rem 0" },
1911
+ xl: { padding: "0.75rem 0" }
1912
+ };
1913
+ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
1706
1914
  id: "editorial-link",
1707
- name: "Editorial Link",
1708
- description: "Link-style with a growing underline. Refined, typographic.",
1915
+ accessibilityLabel: "Flat typographic buttons with an underline treatment",
1709
1916
  tags: {
1710
1917
  tone: "minimal",
1711
1918
  energy: "calm",
1712
1919
  motion: "subtle",
1713
1920
  era: "editorial"
1714
1921
  },
1715
- buttonSystem: {
1922
+ system: {
1716
1923
  global: {
1717
1924
  cornerStyle: "square",
1718
1925
  textTransform: "none",
1719
1926
  fontWeight: 500,
1720
- borderWidth: 1,
1721
1927
  hoverTransform: "none",
1722
1928
  hoverColor: "none"
1723
1929
  },
1724
- variants: [
1725
- {
1726
- id: "primary",
1727
- name: "Primary",
1728
- enabled: true,
1729
- priority: 1,
1730
- background: {
1731
- type: "surface",
1732
- role: "link"
1733
- },
1734
- borderRadius: "rounded-none",
1735
- sizes: {
1736
- sm: { padding: "0.25rem 0" },
1737
- md: { padding: "0.5rem 0" },
1738
- lg: { padding: "0.625rem 0" },
1739
- xl: { padding: "0.75rem 0" }
1740
- },
1741
- effects: { base: [{
1742
- effectId: "border-bottom-grow",
1743
- options: {
1744
- height: 2,
1745
- colorToken: "text",
1746
- origin: "left"
1747
- }
1748
- }] }
1930
+ roles: {
1931
+ primary: {
1932
+ kind: "complete",
1933
+ appearance: {
1934
+ background: {
1935
+ type: "surface",
1936
+ role: "link"
1937
+ },
1938
+ borderRadius: "rounded-none",
1939
+ sizes: editorialSizes,
1940
+ effects: { base: [{
1941
+ effectId: "border-bottom-grow",
1942
+ options: {
1943
+ height: 2,
1944
+ origin: "left"
1945
+ }
1946
+ }] }
1947
+ }
1749
1948
  },
1750
- {
1751
- id: "secondary",
1752
- name: "Secondary",
1753
- enabled: true,
1754
- priority: 2,
1755
- background: {
1756
- type: "surface",
1757
- role: "link"
1758
- },
1759
- borderRadius: "rounded-none",
1760
- sizes: {
1761
- sm: { padding: "0.25rem 0" },
1762
- md: { padding: "0.5rem 0" },
1763
- lg: { padding: "0.625rem 0" },
1764
- xl: { padding: "0.75rem 0" }
1765
- },
1766
- effects: { base: [{
1767
- effectId: "border-bottom-grow",
1768
- options: {
1769
- height: 1,
1770
- colorToken: "mutedText",
1771
- origin: "left"
1772
- }
1773
- }] }
1949
+ secondary: {
1950
+ kind: "complete",
1951
+ appearance: {
1952
+ background: {
1953
+ type: "surface",
1954
+ role: "link"
1955
+ },
1956
+ borderRadius: "rounded-none",
1957
+ sizes: editorialSizes,
1958
+ effects: { base: [{
1959
+ effectId: "border-bottom-grow",
1960
+ options: {
1961
+ height: 1,
1962
+ origin: "left"
1963
+ }
1964
+ }] }
1965
+ }
1774
1966
  },
1775
- {
1776
- id: "outline",
1777
- name: "Outline",
1778
- enabled: true,
1779
- priority: 3,
1780
- background: {
1781
- type: "surface",
1782
- role: "link"
1783
- },
1784
- borderRadius: "rounded-none",
1785
- sizes: {
1786
- sm: { padding: "0.25rem 0" },
1787
- md: { padding: "0.5rem 0" },
1788
- lg: { padding: "0.625rem 0" },
1789
- xl: { padding: "0.75rem 0" }
1790
- },
1791
- effects: { base: [{
1967
+ outline: {
1968
+ kind: "complete",
1969
+ appearance: {
1970
+ background: {
1971
+ type: "surface",
1972
+ role: "link"
1973
+ },
1974
+ borderRadius: "rounded-none",
1975
+ sizes: editorialSizes,
1976
+ effects: { base: [{
1977
+ effectId: "border-bottom-grow",
1978
+ options: {
1979
+ height: 1,
1980
+ origin: "left"
1981
+ }
1982
+ }] }
1983
+ }
1984
+ },
1985
+ ghost: {
1986
+ kind: "complete",
1987
+ appearance: {
1988
+ background: {
1989
+ type: "surface",
1990
+ role: "link"
1991
+ },
1992
+ borderRadius: "rounded-none",
1993
+ sizes: editorialSizes
1994
+ }
1995
+ },
1996
+ accent: {
1997
+ kind: "derive",
1998
+ from: "primary",
1999
+ overrides: { effects: { base: [{
1792
2000
  effectId: "border-bottom-grow",
1793
2001
  options: {
1794
- height: 1,
1795
- colorToken: "accent",
2002
+ height: 2,
1796
2003
  origin: "left"
1797
2004
  }
1798
- }] }
1799
- },
1800
- {
1801
- id: "ghost",
1802
- name: "Ghost",
1803
- enabled: true,
1804
- priority: 3,
1805
- background: {
1806
- type: "surface",
1807
- role: "link"
1808
- },
1809
- borderRadius: "rounded-none",
1810
- sizes: {
1811
- sm: { padding: "0.25rem 0" },
1812
- md: { padding: "0.5rem 0" },
1813
- lg: { padding: "0.625rem 0" },
1814
- xl: { padding: "0.75rem 0" }
1815
- }
2005
+ }] } }
1816
2006
  }
1817
- ]
2007
+ }
1818
2008
  }
1819
2009
  });
1820
- //#endregion
1821
- //#region ../theme-core/src/buttons/personalities/flat-ink.ts
1822
- /**
1823
- * Flat Ink — a solid ink primary, a hairline ghost secondary, and a single
1824
- * amber accent climax, all completely flat (no drop shadow) with a modest
1825
- * radius. Reads as grounded, editorial and clinician-precise: the Fulcrum
1826
- * physiotherapy voice. The primary shifts to the secondary (moss) on hover and
1827
- * every variant lifts 2px; the amber accent is meant to be used sparingly as
1828
- * the page's one conversion climax.
1829
- */
1830
- const flatInk = defineButtonPersonality({
1831
- id: "flat-ink",
1832
- name: "Flat Ink",
1833
- description: "Flat solid-ink primary, hairline ghost secondary, and a single amber accent climax — modest radius, no shadow.",
2010
+ const pebbleRecipe = defineStaticButtonStyleRecipe({
2011
+ id: "pebble",
2012
+ accessibilityLabel: "Generously padded pill buttons",
1834
2013
  tags: {
1835
2014
  tone: "classic",
1836
2015
  energy: "calm",
1837
- motion: "subtle",
1838
- era: "editorial"
2016
+ motion: "standard",
2017
+ era: "organic"
1839
2018
  },
1840
- buttonSystem: {
2019
+ system: {
1841
2020
  global: {
1842
- cornerStyle: "rounded",
2021
+ cornerStyle: "pill",
1843
2022
  textTransform: "none",
1844
- fontWeight: 600,
1845
- borderWidth: 1,
1846
- typography: "body",
1847
- letterSpacing: "tight",
1848
- paddingPreset: "default",
1849
- hoverTransform: "lift",
2023
+ fontWeight: 500,
2024
+ hoverTransform: "none",
1850
2025
  hoverColor: "none"
1851
2026
  },
1852
2027
  sizes: {
1853
2028
  sm: {
1854
- padding: "0.625rem 1.125rem",
2029
+ padding: "0.625rem 1.75rem",
1855
2030
  fontSize: "text-sm"
1856
2031
  },
1857
- md: { padding: "0.8125rem 1.375rem" },
2032
+ md: { padding: "0.875rem 2.25rem" },
1858
2033
  lg: {
1859
- padding: "0.9375rem 1.625rem",
2034
+ padding: "1.125rem 2.75rem",
1860
2035
  fontSize: "text-lg"
1861
2036
  },
1862
2037
  xl: {
1863
- padding: "1.0625rem 2rem",
2038
+ padding: "1.5rem 3.5rem",
1864
2039
  fontSize: "text-xl"
1865
2040
  }
1866
2041
  },
1867
- variants: [
1868
- {
1869
- id: "primary",
1870
- name: "Primary",
1871
- enabled: true,
1872
- priority: 1,
1873
- background: {
1874
- type: "solid",
1875
- colorToken: "primary"
1876
- },
1877
- borderRadius: "rounded-lg",
1878
- affordance: { iconId: "ArrowRight" },
1879
- effects: { hover: [{
1880
- effectId: "lift",
1881
- options: { translateY: "-2px" }
1882
- }, {
1883
- effectId: "background-on-hover",
1884
- options: { colorToken: "secondary" }
1885
- }] }
2042
+ roles: {
2043
+ primary: {
2044
+ kind: "complete",
2045
+ appearance: {
2046
+ background: {
2047
+ type: "solid",
2048
+ colorToken: "primary"
2049
+ },
2050
+ borderRadius: "rounded-full",
2051
+ effects: { hover: [{
2052
+ effectId: "darken-background",
2053
+ options: { amount: 100 }
2054
+ }] }
2055
+ }
1886
2056
  },
1887
- {
1888
- id: "secondary",
1889
- name: "Secondary",
1890
- enabled: true,
1891
- priority: 2,
1892
- background: {
1893
- type: "surface",
1894
- role: "link"
1895
- },
1896
- borderRadius: "rounded-lg",
1897
- border: { widthClass: "border" },
1898
- effects: { hover: [{
1899
- effectId: "lift",
1900
- options: { translateY: "-2px" }
1901
- }, {
1902
- effectId: "background-on-hover",
1903
- options: { colorToken: "surfaceAlt" }
1904
- }] }
2057
+ secondary: {
2058
+ kind: "complete",
2059
+ appearance: {
2060
+ background: {
2061
+ type: "surface",
2062
+ role: "link"
2063
+ },
2064
+ borderRadius: "rounded-full",
2065
+ border: { widthClass: "border-2" },
2066
+ effects: { hover: [{
2067
+ effectId: "background-on-hover",
2068
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
2069
+ }] }
2070
+ }
1905
2071
  },
1906
- {
1907
- id: "accent",
1908
- name: "Accent",
1909
- enabled: true,
1910
- priority: 3,
1911
- background: {
1912
- type: "solid",
1913
- colorToken: "accent"
1914
- },
1915
- borderRadius: "rounded-lg",
1916
- affordance: { iconId: "ArrowRight" },
1917
- effects: { hover: [{
1918
- effectId: "lift",
1919
- options: { translateY: "-2px" }
1920
- }] }
2072
+ outline: {
2073
+ kind: "complete",
2074
+ appearance: {
2075
+ background: {
2076
+ type: "surface",
2077
+ role: "link"
2078
+ },
2079
+ borderRadius: "rounded-full",
2080
+ border: { widthClass: "border" },
2081
+ effects: { hover: [{
2082
+ effectId: "background-on-hover",
2083
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2084
+ }] }
2085
+ }
2086
+ },
2087
+ ghost: {
2088
+ kind: "complete",
2089
+ appearance: {
2090
+ background: {
2091
+ type: "surface",
2092
+ role: "link"
2093
+ },
2094
+ borderRadius: "rounded-full",
2095
+ sizes: {
2096
+ sm: {
2097
+ padding: "0.375rem 0.875rem",
2098
+ fontSize: "text-sm"
2099
+ },
2100
+ md: { padding: "0.5rem 1rem" },
2101
+ lg: {
2102
+ padding: "0.625rem 1.25rem",
2103
+ fontSize: "text-lg"
2104
+ },
2105
+ xl: {
2106
+ padding: "0.75rem 1.5rem",
2107
+ fontSize: "text-xl"
2108
+ }
2109
+ }
2110
+ }
2111
+ },
2112
+ accent: {
2113
+ kind: "derive",
2114
+ from: "primary",
2115
+ overrides: { background: {
2116
+ type: "solid",
2117
+ colorToken: "accent"
2118
+ } }
1921
2119
  }
1922
- ]
2120
+ }
1923
2121
  }
1924
2122
  });
1925
- //#endregion
1926
- //#region ../theme-core/src/buttons/personalities/ink-stamp.ts
1927
- /**
1928
- * Ink Stamp — solid earthy fills with a bordered, hand-stamped block-print
1929
- * feel. Reads as bold and handmade; suits expressive craft brands.
1930
- */
1931
- const inkStamp = defineButtonPersonality({
2123
+ const brushedWashRecipe = defineStaticButtonStyleRecipe({
2124
+ id: "brushed-wash",
2125
+ accessibilityLabel: "Generously padded gradient buttons with soft shadows",
2126
+ tags: {
2127
+ tone: "classic",
2128
+ energy: "vibrant",
2129
+ motion: "standard",
2130
+ era: "organic"
2131
+ },
2132
+ system: {
2133
+ global: {
2134
+ cornerStyle: "rounded",
2135
+ shadow: "low",
2136
+ textTransform: "none",
2137
+ fontWeight: 500,
2138
+ hoverTransform: "none",
2139
+ hoverColor: "none"
2140
+ },
2141
+ sizes: {
2142
+ sm: {
2143
+ padding: "0.75rem 2rem",
2144
+ fontSize: "text-sm"
2145
+ },
2146
+ md: { padding: "1rem 2.5rem" },
2147
+ lg: {
2148
+ padding: "1.25rem 3rem",
2149
+ fontSize: "text-lg"
2150
+ },
2151
+ xl: {
2152
+ padding: "1.625rem 3.75rem",
2153
+ fontSize: "text-xl"
2154
+ }
2155
+ },
2156
+ roles: {
2157
+ primary: {
2158
+ kind: "complete",
2159
+ appearance: {
2160
+ background: {
2161
+ type: "gradient",
2162
+ stops: ["primary", "accent"],
2163
+ direction: "to-r",
2164
+ foregroundToken: "primaryForeground"
2165
+ },
2166
+ borderRadius: "rounded-lg",
2167
+ shadow: {
2168
+ elevation: "low",
2169
+ softness: "soft",
2170
+ position: "bottom"
2171
+ }
2172
+ }
2173
+ },
2174
+ secondary: {
2175
+ kind: "complete",
2176
+ appearance: {
2177
+ background: {
2178
+ type: "gradient",
2179
+ stops: ["secondary", "accent"],
2180
+ direction: "to-br",
2181
+ foregroundToken: "primaryForeground"
2182
+ },
2183
+ borderRadius: "rounded-lg",
2184
+ shadow: {
2185
+ elevation: "low",
2186
+ softness: "soft",
2187
+ position: "bottom"
2188
+ }
2189
+ }
2190
+ },
2191
+ outline: {
2192
+ kind: "complete",
2193
+ appearance: {
2194
+ background: {
2195
+ type: "surface",
2196
+ role: "link"
2197
+ },
2198
+ borderRadius: "rounded-lg",
2199
+ border: { widthClass: "border" },
2200
+ effects: { hover: [{
2201
+ effectId: "background-on-hover",
2202
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2203
+ }] }
2204
+ }
2205
+ },
2206
+ ghost: {
2207
+ kind: "complete",
2208
+ appearance: {
2209
+ background: {
2210
+ type: "surface",
2211
+ role: "link"
2212
+ },
2213
+ borderRadius: "rounded-lg",
2214
+ effects: { hover: [{
2215
+ effectId: "background-on-hover",
2216
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2217
+ }] }
2218
+ }
2219
+ },
2220
+ accent: {
2221
+ kind: "derive",
2222
+ from: "primary",
2223
+ overrides: { background: {
2224
+ type: "solid",
2225
+ colorToken: "accent"
2226
+ } }
2227
+ }
2228
+ }
2229
+ }
2230
+ });
2231
+ const inkStampRecipe = defineStaticButtonStyleRecipe({
1932
2232
  id: "ink-stamp",
1933
- name: "Ink Stamp",
1934
- description: "Hand-stamped block-print buttons with a slight lift on hover.",
2233
+ accessibilityLabel: "Uppercase block-print buttons with a playful hover",
1935
2234
  tags: {
1936
2235
  tone: "bold",
1937
2236
  energy: "vibrant",
1938
2237
  motion: "standard",
1939
2238
  era: "organic"
1940
2239
  },
1941
- buttonSystem: {
2240
+ system: {
1942
2241
  global: {
1943
2242
  cornerStyle: "rounded",
1944
2243
  textTransform: "uppercase",
1945
2244
  fontWeight: 600,
1946
- borderWidth: 1,
1947
2245
  hoverTransform: "none",
1948
2246
  hoverColor: "none",
1949
2247
  letterSpacing: "loose"
@@ -1966,126 +2264,329 @@ const inkStamp = defineButtonPersonality({
1966
2264
  fontSize: "text-lg"
1967
2265
  }
1968
2266
  },
1969
- variants: [
1970
- {
1971
- id: "primary",
1972
- name: "Primary",
1973
- enabled: true,
1974
- priority: 1,
1975
- background: {
2267
+ roles: {
2268
+ primary: {
2269
+ kind: "complete",
2270
+ appearance: {
2271
+ background: {
2272
+ type: "solid",
2273
+ colorToken: "primary"
2274
+ },
2275
+ borderRadius: "rounded-md",
2276
+ effects: {
2277
+ hover: [{
2278
+ effectId: "drop-shadow",
2279
+ options: { intensity: "medium" }
2280
+ }, {
2281
+ effectId: "scale-up",
2282
+ options: { scale: "1.02" }
2283
+ }],
2284
+ active: [{
2285
+ effectId: "scale-down",
2286
+ options: { scale: "0.98" }
2287
+ }]
2288
+ }
2289
+ }
2290
+ },
2291
+ secondary: {
2292
+ kind: "complete",
2293
+ appearance: {
2294
+ background: {
2295
+ type: "surface",
2296
+ role: "link"
2297
+ },
2298
+ borderRadius: "rounded-md",
2299
+ border: { widthClass: "border-2" },
2300
+ effects: { hover: [{
2301
+ effectId: "background-on-hover",
2302
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2303
+ }] }
2304
+ }
2305
+ },
2306
+ outline: {
2307
+ kind: "complete",
2308
+ appearance: {
2309
+ background: {
2310
+ type: "surface",
2311
+ role: "link"
2312
+ },
2313
+ borderRadius: "rounded-md",
2314
+ border: { widthClass: "border-2" },
2315
+ effects: { hover: [{
2316
+ effectId: "background-on-hover",
2317
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2318
+ }] }
2319
+ }
2320
+ },
2321
+ ghost: {
2322
+ kind: "complete",
2323
+ appearance: {
2324
+ background: {
2325
+ type: "surface",
2326
+ role: "link"
2327
+ },
2328
+ borderRadius: "rounded-none",
2329
+ sizes: {
2330
+ sm: {
2331
+ padding: "0.375rem 0",
2332
+ fontSize: "text-xs"
2333
+ },
2334
+ md: {
2335
+ padding: "0.5rem 0",
2336
+ fontSize: "text-sm"
2337
+ },
2338
+ lg: {
2339
+ padding: "0.625rem 0",
2340
+ fontSize: "text-base"
2341
+ },
2342
+ xl: {
2343
+ padding: "0.75rem 0",
2344
+ fontSize: "text-lg"
2345
+ }
2346
+ },
2347
+ effects: { base: [{
2348
+ effectId: "border-bottom-grow",
2349
+ options: {
2350
+ height: 1,
2351
+ origin: "left"
2352
+ }
2353
+ }] }
2354
+ }
2355
+ },
2356
+ accent: {
2357
+ kind: "derive",
2358
+ from: "primary",
2359
+ overrides: { background: {
1976
2360
  type: "solid",
1977
- colorToken: "primary"
1978
- },
1979
- borderRadius: "rounded-md",
1980
- effects: {
1981
- hover: [{
1982
- effectId: "drop-shadow",
1983
- options: { intensity: "medium" }
1984
- }, {
1985
- effectId: "scale-up",
1986
- options: { scale: "1.02" }
1987
- }],
1988
- active: [{
1989
- effectId: "scale-down",
1990
- options: { scale: "0.98" }
1991
- }]
2361
+ colorToken: "accent"
2362
+ } }
2363
+ }
2364
+ }
2365
+ }
2366
+ });
2367
+ const flatInkRecipe = defineStaticButtonStyleRecipe({
2368
+ id: "flat-ink",
2369
+ accessibilityLabel: "Flat rounded buttons with arrow affordances",
2370
+ tags: {
2371
+ tone: "classic",
2372
+ energy: "calm",
2373
+ motion: "subtle",
2374
+ era: "editorial"
2375
+ },
2376
+ system: {
2377
+ global: {
2378
+ cornerStyle: "rounded",
2379
+ textTransform: "none",
2380
+ fontWeight: 600,
2381
+ typography: "body",
2382
+ letterSpacing: "tight",
2383
+ paddingPreset: "default",
2384
+ hoverTransform: "lift",
2385
+ hoverColor: "none"
2386
+ },
2387
+ sizes: {
2388
+ sm: {
2389
+ padding: "0.625rem 1.125rem",
2390
+ fontSize: "text-sm"
2391
+ },
2392
+ md: { padding: "0.8125rem 1.375rem" },
2393
+ lg: {
2394
+ padding: "0.9375rem 1.625rem",
2395
+ fontSize: "text-lg"
2396
+ },
2397
+ xl: {
2398
+ padding: "1.0625rem 2rem",
2399
+ fontSize: "text-xl"
2400
+ }
2401
+ },
2402
+ roles: {
2403
+ primary: {
2404
+ kind: "complete",
2405
+ appearance: {
2406
+ background: {
2407
+ type: "solid",
2408
+ colorToken: "primary"
2409
+ },
2410
+ borderRadius: "rounded-lg",
2411
+ affordance: { iconId: "ArrowRight" },
2412
+ effects: { hover: [{ effectId: "lift" }, {
2413
+ effectId: "background-on-hover",
2414
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("secondary") }
2415
+ }] }
1992
2416
  }
1993
2417
  },
1994
- {
1995
- id: "secondary",
1996
- name: "Secondary",
1997
- enabled: true,
1998
- priority: 2,
1999
- background: {
2000
- type: "surface",
2001
- role: "link"
2002
- },
2003
- borderRadius: "rounded-md",
2004
- border: { widthClass: "border-2" },
2005
- effects: { hover: [{
2006
- effectId: "background-on-hover",
2007
- options: { colorToken: "surface" }
2008
- }] }
2418
+ secondary: {
2419
+ kind: "complete",
2420
+ appearance: {
2421
+ background: {
2422
+ type: "surface",
2423
+ role: "link"
2424
+ },
2425
+ borderRadius: "rounded-lg",
2426
+ border: { widthClass: "border" },
2427
+ effects: { hover: [{ effectId: "lift" }, {
2428
+ effectId: "background-on-hover",
2429
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
2430
+ }] }
2431
+ }
2009
2432
  },
2010
- {
2011
- id: "outline",
2012
- name: "Outline",
2013
- enabled: true,
2014
- priority: 3,
2015
- background: {
2016
- type: "surface",
2017
- role: "link"
2018
- },
2019
- borderRadius: "rounded-md",
2020
- border: { widthClass: "border-2" },
2021
- effects: { hover: [{
2022
- effectId: "background-on-hover",
2023
- options: { colorToken: "surface" }
2024
- }] }
2433
+ outline: {
2434
+ kind: "complete",
2435
+ appearance: {
2436
+ background: {
2437
+ type: "surface",
2438
+ role: "link"
2439
+ },
2440
+ borderRadius: "rounded-lg",
2441
+ border: { widthClass: "border" },
2442
+ effects: { hover: [{ effectId: "lift" }, {
2443
+ effectId: "background-on-hover",
2444
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
2445
+ }] }
2446
+ }
2025
2447
  },
2026
- {
2027
- id: "ghost",
2028
- name: "Ghost",
2029
- enabled: true,
2030
- priority: 3,
2031
- background: {
2032
- type: "surface",
2033
- role: "link"
2034
- },
2035
- borderRadius: "rounded-none",
2036
- sizes: {
2037
- sm: {
2038
- padding: "0.375rem 0",
2039
- fontSize: "text-xs"
2448
+ ghost: {
2449
+ kind: "complete",
2450
+ appearance: {
2451
+ background: {
2452
+ type: "surface",
2453
+ role: "link"
2040
2454
  },
2041
- md: {
2042
- padding: "0.5rem 0",
2043
- fontSize: "text-sm"
2455
+ borderRadius: "rounded-lg",
2456
+ effects: { hover: [{ effectId: "lift" }] }
2457
+ }
2458
+ },
2459
+ accent: {
2460
+ kind: "complete",
2461
+ appearance: {
2462
+ background: {
2463
+ type: "solid",
2464
+ colorToken: "accent"
2044
2465
  },
2045
- lg: {
2046
- padding: "0.625rem 0",
2047
- fontSize: "text-base"
2466
+ borderRadius: "rounded-lg",
2467
+ affordance: { iconId: "ArrowRight" },
2468
+ effects: { hover: [{ effectId: "lift" }] }
2469
+ }
2470
+ }
2471
+ }
2472
+ }
2473
+ });
2474
+ const showtimePillRecipe = defineStaticButtonStyleRecipe({
2475
+ id: "showtime-pill",
2476
+ accessibilityLabel: "Bold uppercase pill buttons with playful movement",
2477
+ tags: {
2478
+ tone: "bold",
2479
+ energy: "vibrant",
2480
+ motion: "expressive",
2481
+ era: "modern"
2482
+ },
2483
+ system: {
2484
+ global: {
2485
+ cornerStyle: "pill",
2486
+ shadow: "low",
2487
+ textTransform: "uppercase",
2488
+ fontWeight: 700,
2489
+ hoverTransform: "lift",
2490
+ hoverColor: "none",
2491
+ typography: "body",
2492
+ paddingPreset: "spacious",
2493
+ italic: false
2494
+ },
2495
+ sizes: {
2496
+ sm: {
2497
+ padding: "0.625rem 1.25rem",
2498
+ fontSize: "0.875rem"
2499
+ },
2500
+ md: {
2501
+ padding: "0.875rem 1.75rem",
2502
+ fontSize: "1rem"
2503
+ },
2504
+ lg: {
2505
+ padding: "1.125rem 2.25rem",
2506
+ fontSize: "1.125rem"
2507
+ },
2508
+ xl: {
2509
+ padding: "1.125rem 2.25rem",
2510
+ fontSize: "1.125rem"
2511
+ }
2512
+ },
2513
+ roles: {
2514
+ primary: {
2515
+ kind: "complete",
2516
+ appearance: {
2517
+ background: {
2518
+ type: "solid",
2519
+ colorToken: "primary"
2048
2520
  },
2049
- xl: {
2050
- padding: "0.75rem 0",
2051
- fontSize: "text-lg"
2052
- }
2053
- },
2054
- effects: { base: [{
2055
- effectId: "border-bottom-grow",
2056
- options: {
2057
- height: 1,
2058
- colorToken: "accent",
2059
- origin: "left"
2060
- }
2061
- }] }
2521
+ borderRadius: "rounded-full",
2522
+ effects: { hover: [{ effectId: "pop" }] }
2523
+ }
2524
+ },
2525
+ secondary: {
2526
+ kind: "complete",
2527
+ appearance: {
2528
+ background: {
2529
+ type: "surface",
2530
+ role: "link"
2531
+ },
2532
+ borderRadius: "rounded-full",
2533
+ border: { widthClass: "border-2" },
2534
+ effects: { hover: [{ effectId: "pop" }] }
2535
+ }
2536
+ },
2537
+ outline: {
2538
+ kind: "complete",
2539
+ appearance: {
2540
+ background: {
2541
+ type: "surface",
2542
+ role: "link"
2543
+ },
2544
+ borderRadius: "rounded-full",
2545
+ border: { widthClass: "border-2" },
2546
+ effects: { hover: [{
2547
+ effectId: "background-on-hover",
2548
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
2549
+ }] }
2550
+ }
2551
+ },
2552
+ ghost: {
2553
+ kind: "complete",
2554
+ appearance: {
2555
+ background: {
2556
+ type: "surface",
2557
+ role: "link"
2558
+ },
2559
+ borderRadius: "rounded-full",
2560
+ effects: { hover: [{
2561
+ effectId: "background-on-hover",
2562
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2563
+ }] }
2564
+ }
2565
+ },
2566
+ accent: {
2567
+ kind: "complete",
2568
+ appearance: {
2569
+ background: {
2570
+ type: "solid",
2571
+ colorToken: "secondary"
2572
+ },
2573
+ borderRadius: "rounded-full",
2574
+ effects: { hover: [{ effectId: "pop" }] }
2575
+ }
2062
2576
  }
2063
- ]
2577
+ }
2064
2578
  }
2065
2579
  });
2066
- //#endregion
2067
- //#region ../theme-core/src/buttons/personalities/joy-stamp.ts
2068
- /**
2069
- * Joy Stamp — neo-brutalist pills with a hard, brand-coloured offset shadow
2070
- * that collapses as the button presses into it on hover. Authored for the
2071
- * Original Joy site style: a cream "stamp" shadow under the solid primary, and
2072
- * a brown shadow under the cream outline. Reads as bold, warm, and handmade.
2073
- *
2074
- * The coloured offset shadow relies on the per-variant `shadow.colorToken`
2075
- * extension; the press is the shared `press-down` effect, which matches its
2076
- * translate to each variant's own shadow offset.
2077
- */
2078
- const joyStamp = defineButtonPersonality({
2580
+ const joyStampRecipe = defineStaticButtonStyleRecipe({
2079
2581
  id: "joy-stamp",
2080
- name: "Joy Stamp",
2081
- description: "Pill buttons with a hard, brand-coloured offset shadow that presses in on hover.",
2582
+ accessibilityLabel: "Bold pill buttons with a hard offset shadow",
2082
2583
  tags: {
2083
2584
  tone: "bold",
2084
2585
  energy: "vibrant",
2085
2586
  motion: "expressive",
2086
2587
  era: "organic"
2087
2588
  },
2088
- buttonSystem: {
2589
+ system: {
2089
2590
  global: {
2090
2591
  cornerStyle: "pill",
2091
2592
  shadow: "high",
@@ -2093,7 +2594,6 @@ const joyStamp = defineButtonPersonality({
2093
2594
  typography: "heading",
2094
2595
  fontWeight: 700,
2095
2596
  fontSize: "text-lg",
2096
- borderWidth: 2,
2097
2597
  hoverTransform: "none",
2098
2598
  hoverColor: "none"
2099
2599
  },
@@ -2115,66 +2615,82 @@ const joyStamp = defineButtonPersonality({
2115
2615
  fontSize: "text-2xl"
2116
2616
  }
2117
2617
  },
2118
- variants: [{
2119
- id: "primary",
2120
- name: "Primary",
2121
- enabled: true,
2122
- priority: 1,
2123
- background: {
2124
- type: "solid",
2125
- colorToken: "primary"
2618
+ roles: {
2619
+ primary: {
2620
+ kind: "complete",
2621
+ appearance: {
2622
+ background: {
2623
+ type: "solid",
2624
+ colorToken: "primary"
2625
+ },
2626
+ borderRadius: "rounded-full",
2627
+ shadow: {
2628
+ elevation: "high",
2629
+ softness: "hard",
2630
+ position: "bottom-right",
2631
+ colorToken: unsafeAsOpaqueButtonColourToken("text")
2632
+ },
2633
+ effects: { hover: [{ effectId: "press-down" }] }
2634
+ }
2126
2635
  },
2127
- borderRadius: "rounded-full",
2128
- shadow: {
2129
- elevation: "high",
2130
- softness: "hard",
2131
- position: "bottom-right",
2132
- colorToken: "text"
2636
+ secondary: {
2637
+ kind: "complete",
2638
+ appearance: {
2639
+ background: {
2640
+ type: "surface",
2641
+ role: "link"
2642
+ },
2643
+ borderRadius: "rounded-full",
2644
+ border: { widthClass: "border-2" },
2645
+ shadow: {
2646
+ elevation: "high",
2647
+ softness: "hard",
2648
+ position: "bottom-right",
2649
+ colorToken: unsafeAsOpaqueButtonColourToken("secondary")
2650
+ },
2651
+ effects: { hover: [{ effectId: "press-down" }] }
2652
+ }
2133
2653
  },
2134
- effects: { hover: [{ effectId: "press-down" }] }
2135
- }, {
2136
- id: "secondary",
2137
- name: "Secondary",
2138
- enabled: true,
2139
- priority: 2,
2140
- background: {
2141
- type: "surface",
2142
- role: "link"
2654
+ outline: {
2655
+ kind: "derive",
2656
+ from: "secondary"
2143
2657
  },
2144
- borderRadius: "rounded-full",
2145
- border: { widthClass: "border-2" },
2146
- shadow: {
2147
- elevation: "high",
2148
- softness: "hard",
2149
- position: "bottom-right",
2150
- colorToken: "secondary"
2658
+ ghost: {
2659
+ kind: "complete",
2660
+ appearance: {
2661
+ background: {
2662
+ type: "surface",
2663
+ role: "link"
2664
+ },
2665
+ borderRadius: "rounded-full",
2666
+ effects: { hover: [{ effectId: "press-down" }] }
2667
+ }
2151
2668
  },
2152
- effects: { hover: [{ effectId: "press-down" }] }
2153
- }]
2669
+ accent: {
2670
+ kind: "derive",
2671
+ from: "primary",
2672
+ overrides: { background: {
2673
+ type: "solid",
2674
+ colorToken: "accent"
2675
+ } }
2676
+ }
2677
+ }
2154
2678
  }
2155
2679
  });
2156
- //#endregion
2157
- //#region ../theme-core/src/buttons/personalities/ornate-ritual.ts
2158
- /**
2159
- * Ornate Ritual — framed, ceremonial buttons with jewel-toned fills and
2160
- * deliberate spacing. Designed for music, ceremony, and soulful event sites.
2161
- */
2162
- const ornateRitual = defineButtonPersonality({
2680
+ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
2163
2681
  id: "ornate-ritual",
2164
- name: "Ornate Ritual",
2165
- description: "Ceremonial framed buttons with jewel-toned fills and quiet color-change hover states.",
2682
+ accessibilityLabel: "Uppercase framed buttons with restrained movement",
2166
2683
  tags: {
2167
2684
  tone: "classic",
2168
2685
  energy: "vibrant",
2169
2686
  motion: "subtle",
2170
2687
  era: "organic"
2171
2688
  },
2172
- buttonSystem: {
2689
+ system: {
2173
2690
  global: {
2174
2691
  cornerStyle: "rounded",
2175
2692
  textTransform: "uppercase",
2176
2693
  fontWeight: 600,
2177
- borderWidth: 1,
2178
2694
  hoverTransform: "none",
2179
2695
  hoverColor: "none",
2180
2696
  letterSpacing: "loose"
@@ -2188,763 +2704,182 @@ const ornateRitual = defineButtonPersonality({
2188
2704
  padding: "0.75rem 1.75rem",
2189
2705
  fontSize: "text-xs"
2190
2706
  },
2191
- lg: {
2192
- padding: "0.875rem 2.25rem",
2193
- fontSize: "text-sm"
2194
- },
2195
- xl: {
2196
- padding: "1rem 2.75rem",
2197
- fontSize: "text-base"
2198
- }
2199
- },
2200
- variants: [
2201
- {
2202
- id: "primary",
2203
- name: "Primary",
2204
- enabled: true,
2205
- priority: 1,
2206
- background: {
2207
- type: "solid",
2208
- colorToken: "primary"
2209
- },
2210
- borderRadius: "rounded-md",
2211
- border: { widthClass: "border" },
2212
- effects: {
2213
- hover: [{
2214
- effectId: "background-on-hover",
2215
- options: { colorToken: "primary-100" }
2216
- }],
2217
- active: [{
2218
- effectId: "scale-down",
2219
- options: { scale: "0.98" }
2220
- }]
2221
- }
2222
- },
2223
- {
2224
- id: "secondary",
2225
- name: "Secondary",
2226
- enabled: true,
2227
- priority: 2,
2228
- background: {
2229
- type: "solid",
2230
- colorToken: "secondary"
2231
- },
2232
- borderRadius: "rounded-md",
2233
- border: { widthClass: "border" },
2234
- effects: { hover: [{
2235
- effectId: "background-on-hover",
2236
- options: { colorToken: "surface" }
2237
- }] }
2238
- },
2239
- {
2240
- id: "outline",
2241
- name: "Outline",
2242
- enabled: true,
2243
- priority: 3,
2244
- background: {
2245
- type: "surface",
2246
- role: "link"
2247
- },
2248
- borderRadius: "rounded-md",
2249
- border: { widthClass: "border" },
2250
- effects: { hover: [{
2251
- effectId: "background-on-hover",
2252
- options: { colorToken: "muted" }
2253
- }] }
2254
- },
2255
- {
2256
- id: "ghost",
2257
- name: "Ghost",
2258
- enabled: true,
2259
- priority: 3,
2260
- background: {
2261
- type: "surface",
2262
- role: "link"
2263
- },
2264
- borderRadius: "rounded-none",
2265
- sizes: {
2266
- sm: {
2267
- padding: "0.375rem 0",
2268
- fontSize: "text-xs"
2269
- },
2270
- md: {
2271
- padding: "0.5rem 0",
2272
- fontSize: "text-sm"
2273
- },
2274
- lg: {
2275
- padding: "0.625rem 0",
2276
- fontSize: "text-base"
2277
- },
2278
- xl: {
2279
- padding: "0.75rem 0",
2280
- fontSize: "text-lg"
2281
- }
2282
- },
2283
- effects: { base: [{
2284
- effectId: "border-bottom-grow",
2285
- options: {
2286
- height: 1,
2287
- colorToken: "accent",
2288
- origin: "left"
2289
- }
2290
- }] }
2291
- }
2292
- ]
2293
- }
2294
- });
2295
- //#endregion
2296
- //#region ../theme-core/src/buttons/personalities/pebble.ts
2297
- /**
2298
- * Pebble — large pill primaries with generous padding. Reads as spa-luxurious
2299
- * and natural; pairs well with wellness/yoga/dance brands.
2300
- */
2301
- const pebble = defineButtonPersonality({
2302
- id: "pebble",
2303
- name: "Pebble",
2304
- description: "Generous pill buttons with a quiet colour-softening hover.",
2305
- tags: {
2306
- tone: "classic",
2307
- energy: "calm",
2308
- motion: "standard",
2309
- era: "organic"
2310
- },
2311
- buttonSystem: {
2312
- global: {
2313
- cornerStyle: "pill",
2314
- textTransform: "none",
2315
- fontWeight: 500,
2316
- borderWidth: 2,
2317
- hoverTransform: "none",
2318
- hoverColor: "none"
2319
- },
2320
- sizes: {
2321
- sm: {
2322
- padding: "0.625rem 1.75rem",
2323
- fontSize: "text-sm"
2324
- },
2325
- md: { padding: "0.875rem 2.25rem" },
2326
- lg: {
2327
- padding: "1.125rem 2.75rem",
2328
- fontSize: "text-lg"
2329
- },
2330
- xl: {
2331
- padding: "1.5rem 3.5rem",
2332
- fontSize: "text-xl"
2333
- }
2334
- },
2335
- variants: [
2336
- {
2337
- id: "primary",
2338
- name: "Primary",
2339
- enabled: true,
2340
- priority: 1,
2341
- background: {
2342
- type: "solid",
2343
- colorToken: "primary"
2344
- },
2345
- borderRadius: "rounded-full",
2346
- effects: { hover: [{
2347
- effectId: "darken-background",
2348
- options: { amount: 100 }
2349
- }] }
2350
- },
2351
- {
2352
- id: "secondary",
2353
- name: "Secondary",
2354
- enabled: true,
2355
- priority: 2,
2356
- background: {
2357
- type: "surface",
2358
- role: "link"
2359
- },
2360
- borderRadius: "rounded-full",
2361
- border: { widthClass: "border-2" },
2362
- effects: { hover: [{
2363
- effectId: "background-on-hover",
2364
- options: { colorToken: "accent" }
2365
- }] }
2366
- },
2367
- {
2368
- id: "outline",
2369
- name: "Outline",
2370
- enabled: true,
2371
- priority: 3,
2372
- background: {
2373
- type: "surface",
2374
- role: "link"
2375
- },
2376
- borderRadius: "rounded-full",
2377
- border: { widthClass: "border" },
2378
- effects: { hover: [{
2379
- effectId: "background-on-hover",
2380
- options: { colorToken: "surface" }
2381
- }] }
2382
- },
2383
- {
2384
- id: "ghost",
2385
- name: "Ghost",
2386
- enabled: true,
2387
- priority: 3,
2388
- background: {
2389
- type: "surface",
2390
- role: "link"
2391
- },
2392
- borderRadius: "rounded-full",
2393
- sizes: {
2394
- sm: {
2395
- padding: "0.375rem 0.875rem",
2396
- fontSize: "text-sm"
2397
- },
2398
- md: { padding: "0.5rem 1rem" },
2399
- lg: {
2400
- padding: "0.625rem 1.25rem",
2401
- fontSize: "text-lg"
2402
- },
2403
- xl: {
2404
- padding: "0.75rem 1.5rem",
2405
- fontSize: "text-xl"
2406
- }
2407
- }
2408
- }
2409
- ]
2410
- }
2411
- });
2412
- //#endregion
2413
- //#region ../theme-core/src/buttons/personalities/quiet-arrow.ts
2414
- /**
2415
- * Quiet Arrow — wide, flat editorial buttons for grounded service businesses.
2416
- * Primary and secondary keep stable semantic colours; surrounding surfaces are
2417
- * responsible for contrast rather than reversing the button roles.
2418
- */
2419
- const quietArrow = defineButtonPersonality({
2420
- id: "quiet-arrow",
2421
- name: "Quiet Arrow",
2422
- description: "Wide, flat arrow buttons with a solid primary and a primary-colour outlined secondary.",
2423
- tags: {
2424
- tone: "classic",
2425
- energy: "calm",
2426
- motion: "subtle",
2427
- era: "editorial"
2428
- },
2429
- buttonSystem: {
2430
- global: {
2431
- cornerStyle: "rounded",
2432
- textTransform: "uppercase",
2433
- fontWeight: 500,
2434
- borderWidth: 1,
2435
- typography: "body",
2436
- fontSize: "text-sm",
2437
- letterSpacing: "loose",
2438
- hoverTransform: "none",
2439
- hoverColor: "none"
2440
- },
2441
- sizes: {
2442
- sm: {
2443
- padding: "0.625rem 1.25rem",
2444
- fontSize: "text-xs"
2445
- },
2446
- md: {
2447
- padding: "0.8125rem 1.75rem",
2448
- fontSize: "text-sm"
2449
- },
2450
- lg: {
2451
- padding: "0.9375rem 2.125rem",
2452
- fontSize: "text-sm"
2453
- },
2454
- xl: {
2455
- padding: "1.0625rem 2.5rem",
2456
- fontSize: "text-base"
2457
- }
2458
- },
2459
- variants: [
2460
- {
2461
- id: "primary",
2462
- name: "Primary",
2463
- enabled: true,
2464
- priority: 1,
2465
- background: {
2466
- type: "solid",
2467
- colorToken: "primary"
2468
- },
2469
- borderRadius: "rounded-xl",
2470
- affordance: { iconId: "ArrowRight" },
2471
- effects: { hover: [{
2472
- effectId: "darken-background",
2473
- options: { amount: 100 }
2474
- }] }
2475
- },
2476
- {
2477
- id: "secondary",
2478
- name: "Secondary",
2479
- enabled: true,
2480
- priority: 2,
2481
- background: {
2482
- type: "surface",
2483
- role: "link"
2484
- },
2485
- borderRadius: "rounded-xl",
2486
- border: { widthClass: "border" },
2487
- affordance: { iconId: "ArrowRight" },
2488
- effects: { hover: [{
2489
- effectId: "background-on-hover",
2490
- options: { colorToken: "surfaceAlt" }
2491
- }] }
2492
- },
2493
- {
2494
- id: "outline",
2495
- name: "Outline",
2496
- enabled: true,
2497
- priority: 3,
2498
- background: {
2499
- type: "surface",
2500
- role: "link"
2501
- },
2502
- borderRadius: "rounded-xl",
2503
- border: { widthClass: "border" }
2504
- },
2505
- {
2506
- id: "ghost",
2507
- name: "Ghost",
2508
- enabled: true,
2509
- priority: 3,
2510
- background: {
2511
- type: "surface",
2512
- role: "link"
2513
- },
2514
- borderRadius: "rounded-xl"
2515
- }
2516
- ]
2517
- }
2518
- });
2519
- //#endregion
2520
- //#region ../theme-core/src/buttons/personalities/showtime-pill.ts
2521
- /**
2522
- * Showtime Pill — bold, spacious, fully rounded buttons with playful pop
2523
- * motion. Suits energetic schools, performers, festivals, and community brands
2524
- * that need calls to action to feel loud without becoming visually chaotic.
2525
- */
2526
- const showtimePill = defineButtonPersonality({
2527
- id: "showtime-pill",
2528
- name: "Showtime Pill",
2529
- description: "Bold pill buttons with uppercase labels, generous padding, and a playful pop.",
2530
- tags: {
2531
- tone: "bold",
2532
- energy: "vibrant",
2533
- motion: "expressive",
2534
- era: "modern"
2535
- },
2536
- buttonSystem: {
2537
- global: {
2538
- cornerStyle: "pill",
2539
- shadow: "low",
2540
- textTransform: "uppercase",
2541
- fontWeight: 700,
2542
- borderWidth: 2,
2543
- hoverTransform: "lift",
2544
- hoverColor: "darken",
2545
- typography: "body",
2546
- paddingPreset: "spacious",
2547
- italic: false
2548
- },
2549
- sizes: {
2550
- sm: {
2551
- padding: "0.625rem 1.25rem",
2552
- fontSize: "0.875rem"
2553
- },
2554
- md: {
2555
- padding: "0.875rem 1.75rem",
2556
- fontSize: "1rem"
2557
- },
2558
- lg: {
2559
- padding: "1.125rem 2.25rem",
2560
- fontSize: "1.125rem"
2561
- },
2562
- xl: {
2563
- padding: "1.125rem 2.25rem",
2564
- fontSize: "1.125rem"
2565
- }
2566
- },
2567
- variants: [
2568
- {
2569
- id: "primary",
2570
- name: "Primary",
2571
- enabled: true,
2572
- priority: 1,
2573
- background: {
2574
- type: "solid",
2575
- colorToken: "primary"
2576
- },
2577
- borderRadius: "rounded-full",
2578
- effects: { hover: [{ effectId: "pop" }] }
2579
- },
2580
- {
2581
- id: "secondary",
2582
- name: "Secondary",
2583
- enabled: true,
2584
- priority: 2,
2585
- background: {
2586
- type: "surface",
2587
- role: "link"
2588
- },
2589
- borderRadius: "rounded-full",
2590
- border: { widthClass: "border-2" },
2591
- effects: { hover: [{ effectId: "pop" }] }
2592
- },
2593
- {
2594
- id: "hero",
2595
- name: "Hero",
2596
- enabled: true,
2597
- priority: 1,
2598
- background: {
2599
- type: "solid",
2600
- colorToken: "secondary"
2601
- },
2602
- borderRadius: "rounded-full",
2603
- effects: { hover: [{ effectId: "pop" }] }
2604
- },
2605
- {
2606
- id: "header",
2607
- name: "Header",
2608
- enabled: true,
2609
- priority: 2,
2610
- background: {
2611
- type: "solid",
2612
- colorToken: "background"
2613
- },
2614
- borderRadius: "rounded-full",
2615
- border: { widthClass: "border-2" },
2616
- effects: { hover: [{
2617
- effectId: "background-on-hover",
2618
- options: { colorToken: "surface" }
2619
- }] }
2620
- },
2621
- {
2622
- id: "outline",
2623
- name: "Outline",
2624
- enabled: true,
2625
- priority: 3,
2626
- background: {
2627
- type: "surface",
2628
- role: "link"
2629
- },
2630
- borderRadius: "rounded-full",
2631
- border: { widthClass: "border-2" },
2632
- effects: { hover: [{
2633
- effectId: "background-on-hover",
2634
- options: { colorToken: "background" }
2635
- }] }
2636
- },
2637
- {
2638
- id: "ghost",
2639
- name: "Ghost",
2640
- enabled: true,
2641
- priority: 3,
2642
- background: {
2643
- type: "surface",
2644
- role: "link"
2645
- },
2646
- borderRadius: "rounded-full",
2647
- effects: { hover: [{
2648
- effectId: "background-on-hover",
2649
- options: { colorToken: "surface" }
2650
- }] }
2651
- }
2652
- ]
2653
- }
2654
- });
2655
- //#endregion
2656
- //#region ../theme-core/src/buttons/personalities/soft-pill.ts
2657
- /**
2658
- * Soft Pill — rounded-full pill buttons with a hover lift. The default for
2659
- * Calm Studio and Modern Wellness; reads as quietly modern and welcoming.
2660
- */
2661
- const softPill = defineButtonPersonality({
2662
- id: "soft-pill",
2663
- name: "Soft Pill",
2664
- description: "Rounded pills with a gentle lift on hover. Quietly modern.",
2665
- tags: {
2666
- tone: "classic",
2667
- energy: "calm",
2668
- motion: "subtle",
2669
- era: "organic"
2670
- },
2671
- buttonSystem: {
2672
- global: {
2673
- cornerStyle: "pill",
2674
- shadow: "low",
2675
- textTransform: "none",
2676
- fontWeight: 500,
2677
- borderWidth: 2,
2678
- hoverTransform: "lift",
2679
- hoverColor: "none"
2680
- },
2681
- variants: [
2682
- {
2683
- id: "primary",
2684
- name: "Primary",
2685
- enabled: true,
2686
- priority: 1,
2687
- background: {
2688
- type: "solid",
2689
- colorToken: "primary"
2690
- },
2691
- borderRadius: "rounded-full",
2692
- shadow: {
2693
- elevation: "low",
2694
- softness: "soft",
2695
- position: "bottom"
2696
- },
2697
- effects: {
2698
- hover: [{
2699
- effectId: "lift",
2700
- options: { translateY: "-1px" }
2701
- }],
2702
- active: [{
2703
- effectId: "scale-down",
2704
- options: { scale: "0.98" }
2705
- }]
2706
- }
2707
- },
2708
- {
2709
- id: "secondary",
2710
- name: "Secondary",
2711
- enabled: true,
2712
- priority: 2,
2713
- background: {
2714
- type: "surface",
2715
- role: "link"
2716
- },
2717
- borderRadius: "rounded-full",
2718
- border: { widthClass: "border-2" },
2719
- effects: { hover: [{
2720
- effectId: "background-on-hover",
2721
- options: { colorToken: "surface" }
2722
- }] }
2723
- },
2724
- {
2725
- id: "outline",
2726
- name: "Outline",
2727
- enabled: true,
2728
- priority: 3,
2729
- background: {
2730
- type: "surface",
2731
- role: "link"
2732
- },
2733
- borderRadius: "rounded-full",
2734
- border: { widthClass: "border" },
2735
- effects: { hover: [{
2736
- effectId: "background-on-hover",
2737
- options: { colorToken: "surface" }
2738
- }] }
2739
- },
2740
- {
2741
- id: "ghost",
2742
- name: "Ghost",
2743
- enabled: true,
2744
- priority: 3,
2745
- background: {
2746
- type: "surface",
2747
- role: "link"
2748
- },
2749
- borderRadius: "rounded-full",
2750
- effects: { hover: [{
2751
- effectId: "background-on-hover",
2752
- options: { colorToken: "surface" }
2753
- }] }
2754
- }
2755
- ]
2756
- }
2757
- });
2758
- //#endregion
2759
- //#region ../theme-core/src/buttons/personalities/two-tone-pill.ts
2760
- const solidSecondary = {
2761
- id: "secondary",
2762
- name: "Secondary",
2763
- enabled: true,
2764
- priority: 2,
2765
- background: {
2766
- type: "solid",
2767
- colorToken: unsafeAsOpaqueButtonColourToken("secondary")
2768
- },
2769
- borderRadius: "rounded-full",
2770
- shadow: {
2771
- elevation: "none",
2772
- softness: null,
2773
- position: "bottom"
2774
- },
2775
- effects: {
2776
- hover: [{
2777
- effectId: "background-on-hover-alpha",
2778
- options: {
2779
- colorToken: "secondary",
2780
- opacity: 88
2781
- }
2782
- }],
2783
- active: [{
2784
- effectId: "scale-down",
2785
- options: { scale: "0.98" }
2786
- }]
2787
- }
2788
- };
2789
- //#endregion
2790
- //#region ../theme-core/src/buttons/personalities/index.ts
2791
- const buttonPersonalities = [
2792
- softPill,
2793
- defineButtonPersonality({
2794
- id: "two-tone-pill",
2795
- name: "Two-tone Pill",
2796
- description: "Rounded pills with distinct solid primary and secondary brand colours.",
2797
- tags: softPill.tags,
2798
- buttonSystem: {
2799
- ...softPill.buttonSystem,
2800
- variants: softPill.buttonSystem.variants.map((variant) => variant.id === "secondary" ? solidSecondary : variant)
2801
- }
2802
- }),
2803
- earthPill,
2804
- confidentChip,
2805
- editorialLink,
2806
- pebble,
2807
- inkStamp,
2808
- flatInk,
2809
- brushedWash,
2810
- showtimePill,
2811
- joyStamp,
2812
- ornateRitual,
2813
- quietArrow
2814
- ];
2815
- new Map(buttonPersonalities.map((p) => [p.id, p]));
2816
- buttonPersonalities.map((personality) => ({
2817
- id: personality.id,
2818
- name: personality.name,
2819
- description: personality.description,
2820
- category: presetCategory(personality),
2821
- buttonSystem: personality.buttonSystem,
2822
- compatibility: {
2823
- ...personality.tags.tone ? { tones: [personality.tags.tone] } : {},
2824
- ...personality.tags.energy ? { energies: [personality.tags.energy] } : {}
2825
- }
2826
- }));
2827
- function presetCategory(personality) {
2828
- switch (personality.tags.era) {
2829
- case "retro": return "retro";
2830
- case "editorial": return "minimal";
2831
- case "organic": return "artistic";
2832
- case "modern": return personality.tags.tone === "bold" ? "modern" : "technical";
2833
- case "technical": return "technical";
2834
- case void 0: return "modern";
2835
- }
2836
- }
2837
- //#endregion
2838
- //#region ../theme-core/src/buttons/core.ts
2839
- const CORNER_RADIUS_MAP$2 = {
2840
- square: "0",
2841
- soft: "0.375rem",
2842
- rounded: "0.5rem",
2843
- pill: "9999px"
2844
- };
2845
- const BORDER_WIDTH_MAP$2 = {
2846
- none: "0",
2847
- thin: "1px",
2848
- medium: "2px",
2849
- thick: "4px"
2850
- };
2851
- const SHADOW_VALUES$2 = {
2852
- none: "none",
2853
- low: "0 1px 2px rgba(0,0,0,0.06)",
2854
- medium: "0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)",
2855
- high: "0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)"
2856
- };
2857
- const RESOLVER_GLOBAL = {
2858
- cornerStyle: "rounded",
2859
- textTransform: "none",
2860
- fontWeight: 500,
2861
- borderWidth: 1,
2862
- hoverTransform: "none",
2863
- hoverColor: "none"
2864
- };
2865
- function generateButtonCoreCss(scopeId, variants, settings, palette) {
2866
- return variants.map((variant) => generateVariantCss$1(scopeId, variant, settings, palette)).join("\n\n");
2867
- }
2868
- function generateVariantCss$1(scopeId, variant, settings, palette) {
2869
- const borderWidth = BORDER_WIDTH_MAP$2[variant.borderWidth ?? "none"];
2870
- const result = compileButtonColourStates({
2871
- variant: {
2872
- id: variant.id,
2873
- name: variant.id,
2874
- enabled: true,
2875
- priority: 1,
2876
- background: variant.treatment,
2877
- ...borderWidth === "0" ? {} : { border: { widthClass: borderWidth } }
2878
- },
2879
- global: RESOLVER_GLOBAL,
2880
- palette
2881
- });
2882
- if (!result.ok) throw new Error(`[ThemeBridge] ${formatButtonColourContractError(result.error)}`);
2883
- const selector = `:where([data-theme-scope="${scopeId}"]) .button-${variant.id}`;
2884
- return [
2885
- rule(selector, [
2886
- ...borderWidth === "0" ? ["padding: 0.5rem 1rem;"] : [
2887
- `padding-top: calc(0.5rem - ${borderWidth});`,
2888
- `padding-bottom: calc(0.5rem - ${borderWidth});`,
2889
- `padding-left: calc(1rem - ${borderWidth});`,
2890
- `padding-right: calc(1rem - ${borderWidth});`
2891
- ],
2892
- `font-weight: ${settings.fontWeight ?? 500};`,
2893
- ...settings.textTransform && settings.textTransform !== "none" ? [`text-transform: ${settings.textTransform};`] : [],
2894
- "cursor: pointer;",
2895
- "transition: all 200ms ease-in-out;",
2896
- "display: inline-flex;",
2897
- "align-items: center;",
2898
- "justify-content: center;",
2899
- `border-radius: ${CORNER_RADIUS_MAP$2[settings.corners]};`,
2900
- `box-shadow: ${SHADOW_VALUES$2[settings.shadow]};`,
2901
- ...declarationStrings(resolvedButtonColourDeclarations(result.states.base)),
2902
- borderWidth === "0" ? "border: none;" : `border: ${borderWidth} solid currentColor;`
2903
- ]),
2904
- rule(`${selector}:hover`, declarationStrings(resolvedButtonColourDeclarations(result.states.hover))),
2905
- rule(`${selector}:active`, [...declarationStrings(resolvedButtonColourDeclarations(result.states.active)), "transform: scale(0.98);"]),
2906
- rule(`${selector}:focus-visible`, declarationStrings(resolvedButtonFocusDeclarations(result.focusIndicator))),
2907
- rule(`${selector}:disabled,\n${selector}:disabled:hover,\n${selector}:disabled:active`, [...declarationStrings(resolvedButtonColourDeclarations(result.states.disabled)), ...declarationStrings(RESOLVED_BUTTON_DISABLED_DECLARATIONS)])
2908
- ].join("\n\n");
2909
- }
2910
- function declarationStrings(declarations) {
2911
- return declarations.map(([property, value]) => `${property}: ${value};`);
2912
- }
2913
- function rule(selector, declarations) {
2914
- return `${selector} {\n ${declarations.join("\n ")}\n}`;
2915
- }
2916
- function getDefaultButtonVariants() {
2917
- return [
2918
- {
2919
- id: "primary",
2920
- treatment: {
2921
- type: "solid",
2922
- colorToken: unsafeAsOpaqueButtonColourToken("primary")
2923
- }
2924
- },
2925
- {
2926
- id: "secondary",
2927
- treatment: {
2928
- type: "solid",
2929
- colorToken: unsafeAsOpaqueButtonColourToken("secondary")
2707
+ lg: {
2708
+ padding: "0.875rem 2.25rem",
2709
+ fontSize: "text-sm"
2710
+ },
2711
+ xl: {
2712
+ padding: "1rem 2.75rem",
2713
+ fontSize: "text-base"
2930
2714
  }
2931
2715
  },
2932
- {
2933
- id: "outline",
2934
- treatment: {
2935
- type: "surface",
2936
- role: "link"
2716
+ roles: {
2717
+ primary: {
2718
+ kind: "complete",
2719
+ appearance: {
2720
+ background: {
2721
+ type: "solid",
2722
+ colorToken: "primary"
2723
+ },
2724
+ borderRadius: "rounded-md",
2725
+ border: { widthClass: "border" },
2726
+ effects: {
2727
+ hover: [{
2728
+ effectId: "background-on-hover",
2729
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("primary-100") }
2730
+ }],
2731
+ active: [{
2732
+ effectId: "scale-down",
2733
+ options: { scale: "0.98" }
2734
+ }]
2735
+ }
2736
+ }
2937
2737
  },
2938
- borderWidth: "thin"
2939
- },
2940
- {
2941
- id: "ghost",
2942
- treatment: {
2943
- type: "surface",
2944
- role: "link"
2738
+ secondary: {
2739
+ kind: "complete",
2740
+ appearance: {
2741
+ background: {
2742
+ type: "solid",
2743
+ colorToken: "secondary"
2744
+ },
2745
+ borderRadius: "rounded-md",
2746
+ border: { widthClass: "border" },
2747
+ effects: { hover: [{
2748
+ effectId: "background-on-hover",
2749
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2750
+ }] }
2751
+ }
2752
+ },
2753
+ outline: {
2754
+ kind: "complete",
2755
+ appearance: {
2756
+ background: {
2757
+ type: "surface",
2758
+ role: "link"
2759
+ },
2760
+ borderRadius: "rounded-md",
2761
+ border: { widthClass: "border" },
2762
+ effects: { hover: [{
2763
+ effectId: "background-on-hover",
2764
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
2765
+ }] }
2766
+ }
2767
+ },
2768
+ ghost: {
2769
+ kind: "complete",
2770
+ appearance: {
2771
+ background: {
2772
+ type: "surface",
2773
+ role: "link"
2774
+ },
2775
+ borderRadius: "rounded-none",
2776
+ sizes: {
2777
+ sm: {
2778
+ padding: "0.375rem 0",
2779
+ fontSize: "text-xs"
2780
+ },
2781
+ md: {
2782
+ padding: "0.5rem 0",
2783
+ fontSize: "text-sm"
2784
+ },
2785
+ lg: {
2786
+ padding: "0.625rem 0",
2787
+ fontSize: "text-base"
2788
+ },
2789
+ xl: {
2790
+ padding: "0.75rem 0",
2791
+ fontSize: "text-lg"
2792
+ }
2793
+ },
2794
+ effects: { base: [{
2795
+ effectId: "border-bottom-grow",
2796
+ options: {
2797
+ height: 1,
2798
+ origin: "left"
2799
+ }
2800
+ }] }
2801
+ }
2802
+ },
2803
+ accent: {
2804
+ kind: "derive",
2805
+ from: "primary",
2806
+ overrides: { background: {
2807
+ type: "solid",
2808
+ colorToken: "accent"
2809
+ } }
2945
2810
  }
2946
2811
  }
2947
- ];
2812
+ }
2813
+ });
2814
+ //#endregion
2815
+ //#region ../theme-core/src/buttons/styles/registry.ts
2816
+ const buttonStyleRecipes = [
2817
+ softPillRecipe,
2818
+ earthPillRecipe,
2819
+ confidentChipRecipe,
2820
+ editorialLinkRecipe,
2821
+ pebbleRecipe,
2822
+ inkStampRecipe,
2823
+ flatInkRecipe,
2824
+ brushedWashRecipe,
2825
+ showtimePillRecipe,
2826
+ joyStampRecipe,
2827
+ ornateRitualRecipe,
2828
+ quietArrowRecipe
2829
+ ];
2830
+ const recipesById = new Map(buttonStyleRecipes.map((recipe) => [recipe.id, recipe]));
2831
+ function findButtonStyleRecipe(id) {
2832
+ const recipe = recipesById.get(id);
2833
+ if (recipe === void 0) throw new Error(`Button style registry is missing known style ${id}`);
2834
+ return recipe;
2835
+ }
2836
+ function resolveButtonStyleSelection(selection) {
2837
+ switch (selection.styleId) {
2838
+ case "soft-pill": return resolveButtonStyleRecipe(softPillRecipe, selection.parameters);
2839
+ case "earth-pill": return resolveButtonStyleRecipe(earthPillRecipe, selection.parameters);
2840
+ case "confident-chip": return resolveButtonStyleRecipe(confidentChipRecipe, selection.parameters);
2841
+ case "editorial-link": return resolveButtonStyleRecipe(editorialLinkRecipe, selection.parameters);
2842
+ case "pebble": return resolveButtonStyleRecipe(pebbleRecipe, selection.parameters);
2843
+ case "ink-stamp": return resolveButtonStyleRecipe(inkStampRecipe, selection.parameters);
2844
+ case "flat-ink": return resolveButtonStyleRecipe(flatInkRecipe, selection.parameters);
2845
+ case "brushed-wash": return resolveButtonStyleRecipe(brushedWashRecipe, selection.parameters);
2846
+ case "showtime-pill": return resolveButtonStyleRecipe(showtimePillRecipe, selection.parameters);
2847
+ case "joy-stamp": return resolveButtonStyleRecipe(joyStampRecipe, selection.parameters);
2848
+ case "ornate-ritual": return resolveButtonStyleRecipe(ornateRitualRecipe, selection.parameters);
2849
+ case "quiet-arrow": return resolveButtonStyleRecipe(quietArrowRecipe, selection.parameters);
2850
+ }
2851
+ }
2852
+ function defaultButtonStyleSelectionFor(styleId) {
2853
+ return {
2854
+ styleId,
2855
+ parameters: findButtonStyleRecipe(styleId).defaultParameters
2856
+ };
2857
+ }
2858
+ 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");
2859
+ buttonStyleRecipes.map((recipe) => {
2860
+ const resolved = resolveButtonStyleSelection(defaultButtonStyleSelectionFor(recipe.id));
2861
+ if (resolved.kind === "error") throw new Error(`Invalid registered button style ${recipe.id}: ${resolved.error.issues.join(", ")}`);
2862
+ return {
2863
+ id: recipe.id,
2864
+ name: recipe.accessibilityLabel,
2865
+ description: recipe.accessibilityLabel,
2866
+ category: presetCategory(recipe),
2867
+ buttonSystem: resolved.buttonSystem,
2868
+ compatibility: {
2869
+ ...recipe.tags.tone ? { tones: [recipe.tags.tone] } : {},
2870
+ ...recipe.tags.energy ? { energies: [recipe.tags.energy] } : {}
2871
+ }
2872
+ };
2873
+ });
2874
+ function presetCategory(recipe) {
2875
+ switch (recipe.tags.era) {
2876
+ case "retro": return "retro";
2877
+ case "editorial": return "minimal";
2878
+ case "organic": return "artistic";
2879
+ case "modern": return recipe.tags.tone === "bold" ? "modern" : "technical";
2880
+ case "technical": return "technical";
2881
+ case void 0: return "modern";
2882
+ }
2948
2883
  }
2949
2884
  //#endregion
2950
2885
  //#region ../theme-core/src/cards/types.ts
@@ -3065,13 +3000,13 @@ const cardSystemSchema = z$1.object({ variants: z$1.array(cardVariantSchema).min
3065
3000
  * Pure functions for generating card CSS without requiring the full Theme type.
3066
3001
  * Used by both the full CMS theme system and the SDK theme bridge.
3067
3002
  */
3068
- const CORNER_RADIUS_MAP$1 = {
3003
+ const CORNER_RADIUS_MAP$2 = {
3069
3004
  square: "0",
3070
3005
  soft: "0.5rem",
3071
3006
  rounded: "1rem",
3072
3007
  pill: "1.5rem"
3073
3008
  };
3074
- const BORDER_WIDTH_MAP$1 = {
3009
+ const BORDER_WIDTH_MAP$2 = {
3075
3010
  none: "0",
3076
3011
  thin: "1px",
3077
3012
  medium: "2px",
@@ -3101,7 +3036,7 @@ const ACCENT_EDGE_SIDE_MAP = {
3101
3036
  * unspecified corner from the global corners setting.
3102
3037
  */
3103
3038
  function resolveCornerRadiiCss(cornerRadii, fallback) {
3104
- const fallbackValue = CORNER_RADIUS_MAP$1[fallback];
3039
+ const fallbackValue = CORNER_RADIUS_MAP$2[fallback];
3105
3040
  const at = (value) => value ? PER_CORNER_RADIUS_MAP[value] : fallbackValue;
3106
3041
  return `${at(cornerRadii.topLeft)} ${at(cornerRadii.topRight)} ${at(cornerRadii.bottomRight)} ${at(cornerRadii.bottomLeft)}`;
3107
3042
  }
@@ -3115,7 +3050,7 @@ const GRADIENT_DIRECTION_MAP = {
3115
3050
  "to-br": "to bottom right",
3116
3051
  "to-bl": "to bottom left"
3117
3052
  };
3118
- const SHADOW_VALUES$1 = {
3053
+ const SHADOW_VALUES$2 = {
3119
3054
  none: "none",
3120
3055
  low: "0 1px 2px rgba(0,0,0,0.06)",
3121
3056
  medium: "0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)",
@@ -3143,7 +3078,7 @@ const SPACING_MAP = {
3143
3078
  function generateCardCoreCss(scopeId, variants, settings) {
3144
3079
  const cssChunks = [];
3145
3080
  for (const variant of variants) {
3146
- const css = generateVariantCss(scopeId, variant, settings);
3081
+ const css = generateVariantCss$1(scopeId, variant, settings);
3147
3082
  cssChunks.push(css);
3148
3083
  }
3149
3084
  return cssChunks.join("\n\n");
@@ -3153,7 +3088,7 @@ function generateCardCoreCss(scopeId, variants, settings) {
3153
3088
  *
3154
3089
  * Selectors use :where() for zero specificity, allowing site styles to override easily.
3155
3090
  */
3156
- function generateVariantCss(scopeId, variant, settings) {
3091
+ function generateVariantCss$1(scopeId, variant, settings) {
3157
3092
  const containerSelector = `:where([data-theme-scope="${scopeId}"]) .card-${variant.id}`;
3158
3093
  const mediaSelector = `${containerSelector} .card-media`;
3159
3094
  const contentSelector = `${containerSelector} .card-content`;
@@ -3179,16 +3114,16 @@ function generateVariantCss(scopeId, variant, settings) {
3179
3114
  containerRules.push("border: 0");
3180
3115
  containerRules.push(`${side}: ${width} solid rgb(var(--tb-${variant.accentEdge.colorToken}))`);
3181
3116
  } else {
3182
- const borderWidth = variant.borderWidth ? BORDER_WIDTH_MAP$1[variant.borderWidth] : variant.borderToken ? BORDER_WIDTH_MAP$1[settings.borderWidth] : "0";
3117
+ const borderWidth = variant.borderWidth ? BORDER_WIDTH_MAP$2[variant.borderWidth] : variant.borderToken ? BORDER_WIDTH_MAP$2[settings.borderWidth] : "0";
3183
3118
  if (variant.borderToken && borderWidth !== "0") containerRules.push(`border: ${borderWidth} solid rgb(var(--tb-${variant.borderToken}))`);
3184
3119
  }
3185
- containerRules.push(`border-radius: ${variant.cornerRadii ? resolveCornerRadiiCss(variant.cornerRadii, settings.corners) : CORNER_RADIUS_MAP$1[settings.corners]}`);
3186
- if (settings.shadow !== "none") containerRules.push(`box-shadow: ${SHADOW_VALUES$1[settings.shadow]}`);
3120
+ containerRules.push(`border-radius: ${variant.cornerRadii ? resolveCornerRadiiCss(variant.cornerRadii, settings.corners) : CORNER_RADIUS_MAP$2[settings.corners]}`);
3121
+ if (settings.shadow !== "none") containerRules.push(`box-shadow: ${SHADOW_VALUES$2[settings.shadow]}`);
3187
3122
  containerRules.push("display: flex");
3188
3123
  containerRules.push("flex-direction: column");
3189
3124
  containerRules.push("position: relative");
3190
3125
  containerRules.push("overflow: visible");
3191
- const mediaRadius = CORNER_RADIUS_MAP$1[settings.corners];
3126
+ const mediaRadius = CORNER_RADIUS_MAP$2[settings.corners];
3192
3127
  const mediaRules = [`border-top-left-radius: ${mediaRadius}`, `border-top-right-radius: ${mediaRadius}`];
3193
3128
  const contentRules = [`padding: ${SPACING_MAP[variant.spacing]}`];
3194
3129
  return [
@@ -5217,6 +5152,39 @@ const paletteValueKeySchema = z$1.string().transform((value, ctx) => {
5217
5152
  return z$1.NEVER;
5218
5153
  });
5219
5154
  //#endregion
5155
+ //#region ../theme-core/src/site-styles/styleTags.ts
5156
+ /**
5157
+ * Descriptive style-axis metadata for button personalities and palette
5158
+ * variants. Site Style picker shape is curated explicitly; these tags remain
5159
+ * for catalog audit, docs, and future discovery tooling.
5160
+ */
5161
+ const STYLE_AXIS_VALUES = {
5162
+ tone: [
5163
+ "minimal",
5164
+ "classic",
5165
+ "bold"
5166
+ ],
5167
+ energy: ["calm", "vibrant"],
5168
+ motion: [
5169
+ "subtle",
5170
+ "standard",
5171
+ "expressive"
5172
+ ],
5173
+ era: [
5174
+ "editorial",
5175
+ "modern",
5176
+ "organic",
5177
+ "technical",
5178
+ "retro"
5179
+ ]
5180
+ };
5181
+ const styleTagsSchema = z$1.object({
5182
+ tone: z$1.enum(STYLE_AXIS_VALUES.tone).optional(),
5183
+ energy: z$1.enum(STYLE_AXIS_VALUES.energy).optional(),
5184
+ motion: z$1.enum(STYLE_AXIS_VALUES.motion).optional(),
5185
+ era: z$1.enum(STYLE_AXIS_VALUES.era).optional()
5186
+ });
5187
+ //#endregion
5220
5188
  //#region ../theme-core/src/palette/curated/types.ts
5221
5189
  function asCuratedPaletteAuthoringKey(value) {
5222
5190
  if (value.length === 0) throw new Error("CuratedPaletteAuthoringKey must be a non-empty string");
@@ -8082,324 +8050,92 @@ const headerLookCatalog = defineExactCatalog()([
8082
8050
  },
8083
8051
  {
8084
8052
  id: asHeaderLookId("centered-calm"),
8085
- label: "Centered calm",
8086
- visualTreatment: "light-serif",
8087
- layoutBehavior: "normal-flow",
8088
- configuration: {
8089
- structure: "centered-stack",
8090
- treatment: "light-serif",
8091
- behavior: "normal-flow"
8092
- },
8093
- openingRequirement: "none",
8094
- maxRecommendedNavItems: 5,
8095
- logoAccommodations: centeredLogoAccommodations,
8096
- compile: centeredCalmHeader
8097
- },
8098
- {
8099
- id: asHeaderLookId("practical-utility"),
8100
- label: "Practical utility",
8101
- visualTreatment: "solid-neutral",
8102
- layoutBehavior: "sticky-shrink",
8103
- configuration: {
8104
- structure: "inline-classic",
8105
- treatment: "solid-neutral",
8106
- behavior: "sticky-shrink"
8107
- },
8108
- openingRequirement: "none",
8109
- requiresProminentCta: true,
8110
- logoAccommodations: inlineClassicLogoAccommodations,
8111
- compile: practicalUtilityHeader
8112
- },
8113
- {
8114
- id: asHeaderLookId("minimal-transparent"),
8115
- label: "Minimal transparent",
8116
- visualTreatment: "minimal-transparent",
8117
- layoutBehavior: "normal-flow",
8118
- configuration: {
8119
- structure: "inline-classic",
8120
- treatment: "minimal-transparent",
8121
- behavior: "normal-flow"
8122
- },
8123
- openingRequirement: "reserved-space-ok",
8124
- logoAccommodations: inlineClassicLogoAccommodations,
8125
- compile: minimalTransparentHeader
8126
- },
8127
- {
8128
- id: asHeaderLookId("transparent-overlay"),
8129
- label: "Transparent overlay",
8130
- visualTreatment: "transparent-overlay",
8131
- layoutBehavior: "fixed-overlay",
8132
- configuration: {
8133
- structure: "inline-classic",
8134
- treatment: "transparent-overlay",
8135
- behavior: "fixed-overlay"
8136
- },
8137
- openingRequirement: "requires-image-hero-with-contrast-overlay",
8138
- maxRecommendedNavItems: 5,
8139
- logoAccommodations: overlayLogoAccommodations,
8140
- compile: transparentOverlayHeader
8141
- },
8142
- {
8143
- id: asHeaderLookId("floating-glass"),
8144
- label: "Floating glass",
8145
- visualTreatment: "floating-glass",
8146
- layoutBehavior: "fixed-floating",
8147
- configuration: {
8148
- structure: "floating-shell",
8149
- treatment: "floating-glass",
8150
- behavior: "fixed-floating"
8151
- },
8152
- openingRequirement: "requires-image-hero-with-contrast-overlay",
8153
- maxRecommendedNavItems: 5,
8154
- logoAccommodations: overlayLogoAccommodations,
8155
- compile: floatingGlassHeader
8156
- }
8157
- ]);
8158
- new Set(headerLookCatalog.map((look) => headerConfigurationKey(look.configuration)));
8159
- new Map(headerLookCatalog.map((look) => [look.id, look]));
8160
- function headerConfigurationKey(configuration) {
8161
- return `${configuration.structure}:${configuration.treatment}:${configuration.behavior}`;
8162
- }
8163
- //#endregion
8164
- //#region ../theme-core/src/site-styles/footerLooks.ts
8165
- function asFooterLookId(value) {
8166
- return value;
8167
- }
8168
- function asFooterLayoutId(value) {
8169
- return value;
8170
- }
8171
- function asFooterStyleId(value) {
8172
- return value;
8173
- }
8174
- const footerLayoutCatalog = defineExactCatalog()([
8175
- {
8176
- id: asFooterLayoutId("identity"),
8177
- label: "Identity",
8178
- description: "Logo, site text, address, and legal copy without relying on footer navigation."
8179
- },
8180
- {
8181
- id: asFooterLayoutId("centered"),
8182
- label: "Centered",
8183
- description: "A calm centered stack for identity, short copy, and optional compact navigation.",
8184
- maxRecommendedNavDensity: "sparse"
8185
- },
8186
- {
8187
- id: asFooterLayoutId("split"),
8188
- label: "Split",
8189
- description: "Navigation and brand signoff separated into a wider split footer.",
8190
- requiresFooterNav: true,
8191
- maxRecommendedNavDensity: "balanced"
8192
- },
8193
- {
8194
- id: asFooterLayoutId("columns"),
8195
- label: "Columns",
8196
- description: "Grouped footer navigation columns with a supporting bottom line.",
8197
- requiresFooterNav: true,
8198
- requiresFooterNavGroups: true
8199
- }
8200
- ]);
8201
- const footerStyleCatalog = defineExactCatalog()([
8202
- {
8203
- id: asFooterStyleId("quiet"),
8204
- label: "Quiet",
8205
- description: "Lightweight, practical footer treatment."
8206
- },
8207
- {
8208
- id: asFooterStyleId("calm"),
8209
- label: "Calm",
8210
- description: "Soft centered treatment with restrained dividers."
8211
- },
8212
- {
8213
- id: asFooterStyleId("editorial"),
8214
- label: "Editorial",
8215
- description: "Text-forward treatment with fine-line structure."
8216
- },
8217
- {
8218
- id: asFooterStyleId("brand-band"),
8219
- label: "Brand band",
8220
- description: "High-contrast brand treatment with a stronger bottom bar."
8221
- }
8222
- ]);
8223
- new Map(footerLayoutCatalog.map((layout) => [layout.id, layout]));
8224
- new Map(footerStyleCatalog.map((style) => [style.id, style]));
8225
- /**
8226
- * No-nav-safe identity footer: brand and legal/supporting copy carry the
8227
- * footer without implying missing navigation.
8228
- */
8229
- function identityQuietFooter(theme) {
8230
- return {
8231
- ...theme.footer,
8232
- variant: "simple",
8233
- maxWidth: "container",
8234
- background: {
8235
- type: "color",
8236
- color: "surface"
8237
- },
8238
- navStyle: "minimal",
8239
- navWeight: "regular",
8240
- navColor: "text",
8241
- navLinkStyle: {
8242
- typography: "body",
8243
- fontWeight: "regular",
8244
- textTransform: "none",
8245
- italic: false,
8246
- colorToken: "text",
8247
- hoverColorToken: "primary",
8248
- padding: "none",
8249
- borderRadius: "none"
8250
- },
8251
- navLayout: {
8252
- layout: "inline-wrap",
8253
- align: "start",
8254
- gapX: "default",
8255
- gapY: "tight"
8256
- },
8257
- logo: {
8258
- showLogo: true,
8259
- showLogoText: true,
8260
- placement: "left",
8261
- size: "sm",
8262
- align: "start"
8263
- },
8264
- bottomBar: {
8265
- enabled: false,
8266
- fullBleed: false,
8267
- textAlign: "left",
8268
- paddingX: "default",
8269
- paddingY: "compact",
8270
- borderTop: { width: "none" }
8271
- }
8272
- };
8273
- }
8274
- /**
8275
- * Back-compat alias for the previous default footer Look. It keeps existing
8276
- * persisted selections valid while staying hidden from the new layout/style UI.
8277
- */
8278
- function mutedGroundingFooter(theme) {
8279
- return {
8280
- ...identityQuietFooter(theme),
8281
- background: theme.footer.background,
8282
- navStyle: theme.footer.navStyle,
8283
- navColor: theme.footer.navColor,
8284
- navWeight: theme.footer.navWeight,
8285
- navLinkStyle: theme.footer.navLinkStyle,
8286
- bottomTextLinkStyle: theme.footer.bottomTextLinkStyle
8287
- };
8288
- }
8289
- /** Applies a high-contrast brand band with a darker full-bleed bottom bar. */
8290
- function brandTwoBandFooter(theme) {
8291
- return {
8292
- ...theme.footer,
8293
- variant: "split",
8294
- maxWidth: "container",
8295
- background: {
8296
- type: "color",
8297
- color: "primary-800"
8298
- },
8299
- navStyle: "minimal",
8300
- navWeight: "medium",
8301
- navColor: "primaryForeground",
8302
- navLinkStyle: {
8303
- typography: "body",
8304
- fontWeight: "medium",
8305
- textTransform: "none",
8306
- italic: false,
8307
- colorToken: "primaryForeground",
8308
- hoverColorToken: "secondary",
8309
- padding: "none",
8310
- borderRadius: "none"
8311
- },
8312
- bottomTextLinkStyle: {
8313
- colorToken: "secondary",
8314
- decorationColorToken: "secondary"
8315
- },
8316
- navLayout: {
8317
- layout: "inline-wrap",
8318
- align: "start",
8319
- gapX: "default",
8320
- gapY: "tight"
8321
- },
8322
- logo: {
8323
- showLogo: true,
8324
- showLogoText: false,
8325
- placement: "left",
8326
- size: "sm",
8327
- align: "start"
8053
+ label: "Centered calm",
8054
+ visualTreatment: "light-serif",
8055
+ layoutBehavior: "normal-flow",
8056
+ configuration: {
8057
+ structure: "centered-stack",
8058
+ treatment: "light-serif",
8059
+ behavior: "normal-flow"
8328
8060
  },
8329
- bottomBar: {
8330
- enabled: true,
8331
- fullBleed: true,
8332
- background: {
8333
- type: "color",
8334
- color: "primary-900"
8335
- },
8336
- textColor: "primaryForeground",
8337
- textAlign: "center",
8338
- paddingX: "default",
8339
- paddingY: "compact",
8340
- borderTop: { width: "none" }
8341
- }
8342
- };
8343
- }
8344
- /**
8345
- * Centered stack on a softly tinted band: logo, inline nav, address, and a
8346
- * hairline-topped copyright line, all centered.
8347
- */
8348
- function centeredCalmFooter(theme) {
8349
- return {
8350
- ...theme.footer,
8351
- variant: "simple",
8352
- maxWidth: "container",
8353
- background: {
8354
- type: "color",
8355
- color: "surfaceAlt"
8061
+ openingRequirement: "none",
8062
+ maxRecommendedNavItems: 5,
8063
+ logoAccommodations: centeredLogoAccommodations,
8064
+ compile: centeredCalmHeader
8065
+ },
8066
+ {
8067
+ id: asHeaderLookId("practical-utility"),
8068
+ label: "Practical utility",
8069
+ visualTreatment: "solid-neutral",
8070
+ layoutBehavior: "sticky-shrink",
8071
+ configuration: {
8072
+ structure: "inline-classic",
8073
+ treatment: "solid-neutral",
8074
+ behavior: "sticky-shrink"
8356
8075
  },
8357
- navStyle: "minimal",
8358
- navWeight: "regular",
8359
- navColor: "text",
8360
- navLinkStyle: {
8361
- typography: "body",
8362
- fontWeight: "regular",
8363
- textTransform: "none",
8364
- italic: false,
8365
- colorToken: "text",
8366
- hoverColorToken: "primary",
8367
- padding: "none",
8368
- borderRadius: "none"
8076
+ openingRequirement: "none",
8077
+ requiresProminentCta: true,
8078
+ logoAccommodations: inlineClassicLogoAccommodations,
8079
+ compile: practicalUtilityHeader
8080
+ },
8081
+ {
8082
+ id: asHeaderLookId("minimal-transparent"),
8083
+ label: "Minimal transparent",
8084
+ visualTreatment: "minimal-transparent",
8085
+ layoutBehavior: "normal-flow",
8086
+ configuration: {
8087
+ structure: "inline-classic",
8088
+ treatment: "minimal-transparent",
8089
+ behavior: "normal-flow"
8369
8090
  },
8370
- navLayout: {
8371
- layout: "inline-wrap",
8372
- align: "center",
8373
- gapX: "relaxed",
8374
- gapY: "tight"
8091
+ openingRequirement: "reserved-space-ok",
8092
+ logoAccommodations: inlineClassicLogoAccommodations,
8093
+ compile: minimalTransparentHeader
8094
+ },
8095
+ {
8096
+ id: asHeaderLookId("transparent-overlay"),
8097
+ label: "Transparent overlay",
8098
+ visualTreatment: "transparent-overlay",
8099
+ layoutBehavior: "fixed-overlay",
8100
+ configuration: {
8101
+ structure: "inline-classic",
8102
+ treatment: "transparent-overlay",
8103
+ behavior: "fixed-overlay"
8375
8104
  },
8376
- logo: {
8377
- showLogo: true,
8378
- showLogoText: false,
8379
- placement: "above",
8380
- size: "sm",
8381
- align: "center"
8105
+ openingRequirement: "requires-image-hero-with-contrast-overlay",
8106
+ maxRecommendedNavItems: 5,
8107
+ logoAccommodations: overlayLogoAccommodations,
8108
+ compile: transparentOverlayHeader
8109
+ },
8110
+ {
8111
+ id: asHeaderLookId("floating-glass"),
8112
+ label: "Floating glass",
8113
+ visualTreatment: "floating-glass",
8114
+ layoutBehavior: "fixed-floating",
8115
+ configuration: {
8116
+ structure: "floating-shell",
8117
+ treatment: "floating-glass",
8118
+ behavior: "fixed-floating"
8382
8119
  },
8383
- bottomBar: {
8384
- enabled: true,
8385
- fullBleed: false,
8386
- textAlign: "center",
8387
- paddingX: "default",
8388
- paddingY: "compact",
8389
- borderTop: { width: "thin" }
8390
- }
8391
- };
8120
+ openingRequirement: "requires-image-hero-with-contrast-overlay",
8121
+ maxRecommendedNavItems: 5,
8122
+ logoAccommodations: overlayLogoAccommodations,
8123
+ compile: floatingGlassHeader
8124
+ }
8125
+ ]);
8126
+ new Set(headerLookCatalog.map((look) => headerConfigurationKey(look.configuration)));
8127
+ new Map(headerLookCatalog.map((look) => [look.id, look]));
8128
+ function headerConfigurationKey(configuration) {
8129
+ return `${configuration.structure}:${configuration.treatment}:${configuration.behavior}`;
8130
+ }
8131
+ //#endregion
8132
+ //#region ../theme-core/src/site-styles/footerLooks.ts
8133
+ function asFooterLookId(value) {
8134
+ return value;
8392
8135
  }
8393
- /** Editorial split footer: compact nav on one side, brand signoff on the other. */
8394
- function splitEditorialFooter(theme) {
8136
+ function quietFooterLinks(theme) {
8395
8137
  return {
8396
8138
  ...theme.footer,
8397
- variant: "split",
8398
- maxWidth: "container",
8399
- background: {
8400
- type: "color",
8401
- color: "surface"
8402
- },
8403
8139
  navStyle: "minimal",
8404
8140
  navWeight: "regular",
8405
8141
  navColor: "text",
@@ -8412,120 +8148,38 @@ function splitEditorialFooter(theme) {
8412
8148
  hoverColorToken: "primary",
8413
8149
  padding: "none",
8414
8150
  borderRadius: "none"
8415
- },
8416
- navLayout: {
8417
- layout: "inline-wrap",
8418
- align: "start",
8419
- gapX: "relaxed",
8420
- gapY: "tight"
8421
- },
8422
- logo: {
8423
- showLogo: true,
8424
- showLogoText: true,
8425
- placement: "right",
8426
- size: "sm",
8427
- align: "end"
8428
- },
8429
- bottomBar: {
8430
- enabled: true,
8431
- fullBleed: false,
8432
- textAlign: "left",
8433
- paddingX: "default",
8434
- paddingY: "compact",
8435
- borderTop: { width: "thin" }
8436
8151
  }
8437
8152
  };
8438
8153
  }
8439
- /**
8440
- * Editorial columns: site name and supporting copy on the left, inline nav on
8441
- * the right, with a hairline-topped bottom line. Uses the footer block's
8442
- * columns layout.
8443
- */
8444
- function editorialColumnsFooter(theme) {
8154
+ function emphasizedFooterLinks(theme) {
8445
8155
  return {
8446
8156
  ...theme.footer,
8447
- variant: "columns",
8448
- maxWidth: "container",
8449
- background: {
8450
- type: "color",
8451
- color: "surface"
8452
- },
8453
8157
  navStyle: "minimal",
8454
- navWeight: "regular",
8158
+ navWeight: "medium",
8455
8159
  navColor: "text",
8456
8160
  navLinkStyle: {
8457
8161
  typography: "body",
8458
- fontWeight: "regular",
8162
+ fontWeight: "medium",
8459
8163
  textTransform: "none",
8460
8164
  italic: false,
8461
8165
  colorToken: "text",
8462
8166
  hoverColorToken: "primary",
8463
8167
  padding: "none",
8464
8168
  borderRadius: "none"
8465
- },
8466
- logo: {
8467
- showLogo: true,
8468
- showLogoText: true,
8469
- placement: "left",
8470
- size: "sm",
8471
- align: "start"
8472
- },
8473
- bottomBar: {
8474
- enabled: true,
8475
- fullBleed: false,
8476
- textAlign: "center",
8477
- paddingX: "default",
8478
- paddingY: "compact",
8479
- borderTop: { width: "thin" }
8480
8169
  }
8481
8170
  };
8482
8171
  }
8483
- const footerLookCatalog = defineExactCatalog()([
8484
- {
8485
- id: asFooterLookId("footer-identity-quiet"),
8486
- label: "Identity footer",
8487
- layoutId: asFooterLayoutId("identity"),
8488
- styleId: asFooterStyleId("quiet"),
8489
- compile: identityQuietFooter
8490
- },
8491
- {
8492
- id: asFooterLookId("footer-muted-grounding"),
8493
- label: "Muted grounding footer",
8494
- layoutId: asFooterLayoutId("identity"),
8495
- styleId: asFooterStyleId("quiet"),
8496
- hiddenFromLayoutStyleControls: true,
8497
- compile: mutedGroundingFooter
8498
- },
8499
- {
8500
- id: asFooterLookId("footer-centered-calm"),
8501
- label: "Centered calm footer",
8502
- layoutId: asFooterLayoutId("centered"),
8503
- styleId: asFooterStyleId("calm"),
8504
- compile: centeredCalmFooter
8505
- },
8506
- {
8507
- id: asFooterLookId("footer-split-editorial"),
8508
- label: "Split editorial footer",
8509
- layoutId: asFooterLayoutId("split"),
8510
- styleId: asFooterStyleId("editorial"),
8511
- compile: splitEditorialFooter
8512
- },
8513
- {
8514
- id: asFooterLookId("footer-editorial-columns"),
8515
- label: "Editorial columns footer",
8516
- layoutId: asFooterLayoutId("columns"),
8517
- styleId: asFooterStyleId("editorial"),
8518
- compile: editorialColumnsFooter
8519
- },
8520
- {
8521
- id: asFooterLookId("site-footer-brand-two-band"),
8522
- label: "Two-band brand footer",
8523
- layoutId: asFooterLayoutId("split"),
8524
- styleId: asFooterStyleId("brand-band"),
8525
- allowedContentPresence: ["default-footer", "default-and-blocks"],
8526
- compile: brandTwoBandFooter
8527
- }
8528
- ]);
8172
+ const footerLookCatalog = defineExactCatalog()([{
8173
+ id: asFooterLookId("footer-links-quiet"),
8174
+ label: "Quiet links",
8175
+ description: "Regular-weight footer navigation with a restrained hover.",
8176
+ compile: quietFooterLinks
8177
+ }, {
8178
+ id: asFooterLookId("footer-links-emphasized"),
8179
+ label: "Emphasized links",
8180
+ description: "Medium-weight footer navigation with a clearer emphasis.",
8181
+ compile: emphasizedFooterLinks
8182
+ }]);
8529
8183
  new Map(footerLookCatalog.map((look) => [look.id, look]));
8530
8184
  //#endregion
8531
8185
  //#region ../theme-core/src/site-styles/sourceCatalogs.ts
@@ -9654,17 +9308,21 @@ function defineCuratedSiteStyle(input) {
9654
9308
  })),
9655
9309
  recommendedHeaderLookIds: legacyHeaderLookIds.map(asHeaderLookId),
9656
9310
  recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(asFooterLookId),
9657
- buttonPersonalityChoices: input.buttonPersonalityChoices,
9311
+ buttonStyleChoices: input.buttonStyleChoices,
9658
9312
  paletteRecommendations: input.paletteRecommendations,
9659
9313
  typography: input.typography ?? defaultTypographyForRecipe(input.tokenRecipes.typography),
9660
9314
  ...input.heroTypography ? { heroTypography: input.heroTypography } : {}
9661
9315
  };
9662
9316
  }
9663
- function buttonChoice(id, note) {
9317
+ function buttonChoice(styleId, note, parameters) {
9318
+ const selection = parameters === void 0 ? defaultButtonStyleSelectionFor(styleId) : buttonStyleSelectionSchema.parse({
9319
+ styleId,
9320
+ parameters
9321
+ });
9664
9322
  return note ? {
9665
- id: asButtonPersonalityId(id),
9323
+ ...selection,
9666
9324
  note
9667
- } : { id: asButtonPersonalityId(id) };
9325
+ } : selection;
9668
9326
  }
9669
9327
  function paletteRecommendation(authoringKey, note) {
9670
9328
  const valueKey = requireCuratedPaletteValueKey(asCuratedPaletteAuthoringKey(authoringKey));
@@ -9849,9 +9507,8 @@ const curatedSiteStyles = [
9849
9507
  "minimal-transparent",
9850
9508
  "clean-base"
9851
9509
  ],
9852
- buttonPersonalityChoices: [
9510
+ buttonStyleChoices: [
9853
9511
  buttonChoice("soft-pill"),
9854
- buttonChoice("two-tone-pill"),
9855
9512
  buttonChoice("pebble"),
9856
9513
  buttonChoice("editorial-link"),
9857
9514
  buttonChoice("brushed-wash")
@@ -9887,7 +9544,7 @@ const curatedSiteStyles = [
9887
9544
  "brand-solid",
9888
9545
  "clean-base"
9889
9546
  ],
9890
- buttonPersonalityChoices: [
9547
+ buttonStyleChoices: [
9891
9548
  buttonChoice("confident-chip"),
9892
9549
  buttonChoice("soft-pill"),
9893
9550
  buttonChoice("editorial-link")
@@ -9926,7 +9583,7 @@ const curatedSiteStyles = [
9926
9583
  "minimal-transparent",
9927
9584
  "centered-calm"
9928
9585
  ],
9929
- buttonPersonalityChoices: [
9586
+ buttonStyleChoices: [
9930
9587
  buttonChoice("editorial-link"),
9931
9588
  buttonChoice("soft-pill"),
9932
9589
  buttonChoice("brushed-wash")
@@ -9966,7 +9623,7 @@ const curatedSiteStyles = [
9966
9623
  "practical-utility",
9967
9624
  "clean-base"
9968
9625
  ],
9969
- buttonPersonalityChoices: [
9626
+ buttonStyleChoices: [
9970
9627
  buttonChoice("pebble"),
9971
9628
  buttonChoice("brushed-wash"),
9972
9629
  buttonChoice("confident-chip")
@@ -10027,7 +9684,7 @@ const curatedSiteStyles = [
10027
9684
  "serif-line",
10028
9685
  "clean-base"
10029
9686
  ],
10030
- buttonPersonalityChoices: [
9687
+ buttonStyleChoices: [
10031
9688
  buttonChoice("editorial-link"),
10032
9689
  buttonChoice("confident-chip"),
10033
9690
  buttonChoice("soft-pill")
@@ -10089,7 +9746,7 @@ const curatedSiteStyles = [
10089
9746
  "brand-solid",
10090
9747
  "clean-base"
10091
9748
  ],
10092
- buttonPersonalityChoices: [
9749
+ buttonStyleChoices: [
10093
9750
  buttonChoice("confident-chip"),
10094
9751
  buttonChoice("pebble"),
10095
9752
  buttonChoice("ink-stamp")
@@ -10128,7 +9785,7 @@ const curatedSiteStyles = [
10128
9785
  "minimal-transparent",
10129
9786
  "clean-base"
10130
9787
  ],
10131
- buttonPersonalityChoices: [
9788
+ buttonStyleChoices: [
10132
9789
  buttonChoice("soft-pill"),
10133
9790
  buttonChoice("pebble"),
10134
9791
  buttonChoice("confident-chip")
@@ -10201,7 +9858,7 @@ const curatedSiteStyles = [
10201
9858
  "clean-base",
10202
9859
  "centered-calm"
10203
9860
  ],
10204
- buttonPersonalityChoices: [
9861
+ buttonStyleChoices: [
10205
9862
  buttonChoice("pebble"),
10206
9863
  buttonChoice("soft-pill"),
10207
9864
  buttonChoice("editorial-link")
@@ -10320,12 +9977,8 @@ const curatedSiteStyles = [
10320
9977
  "serif-line",
10321
9978
  "minimal-transparent"
10322
9979
  ],
10323
- recommendedFooterLookIds: [
10324
- "footer-centered-calm",
10325
- "footer-editorial-columns",
10326
- "footer-muted-grounding"
10327
- ],
10328
- buttonPersonalityChoices: [
9980
+ recommendedFooterLookIds: ["footer-links-quiet"],
9981
+ buttonStyleChoices: [
10329
9982
  buttonChoice("soft-pill"),
10330
9983
  buttonChoice("pebble"),
10331
9984
  buttonChoice("editorial-link")
@@ -10399,7 +10052,7 @@ const curatedSiteStyles = [
10399
10052
  "centered-calm",
10400
10053
  "minimal-transparent"
10401
10054
  ],
10402
- buttonPersonalityChoices: [
10055
+ buttonStyleChoices: [
10403
10056
  buttonChoice("editorial-link"),
10404
10057
  buttonChoice("soft-pill"),
10405
10058
  buttonChoice("brushed-wash")
@@ -10472,8 +10125,8 @@ const curatedSiteStyles = [
10472
10125
  "practical-utility",
10473
10126
  "clean-base"
10474
10127
  ],
10475
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
10476
- buttonPersonalityChoices: [
10128
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
10129
+ buttonStyleChoices: [
10477
10130
  buttonChoice("pebble"),
10478
10131
  buttonChoice("confident-chip"),
10479
10132
  buttonChoice("ink-stamp"),
@@ -10594,8 +10247,8 @@ const curatedSiteStyles = [
10594
10247
  "minimal-transparent",
10595
10248
  "serif-line"
10596
10249
  ],
10597
- recommendedFooterLookIds: ["footer-muted-grounding", "site-footer-brand-two-band"],
10598
- buttonPersonalityChoices: [
10250
+ recommendedFooterLookIds: ["footer-links-quiet", "footer-links-emphasized"],
10251
+ buttonStyleChoices: [
10599
10252
  buttonChoice("earth-pill"),
10600
10253
  buttonChoice("soft-pill"),
10601
10254
  buttonChoice("pebble"),
@@ -10666,7 +10319,7 @@ const curatedSiteStyles = [
10666
10319
  "floating-glass",
10667
10320
  "brand-solid"
10668
10321
  ],
10669
- buttonPersonalityChoices: [
10322
+ buttonStyleChoices: [
10670
10323
  buttonChoice("ink-stamp"),
10671
10324
  buttonChoice("confident-chip"),
10672
10325
  buttonChoice("brushed-wash"),
@@ -10721,8 +10374,8 @@ const curatedSiteStyles = [
10721
10374
  "transparent-overlay",
10722
10375
  "practical-utility"
10723
10376
  ],
10724
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
10725
- buttonPersonalityChoices: [
10377
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
10378
+ buttonStyleChoices: [
10726
10379
  buttonChoice("showtime-pill"),
10727
10380
  buttonChoice("confident-chip"),
10728
10381
  buttonChoice("ink-stamp"),
@@ -10803,8 +10456,8 @@ const curatedSiteStyles = [
10803
10456
  headerStyleChoice("glass")
10804
10457
  ] },
10805
10458
  recommendedHeaderLookIds: ["minimal-transparent"],
10806
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
10807
- buttonPersonalityChoices: [
10459
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
10460
+ buttonStyleChoices: [
10808
10461
  buttonChoice("ornate-ritual"),
10809
10462
  buttonChoice("joy-stamp"),
10810
10463
  buttonChoice("ink-stamp")
@@ -10857,8 +10510,8 @@ const curatedSiteStyles = [
10857
10510
  headerStyleChoice("glass")
10858
10511
  ] },
10859
10512
  recommendedHeaderLookIds: ["minimal-transparent"],
10860
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
10861
- buttonPersonalityChoices: [
10513
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
10514
+ buttonStyleChoices: [
10862
10515
  buttonChoice("joy-stamp"),
10863
10516
  buttonChoice("ink-stamp"),
10864
10517
  buttonChoice("showtime-pill")
@@ -10948,8 +10601,8 @@ const curatedSiteStyles = [
10948
10601
  "centered-calm",
10949
10602
  "clean-base"
10950
10603
  ],
10951
- recommendedFooterLookIds: ["footer-editorial-columns", "footer-muted-grounding"],
10952
- buttonPersonalityChoices: [
10604
+ recommendedFooterLookIds: ["footer-links-quiet"],
10605
+ buttonStyleChoices: [
10953
10606
  buttonChoice("flat-ink"),
10954
10607
  buttonChoice("confident-chip"),
10955
10608
  buttonChoice("editorial-link")
@@ -11026,14 +10679,9 @@ const curatedSiteStyles = [
11026
10679
  "serif-line",
11027
10680
  "clean-base"
11028
10681
  ],
11029
- recommendedFooterLookIds: [
11030
- "footer-editorial-columns",
11031
- "footer-muted-grounding",
11032
- "footer-identity-quiet"
11033
- ],
11034
- buttonPersonalityChoices: [
11035
- buttonChoice("quiet-arrow"),
11036
- buttonChoice("two-tone-pill"),
10682
+ recommendedFooterLookIds: ["footer-links-quiet"],
10683
+ buttonStyleChoices: [
10684
+ buttonChoice("quiet-arrow", void 0, { secondaryTreatment: "solid-accent" }),
11037
10685
  buttonChoice("flat-ink"),
11038
10686
  buttonChoice("editorial-link")
11039
10687
  ],
@@ -24997,6 +24645,123 @@ function ThemeScopeCore({ cssVars, buttonCss, headerCss, footerCss, cardCss, acc
24997
24645
  });
24998
24646
  }
24999
24647
  //#endregion
24648
+ //#region ../theme-core/src/buttons/core.ts
24649
+ const CORNER_RADIUS_MAP$1 = {
24650
+ square: "0",
24651
+ soft: "0.375rem",
24652
+ rounded: "0.5rem",
24653
+ pill: "9999px"
24654
+ };
24655
+ const BORDER_WIDTH_MAP$1 = {
24656
+ none: "0",
24657
+ thin: "1px",
24658
+ medium: "2px",
24659
+ thick: "4px"
24660
+ };
24661
+ const SHADOW_VALUES$1 = {
24662
+ none: "none",
24663
+ low: "0 1px 2px rgba(0,0,0,0.06)",
24664
+ medium: "0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)",
24665
+ high: "0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)"
24666
+ };
24667
+ const RESOLVER_GLOBAL = {
24668
+ cornerStyle: "rounded",
24669
+ textTransform: "none",
24670
+ fontWeight: 500,
24671
+ hoverTransform: "none",
24672
+ hoverColor: "none"
24673
+ };
24674
+ function generateButtonCoreCss(scopeId, variants, settings, palette) {
24675
+ const seenIds = /* @__PURE__ */ new Set();
24676
+ for (const variant of variants) {
24677
+ if (!buttonVariantIdSchema.safeParse(variant.id).success) throw new Error(`[ThemeBridge] Invalid button variant ID: ${variant.id}`);
24678
+ if (seenIds.has(variant.id)) throw new Error(`[ThemeBridge] Duplicate button variant ID: ${variant.id}`);
24679
+ seenIds.add(variant.id);
24680
+ }
24681
+ return variants.map((variant) => generateVariantCss(scopeId, variant, settings, palette)).join("\n\n");
24682
+ }
24683
+ function generateVariantCss(scopeId, variant, settings, palette) {
24684
+ const borderWidth = BORDER_WIDTH_MAP$1[variant.borderWidth ?? "none"];
24685
+ const result = compileButtonColourStates({
24686
+ variant: {
24687
+ id: variant.id,
24688
+ name: variant.id,
24689
+ enabled: true,
24690
+ priority: 1,
24691
+ background: variant.treatment,
24692
+ ...borderWidth === "0" ? {} : { border: { widthClass: borderWidth } }
24693
+ },
24694
+ global: RESOLVER_GLOBAL,
24695
+ palette
24696
+ });
24697
+ if (!result.ok) throw new Error(`[ThemeBridge] ${formatButtonColourContractError(result.error)}`);
24698
+ const selector = `:where([data-theme-scope="${scopeId}"]) .button-${variant.id}`;
24699
+ return [
24700
+ rule(selector, [
24701
+ ...borderWidth === "0" ? ["padding: 0.5rem 1rem;"] : [
24702
+ `padding-top: calc(0.5rem - ${borderWidth});`,
24703
+ `padding-bottom: calc(0.5rem - ${borderWidth});`,
24704
+ `padding-left: calc(1rem - ${borderWidth});`,
24705
+ `padding-right: calc(1rem - ${borderWidth});`
24706
+ ],
24707
+ `font-weight: ${settings.fontWeight ?? 500};`,
24708
+ ...settings.textTransform && settings.textTransform !== "none" ? [`text-transform: ${settings.textTransform};`] : [],
24709
+ "cursor: pointer;",
24710
+ "transition: all 200ms ease-in-out;",
24711
+ "display: inline-flex;",
24712
+ "align-items: center;",
24713
+ "justify-content: center;",
24714
+ `border-radius: ${CORNER_RADIUS_MAP$1[settings.corners]};`,
24715
+ `box-shadow: ${SHADOW_VALUES$1[settings.shadow]};`,
24716
+ ...declarationStrings(resolvedButtonColourDeclarations(result.states.base)),
24717
+ borderWidth === "0" ? "border: none;" : `border: ${borderWidth} solid currentColor;`
24718
+ ]),
24719
+ rule(`${selector}:hover`, declarationStrings(resolvedButtonColourDeclarations(result.states.hover))),
24720
+ rule(`${selector}:active`, [...declarationStrings(resolvedButtonColourDeclarations(result.states.active)), "transform: scale(0.98);"]),
24721
+ rule(`${selector}:focus-visible`, declarationStrings(resolvedButtonFocusDeclarations(result.focusIndicator))),
24722
+ rule(`${selector}:disabled,\n${selector}:disabled:hover,\n${selector}:disabled:active`, [...declarationStrings(resolvedButtonColourDeclarations(result.states.disabled)), ...declarationStrings(RESOLVED_BUTTON_DISABLED_DECLARATIONS)])
24723
+ ].join("\n\n");
24724
+ }
24725
+ function declarationStrings(declarations) {
24726
+ return declarations.map(([property, value]) => `${property}: ${value};`);
24727
+ }
24728
+ function rule(selector, declarations) {
24729
+ return `${selector} {\n ${declarations.join("\n ")}\n}`;
24730
+ }
24731
+ function getDefaultButtonVariants() {
24732
+ return [
24733
+ {
24734
+ id: "primary",
24735
+ treatment: {
24736
+ type: "solid",
24737
+ colorToken: unsafeAsOpaqueButtonColourToken("primary")
24738
+ }
24739
+ },
24740
+ {
24741
+ id: "secondary",
24742
+ treatment: {
24743
+ type: "solid",
24744
+ colorToken: unsafeAsOpaqueButtonColourToken("secondary")
24745
+ }
24746
+ },
24747
+ {
24748
+ id: "outline",
24749
+ treatment: {
24750
+ type: "surface",
24751
+ role: "link"
24752
+ },
24753
+ borderWidth: "thin"
24754
+ },
24755
+ {
24756
+ id: "ghost",
24757
+ treatment: {
24758
+ type: "surface",
24759
+ role: "link"
24760
+ }
24761
+ }
24762
+ ];
24763
+ }
24764
+ //#endregion
25000
24765
  //#region ../theme-core/src/inputs/core.ts
25001
24766
  const CORNER_RADIUS_MAP = {
25002
24767
  square: "0",
@@ -25603,7 +25368,6 @@ function generateButtonsCss(config, corners, shadows) {
25603
25368
  const settings = {
25604
25369
  corners,
25605
25370
  shadow: shadows,
25606
- borderWidth: "thin",
25607
25371
  fontWeight: 500,
25608
25372
  textTransform: "none"
25609
25373
  };