@deriv-com/dds-marketing 0.2.0 → 1.0.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 (279) hide show
  1. package/.llm/components/accordion.md +8 -0
  2. package/.llm/components/accordionitem.md +8 -0
  3. package/.llm/components/aspectratio.md +8 -0
  4. package/.llm/components/badge.md +8 -0
  5. package/.llm/components/bottomsheet.md +8 -0
  6. package/.llm/components/breadcrumb.md +8 -0
  7. package/.llm/components/breadcrumbitem.md +8 -0
  8. package/.llm/components/button.md +46 -22
  9. package/.llm/components/buttonicon.md +14 -6
  10. package/.llm/components/card.md +15 -1
  11. package/.llm/components/cardbody.md +28 -2
  12. package/.llm/components/cardbutton.md +15 -1
  13. package/.llm/components/checkbox.md +8 -0
  14. package/.llm/components/ctabanner.md +186 -0
  15. package/.llm/components/ctabannerslider.md +204 -0
  16. package/.llm/components/divider.md +8 -0
  17. package/.llm/components/dropdownmenu.md +13 -5
  18. package/.llm/components/faqaccordion.md +217 -0
  19. package/.llm/components/featurebullets.md +254 -0
  20. package/.llm/components/featurecards.md +313 -0
  21. package/.llm/components/featurescroll.md +284 -0
  22. package/.llm/components/featuresplit.md +249 -0
  23. package/.llm/components/filterchip.md +8 -0
  24. package/.llm/components/footer.md +8 -0
  25. package/.llm/components/footergroup.md +8 -0
  26. package/.llm/components/grid.md +8 -0
  27. package/.llm/components/icon.md +8 -0
  28. package/.llm/components/landinghero.md +254 -0
  29. package/.llm/components/link.md +9 -1
  30. package/.llm/components/logocolumns.md +235 -0
  31. package/.llm/components/logorows.md +212 -0
  32. package/.llm/components/menuitem.md +8 -0
  33. package/.llm/components/navbar.md +79 -15
  34. package/.llm/components/navbaritem.md +9 -1
  35. package/.llm/components/navbarmenu.md +8 -0
  36. package/.llm/components/navbarmenugroup.md +8 -0
  37. package/.llm/components/navbarpanel.md +9 -1
  38. package/.llm/components/navbarswitcher.md +9 -1
  39. package/.llm/components/navbarswitcheroption.md +8 -0
  40. package/.llm/components/option.md +8 -0
  41. package/.llm/components/pageheader.md +231 -0
  42. package/.llm/components/pagination.md +26 -89
  43. package/.llm/components/paginationdots.md +215 -0
  44. package/.llm/components/producthero.md +248 -0
  45. package/.llm/components/removablechip.md +8 -0
  46. package/.llm/components/row.md +8 -0
  47. package/.llm/components/scroller.md +8 -0
  48. package/.llm/components/searchinput.md +8 -0
  49. package/.llm/components/segmentedcontrol.md +8 -0
  50. package/.llm/components/segmentedcontrolitem.md +8 -0
  51. package/.llm/components/select.md +8 -0
  52. package/.llm/components/selectchip.md +56 -15
  53. package/.llm/components/spinner.md +8 -0
  54. package/.llm/components/stack.md +8 -0
  55. package/.llm/components/statusdot.md +8 -0
  56. package/.llm/components/subdomainnavbar.md +8 -0
  57. package/.llm/components/tab.md +8 -0
  58. package/.llm/components/table.md +8 -0
  59. package/.llm/components/tablebody.md +8 -0
  60. package/.llm/components/tablecell.md +8 -0
  61. package/.llm/components/tablehead.md +8 -0
  62. package/.llm/components/tableheadercell.md +8 -0
  63. package/.llm/components/tablerow.md +8 -0
  64. package/.llm/components/tablist.md +8 -0
  65. package/.llm/components/testimonialrow.md +235 -0
  66. package/.llm/components/testimonialslider.md +254 -0
  67. package/.llm/components/textarea.md +8 -0
  68. package/.llm/components/textinput.md +8 -0
  69. package/.llm/components/tooltip.md +8 -0
  70. package/.llm/components/typography.md +8 -0
  71. package/.llm/digest/button.md +11 -6
  72. package/.llm/digest/buttonicon.md +2 -2
  73. package/.llm/digest/card.md +1 -0
  74. package/.llm/digest/cardbody.md +3 -1
  75. package/.llm/digest/cardbutton.md +1 -0
  76. package/.llm/digest/ctabanner.md +44 -0
  77. package/.llm/digest/ctabannerslider.md +45 -0
  78. package/.llm/digest/dropdownmenu.md +1 -1
  79. package/.llm/digest/faqaccordion.md +43 -0
  80. package/.llm/digest/featurebullets.md +52 -0
  81. package/.llm/digest/featurecards.md +49 -0
  82. package/.llm/digest/featurescroll.md +52 -0
  83. package/.llm/digest/featuresplit.md +54 -0
  84. package/.llm/digest/landinghero.md +53 -0
  85. package/.llm/digest/logocolumns.md +55 -0
  86. package/.llm/digest/logorows.md +48 -0
  87. package/.llm/digest/navbar.md +18 -3
  88. package/.llm/digest/pageheader.md +49 -0
  89. package/.llm/digest/pagination.md +6 -17
  90. package/.llm/digest/paginationdots.md +43 -0
  91. package/.llm/digest/producthero.md +53 -0
  92. package/.llm/digest/selectchip.md +6 -1
  93. package/.llm/digest/testimonialrow.md +51 -0
  94. package/.llm/digest/testimonialslider.md +51 -0
  95. package/.llm/index.md +24 -3
  96. package/.llm/rules.md +24 -0
  97. package/.llm/tokens.md +56 -12
  98. package/AGENTS.md +28 -3
  99. package/README.md +41 -21
  100. package/dist/components/banner-data.d.ts +38 -0
  101. package/dist/components/banner-data.js +15 -0
  102. package/dist/components/blocks/block-reveal.css +90 -0
  103. package/dist/components/blocks/cta-banner/CtaBanner.css +66 -0
  104. package/dist/components/blocks/cta-banner/CtaBanner.d.ts +22 -0
  105. package/dist/components/blocks/cta-banner/CtaBanner.js +31 -0
  106. package/dist/components/blocks/cta-banner/CtaBanner.types.d.ts +29 -0
  107. package/dist/components/blocks/cta-banner/CtaBanner.types.js +13 -0
  108. package/dist/components/blocks/cta-banner/cta-banner-impl.css +29 -0
  109. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.css +90 -0
  110. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.d.ts +39 -0
  111. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.js +60 -0
  112. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.d.ts +41 -0
  113. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.js +15 -0
  114. package/dist/components/blocks/cta-banner-slider/cta-banner-slider-impl.css +73 -0
  115. package/dist/components/blocks/faq-accordion/FaqAccordion.css +54 -0
  116. package/dist/components/blocks/faq-accordion/FaqAccordion.d.ts +20 -0
  117. package/dist/components/blocks/faq-accordion/FaqAccordion.js +28 -0
  118. package/dist/components/blocks/faq-accordion/FaqAccordion.types.d.ts +25 -0
  119. package/dist/components/blocks/faq-accordion/FaqAccordion.types.js +10 -0
  120. package/dist/components/blocks/faq-accordion/faq-accordion-impl.css +54 -0
  121. package/dist/components/blocks/feature-bullets/FeatureBullets.css +139 -0
  122. package/dist/components/blocks/feature-bullets/FeatureBullets.d.ts +31 -0
  123. package/dist/components/blocks/feature-bullets/FeatureBullets.js +55 -0
  124. package/dist/components/blocks/feature-bullets/FeatureBullets.types.d.ts +39 -0
  125. package/dist/components/blocks/feature-bullets/FeatureBullets.types.js +16 -0
  126. package/dist/components/blocks/feature-bullets/feature-bullets-impl.css +104 -0
  127. package/dist/components/blocks/feature-cards/FeatureCards.css +84 -0
  128. package/dist/components/blocks/feature-cards/FeatureCards.d.ts +24 -0
  129. package/dist/components/blocks/feature-cards/FeatureCards.js +66 -0
  130. package/dist/components/blocks/feature-cards/FeatureCards.types.d.ts +33 -0
  131. package/dist/components/blocks/feature-cards/FeatureCards.types.js +14 -0
  132. package/dist/components/blocks/feature-cards/feature-cards-impl.css +245 -0
  133. package/dist/components/blocks/feature-scroll/FeatureScroll.css +137 -0
  134. package/dist/components/blocks/feature-scroll/FeatureScroll.d.ts +39 -0
  135. package/dist/components/blocks/feature-scroll/FeatureScroll.js +167 -0
  136. package/dist/components/blocks/feature-scroll/FeatureScroll.types.d.ts +40 -0
  137. package/dist/components/blocks/feature-scroll/FeatureScroll.types.js +17 -0
  138. package/dist/components/blocks/feature-scroll/feature-scroll-impl.css +292 -0
  139. package/dist/components/blocks/feature-split/FeatureSplit.css +95 -0
  140. package/dist/components/blocks/feature-split/FeatureSplit.d.ts +30 -0
  141. package/dist/components/blocks/feature-split/FeatureSplit.js +38 -0
  142. package/dist/components/blocks/feature-split/FeatureSplit.types.d.ts +39 -0
  143. package/dist/components/blocks/feature-split/FeatureSplit.types.js +14 -0
  144. package/dist/components/blocks/feature-split/feature-split-impl.css +83 -0
  145. package/dist/components/blocks/landing-hero/LandingHero.css +85 -0
  146. package/dist/components/blocks/landing-hero/LandingHero.d.ts +41 -0
  147. package/dist/components/blocks/landing-hero/LandingHero.js +54 -0
  148. package/dist/components/blocks/landing-hero/LandingHero.types.d.ts +37 -0
  149. package/dist/components/blocks/landing-hero/LandingHero.types.js +15 -0
  150. package/dist/components/blocks/landing-hero/landing-hero-impl.css +355 -0
  151. package/dist/components/blocks/logo-columns/LogoColumns.css +161 -0
  152. package/dist/components/blocks/logo-columns/LogoColumns.d.ts +23 -0
  153. package/dist/components/blocks/logo-columns/LogoColumns.js +46 -0
  154. package/dist/components/blocks/logo-columns/LogoColumns.types.d.ts +46 -0
  155. package/dist/components/blocks/logo-columns/LogoColumns.types.js +18 -0
  156. package/dist/components/blocks/logo-columns/logo-columns-impl.css +188 -0
  157. package/dist/components/blocks/logo-rows/LogoRows.css +122 -0
  158. package/dist/components/blocks/logo-rows/LogoRows.d.ts +20 -0
  159. package/dist/components/blocks/logo-rows/LogoRows.js +43 -0
  160. package/dist/components/blocks/logo-rows/LogoRows.types.d.ts +36 -0
  161. package/dist/components/blocks/logo-rows/LogoRows.types.js +16 -0
  162. package/dist/components/blocks/logo-rows/logo-rows-impl.css +179 -0
  163. package/dist/components/blocks/page-header/PageHeader.css +79 -0
  164. package/dist/components/blocks/page-header/PageHeader.d.ts +34 -0
  165. package/dist/components/blocks/page-header/PageHeader.js +43 -0
  166. package/dist/components/blocks/page-header/PageHeader.types.d.ts +32 -0
  167. package/dist/components/blocks/page-header/PageHeader.types.js +14 -0
  168. package/dist/components/blocks/page-header/page-header-impl.css +176 -0
  169. package/dist/components/blocks/product-hero/ProductHero.css +86 -0
  170. package/dist/components/blocks/product-hero/ProductHero.d.ts +35 -0
  171. package/dist/components/blocks/product-hero/ProductHero.js +48 -0
  172. package/dist/components/blocks/product-hero/ProductHero.types.d.ts +37 -0
  173. package/dist/components/blocks/product-hero/ProductHero.types.js +15 -0
  174. package/dist/components/blocks/product-hero/product-hero-impl.css +354 -0
  175. package/dist/components/blocks/testimonial-row/TestimonialRow.css +245 -0
  176. package/dist/components/blocks/testimonial-row/TestimonialRow.d.ts +20 -0
  177. package/dist/components/blocks/testimonial-row/TestimonialRow.js +128 -0
  178. package/dist/components/blocks/testimonial-row/TestimonialRow.types.d.ts +54 -0
  179. package/dist/components/blocks/testimonial-row/TestimonialRow.types.js +26 -0
  180. package/dist/components/blocks/testimonial-row/testimonial-row-impl.css +195 -0
  181. package/dist/components/blocks/testimonial-slider/TestimonialSlider.css +181 -0
  182. package/dist/components/blocks/testimonial-slider/TestimonialSlider.d.ts +22 -0
  183. package/dist/components/blocks/testimonial-slider/TestimonialSlider.js +36 -0
  184. package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.d.ts +49 -0
  185. package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.js +21 -0
  186. package/dist/components/blocks/testimonial-slider/testimonial-slider-impl.css +202 -0
  187. package/dist/components/blocks/use-reveal.d.ts +46 -0
  188. package/dist/components/blocks/use-reveal.js +120 -0
  189. package/dist/components/blocks/use-rotation.d.ts +62 -0
  190. package/dist/components/blocks/use-rotation.js +176 -0
  191. package/dist/components/core/accordion-item/AccordionItem.css +6 -5
  192. package/dist/components/core/bottom-sheet/BottomSheet.css +1 -1
  193. package/dist/components/core/button/Button.css +63 -16
  194. package/dist/components/core/button/Button.d.ts +14 -12
  195. package/dist/components/core/button/Button.js +43 -14
  196. package/dist/components/core/button/Button.types.d.ts +9 -14
  197. package/dist/components/core/button/button-impl.css +25 -0
  198. package/dist/components/core/button-icon/ButtonIcon.css +31 -15
  199. package/dist/components/core/button-icon/ButtonIcon.d.ts +2 -2
  200. package/dist/components/core/button-icon/ButtonIcon.js +2 -2
  201. package/dist/components/core/button-icon/ButtonIcon.types.d.ts +4 -4
  202. package/dist/components/core/card/Card.css +13 -4
  203. package/dist/components/core/card/Card.types.d.ts +2 -1
  204. package/dist/components/core/card-body/CardBody.css +11 -6
  205. package/dist/components/core/card-body/CardBody.d.ts +1 -1
  206. package/dist/components/core/card-body/CardBody.js +2 -2
  207. package/dist/components/core/card-body/CardBody.types.d.ts +4 -1
  208. package/dist/components/core/card-body/CardBody.types.js +1 -0
  209. package/dist/components/core/card-button/CardButton.css +13 -4
  210. package/dist/components/core/card-button/CardButton.types.d.ts +2 -1
  211. package/dist/components/core/checkbox/Checkbox.css +8 -1
  212. package/dist/components/core/dropdown-menu/DropdownMenu.css +13 -12
  213. package/dist/components/core/dropdown-menu/DropdownMenu.d.ts +5 -3
  214. package/dist/components/core/dropdown-menu/DropdownMenu.js +5 -3
  215. package/dist/components/core/filter-chip/FilterChip.css +2 -1
  216. package/dist/components/core/footer/footer-impl.css +1 -1
  217. package/dist/components/core/footer-group/FooterGroup.css +8 -7
  218. package/dist/components/core/icon/Icon.css +1 -1
  219. package/dist/components/core/link/Link.css +1 -1
  220. package/dist/components/core/menu-item/MenuItem.css +1 -1
  221. package/dist/components/core/navbar/Navbar.css +7 -8
  222. package/dist/components/core/navbar/Navbar.d.ts +17 -1
  223. package/dist/components/core/navbar/Navbar.js +139 -12
  224. package/dist/components/core/navbar/Navbar.types.d.ts +23 -4
  225. package/dist/components/core/navbar/Navbar.types.js +1 -1
  226. package/dist/components/core/navbar/navbar-impl.css +10 -3
  227. package/dist/components/core/navbar/navbar-material.css +96 -0
  228. package/dist/components/core/navbar-item/NavbarItem.css +4 -4
  229. package/dist/components/core/navbar-menu/NavbarMenu.css +7 -5
  230. package/dist/components/core/navbar-menu/NavbarMenu.d.ts +1 -0
  231. package/dist/components/core/navbar-menu/NavbarMenu.js +1 -0
  232. package/dist/components/core/navbar-menu/navbar-menu-impl.css +7 -7
  233. package/dist/components/core/navbar-switcher/NavbarSwitcher.css +6 -5
  234. package/dist/components/core/navbar-switcher/NavbarSwitcher.d.ts +1 -0
  235. package/dist/components/core/navbar-switcher/NavbarSwitcher.js +2 -1
  236. package/dist/components/core/option/Option.css +1 -1
  237. package/dist/components/core/pagination/Pagination.css +1 -75
  238. package/dist/components/core/pagination/Pagination.d.ts +4 -4
  239. package/dist/components/core/pagination/Pagination.js +11 -51
  240. package/dist/components/core/pagination/Pagination.types.d.ts +5 -17
  241. package/dist/components/core/pagination/Pagination.types.js +1 -3
  242. package/dist/components/core/pagination-dots/PaginationDots.css +60 -0
  243. package/dist/components/core/pagination-dots/PaginationDots.d.ts +25 -0
  244. package/dist/components/core/pagination-dots/PaginationDots.js +104 -0
  245. package/dist/components/core/pagination-dots/PaginationDots.types.d.ts +38 -0
  246. package/dist/components/core/pagination-dots/PaginationDots.types.js +9 -0
  247. package/dist/components/core/removable-chip/RemovableChip.css +3 -3
  248. package/dist/components/core/search-input/SearchInput.css +1 -1
  249. package/dist/components/core/segmented-control/SegmentedControl.css +1 -1
  250. package/dist/components/core/segmented-control-item/SegmentedControlItem.css +1 -1
  251. package/dist/components/core/select/Select.css +2 -1
  252. package/dist/components/core/select-chip/SelectChip.css +14 -7
  253. package/dist/components/core/select-chip/SelectChip.d.ts +1 -1
  254. package/dist/components/core/select-chip/SelectChip.js +7 -4
  255. package/dist/components/core/select-chip/SelectChip.types.d.ts +7 -1
  256. package/dist/components/core/select-chip/SelectChip.types.js +1 -1
  257. package/dist/components/core/select-chip/select-chip-impl.css +14 -3
  258. package/dist/components/core/status-dot/StatusDot.css +1 -1
  259. package/dist/components/core/subdomain-navbar/SubdomainNavbar.css +3 -3
  260. package/dist/components/core/tab/Tab.css +1 -1
  261. package/dist/components/core/tab-list/TabList.css +1 -1
  262. package/dist/components/core/table/table-impl.css +36 -14
  263. package/dist/components/core/table-header-cell/TableHeaderCell.css +5 -5
  264. package/dist/components/core/text-area/TextArea.css +1 -1
  265. package/dist/components/core/text-input/TextInput.css +1 -1
  266. package/dist/components/core/tooltip/Tooltip.css +1 -1
  267. package/dist/components/core/typography/Typography.css +5 -5
  268. package/dist/components/index.d.ts +35 -0
  269. package/dist/components/index.js +30 -0
  270. package/dist/components/logo-data.d.ts +24 -0
  271. package/dist/components/logo-data.js +11 -0
  272. package/dist/components/scroll-data.d.ts +64 -0
  273. package/dist/components/scroll-data.js +17 -0
  274. package/dist/components/testimonial-row-data.d.ts +51 -0
  275. package/dist/components/testimonial-row-data.js +11 -0
  276. package/dist/components/testimonial-slider-data.d.ts +26 -0
  277. package/dist/components/testimonial-slider-data.js +10 -0
  278. package/dist/marketing.css +385 -14
  279. package/package.json +1 -6
