@usableapp/cardds 0.7.95 → 0.7.97

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 CHANGED
@@ -2,6 +2,75 @@
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.97 — 2026-10-18
6
+
7
+ Docs only; no component, prop, class or token changes (Lh 2026-10-18: the README says what cardds is, nothing more).
8
+
9
+ ### Changed
10
+ - **The README is a few lines on what cardds is.** Before → after: the README held the whole reference (install, markup, the rules of the system, the theme, ink) → it says what cardds is and links on. The reference moves unchanged to **`docs/reference.md`**, shipped in the package beside the README. Every pointer that named a README section (`npx cardds guide`, the MCP instructions, doc comments, the CSS comments) now names `docs/reference.md`; the section names are the same.
11
+
12
+ ## 0.7.96 — 2026-10-18
13
+
14
+ From timebank's help sheet (Lh 2026-10-18): "the card's colour is no different from the background at all". A card is one boundary; a boundary the member cannot see is no boundary (WCAG 2.2 SC 1.4.11, 3:1). No prop changes. Two looks change on existing screens: every card in coloured mode and under the `lit` and `sticker` finishes now has a visible edge, and a `Tile stat` takes the ink of the card it stands on.
15
+
16
+ Then the ink (Lh 2026-10-18). On `Tile · StatOnEachTone` at tone 3: "Text on a dark background like this must be light or white". The model, ruled the same day: "there are text colours ONLIGHT and ONDARK. When the ground is light, use onlight; when the ground is dark, use ondark. In future, with a dark mode, text uses ondark too, without changing the way of thinking", and "the onlight and ondark principle applies to other glyphs too". **Ink follows its ground** (README): two ink sets per palette, every ground declares only its side, and every word and glyph on it follows. Measured by the new check on every gallery story × 7 palettes × (as written + tones 1–5): 15,137 pieces under AA at 0a36c7a → 0, and 0 in a dark mode made of sides alone. **A theme that set a per-tone ink token must move to the two sets** (Removed, below). A theme that sets only the five `--color-*` bases (timebank) changes nothing: the sets derive from `--color-ink` and `--color-on-brand`.
17
+
18
+ ### Added
19
+ - **`cardGrounds()`: can the member see each card on your theme?** Before → after: nothing measured a card against its ground, and the README said cardds made no contrast check → a function the package exports builds a card of each tone (1–5) on the screen, in a sheet's body and in a `paper` sheet's body, where your theme is loaded, and returns per pair the fill's contrast, the edge's, `pass` (one of them 3:1) and a `problem` that names the tokens and the shortfall. It changes nothing; the theme's values stay yours. Run it on a dev page (`console.table(cardGrounds())`) or in a Playwright test (`await page.evaluate(cardGrounds)`). README "Can the member see the card?".
20
+ - **Story `Tile · StatOnEachTone`**: two stat tiles on each tone.
21
+ - **Two ink sets.** `--ink-onlight` and `--ink-onlight-muted` (words and glyphs on a light ground), `--ink-ondark` and `--ink-ondark-muted` (on a dark one). Each holds 4.5:1 on every ground of its side. Unset, they derive from `--color-ink` and `--color-on-brand`; the wireframe's are #141414 / #575757 and #ffffff / #a8a8a8.
22
+ - **Sides.** `--surface-dark`, `--card-1-dark` … `--card-5-dark`, `--accent-dark`, `--action-dark`, `--neg-dark`: `1` = a dark ground, `0` = a light one. The defaults: the screen, tones 1, 2, 4 and the paper light; tone 3, tone 5, the brand fill and a falling Delta dark. orchard and vers declare their tone 5 light. A surface sets `--dark` from its fill's side; the surface list in tokens.css gives it `--card-ink`, `--card-muted`, `--on-accent`, `--accent-ink` (the brand as a glyph: itself on a light ground, ondark on a dark one) and the four signals.
23
+ - **Signals by side.** `--signal-{ok,warn,error,info}-onlight` (the shade on a light ground, 4.5:1 on every one) and `--signal-…-ondark` (the ondark ink unless a palette gives its own: orchard does). `--signal-ok` etc. are now what a piece reads, derived on each surface.
24
+ - **Dark mode falls out.** Turn the light sides to 1 and darken their fills, in a block of your own (README "Ink follows its ground"); no rule per piece. `tests/ink.spec.js` holds the gallery to that block: 0 short.
25
+ - **`inkGrounds()`: can the member read every word and glyph on your theme?** A function the package exports walks every visible word, field value, `svg.icon` and glyph drawn as a fill (a signal dot, a day's dot, the pager's dots, a check's tick, a switch's knob, the strong calendar mark's ring) inside a root, finds the ground under it (every fill, through every opacity) and returns `{ piece, surface, side, set, kind, ink, ground, ratio, needs, pass, problem }`. `side` is what the ground declares, `set` the ink set the colour is; `problem` names both, e.g. `… on .card.card--3 (light side): #575757 (--card-muted = --ink-onlight-muted) on #141414 (--card-bg) is 2.55:1, words need 4.5:1`. Words 4.5:1; large words, icons and glyphs 3:1. It changes nothing. `console.table(inkGrounds().filter((r) => !r.pass))` or `await page.evaluate(inkGrounds)`. `tests/ink.spec.js` runs it over every story in every stock palette and in dark mode, in `npm run ci`.
26
+ - **Knobs.** `--sticky-dark` (a note's side, 0), `--bubble-meta-icon-ink`, plus the knobs #35 added for muted pieces: `--day-rest-ink`, `--segment-rest-ink`, `--float-bar-item-rest-ink`, `--picker-rest-ink`, `--tile-sub-ink`, `--tile-badge-label-ink`, `--callout-sub-ink`, `--snackbar-caption-ink`, `--modal-drawer-caption-ink`, `--route-via-ink`, `--sheet-step-summary-ink`, `--sticky-heading-caption-ink`, `--calendar-day-mark2-shadow`, `--sheet-stage-foot-bg` (docs/knobs.md).
27
+
28
+ ### Removed (before → after, for a theme that set them)
29
+ - `--card-1-ink`, `--card-2-ink`, `--card-4-ink` (and `--color-ink` where it meant them) → `--ink-onlight`: one ink for every light ground.
30
+ - `--card-3-ink`, `--card-5-ink` → `--ink-ondark`.
31
+ - `--card-muted` (on `:root`, the older name), `--card-1-muted`, `--card-2-muted`, `--card-4-muted` → `--ink-onlight-muted`. `--card-muted` stays as what a piece reads on its surface; set on `:root` it no longer retunes anything.
32
+ - `--card-3-muted`, `--card-5-muted` → `--ink-ondark-muted`.
33
+ - A tone whose words were set the other way (orchard's and vers's light tone 5) → `--card-5-dark: 0`.
34
+ - `--on-surface`, `--on-surface-muted`, `--on-accent`, `--action-ink`, `--action-muted` set directly → the screen's, the brand fill's and the paper's side (`--surface-dark`, `--accent-dark`, `--action-dark`). The names stay readable; they now derive.
35
+ - `--signal-ok`, `--signal-warn`, `--signal-error`, `--signal-info` set on `:root` → `--signal-…-onlight` (and `--signal-…-ondark`).
36
+ - `--dim` and `--rest` (#35) → the muted shade of the side; `--faint` → a pager dot at rest is the muted ink, a solid shade.
37
+
38
+ ### Changed
39
+ - **A card keeps an edge in coloured mode.** Before → after: `[data-palette]` set `--card-border: transparent`, so a card's only boundary was its fill and a 6–8% shadow: in every stock palette tones 1, 2 and 4 (and 5 in orchard and vers) sat under 3:1 on the screen, and a tone-1 card in a tone-1 sheet was 1:1 → `--card-border` is `--on-surface-muted` (the ground's muted words) under any `data-palette`, a 1.5px line (`--border-w`). Every tone on every ground now holds 3:1 in every stock palette and finish (525 pairs, `tests/card-grounds.spec.js`). The shadow stays. A project that wants its own edge sets `--card-border` in `theme.css` and runs `cardGrounds()`; the old look is `--card-border: transparent`, which the check will name.
40
+ - **The `lit` and `sticker` finishes keep the card's edge.** Before → after: every finish set `--card-border: transparent`; lit's 7% ring and sticker's white cut measured 1.15–1.41:1 on a light ground → only `--action-border` steps back under a finish; `print` and `ink` draw their own line as before.
41
+ - **`Tile stat` takes the ink of what it stands on** (timebank: in `Card tone={3}` the value and icon were rgb(42,36,28) on rgb(92,107,71)). Before → after: the stat tile drops the plain tile's fill (`--action-bg`) but kept its ink (`--action-ink`), dark on a dark card → its ink is inherited, as the card's heading's; `--tile-ink` still overrides. Its sub line is the card's muted words (`--card-muted`, which each tone holds to AA) instead of the full ink at `--dim`, which was 3.3:1 on clay's terracotta.
42
+ - **Every piece reads its ink from its ground's side.** Before → after (since 0a36c7a): `.card--3` set only its ink and the accent pair; a hand list in card.css faded ten named pieces by `opacity: var(--dim)`; six `.card--3 .x` patches in lists.css; per-tone ink tokens chosen one by one → a ground declares its side and the inks follow (the surface list in tokens.css: the screen, every card tone, a sheet, a tile, a chip, a switch, the drawer, a cover, each Postcard face, a note, the post paper, the float bar's pill, the snackbar, a Delta, the track and its steps, a tile badge, an avatar, a bubble, the map's hint). A piece with no fill that stands in for one takes its ground's side (`--dark: inherit`: a stat tile, an upload tile, a plain tile badge, an outline avatar, a light drawer).
43
+ - **A muted word or glyph is a shade, never an opacity.** Unpicked days, segments, picker values, float-bar items, a tile's sub line, captions: the side's muted ink. The pager's dots at rest were 30% of the ink (1.5:1) → the muted ink; the one where you are, the full ink (it was the accent, 1.6:1 on the wireframe's tone 5). A switch's knob at rest was 45% of the ink (2.4:1, and white on the paper switch on a dark card) → the paper side's muted ink.
44
+ - **One muted shade per side.** Wireframe: tone 1's #6b6b6b, tone 2's #5f5f5f, tone 4's #555555 and a note's 68% of the ink → #575757 (4.6:1 on the water note, the darkest light ground); tone 3's #b9b9b9 and tone 5's #c4c4c4 → #a8a8a8 (4.6:1 on tone 5). Each stock palette's sets are in palette.css with the ground that bounds them.
45
+ - **Each tone's words are its side's ink.** orchard's per-tone inks (sand #33291c, sage #2b3322, clay #3a2a1c) → its onlight umber #2a241c; clay's terracotta and mustard muted → #2a2723 (the terracotta is a middle ground: no lighter muted holds 4.5:1 on it). On the brand card the inverted primary button's words are onlight (they were the brand colour).
46
+ - **A chip is a ground of the paper's side.** A signal dot on a chip on a dark card took the card's ondark signal (1:1 on the white chip) → onlight. A picked chip or tile is a ground of the accent's side.
47
+ - **The track** lays down the accent fill of where it stands and is that fill's side; its steps re-point the accent (the `.card--3 .track` rule is gone).
48
+ - **Signals.** On a light ground, the onlight shade: wireframe ok #2b7a2f → #27692a, warn #7f6400 → #705903, error #c62828 → #af2525, info #2f5f9e → #2e5c98 (each 4.5:1 on tone 4's grey; tones 2 and 4 used to take the card's ink); orchard ok #497645 → #3e5a37, warn #8d641b → #6b4e1b, error #b04e39 → #82402f, info #4c6e95 → #40556c; vers ok #477242 → #3b5734, warn #856122 → #654b1e, error #a84a37 → #803c2d, info #49698f → #3c5169; clay ok #205622 → #1b2c18, warn #5d4a00 → #2f280d, error #931e1e → #471a17, info #264c7f → #1d2938 (4.5:1 on the terracotta: nearly the ink). On a dark ground, the ondark ink; orchard's own light shades (#f9ccc0, #f2d28b, #cfe6b8, #c5d7ef, 4.5:1 on the moss) now hold on every dark ground of orchard, not only tone 3.
49
+ - **Stock palette fills**, chosen so each side's ink holds 4.5:1 on the fill, on the fill's own hue (OKLCH, lightness only), and so a tone's ink holds on its 12% tint too (a banner, a step bar, today's day carry words there):
50
+
51
+ | palette | fill | before #35 | #35 | now | its ink | ink on it, before → now | on its 12% tint now |
52
+ |---|---|---|---|---|---|---|---|
53
+ | roast | tone 3 · --accent | #b97e3c | #805729 | #8c5402 | #fdf9f1 | 3.27 → 5.91 | 4.59 |
54
+ | hydro | tone 3 · --accent | #3d63e0 | #385bce | #365bd7 | #ffffff | 5.17 → 5.78 | 4.55 |
55
+ | orchard | tone 3 · --accent | #5c6b47 | #525f3f | #52613d | #f6f1e6 | 5.11 → 5.94 | 4.55 |
56
+ | vers | tone 3 · --accent | #678d58 | #4d6a42 | #496d3a | #ffffff | 3.8 → 5.95 | 4.55 |
57
+ | clay | tone 2 (light) | #e05c3a | #e36d4f | #eb6644 | #191713 | 4.91 → 5.55 | 4.56 |
58
+ | orchard | --highlight-1 | #d93a1f | #d1381e | #d03114 | #f6f1e6 | 4.07 → 4.51 | no words on a tint |
59
+ | orchard | --highlight-4 | #e0457b | #cd3f71 | #ca2e69 | #f6f1e6 | 3.51 → 4.54 | no words on a tint |
60
+ | orchard | --neg | #c4694f | #a25741 | #ad553b | #f6f1e6 | 3.4 → 4.5 | no words on a tint |
61
+ | vers | --neg | #dd9787 | #a84a37 | #a76557 | #ffffff | 2.37 → 4.52 | no words on a tint |
62
+
63
+ hydro's ondark ink #f2f6ff → #ffffff (#35). The highlight and Delta fills carry no tint, so they hold the fill alone. A palette's `--card-border` is still `--on-surface-muted`: now the onlight muted ink, a step darker.
64
+
65
+ ### Fixed
66
+ - **`pager-forward-primary` reads a conditional forward slot as one** (reported by timebank 2026-10-18, poc/help-flow phone.tsx). Before → after: `<Btn>Back</Btn>{last ? <Btn primary>Send</Btn> : <Btn primary>When</Btn>}` was flagged, the first branch counted as a back button → the two branches of a conditional are one slot, and both are the forward Btn that must be `primary`.
67
+
68
+ ### Known, not changed
69
+ - `inkGrounds()` reads ancestors only: words over a scrim drawn by `::after`, or over a sibling that is positioned under them, are measured against the ancestors' fills. A `url()` picture is skipped; a gradient is read as decoration unless it is one colour.
70
+ - A `Delta` pill (bg `--card-3-bg`) has no visible boundary on the dark card (its words pass); a mark, not words, so the ink check does not read it.
71
+ - A calendar `mark` is a 12% accent tint: the day's number reads on it, but the mark itself is not a 3:1 glyph (`mark2` adds a 3:1 ring). Decoration colours (`--dot-a`, `--dot-b`, the highlights) are not inks and are not measured: a brand-coloured legend dot vanishes on the brand card.
72
+ - The wireframe's card edge (#141414) and its brand fill are near-black: in a dark mode they need their own colours to keep a card's boundary (cardGrounds()); the ink holds without them.
73
+
5
74
  ## 0.7.95 — 2026-10-18
6
75
 
7
76
  From timebank's help-ask prototype (Lh 2026-10-18): its Composer, Dropdown and map stood on white cards inside the help sheet. Ruled: the sheet is the paper the member fills in.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2026 everysundays. All rights reserved.
2
+
3
+ cardds is unfinished work. Its source is public so that it can be read,
4
+ not so that it can be used.
5
+
6
+ No licence is granted. You may not use, copy, modify, merge, publish,
7
+ distribute, sublicense or sell this software or any part of it, and you
8
+ may not install the @usableapp/cardds package in a project, without the
9
+ prior written permission of the copyright holder.
10
+
11
+ Viewing the source on GitHub, and forking it on GitHub as the GitHub Terms
12
+ of Service allow, does not grant any right beyond that.
13
+
14
+ The fonts in fonts/ are not covered by this notice. Each keeps its own
15
+ licence, listed in fonts/LICENSES.md.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR ITS USE.