@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,161 @@
1
+ /* GENERATED from logocolumns.contract.json. Do not edit. */
2
+
3
+ :where([data-dds-context="marketing"]) .dds-logocolumns {
4
+ box-sizing: border-box;
5
+ container-type: inline-size;
6
+ display: flex;
7
+ inline-size: 100%;
8
+ justify-content: center;
9
+ overflow: clip;
10
+ }
11
+
12
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__inner {
13
+ box-sizing: border-box;
14
+ display: flex;
15
+ flex-direction: column;
16
+ inline-size: 100%;
17
+ min-inline-size: 0;
18
+ max-inline-size: var(--size-content-max);
19
+ padding-block: var(--space-section-default);
20
+ padding-inline: var(--space-inset-page);
21
+ }
22
+
23
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__split {
24
+ align-items: stretch;
25
+ display: flex;
26
+ min-inline-size: 0;
27
+ column-gap: var(--space-gap-3xl);
28
+ row-gap: var(--space-gap-2xl);
29
+ }
30
+
31
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__content {
32
+ display: flex;
33
+ flex-direction: column;
34
+ min-inline-size: 0;
35
+ row-gap: var(--space-gap-none);
36
+ }
37
+
38
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__title {
39
+ margin-block: 0;
40
+ text-wrap: balance;
41
+ font-family: var(--font-h2-family);
42
+ font-size: var(--font-h2-size);
43
+ font-weight: var(--font-h2-weight);
44
+ letter-spacing: var(--font-h2-letter-spacing);
45
+ line-height: var(--font-h2-line-height);
46
+ margin-block-end: var(--space-heading-title-description);
47
+ }
48
+
49
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__description {
50
+ margin-block: 0;
51
+ font-family: var(--font-body-md-family);
52
+ font-size: var(--font-body-md-size);
53
+ font-weight: var(--font-body-md-weight);
54
+ letter-spacing: var(--font-body-md-letter-spacing);
55
+ line-height: var(--font-body-md-line-height);
56
+ margin-block-end: var(--space-heading-description-actions);
57
+ max-inline-size: var(--size-measure-description);
58
+ }
59
+
60
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__disclaimer {
61
+ margin-block: 0;
62
+ font-family: var(--font-body-sm-family);
63
+ font-size: var(--font-body-sm-size);
64
+ font-weight: var(--font-body-sm-weight);
65
+ letter-spacing: var(--font-body-sm-letter-spacing);
66
+ line-height: var(--font-body-sm-line-height);
67
+ margin-block-end: var(--space-heading-description-actions);
68
+ max-inline-size: var(--size-measure-description);
69
+ }
70
+
71
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__link {
72
+ display: flex;
73
+ margin-block-start: var(--space-gap-none);
74
+ }
75
+
76
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__media {
77
+ display: flex;
78
+ min-inline-size: 0;
79
+ overflow: clip;
80
+ position: relative;
81
+ block-size: var(--size-logo-columns-height);
82
+ column-gap: var(--space-grid-gutter);
83
+ }
84
+
85
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__column {
86
+ display: flex;
87
+ flex-direction: column;
88
+ list-style: none;
89
+ margin: 0;
90
+ min-inline-size: 0;
91
+ padding: 0;
92
+ row-gap: var(--space-grid-gutter);
93
+ }
94
+
95
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__logo {
96
+ align-items: center;
97
+ box-sizing: border-box;
98
+ display: flex;
99
+ justify-content: center;
100
+ aspect-ratio: var(--aspect-landscape);
101
+ border-radius: var(--radius-container-item);
102
+ padding-block: var(--space-inset-md);
103
+ padding-inline: var(--space-inset-md);
104
+ }
105
+
106
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__logo-image {
107
+ block-size: 100%;
108
+ display: block;
109
+ inline-size: 100%;
110
+ object-fit: contain;
111
+ border-radius: var(--radius-control-sm);
112
+ }
113
+
114
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-media-position="end"] .dds-logocolumns__split {
115
+ flex-direction: row;
116
+ }
117
+
118
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-media-position="start"] .dds-logocolumns__split {
119
+ flex-direction: row-reverse;
120
+ }
121
+
122
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="page"] {
123
+ background-color: var(--color-bg-page);
124
+ color: var(--color-fg-default);
125
+ }
126
+
127
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="page"] .dds-logocolumns__disclaimer {
128
+ color: var(--color-fg-muted);
129
+ }
130
+
131
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="page"] .dds-logocolumns__logo {
132
+ background-color: var(--color-bg-surface);
133
+ }
134
+
135
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="strong"] {
136
+ background-color: var(--color-bg-brand-strong);
137
+ color: var(--color-fg-on-brand-strong);
138
+ }
139
+
140
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="strong"] .dds-logocolumns__disclaimer {
141
+ color: var(--color-fg-muted-inverse);
142
+ }
143
+
144
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="strong"] .dds-logocolumns__logo {
145
+ background-color: var(--color-bg-surface-card-strong);
146
+ }
147
+
148
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="subtle"] {
149
+ background-color: var(--color-bg-page);
150
+ background-image: linear-gradient(var(--color-bg-band-subtle), var(--color-bg-band-subtle));
151
+ color: var(--color-fg-default);
152
+ }
153
+
154
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="subtle"] .dds-logocolumns__disclaimer {
155
+ color: var(--color-fg-muted);
156
+ }
157
+
158
+ :where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="subtle"] .dds-logocolumns__logo {
159
+ background-color: var(--color-bg-surface-card-raised);
160
+ }
161
+
@@ -0,0 +1,23 @@
1
+ import './LogoColumns.css';
2
+ import './logo-columns-impl.css';
3
+ import '../block-reveal.css';
4
+ import { type LogoColumnsProps } from './LogoColumns.types.js';
5
+ export type { LogoColumnsProps };
6
+ /**
7
+ * A claim beside a wall of logos — the reference site's LogoMarquee, as FeatureSplit with the
8
+ * picture replaced by the names that back the words.
9
+ *
10
+ * Nothing here moves on its own. The two columns are moved by the stylesheet, on a view timeline
11
+ * the wall carries, so they run with the reader's scroll — the first rising, the second falling —
12
+ * and stand still the moment the page does, and for a reader who asked for less motion. The
13
+ * reference drives the same effect from scroll velocity in a frame loop; a scroll timeline is the
14
+ * platform doing that, with no script running per frame.
15
+ *
16
+ * The logos are dealt into the two columns in order, alternately, so a page orders one list rather
17
+ * than splitting it. Each column is a list of the logos it was dealt, drawn `SETS` times over; only
18
+ * the first set is announced, so a screen reader hears each name once.
19
+ *
20
+ * The steps inside the column of words follow FeatureSplit's: each part's own `margin-block-end`.
21
+ * The title carries the section's accessible name through `aria-labelledby`.
22
+ */
23
+ export declare function LogoColumns({ ground, mediaPosition, title, description, disclaimer, link, logos, }: LogoColumnsProps): import("react").JSX.Element | null;
@@ -0,0 +1,46 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from 'react';
4
+ import './LogoColumns.css';
5
+ import './logo-columns-impl.css';
6
+ import '../block-reveal.css';
7
+ import { arriving, useReveal } from '../use-reveal.js';
8
+ import { given } from '../../given.js';
9
+ import { logoColumnsDefaults, logoColumnsParts, } from './LogoColumns.types.js';
10
+ /**
11
+ * How many times each column is drawn. The columns move by one set across the wall's pass, so the
12
+ * end of the movement shows what the start did; three sets keep a column running on past both
13
+ * edges at every point of it, even for a short column.
14
+ */
15
+ const SETS = 3;
16
+ /**
17
+ * A claim beside a wall of logos — the reference site's LogoMarquee, as FeatureSplit with the
18
+ * picture replaced by the names that back the words.
19
+ *
20
+ * Nothing here moves on its own. The two columns are moved by the stylesheet, on a view timeline
21
+ * the wall carries, so they run with the reader's scroll — the first rising, the second falling —
22
+ * and stand still the moment the page does, and for a reader who asked for less motion. The
23
+ * reference drives the same effect from scroll velocity in a frame loop; a scroll timeline is the
24
+ * platform doing that, with no script running per frame.
25
+ *
26
+ * The logos are dealt into the two columns in order, alternately, so a page orders one list rather
27
+ * than splitting it. Each column is a list of the logos it was dealt, drawn `SETS` times over; only
28
+ * the first set is announced, so a screen reader hears each name once.
29
+ *
30
+ * The steps inside the column of words follow FeatureSplit's: each part's own `margin-block-end`.
31
+ * The title carries the section's accessible name through `aria-labelledby`.
32
+ */
33
+ export function LogoColumns({ ground = logoColumnsDefaults.ground, mediaPosition = logoColumnsDefaults.mediaPosition, title, description, disclaimer, link, logos, }) {
34
+ const titleId = useId();
35
+ const [band, revealed] = useReveal();
36
+ // Nothing to show is nothing drawn: a wall with no logo on it is a claim with no evidence.
37
+ if (logos.length === 0)
38
+ return null;
39
+ const columns = [
40
+ logos.filter((_, at) => at % 2 === 0),
41
+ logos.filter((_, at) => at % 2 === 1),
42
+ ];
43
+ return (_jsx("section", { className: logoColumnsParts.root, "data-ground": ground, "data-media-position": mediaPosition, "aria-labelledby": titleId, children: _jsx("div", { className: logoColumnsParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: logoColumnsParts.split, children: [_jsxs("div", { className: logoColumnsParts.content, children: [_jsx("h2", { className: logoColumnsParts.title, ...arriving(0), id: titleId, children: title }), given(description) ? (_jsx("p", { className: logoColumnsParts.description, ...arriving(1), children: description })) : null, disclaimer !== undefined && given(disclaimer) ? (_jsx("p", { className: logoColumnsParts.disclaimer, ...arriving(1), children: disclaimer })) : null, link ? (_jsx("div", { className: logoColumnsParts.link, ...arriving(2), children: link })) : null] }), _jsx("div", { className: logoColumnsParts.media, ...arriving(3), children: columns.map((column, at) => column.length === 0 ? null : (_jsx("ul", { className: logoColumnsParts.column, "data-column": at === 0 ? 'rising' : 'falling', children: Array.from({ length: SETS }, (_, set) => column.map((logo, index) => (
44
+ // A logo's place is its identity: the list is the page's, and nothing reorders it.
45
+ _jsx("li", { className: logoColumnsParts.logo, "aria-hidden": set === 0 ? undefined : 'true', children: _jsx("img", { className: logoColumnsParts['logo-image'], src: logo.src, alt: logo.name, draggable: false }) }, `${set}-${index}`)))) }, at))) })] }) }) }));
46
+ }
@@ -0,0 +1,46 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { LogoTile } from '../../logo-data.js';
3
+ export interface LogoColumnsOwnProps {
4
+ /**
5
+ * `page` — The page's own white, with tiles at the recessed gray. For full-colour logos drawn for a light ground
6
+ * `subtle` — The grey band, with white tiles on it. For full-colour logos, where the section needs setting apart from the ones around it. Painted as the band's tint over the page's own ground, so it is the same grey whatever is behind the section
7
+ * `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. The ground white wordmarks are drawn for
8
+ */
9
+ ground?: 'page' | 'subtle' | 'strong';
10
+ /**
11
+ * `start` — The default, the reference design's: the wall at the start, the claim beside it at the end
12
+ * `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
13
+ */
14
+ mediaPosition?: 'start' | 'end';
15
+ /** Always. The one claim the logos back, in the fewest words that say it — "Trusted by leading platforms worldwide". */
16
+ title: string;
17
+ /** The line under the heading: what the logos mean for the reader — which payment methods they can use, which platforms they can trade on. */
18
+ description?: string;
19
+ /** Small print the claim needs — "*Availability varies by region." Under the description, quieter than it. */
20
+ disclaimer?: string;
21
+ /** The way onward — a standalone Link, "View all partners", usually. Under the words, never on the wall: the tiles move. */
22
+ link?: ReactNode;
23
+ /** 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. Each name is what a screen reader hears for its logo. */
24
+ logos: LogoTile[];
25
+ }
26
+ export type LogoColumnsProps = LogoColumnsOwnProps;
27
+ /** The class each part carries. Apply these — do not retype them. */
28
+ export declare const logoColumnsParts: {
29
+ readonly root: "dds-logocolumns";
30
+ readonly inner: "dds-logocolumns__inner";
31
+ readonly split: "dds-logocolumns__split";
32
+ readonly content: "dds-logocolumns__content";
33
+ readonly title: "dds-logocolumns__title";
34
+ readonly description: "dds-logocolumns__description";
35
+ readonly disclaimer: "dds-logocolumns__disclaimer";
36
+ readonly link: "dds-logocolumns__link";
37
+ readonly media: "dds-logocolumns__media";
38
+ readonly column: "dds-logocolumns__column";
39
+ readonly logo: "dds-logocolumns__logo";
40
+ readonly 'logo-image': "dds-logocolumns__logo-image";
41
+ };
42
+ /** Generated so defaults cannot drift from the contract. */
43
+ export declare const logoColumnsDefaults: {
44
+ readonly ground: "strong";
45
+ readonly mediaPosition: "start";
46
+ };
@@ -0,0 +1,18 @@
1
+ // GENERATED from logo-columns.contract.json. Do not edit.
2
+ /** The class each part carries. Apply these — do not retype them. */
3
+ export const logoColumnsParts = {
4
+ root: 'dds-logocolumns',
5
+ inner: 'dds-logocolumns__inner',
6
+ split: 'dds-logocolumns__split',
7
+ content: 'dds-logocolumns__content',
8
+ title: 'dds-logocolumns__title',
9
+ description: 'dds-logocolumns__description',
10
+ disclaimer: 'dds-logocolumns__disclaimer',
11
+ link: 'dds-logocolumns__link',
12
+ media: 'dds-logocolumns__media',
13
+ column: 'dds-logocolumns__column',
14
+ logo: 'dds-logocolumns__logo',
15
+ 'logo-image': 'dds-logocolumns__logo-image',
16
+ };
17
+ /** Generated so defaults cannot drift from the contract. */
18
+ export const logoColumnsDefaults = { ground: 'strong', mediaPosition: 'start' };
@@ -0,0 +1,188 @@
1
+ /*
2
+ * Scoped to this package, like the generated sheet beside it.
3
+ *
4
+ * `:where([data-dds-context="marketing"])` confines these rules without contributing specificity,
5
+ * so each is decided against the generated rule on its own terms.
6
+ */
7
+
8
+ /*
9
+ * The last of the words carries no step under it — FeatureSplit's rule and its reason: the steps
10
+ * sit on each part's own `margin-block-end`, so whichever part ends the column would otherwise be
11
+ * measured against nothing.
12
+ */
13
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__title:last-child,
14
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__description:last-child,
15
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__disclaimer:last-child {
16
+ margin-block-end: 0;
17
+ }
18
+
19
+ /* The disclaimer sits close under the description it qualifies, not a full step away. */
20
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__description:has(+ .dds-logocolumns__disclaimer) {
21
+ margin-block-end: var(--space-heading-title-description);
22
+ }
23
+
24
+ /*
25
+ * One column below the fold, and the words lead it — FeatureSplit's fold, written with the
26
+ * `data-media-position` attribute so it carries the weight of the generated rules keyed on it.
27
+ */
28
+ @container (max-width: 47.9375rem) {
29
+ :where([data-dds-context="marketing"])
30
+ .dds-logocolumns[data-media-position]
31
+ .dds-logocolumns__split {
32
+ flex-direction: column;
33
+ }
34
+
35
+ }
36
+
37
+ /* At full width the claim takes a measure and the wall takes the rest, FeatureSplit's shares. */
38
+ @container (min-width: 48rem) {
39
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__split {
40
+ align-items: center;
41
+ }
42
+
43
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__content {
44
+ flex: 0 0 45%;
45
+ }
46
+
47
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__media {
48
+ flex: 1 1 0;
49
+ }
50
+ }
51
+
52
+ /*
53
+ * The wall's edges fade out rather than cut.
54
+ *
55
+ * A mask rather than a gradient painted over the tiles: a painted fade has to be the ground's own
56
+ * colour to disappear into it, and would need restating for every ground and theme. A mask takes
57
+ * the tiles to transparent, so whatever is behind the wall shows through on any ground.
58
+ *
59
+ * A tenth of the wall at each edge, and eased: the mask's opacity follows a smoothstep curve across
60
+ * the fade rather than a straight line, which is what made the first one read as a hard band — a
61
+ * linear fade has its sharpest change at both of its ends. The stops are the curve sampled; a
62
+ * gradient between two stops is still linear, so the curve is in how many there are.
63
+ *
64
+ * Most of the fade only dims: the tiles fall to two fifths over the inner four fifths of it, eased,
65
+ * and only the last fifth at the very edge takes them on to nothing. The wall reads as running on
66
+ * behind the fade rather than dissolving into it, and still ends in no line — a fade that stopped
67
+ * at two fifths left the tiles cut off at the wall's edge in a straight one. Each is black
68
+ * mixed toward transparent rather than a colour value: a mask reads only the alpha, and the two
69
+ * keywords say so without a raw colour in a component's stylesheet.
70
+ */
71
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__media {
72
+ --dds-logocolumns-fade: calc(var(--size-logo-columns-height) * 0.1);
73
+ mask-image: linear-gradient(
74
+ to bottom,
75
+ transparent calc(var(--dds-logocolumns-fade) * 0),
76
+ color-mix(in srgb, black 40.0%, transparent) calc(var(--dds-logocolumns-fade) * 0.2),
77
+ color-mix(in srgb, black 46.2%, transparent) calc(var(--dds-logocolumns-fade) * 0.36),
78
+ color-mix(in srgb, black 61.1%, transparent) calc(var(--dds-logocolumns-fade) * 0.52),
79
+ color-mix(in srgb, black 78.9%, transparent) calc(var(--dds-logocolumns-fade) * 0.68),
80
+ color-mix(in srgb, black 93.8%, transparent) calc(var(--dds-logocolumns-fade) * 0.84),
81
+ black calc(var(--dds-logocolumns-fade) * 1.0),
82
+ black calc(100% - var(--dds-logocolumns-fade) * 1.0),
83
+ color-mix(in srgb, black 93.8%, transparent) calc(100% - var(--dds-logocolumns-fade) * 0.84),
84
+ color-mix(in srgb, black 78.9%, transparent) calc(100% - var(--dds-logocolumns-fade) * 0.68),
85
+ color-mix(in srgb, black 61.1%, transparent) calc(100% - var(--dds-logocolumns-fade) * 0.52),
86
+ color-mix(in srgb, black 46.2%, transparent) calc(100% - var(--dds-logocolumns-fade) * 0.36),
87
+ color-mix(in srgb, black 40.0%, transparent) calc(100% - var(--dds-logocolumns-fade) * 0.2),
88
+ transparent calc(100% - var(--dds-logocolumns-fade) * 0)
89
+ );
90
+ }
91
+
92
+ @container (max-width: 47.9375rem) {
93
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__media {
94
+ --dds-logocolumns-fade: calc(var(--size-logo-columns-height) * 0.05);
95
+ }
96
+ }
97
+
98
+ /*
99
+ * The wall runs to the section's own edges, top and bottom.
100
+ *
101
+ * It is drawn taller than its token by the section step at each end, and pulled back by the same
102
+ * distance into the band's padding: the section keeps its height and the words beside the wall
103
+ * keep their air, while the tiles run on to the band's edge and fade out there rather than stopping
104
+ * a step short of it — which left a band of empty ground under a fade that had already ended.
105
+ */
106
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__media {
107
+ block-size: calc(var(--size-logo-columns-height) + 2 * var(--space-section-default));
108
+ margin-block: calc(-1 * var(--space-section-default));
109
+ }
110
+
111
+ /* Half the wall on a phone: a screen of tiles under the words would be a screen the reader
112
+ scrolls past to find out the section is over. */
113
+ @container (max-width: 47.9375rem) {
114
+ /* Only the foot runs to the band's edge on a phone. The top edge sits under the words rather
115
+ than at the band's edge, and pulled up it would fade into the link. */
116
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__media {
117
+ block-size: calc(var(--size-logo-columns-height) * 0.5 + var(--space-section-default));
118
+ margin-block-start: 0;
119
+ }
120
+ }
121
+
122
+ /*
123
+ * Two columns sharing the wall, each as tall as its tiles. `align-self: flex-start` is what lets a
124
+ * column be taller than the wall: stretched, it would be held to the wall's height and have nothing
125
+ * to travel through.
126
+ */
127
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__column {
128
+ align-self: flex-start;
129
+ flex: 1 1 0;
130
+ }
131
+
132
+ /*
133
+ * The columns run with the scroll, in opposite directions.
134
+ *
135
+ * A view timeline on the wall measures its pass through the viewport, and each column travels one
136
+ * set — a third of its own height with the gap after its last tile counted in, the column being
137
+ * three sets — across that pass: the first rising, the second falling. One set is the distance at
138
+ * which the column shows exactly what it did at the start, so nothing jumps at either end. Scroll-
139
+ * driven, so it moves as the reader scrolls and back again as they scroll back, and stands still
140
+ * while the page does.
141
+ *
142
+ * The timeline measures against the nearest scroll container, which is why the section and the
143
+ * wall clip with `overflow: clip` rather than `hidden`: `hidden` makes a box a scroll container
144
+ * even when it never scrolls, and the columns would then sit still however far the page moved.
145
+ * A browser with no scroll timeline draws the columns still, which is the whole of the fallback.
146
+ */
147
+ @keyframes dds-logocolumns-rise {
148
+ from {
149
+ translate: none;
150
+ }
151
+ to {
152
+ translate: 0 calc(-1 * (100% + var(--space-grid-gutter)) / 3);
153
+ }
154
+ }
155
+
156
+ @keyframes dds-logocolumns-fall {
157
+ from {
158
+ translate: 0 calc(-1 * (100% + var(--space-grid-gutter)) / 3);
159
+ }
160
+ to {
161
+ translate: none;
162
+ }
163
+ }
164
+
165
+ @supports (animation-timeline: view()) {
166
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__media {
167
+ view-timeline: --dds-logocolumns-wall block;
168
+ }
169
+
170
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__column[data-column='rising'] {
171
+ animation: dds-logocolumns-rise linear both;
172
+ animation-range: cover;
173
+ animation-timeline: --dds-logocolumns-wall;
174
+ }
175
+
176
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__column[data-column='falling'] {
177
+ animation: dds-logocolumns-fall linear both;
178
+ animation-range: cover;
179
+ animation-timeline: --dds-logocolumns-wall;
180
+ }
181
+ }
182
+
183
+ /* A reader who asked for less movement gets none of it: the columns stand still. */
184
+ @media (prefers-reduced-motion: reduce) {
185
+ :where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__column {
186
+ animation: none;
187
+ }
188
+ }
@@ -0,0 +1,122 @@
1
+ /* GENERATED from logorows.contract.json. Do not edit. */
2
+
3
+ :where([data-dds-context="marketing"]) .dds-logorows {
4
+ box-sizing: border-box;
5
+ container-type: inline-size;
6
+ display: flex;
7
+ inline-size: 100%;
8
+ justify-content: center;
9
+ overflow: clip;
10
+ }
11
+
12
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__inner {
13
+ box-sizing: border-box;
14
+ display: flex;
15
+ flex-direction: column;
16
+ inline-size: 100%;
17
+ min-inline-size: 0;
18
+ max-inline-size: var(--size-content-max);
19
+ padding-block: var(--space-section-default);
20
+ padding-inline: var(--space-inset-page);
21
+ row-gap: var(--space-heading-content);
22
+ }
23
+
24
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__header {
25
+ display: flex;
26
+ flex-direction: column;
27
+ min-inline-size: 0;
28
+ max-inline-size: var(--size-measure-heading);
29
+ row-gap: var(--space-gap-none);
30
+ }
31
+
32
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__title {
33
+ margin-block: 0;
34
+ text-wrap: balance;
35
+ font-family: var(--font-h2-family);
36
+ font-size: var(--font-h2-size);
37
+ font-weight: var(--font-h2-weight);
38
+ letter-spacing: var(--font-h2-letter-spacing);
39
+ line-height: var(--font-h2-line-height);
40
+ margin-block-end: var(--space-heading-title-description);
41
+ }
42
+
43
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__description {
44
+ margin-block: 0;
45
+ font-family: var(--font-body-md-family);
46
+ font-size: var(--font-body-md-size);
47
+ font-weight: var(--font-body-md-weight);
48
+ letter-spacing: var(--font-body-md-letter-spacing);
49
+ line-height: var(--font-body-md-line-height);
50
+ max-inline-size: var(--size-measure-description);
51
+ }
52
+
53
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__link {
54
+ display: flex;
55
+ margin-block-start: var(--space-heading-description-actions);
56
+ }
57
+
58
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__rail {
59
+ display: flex;
60
+ flex-direction: column;
61
+ min-inline-size: 0;
62
+ overflow: clip;
63
+ row-gap: var(--space-grid-gutter);
64
+ }
65
+
66
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__track {
67
+ display: flex;
68
+ flex: none;
69
+ list-style: none;
70
+ margin: 0;
71
+ padding: 0;
72
+ column-gap: var(--space-grid-gutter);
73
+ }
74
+
75
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__logo {
76
+ align-items: center;
77
+ box-sizing: border-box;
78
+ display: flex;
79
+ justify-content: center;
80
+ aspect-ratio: var(--aspect-landscape);
81
+ border-radius: var(--radius-container-item);
82
+ inline-size: var(--size-logo-rows-tile);
83
+ padding-block: var(--space-inset-md);
84
+ padding-inline: var(--space-inset-md);
85
+ }
86
+
87
+ :where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__logo-image {
88
+ block-size: 100%;
89
+ display: block;
90
+ inline-size: 100%;
91
+ object-fit: contain;
92
+ border-radius: var(--radius-control-sm);
93
+ }
94
+
95
+ :where([data-dds-context="marketing"]) .dds-logorows[data-ground="page"] {
96
+ background-color: var(--color-bg-page);
97
+ color: var(--color-fg-default);
98
+ }
99
+
100
+ :where([data-dds-context="marketing"]) .dds-logorows[data-ground="page"] .dds-logorows__logo {
101
+ background-color: var(--color-bg-surface);
102
+ }
103
+
104
+ :where([data-dds-context="marketing"]) .dds-logorows[data-ground="strong"] {
105
+ background-color: var(--color-bg-brand-strong);
106
+ color: var(--color-fg-on-brand-strong);
107
+ }
108
+
109
+ :where([data-dds-context="marketing"]) .dds-logorows[data-ground="strong"] .dds-logorows__logo {
110
+ background-color: var(--color-bg-surface-card-strong);
111
+ }
112
+
113
+ :where([data-dds-context="marketing"]) .dds-logorows[data-ground="subtle"] {
114
+ background-color: var(--color-bg-page);
115
+ background-image: linear-gradient(var(--color-bg-band-subtle), var(--color-bg-band-subtle));
116
+ color: var(--color-fg-default);
117
+ }
118
+
119
+ :where([data-dds-context="marketing"]) .dds-logorows[data-ground="subtle"] .dds-logorows__logo {
120
+ background-color: var(--color-bg-surface-card-raised);
121
+ }
122
+
@@ -0,0 +1,20 @@
1
+ import './LogoRows.css';
2
+ import './logo-rows-impl.css';
3
+ import '../block-reveal.css';
4
+ import { type LogoRowsProps } from './LogoRows.types.js';
5
+ export type { LogoRowsProps };
6
+ /**
7
+ * A claim over two rows of logos — LogoColumns stacked: the words centred on top, the logos in
8
+ * two rows across the band's full width under them.
9
+ *
10
+ * Nothing here moves on its own. The stylesheet slides the rows sideways on a view timeline the
11
+ * rail carries — the first toward the start, the second toward the end — so they run with the
12
+ * reader's scroll and stand still the moment the page does, and for a reader who asked for less
13
+ * motion.
14
+ *
15
+ * The logos are dealt into the two rows in order, alternately, so a page orders one list rather
16
+ * than splitting it. Each row is a list of the logos it was dealt, drawn `SETS` times over; only
17
+ * the first set is announced, so a screen reader hears each name once. The title carries the
18
+ * section's accessible name through `aria-labelledby`.
19
+ */
20
+ export declare function LogoRows({ ground, title, description, link, logos, }: LogoRowsProps): import("react").JSX.Element | null;
@@ -0,0 +1,43 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from 'react';
4
+ import './LogoRows.css';
5
+ import './logo-rows-impl.css';
6
+ import '../block-reveal.css';
7
+ import { arriving, useReveal } from '../use-reveal.js';
8
+ import { given } from '../../given.js';
9
+ import { logoRowsDefaults, logoRowsParts, } from './LogoRows.types.js';
10
+ /**
11
+ * How many times each row is drawn. A row moves by one set across the rail's pass, so the end of
12
+ * the movement shows what the start did; four sets keep it running on past both ends of a wide
13
+ * screen at every point of it. The stylesheet's travel — a quarter of the row — is written for four.
14
+ */
15
+ const SETS = 4;
16
+ /**
17
+ * A claim over two rows of logos — LogoColumns stacked: the words centred on top, the logos in
18
+ * two rows across the band's full width under them.
19
+ *
20
+ * Nothing here moves on its own. The stylesheet slides the rows sideways on a view timeline the
21
+ * rail carries — the first toward the start, the second toward the end — so they run with the
22
+ * reader's scroll and stand still the moment the page does, and for a reader who asked for less
23
+ * motion.
24
+ *
25
+ * The logos are dealt into the two rows in order, alternately, so a page orders one list rather
26
+ * than splitting it. Each row is a list of the logos it was dealt, drawn `SETS` times over; only
27
+ * the first set is announced, so a screen reader hears each name once. The title carries the
28
+ * section's accessible name through `aria-labelledby`.
29
+ */
30
+ export function LogoRows({ ground = logoRowsDefaults.ground, title, description, link, logos, }) {
31
+ const titleId = useId();
32
+ const [band, revealed] = useReveal();
33
+ // Nothing to show is nothing drawn: a row with no logo on it is a claim with no evidence.
34
+ if (logos.length === 0)
35
+ return null;
36
+ const rows = [
37
+ logos.filter((_, at) => at % 2 === 0),
38
+ logos.filter((_, at) => at % 2 === 1),
39
+ ];
40
+ return (_jsx("section", { className: logoRowsParts.root, "data-ground": ground, "aria-labelledby": titleId, children: _jsxs("div", { className: logoRowsParts.inner, ref: band, "data-revealed": revealed, children: [_jsxs("div", { className: logoRowsParts.header, children: [_jsx("h2", { className: logoRowsParts.title, id: titleId, ...arriving(0), children: title }), given(description) ? (_jsx("p", { className: logoRowsParts.description, ...arriving(1), children: description })) : null, link ? (_jsx("div", { className: logoRowsParts.link, ...arriving(2), children: link })) : null] }), _jsx("div", { className: logoRowsParts.rail, ...arriving(3), children: rows.map((row, at) => row.length === 0 ? null : (_jsx("ul", { className: logoRowsParts.track, "data-row": at === 0 ? 'leading' : 'trailing', children: Array.from({ length: SETS }, (_, set) => row.map((logo, index) => (
41
+ // A logo's place is its identity: the list is the page's, and nothing reorders it.
42
+ _jsx("li", { className: logoRowsParts.logo, "aria-hidden": set === 0 ? undefined : 'true', children: _jsx("img", { className: logoRowsParts['logo-image'], src: logo.src, alt: logo.name, draggable: false }) }, `${set}-${index}`)))) }, at))) })] }) }));
43
+ }