@@ -0,0 +1,55 @@
1
+ <!-- GENERATED from logocolumns.contract.json. Do not edit. -->
2
+
3
+ # LogoColumns
4
+
5
+ A section that backs one claim with the names behind it: a heading, a line, an optional disclaimer and a way onward, beside a wall of logo tiles in two columns that run in opposite directions as the reader scrolls past — one rising, one falling — fading out at the wall's top and bottom edge so the set reads as longer than the space it is shown in. …
6
+
7
+ `import { LogoColumns } from '@deriv-com/dds-marketing'`
8
+
9
+ ## Reach for it when
10
+
11
+ - Showing the partners, integrations or payment methods behind a claim — the names a reader recognises, as evidence for what the words say
12
+ - Eight or more logos, enough that each column reads as running on past both edges of the wall
13
+
14
+ ## Something else, when
15
+
16
+ - A handful of logos a reader should be able to count and compare → **Grid**
17
+ - One picture beside the claim → **FeatureSplit**
18
+ - Each logo needs to be pressed — a partner directory → **FeatureCards**
19
+
20
+ ## Never
21
+
22
+ - Logos the brand has not been given the right to show. A partner's mark is a claim made in the partner's name
23
+ - A few logos. Three repeated to fill a wall read as three repeated; a short set belongs in a still grid
24
+ - Anything a reader has to press or read in full. Every tile moves with the scroll and is clipped at the wall's edge
25
+
26
+ ## Props
27
+
28
+ - **ground** `enum` · default "strong" — Which of the page's grounds the section paints, and with it the tiles' fill: the recessed surface on the page, the raised white on the grey band, and the strong card on the dark band. …
29
+ - `page` — The page's own white, with tiles at the recessed gray. For full-colour logos drawn for a light ground
30
+ - `subtle` — The grey band, with white tiles on it. For full-colour logos, where the section needs setting apart from the ones around it. …
31
+ - `strong` — The default. `color.bg.brand-strong`, the dark band, with white words and tiles at color.bg.surface-card-strong — gray.900 in both themes, so the wall is a set of tiles a step lighter than the band. …
32
+ - never: Marking importance. Every section on a page painted dark is a page with no emphasis left, and a reader stops reading the grounds as meaning anything. Alternating for its own sake is the same mistake more slowly. And never the brand's own coral, `color.bg.brand`, which is not offered here. …
33
+ - **mediaPosition** `enum` · default "start" — Which side the wall takes at full width. Never a promise about a phone: below the fold the words are always first, because a reader on a phone came for them
34
+ - `start` — The default, the reference design's: the wall at the start, the claim beside it at the end
35
+ - `end` — The second of two on a page, or after a FeatureSplit whose picture is at the start, so the two do not read as one column
36
+ - never: Moving the wall on a phone. There is one column there and the words lead it
37
+ - **title** `string` · required — Always. The one claim the logos back, in the fewest words that say it — "Trusted by leading platforms worldwide"
38
+ - never: A list of the names. The logos are the names; the heading says what they prove
39
+ - **description** `string` · optional — The line under the heading: what the logos mean for the reader — which payment methods they can use, which platforms they can trade on
40
+ - never: A paragraph. Past about two hundred characters the text column runs longer than the wall beside it and the two halves stop lining up, which is the one thing a split has to get right. The reference design caps it at exactly that
41
+ - **disclaimer** `string` · optional — Small print the claim needs — "*Availability varies by region." Under the description, quieter than it
42
+ - never: A second description. Anything a reader should take in belongs in the description; this is the line a regulator asks for
43
+ - **link** `node` · optional — The way onward — a standalone Link, "View all partners", usually. Under the words, never on the wall: the tiles move
44
+ - never: The page's main call to action. This is a way onward from a supporting point, and a primary button here competes with the one the page actually wants pressed
45
+ - **logos** `data` · required — Always. The logos, in the order the wall deals them into its two columns — the first to the first column, the second to the second, and so on. Eight or more, so each column runs on past both edges. …
46
+ - never: A set split by hand into two. The wall deals them; a page that wants a logo in a particular column orders the list
47
+
48
+ ## Inside it
49
+
50
+ - 8 components are refused inside it; the list and the reasons are in the long document.
51
+ - Renders 12 parts: root, inner, split, content, title, description, disclaimer, link, media, column, logo, logo-image.
52
+
53
+ ---
54
+
55
+ The reasoning behind each of these, the parts this renders, its states and snippets that compile: `.llm/components/logocolumns.md`.
@@ -0,0 +1,48 @@
1
+ <!-- GENERATED from logorows.contract.json. Do not edit. -->
2
+
3
+ # LogoRows
4
+
5
+ A section that backs one claim with the names behind it, stacked: a heading, a line and a way onward, centred, over two rows of logo tiles across the band's full width that slide sideways in opposite directions as the reader scrolls past — fading out at both of their ends, so the set reads as longer than the band. …
6
+
7
+ `import { LogoRows } from '@deriv-com/dds-marketing'`
8
+
9
+ ## Reach for it when
10
+
11
+ - Showing the partners, integrations or payment methods behind a claim under it, where the words lead and the logos follow
12
+ - Eight or more logos, enough that each of the two rows reads as running on past both edges of the band
13
+
14
+ ## Something else, when
15
+
16
+ - The logos should stand beside the claim, as a wall that is half the section → **LogoColumns**
17
+ - A handful of logos a reader should be able to count and compare → **Grid**
18
+
19
+ ## Never
20
+
21
+ - Logos the brand has not been given the right to show. A partner's mark is a claim made in the partner's name
22
+ - A few logos. Three repeated to fill a row read as three repeated; a short set belongs in a still grid
23
+ - Anything a reader has to press or read in full. Every tile moves with the scroll and is clipped at the band's edge
24
+
25
+ ## Props
26
+
27
+ - **ground** `enum` · default "strong" — Which of the page's grounds the section paints, and with it the tiles' fill: the recessed surface on the page, the raised white on the grey band, and the strong card on the dark band. …
28
+ - `page` — The page's own white, with tiles at the recessed gray. For full-colour logos drawn for a light ground
29
+ - `subtle` — The grey band, with white tiles on it. For full-colour logos, where the section needs setting apart from the ones around it. …
30
+ - `strong` — The default. `color.bg.brand-strong`, the dark band, with white words and tiles at color.bg.surface-card-strong — gray.900 in both themes, so the row is a set of tiles a step lighter than the band. …
31
+ - never: Marking importance. Every section on a page painted dark is a page with no emphasis left, and a reader stops reading the grounds as meaning anything. Alternating for its own sake is the same mistake more slowly. And never the brand's own coral, `color.bg.brand`, which is not offered here. …
32
+ - **title** `string` · required — Always. The one claim the logos back, in the fewest words that say it — "Trusted by leading platforms worldwide"
33
+ - never: A list of the names. The logos are the names; the heading says what they prove
34
+ - **description** `string` · optional — The line under the heading: what the logos mean for the reader — which payment methods they can use, which platforms they can trade on
35
+ - never: A paragraph. The heading and this line are read on the way to the logos; copy a reader has to work through is copy they scroll past
36
+ - **link** `node` · optional — The way onward — a standalone Link, "View all partners", usually. Under the line, never on the row: the tiles move
37
+ - never: A button. The section's claim is made by the logos; a call to action over them is a second, louder one
38
+ - **logos** `data` · required — Always. The logos, in the order the section deals them into its two rows — the first to the first row, the second to the second, and so on. Eight or more, so each row runs on past both edges of the band. …
39
+ - never: A set split or repeated by hand. The section deals the rows and repeats them; a page passes each logo once, ordering the list to place one in a particular row
40
+
41
+ ## Inside it
42
+
43
+ - 7 components are refused inside it; the list and the reasons are in the long document.
44
+ - Renders 10 parts: root, inner, header, title, description, link, rail, track, logo, logo-image.
45
+
46
+ ---
47
+
48
+ The reasoning behind each of these, the parts this renders, its states and snippets that compile: `.llm/components/logorows.md`.
@@ -38,17 +38,32 @@ The bar across the top of a marketing page, and three regions: the mark that say
38
38
  - never: The trigger's name. They are two controls in two places — the trigger is in the bar underneath the panel, and a reader cannot reach it while the panel is open
