@designcrowd/library.brand-page 6.2.11-builder-v2-1 → 6.2.12

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 (579) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-Dg2pOwbr.js → CreatedOnBrandCrowd-de-de-BtVKllNQ.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-BILs_hsB.js → CreatedOnBrandCrowd-en-us-CX5V0v8u.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-VpxQ0N5F.js → CreatedOnBrandCrowd-es-es-CbA02PCL.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-CFHWRHzi.js → CreatedOnBrandCrowd-fr-ca-BQAKruBF.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-CFHWRHzi.js → CreatedOnBrandCrowd-fr-fr-BQAKruBF.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-CZfs45s9.js → CreatedOnBrandCrowd-pt-br-Yk_yzB3s.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-CZfs45s9.js → CreatedOnBrandCrowd-pt-pt-Yk_yzB3s.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-DYMQ6sIF.js → CreatedOnDcom-de-de-DJZQbPSD.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-Dj5sdPid.js → CreatedOnDcom-en-us-BJvNAa4l.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-Cx9yNTro.js → CreatedOnDcom-es-es-CUwB1FRY.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-Bzr0SjGq.js → CreatedOnDcom-fr-ca-CK54U4oh.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-BgqKY35F.js → CreatedOnDcom-fr-fr-DuUNBGrM.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CXK6qfvL.js → CreatedOnDcom-pt-br-BfODpFNV.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-B8SggNTQ.js → CreatedOnDcom-pt-pt-Cf6u2GCg.js} +1 -1
  15. package/lib/src/brand-page/__fixtures__/production-text-style-resolver.fixture.d.ts +16 -0
  16. package/lib/src/brand-page/__fixtures__/production-text-style-resolver.fixture.js +35 -0
  17. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.d.ts +3 -0
  18. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +19 -13
  19. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.d.ts +3 -1
  20. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +17 -2
  21. package/lib/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.d.ts +11 -3
  22. package/lib/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.js +35 -1
  23. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.d.ts +8 -2
  24. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +27 -3
  25. package/lib/src/brand-page/components/page/Page.mixin.d.ts +5 -2
  26. package/lib/src/brand-page/components/page/Page.mixin.js +33 -27
  27. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.d.ts +7 -2
  28. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.js +21 -1
  29. package/lib/src/brand-page/components/payment/Payment.mixin.d.ts +5 -2
  30. package/lib/src/brand-page/components/payment/Payment.mixin.js +22 -2
  31. package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.d.ts +6 -2
  32. package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.js +32 -1
  33. package/lib/src/brand-page/components/social-links/SocialLinks.stories.js +0 -3
  34. package/lib/src/brand-page/components/testimonial-section/__fixtures__/data.js +0 -3
  35. package/lib/src/brand-page/components/text/Text.stories.js +0 -17
  36. package/lib/src/brand-page/constants/font.constants.d.ts +62 -0
  37. package/lib/src/brand-page/constants/font.constants.js +35 -0
  38. package/lib/src/brand-page/models/brand-page-context.model.d.ts +2 -0
  39. package/lib/src/brand-page/models/brand-page-context.model.js +7 -0
  40. package/lib/src/brand-page/models/index.d.ts +23 -24
  41. package/lib/src/brand-page/models/index.js +20 -7
  42. package/lib/src/brand-page/models/navigation-styles.model.d.ts +1 -1
  43. package/lib/src/brand-page/models/navigation-styles.model.js +17 -8
  44. package/lib/src/brand-page/models/payment.model.d.ts +11 -6
  45. package/lib/src/brand-page/models/styles.model.d.ts +53 -7
  46. package/lib/src/brand-page/models/styles.model.js +115 -27
  47. package/lib/src/brand-page/utils/color-palette.util.d.ts +43 -23
  48. package/lib/src/brand-page/utils/color-palette.util.js +65 -27
  49. package/lib/src/brand-page/utils/color.util.d.ts +13 -9
  50. package/lib/src/brand-page/utils/color.util.js +56 -15
  51. package/lib/src/brand-page/utils/container-text-color.util.d.ts +46 -13
  52. package/lib/src/brand-page/utils/container-text-color.util.js +321 -41
  53. package/lib/src/brand-page/utils/index.d.ts +1 -0
  54. package/lib/src/brand-page/utils/index.js +1 -0
  55. package/lib/src/brand-page/utils/migration/migration-20.js +6 -2
  56. package/lib/src/brand-page/utils/migration/migration-21.js +34 -6
  57. package/lib/src/brand-page/utils/migration/migration-22.d.ts +99 -0
  58. package/lib/src/brand-page/utils/migration/migration-22.js +909 -0
  59. package/lib/src/brand-page/utils/migration.util.js +17 -0
  60. package/lib/src/brand-page/utils/model.util.d.ts +4 -0
  61. package/lib/src/brand-page/utils/model.util.js +4 -0
  62. package/lib/src/brand-page/utils/personalisation.util.js +9 -1
  63. package/lib/src/brand-page/utils/rte-role-lift.util.d.ts +72 -0
  64. package/lib/src/brand-page/utils/rte-role-lift.util.js +275 -0
  65. package/lib/src/brand-page/utils/style.util.d.ts +5 -1
  66. package/lib/src/brand-page/utils/style.util.js +34 -11
  67. package/lib/src/brand-page/utils/text-role-css.util.d.ts +19 -0
  68. package/lib/src/brand-page/utils/text-role-css.util.js +186 -0
  69. package/lib/src/brand-page/utils/text-role-reconnect.util.d.ts +90 -0
  70. package/lib/src/brand-page/utils/text-role-reconnect.util.js +434 -0
  71. package/lib/src/brand-page/utils/text-style.util.d.ts +53 -23
  72. package/lib/src/brand-page/utils/text-style.util.js +122 -22
  73. package/lib/src/brand-page/utils/view-model.util.d.ts +9 -1
  74. package/lib/src/brand-page/utils/view-model.util.js +124 -111
  75. package/lib/src/brand-page/view-models.d.ts +1 -0
  76. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +4 -1
  77. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +34 -2
  78. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +4 -4
  79. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +4 -1
  80. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -10
  81. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.js +0 -1
  82. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +44 -138
  83. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.js +0 -28
  84. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +4 -1
  85. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +1 -1
  86. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +7 -0
  87. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +21 -0
  88. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +25 -1
  89. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +25 -1
  90. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +21 -0
  91. package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +4 -1
  92. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +25 -1
  93. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +21 -0
  94. package/lib/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.d.ts +10 -0
  95. package/lib/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.js +11 -0
  96. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
  97. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
  98. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +14 -0
  99. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.d.ts +16 -0
  100. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.js +61 -0
  101. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.d.ts +11 -0
  102. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.js +236 -0
  103. package/lib/src/brand-page-maker/composables/rich-text-editor/font.d.ts +2 -1
  104. package/lib/src/brand-page-maker/composables/rich-text-editor/font.js +25 -6
  105. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.d.ts +17 -4
  106. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.js +204 -17
  107. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.d.ts +1 -1
  108. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.js +29 -31
  109. package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.d.ts +20 -0
  110. package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.js +60 -0
  111. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.d.ts +2 -1
  112. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.js +22 -6
  113. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +10 -4
  114. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +319 -275
  115. package/lib/src/brand-page-maker/constants/config-settings-constant.js +1 -5
  116. package/lib/src/brand-page-maker/convertors/text-css-style-options.convertor.js +6 -2
  117. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.d.ts +1 -1
  118. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
  119. package/lib/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.js +7 -14
  120. package/lib/src/brand-page-maker/default-getters/text-color.default-getter.js +6 -13
  121. package/lib/src/brand-page-maker/models/content-settings.d.ts +8 -0
  122. package/lib/src/brand-page-maker/models/content-settings.js +112 -81
  123. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.d.ts +2 -2
  124. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.js +5 -2
  125. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.js +4 -3
  126. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +1257 -117
  127. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +9 -2
  128. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.js +20 -0
  129. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +21 -0
  130. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +6 -1
  131. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +17 -9
  132. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +59 -5
  133. package/lib/src/brand-page-maker/stores/history/history-store.js +22 -2
  134. package/lib/src/brand-page-maker/utils/apply-color-strategy.js +26 -8
  135. package/lib/src/brand-page-maker/utils/index.d.ts +2 -1
  136. package/lib/src/brand-page-maker/utils/index.js +2 -1
  137. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +117 -15
  138. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +435 -281
  139. package/lib/src/brand-page-maker/utils/rte-authoring.util.d.ts +4 -0
  140. package/lib/src/brand-page-maker/utils/rte-authoring.util.js +101 -0
  141. package/lib/src/brand-page-maker/utils/rte-clipboard.util.d.ts +126 -0
  142. package/lib/src/brand-page-maker/utils/rte-clipboard.util.js +307 -0
  143. package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +13 -3
  144. package/lib/src/{bundled-translations-zfiA5Tsw.js → bundled-translations-yGrvPE5i.js} +17 -17
  145. package/lib/src/{bundled-translations.de-DE-ChsdSyAP.js → bundled-translations.de-DE-L4Znf8Hs.js} +17 -17
  146. package/lib/src/{bundled-translations.es-ES-DflsWQK0.js → bundled-translations.es-ES-D6iticrK.js} +15 -15
  147. package/lib/src/{bundled-translations.fr-CA-fpDRuZ52.js → bundled-translations.fr-CA-BgAVE-9k.js} +25 -25
  148. package/lib/src/{bundled-translations.fr-FR-Bub73Zt-.js → bundled-translations.fr-FR-B8GbyqxQ.js} +17 -17
  149. package/lib/src/{bundled-translations.pt-BR-BlnWE9TB.js → bundled-translations.pt-BR-DjPU3Db7.js} +25 -25
  150. package/lib/src/{bundled-translations.pt-PT-DmzXlnaS.js → bundled-translations.pt-PT-BaepaDpr.js} +23 -23
  151. package/lib/src/bundles/bundled-translations.de-DE.json +21 -2
  152. package/lib/src/bundles/bundled-translations.es-ES.json +21 -2
  153. package/lib/src/bundles/bundled-translations.fr-CA.json +21 -2
  154. package/lib/src/bundles/bundled-translations.fr-FR.json +21 -2
  155. package/lib/src/bundles/bundled-translations.json +21 -2
  156. package/lib/src/bundles/bundled-translations.pt-BR.json +21 -2
  157. package/lib/src/bundles/bundled-translations.pt-PT.json +21 -2
  158. package/lib/src/clients/ai-assistant-client.d.ts +7 -1
  159. package/lib/src/clients/ai-assistant-client.js +7 -15
  160. package/lib/src/composables/useTranslate.d.ts +1 -1
  161. package/lib/src/composables/useTranslate.js +1 -1
  162. package/lib/src/css/library.brand-page-brandCrowd.min.css +284 -188
  163. package/lib/src/css/library.brand-page-brandPage.min.css +284 -188
  164. package/lib/src/css/library.brand-page-designCom.min.css +284 -188
  165. package/lib/src/css/library.brand-page-preview.min.css +284 -188
  166. package/lib/src/index.d.ts +2 -1
  167. package/lib/src/index.mjs +195 -191
  168. package/lib/src/{lib-7gtW85nE.js → lib-kGRlD3_P.js} +39082 -36131
  169. package/lib/src/lib.js +2 -1
  170. package/lib/src/metadata-builder/builders/footer-builder.js +4 -5
  171. package/lib/src/metadata-builder/builders/global-role-propagation.d.ts +58 -0
  172. package/lib/src/metadata-builder/builders/global-role-propagation.js +246 -0
  173. package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +1 -0
  174. package/lib/src/metadata-builder/builders/global-styles-builder.js +116 -45
  175. package/lib/src/metadata-builder/builders/header-builder.js +13 -4
  176. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -3
  177. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -3
  178. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -3
  179. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -4
  180. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -3
  181. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -2
  182. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -2
  183. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -4
  184. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -3
  185. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +8 -2
  186. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -2
  187. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +60 -29
  188. package/lib/src/metadata-builder/builders/section-field-maps.js +1 -0
  189. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +48 -19
  190. package/lib/src/metadata-builder/builders/section-field-utils.js +128 -52
  191. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +4 -2
  192. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +28 -12
  193. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +5 -1
  194. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +1 -1
  195. package/lib/src/metadata-builder/helpers/rte.helpers.js +97 -40
  196. package/lib/src/metadata-builder/metadata-executor.js +23 -1
  197. package/lib/src/metadata-builder/models.d.ts +2 -0
  198. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +18 -19
  199. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +18 -1
  200. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +1 -1
  201. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +0 -1
  202. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +5 -8
  203. package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +7 -16
  204. package/lib/src/metadata-builder/sanitizers/section-args-validator.js +95 -22
  205. package/lib/src/shared/color-palette/section-color-matches.js +9 -25
  206. package/lib/src/shared/color-strategies/color-strategies.d.ts +15 -0
  207. package/lib/src/shared/color-strategies/color-strategies.js +31 -0
  208. package/lib/src/shared/color-strategies/rte-color.d.ts +8 -0
  209. package/lib/src/shared/color-strategies/rte-color.js +16 -0
  210. package/lib/src/shared/color-strategies/rte-field-pairs.d.ts +23 -0
  211. package/lib/src/shared/color-strategies/rte-field-pairs.js +28 -0
  212. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +9 -135
  213. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +1 -27
  214. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +12 -2
  215. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +7 -0
  216. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +75 -6
  217. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +18 -7
  218. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +6 -1
  219. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +0 -7
  220. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +22 -0
  221. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +8 -4
  222. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +1255 -26
  223. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.js +203 -59
  224. package/lib/src/shared/content-settings/store/content-settings-store.d.ts +6 -0
  225. package/lib/src/shared/content-settings/store/content-settings-store.js +105 -8
  226. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +26 -1
  227. package/lib/src/shared/navigation-style-settings/store/index.d.ts +7 -3
  228. package/lib/src/shared/navigation-style-settings/store/index.js +40 -15
  229. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +1 -0
  230. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +38 -5
  231. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +91 -13
  232. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +10 -2
  233. package/lib/src/shared/page-settings/store/page-settings-store.d.ts +2 -1
  234. package/lib/src/shared/page-settings/store/page-settings-store.js +17 -0
  235. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +32 -1
  236. package/lib/src/shared/rte-extensions/AutoLink.d.ts +17 -0
  237. package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.js +67 -51
  238. package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.js +4 -1
  239. package/lib/src/shared/rte-extensions/TextEffects.d.ts +28 -0
  240. package/lib/src/shared/rte-extensions/TextEffects.js +96 -0
  241. package/lib/src/shared/rte-extensions/ViewDomParser.d.ts +2 -0
  242. package/lib/src/shared/rte-extensions/ViewDomParser.js +21 -0
  243. package/lib/src/shared/rte-extensions.util.d.ts +25 -0
  244. package/lib/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.js → shared/rte-extensions.util.js} +62 -7
  245. package/lib/src/shared/rte-link.util.d.ts +1 -0
  246. package/lib/src/shared/rte-link.util.js +1 -0
  247. package/lib/src/shared/rte-render.util.d.ts +112 -0
  248. package/lib/src/shared/rte-render.util.js +255 -0
  249. package/lib/src/shared/rte-shape.util.d.ts +6 -0
  250. package/lib/src/shared/rte-shape.util.js +18 -0
  251. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +23 -1
  252. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +1 -0
  253. package/lib/src/shared/side-bar/store/side-bar-store.d.ts +2 -0
  254. package/lib/src/shared/side-bar/store/side-bar-store.js +9 -0
  255. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +176 -15
  256. package/lib/src/shared/style-settings/components/StyleSettings.mixin.js +7 -1
  257. package/lib/src/shared/style-settings/store/style-settings-store.d.ts +1 -9
  258. package/lib/src/shared/style-settings/store/style-settings-store.js +3 -33
  259. package/lib/src/shared/style-settings/text-style-size-order.d.ts +2 -0
  260. package/lib/src/shared/style-settings/text-style-size-order.js +13 -0
  261. package/lib/src/shared/text-role-typography.util.d.ts +64 -0
  262. package/lib/src/shared/text-role-typography.util.js +183 -0
  263. package/lib/src/utils/minify-brand-page-metadata.d.ts +16 -1
  264. package/lib/src/utils/minify-brand-page-metadata.js +31 -9
  265. package/package.json +1 -1
  266. package/src/brand-page/__fixtures__/migration-22-v21/edited-brandsite-sections.v21.json +982 -0
  267. package/src/brand-page/__fixtures__/migration-22-v21/new-brandcontact-every-section.v21.json +1231 -0
  268. package/src/brand-page/__fixtures__/migration-22-v21/new-brandpage-every-section.v21.json +1231 -0
  269. package/src/brand-page/__fixtures__/migration-22-v21/new-brandsite-every-section.v21.json +1243 -0
  270. package/src/brand-page/__fixtures__/migration-22-v21/real-brandcontact.v21.json +755 -0
  271. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-general-link.v21.json +527 -0
  272. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-links.v21.json +755 -0
  273. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-social-links.v21.json +514 -0
  274. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-about.v21.json +459 -0
  275. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-footer.v21.json +469 -0
  276. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-header-banner.v21.json +481 -0
  277. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-sections.v21.json +800 -0
  278. package/src/brand-page/__fixtures__/production-text-style-resolver.fixture.ts +52 -0
  279. package/src/brand-page/components/about-section/AboutSection.vue.test.ts +0 -10
  280. package/src/brand-page/components/contact-form/ContactForm.mixin.test.ts +127 -0
  281. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +31 -14
  282. package/src/brand-page/components/contact-form/ContactForm.vue +26 -12
  283. package/src/brand-page/components/contact-form/ContactForm.vue.test.ts +60 -0
  284. package/src/brand-page/components/mailing-list/MailingList.mixin.test.ts +92 -0
  285. package/src/brand-page/components/mailing-list/MailingList.mixin.ts +28 -3
  286. package/src/brand-page/components/mailing-list/MailingList.vue +9 -4
  287. package/src/brand-page/components/mailing-list/MailingList.vue.test.ts +63 -0
  288. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.ts +51 -1
  289. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.test.ts +114 -0
  290. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.vue +8 -2
  291. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.test.ts +182 -0
  292. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.vue +58 -12
  293. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +40 -3
  294. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue +15 -7
  295. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue.test.ts +133 -3
  296. package/src/brand-page/components/page/Page.mixin.ts +41 -34
  297. package/src/brand-page/components/page/Page.vue +17 -6
  298. package/src/brand-page/components/page/Page.vue.test.ts +91 -1
  299. package/src/brand-page/components/page-footer/PageFooter.mixin.ts +32 -2
  300. package/src/brand-page/components/page-footer/PageFooter.test.ts +79 -0
  301. package/src/brand-page/components/page-footer/PageFooter.vue +12 -4
  302. package/src/brand-page/components/payment/Payment.mixin.ts +34 -2
  303. package/src/brand-page/components/payment/Payment.test.ts +188 -0
  304. package/src/brand-page/components/payment/Payment.vue +12 -5
  305. package/src/brand-page/components/payment/RequestPaymentStripe.vue +1 -0
  306. package/src/brand-page/components/payment/support-me/SupportMe.mixin.ts +49 -2
  307. package/src/brand-page/components/payment/support-me/SupportMe.test.ts +100 -0
  308. package/src/brand-page/components/payment/support-me/SupportMe.vue +7 -1
  309. package/src/brand-page/components/payment/support-me/SupportMe.vue.test.ts +66 -0
  310. package/src/brand-page/components/save-contact/SaveContactWidget.test.ts +100 -0
  311. package/src/brand-page/components/save-contact/SaveContactWidget.vue +6 -3
  312. package/src/brand-page/components/shop/PaymentModal.vue +2 -6
  313. package/src/brand-page/components/shop/PaymentShippingAddress.vue +6 -0
  314. package/src/brand-page/components/shop/Shop.vue +15 -2
  315. package/src/brand-page/components/shop/Shop.vue.test.ts +74 -2
  316. package/src/brand-page/components/social-links/SocialLinks.stories.ts +0 -3
  317. package/src/brand-page/components/social-links/SocialLinks.vue.test.ts +0 -3
  318. package/src/brand-page/components/testimonial-section/__fixtures__/data.ts +0 -3
  319. package/src/brand-page/components/text/Text.stories.ts +0 -17
  320. package/src/brand-page/components/text-wrapper/TextWrapper.parity.test.ts +136 -0
  321. package/src/brand-page/components/text-wrapper/TextWrapper.test.ts +358 -0
  322. package/src/brand-page/components/text-wrapper/TextWrapper.vue +82 -22
  323. package/src/brand-page/constants/font.constants.ts +37 -0
  324. package/src/brand-page/models/brand-page-context.model.ts +13 -0
  325. package/src/brand-page/models/footer-icon-color.test.ts +22 -0
  326. package/src/brand-page/models/index.ts +50 -28
  327. package/src/brand-page/models/navigation-styles.model.test.ts +77 -1
  328. package/src/brand-page/models/navigation-styles.model.ts +26 -9
  329. package/src/brand-page/models/payment.model.ts +15 -6
  330. package/src/brand-page/models/styles.model.test.ts +104 -0
  331. package/src/brand-page/models/styles.model.ts +181 -47
  332. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +619 -115
  333. package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +150 -9
  334. package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +300 -18
  335. package/src/brand-page/utils/color-palette.util.test.ts +126 -1
  336. package/src/brand-page/utils/color-palette.util.ts +92 -26
  337. package/src/brand-page/utils/color.util.test.ts +62 -29
  338. package/src/brand-page/utils/color.util.ts +77 -14
  339. package/src/brand-page/utils/container-text-color.util.test.ts +672 -26
  340. package/src/brand-page/utils/container-text-color.util.ts +472 -46
  341. package/src/brand-page/utils/index.ts +1 -0
  342. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/edited-brandsite-sections.v22.json +1191 -0
  343. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandcontact-every-section.v22.json +2026 -0
  344. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandpage-every-section.v22.json +2017 -0
  345. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandsite-every-section.v22.json +2031 -0
  346. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandcontact.v22.json +1145 -0
  347. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-general-link.v22.json +645 -0
  348. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-links.v22.json +1136 -0
  349. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-social-links.v22.json +662 -0
  350. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-about.v22.json +638 -0
  351. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-footer.v22.json +610 -0
  352. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-header-banner.v22.json +660 -0
  353. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-sections.v22.json +1132 -0
  354. package/src/brand-page/utils/migration/migration-01.ts +293 -237
  355. package/src/brand-page/utils/migration/migration-02.ts +8 -1
  356. package/src/brand-page/utils/migration/migration-20.ts +6 -3
  357. package/src/brand-page/utils/migration/migration-20_5.test.ts +5 -2
  358. package/src/brand-page/utils/migration/migration-21.test.ts +34 -0
  359. package/src/brand-page/utils/migration/migration-21.ts +46 -10
  360. package/src/brand-page/utils/migration/migration-22.fixed-input.test.ts +43 -0
  361. package/src/brand-page/utils/migration/migration-22.test.ts +4103 -0
  362. package/src/brand-page/utils/migration/migration-22.text-font-family.test.ts +72 -0
  363. package/src/brand-page/utils/migration/migration-22.ts +1336 -0
  364. package/src/brand-page/utils/migration.util.test.ts +146 -32
  365. package/src/brand-page/utils/migration.util.ts +18 -0
  366. package/src/brand-page/utils/model.util.ts +4 -0
  367. package/src/brand-page/utils/personalisation.util.test.ts +148 -3
  368. package/src/brand-page/utils/personalisation.util.ts +9 -1
  369. package/src/brand-page/utils/rte-role-lift.util.ts +409 -0
  370. package/src/brand-page/utils/style.util.test.ts +35 -2
  371. package/src/brand-page/utils/style.util.ts +45 -11
  372. package/src/brand-page/utils/text-role-css.util.test.ts +525 -0
  373. package/src/brand-page/utils/text-role-css.util.ts +321 -0
  374. package/src/brand-page/utils/text-role-reconnect.util.test.ts +604 -0
  375. package/src/brand-page/utils/text-role-reconnect.util.ts +727 -0
  376. package/src/brand-page/utils/text-style.util.test.ts +305 -0
  377. package/src/brand-page/utils/text-style.util.ts +198 -24
  378. package/src/brand-page/utils/view-model.page-data.test.ts +232 -0
  379. package/src/brand-page/utils/view-model.util.test.ts +954 -133
  380. package/src/brand-page/utils/view-model.util.ts +187 -139
  381. package/src/brand-page/view-models.ts +4 -0
  382. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.blank-site.test.ts +57 -0
  383. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +9 -5
  384. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -10
  385. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.ts +0 -1
  386. package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.ts +0 -44
  387. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +253 -200
  388. package/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.test.ts +82 -0
  389. package/src/brand-page-maker/composables/ai-chat/ai-builder-experiment.ts +19 -0
  390. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +2 -0
  391. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +19 -0
  392. package/src/brand-page-maker/composables/rich-text-editor/block-typography.test.ts +519 -0
  393. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +1 -1
  394. package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.test.ts +26 -1
  395. package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.test.ts +110 -0
  396. package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.ts +99 -0
  397. package/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.ts +397 -0
  398. package/src/brand-page-maker/composables/rich-text-editor/extensions/ViewDomParser.test.ts +139 -0
  399. package/src/brand-page-maker/composables/rich-text-editor/font.ts +36 -5
  400. package/src/brand-page-maker/composables/rich-text-editor/formatting.test.ts +375 -1
  401. package/src/brand-page-maker/composables/rich-text-editor/formatting.ts +301 -17
  402. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.test.ts +82 -1
  403. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.ts +28 -34
  404. package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.test.ts +80 -0
  405. package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.ts +75 -0
  406. package/src/brand-page-maker/composables/rich-text-editor/spacing.ts +31 -6
  407. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.test.ts +2485 -0
  408. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +435 -337
  409. package/src/brand-page-maker/constants/config-settings-constant.ts +0 -6
  410. package/src/brand-page-maker/convertors/text-css-style-options.convertor.test.ts +43 -0
  411. package/src/brand-page-maker/convertors/text-css-style-options.convertor.ts +6 -2
  412. package/src/brand-page-maker/convertors/text-size-value.convertor.test.ts +24 -0
  413. package/src/brand-page-maker/convertors/text-size-value.convertor.ts +17 -13
  414. package/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.ts +7 -22
  415. package/src/brand-page-maker/default-getters/text-color.default-getter.ts +5 -21
  416. package/src/brand-page-maker/models/content-settings.test.ts +708 -0
  417. package/src/brand-page-maker/models/content-settings.ts +133 -82
  418. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.test.ts +63 -1
  419. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.ts +16 -3
  420. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.test.ts +34 -0
  421. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.ts +4 -2
  422. package/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.ts +30 -0
  423. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +185 -1
  424. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +22 -34
  425. package/src/brand-page-maker/stores/history/history-store.ts +35 -2
  426. package/src/brand-page-maker/utils/__snapshots__/apply-color-strategy.golden.test.ts.snap +528 -0
  427. package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +12 -0
  428. package/src/brand-page-maker/utils/apply-color-strategy.golden.test.ts +2 -0
  429. package/src/brand-page-maker/utils/apply-color-strategy.test.ts +181 -3
  430. package/src/brand-page-maker/utils/apply-color-strategy.ts +36 -4
  431. package/src/brand-page-maker/utils/index.ts +2 -1
  432. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +447 -410
  433. package/src/brand-page-maker/utils/rich-text-editor.util.ts +610 -506
  434. package/src/brand-page-maker/utils/rte-authoring.util.test.ts +244 -0
  435. package/src/brand-page-maker/utils/rte-authoring.util.ts +175 -0
  436. package/src/brand-page-maker/utils/rte-clipboard.util.test.ts +558 -0
  437. package/src/brand-page-maker/utils/rte-clipboard.util.ts +473 -0
  438. package/src/brand-page-maker/utils/rte-features.test.ts +99 -3
  439. package/src/brand-page-maker/utils/rte-render-parity.test.ts +1 -1
  440. package/src/brand-page-maker/utils/rte-render.util.test.ts +230 -0
  441. package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +1 -1
  442. package/src/brand-page-maker/utils/rte-sanitize.util.ts +14 -3
  443. package/src/brand-page-maker/utils/rte-schema-version.test.ts +102 -0
  444. package/src/bundles/bundled-translations.de-DE.json +21 -2
  445. package/src/bundles/bundled-translations.es-ES.json +21 -2
  446. package/src/bundles/bundled-translations.fr-CA.json +21 -2
  447. package/src/bundles/bundled-translations.fr-FR.json +21 -2
  448. package/src/bundles/bundled-translations.json +21 -2
  449. package/src/bundles/bundled-translations.pt-BR.json +21 -2
  450. package/src/bundles/bundled-translations.pt-PT.json +21 -2
  451. package/src/clients/ai-assistant-client.ts +13 -18
  452. package/src/composables/useTranslate.ts +2 -1
  453. package/src/lib.ts +2 -2
  454. package/src/metadata-builder/builders/footer-builder.test.ts +70 -45
  455. package/src/metadata-builder/builders/footer-builder.ts +4 -8
  456. package/src/metadata-builder/builders/global-role-propagation.test.ts +907 -0
  457. package/src/metadata-builder/builders/global-role-propagation.ts +430 -0
  458. package/src/metadata-builder/builders/global-styles-builder.test.ts +1020 -0
  459. package/src/metadata-builder/builders/global-styles-builder.ts +194 -48
  460. package/src/metadata-builder/builders/header-builder.test.ts +112 -40
  461. package/src/metadata-builder/builders/header-builder.ts +18 -8
  462. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +5 -3
  463. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +5 -3
  464. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -3
  465. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +7 -4
  466. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +5 -3
  467. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +3 -2
  468. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +3 -2
  469. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +7 -7
  470. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +5 -3
  471. package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +2 -2
  472. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +21 -10
  473. package/src/metadata-builder/builders/section-builders/support-me-builder.test.ts +10 -0
  474. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +3 -2
  475. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +111 -61
  476. package/src/metadata-builder/builders/section-field-maps.ts +1 -0
  477. package/src/metadata-builder/builders/section-field-utils.test.ts +545 -2
  478. package/src/metadata-builder/builders/section-field-utils.ts +202 -69
  479. package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +38 -13
  480. package/src/metadata-builder/builders/section-rules/social-links.rules.ts +5 -0
  481. package/src/metadata-builder/helpers/rte.helpers.test.ts +101 -0
  482. package/src/metadata-builder/helpers/rte.helpers.ts +129 -43
  483. package/src/metadata-builder/metadata-executor.test.ts +167 -0
  484. package/src/metadata-builder/metadata-executor.ts +34 -1
  485. package/src/metadata-builder/models.ts +2 -0
  486. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +23 -7
  487. package/src/metadata-builder/parsers/section-tool-arguments.ts +21 -1
  488. package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +215 -0
  489. package/src/metadata-builder/sanitizers/rte-schema-check.ts +1 -1
  490. package/src/metadata-builder/sanitizers/sanitizer-rules.ts +4 -8
  491. package/src/metadata-builder/sanitizers/section-args-validator.ts +136 -53
  492. package/src/shared/color-palette/section-color-matches.test.ts +15 -11
  493. package/src/shared/color-palette/section-color-matches.ts +9 -28
  494. package/src/shared/color-strategies/color-strategies.ts +35 -0
  495. package/src/shared/color-strategies/rte-color.test.ts +1 -1
  496. package/src/shared/color-strategies/rte-color.ts +19 -0
  497. package/src/shared/color-strategies/rte-field-pairs.test.ts +26 -5
  498. package/src/shared/color-strategies/rte-field-pairs.ts +33 -0
  499. package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.test.ts +43 -66
  500. package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.vue +7 -1
  501. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +1 -48
  502. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +33 -7
  503. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.test.ts +128 -1
  504. package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +0 -6
  505. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.test.ts +56 -3
  506. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +11 -4
  507. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.test.ts +335 -25
  508. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.ts +248 -70
  509. package/src/shared/content-settings/components/text-style-field/TextStyleField.vue +113 -25
  510. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.de-DE.json +17 -10
  511. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.es-ES.json +17 -10
  512. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-CA.json +17 -10
  513. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-FR.json +17 -10
  514. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.json +8 -1
  515. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-BR.json +17 -10
  516. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-PT.json +17 -10
  517. package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.test.ts +141 -0
  518. package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.vue +136 -0
  519. package/src/shared/content-settings/store/content-settings-store.test.ts +491 -6
  520. package/src/shared/content-settings/store/content-settings-store.ts +159 -17
  521. package/src/shared/navigation-style-settings/store/index.test.ts +295 -0
  522. package/src/shared/navigation-style-settings/store/index.ts +65 -15
  523. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.test.ts +44 -4
  524. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.vue +13 -4
  525. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.navigation.test.ts +89 -0
  526. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.text-style.test.ts +91 -0
  527. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +14 -2
  528. package/src/shared/page-settings/store/page-settings-store.text-style.test.ts +84 -0
  529. package/src/shared/page-settings/store/page-settings-store.ts +30 -1
  530. package/src/shared/rte-extensions/AutoLink.test.ts +98 -0
  531. package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.ts +87 -58
  532. package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.ts +4 -1
  533. package/src/shared/rte-extensions/TextEffects.ts +151 -0
  534. package/src/shared/rte-extensions/ViewDomParser.ts +27 -0
  535. package/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.ts → shared/rte-extensions.util.ts} +66 -9
  536. package/src/shared/rte-link.util.ts +2 -0
  537. package/src/shared/rte-render.util.ts +385 -0
  538. package/src/shared/rte-shape.util.ts +29 -0
  539. package/src/shared/side-bar/store/side-bar-store.test.ts +27 -1
  540. package/src/shared/side-bar/store/side-bar-store.ts +11 -0
  541. package/src/shared/style-settings/components/StyleSettings.mixin.ts +7 -3
  542. package/src/shared/style-settings/components/StyleSettings.test.ts +116 -0
  543. package/src/shared/style-settings/components/StyleSettings.vue +74 -25
  544. package/src/shared/style-settings/components/i18n/style-settings.de-DE.json +32 -20
  545. package/src/shared/style-settings/components/i18n/style-settings.es-ES.json +32 -20
  546. package/src/shared/style-settings/components/i18n/style-settings.fr-CA.json +32 -20
  547. package/src/shared/style-settings/components/i18n/style-settings.fr-FR.json +32 -20
  548. package/src/shared/style-settings/components/i18n/style-settings.json +13 -3
  549. package/src/shared/style-settings/components/i18n/style-settings.pt-BR.json +32 -20
  550. package/src/shared/style-settings/components/i18n/style-settings.pt-PT.json +32 -20
  551. package/src/shared/style-settings/components/text-style-options-settings-with-state/TextStyleOptionsSettingsWithState.vue +14 -34
  552. package/src/shared/style-settings/store/style-settings-store.ts +3 -49
  553. package/src/shared/style-settings/text-style-size-order.test.ts +76 -0
  554. package/src/shared/style-settings/text-style-size-order.ts +28 -0
  555. package/src/shared/text-role-typography.util.ts +277 -0
  556. package/src/utils/minify-brand-page-metadata.test.ts +102 -7
  557. package/src/utils/minify-brand-page-metadata.ts +62 -8
  558. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.d.ts +0 -2
  559. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
  560. package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -63
  561. package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -106
  562. package/lib/src/brand-page-maker/utils/rte-shape.d.ts +0 -18
  563. package/lib/src/brand-page-maker/utils/rte-shape.js +0 -21
  564. package/lib/src/metadata-builder/builders/global-font-propagation.d.ts +0 -41
  565. package/lib/src/metadata-builder/builders/global-font-propagation.js +0 -146
  566. package/src/brand-page/models/brand-page-context.model.test.ts +0 -38
  567. package/src/brand-page-maker/utils/rte-render.util.ts +0 -179
  568. package/src/brand-page-maker/utils/rte-shape.ts +0 -29
  569. package/src/clients/ai-assistant-client.test.ts +0 -135
  570. package/src/metadata-builder/builders/global-font-propagation.test.ts +0 -401
  571. package/src/metadata-builder/builders/global-font-propagation.ts +0 -238
  572. package/src/shared/style-settings/components/StyleSettingsSection.vue +0 -8
  573. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.d.ts +0 -0
  574. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.js +0 -0
  575. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.d.ts +0 -0
  576. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.js +0 -0
  577. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.d.ts +0 -0
  578. /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.ts +0 -0
  579. /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.ts +0 -0
