@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
@@ -7,26 +7,43 @@
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
15
  import type {
12
16
  Content,
13
17
  PageStyles,
14
18
  BrandPageType,
15
19
  ColorItem,
20
+ ShopContent,
21
+ SocialLinksContent,
16
22
  TextStyleDeclaration,
17
23
  } from '../models';
18
24
  import { BRAND_PAGE_TYPES } from '../models';
19
- import type { ContentTextStylePropertyKey } from '../constants';
25
+ import {
26
+ CONTENT_TEXT_STYLE_PROPERTY_KEYS,
27
+ type ContentTextStylePropertyKey,
28
+ ALIGN_CARD_CENTER_IMAGE,
29
+ ALIGN_CARD_LEFT_IMAGE,
30
+ } from '../constants';
20
31
  import {
21
32
  backgroundColorFromStyle,
22
33
  isTransparentColour,
23
34
  isHexTransparent,
24
35
  } from './color.util';
36
+ import { isButtonContent } from './model.util';
25
37
  import {
26
38
  resolveColorReference,
27
39
  bestContrastBrandRole,
40
+ bestContrastNeutralRole,
41
+ firstViableContrastRole,
28
42
  toColorVarReference,
29
43
  roleValueOrDefault,
44
+ isBlankColorValue,
45
+ PALETTE_COLOR_IDS,
46
+ STRATEGY_COPY_MIN_CONTRAST,
30
47
  } from './color-palette.util';
31
48
 