39
39
  - **brand** `node` · optional — Effectively always on a real site — the mark, and usually an anchor to the home page wrapped around it. It is drawn twice: in the bar, and again in the panel's header, where it is the only thing left saying whose site this is
40
40
  - never: A heading for the page. This is the site's mark, not the page's title, and a reader who meets the page's `<h1>` in the bar has been told the name of somewhere they already are
41
- - **utilities** `node` · optional — The bar's trailing end has something in it — a language switcher, a theme switcher, a conversion action, or some combination. …
42
- - never: Destinations. Anything that goes to a section of the site belongs in the children, where the navigation landmark announces it as one. The trailing end is for what a reader reaches for, not for the places the bar ran out of room for
43
- - **compactAction** `node` · optional — The one thing a reader should still be able to do once the bar has collapsed and everything else has gone into the panel — a sign-up, usually. Drawn beside the control that opens the panel, and only at the widths where that control is drawn
41
+ - **utilities** `node` · optional — The bar's trailing end has the site's actions in it: one Button, which is primary, or two — one primary and one secondary, the conversion beside the way back in. …
42
+ - never: More than two Buttons, a lone Button that is not primary, or a pair that is not one primary and one secondary — the bar's actions are a conversion and its alternative, and a third pill or a second of either rank makes the reader choose between things the bar should have ranked. A switcher is not a Button and does not count against the two. …
43
+ - **compactAction** `node` · optional — The one thing a reader should still be able to do once the bar has collapsed and everything else has gone into the panel — a sign-up, usually. Drawn beside the control that opens the panel, and only at the widths where that control is drawn. …
44
44
  - never: The whole of utilities. A phone has room for one action beside a mark and a menu button, and a bar handed two of them either wraps or pushes the mark off its own edge — the rest belong in utilities, which the panel lays out down its foot where there is room for all of them
45
45
  - **preferences** `node` · optional — A switcher that belongs with the destinations rather than with the conversion — a language picker, a theme toggle. It is drawn inside the pill, beside the sections, at every scroll position. …
