@luz-ds/landing 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +90 -2
- package/dist/classes.json +39 -0
- package/dist/components/footer.css +80 -0
- package/dist/components/footer.min.css +1 -0
- package/dist/components/glow.css +31 -0
- package/dist/components/glow.min.css +1 -0
- package/dist/components/header.css +71 -0
- package/dist/components/header.min.css +1 -0
- package/dist/components/hero.css +141 -0
- package/dist/components/hero.min.css +1 -0
- package/dist/components/main.css +16 -0
- package/dist/components/main.min.css +1 -0
- package/dist/components/section.css +54 -0
- package/dist/components/section.min.css +1 -0
- package/dist/components/stat.css +34 -0
- package/dist/components/stat.min.css +1 -0
- package/dist/landing.css +421 -0
- package/dist/landing.min.css +1 -0
- package/package.json +52 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024–2026 Fernando Muñoz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,91 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @luz-ds/landing
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The page structure of one kind of site, a landing page: the page of a product, a service or an event that asks the visitor to act. Its header, hero, main, sections, stats, footer and glow are classes on native elements, laid out in the markup by core's objects (`.o-page`, `.o-sticky`, `.o-container`, `.o-row`, `.o-stack`, `.o-grid--split`) and core's navbar; this package adds only their skin and rhythm. `@luz-ds/site` is optional: load it for the search, the language switch or the cookie banner.
|
|
4
|
+
|
|
5
|
+
> **Beta, version 0.x.** Landing has a version of its own, apart from tokens, core and site, and grows in minor versions while it is 0.x: any of them may change a class. Pin an exact version and read the changelog before you upgrade.
|
|
6
|
+
|
|
7
|
+
## When to use it
|
|
8
|
+
|
|
9
|
+
- You build the page of a product, a service or an event, with a hero and features to show side by side.
|
|
10
|
+
- Not for articles or an app: `@luz-ds/cms` and core's shell have what they need.
|
|
11
|
+
|
|
12
|
+
The blocks of an event landing page (hero, programme, speakers, tickets, call to action, registration) are markup to copy, on the [Landing page templates](https://nandovejer.github.io/luz/docs/landing/templates/) page of the docs. They use the classes of core and this package; a block of features of equal weight is a list on core's split grid, `ul.o-grid.o-grid--split`.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
Requires `@luz-ds/tokens` and `@luz-ds/core`, version `^0.1.0`, declared as peer dependencies, loaded in that order before this package. `@luz-ds/site` (`^0.1.0`) is an optional peer: load it before this package if you use its pieces; the patterns work without it.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @luz-ds/tokens @luz-ds/core @luz-ds/site @luz-ds/landing
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Via npm/bundler
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
import '@luz-ds/tokens/css'
|
|
30
|
+
import '@luz-ds/core/css'
|
|
31
|
+
import '@luz-ds/site/css'
|
|
32
|
+
import '@luz-ds/landing/css'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Via CDN
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/tokens@0.1.0/dist/luz-tokens.min.css">
|
|
39
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/core@0.1.0/dist/luz.min.css">
|
|
40
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/site@0.1.0/dist/site.min.css">
|
|
41
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/landing@0.1.0/dist/landing.min.css">
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
There is no script. Add core's and site's if you use their behaviours.
|
|
45
|
+
|
|
46
|
+
## Package exports
|
|
47
|
+
|
|
48
|
+
- **`./css`** → `landing.css` — the patterns, in the cascade layer `luz.landing`, after `luz.site` (`./css/min` for the minified twin)
|
|
49
|
+
- **`./components/*`** → `dist/components/` — one stylesheet per pattern, `<name>.css` and `<name>.min.css`, each in `luz.landing`, for a page that loads only what it uses
|
|
50
|
+
|
|
51
|
+
## Classes included
|
|
52
|
+
|
|
53
|
+
- `.luz-landing-header`, `__brand`, `__actions` — The header: on `header.o-sticky > .o-container.o-container--inline.o-row`, with core's `.luz-nav-toggle` and `.luz-navbar`. The page surface, a rule underneath, the brand and the row's gaps; its panels open under it. [Docs](https://nandovejer.github.io/luz/docs/landing/header/)
|
|
54
|
+
- `.luz-landing-hero`, `__copy`, `__eyebrow`, `__title`, `__lead`, `__media` — The first block: on `section.o-grid.o-grid--split`, two equal columns when each gets 24rem, one below. `--centered`: one column, the copy centred above the media. `__media--bleed`, in a centred hero: the media runs from edge to edge of the window, with no sideways scroll. [Docs](https://nandovejer.github.io/luz/docs/landing/hero/)
|
|
55
|
+
- `.luz-landing-main`, `.luz-landing-section`, `__eyebrow`, `__title`, `__lead`, `.luz-landing-glow` — The rhythm of the page, on `main.o-container.o-stack` and `section.o-stack`; the head of a section, which shares the hero's rules (load `hero.css` with `section.css`) one step smaller; and a tint behind the `.o-page`. Two knobs: `--luz-landing-title-accent`, the colour of the `em` in a hero or section title (unset, the title's), and `--luz-landing-glow-x`, where along the top edge the tint sits (unset, the edge where reading starts). [Docs](https://nandovejer.github.io/luz/docs/landing/section/)
|
|
56
|
+
- `.luz-landing-stat`, `__value`, `__label` — A figure and what it counts, alone or in core's `.luz-card`: a big number in the heading face with tabular figures, the label under it. [Docs](https://nandovejer.github.io/luz/docs/landing/stat/)
|
|
57
|
+
- `.luz-landing-footer`, `__brand`, `__col`, `__col-title` — The footer: on `footer > .o-container.o-container--inline.o-row`, a rule on top and its items at the two ends of the row; or on `footer > .o-container.o-container--inline.o-grid`, a brand block and columns of links, side by side from 768px, one under the other below. [Docs](https://nandovejer.github.io/luz/docs/landing/footer/)
|
|
58
|
+
|
|
59
|
+
<!-- luz:ai-agents:start -->
|
|
60
|
+
## For AI agents
|
|
61
|
+
|
|
62
|
+
`@luz-ds/landing` 0.1.0 is in beta: any release may break anything. Read the breaking changes below before you update, and use only what the files under "Read first" list.
|
|
63
|
+
|
|
64
|
+
### Breaking changes
|
|
65
|
+
|
|
66
|
+
First release of `@luz-ds/landing`. Nothing breaks inside @luz-ds. Coming from `@cai-ds/*`: see the migration note in `CHANGELOG.md`.
|
|
67
|
+
|
|
68
|
+
Older versions: https://github.com/nandovejer/luz/blob/main/packages/landing/CHANGELOG.md
|
|
69
|
+
|
|
70
|
+
### Read first
|
|
71
|
+
|
|
72
|
+
1. `dist/classes.json` in this package: the classes and custom properties its CSS defines. Write only those.
|
|
73
|
+
2. https://nandovejer.github.io/luz/llms.txt: the index of the documentation, short enough for a small context.
|
|
74
|
+
3. https://nandovejer.github.io/luz/llms-full.txt: the same pages in full.
|
|
75
|
+
4. https://nandovejer.github.io/luz/examples/: one standalone page of markup for each component and pattern.
|
|
76
|
+
|
|
77
|
+
### Load order
|
|
78
|
+
|
|
79
|
+
This package needs `@luz-ds/tokens` and `@luz-ds/core` loaded first.
|
|
80
|
+
|
|
81
|
+
`@luz-ds/site` is optional: the CSS of this package works with the packages above alone.
|
|
82
|
+
|
|
83
|
+
### Check what you write
|
|
84
|
+
|
|
85
|
+
Run `npx @luz-ds/check <files>` on every HTML and CSS file you write, and fix what it reports. To copy the accessibility reviewer into your project: `npx @luz-ds/check agent > .claude/agents/luz-accessibility-reviewer.md`.
|
|
86
|
+
|
|
87
|
+
<!-- luz:ai-agents:end -->
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
MIT
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"package": "@luz-ds/landing",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"classes": [
|
|
6
|
+
{ "name": "luz-landing-footer", "kind": "pattern", "layer": "luz.landing", "files": ["components/footer.css"], "defined": true, "block": "luz-landing-footer" },
|
|
7
|
+
{ "name": "luz-landing-footer__brand", "kind": "pattern", "layer": "luz.landing", "files": ["components/footer.css"], "defined": true, "block": "luz-landing-footer", "part": "brand" },
|
|
8
|
+
{ "name": "luz-landing-footer__col", "kind": "pattern", "layer": "luz.landing", "files": ["components/footer.css"], "defined": true, "block": "luz-landing-footer", "part": "col" },
|
|
9
|
+
{ "name": "luz-landing-footer__col-title", "kind": "pattern", "layer": "luz.landing", "files": ["components/footer.css"], "defined": true, "block": "luz-landing-footer", "part": "col-title" },
|
|
10
|
+
{ "name": "luz-landing-glow", "kind": "pattern", "layer": "luz.landing", "files": ["components/glow.css"], "defined": true, "block": "luz-landing-glow" },
|
|
11
|
+
{ "name": "luz-landing-header", "kind": "pattern", "layer": "luz.landing", "files": ["components/header.css"], "defined": true, "block": "luz-landing-header" },
|
|
12
|
+
{ "name": "luz-landing-header__actions", "kind": "pattern", "layer": "luz.landing", "files": ["components/header.css"], "defined": true, "block": "luz-landing-header", "part": "actions" },
|
|
13
|
+
{ "name": "luz-landing-header__brand", "kind": "pattern", "layer": "luz.landing", "files": ["components/header.css"], "defined": true, "block": "luz-landing-header", "part": "brand" },
|
|
14
|
+
{ "name": "luz-landing-hero", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css"], "defined": true, "block": "luz-landing-hero" },
|
|
15
|
+
{ "name": "luz-landing-hero--centered", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css"], "defined": true, "block": "luz-landing-hero", "modifier": "centered" },
|
|
16
|
+
{ "name": "luz-landing-hero__copy", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css"], "defined": true, "block": "luz-landing-hero", "part": "copy" },
|
|
17
|
+
{ "name": "luz-landing-hero__eyebrow", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css"], "defined": true, "block": "luz-landing-hero", "part": "eyebrow" },
|
|
18
|
+
{ "name": "luz-landing-hero__lead", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css"], "defined": true, "block": "luz-landing-hero", "part": "lead" },
|
|
19
|
+
{ "name": "luz-landing-hero__media", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css"], "defined": true, "block": "luz-landing-hero", "part": "media" },
|
|
20
|
+
{ "name": "luz-landing-hero__media--bleed", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css"], "defined": true, "block": "luz-landing-hero", "modifier": "bleed", "part": "media" },
|
|
21
|
+
{ "name": "luz-landing-hero__title", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css"], "defined": true, "block": "luz-landing-hero", "part": "title" },
|
|
22
|
+
{ "name": "luz-landing-main", "kind": "pattern", "layer": "luz.landing", "files": ["components/main.css"], "defined": true, "block": "luz-landing-main" },
|
|
23
|
+
{ "name": "luz-landing-section", "kind": "pattern", "layer": "luz.landing", "files": ["components/section.css"], "defined": true, "block": "luz-landing-section" },
|
|
24
|
+
{ "name": "luz-landing-section__eyebrow", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css", "components/section.css"], "defined": true, "block": "luz-landing-section", "part": "eyebrow" },
|
|
25
|
+
{ "name": "luz-landing-section__lead", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css", "components/section.css"], "defined": true, "block": "luz-landing-section", "part": "lead" },
|
|
26
|
+
{ "name": "luz-landing-section__title", "kind": "pattern", "layer": "luz.landing", "files": ["components/hero.css", "components/section.css"], "defined": true, "block": "luz-landing-section", "part": "title" },
|
|
27
|
+
{ "name": "luz-landing-stat", "kind": "pattern", "layer": "luz.landing", "files": ["components/stat.css"], "defined": true, "block": "luz-landing-stat" },
|
|
28
|
+
{ "name": "luz-landing-stat__label", "kind": "pattern", "layer": "luz.landing", "files": ["components/stat.css"], "defined": true, "block": "luz-landing-stat", "part": "label" },
|
|
29
|
+
{ "name": "luz-landing-stat__value", "kind": "pattern", "layer": "luz.landing", "files": ["components/section.css", "components/stat.css"], "defined": true, "block": "luz-landing-stat", "part": "value" },
|
|
30
|
+
{ "name": "o-actions", "kind": "object", "layer": "luz.landing", "files": ["components/hero.css"], "defined": false, "block": "o-actions" },
|
|
31
|
+
{ "name": "o-grid", "kind": "object", "layer": "luz.landing", "files": ["components/footer.css"], "defined": false, "block": "o-grid" },
|
|
32
|
+
{ "name": "o-row", "kind": "object", "layer": "luz.landing", "files": ["components/footer.css", "components/header.css"], "defined": false, "block": "o-row" }
|
|
33
|
+
],
|
|
34
|
+
"properties": [
|
|
35
|
+
{ "name": "--luz-grid-min", "scope": "component", "layer": "luz.landing", "files": ["components/hero.css"] },
|
|
36
|
+
{ "name": "--luz-landing-glow-start", "scope": "component", "layer": "luz.landing", "files": ["components/glow.css"] },
|
|
37
|
+
{ "name": "--luz-lang-switch-top", "scope": "component", "layer": "luz.landing", "files": ["components/header.css"] }
|
|
38
|
+
]
|
|
39
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
@layer luz.tokens, luz.themes, luz.settings, luz.generic, luz.elements, luz.objects, luz.components, luz.utilities, luz.site, luz.landing, luz.cms, luz.app, luz.docs, luz.print;
|
|
2
|
+
@layer luz.landing {
|
|
3
|
+
/* ==========================================================================
|
|
4
|
+
LUZ Landing: footer.
|
|
5
|
+
footer.luz-landing-footer > div.o-container.o-container--inline.o-row: a
|
|
6
|
+
divider above, its items at the two ends of the row; at 768px and below
|
|
7
|
+
a column aligned to the start.
|
|
8
|
+
Or > div.o-container.o-container--inline.o-grid holding a __brand (the
|
|
9
|
+
name, a version, one line) and __col columns (nav > h2.__col-title + ul
|
|
10
|
+
of links, each a target of 24px or more): one under the other, side
|
|
11
|
+
by side from 768px, the brand twice as wide as a column.
|
|
12
|
+
========================================================================== */
|
|
13
|
+
|
|
14
|
+
.luz-landing-footer {
|
|
15
|
+
padding-block: var(--luz-space-lg) var(--luz-space-xl);
|
|
16
|
+
border-block-start: 1px solid var(--luz-divider);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.luz-landing-footer > .o-row {
|
|
20
|
+
justify-content: space-between;
|
|
21
|
+
gap: var(--luz-space-md);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* A column that does not wrap: a wrapping column nested in grids makes
|
|
25
|
+
Chromium's layout take tens of seconds */
|
|
26
|
+
@media (max-width: 768px) {
|
|
27
|
+
.luz-landing-footer > .o-row {
|
|
28
|
+
flex-flow: column nowrap;
|
|
29
|
+
align-items: flex-start;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.luz-landing-footer > .o-grid {
|
|
34
|
+
gap: var(--luz-space-lg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@media (min-width: 768px) {
|
|
38
|
+
.luz-landing-footer > .o-grid {
|
|
39
|
+
grid-template-columns: minmax(0, 2fr);
|
|
40
|
+
grid-auto-columns: minmax(0, 1fr);
|
|
41
|
+
grid-auto-flow: column;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.luz-landing-footer__brand,
|
|
46
|
+
.luz-landing-footer__col,
|
|
47
|
+
.luz-landing-footer__col :where(ul) {
|
|
48
|
+
display: grid;
|
|
49
|
+
align-content: start;
|
|
50
|
+
gap: var(--luz-space-xs);
|
|
51
|
+
margin: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.luz-landing-footer__brand > *,
|
|
55
|
+
.luz-landing-footer__col-title {
|
|
56
|
+
margin: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.luz-landing-footer__col-title {
|
|
60
|
+
font-family: var(--luz-font-sans);
|
|
61
|
+
font-size: var(--luz-text-sm);
|
|
62
|
+
font-weight: 600;
|
|
63
|
+
letter-spacing: 0;
|
|
64
|
+
color: var(--luz-text-primary);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.luz-landing-footer__col :where(ul) {
|
|
68
|
+
padding: 0;
|
|
69
|
+
list-style: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* Each link is a target of 24px or more (WCAG 2.5.8): a box of its own,
|
|
73
|
+
as tall as a small control, the text centred in it */
|
|
74
|
+
.luz-landing-footer__col :where(a) {
|
|
75
|
+
display: inline-flex;
|
|
76
|
+
align-items: center;
|
|
77
|
+
min-block-size: var(--luz-control-sm);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer luz.tokens,luz.themes,luz.settings,luz.generic,luz.elements,luz.objects,luz.components,luz.utilities,luz.site,luz.landing,luz.cms,luz.app,luz.docs,luz.print;@layer luz.landing{.luz-landing-footer{padding-block:var(--luz-space-lg) var(--luz-space-xl);border-block-start:1px solid var(--luz-divider)}.luz-landing-footer>.o-row{justify-content:space-between;gap:var(--luz-space-md)}@media(max-width:768px){.luz-landing-footer>.o-row{flex-flow:column nowrap;align-items:flex-start}}.luz-landing-footer>.o-grid{gap:var(--luz-space-lg)}@media(min-width:768px){.luz-landing-footer>.o-grid{grid-template-columns:minmax(0,2fr);grid-auto-columns:minmax(0,1fr);grid-auto-flow:column}}.luz-landing-footer__brand,.luz-landing-footer__col,.luz-landing-footer__col :where(ul){display:grid;align-content:start;gap:var(--luz-space-xs);margin:0}.luz-landing-footer__brand>*,.luz-landing-footer__col-title{margin:0}.luz-landing-footer__col-title{font-family:var(--luz-font-sans);font-size:var(--luz-text-sm);font-weight:600;letter-spacing:0;color:var(--luz-text-primary)}.luz-landing-footer__col :where(ul){padding:0;list-style:none}.luz-landing-footer__col :where(a){display:inline-flex;align-items:center;min-block-size:var(--luz-control-sm)}}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
@layer luz.tokens, luz.themes, luz.settings, luz.generic, luz.elements, luz.objects, luz.components, luz.utilities, luz.site, luz.landing, luz.cms, luz.app, luz.docs, luz.print;
|
|
2
|
+
@layer luz.landing {
|
|
3
|
+
/* ==========================================================================
|
|
4
|
+
LUZ Landing: glow.
|
|
5
|
+
On the .o-page element: the brand's subtle tint at the top of the page,
|
|
6
|
+
over a fade from the page surface to the muted one. Decoration only: it
|
|
7
|
+
carries no meaning, and paper does not get it.
|
|
8
|
+
--luz-landing-glow-x: where along the top edge the tint sits, a physical
|
|
9
|
+
position (0% the left, 100% the right). Unset, the edge where reading
|
|
10
|
+
starts: the left in left-to-right text, the right in right-to-left.
|
|
11
|
+
========================================================================== */
|
|
12
|
+
|
|
13
|
+
.luz-landing-glow {
|
|
14
|
+
--luz-landing-glow-start: 100%;
|
|
15
|
+
|
|
16
|
+
background:
|
|
17
|
+
radial-gradient(circle at var(--luz-landing-glow-x, var(--luz-landing-glow-start)) 0%, var(--luz-brand-subtle), transparent 28%),
|
|
18
|
+
linear-gradient(180deg, var(--luz-surface-page) 0%, var(--luz-surface-muted) 100%);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.luz-landing-glow:dir(ltr) {
|
|
22
|
+
--luz-landing-glow-start: 0%;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@media print {
|
|
26
|
+
.luz-landing-glow {
|
|
27
|
+
background: none;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer luz.tokens,luz.themes,luz.settings,luz.generic,luz.elements,luz.objects,luz.components,luz.utilities,luz.site,luz.landing,luz.cms,luz.app,luz.docs,luz.print;@layer luz.landing{.luz-landing-glow{--luz-landing-glow-start: 100%;background:radial-gradient(circle at var(--luz-landing-glow-x, var(--luz-landing-glow-start)) 0%,var(--luz-brand-subtle),transparent 28%),linear-gradient(180deg,var(--luz-surface-page) 0%,var(--luz-surface-muted) 100%)}.luz-landing-glow:dir(ltr){--luz-landing-glow-start: 0%}@media print{.luz-landing-glow{background:none}}}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
@layer luz.tokens, luz.themes, luz.settings, luz.generic, luz.elements, luz.objects, luz.components, luz.utilities, luz.site, luz.landing, luz.cms, luz.app, luz.docs, luz.print;
|
|
2
|
+
@layer luz.landing {
|
|
3
|
+
/* ==========================================================================
|
|
4
|
+
LUZ Landing: header.
|
|
5
|
+
header.luz-landing-header.o-sticky > div.o-container.o-container--inline.o-row
|
|
6
|
+
holding core's .luz-nav-toggle, the __brand link, core's
|
|
7
|
+
nav.luz-navbar[popover] and a div.o-row.__actions (search, language,
|
|
8
|
+
a login link). Core gives the stickiness, the width and the row; the
|
|
9
|
+
landing adds the surface, the divider, the brand and the gaps.
|
|
10
|
+
========================================================================== */
|
|
11
|
+
|
|
12
|
+
/* A one-row bar of 44px controls is core's --luz-bar-h tall: two 2xs
|
|
13
|
+
paddings, the row and the divider. With enlarged text the row wraps
|
|
14
|
+
and the bar grows. */
|
|
15
|
+
.luz-landing-header {
|
|
16
|
+
padding-block: var(--luz-space-2xs);
|
|
17
|
+
border-block-end: 1px solid var(--luz-divider);
|
|
18
|
+
background: var(--luz-surface-page);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* The row wraps rather than overflow (WCAG 1.4.4, 1.4.10); its gutters are
|
|
22
|
+
the page's, so the brand starts where the content starts */
|
|
23
|
+
.luz-landing-header > .o-row {
|
|
24
|
+
gap: var(--luz-space-xs) var(--luz-space-md);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* A link outside a <nav>, so core would underline it. It takes the free
|
|
28
|
+
room of the row, which pushes the links and the actions to the end */
|
|
29
|
+
.luz-landing-header__brand {
|
|
30
|
+
display: inline-flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
gap: var(--luz-space-xs);
|
|
33
|
+
min-block-size: var(--luz-control-lg);
|
|
34
|
+
margin-inline-end: auto;
|
|
35
|
+
color: var(--luz-text-primary);
|
|
36
|
+
font-family: var(--luz-font-sans);
|
|
37
|
+
font-size: var(--luz-text-base);
|
|
38
|
+
font-weight: 600;
|
|
39
|
+
text-decoration: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.luz-landing-header__actions {
|
|
43
|
+
gap: var(--luz-space-xs);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* The language list of site's <luz-lang-switch> opens under this bar */
|
|
47
|
+
.luz-landing-header :where(luz-lang-switch) {
|
|
48
|
+
--luz-lang-switch-top: var(--luz-bar-h);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@media (min-width: 769px) {
|
|
52
|
+
.luz-landing-header > .o-row {
|
|
53
|
+
column-gap: var(--luz-space-lg);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* With anchor positioning the panels opened inside the bar (core's navbar,
|
|
58
|
+
the language list) open at its block end, on two rows as on one. Scoped,
|
|
59
|
+
so with two bars on a page each panel finds its own */
|
|
60
|
+
@supports (anchor-name: --luz-bar) {
|
|
61
|
+
.luz-landing-header {
|
|
62
|
+
anchor-name: --luz-bar;
|
|
63
|
+
anchor-scope: --luz-bar;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.luz-landing-header :where(luz-lang-switch) {
|
|
67
|
+
--luz-lang-switch-top: anchor(--luz-bar end, var(--luz-bar-h));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer luz.tokens,luz.themes,luz.settings,luz.generic,luz.elements,luz.objects,luz.components,luz.utilities,luz.site,luz.landing,luz.cms,luz.app,luz.docs,luz.print;@layer luz.landing{.luz-landing-header{padding-block:var(--luz-space-2xs);border-block-end:1px solid var(--luz-divider);background:var(--luz-surface-page)}.luz-landing-header>.o-row{gap:var(--luz-space-xs) var(--luz-space-md)}.luz-landing-header__brand{display:inline-flex;align-items:center;gap:var(--luz-space-xs);min-block-size:var(--luz-control-lg);margin-inline-end:auto;color:var(--luz-text-primary);font-family:var(--luz-font-sans);font-size:var(--luz-text-base);font-weight:600;text-decoration:none}.luz-landing-header__actions{gap:var(--luz-space-xs)}.luz-landing-header :where(luz-lang-switch){--luz-lang-switch-top: var(--luz-bar-h)}@media(min-width:769px){.luz-landing-header>.o-row{column-gap:var(--luz-space-lg)}}@supports (anchor-name: --luz-bar){.luz-landing-header{anchor-name:--luz-bar;anchor-scope:--luz-bar}.luz-landing-header :where(luz-lang-switch){--luz-lang-switch-top: anchor(--luz-bar end, var(--luz-bar-h))}}}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
@layer luz.tokens, luz.themes, luz.settings, luz.generic, luz.elements, luz.objects, luz.components, luz.utilities, luz.site, luz.landing, luz.cms, luz.app, luz.docs, luz.print;
|
|
2
|
+
@layer luz.landing {
|
|
3
|
+
/* ==========================================================================
|
|
4
|
+
LUZ Landing: hero.
|
|
5
|
+
The first block of a home or a landing page:
|
|
6
|
+
section.luz-landing-hero.o-grid.o-grid--split > __copy (+ __media). Core's
|
|
7
|
+
split grid gives two equal columns when each gets 24rem and one below:
|
|
8
|
+
intrinsic, so it stacks in a narrow column and with larger text. Copy
|
|
9
|
+
first in the source, so first in reading order in both directions.
|
|
10
|
+
--centered: one column, the copy centred above the media. __media--bleed,
|
|
11
|
+
in a centred hero: the media runs from edge to edge of the window.
|
|
12
|
+
The eyebrow, the title and the lead share their rules with the head of a
|
|
13
|
+
section (section.css).
|
|
14
|
+
========================================================================== */
|
|
15
|
+
|
|
16
|
+
.luz-landing-hero {
|
|
17
|
+
--luz-grid-min: 24rem;
|
|
18
|
+
|
|
19
|
+
gap: var(--luz-space-xl) var(--luz-space-2xl);
|
|
20
|
+
align-items: center;
|
|
21
|
+
padding-block-start: var(--luz-space-3xl);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Grid items: a long word or a wide child never widens the column */
|
|
25
|
+
.luz-landing-hero__copy,
|
|
26
|
+
.luz-landing-hero__media {
|
|
27
|
+
min-inline-size: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* A word longer than the line (400 % text on a phone, WCAG 1.4.10) breaks
|
|
31
|
+
instead of widening the column: the centred copy is sized to its content,
|
|
32
|
+
so its narrowest width is its longest word */
|
|
33
|
+
.luz-landing-hero__copy {
|
|
34
|
+
overflow-wrap: anywhere;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.luz-landing-hero__eyebrow,
|
|
38
|
+
.luz-landing-section__eyebrow {
|
|
39
|
+
margin-block-end: var(--luz-space-sm);
|
|
40
|
+
font-family: var(--luz-font-mono);
|
|
41
|
+
font-size: var(--luz-text-xs);
|
|
42
|
+
font-weight: 500;
|
|
43
|
+
line-height: 1.5;
|
|
44
|
+
letter-spacing: 0.1em;
|
|
45
|
+
text-transform: uppercase;
|
|
46
|
+
color: var(--luz-text-secondary);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.luz-landing-hero__title,
|
|
50
|
+
.luz-landing-section__title {
|
|
51
|
+
font-family: var(--luz-font-heading);
|
|
52
|
+
font-size: var(--luz-text-4xl);
|
|
53
|
+
font-weight: 300;
|
|
54
|
+
line-height: 1.1;
|
|
55
|
+
letter-spacing: -0.02em;
|
|
56
|
+
text-wrap: balance;
|
|
57
|
+
color: var(--luz-text-primary);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* The mono has no Arabic letters; spacing between letters breaks the joins */
|
|
61
|
+
.luz-landing-hero__eyebrow:lang(ar),
|
|
62
|
+
.luz-landing-section__eyebrow:lang(ar) {
|
|
63
|
+
font-family: var(--luz-font-sans);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.luz-landing-hero__eyebrow:lang(ar),
|
|
67
|
+
.luz-landing-section__eyebrow:lang(ar),
|
|
68
|
+
.luz-landing-hero__title:lang(ar),
|
|
69
|
+
.luz-landing-section__title:lang(ar) {
|
|
70
|
+
letter-spacing: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.luz-landing-hero__lead,
|
|
74
|
+
.luz-landing-section__lead {
|
|
75
|
+
max-inline-size: 70ch;
|
|
76
|
+
font-size: var(--luz-text-xl);
|
|
77
|
+
line-height: 1.4;
|
|
78
|
+
text-wrap: pretty;
|
|
79
|
+
color: var(--luz-text-secondary);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.luz-landing-hero__lead {
|
|
83
|
+
margin-block: var(--luz-space-md) var(--luz-space-lg);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* One column: core's split grid with a column as wide as the row */
|
|
87
|
+
.luz-landing-hero--centered {
|
|
88
|
+
--luz-grid-min: 100%;
|
|
89
|
+
|
|
90
|
+
text-align: center;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.luz-landing-hero--centered > .luz-landing-hero__copy {
|
|
94
|
+
justify-self: center;
|
|
95
|
+
max-inline-size: min(100%, 48rem);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.luz-landing-hero--centered .luz-landing-hero__lead {
|
|
99
|
+
margin-inline: auto;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.luz-landing-hero--centered .o-actions {
|
|
103
|
+
justify-content: center;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* The window's width without a viewport unit, which counts a visible
|
|
107
|
+
scrollbar and scrolls sideways: the root is the query container, and
|
|
108
|
+
the media's margins go out from the centre of the column to its edges */
|
|
109
|
+
:root:has(.luz-landing-hero__media--bleed) {
|
|
110
|
+
container-type: inline-size;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.luz-landing-hero__media--bleed {
|
|
114
|
+
margin-inline: calc(50% - 50cqi);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@media (max-width: 1023px) {
|
|
118
|
+
.luz-landing-hero {
|
|
119
|
+
padding-block-start: calc(var(--luz-space-xl) + var(--luz-space-xs));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.luz-landing-hero__title {
|
|
123
|
+
font-size: var(--luz-text-3xl);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.luz-landing-hero__lead {
|
|
127
|
+
font-size: var(--luz-text-lg);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@media (max-width: 640px) {
|
|
132
|
+
.luz-landing-hero__title {
|
|
133
|
+
font-size: var(--luz-text-2xl);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.luz-landing-hero__lead {
|
|
137
|
+
font-size: var(--luz-text-base);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer luz.tokens,luz.themes,luz.settings,luz.generic,luz.elements,luz.objects,luz.components,luz.utilities,luz.site,luz.landing,luz.cms,luz.app,luz.docs,luz.print;@layer luz.landing{.luz-landing-hero{--luz-grid-min: 24rem;gap:var(--luz-space-xl) var(--luz-space-2xl);align-items:center;padding-block-start:var(--luz-space-3xl)}.luz-landing-hero__copy,.luz-landing-hero__media{min-inline-size:0}.luz-landing-hero__copy{overflow-wrap:anywhere}.luz-landing-hero__eyebrow,.luz-landing-section__eyebrow{margin-block-end:var(--luz-space-sm);font-family:var(--luz-font-mono);font-size:var(--luz-text-xs);font-weight:500;line-height:1.5;letter-spacing:.1em;text-transform:uppercase;color:var(--luz-text-secondary)}.luz-landing-hero__title,.luz-landing-section__title{font-family:var(--luz-font-heading);font-size:var(--luz-text-4xl);font-weight:300;line-height:1.1;letter-spacing:-.02em;text-wrap:balance;color:var(--luz-text-primary)}.luz-landing-hero__eyebrow:lang(ar),.luz-landing-section__eyebrow:lang(ar){font-family:var(--luz-font-sans)}.luz-landing-hero__eyebrow:lang(ar),.luz-landing-section__eyebrow:lang(ar),.luz-landing-hero__title:lang(ar),.luz-landing-section__title:lang(ar){letter-spacing:0}.luz-landing-hero__lead,.luz-landing-section__lead{max-inline-size:70ch;font-size:var(--luz-text-xl);line-height:1.4;text-wrap:pretty;color:var(--luz-text-secondary)}.luz-landing-hero__lead{margin-block:var(--luz-space-md) var(--luz-space-lg)}.luz-landing-hero--centered{--luz-grid-min: 100%;text-align:center}.luz-landing-hero--centered>.luz-landing-hero__copy{justify-self:center;max-inline-size:min(100%,48rem)}.luz-landing-hero--centered .luz-landing-hero__lead{margin-inline:auto}.luz-landing-hero--centered .o-actions{justify-content:center}:root:has(.luz-landing-hero__media--bleed){container-type:inline-size}.luz-landing-hero__media--bleed{margin-inline:calc(50% - 50cqi)}@media(max-width:1023px){.luz-landing-hero{padding-block-start:calc(var(--luz-space-xl) + var(--luz-space-xs))}.luz-landing-hero__title{font-size:var(--luz-text-3xl)}.luz-landing-hero__lead{font-size:var(--luz-text-lg)}}@media(max-width:640px){.luz-landing-hero__title{font-size:var(--luz-text-2xl)}.luz-landing-hero__lead{font-size:var(--luz-text-base)}}}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
@layer luz.tokens, luz.themes, luz.settings, luz.generic, luz.elements, luz.objects, luz.components, luz.utilities, luz.site, luz.landing, luz.cms, luz.app, luz.docs, luz.print;
|
|
2
|
+
@layer luz.landing {
|
|
3
|
+
/* ==========================================================================
|
|
4
|
+
LUZ Landing: main.
|
|
5
|
+
The rhythm of the page: main.o-container.o-stack.luz-landing-main. Wide
|
|
6
|
+
room between the blocks and under the last one; none above the first,
|
|
7
|
+
as the hero brings its own. The landing's layer comes after core's
|
|
8
|
+
objects, so this gap wins over .o-stack's.
|
|
9
|
+
========================================================================== */
|
|
10
|
+
|
|
11
|
+
.luz-landing-main {
|
|
12
|
+
gap: var(--luz-space-3xl);
|
|
13
|
+
padding-block: 0 var(--luz-space-3xl);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer luz.tokens,luz.themes,luz.settings,luz.generic,luz.elements,luz.objects,luz.components,luz.utilities,luz.site,luz.landing,luz.cms,luz.app,luz.docs,luz.print;@layer luz.landing{.luz-landing-main{gap:var(--luz-space-3xl);padding-block:0 var(--luz-space-3xl)}}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
@layer luz.tokens, luz.themes, luz.settings, luz.generic, luz.elements, luz.objects, luz.components, luz.utilities, luz.site, luz.landing, luz.cms, luz.app, luz.docs, luz.print;
|
|
2
|
+
@layer luz.landing {
|
|
3
|
+
/* ==========================================================================
|
|
4
|
+
LUZ Landing: section.
|
|
5
|
+
A block of the page after the hero: section.o-stack.luz-landing-section,
|
|
6
|
+
its heading first. Add core's .luz-band for a tint from edge to edge.
|
|
7
|
+
The head: __eyebrow, __title and __lead share the rules of the hero's
|
|
8
|
+
(one selector list, in hero.css, so load it with this file); the title
|
|
9
|
+
is one step smaller.
|
|
10
|
+
========================================================================== */
|
|
11
|
+
|
|
12
|
+
.luz-landing-section {
|
|
13
|
+
gap: var(--luz-space-md);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.luz-landing-section__eyebrow {
|
|
17
|
+
margin-block-end: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.luz-landing-section__title,
|
|
21
|
+
.luz-landing-stat__value {
|
|
22
|
+
font-size: var(--luz-text-3xl);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* A knob for the stressed word of a hero's or a section's title; unset,
|
|
26
|
+
the title's colour */
|
|
27
|
+
.luz-landing-hero__title em,
|
|
28
|
+
.luz-landing-section__title em {
|
|
29
|
+
color: var(--luz-landing-title-accent, inherit);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.luz-landing-section__lead {
|
|
33
|
+
font-size: var(--luz-text-lg);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media (max-width: 1023px) {
|
|
37
|
+
.luz-landing-section__title,
|
|
38
|
+
.luz-landing-stat__value {
|
|
39
|
+
font-size: var(--luz-text-2xl);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@media (max-width: 640px) {
|
|
44
|
+
.luz-landing-section__title,
|
|
45
|
+
.luz-landing-stat__value {
|
|
46
|
+
font-size: var(--luz-text-xl);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.luz-landing-section__lead {
|
|
50
|
+
font-size: var(--luz-text-base);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer luz.tokens,luz.themes,luz.settings,luz.generic,luz.elements,luz.objects,luz.components,luz.utilities,luz.site,luz.landing,luz.cms,luz.app,luz.docs,luz.print;@layer luz.landing{.luz-landing-section{gap:var(--luz-space-md)}.luz-landing-section__eyebrow{margin-block-end:0}.luz-landing-section__title,.luz-landing-stat__value{font-size:var(--luz-text-3xl)}.luz-landing-hero__title em,.luz-landing-section__title em{color:var(--luz-landing-title-accent, inherit)}.luz-landing-section__lead{font-size:var(--luz-text-lg)}@media(max-width:1023px){.luz-landing-section__title,.luz-landing-stat__value{font-size:var(--luz-text-2xl)}}@media(max-width:640px){.luz-landing-section__title,.luz-landing-stat__value{font-size:var(--luz-text-xl)}.luz-landing-section__lead{font-size:var(--luz-text-base)}}}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@layer luz.tokens, luz.themes, luz.settings, luz.generic, luz.elements, luz.objects, luz.components, luz.utilities, luz.site, luz.landing, luz.cms, luz.app, luz.docs, luz.print;
|
|
2
|
+
@layer luz.landing {
|
|
3
|
+
/* ==========================================================================
|
|
4
|
+
LUZ Landing: stat.
|
|
5
|
+
A figure and what it counts: div.luz-landing-stat > p.__value + p.__label,
|
|
6
|
+
alone or inside core's .luz-card. Tabular figures, so a row of stats
|
|
7
|
+
lines up digit under digit.
|
|
8
|
+
========================================================================== */
|
|
9
|
+
|
|
10
|
+
.luz-landing-stat {
|
|
11
|
+
display: grid;
|
|
12
|
+
gap: var(--luz-space-2xs);
|
|
13
|
+
min-inline-size: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.luz-landing-stat > * {
|
|
17
|
+
margin: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.luz-landing-stat__value {
|
|
21
|
+
font-family: var(--luz-font-heading);
|
|
22
|
+
font-weight: 300;
|
|
23
|
+
font-variant-numeric: tabular-nums;
|
|
24
|
+
line-height: 1.1;
|
|
25
|
+
overflow-wrap: anywhere;
|
|
26
|
+
color: var(--luz-text-primary);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.luz-landing-stat__label {
|
|
30
|
+
font-size: var(--luz-text-base);
|
|
31
|
+
color: var(--luz-text-secondary);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer luz.tokens,luz.themes,luz.settings,luz.generic,luz.elements,luz.objects,luz.components,luz.utilities,luz.site,luz.landing,luz.cms,luz.app,luz.docs,luz.print;@layer luz.landing{.luz-landing-stat{display:grid;gap:var(--luz-space-2xs);min-inline-size:0}.luz-landing-stat>*{margin:0}.luz-landing-stat__value{font-family:var(--luz-font-heading);font-weight:300;font-variant-numeric:tabular-nums;line-height:1.1;overflow-wrap:anywhere;color:var(--luz-text-primary)}.luz-landing-stat__label{font-size:var(--luz-text-base);color:var(--luz-text-secondary)}}
|
package/dist/landing.css
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
@layer luz.tokens, luz.themes, luz.settings, luz.generic, luz.elements, luz.objects, luz.components, luz.utilities, luz.site, luz.landing, luz.cms, luz.app, luz.docs, luz.print;
|
|
2
|
+
@layer luz.landing {
|
|
3
|
+
/* ==========================================================================
|
|
4
|
+
LUZ Landing
|
|
5
|
+
The page structure of one kind of site, a landing page: its header,
|
|
6
|
+
hero, main, sections, stats, footer and glow. Each is a class of the landing on
|
|
7
|
+
a native element, laid out in the markup by core's objects (.o-page,
|
|
8
|
+
.o-sticky, .o-container, .o-row, .o-stack, .o-grid--split); the landing
|
|
9
|
+
adds only its skin and its rhythm.
|
|
10
|
+
Requires: @luz-ds/tokens and @luz-ds/core loaded first; @luz-ds/site
|
|
11
|
+
optional, loaded before this file.
|
|
12
|
+
========================================================================== */
|
|
13
|
+
|
|
14
|
+
/* ==========================================================================
|
|
15
|
+
LUZ Landing: header.
|
|
16
|
+
header.luz-landing-header.o-sticky > div.o-container.o-container--inline.o-row
|
|
17
|
+
holding core's .luz-nav-toggle, the __brand link, core's
|
|
18
|
+
nav.luz-navbar[popover] and a div.o-row.__actions (search, language,
|
|
19
|
+
a login link). Core gives the stickiness, the width and the row; the
|
|
20
|
+
landing adds the surface, the divider, the brand and the gaps.
|
|
21
|
+
========================================================================== */
|
|
22
|
+
|
|
23
|
+
/* A one-row bar of 44px controls is core's --luz-bar-h tall: two 2xs
|
|
24
|
+
paddings, the row and the divider. With enlarged text the row wraps
|
|
25
|
+
and the bar grows. */
|
|
26
|
+
.luz-landing-header {
|
|
27
|
+
padding-block: var(--luz-space-2xs);
|
|
28
|
+
border-block-end: 1px solid var(--luz-divider);
|
|
29
|
+
background: var(--luz-surface-page);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* The row wraps rather than overflow (WCAG 1.4.4, 1.4.10); its gutters are
|
|
33
|
+
the page's, so the brand starts where the content starts */
|
|
34
|
+
.luz-landing-header > .o-row {
|
|
35
|
+
gap: var(--luz-space-xs) var(--luz-space-md);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* A link outside a <nav>, so core would underline it. It takes the free
|
|
39
|
+
room of the row, which pushes the links and the actions to the end */
|
|
40
|
+
.luz-landing-header__brand {
|
|
41
|
+
display: inline-flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
gap: var(--luz-space-xs);
|
|
44
|
+
min-block-size: var(--luz-control-lg);
|
|
45
|
+
margin-inline-end: auto;
|
|
46
|
+
color: var(--luz-text-primary);
|
|
47
|
+
font-family: var(--luz-font-sans);
|
|
48
|
+
font-size: var(--luz-text-base);
|
|
49
|
+
font-weight: 600;
|
|
50
|
+
text-decoration: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.luz-landing-header__actions {
|
|
54
|
+
gap: var(--luz-space-xs);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* The language list of site's <luz-lang-switch> opens under this bar */
|
|
58
|
+
.luz-landing-header :where(luz-lang-switch) {
|
|
59
|
+
--luz-lang-switch-top: var(--luz-bar-h);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@media (min-width: 769px) {
|
|
63
|
+
.luz-landing-header > .o-row {
|
|
64
|
+
column-gap: var(--luz-space-lg);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* With anchor positioning the panels opened inside the bar (core's navbar,
|
|
69
|
+
the language list) open at its block end, on two rows as on one. Scoped,
|
|
70
|
+
so with two bars on a page each panel finds its own */
|
|
71
|
+
@supports (anchor-name: --luz-bar) {
|
|
72
|
+
.luz-landing-header {
|
|
73
|
+
anchor-name: --luz-bar;
|
|
74
|
+
anchor-scope: --luz-bar;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.luz-landing-header :where(luz-lang-switch) {
|
|
78
|
+
--luz-lang-switch-top: anchor(--luz-bar end, var(--luz-bar-h));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* ==========================================================================
|
|
83
|
+
LUZ Landing: hero.
|
|
84
|
+
The first block of a home or a landing page:
|
|
85
|
+
section.luz-landing-hero.o-grid.o-grid--split > __copy (+ __media). Core's
|
|
86
|
+
split grid gives two equal columns when each gets 24rem and one below:
|
|
87
|
+
intrinsic, so it stacks in a narrow column and with larger text. Copy
|
|
88
|
+
first in the source, so first in reading order in both directions.
|
|
89
|
+
--centered: one column, the copy centred above the media. __media--bleed,
|
|
90
|
+
in a centred hero: the media runs from edge to edge of the window.
|
|
91
|
+
The eyebrow, the title and the lead share their rules with the head of a
|
|
92
|
+
section (section.css).
|
|
93
|
+
========================================================================== */
|
|
94
|
+
|
|
95
|
+
.luz-landing-hero {
|
|
96
|
+
--luz-grid-min: 24rem;
|
|
97
|
+
|
|
98
|
+
gap: var(--luz-space-xl) var(--luz-space-2xl);
|
|
99
|
+
align-items: center;
|
|
100
|
+
padding-block-start: var(--luz-space-3xl);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Grid items: a long word or a wide child never widens the column */
|
|
104
|
+
.luz-landing-hero__copy,
|
|
105
|
+
.luz-landing-hero__media {
|
|
106
|
+
min-inline-size: 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* A word longer than the line (400 % text on a phone, WCAG 1.4.10) breaks
|
|
110
|
+
instead of widening the column: the centred copy is sized to its content,
|
|
111
|
+
so its narrowest width is its longest word */
|
|
112
|
+
.luz-landing-hero__copy {
|
|
113
|
+
overflow-wrap: anywhere;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.luz-landing-hero__eyebrow,
|
|
117
|
+
.luz-landing-section__eyebrow {
|
|
118
|
+
margin-block-end: var(--luz-space-sm);
|
|
119
|
+
font-family: var(--luz-font-mono);
|
|
120
|
+
font-size: var(--luz-text-xs);
|
|
121
|
+
font-weight: 500;
|
|
122
|
+
line-height: 1.5;
|
|
123
|
+
letter-spacing: 0.1em;
|
|
124
|
+
text-transform: uppercase;
|
|
125
|
+
color: var(--luz-text-secondary);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.luz-landing-hero__title,
|
|
129
|
+
.luz-landing-section__title {
|
|
130
|
+
font-family: var(--luz-font-heading);
|
|
131
|
+
font-size: var(--luz-text-4xl);
|
|
132
|
+
font-weight: 300;
|
|
133
|
+
line-height: 1.1;
|
|
134
|
+
letter-spacing: -0.02em;
|
|
135
|
+
text-wrap: balance;
|
|
136
|
+
color: var(--luz-text-primary);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* The mono has no Arabic letters; spacing between letters breaks the joins */
|
|
140
|
+
.luz-landing-hero__eyebrow:lang(ar),
|
|
141
|
+
.luz-landing-section__eyebrow:lang(ar) {
|
|
142
|
+
font-family: var(--luz-font-sans);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.luz-landing-hero__eyebrow:lang(ar),
|
|
146
|
+
.luz-landing-section__eyebrow:lang(ar),
|
|
147
|
+
.luz-landing-hero__title:lang(ar),
|
|
148
|
+
.luz-landing-section__title:lang(ar) {
|
|
149
|
+
letter-spacing: 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.luz-landing-hero__lead,
|
|
153
|
+
.luz-landing-section__lead {
|
|
154
|
+
max-inline-size: 70ch;
|
|
155
|
+
font-size: var(--luz-text-xl);
|
|
156
|
+
line-height: 1.4;
|
|
157
|
+
text-wrap: pretty;
|
|
158
|
+
color: var(--luz-text-secondary);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.luz-landing-hero__lead {
|
|
162
|
+
margin-block: var(--luz-space-md) var(--luz-space-lg);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* One column: core's split grid with a column as wide as the row */
|
|
166
|
+
.luz-landing-hero--centered {
|
|
167
|
+
--luz-grid-min: 100%;
|
|
168
|
+
|
|
169
|
+
text-align: center;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.luz-landing-hero--centered > .luz-landing-hero__copy {
|
|
173
|
+
justify-self: center;
|
|
174
|
+
max-inline-size: min(100%, 48rem);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.luz-landing-hero--centered .luz-landing-hero__lead {
|
|
178
|
+
margin-inline: auto;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.luz-landing-hero--centered .o-actions {
|
|
182
|
+
justify-content: center;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* The window's width without a viewport unit, which counts a visible
|
|
186
|
+
scrollbar and scrolls sideways: the root is the query container, and
|
|
187
|
+
the media's margins go out from the centre of the column to its edges */
|
|
188
|
+
:root:has(.luz-landing-hero__media--bleed) {
|
|
189
|
+
container-type: inline-size;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.luz-landing-hero__media--bleed {
|
|
193
|
+
margin-inline: calc(50% - 50cqi);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@media (max-width: 1023px) {
|
|
197
|
+
.luz-landing-hero {
|
|
198
|
+
padding-block-start: calc(var(--luz-space-xl) + var(--luz-space-xs));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.luz-landing-hero__title {
|
|
202
|
+
font-size: var(--luz-text-3xl);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.luz-landing-hero__lead {
|
|
206
|
+
font-size: var(--luz-text-lg);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@media (max-width: 640px) {
|
|
211
|
+
.luz-landing-hero__title {
|
|
212
|
+
font-size: var(--luz-text-2xl);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.luz-landing-hero__lead {
|
|
216
|
+
font-size: var(--luz-text-base);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* ==========================================================================
|
|
221
|
+
LUZ Landing: main.
|
|
222
|
+
The rhythm of the page: main.o-container.o-stack.luz-landing-main. Wide
|
|
223
|
+
room between the blocks and under the last one; none above the first,
|
|
224
|
+
as the hero brings its own. The landing's layer comes after core's
|
|
225
|
+
objects, so this gap wins over .o-stack's.
|
|
226
|
+
========================================================================== */
|
|
227
|
+
|
|
228
|
+
.luz-landing-main {
|
|
229
|
+
gap: var(--luz-space-3xl);
|
|
230
|
+
padding-block: 0 var(--luz-space-3xl);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* ==========================================================================
|
|
234
|
+
LUZ Landing: section.
|
|
235
|
+
A block of the page after the hero: section.o-stack.luz-landing-section,
|
|
236
|
+
its heading first. Add core's .luz-band for a tint from edge to edge.
|
|
237
|
+
The head: __eyebrow, __title and __lead share the rules of the hero's
|
|
238
|
+
(one selector list, in hero.css, so load it with this file); the title
|
|
239
|
+
is one step smaller.
|
|
240
|
+
========================================================================== */
|
|
241
|
+
|
|
242
|
+
.luz-landing-section {
|
|
243
|
+
gap: var(--luz-space-md);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.luz-landing-section__eyebrow {
|
|
247
|
+
margin-block-end: 0;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.luz-landing-section__title,
|
|
251
|
+
.luz-landing-stat__value {
|
|
252
|
+
font-size: var(--luz-text-3xl);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* A knob for the stressed word of a hero's or a section's title; unset,
|
|
256
|
+
the title's colour */
|
|
257
|
+
.luz-landing-hero__title em,
|
|
258
|
+
.luz-landing-section__title em {
|
|
259
|
+
color: var(--luz-landing-title-accent, inherit);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.luz-landing-section__lead {
|
|
263
|
+
font-size: var(--luz-text-lg);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
@media (max-width: 1023px) {
|
|
267
|
+
.luz-landing-section__title,
|
|
268
|
+
.luz-landing-stat__value {
|
|
269
|
+
font-size: var(--luz-text-2xl);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
@media (max-width: 640px) {
|
|
274
|
+
.luz-landing-section__title,
|
|
275
|
+
.luz-landing-stat__value {
|
|
276
|
+
font-size: var(--luz-text-xl);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.luz-landing-section__lead {
|
|
280
|
+
font-size: var(--luz-text-base);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* ==========================================================================
|
|
285
|
+
LUZ Landing: stat.
|
|
286
|
+
A figure and what it counts: div.luz-landing-stat > p.__value + p.__label,
|
|
287
|
+
alone or inside core's .luz-card. Tabular figures, so a row of stats
|
|
288
|
+
lines up digit under digit.
|
|
289
|
+
========================================================================== */
|
|
290
|
+
|
|
291
|
+
.luz-landing-stat {
|
|
292
|
+
display: grid;
|
|
293
|
+
gap: var(--luz-space-2xs);
|
|
294
|
+
min-inline-size: 0;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.luz-landing-stat > * {
|
|
298
|
+
margin: 0;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.luz-landing-stat__value {
|
|
302
|
+
font-family: var(--luz-font-heading);
|
|
303
|
+
font-weight: 300;
|
|
304
|
+
font-variant-numeric: tabular-nums;
|
|
305
|
+
line-height: 1.1;
|
|
306
|
+
overflow-wrap: anywhere;
|
|
307
|
+
color: var(--luz-text-primary);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.luz-landing-stat__label {
|
|
311
|
+
font-size: var(--luz-text-base);
|
|
312
|
+
color: var(--luz-text-secondary);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* ==========================================================================
|
|
316
|
+
LUZ Landing: footer.
|
|
317
|
+
footer.luz-landing-footer > div.o-container.o-container--inline.o-row: a
|
|
318
|
+
divider above, its items at the two ends of the row; at 768px and below
|
|
319
|
+
a column aligned to the start.
|
|
320
|
+
Or > div.o-container.o-container--inline.o-grid holding a __brand (the
|
|
321
|
+
name, a version, one line) and __col columns (nav > h2.__col-title + ul
|
|
322
|
+
of links, each a target of 24px or more): one under the other, side
|
|
323
|
+
by side from 768px, the brand twice as wide as a column.
|
|
324
|
+
========================================================================== */
|
|
325
|
+
|
|
326
|
+
.luz-landing-footer {
|
|
327
|
+
padding-block: var(--luz-space-lg) var(--luz-space-xl);
|
|
328
|
+
border-block-start: 1px solid var(--luz-divider);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.luz-landing-footer > .o-row {
|
|
332
|
+
justify-content: space-between;
|
|
333
|
+
gap: var(--luz-space-md);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* A column that does not wrap: a wrapping column nested in grids makes
|
|
337
|
+
Chromium's layout take tens of seconds */
|
|
338
|
+
@media (max-width: 768px) {
|
|
339
|
+
.luz-landing-footer > .o-row {
|
|
340
|
+
flex-flow: column nowrap;
|
|
341
|
+
align-items: flex-start;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.luz-landing-footer > .o-grid {
|
|
346
|
+
gap: var(--luz-space-lg);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
@media (min-width: 768px) {
|
|
350
|
+
.luz-landing-footer > .o-grid {
|
|
351
|
+
grid-template-columns: minmax(0, 2fr);
|
|
352
|
+
grid-auto-columns: minmax(0, 1fr);
|
|
353
|
+
grid-auto-flow: column;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.luz-landing-footer__brand,
|
|
358
|
+
.luz-landing-footer__col,
|
|
359
|
+
.luz-landing-footer__col :where(ul) {
|
|
360
|
+
display: grid;
|
|
361
|
+
align-content: start;
|
|
362
|
+
gap: var(--luz-space-xs);
|
|
363
|
+
margin: 0;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.luz-landing-footer__brand > *,
|
|
367
|
+
.luz-landing-footer__col-title {
|
|
368
|
+
margin: 0;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.luz-landing-footer__col-title {
|
|
372
|
+
font-family: var(--luz-font-sans);
|
|
373
|
+
font-size: var(--luz-text-sm);
|
|
374
|
+
font-weight: 600;
|
|
375
|
+
letter-spacing: 0;
|
|
376
|
+
color: var(--luz-text-primary);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.luz-landing-footer__col :where(ul) {
|
|
380
|
+
padding: 0;
|
|
381
|
+
list-style: none;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/* Each link is a target of 24px or more (WCAG 2.5.8): a box of its own,
|
|
385
|
+
as tall as a small control, the text centred in it */
|
|
386
|
+
.luz-landing-footer__col :where(a) {
|
|
387
|
+
display: inline-flex;
|
|
388
|
+
align-items: center;
|
|
389
|
+
min-block-size: var(--luz-control-sm);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* ==========================================================================
|
|
393
|
+
LUZ Landing: glow.
|
|
394
|
+
On the .o-page element: the brand's subtle tint at the top of the page,
|
|
395
|
+
over a fade from the page surface to the muted one. Decoration only: it
|
|
396
|
+
carries no meaning, and paper does not get it.
|
|
397
|
+
--luz-landing-glow-x: where along the top edge the tint sits, a physical
|
|
398
|
+
position (0% the left, 100% the right). Unset, the edge where reading
|
|
399
|
+
starts: the left in left-to-right text, the right in right-to-left.
|
|
400
|
+
========================================================================== */
|
|
401
|
+
|
|
402
|
+
.luz-landing-glow {
|
|
403
|
+
--luz-landing-glow-start: 100%;
|
|
404
|
+
|
|
405
|
+
background:
|
|
406
|
+
radial-gradient(circle at var(--luz-landing-glow-x, var(--luz-landing-glow-start)) 0%, var(--luz-brand-subtle), transparent 28%),
|
|
407
|
+
linear-gradient(180deg, var(--luz-surface-page) 0%, var(--luz-surface-muted) 100%);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.luz-landing-glow:dir(ltr) {
|
|
411
|
+
--luz-landing-glow-start: 0%;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
@media print {
|
|
415
|
+
.luz-landing-glow {
|
|
416
|
+
background: none;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer luz.tokens,luz.themes,luz.settings,luz.generic,luz.elements,luz.objects,luz.components,luz.utilities,luz.site,luz.landing,luz.cms,luz.app,luz.docs,luz.print;@layer luz.landing{.luz-landing-header{padding-block:var(--luz-space-2xs);border-block-end:1px solid var(--luz-divider);background:var(--luz-surface-page)}.luz-landing-header>.o-row{gap:var(--luz-space-xs) var(--luz-space-md)}.luz-landing-header__brand{display:inline-flex;align-items:center;gap:var(--luz-space-xs);min-block-size:var(--luz-control-lg);margin-inline-end:auto;color:var(--luz-text-primary);font-family:var(--luz-font-sans);font-size:var(--luz-text-base);font-weight:600;text-decoration:none}.luz-landing-header__actions{gap:var(--luz-space-xs)}.luz-landing-header :where(luz-lang-switch){--luz-lang-switch-top: var(--luz-bar-h)}@media(min-width:769px){.luz-landing-header>.o-row{column-gap:var(--luz-space-lg)}}@supports (anchor-name: --luz-bar){.luz-landing-header{anchor-name:--luz-bar;anchor-scope:--luz-bar}.luz-landing-header :where(luz-lang-switch){--luz-lang-switch-top: anchor(--luz-bar end, var(--luz-bar-h))}}.luz-landing-hero{--luz-grid-min: 24rem;gap:var(--luz-space-xl) var(--luz-space-2xl);align-items:center;padding-block-start:var(--luz-space-3xl)}.luz-landing-hero__copy,.luz-landing-hero__media{min-inline-size:0}.luz-landing-hero__copy{overflow-wrap:anywhere}.luz-landing-hero__eyebrow,.luz-landing-section__eyebrow{margin-block-end:var(--luz-space-sm);font-family:var(--luz-font-mono);font-size:var(--luz-text-xs);font-weight:500;line-height:1.5;letter-spacing:.1em;text-transform:uppercase;color:var(--luz-text-secondary)}.luz-landing-hero__title,.luz-landing-section__title{font-family:var(--luz-font-heading);font-size:var(--luz-text-4xl);font-weight:300;line-height:1.1;letter-spacing:-.02em;text-wrap:balance;color:var(--luz-text-primary)}.luz-landing-hero__eyebrow:lang(ar),.luz-landing-section__eyebrow:lang(ar){font-family:var(--luz-font-sans)}.luz-landing-hero__eyebrow:lang(ar),.luz-landing-section__eyebrow:lang(ar),.luz-landing-hero__title:lang(ar),.luz-landing-section__title:lang(ar){letter-spacing:0}.luz-landing-hero__lead,.luz-landing-section__lead{max-inline-size:70ch;font-size:var(--luz-text-xl);line-height:1.4;text-wrap:pretty;color:var(--luz-text-secondary)}.luz-landing-hero__lead{margin-block:var(--luz-space-md) var(--luz-space-lg)}.luz-landing-hero--centered{--luz-grid-min: 100%;text-align:center}.luz-landing-hero--centered>.luz-landing-hero__copy{justify-self:center;max-inline-size:min(100%,48rem)}.luz-landing-hero--centered .luz-landing-hero__lead{margin-inline:auto}.luz-landing-hero--centered .o-actions{justify-content:center}:root:has(.luz-landing-hero__media--bleed){container-type:inline-size}.luz-landing-hero__media--bleed{margin-inline:calc(50% - 50cqi)}@media(max-width:1023px){.luz-landing-hero{padding-block-start:calc(var(--luz-space-xl) + var(--luz-space-xs))}.luz-landing-hero__title{font-size:var(--luz-text-3xl)}.luz-landing-hero__lead{font-size:var(--luz-text-lg)}}@media(max-width:640px){.luz-landing-hero__title{font-size:var(--luz-text-2xl)}.luz-landing-hero__lead{font-size:var(--luz-text-base)}}.luz-landing-main{gap:var(--luz-space-3xl);padding-block:0 var(--luz-space-3xl)}.luz-landing-section{gap:var(--luz-space-md)}.luz-landing-section__eyebrow{margin-block-end:0}.luz-landing-section__title,.luz-landing-stat__value{font-size:var(--luz-text-3xl)}.luz-landing-hero__title em,.luz-landing-section__title em{color:var(--luz-landing-title-accent, inherit)}.luz-landing-section__lead{font-size:var(--luz-text-lg)}@media(max-width:1023px){.luz-landing-section__title,.luz-landing-stat__value{font-size:var(--luz-text-2xl)}}@media(max-width:640px){.luz-landing-section__title,.luz-landing-stat__value{font-size:var(--luz-text-xl)}.luz-landing-section__lead{font-size:var(--luz-text-base)}}.luz-landing-stat{display:grid;gap:var(--luz-space-2xs);min-inline-size:0}.luz-landing-stat>*{margin:0}.luz-landing-stat__value{font-family:var(--luz-font-heading);font-weight:300;font-variant-numeric:tabular-nums;line-height:1.1;overflow-wrap:anywhere;color:var(--luz-text-primary)}.luz-landing-stat__label{font-size:var(--luz-text-base);color:var(--luz-text-secondary)}.luz-landing-footer{padding-block:var(--luz-space-lg) var(--luz-space-xl);border-block-start:1px solid var(--luz-divider)}.luz-landing-footer>.o-row{justify-content:space-between;gap:var(--luz-space-md)}@media(max-width:768px){.luz-landing-footer>.o-row{flex-flow:column nowrap;align-items:flex-start}}.luz-landing-footer>.o-grid{gap:var(--luz-space-lg)}@media(min-width:768px){.luz-landing-footer>.o-grid{grid-template-columns:minmax(0,2fr);grid-auto-columns:minmax(0,1fr);grid-auto-flow:column}}.luz-landing-footer__brand,.luz-landing-footer__col,.luz-landing-footer__col :where(ul){display:grid;align-content:start;gap:var(--luz-space-xs);margin:0}.luz-landing-footer__brand>*,.luz-landing-footer__col-title{margin:0}.luz-landing-footer__col-title{font-family:var(--luz-font-sans);font-size:var(--luz-text-sm);font-weight:600;letter-spacing:0;color:var(--luz-text-primary)}.luz-landing-footer__col :where(ul){padding:0;list-style:none}.luz-landing-footer__col :where(a){display:inline-flex;align-items:center;min-block-size:var(--luz-control-sm)}.luz-landing-glow{--luz-landing-glow-start: 100%;background:radial-gradient(circle at var(--luz-landing-glow-x, var(--luz-landing-glow-start)) 0%,var(--luz-brand-subtle),transparent 28%),linear-gradient(180deg,var(--luz-surface-page) 0%,var(--luz-surface-muted) 100%)}.luz-landing-glow:dir(ltr){--luz-landing-glow-start: 0%}@media print{.luz-landing-glow{background:none}}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luz-ds/landing",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "LUZ Design System — the page structure of a landing page (header, hero, main, sections, footer, glow), built on @luz-ds/core",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
"./css": "./dist/landing.css",
|
|
9
|
+
"./css/min": "./dist/landing.min.css",
|
|
10
|
+
"./components/*": "./dist/components/*",
|
|
11
|
+
"./classes.json": "./dist/classes.json",
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/nandovejer/luz.git",
|
|
21
|
+
"directory": "packages/landing"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/nandovejer/luz#readme",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/nandovejer/luz/issues"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"design-system",
|
|
29
|
+
"css",
|
|
30
|
+
"landing-page",
|
|
31
|
+
"patterns",
|
|
32
|
+
"vanilla"
|
|
33
|
+
],
|
|
34
|
+
"sideEffects": [
|
|
35
|
+
"*.css"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@luz-ds/core": "^0.1.0",
|
|
42
|
+
"@luz-ds/site": "^0.1.0",
|
|
43
|
+
"@luz-ds/tokens": "^0.1.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependenciesMeta": {
|
|
46
|
+
"@luz-ds/site": {
|
|
47
|
+
"optional": true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@luz-ds/site": "0.1.0",
|
|
52
|
+
"@luz-ds/core": "0.1.0",
|
|
53
|
+
"@luz-ds/tokens": "0.1.0"
|
|
54
|
+
}
|
|
6
55
|
}
|