@deriv-com/dds-marketing 1.1.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/.llm/components/accordion.md +6 -0
  2. package/.llm/components/accordionitem.md +6 -0
  3. package/.llm/components/aspectratio.md +6 -0
  4. package/.llm/components/awards.md +6 -0
  5. package/.llm/components/background.md +49 -10
  6. package/.llm/components/badge.md +6 -0
  7. package/.llm/components/bottomsheet.md +6 -0
  8. package/.llm/components/breadcrumb.md +6 -0
  9. package/.llm/components/breadcrumbitem.md +6 -0
  10. package/.llm/components/button.md +9 -3
  11. package/.llm/components/buttonicon.md +7 -1
  12. package/.llm/components/card.md +6 -0
  13. package/.llm/components/cardbody.md +7 -1
  14. package/.llm/components/cardbutton.md +6 -0
  15. package/.llm/components/checkbox.md +6 -0
  16. package/.llm/components/comparisoncards.md +9 -3
  17. package/.llm/components/comparisontable.md +6 -0
  18. package/.llm/components/ctabanner.md +6 -0
  19. package/.llm/components/ctabannerslider.md +6 -0
  20. package/.llm/components/datatable.md +6 -0
  21. package/.llm/components/divider.md +6 -0
  22. package/.llm/components/documentlink.md +237 -0
  23. package/.llm/components/documents.md +268 -0
  24. package/.llm/components/downloadbanner.md +7 -1
  25. package/.llm/components/dropdownmenu.md +6 -0
  26. package/.llm/components/estimator.md +6 -0
  27. package/.llm/components/faqaccordion.md +6 -0
  28. package/.llm/components/featurebullets.md +6 -0
  29. package/.llm/components/featurecards.md +42 -2
  30. package/.llm/components/featurecardscarousel.md +7 -1
  31. package/.llm/components/featurescroll.md +6 -0
  32. package/.llm/components/featuresplit.md +6 -0
  33. package/.llm/components/featurestack.md +6 -0
  34. package/.llm/components/featuretabs.md +369 -0
  35. package/.llm/components/filterchip.md +6 -0
  36. package/.llm/components/footer.md +6 -0
  37. package/.llm/components/footergroup.md +6 -0
  38. package/.llm/components/grid.md +30 -1
  39. package/.llm/components/icon.md +6 -0
  40. package/.llm/components/illustrationcard.md +52 -2
  41. package/.llm/components/illustrationcheck.md +193 -0
  42. package/.llm/components/illustrationchoice.md +187 -0
  43. package/.llm/components/illustrationcode.md +192 -0
  44. package/.llm/components/illustrationlist.md +175 -0
  45. package/.llm/components/illustrationscene.md +29 -3
  46. package/.llm/components/imagebanner.md +30 -5
  47. package/.llm/components/landinghero.md +6 -0
  48. package/.llm/components/link.md +7 -1
  49. package/.llm/components/logocolumns.md +7 -1
  50. package/.llm/components/logorows.md +42 -2
  51. package/.llm/components/menuitem.md +6 -0
  52. package/.llm/components/navbar.md +6 -0
  53. package/.llm/components/navbaritem.md +6 -0
  54. package/.llm/components/navbarmenu.md +6 -0
  55. package/.llm/components/navbarmenugroup.md +6 -0
  56. package/.llm/components/navbarpanel.md +6 -0
  57. package/.llm/components/navbarswitcher.md +6 -0
  58. package/.llm/components/navbarswitcheroption.md +6 -0
  59. package/.llm/components/option.md +6 -0
  60. package/.llm/components/pageheader.md +6 -0
  61. package/.llm/components/pagination.md +6 -0
  62. package/.llm/components/paginationdots.md +6 -0
  63. package/.llm/components/producthero.md +29 -4
  64. package/.llm/components/progressbar.md +305 -0
  65. package/.llm/components/removablechip.md +6 -0
  66. package/.llm/components/resourcebanner.md +6 -0
  67. package/.llm/components/row.md +6 -0
  68. package/.llm/components/scenescroll.md +38 -24
  69. package/.llm/components/scenescrollword.md +267 -0
  70. package/.llm/components/scroller.md +6 -0
  71. package/.llm/components/searchinput.md +6 -0
  72. package/.llm/components/segmentedcontrol.md +28 -1
  73. package/.llm/components/segmentedcontrolitem.md +6 -0
  74. package/.llm/components/select.md +6 -0
  75. package/.llm/components/selectchip.md +6 -0
  76. package/.llm/components/spinner.md +6 -0
  77. package/.llm/components/stack.md +6 -0
  78. package/.llm/components/stats.md +46 -1
  79. package/.llm/components/statscarousel.md +227 -0
  80. package/.llm/components/statusdot.md +41 -1
  81. package/.llm/components/steps.md +6 -0
  82. package/.llm/components/stickycards.md +6 -0
  83. package/.llm/components/subdomainnavbar.md +6 -0
  84. package/.llm/components/tab.md +6 -0
  85. package/.llm/components/table.md +6 -0
  86. package/.llm/components/tablebody.md +6 -0
  87. package/.llm/components/tablecell.md +6 -0
  88. package/.llm/components/tablehead.md +6 -0
  89. package/.llm/components/tableheadercell.md +6 -0
  90. package/.llm/components/tablerow.md +6 -0
  91. package/.llm/components/tablist.md +6 -0
  92. package/.llm/components/teamgrid.md +6 -0
  93. package/.llm/components/testimonialrow.md +43 -3
  94. package/.llm/components/testimonialslider.md +8 -2
  95. package/.llm/components/textarea.md +6 -0
  96. package/.llm/components/textinput.md +6 -0
  97. package/.llm/components/textscroll.md +6 -0
  98. package/.llm/components/tiers.md +13 -7
  99. package/.llm/components/tooltip.md +6 -0
  100. package/.llm/components/typography.md +63 -1
  101. package/.llm/digest/background.md +14 -6
  102. package/.llm/digest/button.md +1 -1
  103. package/.llm/digest/buttonicon.md +1 -1
  104. package/.llm/digest/documentlink.md +52 -0
  105. package/.llm/digest/documents.md +51 -0
  106. package/.llm/digest/downloadbanner.md +1 -1
  107. package/.llm/digest/featurecards.md +7 -0
  108. package/.llm/digest/featuretabs.md +50 -0
  109. package/.llm/digest/grid.md +1 -0
  110. package/.llm/digest/illustrationcard.md +6 -1
  111. package/.llm/digest/illustrationcheck.md +42 -0
  112. package/.llm/digest/illustrationchoice.md +43 -0
  113. package/.llm/digest/illustrationcode.md +41 -0
  114. package/.llm/digest/illustrationlist.md +38 -0
  115. package/.llm/digest/illustrationscene.md +4 -2
  116. package/.llm/digest/imagebanner.md +9 -3
  117. package/.llm/digest/logocolumns.md +1 -1
  118. package/.llm/digest/logorows.md +8 -1
  119. package/.llm/digest/producthero.md +8 -2
  120. package/.llm/digest/progressbar.md +56 -0
  121. package/.llm/digest/scenescroll.md +6 -5
  122. package/.llm/digest/scenescrollword.md +56 -0
  123. package/.llm/digest/segmentedcontrol.md +3 -0
  124. package/.llm/digest/stats.md +8 -0
  125. package/.llm/digest/statscarousel.md +48 -0
  126. package/.llm/digest/statusdot.md +7 -0
  127. package/.llm/digest/testimonialrow.md +8 -1
  128. package/.llm/digest/testimonialslider.md +1 -1
  129. package/.llm/digest/typography.md +18 -0
  130. package/.llm/index.md +14 -4
  131. package/.llm/rules.md +10 -0
  132. package/.llm/tokens.md +12 -3
  133. package/AGENTS.md +13 -2
  134. package/dist/components/arrival.d.ts +32 -0
  135. package/dist/components/arrival.js +140 -0
  136. package/dist/components/arrives.d.ts +17 -0
  137. package/dist/components/arrives.js +14 -0
  138. package/dist/components/blocks/awards/Awards.js +2 -27
  139. package/dist/components/blocks/block-pattern.css +23 -0
  140. package/dist/components/blocks/comparison-cards/comparison-cards-impl.css +29 -0
  141. package/dist/components/blocks/documents/Documents.css +90 -0
  142. package/dist/components/blocks/documents/Documents.d.ts +22 -0
  143. package/dist/components/blocks/documents/Documents.js +30 -0
  144. package/dist/components/blocks/documents/Documents.types.d.ts +37 -0
  145. package/dist/components/blocks/documents/Documents.types.js +14 -0
  146. package/dist/components/blocks/documents/documents-impl.css +103 -0
  147. package/dist/components/blocks/download-banner/DownloadBanner.css +1 -1
  148. package/dist/components/blocks/download-banner/DownloadBanner.types.d.ts +1 -1
  149. package/dist/components/blocks/feature-cards/FeatureCards.d.ts +2 -1
  150. package/dist/components/blocks/feature-cards/FeatureCards.js +10 -7
  151. package/dist/components/blocks/feature-cards/FeatureCards.types.d.ts +9 -1
  152. package/dist/components/blocks/feature-cards/feature-cards-impl.css +15 -3
  153. package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.types.d.ts +1 -1
  154. package/dist/components/blocks/feature-cards-carousel/feature-cards-carousel-impl.css +12 -0
  155. package/dist/components/blocks/feature-tabs/FeatureTabs.css +100 -0
  156. package/dist/components/blocks/feature-tabs/FeatureTabs.d.ts +23 -0
  157. package/dist/components/blocks/feature-tabs/FeatureTabs.js +38 -0
  158. package/dist/components/blocks/feature-tabs/FeatureTabs.types.d.ts +35 -0
  159. package/dist/components/blocks/feature-tabs/FeatureTabs.types.js +14 -0
  160. package/dist/components/blocks/feature-tabs/feature-tabs-impl.css +53 -0
  161. package/dist/components/blocks/image-banner/ImageBanner.css +1 -1
  162. package/dist/components/blocks/image-banner/ImageBanner.d.ts +1 -1
  163. package/dist/components/blocks/image-banner/ImageBanner.js +2 -2
  164. package/dist/components/blocks/image-banner/ImageBanner.types.d.ts +9 -7
  165. package/dist/components/blocks/image-banner/ImageBanner.types.js +1 -1
  166. package/dist/components/blocks/image-banner/image-banner-impl.css +77 -26
  167. package/dist/components/blocks/laurel.d.ts +16 -0
  168. package/dist/components/blocks/laurel.js +28 -0
  169. package/dist/components/blocks/logo-columns/LogoColumns.css +1 -1
  170. package/dist/components/blocks/logo-columns/LogoColumns.types.d.ts +1 -1
  171. package/dist/components/blocks/logo-rows/LogoRows.css +1 -1
  172. package/dist/components/blocks/logo-rows/LogoRows.d.ts +2 -1
  173. package/dist/components/blocks/logo-rows/LogoRows.js +7 -4
  174. package/dist/components/blocks/logo-rows/LogoRows.types.d.ts +9 -1
  175. package/dist/components/blocks/pattern-tone.d.ts +11 -0
  176. package/dist/components/blocks/pattern-tone.js +7 -0
  177. package/dist/components/blocks/product-hero/ProductHero.d.ts +1 -1
  178. package/dist/components/blocks/product-hero/ProductHero.js +2 -2
  179. package/dist/components/blocks/product-hero/ProductHero.types.d.ts +8 -3
  180. package/dist/components/blocks/product-hero/ProductHero.types.js +1 -1
  181. package/dist/components/blocks/product-hero/product-hero-impl.css +54 -0
  182. package/dist/components/blocks/resource-banner/ResourceBanner.css +1 -1
  183. package/dist/components/blocks/scene-scroll/SceneScroll.css +1 -1
  184. package/dist/components/blocks/scene-scroll/SceneScroll.d.ts +6 -5
  185. package/dist/components/blocks/scene-scroll/SceneScroll.js +8 -7
  186. package/dist/components/blocks/scene-scroll/SceneScroll.types.d.ts +5 -5
  187. package/dist/components/blocks/scene-scroll/SceneScroll.types.js +1 -1
  188. package/dist/components/blocks/scene-scroll/scene-scroll-impl.css +61 -44
  189. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.css +105 -0
  190. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.d.ts +31 -0
  191. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.js +67 -0
  192. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.types.d.ts +39 -0
  193. package/dist/components/blocks/scene-scroll-word/SceneScrollWord.types.js +18 -0
  194. package/dist/components/blocks/scene-scroll-word/scene-scroll-word-impl.css +370 -0
  195. package/dist/components/blocks/stats/Stats.d.ts +2 -1
  196. package/dist/components/blocks/stats/Stats.js +17 -14
  197. package/dist/components/blocks/stats/Stats.types.d.ts +8 -0
  198. package/dist/components/blocks/stats/stats-impl.css +4 -1
  199. package/dist/components/blocks/stats/use-wheel.d.ts +1 -1
  200. package/dist/components/blocks/stats/use-wheel.js +8 -4
  201. package/dist/components/blocks/stats-carousel/StatsCarousel.css +209 -0
  202. package/dist/components/blocks/stats-carousel/StatsCarousel.d.ts +20 -0
  203. package/dist/components/blocks/stats-carousel/StatsCarousel.js +48 -0
  204. package/dist/components/blocks/stats-carousel/StatsCarousel.types.d.ts +43 -0
  205. package/dist/components/blocks/stats-carousel/StatsCarousel.types.js +23 -0
  206. package/dist/components/blocks/stats-carousel/stats-carousel-impl.css +233 -0
  207. package/dist/components/blocks/sticky-cards/sticky-cards-impl.css +8 -0
  208. package/dist/components/blocks/testimonial-row/TestimonialRow.css +1 -1
  209. package/dist/components/blocks/testimonial-row/TestimonialRow.d.ts +2 -1
  210. package/dist/components/blocks/testimonial-row/TestimonialRow.js +16 -13
  211. package/dist/components/blocks/testimonial-row/TestimonialRow.types.d.ts +9 -1
  212. package/dist/components/blocks/testimonial-slider/TestimonialSlider.css +1 -1
  213. package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.d.ts +1 -1
  214. package/dist/components/blocks/tiers/Tiers.types.d.ts +1 -1
  215. package/dist/components/core/background/Background.css +19 -0
  216. package/dist/components/core/background/Background.types.d.ts +2 -1
  217. package/dist/components/core/background/background-impl.css +47 -15
  218. package/dist/components/core/background/halftone.js +1 -1
  219. package/dist/components/core/button/Button.css +5 -5
  220. package/dist/components/core/button-icon/ButtonIcon.types.d.ts +1 -1
  221. package/dist/components/core/card-body/CardBody.css +5 -0
  222. package/dist/components/core/card-body/CardBody.types.d.ts +1 -1
  223. package/dist/components/core/document-link/DocumentLink.css +59 -0
  224. package/dist/components/core/document-link/DocumentLink.d.ts +19 -0
  225. package/dist/components/core/document-link/DocumentLink.js +21 -0
  226. package/dist/components/core/document-link/DocumentLink.types.d.ts +41 -0
  227. package/dist/components/core/document-link/DocumentLink.types.js +11 -0
  228. package/dist/components/core/document-link/document-link-impl.css +23 -0
  229. package/dist/components/core/illustration-card/IllustrationCard.css +7 -0
  230. package/dist/components/core/illustration-card/IllustrationCard.d.ts +5 -1
  231. package/dist/components/core/illustration-card/IllustrationCard.js +34 -8
  232. package/dist/components/core/illustration-card/IllustrationCard.types.d.ts +8 -1
  233. package/dist/components/core/illustration-card/IllustrationCard.types.js +1 -0
  234. package/dist/components/core/illustration-card/illustration-card-impl.css +113 -0
  235. package/dist/components/core/illustration-check/IllustrationCheck.css +25 -0
  236. package/dist/components/core/illustration-check/IllustrationCheck.d.ts +16 -0
  237. package/dist/components/core/illustration-check/IllustrationCheck.js +22 -0
  238. package/dist/components/core/illustration-check/IllustrationCheck.types.d.ts +25 -0
  239. package/dist/components/core/illustration-check/IllustrationCheck.types.js +9 -0
  240. package/dist/components/core/illustration-check/illustration-check-impl.css +76 -0
  241. package/dist/components/core/illustration-choice/IllustrationChoice.css +62 -0
  242. package/dist/components/core/illustration-choice/IllustrationChoice.d.ts +16 -0
  243. package/dist/components/core/illustration-choice/IllustrationChoice.js +31 -0
  244. package/dist/components/core/illustration-choice/IllustrationChoice.types.d.ts +25 -0
  245. package/dist/components/core/illustration-choice/IllustrationChoice.types.js +11 -0
  246. package/dist/components/core/illustration-choice/illustration-choice-impl.css +103 -0
  247. package/dist/components/core/illustration-code/IllustrationCode.css +25 -0
  248. package/dist/components/core/illustration-code/IllustrationCode.d.ts +12 -0
  249. package/dist/components/core/illustration-code/IllustrationCode.js +20 -0
  250. package/dist/components/core/illustration-code/IllustrationCode.types.d.ts +23 -0
  251. package/dist/components/core/illustration-code/IllustrationCode.types.js +8 -0
  252. package/dist/components/core/illustration-code/illustration-code-impl.css +42 -0
  253. package/dist/components/core/illustration-list/IllustrationList.css +19 -0
  254. package/dist/components/core/illustration-list/IllustrationList.d.ts +16 -0
  255. package/dist/components/core/illustration-list/IllustrationList.js +18 -0
  256. package/dist/components/core/illustration-list/IllustrationList.types.d.ts +15 -0
  257. package/dist/components/core/illustration-list/IllustrationList.types.js +6 -0
  258. package/dist/components/core/illustration-list/illustration-list-impl.css +52 -0
  259. package/dist/components/core/illustration-scene/IllustrationScene.css +6 -0
  260. package/dist/components/core/illustration-scene/IllustrationScene.d.ts +3 -2
  261. package/dist/components/core/illustration-scene/IllustrationScene.js +4 -3
  262. package/dist/components/core/illustration-scene/IllustrationScene.types.d.ts +5 -1
  263. package/dist/components/core/illustration-scene/IllustrationScene.types.js +2 -1
  264. package/dist/components/core/illustration-scene/illustration-scene-impl.css +65 -0
  265. package/dist/components/core/link/link-impl.css +5 -19
  266. package/dist/components/core/progress-bar/ProgressBar.css +101 -0
  267. package/dist/components/core/progress-bar/ProgressBar.d.ts +5 -0
  268. package/dist/components/core/progress-bar/ProgressBar.js +34 -0
  269. package/dist/components/core/progress-bar/ProgressBar.types.d.ts +52 -0
  270. package/dist/components/core/progress-bar/ProgressBar.types.js +12 -0
  271. package/dist/components/core/progress-bar/progress-bar-impl.css +45 -0
  272. package/dist/components/core/segmented-control/SegmentedControl.d.ts +1 -1
  273. package/dist/components/core/segmented-control/SegmentedControl.js +13 -5
  274. package/dist/components/core/segmented-control/SegmentedControl.types.d.ts +5 -1
  275. package/dist/components/core/segmented-control/segmented-control-impl.css +35 -0
  276. package/dist/components/core/status-dot/StatusDot.d.ts +1 -1
  277. package/dist/components/core/status-dot/StatusDot.js +7 -4
  278. package/dist/components/core/status-dot/StatusDot.types.d.ts +9 -1
  279. package/dist/components/core/status-dot/status-dot-impl.css +101 -0
  280. package/dist/components/core/typography/Typography.d.ts +3 -283
  281. package/dist/components/core/typography/Typography.js +9 -1
  282. package/dist/components/core/typography/Typography.types.d.ts +9 -15
  283. package/dist/components/core/typography/TypographyMotion.d.ts +28 -0
  284. package/dist/components/core/typography/TypographyMotion.js +43 -0
  285. package/dist/components/core/typography/typography-impl.css +106 -0
  286. package/dist/components/illustration-data.d.ts +15 -0
  287. package/dist/components/illustration-data.js +7 -0
  288. package/dist/components/index.d.ts +22 -1
  289. package/dist/components/index.js +20 -0
  290. package/dist/components/layout/grid/Grid.css +5 -0
  291. package/dist/components/layout/grid/Grid.types.d.ts +2 -1
  292. package/dist/components/scene-scroll-data.d.ts +35 -0
  293. package/dist/components/tiers-data.d.ts +3 -2
  294. package/dist/marketing.css +24 -6
  295. package/package.json +1 -1