46
46
  - never: A conversion action. Those belong in utilities, at the trailing end of the bar where a reader looks for them, and drawing one inside the pill would put the thing the page most wants pressed in among the places it goes
47
+ - **showThemeToggle** `boolean` · default false — The site offers light and dark and a reader can choose between them. …
48
+ - never: A site that ships one theme. A toggle that changes nothing is a control that lies about the page
49
+ - **theme** `enum` · optional — Whenever showThemeToggle is — the theme in force. The page owns it, because what it switches is the page's data-theme rather than anything inside the bar; the bar only draws the toggle and reports presses
50
+ - `light` — The page is drawn in its light theme, so the toggle offers dark
51
+ - `dark` — The page is drawn in its dark theme, so the toggle offers light
52
+ - **onThemeChange** `callback` · optional — Whenever showThemeToggle is. Called with the theme a press moves to; the page sets its data-theme from it and hands the new value back as theme
53
+ - never: Persisting a preference the page has not decided to keep. Remembering the choice across visits is the site's call, made where it sets data-theme
54
+ - **themeToggleLabel** `string` · optional — Whenever showThemeToggle is — the toggle draws a glyph and no words, and this is the only name it has. …
55
+ - never: Visible text. Nothing is drawn beside the glyph; a toggle with words is a NavbarSwitcher
47
56
  - **menuOpen** `boolean` · optional — The page is holding whether the panel is open, because something else depends on it — a route change that should close it, a surface of its own that must not open at the same time. …
48
57
  - never: Half of a controlled bar. A menuOpen passed without an onMenuOpenChange to move it is a panel that cannot be closed from its own close button — a trap around the whole page rather than a bar with a bug
49
58
  - **onMenuOpenChange** `callback` · optional — Whenever menuOpen is — together they are how a page holds the panel. It is called with the state being moved to, by the trigger, by the close button and by Escape, so a page listening to it hears every way the panel can change
50
59
  - never: Navigation. This says whether the panel is showing; a page that also routed on it would close the panel by leaving, and a reader pressing a destination inside it would fire both
51
60
 
61
+ ## The type refuses
62
+
63
+ - showThemeToggle=true with theme=null — A toggle that does not know which theme is in force cannot say which one a press moves to, and would draw the wrong glyph half the time
64
+ - showThemeToggle=true with onThemeChange=null — A toggle with nothing to call answers the pointer and changes nothing — the one failure the affordance cannot disclose
65
+ - showThemeToggle=true with themeToggleLabel=null — The toggle draws a glyph and no words, so without this it ships unnamed and a screen reader announces a button and nothing else
66
+
52
67
  ## Inside it
53
68
 
54
69
  - Takes only NavbarItem, NavbarMenu.
@@ -0,0 +1,49 @@
1
+ <!-- GENERATED from pageheader.contract.json. Do not edit. -->
2
+
3
+ # PageHeader
4
+
5
+ The band that opens a company or a legal page: the page's name, a line saying what it is, and nothing else. The third of three opening bands and the only one that is not a hero. …
6
+
7
+ `import { PageHeader } from '@deriv-com/dds-marketing'`
8
+
9
+ ## Reach for it when
10
+
11
+ - A company, legal or support page needs its opening band — contact, about, terms, a regulatory notice
12
+ - The page is read rather than acted on, so its opening should name it and then get out of the way
13
+ - The steps between an eyebrow, a title and a description have to be the same on every such page
14
+
15
+ ## Something else, when
16
+
17
+ - The page is the front page, or a campaign page under it → **LandingHero**
18
+ - The page is a product or a market page → **ProductHero**
19
+ - The band closes the page rather than opening it → **Footer**
20
+
21
+ ## Never
22
+
23
+ - A landing or product page. Each tier has its own band, and the reason they are separate components is so that this cannot be overridden
24
+ - Carrying a photograph or a product shot. This tier has no visual slot, which is a decision rather than an omission — a page of terms has nothing to show
25
+ - The navigation above it or the trail beneath that. Both are the page's and neither is the band's
26
+
27
+ ## Props
28
+
29
+ - **eyebrow** `string` · optional — A word or two placing the page before its title names it — a product family, a market, a campaign
30
+ - never: A second sentence. This is the line a reader takes in without reading; at the length of a clause it is a description in the wrong place and at the wrong weight
31
+ - **title** `string` · required — Always. The one thing the page is about, in the fewest words that still say it. It is the page's leading heading and the band's accessible name
32
+ - never: A sentence with a full stop. A title that reads as prose is a description that has been set at eighty pixels
33
+ - **headingLevel** `enum` · default "h1" — Which heading element the title renders as. The default is right for the band a page opens with, which is the only place this belongs. …
34
+ - `h1` — The default, and correct whenever the hero opens the page — which is what a hero is for
35
+ - `h2` — The rare page that already carries its `h1` elsewhere, and would otherwise have two
36
+ - never: Making the title look smaller. The level is what a screen reader builds its outline from, and nothing about it reaches the type
37
+ - **description** `string` · optional — The sentence under the title that says what the claim above it means, for the reader who is not yet convinced by the claim alone
38
+ - never: A paragraph. It is held to a readable measure and set at body size; past a couple of sentences a reader scrolls rather than reads, and the actions go under the fold
39
+ - **actions** `node` · optional — The one or two things the page wants a reader to do. Composed by the page rather than described to this component, so a call to action is the same Button here as anywhere else on the site
40
+ - never: A row of destinations. Three or more controls under a title is a menu, and a reader who has to choose between five things chooses none
41
+
42
+ ## Inside it
43
+
44
+ - 9 components are refused inside it; the list and the reasons are in the long document.
45
+ - Renders 8 parts: root, inner, content, text, eyebrow, title, description, actions.
46
+
47
+ ---
48
+
49
+ The reasoning behind each of these, the parts this renders, its states and snippets that compile: `.llm/components/pageheader.md`.
@@ -11,11 +11,10 @@ The control that moves a reader through a set too large to show at once. …
11
11
  - An index or archive has been split across pages and the reader needs to move through it — a blog listing, a news archive, a resource library. …
12
12
  - The reader needs to reach a particular page rather than step towards it — page fourteen of forty, in one press. …
13
13
  - The pages have addresses a search engine should follow. …
14
- - How much is left matters as much as where the reader stands. …
15
- - The reader is walking a short visual sequence and what they want to know is where they are in it rather than what that position is called — a carousel of cards, a testimonial slider, a walkthrough. …
16
14
 
17
15
  ## Something else, when
18
16
 
17
+ - A short sequence the reader moves through — a slider's slides, a carousel of cards, a walkthrough → **PaginationDots**
19
18
  - The reader is moving between views of one page rather than through one long set → **TabList**
20
19
  - More results are appended to the view as the reader reaches the end, rather than one page replacing another → **Button**
21
20
  - The reader is hunting for one row among thousands rather than walking the set → **SearchInput**
@@ -24,32 +23,22 @@ The control that moves a reader through a set too large to show at once. …
24
23
 
25
24
  - A set that fits on one page. There is nothing to move between, and a control offering to move is read as a promise that there is more — so the reader presses it, nothing happens, and they are left unsure whether the control or the results are at fault
26
25
  - Placing above the content it governs. The reader decides whether to move on only after seeing what is here, so a control above the results asks the question before they hold the answer — and on a long page it puts the control off screen at exactly the moment they want it
27
- - Ten or more positions under the dots variant. A dot carries no number, so a reader working out where they are is counting marks; past a handful the marks are too small and too many to count, and the row degrades into saying only "somewhere in the middle"
28
26
  - Standing in for a filter. Handing a reader four hundred pages is not giving them access to the set, it is giving them the shape of it — the answer is a narrower query, and pagination is what works once the set is small enough to walk
29
27
 
30
28
  ## Props
31
29
 
32
30
  - **variant** `enum` · default "pages"
33
31
  - `pages` — An index or archive whose pages have addresses of their own — a blog listing, a news archive, a resource library. …
34
- - `count` — A long set where the reader's real question is how much is left rather than which page they are on — "page 3" says nothing until you know whether there are four pages or four hundred. …
35
32
  - `compact` — A place with no room for a row of numbers — a card footer, a sidebar, a column at a phone's width. Position and the two steps, and nothing else. …
36
- - `none` — The two steps and nothing between them, for a place where position is either obvious or beside the point — a lightbox moving through images, a set of two. …
37
- - `dots` — A carousel of cards, a testimonial slider, a walkthrough — a short visual sequence where the reader cares where they are rather than what that position is called. …
38
- - never: Choosing by the width available rather than by the reader's question. The five answer different questions, and which one is being asked comes from the content above the control, not the room beneath it. …
39
- - **showSteps** `boolean` · default true — Whether the two step controls are drawn, under the dots variant. True wherever this component is the way through the set, which is nearly all of them. …
40
- - never: Any variant but dots, where it is inert rather than obeyed — the same as siblingCount under count, or totalItems under pages. Dots is the only middle holding targets of its own, so it is the only row that still works once the arrows go. …
33
+ - never: Choosing by the width available rather than by the reader's question. The two answer different questions, and which one is being asked comes from the content above the control, not the room beneath it. …
41
34
  - **page** `number` · default 1 — Always — it is which page is on screen, counting from one, and the component renders around it rather than holding it. …
42
35
  - never: Half a controlled component. Passing this without updating it when onPageChange fires gives a row that cannot move — the reader presses, the number stays, and the control reads as broken. …
43
36
  - **totalPages** `number` · default 1 — How many pages the set has been divided into. It decides where the row ends, when the ellipsis appears, and when next goes disabled. …
