@deriv-com/dds-marketing 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.llm/components/accordion.md +8 -0
- package/.llm/components/accordionitem.md +8 -0
- package/.llm/components/aspectratio.md +8 -0
- package/.llm/components/badge.md +8 -0
- package/.llm/components/bottomsheet.md +8 -0
- package/.llm/components/breadcrumb.md +8 -0
- package/.llm/components/breadcrumbitem.md +8 -0
- package/.llm/components/button.md +46 -22
- package/.llm/components/buttonicon.md +14 -6
- package/.llm/components/card.md +15 -1
- package/.llm/components/cardbody.md +28 -2
- package/.llm/components/cardbutton.md +15 -1
- package/.llm/components/checkbox.md +8 -0
- package/.llm/components/ctabanner.md +186 -0
- package/.llm/components/ctabannerslider.md +204 -0
- package/.llm/components/divider.md +8 -0
- package/.llm/components/dropdownmenu.md +13 -5
- package/.llm/components/faqaccordion.md +217 -0
- package/.llm/components/featurebullets.md +254 -0
- package/.llm/components/featurecards.md +313 -0
- package/.llm/components/featurescroll.md +284 -0
- package/.llm/components/featuresplit.md +249 -0
- package/.llm/components/filterchip.md +8 -0
- package/.llm/components/footer.md +8 -0
- package/.llm/components/footergroup.md +8 -0
- package/.llm/components/grid.md +8 -0
- package/.llm/components/icon.md +8 -0
- package/.llm/components/landinghero.md +254 -0
- package/.llm/components/link.md +9 -1
- package/.llm/components/logocolumns.md +235 -0
- package/.llm/components/logorows.md +212 -0
- package/.llm/components/menuitem.md +8 -0
- package/.llm/components/navbar.md +79 -15
- package/.llm/components/navbaritem.md +9 -1
- package/.llm/components/navbarmenu.md +8 -0
- package/.llm/components/navbarmenugroup.md +8 -0
- package/.llm/components/navbarpanel.md +9 -1
- package/.llm/components/navbarswitcher.md +9 -1
- package/.llm/components/navbarswitcheroption.md +8 -0
- package/.llm/components/option.md +8 -0
- package/.llm/components/pageheader.md +231 -0
- package/.llm/components/pagination.md +26 -89
- package/.llm/components/paginationdots.md +215 -0
- package/.llm/components/producthero.md +248 -0
- package/.llm/components/removablechip.md +8 -0
- package/.llm/components/row.md +8 -0
- package/.llm/components/scroller.md +8 -0
- package/.llm/components/searchinput.md +8 -0
- package/.llm/components/segmentedcontrol.md +8 -0
- package/.llm/components/segmentedcontrolitem.md +8 -0
- package/.llm/components/select.md +8 -0
- package/.llm/components/selectchip.md +56 -15
- package/.llm/components/spinner.md +8 -0
- package/.llm/components/stack.md +8 -0
- package/.llm/components/statusdot.md +8 -0
- package/.llm/components/subdomainnavbar.md +8 -0
- package/.llm/components/tab.md +8 -0
- package/.llm/components/table.md +8 -0
- package/.llm/components/tablebody.md +8 -0
- package/.llm/components/tablecell.md +8 -0
- package/.llm/components/tablehead.md +8 -0
- package/.llm/components/tableheadercell.md +8 -0
- package/.llm/components/tablerow.md +8 -0
- package/.llm/components/tablist.md +8 -0
- package/.llm/components/testimonialrow.md +235 -0
- package/.llm/components/testimonialslider.md +254 -0
- package/.llm/components/textarea.md +8 -0
- package/.llm/components/textinput.md +8 -0
- package/.llm/components/tooltip.md +8 -0
- package/.llm/components/typography.md +8 -0
- package/.llm/digest/button.md +11 -6
- package/.llm/digest/buttonicon.md +2 -2
- package/.llm/digest/card.md +1 -0
- package/.llm/digest/cardbody.md +3 -1
- package/.llm/digest/cardbutton.md +1 -0
- package/.llm/digest/ctabanner.md +44 -0
- package/.llm/digest/ctabannerslider.md +45 -0
- package/.llm/digest/dropdownmenu.md +1 -1
- package/.llm/digest/faqaccordion.md +43 -0
- package/.llm/digest/featurebullets.md +52 -0
- package/.llm/digest/featurecards.md +49 -0
- package/.llm/digest/featurescroll.md +52 -0
- package/.llm/digest/featuresplit.md +54 -0
- package/.llm/digest/landinghero.md +53 -0
- package/.llm/digest/logocolumns.md +55 -0
- package/.llm/digest/logorows.md +48 -0
- package/.llm/digest/navbar.md +18 -3
- package/.llm/digest/pageheader.md +49 -0
- package/.llm/digest/pagination.md +6 -17
- package/.llm/digest/paginationdots.md +43 -0
- package/.llm/digest/producthero.md +53 -0
- package/.llm/digest/selectchip.md +6 -1
- package/.llm/digest/testimonialrow.md +51 -0
- package/.llm/digest/testimonialslider.md +51 -0
- package/.llm/index.md +24 -3
- package/.llm/rules.md +24 -0
- package/.llm/tokens.md +56 -12
- package/AGENTS.md +28 -3
- package/README.md +41 -21
- package/dist/components/banner-data.d.ts +38 -0
- package/dist/components/banner-data.js +15 -0
- package/dist/components/blocks/block-reveal.css +90 -0
- package/dist/components/blocks/cta-banner/CtaBanner.css +66 -0
- package/dist/components/blocks/cta-banner/CtaBanner.d.ts +22 -0
- package/dist/components/blocks/cta-banner/CtaBanner.js +31 -0
- package/dist/components/blocks/cta-banner/CtaBanner.types.d.ts +29 -0
- package/dist/components/blocks/cta-banner/CtaBanner.types.js +13 -0
- package/dist/components/blocks/cta-banner/cta-banner-impl.css +29 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.css +90 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.d.ts +39 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.js +60 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.d.ts +41 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.js +15 -0
- package/dist/components/blocks/cta-banner-slider/cta-banner-slider-impl.css +73 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.css +54 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.d.ts +20 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.js +28 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.types.d.ts +25 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.types.js +10 -0
- package/dist/components/blocks/faq-accordion/faq-accordion-impl.css +54 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.css +139 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.d.ts +31 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.js +55 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.types.d.ts +39 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.types.js +16 -0
- package/dist/components/blocks/feature-bullets/feature-bullets-impl.css +104 -0
- package/dist/components/blocks/feature-cards/FeatureCards.css +84 -0
- package/dist/components/blocks/feature-cards/FeatureCards.d.ts +24 -0
- package/dist/components/blocks/feature-cards/FeatureCards.js +66 -0
- package/dist/components/blocks/feature-cards/FeatureCards.types.d.ts +33 -0
- package/dist/components/blocks/feature-cards/FeatureCards.types.js +14 -0
- package/dist/components/blocks/feature-cards/feature-cards-impl.css +245 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.css +137 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.d.ts +39 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.js +167 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.types.d.ts +40 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.types.js +17 -0
- package/dist/components/blocks/feature-scroll/feature-scroll-impl.css +292 -0
- package/dist/components/blocks/feature-split/FeatureSplit.css +95 -0
- package/dist/components/blocks/feature-split/FeatureSplit.d.ts +30 -0
- package/dist/components/blocks/feature-split/FeatureSplit.js +38 -0
- package/dist/components/blocks/feature-split/FeatureSplit.types.d.ts +39 -0
- package/dist/components/blocks/feature-split/FeatureSplit.types.js +14 -0
- package/dist/components/blocks/feature-split/feature-split-impl.css +83 -0
- package/dist/components/blocks/landing-hero/LandingHero.css +85 -0
- package/dist/components/blocks/landing-hero/LandingHero.d.ts +41 -0
- package/dist/components/blocks/landing-hero/LandingHero.js +54 -0
- package/dist/components/blocks/landing-hero/LandingHero.types.d.ts +37 -0
- package/dist/components/blocks/landing-hero/LandingHero.types.js +15 -0
- package/dist/components/blocks/landing-hero/landing-hero-impl.css +355 -0
- package/dist/components/blocks/logo-columns/LogoColumns.css +161 -0
- package/dist/components/blocks/logo-columns/LogoColumns.d.ts +23 -0
- package/dist/components/blocks/logo-columns/LogoColumns.js +46 -0
- package/dist/components/blocks/logo-columns/LogoColumns.types.d.ts +46 -0
- package/dist/components/blocks/logo-columns/LogoColumns.types.js +18 -0
- package/dist/components/blocks/logo-columns/logo-columns-impl.css +188 -0
- package/dist/components/blocks/logo-rows/LogoRows.css +122 -0
- package/dist/components/blocks/logo-rows/LogoRows.d.ts +20 -0
- package/dist/components/blocks/logo-rows/LogoRows.js +43 -0
- package/dist/components/blocks/logo-rows/LogoRows.types.d.ts +36 -0
- package/dist/components/blocks/logo-rows/LogoRows.types.js +16 -0
- package/dist/components/blocks/logo-rows/logo-rows-impl.css +179 -0
- package/dist/components/blocks/page-header/PageHeader.css +79 -0
- package/dist/components/blocks/page-header/PageHeader.d.ts +34 -0
- package/dist/components/blocks/page-header/PageHeader.js +43 -0
- package/dist/components/blocks/page-header/PageHeader.types.d.ts +32 -0
- package/dist/components/blocks/page-header/PageHeader.types.js +14 -0
- package/dist/components/blocks/page-header/page-header-impl.css +176 -0
- package/dist/components/blocks/product-hero/ProductHero.css +86 -0
- package/dist/components/blocks/product-hero/ProductHero.d.ts +35 -0
- package/dist/components/blocks/product-hero/ProductHero.js +48 -0
- package/dist/components/blocks/product-hero/ProductHero.types.d.ts +37 -0
- package/dist/components/blocks/product-hero/ProductHero.types.js +15 -0
- package/dist/components/blocks/product-hero/product-hero-impl.css +354 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.css +245 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.d.ts +20 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.js +128 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.types.d.ts +54 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.types.js +26 -0
- package/dist/components/blocks/testimonial-row/testimonial-row-impl.css +195 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.css +181 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.d.ts +22 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.js +36 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.d.ts +49 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.js +21 -0
- package/dist/components/blocks/testimonial-slider/testimonial-slider-impl.css +202 -0
- package/dist/components/blocks/use-reveal.d.ts +46 -0
- package/dist/components/blocks/use-reveal.js +120 -0
- package/dist/components/blocks/use-rotation.d.ts +62 -0
- package/dist/components/blocks/use-rotation.js +176 -0
- package/dist/components/core/accordion-item/AccordionItem.css +6 -5
- package/dist/components/core/bottom-sheet/BottomSheet.css +1 -1
- package/dist/components/core/button/Button.css +63 -16
- package/dist/components/core/button/Button.d.ts +14 -12
- package/dist/components/core/button/Button.js +43 -14
- package/dist/components/core/button/Button.types.d.ts +9 -14
- package/dist/components/core/button/button-impl.css +25 -0
- package/dist/components/core/button-icon/ButtonIcon.css +31 -15
- package/dist/components/core/button-icon/ButtonIcon.d.ts +2 -2
- package/dist/components/core/button-icon/ButtonIcon.js +2 -2
- package/dist/components/core/button-icon/ButtonIcon.types.d.ts +4 -4
- package/dist/components/core/card/Card.css +13 -4
- package/dist/components/core/card/Card.types.d.ts +2 -1
- package/dist/components/core/card-body/CardBody.css +11 -6
- package/dist/components/core/card-body/CardBody.d.ts +1 -1
- package/dist/components/core/card-body/CardBody.js +2 -2
- package/dist/components/core/card-body/CardBody.types.d.ts +4 -1
- package/dist/components/core/card-body/CardBody.types.js +1 -0
- package/dist/components/core/card-button/CardButton.css +13 -4
- package/dist/components/core/card-button/CardButton.types.d.ts +2 -1
- package/dist/components/core/checkbox/Checkbox.css +8 -1
- package/dist/components/core/dropdown-menu/DropdownMenu.css +13 -12
- package/dist/components/core/dropdown-menu/DropdownMenu.d.ts +5 -3
- package/dist/components/core/dropdown-menu/DropdownMenu.js +5 -3
- package/dist/components/core/filter-chip/FilterChip.css +2 -1
- package/dist/components/core/footer/footer-impl.css +1 -1
- package/dist/components/core/footer-group/FooterGroup.css +8 -7
- package/dist/components/core/icon/Icon.css +1 -1
- package/dist/components/core/link/Link.css +1 -1
- package/dist/components/core/menu-item/MenuItem.css +1 -1
- package/dist/components/core/navbar/Navbar.css +7 -8
- package/dist/components/core/navbar/Navbar.d.ts +17 -1
- package/dist/components/core/navbar/Navbar.js +139 -12
- package/dist/components/core/navbar/Navbar.types.d.ts +23 -4
- package/dist/components/core/navbar/Navbar.types.js +1 -1
- package/dist/components/core/navbar/navbar-impl.css +10 -3
- package/dist/components/core/navbar/navbar-material.css +96 -0
- package/dist/components/core/navbar-item/NavbarItem.css +4 -4
- package/dist/components/core/navbar-menu/NavbarMenu.css +7 -5
- package/dist/components/core/navbar-menu/NavbarMenu.d.ts +1 -0
- package/dist/components/core/navbar-menu/NavbarMenu.js +1 -0
- package/dist/components/core/navbar-menu/navbar-menu-impl.css +7 -7
- package/dist/components/core/navbar-switcher/NavbarSwitcher.css +6 -5
- package/dist/components/core/navbar-switcher/NavbarSwitcher.d.ts +1 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.js +2 -1
- package/dist/components/core/option/Option.css +1 -1
- package/dist/components/core/pagination/Pagination.css +1 -75
- package/dist/components/core/pagination/Pagination.d.ts +4 -4
- package/dist/components/core/pagination/Pagination.js +11 -51
- package/dist/components/core/pagination/Pagination.types.d.ts +5 -17
- package/dist/components/core/pagination/Pagination.types.js +1 -3
- package/dist/components/core/pagination-dots/PaginationDots.css +60 -0
- package/dist/components/core/pagination-dots/PaginationDots.d.ts +25 -0
- package/dist/components/core/pagination-dots/PaginationDots.js +104 -0
- package/dist/components/core/pagination-dots/PaginationDots.types.d.ts +38 -0
- package/dist/components/core/pagination-dots/PaginationDots.types.js +9 -0
- package/dist/components/core/removable-chip/RemovableChip.css +3 -3
- package/dist/components/core/search-input/SearchInput.css +1 -1
- package/dist/components/core/segmented-control/SegmentedControl.css +1 -1
- package/dist/components/core/segmented-control-item/SegmentedControlItem.css +1 -1
- package/dist/components/core/select/Select.css +2 -1
- package/dist/components/core/select-chip/SelectChip.css +14 -7
- package/dist/components/core/select-chip/SelectChip.d.ts +1 -1
- package/dist/components/core/select-chip/SelectChip.js +7 -4
- package/dist/components/core/select-chip/SelectChip.types.d.ts +7 -1
- package/dist/components/core/select-chip/SelectChip.types.js +1 -1
- package/dist/components/core/select-chip/select-chip-impl.css +14 -3
- package/dist/components/core/status-dot/StatusDot.css +1 -1
- package/dist/components/core/subdomain-navbar/SubdomainNavbar.css +3 -3
- package/dist/components/core/tab/Tab.css +1 -1
- package/dist/components/core/tab-list/TabList.css +1 -1
- package/dist/components/core/table/table-impl.css +36 -14
- package/dist/components/core/table-header-cell/TableHeaderCell.css +5 -5
- package/dist/components/core/text-area/TextArea.css +1 -1
- package/dist/components/core/text-input/TextInput.css +1 -1
- package/dist/components/core/tooltip/Tooltip.css +1 -1
- package/dist/components/core/typography/Typography.css +5 -5
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +30 -0
- package/dist/components/logo-data.d.ts +24 -0
- package/dist/components/logo-data.js +11 -0
- package/dist/components/scroll-data.d.ts +64 -0
- package/dist/components/scroll-data.js +17 -0
- package/dist/components/testimonial-row-data.d.ts +51 -0
- package/dist/components/testimonial-row-data.js +11 -0
- package/dist/components/testimonial-slider-data.d.ts +26 -0
- package/dist/components/testimonial-slider-data.js +10 -0
- package/dist/marketing.css +385 -14
- package/package.json +1 -6
package/.llm/rules.md
CHANGED
|
@@ -95,6 +95,18 @@ Declared rather than emergent. Padding plus contents does clear 24px in several
|
|
|
95
95
|
|
|
96
96
|
Guidance only — cannot be checked automatically.
|
|
97
97
|
|
|
98
|
+
### A component is written along the reading axis, not along the page's left and right
|
|
99
|
+
|
|
100
|
+
Every measure, inset and placement in this package names an axis rather than a side: inline-size and block-size, padding-inline and padding-block, inset-inline-start and inset-block-end, margin-inline: auto, text-align: start. Written that way a component follows whichever direction the page is read in, and a band whose claim ranges to the leading edge with its subject on the trailing one is the same composition in Arabic as in English, mirrored, with nothing restated. Written as left and right it is the same pixels in both, which is a layout nobody designed for the second language.
|
|
101
|
+
|
|
102
|
+
The enum values follow the same rule and for the same reason. A prop that names where a picture sits takes start and end, never left and right — FeatureSplit, FeatureBullets and FeatureScroll all declare mediaPosition that way, and the flex directions they generate flip on their own because row already means the reading order. A value called left would have to be re-read as right by every author working in a mirrored page, which is a translation this system should be doing rather than asking for.
|
|
103
|
+
|
|
104
|
+
The guidance a contract carries is part of the component, so it follows too. Describing a claim as ranging left is describing one of the two languages, and it was written that way here for a while: three of the opening bands said so in their own intent. A reader in a mirrored page meets that sentence and has to decide whether the component is wrong or the sentence is, and neither answer is one documentation should force.
|
|
105
|
+
|
|
106
|
+
Two things genuinely have no logical form and are not covered by this. A CSS gradient takes a physical direction — there is no to inline-end — so a pattern that must mirror has to be stated twice under a direction query, and one that is periodic and centred, like PageHeader's rule grid, does not need to. A glyph that points the way onward is the other: an arrow is a picture of a direction, and mirroring it belongs to the icon set rather than to the component holding it.
|
|
107
|
+
|
|
108
|
+
Guidance only — cannot be checked automatically.
|
|
109
|
+
|
|
98
110
|
## Component rules
|
|
99
111
|
|
|
100
112
|
### Destructive actions require a confirmation step (`Button`) *(applies to something not built yet)*
|
|
@@ -115,6 +127,18 @@ Quill ships every system glyph three times — light, regular and solid — as s
|
|
|
115
127
|
|
|
116
128
|
Guidance only — cannot be checked automatically.
|
|
117
129
|
|
|
130
|
+
### A navigation bar holds at most two buttons: one primary, and one secondary beside it (`Button`)
|
|
131
|
+
|
|
132
|
+
The bar's actions are the conversion and the way back in for a reader who already has an account — sign up and log in. That is two things, and they rank: the one the site wants is primary and the other is secondary. A third button is a third thing the bar is asking for, and a row of three pills beside a mark and a set of destinations stops reading as a pair of actions and starts reading as a second navigation.
|
|
133
|
+
|
|
134
|
+
A single button is the primary. Alone, there is nothing for a secondary to be quieter than, and a bar whose only action is the quiet one has hidden the thing it exists to offer. Two buttons are one primary and one secondary, never two of either: two primaries are two demands, and two secondaries leave the reader to guess which one the site meant.
|
|
135
|
+
|
|
136
|
+
A switcher is not a button here — a DropdownMenu or a ButtonIcon for the language or the theme — and does not count against the two.
|
|
137
|
+
|
|
138
|
+
Guidance rather than a count. The bar is drawn with a second copy of an action in compactAction for narrow widths, and a count of Buttons under Navbar cannot tell that slot from utilities or a ranked pair from two primaries. Navbar checks the pair itself, on what utilities is handed, and says so in the console.
|
|
139
|
+
|
|
140
|
+
Guidance only — cannot be checked automatically.
|
|
141
|
+
|
|
118
142
|
### At most one primary button per view (`Button`)
|
|
119
143
|
|
|
120
144
|
Two primary actions compete for attention; the user cannot tell which one the system wants them to take.
|
package/.llm/tokens.md
CHANGED
|
@@ -13,16 +13,19 @@ one value at every width.
|
|
|
13
13
|
|
|
14
14
|
- `--color-bg-active` — Pressed state for interactive elements. Alpha-based like the hover and one step heavier, so it tints whatever surface it lands on — ink on light and paper on dark.
|
|
15
15
|
- `--color-bg-active-inverse` — Pressed state for an interactive element on a surface that runs against the mode, one step heavier than color.bg.hover-inverse. The mirror of color.bg.active, and paired with it on the same reasoning.
|
|
16
|
-
- `--color-bg-brand` —
|
|
16
|
+
- `--color-bg-active-on-brand-strong` — Pressed state for an interactive element standing on color.bg.brand-strong, one step heavier than color.bg.hover-on-brand-strong. White at eight in both modes. For a surface that flips with the mode use color.bg.active-inverse.
|
|
17
|
+
- `--color-bg-band-subtle` — A recessed band across the page, e.g. a section of steps or features set apart from the ones around it. gray.50 in light, white at six in dark. For a fill inside a control — a secondary button, a badge — use color.bg.subtle.
|
|
18
|
+
- `--color-bg-brand` — Primary action surface, e.g. sign-up button, hero CTA, promotional banner. The same coral in light and dark; pair with color.fg.on-brand for text.
|
|
17
19
|
- `--color-bg-brand-active` — Pressed state for color.bg.brand. One step further along the ramp than the hover, in the same direction, so a press reads as more of what the hover began.
|
|
18
20
|
- `--color-bg-brand-hover` — Hover state for color.bg.brand.
|
|
19
|
-
- `--color-bg-brand-strong` — A dark
|
|
21
|
+
- `--color-bg-brand-strong` — A dark surface, for a band breaking a long page or a card carrying more weight than its neighbours, e.g. a feature band, the footer. gray.950 in light and dark alike, so the band is the same wherever it is drawn. Pair with color.fg.on-brand-strong for text.
|
|
20
22
|
- `--color-bg-brand-subtle` — A brand ground quiet enough to read dark ink on. The solid coral takes white at 3.39:1 and is waived for a word; this pairs with color.fg.brand well past the bar, so a mark can be brand-coloured without spending the waiver.
|
|
21
23
|
- `--color-bg-danger` — Destructive action surface, e.g. cancel subscription, delete account. Pair with color.fg.on-solid for text.
|
|
22
24
|
- `--color-bg-danger-subtle` — Lightweight danger fill, e.g. error banners, danger badges. Pair with color.fg.danger for text.
|
|
23
25
|
- `--color-bg-field` — The ground of a control a reader types into or picks from — a text field, a select, an upload zone. An alpha, so it can never come out the same colour as the container holding it, which a solid can. For the container itself use color.bg.surface.
|
|
24
26
|
- `--color-bg-hover` — Hover state for interactive elements. Alpha-based, so it tints whatever surface it lands on rather than replacing it — ink on light and paper on dark, because a black alpha on a dark surface darkens what is already dark and reads as nothing at all.
|
|
25
27
|
- `--color-bg-hover-inverse` — Hover for an interactive element on a surface that runs against the mode — a dark chip in light. The mirror of color.bg.hover, which tints with the mode and so shows nothing on a ground the mode did not paint. Use color.bg.hover where the mode paints the ground.
|
|
28
|
+
- `--color-bg-hover-on-brand-strong` — Hover for an interactive element standing on color.bg.brand-strong, e.g. a navigation item or a plain icon button on a dark hero. White at four in both modes, because the band does not change. For a surface that flips with the mode use color.bg.hover-inverse.
|
|
26
29
|
- `--color-bg-info` — Informational surface, e.g. info banners, tips. Pair with color.fg.on-solid for text.
|
|
27
30
|
- `--color-bg-info-subtle` — Lightweight info fill, e.g. info badges, inline notices. Pair with color.fg.info for text.
|
|
28
31
|
- `--color-bg-overlay` — Scrim behind modal dialogs and drawers. Blocks interaction with content beneath.
|
|
@@ -31,14 +34,26 @@ one value at every width.
|
|
|
31
34
|
- `--color-bg-readonly` — A field whose value is fixed but still worth reading. Lighter than the disabled ground and at full contrast, which is the distinction: readonly is legible and settled, disabled recedes because it is not actionable.
|
|
32
35
|
- `--color-bg-selected` — The active or current item in a set of choices, e.g. selected nav item, current tab, highlighted row. Not for recessive areas — use color.bg.subtle.
|
|
33
36
|
- `--color-bg-strong` — Inverted neutral fill for an action that has to outrank everything around it — near-black in light and pure white in dark, the highest contrast the page can carry. Not a section ground: a band takes bg.subtle, bg.brand-strong or bg.brand. Pair with color.fg.on-strong.
|
|
34
|
-
- `--color-bg-
|
|
37
|
+
- `--color-bg-strong-on-brand` — The solid fill of a control on color.bg.brand, e.g. the primary action on the coral band. Near-black in both modes, because the band does not change — unlike color.bg.strong, which turns white in dark.
|
|
38
|
+
- `--color-bg-subtle` — A recessive fill inside a control or a small area, e.g. a secondary button, a neutral badge. For a band across the page use color.bg.band-subtle; for selected items, color.bg.selected.
|
|
39
|
+
- `--color-bg-subtle-on-brand-strong` — A recessive fill on a painted band — color.bg.brand-strong or the coral color.bg.brand — e.g. a secondary button there. White at six in both modes; hover and press layer color.bg.hover-on-brand-strong and color.bg.active-on-brand-strong over it.
|
|
35
40
|
- `--color-bg-success` — Confirmation surface, e.g. sign-up complete, payment confirmed. Pair with color.fg.on-solid for text.
|
|
36
41
|
- `--color-bg-success-subtle` — Lightweight success fill, e.g. success banners, success badges. Pair with color.fg.success for text.
|
|
37
42
|
- `--color-bg-surface` — A card on the page: one step from the ground, so it reads as recessed against the page and raised on a subtle band. For a card that floats above the page, color.bg.surface-raised.
|
|
43
|
+
- `--color-bg-surface-card-light` — A light card that stays light whatever the theme, e.g. a surface-light Card or CardButton set among dark ones. gray.50 in both modes. Pair with color.fg.on-surface-card-light; for a card that follows the theme use color.bg.surface.
|
|
44
|
+
- `--color-bg-surface-card-light-raised` — The light card on a subtle band. White in light mode, where the band is the light card's own gray.50 and it would vanish; gray.50 in dark, where the band is a tint over near-black. Pair with color.fg.on-surface-card-light.
|
|
45
|
+
- `--color-bg-surface-card-raised` — A card lifting off the ground behind it, e.g. a Card or CardButton on a color.bg.subtle band. White in light, white at six in dark, so a dark card tints the band instead of sitting on it as grey. Menus and popovers take color.bg.surface-raised.
|
|
46
|
+
- `--color-bg-surface-card-strong` — The dark fill of a card weightier than its neighbours, e.g. an accent-strong Card or CardButton. gray.900 in both modes, a step lighter than color.bg.brand-strong so it reads as a card, not a band.
|
|
47
|
+
- `--color-bg-surface-card-strong-raised` — The strong card on a subtle band. gray.900 in light mode, the strong card's own fill, which already stands off the gray.50 band; gray.800 in dark, where the band is a near-black tint the strong card would blend into. Pair with color.fg.on-brand-strong.
|
|
38
48
|
- `--color-bg-surface-inverse` — The quieter of the two surfaces on a dark ground, for a panel rather than a pill. color.bg.surface-raised-inverse is the stronger lift and is right on a control the size of a navbar's; at that weight a card-sized box reads as a pale patch rather than a surface.
|
|
39
49
|
- `--color-bg-surface-modal` — A surface that covers the page behind a scrim — dialogs, drawers, bottom sheets. The topmost plane there is, so it stays white in light where color.bg.surface is recessed. For one that floats without dimming what is under it use color.bg.surface-raised.
|
|
40
50
|
- `--color-bg-surface-raised` — A surface that lifts off the one behind it, e.g. a dropdown, a popover, a card on a color.bg.subtle band. A card on the page itself takes color.bg.surface, which reads as recessed against it instead.
|
|
41
51
|
- `--color-bg-surface-raised-inverse` — A raised surface on a ground that runs against the mode — a navigation bar's pill on a dark hero. An alpha rather than a grey step: a hero is often a photograph or a brand colour, which a solid surface would clash with.
|
|
52
|
+
- `--color-bg-surface-raised-on-brand-strong` — A raised surface on color.bg.brand-strong, e.g. the navigation bar's pill on a dark hero. White at twenty-four in both modes, because the band does not change. For one that flips with the mode use color.bg.surface-raised-inverse.
|
|
53
|
+
- `--color-bg-surface-translucent` — The base of a see-through surface with a blur behind it, e.g. the navigation bar's pill. Nearly opaque in its own ink — white in light, black in dark — so what scrolls behind cannot set its colour. color.bg.surface-translucent-tint goes over it.
|
|
54
|
+
- `--color-bg-surface-translucent-on-brand-strong` — The base of a see-through surface on color.bg.brand-strong, e.g. the navigation bar's pill on a dark hero. Black at eighty-eight in both modes, so a light photograph behind cannot wash it out.
|
|
55
|
+
- `--color-bg-surface-translucent-tint` — The lift laid over color.bg.surface-translucent, e.g. the navigation bar's pill. None in light, where the base is already the surface; white at sixteen in dark, which is what makes the pill read as a surface over the page.
|
|
56
|
+
- `--color-bg-surface-translucent-tint-on-brand-strong` — The lift laid over color.bg.surface-translucent-on-brand-strong, e.g. the navigation bar's pill on a dark hero. White at twelve in both modes, because the band does not change.
|
|
42
57
|
- `--color-bg-track` — The channel a thing travels or fills along — a grab handle on a sheet, a rail. An alpha rather than a ramp step, so it darkens whatever is behind it and stays a groove on a raised panel, where a fixed grey would stop matching the moment the surface changed.
|
|
43
58
|
- `--color-bg-track-active` — Pressed state for the same mark. One step further than the hover, in the same direction, so a press always reads as more than a hover.
|
|
44
59
|
- `--color-bg-track-hover` — Hover state for a mark drawn in color.bg.track, which is the only thing in this colour that hovers — a track itself never does. One step more ink, so a pointer over the mark reads as more, never less. An alpha like the track, so it keeps tinting what is behind it.
|
|
@@ -49,6 +64,7 @@ one value at every width.
|
|
|
49
64
|
- `--color-border-default` — Standard border for containers and controls, e.g. input outlines, grouped sections.
|
|
50
65
|
- `--color-border-focus` — The keyboard focus indicator — a border on some controls, a ring on others. Never remove: required for accessibility. Neutral rather than blue, so it is never mistaken for the danger a control is also able to show. Inverts by mode.
|
|
51
66
|
- `--color-border-focus-inverse` — The focus ring on a ground that runs against the mode. color.border.focus is near-black, which is invisible on a dark bar — and a focus ring that cannot be seen is the one affordance a keyboard reader has nothing to fall back on.
|
|
67
|
+
- `--color-border-focus-on-brand-strong` — The focus ring on color.bg.brand-strong, e.g. a navigation bar's controls on a dark hero, a footer's links. White in both modes, because the band does not change. For a surface that flips with the mode use color.border.focus-inverse.
|
|
52
68
|
- `--color-border-info` — Informational accent border, e.g. info banner edge, highlighted section.
|
|
53
69
|
- `--color-border-strong` — Emphasised border for active or prominent elements, e.g. active input, selected card edge.
|
|
54
70
|
- `--color-border-subtle` — A quiet separator, e.g. dividers, table rules. Alpha-based — works on any surface.
|
|
@@ -63,9 +79,12 @@ one value at every width.
|
|
|
63
79
|
- `--color-fg-info` — Informational text on neutral surfaces, e.g. links, tips, contextual help.
|
|
64
80
|
- `--color-fg-muted` — Supporting copy, e.g. subheadings, feature descriptions, form labels. Not for content the user must read to act.
|
|
65
81
|
- `--color-fg-muted-inverse` — Supporting copy on a dark ground, e.g. a footer's group labels. White at sixty-four, so it takes the hue of whatever the band is painted rather than sitting cool against a warm one — and so it stays muted on any dark ground instead of on one.
|
|
82
|
+
- `--color-fg-on-brand` — Text and marks on color.bg.brand, e.g. a primary button's label, a checked accent checkbox's tick. White in light and dark alike, because the brand fill does not change with the theme. For other solid fills — danger, success, info — use color.fg.on-solid.
|
|
66
83
|
- `--color-fg-on-brand-strong` — Text and glyphs on color.bg.brand-strong. White in both modes, that surface being dark in both — unlike color.fg.on-solid, which follows the theme.
|
|
67
|
-
- `--color-fg-on-solid` — Text on solid
|
|
84
|
+
- `--color-fg-on-solid` — Text on solid status fills, e.g. danger, success, info buttons and badges. For text on color.bg.brand use color.fg.on-brand; on neutral surfaces use color.fg.default.
|
|
68
85
|
- `--color-fg-on-strong` — Text on color.bg.strong. The opposite extreme from the fill, so the pair is always near-black on white or white on near-black.
|
|
86
|
+
- `--color-fg-on-strong-on-brand` — Text and glyphs on color.bg.strong-on-brand, the near-black fill on the coral band. White in both modes, because the fill does not change — unlike color.fg.on-strong, which follows the theme.
|
|
87
|
+
- `--color-fg-on-surface-card-light` — Text on color.bg.surface-card-light, e.g. a surface-light card's title and copy. gray.950 in both modes, because the card does not change. On the page's own ground use color.fg.default.
|
|
69
88
|
- `--color-fg-on-warning` — Text on a warning surface. Always dark because the warning background is bright in both modes.
|
|
70
89
|
- `--color-fg-required` — The mark that says a field must be filled. The same red as fg.danger and a role of its own, because required is not a verdict — a field carrying an asterisk has not failed anything yet.
|
|
71
90
|
- `--color-fg-success` — Positive text on neutral surfaces, e.g. profit values, confirmation messages.
|
|
@@ -74,7 +93,7 @@ one value at every width.
|
|
|
74
93
|
|
|
75
94
|
## space
|
|
76
95
|
|
|
77
|
-
- `--space-actions-gap`
|
|
96
|
+
- `--space-actions-gap` — The step between two calls to action standing side by side. Eight: they are one decision offered two ways, not two decisions, and the reference design sets them this close on every band. Sixteen read as two separate offers.
|
|
78
97
|
- `--space-control-lg` — Side padding inside a large pill control. Half of size.control.lg, on the same reasoning as the default step. It coincides with space.inset.lg today and is still its own role: one follows a control's height, the other a section's rhythm, and they are free to move apart.
|
|
79
98
|
- `--space-control-md` — Side padding inside a default-size pill control. Half of size.control.md, so the corner radius and the padding are one measure and a label starts where the curve stops. The inset scale has no step here — its steps answer to sections, not to a control's geometry.
|
|
80
99
|
- `--space-control-sm` — Side padding inside a small pill control. Half of size.control.sm, on the same reasoning as the default step — the corner radius and the padding are one measure, so a label starts where the curve stops.
|
|
@@ -88,7 +107,7 @@ one value at every width.
|
|
|
88
107
|
- `--space-gap-xs` — Tightest gap between related elements, e.g. icon and label, inline text pairs.
|
|
89
108
|
- `--space-grid-gutter` **adapts** — The space between two cards, across and down. One value on both axes, so a grid reads as an even field rather than as rows with a seam between them.
|
|
90
109
|
- `--space-heading-content` **adapts** — Between a heading group and the content it introduces, stacked or side by side. Measured from the last part the group actually shows, so a section opens the same way whether or not every part is present.
|
|
91
|
-
- `--space-heading-description-actions`
|
|
110
|
+
- `--space-heading-description-actions` — The step from a description down to what a reader can do about it. Twenty-four, which is the reference design's step on every opening band, and what the mobile override already said.
|
|
92
111
|
- `--space-heading-eyebrow-title` **adapts** — Between an eyebrow and the title under it. The tightest step in the group, because an eyebrow reads as the title's first line rather than as a line of its own.
|
|
93
112
|
- `--space-heading-title-description` — Between a display title and the description under it. Smaller than it looks: a title's leading and descender depth sit inside the gap, and both scale with the type, so a smaller title takes the compact step instead.
|
|
94
113
|
- `--space-heading-title-description-compact` — The same step under a title that is not a display size — a card's, a panel's. Half the measure because the leading above it is half as deep, and what the eye reads is this plus that leading.
|
|
@@ -108,6 +127,9 @@ one value at every width.
|
|
|
108
127
|
|
|
109
128
|
## size
|
|
110
129
|
|
|
130
|
+
- `--size-avatar` — A person's picture beside their words — the author of a testimonial. Forty-eight, round: large enough to recognise a face, small enough to stay a signature under the quote rather than a portrait above it.
|
|
131
|
+
- `--size-backdrop-blur` — How far a see-through surface blurs what is behind it, e.g. the navigation bar over the page it scrolls across. Enough that the words behind it stop reading as words, so the bar's own stay legible.
|
|
132
|
+
- `--size-band-compact` — The least height an opening band takes when it is not a screen tall — a company, legal or support page, where a full viewport would be a wall before the first sentence. Deep enough that the band reads as a band rather than a gap the title fell into.
|
|
111
133
|
- `--size-bar-height` — The height of a collapsed navigation bar, which both bars here take. Declared rather than left to what a page hands the bar: an action beside the mark would otherwise set it.
|
|
112
134
|
- `--size-breakpoint-lg` — Where a bar has room for its destinations. A value to read, not a condition to write: `var()` is not allowed in a query, so the seven stylesheets that bend here still carry 64rem themselves.
|
|
113
135
|
- `--size-breakpoint-md` — Where the phone's type layer stops — the mobile overrides resolve below it, so 767 is the last width that reads as a phone. A value to read, not a condition to write: `var()` is not allowed in a media query.
|
|
@@ -116,17 +138,25 @@ one value at every width.
|
|
|
116
138
|
- `--size-control-lg` — Height of a large control, for a hero or a conversion band. Twice space.control.lg, on the same reasoning as the default step.
|
|
117
139
|
- `--size-control-md` — Height of a default-size control, the same measure product gives its own default. Twice space.control.md, so on a pill the corner radius and the side padding are one measure and a label starts where the curve stops.
|
|
118
140
|
- `--size-control-sm` — Height of a small control — a picker in a navigation bar, a field in a filter row. Half of it is space.control.sm and a quarter is radius.control.sm, the ratio every step of this ramp holds. Desktop only: below what a finger reliably hits.
|
|
141
|
+
- `--size-dot-current` — How wide the current mark in a row of dots stretches, against size.dot.diameter for the rest — a pill three dots long, so where the reader is reads by shape.
|
|
119
142
|
- `--size-dot-diameter` — The mark standing in for one page of a short sequence, or for a status beside a name. Eight: small enough that a row of ten reads as a row rather than as ten controls, and large enough to find at arm's length.
|
|
120
143
|
- `--size-grid-track-lg` — For a cell holding a picture as well as words, or a pricing plan with a list under it. Three fit the page's measure and four do not, which is what makes this the floor for a grid meant to read as three across.
|
|
121
144
|
- `--size-grid-track-md` — The default track floor, for a feature card: a heading and a line or two beneath it. Four of these fit the page's measure, so a grid asking for three has room to spare and drops to two on a tablet rather than at the first sign of pressure.
|
|
122
145
|
- `--size-grid-track-sm` — The narrowest a grid track goes before the grid drops a column. For a cell holding a logo, an icon and a word, or one short claim — six of them clear the page's measure with the page gutter still on both sides.
|
|
123
146
|
- `--size-heading-group-max` — How wide an eyebrow, a title and a description may run as a block. Independent or centred groups take this; one that has to sit on the grid takes eight columns instead, which is a span rather than a measure.
|
|
147
|
+
- `--size-logo-columns-height` — How much of a LogoColumns wall shows at once, from the fold. Tall enough that a column reads as running on past both edges; half of it on a phone.
|
|
148
|
+
- `--size-logo-rows-tile` — The width of a tile on a LogoRows, from the fold; three quarters of it on a phone. Wide enough for a wordmark, narrow enough that a row shows several at once.
|
|
124
149
|
- `--size-measure-description` — How wide a supporting description runs. Wider than a title because it is read rather than taken in, and narrower than long-form because it sits under something.
|
|
150
|
+
- `--size-measure-heading` — The width a centred heading block is held to. Narrower than the page measure, because a title centred across the full 1280 is read from a different edge on every line.
|
|
151
|
+
- `--size-measure-hero-description` — How wide the description under an opening band's title runs, e.g. in LandingHero, ProductHero, PageHeader. Wider than size.measure.description because it is set larger and read once, at the top.
|
|
152
|
+
- `--size-measure-hero-heading` — The width the text column of a band that opens a page is held to, e.g. PageHeader's title and actions. Wider than size.measure.heading because a page's name is set at h1 and 846 breaks it early.
|
|
125
153
|
- `--size-measure-long-form` — How wide running text runs. Past this the eye loses the line it was on when it returns to the left edge, which is the whole reason a measure exists.
|
|
126
154
|
- `--size-measure-title` — How wide a title runs before it wraps. A starting point — eighteen to twenty-four after a look. `ch` is the width of the font's zero, so it is a measure rather than a letter count, and typed string because a Figma variable carries a number.
|
|
127
155
|
- `--size-menu-panel-max` — The widest a section's menu panel gets. Narrower than the page's own measure on purpose: a panel is scanned across with a pointer already on it, and one as wide as the page leaves its last column a long way from the name that opened it.
|
|
128
156
|
- `--size-menu-panel-min` — The shortest a section's menu panel gets, whatever it holds. A bar's sections rarely have the same number of destinations, and panels that each took their own height would change size as the reader moved along the row.
|
|
129
157
|
- `--size-menu-max` — The tallest a menu's surface gets before its commands scroll. Product's measure, and counted in rows: five whole and part of a sixth at either size. Neither lands on a row boundary — a ceiling cutting clean at the last full row looks like the whole set.
|
|
158
|
+
- `--size-review-card-min` — The shortest a TestimonialRow card gets. A floor, not a height: a one-line review keeps a card's shape, and a longer one still grows it.
|
|
159
|
+
- `--size-rule-grid-pitch` — How often the rule grid repeats on a band that paints one. A pitch rather than a gap: it is how far apart a decorative line recurs, not the space between two things a reader is comparing.
|
|
130
160
|
- `--size-sheet-handle-height` — The thickness of that handle. At the smallest step the scale has, because a grab bar is a hint that the sheet moves rather than a part of what it holds.
|
|
131
161
|
- `--size-sheet-handle-width` — The width of the grab handle at the top of a BottomSheet. Wide enough to take hold of, narrow enough to read as a grip rather than as a rule across the sheet.
|
|
132
162
|
- `--size-sheet-max` — The widest a BottomSheet gets before it stops growing and centres. A sheet is a small-screen pattern, and one running the width of a desktop is a dialog that arrived from the wrong edge.
|
|
@@ -139,6 +169,7 @@ one value at every width.
|
|
|
139
169
|
- `--size-spinner-sm` — Spinner diameter at size sm. Sixteen, which is the size of the body copy it sits beside — an indicator in a line of text reads as part of the line rather than as something dropped into it.
|
|
140
170
|
- `--size-switcher-panel-width` — The width of a switcher's floating panel. Stated because the panel is out of flow and would otherwise shrink to the trigger it hangs from, wrapping every choice and running the set down the page.
|
|
141
171
|
- `--size-target-min` — The smallest a thing a pointer has to hit may be. Bind it as a minimum on any control whose size would otherwise come from its contents — a pressable card is as big as its words, and one holding a single short line is smaller than a fingertip.
|
|
172
|
+
- `--size-testimonial-art` — The decorative pictures in a TestimonialSlider's corners, as squares. Large enough to read as pictures, small enough to leave the card the quote's.
|
|
142
173
|
- `--size-tooltip-max` — The widest a tooltip gets before its text wraps. Short enough that the eye finds the start of the next line without hunting for it, which is the whole job of a measure — and a tooltip that needs more than two lines is a tooltip carrying something that belongs on the page.
|
|
143
174
|
|
|
144
175
|
## radius
|
|
@@ -189,12 +220,18 @@ one value at every width.
|
|
|
189
220
|
- `--font-body-sm-line-height`
|
|
190
221
|
- `--font-body-sm-size`
|
|
191
222
|
- `--font-body-sm-weight`
|
|
192
|
-
- `font.eyebrow` —
|
|
193
|
-
- `--font-eyebrow-family`
|
|
194
|
-
- `--font-eyebrow-letter-spacing`
|
|
195
|
-
- `--font-eyebrow-line-height`
|
|
196
|
-
- `--font-eyebrow-size`
|
|
197
|
-
- `--font-eyebrow-weight`
|
|
223
|
+
- `font.eyebrow.lg` — The line that leads into a display claim on an opening band, sized against the heading under it rather than against body text. Sentence case, unlike the small step: capitals are what make a twelve-pixel label a label, and at this size they shout.
|
|
224
|
+
- `--font-eyebrow-lg-family`
|
|
225
|
+
- `--font-eyebrow-lg-letter-spacing`
|
|
226
|
+
- `--font-eyebrow-lg-line-height`
|
|
227
|
+
- `--font-eyebrow-lg-size` **adapts**
|
|
228
|
+
- `--font-eyebrow-lg-weight`
|
|
229
|
+
- `font.eyebrow.sm` — Uppercase category labels above a headline — section tags, plan badges, feature categories. Carries the size, weight and wide tracking that setting needs; the capitals are the component's, through text-transform, which leaves the accessible name in the case it was written.
|
|
230
|
+
- `--font-eyebrow-sm-family`
|
|
231
|
+
- `--font-eyebrow-sm-letter-spacing`
|
|
232
|
+
- `--font-eyebrow-sm-line-height`
|
|
233
|
+
- `--font-eyebrow-sm-size`
|
|
234
|
+
- `--font-eyebrow-sm-weight`
|
|
198
235
|
- `font.field-label.lg` — The words naming a field in a large form, the step that pairs with a large control. Sized with the field it sits above, weighted like every other step of this role.
|
|
199
236
|
- `--font-field-label-lg-family`
|
|
200
237
|
- `--font-field-label-lg-letter-spacing`
|
|
@@ -310,7 +347,9 @@ one value at every width.
|
|
|
310
347
|
|
|
311
348
|
## motion
|
|
312
349
|
|
|
350
|
+
- `--motion-distance-drift` — How far decoration travels against the scroll while its section passes through the view, one way or the other. Far enough to be seen moving as the reader scrolls past, so it reads as depth.
|
|
313
351
|
- `--motion-duration-dramatic` — Editorial hero entrances for visual impact, e.g. hero headline revealing, landing page title appearing. Not for scroll reveals — use motion.duration.reveal.
|
|
352
|
+
- `--motion-duration-dwell` — How long a rotating message holds before the next one moves in, e.g. a CTA banner's slides. Long enough to read a headline and a line under it; the reference site's 2000 moved before a reader reached the button.
|
|
314
353
|
- `--motion-duration-fast` — Direct user actions that should feel instant, e.g. hover, press, toggle.
|
|
315
354
|
- `--motion-duration-instant` — A change the reader has already moved past — a tooltip leaving once the pointer is elsewhere. Not a short duration but no duration: animating a dismissal keeps a thing on screen after the reason for it has gone.
|
|
316
355
|
- `--motion-duration-media-hover` — How long art takes to settle inside a frame that holds still. Longer than duration.normal, which suits a card that lifts and is over; a picture that zooms is still on screen when it stops and the eye follows it the whole way.
|
|
@@ -320,6 +359,7 @@ one value at every width.
|
|
|
320
359
|
- `--motion-duration-shift` — A surface rearranging itself between two resting states on the reader's scroll — a navigation bar gathering, and ungathering on the way back. Longer than a UI element entering, because nobody asked for it.
|
|
321
360
|
- `--motion-duration-slow` — Large UI transitions, e.g. accordions expanding, page transitions, interactive demos.
|
|
322
361
|
- `--motion-duration-spinner` — One full rotation of a spinner. Fast enough to read as working, slow enough that the stroke does not blur into a solid ring.
|
|
362
|
+
- `--motion-duration-stagger` — The step between one part of a section arriving and the next. A gap rather than a length: five parts at this step trail the first by less than half a second, so a block still arrives as one thing rather than assembling itself while a reader waits.
|
|
323
363
|
- `--motion-easing-enter` — UI elements arriving on screen — decelerates into place, e.g. dropdown opening, tooltip appearing.
|
|
324
364
|
- `--motion-easing-exit` — UI elements leaving the screen — accelerates away, e.g. menu closing, notification dismissing.
|
|
325
365
|
- `--motion-easing-media-hover` — Art moving inside a frame that holds still. Symmetric, unlike easing.standard: a hover runs forward on enter and backward on leave, so a one-way curve that settles hard reads as a snap going one way and a drift the other.
|
|
@@ -327,15 +367,19 @@ one value at every width.
|
|
|
327
367
|
- `--motion-easing-shift` — Symmetric, for a change that runs both ways: a bar gathering on scroll and ungathering on the way back should read the same in each direction, which easing.standard cannot do.
|
|
328
368
|
- `--motion-easing-spinner` — Constant-speed rotation for a spinner. Linear because a loop is the one case with no arrival to ease into — any acceleration lands a seam at the point the animation restarts, and the eye finds it on the second turn.
|
|
329
369
|
- `--motion-easing-standard` — Default easing for anything moving within the viewport. Use this unless the element is specifically entering, exiting, or revealing.
|
|
370
|
+
- `--motion-scale-band-exit` — How far an opening band draws back as it scrolls out. Its own role rather than motion.scale.enter, which is named for something arriving.
|
|
330
371
|
- `--motion-scale-enter` — What a component scales from when something reveals it — a tooltip appearing. Needs a transform origin on the edge nearest its anchor, or it grows out of its own middle. The counterpart to scale.hover, which is a response rather than an entrance.
|
|
331
372
|
- `--motion-scale-hover` — How much a control grows under the cursor on hover. Deliberately small — a control that grows past the pointer fires its own mouse-out.
|
|
332
373
|
- `--motion-scale-media-hover` — How much art grows inside a frame that holds still — an editorial card's picture under the cursor. Twice motion.scale.hover, which stays smaller because a control can outrun its own pointer and a framed picture cannot.
|
|
333
374
|
- `--motion-translate-enter` — Where a surface waits before something reveals it: level on the inline axis, its own full height down the block one. A share of the element rather than of the page, so a sheet travels exactly its own height whatever that turns out to be.
|
|
334
375
|
- `--motion-translate-hover` — How far a pressable surface rises under the cursor. A fixed distance rather than a share of the element, so a tall card and a short one lift by the same amount and a row of them stays level. Small enough that nothing it sits beside looks disturbed.
|
|
376
|
+
- `--motion-translate-reveal` — How far a section waits below where it lands, before the scroll brings it up. A fixed distance rather than a share of the block, so a hero a screen tall and a split half that arrive by the same movement. Pairs with motion.easing.reveal.
|
|
335
377
|
|
|
336
378
|
## opacity
|
|
337
379
|
|
|
338
380
|
- `--opacity-disabled` — How far a control recedes when it is unavailable. Applied to the control as a whole rather than re-colouring its parts, so what is inside keeps its relationships and the whole thing reads as one unavailable object.
|
|
381
|
+
- `--opacity-dot-current` — The position in a row of dots that the reader is on — the ground's own ink at full strength, stretched into a pill so the current one is told apart by shape as well as by weight.
|
|
382
|
+
- `--opacity-dot-rest` — The positions in a row of dots that the reader is not on, e.g. a slider's other slides. Drawn in the ground's own ink at forty-eight, so the row reads on any band without a colour of its own.
|
|
339
383
|
- `--opacity-hidden` — What a component fades from when something reveals it. Not a dimming treatment — something unavailable or quiet says so in its own colour role, where the contrast checker can see it. The first entry in a group this package had left empty.
|
|
340
384
|
- `--opacity-muted` — A mark at rest, before a pointer reaches it. For artwork that carries its own colours and so cannot be quietened by an ink role — a brand logo, a partner mark — where every other quiet thing in this system says so in colour.
|
|
341
385
|
- `--opacity-track` — How far a track recedes behind the thing travelling over it. Both are drawn in one colour, so this alpha is the only thing separating them — which is why it is a ratio and not a colour role.
|
package/AGENTS.md
CHANGED
|
@@ -32,9 +32,14 @@ and Red Hat Mono but cannot carry the files. An app that already self-hosts the
|
|
|
32
32
|
(next/font, Fontsource) skips `fonts.css` and sets `--font-family-sans` /
|
|
33
33
|
`--font-family-mono` instead; the README covers that path.
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
Dark is `data-theme="dark"` on any ancestor, usually `<html>`. Both themes live in that one
|
|
36
|
+
stylesheet — there is no second import and no provider. The two attributes are independent:
|
|
37
|
+
the theme can sit above the scope, on the same element as it, or below it.
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<html data-theme="dark">
|
|
41
|
+
<body><div data-dds-context="marketing"> <!-- dark, from here down --></div></body>
|
|
42
|
+
```
|
|
38
43
|
|
|
39
44
|
## Server Components
|
|
40
45
|
|
|
@@ -48,6 +53,8 @@ a component you give `onChange` or `onClick` to goes in a file of your own that
|
|
|
48
53
|
|
|
49
54
|
## Rules that span components
|
|
50
55
|
|
|
56
|
+
- **A component is written along the reading axis, not along the page's left and right**
|
|
57
|
+
- **A navigation bar holds at most two buttons: one primary, and one secondary beside it**
|
|
51
58
|
- **A section that paints a ground sets the ink to go with it**
|
|
52
59
|
- **A section's title is centred over stacked content, starts beside content in columns, and starts on a phone**
|
|
53
60
|
- **Anything a pointer has to hit is at least 24px in both directions**
|
|
@@ -101,6 +108,7 @@ screen is built in is not something to reach for while building a control.
|
|
|
101
108
|
- **NavbarSwitcherOption** — A NavbarSwitcher needs its choices
|
|
102
109
|
- **Option** — An answer inside a control that opens a list
|
|
103
110
|
- **Pagination** — An index or archive has been split across pages and the reader needs to move through it
|
|
111
|
+
- **PaginationDots** — Showing where the reader is in a short sequence they move through
|
|
104
112
|
- **RemovableChip** — An index shows the narrowings currently applied above its results, and each has to come off on its own without clearing the rest
|
|
105
113
|
- **SearchInput** — A help centre, a knowledge base, or documentation
|
|
106
114
|
- **SegmentedControl** — Two to four alternatives that exclude one another, where the whole set is worth showing at once and the reader decides by weighing them side by side rather than recalling which exist
|
|
@@ -131,6 +139,23 @@ screen is built in is not something to reach for while building a control.
|
|
|
131
139
|
- **Scroller** — A set is longer than the space and its order is worth keeping
|
|
132
140
|
- **Stack** — Two or more things are read down the page in order and the space between them is the same the whole way down
|
|
133
141
|
|
|
142
|
+
### Blocks — the sections a page is built from, and the rhythm between them
|
|
143
|
+
|
|
144
|
+
- **CtaBanner** — A short, high-contrast promotion with one clear action
|
|
145
|
+
- **CtaBannerSlider** — Rotating between two or three genuinely different promotions without a hero's weight
|
|
146
|
+
- **FaqAccordion** — The questions a reader asks before acting
|
|
147
|
+
- **FeatureBullets** — A page has to list what a product or a plan includes, and the list is the argument
|
|
148
|
+
- **FeatureCards** — Three or four things a product does, each a heading and a sentence, read side by side and compared at a glance
|
|
149
|
+
- **FeatureScroll** — A page has three or more things of the same kind to explain, each with a picture worth a screen
|
|
150
|
+
- **FeatureSplit** — A page needs one more point about something it has already introduced, with a picture to carry it
|
|
151
|
+
- **LandingHero** — A main landing page needs its opening band
|
|
152
|
+
- **LogoColumns** — Showing the partners, integrations or payment methods behind a claim
|
|
153
|
+
- **LogoRows** — Showing the partners, integrations or payment methods behind a claim under it, where the words lead and the logos follow
|
|
154
|
+
- **PageHeader** — A company, legal or support page needs its opening band
|
|
155
|
+
- **ProductHero** — A product or a market page needs its opening band
|
|
156
|
+
- **TestimonialRow** — Five to ten short, rated reviews collected by a review service, where seeing several at once is the point and the overall score is worth stating
|
|
157
|
+
- **TestimonialSlider** — Two to five real quotes from partners or customers, each a few sentences, read one at a time
|
|
158
|
+
|
|
134
159
|
## Components that need mounting
|
|
135
160
|
|
|
136
161
|
These do not work from the import alone. Each has a Behaviour section in its own document
|
package/README.md
CHANGED
|
@@ -6,10 +6,12 @@ pages, pricing, sign-up.
|
|
|
6
6
|
**Working with an AI agent?** Point it at [`AGENTS.md`](./AGENTS.md) in this package. It is
|
|
7
7
|
the short version of everything below and says which of the `.llm/` documents to open.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
It has two kinds of component: **core** components — Button, Navbar, Card, Link, the form
|
|
10
|
+
controls and the rest — and **blocks**, the bands a page is built from: `LandingHero`,
|
|
11
|
+
`ProductHero` and `PageHeader` to open a page, and `FeatureSplit`, `FeatureBullets` and
|
|
12
|
+
`FeatureScroll` for the sections under it. `AGENTS.md` lists every one of them with a line
|
|
13
|
+
on when to reach for it. Product apps want
|
|
14
|
+
[`@deriv-com/dds-product`](https://www.npmjs.com/package/@deriv-com/dds-product).
|
|
13
15
|
|
|
14
16
|
## Install
|
|
15
17
|
|
|
@@ -26,19 +28,37 @@ npm install react react-dom @deriv-com/quill-icons-web
|
|
|
26
28
|
|
|
27
29
|
## Use
|
|
28
30
|
|
|
29
|
-
Import the stylesheet once, at the root of your app
|
|
31
|
+
Import the stylesheet once, at the root of your app. It defines every token this package's
|
|
32
|
+
components bind to — without it they render unstyled.
|
|
30
33
|
|
|
31
34
|
```tsx
|
|
32
35
|
import '@deriv-com/dds-marketing/marketing.css'
|
|
33
36
|
```
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
Then put `data-dds-context="marketing"` on whatever wraps the components — the app root, or
|
|
39
|
+
the section, if marketing and product live on one page. Component rules are published only
|
|
40
|
+
inside that scope, because both packages emit classes like `.dds-button` and one would
|
|
41
|
+
otherwise paint the other. Without it the components render unstyled too.
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
Then import components by name:
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import { Button, LandingHero } from '@deriv-com/dds-marketing'
|
|
47
|
+
|
|
48
|
+
export function Home() {
|
|
49
|
+
return (
|
|
50
|
+
<div data-dds-context="marketing">
|
|
51
|
+
<LandingHero
|
|
52
|
+
title="Trade smarter with Deriv"
|
|
53
|
+
description="Access 250+ markets with tight spreads and powerful tools."
|
|
54
|
+
actions={<Button href="/signup">Get started free</Button>}
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Each component brings its own stylesheet with it, so nothing else needs importing.
|
|
42
62
|
|
|
43
63
|
## Fonts
|
|
44
64
|
|
|
@@ -74,20 +94,20 @@ Every type role reads its family from these two variables, so this redirects the
|
|
|
74
94
|
system at once. Load weights 400–700 for Inter (a variable font covers this in one file);
|
|
75
95
|
a missing weight does not fall back visibly — the browser synthesises a faux bold instead.
|
|
76
96
|
|
|
77
|
-
##
|
|
78
|
-
|
|
79
|
-
`marketing.css` ships light only. It contains no `[data-theme="dark"]` block, so setting
|
|
80
|
-
that attribute — anywhere, including on `<html>` for the rest of your app — leaves these
|
|
81
|
-
components light. There is nothing to configure and nothing to guard against.
|
|
97
|
+
## Light and dark, and a viewport axis
|
|
82
98
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
publishes in its own manifest:
|
|
99
|
+
`marketing.css` defines both themes. Dark is selected by `data-theme="dark"` on any
|
|
100
|
+
ancestor — usually `<html>`:
|
|
86
101
|
|
|
87
|
-
```
|
|
88
|
-
|
|
102
|
+
```html
|
|
103
|
+
<html data-theme="dark">
|
|
104
|
+
<body>
|
|
105
|
+
<div data-dds-context="marketing"> <!-- dark, from here down -->
|
|
89
106
|
```
|
|
90
107
|
|
|
108
|
+
The theme attribute and the context attribute are independent, and the theme may sit above
|
|
109
|
+
the scope, on the same element, or below it. There is no provider and no second import.
|
|
110
|
+
|
|
91
111
|
Marketing does carry a mobile viewport axis: seven roles take different values below
|
|
92
112
|
768px, applied automatically and overridable with `data-dds-viewport="mobile"` or
|
|
93
113
|
`"desktop"` when a page renders a device frame inside a wider window.
|
|
@@ -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
|
+
}
|