@wtfalch/design 0.6.0 → 0.8.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 +0 -31
- package/dist/components/Checkbox.js +7 -0
- 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 +22 -50
- package/dist/components/Field.js +18 -9
- package/dist/components/Identity.d.ts +0 -25
- package/dist/components/Identity.js +7 -0
- package/dist/components/Input.d.ts +10 -0
- package/dist/components/Input.js +31 -3
- 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 +8 -1
- package/dist/components/Select.js +34 -5
- package/dist/components/Shell.d.ts +35 -0
- package/dist/components/Shell.js +26 -0
- 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/Textarea.js +14 -4
- package/dist/components/ThemeSwitch.d.ts +19 -0
- package/dist/components/ThemeSwitch.js +65 -0
- 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/components/fieldWiring.d.ts +44 -0
- package/dist/components/fieldWiring.js +30 -0
- package/dist/index.d.ts +23 -3
- package/dist/index.js +17 -1
- package/dist/styles/index.css +259 -13
- package/dist/tf.css +259 -13
- package/dist/themes/choice.d.ts +71 -0
- package/dist/themes/choice.js +81 -0
- package/dist/valet.css +259 -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
|
}
|
|
@@ -3080,6 +3118,70 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3080
3118
|
|
|
3081
3119
|
.secret-lg > .secret-eye { padding: var(--space-2); }
|
|
3082
3120
|
|
|
3121
|
+
/* An input with something inside its edges: a glyph on the left, a hint or a
|
|
3122
|
+
clear button on the right. Same arrangement as `.secret` above, and for the
|
|
3123
|
+
same reason -- one grid cell with everything stacked in it, and the room
|
|
3124
|
+
reserved in the input's own padding, so nothing is positioned against a
|
|
3125
|
+
height that changes with `size`. */
|
|
3126
|
+
.adorned { display: grid; align-items: center; }
|
|
3127
|
+
|
|
3128
|
+
.adorned > input,
|
|
3129
|
+
.adorned > .adorned-mark,
|
|
3130
|
+
.adorned > .adorned-end { grid-area: 1 / 1; }
|
|
3131
|
+
|
|
3132
|
+
.adorned.block { width: 100%; }
|
|
3133
|
+
|
|
3134
|
+
.adorned > .adorned-mark {
|
|
3135
|
+
justify-self: start;
|
|
3136
|
+
margin-left: var(--space-2);
|
|
3137
|
+
color: var(--muted);
|
|
3138
|
+
/* The glyph is decoration over the box; clicks belong to the input under
|
|
3139
|
+
it, which is otherwise unreachable in its own left edge. */
|
|
3140
|
+
pointer-events: none;
|
|
3141
|
+
/* Over the input, not under it. Both share one grid cell, the input has an
|
|
3142
|
+
opaque `--control` background, and it comes later in the DOM -- so
|
|
3143
|
+
without this the glyph is painted and then covered, which looks exactly
|
|
3144
|
+
like an icon that failed to render. `.secret` never hit this because its
|
|
3145
|
+
button is written after the input. */
|
|
3146
|
+
z-index: 1;
|
|
3147
|
+
}
|
|
3148
|
+
|
|
3149
|
+
/* Room for the glyph, on the scale, so a density change moves the text with
|
|
3150
|
+
the mark rather than leaving one behind. `--space-8` is what `.secret`
|
|
3151
|
+
reserves on the right for the same reason; the scale has no 7, and an
|
|
3152
|
+
undefined custom property does not fall back -- the declaration computes
|
|
3153
|
+
to 0 and the text sits under the glyph. */
|
|
3154
|
+
.adorned-icon > input { padding-left: var(--space-8); }
|
|
3155
|
+
|
|
3156
|
+
/* No `--space-12` on the scale; two steps that are, added. Same arithmetic
|
|
3157
|
+
as `.secret-lg`. */
|
|
3158
|
+
.adorned-icon.adorned-lg > input { padding-left: calc(var(--space-10) + var(--space-1)); }
|
|
3159
|
+
|
|
3160
|
+
.adorned > .adorned-end {
|
|
3161
|
+
justify-self: end;
|
|
3162
|
+
display: flex;
|
|
3163
|
+
align-items: center;
|
|
3164
|
+
gap: var(--space-1);
|
|
3165
|
+
margin-right: var(--space-1);
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
/* `:has`, not a sibling combinator: the input comes *before* the end cap in
|
|
3169
|
+
the DOM, so `~` reads the wrong way and matches nothing. */
|
|
3170
|
+
.adorned:has(> .adorned-end) > input { padding-right: var(--space-8); }
|
|
3171
|
+
.adorned-lg:has(> .adorned-end) > input {
|
|
3172
|
+
padding-right: calc(var(--space-10) + var(--space-1));
|
|
3173
|
+
}
|
|
3174
|
+
|
|
3175
|
+
/* Sized from its glyph, not `.icon-btn`'s 34px tile, which would be taller
|
|
3176
|
+
than a small input -- the note above `.secret-eye` in full. */
|
|
3177
|
+
.adorned-clear {
|
|
3178
|
+
width: auto; height: auto;
|
|
3179
|
+
padding: var(--space-1);
|
|
3180
|
+
opacity: 1;
|
|
3181
|
+
}
|
|
3182
|
+
|
|
3183
|
+
.adorned-lg .adorned-clear { padding: var(--space-2); }
|
|
3184
|
+
|
|
3083
3185
|
/* ---- ./tour.css ---- */
|
|
3084
3186
|
/* tour ----------------------------------------------------------------- */
|
|
3085
3187
|
|
|
@@ -3147,6 +3249,150 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3147
3249
|
anchored surfaces (`.pop`, `.menu-sheet`, `.cmd`) sit over everything and a
|
|
3148
3250
|
rule of equal specificity that came earlier would lose to whatever the
|
|
3149
3251
|
sheets they cover happen to set. */
|
|
3252
|
+
/* ---- ./kbd.css ---- */
|
|
3253
|
+
/* One rule where there were two identical ones, in `menu.css` and
|
|
3254
|
+
`command.css`. Both keep their class as well, so `Menu` and `Command` are
|
|
3255
|
+
`.kbd .menu-key` and `.kbd .cmd-key` now: the declarations are the same, so
|
|
3256
|
+
nothing moves, and the context classes stay available for a rule that ever
|
|
3257
|
+
needs to tell the two apart. */
|
|
3258
|
+
.kbd {
|
|
3259
|
+
flex: none;
|
|
3260
|
+
font-family: var(--font-mono);
|
|
3261
|
+
font-size: var(--text-2xs);
|
|
3262
|
+
color: var(--muted);
|
|
3263
|
+
letter-spacing: var(--tracking);
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
/* ---- ./stat.css ---- */
|
|
3267
|
+
/* A figure with furniture. `--space-1` between the three lines because they
|
|
3268
|
+
are one object read top to bottom, not three paragraphs. */
|
|
3269
|
+
.stat {
|
|
3270
|
+
display: grid;
|
|
3271
|
+
gap: var(--space-1);
|
|
3272
|
+
padding: var(--space-4);
|
|
3273
|
+
border: var(--border-width) solid var(--border);
|
|
3274
|
+
border-radius: var(--radius-md);
|
|
3275
|
+
background: var(--panel);
|
|
3276
|
+
}
|
|
3277
|
+
|
|
3278
|
+
/* Inside something already bordered. A bordered tile in a bordered row is two
|
|
3279
|
+
boxes saying one thing. */
|
|
3280
|
+
.stat-bare {
|
|
3281
|
+
padding: 0;
|
|
3282
|
+
border: 0;
|
|
3283
|
+
border-radius: 0;
|
|
3284
|
+
background: none;
|
|
3285
|
+
gap: 0;
|
|
3286
|
+
line-height: 1.25;
|
|
3287
|
+
}
|
|
3288
|
+
|
|
3289
|
+
.stat > p { margin: 0; }
|
|
3290
|
+
|
|
3291
|
+
.stat-label {
|
|
3292
|
+
color: var(--muted);
|
|
3293
|
+
font-size: var(--text-xs);
|
|
3294
|
+
}
|
|
3295
|
+
|
|
3296
|
+
/* Tabular figures are the point: a column of numbers is compared by its
|
|
3297
|
+
digits' positions, and proportional ones move them per row. */
|
|
3298
|
+
.stat-value {
|
|
3299
|
+
font-size: var(--text-lg);
|
|
3300
|
+
font-weight: var(--weight-strong);
|
|
3301
|
+
font-variant-numeric: tabular-nums;
|
|
3302
|
+
}
|
|
3303
|
+
|
|
3304
|
+
.stat-bare .stat-value { font-size: var(--text-sm); }
|
|
3305
|
+
|
|
3306
|
+
.stat-note {
|
|
3307
|
+
color: var(--muted);
|
|
3308
|
+
font-size: var(--text-xs);
|
|
3309
|
+
}
|
|
3310
|
+
|
|
3311
|
+
/* Only the figure takes the colour. Colouring the label too makes the tile a
|
|
3312
|
+
status box, and a tone here is a remark about the number. */
|
|
3313
|
+
.stat[data-tone='info'] .stat-value { color: var(--info); }
|
|
3314
|
+
.stat[data-tone='good'] .stat-value { color: var(--good); }
|
|
3315
|
+
.stat[data-tone='warn'] .stat-value { color: var(--warn); }
|
|
3316
|
+
.stat[data-tone='bad'] .stat-value { color: var(--bad); }
|
|
3317
|
+
|
|
3318
|
+
/* ---- ./shell.css ---- */
|
|
3319
|
+
/* The frame. Layout only: every colour and every step is a token, and the
|
|
3320
|
+
page inside it owns its own spacing. */
|
|
3321
|
+
.shell {
|
|
3322
|
+
display: flex;
|
|
3323
|
+
flex-direction: column;
|
|
3324
|
+
min-height: 100vh;
|
|
3325
|
+
background: var(--bg);
|
|
3326
|
+
color: var(--text);
|
|
3327
|
+
}
|
|
3328
|
+
|
|
3329
|
+
.shell-head {
|
|
3330
|
+
border-bottom: var(--border-width) solid var(--border);
|
|
3331
|
+
background: var(--panel);
|
|
3332
|
+
/* `flex: none` so a long page does not squeeze the header. */
|
|
3333
|
+
flex: none;
|
|
3334
|
+
}
|
|
3335
|
+
|
|
3336
|
+
/* The measure, said once. `--shell-measure` rather than a literal so an app
|
|
3337
|
+
with a different one sets a variable instead of overriding three rules and
|
|
3338
|
+
missing the fourth -- which is how manage ended up with `head-inner-wide`
|
|
3339
|
+
and `main-wide` as separate classes. */
|
|
3340
|
+
.shell {
|
|
3341
|
+
--shell-measure: 64rem;
|
|
3342
|
+
--shell-measure-wide: 90rem;
|
|
3343
|
+
}
|
|
3344
|
+
|
|
3345
|
+
.shell-head-inner,
|
|
3346
|
+
.shell-nav,
|
|
3347
|
+
.shell-main {
|
|
3348
|
+
width: 100%;
|
|
3349
|
+
max-width: var(--shell-measure);
|
|
3350
|
+
margin-inline: auto;
|
|
3351
|
+
padding-inline: var(--space-4);
|
|
3352
|
+
}
|
|
3353
|
+
|
|
3354
|
+
.shell-wide { max-width: var(--shell-measure-wide); }
|
|
3355
|
+
|
|
3356
|
+
.shell-head-inner {
|
|
3357
|
+
display: flex;
|
|
3358
|
+
align-items: center;
|
|
3359
|
+
justify-content: space-between;
|
|
3360
|
+
gap: var(--space-4);
|
|
3361
|
+
padding-block: var(--space-3);
|
|
3362
|
+
min-width: 0;
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
.shell-who {
|
|
3366
|
+
display: flex;
|
|
3367
|
+
align-items: center;
|
|
3368
|
+
gap: var(--space-3);
|
|
3369
|
+
min-width: 0;
|
|
3370
|
+
}
|
|
3371
|
+
|
|
3372
|
+
.shell-nav { padding-bottom: var(--space-2); }
|
|
3373
|
+
|
|
3374
|
+
.shell-main {
|
|
3375
|
+
flex: 1;
|
|
3376
|
+
padding-block: var(--space-6);
|
|
3377
|
+
/* `min-width: 0` because a flex child will not shrink below its content,
|
|
3378
|
+
and one wide table inside then pushes the whole page sideways. */
|
|
3379
|
+
min-width: 0;
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
/* The label beside the theme control, when it is drawn. */
|
|
3383
|
+
.theme-switch {
|
|
3384
|
+
display: flex;
|
|
3385
|
+
align-items: center;
|
|
3386
|
+
gap: var(--space-2);
|
|
3387
|
+
min-width: 0;
|
|
3388
|
+
}
|
|
3389
|
+
|
|
3390
|
+
.theme-switch-label {
|
|
3391
|
+
color: var(--muted);
|
|
3392
|
+
font-size: var(--text-sm);
|
|
3393
|
+
white-space: nowrap;
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3150
3396
|
/* ---- ./scrollarea.css ---- */
|
|
3151
3397
|
/* A box that scrolls, with its edges drawn.
|
|
3152
3398
|
|