@deriv-com/dds-marketing 1.1.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/.llm/components/accordion.md +6 -0
  2. package/.llm/components/accordionitem.md +6 -0
  3. package/.llm/components/aspectratio.md +6 -0
  4. package/.llm/components/awards.md +6 -0
  5. package/.llm/components/background.md +49 -10
  6. package/.llm/components/badge.md +6 -0
  7. package/.llm/components/bottomsheet.md +6 -0
  8. package/.llm/components/breadcrumb.md +6 -0
  9. package/.llm/components/breadcrumbitem.md +6 -0
  10. package/.llm/components/button.md +9 -3
  11. package/.llm/components/buttonicon.md +7 -1
  12. package/.llm/components/card.md +6 -0
  13. package/.llm/components/cardbody.md +7 -1
  14. package/.llm/components/cardbutton.md +6 -0
  15. package/.llm/components/checkbox.md +6 -0
  16. package/.llm/components/comparisoncards.md +9 -3
  17. package/.llm/components/comparisontable.md +6 -0
  18. package/.llm/components/ctabanner.md +6 -0
  19. package/.llm/components/ctabannerslider.md +6 -0
  20. package/.llm/components/datatable.md +6 -0
  21. package/.llm/components/divider.md +6 -0
  22. package/.llm/components/documentlink.md +237 -0
  23. package/.llm/components/documents.md +268 -0
  24. package/.llm/components/downloadbanner.md +7 -1
  25. package/.llm/components/dropdownmenu.md +6 -0
  26. package/.llm/components/estimator.md +6 -0
  27. package/.llm/components/faqaccordion.md +6 -0
  28. package/.llm/components/featurebullets.md +6 -0
  29. package/.llm/components/featurecards.md +42 -2
  30. package/.llm/components/featurecardscarousel.md +7 -1
  31. package/.llm/components/featurescroll.md +6 -0
  32. package/.llm/components/featuresplit.md +6 -0
  33. package/.llm/components/featurestack.md +6 -0
  34. package/.llm/components/featuretabs.md +369 -0
  35. package/.llm/components/filterchip.md +6 -0
  36. package/.llm/components/footer.md +6 -0
  37. package/.llm/components/footergroup.md +6 -0
  38. package/.llm/components/grid.md +30 -1
  39. package/.llm/components/icon.md +6 -0
  40. package/.llm/components/illustrationcard.md +52 -2
  41. package/.llm/components/illustrationcheck.md +193 -0
  42. package/.llm/components/illustrationchoice.md +187 -0
  43. package/.llm/components/illustrationcode.md +192 -0
  44. package/.llm/components/illustrationlist.md +175 -0
  45. package/.llm/components/illustrationscene.md +29 -3
  46. package/.llm/components/imagebanner.md +30 -5
  47. package/.llm/components/landinghero.md +6 -0
  48. package/.llm/components/link.md +7 -1
  49. package/.llm/components/logocolumns.md +7 -1
  50. package/.llm/components/logorows.md +42 -2
  51. package/.llm/components/menuitem.md +6 -0
  52. package/.llm/components/navbar.md +6 -0
  53. package/.llm/components/navbaritem.md +6 -0
  54. package/.llm/components/navbarmenu.md +6 -0
  55. package/.llm/components/navbarmenugroup.md +6 -0
  56. package/.llm/components/navbarpanel.md +6 -0
  57. package/.llm/components/navbarswitcher.md +6 -0
  58. package/.llm/components/navbarswitcheroption.md +6 -0
  59. package/.llm/components/option.md +6 -0
  60. package/.llm/components/pageheader.md +6 -0
  61. package/.llm/components/pagination.md +6 -0
  62. package/.llm/components/paginationdots.md +6 -0
  63. package/.llm/components/producthero.md +29 -4
  64. package/.llm/components/progressbar.md +305 -0
  65. package/.llm/components/removablechip.md +6 -0
  66. package/.llm/components/resourcebanner.md +6 -0
  67. package/.llm/components/row.md +6 -0
  68. package/.llm/components/scenescroll.md +38 -24
  69. package/.llm/components/scenescrollword.md +267 -0
  70. package/.llm/components/scroller.md +6 -0
  71. package/.llm/components/searchinput.md +6 -0
  72. package/.llm/components/segmentedcontrol.md +28 -1
  73. package/.llm/components/segmentedcontrolitem.md +6 -0
  74. package/.llm/components/select.md +6 -0
  75. package/.llm/components/selectchip.md +6 -0
  76. package/.llm/components/spinner.md +6 -0
  77. package/.llm/components/stack.md +6 -0
  78. package/.llm/components/stats.md +46 -1
  79. package/.llm/components/statscarousel.md +227 -0
  80. package/.llm/components/statusdot.md +41 -1
  81. package/.llm/components/steps.md +6 -0
  82. package/.llm/components/stickycards.md +6 -0
  83. package/.llm/components/subdomainnavbar.md +6 -0
  84. package/.llm/components/tab.md +6 -0
  85. package/.llm/components/table.md +6 -0
  86. package/.llm/components/tablebody.md +6 -0
  87. package/.llm/components/tablecell.md +6 -0
  88. package/.llm/components/tablehead.md +6 -0
  89. package/.llm/components/tableheadercell.md +6 -0
  90. package/.llm/components/tablerow.md +6 -0
  91. package/.llm/components/tablist.md +6 -0
  92. package/.llm/components/teamgrid.md +6 -0
  93. package/.llm/components/testimonialrow.md +43 -3
  94. package/.llm/components/testimonialslider.md +8 -2
  95. package/.llm/components/textarea.md +6 -0
  96. package/.llm/components/textinput.md +6 -0
  97. package/.llm/components/textscroll.md +6 -0
  98. package/.llm/components/tiers.md +13 -7
  99. package/.llm/components/tooltip.md +6 -0
  100. package/.llm/components/typography.md +63 -1
  101. package/.llm/digest/background.md +14 -6
  102. package/.llm/digest/button.md +1 -1
  103. package/.llm/digest/buttonicon.md +1 -1
  104. package/.llm/digest/documentlink.md +52 -0
  105. package/.llm/digest/documents.md +51 -0
  106. package/.llm/digest/downloadbanner.md +1 -1
  107. package/.llm/digest/featurecards.md +7 -0
  108. package/.llm/digest/featuretabs.md +50 -0
  109. package/.llm/digest/grid.md +1 -0
  110. package/.llm/digest/illustrationcard.md +6 -1
  111. package/.llm/digest/illustrationcheck.md +42 -0
  112. package/.llm/digest/illustrationchoice.md +43 -0
  113. package/.llm/digest/illustrationcode.md +41 -0
  114. package/.llm/digest/illustrationlist.md +38 -0
  115. package/.llm/digest/illustrationscene.md +4 -2
  116. package/.llm/digest/imagebanner.md +9 -3
  117. package/.llm/digest/logocolumns.md +1 -1
  118. package/.llm/digest/logorows.md +8 -1
  119. package/.llm/digest/producthero.md +8 -2
  120. package/.llm/digest/progressbar.md +56 -0
  121. package/.llm/digest/scenescroll.md +6 -5
  122. package/.llm/digest/scenescrollword.md +56 -0
  123. package/.llm/digest/segmentedcontrol.md +3 -0
  124. package/.llm/digest/stats.md +8 -0
  125. package/.llm/digest/statscarousel.md +48 -0
  126. package/.llm/digest/statusdot.md +7 -0
  127. package/.llm/digest/testimonialrow.md +8 -1
  128. package/.llm/digest/testimonialslider.md +1 -1
  129. package/.llm/digest/typography.md +18 -0
  130. package/.llm/index.md +14 -4
  131. package/.llm/rules.md +10 -0
  132. package/.llm/tokens.md +12 -3
  133. package/AGENTS.md +13 -2
  134. package/dist/components/arrival.d.ts +32 -0
  135. package/dist/components/arrival.js +140 -0
  136. package/dist/components/arrives.d.ts +17 -0
  137. package/dist/components/arrives.js +14 -0
  138. package/dist/components/blocks/awards/Awards.js +2 -27
  139. package/dist/components/blocks/block-pattern.css +23 -0
  140. package/dist/components/blocks/comparison-cards/comparison-cards-impl.css +29 -0
  141. package/dist/components/blocks/documents/Documents.css +90 -0
  142. package/dist/components/blocks/documents/Documents.d.ts +22 -0
  143. package/dist/components/blocks/documents/Documents.js +30 -0
  144. package/dist/components/blocks/documents/Documents.types.d.ts +37 -0
  145. package/dist/components/blocks/documents/Documents.types.js +14 -0
  146. package/dist/components/blocks/documents/documents-impl.css +103 -0
  147. package/dist/components/blocks/download-banner/DownloadBanner.css +1 -1
  148. package/dist/components/blocks/download-banner/DownloadBanner.types.d.ts +1 -1
  149. package/dist/components/blocks/feature-cards/FeatureCards.d.ts +2 -1
  150. package/dist/components/blocks/feature-cards/FeatureCards.js +10 -7
  151. package/dist/components/blocks/feature-cards/FeatureCards.types.d.ts +9 -1
  152. package/dist/components/blocks/feature-cards/feature-cards-impl.css +15 -3
  153. package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.types.d.ts +1 -1
  154. package/dist/components/blocks/feature-cards-carousel/feature-cards-carousel-impl.css +12 -0
  155. package/dist/components/blocks/feature-tabs/FeatureTabs.css +100 -0
  156. package/dist/components/blocks/feature-tabs/FeatureTabs.d.ts +23 -0
  157. package/dist/components/blocks/feature-tabs/FeatureTabs.js +38 -0
  158. package/dist/components/blocks/feature-tabs/FeatureTabs.types.d.ts +35 -0
  159. package/dist/components/blocks/feature-tabs/FeatureTabs.types.js +14 -0
  160. package/dist/components/blocks/feature-tabs/feature-tabs-impl.css +53 -0
  161. package/dist/components/blocks/image-banner/ImageBanner.css +1 -1
  162. package/dist/components/blocks/image-banner/ImageBanner.d.ts +1 -1
  163. package/dist/components/blocks/image-banner/ImageBanner.js +2 -2
  164. package/dist/components/blocks/image-banner/ImageBanner.types.d.ts +9 -7
  165. package/dist/components/blocks/image-banner/ImageBanner.types.js +1 -1
  166. package/dist/components/blocks/image-banner/image-banner-impl.css +77 -26
  167. package/dist/components/blocks/laurel.d.ts +16 -0
  168. package/dist/components/blocks/laurel.js +28 -0
  169. package/dist/components/blocks/logo-columns/LogoColumns.css +1 -1
  170. package/dist/components/blocks/logo-columns/LogoColumns.types.d.ts +1 -1
  171. package/dist/components/blocks/logo-rows/LogoRows.css +1 -1
  172. package/dist/components/blocks/logo-rows/LogoRows.d.ts +2 -1
  173. package/dist/components/blocks/logo-rows/LogoRows.js +7 -4
  174. package/dist/components/blocks/logo-rows/LogoRows.types.d.ts +9 -1
  175. package/dist/components/blocks/pattern-tone.d.ts +11 -0
  176. package/dist/components/blocks/pattern-tone.js +7 -0
  177. package/dist/components/blocks/product-hero/ProductHero.d.ts +1 -1
  178. package/dist/components/blocks/product-hero/ProductHero.js +2 -2
  179. package/dist/components/blocks/product-hero/ProductHero.types.d.ts +8 -3
  180. package/dist/components/blocks/product-hero/ProductHero.types.js +1 -1
  181. package/dist/components/blocks/product-hero/product-hero-impl.css +54 -0
  182. package/dist/components/blocks/resource-banner/ResourceBanner.css +1 -1
  183. package/dist/components/blocks/scene-scroll/SceneScroll.css +1 -1
  184. package/dist/components/blocks/scene-scroll/SceneScroll.d.ts +6 -5
  185. package/dist/components/blocks/scene-scroll/SceneScroll.js +8 -7
  186. package/dist/components/blocks/scene-scroll/SceneScroll.types.d.ts +5 -5
  187. package/dist/components/blocks/scene-scroll/SceneScroll.types.js +1 -1
  188. package/dist/components/blocks/scene-scroll/scene-scroll-impl.css +61 -44
  189. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.css +105 -0
  190. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.d.ts +31 -0
  191. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.js +67 -0
  192. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.types.d.ts +39 -0
  193. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.types.js +18 -0
  194. package/dist/components/blocks/scene-scroll-word/scene-scroll-word-impl.css +370 -0
  195. package/dist/components/blocks/stats/Stats.d.ts +2 -1
  196. package/dist/components/blocks/stats/Stats.js +17 -14
  197. package/dist/components/blocks/stats/Stats.types.d.ts +8 -0
  198. package/dist/components/blocks/stats/stats-impl.css +4 -1
  199. package/dist/components/blocks/stats/use-wheel.d.ts +1 -1
  200. package/dist/components/blocks/stats/use-wheel.js +8 -4
  201. package/dist/components/blocks/stats-carousel/StatsCarousel.css +209 -0
  202. package/dist/components/blocks/stats-carousel/StatsCarousel.d.ts +20 -0
  203. package/dist/components/blocks/stats-carousel/StatsCarousel.js +48 -0
  204. package/dist/components/blocks/stats-carousel/StatsCarousel.types.d.ts +43 -0
  205. package/dist/components/blocks/stats-carousel/StatsCarousel.types.js +23 -0
  206. package/dist/components/blocks/stats-carousel/stats-carousel-impl.css +233 -0
  207. package/dist/components/blocks/sticky-cards/sticky-cards-impl.css +8 -0
  208. package/dist/components/blocks/testimonial-row/TestimonialRow.css +1 -1
  209. package/dist/components/blocks/testimonial-row/TestimonialRow.d.ts +2 -1
  210. package/dist/components/blocks/testimonial-row/TestimonialRow.js +16 -13
  211. package/dist/components/blocks/testimonial-row/TestimonialRow.types.d.ts +9 -1
  212. package/dist/components/blocks/testimonial-slider/TestimonialSlider.css +1 -1
  213. package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.d.ts +1 -1
  214. package/dist/components/blocks/tiers/Tiers.types.d.ts +1 -1
  215. package/dist/components/core/background/Background.css +19 -0
  216. package/dist/components/core/background/Background.types.d.ts +2 -1
  217. package/dist/components/core/background/background-impl.css +47 -15
  218. package/dist/components/core/background/halftone.js +1 -1
  219. package/dist/components/core/button/Button.css +5 -5
  220. package/dist/components/core/button-icon/ButtonIcon.types.d.ts +1 -1
  221. package/dist/components/core/card-body/CardBody.css +5 -0
  222. package/dist/components/core/card-body/CardBody.types.d.ts +1 -1
  223. package/dist/components/core/document-link/DocumentLink.css +59 -0
  224. package/dist/components/core/document-link/DocumentLink.d.ts +19 -0
  225. package/dist/components/core/document-link/DocumentLink.js +21 -0
  226. package/dist/components/core/document-link/DocumentLink.types.d.ts +41 -0
  227. package/dist/components/core/document-link/DocumentLink.types.js +11 -0
  228. package/dist/components/core/document-link/document-link-impl.css +23 -0
  229. package/dist/components/core/illustration-card/IllustrationCard.css +7 -0
  230. package/dist/components/core/illustration-card/IllustrationCard.d.ts +5 -1
  231. package/dist/components/core/illustration-card/IllustrationCard.js +34 -8
  232. package/dist/components/core/illustration-card/IllustrationCard.types.d.ts +8 -1
  233. package/dist/components/core/illustration-card/IllustrationCard.types.js +1 -0
  234. package/dist/components/core/illustration-card/illustration-card-impl.css +113 -0
  235. package/dist/components/core/illustration-check/IllustrationCheck.css +25 -0
  236. package/dist/components/core/illustration-check/IllustrationCheck.d.ts +16 -0
  237. package/dist/components/core/illustration-check/IllustrationCheck.js +22 -0
  238. package/dist/components/core/illustration-check/IllustrationCheck.types.d.ts +25 -0
  239. package/dist/components/core/illustration-check/IllustrationCheck.types.js +9 -0
  240. package/dist/components/core/illustration-check/illustration-check-impl.css +76 -0
  241. package/dist/components/core/illustration-choice/IllustrationChoice.css +62 -0
  242. package/dist/components/core/illustration-choice/IllustrationChoice.d.ts +16 -0
  243. package/dist/components/core/illustration-choice/IllustrationChoice.js +31 -0
  244. package/dist/components/core/illustration-choice/IllustrationChoice.types.d.ts +25 -0
  245. package/dist/components/core/illustration-choice/IllustrationChoice.types.js +11 -0
  246. package/dist/components/core/illustration-choice/illustration-choice-impl.css +103 -0
  247. package/dist/components/core/illustration-code/IllustrationCode.css +25 -0
  248. package/dist/components/core/illustration-code/IllustrationCode.d.ts +12 -0
  249. package/dist/components/core/illustration-code/IllustrationCode.js +20 -0
  250. package/dist/components/core/illustration-code/IllustrationCode.types.d.ts +23 -0
  251. package/dist/components/core/illustration-code/IllustrationCode.types.js +8 -0
  252. package/dist/components/core/illustration-code/illustration-code-impl.css +42 -0
  253. package/dist/components/core/illustration-list/IllustrationList.css +19 -0
  254. package/dist/components/core/illustration-list/IllustrationList.d.ts +16 -0
  255. package/dist/components/core/illustration-list/IllustrationList.js +18 -0
  256. package/dist/components/core/illustration-list/IllustrationList.types.d.ts +15 -0
  257. package/dist/components/core/illustration-list/IllustrationList.types.js +6 -0
  258. package/dist/components/core/illustration-list/illustration-list-impl.css +52 -0
  259. package/dist/components/core/illustration-scene/IllustrationScene.css +6 -0
  260. package/dist/components/core/illustration-scene/IllustrationScene.d.ts +3 -2
  261. package/dist/components/core/illustration-scene/IllustrationScene.js +4 -3
  262. package/dist/components/core/illustration-scene/IllustrationScene.types.d.ts +5 -1
  263. package/dist/components/core/illustration-scene/IllustrationScene.types.js +2 -1
  264. package/dist/components/core/illustration-scene/illustration-scene-impl.css +65 -0
  265. package/dist/components/core/link/link-impl.css +5 -19
  266. package/dist/components/core/progress-bar/ProgressBar.css +101 -0
  267. package/dist/components/core/progress-bar/ProgressBar.d.ts +5 -0
  268. package/dist/components/core/progress-bar/ProgressBar.js +34 -0
  269. package/dist/components/core/progress-bar/ProgressBar.types.d.ts +52 -0
  270. package/dist/components/core/progress-bar/ProgressBar.types.js +12 -0
  271. package/dist/components/core/progress-bar/progress-bar-impl.css +45 -0
  272. package/dist/components/core/segmented-control/SegmentedControl.d.ts +1 -1
  273. package/dist/components/core/segmented-control/SegmentedControl.js +13 -5
  274. package/dist/components/core/segmented-control/SegmentedControl.types.d.ts +5 -1
  275. package/dist/components/core/segmented-control/segmented-control-impl.css +35 -0
  276. package/dist/components/core/status-dot/StatusDot.d.ts +1 -1
  277. package/dist/components/core/status-dot/StatusDot.js +7 -4
  278. package/dist/components/core/status-dot/StatusDot.types.d.ts +9 -1
  279. package/dist/components/core/status-dot/status-dot-impl.css +101 -0
  280. package/dist/components/core/typography/Typography.d.ts +3 -283
  281. package/dist/components/core/typography/Typography.js +9 -1
  282. package/dist/components/core/typography/Typography.types.d.ts +9 -15
  283. package/dist/components/core/typography/TypographyMotion.d.ts +28 -0
  284. package/dist/components/core/typography/TypographyMotion.js +43 -0
  285. package/dist/components/core/typography/typography-impl.css +106 -0
  286. package/dist/components/illustration-data.d.ts +15 -0
  287. package/dist/components/illustration-data.js +7 -0
  288. package/dist/components/index.d.ts +22 -1
  289. package/dist/components/index.js +20 -0
  290. package/dist/components/layout/grid/Grid.css +5 -0
  291. package/dist/components/layout/grid/Grid.types.d.ts +2 -1
  292. package/dist/components/scene-scroll-data.d.ts +35 -0
  293. package/dist/components/tiers-data.d.ts +3 -2
  294. package/dist/marketing.css +24 -6
  295. package/package.json +1 -1
