@deriv-com/dds-marketing 1.1.1 → 1.1.3

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 (256) hide show
  1. package/.llm/components/accordion.md +4 -0
  2. package/.llm/components/accordionitem.md +4 -0
  3. package/.llm/components/aspectratio.md +4 -0
  4. package/.llm/components/awards.md +4 -0
  5. package/.llm/components/background.md +4 -0
  6. package/.llm/components/badge.md +7 -3
  7. package/.llm/components/bottomsheet.md +7 -3
  8. package/.llm/components/breadcrumb.md +4 -0
  9. package/.llm/components/breadcrumbitem.md +4 -0
  10. package/.llm/components/button.md +4 -0
  11. package/.llm/components/buttonicon.md +10 -6
  12. package/.llm/components/card.md +5 -1
  13. package/.llm/components/cardbody.md +5 -1
  14. package/.llm/components/cardbutton.md +4 -0
  15. package/.llm/components/checkbox.md +1 -1
  16. package/.llm/components/comparisoncards.md +4 -0
  17. package/.llm/components/comparisontable.md +4 -0
  18. package/.llm/components/ctabanner.md +4 -0
  19. package/.llm/components/ctabannerslider.md +4 -0
  20. package/.llm/components/datatable.md +4 -0
  21. package/.llm/components/divider.md +4 -0
  22. package/.llm/components/downloadbanner.md +4 -0
  23. package/.llm/components/dropdownmenu.md +9 -5
  24. package/.llm/components/estimator.md +336 -0
  25. package/.llm/components/faqaccordion.md +4 -0
  26. package/.llm/components/featurebullets.md +4 -0
  27. package/.llm/components/featurecards.md +5 -1
  28. package/.llm/components/featurecardscarousel.md +4 -0
  29. package/.llm/components/featurescroll.md +5 -1
  30. package/.llm/components/featuresplit.md +4 -0
  31. package/.llm/components/featurestack.md +4 -0
  32. package/.llm/components/filterchip.md +5 -1
  33. package/.llm/components/footer.md +4 -0
  34. package/.llm/components/footergroup.md +4 -0
  35. package/.llm/components/grid.md +4 -0
  36. package/.llm/components/icon.md +9 -5
  37. package/.llm/components/illustrationcard.md +4 -0
  38. package/.llm/components/illustrationscene.md +4 -0
  39. package/.llm/components/imagebanner.md +6 -2
  40. package/.llm/components/landinghero.md +4 -0
  41. package/.llm/components/link.md +5 -1
  42. package/.llm/components/logocolumns.md +4 -0
  43. package/.llm/components/logorows.md +4 -0
  44. package/.llm/components/menuitem.md +6 -2
  45. package/.llm/components/navbar.md +5 -1
  46. package/.llm/components/navbaritem.md +4 -0
  47. package/.llm/components/navbarmenu.md +4 -0
  48. package/.llm/components/navbarmenugroup.md +4 -0
  49. package/.llm/components/navbarpanel.md +4 -0
  50. package/.llm/components/navbarswitcher.md +10 -6
  51. package/.llm/components/navbarswitcheroption.md +4 -0
  52. package/.llm/components/option.md +5 -1
  53. package/.llm/components/pageheader.md +4 -0
  54. package/.llm/components/pagination.md +4 -0
  55. package/.llm/components/paginationdots.md +4 -0
  56. package/.llm/components/producthero.md +4 -0
  57. package/.llm/components/removablechip.md +5 -1
  58. package/.llm/components/resourcebanner.md +4 -0
  59. package/.llm/components/row.md +4 -0
  60. package/.llm/components/scenescroll.md +4 -0
  61. package/.llm/components/scroller.md +4 -0
  62. package/.llm/components/searchinput.md +4 -0
  63. package/.llm/components/segmentedcontrol.md +5 -1
  64. package/.llm/components/segmentedcontrolitem.md +6 -2
  65. package/.llm/components/select.md +4 -0
  66. package/.llm/components/selectchip.md +4 -0
  67. package/.llm/components/spinner.md +4 -0
  68. package/.llm/components/stack.md +4 -0
  69. package/.llm/components/stats.md +4 -0
  70. package/.llm/components/statusdot.md +4 -0
  71. package/.llm/components/steps.md +18 -6
  72. package/.llm/components/stickycards.md +4 -0
  73. package/.llm/components/subdomainnavbar.md +5 -1
  74. package/.llm/components/tab.md +6 -2
  75. package/.llm/components/table.md +4 -0
  76. package/.llm/components/tablebody.md +4 -0
  77. package/.llm/components/tablecell.md +4 -0
  78. package/.llm/components/tablehead.md +4 -0
  79. package/.llm/components/tableheadercell.md +4 -0
  80. package/.llm/components/tablerow.md +4 -0
  81. package/.llm/components/tablist.md +4 -0
  82. package/.llm/components/teamgrid.md +4 -0
  83. package/.llm/components/testimonialrow.md +4 -0
  84. package/.llm/components/testimonialslider.md +4 -0
  85. package/.llm/components/textarea.md +4 -0
  86. package/.llm/components/textinput.md +5 -1
  87. package/.llm/components/textscroll.md +4 -0
  88. package/.llm/components/tiers.md +4 -0
  89. package/.llm/components/typography.md +4 -0
  90. package/.llm/digest/accordion.md +1 -1
  91. package/.llm/digest/accordionitem.md +1 -1
  92. package/.llm/digest/aspectratio.md +1 -1
  93. package/.llm/digest/awards.md +1 -1
  94. package/.llm/digest/background.md +1 -1
  95. package/.llm/digest/badge.md +1 -1
  96. package/.llm/digest/bottomsheet.md +1 -1
  97. package/.llm/digest/breadcrumb.md +1 -1
  98. package/.llm/digest/breadcrumbitem.md +1 -1
  99. package/.llm/digest/button.md +1 -1
  100. package/.llm/digest/buttonicon.md +1 -1
  101. package/.llm/digest/card.md +1 -1
  102. package/.llm/digest/cardbody.md +1 -1
  103. package/.llm/digest/cardbutton.md +1 -1
  104. package/.llm/digest/checkbox.md +1 -1
  105. package/.llm/digest/comparisoncards.md +1 -1
  106. package/.llm/digest/comparisontable.md +1 -1
  107. package/.llm/digest/ctabanner.md +1 -1
  108. package/.llm/digest/ctabannerslider.md +1 -1
  109. package/.llm/digest/datatable.md +1 -1
  110. package/.llm/digest/divider.md +1 -1
  111. package/.llm/digest/downloadbanner.md +1 -1
  112. package/.llm/digest/dropdownmenu.md +1 -1
  113. package/.llm/digest/estimator.md +66 -0
  114. package/.llm/digest/faqaccordion.md +1 -1
  115. package/.llm/digest/featurebullets.md +1 -1
  116. package/.llm/digest/featurecards.md +1 -1
  117. package/.llm/digest/featurecardscarousel.md +1 -1
  118. package/.llm/digest/featurescroll.md +1 -1
  119. package/.llm/digest/featuresplit.md +1 -1
  120. package/.llm/digest/featurestack.md +1 -1
  121. package/.llm/digest/filterchip.md +1 -1
  122. package/.llm/digest/footer.md +1 -1
  123. package/.llm/digest/footergroup.md +1 -1
  124. package/.llm/digest/grid.md +1 -1
  125. package/.llm/digest/icon.md +1 -1
  126. package/.llm/digest/illustrationcard.md +1 -1
  127. package/.llm/digest/illustrationscene.md +1 -1
  128. package/.llm/digest/imagebanner.md +2 -2
  129. package/.llm/digest/landinghero.md +1 -1
  130. package/.llm/digest/link.md +1 -1
  131. package/.llm/digest/logocolumns.md +1 -1
  132. package/.llm/digest/logorows.md +1 -1
  133. package/.llm/digest/menuitem.md +1 -1
  134. package/.llm/digest/navbar.md +1 -1
  135. package/.llm/digest/navbaritem.md +1 -1
  136. package/.llm/digest/navbarmenu.md +1 -1
  137. package/.llm/digest/navbarmenugroup.md +1 -1
  138. package/.llm/digest/navbarpanel.md +1 -1
  139. package/.llm/digest/navbarswitcher.md +1 -1
  140. package/.llm/digest/navbarswitcheroption.md +1 -1
  141. package/.llm/digest/option.md +1 -1
  142. package/.llm/digest/pageheader.md +1 -1
  143. package/.llm/digest/pagination.md +1 -1
  144. package/.llm/digest/paginationdots.md +1 -1
  145. package/.llm/digest/producthero.md +1 -1
  146. package/.llm/digest/removablechip.md +1 -1
  147. package/.llm/digest/resourcebanner.md +1 -1
  148. package/.llm/digest/row.md +1 -1
  149. package/.llm/digest/scenescroll.md +1 -1
  150. package/.llm/digest/scroller.md +1 -1
  151. package/.llm/digest/searchinput.md +1 -1
  152. package/.llm/digest/segmentedcontrol.md +1 -1
  153. package/.llm/digest/segmentedcontrolitem.md +2 -2
  154. package/.llm/digest/select.md +1 -1
  155. package/.llm/digest/selectchip.md +1 -1
  156. package/.llm/digest/spinner.md +1 -1
  157. package/.llm/digest/stack.md +1 -1
  158. package/.llm/digest/stats.md +1 -1
  159. package/.llm/digest/statusdot.md +1 -1
  160. package/.llm/digest/steps.md +3 -3
  161. package/.llm/digest/stickycards.md +1 -1
  162. package/.llm/digest/subdomainnavbar.md +1 -1
  163. package/.llm/digest/tab.md +1 -1
  164. package/.llm/digest/table.md +1 -1
  165. package/.llm/digest/tablebody.md +1 -1
  166. package/.llm/digest/tablecell.md +1 -1
  167. package/.llm/digest/tablehead.md +1 -1
  168. package/.llm/digest/tableheadercell.md +1 -1
  169. package/.llm/digest/tablerow.md +1 -1
  170. package/.llm/digest/tablist.md +1 -1
  171. package/.llm/digest/teamgrid.md +1 -1
  172. package/.llm/digest/testimonialrow.md +1 -1
  173. package/.llm/digest/testimonialslider.md +1 -1
  174. package/.llm/digest/textarea.md +1 -1
  175. package/.llm/digest/textinput.md +1 -1
  176. package/.llm/digest/textscroll.md +1 -1
  177. package/.llm/digest/tiers.md +1 -1
  178. package/.llm/digest/typography.md +1 -1
  179. package/.llm/index.md +2 -1
  180. package/.llm/tokens.md +5 -0
  181. package/AGENTS.md +1 -0
  182. package/README.md +28 -3
  183. package/dist/components/blocks/block-parallax.css +62 -0
  184. package/dist/components/blocks/comparison-cards/comparison-cards-impl.css +0 -12
  185. package/dist/components/blocks/download-banner/DownloadBanner.d.ts +1 -0
  186. package/dist/components/blocks/download-banner/DownloadBanner.js +2 -1
  187. package/dist/components/blocks/estimator/Estimator.css +206 -0
  188. package/dist/components/blocks/estimator/Estimator.d.ts +27 -0
  189. package/dist/components/blocks/estimator/Estimator.js +61 -0
  190. package/dist/components/blocks/estimator/Estimator.types.d.ts +63 -0
  191. package/dist/components/blocks/estimator/Estimator.types.js +25 -0
  192. package/dist/components/blocks/estimator/estimator-impl.css +159 -0
  193. package/dist/components/blocks/feature-bullets/FeatureBullets.d.ts +1 -0
  194. package/dist/components/blocks/feature-bullets/FeatureBullets.js +2 -1
  195. package/dist/components/blocks/feature-cards/FeatureCards.d.ts +1 -0
  196. package/dist/components/blocks/feature-cards/FeatureCards.js +1 -0
  197. package/dist/components/blocks/feature-scroll/FeatureScroll.js +9 -3
  198. package/dist/components/blocks/feature-scroll/feature-scroll-impl.css +63 -40
  199. package/dist/components/blocks/feature-split/FeatureSplit.d.ts +1 -0
  200. package/dist/components/blocks/feature-split/FeatureSplit.js +2 -1
  201. package/dist/components/blocks/feature-stack/FeatureStack.d.ts +1 -0
  202. package/dist/components/blocks/feature-stack/FeatureStack.js +2 -1
  203. package/dist/components/blocks/image-banner/ImageBanner.d.ts +1 -0
  204. package/dist/components/blocks/image-banner/ImageBanner.js +2 -1
  205. package/dist/components/blocks/image-banner/ImageBanner.types.d.ts +2 -2
  206. package/dist/components/blocks/image-banner/ImageBanner.types.js +1 -1
  207. package/dist/components/blocks/image-banner/image-banner-impl.css +7 -51
  208. package/dist/components/blocks/landing-hero/LandingHero.css +1 -1
  209. package/dist/components/blocks/landing-hero/LandingHero.d.ts +1 -0
  210. package/dist/components/blocks/landing-hero/LandingHero.js +2 -1
  211. package/dist/components/blocks/product-hero/ProductHero.css +1 -1
  212. package/dist/components/blocks/product-hero/ProductHero.d.ts +1 -0
  213. package/dist/components/blocks/product-hero/ProductHero.js +2 -1
  214. package/dist/components/blocks/steps/Steps.css +2 -2
  215. package/dist/components/blocks/steps/Steps.d.ts +1 -0
  216. package/dist/components/blocks/steps/Steps.js +3 -2
  217. package/dist/components/blocks/steps/Steps.types.d.ts +1 -1
  218. package/dist/components/blocks/steps/steps-impl.css +76 -4
  219. package/dist/components/blocks/steps/use-turn.d.ts +8 -8
  220. package/dist/components/blocks/steps/use-turn.js +19 -16
  221. package/dist/components/blocks/team-grid/TeamGrid.d.ts +1 -0
  222. package/dist/components/blocks/team-grid/TeamGrid.js +2 -1
  223. package/dist/components/core/card/Card.css +1 -1
  224. package/dist/components/core/segmented-control-item/SegmentedControlItem.types.d.ts +1 -1
  225. package/dist/components/core/select/Select.css +2 -0
  226. package/dist/components/core/select/select-impl.css +58 -0
  227. package/dist/components/core/text-area/TextArea.css +2 -0
  228. package/dist/components/core/text-area/text-area-impl.css +54 -0
  229. package/dist/components/core/text-input/TextInput.css +2 -0
  230. package/dist/components/core/text-input/text-input-impl.css +63 -0
  231. package/dist/components/estimator-data.d.ts +29 -0
  232. package/dist/components/estimator-data.js +12 -0
  233. package/dist/components/index.d.ts +3 -0
  234. package/dist/components/index.js +2 -0
  235. package/dist/icons/accounts.d.ts +1 -0
  236. package/dist/icons/accounts.js +1 -0
  237. package/dist/icons/app-stores.d.ts +1 -0
  238. package/dist/icons/app-stores.js +1 -0
  239. package/dist/icons/currency.d.ts +1 -0
  240. package/dist/icons/currency.js +1 -0
  241. package/dist/icons/flag.d.ts +1 -0
  242. package/dist/icons/flag.js +1 -0
  243. package/dist/icons/illustrative.d.ts +1 -0
  244. package/dist/icons/illustrative.js +1 -0
  245. package/dist/icons/index.d.ts +1 -0
  246. package/dist/icons/index.js +4 -0
  247. package/dist/icons/markets.d.ts +1 -0
  248. package/dist/icons/markets.js +1 -0
  249. package/dist/icons/social.d.ts +1 -0
  250. package/dist/icons/social.js +1 -0
  251. package/dist/icons/system.d.ts +1 -0
  252. package/dist/icons/system.js +1 -0
  253. package/dist/icons/trade.d.ts +1 -0
  254. package/dist/icons/trade.js +1 -0
  255. package/dist/marketing.css +10 -0
  256. package/package.json +44 -2
