@usableapp/cardds 0.7.95 → 0.7.97
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/CHANGELOG.md +69 -0
- package/LICENSE +21 -0
- package/README.md +3 -1045
- package/bin/cardds.mjs +2 -2
- package/css/actions.css +11 -14
- package/css/base.css +3 -6
- package/css/card.css +11 -17
- package/css/choice.css +14 -11
- package/css/finish.css +4 -2
- package/css/journey.css +7 -4
- package/css/layover.css +16 -11
- package/css/lists.css +4 -9
- package/css/media.css +20 -16
- package/css/numbers.css +16 -18
- package/css/palette.css +79 -97
- package/css/people.css +5 -4
- package/css/post.css +2 -1
- package/css/sheet.css +13 -10
- package/css/stack.css +1 -1
- package/css/sticky.css +6 -5
- package/css/theme.template.css +16 -7
- package/css/tokens.css +69 -35
- package/dist/actions/Chip.d.ts +1 -1
- package/dist/actions/Dropdown.d.ts +1 -1
- package/dist/cardds.css +283 -263
- package/dist/cards/cardGrounds.d.ts +22 -0
- package/dist/cards/cardGrounds.js +84 -0
- package/dist/cards/inkGrounds.d.ts +34 -0
- package/dist/cards/inkGrounds.js +181 -0
- package/dist/catalog.json +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/docs/reference.md +1137 -0
- package/lib/guide.mjs +1 -1
- package/lint/rules.mjs +5 -1
- package/package.json +2 -1
package/css/numbers.css
CHANGED
|
@@ -45,25 +45,21 @@
|
|
|
45
45
|
.track {
|
|
46
46
|
--_step: calc(var(--tap-base) * 2 / 3); /* 32 the round of one step */
|
|
47
47
|
--_pad: calc((var(--header-h) - var(--_step)) / 2); /* 14 round + its room = the top bar's height; the end rounds sit concentric in the pill */
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
re-points the accent to its own ink (README rule 10). Without this, any
|
|
52
|
-
palette where --accent equals --card-3-bg — field, hydro, and the
|
|
53
|
-
wireframe default — paints done steps invisibly on the track. */
|
|
54
|
-
--accent: var(--_ink);
|
|
55
|
-
--on-accent: var(--_bg);
|
|
48
|
+
/* the track lays down the accent fill of where it stands (the brand on a light card, the card's ink on the brand card), so it is a
|
|
49
|
+
surface of that fill's side; its steps re-point the accent to its ink, as the brand card slot does (docs/reference.md rule 10) */
|
|
50
|
+
--dark: var(--accent-dark);
|
|
56
51
|
list-style: none;
|
|
57
52
|
margin: 0;
|
|
58
53
|
padding: var(--track-pad, var(--_pad));
|
|
59
54
|
display: flex;
|
|
60
55
|
align-items: center;
|
|
61
56
|
border-radius: var(--track-radius, var(--r-chip));
|
|
62
|
-
background: var(--
|
|
63
|
-
color: var(--
|
|
57
|
+
background: var(--accent);
|
|
58
|
+
color: var(--card-ink);
|
|
64
59
|
}
|
|
65
|
-
.card--3 .track { --_bg: var(--card-3-ink); --_ink: var(--card-3-bg); }
|
|
66
60
|
.track__step {
|
|
61
|
+
--accent: var(--card-ink);
|
|
62
|
+
--accent-dark: calc(1 - var(--dark));
|
|
67
63
|
flex: 1;
|
|
68
64
|
display: flex;
|
|
69
65
|
align-items: center;
|
|
@@ -75,7 +71,7 @@
|
|
|
75
71
|
content: "";
|
|
76
72
|
flex: 1;
|
|
77
73
|
height: var(--sp-2);
|
|
78
|
-
background: var(--ink-rail); /* the track's own ink at 30
|
|
74
|
+
background: var(--ink-rail); /* the track's own ink at 30%: --ink-rail reads currentColor */
|
|
79
75
|
}
|
|
80
76
|
.track__step:first-child::before { display: none; }
|
|
81
77
|
.track__step.is-done::before { background: var(--accent); }
|
|
@@ -87,8 +83,9 @@
|
|
|
87
83
|
padding: calc(var(--_step) * 7 / 32); /* the glyph = 18 in the 32 round */
|
|
88
84
|
border-radius: 50%;
|
|
89
85
|
background: var(--ink-rail);
|
|
90
|
-
color: var(--
|
|
86
|
+
color: var(--card-ink);
|
|
91
87
|
}
|
|
88
|
+
.track__step > .track__dot { background: var(--ink-tint); } /* a number is words: on the 30% rail it fell under 4.5:1 on a mid-dark track; the 12% tint is what every tone holds its ink on */
|
|
92
89
|
.track__step > .track__dot { /* a number in the round (TrackStep num) */
|
|
93
90
|
display: grid; place-items: center; box-sizing: border-box;
|
|
94
91
|
font: var(--track-dot-font, var(--type-caption)); line-height: 1; font-variant-numeric: tabular-nums;
|
|
@@ -185,10 +182,11 @@
|
|
|
185
182
|
font: var(--picker-item-font, var(--type-stat));
|
|
186
183
|
letter-spacing: var(--track-display);
|
|
187
184
|
font-variant-numeric: tabular-nums;
|
|
188
|
-
|
|
185
|
+
--_rest: var(--picker-rest-ink, var(--card-muted)); /* the values either side: the ground's muted words (they faded to 0.3, 1.8:1) */
|
|
186
|
+
color: var(--_rest);
|
|
189
187
|
text-align: center;
|
|
190
188
|
}
|
|
191
|
-
.picker__item[aria-selected="true"] {
|
|
189
|
+
.picker__item[aria-selected="true"] { color: var(--card-ink); }
|
|
192
190
|
/* centre rules either side of the selected value */
|
|
193
191
|
.picker::before,
|
|
194
192
|
.picker::after {
|
|
@@ -204,10 +202,10 @@
|
|
|
204
202
|
.picker__unit { font: var(--picker-unit-font, var(--type-caption)); color: var(--picker-unit-ink, var(--card-muted)); }
|
|
205
203
|
/* the scrolled-to item lights up by position — no JS */
|
|
206
204
|
@supports (animation-timeline: view(x)) {
|
|
207
|
-
.picker__item { animation: picker-focus linear both; animation-timeline: view(x); }
|
|
205
|
+
.picker__item { animation: picker-focus linear both; animation-timeline: view(x); }
|
|
208
206
|
@keyframes picker-focus {
|
|
209
|
-
0%, 100% {
|
|
210
|
-
45%, 55% {
|
|
207
|
+
0%, 100% { color: var(--_rest); }
|
|
208
|
+
45%, 55% { color: var(--card-ink); }
|
|
211
209
|
}
|
|
212
210
|
}
|
|
213
211
|
|
package/css/palette.css
CHANGED
|
@@ -3,156 +3,138 @@
|
|
|
3
3
|
Apply with <html data-palette="clay"> (or <body>).
|
|
4
4
|
No attribute = wireframe grayscale from tokens.css.
|
|
5
5
|
Each palette overrides role tokens only — components never change.
|
|
6
|
+
A palette sets its grounds, its two ink sets (onlight, ondark; docs/reference.md "Ink follows its ground") and the side of any ground
|
|
7
|
+
that is not the default's (tokens.css: tones 1, 2, 4 and the paper light; tone 3, tone 5 and the brand dark). Each ink set
|
|
8
|
+
holds 4.5:1 on every ground of its side; a tone with words on its 12% tint (a banner, a step bar, today) holds them there too.
|
|
6
9
|
============================================================ */
|
|
7
10
|
|
|
8
11
|
/* ---- CLAY — earth-toned: cream surface, terracotta / mustard / ink cards ---- */
|
|
9
12
|
[data-palette="clay"] {
|
|
10
13
|
--surface: #ece5d8;
|
|
11
|
-
--
|
|
12
|
-
--
|
|
14
|
+
--ink-onlight: #191713; --ink-onlight-muted: #2a2723; /* the terracotta is a middle ground: no muted shade a step lighter holds 4.5:1 on it (4.6) */
|
|
15
|
+
--ink-ondark: #f4efe4; --ink-ondark-muted: #aeaaa1; /* 4.6:1 on tone 5's grey */
|
|
13
16
|
|
|
14
|
-
--card-1-bg: #e8b647;
|
|
15
|
-
--card-2-bg: #
|
|
16
|
-
--card-3-bg: #1c1a17;
|
|
17
|
+
--card-1-bg: #e8b647; /* mustard hero */
|
|
18
|
+
--card-2-bg: #eb6644; /* terracotta, a step lighter: the ink 5.5:1, 4.5 on its own tint (#e05c3a was 4.9 and 4.1) */
|
|
19
|
+
--card-3-bg: #1c1a17; /* ink */
|
|
17
20
|
|
|
18
|
-
--
|
|
19
|
-
--
|
|
20
|
-
--card-2-muted: var(--card-2-ink); /* terracotta holds 5:1 for its ink alone; nothing lighter passes AA, so tone 2 has no muted */
|
|
21
|
-
|
|
22
|
-
--accent: #1c1a17; --on-accent: #f4efe4;
|
|
23
|
-
--action-bg: #f7f3e9; --action-ink: #191713; --action-border: transparent;
|
|
21
|
+
--accent: #1c1a17;
|
|
22
|
+
--action-bg: #f7f3e9; --action-border: transparent;
|
|
24
23
|
|
|
25
24
|
--pos: #3e7d4f; --neg: #c23c1d;
|
|
26
|
-
--dot-a: #
|
|
25
|
+
--dot-a: #eb6644; --dot-b: #6f6be0;
|
|
26
|
+
/* the signals, deep enough for words on the terracotta (4.5:1) and so on every lighter ground; nearly the ink, the hue stays */
|
|
27
|
+
--signal-ok-onlight: #1b2c18; --signal-warn-onlight: #2f280d; --signal-error-onlight: #471a17; --signal-info-onlight: #1d2938;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
/* ---- ROAST — coffee: warm cream surface, caramel accent ---- */
|
|
30
31
|
[data-palette="roast"] {
|
|
31
32
|
--surface: #f6f1e7;
|
|
32
|
-
--
|
|
33
|
-
--
|
|
34
|
-
|
|
35
|
-
--card-1-bg: #ffffff; --card-1-ink: #2b211a;
|
|
36
|
-
--card-2-bg: #e9dcc6; --card-2-ink: #2b211a;
|
|
37
|
-
--card-3-bg: #b97e3c; --card-3-ink: #fdf9f1;
|
|
33
|
+
--ink-onlight: #2b211a; --ink-onlight-muted: #5e554d; /* 4.6:1 on the water note, the darkest light ground */
|
|
34
|
+
--ink-ondark: #fdf9f1; --ink-ondark-muted: #ecdfcb; /* 4.6:1 on the caramel */
|
|
38
35
|
|
|
39
|
-
--card-
|
|
40
|
-
--card-
|
|
36
|
+
--card-1-bg: #ffffff;
|
|
37
|
+
--card-2-bg: #e9dcc6;
|
|
38
|
+
--card-3-bg: #8c5402; /* caramel, on its own hue as far as the light ink holds 4.5:1 on it and on its tint (#b97e3c held it at 3.3) */
|
|
41
39
|
|
|
42
|
-
--accent: #
|
|
43
|
-
--action-bg: #ffffff; --action-
|
|
40
|
+
--accent: #8c5402;
|
|
41
|
+
--action-bg: #ffffff; --action-border: transparent;
|
|
44
42
|
|
|
45
43
|
--pos: #3e7d4f; --neg: #bf4028;
|
|
46
|
-
--dot-a: #
|
|
44
|
+
--dot-a: #8c5402; --dot-b: #2b211a;
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
/* ---- HYDRO — cool shiny blue: airy surface, saturated blue CTA ---- */
|
|
50
48
|
[data-palette="hydro"] {
|
|
51
49
|
--surface: #e9f0fb;
|
|
52
|
-
--
|
|
53
|
-
--
|
|
50
|
+
--ink-onlight: #17203a; --ink-onlight-muted: #4e566c; /* 4.6:1 on the water note, the darkest light ground */
|
|
51
|
+
--ink-ondark: #ffffff; --ink-ondark-muted: #e0e6f9; /* 4.6:1 on the blue */
|
|
54
52
|
|
|
55
|
-
--card-1-bg: #ffffff;
|
|
56
|
-
--card-2-bg: #cddcf7;
|
|
57
|
-
--card-3-bg: #
|
|
53
|
+
--card-1-bg: #ffffff;
|
|
54
|
+
--card-2-bg: #cddcf7;
|
|
55
|
+
--card-3-bg: #365bd7; /* white 5.7:1, 4.5 on its tint (#3d63e0 was 5.2 and 4.1) */
|
|
58
56
|
|
|
59
|
-
--
|
|
60
|
-
--
|
|
61
|
-
|
|
62
|
-
--accent: #3d63e0; --on-accent: #f2f6ff;
|
|
63
|
-
--action-bg: #ffffff; --action-ink: #17203a; --action-border: transparent;
|
|
57
|
+
--accent: #365bd7;
|
|
58
|
+
--action-bg: #ffffff; --action-border: transparent;
|
|
64
59
|
|
|
65
60
|
--pos: #2e8f52; --neg: #d13b1a;
|
|
66
|
-
--dot-a: #
|
|
61
|
+
--dot-a: #365bd7; --dot-b: #eec85a;
|
|
67
62
|
}
|
|
68
63
|
|
|
69
|
-
/* ---- ORCHARD — modern earth: calm, real, touchable (Lh 2026-09-25). Linen base, bone paper, moss brand
|
|
70
|
-
|
|
71
|
-
edges) come out as a darker tint of the ground under them — never a grey on a warm card. Four highlights for the
|
|
72
|
-
atmosphere, off the earth wheel on purpose: maple red · bright yellow · sky · fuchsia. ---- */
|
|
64
|
+
/* ---- ORCHARD — modern earth: calm, real, touchable (Lh 2026-09-25). Linen base, bone paper, moss brand. Four highlights for
|
|
65
|
+
the atmosphere, off the earth wheel on purpose: maple red · bright yellow · sky · fuchsia. ---- */
|
|
73
66
|
[data-palette="orchard"] {
|
|
74
67
|
--surface: #f4efe6; /* linen */
|
|
75
|
-
--
|
|
76
|
-
--
|
|
77
|
-
|
|
78
|
-
--card-1-bg: #fbf8f2; --card-1-ink: #2a241c; /* bone paper — sheets */
|
|
79
|
-
--card-2-bg: #e6d8bf; --card-2-ink: #33291c; /* sand */
|
|
80
|
-
--card-3-bg: #5c6b47; --card-3-ink: #f6f1e6; --card-3-muted: #d3d8c4; /* moss — the brand */
|
|
81
|
-
--card-4-bg: #d3d9c4; --card-4-ink: #2b3322; --card-4-muted: #515c42; /* sage mist */
|
|
82
|
-
--card-5-bg: #dcc2a6; --card-5-ink: #3a2a1c; --card-5-muted: #6b503a; /* clay */
|
|
68
|
+
--ink-onlight: #2a241c; --ink-onlight-muted: #565148; /* umber; muted 4.6:1 on the clay tone */
|
|
69
|
+
--ink-ondark: #f6f1e6; --ink-ondark-muted: #d7d6c6; /* linen; muted 4.6:1 on the moss */
|
|
83
70
|
|
|
84
|
-
--card-
|
|
85
|
-
--card-
|
|
86
|
-
--card-
|
|
71
|
+
--card-1-bg: #fbf8f2; /* bone paper — sheets */
|
|
72
|
+
--card-2-bg: #e6d8bf; /* sand */
|
|
73
|
+
--card-3-bg: #52613d; /* moss — the brand: its ink 5.9:1, 4.5 on its tint (#5c6b47 was 5.1 and 4.0) */
|
|
74
|
+
--card-4-bg: #d3d9c4; /* sage mist */
|
|
75
|
+
--card-5-bg: #dcc2a6; --card-5-dark: 0; /* clay: a light tone here */
|
|
87
76
|
|
|
88
|
-
--accent: #
|
|
89
|
-
--action-bg: #fbf8f2; --action-
|
|
77
|
+
--accent: #52613d;
|
|
78
|
+
--action-bg: #fbf8f2; --action-border: transparent;
|
|
90
79
|
|
|
91
80
|
/* highlights — decoration and atmosphere, a small dose: counts, marks, chart dots, a badge on a tile */
|
|
92
|
-
--highlight-1: #
|
|
81
|
+
--highlight-1: #d03114; /* maple red — the linen ink 4.5:1 on it (#d93a1f was 4.1) */
|
|
93
82
|
--highlight-2: #f5c518; /* bright yellow */
|
|
94
83
|
--highlight-3: #3a9fe0; /* sky */
|
|
95
|
-
--highlight-4: #
|
|
84
|
+
--highlight-4: #ca2e69; /* fuchsia — the linen ink 4.5:1 on it (#e0457b was 3.5) */
|
|
96
85
|
--dot-a: var(--highlight-1); --dot-b: var(--highlight-3);
|
|
97
86
|
|
|
98
87
|
/* signals from Sweet Salmon #dd9787 — words and edges, always with an icon */
|
|
99
|
-
--pos: #6f8f5a; --neg: #c4694f
|
|
100
|
-
--signal-error: #
|
|
101
|
-
--signal-warn: #
|
|
102
|
-
--signal-ok: #4f7f4a; /* leaf */
|
|
103
|
-
--signal-info: #4d6f96; /* slate */
|
|
88
|
+
--pos: #6f8f5a; --neg: #ad553b; /* a falling delta's linen words 4.5:1 (#c4694f was 3.4) */
|
|
89
|
+
--signal-error-onlight: #82402f; --signal-warn-onlight: #6b4e1b; --signal-ok-onlight: #3e5a37; --signal-info-onlight: #40556c; /* 4.5:1 on the clay tone */
|
|
90
|
+
--signal-error-ondark: #f9ccc0; --signal-warn-ondark: #f2d28b; --signal-ok-ondark: #cfe6b8; --signal-info-ondark: #c5d7ef; /* the same hues, 4.5:1 on the moss */
|
|
104
91
|
}
|
|
105
|
-
/*
|
|
106
|
-
|
|
107
|
-
[data-palette="orchard"] .badge:not(.badge--soft) { background: var(--badge-bg, var(--highlight-1)); color: var(--badge-ink,
|
|
108
|
-
[data-palette="orchard"] .tile-badge:not(.tile-badge--plain) { background: var(--tile-badge-bg, var(--highlight-2));
|
|
109
|
-
[data-palette="orchard"] .calendar__day--mark { background: var(--calendar-day-mark-bg, color-mix(in srgb, var(--highlight-2)
|
|
110
|
-
/* fields are WHITE boxes on every ground (Lh 2026-09-25)
|
|
111
|
-
[data-palette="orchard"] .field { background: var(--field-bg, #ffffff); color:
|
|
112
|
-
[data-palette="orchard"] .pin__cell { background: var(--pin-cell-bg, #ffffff); color:
|
|
92
|
+
/* where the highlights land — written as the component's own rule, its knob still first, so a project's knob wins (a palette never DECLARES a
|
|
93
|
+
knob). Each fill says its side; the words on it follow */
|
|
94
|
+
[data-palette="orchard"] .badge:not(.badge--soft) { background: var(--badge-bg, var(--highlight-1)); color: var(--badge-ink, var(--ink-ondark)); }
|
|
95
|
+
[data-palette="orchard"] .tile-badge:not(.tile-badge--plain) { background: var(--tile-badge-bg, var(--highlight-2)); --dark: 0; }
|
|
96
|
+
[data-palette="orchard"] .calendar__day--mark { background: var(--calendar-day-mark-bg, color-mix(in srgb, var(--highlight-2) 15%, transparent)); }
|
|
97
|
+
/* fields are WHITE boxes on every ground (Lh 2026-09-25): a light ground, so the words typed in them are onlight, even on the moss card */
|
|
98
|
+
[data-palette="orchard"] .field { background: var(--field-bg, #ffffff); color: var(--ink-onlight); }
|
|
99
|
+
[data-palette="orchard"] .pin__cell { background: var(--pin-cell-bg, #ffffff); color: var(--ink-onlight); }
|
|
113
100
|
/* the vivid ones, tried on the live parts (Lh 2026-09-25): primary = yellow · a user avatar = fuchsia · ring = sky · a switch on = sky · maple only on small dots (the count, dot a); the chosen stack tab stays moss */
|
|
114
|
-
[data-palette="orchard"] .btn--primary { background: var(--btn-primary-bg, var(--highlight-2)); color: var(--btn-primary-ink,
|
|
115
|
-
[data-palette="orchard"] .avatar:not(.avatar--outline, .avatar--add, .avatar--on) { background: var(--avatar-bg, var(--highlight-4));
|
|
101
|
+
[data-palette="orchard"] .btn--primary { background: var(--btn-primary-bg, var(--highlight-2)); color: var(--btn-primary-ink, var(--ink-onlight)); }
|
|
102
|
+
[data-palette="orchard"] .avatar:not(.avatar--outline, .avatar--add, .avatar--on) { background: var(--avatar-bg, var(--highlight-4)); --dark: 1; }
|
|
116
103
|
[data-palette="orchard"] .ring::before { background: conic-gradient(var(--highlight-3) calc(var(--value) * 1%), var(--ink-tint) 0); }
|
|
117
|
-
[data-palette="orchard"] .toggle:checked { background: var(--highlight-3); }
|
|
118
|
-
[data-palette="orchard"] .toggle:checked::after { background: #ffffff; }
|
|
119
|
-
[data-palette="orchard"] .card--3 { --signal-error: #f4b7a6; --signal-warn: #f1d18a; --signal-ok: #cfe6b8; --signal-info: #bcd0ec; }
|
|
104
|
+
[data-palette="orchard"] .toggle:checked { background: var(--highlight-3); --accent-dark: 0; } /* sky is a light ground: its knob is onlight */
|
|
120
105
|
|
|
121
106
|
/* ---- VERS — Lh's own-palette pick (2026-09-25): white surface, champagne paper, sage brand; earth tones for tones 2·4·5 ---- */
|
|
122
107
|
[data-palette="vers"] {
|
|
123
108
|
--surface: #ffffff;
|
|
124
|
-
--
|
|
125
|
-
--
|
|
126
|
-
|
|
127
|
-
--card-1-bg: #f6e7cb;
|
|
128
|
-
--card-2-bg: #e3cfa6;
|
|
129
|
-
--card-3-bg: #
|
|
130
|
-
--card-4-bg: #c9d6b0;
|
|
131
|
-
--card-5-bg: #d4bf9c; --card-5-
|
|
132
|
-
|
|
133
|
-
--
|
|
134
|
-
--
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
--
|
|
139
|
-
--action-bg: #f6e7cb; --action-ink: #1f1b16; --action-border: transparent;
|
|
140
|
-
|
|
141
|
-
/* signals from Sweet Salmon #dd9787, deepened to read on white/champagne */
|
|
142
|
-
--pos: #7fa86f; --neg: #dd9787;
|
|
143
|
-
--signal-error: #b5503b; /* salmon */
|
|
144
|
-
--signal-warn: #a5782a; /* ochre */
|
|
145
|
-
--signal-ok: #4f7f4a; /* leaf */
|
|
146
|
-
--signal-info: #4d6f96; /* slate */
|
|
109
|
+
--ink-onlight: #1f1b16; --ink-onlight-muted: #534f4c; /* 4.5:1 on the wheat */
|
|
110
|
+
--ink-ondark: #ffffff; --ink-ondark-muted: #dee5dc; /* 4.6:1 on the sage */
|
|
111
|
+
|
|
112
|
+
--card-1-bg: #f6e7cb; /* paper — Champagne */
|
|
113
|
+
--card-2-bg: #e3cfa6; /* sand */
|
|
114
|
+
--card-3-bg: #496d3a; /* brand — Sage, on its own hue as far as white holds 4.5:1 on it and on its tint (#678d58 held it at 3.8) */
|
|
115
|
+
--card-4-bg: #c9d6b0; /* lichen */
|
|
116
|
+
--card-5-bg: #d4bf9c; --card-5-dark: 0; /* wheat — a light tone here */
|
|
117
|
+
|
|
118
|
+
--accent: #496d3a;
|
|
119
|
+
--action-bg: #f6e7cb; --action-border: transparent;
|
|
120
|
+
|
|
121
|
+
/* signals from Sweet Salmon #dd9787, deepened to read on every light ground (4.5:1 on the wheat) */
|
|
122
|
+
--pos: #7fa86f; --neg: #a76557; /* the salmon deepened as far as a falling delta's white words hold 4.5:1 (#dd9787 was 2.4) */
|
|
123
|
+
--signal-error-onlight: #803c2d; --signal-warn-onlight: #654b1e; --signal-ok-onlight: #3b5734; --signal-info-onlight: #3c5169;
|
|
147
124
|
--dot-a: #dd9787; --dot-b: #b08a5a;
|
|
148
125
|
}
|
|
149
126
|
|
|
150
|
-
/* Colored palettes
|
|
127
|
+
/* Colored palettes add a soft elevation under the card's edge. */
|
|
151
128
|
[data-palette] :is(.card, .band-stack) { box-shadow: var(--shadow-card); }
|
|
152
129
|
/* COLOURED MODE is the attribute, whatever its value: a project with colours of its own (the five
|
|
153
130
|
--color-* bases, or roles, in its theme.css) writes <html data-palette="own"> — no block here matches
|
|
154
131
|
"own", so only the three generic rules apply: the card's shadow, the soft outline, the field's soft
|
|
155
|
-
edge (forms.css); and the
|
|
156
|
-
|
|
132
|
+
edge (forms.css); and the controls' wireframe border steps back, as in every stock palette.
|
|
133
|
+
THE CARD KEEPS AN EDGE (Lh 2026-10-18, timebank's help sheet: white cards on the white sheet, "no different from
|
|
134
|
+
the background at all"). A card is one boundary, and WCAG 2.2 SC 1.4.11 asks 3:1 for it against what it stands
|
|
135
|
+
on. Light cards on a light ground cannot reach 3:1 by fill (a tone-1 card in a tone-1 sheet is 1:1), so the
|
|
136
|
+
edge carries it: the muted ink of the ground, which every palette already holds to AA on its surface.
|
|
137
|
+
`cardGrounds()` measures each tone on each ground (tests/card-grounds.spec.js). */
|
|
138
|
+
[data-palette] { --card-border: var(--on-surface-muted); --action-border: transparent; }
|
|
157
139
|
/* …but controls keep a faint edge so they still read as controls */
|
|
158
140
|
[data-palette] { --outline: color-mix(in srgb, currentColor 25%, transparent); }
|
package/css/people.css
CHANGED
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
display: grid;
|
|
17
17
|
place-items: center;
|
|
18
18
|
background: var(--avatar-bg, var(--card-2-bg));
|
|
19
|
-
|
|
19
|
+
--dark: var(--card-2-dark);
|
|
20
|
+
color: var(--avatar-ink, var(--card-ink));
|
|
20
21
|
font: var(--avatar-font, var(--type-label));
|
|
21
22
|
font-size: calc(var(--_size) * 0.3);
|
|
22
23
|
text-transform: uppercase;
|
|
@@ -30,10 +31,10 @@
|
|
|
30
31
|
.avatar--lg { --_size: var(--avatar-lg); }
|
|
31
32
|
.avatar--xl { --_size: var(--avatar-xl); } /* sheet head icon ring */
|
|
32
33
|
/* outline avatar: no fill, an edge — icons in a ring, "add" slots */
|
|
33
|
-
.avatar--outline { background: transparent; color: inherit; border: var(--border-w) solid var(--avatar-outline-border, var(--outline)); }
|
|
34
|
-
.avatar--add { background: transparent; color: inherit; border: var(--border-w) dashed var(--avatar-add-border, var(--outline)); }
|
|
34
|
+
.avatar--outline { background: transparent; --dark: inherit; color: inherit; border: var(--border-w) solid var(--avatar-outline-border, var(--outline)); }
|
|
35
|
+
.avatar--add { background: transparent; --dark: inherit; color: inherit; border: var(--border-w) dashed var(--avatar-add-border, var(--outline)); }
|
|
35
36
|
/* accent avatar: the "+7" tail, the selected person */
|
|
36
|
-
.avatar--on { background: var(--avatar-on-bg, var(--accent)); color: var(--avatar-on-ink, var(--
|
|
37
|
+
.avatar--on { background: var(--avatar-on-bg, var(--accent)); --dark: var(--accent-dark); color: var(--avatar-on-ink, var(--card-ink)); }
|
|
37
38
|
/* halo: faint concentric rings behind a hero avatar (decorative) */
|
|
38
39
|
.avatar--halo::before {
|
|
39
40
|
content: "";
|
package/css/post.css
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
/* ---- post-paper: the card stock. Its own ground and ink, wherever it lies; its parts read --_muted and --_rule ---- */
|
|
7
7
|
.post-paper {
|
|
8
8
|
background: var(--post-paper-bg, var(--card-1-bg));
|
|
9
|
-
|
|
9
|
+
--dark: var(--card-1-dark);
|
|
10
|
+
color: var(--post-paper-ink, var(--card-ink));
|
|
10
11
|
border-radius: var(--post-paper-radius, var(--sp-2));
|
|
11
12
|
box-shadow: var(--post-paper-shadow, var(--shadow-card));
|
|
12
13
|
--_muted: var(--post-paper-muted-ink, var(--card-muted));
|
package/css/sheet.css
CHANGED
|
@@ -205,12 +205,10 @@
|
|
|
205
205
|
the default spacing), the body's own top padding, and only when the sheet is paper.
|
|
206
206
|
A plain sheet keeps padding-top 0. A sheet in a stack wears the same class and the same
|
|
207
207
|
inset: the stack's own gap under the head is the card's colour, so the row still needs this white.
|
|
208
|
-
The
|
|
209
|
-
inherit a dark card's light ink, and the words would vanish on the white. */
|
|
208
|
+
The paper is a surface of the plain card's side: on a dark sheet its words still turn to onlight. */
|
|
210
209
|
.sheet--paper > .sheet__body {
|
|
211
210
|
--card-bg: var(--color-paper, #fff);
|
|
212
|
-
--
|
|
213
|
-
--card-muted: var(--_muted-on-paper, #555555);
|
|
211
|
+
--dark: var(--card-1-dark);
|
|
214
212
|
background: var(--card-bg);
|
|
215
213
|
color: var(--card-ink);
|
|
216
214
|
padding-top: var(--sp-6);
|
|
@@ -391,7 +389,7 @@
|
|
|
391
389
|
bottom: var(--sp-2);
|
|
392
390
|
padding: var(--sp-0) var(--sp-2);
|
|
393
391
|
border-radius: var(--map-credit-radius, var(--r-chip));
|
|
394
|
-
background: var(--map-credit-bg,
|
|
392
|
+
background: var(--map-credit-bg, var(--surface)); /* solid: at 80% over a map the muted words fell under 4.5:1 (clay, 3.9) */
|
|
395
393
|
color: var(--map-credit-ink, var(--on-surface-muted));
|
|
396
394
|
font: var(--map-credit-font, var(--type-caption));
|
|
397
395
|
pointer-events: none;
|
|
@@ -407,7 +405,8 @@
|
|
|
407
405
|
padding: var(--sp-2) var(--sp-4);
|
|
408
406
|
border-radius: var(--map-hint-radius, var(--r-chip));
|
|
409
407
|
background: var(--map-hint-bg, var(--card-3-bg));
|
|
410
|
-
|
|
408
|
+
--dark: var(--card-3-dark);
|
|
409
|
+
color: var(--map-hint-ink, var(--card-ink));
|
|
411
410
|
font: var(--map-hint-font, var(--type-label));
|
|
412
411
|
text-align: center;
|
|
413
412
|
box-shadow: var(--map-hint-shadow, var(--shadow-float));
|
|
@@ -456,9 +455,9 @@
|
|
|
456
455
|
width: var(--map-pick-size, var(--sp-6));
|
|
457
456
|
height: var(--map-pick-size, var(--sp-6));
|
|
458
457
|
border-radius: 50%;
|
|
459
|
-
border: var(--border-w) solid var(--map-pick-border, var(--accent));
|
|
458
|
+
border: var(--border-w) solid var(--map-pick-border, var(--action-accent));
|
|
460
459
|
background: var(--map-pick-bg, var(--surface));
|
|
461
|
-
color: var(--map-pick-mark-ink, var(--accent));
|
|
460
|
+
color: var(--map-pick-mark-ink, var(--action-accent));
|
|
462
461
|
box-shadow: var(--map-pick-shadow, var(--shadow-float));
|
|
463
462
|
pointer-events: none;
|
|
464
463
|
}
|
|
@@ -495,7 +494,10 @@
|
|
|
495
494
|
display: grid;
|
|
496
495
|
place-items: center;
|
|
497
496
|
font: var(--sheet-stage-foot-font, var(--type-caption));
|
|
498
|
-
|
|
497
|
+
/* words on the scrim: white on a strip of the scrim over it. The scrim alone is half black, so over a white page it is #808080, where white
|
|
498
|
+
is 3.9:1; doubled, #404040, 10:1. It read --card-3-ink, a brand's light ink, on a black scrim */
|
|
499
|
+
background: var(--sheet-stage-foot-bg, var(--scrim));
|
|
500
|
+
color: var(--sheet-stage-foot-ink, #ffffff);
|
|
499
501
|
z-index: 2;
|
|
500
502
|
}
|
|
501
503
|
|
|
@@ -538,6 +540,7 @@
|
|
|
538
540
|
display: flex; align-items: center; gap: var(--sp-3); min-height: var(--_row-h); min-width: 0; /* THIN: 32px, a summary line, not a button (Lh 2026-09-25) — the tap stays 44, see __go */
|
|
539
541
|
padding-inline: var(--sheet-step-bar-pad-x, var(--sp-3)); border-radius: var(--sheet-step-bar-radius, var(--r-chip));
|
|
540
542
|
background: var(--sheet-step-bar-bg, var(--ink-tint)); color: var(--sheet-step-bar-ink, inherit);
|
|
543
|
+
--card-muted: var(--card-ink); /* a tint of the ink: its secondary words are the full ink (no lighter shade holds 4.5:1 there) */
|
|
541
544
|
border-top: var(--sheet-step-border-w, 0rem) solid var(--sheet-step-border, currentColor); /* a rule instead of the bar: set this, the bar's bg transparent, radius 0 */
|
|
542
545
|
}
|
|
543
546
|
.sheet-step__title { font: var(--sheet-step-title-font, var(--type-label)); margin: 0; flex: 0 1 auto; min-width: 0; outline: none; /* the label size, not a body title: a pile of rows must stay small (Lh 2026-09-24) */ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -548,7 +551,7 @@
|
|
|
548
551
|
border-radius: 50%; font: var(--sheet-step-num-font, var(--type-caption)); line-height: 1; font-variant-numeric: tabular-nums;
|
|
549
552
|
background: var(--sheet-step-num-bg, var(--card-bg)); color: var(--sheet-step-num-ink, inherit);
|
|
550
553
|
}
|
|
551
|
-
.sheet-step__summary { color:
|
|
554
|
+
.sheet-step__summary { color: var(--sheet-step-summary-ink, var(--card-muted)); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
552
555
|
.sheet-step__check { margin-inline-start: auto; }
|
|
553
556
|
.sheet-step__body { min-height: 0; overflow: clip; overflow-clip-margin: var(--sp-1); }
|
|
554
557
|
.sheet-step__inner { display: grid; gap: var(--card-gap); padding-block: var(--card-gap); padding-inline: var(--sheet-step-inner-pad-x, var(--sheet-step-bar-pad-x, var(--sp-3))); } /* the open step's content in the frame of its title's words (the bar's own inset), so it reads as that step's (Lh 2026-09-28, #153) */
|
package/css/stack.css
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
bottom, the headroom above is the base's (block below).
|
|
33
33
|
--flood (with --closed): an open sheet fills the whole screen, over the top bar.
|
|
34
34
|
Direct children only, five at most (slots are :nth-child below):
|
|
35
|
-
first = the back of the stack, last = the front.
|
|
35
|
+
first = the back of the stack, last = the front. docs/reference.md "Sheet stack
|
|
36
36
|
markup". The SheetStack component opens and closes a --tap stack; without it the
|
|
37
37
|
stack still renders, it just won't open.
|
|
38
38
|
============================================================ */
|
package/css/sticky.css
CHANGED
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
only its content box, which stops one fold short of the right and bottom edges; the paper's negative margins run
|
|
17
17
|
back out to the full size. The paper takes the tone by `inherit`. */
|
|
18
18
|
.sticky {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
--dark: var(--sticky-dark, 0); /* a note is pastel paper: a light ground in any palette and any mode, so its words are onlight */
|
|
20
|
+
color: var(--sticky-ink, var(--card-ink));
|
|
21
|
+
--_muted: var(--card-muted);
|
|
21
22
|
padding-inline-end: var(--sticky-fold, var(--sp-6)); /* the knob, read by a real property first (the knob test probes that one); --_fold hands the same value to the paper and the flap */
|
|
22
23
|
--_fold: var(--sticky-fold, var(--sp-6));
|
|
23
24
|
position: relative;
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
.sticky__head:has(> .sticky-date) > .ph { flex: none; width: var(--sticky-pic-size, calc(var(--tap) * 1.5)); min-height: 0; aspect-ratio: 1; } /* beside a date the picture is a small square at the start */
|
|
82
83
|
.sticky__body { flex: 1 1 auto; min-width: 0; min-height: 0; overflow: clip; /* words past the note's room are cut, the foot keeps its place */ font: var(--sticky-font, var(--type-title)); overflow-wrap: anywhere; }
|
|
83
84
|
.sticky--small .sticky__body { font: var(--sticky-small-font, var(--type-label)); } /* the note measured its words and they did not fit at its size (src/sticky/fit.ts) */
|
|
84
|
-
.sticky__paper > :not(.sticky__body) > .chip { border-color: transparent; background-color: var(--sticky-chip-bg, rgb(255 255 255 / 0.85)); color: var(--sticky-ink,
|
|
85
|
+
.sticky__paper > :not(.sticky__body) > .chip { border-color: transparent; background-color: var(--sticky-chip-bg, rgb(255 255 255 / 0.85)); --dark: inherit; color: var(--sticky-ink, var(--card-ink)); } /* a chip on a note is a label ON the paper (whose note it is): a pale ground nearly opaque (it may lie over words), no edge, the note's ink */
|
|
85
86
|
.sticky__foot { flex: none; font: var(--sticky-foot-font, var(--type-caption)); color: var(--sticky-muted-ink, var(--_muted)); padding-inline-end: var(--_fold); } /* the line stops before the fold */
|
|
86
87
|
/* the flap: a square in the corner — the paper's cut takes its outer half, what is left is the triangle lying on the note */
|
|
87
88
|
.sticky__fold {
|
|
@@ -109,7 +110,7 @@
|
|
|
109
110
|
|
|
110
111
|
/* ---- sticky date: the day, big, the month under it — at the end of the note's head (its top-right corner) ----
|
|
111
112
|
<div class="sticky__head">…<time class="sticky-date" datetime="2026-02-14"><span class="sticky-date__day">14</span><span class="sticky-date__month">ก.พ.</span></time></div> */
|
|
112
|
-
.sticky-date { display: grid; justify-items: end; margin-inline-start: auto; text-align: end; color: var(--sticky-ink,
|
|
113
|
+
.sticky-date { display: grid; justify-items: end; margin-inline-start: auto; text-align: end; color: var(--sticky-ink, var(--card-ink)); }
|
|
113
114
|
.sticky-date__day { font: var(--sticky-date-day-font, var(--type-stat)); }
|
|
114
115
|
.sticky-date__month { font: var(--sticky-date-month-font, var(--type-caption)); color: var(--sticky-muted-ink, var(--_muted)); }
|
|
115
116
|
|
|
@@ -393,7 +394,7 @@
|
|
|
393
394
|
font: inherit;
|
|
394
395
|
}
|
|
395
396
|
.sticky-heading__title { min-width: 0; max-width: 100%; font: var(--sticky-heading-title-font, var(--type-label)); line-height: 1.35; /* Thai marks stack taller than the label's 1.2, and overflow clips them */ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
396
|
-
.sticky-heading__caption { font: var(--sticky-heading-caption-font, var(--type-caption)); color:
|
|
397
|
+
.sticky-heading__caption { font: var(--sticky-heading-caption-font, var(--type-caption)); color: var(--sticky-heading-caption-ink, var(--card-muted)); white-space: nowrap; } /* the muted words of what it stands on: a note, or the screen */
|
|
397
398
|
/* on a note: across the top of its paper, and the note's words start under it */
|
|
398
399
|
.sticky__stuck > .sticky-heading { position: absolute; inset: var(--sp-2) var(--sp-4) auto; }
|
|
399
400
|
.sticky:has(> .sticky__stuck > .sticky-heading) > .sticky__paper { padding-block-start: var(--sticky-heading-room, calc(var(--sp-12) + var(--sp-4))); }
|
package/css/theme.template.css
CHANGED
|
@@ -43,13 +43,22 @@
|
|
|
43
43
|
/* --color-brand: #ef4e0b; */ /* the primary action, the strong card */
|
|
44
44
|
/* --color-on-brand: #fff4ec; */ /* the words on the brand */
|
|
45
45
|
|
|
46
|
+
/* ---- ink: two sets, ONLIGHT and ONDARK (docs/reference.md "Ink follows its ground") ----
|
|
47
|
+
Every word and glyph on a light ground is onlight, on a dark ground ondark. Set the two sets; each one's ink and its muted shade
|
|
48
|
+
hold 4.5:1 on every ground of its side (inkGrounds() measures it). Unset, --color-ink and --color-on-brand derive them.
|
|
49
|
+
--ink-onlight --ink-onlight-muted --ink-ondark --ink-ondark-muted
|
|
50
|
+
---- sides: each ground says only whether it is dark (1) or light (0); its words and glyphs follow ----
|
|
51
|
+
--surface-dark (0) --card-1-dark (0) --card-2-dark (0) --card-3-dark (1) --card-4-dark (0) --card-5-dark (1)
|
|
52
|
+
--accent-dark (1, the brand fill) --action-dark (0, the paper of buttons, chips, fields) --neg-dark (1, a falling Delta)
|
|
53
|
+
A dark mode is these sides turned to 1 with their fills darkened, in a [data-mode="dark"] block of your own: no rule per piece.
|
|
54
|
+
A surface of your own: give it a fill and `--dark: 1` (or 0), and its --card-ink / --card-muted that side's set. */
|
|
55
|
+
|
|
46
56
|
/* ---- colour roles: only where a derivation is not what you want — a role set here wins over it ----
|
|
47
|
-
--surface --
|
|
48
|
-
--card-
|
|
49
|
-
--
|
|
50
|
-
--accent --on-accent --action-bg --action-ink --action-border
|
|
57
|
+
--surface --card-1-bg … --card-5-bg (five card tones: fills only, their words follow their side)
|
|
58
|
+
--card-border (a card's fill or its --card-border holds 3:1 on its ground: cardGrounds(), docs/reference.md)
|
|
59
|
+
--accent --action-bg --action-border
|
|
51
60
|
--pos --neg --dot-a --dot-b
|
|
52
|
-
--signal-ok --signal-warn --signal-error --signal-info (the signal set: green · yellow · red ·
|
|
53
|
-
keep the meaning;
|
|
54
|
-
|
|
61
|
+
--signal-ok-onlight --signal-warn-onlight --signal-error-onlight --signal-info-onlight (the signal set: green · yellow · red ·
|
|
62
|
+
blue — retune the shade, keep the meaning; 4.5:1 on every light ground) and --signal-*-ondark (on the dark side; the ondark ink
|
|
63
|
+
unless set). --signal-*-soft, the light ground of each, follows by itself */
|
|
55
64
|
}
|