@@ -0,0 +1,233 @@
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 header starts on a phone and is centred from the fold, over the card it names — Stats' rule
10
+ * and its reason: a centred line starts at a different edge each time, which costs little across a
11
+ * wide measure and a great deal across a narrow one.
12
+ */
13
+ @container (min-width: 48rem) {
14
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__header {
15
+ align-items: center;
16
+ display: flex;
17
+ flex-direction: column;
18
+ margin-inline: auto;
19
+ text-align: center;
20
+ }
21
+
22
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__description {
23
+ margin-inline: auto;
24
+ }
25
+ }
26
+
27
+ /* A title with nothing under it carries no step under it. */
28
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__title:last-child {
29
+ margin-block-end: 0;
30
+ }
31
+
32
+ /*
33
+ * The card and the awards. Below 62rem the card is over the awards, their two columns side by side
34
+ * under it — the reference's two-up grid. From 62rem the columns stand either side of the card, its
35
+ * own column the card's size. `62rem` longhand because `var()` is not permitted in a container query
36
+ * condition; it is the reference's 992px.
37
+ *
38
+ * The card is square, as wide as size.grid.track-lg and the card's inset either side, or the column
39
+ * it is in where that is narrower. It holds its square whatever the turn inside it needs: the list
40
+ * keeps the room it leaves above and below the figure in place, centred in the card and clipped by it.
41
+ */
42
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__stage {
43
+ --dds-statscarousel-card-size: min(100%, calc(var(--size-grid-track-lg) + 2 * var(--space-inset-xl)));
44
+
45
+ grid-template-areas:
46
+ 'card card'
47
+ 'start end';
48
+ grid-template-columns: repeat(2, minmax(0, 1fr));
49
+ inline-size: 100%;
50
+ }
51
+
52
+ @container (min-width: 62rem) {
53
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__stage {
54
+ grid-template-areas: 'start card end';
55
+ grid-template-columns: minmax(0, 1fr) var(--dds-statscarousel-card-size) minmax(0, 1fr);
56
+ }
57
+ }
58
+
59
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__card {
60
+ aspect-ratio: var(--aspect-square);
61
+ grid-area: card;
62
+ inline-size: var(--dds-statscarousel-card-size);
63
+ min-block-size: 0;
64
+ }
65
+
66
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list {
67
+ inline-size: 100%;
68
+ }
69
+
70
+ /*
71
+ * Still — a reader who asked for less movement, or a single figure — the figures stand two to a row
72
+ * in the card, at font.h4: a square card's width holds two figures, not four, and at the turn's size
73
+ * "168M+" broke over two lines.
74
+ */
75
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list:not([data-wheel]) {
76
+ grid-template-columns: repeat(2, minmax(0, 1fr));
77
+ }
78
+
79
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list:not([data-wheel]) .dds-statscarousel__value {
80
+ font-family: var(--font-h4-family);
81
+ font-size: var(--font-h4-size);
82
+ font-weight: var(--font-h4-weight);
83
+ letter-spacing: var(--font-h4-letter-spacing);
84
+ line-height: var(--font-h4-line-height);
85
+ }
86
+
87
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list:not([data-wheel]) .dds-statscarousel__label {
88
+ font-family: var(--font-body-md-family);
89
+ font-size: var(--font-body-md-size);
90
+ font-weight: var(--font-body-md-weight);
91
+ letter-spacing: var(--font-body-md-letter-spacing);
92
+ line-height: var(--font-body-md-line-height);
93
+ }
94
+
95
+ /*
96
+ * The turn, Stats' phone wheel (stats-impl.css) centred in the card: one figure in place, the one
97
+ * before it smaller above, the next smaller below, turning every motion.duration.hold over
98
+ * motion.duration.turn. useWheel sets `data-wheel` for two figures or more and never for a reader who
99
+ * asked for less movement.
100
+ *
101
+ * Every figure stands in the one cell and is moved off it; a step is a whole figure's height. The side
102
+ * figures stand at --dds-statscarousel-side of their size (0.65), the reference's scale, and fade into
103
+ * the card by a mask rather than an ink of their own, so the turn reads on every ground. The block
104
+ * padding is the room the side figures need above and below.
105
+ */
106
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list[data-wheel] {
107
+ --dds-statscarousel-item: calc(
108
+ var(--font-figure-lg-size) * var(--font-figure-lg-line-height) + var(--space-gap-sm) + var(--font-body-lg-size) *
109
+ var(--font-body-lg-line-height)
110
+ );
111
+ --dds-statscarousel-side: 0.65;
112
+ --dds-statscarousel-away: 0.4;
113
+ --dds-statscarousel-room: 0.85;
114
+ --dds-statscarousel-fade: 35%;
115
+
116
+ grid-template-columns: minmax(0, 1fr);
117
+ mask-image: linear-gradient(
118
+ transparent,
119
+ black var(--dds-statscarousel-fade),
120
+ black calc(100% - var(--dds-statscarousel-fade)),
121
+ transparent
122
+ );
123
+ padding-block: calc(var(--dds-statscarousel-item) * var(--dds-statscarousel-room));
124
+ }
125
+
126
+ /*
127
+ * A tab stop while it turns — focus holds it still — so it shows where focus is, as Stats' wheel
128
+ * does: the ring drawn inside, and the fade gone while it holds focus, since the mask would fade
129
+ * the ring's top and foot with the figures.
130
+ */
131
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list[data-wheel]:focus-visible {
132
+ mask-image: none;
133
+ outline: var(--border-width-focus) solid var(--color-border-focus);
134
+ outline-offset: calc(-1 * var(--border-width-focus));
135
+ }
136
+
137
+ :where([data-dds-context="marketing"]) .dds-statscarousel[data-ground="strong"] .dds-statscarousel__list[data-wheel]:focus-visible {
138
+ outline-color: var(--color-border-focus-on-brand-strong);
139
+ }
140
+
141
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list[data-wheel] > .dds-statscarousel__item {
142
+ grid-area: 1 / 1;
143
+ inline-size: 100%;
144
+ transform-origin: center;
145
+ transition-duration: var(--motion-duration-turn);
146
+ transition-property: opacity, scale, translate;
147
+ transition-timing-function: var(--motion-easing-reveal);
148
+ }
149
+
150
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list[data-wheel] > [data-slot='above'] {
151
+ scale: var(--dds-statscarousel-side);
152
+ translate: 0 -100%;
153
+ }
154
+
155
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list[data-wheel] > [data-slot='below'] {
156
+ animation: dds-statscarousel-in var(--motion-duration-turn) var(--motion-easing-reveal);
157
+ scale: var(--dds-statscarousel-side);
158
+ translate: 0 100%;
159
+ }
160
+
161
+ /*
162
+ * Out of sight, a figure waits where the one above leaves to — risen and shrunk away — so leaving is
163
+ * a movement on, never back; it comes in below by an arrival of its own.
164
+ */
165
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list[data-wheel] > [data-slot='hidden'] {
166
+ opacity: var(--opacity-hidden);
167
+ scale: var(--dds-statscarousel-away);
168
+ translate: 0 -100%;
169
+ }
170
+
171
+ @keyframes dds-statscarousel-in {
172
+ from {
173
+ opacity: var(--opacity-hidden);
174
+ scale: var(--dds-statscarousel-away);
175
+ translate: 0 200%;
176
+ }
177
+ }
178
+
179
+ @media (prefers-reduced-motion: reduce) {
180
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__list[data-wheel] > .dds-statscarousel__item {
181
+ animation: none;
182
+ transition: none;
183
+ }
184
+ }
185
+
186
+ /*
187
+ * The award columns. Each fills its side of the stage — centred, as the stage centres its items, a
188
+ * column shrank to its words — with its badges centred below 62rem and leaning toward the card from
189
+ * there, as the reference's do.
190
+ */
191
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__awards {
192
+ justify-self: stretch;
193
+ }
194
+
195
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__awards[data-side="start"] {
196
+ grid-area: start;
197
+ }
198
+
199
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__awards[data-side="end"] {
200
+ grid-area: end;
201
+ }
202
+
203
+ @container (min-width: 62rem) {
204
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__awards[data-side="start"] {
205
+ align-items: flex-end;
206
+ }
207
+
208
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__awards[data-side="end"] {
209
+ align-items: flex-start;
210
+ }
211
+ }
212
+
213
+ /* The badges, as the Awards block draws them (awards-impl.css), each its column's width up to theirs. */
214
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__award {
215
+ inline-size: 100%;
216
+ }
217
+
218
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__award-laurel {
219
+ block-size: auto;
220
+ }
221
+
222
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__award-copy {
223
+ flex: 1 1 0;
224
+ }
225
+
226
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__award-laurel[data-side="trailing"],
227
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__award-laurel[data-side="leading"]:dir(rtl) {
228
+ scale: -1 1;
229
+ }
230
+
231
+ :where([data-dds-context="marketing"]) .dds-statscarousel .dds-statscarousel__award-laurel[data-side="trailing"]:dir(rtl) {
232
+ scale: none;
233
+ }
@@ -73,6 +73,13 @@
73
73
  background-color: var(--color-bg-surface-card-strong-raised);