@@ -79,6 +79,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
79
79
  Guidance only — cannot be checked automatically.
80
80
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
81
81
  Guidance only — cannot be checked automatically.
82
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
83
+
84
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
85
+
86
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
87
+ Guidance only — cannot be checked automatically.
82
88
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
83
89
 
84
90
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -105,6 +105,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
105
105
  Guidance only — cannot be checked automatically.
106
106
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
107
107
  Guidance only — cannot be checked automatically.
108
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
109
+
110
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
111
+
112
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
113
+ Guidance only — cannot be checked automatically.
108
114
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
109
115
 
110
116
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -89,6 +89,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
89
89
  Guidance only — cannot be checked automatically.
90
90
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
91
91
  Guidance only — cannot be checked automatically.
92
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
93
+
94
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
95
+
96
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
97
+ Guidance only — cannot be checked automatically.
92
98
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
93
99
 
94
100
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -157,6 +157,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
157
157
  Guidance only — cannot be checked automatically.
158
158
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
159
159
  Guidance only — cannot be checked automatically.
160
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
161
+
162
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
163
+
164
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
165
+ Guidance only — cannot be checked automatically.
160
166
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
161
167
 
162
168
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -105,6 +105,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
105
105
  Guidance only — cannot be checked automatically.
106
106
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
107
107
  Guidance only — cannot be checked automatically.
