@designcrowd/library.brand-page 6.2.11 → 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 (576) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-DDcraD5S.js → CreatedOnBrandCrowd-de-de-BtVKllNQ.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DtOeaisf.js → CreatedOnBrandCrowd-en-us-CX5V0v8u.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BZpmJPew.js → CreatedOnBrandCrowd-es-es-CbA02PCL.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-CqRwC4e7.js → CreatedOnBrandCrowd-fr-ca-BQAKruBF.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-CqRwC4e7.js → CreatedOnBrandCrowd-fr-fr-BQAKruBF.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-DId9Dfjh.js → CreatedOnBrandCrowd-pt-br-Yk_yzB3s.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-DId9Dfjh.js → CreatedOnBrandCrowd-pt-pt-Yk_yzB3s.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BTDfmOcm.js → CreatedOnDcom-de-de-DJZQbPSD.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-CeAu9Ayx.js → CreatedOnDcom-en-us-BJvNAa4l.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-WCv0K41H.js → CreatedOnDcom-es-es-CUwB1FRY.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-BlfevQDY.js → CreatedOnDcom-fr-ca-CK54U4oh.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-Cvt7MHPZ.js → CreatedOnDcom-fr-fr-DuUNBGrM.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-DipZuylv.js → CreatedOnDcom-pt-br-BfODpFNV.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-BCw4lcKN.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/index.d.ts +23 -24
  39. package/lib/src/brand-page/models/index.js +20 -7
  40. package/lib/src/brand-page/models/navigation-styles.model.d.ts +1 -1
  41. package/lib/src/brand-page/models/navigation-styles.model.js +17 -8
  42. package/lib/src/brand-page/models/payment.model.d.ts +11 -6
  43. package/lib/src/brand-page/models/styles.model.d.ts +53 -7
  44. package/lib/src/brand-page/models/styles.model.js +115 -27
  45. package/lib/src/brand-page/utils/color-palette.util.d.ts +43 -23
  46. package/lib/src/brand-page/utils/color-palette.util.js +65 -27
  47. package/lib/src/brand-page/utils/color.util.d.ts +13 -9
  48. package/lib/src/brand-page/utils/color.util.js +56 -15
  49. package/lib/src/brand-page/utils/container-text-color.util.d.ts +46 -13
  50. package/lib/src/brand-page/utils/container-text-color.util.js +321 -41
  51. package/lib/src/brand-page/utils/index.d.ts +1 -0
  52. package/lib/src/brand-page/utils/index.js +1 -0
  53. package/lib/src/brand-page/utils/migration/migration-20.js +6 -2
  54. package/lib/src/brand-page/utils/migration/migration-21.js +34 -6
  55. package/lib/src/brand-page/utils/migration/migration-22.d.ts +99 -0
  56. package/lib/src/brand-page/utils/migration/migration-22.js +909 -0
  57. package/lib/src/brand-page/utils/migration.util.js +17 -0
  58. package/lib/src/brand-page/utils/model.util.d.ts +4 -0
  59. package/lib/src/brand-page/utils/model.util.js +4 -0
  60. package/lib/src/brand-page/utils/personalisation.util.js +9 -1
  61. package/lib/src/brand-page/utils/rte-role-lift.util.d.ts +72 -0
  62. package/lib/src/brand-page/utils/rte-role-lift.util.js +275 -0
  63. package/lib/src/brand-page/utils/style.util.d.ts +5 -1
  64. package/lib/src/brand-page/utils/style.util.js +34 -11
  65. package/lib/src/brand-page/utils/text-role-css.util.d.ts +19 -0
  66. package/lib/src/brand-page/utils/text-role-css.util.js +186 -0
  67. package/lib/src/brand-page/utils/text-role-reconnect.util.d.ts +90 -0
  68. package/lib/src/brand-page/utils/text-role-reconnect.util.js +434 -0
  69. package/lib/src/brand-page/utils/text-style.util.d.ts +53 -23
  70. package/lib/src/brand-page/utils/text-style.util.js +122 -22
  71. package/lib/src/brand-page/utils/view-model.util.d.ts +9 -1
  72. package/lib/src/brand-page/utils/view-model.util.js +124 -111
  73. package/lib/src/brand-page/view-models.d.ts +1 -0
  74. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +4 -1
  75. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +13 -2
  76. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +4 -4
  77. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +4 -1
  78. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -10
  79. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.js +0 -1
  80. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +23 -138
  81. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.js +0 -28
  82. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +4 -1
  83. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +1 -1
  84. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +5 -2
  85. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +4 -1
  86. package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +4 -1
  87. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +4 -1
  88. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
  89. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
  90. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +1 -0
  91. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.d.ts +16 -0
  92. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.js +61 -0
  93. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.d.ts +11 -0
  94. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.js +236 -0
  95. package/lib/src/brand-page-maker/composables/rich-text-editor/font.d.ts +2 -1
  96. package/lib/src/brand-page-maker/composables/rich-text-editor/font.js +25 -6
  97. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.d.ts +17 -4
  98. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.js +204 -17
  99. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.d.ts +1 -1
  100. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.js +29 -31
  101. package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.d.ts +20 -0
  102. package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.js +60 -0
  103. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.d.ts +2 -1
  104. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.js +22 -6
  105. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +10 -4
  106. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +319 -275
  107. package/lib/src/brand-page-maker/constants/config-settings-constant.js +1 -5
  108. package/lib/src/brand-page-maker/convertors/text-css-style-options.convertor.js +6 -2
  109. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.d.ts +1 -1
  110. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
  111. package/lib/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.js +7 -14
  112. package/lib/src/brand-page-maker/default-getters/text-color.default-getter.js +6 -13
  113. package/lib/src/brand-page-maker/models/content-settings.d.ts +8 -0
  114. package/lib/src/brand-page-maker/models/content-settings.js +112 -81
  115. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.d.ts +2 -2
  116. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.js +5 -2
  117. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.js +4 -3
  118. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +1257 -117
  119. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +6 -1
  120. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +17 -9
  121. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +59 -5
  122. package/lib/src/brand-page-maker/stores/history/history-store.js +22 -2
  123. package/lib/src/brand-page-maker/utils/apply-color-strategy.js +26 -8
  124. package/lib/src/brand-page-maker/utils/index.d.ts +2 -1
  125. package/lib/src/brand-page-maker/utils/index.js +2 -1
  126. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +117 -15
  127. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +435 -281
  128. package/lib/src/brand-page-maker/utils/rte-authoring.util.d.ts +4 -0
  129. package/lib/src/brand-page-maker/utils/rte-authoring.util.js +101 -0
  130. package/lib/src/brand-page-maker/utils/rte-clipboard.util.d.ts +126 -0
  131. package/lib/src/brand-page-maker/utils/rte-clipboard.util.js +307 -0
  132. package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +13 -3
  133. package/lib/src/{bundled-translations-zfiA5Tsw.js → bundled-translations-yGrvPE5i.js} +17 -17
  134. package/lib/src/{bundled-translations.de-DE-ChsdSyAP.js → bundled-translations.de-DE-L4Znf8Hs.js} +17 -17
  135. package/lib/src/{bundled-translations.es-ES-DflsWQK0.js → bundled-translations.es-ES-D6iticrK.js} +15 -15
  136. package/lib/src/{bundled-translations.fr-CA-fpDRuZ52.js → bundled-translations.fr-CA-BgAVE-9k.js} +25 -25
  137. package/lib/src/{bundled-translations.fr-FR-Bub73Zt-.js → bundled-translations.fr-FR-B8GbyqxQ.js} +17 -17
  138. package/lib/src/{bundled-translations.pt-BR-BlnWE9TB.js → bundled-translations.pt-BR-DjPU3Db7.js} +25 -25
  139. package/lib/src/{bundled-translations.pt-PT-DmzXlnaS.js → bundled-translations.pt-PT-BaepaDpr.js} +23 -23
  140. package/lib/src/bundles/bundled-translations.de-DE.json +21 -2
  141. package/lib/src/bundles/bundled-translations.es-ES.json +21 -2
  142. package/lib/src/bundles/bundled-translations.fr-CA.json +21 -2
  143. package/lib/src/bundles/bundled-translations.fr-FR.json +21 -2
  144. package/lib/src/bundles/bundled-translations.json +21 -2
  145. package/lib/src/bundles/bundled-translations.pt-BR.json +21 -2
  146. package/lib/src/bundles/bundled-translations.pt-PT.json +21 -2
  147. package/lib/src/clients/ai-assistant-client.d.ts +1 -0
  148. package/lib/src/composables/useTranslate.d.ts +1 -1
  149. package/lib/src/composables/useTranslate.js +1 -1
  150. package/lib/src/css/library.brand-page-brandCrowd.min.css +303 -207
  151. package/lib/src/css/library.brand-page-brandPage.min.css +303 -207
  152. package/lib/src/css/library.brand-page-designCom.min.css +303 -207
  153. package/lib/src/css/library.brand-page-preview.min.css +303 -207
  154. package/lib/src/index.d.ts +2 -1
  155. package/lib/src/index.mjs +195 -191
  156. package/lib/src/{lib-1AqtEmvQ.js → lib-kGRlD3_P.js} +36855 -33893
  157. package/lib/src/lib.js +2 -1
  158. package/lib/src/metadata-builder/builders/footer-builder.js +4 -5
  159. package/lib/src/metadata-builder/builders/global-role-propagation.d.ts +58 -0
  160. package/lib/src/metadata-builder/builders/global-role-propagation.js +246 -0
  161. package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +1 -0
  162. package/lib/src/metadata-builder/builders/global-styles-builder.js +116 -45
  163. package/lib/src/metadata-builder/builders/header-builder.js +13 -4
  164. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -3
  165. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -3
  166. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -3
  167. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -4
  168. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -3
  169. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -2
  170. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -2
  171. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -4
  172. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -3
  173. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +8 -2
  174. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -2
  175. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +60 -29
  176. package/lib/src/metadata-builder/builders/section-field-maps.js +1 -0
  177. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +48 -19
  178. package/lib/src/metadata-builder/builders/section-field-utils.js +128 -52
  179. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +4 -2
  180. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +28 -12
  181. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +5 -1
  182. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +1 -1
  183. package/lib/src/metadata-builder/helpers/rte.helpers.js +97 -40
  184. package/lib/src/metadata-builder/metadata-executor.js +23 -1
  185. package/lib/src/metadata-builder/models.d.ts +2 -0
  186. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +18 -19
  187. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +18 -1
  188. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +1 -1
  189. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +0 -1
  190. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +5 -8
  191. package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +7 -16
  192. package/lib/src/metadata-builder/sanitizers/section-args-validator.js +95 -22
  193. package/lib/src/shared/color-palette/section-color-matches.js +9 -25
  194. package/lib/src/shared/color-strategies/color-strategies.d.ts +15 -0
  195. package/lib/src/shared/color-strategies/color-strategies.js +31 -0
  196. package/lib/src/shared/color-strategies/rte-color.d.ts +8 -0
  197. package/lib/src/shared/color-strategies/rte-color.js +16 -0
  198. package/lib/src/shared/color-strategies/rte-field-pairs.d.ts +23 -0
  199. package/lib/src/shared/color-strategies/rte-field-pairs.js +28 -0
  200. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +9 -135
  201. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +1 -27
  202. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +12 -2
  203. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +7 -0
  204. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +75 -6
  205. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +18 -7
  206. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +6 -1
  207. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +0 -7
  208. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +1 -0
  209. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +8 -4
  210. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +1255 -26
  211. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.js +203 -59
  212. package/lib/src/shared/content-settings/store/content-settings-store.d.ts +6 -0
  213. package/lib/src/shared/content-settings/store/content-settings-store.js +105 -8
  214. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +5 -1
  215. package/lib/src/shared/navigation-style-settings/store/index.d.ts +7 -3
  216. package/lib/src/shared/navigation-style-settings/store/index.js +40 -15
  217. package/lib/src/shared/page-settings/components/delete-page-modal/DeletePageModal.mixin.d.ts +1 -1
  218. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +1 -0
  219. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +17 -5
  220. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +70 -13
  221. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +10 -2
  222. package/lib/src/shared/page-settings/store/page-settings-store.d.ts +2 -1
  223. package/lib/src/shared/page-settings/store/page-settings-store.js +17 -0
  224. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +4 -1
  225. package/lib/src/shared/rte-extensions/AutoLink.d.ts +17 -0
  226. package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.js +67 -51
  227. package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.js +4 -1
  228. package/lib/src/shared/rte-extensions/TextEffects.d.ts +28 -0
  229. package/lib/src/shared/rte-extensions/TextEffects.js +96 -0
  230. package/lib/src/shared/rte-extensions/ViewDomParser.d.ts +2 -0
  231. package/lib/src/shared/rte-extensions/ViewDomParser.js +21 -0
  232. package/lib/src/shared/rte-extensions.util.d.ts +25 -0
  233. package/lib/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.js → shared/rte-extensions.util.js} +62 -7
  234. package/lib/src/shared/rte-link.util.d.ts +1 -0
  235. package/lib/src/shared/rte-link.util.js +1 -0
  236. package/lib/src/shared/rte-render.util.d.ts +112 -0
  237. package/lib/src/shared/rte-render.util.js +255 -0
  238. package/lib/src/shared/rte-shape.util.d.ts +6 -0
  239. package/lib/src/shared/rte-shape.util.js +18 -0
  240. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +2 -1
  241. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +1 -0
  242. package/lib/src/shared/side-bar/store/side-bar-store.d.ts +2 -0
  243. package/lib/src/shared/side-bar/store/side-bar-store.js +9 -0
  244. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +155 -15
  245. package/lib/src/shared/style-settings/components/StyleSettings.mixin.js +7 -1
  246. package/lib/src/shared/style-settings/store/style-settings-store.d.ts +1 -9
  247. package/lib/src/shared/style-settings/store/style-settings-store.js +3 -33
  248. package/lib/src/shared/style-settings/text-style-size-order.d.ts +2 -0
  249. package/lib/src/shared/style-settings/text-style-size-order.js +13 -0
  250. package/lib/src/shared/text-role-typography.util.d.ts +64 -0
  251. package/lib/src/shared/text-role-typography.util.js +183 -0
  252. package/lib/src/utils/minify-brand-page-metadata.d.ts +16 -1
  253. package/lib/src/utils/minify-brand-page-metadata.js +31 -9
  254. package/package.json +1 -1
  255. package/src/brand-page/__fixtures__/migration-22-v21/edited-brandsite-sections.v21.json +982 -0
  256. package/src/brand-page/__fixtures__/migration-22-v21/new-brandcontact-every-section.v21.json +1231 -0
  257. package/src/brand-page/__fixtures__/migration-22-v21/new-brandpage-every-section.v21.json +1231 -0
  258. package/src/brand-page/__fixtures__/migration-22-v21/new-brandsite-every-section.v21.json +1243 -0
  259. package/src/brand-page/__fixtures__/migration-22-v21/real-brandcontact.v21.json +755 -0
  260. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-general-link.v21.json +527 -0
  261. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-links.v21.json +755 -0
  262. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-social-links.v21.json +514 -0
  263. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-about.v21.json +459 -0
  264. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-footer.v21.json +469 -0
  265. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-header-banner.v21.json +481 -0
  266. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-sections.v21.json +800 -0
  267. package/src/brand-page/__fixtures__/production-text-style-resolver.fixture.ts +52 -0
  268. package/src/brand-page/components/about-section/AboutSection.vue.test.ts +0 -10
  269. package/src/brand-page/components/contact-form/ContactForm.mixin.test.ts +127 -0
  270. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +31 -14
  271. package/src/brand-page/components/contact-form/ContactForm.vue +26 -12
  272. package/src/brand-page/components/contact-form/ContactForm.vue.test.ts +60 -0
  273. package/src/brand-page/components/mailing-list/MailingList.mixin.test.ts +92 -0
  274. package/src/brand-page/components/mailing-list/MailingList.mixin.ts +28 -3
  275. package/src/brand-page/components/mailing-list/MailingList.vue +9 -4
  276. package/src/brand-page/components/mailing-list/MailingList.vue.test.ts +63 -0
  277. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.ts +51 -1
  278. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.test.ts +114 -0
  279. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.vue +8 -2
  280. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.test.ts +182 -0
  281. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.vue +59 -12
  282. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +40 -3
  283. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue +15 -7
  284. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue.test.ts +133 -3
  285. package/src/brand-page/components/page/Page.mixin.ts +41 -34
  286. package/src/brand-page/components/page/Page.vue +17 -6
  287. package/src/brand-page/components/page/Page.vue.test.ts +91 -1
  288. package/src/brand-page/components/page-footer/PageFooter.mixin.ts +32 -2
  289. package/src/brand-page/components/page-footer/PageFooter.test.ts +79 -0
  290. package/src/brand-page/components/page-footer/PageFooter.vue +12 -4
  291. package/src/brand-page/components/payment/Payment.mixin.ts +34 -2
  292. package/src/brand-page/components/payment/Payment.test.ts +188 -0
  293. package/src/brand-page/components/payment/Payment.vue +12 -5
  294. package/src/brand-page/components/payment/RequestPaymentStripe.vue +1 -0
  295. package/src/brand-page/components/payment/support-me/SupportMe.mixin.ts +49 -2
  296. package/src/brand-page/components/payment/support-me/SupportMe.test.ts +100 -0
  297. package/src/brand-page/components/payment/support-me/SupportMe.vue +7 -1
  298. package/src/brand-page/components/payment/support-me/SupportMe.vue.test.ts +66 -0
  299. package/src/brand-page/components/save-contact/SaveContactWidget.test.ts +100 -0
  300. package/src/brand-page/components/save-contact/SaveContactWidget.vue +6 -3
  301. package/src/brand-page/components/shop/PaymentModal.vue +2 -6
  302. package/src/brand-page/components/shop/PaymentShippingAddress.vue +6 -0
  303. package/src/brand-page/components/shop/Shop.vue +15 -2
  304. package/src/brand-page/components/shop/Shop.vue.test.ts +74 -2
  305. package/src/brand-page/components/social-links/SocialLinks.stories.ts +0 -3
  306. package/src/brand-page/components/social-links/SocialLinks.vue.test.ts +0 -3
  307. package/src/brand-page/components/testimonial-section/__fixtures__/data.ts +0 -3
  308. package/src/brand-page/components/text/Text.stories.ts +0 -17
  309. package/src/brand-page/components/text-wrapper/TextWrapper.parity.test.ts +136 -0
  310. package/src/brand-page/components/text-wrapper/TextWrapper.test.ts +358 -0
  311. package/src/brand-page/components/text-wrapper/TextWrapper.vue +82 -22
  312. package/src/brand-page/constants/font.constants.ts +37 -0
  313. package/src/brand-page/models/footer-icon-color.test.ts +22 -0
  314. package/src/brand-page/models/index.ts +50 -28
  315. package/src/brand-page/models/navigation-styles.model.test.ts +77 -1
  316. package/src/brand-page/models/navigation-styles.model.ts +26 -9
  317. package/src/brand-page/models/payment.model.ts +15 -6
  318. package/src/brand-page/models/styles.model.test.ts +104 -0
  319. package/src/brand-page/models/styles.model.ts +181 -47
  320. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +619 -115
  321. package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +150 -9
  322. package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +300 -18
  323. package/src/brand-page/utils/color-palette.util.test.ts +126 -1
  324. package/src/brand-page/utils/color-palette.util.ts +92 -26
  325. package/src/brand-page/utils/color.util.test.ts +62 -29
  326. package/src/brand-page/utils/color.util.ts +77 -14
  327. package/src/brand-page/utils/container-text-color.util.test.ts +672 -26
  328. package/src/brand-page/utils/container-text-color.util.ts +472 -46
  329. package/src/brand-page/utils/index.ts +1 -0
  330. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/edited-brandsite-sections.v22.json +1191 -0
  331. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandcontact-every-section.v22.json +2026 -0
  332. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandpage-every-section.v22.json +2017 -0
  333. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandsite-every-section.v22.json +2031 -0
  334. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandcontact.v22.json +1145 -0
  335. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-general-link.v22.json +645 -0
  336. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-links.v22.json +1136 -0
  337. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-social-links.v22.json +662 -0
  338. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-about.v22.json +638 -0
  339. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-footer.v22.json +610 -0
  340. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-header-banner.v22.json +660 -0
  341. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-sections.v22.json +1132 -0
  342. package/src/brand-page/utils/migration/migration-01.ts +293 -237
  343. package/src/brand-page/utils/migration/migration-02.ts +8 -1
  344. package/src/brand-page/utils/migration/migration-20.ts +6 -3
  345. package/src/brand-page/utils/migration/migration-20_5.test.ts +5 -2
  346. package/src/brand-page/utils/migration/migration-21.test.ts +34 -0
  347. package/src/brand-page/utils/migration/migration-21.ts +46 -10
  348. package/src/brand-page/utils/migration/migration-22.fixed-input.test.ts +43 -0
  349. package/src/brand-page/utils/migration/migration-22.test.ts +4103 -0
  350. package/src/brand-page/utils/migration/migration-22.text-font-family.test.ts +72 -0
  351. package/src/brand-page/utils/migration/migration-22.ts +1336 -0
  352. package/src/brand-page/utils/migration.util.test.ts +146 -32
  353. package/src/brand-page/utils/migration.util.ts +18 -0
  354. package/src/brand-page/utils/model.util.ts +4 -0
  355. package/src/brand-page/utils/personalisation.util.test.ts +148 -3
  356. package/src/brand-page/utils/personalisation.util.ts +9 -1
  357. package/src/brand-page/utils/rte-role-lift.util.ts +409 -0
  358. package/src/brand-page/utils/style.util.test.ts +35 -2
  359. package/src/brand-page/utils/style.util.ts +45 -11
  360. package/src/brand-page/utils/text-role-css.util.test.ts +525 -0
  361. package/src/brand-page/utils/text-role-css.util.ts +321 -0
  362. package/src/brand-page/utils/text-role-reconnect.util.test.ts +604 -0
  363. package/src/brand-page/utils/text-role-reconnect.util.ts +727 -0
  364. package/src/brand-page/utils/text-style.util.test.ts +305 -0
  365. package/src/brand-page/utils/text-style.util.ts +198 -24
  366. package/src/brand-page/utils/view-model.page-data.test.ts +232 -0
  367. package/src/brand-page/utils/view-model.util.test.ts +954 -133
  368. package/src/brand-page/utils/view-model.util.ts +187 -139
  369. package/src/brand-page/view-models.ts +4 -0
  370. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.blank-site.test.ts +57 -0
  371. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +9 -5
  372. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -10
  373. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.ts +0 -1
  374. package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.ts +0 -44
  375. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +253 -200
  376. package/src/brand-page-maker/components/shop/AddOrEditProductContainer.vue +1 -0
  377. package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +1 -0
  378. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +2 -0
  379. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +1 -0
  380. package/src/brand-page-maker/composables/rich-text-editor/block-typography.test.ts +519 -0
  381. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +1 -1
  382. package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.test.ts +26 -1
  383. package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.test.ts +110 -0
  384. package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.ts +99 -0
  385. package/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.ts +397 -0
  386. package/src/brand-page-maker/composables/rich-text-editor/extensions/ViewDomParser.test.ts +139 -0
  387. package/src/brand-page-maker/composables/rich-text-editor/font.ts +36 -5
  388. package/src/brand-page-maker/composables/rich-text-editor/formatting.test.ts +375 -1
  389. package/src/brand-page-maker/composables/rich-text-editor/formatting.ts +301 -17
  390. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.test.ts +82 -1
  391. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.ts +28 -34
  392. package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.test.ts +80 -0
  393. package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.ts +75 -0
  394. package/src/brand-page-maker/composables/rich-text-editor/spacing.ts +31 -6
  395. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.test.ts +2485 -0
  396. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +435 -337
  397. package/src/brand-page-maker/constants/config-settings-constant.ts +0 -6
  398. package/src/brand-page-maker/convertors/text-css-style-options.convertor.test.ts +43 -0
  399. package/src/brand-page-maker/convertors/text-css-style-options.convertor.ts +6 -2
  400. package/src/brand-page-maker/convertors/text-size-value.convertor.test.ts +24 -0
  401. package/src/brand-page-maker/convertors/text-size-value.convertor.ts +17 -13
  402. package/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.ts +7 -22
  403. package/src/brand-page-maker/default-getters/text-color.default-getter.ts +5 -21
  404. package/src/brand-page-maker/models/content-settings.test.ts +708 -0
  405. package/src/brand-page-maker/models/content-settings.ts +133 -82
  406. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.test.ts +63 -1
  407. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.ts +16 -3
  408. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.test.ts +34 -0
  409. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.ts +4 -2
  410. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +185 -1
  411. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +22 -34
  412. package/src/brand-page-maker/stores/history/history-store.ts +35 -2
  413. package/src/brand-page-maker/utils/__snapshots__/apply-color-strategy.golden.test.ts.snap +528 -0
  414. package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +12 -0
  415. package/src/brand-page-maker/utils/apply-color-strategy.golden.test.ts +2 -0
  416. package/src/brand-page-maker/utils/apply-color-strategy.test.ts +181 -3
  417. package/src/brand-page-maker/utils/apply-color-strategy.ts +36 -4
  418. package/src/brand-page-maker/utils/index.ts +2 -1
  419. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +447 -410
  420. package/src/brand-page-maker/utils/rich-text-editor.util.ts +610 -506
  421. package/src/brand-page-maker/utils/rte-authoring.util.test.ts +244 -0
  422. package/src/brand-page-maker/utils/rte-authoring.util.ts +175 -0
  423. package/src/brand-page-maker/utils/rte-clipboard.util.test.ts +558 -0
  424. package/src/brand-page-maker/utils/rte-clipboard.util.ts +473 -0
  425. package/src/brand-page-maker/utils/rte-features.test.ts +99 -3
  426. package/src/brand-page-maker/utils/rte-render-parity.test.ts +1 -1
  427. package/src/brand-page-maker/utils/rte-render.util.test.ts +230 -0
  428. package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +1 -1
  429. package/src/brand-page-maker/utils/rte-sanitize.util.ts +14 -3
  430. package/src/brand-page-maker/utils/rte-schema-version.test.ts +102 -0
  431. package/src/bundles/bundled-translations.de-DE.json +21 -2
  432. package/src/bundles/bundled-translations.es-ES.json +21 -2
  433. package/src/bundles/bundled-translations.fr-CA.json +21 -2
  434. package/src/bundles/bundled-translations.fr-FR.json +21 -2
  435. package/src/bundles/bundled-translations.json +21 -2
  436. package/src/bundles/bundled-translations.pt-BR.json +21 -2
  437. package/src/bundles/bundled-translations.pt-PT.json +21 -2
  438. package/src/clients/ai-assistant-client.ts +1 -0
  439. package/src/composables/useTranslate.ts +2 -1
  440. package/src/lib.ts +2 -2
  441. package/src/metadata-builder/builders/footer-builder.test.ts +70 -45
  442. package/src/metadata-builder/builders/footer-builder.ts +4 -8
  443. package/src/metadata-builder/builders/global-role-propagation.test.ts +907 -0
  444. package/src/metadata-builder/builders/global-role-propagation.ts +430 -0
  445. package/src/metadata-builder/builders/global-styles-builder.test.ts +1020 -0
  446. package/src/metadata-builder/builders/global-styles-builder.ts +194 -48
  447. package/src/metadata-builder/builders/header-builder.test.ts +112 -40
  448. package/src/metadata-builder/builders/header-builder.ts +18 -8
  449. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +5 -3
  450. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +5 -3
  451. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -3
  452. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +7 -4
  453. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +5 -3
  454. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +3 -2
  455. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +3 -2
  456. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +7 -7
  457. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +5 -3
  458. package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +2 -2
  459. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +21 -10
  460. package/src/metadata-builder/builders/section-builders/support-me-builder.test.ts +10 -0
  461. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +3 -2
  462. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +111 -61
  463. package/src/metadata-builder/builders/section-field-maps.ts +1 -0
  464. package/src/metadata-builder/builders/section-field-utils.test.ts +545 -2
  465. package/src/metadata-builder/builders/section-field-utils.ts +202 -69
  466. package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +38 -13
  467. package/src/metadata-builder/builders/section-rules/social-links.rules.ts +5 -0
  468. package/src/metadata-builder/helpers/rte.helpers.test.ts +101 -0
  469. package/src/metadata-builder/helpers/rte.helpers.ts +129 -43
  470. package/src/metadata-builder/metadata-executor.test.ts +167 -0
  471. package/src/metadata-builder/metadata-executor.ts +34 -1
  472. package/src/metadata-builder/models.ts +2 -0
  473. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +23 -7
  474. package/src/metadata-builder/parsers/section-tool-arguments.ts +21 -1
  475. package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +215 -0
  476. package/src/metadata-builder/sanitizers/rte-schema-check.ts +1 -1
  477. package/src/metadata-builder/sanitizers/sanitizer-rules.ts +4 -8
  478. package/src/metadata-builder/sanitizers/section-args-validator.ts +136 -53
  479. package/src/shared/color-palette/section-color-matches.test.ts +15 -11
  480. package/src/shared/color-palette/section-color-matches.ts +9 -28
  481. package/src/shared/color-strategies/color-strategies.ts +35 -0
  482. package/src/shared/color-strategies/rte-color.test.ts +1 -1
  483. package/src/shared/color-strategies/rte-color.ts +19 -0
  484. package/src/shared/color-strategies/rte-field-pairs.test.ts +26 -5
  485. package/src/shared/color-strategies/rte-field-pairs.ts +33 -0
  486. package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.test.ts +43 -66
  487. package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.vue +7 -1
  488. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +1 -48
  489. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +33 -7
  490. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.test.ts +128 -1
  491. package/src/shared/content-settings/components/draggable-item-list/DraggableItemList.vue +1 -0
  492. package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +0 -6
  493. package/src/shared/content-settings/components/logo-selection-field/LogoSelection.vue +3 -0
  494. package/src/shared/content-settings/components/logo-size-field/LogoSizeSlider.vue +3 -0
  495. package/src/shared/content-settings/components/logo-size-field/LogoSizeSliderField.vue +1 -0
  496. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +1 -0
  497. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.test.ts +56 -3
  498. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +11 -4
  499. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.test.ts +335 -25
  500. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.ts +248 -70
  501. package/src/shared/content-settings/components/text-style-field/TextStyleField.vue +113 -25
  502. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.de-DE.json +17 -10
  503. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.es-ES.json +17 -10
  504. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-CA.json +17 -10
  505. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-FR.json +17 -10
  506. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.json +8 -1
  507. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-BR.json +17 -10
  508. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-PT.json +17 -10
  509. package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.test.ts +141 -0
  510. package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.vue +136 -0
  511. package/src/shared/content-settings/store/content-settings-store.test.ts +491 -6
  512. package/src/shared/content-settings/store/content-settings-store.ts +159 -17
  513. package/src/shared/logo-settings/components/EditLogoSettings.vue +1 -0
  514. package/src/shared/logo-settings/components/LogoVariations.vue +1 -0
  515. package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.vue +1 -0
  516. package/src/shared/navigation-style-settings/store/index.test.ts +295 -0
  517. package/src/shared/navigation-style-settings/store/index.ts +65 -15
  518. package/src/shared/page-settings/components/header-settings-panel/HeaderSettingsPanel.vue +2 -0
  519. package/src/shared/page-settings/components/page-settings/PageElement.vue +1 -0
  520. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.test.ts +44 -4
  521. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.vue +13 -4
  522. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.navigation.test.ts +89 -0
  523. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.text-style.test.ts +91 -0
  524. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +14 -2
  525. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.vue +2 -0
  526. package/src/shared/page-settings/store/page-settings-store.text-style.test.ts +84 -0
  527. package/src/shared/page-settings/store/page-settings-store.ts +30 -1
  528. package/src/shared/rte-extensions/AutoLink.test.ts +98 -0
  529. package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.ts +87 -58
  530. package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.ts +4 -1
  531. package/src/shared/rte-extensions/TextEffects.ts +151 -0
  532. package/src/shared/rte-extensions/ViewDomParser.ts +27 -0
  533. package/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.ts → shared/rte-extensions.util.ts} +66 -9
  534. package/src/shared/rte-link.util.ts +2 -0
  535. package/src/shared/rte-render.util.ts +385 -0
  536. package/src/shared/rte-shape.util.ts +29 -0
  537. package/src/shared/side-bar/store/side-bar-store.test.ts +27 -1
  538. package/src/shared/side-bar/store/side-bar-store.ts +11 -0
  539. package/src/shared/style-settings/components/StyleSettings.mixin.ts +7 -3
  540. package/src/shared/style-settings/components/StyleSettings.test.ts +116 -0
  541. package/src/shared/style-settings/components/StyleSettings.vue +75 -25
  542. package/src/shared/style-settings/components/i18n/style-settings.de-DE.json +32 -20
  543. package/src/shared/style-settings/components/i18n/style-settings.es-ES.json +32 -20
  544. package/src/shared/style-settings/components/i18n/style-settings.fr-CA.json +32 -20
  545. package/src/shared/style-settings/components/i18n/style-settings.fr-FR.json +32 -20
  546. package/src/shared/style-settings/components/i18n/style-settings.json +13 -3
  547. package/src/shared/style-settings/components/i18n/style-settings.pt-BR.json +32 -20
  548. package/src/shared/style-settings/components/i18n/style-settings.pt-PT.json +32 -20
  549. package/src/shared/style-settings/components/text-style-options-settings-with-state/TextStyleOptionsSettingsWithState.vue +14 -34
  550. package/src/shared/style-settings/store/style-settings-store.ts +3 -49
  551. package/src/shared/style-settings/text-style-size-order.test.ts +76 -0
  552. package/src/shared/style-settings/text-style-size-order.ts +28 -0
  553. package/src/shared/template-settings/components/TemplatesSettings.vue +4 -0
  554. package/src/shared/text-role-typography.util.ts +277 -0
  555. package/src/utils/minify-brand-page-metadata.test.ts +102 -7
  556. package/src/utils/minify-brand-page-metadata.ts +62 -8
  557. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.d.ts +0 -2
  558. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
  559. package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -63
  560. package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -106
  561. package/lib/src/brand-page-maker/utils/rte-shape.d.ts +0 -18
  562. package/lib/src/brand-page-maker/utils/rte-shape.js +0 -21
  563. package/lib/src/metadata-builder/builders/global-font-propagation.d.ts +0 -41
  564. package/lib/src/metadata-builder/builders/global-font-propagation.js +0 -146
  565. package/src/brand-page-maker/utils/rte-render.util.ts +0 -179
  566. package/src/brand-page-maker/utils/rte-shape.ts +0 -29
  567. package/src/metadata-builder/builders/global-font-propagation.test.ts +0 -401
  568. package/src/metadata-builder/builders/global-font-propagation.ts +0 -238
  569. package/src/shared/style-settings/components/StyleSettingsSection.vue +0 -8
  570. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.d.ts +0 -0
  571. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.js +0 -0
  572. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.d.ts +0 -0
  573. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.js +0 -0
  574. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.d.ts +0 -0
  575. /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.ts +0 -0
  576. /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.ts +0 -0
