@deriv-com/dds-marketing 0.2.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.llm/components/accordion.md +9 -1
- package/.llm/components/accordionitem.md +9 -1
- package/.llm/components/aspectratio.md +9 -1
- package/.llm/components/badge.md +9 -1
- package/.llm/components/bottomsheet.md +9 -1
- package/.llm/components/breadcrumb.md +9 -1
- package/.llm/components/breadcrumbitem.md +9 -1
- package/.llm/components/button.md +55 -27
- package/.llm/components/buttonicon.md +16 -8
- package/.llm/components/card.md +16 -2
- package/.llm/components/cardbody.md +29 -3
- package/.llm/components/cardbutton.md +16 -2
- package/.llm/components/checkbox.md +9 -1
- package/.llm/components/ctabanner.md +186 -0
- package/.llm/components/ctabannerslider.md +204 -0
- package/.llm/components/divider.md +9 -1
- package/.llm/components/dropdownmenu.md +15 -7
- 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 +9 -1
- package/.llm/components/footer.md +9 -1
- package/.llm/components/footergroup.md +9 -1
- package/.llm/components/grid.md +9 -1
- package/.llm/components/icon.md +21 -3
- package/.llm/components/landinghero.md +254 -0
- package/.llm/components/link.md +13 -5
- package/.llm/components/logocolumns.md +235 -0
- package/.llm/components/logorows.md +212 -0
- package/.llm/components/menuitem.md +9 -1
- package/.llm/components/navbar.md +80 -16
- package/.llm/components/navbaritem.md +10 -2
- package/.llm/components/navbarmenu.md +9 -1
- package/.llm/components/navbarmenugroup.md +9 -1
- package/.llm/components/navbarpanel.md +10 -2
- package/.llm/components/navbarswitcher.md +10 -2
- package/.llm/components/navbarswitcheroption.md +9 -1
- package/.llm/components/option.md +9 -1
- package/.llm/components/pageheader.md +231 -0
- package/.llm/components/pagination.md +27 -90
- package/.llm/components/paginationdots.md +215 -0
- package/.llm/components/producthero.md +248 -0
- package/.llm/components/removablechip.md +9 -1
- package/.llm/components/row.md +9 -1
- package/.llm/components/scroller.md +9 -1
- package/.llm/components/searchinput.md +9 -1
- package/.llm/components/segmentedcontrol.md +9 -1
- package/.llm/components/segmentedcontrolitem.md +9 -1
- package/.llm/components/select.md +9 -1
- package/.llm/components/selectchip.md +57 -16
- package/.llm/components/spinner.md +9 -1
- package/.llm/components/stack.md +9 -1
- package/.llm/components/statusdot.md +9 -1
- package/.llm/components/subdomainnavbar.md +9 -1
- package/.llm/components/tab.md +11 -3
- package/.llm/components/table.md +9 -1
- package/.llm/components/tablebody.md +9 -1
- package/.llm/components/tablecell.md +9 -1
- package/.llm/components/tablehead.md +9 -1
- package/.llm/components/tableheadercell.md +9 -1
- package/.llm/components/tablerow.md +9 -1
- package/.llm/components/tablist.md +9 -1
- package/.llm/components/testimonialrow.md +235 -0
- package/.llm/components/testimonialslider.md +254 -0
- package/.llm/components/textarea.md +9 -1
- package/.llm/components/textinput.md +9 -1
- package/.llm/components/tooltip.md +9 -1
- package/.llm/components/typography.md +9 -1
- 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 +43 -9
- package/.llm/tokens.md +56 -12
- package/AGENTS.md +32 -8
- 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/link/Link.js +5 -5
- 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/Tab.types.d.ts +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
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Scoped to this package, like the generated sheet beside it.
|
|
3
|
+
*
|
|
4
|
+
* `:where([data-dds-context="marketing"])` confines these rules without contributing specificity,
|
|
5
|
+
* so each is decided against the generated rule on its own terms. Rules that have to win are
|
|
6
|
+
* written a class deeper than they look, which is what footer-impl.css does and for the same
|
|
7
|
+
* reason: weight rather than which sheet the bundler happened to write last.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* The photograph, drawn the one way a band wants it.
|
|
12
|
+
*
|
|
13
|
+
* The page passes which image; how it is fitted is this component's decision and belongs here
|
|
14
|
+
* rather than in the inline style, where a page could not see it and a reader of the markup would
|
|
15
|
+
* think the four properties were the page's choice. `cover` because a hero is a band of fixed
|
|
16
|
+
* height and a photograph that letterboxed would show the ground through it.
|
|
17
|
+
*/
|
|
18
|
+
:where([data-dds-context="marketing"]) .dds-landinghero {
|
|
19
|
+
background-position: center;
|
|
20
|
+
background-repeat: no-repeat;
|
|
21
|
+
background-size: cover;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
* A title with nothing under it carries no step under it.
|
|
26
|
+
*
|
|
27
|
+
* The steps inside the text block sit on each part's own `margin-block-end`, because eyebrow-to-
|
|
28
|
+
* title and title-to-description are two roles that agree at full width and part company on a
|
|
29
|
+
* phone. The cost of that arrangement is a trailing margin: with `description` absent the title is
|
|
30
|
+
* the last child and its step is measured against nothing, which adds sixteen pixels to the step
|
|
31
|
+
* `content` already sets between the text and the actions.
|
|
32
|
+
*
|
|
33
|
+
* `:last-child` is the condition itself rather than a prop standing in for it — the description is
|
|
34
|
+
* one of two parts that can follow the title, and asking the DOM which is last is the question with
|
|
35
|
+
* one answer.
|
|
36
|
+
*/
|
|
37
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__title:last-child {
|
|
38
|
+
margin-block-end: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
* The band is at least a screen tall.
|
|
43
|
+
*
|
|
44
|
+
* `100cqh` rather than `100svh`, and the two are the same number on a real page: with no ancestor
|
|
45
|
+
* declaring size containment, a container query length falls back to the small viewport, which is
|
|
46
|
+
* the unit this wants and the reason it is not `vh` — on a phone the large viewport is measured
|
|
47
|
+
* with the browser chrome retracted, so a hero sized to it puts its own actions under the address
|
|
48
|
+
* bar until the reader scrolls, which is the one thing the band exists to prevent.
|
|
49
|
+
*
|
|
50
|
+
* What the container unit adds is an answer for a frame standing in for a window. The preview
|
|
51
|
+
* shows a band inside a panel a fraction of the screen's height; sized against the viewport it
|
|
52
|
+
* escaped that panel and covered the controls under it. A frame that declares `container-type:
|
|
53
|
+
* size` is now what this measures against, which is the same arrangement the preview already uses
|
|
54
|
+
* for a component pinned to the window — the component is right about what it wants, and the frame
|
|
55
|
+
* is what has to behave like a window.
|
|
56
|
+
*
|
|
57
|
+
* `min-block-size` rather than `block-size`, so a band whose copy runs long grows instead of
|
|
58
|
+
* clipping it. A fixed height was the source design's and it loses the description at a large text
|
|
59
|
+
* size.
|
|
60
|
+
*/
|
|
61
|
+
:where([data-dds-context="marketing"]) .dds-landinghero {
|
|
62
|
+
/*
|
|
63
|
+
* Where the content sits is `inner`'s to say, not this element's.
|
|
64
|
+
*
|
|
65
|
+
* The band declares `container-type`, and a container query cannot reach the element that
|
|
66
|
+
* declares it — a rule on the band inside one is measured against the band's own ancestor, which
|
|
67
|
+
* on a page is nothing at all. Written here, the phone's arrangement held at every width and the
|
|
68
|
+
* claim ran off the foot of a desktop band. `inner` is a descendant, so a query reaches it, and
|
|
69
|
+
* the band simply lets it fill the height.
|
|
70
|
+
*
|
|
71
|
+
* On a phone the claim sits at the foot of the band, not in the middle of it.
|
|
72
|
+
*
|
|
73
|
+
* There the subject fills the band behind the words, and text centred against it reads as
|
|
74
|
+
* floating in front of a picture. At the base the words read as standing on the same ground —
|
|
75
|
+
* subject above, claim at the foot, where a reader's eye finishes and the scroll carries on.
|
|
76
|
+
*
|
|
77
|
+
* At full width the arrangement is the other one and the wide rule says so: the subject is
|
|
78
|
+
* beside the claim rather than behind it, so there is nothing to stand on and centring is what
|
|
79
|
+
* pairs the two columns.
|
|
80
|
+
*
|
|
81
|
+
* The step below the words is the band's own `padding-block`, which holds here, where the
|
|
82
|
+
* content rests on the band's foot. The wide rule zeroes it, because centred content needs no
|
|
83
|
+
* step, and content resting on an edge is the one case that does.
|
|
84
|
+
*/
|
|
85
|
+
min-block-size: 100cqh;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
* The subject is placed against the band at every width, never laid out beside the text.
|
|
90
|
+
*
|
|
91
|
+
* Absolute is the base rule rather than the wide one, which is the correction: `media` is a child
|
|
92
|
+
* of the band and the band is a flex row, so without this it became a second column at anything
|
|
93
|
+
* under the fold width — a picture beside the claim, each squeezing the other, with the title run
|
|
94
|
+
* off the inline edge. The source design has it absolute at every width for exactly this reason
|
|
95
|
+
* and moves it at the breakpoint rather than placing it there.
|
|
96
|
+
*
|
|
97
|
+
* Centred and filling the band by default, which is what a narrow screen wants: the subject behind
|
|
98
|
+
* the claim rather than next to it. `inner` is painted over it by DOM order — it comes last in the
|
|
99
|
+
* markup and both are positioned — so no stacking order has to be named.
|
|
100
|
+
*
|
|
101
|
+
* `pointer-events: none` because it is decoration and the contract says so. Without it a subject
|
|
102
|
+
* covering the band would swallow a press meant for the button underneath.
|
|
103
|
+
*/
|
|
104
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__media {
|
|
105
|
+
/*
|
|
106
|
+
* Stood on the band's foot rather than floated in it.
|
|
107
|
+
*
|
|
108
|
+
* A cutout of a person hanging with air under it reads as a sticker; cropped by the edge it is
|
|
109
|
+
* standing in the band. It is also what puts the subject above the claim now that the claim is
|
|
110
|
+
* at the base — the two share the foot of the band rather than overlapping in the middle of it.
|
|
111
|
+
*
|
|
112
|
+
* One inset and a size, never both insets: naming a start, an end and a height over-constrains
|
|
113
|
+
* the box, and CSS resolves that by dropping the end — which is how the wide rule came to hug
|
|
114
|
+
* the top while saying bottom.
|
|
115
|
+
*/
|
|
116
|
+
align-items: flex-end;
|
|
117
|
+
display: flex;
|
|
118
|
+
inset-block-end: 0;
|
|
119
|
+
inset-block-start: auto;
|
|
120
|
+
inset-inline: 0;
|
|
121
|
+
block-size: 80%;
|
|
122
|
+
justify-content: center;
|
|
123
|
+
pointer-events: none;
|
|
124
|
+
position: absolute;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/*
|
|
128
|
+
* And the words are read off a scrim rather than off the subject.
|
|
129
|
+
*
|
|
130
|
+
* At a phone's width the claim sits over the picture, and a photograph is not a ground anybody
|
|
131
|
+
* chose — whatever is behind a given line is whatever the art happened to put there. The scrim
|
|
132
|
+
* darkens the foot of the band and fades out above it, so the words have a ground that is the
|
|
133
|
+
* band's own and the subject is still visible through it.
|
|
134
|
+
*
|
|
135
|
+
* `color.bg.overlay` rather than `overlay-subtle`, and the difference is what the scrim is for. A
|
|
136
|
+
* light scrim is enough to settle a picture that is already dark; this one has to hold white type
|
|
137
|
+
* over art nobody has seen. A page passing a bright photograph is the case that decides the value,
|
|
138
|
+
* and at a quarter of black white text on it is unreadable — which is a legibility failure a
|
|
139
|
+
* component cannot leave to whoever picks the art.
|
|
140
|
+
*
|
|
141
|
+
* It costs nothing where it is not needed: the band's own ground is near-black, so over that the
|
|
142
|
+
* scrim is invisible, and it only does work once something light is behind it.
|
|
143
|
+
*
|
|
144
|
+
* It is a black alpha, so fading it to `transparent` fades within one hue: a scrim of any other
|
|
145
|
+
* colour would pass through grey on its way out and leave a band across the picture.
|
|
146
|
+
*
|
|
147
|
+
* On `inner` rather than on the band, because the band paints before the subject and the scrim has
|
|
148
|
+
* to come after it. `inner` is the last thing in the markup and is positioned, so it paints over
|
|
149
|
+
* the picture without a stacking order being named — the same arrangement the subject itself
|
|
150
|
+
* relies on. At this width `inner` is the full width of the phone, so the scrim runs edge to edge
|
|
151
|
+
* and only its contents are held off by the gutter.
|
|
152
|
+
*/
|
|
153
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__inner {
|
|
154
|
+
/* At the foot on a phone, and filling the band so the scrim has somewhere to sit. */
|
|
155
|
+
align-items: flex-end;
|
|
156
|
+
background-image: linear-gradient(to top, var(--color-bg-overlay), transparent);
|
|
157
|
+
/* Anchored to the foot and given a height of its own, so the scrim is a band under the words
|
|
158
|
+
rather than a wash over the whole picture. This box is the height of the viewport; the paint
|
|
159
|
+
is three fifths of it, which covers the claim and its actions and leaves the subject above
|
|
160
|
+
them untouched. */
|
|
161
|
+
background-position: bottom;
|
|
162
|
+
background-repeat: no-repeat;
|
|
163
|
+
background-size: 100% 60%;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/*
|
|
167
|
+
* Text against the measure's leading edge, visual against the band's own.
|
|
168
|
+
*
|
|
169
|
+
* The column takes half the measure and no more. A claim set at eighty pixels across the full
|
|
170
|
+
* twelve hundred is two words a line with a ragged edge, and the visual it is supposed to sit
|
|
171
|
+
* beside has nowhere to be.
|
|
172
|
+
*
|
|
173
|
+
* `@container` rather than `@media`, asking the band's own width: the root declares
|
|
174
|
+
* `container-type`, so a hero placed in a narrow region of a wide page folds on its own measure.
|
|
175
|
+
* `48rem` longhand because `var()` is not permitted in a container query condition — the same
|
|
176
|
+
* constraint footer-impl.css works under, and the same width, so the two bands fold together.
|
|
177
|
+
*/
|
|
178
|
+
@container (min-width: 48rem) {
|
|
179
|
+
/*
|
|
180
|
+
* Half the measure, which is the reference design's 600 against its 1280 to within a few pixels
|
|
181
|
+
* — and holds at any width, where a number would only be right at one.
|
|
182
|
+
*/
|
|
183
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__content {
|
|
184
|
+
max-inline-size: 50%;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/*
|
|
188
|
+
* No step above or below the words at this width.
|
|
189
|
+
*
|
|
190
|
+
* The band is already a screen tall and the content is centred in it, so the section step has
|
|
191
|
+
* nothing to do: centring sets where the words sit, and a step on either side would only move
|
|
192
|
+
* them off the middle. The step the contract binds is for the narrower arrangement, where the
|
|
193
|
+
* words rest on the band's foot and need the distance from it.
|
|
194
|
+
*/
|
|
195
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__inner {
|
|
196
|
+
/* Centred, because the two columns are a pair rather than a thing standing on a ground. */
|
|
197
|
+
align-items: center;
|
|
198
|
+
/* No scrim: the subject is beside the claim here, not behind it, so there is nothing for the
|
|
199
|
+
words to be read off and a gradient would be a shadow under a column of text. */
|
|
200
|
+
background-image: none;
|
|
201
|
+
padding-block: 0;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/*
|
|
205
|
+
* The visual is placed against the band's inline end, not the column.
|
|
206
|
+
*
|
|
207
|
+
* Absolute against the root — which is why `media` is the band's child and not the content's.
|
|
208
|
+
* Off the band's block end but held off its inline one, so a cutout of a person is cropped at the
|
|
209
|
+
* waist by the band's own foot while still standing inside the page's gutter. The source design
|
|
210
|
+
* bleeds it off the side as well; run to the edge it read as a panel butted against the window
|
|
211
|
+
* rather than as a subject in the band, and the two edges are not the same decision — the foot
|
|
212
|
+
* is a crop and the side is a margin.
|
|
213
|
+
*
|
|
214
|
+
* `space.inset.page` is that margin, which is the role that holds a page's content off the edge
|
|
215
|
+
* of the window. The subject lands on the same line the content does, so the band has one gutter
|
|
216
|
+
* rather than a gutter and a picture that ignores it.
|
|
217
|
+
*
|
|
218
|
+
* The two `auto`s are what make that true, and their absence is why it was not. The base rule
|
|
219
|
+
* above sets `inset: 0` — all four sides — because at narrow widths the visual fills the band.
|
|
220
|
+
* Naming only the end insets here left both sides set on each axis with a size as well, which is
|
|
221
|
+
* over-constrained: CSS resolves that by ignoring the end value, so the visual hugged the start
|
|
222
|
+
* and the top while the rule said end and bottom. Releasing the start insets is what lets the
|
|
223
|
+
* ones named below take effect.
|
|
224
|
+
*/
|
|
225
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__media {
|
|
226
|
+
block-size: 100%;
|
|
227
|
+
/*
|
|
228
|
+
* Wide enough for the shape rather than for a share of the band.
|
|
229
|
+
*
|
|
230
|
+
* The height is the band's and `aspect.portrait` is bound on the part, so the width follows
|
|
231
|
+
* from the two — about half the band at a laptop's proportions, which is what the fixed half
|
|
232
|
+
* was approximating. Stated as a share it was right at one window shape and wrong at every
|
|
233
|
+
* other: a tall window gave a portrait subject a landscape box and cropped the figure's head.
|
|
234
|
+
*/
|
|
235
|
+
inline-size: auto;
|
|
236
|
+
inset-block-end: -14%;
|
|
237
|
+
inset-block-start: auto;
|
|
238
|
+
inset-inline-end: var(--space-inset-page);
|
|
239
|
+
inset-inline-start: auto;
|
|
240
|
+
position: absolute;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/*
|
|
246
|
+
* Whatever the page put in a visual slot fills the slot.
|
|
247
|
+
*
|
|
248
|
+
* The slots take a node rather than a source, so what arrives is the page's element and this
|
|
249
|
+
* cannot know whether it carries dimensions. Left alone an `<img>` renders at its intrinsic size,
|
|
250
|
+
* which for a product screenshot is wider than the band. `max-inline-size` rather than
|
|
251
|
+
* `inline-size` so a mark narrower than the slot is not stretched to fill it.
|
|
252
|
+
*/
|
|
253
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__media > * {
|
|
254
|
+
block-size: 100%;
|
|
255
|
+
max-inline-size: 100%;
|
|
256
|
+
object-fit: contain;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/*
|
|
260
|
+
* The band rounds off as it leaves.
|
|
261
|
+
*
|
|
262
|
+
* Scroll-driven rather than timed: `view()` measures the band against the viewport, so the corner
|
|
263
|
+
* arrives as the reader scrolls and reverses when they scroll back. There is no element entering
|
|
264
|
+
* and no transition to hang it on, which is what puts a keyframed animation in this file rather
|
|
265
|
+
* than in a binding.
|
|
266
|
+
*
|
|
267
|
+
* `radius.expressive` is the corner, and it is the role's own description — the most rounding
|
|
268
|
+
* before full, for high-impact visual sections and banners. The source design carries fifty-six
|
|
269
|
+
* pixels here, which is not a step on this ramp; forty-eight is, and the difference is invisible
|
|
270
|
+
* against a band the width of the page.
|
|
271
|
+
*
|
|
272
|
+
* Only the two lower corners. The band starts at the top of the document with nothing above it to
|
|
273
|
+
* round away from, and a hero that curved at the top would read as a card the page had been
|
|
274
|
+
* dropped into.
|
|
275
|
+
*/
|
|
276
|
+
@keyframes dds-landinghero-exit {
|
|
277
|
+
to {
|
|
278
|
+
border-end-end-radius: var(--radius-expressive);
|
|
279
|
+
border-end-start-radius: var(--radius-expressive);
|
|
280
|
+
scale: var(--motion-scale-band-exit);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
@supports (animation-timeline: view()) {
|
|
285
|
+
:where([data-dds-context="marketing"]) .dds-landinghero {
|
|
286
|
+
animation: dds-landinghero-exit linear both;
|
|
287
|
+
animation-range: exit 0% exit 40%;
|
|
288
|
+
animation-timeline: view();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/*
|
|
293
|
+
* A reader who asked for less movement gets none of it.
|
|
294
|
+
*
|
|
295
|
+
* The generated sheet writes a reduced-motion block from its bindings, and this animation is not
|
|
296
|
+
* one of them — it is written here, so its own exception has to be too. The band simply keeps its
|
|
297
|
+
* square corner, which is what it has at rest anyway.
|
|
298
|
+
*/
|
|
299
|
+
@media (prefers-reduced-motion: reduce) {
|
|
300
|
+
:where([data-dds-context="marketing"]) .dds-landinghero {
|
|
301
|
+
animation: none;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/*
|
|
306
|
+
* A band in a short container compacts, rather than clipping what it holds.
|
|
307
|
+
*
|
|
308
|
+
* `space.section.default` is 112 top and bottom — 224 of the band before a word is set, which is
|
|
309
|
+
* right at a screen's height and is most of an overview row. The band is as tall as the screen, so
|
|
310
|
+
* it is the screen's height that is asked: a `@media` query, on a real page. The band's own
|
|
311
|
+
* `container-type` is `inline-size`, which cannot answer a height, so a container query alone
|
|
312
|
+
* matched only inside a frame that measures its height — the preview's — and never in production.
|
|
313
|
+
* Both are written: the media query for a page, the container query for a frame. The role already
|
|
314
|
+
* exists for a band that has to be shorter; nothing new is named here.
|
|
315
|
+
*
|
|
316
|
+
* `40rem` longhand because `var()` is not permitted in a container query condition.
|
|
317
|
+
*/
|
|
318
|
+
@container (max-height: 40rem) {
|
|
319
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__inner {
|
|
320
|
+
padding-block: var(--space-section-compact);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
@media (max-height: 40rem) {
|
|
325
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__inner {
|
|
326
|
+
padding-block: var(--space-section-compact);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/*
|
|
331
|
+
* Two calls to action stack on a phone and stand side by side once there is room.
|
|
332
|
+
*
|
|
333
|
+
* The reference design makes each one full width at the narrow end — a button that hugs its label
|
|
334
|
+
* on a phone is a tap target sized by how long the word happens to be — and lets them hug once the
|
|
335
|
+
* band is wide enough to hold both on a line.
|
|
336
|
+
*/
|
|
337
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__actions {
|
|
338
|
+
align-items: stretch;
|
|
339
|
+
flex-direction: column;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__actions > * {
|
|
343
|
+
inline-size: 100%;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
@container (min-width: 48rem) {
|
|
347
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__actions {
|
|
348
|
+
align-items: center;
|
|
349
|
+
flex-direction: row;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
:where([data-dds-context="marketing"]) .dds-landinghero .dds-landinghero__actions > * {
|
|
353
|
+
inline-size: auto;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/* GENERATED from logocolumns.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns {
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
container-type: inline-size;
|
|
6
|
+
display: flex;
|
|
7
|
+
inline-size: 100%;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
overflow: clip;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__inner {
|
|
13
|
+
box-sizing: border-box;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
inline-size: 100%;
|
|
17
|
+
min-inline-size: 0;
|
|
18
|
+
max-inline-size: var(--size-content-max);
|
|
19
|
+
padding-block: var(--space-section-default);
|
|
20
|
+
padding-inline: var(--space-inset-page);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__split {
|
|
24
|
+
align-items: stretch;
|
|
25
|
+
display: flex;
|
|
26
|
+
min-inline-size: 0;
|
|
27
|
+
column-gap: var(--space-gap-3xl);
|
|
28
|
+
row-gap: var(--space-gap-2xl);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__content {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
min-inline-size: 0;
|
|
35
|
+
row-gap: var(--space-gap-none);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__title {
|
|
39
|
+
margin-block: 0;
|
|
40
|
+
text-wrap: balance;
|
|
41
|
+
font-family: var(--font-h2-family);
|
|
42
|
+
font-size: var(--font-h2-size);
|
|
43
|
+
font-weight: var(--font-h2-weight);
|
|
44
|
+
letter-spacing: var(--font-h2-letter-spacing);
|
|
45
|
+
line-height: var(--font-h2-line-height);
|
|
46
|
+
margin-block-end: var(--space-heading-title-description);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__description {
|
|
50
|
+
margin-block: 0;
|
|
51
|
+
font-family: var(--font-body-md-family);
|
|
52
|
+
font-size: var(--font-body-md-size);
|
|
53
|
+
font-weight: var(--font-body-md-weight);
|
|
54
|
+
letter-spacing: var(--font-body-md-letter-spacing);
|
|
55
|
+
line-height: var(--font-body-md-line-height);
|
|
56
|
+
margin-block-end: var(--space-heading-description-actions);
|
|
57
|
+
max-inline-size: var(--size-measure-description);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__disclaimer {
|
|
61
|
+
margin-block: 0;
|
|
62
|
+
font-family: var(--font-body-sm-family);
|
|
63
|
+
font-size: var(--font-body-sm-size);
|
|
64
|
+
font-weight: var(--font-body-sm-weight);
|
|
65
|
+
letter-spacing: var(--font-body-sm-letter-spacing);
|
|
66
|
+
line-height: var(--font-body-sm-line-height);
|
|
67
|
+
margin-block-end: var(--space-heading-description-actions);
|
|
68
|
+
max-inline-size: var(--size-measure-description);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__link {
|
|
72
|
+
display: flex;
|
|
73
|
+
margin-block-start: var(--space-gap-none);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__media {
|
|
77
|
+
display: flex;
|
|
78
|
+
min-inline-size: 0;
|
|
79
|
+
overflow: clip;
|
|
80
|
+
position: relative;
|
|
81
|
+
block-size: var(--size-logo-columns-height);
|
|
82
|
+
column-gap: var(--space-grid-gutter);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__column {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
list-style: none;
|
|
89
|
+
margin: 0;
|
|
90
|
+
min-inline-size: 0;
|
|
91
|
+
padding: 0;
|
|
92
|
+
row-gap: var(--space-grid-gutter);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__logo {
|
|
96
|
+
align-items: center;
|
|
97
|
+
box-sizing: border-box;
|
|
98
|
+
display: flex;
|
|
99
|
+
justify-content: center;
|
|
100
|
+
aspect-ratio: var(--aspect-landscape);
|
|
101
|
+
border-radius: var(--radius-container-item);
|
|
102
|
+
padding-block: var(--space-inset-md);
|
|
103
|
+
padding-inline: var(--space-inset-md);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns .dds-logocolumns__logo-image {
|
|
107
|
+
block-size: 100%;
|
|
108
|
+
display: block;
|
|
109
|
+
inline-size: 100%;
|
|
110
|
+
object-fit: contain;
|
|
111
|
+
border-radius: var(--radius-control-sm);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-media-position="end"] .dds-logocolumns__split {
|
|
115
|
+
flex-direction: row;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-media-position="start"] .dds-logocolumns__split {
|
|
119
|
+
flex-direction: row-reverse;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="page"] {
|
|
123
|
+
background-color: var(--color-bg-page);
|
|
124
|
+
color: var(--color-fg-default);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="page"] .dds-logocolumns__disclaimer {
|
|
128
|
+
color: var(--color-fg-muted);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="page"] .dds-logocolumns__logo {
|
|
132
|
+
background-color: var(--color-bg-surface);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="strong"] {
|
|
136
|
+
background-color: var(--color-bg-brand-strong);
|
|
137
|
+
color: var(--color-fg-on-brand-strong);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="strong"] .dds-logocolumns__disclaimer {
|
|
141
|
+
color: var(--color-fg-muted-inverse);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="strong"] .dds-logocolumns__logo {
|
|
145
|
+
background-color: var(--color-bg-surface-card-strong);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="subtle"] {
|
|
149
|
+
background-color: var(--color-bg-page);
|
|
150
|
+
background-image: linear-gradient(var(--color-bg-band-subtle), var(--color-bg-band-subtle));
|
|
151
|
+
color: var(--color-fg-default);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="subtle"] .dds-logocolumns__disclaimer {
|
|
155
|
+
color: var(--color-fg-muted);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
:where([data-dds-context="marketing"]) .dds-logocolumns[data-ground="subtle"] .dds-logocolumns__logo {
|
|
159
|
+
background-color: var(--color-bg-surface-card-raised);
|
|
160
|
+
}
|
|
161
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import './LogoColumns.css';
|
|
2
|
+
import './logo-columns-impl.css';
|
|
3
|
+
import '../block-reveal.css';
|
|
4
|
+
import { type LogoColumnsProps } from './LogoColumns.types.js';
|
|
5
|
+
export type { LogoColumnsProps };
|
|
6
|
+
/**
|
|
7
|
+
* A claim beside a wall of logos — the reference site's LogoMarquee, as FeatureSplit with the
|
|
8
|
+
* picture replaced by the names that back the words.
|
|
9
|
+
*
|
|
10
|
+
* Nothing here moves on its own. The two columns are moved by the stylesheet, on a view timeline
|
|
11
|
+
* the wall carries, so they run with the reader's scroll — the first rising, the second falling —
|
|
12
|
+
* and stand still the moment the page does, and for a reader who asked for less motion. The
|
|
13
|
+
* reference drives the same effect from scroll velocity in a frame loop; a scroll timeline is the
|
|
14
|
+
* platform doing that, with no script running per frame.
|
|
15
|
+
*
|
|
16
|
+
* The logos are dealt into the two columns in order, alternately, so a page orders one list rather
|
|
17
|
+
* than splitting it. Each column is a list of the logos it was dealt, drawn `SETS` times over; only
|
|
18
|
+
* the first set is announced, so a screen reader hears each name once.
|
|
19
|
+
*
|
|
20
|
+
* The steps inside the column of words follow FeatureSplit's: each part's own `margin-block-end`.
|
|
21
|
+
* The title carries the section's accessible name through `aria-labelledby`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function LogoColumns({ ground, mediaPosition, title, description, disclaimer, link, logos, }: LogoColumnsProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId } from 'react';
|
|
4
|
+
import './LogoColumns.css';
|
|
5
|
+
import './logo-columns-impl.css';
|
|
6
|
+
import '../block-reveal.css';
|
|
7
|
+
import { arriving, useReveal } from '../use-reveal.js';
|
|
8
|
+
import { given } from '../../given.js';
|
|
9
|
+
import { logoColumnsDefaults, logoColumnsParts, } from './LogoColumns.types.js';
|
|
10
|
+
/**
|
|
11
|
+
* How many times each column is drawn. The columns move by one set across the wall's pass, so the
|
|
12
|
+
* end of the movement shows what the start did; three sets keep a column running on past both
|
|
13
|
+
* edges at every point of it, even for a short column.
|
|
14
|
+
*/
|
|
15
|
+
const SETS = 3;
|
|
16
|
+
/**
|
|
17
|
+
* A claim beside a wall of logos — the reference site's LogoMarquee, as FeatureSplit with the
|
|
18
|
+
* picture replaced by the names that back the words.
|
|
19
|
+
*
|
|
20
|
+
* Nothing here moves on its own. The two columns are moved by the stylesheet, on a view timeline
|
|
21
|
+
* the wall carries, so they run with the reader's scroll — the first rising, the second falling —
|
|
22
|
+
* and stand still the moment the page does, and for a reader who asked for less motion. The
|
|
23
|
+
* reference drives the same effect from scroll velocity in a frame loop; a scroll timeline is the
|
|
24
|
+
* platform doing that, with no script running per frame.
|
|
25
|
+
*
|
|
26
|
+
* The logos are dealt into the two columns in order, alternately, so a page orders one list rather
|
|
27
|
+
* than splitting it. Each column is a list of the logos it was dealt, drawn `SETS` times over; only
|
|
28
|
+
* the first set is announced, so a screen reader hears each name once.
|
|
29
|
+
*
|
|
30
|
+
* The steps inside the column of words follow FeatureSplit's: each part's own `margin-block-end`.
|
|
31
|
+
* The title carries the section's accessible name through `aria-labelledby`.
|
|
32
|
+
*/
|
|
33
|
+
export function LogoColumns({ ground = logoColumnsDefaults.ground, mediaPosition = logoColumnsDefaults.mediaPosition, title, description, disclaimer, link, logos, }) {
|
|
34
|
+
const titleId = useId();
|
|
35
|
+
const [band, revealed] = useReveal();
|
|
36
|
+
// Nothing to show is nothing drawn: a wall with no logo on it is a claim with no evidence.
|
|
37
|
+
if (logos.length === 0)
|
|
38
|
+
return null;
|
|
39
|
+
const columns = [
|
|
40
|
+
logos.filter((_, at) => at % 2 === 0),
|
|
41
|
+
logos.filter((_, at) => at % 2 === 1),
|
|
42
|
+
];
|
|
43
|
+
return (_jsx("section", { className: logoColumnsParts.root, "data-ground": ground, "data-media-position": mediaPosition, "aria-labelledby": titleId, children: _jsx("div", { className: logoColumnsParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: logoColumnsParts.split, children: [_jsxs("div", { className: logoColumnsParts.content, children: [_jsx("h2", { className: logoColumnsParts.title, ...arriving(0), id: titleId, children: title }), given(description) ? (_jsx("p", { className: logoColumnsParts.description, ...arriving(1), children: description })) : null, disclaimer !== undefined && given(disclaimer) ? (_jsx("p", { className: logoColumnsParts.disclaimer, ...arriving(1), children: disclaimer })) : null, link ? (_jsx("div", { className: logoColumnsParts.link, ...arriving(2), children: link })) : null] }), _jsx("div", { className: logoColumnsParts.media, ...arriving(3), children: columns.map((column, at) => column.length === 0 ? null : (_jsx("ul", { className: logoColumnsParts.column, "data-column": at === 0 ? 'rising' : 'falling', children: Array.from({ length: SETS }, (_, set) => column.map((logo, index) => (
|
|
44
|
+
// A logo's place is its identity: the list is the page's, and nothing reorders it.
|
|
45
|
+
_jsx("li", { className: logoColumnsParts.logo, "aria-hidden": set === 0 ? undefined : 'true', children: _jsx("img", { className: logoColumnsParts['logo-image'], src: logo.src, alt: logo.name, draggable: false }) }, `${set}-${index}`)))) }, at))) })] }) }) }));
|
|
46
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { LogoTile } from '../../logo-data.js';
|
|
3
|
+
export interface LogoColumnsOwnProps {
|
|
4
|
+
/**
|
|
5
|
+
* `page` — The page's own white, with tiles at the recessed gray. For full-colour logos drawn for a light ground
|
|
6
|
+
* `subtle` — The grey band, with white tiles on it. For full-colour logos, where the section needs setting apart from the ones around it. Painted as the band's tint over the page's own ground, so it is the same grey whatever is behind the section
|
|
7
|
+
* `strong` — The default. `color.bg.brand-strong`, the dark band, with white words and tiles at color.bg.surface-card-strong — gray.900 in both themes, so the wall is a set of tiles a step lighter than the band. The ground white wordmarks are drawn for
|
|
8
|
+
*/
|
|
9
|
+
ground?: 'page' | 'subtle' | 'strong';
|
|
10
|
+
/**
|
|
11
|
+
* `start` — The default, the reference design's: the wall at the start, the claim beside it at the end
|
|
12
|
+
* `end` — The second of two on a page, or after a FeatureSplit whose picture is at the start, so the two do not read as one column
|
|
13
|
+
*/
|
|
14
|
+
mediaPosition?: 'start' | 'end';
|
|
15
|
+
/** Always. The one claim the logos back, in the fewest words that say it — "Trusted by leading platforms worldwide". */
|
|
16
|
+
title: string;
|
|
17
|
+
/** The line under the heading: what the logos mean for the reader — which payment methods they can use, which platforms they can trade on. */
|
|
18
|
+
description?: string;
|
|
19
|
+
/** Small print the claim needs — "*Availability varies by region." Under the description, quieter than it. */
|
|
20
|
+
disclaimer?: string;
|
|
21
|
+
/** The way onward — a standalone Link, "View all partners", usually. Under the words, never on the wall: the tiles move. */
|
|
22
|
+
link?: ReactNode;
|
|
23
|
+
/** Always. The logos, in the order the wall deals them into its two columns — the first to the first column, the second to the second, and so on. Eight or more, so each column runs on past both edges. Each name is what a screen reader hears for its logo. */
|
|
24
|
+
logos: LogoTile[];
|
|
25
|
+
}
|
|
26
|
+
export type LogoColumnsProps = LogoColumnsOwnProps;
|
|
27
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
28
|
+
export declare const logoColumnsParts: {
|
|
29
|
+
readonly root: "dds-logocolumns";
|
|
30
|
+
readonly inner: "dds-logocolumns__inner";
|
|
31
|
+
readonly split: "dds-logocolumns__split";
|
|
32
|
+
readonly content: "dds-logocolumns__content";
|
|
33
|
+
readonly title: "dds-logocolumns__title";
|
|
34
|
+
readonly description: "dds-logocolumns__description";
|
|
35
|
+
readonly disclaimer: "dds-logocolumns__disclaimer";
|
|
36
|
+
readonly link: "dds-logocolumns__link";
|
|
37
|
+
readonly media: "dds-logocolumns__media";
|
|
38
|
+
readonly column: "dds-logocolumns__column";
|
|
39
|
+
readonly logo: "dds-logocolumns__logo";
|
|
40
|
+
readonly 'logo-image': "dds-logocolumns__logo-image";
|
|
41
|
+
};
|
|
42
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
43
|
+
export declare const logoColumnsDefaults: {
|
|
44
|
+
readonly ground: "strong";
|
|
45
|
+
readonly mediaPosition: "start";
|
|
46
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// GENERATED from logo-columns.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const logoColumnsParts = {
|
|
4
|
+
root: 'dds-logocolumns',
|
|
5
|
+
inner: 'dds-logocolumns__inner',
|
|
6
|
+
split: 'dds-logocolumns__split',
|
|
7
|
+
content: 'dds-logocolumns__content',
|
|
8
|
+
title: 'dds-logocolumns__title',
|
|
9
|
+
description: 'dds-logocolumns__description',
|
|
10
|
+
disclaimer: 'dds-logocolumns__disclaimer',
|
|
11
|
+
link: 'dds-logocolumns__link',
|
|
12
|
+
media: 'dds-logocolumns__media',
|
|
13
|
+
column: 'dds-logocolumns__column',
|
|
14
|
+
logo: 'dds-logocolumns__logo',
|
|
15
|
+
'logo-image': 'dds-logocolumns__logo-image',
|
|
16
|
+
};
|
|
17
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
18
|
+
export const logoColumnsDefaults = { ground: 'strong', mediaPosition: 'start' };
|