swatchkit 1.1.0 → 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/build.js +82 -90
- package/package.json +2 -2
- package/src/blueprints/colors.json +11 -0
- package/src/blueprints/compositions/cluster.css +20 -0
- package/src/blueprints/compositions/flow.css +10 -0
- package/src/blueprints/compositions/grid.css +36 -0
- package/src/blueprints/compositions/index.css +12 -0
- package/src/blueprints/compositions/prose.css +89 -0
- package/src/blueprints/compositions/repel.css +23 -0
- package/src/blueprints/compositions/sidebar.css +44 -0
- package/src/blueprints/compositions/switcher.css +32 -0
- package/src/blueprints/compositions/wrapper.css +14 -0
- package/src/blueprints/fonts.json +24 -0
- package/src/blueprints/global/elements.css +609 -0
- package/src/blueprints/global/index.css +13 -0
- package/src/blueprints/global/reset.css +91 -0
- package/src/blueprints/global/variables.css +58 -0
- package/src/blueprints/main.css +27 -0
- package/src/blueprints/spacing.json +19 -0
- package/src/blueprints/swatches/hello.css +11 -0
- package/src/blueprints/swatches/index.css +7 -0
- package/src/blueprints/swatchkit-ui.css +79 -0
- package/src/blueprints/text-leading.json +13 -0
- package/src/blueprints/text-sizes.json +21 -0
- package/src/blueprints/text-weights.json +11 -0
- package/src/blueprints/utilities/index.css +9 -0
- package/src/blueprints/utilities/region.css +12 -0
- package/src/blueprints/utilities/visually-hidden.css +18 -0
- package/src/blueprints/viewports.json +10 -0
- package/src/generators/index.js +437 -0
- package/src/layout.html +0 -1
- package/src/preview-layout.html +13 -0
- package/src/templates/compositions/cluster/description.html +7 -0
- package/src/templates/compositions/cluster/index.html +7 -0
- package/src/templates/compositions/flow/description.html +8 -0
- package/src/templates/compositions/flow/index.html +6 -0
- package/src/templates/compositions/grid/description.html +12 -0
- package/src/templates/compositions/grid/index.html +7 -0
- package/src/templates/compositions/prose/description.html +8 -0
- package/src/templates/compositions/prose/index.html +6 -0
- package/src/templates/compositions/repel/description.html +9 -0
- package/src/templates/compositions/repel/index.html +4 -0
- package/src/templates/compositions/sidebar/description.html +13 -0
- package/src/templates/compositions/sidebar/index.html +4 -0
- package/src/templates/compositions/switcher/description.html +8 -0
- package/src/templates/compositions/switcher/index.html +29 -0
- package/src/templates/compositions/wrapper/description.html +8 -0
- package/src/templates/compositions/wrapper/index.html +5 -0
- package/src/templates/hello/README.md +83 -0
- package/src/templates/hello/index.html +1 -0
- package/src/templates/prose.html +366 -0
- package/src/templates/script.js +41 -0
- package/src/templates/utilities/region/description.html +8 -0
- package/src/templates/utilities/region/index.html +5 -0
- package/src/templates/utilities/visually-hidden/description.html +7 -0
- package/src/templates/utilities/visually-hidden/index.html +7 -0
- package/src/tokens.js +428 -0
- package/src/utils/clamp-generator.js +38 -0
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SwatchKit Global Styles
|
|
3
|
+
*
|
|
4
|
+
* Sensible defaults for HTML elements that make content look good
|
|
5
|
+
* without requiring component-specific CSS. Writing CSS "high up"
|
|
6
|
+
* reduces repetition and provides a solid foundation.
|
|
7
|
+
* This file is yours to edit.
|
|
8
|
+
*
|
|
9
|
+
* Variable references use the default token names from tokens/*.json.
|
|
10
|
+
* If you have renamed any tokens, update the var() references below to match.
|
|
11
|
+
*
|
|
12
|
+
* Based on Andy Bell's Complete CSS course methodology.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/* ==========================================================================
|
|
16
|
+
BODY & TYPOGRAPHY
|
|
17
|
+
========================================================================== */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Base body styles using design tokens.
|
|
21
|
+
* font-size-adjust: from-font makes elements like <code> render in better
|
|
22
|
+
* proportion relative to your base font.
|
|
23
|
+
*/
|
|
24
|
+
body {
|
|
25
|
+
background: var(--color-light);
|
|
26
|
+
color: var(--color-dark);
|
|
27
|
+
font-size: var(--step-1);
|
|
28
|
+
font-family: var(--font-base);
|
|
29
|
+
line-height: var(--leading-standard);
|
|
30
|
+
font-size-adjust: from-font;
|
|
31
|
+
margin: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Headings get a tighter line-height to prevent awkward gaps when they
|
|
36
|
+
* wrap to multiple lines. text-wrap: balance creates more even line lengths.
|
|
37
|
+
*/
|
|
38
|
+
:is(h1, h2, h3, h4) {
|
|
39
|
+
line-height: var(--leading-fine);
|
|
40
|
+
text-wrap: balance;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Heading sizes step down the typography scale.
|
|
45
|
+
* max-width in ch units (width of "0" character) limits line length
|
|
46
|
+
* for readability - especially important for large headings.
|
|
47
|
+
*/
|
|
48
|
+
h1 {
|
|
49
|
+
font-size: var(--step-6);
|
|
50
|
+
max-width: 20ch;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
h2 {
|
|
54
|
+
font-size: var(--step-5);
|
|
55
|
+
max-width: 35ch;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
h3 {
|
|
59
|
+
font-size: var(--step-4);
|
|
60
|
+
max-width: 35ch;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* h4-h6 share the same size - the hierarchy is established
|
|
65
|
+
* through context rather than size at this point.
|
|
66
|
+
*/
|
|
67
|
+
:is(h4, h5, h6) {
|
|
68
|
+
font-size: var(--step-3);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* ==========================================================================
|
|
72
|
+
INLINE TEXT ELEMENTS
|
|
73
|
+
========================================================================== */
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* <small> uses the base step for legal text, captions, etc.
|
|
77
|
+
*/
|
|
78
|
+
small {
|
|
79
|
+
font-size: var(--step-0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* <ins> creates a highlight style - useful for marking additions
|
|
84
|
+
* or drawing attention to text.
|
|
85
|
+
*/
|
|
86
|
+
ins {
|
|
87
|
+
text-decoration: none;
|
|
88
|
+
background: var(--color-primary);
|
|
89
|
+
color: var(--color-dark);
|
|
90
|
+
padding-inline: 0.3em;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Code-like elements get monospace font and consistent padding.
|
|
95
|
+
* box-decoration-break: clone ensures background/padding carry over
|
|
96
|
+
* nicely when the element breaks across multiple lines.
|
|
97
|
+
*/
|
|
98
|
+
:is(code, kbd, samp) {
|
|
99
|
+
font-family: var(--font-mono);
|
|
100
|
+
padding: 0.2em 0.2em 0.05em 0.2em;
|
|
101
|
+
hyphens: none;
|
|
102
|
+
tab-size: 2;
|
|
103
|
+
text-align: left;
|
|
104
|
+
word-spacing: normal;
|
|
105
|
+
word-break: normal;
|
|
106
|
+
word-wrap: normal;
|
|
107
|
+
box-decoration-break: clone;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Fallback for browsers that don't support font-size-adjust.
|
|
112
|
+
* Monospace fonts (especially system ones) tend to render either
|
|
113
|
+
* too large or too small - 0.8em is a sensible middle ground.
|
|
114
|
+
*/
|
|
115
|
+
@supports not (font-size-adjust: from-font) {
|
|
116
|
+
:is(code, kbd, samp) {
|
|
117
|
+
font-size: 0.8em;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Code blocks (<pre> with <code>) become horizontally scrollable
|
|
123
|
+
* instead of wrapping, which preserves formatting.
|
|
124
|
+
*/
|
|
125
|
+
pre:has(code) {
|
|
126
|
+
width: max-content;
|
|
127
|
+
max-width: 100%;
|
|
128
|
+
overflow-x: auto;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Reset inline code styles when inside a <pre> block.
|
|
133
|
+
*/
|
|
134
|
+
pre code {
|
|
135
|
+
border: none;
|
|
136
|
+
background: none;
|
|
137
|
+
padding: 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* <kbd> (keyboard input) gets a subtle border to look like a key.
|
|
142
|
+
*/
|
|
143
|
+
kbd {
|
|
144
|
+
border: 1px solid;
|
|
145
|
+
padding-block-end: 0.1em;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* <var> (variable) - remove italic default, use medium weight instead.
|
|
150
|
+
*/
|
|
151
|
+
var {
|
|
152
|
+
font-style: normal;
|
|
153
|
+
font-weight: var(--weight-medium);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* <q> (inline quote) - italic provides visual distinction.
|
|
158
|
+
*/
|
|
159
|
+
q {
|
|
160
|
+
font-style: italic;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* ==========================================================================
|
|
164
|
+
LISTS
|
|
165
|
+
========================================================================== */
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Lists without classes are "content" lists and get nice default styling.
|
|
169
|
+
* The 1.7ch padding keeps disc markers aligned with the text's left edge
|
|
170
|
+
* rather than outdented.
|
|
171
|
+
*/
|
|
172
|
+
ul:not([class]) {
|
|
173
|
+
padding-inline-start: 1.7ch;
|
|
174
|
+
list-style-type: disc;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
ul:not([class]) > li {
|
|
178
|
+
padding-inline-start: var(--space-xs);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Vertical spacing for list items within standard lists.
|
|
183
|
+
*/
|
|
184
|
+
:is(ol, ul):not([class]) li + * {
|
|
185
|
+
margin-block-start: var(--flow-space, var(--space-xs));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Marker sizing uses relative units so they scale with text.
|
|
190
|
+
* lh (line-height) units work well for disc markers;
|
|
191
|
+
* em units work well for numbers.
|
|
192
|
+
*/
|
|
193
|
+
ul ::marker {
|
|
194
|
+
font-size: 0.8lh;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
ol ::marker {
|
|
198
|
+
font-size: 1em;
|
|
199
|
+
font-weight: var(--weight-bold);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Lists with explicit roles and classes are presumed to be styled
|
|
204
|
+
* separately (navigation, tabs, etc.), so remove default spacing.
|
|
205
|
+
*/
|
|
206
|
+
[role="list"][class],
|
|
207
|
+
[role="tablist"][class] {
|
|
208
|
+
margin-block: 0;
|
|
209
|
+
padding: 0;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Definition lists: <dt> terms are emphasized, <dd> descriptions
|
|
214
|
+
* are indented. Spacing handles the rhythm between terms and definitions.
|
|
215
|
+
*/
|
|
216
|
+
dt {
|
|
217
|
+
font-weight: var(--weight-medium);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
dt + dd {
|
|
221
|
+
margin-block-start: var(--space-xs);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
dd + dt {
|
|
225
|
+
margin-block-start: var(--space-s);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The 1.5ch indent is relative to character width,
|
|
230
|
+
* creating a natural visual hierarchy.
|
|
231
|
+
*/
|
|
232
|
+
dd {
|
|
233
|
+
margin-inline-start: 1.5ch;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* ==========================================================================
|
|
237
|
+
BLOCKQUOTES
|
|
238
|
+
========================================================================== */
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Remove default inline margin, apply a distinct color.
|
|
242
|
+
*/
|
|
243
|
+
blockquote {
|
|
244
|
+
margin-inline: 0;
|
|
245
|
+
color: var(--color-dark-glare);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Footer in a blockquote typically contains attribution.
|
|
250
|
+
* Smaller text and different color separates it from the quote.
|
|
251
|
+
*/
|
|
252
|
+
blockquote footer {
|
|
253
|
+
margin-block-start: var(--space-s);
|
|
254
|
+
color: var(--color-primary);
|
|
255
|
+
font-size: var(--step-0);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Remove italic from <q> inside blockquotes since the
|
|
260
|
+
* blockquote itself provides context.
|
|
261
|
+
*/
|
|
262
|
+
blockquote q {
|
|
263
|
+
font-style: normal;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* ==========================================================================
|
|
267
|
+
MEDIA
|
|
268
|
+
========================================================================== */
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Video embeds (native and from YouTube/Vimeo) get sensible defaults:
|
|
272
|
+
* full width, 16:9 aspect ratio, auto height.
|
|
273
|
+
*/
|
|
274
|
+
:is(video, iframe[src*="youtube"], iframe[src*="vimeo"]) {
|
|
275
|
+
display: block;
|
|
276
|
+
width: 100%;
|
|
277
|
+
height: auto;
|
|
278
|
+
aspect-ratio: 16/9;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Responsive images: max-width prevents blowout on small screens,
|
|
283
|
+
* display: block removes the annoying bottom space from inline display.
|
|
284
|
+
*/
|
|
285
|
+
img,
|
|
286
|
+
picture {
|
|
287
|
+
height: auto;
|
|
288
|
+
max-width: 100%;
|
|
289
|
+
display: block;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
picture {
|
|
293
|
+
width: max-content;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Figcaption gets a touch of padding and monospace for a technical feel.
|
|
298
|
+
*/
|
|
299
|
+
figcaption {
|
|
300
|
+
padding-block-start: 0.5em;
|
|
301
|
+
font-size: var(--step-0);
|
|
302
|
+
font-family: var(--font-mono);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* ==========================================================================
|
|
306
|
+
TABLES
|
|
307
|
+
========================================================================== */
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Tables get consistent borders using the --stroke variable.
|
|
311
|
+
* border-collapse merges adjacent borders for a cleaner look.
|
|
312
|
+
*/
|
|
313
|
+
table {
|
|
314
|
+
border: var(--stroke);
|
|
315
|
+
border-collapse: collapse;
|
|
316
|
+
width: 100%;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
th {
|
|
320
|
+
text-align: left;
|
|
321
|
+
font-weight: var(--weight-bold);
|
|
322
|
+
line-height: var(--leading-fine);
|
|
323
|
+
background: rgb(0 0 0 / 2%);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
thead th {
|
|
327
|
+
padding-block: var(--space-s);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
td,
|
|
331
|
+
th {
|
|
332
|
+
padding: var(--space-xs) var(--space-s);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Border logic: when there are multiple <th> elements, add bottom border.
|
|
337
|
+
* When there's only one <th> (row header), add right border instead.
|
|
338
|
+
*/
|
|
339
|
+
th:not(:only-of-type) {
|
|
340
|
+
border-block-end: var(--stroke);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
th:only-of-type {
|
|
344
|
+
border-inline-end: var(--stroke);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Sibling cells get a left border to create the grid effect.
|
|
349
|
+
*/
|
|
350
|
+
:is(th, td) ~ :is(th, td) {
|
|
351
|
+
border-inline-start: var(--stroke);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Rows after the first get a top border.
|
|
356
|
+
*/
|
|
357
|
+
tr + tr :is(th, td) {
|
|
358
|
+
border-block-start: var(--stroke);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Caption at the bottom with some breathing room.
|
|
363
|
+
*/
|
|
364
|
+
caption {
|
|
365
|
+
caption-side: bottom;
|
|
366
|
+
margin-block-start: var(--space-s);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/* ==========================================================================
|
|
370
|
+
LINKS & INTERACTIVE
|
|
371
|
+
========================================================================== */
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Links without classes (content links) get subtle underline treatment.
|
|
375
|
+
* Targeting only classless links means component styles like .button
|
|
376
|
+
* won't be affected.
|
|
377
|
+
*/
|
|
378
|
+
a:not([class]):hover {
|
|
379
|
+
text-underline-offset: 0.2lh;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Links in headings need thinner underlines - browsers default to
|
|
384
|
+
* unnecessarily thick ones for large text.
|
|
385
|
+
*/
|
|
386
|
+
:is(h1, h2, h3, h4) a:not([class]) {
|
|
387
|
+
text-decoration-thickness: 0.1ex;
|
|
388
|
+
text-underline-offset: 0.2ex;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
:is(h1, h2, h3, h4) a:not([class]):hover {
|
|
392
|
+
text-underline-offset: 0.3ex;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Focus styles: :focus-visible shows outlines only for keyboard navigation,
|
|
397
|
+
* not for mouse/touch interactions. This is the modern best practice.
|
|
398
|
+
*/
|
|
399
|
+
:focus {
|
|
400
|
+
outline: none;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
:focus-visible {
|
|
404
|
+
outline: 2px solid var(--focus-color, currentColor);
|
|
405
|
+
outline-offset: var(--focus-offset, 0.2lh);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Firefox doesn't outline inline elements fully unless they're inline-block,
|
|
410
|
+
* which causes layout issues. This vendor-prefix detection reduces the
|
|
411
|
+
* focus offset to compensate.
|
|
412
|
+
*/
|
|
413
|
+
@supports (-moz-appearance: none) {
|
|
414
|
+
:root {
|
|
415
|
+
--focus-offset: 0.08em;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* When navigating to an anchor (#section), add scroll margin so the
|
|
421
|
+
* target doesn't slam against the top of the viewport.
|
|
422
|
+
* Using 5ex provides a modest cushion (approx 2-3 lines) without being huge.
|
|
423
|
+
*/
|
|
424
|
+
:target {
|
|
425
|
+
scroll-margin-block: 5ex;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Text selection with high contrast for users who select text
|
|
430
|
+
* to improve readability (common for those with astigmatism).
|
|
431
|
+
*/
|
|
432
|
+
::selection {
|
|
433
|
+
color: var(--color-light);
|
|
434
|
+
background: var(--color-dark);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/* ==========================================================================
|
|
438
|
+
MISCELLANEOUS ELEMENTS
|
|
439
|
+
========================================================================== */
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Horizontal rules: remove all borders, add just the top one.
|
|
443
|
+
* Uses --flow-space if in a .flow context, otherwise falls back to --space-xl.
|
|
444
|
+
*/
|
|
445
|
+
hr {
|
|
446
|
+
border: none;
|
|
447
|
+
border-block-start: var(--hr-stroke, var(--stroke));
|
|
448
|
+
margin-block: var(--flow-space, var(--space-xl));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* SVGs without classes get a sensible default size: auto width,
|
|
453
|
+
* height based on line-height so they sit nicely with text.
|
|
454
|
+
*/
|
|
455
|
+
svg:not([class]) {
|
|
456
|
+
width: auto;
|
|
457
|
+
height: 1lh;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Prevent SVGs from shrinking in flex containers.
|
|
462
|
+
*/
|
|
463
|
+
svg {
|
|
464
|
+
flex-shrink: 0;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* SVGs with role="img" and explicit dimensions are treated as images.
|
|
469
|
+
* Light background ensures dark SVGs don't vanish on dark backgrounds.
|
|
470
|
+
* revert allows the width/height attributes to take control.
|
|
471
|
+
*/
|
|
472
|
+
svg[role="img"][width][height] {
|
|
473
|
+
width: revert;
|
|
474
|
+
height: revert;
|
|
475
|
+
background: var(--color-light);
|
|
476
|
+
padding: var(--space-xs);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/* ==========================================================================
|
|
480
|
+
FORMS
|
|
481
|
+
========================================================================== */
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Form spacing using the "lobotomized owl" selector.
|
|
485
|
+
* Uses --flow-space for consistency with .flow composition.
|
|
486
|
+
* This prevents forms from needing class="flow" on every element.
|
|
487
|
+
*/
|
|
488
|
+
form > * + * {
|
|
489
|
+
margin-top: var(--flow-space, 1rem);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* accent-color customizes checkboxes, radio buttons, and range inputs
|
|
494
|
+
* to match your brand instead of the browser's default blue.
|
|
495
|
+
*/
|
|
496
|
+
:is(input, select, textarea) {
|
|
497
|
+
accent-color: var(--color-primary);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Text inputs, selects, and textareas get consistent styling.
|
|
502
|
+
* em units for padding let it scale with text size.
|
|
503
|
+
* width: 100% lets the container determine the size.
|
|
504
|
+
*/
|
|
505
|
+
:is(
|
|
506
|
+
input:not([type="checkbox"], [type="radio"], [type="color"]),
|
|
507
|
+
select,
|
|
508
|
+
textarea
|
|
509
|
+
) {
|
|
510
|
+
padding: 0.5em 0.8em;
|
|
511
|
+
border-radius: var(--radius-s);
|
|
512
|
+
border: var(--stroke-solid);
|
|
513
|
+
background: var(--color-dark-glare);
|
|
514
|
+
color: var(--color-light);
|
|
515
|
+
width: 100%;
|
|
516
|
+
|
|
517
|
+
&::placeholder {
|
|
518
|
+
color: var(--color-mid);
|
|
519
|
+
opacity: 1;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Labels get medium weight and tighter line-height.
|
|
525
|
+
* The ::after trick creates a line break, allowing the label
|
|
526
|
+
* to remain inline while visually separating from the input.
|
|
527
|
+
*/
|
|
528
|
+
label {
|
|
529
|
+
line-height: var(--leading-fine);
|
|
530
|
+
font-weight: var(--weight-medium);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
label::after {
|
|
534
|
+
content: "\A";
|
|
535
|
+
white-space: pre;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Labels wrapping checkboxes/radios get flex layout.
|
|
540
|
+
* baseline alignment keeps the control aligned with the first line
|
|
541
|
+
* of text (better than center if text wraps).
|
|
542
|
+
*/
|
|
543
|
+
label:has(input) {
|
|
544
|
+
display: flex;
|
|
545
|
+
align-items: baseline;
|
|
546
|
+
gap: var(--space-s);
|
|
547
|
+
font-weight: var(--weight-regular);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Tighter spacing between consecutive checkbox/radio labels.
|
|
552
|
+
*/
|
|
553
|
+
label:has(input) + label:has(input) {
|
|
554
|
+
--flow-space: var(--space-s-m);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Optical adjustment: baseline-aligned controls look slightly off,
|
|
559
|
+
* so nudge them up a tiny bit.
|
|
560
|
+
*/
|
|
561
|
+
label:has(input) input {
|
|
562
|
+
transform: translateY(-0.1ex);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Disabled inputs get a muted background and not-allowed cursor.
|
|
567
|
+
* The cursor also applies to text following the disabled input.
|
|
568
|
+
*/
|
|
569
|
+
input:disabled {
|
|
570
|
+
background: var(--color-mid);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
input:disabled,
|
|
574
|
+
label input:disabled + * {
|
|
575
|
+
cursor: not-allowed;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Fieldset and legend get consistent border and padding.
|
|
580
|
+
*/
|
|
581
|
+
fieldset {
|
|
582
|
+
border: var(--stroke);
|
|
583
|
+
padding: var(--space-s);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
legend {
|
|
587
|
+
font-weight: var(--weight-medium);
|
|
588
|
+
padding-inline: var(--space-xs);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/* ==========================================================================
|
|
592
|
+
DETAILS & SUMMARY
|
|
593
|
+
========================================================================== */
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Summary gets bold weight and pointer cursor.
|
|
597
|
+
* Pointer cursor signals that the element is interactive.
|
|
598
|
+
*/
|
|
599
|
+
summary {
|
|
600
|
+
font-weight: var(--weight-bold);
|
|
601
|
+
cursor: pointer;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* When details is open, add space between summary and content.
|
|
606
|
+
*/
|
|
607
|
+
details[open] summary {
|
|
608
|
+
margin-block-end: var(--space-s);
|
|
609
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* Modern reset: https://piccalil.li/blog/a-more-modern-css-reset/ */
|
|
2
|
+
|
|
3
|
+
/* Box sizing rules */
|
|
4
|
+
*,
|
|
5
|
+
*::before,
|
|
6
|
+
*::after {
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/* Prevent font size inflation */
|
|
11
|
+
html {
|
|
12
|
+
-moz-text-size-adjust: none;
|
|
13
|
+
-webkit-text-size-adjust: none;
|
|
14
|
+
text-size-adjust: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* Remove default margin in favour of better control in authored CSS */
|
|
18
|
+
body,
|
|
19
|
+
h1,
|
|
20
|
+
h2,
|
|
21
|
+
h3,
|
|
22
|
+
h4,
|
|
23
|
+
p,
|
|
24
|
+
figure,
|
|
25
|
+
blockquote,
|
|
26
|
+
dl,
|
|
27
|
+
dd {
|
|
28
|
+
margin-block: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
|
|
32
|
+
ul[role="list"],
|
|
33
|
+
ol[role="list"] {
|
|
34
|
+
list-style: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Set core body defaults */
|
|
38
|
+
body {
|
|
39
|
+
min-height: 100vh;
|
|
40
|
+
line-height: 1.5;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Set shorter line heights on headings and interactive elements */
|
|
44
|
+
h1,
|
|
45
|
+
h2,
|
|
46
|
+
h3,
|
|
47
|
+
h4,
|
|
48
|
+
button,
|
|
49
|
+
input,
|
|
50
|
+
label {
|
|
51
|
+
line-height: 1.1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Balance text wrapping on headings */
|
|
55
|
+
h1,
|
|
56
|
+
h2,
|
|
57
|
+
h3,
|
|
58
|
+
h4 {
|
|
59
|
+
text-wrap: balance;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* A elements that don't have a class get default styles */
|
|
63
|
+
a:not([class]) {
|
|
64
|
+
text-decoration-skip-ink: auto;
|
|
65
|
+
color: currentColor;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Make images easier to work with */
|
|
69
|
+
img,
|
|
70
|
+
picture {
|
|
71
|
+
max-inline-size: 100%;
|
|
72
|
+
display: block;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* Inherit fonts for inputs and buttons */
|
|
76
|
+
input,
|
|
77
|
+
button,
|
|
78
|
+
textarea,
|
|
79
|
+
select {
|
|
80
|
+
font: inherit;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Make sure textareas without a rows attribute are not tiny */
|
|
84
|
+
textarea:not([rows]) {
|
|
85
|
+
min-height: 10em;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Anything that has been anchored to should have extra scroll margin */
|
|
89
|
+
:target {
|
|
90
|
+
scroll-margin-block: 5ex;
|
|
91
|
+
}
|