@@ -6,6 +6,8 @@ import { validateTestimonialSection } from '../../builders/section-rules/testimo
6
6
  import { validateSocialLinks } from '../../builders/section-rules/social-links.rules';
7
7
  import { validateTextSection } from '../../builders/section-rules/text-section.rules';
8
8
  import { validateMailingList } from '../../builders/section-rules/mailing-list.rules';
9
+ import { getSchema } from '@tiptap/core';
10
+ import { getRteExtensions } from '@shared/rte-extensions.util';
9
11
 
10
12
  // ─── helpers ─────────────────────────────────────────────────────────────────
11
13
 
@@ -683,6 +685,68 @@ describe('RTE inline mark style validation', () => {
683
685
  });
684
686
  });
685
687
 
688
+ describe('textDecoration in textStyle mark', () => {
689
+ // The maker's strike + underline toggles compose text-decoration (formatting.ts's
690
+ // decorationSet/composeDecoration), and the role-lift migration of a legacy <u><s> run does the
691
+ // same (rte-role-lift.util.ts) — a mark echoed back by the AI must accept that combined value,
692
+ // not just a single keyword, the same as a role definition does.
693
+ it('accepts a combined text-decoration value ("underline line-through")', () => {
694
+ const errors = validateBannerSection(
695
+ {
696
+ title: rteDoc([
697
+ textStyleMark({ textDecoration: 'underline line-through' }),
698
+ ]),
699
+ } as any,
700
+ {},
701
+ );
702
+
703
+ expect(errors).toHaveLength(0);
704
+ });
705
+
706
+ it('accepts the compatible reset marker used to remove a role underline', () => {
707
+ const errors = validateBannerSection(
708
+ {
709
+ title: rteDoc([
710
+ textStyleMark({
711
+ textDecoration: 'line-through',
712
+ textDecorationReset: true,
713
+ }),
714
+ ]),
715
+ } as any,
716
+ {},
717
+ );
718
+
719
+ expect(errors).toHaveLength(0);
720
+ });
721
+
722
+ it('continues accepting the legacy reset-plus-strike representation', () => {
723
+ const errors = validateBannerSection(
724
+ {
725
+ title: rteDoc([
726
+ textStyleMark({ textDecoration: 'none line-through' }),
727
+ ]),
728
+ } as any,
729
+ {},
730
+ );
731
+
732
+ expect(errors).toHaveLength(0);
733
+ });
734
+
735
+ it('rejects a repeated textDecoration keyword ("underline underline")', () => {
736
+ const errors = validateBannerSection(
737
+ {
738
+ title: rteDoc([
739
+ textStyleMark({ textDecoration: 'underline underline' }),
740
+ ]),
741
+ } as any,
742
+ {},
743
+ );
744
+
745
+ expect(errors).toHaveLength(1);
746
+ expect(errors[0]).toMatch(/textDecoration/);
747
+ });
748
+ });
749
+
686
750
  it('errors when an item array text field contains an invalid textStyle mark', () => {
687
751
  const errors = validateImagesSection(
688
752
  {
@@ -696,4 +760,155 @@ describe('RTE inline mark style validation', () => {
696
760
  expect(errors[0]).toMatch(/fontSize/);
697
761
  expect(errors[0]).toMatch(/out of bounds/);
698
762
  });
763
+
764
+ // BP-5969 R17 — a role var ref on its own baked attr passes; any other var(...) still fails.
765
+ describe('role var refs', () => {
766
+ it('passes a banner title and a text-section item whose marks carry the four role refs', () => {
767
+ const roleMarks = textStyleMark({
768
+ fontFamily: 'var(--role-font-family)',
769
+ fontSize: 'var(--role-font-size)',
770
+ lineHeight: 'var(--role-line-height)',
771
+ letterSpacing: 'var(--role-letter-spacing)',
772
+ });
773
+
774
+ expect(
775
+ validateBannerSection({ title: rteDoc([roleMarks]) } as any, {}),
776
+ ).toHaveLength(0);
777
+ expect(
778
+ validateTextSection(
779
+ { items: [{ text: rteDoc([roleMarks]) }] } as any,
780
+ {},
781
+ ),
782
+ ).toHaveLength(0);
783
+ });
784
+
785
+ // F1 (regression from B5, 2026-10-01) — B5's fontWeight/fontStyle/textDecoration enum checks
786
+ // ran on RTE marks too, but the role-ref exemption only listed the original 4 attrs. The
787
+ // maker's relink (relinkTypographyChain, relinkDocToRole) bakes all 7 as refs, so an AI call
788
+ // echoing a stored doc that carries them was rejected.
789
+ it('passes a mark carrying all 7 baked attrs as their own role ref', () => {
790
+ const roleMarks = textStyleMark({
791
+ fontFamily: 'var(--role-font-family)',
792
+ fontSize: 'var(--role-font-size)',
793
+ lineHeight: 'var(--role-line-height)',
794
+ letterSpacing: 'var(--role-letter-spacing)',
795
+ fontWeight: 'var(--role-font-weight)',
796
+ fontStyle: 'var(--role-font-style)',
797
+ textDecoration: 'var(--role-text-decoration)',
798
+ });
799
+
800
+ expect(
801
+ validateBannerSection({ title: rteDoc([roleMarks]) } as any, {}),
802
+ ).toHaveLength(0);
803
+ });
804
+
805
+ it('rejects a fontWeight/fontStyle/textDecoration ref on the wrong attr', () => {
806
+ const wrongAttr = validateBannerSection(
807
+ {
808
+ title: rteDoc([
809
+ textStyleMark({ fontWeight: 'var(--role-font-style)' }),
810
+ ]),
811
+ } as any,
812
+ {},
813
+ );
814
+
815
+ expect(wrongAttr).toHaveLength(1);
816
+ expect(wrongAttr[0]).toMatch(/fontWeight/);
817
+ });
818
+
819
+ it('rejects a var(...) that names the wrong attr, wrong role property, or a palette ref', () => {
820
+ const wrongAttr = validateBannerSection(
821
+ {
822
+ title: rteDoc([
823
+ textStyleMark({ fontFamily: 'var(--role-font-size)' }),
824
+ ]),
825
+ } as any,
826
+ {},
827
+ );
828
+ const wrongVar = validateBannerSection(
829
+ {
830
+ title: rteDoc([textStyleMark({ fontSize: 'var(--role-size)' })]),
831
+ } as any,
832
+ {},
833
+ );
834
+ const paletteRef = validateBannerSection(
835
+ {
836
+ title: rteDoc([textStyleMark({ fontSize: 'var(--palette-1)' })]),
837
+ } as any,
838
+ {},
839
+ );
840
+ const extraText = validateBannerSection(
841
+ {
842
+ title: rteDoc([
843
+ textStyleMark({ fontSize: 'var(--role-font-size) 2em' }),
844
+ ]),
845
+ } as any,
846
+ {},
847
+ );
848
+
849
+ expect(wrongAttr).toHaveLength(1);
850
+ expect(wrongAttr[0]).toMatch(/fontFamily/);
851
+ expect(wrongVar).toHaveLength(1);
852
+ expect(wrongVar[0]).toMatch(/fontSize/);
853
+ expect(paletteRef).toHaveLength(1);
854
+ expect(extraText).toHaveLength(1);
855
+ });
856
+
857
+ it('existing literal cases are unchanged', () => {
858
+ expect(
859
+ validateBannerSection(
860
+ { title: rteDoc([textStyleMark({ fontSize: '16px' })]) } as any,
861
+ {},
862
+ )[0],
863
+ ).toMatch(/must use "em" units/);
864
+ expect(
865
+ validateBannerSection(
866
+ {
867
+ title: rteDoc([textStyleMark({ fontFamily: 'Playfair Display' })]),
868
+ } as any,
869
+ {},
870
+ ),
871
+ ).toHaveLength(0);
872
+ });
873
+
874
+ it('a role-ref doc passes rteSchemaCheck and keeps the four attrs through the real ProseMirror schema', () => {
875
+ const errors = validateBannerSection(
876
+ {
877
+ title: rteDoc([
878
+ textStyleMark({
879
+ fontFamily: 'var(--role-font-family)',
880
+ fontSize: 'var(--role-font-size)',
881
+ lineHeight: 'var(--role-line-height)',
882
+ letterSpacing: 'var(--role-letter-spacing)',
883
+ }),
884
+ ]),
885
+ } as any,
886
+ {},
887
+ );
888
+
889
+ expect(errors).toHaveLength(0);
890
+
891
+ const schema = getSchema(getRteExtensions());
892
+ const node = schema.nodeFromJSON(
893
+ rteDoc([
894
+ textStyleMark({
895
+ fontFamily: 'var(--role-font-family)',
896
+ fontSize: 'var(--role-font-size)',
897
+ lineHeight: 'var(--role-line-height)',
898
+ letterSpacing: 'var(--role-letter-spacing)',
899
+ }),
900
+ ]),
901
+ );
902
+ const mark = node.content.firstChild?.firstChild?.marks.find(
903
+ (m) => m.type.name === 'textStyle',
904
+ );
905
+
906
+ expect(mark?.attrs).toMatchObject({
907
+ fontFamily: 'var(--role-font-family)',
908
+ fontSize: 'var(--role-font-size)',
909
+ lineHeight: 'var(--role-line-height)',
910
+ letterSpacing: 'var(--role-letter-spacing)',
911
+ });
912
+ });
913
+ });
699
914
  });
@@ -1,6 +1,6 @@
1
1
  import { getSchema } from '@tiptap/core';
2
2
  import type { Schema } from '@tiptap/pm/model';
3
- import { getRteExtensions } from '../../brand-page-maker/composables/rich-text-editor/getRteExtensions';
3
+ import { getRteExtensions } from '@shared/rte-extensions.util';
4
4
  import { isTiptapDocument } from '../parsers/section-tool-arguments';
5
5
  import {
6
6
  rteStyleCheck,
@@ -13,7 +13,6 @@ import {
13
13
  MIN_LETTER_SPACING_PERCENT,
14
14
  MAX_LETTER_SPACING_PERCENT,
15
15
  FONT_FAMILY_CONFIGS,
16
- FONT_FAMILY_KEYS,
17
16
  } from '../../brand-page/constants/font.constants';
18
17
  import {
19
18
  MAX_PAGE_TITLE_LENGTH,
@@ -31,9 +30,9 @@ import { pxToEm } from '../../brand-page-maker/utils/text.util';
31
30
  // Applies to any TextStyleArguments object (section styles, global styles,
32
31
  // header/footer viewport overrides).
33
32
  //
34
- // fontFamilyNames / fontFamilyKeys use Set (not readonly arrays) because both
35
- // are derived dynamically from FONT_FAMILY_CONFIGS at runtime — as const
36
- // literal narrowing is not possible. Consumers call .has(value).
33
+ // fontFamilyNames uses a Set (not a readonly array) because it is derived
34
+ // dynamically from FONT_FAMILY_CONFIGS at runtime — as const literal narrowing
35
+ // is not possible. Consumers call .has(value).
37
36
 
38
37
  export const STYLE_RULES = {
39
38
  // fontSize bounds are in px (natural unit for clamping).
@@ -53,9 +52,7 @@ export const STYLE_RULES = {
53
52
  min: MIN_LETTER_SPACING_PERCENT,
54
53
  max: MAX_LETTER_SPACING_PERCENT,
55
54
  },
56
- // Two separate sets because the format differs by context:
57
- // TextStyleArguments.fontFamily → display name (e.g. 'Playfair Display')
58
- // UpdateGlobalStylesArguments.textFontFamily → camelCase key (e.g. 'playfairDisplay')
55
+ // Every font the AI sends is a display name (e.g. 'Playfair Display').
59
56
  fontFamilyNames: new Set(
60
57
  Object.values(FONT_FAMILY_CONFIGS).map((c) =>
61
58
  // Some font names are stored with surrounding single-quotes (e.g. "'Exo 2'").
@@ -63,7 +60,6 @@ export const STYLE_RULES = {
63
60
  c.name.replace(/^'(.*)'$/, '$1'),
64
61
  ),
65
62
  ),
66
- fontFamilyKeys: new Set(Object.keys(FONT_FAMILY_KEYS)),
67
63
  } as const;
68
64
 
69
65
  // ─── 2. Logo size rules ───────────────────────────────────────────────────────
@@ -11,7 +11,16 @@ import {
11
11
  type ItemCapRule,
12
12
  } from './sanitizer-rules';
13
13
 
14
- // ─── Helpers ──────────────────────────────────────────────────────────────────
14
+ // Kept local to avoid the validator/schema import cycle.
15
+ const ROLE_VAR_REF: Readonly<Record<string, string>> = {
16
+ fontFamily: 'var(--role-font-family)',
17
+ fontSize: 'var(--role-font-size)',
18
+ lineHeight: 'var(--role-line-height)',
19
+ letterSpacing: 'var(--role-letter-spacing)',
20
+ fontWeight: 'var(--role-font-weight)',
21
+ fontStyle: 'var(--role-font-style)',
22
+ textDecoration: 'var(--role-text-decoration)',
23
+ };
15
24
 
16
25
  function extractPlainText(value: string | TiptapDocument): string {
17
26
  if (typeof value === 'string') return value;
@@ -23,14 +32,6 @@ function extractPlainText(value: string | TiptapDocument): string {
23
32
  .join('');
24
33
  }
25
34
 
26
- // ─── Style property checks (compiled from STYLE_RULES at module init) ─────────
27
- //
28
- // Each check takes (fieldLabel, style) → string | null.
29
- // STYLE_RULES is the base — no if-conditions in validateStyleArgs itself.
30
- //
31
- // TiptapDocument inline mark styles (textStyle marks within RTE content) are
32
- // validated by validateRteMarkStyle / validateRteDocument below.
33
-
34
35
  type StylePropertyCheck = (
35
36
  fieldLabel: string,
36
37
  style: TextStyleArguments,
@@ -102,23 +103,77 @@ function validateStyleArgs(
102
103
  });
103
104
  }
104
105
 
105
- // ─── RTE mark style validation ───────────────────────────────────────────────
106
- //
107
- // Mark attrs are all strings, unlike TextStyleArguments which uses numbers for
108
- // lineHeight and letterSpacing. Key format differences:
109
- // lineHeight → unitless string "1.5" (not a number)
110
- // letterSpacing → em string "0.05em" (percent / 100; range: [0em, 1em])
106
+ interface ValidatableStyleAttrs {
107
+ fontSize?: string | null;
108
+ fontFamily?: string | null;
109
+ lineHeight?: string | null;
110
+ letterSpacing?: string | null;
111
+ fontWeight?: string | null;
112
+ fontStyle?: string | null;
113
+ textDecoration?: string | null;
114
+ }
111
115
 
112
116
  type RteMarkCheck = (
113
117
  path: string,
114
- attrs: NonNullable<TiptapMark['attrs']>,
118
+ attrs: ValidatableStyleAttrs,
115
119
  ) => string | null;
116
120
 
121
+ const isNoValue = (value: string | null | undefined): boolean =>
122
+ value == null || value === '';
123
+
124
+ const FONT_WEIGHT_VALUES = new Set([
125
+ 'normal',
126
+ 'bold',
127
+ 'bolder',
128
+ 'lighter',
129
+ '100',
130
+ '200',
131
+ '300',
132
+ '400',
133
+ '500',
134
+ '600',
135
+ '700',
136
+ '800',
137
+ '900',
138
+ ]);
139
+ const FONT_STYLE_VALUES = new Set(['normal', 'italic', 'oblique']);
140
+
141
+ const TEXT_DECORATION_KEYWORDS = new Set([
142
+ 'underline',
143
+ 'line-through',
144
+ 'overline',
145
+ ]);
146
+
147
+ const isValidTextDecoration = (
148
+ value: string,
149
+ allowRoleReset = false,
150
+ ): boolean => {
151
+ const flags = value.trim().toLowerCase().split(/\s+/).filter(Boolean);
152
+
153
+ if (flags.length === 0) return false;
154
+
155
+ if (flags[0] === 'none') {
156
+ return (
157
+ (flags.length === 1 ||
158
+ (allowRoleReset &&
159
+ flags
160
+ .slice(1)
161
+ .every((flag) => TEXT_DECORATION_KEYWORDS.has(flag)))) &&
162
+ new Set(flags).size === flags.length
163
+ );
164
+ }
165
+
166
+ return (
167
+ flags.every((flag) => TEXT_DECORATION_KEYWORDS.has(flag)) &&
168
+ new Set(flags).size === flags.length
169
+ );
170
+ };
171
+
117
172
  const RTE_MARK_PROPERTY_CHECKS: RteMarkCheck[] = [
118
173
  (path, attrs) => {
119
- if (attrs.fontSize == null) return null;
174
+ if (isNoValue(attrs.fontSize)) return null;
120
175
 
121
- const raw = attrs.fontSize.trim().toLowerCase();
176
+ const raw = String(attrs.fontSize).trim().toLowerCase();
122
177
  const unit = fontUnit.allowedUnits[0];
123
178
  const match = raw.match(new RegExp(`^(\\d+(?:\\.\\d+)?)${unit}$`));
124
179
 
@@ -136,18 +191,19 @@ const RTE_MARK_PROPERTY_CHECKS: RteMarkCheck[] = [
136
191
  },
137
192
 
138
193
  (path, attrs) => {
139
- if (attrs.fontFamily == null) return null;
194
+ if (isNoValue(attrs.fontFamily)) return null;
140
195
 
141
- return !fontFamilyNames.has(attrs.fontFamily)
196
+ return !fontFamilyNames.has(attrs.fontFamily!)
142
197
  ? `"${path}.fontFamily" "${attrs.fontFamily}" is not a recognized font family`
143
198
  : null;
144
199
  },
145
200
 
146
201
  (path, attrs) => {
147
- if (attrs.lineHeight == null) return null;
202
+ if (isNoValue(attrs.lineHeight)) return null;
148
203
 
149
- const val = parseFloat(attrs.lineHeight);
150
- const isUnitless = !isNaN(val) && attrs.lineHeight.trim() === String(val);
204
+ const val = parseFloat(attrs.lineHeight!);
205
+ const isUnitless =
206
+ !isNaN(val) && String(attrs.lineHeight).trim() === String(val);
151
207
 
152
208
  if (!isUnitless) {
153
209
  return `"${path}.lineHeight" must be a unitless number (got "${attrs.lineHeight}")`;
@@ -159,12 +215,11 @@ const RTE_MARK_PROPERTY_CHECKS: RteMarkCheck[] = [
159
215
  },
160
216
 
161
217
  (path, attrs) => {
162
- if (attrs.letterSpacing == null) return null;
218
+ if (isNoValue(attrs.letterSpacing)) return null;
163
219
 
164
- const raw = attrs.letterSpacing.trim().toLowerCase();
220
+ const raw = String(attrs.letterSpacing).trim().toLowerCase();
165
221
 
166
- // "0" is valid CSS without units — treat as 0em.
167
- if (raw === '0') return null;
222
+ if (raw === '0' || raw === 'normal') return null;
168
223
 
169
224
  const match = raw.match(/^(\d+(?:\.\d+)?)em$/);
170
225
 
@@ -180,25 +235,40 @@ const RTE_MARK_PROPERTY_CHECKS: RteMarkCheck[] = [
180
235
  ? `"${path}.letterSpacing" ${attrs.letterSpacing} is out of bounds (${minEm}em–${maxEm}em)`
181
236
  : null;
182
237
  },
238
+
239
+ (path, attrs) => {
240
+ if (isNoValue(attrs.fontWeight)) return null;
241
+
242
+ return !FONT_WEIGHT_VALUES.has(
243
+ String(attrs.fontWeight).trim().toLowerCase(),
244
+ )
245
+ ? `"${path}.fontWeight" "${attrs.fontWeight}" is not a recognized value`
246
+ : null;
247
+ },
248
+
249
+ (path, attrs) => {
250
+ if (isNoValue(attrs.fontStyle)) return null;
251
+
252
+ return !FONT_STYLE_VALUES.has(String(attrs.fontStyle).trim().toLowerCase())
253
+ ? `"${path}.fontStyle" "${attrs.fontStyle}" is not a recognized value`
254
+ : null;
255
+ },
256
+
257
+ (path, attrs) => {
258
+ if (isNoValue(attrs.textDecoration)) return null;
259
+
260
+ return !isValidTextDecoration(String(attrs.textDecoration))
261
+ ? `"${path}.textDecoration" "${attrs.textDecoration}" is not a recognized value`
262
+ : null;
263
+ },
183
264
  ];
184
265
 
185
- /**
186
- * Validates CSS string-format style attrs (fontSize em, fontFamily name,
187
- * lineHeight unitless, letterSpacing em) against STYLE_RULES bounds.
188
- * Used for both RTE textStyle mark attrs and GlobalStyles textStyleOptions.
189
- * Returns the first error string, or null if all attrs are valid / absent.
190
- */
191
266
  export function validateStringStyleAttrs(
192
267
  path: string,
193
- attrs: {
194
- fontSize?: string | null;
195
- fontFamily?: string | null;
196
- lineHeight?: string | null;
197
- letterSpacing?: string | null;
198
- },
268
+ attrs: ValidatableStyleAttrs,
199
269
  ): string | null {
200
270
  for (const check of RTE_MARK_PROPERTY_CHECKS) {
201
- const err = check(path, attrs as NonNullable<TiptapMark['attrs']>);
271
+ const err = check(path, attrs);
202
272
 
203
273
  if (err) return err;
204
274
  }
@@ -210,7 +280,32 @@ function validateRteMarkStyle(
210
280
  path: string,
211
281
  attrs: NonNullable<TiptapMark['attrs']>,
212
282
  ): string | null {
213
- return validateStringStyleAttrs(path, attrs);
283
+ const literalOnly: ValidatableStyleAttrs = {};
284
+
285
+ for (const [attr, value] of Object.entries(attrs)) {
286
+ if (attr === 'textDecorationReset') {
287
+ if (value !== true && value !== false && value != null) {
288
+ return `"${path}.textDecorationReset" must be a boolean`;
289
+ }
290
+
291
+ continue;
292
+ }
293
+
294
+ if (
295
+ attr === 'textDecoration' &&
296
+ typeof value === 'string' &&
297
+ value.trim().startsWith('none ') &&
298
+ isValidTextDecoration(value, true)
299
+ ) {
300
+ continue;
301
+ }
302
+
303
+ if (value !== ROLE_VAR_REF[attr]) {
304
+ literalOnly[attr as keyof ValidatableStyleAttrs] = value as string | null;
305
+ }
306
+ }
307
+
308
+ return validateStringStyleAttrs(path, literalOnly);
214
309
  }
215
310
 
216
311
  function validateRteDocument(
@@ -234,24 +329,16 @@ function validateRteDocument(
234
329
  return null;
235
330
  }
236
331
 
237
- // ─── Public check API ─────────────────────────────────────────────────────────
238
-
239
332
  export interface ValidationContext {
240
333
  brandPageType?: string;
241
334
  mode?: 'create' | 'update';
242
335
  }
243
336
 
244
- /**
245
- * A pure validation check: record + context → one error string or null.
246
- * All checks operate on Record<string, unknown> — no concrete section type casting.
247
- */
248
337
  export type SectionCheck = (
249
338
  record: Record<string, unknown>,
250
339
  ctx: ValidationContext,
251
340
  ) => string | null;
252
341
 
253
- // ─── Check factories ──────────────────────────────────────────────────────────
254
-
255
342
  export const textCheck =
256
343
  (field: string, max: number): SectionCheck =>
257
344
  (record) => {
@@ -393,10 +480,6 @@ export const itemCapCheck =
393
480
  : null;
394
481
  };
395
482
 
396
- /**
397
- * Runs an array of SectionChecks against the given args and context.
398
- * Returns all non-null error strings.
399
- */
400
483
  export function runChecks(
401
484
  checks: SectionCheck[],
402
485
  args: Record<string, unknown>,
@@ -276,17 +276,21 @@ describe('collectSectionColorMatches — text styles', () => {
276
276
  });
277
277
  });
278
278
 
279
- test('with no colour of its own it reports the linked style’s colour and role', () => {
279
+ test('with no colour of its own it reports what it inherits — the role colour is ignored (ADR-0020)', () => {
280
280
  const [match] = collectSectionColorMatches(
281
281
  config,
282
282
  { titleStyle: { textStyleType: 'titles' } },
283
283
  { textStyleOptions },
284
284
  );
285
285
 
286
- expect(match.entries[0]).toMatchObject({
287
- value: OTHER_ROLE,
288
- state: { kind: 'brand', roleId: 'palette-0' },
286
+ // The role's colour (OTHER_ROLE) no longer flows; with no site default given the
287
+ // field simply inherits, naming its link.
288
+ expect(match.entries[0].state).toEqual({
289
+ kind: 'inherits',
290
+ styleType: 'titles',
291
+ inheritedRoleId: undefined,
289
292
  });
293
+ expect(match.origin).toBe('site-default');
290
294
  });
291
295
 
292
296
  test('when neither carries a colour it reports what it inherits', () => {
@@ -665,9 +669,7 @@ describe('collectSectionColorMatches — the text cascade is reported, not flatt
665
669
  expect(match.entries[0].value).toBe(ROLE);
666
670
  });
667
671
 
668
- test('a colour handed down by the global style is origin `global-style`', () => {
669
- // The information the panel used to lose: it showed the resolved colour with
670
- // no hint that changing it means changing every Title on the site.
672
+ test('a role colour is ignored — a link-only field falls to the site default even when its role has a colour (ADR-0020)', () => {
671
673
  const [match] = collectSectionColorMatches(
672
674
  config,
673
675
  { titleStyle: { textStyleType: 'titles' } },
@@ -677,11 +679,13 @@ describe('collectSectionColorMatches — the text cascade is reported, not flatt
677
679
  },
678
680
  );
679
681
 
682
+ // Role colour no longer cascades, so this reads exactly like a role with no colour:
683
+ // the field renders the site base coat, named through its link.
680
684
  expect(match).toMatchObject({
681
- origin: 'global-style',
685
+ origin: 'site-default',
682
686
  originStyleType: 'titles',
683
687
  });
684
- expect(match.entries[0].value).toBe(OTHER_ROLE);
688
+ expect(match.entries[0].value).toBe(SITE_DEFAULT);
685
689
  });
686
690
 
687
691
  test('a linked style with no colour of its own falls to the site default', () => {
@@ -738,7 +742,7 @@ describe('collectSectionColorMatches — the text cascade is reported, not flatt
738
742
  expect(collectSectionColorMatches(config, { titleStyle: {} })).toEqual([]);
739
743
  });
740
744
 
741
- test('a button label follows the same cascade as any other text', () => {
745
+ test('a button label follows the same cascade as any other text (its role colour is ignored too)', () => {
742
746
  const [match] = collectSectionColorMatches(
743
747
  {
744
748
  type: 'about-section',
@@ -749,7 +753,7 @@ describe('collectSectionColorMatches — the text cascade is reported, not flatt
749
753
  );
750
754
 
751
755
  expect(match).toMatchObject({
752
- origin: 'global-style',
756
+ origin: 'site-default',
753
757
  originStyleType: 'buttons',
754
758
  });
755
759
  });