108
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
109
+
110
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
111
+
112
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
113
+ Guidance only — cannot be checked automatically.
108
114
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
109
115
 
110
116
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -102,6 +102,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
102
102
  Guidance only — cannot be checked automatically.
103
103
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
104
104
  Guidance only — cannot be checked automatically.
105
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
106
+
107
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
108
+
109
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
110
+ Guidance only — cannot be checked automatically.
105
111
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
106
112
 
107
113
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -128,6 +128,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
128
128
  Guidance only — cannot be checked automatically.
129
129
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
130
130
  Guidance only — cannot be checked automatically.
131
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
132
+
133
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
134
+
135
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
136
+ Guidance only — cannot be checked automatically.
131
137
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
132
138
 
133
139
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -27,7 +27,7 @@ The reference design's Testimonial in its review-row form. It names no review pl
27
27
 
28
28
  TestimonialRow renders 20 elements. A token binding names the part it applies to.
29
29
 
30
- - `root` — `<section>`, class `dds-testimonialrow`. The section. It paints the ground and the ink to go with it — see `ground` — and asks its own width, which is what the row's breakout and the cards' share of it are measured against. A region named by its heading.
30
+ - `root` — `<section>`, class `dds-testimonialrow`. The section. It paints the ground and the ink to go with it — see `ground` — and asks its own width, which is what the row's breakout and the cards' share of it are measured against. A region named by its heading. Given `background`, it draws the page's one patterned band: a Background as its first layer, under everything it holds, in the tone of its ground.
31
31
  - `inner` — `<div>`, class `dds-testimonialrow__inner`. The measure and the gutter, the same column every band holds its content in.