44
- - never: A count of items. That is totalItems, and passing one for the other gives a reader four hundred page numbers for forty pages of results. Nor for an unknown total: a number invented so the component would render is a promise about how much is left, and the reader has no way to tell it from a real one
45
- - **onPageChange** `callback` · optional — What the page does when the reader asks for another one, counting from one. Required wherever the route to a page is a press rather than a destination: the dots variant always, and the steps under any variant given no pageHref. …
37
+ - never: A count of items. Pages, not results: passing the number of results gives a reader four hundred page numbers for forty pages of them. Nor for an unknown total: a number invented so the component would render is a promise about how much is left, and the reader has no way to tell it from a real one
38
+ - **onPageChange** `callback` · optional — What the page does when the reader asks for another one, counting from one. Required wherever the route to a page is a press rather than a destination: the numbered targets and the steps under any variant given no pageHref. …
46
39
  - never: Navigating by hand when pageHref would do it. A press handler that sets window.location is an anchor with its advantages removed — no cmd-click, no destination in the status bar, nothing for a crawler to follow
47
40
  - **pageHref** `callback` · optional — The address of a page, given the page number. Passing it makes every route to a page an anchor: the numbered targets, and both steps. …
48
- - never: A carousel or any sequence whose positions have no address. A slide is not a place, so a link to one is a link to nowhere and the dots variant ignores this entirely. …
49
- - **totalItems** `number` · optional — How many results there are altogether, where that is known. …
50
- - never: A count of what is on this page. It is the whole set, which is what makes the range in front of it mean anything. Nor an estimate presented as exact: a reader shown a total treats it as one, and a number that moves as they page through the set reads as the results changing underneath them
51
- - **pageSize** `number` · optional — How many items each page holds, which is what lets the count variant work out the range on screen from the page number alone. Pass it alongside totalItems; on its own it has nothing to be a fraction of. …
52
- - never: Changing how many items are fetched. This component displays and nothing else — the fetch is the consumer's, and a page size passed here while the query still asks for a different number produces a readout that describes a page nobody is looking at
41
+ - never: A carousel or any sequence whose positions have no address. Nor for smuggling state into a query string the page does not actually route on — a URL that renders the same page whatever it says is worse than a button, which at least does not promise otherwise
53
42
  - **siblingCount** `number` · default 1 — How many numbered pages sit around the current one before the row breaks, under the pages variant. …
54
43
  - never: Widening the row until nothing is hidden. Past a few siblings the row is longer than the eye scans, and a reader who needs page 200 of 400 is not served by seeing 199 either. What widening removes is also a control now rather than a mark: the break it takes away was the menu that reached those pages in one press
55
44
  - **label** `string` · default "Pagination" — Always, and the default is almost always right. It names the landmark rather than the content — a screen reader user listing what is on a page hears this, and a nav with no name is one they cannot tell from the page's other navigation. …
@@ -64,7 +53,7 @@ The control that moves a reader through a set too large to show at once. …
64
53
  ## Inside it
65
54
 
66
55
  - 4 components are refused inside it; the list and the reasons are in the long document.
67
- - Renders 8 parts: root, list, summary, dot, dot-mark, step, page, break.
56
+ - Renders 6 parts: root, list, summary, step, page, break.
68
57
 
69
58
  ---
70
59
 
@@ -0,0 +1,43 @@
1
+ <!-- GENERATED from paginationdots.contract.json. Do not edit. -->
2
+
3
+ # PaginationDots
4
+
5
+ A row of marks, one per position in a short sequence — the slides of a slider, the steps of a walkthrough — with the one the reader is on drawn as a longer, solid pill and the rest as small translucent dots. …
6
+
7
+ `import { PaginationDots } from '@deriv-com/dds-marketing'`
8
+
9
+ ## Reach for it when
10
+
11
+ - Showing where the reader is in a short sequence they move through — a slider's slides, a carousel of cards, the steps of a walkthrough — and letting them jump to any of it …
12
+
13
+ ## Something else, when
14
+
15
+ - A set divided into pages of results → **Pagination**
16
+
17
+ ## Never
18
+
19
+ - More than about ten positions — a dot carries no number, so past a handful the reader is counting marks too small and too many to count
20
+ - The only way through a sequence without thinking about it: the marks are 8px-wide targets, so a row that stands alone — as CtaBannerSlider's does, beside a swipe — is the hardest control a pointer has to hit on the page. Give the holder previous and next steps where the sequence is one a reader works through
21
+
22
+ ## Props
23
+
24
+ - **variant** `enum` · default "default" — Whether the marks belong to their ground or to the brand
25
+ - `default` — The marks take the ink of whatever the row stands on — white on a coral or dark band, near-black on the page — so the row belongs to its ground. The usual choice, and the only one on a band
26
+ - `accent` — On the bare page, where the row should carry the brand: the marks are color.fg.brand-accent, the current pill solid coral and the rest the same coral held back. …
27
+ - never: accent on a coral or brand band, where coral marks on the coral ground disappear, or on a tinted surface, which takes the coral below the 3:1 a mark is owed
28
+ - **page** `number` · default 1 — Which position the reader is on, counted from 1. The consumer holds it, because the slide or step in view is theirs too and the two are one fact
29
+ - **totalPages** `number` · default 1 — How many positions there are, which is how many marks the row draws
30
+ - **onPageChange** `callback` · optional — Whenever the marks should move anything — called with the position pressed. The row does not move itself; the consumer sets page from it
31
+ - **autoplay** `boolean` · default false — The sequence should move on its own — a slider of promotions, a hero that rotates. The row advances page through onPageChange every motion.duration.dwell, wrapping from the last position to the first. …
32
+ - never: A sequence the reader has to work through — a walkthrough, a form in steps. Moving it for them takes away the one thing they came to control
33
+ - **paused** `boolean` · default false — Whatever holds the row wants the rotation held for now — while the pointer is over the slide or focus is inside it, so a reader is never moved on mid-sentence. It lets go when this goes false
34
+ - **label** `string` · default "Slides" — The name the row is announced by, as a group. Name what the positions are: 'Slides', 'Steps'. Translate it with the page
35
+ - **itemLabel** `string` · default "Slide" — The word each mark is named by, before its number — 'Slide 2'. Translate it with the page; a language that puts the number first is the reason a sentence template would be better, and the reason this is not yet one
36
+
37
+ ## Inside it
38
+
39
+ - Renders 3 parts: root, dot, mark.
40
+
41
+ ---
42
+
43
+ The reasoning behind each of these, the parts this renders, its states and snippets that compile: `.llm/components/paginationdots.md`.
@@ -0,0 +1,53 @@
1
+ <!-- GENERATED from producthero.contract.json. Do not edit. -->
2
+
3
+ # ProductHero
4
+
5
+ The band that opens a product or a market page: the one thing the page is about, centred, over a ground dark enough that nothing above it competes. The second of three opening bands. …
6
+
7
+ `import { ProductHero } from '@deriv-com/dds-marketing'`
8
+
9
+ ## Reach for it when
10
+
11
+ - A product or a market page needs its opening band — a platform, an instrument, an asset class
12
+ - The thing the page is about is worth showing whole, under the claim rather than beside it
13
+ - The steps between an eyebrow, a title, a description and the actions under them have to be the same on every product page
14
+
15
+ ## Something else, when
16
+
17
+ - The page is the front page, or a campaign page under it → **LandingHero**
18
+ - The page is a company or a legal one — contact, about, terms → **PageHeader**
19
+ - The band closes the page rather than opening it → **Footer**
20
+
21
+ ## Never
22
+
23
+ - A landing, company or legal page. Each tier has its own band, and the reason they are separate components is so that this cannot be overridden
24
+ - A second band further down the page. This is the page's opening and its `h1`
25
+ - The navigation above it or the trail beneath that. Both are the page's and neither is the band's
26
+
27
+ ## Props
28
+
29
+ - **eyebrow** `string` · optional — A word or two placing the page before its title names it — a product family, a market, a campaign
30
+ - never: A second sentence. This is the line a reader takes in without reading; at the length of a clause it is a description in the wrong place and at the wrong weight
31
+ - **title** `string` · required — Always. The one thing the page is about, in the fewest words that still say it. It is the page's leading heading and the band's accessible name
32
+ - never: A sentence with a full stop. A title that reads as prose is a description that has been set at eighty pixels
33
+ - **headingLevel** `enum` · default "h1" — Which heading element the title renders as. The default is right for the band a page opens with, which is the only place this belongs. …
34
+ - `h1` — The default, and correct whenever the hero opens the page — which is what a hero is for
35
+ - `h2` — The rare page that already carries its `h1` elsewhere, and would otherwise have two
36
+ - never: Making the title look smaller. The level is what a screen reader builds its outline from, and nothing about it reaches the type
37
+ - **description** `string` · optional — The sentence under the title that says what the claim above it means, for the reader who is not yet convinced by the claim alone
38
+ - never: A paragraph. It is held to a readable measure and set at body size; past a couple of sentences a reader scrolls rather than reads, and the actions go under the fold
39
+ - **actions** `node` · optional — The one or two things the page wants a reader to do. Composed by the page rather than described to this component, so a call to action is the same Button here as anywhere else on the site
40
+ - never: A row of destinations. Three or more controls under a title is a menu, and a reader who has to choose between five things chooses none
41
+ - **media** `node` · optional — The product itself, under the claim and the actions — in the column, capped to the measure, and whole
42
+ - never: The background. A photograph filling the band is `backgroundImage`; this sits in front of it, in the column, and is never cropped
43
+ - **backgroundImage** `string` · optional — A photograph filling the whole band. It is shown as it is — nothing is painted over it, so choose one already dark enough that the title reads on it
44
+ - never: A flat colour, or a bright photograph. The band already paints its ground, and nothing here darkens an image on the page's behalf — a pale one leaves the claim unreadable
45
+
46
+ ## Inside it
47
+
48
+ - 8 components are refused inside it; the list and the reasons are in the long document.
49
+ - Renders 9 parts: root, inner, content, text, eyebrow, title, description, actions, media.
50
+
51
+ ---
52
+
53
+ The reasoning behind each of these, the parts this renders, its states and snippets that compile: `.llm/components/producthero.md`.
@@ -11,6 +11,7 @@ A chip that opens a list of answers and keeps the one chosen, so a filter row sh
11
11
  - A row narrows an index by one value out of a set, and has to keep showing which value that is
12
12
  - The set is short enough to scan rather than search — a region, a language, a sort order
13
13
  - The row has no space for a form field: nothing above the control, nothing beneath it, only the answer