74
74
  }
75
75
 
76
+ :where([data-dds-context="marketing"])
77
+ .dds-stickycards[data-ground="strong"]
78
+ .dds-stickycards__item
79
+ > .dds-card[data-variant="accent-strong"] {
80
+ background-color: var(--color-bg-surface-card-strong-on-brand-strong);
81
+ }
82
+
76
83
  /*
77
84
  * ── compact ──────────────────────────────────────────────────────────────────────────────────
78
85
  *
@@ -140,6 +147,7 @@
140
147
  :where([data-dds-context="marketing"]) .dds-stickycards .dds-card[data-variant="accent"] { --dds-stickycards-fill: var(--color-bg-brand); }
141
148
  :where([data-dds-context="marketing"]) .dds-stickycards .dds-card[data-variant="surface-light"] { --dds-stickycards-fill: var(--color-bg-surface-card-light); }
142
149
  :where([data-dds-context="marketing"]) .dds-stickycards[data-ground="subtle"] .dds-card[data-variant="accent-strong"] { --dds-stickycards-fill: var(--color-bg-surface-card-strong-raised); }
150
+ :where([data-dds-context="marketing"]) .dds-stickycards[data-ground="strong"] .dds-card[data-variant="accent-strong"] { --dds-stickycards-fill: var(--color-bg-surface-card-strong-on-brand-strong); }
143
151
  :where([data-dds-context="marketing"]) .dds-stickycards[data-ground="subtle"] .dds-card[data-variant="surface-light"] { --dds-stickycards-fill: var(--color-bg-surface-card-light-raised); }
144
152
 
145
153
  :where([data-dds-context="marketing"]) .dds-stickycards .dds-stickycards__body {
@@ -213,7 +213,7 @@
213
213
  }
214
214
 
215
215
  :where([data-dds-context="marketing"]) .dds-testimonialrow[data-ground="strong"] .dds-testimonialrow__item {
216
- background-color: var(--color-bg-surface-card-strong);
216
+ background-color: var(--color-bg-surface-card-strong-on-brand-strong);
217
217
  color: var(--color-fg-on-brand-strong);
218
218
  }
219
219
 
@@ -1,6 +1,7 @@
1
1
  import "./TestimonialRow.css";
2
2
  import "./testimonial-row-impl.css";
3
3
  import "../block-reveal.css";
4
+ import "../block-pattern.css";
4
5
  import { type TestimonialRowProps } from "./TestimonialRow.types.js";
5
6
  export type { TestimonialRowProps };
6
7
  /**
@@ -17,4 +18,4 @@ export type { TestimonialRowProps };
17
18
  * `'use client'` for the row's scroll position, the arrival, and `useId`, which names the region
18
19
  * by its heading.
19
20
  */
