@usableapp/cardds 0.7.14 → 0.7.16
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 +43 -0
- package/README.md +6 -8
- package/css/actions.css +24 -1
- package/css/base.css +2 -2
- package/css/card.css +9 -13
- package/css/choice.css +2 -2
- package/css/journey.css +3 -3
- package/css/layover.css +5 -17
- package/css/media.css +6 -5
- package/css/numbers.css +4 -3
- package/css/palette.css +81 -40
- package/css/people.css +3 -2
- package/css/sheet.css +4 -6
- package/css/stack.css +6 -10
- package/css/step.css +3 -5
- package/css/theme.template.css +2 -1
- package/css/tokens.css +12 -1
- package/dist/actions/Dropdown.js +4 -5
- package/dist/cardds.css +164 -110
- package/dist/cards/Card.d.ts +3 -3
- package/dist/choice/Calendar.js +3 -5
- package/dist/choice/Mood.d.ts +10 -5
- package/dist/choice/Mood.js +4 -2
- package/dist/forms/Pin.js +7 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lists/Row.d.ts +2 -1
- package/dist/lists/Row.js +2 -2
- package/dist/media/Postcard.js +3 -5
- package/dist/media/Tile.d.ts +1 -1
- package/dist/numbers/Band.d.ts +1 -1
- package/dist/numbers/Picker.js +4 -5
- package/dist/numbers/Track.d.ts +4 -2
- package/dist/numbers/Track.js +3 -3
- package/dist/people/AvatarPick.d.ts +3 -1
- package/dist/people/AvatarPick.js +2 -2
- package/dist/scaffold/Centre.d.ts +1 -1
- package/dist/scaffold/Centre.js +1 -1
- package/dist/scaffold/Screen.d.ts +1 -1
- package/dist/scaffold/Screen.js +3 -4
- package/dist/scaffold/TopBar.js +3 -5
- package/dist/sheets/Sheet.js +5 -7
- package/dist/sheets/SheetStack.js +4 -5
- package/dist/sheets/SheetSteps.js +5 -6
- package/dist/sheets/StackSheet.d.ts +1 -1
- package/dist/sheets/StackSheet.js +4 -5
- package/dist/state.d.ts +7 -0
- package/dist/state.js +17 -0
- package/dist/templates/CallSheet.js +3 -4
- package/dist/templates/Home.d.ts +1 -1
- package/dist/templates/Home.js +3 -4
- package/dist/templates/Splash.js +2 -1
- package/dist/templates/Walkthrough.js +4 -5
- package/dist/type/Icon.js +3 -5
- package/dist/type/textScale.d.ts +6 -0
- package/dist/type/textScale.js +12 -0
- package/package.json +1 -1
- package/dist/layover/Deck.d.ts +0 -9
- package/dist/layover/Deck.js +0 -10
package/dist/cardds.css
CHANGED
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
--btn-h: calc(var(--tap-base) * 13 / 12); /* 52 button height */
|
|
90
90
|
--btn-xl-h: calc(var(--tap-base) * 11 / 6); /* 88 the one giant CTA */
|
|
91
91
|
--chip-h: calc(var(--tap-base) * 19 / 24); /* 38 chip height */
|
|
92
|
-
--bar-h: calc(var(--tap-base) * 4 / 3); /* 64 float bar, day cell
|
|
92
|
+
--bar-h: calc(var(--tap-base) * 4 / 3); /* 64 float bar, day cell */
|
|
93
93
|
--header-h: calc(var(--tap-base) * 5 / 4); /* 60 top bar — .topbar and .appbar alike */
|
|
94
94
|
--card-pad-rest: var(--sp-5); /* 20 a card's padding before any variant — .card publishes it as --card-pad; the sheet's peek strip is built from it where no card is in scope */
|
|
95
95
|
--card-gap-rest: var(--sp-4); /* 16 …and its gap */
|
|
@@ -136,6 +136,9 @@
|
|
|
136
136
|
--motion-sheet: 0.35s;
|
|
137
137
|
--motion-slide: 0.22s; /* a centred card sliding out and the next in (card.css) — quick, a page turn (Lh, 2026-09-12) */
|
|
138
138
|
--motion-flip: 0.45s; /* a postcard turning over (media.css) — slow enough to read as a card in the hand */
|
|
139
|
+
--dim: 0.7; /* secondary words dimmed on a ground whose muted ink does not fit (the dark card --3, a drawer, a tile's sub line): ONE share for all */
|
|
140
|
+
--motion-press: 0.12s; /* a control giving under the finger and springing back (actions.css PRESS) */
|
|
141
|
+
--press-scale: 0.96; /* how far it gives — a share of its size */
|
|
139
142
|
|
|
140
143
|
/* ---- typography: one scale, rem so it follows the root ---- */
|
|
141
144
|
--font-ui: "PK Nonthaburi", -apple-system, system-ui, sans-serif; /* fonts.css ships it; the rest is the fallback while it loads */
|
|
@@ -208,6 +211,9 @@
|
|
|
208
211
|
--card-1-bg: var(--color-paper, #ffffff); --card-1-ink: var(--color-ink, #141414);
|
|
209
212
|
--card-2-bg: var(--_tone-2, #e6e6e3); --card-2-ink: var(--color-ink, #141414);
|
|
210
213
|
--card-3-bg: var(--color-brand, #141414); --card-3-ink: var(--color-on-brand, #ffffff);
|
|
214
|
+
/* tones 4 · 5 (Lh 2026-09-25): more card colours for a palette that has them — the wireframe keeps them grey */
|
|
215
|
+
--card-4-bg: #d4d4d0; --card-4-ink: var(--color-ink, #141414); --card-4-muted: #555555;
|
|
216
|
+
--card-5-bg: #3d3d3d; --card-5-ink: #ffffff; --card-5-muted: #c4c4c4;
|
|
211
217
|
|
|
212
218
|
--card-border: #141414; /* wireframe: visible outline; palettes may set transparent */
|
|
213
219
|
--card-muted: var(--_muted-on-paper, #6b6b6b); /* secondary text inside cards (the default, tone-1 card) */
|
|
@@ -228,6 +234,11 @@
|
|
|
228
234
|
--neg: #3d3d3d;
|
|
229
235
|
--dot-a: var(--color-brand, #141414);
|
|
230
236
|
--dot-b: #8a8a8a;
|
|
237
|
+
--signal-warn: #8a6d00; /* the full signal set (Lh 2026-09-25): error · warn · ok · info — each with an icon and words */
|
|
238
|
+
--signal-ok: #2e7d32;
|
|
239
|
+
--signal-info: #2f5f9e;
|
|
240
|
+
/* highlights (Lh 2026-09-25): four atmosphere colours a palette may set for decoration — a count, a mark, a chart dot; the wireframe keeps them grey */
|
|
241
|
+
--highlight-1: #3d3d3d; --highlight-2: #8a8a8a; --highlight-3: #5f5f5f; --highlight-4: #b0b0b0;
|
|
231
242
|
--signal-error: #c62828; /* the ONE colour in the wireframe (Lh 2026-09-24): something went wrong — a field's edge, the words that say what. Always with an icon and words, never the colour alone */
|
|
232
243
|
|
|
233
244
|
/* derived tints — read the element's own ink, so they work on any slot */
|
|
@@ -288,46 +299,6 @@
|
|
|
288
299
|
--dot-a: #e05c3a; --dot-b: #6f6be0;
|
|
289
300
|
}
|
|
290
301
|
|
|
291
|
-
/* ---- SHINE — shiny: periwinkle surface, coral / black / gold cards ---- */
|
|
292
|
-
[data-palette="shine"] {
|
|
293
|
-
--surface: #6d6ae4;
|
|
294
|
-
--on-surface: #ffffff;
|
|
295
|
-
--on-surface-muted: #d3d2f7;
|
|
296
|
-
|
|
297
|
-
--card-1-bg: #eec85a; --card-1-ink: #16161a;
|
|
298
|
-
--card-2-bg: #e8624a; --card-2-ink: #16161a;
|
|
299
|
-
--card-3-bg: #1b1b1f; --card-3-ink: #ffffff;
|
|
300
|
-
|
|
301
|
-
--card-border: transparent;
|
|
302
|
-
--card-muted: #4c4a44;
|
|
303
|
-
|
|
304
|
-
--accent: #1b1b1f; --on-accent: #ffffff;
|
|
305
|
-
--action-bg: #ffffff; --action-ink: #16161a; --action-border: transparent;
|
|
306
|
-
|
|
307
|
-
--pos: #2e9e5b; --neg: #d6402a;
|
|
308
|
-
--dot-a: #e8624a; --dot-b: #6d6ae4;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/* ---- FIELD — warm peach editorial: cream surface, orange accent ---- */
|
|
312
|
-
[data-palette="field"] {
|
|
313
|
-
--surface: #f9e8dc;
|
|
314
|
-
--on-surface: #241f1b;
|
|
315
|
-
--on-surface-muted: #8a7d72;
|
|
316
|
-
|
|
317
|
-
--card-1-bg: #ffffff; --card-1-ink: #241f1b;
|
|
318
|
-
--card-2-bg: #f6d9c5; --card-2-ink: #241f1b;
|
|
319
|
-
--card-3-bg: #ef4e0b; --card-3-ink: #fff4ec;
|
|
320
|
-
|
|
321
|
-
--card-border: transparent;
|
|
322
|
-
--card-muted: #8a7d72;
|
|
323
|
-
|
|
324
|
-
--accent: #ef4e0b; --on-accent: #fff4ec;
|
|
325
|
-
--action-bg: #ffffff; --action-ink: #241f1b; --action-border: transparent;
|
|
326
|
-
|
|
327
|
-
--pos: #2e8f52; --neg: #d13b1a;
|
|
328
|
-
--dot-a: #ef4e0b; --dot-b: #241f1b;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
302
|
/* ---- ROAST — coffee: warm cream surface, caramel accent ---- */
|
|
332
303
|
[data-palette="roast"] {
|
|
333
304
|
--surface: #f6f1e7;
|
|
@@ -368,6 +339,87 @@
|
|
|
368
339
|
--dot-a: #3d63e0; --dot-b: #eec85a;
|
|
369
340
|
}
|
|
370
341
|
|
|
342
|
+
/* ---- ORCHARD — modern earth: calm, real, touchable (Lh 2026-09-25). Linen base, bone paper, moss brand; every
|
|
343
|
+
tone's ink + muted is a deep shade of ITS OWN ground, so lines (currentColor mixes: --hairline, --outline, field
|
|
344
|
+
edges) come out as a darker tint of the ground under them — never a grey on a warm card. Four highlights for the
|
|
345
|
+
atmosphere, off the earth wheel on purpose: maple red · bright yellow · sky · fuchsia. ---- */
|
|
346
|
+
[data-palette="orchard"] {
|
|
347
|
+
--surface: #f4efe6; /* linen */
|
|
348
|
+
--on-surface: #2a241c; /* umber */
|
|
349
|
+
--on-surface-muted: #6e6353;
|
|
350
|
+
|
|
351
|
+
--card-1-bg: #fbf8f2; --card-1-ink: #2a241c; /* bone paper — sheets */
|
|
352
|
+
--card-2-bg: #e6d8bf; --card-2-ink: #33291c; /* sand */
|
|
353
|
+
--card-3-bg: #5c6b47; --card-3-ink: #f6f1e6; --card-3-muted: #d3d8c4; /* moss — the brand */
|
|
354
|
+
--card-4-bg: #d3d9c4; --card-4-ink: #2b3322; --card-4-muted: #515c42; /* sage mist */
|
|
355
|
+
--card-5-bg: #dcc2a6; --card-5-ink: #3a2a1c; --card-5-muted: #6b503a; /* clay */
|
|
356
|
+
|
|
357
|
+
--card-border: transparent;
|
|
358
|
+
--card-muted: #736754;
|
|
359
|
+
--card-2-muted: #66573f;
|
|
360
|
+
|
|
361
|
+
--accent: #5c6b47; --on-accent: #f6f1e6;
|
|
362
|
+
--action-bg: #fbf8f2; --action-ink: #2a241c; --action-border: transparent;
|
|
363
|
+
|
|
364
|
+
/* highlights — decoration and atmosphere, a small dose: counts, marks, chart dots, a badge on a tile */
|
|
365
|
+
--highlight-1: #d93a1f; /* maple red */
|
|
366
|
+
--highlight-2: #f5c518; /* bright yellow */
|
|
367
|
+
--highlight-3: #3a9fe0; /* sky */
|
|
368
|
+
--highlight-4: #e0457b; /* fuchsia */
|
|
369
|
+
--dot-a: var(--highlight-1); --dot-b: var(--highlight-3);
|
|
370
|
+
|
|
371
|
+
/* signals from Sweet Salmon #dd9787 — words and edges, always with an icon */
|
|
372
|
+
--pos: #6f8f5a; --neg: #c4694f;
|
|
373
|
+
--signal-error: #b5503b; /* salmon, deepened */
|
|
374
|
+
--signal-warn: #a0721f; /* ochre */
|
|
375
|
+
--signal-ok: #4f7f4a; /* leaf */
|
|
376
|
+
--signal-info: #4d6f96; /* slate */
|
|
377
|
+
}
|
|
378
|
+
/* on the dark moss card the signals turn to their light shades — the same hues, readable on the ground */
|
|
379
|
+
/* where the highlights land — written as the component's own rule, its knob still first, so a project's knob wins (a palette never DECLARES a knob) */
|
|
380
|
+
[data-palette="orchard"] .badge:not(.badge--soft) { background: var(--badge-bg, var(--highlight-1)); color: var(--badge-ink, #fff8f0); }
|
|
381
|
+
[data-palette="orchard"] .tile-badge:not(.tile-badge--plain) { background: var(--tile-badge-bg, var(--highlight-2)); color: var(--tile-badge-ink, #2a241c); }
|
|
382
|
+
[data-palette="orchard"] .calendar__day--mark { background: var(--calendar-day-mark-bg, color-mix(in srgb, var(--highlight-2) 40%, transparent)); }
|
|
383
|
+
/* fields are WHITE boxes on every ground (Lh 2026-09-25) — the words typed in them read dark, even on the moss card */
|
|
384
|
+
[data-palette="orchard"] .field { background: var(--field-bg, #ffffff); color: #2a241c; }
|
|
385
|
+
[data-palette="orchard"] .pin__cell { background: var(--pin-cell-bg, #ffffff); color: #2a241c; }
|
|
386
|
+
/* the vivid ones, tried on the live parts (Lh 2026-09-25): primary = yellow · a user avatar = fuchsia · ring = sky · a switch on = sky · maple only on small dots (the count, dot a); the chosen stack tab stays moss */
|
|
387
|
+
[data-palette="orchard"] .btn--primary { background: var(--btn-primary-bg, var(--highlight-2)); color: var(--btn-primary-ink, #2a241c); }
|
|
388
|
+
[data-palette="orchard"] .avatar:not(.avatar--outline, .avatar--add, .avatar--on) { background: var(--avatar-bg, var(--highlight-4)); color: var(--avatar-ink, #ffffff); }
|
|
389
|
+
[data-palette="orchard"] .ring::before { background: conic-gradient(var(--highlight-3) calc(var(--value) * 1%), var(--ink-tint) 0); }
|
|
390
|
+
[data-palette="orchard"] .toggle:checked { background: var(--highlight-3); }
|
|
391
|
+
[data-palette="orchard"] .toggle:checked::after { background: #ffffff; }
|
|
392
|
+
[data-palette="orchard"] .card--3 { --signal-error: #f4b7a6; --signal-warn: #f1d18a; --signal-ok: #cfe6b8; --signal-info: #bcd0ec; }
|
|
393
|
+
|
|
394
|
+
/* ---- VERS — Lh's own-palette pick (2026-09-25): white surface, champagne paper, sage brand; earth tones for tones 2·4·5 ---- */
|
|
395
|
+
[data-palette="vers"] {
|
|
396
|
+
--surface: #ffffff;
|
|
397
|
+
--on-surface: #1f1b16;
|
|
398
|
+
--on-surface-muted: #6b6358;
|
|
399
|
+
|
|
400
|
+
--card-1-bg: #f6e7cb; --card-1-ink: #1f1b16; /* paper — Champagne */
|
|
401
|
+
--card-2-bg: #e3cfa6; --card-2-ink: #1f1b16; /* sand */
|
|
402
|
+
--card-3-bg: #678d58; --card-3-ink: #ffffff; /* brand — Sage */
|
|
403
|
+
--card-4-bg: #c9d6b0; --card-4-ink: #1f1b16; --card-4-muted: #4a5438; /* lichen */
|
|
404
|
+
--card-5-bg: #d4bf9c; --card-5-ink: #1f1b16; --card-5-muted: #5e4a36; /* wheat — bark was too dark */
|
|
405
|
+
|
|
406
|
+
--card-border: transparent;
|
|
407
|
+
--card-muted: #6b5f4c;
|
|
408
|
+
--card-2-muted: #5c4f3a;
|
|
409
|
+
--card-3-muted: #dfe8d6;
|
|
410
|
+
|
|
411
|
+
--accent: #678d58; --on-accent: #ffffff;
|
|
412
|
+
--action-bg: #f6e7cb; --action-ink: #1f1b16; --action-border: transparent;
|
|
413
|
+
|
|
414
|
+
/* signals from Sweet Salmon #dd9787, deepened to read on white/champagne */
|
|
415
|
+
--pos: #7fa86f; --neg: #dd9787;
|
|
416
|
+
--signal-error: #b5503b; /* salmon */
|
|
417
|
+
--signal-warn: #a5782a; /* ochre */
|
|
418
|
+
--signal-ok: #4f7f4a; /* leaf */
|
|
419
|
+
--signal-info: #4d6f96; /* slate */
|
|
420
|
+
--dot-a: #dd9787; --dot-b: #b08a5a;
|
|
421
|
+
}
|
|
422
|
+
|
|
371
423
|
/* Colored palettes trade wireframe outlines for soft elevation. */
|
|
372
424
|
[data-palette] :is(.card, .band-stack) { box-shadow: var(--shadow-card); }
|
|
373
425
|
/* COLOURED MODE is the attribute, whatever its value: a project with colours of its own (the five
|
|
@@ -390,7 +442,7 @@
|
|
|
390
442
|
the member wants to copy), and inputs are untouched. Native buttons and
|
|
391
443
|
links are matched by element; the rest by the class that makes them one */
|
|
392
444
|
button, [role="button"], [role="tab"], [role="option"], [role="menuitem"], a.btn, a.icon-btn, a.chip, label.chip, .chip--pick,
|
|
393
|
-
.segment__item, .day, .calendar__day, .mood__opt, .pin__cell, .slider, .picker__item, .float-bar__item, .menu__item, .sheet__handle, .
|
|
445
|
+
.segment__item, .day, .calendar__day, .mood__opt, .pin__cell, .slider, .picker__item, .float-bar__item, .menu__item, .sheet__handle, .track__step, .pager__at {
|
|
394
446
|
user-select: none;
|
|
395
447
|
-webkit-user-select: none;
|
|
396
448
|
-webkit-touch-callout: none;
|
|
@@ -483,7 +535,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
483
535
|
|
|
484
536
|
.t-muted { color: var(--on-surface-muted); }
|
|
485
537
|
.card .t-muted { color: var(--card-muted); } /* muted follows the card's ink, not the surface's */
|
|
486
|
-
.card--3 .t-muted { color: inherit; opacity:
|
|
538
|
+
.card--3 .t-muted { color: inherit; opacity: var(--dim); } /* card-muted is tuned for light cards; dim instead on the dark slot */
|
|
487
539
|
.t-caps { text-transform: uppercase; }
|
|
488
540
|
.grow { flex: 1; min-width: 0; } /* the child that takes the remaining row space */
|
|
489
541
|
/* read, not shown (Lh 2026-09-23): words a screen reader needs — a page's h1 the design leaves out — kept in the page, taking no room.
|
|
@@ -564,6 +616,8 @@ button { font: inherit; cursor: pointer; }
|
|
|
564
616
|
|
|
565
617
|
.card--2 { --card-bg: var(--card-2-bg); --card-ink: var(--card-2-ink); --card-muted: var(--card-2-muted); }
|
|
566
618
|
.card--3 { --card-bg: var(--card-3-bg); --card-ink: var(--card-3-ink); }
|
|
619
|
+
.card--4 { --card-bg: var(--card-4-bg); --card-ink: var(--card-4-ink); --card-muted: var(--card-4-muted); }
|
|
620
|
+
.card--5 { --card-bg: var(--card-5-bg); --card-ink: var(--card-5-ink); --card-muted: var(--card-5-muted); }
|
|
567
621
|
|
|
568
622
|
/* dark/accent slot: accent-toned controls would vanish — the slot re-points
|
|
569
623
|
the accent tokens, so every accent consumer (btn--primary, chip--on,
|
|
@@ -697,8 +751,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
697
751
|
one is there, and the screen's gap), or twice the room below it (the
|
|
698
752
|
bar's reserve) — whichever is less. --_lead is the title bar's height
|
|
699
753
|
only on a screen that HAS one: without a .topbar/.appbar before it the
|
|
700
|
-
block keeps that room (a
|
|
701
|
-
under it, need it on a short phone; Lh, 2026-09-11). */
|
|
754
|
+
block keeps that room (a card and its pager under it needs it on a short phone; Lh, 2026-09-11). */
|
|
702
755
|
--_lead: 0rem;
|
|
703
756
|
max-height: calc(2 * min(var(--screen-centre) - var(--_lead) - var(--screen-gap), 100% - var(--screen-centre) - var(--bar-reserve)));
|
|
704
757
|
overflow-y: auto;
|
|
@@ -709,9 +762,8 @@ button { font: inherit; cursor: pointer; }
|
|
|
709
762
|
|
|
710
763
|
/* ---- centred block: the same place, for one thing to read that is not a
|
|
711
764
|
lone card — an empty state, a card with its quiet second button and the
|
|
712
|
-
pager under it
|
|
713
|
-
edge and keeps the screen's inset as padding,
|
|
714
|
-
overhang and clip at the screen's edges (correct — the fold visual), and
|
|
765
|
+
pager under it. The block runs edge to
|
|
766
|
+
edge and keeps the screen's inset as padding, and
|
|
715
767
|
its children stack at the screen's own rhythm (Lh, 2026-09-11):
|
|
716
768
|
<div class="screen screen--fill"><header class="topbar">…</header>
|
|
717
769
|
<div class="screen__centre"><article class="card">…</article><button class="btn btn--quiet btn--block">…</button></div>
|
|
@@ -784,14 +836,10 @@ button { font: inherit; cursor: pointer; }
|
|
|
784
836
|
animation-timing-function: ease-out;
|
|
785
837
|
mix-blend-mode: normal;
|
|
786
838
|
}
|
|
787
|
-
:root[data-slide="next"]::view-transition-old(centre-card-out) { animation-name: centre-card-out-left; }
|
|
788
|
-
:root[data-slide="next"]::view-transition-new(centre-card-in) { animation-name: centre-card-in-right; }
|
|
789
|
-
:root[data-slide="back"]::view-transition-old(centre-card-out) { animation-name: centre-card-out-right; }
|
|
790
|
-
:root[data-slide="back"]::view-transition-new(centre-card-in) { animation-name: centre-card-in-left; }
|
|
791
|
-
:root[data-slide="next"]::view-transition-old(screen-out) { animation-name: centre-card-out-left; }
|
|
792
|
-
:root[data-slide="next"]::view-transition-new(screen-in) { animation-name: centre-card-in-right; }
|
|
793
|
-
:root[data-slide="back"]::view-transition-old(screen-out) { animation-name: centre-card-out-right; }
|
|
794
|
-
:root[data-slide="back"]::view-transition-new(screen-in) { animation-name: centre-card-in-left; }
|
|
839
|
+
:root[data-slide="next"]::view-transition-old(centre-card-out), :root[data-slide="next"]::view-transition-old(screen-out) { animation-name: centre-card-out-left; }
|
|
840
|
+
:root[data-slide="next"]::view-transition-new(centre-card-in), :root[data-slide="next"]::view-transition-new(screen-in) { animation-name: centre-card-in-right; }
|
|
841
|
+
:root[data-slide="back"]::view-transition-old(centre-card-out), :root[data-slide="back"]::view-transition-old(screen-out) { animation-name: centre-card-out-right; }
|
|
842
|
+
:root[data-slide="back"]::view-transition-new(centre-card-in), :root[data-slide="back"]::view-transition-new(screen-in) { animation-name: centre-card-in-left; }
|
|
795
843
|
@keyframes centre-card-out-left { to { translate: -100% 0; opacity: 0; } }
|
|
796
844
|
@keyframes centre-card-out-right { to { translate: 100% 0; opacity: 0; } }
|
|
797
845
|
@keyframes centre-card-in-right { from { translate: 100% 0; opacity: 0; } }
|
|
@@ -1098,9 +1146,6 @@ button { font: inherit; cursor: pointer; }
|
|
|
1098
1146
|
padding-left: 0;
|
|
1099
1147
|
transition: padding-left 0.35s ease;
|
|
1100
1148
|
}
|
|
1101
|
-
.sheet-stack--tap > .card.is-open > .card__head {
|
|
1102
|
-
padding-left: calc(var(--tap-sm) + var(--sp-3));
|
|
1103
|
-
}
|
|
1104
1149
|
.sheet-stack--tap .sheet-stack__back {
|
|
1105
1150
|
position: absolute;
|
|
1106
1151
|
left: 0;
|
|
@@ -1109,6 +1154,12 @@ button { font: inherit; cursor: pointer; }
|
|
|
1109
1154
|
opacity: 0;
|
|
1110
1155
|
visibility: hidden;
|
|
1111
1156
|
transition: opacity 0.35s ease, visibility 0.35s;
|
|
1157
|
+
/* SMALL (see "the back button, SMALL" below) */
|
|
1158
|
+
width: var(--stack-back-size, calc(var(--tap-base) * 2 / 3));
|
|
1159
|
+
height: var(--stack-back-size, calc(var(--tap-base) * 2 / 3));
|
|
1160
|
+
min-width: 0;
|
|
1161
|
+
min-height: 0;
|
|
1162
|
+
padding: 0;
|
|
1112
1163
|
}
|
|
1113
1164
|
.sheet-stack--tap > .card.is-open .sheet-stack__back {
|
|
1114
1165
|
opacity: 1;
|
|
@@ -1168,13 +1219,6 @@ button { font: inherit; cursor: pointer; }
|
|
|
1168
1219
|
tappable"): a SMALL DISC — its ring kept, 32px instead of 44, the chevron in it at 20 — so the head gives it 32px + a gap
|
|
1169
1220
|
(was 56px). Its tap target stays 44px: an invisible ::after around the disc. ---- */
|
|
1170
1221
|
.sheet-stack--tap > .card.is-open > .card__head { padding-left: var(--stack-back-room, calc(var(--stack-back-size, calc(var(--tap-base) * 2 / 3)) + var(--sp-2))); }
|
|
1171
|
-
.sheet-stack--tap .sheet-stack__back {
|
|
1172
|
-
width: var(--stack-back-size, calc(var(--tap-base) * 2 / 3));
|
|
1173
|
-
height: var(--stack-back-size, calc(var(--tap-base) * 2 / 3));
|
|
1174
|
-
min-width: 0;
|
|
1175
|
-
min-height: 0;
|
|
1176
|
-
padding: 0;
|
|
1177
|
-
}
|
|
1178
1222
|
.sheet-stack--tap .sheet-stack__back > .icon { width: var(--stack-back-icon, calc(var(--tap-base) * 13 / 24)); height: var(--stack-back-icon, calc(var(--tap-base) * 13 / 24)); flex: none; } /* 26: the chevron fills the small disc (Lh 2026-09-23) */
|
|
1179
1223
|
.sheet-stack--tap .sheet-stack__back::after { content: ""; position: absolute; inset: calc((var(--stack-back-size, calc(var(--tap-base) * 2 / 3)) - var(--tap-sm)) / 2); }
|
|
1180
1224
|
|
|
@@ -1568,9 +1612,8 @@ button { font: inherit; cursor: pointer; }
|
|
|
1568
1612
|
bottom of the body, each its title line. Every step has a thin rule on top. A step opens and folds as a 1fr ↔ 0fr grid row, so the pile rises and
|
|
1569
1613
|
falls — no height is written. Nothing fades: done and next read at full ink. */
|
|
1570
1614
|
.sheet__body:has(> .sheet-steps) { display: flex; flex-direction: column; }
|
|
1571
|
-
.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; }
|
|
1615
|
+
.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; }
|
|
1572
1616
|
.sheet-steps__holder { position: absolute; top: 0; left: 0; width: 1rem; height: 1rem; padding: 0; border: 0; opacity: 0; pointer-events: none; font-size: 1rem; } /* 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 */
|
|
1573
|
-
.sheet-steps { position: relative; }
|
|
1574
1617
|
.sheet-steps__track { list-style: none; margin: 0; padding: 0; flex: 1; display: flex; flex-direction: column; }
|
|
1575
1618
|
|
|
1576
1619
|
.sheet-step {
|
|
@@ -1588,23 +1631,22 @@ button { font: inherit; cursor: pointer; }
|
|
|
1588
1631
|
display: flex; align-items: center; gap: var(--sp-3); min-height: var(--sheet-steps-row-h, calc(var(--tap-base) * 2 / 3)); /* THIN: 32px, a summary line, not a button (Lh 2026-09-25) — the tap stays 44, see __go */
|
|
1589
1632
|
padding-inline: var(--sheet-step-bar-pad-x, var(--sp-3)); border-radius: var(--sheet-step-bar-radius, var(--r-chip));
|
|
1590
1633
|
background: var(--sheet-step-bar-bg, var(--ink-tint)); color: var(--sheet-step-bar-ink, inherit);
|
|
1591
|
-
border-top: var(--sheet-step-border-w,
|
|
1634
|
+
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 */
|
|
1592
1635
|
}
|
|
1593
|
-
.sheet-step__summary { color: inherit; opacity: 0.8; }
|
|
1594
1636
|
.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; }
|
|
1595
1637
|
.sheet-step__num { /* `numbered`: the step's number in a disc BEFORE its title (Lh 2026-09-25) — a white disc on the bar, the number in the ink */
|
|
1596
1638
|
flex: none; display: grid; place-items: center; inline-size: var(--sheet-step-num-size, calc(var(--tap-base) / 2)); block-size: var(--sheet-step-num-size, calc(var(--tap-base) / 2));
|
|
1597
1639
|
border-radius: 50%; font: var(--sheet-step-num-font, var(--type-caption)); font-variant-numeric: tabular-nums;
|
|
1598
1640
|
background: var(--sheet-step-num-bg, var(--card-bg)); color: var(--sheet-step-num-ink, inherit);
|
|
1599
1641
|
}
|
|
1600
|
-
.sheet-step__summary { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1642
|
+
.sheet-step__summary { color: inherit; opacity: 0.8; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1601
1643
|
.sheet-step__check { margin-inline-start: auto; }
|
|
1602
1644
|
.sheet-step__body { min-height: 0; overflow: clip; overflow-clip-margin: var(--sp-1); }
|
|
1603
1645
|
.sheet-step__inner { display: grid; gap: var(--card-gap); padding-block: var(--card-gap); }
|
|
1604
1646
|
.sheet-step__inner > * { min-width: 0; }
|
|
1605
1647
|
.sheet-step__inner > .link { justify-self: center; } /* a link of its own row in a step (skip, "change number", "set PIN again"): centred under the step, as the skip (Lh 2026-09-25) */
|
|
1606
1648
|
.sheet-step:not(.sheet-step--now) > .sheet-step__body { visibility: hidden; transition: visibility 0s linear var(--motion-sheet); }
|
|
1607
|
-
.sheet-step__go { position: absolute; inset: min(
|
|
1649
|
+
.sheet-step__go { position: absolute; inset: min(0rem, (var(--sheet-steps-row-h, calc(var(--tap-base) * 2 / 3)) - var(--tap-sm)) / 2) 0 auto; min-height: max(100%, var(--tap-sm)); /* a thin bar still takes a 44px tap */ margin: 0; padding: 0; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
|
|
1608
1650
|
/* the last step's finish, when the app gives one: under the steps */
|
|
1609
1651
|
.sheet-steps__finish { display: grid; padding-top: var(--card-gap); }
|
|
1610
1652
|
@media (prefers-reduced-motion: reduce) { .sheet-step { transition: none; } }
|
|
@@ -1704,8 +1746,6 @@ button { font: inherit; cursor: pointer; }
|
|
|
1704
1746
|
.step:has(> .sheet--peek) > :is(.page, .pages) { padding-bottom: var(--sheet-peek); }
|
|
1705
1747
|
.step > :is(.page, .pages) {
|
|
1706
1748
|
flex: 0 1 auto;
|
|
1707
|
-
}
|
|
1708
|
-
.step > :is(.page, .pages) {
|
|
1709
1749
|
min-height: 0;
|
|
1710
1750
|
margin: var(--_lead, 0) var(--screen-pad) 0; /* the screen's gap, moved in here from above the step; the inset, taken back from the bleed */
|
|
1711
1751
|
overflow-y: auto;
|
|
@@ -1717,12 +1757,12 @@ button { font: inherit; cursor: pointer; }
|
|
|
1717
1757
|
padding above AND below — so the words begin near the middle and, when a big text size runs them long, scroll up clear.
|
|
1718
1758
|
The walk shows no scrollbar. */
|
|
1719
1759
|
.step > .pages { margin: 0; scrollbar-width: none; touch-action: pan-y; } /* pan-y: the walk scrolls itself up and down; a sideways swipe is the Walkthrough's (it turns the page) */ /* the scrolling box is the whole content: from the step's top edge, edge to edge — no margin (Lh 2026-09-23) */
|
|
1720
|
-
.step > .pages > .page { padding-inline: var(--screen-pad); } /* the words keep the inset INSIDE it */
|
|
1721
|
-
.step > .pages > .page { margin-top: var(--_lead, 0rem); } /* the lead is each PAGE's margin (15% with no top, the screen's gap under a bar): the words start there and scroll up to the box's edge */
|
|
1722
|
-
.step > .pages::-webkit-scrollbar { display: none; }
|
|
1723
1760
|
.step > .pages > .page {
|
|
1761
|
+
padding-inline: var(--screen-pad); /* the words keep the inset INSIDE it */
|
|
1762
|
+
margin-top: var(--_lead, 0rem); /* the lead is each PAGE's margin (15% with no top, the screen's gap under a bar): the words start there and scroll up to the box's edge */
|
|
1724
1763
|
padding-bottom: var(--bottom-h, 0rem); /* exactly the bottom layer (measured by Screen): a page scrolls ONLY when the layer would cover its words, and then just far enough to clear them — at 100% nothing scrolls (Lh 2026-09-23) */
|
|
1725
1764
|
}
|
|
1765
|
+
.step > .pages::-webkit-scrollbar { display: none; }
|
|
1726
1766
|
|
|
1727
1767
|
/* ============================================================
|
|
1728
1768
|
TOP + CONTENT in one flex column; BOTTOM is a LAYER over them (Lh 2026-09-23, second call — replaces "the bar is a row"):
|
|
@@ -1893,7 +1933,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
1893
1933
|
.route__point--end .route__code::after { content: none; }
|
|
1894
1934
|
.route__time { font: var(--route-time-font, var(--type-body)); font-variant-numeric: tabular-nums; }
|
|
1895
1935
|
.route__place { font: var(--route-place-font, var(--type-caption)); color: var(--route-place-ink, var(--card-muted)); }
|
|
1896
|
-
.card--3 .route__place { color: inherit; opacity:
|
|
1936
|
+
.card--3 .route__place { color: inherit; opacity: var(--dim); }
|
|
1897
1937
|
|
|
1898
1938
|
.route__via { grid-column: 2; grid-row: 2; align-self: center; display: flex; align-items: center; opacity: 0.65; font-size: var(--route-via-font-size, var(--fs-body)); }
|
|
1899
1939
|
|
|
@@ -1907,7 +1947,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
1907
1947
|
background: var(--tile-badge-bg, var(--card-3-bg));
|
|
1908
1948
|
color: var(--tile-badge-ink, var(--card-3-ink));
|
|
1909
1949
|
}
|
|
1910
|
-
.tile-badge__label { font: var(--tile-badge-label-font, var(--type-caption)); opacity:
|
|
1950
|
+
.tile-badge__label { font: var(--tile-badge-label-font, var(--type-caption)); opacity: var(--dim); }
|
|
1911
1951
|
.tile-badge__value { font: 800 var(--fs-lg)/1.1 var(--font-display); font-variant-numeric: tabular-nums; }
|
|
1912
1952
|
|
|
1913
1953
|
/* plain: no fill — a date box beside a title (Jun / 18) */
|
|
@@ -1925,7 +1965,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
1925
1965
|
font: var(--note-row-font, var(--type-caption));
|
|
1926
1966
|
color: var(--note-row-ink, var(--card-muted));
|
|
1927
1967
|
}
|
|
1928
|
-
.card--3 .note-row { color: inherit; opacity:
|
|
1968
|
+
.card--3 .note-row { color: inherit; opacity: var(--dim); }
|
|
1929
1969
|
|
|
1930
1970
|
/* ---- css/actions.css — topbar, chips, buttons, CTA pack ---- */
|
|
1931
1971
|
/* ============================================================
|
|
@@ -2002,7 +2042,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2002
2042
|
border-radius: var(--appbar-who-radius, var(--r-chip));
|
|
2003
2043
|
-webkit-tap-highlight-color: transparent;
|
|
2004
2044
|
}
|
|
2005
|
-
.appbar__who:focus-visible { outline: var(--focus); outline-offset:
|
|
2045
|
+
.appbar__who:focus-visible { outline: var(--focus); outline-offset: var(--sp-1); }
|
|
2006
2046
|
.appbar__title, .appbar__sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.35; } /* clipped lines: room for Thai marks */
|
|
2007
2047
|
.appbar__title { font: var(--type-label); }
|
|
2008
2048
|
.appbar__sub { font: var(--type-caption); color: var(--on-surface-muted); }
|
|
@@ -2264,6 +2304,29 @@ button { font: inherit; cursor: pointer; }
|
|
|
2264
2304
|
.action-note__words { display: block; } /* ONE run of words: an icon inside sits in the line, the spaces around it kept */
|
|
2265
2305
|
.action-note__words > .icon { display: inline-block; vertical-align: -0.2em; width: 1.25em; height: 1.25em; margin-inline: 0.15em; color: var(--action-note-icon-ink, inherit); } /* a project may colour the icon apart from the words — e.g. the system blue of the control it points at (Lh 2026-09-24) */
|
|
2266
2306
|
|
|
2307
|
+
/* PRESS (Lh 2026-09-25): every CONTROL answers a tap — it gives under the finger and springs back, its choice fill fades in;
|
|
2308
|
+
INFORMATION never does (no pointer, no press). One list, zero specificity: a component's own rule always wins. */
|
|
2309
|
+
:where(.btn, .icon-btn, .fab, .link, a.chip, button.chip, .chip--pick, a.tile, button.tile, .tile--pick, .day, .segment__item,
|
|
2310
|
+
.calendar__day, .float-bar__item, .avatar-pick__item, .add-row, .picker__item, .sheet-stack__back, .dropdown__btn, .appbar__who, .menu__item) {
|
|
2311
|
+
cursor: pointer;
|
|
2312
|
+
touch-action: manipulation;
|
|
2313
|
+
transition: scale var(--motion-press) ease-out;
|
|
2314
|
+
}
|
|
2315
|
+
/* a CHOICE's fill fades in as it is picked (a button's colour never changes on a tap, so it does not fade) */
|
|
2316
|
+
:where(.chip--pick, .tile--pick, .day, .segment__item, .calendar__day, .float-bar__item, .menu__item) {
|
|
2317
|
+
transition: scale var(--motion-press) ease-out, background-color var(--motion-press) ease-out, color var(--motion-press) ease-out, border-color var(--motion-press) ease-out;
|
|
2318
|
+
}
|
|
2319
|
+
:where(.btn, .icon-btn, .fab, .link, a.chip, button.chip, .chip--pick, a.tile, button.tile, .tile--pick, .day, .segment__item,
|
|
2320
|
+
.calendar__day, .float-bar__item, .avatar-pick__item, .add-row, .picker__item, .sheet-stack__back, .dropdown__btn, .appbar__who, .menu__item):active:not(:disabled, [aria-disabled="true"]) {
|
|
2321
|
+
scale: var(--press-scale);
|
|
2322
|
+
}
|
|
2323
|
+
:where(.btn, .icon-btn, .fab, .link, a.chip, button.chip, a.tile, button.tile, .day, .segment__item, .calendar__day, .float-bar__item,
|
|
2324
|
+
.avatar-pick__item, .add-row, .picker__item, .sheet-stack__back, .dropdown__btn):focus-visible { outline: var(--focus); outline-offset: var(--sp-1); }
|
|
2325
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2326
|
+
:where(.btn, .icon-btn, .fab, .link, a.chip, button.chip, .chip--pick, a.tile, button.tile, .tile--pick, .day, .segment__item,
|
|
2327
|
+
.calendar__day, .float-bar__item, .avatar-pick__item, .add-row, .picker__item, .sheet-stack__back, .dropdown__btn, .appbar__who, .menu__item):active { scale: none; }
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2267
2330
|
/* ---- css/numbers.css — ring, track, band, dot grid, picker, badge, bars ---- */
|
|
2268
2331
|
/* ============================================================
|
|
2269
2332
|
cardds/numbers.css — big numbers inside cards:
|
|
@@ -2300,7 +2363,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2300
2363
|
}
|
|
2301
2364
|
.ring__value { font: var(--ring-value-font, var(--type-stat)); letter-spacing: var(--track-display); }
|
|
2302
2365
|
.ring__label { font: var(--ring-label-font, var(--type-caption)); color: var(--ring-label-ink, var(--card-muted)); }
|
|
2303
|
-
.card--3 .ring__label { color: inherit; opacity:
|
|
2366
|
+
.card--3 .ring__label { color: inherit; opacity: var(--dim); }
|
|
2304
2367
|
.ring--sm { --_size: var(--avatar-xl); --_w: var(--sp-3); }
|
|
2305
2368
|
.ring--sm .ring__value { font: 800 var(--fs-2xl)/1 var(--font-display); }
|
|
2306
2369
|
.ring--xs { --_size: var(--tap-sm); --_w: var(--dot-xs); } /* inline counter (step 3 of 5) */
|
|
@@ -2353,6 +2416,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2353
2416
|
background: color-mix(in srgb, var(--_ink) 30%, transparent);
|
|
2354
2417
|
color: var(--_ink);
|
|
2355
2418
|
}
|
|
2419
|
+
.track__step > .track__dot { display: grid; place-items: center; padding: 0; font: var(--track-dot-font, var(--type-title)); font-variant-numeric: tabular-nums; } /* a number in the round (TrackStep num) */
|
|
2356
2420
|
.track__step.is-done > .icon,
|
|
2357
2421
|
.track__step.is-done > .track__dot { background: var(--accent); color: var(--on-accent); }
|
|
2358
2422
|
|
|
@@ -2374,7 +2438,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2374
2438
|
}
|
|
2375
2439
|
.band__num small { font-size: 0.5em; font-weight: 700; margin-right: 0.1em; } /* unit or % */
|
|
2376
2440
|
.band__foot { grid-area: foot; font: var(--band-foot-font, var(--type-caption)); color: var(--band-foot-ink, var(--card-muted)); }
|
|
2377
|
-
.card--3 .band__foot { color: inherit; opacity:
|
|
2441
|
+
.card--3 .band__foot { color: inherit; opacity: var(--dim); }
|
|
2378
2442
|
/* band stack: ONE card boundary; bands are frameless inside it, a hairline
|
|
2379
2443
|
between each. Bands may still carry slot tints (card--2 / card--3). */
|
|
2380
2444
|
.band-stack {
|
|
@@ -2473,7 +2537,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2473
2537
|
}
|
|
2474
2538
|
.picker::after { left: auto; right: calc(100% / 3); }
|
|
2475
2539
|
.picker__unit { font: var(--picker-unit-font, var(--type-caption)); color: var(--picker-unit-ink, var(--card-muted)); }
|
|
2476
|
-
.card--3 .picker__unit { color: inherit; opacity:
|
|
2540
|
+
.card--3 .picker__unit { color: inherit; opacity: var(--dim); }
|
|
2477
2541
|
/* the scrolled-to item lights up by position — no JS */
|
|
2478
2542
|
@supports (animation-timeline: view(x)) {
|
|
2479
2543
|
.picker__item { opacity: 0.3; animation: picker-focus linear both; animation-timeline: view(x); }
|
|
@@ -2574,7 +2638,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2574
2638
|
.avatar--xl { --_size: var(--avatar-xl); } /* sheet head icon ring */
|
|
2575
2639
|
/* outline avatar: no fill, an edge — icons in a ring, "add" slots */
|
|
2576
2640
|
.avatar--outline { background: transparent; color: inherit; border: var(--border-w) solid var(--avatar-outline-border, var(--outline)); }
|
|
2577
|
-
.avatar--add { background: transparent; color: inherit; border: var(--border-w) dashed var(--avatar-add-border, var(--outline));
|
|
2641
|
+
.avatar--add { background: transparent; color: inherit; border: var(--border-w) dashed var(--avatar-add-border, var(--outline)); }
|
|
2578
2642
|
/* accent avatar: the "+7" tail, the selected person */
|
|
2579
2643
|
.avatar--on { background: var(--avatar-on-bg, var(--accent)); color: var(--avatar-on-ink, var(--on-accent)); }
|
|
2580
2644
|
/* halo: faint concentric rings behind a hero avatar (decorative) */
|
|
@@ -2619,7 +2683,8 @@ button { font: inherit; cursor: pointer; }
|
|
|
2619
2683
|
}
|
|
2620
2684
|
.avatar-pick__name { font: var(--avatar-pick-name-font, var(--type-label)); font-size: var(--avatar-pick-name-font-size, var(--fs-sm)); }
|
|
2621
2685
|
.avatar-pick__role { font: var(--avatar-pick-role-font, var(--type-caption)); color: var(--avatar-pick-role-ink, var(--card-muted)); margin-top: calc(-1 * var(--sp-1)); }
|
|
2622
|
-
.
|
|
2686
|
+
.avatar-pick__item[aria-pressed="true"] > .avatar { background: var(--avatar-pick-on-bg, var(--accent)); color: var(--avatar-pick-on-ink, var(--on-accent)); border-color: transparent; } /* the picked person */
|
|
2687
|
+
.card--3 .avatar-pick__role { color: inherit; opacity: var(--dim); }
|
|
2623
2688
|
|
|
2624
2689
|
/* ---- css/choice.css — check, toggle, toggle chip, chip grid, days, calendar, mood, pin, composer ---- */
|
|
2625
2690
|
/* ============================================================
|
|
@@ -2763,7 +2828,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2763
2828
|
.calendar__head { display: flex; align-items: center; justify-content: space-between; gap: var(--calendar-head-gap, var(--sp-2)); }
|
|
2764
2829
|
.calendar__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--calendar-grid-gap, var(--sp-1)); justify-items: center; }
|
|
2765
2830
|
.calendar__wd { font: var(--calendar-wd-font, var(--type-caption)); color: var(--calendar-wd-ink, var(--card-muted)); padding-block: var(--calendar-wd-pad-y, var(--sp-2)); }
|
|
2766
|
-
.card--3 .calendar__wd { color: inherit; opacity:
|
|
2831
|
+
.card--3 .calendar__wd { color: inherit; opacity: var(--dim); }
|
|
2767
2832
|
.calendar__day {
|
|
2768
2833
|
width: 100%;
|
|
2769
2834
|
max-width: var(--calendar-day-max-w, var(--tap));
|
|
@@ -2866,7 +2931,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
2866
2931
|
.composer__input::placeholder { color: inherit; opacity: 0.4; }
|
|
2867
2932
|
.composer__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--composer-bar-gap, var(--sp-3)); }
|
|
2868
2933
|
.composer__hint { font: var(--composer-hint-font, var(--type-caption)); color: var(--composer-hint-ink, var(--card-muted)); }
|
|
2869
|
-
.card--3 .composer__hint { color: inherit; opacity:
|
|
2934
|
+
.card--3 .composer__hint { color: inherit; opacity: var(--dim); }
|
|
2870
2935
|
|
|
2871
2936
|
/* ---- slider: one value along a track, a thumb-size knob ----
|
|
2872
2937
|
<label class="slider"><span class="slider__label">ขนาดตัวหนังสือ</span><input class="slider__range" type="range" min="100" max="160" step="15" aria-label="ขนาดตัวหนังสือ"></label>
|
|
@@ -3209,7 +3274,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
3209
3274
|
.quote__text { margin: 0; font: var(--quote-text-font, var(--type-h1)); letter-spacing: var(--track-h1); text-wrap: balance; }
|
|
3210
3275
|
.quote--sm .quote__text { font: var(--type-h2); letter-spacing: var(--track-h2); }
|
|
3211
3276
|
.quote__by { font: var(--quote-by-font, var(--type-caption)); color: var(--quote-by-ink, var(--card-muted)); }
|
|
3212
|
-
.card--3 .quote__by { color: inherit; opacity:
|
|
3277
|
+
.card--3 .quote__by { color: inherit; opacity: var(--dim); }
|
|
3213
3278
|
|
|
3214
3279
|
/* ---- tile grid: big square tiles — icon top, label bottom ----
|
|
3215
3280
|
<div class="tile-grid"><button class="tile"><svg class="icon"/><span class="tile__label">Light</span></button>
|
|
@@ -3235,11 +3300,10 @@ button { font: inherit; cursor: pointer; }
|
|
|
3235
3300
|
font: inherit;
|
|
3236
3301
|
text-align: left;
|
|
3237
3302
|
position: relative;
|
|
3238
|
-
cursor: pointer;
|
|
3239
3303
|
}
|
|
3240
3304
|
.tile__label { font: var(--tile-label-font, var(--type-title)); }
|
|
3241
3305
|
.tile__value { font: var(--tile-value-font, var(--type-h2)); letter-spacing: var(--track-h2); font-variant-numeric: tabular-nums; }
|
|
3242
|
-
.tile__sub { font: var(--tile-sub-font, var(--type-caption)); opacity:
|
|
3306
|
+
.tile__sub { font: var(--tile-sub-font, var(--type-caption)); opacity: var(--dim); }
|
|
3243
3307
|
.tile__text { display: grid; gap: var(--tile-text-gap, var(--sp-0)); }
|
|
3244
3308
|
.tile--on { background: var(--tile-on-bg, var(--accent)); color: var(--tile-on-ink, var(--on-accent)); border-color: transparent; }
|
|
3245
3309
|
.tile--pick > input { appearance: none; position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
|
|
@@ -3247,7 +3311,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
3247
3311
|
.tile--pick:has(:focus-visible) { outline: var(--focus); outline-offset: var(--sp-1); }
|
|
3248
3312
|
.tile--wide { grid-column: 1 / -1; }
|
|
3249
3313
|
/* stat: READ, not pressed — no frame of its own inside a card (a frame says "tap me"): icon · value · words on the card's ground */
|
|
3250
|
-
.tile--stat { border-color: transparent; background: none; padding-inline: 0;
|
|
3314
|
+
.tile--stat { border-color: transparent; background: none; padding-inline: 0; }
|
|
3251
3315
|
.tile--stat { min-height: var(--tile-stat-min-h, var(--avatar-xl)); gap: var(--tile-stat-gap, var(--sp-3)); grid-template-columns: auto 1fr; align-items: center; }
|
|
3252
3316
|
/* upload: dashed, centred plus + label */
|
|
3253
3317
|
.tile--upload {
|
|
@@ -3261,6 +3325,8 @@ button { font: inherit; cursor: pointer; }
|
|
|
3261
3325
|
}
|
|
3262
3326
|
/* tinted tiles: slot colors inside a card (schedule, notes) */
|
|
3263
3327
|
.tile--2 { background: var(--tile-2-bg, var(--card-2-bg)); color: var(--tile-2-ink, var(--card-2-ink)); border-color: transparent; }
|
|
3328
|
+
.tile--4 { background: var(--tile-4-bg, var(--card-4-bg)); color: var(--tile-4-ink, var(--card-4-ink)); border-color: transparent; }
|
|
3329
|
+
.tile--5 { background: var(--tile-5-bg, var(--card-5-bg)); color: var(--tile-5-ink, var(--card-5-ink)); border-color: transparent; }
|
|
3264
3330
|
.tile--3 { background: var(--tile-3-bg, var(--card-3-bg)); color: var(--tile-3-ink, var(--card-3-ink)); border-color: transparent; }
|
|
3265
3331
|
|
|
3266
3332
|
/* ---- fold: a sticky-note corner on any card (decorative) ----
|
|
@@ -3269,7 +3335,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
3269
3335
|
the corner read as a notch with a line through it rather than a lifted flap.
|
|
3270
3336
|
The COLOUR goes transparent rather than the border going to 0, so the box
|
|
3271
3337
|
keeps its geometry and a fold card still measures the same as the cards
|
|
3272
|
-
beside it
|
|
3338
|
+
beside it. */
|
|
3273
3339
|
.card--fold {
|
|
3274
3340
|
border-color: transparent;
|
|
3275
3341
|
border-bottom-right-radius: 0;
|
|
@@ -3446,7 +3512,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
3446
3512
|
/* ============================================================
|
|
3447
3513
|
cardds/layover.css — cards that lay OVER other content:
|
|
3448
3514
|
Modal (ask) · popover menu · expanding banner · float bar ·
|
|
3449
|
-
callout
|
|
3515
|
+
callout. The sheet (peek / half / full / page)
|
|
3450
3516
|
lives in sheet.css; these compose with .sheet-stage.
|
|
3451
3517
|
============================================================ */
|
|
3452
3518
|
|
|
@@ -3517,7 +3583,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
3517
3583
|
--accent: var(--card-3-ink); /* the one solid button inverts on the dark drawer */
|
|
3518
3584
|
--on-accent: var(--card-3-bg);
|
|
3519
3585
|
}
|
|
3520
|
-
.modal__drawer .t-caption { opacity:
|
|
3586
|
+
.modal__drawer .t-caption { opacity: var(--dim); }
|
|
3521
3587
|
.modal__drawer .icon-btn { background: transparent; color: inherit; border-color: var(--ink-rail); }
|
|
3522
3588
|
.modal__drawer .icon-btn--invert { background: var(--accent); color: var(--on-accent); border-color: transparent; width: var(--tap-lg); height: var(--tap-lg); }
|
|
3523
3589
|
@media (prefers-reduced-motion: no-preference) {
|
|
@@ -3589,7 +3655,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
3589
3655
|
cursor: pointer;
|
|
3590
3656
|
}
|
|
3591
3657
|
.menu__item:hover, .menu__item:focus-visible { background: var(--ink-tint); outline: none; }
|
|
3592
|
-
.menu__item[aria-current]
|
|
3658
|
+
.menu__item[aria-current] { background: var(--accent); color: var(--on-accent); }
|
|
3593
3659
|
@supports (anchor-name: --a) {
|
|
3594
3660
|
.menu[popover] {
|
|
3595
3661
|
position-area: block-end span-inline-end;
|
|
@@ -3700,8 +3766,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
3700
3766
|
}
|
|
3701
3767
|
/* aria-current="false" is the correct way to mark the OTHER tabs, so the
|
|
3702
3768
|
bare attribute selector lights every one of them up */
|
|
3703
|
-
.float-bar__item[aria-current]:not([aria-current="false"])
|
|
3704
|
-
.float-bar__item.is-on { background: var(--accent); color: var(--on-accent); opacity: 1; }
|
|
3769
|
+
.float-bar__item[aria-current]:not([aria-current="false"]) { background: var(--accent); color: var(--on-accent); opacity: 1; }
|
|
3705
3770
|
.float-bar > .icon-btn { width: var(--bar-h); height: var(--bar-h); box-shadow: var(--shadow-float); }
|
|
3706
3771
|
|
|
3707
3772
|
/* ---- callout: a small card with a tail — over a map, a media, a mascot ----
|
|
@@ -3735,18 +3800,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
3735
3800
|
border-left: 0;
|
|
3736
3801
|
}
|
|
3737
3802
|
.callout__title { font: var(--callout-title-font, var(--type-title)); }
|
|
3738
|
-
.callout__sub { font: var(--callout-sub-font, var(--type-caption)); opacity:
|
|
3739
|
-
/* ---- deck: swipe cards; the last child is on top ----
|
|
3740
|
-
<div class="deck"><article class="card">…</article><article class="card">…</article><article class="card card--fold">front</article></div>
|
|
3741
|
-
<div class="deck__actions"><button class="icon-btn">×</button><button class="icon-btn icon-btn--invert">✓</button></div> */
|
|
3742
|
-
.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)); }
|
|
3743
|
-
.deck > .card { grid-area: 1 / 1; width: min(100%, 20rem); min-height: 12.5rem; transition: rotate 0.3s ease, translate 0.3s ease; }
|
|
3744
|
-
.deck > .card:nth-last-child(2) { rotate: -4deg; translate: calc(-1 * var(--sp-2)) var(--sp-2); opacity: 0.85; }
|
|
3745
|
-
.deck > .card:nth-last-child(3) { rotate: 5deg; translate: var(--sp-3) var(--sp-4); opacity: 0.6; }
|
|
3746
|
-
.deck > .card:nth-last-child(n + 4) { display: none; }
|
|
3747
|
-
.deck__actions { display: flex; justify-content: center; gap: var(--deck-actions-gap, var(--sp-8)); }
|
|
3748
|
-
.deck__actions > .icon-btn { width: var(--bar-h); height: var(--bar-h); }
|
|
3749
|
-
|
|
3803
|
+
.callout__sub { font: var(--callout-sub-font, var(--type-caption)); opacity: var(--dim); }
|
|
3750
3804
|
/* ---- splash: the app's mark at the human centre while it boots (Lh 2026-09-24) ----
|
|
3751
3805
|
<section class="screen screen--fill splash"><div class="splash__group"><div class="splash__mark">{the app's lottie/img}</div>
|
|
3752
3806
|
<p class="splash__text">…</p></div></section>
|
package/dist/cards/Card.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { type ComponentProps } from 'react';
|
|
2
2
|
export interface CardProps extends ComponentProps<'article'> {
|
|
3
|
-
/** the tone slot: 1 (default, light) · 2 (tinted) · 3 (dark / accent — controls invert automatically) */
|
|
4
|
-
tone?: 1 | 2 | 3;
|
|
3
|
+
/** the tone slot: 1 (default, light) · 2 (tinted) · 3 (dark / accent — controls invert automatically) · 4 · 5 (more colours, from the palette) */
|
|
4
|
+
tone?: 1 | 2 | 3 | 4 | 5;
|
|
5
5
|
/** compact: a small card inside a card or a sheet body (a note, a promo) */
|
|
6
6
|
sm?: boolean;
|
|
7
7
|
/** a list row that is its own card: thumb · body · end, in a CardList */
|
|
8
8
|
row?: boolean;
|
|
9
9
|
/** the image IS the card: a Placeholder or img first, text over a scrim */
|
|
10
10
|
cover?: boolean;
|
|
11
|
-
/** a sticky-note corner, no border (
|
|
11
|
+
/** a sticky-note corner, no border (quotes) */
|
|
12
12
|
fold?: boolean;
|
|
13
13
|
/** one card at the human centre of a `Screen fill` (the introduction screens) */
|
|
14
14
|
centre?: boolean;
|
package/dist/choice/Calendar.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useControlled } from '../state.js';
|
|
3
3
|
import { cx } from '../cx.js';
|
|
4
4
|
import { IconBtn } from '../actions/IconBtn.js';
|
|
5
5
|
/** Calendar — a month grid of 44px round cells: one accent day, optional marks; prev/next in the head. It shows ONE month and knows no dates:
|
|
6
6
|
* the app owns which month (`title`, `days`, `start` + `onPrev` / `onNext`) and which day (`selected` + `onSelect`, or `defaultSelected`). */
|
|
7
7
|
export function Calendar({ title, days = 30, start = 1, selected, defaultSelected, onSelect, onPrev, onNext, prevLabel = 'Previous', nextLabel = 'Next', marks = [], marks2 = [], disabled = [], weekdays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], nav, className, ...rest }) {
|
|
8
|
-
const [
|
|
9
|
-
const
|
|
10
|
-
const pick = (d) => { if (selected === undefined)
|
|
11
|
-
setInner(d); onSelect?.(d); };
|
|
8
|
+
const [day, setOwn] = useControlled(selected, defaultSelected);
|
|
9
|
+
const pick = (d) => { setOwn(d); onSelect?.(d); };
|
|
12
10
|
return (_jsxs("div", { className: cx('calendar', className), ...rest, children: [_jsxs("div", { className: "calendar__head", children: [_jsx("span", { className: "t-title", children: title }), nav ?? (_jsxs("span", { className: "icon-row", children: [_jsx(IconBtn, { sm: true, icon: "chevron-left", label: prevLabel, onClick: onPrev }), _jsx(IconBtn, { sm: true, icon: "chevron-right", label: nextLabel, onClick: onNext })] }))] }), _jsxs("div", { className: "calendar__grid", children: [weekdays.map((d) => _jsx("span", { className: "calendar__wd", children: d }, d)), Array.from({ length: days }, (_, i) => i + 1).map((d) => (_jsx("button", { type: "button", className: cx('calendar__day', marks.includes(d) && 'calendar__day--mark', marks2.includes(d) && 'calendar__day--mark2'), "aria-selected": d === day ? 'true' : undefined, onClick: () => pick(d), disabled: disabled.includes(d), style: d === 1 ? { '--start': start } : undefined, children: d }, d)))] })] }));
|
|
13
11
|
}
|