@deriv-com/dds-marketing 0.1.0 → 0.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 (460) hide show
  1. package/.llm/components/accordion.md +193 -0
  2. package/.llm/components/accordionitem.md +236 -0
  3. package/.llm/components/aspectratio.md +212 -0
  4. package/.llm/components/badge.md +231 -0
  5. package/.llm/components/bottomsheet.md +404 -0
  6. package/.llm/components/breadcrumb.md +197 -0
  7. package/.llm/components/breadcrumbitem.md +178 -0
  8. package/.llm/components/button.md +271 -0
  9. package/.llm/components/buttonicon.md +313 -0
  10. package/.llm/components/card.md +313 -0
  11. package/.llm/components/cardbody.md +409 -0
  12. package/.llm/components/cardbutton.md +259 -0
  13. package/.llm/components/checkbox.md +285 -0
  14. package/.llm/components/divider.md +230 -0
  15. package/.llm/components/dropdownmenu.md +453 -0
  16. package/.llm/components/filterchip.md +314 -0
  17. package/.llm/components/footer.md +408 -0
  18. package/.llm/components/footergroup.md +241 -0
  19. package/.llm/components/grid.md +659 -0
  20. package/.llm/components/icon.md +194 -0
  21. package/.llm/components/link.md +354 -0
  22. package/.llm/components/menuitem.md +218 -0
  23. package/.llm/components/navbar.md +458 -0
  24. package/.llm/components/navbaritem.md +238 -0
  25. package/.llm/components/navbarmenu.md +319 -0
  26. package/.llm/components/navbarmenugroup.md +184 -0
  27. package/.llm/components/navbarpanel.md +255 -0
  28. package/.llm/components/navbarswitcher.md +343 -0
  29. package/.llm/components/navbarswitcheroption.md +156 -0
  30. package/.llm/components/option.md +268 -0
  31. package/.llm/components/pagination.md +361 -0
  32. package/.llm/components/removablechip.md +247 -0
  33. package/.llm/components/row.md +381 -0
  34. package/.llm/components/scroller.md +470 -0
  35. package/.llm/components/searchinput.md +279 -0
  36. package/.llm/components/segmentedcontrol.md +358 -0
  37. package/.llm/components/segmentedcontrolitem.md +272 -0
  38. package/.llm/components/select.md +509 -0
  39. package/.llm/components/selectchip.md +334 -0
  40. package/.llm/components/spinner.md +222 -0
  41. package/.llm/components/stack.md +334 -0
  42. package/.llm/components/statusdot.md +205 -0
  43. package/.llm/components/subdomainnavbar.md +327 -0
  44. package/.llm/components/tab.md +291 -0
  45. package/.llm/components/table.md +660 -0
  46. package/.llm/components/tablebody.md +258 -0
  47. package/.llm/components/tablecell.md +248 -0
  48. package/.llm/components/tablehead.md +248 -0
  49. package/.llm/components/tableheadercell.md +298 -0
  50. package/.llm/components/tablerow.md +285 -0
  51. package/.llm/components/tablist.md +210 -0
  52. package/.llm/components/textarea.md +362 -0
  53. package/.llm/components/textinput.md +467 -0
  54. package/.llm/components/tooltip.md +267 -0
  55. package/.llm/components/typography.md +245 -0
  56. package/.llm/digest/accordion.md +43 -0
  57. package/.llm/digest/accordionitem.md +47 -0
  58. package/.llm/digest/aspectratio.md +47 -0
  59. package/.llm/digest/badge.md +45 -0
  60. package/.llm/digest/bottomsheet.md +69 -0
  61. package/.llm/digest/breadcrumb.md +38 -0
  62. package/.llm/digest/breadcrumbitem.md +43 -0
  63. package/.llm/digest/button.md +48 -0
  64. package/.llm/digest/buttonicon.md +61 -0
  65. package/.llm/digest/card.md +50 -0
  66. package/.llm/digest/cardbody.md +68 -0
  67. package/.llm/digest/cardbutton.md +49 -0
  68. package/.llm/digest/checkbox.md +63 -0
  69. package/.llm/digest/divider.md +52 -0
  70. package/.llm/digest/dropdownmenu.md +67 -0
  71. package/.llm/digest/filterchip.md +68 -0
  72. package/.llm/digest/footer.md +57 -0
  73. package/.llm/digest/footergroup.md +42 -0
  74. package/.llm/digest/grid.md +62 -0
  75. package/.llm/digest/icon.md +45 -0
  76. package/.llm/digest/link.md +59 -0
  77. package/.llm/digest/menuitem.md +46 -0
  78. package/.llm/digest/navbar.md +60 -0
  79. package/.llm/digest/navbaritem.md +54 -0
  80. package/.llm/digest/navbarmenu.md +54 -0
  81. package/.llm/digest/navbarmenugroup.md +40 -0
  82. package/.llm/digest/navbarpanel.md +53 -0
  83. package/.llm/digest/navbarswitcher.md +51 -0
  84. package/.llm/digest/navbarswitcheroption.md +37 -0
  85. package/.llm/digest/option.md +54 -0
  86. package/.llm/digest/pagination.md +71 -0
  87. package/.llm/digest/removablechip.md +51 -0
  88. package/.llm/digest/row.md +60 -0
  89. package/.llm/digest/scroller.md +59 -0
  90. package/.llm/digest/searchinput.md +56 -0
  91. package/.llm/digest/segmentedcontrol.md +59 -0
  92. package/.llm/digest/segmentedcontrolitem.md +59 -0
  93. package/.llm/digest/select.md +92 -0
  94. package/.llm/digest/selectchip.md +68 -0
  95. package/.llm/digest/spinner.md +52 -0
  96. package/.llm/digest/stack.md +56 -0
  97. package/.llm/digest/statusdot.md +46 -0
  98. package/.llm/digest/subdomainnavbar.md +54 -0
  99. package/.llm/digest/tab.md +60 -0
  100. package/.llm/digest/table.md +71 -0
  101. package/.llm/digest/tablebody.md +49 -0
  102. package/.llm/digest/tablecell.md +55 -0
  103. package/.llm/digest/tablehead.md +50 -0
  104. package/.llm/digest/tableheadercell.md +65 -0
  105. package/.llm/digest/tablerow.md +56 -0
  106. package/.llm/digest/tablist.md +46 -0
  107. package/.llm/digest/textarea.md +78 -0
  108. package/.llm/digest/textinput.md +95 -0
  109. package/.llm/digest/tooltip.md +58 -0
  110. package/.llm/digest/typography.md +59 -0
  111. package/.llm/index.md +86 -0
  112. package/.llm/rules.md +122 -0
  113. package/.llm/tokens.md +341 -0
  114. package/AGENTS.md +164 -0
  115. package/LICENSE +21 -0
  116. package/README.md +63 -15
  117. package/dist/components/core/accordion/Accordion.css +10 -0
  118. package/dist/components/core/accordion/Accordion.d.ts +20 -0
  119. package/dist/components/core/accordion/Accordion.js +69 -0
  120. package/dist/components/core/accordion/Accordion.types.d.ts +20 -0
  121. package/dist/components/core/accordion/Accordion.types.js +7 -0
  122. package/dist/components/core/accordion-item/AccordionItem.css +98 -0
  123. package/dist/components/core/accordion-item/AccordionItem.d.ts +44 -0
  124. package/dist/components/core/accordion-item/AccordionItem.js +63 -0
  125. package/dist/components/core/accordion-item/AccordionItem.types.d.ts +32 -0
  126. package/dist/components/core/accordion-item/AccordionItem.types.js +13 -0
  127. package/dist/components/core/accordion-item/accordion-item-impl.css +107 -0
  128. package/dist/components/core/badge/Badge.css +37 -0
  129. package/dist/components/core/badge/Badge.d.ts +37 -0
  130. package/dist/components/core/badge/Badge.js +40 -0
  131. package/dist/components/core/badge/Badge.types.d.ts +24 -0
  132. package/dist/components/core/badge/Badge.types.js +8 -0
  133. package/dist/components/core/badge/badge-impl.css +32 -0
  134. package/dist/components/core/bottom-sheet/BottomSheet.css +178 -0
  135. package/dist/components/core/bottom-sheet/BottomSheet.d.ts +22 -0
  136. package/dist/components/core/bottom-sheet/BottomSheet.js +359 -0
  137. package/dist/components/core/bottom-sheet/BottomSheet.types.d.ts +67 -0
  138. package/dist/components/core/bottom-sheet/BottomSheet.types.js +18 -0
  139. package/dist/components/core/bottom-sheet/bottom-sheet-impl.css +57 -0
  140. package/dist/components/core/breadcrumb/Breadcrumb.css +19 -0
  141. package/dist/components/core/breadcrumb/Breadcrumb.d.ts +16 -0
  142. package/dist/components/core/breadcrumb/Breadcrumb.js +22 -0
  143. package/dist/components/core/breadcrumb/Breadcrumb.types.d.ts +18 -0
  144. package/dist/components/core/breadcrumb/Breadcrumb.types.js +9 -0
  145. package/dist/components/core/breadcrumb-item/BreadcrumbItem.css +34 -0
  146. package/dist/components/core/breadcrumb-item/BreadcrumbItem.d.ts +12 -0
  147. package/dist/components/core/breadcrumb-item/BreadcrumbItem.js +15 -0
  148. package/dist/components/core/breadcrumb-item/BreadcrumbItem.types.d.ts +22 -0
  149. package/dist/components/core/breadcrumb-item/BreadcrumbItem.types.js +9 -0
  150. package/dist/components/core/button/Button.css +141 -0
  151. package/dist/components/core/button/Button.d.ts +25 -0
  152. package/dist/components/core/button/Button.js +28 -0
  153. package/dist/components/core/button/Button.types.d.ts +40 -0
  154. package/dist/components/core/button/Button.types.js +9 -0
  155. package/dist/components/core/button/button-impl.css +46 -0
  156. package/dist/components/core/button-icon/ButtonIcon.css +135 -0
  157. package/dist/components/core/button-icon/ButtonIcon.d.ts +34 -0
  158. package/dist/components/core/button-icon/ButtonIcon.js +117 -0
  159. package/dist/components/core/button-icon/ButtonIcon.types.d.ts +41 -0
  160. package/dist/components/core/button-icon/ButtonIcon.types.js +8 -0
  161. package/dist/components/core/card/Card.css +65 -0
  162. package/dist/components/core/card/Card.d.ts +24 -0
  163. package/dist/components/core/card/Card.js +26 -0
  164. package/dist/components/core/card/Card.types.d.ts +33 -0
  165. package/dist/components/core/card/Card.types.js +7 -0
  166. package/dist/components/core/card-body/CardBody.css +139 -0
  167. package/dist/components/core/card-body/CardBody.d.ts +62 -0
  168. package/dist/components/core/card-body/CardBody.js +97 -0
  169. package/dist/components/core/card-body/CardBody.types.d.ts +61 -0
  170. package/dist/components/core/card-body/CardBody.types.js +15 -0
  171. package/dist/components/core/card-body/card-body-impl.css +87 -0
  172. package/dist/components/core/card-button/CardButton.css +73 -0
  173. package/dist/components/core/card-button/CardButton.d.ts +27 -0
  174. package/dist/components/core/card-button/CardButton.js +37 -0
  175. package/dist/components/core/card-button/CardButton.types.d.ts +24 -0
  176. package/dist/components/core/card-button/CardButton.types.js +7 -0
  177. package/dist/components/core/card-button/card-button-impl.css +39 -0
  178. package/dist/components/core/checkbox/Checkbox.css +149 -0
  179. package/dist/components/core/checkbox/Checkbox.d.ts +21 -0
  180. package/dist/components/core/checkbox/Checkbox.js +97 -0
  181. package/dist/components/core/checkbox/Checkbox.types.d.ts +46 -0
  182. package/dist/components/core/checkbox/Checkbox.types.js +15 -0
  183. package/dist/components/core/checkbox/checkbox-impl.css +90 -0
  184. package/dist/components/core/divider/Divider.css +41 -0
  185. package/dist/components/core/divider/Divider.d.ts +46 -0
  186. package/dist/components/core/divider/Divider.js +51 -0
  187. package/dist/components/core/divider/Divider.types.d.ts +25 -0
  188. package/dist/components/core/divider/Divider.types.js +9 -0
  189. package/dist/components/core/dropdown-menu/DropdownMenu.css +146 -0
  190. package/dist/components/core/dropdown-menu/DropdownMenu.d.ts +22 -0
  191. package/dist/components/core/dropdown-menu/DropdownMenu.js +309 -0
  192. package/dist/components/core/dropdown-menu/DropdownMenu.types.d.ts +62 -0
  193. package/dist/components/core/dropdown-menu/DropdownMenu.types.js +12 -0
  194. package/dist/components/core/dropdown-menu/dropdown-menu-impl.css +70 -0
  195. package/dist/components/core/filter-chip/FilterChip.css +149 -0
  196. package/dist/components/core/filter-chip/FilterChip.d.ts +23 -0
  197. package/dist/components/core/filter-chip/FilterChip.js +37 -0
  198. package/dist/components/core/filter-chip/FilterChip.types.d.ts +53 -0
  199. package/dist/components/core/filter-chip/FilterChip.types.js +12 -0
  200. package/dist/components/core/footer/Footer.css +104 -0
  201. package/dist/components/core/footer/Footer.d.ts +43 -0
  202. package/dist/components/core/footer/Footer.js +53 -0
  203. package/dist/components/core/footer/Footer.types.d.ts +47 -0
  204. package/dist/components/core/footer/Footer.types.js +18 -0
  205. package/dist/components/core/footer/footer-impl.css +218 -0
  206. package/dist/components/core/footer-group/FooterGroup.css +90 -0
  207. package/dist/components/core/footer-group/FooterGroup.d.ts +32 -0
  208. package/dist/components/core/footer-group/FooterGroup.js +64 -0
  209. package/dist/components/core/footer-group/FooterGroup.types.d.ts +25 -0
  210. package/dist/components/core/footer-group/FooterGroup.types.js +12 -0
  211. package/dist/components/core/footer-group/footer-group-impl.css +78 -0
  212. package/dist/components/core/icon/Icon.css +40 -0
  213. package/dist/components/core/icon/Icon.d.ts +23 -0
  214. package/dist/components/core/icon/Icon.js +79 -0
  215. package/dist/components/core/icon/Icon.types.d.ts +24 -0
  216. package/dist/components/core/icon/Icon.types.js +7 -0
  217. package/dist/components/core/link/Link.css +89 -0
  218. package/dist/components/core/link/Link.d.ts +37 -0
  219. package/dist/components/core/link/Link.js +141 -0
  220. package/dist/components/core/link/Link.types.d.ts +41 -0
  221. package/dist/components/core/link/Link.types.js +9 -0
  222. package/dist/components/core/link/link-impl.css +168 -0
  223. package/dist/components/core/menu-item/MenuItem.css +70 -0
  224. package/dist/components/core/menu-item/MenuItem.d.ts +11 -0
  225. package/dist/components/core/menu-item/MenuItem.js +26 -0
  226. package/dist/components/core/menu-item/MenuItem.types.d.ts +28 -0
  227. package/dist/components/core/menu-item/MenuItem.types.js +9 -0
  228. package/dist/components/core/navbar/Navbar.css +135 -0
  229. package/dist/components/core/navbar/Navbar.d.ts +36 -0
  230. package/dist/components/core/navbar/Navbar.js +371 -0
  231. package/dist/components/core/navbar/Navbar.types.d.ts +49 -0
  232. package/dist/components/core/navbar/Navbar.types.js +17 -0
  233. package/dist/components/core/navbar/navbar-impl.css +590 -0
  234. package/dist/components/core/navbar-item/NavbarItem.css +75 -0
  235. package/dist/components/core/navbar-item/NavbarItem.d.ts +22 -0
  236. package/dist/components/core/navbar-item/NavbarItem.js +40 -0
  237. package/dist/components/core/navbar-item/NavbarItem.types.d.ts +34 -0
  238. package/dist/components/core/navbar-item/NavbarItem.types.js +10 -0
  239. package/dist/components/core/navbar-menu/NavbarMenu.css +128 -0
  240. package/dist/components/core/navbar-menu/NavbarMenu.d.ts +5 -0
  241. package/dist/components/core/navbar-menu/NavbarMenu.js +186 -0
  242. package/dist/components/core/navbar-menu/NavbarMenu.types.d.ts +45 -0
  243. package/dist/components/core/navbar-menu/NavbarMenu.types.js +12 -0
  244. package/dist/components/core/navbar-menu/navbar-menu-impl.css +186 -0
  245. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.css +26 -0
  246. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.d.ts +17 -0
  247. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.js +22 -0
  248. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.types.d.ts +14 -0
  249. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.types.js +7 -0
  250. package/dist/components/core/navbar-panel/NavbarPanel.css +87 -0
  251. package/dist/components/core/navbar-panel/NavbarPanel.d.ts +34 -0
  252. package/dist/components/core/navbar-panel/NavbarPanel.js +46 -0
  253. package/dist/components/core/navbar-panel/NavbarPanel.types.d.ts +29 -0
  254. package/dist/components/core/navbar-panel/NavbarPanel.types.js +12 -0
  255. package/dist/components/core/navbar-panel/navbar-panel-impl.css +104 -0
  256. package/dist/components/core/navbar-panel/use-navbar-panel.d.ts +26 -0
  257. package/dist/components/core/navbar-panel/use-navbar-panel.js +135 -0
  258. package/dist/components/core/navbar-switcher/NavbarSwitcher.css +117 -0
  259. package/dist/components/core/navbar-switcher/NavbarSwitcher.d.ts +20 -0
  260. package/dist/components/core/navbar-switcher/NavbarSwitcher.js +90 -0
  261. package/dist/components/core/navbar-switcher/NavbarSwitcher.types.d.ts +46 -0
  262. package/dist/components/core/navbar-switcher/NavbarSwitcher.types.js +13 -0
  263. package/dist/components/core/navbar-switcher/navbar-switcher-impl.css +179 -0
  264. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.css +39 -0
  265. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.d.ts +16 -0
  266. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.js +19 -0
  267. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.types.d.ts +18 -0
  268. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.types.js +7 -0
  269. package/dist/components/core/option/Option.css +133 -0
  270. package/dist/components/core/option/Option.d.ts +25 -0
  271. package/dist/components/core/option/Option.js +31 -0
  272. package/dist/components/core/option/Option.types.d.ts +44 -0
  273. package/dist/components/core/option/Option.types.js +14 -0
  274. package/dist/components/core/pagination/Pagination.css +237 -0
  275. package/dist/components/core/pagination/Pagination.d.ts +30 -0
  276. package/dist/components/core/pagination/Pagination.js +406 -0
  277. package/dist/components/core/pagination/Pagination.types.d.ts +59 -0
  278. package/dist/components/core/pagination/Pagination.types.js +14 -0
  279. package/dist/components/core/pagination/pagination-impl.css +17 -0
  280. package/dist/components/core/removable-chip/RemovableChip.css +125 -0
  281. package/dist/components/core/removable-chip/RemovableChip.d.ts +25 -0
  282. package/dist/components/core/removable-chip/RemovableChip.js +36 -0
  283. package/dist/components/core/removable-chip/RemovableChip.types.d.ts +38 -0
  284. package/dist/components/core/removable-chip/RemovableChip.types.js +13 -0
  285. package/dist/components/core/search-input/SearchInput.css +205 -0
  286. package/dist/components/core/search-input/SearchInput.d.ts +5 -0
  287. package/dist/components/core/search-input/SearchInput.js +81 -0
  288. package/dist/components/core/search-input/SearchInput.types.d.ts +43 -0
  289. package/dist/components/core/search-input/SearchInput.types.js +13 -0
  290. package/dist/components/core/search-input/search-input-impl.css +20 -0
  291. package/dist/components/core/segmented-control/SegmentedControl.css +57 -0
  292. package/dist/components/core/segmented-control/SegmentedControl.d.ts +37 -0
  293. package/dist/components/core/segmented-control/SegmentedControl.js +269 -0
  294. package/dist/components/core/segmented-control/SegmentedControl.types.d.ts +38 -0
  295. package/dist/components/core/segmented-control/SegmentedControl.types.js +8 -0
  296. package/dist/components/core/segmented-control/segmented-control-impl.css +57 -0
  297. package/dist/components/core/segmented-control-item/SegmentedControlItem.css +151 -0
  298. package/dist/components/core/segmented-control-item/SegmentedControlItem.d.ts +50 -0
  299. package/dist/components/core/segmented-control-item/SegmentedControlItem.js +101 -0
  300. package/dist/components/core/segmented-control-item/SegmentedControlItem.types.d.ts +37 -0
  301. package/dist/components/core/segmented-control-item/SegmentedControlItem.types.js +10 -0
  302. package/dist/components/core/segmented-control-item/segmented-control-item-impl.css +69 -0
  303. package/dist/components/core/select/Select.css +400 -0
  304. package/dist/components/core/select/Select.d.ts +29 -0
  305. package/dist/components/core/select/Select.js +524 -0
  306. package/dist/components/core/select/Select.types.d.ts +96 -0
  307. package/dist/components/core/select/Select.types.js +26 -0
  308. package/dist/components/core/select/select-impl.css +114 -0
  309. package/dist/components/core/select-chip/SelectChip.css +155 -0
  310. package/dist/components/core/select-chip/SelectChip.d.ts +20 -0
  311. package/dist/components/core/select-chip/SelectChip.js +273 -0
  312. package/dist/components/core/select-chip/SelectChip.types.d.ts +56 -0
  313. package/dist/components/core/select-chip/SelectChip.types.js +14 -0
  314. package/dist/components/core/select-chip/select-chip-impl.css +38 -0
  315. package/dist/components/core/spinner/Spinner.css +76 -0
  316. package/dist/components/core/spinner/Spinner.d.ts +5 -0
  317. package/dist/components/core/spinner/Spinner.js +29 -0
  318. package/dist/components/core/spinner/Spinner.types.d.ts +37 -0
  319. package/dist/components/core/spinner/Spinner.types.js +10 -0
  320. package/dist/components/core/spinner/spinner-impl.css +27 -0
  321. package/dist/components/core/status-dot/StatusDot.css +43 -0
  322. package/dist/components/core/status-dot/StatusDot.d.ts +35 -0
  323. package/dist/components/core/status-dot/StatusDot.js +46 -0
  324. package/dist/components/core/status-dot/StatusDot.types.d.ts +29 -0
  325. package/dist/components/core/status-dot/StatusDot.types.js +7 -0
  326. package/dist/components/core/status-dot/status-dot-impl.css +42 -0
  327. package/dist/components/core/subdomain-navbar/SubdomainNavbar.css +89 -0
  328. package/dist/components/core/subdomain-navbar/SubdomainNavbar.d.ts +21 -0
  329. package/dist/components/core/subdomain-navbar/SubdomainNavbar.js +127 -0
  330. package/dist/components/core/subdomain-navbar/SubdomainNavbar.types.d.ts +43 -0
  331. package/dist/components/core/subdomain-navbar/SubdomainNavbar.types.js +13 -0
  332. package/dist/components/core/subdomain-navbar/subdomain-navbar-impl.css +147 -0
  333. package/dist/components/core/tab/Tab.css +113 -0
  334. package/dist/components/core/tab/Tab.d.ts +36 -0
  335. package/dist/components/core/tab/Tab.js +53 -0
  336. package/dist/components/core/tab/Tab.types.d.ts +42 -0
  337. package/dist/components/core/tab/Tab.types.js +13 -0
  338. package/dist/components/core/tab/tab-impl.css +49 -0
  339. package/dist/components/core/tab-list/TabList.css +40 -0
  340. package/dist/components/core/tab-list/TabList.d.ts +26 -0
  341. package/dist/components/core/tab-list/TabList.js +124 -0
  342. package/dist/components/core/tab-list/TabList.types.d.ts +20 -0
  343. package/dist/components/core/tab-list/TabList.types.js +7 -0
  344. package/dist/components/core/tab-list/tab-list-impl.css +56 -0
  345. package/dist/components/core/table/Table.css +40 -0
  346. package/dist/components/core/table/Table.d.ts +19 -0
  347. package/dist/components/core/table/Table.js +55 -0
  348. package/dist/components/core/table/Table.types.d.ts +59 -0
  349. package/dist/components/core/table/Table.types.js +9 -0
  350. package/dist/components/core/table/table-impl.css +75 -0
  351. package/dist/components/core/table/use-table-sort.d.ts +43 -0
  352. package/dist/components/core/table/use-table-sort.js +51 -0
  353. package/dist/components/core/table-body/TableBody.css +6 -0
  354. package/dist/components/core/table-body/TableBody.d.ts +12 -0
  355. package/dist/components/core/table-body/TableBody.js +26 -0
  356. package/dist/components/core/table-body/TableBody.types.d.ts +36 -0
  357. package/dist/components/core/table-body/TableBody.types.js +7 -0
  358. package/dist/components/core/table-cell/TableCell.css +76 -0
  359. package/dist/components/core/table-cell/TableCell.d.ts +21 -0
  360. package/dist/components/core/table-cell/TableCell.js +31 -0
  361. package/dist/components/core/table-cell/TableCell.types.d.ts +43 -0
  362. package/dist/components/core/table-cell/TableCell.types.js +7 -0
  363. package/dist/components/core/table-head/TableHead.css +6 -0
  364. package/dist/components/core/table-head/TableHead.d.ts +22 -0
  365. package/dist/components/core/table-head/TableHead.js +52 -0
  366. package/dist/components/core/table-head/TableHead.types.d.ts +39 -0
  367. package/dist/components/core/table-head/TableHead.types.js +7 -0
  368. package/dist/components/core/table-head/table-head-impl.css +51 -0
  369. package/dist/components/core/table-header-cell/TableHeaderCell.css +126 -0
  370. package/dist/components/core/table-header-cell/TableHeaderCell.d.ts +21 -0
  371. package/dist/components/core/table-header-cell/TableHeaderCell.js +34 -0
  372. package/dist/components/core/table-header-cell/TableHeaderCell.types.d.ts +56 -0
  373. package/dist/components/core/table-header-cell/TableHeaderCell.types.js +9 -0
  374. package/dist/components/core/table-header-cell/table-header-cell-impl.css +74 -0
  375. package/dist/components/core/table-row/TableRow.css +18 -0
  376. package/dist/components/core/table-row/TableRow.d.ts +17 -0
  377. package/dist/components/core/table-row/TableRow.js +32 -0
  378. package/dist/components/core/table-row/TableRow.types.d.ts +45 -0
  379. package/dist/components/core/table-row/TableRow.types.js +7 -0
  380. package/dist/components/core/table-row/table-row-impl.css +31 -0
  381. package/dist/components/core/text-area/TextArea.css +325 -0
  382. package/dist/components/core/text-area/TextArea.d.ts +13 -0
  383. package/dist/components/core/text-area/TextArea.js +133 -0
  384. package/dist/components/core/text-area/TextArea.types.d.ts +67 -0
  385. package/dist/components/core/text-area/TextArea.types.js +19 -0
  386. package/dist/components/core/text-area/text-area-impl.css +36 -0
  387. package/dist/components/core/text-input/TextInput.css +400 -0
  388. package/dist/components/core/text-input/TextInput.d.ts +5 -0
  389. package/dist/components/core/text-input/TextInput.js +130 -0
  390. package/dist/components/core/text-input/TextInput.types.d.ts +96 -0
  391. package/dist/components/core/text-input/TextInput.types.js +24 -0
  392. package/dist/components/core/text-input/text-input-impl.css +36 -0
  393. package/dist/components/core/tooltip/Tooltip.css +101 -0
  394. package/dist/components/core/tooltip/Tooltip.d.ts +51 -0
  395. package/dist/components/core/tooltip/Tooltip.js +87 -0
  396. package/dist/components/core/tooltip/Tooltip.types.d.ts +38 -0
  397. package/dist/components/core/tooltip/Tooltip.types.js +9 -0
  398. package/dist/components/core/tooltip/TooltipAnchor.d.ts +52 -0
  399. package/dist/components/core/tooltip/TooltipAnchor.js +69 -0
  400. package/dist/components/core/tooltip/tooltip-anchor.css +145 -0
  401. package/dist/components/core/tooltip/tooltip-impl.css +54 -0
  402. package/dist/components/core/tooltip/use-tooltip.d.ts +111 -0
  403. package/dist/components/core/tooltip/use-tooltip.js +189 -0
  404. package/dist/components/core/typography/Typography.css +96 -0
  405. package/dist/components/core/typography/Typography.d.ts +297 -0
  406. package/dist/components/core/typography/Typography.js +28 -0
  407. package/dist/components/core/typography/Typography.types.d.ts +40 -0
  408. package/dist/components/core/typography/Typography.types.js +7 -0
  409. package/dist/components/css-time.d.ts +20 -0
  410. package/dist/components/css-time.js +30 -0
  411. package/dist/components/given.d.ts +7 -0
  412. package/dist/components/given.js +9 -0
  413. package/dist/components/hover-open.d.ts +34 -0
  414. package/dist/components/hover-open.js +90 -0
  415. package/dist/components/index.d.ts +114 -1
  416. package/dist/components/index.js +115 -2
  417. package/dist/components/layout/aspect-ratio/AspectRatio.css +29 -0
  418. package/dist/components/layout/aspect-ratio/AspectRatio.d.ts +24 -0
  419. package/dist/components/layout/aspect-ratio/AspectRatio.js +26 -0
  420. package/dist/components/layout/aspect-ratio/AspectRatio.types.d.ts +22 -0
  421. package/dist/components/layout/aspect-ratio/AspectRatio.types.js +7 -0
  422. package/dist/components/layout/aspect-ratio/aspect-ratio-impl.css +44 -0
  423. package/dist/components/layout/grid/Grid.css +76 -0
  424. package/dist/components/layout/grid/Grid.d.ts +31 -0
  425. package/dist/components/layout/grid/Grid.js +33 -0
  426. package/dist/components/layout/grid/Grid.types.d.ts +48 -0
  427. package/dist/components/layout/grid/Grid.types.js +7 -0
  428. package/dist/components/layout/grid/grid-impl.css +62 -0
  429. package/dist/components/layout/row/Row.css +85 -0
  430. package/dist/components/layout/row/Row.d.ts +32 -0
  431. package/dist/components/layout/row/Row.js +34 -0
  432. package/dist/components/layout/row/Row.types.d.ts +45 -0
  433. package/dist/components/layout/row/Row.types.js +7 -0
  434. package/dist/components/layout/scroller/Scroller.css +59 -0
  435. package/dist/components/layout/scroller/Scroller.d.ts +34 -0
  436. package/dist/components/layout/scroller/Scroller.js +36 -0
  437. package/dist/components/layout/scroller/Scroller.types.d.ts +38 -0
  438. package/dist/components/layout/scroller/Scroller.types.js +7 -0
  439. package/dist/components/layout/scroller/scroller-impl.css +45 -0
  440. package/dist/components/layout/stack/Stack.css +73 -0
  441. package/dist/components/layout/stack/Stack.d.ts +28 -0
  442. package/dist/components/layout/stack/Stack.js +30 -0
  443. package/dist/components/layout/stack/Stack.types.d.ts +41 -0
  444. package/dist/components/layout/stack/Stack.types.js +7 -0
  445. package/dist/components/visually-hidden.d.ts +22 -0
  446. package/dist/components/visually-hidden.js +31 -0
  447. package/dist/fonts/LICENSE-inter.txt +93 -0
  448. package/dist/fonts/LICENSE-red-hat-mono.txt +93 -0
  449. package/dist/fonts/fonts.css +111 -0
  450. package/dist/fonts/inter-cyrillic-ext-wght-normal.woff2 +0 -0
  451. package/dist/fonts/inter-cyrillic-wght-normal.woff2 +0 -0
  452. package/dist/fonts/inter-greek-ext-wght-normal.woff2 +0 -0
  453. package/dist/fonts/inter-greek-wght-normal.woff2 +0 -0
  454. package/dist/fonts/inter-latin-ext-wght-normal.woff2 +0 -0
  455. package/dist/fonts/inter-latin-wght-normal.woff2 +0 -0
  456. package/dist/fonts/inter-vietnamese-wght-normal.woff2 +0 -0
  457. package/dist/fonts/red-hat-mono-latin-ext-wght-normal.woff2 +0 -0
  458. package/dist/fonts/red-hat-mono-latin-wght-normal.woff2 +0 -0
  459. package/dist/marketing.css +289 -241
  460. package/package.json +18 -4
