@usableapp/cardds 0.2.2 → 0.4.0
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/README.md +35 -107
- package/cardds.js +6 -449
- package/css/actions.css +41 -35
- package/css/base.css +9 -9
- package/css/card.css +26 -25
- package/css/choice.css +50 -50
- package/css/forms.css +18 -18
- package/css/journey.css +16 -16
- package/css/layover.css +45 -45
- package/css/lists.css +43 -43
- package/css/media.css +33 -33
- package/css/numbers.css +25 -25
- package/css/people.css +11 -11
- package/css/sheet.css +29 -29
- package/css/step.css +6 -6
- package/css/theme.template.css +6 -3
- package/css/tokens.css +2 -0
- package/dist/actions/Btn.d.ts +109 -108
- package/dist/actions/BtnRow.d.ts +2 -2
- package/dist/actions/Chip.d.ts +102 -101
- package/dist/actions/Dot.d.ts +2 -2
- package/dist/actions/Dropdown.d.ts +36 -19
- package/dist/actions/Dropdown.js +41 -11
- package/dist/actions/Fab.d.ts +2 -2
- package/dist/actions/IconBtn.d.ts +298 -10
- package/dist/actions/IconBtn.js +6 -8
- package/dist/actions/Link.d.ts +105 -104
- package/dist/actions/Segment.d.ts +3 -3
- package/dist/cardds.css +354 -345
- package/dist/cards/Card.d.ts +99 -98
- package/dist/cards/CardFoot.d.ts +2 -2
- package/dist/cards/CardHead.d.ts +2 -2
- package/dist/cards/CardParts.d.ts +7 -7
- package/dist/cards/Placeholder.d.ts +2 -2
- package/dist/cards/Stat.d.ts +7 -5
- package/dist/cards/Stat.js +2 -2
- package/dist/choice/Calendar.d.ts +17 -6
- package/dist/choice/Calendar.js +9 -3
- package/dist/choice/Check.d.ts +3 -3
- package/dist/choice/DayStrip.d.ts +3 -3
- package/dist/choice/Mood.d.ts +2 -2
- package/dist/choice/Slider.d.ts +3 -3
- package/dist/choice/Slider.js +12 -8
- package/dist/forms/AddRow.d.ts +2 -2
- package/dist/forms/Composer.d.ts +2 -2
- package/dist/forms/Field.d.ts +2 -2
- package/dist/forms/FileBtn.d.ts +2 -2
- package/dist/forms/Pin.d.ts +10 -7
- package/dist/forms/Pin.js +47 -18
- package/dist/journey/NoteRow.d.ts +2 -2
- package/dist/journey/Route.d.ts +2 -2
- package/dist/journey/TileBadge.d.ts +2 -2
- package/dist/layover/Banner.d.ts +2 -2
- package/dist/layover/Callout.d.ts +2 -2
- package/dist/layover/Deck.d.ts +3 -3
- package/dist/lists/Bubble.d.ts +3 -3
- package/dist/lists/Kv.d.ts +5 -5
- package/dist/lists/Legend.d.ts +3 -3
- package/dist/lists/Row.d.ts +5 -4
- package/dist/lists/Timeline.d.ts +3 -3
- package/dist/media/MapArea.d.ts +2 -2
- package/dist/media/Mosaic.d.ts +3 -3
- package/dist/media/Postcard.d.ts +9 -5
- package/dist/media/Postcard.js +8 -3
- package/dist/media/Quote.d.ts +2 -2
- package/dist/media/Tile.d.ts +5 -4
- package/dist/numbers/Badge.d.ts +2 -2
- package/dist/numbers/Band.d.ts +3 -3
- package/dist/numbers/Bars.d.ts +3 -3
- package/dist/numbers/DotGrid.d.ts +2 -2
- package/dist/numbers/Picker.d.ts +20 -8
- package/dist/numbers/Picker.js +51 -13
- package/dist/numbers/Ring.d.ts +2 -2
- package/dist/numbers/Track.d.ts +3 -3
- package/dist/people/Avatar.d.ts +100 -99
- package/dist/people/AvatarPick.d.ts +3 -3
- package/dist/scaffold/ActionBar.d.ts +3 -3
- package/dist/scaffold/AppBar.d.ts +2 -2
- package/dist/scaffold/BaseContent.d.ts +7 -7
- package/dist/scaffold/BaseContent.js +4 -4
- package/dist/scaffold/Centre.d.ts +3 -3
- package/dist/scaffold/EmptyState.d.ts +2 -2
- package/dist/scaffold/FilterRow.d.ts +2 -2
- package/dist/scaffold/FloatBar.d.ts +105 -104
- package/dist/scaffold/PagerAt.d.ts +2 -2
- package/dist/scaffold/Screen.d.ts +100 -99
- package/dist/scaffold/TopBar.d.ts +2 -2
- package/dist/sheets/CardBack.d.ts +2 -2
- package/dist/sheets/Drawer.d.ts +19 -8
- package/dist/sheets/Drawer.js +29 -5
- package/dist/sheets/Sheet.d.ts +29 -16
- package/dist/sheets/Sheet.js +157 -11
- package/dist/sheets/SheetBody.d.ts +2 -2
- package/dist/sheets/SheetHead.d.ts +2 -2
- package/dist/sheets/SheetStack.d.ts +15 -3
- package/dist/sheets/SheetStack.js +74 -2
- package/dist/sheets/SheetStage.d.ts +2 -2
- package/dist/sheets/Step.d.ts +2 -2
- package/dist/type/Icon.d.ts +22 -7
- package/dist/type/Icon.js +27 -4
- package/dist/type/Text.d.ts +7 -1
- package/dist/type/Text.js +2 -2
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# cardds
|
|
2
2
|
|
|
3
|
+
> **cardds is a UI framework, not one project's design system.** A project takes it and puts its own values and
|
|
4
|
+
> content into the UI — tokens (`theme.css`), props, slots, composition — without touching cardds. When a project
|
|
5
|
+
> cannot get what it needs from outside, that is a gap in the framework: report it; it is closed here as a
|
|
6
|
+
> GENERAL extension point, never as that project's special case. A consumer project never edits or releases cardds.
|
|
7
|
+
>
|
|
3
8
|
> **For:** people and AI alike — this is the reference, the one place a rule of the system is written.
|
|
4
9
|
> The other docs only point here: `CLAUDE.md` (AI working IN this repo — decisions and gotchas),
|
|
5
10
|
> `docs/guides/building-with-cardds.md` (AI composing screens in React; shipped to Claude Design),
|
|
@@ -9,8 +14,7 @@ Card-first mobile design system, **React-first**: `src/` is the component
|
|
|
9
14
|
library — one thin component per pattern, emitting exactly the markup the CSS
|
|
10
15
|
documents. The CSS (`css/*.css`)
|
|
11
16
|
stays the only truth: a component never styles anything, it only picks classes
|
|
12
|
-
from props. The
|
|
13
|
-
class names rather than components. The demo is the gallery (`npm run dev`):
|
|
17
|
+
from props. The demo is the gallery (`npm run dev`):
|
|
14
18
|
every component's stories, live, searchable.
|
|
15
19
|
|
|
16
20
|
Repo: **https://github.com/everysundays/cardds** (private — this is the
|
|
@@ -53,19 +57,6 @@ story live in a 375×812 phone cell, grouped by `src/<group>/`, searchable; swit
|
|
|
53
57
|
it comes up over the phone cell and publishes `--kb` there — to SEE what a keyboard leaves of the screen; it
|
|
54
58
|
types nothing), text size, and a slider per size base. Nothing is hand-listed: add a preview file or a story and it shows.
|
|
55
59
|
|
|
56
|
-
**CSS only** (no React, no build):
|
|
57
|
-
|
|
58
|
-
```html
|
|
59
|
-
<link rel="stylesheet" href="cardds.css">
|
|
60
|
-
<script src="cardds.js" defer></script> <!-- optional: the behaviours above -->
|
|
61
|
-
<html data-palette="clay"> <!-- omit for b&w wireframe -->
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Everything renders without `cardds.js`: a dropdown still opens (a native
|
|
65
|
-
popover) but won't update its label, a stack still displays but won't open, a
|
|
66
|
-
sheet renders every state but only moves when a class changes, a pin is six
|
|
67
|
-
plain inputs.
|
|
68
|
-
|
|
69
60
|
`tests/fixtures/*.html` are the pages the geometry tests measure — not a demo. Nothing here is verified by eye.
|
|
70
61
|
|
|
71
62
|
### In another project
|
|
@@ -83,38 +74,6 @@ import '@usableapp/cardds/dist/cardds.css'; // the CSS, fonts resolve from the
|
|
|
83
74
|
```
|
|
84
75
|
|
|
85
76
|
|
|
86
|
-
**CSS only:** there's no build and no dependencies, so installing is cloning once, then
|
|
87
|
-
copying the static files into your project — never edit the clone, never
|
|
88
|
-
fork the CSS:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
# once, wherever you keep it (~/Sites/cardds is the convention on this machine)
|
|
92
|
-
git clone git@github.com:everysundays/cardds.git ~/Sites/cardds
|
|
93
|
-
# to update it later
|
|
94
|
-
git -C ~/Sites/cardds pull
|
|
95
|
-
|
|
96
|
-
# then vendor the static files into the consuming project
|
|
97
|
-
cp -R ~/Sites/cardds/css ~/Sites/cardds/fonts ~/Sites/cardds/cardds.css \
|
|
98
|
-
~/Sites/cardds/cardds.js ~/Sites/cardds/icons.svg \
|
|
99
|
-
./assets/
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
`cardds.css` is just the import bundle for `css/*.css`, so keep the `css/`
|
|
103
|
-
folder next to it, and `fonts/` beside that (`css/fonts.css` reaches the faces
|
|
104
|
-
as `../fonts/`). `icons.svg` is referenced by path from your markup
|
|
105
|
-
(`<use href="icons.svg#bell">`), so put it where those references resolve.
|
|
106
|
-
Then follow the rules below — the short version is: tune your own `theme.css`
|
|
107
|
-
(a copy of `css/theme.template.css`, see "A project's theme") and nothing else, and never write a raw hex or px in a component.
|
|
108
|
-
|
|
109
|
-
The repo is private, so cloning needs an account with access (`everysundays`
|
|
110
|
-
on GitHub) — set that up as an SSH host alias if you already use a different
|
|
111
|
-
account for `git@github.com` day to day, the way this machine's `~/.ssh/config`
|
|
112
|
-
does it for other `everysundays` repos.
|
|
113
|
-
|
|
114
|
-
**Record what you copied.** A vendored copy with no record of the commit it came
|
|
115
|
-
from can't be told apart from a fork: write the commit hash (and a sha256 per
|
|
116
|
-
file) beside the copy, so a hand edit or a stale copy can be caught.
|
|
117
|
-
|
|
118
77
|
Working with Claude in another project? The `/cardds` skill
|
|
119
78
|
(`~/.claude/skills/cardds/`) carries the install and the contract, and points
|
|
120
79
|
back here. It is deliberately thin — **this repo stays the source of truth**,
|
|
@@ -126,10 +85,10 @@ if the contract itself changes.
|
|
|
126
85
|
`src/<group>/<Name>.tsx`, one export per class family; sub-parts are their own
|
|
127
86
|
components (`CardHead`, `KvRow`, `TrackStep`, `SheetBody`). A component
|
|
128
87
|
chooses classes from props (`tone`, `state`, `primary`, `sm`…) and lays the
|
|
129
|
-
contract's children in order
|
|
130
|
-
(
|
|
131
|
-
|
|
132
|
-
|
|
88
|
+
contract's children in order. A component that has STATE is controlled like an input
|
|
89
|
+
(`state` / `open` / `value` / `flipped` / `selected` + its `on…`, or a `default…` twin), keeps its own behaviour
|
|
90
|
+
inside itself and only ever asks through that callback; it never knows another component — the app wires them
|
|
91
|
+
(2026-09-21; `cardds.js` is down to `--kb`). Never fix a look in a wrapper: fix the CSS, the
|
|
133
92
|
wrapper follows. **Claude Design** builds with these components through
|
|
134
93
|
`/design-sync` (`.design-sync/`: the sync config, the authored preview
|
|
135
94
|
stories, the conventions the design agent reads) — a new component needs a
|
|
@@ -191,7 +150,7 @@ whose markup has rules, because the sheet's box is the step itself:
|
|
|
191
150
|
<!-- acts: the words + a sheet -->
|
|
192
151
|
<section class="step">
|
|
193
152
|
<section class="base-content">…the words…</section>
|
|
194
|
-
<article class="card sheet sheet--half"
|
|
153
|
+
<article class="card sheet sheet--half">
|
|
195
154
|
<button class="sheet__handle" type="button" aria-label="ปรับความสูง"></button>
|
|
196
155
|
<div class="card__head"><h2 class="t-h2">…</h2><span class="chip">…</span></div>
|
|
197
156
|
<div class="sheet__body">
|
|
@@ -244,12 +203,14 @@ whose markup has rules, because the sheet's box is the step itself:
|
|
|
244
203
|
screen with a sheet finishes ON the sheet: a `.card__foot`, the sheet's last child — ONE row, the page's
|
|
245
204
|
conclusion. The foot stands on the screen's bottom edge at half, 3q and full alike (a layer as tall as
|
|
246
205
|
the sheet, slid up by the share the sheet slid down — `sheet.css`), and is gone at peek. Nothing inside
|
|
247
|
-
the sheet's body commits on its own (a `Composer` there takes no `send`).
|
|
248
|
-
|
|
206
|
+
the sheet's body commits on its own (a `Composer` there takes no `send`). This is how cardds's own screens are
|
|
207
|
+
composed — guidance; the framework does not enforce it: a component never changes because another one is there.
|
|
249
208
|
- **Never write a sheet's height, and never a `.sheet-stage` inside a step.**
|
|
250
209
|
State is a class (`sheet--peek` / `--half` / `--full`); the sheet is always
|
|
251
|
-
the step's full height and only slides.
|
|
252
|
-
|
|
210
|
+
the step's full height and only slides. In React the APP owns it: `<Sheet state={s}
|
|
211
|
+
onStateChange={setS}>` (controlled) or `<Sheet defaultState="half">` (it keeps its own). The sheet's own behaviour —
|
|
212
|
+
the handle's tap and drag, the focus raise, the climb when the keyboard moves the cut — lives in the component and
|
|
213
|
+
only ever ASKS through `onStateChange(state, reason)`; nothing outside the sheet is touched.
|
|
253
214
|
|
|
254
215
|
## Centred card markup
|
|
255
216
|
|
|
@@ -297,56 +258,19 @@ between at 40% down the screen (see *Anatomy*, "Where the centre is"):
|
|
|
297
258
|
- **BaseContent that moves** (Lh 2026-09-20) — two ways, never both on one screen:
|
|
298
259
|
- *Pages of words:* `.step > .pages > .base-content` (one `aria-current="step"`, the rest `inert`) — every page
|
|
299
260
|
one height, the round pager turns them (`slideTo()`), the words slide like a page. No sheet there.
|
|
300
|
-
- *
|
|
301
|
-
sheet
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
261
|
+
- *Sheets the app calls:* the base offers WAYS IN — sign in · new phone · join — as buttons (`.cta-pack`); each
|
|
262
|
+
way has a sheet that holds its WHOLE form and its own submit on its foot, starting `.sheet--away` (not on the
|
|
263
|
+
screen: slid out, hidden once gone, `inert`). **The wiring is the app's, not cardds's**: a `useState` of which
|
|
264
|
+
sheet is on and where, each button sets it, each `<Sheet state onStateChange>` reads it — one at a time, the same
|
|
265
|
+
button raises a peeked sheet, the handle stops at peek (`states="peek full"`). Story `Step · Calls` is those few
|
|
266
|
+
lines; it could as well be a route, which is what makes the phone's back button close a sheet. CSS's only part:
|
|
267
|
+
behind a peeked sheet the words keep `--sheet-peek` of room (the box declares the token), so the buttons under
|
|
268
|
+
it scroll clear.
|
|
307
269
|
**Never a form taken apart** — one sheet per field, a "send" left on the base: a form lives whole in ONE sheet.
|
|
308
270
|
Fixture `tests/fixtures/calls.html`, tests `tests/calls.spec.js`, stories `Step · Walks` / `Step · Calls`.
|
|
309
271
|
- **A pager turns pages of words, never a screen with a sheet** (Lh 2026-09-20). A
|
|
310
272
|
sheet means this screen has work that cannot be walked past: no ← →, no bar at all — the sheet's
|
|
311
|
-
own foot finishes it.
|
|
312
|
-
down while the sheet is on the screen, a peeking one included: dimmed, no pointer
|
|
313
|
-
(`actions.css`), `inert` (`cardds.js`).
|
|
314
|
-
|
|
315
|
-
## Files
|
|
316
|
-
|
|
317
|
-
| file | what | touch it? |
|
|
318
|
-
|---|---|---|
|
|
319
|
-
| `css/fonts.css` + `fonts/` | the two `@font-face`s: PK Nonthaburi (body, `--font-ui`), FC Pride (display, `--font-display`); the font files and their licences | when swapping a face |
|
|
320
|
-
| `css/tokens.css` | spacing, radius, type levels, motion (`--motion-sheet`), the human centre (`--screen-centre`), grayscale role defaults; registers the two sheet tokens (`--sheet-peek`, `--sheet-half`) so script can read them resolved | rarely |
|
|
321
|
-
| `css/theme.template.css` | **a project's theme** — the four size bases + the colour roles, at their defaults; NOT in the bundle: copied into the project as its `theme.css`, loaded after `cardds.css` | copy it, don't edit it |
|
|
322
|
-
| `css/palette.css` | **color settings — palettes as role-token overrides** | yes, this one |
|
|
323
|
-
| `css/base.css` | reset, surface, typography classes, `.base-content` | rarely |
|
|
324
|
-
| `css/card.css` | `.card` + its skeleton (`.card__head` / content / `.card__foot`), `.card-list`, `.card--row`, `.icon-row`, stats, `.card--centre` (one card at the human centre of a fill screen) and `.screen__centre` (a small group there) | when adding variants |
|
|
325
|
-
| `css/stack.css` | **sheet stack** — `.sheet-stack`: the menu, sheets stacked (heads peek, up to 5; `--tap` tap-to-open, the back button dissolves in; `--closed` nothing open, heads at the bottom, the base above (`.sheet-stack__base`); `--display` the title is the peek, `--fanned` wider peeks); always edge to edge; a stacked sheet is a `.card` | rarely |
|
|
326
|
-
| `css/sheet.css` | **sheet single** — `.sheet`: a card as bottom sheet, full height always, a state is how far it slid: `--peek` / `--half` / `--full` (translate only); handle · head · `.sheet__body` (the head pinned, the body scrolls); `.sheet-stage` (overlay stage: map sheet, a `__hero` — one thing centred in the band a half sheet leaves open, `--dim`, `--raised`, ask drawer) | when adding states |
|
|
327
|
-
| `css/step.css` | `.step` — one screen, one task: `.base-content` (reads) + optional `.sheet` (acts), the bar's room, the keyboard's room | rarely |
|
|
328
|
-
| `css/forms.css` | `.field` (outlined input, label = placeholder), `.add-row` | when adding controls |
|
|
329
|
-
| `css/journey.css` | `.route`, `.tile-badge`, `.note-row` — trip/status primitives | when adding variants |
|
|
330
|
-
| `css/actions.css` | topbar, chips, buttons (`.btn--xl`), `.dropdown` (the standard select: pill + `.menu` popover), `.action-bar` (+ `--pager` for previous/next, two round icon buttons, never labels; `--tiers` for a control row above the buttons), `.fab` | when adding actions |
|
|
331
|
-
| `css/numbers.css` | `.ring` gauge, `.track` steps, `.card--band` + `.band-stack`, `.dotgrid`, `.picker`, `.badge`, `.bars` | big numbers |
|
|
332
|
-
| `css/people.css` | `.avatar` (sm/lg/xl, outline, add, on, halo), `.avatar-stack`, `.avatar-pick` | people |
|
|
333
|
-
| `css/choice.css` | `.check`, `.toggle`, `.chip-grid` + `.chip--pick` (+ `--sign`), `.day-strip`, `.calendar`, `.mood`, `.pin`, `.composer`, `.slider` | choice controls |
|
|
334
|
-
| `css/lists.css` | `.row` / `.rows` (frameless rows in a card), `.kv`, `.kv-grid`, `.thread` + `.bubble` (chat: theirs left, mine right, no tail), `.timeline`, `.legend`, `.link` | lists inside cards |
|
|
335
|
-
| `css/media.css` | `.card--cover`, `.quote`, `.tile-grid` + `.tile`, `.card--fold`, `.mosaic`, `.wave` | media & display |
|
|
336
|
-
| `css/layover.css` | `.modal` (the ask: `__lift` + `__drawer`, closes on any drawer button → `cardds:modal`), `.menu` (popover), `.banner` (details), `.float-bar`, `.callout`, `.deck` | cards over content |
|
|
337
|
-
| `icons.svg` | Lucide sprite (ISC), 56 minimal stroke icons | add symbols as needed |
|
|
338
|
-
| `src/` → `dist/` | the React library: `src/<group>/<Name>.tsx`, one thin component per pattern, JSDoc = the rule; built by `npm run build` (tsc) into `dist/` with `.d.ts`; `src/type/icons.ts` is generated from `icons.svg` | when adding a component |
|
|
339
|
-
| `gallery/` | the gallery site: `npm run dev` → `/` every story, `/:Name` one component (`gallery/src/Gallery.tsx` globs `.design-sync/previews/`) | the demo |
|
|
340
|
-
| `tests/fixtures/` | the HTML pages (`index`, `sheet`, `stack`, `elements`) the geometry tests measure — ex `demo/`, not a demo | when a geometry test needs a new case |
|
|
341
|
-
| `docs/handoff/` | the Claude Design handoff spec (the Commons Time Bank app built from it was dropped 2026-09-16) | reference |
|
|
342
|
-
| `scripts/` | `build-icons.mjs` (icons.svg → `src/type/icons.ts`), `flatten-css.mjs` (`cardds.css` + imports → `dist/cardds.css`) | rarely |
|
|
343
|
-
| `docs/guides/` | `building-with-cardds.md` — the anatomy, the step, the two sheet systems and the vocabulary in React terms; shipped to Claude Design as its guidelines | when the contract changes |
|
|
344
|
-
| `cardds.js` | the behaviours (delegated, class/property toggles only — everything renders without it): dropdown value sync, `.sheet-stack--tap` open/close (tolerates one wrapper per sheet; close reads the tapped sheet), `.pin` auto-advance / Backspace / paste + `cardds:pin`, the sheet handle (tap / drag-snap / Enter / Space), the focus and keyboard raises (`--kb`), `cardds:sheet` | rarely |
|
|
345
|
-
|
|
346
|
-
## Anatomy — base, menus, content, and the card skeleton
|
|
347
|
-
|
|
348
|
-
Every screen is the same four things, and every card the same three:
|
|
349
|
-
|
|
273
|
+
own foot finishes it. (Guidance — not enforced.)
|
|
350
274
|
- A screen is **base, top menu, bottom menu, content**. The base is the
|
|
351
275
|
surface; the menus are the chrome above and below (`.topbar` / `.appbar`,
|
|
352
276
|
`.action-bar` / `.float-bar`); content is everything between.
|
|
@@ -543,7 +467,7 @@ A project retunes cardds from ONE file of its own, and nothing else. Copy
|
|
|
543
467
|
<html data-palette="own"> <!-- colours of your own = coloured mode; any value no stock palette uses -->
|
|
544
468
|
```
|
|
545
469
|
|
|
546
|
-
That file is
|
|
470
|
+
That file is where a project's look lives. Bases and roles:
|
|
547
471
|
|
|
548
472
|
| what | tokens | moves |
|
|
549
473
|
|---|---|---|
|
|
@@ -557,10 +481,14 @@ That file is the whole public surface:
|
|
|
557
481
|
|
|
558
482
|
Rules:
|
|
559
483
|
|
|
560
|
-
- **
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
484
|
+
- **Three levels, widest first — use the widest that says what you mean.**
|
|
485
|
+
1. a **base** moves a whole family (`--sp-base`, `--fs-base`, `--r-base`, `--tap-base`, the five `--color-*`): the system keeps its proportions.
|
|
486
|
+
2. a **role / root token** moves one meaning everywhere (`--accent`, `--card-1-bg`, `--btn-h`, `--chip-h`, `--header-h`, `--screen-w`, `--motion-sheet`…).
|
|
487
|
+
3. a **knob** moves ONE component (`--btn-pad-x`, `--chip-bg`, `--icon-btn-size`, `--appbar-pad-x`…) — on `:root` for everywhere, or on any element for
|
|
488
|
+
the components inside it. A knob is declared nowhere; its default is the fallback in the rule. The full list is generated from the CSS:
|
|
489
|
+
[`docs/knobs.md`](docs/knobs.md) (`npm run knobs`). Missing the knob you need? That is a gap in cardds — report it; it is added as a knob, never as your special case.
|
|
490
|
+
- **Never a multiplier, never a step of the scale** (`--sp-4`, `--fs-h1`, `--r-card` — retune the base, or the component's knob), never a private
|
|
491
|
+
(`--_*`) or a published value (`--card-pad`, `--bar-reserve`, `--sheet-*`: other rules do arithmetic with them).
|
|
564
492
|
- **On `:root` only.** The derived tokens are computed where they are declared
|
|
565
493
|
(`:root`), so a base set on a subtree does not reach them.
|
|
566
494
|
- **After `cardds.css`.** A stock palette's block and a project's `:root` weigh
|