20
- export declare function TestimonialRow({ ground, title, reviews, summary, ratingLabel, label, externalLabel, previousLabel, nextLabel, }: TestimonialRowProps): import("react").JSX.Element | null;
21
+ export declare function TestimonialRow({ ground, background, title, reviews, summary, ratingLabel, label, externalLabel, previousLabel, nextLabel, }: TestimonialRowProps): import("react").JSX.Element | null;
@@ -5,11 +5,14 @@ import { ChevronLeftRegularIcon, ChevronRightRegularIcon, StarSolidIcon } from "
5
5
  import "./TestimonialRow.css";
6
6
  import "./testimonial-row-impl.css";
7
7
  import "../block-reveal.css";
8
+ import "../block-pattern.css";
8
9
  import { given } from "../../given.js";
9
10
  import { ButtonIcon } from "../../core/button-icon/ButtonIcon.js";
10
11
  import { Link } from "../../core/link/Link.js";
11
12
  import { visuallyHidden } from "../../visually-hidden.js";
12
13
  import { arriving, useReveal } from "../use-reveal.js";
14
+ import { Background } from "../../core/background/Background.js";
15
+ import { PATTERN_TONE } from "../pattern-tone.js";
13
16
  import { testimonialRowDefaults, testimonialRowParts, } from "./TestimonialRow.types.js";
