@wtfalch/design 0.5.0 → 0.7.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/dist/components/Button.d.ts +19 -27
- package/dist/components/Button.js +61 -1
- package/dist/components/Callout.d.ts +0 -21
- package/dist/components/Callout.js +7 -0
- package/dist/components/Card.js +7 -0
- package/dist/components/Checkbox.d.ts +12 -23
- package/dist/components/Checkbox.js +25 -2
- package/dist/components/Command.js +10 -2
- package/dist/components/DangerZone.js +7 -0
- package/dist/components/Dialog.d.ts +0 -21
- package/dist/components/Dialog.js +7 -0
- package/dist/components/Field.d.ts +13 -31
- package/dist/components/Field.js +10 -1
- package/dist/components/Identity.d.ts +0 -25
- package/dist/components/Identity.js +7 -0
- package/dist/components/Input.js +7 -0
- package/dist/components/Kbd.d.ts +7 -0
- package/dist/components/Kbd.js +34 -0
- package/dist/components/Markdown.js +7 -0
- package/dist/components/Menu.js +10 -2
- package/dist/components/Modal.d.ts +0 -33
- package/dist/components/Modal.js +7 -0
- package/dist/components/Pagination.d.ts +0 -33
- package/dist/components/Pagination.js +7 -0
- package/dist/components/Popover.js +7 -0
- package/dist/components/Rows.js +7 -0
- package/dist/components/ScrollArea.js +7 -0
- package/dist/components/Select.d.ts +6 -1
- package/dist/components/Select.js +9 -2
- package/dist/components/SizeGrid.js +7 -0
- package/dist/components/Slider.js +7 -0
- package/dist/components/SplitPane.js +7 -0
- package/dist/components/Stat.d.ts +45 -0
- package/dist/components/Stat.js +31 -0
- package/dist/components/Tabs.d.ts +21 -0
- package/dist/components/Tabs.js +8 -1
- package/dist/components/Toast.d.ts +24 -18
- package/dist/components/Toast.js +44 -3
- package/dist/components/Toggle.d.ts +0 -30
- package/dist/components/Toggle.js +7 -0
- package/dist/components/Tooltip.js +7 -0
- package/dist/components/Tour.d.ts +0 -23
- package/dist/components/Tour.js +7 -0
- package/dist/index.d.ts +13 -2
- package/dist/index.js +9 -1
- package/dist/styles/index.css +117 -13
- package/dist/tf.css +117 -13
- package/dist/valet.css +117 -13
- package/package.json +2 -1
package/dist/styles/index.css
CHANGED
|
@@ -93,7 +93,28 @@ body::before {
|
|
|
93
93
|
where the flat grey reads as recessed rather than as something to use. It is
|
|
94
94
|
derived rather than declared -- a new token would have to be added to every
|
|
95
95
|
theme in `themes.ts`, and a theme that missed it would lose its controls. */
|
|
96
|
+
/* An anchor drawn as a button. Three things the element brings that a
|
|
97
|
+
`<button>` does not, and all three have to go: the underline, the link
|
|
98
|
+
colour, and the text alignment a block anchor inherits. `cursor: pointer`
|
|
99
|
+
it already has. Disabled is `aria-disabled` here -- an anchor ignores the
|
|
100
|
+
native attribute -- so every `:disabled` rule above has an
|
|
101
|
+
`[aria-disabled='true']` twin rather than a rewrite, which leaves each
|
|
102
|
+
`button` selector at the specificity it had and every committed baseline
|
|
103
|
+
untouched. */
|
|
104
|
+
a.btn {
|
|
105
|
+
text-decoration: none;
|
|
106
|
+
color: var(--text);
|
|
107
|
+
text-align: center;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
a.btn[aria-disabled='true'] {
|
|
111
|
+
/* A disabled anchor still takes the pointer, so say so. The click itself is
|
|
112
|
+
blocked in the capture phase by the component. */
|
|
113
|
+
cursor: not-allowed;
|
|
114
|
+
}
|
|
115
|
+
|
|
96
116
|
button,
|
|
117
|
+
a.btn,
|
|
97
118
|
input,
|
|
98
119
|
textarea,
|
|
99
120
|
select {
|
|
@@ -117,7 +138,8 @@ select {
|
|
|
117
138
|
the icon; the button simply had no opinion about how to arrange two things.
|
|
118
139
|
`inline-flex` and a gap gives it one, and the gap replaces the space
|
|
119
140
|
character people were putting between an icon and its label. */
|
|
120
|
-
button
|
|
141
|
+
button,
|
|
142
|
+
a.btn {
|
|
121
143
|
display: inline-flex;
|
|
122
144
|
align-items: center;
|
|
123
145
|
justify-content: center;
|
|
@@ -143,7 +165,8 @@ button[aria-pressed='true']:hover:not(:disabled) { border-color: var(--accent);
|
|
|
143
165
|
|
|
144
166
|
/* The glyph never shrinks: in a narrow row flexbox would take it from the icon
|
|
145
167
|
before the text, and half an icon is not a smaller icon. */
|
|
146
|
-
button > svg
|
|
168
|
+
button > svg,
|
|
169
|
+
a.btn > svg { flex: none; }
|
|
147
170
|
|
|
148
171
|
.size-sm { font-size: var(--text-xs); padding: var(--space-1) var(--space-2); }
|
|
149
172
|
|
|
@@ -169,6 +192,7 @@ input, textarea, select { width: 100%; }
|
|
|
169
192
|
textarea { resize: none; }
|
|
170
193
|
|
|
171
194
|
button:hover:not(:disabled),
|
|
195
|
+
a.btn:hover:not([aria-disabled='true']),
|
|
172
196
|
input:hover:not(:disabled),
|
|
173
197
|
textarea:hover:not(:disabled),
|
|
174
198
|
select:hover:not(:disabled) { border-color: var(--accent); }
|
|
@@ -177,6 +201,7 @@ select:hover:not(:disabled) { border-color: var(--accent); }
|
|
|
177
201
|
`:focus` on the fields because a focused field is a place you are typing and
|
|
178
202
|
should say so however you got there. */
|
|
179
203
|
button:focus-visible,
|
|
204
|
+
a.btn:focus-visible,
|
|
180
205
|
input:focus,
|
|
181
206
|
textarea:focus,
|
|
182
207
|
select:focus { outline: none; border-color: var(--accent); }
|
|
@@ -270,11 +295,13 @@ input[type='checkbox']:disabled,
|
|
|
270
295
|
input[type='radio']:disabled { cursor: not-allowed; background: var(--panel-2); }
|
|
271
296
|
|
|
272
297
|
button:disabled,
|
|
298
|
+
a.btn[aria-disabled='true'],
|
|
273
299
|
input:disabled,
|
|
274
300
|
textarea:disabled,
|
|
275
301
|
select:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
276
302
|
|
|
277
|
-
button.primary
|
|
303
|
+
button.primary,
|
|
304
|
+
a.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
|
|
278
305
|
|
|
279
306
|
/* A disabled primary is not a faded primary.
|
|
280
307
|
`opacity: .45` was the whole of it, and a coloured fill at 45% is still a
|
|
@@ -282,7 +309,8 @@ button.primary { background: var(--accent); border-color: var(--accent); color:
|
|
|
282
309
|
thing on the panel. That got worse when onboarding started holding people at
|
|
283
310
|
a disabled Next. So it gives up the fill entirely and becomes the shape of a
|
|
284
311
|
disabled control -- the opacity then has nothing left to do. */
|
|
285
|
-
button.primary:disabled
|
|
312
|
+
button.primary:disabled,
|
|
313
|
+
a.btn.primary[aria-disabled='true'] {
|
|
286
314
|
background: var(--panel-2);
|
|
287
315
|
border-color: var(--border);
|
|
288
316
|
color: var(--muted);
|
|
@@ -352,13 +380,15 @@ button[aria-busy='true']::after {
|
|
|
352
380
|
|
|
353
381
|
/* Quiet: no border, no fill. For the action beside the action -- Cancel next to
|
|
354
382
|
Save -- where a bordered box competes with the thing it is next to. */
|
|
355
|
-
button.ghost
|
|
383
|
+
button.ghost,
|
|
384
|
+
a.btn.ghost {
|
|
356
385
|
background: transparent;
|
|
357
386
|
border-color: transparent;
|
|
358
387
|
color: var(--muted);
|
|
359
388
|
}
|
|
360
389
|
|
|
361
|
-
button.ghost:hover:not(:disabled)
|
|
390
|
+
button.ghost:hover:not(:disabled),
|
|
391
|
+
a.btn.ghost:hover:not([aria-disabled='true']) {
|
|
362
392
|
background: var(--panel-2);
|
|
363
393
|
border-color: transparent;
|
|
364
394
|
color: var(--text);
|
|
@@ -565,19 +595,22 @@ button.ghost:hover:not(:disabled) {
|
|
|
565
595
|
/* `:where(button)` so this carries no specificity of its own: a component's
|
|
566
596
|
press rule below -- a card, a tab, a rail item, all of them buttons --
|
|
567
597
|
wins by coming later, instead of every one having to restate `button`. */
|
|
568
|
-
:where(button):active:not(:disabled)
|
|
598
|
+
:where(button):active:not(:disabled),
|
|
599
|
+
:where(a.btn):active:not([aria-disabled='true']) {
|
|
569
600
|
background: color-mix(in srgb, var(--text) var(--press-ink), var(--control));
|
|
570
601
|
border-color: var(--accent);
|
|
571
602
|
transform: scale(var(--press-scale));
|
|
572
603
|
transition: none;
|
|
573
604
|
}
|
|
574
605
|
|
|
575
|
-
button.primary:active:not(:disabled)
|
|
606
|
+
button.primary:active:not(:disabled),
|
|
607
|
+
a.btn.primary:active:not([aria-disabled='true']) {
|
|
576
608
|
background: color-mix(in srgb, var(--text) var(--press-ink), var(--accent));
|
|
577
609
|
border-color: color-mix(in srgb, var(--text) var(--press-ink), var(--accent));
|
|
578
610
|
}
|
|
579
611
|
|
|
580
|
-
button.ghost:active:not(:disabled)
|
|
612
|
+
button.ghost:active:not(:disabled),
|
|
613
|
+
a.btn.ghost:active:not([aria-disabled='true']) {
|
|
581
614
|
background: color-mix(in srgb, var(--text) var(--press-ink), var(--panel-2));
|
|
582
615
|
border-color: transparent;
|
|
583
616
|
}
|
|
@@ -800,7 +833,8 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
800
833
|
/* Full width, for the one action a card or a step is about. Not a size: a
|
|
801
834
|
`block` button is the same height as any other, it just stops being a thing
|
|
802
835
|
you have to aim at. */
|
|
803
|
-
button.block
|
|
836
|
+
button.block,
|
|
837
|
+
a.btn.block { display: flex; width: 100%; }
|
|
804
838
|
|
|
805
839
|
/* The default is `size-md`, spelled once for every control.
|
|
806
840
|
The paragraph above promised one scale for buttons, inputs and selects, and
|
|
@@ -809,6 +843,7 @@ button.block { display: flex; width: 100%; }
|
|
|
809
843
|
could line up. The download modal's search box against its Search button was
|
|
810
844
|
the version you could see from across the room. */
|
|
811
845
|
button,
|
|
846
|
+
a.btn,
|
|
812
847
|
input,
|
|
813
848
|
textarea,
|
|
814
849
|
select,
|
|
@@ -959,18 +994,21 @@ select,
|
|
|
959
994
|
|
|
960
995
|
/* ---- ./dangerzone.css ---- */
|
|
961
996
|
/* Destructive, and legible as such standing still. */
|
|
962
|
-
button.danger
|
|
997
|
+
button.danger,
|
|
998
|
+
a.btn.danger {
|
|
963
999
|
color: var(--bad);
|
|
964
1000
|
border-color: color-mix(in srgb, var(--bad) 45%, var(--border-strong));
|
|
965
1001
|
}
|
|
966
1002
|
|
|
967
|
-
button.danger:hover:not(:disabled)
|
|
1003
|
+
button.danger:hover:not(:disabled),
|
|
1004
|
+
a.btn.danger:hover:not([aria-disabled='true']) {
|
|
968
1005
|
background: color-mix(in srgb, var(--bad) 12%, var(--panel));
|
|
969
1006
|
border-color: var(--bad);
|
|
970
1007
|
color: var(--bad);
|
|
971
1008
|
}
|
|
972
1009
|
|
|
973
|
-
button.danger:active:not(:disabled)
|
|
1010
|
+
button.danger:active:not(:disabled),
|
|
1011
|
+
a.btn.danger:active:not([aria-disabled='true']) {
|
|
974
1012
|
background: color-mix(in srgb, var(--bad) 20%, var(--panel));
|
|
975
1013
|
border-color: var(--bad);
|
|
976
1014
|
}
|
|
@@ -3147,6 +3185,72 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3147
3185
|
anchored surfaces (`.pop`, `.menu-sheet`, `.cmd`) sit over everything and a
|
|
3148
3186
|
rule of equal specificity that came earlier would lose to whatever the
|
|
3149
3187
|
sheets they cover happen to set. */
|
|
3188
|
+
/* ---- ./kbd.css ---- */
|
|
3189
|
+
/* One rule where there were two identical ones, in `menu.css` and
|
|
3190
|
+
`command.css`. Both keep their class as well, so `Menu` and `Command` are
|
|
3191
|
+
`.kbd .menu-key` and `.kbd .cmd-key` now: the declarations are the same, so
|
|
3192
|
+
nothing moves, and the context classes stay available for a rule that ever
|
|
3193
|
+
needs to tell the two apart. */
|
|
3194
|
+
.kbd {
|
|
3195
|
+
flex: none;
|
|
3196
|
+
font-family: var(--font-mono);
|
|
3197
|
+
font-size: var(--text-2xs);
|
|
3198
|
+
color: var(--muted);
|
|
3199
|
+
letter-spacing: var(--tracking);
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
/* ---- ./stat.css ---- */
|
|
3203
|
+
/* A figure with furniture. `--space-1` between the three lines because they
|
|
3204
|
+
are one object read top to bottom, not three paragraphs. */
|
|
3205
|
+
.stat {
|
|
3206
|
+
display: grid;
|
|
3207
|
+
gap: var(--space-1);
|
|
3208
|
+
padding: var(--space-4);
|
|
3209
|
+
border: var(--border-width) solid var(--border);
|
|
3210
|
+
border-radius: var(--radius-md);
|
|
3211
|
+
background: var(--panel);
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3214
|
+
/* Inside something already bordered. A bordered tile in a bordered row is two
|
|
3215
|
+
boxes saying one thing. */
|
|
3216
|
+
.stat-bare {
|
|
3217
|
+
padding: 0;
|
|
3218
|
+
border: 0;
|
|
3219
|
+
border-radius: 0;
|
|
3220
|
+
background: none;
|
|
3221
|
+
gap: 0;
|
|
3222
|
+
line-height: 1.25;
|
|
3223
|
+
}
|
|
3224
|
+
|
|
3225
|
+
.stat > p { margin: 0; }
|
|
3226
|
+
|
|
3227
|
+
.stat-label {
|
|
3228
|
+
color: var(--muted);
|
|
3229
|
+
font-size: var(--text-xs);
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
/* Tabular figures are the point: a column of numbers is compared by its
|
|
3233
|
+
digits' positions, and proportional ones move them per row. */
|
|
3234
|
+
.stat-value {
|
|
3235
|
+
font-size: var(--text-lg);
|
|
3236
|
+
font-weight: var(--weight-strong);
|
|
3237
|
+
font-variant-numeric: tabular-nums;
|
|
3238
|
+
}
|
|
3239
|
+
|
|
3240
|
+
.stat-bare .stat-value { font-size: var(--text-sm); }
|
|
3241
|
+
|
|
3242
|
+
.stat-note {
|
|
3243
|
+
color: var(--muted);
|
|
3244
|
+
font-size: var(--text-xs);
|
|
3245
|
+
}
|
|
3246
|
+
|
|
3247
|
+
/* Only the figure takes the colour. Colouring the label too makes the tile a
|
|
3248
|
+
status box, and a tone here is a remark about the number. */
|
|
3249
|
+
.stat[data-tone='info'] .stat-value { color: var(--info); }
|
|
3250
|
+
.stat[data-tone='good'] .stat-value { color: var(--good); }
|
|
3251
|
+
.stat[data-tone='warn'] .stat-value { color: var(--warn); }
|
|
3252
|
+
.stat[data-tone='bad'] .stat-value { color: var(--bad); }
|
|
3253
|
+
|
|
3150
3254
|
/* ---- ./scrollarea.css ---- */
|
|
3151
3255
|
/* A box that scrolls, with its edges drawn.
|
|
3152
3256
|
|
package/dist/tf.css
CHANGED
|
@@ -363,7 +363,28 @@ body::before {
|
|
|
363
363
|
where the flat grey reads as recessed rather than as something to use. It is
|
|
364
364
|
derived rather than declared -- a new token would have to be added to every
|
|
365
365
|
theme in `themes.ts`, and a theme that missed it would lose its controls. */
|
|
366
|
+
/* An anchor drawn as a button. Three things the element brings that a
|
|
367
|
+
`<button>` does not, and all three have to go: the underline, the link
|
|
368
|
+
colour, and the text alignment a block anchor inherits. `cursor: pointer`
|
|
369
|
+
it already has. Disabled is `aria-disabled` here -- an anchor ignores the
|
|
370
|
+
native attribute -- so every `:disabled` rule above has an
|
|
371
|
+
`[aria-disabled='true']` twin rather than a rewrite, which leaves each
|
|
372
|
+
`button` selector at the specificity it had and every committed baseline
|
|
373
|
+
untouched. */
|
|
374
|
+
a.btn {
|
|
375
|
+
text-decoration: none;
|
|
376
|
+
color: var(--text);
|
|
377
|
+
text-align: center;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
a.btn[aria-disabled='true'] {
|
|
381
|
+
/* A disabled anchor still takes the pointer, so say so. The click itself is
|
|
382
|
+
blocked in the capture phase by the component. */
|
|
383
|
+
cursor: not-allowed;
|
|
384
|
+
}
|
|
385
|
+
|
|
366
386
|
button,
|
|
387
|
+
a.btn,
|
|
367
388
|
input,
|
|
368
389
|
textarea,
|
|
369
390
|
select {
|
|
@@ -387,7 +408,8 @@ select {
|
|
|
387
408
|
the icon; the button simply had no opinion about how to arrange two things.
|
|
388
409
|
`inline-flex` and a gap gives it one, and the gap replaces the space
|
|
389
410
|
character people were putting between an icon and its label. */
|
|
390
|
-
button
|
|
411
|
+
button,
|
|
412
|
+
a.btn {
|
|
391
413
|
display: inline-flex;
|
|
392
414
|
align-items: center;
|
|
393
415
|
justify-content: center;
|
|
@@ -413,7 +435,8 @@ button[aria-pressed='true']:hover:not(:disabled) { border-color: var(--accent);
|
|
|
413
435
|
|
|
414
436
|
/* The glyph never shrinks: in a narrow row flexbox would take it from the icon
|
|
415
437
|
before the text, and half an icon is not a smaller icon. */
|
|
416
|
-
button > svg
|
|
438
|
+
button > svg,
|
|
439
|
+
a.btn > svg { flex: none; }
|
|
417
440
|
|
|
418
441
|
.size-sm { font-size: var(--text-xs); padding: var(--space-1) var(--space-2); }
|
|
419
442
|
|
|
@@ -439,6 +462,7 @@ input, textarea, select { width: 100%; }
|
|
|
439
462
|
textarea { resize: none; }
|
|
440
463
|
|
|
441
464
|
button:hover:not(:disabled),
|
|
465
|
+
a.btn:hover:not([aria-disabled='true']),
|
|
442
466
|
input:hover:not(:disabled),
|
|
443
467
|
textarea:hover:not(:disabled),
|
|
444
468
|
select:hover:not(:disabled) { border-color: var(--accent); }
|
|
@@ -447,6 +471,7 @@ select:hover:not(:disabled) { border-color: var(--accent); }
|
|
|
447
471
|
`:focus` on the fields because a focused field is a place you are typing and
|
|
448
472
|
should say so however you got there. */
|
|
449
473
|
button:focus-visible,
|
|
474
|
+
a.btn:focus-visible,
|
|
450
475
|
input:focus,
|
|
451
476
|
textarea:focus,
|
|
452
477
|
select:focus { outline: none; border-color: var(--accent); }
|
|
@@ -540,11 +565,13 @@ input[type='checkbox']:disabled,
|
|
|
540
565
|
input[type='radio']:disabled { cursor: not-allowed; background: var(--panel-2); }
|
|
541
566
|
|
|
542
567
|
button:disabled,
|
|
568
|
+
a.btn[aria-disabled='true'],
|
|
543
569
|
input:disabled,
|
|
544
570
|
textarea:disabled,
|
|
545
571
|
select:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
546
572
|
|
|
547
|
-
button.primary
|
|
573
|
+
button.primary,
|
|
574
|
+
a.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
|
|
548
575
|
|
|
549
576
|
/* A disabled primary is not a faded primary.
|
|
550
577
|
`opacity: .45` was the whole of it, and a coloured fill at 45% is still a
|
|
@@ -552,7 +579,8 @@ button.primary { background: var(--accent); border-color: var(--accent); color:
|
|
|
552
579
|
thing on the panel. That got worse when onboarding started holding people at
|
|
553
580
|
a disabled Next. So it gives up the fill entirely and becomes the shape of a
|
|
554
581
|
disabled control -- the opacity then has nothing left to do. */
|
|
555
|
-
button.primary:disabled
|
|
582
|
+
button.primary:disabled,
|
|
583
|
+
a.btn.primary[aria-disabled='true'] {
|
|
556
584
|
background: var(--panel-2);
|
|
557
585
|
border-color: var(--border);
|
|
558
586
|
color: var(--muted);
|
|
@@ -622,13 +650,15 @@ button[aria-busy='true']::after {
|
|
|
622
650
|
|
|
623
651
|
/* Quiet: no border, no fill. For the action beside the action -- Cancel next to
|
|
624
652
|
Save -- where a bordered box competes with the thing it is next to. */
|
|
625
|
-
button.ghost
|
|
653
|
+
button.ghost,
|
|
654
|
+
a.btn.ghost {
|
|
626
655
|
background: transparent;
|
|
627
656
|
border-color: transparent;
|
|
628
657
|
color: var(--muted);
|
|
629
658
|
}
|
|
630
659
|
|
|
631
|
-
button.ghost:hover:not(:disabled)
|
|
660
|
+
button.ghost:hover:not(:disabled),
|
|
661
|
+
a.btn.ghost:hover:not([aria-disabled='true']) {
|
|
632
662
|
background: var(--panel-2);
|
|
633
663
|
border-color: transparent;
|
|
634
664
|
color: var(--text);
|
|
@@ -835,19 +865,22 @@ button.ghost:hover:not(:disabled) {
|
|
|
835
865
|
/* `:where(button)` so this carries no specificity of its own: a component's
|
|
836
866
|
press rule below -- a card, a tab, a rail item, all of them buttons --
|
|
837
867
|
wins by coming later, instead of every one having to restate `button`. */
|
|
838
|
-
:where(button):active:not(:disabled)
|
|
868
|
+
:where(button):active:not(:disabled),
|
|
869
|
+
:where(a.btn):active:not([aria-disabled='true']) {
|
|
839
870
|
background: color-mix(in srgb, var(--text) var(--press-ink), var(--control));
|
|
840
871
|
border-color: var(--accent);
|
|
841
872
|
transform: scale(var(--press-scale));
|
|
842
873
|
transition: none;
|
|
843
874
|
}
|
|
844
875
|
|
|
845
|
-
button.primary:active:not(:disabled)
|
|
876
|
+
button.primary:active:not(:disabled),
|
|
877
|
+
a.btn.primary:active:not([aria-disabled='true']) {
|
|
846
878
|
background: color-mix(in srgb, var(--text) var(--press-ink), var(--accent));
|
|
847
879
|
border-color: color-mix(in srgb, var(--text) var(--press-ink), var(--accent));
|
|
848
880
|
}
|
|
849
881
|
|
|
850
|
-
button.ghost:active:not(:disabled)
|
|
882
|
+
button.ghost:active:not(:disabled),
|
|
883
|
+
a.btn.ghost:active:not([aria-disabled='true']) {
|
|
851
884
|
background: color-mix(in srgb, var(--text) var(--press-ink), var(--panel-2));
|
|
852
885
|
border-color: transparent;
|
|
853
886
|
}
|
|
@@ -1070,7 +1103,8 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
1070
1103
|
/* Full width, for the one action a card or a step is about. Not a size: a
|
|
1071
1104
|
`block` button is the same height as any other, it just stops being a thing
|
|
1072
1105
|
you have to aim at. */
|
|
1073
|
-
button.block
|
|
1106
|
+
button.block,
|
|
1107
|
+
a.btn.block { display: flex; width: 100%; }
|
|
1074
1108
|
|
|
1075
1109
|
/* The default is `size-md`, spelled once for every control.
|
|
1076
1110
|
The paragraph above promised one scale for buttons, inputs and selects, and
|
|
@@ -1079,6 +1113,7 @@ button.block { display: flex; width: 100%; }
|
|
|
1079
1113
|
could line up. The download modal's search box against its Search button was
|
|
1080
1114
|
the version you could see from across the room. */
|
|
1081
1115
|
button,
|
|
1116
|
+
a.btn,
|
|
1082
1117
|
input,
|
|
1083
1118
|
textarea,
|
|
1084
1119
|
select,
|
|
@@ -1229,18 +1264,21 @@ select,
|
|
|
1229
1264
|
|
|
1230
1265
|
/* ---- ./dangerzone.css ---- */
|
|
1231
1266
|
/* Destructive, and legible as such standing still. */
|
|
1232
|
-
button.danger
|
|
1267
|
+
button.danger,
|
|
1268
|
+
a.btn.danger {
|
|
1233
1269
|
color: var(--bad);
|
|
1234
1270
|
border-color: color-mix(in srgb, var(--bad) 45%, var(--border-strong));
|
|
1235
1271
|
}
|
|
1236
1272
|
|
|
1237
|
-
button.danger:hover:not(:disabled)
|
|
1273
|
+
button.danger:hover:not(:disabled),
|
|
1274
|
+
a.btn.danger:hover:not([aria-disabled='true']) {
|
|
1238
1275
|
background: color-mix(in srgb, var(--bad) 12%, var(--panel));
|
|
1239
1276
|
border-color: var(--bad);
|
|
1240
1277
|
color: var(--bad);
|
|
1241
1278
|
}
|
|
1242
1279
|
|
|
1243
|
-
button.danger:active:not(:disabled)
|
|
1280
|
+
button.danger:active:not(:disabled),
|
|
1281
|
+
a.btn.danger:active:not([aria-disabled='true']) {
|
|
1244
1282
|
background: color-mix(in srgb, var(--bad) 20%, var(--panel));
|
|
1245
1283
|
border-color: var(--bad);
|
|
1246
1284
|
}
|
|
@@ -3417,6 +3455,72 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3417
3455
|
anchored surfaces (`.pop`, `.menu-sheet`, `.cmd`) sit over everything and a
|
|
3418
3456
|
rule of equal specificity that came earlier would lose to whatever the
|
|
3419
3457
|
sheets they cover happen to set. */
|
|
3458
|
+
/* ---- ./kbd.css ---- */
|
|
3459
|
+
/* One rule where there were two identical ones, in `menu.css` and
|
|
3460
|
+
`command.css`. Both keep their class as well, so `Menu` and `Command` are
|
|
3461
|
+
`.kbd .menu-key` and `.kbd .cmd-key` now: the declarations are the same, so
|
|
3462
|
+
nothing moves, and the context classes stay available for a rule that ever
|
|
3463
|
+
needs to tell the two apart. */
|
|
3464
|
+
.kbd {
|
|
3465
|
+
flex: none;
|
|
3466
|
+
font-family: var(--font-mono);
|
|
3467
|
+
font-size: var(--text-2xs);
|
|
3468
|
+
color: var(--muted);
|
|
3469
|
+
letter-spacing: var(--tracking);
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
/* ---- ./stat.css ---- */
|
|
3473
|
+
/* A figure with furniture. `--space-1` between the three lines because they
|
|
3474
|
+
are one object read top to bottom, not three paragraphs. */
|
|
3475
|
+
.stat {
|
|
3476
|
+
display: grid;
|
|
3477
|
+
gap: var(--space-1);
|
|
3478
|
+
padding: var(--space-4);
|
|
3479
|
+
border: var(--border-width) solid var(--border);
|
|
3480
|
+
border-radius: var(--radius-md);
|
|
3481
|
+
background: var(--panel);
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3484
|
+
/* Inside something already bordered. A bordered tile in a bordered row is two
|
|
3485
|
+
boxes saying one thing. */
|
|
3486
|
+
.stat-bare {
|
|
3487
|
+
padding: 0;
|
|
3488
|
+
border: 0;
|
|
3489
|
+
border-radius: 0;
|
|
3490
|
+
background: none;
|
|
3491
|
+
gap: 0;
|
|
3492
|
+
line-height: 1.25;
|
|
3493
|
+
}
|
|
3494
|
+
|
|
3495
|
+
.stat > p { margin: 0; }
|
|
3496
|
+
|
|
3497
|
+
.stat-label {
|
|
3498
|
+
color: var(--muted);
|
|
3499
|
+
font-size: var(--text-xs);
|
|
3500
|
+
}
|
|
3501
|
+
|
|
3502
|
+
/* Tabular figures are the point: a column of numbers is compared by its
|
|
3503
|
+
digits' positions, and proportional ones move them per row. */
|
|
3504
|
+
.stat-value {
|
|
3505
|
+
font-size: var(--text-lg);
|
|
3506
|
+
font-weight: var(--weight-strong);
|
|
3507
|
+
font-variant-numeric: tabular-nums;
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3510
|
+
.stat-bare .stat-value { font-size: var(--text-sm); }
|
|
3511
|
+
|
|
3512
|
+
.stat-note {
|
|
3513
|
+
color: var(--muted);
|
|
3514
|
+
font-size: var(--text-xs);
|
|
3515
|
+
}
|
|
3516
|
+
|
|
3517
|
+
/* Only the figure takes the colour. Colouring the label too makes the tile a
|
|
3518
|
+
status box, and a tone here is a remark about the number. */
|
|
3519
|
+
.stat[data-tone='info'] .stat-value { color: var(--info); }
|
|
3520
|
+
.stat[data-tone='good'] .stat-value { color: var(--good); }
|
|
3521
|
+
.stat[data-tone='warn'] .stat-value { color: var(--warn); }
|
|
3522
|
+
.stat[data-tone='bad'] .stat-value { color: var(--bad); }
|
|
3523
|
+
|
|
3420
3524
|
/* ---- ./scrollarea.css ---- */
|
|
3421
3525
|
/* A box that scrolls, with its edges drawn.
|
|
3422
3526
|
|