@usableapp/cardds 0.7.13 → 0.7.15

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,34 @@
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.15 — 2026-09-25
6
+
7
+ ### Removed (breaking for anyone using them)
8
+ - Palettes `shine` and `field`. `data-palette="shine"|"field"` → pick `clay`, `roast`, `hydro`, `orchard` or `vers`.
9
+ The `Palette` type no longer lists them.
10
+
11
+ ### Added
12
+ - Palette `vers`: white surface, champagne paper, sage brand, earth tones 2·4·5, signals from salmon.
13
+ - Palette `orchard` (reworked): modern earth (linen · bone · sand · moss · sage mist · clay); each tone's ink is a deep
14
+ shade of its own ground, so lines tint with the ground. Fields and PIN cells are white. Vivid accents: primary `Btn`
15
+ yellow, avatars fuchsia, `Ring` and a `Toggle` that is on in sky, the count badge and dot a in maple. Every one of these
16
+ still yields to its knob (`--btn-primary-bg`, `--avatar-bg`, `--badge-bg`…) set by a project.
17
+ - Tokens `--highlight-1` … `--highlight-4`: four atmosphere colours a palette may set (grey in the wireframe). Nothing
18
+ changes for a project that doesn't set them.
19
+ - Card tones 4 · 5 and signals `--signal-warn` · `--signal-ok` · `--signal-info` (with `--signal-error`).
20
+ - Gallery: a `Palette` page (type group) — every colour role of the palette on now, plus stories `Signals` and `Highlights`.
21
+
22
+ ## 0.7.14 — 2026-09-25
23
+
24
+ ### Added
25
+ - `Btn form`: a form's button. It is sized to its words with wide sides (58px, knob `--btn-form-pad-x`) and centred on its
26
+ own row under the field, so it reads as part of the form, not a page CTA. Use it for a SheetStep's button:
27
+ `<Btn primary block>` → `<Btn primary form>`. Don't combine it with `block` (block wins). Replaces the native `form`
28
+ attribute on `Btn`. Story `Btn · Form`.
29
+
30
+ ### Changed
31
+ - Gallery: `IconBtn`'s stories are on the Btn page (no IconBtn page). The component and its API are unchanged.
32
+
5
33
  ## 0.7.13 — 2026-09-25
6
34
 
7
35
  ### Added
package/css/actions.css CHANGED
@@ -123,6 +123,7 @@
123
123
  would take the light-card action ink and vanish */
124
124
  .btn--quiet { background: transparent; color: inherit; border-color: color-mix(in srgb, currentColor 35%, transparent); }
125
125
  .btn--block { width: 100%; }
126
+ .btn--form { justify-self: center; align-self: center; margin-inline: auto; padding-inline: var(--btn-form-pad-x, calc(var(--sp-base) * 14.5)); /* 58px: "ส่งรหัส OTP" at 213px, 20% longer than at 40px sides (Lh 2026-09-25) */ } /* a form's button: its words + wide sides, centred in a grid (a step) or a block (Lh 2026-09-25) */
126
127
  /* xl: the one giant call to action in a tinted card ("Taxi!") */
127
128
  .btn--xl { min-height: var(--btn-xl-h); font: 800 var(--fs-3xl)/1 var(--font-display); letter-spacing: var(--track-h1); border-radius: var(--r-card); padding-inline: var(--sp-8); }
128
129
  /* disabled keeps the slot — a control that vanishes moves everything else,
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,
package/css/media.css CHANGED
@@ -105,6 +105,8 @@
105
105
  }
106
106
  /* tinted tiles: slot colors inside a card (schedule, notes) */
107
107
  .tile--2 { background: var(--tile-2-bg, var(--card-2-bg)); color: var(--tile-2-ink, var(--card-2-ink)); border-color: transparent; }
108
+ .tile--4 { background: var(--tile-4-bg, var(--card-4-bg)); color: var(--tile-4-ink, var(--card-4-ink)); border-color: transparent; }
109
+ .tile--5 { background: var(--tile-5-bg, var(--card-5-bg)); color: var(--tile-5-ink, var(--card-5-ink)); border-color: transparent; }
108
110
  .tile--3 { background: var(--tile-3-bg, var(--card-3-bg)); color: var(--tile-3-ink, var(--card-3-ink)); border-color: transparent; }
109
111
 