14
17
  /**
15
18
  * Five stars, filled to a score out of five.
@@ -46,7 +49,7 @@ const AT_END = 2;
46
49
  * `'use client'` for the row's scroll position, the arrival, and `useId`, which names the region
47
50
  * by its heading.
48
51
  */
49
- export function TestimonialRow({ ground = testimonialRowDefaults.ground, title, reviews, summary, ratingLabel, label = testimonialRowDefaults.label, externalLabel = testimonialRowDefaults.externalLabel, previousLabel = testimonialRowDefaults.previousLabel, nextLabel = testimonialRowDefaults.nextLabel, }) {
52
+ export function TestimonialRow({ ground = testimonialRowDefaults.ground, background, title, reviews, summary, ratingLabel, label = testimonialRowDefaults.label, externalLabel = testimonialRowDefaults.externalLabel, previousLabel = testimonialRowDefaults.previousLabel, nextLabel = testimonialRowDefaults.nextLabel, }) {
50
53
  const titleId = useId();
51
54
  const [band, revealed] = useReveal();
52
55
  const row = useRef(null);
@@ -114,16 +117,16 @@ export function TestimonialRow({ ground = testimonialRowDefaults.ground, title,
114
117
  const scrolls = ends.back || ends.on;
115
118
  // Button's secondary, as a circle; on the dark band its inverse tone turns the tint white.
116
119
  const arrow = { variant: "secondary", tone: ground === "strong" ? "inverse" : "default" };
117
- return (_jsx("section", { className: testimonialRowParts.root, "data-ground": ground, "aria-labelledby": titleId, children: _jsxs("div", { className: testimonialRowParts.inner, ref: band, "data-revealed": revealed, children: [_jsxs("div", { className: testimonialRowParts.header, children: [_jsx("h2", { className: testimonialRowParts.title, id: titleId, ...arriving(0), children: title }), summary === undefined ? null : (_jsx("p", { className: testimonialRowParts.summary, ...arriving(1), children: summary.href !== undefined && given(summary.href) ? (
118
- // A link on its own line, so the standalone one: brand ink and a mark. On the dark
119
- // band it takes the band's ink, where coral is the wrong colour for words.
120
- _jsxs(Link, { variant: "standalone", tone: ground === "strong" ? "inherit" : "brand", external: true, href: summary.href, children: [summary.label, _jsx("span", { style: visuallyHidden, children: ` ${externalLabel}` })] })) : (_jsx("span", { children: summary.label })) }))] }), _jsxs("div", { className: testimonialRowParts.carousel, children: [_jsx("div", { ref: row, className: testimonialRowParts.track, role: "group", "aria-label": label, tabIndex: 0, onScroll: read, ...arriving(2), children: reviews.map((each, at) => {
121
- // A review's position is its identity: the set is a list, and nothing reorders it.
122
- const card = (_jsxs("figure", { className: testimonialRowParts.item, children: [each.rating === undefined ? null : (
123
- // Named by the score it is drawn at, so a 4.3 is heard as the 4.5 a reader
124
- // sees rather than as a number the stars do not show.
125
- _jsx(Rating, { score: each.rating, label: ratingLabel?.(toHalves(each.rating)) ?? `Rated ${toHalves(each.rating)} out of 5` })), _jsx("blockquote", { className: testimonialRowParts.quote, children: each.quote }), _jsx("figcaption", { className: testimonialRowParts.author, children: _jsxs("span", { children: [_jsx("span", { className: testimonialRowParts.name, children: each.name }), given(each.detail) ? (_jsx("span", { className: testimonialRowParts.detail, children: each.detail })) : null] }) })] }, at));
126
- // The review is on a service the page does not own, so it opens beside the page.
127
- return given(each.href) ? (_jsxs("a", { className: testimonialRowParts["review-link"], href: each.href, target: "_blank", rel: "noopener noreferrer", children: [card, _jsx("span", { style: visuallyHidden, children: ` ${externalLabel}` })] }, at)) : (card);
128
- }) }), reviews.length > 1 ? (_jsx("div", { className: testimonialRowParts.footer, ...arriving(3), children: _jsxs("div", { className: testimonialRowParts.nav, hidden: !scrolls, children: [_jsx("span", { ref: back, className: testimonialRowParts["nav-slot"], "data-available": ends.back, inert: !ends.back, children: _jsx(ButtonIcon, { icon: _jsx(ChevronLeftRegularIcon, {}), label: previousLabel, ...arrow, onClick: () => step(-1) }) }), _jsx("span", { ref: on, className: testimonialRowParts["nav-slot"], "data-available": ends.on, inert: !ends.on, children: _jsx(ButtonIcon, { icon: _jsx(ChevronRightRegularIcon, {}), label: nextLabel, ...arrow, onClick: () => step(1) }) })] }) })) : null] })] }) }));
120
+ return (_jsxs("section", { className: testimonialRowParts.root, "data-ground": ground, "data-background": background, "aria-labelledby": titleId, children: [background ? _jsx(Background, { tone: PATTERN_TONE[ground], pattern: background, children: null }) : null, _jsxs("div", { className: testimonialRowParts.inner, ref: band, "data-revealed": revealed, children: [_jsxs("div", { className: testimonialRowParts.header, children: [_jsx("h2", { className: testimonialRowParts.title, id: titleId, ...arriving(0), children: title }), summary === undefined ? null : (_jsx("p", { className: testimonialRowParts.summary, ...arriving(1), children: summary.href !== undefined && given(summary.href) ? (
121
+ // A link on its own line, so the standalone one: brand ink and a mark. On the dark
122
+ // band it takes the band's ink, where coral is the wrong colour for words.
123
+ _jsxs(Link, { variant: "standalone", tone: ground === "strong" ? "inherit" : "brand", external: true, href: summary.href, children: [summary.label, _jsx("span", { style: visuallyHidden, children: ` ${externalLabel}` })] })) : (_jsx("span", { children: summary.label })) }))] }), _jsxs("div", { className: testimonialRowParts.carousel, children: [_jsx("div", { ref: row, className: testimonialRowParts.track, role: "group", "aria-label": label, tabIndex: 0, onScroll: read, ...arriving(2), children: reviews.map((each, at) => {
124
+ // A review's position is its identity: the set is a list, and nothing reorders it.
125
+ const card = (_jsxs("figure", { className: testimonialRowParts.item, children: [each.rating === undefined ? null : (
126
+ // Named by the score it is drawn at, so a 4.3 is heard as the 4.5 a reader
127
+ // sees rather than as a number the stars do not show.
128
+ _jsx(Rating, { score: each.rating, label: ratingLabel?.(toHalves(each.rating)) ?? `Rated ${toHalves(each.rating)} out of 5` })), _jsx("blockquote", { className: testimonialRowParts.quote, children: each.quote }), _jsx("figcaption", { className: testimonialRowParts.author, children: _jsxs("span", { children: [_jsx("span", { className: testimonialRowParts.name, children: each.name }), given(each.detail) ? (_jsx("span", { className: testimonialRowParts.detail, children: each.detail })) : null] }) })] }, at));
129
+ // The review is on a service the page does not own, so it opens beside the page.
130
+ return given(each.href) ? (_jsxs("a", { className: testimonialRowParts["review-link"], href: each.href, target: "_blank", rel: "noopener noreferrer", children: [card, _jsx("span", { style: visuallyHidden, children: ` ${externalLabel}` })] }, at)) : (card);
131
+ }) }), reviews.length > 1 ? (_jsx("div", { className: testimonialRowParts.footer, ...arriving(3), children: _jsxs("div", { className: testimonialRowParts.nav, hidden: !scrolls, children: [_jsx("span", { ref: back, className: testimonialRowParts["nav-slot"], "data-available": ends.back, inert: !ends.back, children: _jsx(ButtonIcon, { icon: _jsx(ChevronLeftRegularIcon, {}), label: previousLabel, ...arrow, onClick: () => step(-1) }) }), _jsx("span", { ref: on, className: testimonialRowParts["nav-slot"], "data-available": ends.on, inert: !ends.on, children: _jsx(ButtonIcon, { icon: _jsx(ChevronRightRegularIcon, {}), label: nextLabel, ...arrow, onClick: () => step(1) }) })] }) })) : null] })] })] }));
129
132
  }
@@ -3,9 +3,17 @@ export interface TestimonialRowOwnProps {
3
3
  /**
4
4
  * `page` — The default, and the page's own white. The cards are the recessed gray that sets them off
5
5
  * `subtle` — The grey band, the reference design's ground for this section. The cards turn white on it. Painted as the band's tint laid over the page's own ground, so it is the same grey whatever is behind the section
6
- * `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading, the summary and the cards' words turn white, and the cards take color.bg.surface-card-strong — gray.900 in both themes, the colour a page card takes in dark mode — so the band reads as a dark-mode section in either theme. The arrows take ButtonIcon's inverse tone
6
+ * `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading, the summary and the cards' words turn white, and the cards take color.bg.surface-card-strong-on-brand-strong — slate.850 in light and slate.900 in dark, a step above the band in both, a step lighter than the band — so the band reads as a dark-mode section in either theme. The arrows take ButtonIcon's inverse tone
7
7
  */
8
8
  ground?: 'page' | 'subtle' | 'strong';
9
+ /**
10
+ * `halftone` — A field of coral dots that grow towards a soft glow at the band's foot and settle to a fine screen away from it.
11
+ * `aurora` — Curtains of the brand's light rising from the band's foot and swaying slowly.
12
+ * `mesh` — The band in the brand's reds folded into one another like a liquid — the loudest of the five, for a dark band.
13
+ * `grid` — Hairlines a pitch apart rising from a soft bloom at the band's foot — the quietest, and the one to reach for first.
14
+ * `rings` — Hairline circles spreading out from the middle of the band's foot.
15
+ */
16
+ background?: 'halftone' | 'aurora' | 'mesh' | 'grid' | 'rings';
9
17
  /** Always. Whose reviews these are, in a few words — "What our customers say". */
10
18
  title: string;
11
19
  /** 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. */
@@ -157,7 +157,7 @@
157
157
  }
158
158
 
159
159
  :where([data-dds-context="marketing"]) .dds-testimonialslider[data-ground="strong"] .dds-testimonialslider__item {
160
- background-color: var(--color-bg-surface-card-strong);
160
+ background-color: var(--color-bg-surface-card-strong-on-brand-strong);
161
161
  color: var(--color-fg-on-brand-strong);
162
162
  }
163
163
 
@@ -3,7 +3,7 @@ export interface TestimonialSliderOwnProps {
3
3
  /**
4
4
  * `page` — The default, and the page's own white. The card is the recessed gray that sets it off
5
5
  * `subtle` — The grey band, the reference design's ground for this section. The card turns white on it. Painted as the band's tint laid over the page's own ground, so it is the same grey whatever is behind the section
6
- * `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading and the quote turn white and the card takes color.bg.surface-card-strong — gray.900 in both themes, the colour a page card takes in dark mode, and TestimonialRow's card on the same band — so the band reads as a dark-mode section in either theme. The coral dots sit on it
6
+ * `strong` — `color.bg.brand-strong`, the dark band, for a section a reader should arrive at. The heading and the quote turn white and the card takes color.bg.surface-card-strong-on-brand-strong — slate.850 in light and slate.900 in dark, a step above the band in both, a step lighter than the band, and TestimonialRow's card on the same band — so the band reads as a dark-mode section in either theme. The coral dots sit on it
7
7
  */
8
8
  ground?: 'page' | 'subtle' | 'strong';
9
9
  /** Always. Whose words these are, in a few — "What our partners say", "What our customers say". */
@@ -11,7 +11,7 @@ export interface TiersOwnProps {
11
11
  title: string;
12
12
  /** A line saying how the tiers work, when the title alone does not — 'Our tiered partnership model rewards performance.' */
13
13
  description?: string;
14
- /** Always. The tiers, lowest first — two to four, four for a partnership programme. Each is a one-word `name`, a one-verb `stage`, a `medal` picture, a `benefit` headline and the sentence under it, and — on every tier above the entry one — the `qualification` that reaches it, with a line break before the amount. The order of the list is the order of the ladder, so reordering it reorders the tiers. */
14
+ /** Always. The tiers, lowest first — two to four, four for a partnership programme. Each is a one-word `name`, a one-verb `stage`, a `medal` picture, a `benefit` headline and the sentence under it, and the `qualification` that reaches it, with a line break before the amount — the entry tier's too, saying what it takes to join, so every tier's card has the same line under it. The order of the list is the order of the ladder, so reordering it reorders the tiers. */
15
15
  tiers: TiersItem[];
16
16
  /** A way on to the programme's full terms — 'Learn more about partner tiers'. A standalone Link, under the row. */
17
17
  link?: ReactNode;
@@ -85,6 +85,25 @@
85
85
  background-color: var(--color-bg-page);
86
86
  }
87
87
 
88
+ :where([data-dds-context="marketing"]) .dds-background[data-tone="subtle"] {
89
+ background-color: var(--color-bg-page);
90
+ background-image: linear-gradient(var(--color-bg-band-subtle), var(--color-bg-band-subtle));
91
+ }
92
+
93
+ :where([data-dds-context="marketing"]) .dds-background[data-tone="subtle"] .dds-background__canvas {
94
+ color: var(--color-bg-brand);
95
+ outline-color: var(--color-bg-brand);
96
+ }
97
+
98
+ :where([data-dds-context="marketing"]) .dds-background[data-tone="subtle"] .dds-background__content {
99
+ color: var(--color-fg-default);
100
+ }
101
+
102
+ :where([data-dds-context="marketing"]) .dds-background[data-tone="subtle"] .dds-background__mesh {
103
+ background-color: var(--color-bg-page);
104
+ background-image: linear-gradient(var(--color-bg-band-subtle), var(--color-bg-band-subtle));
105
+ }
106
+
88
107
  @media (prefers-reduced-motion: reduce) {
89
108
  :where([data-dds-context="marketing"]) .dds-background,
90
109
  :where([data-dds-context="marketing"]) .dds-background * { transition: none !important; }
@@ -3,9 +3,10 @@ export interface BackgroundOwnProps {
3
3
  /**
4
4
  * `dark` — The band the halftone was drawn for: coral dots glowing on color.bg.brand-strong, which is dark in both modes. Reach for it for the band a page opens or closes on, where the glow gives the band a centre
5
5
  * `light` — Coral dots on the page's own ground, for a light page that wants one moment of brand colour without a solid coral band. The glow reads as warmth rather than light, so keep it for a section that is not competing with a dark one nearby
6
+ * `subtle` — The light pattern on the subtle band's grey — color.bg.band-subtle laid over the page, the grey a block's `ground="subtle"` paints — for a block that carries a pattern on that ground. The same coral as the light tone; only the ground under it is the band's grey rather than the page's white.
6
7
  * `brand` — The default: the brand's own coral, the ground the mesh was made for and the one a call to action stands on. White dots on it for the halftone. The heading is white too, and the glow rises from the foot of the band towards it, so check the words read on the coral alone — the pattern can only add to what is behind them
7
8
  */
8
- tone?: 'dark' | 'light' | 'brand';
9
+ tone?: 'dark' | 'light' | 'subtle' | 'brand';
9
10
  /**
10
11
  * `halftone` — A grid of dots across the whole band that grow towards a soft glow and settle to a fine screen away from it, over a faint wash of their own ink. The glow's edge wanders from a plain ellipse as it drifts, so it reads as light on a surface rather than a spotlight. The default, and the one that moves most
11
12
  * `aurora` — Curtains of light rising from the band's foot: sheets of the brand's colour swaying and folding, with a ragged crest and fine rays running up through them — light falling through folds rather than pools of colour. Drawn by a shader with a grain over it; before it has drawn, and where it cannot, soft pools of the same colour painted by the stylesheet. At rest the curtains sway over motion.duration.drift; on an interactive band the pointer bends them towards it and brightens them. Reach for it where the halftone would be too busy — an opening band with a picture or a product on it, where dots behind the picture fight it and a wash of light does not
@@ -33,6 +33,29 @@
33
33
  position: relative;
34
34
  }
35
35
 
36
+ /*
37
+ * The ground a light pattern is drawn on, as one solid colour: the page's own on the light tone, and
38
+ * the subtle band's grey on the subtle tone, so a block on its grey band can carry a pattern without
39
+ * the band turning white under it.
40
+ *
41
+ * The patterns are drawn by shaders that take their ground as one opaque colour, and the subtle band
42
+ * is a tint laid over the page — gray.50 in light mode, which is already solid, and white at six over
43
+ * the near-black page in dark mode, which is not. So in dark mode the grey is mixed out solid: the
44
+ * band's white at its own six percent into the page, which is the colour the tint comes to.
45
+ */
46
+ :where([data-dds-context="marketing"]) .dds-background[data-tone='light'] {
47
+ --dds-background-ground: var(--color-bg-page);
48
+ }
49
+
50
+ :where([data-dds-context="marketing"]) .dds-background[data-tone='subtle'] {
51
+ --dds-background-ground: var(--color-bg-band-subtle);
52
+ }
53
+
54
+ :where([data-theme='dark']) :where([data-dds-context="marketing"]) .dds-background[data-tone='subtle'],
55
+ :where([data-dds-context="marketing"][data-theme='dark']) .dds-background[data-tone='subtle'] {
56
+ --dds-background-ground: color-mix(in srgb, var(--color-fg-on-brand-strong) 6%, var(--color-bg-page));
57
+ }
58
+
36
59
  /*
37
60
  * A Background with nothing to hold is a layer: it fills the band it is placed in, behind that
38
61
  * band's own content, which is how a block draws the pattern under itself without its layout
@@ -85,9 +108,9 @@
85
108
  * and the aurora's pools are there: a third of color.bg.brand, about as strong as the grey it
86
109
  * replaces, so the grid stays quiet but reads as the brand's. It lights up to the full coral.
87
110
  */
88
- :where([data-dds-context="marketing"]) .dds-background:is([data-pattern='grid'], [data-pattern='rings'])[data-tone='light'] {
111
+ :where([data-dds-context="marketing"]) .dds-background:is([data-pattern='grid'], [data-pattern='rings']):is([data-tone='light'], [data-tone='subtle']) {
89
112
  --dds-background-rule: color-mix(in srgb, var(--color-bg-brand) 35%, transparent);
90
- --dds-background-fade: var(--color-bg-page);
113
+ --dds-background-fade: var(--dds-background-ground);
91
114
  }
92
115
 
93
116
  /*
@@ -130,6 +153,15 @@
130
153
  left calc(var(--dds-background-shift, 0%) * -1);
131
154
  }
132
155
 
156
+ /*
157
+ * On the subtle tone the band's tint is the root's background-image, which the grid's and the
158
+ * rings' own images replace — so the band would fall to the page's white under them, in the frame
159
+ * before the shader draws or wherever it cannot. The ground goes under them as a colour instead.
160
+ */
161
+ :where([data-dds-context="marketing"]) .dds-background[data-tone='subtle']:is([data-pattern='grid'], [data-pattern='rings']) {
162
+ background-color: var(--dds-background-ground);
163
+ }
164
+
133
165
  /*
134
166
  * The rings: circles at size.rings.pitch, centred on the middle of the band's foot, so they spread
135
167
  * up and out from where the halftone's glow would rest.
@@ -220,7 +252,7 @@
220
252
  background-image: var(--dds-background-rings);
221
253
  }
222
254
 
223
- :where([data-dds-context="marketing"]) .dds-background:is([data-pattern='grid'], [data-pattern='rings'])[data-tone='light']::before {
255
+ :where([data-dds-context="marketing"]) .dds-background:is([data-pattern='grid'], [data-pattern='rings']):is([data-tone='light'], [data-tone='subtle'])::before {
224
256
  --dds-background-lit: var(--color-bg-brand);
225
257
  }
226
258
 
@@ -266,7 +298,7 @@
266
298
  --dds-background-hover: 0.25;
267
299
  }
268
300
 
269
- :where([data-dds-context="marketing"]) .dds-background[data-pattern='aurora'][data-tone='light'] {
301
+ :where([data-dds-context="marketing"]) .dds-background[data-pattern='aurora']:is([data-tone='light'], [data-tone='subtle']) {
270
302
  --dds-background-pool-deep: var(--color-bg-brand-hover);
271
303
  --dds-background-strength: 0.22;
272
304
  --dds-background-hover: 0.3;
@@ -475,7 +507,7 @@
475
507
  --dds-background-mesh-strength: 0.6;
476
508
  }
477
509
 
478
- :where([data-dds-context="marketing"]) .dds-background[data-tone='light'] .dds-background__mesh {
510
+ :where([data-dds-context="marketing"]) .dds-background:is([data-tone='light'], [data-tone='subtle']) .dds-background__mesh {
479
511
  --dds-background-mesh-1: var(--color-bg-brand-subtle);
480
512
  --dds-background-mesh-2: var(--color-bg-brand);
481
513
  --dds-background-mesh-3: var(--color-bg-brand-subtle);
@@ -620,7 +652,7 @@
620
652
  --dds-background-gl-grain: 0.05;
621
653
  }
622
654
 
623
- :where([data-dds-context="marketing"]) .dds-background[data-tone='light'] {
655
+ :where([data-dds-context="marketing"]) .dds-background:is([data-tone='light'], [data-tone='subtle']) {
624
656
  --dds-background-gl-grain: 0.025;
625
657
  }
626
658
 
@@ -654,11 +686,11 @@
654
686
  --dds-background-gl-strength: 0.85;
655
687
  }
656
688
 
657
- :where([data-dds-context="marketing"]) .dds-background[data-pattern='aurora'][data-tone='light'] {
658
- --dds-background-gl-ink0: var(--color-bg-page);
689
+ :where([data-dds-context="marketing"]) .dds-background[data-pattern='aurora']:is([data-tone='light'], [data-tone='subtle']) {
690
+ --dds-background-gl-ink0: var(--dds-background-ground);
659
691
  --dds-background-gl-ink1: var(--color-bg-brand);
660
692
  --dds-background-gl-ink2: var(--color-bg-brand-hover);
661
- --dds-background-gl-ink3: color-mix(in srgb, var(--color-bg-brand) 50%, var(--color-bg-page));
693
+ --dds-background-gl-ink3: color-mix(in srgb, var(--color-bg-brand) 50%, var(--dds-background-ground));
662
694
  --dds-background-gl-strength: 0.35;
663
695
  }
664
696
 
@@ -689,8 +721,8 @@
689
721
  --dds-background-gl-strength: 0.35;
690
722
  }
691
723
 
692
- :where([data-dds-context="marketing"]) .dds-background[data-pattern='mesh'][data-tone='light'] {
693
- --dds-background-gl-ink0: var(--color-bg-page);
724
+ :where([data-dds-context="marketing"]) .dds-background[data-pattern='mesh']:is([data-tone='light'], [data-tone='subtle']) {
725
+ --dds-background-gl-ink0: var(--dds-background-ground);
694
726
  --dds-background-gl-ink1: var(--color-bg-brand-subtle);
695
727
  --dds-background-gl-ink2: var(--color-bg-brand);
696
728
  --dds-background-gl-ink3: var(--color-bg-brand-subtle);
@@ -730,11 +762,11 @@
730
762
  --dds-background-gl-ink3: var(--color-bg-brand-deep);
731
763
  }
732
764
 
733
- :where([data-dds-context="marketing"]) .dds-background:is([data-pattern='grid'], [data-pattern='rings'])[data-tone='light'] {
734
- --dds-background-gl-ink0: var(--color-bg-page);
735
- --dds-background-gl-ink1: color-mix(in srgb, var(--color-bg-brand) 28%, var(--color-bg-page));
765
+ :where([data-dds-context="marketing"]) .dds-background:is([data-pattern='grid'], [data-pattern='rings']):is([data-tone='light'], [data-tone='subtle']) {
766
+ --dds-background-gl-ink0: var(--dds-background-ground);
767
+ --dds-background-gl-ink1: color-mix(in srgb, var(--color-bg-brand) 28%, var(--dds-background-ground));
736
768
  --dds-background-gl-ink2: var(--color-bg-brand);
737
- --dds-background-gl-ink3: color-mix(in srgb, var(--color-bg-brand) 12%, var(--color-bg-page));
769
+ --dds-background-gl-ink3: color-mix(in srgb, var(--color-bg-brand) 12%, var(--dds-background-ground));
738
770
  }
739
771
 
740
772
  /*
@@ -37,7 +37,7 @@
37
37
  * the glow's heart outshone the words standing on it. The light and the coral grounds keep most of
38
38
  * theirs, where the dots are closer to the ground they sit on.
39
39
  */
40
- const OPACITY = { dark: 0.55, light: 0.85, brand: 0.85 };
40
+ const OPACITY = { dark: 0.55, light: 0.85, subtle: 0.85, brand: 0.85 };
41
41
  const SETTINGS = {
42
42
  // A third opaque at the faintest: the edge of the glow is a dim field of dots rather than a
43
43
  // fade to nothing, so the pattern reaches the band's edges without competing with its heart.
@@ -136,16 +136,16 @@
136
136
  }
137
137
 
138
138
  :where([data-dds-context="marketing"]) .dds-button[data-variant="secondary"][data-tone="brand"] {
139
- background-color: var(--color-bg-subtle-on-brand-strong);
139
+ border-color: var(--color-border-strong-inverse);
140
140
  color: var(--color-fg-on-brand-strong);
141
141
  }
142
142
 
143
143
  :where([data-dds-context="marketing"]) .dds-button[data-variant="secondary"][data-tone="default"] {
144
- background-color: var(--color-bg-subtle);
144
+ border-color: var(--color-border-strong);
145
145
  }
146
146
 
147
147
  :where([data-dds-context="marketing"]) .dds-button[data-variant="secondary"][data-tone="inverse"] {
148
- background-color: var(--color-bg-subtle-on-brand-strong);
148
+ border-color: var(--color-border-strong-inverse);
149
149
  color: var(--color-fg-on-brand-strong);
150
150
  }
151
151
 
@@ -158,7 +158,7 @@
158
158
  }
159
159
 
160
160
  :where([data-dds-context="marketing"]) .dds-button[data-variant="secondary"][data-tone="default"]:hover:where(:not(:disabled)) {
161
- background-image: linear-gradient(var(--color-bg-hover), var(--color-bg-hover));
161
+ background-color: var(--color-bg-hover);
162
162
  }
163
163
 
164
164
  :where([data-dds-context="marketing"]) .dds-button[data-variant="secondary"][data-tone="inverse"]:hover:where(:not(:disabled)) {
@@ -174,7 +174,7 @@
174
174
  }
175
175
 
176
176
  :where([data-dds-context="marketing"]) .dds-button[data-variant="secondary"][data-tone="default"]:active {
177
- background-image: linear-gradient(var(--color-bg-active), var(--color-bg-active));
177
+ background-color: var(--color-bg-active);
178
178
  }
179
179
 
180
180
  :where([data-dds-context="marketing"]) .dds-button[data-variant="secondary"][data-tone="inverse"]:active {
@@ -15,7 +15,7 @@ export interface ButtonIconOwnProps {
15
15
  size?: 'sm' | 'md' | 'lg';
16
16
  /**
17
17
  * `default` — The control is on a light ground, which is every surface this package paints by default
18
- * `inverse` — The control stands on the dark band, color.bg.brand-strong — a mark in a navigation bar on a hero, a social mark in a footer — which is the same near-black in light and dark. The ink and the tints move to the band's fixed roles; nothing else does
18
+ * `inverse` — The control stands on the dark band, color.bg.brand-strong — a mark in a navigation bar on a hero, a social mark in a footer — which is near-black in light and dark alike — slate.900 in light, a step deeper in dark. The ink and the tints move to the band's fixed roles; nothing else does
19
19
  */
20
20
  tone?: 'default' | 'inverse';
21
21
  /** Always — the glyph is the whole control, so it is required rather than a slot that may be empty. Pass the glyph itself, from the icon package, rather than one already sized: the size a mark takes in this circle is this component's decision, at icon.control.md on md and icon.control.lg on lg, and the width and height the glyph shipped with are overridden by the class this component clones onto it. */