@riverbankcms/sdk 0.111.0 → 0.119.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 (196) hide show
  1. package/dist/{PreviewEditorSidebar-CTR6LUhN.mjs → PreviewEditorSidebar-C7TXFitV.mjs} +4 -4
  2. package/dist/{PreviewEditorUI-DZg15Zip.mjs → PreviewEditorUI-_1JIHTXS.mjs} +3 -3
  3. package/dist/{PreviewQueryProvider-kkmjklLG.mjs → PreviewQueryProvider-nKUT4TL-.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-DeOTAFvR.mjs → SdkPreviewModeRuntime-CvJTVgWa.mjs} +2579 -34325
  5. package/dist/{SiteChromeCustomizeContext-DOSDLCiJ.mjs → SiteChromeCustomizeContext-66QfCbAS.mjs} +64625 -32791
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +5211 -639
  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/bookingConfig.d.ts +26 -1
  10. package/dist/_dts/api/src/bookingRecords.d.ts +6 -74
  11. package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +3 -3
  12. package/dist/_dts/api/src/contentRuntime.d.ts +5 -1
  13. package/dist/_dts/api/src/customerMembershipOutcomes.d.ts +4 -4
  14. package/dist/_dts/api/src/endpoints.d.ts +35 -0
  15. package/dist/_dts/api/src/event-presentation.d.ts +4 -0
  16. package/dist/_dts/api/src/index.d.ts +4 -4
  17. package/dist/_dts/api/src/navigation/dashboardBookingsNav.d.ts +4 -1
  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 +85 -7
  21. package/dist/_dts/api/src/siteBanner.d.ts +8 -8
  22. package/dist/_dts/api/src/siteOperations.d.ts +1 -1
  23. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +32 -4
  24. package/dist/_dts/block-form/src/widgets/RichTextField/richTextFieldDefaults.d.ts +3 -12
  25. package/dist/_dts/block-form/src/widgets/RichTextField/richTextFieldSchema.d.ts +1 -5
  26. package/dist/_dts/blocks/src/bindings/index.d.ts +1 -10
  27. package/dist/_dts/blocks/src/index.d.ts +3 -6
  28. package/dist/_dts/blocks/src/primitives/content/primitives.d.ts +2 -2
  29. package/dist/_dts/blocks/src/system/blocks/body-text.d.ts +2 -2
  30. package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule.d.ts +2 -2
  31. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +2 -8
  32. package/dist/_dts/blocks/src/system/blocks/feature-card-icons.d.ts +2 -2
  33. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +3 -3
  34. package/dist/_dts/blocks/src/system/blocks/form.d.ts +2 -15
  35. package/dist/_dts/blocks/src/system/blocks/intro.d.ts +2 -2
  36. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +66 -66
  37. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +2 -16
  38. package/dist/_dts/blocks/src/system/blocks/site-footer.d.ts +0 -3
  39. package/dist/_dts/blocks/src/system/fragments/index.d.ts +0 -1
  40. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +19 -2
  41. package/dist/_dts/blocks/src/system/manifest/richTextSchema.d.ts +8 -70
  42. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +1 -0
  43. package/dist/_dts/blocks/src/system/manifest/validation.d.ts +6 -0
  44. package/dist/_dts/blocks/src/system/node/schema.d.ts +4 -4
  45. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +1 -10
  46. package/dist/_dts/blocks/src/system/runtime/nodes/buttonAffordance.d.ts +5 -21
  47. package/dist/_dts/blocks/src/system/runtime/nodes/richText-coerce.d.ts +14 -2
  48. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +1 -1
  49. package/dist/_dts/content-editor/src/controller/seedDraftBaselinesFromBlocks.d.ts +1 -1
  50. package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +17 -1
  51. package/dist/_dts/content-editor/src/hooks/useDebouncedLatestSave.d.ts +1 -1
  52. package/dist/_dts/content-editor/src/hooks/useSimpleAutosave.d.ts +1 -1
  53. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +3 -2
  54. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +2 -2
  55. package/dist/_dts/content-editor/src/ui/stores/autosaveStore.d.ts +1 -1
  56. package/dist/_dts/content-editor/src/ui/stores/types.d.ts +1 -1
  57. package/dist/_dts/content-model/src/content-types/builtins.d.ts +3 -15
  58. package/dist/_dts/content-model/src/content-types/entryValidation.d.ts +2 -0
  59. package/dist/_dts/content-model/src/content-types/schema.d.ts +1 -1
  60. package/dist/_dts/content-model/src/templates/defaults.d.ts +1 -21
  61. package/dist/_dts/core/src/editor-state.d.ts +14 -1
  62. package/dist/_dts/core/src/footer-composition.d.ts +2 -1
  63. package/dist/_dts/core/src/index.d.ts +1 -0
  64. package/dist/_dts/core/src/rich-text.d.ts +16 -0
  65. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +189 -86
  66. package/dist/_dts/editor/src/index.d.ts +1 -1
  67. package/dist/_dts/editor/src/primitives/rich-text/utils.d.ts +3 -5
  68. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +1 -1
  69. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +2 -1
  70. package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +2 -1
  71. package/dist/_dts/editor-blocks/src/block-editor/blockDraftBaselineSeed.d.ts +15 -0
  72. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockBaselineSync.d.ts +3 -7
  73. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +12 -0
  74. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +1 -0
  75. package/dist/_dts/editor-blocks/src/block-editor/utils.d.ts +1 -1
  76. package/dist/_dts/editor-blocks/src/index.d.ts +6 -5
  77. package/dist/_dts/editor-blocks/src/widgets/rich-text/RichTextField.d.ts +2 -2
  78. package/dist/_dts/media-core/src/contentMediaAudit.d.ts +104 -0
  79. package/dist/_dts/media-core/src/contentMediaAuditFieldAdapter.d.ts +8 -0
  80. package/dist/_dts/media-core/src/contentMediaSnapshotAudit.d.ts +22 -0
  81. package/dist/_dts/media-core/src/index.d.ts +3 -1
  82. package/dist/_dts/sdk/src/cli/commands/event.d.ts +18 -1
  83. package/dist/_dts/sdk/src/cli/commands/push/execute/theme.d.ts +2 -16
  84. package/dist/_dts/sdk/src/cli/content/reader.d.ts +8 -5
  85. package/dist/_dts/sdk/src/client/management/events.d.ts +2 -1
  86. package/dist/_dts/sdk/src/client/management/index.d.ts +1 -1
  87. package/dist/_dts/sdk/src/client/management/types.d.ts +36 -9
  88. package/dist/_dts/sdk/src/config/typed-entries.d.ts +7 -7
  89. package/dist/_dts/sdk/src/config/validation.d.ts +7 -7
  90. package/dist/_dts/sdk/src/contracts/content.d.ts +5 -15
  91. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  92. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +12 -25
  93. package/dist/_dts/sdk/src/contracts/theme.d.ts +2 -18
  94. package/dist/_dts/sdk/src/manifest/passes/pass1-fields.d.ts +1 -1
  95. package/dist/_dts/sdk/src/manifest/three-pass-converter.d.ts +4 -4
  96. package/dist/_dts/sdk/src/rendering/helpers/bindings.d.ts +1 -2
  97. package/dist/_dts/sdk/src/rendering/helpers/index.d.ts +1 -1
  98. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +2 -13
  99. package/dist/_dts/sdk/src/theme/index.d.ts +0 -29
  100. package/dist/_dts/sdk/src/version.d.ts +1 -1
  101. package/dist/_dts/site-commands/src/commands.d.ts +31 -18
  102. package/dist/_dts/theme-core/src/buttons/affordanceIcons.d.ts +2 -2
  103. package/dist/_dts/theme-core/src/buttons/core.d.ts +0 -1
  104. package/dist/_dts/theme-core/src/buttons/effectClassification.d.ts +22 -9
  105. package/dist/_dts/theme-core/src/buttons/effects/presets/background.d.ts +1 -2
  106. package/dist/_dts/theme-core/src/buttons/effects/presets/border.d.ts +1 -2
  107. package/dist/_dts/theme-core/src/buttons/effects/presets/overlay.d.ts +3 -1
  108. package/dist/_dts/theme-core/src/buttons/effects/presets/shadow.d.ts +2 -2
  109. package/dist/_dts/theme-core/src/buttons/effects/types.d.ts +8 -18
  110. package/dist/_dts/theme-core/src/buttons/generateButtonCss.d.ts +2 -2
  111. package/dist/_dts/theme-core/src/buttons/generateDefaultButtonSystem.d.ts +5 -5
  112. package/dist/_dts/theme-core/src/buttons/index.d.ts +1 -4
  113. package/dist/_dts/theme-core/src/buttons/parseThemeForPersistence.d.ts +36 -0
  114. package/dist/_dts/theme-core/src/buttons/types.d.ts +1638 -93
  115. package/dist/_dts/theme-core/src/cards/types.d.ts +13 -13
  116. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +969 -69
  117. package/dist/_dts/theme-core/src/navigation/types.d.ts +2 -2
  118. package/dist/_dts/theme-core/src/recommend/generateThemes.d.ts +0 -1
  119. package/dist/_dts/theme-core/src/schema.d.ts +1100 -116
  120. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  121. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +14 -14
  122. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +2 -2
  123. package/dist/_dts/theme-core/src/site-styles/pageDesignIntent.d.ts +4 -4
  124. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +6 -0
  125. package/dist/cli/index.mjs +5706 -4852
  126. package/dist/cli/init-docs/content/cli-reference.md +40 -1
  127. package/dist/cli/init-docs/content/content-management.md +6 -0
  128. package/dist/client/{DiscountCodeDisclosure-C4xvTBux.mjs → DiscountCodeDisclosure-DIWj-P9v.mjs} +1 -1
  129. package/dist/client/{EventCombined.client-Cr7G131j.mjs → EventCombined.client-De8YWBSr.mjs} +2 -2
  130. package/dist/client/{EventListing.client-CAjbseNy.mjs → EventListing.client-seHTjimY.mjs} +2 -2
  131. package/dist/client/{LeafletStaticMap-BMlWfwz3.mjs → LeafletStaticMap-BmQxFcJW.mjs} +1 -1
  132. package/dist/client/{MagicLinkForm-ChdFz96y.mjs → MagicLinkForm-OoJAIUIj.mjs} +1 -1
  133. package/dist/client/{StepIndicator-7D3GaBeM.mjs → StepIndicator-CiZ8kdPk.mjs} +2 -2
  134. package/dist/client/{accordion-D8JTs2Si.mjs → accordion-6lnN__XJ.mjs} +1 -1
  135. package/dist/client/{bookingForm-H3DCRBHs.mjs → bookingForm-5uyqhONU.mjs} +6 -6
  136. package/dist/client/bookings.mjs +2219 -527
  137. package/dist/client/{carousel-DMr_QWlz.mjs → carousel-Dtnifil_.mjs} +1 -1
  138. package/dist/client/{cart-DWMbfBdR.mjs → cart-5Tc5S7NV.mjs} +3 -3
  139. package/dist/client/{checkout-zmfdkXLx.mjs → checkout-CYKKN5Hr.mjs} +3 -3
  140. package/dist/client/client.mjs +2498 -2384
  141. package/dist/client/{colorTokenParts-FSS3al6l.mjs → colorStyles-BWpj_h4C.mjs} +88 -1
  142. package/dist/client/{courseRegistration-Z_mn18jy.mjs → courseRegistration-CxCBybB4.mjs} +6 -6
  143. package/dist/client/{eventCalendar-CYp0YJGF.mjs → eventCalendar-Xj2jZS9X.mjs} +4 -4
  144. package/dist/client/{eventCombined-rKyYZUa9.mjs → eventCombined-CgcMoOgM.mjs} +2 -2
  145. package/dist/client/{eventDetails-X0ZaUuMj.mjs → eventDetails-CEAH8Edc.mjs} +3 -3
  146. package/dist/client/{eventListing-W1SuL7EP.mjs → eventListing-qyPVQ0wP.mjs} +2 -2
  147. package/dist/client/{eventRegistration-ClWricui.mjs → eventRegistration-DDu79CtL.mjs} +6 -6
  148. package/dist/client/{form--eKPwAAD.mjs → form-Bc7JKI7I.mjs} +1 -1
  149. package/dist/client/{headerSection-BSeGr-FS.mjs → headerSection-vTku_LEl.mjs} +2 -2
  150. package/dist/client/hooks.mjs +373 -555
  151. package/dist/client/{locationMap-BpOrtNYn.mjs → locationMap-Bg7X4Jna.mjs} +3 -3
  152. package/dist/client/{media-DoF0dcVx.mjs → media-CNE1Z-wb.mjs} +1 -2
  153. package/dist/client/{newsletterForm-Bt7it7Dy.mjs → newsletterForm-lpylVdp5.mjs} +1 -1
  154. package/dist/client/{pricing-BTjSDDr4.mjs → pricing-DE8fjJiT.mjs} +1 -1
  155. package/dist/client/{productDetail-ICnVTcCg.mjs → productDetail-D7Bo2RMH.mjs} +3 -3
  156. package/dist/client/{productList-ZHr6D604.mjs → productList-VjnZqiqN.mjs} +3 -3
  157. package/dist/client/{propsDecoder-wWN0tBDF.mjs → propsDecoder-DreFXjNP.mjs} +2212 -621
  158. package/dist/client/rendering/client.mjs +21612 -21646
  159. package/dist/client/rendering/islands.mjs +20 -20
  160. package/dist/client/rendering.mjs +1571 -1547
  161. package/dist/client/{shop-C1u_BUn0.mjs → shop-IRsHHbf7.mjs} +5 -5
  162. package/dist/client/{shop-commerce-CleZdRha.mjs → shop-commerce-gnI8PieZ.mjs} +27 -10
  163. package/dist/client/{shop-commerce-store-ycnoB2Ce.mjs → shop-commerce-store-BTbrhObn.mjs} +1 -1
  164. package/dist/client/{shopShared-CPhByt2a.mjs → shopShared-D6KS2_qk.mjs} +3 -3
  165. package/dist/client/{useDiscountCodeUi-cStSQI6C.mjs → useDiscountCodeUi-DCccGCxV.mjs} +1 -1
  166. package/dist/client/{useEventFilters-DKPN7hSY.mjs → useEventFilters-eGs3rPZQ.mjs} +3 -104
  167. package/dist/client/{usePolling-BKAd6pkZ.mjs → usePolling-CvSU2sur.mjs} +2 -2
  168. package/dist/preview-next/before-render.mjs +57 -0
  169. package/dist/preview-next/client/runtime.mjs +4 -4
  170. package/dist/preview-next/middleware.mjs +57 -0
  171. package/dist/{previewAuthStore-BkT1D06A.mjs → previewAuthStore-DN7vcRsv.mjs} +57 -0
  172. package/dist/{sdk-runtime-hu3wr3ng.mjs → sdk-runtime-DaOiA7ct.mjs} +2 -2
  173. package/dist/{separator-Bln8izQ9.mjs → separator-CqRhcCxD.mjs} +1 -1
  174. package/dist/server/components.mjs +4092 -4108
  175. package/dist/server/config-template-validation.mjs +4 -23
  176. package/dist/server/config-validation.mjs +373 -555
  177. package/dist/server/config.mjs +410 -558
  178. package/dist/server/data.mjs +373 -555
  179. package/dist/server/index.mjs +58 -1
  180. package/dist/server/next.mjs +32958 -32926
  181. package/dist/server/page-converter.mjs +369 -526
  182. package/dist/server/prebuild.mjs +1 -1
  183. package/dist/server/rendering/server.mjs +5371 -3174
  184. package/dist/server/rendering.mjs +4099 -4124
  185. package/dist/server/routing.mjs +758 -966
  186. package/dist/server/server.mjs +448 -632
  187. package/dist/server/theme-bridge.mjs +472 -525
  188. package/dist/server/theme.mjs +1074 -392
  189. package/package.json +1 -1
  190. package/dist/_dts/blocks/src/primitives/content/components/Button.d.ts +0 -40
  191. package/dist/_dts/blocks/src/system/fragments/library/footerBottomText.d.ts +0 -19
  192. package/dist/_dts/media-core/src/legacyMediaValue.d.ts +0 -11
  193. package/dist/_dts/theme-core/src/styles/buttons.d.ts +0 -27
  194. package/dist/_dts/theme-core/src/styles/buttonsLibrary.d.ts +0 -2
  195. package/dist/_dts/theme-core/src/styles/glow.d.ts +0 -3
  196. package/dist/client/colorStyles-gcTh5yZT.mjs +0 -89