@@ -4,6 +4,7 @@ import { useId } from 'react';
4
4
  import './Steps.css';
5
5
  import './steps-impl.css';
6
6
  import '../block-reveal.css';
7
+ import '../block-parallax.css';
7
8
  import { arriving, useReveal } from '../use-reveal.js';
8
9
  import { given } from '../../given.js';
9
10
  import { useTurn } from './use-turn.js';
@@ -41,11 +42,11 @@ export function Steps({ ground = stepsDefaults.ground, mediaPosition = stepsDefa
41
42
  // records as they are typed, and a number against nothing is a step the page did not write — so
42
43
  // it is dropped before the count is taken, and the numbers close up rather than skipping one.
43
44
  const shown = steps.filter((step) => given(step.title));
44
- const { current, turning, playing, next, choose, section, hold } = useTurn(shown.length, autoplay);
45
+ const { current, going, turning, playing, next, choose, section, hold } = useTurn(shown.length, autoplay);
45
46
  // The steps' own pictures replace the one picture only where every step has one: a turn that
46
47
  // reached a step without a picture would show nothing beside it.
47
48
  const pictured = shown.length > 0 && shown.every((step) => given(step.image?.src));
48
- return (_jsx("section", { className: stepsParts.root, ref: section, "data-ground": ground, "data-media-position": mediaPosition, "data-autoplay": autoplay || undefined, "aria-labelledby": titleId, ...(autoplay ? hold : {}), children: _jsx("div", { className: stepsParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: stepsParts.split, children: [_jsx("div", { className: stepsParts.media, ...arriving(0), "aria-hidden": "true", children: pictured
49
+ return (_jsx("section", { className: stepsParts.root, ref: section, "data-ground": ground, "data-media-position": mediaPosition, "data-autoplay": autoplay || undefined, "data-going": going, "aria-labelledby": titleId, ...(autoplay ? hold : {}), children: _jsx("div", { className: stepsParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: stepsParts.split, children: [_jsx("div", { "data-dds-parallax": "", className: stepsParts.media, ...arriving(0), "aria-hidden": "true", children: pictured
49
50
  ? shown.map((step, at) => (_jsx("img", { className: stepsParts.image, src: step.image?.src, alt: "", width: step.image?.width, height: step.image?.height, "data-current": at === current, loading: at === 0 ? undefined : 'lazy' }, `${at}:${step.title}`)))
50
51
  : media }), _jsxs("div", { className: stepsParts.content, children: [_jsx("h2", { className: stepsParts.title, ...arriving(0), id: titleId, children: title }), _jsx("ol", { className: stepsParts.list, role: "list", "data-turning": autoplay ? turning : undefined, "data-playing": autoplay ? playing : undefined, children: shown.map((step, at) => (
51
52
  /* Keyed by the step's own name. An index would key the list by position, so
@@ -12,7 +12,7 @@ export interface StepsOwnProps {
12
12
  * `end` — The steps first, for a section sitting under a split whose picture is already at the start
13
13
  */
14
14
  mediaPosition?: 'start' | 'end';
15
- /** Whether the steps take their turn on their own: one step is current, its rule fills over motion.duration.dwell, then the next takes over, and back to the first after the last. The current step's number is drawn at full strength and the rest recede; with an `image` on each step the picture changes to the current one's. Each step's title becomes a button that makes it current. Off by default, so a list nobody configured stays still. On, it holds while the pointer is over the section or focus is inside it, waits until the section is on screen, never moves for a reader who asked for less motion, and stops for good once the reader presses a step — the WAI carousel rule CtaBannerSlider follows: a reader who has chosen a step is reading it. That gives a reader a way to stop it, which WCAG 2.2.2 asks for, but not a visible one, so a page that needs 2.2.2 met plainly should leave it off. */
15
+ /** Whether the steps take their turn on their own: one step is current, its rule fills over motion.duration.step, then the next takes over, and back to the first after the last. The current step's number is drawn at full strength and the rest recede; with an `image` on each step the picture changes to the current one's. Each step's title becomes a button that makes it current. Off by default, so a list nobody configured stays still. On, it holds while focus is inside the section — not under the pointer, so it keeps turning while a reader watches it — waits until the section is on screen, never moves for a reader who asked for less motion, and stops for good once the reader presses a step — the WAI carousel rule CtaBannerSlider follows: a reader who has chosen a step is reading it. That gives a reader a way to stop it, which WCAG 2.2.2 asks for, but not a visible one, so a page that needs 2.2.2 met plainly should leave it off. */
16
16
  autoplay?: boolean;
17
17
  /** Always. What the steps get a reader to, in the fewest words that say it — 'Get started in 3 steps' */
18
18
  title: string;
@@ -152,7 +152,7 @@
152
152
  }
153
153
 
154
154
  /*
155
- * The fill: the current step's rule, drawn from the start edge over motion.duration.dwell. When it
155
+ * The fill: the current step's rule, drawn from the start edge over motion.duration.step. When it
156
156
  * ends the next step takes over — the component listens for the end, so the bar and the turn are
157
157
  * one clock. Paused wherever the turn is held; full and still where the turn has stopped or never
158
158
  * runs, so the current step is still marked.
@@ -175,7 +175,7 @@
175
175
  }
176
176
 
177
177
  :where([data-dds-context="marketing"]) .dds-steps .dds-steps__list[data-turning="true"] > .dds-steps__step[data-current="true"] > .dds-steps__progress {
178
- animation: dds-steps-fill var(--motion-duration-dwell) linear;
178
+ animation: dds-steps-fill var(--motion-duration-step) linear;
179
179
  }
180
180
 
181
181
  :where([data-dds-context="marketing"]) .dds-steps .dds-steps__list[data-playing="false"] > .dds-steps__step[data-current="true"] > .dds-steps__progress {
@@ -184,7 +184,20 @@
184
184
 
185
185
  /*
186
186
  * The steps' own pictures share the media cell, and the current step's is the one shown — the
187
- * first while the list is still. They cross over rather than cut, in motion.duration.shift.
187
+ * first while the list is still.
188
+ *
189
+ * The next is uncovered over the last rather than faded into it, FeatureScroll's change. A fade put
190
+ * both pictures on screen at half strength at once — a double exposure that read as the two
191
+ * overlapping. Uncovered from an edge, every point of the square is one picture or the other at full
192
+ * strength: up from the foot as the turn moves on, the wrap to the first step included, and down
193
+ * from the head when a reader presses an earlier step.
194
+ *
195
+ * An animation rather than a transition, because an animation starts from its first frame and a
196
+ * transition from wherever the picture last rested. The current picture is brought to the front and
197
+ * uncovered over motion.duration.turn — the figure-to-figure step a turning set already takes — and
198
+ * the one it replaces stays beneath, whole, for that long, then goes: a zero-length transition
199
+ * delayed by the same role, so the two cannot drift into a gap. Every other picture is already gone.
200
+ * No `data-going` before the first change, so the picture a reader opens on is simply there.
188
201
  */
189
202
  :where([data-dds-context="marketing"]) .dds-steps .dds-steps__media:has(> .dds-steps__image) {
190
203
  display: grid;
@@ -193,11 +206,66 @@
193
206
  :where([data-dds-context="marketing"]) .dds-steps .dds-steps__media > .dds-steps__image {
194
207
  grid-area: 1 / 1;
195
208
  opacity: 0;
196
- transition-property: opacity;
209
+ transition: opacity 0s linear var(--motion-duration-turn);
197
210
  }
198
211
 
199
212
  :where([data-dds-context="marketing"]) .dds-steps .dds-steps__media > .dds-steps__image[data-current="true"] {
200
213
  opacity: 1;
214
+ transition-delay: 0s;
215
+ z-index: 1;
216
+ }
217
+
218
+ :where([data-dds-context="marketing"]) .dds-steps[data-going="on"] .dds-steps__media > .dds-steps__image[data-current="true"] {
219
+ animation: dds-steps-from-foot var(--motion-duration-turn) var(--motion-easing-reveal);
220
+ }
221
+
222
+ :where([data-dds-context="marketing"]) .dds-steps[data-going="back"] .dds-steps__media > .dds-steps__image[data-current="true"] {
223
+ animation: dds-steps-from-head var(--motion-duration-turn) var(--motion-easing-reveal);
224
+ }
225
+
226
+ /*
227
+ * The wipe and the parallax together. The current picture's wipe is an `animation`, and so is the
228
+ * drift block-parallax.css gives every picture in the frame — one shorthand would replace the other,
229
+ * and the current picture, the only one a reader sees, would stop drifting the moment it arrived. So
230
+ * both are listed here: the wipe on the document's clock, the drift on the frame's view timeline,
231
+ * where the browser can drive one and the reader has not asked for less motion.
232
+ */
233
+ @supports (animation-timeline: view()) {
234
+ @media (prefers-reduced-motion: no-preference) {
235
+ :where([data-dds-context="marketing"]) .dds-steps[data-going="on"] .dds-steps__media > .dds-steps__image[data-current="true"] {
236
+ animation:
237
+ dds-steps-from-foot var(--motion-duration-turn) var(--motion-easing-reveal),
238
+ dds-parallax linear both;
239
+ animation-range: normal, cover;
240
+ animation-timeline: auto, --dds-parallax;
241
+ }
242
+
243
+ :where([data-dds-context="marketing"]) .dds-steps[data-going="back"] .dds-steps__media > .dds-steps__image[data-current="true"] {
244
+ animation:
245
+ dds-steps-from-head var(--motion-duration-turn) var(--motion-easing-reveal),
246
+ dds-parallax linear both;
247
+ animation-range: normal, cover;
248
+ animation-timeline: auto, --dds-parallax;
249
+ }
250
+ }
251
+ }
252
+
253
+ @keyframes dds-steps-from-foot {
254
+ from {
255
+ clip-path: inset(100% 0 0 0);
256
+ }
257
+ to {
258
+ clip-path: inset(0);
259
+ }
260
+ }
261
+
262
+ @keyframes dds-steps-from-head {
263
+ from {
264
+ clip-path: inset(0 0 100% 0);
265
+ }
266
+ to {
267
+ clip-path: inset(0);
268
+ }
201
269
  }
202
270
 
203
271
  /*
@@ -213,4 +281,8 @@
213
281
  :where([data-dds-context="marketing"]) .dds-steps[data-autoplay] .dds-steps__number {
214
282
  transition: none;
215
283
  }
284
+
285
+ :where([data-dds-context="marketing"]) .dds-steps .dds-steps__media > .dds-steps__image[data-current="true"] {
286
+ animation: none;
287
+ }
216
288
  }
@@ -1,9 +1,9 @@
1
- import { type FocusEvent, type PointerEvent } from 'react';
1
+ import { type FocusEvent } from 'react';
2
2
  /**
3
3
  * The steps taking their turn under `autoplay`: which step is current, and whether the turn is
4
4
  * running.
5
5
  *
6
- * The timing is not here. The current step's rule fills over motion.duration.dwell as a CSS
6
+ * The timing is not here. The current step's rule fills over motion.duration.step as a CSS
7
7
  * animation, and the turn moves on when that animation ends (`next`), so the bar a reader watches
8
8
  * and the step changing are one clock rather than two that drift. Holding the turn is pausing that
9
9
  * animation, which is what `playing` is for: the stylesheet pauses the fill wherever it is false.
@@ -12,21 +12,21 @@ import { type FocusEvent, type PointerEvent } from 'react';
12
12
  * - `autoplay` is on and there are two steps or more;
13
13
  * - the reader has not asked for less motion — asked live, so turning it on mid-visit stops it;
14
14
  * - the section is on screen. A turn nobody can see does not run, and starts again where it was;
15
- * - nothing holds it: a pointer over the section or focus inside it holds it for as long as it
16
- * lasts, and pressing a step stops it for good — CtaBannerSlider's rule, by way of the WAI
17
- * carousel pattern: a reader who has chosen a step is reading it. The pointer's way, the
18
- * keyboard's and a touch screen's, which WCAG 2.2.2 asks for of anything that moves on its own.
15
+ * - nothing holds it: focus inside the section holds it for as long as it lasts, and pressing a
16
+ * step stops it for good — a reader who has chosen a step is reading it. The keyboard's way and
17
+ * the pointer's and a touch screen's, which WCAG 2.2.2 asks for of anything that moves on its own.
18
+ * A pointer merely resting over the section does not hold it: the list is meant to be watched as
19
+ * it turns, and pausing whenever the pointer crossed it read as the list having stopped.
19
20
  */
20
21
  export declare function useTurn(count: number, autoplay: boolean): {
21
22
  current: number;
23
+ going: "on" | "back" | undefined;
22
24
  turning: boolean;
23
25
  playing: boolean;
24
26
  next: () => void;
25
27
  choose: (at: number) => void;
26
28
  section: import("react").RefObject<HTMLElement | null>;
27
29
  hold: {
28
- onPointerEnter: (event: PointerEvent<HTMLElement>) => void;
29
- onPointerLeave: (event: PointerEvent<HTMLElement>) => void;
30
30
  onFocus: () => void;
31
31
  onBlur: (event: FocusEvent<HTMLElement>) => void;
32
32
  };
@@ -4,7 +4,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
4
4
  * The steps taking their turn under `autoplay`: which step is current, and whether the turn is
5
5
  * running.
6
6
  *
7
- * The timing is not here. The current step's rule fills over motion.duration.dwell as a CSS
7
+ * The timing is not here. The current step's rule fills over motion.duration.step as a CSS
8
8
  * animation, and the turn moves on when that animation ends (`next`), so the bar a reader watches
9
9
  * and the step changing are one clock rather than two that drift. Holding the turn is pausing that
10
10
  * animation, which is what `playing` is for: the stylesheet pauses the fill wherever it is false.
@@ -13,13 +13,21 @@ import { useCallback, useEffect, useRef, useState } from 'react';
13
13
  * - `autoplay` is on and there are two steps or more;
14
14
  * - the reader has not asked for less motion — asked live, so turning it on mid-visit stops it;
15
15
  * - the section is on screen. A turn nobody can see does not run, and starts again where it was;
16
- * - nothing holds it: a pointer over the section or focus inside it holds it for as long as it
17
- * lasts, and pressing a step stops it for good — CtaBannerSlider's rule, by way of the WAI
18
- * carousel pattern: a reader who has chosen a step is reading it. The pointer's way, the
19
- * keyboard's and a touch screen's, which WCAG 2.2.2 asks for of anything that moves on its own.
16
+ * - nothing holds it: focus inside the section holds it for as long as it lasts, and pressing a
17
+ * step stops it for good — a reader who has chosen a step is reading it. The keyboard's way and
18
+ * the pointer's and a touch screen's, which WCAG 2.2.2 asks for of anything that moves on its own.
19
+ * A pointer merely resting over the section does not hold it: the list is meant to be watched as
20
+ * it turns, and pausing whenever the pointer crossed it read as the list having stopped.
20
21
  */
21
22
  export function useTurn(count, autoplay) {
22
23
  const [current, setCurrent] = useState(0);
24
+ /*
25
+ Which way the last change went, for the picture to be uncovered from the matching edge: on, from
26
+ the foot, for every turn — the wrap from the last step to the first included, because the turn
27
+ still moves on — and back, from the head, when a reader presses an earlier step. Absent until the
28
+ first change, so the picture a reader opens on is simply there.
29
+ */
30
+ const [going, setGoing] = useState(undefined);
23
31
  const [seen, setSeen] = useState(false);
24
32
  const [still, setStill] = useState(false);
25
33
  const [held, setHeld] = useState(false);
@@ -46,24 +54,19 @@ export function useTurn(count, autoplay) {
46
54
  }, [autoplay]);
47
55
  /** The current step's fill has run: the next step takes over, and the first after the last. */
48
56
  const next = useCallback(() => {
49
- if (count > 0)
57
+ if (count > 0) {
58
+ setGoing('on');
50
59
  setCurrent((at) => (at + 1) % count);
60
+ }
51
61
  }, [count]);
52
62
  /** A step pressed: it is current, and the turn stops for good. */
53
63
  const choose = useCallback((at) => {
64
+ setGoing(at >= current ? 'on' : 'back');
54
65
  setCurrent(at);
55
66
  setStopped(true);
56
- }, []);
67
+ }, [current]);
57
68
  /** Spread on the section: what holds the turn. */
58
69
  const hold = {
59
- onPointerEnter: (event) => {
60
- if (event.pointerType === 'mouse')
61
- setHeld(true);
62
- },
63
- onPointerLeave: (event) => {
64
- if (event.pointerType === 'mouse')
65
- setHeld(false);
66
- },
67
70
  onFocus: () => setHeld(true),
68
71
  onBlur: (event) => {
69
72
  if (!event.currentTarget.contains(event.relatedTarget))
@@ -71,5 +74,5 @@ export function useTurn(count, autoplay) {
71
74
  },
72
75
  };
73
76
  // A list that shrank under the current step falls back to its first.
74
- return { current: current < count ? current : 0, turning, playing, next, choose, section, hold };
77
+ return { current: current < count ? current : 0, going, turning, playing, next, choose, section, hold };
75
78
  }
@@ -1,6 +1,7 @@
1
1
  import './TeamGrid.css';
2
2
  import './team-grid-impl.css';
3
3
  import '../block-reveal.css';
4
+ import '../block-parallax.css';
4
5
  import { type TeamGridProps } from './TeamGrid.types.js';
5
6
  export type { TeamGridProps };
6
7
  /**
@@ -4,6 +4,7 @@ import { useId, useState } from 'react';
4
4
  import './TeamGrid.css';
5
5
  import './team-grid-impl.css';
6
6
  import '../block-reveal.css';
7
+ import '../block-parallax.css';
7
8
  import { given } from '../../given.js';
8
9
  import { Button } from '../../core/button/Button.js';
9
10
  import { Link } from '../../core/link/Link.js';
@@ -69,6 +70,6 @@ export function TeamGrid({ ground = teamGridDefaults.ground, title, description,
69
70
  style: { '--dds-teamgrid-extra-at': at - shown },
70
71
  }
71
72
  : arriving(Math.min(FIRST_PERSON + at, LAST_STEP));
72
- return (_jsxs("li", { className: teamGridParts.item, hidden: extra && !expanded, ...motion, children: [_jsx("div", { className: teamGridParts.media, children: _jsx(AspectRatio, { ratio: "square", children: _jsx("img", { src: person.image.src, alt: person.image.alt, loading: "lazy", decoding: "async" }) }) }), _jsxs("div", { className: teamGridParts.text, children: [_jsx("h3", { className: teamGridParts.name, children: person.name }), _jsx("p", { className: teamGridParts.role, children: person.role }), person.profile !== undefined ? (_jsx("div", { className: teamGridParts.profile, children: _jsx(Link, { href: person.profile.href, external: true, tone: inverse ? 'inherit' : 'brand', "aria-label": `${profileName(person)} ${externalLabel}`, children: person.profile.label }) })) : null] })] }, `${person.name}-${at}`));
73
+ return (_jsxs("li", { className: teamGridParts.item, hidden: extra && !expanded, ...motion, children: [_jsx("div", { "data-dds-parallax": "", className: teamGridParts.media, children: _jsx(AspectRatio, { ratio: "square", children: _jsx("img", { src: person.image.src, alt: person.image.alt, loading: "lazy", decoding: "async" }) }) }), _jsxs("div", { className: teamGridParts.text, children: [_jsx("h3", { className: teamGridParts.name, children: person.name }), _jsx("p", { className: teamGridParts.role, children: person.role }), person.profile !== undefined ? (_jsx("div", { className: teamGridParts.profile, children: _jsx(Link, { href: person.profile.href, external: true, tone: inverse ? 'inherit' : 'brand', "aria-label": `${profileName(person)} ${externalLabel}`, children: person.profile.label }) })) : null] })] }, `${person.name}-${at}`));
73
74
  }) }), longer ? (_jsx("div", { className: teamGridParts.actions, ...arriving(Math.min(FIRST_PERSON + shown, LAST_STEP + 1)), children: _jsx(Button, { variant: "secondary", size: "md", tone: inverse ? 'inverse' : 'default', "aria-expanded": expanded, "aria-controls": listId, onClick: () => setExpanded((open) => !open), children: expanded ? collapseLabel : expandLabel }) })) : null] })] }) }));
74
75
  }
@@ -4,7 +4,7 @@
4
4
  box-sizing: border-box;
5
5
  display: flex;
6
6
  flex-direction: column;
7
- overflow: hidden;
7
+ overflow: clip;
8
8
  border-radius: var(--radius-surface);
9
9
  }
10
10
 
@@ -10,7 +10,7 @@ export interface SegmentedControlItemOwnProps {
10
10
  value: string;
11
11
  /** Always — it is the segment's accessible name as well as its words, and a radio with no name is announced as a control with nothing in it. One or two words: a row is scanned across, and the segment that needs a phrase is a choice that wanted a list */
12
12
  label: string;
13
- /** The glyph tells the modes apart faster than the words do — a card and a bank beside two payment methods. Import it from @deriv-com/quill-icons-web and pass the element */
13
+ /** The glyph tells the modes apart faster than the words do — a card and a bank beside two payment methods. Import it from @deriv-com/dds-marketing/icons and pass the element */
14
14
  icon?: ReactNode;
15
15
  /** This segment reports its own presses — logging which plan a visitor looked at, say. It is called with this segment's value, and SegmentedControl chains its own handler after it rather than replacing it */
16
16
  onSelect?: (value: string) => void;
@@ -151,6 +151,8 @@
151
151
  gap: var(--space-gap-xs);
152
152
  letter-spacing: var(--font-body-sm-letter-spacing);
153
153
  line-height: var(--font-body-sm-line-height);
154
+ transition-duration: var(--motion-duration-fast);
155
+ transition-timing-function: var(--motion-easing-standard);
154
156
  }
155
157
 
156
158
  :where([data-dds-context="marketing"]) .dds-select .dds-select__message-icon {
@@ -112,3 +112,61 @@
112
112
  animation: none;
113
113
  }
114
114
  }
115
+
116
+ /*
117
+ * The status message fades in when it arrives.
118
+ *
119
+ * A contract binds transitions, and a transition needs a value to move from: the message is not
120
+ * in the DOM until a status is reported, so only a keyframe can bring it in. Opacity alone — the
121
+ * message takes the helper's place rather than pushing the row down, so there is no distance to
122
+ * travel, and moving it would shift the words being read. A status changing while the message is
123
+ * showing keeps the same element, and its colour moves with the transition the contract binds.
124
+ */
125
+ @keyframes dds-select-message-in {
126
+ from {
127
+ opacity: 0;
128
+ }
129
+ }
130
+
131
+ :where([data-dds-context="marketing"]) .dds-select .dds-select__message {
132
+ animation: dds-select-message-in var(--motion-duration-normal) var(--motion-easing-enter);
133
+ }
134
+
135
+ /*
136
+ * The box shakes once when the field turns to an error, as TextInput's does.
137
+ *
138
+ * Once, on arrival: the animation is attached by the error status, so it plays when the status
139
+ * becomes error and not again while it stays one. Only the box moves; the label and the
140
+ * message hold still, so the words saying what went wrong can be read while it settles.
141
+ *
142
+ * Not while the list is open. The popup is drawn inside the box, so shaking the box would shake
143
+ * the answers being read along with it. A status that arrives while it is open shakes the box
144
+ * as the list closes, which is the moment the answer is handed in.
145
+ */
146
+ @keyframes dds-select-shake {
147
+ 20% {
148
+ translate: calc(var(--motion-distance-shake) * -1) 0;
149
+ }
150
+ 40% {
151
+ translate: var(--motion-distance-shake) 0;
152
+ }
153
+ 60% {
154
+ translate: calc(var(--motion-distance-shake) * -0.5) 0;
155
+ }
156
+ 80% {
157
+ translate: calc(var(--motion-distance-shake) * 0.5) 0;
158
+ }
159
+ }
160
+
161
+ :where([data-dds-context="marketing"]) .dds-select[data-status="error"]:not(:has([aria-expanded="true"])) .dds-select__control {
162
+ animation: dds-select-shake var(--motion-duration-slow) var(--motion-easing-standard);
163
+ }
164
+
165
+ /* The generated reduce block is written from the token bindings and these are not. A reader who
166
+ has asked for less movement has asked for this too. */
167
+ @media (prefers-reduced-motion: reduce) {
168
+ :where([data-dds-context="marketing"]) .dds-select .dds-select__message,
169
+ :where([data-dds-context="marketing"]) .dds-select[data-status="error"]:not(:has([aria-expanded="true"])) .dds-select__control {
170
+ animation: none;
171
+ }
172
+ }
@@ -92,6 +92,8 @@
92
92
  gap: var(--space-gap-xs);
93
93
  letter-spacing: var(--font-body-sm-letter-spacing);
94
94
  line-height: var(--font-body-sm-line-height);
95
+ transition-duration: var(--motion-duration-fast);
96
+ transition-timing-function: var(--motion-easing-standard);
95
97
  }
96
98
 
97
99
  :where([data-dds-context="marketing"]) .dds-textarea .dds-textarea__message-icon {
@@ -34,3 +34,57 @@
34
34
  :where([data-dds-context="marketing"]) .dds-textarea__message-icon {
35
35
  block-size: calc(var(--font-body-sm-size) * var(--font-body-sm-line-height));
36
36
  }
37
+
38
+ /*
39
+ * The status message fades in when it arrives.
40
+ *
41
+ * A contract binds transitions, and a transition needs a value to move from: the message is not
42
+ * in the DOM until a status is reported, so only a keyframe can bring it in. Opacity alone — the
43
+ * message takes the helper's place rather than pushing the row down, so there is no distance to
44
+ * travel, and moving it would shift the words being read. A status changing while the message is
45
+ * showing keeps the same element, and its colour moves with the transition the contract binds.
46
+ */
47
+ @keyframes dds-textarea-message-in {
48
+ from {
49
+ opacity: 0;
50
+ }
51
+ }
52
+
53
+ :where([data-dds-context="marketing"]) .dds-textarea .dds-textarea__message {
54
+ animation: dds-textarea-message-in var(--motion-duration-normal) var(--motion-easing-enter);
55
+ }
56
+
57
+ /*
58
+ * The box shakes once when the field turns to an error, as TextInput's does.
59
+ *
60
+ * Once, on arrival: the animation is attached by the error status, so it plays when the status
61
+ * becomes error and not again while it stays one. Only the box moves; the label and the
62
+ * message hold still, so the words saying what went wrong can be read while it settles.
63
+ */
64
+ @keyframes dds-textarea-shake {
65
+ 20% {
66
+ translate: calc(var(--motion-distance-shake) * -1) 0;
67
+ }
68
+ 40% {
69
+ translate: var(--motion-distance-shake) 0;
70
+ }
71
+ 60% {
72
+ translate: calc(var(--motion-distance-shake) * -0.5) 0;
73
+ }
74
+ 80% {
75
+ translate: calc(var(--motion-distance-shake) * 0.5) 0;
76
+ }
77
+ }
78
+
79
+ :where([data-dds-context="marketing"]) .dds-textarea[data-status="error"] .dds-textarea__control {
80
+ animation: dds-textarea-shake var(--motion-duration-slow) var(--motion-easing-standard);
81
+ }
82
+
83
+ /* The generated reduce block is written from the token bindings and these are not. A reader who
84
+ has asked for less movement has asked for this too. */
85
+ @media (prefers-reduced-motion: reduce) {
86
+ :where([data-dds-context="marketing"]) .dds-textarea .dds-textarea__message,
87
+ :where([data-dds-context="marketing"]) .dds-textarea[data-status="error"] .dds-textarea__control {
88
+ animation: none;
89
+ }
90
+ }
@@ -118,6 +118,8 @@
118
118
  gap: var(--space-gap-xs);
119
119
  letter-spacing: var(--font-body-sm-letter-spacing);
120
120
  line-height: var(--font-body-sm-line-height);
121
+ transition-duration: var(--motion-duration-fast);
122
+ transition-timing-function: var(--motion-easing-standard);
121
123
  }
122
124
 
123
125
  :where([data-dds-context="marketing"]) .dds-textinput .dds-textinput__message-icon {
@@ -34,3 +34,66 @@
34
34
  :where([data-dds-context="marketing"]) .dds-textinput__message-icon {
35
35
  block-size: calc(var(--font-body-sm-size) * var(--font-body-sm-line-height));
36
36
  }
37
+
38
+ /*
39
+ * The status message fades in when it arrives.
40
+ *
41
+ * A contract binds transitions, and a transition needs a value to move from: the message is not
42
+ * in the DOM until a status is reported, so there is nothing to transition and only a keyframe
43
+ * can bring it in. Opacity alone — the message takes the helper's place rather than pushing the
44
+ * row down, so there is no distance to travel, and moving it would shift the words being read.
45
+ *
46
+ * It plays once, on arrival. A status changing while the message is already showing keeps the
47
+ * same element, and its colour moves with the transition the contract binds rather than the
48
+ * whole message blinking out and back.
49
+ */
50
+ @keyframes dds-textinput-message-in {
51
+ from {
52
+ opacity: 0;
53
+ }
54
+ }
55
+
56
+ :where([data-dds-context="marketing"]) .dds-textinput .dds-textinput__message {
57
+ animation: dds-textinput-message-in var(--motion-duration-normal) var(--motion-easing-enter);
58
+ }
59
+
60
+ /*
61
+ * The box shakes once when the field turns to an error.
62
+ *
63
+ * Once, on arrival: the animation is attached by the error status, so it plays when the status
64
+ * becomes error and not again while it stays one — typing on in a field that is still wrong does
65
+ * not shake it at every keystroke. Leaving the error and coming back is a new refusal and shakes
66
+ * again. Only the box moves; the label above it and the message below hold still, so the words
67
+ * saying what went wrong can be read while it settles.
68
+ *
69
+ * Each swing is smaller than the last, so it reads as a shake that stops rather than a vibration
70
+ * that is cut off. The swing is symmetric, so it reads the same in either writing direction.
71
+ */
72
+ @keyframes dds-textinput-shake {
73
+ 20% {
74
+ translate: calc(var(--motion-distance-shake) * -1) 0;
75
+ }
76
+ 40% {
77
+ translate: var(--motion-distance-shake) 0;
78
+ }
79
+ 60% {
80
+ translate: calc(var(--motion-distance-shake) * -0.5) 0;
81
+ }
82
+ 80% {
83
+ translate: calc(var(--motion-distance-shake) * 0.5) 0;
84
+ }
85
+ }
86
+
87
+ :where([data-dds-context="marketing"]) .dds-textinput[data-status="error"] .dds-textinput__control {
88
+ animation: dds-textinput-shake var(--motion-duration-slow) var(--motion-easing-standard);
89
+ }
90
+
91
+ /* The generated reduce block is written from the token bindings and these are not. A reader who
92
+ has asked for less movement has asked for this too — and a shake is the movement most likely
93
+ to be the reason they asked. */
94
+ @media (prefers-reduced-motion: reduce) {
95
+ :where([data-dds-context="marketing"]) .dds-textinput .dds-textinput__message,
96
+ :where([data-dds-context="marketing"]) .dds-textinput[data-status="error"] .dds-textinput__control {
97
+ animation: none;
98
+ }
99
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The figures an Estimator lays out once a reader has filled its inputs in.
3
+ *
4
+ * Exported from the package for the reason `stats-data.ts` and `comparison-cards-data.ts` are: a
5
+ * block whose content is a list is one whose consumer builds a value before passing it.
6
+ *
7
+ * A record rather than a component per figure, because a result is a number and the words that say
8
+ * what it is — nothing in it is an element a page composes. The page works the figures out, from a
9
+ * live feed, a formula or both; the block only sets them, so the same block serves a margin
10
+ * calculator, a crypto converter and an affiliate's income estimate without knowing which.
11
+ */
12
+ /** One figure an Estimator shows: what it is, its value, and anything a reader needs to read it. */
13
+ export interface EstimatorResult {
14
+ /** What the figure is, in a few words: 'Margin required', 'You receive', 'Monthly income'. */
15
+ label: string;
16
+ /**
17
+ * The figure, written exactly as it is to be read: '1,240.50 USD', '0.0214 BTC', '$2,400'.
18
+ *
19
+ * A string rather than a number, because the way it is written is the page's: its currency, its
20
+ * digits, its grouping, its locale. The block draws it as given and isolates it, so a sign or a
21
+ * currency keeps its place in a right-to-left line.
22
+ */
23
+ value: string;
24
+ /**
25
+ * A line under the figure, where it needs one to be read correctly: 'Per lot, at 1:500
26
+ * leverage', 'Estimate at the current price'. Optional; most figures need none.
27
+ */
28
+ note?: string;
29
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The figures an Estimator lays out once a reader has filled its inputs in.
3
+ *
4
+ * Exported from the package for the reason `stats-data.ts` and `comparison-cards-data.ts` are: a
5
+ * block whose content is a list is one whose consumer builds a value before passing it.
6
+ *
7
+ * A record rather than a component per figure, because a result is a number and the words that say
8
+ * what it is — nothing in it is an element a page composes. The page works the figures out, from a
9
+ * live feed, a formula or both; the block only sets them, so the same block serves a margin
10
+ * calculator, a crypto converter and an affiliate's income estimate without knowing which.
11
+ */
12
+ export {};
@@ -44,6 +44,8 @@ export { DownloadBanner, type DownloadBannerProps } from './blocks/download-bann
44
44
  export { downloadBannerParts, downloadBannerDefaults } from './blocks/download-banner/DownloadBanner.types.js';
45
45
  export { DropdownMenu, type DropdownMenuProps } from './core/dropdown-menu/DropdownMenu.js';
46
46
  export { dropdownMenuParts, dropdownMenuDefaults } from './core/dropdown-menu/DropdownMenu.types.js';
47
+ export { Estimator, type EstimatorProps } from './blocks/estimator/Estimator.js';
48
+ export { estimatorParts, estimatorDefaults } from './blocks/estimator/Estimator.types.js';
47
49
  export { FaqAccordion, type FaqAccordionProps } from './blocks/faq-accordion/FaqAccordion.js';
48
50
  export { faqAccordionParts, faqAccordionDefaults } from './blocks/faq-accordion/FaqAccordion.types.js';
49
51
  export { FeatureBullets, type FeatureBulletsProps } from './blocks/feature-bullets/FeatureBullets.js';
@@ -187,6 +189,7 @@ export type { ComparisonCardsCard } from './comparison-cards-data.js';
187
189
  export type { ComparisonTableColumn, ComparisonTableRow } from './comparison-table-data.js';
188
190
  export type { DataTableColumn, DataTableRow } from './data-table-data.js';
189
191
  export type { DownloadBannerBadge, DownloadBannerQr } from './download-banner-data.js';
192
+ export type { EstimatorResult } from './estimator-data.js';
190
193
  export type { LogoTile } from './logo-data.js';
191
194
  export type { ResourceBannerLink } from './resource-banner-data.js';
192
195
  export type { SceneScrollScene } from './scene-scroll-data.js';
@@ -45,6 +45,8 @@ export { DownloadBanner } from './blocks/download-banner/DownloadBanner.js';
45
45
  export { downloadBannerParts, downloadBannerDefaults } from './blocks/download-banner/DownloadBanner.types.js';
46
46
  export { DropdownMenu } from './core/dropdown-menu/DropdownMenu.js';
47
47
  export { dropdownMenuParts, dropdownMenuDefaults } from './core/dropdown-menu/DropdownMenu.types.js';
48
+ export { Estimator } from './blocks/estimator/Estimator.js';
49
+ export { estimatorParts, estimatorDefaults } from './blocks/estimator/Estimator.types.js';
48
50
  export { FaqAccordion } from './blocks/faq-accordion/FaqAccordion.js';
49
51
  export { faqAccordionParts, faqAccordionDefaults } from './blocks/faq-accordion/FaqAccordion.types.js';
50
52
  export { FeatureBullets } from './blocks/feature-bullets/FeatureBullets.js';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/accounts';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/accounts';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/app-stores';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/app-stores';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/currency';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/currency';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/flag';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/flag';
@@ -0,0 +1 @@
1
+ export * from '@deriv-com/quill-icons-web/illustrative';