32
32
  - `header` — `<div>`, class `dds-testimonialrow__header`. The heading and the overall rating under it, FeatureCards' header and its arrangement: ranged to the start on a phone and centred from the fold. It sets no gap: each part's own margin is the step.
33
33
  - `title` — `<h2>`, class `dds-testimonialrow__title`. Whose reviews these are. `h2`, ranged to the start on a phone and centred from the fold with the rating under it, as every other block's heading is.
@@ -61,11 +61,22 @@ Apply these classes from the generated `testimonialRowParts` constant rather tha
61
61
 
62
62
  - `page` — The default, and the page's own white. The cards are the recessed gray that sets them off
63
63
  - `subtle` — The grey band, the reference design's ground for this section. The cards turn white on it. Painted as the band's tint laid over the page's own ground, so it is the same grey whatever is behind the section
64
- - `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading, the summary and the cards' words turn white, and the cards take color.bg.surface-card-strong — gray.900 in both themes, the colour a page card takes in dark mode — so the band reads as a dark-mode section in either theme. The arrows take ButtonIcon's inverse tone
64
+ - `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading, the summary and the cards' words turn white, and the cards take color.bg.surface-card-strong-on-brand-strong — slate.850 in light and slate.900 in dark, a step above the band in both, a step lighter than the band — so the band reads as a dark-mode section in either theme. The arrows take ButtonIcon's inverse tone
65
65
 
66
- Use when: Which of the page's grounds the section paints, and with it the cards' fill: the recessed surface on the page, the raised white on the grey band — the reference design's slate band — and the strong card on the dark band, gray.900 in both themes.
66
+ Use when: Which of the page's grounds the section paints, and with it the cards' fill: the recessed surface on the page, the raised white on the grey band — the reference design's slate band — and the strong card on the dark band, slate.850 in light and slate.900 in dark, a step above the band in both.
67
67
  Never for: Marking importance. Every section on a page painted a ground is a page with no emphasis left. And never a dark card on the dark band: a few sentences of white on dark gray is a paragraph a reader works through rather than a quote they take in.
68
68
 
69
+ ### background — `halftone` | `aurora` | `mesh` | `grid` | `rings`
70
+
71
+ - `halftone` — A field of coral dots that grow towards a soft glow at the band's foot and settle to a fine screen away from it.
72
+ - `aurora` — Curtains of the brand's light rising from the band's foot and swaying slowly.
73
+ - `mesh` — The band in the brand's reds folded into one another like a liquid — the loudest of the five, for a dark band.
74
+ - `grid` — Hairlines a pitch apart rising from a soft bloom at the band's foot — the quietest, and the one to reach for first.
75
+ - `rings` — Hairline circles spreading out from the middle of the band's foot.
76
+
77
+ Use when: The page's one patterned band, between its hero and its closing call to action — a band a reader should stop at. The pattern is drawn by Background as the section's first layer, under its content and over nothing, in the tone of the ground: the light pattern on `page`, the same on the grey of `subtle`, the dark one on `strong`. Every pattern rises from the band's foot, which this block leaves open under its content. Leave it out and the band is its flat ground, as most bands on a page are.
78
+ Never for: More than one band on a page, or a band that is already the hero or the call to action — those carry their own patterns. One pattern is what makes a band the one a reader remembers; two make neither, and a page of them is noise. Never wrap this block in a Background instead: it paints its own ground over whatever is behind it, so the pattern would be hidden, and the pattern belongs under the content, not around it.
79
+
69
80
  ### title — `string` **Required.**
70
81
 
71
82
  Use when: Always. Whose reviews these are, in a few words — "What our customers say".
@@ -133,6 +144,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
133
144
  Guidance only — cannot be checked automatically.
134
145
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
135
146
  Guidance only — cannot be checked automatically.
147
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
148
+
149
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
150
+
151
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
152
+ Guidance only — cannot be checked automatically.
136
153
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
137
154
 
138
155
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -242,3 +259,26 @@ import { TestimonialRow } from '@deriv-com/dds-marketing'
242
259
  // ground="strong"
243
260
  <TestimonialRow title="What our customers say" reviews={[{"quote":"Trading with Deriv has been great. Low spreads, and withdrawals reach me quickly.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/1","detail":"United Kingdom"},{"quote":"An easy, smooth trading experience — the platform does what I need without getting in the way.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/2","detail":"Malaysia"},{"quote":"Support answered my question about deposits within minutes, in my own language.","name":"A Deriv customer","rating":4.5,"href":"https://example.com/reviews/3","detail":"South Africa"},{"quote":"I have used a few brokers. This is the one I stayed with, mostly for the range of markets.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/4","detail":"Brazil"},{"quote":"Clear charts, fast execution and no surprises in the fees.","name":"A Deriv customer","rating":4,"href":"https://example.com/reviews/5","detail":"Nigeria"},{"quote":"Opening an account took a few minutes, and verifying it took less than a day.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/6","detail":"Indonesia"}]} summary={{"label":"Rated 4.5 out of 5 by our customers","href":"https://example.com/reviews"}} ground="strong" />
