@fluid-theme/core 0.4.3 → 2.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/AGENTS.md +6 -29
- package/CHANGELOG.md +543 -2
- package/CLAUDE.md +193 -14
- package/GEMINI.md +6 -45
- package/README.md +17 -8
- package/assets/js/compare.js +77 -0
- package/assets/js/fit-text.js +103 -0
- package/assets/js/lightbox.js +153 -0
- package/assets/js/scroll-reveal.js +72 -0
- package/assets/js/toc-build.mjs +86 -0
- package/assets/js/toc.js +384 -0
- package/dist/fluid-1x.min.css +4 -0
- package/dist/fluid-fonts.min.css +2 -0
- package/dist/fluid-legacy-1x.css +3 -0
- package/dist/fluid-nav.min.css +3 -0
- package/dist/fluid-toc.min.css +3 -0
- package/dist/fluid-zero.min.css +3 -0
- package/dist/fluid.min.css +3 -2
- package/dist/fonts/OFL-newsreader.txt +93 -0
- package/dist/fonts/OFL-schibsted-grotesk.txt +93 -0
- package/dist/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
- package/dist/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
- package/dist/fonts/schibsted-grotesk-latin-wght-italic.woff2 +0 -0
- package/dist/fonts/schibsted-grotesk-latin-wght-normal.woff2 +0 -0
- package/fluid-agent-kit/README.md +1 -0
- package/fluid-agent-kit/skills/accessibility.md +3 -1
- package/fluid-agent-kit/skills/css-conventions.md +22 -5
- package/fluid-agent-kit/skills/image-optimization.md +2 -0
- package/fluid-agent-kit/skills/preset-composition.md +108 -0
- package/package.json +29 -3
- package/src/animations/scroll-reveal.css +75 -193
- package/src/components/accordion.css +6 -47
- package/src/components/alert.css +47 -88
- package/src/components/avatar.css +4 -20
- package/src/components/badge.css +25 -48
- package/src/components/button.css +69 -175
- package/src/components/card.css +146 -481
- package/src/components/chip.css +46 -12
- package/src/components/compare.css +234 -0
- package/src/components/dropdown.css +10 -67
- package/src/components/empty-state.css +4 -0
- package/src/components/form.css +113 -81
- package/src/components/gallery.css +252 -0
- package/src/components/hero.css +203 -88
- package/src/components/indicator.css +23 -117
- package/src/components/loading.css +7 -29
- package/src/components/modal.css +12 -65
- package/src/components/nav-modes.css +261 -0
- package/src/components/nav.css +324 -392
- package/src/components/search-input.css +4 -2
- package/src/components/step-indicator.css +26 -27
- package/src/components/table.css +64 -171
- package/src/components/toc.css +254 -0
- package/src/components/tooltip.css +5 -46
- package/src/core/base.css +393 -547
- package/src/core/reset.css +17 -5
- package/src/core/tokens.css +426 -2276
- package/src/fluid.css +258 -17
- package/src/fonts/OFL-newsreader.txt +93 -0
- package/src/fonts/OFL-schibsted-grotesk.txt +93 -0
- package/src/fonts/fluid-fonts.css +55 -0
- package/src/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
- package/src/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
- package/src/fonts/schibsted-grotesk-latin-wght-italic.woff2 +0 -0
- package/src/fonts/schibsted-grotesk-latin-wght-normal.woff2 +0 -0
- package/src/layouts/positioning.css +6 -3
- package/src/legacy-1x.css +61 -0
- package/src/sections/cta.css +33 -101
- package/src/sections/features.css +42 -219
- package/src/sections/footer.css +53 -134
- package/src/sections/stats.css +40 -153
- package/src/sections/team.css +24 -113
- package/src/sections/testimonials.css +34 -148
- package/src/zero/base.css +166 -0
- package/src/zero/tokens.css +64 -0
- package/src/zero.css +20 -0
- package/src/components/scroll-progress.css +0 -104
- package/src/components/settings-panel.css +0 -603
- package/src/components/themed-images.css +0 -229
- package/src/components/version-badge.css +0 -70
package/src/sections/team.css
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* </header>
|
|
14
14
|
* <div class="team__grid">
|
|
15
15
|
* <article class="team-member">
|
|
16
|
-
* <img class="avatar
|
|
16
|
+
* <img class="avatar" data-size="xl" src="..." alt="Jane Doe">
|
|
17
17
|
* <h3 class="team-member__name">Jane Doe</h3>
|
|
18
18
|
* <p class="team-member__role">CEO & Co-founder</p>
|
|
19
19
|
* <p class="team-member__bio">Short bio about Jane.</p>
|
|
@@ -28,154 +28,65 @@
|
|
|
28
28
|
|
|
29
29
|
@layer components {
|
|
30
30
|
|
|
31
|
-
/*
|
|
32
|
-
|
|
33
|
-
======================================== */
|
|
31
|
+
/* The band's padding and edges, and the header (a section head), are in
|
|
32
|
+
src/fluid.css (layouts). */
|
|
34
33
|
|
|
35
|
-
.
|
|
36
|
-
padding-block: var(--space-16);
|
|
37
|
-
padding-inline: var(--space-5);
|
|
38
|
-
max-inline-size: var(--container-xl);
|
|
39
|
-
margin-inline: auto;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.team__header {
|
|
43
|
-
text-align: center;
|
|
44
|
-
max-inline-size: var(--container-md);
|
|
45
|
-
margin-inline: auto;
|
|
46
|
-
margin-block-end: var(--space-12);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.team__header h2 {
|
|
50
|
-
font-size: var(--font-size-3xl);
|
|
51
|
-
font-weight: var(--weight-bold);
|
|
52
|
-
color: var(--color-text);
|
|
53
|
-
margin-block-end: var(--space-3);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.team__header p {
|
|
57
|
-
font-size: var(--font-size-lg);
|
|
58
|
-
color: var(--color-text-muted);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
/* ========================================
|
|
63
|
-
TEAM GRID
|
|
64
|
-
======================================== */
|
|
34
|
+
.team__header p:not(.eyebrow, .lede) { color: var(--color-text-muted); } /* the label voice owns the eyebrow's colour */
|
|
65
35
|
|
|
66
36
|
.team__grid {
|
|
67
37
|
display: grid;
|
|
68
|
-
gap: var(--space-
|
|
69
|
-
grid-template-columns: repeat(
|
|
70
|
-
auto-fit,
|
|
71
|
-
minmax(min(100%, 14rem), 1fr)
|
|
72
|
-
);
|
|
38
|
+
gap: var(--space-l) var(--space-m);
|
|
39
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
|
|
73
40
|
}
|
|
74
41
|
|
|
75
|
-
|
|
76
|
-
/* ========================================
|
|
77
|
-
TEAM MEMBER CARD
|
|
78
|
-
======================================== */
|
|
79
|
-
|
|
42
|
+
/* A member is open, like a card: avatar or photo, name, role, bio. */
|
|
80
43
|
.team-member {
|
|
81
|
-
--_member-bg: var(--color-surface);
|
|
82
|
-
--_member-border: var(--color-border-subtle);
|
|
83
|
-
--_member-radius: var(--radius-xl);
|
|
84
|
-
--_member-padding: var(--space-6);
|
|
85
|
-
|
|
86
44
|
display: flex;
|
|
87
45
|
flex-direction: column;
|
|
88
|
-
|
|
89
|
-
text-align: center;
|
|
90
|
-
gap: var(--space-2);
|
|
91
|
-
padding: var(--_member-padding);
|
|
92
|
-
background-color: var(--_member-bg);
|
|
93
|
-
border: var(--border-width) solid var(--_member-border);
|
|
94
|
-
border-radius: var(--_member-radius);
|
|
95
|
-
transition:
|
|
96
|
-
box-shadow var(--duration-normal) var(--ease-fluid),
|
|
97
|
-
transform var(--duration-normal) var(--ease-settle);
|
|
46
|
+
gap: var(--space-xs);
|
|
98
47
|
}
|
|
99
48
|
|
|
100
|
-
.team-member:
|
|
101
|
-
box-shadow: var(--shadow-md);
|
|
102
|
-
transform: translateY(-2px);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.team-member .avatar {
|
|
106
|
-
margin-block-end: var(--space-2);
|
|
107
|
-
}
|
|
49
|
+
.team-member .avatar { margin-block-end: var(--space-xs); }
|
|
108
50
|
|
|
109
51
|
.team-member__name {
|
|
110
|
-
font-
|
|
111
|
-
font-
|
|
112
|
-
|
|
52
|
+
font-family: var(--font-heading);
|
|
53
|
+
font-size: var(--step-1);
|
|
54
|
+
font-weight: calc(500 + var(--_dark-weight));
|
|
55
|
+
line-height: var(--leading-heading);
|
|
113
56
|
margin: 0;
|
|
114
57
|
}
|
|
115
58
|
|
|
116
59
|
.team-member__role {
|
|
117
|
-
font-size: var(--
|
|
118
|
-
color: var(--
|
|
60
|
+
font-size: var(--step--1);
|
|
61
|
+
color: var(--color-text-muted);
|
|
119
62
|
margin: 0;
|
|
120
63
|
}
|
|
121
64
|
|
|
122
65
|
.team-member__bio {
|
|
123
|
-
font-size: var(--font-size-sm);
|
|
124
66
|
color: var(--color-text-muted);
|
|
125
|
-
|
|
126
|
-
margin: 0;
|
|
127
|
-
margin-block-start: var(--space-2);
|
|
67
|
+
margin: 0; margin-block-start: var(--space-xs);
|
|
128
68
|
}
|
|
129
69
|
|
|
130
|
-
|
|
131
|
-
/* ========================================
|
|
132
|
-
SOCIAL LINKS
|
|
133
|
-
======================================== */
|
|
134
|
-
|
|
135
70
|
.team-member__social {
|
|
136
71
|
display: flex;
|
|
137
|
-
gap: var(--space-
|
|
138
|
-
margin-block-start: var(--space-
|
|
72
|
+
gap: var(--space-1);
|
|
73
|
+
margin-block-start: var(--space-xs);
|
|
74
|
+
margin-inline-start: -0.75rem;
|
|
139
75
|
}
|
|
140
76
|
|
|
141
77
|
.team-member__social a {
|
|
142
78
|
display: flex;
|
|
143
79
|
align-items: center;
|
|
144
80
|
justify-content: center;
|
|
145
|
-
inline-size:
|
|
146
|
-
block-size:
|
|
147
|
-
border-radius: var(--radius-full);
|
|
81
|
+
inline-size: 2.75rem;
|
|
82
|
+
block-size: 2.75rem;
|
|
148
83
|
color: var(--color-text-muted);
|
|
149
|
-
transition: color var(--duration-fast) var(--ease-fluid);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.team-member__social a:hover {
|
|
153
|
-
color: var(--accent);
|
|
154
84
|
}
|
|
155
85
|
|
|
156
|
-
.team-member__social a:
|
|
157
|
-
outline: 2px solid var(--color-focus);
|
|
158
|
-
outline-offset: 2px;
|
|
159
|
-
}
|
|
86
|
+
.team-member__social a:hover { color: var(--color-text); }
|
|
160
87
|
|
|
161
88
|
.team-member__social svg {
|
|
162
|
-
inline-size:
|
|
163
|
-
block-size:
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
/* ========================================
|
|
168
|
-
ACCESSIBILITY
|
|
169
|
-
======================================== */
|
|
170
|
-
|
|
171
|
-
@media (prefers-reduced-motion: reduce) {
|
|
172
|
-
.team-member,
|
|
173
|
-
.team-member__social a {
|
|
174
|
-
transition: none;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
.team-member:hover {
|
|
178
|
-
transform: none;
|
|
179
|
-
}
|
|
89
|
+
inline-size: 1.125rem;
|
|
90
|
+
block-size: 1.125rem;
|
|
180
91
|
}
|
|
181
92
|
}
|
|
@@ -48,204 +48,90 @@
|
|
|
48
48
|
|
|
49
49
|
@layer components {
|
|
50
50
|
|
|
51
|
-
/*
|
|
52
|
-
|
|
53
|
-
======================================== */
|
|
54
|
-
|
|
55
|
-
.testimonials {
|
|
56
|
-
padding-block: var(--space-16);
|
|
57
|
-
padding-inline: var(--space-5);
|
|
58
|
-
max-inline-size: var(--container-xl);
|
|
59
|
-
margin-inline: auto;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.testimonials__header {
|
|
63
|
-
text-align: center;
|
|
64
|
-
max-inline-size: var(--container-md);
|
|
65
|
-
margin-inline: auto;
|
|
66
|
-
margin-block-end: var(--space-12);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.testimonials__header h2 {
|
|
70
|
-
font-size: var(--font-size-3xl);
|
|
71
|
-
font-weight: var(--weight-bold);
|
|
72
|
-
color: var(--color-text);
|
|
73
|
-
margin-block-end: var(--space-3);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.testimonials__header p {
|
|
77
|
-
font-size: var(--font-size-lg);
|
|
78
|
-
color: var(--color-text-muted);
|
|
79
|
-
}
|
|
51
|
+
/* The band's padding and edges, and the header (a section head), are in
|
|
52
|
+
src/fluid.css (layouts). */
|
|
80
53
|
|
|
54
|
+
.testimonials__header p:not(.eyebrow, .lede) { color: var(--color-text-muted); } /* the label voice owns the eyebrow's colour */
|
|
81
55
|
|
|
82
|
-
/*
|
|
83
|
-
SINGLE CENTERED (default)
|
|
84
|
-
Large featured testimonial
|
|
85
|
-
======================================== */
|
|
86
|
-
|
|
56
|
+
/* A testimonial is a serif quote and a label-voice attribution. No box. */
|
|
87
57
|
.testimonial {
|
|
88
|
-
--_testi-bg: var(--color-surface);
|
|
89
|
-
--_testi-border: var(--color-border-subtle);
|
|
90
|
-
--_testi-padding: var(--space-8);
|
|
91
|
-
--_testi-radius: var(--radius-xl);
|
|
92
|
-
|
|
93
58
|
display: flex;
|
|
94
59
|
flex-direction: column;
|
|
95
|
-
|
|
96
|
-
gap: var(--space-6);
|
|
97
|
-
padding: var(--_testi-padding);
|
|
98
|
-
background-color: var(--_testi-bg);
|
|
99
|
-
border: var(--border-width) solid var(--_testi-border);
|
|
100
|
-
border-radius: var(--_testi-radius);
|
|
60
|
+
gap: var(--space-m);
|
|
101
61
|
margin: 0;
|
|
102
|
-
text-align: center;
|
|
103
|
-
position: relative;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/* Decorative quote mark */
|
|
107
|
-
.testimonial::before {
|
|
108
|
-
content: "\201C";
|
|
109
|
-
position: absolute;
|
|
110
|
-
inset-block-start: var(--space-4);
|
|
111
|
-
inset-inline-start: var(--space-6);
|
|
112
|
-
font-size: var(--font-size-5xl);
|
|
113
|
-
line-height: 1;
|
|
114
|
-
color: color-mix(in oklch, var(--accent) 25%, transparent);
|
|
115
|
-
font-family: var(--font-serif, Georgia, serif);
|
|
116
|
-
pointer-events: none;
|
|
117
62
|
}
|
|
118
63
|
|
|
119
64
|
.testimonial__quote {
|
|
120
65
|
margin: 0;
|
|
121
66
|
padding: 0;
|
|
122
|
-
border:
|
|
123
|
-
|
|
67
|
+
border: 0;
|
|
68
|
+
font-style: normal;
|
|
124
69
|
}
|
|
125
70
|
|
|
126
71
|
.testimonial__quote p {
|
|
127
|
-
font-
|
|
128
|
-
font-
|
|
129
|
-
|
|
130
|
-
|
|
72
|
+
font-family: var(--font-heading);
|
|
73
|
+
font-size: var(--step-2);
|
|
74
|
+
font-weight: calc(var(--weight-light) + var(--_dark-weight));
|
|
75
|
+
line-height: 1.3;
|
|
76
|
+
letter-spacing: var(--tracking-heading);
|
|
77
|
+
text-wrap: balance;
|
|
78
|
+
max-inline-size: 32em;
|
|
131
79
|
margin: 0;
|
|
132
80
|
}
|
|
133
81
|
|
|
82
|
+
.testimonial__quote p::before { content: "\201C"; }
|
|
83
|
+
.testimonial__quote p::after { content: "\201D"; }
|
|
84
|
+
|
|
134
85
|
.testimonial__author {
|
|
135
86
|
display: flex;
|
|
136
87
|
align-items: center;
|
|
137
|
-
gap: var(--space-
|
|
88
|
+
gap: var(--space-s);
|
|
138
89
|
}
|
|
139
90
|
|
|
140
|
-
.testimonial__author .avatar {
|
|
141
|
-
flex-shrink: 0;
|
|
142
|
-
}
|
|
91
|
+
.testimonial__author .avatar { flex-shrink: 0; }
|
|
143
92
|
|
|
144
93
|
.testimonial__name {
|
|
145
94
|
display: block;
|
|
146
95
|
font-style: normal;
|
|
147
|
-
font-weight:
|
|
148
|
-
|
|
149
|
-
font-size: var(--font-size-sm);
|
|
96
|
+
font-weight: 600;
|
|
97
|
+
font-size: var(--step--1);
|
|
150
98
|
}
|
|
151
99
|
|
|
152
100
|
.testimonial__role {
|
|
153
101
|
display: block;
|
|
154
|
-
font-size: var(--
|
|
102
|
+
font-size: var(--step--1);
|
|
155
103
|
color: var(--color-text-muted);
|
|
156
104
|
}
|
|
157
105
|
|
|
158
|
-
/*
|
|
159
|
-
.testimonials:not([data-type]) .testimonial {
|
|
160
|
-
max-inline-size: var(--container-md);
|
|
161
|
-
margin-inline: auto;
|
|
162
|
-
padding: var(--space-10);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.testimonials:not([data-type]) .testimonial__quote p {
|
|
166
|
-
font-size: var(--font-size-xl);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
/* ========================================
|
|
171
|
-
GRID
|
|
172
|
-
Multiple testimonials in card grid
|
|
173
|
-
======================================== */
|
|
174
|
-
|
|
106
|
+
/* Grid: smaller quotes under ink hairlines, like cards. */
|
|
175
107
|
.testimonials__grid {
|
|
176
108
|
display: grid;
|
|
177
|
-
gap: var(--space-
|
|
178
|
-
grid-template-columns: repeat(
|
|
179
|
-
auto-fit,
|
|
180
|
-
minmax(min(100%, 18rem), 1fr)
|
|
181
|
-
);
|
|
109
|
+
gap: var(--space-l) var(--space-m);
|
|
110
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
|
|
182
111
|
}
|
|
183
112
|
|
|
184
113
|
.testimonials[data-type="grid"] .testimonial {
|
|
185
|
-
|
|
186
|
-
|
|
114
|
+
padding-block-start: var(--space-s);
|
|
115
|
+
border-block-start-color: var(--color-border-strong);
|
|
187
116
|
}
|
|
188
117
|
|
|
189
|
-
.testimonials[data-type="grid"] .
|
|
190
|
-
font-size: var(--font-size-4xl);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.testimonials[data-type="grid"] .testimonial__quote p {
|
|
194
|
-
font-size: var(--font-size-base);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
/* ========================================
|
|
199
|
-
LOGO WALL
|
|
200
|
-
Client/partner logos in a responsive row
|
|
201
|
-
======================================== */
|
|
118
|
+
.testimonials[data-type="grid"] .testimonial__quote p { font-size: var(--step-1); }
|
|
202
119
|
|
|
120
|
+
/* Logo wall */
|
|
203
121
|
.testimonials__logos {
|
|
204
122
|
display: flex;
|
|
205
123
|
flex-wrap: wrap;
|
|
206
|
-
justify-content: center;
|
|
207
124
|
align-items: center;
|
|
208
|
-
gap: var(--space-
|
|
125
|
+
gap: var(--space-l);
|
|
209
126
|
}
|
|
210
127
|
|
|
211
|
-
.testimonials__logos img,
|
|
212
|
-
.testimonials__logos svg {
|
|
128
|
+
.testimonials__logos :is(img, svg) {
|
|
213
129
|
block-size: 2.5rem;
|
|
214
130
|
inline-size: auto;
|
|
215
131
|
object-fit: contain;
|
|
216
|
-
opacity: 0.
|
|
217
|
-
|
|
218
|
-
transition:
|
|
219
|
-
opacity var(--duration-normal) var(--ease-fluid),
|
|
220
|
-
filter var(--duration-normal) var(--ease-fluid);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
.testimonials__logos img:hover,
|
|
224
|
-
.testimonials__logos svg:hover {
|
|
225
|
-
opacity: 1;
|
|
226
|
-
filter: grayscale(0%);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.testimonials[data-type="logos"] .testimonials__header {
|
|
230
|
-
margin-block-end: var(--space-8);
|
|
132
|
+
opacity: 0.7;
|
|
133
|
+
transition: opacity var(--duration-fast) var(--ease-fluid);
|
|
231
134
|
}
|
|
232
135
|
|
|
233
|
-
.
|
|
234
|
-
font-size: var(--font-size-sm);
|
|
235
|
-
text-transform: uppercase;
|
|
236
|
-
letter-spacing: var(--tracking-wider);
|
|
237
|
-
color: var(--color-text-muted);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
/* ========================================
|
|
242
|
-
ACCESSIBILITY
|
|
243
|
-
======================================== */
|
|
244
|
-
|
|
245
|
-
@media (prefers-reduced-motion: reduce) {
|
|
246
|
-
.testimonials__logos img,
|
|
247
|
-
.testimonials__logos svg {
|
|
248
|
-
transition: none;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
136
|
+
.testimonials__logos :is(img, svg):hover { opacity: 1; }
|
|
251
137
|
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluid Zero - base
|
|
3
|
+
* @layer base
|
|
4
|
+
*
|
|
5
|
+
* Native elements only. Every selector is :where(), so any later rule wins.
|
|
6
|
+
* The reset zeroes margins; the flow below puts them back, once.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
@layer base {
|
|
10
|
+
:where(:root) {
|
|
11
|
+
accent-color: var(--accent);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:where(body) {
|
|
15
|
+
padding-inline: calc(var(--space-gutter) / 2);
|
|
16
|
+
font-family: var(--font-body);
|
|
17
|
+
font-size: clamp(1rem, 0.95rem + 0.25vi, 1.125rem);
|
|
18
|
+
line-height: 1.6;
|
|
19
|
+
color: var(--color-text);
|
|
20
|
+
background-color: var(--color-background);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Flow: space after each block; more above a heading than below it. */
|
|
24
|
+
:where(p, ul, ol, dl, blockquote, pre, figure, table, hr, form, fieldset, details, address, h1, h2, h3, h4, h5, h6) {
|
|
25
|
+
margin-block: 0 1em;
|
|
26
|
+
}
|
|
27
|
+
:where(* + h1, * + h2, * + h3, * + h4, * + h5, * + h6) {
|
|
28
|
+
margin-block-start: 1.75em;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:where(h1, h2, h3, h4, h5, h6) {
|
|
32
|
+
font-family: var(--font-heading);
|
|
33
|
+
font-size: 1em;
|
|
34
|
+
font-weight: 700;
|
|
35
|
+
line-height: 1.15;
|
|
36
|
+
margin-block-end: 0.5em;
|
|
37
|
+
}
|
|
38
|
+
:where(h1) { font-size: clamp(2rem, 1.6667rem + 1.4815vi, 3rem); } /* 32 → 48 */
|
|
39
|
+
:where(h2) { font-size: clamp(1.5rem, 1.3333rem + 0.7407vi, 2rem); } /* 24 → 32 */
|
|
40
|
+
:where(h3) { font-size: clamp(1.25rem, 1.1667rem + 0.3704vi, 1.5rem); } /* 20 → 24 */
|
|
41
|
+
|
|
42
|
+
:where(p, li, dd, blockquote, figcaption) {
|
|
43
|
+
max-inline-size: var(--measure);
|
|
44
|
+
}
|
|
45
|
+
:where(dt) { font-weight: 600; }
|
|
46
|
+
:where(dd) { margin-inline-start: 1.5em; }
|
|
47
|
+
|
|
48
|
+
:where(a) {
|
|
49
|
+
color: var(--accent-ink);
|
|
50
|
+
text-decoration: underline;
|
|
51
|
+
text-decoration-thickness: 0.06em;
|
|
52
|
+
}
|
|
53
|
+
:where(a:hover) { text-decoration-thickness: 0.12em; }
|
|
54
|
+
|
|
55
|
+
:where(blockquote) {
|
|
56
|
+
padding-inline-start: 1em;
|
|
57
|
+
border-inline-start: 3px solid var(--color-border-strong);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:where(code, kbd, samp, pre) {
|
|
61
|
+
font-family: var(--font-mono);
|
|
62
|
+
font-size: 0.9em;
|
|
63
|
+
}
|
|
64
|
+
:where(:not(pre) > code, pre) {
|
|
65
|
+
background-color: var(--color-surface);
|
|
66
|
+
}
|
|
67
|
+
:where(:not(pre) > code) { padding: 0.1em 0.3em; }
|
|
68
|
+
:where(pre) {
|
|
69
|
+
padding: 1em;
|
|
70
|
+
overflow-x: auto;
|
|
71
|
+
border: var(--border-width) solid var(--color-border);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
:where(hr) {
|
|
75
|
+
border: 0;
|
|
76
|
+
border-block-start: var(--border-width) solid var(--color-border);
|
|
77
|
+
margin-block: 2em;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
:where(figure img) { inline-size: 100%; }
|
|
81
|
+
:where(figcaption) {
|
|
82
|
+
margin-block-start: 0.5em;
|
|
83
|
+
font-size: 0.875em;
|
|
84
|
+
color: var(--color-text-muted);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:where(table) { inline-size: 100%; }
|
|
88
|
+
:where(th) { text-align: start; }
|
|
89
|
+
:where(th, td) {
|
|
90
|
+
padding: 0.5em 0.75em 0.5em 0;
|
|
91
|
+
border-block-end: var(--border-width) solid var(--color-border);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
:where(legend, label) { font-weight: 600; }
|
|
95
|
+
|
|
96
|
+
/* Fields: every text-like input, select and textarea. */
|
|
97
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="submit"], [type="reset"], [type="button"], [type="image"]), select, textarea) {
|
|
98
|
+
min-block-size: 2.75rem;
|
|
99
|
+
padding: 0.5em 0.75em;
|
|
100
|
+
border: var(--border-width) solid var(--color-border-strong);
|
|
101
|
+
border-radius: var(--radius-control);
|
|
102
|
+
background-color: var(--color-background);
|
|
103
|
+
}
|
|
104
|
+
:where(input, select, textarea):focus-visible { outline-offset: 1px; }
|
|
105
|
+
:where(input, select, textarea):user-invalid { border-color: var(--color-error); }
|
|
106
|
+
:where(input:is([type="checkbox"], [type="radio"])) {
|
|
107
|
+
inline-size: 1.25em;
|
|
108
|
+
block-size: 1.25em;
|
|
109
|
+
vertical-align: -0.25em;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
:where(button, [type="submit"], [type="reset"], [type="button"]) {
|
|
113
|
+
min-block-size: 2.75rem;
|
|
114
|
+
padding: 0.5em 1.25em;
|
|
115
|
+
border: var(--border-width) solid var(--accent);
|
|
116
|
+
border-radius: var(--radius-control);
|
|
117
|
+
background-color: var(--accent);
|
|
118
|
+
color: var(--on-accent);
|
|
119
|
+
font-weight: 600;
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
:where(:disabled) {
|
|
124
|
+
opacity: 0.5;
|
|
125
|
+
cursor: not-allowed;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
:where([data-bg="tinted"]) {
|
|
129
|
+
padding: 1.5rem;
|
|
130
|
+
background-color: var(--color-surface);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
:where(.sr-only) {
|
|
134
|
+
position: absolute;
|
|
135
|
+
inline-size: 1px;
|
|
136
|
+
block-size: 1px;
|
|
137
|
+
overflow: hidden;
|
|
138
|
+
clip-path: inset(50%);
|
|
139
|
+
white-space: nowrap;
|
|
140
|
+
}
|
|
141
|
+
:where(.skip-link) {
|
|
142
|
+
position: absolute;
|
|
143
|
+
inset-block-start: 0.5rem;
|
|
144
|
+
inset-inline-start: 0.5rem;
|
|
145
|
+
padding: 0.5em 1em;
|
|
146
|
+
background-color: var(--color-background);
|
|
147
|
+
translate: 0 -200%;
|
|
148
|
+
}
|
|
149
|
+
:where(.skip-link:focus) { translate: none; }
|
|
150
|
+
|
|
151
|
+
/* Dialog and fieldset: the reset strips their edge, so give it back. */
|
|
152
|
+
:where(dialog, fieldset) {
|
|
153
|
+
border: var(--border-width) solid var(--color-border-strong);
|
|
154
|
+
padding: 1em;
|
|
155
|
+
}
|
|
156
|
+
:where(dialog) {
|
|
157
|
+
color: var(--color-text);
|
|
158
|
+
background-color: var(--color-background);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* No !important: an important rule in this early layer would beat every
|
|
162
|
+
child theme. Browsers drop backgrounds in print on their own. */
|
|
163
|
+
@media print {
|
|
164
|
+
:where(*) { color: #000; }
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluid Zero - tokens
|
|
3
|
+
* @layer tokens
|
|
4
|
+
*
|
|
5
|
+
* KNOBS share the base's names (set them on :root in @layer themes).
|
|
6
|
+
* ROLES share the base's names too, through light-dark(): the OS decides,
|
|
7
|
+
* <html data-theme="light|dark"> overrides.
|
|
8
|
+
*
|
|
9
|
+
* The plain values first are the floor for browsers without relative colour
|
|
10
|
+
* (Safari before 18); the @supports block derives the same roles from
|
|
11
|
+
* --accent and --neutral-tint, as the base does.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
@layer tokens {
|
|
15
|
+
:root {
|
|
16
|
+
color-scheme: light dark;
|
|
17
|
+
|
|
18
|
+
/* KNOBS */
|
|
19
|
+
--accent: oklch(42% 0.15 22);
|
|
20
|
+
--neutral-tint: oklch(50% 0.01 75);
|
|
21
|
+
--font-heading: system-ui, sans-serif;
|
|
22
|
+
--font-body: system-ui, sans-serif;
|
|
23
|
+
--font-mono: ui-monospace, monospace;
|
|
24
|
+
--font-serif: ui-serif, Georgia, serif; /* for a site that wants it */
|
|
25
|
+
--measure: 66ch;
|
|
26
|
+
--space-gutter: clamp(2rem, 1rem + 5vi, 5rem); /* both sides together, as in core: 16 → 40px a side */
|
|
27
|
+
--radius-control: 0.25rem;
|
|
28
|
+
--border-width: 1px;
|
|
29
|
+
|
|
30
|
+
/* ROLES: the floor */
|
|
31
|
+
--on-accent: #fff;
|
|
32
|
+
--accent-ink: light-dark(var(--accent), color-mix(in oklch, var(--accent) 40%, #fff));
|
|
33
|
+
--color-text: light-dark(oklch(17% 0.01 75), oklch(93% 0.01 75));
|
|
34
|
+
--color-text-muted: light-dark(oklch(44% 0.01 75), oklch(74% 0.01 75));
|
|
35
|
+
--color-background: light-dark(oklch(99% 0.0075 75), oklch(14.5% 0.01 75));
|
|
36
|
+
--color-surface: light-dark(oklch(95.5% 0.01 75), oklch(19% 0.01 75));
|
|
37
|
+
--color-border: light-dark(oklch(86% 0.01 75), oklch(30% 0.01 75));
|
|
38
|
+
--color-border-strong: var(--color-text);
|
|
39
|
+
--color-error: light-dark(oklch(48% 0.17 25), oklch(76% 0.13 25));
|
|
40
|
+
--color-focus: var(--accent-ink);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@supports (color: oklch(from red l c h)) {
|
|
44
|
+
:root {
|
|
45
|
+
--on-accent: oklch(from var(--accent) clamp(0, (0.575 - l) * 1000, 1) 0 0);
|
|
46
|
+
--accent-ink: light-dark(oklch(from var(--accent) min(l, 0.45) c h), oklch(from var(--accent) max(l, 0.76) c h));
|
|
47
|
+
--color-text: light-dark(oklch(from var(--neutral-tint) 0.17 c h), oklch(from var(--neutral-tint) 0.93 c h));
|
|
48
|
+
--color-text-muted: light-dark(oklch(from var(--neutral-tint) 0.44 c h), oklch(from var(--neutral-tint) 0.74 c h));
|
|
49
|
+
--color-background: light-dark(oklch(from var(--neutral-tint) 0.99 calc(c * 0.75) h), oklch(from var(--neutral-tint) 0.145 c h));
|
|
50
|
+
--color-surface: light-dark(oklch(from var(--neutral-tint) 0.955 c h), oklch(from var(--neutral-tint) 0.19 c h));
|
|
51
|
+
--color-border: light-dark(oklch(from var(--neutral-tint) 0.86 c h), oklch(from var(--neutral-tint) 0.30 c h));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
:root[data-theme="light"] { color-scheme: light; }
|
|
56
|
+
:root[data-theme="dark"] { color-scheme: dark; }
|
|
57
|
+
|
|
58
|
+
@media (prefers-contrast: more) {
|
|
59
|
+
:root {
|
|
60
|
+
--color-text-muted: var(--color-text);
|
|
61
|
+
--color-border: var(--color-border-strong);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
package/src/zero.css
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluid Zero: the tiny alternate base (dist/fluid-zero.min.css).
|
|
3
|
+
*
|
|
4
|
+
* A modern cross-browser reset, system fonts, and the least CSS a readable,
|
|
5
|
+
* accessible page needs. For a utility page, an admin screen, or a site that
|
|
6
|
+
* builds its own look from nothing. It is NOT the default base: that is
|
|
7
|
+
* fluid.css.
|
|
8
|
+
*
|
|
9
|
+
* Same layer order and the same knob and role names as the base, so a child
|
|
10
|
+
* theme in @layer themes works on either: the knobs both define take effect
|
|
11
|
+
* on both; component rules simply have nothing to style here.
|
|
12
|
+
* No components, sections, content grid, web fonts or JS.
|
|
13
|
+
* Budget: 4,096 B gzip (build-css.mjs fails above it).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
@layer reset, tokens, base, layouts, components, themes, utilities;
|
|
17
|
+
|
|
18
|
+
@import "./core/reset.css";
|
|
19
|
+
@import "./zero/tokens.css";
|
|
20
|
+
@import "./zero/base.css";
|