@deriv-com/dds-marketing 0.2.0 → 1.0.1

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 (281) hide show
  1. package/.llm/components/accordion.md +9 -1
  2. package/.llm/components/accordionitem.md +9 -1
  3. package/.llm/components/aspectratio.md +9 -1
  4. package/.llm/components/badge.md +9 -1
  5. package/.llm/components/bottomsheet.md +9 -1
  6. package/.llm/components/breadcrumb.md +9 -1
  7. package/.llm/components/breadcrumbitem.md +9 -1
  8. package/.llm/components/button.md +55 -27
  9. package/.llm/components/buttonicon.md +16 -8
  10. package/.llm/components/card.md +16 -2
  11. package/.llm/components/cardbody.md +29 -3
  12. package/.llm/components/cardbutton.md +16 -2
  13. package/.llm/components/checkbox.md +9 -1
  14. package/.llm/components/ctabanner.md +186 -0
  15. package/.llm/components/ctabannerslider.md +204 -0
  16. package/.llm/components/divider.md +9 -1
  17. package/.llm/components/dropdownmenu.md +15 -7
  18. package/.llm/components/faqaccordion.md +217 -0
  19. package/.llm/components/featurebullets.md +254 -0
  20. package/.llm/components/featurecards.md +313 -0
  21. package/.llm/components/featurescroll.md +284 -0
  22. package/.llm/components/featuresplit.md +249 -0
  23. package/.llm/components/filterchip.md +9 -1
  24. package/.llm/components/footer.md +9 -1
  25. package/.llm/components/footergroup.md +9 -1
  26. package/.llm/components/grid.md +9 -1
  27. package/.llm/components/icon.md +21 -3
  28. package/.llm/components/landinghero.md +254 -0
  29. package/.llm/components/link.md +13 -5
  30. package/.llm/components/logocolumns.md +235 -0
  31. package/.llm/components/logorows.md +212 -0
  32. package/.llm/components/menuitem.md +9 -1
  33. package/.llm/components/navbar.md +80 -16
  34. package/.llm/components/navbaritem.md +10 -2
  35. package/.llm/components/navbarmenu.md +9 -1
  36. package/.llm/components/navbarmenugroup.md +9 -1
  37. package/.llm/components/navbarpanel.md +10 -2
  38. package/.llm/components/navbarswitcher.md +10 -2
  39. package/.llm/components/navbarswitcheroption.md +9 -1
  40. package/.llm/components/option.md +9 -1
  41. package/.llm/components/pageheader.md +231 -0
  42. package/.llm/components/pagination.md +27 -90
  43. package/.llm/components/paginationdots.md +215 -0
  44. package/.llm/components/producthero.md +248 -0
  45. package/.llm/components/removablechip.md +9 -1
  46. package/.llm/components/row.md +9 -1
  47. package/.llm/components/scroller.md +9 -1
  48. package/.llm/components/searchinput.md +9 -1
  49. package/.llm/components/segmentedcontrol.md +9 -1
  50. package/.llm/components/segmentedcontrolitem.md +9 -1
  51. package/.llm/components/select.md +9 -1
  52. package/.llm/components/selectchip.md +57 -16
  53. package/.llm/components/spinner.md +9 -1
  54. package/.llm/components/stack.md +9 -1
  55. package/.llm/components/statusdot.md +9 -1
  56. package/.llm/components/subdomainnavbar.md +9 -1
  57. package/.llm/components/tab.md +11 -3
  58. package/.llm/components/table.md +9 -1
  59. package/.llm/components/tablebody.md +9 -1
  60. package/.llm/components/tablecell.md +9 -1
  61. package/.llm/components/tablehead.md +9 -1
  62. package/.llm/components/tableheadercell.md +9 -1
  63. package/.llm/components/tablerow.md +9 -1
  64. package/.llm/components/tablist.md +9 -1
  65. package/.llm/components/testimonialrow.md +235 -0
  66. package/.llm/components/testimonialslider.md +254 -0
  67. package/.llm/components/textarea.md +9 -1
  68. package/.llm/components/textinput.md +9 -1
  69. package/.llm/components/tooltip.md +9 -1
  70. package/.llm/components/typography.md +9 -1
  71. package/.llm/digest/button.md +11 -6
  72. package/.llm/digest/buttonicon.md +2 -2
  73. package/.llm/digest/card.md +1 -0
  74. package/.llm/digest/cardbody.md +3 -1
  75. package/.llm/digest/cardbutton.md +1 -0
  76. package/.llm/digest/ctabanner.md +44 -0
  77. package/.llm/digest/ctabannerslider.md +45 -0
  78. package/.llm/digest/dropdownmenu.md +1 -1
  79. package/.llm/digest/faqaccordion.md +43 -0
  80. package/.llm/digest/featurebullets.md +52 -0
  81. package/.llm/digest/featurecards.md +49 -0
  82. package/.llm/digest/featurescroll.md +52 -0
  83. package/.llm/digest/featuresplit.md +54 -0
  84. package/.llm/digest/landinghero.md +53 -0
  85. package/.llm/digest/logocolumns.md +55 -0
  86. package/.llm/digest/logorows.md +48 -0
  87. package/.llm/digest/navbar.md +18 -3
  88. package/.llm/digest/pageheader.md +49 -0
  89. package/.llm/digest/pagination.md +6 -17
  90. package/.llm/digest/paginationdots.md +43 -0
  91. package/.llm/digest/producthero.md +53 -0
  92. package/.llm/digest/selectchip.md +6 -1
  93. package/.llm/digest/testimonialrow.md +51 -0
  94. package/.llm/digest/testimonialslider.md +51 -0
  95. package/.llm/index.md +24 -3
  96. package/.llm/rules.md +43 -9
  97. package/.llm/tokens.md +56 -12
  98. package/AGENTS.md +32 -8
  99. package/README.md +41 -21
  100. package/dist/components/banner-data.d.ts +38 -0
  101. package/dist/components/banner-data.js +15 -0
  102. package/dist/components/blocks/block-reveal.css +90 -0
  103. package/dist/components/blocks/cta-banner/CtaBanner.css +66 -0
  104. package/dist/components/blocks/cta-banner/CtaBanner.d.ts +22 -0
  105. package/dist/components/blocks/cta-banner/CtaBanner.js +31 -0
  106. package/dist/components/blocks/cta-banner/CtaBanner.types.d.ts +29 -0
  107. package/dist/components/blocks/cta-banner/CtaBanner.types.js +13 -0
  108. package/dist/components/blocks/cta-banner/cta-banner-impl.css +29 -0
  109. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.css +90 -0
  110. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.d.ts +39 -0
  111. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.js +60 -0
  112. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.d.ts +41 -0
  113. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.js +15 -0
  114. package/dist/components/blocks/cta-banner-slider/cta-banner-slider-impl.css +73 -0
  115. package/dist/components/blocks/faq-accordion/FaqAccordion.css +54 -0
  116. package/dist/components/blocks/faq-accordion/FaqAccordion.d.ts +20 -0
  117. package/dist/components/blocks/faq-accordion/FaqAccordion.js +28 -0
  118. package/dist/components/blocks/faq-accordion/FaqAccordion.types.d.ts +25 -0
  119. package/dist/components/blocks/faq-accordion/FaqAccordion.types.js +10 -0
  120. package/dist/components/blocks/faq-accordion/faq-accordion-impl.css +54 -0
  121. package/dist/components/blocks/feature-bullets/FeatureBullets.css +139 -0
  122. package/dist/components/blocks/feature-bullets/FeatureBullets.d.ts +31 -0
  123. package/dist/components/blocks/feature-bullets/FeatureBullets.js +55 -0
  124. package/dist/components/blocks/feature-bullets/FeatureBullets.types.d.ts +39 -0
  125. package/dist/components/blocks/feature-bullets/FeatureBullets.types.js +16 -0
  126. package/dist/components/blocks/feature-bullets/feature-bullets-impl.css +104 -0
  127. package/dist/components/blocks/feature-cards/FeatureCards.css +84 -0
  128. package/dist/components/blocks/feature-cards/FeatureCards.d.ts +24 -0
  129. package/dist/components/blocks/feature-cards/FeatureCards.js +66 -0
  130. package/dist/components/blocks/feature-cards/FeatureCards.types.d.ts +33 -0
  131. package/dist/components/blocks/feature-cards/FeatureCards.types.js +14 -0
  132. package/dist/components/blocks/feature-cards/feature-cards-impl.css +245 -0
  133. package/dist/components/blocks/feature-scroll/FeatureScroll.css +137 -0
  134. package/dist/components/blocks/feature-scroll/FeatureScroll.d.ts +39 -0
  135. package/dist/components/blocks/feature-scroll/FeatureScroll.js +167 -0
  136. package/dist/components/blocks/feature-scroll/FeatureScroll.types.d.ts +40 -0
  137. package/dist/components/blocks/feature-scroll/FeatureScroll.types.js +17 -0
  138. package/dist/components/blocks/feature-scroll/feature-scroll-impl.css +292 -0
  139. package/dist/components/blocks/feature-split/FeatureSplit.css +95 -0
  140. package/dist/components/blocks/feature-split/FeatureSplit.d.ts +30 -0
  141. package/dist/components/blocks/feature-split/FeatureSplit.js +38 -0
  142. package/dist/components/blocks/feature-split/FeatureSplit.types.d.ts +39 -0
  143. package/dist/components/blocks/feature-split/FeatureSplit.types.js +14 -0
  144. package/dist/components/blocks/feature-split/feature-split-impl.css +83 -0
  145. package/dist/components/blocks/landing-hero/LandingHero.css +85 -0
  146. package/dist/components/blocks/landing-hero/LandingHero.d.ts +41 -0
  147. package/dist/components/blocks/landing-hero/LandingHero.js +54 -0
  148. package/dist/components/blocks/landing-hero/LandingHero.types.d.ts +37 -0
  149. package/dist/components/blocks/landing-hero/LandingHero.types.js +15 -0
  150. package/dist/components/blocks/landing-hero/landing-hero-impl.css +355 -0
  151. package/dist/components/blocks/logo-columns/LogoColumns.css +161 -0
  152. package/dist/components/blocks/logo-columns/LogoColumns.d.ts +23 -0
  153. package/dist/components/blocks/logo-columns/LogoColumns.js +46 -0
  154. package/dist/components/blocks/logo-columns/LogoColumns.types.d.ts +46 -0
  155. package/dist/components/blocks/logo-columns/LogoColumns.types.js +18 -0
  156. package/dist/components/blocks/logo-columns/logo-columns-impl.css +188 -0
  157. package/dist/components/blocks/logo-rows/LogoRows.css +122 -0
  158. package/dist/components/blocks/logo-rows/LogoRows.d.ts +20 -0
  159. package/dist/components/blocks/logo-rows/LogoRows.js +43 -0
  160. package/dist/components/blocks/logo-rows/LogoRows.types.d.ts +36 -0
  161. package/dist/components/blocks/logo-rows/LogoRows.types.js +16 -0
  162. package/dist/components/blocks/logo-rows/logo-rows-impl.css +179 -0
  163. package/dist/components/blocks/page-header/PageHeader.css +79 -0
  164. package/dist/components/blocks/page-header/PageHeader.d.ts +34 -0
  165. package/dist/components/blocks/page-header/PageHeader.js +43 -0
  166. package/dist/components/blocks/page-header/PageHeader.types.d.ts +32 -0
  167. package/dist/components/blocks/page-header/PageHeader.types.js +14 -0
  168. package/dist/components/blocks/page-header/page-header-impl.css +176 -0
  169. package/dist/components/blocks/product-hero/ProductHero.css +86 -0
  170. package/dist/components/blocks/product-hero/ProductHero.d.ts +35 -0
  171. package/dist/components/blocks/product-hero/ProductHero.js +48 -0
  172. package/dist/components/blocks/product-hero/ProductHero.types.d.ts +37 -0
  173. package/dist/components/blocks/product-hero/ProductHero.types.js +15 -0
  174. package/dist/components/blocks/product-hero/product-hero-impl.css +354 -0
  175. package/dist/components/blocks/testimonial-row/TestimonialRow.css +245 -0
  176. package/dist/components/blocks/testimonial-row/TestimonialRow.d.ts +20 -0
  177. package/dist/components/blocks/testimonial-row/TestimonialRow.js +128 -0
  178. package/dist/components/blocks/testimonial-row/TestimonialRow.types.d.ts +54 -0
  179. package/dist/components/blocks/testimonial-row/TestimonialRow.types.js +26 -0
  180. package/dist/components/blocks/testimonial-row/testimonial-row-impl.css +195 -0
  181. package/dist/components/blocks/testimonial-slider/TestimonialSlider.css +181 -0
  182. package/dist/components/blocks/testimonial-slider/TestimonialSlider.d.ts +22 -0
  183. package/dist/components/blocks/testimonial-slider/TestimonialSlider.js +36 -0
  184. package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.d.ts +49 -0
  185. package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.js +21 -0
  186. package/dist/components/blocks/testimonial-slider/testimonial-slider-impl.css +202 -0
  187. package/dist/components/blocks/use-reveal.d.ts +46 -0
  188. package/dist/components/blocks/use-reveal.js +120 -0
  189. package/dist/components/blocks/use-rotation.d.ts +62 -0
  190. package/dist/components/blocks/use-rotation.js +176 -0
  191. package/dist/components/core/accordion-item/AccordionItem.css +6 -5
  192. package/dist/components/core/bottom-sheet/BottomSheet.css +1 -1
  193. package/dist/components/core/button/Button.css +63 -16
  194. package/dist/components/core/button/Button.d.ts +14 -12
  195. package/dist/components/core/button/Button.js +43 -14
  196. package/dist/components/core/button/Button.types.d.ts +9 -14
  197. package/dist/components/core/button/button-impl.css +25 -0
  198. package/dist/components/core/button-icon/ButtonIcon.css +31 -15
  199. package/dist/components/core/button-icon/ButtonIcon.d.ts +2 -2
  200. package/dist/components/core/button-icon/ButtonIcon.js +2 -2
  201. package/dist/components/core/button-icon/ButtonIcon.types.d.ts +4 -4
  202. package/dist/components/core/card/Card.css +13 -4
  203. package/dist/components/core/card/Card.types.d.ts +2 -1
  204. package/dist/components/core/card-body/CardBody.css +11 -6
  205. package/dist/components/core/card-body/CardBody.d.ts +1 -1
  206. package/dist/components/core/card-body/CardBody.js +2 -2
  207. package/dist/components/core/card-body/CardBody.types.d.ts +4 -1
  208. package/dist/components/core/card-body/CardBody.types.js +1 -0
  209. package/dist/components/core/card-button/CardButton.css +13 -4
  210. package/dist/components/core/card-button/CardButton.types.d.ts +2 -1
  211. package/dist/components/core/checkbox/Checkbox.css +8 -1
  212. package/dist/components/core/dropdown-menu/DropdownMenu.css +13 -12
  213. package/dist/components/core/dropdown-menu/DropdownMenu.d.ts +5 -3
  214. package/dist/components/core/dropdown-menu/DropdownMenu.js +5 -3
  215. package/dist/components/core/filter-chip/FilterChip.css +2 -1
  216. package/dist/components/core/footer/footer-impl.css +1 -1
  217. package/dist/components/core/footer-group/FooterGroup.css +8 -7
  218. package/dist/components/core/icon/Icon.css +1 -1
  219. package/dist/components/core/link/Link.css +1 -1
  220. package/dist/components/core/link/Link.js +5 -5
  221. package/dist/components/core/menu-item/MenuItem.css +1 -1
  222. package/dist/components/core/navbar/Navbar.css +7 -8
  223. package/dist/components/core/navbar/Navbar.d.ts +17 -1
  224. package/dist/components/core/navbar/Navbar.js +139 -12
  225. package/dist/components/core/navbar/Navbar.types.d.ts +23 -4
  226. package/dist/components/core/navbar/Navbar.types.js +1 -1
  227. package/dist/components/core/navbar/navbar-impl.css +10 -3
  228. package/dist/components/core/navbar/navbar-material.css +96 -0
  229. package/dist/components/core/navbar-item/NavbarItem.css +4 -4
  230. package/dist/components/core/navbar-menu/NavbarMenu.css +7 -5
  231. package/dist/components/core/navbar-menu/NavbarMenu.d.ts +1 -0
  232. package/dist/components/core/navbar-menu/NavbarMenu.js +1 -0
  233. package/dist/components/core/navbar-menu/navbar-menu-impl.css +7 -7
  234. package/dist/components/core/navbar-switcher/NavbarSwitcher.css +6 -5
  235. package/dist/components/core/navbar-switcher/NavbarSwitcher.d.ts +1 -0
  236. package/dist/components/core/navbar-switcher/NavbarSwitcher.js +2 -1
  237. package/dist/components/core/option/Option.css +1 -1
  238. package/dist/components/core/pagination/Pagination.css +1 -75
  239. package/dist/components/core/pagination/Pagination.d.ts +4 -4
  240. package/dist/components/core/pagination/Pagination.js +11 -51
  241. package/dist/components/core/pagination/Pagination.types.d.ts +5 -17
  242. package/dist/components/core/pagination/Pagination.types.js +1 -3
  243. package/dist/components/core/pagination-dots/PaginationDots.css +60 -0
  244. package/dist/components/core/pagination-dots/PaginationDots.d.ts +25 -0
  245. package/dist/components/core/pagination-dots/PaginationDots.js +104 -0
  246. package/dist/components/core/pagination-dots/PaginationDots.types.d.ts +38 -0
  247. package/dist/components/core/pagination-dots/PaginationDots.types.js +9 -0
  248. package/dist/components/core/removable-chip/RemovableChip.css +3 -3
  249. package/dist/components/core/search-input/SearchInput.css +1 -1
  250. package/dist/components/core/segmented-control/SegmentedControl.css +1 -1
  251. package/dist/components/core/segmented-control-item/SegmentedControlItem.css +1 -1
  252. package/dist/components/core/select/Select.css +2 -1
  253. package/dist/components/core/select-chip/SelectChip.css +14 -7
  254. package/dist/components/core/select-chip/SelectChip.d.ts +1 -1
  255. package/dist/components/core/select-chip/SelectChip.js +7 -4
  256. package/dist/components/core/select-chip/SelectChip.types.d.ts +7 -1
  257. package/dist/components/core/select-chip/SelectChip.types.js +1 -1
  258. package/dist/components/core/select-chip/select-chip-impl.css +14 -3
  259. package/dist/components/core/status-dot/StatusDot.css +1 -1
  260. package/dist/components/core/subdomain-navbar/SubdomainNavbar.css +3 -3
  261. package/dist/components/core/tab/Tab.css +1 -1
  262. package/dist/components/core/tab/Tab.types.d.ts +1 -1
  263. package/dist/components/core/tab-list/TabList.css +1 -1
  264. package/dist/components/core/table/table-impl.css +36 -14
  265. package/dist/components/core/table-header-cell/TableHeaderCell.css +5 -5
  266. package/dist/components/core/text-area/TextArea.css +1 -1
  267. package/dist/components/core/text-input/TextInput.css +1 -1
  268. package/dist/components/core/tooltip/Tooltip.css +1 -1
  269. package/dist/components/core/typography/Typography.css +5 -5
  270. package/dist/components/index.d.ts +35 -0
  271. package/dist/components/index.js +30 -0
  272. package/dist/components/logo-data.d.ts +24 -0
  273. package/dist/components/logo-data.js +11 -0
  274. package/dist/components/scroll-data.d.ts +64 -0
  275. package/dist/components/scroll-data.js +17 -0
  276. package/dist/components/testimonial-row-data.d.ts +51 -0
  277. package/dist/components/testimonial-row-data.js +11 -0
  278. package/dist/components/testimonial-slider-data.d.ts +26 -0
  279. package/dist/components/testimonial-slider-data.js +10 -0
  280. package/dist/marketing.css +385 -14
  281. package/package.json +1 -6
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The messages a CtaBannerSlider rotates between.
3
+ *
4
+ * Exported from the package for the reason `scroll-data.ts` is: a block whose content is a list is
5
+ * one whose consumer builds a value before passing it, and building it without the type means
6
+ * writing the shape out twice.
7
+ *
8
+ * A record rather than a component per slide, by decision on 2026-10-01. A slide was CtaBannerSlide,
9
+ * a child that took its actions as elements; it existed only so a slide could carry a Button, and it
10
+ * was a second component to learn for what is one block. As data, the set can come from a CMS, and
11
+ * the slider draws the buttons itself — the primary as Button variant="inverse", the second as the
12
+ * white-tinted secondary, both at tone="brand" — so no slide can put a coral button on the coral
13
+ * ground. What it costs is the slot: an action is a label and a href, not a Button the page composed.
14
+ */
15
+ /** A way onward from a slide: the words on the button and where it goes. */
16
+ export interface CtaBannerAction {
17
+ /** What the button says, as a verb — 'Open account', 'Try TradersView'. */
18
+ label: string;
19
+ /** Where it goes. A slide's action is always a link; a banner that runs code on press is not a banner. */
20
+ href: string;
21
+ }
22
+ /** One message in a CtaBannerSlider: the headline, the line under it, and what it asks for. */
23
+ export interface CtaBannerSlide {
24
+ /**
25
+ * The message, in a few words. Short enough to take in as the slide arrives; drawn as a heading
26
+ * at font.h1, so a reader moving by heading finds the message in view.
27
+ */
28
+ title: string;
29
+ /** A line saying why the action is worth taking. A sentence, not a paragraph. */
30
+ description?: string;
31
+ /** The action the message asks for, drawn as Button variant="inverse" tone="brand" — near-black in both themes. */
32
+ primaryAction?: CtaBannerAction;
33
+ /**
34
+ * A second, lesser action, drawn as the white-tinted secondary, Button tone="brand". Drawn only beside a
35
+ * primary: a slide with one action makes it the primary, the rule Navbar holds its pair to.
36
+ */
37
+ secondaryAction?: CtaBannerAction;
38
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The messages a CtaBannerSlider rotates between.
3
+ *
4
+ * Exported from the package for the reason `scroll-data.ts` is: a block whose content is a list is
5
+ * one whose consumer builds a value before passing it, and building it without the type means
6
+ * writing the shape out twice.
7
+ *
8
+ * A record rather than a component per slide, by decision on 2026-10-01. A slide was CtaBannerSlide,
9
+ * a child that took its actions as elements; it existed only so a slide could carry a Button, and it
10
+ * was a second component to learn for what is one block. As data, the set can come from a CMS, and
11
+ * the slider draws the buttons itself — the primary as Button variant="inverse", the second as the
12
+ * white-tinted secondary, both at tone="brand" — so no slide can put a coral button on the coral
13
+ * ground. What it costs is the slot: an action is a label and a href, not a Button the page composed.
14
+ */
15
+ export {};
@@ -0,0 +1,90 @@
1
+ /*
2
+ * The arrival every block shares, defined once.
3
+ *
4
+ * A section's parts wait a short way below where they land and come up in reading order as a
5
+ * reader reaches the block. It is the only motion these blocks have in common, and a copy per
6
+ * block is how six sections come to disagree about what arriving looks like — one tuned, five not,
7
+ * and nothing to say which is the house answer. So the movement is stated here and each block's
8
+ * own stylesheet says which of its parts make it.
9
+ *
10
+ * Imported by each block's component, which is what puts it in the bundle once however many
11
+ * blocks a page uses.
12
+ *
13
+ * `data-revealed` goes on the box that is watched — see `use-reveal.ts`, which explains why
14
+ * neither trigger CSS can offer on its own is enough. `data-reveal-at` marks each part inside it
15
+ * that arrives, and the same number is set as `--dds-reveal-at` for the arithmetic: an attribute
16
+ * is what CSS can select on, and a custom property is what it can multiply. Two spellings of one
17
+ * index, each doing the job the other cannot.
18
+ *
19
+ * The waiting state is `[data-revealed="false"]` rather than the absence of a value, so a block
20
+ * rendered before any script has run — or where none ever will — is visible rather than hidden.
21
+ * Content behind a script is the one failure this could have that is worse than no motion.
22
+ *
23
+ * Every value is a token, and three of them are the set this system already had for the job:
24
+ * `motion.duration.reveal` is described as "content appearing on scroll, section reveals, feature
25
+ * items fading in", `motion.easing.reveal` is its curve, and `motion.translate.reveal` is the
26
+ * distance. `opacity.hidden` is what a part waits at and `motion.duration.stagger` is the step
27
+ * between one part and the next.
28
+ *
29
+ * The duration was `motion.duration.dramatic` for a while, which is the role for an editorial hero
30
+ * entrance — right while the opening bands were on a timer and wrong once every block arrived on a
31
+ * reader reaching it. Two roles were named for these two triggers and the work had drifted onto
32
+ * the wrong one.
33
+ */
34
+ /*
35
+ * Waiting is instant; only arriving is animated.
36
+ *
37
+ * A transition is decided by the state a thing is moving *to*, so declaring it on both states
38
+ * animates the way in and the way out alike — and the way out is not a thing anybody should see.
39
+ * A block is marked as waiting once, in a layout effect, before the browser has painted; if that
40
+ * ever lands a frame late the block has already been drawn, and an animated hide turns one dropped
41
+ * frame into three-quarters of a second of the section fading away in front of a reader. That is
42
+ * exactly what it looked like.
43
+ *
44
+ * `transition: none` here rather than nothing, because the arrived rule below is what carries the
45
+ * timings and a part moving back to waiting must not inherit them.
46
+ *
47
+ * Both spellings on every rule: a part is usually inside the box that is watched, and sometimes it
48
+ * is that box. FeatureScroll's heading is the case — the section watches the heading itself, and
49
+ * wrapping it in something whose only job was to be a container would put a box in the markup to
50
+ * satisfy a stylesheet.
51
+ */
52
+ :where([data-dds-context="marketing"]) [data-revealed='false'] [data-reveal-at],
53
+ :where([data-dds-context="marketing"]) [data-revealed='false'][data-reveal-at] {
54
+ opacity: var(--opacity-hidden);
55
+ transition: none;
56
+ translate: var(--motion-translate-reveal);
57
+ }
58
+
59
+ /*
60
+ * Each part a step behind the one before it.
61
+ *
62
+ * On the way in only. The delay is declared on the arrived state, which is the state a part is
63
+ * transitioning *to* — so a block that is somehow put back to waiting drops without a queue.
64
+ *
65
+ * A block arrives as one thing that happens to be made of parts, which is what the step size is
66
+ * for: at a tenth of a second, five parts trail the first by less than half a second, well inside
67
+ * the movement's own duration. A longer step would be the section assembling itself while a reader
68
+ * waits for the sentence they came to read.
69
+ */
70
+ :where([data-dds-context="marketing"]) [data-revealed='true'] [data-reveal-at],
71
+ :where([data-dds-context="marketing"]) [data-revealed='true'][data-reveal-at] {
72
+ transition-delay: calc(var(--dds-reveal-at, 0) * var(--motion-duration-stagger));
73
+ transition-duration: var(--motion-duration-reveal);
74
+ transition-property: opacity, translate;
75
+ transition-timing-function: var(--motion-easing-reveal);
76
+ }
77
+
78
+ /*
79
+ * A reader who asked for less movement gets none of it.
80
+ *
81
+ * The hook declines to hide anything under this preference, so the parts are never in the waiting
82
+ * state to begin with. This is the second half of the same answer: if a part is somehow marked as
83
+ * waiting, it still arrives without travelling and without queueing behind its neighbours.
84
+ */
85
+ @media (prefers-reduced-motion: reduce) {
86
+ :where([data-dds-context="marketing"]) [data-revealed] [data-reveal-at],
87
+ :where([data-dds-context="marketing"]) [data-revealed][data-reveal-at] {
88
+ transition: none;
89
+ }
90
+ }
@@ -0,0 +1,66 @@
1
+ /* GENERATED from ctabanner.contract.json. Do not edit. */
2
+
3
+ :where([data-dds-context="marketing"]) .dds-ctabanner {
4
+ box-sizing: border-box;
5
+ container-type: inline-size;
6
+ display: flex;
7
+ inline-size: 100%;
8
+ justify-content: center;
9
+ position: relative;
10
+ background-color: var(--color-bg-brand);
11
+ color: var(--color-fg-on-brand);
12
+ }
13
+
14
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__inner {
15
+ box-sizing: border-box;
16
+ display: flex;
17
+ flex-direction: column;
18
+ inline-size: 100%;
19
+ min-inline-size: 0;
20
+ max-inline-size: var(--size-content-max);
21
+ padding-block: var(--space-section-default);
22
+ padding-inline: var(--space-inset-page);
23
+ }
24
+
25
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__content {
26
+ display: flex;
27
+ flex-direction: column;
28
+ min-inline-size: 0;
29
+ row-gap: var(--space-heading-description-actions);
30
+ }
31
+
32
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__text {
33
+ display: flex;
34
+ flex-direction: column;
35
+ min-inline-size: 0;
36
+ max-inline-size: var(--size-measure-heading);
37
+ }
38
+
39
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__title {
40
+ margin-block: 0;
41
+ text-wrap: balance;
42
+ font-family: var(--font-h1-family);
43
+ font-size: var(--font-h1-size);
44
+ font-weight: var(--font-h1-weight);
45
+ letter-spacing: var(--font-h1-letter-spacing);
46
+ line-height: var(--font-h1-line-height);
47
+ margin-block-end: var(--space-heading-title-description);
48
+ }
49
+
50
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__description {
51
+ margin-block: 0;
52
+ font-family: var(--font-body-lg-family);
53
+ font-size: var(--font-body-lg-size);
54
+ font-weight: var(--font-body-lg-weight);
55
+ letter-spacing: var(--font-body-lg-letter-spacing);
56
+ line-height: var(--font-body-lg-line-height);
57
+ max-inline-size: var(--size-measure-description);
58
+ }
59
+
60
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__actions {
61
+ display: flex;
62
+ flex-wrap: wrap;
63
+ column-gap: var(--space-actions-gap);
64
+ row-gap: var(--space-actions-gap);
65
+ }
66
+
@@ -0,0 +1,22 @@
1
+ import './CtaBanner.css';
2
+ import './cta-banner-impl.css';
3
+ import '../block-reveal.css';
4
+ import { type CtaBannerProps } from './CtaBanner.types.js';
5
+ export type { CtaBannerProps };
6
+ /**
7
+ * A full-bleed coral band carrying one promotion and the action it asks for.
8
+ *
9
+ * The reference site's CoralBanner in its single form, named for what it is for. The ground is
10
+ * color.bg.brand and the ink color.fg.on-brand, both the same in light and dark, so the banner is
11
+ * the same coral whatever theme the reader is in. Nothing moves: two or three promotions to rotate
12
+ * between are CtaBannerSlider, which is this band with a slider in it — the same column, the same
13
+ * headline and line, so a page can carry either and read the same.
14
+ *
15
+ * The region is named by its headline, the way PageHeader's is, so a reader can jump to the band
16
+ * and past it. `'use client'` only for `useId`, which ties the region to its headline — the same
17
+ * reason PageHeader carries it.
18
+ *
19
+ * It arrives the way every block does, and the way CtaBannerSlider's slides do: block-reveal.css
20
+ * brings the headline, the line and the actions up a step apart once the band is in view.
21
+ */
22
+ export declare function CtaBanner({ title, headingLevel, description, actions, }: CtaBannerProps): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from 'react';
4
+ import './CtaBanner.css';
5
+ import './cta-banner-impl.css';
6
+ import '../block-reveal.css';
7
+ import { arriving, useReveal } from '../use-reveal.js';
8
+ import { given } from '../../given.js';
9
+ import { ctaBannerDefaults, ctaBannerParts } from './CtaBanner.types.js';
10
+ /**
11
+ * A full-bleed coral band carrying one promotion and the action it asks for.
12
+ *
13
+ * The reference site's CoralBanner in its single form, named for what it is for. The ground is
14
+ * color.bg.brand and the ink color.fg.on-brand, both the same in light and dark, so the banner is
15
+ * the same coral whatever theme the reader is in. Nothing moves: two or three promotions to rotate
16
+ * between are CtaBannerSlider, which is this band with a slider in it — the same column, the same
17
+ * headline and line, so a page can carry either and read the same.
18
+ *
19
+ * The region is named by its headline, the way PageHeader's is, so a reader can jump to the band
20
+ * and past it. `'use client'` only for `useId`, which ties the region to its headline — the same
21
+ * reason PageHeader carries it.
22
+ *
23
+ * It arrives the way every block does, and the way CtaBannerSlider's slides do: block-reveal.css
24
+ * brings the headline, the line and the actions up a step apart once the band is in view.
25
+ */
26
+ export function CtaBanner({ title, headingLevel = ctaBannerDefaults.headingLevel, description, actions, }) {
27
+ const titleId = useId();
28
+ const [band, revealed] = useReveal();
29
+ const Title = headingLevel === 'h3' ? 'h3' : 'h2';
30
+ return (_jsx("section", { className: ctaBannerParts.root, "aria-labelledby": titleId, children: _jsx("div", { className: ctaBannerParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: ctaBannerParts.content, children: [_jsxs("div", { className: ctaBannerParts.text, children: [_jsx(Title, { className: ctaBannerParts.title, id: titleId, ...arriving(0), children: title }), given(description) ? (_jsx("p", { className: ctaBannerParts.description, ...arriving(1), children: description })) : null] }), actions ? (_jsx("div", { className: ctaBannerParts.actions, ...arriving(2), children: actions })) : null] }) }) }));
31
+ }
@@ -0,0 +1,29 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface CtaBannerOwnProps {
3
+ /** Always — the message, in a few words. Short enough to take in at a glance; a line break goes where the words pause, not where the box runs out. */
4
+ title: string;
5
+ /**
6
+ * `h2` — The default: a banner is a section of the page, under the page's own h1
7
+ * `h3` — A banner nested inside a section that already carries the h2 it belongs to
8
+ */
9
+ headingLevel?: 'h2' | 'h3';
10
+ /** A line saying why the action is worth taking — what the reader gets, or how little it costs them. */
11
+ description?: string;
12
+ /** The one action the message asks for, or two at most. The coral is the banner's ground, so the primary is Button variant="inverse" tone="brand" — a primary Button is coral on coral, and the tone keeps it near-black in both themes — and a second is Button variant="secondary" tone="brand" — a white tint with a white label, fixed in both themes like the band. */
13
+ actions?: ReactNode;
14
+ }
15
+ export type CtaBannerProps = CtaBannerOwnProps;
16
+ /** The class each part carries. Apply these — do not retype them. */
17
+ export declare const ctaBannerParts: {
18
+ readonly root: "dds-ctabanner";
19
+ readonly inner: "dds-ctabanner__inner";
20
+ readonly content: "dds-ctabanner__content";
21
+ readonly text: "dds-ctabanner__text";
22
+ readonly title: "dds-ctabanner__title";
23
+ readonly description: "dds-ctabanner__description";
24
+ readonly actions: "dds-ctabanner__actions";
25
+ };
26
+ /** Generated so defaults cannot drift from the contract. */
27
+ export declare const ctaBannerDefaults: {
28
+ readonly headingLevel: "h2";
29
+ };
@@ -0,0 +1,13 @@
1
+ // GENERATED from cta-banner.contract.json. Do not edit.
2
+ /** The class each part carries. Apply these — do not retype them. */
3
+ export const ctaBannerParts = {
4
+ root: 'dds-ctabanner',
5
+ inner: 'dds-ctabanner__inner',
6
+ content: 'dds-ctabanner__content',
7
+ text: 'dds-ctabanner__text',
8
+ title: 'dds-ctabanner__title',
9
+ description: 'dds-ctabanner__description',
10
+ actions: 'dds-ctabanner__actions',
11
+ };
12
+ /** Generated so defaults cannot drift from the contract. */
13
+ export const ctaBannerDefaults = { headingLevel: 'h2' };
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Scoped to this package, like the generated sheet beside it.
3
+ */
4
+
5
+ /*
6
+ * Starts on a phone, centred once the band is wide enough to hold a line.
7
+ *
8
+ * PageHeader's rule and its reason: centred text starts every line at a different edge, which costs
9
+ * little across a wide measure and a great deal across a narrow one. CtaBannerSlider centres at the
10
+ * same width, so a page can carry either band and read the same.
11
+ *
12
+ * The text and the line under it are capped narrower than the column, so `margin-inline: auto` is
13
+ * what centres those boxes rather than their words inside a box left at the start edge.
14
+ */
15
+ @container (min-width: 48rem) {
16
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__content {
17
+ align-items: center;
18
+ text-align: center;
19
+ }
20
+
21
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__text,
22
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__description {
23
+ margin-inline: auto;
24
+ }
25
+
26
+ :where([data-dds-context="marketing"]) .dds-ctabanner .dds-ctabanner__actions {
27
+ justify-content: center;
28
+ }
29
+ }
@@ -0,0 +1,90 @@
1
+ /* GENERATED from ctabannerslider.contract.json. Do not edit. */
2
+
3
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider {
4
+ box-sizing: border-box;
5
+ container-type: inline-size;
6
+ display: flex;
7
+ inline-size: 100%;
8
+ justify-content: center;
9
+ overflow: hidden;
10
+ position: relative;
11
+ background-color: var(--color-bg-brand);
12
+ color: var(--color-fg-on-brand);
13
+ }
14
+
15
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider .dds-ctabannerslider__inner {
16
+ box-sizing: border-box;
17
+ display: flex;
18
+ flex-direction: column;
19
+ inline-size: 100%;
20
+ min-inline-size: 0;
21
+ max-inline-size: var(--size-content-max);
22
+ padding-block: var(--space-section-default);
23
+ padding-inline: var(--space-inset-page);
24
+ }
25
+
26
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider .dds-ctabannerslider__track {
27
+ display: grid;
28
+ transition-property: none;
29
+ transition-duration: var(--motion-duration-slow);
30
+ transition-timing-function: var(--motion-easing-shift);
31
+ }
32
+
33
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider .dds-ctabannerslider__slide {
34
+ box-sizing: border-box;
35
+ display: flex;
36
+ flex: none;
37
+ flex-direction: column;
38
+ inline-size: 100%;
39
+ min-inline-size: 0;
40
+ row-gap: var(--space-heading-description-actions);
41
+ }
42
+
43
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider .dds-ctabannerslider__text {
44
+ display: flex;
45
+ flex-direction: column;
46
+ min-inline-size: 0;
47
+ max-inline-size: var(--size-measure-heading);
48
+ }
49
+
50
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider .dds-ctabannerslider__title {
51
+ margin-block: 0;
52
+ text-wrap: balance;
53
+ font-family: var(--font-h1-family);
54
+ font-size: var(--font-h1-size);
55
+ font-weight: var(--font-h1-weight);
56
+ letter-spacing: var(--font-h1-letter-spacing);
57
+ line-height: var(--font-h1-line-height);
58
+ margin-block-end: var(--space-heading-title-description);
59
+ }
60
+
61
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider .dds-ctabannerslider__description {
62
+ margin-block: 0;
63
+ font-family: var(--font-body-lg-family);
64
+ font-size: var(--font-body-lg-size);
65
+ font-weight: var(--font-body-lg-weight);
66
+ letter-spacing: var(--font-body-lg-letter-spacing);
67
+ line-height: var(--font-body-lg-line-height);
68
+ max-inline-size: var(--size-measure-description);
69
+ }
70
+
71
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider .dds-ctabannerslider__actions {
72
+ display: flex;
73
+ flex-wrap: wrap;
74
+ column-gap: var(--space-actions-gap);
75
+ row-gap: var(--space-actions-gap);
76
+ }
77
+
78
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider .dds-ctabannerslider__controls {
79
+ align-items: center;
80
+ display: flex;
81
+ flex-wrap: wrap;
82
+ column-gap: var(--space-actions-gap);
83
+ margin-block-start: var(--space-heading-description-actions);
84
+ }
85
+
86
+ @media (prefers-reduced-motion: reduce) {
87
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider,
88
+ :where([data-dds-context="marketing"]) .dds-ctabannerslider * { transition: none !important; }
89
+ }
90
+
@@ -0,0 +1,39 @@
1
+ import './CtaBannerSlider.css';
2
+ import './cta-banner-slider-impl.css';
3
+ import '../block-reveal.css';
4
+ import { type CtaBannerSliderProps } from './CtaBannerSlider.types.js';
5
+ export type { CtaBannerSliderProps };
6
+ /**
7
+ * CtaBanner's layout with a slider in it: the same coral band, rotating between a few promotions.
8
+ *
9
+ * The reference site's CoralBanner in its carousel form. The ground is color.bg.brand and the ink
10
+ * color.fg.on-brand, both the same in light and dark, exactly as CtaBanner paints them. A single
11
+ * promotion is CtaBanner; this is for two or three, and handed only one it draws it still rather
12
+ * than as a carousel with nowhere to go.
13
+ *
14
+ * One slide is in view. The slides are stacked in one place, and a change is the new one fading in
15
+ * where the old one stood — no travel, the old one's words gone at once. PaginationDots says
16
+ * where the reader is and moves to any slide pressed; with the swipe, it is the whole of how a reader
17
+ * moves the slider — there are no previous and next steps, by decision.
18
+ * Autoplay is off unless asked for. When it is on, rotation holds while the pointer is over the
19
+ * band or focus is inside it, never runs for a reader who asked for less motion, and stops for good
20
+ * once the reader presses anything in it. There is no pause control, by decision, so that press is
21
+ * the reader's only way to stop it, and nothing on screen says so — the contract records what that
22
+ * does and does not give WCAG 2.2.2. The default keeps a slider nobody configured still.
23
+ *
24
+ * Every slide out of view is inert and hidden from assistive technology, so Tab never reaches a
25
+ * button the reader cannot see, and the one in view is named by its position.
26
+ *
27
+ * The slides arrive as data and the banner draws them, buttons included: the primary as Button
28
+ * variant="inverse" and the second as the white-tinted secondary, both at tone="brand" so neither
29
+ * switches with the theme on a band that does not. A slide was once a
30
+ * child component of its own, which existed only to carry its Button; as a record it is one
31
+ * component to learn, and no slide can put a coral button on the coral ground.
32
+ *
33
+ * A slide's words arrive the way every block's do — block-reveal.css, the house answer — and they do
34
+ * it each time a slide comes into view, not only when the band first scrolls in: the slide in view
35
+ * is the one marked arrived, so a change puts the new slide's headline, line and actions through
36
+ * the same rise, a step apart. The slide leaving drops to waiting at once, as that sheet has every
37
+ * part do, so the outgoing words never travel.
38
+ */
39
+ export declare function CtaBannerSlider({ slides, headingLevel, autoplay, label, controlsLabel, slideLabel, }: CtaBannerSliderProps): import("react").JSX.Element | null;
@@ -0,0 +1,60 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import './CtaBannerSlider.css';
4
+ import './cta-banner-slider-impl.css';
5
+ import '../block-reveal.css';
6
+ import { arriving, useReveal } from '../use-reveal.js';
7
+ import { useRotation } from '../use-rotation.js';
8
+ import { given } from '../../given.js';
9
+ import { Button } from '../../core/button/Button.js';
10
+ import { PaginationDots } from '../../core/pagination-dots/PaginationDots.js';
11
+ import { ctaBannerSliderDefaults, ctaBannerSliderParts, } from './CtaBannerSlider.types.js';
12
+ /**
13
+ * CtaBanner's layout with a slider in it: the same coral band, rotating between a few promotions.
14
+ *
15
+ * The reference site's CoralBanner in its carousel form. The ground is color.bg.brand and the ink
16
+ * color.fg.on-brand, both the same in light and dark, exactly as CtaBanner paints them. A single
17
+ * promotion is CtaBanner; this is for two or three, and handed only one it draws it still rather
18
+ * than as a carousel with nowhere to go.
19
+ *
20
+ * One slide is in view. The slides are stacked in one place, and a change is the new one fading in
21
+ * where the old one stood — no travel, the old one's words gone at once. PaginationDots says
22
+ * where the reader is and moves to any slide pressed; with the swipe, it is the whole of how a reader
23
+ * moves the slider — there are no previous and next steps, by decision.
24
+ * Autoplay is off unless asked for. When it is on, rotation holds while the pointer is over the
25
+ * band or focus is inside it, never runs for a reader who asked for less motion, and stops for good
26
+ * once the reader presses anything in it. There is no pause control, by decision, so that press is
27
+ * the reader's only way to stop it, and nothing on screen says so — the contract records what that
28
+ * does and does not give WCAG 2.2.2. The default keeps a slider nobody configured still.
29
+ *
30
+ * Every slide out of view is inert and hidden from assistive technology, so Tab never reaches a
31
+ * button the reader cannot see, and the one in view is named by its position.
32
+ *
33
+ * The slides arrive as data and the banner draws them, buttons included: the primary as Button
34
+ * variant="inverse" and the second as the white-tinted secondary, both at tone="brand" so neither
35
+ * switches with the theme on a band that does not. A slide was once a
36
+ * child component of its own, which existed only to carry its Button; as a record it is one
37
+ * component to learn, and no slide can put a coral button on the coral ground.
38
+ *
39
+ * A slide's words arrive the way every block's do — block-reveal.css, the house answer — and they do
40
+ * it each time a slide comes into view, not only when the band first scrolls in: the slide in view
41
+ * is the one marked arrived, so a change puts the new slide's headline, line and actions through
42
+ * the same rise, a step apart. The slide leaving drops to waiting at once, as that sheet has every
43
+ * part do, so the outgoing words never travel.
44
+ */
45
+ export function CtaBannerSlider({ slides, headingLevel = ctaBannerSliderDefaults.headingLevel, autoplay = ctaBannerSliderDefaults.autoplay, label = ctaBannerSliderDefaults.label, controlsLabel = ctaBannerSliderDefaults.controlsLabel, slideLabel = ctaBannerSliderDefaults.slideLabel, }) {
46
+ const Title = headingLevel === 'h3' ? 'h3' : 'h2';
47
+ const count = slides.length;
48
+ // The band arriving on screen, as every block does; until then no slide has arrived.
49
+ const [band, revealed] = useReveal();
50
+ // Which slide is in view, and every way a reader moves, holds or stops the set — shared with
51
+ // TestimonialSlider, so the two rotate by one set of rules. See use-rotation.ts.
52
+ const { current, rotating, root, region, track, item, away, dots } = useRotation(count, autoplay);
53
+ // Nothing to show is nothing drawn: a named region with no message in it is a landmark that
54
+ // leads a screen reader to an empty band.
55
+ if (count === 0)
56
+ return null;
57
+ return (_jsx("section", { ref: root, className: ctaBannerSliderParts.root, "aria-label": label, ...region, children: _jsxs("div", { className: ctaBannerSliderParts.inner, ref: band, children: [_jsx("div", { className: ctaBannerSliderParts.track, ...track, children: slides.map((slide, at) => (_jsxs("div", { className: ctaBannerSliderParts.slide, ...item(at), "data-revealed": revealed && !away(at), children: [_jsxs("div", { className: ctaBannerSliderParts.text, children: [_jsx(Title, { className: ctaBannerSliderParts.title, ...arriving(0), children: slide.title }), given(slide.description) ? (_jsx("p", { className: ctaBannerSliderParts.description, ...arriving(1), children: slide.description })) : null] }), slide.primaryAction ? (_jsxs("div", { className: ctaBannerSliderParts.actions, ...arriving(2), children: [_jsx(Button, { variant: "inverse", tone: "brand", href: slide.primaryAction.href, children: slide.primaryAction.label }), slide.secondaryAction ? (_jsx(Button, { variant: "secondary", tone: "brand", href: slide.secondaryAction.href, children: slide.secondaryAction.label })) : null] })) : null] }, at))) }), rotating ? (_jsx("div", { className: ctaBannerSliderParts.controls, children: _jsx(PaginationDots, { ...dots,
58
+ /* A dot pressed stops the dots' own rotation; the band's press handler stops this. */
59
+ label: controlsLabel, itemLabel: slideLabel }) })) : null] }) }));
60
+ }
@@ -0,0 +1,41 @@
1
+ import type { CtaBannerSlide } from '../../banner-data.js';
2
+ export interface CtaBannerSliderOwnProps {
3
+ /** Always. The messages, in the order they rotate — two or three. Each is a headline, a line under it, and up to two actions as a label and a href: the banner draws the primary as Button variant="inverse" tone="brand", near-black in both themes, and the second as the white-tinted secondary, Button tone="brand", so no slide can put a coral button on the coral ground. A secondary is drawn only beside a primary — one action is the primary.
4
+
5
+ An empty list draws nothing — no region with nothing in it. A list of records rather than a child per slide, by decision: the set can come from a CMS, and there is one component to learn rather than two. */
6
+ slides: CtaBannerSlide[];
7
+ /**
8
+ * `h2` — The default: a banner is a section of the page, under the page's own h1
9
+ * `h3` — A banner nested inside a section that already carries the h2 it belongs to
10
+ */
11
+ headingLevel?: 'h2' | 'h3';
12
+ /** Whether it advances on its own, holding each slide for motion.duration.dwell. Off by default, so a slider nobody configured stays still. On, it holds while the pointer is over it or focus is inside it, never moves for a reader who asked for less motion, and stops for good once the reader presses anything in it — a slide, its action, a dot — or swipes it. A press stops it for good — the WAI carousel pattern's rule that a reader who has interacted is reading, not watching. That gives a reader a way to stop the rotation, which WCAG 2.2.2 asks for, but not a visible one: nothing says a press will stop it, so a page that needs 2.2.2 met plainly should still offer its own pause, or leave autoplay off. */
13
+ autoplay?: boolean;
14
+ /** The name the banner is announced by — a region a screen reader can jump to and skip. Name what it holds, not that it is a banner: 'Promotions', 'Offers'. Translate it with the page. */
15
+ label?: string;
16
+ /** The name the dots are announced by, as a group inside the banner. Its own name rather than the banner's, so a screen reader moving into the dots hears what they are rather than 'Promotions' a second time. Translate it with the page, like label. */
17
+ controlsLabel?: string;
18
+ /** The word each dot is announced by, before its number — 'Slide 2'. Translate it with the page, as controlsLabel is; a page that translates only the group's name still has every dot announced in English. */
19
+ slideLabel?: string;
20
+ }
21
+ export type CtaBannerSliderProps = CtaBannerSliderOwnProps;
22
+ /** The class each part carries. Apply these — do not retype them. */
23
+ export declare const ctaBannerSliderParts: {
24
+ readonly root: "dds-ctabannerslider";
25
+ readonly inner: "dds-ctabannerslider__inner";
26
+ readonly track: "dds-ctabannerslider__track";
27
+ readonly slide: "dds-ctabannerslider__slide";
28
+ readonly text: "dds-ctabannerslider__text";
29
+ readonly title: "dds-ctabannerslider__title";
30
+ readonly description: "dds-ctabannerslider__description";
31
+ readonly actions: "dds-ctabannerslider__actions";
32
+ readonly controls: "dds-ctabannerslider__controls";
33
+ };
34
+ /** Generated so defaults cannot drift from the contract. */
35
+ export declare const ctaBannerSliderDefaults: {
36
+ readonly headingLevel: "h2";
37
+ readonly autoplay: false;
38
+ readonly label: "Promotions";
39
+ readonly controlsLabel: "Slides";
40
+ readonly slideLabel: "Slide";
41
+ };
@@ -0,0 +1,15 @@
1
+ // GENERATED from cta-banner-slider.contract.json. Do not edit.
2
+ /** The class each part carries. Apply these — do not retype them. */
3
+ export const ctaBannerSliderParts = {
4
+ root: 'dds-ctabannerslider',
5
+ inner: 'dds-ctabannerslider__inner',
6
+ track: 'dds-ctabannerslider__track',
7
+ slide: 'dds-ctabannerslider__slide',
8
+ text: 'dds-ctabannerslider__text',
9
+ title: 'dds-ctabannerslider__title',
10
+ description: 'dds-ctabannerslider__description',
11
+ actions: 'dds-ctabannerslider__actions',
12
+ controls: 'dds-ctabannerslider__controls',
13
+ };
14
+ /** Generated so defaults cannot drift from the contract. */
15
+ export const ctaBannerSliderDefaults = { headingLevel: 'h2', autoplay: false, label: 'Promotions', controlsLabel: 'Slides', slideLabel: 'Slide' };