@usableapp/cardds 0.3.0 → 0.4.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/README.md +12 -8
- package/css/actions.css +38 -27
- package/css/base.css +9 -9
- package/css/card.css +24 -23
- package/css/choice.css +50 -50
- package/css/forms.css +18 -18
- package/css/journey.css +16 -16
- package/css/layover.css +57 -60
- package/css/lists.css +52 -43
- package/css/media.css +96 -60
- package/css/numbers.css +41 -25
- package/css/people.css +11 -11
- package/css/sheet.css +28 -24
- package/css/stack.css +3 -3
- package/css/theme.template.css +6 -3
- package/dist/actions/Btn.d.ts +109 -108
- package/dist/actions/BtnRow.d.ts +2 -2
- package/dist/actions/Chip.d.ts +102 -101
- package/dist/actions/Dot.d.ts +2 -2
- package/dist/actions/Dropdown.d.ts +4 -4
- package/dist/actions/Fab.d.ts +2 -2
- package/dist/actions/IconBtn.d.ts +107 -106
- package/dist/actions/Link.d.ts +105 -104
- package/dist/actions/Segment.d.ts +3 -3
- package/dist/cardds.css +443 -369
- package/dist/cards/Card.d.ts +99 -98
- package/dist/cards/CardFoot.d.ts +2 -2
- package/dist/cards/CardHead.d.ts +2 -2
- package/dist/cards/CardParts.d.ts +7 -7
- package/dist/cards/Placeholder.d.ts +2 -2
- package/dist/cards/Stat.d.ts +7 -5
- package/dist/cards/Stat.js +2 -2
- package/dist/choice/Calendar.d.ts +2 -2
- package/dist/choice/Check.d.ts +3 -3
- package/dist/choice/DayStrip.d.ts +3 -3
- package/dist/choice/Mood.d.ts +2 -2
- package/dist/choice/Slider.d.ts +2 -2
- package/dist/forms/AddRow.d.ts +2 -2
- package/dist/forms/Composer.d.ts +2 -2
- package/dist/forms/Field.d.ts +2 -2
- package/dist/forms/FileBtn.d.ts +2 -2
- package/dist/forms/Pin.d.ts +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/journey/NoteRow.d.ts +2 -2
- package/dist/journey/Route.d.ts +2 -2
- package/dist/journey/TileBadge.d.ts +2 -2
- package/dist/layover/Banner.d.ts +2 -2
- package/dist/layover/Callout.d.ts +2 -2
- package/dist/layover/Deck.d.ts +3 -3
- package/dist/lists/Bubble.d.ts +3 -3
- package/dist/lists/Kv.d.ts +5 -5
- package/dist/lists/Legend.d.ts +3 -3
- package/dist/lists/Row.d.ts +14 -285
- package/dist/lists/Row.js +10 -3
- package/dist/lists/Timeline.d.ts +3 -3
- package/dist/media/MapArea.d.ts +2 -2
- package/dist/media/Mosaic.d.ts +3 -3
- package/dist/media/Postcard.d.ts +17 -7
- package/dist/media/Postcard.js +8 -5
- package/dist/media/Quote.d.ts +2 -2
- package/dist/media/Tile.d.ts +5 -4
- package/dist/numbers/Badge.d.ts +2 -2
- package/dist/numbers/Band.d.ts +3 -3
- package/dist/numbers/Bars.d.ts +3 -3
- package/dist/numbers/DotGrid.d.ts +2 -2
- package/dist/numbers/Picker.d.ts +3 -3
- package/dist/numbers/Progress.d.ts +9 -0
- package/dist/numbers/Progress.js +7 -0
- package/dist/numbers/Ring.d.ts +2 -2
- package/dist/numbers/Track.d.ts +3 -3
- package/dist/people/Avatar.d.ts +100 -99
- package/dist/people/AvatarPick.d.ts +3 -3
- package/dist/scaffold/ActionBar.d.ts +3 -3
- package/dist/scaffold/AppBar.d.ts +2 -2
- package/dist/scaffold/BaseContent.d.ts +3 -3
- package/dist/scaffold/Centre.d.ts +3 -3
- package/dist/scaffold/EmptyState.d.ts +2 -2
- package/dist/scaffold/FilterRow.d.ts +2 -2
- package/dist/scaffold/FloatBar.d.ts +105 -104
- package/dist/scaffold/PagerAt.d.ts +2 -2
- package/dist/scaffold/Screen.d.ts +100 -99
- package/dist/scaffold/TopBar.d.ts +2 -2
- package/dist/sheets/Drawer.d.ts +7 -7
- package/dist/sheets/Drawer.js +1 -1
- package/dist/sheets/Sheet.d.ts +3 -5
- package/dist/sheets/Sheet.js +2 -2
- package/dist/sheets/SheetBody.d.ts +2 -2
- package/dist/sheets/SheetHead.d.ts +2 -2
- package/dist/sheets/SheetStack.d.ts +5 -5
- package/dist/sheets/SheetStack.js +3 -3
- package/dist/sheets/SheetStage.d.ts +5 -7
- package/dist/sheets/SheetStage.js +3 -3
- package/dist/sheets/StackBack.d.ts +7 -0
- package/dist/sheets/StackBack.js +7 -0
- package/dist/sheets/Step.d.ts +2 -2
- package/dist/type/Icon.d.ts +22 -7
- package/dist/type/Icon.js +27 -4
- package/dist/type/Text.d.ts +7 -1
- package/dist/type/Text.js +2 -2
- package/package.json +3 -2
- package/dist/sheets/CardBack.d.ts +0 -7
- package/dist/sheets/CardBack.js +0 -7
package/css/journey.css
CHANGED
|
@@ -5,40 +5,40 @@
|
|
|
5
5
|
============================================================ */
|
|
6
6
|
|
|
7
7
|
/* ---- route: endpoint · dotted connector (icon in middle) · endpoint ---- */
|
|
8
|
-
.route { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; column-gap: var(--sp-1); } /* line → icon: --sp-1, as the via always had; code → line is the code row's own --sp-3 */
|
|
8
|
+
.route { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; column-gap: var(--route-col-gap, var(--sp-1)); } /* line → icon: --sp-1, as the via always had; code → line is the code row's own --sp-3 */
|
|
9
9
|
/* the two endpoints get EQUAL columns whatever their words measure, so the via
|
|
10
10
|
(the icon alone) sits at the card's centre; each dotted run lives on ITS
|
|
11
11
|
endpoint's code row and fills that side's leftover — with short names the
|
|
12
12
|
runs are long and equal, a long place name wraps in its half instead of
|
|
13
13
|
pushing the plane (Lh 2026-09-16) */
|
|
14
14
|
|
|
15
|
-
.route__point { display: grid; gap: var(--sp-0); min-width: 0; }
|
|
15
|
+
.route__point { display: grid; gap: var(--route-point-gap, var(--sp-0)); min-width: 0; }
|
|
16
16
|
.route__point--end { text-align: right; }
|
|
17
17
|
|
|
18
|
-
.route__code { font: var(--type-h2); letter-spacing: var(--track-h2); display: flex; align-items: center; gap: var(--sp-3); }
|
|
18
|
+
.route__code { font: var(--route-code-font, var(--type-h2)); letter-spacing: var(--track-h2); display: flex; align-items: center; gap: var(--route-code-gap, var(--sp-3)); }
|
|
19
19
|
.route__code::after, .route__point--end .route__code::before { content: ""; flex: 1; border-top: var(--rule-w) dotted currentColor; opacity: 0.65; }
|
|
20
20
|
.route__point--end .route__code::after { content: none; }
|
|
21
|
-
.route__time { font: var(--type-body); font-variant-numeric: tabular-nums; }
|
|
22
|
-
.route__place { font: var(--type-caption); color: var(--card-muted); }
|
|
21
|
+
.route__time { font: var(--route-time-font, var(--type-body)); font-variant-numeric: tabular-nums; }
|
|
22
|
+
.route__place { font: var(--route-place-font, var(--type-caption)); color: var(--route-place-ink, var(--card-muted)); }
|
|
23
23
|
.card--3 .route__place { color: inherit; opacity: 0.7; }
|
|
24
24
|
|
|
25
|
-
.route__via { display: flex; align-items: center; opacity: 0.65; font-size: var(--fs-body); }
|
|
25
|
+
.route__via { display: flex; align-items: center; opacity: 0.65; font-size: var(--route-via-font-size, var(--fs-body)); }
|
|
26
26
|
|
|
27
27
|
/* ---- tile badge: tiny label over a big value (gate, seat, zone) ---- */
|
|
28
28
|
.tile-badge {
|
|
29
29
|
display: inline-grid;
|
|
30
30
|
justify-items: center;
|
|
31
|
-
gap: var(--sp-0);
|
|
32
|
-
padding: var(--sp-1) var(--sp-2);
|
|
33
|
-
border-radius: var(--r-badge);
|
|
34
|
-
background: var(--card-3-bg);
|
|
35
|
-
color: var(--card-3-ink);
|
|
31
|
+
gap: var(--tile-badge-gap, var(--sp-0));
|
|
32
|
+
padding: var(--tile-badge-pad-y, var(--sp-1)) var(--tile-badge-pad-x, var(--sp-2));
|
|
33
|
+
border-radius: var(--tile-badge-radius, var(--r-badge));
|
|
34
|
+
background: var(--tile-badge-bg, var(--card-3-bg));
|
|
35
|
+
color: var(--tile-badge-ink, var(--card-3-ink));
|
|
36
36
|
}
|
|
37
|
-
.tile-badge__label { font: var(--type-overline); letter-spacing: var(--track-overline); text-transform: uppercase; opacity: 0.7; }
|
|
37
|
+
.tile-badge__label { font: var(--tile-badge-label-font, var(--type-overline)); letter-spacing: var(--track-overline); text-transform: uppercase; opacity: 0.7; }
|
|
38
38
|
.tile-badge__value { font: 800 var(--fs-lg)/1.1 var(--font-display); font-variant-numeric: tabular-nums; }
|
|
39
39
|
|
|
40
40
|
/* plain: no fill — a date box beside a title (Jun / 18) */
|
|
41
|
-
.tile-badge--plain { background: transparent; color: inherit; padding: 0; min-width: var(--tap-sm); }
|
|
41
|
+
.tile-badge--plain { background: transparent; color: inherit; padding: 0; min-width: var(--tile-badge-plain-min-w, var(--tap-sm)); }
|
|
42
42
|
.tile-badge--plain .tile-badge__value { font: 800 var(--fs-h1)/1 var(--font-display); }
|
|
43
43
|
|
|
44
44
|
/* corner badge: pin a tile badge on media (rating, price) — .card__media is relative */
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
.note-row {
|
|
49
49
|
display: flex;
|
|
50
50
|
align-items: center;
|
|
51
|
-
gap: var(--sp-2);
|
|
52
|
-
font: var(--type-caption);
|
|
53
|
-
color: var(--card-muted);
|
|
51
|
+
gap: var(--note-row-gap, var(--sp-2));
|
|
52
|
+
font: var(--note-row-font, var(--type-caption));
|
|
53
|
+
color: var(--note-row-ink, var(--card-muted));
|
|
54
54
|
}
|
|
55
55
|
.card--3 .note-row { color: inherit; opacity: 0.7; }
|
package/css/layover.css
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
lives in sheet.css; these compose with .sheet-stage.
|
|
6
6
|
============================================================ */
|
|
7
7
|
|
|
8
|
-
/* ----
|
|
9
|
-
<div class="sheet-stage sheet-stage--
|
|
8
|
+
/* ---- the Modal — the case drops in, its drawer opens below (Lh 2026-09-16: ONE card, two parts)
|
|
9
|
+
<div class="sheet-stage sheet-stage--dim"> (dim = the page under a scrim; a Modal on a clean ground is the stage without it — Lh 2026-09-22, `--ask` retired: the stage does the ground, the modal centres itself)
|
|
10
10
|
<article class="card modal">
|
|
11
11
|
<div class="modal__lift">…the card's content (a head, rows, a timeline)…</div>
|
|
12
12
|
<div class="modal__drawer"><h2 class="t-h2">Take the case?</h2><p class="t-caption">This cannot be undone.</p>
|
|
@@ -17,36 +17,33 @@
|
|
|
17
17
|
.modal is the card — no border (the shadow is its edge on the scrim);
|
|
18
18
|
.modal__lift the light part that holds the thing being asked about (it
|
|
19
19
|
scrolls when tall); .modal__drawer the dark end that asks. The ground is
|
|
20
|
-
the
|
|
20
|
+
whatever the stage shows (dim it or not). Two beats (2 × --motion-sheet) when
|
|
21
21
|
the stage appears, and the same two backwards when it closes:
|
|
22
22
|
1. the card drops in from above the stage to the screen's centre — its
|
|
23
23
|
drawer still inside it, height 0: nothing of the ask shows yet
|
|
24
24
|
2. the drawer comes out of the card's bottom edge while the lift moves
|
|
25
25
|
up, both at once: the card grows from its centre, which never moves
|
|
26
|
-
(the
|
|
26
|
+
(the modal centres itself — absolute, margin auto; a growing card keeps its middle where it is)
|
|
27
27
|
Closing: a click on any button in the drawer plays the same animations in
|
|
28
28
|
reverse (cardds.js: Animation.reverse() on each — nothing duplicated), then
|
|
29
29
|
fires "cardds:modal" on the .sheet-stage (bubbles, detail.answer from the
|
|
30
30
|
button's data-answer) for the app to remove the stage.
|
|
31
31
|
Reduced motion: the finished state, no beats; closing fires at once. */
|
|
32
|
-
.sheet-stage--ask {
|
|
33
|
-
--drawer-h: 14rem;
|
|
34
|
-
display: grid;
|
|
35
|
-
align-content: center; /* the card at the screen's centre — and kept there as it grows */
|
|
36
|
-
padding-inline: var(--screen-pad);
|
|
37
|
-
}
|
|
38
|
-
.sheet-stage--ask::after { content: ""; position: absolute; inset: 0; background: var(--scrim); } /* the page dimmed */
|
|
39
|
-
.sheet-stage--ask > .sheet-stage__bg { filter: blur(var(--sp-2)); }
|
|
40
32
|
.modal {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
--drawer-h: 14rem;
|
|
34
|
+
position: absolute; /* at the stage's centre, and kept there as it grows: absolute + margin auto re-centres on every height */
|
|
35
|
+
inset: 0;
|
|
36
|
+
margin: auto;
|
|
37
|
+
height: fit-content; /* inset 0 alone would stretch it to the stage: its own height, then the margins share the rest */
|
|
38
|
+
width: calc(100% - 2 * var(--screen-pad));
|
|
39
|
+
z-index: 2; /* over the dim stage's scrim (z 1) */
|
|
40
|
+
max-height: calc(100cqh - 2 * var(--sp-5)); /* cqh: the stage (a size container) */
|
|
44
41
|
padding: 0; /* the parts pad themselves */
|
|
45
42
|
border: 0; /* no frame on the modal (Lh 2026-09-16) — its edge is the shadow */
|
|
46
43
|
display: grid;
|
|
47
44
|
grid-template-rows: minmax(0, 1fr) auto;
|
|
48
45
|
overflow: clip;
|
|
49
|
-
box-shadow: var(--shadow-sheet);
|
|
46
|
+
box-shadow: var(--modal-shadow, var(--shadow-sheet));
|
|
50
47
|
}
|
|
51
48
|
.modal__lift {
|
|
52
49
|
padding: var(--card-pad);
|
|
@@ -60,15 +57,15 @@
|
|
|
60
57
|
.modal__drawer {
|
|
61
58
|
height: var(--drawer-h);
|
|
62
59
|
box-sizing: border-box;
|
|
63
|
-
padding: var(--sp-5);
|
|
60
|
+
padding: var(--modal-drawer-pad, var(--sp-5));
|
|
64
61
|
overflow: clip;
|
|
65
62
|
display: grid;
|
|
66
63
|
align-content: center;
|
|
67
64
|
justify-items: center;
|
|
68
|
-
gap: var(--sp-1);
|
|
65
|
+
gap: var(--modal-drawer-gap, var(--sp-1));
|
|
69
66
|
text-align: center;
|
|
70
|
-
background: var(--card-3-bg);
|
|
71
|
-
color: var(--card-3-ink);
|
|
67
|
+
background: var(--modal-drawer-bg, var(--card-3-bg));
|
|
68
|
+
color: var(--modal-drawer-ink, var(--card-3-ink));
|
|
72
69
|
--accent: var(--card-3-ink); /* the one solid button inverts on the dark drawer */
|
|
73
70
|
--on-accent: var(--card-3-bg);
|
|
74
71
|
}
|
|
@@ -84,14 +81,14 @@
|
|
|
84
81
|
}
|
|
85
82
|
@keyframes modal-open {
|
|
86
83
|
0%, 50% { height: 0; padding-block: 0; } /* inside the card */
|
|
87
|
-
100% { height: var(--drawer-h); padding-block: var(--sp-5); } /* 2. out below, the lift up, together */
|
|
84
|
+
100% { height: var(--drawer-h); padding-block: var(--modal-drawer-pad, var(--sp-5)); } /* 2. out below, the lift up, together — the same knob the rule reads: a keyframe that pinned the value would make the knob dead */
|
|
88
85
|
}
|
|
89
86
|
}
|
|
90
87
|
|
|
91
|
-
.btn-trio { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-3); }
|
|
88
|
+
.btn-trio { display: flex; align-items: center; gap: var(--btn-trio-gap, var(--sp-3)); margin-top: var(--sp-3); }
|
|
92
89
|
.btn-trio__dots {
|
|
93
|
-
width: var(--sp-5);
|
|
94
|
-
height: var(--sp-1);
|
|
90
|
+
width: var(--btn-trio-dots-w, var(--sp-5));
|
|
91
|
+
height: var(--btn-trio-dots-h, var(--sp-1));
|
|
95
92
|
background: radial-gradient(circle, currentColor var(--sp-0), transparent calc(var(--sp-0) + 0.5px)) 0 0 / calc(var(--sp-5) / 2) 100% repeat-x;
|
|
96
93
|
opacity: 0.4;
|
|
97
94
|
}
|
|
@@ -112,31 +109,31 @@
|
|
|
112
109
|
display: none; /* explicit closed state — never display on the base rule */
|
|
113
110
|
margin: 0;
|
|
114
111
|
inset: auto;
|
|
115
|
-
border: var(--border-w) solid var(--action-border);
|
|
116
|
-
border-radius: var(--r-card);
|
|
112
|
+
border: var(--border-w) solid var(--menu-border, var(--action-border));
|
|
113
|
+
border-radius: var(--menu-radius, var(--r-card));
|
|
117
114
|
--menu-pad: var(--sp-2); /* published: a row's radius is concentric with the panel's */
|
|
118
115
|
padding: var(--menu-pad);
|
|
119
116
|
min-width: 12rem;
|
|
120
|
-
background: var(--action-bg);
|
|
121
|
-
color: var(--action-ink);
|
|
122
|
-
box-shadow: var(--shadow-float);
|
|
117
|
+
background: var(--menu-bg, var(--action-bg));
|
|
118
|
+
color: var(--menu-ink, var(--action-ink));
|
|
119
|
+
box-shadow: var(--menu-shadow, var(--shadow-float));
|
|
123
120
|
}
|
|
124
121
|
.menu:popover-open { display: grid; }
|
|
125
122
|
.menu:not([popover]) { display: grid; position: relative; } /* inline usage (no attribute) */
|
|
126
123
|
.menu__item {
|
|
127
124
|
display: flex;
|
|
128
125
|
align-items: center;
|
|
129
|
-
gap: var(--sp-3);
|
|
130
|
-
min-height: var(--tap);
|
|
126
|
+
gap: var(--menu-item-gap, var(--sp-3));
|
|
127
|
+
min-height: var(--menu-item-min-h, var(--tap));
|
|
131
128
|
width: 100%;
|
|
132
|
-
padding: 0 var(--sp-3);
|
|
129
|
+
padding: var(--menu-item-pad-y, 0) var(--menu-item-pad-x, var(--sp-3));
|
|
133
130
|
border: 0;
|
|
134
131
|
/* concentric with the panel: the card radius minus the panel's padding, so the
|
|
135
132
|
highlight's curve follows the outer corner (Lh 2026-09-16) */
|
|
136
133
|
border-radius: calc(var(--r-card) - var(--menu-pad, var(--sp-2)));
|
|
137
134
|
background: transparent;
|
|
138
135
|
color: inherit;
|
|
139
|
-
font: var(--type-title);
|
|
136
|
+
font: var(--menu-item-font, var(--type-title));
|
|
140
137
|
text-align: left;
|
|
141
138
|
cursor: pointer;
|
|
142
139
|
}
|
|
@@ -164,12 +161,12 @@
|
|
|
164
161
|
/* ---- banner: a chip that opens into a tinted card, no JS ----
|
|
165
162
|
<details class="banner"><summary class="chip chip--on">Save $30 on orders over $70 <svg class="icon icon--xs"/></summary>
|
|
166
163
|
<div class="card card--3 banner__body">…</div></details> */
|
|
167
|
-
.banner { display: grid; gap: var(--sp-2); justify-items: start; }
|
|
164
|
+
.banner { display: grid; gap: var(--banner-gap, var(--sp-2)); justify-items: start; }
|
|
168
165
|
.banner > summary { list-style: none; cursor: pointer; }
|
|
169
166
|
.banner > summary::-webkit-details-marker { display: none; }
|
|
170
167
|
.banner > summary .icon { transition: rotate 0.2s ease; }
|
|
171
168
|
.banner[open] > summary .icon { rotate: 180deg; }
|
|
172
|
-
.banner__body { width: 100%; padding: var(--sp-4) var(--sp-5); --card-gap: var(--sp-1); }
|
|
169
|
+
.banner__body { width: 100%; padding: var(--banner-body-pad-y, var(--sp-4)) var(--banner-body-pad-x, var(--sp-5)); --card-gap: var(--sp-1); }
|
|
173
170
|
.banner::details-content { width: 100%; } /* Chromium wraps the content in this pseudo; justify-items: start shrink-wrapped it, so the body never reached the width */
|
|
174
171
|
@supports (interpolate-size: allow-keywords) {
|
|
175
172
|
@media (prefers-reduced-motion: no-preference) {
|
|
@@ -187,9 +184,9 @@
|
|
|
187
184
|
bottom: var(--sp-5);
|
|
188
185
|
max-width: var(--screen-w);
|
|
189
186
|
margin-inline: auto;
|
|
190
|
-
padding-inline: var(--sp-4);
|
|
187
|
+
padding-inline: var(--float-bar-pad-x, var(--sp-4));
|
|
191
188
|
display: flex;
|
|
192
|
-
gap: var(--sp-2);
|
|
189
|
+
gap: var(--float-bar-gap, var(--sp-2));
|
|
193
190
|
align-items: center;
|
|
194
191
|
z-index: 30;
|
|
195
192
|
}
|
|
@@ -204,29 +201,29 @@
|
|
|
204
201
|
display: flex;
|
|
205
202
|
justify-content: space-around;
|
|
206
203
|
align-items: center;
|
|
207
|
-
min-height: var(--bar-h);
|
|
208
|
-
padding: var(--sp-1);
|
|
209
|
-
border-radius: var(--r-chip);
|
|
210
|
-
border: var(--border-w) solid var(--action-border);
|
|
211
|
-
background: color-mix(in srgb, var(--action-bg) 82%, transparent);
|
|
212
|
-
color: var(--action-ink);
|
|
204
|
+
min-height: var(--float-bar-pill-min-h, var(--bar-h));
|
|
205
|
+
padding: var(--float-bar-pill-pad, var(--sp-1));
|
|
206
|
+
border-radius: var(--float-bar-pill-radius, var(--r-chip));
|
|
207
|
+
border: var(--border-w) solid var(--float-bar-pill-border, var(--action-border));
|
|
208
|
+
background: var(--float-bar-pill-bg, color-mix(in srgb, var(--action-bg) 82%, transparent));
|
|
209
|
+
color: var(--float-bar-pill-ink, var(--action-ink));
|
|
213
210
|
backdrop-filter: blur(var(--sp-3));
|
|
214
211
|
-webkit-backdrop-filter: blur(var(--sp-3));
|
|
215
|
-
box-shadow: var(--shadow-float);
|
|
212
|
+
box-shadow: var(--float-bar-pill-shadow, var(--shadow-float));
|
|
216
213
|
}
|
|
217
214
|
.float-bar__item {
|
|
218
215
|
flex: 1;
|
|
219
216
|
min-width: 0;
|
|
220
217
|
display: grid;
|
|
221
218
|
justify-items: center;
|
|
222
|
-
gap: var(--sp-0);
|
|
223
|
-
min-height: var(--tap-lg);
|
|
224
|
-
padding: var(--sp-1);
|
|
219
|
+
gap: var(--float-bar-item-gap, var(--sp-0));
|
|
220
|
+
min-height: var(--float-bar-item-min-h, var(--tap-lg));
|
|
221
|
+
padding: var(--float-bar-item-pad, var(--sp-1));
|
|
225
222
|
border: 0;
|
|
226
|
-
border-radius: var(--r-chip);
|
|
223
|
+
border-radius: var(--float-bar-item-radius, var(--r-chip));
|
|
227
224
|
background: transparent;
|
|
228
225
|
color: inherit;
|
|
229
|
-
font: var(--type-caption);
|
|
226
|
+
font: var(--float-bar-item-font, var(--type-caption));
|
|
230
227
|
text-decoration: none;
|
|
231
228
|
opacity: 0.6;
|
|
232
229
|
overflow: hidden;
|
|
@@ -244,15 +241,15 @@
|
|
|
244
241
|
.callout {
|
|
245
242
|
position: absolute;
|
|
246
243
|
display: grid;
|
|
247
|
-
gap: var(--sp-0);
|
|
244
|
+
gap: var(--callout-gap, var(--sp-0));
|
|
248
245
|
width: max-content;
|
|
249
246
|
max-width: 15rem;
|
|
250
|
-
padding: var(--sp-3) var(--sp-4);
|
|
251
|
-
border: var(--border-w) solid var(--action-border);
|
|
252
|
-
border-radius: var(--r-card);
|
|
253
|
-
background: var(--action-bg);
|
|
254
|
-
color: var(--action-ink);
|
|
255
|
-
box-shadow: var(--shadow-float);
|
|
247
|
+
padding: var(--callout-pad-y, var(--sp-3)) var(--callout-pad-x, var(--sp-4));
|
|
248
|
+
border: var(--border-w) solid var(--callout-border, var(--action-border));
|
|
249
|
+
border-radius: var(--callout-radius, var(--r-card));
|
|
250
|
+
background: var(--callout-bg, var(--action-bg));
|
|
251
|
+
color: var(--callout-ink, var(--action-ink));
|
|
252
|
+
box-shadow: var(--callout-shadow, var(--shadow-float));
|
|
256
253
|
text-align: center;
|
|
257
254
|
}
|
|
258
255
|
.callout::after {
|
|
@@ -269,15 +266,15 @@
|
|
|
269
266
|
border-top: 0;
|
|
270
267
|
border-left: 0;
|
|
271
268
|
}
|
|
272
|
-
.callout__title { font: var(--type-title); }
|
|
273
|
-
.callout__sub { font: var(--type-caption); opacity: 0.7; }
|
|
269
|
+
.callout__title { font: var(--callout-title-font, var(--type-title)); }
|
|
270
|
+
.callout__sub { font: var(--callout-sub-font, var(--type-caption)); opacity: 0.7; }
|
|
274
271
|
/* ---- deck: swipe cards; the last child is on top ----
|
|
275
272
|
<div class="deck"><article class="card">…</article><article class="card">…</article><article class="card card--fold">front</article></div>
|
|
276
273
|
<div class="deck__actions"><button class="icon-btn">×</button><button class="icon-btn icon-btn--invert">✓</button></div> */
|
|
277
|
-
.deck { display: grid; place-items: center; padding: var(--sp-4) var(--sp-4) var(--sp-6); }
|
|
274
|
+
.deck { display: grid; place-items: center; padding: var(--deck-pad-top, var(--sp-4)) var(--deck-pad-x, var(--sp-4)) var(--deck-pad-bottom, var(--sp-6)); }
|
|
278
275
|
.deck > .card { grid-area: 1 / 1; width: min(100%, 20rem); min-height: 12.5rem; transition: rotate 0.3s ease, translate 0.3s ease; }
|
|
279
276
|
.deck > .card:nth-last-child(2) { rotate: -4deg; translate: calc(-1 * var(--sp-2)) var(--sp-2); opacity: 0.85; }
|
|
280
277
|
.deck > .card:nth-last-child(3) { rotate: 5deg; translate: var(--sp-3) var(--sp-4); opacity: 0.6; }
|
|
281
278
|
.deck > .card:nth-last-child(n + 4) { display: none; }
|
|
282
|
-
.deck__actions { display: flex; justify-content: center; gap: var(--sp-8); }
|
|
279
|
+
.deck__actions { display: flex; justify-content: center; gap: var(--deck-actions-gap, var(--sp-8)); }
|
|
283
280
|
.deck__actions > .icon-btn { width: var(--bar-h); height: var(--bar-h); }
|
package/css/lists.css
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
.row {
|
|
12
12
|
display: flex;
|
|
13
13
|
align-items: center;
|
|
14
|
-
gap: var(--sp-3);
|
|
15
|
-
min-height: var(--tap); /* the tap target's room — the row's only vertical size */
|
|
14
|
+
gap: var(--row-gap, var(--sp-3));
|
|
15
|
+
min-height: var(--row-min-h, var(--tap)); /* the tap target's room — the row's only vertical size */
|
|
16
16
|
min-width: 0;
|
|
17
17
|
color: inherit;
|
|
18
18
|
text-decoration: none; /* .row works as <a> too — it is a tap target */
|
|
@@ -21,21 +21,30 @@
|
|
|
21
21
|
Space BETWEEN rows is .rows' gap; a lone row as card content takes the card's
|
|
22
22
|
gap. (.row--flush, which zeroed the old padding, is gone — every row is flush.) */
|
|
23
23
|
.row__lead {
|
|
24
|
-
width: var(--tap);
|
|
25
|
-
height: var(--tap);
|
|
24
|
+
width: var(--row-lead-size, var(--tap));
|
|
25
|
+
height: var(--row-lead-size, var(--tap));
|
|
26
26
|
flex: none;
|
|
27
|
-
border-radius: var(--r-control);
|
|
28
|
-
border: var(--border-w) solid var(--outline);
|
|
27
|
+
border-radius: var(--row-lead-radius, var(--r-control));
|
|
28
|
+
border: var(--border-w) solid var(--row-lead-border, var(--outline));
|
|
29
29
|
display: grid;
|
|
30
30
|
place-items: center;
|
|
31
31
|
}
|
|
32
|
-
.row__body { flex: 1; min-width: 0; display: grid; gap: var(--sp-0); }
|
|
33
|
-
.row__title { font: var(--type-title); overflow-wrap: anywhere; } /* wraps freely — no clip, so no padding trick for Thai marks (Lh 2026-09-16, same call as the card heading) */
|
|
34
|
-
.row__meta { font: var(--type-caption); color: var(--card-muted); display: flex; align-items: center; gap: var(--sp-1); }
|
|
32
|
+
.row__body { flex: 1; min-width: 0; display: grid; gap: var(--row-body-gap, var(--sp-0)); }
|
|
33
|
+
.row__title { font: var(--row-title-font, var(--type-title)); overflow-wrap: anywhere; } /* wraps freely — no clip, so no padding trick for Thai marks (Lh 2026-09-16, same call as the card heading) */
|
|
34
|
+
.row__meta { font: var(--row-meta-font, var(--type-caption)); color: var(--row-meta-ink, var(--card-muted)); display: flex; align-items: center; gap: var(--row-meta-gap, var(--sp-1)); }
|
|
35
35
|
.card--3 .row__meta { color: inherit; opacity: 0.7; }
|
|
36
|
-
.row__end { margin-left: auto; text-align: right; display: grid; gap: var(--sp-0); justify-items: end; flex: none; }
|
|
37
|
-
.row--lg { min-height: var(--fab); } /* menu rows: a taller target, round arrow at the end; .rows gives them more air */
|
|
36
|
+
.row__end { margin-left: auto; text-align: right; display: grid; gap: var(--row-end-gap, var(--sp-0)); justify-items: end; flex: none; }
|
|
37
|
+
.row--lg { min-height: var(--row-lg-min-h, var(--fab)); } /* menu rows: a taller target, round arrow at the end; .rows gives them more air */
|
|
38
38
|
.row--lg .row__title { font: 700 var(--fs-lg)/1.2 var(--font-display); }
|
|
39
|
+
/* a row that EXPANDS (Lh 2026-09-22): the row is a <details>' summary, what it shows comes out under it —
|
|
40
|
+
who liked a postcard, the rest of a list. An end chevron turns when open. The app owns the list.
|
|
41
|
+
<details class="row-expand"><summary class="row">…lead · body · end…</summary><div class="row-expand__more">…</div></details> */
|
|
42
|
+
.row-expand { display: block; }
|
|
43
|
+
.row-expand > summary { list-style: none; cursor: pointer; }
|
|
44
|
+
.row-expand > summary::-webkit-details-marker { display: none; }
|
|
45
|
+
.row-expand > summary > .icon:last-child { transition: rotate var(--motion-slide); }
|
|
46
|
+
.row-expand[open] > summary > .icon:last-child { rotate: 180deg; }
|
|
47
|
+
.row-expand__more { padding-top: var(--row-expand-gap, var(--sp-3)); }
|
|
39
48
|
/* a finished item in a checklist (a to-do list, an onboarding "complete your introduction" list):
|
|
40
49
|
the words go muted, a filled tick sits at the end, and the row is no longer a tap target —
|
|
41
50
|
pointer-events off here, aria-disabled from the markup. The tick is the .check's checked look
|
|
@@ -44,13 +53,13 @@
|
|
|
44
53
|
.row--done .row__title { color: var(--card-muted); }
|
|
45
54
|
.card--3 .row--done .row__title { color: inherit; opacity: 0.7; }
|
|
46
55
|
.row__done {
|
|
47
|
-
width: var(--tap-sm);
|
|
48
|
-
height: var(--tap-sm);
|
|
56
|
+
width: var(--row-done-size, var(--tap-sm));
|
|
57
|
+
height: var(--row-done-size, var(--tap-sm));
|
|
49
58
|
flex: none;
|
|
50
59
|
margin-left: auto;
|
|
51
60
|
border-radius: 50%;
|
|
52
|
-
background: var(--accent);
|
|
53
|
-
color: var(--on-accent);
|
|
61
|
+
background: var(--row-done-bg, var(--accent));
|
|
62
|
+
color: var(--row-done-ink, var(--on-accent));
|
|
54
63
|
display: grid;
|
|
55
64
|
place-items: center;
|
|
56
65
|
}
|
|
@@ -71,20 +80,20 @@
|
|
|
71
80
|
/* ---- kv: label left, value right ----
|
|
72
81
|
<dl class="kv"><div class="kv__row"><dt class="kv__key">Pay with</dt><dd class="kv__val">GHO</dd></div>…</dl> */
|
|
73
82
|
.kv { margin: 0; display: grid; }
|
|
74
|
-
.kv__row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); min-height: var(--tap); }
|
|
83
|
+
.kv__row { display: flex; align-items: center; justify-content: space-between; gap: var(--kv-row-gap, var(--sp-3)); min-height: var(--kv-row-min-h, var(--tap)); }
|
|
75
84
|
.kv--lined > .kv__row + .kv__row { border-top: var(--border-w) solid var(--hairline); }
|
|
76
|
-
.kv__key { font: var(--type-body); color: var(--card-muted); }
|
|
85
|
+
.kv__key { font: var(--kv-key-font, var(--type-body)); color: var(--kv-key-ink, var(--card-muted)); }
|
|
77
86
|
.card--3 .kv__key { color: inherit; opacity: 0.7; }
|
|
78
|
-
.kv__val { margin: 0; font: var(--type-title); display: inline-flex; align-items: center; gap: var(--sp-2); text-align: right; min-width: 0; }
|
|
87
|
+
.kv__val { margin: 0; font: var(--kv-val-font, var(--type-title)); display: inline-flex; align-items: center; gap: var(--kv-val-gap, var(--sp-2)); text-align: right; min-width: 0; }
|
|
79
88
|
|
|
80
89
|
/* ---- kv grid: value over label, cells split by a rule (Sex | Weight) ----
|
|
81
90
|
<div class="kv-grid"><div class="kv-cell"><svg class="icon"/><span class="kv-cell__val">15.6 kg</span><span class="kv-cell__key">Weight</span></div>…</div> */
|
|
82
|
-
.kv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(var(--tile-min), 100%), 1fr)); gap: var(--sp-4); }
|
|
91
|
+
.kv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(var(--tile-min), 100%), 1fr)); gap: var(--kv-grid-gap, var(--sp-4)); }
|
|
83
92
|
.kv-grid > .kv-cell + .kv-cell { border-left: var(--border-w) solid var(--hairline); padding-left: var(--sp-4); }
|
|
84
|
-
.kv-cell { display: grid; gap: var(--sp-0); align-content: start; min-width: 0; }
|
|
93
|
+
.kv-cell { display: grid; gap: var(--kv-cell-gap, var(--sp-0)); align-content: start; min-width: 0; }
|
|
85
94
|
.kv-cell > .icon { margin-bottom: var(--sp-1); }
|
|
86
|
-
.kv-cell__val { font: var(--type-h2); letter-spacing: var(--track-h2); font-variant-numeric: tabular-nums; }
|
|
87
|
-
.kv-cell__key { font: var(--type-caption); color: var(--card-muted); }
|
|
95
|
+
.kv-cell__val { font: var(--kv-cell-val-font, var(--type-h2)); letter-spacing: var(--track-h2); font-variant-numeric: tabular-nums; }
|
|
96
|
+
.kv-cell__key { font: var(--kv-cell-key-font, var(--type-caption)); color: var(--kv-cell-key-ink, var(--card-muted)); }
|
|
88
97
|
.card--3 .kv-cell__key { color: inherit; opacity: 0.7; }
|
|
89
98
|
|
|
90
99
|
/* ---- bubble: a chat message — theirs on the left, mine on the right (Lh 2026-09-18, replaces the chip's tail) ----
|
|
@@ -96,7 +105,7 @@
|
|
|
96
105
|
<div class="bubble"><p class="bubble__body">…</p><span class="bubble__actions">…icon-btns…</span><span class="bubble__meta">Dec 4 · 8:15</span></div>
|
|
97
106
|
<div class="bubble bubble--right">…</div>
|
|
98
107
|
</div> */
|
|
99
|
-
.thread { display: grid; gap: var(--sp-4); }
|
|
108
|
+
.thread { display: grid; gap: var(--thread-gap, var(--sp-4)); }
|
|
100
109
|
/* two columns: the message (max-content, but it gives way — minmax(0) — so a long one shrinks
|
|
101
110
|
and wraps while the actions stay beside it) and the actions; the meta on a second row under the message */
|
|
102
111
|
.bubble {
|
|
@@ -116,12 +125,12 @@
|
|
|
116
125
|
.bubble__body {
|
|
117
126
|
margin: 0;
|
|
118
127
|
min-width: 0;
|
|
119
|
-
padding: var(--sp-3) var(--sp-4);
|
|
120
|
-
border-radius: var(--r-card);
|
|
128
|
+
padding: var(--bubble-body-pad-y, var(--sp-3)) var(--bubble-body-pad-x, var(--sp-4));
|
|
129
|
+
border-radius: var(--bubble-body-radius, var(--r-card));
|
|
121
130
|
border-bottom-left-radius: var(--r-control);
|
|
122
|
-
background: var(--card-2-bg);
|
|
123
|
-
color: var(--card-2-ink);
|
|
124
|
-
font: var(--type-body);
|
|
131
|
+
background: var(--bubble-body-bg, var(--card-2-bg));
|
|
132
|
+
color: var(--bubble-body-ink, var(--card-2-ink));
|
|
133
|
+
font: var(--bubble-body-font, var(--type-body));
|
|
125
134
|
overflow-wrap: anywhere;
|
|
126
135
|
}
|
|
127
136
|
.bubble--right > .bubble__body {
|
|
@@ -131,8 +140,8 @@
|
|
|
131
140
|
color: var(--on-accent);
|
|
132
141
|
text-align: right;
|
|
133
142
|
}
|
|
134
|
-
.bubble__actions { display: flex; gap: var(--sp-1); flex: none; opacity: 0.7; }
|
|
135
|
-
.bubble__meta { display: flex; align-items: center; gap: var(--sp-1); font: var(--type-caption); color: var(--on-surface-muted); }
|
|
143
|
+
.bubble__actions { display: flex; gap: var(--bubble-actions-gap, var(--sp-1)); flex: none; opacity: 0.7; }
|
|
144
|
+
.bubble__meta { display: flex; align-items: center; gap: var(--bubble-meta-gap, var(--sp-1)); font: var(--bubble-meta-font, var(--type-caption)); color: var(--bubble-meta-ink, var(--on-surface-muted)); }
|
|
136
145
|
.bubble--right > .bubble__meta { justify-self: end; }
|
|
137
146
|
.bubble__meta > .icon { color: var(--accent); }
|
|
138
147
|
.card--3 .bubble__meta { color: inherit; opacity: 0.7; }
|
|
@@ -144,7 +153,7 @@
|
|
|
144
153
|
margin: 0;
|
|
145
154
|
padding: 0 0 0 var(--sp-6);
|
|
146
155
|
display: grid;
|
|
147
|
-
gap: var(--sp-5);
|
|
156
|
+
gap: var(--timeline-gap, var(--sp-5));
|
|
148
157
|
position: relative;
|
|
149
158
|
}
|
|
150
159
|
.timeline::before {
|
|
@@ -155,7 +164,7 @@
|
|
|
155
164
|
bottom: var(--sp-3);
|
|
156
165
|
border-left: var(--border-w) solid var(--hairline);
|
|
157
166
|
}
|
|
158
|
-
.timeline__item { display: grid; gap: var(--sp-2); position: relative; min-width: 0; }
|
|
167
|
+
.timeline__item { display: grid; gap: var(--timeline-item-gap, var(--sp-2)); position: relative; min-width: 0; }
|
|
159
168
|
.timeline__item::before {
|
|
160
169
|
content: "";
|
|
161
170
|
position: absolute;
|
|
@@ -168,35 +177,35 @@
|
|
|
168
177
|
}
|
|
169
178
|
.timeline__mark {
|
|
170
179
|
justify-self: start;
|
|
171
|
-
font: var(--type-overline);
|
|
180
|
+
font: var(--timeline-mark-font, var(--type-overline));
|
|
172
181
|
letter-spacing: var(--track-overline);
|
|
173
182
|
text-transform: uppercase;
|
|
174
|
-
padding: var(--sp-1) var(--sp-2);
|
|
175
|
-
border-radius: var(--r-chip);
|
|
176
|
-
background: var(--ink-tint);
|
|
183
|
+
padding: var(--timeline-mark-pad-y, var(--sp-1)) var(--timeline-mark-pad-x, var(--sp-2));
|
|
184
|
+
border-radius: var(--timeline-mark-radius, var(--r-chip));
|
|
185
|
+
background: var(--timeline-mark-bg, var(--ink-tint));
|
|
177
186
|
}
|
|
178
187
|
|
|
179
188
|
/* ---- legend: signal dots with captions ----
|
|
180
189
|
<div class="legend"><span class="legend__item"><span class="dot"></span> very high</span>…</div> */
|
|
181
|
-
.legend { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); font: var(--type-caption); color: var(--card-muted); }
|
|
190
|
+
.legend { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); font: var(--legend-font, var(--type-caption)); color: var(--legend-ink, var(--card-muted)); }
|
|
182
191
|
.card--3 .legend { color: inherit; opacity: 0.8; }
|
|
183
|
-
.legend__item { display: inline-flex; align-items: center; gap: var(--sp-2); min-height: var(--icon); }
|
|
192
|
+
.legend__item { display: inline-flex; align-items: center; gap: var(--legend-item-gap, var(--sp-2)); min-height: var(--legend-item-min-h, var(--icon)); }
|
|
184
193
|
|
|
185
194
|
/* ---- link: "See all ↗" in a card head, big enough to tap ----
|
|
186
195
|
<a class="link" href="#">See all <svg class="icon icon--xs"/></a> */
|
|
187
196
|
.link {
|
|
188
197
|
display: inline-flex;
|
|
189
198
|
align-items: center;
|
|
190
|
-
gap: var(--sp-1);
|
|
191
|
-
min-height: var(--tap-sm);
|
|
199
|
+
gap: var(--link-gap, var(--sp-1));
|
|
200
|
+
min-height: var(--link-min-h, var(--tap-sm));
|
|
192
201
|
color: inherit;
|
|
193
202
|
text-decoration: none;
|
|
194
|
-
font: var(--type-label);
|
|
195
|
-
font-size: var(--fs-body);
|
|
203
|
+
font: var(--link-font, var(--type-label));
|
|
204
|
+
font-size: var(--link-font-size, var(--fs-body));
|
|
196
205
|
border: 0;
|
|
197
206
|
background: transparent;
|
|
198
207
|
padding: 0;
|
|
199
208
|
cursor: pointer;
|
|
200
209
|
}
|
|
201
|
-
.link--muted { color: var(--card-muted); }
|
|
210
|
+
.link--muted { color: var(--link-muted-ink, var(--card-muted)); }
|
|
202
211
|
.card--3 .link--muted { color: inherit; opacity: 0.7; }
|