110
112
  /* ---- fold: a sticky-note corner on any card (decorative) ----
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/tokens.css CHANGED
@@ -167,6 +167,9 @@
167
167
  --card-1-bg: var(--color-paper, #ffffff); --card-1-ink: var(--color-ink, #141414);
168
168
  --card-2-bg: var(--_tone-2, #e6e6e3); --card-2-ink: var(--color-ink, #141414);
169
169
  --card-3-bg: var(--color-brand, #141414); --card-3-ink: var(--color-on-brand, #ffffff);
170
+ /* tones 4 · 5 (Lh 2026-09-25): more card colours for a palette that has them — the wireframe keeps them grey */
171
+ --card-4-bg: #d4d4d0; --card-4-ink: var(--color-ink, #141414); --card-4-muted: #555555;
172
+ --card-5-bg: #3d3d3d; --card-5-ink: #ffffff; --card-5-muted: #c4c4c4;
170
173
 
171
174
  --card-border: #141414; /* wireframe: visible outline; palettes may set transparent */
172
175
  --card-muted: var(--_muted-on-paper, #6b6b6b); /* secondary text inside cards (the default, tone-1 card) */
@@ -187,6 +190,11 @@
187
190
  --neg: #3d3d3d;
188
191
  --dot-a: var(--color-brand, #141414);
189
192
  --dot-b: #8a8a8a;
193
+ --signal-warn: #8a6d00; /* the full signal set (Lh 2026-09-25): error · warn · ok · info — each with an icon and words */
194
+ --signal-ok: #2e7d32;
195
+ --signal-info: #2f5f9e;
196
+ /* 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 */
197
+ --highlight-1: #3d3d3d; --highlight-2: #8a8a8a; --highlight-3: #5f5f5f; --highlight-4: #b0b0b0;
190
198
  --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 */
191
199
 
192
200
  /* derived tints — read the element's own ink, so they work on any slot */
@@ -1,11 +1,14 @@
1
1
  import { type ComponentProps } from 'react';
2
- export interface BtnProps extends ComponentProps<'button'> {
2
+ export interface BtnProps extends Omit<ComponentProps<'button'>, 'form'> {
3
3
  /** the filled accent button — the one forward move */
4
4
  primary?: boolean;
5
5
  /** ink on whatever it sits on, a faint outline */
6
6
  quiet?: boolean;
7
7
  /** full width */
8
8
  block?: boolean;
9
+ /** a form's button: sized to its words with wide side padding, centred on its own row — it reads as part of the form above it,
10
+ * not a page CTA (Lh 2026-09-25). Replaces the native `form` attribute (a button outside its <form> — not a cardds pattern). */
11
+ form?: boolean;
9
12
  /** the one giant call to action in a tinted card ("Taxi!") */
10
13
  xl?: boolean;
11
14
  /** a link styled as a button */
@@ -15,129 +18,76 @@ export interface BtnProps extends ComponentProps<'button'> {
15
18
  * Btn — the pill button (48px+ tall). Plain by default; `primary` for the one move; `quiet` on tinted cards.
16
19
  * In a CardFoot up to four share the line; in an ActionBar it takes the width. An Icon xs may lead or trail the label.
17
20
  */
18
- export declare function Btn({ primary, quiet, block, xl, href, className, type, ...rest }: BtnProps): import("react").DetailedReactHTMLElement<{
19
- ref?: import("react").Ref<HTMLButtonElement> | undefined;
20
- key?: import("react").Key | null | undefined;
21
- disabled?: boolean | undefined;
22
- form?: string | undefined;
23
- formAction?: string | ((formData: FormData) => void | Promise<void>) | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS] | undefined;
24
- formEncType?: string | undefined;
25
- formMethod?: string | undefined;
26
- formNoValidate?: boolean | undefined;
27
- formTarget?: string | undefined;
28
- name?: string | undefined;
29
- value?: string | readonly string[] | number | undefined;
30
- defaultChecked?: boolean | undefined;
31
- defaultValue?: string | number | readonly string[] | undefined;
32
- suppressContentEditableWarning?: boolean | undefined;
33
- suppressHydrationWarning?: boolean | undefined;
34
- accessKey?: string | undefined;
35
- autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {});
36
- autoFocus?: boolean | undefined;
37
- contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
38
- contextMenu?: string | undefined;
39
- dir?: string | undefined;
40
- draggable?: (boolean | "true" | "false") | undefined;
41
- enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
42
- hidden?: boolean | undefined;
43
- id?: string | undefined;
44
- lang?: string | undefined;
45
- nonce?: string | undefined;
46
- slot?: string | undefined;
47
- spellCheck?: (boolean | "true" | "false") | undefined;
21
+ export declare function Btn({ primary, quiet, block, form, xl, href, className, type, ...rest }: BtnProps): import("react").DetailedReactHTMLElement<{
22
+ name?: string | undefined | undefined;
23
+ slot?: string | undefined | undefined;
48
24
  style?: import("react").CSSProperties | undefined;
49
- tabIndex?: number | undefined;
50
- title?: string | undefined;
51
- translate?: "yes" | "no" | undefined;
52
- radioGroup?: string | undefined;
25
+ title?: string | undefined | undefined;
26
+ children?: import("react").ReactNode;
27
+ suppressHydrationWarning?: boolean | undefined | undefined;
28
+ color?: string | undefined | undefined;
29
+ id?: string | undefined | undefined;
30
+ lang?: string | undefined | undefined;
31
+ nonce?: string | undefined | undefined;
32
+ part?: string | undefined | undefined;
53
33
  role?: import("react").AriaRole | undefined;
54
- about?: string | undefined;
55
- content?: string | undefined;
56
- datatype?: string | undefined;
57
- inlist?: any;
58
- prefix?: string | undefined;
59
- property?: string | undefined;
60
- rel?: string | undefined;
61
- resource?: string | undefined;
62
- rev?: string | undefined;
63
- typeof?: string | undefined;
64
- vocab?: string | undefined;
65
- autoCorrect?: string | undefined;
66
- autoSave?: string | undefined;
67
- color?: string | undefined;
68
- itemProp?: string | undefined;
69
- itemScope?: boolean | undefined;
70
- itemType?: string | undefined;
71
- itemID?: string | undefined;
72
- itemRef?: string | undefined;
73
- results?: number | undefined;
74
- security?: string | undefined;
75
- unselectable?: "on" | "off" | undefined;
76
- popover?: "" | "auto" | "manual" | "hint" | undefined;
77
- popoverTargetAction?: "toggle" | "show" | "hide" | undefined;
78
- popoverTarget?: string | undefined;
79
- inert?: boolean | undefined;
80
- inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined;
81
- is?: string | undefined;
82
- exportparts?: string | undefined;
83
- part?: string | undefined;
84
- "aria-activedescendant"?: string | undefined;
34
+ tabIndex?: number | undefined | undefined;
35
+ "aria-activedescendant"?: string | undefined | undefined;
85
36
  "aria-atomic"?: (boolean | "true" | "false") | undefined;
86
- "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined;
87
- "aria-braillelabel"?: string | undefined;
88
- "aria-brailleroledescription"?: string | undefined;
37
+ "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
38
+ "aria-braillelabel"?: string | undefined | undefined;
39
+ "aria-brailleroledescription"?: string | undefined | undefined;
89
40
  "aria-busy"?: (boolean | "true" | "false") | undefined;
90
- "aria-checked"?: boolean | "false" | "mixed" | "true" | undefined;
91
- "aria-colcount"?: number | undefined;
92
- "aria-colindex"?: number | undefined;
93
- "aria-colindextext"?: string | undefined;
94
- "aria-colspan"?: number | undefined;
95
- "aria-controls"?: string | undefined;
96
- "aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined;
97
- "aria-describedby"?: string | undefined;
98
- "aria-description"?: string | undefined;
99
- "aria-details"?: string | undefined;
41
+ "aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
42
+ "aria-colcount"?: number | undefined | undefined;
43
+ "aria-colindex"?: number | undefined | undefined;
44
+ "aria-colindextext"?: string | undefined | undefined;
45
+ "aria-colspan"?: number | undefined | undefined;
46
+ "aria-controls"?: string | undefined | undefined;
47
+ "aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
48
+ "aria-describedby"?: string | undefined | undefined;
49
+ "aria-description"?: string | undefined | undefined;
50
+ "aria-details"?: string | undefined | undefined;
100
51
  "aria-disabled"?: (boolean | "true" | "false") | undefined;
101
- "aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined;
102
- "aria-errormessage"?: string | undefined;
52
+ "aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
53
+ "aria-errormessage"?: string | undefined | undefined;
103
54
  "aria-expanded"?: (boolean | "true" | "false") | undefined;
104
- "aria-flowto"?: string | undefined;
55
+ "aria-flowto"?: string | undefined | undefined;
105
56
  "aria-grabbed"?: (boolean | "true" | "false") | undefined;
106
- "aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined;
57
+ "aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
107
58
  "aria-hidden"?: (boolean | "true" | "false") | undefined;
108
- "aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined;
109
- "aria-keyshortcuts"?: string | undefined;
110
- "aria-label"?: string | undefined;
111
- "aria-labelledby"?: string | undefined;
112
- "aria-level"?: number | undefined;
113
- "aria-live"?: "off" | "assertive" | "polite" | undefined;
59
+ "aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
60
+ "aria-keyshortcuts"?: string | undefined | undefined;
61
+ "aria-label"?: string | undefined | undefined;
62
+ "aria-labelledby"?: string | undefined | undefined;
63
+ "aria-level"?: number | undefined | undefined;
64
+ "aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
114
65
  "aria-modal"?: (boolean | "true" | "false") | undefined;
115
66
  "aria-multiline"?: (boolean | "true" | "false") | undefined;
116
67
  "aria-multiselectable"?: (boolean | "true" | "false") | undefined;
117
- "aria-orientation"?: "horizontal" | "vertical" | undefined;
118
- "aria-owns"?: string | undefined;
119
- "aria-placeholder"?: string | undefined;
120
- "aria-posinset"?: number | undefined;
121
- "aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined;
68
+ "aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
69
+ "aria-owns"?: string | undefined | undefined;
70
+ "aria-placeholder"?: string | undefined | undefined;
71
+ "aria-posinset"?: number | undefined | undefined;
72
+ "aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
122
73
  "aria-readonly"?: (boolean | "true" | "false") | undefined;
123
- "aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined;
74
+ "aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
124
75
  "aria-required"?: (boolean | "true" | "false") | undefined;
125
- "aria-roledescription"?: string | undefined;
126
- "aria-rowcount"?: number | undefined;
127
- "aria-rowindex"?: number | undefined;
128
- "aria-rowindextext"?: string | undefined;
129
- "aria-rowspan"?: number | undefined;
76
+ "aria-roledescription"?: string | undefined | undefined;
77
+ "aria-rowcount"?: number | undefined | undefined;
78
+ "aria-rowindex"?: number | undefined | undefined;
79
+ "aria-rowindextext"?: string | undefined | undefined;
80
+ "aria-rowspan"?: number | undefined | undefined;
130
81
  "aria-selected"?: (boolean | "true" | "false") | undefined;
131
- "aria-setsize"?: number | undefined;
132
- "aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined;
133
- "aria-valuemax"?: number | undefined;
134
- "aria-valuemin"?: number | undefined;
135
- "aria-valuenow"?: number | undefined;
136
- "aria-valuetext"?: string | undefined;
137
- children?: import("react").ReactNode | undefined;
82
+ "aria-setsize"?: number | undefined | undefined;
83
+ "aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
84
+ "aria-valuemax"?: number | undefined | undefined;
85
+ "aria-valuemin"?: number | undefined | undefined;
86
+ "aria-valuenow"?: number | undefined | undefined;
87
+ "aria-valuetext"?: string | undefined | undefined;
138
88
  dangerouslySetInnerHTML?: {
139
89
  __html: string | TrustedHTML;
140
- } | undefined;
90
+ } | undefined | undefined;
141
91
  onCopy?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
142
92
  onCopyCapture?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
143
93
  onCut?: import("react").ClipboardEventHandler<HTMLButtonElement> | undefined;
@@ -306,6 +256,58 @@ export declare function Btn({ primary, quiet, block, xl, href, className, type,
306
256
  onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
307
257
  onTransitionStart?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
308
258
  onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLButtonElement> | undefined;
259
+ ref?: import("react").Ref<HTMLButtonElement> | undefined;
260
+ key?: import("react").Key | null | undefined;
261
+ defaultChecked?: boolean | undefined | undefined;
262
+ defaultValue?: string | number | readonly string[] | undefined;
263
+ suppressContentEditableWarning?: boolean | undefined | undefined;
264
+ accessKey?: string | undefined | undefined;
265
+ autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
266
+ autoFocus?: boolean | undefined | undefined;
267
+ contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
268
+ contextMenu?: string | undefined | undefined;
269
+ dir?: string | undefined | undefined;
270
+ draggable?: (boolean | "true" | "false") | undefined;
271
+ enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
272
+ hidden?: boolean | undefined | undefined;
273
+ spellCheck?: (boolean | "true" | "false") | undefined;
274
+ translate?: "yes" | "no" | undefined | undefined;
275
+ radioGroup?: string | undefined | undefined;
276
+ about?: string | undefined | undefined;
277
+ content?: string | undefined | undefined;
278
+ datatype?: string | undefined | undefined;
279
+ inlist?: any;
280
+ prefix?: string | undefined | undefined;
281
+ property?: string | undefined | undefined;
282
+ rel?: string | undefined | undefined;
283
+ resource?: string | undefined | undefined;
284
+ rev?: string | undefined | undefined;
285
+ typeof?: string | undefined | undefined;
286
+ vocab?: string | undefined | undefined;
287
+ autoCorrect?: string | undefined | undefined;
288
+ autoSave?: string | undefined | undefined;
289
+ itemProp?: string | undefined | undefined;
290
+ itemScope?: boolean | undefined | undefined;
291
+ itemType?: string | undefined | undefined;
292
+ itemID?: string | undefined | undefined;
293
+ itemRef?: string | undefined | undefined;
294
+ results?: number | undefined | undefined;
295
+ security?: string | undefined | undefined;
296
+ unselectable?: "on" | "off" | undefined | undefined;
297
+ popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
298
+ popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
299
+ popoverTarget?: string | undefined | undefined;
300
+ inert?: boolean | undefined | undefined;
301
+ inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
302
+ is?: string | undefined | undefined;
303
+ exportparts?: string | undefined | undefined;
304
+ disabled?: boolean | undefined | undefined;
305
+ formAction?: string | ((formData: FormData) => void | Promise<void>) | undefined;
306
+ formEncType?: string | undefined | undefined;
307
+ formMethod?: string | undefined | undefined;
308
+ formNoValidate?: boolean | undefined | undefined;
309
+ formTarget?: string | undefined | undefined;
310
+ value?: string | number | readonly string[] | undefined;
309
311
  href: string | undefined;
310
312
  type: "button" | "submit" | "reset" | undefined;
311
313
  className: string;
@@ -4,11 +4,11 @@ import { cx } from '../cx.js';
4
4
  * Btn — the pill button (48px+ tall). Plain by default; `primary` for the one move; `quiet` on tinted cards.
5
5
  * In a CardFoot up to four share the line; in an ActionBar it takes the width. An Icon xs may lead or trail the label.
6
6
  */
7
- export function Btn({ primary, quiet, block, xl, href, className, type, ...rest }) {
7
+ export function Btn({ primary, quiet, block, form, xl, href, className, type, ...rest }) {
8
8
  return createElement(href ? 'a' : 'button', {
9
9
  href,
10
10
  type: href ? undefined : type ?? 'button',
11
- className: cx('btn', primary && 'btn--primary', quiet && 'btn--quiet', block && 'btn--block', xl && 'btn--xl', className),
11
+ className: cx('btn', primary && 'btn--primary', quiet && 'btn--quiet', block && 'btn--block', form && 'btn--form', xl && 'btn--xl', className),
12
12
  ...rest,
13
13
  });
14
14
  }
package/dist/cardds.css CHANGED
@@ -208,6 +208,9 @@
208
208
  --card-1-bg: var(--color-paper, #ffffff); --card-1-ink: var(--color-ink, #141414);
209
209
  --card-2-bg: var(--_tone-2, #e6e6e3); --card-2-ink: var(--color-ink, #141414);
210
210
  --card-3-bg: var(--color-brand, #141414); --card-3-ink: var(--color-on-brand, #ffffff);
211
+ /* tones 4 · 5 (Lh 2026-09-25): more card colours for a palette that has them — the wireframe keeps them grey */
212
+ --card-4-bg: #d4d4d0; --card-4-ink: var(--color-ink, #141414); --card-4-muted: #555555;
213
+ --card-5-bg: #3d3d3d; --card-5-ink: #ffffff; --card-5-muted: #c4c4c4;
211
214
 
212
215
  --card-border: #141414; /* wireframe: visible outline; palettes may set transparent */
213
216
  --card-muted: var(--_muted-on-paper, #6b6b6b); /* secondary text inside cards (the default, tone-1 card) */
@@ -228,6 +231,11 @@
228
231
  --neg: #3d3d3d;
229
232
  --dot-a: var(--color-brand, #141414);
230
233
  --dot-b: #8a8a8a;
234
+ --signal-warn: #8a6d00; /* the full signal set (Lh 2026-09-25): error · warn · ok · info — each with an icon and words */
235
+ --signal-ok: #2e7d32;
236
+ --signal-info: #2f5f9e;
237
+ /* 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 */
238
+ --highlight-1: #3d3d3d; --highlight-2: #8a8a8a; --highlight-3: #5f5f5f; --highlight-4: #b0b0b0;
231
239
  --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
240
 
233
241
  /* derived tints — read the element's own ink, so they work on any slot */
@@ -288,46 +296,6 @@
288
296
  --dot-a: #e05c3a; --dot-b: #6f6be0;
289
297
  }
290
298
 
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
299
  /* ---- ROAST — coffee: warm cream surface, caramel accent ---- */
332
300
  [data-palette="roast"] {
333
301
  --surface: #f6f1e7;
@@ -368,6 +336,87 @@
368
336
  --dot-a: #3d63e0; --dot-b: #eec85a;
369
337
  }
370
338
 
339
+ /* ---- ORCHARD — modern earth: calm, real, touchable (Lh 2026-09-25). Linen base, bone paper, moss brand; every
340
+ tone's ink + muted is a deep shade of ITS OWN ground, so lines (currentColor mixes: --hairline, --outline, field
341
+ edges) come out as a darker tint of the ground under them — never a grey on a warm card. Four highlights for the
342
+ atmosphere, off the earth wheel on purpose: maple red · bright yellow · sky · fuchsia. ---- */
343
+ [data-palette="orchard"] {
344
+ --surface: #f4efe6; /* linen */
345
+ --on-surface: #2a241c; /* umber */
346
+ --on-surface-muted: #6e6353;
347
+
348
+ --card-1-bg: #fbf8f2; --card-1-ink: #2a241c; /* bone paper — sheets */
349
+ --card-2-bg: #e6d8bf; --card-2-ink: #33291c; /* sand */
350
+ --card-3-bg: #5c6b47; --card-3-ink: #f6f1e6; --card-3-muted: #d3d8c4; /* moss — the brand */
351
+ --card-4-bg: #d3d9c4; --card-4-ink: #2b3322; --card-4-muted: #515c42; /* sage mist */
352
+ --card-5-bg: #dcc2a6; --card-5-ink: #3a2a1c; --card-5-muted: #6b503a; /* clay */
353
+
354
+ --card-border: transparent;
355
+ --card-muted: #736754;
356
+ --card-2-muted: #66573f;
357
+
358
+ --accent: #5c6b47; --on-accent: #f6f1e6;
359
+ --action-bg: #fbf8f2; --action-ink: #2a241c; --action-border: transparent;
360
+
361
+ /* highlights — decoration and atmosphere, a small dose: counts, marks, chart dots, a badge on a tile */
362
+ --highlight-1: #d93a1f; /* maple red */
363
+ --highlight-2: #f5c518; /* bright yellow */
364
+ --highlight-3: #3a9fe0; /* sky */
365
+ --highlight-4: #e0457b; /* fuchsia */
366
+ --dot-a: var(--highlight-1); --dot-b: var(--highlight-3);
367
+
368
+ /* signals from Sweet Salmon #dd9787 — words and edges, always with an icon */
369
+ --pos: #6f8f5a; --neg: #c4694f;
370
+ --signal-error: #b5503b; /* salmon, deepened */
371
+ --signal-warn: #a0721f; /* ochre */
372
+ --signal-ok: #4f7f4a; /* leaf */
373
+ --signal-info: #4d6f96; /* slate */
374
+ }
375
+ /* on the dark moss card the signals turn to their light shades — the same hues, readable on the ground */
376
+ /* 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) */
377
+ [data-palette="orchard"] .badge:not(.badge--soft) { background: var(--badge-bg, var(--highlight-1)); color: var(--badge-ink, #fff8f0); }
378
+ [data-palette="orchard"] .tile-badge:not(.tile-badge--plain) { background: var(--tile-badge-bg, var(--highlight-2)); color: var(--tile-badge-ink, #2a241c); }
379
+ [data-palette="orchard"] .calendar__day--mark { background: var(--calendar-day-mark-bg, color-mix(in srgb, var(--highlight-2) 40%, transparent)); }
380
+ /* fields are WHITE boxes on every ground (Lh 2026-09-25) — the words typed in them read dark, even on the moss card */
381
+ [data-palette="orchard"] .field { background: var(--field-bg, #ffffff); color: #2a241c; }
382
+ [data-palette="orchard"] .pin__cell { background: var(--pin-cell-bg, #ffffff); color: #2a241c; }
383
+ /* 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 */
384
+ [data-palette="orchard"] .btn--primary { background: var(--btn-primary-bg, var(--highlight-2)); color: var(--btn-primary-ink, #2a241c); }
385
+ [data-palette="orchard"] .avatar:not(.avatar--outline, .avatar--add, .avatar--on) { background: var(--avatar-bg, var(--highlight-4)); color: var(--avatar-ink, #ffffff); }
386
+ [data-palette="orchard"] .ring::before { background: conic-gradient(var(--highlight-3) calc(var(--value) * 1%), var(--ink-tint) 0); }
387
+ [data-palette="orchard"] .toggle:checked { background: var(--highlight-3); }
388
+ [data-palette="orchard"] .toggle:checked::after { background: #ffffff; }
389
+ [data-palette="orchard"] .card--3 { --signal-error: #f4b7a6; --signal-warn: #f1d18a; --signal-ok: #cfe6b8; --signal-info: #bcd0ec; }
390
+
391
+ /* ---- VERS — Lh's own-palette pick (2026-09-25): white surface, champagne paper, sage brand; earth tones for tones 2·4·5 ---- */
392
+ [data-palette="vers"] {
393
+ --surface: #ffffff;
394
+ --on-surface: #1f1b16;
395
+ --on-surface-muted: #6b6358;
396
+
397
+ --card-1-bg: #f6e7cb; --card-1-ink: #1f1b16; /* paper — Champagne */
398
+ --card-2-bg: #e3cfa6; --card-2-ink: #1f1b16; /* sand */
399
+ --card-3-bg: #678d58; --card-3-ink: #ffffff; /* brand — Sage */
400
+ --card-4-bg: #c9d6b0; --card-4-ink: #1f1b16; --card-4-muted: #4a5438; /* lichen */
401
+ --card-5-bg: #d4bf9c; --card-5-ink: #1f1b16; --card-5-muted: #5e4a36; /* wheat — bark was too dark */
402
+
403
+ --card-border: transparent;
404
+ --card-muted: #6b5f4c;
405
+ --card-2-muted: #5c4f3a;
406
+ --card-3-muted: #dfe8d6;
407
+
408
+ --accent: #678d58; --on-accent: #ffffff;
409
+ --action-bg: #f6e7cb; --action-ink: #1f1b16; --action-border: transparent;
410
+
411
+ /* signals from Sweet Salmon #dd9787, deepened to read on white/champagne */
412
+ --pos: #7fa86f; --neg: #dd9787;
413
+ --signal-error: #b5503b; /* salmon */
414
+ --signal-warn: #a5782a; /* ochre */
415
+ --signal-ok: #4f7f4a; /* leaf */
416
+ --signal-info: #4d6f96; /* slate */
417
+ --dot-a: #dd9787; --dot-b: #b08a5a;
418
+ }
419
+
371
420
  /* Colored palettes trade wireframe outlines for soft elevation. */
372
421
  [data-palette] :is(.card, .band-stack) { box-shadow: var(--shadow-card); }
373
422
  /* COLOURED MODE is the attribute, whatever its value: a project with colours of its own (the five
@@ -564,6 +613,8 @@ button { font: inherit; cursor: pointer; }
564
613
 
565
614
  .card--2 { --card-bg: var(--card-2-bg); --card-ink: var(--card-2-ink); --card-muted: var(--card-2-muted); }
566
615
  .card--3 { --card-bg: var(--card-3-bg); --card-ink: var(--card-3-ink); }
616
+ .card--4 { --card-bg: var(--card-4-bg); --card-ink: var(--card-4-ink); --card-muted: var(--card-4-muted); }
617
+ .card--5 { --card-bg: var(--card-5-bg); --card-ink: var(--card-5-ink); --card-muted: var(--card-5-muted); }
567
618
 
568
619
  /* dark/accent slot: accent-toned controls would vanish — the slot re-points
569
620
  the accent tokens, so every accent consumer (btn--primary, chip--on,
@@ -2053,6 +2104,7 @@ button { font: inherit; cursor: pointer; }
2053
2104
  would take the light-card action ink and vanish */
2054
2105
  .btn--quiet { background: transparent; color: inherit; border-color: color-mix(in srgb, currentColor 35%, transparent); }
2055
2106
  .btn--block { width: 100%; }
2107
+ .btn--form { justify-self: center; align-self: center; margin-inline: auto; padding-inline: var(--btn-form-pad-x, calc(var(--sp-base) * 14.5)); /* 58px: "ส่งรหัส OTP" at 213px, 20% longer than at 40px sides (Lh 2026-09-25) */ } /* a form's button: its words + wide sides, centred in a grid (a step) or a block (Lh 2026-09-25) */
2056
2108
  /* xl: the one giant call to action in a tinted card ("Taxi!") */
2057
2109
  .btn--xl { min-height: var(--btn-xl-h); font: 800 var(--fs-3xl)/1 var(--font-display); letter-spacing: var(--track-h1); border-radius: var(--r-card); padding-inline: var(--sp-8); }
2058
2110
  /* disabled keeps the slot — a control that vanishes moves everything else,
@@ -3260,6 +3312,8 @@ button { font: inherit; cursor: pointer; }
3260
3312
  }
3261
3313
  /* tinted tiles: slot colors inside a card (schedule, notes) */
3262
3314
  .tile--2 { background: var(--tile-2-bg, var(--card-2-bg)); color: var(--tile-2-ink, var(--card-2-ink)); border-color: transparent; }
3315
+ .tile--4 { background: var(--tile-4-bg, var(--card-4-bg)); color: var(--tile-4-ink, var(--card-4-ink)); border-color: transparent; }
3316
+ .tile--5 { background: var(--tile-5-bg, var(--card-5-bg)); color: var(--tile-5-ink, var(--card-5-ink)); border-color: transparent; }
3263
3317
  .tile--3 { background: var(--tile-3-bg, var(--card-3-bg)); color: var(--tile-3-ink, var(--card-3-ink)); border-color: transparent; }
3264
3318
 
3265
3319
  /* ---- fold: a sticky-note corner on any card (decorative) ----
@@ -1,7 +1,7 @@
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 */
@@ -32,7 +32,7 @@ export interface TileProps extends Omit<ComponentProps<'div'>, 'onChange'> {
32
32
  /** spans the whole grid */
33
33
  wide?: boolean;
34
34
  /** a slot tint */
35
- tone?: 2 | 3;
35
+ tone?: 2 | 3 | 4 | 5;
36
36
  /** div (default), button for a tap tile — pick tiles render as a label */
37
37
  as?: 'div' | 'button';
38
38
  }
@@ -6,7 +6,7 @@ export interface BandProps extends ComponentProps<'article'> {
6
6
  num: ReactNode;
7
7
  /** the footnote under the label */
8
8
  foot?: ReactNode;
9
- tone?: 1 | 2 | 3;
9
+ tone?: 1 | 2 | 3 | 4 | 5;
10
10
  }
11
11
  /** Band — a data card: 2-line label · giant number · footnote. Stack several in a BandStack for one boundary with hairlines. */
12
12
  export declare function Band({ label, num, foot, tone, className, ...rest }: BandProps): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { type ComponentProps, type ReactNode, type Ref } from 'react';
2
- export type Palette = 'clay' | 'shine' | 'field' | 'roast' | 'hydro';
2
+ export type Palette = 'clay' | 'roast' | 'hydro' | 'orchard' | 'vers';
3
3
  export interface ScreenProps extends ComponentProps<'div'> {
4
4
  /** exactly one phone height (100dvh), clipped: the box a Step or a SheetStack fills — an app screen, not a scrolling page */
5
5
  fill?: boolean;
@@ -12,7 +12,7 @@ export interface StackSheetProps extends Omit<ComponentProps<'article'>, 'title'
12
12
  /** the SHEET HEAD's title — an h2 (the page's h1 is its own) */
13
13
  title: ReactNode;
14
14
  /** the paper: 1 light · 2 tinted · 3 dark */
15
- tone?: 1 | 2 | 3;
15
+ tone?: 1 | 2 | 3 | 4 | 5;
16
16
  /** the head's end when the sheet has no tabs: an Icon, an IconRow */
17
17
  icon?: ReactNode;
18
18
  /** TABS in the head: icon buttons at the end — the sheet's pages. A tap on one in a peeked head opens the sheet on it */
@@ -7,7 +7,7 @@ export interface HomeSheet {
7
7
  /** the sheet head's end when it has no tabs: an Icon, an IconRow */
8
8
  icon?: ReactNode;
9
9
  /** the paper: 1 light · 2 tinted · 3 dark (default: 2, 3, 1, 2, 3 by place) */
10
- tone?: 1 | 2 | 3;
10
+ tone?: 1 | 2 | 3 | 4 | 5;
11
11
  /** the sheet's pages as icon tabs in its head (a count shows as a small circle over the icon) — see `StackSheet` */
12
12
  tabs?: StackSheetTab[];
13
13
  /** the tab shown first (default: the first) */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usableapp/cardds",
3
- "version": "0.7.13",
3
+ "version": "0.7.15",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "description": "card-first mobile design system, React-first: the components in src/ are thin wrappers over the CSS contract (css/*.css stays the only truth); gallery/ shows every story live (npm run dev), tests/ measures the geometry.",