@gjermundgaraba-designs/pixel-paper 0.22.2 → 0.23.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/DESIGN.md +13 -13
- package/dist/src/adapters/mermaid.d.ts.map +1 -1
- package/dist/src/adapters/mermaid.js +0 -24
- package/dist/src/announcer/announcer.d.ts.map +1 -1
- package/dist/src/announcer/announcer.js +12 -12
- package/dist/src/board/board.d.ts +0 -10
- package/dist/src/board/board.d.ts.map +1 -1
- package/dist/src/board/board.js +36 -64
- package/dist/src/board/index.d.ts +2 -1
- package/dist/src/board/index.d.ts.map +1 -1
- package/dist/src/board/index.js +2 -1
- package/dist/src/button/button.d.ts +1 -1
- package/dist/src/button/button.d.ts.map +1 -1
- package/dist/src/commandPalette/commandPalette.d.ts.map +1 -1
- package/dist/src/commandPalette/commandPalette.js +78 -83
- package/dist/src/commandPalette/keys.d.ts +2 -2
- package/dist/src/commandPalette/keys.d.ts.map +1 -1
- package/dist/src/commandPalette/keys.js +2 -4
- package/dist/src/commandPalette/match.d.ts.map +1 -1
- package/dist/src/commandPalette/match.js +2 -2
- package/dist/src/confirmDialog/confirmDialog.d.ts.map +1 -1
- package/dist/src/confirmDialog/confirmDialog.js +1 -2
- package/dist/src/copyButton/copyButton.d.ts +0 -5
- package/dist/src/copyButton/copyButton.d.ts.map +1 -1
- package/dist/src/copyButton/copyButton.js +2 -2
- package/dist/src/crumbs/crumbs.d.ts +0 -2
- package/dist/src/crumbs/crumbs.d.ts.map +1 -1
- package/dist/src/crumbs/crumbs.js +2 -2
- package/dist/src/dialog/dialog.d.ts +2 -0
- package/dist/src/dialog/dialog.d.ts.map +1 -1
- package/dist/src/dialog/dialog.js +3 -2
- package/dist/src/drag/drag.d.ts +28 -0
- package/dist/src/drag/drag.d.ts.map +1 -1
- package/dist/src/drag/drag.js +39 -17
- package/dist/src/editableTitle/editableTitle.d.ts +4 -4
- package/dist/src/field/field.d.ts +7 -1
- package/dist/src/field/field.d.ts.map +1 -1
- package/dist/src/field/field.js +14 -6
- package/dist/src/fieldset/fieldset.d.ts.map +1 -1
- package/dist/src/fieldset/fieldset.js +2 -4
- package/dist/src/fileTree/fileTree.d.ts.map +1 -1
- package/dist/src/fileTree/fileTree.js +16 -16
- package/dist/src/inlineInput/inlineInput.d.ts +4 -0
- package/dist/src/inlineInput/inlineInput.d.ts.map +1 -1
- package/dist/src/inlineInput/inlineInput.js +9 -6
- package/dist/src/keyHelp/index.d.ts +1 -1
- package/dist/src/keyHelp/index.d.ts.map +1 -1
- package/dist/src/keyHelp/index.js +1 -1
- package/dist/src/keyHelp/keyHelp.d.ts +1 -3
- package/dist/src/keyHelp/keyHelp.d.ts.map +1 -1
- package/dist/src/keyHelp/keyHelp.js +3 -6
- package/dist/src/keyHint/keyLabel.d.ts +2 -0
- package/dist/src/keyHint/keyLabel.d.ts.map +1 -1
- package/dist/src/keyHint/keyLabel.js +3 -2
- package/dist/src/lineDiff/diff.d.ts +6 -3
- package/dist/src/lineDiff/diff.d.ts.map +1 -1
- package/dist/src/lineDiff/diff.js +40 -28
- package/dist/src/lineDiff/patch.d.ts.map +1 -1
- package/dist/src/lineDiff/patch.js +18 -13
- package/dist/src/linkState/linkState.d.ts.map +1 -1
- package/dist/src/linkState/linkState.js +1 -7
- package/dist/src/menu/slip.js +2 -2
- package/dist/src/meter/meter.d.ts.map +1 -1
- package/dist/src/meter/meter.js +22 -17
- package/dist/src/notice/notice.d.ts +2 -0
- package/dist/src/notice/notice.d.ts.map +1 -1
- package/dist/src/notice/notice.js +2 -1
- package/dist/src/passwordField/passwordField.d.ts.map +1 -1
- package/dist/src/passwordField/passwordField.js +3 -7
- package/dist/src/rail/rail.d.ts +17 -3
- package/dist/src/rail/rail.d.ts.map +1 -1
- package/dist/src/rail/rail.js +6 -6
- package/dist/src/reel/layout.d.ts +9 -5
- package/dist/src/reel/layout.d.ts.map +1 -1
- package/dist/src/reel/layout.js +11 -5
- package/dist/src/reel/reel.d.ts.map +1 -1
- package/dist/src/reel/reel.js +122 -68
- package/dist/src/scheme/scheme.d.ts +1 -1
- package/dist/src/scheme/scheme.d.ts.map +1 -1
- package/dist/src/segmented/segmented.d.ts +0 -3
- package/dist/src/segmented/segmented.d.ts.map +1 -1
- package/dist/src/segmented/segmented.js +1 -6
- package/dist/src/selectField/selectField.d.ts.map +1 -1
- package/dist/src/selectField/selectField.js +3 -10
- package/dist/src/sortable/index.d.ts +1 -1
- package/dist/src/sortable/index.d.ts.map +1 -1
- package/dist/src/sortable/index.js +1 -1
- package/dist/src/sortable/sortable.d.ts +39 -40
- package/dist/src/sortable/sortable.d.ts.map +1 -1
- package/dist/src/sortable/sortable.js +14 -31
- package/dist/src/stack/stack.d.ts +1 -1
- package/dist/src/stack/stack.d.ts.map +1 -1
- package/dist/src/stack/stack.js +1 -1
- package/dist/src/tabs/tabs.d.ts +1 -1
- package/dist/src/tabs/tabs.d.ts.map +1 -1
- package/dist/src/tabs/tabs.js +1 -1
- package/dist/src/textareaField/textareaField.d.ts.map +1 -1
- package/dist/src/textareaField/textareaField.js +3 -7
- package/dist/src/time/time.d.ts.map +1 -1
- package/dist/src/time/time.js +4 -2
- package/dist/src/tips/index.d.ts +1 -1
- package/dist/src/tips/index.d.ts.map +1 -1
- package/dist/src/toast/index.d.ts +1 -1
- package/dist/src/toast/index.d.ts.map +1 -1
- package/dist/src/toast/toast.d.ts +5 -5
- package/dist/src/toast/toast.d.ts.map +1 -1
- package/dist/src/toast/toast.js +1 -6
- package/dist/src/toolbar/toolbar.d.ts +0 -3
- package/dist/src/toolbar/toolbar.d.ts.map +1 -1
- package/dist/src/toolbar/toolbar.js +1 -2
- package/package.json +1 -1
- package/src/adapters/mermaid.ts +0 -24
- package/src/announcer/announcer.ts +13 -17
- package/src/board/board.ts +32 -80
- package/src/board/index.ts +1 -1
- package/src/button/button.ts +1 -1
- package/src/commandPalette/commandPalette.ts +21 -38
- package/src/commandPalette/keys.ts +2 -4
- package/src/commandPalette/match.ts +3 -3
- package/src/confirmDialog/confirmDialog.ts +5 -3
- package/src/copyButton/copyButton.ts +2 -5
- package/src/crumbs/crumbs.ts +2 -4
- package/src/dialog/dialog.ts +3 -2
- package/src/drag/drag.ts +54 -5
- package/src/field/field.ts +29 -7
- package/src/fieldset/fieldset.ts +2 -4
- package/src/fileTree/fileTree.ts +10 -12
- package/src/inlineInput/inlineInput.ts +11 -2
- package/src/keyHelp/index.ts +0 -1
- package/src/keyHelp/keyHelp.ts +3 -9
- package/src/keyHint/keyLabel.ts +5 -2
- package/src/lineDiff/diff.ts +70 -54
- package/src/lineDiff/patch.ts +27 -14
- package/src/linkState/linkState.ts +1 -8
- package/src/menu/slip.ts +2 -2
- package/src/meter/meter.ts +25 -15
- package/src/notice/notice.ts +2 -1
- package/src/passwordField/passwordField.ts +3 -7
- package/src/pixel-paper.css +82 -131
- package/src/rail/rail.ts +8 -6
- package/src/reel/layout.ts +14 -7
- package/src/reel/reel.ts +132 -63
- package/src/scheme/scheme.ts +1 -1
- package/src/segmented/segmented.ts +1 -9
- package/src/selectField/selectField.ts +3 -10
- package/src/sortable/index.ts +0 -1
- package/src/sortable/sortable.ts +35 -54
- package/src/stack/stack.ts +1 -1
- package/src/tabs/tabs.ts +1 -1
- package/src/textareaField/textareaField.ts +3 -7
- package/src/time/time.ts +6 -7
- package/src/tips/index.ts +1 -1
- package/src/toast/index.ts +1 -1
- package/src/toast/toast.ts +2 -8
- package/src/tokens.css +6 -0
- package/src/toolbar/toolbar.ts +0 -5
- package/dist/src/inlineInput/inline.d.ts +0 -6
- package/dist/src/inlineInput/inline.d.ts.map +0 -1
- package/dist/src/inlineInput/inline.js +0 -7
- package/src/inlineInput/inline.ts +0 -13
package/src/meter/meter.ts
CHANGED
|
@@ -105,32 +105,41 @@ const numbersText = (value: number, max: number, unit: string | undefined): stri
|
|
|
105
105
|
return unit === undefined ? numbers : `${numbers} ${unit}`;
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
/** How high a reading is: full at `max`, high from `HIGH_SHARE` of it, calm below. The
|
|
109
|
+
* percentage and a toned meter's cells both print it. */
|
|
110
|
+
type Level = "Full" | "High" | "Calm";
|
|
111
|
+
|
|
112
|
+
const levelOf = (value: number, max: number): Level => {
|
|
113
|
+
if (value >= max) {
|
|
114
|
+
return "Full";
|
|
115
|
+
} else if (value >= max * HIGH_SHARE) {
|
|
116
|
+
return "High";
|
|
117
|
+
} else {
|
|
118
|
+
return "Calm";
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
108
122
|
const percentView = <Message>(
|
|
109
123
|
config: MeterConfig,
|
|
110
124
|
percent: number,
|
|
111
|
-
|
|
125
|
+
level: Level,
|
|
112
126
|
h: HtmlBuilder<Message>,
|
|
113
127
|
): Html => {
|
|
114
128
|
const percentText = `${percent}%`;
|
|
115
|
-
const high = config.max * HIGH_SHARE;
|
|
116
129
|
|
|
117
|
-
if (
|
|
130
|
+
if (level === "Full") {
|
|
118
131
|
return Chip.view({ label: config.full ?? percentText, tone: "Blocked" }, h);
|
|
119
|
-
} else if (
|
|
132
|
+
} else if (level === "High") {
|
|
120
133
|
return Mark.readingView({ label: percentText }, h);
|
|
121
134
|
} else {
|
|
122
135
|
return h.span([h.Class("pct")], [percentText]);
|
|
123
136
|
}
|
|
124
137
|
};
|
|
125
138
|
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return " toned high";
|
|
131
|
-
} else {
|
|
132
|
-
return " toned";
|
|
133
|
-
}
|
|
139
|
+
const TONE_CLASS: Readonly<Record<Level, string>> = {
|
|
140
|
+
Full: " toned full",
|
|
141
|
+
High: " toned high",
|
|
142
|
+
Calm: " toned",
|
|
134
143
|
};
|
|
135
144
|
|
|
136
145
|
const meterView = <Message>(config: MeterConfig, h: HtmlBuilder<Message>): Html => {
|
|
@@ -146,9 +155,10 @@ const meterView = <Message>(config: MeterConfig, h: HtmlBuilder<Message>): Html
|
|
|
146
155
|
isToned = false,
|
|
147
156
|
} = config;
|
|
148
157
|
const share = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;
|
|
149
|
-
const
|
|
158
|
+
const level = levelOf(value, max);
|
|
159
|
+
const isFull = level === "Full";
|
|
150
160
|
const numbers = config.valueText ?? numbersText(value, max, config.unit);
|
|
151
|
-
const rowClass = `meter-row${isStale ? " stale" : ""}${isToned ?
|
|
161
|
+
const rowClass = `meter-row${isStale ? " stale" : ""}${isToned ? TONE_CLASS[level] : ""}`;
|
|
152
162
|
|
|
153
163
|
return UiMeter.view(
|
|
154
164
|
{
|
|
@@ -179,7 +189,7 @@ const meterView = <Message>(config: MeterConfig, h: HtmlBuilder<Message>): Html
|
|
|
179
189
|
[...groups.meter, h.Class("cells")],
|
|
180
190
|
cellRowView(METER_CELLS, scaled(share, METER_CELLS, isFull), h),
|
|
181
191
|
),
|
|
182
|
-
percentView(config, scaled(share, PERCENT, isFull),
|
|
192
|
+
percentView(config, scaled(share, PERCENT, isFull), level, h),
|
|
183
193
|
...(hasNumbers ? [h.span([h.Class("meter-num tnum")], [numbers])] : []),
|
|
184
194
|
],
|
|
185
195
|
),
|
package/src/notice/notice.ts
CHANGED
|
@@ -22,7 +22,8 @@ const toneGlyph = (tone: Tone): GlyphName =>
|
|
|
22
22
|
Match.exhaustive,
|
|
23
23
|
);
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
/** The class a tone adds to a notice's, a toast's or a glyph box's own. */
|
|
26
|
+
export const TONE_CLASS: Readonly<Record<Tone, string>> = {
|
|
26
27
|
Warn: "",
|
|
27
28
|
Error: " error",
|
|
28
29
|
Ok: " ok",
|
|
@@ -3,7 +3,7 @@ import { Match, Schema } from "effect";
|
|
|
3
3
|
import type { Html, HtmlBuilder } from "foldkit/html";
|
|
4
4
|
|
|
5
5
|
import { pressedAttribute } from "../button/button.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { controlAttributes, errorView, helpView } from "../field/field.ts";
|
|
7
7
|
import * as IconButton from "../iconButton/iconButton.ts";
|
|
8
8
|
import * as Meter from "../meter/meter.ts";
|
|
9
9
|
|
|
@@ -95,12 +95,10 @@ export const view = <Message>(config: ViewConfig<Message>, h: HtmlBuilder<Messag
|
|
|
95
95
|
h.span(
|
|
96
96
|
[h.Class("password")],
|
|
97
97
|
[
|
|
98
|
-
// NOTE: @foldkit/ui gap: Input has no required option, so the wrapper says it.
|
|
99
98
|
h.input([
|
|
100
99
|
...groups.input,
|
|
101
100
|
h.Autocomplete(autocomplete),
|
|
102
|
-
...
|
|
103
|
-
...(isRequired ? [h.AriaRequired(true)] : []),
|
|
101
|
+
...controlAttributes(id, error, help, isRequired, h),
|
|
104
102
|
]),
|
|
105
103
|
IconButton.view(
|
|
106
104
|
{
|
|
@@ -136,9 +134,7 @@ export const view = <Message>(config: ViewConfig<Message>, h: HtmlBuilder<Messag
|
|
|
136
134
|
],
|
|
137
135
|
),
|
|
138
136
|
]),
|
|
139
|
-
...(help
|
|
140
|
-
? []
|
|
141
|
-
: [h.p([...groups.description, h.Class("field-help")], [help])]),
|
|
137
|
+
...helpView(help, groups.description, h),
|
|
142
138
|
],
|
|
143
139
|
),
|
|
144
140
|
},
|
package/src/pixel-paper.css
CHANGED
|
@@ -13,11 +13,17 @@
|
|
|
13
13
|
|
|
14
14
|
/* anchors land 16px clear of the sticky top bar, at the height TopBar measures it to be
|
|
15
15
|
however it wraps; without Foldkit, at one line's height. A status bar along the bottom is
|
|
16
|
-
kept clear the same way: the page ends above it, and so does a scrolled-to anchor
|
|
16
|
+
kept clear the same way: the page ends above it, and so does a scrolled-to anchor. The
|
|
17
|
+
measured heights are written inline on <html>, over these */
|
|
18
|
+
:root {
|
|
19
|
+
--topbar-h: 48px;
|
|
20
|
+
--statusbar-h: 0px;
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
html {
|
|
18
24
|
height: 100%;
|
|
19
|
-
scroll-padding-top: calc(var(--topbar-h
|
|
20
|
-
scroll-padding-bottom: var(--statusbar-h
|
|
25
|
+
scroll-padding-top: calc(var(--topbar-h) + 16px);
|
|
26
|
+
scroll-padding-bottom: var(--statusbar-h);
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
:root:has(footer.statusbar) {
|
|
@@ -26,7 +32,7 @@ html {
|
|
|
26
32
|
|
|
27
33
|
body {
|
|
28
34
|
min-height: 100%;
|
|
29
|
-
padding-bottom: var(--statusbar-h
|
|
35
|
+
padding-bottom: var(--statusbar-h);
|
|
30
36
|
font-family: var(--font-body);
|
|
31
37
|
font-size: var(--type-body);
|
|
32
38
|
line-height: 1.45;
|
|
@@ -40,10 +46,6 @@ fieldset {
|
|
|
40
46
|
min-width: 0;
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
legend {
|
|
44
|
-
padding: 0;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
49
|
::selection {
|
|
48
50
|
background: var(--ink);
|
|
49
51
|
color: var(--paper);
|
|
@@ -93,7 +95,6 @@ kbd {
|
|
|
93
95
|
position: absolute;
|
|
94
96
|
width: 1px;
|
|
95
97
|
height: 1px;
|
|
96
|
-
padding: 0;
|
|
97
98
|
margin: -1px;
|
|
98
99
|
overflow: hidden;
|
|
99
100
|
clip-path: inset(50%);
|
|
@@ -129,8 +130,8 @@ kbd {
|
|
|
129
130
|
keeps its look and takes the pointer over an invisible 24px square centred on it */
|
|
130
131
|
:is(
|
|
131
132
|
.nav.tabs button,
|
|
132
|
-
.switch >
|
|
133
|
-
:is(button,
|
|
133
|
+
.switch > button,
|
|
134
|
+
:is(button, label).fchip,
|
|
134
135
|
button.glyph,
|
|
135
136
|
button.mark,
|
|
136
137
|
button.tag:has(> span),
|
|
@@ -143,8 +144,8 @@ kbd {
|
|
|
143
144
|
|
|
144
145
|
:is(
|
|
145
146
|
.nav.tabs button,
|
|
146
|
-
.switch >
|
|
147
|
-
:is(button,
|
|
147
|
+
.switch > button,
|
|
148
|
+
:is(button, label).fchip,
|
|
148
149
|
button.glyph,
|
|
149
150
|
button.mark,
|
|
150
151
|
button.tag:has(> span),
|
|
@@ -340,7 +341,6 @@ button.tag > span {
|
|
|
340
341
|
font-size: var(--type-wordmark);
|
|
341
342
|
font-weight: 400;
|
|
342
343
|
letter-spacing: -0.02em;
|
|
343
|
-
margin: 0;
|
|
344
344
|
color: inherit;
|
|
345
345
|
text-decoration: none;
|
|
346
346
|
white-space: nowrap;
|
|
@@ -378,8 +378,8 @@ button.tag > span {
|
|
|
378
378
|
flex: 1;
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
-
/* the right-hand tools wrap as one group, never one control per line
|
|
382
|
-
|
|
381
|
+
/* the right-hand tools wrap as one group, never one control per line; a group wider than the
|
|
382
|
+
window wraps onto lines of its own, at the right */
|
|
383
383
|
.topbar-tools {
|
|
384
384
|
display: flex;
|
|
385
385
|
flex-wrap: wrap;
|
|
@@ -456,7 +456,6 @@ a.textbtn {
|
|
|
456
456
|
}
|
|
457
457
|
|
|
458
458
|
/* tabs at the top of a flush panel sit inside its padding */
|
|
459
|
-
.panel > .nav.tabs,
|
|
460
459
|
.panel > .tabbed > .nav.tabs {
|
|
461
460
|
margin: var(--pad) var(--pad) 0;
|
|
462
461
|
}
|
|
@@ -498,7 +497,6 @@ a.textbtn {
|
|
|
498
497
|
color: var(--on-head);
|
|
499
498
|
}
|
|
500
499
|
|
|
501
|
-
.nav.tabs a,
|
|
502
500
|
.nav.tabs button {
|
|
503
501
|
padding: 4px 12px;
|
|
504
502
|
font-size: var(--type-state);
|
|
@@ -607,7 +605,7 @@ a.textbtn {
|
|
|
607
605
|
|
|
608
606
|
.places li:has(> [aria-current]) :is(.place-count, .iconbtn.quiet) {
|
|
609
607
|
color: inherit;
|
|
610
|
-
opacity:
|
|
608
|
+
opacity: var(--fade-on-ink);
|
|
611
609
|
}
|
|
612
610
|
|
|
613
611
|
.places li:has(> [aria-current]) :focus-visible {
|
|
@@ -798,8 +796,6 @@ a.textbtn {
|
|
|
798
796
|
.menu {
|
|
799
797
|
position: absolute;
|
|
800
798
|
z-index: 200;
|
|
801
|
-
margin: 0;
|
|
802
|
-
padding: 0;
|
|
803
799
|
min-width: 148px;
|
|
804
800
|
max-width: calc(100vw - 24px);
|
|
805
801
|
color: var(--ink);
|
|
@@ -875,7 +871,7 @@ a.textbtn {
|
|
|
875
871
|
|
|
876
872
|
.menu :is([aria-current="page"], [role="menuitemradio"][aria-checked="true"]) .key-hint {
|
|
877
873
|
color: inherit;
|
|
878
|
-
opacity:
|
|
874
|
+
opacity: var(--fade-on-ink);
|
|
879
875
|
}
|
|
880
876
|
|
|
881
877
|
.menu .menu-check {
|
|
@@ -952,7 +948,7 @@ a.textbtn {
|
|
|
952
948
|
margin-left: auto;
|
|
953
949
|
font-size: var(--type-state);
|
|
954
950
|
color: inherit;
|
|
955
|
-
opacity:
|
|
951
|
+
opacity: var(--fade-on-ink);
|
|
956
952
|
}
|
|
957
953
|
|
|
958
954
|
.panel-body {
|
|
@@ -1046,14 +1042,12 @@ a.textbtn {
|
|
|
1046
1042
|
color: var(--paper);
|
|
1047
1043
|
background: var(--ink);
|
|
1048
1044
|
border-color: var(--paper);
|
|
1049
|
-
opacity:
|
|
1045
|
+
opacity: var(--fade-held);
|
|
1050
1046
|
}
|
|
1051
1047
|
|
|
1052
1048
|
/* a quiet icon button prints in paper, and a hover cannot darken it to the ink of the bar */
|
|
1053
1049
|
.panel-lead .iconbtn.quiet,
|
|
1054
|
-
.panel-acts .iconbtn.quiet
|
|
1055
|
-
.panel-lead .iconbtn.quiet:hover,
|
|
1056
|
-
.panel-acts .iconbtn.quiet:hover {
|
|
1050
|
+
.panel-acts .iconbtn.quiet {
|
|
1057
1051
|
color: inherit;
|
|
1058
1052
|
}
|
|
1059
1053
|
|
|
@@ -1087,7 +1081,6 @@ a.textbtn {
|
|
|
1087
1081
|
flex: none;
|
|
1088
1082
|
}
|
|
1089
1083
|
|
|
1090
|
-
.switch a,
|
|
1091
1084
|
.switch button {
|
|
1092
1085
|
width: 26px;
|
|
1093
1086
|
height: 22px;
|
|
@@ -1100,12 +1093,11 @@ a.textbtn {
|
|
|
1100
1093
|
cursor: pointer;
|
|
1101
1094
|
}
|
|
1102
1095
|
|
|
1103
|
-
.switch >
|
|
1096
|
+
.switch > button + button {
|
|
1104
1097
|
border-left: var(--line) solid var(--ink);
|
|
1105
1098
|
}
|
|
1106
1099
|
|
|
1107
|
-
.switch [aria-pressed="true"]
|
|
1108
|
-
.switch [aria-current="page"] {
|
|
1100
|
+
.switch [aria-pressed="true"] {
|
|
1109
1101
|
background: var(--ink);
|
|
1110
1102
|
color: var(--paper);
|
|
1111
1103
|
}
|
|
@@ -1159,11 +1151,6 @@ button.fchip:active {
|
|
|
1159
1151
|
color: inherit;
|
|
1160
1152
|
}
|
|
1161
1153
|
|
|
1162
|
-
a.fchip {
|
|
1163
|
-
cursor: pointer;
|
|
1164
|
-
text-decoration: none;
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
1154
|
.fchip.query {
|
|
1168
1155
|
cursor: text;
|
|
1169
1156
|
isolation: isolate;
|
|
@@ -1407,12 +1394,6 @@ button.glyph {
|
|
|
1407
1394
|
margin: -4px;
|
|
1408
1395
|
}
|
|
1409
1396
|
|
|
1410
|
-
/* an inline edit in a row shows its focus as its caret and its rule, thickened below, not a
|
|
1411
|
-
ring */
|
|
1412
|
-
.row .grow input.inline-input:focus-visible {
|
|
1413
|
-
outline: none;
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
1397
|
/* the title opens the record; the pencil renames */
|
|
1417
1398
|
.row .title {
|
|
1418
1399
|
font: inherit;
|
|
@@ -1510,10 +1491,13 @@ button.glyph {
|
|
|
1510
1491
|
outline-offset: -4px;
|
|
1511
1492
|
}
|
|
1512
1493
|
|
|
1513
|
-
/* the row you are on (its link is aria-current)
|
|
1514
|
-
|
|
1515
|
-
paper prints in paper at
|
|
1516
|
-
|
|
1494
|
+
/* the row you are on (its link is aria-current) and a board's cursor card print inverted, as
|
|
1495
|
+
a place does and as the system marks the one current thing: hover adds nothing, what prints
|
|
1496
|
+
muted on paper prints in paper at --fade-on-ink, as a title bar's meta does, chips, marks
|
|
1497
|
+
and buttons keep their own fills, and a ring inside prints in paper. Each selector is
|
|
1498
|
+
written out, not joined in :is(), so each keeps its own specificity */
|
|
1499
|
+
.row.linked:has(.grow a[aria-current]),
|
|
1500
|
+
.board-card[aria-current="true"] {
|
|
1517
1501
|
background-color: var(--ink);
|
|
1518
1502
|
color: var(--paper);
|
|
1519
1503
|
}
|
|
@@ -1522,16 +1506,20 @@ button.glyph {
|
|
|
1522
1506
|
border-color: var(--paper);
|
|
1523
1507
|
}
|
|
1524
1508
|
|
|
1525
|
-
.row.linked:has(.grow a[aria-current]) :is(.glyph, .age, .due, .tag, .done-title, .iconbtn.quiet)
|
|
1509
|
+
.row.linked:has(.grow a[aria-current]) :is(.glyph, .age, .due, .tag, .done-title, .iconbtn.quiet),
|
|
1510
|
+
.board-card[aria-current="true"] :is(.glyph, .age, .due, .tag, .done-title, .iconbtn.quiet) {
|
|
1526
1511
|
color: inherit;
|
|
1527
|
-
opacity:
|
|
1512
|
+
opacity: var(--fade-on-ink);
|
|
1528
1513
|
}
|
|
1529
1514
|
|
|
1530
|
-
.row.linked:has(.grow a[aria-current]) .tag
|
|
1515
|
+
.row.linked:has(.grow a[aria-current]) .tag,
|
|
1516
|
+
.board-card[aria-current="true"] .tag {
|
|
1531
1517
|
border-color: currentColor;
|
|
1532
1518
|
}
|
|
1533
1519
|
|
|
1534
|
-
|
|
1520
|
+
/* lateness cannot be red on ink: it takes a red slip, drawn by a spread so nothing moves */
|
|
1521
|
+
.row.linked:has(.grow a[aria-current]) :is(.due.late, .age.stale),
|
|
1522
|
+
.board-card[aria-current="true"] :is(.due.late, .age.stale) {
|
|
1535
1523
|
opacity: 1;
|
|
1536
1524
|
background: var(--red);
|
|
1537
1525
|
color: var(--on-red);
|
|
@@ -1539,7 +1527,8 @@ button.glyph {
|
|
|
1539
1527
|
}
|
|
1540
1528
|
|
|
1541
1529
|
.row.linked:has(.grow a[aria-current]) :focus-visible,
|
|
1542
|
-
.row.linked:has(.grow a[aria-current]:focus-visible)
|
|
1530
|
+
.row.linked:has(.grow a[aria-current]:focus-visible),
|
|
1531
|
+
.board-card[aria-current="true"] :focus-visible {
|
|
1543
1532
|
outline-color: var(--paper);
|
|
1544
1533
|
}
|
|
1545
1534
|
|
|
@@ -1566,35 +1555,6 @@ button.glyph {
|
|
|
1566
1555
|
opacity: 1;
|
|
1567
1556
|
}
|
|
1568
1557
|
|
|
1569
|
-
/* a board's cursor card is inverted, as the system marks the one current thing. What prints
|
|
1570
|
-
muted on paper prints in paper at 0.75, as a title bar's meta does; chips, marks and buttons
|
|
1571
|
-
keep their own fills; a ring inside it prints in paper. Hover adds nothing to it */
|
|
1572
|
-
.board-card[aria-current="true"] {
|
|
1573
|
-
background-color: var(--ink);
|
|
1574
|
-
color: var(--paper);
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
|
-
.board-card[aria-current="true"] :is(.glyph, .age, .due, .tag, .done-title, .iconbtn.quiet) {
|
|
1578
|
-
color: inherit;
|
|
1579
|
-
opacity: 0.75;
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
.board-card[aria-current="true"] .tag {
|
|
1583
|
-
border-color: currentColor;
|
|
1584
|
-
}
|
|
1585
|
-
|
|
1586
|
-
/* lateness cannot be red on ink: it takes a red slip, drawn by a spread so nothing moves */
|
|
1587
|
-
.board-card[aria-current="true"] :is(.due.late, .age.stale) {
|
|
1588
|
-
opacity: 1;
|
|
1589
|
-
background: var(--red);
|
|
1590
|
-
color: var(--on-red);
|
|
1591
|
-
box-shadow: 0 0 0 3px var(--red);
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
.board-card[aria-current="true"] :focus-visible {
|
|
1595
|
-
outline-color: var(--paper);
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
1558
|
/* a phone has no room for the hover tools; the detail card carries every edit. Titles
|
|
1599
1559
|
wrap to a second line instead of clipping to a few characters beside the chips */
|
|
1600
1560
|
@media (max-width: 600px) {
|
|
@@ -1747,10 +1707,11 @@ input.inline-input[aria-invalid="true"] {
|
|
|
1747
1707
|
border-bottom-color: var(--red);
|
|
1748
1708
|
}
|
|
1749
1709
|
|
|
1750
|
-
/* in a row,
|
|
1751
|
-
drawn inside the box, so the row keeps its height, and in the rule's
|
|
1752
|
-
refused edit stays red */
|
|
1710
|
+
/* in a row, focus shows as the caret and the rule, not a ring: the rule doubles to 2px, as a
|
|
1711
|
+
field's baseline does, drawn inside the box, so the row keeps its height, and in the rule's
|
|
1712
|
+
own colour, so a refused edit stays red */
|
|
1753
1713
|
.row .grow input.inline-input:focus-visible {
|
|
1714
|
+
outline: none;
|
|
1754
1715
|
box-shadow: inset 0 -1px 0 var(--ink);
|
|
1755
1716
|
}
|
|
1756
1717
|
|
|
@@ -2081,7 +2042,6 @@ textarea::-webkit-resizer {
|
|
|
2081
2042
|
font-size: var(--type-control);
|
|
2082
2043
|
}
|
|
2083
2044
|
|
|
2084
|
-
.title-edit,
|
|
2085
2045
|
input.inline-input.title-edit {
|
|
2086
2046
|
font-size: var(--type-title);
|
|
2087
2047
|
font-weight: 600;
|
|
@@ -2292,12 +2252,6 @@ select[aria-invalid="true"] {
|
|
|
2292
2252
|
margin-left: 8px;
|
|
2293
2253
|
}
|
|
2294
2254
|
|
|
2295
|
-
.table .chips {
|
|
2296
|
-
display: inline-flex;
|
|
2297
|
-
gap: 6px;
|
|
2298
|
-
flex-wrap: wrap;
|
|
2299
|
-
}
|
|
2300
|
-
|
|
2301
2255
|
/* a stacked table: on a phone each row becomes a block of label and value lines, so a
|
|
2302
2256
|
pinned action column never slices through what the row says */
|
|
2303
2257
|
@media (max-width: 600px) {
|
|
@@ -2719,15 +2673,10 @@ pre.code-surface {
|
|
|
2719
2673
|
element of its own (.veil-backdrop) under the pad; the pad lets a press through to it
|
|
2720
2674
|
everywhere but on the card it holds, and a press on the veil closes the dialog. */
|
|
2721
2675
|
dialog.veil {
|
|
2722
|
-
margin: 0;
|
|
2723
2676
|
color: inherit;
|
|
2724
2677
|
overflow-y: auto;
|
|
2725
2678
|
}
|
|
2726
2679
|
|
|
2727
|
-
dialog.veil[open] {
|
|
2728
|
-
display: block;
|
|
2729
|
-
}
|
|
2730
|
-
|
|
2731
2680
|
dialog.veil:focus {
|
|
2732
2681
|
outline: none;
|
|
2733
2682
|
}
|
|
@@ -2819,12 +2768,12 @@ dialog.veil:focus {
|
|
|
2819
2768
|
.card-tb .meta {
|
|
2820
2769
|
font-size: var(--type-state);
|
|
2821
2770
|
color: inherit;
|
|
2822
|
-
opacity:
|
|
2771
|
+
opacity: var(--fade-on-ink);
|
|
2823
2772
|
}
|
|
2824
2773
|
|
|
2825
2774
|
/* a held icon button fades on the bar, as a held button in a panel's title bar does */
|
|
2826
2775
|
:is(.card-tb, .panel-tb) .iconbtn[aria-disabled="true"] {
|
|
2827
|
-
opacity:
|
|
2776
|
+
opacity: var(--fade-held);
|
|
2828
2777
|
cursor: default;
|
|
2829
2778
|
}
|
|
2830
2779
|
|
|
@@ -3066,7 +3015,7 @@ dialog.veil:focus {
|
|
|
3066
3015
|
.palette-row[aria-selected="true"] .hint,
|
|
3067
3016
|
.palette-row[aria-selected="true"] .tag {
|
|
3068
3017
|
color: inherit;
|
|
3069
|
-
opacity:
|
|
3018
|
+
opacity: var(--fade-on-ink);
|
|
3070
3019
|
}
|
|
3071
3020
|
|
|
3072
3021
|
.palette-row[aria-selected="true"] .tag {
|
|
@@ -3130,7 +3079,6 @@ dialog.veil:focus {
|
|
|
3130
3079
|
}
|
|
3131
3080
|
|
|
3132
3081
|
.empty-title {
|
|
3133
|
-
margin: 0;
|
|
3134
3082
|
font-family: var(--font-px);
|
|
3135
3083
|
font-size: var(--type-control);
|
|
3136
3084
|
text-transform: uppercase;
|
|
@@ -3151,7 +3099,7 @@ dialog.veil:focus {
|
|
|
3151
3099
|
|
|
3152
3100
|
.banner {
|
|
3153
3101
|
position: fixed;
|
|
3154
|
-
bottom: calc(var(--statusbar-h
|
|
3102
|
+
bottom: calc(var(--statusbar-h) + 16px);
|
|
3155
3103
|
left: 50%;
|
|
3156
3104
|
transform: translateX(-50%);
|
|
3157
3105
|
z-index: 150;
|
|
@@ -3408,7 +3356,7 @@ dialog.veil:focus {
|
|
|
3408
3356
|
}
|
|
3409
3357
|
|
|
3410
3358
|
.board-card.drag-dim {
|
|
3411
|
-
opacity:
|
|
3359
|
+
opacity: var(--fade-dragged);
|
|
3412
3360
|
}
|
|
3413
3361
|
|
|
3414
3362
|
/* focus on the title rings the whole slip, outside its own border */
|
|
@@ -3501,7 +3449,7 @@ dialog.veil:focus {
|
|
|
3501
3449
|
}
|
|
3502
3450
|
|
|
3503
3451
|
.sortable-item.drag-dim {
|
|
3504
|
-
opacity:
|
|
3452
|
+
opacity: var(--fade-dragged);
|
|
3505
3453
|
}
|
|
3506
3454
|
|
|
3507
3455
|
/* where a pointer would drop the held item: a 2px dashed ink line beside the item it lands
|
|
@@ -5064,7 +5012,6 @@ dialog.veil:focus {
|
|
|
5064
5012
|
display: flex;
|
|
5065
5013
|
flex-wrap: wrap;
|
|
5066
5014
|
gap: 4px 12px;
|
|
5067
|
-
margin: 0;
|
|
5068
5015
|
}
|
|
5069
5016
|
|
|
5070
5017
|
.statusbar-keys .key-hint {
|
|
@@ -5076,24 +5023,34 @@ dialog.veil:focus {
|
|
|
5076
5023
|
|
|
5077
5024
|
/* one element in two places: at rest, fixed down the left edge from the top bar's lower
|
|
5078
5025
|
edge (as the stage hangs) and scrolling itself; on a phone the same element opens as a
|
|
5079
|
-
popover drawer.
|
|
5080
|
-
.railed, so the page's padding and the rail's width follow it together
|
|
5026
|
+
popover drawer. The reader's width, when they gave one, is --railed-width, which the view
|
|
5027
|
+
sets on .railed, so the page's padding and the rail's width follow it together; without one,
|
|
5028
|
+
--rail. It is not inherited: each box it sizes takes it from .railed by name, so a width that
|
|
5029
|
+
changes under a dragged splitter restyles those four and none of the rows inside them */
|
|
5030
|
+
@property --railed-width {
|
|
5031
|
+
syntax: "*";
|
|
5032
|
+
inherits: false;
|
|
5033
|
+
}
|
|
5034
|
+
|
|
5081
5035
|
.railed {
|
|
5082
|
-
padding-left: var(--rail);
|
|
5036
|
+
padding-left: var(--railed-width, var(--rail));
|
|
5037
|
+
}
|
|
5038
|
+
|
|
5039
|
+
.railed > :is(.rail, .rail-resize, .bench) {
|
|
5040
|
+
--railed-width: inherit;
|
|
5083
5041
|
}
|
|
5084
5042
|
|
|
5085
5043
|
.rail[popover] {
|
|
5086
5044
|
position: fixed;
|
|
5087
5045
|
inset: auto;
|
|
5088
5046
|
top: anchor(--topbar bottom, 0px);
|
|
5089
|
-
bottom: var(--statusbar-h
|
|
5047
|
+
bottom: var(--statusbar-h);
|
|
5090
5048
|
left: 0;
|
|
5091
5049
|
display: grid;
|
|
5092
5050
|
align-content: start;
|
|
5093
5051
|
gap: var(--gap);
|
|
5094
|
-
width: var(--rail);
|
|
5052
|
+
width: var(--railed-width, var(--rail));
|
|
5095
5053
|
height: auto;
|
|
5096
|
-
margin: 0;
|
|
5097
5054
|
padding: var(--gap) 10px var(--gap) 20px;
|
|
5098
5055
|
border: 0;
|
|
5099
5056
|
background: none;
|
|
@@ -5112,8 +5069,8 @@ dialog.veil:focus {
|
|
|
5112
5069
|
.rail-resize {
|
|
5113
5070
|
position: fixed;
|
|
5114
5071
|
top: anchor(--topbar bottom, 0px);
|
|
5115
|
-
bottom: var(--statusbar-h
|
|
5116
|
-
left: var(--rail);
|
|
5072
|
+
bottom: var(--statusbar-h);
|
|
5073
|
+
left: var(--railed-width, var(--rail));
|
|
5117
5074
|
z-index: 1;
|
|
5118
5075
|
width: 12px;
|
|
5119
5076
|
cursor: col-resize;
|
|
@@ -5196,21 +5153,24 @@ dialog.veil:focus {
|
|
|
5196
5153
|
/* hung from the top bar's lower edge like the stage, down to the status bar, edge to edge, or
|
|
5197
5154
|
from the rail's edge beside one (a fixed box takes nothing from .railed's padding). The head
|
|
5198
5155
|
takes its own height while the work keeps at least --bench-work-min, or all but the head's
|
|
5199
|
-
first
|
|
5156
|
+
first --bench-head-min (its padding and a small button: the rail's open button) on a window too short
|
|
5200
5157
|
for both; past that the head scrolls itself. The work takes the rest and lays out what
|
|
5201
5158
|
fills it (a reel's height is 100% of it). The page does not scroll */
|
|
5202
5159
|
.bench {
|
|
5203
5160
|
position: fixed;
|
|
5204
5161
|
top: anchor(--topbar bottom, 0px);
|
|
5205
5162
|
right: 0;
|
|
5206
|
-
bottom: var(--statusbar-h
|
|
5163
|
+
bottom: var(--statusbar-h);
|
|
5207
5164
|
left: 0;
|
|
5208
5165
|
display: grid;
|
|
5209
|
-
grid-template-rows: minmax(0, max-content) minmax(
|
|
5166
|
+
grid-template-rows: minmax(0, max-content) minmax(
|
|
5167
|
+
min(var(--bench-work-min), 100% - var(--bench-head-min)),
|
|
5168
|
+
1fr
|
|
5169
|
+
);
|
|
5210
5170
|
}
|
|
5211
5171
|
|
|
5212
5172
|
.railed > .bench {
|
|
5213
|
-
left: var(--rail);
|
|
5173
|
+
left: var(--railed-width, var(--rail));
|
|
5214
5174
|
}
|
|
5215
5175
|
|
|
5216
5176
|
/* the head lines up with a reel's windows, a reel's gutter in from the edge; the reel's own
|
|
@@ -5248,7 +5208,7 @@ dialog.veil:focus {
|
|
|
5248
5208
|
position: fixed;
|
|
5249
5209
|
top: anchor(--topbar bottom, 0px);
|
|
5250
5210
|
right: 0;
|
|
5251
|
-
bottom: var(--statusbar-h
|
|
5211
|
+
bottom: var(--statusbar-h);
|
|
5252
5212
|
left: 0;
|
|
5253
5213
|
overflow: hidden;
|
|
5254
5214
|
}
|
|
@@ -5347,8 +5307,7 @@ dialog.veil:focus {
|
|
|
5347
5307
|
border-color: var(--paper);
|
|
5348
5308
|
}
|
|
5349
5309
|
|
|
5350
|
-
.window > .panel-tb .iconbtn
|
|
5351
|
-
.window > .panel-tb .iconbtn.quiet {
|
|
5310
|
+
.window > .panel-tb .iconbtn {
|
|
5352
5311
|
color: inherit;
|
|
5353
5312
|
}
|
|
5354
5313
|
|
|
@@ -5558,7 +5517,7 @@ dialog.veil:focus {
|
|
|
5558
5517
|
}
|
|
5559
5518
|
|
|
5560
5519
|
.reel-pane.drag-dim {
|
|
5561
|
-
opacity:
|
|
5520
|
+
opacity: var(--fade-dragged);
|
|
5562
5521
|
}
|
|
5563
5522
|
|
|
5564
5523
|
/* only the grips lift: a pane's text selects and its terminal takes the pointer */
|
|
@@ -5767,7 +5726,6 @@ dialog.veil:focus {
|
|
|
5767
5726
|
inset: 0;
|
|
5768
5727
|
width: 100%;
|
|
5769
5728
|
height: 100%;
|
|
5770
|
-
margin: 0;
|
|
5771
5729
|
opacity: 0;
|
|
5772
5730
|
appearance: none;
|
|
5773
5731
|
cursor: pointer;
|
|
@@ -5826,7 +5784,7 @@ dialog.veil:focus {
|
|
|
5826
5784
|
padding from the corner), so the stylesheet raises it clear of a banner, its anchor when one
|
|
5827
5785
|
is showing, or of a status bar, and sets the gap. A phone spans it across the bottom */
|
|
5828
5786
|
.toasts .toast-stack {
|
|
5829
|
-
bottom: calc(anchor(--banner top, calc(var(--statusbar-h
|
|
5787
|
+
bottom: calc(anchor(--banner top, calc(var(--statusbar-h) + 4px)) - 4px) !important;
|
|
5830
5788
|
gap: 10px !important;
|
|
5831
5789
|
width: min(392px, 100vw);
|
|
5832
5790
|
}
|
|
@@ -5874,21 +5832,14 @@ dialog.veil:focus {
|
|
|
5874
5832
|
}
|
|
5875
5833
|
}
|
|
5876
5834
|
|
|
5877
|
-
@media (prefers-reduced-motion: reduce) {
|
|
5878
|
-
.toasts .toast {
|
|
5879
|
-
animation: none;
|
|
5880
|
-
}
|
|
5881
|
-
}
|
|
5882
|
-
|
|
5883
5835
|
/* ---------- reduced motion ---------- */
|
|
5884
5836
|
|
|
5885
5837
|
@media (prefers-reduced-motion: reduce) {
|
|
5886
|
-
.cursor
|
|
5887
|
-
animation: none;
|
|
5888
|
-
}
|
|
5838
|
+
.cursor,
|
|
5889
5839
|
.veil-backdrop,
|
|
5890
5840
|
.card,
|
|
5891
|
-
.rail[popover]:popover-open
|
|
5841
|
+
.rail[popover]:popover-open,
|
|
5842
|
+
.toasts .toast {
|
|
5892
5843
|
animation: none;
|
|
5893
5844
|
}
|
|
5894
5845
|
}
|