@riverbankcms/sdk 0.109.0 → 0.111.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 (186) hide show
  1. package/dist/{PreviewEditorSidebar-DWqwfy3_.mjs → PreviewEditorSidebar-CTR6LUhN.mjs} +178 -117
  2. package/dist/{PreviewEditorUI-B7OL4sfR.mjs → PreviewEditorUI-DZg15Zip.mjs} +3 -4
  3. package/dist/{PreviewQueryProvider-D0y2l8JN.mjs → PreviewQueryProvider-kkmjklLG.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-D8Gt9Gbe.mjs → SdkPreviewModeRuntime-DeOTAFvR.mjs} +229 -219
  5. package/dist/{SiteChromeCustomizeContext-DUpalEdL.mjs → SiteChromeCustomizeContext-DOSDLCiJ.mjs} +1695 -2169
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +1716 -76
  7. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +5 -5
  8. package/dist/_dts/api/src/contentRuntime.d.ts +4 -1
  9. package/dist/_dts/api/src/courses.d.ts +30 -15
  10. package/dist/_dts/api/src/endpoints.d.ts +14 -4
  11. package/dist/_dts/api/src/index.d.ts +2 -2
  12. package/dist/_dts/api/src/sdkContracts.d.ts +23 -11
  13. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -1
  14. package/dist/_dts/api/src/siteOperations.d.ts +11 -19
  15. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +6 -6
  16. package/dist/_dts/api/src/webhooks.d.ts +98 -1
  17. package/dist/_dts/billing/src/site-arrangements.d.ts +3 -0
  18. package/dist/_dts/blocks/src/client/course-registration.d.ts +4 -1
  19. package/dist/_dts/blocks/src/client.d.ts +4 -1
  20. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -4
  21. package/dist/_dts/blocks/src/index.d.ts +3 -1
  22. package/dist/_dts/blocks/src/system/blocks/course-registration.d.ts +2 -1
  23. package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +2 -1
  24. package/dist/_dts/blocks/src/system/blocks/cta-full.d.ts +2 -4
  25. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +2 -1
  26. package/dist/_dts/blocks/src/system/blocks/events/event-listing.d.ts +2 -1
  27. package/dist/_dts/blocks/src/system/blocks/events/event-spotlight.d.ts +2 -1
  28. package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule.d.ts +3 -2
  29. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +2 -1
  30. package/dist/_dts/blocks/src/system/blocks/file-download.d.ts +2 -1
  31. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +2 -1
  32. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +2 -1
  33. package/dist/_dts/blocks/src/system/blocks/single-button.d.ts +2 -1
  34. package/dist/_dts/blocks/src/system/constants/buttonRoles.d.ts +35 -0
  35. package/dist/_dts/blocks/src/system/fields/button.d.ts +10 -21
  36. package/dist/_dts/blocks/src/system/fields/ctas.d.ts +2 -1
  37. package/dist/_dts/blocks/src/system/fragments/library/heroCtaRow.d.ts +9 -5
  38. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +18 -18
  39. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +9 -9
  40. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessWholeSeriesRegistrationFlow.d.ts +29 -0
  41. package/dist/_dts/blocks/src/system/runtime/nodes/buttonAffordance.d.ts +1 -1
  42. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/ErrorStep.d.ts +2 -1
  43. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/PaymentFailedStep.d.ts +2 -1
  44. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/VerifyingTimeoutStep.d.ts +2 -1
  45. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/types.d.ts +21 -0
  46. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +4 -4
  47. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/whole-series-registration.headless.contract.d.ts +326 -0
  48. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/whole-series-registration.headless.planning.d.ts +27 -0
  49. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.interactive.d.ts +5 -4
  50. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +3 -2
  51. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +2 -1
  52. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +5 -4
  53. package/dist/_dts/blocks/src/system/runtime/nodes/file-download.d.ts +2 -3
  54. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +2 -1
  55. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +6 -3
  56. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +7 -6
  57. package/dist/_dts/blocks/src/system/runtime/nodes/shop.types.d.ts +2 -1
  58. package/dist/_dts/blocks/src/system/runtime/shared/types.d.ts +2 -1
  59. package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +4 -2
  60. package/dist/_dts/content-editor/src/index.d.ts +12 -12
  61. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +17 -2
  62. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +221 -53
  63. package/dist/_dts/editor-blocks/src/widgets/button/context.d.ts +3 -2
  64. package/dist/_dts/preview-next/src/client/index.d.ts +3 -2
  65. package/dist/_dts/preview-next/src/client/preview/ButtonStylePicker.d.ts +16 -0
  66. package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -3
  67. package/dist/_dts/preview-next/src/client/preview/PreviewDesignOpenRequestContext.d.ts +7 -0
  68. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +5 -11
  69. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +5 -6
  70. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +6 -7
  71. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +7 -9
  72. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.d.ts +4 -11
  73. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +7 -7
  74. package/dist/_dts/preview-next/src/client/preview/sidebarTabPreference.d.ts +0 -8
  75. package/dist/_dts/preview-next/src/client/preview/siteChromeLookRows.d.ts +1 -11
  76. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +1 -5
  77. package/dist/_dts/preview-next/src/client/preview/siteChromeSavePlan.d.ts +2 -3
  78. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +3 -4
  79. package/dist/_dts/preview-next/src/client/preview/styleConfiguratorSnapshot.d.ts +3 -5
  80. package/dist/_dts/sdk/src/bookings/index.d.ts +5 -4
  81. package/dist/_dts/sdk/src/bookings/types.d.ts +3 -3
  82. package/dist/_dts/sdk/src/cli/commands/style.d.ts +3 -2
  83. package/dist/_dts/sdk/src/client/management/types.d.ts +2 -1
  84. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +12 -15
  85. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -1
  86. package/dist/_dts/sdk/src/version.d.ts +1 -1
  87. package/dist/_dts/sdk/src/webhooks/index.d.ts +1 -1
  88. package/dist/_dts/sdk/src/webhooks/verify.d.ts +3 -3
  89. package/dist/_dts/site-commands/src/commands.d.ts +129 -6
  90. package/dist/_dts/theme-core/src/buttons/index.d.ts +1 -1
  91. package/dist/_dts/theme-core/src/buttons/styles/domain.d.ts +80 -0
  92. package/dist/_dts/theme-core/src/buttons/styles/index.d.ts +3 -0
  93. package/dist/_dts/theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.d.ts +49 -0
  94. package/dist/_dts/theme-core/src/buttons/styles/recipes/quietArrow.d.ts +67 -0
  95. package/dist/_dts/theme-core/src/buttons/styles/recipes/staticRecipes.d.ts +649 -0
  96. package/dist/_dts/theme-core/src/buttons/styles/registry.d.ts +753 -0
  97. package/dist/_dts/theme-core/src/buttons/styles/selection.d.ts +69 -0
  98. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +26 -24
  99. package/dist/_dts/theme-core/src/site-styles/footerLooks.d.ts +19 -153
  100. package/dist/_dts/theme-core/src/site-styles/headerCtaVariants.d.ts +3 -1
  101. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +8 -9
  102. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +4 -4
  103. package/dist/_dts/ui/src/palette/hex.d.ts +3 -3
  104. package/dist/cli/index.mjs +1760 -1914
  105. package/dist/cli/init-docs/content/workflow-isr-revalidation.md +1 -1
  106. package/dist/client/{DiscountCodeDisclosure-DU1ygxU2.mjs → DiscountCodeDisclosure-C4xvTBux.mjs} +1 -1
  107. package/dist/client/{EventCombined.client-DB5zagCo.mjs → EventCombined.client-Cr7G131j.mjs} +2 -3
  108. package/dist/client/{EventListing.client-CTX9JHBL.mjs → EventListing.client-CAjbseNy.mjs} +2 -2
  109. package/dist/client/{LeafletStaticMap-BYImhgiB.mjs → LeafletStaticMap-BMlWfwz3.mjs} +1 -1
  110. package/dist/client/{MagicLinkForm-CRkw_M3l.mjs → MagicLinkForm-ChdFz96y.mjs} +1 -2
  111. package/dist/client/{StepIndicator-BnmVBJJh.mjs → StepIndicator-7D3GaBeM.mjs} +2 -2
  112. package/dist/client/{accordion-CeGreumd.mjs → accordion-D8JTs2Si.mjs} +1 -1
  113. package/dist/client/{bookingForm-CSzFNrpN.mjs → bookingForm-H3DCRBHs.mjs} +6 -7
  114. package/dist/client/bookings.mjs +3069 -1447
  115. package/dist/client/{carousel-B2jDtogf.mjs → carousel-DMr_QWlz.mjs} +1 -1
  116. package/dist/client/{cart-D-jZ-vaY.mjs → cart-DWMbfBdR.mjs} +3 -3
  117. package/dist/client/{checkout-Dza-LA7N.mjs → checkout-zmfdkXLx.mjs} +3 -3
  118. package/dist/client/client.mjs +1732 -1913
  119. package/dist/client/{colorStyles-CrgzoXsm.mjs → colorStyles-gcTh5yZT.mjs} +2 -12
  120. package/dist/client/{colorTokenParts-CMugwvX_.mjs → colorTokenParts-FSS3al6l.mjs} +31 -1
  121. package/dist/client/{courseRegistration-TYkNychb.mjs → courseRegistration-Z_mn18jy.mjs} +100 -37
  122. package/dist/client/{eventCalendar-BI_90SsT.mjs → eventCalendar-CYp0YJGF.mjs} +4 -5
  123. package/dist/client/{eventCombined-mNrpryE9.mjs → eventCombined-rKyYZUa9.mjs} +2 -2
  124. package/dist/client/{eventDetails-D4GVlCIY.mjs → eventDetails-X0ZaUuMj.mjs} +3 -3
  125. package/dist/client/{eventListing-YhKN018y.mjs → eventListing-W1SuL7EP.mjs} +2 -2
  126. package/dist/client/{eventRegistration-CdHGtilr.mjs → eventRegistration-ClWricui.mjs} +6 -7
  127. package/dist/client/{form-AcAL45rA.mjs → form--eKPwAAD.mjs} +1 -2
  128. package/dist/client/{headerSection-uEC52ueD.mjs → headerSection-BSeGr-FS.mjs} +2 -3
  129. package/dist/client/hooks.mjs +1554 -1871
  130. package/dist/client/{locationMap-_wJDSUYe.mjs → locationMap-BpOrtNYn.mjs} +8 -5
  131. package/dist/client/{media-BK0O3b-U.mjs → media-DoF0dcVx.mjs} +2 -2
  132. package/dist/client/{newsletterForm-DrArsb2B.mjs → newsletterForm-Bt7it7Dy.mjs} +1 -2
  133. package/dist/client/{pricing-BSYVghwo.mjs → pricing-BTjSDDr4.mjs} +1 -1
  134. package/dist/client/{productDetail-Dyk90sMs.mjs → productDetail-ICnVTcCg.mjs} +3 -3
  135. package/dist/client/{productList-BCKThwAI.mjs → productList-ZHr6D604.mjs} +3 -3
  136. package/dist/client/{propsDecoder-CkXxkdSR.mjs → propsDecoder-wWN0tBDF.mjs} +2351 -129
  137. package/dist/client/rendering/client.mjs +1664 -1824
  138. package/dist/client/rendering/islands.mjs +20 -20
  139. package/dist/client/rendering.mjs +1697 -1909
  140. package/dist/client/{shop-DeltVH10.mjs → shop-C1u_BUn0.mjs} +5 -6
  141. package/dist/client/{shop-commerce-BD9Jsm2Z.mjs → shop-commerce-CleZdRha.mjs} +5 -6
  142. package/dist/client/{shop-commerce-store-CmXD6FDS.mjs → shop-commerce-store-ycnoB2Ce.mjs} +1 -1
  143. package/dist/client/{shopShared-B8v-lH_F.mjs → shopShared-CPhByt2a.mjs} +3 -3
  144. package/dist/client/{useDiscountCodeUi-DbWJN8ld.mjs → useDiscountCodeUi-cStSQI6C.mjs} +1 -1
  145. package/dist/client/{useEventFilters-EJIMUnqT.mjs → useEventFilters-DKPN7hSY.mjs} +26 -27
  146. package/dist/client/{usePolling-Cmh14fc7.mjs → usePolling-BKAd6pkZ.mjs} +2 -2
  147. package/dist/preview-next/before-render.mjs +37 -6
  148. package/dist/preview-next/client/runtime.mjs +4 -4
  149. package/dist/preview-next/middleware.mjs +37 -6
  150. package/dist/{previewAuthStore-CTO7CRPk.mjs → previewAuthStore-BkT1D06A.mjs} +37 -6
  151. package/dist/{sdk-runtime-Dou0GAav.mjs → sdk-runtime-hu3wr3ng.mjs} +2 -2
  152. package/dist/{separator-CI5wZNXT.mjs → separator-Bln8izQ9.mjs} +1 -1
  153. package/dist/server/components.mjs +1472 -1788
  154. package/dist/server/config-validation.mjs +1559 -1876
  155. package/dist/server/config.mjs +1559 -1876
  156. package/dist/server/data.mjs +1554 -1871
  157. package/dist/server/index.mjs +38 -7
  158. package/dist/server/next/revalidate.mjs +53 -1
  159. package/dist/server/next.mjs +1584 -1869
  160. package/dist/server/page-converter.mjs +1543 -1860
  161. package/dist/server/prebuild.mjs +1 -1
  162. package/dist/server/rendering/server.mjs +1472 -1788
  163. package/dist/server/rendering.mjs +1472 -1788
  164. package/dist/server/routing.mjs +1600 -1891
  165. package/dist/server/server.mjs +1574 -1860
  166. package/dist/server/theme-bridge.mjs +1436 -1619
  167. package/dist/server/theme.mjs +1345 -1241
  168. package/dist/server/webhooks.mjs +54 -2
  169. package/package.json +1 -1
  170. package/dist/_dts/theme-core/src/buttons/personalities/brushed-wash.d.ts +0 -16
  171. package/dist/_dts/theme-core/src/buttons/personalities/confident-chip.d.ts +0 -16
  172. package/dist/_dts/theme-core/src/buttons/personalities/earth-pill.d.ts +0 -16
  173. package/dist/_dts/theme-core/src/buttons/personalities/editorial-link.d.ts +0 -16
  174. package/dist/_dts/theme-core/src/buttons/personalities/flat-ink.d.ts +0 -20
  175. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +0 -172
  176. package/dist/_dts/theme-core/src/buttons/personalities/ink-stamp.d.ts +0 -16
  177. package/dist/_dts/theme-core/src/buttons/personalities/joy-stamp.d.ts +0 -22
  178. package/dist/_dts/theme-core/src/buttons/personalities/ornate-ritual.d.ts +0 -16
  179. package/dist/_dts/theme-core/src/buttons/personalities/pebble.d.ts +0 -16
  180. package/dist/_dts/theme-core/src/buttons/personalities/quiet-arrow.d.ts +0 -17
  181. package/dist/_dts/theme-core/src/buttons/personalities/showtime-pill.d.ts +0 -17
  182. package/dist/_dts/theme-core/src/buttons/personalities/soft-pill.d.ts +0 -16
  183. package/dist/_dts/theme-core/src/buttons/personalities/two-tone-pill.d.ts +0 -17
  184. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +0 -285
  185. package/dist/client/buttons-DoFV7KDL.mjs +0 -2115
  186. package/dist/client/foregroundContract-xICPq59x.mjs +0 -31
@@ -3200,7 +3200,7 @@ const gradientDirectionSchema$1 = z$1.enum([
3200
3200
  "to-br",
3201
3201
  "to-bl"
3202
3202
  ]);