@@ -0,0 +1,409 @@
1
+ <!-- GENERATED from card-body.contract.json. Do not edit. -->
2
+
3
+ # CardBody
4
+
5
+ Everything a card holds: the words inset from its edges and the picture that reaches them, in one region. The surface around it keeps a fill and a corner and nothing else. The inset belongs to the words alone rather than to this whole box, which is what lets a photograph meet the corner while a sentence three lines above it does not — one measure cannot serve both, and putting the padding on the copy instead of on the container is how the same component draws both.
6
+
7
+ ## Use when
8
+
9
+ - Words, a picture, or both inside a Card — a feature and the sentence explaining it, a screenshot under the copy that describes it
10
+ - A photograph, render or screenshot that should reach the card's edges while the copy above it stays inset
11
+ - A picture that should absorb whatever height the copy leaves, so a row of cards ends flush no matter how much each one says
12
+ - A mark above the words — the glyph a feature card leads with, sized and inset with the copy rather than reaching the card's edges
13
+ - Copy that sits over the picture rather than beside it — a photograph as the card's ground, with a title and a sentence washed over it
14
+ - A line above the title filing the card under something — the date an article ran, how long it takes to read, the category it belongs to. It is set in capitals at the eyebrow step, which is what tells it apart from the copy without it needing a colour of its own
15
+
16
+ ## Do not use
17
+
18
+ - The whole card is one picture, with no words at all → `Card`
19
+ - A surface of its own. It has no fill and no corner: outside a Card it is a stack with padding on part of it, which is a layout rather than a component
20
+ - Copy over a picture with nothing to darken it. `overMedia` paints a ground and a wash under the words and is the only supported way to lay them over art — setting `src` alone puts the picture in the column, under the copy rather than behind it, which is a different card
21
+ - Text baked into the picture. It cannot be selected, translated, or reflowed at the width a phone gives the card — words go in title and description, which are text at a size the type ramp chose
22
+ - Controlling the gap between unrelated blocks. It stacks its copy at one measure, and a page needing two different gaps is composing the stack itself
23
+
24
+ ## Anatomy
25
+
26
+ CardBody renders 9 elements. A token binding names the part it applies to.
27
+
28
+ - `root` — `<div>`, class `dds-cardbody`. The whole of the card's content, and no padding of its own. That is the entire trick: the inset sits on `content` one level in, so the picture beside it can reach the card's edges without anything being cancelled back off. A body that padded itself and then pulled the picture out again with a negative margin would be two decisions undoing each other, and neither would be findable from the other.
29
+
30
+ `flex: auto` with `min-block-size: 0`, so the body takes the height the card was given rather than the height its words happen to need. This is what a row of cards depends on: the grid stretches every card to the tallest, the body inherits that height, and the picture inside it absorbs whatever the copy did not use. Without it the body would shrink to its text and the picture would have no slack to take.
31
+
32
+ It stacks at no gap. The space between the copy and the picture is `content`'s own bottom padding, which is already the right measure and already there — a gap on top of it would be a second decision about one piece of space.
33
+
34
+ `position: relative` always, so the layered case has something to pin to, and `display` is the one thing that varies: a flex column while the picture is a region in the flow, a grid once it is the ground behind everything. Under `overMedia` the content is the only child still in the flow — the picture and the wash are pinned to all four edges and out of it — so it lands in the single cell without a template being written for it.
35
+
36
+ Under `overMedia` it paints `color.bg.brand-strong` and takes `color.fg.on-brand-strong`. The ground is never seen while the picture loads, which is the point of it: a photograph that 404s or has not arrived yet leaves white text on whatever was underneath, and the darkest ground the package has is the one that takes white at 20.55:1. It is a floor rather than a guarantee — no wash makes white legible over white, and what answers that is art with somewhere for the words to go.
37
+ - `scrim` — `<span>`, class `dds-cardbody__scrim`. A wash over the picture, so the words have a ground rather than a photograph. Drawn whenever `overMedia` is set — one prop for one decision, rather than a second asking whether the first needs to be legible.
38
+
39
+ Above the picture and below the words, which is markup order: all three are in the same grid cell, and the two pinned layers stack in the order they are written.
40
+
41
+ A <span> rather than a <div> because it is not a region and holds nothing — there is no content here to group, only a colour between two layers. Rendered only when `overMedia` is set.
42
+ - `content` — `<div>`, class `dds-cardbody__content`. The inset region: the mark, the title and the sentence, held off the card's edges so nothing reads as spilling out of the corner. It pads on both axes at `space.inset.lg` and stacks what it holds at `space.gap.sm` — close enough that a title and the sentence under it read as one block. Product's own card body stacks wider; the two packages disagree here and this one follows its own page.
43
+
44
+ Always rendered, even with nothing in it. A conditional region would have to name the one prop that brings it back, and there are three that should — a card with only a description and no title still wants its copy inset. The cost is the case in `useInstead`: a card that is nothing but a picture gets an empty padded band above it, and belongs in a bare Card instead.
45
+
46
+ Under `flush` the inline padding goes and the block padding stays. That asymmetry is the whole point of the prop rather than an oversight in it: the inset exists to hold words off a fill, so a card with no fill has nothing for the inline half of it to do — the picture is the card's edge there, and copy indented from it reads as a mistake rather than as a margin. The block half is answering a different question, the space between a picture and the first line under it, and no change of ground affects that. One prop, two paddings, and only one of them was ever a decision about the fill.
47
+
48
+ It insets by space.inset.card rather than by a step off the generic scale. The generic step held one value at every width, so a card on a phone was padded as generously as one on a desktop while its column was a third as wide; the role comes down with the viewport, and it is a role rather than a size because a row of cards padded differently is a row of different cards.
49
+
50
+ Its gap is space.heading.title-description-compact, which is the section heading group's step at the size a card sets. The relationship is the same one and the number is not, because what the eye reads is the gap plus the leading above it: under a display title the leading is most of it, under a card's title it is half as deep, and one value would make the card look loose where the section looked right. One gap for all three regions is the limit here: an eyebrow wants to sit nearer its title than the title sits to its description, and a single gap cannot say that — the same limit Stack has, and the reason a heading group is not one.
51
+
52
+ The inset has two steps. `space.inset.card` is the one a card in a grid of cards wants; `compact` drops it to `space.inset.md` for a card small enough that thirty-two either side is most of its width — a rail beside a footer's columns is the case it was added for. One axis against the unconditional binding, so the cascade picks the narrower one and Figma is told which.
53
+ - `mark` — `<div>`, class `dds-cardbody__mark`. The glyph the card leads with, above the title. A <div> wrapping whatever was passed rather than an element of its own: Marketing has no Icon yet, so what arrives here is a quill glyph, an inline <svg> or a small <img> depending on the page, and a wrapper is what gives all three the same position without this part claiming to know which it got.
54
+
55
+ It is drawn by `Icon` at `icon.size.lg` — the step whose own description reads "cards and content sections", which is this exact job. The step is the card's rather than the page's: a set of feature cards has to agree about how big their marks are, and Icon unwraps one that arrives already sized so a call site cannot quietly disagree.
56
+
57
+ This used to be sized here instead, and it did not work on its own — every Quill glyph ships width and height attributes, so a box with a measure has no effect on the SVG inside it, and there was an impl sheet reaching into a child to force it. That sheet is gone. A component that owns the SVG needs no rule about somebody else's.
58
+
59
+ `align-self: flex-start`, so the box is as wide as the mark rather than as wide as the card. Stretched, it would be a full-width block whose glyph merely happens to sit at the left, which reads identically until something is centred and cannot be. `display: flex` for the same class of reason: an inline SVG sits on a text baseline and leaves a few pixels under it that look like a spacing bug and are not one.
60
+
61
+ It carries `space.gap.lg` beneath it, which the column's own `space.gap.sm` adds to, so the mark stands off the title by the two together. The column measure is right for a title and the sentence under it, which are one block of copy read as a unit; a mark is not part of that block, and at the column's own measure it reads as a bullet on the heading rather than as the card's own sign.
62
+
63
+ It binds no colour, for the reason the title does not: Card sets one per variant and it inherits, so the same mark is white on the brand fill and near-black on the page. Rendered only when `mark` is set.
64
+ - `eyebrow` — `<p>`, class `dds-cardbody__eyebrow`. The line above the title naming what the card is filed under — a date, a read time, a category. It takes font.eyebrow: twelve pixels, medium, and the wide tracking that setting needs, which is the step this package already uses for a tag above a headline.
65
+
66
+ The capitals are this part's, through `text-transform`, rather than the page's through the string it was handed. That is the whole reason the transform is here: an accessible name is read from the markup, so a month typed as AUGUST reaches a screen reader as a token several of them spell out one letter at a time. Written as August and drawn as capitals, it is announced as a month and shown as a label.
67
+
68
+ A <p> with `margin: 0`, for the reason the description is one — it is a line of text in the copy column, and the column's own gap is what stands it off the title rather than a margin of its own.
69
+
70
+ It binds no colour, which is the decision the title and the description also make and the one most likely to be argued with here. An eyebrow is usually drawn quieter than the copy under it, and color.fg.muted is the role that would say so. But Card sets a colour per variant and this inherits it, so a muted role would hold on the page and fail on the two brand grounds — fg.muted is gray.600, which on color.bg.brand-strong is near-black on near-black. What tells this line apart from the title is its size, its weight and its tracking, and all three survive a change of ground.
71
+
72
+ Muted, and the one part of this body that is. A date, a category, a kind — an eyebrow names which of something this is rather than what it says, so it is read once on the way to the title and not again. The title and the description are the pair the card is actually made of and they share an ink; a third thing in that same ink over them reads as the first line of the card rather than as the tag on it.
73
+
74
+ Not when it sits over media. There the root has already taken the ink the scrim was drawn for, and a grey mixed for a white page laid over a photograph is neither legible nor a step back from anything — it is the one ground where being lighter stops meaning quieter.
75
+
76
+ It is the one part here with an ink of its own, and so the one that has to be told which way round the ground is. Everything else takes the colour the card sets and inherits it; this is deliberately quieter than the copy beneath it, and "quieter" is a different colour on a dark card than on a light one — `color.fg.muted` against an inverse card is 3.08:1. Rendered only when `eyebrow` is set.
77
+ - `title` — `<h3>`, class `dds-cardbody__title`. The card's name. An <h3> because a card most often sits under a section's own h2, and because a title that was a div would leave a page of cards with no structure in it at all — the same choice Dialog, Drawer and BottomSheet make. A page whose cards sit at another depth composes its own heading above the card instead.
78
+
79
+ It takes font.h5, the smallest step the heading scale has and the one this package's cards already used. The level and the size are separate decisions and this part makes both, which is the trade for a consumer not having to know either.
80
+
81
+ It binds no colour. The Card sets one per variant on its root and colour inherits, so a title on the brand fill takes fg.on-solid and the same title on the page takes fg.default without this part knowing which card it is in. Binding a role here would override that and put near-black text on the brand-strong fill.
82
+
83
+ It has two steps. `font.h5` is the default and is a heading over a group of cards; `compact` takes `font.label.md`, sixteen at semibold.
84
+
85
+ That role is described as interactive text — navigation links, form labels, a call to action — and a card's name is none of those. It is the only sixteen-pixel semibold step this package has, and the alternatives are worse: `field-label` at the same size is medium weight and names a form field, and `label-medium` stops at fourteen. A role named for one job doing another is worth writing down rather than leaving for the next reader to wonder at; the honest fix is a step in this scale for the name of a small surface. Rendered only when `title` is set.
86
+ - `description` — `<p>`, class `dds-cardbody__description`. The sentence under the title, at font.body.md — the default body step, because a card's copy is copy rather than a caption. It sits at space.gap.sm from the title, close enough that the two read as one block.
87
+
88
+ A <p>. It binds no colour, for the reason the title does not.
89
+
90
+ It moves with the title. `font.body.md` by default and `font.body.sm` when the card is compact, which keeps the two a step apart — a sixteen-pixel title above sixteen-pixel copy is a card with no heading in it. Rendered only when `description` is set.
91
+ - `media-frame` — `<div>`, class `dds-cardbody__media-frame`. The picture's own box, and the reason a zoom looks like a zoom. An <img> cannot clip itself — `overflow` does not apply to replaced content — so a picture that scales has to be scaled inside something. Without this the nearest clip is the Card's, one level up and around the copy as well, and a picture growing by a per cent pushes its bottom edge down over the eyebrow and the headline. In a body with no card around it at all, nothing clips it and it simply paints over whatever is below.
92
+
93
+ So the frame holds the shape and the picture moves inside it: the box keeps its place in the column while the art grows past its edges and is cut off at them, which is the whole effect.
94
+
95
+ It is drawn whenever there is a `src`, rather than only when `zoomOnHover` is set. A part that appeared with the zoom would be a second thing the prop did, and the layout role has to move here either way — the frame is what now takes the height the copy leaves, and the picture fills it. One shape for every card with a picture is cheaper to reason about than two.
96
+
97
+ It carries the flex sizing the media used to: `flex: auto` with `min-block-size: 0`, so it absorbs whatever height the copy did not use, and `aspect` is applied here rather than to the picture, being a fact about the box rather than about the art in it. Rendered only when `src` is set.
98
+ - `media` — `<img>`, class `dds-cardbody__media`. The picture, reaching the card's edges because nothing above it in this box has padding to keep it off them. The corner is Card's, drawn by its overflow, which is why this meets a rounded edge rather than squaring one off.
99
+
100
+ `display: block`, which is the decision a page most often gets wrong on its own. An img is inline by default, so it sits on a text baseline and leaves a strip of the card's fill beneath it that looks like a spacing bug and is not one — no gap token is involved, and no amount of hunting through the padding finds it.
101
+
102
+ It fills `media-frame` at 100% in both axes and sizes nothing itself. The `flex: auto` and `min-block-size: 0` that used to be here are the frame's, which is the element in the column now: a flex item will not shrink below its content size without the second of those, and an image's content size is its natural height, so a tall photograph would otherwise push the card open from the inside. Product's banner learned this the hard way and took its art out of the flow entirely; here the frame stays in the column and is allowed to shrink instead.
103
+
104
+ `object-fit: cover`, because a region whose height is decided by something else cannot also honour the picture's own proportions. Cover crops; the alternative letterboxes, which shows the card's fill at two edges of a picture asked to reach them.
105
+
106
+ It binds `radius.none`, which is a decision rather than a default. Avatar's image rounds itself, at `radius.pill`, because the status mark at its corner means its root cannot hide its overflow. This is the same property argued the other way: the clip belongs to Card, so rounding here would curve the two corners the card already curved and leave the two in the middle of the column square.
107
+
108
+ It binds no ground. A render with transparency is meant to sit on the card's own fill — the coral behind a rosette, the near-black behind a shield are the Card's — and a fill of its own would paint a rectangle over the bottom half of the card.
109
+
110
+ Under `zoomOnHover` it grows by `motion.scale.media-hover` while the pointer is over the body, and `media-frame`'s `overflow: hidden` is what makes that read as anything: the frame holds still and the art moves inside it. The card's own clip is one level further out and around the copy as well, which is why it could not do this job — see the frame's own description. CSS's own `scale` property rather than a `transform`, which is what CardButton's lift already uses for its `translate` — the two are independent properties, so a card could in principle do both without either having to know the other's matrix. It does not, and that is a decision rather than a limitation: CardButton drops its lift whenever the body it holds zooms, on every variant, so one gesture moves one thing.
111
+
112
+ The rule itself is in the impl sheet, because the contract cannot hold its shape. A state bound on a part emits hover on that part — `.dds-cardbody__media:hover` — which would zoom the picture only while the pointer was on the picture, and leave it still when the pointer was on the headline of the very same card. What is wanted is the root's hover reaching one of its own children, and there is no vocabulary for that here. Rendered only when `src` is set.
113
+
114
+ Apply these classes from the generated `cardBodyParts` constant rather than writing the strings by hand.
115
+
116
+ ## Composition
117
+
118
+ - Takes no children. Everything it renders comes from props
119
+ - Never contains: `Card`, `CardBody` — in children or in any prop that takes a node
120
+
121
+ ## Props
122
+
123
+ ### overMedia — `boolean` (default `false`)
124
+
125
+ Use when: The picture is the card's ground and the copy is read on top of it. Set explicitly rather than inferred from src, which BannerBody can afford to do and this cannot: there, art is always behind the words, so having art and being over it are the same fact. Here a picture is a region in the column by default, and the same src means two different cards
126
+ Never for: Making a card look richer. It forces the dark ground and the light ink on every word in the body, so a title that was near-black on the page turns white — and over a pale photograph with no wash strong enough to hold it, that is the least legible card on the page rather than the most striking
127
+
128
+ ### flush — `boolean` (default `false`)
129
+
130
+ Use when: The card has no fill for the copy to be held off — Card's `plain` variant, where the picture is the card's edge rather than the ground being it. The inline inset goes and the copy lines up with the picture above it; the block padding stays, because the space between a picture and the line under it is still doing its job
131
+ Never for: A filled card. The inset is what keeps the words off the ground's edge, and on surface, accent or accent-strong removing it puts a headline hard against the colour — which is the one way a card looks broken rather than merely tight.
132
+
133
+ It is paired with variant="plain", and the two are set together or neither is: a plain card that is not flush reads as copy indented from its own picture, and a flush card that is not plain reads as text spilling out of a fill. Nothing can check the pair, because the ground is the Card's prop and the inset is this one's, and neither component can see the other.
134
+
135
+ ### zoomOnHover — `boolean` (default `false`)
136
+
137
+ Use when: The card is pressable and its picture is what answers the pointer — an editorial card inside a CardButton, on any ground. The picture grows by motion.scale.media-hover and media-frame clips it, so what the reader sees is the frame holding still while the art moves inside it. Setting this is also what stops the card lifting: CardButton suppresses its own lift when the body it holds zooms, so the two motions never compete
138
+ Never for: A card that is not pressable. Motion under the cursor is how a surface says it responds to a press, and on a plain Card — a div with no role — it says that to a mouse user about something that does nothing, while telling a keyboard user nothing at all, since there is no hover without a pointer and no focus without a control. Inside a CardButton the same movement is decoration on a real target that already has a focus ring.
139
+
140
+ Not every card with a picture, either. This is the editorial card's motion, and a row of feature tiles that all zoom is a page where nothing is being pointed out.
141
+
142
+ ### compact — `boolean` (default `false`)
143
+
144
+ Use when: The card is small enough that the standard inset and the standard type are most of it. `space.inset.card` is thirty-two, which is a fifth of the width of a rail beside a footer's columns; `font.h5` is twenty-four, which is a heading over a group of cards rather than the name of one two hundred pixels wide.
145
+
146
+ This takes the inset to `space.inset.md`, the title to `font.label.md` and the description to `font.body.sm` — sixteen and fourteen, where the standard card runs twenty-four and sixteen. The pair moves together: dropping the title alone would put a heading two pixels above its own body copy.
147
+
148
+ It is about the card's size rather than its importance. A compact card is not a lesser one.
149
+ Never for: Fitting more words into a card that is too small for them. The inset is not what is wrong with a card whose copy will not fit — taking sixteen pixels off each side buys one word a line and leaves the same card overfull
150
+
151
+ It does not undo `flush`. A flush card has no inline inset at all — the copy lines up with the picture above it — and the two together keep that: the compact inline step names `flush: false`, so the wider rule cannot win on source order alone. The block inset still narrows, which is what `flush` leaves alone anyway.
152
+
153
+ ### tone — `default` | `inverse` (default `default`)
154
+
155
+ - `default` — The card is on the page, which is nearly every card
156
+ - `inverse` — The card sits on a band that paints its own dark ground, and carries `tone="inverse"` itself. The eyebrow takes the inverse muted ink so it stays quieter than the copy without falling below what a reader can make out
157
+
158
+ Use when: Which way round the ground under it is, and it pairs with Card's prop of the same name for the reason `compact` does: the box and its contents are separate components, and only the page knows it has put one inside the other.
159
+
160
+ Only the eyebrow reads it. Everything else here takes the ink the card sets and inherits it — the eyebrow is the one part with a colour of its own, because it is quieter than the copy beneath it, and `color.fg.muted` is quieter than dark text on a light card rather than quieter than anything. On a dark card it comes to 3.08:1, which is a line a reader with low vision is asked to take on trust.
161
+ Never for: Setting it on one of the pair and not the other. A card whose ground is inverse and whose body is not has one line in an ink chosen for a page it is not on
162
+
163
+ ### eyebrow — `string`
164
+
165
+ Use when: The card is filed under something a reader scans before the headline — the date an article ran, how long it takes to read, the category it sits in. Write it in the case it should be read in: the part draws the capitals itself, so 'August' is what belongs here and AUGUST is what appears
166
+ Never for: A sentence, or a second headline. It is set at twelve pixels with wide tracking, a measure chosen for three or four words and a wall at the length of a clause — what the card is about is the title's job.
167
+
168
+ Nor a status or a count. It paints no ground and binds no colour, so it cannot say 'New' or '2 left' the way a filled pill does; it is a filing label at the body's own ink, and a reader scanning a column of cards reads it as one.
169
+
170
+ ### title — `string`
171
+
172
+ Use when: The card names what it is about. A noun phrase rather than a sentence — 'Balance protection', not 'We protect your balance' — because it is read as a label on the block beneath it. A string rather than a node: a node could carry a mark or a link, and would cost the component its examples — the checker requires a named element there, so no row could ever show a card with real copy in it.
173
+ Never for: The sentence explaining the card. That is description, which sits under this at a gap close enough that the two read as one block. A title that runs to a sentence leaves the copy with nothing to add
174
+
175
+ ### description — `string`
176
+
177
+ Use when: What the title means, usually a sentence or two. It takes the default body step, because a card's copy is copy rather than a caption. A string rather than a node, for the reason the title is one — a node prop cannot be given text in an examples row, and a card nobody can show is worse than a sentence that cannot hold a link.
178
+ Never for: A control. This body holds two regions and neither is a place to act from — a card with a call to action puts it in the Card beneath this, where it is not wearing the body's copy styling
179
+
180
+ ### mark — `node`
181
+
182
+ Accepts: Icon
183
+ Use when: The card leads with a glyph — a badge, a shield, a small piece of art that makes the feature recognisable before the title is read. Set it on every card in a set or on none of them: one card in a row carrying a mark reads as the important one, which is a claim the mark was not meant to make. Pass the glyph; the body draws it at its own step, and an Icon passed already sized is unwrapped rather than obeyed
184
+ Never for: A picture that should reach the card's edges. This is inset with the copy and sized to sit above a heading; a photograph put through it is a stamp in the corner of a wide margin. That is src, which renders the media region below or above this whole block rather than inside it
185
+
186
+ ### src — `string`
187
+
188
+ Use when: The card shows a picture — a photograph, a product render, a screenshot of the thing being described. Absent is the ordinary case: most cards are words
189
+ Never for: A data URI holding a photograph. A card's picture is the heaviest thing on a marketing page and inlining it costs the page its cache; a path belongs here, and the formats and sizes behind it are the page's build to decide
190
+
191
+ ### alt — `string`
192
+
193
+ Use when: Whenever src is, and empty when the picture says nothing the copy has not already said. A decorative render beside a title naming it — a shield next to 'Integrity' — takes alt="", which tells a screen reader to skip it rather than read a filename aloud. A photograph carrying meaning of its own takes a sentence describing what it shows
194
+ Never for: Repeating the card's title. The reader heard it from the heading a moment earlier, and hearing it twice is how a decorative image makes a card worse than one with no image at all. If the sentence you would write is the title, the right value is the empty string.
195
+
196
+ Nothing enforces that this is set when src is, and it is worth knowing why rather than assuming an oversight. The rule exists in the vocabulary — a `null` consequent is how one prop obliges another — but `null` there matches undefined, null and "" alike, on the argument that a label of "" puts no button on screen and so obliges nothing. That argument does not survive contact with alt, where "" is not absence but the decision to say nothing, and is the correct answer for every decorative render in these cards. Written as a rule it would fail exactly the examples that teach the right thing, so it is written here instead and repeated in the accessibility requirements.
197
+
198
+ ### aspect — `number`
199
+
200
+ Use when: The picture must hold a known shape rather than absorb the card's spare height — a logo that distorts the moment it is cropped, or a chart whose proportions are the point. Written as the division rather than the result, so the shape is legible: aspect={16 / 9}, not aspect={1.7778}
201
+ Never for: A row of cards that should end flush. Setting this stops the picture absorbing the height the copy leaves, so a card whose title runs to two lines grows taller than its neighbours and the row goes ragged. Absent is right for almost every card in a set
202
+
203
+ ### mediaPosition — `below` | `above` (default `below`)
204
+
205
+ - `below` — The copy introduces the picture — a feature named and explained, then shown. The ordinary case, and what a reader scanning a column of cards is reading for
206
+ - `above` — The picture is what the reader recognises the card by and the words caption it — a photograph leading an article, a screenshot the copy then describes. Changes the order of the elements themselves rather than only their appearance, so what a screen reader hears follows what the page shows
207
+
208
+ Also accepts everything from `HTMLAttributes<HTMLDivElement>`.
209
+
210
+ ## Accessibility
211
+
212
+ Guaranteed by the component. Write none of it by hand: the ids these attributes point at are generated per instance, so an attribute set from outside either says the same thing twice or points at nothing.
213
+
214
+ - A card that sets src sets alt too, and sets it to the empty string when the picture is decorative. An img with no alt attribute announces its filename; alt="" is the deliberate silence, and the two are not the same thing to anything reading the page aloud.
215
+ - Copy the reader has to be able to select, translate or reflow does not go in the picture. A card's words belong in title and description, where they are text at a size the type ramp chose; baked into an image they are pixels a phone shrinks along with everything else.
216
+
217
+ ## Rules
218
+
219
+ - **On a phone a section's actions stack and each fills the width, including when there is only one** — On a phone a page's actions stack, and each one fills the width. Not most of it, and not the width its label happens to need — the whole column.
220
+
221
+ Two side by side is what this replaces. On the narrowest screen each gets half a column minus the gap, which is rarely enough for a real label: the words wrap inside the pills, the two buttons come out different heights, and the pair reads as a broken row rather than as a choice. Stacked, each has the whole width and neither has to shorten its words to fit.
222
+
223
+ A single action fills too, and that is the part worth saying, because it is the one that looks unnecessary. A lone button has the room to sit at its natural width and still should not: a full-width control is the phone's convention for the thing the screen is asking you to do, and a pill hugging its label reads as one option among others that are not there. It also makes the target predictable — the whole width, wherever the thumb lands — which a centred pill does not.
224
+
225
+ Filling is the row's job rather than the button's. A button has no width of its own and is not given one; the row it sits in becomes a column and stretches its children, so nothing about the control changes and the same button is full width here and its own size on a desktop.
226
+
227
+ This is the phone's breakpoint, size.breakpoint.md, and not the wider one that decides whether a heading is centred. Those are different questions and they break at different widths: a heading stops being centred when the measure is the screen, while a button stops being full width much sooner than that — stretched across a tablet it is a long way from its own label, and a label centred in a metre of pill is harder to hit than one in a pill the size of the words.
228
+
229
+ What this is not about is every row of controls. A set of filter chips, a pagination strip, a toolbar, a link sitting after a sentence — none of these is the page asking for something, and stacking them to full width would turn a strip the eye skims into a list it has to read. The test is whether the row is the call to action the section was written for.
230
+ Guidance only — cannot be checked automatically.
231
+ - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, Input and Switch simultaneously.
232
+ Guidance only — cannot be checked automatically.
233
+ - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
234
+
235
+ color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
236
+
237
+ color.bg.strong is not a section ground. It is the inverted fill for an action that has to outrank what surrounds it, and the components that paint it — Button and ButtonIcon in their inverse form — already set both halves in one rule, which is the pattern a hand-painted section has to copy.
238
+ Guidance only — cannot be checked automatically.
239
+ - **Every gap inside a section names the relationship it expresses, and the same relationship keeps its measure when it turns on its side** — A section's spacing is named by the relationship it expresses, not chosen by size. Every gap in a section has a role token, and reaching for a step off the generic scale because it happens to be the right number is how two sections written by two people stop lining up: the numbers agree today and drift the first time one of them is tuned.
240
+
241
+ The heading group is three steps, not one gap. An eyebrow sits nearer its title than the title sits to its description, and the actions sit further from the description than either — space.heading.eyebrow-title, space.heading.title-description, space.heading.description-actions, in that order. A single `gap` on the group cannot say this; it sets all three the same and the block reads as evenly spaced lines rather than as a mark, a name and a paragraph. The eyebrow has to identify itself for this to work, because a group that opens with a title must not give its description the eyebrow's tighter step.
242
+
243
+ The step between a title and its description follows the size of the title, which is why there are two of it. What a reader sees is not the gap but the gap plus the leading above it, and leading scales with the type: under a display title the leading is most of the space, under a card's title it is half as deep. One value for both makes a card look loose at the size that made a section look right. So space.heading.title-description is the display step and space.heading.title-description-compact is the step at a card's size, and the choice is made by how big the title is rather than by what kind of block it sits in.
244
+
245
+ Every one of those steps is smaller than the gap below the group, and that ordering is what holds the group together as one thing. space.heading.content is the step between a heading group and the content it introduces, and it is the widest measure inside a section: the one gap the eye reads as a change of subject rather than as a continuation.
246
+
247
+ That step is the same whether the content is under the heading or beside it. A split is the same relationship turned on its side — a heading group and the content it introduces — so the space between the two halves is space.heading.content, not a gutter. When the split collapses to one column on a phone the gap becomes vertical again, which is where it started, and nothing has to change for that to be right.
248
+
249
+ space.grid.gutter is between two things of the same kind. Two cards in a row are the same kind; the two halves of a split are not, which is why the gutter is the wrong measure there even when the number would have looked acceptable. The gutter runs on both axes, so a grid reads as an even field rather than as rows with a seam down them.
250
+
251
+ space.inset.card is the card's, not the page's. A row of cards padded differently is a row of different cards, and the fill is the only edge they have. A page composing a row does not get to choose it.
252
+
253
+ Column count is not a breakpoint decision. A row holds as many columns as fit before a column would be narrower than size.grid.column-min, and drops one when they would not. Written as a fixed count that collapses at a breakpoint, a four-up row keeps four columns at every width above the phone and sets its copy two or three words to a line through the whole of the tablet range — and on a narrow desktop, which no breakpoint sits on at all. The threshold is a property of the row rather than of a card: a card fills whatever cell it is given.
254
+
255
+ What this does not cover is the space above and below a section, which is space.section.default and space.section.compact, and the page's own side margin, which is space.inset.page. Those are the section's outside; everything here is its inside.
256
+ Guidance only — cannot be checked automatically.
257
+ - **A section's title is centred over stacked content, starts beside content in columns, and starts on a phone** — Two arrangements, and the title's alignment is decided by which one it is introducing rather than chosen per section.
258
+
259
+ Content stacked under the title — a row of cards, an accordion, a set of steps — takes a centred title. The heading group and the block below it share one axis, so a centred title is symmetric with the thing it names, and the eye drops from the middle of the words to the middle of the set. A title starting at the left over a centred or full-width block reads as belonging to the first column rather than to all of them.
260
+
261
+ Content beside the title — a split, a picture in the other half, anything laid out in columns — takes a title that starts where its content starts. The two share a left edge, and that edge is what says they are one thing read across rather than two stacked. Centring the title there breaks the only alignment the reader has to hold the halves together, and it drifts further from its content the wider the page gets.
262
+
263
+ The heading group is what carries this, not the heading alone. An eyebrow, a title and a description are read as one block and align together; aligning the title without them leaves a centred heading over start-aligned copy, which reads as a mistake rather than as a choice.
264
+
265
+ Centred means all of it, not just the words. A badge, a row of actions, a picture — these are flex children, and a flex child is placed by align-items rather than by text-align, so a block that only sets the text leaves everything that is not text at the start. A hero is the case that shows it: its title and copy centred while its badge and its buttons did not.
266
+
267
+ A capped block centres itself as well as its words. A heading group takes size.heading-group.max, and a cap that is not centred leaves the measure at the start of the column with the words centred inside it — composed, and a long way left of the middle it appears to be in.
268
+
269
+ Both arrangements go to the start on a phone. A centred block reverts below the breakpoint, and the reason is the measure: on a phone the measure is the screen, so a centred title wraps to three or four ragged lines and the eye loses the left edge it was tracking — the same symmetry that reads as composure on a desktop is what makes it hard to scan on a phone. Centring there has to be asked for twice, and a section title is not one of the things that asks: it is centred because there is room for it, and on a phone there is not. Going back to the start means all of it too, and a capped block is the one that hides a leftover: its words go to the start while its measure stays in the middle of the column, which reads as a title still centred over a badge and buttons that are not — the box in the middle and the line inside it at the edge.
270
+
271
+ A hero is a section like any other: its badge, title, copy and actions are one stacked block, so it is centred on a desktop and starts on a phone with everything else.
272
+
273
+ What this is not about is a page whose body is a form or a document. A title over a sign-up form or a guide is not introducing a set of content — it is the first line of the thing itself, and it keeps the alignment the body has, which for running text is the start. The distinction is whether the block below is content the title names or content the title is part of.
274
+ Guidance only — cannot be checked automatically.
275
+ - **Anything a pointer has to hit is at least 24px in both directions** — A control sized by its contents is as big as its contents, and a glyph is chosen for how it reads rather than for how easily it is hit. An icon-only button with no padding is a 16px target — smaller than the pad of a finger, and smaller than the tremor of a hand using a mouse.
276
+
277
+ WCAG 2.2 asks for 24 by 24 CSS pixels at AA. The exceptions are narrower than they look: inline targets inside a sentence are exempt, and so is a small target with 24px of clear space around it — but a clear button sits against the field it empties, and a field is itself a target, so the spacing exemption does not apply to the case that keeps arising.
278
+
279
+ The target and the mark are separate decisions, and conflating them is what produces both faults. Growing the glyph to 24px makes it shout; leaving the button at 16px makes it hard to hit. So the glyph keeps the size that reads correctly beside its text, and the box around it declares a minimum of its own — which is what size.target.min is for.
280
+
281
+ Declared rather than emergent. Padding plus contents does clear 24px in several components today, and it is the weaker statement: it is a size nobody wrote down, so it moves when the type scale or the glyph does, and nothing says it was meant to be a target at all.
282
+ Guidance only — cannot be checked automatically.
283
+
284
+ ## Anti-examples
285
+
286
+ ❌ CardBody for: The whole card is one picture, with no words at all
287
+ This is a body, and it draws its inset region whether or not anything was put in it — a card with no copy gets a band of empty padding above the picture. A picture that is the entire card goes straight into the Card, which pads nothing and clips the corner itself
288
+ → use `Card` instead.
289
+
290
+ ## Example
291
+
292
+ ```tsx
293
+ import { CardBody } from '@deriv-com/dds-marketing'
294
+
295
+ <CardBody title="Balance protection" description="Protect your account from unexpected market swings, with no action needed on your part." />
296
+ ```
297
+
298
+ ## In use
299
+
300
+ ### What a body holds
301
+
302
+ Every region appears only once it is given something. A card with no description is a title with nothing under it rather than a title and an empty line holding space open.
303
+
304
+ ```tsx
305
+ import { CardBody, Icon } from '@deriv-com/dds-marketing'
306
+ import { MemoCircleCheckRegularIcon } from '@deriv-com/quill-icons-web'
307
+
308
+ // A title on its own
309
+ <CardBody title="Tight spreads" />
310
+
311
+ // A title and the sentence under it
312
+ <CardBody title="Tight spreads" description="Competitive pricing on every market, with no hidden markup." />
313
+
314
+ // An eyebrow filing it under a date
315
+ <CardBody eyebrow="14 August 2026" title="A bank can bank your IPO and still refuse your account" />
316
+
317
+ // A mark above the words
318
+ <CardBody mark={<Icon size="xs"><MemoCircleCheckRegularIcon /></Icon>} title="Be reliable" description="We settle all contracts fairly and process every withdrawal promptly." />
319
+ ```
320
+
321
+ ### The eyebrow
322
+
323
+ A short label above the title — a date, a read time, a category. The capitals are the stylesheet's, not the string's, so a screen reader hears the case it was written in. It binds no colour.
324
+
325
+ ```tsx
326
+ import { CardBody } from '@deriv-com/dds-marketing'
327
+
328
+ // A date
329
+ <CardBody eyebrow="14 August 2026" title="A bank can bank your IPO and still refuse your account" />
330
+
331
+ // A read time, over a headline and its summary
332
+ <CardBody eyebrow="3 min read" title="When a boss hypes the boom that sells his product" description="Nvidia's boss says AI has arrived, but insiders sold shares and a top customer is building its own chips." />
333
+
334
+ // The same card without one
335
+ <CardBody title="When a boss hypes the boom that sells his product" description="Nvidia's boss says AI has arrived, but insiders sold shares and a top customer is building its own chips." />
336
+
337
+ // Over the picture — it takes the light ink with the rest
338
+ <CardBody overMedia eyebrow="Technology" title="Tech stocks" description="Companies that lead the charge in digital evolution and breakthroughs." src="/sample-card-image.svg" alt="" />
339
+ ```
340
+
341
+ ### Where the picture goes
342
+
343
+ The copy is inset and the picture is not, which is how both live in one body. mediaPosition reorders the elements themselves, so a screen reader hears what the page shows.
344
+
345
+ ```tsx
346
+ import { CardBody } from '@deriv-com/dds-marketing'
347
+
348
+ // below — the copy introduces the picture
349
+ <CardBody title="Teamwork" description="We value team players that collaborate freely across departments." src="/sample-card-image.svg" alt="Two colleagues talking over a laptop in an open-plan office." />
350
+
351
+ // above — the picture leads and the words caption it
352
+ <CardBody title="Teamwork" description="We value team players that collaborate freely across departments." src="/sample-card-image.svg" alt="" mediaPosition="above" />
353
+ ```
354
+
355
+ ### Copy over the picture
356
+
357
+ overMedia takes the picture out of the column and makes it the ground. It paints a dark fill and a wash under the words, so the copy has something to be read on if the art does not answer for it.
358
+
359
+ ```tsx
360
+ import { CardBody } from '@deriv-com/dds-marketing'
361
+
362
+ // overMedia — the picture is the ground
363
+ <CardBody overMedia title="Teamwork" description="We value team players that collaborate freely across departments." src="/sample-card-image.svg" alt="" />
364
+
365
+ // The same picture in the column, for comparison
366
+ <CardBody title="Teamwork" description="We value team players that collaborate freely across departments." src="/sample-card-image.svg" alt="" />
367
+
368
+ // overMedia with no picture — the ground it falls back to
369
+ <CardBody overMedia title="Teamwork" description="We value team players that collaborate freely across departments." />
370
+ ```
371
+
372
+ ### Flush, for a card with no fill
373
+
374
+ The inline inset holds words off a fill. On Card's `plain` variant there is none, so the picture marks the edge, and `flush` drops that half of the padding to meet it.
375
+
376
+ ```tsx
377
+ import { CardBody } from '@deriv-com/dds-marketing'
378
+
379
+ // flush — the copy meets the picture's edge
380
+ <CardBody flush src="/sample-card-image.svg" alt="" mediaPosition="above" aspect={1.7777777777777777} eyebrow="14 August 2026" title="A bank can bank your IPO and still refuse your account" />
381
+ ```
382
+
383
+ ### Two sizes of card
384
+
385
+ Thirty-two of inset with a twenty-four title over sixteen copy is right for a feature card in a grid. On a rail beside a footer it is most of the card, so all three step down together.
386
+
387
+ ```tsx
388
+ import { CardBody } from '@deriv-com/dds-marketing'
389
+
390
+ // standard — inset 32, title 24, copy 16
391
+ <CardBody title="Deriv App" description="Manage accounts, transfer funds, and access markets anytime, anywhere." />
392
+
393
+ // compact — inset 16, title 16, copy 14
394
+ <CardBody compact title="Deriv App" description="Manage accounts, transfer funds, and access markets anytime, anywhere." />
395
+ ```
396
+
397
+ ### Which way round the ground is
398
+
399
+ Only the eyebrow reads this. Everything else takes the ink the card sets; the eyebrow has one of its own, and quieter is a different colour on a dark card than on a light one.
400
+
401
+ ```tsx
402
+ import { CardBody } from '@deriv-com/dds-marketing'
403
+
404
+ // default — the eyebrow at color.fg.muted
405
+ <CardBody eyebrow="New" title="Deriv App" description="Manage accounts and access markets anytime." />
406
+
407
+ // inverse — it follows the dark ground
408
+ <CardBody tone="inverse" eyebrow="New" title="Deriv App" description="Manage accounts and access markets anytime." />
409
+ ```