244
261
  ```
262
+
263
+ ### The page's one patterned band
264
+
265
+ One band per page, between the hero and the closing call to action, its pattern drawn under the content in the tone of its ground.
266
+
267
+ ```tsx
268
+ import { TestimonialRow } from '@deriv-com/dds-marketing'
269
+
270
+ // grid on page
271
+ <TestimonialRow title="What our customers say" reviews={[{"quote":"Trading with Deriv has been great. Low spreads, and withdrawals reach me quickly.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/1","detail":"United Kingdom"},{"quote":"An easy, smooth trading experience — the platform does what I need without getting in the way.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/2","detail":"Malaysia"},{"quote":"Support answered my question about deposits within minutes, in my own language.","name":"A Deriv customer","rating":4.5,"href":"https://example.com/reviews/3","detail":"South Africa"},{"quote":"I have used a few brokers. This is the one I stayed with, mostly for the range of markets.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/4","detail":"Brazil"},{"quote":"Clear charts, fast execution and no surprises in the fees.","name":"A Deriv customer","rating":4,"href":"https://example.com/reviews/5","detail":"Nigeria"},{"quote":"Opening an account took a few minutes, and verifying it took less than a day.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/6","detail":"Indonesia"}]} summary={{"label":"Rated 4.5 out of 5 by our customers","href":"https://example.com/reviews"}} background="grid" ground="page" />
272
+
273
+ // rings on subtle
274
+ <TestimonialRow title="What our customers say" reviews={[{"quote":"Trading with Deriv has been great. Low spreads, and withdrawals reach me quickly.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/1","detail":"United Kingdom"},{"quote":"An easy, smooth trading experience — the platform does what I need without getting in the way.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/2","detail":"Malaysia"},{"quote":"Support answered my question about deposits within minutes, in my own language.","name":"A Deriv customer","rating":4.5,"href":"https://example.com/reviews/3","detail":"South Africa"},{"quote":"I have used a few brokers. This is the one I stayed with, mostly for the range of markets.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/4","detail":"Brazil"},{"quote":"Clear charts, fast execution and no surprises in the fees.","name":"A Deriv customer","rating":4,"href":"https://example.com/reviews/5","detail":"Nigeria"},{"quote":"Opening an account took a few minutes, and verifying it took less than a day.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/6","detail":"Indonesia"}]} summary={{"label":"Rated 4.5 out of 5 by our customers","href":"https://example.com/reviews"}} background="rings" ground="subtle" />
275
+
276
+ // halftone on strong
277
+ <TestimonialRow title="What our customers say" reviews={[{"quote":"Trading with Deriv has been great. Low spreads, and withdrawals reach me quickly.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/1","detail":"United Kingdom"},{"quote":"An easy, smooth trading experience — the platform does what I need without getting in the way.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/2","detail":"Malaysia"},{"quote":"Support answered my question about deposits within minutes, in my own language.","name":"A Deriv customer","rating":4.5,"href":"https://example.com/reviews/3","detail":"South Africa"},{"quote":"I have used a few brokers. This is the one I stayed with, mostly for the range of markets.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/4","detail":"Brazil"},{"quote":"Clear charts, fast execution and no surprises in the fees.","name":"A Deriv customer","rating":4,"href":"https://example.com/reviews/5","detail":"Nigeria"},{"quote":"Opening an account took a few minutes, and verifying it took less than a day.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/6","detail":"Indonesia"}]} summary={{"label":"Rated 4.5 out of 5 by our customers","href":"https://example.com/reviews"}} background="halftone" ground="strong" />
278
+
279
+ // aurora on strong
280
+ <TestimonialRow title="What our customers say" reviews={[{"quote":"Trading with Deriv has been great. Low spreads, and withdrawals reach me quickly.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/1","detail":"United Kingdom"},{"quote":"An easy, smooth trading experience — the platform does what I need without getting in the way.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/2","detail":"Malaysia"},{"quote":"Support answered my question about deposits within minutes, in my own language.","name":"A Deriv customer","rating":4.5,"href":"https://example.com/reviews/3","detail":"South Africa"},{"quote":"I have used a few brokers. This is the one I stayed with, mostly for the range of markets.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/4","detail":"Brazil"},{"quote":"Clear charts, fast execution and no surprises in the fees.","name":"A Deriv customer","rating":4,"href":"https://example.com/reviews/5","detail":"Nigeria"},{"quote":"Opening an account took a few minutes, and verifying it took less than a day.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/6","detail":"Indonesia"}]} summary={{"label":"Rated 4.5 out of 5 by our customers","href":"https://example.com/reviews"}} background="aurora" ground="strong" />
281
+
282
+ // mesh on strong
283
+ <TestimonialRow title="What our customers say" reviews={[{"quote":"Trading with Deriv has been great. Low spreads, and withdrawals reach me quickly.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/1","detail":"United Kingdom"},{"quote":"An easy, smooth trading experience — the platform does what I need without getting in the way.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/2","detail":"Malaysia"},{"quote":"Support answered my question about deposits within minutes, in my own language.","name":"A Deriv customer","rating":4.5,"href":"https://example.com/reviews/3","detail":"South Africa"},{"quote":"I have used a few brokers. This is the one I stayed with, mostly for the range of markets.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/4","detail":"Brazil"},{"quote":"Clear charts, fast execution and no surprises in the fees.","name":"A Deriv customer","rating":4,"href":"https://example.com/reviews/5","detail":"Nigeria"},{"quote":"Opening an account took a few minutes, and verifying it took less than a day.","name":"A Deriv customer","rating":5,"href":"https://example.com/reviews/6","detail":"Indonesia"}]} summary={{"label":"Rated 4.5 out of 5 by our customers","href":"https://example.com/reviews"}} background="mesh" ground="strong" />
284
+ ```
@@ -55,9 +55,9 @@ Apply these classes from the generated `testimonialSliderParts` constant rather
55
55
 
56
56
  - `page` — The default, and the page's own white. The card is the recessed gray that sets it off
57
57
  - `subtle` — The grey band, the reference design's ground for this section. The card turns white on it. Painted as the band's tint laid over the page's own ground, so it is the same grey whatever is behind the section
58
- - `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading and the quote turn white and the card takes color.bg.surface-card-strong — gray.900 in both themes, the colour a page card takes in dark mode, and TestimonialRow's card on the same band — so the band reads as a dark-mode section in either theme. The coral dots sit on it
58
+ - `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading and the quote turn white and the card takes color.bg.surface-card-strong-on-brand-strong — slate.850 in light and slate.900 in dark, a step above the band in both, a step lighter than the band, and TestimonialRow's card on the same band — so the band reads as a dark-mode section in either theme. The coral dots sit on it
59
59
 
60
- Use when: Which of the page's grounds the section paints, and with it the card's fill: the recessed surface on the page, the raised white on the grey band — the reference design's slate testimonial — and the strong card on the dark band, gray.900 in both themes, so the card has an edge on each.
60
+ Use when: Which of the page's grounds the section paints, and with it the card's fill: the recessed surface on the page, the raised white on the grey band — the reference design's slate testimonial — and the strong card on the dark band, slate.850 in light and slate.900 in dark, a step above the band in both, so the card has an edge on each.
61
61
  Never for: Marking importance. Every section on a page painted a ground is a page with no emphasis left.
62
62
 
63
63
  ### title — `string` **Required.**
@@ -135,6 +135,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
135
135
  Guidance only — cannot be checked automatically.
136
136
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
137
137
  Guidance only — cannot be checked automatically.
138
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
139
+
140
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
141
+
142
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
143
+ Guidance only — cannot be checked automatically.
138
144
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
139
145
 
140
146
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -192,6 +192,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
192
192
  Guidance only — cannot be checked automatically.
193
193
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
194
194
  Guidance only — cannot be checked automatically.
195
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
196
+
197
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
198
+
199
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
200
+ Guidance only — cannot be checked automatically.
195
201
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
196
202
 
197
203
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -245,6 +245,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
245
245
  Guidance only — cannot be checked automatically.
246
246
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
247
247
  Guidance only — cannot be checked automatically.
248
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
249
+
250
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
251
+
252
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
253
+ Guidance only — cannot be checked automatically.
248
254
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
249
255
 
250
256
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -80,6 +80,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
80
80
  Guidance only — cannot be checked automatically.
81
81
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
82
82
  Guidance only — cannot be checked automatically.
83
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
84
+
85
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
86
+
87
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
88
+ Guidance only — cannot be checked automatically.
83
89
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
84
90
 
85
91
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -48,7 +48,7 @@ Tiers renders 19 elements. A token binding names the part it applies to.
48
48
  - `benefit` — `<div>`, class `dds-tiers__benefit`. Inside the page's own Card: the card's inset and the benefit's headline and sentence, held together at a card's title-to-description step. The Card grows to the tallest in the row, so the cards end level and the qualifications under them start on one line.
49
49
  - `benefit-title` — `<p>`, class `dds-tiers__benefit-title`. What the tier gives, as a headline. A paragraph rather than a heading: the tier's name is the heading, and this is what is under it.
50
50
  - `benefit-description` — `<p>`, class `dds-tiers__benefit-description`. What the benefit means, in a sentence.
51
- - `qualification` — `<p>`, class `dds-tiers__qualification`. What it takes to reach the tier, under its card. A line break in it is kept, so the measure and the amount sit on lines of their own. Drawn only for a tier that has one — the entry tier has nothing to clear.
51
+ - `qualification` — `<p>`, class `dds-tiers__qualification`. What it takes to reach the tier, under its card. A line break in it is kept, so the measure and the amount sit on lines of their own. Every tier carries one, the entry tier included — what it takes to join — so the row ends on one line under every card.
52
52
  - `footer` — `<div>`, class `dds-tiers__footer`. The way on, under the row. At the start on a phone and centred from the fold, under the centred heading. It adds no step of its own: the gap from the tiers is the inner column's, the one between a heading and what it introduces. Rendered only when `link` is set.
53
53
 
54
54
  Apply these classes from the generated `tiersParts` constant rather than writing the strings by hand.
@@ -83,7 +83,7 @@ Never for: A paragraph, or a summary of every tier. The tiers say what they give
83
83
 
84
84
  ### tiers — `data` `TiersItem[]` **Required.**
85
85
 
86
- Use when: Always. The tiers, lowest first — two to four, four for a partnership programme. Each is a one-word `name`, a one-verb `stage`, a `medal` picture, a `benefit` headline and the sentence under it, and — on every tier above the entry one — the `qualification` that reaches it, with a line break before the amount. The order of the list is the order of the ladder, so reordering it reorders the tiers.
86
+ Use when: Always. The tiers, lowest first — two to four, four for a partnership programme. Each is a one-word `name`, a one-verb `stage`, a `medal` picture, a `benefit` headline and the sentence under it, and the `qualification` that reaches it, with a line break before the amount — the entry tier's too, saying what it takes to join, so every tier's card has the same line under it. The order of the list is the order of the ladder, so reordering it reorders the tiers.
87
87
  Never for: Tiers in any order but lowest to highest. The track through the medals reads start to end, and a ladder drawn out of order is one a reader climbs the wrong way.
88
88
 
89
89
  ### link — `node`
@@ -119,6 +119,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
119
119
  Guidance only — cannot be checked automatically.
120
120
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
121
121
  Guidance only — cannot be checked automatically.
122
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
123
+
124
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
125
+
126
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
127
+ Guidance only — cannot be checked automatically.
122
128
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
123
129
 
124
130
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -197,7 +203,7 @@ Two things genuinely have no logical form and are not covered by this. A CSS gra
197
203
  ```tsx