@@ -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",
@@ -479,11 +471,11 @@ const gradientDirectionSchema$1 = z$1.enum([
479
471
  "to-bl"
480
472
  ]);
481
473
  const buttonColourTreatmentSchema = z$1.discriminatedUnion("type", [
482
- z$1.object({
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,19 +489,15 @@ const buttonColourTreatmentSchema = 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
497
  const buttonBackgroundSchema = buttonColourTreatmentSchema;
506
- const effectApplicationSchema$1 = z$1.object({
507
- effectId: z$1.string(),
508
- options: z$1.record(z$1.string(), z$1.json()).optional()
509
- });
510
- const buttonBorderSchema = z$1.object({ widthClass: z$1.string() });
511
- const buttonVariantAffordanceSchema = z$1.object({ iconId: z$1.string().min(1) });
512
- const variantShadowSchema = z$1.object({
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({
513
501
  elevation: z$1.enum([
514
502
  "none",
515
503
  "low",
@@ -522,13 +510,13 @@ const variantShadowSchema = z$1.object({
522
510
  "hard"
523
511
  ]).nullable(),
524
512
  position: z$1.enum(["bottom", "bottom-right"]).default("bottom"),
525
- colorToken: themeColorTokenSchema.optional()
513
+ colorToken: opaqueButtonColourTokenSchema.optional()
526
514
  });
527
- const variantEffectsSchema = z$1.object({
528
- base: z$1.array(effectApplicationSchema$1).optional(),
529
- hover: z$1.array(effectApplicationSchema$1).optional(),
530
- active: z$1.array(effectApplicationSchema$1).optional(),
531
- 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()
532
520
  });
533
521
  /**
534
522
  * Per-variant size overrides schema — every entry is optional.
@@ -549,8 +537,8 @@ const variantSizeOverridesSchema = z$1.object({
549
537
  * default (e.g. link-style variants declaring zero horizontal padding at
550
538
  * every size).
551
539
  */
552
- const canonicalButtonVariantSchema = z$1.object({
553
- id: z$1.string(),
540
+ const buttonVariantSchema = z$1.strictObject({
541
+ id: buttonVariantIdSchema,
554
542
  name: z$1.string().min(1).max(20),
555
543
  enabled: z$1.boolean(),
556
544
  priority: prioritySchema,
@@ -564,176 +552,25 @@ const canonicalButtonVariantSchema = z$1.object({
564
552
  sizes: variantSizeOverridesSchema.optional(),
565
553
  affordance: buttonVariantAffordanceSchema.optional()
566
554
  });
567
- /**
568
- * Temporary persisted-theme admission boundary for issue #1206.
569
- *
570
- * Production inventory on 2026-07-22 found 22 rows using the old independent
571
- * `textColorToken`/border colour shape. New source and all downstream code use
572
- * only the canonical relationship. Delete this preprocessor after the reviewed
573
- * production rewrite reports zero legacy rows.
574
- */
575
- const buttonVariantSchema = z$1.preprocess(normalizeLegacyButtonVariantInput, canonicalButtonVariantSchema);
576
- const buttonSystemSchema = z$1.object({
555
+ const buttonSystemSchema = z$1.strictObject({
577
556
  global: buttonGlobalSettingsSchema,
578
557
  variants: z$1.array(buttonVariantSchema).min(1).max(6),
579
558
  sizes: buttonSizesSchema.optional()
580
- });
581
- function normalizeLegacyButtonVariantInput(input) {
582
- if (!isUnknownRecord(input)) return input;
583
- const background = input.background;
584
- if (!isUnknownRecord(background)) return input;
585
- 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;
586
- const { textColorToken, ...withoutLegacyText } = input;
587
- const normalizedBorder = isUnknownRecord(input.border) && typeof input.border.widthClass === "string" ? { widthClass: input.border.widthClass } : input.border;
588
- const normalizedAffordance = isUnknownRecord(input.affordance) && typeof input.affordance.iconId === "string" ? { iconId: input.affordance.iconId } : input.affordance;
589
- const normalizedEffects = normalizeLegacyButtonEffects(input.effects, background.type);
590
- const hoverBackgroundToken = stripLegacyTokenAlpha(input.hoverBackgroundToken);
591
- if (background.type === "transparent") return {
592
- ...withoutLegacyText,
593
- background: {
594
- type: "surface",
595
- role: "link"
596
- },
597
- border: normalizedBorder,
598
- affordance: normalizedAffordance,
599
- effects: normalizedEffects,
600
- hoverBackgroundToken
601
- };
602
- if (background.type === "gradient") {
603
- const stops = Array.isArray(background.stops) ? background.stops.map(stripLegacyTokenAlpha) : background.stops;
604
- return {
605
- ...withoutLegacyText,
606
- background: {
607
- ...background,
608
- stops,
609
- foregroundToken: stripLegacyTokenAlpha(background.foregroundToken ?? textColorToken)
610
- },
611
- border: normalizedBorder,
612
- affordance: normalizedAffordance,
613
- effects: normalizedEffects,
614
- hoverBackgroundToken
615
- };
616
- }
617
- return {
618
- ...withoutLegacyText,
619
- background: background.type === "solid" ? {
620
- ...background,
621
- colorToken: stripLegacyTokenAlpha(background.colorToken)
622
- } : background,
623
- border: normalizedBorder,
624
- affordance: normalizedAffordance,
625
- effects: normalizedEffects,
626
- hoverBackgroundToken
627
- };
628
- }
629
- function normalizeLegacyButtonGlobalInput(input) {
630
- if (!isUnknownRecord(input)) return input;
631
- const hoverColorToken = stripLegacyTokenAlpha(input.hoverColorToken);
632
- return hoverColorToken === input.hoverColorToken ? input : {
633
- ...input,
634
- hoverColorToken
635
- };
636
- }
637
- function hasLegacyAlphaToken(input, background) {
638
- const stops = isUnknownArray(background.stops) ? background.stops : [];
639
- return [
640
- input.hoverBackgroundToken,
641
- background.colorToken,
642
- background.foregroundToken,
643
- ...stops
644
- ].some((token) => stripLegacyTokenAlpha(token) !== token);
645
- }
646
- function stripLegacyTokenAlpha(value) {
647
- if (typeof value !== "string") return value;
648
- const slashIndex = value.indexOf("/");
649
- return slashIndex < 0 ? value : value.slice(0, slashIndex);
650
- }
651
- function hasLegacyButtonEffects(input) {
652
- if (!isUnknownRecord(input)) return false;
653
- return [
654
- "base",
655
- "hover",
656
- "active",
657
- "focus"
658
- ].some((state) => {
659
- const effects = input[state];
660
- return Array.isArray(effects) && effects.some((effect) => {
661
- if (!isUnknownRecord(effect) || typeof effect.effectId !== "string") return true;
662
- const classification = classifyButtonEffectId(effect.effectId);
663
- if (classification !== "colour-transition" && classification !== "non-colour") return true;
664
- 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}`
665
570
  });
571
+ seen.add(variant.id);
666
572
  });
667
- }
668
- function normalizeLegacyButtonEffects(input, backgroundType) {
669
- if (!isUnknownRecord(input)) return input;
670
- const normalized = {};
671
- for (const state of [
672
- "base",
673
- "hover",
674
- "active",
675
- "focus"
676
- ]) {
677
- const effects = input[state];
678
- if (!Array.isArray(effects)) continue;
679
- const safeEffects = effects.flatMap((effect) => {
680
- if (!isUnknownRecord(effect) || typeof effect.effectId !== "string") return [];
681
- const classification = classifyButtonEffectId(effect.effectId);
682
- if (classification === "non-colour") return [effect];
683
- if (classification !== "colour-transition") return [];
684
- if (effect.effectId === "background-on-hover") {
685
- const options = isUnknownRecord(effect.options) ? effect.options : null;
686
- const colorToken = options === null ? null : parseOpaqueButtonColourToken(stripLegacyTokenAlpha(options.colorToken));
687
- return colorToken === null ? [] : [{
688
- ...effect,
689
- options: {
690
- ...options,
691
- colorToken
692
- }
693
- }];
694
- }
695
- if (backgroundType !== "solid") return [];
696
- const rawAmount = isUnknownRecord(effect.options) ? effect.options.amount : void 0;
697
- const amount = typeof rawAmount === "number" && rawAmount > 0 ? Math.max(100, Math.round(rawAmount / 100) * 100) : 100;
698
- return [{
699
- ...effect,
700
- options: {
701
- ...isUnknownRecord(effect.options) ? effect.options : {},
702
- amount
703
- }
704
- }];
705
- });
706
- if (safeEffects.length > 0) normalized[state] = safeEffects;
707
- }
708
- return Object.keys(normalized).length === 0 ? void 0 : normalized;
709
- }
710
- function isUnknownRecord(value) {
711
- return typeof value === "object" && value !== null && !Array.isArray(value);
712
- }
713
- function isUnknownArray(value) {
714
- return Array.isArray(value);
715
- }
716
- //#endregion
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"
736
- };
573
+ });
737
574
  //#endregion
738
575
  //#region ../theme-core/src/palette/utils/colorConversion.ts
739
576
  function hexToRgb(hex) {
@@ -860,21 +697,163 @@ function requireSurfaceColorValue(role, value) {
860
697
  function completeSurfaceForegrounds(input) {
861
698
  const text = requireSurfaceColorValue("text", input.text);
862
699
  return {
863
- text,
864
- heading: input.heading === void 0 ? text : requireSurfaceColorValue("heading", input.heading),
865
- link: input.link === void 0 ? text : requireSurfaceColorValue("link", input.link),
866
- supporting: input.supporting === void 0 ? text : requireSurfaceColorValue("supporting", input.supporting)
700
+ text,
701
+ heading: input.heading === void 0 ? text : requireSurfaceColorValue("heading", input.heading),
702
+ link: input.link === void 0 ? text : requireSurfaceColorValue("link", input.link),
703
+ supporting: input.supporting === void 0 ? text : requireSurfaceColorValue("supporting", input.supporting)
704
+ };
705
+ }
706
+ function surfaceForegroundValue(role, outsideProviderFallback = DEFAULT_ROLE_FALLBACKS[role]) {
707
+ const roleVariable = SURFACE_FOREGROUND_CSS_VARS[role];
708
+ const fallback = requireSurfaceColorValue("fallback", outsideProviderFallback);
709
+ if (role === "text") return `var(${roleVariable}, ${fallback})`;
710
+ return `var(${roleVariable}, var(${SURFACE_FOREGROUND_CSS_VARS.text}, ${fallback}))`;
711
+ }
712
+ function surfaceForegroundDeclarations(input) {
713
+ const foregrounds = completeSurfaceForegrounds(input);
714
+ return [`color: ${foregrounds.text}`, ...SURFACE_FOREGROUND_ROLES.map((role) => `${SURFACE_FOREGROUND_CSS_VARS[role]}: ${foregrounds[role]}`)];
715
+ }
716
+ //#endregion
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"
736
+ };
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")
867
853
  };
868
854
  }
869
- function surfaceForegroundValue(role, outsideProviderFallback = DEFAULT_ROLE_FALLBACKS[role]) {
870
- const roleVariable = SURFACE_FOREGROUND_CSS_VARS[role];
871
- const fallback = requireSurfaceColorValue("fallback", outsideProviderFallback);
872
- if (role === "text") return `var(${roleVariable}, ${fallback})`;
873
- return `var(${roleVariable}, var(${SURFACE_FOREGROUND_CSS_VARS.text}, ${fallback}))`;
874
- }
875
- function surfaceForegroundDeclarations(input) {
876
- const foregrounds = completeSurfaceForegrounds(input);
877
- return [`color: ${foregrounds.text}`, ...SURFACE_FOREGROUND_ROLES.map((role) => `${SURFACE_FOREGROUND_CSS_VARS[role]}: ${foregrounds[role]}`)];
855
+ function getButtonEffectPolicy(effectId) {
856
+ return Object.prototype.hasOwnProperty.call(BUTTON_EFFECT_POLICIES, effectId) ? BUTTON_EFFECT_POLICIES[effectId] : null;
878
857
  }
879
858
  //#endregion
880
859
  //#region ../theme-core/src/buttons/resolveButtonColourStates.ts
@@ -967,15 +946,17 @@ function applyColourEffects(input) {
967
946
  for (const effect of input.effects ?? []) {
968
947
  const policy = getButtonEffectPolicy(effect.effectId);
969
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);
970
952
  switch (policy.classification) {
971
953
  case "non-colour":
954
+ case "decorative-colour":
972
955
  nonColourEffects.push(effect);
973
956
  break;
974
- case "unsupported-colour":
975
- case "unsupported-background-overlay":
976
- case "not-button": return unsupportedEffect(input, effect, policy.reason);
977
957
  case "colour-transition":
978
958
  if (policy.transition.kind === "adjust-shade") {
959
+ if (effect.effectId !== "darken-background" && effect.effectId !== "lighten-background") return unknownEffect(input, effect);
979
960
  if (treatment.type !== "solid") return inapplicableEffect(input, effect, treatment);
980
961
  const amount = readShadeAmount(effect);
981
962
  if (amount === null) return invalidEffectOption(input, effect, "amount");
@@ -987,7 +968,8 @@ function applyColourEffects(input) {
987
968
  break;
988
969
  }
989
970
  if (policy.transition.kind === "replace-background") {
990
- const colorToken = readOpaqueToken(effect, "colorToken", "neutral-800");
971
+ if (effect.effectId !== "background-on-hover") return unknownEffect(input, effect);
972
+ const colorToken = readOpaqueToken(effect);
991
973
  if (colorToken === null) return invalidEffectOption(input, effect, "colorToken");
992
974
  treatment = {
993
975
  type: "solid",
@@ -1179,8 +1161,8 @@ function readShadeAmount(effect) {
1179
1161
  const value = effect.options?.amount ?? 100;
1180
1162
  return typeof value === "number" && Number.isFinite(value) && value >= 0 && value % 100 === 0 ? value : null;
1181
1163
  }
1182
- function readOpaqueToken(effect, key, fallback) {
1183
- return parseOpaqueButtonColourToken(effect.options?.[key] ?? fallback);
1164
+ function readOpaqueToken(effect) {
1165
+ return parseOpaqueButtonColourToken(effect.options?.colorToken ?? "neutral-800");
1184
1166
  }
1185
1167
  function unsupportedEffect(input, effect, reason) {
1186
1168
  return {
@@ -1436,7 +1418,6 @@ const quietArrowRecipe = defineButtonStyleRecipe({
1436
1418
  cornerStyle: "rounded",
1437
1419
  textTransform: "uppercase",
1438
1420
  fontWeight: 500,
1439
- borderWidth: 1,
1440
1421
  typography: "body",
1441
1422
  fontSize: "text-sm",
1442
1423
  letterSpacing: "loose",
@@ -1500,7 +1481,7 @@ const quietArrowRecipe = defineButtonStyleRecipe({
1500
1481
  affordance: { iconId: "ArrowRight" },
1501
1482
  effects: { hover: [{
1502
1483
  effectId: "background-on-hover",
1503
- options: { colorToken: "surfaceAlt" }
1484
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
1504
1485
  }] }
1505
1486
  }
1506
1487
  },
@@ -1611,7 +1592,6 @@ const softPillRecipe = defineStaticButtonStyleRecipe({
1611
1592
  shadow: "low",
1612
1593
  textTransform: "none",
1613
1594
  fontWeight: 500,
1614
- borderWidth: 2,
1615
1595
  hoverTransform: "lift",
1616
1596
  hoverColor: "none"
1617
1597
  },
@@ -1630,10 +1610,7 @@ const softPillRecipe = defineStaticButtonStyleRecipe({
1630
1610
  position: "bottom"
1631
1611
  },
1632
1612
  effects: {
1633
- hover: [{
1634
- effectId: "lift",
1635
- options: { translateY: "-1px" }
1636
- }],
1613
+ hover: [{ effectId: "lift" }],
1637
1614
  active: [{
1638
1615
  effectId: "scale-down",
1639
1616
  options: { scale: "0.98" }
@@ -1652,7 +1629,7 @@ const softPillRecipe = defineStaticButtonStyleRecipe({
1652
1629
  border: { widthClass: "border-2" },
1653
1630
  effects: { hover: [{
1654
1631
  effectId: "background-on-hover",
1655
- options: { colorToken: "surface" }
1632
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1656
1633
  }] }
1657
1634
  }
1658
1635
  },
@@ -1667,7 +1644,7 @@ const softPillRecipe = defineStaticButtonStyleRecipe({
1667
1644
  border: { widthClass: "border" },
1668
1645
  effects: { hover: [{
1669
1646
  effectId: "background-on-hover",
1670
- options: { colorToken: "surface" }
1647
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1671
1648
  }] }
1672
1649
  }
1673
1650
  },
@@ -1681,7 +1658,7 @@ const softPillRecipe = defineStaticButtonStyleRecipe({
1681
1658
  borderRadius: "rounded-full",
1682
1659
  effects: { hover: [{
1683
1660
  effectId: "background-on-hover",
1684
- options: { colorToken: "surface" }
1661
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1685
1662
  }] }
1686
1663
  }
1687
1664
  },
@@ -1711,7 +1688,6 @@ const earthPillRecipe = defineStaticButtonStyleRecipe({
1711
1688
  shadow: "low",
1712
1689
  textTransform: "none",
1713
1690
  fontWeight: 500,
1714
- borderWidth: 1,
1715
1691
  hoverTransform: "lift",
1716
1692
  hoverColor: "none",
1717
1693
  typography: "body",
@@ -1747,12 +1723,9 @@ const earthPillRecipe = defineStaticButtonStyleRecipe({
1747
1723
  position: "bottom"
1748
1724
  },
1749
1725
  effects: {
1750
- hover: [{
1751
- effectId: "lift",
1752
- options: { translateY: "-1px" }
1753
- }, {
1726
+ hover: [{ effectId: "lift" }, {
1754
1727
  effectId: "background-on-hover",
1755
- options: { colorToken: "accent" }
1728
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
1756
1729
  }],
1757
1730
  active: [{
1758
1731
  effectId: "scale-down",
@@ -1772,7 +1745,7 @@ const earthPillRecipe = defineStaticButtonStyleRecipe({
1772
1745
  border: { widthClass: "border" },
1773
1746
  effects: { hover: [{
1774
1747
  effectId: "background-on-hover",
1775
- options: { colorToken: "muted" }
1748
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
1776
1749
  }] }
1777
1750
  }
1778
1751
  },
@@ -1787,7 +1760,7 @@ const earthPillRecipe = defineStaticButtonStyleRecipe({
1787
1760
  border: { widthClass: "border" },
1788
1761
  effects: { hover: [{
1789
1762
  effectId: "background-on-hover",
1790
- options: { colorToken: "surfaceAlt" }
1763
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
1791
1764
  }] }
1792
1765
  }
1793
1766
  },
@@ -1847,7 +1820,6 @@ const confidentChipRecipe = defineStaticButtonStyleRecipe({
1847
1820
  shadow: "medium",
1848
1821
  textTransform: "none",
1849
1822
  fontWeight: 600,
1850
- borderWidth: 1,
1851
1823
  hoverTransform: "none",
1852
1824
  hoverColor: "none"
1853
1825
  },
@@ -1888,7 +1860,7 @@ const confidentChipRecipe = defineStaticButtonStyleRecipe({
1888
1860
  border: { widthClass: "border" },
1889
1861
  effects: { hover: [{
1890
1862
  effectId: "background-on-hover",
1891
- options: { colorToken: "background" }
1863
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
1892
1864
  }] }
1893
1865
  }
1894
1866
  },
@@ -1903,7 +1875,7 @@ const confidentChipRecipe = defineStaticButtonStyleRecipe({
1903
1875
  border: { widthClass: "border" },
1904
1876
  effects: { hover: [{
1905
1877
  effectId: "background-on-hover",
1906
- options: { colorToken: "surface" }
1878
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1907
1879
  }] }
1908
1880
  }
1909
1881
  },
@@ -1917,7 +1889,7 @@ const confidentChipRecipe = defineStaticButtonStyleRecipe({
1917
1889
  borderRadius: "rounded-md",
1918
1890
  effects: { hover: [{
1919
1891
  effectId: "background-on-hover",
1920
- options: { colorToken: "surface" }
1892
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
1921
1893
  }] }
1922
1894
  }
1923
1895
  },
@@ -1952,7 +1924,6 @@ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
1952
1924
  cornerStyle: "square",
1953
1925
  textTransform: "none",
1954
1926
  fontWeight: 500,
1955
- borderWidth: 1,
1956
1927
  hoverTransform: "none",
1957
1928
  hoverColor: "none"
1958
1929
  },
@@ -1970,7 +1941,6 @@ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
1970
1941
  effectId: "border-bottom-grow",
1971
1942
  options: {
1972
1943
  height: 2,
1973
- colorToken: "text",
1974
1944
  origin: "left"
1975
1945
  }
1976
1946
  }] }
@@ -1989,7 +1959,6 @@ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
1989
1959
  effectId: "border-bottom-grow",
1990
1960
  options: {
1991
1961
  height: 1,
1992
- colorToken: "mutedText",
1993
1962
  origin: "left"
1994
1963
  }
1995
1964
  }] }
@@ -2008,7 +1977,6 @@ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
2008
1977
  effectId: "border-bottom-grow",
2009
1978
  options: {
2010
1979
  height: 1,
2011
- colorToken: "accent",
2012
1980
  origin: "left"
2013
1981
  }
2014
1982
  }] }
@@ -2032,7 +2000,6 @@ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
2032
2000
  effectId: "border-bottom-grow",
2033
2001
  options: {
2034
2002
  height: 2,
2035
- colorToken: "accent",
2036
2003
  origin: "left"
2037
2004
  }
2038
2005
  }] } }
@@ -2054,7 +2021,6 @@ const pebbleRecipe = defineStaticButtonStyleRecipe({
2054
2021
  cornerStyle: "pill",
2055
2022
  textTransform: "none",
2056
2023
  fontWeight: 500,
2057
- borderWidth: 2,
2058
2024
  hoverTransform: "none",
2059
2025
  hoverColor: "none"
2060
2026
  },
@@ -2099,7 +2065,7 @@ const pebbleRecipe = defineStaticButtonStyleRecipe({
2099
2065
  border: { widthClass: "border-2" },
2100
2066
  effects: { hover: [{
2101
2067
  effectId: "background-on-hover",
2102
- options: { colorToken: "accent" }
2068
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("accent") }
2103
2069
  }] }
2104
2070
  }
2105
2071
  },
@@ -2114,7 +2080,7 @@ const pebbleRecipe = defineStaticButtonStyleRecipe({
2114
2080
  border: { widthClass: "border" },
2115
2081
  effects: { hover: [{
2116
2082
  effectId: "background-on-hover",
2117
- options: { colorToken: "surface" }
2083
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2118
2084
  }] }
2119
2085
  }
2120
2086
  },
@@ -2169,7 +2135,6 @@ const brushedWashRecipe = defineStaticButtonStyleRecipe({
2169
2135
  shadow: "low",
2170
2136
  textTransform: "none",
2171
2137
  fontWeight: 500,
2172
- borderWidth: 1,
2173
2138
  hoverTransform: "none",
2174
2139
  hoverColor: "none"
2175
2140
  },
@@ -2234,7 +2199,7 @@ const brushedWashRecipe = defineStaticButtonStyleRecipe({
2234
2199
  border: { widthClass: "border" },
2235
2200
  effects: { hover: [{
2236
2201
  effectId: "background-on-hover",
2237
- options: { colorToken: "surface" }
2202
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2238
2203
  }] }
2239
2204
  }
2240
2205
  },
@@ -2248,7 +2213,7 @@ const brushedWashRecipe = defineStaticButtonStyleRecipe({
2248
2213
  borderRadius: "rounded-lg",
2249
2214
  effects: { hover: [{
2250
2215
  effectId: "background-on-hover",
2251
- options: { colorToken: "surface" }
2216
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2252
2217
  }] }
2253
2218
  }
2254
2219
  },
@@ -2277,7 +2242,6 @@ const inkStampRecipe = defineStaticButtonStyleRecipe({
2277
2242
  cornerStyle: "rounded",
2278
2243
  textTransform: "uppercase",
2279
2244
  fontWeight: 600,
2280
- borderWidth: 1,
2281
2245
  hoverTransform: "none",
2282
2246
  hoverColor: "none",
2283
2247
  letterSpacing: "loose"
@@ -2335,7 +2299,7 @@ const inkStampRecipe = defineStaticButtonStyleRecipe({
2335
2299
  border: { widthClass: "border-2" },
2336
2300
  effects: { hover: [{
2337
2301
  effectId: "background-on-hover",
2338
- options: { colorToken: "surface" }
2302
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2339
2303
  }] }
2340
2304
  }
2341
2305
  },
@@ -2350,7 +2314,7 @@ const inkStampRecipe = defineStaticButtonStyleRecipe({
2350
2314
  border: { widthClass: "border-2" },
2351
2315
  effects: { hover: [{
2352
2316
  effectId: "background-on-hover",
2353
- options: { colorToken: "surface" }
2317
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2354
2318
  }] }
2355
2319
  }
2356
2320
  },
@@ -2384,7 +2348,6 @@ const inkStampRecipe = defineStaticButtonStyleRecipe({
2384
2348
  effectId: "border-bottom-grow",
2385
2349
  options: {
2386
2350
  height: 1,
2387
- colorToken: "accent",
2388
2351
  origin: "left"
2389
2352
  }
2390
2353
  }] }
@@ -2415,7 +2378,6 @@ const flatInkRecipe = defineStaticButtonStyleRecipe({
2415
2378
  cornerStyle: "rounded",
2416
2379
  textTransform: "none",
2417
2380
  fontWeight: 600,
2418
- borderWidth: 1,
2419
2381
  typography: "body",
2420
2382
  letterSpacing: "tight",
2421
2383
  paddingPreset: "default",
@@ -2447,12 +2409,9 @@ const flatInkRecipe = defineStaticButtonStyleRecipe({
2447
2409
  },
2448
2410
  borderRadius: "rounded-lg",
2449
2411
  affordance: { iconId: "ArrowRight" },
2450
- effects: { hover: [{
2451
- effectId: "lift",
2452
- options: { translateY: "-2px" }
2453
- }, {
2412
+ effects: { hover: [{ effectId: "lift" }, {
2454
2413
  effectId: "background-on-hover",
2455
- options: { colorToken: "secondary" }
2414
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("secondary") }
2456
2415
  }] }
2457
2416
  }
2458
2417
  },
@@ -2465,12 +2424,9 @@ const flatInkRecipe = defineStaticButtonStyleRecipe({
2465
2424
  },
2466
2425
  borderRadius: "rounded-lg",
2467
2426
  border: { widthClass: "border" },
2468
- effects: { hover: [{
2469
- effectId: "lift",
2470
- options: { translateY: "-2px" }
2471
- }, {
2427
+ effects: { hover: [{ effectId: "lift" }, {
2472
2428
  effectId: "background-on-hover",
2473
- options: { colorToken: "surfaceAlt" }
2429
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
2474
2430
  }] }
2475
2431
  }
2476
2432
  },
@@ -2483,12 +2439,9 @@ const flatInkRecipe = defineStaticButtonStyleRecipe({
2483
2439
  },
2484
2440
  borderRadius: "rounded-lg",
2485
2441
  border: { widthClass: "border" },
2486
- effects: { hover: [{
2487
- effectId: "lift",
2488
- options: { translateY: "-2px" }
2489
- }, {
2442
+ effects: { hover: [{ effectId: "lift" }, {
2490
2443
  effectId: "background-on-hover",
2491
- options: { colorToken: "surfaceAlt" }
2444
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
2492
2445
  }] }
2493
2446
  }
2494
2447
  },
@@ -2500,10 +2453,7 @@ const flatInkRecipe = defineStaticButtonStyleRecipe({
2500
2453
  role: "link"
2501
2454
  },
2502
2455
  borderRadius: "rounded-lg",
2503
- effects: { hover: [{
2504
- effectId: "lift",
2505
- options: { translateY: "-2px" }
2506
- }] }
2456
+ effects: { hover: [{ effectId: "lift" }] }
2507
2457
  }
2508
2458
  },
2509
2459
  accent: {
@@ -2515,10 +2465,7 @@ const flatInkRecipe = defineStaticButtonStyleRecipe({
2515
2465
  },
2516
2466
  borderRadius: "rounded-lg",
2517
2467
  affordance: { iconId: "ArrowRight" },
2518
- effects: { hover: [{
2519
- effectId: "lift",
2520
- options: { translateY: "-2px" }
2521
- }] }
2468
+ effects: { hover: [{ effectId: "lift" }] }
2522
2469
  }
2523
2470
  }
2524
2471
  }
@@ -2539,9 +2486,8 @@ const showtimePillRecipe = defineStaticButtonStyleRecipe({
2539
2486
  shadow: "low",
2540
2487
  textTransform: "uppercase",
2541
2488
  fontWeight: 700,
2542
- borderWidth: 2,
2543
2489
  hoverTransform: "lift",
2544
- hoverColor: "darken",
2490
+ hoverColor: "none",
2545
2491
  typography: "body",
2546
2492
  paddingPreset: "spacious",
2547
2493
  italic: false
@@ -2599,7 +2545,7 @@ const showtimePillRecipe = defineStaticButtonStyleRecipe({
2599
2545
  border: { widthClass: "border-2" },
2600
2546
  effects: { hover: [{
2601
2547
  effectId: "background-on-hover",
2602
- options: { colorToken: "background" }
2548
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("background") }
2603
2549
  }] }
2604
2550
  }
2605
2551
  },
@@ -2613,7 +2559,7 @@ const showtimePillRecipe = defineStaticButtonStyleRecipe({
2613
2559
  borderRadius: "rounded-full",
2614
2560
  effects: { hover: [{
2615
2561
  effectId: "background-on-hover",
2616
- options: { colorToken: "surface" }
2562
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2617
2563
  }] }
2618
2564
  }
2619
2565
  },
@@ -2648,7 +2594,6 @@ const joyStampRecipe = defineStaticButtonStyleRecipe({
2648
2594
  typography: "heading",
2649
2595
  fontWeight: 700,
2650
2596
  fontSize: "text-lg",
2651
- borderWidth: 2,
2652
2597
  hoverTransform: "none",
2653
2598
  hoverColor: "none"
2654
2599
  },
@@ -2683,7 +2628,7 @@ const joyStampRecipe = defineStaticButtonStyleRecipe({
2683
2628
  elevation: "high",
2684
2629
  softness: "hard",
2685
2630
  position: "bottom-right",
2686
- colorToken: "text"
2631
+ colorToken: unsafeAsOpaqueButtonColourToken("text")
2687
2632
  },
2688
2633
  effects: { hover: [{ effectId: "press-down" }] }
2689
2634
  }
@@ -2701,7 +2646,7 @@ const joyStampRecipe = defineStaticButtonStyleRecipe({
2701
2646
  elevation: "high",
2702
2647
  softness: "hard",
2703
2648
  position: "bottom-right",
2704
- colorToken: "secondary"
2649
+ colorToken: unsafeAsOpaqueButtonColourToken("secondary")
2705
2650
  },
2706
2651
  effects: { hover: [{ effectId: "press-down" }] }
2707
2652
  }
@@ -2746,7 +2691,6 @@ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
2746
2691
  cornerStyle: "rounded",
2747
2692
  textTransform: "uppercase",
2748
2693
  fontWeight: 600,
2749
- borderWidth: 1,
2750
2694
  hoverTransform: "none",
2751
2695
  hoverColor: "none",
2752
2696
  letterSpacing: "loose"
@@ -2782,7 +2726,7 @@ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
2782
2726
  effects: {
2783
2727
  hover: [{
2784
2728
  effectId: "background-on-hover",
2785
- options: { colorToken: "primary-100" }
2729
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("primary-100") }
2786
2730
  }],
2787
2731
  active: [{
2788
2732
  effectId: "scale-down",
@@ -2802,7 +2746,7 @@ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
2802
2746
  border: { widthClass: "border" },
2803
2747
  effects: { hover: [{
2804
2748
  effectId: "background-on-hover",
2805
- options: { colorToken: "surface" }
2749
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surface") }
2806
2750
  }] }
2807
2751
  }
2808
2752
  },
@@ -2817,7 +2761,7 @@ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
2817
2761
  border: { widthClass: "border" },
2818
2762
  effects: { hover: [{
2819
2763
  effectId: "background-on-hover",
2820
- options: { colorToken: "muted" }
2764
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("muted") }
2821
2765
  }] }
2822
2766
  }
2823
2767
  },
@@ -2851,7 +2795,6 @@ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
2851
2795
  effectId: "border-bottom-grow",
2852
2796
  options: {
2853
2797
  height: 1,
2854
- colorToken: "accent",
2855
2798
  origin: "left"
2856
2799
  }
2857
2800
  }] }
@@ -2939,118 +2882,6 @@ function presetCategory(recipe) {
2939
2882
  }
2940
2883
  }
2941
2884
  //#endregion
2942
- //#region ../theme-core/src/buttons/core.ts
2943
- const CORNER_RADIUS_MAP$2 = {
2944
- square: "0",
2945
- soft: "0.375rem",
2946
- rounded: "0.5rem",
2947
- pill: "9999px"
2948
- };
2949
- const BORDER_WIDTH_MAP$2 = {
2950
- none: "0",
2951
- thin: "1px",
2952
- medium: "2px",
2953
- thick: "4px"
2954
- };
2955
- const SHADOW_VALUES$2 = {
2956
- none: "none",
2957
- low: "0 1px 2px rgba(0,0,0,0.06)",
2958
- medium: "0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)",
2959
- high: "0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)"
2960
- };
2961
- const RESOLVER_GLOBAL = {
2962
- cornerStyle: "rounded",
2963
- textTransform: "none",
2964
- fontWeight: 500,
2965
- borderWidth: 1,
2966
- hoverTransform: "none",
2967
- hoverColor: "none"
2968
- };
2969
- function generateButtonCoreCss(scopeId, variants, settings, palette) {
2970
- return variants.map((variant) => generateVariantCss$1(scopeId, variant, settings, palette)).join("\n\n");
2971
- }
2972
- function generateVariantCss$1(scopeId, variant, settings, palette) {
2973
- const borderWidth = BORDER_WIDTH_MAP$2[variant.borderWidth ?? "none"];
2974
- const result = compileButtonColourStates({
2975
- variant: {
2976
- id: variant.id,
2977
- name: variant.id,
2978
- enabled: true,
2979
- priority: 1,
2980
- background: variant.treatment,
2981
- ...borderWidth === "0" ? {} : { border: { widthClass: borderWidth } }
2982
- },
2983
- global: RESOLVER_GLOBAL,
2984
- palette
2985
- });
2986
- if (!result.ok) throw new Error(`[ThemeBridge] ${formatButtonColourContractError(result.error)}`);
2987
- const selector = `:where([data-theme-scope="${scopeId}"]) .button-${variant.id}`;
2988
- return [
2989
- rule(selector, [
2990
- ...borderWidth === "0" ? ["padding: 0.5rem 1rem;"] : [
2991
- `padding-top: calc(0.5rem - ${borderWidth});`,
2992
- `padding-bottom: calc(0.5rem - ${borderWidth});`,
2993
- `padding-left: calc(1rem - ${borderWidth});`,
2994
- `padding-right: calc(1rem - ${borderWidth});`
2995
- ],
2996
- `font-weight: ${settings.fontWeight ?? 500};`,
2997
- ...settings.textTransform && settings.textTransform !== "none" ? [`text-transform: ${settings.textTransform};`] : [],
2998
- "cursor: pointer;",
2999
- "transition: all 200ms ease-in-out;",
3000
- "display: inline-flex;",
3001
- "align-items: center;",
3002
- "justify-content: center;",
3003
- `border-radius: ${CORNER_RADIUS_MAP$2[settings.corners]};`,
3004
- `box-shadow: ${SHADOW_VALUES$2[settings.shadow]};`,
3005
- ...declarationStrings(resolvedButtonColourDeclarations(result.states.base)),
3006
- borderWidth === "0" ? "border: none;" : `border: ${borderWidth} solid currentColor;`
3007
- ]),
3008
- rule(`${selector}:hover`, declarationStrings(resolvedButtonColourDeclarations(result.states.hover))),
3009
- rule(`${selector}:active`, [...declarationStrings(resolvedButtonColourDeclarations(result.states.active)), "transform: scale(0.98);"]),
3010
- rule(`${selector}:focus-visible`, declarationStrings(resolvedButtonFocusDeclarations(result.focusIndicator))),
3011
- rule(`${selector}:disabled,\n${selector}:disabled:hover,\n${selector}:disabled:active`, [...declarationStrings(resolvedButtonColourDeclarations(result.states.disabled)), ...declarationStrings(RESOLVED_BUTTON_DISABLED_DECLARATIONS)])
3012
- ].join("\n\n");
3013
- }
3014
- function declarationStrings(declarations) {
3015
- return declarations.map(([property, value]) => `${property}: ${value};`);
3016
- }
3017
- function rule(selector, declarations) {
3018
- return `${selector} {\n ${declarations.join("\n ")}\n}`;
3019
- }
3020
- function getDefaultButtonVariants() {
3021
- return [
3022
- {
3023
- id: "primary",
3024
- treatment: {
3025
- type: "solid",
3026
- colorToken: unsafeAsOpaqueButtonColourToken("primary")
3027
- }
3028
- },
3029
- {
3030
- id: "secondary",
3031
- treatment: {
3032
- type: "solid",
3033
- colorToken: unsafeAsOpaqueButtonColourToken("secondary")
3034
- }
3035
- },
3036
- {
3037
- id: "outline",
3038
- treatment: {
3039
- type: "surface",
3040
- role: "link"
3041
- },
3042
- borderWidth: "thin"
3043
- },
3044
- {
3045
- id: "ghost",
3046
- treatment: {
3047
- type: "surface",
3048
- role: "link"
3049
- }
3050
- }
3051
- ];
3052
- }
3053
- //#endregion
3054
2885
  //#region ../theme-core/src/cards/types.ts
3055
2886
  const cardVariantRoleValues = ["default", "alternative"];
3056
2887
  const boxlessCardVariantValue = "none";
@@ -3169,13 +3000,13 @@ const cardSystemSchema = z$1.object({ variants: z$1.array(cardVariantSchema).min
3169
3000
  * Pure functions for generating card CSS without requiring the full Theme type.
3170
3001
  * Used by both the full CMS theme system and the SDK theme bridge.
3171
3002
  */
3172
- const CORNER_RADIUS_MAP$1 = {
3003
+ const CORNER_RADIUS_MAP$2 = {
3173
3004
  square: "0",
3174
3005
  soft: "0.5rem",
3175
3006
  rounded: "1rem",
3176
3007
  pill: "1.5rem"
3177
3008
  };
3178
- const BORDER_WIDTH_MAP$1 = {
3009
+ const BORDER_WIDTH_MAP$2 = {
3179
3010
  none: "0",
3180
3011
  thin: "1px",
3181
3012
  medium: "2px",
@@ -3205,7 +3036,7 @@ const ACCENT_EDGE_SIDE_MAP = {
3205
3036
  * unspecified corner from the global corners setting.
3206
3037
  */
3207
3038
  function resolveCornerRadiiCss(cornerRadii, fallback) {
3208
- const fallbackValue = CORNER_RADIUS_MAP$1[fallback];
3039
+ const fallbackValue = CORNER_RADIUS_MAP$2[fallback];
3209
3040
  const at = (value) => value ? PER_CORNER_RADIUS_MAP[value] : fallbackValue;
3210
3041
  return `${at(cornerRadii.topLeft)} ${at(cornerRadii.topRight)} ${at(cornerRadii.bottomRight)} ${at(cornerRadii.bottomLeft)}`;
3211
3042
  }
@@ -3219,7 +3050,7 @@ const GRADIENT_DIRECTION_MAP = {
3219
3050
  "to-br": "to bottom right",
3220
3051
  "to-bl": "to bottom left"
3221
3052
  };
3222
- const SHADOW_VALUES$1 = {
3053
+ const SHADOW_VALUES$2 = {
3223
3054
  none: "none",
3224
3055
  low: "0 1px 2px rgba(0,0,0,0.06)",
3225
3056
  medium: "0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1)",
@@ -3247,7 +3078,7 @@ const SPACING_MAP = {
3247
3078
  function generateCardCoreCss(scopeId, variants, settings) {
3248
3079
  const cssChunks = [];
3249
3080
  for (const variant of variants) {
3250
- const css = generateVariantCss(scopeId, variant, settings);
3081
+ const css = generateVariantCss$1(scopeId, variant, settings);
3251
3082
  cssChunks.push(css);
3252
3083
  }
3253
3084
  return cssChunks.join("\n\n");
@@ -3257,7 +3088,7 @@ function generateCardCoreCss(scopeId, variants, settings) {
3257
3088
  *
3258
3089
  * Selectors use :where() for zero specificity, allowing site styles to override easily.
3259
3090
  */
3260
- function generateVariantCss(scopeId, variant, settings) {
3091
+ function generateVariantCss$1(scopeId, variant, settings) {
3261
3092
  const containerSelector = `:where([data-theme-scope="${scopeId}"]) .card-${variant.id}`;
3262
3093
  const mediaSelector = `${containerSelector} .card-media`;
3263
3094
  const contentSelector = `${containerSelector} .card-content`;
@@ -3283,16 +3114,16 @@ function generateVariantCss(scopeId, variant, settings) {
3283
3114
  containerRules.push("border: 0");
3284
3115
  containerRules.push(`${side}: ${width} solid rgb(var(--tb-${variant.accentEdge.colorToken}))`);
3285
3116
  } else {
3286
- 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";
3287
3118
  if (variant.borderToken && borderWidth !== "0") containerRules.push(`border: ${borderWidth} solid rgb(var(--tb-${variant.borderToken}))`);
3288
3119
  }
3289
- containerRules.push(`border-radius: ${variant.cornerRadii ? resolveCornerRadiiCss(variant.cornerRadii, settings.corners) : CORNER_RADIUS_MAP$1[settings.corners]}`);
3290
- 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]}`);
3291
3122
  containerRules.push("display: flex");
3292
3123
  containerRules.push("flex-direction: column");
3293
3124
  containerRules.push("position: relative");
3294
3125
  containerRules.push("overflow: visible");
3295
- const mediaRadius = CORNER_RADIUS_MAP$1[settings.corners];
3126
+ const mediaRadius = CORNER_RADIUS_MAP$2[settings.corners];
3296
3127
  const mediaRules = [`border-top-left-radius: ${mediaRadius}`, `border-top-right-radius: ${mediaRadius}`];
3297
3128
  const contentRules = [`padding: ${SPACING_MAP[variant.spacing]}`];
3298
3129
  return [
@@ -24814,6 +24645,123 @@ function ThemeScopeCore({ cssVars, buttonCss, headerCss, footerCss, cardCss, acc
24814
24645
  });
24815
24646
  }
24816
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
24817
24765
  //#region ../theme-core/src/inputs/core.ts
24818
24766
  const CORNER_RADIUS_MAP = {
24819
24767
  square: "0",
@@ -25420,7 +25368,6 @@ function generateButtonsCss(config, corners, shadows) {
25420
25368
  const settings = {
25421
25369
  corners,
25422
25370
  shadow: shadows,
25423
- borderWidth: "thin",
25424
25371
  fontWeight: 500,
25425
25372
  textTransform: "none"
25426
25373
  };