32
49
  /**
@@ -42,11 +59,17 @@ export const CONTAINER_BOUND_TEXT_STYLE_KEYS: Partial<
42
59
  Record<Content['type'], ContentTextStylePropertyKey[]>
43
60
  > = {
44
61
  'mailing-list': ['titleStyle'],
45
- 'request-payment': ['titleStyle', 'descriptionStyle', 'itemTextStyle'],
62
+ 'request-payment': [
63
+ 'titleStyle',
64
+ 'descriptionStyle',
65
+ 'successMessageStyle',
66
+ 'itemTextStyle',
67
+ ],
46
68
  'support-me': [
47
69
  'titleStyle',
48
70
  'headingStyle',
49
71
  'descriptionStyle',
72
+ 'successMessageStyle',
50
73
  'itemTextStyle',
51
74
  ],
52
75
  'contact-form': ['titleStyle', 'descriptionStyle', 'successMessageStyle'],
@@ -67,6 +90,22 @@ const BUTTON_BOUND_TEXT_STYLE_KEYS: Partial<
67
90
  'support-me': ['itemTextStyle'],
68
91
  };
69
92
 
93
+ /**
94
+ * Shop's title and description sit on the band (`backgroundStyle`), never the product
95
+ * tile (`fillColor`) — a sibling surface stacked below them, not behind them. Routed here
96
+ * rather than through `topmostSolidSurface`'s generic top-of-stack scan, which would pick
97
+ * the tile fill first and MIScolour the title against a surface it doesn't sit on.
98
+ */
99
+ const SHOP_BAND_ROUTED_KEYS = new Set<ContentTextStylePropertyKey>([
100
+ 'titleStyle',
101
+ 'descriptionStyle',
102
+ ]);
103
+
104
+ const isShopBandRoutedField = (
105
+ content: Content,
106
+ key: ContentTextStylePropertyKey,
107
+ ): boolean => content.type === 'shop-section' && SHOP_BAND_ROUTED_KEYS.has(key);
108
+
70
109
  /**
71
110
  * The filled surface the block's text sits on: the block's OWN container colour
72
111
  * (`backgroundStyle`, or `cardStyle` for contact-form) when set, else the global
@@ -121,21 +160,78 @@ const optionButtonSurfaceForContent = (
121
160
  return backgroundColorFromStyle(own) ? own : styles.buttonStyles?.style;
122
161
  };
123
162
 
163
+ // The button label owns its own fill/text pairing and copyright is page-level — neither
164
+ // contrasts a SECTION surface, so they get no birth-time contrast bake. This is keyed on the
165
+ // FIELD name: `buttonTextStyle` is the CTA button embedded in a section (banner/about/…). A
166
+ // STANDALONE button (general-link + its variants) instead keeps its label in `titleStyle` — a
167
+ // key shared with ordinary headings — so that case is handled per content type, not here
168
+ // (`isButtonLabelField`).
169
+ const NON_SECTION_SURFACE_KEYS = new Set<ContentTextStylePropertyKey>([
170
+ 'buttonTextStyle',
171
+ 'copyrightStyle',
172
+ ]);
173
+
124
174
  /**
125
- * The surface a single container-bound text field contrasts: the option-button fill for
126
- * a button-bound field (`itemTextStyle`), else the block's card. THE per-field router
127
- * shared by the render default and the creation-time bake, so they cannot disagree on
128
- * which surface a field sits on.
175
+ * A standalone button's LABEL (`isButtonContent` → general-link, website, email, phone, and the
176
+ * social buttons — all store the label in `titleStyle`). Like `buttonTextStyle`, the label sits on
177
+ * the button fill, not a section surface: the button owns its own fill/text pairing, so it must not
178
+ * bake. With no baked colour the label inherits the button's on-fill text colour at render
179
+ * (`buttonStyles.style.color`), which is guaranteed to contrast the fill — whereas baking would
180
+ * contrast the PAGE instead and collide with the fill (the default theme paints both from the same
181
+ * brand role, hiding the text).
182
+ */
183
+ const isButtonLabelField = (
184
+ content: Content,
185
+ key: ContentTextStylePropertyKey,
186
+ ): boolean => key === 'titleStyle' && isButtonContent(content);
187
+
188
+ /**
189
+ * The colour the maker's Text Style swatch shows for a STANDALONE button's LABEL. The label is left
190
+ * uncoloured on the element (`isButtonLabelField` exempts it from the birth-time bake) and inherits
191
+ * the button's on-fill colour at render via CSS (`buttonStyles.style.color`). The panel has no
192
+ * inherited value to read off the element, so it derives the SAME colour here — the swatch matches
193
+ * the canvas, both from one helper, exactly as `containerTextColorDefaults` feeds the swatch for
194
+ * container-bound fields. `undefined` for a non-label field or a button with no text colour.
195
+ */
196
+ export const buttonLabelColorDefault = (
197
+ content: Content,
198
+ styles: PageStyles,
199
+ key: string,
200
+ ): string | undefined =>
201
+ isButtonLabelField(content, key as ContentTextStylePropertyKey)
202
+ ? styles.buttonStyles?.style?.color || undefined
203
+ : undefined;
204
+
205
+ /**
206
+ * The surface a single text field contrasts — THE per-field router shared by the render
207
+ * default and the creation-time bake, so they cannot disagree on which surface a field sits
208
+ * on: the option-button fill for a button-bound field (`itemTextStyle`), the block's card
209
+ * for a container-bound field (with the brandSite contact-form carve-out), the section's own
210
+ * topmost solid surface for any other text field, and nothing for the button label /
211
+ * copyright (they don't sit on a section surface).
129
212
  */
130
213
  const surfaceForTextStyleKey = (
131
214
  content: Content,
132
215
  styles: PageStyles,
133
216
  key: ContentTextStylePropertyKey,
134
217
  brandPageType?: BrandPageType,
135
- ): BrandPageCssStyle | undefined =>
136
- BUTTON_BOUND_TEXT_STYLE_KEYS[content.type]?.includes(key)
137
- ? optionButtonSurfaceForContent(content, styles)
138
- : containerSurfaceForContent(content, styles, brandPageType);
218
+ ): BrandPageCssStyle | undefined => {
219
+ if (NON_SECTION_SURFACE_KEYS.has(key)) {
220
+ return undefined;
221
+ }
222
+
223
+ if (BUTTON_BOUND_TEXT_STYLE_KEYS[content.type]?.includes(key)) {
224
+ return optionButtonSurfaceForContent(content, styles);
225
+ }
226
+
227
+ if (isShopBandRoutedField(content, key)) {
228
+ return (content as ShopContent).backgroundStyle;
229
+ }
230
+
231
+ return CONTAINER_BOUND_TEXT_STYLE_KEYS[content.type]?.includes(key)
232
+ ? containerSurfaceForContent(content, styles, brandPageType)
233
+ : topmostSolidSurface(content, styles.colors);
234
+ };
139
235
 