198
204
  import { Tiers, Link } from '@deriv-com/dds-marketing'
199
205
 
200
- <Tiers ground="subtle" title="Growing rewards as you scale" description="Our tiered partnership model rewards performance. As you grow, you unlock higher bonuses." tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Full access from day one","description":"Every partner tool, report and marketing asset, from the day you join."},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Commission + 4% bonus","description":"An extra 4% on top of your commission, paid every month.","qualification":"3-month average commission:\n$500+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Commission + 6% bonus","description":"Your monthly bonus grows to 6% to match your performance.","qualification":"3-month average commission:\n$1,000+"},{"name":"Platinum","stage":"Lead","medal":"/sample-stop-purple.svg","benefit":"Commission + 8% bonus","description":"A further quarterly bonus and invitations to our annual partner events.","qualification":"3-month average commission:\n$5,000+"}]} link={<Link href="/partners/tiers">Learn more about partner tiers</Link>} />
206
+ <Tiers ground="subtle" title="Growing rewards as you scale" description="Our tiered partnership model rewards performance. As you grow, you unlock higher bonuses." tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Full access from day one","description":"Every partner tool, report and marketing asset, from the day you join.","qualification":"To join:\nSign up as a partner"},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Commission + 4% bonus","description":"An extra 4% on top of your commission, paid every month.","qualification":"3-month average commission:\n$500+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Commission + 6% bonus","description":"Your monthly bonus grows to 6% to match your performance.","qualification":"3-month average commission:\n$1,000+"},{"name":"Platinum","stage":"Lead","medal":"/sample-stop-purple.svg","benefit":"Commission + 8% bonus","description":"A further quarterly bonus and invitations to our annual partner events.","qualification":"3-month average commission:\n$5,000+"}]} link={<Link href="/partners/tiers">Learn more about partner tiers</Link>} />
201
207
  ```
202
208
 
203
209
  ## In use
@@ -210,10 +216,10 @@ A partnership ladder in four tiers, one row with a track through the medals; thr
210
216
  import { Link, Tiers } from '@deriv-com/dds-marketing'
211
217
 
212
218
  // Four tiers, with a way on
213
- <Tiers title="Growing rewards as you scale" description="Our tiered partnership model rewards performance. As you grow, you unlock higher bonuses." tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Full access from day one","description":"Every partner tool, report and marketing asset, from the day you join."},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Commission + 4% bonus","description":"An extra 4% on top of your commission, paid every month.","qualification":"3-month average commission:\n$500+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Commission + 6% bonus","description":"Your monthly bonus grows to 6% to match your performance.","qualification":"3-month average commission:\n$1,000+"},{"name":"Platinum","stage":"Lead","medal":"/sample-stop-purple.svg","benefit":"Commission + 8% bonus","description":"A further quarterly bonus and invitations to our annual partner events.","qualification":"3-month average commission:\n$5,000+"}]} link={<Link href="/partners/tiers">Learn more about partner tiers</Link>} />
219
+ <Tiers title="Growing rewards as you scale" description="Our tiered partnership model rewards performance. As you grow, you unlock higher bonuses." tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Full access from day one","description":"Every partner tool, report and marketing asset, from the day you join.","qualification":"To join:\nSign up as a partner"},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Commission + 4% bonus","description":"An extra 4% on top of your commission, paid every month.","qualification":"3-month average commission:\n$500+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Commission + 6% bonus","description":"Your monthly bonus grows to 6% to match your performance.","qualification":"3-month average commission:\n$1,000+"},{"name":"Platinum","stage":"Lead","medal":"/sample-stop-purple.svg","benefit":"Commission + 8% bonus","description":"A further quarterly bonus and invitations to our annual partner events.","qualification":"3-month average commission:\n$5,000+"}]} link={<Link href="/partners/tiers">Learn more about partner tiers</Link>} />
214
220
 
215
221
  // Three tiers, no line or link
216
- <Tiers title="Earn more as your clients trade" tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Up to $10 per lot","description":"Earn on every lot your referred clients trade on CFDs."},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Up to $12 per lot","description":"A higher rate per lot once your clients trade more.","qualification":"Monthly volume:\n500 lots+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Up to $15 per lot","description":"Our highest rate, and a dedicated partner manager.","qualification":"Monthly volume:\n2,000 lots+"}]} />
222
+ <Tiers title="Earn more as your clients trade" tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Up to $10 per lot","description":"Earn on every lot your referred clients trade on CFDs.","qualification":"To join:\nSign up as a partner"},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Up to $12 per lot","description":"A higher rate per lot once your clients trade more.","qualification":"Monthly volume:\n500 lots+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Up to $15 per lot","description":"Our highest rate, and a dedicated partner manager.","qualification":"Monthly volume:\n2,000 lots+"}]} />
217
223
  ```
218
224
 
219
225
  ### On the grey band and the dark one