14
+ - A view setting that always has an answer — a sort order, a language — where every answer is a way of looking rather than a way of leaving out
14
15
 
15
16
  ## Something else, when
16
17
 
@@ -36,7 +37,11 @@ A chip that opens a list of answers and keeps the one chosen, so a filter row sh
36
37
  - `start` — The list's leading edge lines up with the chip's. The default, because a reader reads from that edge and the answers begin where the chip's own words began
37
38
  - `end` — Its trailing edge lines up instead, for a chip near the end of a row where a list opening the other way would run off the screen
38
39
  - never: Nudging the list into place a few pixels. It names an edge to line up, not an offset
39
- - **label** `string` · required — Always, and required on that account — it names what is being chosen, and it is what the chip shows until something has been. Short enough to read at a glance in a row of other chips
40
+ - **emphasis** `enum` · default "highlight" — Whether the chip fills once an answer is chosen. Ask one question: does choosing an answer hide anything? If it does, it is a filter and the chip is highlight. If it only changes how the page is shown, it is a setting and the chip is quiet
41
+ - `highlight` — A filter. Choosing an answer hides part of the list, like a category, a topic or a product line. The chip fills to show a filter is on
42
+ - `quiet` — A setting that only changes how the page is shown, like a sort order, a language or a layout. Nothing is hidden, so the chip stays plain and reads "Label: Value". …
43
+ - never: Making one chip in a row look more important than the others. Decide by what the chip does to the page, not by how much it matters. Having a starting value does not make a chip quiet either: a status filter that starts on Open still hides the closed ones, so it stays highlight
44
+ - **label** `string` · required — Always, and required on that account — it names what is being chosen, and it is what the chip shows until something has been, and what a quiet chip goes on showing ahead of the answer. …
40
45
  - never: Describing what pressing it does. The chip names the narrowing, and what happens is that a list opens
41
46
  - **value** `string` · optional — The page owns the answer — it arrives from a URL, is shared with something else on screen, or has to survive the chip unmounting. Passed, this is the answer, and onChange is the only way it moves
42
47
  - never: Seeding a first answer and then leaving it alone. That is defaultValue, and passing this instead gives a chip that cannot be changed
@@ -0,0 +1,51 @@
1
+ <!-- GENERATED from testimonialrow.contract.json. Do not edit. -->
2
+
3
+ # TestimonialRow
4
+
5
+ A section that lets a review service's numbers back the page: a heading with the overall rating under it — and a way to where the reviews were collected — over a row of rated reviews the reader moves along, each a short review under its star rating with the reviewer's name, and two arrows under the row that step it a card at a time. …
6
+
7
+ `import { TestimonialRow } from '@deriv-com/dds-marketing'`
8
+
9
+ ## Reach for it when
10
+
11
+ - Five to ten short, rated reviews collected by a review service, where seeing several at once is the point and the overall score is worth stating
12
+ - A page that has made its claims and wants customers' own ratings to back them — a homepage's "What our customers say"
13
+
14
+ ## Something else, when
15
+
16
+ - Two to five quotes the page chose, from partners or customers, each a few sentences and read one at a time → **TestimonialSlider**
17
+ - A single review → **FeatureSplit**
18
+
19
+ ## Never
20
+
21
+ - Reviews nobody wrote, or a rating nobody gave. The stars and the summary are a score in a review service's name — keep each rating and the overall score in step with the source, and link to it, or leave them out
22
+ - A review service's own marks. Its logo, wordmark and brand colour belong to its own widget, under its own rules; this draws each card's stars in the page's accent and names the service in words
23
+ - Long reviews. A card is read on the way along the row; one that needs more than a sentence or two is a review the reader skips
24
+
25
+ ## Props
26
+
27
+ - **ground** `enum` · default "page" — 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. …
28
+ - `page` — The default, and the page's own white. The cards are the recessed gray that sets them off
29
+ - `subtle` — The grey band, the reference design's ground for this section. The cards turn white on it. …
30
+ - `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. …
31
+ - never: 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
32
+ - **title** `string` · required — Always. Whose reviews these are, in a few words — "What our customers say"
33
+ - never: A review, or the score. The reviews are the content and the summary states the score; the heading says whose they are
34
+ - **reviews** `data` · required — Always. The reviews, in the order they run along the row — five to ten of a sentence or two, each with the reviewer's name, its `rating` and, where there is one, the `href` of the review itself. An empty list draws nothing
35
+ - never: A review that was not written by the person named, or a rating changed from the one they gave
36
+ - **summary** `data` · optional — The overall rating, in the page's own words under the heading — "Rated 4.5 out of 5 on our review site" — as a standalone Link to where the reviews were collected when it has an `href`. …
37
+ - never: A number the source does not show today
38
+ - **ratingLabel** `callback` · optional — The accessible name of a card's stars, given its rating as drawn — rounded to the nearest half, so what is heard is what is seen. The stars are drawn rather than written, so this is what a screen reader hears for them. …
39
+ - never: Visible text. It names the stars to assistive technology and is never drawn
40
+ - **label** `string` · default "Reviews" — The name the row is announced by. The row is a scrolling region a keyboard has to be able to reach, so it carries a tab stop and a name of its own — Scroller's rule. …
41
+ - **previousLabel** `string` · default "Previous reviews" — The accessible name of the arrow stepping the row back. A glyph announces nothing, so this is the whole of the control's name. Translate it with the page, and keep it parallel to nextLabel
42
+ - **nextLabel** `string` · default "Next reviews" — The accessible name of the arrow stepping the row on, for the reason previousLabel exists
43
+
44
+ ## Inside it
45
+
46
+ - 7 components are refused inside it; the list and the reasons are in the long document.
47
+ - Renders 20 parts: root, inner, header, title, summary, carousel, track, review-link, item, rating, star, star-track, star-fill, quote, author, name, detail, footer, nav, nav-slot.
48
+
49
+ ---
50
+
51
+ The reasoning behind each of these, the parts this renders, its states and snippets that compile: `.llm/components/testimonialrow.md`.
@@ -0,0 +1,51 @@
1
+ <!-- GENERATED from testimonialslider.contract.json. Do not edit. -->
2
+
3
+ # TestimonialSlider
4
+
5
+ A section that lets the people who use the product say what it did for them: a heading over one quote at a time, in a card, with the name of who said it. …
6
+
7
+ `import { TestimonialSlider } from '@deriv-com/dds-marketing'`
8
+
9
+ ## Reach for it when
10
+
11
+ - Two to five real quotes from partners or customers, each a few sentences, read one at a time
12
+ - A page that has made its claims and wants someone other than the brand to back them
13
+
14
+ ## Something else, when
15
+
16
+ - A single quote → **FeatureSplit**
17
+ - Ratings and review counts from a review site → **TestimonialRow**
18
+
19
+ ## Never
20
+
21
+ - Quotes nobody said. A testimonial is a claim made in someone else's name, and an invented one is a false claim — use real, attributable words or none
22
+ - More than a few sentences per quote. A quote is read while it is in view; one that needs scrolling inside the card is never finished
23
+
24
+ ## Props
25
+
26
+ - **ground** `enum` · default "page" — 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. …
27
+ - `page` — The default, and the page's own white. The card is the recessed gray that sets it off
28
+ - `subtle` — The grey band, the reference design's ground for this section. The card turns white on it. …
29
+ - `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. …
30
+ - never: Marking importance. Every section on a page painted a ground is a page with no emphasis left
31
+ - **title** `string` · required — Always. Whose words these are, in a few — "What our partners say", "What our customers say"
32
+ - never: A quote. The quotes are the content; the heading says whose they are
33
+ - **quotes** `data` · required — Always. The quotes, in the order they rotate — two to five, each a few sentences, each with the name of who said it. An empty list draws nothing; one quote is drawn still, with no dots
34
+ - never: A quote that was not said. Every one is attributed to a person or a role, and the page is answerable for each
35
+ - **imageStart** `string` · optional — A decorative picture, laid over the card's top start corner — a photograph, a product screen, any small piece of art, usually a PNG — as a path or a URL. …
36
+ - never: Anything a reader needs: a logo that says who the quotes are from, words, the face of the person quoted. It is hidden from assistive technology so it is art or it is missing
37
+ - **imageEnd** `string` · optional — A decorative picture at the card's bottom end corner, the pair to imageStart: drawn the same way behind the card's bottom edge, and drifting up as the other drifts down, so the two read as depth. …
38
+ - never: The same as imageStart's: art only
39
+ - **autoplay** `boolean` · default false — Whether it advances on its own, holding each slide for motion.duration.dwell. Off by default, so a slider nobody configured stays still. …
40
+ - never: A banner whose slides carry more than a reader can take in during motion.duration.dwell — turn it off rather than shorten the copy to fit the timer
41
+ - **controlsLabel** `string` · default "Testimonials" — The name the dots are announced by. Its own name rather than the section's, so a screen reader moving into the dots hears what they are. Translate it with the page
42
+ - **slideLabel** `string` · default "Slide" — The word each dot is announced by, before its number — 'Slide 2'. Translate it with the page, as controlsLabel is; a page that translates only the group's name still has every dot announced in English
43
+
44
+ ## Inside it
45
+
46
+ - 6 components are refused inside it; the list and the reasons are in the long document.
47
+ - Renders 15 parts: root, inner, title, carousel, track, item, image-start, image-end, image, quote, author, avatar, name, detail, controls.
48
+
49
+ ---
50
+
51
+ The reasoning behind each of these, the parts this renders, its states and snippets that compile: `.llm/components/testimonialslider.md`.
package/.llm/index.md CHANGED
@@ -22,7 +22,7 @@ Domain-neutral building blocks.
22
22
  | Badge | One of a set is the one the page wants read first — the plan most people choose, the market most people start with · Something is new or has changed, and saying so is worth a word rather than a sentence · A number the page is promoting is worth marking as a saving rather than left in the copy — a percentage off, a period free | What it says is a state the reader's account is in → nothing here · The words are the point rather than the mark → `CardBody` |
