@usableapp/cardds 0.7.103 → 0.7.104
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 +27 -0
- package/css/actions.css +102 -36
- package/css/base.css +139 -15
- package/css/card.css +308 -79
- package/css/choice.css +25 -33
- package/css/finish.css +28 -27
- package/css/forms.css +6 -14
- package/css/journey.css +4 -4
- package/css/layover.css +26 -24
- package/css/lists.css +8 -6
- package/css/media.css +13 -74
- package/css/numbers.css +37 -32
- package/css/palette.css +1 -1
- package/css/people.css +3 -8
- package/css/post.css +23 -19
- package/css/sheet.css +84 -56
- package/css/stack.css +39 -215
- package/css/stamp.css +41 -29
- package/css/step.css +1 -107
- package/css/sticky.css +43 -41
- package/css/theme.template.css +12 -0
- package/css/tokens.css +100 -26
- package/dist/actions/Chip.d.ts +1 -1
- package/dist/actions/Chip.js +3 -2
- package/dist/cardds.css +1053 -868
- package/dist/cards/Card.d.ts +3 -3
- package/dist/cards/Card.js +1 -1
- package/dist/cards/CardFeed.js +7 -9
- package/dist/catalog.json +1 -1
- package/dist/layover/Snackbar.js +2 -2
- package/dist/lists/Bubble.d.ts +1 -1
- package/dist/lists/Bubble.js +1 -1
- package/dist/lists/Row.js +5 -7
- package/dist/numbers/Picker.js +11 -18
- package/dist/people/Avatar.d.ts +1 -1
- package/dist/people/Avatar.js +3 -2
- package/dist/post/PostDesk.js +6 -9
- package/dist/post/PostLetter.js +4 -4
- package/dist/pressable.d.ts +9 -0
- package/dist/pressable.js +6 -0
- package/dist/room.d.ts +5 -0
- package/dist/room.js +9 -0
- package/dist/scaffold/Panes.js +8 -14
- package/dist/sheets/Sheet.d.ts +1 -1
- package/dist/sheets/Sheet.js +2 -3
- package/dist/sheets/SheetSteps.js +3 -3
- package/dist/sheets/StackSheet.d.ts +1 -1
- package/dist/sheets/sheetStepsPile.js +2 -3
- package/dist/sheets/stackCard.js +67 -115
- package/dist/state.d.ts +21 -0
- package/dist/state.js +28 -1
- package/dist/sticky/Sticky.js +3 -7
- package/dist/templates/Home.d.ts +1 -1
- package/dist/templates/Splash.js +2 -2
- package/dist/templates/Walkthrough.js +4 -5
- package/docs/reference.md +71 -9
- package/lib/catalog.mjs +23 -7
- package/lint/rules.mjs +7 -5
- package/lint/values.mjs +144 -0
- package/package.json +6 -4
package/css/sheet.css
CHANGED
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
inset: 0;
|
|
72
72
|
top: var(--_top, 0); /* a stage keeps its top bar's line free — see .sheet-stage */
|
|
73
73
|
translate: 0 calc(var(--_y) + var(--_drag, 0rem)); /* --_drag: the Sheet component, only while the handle is held */
|
|
74
|
-
transition: translate var(--motion-sheet) ease;
|
|
74
|
+
transition: translate var(--motion-sheet) var(--ease);
|
|
75
75
|
|
|
76
76
|
/* handle · head · body: a column, the body takes what is left and scrolls
|
|
77
77
|
(below) — so the handle and the head never move, whatever the content */
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
that holds that way's WHOLE form, its submit on the sheet's foot, leading to the next page. The base
|
|
105
105
|
carries no control. It is NOT for a form taken apart — one sheet per field, a "send" left on the base:
|
|
106
106
|
a form lives whole in one sheet. */
|
|
107
|
-
.sheet--away { --_y: 100%; --_cover: var(--_box); visibility: hidden; transition: translate var(--motion-sheet) ease, visibility 0s linear var(--motion-sheet); }
|
|
107
|
+
.sheet--away { --_y: 100%; --_cover: var(--_box); visibility: hidden; transition: translate var(--motion-sheet) var(--ease), visibility 0s var(--ease-linear) var(--motion-sheet); }
|
|
108
108
|
.sheet.is-dragging { transition: none; } /* follows the finger; the snap gets the ease back */
|
|
109
109
|
|
|
110
110
|
/* the body — everything under the head, the one thing in a sheet that
|
|
@@ -149,23 +149,8 @@
|
|
|
149
149
|
One row, ≤ 2 buttons. <div class="card__foot"><button class="btn btn--primary btn--block">…</button></div> */
|
|
150
150
|
/* …and the link row under the button, when there is one (its line + the gap over it) */
|
|
151
151
|
.sheet:has(> .card__foot--link) { --_foot: calc(var(--card-gap) + var(--sheet-foot-h, calc(var(--btn-h) + var(--sp-1) + var(--link-sm-min-h, calc(var(--tap-base) * 7 / 12)))) + var(--card-pad) + var(--_safe-b-open)); } /* --sheet-foot-h: the foot's rows as the Sheet measured them (a button grows with the text size) */
|
|
152
|
-
.sheet > .card__foot {
|
|
153
|
-
position: absolute; inset: calc(-1 * var(--border-w)) 0 0; z-index: 1; /* the sheet's border box: the same height the sheet's own % reads */
|
|
154
|
-
align-items: end;
|
|
155
|
-
align-content: end;
|
|
156
|
-
padding: 0 var(--card-pad) calc(var(--card-pad) + var(--_safe-b-open));
|
|
157
|
-
background: linear-gradient(var(--card-bg), var(--card-bg)) bottom / 100% var(--_foot) no-repeat;
|
|
158
|
-
pointer-events: none;
|
|
159
|
-
translate: 0 calc(-1 * var(--_y) - var(--_drag, 0rem));
|
|
160
|
-
transition: translate var(--motion-sheet) ease, visibility 0s;
|
|
161
|
-
}
|
|
162
152
|
.sheet > .card__foot > * { pointer-events: auto; }
|
|
163
153
|
.sheet:has(> .card__foot) > .sheet__body { margin-bottom: calc(var(--_foot) - var(--card-pad)); } /* the body stops above the strip (the card's own padding is the rest) */
|
|
164
|
-
.sheet.is-dragging > .card__foot { transition: none; }
|
|
165
|
-
/* at peek and away the foot is NOT held on the box's edge: it stands on the sheet's own bottom edge (no counter-slide), so it
|
|
166
|
-
LEAVES AND ARRIVES WITH ITS SHEET — solid the whole way, hidden only once the slide is over. It used to stay in place and
|
|
167
|
-
fade: the body slid through the strip behind a half-transparent button (timebank, Lh 2026-10-01: "ตัวหนังสือลอดใต้ปุ่ม"). */
|
|
168
|
-
:is(.sheet--peek, .sheet--away) > .card__foot { translate: 0 0; visibility: hidden; transition: translate var(--motion-sheet) ease, visibility 0s linear var(--motion-sheet); }
|
|
169
154
|
/* that padding can be taller than the body's own box (a short box: a small phone with the keyboard up) and a
|
|
170
155
|
box is never smaller than its padding — so the pinned parts must not give way to it: the body runs past
|
|
171
156
|
the sheet's clipped edge instead, where nothing shows anyway. At peek and away no part of the body shows. */
|
|
@@ -182,14 +167,14 @@
|
|
|
182
167
|
touch-action: none hands a touch drag to the Sheet component instead of to the scroller. */
|
|
183
168
|
.sheet__handle {
|
|
184
169
|
position: absolute;
|
|
185
|
-
z-index:
|
|
170
|
+
z-index: var(--z-over);
|
|
186
171
|
top: calc((var(--card-pad) - var(--sp-1)) / 2); /* the dots' top: (pad − 4) / 2. The line starts there too */
|
|
187
172
|
left: 50%;
|
|
188
173
|
translate: -50% 0;
|
|
189
174
|
border: 0;
|
|
190
175
|
color: inherit; /* a <button> has its own UA colour; the mark is the card's ink */
|
|
191
176
|
background: currentColor;
|
|
192
|
-
opacity:
|
|
177
|
+
opacity: var(--fade-dim);
|
|
193
178
|
width: calc(var(--sp-base) * 18); /* 72: the line. The grab is the ::before, not this width */
|
|
194
179
|
height: var(--_handle);
|
|
195
180
|
border-radius: var(--sheet-handle-radius, var(--r-chip));
|
|
@@ -198,22 +183,22 @@
|
|
|
198
183
|
touch-action: none;
|
|
199
184
|
cursor: grab;
|
|
200
185
|
}
|
|
201
|
-
/* paper: the head keeps the sheet's own colour, the content is
|
|
186
|
+
/* paper: the head keeps the sheet's own colour, the content is the theme's paper, --action-bg, the ground of every field (Lh 2026-10-05: white; Lh 2026-10-20: the theme's, never a fixed white).
|
|
202
187
|
The body and the foot read as paper; the handle and the head stay on the card.
|
|
203
188
|
The flex gap under the head is outside the body, so it stays the sheet's tint.
|
|
204
|
-
The first field would sit on that colour seam. The
|
|
189
|
+
The first field would sit on that colour seam. The paper's inset is --sp-6 (24px at
|
|
205
190
|
the default spacing), the body's own top padding, and only when the sheet is paper.
|
|
206
191
|
A plain sheet keeps padding-top 0. A sheet in a stack wears the same class and the same
|
|
207
|
-
inset: the stack's own gap under the head is the card's colour, so the row still needs this
|
|
208
|
-
The paper
|
|
192
|
+
inset: the stack's own gap under the head is the card's colour, so the row still needs this paper.
|
|
193
|
+
The paper takes the side of the controls' paper (--action-dark): on a dark sheet its words still turn to onlight. */
|
|
209
194
|
.sheet--paper > .sheet__body {
|
|
210
|
-
--card-bg: var(--
|
|
211
|
-
--dark: var(--
|
|
195
|
+
--card-bg: var(--action-bg);
|
|
196
|
+
--dark: var(--action-dark);
|
|
212
197
|
background: var(--card-bg);
|
|
213
198
|
color: var(--card-ink);
|
|
214
199
|
padding-top: var(--sp-6);
|
|
215
200
|
}
|
|
216
|
-
.sheet--paper > .card__foot { --card-bg: var(--
|
|
201
|
+
.sheet--paper > .card__foot { --card-bg: var(--action-bg); --dark: var(--action-dark); --card-foot-ink: var(--card-ink); }
|
|
217
202
|
.sheet__handle--dots {
|
|
218
203
|
--_dot: var(--sp-1);
|
|
219
204
|
--_step: calc(var(--_dot) * 2.5);
|
|
@@ -230,15 +215,15 @@
|
|
|
230
215
|
background-position: 0 0, var(--_step) 0, calc(2 * var(--_step)) 0, calc(3 * var(--_step)) 0;
|
|
231
216
|
}
|
|
232
217
|
/* the app reloads what the sheet shows (`refreshing`, off unless set): the mark changes colour exactly as a stack sheet's grip
|
|
233
|
-
does —
|
|
218
|
+
does — the ondark ink → the onlight ink and back, so a light sheet and a dark one each get a moment it stands out. --_grip and the keyframes are
|
|
234
219
|
the stack's (stack.css): one sign for both. Nothing travels. */
|
|
235
220
|
.sheet.is-loading > .sheet__handle {
|
|
236
221
|
opacity: 1;
|
|
237
|
-
background-color: color-mix(in srgb,
|
|
238
|
-
animation: stack-grip-dissolve
|
|
222
|
+
background-color: color-mix(in srgb, var(--ink-onlight) calc(var(--_grip) * 100%), var(--ink-ondark));
|
|
223
|
+
animation: stack-grip-dissolve var(--motion-pulse) var(--ease-in-out) infinite alternate;
|
|
239
224
|
}
|
|
240
225
|
.sheet.is-loading > .sheet__handle--dots {
|
|
241
|
-
--_ink: color-mix(in srgb,
|
|
226
|
+
--_ink: color-mix(in srgb, var(--ink-onlight) calc(var(--_grip) * 100%), var(--ink-ondark));
|
|
242
227
|
background-color: transparent;
|
|
243
228
|
}
|
|
244
229
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -262,18 +247,18 @@
|
|
|
262
247
|
- a label .row with its .check / .toggle may be the head when the sheet's
|
|
263
248
|
whole ask is that switch: peek shows it (a row is --tap tall plus its own
|
|
264
249
|
padding; the strip cuts in that padding) — card #67's "ไม่อยู่บ้าน" */
|
|
265
|
-
.sheet > .card__head { min-
|
|
250
|
+
.sheet > .card__head { --card-head-min-h: var(--sheet-head-h); }
|
|
266
251
|
/* a sheet's title is ONE line, always (Lh 2026-09-28, timebank #153: "ข้อกำหนดและเงื่อนไขการใช้งาน" wrapped to two lines at 390px) — the
|
|
267
252
|
thing at its end keeps its place beside it; a caption still takes its own row. A title too long for the line RUNS sideways
|
|
268
253
|
like a song title (Lh 2026-10-03, as the StackSheet's — it was cut with …, and the end of it could never be read): the Sheet
|
|
269
254
|
measures --_over, the width it overflows by, and sets .is-long; one way — it waits, runs to its end, waits, and starts again
|
|
270
255
|
from the first letter. The move is text-indent: the heading is the app's own element, there is no inner box to slide.
|
|
271
256
|
Before the Sheet has measured, and where motion is off, it is cut with …. */
|
|
272
|
-
.sheet > .card__head:not(:has(> :is(.t-caption, .t-body))) {
|
|
257
|
+
.sheet > .card__head:not(:has(> :is(.t-caption, .t-body))) { --card-head-wrap: nowrap; }
|
|
273
258
|
.sheet > .card__head > :is(h1, h2, h3):first-child, .sheet__title { white-space: nowrap; overflow-x: clip; overflow-y: visible; text-overflow: ellipsis; min-width: 0; } /* clip SIDEWAYS only: hidden cut the Thai tone marks over the line */
|
|
274
259
|
.sheet > .card__head > :is(h1, h2, h3):first-child.is-long, .sheet__title.is-long {
|
|
275
260
|
text-overflow: clip;
|
|
276
|
-
animation: sheet-title-run var(--sheet-title-run-time, var(--_run,
|
|
261
|
+
animation: sheet-title-run var(--sheet-title-run-time, var(--_run, var(--motion-run))) var(--ease-in-out) infinite; /* --_run: from the overflow, 30px a second + the pauses */
|
|
277
262
|
}
|
|
278
263
|
@keyframes sheet-title-run { 0%, 20% { text-indent: 0; } 85%, 100% { text-indent: calc(-1 * var(--_over)); } }
|
|
279
264
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -364,11 +349,11 @@
|
|
|
364
349
|
isolation: isolate; /* the ring and the hint stack inside the map only — a sheet over the map covers them */
|
|
365
350
|
color: var(--map-ink, var(--on-surface));
|
|
366
351
|
background:
|
|
367
|
-
repeating-linear-gradient(
|
|
368
|
-
repeating-linear-gradient(-
|
|
352
|
+
repeating-linear-gradient(var(--street-1), transparent 0 calc(var(--tap-base) * 11 / 6), var(--hairline) calc(var(--tap-base) * 11 / 6) calc(var(--tap-base) * 25 / 12)),
|
|
353
|
+
repeating-linear-gradient(var(--street-2), transparent 0 calc(var(--tap-base) * 35 / 12), var(--ink-tint) calc(var(--tap-base) * 35 / 12) calc(var(--tap-base) * 37 / 12)),
|
|
369
354
|
var(--card-2-bg);
|
|
370
355
|
}
|
|
371
|
-
.map > :first-child { position: absolute; inset: 0; z-index:
|
|
356
|
+
.map > :first-child { position: absolute; inset: 0; z-index: var(--z-flat); isolation: isolate; background: transparent; } /* its own stacking context: an engine's layered panes stay under the ring; an engine's own grey ground would hide the pattern while tiles load */
|
|
372
357
|
.map__ring {
|
|
373
358
|
position: absolute;
|
|
374
359
|
left: 50%;
|
|
@@ -383,7 +368,7 @@
|
|
|
383
368
|
background: var(--map-ring-bg, var(--accent-soft));
|
|
384
369
|
box-shadow: var(--map-ring-shadow, var(--shadow-float));
|
|
385
370
|
pointer-events: none;
|
|
386
|
-
z-index:
|
|
371
|
+
z-index: var(--z-over); /* above the engine's panes (Leaflet's tiles sit at 200, but inside their own stacking context) */
|
|
387
372
|
}
|
|
388
373
|
.map__pin { /* mark="pin": an exact point — the pin's TIP is where the ring's centre sits, so the engine reads the element's bottom-centre */
|
|
389
374
|
position: absolute;
|
|
@@ -398,11 +383,11 @@
|
|
|
398
383
|
color: var(--map-pin-ink, var(--card-ink));
|
|
399
384
|
filter: drop-shadow(var(--map-pin-drop, var(--shadow-float)));
|
|
400
385
|
pointer-events: none;
|
|
401
|
-
z-index:
|
|
386
|
+
z-index: var(--z-over);
|
|
402
387
|
}
|
|
403
388
|
/* the lucide tip stops 2.2 of 24 short of the box's bottom: lowered so the tip IS the bottom-centre; filled with the surface so the
|
|
404
389
|
street pattern never shows through the pin's body */
|
|
405
|
-
.map__pin > .icon {
|
|
390
|
+
.map__pin > .icon { --icon-size: 100%; --icon-shift: 0 9%; }
|
|
406
391
|
.map__credit { /* the tile provider's credit — required by OSM; a caption, not the engine's own control */
|
|
407
392
|
position: absolute;
|
|
408
393
|
right: var(--sp-2);
|
|
@@ -413,7 +398,7 @@
|
|
|
413
398
|
color: var(--map-credit-ink, var(--on-surface-muted));
|
|
414
399
|
font: var(--map-credit-font, var(--type-caption));
|
|
415
400
|
pointer-events: none;
|
|
416
|
-
z-index:
|
|
401
|
+
z-index: var(--z-over);
|
|
417
402
|
}
|
|
418
403
|
.map__hint {
|
|
419
404
|
position: absolute;
|
|
@@ -431,7 +416,7 @@
|
|
|
431
416
|
text-align: center;
|
|
432
417
|
box-shadow: var(--map-hint-shadow, var(--shadow-float));
|
|
433
418
|
pointer-events: none;
|
|
434
|
-
z-index:
|
|
419
|
+
z-index: var(--z-over);
|
|
435
420
|
}
|
|
436
421
|
|
|
437
422
|
/* ---- the map IN FLOW (Lh 2026-10-17): `.map--inline` — a box in a card, or the whole of a sheet's body ----
|
|
@@ -461,7 +446,7 @@
|
|
|
461
446
|
name; the picked one fills with accent. Above the ring: the ring takes no taps, the places do. */
|
|
462
447
|
.map-pick {
|
|
463
448
|
position: absolute;
|
|
464
|
-
z-index: 2;
|
|
449
|
+
z-index: var(--z-over-2);
|
|
465
450
|
width: var(--tap);
|
|
466
451
|
height: var(--tap);
|
|
467
452
|
translate: -50% -50%;
|
|
@@ -492,7 +477,7 @@
|
|
|
492
477
|
background: var(--map-pick-name-bg, color-mix(in srgb, var(--surface) 85%, transparent));
|
|
493
478
|
font: var(--map-pick-font, var(--type-caption));
|
|
494
479
|
}
|
|
495
|
-
.map-pick:has(:checked) { z-index: 3; } /* the picked place's name lies over a neighbour's */
|
|
480
|
+
.map-pick:has(:checked) { z-index: var(--z-over-3); } /* the picked place's name lies over a neighbour's */
|
|
496
481
|
.map-pick:has(:checked) > :is(.map-pick__mark, .map-pick__name) { background: var(--map-pick-on-bg, var(--accent)); color: var(--map-pick-on-ink, var(--on-accent)); }
|
|
497
482
|
.map-pick:has(:focus-visible) > .map-pick__mark { outline: var(--focus); outline-offset: var(--sp-0); }
|
|
498
483
|
.map-pick:has(:disabled) { opacity: var(--off); cursor: default; }
|
|
@@ -517,8 +502,8 @@
|
|
|
517
502
|
/* 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
|
|
518
503
|
is 3.9:1; doubled, #404040, 10:1. It read --card-3-ink, a brand's light ink, on a black scrim */
|
|
519
504
|
background: var(--sheet-stage-foot-bg, var(--scrim));
|
|
520
|
-
color: var(--sheet-stage-foot-ink,
|
|
521
|
-
z-index: 2;
|
|
505
|
+
color: var(--sheet-stage-foot-ink, var(--ink-ondark));
|
|
506
|
+
z-index: var(--z-over-2);
|
|
522
507
|
}
|
|
523
508
|
|
|
524
509
|
/* dim stage: blur + darken whatever sits behind the sheet */
|
|
@@ -528,9 +513,9 @@
|
|
|
528
513
|
position: absolute;
|
|
529
514
|
inset: 0;
|
|
530
515
|
background: var(--scrim);
|
|
531
|
-
z-index:
|
|
516
|
+
z-index: var(--z-over);
|
|
532
517
|
}
|
|
533
|
-
.sheet-stage--dim .sheet { z-index: 2; }
|
|
518
|
+
.sheet-stage--dim .sheet { z-index: var(--z-over-2); }
|
|
534
519
|
|
|
535
520
|
/* ---- sheet steps: one task in steps inside one sheet (Lh 2026-09-24) ----
|
|
536
521
|
<div class="sheet-steps"> › <ol class="sheet-steps__track"> of <li class="sheet-step sheet-step--done|now|next">. The done steps
|
|
@@ -541,14 +526,14 @@
|
|
|
541
526
|
falls — no height is written. Nothing fades: done and next read at full ink. */
|
|
542
527
|
.sheet__body:has(> .sheet-steps) { display: flex; flex-direction: column; }
|
|
543
528
|
.sheet-steps { flex-shrink: 0; min-height: calc(100% + var(--kb, 0rem)); /* the keyboard's height more: the pile of next steps stays under the keyboard, it never rises with it */ display: flex; flex-direction: column; touch-action: pan-y; position: relative; }
|
|
544
|
-
.sheet-steps__holder { position: absolute; top: 0; left: 0; width:
|
|
529
|
+
.sheet-steps__holder { position: absolute; top: 0; left: 0; width: var(--browser-text); height: var(--browser-text); padding: 0; border: 0; opacity: 0; pointer-events: none; font-size: var(--browser-text); } /* holds the cursor (and the phone's keyboard) while a step folds; font 1rem = the browser's own size, so iOS does not zoom to it */
|
|
545
530
|
.sheet-steps__track { list-style: none; margin: 0; padding: 0 0 var(--sheet-steps-end, var(--sp-6)); flex: 1; /* room under the LAST step: scrolled to the end it never touches the foot's button (Lh 2026-09-28, #153) */ display: flex; flex-direction: column; }
|
|
546
531
|
|
|
547
532
|
.sheet-step {
|
|
548
533
|
position: relative; min-width: 0;
|
|
549
534
|
display: grid; grid-template-columns: minmax(0, 1fr); /* the column is the step's width, never its words' — a long summary is cut with …, it never pushes the row past the sheet's edge (Lh 2026-09-28, #153) */ grid-template-rows: auto 0fr; align-content: start; /* mid-fold the rows sum to less than the box: the spare room stays BELOW, never spread into the title row (Lh: it looked like a spring) */
|
|
550
535
|
flex: 0 0 auto;
|
|
551
|
-
transition: grid-template-rows var(--motion-sheet) ease, flex-grow var(--motion-sheet) ease;
|
|
536
|
+
transition: grid-template-rows var(--motion-sheet) var(--ease), flex-grow var(--motion-sheet) var(--ease);
|
|
552
537
|
--_row-h: var(--sheet-steps-row-h, calc(var(--tap-base) * 2 / 3)); /* the bar's own floor, read once (__head and __go below share it) */
|
|
553
538
|
}
|
|
554
539
|
/* the open step GROWS into the room left, so the steps not done yet wait in a pile at the bottom — and a move is an ACCORDION:
|
|
@@ -556,7 +541,7 @@
|
|
|
556
541
|
with them, nothing jumps (Lh 2026-09-24) */
|
|
557
542
|
.sheet-step--now { grid-template-rows: auto 1fr; flex-grow: 1; }
|
|
558
543
|
.sheet-step + .sheet-step { margin-top: var(--sheet-steps-gap, var(--sp-1)); } /* the folded bars read as a pile, a little ground between them (Lh 2026-09-25) */
|
|
559
|
-
.sheet-step__head { /* every step's title line is a quiet BAR (a tint of the ink, not the brand — a brand bar read as a button, Lh 2026-09-25), the same height open or folded — opening shows the
|
|
544
|
+
.sheet-step__head { /* every step's title line is a quiet BAR (a tint of the ink, not the brand — a brand bar read as a button, Lh 2026-09-25), the same height open or folded — opening shows the card's room under it, never a taller bar (Lh 2026-09-25; was a thin rule on top) */
|
|
560
545
|
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 */
|
|
561
546
|
padding-inline: var(--sheet-step-bar-pad-x, var(--sp-3)); border-radius: var(--sheet-step-bar-radius, var(--r-chip));
|
|
562
547
|
background: var(--sheet-step-bar-bg, var(--ink-tint)); color: var(--sheet-step-bar-ink, inherit);
|
|
@@ -564,11 +549,11 @@
|
|
|
564
549
|
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 */
|
|
565
550
|
}
|
|
566
551
|
.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; }
|
|
567
|
-
.sheet-step__num { /* `numbered`: the step's number in a disc BEFORE its title (Lh 2026-09-25) — a
|
|
552
|
+
.sheet-step__num { /* `numbered`: the step's number in a disc BEFORE its title (Lh 2026-09-25) — a disc of the card's colour on the bar, the number in the ink */
|
|
568
553
|
flex: none; display: grid; place-items: center; box-sizing: border-box; inline-size: var(--sheet-step-num-size, 1.408em); block-size: var(--sheet-step-num-size, 1.408em); /* em, not rem (Lh 2026-10-03, as the StackSheet's count): the disc is cut from ITS OWN number's size —
|
|
569
554
|
at a large text size the number grew and a 24px disc did not, so the digit sat on its bottom edge; 1.408em of a 17px caption = the 24px it always was */
|
|
570
555
|
padding-bottom: var(--sheet-step-num-lift, 0.1em); /* the room UNDER the number lifts it onto the disc's middle: a digit has no descender, so a centred line box sets it low */
|
|
571
|
-
border-radius: 50%; font: var(--sheet-step-num-font, var(--type-caption)); line-height:
|
|
556
|
+
border-radius: 50%; font: var(--sheet-step-num-font, var(--type-caption)); line-height: var(--lh-solid); font-variant-numeric: tabular-nums;
|
|
572
557
|
background: var(--sheet-step-num-bg, var(--card-bg)); color: var(--sheet-step-num-ink, inherit);
|
|
573
558
|
}
|
|
574
559
|
.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; }
|
|
@@ -576,11 +561,54 @@
|
|
|
576
561
|
.sheet-step__body { min-height: 0; overflow: clip; overflow-clip-margin: var(--sp-1); }
|
|
577
562
|
.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) */
|
|
578
563
|
.sheet-step__inner > * { min-width: 0; }
|
|
579
|
-
.sheet-
|
|
580
|
-
.sheet-step:not(.sheet-step--now) > .sheet-step__body { visibility: hidden; transition: visibility 0s linear var(--motion-sheet); }
|
|
564
|
+
.sheet-step:not(.sheet-step--now) > .sheet-step__body { visibility: hidden; transition: visibility 0s var(--ease-linear) var(--motion-sheet); }
|
|
581
565
|
.sheet-step__go { position: absolute; inset: min(0rem, (var(--_row-h) - var(--tap-sm)) / 2) 0 auto; min-height: max(100%, var(--tap-sm)); /* a thin bar still takes a 44px tap */ margin: 0; cursor: pointer; }
|
|
582
566
|
/* the last step's finish, when the app gives one: under the steps */
|
|
583
567
|
.sheet-steps__finish { display: grid; padding-top: var(--card-gap); }
|
|
584
568
|
@media (prefers-reduced-motion: reduce) { .sheet-step { transition: none; } }
|
|
585
|
-
|
|
586
|
-
|
|
569
|
+
|
|
570
|
+
/* ==== the step bar answers a press, as PRESS in actions.css answers every other control (#62: a block is written in its own file) ==== */
|
|
571
|
+
.sheet-step:has(> .sheet-step__go:active) { opacity: var(--press-dim); } /* the step bar's button is invisible over it: the bar answers */
|
|
572
|
+
|
|
573
|
+
/* ==== a body that holds only an EmptyState stands it at --empty-state-at of its room, as a Step does (step.css) (#62: a block is written in its own file) ==== */
|
|
574
|
+
.sheet__body:has(> .empty-state:only-child) { display: flex; flex-direction: column; gap: 0; }
|
|
575
|
+
.sheet__body:has(> .empty-state:only-child)::before { content: ""; flex: calc(var(--empty-state-at, 0) * 5) 1 0; }
|
|
576
|
+
.sheet__body:has(> .empty-state:only-child)::after { content: ""; flex: calc(5 - var(--empty-state-at, 0) * 5) 1 0; }
|
|
577
|
+
|
|
578
|
+
/* ---- where it sits in what stack.css draws (docs/reference.md rule 15) ---- */
|
|
579
|
+
/* a pull in the content, already at the top: the words move down, the card stays. --_refresh is the finger, private.
|
|
580
|
+
A paper body adds its own --sp-6 on top of this (the rule below): the stack's gap under the head is the
|
|
581
|
+
card's colour, so without the paper's inset the first row sits on that seam. */
|
|
582
|
+
.sheet-stack > .card > .sheet__body { padding-top: var(--_refresh, 0rem); transition: padding-top var(--motion-sheet) var(--ease); }
|
|
583
|
+
/* the head's band is as slim as it can be (Lh 2026-10-06: 20 over · 48 head · 20 under read as a heavy bar): the paper starts
|
|
584
|
+
--sp-3 under the head, not a whole --card-gap (--sp-2 at first; Lh added 4 the same day). The body is pulled up by the difference — the card's gap is left alone, the
|
|
585
|
+
stack's step and the body's own rows read it. */
|
|
586
|
+
.sheet-stack > .card.sheet--paper > .sheet__body {
|
|
587
|
+
margin-top: calc(var(--sp-3) - var(--card-gap));
|
|
588
|
+
padding-top: calc(var(--sp-6) + var(--_refresh, 0rem));
|
|
589
|
+
transition: padding-top var(--motion-sheet) var(--ease), background-color 0s var(--ease-linear);
|
|
590
|
+
}
|
|
591
|
+
/* a pull follows the finger at once, on paper too: the rule above is as strong as the stack's own `is-refreshing` one and comes later */
|
|
592
|
+
.sheet-stack > .card.sheet--paper > .sheet__body.is-refreshing { transition: none; }
|
|
593
|
+
/* a closed paper sheet's body stays clear (Lh 2026-10-06). The next sheet's round top does not
|
|
594
|
+
cover the corners, and a paper body showed there beside the head. Clear, the card's own colour
|
|
595
|
+
shows in that pocket. Open, the body is paper, and the first row sits --sp-6 down, the same paper
|
|
596
|
+
inset a single paper sheet keeps: the flex gap under the head is the card's colour, so the row
|
|
597
|
+
would otherwise sit on that seam. A pull adds --_refresh on top of the inset. On the way back
|
|
598
|
+
into the stack the card colour fades in quickly (--motion-quick) and that fade ends with the
|
|
599
|
+
sheet's own slide (--motion-sheet, plus the same stagger), so the corner is the head colour
|
|
600
|
+
at the moment the sheet stops. Rising, the body is paper at once. */
|
|
601
|
+
.sheet-stack > .card.sheet--paper:not(.is-open) > .sheet__body {
|
|
602
|
+
background-color: transparent;
|
|
603
|
+
transition:
|
|
604
|
+
padding-top var(--motion-sheet) var(--ease),
|
|
605
|
+
background-color var(--motion-quick) var(--ease) calc(var(--stagger, 0) * var(--motion-stagger) + var(--motion-sheet) - var(--motion-quick));
|
|
606
|
+
}
|
|
607
|
+
@media (prefers-reduced-motion: reduce) { .sheet-stack > .card.sheet--paper:not(.is-open) > .sheet__body {
|
|
608
|
+
transition: padding-top var(--motion-sheet) var(--ease), background-color 0s var(--ease-linear);
|
|
609
|
+
} }
|
|
610
|
+
/* ---- where it sits in what step.css draws (docs/reference.md rule 15) ---- */
|
|
611
|
+
.screen--fill > .appbar + .sheet-stage { margin-top: 0; }
|
|
612
|
+
|
|
613
|
+
/* ---- where it sits in what stack.css draws: a body pulled to refresh holds still (docs/reference.md rule 15) ---- */
|
|
614
|
+
.sheet-stack > .card > .sheet__body.is-refreshing { transition: none; }
|