@@ -224,8 +230,8 @@ ground="subtle" sets the section apart and turns the cards white; ground="strong
224
230
  import { Link, Tiers } from '@deriv-com/dds-marketing'
225
231
 
226
232
  // Subtle ground
227
- <Tiers ground="subtle" title="Growing rewards as you scale" tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Full access from day one","description":"Every partner tool, report and marketing asset, from the day you join."},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Commission + 4% bonus","description":"An extra 4% on top of your commission, paid every month.","qualification":"3-month average commission:\n$500+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Commission + 6% bonus","description":"Your monthly bonus grows to 6% to match your performance.","qualification":"3-month average commission:\n$1,000+"},{"name":"Platinum","stage":"Lead","medal":"/sample-stop-purple.svg","benefit":"Commission + 8% bonus","description":"A further quarterly bonus and invitations to our annual partner events.","qualification":"3-month average commission:\n$5,000+"}]} />
233
+ <Tiers ground="subtle" title="Growing rewards as you scale" tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Full access from day one","description":"Every partner tool, report and marketing asset, from the day you join.","qualification":"To join:\nSign up as a partner"},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Commission + 4% bonus","description":"An extra 4% on top of your commission, paid every month.","qualification":"3-month average commission:\n$500+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Commission + 6% bonus","description":"Your monthly bonus grows to 6% to match your performance.","qualification":"3-month average commission:\n$1,000+"},{"name":"Platinum","stage":"Lead","medal":"/sample-stop-purple.svg","benefit":"Commission + 8% bonus","description":"A further quarterly bonus and invitations to our annual partner events.","qualification":"3-month average commission:\n$5,000+"}]} />
228
234
 
229
235
  // Strong ground
230
- <Tiers ground="strong" title="Growing rewards as you scale" description="Our tiered partnership model rewards performance. As you grow, you unlock higher bonuses." tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Full access from day one","description":"Every partner tool, report and marketing asset, from the day you join."},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Commission + 4% bonus","description":"An extra 4% on top of your commission, paid every month.","qualification":"3-month average commission:\n$500+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Commission + 6% bonus","description":"Your monthly bonus grows to 6% to match your performance.","qualification":"3-month average commission:\n$1,000+"},{"name":"Platinum","stage":"Lead","medal":"/sample-stop-purple.svg","benefit":"Commission + 8% bonus","description":"A further quarterly bonus and invitations to our annual partner events.","qualification":"3-month average commission:\n$5,000+"}]} link={<Link href="/partners/tiers" tone="inherit">Learn more about partner tiers</Link>} />
236
+ <Tiers ground="strong" title="Growing rewards as you scale" description="Our tiered partnership model rewards performance. As you grow, you unlock higher bonuses." tiers={[{"name":"Bronze","stage":"Launch","medal":"/sample-stop-amber.svg","benefit":"Full access from day one","description":"Every partner tool, report and marketing asset, from the day you join.","qualification":"To join:\nSign up as a partner"},{"name":"Silver","stage":"Grow","medal":"/sample-stop-teal.svg","benefit":"Commission + 4% bonus","description":"An extra 4% on top of your commission, paid every month.","qualification":"3-month average commission:\n$500+"},{"name":"Gold","stage":"Scale","medal":"/sample-stop-brand.svg","benefit":"Commission + 6% bonus","description":"Your monthly bonus grows to 6% to match your performance.","qualification":"3-month average commission:\n$1,000+"},{"name":"Platinum","stage":"Lead","medal":"/sample-stop-purple.svg","benefit":"Commission + 8% bonus","description":"A further quarterly bonus and invitations to our annual partner events.","qualification":"3-month average commission:\n$5,000+"}]} link={<Link href="/partners/tiers" tone="inherit">Learn more about partner tiers</Link>} />
231
237
  ```
@@ -119,6 +119,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
119
119
  Guidance only — cannot be checked automatically.
120
120
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
121
121
  Guidance only — cannot be checked automatically.
122
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
123
+
124
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
125
+
126
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
127
+ Guidance only — cannot be checked automatically.
122
128
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
123
129
 
124
130
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -34,7 +34,7 @@ Typography renders one element.
34
34
 
35
35
  Its margin is unset. A browser gives <p> and every heading a margin of its own, which would arrive here as spacing nobody asked for and nothing in the contract could see — so the page's own gap is the only thing between two blocks of copy.
36
36
 
37
- The figure variant is the one that sets a property no token holds. Its size and weight are font.figure like every other variant's are their own role, but tabular numerals are a literal here rather than a binding: a composite font token carries family, size, weight, line height and tracking and nothing else, and the numeric form is not a value that varies anyway. A figure is always tabular — that is most of what makes it a figure rather than a heading with a number in it, because a column of counts whose digits do not line up is a column the eye cannot compare.
37
+ The figure variant is the one that sets a property no token holds. Its size and weight are font.figure like every other variant's are their own role, but tabular numerals are a literal here rather than a binding: a composite font token carries family, size, weight, line height and tracking and nothing else, and the numeric form is not a value that varies anyway. A figure is always tabular — that is most of what makes it a figure rather than a heading with a number in it, because a column of counts whose digits do not line up is a column the eye cannot compare. Given `motion` or `from`, it is drawn by TypographyMotion, a client component, and moves once on arrival (`data-arrival`); the text it holds is still the text that is read.
38
38
 
39
39
  Apply these classes from the generated `typographyParts` constant rather than writing the strings by hand.
40
40
 
@@ -72,6 +72,18 @@ Never for: Picking an element. A variant is a size, and the element is `as`
72
72
  - `h6` — The deepest heading level
73
73
  Never for: Anything interactive. A link is Link and a control is Button — an element that responds to a click needs a name, a focus ring and a keyboard route, none of which this has
74
74
 
75
+ ### motion — `roll`
76
+
77
+ - `roll` — A figure the reader would call their own — an amount in a pane, a deposit, a balance in an illustration — rolls into place once: each digit a reel from nought to its value, left to right, a step of motion.duration.stagger apart, over motion.duration.dramatic
78
+
79
+ Use when: The figure moves once, on arrival — when it is well into view, when the block bringing it in has landed, or, in an IllustrationCard, when the pane has. Only the `figure` role, and only a figure given as plain text, since the digits are what roll. At rest, and for a reader who asked for less movement, the figure is simply its value; the value itself is what is read out
80
+ Never for: A product term — a leverage, a spread, a payout rate, a price. A figure counting up reads as a live quote, so it rolls only an illustrative amount, and never a profit climbing upward. Nor more than one moving thing in a pane: one lead motion per pane
81
+
82
+ ### from — `string`
83
+
84
+ Use when: The words this text starts as, which give way once to the words it is — "Opening…" to "Position open", "EUR/USD · Buy" to "EUR/USD · Sell". The first words hold for motion.duration.hold after arrival, rise away, and the text's own words come up into their place. Plain text only. Beside a StatusDot given `from` as well, the dot changes with the words
85
+ Never for: Words a reader must read to act, or a sequence of more than two. The first words are on screen for a second and are not read out — what is read is the text's own words — so nothing the reader needs may live only in them. Nor beside `motion`, which wins: a figure that rolls draws no earlier words
86
+
75
87
  Also accepts everything from `HTMLAttributes<HTMLElement>`.
76
88
 
77
89
  ## Accessibility
@@ -96,6 +108,12 @@ What this is not about is every row of controls. A set of filter chips, a pagina
96
108
  Guidance only — cannot be checked automatically.
97
109
  - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, CardButton and TextInput simultaneously.
98
110
  Guidance only — cannot be checked automatically.
111
+ - **A page has at most one patterned band, between its hero and its closing call to action** — A patterned ground — the halftone, the aurora, the mesh, the grid or the rings — is what makes a band the one a reader stops at, and it only works by being the exception. So a page has at most one, placed between its hero and its closing call to action; the hero's and the call to action's own patterns are theirs and do not count, and the band never goes on either of them.
112
+
113
+ The pattern is the band's first layer, under its content and over nothing. A block that can carry one says so with its own `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows — and draws it there; a section built by hand places a Background with nothing in it as its first child. Never wrap a block in a Background: the block paints its own ground over the pattern and hides it.
114
+
115
+ Only a band whose content is stacked can carry one. Every pattern rises from the band's foot, so the band needs a heading over what it introduces, centred, with the foot left open. A band whose content runs side by side — words beside a picture, a split, columns reaching the foot — puts the glow behind the picture or under the words; it stays on its flat ground.
116
+ Guidance only — cannot be checked automatically.
99
117
  - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