23
23
  | Breadcrumb | The page sits inside a section hierarchy, and the levels above it are places the visitor can navigate to — a product page inside a markets section, a blog post inside a category · A visitor who arrived by search, social link or campaign URL needs to learn where they landed and how the site is organised around them | The visitor is moving through the stages of a sign-up or onboarding flow rather than standing in a hierarchy → nothing here · There is exactly one place to go back to, and it is the previous page rather than a parent section → nothing here |
24
24
  | BreadcrumbItem | Rendering one level of a Breadcrumb — every level in a trail is one of these · The level needs a short name the visitor recognises as a place: the section name, not a sentence about it | The destination is somewhere the visitor goes to act rather than a level they climb back to → nothing here |
25
- | Button | The call to action on a marketing page — the one step you want a visitor to take next · Moving a visitor along a funnel: hero to signup, pricing to checkout, feature page to demo booking · A destination prominent enough that it has to read as a control rather than as words in a sentence | The action happens on the current page — submitting a form, toggling a setting, opening a dialog, removing something → nothing here · The words belong inside a sentence or a paragraph of body copy → nothing here · The control is a glyph alone, with no words → `ButtonIcon` |
25
+ | Button | The call to action on a marketing page — the one step you want a visitor to take next · Moving a visitor along a funnel: hero to signup, pricing to checkout, feature page to demo booking · A destination prominent enough that it has to read as a control rather than as words in a sentence | The action belongs to an application surface — a trade form, a settings panel, a confirmation that removes something → nothing here · The words belong inside a sentence or a paragraph of body copy → `Link` · The control is a glyph alone, with no words → `ButtonIcon` |
26
26
  | ButtonIcon | One press with no room for words — a promotional bar's dismiss, a hero's play control, a carousel step, a footer's social links. Whether it navigates or acts in place is decided by href alone, so the same component covers both · A row of glyph-alone destinations where words would only repeat — social accounts in a footer, app stores in a download band, a region switch in a header · A control the page owns rather than a destination — dismissing a promotional bar, playing a hero video, advancing a carousel, opening a mobile nav. Leave href off and it is a button, which answers Space and fires what the page says · The glyph is one a visitor reads without being taught — a play triangle, a dismiss cross, a chevron, a social mark in its monochrome cut. A marketing page gets no onboarding and usually no second visit to learn in · Room is genuinely short and the words would be the same words several times over. One of these on its own beside prose is usually a Button that lost its label | The control has words, or needs them to be understood → `Button` · The whole surface is the target — a card standing for a feature, a market or a plan → `CardButton` · The mark is an ornament rather than a control → `Icon` · The mark reports a state the visitor sets and reads back — sound on or off, a light and dark switch → nothing here |
27
27
  | Card | Content that is read as one thing — a feature and the sentence explaining it, a plan and what it costs, a step and what it asks for · A picture that reaches the card's edges, with or without copy inset beneath it — a screenshot, a photograph, a band of art. The corner clips it, and the card adds no inset that would leave it floating in a margin · A row or a column of such groups, where the fill is what separates one from the next · A measure a landing page should not be choosing for itself: the corner a card takes and the ground it sits on · An editorial card — an article, a post, a story — where the picture and the headline do the separating and a fill would be a second, weaker edge. That is `plain`, which paints no ground and keeps the corner | The whole surface is the thing the reader presses → `CardButton` |
28
28
  | CardBody | Words, a picture, or both inside a Card — a feature and the sentence explaining it, a screenshot under the copy that describes it · A photograph, render or screenshot that should reach the card's edges while the copy above it stays inset · A picture that should absorb whatever height the copy leaves, so a row of cards ends flush no matter how much each one says · A mark above the words — the glyph a feature card leads with, sized and inset with the copy rather than reaching the card's edges · Copy that sits over the picture rather than beside it — a photograph as the card's ground, with a title and a sentence washed over it · A line above the title filing the card under something — the date an article ran, how long it takes to read, the category it belongs to. It is set in capitals at the eyebrow step, which is what tells it apart from the copy without it needing a colour of its own | The whole card is one picture, with no words at all → `Card` |
@@ -37,6 +37,7 @@ Domain-neutral building blocks.
37
37
  | NavbarItem | A section of the site, in a Navbar — the ordinary case and what this is for · A destination that leaves the site, which it marks as a change of context rather than leaving the reader to find out · The same destination inside the panel a narrow bar collapses into: a page writes its navigation once, and what changes with the width is how it is drawn | The destination opens a panel of further destinations rather than going somewhere → `NavbarMenu` · The destination is a phrase inside a sentence, or a call to action beneath a paragraph → `Link` · The item is one of a set of alternatives rather than a place → `Tab` |
38
38
  | NavbarMenuGroup | A section's panel holds more destinations than a reader takes in at once, and they fall into sets — markets, tools, payments · Two lists in a panel would be told apart by nothing if the words above them were taken away | The panel holds few enough destinations that naming sets would be naming one thing each → `NavbarItem` · The set is a section of the site rather than a set within one → `NavbarMenu` |
39
39
  | Option | An answer inside a control that opens a list — a SelectChip today. One of these per option in the set | Pressing it should do something rather than record an answer → `MenuItem` · The row is one of a few and all of them fit on the page → `FilterChip` |
40
+ | PaginationDots | Showing where the reader is in a short sequence they move through — a slider's slides, a carousel of cards, the steps of a walkthrough — and letting them jump to any of it | A set divided into pages of results → `Pagination` |
40
41
  | SearchInput | A help centre, a knowledge base, or documentation — more pages than a menu can carry · A blog or resource index a reader arrives at knowing roughly what they want · A directory the page already holds and can filter as the reader types — markets, offices, partners | The field is part of a form the reader will submit → nothing here · The set is small enough to show at once → nothing here · The reader is choosing from known options rather than describing what they want → nothing here |
41
42
  | SegmentedControlItem | One option in a SegmentedControl — the thing a reader presses to change which of a few mutually exclusive values is in force · A choice worth showing beside its alternatives rather than hiding in a list, so the reader compares and picks in one glance | The option names a slice of the page the reader moves to rather than a value they set → `Tab` · The choice is on or off rather than one of several → `Button` · The option leads somewhere → `Link` |
42
43
  | Select | A form asks for one answer out of a set the visitor recognises — a country, a language, the reason they are getting in touch · An index or a table is worth narrowing, and the choice reshapes the page rather than being submitted — the sort on a list of articles, the market a pricing table shows · The set is long enough that showing it in full would crowd the page, which is what separates this from a row of chips or a segmented control | The set is a handful and worth comparing side by side → `SegmentedControl` · The choices are destinations rather than answers → `DropdownMenu` · The reader can pick more than one → nothing here · The answer is not on the list, and typing one should stand → nothing here |
@@ -67,10 +68,10 @@ Domain-neutral building blocks.
67
68
  | NavbarPanel | Navbar is collapsing and its destinations have to go somewhere. This is where, and the bar puts them here without being asked · The same navigation has to be read down a phone rather than across a page | The surface is a sheet rising from the foot of the page rather than the site's navigation → `BottomSheet` · What is wanted is a list that opens beside the control that opened it → `DropdownMenu` |
68
69
  | NavbarSwitcher | A bar needs a language or region switcher, which is the case this was drawn for · A set of choices changes how the page is drawn or worded rather than taking a reader anywhere · The set is long enough that a phone should give it the whole panel rather than a dropdown inside one | The control opens a set of commands rather than a set of choices → `DropdownMenu` · The control flips between two states → `ButtonIcon` · The items are places the site has → `NavbarMenu` |
69
70
  | NavbarSwitcherOption | A NavbarSwitcher needs its choices · One of a set of options is in force and a reader should be able to see which | The row goes somewhere → `NavbarItem` · The row is a command in a dropdown → `MenuItem` |
70
- | Pagination | An index or archive has been split across pages and the reader needs to move through it — a blog listing, a news archive, a resource library. It belongs below the results, because the decision to move on is one the reader makes after reading what is here · The reader needs to reach a particular page rather than step towards it — page fourteen of forty, in one press. That is the pages variant, and the only one offering a target with a number on it. Where the row has no room for that number, the break standing in for it opens a menu of the pages it hides, so a page the row cannot show is two presses away rather than a walk · The pages have addresses a search engine should follow. Numbered targets drawn as links are how an index gets crawled past its first page, which on a marketing site is usually the reason the index exists · How much is left matters as much as where the reader stands. A total passed to the count variant turns the readout from a position into a measure, which is what tells someone whether to keep reading or search instead · The reader is walking a short visual sequence and what they want to know is where they are in it rather than what that position is called — a carousel of cards, a testimonial slider, a walkthrough. That is the dots variant, and it holds while the set stays under about ten: a dot carries no number, so past a handful the reader is counting marks too small and too many to count | The reader is moving between views of one page rather than through one long set → `TabList` · More results are appended to the view as the reader reaches the end, rather than one page replacing another → `Button` · The reader is hunting for one row among thousands rather than walking the set → `SearchInput` |
71
+ | Pagination | An index or archive has been split across pages and the reader needs to move through it — a blog listing, a news archive, a resource library. It belongs below the results, because the decision to move on is one the reader makes after reading what is here · The reader needs to reach a particular page rather than step towards it — page fourteen of forty, in one press. That is the pages variant, and the only one offering a target with a number on it. Where the row has no room for that number, the break standing in for it opens a menu of the pages it hides, so a page the row cannot show is two presses away rather than a walk · The pages have addresses a search engine should follow. Numbered targets drawn as links are how an index gets crawled past its first page, which on a marketing site is usually the reason the index exists | A short sequence the reader moves through — a slider's slides, a carousel of cards, a walkthrough → `PaginationDots` · The reader is moving between views of one page rather than through one long set → `TabList` · More results are appended to the view as the reader reaches the end, rather than one page replacing another → `Button` · The reader is hunting for one row among thousands rather than walking the set → `SearchInput` |
71
72
  | RemovableChip | An index shows the narrowings currently applied above its results, and each has to come off on its own without clearing the rest · The reader has assembled something across a page — markets on a comparison, topics on a subscription form — and needs to see and unpick what is in it · What was chosen is worth showing as a token rather than as a sentence, because the reader will act on individual pieces of it | The token is turned on and off rather than added and taken away → `FilterChip` · The thing named cannot be taken away and is there to be read — a category on a card, a status on a plan → `Badge` · The token is really a link to the thing it names → `Link` |