140
236
  // A surface is worth contrasting only when it paints a visible solid. `transparent`
141
237
  // means the text really sits on whatever is behind, so defer to the global colour.
@@ -316,9 +412,10 @@ export const rteFrameFallbackColour = (
316
412
  * resolved (`withRoleDefaults`); `bestContrastBrandRole` itself reads raw values because
317
413
  * its other callers pair it with their own blank-role fallbacks.
318
414
  */
319
- const cardContrastColour = (
415
+ const contrastRoleColour = (
320
416
  surface: BrandPageCssStyle | undefined,
321
417
  styles: PageStyles,
418
+ best: (against: string, colors: ColorItem[]) => string | undefined,
322
419
  ): string | undefined => {
323
420
  const surfaceColour = resolveColorReference(
324
421
  backgroundColorFromStyle(surface) ?? '',
@@ -330,71 +427,400 @@ const cardContrastColour = (
330
427
  return undefined;
331
428
  }
332
429
 
333
- const role = bestContrastBrandRole(
430
+ const role = best(
334
431
  surfaceColour,
335
432
  (styles.colors ?? []).map((c) => ({
336
433
  ...c,
337
434
  value: roleValueOrDefault(c.id, c.value) ?? c.value,
338
435
  })),
339
- 0,
340
436
  );
341
437
 
342
438
  return role ? toColorVarReference(role) : undefined;
343
439
  };
344
440
 
441
+ // Brand roles in preference order: logo-text (`palette-0`) leads, logo-background (`palette-1`)
442
+ // second — the site-identity hierarchy every text field follows before contrast is even compared.
443
+ const BRAND_ROLE_HIERARCHY = [
444
+ PALETTE_COLOR_IDS.primary,
445
+ PALETTE_COLOR_IDS.secondary,
446
+ ];
447
+
448
+ // The first brand role (by the hierarchy) that clears the minimum viable contrast on `against`.
449
+ const viableBrandRole = (
450
+ against: string,
451
+ colors: ColorItem[],
452
+ ): string | undefined =>
453
+ firstViableContrastRole(
454
+ against,
455
+ colors,
456
+ BRAND_ROLE_HIERARCHY,
457
+ STRATEGY_COPY_MIN_CONTRAST,
458
+ );
459
+
345
460
  /**
346
- * Bakes a readable colour into a container-bound block's text so the renderer just paints
347
- * what's stored (no render-time contrast logic). Run when the block is created and whenever
348
- * its text style changes.
349
- *
350
- * For each container-bound text field with no colour of its own, on a solid surface that is
351
- * NOT the button fill, it writes whichever BRAND role contrasts THAT field's surface most —
352
- * the card for card fields, the option-button fill for `itemTextStyle`
353
- * (`surfaceForTextStyleKey`). A button-fill surface is skipped: its render-time pairing
354
- * (`containerTextColorDefaults`) supplies the button's own text colour, so `itemTextStyle`
355
- * on the default option fill needs no bake. Explicitly-coloured fields are left alone; so is
356
- * a palette with no usable brand role.
357
- *
358
- * Mutates and returns `content`.
461
+ * Brand text on a SOLID surface (a card, or a section's own band). Follows the same logo-text-first
462
+ * hierarchy the page uses — `palette-0` while it clears the contrast floor, else `palette-1` — so a
463
+ * section leads with the brand identity rather than whichever brand merely contrasts most. A card
464
+ * always ends on a brand (never a neutral), so if neither role clears the floor it falls back to the
465
+ * best-contrast brand.
359
466
  */
360
- export const applyCardTextContrast = (
467
+ const cardContrastColour = (
468
+ surface: BrandPageCssStyle | undefined,
469
+ styles: PageStyles,
470
+ ): string | undefined =>
471
+ contrastRoleColour(
472
+ surface,
473
+ styles,
474
+ (against, colors) =>
475
+ viableBrandRole(against, colors) ??
476
+ bestContrastBrandRole(against, colors),
477
+ );
478
+
479
+ /**
480
+ * The colour for text that sits on the PAGE background (a section that paints nothing solid),
481
+ * replacing the retired base coat. Same brand hierarchy as `cardContrastColour` — logo-text
482
+ * (`palette-0`) leads while it clears the floor, else `palette-1` — but where a card falls back to a
483
+ * brand, the page falls to the best-contrast NEUTRAL (legibility on a plain surface), and for an
484
+ * unresolvable page (image/gradient) to `neutral-dark`.
485
+ */
486
+ const pageContrastColour = (styles: PageStyles): string | undefined => {
487
+ const surface = styles.backgroundStyles?.style;
488
+
489
+ return (
490
+ contrastRoleColour(surface, styles, viableBrandRole) ??
491
+ contrastRoleColour(surface, styles, bestContrastNeutralRole) ??
492
+ toColorVarReference(PALETTE_COLOR_IDS.neutralDark)
493
+ );
494
+ };
495
+
496
+ /**
497
+ * Assigns the birth-time colour for ONE text field, given the surface it sits on:
498
+ * - a solid surface that is NOT the button fill → the brand hierarchy for it (`cardContrastColour`);
499
+ * - a solid surface that IS the button fill → nothing (the render-time pairing supplies the
500
+ * button's own text colour — the `itemTextStyle`-on-option-button case);
501
+ * - no solid surface → the page background (`pageContrastColour`).
502
+ * Mutates `field`.
503
+ */
504
+ const bakeFieldColour = (
505
+ field: { color?: string },
506
+ surface: BrandPageCssStyle | undefined,
507
+ styles: PageStyles,
508
+ ): void => {
509
+ if (isSolidSurface(surface, styles.colors)) {
510
+ if (surfaceMatchesButtonFill(surface, styles)) {
511
+ return;
512
+ }
513
+
514
+ const colour = cardContrastColour(surface, styles);
515
+
516
+ if (colour) {
517
+ field.color = colour;
518
+ }
519
+
520
+ return;
521
+ }
522
+
523
+ const colour = pageContrastColour(styles);
524
+
525
+ if (colour) {
526
+ field.color = colour;
527
+ }
528
+ };
529
+
530
+ /**
531
+ * The surface ANY text field ends up contrasting — a cascade so no field ever dead-ends
532
+ * uncoloured: the field's OWN surface (`surfaceForTextStyleKey`) if it paints a solid, else the
533
+ * SECTION's own painted surface (`topmostSolidSurface`) — which catches a container whose router
534
+ * yields nothing, e.g. the brandSite contact-form card — else `undefined`, meaning the page.
535
+ */
536
+ const effectiveFieldSurface = (
361
537
  content: Content,
362
538
  styles: PageStyles,
539
+ key: ContentTextStylePropertyKey,
363
540
  brandPageType?: BrandPageType,
364
- ): Content => {
365
- const keys = CONTAINER_BOUND_TEXT_STYLE_KEYS[content.type];
541
+ ): BrandPageCssStyle | undefined => {
542
+ const own = surfaceForTextStyleKey(content, styles, key, brandPageType);
366
543
 
367
- if (!keys?.length) {
368
- return content;
544
+ if (isSolidSurface(own, styles.colors)) {
545
+ return own;
369
546
  }
370
547
 
371
- keys.forEach((key) => {
372
- const field = (content as unknown as Record<string, TextStyleDeclaration>)[
373
- key
374
- ];
548
+ // A shop title/description stops at the band: the section-wide fallback below would
549
+ // otherwise pick up the tile fill, the same surface `isShopBandRoutedField` steers
550
+ // around above.
551
+ return isShopBandRoutedField(content, key)
552
+ ? undefined
553
+ : topmostSolidSurface(content, styles.colors);
554
+ };
555
+
556
+ /**
557
+ * The contrast colour for whatever sits on the title's own surface — the one the title itself
558
+ * gets. Two callers: a social-links section's icons (baked once onto `iconFillStyles.fill` at
559
+ * migration or birth, so they never follow a title recolour) and a shop section's "no products"
560
+ * label (read live in the view model, so it does follow one — there's no stored field to freeze).
561
+ */
562
+ export const titleSurfaceContrastFill = (
563
+ content: Content,
564
+ styles: PageStyles,
565
+ brandPageType?: BrandPageType,
566
+ ): string | undefined => {
567
+ const probe: { color?: string } = {};
568
+
569
+ bakeFieldColour(
570
+ probe,
571
+ effectiveFieldSurface(content, styles, 'titleStyle', brandPageType),
572
+ styles,
573
+ );
574
+
575
+ return probe.color;
576
+ };
577
+
578
+ type RteNode = {
579
+ type?: string;
580
+ text?: string;
581
+ marks?: { type: string; attrs?: { color?: string } }[];
582
+ content?: RteNode[];
583
+ };
584
+
585
+ // The colour on the first text run of an RTE doc (`item.text`), where the birth bake moves a
586
+ // field's colour. Read-only depth-first walk; `undefined` for a plain string or an uncoloured run.
587
+ const firstRunColour = (value: unknown): string | undefined => {
588
+ const walk = (node: RteNode): string | undefined => {
589
+ if (node.type === 'text') {
590
+ return node.marks?.find((mark) => mark.type === 'textStyle')?.attrs
591
+ ?.color;
592
+ }
593
+
594
+ for (const child of node.content ?? []) {
595
+ const found = walk(child);
596
+
597
+ if (found) {
598
+ return found;
599
+ }
600
+ }
601
+
602
+ return undefined;
603
+ };
604
+
605
+ return typeof value === 'object' && value !== null
606
+ ? walk(value as RteNode)
607
+ : undefined;
608
+ };
609
+
610
+ // Whether every VISIBLE run (non-whitespace text) in a doc carries a colour mark — used to decide
611
+ // whether applyTextContrast's bake is redundant. A doc with some coloured runs and some not (an
612
+ // accent word, or a hyperlink, which setRteTextColor always colours) still needs the bake, or its
613
+ // uncoloured runs fall back to the inherited colour.
614
+ const everyRunColoured = (value: unknown): boolean => {
615
+ let sawVisibleRun = false;
616
+ let allColoured = true;
617
+
618
+ const walk = (node: RteNode): void => {
619
+ if (node.type === 'text') {
620
+ if (!node.text?.trim()) return;
621
+
622
+ sawVisibleRun = true;
623
+
624
+ if (
625
+ !node.marks?.find((mark) => mark.type === 'textStyle')?.attrs?.color
626
+ ) {
627
+ allColoured = false;
628
+ }
375
629
 
376
- // Never overwrite an explicit element colour.
377
- if (!field || field.color) {
378
630
  return;
379
631
  }
380
632
 
381
- const surface = surfaceForTextStyleKey(content, styles, key, brandPageType);
633
+ (node.content ?? []).forEach(walk);
634
+ };
635
+
636
+ if (typeof value === 'object' && value !== null) walk(value as RteNode);
637
+
638
+ return sawVisibleRun && allColoured;
639
+ };
640
+
641
+ // A text item's effective (rendered) colour. The RTE run MARK is authoritative and read FIRST: a
642
+ // recolour writes the mark but does NOT clear a stale `textStyle.color` left by an earlier bake, so
643
+ // preferring the style would return the old colour, not what the item shows. `textStyle.color` is
644
+ // the fallback for an item that has no run yet (e.g. a freshly inherited, still-empty item).
645
+ const textItemColour = (item: {
646
+ textStyle?: { color?: string };
647
+ text?: unknown;
648
+ }): string | undefined => firstRunColour(item.text) || item.textStyle?.color;
382
649
 
383
- // A button-fill surface is contrasted by the button's own text colour at render, so it
384
- // needs no baked colour — skip it, exactly as a button-fill card is skipped.
650
+ // A top-level field's own doc, paired by name (`titleStyle` ↔ `title`, `descriptionStyle` ↔
651
+ // `description`, …) — the same convention every Content model follows.
652
+ const textFieldKey = (key: ContentTextStylePropertyKey): string =>
653
+ key.replace(/Style$/, '');
654
+
655
+ /**
656
+ * Bakes a readable colour into a SECTION's text at BIRTH so the renderer just paints what's
657
+ * stored (no render-time contrast logic). Run when a block is created and whenever its text
658
+ * style changes.
659
+ *
660
+ * Every text field (and every `textItems[]` entry) contrasts the topmost solid thing beneath it —
661
+ * its own field surface, else the section's painted surface, else the PAGE background
662
+ * (`effectiveFieldSurface`) — taking the brand hierarchy on a solid surface and `pageContrastColour`
663
+ * on the bare page (the replacement for the retired base coat, ADR-0020). The exempt fields never
664
+ * bake — the section CTA button label (`buttonTextStyle`) and copyright by key, and a standalone
665
+ * button's own label (`titleStyle` on an `isButtonContent`) by type; all own their fill/text
666
+ * pairing rather than a section surface. A field sitting on the button fill likewise defers to the
667
+ * render-time pairing. A social-links section's icons get their own stored fill
668
+ * (`titleSurfaceContrastFill`).
669
+ *
670
+ * Explicitly-coloured fields are left alone; so is a palette with no usable role.
671
+ *
672
+ * Mutates and returns `content`.
673
+ */
674
+ export const applyTextContrast = (
675
+ content: Content,
676
+ styles: PageStyles,
677
+ brandPageType?: BrandPageType,
678
+ ): Content => {
679
+ const record = content as unknown as Record<string, TextStyleDeclaration>;
680
+ const rawContent = content as unknown as Record<string, unknown>;
681
+
682
+ (
683
+ Object.keys(
684
+ CONTENT_TEXT_STYLE_PROPERTY_KEYS,
685
+ ) as ContentTextStylePropertyKey[]
686
+ ).forEach((key) => {
687
+ const field = record[key];
688
+
689
+ // Absent, already coloured — via its style OR every visible run of its paired doc (a recolour
690
+ // moves colour to the marks without clearing a stale `field.color`, same as textItemColour) —
691
+ // an exempt key (section button / copyright), or a standalone button's own label → leave it alone.
385
692
  if (
386
- !isSolidSurface(surface, styles.colors) ||
387
- surfaceMatchesButtonFill(surface, styles)
693
+ !field ||
694
+ field.color ||
695
+ everyRunColoured(rawContent[textFieldKey(key)]) ||
696
+ NON_SECTION_SURFACE_KEYS.has(key) ||
697
+ isButtonLabelField(content, key)
388
698
  ) {
389
699
  return;
390
700
  }
391
701
 
392
- const colour = cardContrastColour(surface, styles);
702
+ bakeFieldColour(
703
+ field,
704
+ effectiveFieldSurface(content, styles, key, brandPageType),
705
+ styles,
706
+ );
707
+ });
393
708
 
394
- if (colour) {
395
- field.color = colour;
709
+ // Per-item text styles (`textItems[]` — the brand-site text section) are not top-level keys, so
710
+ // the loop above misses them. Items stack vertically, so a new (bottom) item INHERITS the colour
711
+ // of the item directly ABOVE it — the copy reads as one block and a newly-added item continues
712
+ // the last item's colour. Only the first item (nothing above) contrasts the surface; the inherit
713
+ // chains down the stack, so a fresh section still resolves to one contrast colour throughout.
714
+ const items = (
715
+ content as {
716
+ textItems?: { textStyle?: { color?: string }; text?: unknown }[];
396
717
  }
397
- });
718
+ ).textItems;
719
+
720
+ if (Array.isArray(items)) {
721
+ const surface = topmostSolidSurface(content, styles.colors);
722
+
723
+ items.forEach((item, index) => {
724
+ // Already coloured — via its style OR its run mark (birth authoring moves colour to the mark
725
+ // and clears the style). Skipping the mark case is what stops a recoloured item being
726
+ // re-contrasted, and keeps it usable as the colour the item below inherits.
727
+ if (!item.textStyle || textItemColour(item)) {
728
+ return;
729
+ }
730
+
731
+ const above = index > 0 ? textItemColour(items[index - 1]) : undefined;
732
+
733
+ if (above) {
734
+ item.textStyle.color = above;
735
+
736
+ return;
737
+ }
738
+
739
+ bakeFieldColour(item.textStyle, surface, styles);
740
+ });
741
+ }
742
+
743
+ if (content.type === 'social-links') {
744
+ const socialLinks = content as SocialLinksContent;
745
+ const iconFillStyles = socialLinks.iconFillStyles ?? {};
746
+
747
+ if (isBlankColorValue(iconFillStyles.fill)) {
748
+ const fill = titleSurfaceContrastFill(content, styles, brandPageType);
749
+
750
+ if (fill) {
751
+ socialLinks.iconFillStyles = { ...iconFillStyles, fill };
752
+ }
753
+ }
754
+ }
398
755
 
399
756
  return content;
400
757
  };
758
+
759
+ /**
760
+ * Phase 2 (ADR-0020): the surface fields a section can paint behind its text, TOP of the
761
+ * stack first (the closest painted layer is what the text sits on). A render-local mirror
762
+ * of the raised/backdrop split in `SURFACE_STACK_RANK` (`section-color-matches.ts`) — kept
763
+ * here so the renderer's contrast bake doesn't depend on the settings-panel module. Only
764
+ * the single-solid-surface fields are walked; array/overlay/tint layers are out of v1 scope.
765
+ * Extract to a shared leaf if a third consumer appears.
766
+ */
767
+ const SURFACE_FIELDS_TOP_FIRST = [
768
+ 'cardStyle',
769
+ 'fillColor',
770
+ 'backgroundStyle',
771
+ 'backgroundColor',
772
+ ] as const;
773
+
774
+ /**
775
+ * A banner paints its `cardStyle` ONLY in the two card layouts (`isCard` in `BANNER_LAYOUTS`,
776
+ * `BannerSection.vue`); every other layout — including the default `centered` — renders the
777
+ * content directly on the band, so the transparent `backgroundStyle` lets the site background
778
+ * show through. The factory seeds `cardStyle` white regardless, so counting it as the surface in
779
+ * a non-card layout would contrast a card the banner never paints (dark title on a dark page).
780
+ */
781
+ const BANNER_CARD_DISPLAY_STYLES = new Set<string>([
782
+ ALIGN_CARD_CENTER_IMAGE,
783
+ ALIGN_CARD_LEFT_IMAGE,
784
+ ]);
785
+
786
+ const isSurfaceFieldPainted = (content: Content, field: string): boolean => {
787
+ if (field === 'cardStyle' && content.type === 'banner-section') {
788
+ return BANNER_CARD_DISPLAY_STYLES.has(
789
+ (content as { displayStyle?: string }).displayStyle ?? '',
790
+ );
791
+ }
792
+
793
+ return true;
794
+ };
795
+
796
+ /**
797
+ * The topmost solid surface painted behind a section's text — the highest-stacked surface
798
+ * field that resolves to a visible solid — or `undefined` when the section paints nothing solid
799
+ * (the text then sits on the page background, `applyTextContrast`'s page branch). A field the
800
+ * section does not actually paint in its current layout is skipped (`isSurfaceFieldPainted`).
801
+ * Palette refs are resolved first (via `isSolidSurface`), so a `var(--palette-N)` fill counts as
802
+ * the solid it resolves to.
803
+ */
804
+ export const topmostSolidSurface = (
805
+ content: Content,
806
+ colors: ColorItem[] = [],
807
+ ): BrandPageCssStyle | undefined => {
808
+ const record = content as unknown as Record<
809
+ string,
810
+ BrandPageCssStyle | undefined
811
+ >;
812
+
813
+ for (const field of SURFACE_FIELDS_TOP_FIRST) {
814
+ if (!isSurfaceFieldPainted(content, field)) {
815
+ continue;
816
+ }
817
+
818
+ const style = record[field];
819
+
820
+ if (isSolidSurface(style, colors)) {
821
+ return style;
822
+ }
823
+ }
824
+
825
+ return undefined;
826
+ };
@@ -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';