100
118
 
101
119
  color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
@@ -169,6 +187,36 @@ Two things genuinely have no logical form and are not covered by this. A CSS gra
169
187
  The container. Colour is inherited here, margin is never set, and a component that owned either would disagree with the layout that placed it.
170
188
  → nothing in this system does this. Not a gap waiting to be filled — the case belongs outside it.
171
189
 
190
+ ❌ variant=h1 + motion is set
191
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
192
+
193
+ ❌ variant=h2 + motion is set
194
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
195
+
196
+ ❌ variant=h3 + motion is set
197
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
198
+
199
+ ❌ variant=h4 + motion is set
200
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
201
+
202
+ ❌ variant=h5 + motion is set
203
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
204
+
205
+ ❌ variant=subtitle + motion is set
206
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
207
+
208
+ ❌ variant=body-lg + motion is set
209
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
210
+
211
+ ❌ variant=body-md + motion is set
212
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
213
+
214
+ ❌ variant=body-sm + motion is set
215
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
216
+
217
+ ❌ variant=eyebrow + motion is set
218
+ Only a figure rolls: the motion turns its digits, and a heading or a line of copy rolling digit by digit is a figure pretending to be words.
219
+
172
220
  ## Example
173
221
 
174
222
  ```tsx
@@ -255,3 +303,17 @@ import { Typography } from '@deriv-com/dds-marketing'
255
303
  // figure — a number, in fixed-width digits
256
304
  <Typography variant="figure" as="span">9,482</Typography>
257
305
  ```
306
+
307
+ ### Moving once on arrival
308
+
309
+ A figure that rolls into place, and words that give way to the words they become. Both play once, then rest.
310
+
311
+ ```tsx
312
+ import { Typography } from '@deriv-com/dds-marketing'
313
+
314
+ // variant="figure" motion="roll"
315
+ <Typography variant="figure" motion="roll">50 USD</Typography>
316
+
317
+ // from — Opening… to Position open
318
+ <Typography variant="body-sm" from="Opening…">Position open</Typography>
319
+ ```
@@ -2,26 +2,33 @@
2
2
 
3
3
  # Background
4
4
 
5
- A patterned ground for a section to sit on
5
+ A patterned ground for a page's one standout band, drawn as its first layer
6
6
 
7
7
  `import { Background } from '@deriv-com/dds-marketing'`
8
8
 
9
9
  ## Reach for it when
10
10
 
11
- - A band that has to stand apart from the page around it with more than a change of fill — the opening of a landing page, a call to action, a section that closes a long page …
12
- - A dark band that would otherwise be a flat slab. The glow gives it a centre for the eye, which is where the band's heading or its action should sit
13
- - A light page that wants one moment of brand colour without a coral block: the dots carry the colour at a fraction of the area a fill would
11
+ - The page's one patterned band, between its hero and its closing call to action, on a section built by hand rather than from a block — a heading stacked over what it introduces, centred, with the band's foot left open, because every pattern rises from the foot …
12
+ - Inside a block that offers it, as that block's `background` prop — FeatureCards, Stats, TestimonialRow and LogoRows draw it as their first layer, and LandingHero, PageHeader, CtaBanner, CtaBannerSlider and DownloadBanner their own. …
14
13
 
15
14
  ## Something else, when
16
15
 
17
- - The band only needs separating from the page around it → **nothing in this system does this**
16
+ - The band is a set of features with a picture each → **FeatureCards**
17
+ - The band is three to five headline numbers → **Stats**
18
+ - The band is a row of short reviews → **TestimonialRow**
19
+ - The band is a strip of partner or payment logos → **LogoRows**
20
+ - The band opens the page → **LandingHero**
21
+ - The band asks the reader to act → **CtaBanner**
18
22
  - The ground is a picture or a video → **AspectRatio**
19
23
 
20
24
  ## Never
21
25
 
26
+ - More than one band on a page. One patterned band, between the hero and the closing call to action, is what makes it the band a reader remembers; two make neither, and a page of them is noise. The hero's and the call to action's own patterns do not count against it, and it does not go on either of them
27
+ - Wrapping a block. Every block paints its own ground over whatever is behind it, so a block inside a Background hides the pattern — and the pattern belongs under a band's content as its first layer, not around it as a frame. A block that can carry one has a `background` prop; one that has not is not a band for a pattern
28
+ - A band whose content runs side by side — words beside a picture, a split, a row of columns reaching the foot. Every pattern rises from the band's foot, so it needs a heading stacked over content with the foot left open; laid across, the glow comes up behind the picture or under the words
29
+ - Separating a band from the page. A block's `ground` — `subtle` for the grey band, `strong` for the dark one — does that with a flat fill at no cost to the eye; a pattern is decoration that has to earn its place
22
30
  - Carrying meaning. The pattern is hidden from assistive technology and reads differently on every screen size, so nothing a reader needs may depend on it — not a highlight, not a direction, not a state
23
31
  - Behind long reading. Dots behind a paragraph are texture under every word, and the brightest of them sit exactly where the eye is reading; put prose on a plain ground and keep this for the band that opens or closes it
24
- - Two in a row. Adjacent patterned bands lose the edge between them, and the reader sees one long busy surface rather than two sections
25
32
  - A card, a panel or any surface smaller than a band. At a few hundred pixels the glow has nowhere to fall off to, and the dots read as noise rather than light
26
33
 
27
34
  ## Props
@@ -29,6 +36,7 @@ A patterned ground for a section to sit on
29
36
  - **tone** `enum` · default "brand" — Which ground the dots are drawn on. It sets the flat colour under the pattern, the dots' ink — coral on the dark and light grounds, white on the coral one — and the ink of what sits on it
30
37
  - `dark` — The band the halftone was drawn for: coral dots glowing on color.bg.brand-strong, which is dark in both modes. …
31
38
  - `light` — Coral dots on the page's own ground, for a light page that wants one moment of brand colour without a solid coral band. …
39
+ - `subtle` — The light pattern on the subtle band's grey — color.bg.band-subtle laid over the page, the grey a block's `ground="subtle"` paints — for a block that carries a pattern on that ground. …
32
40
  - `brand` — The default: the brand's own coral, the ground the mesh was made for and the one a call to action stands on. White dots on it for the halftone. …
33
41
  - never: Matching the page's colour mode. Dark is dark in both modes — a band that should invert with the theme is a plain section on color.bg.page, not this
34
42
  - **pattern** `enum` · default "halftone" — Which pattern is drawn. The halftone is the default and the one that moves most; the aurora drifts slowly; the mesh flows across the whole band; the grid and the rings are the quietest, their lines rising and spreading at a band's pace. …