72
73
  | SegmentedControl | Two to four alternatives that exclude one another, where the whole set is worth showing at once and the reader decides by weighing them side by side rather than recalling which exist · What the reader picks becomes a value something next to it consumes — a period against which prices are quoted, a unit, a plan — which puts the control beside whatever it alters rather than at the head of the page · The alternatives are short enough to read across in a glance. A row is scanned, not worked through | The choice swaps a whole slice of the page rather than setting a value → `TabList` · The alternatives are separate topics rather than values of one question → `Accordion` · There are more than about four, or the labels need more than a word or two → `SelectChip` · The choice is on or off → `Button` · The reader may pick several of the options at once, or none → `FilterChip` |
73
- | SelectChip | A row narrows an index by one value out of a set, and has to keep showing which value that is · The set is short enough to scan rather than search — a region, a language, a sort order · The row has no space for a form field: nothing above the control, nothing beneath it, only the answer | Pressing an item does something rather than answering something → `DropdownMenu` · The chip answers on its own, or the set is short enough for every answer to sit in the row as a chip of its own → `FilterChip` · Each answer is a page with its own address → `Link` |
74
+ | SelectChip | A row narrows an index by one value out of a set, and has to keep showing which value that is · The set is short enough to scan rather than search — a region, a language, a sort order · The row has no space for a form field: nothing above the control, nothing beneath it, only the answer · A view setting that always has an answer — a sort order, a language — where every answer is a way of looking rather than a way of leaving out | Pressing an item does something rather than answering something → `DropdownMenu` · The chip answers on its own, or the set is short enough for every answer to sit in the row as a chip of its own → `FilterChip` · Each answer is a page with its own address → `Link` |
74
75
  | SubdomainNavbar | A subdomain needs its top-level navigation — the mark, the places that subdomain has, and whatever sits at the far end · The bar should sit still. Nothing about it changes as the page scrolls, which is what a reader working in a page rather than reading down one wants of the chrome above it · The destinations belong at the far end with what a reader reaches for, rather than centred over the page: the mark holds one edge, everything a reader does holds the other, and the middle is left empty on purpose | The page is the marketing site itself → `Navbar` · The items are versions of one thing rather than places the subdomain has → `TabList` |
75
76
  | TabList | Two or three versions of one offer differ in a way a reader wants to compare — monthly against yearly, one platform against another · The page has already written every version, and showing them at once would be repetition rather than information · The reader's choice changes what they see and nothing else — no route, no account, nothing the page has to remember | The sections are separate topics rather than versions of one thing → `Accordion` · Every version is worth reading → `Card` · The tabs would go to other pages → nothing here |
76
77
 
@@ -84,3 +85,23 @@ Arrange other components and decide no appearance of their own.
84
85
  | Row | Two or more things are read across rather than down, and the space between them is the same all the way along — a glyph and its label, a title and the action beside it, a set of controls · The spacing is a fact about the group rather than about any member of it. Set here, every item agrees; set on the items, the group is only as consistent as the last person to add one · The items are of different heights and something has to decide how they meet — centred on the line, level at the top, or sitting on one another's baseline. That decision belongs to the line rather than to any item on it | The things are read one above the next → `Stack` · The things must line up down the page as well as across it → `Grid` · The set is longer than the line and has to stay on one line → `Scroller` · The things across are the fields of one record, and the record repeats down the page → `Table` |
85
86
  | Scroller | A set is longer than the space and its order is worth keeping — steps in a sequence, results already ranked, a timeline, a run of chips a reader is scanning rather than comparing · The things are of a kind and of a size, so a line of them reads as a line rather than as a row of unrelated objects that happen to be beside one another · Seeing part of the next item is what tells the reader there is more. A rail cut off mid-item is the affordance, and it is the one thing a wrapped line and a grid cannot offer | Everything fits, or should be made to fit → `Row` · The set may break onto a second line and nothing is lost by it → `Row` · The items should line up in columns as well → `Grid` · The region scrolls down rather than across → nothing here |
86
87
  | Stack | Two or more things are read down the page in order and the space between them is the same the whole way down — an eyebrow, a headline and a line of copy; the points of a feature list; the rows of a plan · The spacing is a fact about the group rather than about any member of it. Set here, every row agrees; set on the rows, the group is only as consistent as the last person to add one · The measure should tighten on a phone without anyone writing a breakpoint. The top three steps of this ramp already do, so a column set at one of them is narrower below 768px and nothing about the page says so | The things sit beside one another rather than one above the next → `Row` · The things must line up across as well as down → `Grid` · The set has to stay on one line and the reader moves along it → `Scroller` |
88
+
89
+ ## Blocks
90
+
91
+ The sections a page is built from, and the rhythm between them.
92
+ | Component | Use when | Not for |
93
+ |---|---|---|
94
+ | CtaBanner | A short, high-contrast promotion with one clear action — open an account, start trading, download the app · The band that closes a page, or breaks a long one, on the action the page exists to produce | Two or three promotions to rotate between → `CtaBannerSlider` · The band that opens the page → `LandingHero` · A message that needs a picture beside it → `FeatureSplit` |
95
+ | CtaBannerSlider | Rotating between two or three genuinely different promotions without a hero's weight — open an account, try a tool, download the app | One promotion → `CtaBanner` · The band that opens the page → `LandingHero` · A message with more than a headline, a line and a button or two → `FeatureSplit` |
96
+ | FaqAccordion | The questions a reader asks before acting — fees, limits, how long a withdrawal takes — near the end of a landing page or on a help page · Objections a page has to answer without making every reader read every answer | The answers are short enough to read all at once → `FeatureBullets` · Each item is a feature, not a question → `FeatureCards` |
97
+ | FeatureBullets | A page has to list what a product or a plan includes, and the list is the argument · Several benefits are each one line long and are read by scanning rather than reading · A claim needs something beside it, and a picture is the only thing there is to put there | The items are two or three words and belong on one line → `Badge` · Each item needs a heading and a paragraph of its own → `Card` · The section opens the page → `ProductHero` |
98
+ | FeatureCards | Three or four things a product does, each a heading and a sentence, read side by side and compared at a glance · A set of destinations — markets, platforms, tools — each a card a reader presses to go there · One feature that deserves the whole row in a card of its own — the words beside a large picture, carded on the section's ground | Each item is one line, and the list is the argument → `FeatureBullets` · One claim beside a picture, with no card around it → `FeatureSplit` · The items are read in order, one leading to the next → `FeatureScroll` |
99
+ | FeatureScroll | A page has three or more things of the same kind to explain, each with a picture worth a screen — the markets a broker offers, the platforms it runs, the steps of an account opening · The set is meant to be walked through rather than compared, and a reader is expected to scroll it · The set comes from somewhere — a CMS, a registry, a filtered list — rather than being written out by hand | There are three or four items a reader is meant to compare → `FeatureCards` · The set is lines rather than things — what an account includes → `FeatureBullets` · There is one point to make → `FeatureSplit` · The section opens the page → `LandingHero` |
100
+ | FeatureSplit | A page needs one more point about something it has already introduced, with a picture to carry it · The point is a sentence rather than a list, and does not earn a set of cards · A section needs a way onward that is not a call to action — a link to the page that says more | The point is several things the reader gets, each one line long → `FeatureBullets` · There are three or four points and each needs its own picture → `FeatureCards` · The section opens the page → `ProductHero` |
101
+ | LandingHero | A main landing page needs its opening band — the front page, or a campaign page under it · The claim has room to range to the reading edge with a subject beside it, which is what the landing tier is for · The steps between an eyebrow, a title, a description and the actions under them have to be the same on every landing page | The page is a product or a market page → `ProductHero` · The page is a company or a legal one — contact, about, terms → `PageHeader` · The band closes the page rather than opening it → `Footer` |
102
+ | LogoColumns | Showing the partners, integrations or payment methods behind a claim — the names a reader recognises, as evidence for what the words say · Eight or more logos, enough that each column reads as running on past both edges of the wall | A handful of logos a reader should be able to count and compare → `Grid` · One picture beside the claim → `FeatureSplit` · Each logo needs to be pressed — a partner directory → `FeatureCards` |
103
+ | LogoRows | Showing the partners, integrations or payment methods behind a claim under it, where the words lead and the logos follow · Eight or more logos, enough that each of the two rows reads as running on past both edges of the band | The logos should stand beside the claim, as a wall that is half the section → `LogoColumns` · A handful of logos a reader should be able to count and compare → `Grid` |
104
+ | PageHeader | A company, legal or support page needs its opening band — contact, about, terms, a regulatory notice · The page is read rather than acted on, so its opening should name it and then get out of the way · The steps between an eyebrow, a title and a description have to be the same on every such page | The page is the front page, or a campaign page under it → `LandingHero` · The page is a product or a market page → `ProductHero` · The band closes the page rather than opening it → `Footer` |
105
+ | ProductHero | A product or a market page needs its opening band — a platform, an instrument, an asset class · The thing the page is about is worth showing whole, under the claim rather than beside it · The steps between an eyebrow, a title, a description and the actions under them have to be the same on every product page | The page is the front page, or a campaign page under it → `LandingHero` · The page is a company or a legal one — contact, about, terms → `PageHeader` · The band closes the page rather than opening it → `Footer` |
106
+ | TestimonialRow | Five to ten short, rated reviews collected by a review service, where seeing several at once is the point and the overall score is worth stating · A page that has made its claims and wants customers' own ratings to back them — a homepage's "What our customers say" | Two to five quotes the page chose, from partners or customers, each a few sentences and read one at a time → `TestimonialSlider` · A single review → `FeatureSplit` |
107
+ | TestimonialSlider | Two to five real quotes from partners or customers, each a few sentences, read one at a time · A page that has made its claims and wants someone other than the brand to back them | A single quote → `FeatureSplit` · Ratings and review counts from a review site → `TestimonialRow` |