@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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,49 @@
|
|
|
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.16 — 2026-09-25
|
|
6
|
+
|
|
7
|
+
Refactor + additions. Same props, same markup, same computed style on every story.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- `setTextScale(percent, root?)` — the member's text size as a share of the theme's `--fs-base` (100 = the theme's own). It reads the base from the CSS, so an app no longer copies `1.375rem`. Keeping the choice (localStorage…) stays the app's.
|
|
11
|
+
|
|
12
|
+
- PRESS: every control (Btn, IconBtn, Fab, Link, a/button Chip, ChipPick, Tile as button/link/pick, Day, SegmentItem, Calendar day, FloatBarItem, AvatarPickItem, AddRow, Picker item, StackBack, Dropdown, AppBar brand, MenuItem) gives under the finger (`--press-scale` 0.96, `--motion-press` 0.12s, off under reduced motion) and shows a focus ring; a choice's fill fades in. Zero specificity (`:where`), so a component's own rule wins.
|
|
13
|
+
- `Rows heading` takes an ELEMENT too: `<Rows heading={<Text level="title" as="h3">…</Text>}>` — that h3 is the group's name (role=group, aria-labelledby). Words still give the small label. Drop a hand-written `role="group" aria-label`.
|
|
14
|
+
- Token `--dim` (0.7): the one share secondary words fade to on the dark card, a drawer, a tile's sub line (was 14 hand-typed `opacity: 0.7`). A theme sets it once.
|
|
15
|
+
- `TrackStep num` — the step's number in the round instead of an Icon (the `.track__dot` look existed in CSS with no way in; story Track · Numbered).
|
|
16
|
+
- `AvatarPickItem selected` (aria-pressed; the picked person's avatar fills with the accent).
|
|
17
|
+
|
|
18
|
+
### Removed (breaking for anyone using them)
|
|
19
|
+
- `Deck` and `DeckActions` (the swipe deck), the `.deck*` CSS and the `--deck-*` knobs — Lh 2026-09-26: no use case. Nothing replaces them; a card to pick from = `Card` + its own buttons.
|
|
20
|
+
|
|
21
|
+
### Changed (may touch a screen)
|
|
22
|
+
- `Mood` is controlled like every other control: `value` + `onChange(value)` or `defaultValue`. Before: `value` was only the starting dot and `onChange` got the input event. Move a starting value to `defaultValue`; read the number from `onChange`.
|
|
23
|
+
- INFORMATION never looks tappable: `.tile` (a plain div) and `Avatar add` no longer set `cursor: pointer`.
|
|
24
|
+
- Stories: Segment, DayStrip, FloatBar (buttons), AvatarPick answer a tap; the Chip filter row is `ChipPick`s (plain `Chip on` is a label, not a choice).
|
|
25
|
+
|
|
26
|
+
### Changed (internal)
|
|
27
|
+
- Every controlled/uncontrolled state (`value`+`onChange` or `defaultValue`, and the same for `state`, `open`, `at`, `tab`, `selected`, `flipped`) now runs on one internal hook, `useControlled`, instead of 12 hand copies.
|
|
28
|
+
- Dev warnings (Icon, TopBar, Screen) share one `warnOnce`.
|
|
29
|
+
- CSS: dead selectors removed (`.dropdown__trigger`, `.menu__item.is-on`, `.float-bar__item.is-on`), one overridden stack-head rule dropped, split rules merged. Two raw `0px` in the SheetSteps CSS → `0rem`.
|
|
30
|
+
|
|
31
|
+
## 0.7.15 — 2026-09-25
|
|
32
|
+
|
|
33
|
+
### Removed (breaking for anyone using them)
|
|
34
|
+
- Palettes `shine` and `field`. `data-palette="shine"|"field"` → pick `clay`, `roast`, `hydro`, `orchard` or `vers`.
|
|
35
|
+
The `Palette` type no longer lists them.
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- Palette `vers`: white surface, champagne paper, sage brand, earth tones 2·4·5, signals from salmon.
|
|
39
|
+
- Palette `orchard` (reworked): modern earth (linen · bone · sand · moss · sage mist · clay); each tone's ink is a deep
|
|
40
|
+
shade of its own ground, so lines tint with the ground. Fields and PIN cells are white. Vivid accents: primary `Btn`
|
|
41
|
+
yellow, avatars fuchsia, `Ring` and a `Toggle` that is on in sky, the count badge and dot a in maple. Every one of these
|
|
42
|
+
still yields to its knob (`--btn-primary-bg`, `--avatar-bg`, `--badge-bg`…) set by a project.
|
|
43
|
+
- Tokens `--highlight-1` … `--highlight-4`: four atmosphere colours a palette may set (grey in the wireframe). Nothing
|
|
44
|
+
changes for a project that doesn't set them.
|
|
45
|
+
- Card tones 4 · 5 and signals `--signal-warn` · `--signal-ok` · `--signal-info` (with `--signal-error`).
|
|
46
|
+
- Gallery: a `Palette` page (type group) — every colour role of the palette on now, plus stories `Signals` and `Highlights`.
|
|
47
|
+
|
|
5
48
|
## 0.7.14 — 2026-09-25
|
|
6
49
|
|
|
7
50
|
### Added
|
package/README.md
CHANGED
|
@@ -307,11 +307,9 @@ between at 40% down the screen (see *Anatomy*, "Where the centre is"):
|
|
|
307
307
|
above the centre (2 × (40% − the title bar)): a card taller than that is
|
|
308
308
|
not a centred card — it is a plain scrolling `.screen` (the detail view).
|
|
309
309
|
- **A small group at the same centre** — an empty state; a card with its quiet
|
|
310
|
-
second button and the pager dots under it
|
|
311
|
-
buttons — is `.screen__centre` (React: `Centre`), a block in the fill
|
|
310
|
+
second button and the pager dots under it — is `.screen__centre` (React: `Centre`), a block in the fill
|
|
312
311
|
screen after the topbar. Same placement and cap; it runs edge to edge with
|
|
313
|
-
the inset as padding,
|
|
314
|
-
screen's edges (the fold visual, not a bug), and stacks its children at the
|
|
312
|
+
the inset as padding, and stacks its children at the
|
|
315
313
|
screen's gap. Never hand-lay `top: 40%` on a screen.
|
|
316
314
|
- **The bar is the screen's bottom.** Plain `.action-bar` for one move; with a
|
|
317
315
|
control that belongs to the screen (a slider), `.action-bar--tiers` stacks a
|
|
@@ -588,8 +586,8 @@ Rules:
|
|
|
588
586
|
theme's values are the project's call. The derivations are only starting points;
|
|
589
587
|
any role can be set outright.
|
|
590
588
|
- The member's text-size setting is the same `--fs-base`, written on `<html>`
|
|
591
|
-
|
|
592
|
-
size. (`--text-scale`, which multiplied the root and zoomed the UI too, is gone.)
|
|
589
|
+
at run time by `setTextScale(percent)` (a share of the theme's base; 100 = the
|
|
590
|
+
theme's own): the words grow, the things keep their size. (`--text-scale`, which multiplied the root and zoomed the UI too, is gone.)
|
|
593
591
|
|
|
594
592
|
Try it live: the gallery's nav (`npm run dev`) has a slider per size base, and
|
|
595
593
|
palette `own` shows a colour well per colour base.
|
|
@@ -619,8 +617,8 @@ whole system still resizes from one number: the root font size. `base.css` keeps
|
|
|
619
617
|
default) and steps narrow phones (≤360px) to `93.75%`, which keeps the 25rem
|
|
620
618
|
column, its 48px taps and its type in proportion on 320–360 screens. Only
|
|
621
619
|
`--border-w`, `--rule-w` and the focus ring stay in px, so edges stay crisp.
|
|
622
|
-
An app with its own text-size setting
|
|
623
|
-
base
|
|
620
|
+
An app with its own text-size setting calls `setTextScale(percent)`, which writes
|
|
621
|
+
`--fs-base` on `<html>` from the theme's base (100% = the theme's; 160% = 2.2rem by default): only the type and its holders (the count
|
|
624
622
|
badge, the inline icon) grow; taps, spacing and radii keep their size.
|
|
625
623
|
Components never write a raw length: spacing from `--sp-*`, control sizes from
|
|
626
624
|
`--tap`, `--tap-lg`, `--btn-h`, `--bar-h`, `--header-h`, `--fab`, `--badge`, container
|
package/css/actions.css
CHANGED
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
border-radius: var(--appbar-who-radius, var(--r-chip));
|
|
73
73
|
-webkit-tap-highlight-color: transparent;
|
|
74
74
|
}
|
|
75
|
-
.appbar__who:focus-visible { outline: var(--focus); outline-offset:
|
|
75
|
+
.appbar__who:focus-visible { outline: var(--focus); outline-offset: var(--sp-1); }
|
|
76
76
|
.appbar__title, .appbar__sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.35; } /* clipped lines: room for Thai marks */
|
|
77
77
|
.appbar__title { font: var(--type-label); }
|
|
78
78
|
.appbar__sub { font: var(--type-caption); color: var(--on-surface-muted); }
|
|
@@ -333,3 +333,26 @@
|
|
|
333
333
|
.card .action-note { color: var(--action-note-ink, var(--card-muted)); }
|
|
334
334
|
.action-note__words { display: block; } /* ONE run of words: an icon inside sits in the line, the spaces around it kept */
|
|
335
335
|
.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) */
|
|
336
|
+
|
|
337
|
+
/* PRESS (Lh 2026-09-25): every CONTROL answers a tap — it gives under the finger and springs back, its choice fill fades in;
|
|
338
|
+
INFORMATION never does (no pointer, no press). One list, zero specificity: a component's own rule always wins. */
|
|
339
|
+
:where(.btn, .icon-btn, .fab, .link, a.chip, button.chip, .chip--pick, a.tile, button.tile, .tile--pick, .day, .segment__item,
|
|
340
|
+
.calendar__day, .float-bar__item, .avatar-pick__item, .add-row, .picker__item, .sheet-stack__back, .dropdown__btn, .appbar__who, .menu__item) {
|
|
341
|
+
cursor: pointer;
|
|
342
|
+
touch-action: manipulation;
|
|
343
|
+
transition: scale var(--motion-press) ease-out;
|
|
344
|
+
}
|
|
345
|
+
/* a CHOICE's fill fades in as it is picked (a button's colour never changes on a tap, so it does not fade) */
|
|
346
|
+
:where(.chip--pick, .tile--pick, .day, .segment__item, .calendar__day, .float-bar__item, .menu__item) {
|
|
347
|
+
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;
|
|
348
|
+
}
|
|
349
|
+
:where(.btn, .icon-btn, .fab, .link, a.chip, button.chip, .chip--pick, a.tile, button.tile, .tile--pick, .day, .segment__item,
|
|
350
|
+
.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"]) {
|
|
351
|
+
scale: var(--press-scale);
|
|
352
|
+
}
|
|
353
|
+
:where(.btn, .icon-btn, .fab, .link, a.chip, button.chip, a.tile, button.tile, .day, .segment__item, .calendar__day, .float-bar__item,
|
|
354
|
+
.avatar-pick__item, .add-row, .picker__item, .sheet-stack__back, .dropdown__btn):focus-visible { outline: var(--focus); outline-offset: var(--sp-1); }
|
|
355
|
+
@media (prefers-reduced-motion: reduce) {
|
|
356
|
+
:where(.btn, .icon-btn, .fab, .link, a.chip, button.chip, .chip--pick, a.tile, button.tile, .tile--pick, .day, .segment__item,
|
|
357
|
+
.calendar__day, .float-bar__item, .avatar-pick__item, .add-row, .picker__item, .sheet-stack__back, .dropdown__btn, .appbar__who, .menu__item):active { scale: none; }
|
|
358
|
+
}
|
package/css/base.css
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
the member wants to copy), and inputs are untouched. Native buttons and
|
|
10
10
|
links are matched by element; the rest by the class that makes them one */
|
|
11
11
|
button, [role="button"], [role="tab"], [role="option"], [role="menuitem"], a.btn, a.icon-btn, a.chip, label.chip, .chip--pick,
|
|
12
|
-
.segment__item, .day, .calendar__day, .mood__opt, .pin__cell, .slider, .picker__item, .float-bar__item, .menu__item, .sheet__handle, .
|
|
12
|
+
.segment__item, .day, .calendar__day, .mood__opt, .pin__cell, .slider, .picker__item, .float-bar__item, .menu__item, .sheet__handle, .track__step, .pager__at {
|
|
13
13
|
user-select: none;
|
|
14
14
|
-webkit-user-select: none;
|
|
15
15
|
-webkit-touch-callout: none;
|
|
@@ -102,7 +102,7 @@ button { font: inherit; cursor: pointer; }
|
|
|
102
102
|
|
|
103
103
|
.t-muted { color: var(--on-surface-muted); }
|
|
104
104
|
.card .t-muted { color: var(--card-muted); } /* muted follows the card's ink, not the surface's */
|
|
105
|
-
.card--3 .t-muted { color: inherit; opacity:
|
|
105
|
+
.card--3 .t-muted { color: inherit; opacity: var(--dim); } /* card-muted is tuned for light cards; dim instead on the dark slot */
|
|
106
106
|
.t-caps { text-transform: uppercase; }
|
|
107
107
|
.grow { flex: 1; min-width: 0; } /* the child that takes the remaining row space */
|
|
108
108
|
/* 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.
|
package/css/card.css
CHANGED
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
|
|
27
27
|
.card--2 { --card-bg: var(--card-2-bg); --card-ink: var(--card-2-ink); --card-muted: var(--card-2-muted); }
|
|
28
28
|
.card--3 { --card-bg: var(--card-3-bg); --card-ink: var(--card-3-ink); }
|
|
29
|
+
.card--4 { --card-bg: var(--card-4-bg); --card-ink: var(--card-4-ink); --card-muted: var(--card-4-muted); }
|
|
30
|
+
.card--5 { --card-bg: var(--card-5-bg); --card-ink: var(--card-5-ink); --card-muted: var(--card-5-muted); }
|
|
29
31
|
|
|
30
32
|
/* dark/accent slot: accent-toned controls would vanish — the slot re-points
|
|
31
33
|
the accent tokens, so every accent consumer (btn--primary, chip--on,
|
|
@@ -159,8 +161,7 @@
|
|
|
159
161
|
one is there, and the screen's gap), or twice the room below it (the
|
|
160
162
|
bar's reserve) — whichever is less. --_lead is the title bar's height
|
|
161
163
|
only on a screen that HAS one: without a .topbar/.appbar before it the
|
|
162
|
-
block keeps that room (a
|
|
163
|
-
under it, need it on a short phone; Lh, 2026-09-11). */
|
|
164
|
+
block keeps that room (a card and its pager under it needs it on a short phone; Lh, 2026-09-11). */
|
|
164
165
|
--_lead: 0rem;
|
|
165
166
|
max-height: calc(2 * min(var(--screen-centre) - var(--_lead) - var(--screen-gap), 100% - var(--screen-centre) - var(--bar-reserve)));
|
|
166
167
|
overflow-y: auto;
|
|
@@ -171,9 +172,8 @@
|
|
|
171
172
|
|
|
172
173
|
/* ---- centred block: the same place, for one thing to read that is not a
|
|
173
174
|
lone card — an empty state, a card with its quiet second button and the
|
|
174
|
-
pager under it
|
|
175
|
-
edge and keeps the screen's inset as padding,
|
|
176
|
-
overhang and clip at the screen's edges (correct — the fold visual), and
|
|
175
|
+
pager under it. The block runs edge to
|
|
176
|
+
edge and keeps the screen's inset as padding, and
|
|
177
177
|
its children stack at the screen's own rhythm (Lh, 2026-09-11):
|
|
178
178
|
<div class="screen screen--fill"><header class="topbar">…</header>
|
|
179
179
|
<div class="screen__centre"><article class="card">…</article><button class="btn btn--quiet btn--block">…</button></div>
|
|
@@ -246,14 +246,10 @@
|
|
|
246
246
|
animation-timing-function: ease-out;
|
|
247
247
|
mix-blend-mode: normal;
|
|
248
248
|
}
|
|
249
|
-
:root[data-slide="next"]::view-transition-old(centre-card-out) { animation-name: centre-card-out-left; }
|
|
250
|
-
:root[data-slide="next"]::view-transition-new(centre-card-in) { animation-name: centre-card-in-right; }
|
|
251
|
-
:root[data-slide="back"]::view-transition-old(centre-card-out) { animation-name: centre-card-out-right; }
|
|
252
|
-
:root[data-slide="back"]::view-transition-new(centre-card-in) { animation-name: centre-card-in-left; }
|
|
253
|
-
:root[data-slide="next"]::view-transition-old(screen-out) { animation-name: centre-card-out-left; }
|
|
254
|
-
:root[data-slide="next"]::view-transition-new(screen-in) { animation-name: centre-card-in-right; }
|
|
255
|
-
:root[data-slide="back"]::view-transition-old(screen-out) { animation-name: centre-card-out-right; }
|
|
256
|
-
:root[data-slide="back"]::view-transition-new(screen-in) { animation-name: centre-card-in-left; }
|
|
249
|
+
: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; }
|
|
250
|
+
: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; }
|
|
251
|
+
: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; }
|
|
252
|
+
: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; }
|
|
257
253
|
@keyframes centre-card-out-left { to { translate: -100% 0; opacity: 0; } }
|
|
258
254
|
@keyframes centre-card-out-right { to { translate: 100% 0; opacity: 0; } }
|
|
259
255
|
@keyframes centre-card-in-right { from { translate: 100% 0; opacity: 0; } }
|
package/css/choice.css
CHANGED
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
.calendar__head { display: flex; align-items: center; justify-content: space-between; gap: var(--calendar-head-gap, var(--sp-2)); }
|
|
140
140
|
.calendar__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--calendar-grid-gap, var(--sp-1)); justify-items: center; }
|
|
141
141
|
.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)); }
|
|
142
|
-
.card--3 .calendar__wd { color: inherit; opacity:
|
|
142
|
+
.card--3 .calendar__wd { color: inherit; opacity: var(--dim); }
|
|
143
143
|
.calendar__day {
|
|
144
144
|
width: 100%;
|
|
145
145
|
max-width: var(--calendar-day-max-w, var(--tap));
|
|
@@ -242,7 +242,7 @@
|
|
|
242
242
|
.composer__input::placeholder { color: inherit; opacity: 0.4; }
|
|
243
243
|
.composer__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--composer-bar-gap, var(--sp-3)); }
|
|
244
244
|
.composer__hint { font: var(--composer-hint-font, var(--type-caption)); color: var(--composer-hint-ink, var(--card-muted)); }
|
|
245
|
-
.card--3 .composer__hint { color: inherit; opacity:
|
|
245
|
+
.card--3 .composer__hint { color: inherit; opacity: var(--dim); }
|
|
246
246
|
|
|
247
247
|
/* ---- slider: one value along a track, a thumb-size knob ----
|
|
248
248
|
<label class="slider"><span class="slider__label">ขนาดตัวหนังสือ</span><input class="slider__range" type="range" min="100" max="160" step="15" aria-label="ขนาดตัวหนังสือ"></label>
|
package/css/journey.css
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
.route__point--end .route__code::after { content: none; }
|
|
27
27
|
.route__time { font: var(--route-time-font, var(--type-body)); font-variant-numeric: tabular-nums; }
|
|
28
28
|
.route__place { font: var(--route-place-font, var(--type-caption)); color: var(--route-place-ink, var(--card-muted)); }
|
|
29
|
-
.card--3 .route__place { color: inherit; opacity:
|
|
29
|
+
.card--3 .route__place { color: inherit; opacity: var(--dim); }
|
|
30
30
|
|
|
31
31
|
.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)); }
|
|
32
32
|
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
background: var(--tile-badge-bg, var(--card-3-bg));
|
|
41
41
|
color: var(--tile-badge-ink, var(--card-3-ink));
|
|
42
42
|
}
|
|
43
|
-
.tile-badge__label { font: var(--tile-badge-label-font, var(--type-caption)); opacity:
|
|
43
|
+
.tile-badge__label { font: var(--tile-badge-label-font, var(--type-caption)); opacity: var(--dim); }
|
|
44
44
|
.tile-badge__value { font: 800 var(--fs-lg)/1.1 var(--font-display); font-variant-numeric: tabular-nums; }
|
|
45
45
|
|
|
46
46
|
/* plain: no fill — a date box beside a title (Jun / 18) */
|
|
@@ -58,4 +58,4 @@
|
|
|
58
58
|
font: var(--note-row-font, var(--type-caption));
|
|
59
59
|
color: var(--note-row-ink, var(--card-muted));
|
|
60
60
|
}
|
|
61
|
-
.card--3 .note-row { color: inherit; opacity:
|
|
61
|
+
.card--3 .note-row { color: inherit; opacity: var(--dim); }
|
package/css/layover.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* ============================================================
|
|
2
2
|
cardds/layover.css — cards that lay OVER other content:
|
|
3
3
|
Modal (ask) · popover menu · expanding banner · float bar ·
|
|
4
|
-
callout
|
|
4
|
+
callout. The sheet (peek / half / full / page)
|
|
5
5
|
lives in sheet.css; these compose with .sheet-stage.
|
|
6
6
|
============================================================ */
|
|
7
7
|
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
--accent: var(--card-3-ink); /* the one solid button inverts on the dark drawer */
|
|
73
73
|
--on-accent: var(--card-3-bg);
|
|
74
74
|
}
|
|
75
|
-
.modal__drawer .t-caption { opacity:
|
|
75
|
+
.modal__drawer .t-caption { opacity: var(--dim); }
|
|
76
76
|
.modal__drawer .icon-btn { background: transparent; color: inherit; border-color: var(--ink-rail); }
|
|
77
77
|
.modal__drawer .icon-btn--invert { background: var(--accent); color: var(--on-accent); border-color: transparent; width: var(--tap-lg); height: var(--tap-lg); }
|
|
78
78
|
@media (prefers-reduced-motion: no-preference) {
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
cursor: pointer;
|
|
145
145
|
}
|
|
146
146
|
.menu__item:hover, .menu__item:focus-visible { background: var(--ink-tint); outline: none; }
|
|
147
|
-
.menu__item[aria-current]
|
|
147
|
+
.menu__item[aria-current] { background: var(--accent); color: var(--on-accent); }
|
|
148
148
|
@supports (anchor-name: --a) {
|
|
149
149
|
.menu[popover] {
|
|
150
150
|
position-area: block-end span-inline-end;
|
|
@@ -255,8 +255,7 @@
|
|
|
255
255
|
}
|
|
256
256
|
/* aria-current="false" is the correct way to mark the OTHER tabs, so the
|
|
257
257
|
bare attribute selector lights every one of them up */
|
|
258
|
-
.float-bar__item[aria-current]:not([aria-current="false"])
|
|
259
|
-
.float-bar__item.is-on { background: var(--accent); color: var(--on-accent); opacity: 1; }
|
|
258
|
+
.float-bar__item[aria-current]:not([aria-current="false"]) { background: var(--accent); color: var(--on-accent); opacity: 1; }
|
|
260
259
|
.float-bar > .icon-btn { width: var(--bar-h); height: var(--bar-h); box-shadow: var(--shadow-float); }
|
|
261
260
|
|
|
262
261
|
/* ---- callout: a small card with a tail — over a map, a media, a mascot ----
|
|
@@ -290,18 +289,7 @@
|
|
|
290
289
|
border-left: 0;
|
|
291
290
|
}
|
|
292
291
|
.callout__title { font: var(--callout-title-font, var(--type-title)); }
|
|
293
|
-
.callout__sub { font: var(--callout-sub-font, var(--type-caption)); opacity:
|
|
294
|
-
/* ---- deck: swipe cards; the last child is on top ----
|
|
295
|
-
<div class="deck"><article class="card">…</article><article class="card">…</article><article class="card card--fold">front</article></div>
|
|
296
|
-
<div class="deck__actions"><button class="icon-btn">×</button><button class="icon-btn icon-btn--invert">✓</button></div> */
|
|
297
|
-
.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)); }
|
|
298
|
-
.deck > .card { grid-area: 1 / 1; width: min(100%, 20rem); min-height: 12.5rem; transition: rotate 0.3s ease, translate 0.3s ease; }
|
|
299
|
-
.deck > .card:nth-last-child(2) { rotate: -4deg; translate: calc(-1 * var(--sp-2)) var(--sp-2); opacity: 0.85; }
|
|
300
|
-
.deck > .card:nth-last-child(3) { rotate: 5deg; translate: var(--sp-3) var(--sp-4); opacity: 0.6; }
|
|
301
|
-
.deck > .card:nth-last-child(n + 4) { display: none; }
|
|
302
|
-
.deck__actions { display: flex; justify-content: center; gap: var(--deck-actions-gap, var(--sp-8)); }
|
|
303
|
-
.deck__actions > .icon-btn { width: var(--bar-h); height: var(--bar-h); }
|
|
304
|
-
|
|
292
|
+
.callout__sub { font: var(--callout-sub-font, var(--type-caption)); opacity: var(--dim); }
|
|
305
293
|
/* ---- splash: the app's mark at the human centre while it boots (Lh 2026-09-24) ----
|
|
306
294
|
<section class="screen screen--fill splash"><div class="splash__group"><div class="splash__mark">{the app's lottie/img}</div>
|
|
307
295
|
<p class="splash__text">…</p></div></section>
|
package/css/media.css
CHANGED
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
.quote__text { margin: 0; font: var(--quote-text-font, var(--type-h1)); letter-spacing: var(--track-h1); text-wrap: balance; }
|
|
54
54
|
.quote--sm .quote__text { font: var(--type-h2); letter-spacing: var(--track-h2); }
|
|
55
55
|
.quote__by { font: var(--quote-by-font, var(--type-caption)); color: var(--quote-by-ink, var(--card-muted)); }
|
|
56
|
-
.card--3 .quote__by { color: inherit; opacity:
|
|
56
|
+
.card--3 .quote__by { color: inherit; opacity: var(--dim); }
|
|
57
57
|
|
|
58
58
|
/* ---- tile grid: big square tiles — icon top, label bottom ----
|
|
59
59
|
<div class="tile-grid"><button class="tile"><svg class="icon"/><span class="tile__label">Light</span></button>
|
|
@@ -79,11 +79,10 @@
|
|
|
79
79
|
font: inherit;
|
|
80
80
|
text-align: left;
|
|
81
81
|
position: relative;
|
|
82
|
-
cursor: pointer;
|
|
83
82
|
}
|
|
84
83
|
.tile__label { font: var(--tile-label-font, var(--type-title)); }
|
|
85
84
|
.tile__value { font: var(--tile-value-font, var(--type-h2)); letter-spacing: var(--track-h2); font-variant-numeric: tabular-nums; }
|
|
86
|
-
.tile__sub { font: var(--tile-sub-font, var(--type-caption)); opacity:
|
|
85
|
+
.tile__sub { font: var(--tile-sub-font, var(--type-caption)); opacity: var(--dim); }
|
|
87
86
|
.tile__text { display: grid; gap: var(--tile-text-gap, var(--sp-0)); }
|
|
88
87
|
.tile--on { background: var(--tile-on-bg, var(--accent)); color: var(--tile-on-ink, var(--on-accent)); border-color: transparent; }
|
|
89
88
|
.tile--pick > input { appearance: none; position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
|
|
@@ -91,7 +90,7 @@
|
|
|
91
90
|
.tile--pick:has(:focus-visible) { outline: var(--focus); outline-offset: var(--sp-1); }
|
|
92
91
|
.tile--wide { grid-column: 1 / -1; }
|
|
93
92
|
/* 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 */
|
|
94
|
-
.tile--stat { border-color: transparent; background: none; padding-inline: 0;
|
|
93
|
+
.tile--stat { border-color: transparent; background: none; padding-inline: 0; }
|
|
95
94
|
.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; }
|
|
96
95
|
/* upload: dashed, centred plus + label */
|
|
97
96
|
.tile--upload {
|
|
@@ -105,6 +104,8 @@
|
|
|
105
104
|
}
|
|
106
105
|
/* tinted tiles: slot colors inside a card (schedule, notes) */
|
|
107
106
|
.tile--2 { background: var(--tile-2-bg, var(--card-2-bg)); color: var(--tile-2-ink, var(--card-2-ink)); border-color: transparent; }
|
|
107
|
+
.tile--4 { background: var(--tile-4-bg, var(--card-4-bg)); color: var(--tile-4-ink, var(--card-4-ink)); border-color: transparent; }
|
|
108
|
+
.tile--5 { background: var(--tile-5-bg, var(--card-5-bg)); color: var(--tile-5-ink, var(--card-5-ink)); border-color: transparent; }
|
|
108
109
|
.tile--3 { background: var(--tile-3-bg, var(--card-3-bg)); color: var(--tile-3-ink, var(--card-3-ink)); border-color: transparent; }
|
|
109
110
|
|
|
110
111
|
/* ---- fold: a sticky-note corner on any card (decorative) ----
|
|
@@ -113,7 +114,7 @@
|
|
|
113
114
|
the corner read as a notch with a line through it rather than a lifted flap.
|
|
114
115
|
The COLOUR goes transparent rather than the border going to 0, so the box
|
|
115
116
|
keeps its geometry and a fold card still measures the same as the cards
|
|
116
|
-
beside it
|
|
117
|
+
beside it. */
|
|
117
118
|
.card--fold {
|
|
118
119
|
border-color: transparent;
|
|
119
120
|
border-bottom-right-radius: 0;
|
package/css/numbers.css
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
}
|
|
34
34
|
.ring__value { font: var(--ring-value-font, var(--type-stat)); letter-spacing: var(--track-display); }
|
|
35
35
|
.ring__label { font: var(--ring-label-font, var(--type-caption)); color: var(--ring-label-ink, var(--card-muted)); }
|
|
36
|
-
.card--3 .ring__label { color: inherit; opacity:
|
|
36
|
+
.card--3 .ring__label { color: inherit; opacity: var(--dim); }
|
|
37
37
|
.ring--sm { --_size: var(--avatar-xl); --_w: var(--sp-3); }
|
|
38
38
|
.ring--sm .ring__value { font: 800 var(--fs-2xl)/1 var(--font-display); }
|
|
39
39
|
.ring--xs { --_size: var(--tap-sm); --_w: var(--dot-xs); } /* inline counter (step 3 of 5) */
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
background: color-mix(in srgb, var(--_ink) 30%, transparent);
|
|
87
87
|
color: var(--_ink);
|
|
88
88
|
}
|
|
89
|
+
.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) */
|
|
89
90
|
.track__step.is-done > .icon,
|
|
90
91
|
.track__step.is-done > .track__dot { background: var(--accent); color: var(--on-accent); }
|
|
91
92
|
|
|
@@ -107,7 +108,7 @@
|
|
|
107
108
|
}
|
|
108
109
|
.band__num small { font-size: 0.5em; font-weight: 700; margin-right: 0.1em; } /* unit or % */
|
|
109
110
|
.band__foot { grid-area: foot; font: var(--band-foot-font, var(--type-caption)); color: var(--band-foot-ink, var(--card-muted)); }
|
|
110
|
-
.card--3 .band__foot { color: inherit; opacity:
|
|
111
|
+
.card--3 .band__foot { color: inherit; opacity: var(--dim); }
|
|
111
112
|
/* band stack: ONE card boundary; bands are frameless inside it, a hairline
|
|
112
113
|
between each. Bands may still carry slot tints (card--2 / card--3). */
|
|
113
114
|
.band-stack {
|
|
@@ -206,7 +207,7 @@
|
|
|
206
207
|
}
|
|
207
208
|
.picker::after { left: auto; right: calc(100% / 3); }
|
|
208
209
|
.picker__unit { font: var(--picker-unit-font, var(--type-caption)); color: var(--picker-unit-ink, var(--card-muted)); }
|
|
209
|
-
.card--3 .picker__unit { color: inherit; opacity:
|
|
210
|
+
.card--3 .picker__unit { color: inherit; opacity: var(--dim); }
|
|
210
211
|
/* the scrolled-to item lights up by position — no JS */
|
|
211
212
|
@supports (animation-timeline: view(x)) {
|
|
212
213
|
.picker__item { opacity: 0.3; animation: picker-focus linear both; animation-timeline: view(x); }
|
package/css/palette.css
CHANGED
|
@@ -26,46 +26,6 @@
|
|
|
26
26
|
--dot-a: #e05c3a; --dot-b: #6f6be0;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/* ---- SHINE — shiny: periwinkle surface, coral / black / gold cards ---- */
|
|
30
|
-
[data-palette="shine"] {
|
|
31
|
-
--surface: #6d6ae4;
|
|
32
|
-
--on-surface: #ffffff;
|
|
33
|
-
--on-surface-muted: #d3d2f7;
|
|
34
|
-
|
|
35
|
-
--card-1-bg: #eec85a; --card-1-ink: #16161a;
|
|
36
|
-
--card-2-bg: #e8624a; --card-2-ink: #16161a;
|
|
37
|
-
--card-3-bg: #1b1b1f; --card-3-ink: #ffffff;
|
|
38
|
-
|
|
39
|
-
--card-border: transparent;
|
|
40
|
-
--card-muted: #4c4a44;
|
|
41
|
-
|
|
42
|
-
--accent: #1b1b1f; --on-accent: #ffffff;
|
|
43
|
-
--action-bg: #ffffff; --action-ink: #16161a; --action-border: transparent;
|
|
44
|
-
|
|
45
|
-
--pos: #2e9e5b; --neg: #d6402a;
|
|
46
|
-
--dot-a: #e8624a; --dot-b: #6d6ae4;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/* ---- FIELD — warm peach editorial: cream surface, orange accent ---- */
|
|
50
|
-
[data-palette="field"] {
|
|
51
|
-
--surface: #f9e8dc;
|
|
52
|
-
--on-surface: #241f1b;
|
|
53
|
-
--on-surface-muted: #8a7d72;
|
|
54
|
-
|
|
55
|
-
--card-1-bg: #ffffff; --card-1-ink: #241f1b;
|
|
56
|
-
--card-2-bg: #f6d9c5; --card-2-ink: #241f1b;
|
|
57
|
-
--card-3-bg: #ef4e0b; --card-3-ink: #fff4ec;
|
|
58
|
-
|
|
59
|
-
--card-border: transparent;
|
|
60
|
-
--card-muted: #8a7d72;
|
|
61
|
-
|
|
62
|
-
--accent: #ef4e0b; --on-accent: #fff4ec;
|
|
63
|
-
--action-bg: #ffffff; --action-ink: #241f1b; --action-border: transparent;
|
|
64
|
-
|
|
65
|
-
--pos: #2e8f52; --neg: #d13b1a;
|
|
66
|
-
--dot-a: #ef4e0b; --dot-b: #241f1b;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
29
|
/* ---- ROAST — coffee: warm cream surface, caramel accent ---- */
|
|
70
30
|
[data-palette="roast"] {
|
|
71
31
|
--surface: #f6f1e7;
|
|
@@ -106,6 +66,87 @@
|
|
|
106
66
|
--dot-a: #3d63e0; --dot-b: #eec85a;
|
|
107
67
|
}
|
|
108
68
|
|
|
69
|
+
/* ---- ORCHARD — modern earth: calm, real, touchable (Lh 2026-09-25). Linen base, bone paper, moss brand; every
|
|
70
|
+
tone's ink + muted is a deep shade of ITS OWN ground, so lines (currentColor mixes: --hairline, --outline, field
|
|
71
|
+
edges) come out as a darker tint of the ground under them — never a grey on a warm card. Four highlights for the
|
|
72
|
+
atmosphere, off the earth wheel on purpose: maple red · bright yellow · sky · fuchsia. ---- */
|
|
73
|
+
[data-palette="orchard"] {
|
|
74
|
+
--surface: #f4efe6; /* linen */
|
|
75
|
+
--on-surface: #2a241c; /* umber */
|
|
76
|
+
--on-surface-muted: #6e6353;
|
|
77
|
+
|
|
78
|
+
--card-1-bg: #fbf8f2; --card-1-ink: #2a241c; /* bone paper — sheets */
|
|
79
|
+
--card-2-bg: #e6d8bf; --card-2-ink: #33291c; /* sand */
|
|
80
|
+
--card-3-bg: #5c6b47; --card-3-ink: #f6f1e6; --card-3-muted: #d3d8c4; /* moss — the brand */
|
|
81
|
+
--card-4-bg: #d3d9c4; --card-4-ink: #2b3322; --card-4-muted: #515c42; /* sage mist */
|
|
82
|
+
--card-5-bg: #dcc2a6; --card-5-ink: #3a2a1c; --card-5-muted: #6b503a; /* clay */
|
|
83
|
+
|
|
84
|
+
--card-border: transparent;
|
|
85
|
+
--card-muted: #736754;
|
|
86
|
+
--card-2-muted: #66573f;
|
|
87
|
+
|
|
88
|
+
--accent: #5c6b47; --on-accent: #f6f1e6;
|
|
89
|
+
--action-bg: #fbf8f2; --action-ink: #2a241c; --action-border: transparent;
|
|
90
|
+
|
|
91
|
+
/* highlights — decoration and atmosphere, a small dose: counts, marks, chart dots, a badge on a tile */
|
|
92
|
+
--highlight-1: #d93a1f; /* maple red */
|
|
93
|
+
--highlight-2: #f5c518; /* bright yellow */
|
|
94
|
+
--highlight-3: #3a9fe0; /* sky */
|
|
95
|
+
--highlight-4: #e0457b; /* fuchsia */
|
|
96
|
+
--dot-a: var(--highlight-1); --dot-b: var(--highlight-3);
|
|
97
|
+
|
|
98
|
+
/* signals from Sweet Salmon #dd9787 — words and edges, always with an icon */
|
|
99
|
+
--pos: #6f8f5a; --neg: #c4694f;
|
|
100
|
+
--signal-error: #b5503b; /* salmon, deepened */
|
|
101
|
+
--signal-warn: #a0721f; /* ochre */
|
|
102
|
+
--signal-ok: #4f7f4a; /* leaf */
|
|
103
|
+
--signal-info: #4d6f96; /* slate */
|
|
104
|
+
}
|
|
105
|
+
/* on the dark moss card the signals turn to their light shades — the same hues, readable on the ground */
|
|
106
|
+
/* 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) */
|
|
107
|
+
[data-palette="orchard"] .badge:not(.badge--soft) { background: var(--badge-bg, var(--highlight-1)); color: var(--badge-ink, #fff8f0); }
|
|
108
|
+
[data-palette="orchard"] .tile-badge:not(.tile-badge--plain) { background: var(--tile-badge-bg, var(--highlight-2)); color: var(--tile-badge-ink, #2a241c); }
|
|
109
|
+
[data-palette="orchard"] .calendar__day--mark { background: var(--calendar-day-mark-bg, color-mix(in srgb, var(--highlight-2) 40%, transparent)); }
|
|
110
|
+
/* fields are WHITE boxes on every ground (Lh 2026-09-25) — the words typed in them read dark, even on the moss card */
|
|
111
|
+
[data-palette="orchard"] .field { background: var(--field-bg, #ffffff); color: #2a241c; }
|
|
112
|
+
[data-palette="orchard"] .pin__cell { background: var(--pin-cell-bg, #ffffff); color: #2a241c; }
|
|
113
|
+
/* the vivid ones, tried on the live parts (Lh 2026-09-25): primary = yellow · a user avatar = fuchsia · ring = sky · a switch on = sky · maple only on small dots (the count, dot a); the chosen stack tab stays moss */
|
|
114
|
+
[data-palette="orchard"] .btn--primary { background: var(--btn-primary-bg, var(--highlight-2)); color: var(--btn-primary-ink, #2a241c); }
|
|
115
|
+
[data-palette="orchard"] .avatar:not(.avatar--outline, .avatar--add, .avatar--on) { background: var(--avatar-bg, var(--highlight-4)); color: var(--avatar-ink, #ffffff); }
|
|
116
|
+
[data-palette="orchard"] .ring::before { background: conic-gradient(var(--highlight-3) calc(var(--value) * 1%), var(--ink-tint) 0); }
|
|
117
|
+
[data-palette="orchard"] .toggle:checked { background: var(--highlight-3); }
|
|
118
|
+
[data-palette="orchard"] .toggle:checked::after { background: #ffffff; }
|
|
119
|
+
[data-palette="orchard"] .card--3 { --signal-error: #f4b7a6; --signal-warn: #f1d18a; --signal-ok: #cfe6b8; --signal-info: #bcd0ec; }
|
|
120
|
+
|
|
121
|
+
/* ---- VERS — Lh's own-palette pick (2026-09-25): white surface, champagne paper, sage brand; earth tones for tones 2·4·5 ---- */
|
|
122
|
+
[data-palette="vers"] {
|
|
123
|
+
--surface: #ffffff;
|
|
124
|
+
--on-surface: #1f1b16;
|
|
125
|
+
--on-surface-muted: #6b6358;
|
|
126
|
+
|
|
127
|
+
--card-1-bg: #f6e7cb; --card-1-ink: #1f1b16; /* paper — Champagne */
|
|
128
|
+
--card-2-bg: #e3cfa6; --card-2-ink: #1f1b16; /* sand */
|
|
129
|
+
--card-3-bg: #678d58; --card-3-ink: #ffffff; /* brand — Sage */
|
|
130
|
+
--card-4-bg: #c9d6b0; --card-4-ink: #1f1b16; --card-4-muted: #4a5438; /* lichen */
|
|
131
|
+
--card-5-bg: #d4bf9c; --card-5-ink: #1f1b16; --card-5-muted: #5e4a36; /* wheat — bark was too dark */
|
|
132
|
+
|
|
133
|
+
--card-border: transparent;
|
|
134
|
+
--card-muted: #6b5f4c;
|
|
135
|
+
--card-2-muted: #5c4f3a;
|
|
136
|
+
--card-3-muted: #dfe8d6;
|
|
137
|
+
|
|
138
|
+
--accent: #678d58; --on-accent: #ffffff;
|
|
139
|
+
--action-bg: #f6e7cb; --action-ink: #1f1b16; --action-border: transparent;
|
|
140
|
+
|
|
141
|
+
/* signals from Sweet Salmon #dd9787, deepened to read on white/champagne */
|
|
142
|
+
--pos: #7fa86f; --neg: #dd9787;
|
|
143
|
+
--signal-error: #b5503b; /* salmon */
|
|
144
|
+
--signal-warn: #a5782a; /* ochre */
|
|
145
|
+
--signal-ok: #4f7f4a; /* leaf */
|
|
146
|
+
--signal-info: #4d6f96; /* slate */
|
|
147
|
+
--dot-a: #dd9787; --dot-b: #b08a5a;
|
|
148
|
+
}
|
|
149
|
+
|
|
109
150
|
/* Colored palettes trade wireframe outlines for soft elevation. */
|
|
110
151
|
[data-palette] :is(.card, .band-stack) { box-shadow: var(--shadow-card); }
|
|
111
152
|
/* COLOURED MODE is the attribute, whatever its value: a project with colours of its own (the five
|
package/css/people.css
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
.avatar--xl { --_size: var(--avatar-xl); } /* sheet head icon ring */
|
|
32
32
|
/* outline avatar: no fill, an edge — icons in a ring, "add" slots */
|
|
33
33
|
.avatar--outline { background: transparent; color: inherit; border: var(--border-w) solid var(--avatar-outline-border, var(--outline)); }
|
|
34
|
-
.avatar--add { background: transparent; color: inherit; border: var(--border-w) dashed var(--avatar-add-border, var(--outline));
|
|
34
|
+
.avatar--add { background: transparent; color: inherit; border: var(--border-w) dashed var(--avatar-add-border, var(--outline)); }
|
|
35
35
|
/* accent avatar: the "+7" tail, the selected person */
|
|
36
36
|
.avatar--on { background: var(--avatar-on-bg, var(--accent)); color: var(--avatar-on-ink, var(--on-accent)); }
|
|
37
37
|
/* halo: faint concentric rings behind a hero avatar (decorative) */
|
|
@@ -76,4 +76,5 @@
|
|
|
76
76
|
}
|
|
77
77
|
.avatar-pick__name { font: var(--avatar-pick-name-font, var(--type-label)); font-size: var(--avatar-pick-name-font-size, var(--fs-sm)); }
|
|
78
78
|
.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)); }
|
|
79
|
-
.
|
|
79
|
+
.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 */
|
|
80
|
+
.card--3 .avatar-pick__role { color: inherit; opacity: var(--dim); }
|
package/css/sheet.css
CHANGED
|
@@ -380,9 +380,8 @@
|
|
|
380
380
|
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
|
|
381
381
|
falls — no height is written. Nothing fades: done and next read at full ink. */
|
|
382
382
|
.sheet__body:has(> .sheet-steps) { display: flex; flex-direction: column; }
|
|
383
|
-
.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; }
|
|
383
|
+
.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; }
|
|
384
384
|
.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 */
|
|
385
|
-
.sheet-steps { position: relative; }
|
|
386
385
|
.sheet-steps__track { list-style: none; margin: 0; padding: 0; flex: 1; display: flex; flex-direction: column; }
|
|
387
386
|
|
|
388
387
|
.sheet-step {
|
|
@@ -400,23 +399,22 @@
|
|
|
400
399
|
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 */
|
|
401
400
|
padding-inline: var(--sheet-step-bar-pad-x, var(--sp-3)); border-radius: var(--sheet-step-bar-radius, var(--r-chip));
|
|
402
401
|
background: var(--sheet-step-bar-bg, var(--ink-tint)); color: var(--sheet-step-bar-ink, inherit);
|
|
403
|
-
border-top: var(--sheet-step-border-w,
|
|
402
|
+
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 */
|
|
404
403
|
}
|
|
405
|
-
.sheet-step__summary { color: inherit; opacity: 0.8; }
|
|
406
404
|
.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; }
|
|
407
405
|
.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 */
|
|
408
406
|
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));
|
|
409
407
|
border-radius: 50%; font: var(--sheet-step-num-font, var(--type-caption)); font-variant-numeric: tabular-nums;
|
|
410
408
|
background: var(--sheet-step-num-bg, var(--card-bg)); color: var(--sheet-step-num-ink, inherit);
|
|
411
409
|
}
|
|
412
|
-
.sheet-step__summary { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
410
|
+
.sheet-step__summary { color: inherit; opacity: 0.8; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
413
411
|
.sheet-step__check { margin-inline-start: auto; }
|
|
414
412
|
.sheet-step__body { min-height: 0; overflow: clip; overflow-clip-margin: var(--sp-1); }
|
|
415
413
|
.sheet-step__inner { display: grid; gap: var(--card-gap); padding-block: var(--card-gap); }
|
|
416
414
|
.sheet-step__inner > * { min-width: 0; }
|
|
417
415
|
.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) */
|
|
418
416
|
.sheet-step:not(.sheet-step--now) > .sheet-step__body { visibility: hidden; transition: visibility 0s linear var(--motion-sheet); }
|
|
419
|
-
.sheet-step__go { position: absolute; inset: min(
|
|
417
|
+
.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; }
|
|
420
418
|
/* the last step's finish, when the app gives one: under the steps */
|
|
421
419
|
.sheet-steps__finish { display: grid; padding-top: var(--card-gap); }
|
|
422
420
|
@media (prefers-reduced-motion: reduce) { .sheet-step { transition: none; } }
|
package/css/stack.css
CHANGED
|
@@ -243,9 +243,6 @@
|
|
|
243
243
|
padding-left: 0;
|
|
244
244
|
transition: padding-left 0.35s ease;
|
|
245
245
|
}
|
|
246
|
-
.sheet-stack--tap > .card.is-open > .card__head {
|
|
247
|
-
padding-left: calc(var(--tap-sm) + var(--sp-3));
|
|
248
|
-
}
|
|
249
246
|
.sheet-stack--tap .sheet-stack__back {
|
|
250
247
|
position: absolute;
|
|
251
248
|
left: 0;
|
|
@@ -254,6 +251,12 @@
|
|
|
254
251
|
opacity: 0;
|
|
255
252
|
visibility: hidden;
|
|
256
253
|
transition: opacity 0.35s ease, visibility 0.35s;
|
|
254
|
+
/* SMALL (see "the back button, SMALL" below) */
|
|
255
|
+
width: var(--stack-back-size, calc(var(--tap-base) * 2 / 3));
|
|
256
|
+
height: var(--stack-back-size, calc(var(--tap-base) * 2 / 3));
|
|
257
|
+
min-width: 0;
|
|
258
|
+
min-height: 0;
|
|
259
|
+
padding: 0;
|
|
257
260
|
}
|
|
258
261
|
.sheet-stack--tap > .card.is-open .sheet-stack__back {
|
|
259
262
|
opacity: 1;
|
|
@@ -313,13 +316,6 @@
|
|
|
313
316
|
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
|
|
314
317
|
(was 56px). Its tap target stays 44px: an invisible ::after around the disc. ---- */
|
|
315
318
|
.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))); }
|
|
316
|
-
.sheet-stack--tap .sheet-stack__back {
|
|
317
|
-
width: var(--stack-back-size, calc(var(--tap-base) * 2 / 3));
|
|
318
|
-
height: var(--stack-back-size, calc(var(--tap-base) * 2 / 3));
|
|
319
|
-
min-width: 0;
|
|
320
|
-
min-height: 0;
|
|
321
|
-
padding: 0;
|
|
322
|
-
}
|
|
323
319
|
.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) */
|
|
324
320
|
.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); }
|
|
325
321
|
|