@wtfalch/design 0.9.0 → 0.9.1
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/Select.js +1 -1
- package/dist/components/SizeGrid.js +6 -2
- package/dist/styles/index.css +122 -36
- package/dist/tf.css +122 -36
- package/dist/valet.css +122 -36
- package/package.json +1 -1
|
@@ -81,5 +81,5 @@ export default function Select({ block = false, size, className, children, value
|
|
|
81
81
|
return (_jsxs(AriaSelect, { className: `sel${block ? ' ctl-block' : ''}${className ? ` ${className}` : ''}`, selectedKey: value !== undefined ? String(value) : undefined, defaultSelectedKey: defaultValue !== undefined ? String(defaultValue) : (options[0]?.value ?? undefined), onSelectionChange: (key) => {
|
|
82
82
|
if (key !== null)
|
|
83
83
|
onChange?.({ target: { value: String(key) } });
|
|
84
|
-
}, isDisabled: disabled, name: name, form: form, "aria-label": ariaLabel, "aria-labelledby": wiredLabelledBy, children: [_jsxs(Button, { ref: control, id: wiredId, "aria-describedby": ariaDescribedBy ?? field?.['aria-describedby'], className: `sel-control${size ? ` size-${size}` : ''}`, children: [_jsx(SelectValue, { className: "sel-value flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: ({ selectedText, defaultChildren }) => selectedText ?? defaultChildren }), _jsx("svg", { className: "sel-caret flex-none opacity-60", viewBox: "0 0 24 24", width: "14", height: "14", "aria-hidden": "true", children: _jsx("path", { fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", d: "m6 9 6 6 6-6" }) })] }), _jsx(Popover, { className: "sel-list z-[60] max-h-[280px] overflow-y-auto m-0 p-1 list-none border border-border-strong rounded-md surface-panel", placement: "bottom start", offset: 4, maxHeight: 280, children: _jsx(ListBox, { children: options.map((o) => (_jsxs(ListBoxItem, { id: o.value, textValue: o.text, isDisabled: o.disabled, className: "sel-item flex items-center gap-2 p-2 rounded-sm cursor-pointer whitespace-nowrap", children: [_jsx("span", { className: "flex-1 min-w-0 overflow-hidden text-ellipsis", children: o.label }), _jsx("svg", { className: "sel-tick flex-none
|
|
84
|
+
}, isDisabled: disabled, name: name, form: form, "aria-label": ariaLabel, "aria-labelledby": wiredLabelledBy, children: [_jsxs(Button, { ref: control, id: wiredId, "aria-describedby": ariaDescribedBy ?? field?.['aria-describedby'], className: `sel-control${size ? ` size-${size}` : ''}`, children: [_jsx(SelectValue, { className: "sel-value flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: ({ selectedText, defaultChildren }) => selectedText ?? defaultChildren }), _jsx("svg", { className: "sel-caret flex-none opacity-60", viewBox: "0 0 24 24", width: "14", height: "14", "aria-hidden": "true", children: _jsx("path", { fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", d: "m6 9 6 6 6-6" }) })] }), _jsx(Popover, { className: "sel-list z-[60] max-h-[280px] overflow-y-auto m-0 p-1 list-none border border-border-strong rounded-md surface-panel", placement: "bottom start", offset: 4, maxHeight: 280, children: _jsx(ListBox, { children: options.map((o) => (_jsxs(ListBoxItem, { id: o.value, textValue: o.text, isDisabled: o.disabled, className: "sel-item flex items-center gap-2 p-2 rounded-sm cursor-pointer whitespace-nowrap", children: [_jsx("span", { className: "flex-1 min-w-0 overflow-hidden text-ellipsis", children: o.label }), _jsx("svg", { className: "sel-tick flex-none", viewBox: "0 0 24 24", width: "13", height: "13", "aria-hidden": "true", children: _jsx("path", { fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", d: "m5 13 4 4 10-10" }) }), aside?.(o.value)] }, o.value))) }) })] }));
|
|
85
85
|
}
|
|
@@ -47,10 +47,14 @@ export default function SizeGrid({ value, max = { cols: 3, rows: 3 }, disabled =
|
|
|
47
47
|
cell with no contents, so it says it is a block rather than
|
|
48
48
|
taking a control's arrangement -- is here. */
|
|
49
49
|
className: [
|
|
50
|
-
|
|
50
|
+
/* Geometry here; colour in `sizegrid.css`. The cell's resting border and
|
|
51
|
+
surface are the thing `on` and `chosen` override, and a utility
|
|
52
|
+
beats a component rule once the sheets are layered -- so stated
|
|
53
|
+
here they would win permanently and no cell would ever light up. */
|
|
54
|
+
'size-cell block w-[18px] h-[14px] p-0 rounded-sm cursor-pointer',
|
|
51
55
|
'disabled:cursor-default disabled:opacity-50',
|
|
52
56
|
on ? 'on' : '',
|
|
53
|
-
chosen && !hover ? '
|
|
57
|
+
chosen && !hover ? 'chosen' : '',
|
|
54
58
|
]
|
|
55
59
|
.filter(Boolean)
|
|
56
60
|
.join(' '), disabled: disabled, "aria-label": `${col} by ${row}`, onMouseEnter: () => !disabled && setHover({ cols: col, rows: row }), onFocus: () => !disabled && setHover({ cols: col, rows: row }), onClick: () => onChange({ cols: col, rows: row }) }, `${col}x${row}`));
|
package/dist/styles/index.css
CHANGED
|
@@ -17,12 +17,9 @@
|
|
|
17
17
|
--font-sans: var(--font-sans);
|
|
18
18
|
--font-mono: var(--font-mono);
|
|
19
19
|
--text-xs: var(--text-xs);
|
|
20
|
-
--text-xs--line-height: inherit;
|
|
21
20
|
--text-sm: var(--text-sm);
|
|
22
|
-
--text-sm--line-height: inherit;
|
|
23
21
|
--text-base: var(--text-base);
|
|
24
22
|
--text-lg: var(--text-lg);
|
|
25
|
-
--text-lg--line-height: inherit;
|
|
26
23
|
--text-xl: var(--text-xl);
|
|
27
24
|
--font-weight-normal: var(--weight);
|
|
28
25
|
--tracking-normal: var(--tracking);
|
|
@@ -37,14 +34,12 @@
|
|
|
37
34
|
--spacing-5: var(--space-5);
|
|
38
35
|
--spacing-6: var(--space-6);
|
|
39
36
|
--spacing-10: var(--space-10);
|
|
40
|
-
--text-2xs--line-height: inherit;
|
|
41
37
|
--text-2xs: var(--text-2xs);
|
|
42
38
|
--text-md: var(--text-md);
|
|
43
39
|
--font-weight-strong: var(--weight-strong);
|
|
44
40
|
--radius-pill: var(--radius-pill);
|
|
45
41
|
--color-text: var(--text);
|
|
46
42
|
--color-muted: var(--muted);
|
|
47
|
-
--color-accent: var(--accent);
|
|
48
43
|
--color-border: var(--border);
|
|
49
44
|
--color-border-strong: var(--border-strong);
|
|
50
45
|
}
|
|
@@ -300,9 +295,6 @@
|
|
|
300
295
|
--tw-border-style: dashed;
|
|
301
296
|
border-style: dashed;
|
|
302
297
|
}
|
|
303
|
-
.border-accent {
|
|
304
|
-
border-color: var(--color-accent);
|
|
305
|
-
}
|
|
306
298
|
.border-border {
|
|
307
299
|
border-color: var(--color-border);
|
|
308
300
|
}
|
|
@@ -353,19 +345,15 @@
|
|
|
353
345
|
}
|
|
354
346
|
.text-2xs {
|
|
355
347
|
font-size: var(--text-2xs);
|
|
356
|
-
line-height: var(--tw-leading, var(--text-2xs--line-height));
|
|
357
348
|
}
|
|
358
349
|
.text-lg {
|
|
359
350
|
font-size: var(--text-lg);
|
|
360
|
-
line-height: var(--tw-leading, var(--text-lg--line-height));
|
|
361
351
|
}
|
|
362
352
|
.text-sm {
|
|
363
353
|
font-size: var(--text-sm);
|
|
364
|
-
line-height: var(--tw-leading, var(--text-sm--line-height));
|
|
365
354
|
}
|
|
366
355
|
.text-xs {
|
|
367
356
|
font-size: var(--text-xs);
|
|
368
|
-
line-height: var(--tw-leading, var(--text-xs--line-height));
|
|
369
357
|
}
|
|
370
358
|
.leading-\[0\] {
|
|
371
359
|
--tw-leading: 0;
|
|
@@ -420,9 +408,6 @@
|
|
|
420
408
|
--tw-numeric-spacing: tabular-nums;
|
|
421
409
|
font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
|
|
422
410
|
}
|
|
423
|
-
.opacity-0 {
|
|
424
|
-
opacity: 0%;
|
|
425
|
-
}
|
|
426
411
|
.opacity-60 {
|
|
427
412
|
opacity: 60%;
|
|
428
413
|
}
|
|
@@ -465,9 +450,6 @@
|
|
|
465
450
|
.surface-panel {
|
|
466
451
|
background: var(--panel);
|
|
467
452
|
}
|
|
468
|
-
.surface-panel-2 {
|
|
469
|
-
background: var(--panel-2);
|
|
470
|
-
}
|
|
471
453
|
.disabled\:cursor-default:disabled {
|
|
472
454
|
cursor: default;
|
|
473
455
|
}
|
|
@@ -707,7 +689,19 @@
|
|
|
707
689
|
}
|
|
708
690
|
}
|
|
709
691
|
|
|
710
|
-
/* ---- ./
|
|
692
|
+
/* ---- ./_system-light.css ---- */
|
|
693
|
+
/* The `system` theme's light half.
|
|
694
|
+
*
|
|
695
|
+
* Its own file, and outside the components layer, because it is a *theme*
|
|
696
|
+
* rather than a component rule. `tokens.css` states the dark base on `:root`
|
|
697
|
+
* and is unlayered; the moment this sat inside `@layer components` it lost to
|
|
698
|
+
* that, and every `system` specimen rendered dark on a light-mode machine.
|
|
699
|
+
* Unlayered beats layered whatever the selector says, which is exactly the
|
|
700
|
+
* trap this repository keeps finding in different costumes.
|
|
701
|
+
*
|
|
702
|
+
* The underscore marks it the same way `_tailwind.built.css` is marked:
|
|
703
|
+
* `copy-css.mjs` passes both through without wrapping them.
|
|
704
|
+
*/
|
|
711
705
|
/* Light, only under the `system` theme. This used to override `:root`
|
|
712
706
|
unconditionally, so choosing a dark theme on a light-mode laptop got
|
|
713
707
|
silently repainted. Every other theme states its own palette. */
|
|
@@ -736,6 +730,8 @@
|
|
|
736
730
|
}
|
|
737
731
|
}
|
|
738
732
|
|
|
733
|
+
/* ---- ./base.css ---- */
|
|
734
|
+
@layer components {
|
|
739
735
|
/* Derived from the two surfaces every theme already defines, so a theme gets a
|
|
740
736
|
control colour without knowing this exists. */
|
|
741
737
|
/* Pseudo-elements too. `*` does not match them, and `box-sizing` is not
|
|
@@ -1596,8 +1592,10 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
1596
1592
|
color: var(--muted);
|
|
1597
1593
|
opacity: 1;
|
|
1598
1594
|
}
|
|
1595
|
+
}
|
|
1599
1596
|
|
|
1600
1597
|
/* ---- ./select.css ---- */
|
|
1598
|
+
@layer components {
|
|
1601
1599
|
/* How big a control is, asked for rather than inherited.
|
|
1602
1600
|
Four sizes existed and every one of them came from a descendant selector:
|
|
1603
1601
|
`.set-row button` was 11px in 3px of padding, `.approval-actions button` was
|
|
@@ -1692,16 +1690,19 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
1692
1690
|
/* State is read off React Aria's attributes: `data-open` on the root,
|
|
1693
1691
|
`data-focused` / `data-selected` / `data-disabled` on an item, where
|
|
1694
1692
|
`.open`, `[data-active]`, `.on` and `.off` used to be. */
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1693
|
+
/* The list keeps two things the utilities on `Select` cannot say.
|
|
1694
|
+
*
|
|
1695
|
+
* `scroll-padding-block`: the same room while the list is scrolled as it has
|
|
1696
|
+
* at rest. Padding at the top of a scroll container scrolls away with the
|
|
1697
|
+
* content, so the row `scrollIntoView({block: 'nearest'})` brings up ended
|
|
1698
|
+
* flush against the border and read as clipped rather than as one of a set --
|
|
1699
|
+
* and this list opens scrolled to whatever is chosen, so that was the
|
|
1700
|
+
* ordinary state.
|
|
1701
|
+
*
|
|
1702
|
+
* `box-shadow`: `--shadow-2` is a token, and a utility would have to inline
|
|
1703
|
+
* the value, which is the one thing the vocabulary exists to stop. */
|
|
1704
|
+
.sel-list {
|
|
1700
1705
|
scroll-padding-block: var(--space-1);
|
|
1701
|
-
list-style: none;
|
|
1702
|
-
border: var(--border-width) solid var(--border-strong);
|
|
1703
|
-
border-radius: var(--radius-md);
|
|
1704
|
-
background: var(--panel);
|
|
1705
1706
|
box-shadow: var(--shadow-2);
|
|
1706
1707
|
}
|
|
1707
1708
|
|
|
@@ -1716,6 +1717,19 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
1716
1717
|
|
|
1717
1718
|
/* The tick marks the chosen row. Colour alone would not: a list where the only
|
|
1718
1719
|
difference is a hue is a list you cannot read past. */
|
|
1720
|
+
/* The tick's resting state lives here, beside the state that overrides it.
|
|
1721
|
+
*
|
|
1722
|
+
* It was `opacity-0` on the element and `opacity: 1` here, which worked only
|
|
1723
|
+
* while this sheet was unlayered. A utility is in `@layer utilities` and
|
|
1724
|
+
* beats `@layer components` whatever the selector, so the moment the sheets
|
|
1725
|
+
* moved into a layer the tick stopped appearing on the selected row -- the
|
|
1726
|
+
* resting state won permanently.
|
|
1727
|
+
*
|
|
1728
|
+
* The rule generalises: a utility for a resting state whose active state is a
|
|
1729
|
+
* relationship between elements will always beat that active state. The pair
|
|
1730
|
+
* has to sit in the same layer. */
|
|
1731
|
+
.sel-tick { opacity: 0; }
|
|
1732
|
+
|
|
1719
1733
|
.sel-item[data-selected] .sel-tick { opacity: 1; }
|
|
1720
1734
|
|
|
1721
1735
|
/* The icon on a speaker's row in the open list -- `Select`'s `aside`. Last in
|
|
@@ -1750,8 +1764,10 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
1750
1764
|
.field > input,
|
|
1751
1765
|
.field > textarea,
|
|
1752
1766
|
.field > .sel { width: 100%; }
|
|
1767
|
+
}
|
|
1753
1768
|
|
|
1754
1769
|
/* ---- ./dangerzone.css ---- */
|
|
1770
|
+
@layer components {
|
|
1755
1771
|
/* Destructive, and legible as such standing still. */
|
|
1756
1772
|
.btn.danger {
|
|
1757
1773
|
color: var(--bad);
|
|
@@ -1863,8 +1879,10 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
1863
1879
|
controls in the same column at the same indent that do not line up read as
|
|
1864
1880
|
an accident rather than as a pair. */
|
|
1865
1881
|
.field-row > button { min-width: 9ch; }
|
|
1882
|
+
}
|
|
1866
1883
|
|
|
1867
1884
|
/* ---- ./callout.css ---- */
|
|
1885
|
+
@layer components {
|
|
1868
1886
|
/* One shape for everything that tells you something.
|
|
1869
1887
|
`.banner` and `.callout` were the same box drawn twice: a bordered, rounded,
|
|
1870
1888
|
12px panel with a tint. They differed in padding by a pixel in each direction
|
|
@@ -2003,8 +2021,10 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
2003
2021
|
}
|
|
2004
2022
|
|
|
2005
2023
|
.callout button { flex: none; }
|
|
2024
|
+
}
|
|
2006
2025
|
|
|
2007
2026
|
/* ---- ./card.css ---- */
|
|
2027
|
+
@layer components {
|
|
2008
2028
|
/* `.card` is public API, not this component's private styling.
|
|
2009
2029
|
*
|
|
2010
2030
|
* Consumers apply it to their own markup -- the gallery's skeleton specimen
|
|
@@ -2146,8 +2166,10 @@ input:active, textarea:active, select:active { transform: none; }
|
|
|
2146
2166
|
}
|
|
2147
2167
|
|
|
2148
2168
|
.card[aria-pressed='true']:hover { border-color: var(--accent); }
|
|
2169
|
+
}
|
|
2149
2170
|
|
|
2150
2171
|
/* ---- ./toggle.css ---- */
|
|
2172
|
+
@layer components {
|
|
2151
2173
|
.card-action .switch-row { padding: 0; gap: var(--space-2); }
|
|
2152
2174
|
|
|
2153
2175
|
.card-action .switch-row .switch-body { flex: none; }
|
|
@@ -2378,8 +2400,10 @@ input[type='radio']:active:not(:disabled) {
|
|
|
2378
2400
|
@media (prefers-reduced-motion: reduce) {
|
|
2379
2401
|
.toggle-sweep::before { animation: none; background: color-mix(in oklab, var(--accent) 45%, transparent); }
|
|
2380
2402
|
}
|
|
2403
|
+
}
|
|
2381
2404
|
|
|
2382
2405
|
/* ---- ./skeleton.css ---- */
|
|
2406
|
+
@layer components {
|
|
2383
2407
|
.muted { color: var(--muted); }
|
|
2384
2408
|
|
|
2385
2409
|
.pulse-block {
|
|
@@ -2434,8 +2458,10 @@ input[type='radio']:active:not(:disabled) {
|
|
|
2434
2458
|
/* Still distinguishable from a real block of colour, and still still. */
|
|
2435
2459
|
.skel-pulse { animation: none; opacity: 0.8; }
|
|
2436
2460
|
}
|
|
2461
|
+
}
|
|
2437
2462
|
|
|
2438
2463
|
/* ---- ./rows.css ---- */
|
|
2464
|
+
@layer components {
|
|
2439
2465
|
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2440
2466
|
|
|
2441
2467
|
/* A name and the pills that qualify it, on one line, where the name is the only
|
|
@@ -2696,8 +2722,10 @@ input[type='radio']:active:not(:disabled) {
|
|
|
2696
2722
|
.row-hit:hover .truncate { color: var(--accent); }
|
|
2697
2723
|
|
|
2698
2724
|
.row-hit:focus-visible { outline: none; box-shadow: var(--focus-ring); }
|
|
2725
|
+
}
|
|
2699
2726
|
|
|
2700
2727
|
/* ---- ./progress.css ---- */
|
|
2728
|
+
@layer components {
|
|
2701
2729
|
/* progress ----------------------------------------------------------- */
|
|
2702
2730
|
|
|
2703
2731
|
/* The bar itself: a track with a child it fills, an animation and a
|
|
@@ -2739,8 +2767,10 @@ input[type='radio']:active:not(:disabled) {
|
|
|
2739
2767
|
/* Still distinguishable from empty, and from full. */
|
|
2740
2768
|
.bar-indeterminate > i { animation: none; width: 100%; opacity: 0.35; }
|
|
2741
2769
|
}
|
|
2770
|
+
}
|
|
2742
2771
|
|
|
2743
2772
|
/* ---- ./tabs.css ---- */
|
|
2773
|
+
@layer components {
|
|
2744
2774
|
/* ---------------------------------------------------------------- tabs */
|
|
2745
2775
|
.tabs { position: relative; display: flex; gap: var(--space-1); }
|
|
2746
2776
|
|
|
@@ -2841,8 +2871,10 @@ input[type='radio']:active:not(:disabled) {
|
|
|
2841
2871
|
}
|
|
2842
2872
|
|
|
2843
2873
|
.tabs-vertical .tab:active:not(:disabled) { border-color: transparent; }
|
|
2874
|
+
}
|
|
2844
2875
|
|
|
2845
2876
|
/* ---- ./toast.css ---- */
|
|
2877
|
+
@layer components {
|
|
2846
2878
|
/* ---------------------------------------------------------------- toasts */
|
|
2847
2879
|
.toasts {
|
|
2848
2880
|
position: fixed;
|
|
@@ -2940,8 +2972,10 @@ input[type='radio']:active:not(:disabled) {
|
|
|
2940
2972
|
outline: 2px solid var(--accent);
|
|
2941
2973
|
outline-offset: 2px;
|
|
2942
2974
|
}
|
|
2975
|
+
}
|
|
2943
2976
|
|
|
2944
2977
|
/* ---- ./modal.css ---- */
|
|
2978
|
+
@layer components {
|
|
2945
2979
|
/* modal --------------------------------------------------------------- */
|
|
2946
2980
|
|
|
2947
2981
|
/* `hidden` needs saying out loud here. The browser's own `[hidden]` rule is a
|
|
@@ -3172,8 +3206,10 @@ input[type='radio']:active:not(:disabled) {
|
|
|
3172
3206
|
.modal.sheet[data-entering],
|
|
3173
3207
|
.modal.sheet[data-exiting] { animation: none; }
|
|
3174
3208
|
}
|
|
3209
|
+
}
|
|
3175
3210
|
|
|
3176
3211
|
/* ---- ./slider.css ---- */
|
|
3212
|
+
@layer components {
|
|
3177
3213
|
/* slider ----------------------------------------------------------------- */
|
|
3178
3214
|
/* A number from a range -- `Slider.tsx` says when one is the right control.
|
|
3179
3215
|
The row is laid out like a switch row: words on the left, the control on the
|
|
@@ -3395,8 +3431,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3395
3431
|
the scale, and the two line up; an explicit `size-*` still wins. */
|
|
3396
3432
|
:where(.set-row) button,
|
|
3397
3433
|
:where(.set-row) .slider-box { font-size: var(--text-xs); }
|
|
3434
|
+
}
|
|
3398
3435
|
|
|
3399
3436
|
/* ---- ./checkbox.css ---- */
|
|
3437
|
+
@layer components {
|
|
3400
3438
|
/* A row you choose. There is no checkbox in it.
|
|
3401
3439
|
Every one of the fourteen in this app sits beside a name and a line of
|
|
3402
3440
|
explanation, so the row was always the thing being designed and the 17px
|
|
@@ -3566,8 +3604,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3566
3604
|
.choice[data-disabled] .choice-why { opacity: 0.5; }
|
|
3567
3605
|
|
|
3568
3606
|
.choice[data-disabled]::after { opacity: 0.4; }
|
|
3607
|
+
}
|
|
3569
3608
|
|
|
3570
3609
|
/* ---- ./table.css ---- */
|
|
3610
|
+
@layer components {
|
|
3571
3611
|
/* A second line under a row's name, inside the `<th scope="row">` that makes it
|
|
3572
3612
|
one. The cell is bold because it is a heading; what hangs under it is not,
|
|
3573
3613
|
and inherited the weight -- so a pinned version read as loud as the thing it
|
|
@@ -3615,27 +3655,48 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3615
3655
|
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
|
|
3616
3656
|
|
|
3617
3657
|
.data-table thead th[style*='right'] { text-align: right; }
|
|
3658
|
+
}
|
|
3618
3659
|
|
|
3619
3660
|
/* ---- ./sizegrid.css ---- */
|
|
3620
|
-
|
|
3661
|
+
@layer components {
|
|
3662
|
+
/* The cell's colour, all of it, in one place.
|
|
3663
|
+
*
|
|
3664
|
+
* `SizeGrid` draws the cell's geometry with utilities and leaves every colour
|
|
3665
|
+
* here, because `on` and `chosen` override the resting state -- and a utility
|
|
3666
|
+
* is in `@layer utilities`, which beats `@layer components` whatever the
|
|
3667
|
+
* selector. Stated as `surface-panel-2` and `border-border` on the element,
|
|
3668
|
+
* the resting state won permanently and no cell ever lit up.
|
|
3621
3669
|
*
|
|
3622
|
-
*
|
|
3623
|
-
*
|
|
3624
|
-
*
|
|
3625
|
-
|
|
3626
|
-
|
|
3670
|
+
* That is the third time this pattern has bitten: `Select`'s tick and
|
|
3671
|
+
* `Empty`'s figure were the other two. The rule: a resting state whose
|
|
3672
|
+
* active state is a CSS rule has to be a CSS rule too. */
|
|
3673
|
+
.size-cell {
|
|
3674
|
+
border: var(--border-width) solid var(--border);
|
|
3675
|
+
background: var(--panel-2);
|
|
3676
|
+
}
|
|
3677
|
+
|
|
3678
|
+
/* `on` follows the pointer; `chosen` is what is actually saved, shown only
|
|
3679
|
+
when nothing is hovered so the two can never contradict each other. */
|
|
3627
3680
|
.size-cell.on {
|
|
3628
3681
|
border-color: var(--accent);
|
|
3629
3682
|
background: color-mix(in srgb, var(--accent) 45%, transparent);
|
|
3630
3683
|
}
|
|
3631
3684
|
|
|
3685
|
+
.size-cell.chosen { border-color: var(--accent); }
|
|
3686
|
+
}
|
|
3687
|
+
|
|
3632
3688
|
/* ---- ./tooltip.css ---- */
|
|
3689
|
+
@layer components {
|
|
3633
3690
|
/* A callout: something worth knowing, with nothing to answer. Distinct from a
|
|
3634
3691
|
`?`, which is an offer to read more, and from a banner, which is a problem.
|
|
3635
3692
|
The mark is a round `i` rather than an emoji so it takes the theme's colours
|
|
3636
3693
|
and stays the same size as the text beside it. */
|
|
3637
|
-
/* An info-toned `.callout`, spelled the old way. Identical to it now rather
|
|
3638
|
-
nearly identical to it, which is the whole point of the consolidation
|
|
3694
|
+
/* An info-toned `.callout`, spelled the old way. Identical to it now rather
|
|
3695
|
+
than nearly identical to it, which is the whole point of the consolidation.
|
|
3696
|
+
(This comment has been unterminated since before the Tailwind branch -- it
|
|
3697
|
+
stops mid-sentence and never closes, so the CSS parser merged it with the
|
|
3698
|
+
one below and recovered. Nothing was lost from the stylesheet; the rest of
|
|
3699
|
+
the sentence was. Closed here rather than guessed at.) */
|
|
3639
3700
|
|
|
3640
3701
|
/* What is left once `Tooltip` draws its own mark: the hover and focus that
|
|
3641
3702
|
reach the mark from its parent, and the tip -- whose closed and open
|
|
@@ -3718,8 +3779,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3718
3779
|
}
|
|
3719
3780
|
|
|
3720
3781
|
.explain-tip strong { color: var(--text); font-weight: 600; }
|
|
3782
|
+
}
|
|
3721
3783
|
|
|
3722
3784
|
/* ---- ./illustration.css ---- */
|
|
3785
|
+
@layer components {
|
|
3723
3786
|
/* illustrations -------------------------------------------------------- */
|
|
3724
3787
|
|
|
3725
3788
|
/* Open Peeps, two colours, wearing whatever the theme is.
|
|
@@ -3757,8 +3820,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3757
3820
|
* original rule already carried a note about needing two classes to beat
|
|
3758
3821
|
* `.illo`; layers make that impossible rather than merely fiddly. */
|
|
3759
3822
|
.nothing-figure { color: var(--muted); }
|
|
3823
|
+
}
|
|
3760
3824
|
|
|
3761
3825
|
/* ---- ./field.css ---- */
|
|
3826
|
+
@layer components {
|
|
3762
3827
|
/* fields --------------------------------------------------------------- */
|
|
3763
3828
|
|
|
3764
3829
|
/* Label, description, input, error -- in the order they are wanted. The
|
|
@@ -3933,8 +3998,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3933
3998
|
background: var(--panel-2);
|
|
3934
3999
|
color: var(--text);
|
|
3935
4000
|
}
|
|
4001
|
+
}
|
|
3936
4002
|
|
|
3937
4003
|
/* ---- ./tour.css ---- */
|
|
4004
|
+
@layer components {
|
|
3938
4005
|
/* tour ----------------------------------------------------------------- */
|
|
3939
4006
|
|
|
3940
4007
|
/* The layer sits over everything and catches nothing: the scrim is painted by
|
|
@@ -3996,12 +4063,14 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
3996
4063
|
.tour-actions { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); }
|
|
3997
4064
|
|
|
3998
4065
|
.tour-count { color: var(--muted); font-size: var(--text-xs); }
|
|
4066
|
+
}
|
|
3999
4067
|
|
|
4000
4068
|
/* The mail and forum shell, added in 0.4.0. After the rest, because the
|
|
4001
4069
|
anchored surfaces (`.pop`, `.menu-sheet`, `.cmd`) sit over everything and a
|
|
4002
4070
|
rule of equal specificity that came earlier would lose to whatever the
|
|
4003
4071
|
sheets they cover happen to set. */
|
|
4004
4072
|
/* ---- ./stat.css ---- */
|
|
4073
|
+
@layer components {
|
|
4005
4074
|
/* What the utilities on `Stat` cannot say: a tone on the tile colouring the
|
|
4006
4075
|
figure inside it. An attribute on the parent selecting a child is a
|
|
4007
4076
|
relationship; a utility is a property on one element.
|
|
@@ -4012,8 +4081,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
4012
4081
|
.stat[data-tone='good'] .stat-value { color: var(--good); }
|
|
4013
4082
|
.stat[data-tone='warn'] .stat-value { color: var(--warn); }
|
|
4014
4083
|
.stat[data-tone='bad'] .stat-value { color: var(--bad); }
|
|
4084
|
+
}
|
|
4015
4085
|
|
|
4016
4086
|
/* ---- ./shell.css ---- */
|
|
4087
|
+
@layer components {
|
|
4017
4088
|
/* The measure, and only the measure.
|
|
4018
4089
|
*
|
|
4019
4090
|
* `Shell` draws itself with utilities -- it is layout and nothing else. What
|
|
@@ -4040,8 +4111,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
4040
4111
|
font-size: var(--text-sm);
|
|
4041
4112
|
white-space: nowrap;
|
|
4042
4113
|
}
|
|
4114
|
+
}
|
|
4043
4115
|
|
|
4044
4116
|
/* ---- ./scrollarea.css ---- */
|
|
4117
|
+
@layer components {
|
|
4045
4118
|
/* A box that scrolls, with its edges drawn.
|
|
4046
4119
|
|
|
4047
4120
|
The fades are `::before`/`::after` on the scroller itself, pinned with
|
|
@@ -4134,8 +4207,10 @@ input[type='range'].slider:disabled::-moz-range-thumb { opacity: 0; }
|
|
|
4134
4207
|
.scroller.faded::before,
|
|
4135
4208
|
.scroller.faded::after { transition: none; }
|
|
4136
4209
|
}
|
|
4210
|
+
}
|
|
4137
4211
|
|
|
4138
4212
|
/* ---- ./splitpane.css ---- */
|
|
4213
|
+
@layer components {
|
|
4139
4214
|
/* Two panes and the handle between them. */
|
|
4140
4215
|
.split {
|
|
4141
4216
|
display: flex;
|
|
@@ -4235,8 +4310,10 @@ body.splitting * { cursor: inherit !important; }
|
|
|
4235
4310
|
@media (prefers-reduced-motion: reduce) {
|
|
4236
4311
|
.split-grip { transition: none; }
|
|
4237
4312
|
}
|
|
4313
|
+
}
|
|
4238
4314
|
|
|
4239
4315
|
/* ---- ./popover.css ---- */
|
|
4316
|
+
@layer components {
|
|
4240
4317
|
/* A small surface anchored to what opened it. Same sheet as the select's list,
|
|
4241
4318
|
because they are the same object -- something that appeared over the page,
|
|
4242
4319
|
attached to a control. */
|
|
@@ -4290,8 +4367,10 @@ body.splitting * { cursor: inherit !important; }
|
|
|
4290
4367
|
.pop[data-entering],
|
|
4291
4368
|
.pop[data-exiting] { animation: none; }
|
|
4292
4369
|
}
|
|
4370
|
+
}
|
|
4293
4371
|
|
|
4294
4372
|
/* ---- ./menu.css ---- */
|
|
4373
|
+
@layer components {
|
|
4295
4374
|
/* What is left once `Menu` draws its sheet and its list: the rows, whose
|
|
4296
4375
|
`data-focused`, `data-pressed` and danger states React Aria stamps on
|
|
4297
4376
|
them, and the rules that reach from a row into what it holds. The
|
|
@@ -4373,8 +4452,10 @@ body.splitting * { cursor: inherit !important; }
|
|
|
4373
4452
|
}
|
|
4374
4453
|
|
|
4375
4454
|
.menu-sheet { box-shadow: var(--shadow-2); }
|
|
4455
|
+
}
|
|
4376
4456
|
|
|
4377
4457
|
/* ---- ./command.css ---- */
|
|
4458
|
+
@layer components {
|
|
4378
4459
|
/* The command palette: a field over the app and a list under it. */
|
|
4379
4460
|
.cmd-scrim {
|
|
4380
4461
|
position: fixed;
|
|
@@ -4516,8 +4597,10 @@ body.splitting * { cursor: inherit !important; }
|
|
|
4516
4597
|
.cmd-scrim[data-exiting],
|
|
4517
4598
|
.cmd[data-entering] { animation: none; }
|
|
4518
4599
|
}
|
|
4600
|
+
}
|
|
4519
4601
|
|
|
4520
4602
|
/* ---- ./pagination.css ---- */
|
|
4603
|
+
@layer components {
|
|
4521
4604
|
/* What is left once `Pagination` draws its own frame: the step and page
|
|
4522
4605
|
buttons, whose hover, focus-visible and current states are pseudo-classes
|
|
4523
4606
|
on two selectors at once, and `.pager-count strong`, which reaches into
|
|
@@ -4636,8 +4719,10 @@ body.splitting * { cursor: inherit !important; }
|
|
|
4636
4719
|
.pager-page,
|
|
4637
4720
|
.pager-jump { transition: none; }
|
|
4638
4721
|
}
|
|
4722
|
+
}
|
|
4639
4723
|
|
|
4640
4724
|
/* ---- ./identity.css ---- */
|
|
4725
|
+
@layer components {
|
|
4641
4726
|
/* A person, said in one line: initials, name, sometimes the address. */
|
|
4642
4727
|
.ident {
|
|
4643
4728
|
display: inline-flex;
|
|
@@ -4738,4 +4823,5 @@ body.splitting * { cursor: inherit !important; }
|
|
|
4738
4823
|
|
|
4739
4824
|
.ident-remove:hover { background: var(--panel); color: var(--text); }
|
|
4740
4825
|
.ident-remove:focus-visible { outline: none; box-shadow: var(--focus-ring); }
|
|
4826
|
+
}
|
|
4741
4827
|
|