3203
- const buttonBackgroundSchema = z$1.discriminatedUnion("type", [
3203
+ const buttonColourTreatmentSchema = z$1.discriminatedUnion("type", [
3204
3204
  z$1.object({
3205
3205
  type: z$1.literal("solid"),
3206
3206
  colorToken: opaqueButtonColourTokenSchema
@@ -3224,6 +3224,7 @@ const buttonBackgroundSchema = z$1.discriminatedUnion("type", [
3224
3224
  role: z$1.literal("link")
3225
3225
  })
3226
3226
  ]);
3227
+ const buttonBackgroundSchema = buttonColourTreatmentSchema;
3227
3228
  const effectApplicationSchema$1 = z$1.object({
3228
3229
  effectId: z$1.string(),
3229
3230
  options: z$1.record(z$1.string(), z$1.json()).optional()
@@ -3436,265 +3437,429 @@ function isUnknownArray(value) {
3436
3437
  }
3437
3438
  buttonSizeNameSchema.options;
3438
3439
  //#endregion
3439
- //#region ../theme-core/src/buttons/personalities/types.ts
3440
- function asButtonPersonalityId(value) {
3441
- if (value.length === 0) throw new Error("ButtonPersonalityId must be a non-empty string");
3442
- return value;
3440
+ //#region ../theme-core/src/buttons/styles/domain.ts
3441
+ const PUBLIC_BUTTON_ROLES = [
3442
+ "primary",
3443
+ "secondary",
3444
+ "outline",
3445
+ "ghost",
3446
+ "accent"
3447
+ ];
3448
+ function defineButtonStyleRecipe(recipe) {
3449
+ return recipe;
3450
+ }
3451
+ function materializeButtonRoles(definitions) {
3452
+ const primary = materializeCompleteRole("primary", definitions.primary.appearance);
3453
+ const secondary = materializeCompleteRole("secondary", definitions.secondary.appearance);
3454
+ const completeRoles = {
3455
+ primary,
3456
+ secondary
3457
+ };
3458
+ return {
3459
+ primary,
3460
+ secondary,
3461
+ outline: materializeSupportingRole("outline", definitions.outline, completeRoles),
3462
+ ghost: materializeSupportingRole("ghost", definitions.ghost, completeRoles),
3463
+ accent: materializeSupportingRole("accent", definitions.accent, completeRoles)
3464
+ };
3443
3465
  }
3444
- const buttonPersonalityIdSchema = z$1.string().min(1).transform((value) => asButtonPersonalityId(value));
3445
- z$1.object({
3446
- id: buttonPersonalityIdSchema,
3447
- name: z$1.string().min(1),
3448
- description: z$1.string().min(1),
3449
- tags: styleTagsSchema,
3450
- buttonSystem: buttonSystemSchema
3451
- });
3452
- /**
3453
- * Helper for personality file modules to keep the call site short and
3454
- * type-safe. `as const satisfies ...` would also work but produces wider
3455
- * types at use sites.
3456
- */
3457
- function defineButtonPersonality(input) {
3466
+ function resolveButtonStyleRecipe(recipe, parameters) {
3467
+ const parsedParameters = recipe.parameterSchema.safeParse(parameters);
3468
+ if (!parsedParameters.success) return {
3469
+ kind: "error",
3470
+ error: {
3471
+ kind: "invalid-parameters",
3472
+ styleId: recipe.id,
3473
+ issues: parsedParameters.error.issues.map((issue) => issue.message)
3474
+ }
3475
+ };
3476
+ const definition = recipe.defineSystem(parsedParameters.data);
3477
+ const roles = materializeButtonRoles(definition.roles);
3478
+ const buttonSystem = {
3479
+ global: definition.global,
3480
+ variants: PUBLIC_BUTTON_ROLES.map((role) => roles[role]),
3481
+ ...definition.sizes ? { sizes: definition.sizes } : {}
3482
+ };
3483
+ const parsedButtonSystem = buttonSystemSchema.safeParse(buttonSystem);
3484
+ if (!parsedButtonSystem.success) return {
3485
+ kind: "error",
3486
+ error: {
3487
+ kind: "invalid-button-system",
3488
+ styleId: recipe.id,
3489
+ issues: parsedButtonSystem.error.issues.map((issue) => issue.message)
3490
+ }
3491
+ };
3458
3492
  return {
3459
- id: asButtonPersonalityId(input.id),
3460
- name: input.name,
3461
- description: input.description,
3462
- tags: input.tags,
3463
- buttonSystem: buttonSystemSchema.parse(input.buttonSystem)
3493
+ kind: "resolved",
3494
+ buttonSystem: parsedButtonSystem.data
3495
+ };
3496
+ }
3497
+ function materializeSupportingRole(role, definition, completeRoles) {
3498
+ if (definition.kind === "complete") return materializeCompleteRole(role, definition.appearance);
3499
+ return {
3500
+ ...completeRoles[definition.from],
3501
+ ...definition.overrides,
3502
+ id: role,
3503
+ name: roleName(role),
3504
+ enabled: true,
3505
+ priority: 3
3506
+ };
3507
+ }
3508
+ function materializeCompleteRole(role, appearance) {
3509
+ return {
3510
+ ...appearance,
3511
+ id: role,
3512
+ name: roleName(role),
3513
+ enabled: true,
3514
+ priority: rolePriority(role)
3464
3515
  };
3465
3516
  }
3517
+ function roleName(role) {
3518
+ return role.charAt(0).toUpperCase() + role.slice(1);
3519
+ }
3520
+ function rolePriority(role) {
3521
+ if (role === "primary") return 1;
3522
+ if (role === "secondary") return 2;
3523
+ return 3;
3524
+ }
3466
3525
  //#endregion
3467
- //#region ../theme-core/src/buttons/personalities/brushed-wash.ts
3468
- /**
3469
- * Brushed Wash — gradient backgrounds that read as watercolour washes.
3470
- * Generous padding, soft shadows; pairs with vibrant organic brands.
3471
- */
3472
- const brushedWash = defineButtonPersonality({
3473
- id: "brushed-wash",
3474
- name: "Brushed Wash",
3475
- description: "Watercolour-gradient buttons with soft shadows and generous padding.",
3526
+ //#region ../theme-core/src/buttons/styles/selection.ts
3527
+ const BUTTON_STYLE_IDS = [
3528
+ "soft-pill",
3529
+ "earth-pill",
3530
+ "confident-chip",
3531
+ "editorial-link",
3532
+ "pebble",
3533
+ "ink-stamp",
3534
+ "flat-ink",
3535
+ "brushed-wash",
3536
+ "showtime-pill",
3537
+ "joy-stamp",
3538
+ "ornate-ritual",
3539
+ "quiet-arrow"
3540
+ ];
3541
+ const quietArrowParametersSchema = z$1.object({ secondaryTreatment: z$1.enum(["outlined", "solid-accent"]) }).strict();
3542
+ const emptyParametersSchema$1 = z$1.object({}).strict();
3543
+ function selectionBranch(styleId, parameters) {
3544
+ return z$1.object({
3545
+ styleId: z$1.literal(styleId),
3546
+ parameters
3547
+ }).strict();
3548
+ }
3549
+ const buttonStyleSelectionSchema = z$1.discriminatedUnion("styleId", [
3550
+ selectionBranch("soft-pill", emptyParametersSchema$1),
3551
+ selectionBranch("earth-pill", emptyParametersSchema$1),
3552
+ selectionBranch("confident-chip", emptyParametersSchema$1),
3553
+ selectionBranch("editorial-link", emptyParametersSchema$1),
3554
+ selectionBranch("pebble", emptyParametersSchema$1),
3555
+ selectionBranch("ink-stamp", emptyParametersSchema$1),
3556
+ selectionBranch("flat-ink", emptyParametersSchema$1),
3557
+ selectionBranch("brushed-wash", emptyParametersSchema$1),
3558
+ selectionBranch("showtime-pill", emptyParametersSchema$1),
3559
+ selectionBranch("joy-stamp", emptyParametersSchema$1),
3560
+ selectionBranch("ornate-ritual", emptyParametersSchema$1),
3561
+ selectionBranch("quiet-arrow", quietArrowParametersSchema)
3562
+ ]);
3563
+ //#endregion
3564
+ //#region ../theme-core/src/buttons/styles/recipes/quietArrow.ts
3565
+ const quietArrowRecipe = defineButtonStyleRecipe({
3566
+ id: "quiet-arrow",
3567
+ accessibilityLabel: "Wide uppercase buttons with trailing arrows",
3476
3568
  tags: {
3477
3569
  tone: "classic",
3478
- energy: "vibrant",
3479
- motion: "standard",
3480
- era: "organic"
3570
+ energy: "calm",
3571
+ motion: "subtle",
3572
+ era: "editorial"
3481
3573
  },
3482
- buttonSystem: {
3574
+ parameterSchema: quietArrowParametersSchema,
3575
+ defaultParameters: { secondaryTreatment: "outlined" },
3576
+ controls: [{
3577
+ kind: "choice",
3578
+ parameter: "secondaryTreatment",
3579
+ label: "Secondary button treatment",
3580
+ options: [{
3581
+ value: "outlined",
3582
+ label: "Outlined"
3583
+ }, {
3584
+ value: "solid-accent",
3585
+ label: "Solid accent"
3586
+ }]
3587
+ }],
3588
+ defineSystem: (parameters) => ({
3483
3589
  global: {
3484
3590
  cornerStyle: "rounded",
3485
- shadow: "low",
3486
- textTransform: "none",
3591
+ textTransform: "uppercase",
3487
3592
  fontWeight: 500,
3488
3593
  borderWidth: 1,
3594
+ typography: "body",
3595
+ fontSize: "text-sm",
3596
+ letterSpacing: "loose",
3489
3597
  hoverTransform: "none",
3490
3598
  hoverColor: "none"
3491
3599
  },
3492
3600
  sizes: {
3493
3601
  sm: {
3494
- padding: "0.75rem 2rem",
3602
+ padding: "0.625rem 1.25rem",
3603
+ fontSize: "text-xs"
3604
+ },
3605
+ md: {
3606
+ padding: "0.8125rem 1.75rem",
3495
3607
  fontSize: "text-sm"
3496
3608
  },
3497
- md: { padding: "1rem 2.5rem" },
3498
3609
  lg: {
3499
- padding: "1.25rem 3rem",
3500
- fontSize: "text-lg"
3610
+ padding: "0.9375rem 2.125rem",
3611
+ fontSize: "text-sm"
3501
3612
  },
3502
3613
  xl: {
3503
- padding: "1.625rem 3.75rem",
3504
- fontSize: "text-xl"
3614
+ padding: "1.0625rem 2.5rem",
3615
+ fontSize: "text-base"
3505
3616
  }
3506
3617
  },
3507
- variants: [
3508
- {
3509
- id: "primary",
3510
- name: "Primary",
3511
- enabled: true,
3512
- priority: 1,
3513
- background: {
3514
- type: "gradient",
3515
- stops: ["primary", "accent"],
3516
- direction: "to-r",
3517
- foregroundToken: "primaryForeground"
3518
- },
3519
- borderRadius: "rounded-lg",
3520
- shadow: {
3521
- elevation: "low",
3522
- softness: "soft",
3523
- position: "bottom"
3618
+ roles: {
3619
+ primary: {
3620
+ kind: "complete",
3621
+ appearance: {
3622
+ background: {
3623
+ type: "solid",
3624
+ colorToken: unsafeAsOpaqueButtonColourToken("primary")
3625
+ },
3626
+ borderRadius: "rounded-xl",
3627
+ affordance: { iconId: "ArrowRight" },
3628
+ effects: { hover: [{
3629
+ effectId: "darken-background",
3630
+ options: { amount: 100 }
3631
+ }] }
3524
3632
  }
3525
3633
  },
3526
- {
3527
- id: "secondary",
3528
- name: "Secondary",
3529
- enabled: true,
3530
- priority: 2,
3531
- background: {
3532
- type: "gradient",
3533
- stops: ["secondary", "accent"],
3534
- direction: "to-br",
3535
- foregroundToken: "primaryForeground"
3536
- },
3537
- borderRadius: "rounded-lg",
3538
- shadow: {
3539
- elevation: "low",
3540
- softness: "soft",
3541
- position: "bottom"
3634
+ secondary: {
3635
+ kind: "complete",
3636
+ appearance: parameters.secondaryTreatment === "solid-accent" ? {
3637
+ background: {
3638
+ type: "solid",
3639
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
3640
+ },
3641
+ borderRadius: "rounded-xl",
3642
+ affordance: { iconId: "ArrowRight" },
3643
+ effects: { hover: [{
3644
+ effectId: "darken-background",
3645
+ options: { amount: 100 }
3646
+ }] }
3647
+ } : {
3648
+ background: {
3649
+ type: "surface",
3650
+ role: "link"
3651
+ },
3652
+ borderRadius: "rounded-xl",
3653
+ border: { widthClass: "border" },
3654
+ affordance: { iconId: "ArrowRight" },
3655
+ effects: { hover: [{
3656
+ effectId: "background-on-hover",
3657
+ options: { colorToken: "surfaceAlt" }
3658
+ }] }
3542
3659
  }
3543
3660
  },
3544
- {
3545
- id: "outline",
3546
- name: "Outline",
3547
- enabled: true,
3548
- priority: 3,
3549
- background: {
3550
- type: "surface",
3551
- role: "link"
3552
- },
3553
- borderRadius: "rounded-lg",
3554
- border: { widthClass: "border" },
3555
- effects: { hover: [{
3556
- effectId: "background-on-hover",
3557
- options: { colorToken: "surface" }
3558
- }] }
3661
+ outline: {
3662
+ kind: "complete",
3663
+ appearance: {
3664
+ background: {
3665
+ type: "surface",
3666
+ role: "link"
3667
+ },
3668
+ borderRadius: "rounded-xl",
3669
+ border: { widthClass: "border" }
3670
+ }
3559
3671
  },
3560
- {
3561
- id: "ghost",
3562
- name: "Ghost",
3563
- enabled: true,
3564
- priority: 3,
3565
- background: {
3566
- type: "surface",
3567
- role: "link"
3568
- },
3569
- borderRadius: "rounded-lg",
3570
- effects: { hover: [{
3571
- effectId: "background-on-hover",
3572
- options: { colorToken: "surface" }
3573
- }] }
3672
+ ghost: {
3673
+ kind: "complete",
3674
+ appearance: {
3675
+ background: {
3676
+ type: "surface",
3677
+ role: "link"
3678
+ },
3679
+ borderRadius: "rounded-xl"
3680
+ }
3681
+ },
3682
+ accent: {
3683
+ kind: "derive",
3684
+ from: "primary",
3685
+ overrides: { background: {
3686
+ type: "solid",
3687
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
3688
+ } }
3574
3689
  }
3575
- ]
3576
- }
3690
+ }
3691
+ })
3577
3692
  });
3578
3693
  //#endregion
3579
- //#region ../theme-core/src/buttons/personalities/confident-chip.ts
3580
- /**
3581
- * Confident Chip — moderate-radius solid buttons that read as competent and
3582
- * direct. Default for Clear Professional; works for any modern brand voice.
3583
- */
3584
- const confidentChip = defineButtonPersonality({
3585
- id: "confident-chip",
3586
- name: "Confident Chip",
3587
- description: "Mid-radius solid buttons with a crisp hover.",
3694
+ //#region ../theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.ts
3695
+ const emptyParametersSchema = z$1.object({}).strict();
3696
+ function defineStaticButtonStyleRecipe(input) {
3697
+ const system = normalizeSystem(input.system);
3698
+ return defineButtonStyleRecipe({
3699
+ id: input.id,
3700
+ accessibilityLabel: input.accessibilityLabel,
3701
+ tags: input.tags,
3702
+ parameterSchema: emptyParametersSchema,
3703
+ defaultParameters: {},
3704
+ controls: [],
3705
+ defineSystem: () => system
3706
+ });
3707
+ }
3708
+ function normalizeSystem(input) {
3709
+ return {
3710
+ global: buttonGlobalSettingsSchema.parse(input.global),
3711
+ ...input.sizes ? { sizes: input.sizes } : {},
3712
+ roles: {
3713
+ primary: normalizeCompleteRole(input.roles.primary),
3714
+ secondary: normalizeCompleteRole(input.roles.secondary),
3715
+ outline: normalizeSupportingRole(input.roles.outline),
3716
+ ghost: normalizeSupportingRole(input.roles.ghost),
3717
+ accent: normalizeSupportingRole(input.roles.accent)
3718
+ }
3719
+ };
3720
+ }
3721
+ function normalizeCompleteRole(role) {
3722
+ return {
3723
+ kind: "complete",
3724
+ appearance: normalizeAppearance(role.appearance)
3725
+ };
3726
+ }
3727
+ function normalizeSupportingRole(role) {
3728
+ if (role.kind === "complete") return normalizeCompleteRole(role);
3729
+ return {
3730
+ kind: "derive",
3731
+ from: role.from,
3732
+ ...role.overrides ? { overrides: normalizeAppearanceOverrides(role.overrides) } : {}
3733
+ };
3734
+ }
3735
+ function normalizeAppearance(appearance) {
3736
+ const { background, hoverBackgroundToken, ...rest } = appearance;
3737
+ return {
3738
+ ...rest,
3739
+ background: buttonColourTreatmentSchema.parse(background),
3740
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
3741
+ };
3742
+ }
3743
+ function normalizeAppearanceOverrides(overrides) {
3744
+ const { background, hoverBackgroundToken, ...rest } = overrides;
3745
+ return {
3746
+ ...rest,
3747
+ ...background ? { background: buttonColourTreatmentSchema.parse(background) } : {},
3748
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
3749
+ };
3750
+ }
3751
+ //#endregion
3752
+ //#region ../theme-core/src/buttons/styles/recipes/staticRecipes.ts
3753
+ const softPillRecipe = defineStaticButtonStyleRecipe({
3754
+ id: "soft-pill",
3755
+ accessibilityLabel: "Rounded pill buttons with a gentle hover lift",
3588
3756
  tags: {
3589
3757
  tone: "classic",
3590
3758
  energy: "calm",
3591
- motion: "standard",
3592
- era: "modern"
3759
+ motion: "subtle",
3760
+ era: "organic"
3593
3761
  },
3594
- buttonSystem: {
3762
+ system: {
3595
3763
  global: {
3596
- cornerStyle: "rounded",
3597
- shadow: "medium",
3764
+ cornerStyle: "pill",
3765
+ shadow: "low",
3598
3766
  textTransform: "none",
3599
- fontWeight: 600,
3600
- borderWidth: 1,
3601
- hoverTransform: "none",
3767
+ fontWeight: 500,
3768
+ borderWidth: 2,
3769
+ hoverTransform: "lift",
3602
3770
  hoverColor: "none"
3603
3771
  },
3604
- variants: [
3605
- {
3606
- id: "primary",
3607
- name: "Primary",
3608
- enabled: true,
3609
- priority: 1,
3610
- background: {
3611
- type: "solid",
3612
- colorToken: "primary"
3613
- },
3614
- borderRadius: "rounded-md",
3615
- shadow: {
3616
- elevation: "medium",
3617
- softness: "soft",
3618
- position: "bottom"
3619
- },
3620
- effects: {
3621
- hover: [{
3622
- effectId: "darken-background",
3623
- options: { amount: 100 }
3624
- }],
3625
- active: [{
3626
- effectId: "scale-down",
3627
- options: { scale: "0.97" }
3628
- }]
3772
+ roles: {
3773
+ primary: {
3774
+ kind: "complete",
3775
+ appearance: {
3776
+ background: {
3777
+ type: "solid",
3778
+ colorToken: "primary"
3779
+ },
3780
+ borderRadius: "rounded-full",
3781
+ shadow: {
3782
+ elevation: "low",
3783
+ softness: "soft",
3784
+ position: "bottom"
3785
+ },
3786
+ effects: {
3787
+ hover: [{
3788
+ effectId: "lift",
3789
+ options: { translateY: "-1px" }
3790
+ }],
3791
+ active: [{
3792
+ effectId: "scale-down",
3793
+ options: { scale: "0.98" }
3794
+ }]
3795
+ }
3629
3796
  }
3630
3797
  },
3631
- {
3632
- id: "secondary",
3633
- name: "Secondary",
3634
- enabled: true,
3635
- priority: 2,
3636
- background: {
3637
- type: "solid",
3638
- colorToken: "surface"
3639
- },
3640
- borderRadius: "rounded-md",
3641
- border: { widthClass: "border" },
3642
- effects: { hover: [{
3643
- effectId: "background-on-hover",
3644
- options: { colorToken: "background" }
3645
- }] }
3798
+ secondary: {
3799
+ kind: "complete",
3800
+ appearance: {
3801
+ background: {
3802
+ type: "surface",
3803
+ role: "link"
3804
+ },
3805
+ borderRadius: "rounded-full",
3806
+ border: { widthClass: "border-2" },
3807
+ effects: { hover: [{
3808
+ effectId: "background-on-hover",
3809
+ options: { colorToken: "surface" }
3810
+ }] }
3811
+ }
3646
3812
  },
3647
- {
3648
- id: "outline",
3649
- name: "Outline",
3650
- enabled: true,
3651
- priority: 3,
3652
- background: {
3653
- type: "surface",
3654
- role: "link"
3655
- },
3656
- borderRadius: "rounded-md",
3657
- border: { widthClass: "border" },
3658
- effects: { hover: [{
3659
- effectId: "background-on-hover",
3660
- options: { colorToken: "surface" }
3661
- }] }
3813
+ outline: {
3814
+ kind: "complete",
3815
+ appearance: {
3816
+ background: {
3817
+ type: "surface",
3818
+ role: "link"
3819
+ },
3820
+ borderRadius: "rounded-full",
3821
+ border: { widthClass: "border" },
3822
+ effects: { hover: [{
3823
+ effectId: "background-on-hover",
3824
+ options: { colorToken: "surface" }
3825
+ }] }
3826
+ }
3662
3827
  },
3663
- {
3664
- id: "ghost",
3665
- name: "Ghost",
3666
- enabled: true,
3667
- priority: 3,
3668
- background: {
3669
- type: "surface",
3670
- role: "link"
3671
- },
3672
- borderRadius: "rounded-md",
3673
- effects: { hover: [{
3674
- effectId: "background-on-hover",
3675
- options: { colorToken: "surface" }
3676
- }] }
3828
+ ghost: {
3829
+ kind: "complete",
3830
+ appearance: {
3831
+ background: {
3832
+ type: "surface",
3833
+ role: "link"
3834
+ },
3835
+ borderRadius: "rounded-full",
3836
+ effects: { hover: [{
3837
+ effectId: "background-on-hover",
3838
+ options: { colorToken: "surface" }
3839
+ }] }
3840
+ }
3841
+ },
3842
+ accent: {
3843
+ kind: "derive",
3844
+ from: "primary",
3845
+ overrides: { background: {
3846
+ type: "solid",
3847
+ colorToken: "accent"
3848
+ } }
3677
3849
  }
3678
- ]
3850
+ }
3679
3851
  }
3680
3852
  });
3681
- //#endregion
3682
- //#region ../theme-core/src/buttons/personalities/earth-pill.ts
3683
- /**
3684
- * Earth Pill - warm studio pills with compact, primary-coloured ghost CTAs.
3685
- * Built for grounded editorial wellness styles such as Soft Earth.
3686
- */
3687
- const earthPill = defineButtonPersonality({
3853
+ const earthPillRecipe = defineStaticButtonStyleRecipe({
3688
3854
  id: "earth-pill",
3689
- name: "Earth Pill",
3690
- description: "Compact terracotta pills with quiet primary-coloured ghost CTAs.",
3855
+ accessibilityLabel: "Compact rounded buttons with a quiet hover lift",
3691
3856
  tags: {
3692
3857
  tone: "classic",
3693
3858
  energy: "calm",
3694
3859
  motion: "subtle",
3695
3860
  era: "organic"
3696
3861
  },
3697
- buttonSystem: {
3862
+ system: {
3698
3863
  global: {
3699
3864
  cornerStyle: "pill",
3700
3865
  shadow: "low",
@@ -3721,576 +3886,547 @@ const earthPill = defineButtonPersonality({
3721
3886
  fontSize: "text-xl"
3722
3887
  }
3723
3888
  },
3724
- variants: [
3725
- {
3726
- id: "primary",
3727
- name: "Primary",
3728
- enabled: true,
3729
- priority: 1,
3730
- background: {
3731
- type: "solid",
3732
- colorToken: "primary"
3733
- },
3734
- borderRadius: "rounded-full",
3735
- shadow: {
3736
- elevation: "low",
3737
- softness: "soft",
3738
- position: "bottom"
3739
- },
3740
- effects: {
3741
- hover: [{
3742
- effectId: "lift",
3743
- options: { translateY: "-1px" }
3744
- }, {
3745
- effectId: "background-on-hover",
3746
- options: { colorToken: "accent" }
3747
- }],
3748
- active: [{
3749
- effectId: "scale-down",
3750
- options: { scale: "0.98" }
3751
- }]
3889
+ roles: {
3890
+ primary: {
3891
+ kind: "complete",
3892
+ appearance: {
3893
+ background: {
3894
+ type: "solid",
3895
+ colorToken: "primary"
3896
+ },
3897
+ borderRadius: "rounded-full",
3898
+ shadow: {
3899
+ elevation: "low",
3900
+ softness: "soft",
3901
+ position: "bottom"
3902
+ },
3903
+ effects: {
3904
+ hover: [{
3905
+ effectId: "lift",
3906
+ options: { translateY: "-1px" }
3907
+ }, {
3908
+ effectId: "background-on-hover",
3909
+ options: { colorToken: "accent" }
3910
+ }],
3911
+ active: [{
3912
+ effectId: "scale-down",
3913
+ options: { scale: "0.98" }
3914
+ }]
3915
+ }
3752
3916
  }
3753
3917
  },
3754
- {
3755
- id: "secondary",
3756
- name: "Secondary",
3757
- enabled: true,
3758
- priority: 2,
3759
- background: {
3760
- type: "surface",
3761
- role: "link"
3762
- },
3763
- borderRadius: "rounded-full",
3764
- border: { widthClass: "border" },
3765
- effects: { hover: [{
3766
- effectId: "background-on-hover",
3767
- options: { colorToken: "muted" }
3768
- }] }
3918
+ secondary: {
3919
+ kind: "complete",
3920
+ appearance: {
3921
+ background: {
3922
+ type: "surface",
3923
+ role: "link"
3924
+ },
3925
+ borderRadius: "rounded-full",
3926
+ border: { widthClass: "border" },
3927
+ effects: { hover: [{
3928
+ effectId: "background-on-hover",
3929
+ options: { colorToken: "muted" }
3930
+ }] }
3931
+ }
3769
3932
  },
3770
- {
3771
- id: "outline",
3772
- name: "Outline",
3773
- enabled: true,
3774
- priority: 3,
3775
- background: {
3776
- type: "surface",
3777
- role: "link"
3778
- },
3779
- borderRadius: "rounded-full",
3780
- border: { widthClass: "border" },
3781
- effects: { hover: [{
3782
- effectId: "background-on-hover",
3783
- options: { colorToken: "surfaceAlt" }
3784
- }] }
3933
+ outline: {
3934
+ kind: "complete",
3935
+ appearance: {
3936
+ background: {
3937
+ type: "surface",
3938
+ role: "link"
3939
+ },
3940
+ borderRadius: "rounded-full",
3941
+ border: { widthClass: "border" },
3942
+ effects: { hover: [{
3943
+ effectId: "background-on-hover",
3944
+ options: { colorToken: "surfaceAlt" }
3945
+ }] }
3946
+ }
3785
3947
  },
3786
- {
3787
- id: "ghost",
3788
- name: "Ghost",
3789
- enabled: true,
3790
- priority: 3,
3791
- background: {
3792
- type: "surface",
3793
- role: "link"
3794
- },
3795
- borderRadius: "rounded-full",
3796
- shadow: {
3797
- elevation: "none",
3798
- softness: null,
3799
- position: "bottom"
3800
- },
3801
- sizes: {
3802
- sm: {
3803
- padding: "0.25rem 0",
3804
- fontSize: "text-sm"
3948
+ ghost: {
3949
+ kind: "complete",
3950
+ appearance: {
3951
+ background: {
3952
+ type: "surface",
3953
+ role: "link"
3805
3954
  },
3806
- md: { padding: "0.375rem 0" },
3807
- lg: {
3808
- padding: "0.5rem 0",
3809
- fontSize: "text-lg"
3955
+ borderRadius: "rounded-full",
3956
+ shadow: {
3957
+ elevation: "none",
3958
+ softness: null,
3959
+ position: "bottom"
3810
3960
  },
3811
- xl: {
3812
- padding: "0.625rem 0",
3813
- fontSize: "text-xl"
3961
+ sizes: {
3962
+ sm: {
3963
+ padding: "0.25rem 0",
3964
+ fontSize: "text-sm"
3965
+ },
3966
+ md: { padding: "0.375rem 0" },
3967
+ lg: {
3968
+ padding: "0.5rem 0",
3969
+ fontSize: "text-lg"
3970
+ },
3971
+ xl: {
3972
+ padding: "0.625rem 0",
3973
+ fontSize: "text-xl"
3974
+ }
3814
3975
  }
3815
3976
  }
3977
+ },
3978
+ accent: {
3979
+ kind: "derive",
3980
+ from: "primary",
3981
+ overrides: { background: {
3982
+ type: "solid",
3983
+ colorToken: "accent"
3984
+ } }
3816
3985
  }
3817
- ]
3986
+ }
3818
3987
  }
3819
3988
  });
3820
- //#endregion
3821
- //#region ../theme-core/src/buttons/personalities/editorial-link.ts
3822
- /**
3823
- * Editorial Link — all variants are link-style with a growing underline.
3824
- * Default for Warm Editorial and Quiet Luxury; reads as refined and quiet.
3825
- */
3826
- const editorialLink = defineButtonPersonality({
3827
- id: "editorial-link",
3828
- name: "Editorial Link",
3829
- description: "Link-style with a growing underline. Refined, typographic.",
3989
+ const confidentChipRecipe = defineStaticButtonStyleRecipe({
3990
+ id: "confident-chip",
3991
+ accessibilityLabel: "Moderately rounded solid buttons with a crisp hover",
3830
3992
  tags: {
3831
- tone: "minimal",
3993
+ tone: "classic",
3832
3994
  energy: "calm",
3833
- motion: "subtle",
3834
- era: "editorial"
3995
+ motion: "standard",
3996
+ era: "modern"
3835
3997
  },
3836
- buttonSystem: {
3998
+ system: {
3837
3999
  global: {
3838
- cornerStyle: "square",
4000
+ cornerStyle: "rounded",
4001
+ shadow: "medium",
3839
4002
  textTransform: "none",
3840
- fontWeight: 500,
4003
+ fontWeight: 600,
3841
4004
  borderWidth: 1,
3842
4005
  hoverTransform: "none",
3843
4006
  hoverColor: "none"
3844
4007
  },
3845
- variants: [
3846
- {
3847
- id: "primary",
3848
- name: "Primary",
3849
- enabled: true,
3850
- priority: 1,
3851
- background: {
3852
- type: "surface",
3853
- role: "link"
3854
- },
3855
- borderRadius: "rounded-none",
3856
- sizes: {
3857
- sm: { padding: "0.25rem 0" },
3858
- md: { padding: "0.5rem 0" },
3859
- lg: { padding: "0.625rem 0" },
3860
- xl: { padding: "0.75rem 0" }
3861
- },
3862
- effects: { base: [{
3863
- effectId: "border-bottom-grow",
3864
- options: {
3865
- height: 2,
3866
- colorToken: "text",
3867
- origin: "left"
4008
+ roles: {
4009
+ primary: {
4010
+ kind: "complete",
4011
+ appearance: {
4012
+ background: {
4013
+ type: "solid",
4014
+ colorToken: "primary"
4015
+ },
4016
+ borderRadius: "rounded-md",
4017
+ shadow: {
4018
+ elevation: "medium",
4019
+ softness: "soft",
4020
+ position: "bottom"
4021
+ },
4022
+ effects: {
4023
+ hover: [{
4024
+ effectId: "darken-background",
4025
+ options: { amount: 100 }
4026
+ }],
4027
+ active: [{
4028
+ effectId: "scale-down",
4029
+ options: { scale: "0.97" }
4030
+ }]
3868
4031
  }
3869
- }] }
4032
+ }
3870
4033
  },
3871
- {
3872
- id: "secondary",
3873
- name: "Secondary",
3874
- enabled: true,
3875
- priority: 2,
3876
- background: {
3877
- type: "surface",
3878
- role: "link"
3879
- },
3880
- borderRadius: "rounded-none",
3881
- sizes: {
3882
- sm: { padding: "0.25rem 0" },
3883
- md: { padding: "0.5rem 0" },
3884
- lg: { padding: "0.625rem 0" },
3885
- xl: { padding: "0.75rem 0" }
3886
- },
3887
- effects: { base: [{
3888
- effectId: "border-bottom-grow",
3889
- options: {
3890
- height: 1,
3891
- colorToken: "mutedText",
3892
- origin: "left"
3893
- }
3894
- }] }
4034
+ secondary: {
4035
+ kind: "complete",
4036
+ appearance: {
4037
+ background: {
4038
+ type: "solid",
4039
+ colorToken: "surface"
4040
+ },
4041
+ borderRadius: "rounded-md",
4042
+ border: { widthClass: "border" },
4043
+ effects: { hover: [{
4044
+ effectId: "background-on-hover",
4045
+ options: { colorToken: "background" }
4046
+ }] }
4047
+ }
3895
4048
  },
3896
- {
3897
- id: "outline",
3898
- name: "Outline",
3899
- enabled: true,
3900
- priority: 3,
3901
- background: {
3902
- type: "surface",
3903
- role: "link"
3904
- },
3905
- borderRadius: "rounded-none",
3906
- sizes: {
3907
- sm: { padding: "0.25rem 0" },
3908
- md: { padding: "0.5rem 0" },
3909
- lg: { padding: "0.625rem 0" },
3910
- xl: { padding: "0.75rem 0" }
3911
- },
3912
- effects: { base: [{
3913
- effectId: "border-bottom-grow",
3914
- options: {
3915
- height: 1,
3916
- colorToken: "accent",
3917
- origin: "left"
3918
- }
3919
- }] }
4049
+ outline: {
4050
+ kind: "complete",
4051
+ appearance: {
4052
+ background: {
4053
+ type: "surface",
4054
+ role: "link"
4055
+ },
4056
+ borderRadius: "rounded-md",
4057
+ border: { widthClass: "border" },
4058
+ effects: { hover: [{
4059
+ effectId: "background-on-hover",
4060
+ options: { colorToken: "surface" }
4061
+ }] }
4062
+ }
3920
4063
  },
3921
- {
3922
- id: "ghost",
3923
- name: "Ghost",
3924
- enabled: true,
3925
- priority: 3,
3926
- background: {
3927
- type: "surface",
3928
- role: "link"
3929
- },
3930
- borderRadius: "rounded-none",
3931
- sizes: {
3932
- sm: { padding: "0.25rem 0" },
3933
- md: { padding: "0.5rem 0" },
3934
- lg: { padding: "0.625rem 0" },
3935
- xl: { padding: "0.75rem 0" }
4064
+ ghost: {
4065
+ kind: "complete",
4066
+ appearance: {
4067
+ background: {
4068
+ type: "surface",
4069
+ role: "link"
4070
+ },
4071
+ borderRadius: "rounded-md",
4072
+ effects: { hover: [{
4073
+ effectId: "background-on-hover",
4074
+ options: { colorToken: "surface" }
4075
+ }] }
3936
4076
  }
4077
+ },
4078
+ accent: {
4079
+ kind: "derive",
4080
+ from: "primary",
4081
+ overrides: { background: {
4082
+ type: "solid",
4083
+ colorToken: "accent"
4084
+ } }
3937
4085
  }
3938
- ]
4086
+ }
3939
4087
  }
3940
4088
  });
3941
- //#endregion
3942
- //#region ../theme-core/src/buttons/personalities/flat-ink.ts
3943
- /**
3944
- * Flat Ink — a solid ink primary, a hairline ghost secondary, and a single
3945
- * amber accent climax, all completely flat (no drop shadow) with a modest
3946
- * radius. Reads as grounded, editorial and clinician-precise: the Fulcrum
3947
- * physiotherapy voice. The primary shifts to the secondary (moss) on hover and
3948
- * every variant lifts 2px; the amber accent is meant to be used sparingly as
3949
- * the page's one conversion climax.
3950
- */
3951
- const flatInk = defineButtonPersonality({
3952
- id: "flat-ink",
3953
- name: "Flat Ink",
3954
- description: "Flat solid-ink primary, hairline ghost secondary, and a single amber accent climax — modest radius, no shadow.",
4089
+ const editorialSizes = {
4090
+ sm: { padding: "0.25rem 0" },
4091
+ md: { padding: "0.5rem 0" },
4092
+ lg: { padding: "0.625rem 0" },
4093
+ xl: { padding: "0.75rem 0" }
4094
+ };
4095
+ const editorialLinkRecipe = defineStaticButtonStyleRecipe({
4096
+ id: "editorial-link",
4097
+ accessibilityLabel: "Flat typographic buttons with an underline treatment",
3955
4098
  tags: {
3956
- tone: "classic",
4099
+ tone: "minimal",
3957
4100
  energy: "calm",
3958
4101
  motion: "subtle",
3959
4102
  era: "editorial"
3960
4103
  },
3961
- buttonSystem: {
4104
+ system: {
3962
4105
  global: {
3963
- cornerStyle: "rounded",
4106
+ cornerStyle: "square",
3964
4107
  textTransform: "none",
3965
- fontWeight: 600,
4108
+ fontWeight: 500,
3966
4109
  borderWidth: 1,
3967
- typography: "body",
3968
- letterSpacing: "tight",
3969
- paddingPreset: "default",
3970
- hoverTransform: "lift",
4110
+ hoverTransform: "none",
3971
4111
  hoverColor: "none"
3972
4112
  },
3973
- sizes: {
3974
- sm: {
3975
- padding: "0.625rem 1.125rem",
3976
- fontSize: "text-sm"
4113
+ roles: {
4114
+ primary: {
4115
+ kind: "complete",
4116
+ appearance: {
4117
+ background: {
4118
+ type: "surface",
4119
+ role: "link"
4120
+ },
4121
+ borderRadius: "rounded-none",
4122
+ sizes: editorialSizes,
4123
+ effects: { base: [{
4124
+ effectId: "border-bottom-grow",
4125
+ options: {
4126
+ height: 2,
4127
+ colorToken: "text",
4128
+ origin: "left"
4129
+ }
4130
+ }] }
4131
+ }
3977
4132
  },
3978
- md: { padding: "0.8125rem 1.375rem" },
3979
- lg: {
3980
- padding: "0.9375rem 1.625rem",
3981
- fontSize: "text-lg"
4133
+ secondary: {
4134
+ kind: "complete",
4135
+ appearance: {
4136
+ background: {
4137
+ type: "surface",
4138
+ role: "link"
4139
+ },
4140
+ borderRadius: "rounded-none",
4141
+ sizes: editorialSizes,
4142
+ effects: { base: [{
4143
+ effectId: "border-bottom-grow",
4144
+ options: {
4145
+ height: 1,
4146
+ colorToken: "mutedText",
4147
+ origin: "left"
4148
+ }
4149
+ }] }
4150
+ }
3982
4151
  },
3983
- xl: {
3984
- padding: "1.0625rem 2rem",
3985
- fontSize: "text-xl"
3986
- }
3987
- },
3988
- variants: [
3989
- {
3990
- id: "primary",
3991
- name: "Primary",
3992
- enabled: true,
3993
- priority: 1,
3994
- background: {
3995
- type: "solid",
3996
- colorToken: "primary"
3997
- },
3998
- borderRadius: "rounded-lg",
3999
- affordance: { iconId: "ArrowRight" },
4000
- effects: { hover: [{
4001
- effectId: "lift",
4002
- options: { translateY: "-2px" }
4003
- }, {
4004
- effectId: "background-on-hover",
4005
- options: { colorToken: "secondary" }
4006
- }] }
4152
+ outline: {
4153
+ kind: "complete",
4154
+ appearance: {
4155
+ background: {
4156
+ type: "surface",
4157
+ role: "link"
4158
+ },
4159
+ borderRadius: "rounded-none",
4160
+ sizes: editorialSizes,
4161
+ effects: { base: [{
4162
+ effectId: "border-bottom-grow",
4163
+ options: {
4164
+ height: 1,
4165
+ colorToken: "accent",
4166
+ origin: "left"
4167
+ }
4168
+ }] }
4169
+ }
4007
4170
  },
4008
- {
4009
- id: "secondary",
4010
- name: "Secondary",
4011
- enabled: true,
4012
- priority: 2,
4013
- background: {
4014
- type: "surface",
4015
- role: "link"
4016
- },
4017
- borderRadius: "rounded-lg",
4018
- border: { widthClass: "border" },
4019
- effects: { hover: [{
4020
- effectId: "lift",
4021
- options: { translateY: "-2px" }
4022
- }, {
4023
- effectId: "background-on-hover",
4024
- options: { colorToken: "surfaceAlt" }
4025
- }] }
4171
+ ghost: {
4172
+ kind: "complete",
4173
+ appearance: {
4174
+ background: {
4175
+ type: "surface",
4176
+ role: "link"
4177
+ },
4178
+ borderRadius: "rounded-none",
4179
+ sizes: editorialSizes
4180
+ }
4026
4181
  },
4027
- {
4028
- id: "accent",
4029
- name: "Accent",
4030
- enabled: true,
4031
- priority: 3,
4032
- background: {
4033
- type: "solid",
4034
- colorToken: "accent"
4035
- },
4036
- borderRadius: "rounded-lg",
4037
- affordance: { iconId: "ArrowRight" },
4038
- effects: { hover: [{
4039
- effectId: "lift",
4040
- options: { translateY: "-2px" }
4041
- }] }
4182
+ accent: {
4183
+ kind: "derive",
4184
+ from: "primary",
4185
+ overrides: { effects: { base: [{
4186
+ effectId: "border-bottom-grow",
4187
+ options: {
4188
+ height: 2,
4189
+ colorToken: "accent",
4190
+ origin: "left"
4191
+ }
4192
+ }] } }
4042
4193
  }
4043
- ]
4194
+ }
4044
4195
  }
4045
4196
  });
4046
- //#endregion
4047
- //#region ../theme-core/src/buttons/personalities/ink-stamp.ts
4048
- /**
4049
- * Ink Stamp — solid earthy fills with a bordered, hand-stamped block-print
4050
- * feel. Reads as bold and handmade; suits expressive craft brands.
4051
- */
4052
- const inkStamp = defineButtonPersonality({
4053
- id: "ink-stamp",
4054
- name: "Ink Stamp",
4055
- description: "Hand-stamped block-print buttons with a slight lift on hover.",
4197
+ const pebbleRecipe = defineStaticButtonStyleRecipe({
4198
+ id: "pebble",
4199
+ accessibilityLabel: "Generously padded pill buttons",
4056
4200
  tags: {
4057
- tone: "bold",
4058
- energy: "vibrant",
4201
+ tone: "classic",
4202
+ energy: "calm",
4059
4203
  motion: "standard",
4060
4204
  era: "organic"
4061
4205
  },
4062
- buttonSystem: {
4206
+ system: {
4063
4207
  global: {
4064
- cornerStyle: "rounded",
4065
- textTransform: "uppercase",
4066
- fontWeight: 600,
4067
- borderWidth: 1,
4208
+ cornerStyle: "pill",
4209
+ textTransform: "none",
4210
+ fontWeight: 500,
4211
+ borderWidth: 2,
4068
4212
  hoverTransform: "none",
4069
- hoverColor: "none",
4070
- letterSpacing: "loose"
4213
+ hoverColor: "none"
4071
4214
  },
4072
4215
  sizes: {
4073
4216
  sm: {
4074
- padding: "0.5rem 1.25rem",
4075
- fontSize: "text-xs"
4076
- },
4077
- md: {
4078
- padding: "0.75rem 1.75rem",
4217
+ padding: "0.625rem 1.75rem",
4079
4218
  fontSize: "text-sm"
4080
4219
  },
4220
+ md: { padding: "0.875rem 2.25rem" },
4081
4221
  lg: {
4082
- padding: "0.875rem 2.25rem",
4083
- fontSize: "text-base"
4084
- },
4085
- xl: {
4086
4222
  padding: "1.125rem 2.75rem",
4087
4223
  fontSize: "text-lg"
4224
+ },
4225
+ xl: {
4226
+ padding: "1.5rem 3.5rem",
4227
+ fontSize: "text-xl"
4088
4228
  }
4089
4229
  },
4090
- variants: [
4091
- {
4092
- id: "primary",
4093
- name: "Primary",
4094
- enabled: true,
4095
- priority: 1,
4096
- background: {
4097
- type: "solid",
4098
- colorToken: "primary"
4099
- },
4100
- borderRadius: "rounded-md",
4101
- effects: {
4102
- hover: [{
4103
- effectId: "drop-shadow",
4104
- options: { intensity: "medium" }
4105
- }, {
4106
- effectId: "scale-up",
4107
- options: { scale: "1.02" }
4108
- }],
4109
- active: [{
4110
- effectId: "scale-down",
4111
- options: { scale: "0.98" }
4112
- }]
4230
+ roles: {
4231
+ primary: {
4232
+ kind: "complete",
4233
+ appearance: {
4234
+ background: {
4235
+ type: "solid",
4236
+ colorToken: "primary"
4237
+ },
4238
+ borderRadius: "rounded-full",
4239
+ effects: { hover: [{
4240
+ effectId: "darken-background",
4241
+ options: { amount: 100 }
4242
+ }] }
4113
4243
  }
4114
4244
  },
4115
- {
4116
- id: "secondary",
4117
- name: "Secondary",
4118
- enabled: true,
4119
- priority: 2,
4120
- background: {
4121
- type: "surface",
4122
- role: "link"
4123
- },
4124
- borderRadius: "rounded-md",
4125
- border: { widthClass: "border-2" },
4126
- effects: { hover: [{
4127
- effectId: "background-on-hover",
4128
- options: { colorToken: "surface" }
4129
- }] }
4130
- },
4131
- {
4132
- id: "outline",
4133
- name: "Outline",
4134
- enabled: true,
4135
- priority: 3,
4136
- background: {
4137
- type: "surface",
4138
- role: "link"
4139
- },
4140
- borderRadius: "rounded-md",
4141
- border: { widthClass: "border-2" },
4142
- effects: { hover: [{
4143
- effectId: "background-on-hover",
4144
- options: { colorToken: "surface" }
4145
- }] }
4146
- },
4147
- {
4148
- id: "ghost",
4149
- name: "Ghost",
4150
- enabled: true,
4151
- priority: 3,
4152
- background: {
4153
- type: "surface",
4154
- role: "link"
4155
- },
4156
- borderRadius: "rounded-none",
4157
- sizes: {
4158
- sm: {
4159
- padding: "0.375rem 0",
4160
- fontSize: "text-xs"
4245
+ secondary: {
4246
+ kind: "complete",
4247
+ appearance: {
4248
+ background: {
4249
+ type: "surface",
4250
+ role: "link"
4161
4251
  },
4162
- md: {
4163
- padding: "0.5rem 0",
4164
- fontSize: "text-sm"
4252
+ borderRadius: "rounded-full",
4253
+ border: { widthClass: "border-2" },
4254
+ effects: { hover: [{
4255
+ effectId: "background-on-hover",
4256
+ options: { colorToken: "accent" }
4257
+ }] }
4258
+ }
4259
+ },
4260
+ outline: {
4261
+ kind: "complete",
4262
+ appearance: {
4263
+ background: {
4264
+ type: "surface",
4265
+ role: "link"
4165
4266
  },
4166
- lg: {
4167
- padding: "0.625rem 0",
4168
- fontSize: "text-base"
4267
+ borderRadius: "rounded-full",
4268
+ border: { widthClass: "border" },
4269
+ effects: { hover: [{
4270
+ effectId: "background-on-hover",
4271
+ options: { colorToken: "surface" }
4272
+ }] }
4273
+ }
4274
+ },
4275
+ ghost: {
4276
+ kind: "complete",
4277
+ appearance: {
4278
+ background: {
4279
+ type: "surface",
4280
+ role: "link"
4169
4281
  },
4170
- xl: {
4171
- padding: "0.75rem 0",
4172
- fontSize: "text-lg"
4173
- }
4174
- },
4175
- effects: { base: [{
4176
- effectId: "border-bottom-grow",
4177
- options: {
4178
- height: 1,
4179
- colorToken: "accent",
4180
- origin: "left"
4282
+ borderRadius: "rounded-full",
4283
+ sizes: {
4284
+ sm: {
4285
+ padding: "0.375rem 0.875rem",
4286
+ fontSize: "text-sm"
4287
+ },
4288
+ md: { padding: "0.5rem 1rem" },
4289
+ lg: {
4290
+ padding: "0.625rem 1.25rem",
4291
+ fontSize: "text-lg"
4292
+ },
4293
+ xl: {
4294
+ padding: "0.75rem 1.5rem",
4295
+ fontSize: "text-xl"
4296
+ }
4181
4297
  }
4182
- }] }
4298
+ }
4299
+ },
4300
+ accent: {
4301
+ kind: "derive",
4302
+ from: "primary",
4303
+ overrides: { background: {
4304
+ type: "solid",
4305
+ colorToken: "accent"
4306
+ } }
4183
4307
  }
4184
- ]
4308
+ }
4185
4309
  }
4186
4310
  });
4187
- //#endregion
4188
- //#region ../theme-core/src/buttons/personalities/joy-stamp.ts
4189
- /**
4190
- * Joy Stamp — neo-brutalist pills with a hard, brand-coloured offset shadow
4191
- * that collapses as the button presses into it on hover. Authored for the
4192
- * Original Joy site style: a cream "stamp" shadow under the solid primary, and
4193
- * a brown shadow under the cream outline. Reads as bold, warm, and handmade.
4194
- *
4195
- * The coloured offset shadow relies on the per-variant `shadow.colorToken`
4196
- * extension; the press is the shared `press-down` effect, which matches its
4197
- * translate to each variant's own shadow offset.
4198
- */
4199
- const joyStamp = defineButtonPersonality({
4200
- id: "joy-stamp",
4201
- name: "Joy Stamp",
4202
- description: "Pill buttons with a hard, brand-coloured offset shadow that presses in on hover.",
4311
+ const brushedWashRecipe = defineStaticButtonStyleRecipe({
4312
+ id: "brushed-wash",
4313
+ accessibilityLabel: "Generously padded gradient buttons with soft shadows",
4203
4314
  tags: {
4204
- tone: "bold",
4315
+ tone: "classic",
4205
4316
  energy: "vibrant",
4206
- motion: "expressive",
4317
+ motion: "standard",
4207
4318
  era: "organic"
4208
4319
  },
4209
- buttonSystem: {
4320
+ system: {
4210
4321
  global: {
4211
- cornerStyle: "pill",
4212
- shadow: "high",
4322
+ cornerStyle: "rounded",
4323
+ shadow: "low",
4213
4324
  textTransform: "none",
4214
- typography: "heading",
4215
- fontWeight: 700,
4216
- fontSize: "text-lg",
4217
- borderWidth: 2,
4325
+ fontWeight: 500,
4326
+ borderWidth: 1,
4218
4327
  hoverTransform: "none",
4219
4328
  hoverColor: "none"
4220
4329
  },
4221
4330
  sizes: {
4222
4331
  sm: {
4223
- padding: "0.625rem 1.25rem",
4224
- fontSize: "text-base"
4225
- },
4226
- md: {
4227
- padding: "0.875rem 1.75rem",
4228
- fontSize: "text-lg"
4332
+ padding: "0.75rem 2rem",
4333
+ fontSize: "text-sm"
4229
4334
  },
4335
+ md: { padding: "1rem 2.5rem" },
4230
4336
  lg: {
4231
- padding: "1.125rem 2.25rem",
4232
- fontSize: "text-xl"
4337
+ padding: "1.25rem 3rem",
4338
+ fontSize: "text-lg"
4233
4339
  },
4234
4340
  xl: {
4235
- padding: "1.25rem 2.75rem",
4236
- fontSize: "text-2xl"
4341
+ padding: "1.625rem 3.75rem",
4342
+ fontSize: "text-xl"
4237
4343
  }
4238
4344
  },
4239
- variants: [{
4240
- id: "primary",
4241
- name: "Primary",
4242
- enabled: true,
4243
- priority: 1,
4244
- background: {
4245
- type: "solid",
4246
- colorToken: "primary"
4345
+ roles: {
4346
+ primary: {
4347
+ kind: "complete",
4348
+ appearance: {
4349
+ background: {
4350
+ type: "gradient",
4351
+ stops: ["primary", "accent"],
4352
+ direction: "to-r",
4353
+ foregroundToken: "primaryForeground"
4354
+ },
4355
+ borderRadius: "rounded-lg",
4356
+ shadow: {
4357
+ elevation: "low",
4358
+ softness: "soft",
4359
+ position: "bottom"
4360
+ }
4361
+ }
4247
4362
  },
4248
- borderRadius: "rounded-full",
4249
- shadow: {
4250
- elevation: "high",
4251
- softness: "hard",
4252
- position: "bottom-right",
4253
- colorToken: "text"
4363
+ secondary: {
4364
+ kind: "complete",
4365
+ appearance: {
4366
+ background: {
4367
+ type: "gradient",
4368
+ stops: ["secondary", "accent"],
4369
+ direction: "to-br",
4370
+ foregroundToken: "primaryForeground"
4371
+ },
4372
+ borderRadius: "rounded-lg",
4373
+ shadow: {
4374
+ elevation: "low",
4375
+ softness: "soft",
4376
+ position: "bottom"
4377
+ }
4378
+ }
4254
4379
  },
4255
- effects: { hover: [{ effectId: "press-down" }] }
4256
- }, {
4257
- id: "secondary",
4258
- name: "Secondary",
4259
- enabled: true,
4260
- priority: 2,
4261
- background: {
4262
- type: "surface",
4263
- role: "link"
4264
- },
4265
- borderRadius: "rounded-full",
4266
- border: { widthClass: "border-2" },
4267
- shadow: {
4268
- elevation: "high",
4269
- softness: "hard",
4270
- position: "bottom-right",
4271
- colorToken: "secondary"
4272
- },
4273
- effects: { hover: [{ effectId: "press-down" }] }
4274
- }]
4380
+ outline: {
4381
+ kind: "complete",
4382
+ appearance: {
4383
+ background: {
4384
+ type: "surface",
4385
+ role: "link"
4386
+ },
4387
+ borderRadius: "rounded-lg",
4388
+ border: { widthClass: "border" },
4389
+ effects: { hover: [{
4390
+ effectId: "background-on-hover",
4391
+ options: { colorToken: "surface" }
4392
+ }] }
4393
+ }
4394
+ },
4395
+ ghost: {
4396
+ kind: "complete",
4397
+ appearance: {
4398
+ background: {
4399
+ type: "surface",
4400
+ role: "link"
4401
+ },
4402
+ borderRadius: "rounded-lg",
4403
+ effects: { hover: [{
4404
+ effectId: "background-on-hover",
4405
+ options: { colorToken: "surface" }
4406
+ }] }
4407
+ }
4408
+ },
4409
+ accent: {
4410
+ kind: "derive",
4411
+ from: "primary",
4412
+ overrides: { background: {
4413
+ type: "solid",
4414
+ colorToken: "accent"
4415
+ } }
4416
+ }
4417
+ }
4275
4418
  }
4276
4419
  });
4277
- //#endregion
4278
- //#region ../theme-core/src/buttons/personalities/ornate-ritual.ts
4279
- /**
4280
- * Ornate Ritual — framed, ceremonial buttons with jewel-toned fills and
4281
- * deliberate spacing. Designed for music, ceremony, and soulful event sites.
4282
- */
4283
- const ornateRitual = defineButtonPersonality({
4284
- id: "ornate-ritual",
4285
- name: "Ornate Ritual",
4286
- description: "Ceremonial framed buttons with jewel-toned fills and quiet color-change hover states.",
4420
+ const inkStampRecipe = defineStaticButtonStyleRecipe({
4421
+ id: "ink-stamp",
4422
+ accessibilityLabel: "Uppercase block-print buttons with a playful hover",
4287
4423
  tags: {
4288
- tone: "classic",
4424
+ tone: "bold",
4289
4425
  energy: "vibrant",
4290
- motion: "subtle",
4426
+ motion: "standard",
4291
4427
  era: "organic"
4292
4428
  },
4293
- buttonSystem: {
4429
+ system: {
4294
4430
  global: {
4295
4431
  cornerStyle: "rounded",
4296
4432
  textTransform: "uppercase",
@@ -4302,655 +4438,656 @@ const ornateRitual = defineButtonPersonality({
4302
4438
  },
4303
4439
  sizes: {
4304
4440
  sm: {
4305
- padding: "0.5625rem 1.25rem",
4441
+ padding: "0.5rem 1.25rem",
4306
4442
  fontSize: "text-xs"
4307
4443
  },
4308
4444
  md: {
4309
4445
  padding: "0.75rem 1.75rem",
4310
- fontSize: "text-xs"
4446
+ fontSize: "text-sm"
4311
4447
  },
4312
4448
  lg: {
4313
4449
  padding: "0.875rem 2.25rem",
4314
- fontSize: "text-sm"
4450
+ fontSize: "text-base"
4315
4451
  },
4316
4452
  xl: {
4317
- padding: "1rem 2.75rem",
4318
- fontSize: "text-base"
4453
+ padding: "1.125rem 2.75rem",
4454
+ fontSize: "text-lg"
4319
4455
  }
4320
4456
  },
4321
- variants: [
4322
- {
4323
- id: "primary",
4324
- name: "Primary",
4325
- enabled: true,
4326
- priority: 1,
4327
- background: {
4328
- type: "solid",
4329
- colorToken: "primary"
4330
- },
4331
- borderRadius: "rounded-md",
4332
- border: { widthClass: "border" },
4333
- effects: {
4334
- hover: [{
4335
- effectId: "background-on-hover",
4336
- options: { colorToken: "primary-100" }
4337
- }],
4338
- active: [{
4339
- effectId: "scale-down",
4340
- options: { scale: "0.98" }
4341
- }]
4457
+ roles: {
4458
+ primary: {
4459
+ kind: "complete",
4460
+ appearance: {
4461
+ background: {
4462
+ type: "solid",
4463
+ colorToken: "primary"
4464
+ },
4465
+ borderRadius: "rounded-md",
4466
+ effects: {
4467
+ hover: [{
4468
+ effectId: "drop-shadow",
4469
+ options: { intensity: "medium" }
4470
+ }, {
4471
+ effectId: "scale-up",
4472
+ options: { scale: "1.02" }
4473
+ }],
4474
+ active: [{
4475
+ effectId: "scale-down",
4476
+ options: { scale: "0.98" }
4477
+ }]
4478
+ }
4342
4479
  }
4343
4480
  },
4344
- {
4345
- id: "secondary",
4346
- name: "Secondary",
4347
- enabled: true,
4348
- priority: 2,
4349
- background: {
4350
- type: "solid",
4351
- colorToken: "secondary"
4352
- },
4353
- borderRadius: "rounded-md",
4354
- border: { widthClass: "border" },
4355
- effects: { hover: [{
4356
- effectId: "background-on-hover",
4357
- options: { colorToken: "surface" }
4358
- }] }
4359
- },
4360
- {
4361
- id: "outline",
4362
- name: "Outline",
4363
- enabled: true,
4364
- priority: 3,
4365
- background: {
4366
- type: "surface",
4367
- role: "link"
4368
- },
4369
- borderRadius: "rounded-md",
4370
- border: { widthClass: "border" },
4371
- effects: { hover: [{
4372
- effectId: "background-on-hover",
4373
- options: { colorToken: "muted" }
4374
- }] }
4481
+ secondary: {
4482
+ kind: "complete",
4483
+ appearance: {
4484
+ background: {
4485
+ type: "surface",
4486
+ role: "link"
4487
+ },
4488
+ borderRadius: "rounded-md",
4489
+ border: { widthClass: "border-2" },
4490
+ effects: { hover: [{
4491
+ effectId: "background-on-hover",
4492
+ options: { colorToken: "surface" }
4493
+ }] }
4494
+ }
4375
4495
  },
4376
- {
4377
- id: "ghost",
4378
- name: "Ghost",
4379
- enabled: true,
4380
- priority: 3,
4381
- background: {
4382
- type: "surface",
4383
- role: "link"
4384
- },
4385
- borderRadius: "rounded-none",
4386
- sizes: {
4387
- sm: {
4388
- padding: "0.375rem 0",
4389
- fontSize: "text-xs"
4496
+ outline: {
4497
+ kind: "complete",
4498
+ appearance: {
4499
+ background: {
4500
+ type: "surface",
4501
+ role: "link"
4390
4502
  },
4391
- md: {
4392
- padding: "0.5rem 0",
4393
- fontSize: "text-sm"
4503
+ borderRadius: "rounded-md",
4504
+ border: { widthClass: "border-2" },
4505
+ effects: { hover: [{
4506
+ effectId: "background-on-hover",
4507
+ options: { colorToken: "surface" }
4508
+ }] }
4509
+ }
4510
+ },
4511
+ ghost: {
4512
+ kind: "complete",
4513
+ appearance: {
4514
+ background: {
4515
+ type: "surface",
4516
+ role: "link"
4394
4517
  },
4395
- lg: {
4396
- padding: "0.625rem 0",
4397
- fontSize: "text-base"
4518
+ borderRadius: "rounded-none",
4519
+ sizes: {
4520
+ sm: {
4521
+ padding: "0.375rem 0",
4522
+ fontSize: "text-xs"
4523
+ },
4524
+ md: {
4525
+ padding: "0.5rem 0",
4526
+ fontSize: "text-sm"
4527
+ },
4528
+ lg: {
4529
+ padding: "0.625rem 0",
4530
+ fontSize: "text-base"
4531
+ },
4532
+ xl: {
4533
+ padding: "0.75rem 0",
4534
+ fontSize: "text-lg"
4535
+ }
4398
4536
  },
4399
- xl: {
4400
- padding: "0.75rem 0",
4401
- fontSize: "text-lg"
4402
- }
4403
- },
4404
- effects: { base: [{
4405
- effectId: "border-bottom-grow",
4406
- options: {
4407
- height: 1,
4408
- colorToken: "accent",
4409
- origin: "left"
4410
- }
4411
- }] }
4537
+ effects: { base: [{
4538
+ effectId: "border-bottom-grow",
4539
+ options: {
4540
+ height: 1,
4541
+ colorToken: "accent",
4542
+ origin: "left"
4543
+ }
4544
+ }] }
4545
+ }
4546
+ },
4547
+ accent: {
4548
+ kind: "derive",
4549
+ from: "primary",
4550
+ overrides: { background: {
4551
+ type: "solid",
4552
+ colorToken: "accent"
4553
+ } }
4412
4554
  }
4413
- ]
4555
+ }
4414
4556
  }
4415
4557
  });
4416
- //#endregion
4417
- //#region ../theme-core/src/buttons/personalities/pebble.ts
4418
- /**
4419
- * Pebble — large pill primaries with generous padding. Reads as spa-luxurious
4420
- * and natural; pairs well with wellness/yoga/dance brands.
4421
- */
4422
- const pebble = defineButtonPersonality({
4423
- id: "pebble",
4424
- name: "Pebble",
4425
- description: "Generous pill buttons with a quiet colour-softening hover.",
4558
+ const flatInkRecipe = defineStaticButtonStyleRecipe({
4559
+ id: "flat-ink",
4560
+ accessibilityLabel: "Flat rounded buttons with arrow affordances",
4426
4561
  tags: {
4427
4562
  tone: "classic",
4428
4563
  energy: "calm",
4429
- motion: "standard",
4430
- era: "organic"
4564
+ motion: "subtle",
4565
+ era: "editorial"
4431
4566
  },
4432
- buttonSystem: {
4567
+ system: {
4433
4568
  global: {
4434
- cornerStyle: "pill",
4569
+ cornerStyle: "rounded",
4435
4570
  textTransform: "none",
4436
- fontWeight: 500,
4437
- borderWidth: 2,
4438
- hoverTransform: "none",
4571
+ fontWeight: 600,
4572
+ borderWidth: 1,
4573
+ typography: "body",
4574
+ letterSpacing: "tight",
4575
+ paddingPreset: "default",
4576
+ hoverTransform: "lift",
4439
4577
  hoverColor: "none"
4440
4578
  },
4441
4579
  sizes: {
4442
4580
  sm: {
4443
- padding: "0.625rem 1.75rem",
4581
+ padding: "0.625rem 1.125rem",
4444
4582
  fontSize: "text-sm"
4445
4583
  },
4446
- md: { padding: "0.875rem 2.25rem" },
4584
+ md: { padding: "0.8125rem 1.375rem" },
4447
4585
  lg: {
4448
- padding: "1.125rem 2.75rem",
4586
+ padding: "0.9375rem 1.625rem",
4449
4587
  fontSize: "text-lg"
4450
4588
  },
4451
4589
  xl: {
4452
- padding: "1.5rem 3.5rem",
4590
+ padding: "1.0625rem 2rem",
4453
4591
  fontSize: "text-xl"
4454
4592
  }
4455
4593
  },
4456
- variants: [
4457
- {
4458
- id: "primary",
4459
- name: "Primary",
4460
- enabled: true,
4461
- priority: 1,
4462
- background: {
4463
- type: "solid",
4464
- colorToken: "primary"
4465
- },
4466
- borderRadius: "rounded-full",
4467
- effects: { hover: [{
4468
- effectId: "darken-background",
4469
- options: { amount: 100 }
4470
- }] }
4594
+ roles: {
4595
+ primary: {
4596
+ kind: "complete",
4597
+ appearance: {
4598
+ background: {
4599
+ type: "solid",
4600
+ colorToken: "primary"
4601
+ },
4602
+ borderRadius: "rounded-lg",
4603
+ affordance: { iconId: "ArrowRight" },
4604
+ effects: { hover: [{
4605
+ effectId: "lift",
4606
+ options: { translateY: "-2px" }
4607
+ }, {
4608
+ effectId: "background-on-hover",
4609
+ options: { colorToken: "secondary" }
4610
+ }] }
4611
+ }
4471
4612
  },
4472
- {
4473
- id: "secondary",
4474
- name: "Secondary",
4475
- enabled: true,
4476
- priority: 2,
4477
- background: {
4478
- type: "surface",
4479
- role: "link"
4480
- },
4481
- borderRadius: "rounded-full",
4482
- border: { widthClass: "border-2" },
4483
- effects: { hover: [{
4484
- effectId: "background-on-hover",
4485
- options: { colorToken: "accent" }
4486
- }] }
4613
+ secondary: {
4614
+ kind: "complete",
4615
+ appearance: {
4616
+ background: {
4617
+ type: "surface",
4618
+ role: "link"
4619
+ },
4620
+ borderRadius: "rounded-lg",
4621
+ border: { widthClass: "border" },
4622
+ effects: { hover: [{
4623
+ effectId: "lift",
4624
+ options: { translateY: "-2px" }
4625
+ }, {
4626
+ effectId: "background-on-hover",
4627
+ options: { colorToken: "surfaceAlt" }
4628
+ }] }
4629
+ }
4487
4630
  },
4488
- {
4489
- id: "outline",
4490
- name: "Outline",
4491
- enabled: true,
4492
- priority: 3,
4493
- background: {
4494
- type: "surface",
4495
- role: "link"
4496
- },
4497
- borderRadius: "rounded-full",
4498
- border: { widthClass: "border" },
4499
- effects: { hover: [{
4500
- effectId: "background-on-hover",
4501
- options: { colorToken: "surface" }
4502
- }] }
4631
+ outline: {
4632
+ kind: "complete",
4633
+ appearance: {
4634
+ background: {
4635
+ type: "surface",
4636
+ role: "link"
4637
+ },
4638
+ borderRadius: "rounded-lg",
4639
+ border: { widthClass: "border" },
4640
+ effects: { hover: [{
4641
+ effectId: "lift",
4642
+ options: { translateY: "-2px" }
4643
+ }, {
4644
+ effectId: "background-on-hover",
4645
+ options: { colorToken: "surfaceAlt" }
4646
+ }] }
4647
+ }
4503
4648
  },
4504
- {
4505
- id: "ghost",
4506
- name: "Ghost",
4507
- enabled: true,
4508
- priority: 3,
4509
- background: {
4510
- type: "surface",
4511
- role: "link"
4512
- },
4513
- borderRadius: "rounded-full",
4514
- sizes: {
4515
- sm: {
4516
- padding: "0.375rem 0.875rem",
4517
- fontSize: "text-sm"
4649
+ ghost: {
4650
+ kind: "complete",
4651
+ appearance: {
4652
+ background: {
4653
+ type: "surface",
4654
+ role: "link"
4518
4655
  },
4519
- md: { padding: "0.5rem 1rem" },
4520
- lg: {
4521
- padding: "0.625rem 1.25rem",
4522
- fontSize: "text-lg"
4656
+ borderRadius: "rounded-lg",
4657
+ effects: { hover: [{
4658
+ effectId: "lift",
4659
+ options: { translateY: "-2px" }
4660
+ }] }
4661
+ }
4662
+ },
4663
+ accent: {
4664
+ kind: "complete",
4665
+ appearance: {
4666
+ background: {
4667
+ type: "solid",
4668
+ colorToken: "accent"
4523
4669
  },
4524
- xl: {
4525
- padding: "0.75rem 1.5rem",
4526
- fontSize: "text-xl"
4527
- }
4670
+ borderRadius: "rounded-lg",
4671
+ affordance: { iconId: "ArrowRight" },
4672
+ effects: { hover: [{
4673
+ effectId: "lift",
4674
+ options: { translateY: "-2px" }
4675
+ }] }
4528
4676
  }
4529
4677
  }
4530
- ]
4678
+ }
4531
4679
  }
4532
4680
  });
4533
- //#endregion
4534
- //#region ../theme-core/src/buttons/personalities/quiet-arrow.ts
4535
- /**
4536
- * Quiet Arrow — wide, flat editorial buttons for grounded service businesses.
4537
- * Primary and secondary keep stable semantic colours; surrounding surfaces are
4538
- * responsible for contrast rather than reversing the button roles.
4539
- */
4540
- const quietArrow = defineButtonPersonality({
4541
- id: "quiet-arrow",
4542
- name: "Quiet Arrow",
4543
- description: "Wide, flat arrow buttons with a solid primary and a primary-colour outlined secondary.",
4681
+ const showtimePillRecipe = defineStaticButtonStyleRecipe({
4682
+ id: "showtime-pill",
4683
+ accessibilityLabel: "Bold uppercase pill buttons with playful movement",
4544
4684
  tags: {
4545
- tone: "classic",
4546
- energy: "calm",
4547
- motion: "subtle",
4548
- era: "editorial"
4685
+ tone: "bold",
4686
+ energy: "vibrant",
4687
+ motion: "expressive",
4688
+ era: "modern"
4549
4689
  },
4550
- buttonSystem: {
4690
+ system: {
4551
4691
  global: {
4552
- cornerStyle: "rounded",
4692
+ cornerStyle: "pill",
4693
+ shadow: "low",
4553
4694
  textTransform: "uppercase",
4554
- fontWeight: 500,
4555
- borderWidth: 1,
4695
+ fontWeight: 700,
4696
+ borderWidth: 2,
4697
+ hoverTransform: "lift",
4698
+ hoverColor: "darken",
4556
4699
  typography: "body",
4557
- fontSize: "text-sm",
4558
- letterSpacing: "loose",
4559
- hoverTransform: "none",
4560
- hoverColor: "none"
4700
+ paddingPreset: "spacious",
4701
+ italic: false
4561
4702
  },
4562
4703
  sizes: {
4563
4704
  sm: {
4564
4705
  padding: "0.625rem 1.25rem",
4565
- fontSize: "text-xs"
4706
+ fontSize: "0.875rem"
4566
4707
  },
4567
4708
  md: {
4568
- padding: "0.8125rem 1.75rem",
4569
- fontSize: "text-sm"
4709
+ padding: "0.875rem 1.75rem",
4710
+ fontSize: "1rem"
4570
4711
  },
4571
4712
  lg: {
4572
- padding: "0.9375rem 2.125rem",
4573
- fontSize: "text-sm"
4713
+ padding: "1.125rem 2.25rem",
4714
+ fontSize: "1.125rem"
4574
4715
  },
4575
4716
  xl: {
4576
- padding: "1.0625rem 2.5rem",
4577
- fontSize: "text-base"
4717
+ padding: "1.125rem 2.25rem",
4718
+ fontSize: "1.125rem"
4578
4719
  }
4579
4720
  },
4580
- variants: [
4581
- {
4582
- id: "primary",
4583
- name: "Primary",
4584
- enabled: true,
4585
- priority: 1,
4586
- background: {
4587
- type: "solid",
4588
- colorToken: "primary"
4589
- },
4590
- borderRadius: "rounded-xl",
4591
- affordance: { iconId: "ArrowRight" },
4592
- effects: { hover: [{
4593
- effectId: "darken-background",
4594
- options: { amount: 100 }
4595
- }] }
4721
+ roles: {
4722
+ primary: {
4723
+ kind: "complete",
4724
+ appearance: {
4725
+ background: {
4726
+ type: "solid",
4727
+ colorToken: "primary"
4728
+ },
4729
+ borderRadius: "rounded-full",
4730
+ effects: { hover: [{ effectId: "pop" }] }
4731
+ }
4596
4732
  },
4597
- {
4598
- id: "secondary",
4599
- name: "Secondary",
4600
- enabled: true,
4601
- priority: 2,
4602
- background: {
4603
- type: "surface",
4604
- role: "link"
4605
- },
4606
- borderRadius: "rounded-xl",
4607
- border: { widthClass: "border" },
4608
- affordance: { iconId: "ArrowRight" },
4609
- effects: { hover: [{
4610
- effectId: "background-on-hover",
4611
- options: { colorToken: "surfaceAlt" }
4612
- }] }
4733
+ secondary: {
4734
+ kind: "complete",
4735
+ appearance: {
4736
+ background: {
4737
+ type: "surface",
4738
+ role: "link"
4739
+ },
4740
+ borderRadius: "rounded-full",
4741
+ border: { widthClass: "border-2" },
4742
+ effects: { hover: [{ effectId: "pop" }] }
4743
+ }
4613
4744
  },
4614
- {
4615
- id: "outline",
4616
- name: "Outline",
4617
- enabled: true,
4618
- priority: 3,
4619
- background: {
4620
- type: "surface",
4621
- role: "link"
4622
- },
4623
- borderRadius: "rounded-xl",
4624
- border: { widthClass: "border" }
4745
+ outline: {
4746
+ kind: "complete",
4747
+ appearance: {
4748
+ background: {
4749
+ type: "surface",
4750
+ role: "link"
4751
+ },
4752
+ borderRadius: "rounded-full",
4753
+ border: { widthClass: "border-2" },
4754
+ effects: { hover: [{
4755
+ effectId: "background-on-hover",
4756
+ options: { colorToken: "background" }
4757
+ }] }
4758
+ }
4625
4759
  },
4626
- {
4627
- id: "ghost",
4628
- name: "Ghost",
4629
- enabled: true,
4630
- priority: 3,
4631
- background: {
4632
- type: "surface",
4633
- role: "link"
4634
- },
4635
- borderRadius: "rounded-xl"
4760
+ ghost: {
4761
+ kind: "complete",
4762
+ appearance: {
4763
+ background: {
4764
+ type: "surface",
4765
+ role: "link"
4766
+ },
4767
+ borderRadius: "rounded-full",
4768
+ effects: { hover: [{
4769
+ effectId: "background-on-hover",
4770
+ options: { colorToken: "surface" }
4771
+ }] }
4772
+ }
4773
+ },
4774
+ accent: {
4775
+ kind: "complete",
4776
+ appearance: {
4777
+ background: {
4778
+ type: "solid",
4779
+ colorToken: "secondary"
4780
+ },
4781
+ borderRadius: "rounded-full",
4782
+ effects: { hover: [{ effectId: "pop" }] }
4783
+ }
4636
4784
  }
4637
- ]
4785
+ }
4638
4786
  }
4639
4787
  });
4640
- //#endregion
4641
- //#region ../theme-core/src/buttons/personalities/showtime-pill.ts
4642
- /**
4643
- * Showtime Pill — bold, spacious, fully rounded buttons with playful pop
4644
- * motion. Suits energetic schools, performers, festivals, and community brands
4645
- * that need calls to action to feel loud without becoming visually chaotic.
4646
- */
4647
- const showtimePill = defineButtonPersonality({
4648
- id: "showtime-pill",
4649
- name: "Showtime Pill",
4650
- description: "Bold pill buttons with uppercase labels, generous padding, and a playful pop.",
4788
+ const joyStampRecipe = defineStaticButtonStyleRecipe({
4789
+ id: "joy-stamp",
4790
+ accessibilityLabel: "Bold pill buttons with a hard offset shadow",
4651
4791
  tags: {
4652
4792
  tone: "bold",
4653
4793
  energy: "vibrant",
4654
4794
  motion: "expressive",
4655
- era: "modern"
4795
+ era: "organic"
4656
4796
  },
4657
- buttonSystem: {
4797
+ system: {
4658
4798
  global: {
4659
4799
  cornerStyle: "pill",
4660
- shadow: "low",
4661
- textTransform: "uppercase",
4800
+ shadow: "high",
4801
+ textTransform: "none",
4802
+ typography: "heading",
4662
4803
  fontWeight: 700,
4804
+ fontSize: "text-lg",
4663
4805
  borderWidth: 2,
4664
- hoverTransform: "lift",
4665
- hoverColor: "darken",
4666
- typography: "body",
4667
- paddingPreset: "spacious",
4668
- italic: false
4806
+ hoverTransform: "none",
4807
+ hoverColor: "none"
4669
4808
  },
4670
4809
  sizes: {
4671
4810
  sm: {
4672
4811
  padding: "0.625rem 1.25rem",
4673
- fontSize: "0.875rem"
4812
+ fontSize: "text-base"
4674
4813
  },
4675
4814
  md: {
4676
4815
  padding: "0.875rem 1.75rem",
4677
- fontSize: "1rem"
4816
+ fontSize: "text-lg"
4678
4817
  },
4679
4818
  lg: {
4680
4819
  padding: "1.125rem 2.25rem",
4681
- fontSize: "1.125rem"
4820
+ fontSize: "text-xl"
4682
4821
  },
4683
4822
  xl: {
4684
- padding: "1.125rem 2.25rem",
4685
- fontSize: "1.125rem"
4823
+ padding: "1.25rem 2.75rem",
4824
+ fontSize: "text-2xl"
4686
4825
  }
4687
4826
  },
4688
- variants: [
4689
- {
4690
- id: "primary",
4691
- name: "Primary",
4692
- enabled: true,
4693
- priority: 1,
4694
- background: {
4695
- type: "solid",
4696
- colorToken: "primary"
4697
- },
4698
- borderRadius: "rounded-full",
4699
- effects: { hover: [{ effectId: "pop" }] }
4827
+ roles: {
4828
+ primary: {
4829
+ kind: "complete",
4830
+ appearance: {
4831
+ background: {
4832
+ type: "solid",
4833
+ colorToken: "primary"
4834
+ },
4835
+ borderRadius: "rounded-full",
4836
+ shadow: {
4837
+ elevation: "high",
4838
+ softness: "hard",
4839
+ position: "bottom-right",
4840
+ colorToken: "text"
4841
+ },
4842
+ effects: { hover: [{ effectId: "press-down" }] }
4843
+ }
4700
4844
  },
4701
- {
4702
- id: "secondary",
4703
- name: "Secondary",
4704
- enabled: true,
4705
- priority: 2,
4706
- background: {
4707
- type: "surface",
4708
- role: "link"
4709
- },
4710
- borderRadius: "rounded-full",
4711
- border: { widthClass: "border-2" },
4712
- effects: { hover: [{ effectId: "pop" }] }
4845
+ secondary: {
4846
+ kind: "complete",
4847
+ appearance: {
4848
+ background: {
4849
+ type: "surface",
4850
+ role: "link"
4851
+ },
4852
+ borderRadius: "rounded-full",
4853
+ border: { widthClass: "border-2" },
4854
+ shadow: {
4855
+ elevation: "high",
4856
+ softness: "hard",
4857
+ position: "bottom-right",
4858
+ colorToken: "secondary"
4859
+ },
4860
+ effects: { hover: [{ effectId: "press-down" }] }
4861
+ }
4713
4862
  },
4714
- {
4715
- id: "hero",
4716
- name: "Hero",
4717
- enabled: true,
4718
- priority: 1,
4719
- background: {
4720
- type: "solid",
4721
- colorToken: "secondary"
4722
- },
4723
- borderRadius: "rounded-full",
4724
- effects: { hover: [{ effectId: "pop" }] }
4863
+ outline: {
4864
+ kind: "derive",
4865
+ from: "secondary"
4725
4866
  },
4726
- {
4727
- id: "header",
4728
- name: "Header",
4729
- enabled: true,
4730
- priority: 2,
4731
- background: {
4867
+ ghost: {
4868
+ kind: "complete",
4869
+ appearance: {
4870
+ background: {
4871
+ type: "surface",
4872
+ role: "link"
4873
+ },
4874
+ borderRadius: "rounded-full",
4875
+ effects: { hover: [{ effectId: "press-down" }] }
4876
+ }
4877
+ },
4878
+ accent: {
4879
+ kind: "derive",
4880
+ from: "primary",
4881
+ overrides: { background: {
4732
4882
  type: "solid",
4733
- colorToken: "background"
4734
- },
4735
- borderRadius: "rounded-full",
4736
- border: { widthClass: "border-2" },
4737
- effects: { hover: [{
4738
- effectId: "background-on-hover",
4739
- options: { colorToken: "surface" }
4740
- }] }
4883
+ colorToken: "accent"
4884
+ } }
4885
+ }
4886
+ }
4887
+ }
4888
+ });
4889
+ const ornateRitualRecipe = defineStaticButtonStyleRecipe({
4890
+ id: "ornate-ritual",
4891
+ accessibilityLabel: "Uppercase framed buttons with restrained movement",
4892
+ tags: {
4893
+ tone: "classic",
4894
+ energy: "vibrant",
4895
+ motion: "subtle",
4896
+ era: "organic"
4897
+ },
4898
+ system: {
4899
+ global: {
4900
+ cornerStyle: "rounded",
4901
+ textTransform: "uppercase",
4902
+ fontWeight: 600,
4903
+ borderWidth: 1,
4904
+ hoverTransform: "none",
4905
+ hoverColor: "none",
4906
+ letterSpacing: "loose"
4907
+ },
4908
+ sizes: {
4909
+ sm: {
4910
+ padding: "0.5625rem 1.25rem",
4911
+ fontSize: "text-xs"
4741
4912
  },
4742
- {
4743
- id: "outline",
4744
- name: "Outline",
4745
- enabled: true,
4746
- priority: 3,
4747
- background: {
4748
- type: "surface",
4749
- role: "link"
4750
- },
4751
- borderRadius: "rounded-full",
4752
- border: { widthClass: "border-2" },
4753
- effects: { hover: [{
4754
- effectId: "background-on-hover",
4755
- options: { colorToken: "background" }
4756
- }] }
4913
+ md: {
4914
+ padding: "0.75rem 1.75rem",
4915
+ fontSize: "text-xs"
4916
+ },
4917
+ lg: {
4918
+ padding: "0.875rem 2.25rem",
4919
+ fontSize: "text-sm"
4757
4920
  },
4758
- {
4759
- id: "ghost",
4760
- name: "Ghost",
4761
- enabled: true,
4762
- priority: 3,
4763
- background: {
4764
- type: "surface",
4765
- role: "link"
4766
- },
4767
- borderRadius: "rounded-full",
4768
- effects: { hover: [{
4769
- effectId: "background-on-hover",
4770
- options: { colorToken: "surface" }
4771
- }] }
4921
+ xl: {
4922
+ padding: "1rem 2.75rem",
4923
+ fontSize: "text-base"
4772
4924
  }
4773
- ]
4774
- }
4775
- });
4776
- //#endregion
4777
- //#region ../theme-core/src/buttons/personalities/soft-pill.ts
4778
- /**
4779
- * Soft Pill — rounded-full pill buttons with a hover lift. The default for
4780
- * Calm Studio and Modern Wellness; reads as quietly modern and welcoming.
4781
- */
4782
- const softPill = defineButtonPersonality({
4783
- id: "soft-pill",
4784
- name: "Soft Pill",
4785
- description: "Rounded pills with a gentle lift on hover. Quietly modern.",
4786
- tags: {
4787
- tone: "classic",
4788
- energy: "calm",
4789
- motion: "subtle",
4790
- era: "organic"
4791
- },
4792
- buttonSystem: {
4793
- global: {
4794
- cornerStyle: "pill",
4795
- shadow: "low",
4796
- textTransform: "none",
4797
- fontWeight: 500,
4798
- borderWidth: 2,
4799
- hoverTransform: "lift",
4800
- hoverColor: "none"
4801
4925
  },
4802
- variants: [
4803
- {
4804
- id: "primary",
4805
- name: "Primary",
4806
- enabled: true,
4807
- priority: 1,
4808
- background: {
4809
- type: "solid",
4810
- colorToken: "primary"
4811
- },
4812
- borderRadius: "rounded-full",
4813
- shadow: {
4814
- elevation: "low",
4815
- softness: "soft",
4816
- position: "bottom"
4817
- },
4818
- effects: {
4819
- hover: [{
4820
- effectId: "lift",
4821
- options: { translateY: "-1px" }
4822
- }],
4823
- active: [{
4824
- effectId: "scale-down",
4825
- options: { scale: "0.98" }
4826
- }]
4926
+ roles: {
4927
+ primary: {
4928
+ kind: "complete",
4929
+ appearance: {
4930
+ background: {
4931
+ type: "solid",
4932
+ colorToken: "primary"
4933
+ },
4934
+ borderRadius: "rounded-md",
4935
+ border: { widthClass: "border" },
4936
+ effects: {
4937
+ hover: [{
4938
+ effectId: "background-on-hover",
4939
+ options: { colorToken: "primary-100" }
4940
+ }],
4941
+ active: [{
4942
+ effectId: "scale-down",
4943
+ options: { scale: "0.98" }
4944
+ }]
4945
+ }
4827
4946
  }
4828
4947
  },
4829
- {
4830
- id: "secondary",
4831
- name: "Secondary",
4832
- enabled: true,
4833
- priority: 2,
4834
- background: {
4835
- type: "surface",
4836
- role: "link"
4837
- },
4838
- borderRadius: "rounded-full",
4839
- border: { widthClass: "border-2" },
4840
- effects: { hover: [{
4841
- effectId: "background-on-hover",
4842
- options: { colorToken: "surface" }
4843
- }] }
4948
+ secondary: {
4949
+ kind: "complete",
4950
+ appearance: {
4951
+ background: {
4952
+ type: "solid",
4953
+ colorToken: "secondary"
4954
+ },
4955
+ borderRadius: "rounded-md",
4956
+ border: { widthClass: "border" },
4957
+ effects: { hover: [{
4958
+ effectId: "background-on-hover",
4959
+ options: { colorToken: "surface" }
4960
+ }] }
4961
+ }
4844
4962
  },
4845
- {
4846
- id: "outline",
4847
- name: "Outline",
4848
- enabled: true,
4849
- priority: 3,
4850
- background: {
4851
- type: "surface",
4852
- role: "link"
4853
- },
4854
- borderRadius: "rounded-full",
4855
- border: { widthClass: "border" },
4856
- effects: { hover: [{
4857
- effectId: "background-on-hover",
4858
- options: { colorToken: "surface" }
4859
- }] }
4963
+ outline: {
4964
+ kind: "complete",
4965
+ appearance: {
4966
+ background: {
4967
+ type: "surface",
4968
+ role: "link"
4969
+ },
4970
+ borderRadius: "rounded-md",
4971
+ border: { widthClass: "border" },
4972
+ effects: { hover: [{
4973
+ effectId: "background-on-hover",
4974
+ options: { colorToken: "muted" }
4975
+ }] }
4976
+ }
4860
4977
  },
4861
- {
4862
- id: "ghost",
4863
- name: "Ghost",
4864
- enabled: true,
4865
- priority: 3,
4866
- background: {
4867
- type: "surface",
4868
- role: "link"
4869
- },
4870
- borderRadius: "rounded-full",
4871
- effects: { hover: [{
4872
- effectId: "background-on-hover",
4873
- options: { colorToken: "surface" }
4874
- }] }
4978
+ ghost: {
4979
+ kind: "complete",
4980
+ appearance: {
4981
+ background: {
4982
+ type: "surface",
4983
+ role: "link"
4984
+ },
4985
+ borderRadius: "rounded-none",
4986
+ sizes: {
4987
+ sm: {
4988
+ padding: "0.375rem 0",
4989
+ fontSize: "text-xs"
4990
+ },
4991
+ md: {
4992
+ padding: "0.5rem 0",
4993
+ fontSize: "text-sm"
4994
+ },
4995
+ lg: {
4996
+ padding: "0.625rem 0",
4997
+ fontSize: "text-base"
4998
+ },
4999
+ xl: {
5000
+ padding: "0.75rem 0",
5001
+ fontSize: "text-lg"
5002
+ }
5003
+ },
5004
+ effects: { base: [{
5005
+ effectId: "border-bottom-grow",
5006
+ options: {
5007
+ height: 1,
5008
+ colorToken: "accent",
5009
+ origin: "left"
5010
+ }
5011
+ }] }
5012
+ }
5013
+ },
5014
+ accent: {
5015
+ kind: "derive",
5016
+ from: "primary",
5017
+ overrides: { background: {
5018
+ type: "solid",
5019
+ colorToken: "accent"
5020
+ } }
4875
5021
  }
4876
- ]
5022
+ }
4877
5023
  }
4878
5024
  });
4879
5025
  //#endregion
4880
- //#region ../theme-core/src/buttons/personalities/two-tone-pill.ts
4881
- const solidSecondary = {
4882
- id: "secondary",
4883
- name: "Secondary",
4884
- enabled: true,
4885
- priority: 2,
4886
- background: {
4887
- type: "solid",
4888
- colorToken: unsafeAsOpaqueButtonColourToken("secondary")
4889
- },
4890
- borderRadius: "rounded-full",
4891
- shadow: {
4892
- elevation: "none",
4893
- softness: null,
4894
- position: "bottom"
4895
- },
4896
- effects: {
4897
- hover: [{
4898
- effectId: "background-on-hover-alpha",
4899
- options: {
4900
- colorToken: "secondary",
4901
- opacity: 88
4902
- }
4903
- }],
4904
- active: [{
4905
- effectId: "scale-down",
4906
- options: { scale: "0.98" }
4907
- }]
4908
- }
4909
- };
4910
- //#endregion
4911
- //#region ../theme-core/src/buttons/personalities/index.ts
4912
- const buttonPersonalities = [
4913
- softPill,
4914
- defineButtonPersonality({
4915
- id: "two-tone-pill",
4916
- name: "Two-tone Pill",
4917
- description: "Rounded pills with distinct solid primary and secondary brand colours.",
4918
- tags: softPill.tags,
4919
- buttonSystem: {
4920
- ...softPill.buttonSystem,
4921
- variants: softPill.buttonSystem.variants.map((variant) => variant.id === "secondary" ? solidSecondary : variant)
4922
- }
4923
- }),
4924
- earthPill,
4925
- confidentChip,
4926
- editorialLink,
4927
- pebble,
4928
- inkStamp,
4929
- flatInk,
4930
- brushedWash,
4931
- showtimePill,
4932
- joyStamp,
4933
- ornateRitual,
4934
- quietArrow
5026
+ //#region ../theme-core/src/buttons/styles/registry.ts
5027
+ const buttonStyleRecipes = [
5028
+ softPillRecipe,
5029
+ earthPillRecipe,
5030
+ confidentChipRecipe,
5031
+ editorialLinkRecipe,
5032
+ pebbleRecipe,
5033
+ inkStampRecipe,
5034
+ flatInkRecipe,
5035
+ brushedWashRecipe,
5036
+ showtimePillRecipe,
5037
+ joyStampRecipe,
5038
+ ornateRitualRecipe,
5039
+ quietArrowRecipe
4935
5040
  ];
4936
- new Map(buttonPersonalities.map((p) => [p.id, p]));
4937
- buttonPersonalities.map((personality) => ({
4938
- id: personality.id,
4939
- name: personality.name,
4940
- description: personality.description,
4941
- category: presetCategory(personality),
4942
- buttonSystem: personality.buttonSystem,
4943
- compatibility: {
4944
- ...personality.tags.tone ? { tones: [personality.tags.tone] } : {},
4945
- ...personality.tags.energy ? { energies: [personality.tags.energy] } : {}
4946
- }
4947
- }));
4948
- function presetCategory(personality) {
4949
- switch (personality.tags.era) {
5041
+ const recipesById = new Map(buttonStyleRecipes.map((recipe) => [recipe.id, recipe]));
5042
+ function findButtonStyleRecipe(id) {
5043
+ const recipe = recipesById.get(id);
5044
+ if (recipe === void 0) throw new Error(`Button style registry is missing known style ${id}`);
5045
+ return recipe;
5046
+ }
5047
+ function resolveButtonStyleSelection(selection) {
5048
+ switch (selection.styleId) {
5049
+ case "soft-pill": return resolveButtonStyleRecipe(softPillRecipe, selection.parameters);
5050
+ case "earth-pill": return resolveButtonStyleRecipe(earthPillRecipe, selection.parameters);
5051
+ case "confident-chip": return resolveButtonStyleRecipe(confidentChipRecipe, selection.parameters);
5052
+ case "editorial-link": return resolveButtonStyleRecipe(editorialLinkRecipe, selection.parameters);
5053
+ case "pebble": return resolveButtonStyleRecipe(pebbleRecipe, selection.parameters);
5054
+ case "ink-stamp": return resolveButtonStyleRecipe(inkStampRecipe, selection.parameters);
5055
+ case "flat-ink": return resolveButtonStyleRecipe(flatInkRecipe, selection.parameters);
5056
+ case "brushed-wash": return resolveButtonStyleRecipe(brushedWashRecipe, selection.parameters);
5057
+ case "showtime-pill": return resolveButtonStyleRecipe(showtimePillRecipe, selection.parameters);
5058
+ case "joy-stamp": return resolveButtonStyleRecipe(joyStampRecipe, selection.parameters);
5059
+ case "ornate-ritual": return resolveButtonStyleRecipe(ornateRitualRecipe, selection.parameters);
5060
+ case "quiet-arrow": return resolveButtonStyleRecipe(quietArrowRecipe, selection.parameters);
5061
+ }
5062
+ }
5063
+ function defaultButtonStyleSelectionFor(styleId) {
5064
+ return {
5065
+ styleId,
5066
+ parameters: findButtonStyleRecipe(styleId).defaultParameters
5067
+ };
5068
+ }
5069
+ 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");
5070
+ buttonStyleRecipes.map((recipe) => {
5071
+ const resolved = resolveButtonStyleSelection(defaultButtonStyleSelectionFor(recipe.id));
5072
+ if (resolved.kind === "error") throw new Error(`Invalid registered button style ${recipe.id}: ${resolved.error.issues.join(", ")}`);
5073
+ return {
5074
+ id: recipe.id,
5075
+ name: recipe.accessibilityLabel,
5076
+ description: recipe.accessibilityLabel,
5077
+ category: presetCategory(recipe),
5078
+ buttonSystem: resolved.buttonSystem,
5079
+ compatibility: {
5080
+ ...recipe.tags.tone ? { tones: [recipe.tags.tone] } : {},
5081
+ ...recipe.tags.energy ? { energies: [recipe.tags.energy] } : {}
5082
+ }
5083
+ };
5084
+ });
5085
+ function presetCategory(recipe) {
5086
+ switch (recipe.tags.era) {
4950
5087
  case "retro": return "retro";
4951
5088
  case "editorial": return "minimal";
4952
5089
  case "organic": return "artistic";
4953
- case "modern": return personality.tags.tone === "bold" ? "modern" : "technical";
5090
+ case "modern": return recipe.tags.tone === "bold" ? "modern" : "technical";
4954
5091
  case "technical": return "technical";
4955
5092
  case void 0: return "modern";
4956
5093
  }
@@ -9396,322 +9533,90 @@ const headerLookCatalog = defineExactCatalog()([
9396
9533
  id: asHeaderLookId("centered-calm"),
9397
9534
  label: "Centered calm",
9398
9535
  visualTreatment: "light-serif",
9399
- layoutBehavior: "normal-flow",
9400
- configuration: {
9401
- structure: "centered-stack",
9402
- treatment: "light-serif",
9403
- behavior: "normal-flow"
9404
- },
9405
- openingRequirement: "none",
9406
- maxRecommendedNavItems: 5,
9407
- logoAccommodations: centeredLogoAccommodations,
9408
- compile: centeredCalmHeader
9409
- },
9410
- {
9411
- id: asHeaderLookId("practical-utility"),
9412
- label: "Practical utility",
9413
- visualTreatment: "solid-neutral",
9414
- layoutBehavior: "sticky-shrink",
9415
- configuration: {
9416
- structure: "inline-classic",
9417
- treatment: "solid-neutral",
9418
- behavior: "sticky-shrink"
9419
- },
9420
- openingRequirement: "none",
9421
- requiresProminentCta: true,
9422
- logoAccommodations: inlineClassicLogoAccommodations,
9423
- compile: practicalUtilityHeader
9424
- },
9425
- {
9426
- id: asHeaderLookId("minimal-transparent"),
9427
- label: "Minimal transparent",
9428
- visualTreatment: "minimal-transparent",
9429
- layoutBehavior: "normal-flow",
9430
- configuration: {
9431
- structure: "inline-classic",
9432
- treatment: "minimal-transparent",
9433
- behavior: "normal-flow"
9434
- },
9435
- openingRequirement: "reserved-space-ok",
9436
- logoAccommodations: inlineClassicLogoAccommodations,
9437
- compile: minimalTransparentHeader
9438
- },
9439
- {
9440
- id: asHeaderLookId("transparent-overlay"),
9441
- label: "Transparent overlay",
9442
- visualTreatment: "transparent-overlay",
9443
- layoutBehavior: "fixed-overlay",
9444
- configuration: {
9445
- structure: "inline-classic",
9446
- treatment: "transparent-overlay",
9447
- behavior: "fixed-overlay"
9448
- },
9449
- openingRequirement: "requires-image-hero-with-contrast-overlay",
9450
- maxRecommendedNavItems: 5,
9451
- logoAccommodations: overlayLogoAccommodations,
9452
- compile: transparentOverlayHeader
9453
- },
9454
- {
9455
- id: asHeaderLookId("floating-glass"),
9456
- label: "Floating glass",
9457
- visualTreatment: "floating-glass",
9458
- layoutBehavior: "fixed-floating",
9459
- configuration: {
9460
- structure: "floating-shell",
9461
- treatment: "floating-glass",
9462
- behavior: "fixed-floating"
9463
- },
9464
- openingRequirement: "requires-image-hero-with-contrast-overlay",
9465
- maxRecommendedNavItems: 5,
9466
- logoAccommodations: overlayLogoAccommodations,
9467
- compile: floatingGlassHeader
9468
- }
9469
- ]);
9470
- new Set(headerLookCatalog.map((look) => headerConfigurationKey(look.configuration)));
9471
- new Map(headerLookCatalog.map((look) => [look.id, look]));
9472
- function headerConfigurationKey(configuration) {
9473
- return `${configuration.structure}:${configuration.treatment}:${configuration.behavior}`;
9474
- }
9475
- //#endregion
9476
- //#region ../theme-core/src/site-styles/footerLooks.ts
9477
- function asFooterLookId(value) {
9478
- return value;
9479
- }
9480
- function asFooterLayoutId(value) {
9481
- return value;
9482
- }
9483
- function asFooterStyleId(value) {
9484
- return value;
9485
- }
9486
- const footerLayoutCatalog = defineExactCatalog()([
9487
- {
9488
- id: asFooterLayoutId("identity"),
9489
- label: "Identity",
9490
- description: "Logo, site text, address, and legal copy without relying on footer navigation."
9491
- },
9492
- {
9493
- id: asFooterLayoutId("centered"),
9494
- label: "Centered",
9495
- description: "A calm centered stack for identity, short copy, and optional compact navigation.",
9496
- maxRecommendedNavDensity: "sparse"
9497
- },
9498
- {
9499
- id: asFooterLayoutId("split"),
9500
- label: "Split",
9501
- description: "Navigation and brand signoff separated into a wider split footer.",
9502
- requiresFooterNav: true,
9503
- maxRecommendedNavDensity: "balanced"
9504
- },
9505
- {
9506
- id: asFooterLayoutId("columns"),
9507
- label: "Columns",
9508
- description: "Grouped footer navigation columns with a supporting bottom line.",
9509
- requiresFooterNav: true,
9510
- requiresFooterNavGroups: true
9511
- }
9512
- ]);
9513
- const footerStyleCatalog = defineExactCatalog()([
9514
- {
9515
- id: asFooterStyleId("quiet"),
9516
- label: "Quiet",
9517
- description: "Lightweight, practical footer treatment."
9518
- },
9519
- {
9520
- id: asFooterStyleId("calm"),
9521
- label: "Calm",
9522
- description: "Soft centered treatment with restrained dividers."
9523
- },
9524
- {
9525
- id: asFooterStyleId("editorial"),
9526
- label: "Editorial",
9527
- description: "Text-forward treatment with fine-line structure."
9528
- },
9529
- {
9530
- id: asFooterStyleId("brand-band"),
9531
- label: "Brand band",
9532
- description: "High-contrast brand treatment with a stronger bottom bar."
9533
- }
9534
- ]);
9535
- new Map(footerLayoutCatalog.map((layout) => [layout.id, layout]));
9536
- new Map(footerStyleCatalog.map((style) => [style.id, style]));
9537
- /**
9538
- * No-nav-safe identity footer: brand and legal/supporting copy carry the
9539
- * footer without implying missing navigation.
9540
- */
9541
- function identityQuietFooter(theme) {
9542
- return {
9543
- ...theme.footer,
9544
- variant: "simple",
9545
- maxWidth: "container",
9546
- background: {
9547
- type: "color",
9548
- color: "surface"
9549
- },
9550
- navStyle: "minimal",
9551
- navWeight: "regular",
9552
- navColor: "text",
9553
- navLinkStyle: {
9554
- typography: "body",
9555
- fontWeight: "regular",
9556
- textTransform: "none",
9557
- italic: false,
9558
- colorToken: "text",
9559
- hoverColorToken: "primary",
9560
- padding: "none",
9561
- borderRadius: "none"
9562
- },
9563
- navLayout: {
9564
- layout: "inline-wrap",
9565
- align: "start",
9566
- gapX: "default",
9567
- gapY: "tight"
9568
- },
9569
- logo: {
9570
- showLogo: true,
9571
- showLogoText: true,
9572
- placement: "left",
9573
- size: "sm",
9574
- align: "start"
9575
- },
9576
- bottomBar: {
9577
- enabled: false,
9578
- fullBleed: false,
9579
- textAlign: "left",
9580
- paddingX: "default",
9581
- paddingY: "compact",
9582
- borderTop: { width: "none" }
9583
- }
9584
- };
9585
- }
9586
- /**
9587
- * Back-compat alias for the previous default footer Look. It keeps existing
9588
- * persisted selections valid while staying hidden from the new layout/style UI.
9589
- */
9590
- function mutedGroundingFooter(theme) {
9591
- return {
9592
- ...identityQuietFooter(theme),
9593
- background: theme.footer.background,
9594
- navStyle: theme.footer.navStyle,
9595
- navColor: theme.footer.navColor,
9596
- navWeight: theme.footer.navWeight,
9597
- navLinkStyle: theme.footer.navLinkStyle,
9598
- bottomTextLinkStyle: theme.footer.bottomTextLinkStyle
9599
- };
9600
- }
9601
- /** Applies a high-contrast brand band with a darker full-bleed bottom bar. */
9602
- function brandTwoBandFooter(theme) {
9603
- return {
9604
- ...theme.footer,
9605
- variant: "split",
9606
- maxWidth: "container",
9607
- background: {
9608
- type: "color",
9609
- color: "primary-800"
9610
- },
9611
- navStyle: "minimal",
9612
- navWeight: "medium",
9613
- navColor: "primaryForeground",
9614
- navLinkStyle: {
9615
- typography: "body",
9616
- fontWeight: "medium",
9617
- textTransform: "none",
9618
- italic: false,
9619
- colorToken: "primaryForeground",
9620
- hoverColorToken: "secondary",
9621
- padding: "none",
9622
- borderRadius: "none"
9623
- },
9624
- bottomTextLinkStyle: {
9625
- colorToken: "secondary",
9626
- decorationColorToken: "secondary"
9627
- },
9628
- navLayout: {
9629
- layout: "inline-wrap",
9630
- align: "start",
9631
- gapX: "default",
9632
- gapY: "tight"
9633
- },
9634
- logo: {
9635
- showLogo: true,
9636
- showLogoText: false,
9637
- placement: "left",
9638
- size: "sm",
9639
- align: "start"
9536
+ layoutBehavior: "normal-flow",
9537
+ configuration: {
9538
+ structure: "centered-stack",
9539
+ treatment: "light-serif",
9540
+ behavior: "normal-flow"
9640
9541
  },
9641
- bottomBar: {
9642
- enabled: true,
9643
- fullBleed: true,
9644
- background: {
9645
- type: "color",
9646
- color: "primary-900"
9647
- },
9648
- textColor: "primaryForeground",
9649
- textAlign: "center",
9650
- paddingX: "default",
9651
- paddingY: "compact",
9652
- borderTop: { width: "none" }
9653
- }
9654
- };
9655
- }
9656
- /**
9657
- * Centered stack on a softly tinted band: logo, inline nav, address, and a
9658
- * hairline-topped copyright line, all centered.
9659
- */
9660
- function centeredCalmFooter(theme) {
9661
- return {
9662
- ...theme.footer,
9663
- variant: "simple",
9664
- maxWidth: "container",
9665
- background: {
9666
- type: "color",
9667
- color: "surfaceAlt"
9542
+ openingRequirement: "none",
9543
+ maxRecommendedNavItems: 5,
9544
+ logoAccommodations: centeredLogoAccommodations,
9545
+ compile: centeredCalmHeader
9546
+ },
9547
+ {
9548
+ id: asHeaderLookId("practical-utility"),
9549
+ label: "Practical utility",
9550
+ visualTreatment: "solid-neutral",
9551
+ layoutBehavior: "sticky-shrink",
9552
+ configuration: {
9553
+ structure: "inline-classic",
9554
+ treatment: "solid-neutral",
9555
+ behavior: "sticky-shrink"
9668
9556
  },
9669
- navStyle: "minimal",
9670
- navWeight: "regular",
9671
- navColor: "text",
9672
- navLinkStyle: {
9673
- typography: "body",
9674
- fontWeight: "regular",
9675
- textTransform: "none",
9676
- italic: false,
9677
- colorToken: "text",
9678
- hoverColorToken: "primary",
9679
- padding: "none",
9680
- borderRadius: "none"
9557
+ openingRequirement: "none",
9558
+ requiresProminentCta: true,
9559
+ logoAccommodations: inlineClassicLogoAccommodations,
9560
+ compile: practicalUtilityHeader
9561
+ },
9562
+ {
9563
+ id: asHeaderLookId("minimal-transparent"),
9564
+ label: "Minimal transparent",
9565
+ visualTreatment: "minimal-transparent",
9566
+ layoutBehavior: "normal-flow",
9567
+ configuration: {
9568
+ structure: "inline-classic",
9569
+ treatment: "minimal-transparent",
9570
+ behavior: "normal-flow"
9681
9571
  },
9682
- navLayout: {
9683
- layout: "inline-wrap",
9684
- align: "center",
9685
- gapX: "relaxed",
9686
- gapY: "tight"
9572
+ openingRequirement: "reserved-space-ok",
9573
+ logoAccommodations: inlineClassicLogoAccommodations,
9574
+ compile: minimalTransparentHeader
9575
+ },
9576
+ {
9577
+ id: asHeaderLookId("transparent-overlay"),
9578
+ label: "Transparent overlay",
9579
+ visualTreatment: "transparent-overlay",
9580
+ layoutBehavior: "fixed-overlay",
9581
+ configuration: {
9582
+ structure: "inline-classic",
9583
+ treatment: "transparent-overlay",
9584
+ behavior: "fixed-overlay"
9687
9585
  },
9688
- logo: {
9689
- showLogo: true,
9690
- showLogoText: false,
9691
- placement: "above",
9692
- size: "sm",
9693
- align: "center"
9586
+ openingRequirement: "requires-image-hero-with-contrast-overlay",
9587
+ maxRecommendedNavItems: 5,
9588
+ logoAccommodations: overlayLogoAccommodations,
9589
+ compile: transparentOverlayHeader
9590
+ },
9591
+ {
9592
+ id: asHeaderLookId("floating-glass"),
9593
+ label: "Floating glass",
9594
+ visualTreatment: "floating-glass",
9595
+ layoutBehavior: "fixed-floating",
9596
+ configuration: {
9597
+ structure: "floating-shell",
9598
+ treatment: "floating-glass",
9599
+ behavior: "fixed-floating"
9694
9600
  },
9695
- bottomBar: {
9696
- enabled: true,
9697
- fullBleed: false,
9698
- textAlign: "center",
9699
- paddingX: "default",
9700
- paddingY: "compact",
9701
- borderTop: { width: "thin" }
9702
- }
9703
- };
9601
+ openingRequirement: "requires-image-hero-with-contrast-overlay",
9602
+ maxRecommendedNavItems: 5,
9603
+ logoAccommodations: overlayLogoAccommodations,
9604
+ compile: floatingGlassHeader
9605
+ }
9606
+ ]);
9607
+ new Set(headerLookCatalog.map((look) => headerConfigurationKey(look.configuration)));
9608
+ new Map(headerLookCatalog.map((look) => [look.id, look]));
9609
+ function headerConfigurationKey(configuration) {
9610
+ return `${configuration.structure}:${configuration.treatment}:${configuration.behavior}`;
9611
+ }
9612
+ //#endregion
9613
+ //#region ../theme-core/src/site-styles/footerLooks.ts
9614
+ function asFooterLookId(value) {
9615
+ return value;
9704
9616
  }
9705
- /** Editorial split footer: compact nav on one side, brand signoff on the other. */
9706
- function splitEditorialFooter(theme) {
9617
+ function quietFooterLinks(theme) {
9707
9618
  return {
9708
9619
  ...theme.footer,
9709
- variant: "split",
9710
- maxWidth: "container",
9711
- background: {
9712
- type: "color",
9713
- color: "surface"
9714
- },
9715
9620
  navStyle: "minimal",
9716
9621
  navWeight: "regular",
9717
9622
  navColor: "text",
@@ -9724,120 +9629,38 @@ function splitEditorialFooter(theme) {
9724
9629
  hoverColorToken: "primary",
9725
9630
  padding: "none",
9726
9631
  borderRadius: "none"
9727
- },
9728
- navLayout: {
9729
- layout: "inline-wrap",
9730
- align: "start",
9731
- gapX: "relaxed",
9732
- gapY: "tight"
9733
- },
9734
- logo: {
9735
- showLogo: true,
9736
- showLogoText: true,
9737
- placement: "right",
9738
- size: "sm",
9739
- align: "end"
9740
- },
9741
- bottomBar: {
9742
- enabled: true,
9743
- fullBleed: false,
9744
- textAlign: "left",
9745
- paddingX: "default",
9746
- paddingY: "compact",
9747
- borderTop: { width: "thin" }
9748
9632
  }
9749
9633
  };
9750
9634
  }
9751
- /**
9752
- * Editorial columns: site name and supporting copy on the left, inline nav on
9753
- * the right, with a hairline-topped bottom line. Uses the footer block's
9754
- * columns layout.
9755
- */
9756
- function editorialColumnsFooter(theme) {
9635
+ function emphasizedFooterLinks(theme) {
9757
9636
  return {
9758
9637
  ...theme.footer,
9759
- variant: "columns",
9760
- maxWidth: "container",
9761
- background: {
9762
- type: "color",
9763
- color: "surface"
9764
- },
9765
9638
  navStyle: "minimal",
9766
- navWeight: "regular",
9639
+ navWeight: "medium",
9767
9640
  navColor: "text",
9768
9641
  navLinkStyle: {
9769
9642
  typography: "body",
9770
- fontWeight: "regular",
9643
+ fontWeight: "medium",
9771
9644
  textTransform: "none",
9772
9645
  italic: false,
9773
9646
  colorToken: "text",
9774
9647
  hoverColorToken: "primary",
9775
9648
  padding: "none",
9776
9649
  borderRadius: "none"
9777
- },
9778
- logo: {
9779
- showLogo: true,
9780
- showLogoText: true,
9781
- placement: "left",
9782
- size: "sm",
9783
- align: "start"
9784
- },
9785
- bottomBar: {
9786
- enabled: true,
9787
- fullBleed: false,
9788
- textAlign: "center",
9789
- paddingX: "default",
9790
- paddingY: "compact",
9791
- borderTop: { width: "thin" }
9792
9650
  }
9793
9651
  };
9794
9652
  }
9795
- const footerLookCatalog = defineExactCatalog()([
9796
- {
9797
- id: asFooterLookId("footer-identity-quiet"),
9798
- label: "Identity footer",
9799
- layoutId: asFooterLayoutId("identity"),
9800
- styleId: asFooterStyleId("quiet"),
9801
- compile: identityQuietFooter
9802
- },
9803
- {
9804
- id: asFooterLookId("footer-muted-grounding"),
9805
- label: "Muted grounding footer",
9806
- layoutId: asFooterLayoutId("identity"),
9807
- styleId: asFooterStyleId("quiet"),
9808
- hiddenFromLayoutStyleControls: true,
9809
- compile: mutedGroundingFooter
9810
- },
9811
- {
9812
- id: asFooterLookId("footer-centered-calm"),
9813
- label: "Centered calm footer",
9814
- layoutId: asFooterLayoutId("centered"),
9815
- styleId: asFooterStyleId("calm"),
9816
- compile: centeredCalmFooter
9817
- },
9818
- {
9819
- id: asFooterLookId("footer-split-editorial"),
9820
- label: "Split editorial footer",
9821
- layoutId: asFooterLayoutId("split"),
9822
- styleId: asFooterStyleId("editorial"),
9823
- compile: splitEditorialFooter
9824
- },
9825
- {
9826
- id: asFooterLookId("footer-editorial-columns"),
9827
- label: "Editorial columns footer",
9828
- layoutId: asFooterLayoutId("columns"),
9829
- styleId: asFooterStyleId("editorial"),
9830
- compile: editorialColumnsFooter
9831
- },
9832
- {
9833
- id: asFooterLookId("site-footer-brand-two-band"),
9834
- label: "Two-band brand footer",
9835
- layoutId: asFooterLayoutId("split"),
9836
- styleId: asFooterStyleId("brand-band"),
9837
- allowedContentPresence: ["default-footer", "default-and-blocks"],
9838
- compile: brandTwoBandFooter
9839
- }
9840
- ]);
9653
+ const footerLookCatalog = defineExactCatalog()([{
9654
+ id: asFooterLookId("footer-links-quiet"),
9655
+ label: "Quiet links",
9656
+ description: "Regular-weight footer navigation with a restrained hover.",
9657
+ compile: quietFooterLinks
9658
+ }, {
9659
+ id: asFooterLookId("footer-links-emphasized"),
9660
+ label: "Emphasized links",
9661
+ description: "Medium-weight footer navigation with a clearer emphasis.",
9662
+ compile: emphasizedFooterLinks
9663
+ }]);
9841
9664
  new Map(footerLookCatalog.map((look) => [look.id, look]));
9842
9665
  //#endregion
9843
9666
  //#region ../theme-core/src/site-styles/sourceCatalogs.ts
@@ -10966,17 +10789,21 @@ function defineCuratedSiteStyle(input) {
10966
10789
  })),
10967
10790
  recommendedHeaderLookIds: legacyHeaderLookIds.map(asHeaderLookId),
10968
10791
  recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(asFooterLookId),
10969
- buttonPersonalityChoices: input.buttonPersonalityChoices,
10792
+ buttonStyleChoices: input.buttonStyleChoices,
10970
10793
  paletteRecommendations: input.paletteRecommendations,
10971
10794
  typography: input.typography ?? defaultTypographyForRecipe(input.tokenRecipes.typography),
10972
10795
  ...input.heroTypography ? { heroTypography: input.heroTypography } : {}
10973
10796
  };
10974
10797
  }
10975
- function buttonChoice(id, note) {
10798
+ function buttonChoice(styleId, note, parameters) {
10799
+ const selection = parameters === void 0 ? defaultButtonStyleSelectionFor(styleId) : buttonStyleSelectionSchema.parse({
10800
+ styleId,
10801
+ parameters
10802
+ });
10976
10803
  return note ? {
10977
- id: asButtonPersonalityId(id),
10804
+ ...selection,
10978
10805
  note
10979
- } : { id: asButtonPersonalityId(id) };
10806
+ } : selection;
10980
10807
  }
10981
10808
  function paletteRecommendation(authoringKey, note) {
10982
10809
  const valueKey = requireCuratedPaletteValueKey(asCuratedPaletteAuthoringKey(authoringKey));
@@ -11161,9 +10988,8 @@ const curatedSiteStyles = [
11161
10988
  "minimal-transparent",
11162
10989
  "clean-base"
11163
10990
  ],
11164
- buttonPersonalityChoices: [
10991
+ buttonStyleChoices: [
11165
10992
  buttonChoice("soft-pill"),
11166
- buttonChoice("two-tone-pill"),
11167
10993
  buttonChoice("pebble"),
11168
10994
  buttonChoice("editorial-link"),
11169
10995
  buttonChoice("brushed-wash")
@@ -11199,7 +11025,7 @@ const curatedSiteStyles = [
11199
11025
  "brand-solid",
11200
11026
  "clean-base"
11201
11027
  ],
11202
- buttonPersonalityChoices: [
11028
+ buttonStyleChoices: [
11203
11029
  buttonChoice("confident-chip"),
11204
11030
  buttonChoice("soft-pill"),
11205
11031
  buttonChoice("editorial-link")
@@ -11238,7 +11064,7 @@ const curatedSiteStyles = [
11238
11064
  "minimal-transparent",
11239
11065
  "centered-calm"
11240
11066
  ],
11241
- buttonPersonalityChoices: [
11067
+ buttonStyleChoices: [
11242
11068
  buttonChoice("editorial-link"),
11243
11069
  buttonChoice("soft-pill"),
11244
11070
  buttonChoice("brushed-wash")
@@ -11278,7 +11104,7 @@ const curatedSiteStyles = [
11278
11104
  "practical-utility",
11279
11105
  "clean-base"
11280
11106
  ],
11281
- buttonPersonalityChoices: [
11107
+ buttonStyleChoices: [
11282
11108
  buttonChoice("pebble"),
11283
11109
  buttonChoice("brushed-wash"),
11284
11110
  buttonChoice("confident-chip")
@@ -11339,7 +11165,7 @@ const curatedSiteStyles = [
11339
11165
  "serif-line",
11340
11166
  "clean-base"
11341
11167
  ],
11342
- buttonPersonalityChoices: [
11168
+ buttonStyleChoices: [
11343
11169
  buttonChoice("editorial-link"),
11344
11170
  buttonChoice("confident-chip"),
11345
11171
  buttonChoice("soft-pill")
@@ -11401,7 +11227,7 @@ const curatedSiteStyles = [
11401
11227
  "brand-solid",
11402
11228
  "clean-base"
11403
11229
  ],
11404
- buttonPersonalityChoices: [
11230
+ buttonStyleChoices: [
11405
11231
  buttonChoice("confident-chip"),
11406
11232
  buttonChoice("pebble"),
11407
11233
  buttonChoice("ink-stamp")
@@ -11440,7 +11266,7 @@ const curatedSiteStyles = [
11440
11266
  "minimal-transparent",
11441
11267
  "clean-base"
11442
11268
  ],
11443
- buttonPersonalityChoices: [
11269
+ buttonStyleChoices: [
11444
11270
  buttonChoice("soft-pill"),
11445
11271
  buttonChoice("pebble"),
11446
11272
  buttonChoice("confident-chip")
@@ -11513,7 +11339,7 @@ const curatedSiteStyles = [
11513
11339
  "clean-base",
11514
11340
  "centered-calm"
11515
11341
  ],
11516
- buttonPersonalityChoices: [
11342
+ buttonStyleChoices: [
11517
11343
  buttonChoice("pebble"),
11518
11344
  buttonChoice("soft-pill"),
11519
11345
  buttonChoice("editorial-link")
@@ -11632,12 +11458,8 @@ const curatedSiteStyles = [
11632
11458
  "serif-line",
11633
11459
  "minimal-transparent"
11634
11460
  ],
11635
- recommendedFooterLookIds: [
11636
- "footer-centered-calm",
11637
- "footer-editorial-columns",
11638
- "footer-muted-grounding"
11639
- ],
11640
- buttonPersonalityChoices: [
11461
+ recommendedFooterLookIds: ["footer-links-quiet"],
11462
+ buttonStyleChoices: [
11641
11463
  buttonChoice("soft-pill"),
11642
11464
  buttonChoice("pebble"),
11643
11465
  buttonChoice("editorial-link")
@@ -11711,7 +11533,7 @@ const curatedSiteStyles = [
11711
11533
  "centered-calm",
11712
11534
  "minimal-transparent"
11713
11535
  ],
11714
- buttonPersonalityChoices: [
11536
+ buttonStyleChoices: [
11715
11537
  buttonChoice("editorial-link"),
11716
11538
  buttonChoice("soft-pill"),
11717
11539
  buttonChoice("brushed-wash")
@@ -11784,8 +11606,8 @@ const curatedSiteStyles = [
11784
11606
  "practical-utility",
11785
11607
  "clean-base"
11786
11608
  ],
11787
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
11788
- buttonPersonalityChoices: [
11609
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
11610
+ buttonStyleChoices: [
11789
11611
  buttonChoice("pebble"),
11790
11612
  buttonChoice("confident-chip"),
11791
11613
  buttonChoice("ink-stamp"),
@@ -11906,8 +11728,8 @@ const curatedSiteStyles = [
11906
11728
  "minimal-transparent",
11907
11729
  "serif-line"
11908
11730
  ],
11909
- recommendedFooterLookIds: ["footer-muted-grounding", "site-footer-brand-two-band"],
11910
- buttonPersonalityChoices: [
11731
+ recommendedFooterLookIds: ["footer-links-quiet", "footer-links-emphasized"],
11732
+ buttonStyleChoices: [
11911
11733
  buttonChoice("earth-pill"),
11912
11734
  buttonChoice("soft-pill"),
11913
11735
  buttonChoice("pebble"),
@@ -11978,7 +11800,7 @@ const curatedSiteStyles = [
11978
11800
  "floating-glass",
11979
11801
  "brand-solid"
11980
11802
  ],
11981
- buttonPersonalityChoices: [
11803
+ buttonStyleChoices: [
11982
11804
  buttonChoice("ink-stamp"),
11983
11805
  buttonChoice("confident-chip"),
11984
11806
  buttonChoice("brushed-wash"),
@@ -12033,8 +11855,8 @@ const curatedSiteStyles = [
12033
11855
  "transparent-overlay",
12034
11856
  "practical-utility"
12035
11857
  ],
12036
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12037
- buttonPersonalityChoices: [
11858
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
11859
+ buttonStyleChoices: [
12038
11860
  buttonChoice("showtime-pill"),
12039
11861
  buttonChoice("confident-chip"),
12040
11862
  buttonChoice("ink-stamp"),
@@ -12115,8 +11937,8 @@ const curatedSiteStyles = [
12115
11937
  headerStyleChoice("glass")
12116
11938
  ] },
12117
11939
  recommendedHeaderLookIds: ["minimal-transparent"],
12118
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12119
- buttonPersonalityChoices: [
11940
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
11941
+ buttonStyleChoices: [
12120
11942
  buttonChoice("ornate-ritual"),
12121
11943
  buttonChoice("joy-stamp"),
12122
11944
  buttonChoice("ink-stamp")
@@ -12169,8 +11991,8 @@ const curatedSiteStyles = [
12169
11991
  headerStyleChoice("glass")
12170
11992
  ] },
12171
11993
  recommendedHeaderLookIds: ["minimal-transparent"],
12172
- recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12173
- buttonPersonalityChoices: [
11994
+ recommendedFooterLookIds: ["footer-links-emphasized", "footer-links-quiet"],
11995
+ buttonStyleChoices: [
12174
11996
  buttonChoice("joy-stamp"),
12175
11997
  buttonChoice("ink-stamp"),
12176
11998
  buttonChoice("showtime-pill")
@@ -12260,8 +12082,8 @@ const curatedSiteStyles = [
12260
12082
  "centered-calm",
12261
12083
  "clean-base"
12262
12084
  ],
12263
- recommendedFooterLookIds: ["footer-editorial-columns", "footer-muted-grounding"],
12264
- buttonPersonalityChoices: [
12085
+ recommendedFooterLookIds: ["footer-links-quiet"],
12086
+ buttonStyleChoices: [
12265
12087
  buttonChoice("flat-ink"),
12266
12088
  buttonChoice("confident-chip"),
12267
12089
  buttonChoice("editorial-link")
@@ -12338,14 +12160,9 @@ const curatedSiteStyles = [
12338
12160
  "serif-line",
12339
12161
  "clean-base"
12340
12162
  ],
12341
- recommendedFooterLookIds: [
12342
- "footer-editorial-columns",
12343
- "footer-muted-grounding",
12344
- "footer-identity-quiet"
12345
- ],
12346
- buttonPersonalityChoices: [
12347
- buttonChoice("quiet-arrow"),
12348
- buttonChoice("two-tone-pill"),
12163
+ recommendedFooterLookIds: ["footer-links-quiet"],
12164
+ buttonStyleChoices: [
12165
+ buttonChoice("quiet-arrow", void 0, { secondaryTreatment: "solid-accent" }),
12349
12166
  buttonChoice("flat-ink"),
12350
12167
  buttonChoice("editorial-link")
12351
12168
  ],
@@ -16291,25 +16108,41 @@ const heroLayoutControlsFragment = defineFragment({
16291
16108
  layout: []
16292
16109
  });
16293
16110
  //#endregion
16111
+ //#region ../blocks/src/system/constants/buttonRoles.ts
16112
+ /**
16113
+ * Semantic button roles available to block authors.
16114
+ *
16115
+ * These roles are deliberately independent of a site's visual button style:
16116
+ * the active theme owns how each role looks.
16117
+ */
16118
+ const BLOCK_BUTTON_ROLES = PUBLIC_BUTTON_ROLES;
16119
+ const blockButtonRoleSchema = z$1.enum(BLOCK_BUTTON_ROLES);
16120
+ /**
16121
+ * Temporary rollout boundary for persisted content written before issue #1220.
16122
+ * Authoring remains strict through `blockButtonRoleSchema`; this parser exists
16123
+ * only until the post-deploy role rewrite has been audited in production.
16124
+ */
16125
+ function canonicalizePersistedBlockButtonRole(value) {
16126
+ return value === "link" || value === "tertiary" ? "ghost" : value;
16127
+ }
16128
+ const persistedBlockButtonRoleSchema = z$1.preprocess((value) => typeof value === "string" ? canonicalizePersistedBlockButtonRole(value) : value, blockButtonRoleSchema);
16129
+ const BLOCK_BUTTON_ROLE_LABELS = {
16130
+ primary: "Primary",
16131
+ secondary: "Secondary",
16132
+ outline: "Outline",
16133
+ ghost: "Ghost",
16134
+ accent: "Accent"
16135
+ };
16136
+ const BLOCK_BUTTON_ROLE_OPTIONS = BLOCK_BUTTON_ROLES.map((value) => ({
16137
+ value,
16138
+ label: BLOCK_BUTTON_ROLE_LABELS[value]
16139
+ }));
16140
+ function isBlockButtonRole(value) {
16141
+ return blockButtonRoleSchema.safeParse(value).success;
16142
+ }
16143
+ //#endregion
16294
16144
  //#region ../blocks/src/system/fields/button.ts
16295
- const DEFAULT_THEME_BUTTON_VARIANTS = [
16296
- {
16297
- value: "primary",
16298
- label: "Primary"
16299
- },
16300
- {
16301
- value: "secondary",
16302
- label: "Secondary"
16303
- },
16304
- {
16305
- value: "outline",
16306
- label: "Outline"
16307
- },
16308
- {
16309
- value: "link",
16310
- label: "Link"
16311
- }
16312
- ];
16145
+ const DEFAULT_THEME_BUTTON_VARIANTS = BLOCK_BUTTON_ROLE_OPTIONS;
16313
16146
  function createButtonVariantField(options = {}) {
16314
16147
  return {
16315
16148
  id: options.id ?? "buttonVariant",
@@ -16327,20 +16160,7 @@ function createButtonVariantField(options = {}) {
16327
16160
  };
16328
16161
  }
16329
16162
  function createButtonGroup(options = {}) {
16330
- const { variants = [
16331
- {
16332
- value: "primary",
16333
- label: "Primary"
16334
- },
16335
- {
16336
- value: "secondary",
16337
- label: "Secondary"
16338
- },
16339
- {
16340
- value: "outline",
16341
- label: "Outline"
16342
- }
16343
- ], defaultVariant, includeSize = true, defaultSize = "md", showGroupLabel = false, groupId = "button", groupLabel = "Button", flattenInRepeater = true } = options;
16163
+ const { variants = BLOCK_BUTTON_ROLE_OPTIONS, defaultVariant, includeSize = true, defaultSize = "md", showGroupLabel = false, groupId = "button", groupLabel = "Button", flattenInRepeater = true } = options;
16344
16164
  const mainFields = [
16345
16165
  {
16346
16166
  id: "label",
@@ -16476,29 +16296,7 @@ const ctaRowFragment = defineFragment({
16476
16296
  fields: [createCtasRepeater({
16477
16297
  label: "Calls to action",
16478
16298
  itemLabel: "CTA",
16479
- maxItems: 3,
16480
- button: { variants: [
16481
- {
16482
- value: "primary",
16483
- label: "Primary"
16484
- },
16485
- {
16486
- value: "secondary",
16487
- label: "Secondary"
16488
- },
16489
- {
16490
- value: "outline",
16491
- label: "Outline"
16492
- },
16493
- {
16494
- value: "link",
16495
- label: "Link"
16496
- },
16497
- {
16498
- value: "accent",
16499
- label: "Accent"
16500
- }
16501
- ] }
16299
+ maxItems: 3
16502
16300
  })],
16503
16301
  layout: [ctaRow({
16504
16302
  collectionPath: "content.ctas",
@@ -16517,10 +16315,6 @@ const heroCtaRowFragment = defineFragment({
16517
16315
  defaultValue: [],
16518
16316
  button: {
16519
16317
  variants: [
16520
- {
16521
- value: "default",
16522
- label: "Default"
16523
- },
16524
16318
  {
16525
16319
  value: "primary",
16526
16320
  label: "Primary"
@@ -16532,9 +16326,17 @@ const heroCtaRowFragment = defineFragment({
16532
16326
  {
16533
16327
  value: "outline",
16534
16328
  label: "Outline"
16329
+ },
16330
+ {
16331
+ value: "ghost",
16332
+ label: "Ghost"
16333
+ },
16334
+ {
16335
+ value: "accent",
16336
+ label: "Accent"
16535
16337
  }
16536
16338
  ],
16537
- defaultVariant: "default",
16339
+ defaultVariant: "primary",
16538
16340
  includeSize: true,
16539
16341
  defaultSize: "lg"
16540
16342
  }
@@ -17225,11 +17027,13 @@ const blogFeaturedPostFragment = defineFragment({
17225
17027
  as: "p",
17226
17028
  style: textColorStyle("text/80")
17227
17029
  }, bind("post.excerpt", { fallback: "Select a blog post to display its preview." })),
17228
- link({
17229
- className: "rb-inline-flex rb-items-center rb-caption rb-hover-opacity-80",
17230
- style: textColorStyle("primary"),
17231
- href: { $bind: { from: "post.path" } }
17232
- }, [text({ as: "strong" }, props({ value: "Read more →" }))])
17030
+ button({
17031
+ className: "rb-self-start",
17032
+ href: { $bind: { from: "post.path" } },
17033
+ variantId: "ghost",
17034
+ size: "sm",
17035
+ linkRequired: true
17036
+ }, [text({ as: "span" }, props({ value: "Read more" }))])
17233
17037
  ])], when("post")), stack({
17234
17038
  gap: "sm",
17235
17039
  className: "rb-rounded-xl rb-border rb-border-dashed rb-p-6",
@@ -17500,21 +17304,7 @@ const newsletterFormFragment = defineFragment({
17500
17304
  createButtonVariantField({
17501
17305
  id: "buttonVariant",
17502
17306
  label: "Button style",
17503
- defaultValue: "primary",
17504
- variants: [
17505
- {
17506
- value: "primary",
17507
- label: "Primary"
17508
- },
17509
- {
17510
- value: "secondary",
17511
- label: "Secondary"
17512
- },
17513
- {
17514
- value: "outline",
17515
- label: "Outline"
17516
- }
17517
- ]
17307
+ defaultValue: "primary"
17518
17308
  }),
17519
17309
  {
17520
17310
  id: "successMessage",
@@ -19063,7 +18853,8 @@ function postExcerpt(className) {
19063
18853
  function postReadMore() {
19064
18854
  return button({
19065
18855
  href: { $bind: { from: "post.path" } },
19066
- className: "rb-self-start"
18856
+ className: "rb-self-start",
18857
+ variantId: "ghost"
19067
18858
  }, [text({ as: "span" }, bind("content.readMoreText", { fallback: "Read more" }), when("content.readMoreText")), text({
19068
18859
  as: "span",
19069
18860
  value: "Read more"
@@ -21338,31 +21129,7 @@ const featureCardsBlockDefinition = { manifest: createBlockManifest({
21338
21129
  label: "Calls to action",
21339
21130
  itemLabel: "CTA",
21340
21131
  maxItems: 1,
21341
- button: {
21342
- variants: [
21343
- {
21344
- value: "primary",
21345
- label: "Primary"
21346
- },
21347
- {
21348
- value: "secondary",
21349
- label: "Secondary"
21350
- },
21351
- {
21352
- value: "outline",
21353
- label: "Outline"
21354
- },
21355
- {
21356
- value: "ghost",
21357
- label: "Ghost"
21358
- },
21359
- {
21360
- value: "link",
21361
- label: "Link"
21362
- }
21363
- ],
21364
- defaultVariant: "ghost"
21365
- }
21132
+ button: { defaultVariant: "ghost" }
21366
21133
  })
21367
21134
  ] }
21368
21135
  },
@@ -23525,17 +23292,8 @@ function readAmount(value) {
23525
23292
  //#endregion
23526
23293
  //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
23527
23294
  const previewStageSchema = z$1.enum(["preview", "published"]);
23528
- const registrationButtonVariantSchema = z$1.enum([
23529
- "primary",
23530
- "secondary",
23531
- "outline"
23532
- ]);
23533
- const eventButtonVariantSchema = z$1.enum([
23534
- "primary",
23535
- "secondary",
23536
- "outline",
23537
- "link"
23538
- ]);
23295
+ const registrationButtonVariantSchema = blockButtonRoleSchema;
23296
+ const eventButtonVariantSchema = persistedBlockButtonRoleSchema;
23539
23297
  const eventLayoutSchema = z$1.enum(eventCalendarListLayoutValues);
23540
23298
  const eventCalendarDisplayModeSchema = z$1.enum(eventCalendarDisplayModeValues);
23541
23299
  const eventCalendarDefaultViewSchema = z$1.enum(eventCalendarDefaultViewValues);
@@ -23900,23 +23658,7 @@ const eventRegistrationBlockDefinition = {
23900
23658
  defaultValue: "Complete Registration",
23901
23659
  maxLength: 40
23902
23660
  },
23903
- createButtonVariantField({
23904
- description: "Choose a button style from your theme",
23905
- variants: [
23906
- {
23907
- value: "primary",
23908
- label: "Primary"
23909
- },
23910
- {
23911
- value: "secondary",
23912
- label: "Secondary"
23913
- },
23914
- {
23915
- value: "outline",
23916
- label: "Outline"
23917
- }
23918
- ]
23919
- })
23661
+ createButtonVariantField()
23920
23662
  ],
23921
23663
  layout: [styledSection({
23922
23664
  baseClass: "",
@@ -24223,23 +23965,7 @@ const courseRegistrationBlockDefinition = {
24223
23965
  defaultValue: "Sign up",
24224
23966
  maxLength: 40
24225
23967
  },
24226
- createButtonVariantField({
24227
- description: "Choose a button style from your theme",
24228
- variants: [
24229
- {
24230
- value: "primary",
24231
- label: "Primary"
24232
- },
24233
- {
24234
- value: "secondary",
24235
- label: "Secondary"
24236
- },
24237
- {
24238
- value: "outline",
24239
- label: "Outline"
24240
- }
24241
- ]
24242
- })
23968
+ createButtonVariantField()
24243
23969
  ],
24244
23970
  layout: [styledSection({
24245
23971
  baseClass: "",
@@ -27104,36 +26830,7 @@ const offeringsPreviewFields = [
27104
26830
  ui: { intent: "content" },
27105
26831
  schema: { fields: groupOverrideFields }
27106
26832
  },
27107
- {
27108
- id: "buttonVariant",
27109
- type: "select",
27110
- label: "Button style",
27111
- required: false,
27112
- multiple: false,
27113
- defaultValue: "primary",
27114
- options: [
27115
- {
27116
- value: "primary",
27117
- label: "Primary"
27118
- },
27119
- {
27120
- value: "secondary",
27121
- label: "Secondary"
27122
- },
27123
- {
27124
- value: "outline",
27125
- label: "Outline"
27126
- },
27127
- {
27128
- value: "link",
27129
- label: "Link"
27130
- }
27131
- ],
27132
- ui: {
27133
- intent: "display",
27134
- widget: "buttonVariant"
27135
- }
27136
- },
26833
+ createButtonVariantField(),
27137
26834
  {
27138
26835
  id: "buttonText",
27139
26836
  type: "text",
@@ -27339,7 +27036,7 @@ function normalizeOfferingsPreviewGroupOverride(value) {
27339
27036
  return [override];
27340
27037
  }
27341
27038
  function isButtonVariant(value) {
27342
- return value === "primary" || value === "secondary" || value === "outline" || value === "link" || value === null;
27039
+ return value === null || isBlockButtonRole(value);
27343
27040
  }
27344
27041
  function normalizeCardStylesContent(value) {
27345
27042
  return isRecord$1(value) || value === null ? value : void 0;
@@ -29191,12 +28888,7 @@ const shopSourceSchema = z$1.object({
29191
28888
  showPrices: z$1.boolean().optional(),
29192
28889
  showValidityPeriod: z$1.boolean().optional(),
29193
28890
  showPricePerCredit: z$1.boolean().nullable().optional(),
29194
- buttonVariant: z$1.enum([
29195
- "primary",
29196
- "secondary",
29197
- "outline",
29198
- "link"
29199
- ]).optional(),
28891
+ buttonVariant: blockButtonRoleSchema.optional(),
29200
28892
  passesHeading: z$1.string().optional(),
29201
28893
  membershipsHeading: z$1.string().optional(),
29202
28894
  buyButtonText: z$1.string().optional(),
@@ -29341,12 +29033,7 @@ const passesMembershipsHydrationSchema = z$1.object({
29341
29033
  passes: z$1.array(publicPassProductSchema),
29342
29034
  memberships: z$1.array(publicMembershipProductSchema),
29343
29035
  passPurchaseMode: z$1.enum(["add_to_cart", "buy_now"]),
29344
- buttonVariant: z$1.enum([
29345
- "primary",
29346
- "secondary",
29347
- "outline",
29348
- "link"
29349
- ])
29036
+ buttonVariant: blockButtonRoleSchema
29350
29037
  });
29351
29038
  const productListHydrationSchema = z$1.object({
29352
29039
  products: z$1.array(publicProductSchema),
@@ -30670,11 +30357,7 @@ const newsletterPresetSchema = z$1.enum([
30670
30357
  "emailNameCompany"
30671
30358
  ]);
30672
30359
  const newsletterDestinationProviderSchema = z$1.enum(["riverbank", "mailchimp"]);
30673
- const newsletterButtonVariantSchema = z$1.enum([
30674
- "primary",
30675
- "secondary",
30676
- "outline"
30677
- ]);
30360
+ const newsletterButtonVariantSchema = blockButtonRoleSchema;
30678
30361
  const newsletterFieldSchema = z$1.object({
30679
30362
  id: z$1.string(),
30680
30363
  type: z$1.enum(["email", "text"]),