@@ -1,8 +1,13 @@
1
+ /**
2
+ * MIGRATION-22 SNAPSHOT DEPENDENCY: its colour bake reaches `backgroundColorFromStyle`,
3
+ * `isTransparentColour` and `isHexTransparent` through `container-text-color.util.ts`. After
4
+ * migration-22 releases, pin their v22 behaviour in the migration before changing them.
5
+ */
1
6
  import isHexColor from 'validator/lib/isHexColor';
2
7
  import { hexToRGBA, RGBAtoHex } from '@src/utils/helpers';
3
8
  // Leaf module, not the `@brand-page/utils` barrel — the barrel's larger graph races
4
9
  // module init and these come back undefined under some import orders.
5
- import { bestContrastBrandRole, resolveColorReference, toColorVarReference, } from './color-palette.util';
10
+ import { bestContrastBrandRole, resolveColorReference, toColorVarReference, PALETTE_COLOR_IDS, STRATEGY_COPY_MIN_CONTRAST, } from './color-palette.util';
6
11
  import Color, {} from 'color';
7
12
  // function from https://stackoverflow.com/a/9733420/3695983
8
13
  export const luminance = (r, g, b) => {
@@ -183,23 +188,59 @@ export const mutedTextForBackground = (bgColor, { targetContrast = 3.5, start =
183
188
  // both. The value may be a gradient/shorthand; callers that need a solid colour
184
189
  // pass it through mutedTextForBackground, which rejects anything unparseable.
185
190
  export const backgroundColorFromStyle = (style) => style?.backgroundColor || style?.background;
191
+ // A solid, fully-opaque hex from any parseable colour, else undefined (transparent,
192
+ // gradient, image, `var(--…)`, unparseable) — so a contrast check only runs against a real
193
+ // surface.
194
+ const solidHex = (value) => {
195
+ if (!value) {
196
+ return undefined;
197
+ }
198
+ try {
199
+ const parsed = Color(value);
200
+ return parsed.alpha() === 1 ? parsed.hex() : undefined;
201
+ }
202
+ catch {
203
+ return undefined;
204
+ }
205
+ };
186
206
  /**
187
- * The nav "theme" for a display-type switch: the base colour the caller passes (kept
188
- * verbatim, incl. its palette `var(--id)` reference) plus the contrasting palette-role
189
- * reference to pair with it — e.g. a TAB_2 selected button paints its background with
190
- * `primaryColor` and its label with `secondaryColor`.
207
+ * The nav "theme" for a header nav display-type switch. Nav themes off the LOGO, independently
208
+ * of the page's button styling (ADR-0022): `primaryColor` — the dominant nav colour used for
209
+ * default text, border and the selected button's fill — is the first brand role that stays
210
+ * legible (>= `STRATEGY_COPY_MIN_CONTRAST`) on the header background: logo text colour
211
+ * (`palette-0`), else logo background colour (`palette-1`), else a generated neutral.
212
+ * `secondaryColor` — the selected button's label — is the brand role that best contrasts
213
+ * `primaryColor` (`bestContrastBrandRole`), so the label reads on the filled pill
214
+ * ("encapsulated contrast").
191
215
  *
192
- * `secondaryColor` is a palette-role reference, not a resolved literal, so the label
193
- * keeps tracking palette edits. It is the brand role that reads best (WCAG) against the
194
- * base's resolved value; when the palette can't supply one (empty/blank palette) it
195
- * falls back to the base so we never mint an off-palette colour.
216
+ * Brand picks are returned as palette `var(--id)` references so the nav keeps tracking palette
217
+ * edits; only the neutral fallback is a literal. `headerBackgroundColor` is the preferred surface
218
+ * the nav sits on. When it does not paint, `pageBackgroundColor` is the surface visible behind the
219
+ * header; white is the final fallback when neither resolves to a solid colour.
196
220
  */
197
- export const getNavThemeByTextStyle = (textStyle, colors = []) => {
198
- const primaryColor = textStyle.color;
199
- const baseValue = resolveColorReference(primaryColor, colors, {
200
- withRoleDefaults: true,
201
- });
202
- const contrastRole = bestContrastBrandRole(baseValue, colors);
221
+ export const getNavThemeByTextStyle = (headerBackgroundColor, colors = [], pageBackgroundColor) => {
222
+ const logoTextColor = toColorVarReference(PALETTE_COLOR_IDS.primary);
223
+ const logoBackgroundColor = toColorVarReference(PALETTE_COLOR_IDS.secondary);
224
+ const resolvedSurface = (color) => solidHex(resolveColorReference(color ?? '', colors, { withRoleDefaults: true }));
225
+ // A transparent/unset header reveals the page surface. Image and gradient backgrounds have no
226
+ // single contrast anchor, so only then does the historic light fallback apply.
227
+ const surface = resolvedSurface(headerBackgroundColor) ??
228
+ resolvedSurface(pageBackgroundColor) ??
229
+ '#ffffff';
230
+ const clearsOnSurface = (roleRef) => {
231
+ const resolved = solidHex(resolveColorReference(roleRef, colors, { withRoleDefaults: true }));
232
+ return (!!resolved &&
233
+ contrastRatio(Color(resolved), Color(surface)) >=
234
+ STRATEGY_COPY_MIN_CONTRAST);
235
+ };
236
+ const primaryColor = clearsOnSurface(logoTextColor)
237
+ ? logoTextColor
238
+ : clearsOnSurface(logoBackgroundColor)
239
+ ? logoBackgroundColor
240
+ : (mutedTextForBackground(surface, {
241
+ targetContrast: STRATEGY_COPY_MIN_CONTRAST,
242
+ }) ?? logoTextColor);
243
+ const contrastRole = bestContrastBrandRole(resolveColorReference(primaryColor, colors, { withRoleDefaults: true }), colors);
203
244
  return {
204
245
  primaryColor,
205
246
  secondaryColor: contrastRole
@@ -7,9 +7,13 @@
7
7
  * surface they sit on, and what colour they default to, so the renderer
8
8
  * (`view-model.util.ts`) and the maker's Text Style panel cannot disagree — the same
9
9
  * reason `resolveTextColor` lives in one place (`text-style.util.ts`).
10
+ *
11
+ * MIGRATION-22 SNAPSHOT DEPENDENCY: the v21 -> v22 colour bake calls
12
+ * `containerTextColorDefaults` and `titleSurfaceContrastFill`. Pin that migration's behaviour
13
+ * before changing either helper after it releases.
10
14
  */
11
- import type { Content, PageStyles, BrandPageType } from '../models';
12
- import type { ContentTextStylePropertyKey } from '../constants';
15
+ import type { Content, PageStyles, BrandPageType, ColorItem } from '../models';
16
+ import { type ContentTextStylePropertyKey } from '../constants';
13
17
  /**
14
18
  * The text-style fields that sit on the block's filled surface. `buttonTextStyle` is
15
19
  * excluded — it paints the button, which owns its own fill/text pairing.
@@ -29,6 +33,15 @@ export declare const CONTAINER_BOUND_TEXT_STYLE_KEYS: Partial<Record<Content['ty
29
33
  * scope here).
30
34
  */
31
35
  export declare const containerSurfaceForContent: (content: Content, styles: PageStyles, brandPageType?: BrandPageType) => BrandPageCssStyle | undefined;
36
+ /**
37
+ * The colour the maker's Text Style swatch shows for a STANDALONE button's LABEL. The label is left
38
+ * uncoloured on the element (`isButtonLabelField` exempts it from the birth-time bake) and inherits
39
+ * the button's on-fill colour at render via CSS (`buttonStyles.style.color`). The panel has no
40
+ * inherited value to read off the element, so it derives the SAME colour here — the swatch matches
41
+ * the canvas, both from one helper, exactly as `containerTextColorDefaults` feeds the swatch for
42
+ * container-bound fields. `undefined` for a non-label field or a button with no text colour.
43
+ */
44
+ export declare const buttonLabelColorDefault: (content: Content, styles: PageStyles, key: string) => string | undefined;
32
45
  /**
33
46
  * The container-aware default colour for each container-bound text field: the button
34
47
  * text colour (`styles.buttonStyles.style.color`), the theme-authored on-fill colour,
@@ -76,18 +89,38 @@ export declare const containerTextColorDefaults: (content: Content, styles: Page
76
89
  */
77
90
  export declare const rteFrameFallbackColour: (content: Content, styles: PageStyles, brandPageType?: BrandPageType) => string | undefined;
78
91
  /**
79
- * Bakes a readable colour into a container-bound block's text so the renderer just paints
80
- * what's stored (no render-time contrast logic). Run when the block is created and whenever
81
- * its text style changes.
92
+ * The contrast colour for whatever sits on the title's own surface — the one the title itself
93
+ * gets. Two callers: a social-links section's icons (baked once onto `iconFillStyles.fill` at
94
+ * migration or birth, so they never follow a title recolour) and a shop section's "no products"
95
+ * label (read live in the view model, so it does follow one — there's no stored field to freeze).
96
+ */
97
+ export declare const titleSurfaceContrastFill: (content: Content, styles: PageStyles, brandPageType?: BrandPageType) => string | undefined;
98
+ /**
99
+ * Bakes a readable colour into a SECTION's text at BIRTH so the renderer just paints what's
100
+ * stored (no render-time contrast logic). Run when a block is created and whenever its text
101
+ * style changes.
102
+ *
103
+ * Every text field (and every `textItems[]` entry) contrasts the topmost solid thing beneath it —
104
+ * its own field surface, else the section's painted surface, else the PAGE background
105
+ * (`effectiveFieldSurface`) — taking the brand hierarchy on a solid surface and `pageContrastColour`
106
+ * on the bare page (the replacement for the retired base coat, ADR-0020). The exempt fields never
107
+ * bake — the section CTA button label (`buttonTextStyle`) and copyright by key, and a standalone
108
+ * button's own label (`titleStyle` on an `isButtonContent`) by type; all own their fill/text
109
+ * pairing rather than a section surface. A field sitting on the button fill likewise defers to the
110
+ * render-time pairing. A social-links section's icons get their own stored fill
111
+ * (`titleSurfaceContrastFill`).
82
112
  *
83
- * For each container-bound text field with no colour of its own, on a solid surface that is
84
- * NOT the button fill, it writes whichever BRAND role contrasts THAT field's surface most —
85
- * the card for card fields, the option-button fill for `itemTextStyle`
86
- * (`surfaceForTextStyleKey`). A button-fill surface is skipped: its render-time pairing
87
- * (`containerTextColorDefaults`) supplies the button's own text colour, so `itemTextStyle`
88
- * on the default option fill needs no bake. Explicitly-coloured fields are left alone; so is
89
- * a palette with no usable brand role.
113
+ * Explicitly-coloured fields are left alone; so is a palette with no usable role.
90
114
  *
91
115
  * Mutates and returns `content`.
92
116
  */
93
- export declare const applyCardTextContrast: (content: Content, styles: PageStyles, brandPageType?: BrandPageType) => Content;
117
+ export declare const applyTextContrast: (content: Content, styles: PageStyles, brandPageType?: BrandPageType) => Content;
118
+ /**
119
+ * The topmost solid surface painted behind a section's text — the highest-stacked surface
120
+ * field that resolves to a visible solid — or `undefined` when the section paints nothing solid
121
+ * (the text then sits on the page background, `applyTextContrast`'s page branch). A field the
122
+ * section does not actually paint in its current layout is skipped (`isSurfaceFieldPainted`).
123
+ * Palette refs are resolved first (via `isSolidSurface`), so a `var(--palette-N)` fill counts as
124
+ * the solid it resolves to.
125
+ */
126
+ export declare const topmostSolidSurface: (content: Content, colors?: ColorItem[]) => BrandPageCssStyle | undefined;
@@ -1,6 +1,8 @@
1
1
  import { BRAND_PAGE_TYPES } from '../models';
2
+ import { CONTENT_TEXT_STYLE_PROPERTY_KEYS, ALIGN_CARD_CENTER_IMAGE, ALIGN_CARD_LEFT_IMAGE, } from '../constants';
2
3
  import { backgroundColorFromStyle, isTransparentColour, isHexTransparent, } from './color.util';
3
- import { resolveColorReference, bestContrastBrandRole, toColorVarReference, roleValueOrDefault, } from './color-palette.util';
4
+ import { isButtonContent } from './model.util';
5
+ import { resolveColorReference, bestContrastBrandRole, bestContrastNeutralRole, firstViableContrastRole, toColorVarReference, roleValueOrDefault, isBlankColorValue, PALETTE_COLOR_IDS, STRATEGY_COPY_MIN_CONTRAST, } from './color-palette.util';
4
6
  /**
5
7
  * The text-style fields that sit on the block's filled surface. `buttonTextStyle` is
6
8
  * excluded — it paints the button, which owns its own fill/text pairing.
@@ -12,11 +14,17 @@ import { resolveColorReference, bestContrastBrandRole, toColorVarReference, role
12
14
  */
13
15
  export const CONTAINER_BOUND_TEXT_STYLE_KEYS = {
14
16
  'mailing-list': ['titleStyle'],
15
- 'request-payment': ['titleStyle', 'descriptionStyle', 'itemTextStyle'],
17
+ 'request-payment': [
18
+ 'titleStyle',
19
+ 'descriptionStyle',
20
+ 'successMessageStyle',
21
+ 'itemTextStyle',
22
+ ],
16
23
  'support-me': [
17
24
  'titleStyle',
18
25
  'headingStyle',
19
26
  'descriptionStyle',
27
+ 'successMessageStyle',
20
28
  'itemTextStyle',
21
29
  ],
22
30
  'contact-form': ['titleStyle', 'descriptionStyle', 'successMessageStyle'],
@@ -33,6 +41,17 @@ const BUTTON_BOUND_TEXT_STYLE_KEYS = {
33
41
  'request-payment': ['itemTextStyle'],
34
42
  'support-me': ['itemTextStyle'],
35
43
  };
44
+ /**
45
+ * Shop's title and description sit on the band (`backgroundStyle`), never the product
46
+ * tile (`fillColor`) — a sibling surface stacked below them, not behind them. Routed here
47
+ * rather than through `topmostSolidSurface`'s generic top-of-stack scan, which would pick
48
+ * the tile fill first and MIScolour the title against a surface it doesn't sit on.
49
+ */
50
+ const SHOP_BAND_ROUTED_KEYS = new Set([
51
+ 'titleStyle',
52
+ 'descriptionStyle',
53
+ ]);
54
+ const isShopBandRoutedField = (content, key) => content.type === 'shop-section' && SHOP_BAND_ROUTED_KEYS.has(key);
36
55
  /**
37
56
  * The filled surface the block's text sits on: the block's OWN container colour
38
57
  * (`backgroundStyle`, or `cardStyle` for contact-form) when set, else the global
@@ -69,15 +88,59 @@ const optionButtonSurfaceForContent = (content, styles) => {
69
88
  const own = content.fillColor;
70
89
  return backgroundColorFromStyle(own) ? own : styles.buttonStyles?.style;
71
90
  };
91
+ // The button label owns its own fill/text pairing and copyright is page-level — neither
92
+ // contrasts a SECTION surface, so they get no birth-time contrast bake. This is keyed on the
93
+ // FIELD name: `buttonTextStyle` is the CTA button embedded in a section (banner/about/…). A
94
+ // STANDALONE button (general-link + its variants) instead keeps its label in `titleStyle` — a
95
+ // key shared with ordinary headings — so that case is handled per content type, not here
96
+ // (`isButtonLabelField`).
97
+ const NON_SECTION_SURFACE_KEYS = new Set([
98
+ 'buttonTextStyle',
99
+ 'copyrightStyle',
100
+ ]);
101
+ /**
102
+ * A standalone button's LABEL (`isButtonContent` → general-link, website, email, phone, and the
103
+ * social buttons — all store the label in `titleStyle`). Like `buttonTextStyle`, the label sits on
104
+ * the button fill, not a section surface: the button owns its own fill/text pairing, so it must not
105
+ * bake. With no baked colour the label inherits the button's on-fill text colour at render
106
+ * (`buttonStyles.style.color`), which is guaranteed to contrast the fill — whereas baking would
107
+ * contrast the PAGE instead and collide with the fill (the default theme paints both from the same
108
+ * brand role, hiding the text).
109
+ */
110
+ const isButtonLabelField = (content, key) => key === 'titleStyle' && isButtonContent(content);
72
111
  /**
73
- * The surface a single container-bound text field contrasts: the option-button fill for
74
- * a button-bound field (`itemTextStyle`), else the block's card. THE per-field router
75
- * shared by the render default and the creation-time bake, so they cannot disagree on
76
- * which surface a field sits on.
112
+ * The colour the maker's Text Style swatch shows for a STANDALONE button's LABEL. The label is left
113
+ * uncoloured on the element (`isButtonLabelField` exempts it from the birth-time bake) and inherits
114
+ * the button's on-fill colour at render via CSS (`buttonStyles.style.color`). The panel has no
115
+ * inherited value to read off the element, so it derives the SAME colour here — the swatch matches
116
+ * the canvas, both from one helper, exactly as `containerTextColorDefaults` feeds the swatch for
117
+ * container-bound fields. `undefined` for a non-label field or a button with no text colour.
77
118
  */
78
- const surfaceForTextStyleKey = (content, styles, key, brandPageType) => BUTTON_BOUND_TEXT_STYLE_KEYS[content.type]?.includes(key)
79
- ? optionButtonSurfaceForContent(content, styles)
80
- : containerSurfaceForContent(content, styles, brandPageType);
119
+ export const buttonLabelColorDefault = (content, styles, key) => isButtonLabelField(content, key)
120
+ ? styles.buttonStyles?.style?.color || undefined
121
+ : undefined;
122
+ /**
123
+ * The surface a single text field contrasts — THE per-field router shared by the render
124
+ * default and the creation-time bake, so they cannot disagree on which surface a field sits
125
+ * on: the option-button fill for a button-bound field (`itemTextStyle`), the block's card
126
+ * for a container-bound field (with the brandSite contact-form carve-out), the section's own
127
+ * topmost solid surface for any other text field, and nothing for the button label /
128
+ * copyright (they don't sit on a section surface).
129
+ */
130
+ const surfaceForTextStyleKey = (content, styles, key, brandPageType) => {
131
+ if (NON_SECTION_SURFACE_KEYS.has(key)) {
132
+ return undefined;
133
+ }
134
+ if (BUTTON_BOUND_TEXT_STYLE_KEYS[content.type]?.includes(key)) {
135
+ return optionButtonSurfaceForContent(content, styles);
136
+ }
137
+ if (isShopBandRoutedField(content, key)) {
138
+ return content.backgroundStyle;
139
+ }
140
+ return CONTAINER_BOUND_TEXT_STYLE_KEYS[content.type]?.includes(key)
141
+ ? containerSurfaceForContent(content, styles, brandPageType)
142
+ : topmostSolidSurface(content, styles.colors);
143
+ };
81
144
  // A surface is worth contrasting only when it paints a visible solid. `transparent`
82
145
  // means the text really sits on whatever is behind, so defer to the global colour.
83
146
  // Palette refs are resolved to their value first (matching the render pass) so a
@@ -213,54 +276,271 @@ export const rteFrameFallbackColour = (content, styles, brandPageType) => {
213
276
  * resolved (`withRoleDefaults`); `bestContrastBrandRole` itself reads raw values because
214
277
  * its other callers pair it with their own blank-role fallbacks.
215
278
  */
216
- const cardContrastColour = (surface, styles) => {
279
+ const contrastRoleColour = (surface, styles, best) => {
217
280
  const surfaceColour = resolveColorReference(backgroundColorFromStyle(surface) ?? '', styles.colors ?? [], { withRoleDefaults: true });
218
281
  if (!surfaceColour) {
219
282
  return undefined;
220
283
  }
221
- const role = bestContrastBrandRole(surfaceColour, (styles.colors ?? []).map((c) => ({
284
+ const role = best(surfaceColour, (styles.colors ?? []).map((c) => ({
222
285
  ...c,
223
286
  value: roleValueOrDefault(c.id, c.value) ?? c.value,
224
- })), 0);
287
+ })));
225
288
  return role ? toColorVarReference(role) : undefined;
226
289
  };
290
+ // Brand roles in preference order: logo-text (`palette-0`) leads, logo-background (`palette-1`)
291
+ // second — the site-identity hierarchy every text field follows before contrast is even compared.
292
+ const BRAND_ROLE_HIERARCHY = [
293
+ PALETTE_COLOR_IDS.primary,
294
+ PALETTE_COLOR_IDS.secondary,
295
+ ];
296
+ // The first brand role (by the hierarchy) that clears the minimum viable contrast on `against`.
297
+ const viableBrandRole = (against, colors) => firstViableContrastRole(against, colors, BRAND_ROLE_HIERARCHY, STRATEGY_COPY_MIN_CONTRAST);
227
298
  /**
228
- * Bakes a readable colour into a container-bound block's text so the renderer just paints
229
- * what's stored (no render-time contrast logic). Run when the block is created and whenever
230
- * its text style changes.
231
- *
232
- * For each container-bound text field with no colour of its own, on a solid surface that is
233
- * NOT the button fill, it writes whichever BRAND role contrasts THAT field's surface most —
234
- * the card for card fields, the option-button fill for `itemTextStyle`
235
- * (`surfaceForTextStyleKey`). A button-fill surface is skipped: its render-time pairing
236
- * (`containerTextColorDefaults`) supplies the button's own text colour, so `itemTextStyle`
237
- * on the default option fill needs no bake. Explicitly-coloured fields are left alone; so is
238
- * a palette with no usable brand role.
239
- *
240
- * Mutates and returns `content`.
299
+ * Brand text on a SOLID surface (a card, or a section's own band). Follows the same logo-text-first
300
+ * hierarchy the page uses — `palette-0` while it clears the contrast floor, else `palette-1` — so a
301
+ * section leads with the brand identity rather than whichever brand merely contrasts most. A card
302
+ * always ends on a brand (never a neutral), so if neither role clears the floor it falls back to the
303
+ * best-contrast brand.
241
304
  */
242
- export const applyCardTextContrast = (content, styles, brandPageType) => {
243
- const keys = CONTAINER_BOUND_TEXT_STYLE_KEYS[content.type];
244
- if (!keys?.length) {
245
- return content;
246
- }
247
- keys.forEach((key) => {
248
- const field = content[key];
249
- // Never overwrite an explicit element colour.
250
- if (!field || field.color) {
251
- return;
252
- }
253
- const surface = surfaceForTextStyleKey(content, styles, key, brandPageType);
254
- // A button-fill surface is contrasted by the button's own text colour at render, so it
255
- // needs no baked colour — skip it, exactly as a button-fill card is skipped.
256
- if (!isSolidSurface(surface, styles.colors) ||
257
- surfaceMatchesButtonFill(surface, styles)) {
305
+ const cardContrastColour = (surface, styles) => contrastRoleColour(surface, styles, (against, colors) => viableBrandRole(against, colors) ??
306
+ bestContrastBrandRole(against, colors));
307
+ /**
308
+ * The colour for text that sits on the PAGE background (a section that paints nothing solid),
309
+ * replacing the retired base coat. Same brand hierarchy as `cardContrastColour` — logo-text
310
+ * (`palette-0`) leads while it clears the floor, else `palette-1` — but where a card falls back to a
311
+ * brand, the page falls to the best-contrast NEUTRAL (legibility on a plain surface), and for an
312
+ * unresolvable page (image/gradient) to `neutral-dark`.
313
+ */
314
+ const pageContrastColour = (styles) => {
315
+ const surface = styles.backgroundStyles?.style;
316
+ return (contrastRoleColour(surface, styles, viableBrandRole) ??
317
+ contrastRoleColour(surface, styles, bestContrastNeutralRole) ??
318
+ toColorVarReference(PALETTE_COLOR_IDS.neutralDark));
319
+ };
320
+ /**
321
+ * Assigns the birth-time colour for ONE text field, given the surface it sits on:
322
+ * - a solid surface that is NOT the button fill → the brand hierarchy for it (`cardContrastColour`);
323
+ * - a solid surface that IS the button fill → nothing (the render-time pairing supplies the
324
+ * button's own text colour — the `itemTextStyle`-on-option-button case);
325
+ * - no solid surface → the page background (`pageContrastColour`).
326
+ * Mutates `field`.
327
+ */
328
+ const bakeFieldColour = (field, surface, styles) => {
329
+ if (isSolidSurface(surface, styles.colors)) {
330
+ if (surfaceMatchesButtonFill(surface, styles)) {
258
331
  return;
259
332
  }
260
333
  const colour = cardContrastColour(surface, styles);
261
334
  if (colour) {
262
335
  field.color = colour;
263
336
  }
337
+ return;
338
+ }
339
+ const colour = pageContrastColour(styles);
340
+ if (colour) {
341
+ field.color = colour;
342
+ }
343
+ };
344
+ /**
345
+ * The surface ANY text field ends up contrasting — a cascade so no field ever dead-ends
346
+ * uncoloured: the field's OWN surface (`surfaceForTextStyleKey`) if it paints a solid, else the
347
+ * SECTION's own painted surface (`topmostSolidSurface`) — which catches a container whose router
348
+ * yields nothing, e.g. the brandSite contact-form card — else `undefined`, meaning the page.
349
+ */
350
+ const effectiveFieldSurface = (content, styles, key, brandPageType) => {
351
+ const own = surfaceForTextStyleKey(content, styles, key, brandPageType);
352
+ if (isSolidSurface(own, styles.colors)) {
353
+ return own;
354
+ }
355
+ // A shop title/description stops at the band: the section-wide fallback below would
356
+ // otherwise pick up the tile fill, the same surface `isShopBandRoutedField` steers
357
+ // around above.
358
+ return isShopBandRoutedField(content, key)
359
+ ? undefined
360
+ : topmostSolidSurface(content, styles.colors);
361
+ };
362
+ /**
363
+ * The contrast colour for whatever sits on the title's own surface — the one the title itself
364
+ * gets. Two callers: a social-links section's icons (baked once onto `iconFillStyles.fill` at
365
+ * migration or birth, so they never follow a title recolour) and a shop section's "no products"
366
+ * label (read live in the view model, so it does follow one — there's no stored field to freeze).
367
+ */
368
+ export const titleSurfaceContrastFill = (content, styles, brandPageType) => {
369
+ const probe = {};
370
+ bakeFieldColour(probe, effectiveFieldSurface(content, styles, 'titleStyle', brandPageType), styles);
371
+ return probe.color;
372
+ };
373
+ // The colour on the first text run of an RTE doc (`item.text`), where the birth bake moves a
374
+ // field's colour. Read-only depth-first walk; `undefined` for a plain string or an uncoloured run.
375
+ const firstRunColour = (value) => {
376
+ const walk = (node) => {
377
+ if (node.type === 'text') {
378
+ return node.marks?.find((mark) => mark.type === 'textStyle')?.attrs
379
+ ?.color;
380
+ }
381
+ for (const child of node.content ?? []) {
382
+ const found = walk(child);
383
+ if (found) {
384
+ return found;
385
+ }
386
+ }
387
+ return undefined;
388
+ };
389
+ return typeof value === 'object' && value !== null
390
+ ? walk(value)
391
+ : undefined;
392
+ };
393
+ // Whether every VISIBLE run (non-whitespace text) in a doc carries a colour mark — used to decide
394
+ // whether applyTextContrast's bake is redundant. A doc with some coloured runs and some not (an
395
+ // accent word, or a hyperlink, which setRteTextColor always colours) still needs the bake, or its
396
+ // uncoloured runs fall back to the inherited colour.
397
+ const everyRunColoured = (value) => {
398
+ let sawVisibleRun = false;
399
+ let allColoured = true;
400
+ const walk = (node) => {
401
+ if (node.type === 'text') {
402
+ if (!node.text?.trim())
403
+ return;
404
+ sawVisibleRun = true;
405
+ if (!node.marks?.find((mark) => mark.type === 'textStyle')?.attrs?.color) {
406
+ allColoured = false;
407
+ }
408
+ return;
409
+ }
410
+ (node.content ?? []).forEach(walk);
411
+ };
412
+ if (typeof value === 'object' && value !== null)
413
+ walk(value);
414
+ return sawVisibleRun && allColoured;
415
+ };
416
+ // A text item's effective (rendered) colour. The RTE run MARK is authoritative and read FIRST: a
417
+ // recolour writes the mark but does NOT clear a stale `textStyle.color` left by an earlier bake, so
418
+ // preferring the style would return the old colour, not what the item shows. `textStyle.color` is
419
+ // the fallback for an item that has no run yet (e.g. a freshly inherited, still-empty item).
420
+ const textItemColour = (item) => firstRunColour(item.text) || item.textStyle?.color;
421
+ // A top-level field's own doc, paired by name (`titleStyle` ↔ `title`, `descriptionStyle` ↔
422
+ // `description`, …) — the same convention every Content model follows.
423
+ const textFieldKey = (key) => key.replace(/Style$/, '');
424
+ /**
425
+ * Bakes a readable colour into a SECTION's text at BIRTH so the renderer just paints what's
426
+ * stored (no render-time contrast logic). Run when a block is created and whenever its text
427
+ * style changes.
428
+ *
429
+ * Every text field (and every `textItems[]` entry) contrasts the topmost solid thing beneath it —
430
+ * its own field surface, else the section's painted surface, else the PAGE background
431
+ * (`effectiveFieldSurface`) — taking the brand hierarchy on a solid surface and `pageContrastColour`
432
+ * on the bare page (the replacement for the retired base coat, ADR-0020). The exempt fields never
433
+ * bake — the section CTA button label (`buttonTextStyle`) and copyright by key, and a standalone
434
+ * button's own label (`titleStyle` on an `isButtonContent`) by type; all own their fill/text
435
+ * pairing rather than a section surface. A field sitting on the button fill likewise defers to the
436
+ * render-time pairing. A social-links section's icons get their own stored fill
437
+ * (`titleSurfaceContrastFill`).
438
+ *
439
+ * Explicitly-coloured fields are left alone; so is a palette with no usable role.
440
+ *
441
+ * Mutates and returns `content`.
442
+ */
443
+ export const applyTextContrast = (content, styles, brandPageType) => {
444
+ const record = content;
445
+ const rawContent = content;
446
+ Object.keys(CONTENT_TEXT_STYLE_PROPERTY_KEYS).forEach((key) => {
447
+ const field = record[key];
448
+ // Absent, already coloured — via its style OR every visible run of its paired doc (a recolour
449
+ // moves colour to the marks without clearing a stale `field.color`, same as textItemColour) —
450
+ // an exempt key (section button / copyright), or a standalone button's own label → leave it alone.
451
+ if (!field ||
452
+ field.color ||
453
+ everyRunColoured(rawContent[textFieldKey(key)]) ||
454
+ NON_SECTION_SURFACE_KEYS.has(key) ||
455
+ isButtonLabelField(content, key)) {
456
+ return;
457
+ }
458
+ bakeFieldColour(field, effectiveFieldSurface(content, styles, key, brandPageType), styles);
264
459
  });
460
+ // Per-item text styles (`textItems[]` — the brand-site text section) are not top-level keys, so
461
+ // the loop above misses them. Items stack vertically, so a new (bottom) item INHERITS the colour
462
+ // of the item directly ABOVE it — the copy reads as one block and a newly-added item continues
463
+ // the last item's colour. Only the first item (nothing above) contrasts the surface; the inherit
464
+ // chains down the stack, so a fresh section still resolves to one contrast colour throughout.
465
+ const items = content.textItems;
466
+ if (Array.isArray(items)) {
467
+ const surface = topmostSolidSurface(content, styles.colors);
468
+ items.forEach((item, index) => {
469
+ // Already coloured — via its style OR its run mark (birth authoring moves colour to the mark
470
+ // and clears the style). Skipping the mark case is what stops a recoloured item being
471
+ // re-contrasted, and keeps it usable as the colour the item below inherits.
472
+ if (!item.textStyle || textItemColour(item)) {
473
+ return;
474
+ }
475
+ const above = index > 0 ? textItemColour(items[index - 1]) : undefined;
476
+ if (above) {
477
+ item.textStyle.color = above;
478
+ return;
479
+ }
480
+ bakeFieldColour(item.textStyle, surface, styles);
481
+ });
482
+ }
483
+ if (content.type === 'social-links') {
484
+ const socialLinks = content;
485
+ const iconFillStyles = socialLinks.iconFillStyles ?? {};
486
+ if (isBlankColorValue(iconFillStyles.fill)) {
487
+ const fill = titleSurfaceContrastFill(content, styles, brandPageType);
488
+ if (fill) {
489
+ socialLinks.iconFillStyles = { ...iconFillStyles, fill };
490
+ }
491
+ }
492
+ }
265
493
  return content;
266
494
  };
495
+ /**
496
+ * Phase 2 (ADR-0020): the surface fields a section can paint behind its text, TOP of the
497
+ * stack first (the closest painted layer is what the text sits on). A render-local mirror
498
+ * of the raised/backdrop split in `SURFACE_STACK_RANK` (`section-color-matches.ts`) — kept
499
+ * here so the renderer's contrast bake doesn't depend on the settings-panel module. Only
500
+ * the single-solid-surface fields are walked; array/overlay/tint layers are out of v1 scope.
501
+ * Extract to a shared leaf if a third consumer appears.
502
+ */
503
+ const SURFACE_FIELDS_TOP_FIRST = [
504
+ 'cardStyle',
505
+ 'fillColor',
506
+ 'backgroundStyle',
507
+ 'backgroundColor',
508
+ ];
509
+ /**
510
+ * A banner paints its `cardStyle` ONLY in the two card layouts (`isCard` in `BANNER_LAYOUTS`,
511
+ * `BannerSection.vue`); every other layout — including the default `centered` — renders the
512
+ * content directly on the band, so the transparent `backgroundStyle` lets the site background
513
+ * show through. The factory seeds `cardStyle` white regardless, so counting it as the surface in
514
+ * a non-card layout would contrast a card the banner never paints (dark title on a dark page).
515
+ */
516
+ const BANNER_CARD_DISPLAY_STYLES = new Set([
517
+ ALIGN_CARD_CENTER_IMAGE,
518
+ ALIGN_CARD_LEFT_IMAGE,
519
+ ]);
520
+ const isSurfaceFieldPainted = (content, field) => {
521
+ if (field === 'cardStyle' && content.type === 'banner-section') {
522
+ return BANNER_CARD_DISPLAY_STYLES.has(content.displayStyle ?? '');
523
+ }
524
+ return true;
525
+ };
526
+ /**
527
+ * The topmost solid surface painted behind a section's text — the highest-stacked surface
528
+ * field that resolves to a visible solid — or `undefined` when the section paints nothing solid
529
+ * (the text then sits on the page background, `applyTextContrast`'s page branch). A field the
530
+ * section does not actually paint in its current layout is skipped (`isSurfaceFieldPainted`).
531
+ * Palette refs are resolved first (via `isSolidSurface`), so a `var(--palette-N)` fill counts as
532
+ * the solid it resolves to.
533
+ */
534
+ export const topmostSolidSurface = (content, colors = []) => {
535
+ const record = content;
536
+ for (const field of SURFACE_FIELDS_TOP_FIRST) {
537
+ if (!isSurfaceFieldPainted(content, field)) {
538
+ continue;
539
+ }
540
+ const style = record[field];
541
+ if (isSolidSurface(style, colors)) {
542
+ return style;
543
+ }
544
+ }
545
+ return undefined;
546
+ };
@@ -1,4 +1,5 @@
1
1
  export * from './style.util';
2
+ export * from './text-role-css.util';
2
3
  export * from './color-palette.util';
3
4
  export * from './shape-color-match.util';
4
5
  export * from './shape-color-apply.util';
@@ -1,4 +1,5 @@
1
1
  export * from './style.util';
2
+ export * from './text-role-css.util';
2
3
  export * from './color-palette.util';
3
4
  export * from './shape-color-match.util';
4
5
  export * from './shape-color-apply.util';
@@ -1,4 +1,5 @@
1
- import { isRteHtmlString, toRteJson, resolveHtmlParser, } from '../../../brand-page-maker/utils';
1
+ import { toRteJson, resolveHtmlParser, } from '@shared/rte-render.util';
2
+ import { isRteHtmlString } from '@shared/rte-shape.util';
2
3
  /**
3
4
  * BP-5787 — migrate existing inline-HTML RTE content to Tiptap JSON.
4
5
  *
@@ -40,7 +41,10 @@ const convertRteStringsToJson = (value, parser) => {
40
41
  const field = record[key];
41
42
  if (isRteHtmlString(field)) {
42
43
  try {
43
- const json = toRteJson(field, parser);
44
+ // Pin the parse to the v20 schema this migration shipped with (pre-TextEffects). Parsing
45
+ // legacy HTML with the live schema would drift a released migration's output — a later
46
+ // schema addition (e.g. TextEffects) would bake attrs it never produced. See docs/decisions.
47
+ const json = toRteJson(field, parser, 20);
44
48
  if (json)
45
49
  record[key] = json;
46
50
  }