@usableapp/cardds 0.7.44 → 0.7.45
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 +9 -0
- package/cardds.css +1 -0
- package/css/finish.css +77 -0
- package/css/numbers.css +11 -7
- package/css/step.css +9 -0
- package/css/tokens.css +1 -1
- package/dist/cardds.css +100 -8
- package/dist/templates/CallSheet.d.ts +6 -3
- package/dist/templates/CallSheet.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
> For: a project that consumes `@usableapp/cardds` and its AI — what changed between versions, written as before → after, so a screen can be brought up to date without reading the source. Newest first. A consumer never edits cardds; if something here leaves you without a way to do what you did before, report the gap.
|
|
4
4
|
|
|
5
|
+
## 0.7.45 — 2026-10-03
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- **`Track` is as tall as the top bar, and a step is a mark, not a control** (Lh 2026-10-03): the pill is `--header-h` tall (60px, was 72) and each step's round is 32px (was 56 — the size of a control, it read as something to press), its glyph 18px, the connector 8px, a `num` at caption size. Nothing to change in a screen: same markup, same props. If your theme sets `--track-pad` or `--track-dot-font`, your value still wins — only the defaults moved (`--track-pad` 8px → 14px, `--track-dot-font` title → caption).
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **A `Track` as the screen's top** (Lh 2026-10-03): `<Screen fill top={<Track>…</Track>}>` — the progress of a task in several sheets stands where a bar would, in the screen's inset, and stays in sight over every sheet. A sheet at full stops 16px under it and never touches it — the same 16px it keeps from the screen's sides and from the status bar. Knobs `--track-top-gap` (16px, the room under it) · `--track-top-lead` (16px, the air over it, under the status bar). Stories `Track · OnTop` (numbers) · `OnTopIcons`.
|
|
12
|
+
- **`CallSheet top`**: the template takes the Screen's `top` (before, it had none and could not be given one) — `<CallSheet top={<Track>…</Track>} …>`. Without it nothing changes: no top, the page starts at the lead.
|
|
13
|
+
|
|
5
14
|
## 0.7.44 — 2026-10-02
|
|
6
15
|
|
|
7
16
|
### Added
|
package/cardds.css
CHANGED
|
@@ -16,3 +16,4 @@
|
|
|
16
16
|
@import url("css/lists.css"); /* row, rows, key-value, kv grid, timeline, legend, link */
|
|
17
17
|
@import url("css/media.css"); /* cover card, quote, tile grid, fold, mosaic, wave */
|
|
18
18
|
@import url("css/layover.css"); /* ask drawer, popover menu, banner, float bar, callout */
|
|
19
|
+
@import url("css/finish.css"); /* light, shadow, edges — only under data-finish="lit" */
|
package/css/finish.css
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
cardds/finish.css — FINISH: light, shadow and edges. A style of its own (Lh 2026-10-02: the plain
|
|
3
|
+
look read flat, "not finished"), apart from colour: palette.css says WHICH colours, this says how
|
|
4
|
+
the material is lit. Apply with <html data-finish="lit"> beside any palette (or none, or "own").
|
|
5
|
+
No attribute = nothing here applies — the flat look, unchanged.
|
|
6
|
+
|
|
7
|
+
The light comes from above:
|
|
8
|
+
- a thing that stands UP (card, sheet, button) has a lit top edge, a hairline ring and a shadow
|
|
9
|
+
that grows with its height: card 1 · sheet / float 2 — the layers cardds already has;
|
|
10
|
+
- a thing that is SUNK (a field, a pin cell) has its shadow inside, under its top edge;
|
|
11
|
+
- information inside a card stays flat: only a container or a control gets an edge.
|
|
12
|
+
Shadows are mixed from the ink (--on-surface), never plain black, so they sit in the palette.
|
|
13
|
+
============================================================ */
|
|
14
|
+
|
|
15
|
+
[data-finish="lit"] {
|
|
16
|
+
--_shade: var(--on-surface);
|
|
17
|
+
--finish-edge: inset 0 1px 0 rgb(255 255 255 / 0.55); /* the lit top edge */
|
|
18
|
+
--finish-ring: 0 0 0 1px color-mix(in srgb, var(--_shade) 7%, transparent); /* the hairline round a raised thing */
|
|
19
|
+
|
|
20
|
+
/* the three shadows every component already reads — layered: one close and crisp, one far and soft */
|
|
21
|
+
--shadow-card: var(--finish-edge), var(--finish-ring),
|
|
22
|
+
0 1px 2px color-mix(in srgb, var(--_shade) 8%, transparent),
|
|
23
|
+
0 0.375rem 0.75rem -0.125rem color-mix(in srgb, var(--_shade) 8%, transparent),
|
|
24
|
+
0 1.25rem 2.5rem -0.75rem color-mix(in srgb, var(--_shade) 14%, transparent);
|
|
25
|
+
--shadow-float: var(--finish-edge), var(--finish-ring),
|
|
26
|
+
0 1px 2px color-mix(in srgb, var(--_shade) 12%, transparent),
|
|
27
|
+
0 0.5rem 1.25rem -0.25rem color-mix(in srgb, var(--_shade) 22%, transparent);
|
|
28
|
+
--shadow-sheet: var(--finish-edge), var(--finish-ring),
|
|
29
|
+
0 -1px 2px color-mix(in srgb, var(--_shade) 6%, transparent),
|
|
30
|
+
0 -0.75rem 2.5rem color-mix(in srgb, var(--_shade) 18%, transparent);
|
|
31
|
+
|
|
32
|
+
/* a control: its own small lift, and the sheen that runs down its face */
|
|
33
|
+
--finish-control: var(--finish-edge), var(--finish-ring),
|
|
34
|
+
0 1px 2px color-mix(in srgb, var(--_shade) 12%, transparent),
|
|
35
|
+
0 0.25rem 0.5rem -0.125rem color-mix(in srgb, var(--_shade) 12%, transparent);
|
|
36
|
+
--finish-control-down: var(--finish-ring), inset 0 1px 2px color-mix(in srgb, var(--_shade) 18%, transparent);
|
|
37
|
+
--finish-sheen: linear-gradient(to bottom, rgb(255 255 255 / 0.16), rgb(255 255 255 / 0) 60%);
|
|
38
|
+
--finish-sunk: inset 0 1px 2px color-mix(in srgb, var(--_shade) 14%, transparent), 0 1px 0 rgb(255 255 255 / 0.5);
|
|
39
|
+
|
|
40
|
+
/* the shadow is the edge: the wireframe's lines step back (as in every colour palette) */
|
|
41
|
+
--card-border: transparent;
|
|
42
|
+
--action-border: transparent;
|
|
43
|
+
--outline: color-mix(in srgb, currentColor 14%, transparent);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* ---- raised: cards, sheets, the stack ---- */
|
|
47
|
+
[data-finish="lit"] :is(.card, .band-stack) { box-shadow: var(--shadow-card); }
|
|
48
|
+
[data-finish="lit"] .band-stack > .card--band { box-shadow: none; }
|
|
49
|
+
/* a sheet lies on the floor and is lit from above: its shadow falls UP the screen, onto what it covers */
|
|
50
|
+
[data-finish="lit"] .sheet { box-shadow: var(--sheet-shadow, var(--shadow-sheet)); }
|
|
51
|
+
[data-finish="lit"] .modal { box-shadow: var(--modal-shadow, var(--shadow-float)); }
|
|
52
|
+
[data-finish="lit"] .sheet-stack > .card,
|
|
53
|
+
[data-finish="lit"] .sheet-stack > :not(.card, .sheet-stack__base) > .card { box-shadow: var(--shadow-sheet); }
|
|
54
|
+
|
|
55
|
+
/* ---- controls: a filled button stands up, and goes down under the finger ---- */
|
|
56
|
+
[data-finish="lit"] .btn:not(.btn--quiet),
|
|
57
|
+
[data-finish="lit"] .icon-btn:not(.icon-btn-group > *, .stack-sheet__tab:not(.icon-btn--invert)) {
|
|
58
|
+
background-image: var(--finish-sheen);
|
|
59
|
+
box-shadow: var(--finish-control);
|
|
60
|
+
}
|
|
61
|
+
/* the main button throws its own colour */
|
|
62
|
+
[data-finish="lit"] .btn--primary,
|
|
63
|
+
[data-finish="lit"] .icon-btn--invert:not(.icon-btn-group > *) {
|
|
64
|
+
box-shadow: var(--finish-edge),
|
|
65
|
+
0 1px 2px color-mix(in srgb, var(--_shade) 20%, transparent),
|
|
66
|
+
0 0.5rem 1rem -0.25rem color-mix(in srgb, var(--accent) 45%, transparent);
|
|
67
|
+
}
|
|
68
|
+
[data-finish="lit"] :is(.btn:not(.btn--quiet), .icon-btn:not(.icon-btn-group > *, .stack-sheet__tab:not(.icon-btn--invert))):active:not(:disabled) {
|
|
69
|
+
background-image: none;
|
|
70
|
+
box-shadow: var(--finish-control-down);
|
|
71
|
+
}
|
|
72
|
+
[data-finish="lit"] .icon-btn-group { box-shadow: var(--finish-control); }
|
|
73
|
+
[data-finish="lit"] .toggle { box-shadow: var(--finish-sunk); }
|
|
74
|
+
[data-finish="lit"] .toggle::after { box-shadow: 0 1px 2px color-mix(in srgb, var(--_shade) 35%, transparent); }
|
|
75
|
+
|
|
76
|
+
/* ---- sunk: what the member types into ---- */
|
|
77
|
+
[data-finish="lit"] :is(.field, .pin__cell) { box-shadow: var(--finish-sunk); }
|
package/css/numbers.css
CHANGED
|
@@ -39,8 +39,12 @@
|
|
|
39
39
|
.ring--xs .ring__value { font: var(--type-caption); }
|
|
40
40
|
|
|
41
41
|
/* ---- track: step progress in a pill — done · done · todo ----
|
|
42
|
-
<ol class="track"><li class="track__step is-done">icon</li> …</ol>
|
|
42
|
+
<ol class="track"><li class="track__step is-done">icon</li> …</ol>
|
|
43
|
+
As tall as the top bar (--header-h), and a step is a MARK, not a control: its round is well under
|
|
44
|
+
the tap floor, so it reads as progress and never as something to press (Lh 2026-10-03). */
|
|
43
45
|
.track {
|
|
46
|
+
--_step: calc(var(--tap-base) * 2 / 3); /* 32 the round of one step */
|
|
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 */
|
|
44
48
|
--_bg: var(--card-3-bg);
|
|
45
49
|
--_ink: var(--card-3-ink);
|
|
46
50
|
/* the track lays down its own dark ground, so like the dark card slot it
|
|
@@ -51,7 +55,7 @@
|
|
|
51
55
|
--on-accent: var(--_bg);
|
|
52
56
|
list-style: none;
|
|
53
57
|
margin: 0;
|
|
54
|
-
padding: var(--track-pad, var(--
|
|
58
|
+
padding: var(--track-pad, var(--_pad));
|
|
55
59
|
display: flex;
|
|
56
60
|
align-items: center;
|
|
57
61
|
border-radius: var(--track-radius, var(--r-chip));
|
|
@@ -70,22 +74,22 @@
|
|
|
70
74
|
.track__step::before {
|
|
71
75
|
content: "";
|
|
72
76
|
flex: 1;
|
|
73
|
-
height: var(--sp-
|
|
77
|
+
height: var(--sp-2);
|
|
74
78
|
background: var(--ink-rail); /* the track's own ink at 30% — identical to color-mix(in srgb, var(--_ink) 30%, transparent): --ink-rail already reads currentColor, and .track sets color to --_ink */
|
|
75
79
|
}
|
|
76
80
|
.track__step:first-child::before { display: none; }
|
|
77
81
|
.track__step.is-done::before { background: var(--accent); }
|
|
78
82
|
.track__step > .icon,
|
|
79
83
|
.track__step > .track__dot {
|
|
80
|
-
width: var(--
|
|
81
|
-
height: var(--
|
|
84
|
+
width: var(--_step);
|
|
85
|
+
height: var(--_step);
|
|
82
86
|
flex: none;
|
|
83
|
-
padding: calc(
|
|
87
|
+
padding: calc(var(--_step) * 7 / 32); /* the glyph = 18 in the 32 round */
|
|
84
88
|
border-radius: 50%;
|
|
85
89
|
background: var(--ink-rail);
|
|
86
90
|
color: var(--_ink);
|
|
87
91
|
}
|
|
88
|
-
.track__step > .track__dot { display: grid; place-items: center; padding: 0; font: var(--track-dot-font, var(--type-
|
|
92
|
+
.track__step > .track__dot { display: grid; place-items: center; padding: 0; font: var(--track-dot-font, var(--type-caption)); font-variant-numeric: tabular-nums; } /* a number in the round (TrackStep num) */
|
|
89
93
|
.track__step.is-done > .icon,
|
|
90
94
|
.track__step.is-done > .track__dot { background: var(--accent); color: var(--on-accent); }
|
|
91
95
|
|
package/css/step.css
CHANGED
|
@@ -141,6 +141,15 @@
|
|
|
141
141
|
them — timebank #137); the words keep the screen's gap as their lead (--_lead, .appbar + .step above) */
|
|
142
142
|
.screen--fill > .appbar:has(+ .step) { margin-bottom: calc(-1 * var(--screen-gap)); }
|
|
143
143
|
.screen--fill > .appbar + .sheet-stage { margin-top: 0; }
|
|
144
|
+
/* a TRACK as the screen's TOP (Lh 2026-10-03): the walk's progress stands where a bar would, a row of the column, in the screen's
|
|
145
|
+
inset — and it never touches what comes up under it: the step (and so a sheet at full) starts --track-top-gap below it. That
|
|
146
|
+
room is the track's own, not the screen's gap; --track-top-lead is the air over it, under the status bar. Both = the screen's side inset (16): the pill
|
|
147
|
+
stands the same distance from everything around it (Lh 2026-10-03: 8 over was too little, 24 under too much). */
|
|
148
|
+
.screen--fill > .track:first-child {
|
|
149
|
+
flex: none;
|
|
150
|
+
margin-top: var(--track-top-lead, var(--sp-4));
|
|
151
|
+
margin-bottom: calc(var(--track-top-gap, var(--sp-4)) - var(--screen-gap));
|
|
152
|
+
}
|
|
144
153
|
/* a walk page that OPENS on a picture (Lh 2026-09-23): the picture takes the lead's room — as wide as the content (edge to edge), from the top edge, as tall as
|
|
145
154
|
the lead + the picture's own height (--page-media-h), square — so the words start where they always did */
|
|
146
155
|
.step > .pages > .page:has(> :is(img, .ph):first-child) { margin-top: 0; }
|
package/css/tokens.css
CHANGED
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
--tap-floor: 2.75rem; /* 44 the HIG floor — no --tap-base takes a touch target under it */
|
|
47
47
|
--tap: max(var(--tap-floor), var(--tap-base)); /* 48 primary touch target */
|
|
48
48
|
--tap-sm: max(var(--tap-floor), calc(var(--tap-base) * 11 / 12)); /* 44 minimum touch target */
|
|
49
|
-
--tap-lg: max(var(--tap-floor), calc(var(--tap-base) * 7 / 6)); /* 56 hero controls:
|
|
49
|
+
--tap-lg: max(var(--tap-floor), calc(var(--tap-base) * 7 / 6)); /* 56 hero controls: send, field with action */
|
|
50
50
|
--btn-h: calc(var(--tap-base) * 13 / 12); /* 52 button height */
|
|
51
51
|
--btn-xl-h: calc(var(--tap-base) * 11 / 6); /* 88 the one giant CTA */
|
|
52
52
|
--chip-h: calc(var(--tap-base) * 19 / 24); /* 38 chip height */
|
package/dist/cardds.css
CHANGED
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
--tap-floor: 2.75rem; /* 44 the HIG floor — no --tap-base takes a touch target under it */
|
|
88
88
|
--tap: max(var(--tap-floor), var(--tap-base)); /* 48 primary touch target */
|
|
89
89
|
--tap-sm: max(var(--tap-floor), calc(var(--tap-base) * 11 / 12)); /* 44 minimum touch target */
|
|
90
|
-
--tap-lg: max(var(--tap-floor), calc(var(--tap-base) * 7 / 6)); /* 56 hero controls:
|
|
90
|
+
--tap-lg: max(var(--tap-floor), calc(var(--tap-base) * 7 / 6)); /* 56 hero controls: send, field with action */
|
|
91
91
|
--btn-h: calc(var(--tap-base) * 13 / 12); /* 52 button height */
|
|
92
92
|
--btn-xl-h: calc(var(--tap-base) * 11 / 6); /* 88 the one giant CTA */
|
|
93
93
|
--chip-h: calc(var(--tap-base) * 19 / 24); /* 38 chip height */
|
|
@@ -1899,6 +1899,15 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
|
|
|
1899
1899
|
them — timebank #137); the words keep the screen's gap as their lead (--_lead, .appbar + .step above) */
|
|
1900
1900
|
.screen--fill > .appbar:has(+ .step) { margin-bottom: calc(-1 * var(--screen-gap)); }
|
|
1901
1901
|
.screen--fill > .appbar + .sheet-stage { margin-top: 0; }
|
|
1902
|
+
/* a TRACK as the screen's TOP (Lh 2026-10-03): the walk's progress stands where a bar would, a row of the column, in the screen's
|
|
1903
|
+
inset — and it never touches what comes up under it: the step (and so a sheet at full) starts --track-top-gap below it. That
|
|
1904
|
+
room is the track's own, not the screen's gap; --track-top-lead is the air over it, under the status bar. Both = the screen's side inset (16): the pill
|
|
1905
|
+
stands the same distance from everything around it (Lh 2026-10-03: 8 over was too little, 24 under too much). */
|
|
1906
|
+
.screen--fill > .track:first-child {
|
|
1907
|
+
flex: none;
|
|
1908
|
+
margin-top: var(--track-top-lead, var(--sp-4));
|
|
1909
|
+
margin-bottom: calc(var(--track-top-gap, var(--sp-4)) - var(--screen-gap));
|
|
1910
|
+
}
|
|
1902
1911
|
/* a walk page that OPENS on a picture (Lh 2026-09-23): the picture takes the lead's room — as wide as the content (edge to edge), from the top edge, as tall as
|
|
1903
1912
|
the lead + the picture's own height (--page-media-h), square — so the words start where they always did */
|
|
1904
1913
|
.step > .pages > .page:has(> :is(img, .ph):first-child) { margin-top: 0; }
|
|
@@ -2516,8 +2525,12 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
|
|
|
2516
2525
|
.ring--xs .ring__value { font: var(--type-caption); }
|
|
2517
2526
|
|
|
2518
2527
|
/* ---- track: step progress in a pill — done · done · todo ----
|
|
2519
|
-
<ol class="track"><li class="track__step is-done">icon</li> …</ol>
|
|
2528
|
+
<ol class="track"><li class="track__step is-done">icon</li> …</ol>
|
|
2529
|
+
As tall as the top bar (--header-h), and a step is a MARK, not a control: its round is well under
|
|
2530
|
+
the tap floor, so it reads as progress and never as something to press (Lh 2026-10-03). */
|
|
2520
2531
|
.track {
|
|
2532
|
+
--_step: calc(var(--tap-base) * 2 / 3); /* 32 the round of one step */
|
|
2533
|
+
--_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 */
|
|
2521
2534
|
--_bg: var(--card-3-bg);
|
|
2522
2535
|
--_ink: var(--card-3-ink);
|
|
2523
2536
|
/* the track lays down its own dark ground, so like the dark card slot it
|
|
@@ -2528,7 +2541,7 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
|
|
|
2528
2541
|
--on-accent: var(--_bg);
|
|
2529
2542
|
list-style: none;
|
|
2530
2543
|
margin: 0;
|
|
2531
|
-
padding: var(--track-pad, var(--
|
|
2544
|
+
padding: var(--track-pad, var(--_pad));
|
|
2532
2545
|
display: flex;
|
|
2533
2546
|
align-items: center;
|
|
2534
2547
|
border-radius: var(--track-radius, var(--r-chip));
|
|
@@ -2547,22 +2560,22 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
|
|
|
2547
2560
|
.track__step::before {
|
|
2548
2561
|
content: "";
|
|
2549
2562
|
flex: 1;
|
|
2550
|
-
height: var(--sp-
|
|
2563
|
+
height: var(--sp-2);
|
|
2551
2564
|
background: var(--ink-rail); /* the track's own ink at 30% — identical to color-mix(in srgb, var(--_ink) 30%, transparent): --ink-rail already reads currentColor, and .track sets color to --_ink */
|
|
2552
2565
|
}
|
|
2553
2566
|
.track__step:first-child::before { display: none; }
|
|
2554
2567
|
.track__step.is-done::before { background: var(--accent); }
|
|
2555
2568
|
.track__step > .icon,
|
|
2556
2569
|
.track__step > .track__dot {
|
|
2557
|
-
width: var(--
|
|
2558
|
-
height: var(--
|
|
2570
|
+
width: var(--_step);
|
|
2571
|
+
height: var(--_step);
|
|
2559
2572
|
flex: none;
|
|
2560
|
-
padding: calc(
|
|
2573
|
+
padding: calc(var(--_step) * 7 / 32); /* the glyph = 18 in the 32 round */
|
|
2561
2574
|
border-radius: 50%;
|
|
2562
2575
|
background: var(--ink-rail);
|
|
2563
2576
|
color: var(--_ink);
|
|
2564
2577
|
}
|
|
2565
|
-
.track__step > .track__dot { display: grid; place-items: center; padding: 0; font: var(--track-dot-font, var(--type-
|
|
2578
|
+
.track__step > .track__dot { display: grid; place-items: center; padding: 0; font: var(--track-dot-font, var(--type-caption)); font-variant-numeric: tabular-nums; } /* a number in the round (TrackStep num) */
|
|
2566
2579
|
.track__step.is-done > .icon,
|
|
2567
2580
|
.track__step.is-done > .track__dot { background: var(--accent); color: var(--on-accent); }
|
|
2568
2581
|
|
|
@@ -3987,3 +4000,82 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
|
|
|
3987
4000
|
.snackbar__caption { font: var(--snackbar-caption-font, var(--type-caption)); opacity: var(--dim); }
|
|
3988
4001
|
@media (prefers-reduced-motion: reduce) { .snackbar { transition: none; } }
|
|
3989
4002
|
|
|
4003
|
+
/* ---- css/finish.css — light, shadow, edges — only under data-finish="lit" ---- */
|
|
4004
|
+
/* ============================================================
|
|
4005
|
+
cardds/finish.css — FINISH: light, shadow and edges. A style of its own (Lh 2026-10-02: the plain
|
|
4006
|
+
look read flat, "not finished"), apart from colour: palette.css says WHICH colours, this says how
|
|
4007
|
+
the material is lit. Apply with <html data-finish="lit"> beside any palette (or none, or "own").
|
|
4008
|
+
No attribute = nothing here applies — the flat look, unchanged.
|
|
4009
|
+
|
|
4010
|
+
The light comes from above:
|
|
4011
|
+
- a thing that stands UP (card, sheet, button) has a lit top edge, a hairline ring and a shadow
|
|
4012
|
+
that grows with its height: card 1 · sheet / float 2 — the layers cardds already has;
|
|
4013
|
+
- a thing that is SUNK (a field, a pin cell) has its shadow inside, under its top edge;
|
|
4014
|
+
- information inside a card stays flat: only a container or a control gets an edge.
|
|
4015
|
+
Shadows are mixed from the ink (--on-surface), never plain black, so they sit in the palette.
|
|
4016
|
+
============================================================ */
|
|
4017
|
+
|
|
4018
|
+
[data-finish="lit"] {
|
|
4019
|
+
--_shade: var(--on-surface);
|
|
4020
|
+
--finish-edge: inset 0 1px 0 rgb(255 255 255 / 0.55); /* the lit top edge */
|
|
4021
|
+
--finish-ring: 0 0 0 1px color-mix(in srgb, var(--_shade) 7%, transparent); /* the hairline round a raised thing */
|
|
4022
|
+
|
|
4023
|
+
/* the three shadows every component already reads — layered: one close and crisp, one far and soft */
|
|
4024
|
+
--shadow-card: var(--finish-edge), var(--finish-ring),
|
|
4025
|
+
0 1px 2px color-mix(in srgb, var(--_shade) 8%, transparent),
|
|
4026
|
+
0 0.375rem 0.75rem -0.125rem color-mix(in srgb, var(--_shade) 8%, transparent),
|
|
4027
|
+
0 1.25rem 2.5rem -0.75rem color-mix(in srgb, var(--_shade) 14%, transparent);
|
|
4028
|
+
--shadow-float: var(--finish-edge), var(--finish-ring),
|
|
4029
|
+
0 1px 2px color-mix(in srgb, var(--_shade) 12%, transparent),
|
|
4030
|
+
0 0.5rem 1.25rem -0.25rem color-mix(in srgb, var(--_shade) 22%, transparent);
|
|
4031
|
+
--shadow-sheet: var(--finish-edge), var(--finish-ring),
|
|
4032
|
+
0 -1px 2px color-mix(in srgb, var(--_shade) 6%, transparent),
|
|
4033
|
+
0 -0.75rem 2.5rem color-mix(in srgb, var(--_shade) 18%, transparent);
|
|
4034
|
+
|
|
4035
|
+
/* a control: its own small lift, and the sheen that runs down its face */
|
|
4036
|
+
--finish-control: var(--finish-edge), var(--finish-ring),
|
|
4037
|
+
0 1px 2px color-mix(in srgb, var(--_shade) 12%, transparent),
|
|
4038
|
+
0 0.25rem 0.5rem -0.125rem color-mix(in srgb, var(--_shade) 12%, transparent);
|
|
4039
|
+
--finish-control-down: var(--finish-ring), inset 0 1px 2px color-mix(in srgb, var(--_shade) 18%, transparent);
|
|
4040
|
+
--finish-sheen: linear-gradient(to bottom, rgb(255 255 255 / 0.16), rgb(255 255 255 / 0) 60%);
|
|
4041
|
+
--finish-sunk: inset 0 1px 2px color-mix(in srgb, var(--_shade) 14%, transparent), 0 1px 0 rgb(255 255 255 / 0.5);
|
|
4042
|
+
|
|
4043
|
+
/* the shadow is the edge: the wireframe's lines step back (as in every colour palette) */
|
|
4044
|
+
--card-border: transparent;
|
|
4045
|
+
--action-border: transparent;
|
|
4046
|
+
--outline: color-mix(in srgb, currentColor 14%, transparent);
|
|
4047
|
+
}
|
|
4048
|
+
|
|
4049
|
+
/* ---- raised: cards, sheets, the stack ---- */
|
|
4050
|
+
[data-finish="lit"] :is(.card, .band-stack) { box-shadow: var(--shadow-card); }
|
|
4051
|
+
[data-finish="lit"] .band-stack > .card--band { box-shadow: none; }
|
|
4052
|
+
/* a sheet lies on the floor and is lit from above: its shadow falls UP the screen, onto what it covers */
|
|
4053
|
+
[data-finish="lit"] .sheet { box-shadow: var(--sheet-shadow, var(--shadow-sheet)); }
|
|
4054
|
+
[data-finish="lit"] .modal { box-shadow: var(--modal-shadow, var(--shadow-float)); }
|
|
4055
|
+
[data-finish="lit"] .sheet-stack > .card,
|
|
4056
|
+
[data-finish="lit"] .sheet-stack > :not(.card, .sheet-stack__base) > .card { box-shadow: var(--shadow-sheet); }
|
|
4057
|
+
|
|
4058
|
+
/* ---- controls: a filled button stands up, and goes down under the finger ---- */
|
|
4059
|
+
[data-finish="lit"] .btn:not(.btn--quiet),
|
|
4060
|
+
[data-finish="lit"] .icon-btn:not(.icon-btn-group > *, .stack-sheet__tab:not(.icon-btn--invert)) {
|
|
4061
|
+
background-image: var(--finish-sheen);
|
|
4062
|
+
box-shadow: var(--finish-control);
|
|
4063
|
+
}
|
|
4064
|
+
/* the main button throws its own colour */
|
|
4065
|
+
[data-finish="lit"] .btn--primary,
|
|
4066
|
+
[data-finish="lit"] .icon-btn--invert:not(.icon-btn-group > *) {
|
|
4067
|
+
box-shadow: var(--finish-edge),
|
|
4068
|
+
0 1px 2px color-mix(in srgb, var(--_shade) 20%, transparent),
|
|
4069
|
+
0 0.5rem 1rem -0.25rem color-mix(in srgb, var(--accent) 45%, transparent);
|
|
4070
|
+
}
|
|
4071
|
+
[data-finish="lit"] :is(.btn:not(.btn--quiet), .icon-btn:not(.icon-btn-group > *, .stack-sheet__tab:not(.icon-btn--invert))):active:not(:disabled) {
|
|
4072
|
+
background-image: none;
|
|
4073
|
+
box-shadow: var(--finish-control-down);
|
|
4074
|
+
}
|
|
4075
|
+
[data-finish="lit"] .icon-btn-group { box-shadow: var(--finish-control); }
|
|
4076
|
+
[data-finish="lit"] .toggle { box-shadow: var(--finish-sunk); }
|
|
4077
|
+
[data-finish="lit"] .toggle::after { box-shadow: 0 1px 2px color-mix(in srgb, var(--_shade) 35%, transparent); }
|
|
4078
|
+
|
|
4079
|
+
/* ---- sunk: what the member types into ---- */
|
|
4080
|
+
[data-finish="lit"] :is(.field, .pin__cell) { box-shadow: var(--finish-sunk); }
|
|
4081
|
+
|
|
@@ -21,10 +21,13 @@ export interface CallSheetWay {
|
|
|
21
21
|
/** what that button brings up */
|
|
22
22
|
sheet: CallSheetSheet;
|
|
23
23
|
}
|
|
24
|
-
export interface CallSheetProps extends Omit<ComponentProps<typeof Screen>, 'children' | 'fill' | '
|
|
24
|
+
export interface CallSheetProps extends Omit<ComponentProps<typeof Screen>, 'children' | 'fill' | 'bottom' | 'title'> {
|
|
25
|
+
/** TOP (optional, the Screen's own): none by default — the page starts at the lead (15%). A walk in several sheets may stand
|
|
26
|
+
* its `Track` here: it stays in sight over every sheet, a full sheet stops under it. */
|
|
27
|
+
top?: ComponentProps<typeof Screen>['top'];
|
|
25
28
|
/** a picture above the words (optional) */
|
|
26
29
|
media?: ReactNode;
|
|
27
|
-
/** the page's one heading — its h1
|
|
30
|
+
/** the page's one heading — its h1 */
|
|
28
31
|
heading: ReactNode;
|
|
29
32
|
/** the words: a string is one paragraph */
|
|
30
33
|
body?: ReactNode;
|
|
@@ -46,7 +49,7 @@ export interface CallSheetProps extends Omit<ComponentProps<typeof Screen>, 'chi
|
|
|
46
49
|
children?: ReactNode;
|
|
47
50
|
}
|
|
48
51
|
/**
|
|
49
|
-
* CallSheet — TEMPLATE, a `Screen` with its parts filled — no top · content: a `Step` holding ONE `Page` (picture · heading (the h1) ·
|
|
52
|
+
* CallSheet — TEMPLATE, a `Screen` with its parts filled — no top (or the one given: `top`) · content: a `Step` holding ONE `Page` (picture · heading (the h1) ·
|
|
50
53
|
* words · the button, or several — `ways`) and the `Sheet` each button calls · no bottom (a sheet finishes on its own foot). The page
|
|
51
54
|
* starts at the screen's lead (15%). The sheets wait `away`; a button brings its own up full; the handle takes it down to peek.
|
|
52
55
|
* One sheet up at a time — a sheet holds that way's WHOLE form.
|
|
@@ -12,7 +12,7 @@ import { Text } from '../type/Text.js';
|
|
|
12
12
|
import { Btn } from '../actions/Btn.js';
|
|
13
13
|
const index = (o) => (o === true ? 0 : typeof o === 'number' ? o : null);
|
|
14
14
|
/**
|
|
15
|
-
* CallSheet — TEMPLATE, a `Screen` with its parts filled — no top · content: a `Step` holding ONE `Page` (picture · heading (the h1) ·
|
|
15
|
+
* CallSheet — TEMPLATE, a `Screen` with its parts filled — no top (or the one given: `top`) · content: a `Step` holding ONE `Page` (picture · heading (the h1) ·
|
|
16
16
|
* words · the button, or several — `ways`) and the `Sheet` each button calls · no bottom (a sheet finishes on its own foot). The page
|
|
17
17
|
* starts at the screen's lead (15%). The sheets wait `away`; a button brings its own up full; the handle takes it down to peek.
|
|
18
18
|
* One sheet up at a time — a sheet holds that way's WHOLE form.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usableapp/cardds",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.45",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "card-first mobile design system, React-first: the components in src/ are thin wrappers over the CSS contract (css/*.css stays the only truth); gallery/ shows every story live (npm run dev), tests/ measures the geometry.",
|