@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
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { LogoTile } from '../../logo-data.js';
|
|
3
|
+
export interface LogoRowsOwnProps {
|
|
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 row 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
|
+
/** Always. The one claim the logos back, in the fewest words that say it — "Trusted by leading platforms worldwide". */
|
|
11
|
+
title: string;
|
|
12
|
+
/** The line under the heading: what the logos mean for the reader — which payment methods they can use, which platforms they can trade on. */
|
|
13
|
+
description?: string;
|
|
14
|
+
/** The way onward — a standalone Link, "View all partners", usually. Under the line, never on the row: the tiles move. */
|
|
15
|
+
link?: ReactNode;
|
|
16
|
+
/** Always. The logos, in the order the section deals them into its two rows — the first to the first row, the second to the second, and so on. Eight or more, so each row runs on past both edges of the band. Each name is what a screen reader hears for its logo. */
|
|
17
|
+
logos: LogoTile[];
|
|
18
|
+
}
|
|
19
|
+
export type LogoRowsProps = LogoRowsOwnProps;
|
|
20
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
21
|
+
export declare const logoRowsParts: {
|
|
22
|
+
readonly root: "dds-logorows";
|
|
23
|
+
readonly inner: "dds-logorows__inner";
|
|
24
|
+
readonly header: "dds-logorows__header";
|
|
25
|
+
readonly title: "dds-logorows__title";
|
|
26
|
+
readonly description: "dds-logorows__description";
|
|
27
|
+
readonly link: "dds-logorows__link";
|
|
28
|
+
readonly rail: "dds-logorows__rail";
|
|
29
|
+
readonly track: "dds-logorows__track";
|
|
30
|
+
readonly logo: "dds-logorows__logo";
|
|
31
|
+
readonly 'logo-image': "dds-logorows__logo-image";
|
|
32
|
+
};
|
|
33
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
34
|
+
export declare const logoRowsDefaults: {
|
|
35
|
+
readonly ground: "strong";
|
|
36
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// GENERATED from logo-rows.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const logoRowsParts = {
|
|
4
|
+
root: 'dds-logorows',
|
|
5
|
+
inner: 'dds-logorows__inner',
|
|
6
|
+
header: 'dds-logorows__header',
|
|
7
|
+
title: 'dds-logorows__title',
|
|
8
|
+
description: 'dds-logorows__description',
|
|
9
|
+
link: 'dds-logorows__link',
|
|
10
|
+
rail: 'dds-logorows__rail',
|
|
11
|
+
track: 'dds-logorows__track',
|
|
12
|
+
logo: 'dds-logorows__logo',
|
|
13
|
+
'logo-image': 'dds-logorows__logo-image',
|
|
14
|
+
};
|
|
15
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
16
|
+
export const logoRowsDefaults = { ground: 'strong' };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Scoped to this package, like the generated sheet beside it.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* The header starts on a phone and is centred from the fold — FeatureCards' arrangement and its
|
|
7
|
+
* reason: centred text starts every line at a different edge, which costs little across a wide
|
|
8
|
+
* measure and a great deal across a narrow one.
|
|
9
|
+
*/
|
|
10
|
+
@container (min-width: 48rem) {
|
|
11
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__header {
|
|
12
|
+
align-items: center;
|
|
13
|
+
margin-inline: auto;
|
|
14
|
+
text-align: center;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__description {
|
|
18
|
+
margin-inline: auto;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__link {
|
|
22
|
+
justify-content: center;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
* The rail runs out to the band's edges.
|
|
28
|
+
*
|
|
29
|
+
* `cqi` is the band's width — the root declares `container-type` — and the bleed is how far the
|
|
30
|
+
* column stands in from the band's edge: half of whatever the band has beyond the content measure,
|
|
31
|
+
* plus the gutter. A negative margin of that measure takes the rail out to both edges, so the row
|
|
32
|
+
* fades out at the band's edge rather than at the column's — TestimonialRow's breakout.
|
|
33
|
+
*/
|
|
34
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__rail {
|
|
35
|
+
--dds-logorows-bleed: calc((100cqi - min(100cqi, var(--size-content-max))) / 2 + var(--space-inset-page));
|
|
36
|
+
margin-inline: calc(-1 * var(--dds-logorows-bleed));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
* Both ends fade out rather than cut — LogoColumns' mask, turned on its side.
|
|
41
|
+
*
|
|
42
|
+
* A mask rather than a painted gradient, so it reads on any ground with no colour to keep in step,
|
|
43
|
+
* and eased: the opacity follows a smoothstep curve across the fade, sampled at its stops, because
|
|
44
|
+
* a straight fade has its sharpest change at both ends. Half a tile at each end. `to right` is
|
|
45
|
+
* physical, and the only gradient direction CSS has — harmless here, the fade being the same at
|
|
46
|
+
* both ends whichever way the page reads.
|
|
47
|
+
*/
|
|
48
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__rail {
|
|
49
|
+
--dds-logorows-fade: calc(var(--size-logo-rows-tile) * 0.5);
|
|
50
|
+
mask-image: linear-gradient(
|
|
51
|
+
to right,
|
|
52
|
+
transparent calc(var(--dds-logorows-fade) * 0),
|
|
53
|
+
color-mix(in srgb, black 6.1%, transparent) calc(var(--dds-logorows-fade) * 0.15),
|
|
54
|
+
color-mix(in srgb, black 21.6%, transparent) calc(var(--dds-logorows-fade) * 0.3),
|
|
55
|
+
color-mix(in srgb, black 42.5%, transparent) calc(var(--dds-logorows-fade) * 0.45),
|
|
56
|
+
color-mix(in srgb, black 64.8%, transparent) calc(var(--dds-logorows-fade) * 0.6),
|
|
57
|
+
color-mix(in srgb, black 84.4%, transparent) calc(var(--dds-logorows-fade) * 0.75),
|
|
58
|
+
color-mix(in srgb, black 97.2%, transparent) calc(var(--dds-logorows-fade) * 0.9),
|
|
59
|
+
black calc(var(--dds-logorows-fade) * 1),
|
|
60
|
+
black calc(100% - var(--dds-logorows-fade) * 1),
|
|
61
|
+
color-mix(in srgb, black 97.2%, transparent) calc(100% - var(--dds-logorows-fade) * 0.9),
|
|
62
|
+
color-mix(in srgb, black 84.4%, transparent) calc(100% - var(--dds-logorows-fade) * 0.75),
|
|
63
|
+
color-mix(in srgb, black 64.8%, transparent) calc(100% - var(--dds-logorows-fade) * 0.6),
|
|
64
|
+
color-mix(in srgb, black 42.5%, transparent) calc(100% - var(--dds-logorows-fade) * 0.45),
|
|
65
|
+
color-mix(in srgb, black 21.6%, transparent) calc(100% - var(--dds-logorows-fade) * 0.3),
|
|
66
|
+
color-mix(in srgb, black 6.1%, transparent) calc(100% - var(--dds-logorows-fade) * 0.15),
|
|
67
|
+
transparent calc(100% - var(--dds-logorows-fade) * 0)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* A tile three quarters as wide on a phone, so a row still shows two and the start of a third. */
|
|
72
|
+
@container (max-width: 47.9375rem) {
|
|
73
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__logo {
|
|
74
|
+
inline-size: calc(var(--size-logo-rows-tile) * 0.75);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
* Tiles keep their width: a flex item shrinks to fit before it overflows, and a row of squeezed
|
|
80
|
+
* tiles is the one thing this is not.
|
|
81
|
+
*/
|
|
82
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__logo {
|
|
83
|
+
flex: none;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/*
|
|
87
|
+
* Each row is as wide as its tiles, not as the rail. The rail is a column, and a column stretches
|
|
88
|
+
* its items across itself, which held every row to the band's width: its movement — a share of its
|
|
89
|
+
* own width — was then a share of the band rather than one set of logos, and changed with the
|
|
90
|
+
* screen instead of with what the row holds.
|
|
91
|
+
*/
|
|
92
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__track {
|
|
93
|
+
align-self: flex-start;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/*
|
|
97
|
+
* The rows run with the scroll, in opposite directions: the first toward the start, the second
|
|
98
|
+
* toward the end.
|
|
99
|
+
*
|
|
100
|
+
* A view timeline on the rail measures its pass through the viewport, and each row travels one set
|
|
101
|
+
* across that pass, so the end of the movement shows exactly what the start did and nothing jumps
|
|
102
|
+
* at either end. One set is a quarter of the row, the row being four sets, with the gap after the
|
|
103
|
+
* last tile counted in — four sets of tiles have one gap fewer than four sets of tile-and-gap.
|
|
104
|
+
* Four rather than three so that a row of eight logos still reaches past a wide screen's far edge
|
|
105
|
+
* at the end of its travel. The second row runs the same
|
|
106
|
+
* distance the other way by starting where the first ends. In a right-to-left page a row is laid
|
|
107
|
+
* from the other edge and runs on past the left one, so both directions turn round.
|
|
108
|
+
*
|
|
109
|
+
* The timeline measures against the nearest scroll container, which is why the section and the
|
|
110
|
+
* rail clip with `overflow: clip` rather than `hidden`: `hidden` makes a box a scroll container even
|
|
111
|
+
* when it never scrolls, and the rows would sit still however far the page moved. A browser with no
|
|
112
|
+
* scroll timeline draws the rows still, which is the whole of the fallback.
|
|
113
|
+
*/
|
|
114
|
+
@keyframes dds-logorows-to-start {
|
|
115
|
+
from {
|
|
116
|
+
translate: none;
|
|
117
|
+
}
|
|
118
|
+
to {
|
|
119
|
+
translate: calc(-1 * (100% + var(--space-grid-gutter)) / 4) 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@keyframes dds-logorows-to-end {
|
|
124
|
+
from {
|
|
125
|
+
translate: calc(-1 * (100% + var(--space-grid-gutter)) / 4) 0;
|
|
126
|
+
}
|
|
127
|
+
to {
|
|
128
|
+
translate: none;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@keyframes dds-logorows-to-start-rtl {
|
|
133
|
+
from {
|
|
134
|
+
translate: none;
|
|
135
|
+
}
|
|
136
|
+
to {
|
|
137
|
+
translate: calc((100% + var(--space-grid-gutter)) / 4) 0;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@keyframes dds-logorows-to-end-rtl {
|
|
142
|
+
from {
|
|
143
|
+
translate: calc((100% + var(--space-grid-gutter)) / 4) 0;
|
|
144
|
+
}
|
|
145
|
+
to {
|
|
146
|
+
translate: none;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@supports (animation-timeline: view()) {
|
|
151
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__rail {
|
|
152
|
+
view-timeline: --dds-logorows-rail block;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__track {
|
|
156
|
+
animation: dds-logorows-to-start linear both;
|
|
157
|
+
animation-range: cover;
|
|
158
|
+
animation-timeline: --dds-logorows-rail;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__track[data-row='trailing'] {
|
|
162
|
+
animation-name: dds-logorows-to-end;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__track:dir(rtl) {
|
|
166
|
+
animation-name: dds-logorows-to-start-rtl;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__track[data-row='trailing']:dir(rtl) {
|
|
170
|
+
animation-name: dds-logorows-to-end-rtl;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* A reader who asked for less movement gets none of it: the rows stand still. */
|
|
175
|
+
@media (prefers-reduced-motion: reduce) {
|
|
176
|
+
:where([data-dds-context="marketing"]) .dds-logorows .dds-logorows__track {
|
|
177
|
+
animation: none;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* GENERATED from pageheader.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-pageheader {
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
container-type: inline-size;
|
|
6
|
+
display: flex;
|
|
7
|
+
inline-size: 100%;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
position: relative;
|
|
11
|
+
background-color: var(--color-bg-brand-strong);
|
|
12
|
+
color: var(--color-fg-on-brand-strong);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__inner {
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
display: flex;
|
|
18
|
+
inline-size: 100%;
|
|
19
|
+
min-inline-size: 0;
|
|
20
|
+
position: relative;
|
|
21
|
+
max-inline-size: var(--size-content-max);
|
|
22
|
+
padding-block: var(--space-section-default);
|
|
23
|
+
padding-inline: var(--space-inset-page);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__content {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
inline-size: 100%;
|
|
30
|
+
min-inline-size: 0;
|
|
31
|
+
row-gap: var(--space-heading-description-actions);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__text {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
min-inline-size: 0;
|
|
38
|
+
max-inline-size: var(--size-measure-hero-heading);
|
|
39
|
+
row-gap: var(--space-gap-none);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__eyebrow {
|
|
43
|
+
margin-block: 0;
|
|
44
|
+
font-family: var(--font-eyebrow-lg-family);
|
|
45
|
+
font-size: var(--font-eyebrow-lg-size);
|
|
46
|
+
font-weight: var(--font-eyebrow-lg-weight);
|
|
47
|
+
letter-spacing: var(--font-eyebrow-lg-letter-spacing);
|
|
48
|
+
line-height: var(--font-eyebrow-lg-line-height);
|
|
49
|
+
margin-block-end: var(--space-heading-eyebrow-title);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__title {
|
|
53
|
+
margin-block: 0;
|
|
54
|
+
text-wrap: balance;
|
|
55
|
+
font-family: var(--font-h1-family);
|
|
56
|
+
font-size: var(--font-h1-size);
|
|
57
|
+
font-weight: var(--font-h1-weight);
|
|
58
|
+
letter-spacing: var(--font-h1-letter-spacing);
|
|
59
|
+
line-height: var(--font-h1-line-height);
|
|
60
|
+
margin-block-end: var(--space-heading-title-description);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__description {
|
|
64
|
+
margin-block: 0;
|
|
65
|
+
font-family: var(--font-body-md-family);
|
|
66
|
+
font-size: var(--font-body-md-size);
|
|
67
|
+
font-weight: var(--font-body-md-weight);
|
|
68
|
+
letter-spacing: var(--font-body-md-letter-spacing);
|
|
69
|
+
line-height: var(--font-body-md-line-height);
|
|
70
|
+
max-inline-size: var(--size-measure-hero-description);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__actions {
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-wrap: wrap;
|
|
76
|
+
column-gap: var(--space-actions-gap);
|
|
77
|
+
row-gap: var(--space-actions-gap);
|
|
78
|
+
}
|
|
79
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import './PageHeader.css';
|
|
2
|
+
import './page-header-impl.css';
|
|
3
|
+
import '../block-reveal.css';
|
|
4
|
+
import { type PageHeaderProps } from './PageHeader.types.js';
|
|
5
|
+
export type { PageHeaderProps };
|
|
6
|
+
/**
|
|
7
|
+
* The band that opens a company or a legal page.
|
|
8
|
+
*
|
|
9
|
+
* The third of three opening bands, and the only one that is not a hero. Which band a page opens
|
|
10
|
+
* with follows from where the page sits rather than from a prop: a landing page takes LandingHero
|
|
11
|
+
* and a product page ProductHero. Separate components rather than one with a switch, so a page
|
|
12
|
+
* cannot be given a tier it is not.
|
|
13
|
+
*
|
|
14
|
+
* Capped rather than a screen tall, which is the whole difference. A reader arrives at Contact or
|
|
15
|
+
* Terms for the content, so the band names the page and gets out of the way — `size.band.compact`
|
|
16
|
+
* is the floor it takes, and the page begins immediately under it.
|
|
17
|
+
*
|
|
18
|
+
* No photograph and no visual slot, which is a decision rather than an omission: there is nothing
|
|
19
|
+
* to show on a page of terms, and a slot for one is a slot somebody eventually fills. What the band
|
|
20
|
+
* paints instead is a faint rule grid over its own ground, drawn in the stylesheet out of a border
|
|
21
|
+
* role — enough to say the band is deliberate rather than a gap.
|
|
22
|
+
*
|
|
23
|
+
* Which also means it has no scrim and needs none. The other two darken a photograph so a title
|
|
24
|
+
* reads over it; here the ground is the component's own and its contrast is already known.
|
|
25
|
+
*
|
|
26
|
+
* The steps inside the text block are carried by each part's own `margin-block-end` rather than by
|
|
27
|
+
* a gap on the block, because eyebrow-to-title and title-to-description are two different roles
|
|
28
|
+
* that agree at full width and part company on a phone.
|
|
29
|
+
*
|
|
30
|
+
* The title carries the band's accessible name through `aria-labelledby`. A `<section>` is only a
|
|
31
|
+
* region landmark once it has a name, and a band that announced itself as an unnamed section is one
|
|
32
|
+
* more thing a screen reader user walks through rather than a place they can skip to.
|
|
33
|
+
*/
|
|
34
|
+
export declare function PageHeader({ eyebrow, title, headingLevel, description, actions, }: PageHeaderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId } from 'react';
|
|
4
|
+
import './PageHeader.css';
|
|
5
|
+
import './page-header-impl.css';
|
|
6
|
+
import '../block-reveal.css';
|
|
7
|
+
import { arriving, useReveal } from '../use-reveal.js';
|
|
8
|
+
import { given } from '../../given.js';
|
|
9
|
+
import { pageHeaderDefaults, pageHeaderParts } from './PageHeader.types.js';
|
|
10
|
+
/**
|
|
11
|
+
* The band that opens a company or a legal page.
|
|
12
|
+
*
|
|
13
|
+
* The third of three opening bands, and the only one that is not a hero. Which band a page opens
|
|
14
|
+
* with follows from where the page sits rather than from a prop: a landing page takes LandingHero
|
|
15
|
+
* and a product page ProductHero. Separate components rather than one with a switch, so a page
|
|
16
|
+
* cannot be given a tier it is not.
|
|
17
|
+
*
|
|
18
|
+
* Capped rather than a screen tall, which is the whole difference. A reader arrives at Contact or
|
|
19
|
+
* Terms for the content, so the band names the page and gets out of the way — `size.band.compact`
|
|
20
|
+
* is the floor it takes, and the page begins immediately under it.
|
|
21
|
+
*
|
|
22
|
+
* No photograph and no visual slot, which is a decision rather than an omission: there is nothing
|
|
23
|
+
* to show on a page of terms, and a slot for one is a slot somebody eventually fills. What the band
|
|
24
|
+
* paints instead is a faint rule grid over its own ground, drawn in the stylesheet out of a border
|
|
25
|
+
* role — enough to say the band is deliberate rather than a gap.
|
|
26
|
+
*
|
|
27
|
+
* Which also means it has no scrim and needs none. The other two darken a photograph so a title
|
|
28
|
+
* reads over it; here the ground is the component's own and its contrast is already known.
|
|
29
|
+
*
|
|
30
|
+
* The steps inside the text block are carried by each part's own `margin-block-end` rather than by
|
|
31
|
+
* a gap on the block, because eyebrow-to-title and title-to-description are two different roles
|
|
32
|
+
* that agree at full width and part company on a phone.
|
|
33
|
+
*
|
|
34
|
+
* The title carries the band's accessible name through `aria-labelledby`. A `<section>` is only a
|
|
35
|
+
* region landmark once it has a name, and a band that announced itself as an unnamed section is one
|
|
36
|
+
* more thing a screen reader user walks through rather than a place they can skip to.
|
|
37
|
+
*/
|
|
38
|
+
export function PageHeader({ eyebrow, title, headingLevel = pageHeaderDefaults.headingLevel, description, actions, }) {
|
|
39
|
+
const titleId = useId();
|
|
40
|
+
const [band, revealed] = useReveal();
|
|
41
|
+
const Title = headingLevel === 'h2' ? 'h2' : 'h1';
|
|
42
|
+
return (_jsx("section", { className: pageHeaderParts.root, "aria-labelledby": titleId, children: _jsx("div", { className: pageHeaderParts.inner, ref: band, "data-revealed": revealed, children: _jsxs("div", { className: pageHeaderParts.content, children: [_jsxs("div", { className: pageHeaderParts.text, children: [given(eyebrow) ? (_jsx("p", { className: pageHeaderParts.eyebrow, ...arriving(0), children: eyebrow })) : null, _jsx(Title, { className: pageHeaderParts.title, ...arriving(1), id: titleId, children: title }), given(description) ? (_jsx("p", { className: pageHeaderParts.description, ...arriving(2), children: description })) : null] }), actions ? (_jsx("div", { className: pageHeaderParts.actions, ...arriving(3), children: actions })) : null] }) }) }));
|
|
43
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface PageHeaderOwnProps {
|
|
3
|
+
/** A word or two placing the page before its title names it — a product family, a market, a campaign */
|
|
4
|
+
eyebrow?: string;
|
|
5
|
+
/** Always. The one thing the page is about, in the fewest words that still say it. It is the page's leading heading and the band's accessible name */
|
|
6
|
+
title: string;
|
|
7
|
+
/**
|
|
8
|
+
* `h1` — The default, and correct whenever the hero opens the page — which is what a hero is for
|
|
9
|
+
* `h2` — The rare page that already carries its `h1` elsewhere, and would otherwise have two
|
|
10
|
+
*/
|
|
11
|
+
headingLevel?: 'h1' | 'h2';
|
|
12
|
+
/** The sentence under the title that says what the claim above it means, for the reader who is not yet convinced by the claim alone */
|
|
13
|
+
description?: string;
|
|
14
|
+
/** The one or two things the page wants a reader to do. Composed by the page rather than described to this component, so a call to action is the same Button here as anywhere else on the site */
|
|
15
|
+
actions?: ReactNode;
|
|
16
|
+
}
|
|
17
|
+
export type PageHeaderProps = PageHeaderOwnProps;
|
|
18
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
19
|
+
export declare const pageHeaderParts: {
|
|
20
|
+
readonly root: "dds-pageheader";
|
|
21
|
+
readonly inner: "dds-pageheader__inner";
|
|
22
|
+
readonly content: "dds-pageheader__content";
|
|
23
|
+
readonly text: "dds-pageheader__text";
|
|
24
|
+
readonly eyebrow: "dds-pageheader__eyebrow";
|
|
25
|
+
readonly title: "dds-pageheader__title";
|
|
26
|
+
readonly description: "dds-pageheader__description";
|
|
27
|
+
readonly actions: "dds-pageheader__actions";
|
|
28
|
+
};
|
|
29
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
30
|
+
export declare const pageHeaderDefaults: {
|
|
31
|
+
readonly headingLevel: "h1";
|
|
32
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// GENERATED from page-header.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const pageHeaderParts = {
|
|
4
|
+
root: 'dds-pageheader',
|
|
5
|
+
inner: 'dds-pageheader__inner',
|
|
6
|
+
content: 'dds-pageheader__content',
|
|
7
|
+
text: 'dds-pageheader__text',
|
|
8
|
+
eyebrow: 'dds-pageheader__eyebrow',
|
|
9
|
+
title: 'dds-pageheader__title',
|
|
10
|
+
description: 'dds-pageheader__description',
|
|
11
|
+
actions: 'dds-pageheader__actions',
|
|
12
|
+
};
|
|
13
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
14
|
+
export const pageHeaderDefaults = { headingLevel: 'h1' };
|
|
@@ -0,0 +1,176 @@
|
|
|
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.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Capped, not a screen.
|
|
10
|
+
*
|
|
11
|
+
* `size.band.compact` is the floor, and it is the one thing that separates this tier from the two
|
|
12
|
+
* above it — both take `100cqh`. A page opened for its content wants its name and then the
|
|
13
|
+
* content, so the band is held to size.band.compact rather than a screen and the first sentence
|
|
14
|
+
* is on screen with it.
|
|
15
|
+
*
|
|
16
|
+
* `min-block-size` rather than `block-size`, so a long title or a third line of description grows
|
|
17
|
+
* the band instead of being clipped by it.
|
|
18
|
+
*/
|
|
19
|
+
:where([data-dds-context="marketing"]) .dds-pageheader {
|
|
20
|
+
align-items: center;
|
|
21
|
+
min-block-size: var(--size-band-compact);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
* The rule grid, drawn rather than fetched.
|
|
26
|
+
*
|
|
27
|
+
* The reference design paints this with an inline SVG carrying its own brand hex — a 3KB data URI
|
|
28
|
+
* with `#FF7E88` written into it, which is a colour decision hidden where no token can reach and
|
|
29
|
+
* no check can read. Two repeating gradients say the same thing out of `color.border.subtle-inverse`,
|
|
30
|
+
* the role this package already has for a hairline on a dark ground.
|
|
31
|
+
*
|
|
32
|
+
* `background-image` rather than a part of its own: it is a texture on the band's ground, not an
|
|
33
|
+
* element, and a part that rendered an empty div to carry a pattern would be markup standing in
|
|
34
|
+
* for a paint.
|
|
35
|
+
*
|
|
36
|
+
* The line is `border.width.hairline` and the step is `size.rule-grid.pitch`, a role added with this
|
|
37
|
+
* band. A pitch is not a gap — it is how far apart a decorative line recurs, not the space between
|
|
38
|
+
* two things a reader is comparing — so it earns a name of its own rather than borrowing one.
|
|
39
|
+
*/
|
|
40
|
+
:where([data-dds-context="marketing"]) .dds-pageheader {
|
|
41
|
+
background-image:
|
|
42
|
+
/*
|
|
43
|
+
* The fade, painted over the grid rather than into it.
|
|
44
|
+
*
|
|
45
|
+
* A background layer list paints first-listed on top, so this sits above both sets of rules
|
|
46
|
+
* and below everything the band holds — the heading is a child element and children paint
|
|
47
|
+
* above every background their box carries, so the fade reaches the grid and nothing else.
|
|
48
|
+
*
|
|
49
|
+
* It fades *from* the band's own ground, which is how a paint covers something without a mask:
|
|
50
|
+
* opaque at the top, where the rules are covered, and transparent at the foot, where they come
|
|
51
|
+
* through. `color.bg.brand-strong` is the same role the band paints beneath, so the fade and
|
|
52
|
+
* the ground are one colour and the grid is the only thing that changes.
|
|
53
|
+
*
|
|
54
|
+
* That way round because the band opens under a navigation bar and closes against the page:
|
|
55
|
+
* the rules gather towards the edge the content carries on over, so the grid reads as the
|
|
56
|
+
* ground the page is built on rather than as a lid over the heading.
|
|
57
|
+
*
|
|
58
|
+
* Masking the element instead would have faded the title with it — the grid is a background
|
|
59
|
+
* and the words are not, and a mask cannot tell them apart.
|
|
60
|
+
*/
|
|
61
|
+
linear-gradient(to bottom, var(--color-bg-brand-strong), transparent),
|
|
62
|
+
/*
|
|
63
|
+
* `to right` is physical, and it is the one place in these blocks that is.
|
|
64
|
+
*
|
|
65
|
+
* A CSS gradient has no logical direction — there is no `to inline-end` — so a pattern that
|
|
66
|
+
* must mirror has to be written twice under a direction query. This one does not: the rules
|
|
67
|
+
* repeat on a fixed pitch and the whole field is centred, so the same pixels land in the same
|
|
68
|
+
* places whichever way the page is read. A grid of evenly spaced lines has no leading edge to
|
|
69
|
+
* get wrong.
|
|
70
|
+
*
|
|
71
|
+
* Said out loud because the next pattern here may not be periodic, and a reader who copies
|
|
72
|
+
* this line into one that is would mirror nothing. See the `written-along-the-reading-axis`
|
|
73
|
+
* rule.
|
|
74
|
+
*/
|
|
75
|
+
repeating-linear-gradient(
|
|
76
|
+
to right,
|
|
77
|
+
var(--color-border-subtle-inverse) 0 var(--border-width-hairline),
|
|
78
|
+
transparent var(--border-width-hairline) var(--size-rule-grid-pitch)
|
|
79
|
+
),
|
|
80
|
+
/*
|
|
81
|
+
* The horizontal rules run up from the foot, not down from the top.
|
|
82
|
+
*
|
|
83
|
+
* Drawn `to bottom` and centred, the last rule landed wherever the band's height left it — a
|
|
84
|
+
* line short of the edge on one page, a line past it on the next. `to top` starts the pattern at
|
|
85
|
+
* the bottom edge, so the first rule is the band's own lower edge and every other one is a
|
|
86
|
+
* whole pitch above it, whatever the title and description make the height. The fade covers
|
|
87
|
+
* the top, which is the only end that can now fall between two rules.
|
|
88
|
+
*/
|
|
89
|
+
repeating-linear-gradient(
|
|
90
|
+
to top,
|
|
91
|
+
var(--color-border-subtle-inverse) 0 var(--border-width-hairline),
|
|
92
|
+
transparent var(--border-width-hairline) var(--size-rule-grid-pitch)
|
|
93
|
+
);
|
|
94
|
+
background-position: center;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/*
|
|
98
|
+
* A title with nothing under it carries no step under it.
|
|
99
|
+
*
|
|
100
|
+
* The steps inside the text block sit on each part's own `margin-block-end`, because eyebrow-to-
|
|
101
|
+
* title and title-to-description are two roles that agree at full width and part company on a
|
|
102
|
+
* phone. The cost is a trailing margin: with `description` absent the title is the last child and
|
|
103
|
+
* its step is measured against nothing.
|
|
104
|
+
*/
|
|
105
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__title:last-child {
|
|
106
|
+
margin-block-end: 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/*
|
|
110
|
+
* Starts on a phone, centred once the band is wide enough to hold a line.
|
|
111
|
+
*
|
|
112
|
+
* The same rule the product tier follows, and the reference design applies it to both: centred
|
|
113
|
+
* text is read from a different starting edge on every line, which costs little across a wide
|
|
114
|
+
* measure and a great deal across a narrow one.
|
|
115
|
+
*
|
|
116
|
+
* `size.measure.hero-heading` caps the block at either width; `margin-inline: auto` is what centres
|
|
117
|
+
* that capped block rather than leaving it at the column's leading edge with its text centred
|
|
118
|
+
* inside it.
|
|
119
|
+
*/
|
|
120
|
+
@container (min-width: 48rem) {
|
|
121
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__content {
|
|
122
|
+
align-items: center;
|
|
123
|
+
text-align: center;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__text {
|
|
127
|
+
margin-inline: auto;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/*
|
|
131
|
+
* And the line under the title, which is held to a narrower measure than the block it sits in.
|
|
132
|
+
*
|
|
133
|
+
* `text` runs to a heading's measure and the description to a reading one, so the description's
|
|
134
|
+
* box is the narrower of the two and was sitting against the start edge of a centred block. Its
|
|
135
|
+
* words were centred within it, so what a reader saw was a centred title over a paragraph that
|
|
136
|
+
* had slipped left — the kind of misalignment that looks like a mistake in the copy rather than
|
|
137
|
+
* in a box nobody can see.
|
|
138
|
+
*
|
|
139
|
+
* Only where the block is centred. Below the fold everything ranges to the start and an auto margin
|
|
140
|
+
* would centre the one part that should not be.
|
|
141
|
+
*/
|
|
142
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__description {
|
|
143
|
+
margin-inline: auto;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__actions {
|
|
147
|
+
justify-content: center;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/*
|
|
152
|
+
* Two calls to action stack on a phone and stand side by side once there is room.
|
|
153
|
+
*
|
|
154
|
+
* The reference design makes each one full width at the narrow end — a button that hugs its label
|
|
155
|
+
* on a phone is a tap target sized by how long the word happens to be — and lets them hug once the
|
|
156
|
+
* band is wide enough to hold both on a line.
|
|
157
|
+
*/
|
|
158
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__actions {
|
|
159
|
+
align-items: stretch;
|
|
160
|
+
flex-direction: column;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__actions > * {
|
|
164
|
+
inline-size: 100%;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@container (min-width: 48rem) {
|
|
168
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__actions {
|
|
169
|
+
align-items: center;
|
|
170
|
+
flex-direction: row;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
:where([data-dds-context="marketing"]) .dds-pageheader .dds-pageheader__actions > * {
|
|
174
|
+
inline-size: auto;
|
|
175
|
+
}
|
|
176
|
+
}
|