@usableapp/cardds 0.7.56 → 0.7.58

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,19 @@
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.58 — 2026-10-06
6
+
7
+ ### Changed
8
+ - **A closed paper sheet in a stack shows the card's colour where the next sheet's round top does not cover it.** The white body used to show in those corners. While the sheet is closed that body is clear. On the way back into the stack the card colour fades in over `--motion-quick`, and the fade ends as the sheet stops. Open, the body is white at once. The first row still sits `--sp-6` down. Nothing to change in a screen.
9
+
10
+ ## 0.7.57 — 2026-10-06
11
+
12
+ ### Added
13
+ - **`paper` on a sheet in a stack.** The same prop as the single sheet, on `StackSheet`, on a `Card` in a `SheetStack`, and on each sheet of `Home`. The head keeps `tone`. The body and the foot are white. The gap under the head stays the sheet's colour. The first row sits `--sp-6` (24px at the default spacing) down into the white. A pull to refresh adds its own room on top of that inset. Pass `paper` on the sheets that should look this way. A sheet without it is unchanged.
14
+
15
+ ### Fixed
16
+ - **A dark `paper` head no longer paints its light ink onto the white body.** The words on the white use the page's ink (`--color-ink`, or the wireframe dark when that is unset). A theme that already sets `--color-ink` is unchanged.
17
+
5
18
  ## 0.7.56 — 2026-10-06
6
19
 
7
20
  ### Changed
package/README.md CHANGED
@@ -275,8 +275,12 @@ whose markup has rules, because the sheet's box is the step itself:
275
275
  pinned; the body is the one thing that scrolls, to the card's own edges. The
276
276
  handle is a line, or four dots (`mark="dots"`): both sit in the card's top
277
277
  padding, the same distance from the edge, so the title stays put. `paper` makes
278
- the content white while the head keeps the sheet's colour (`tone`, as a card). A
279
- sheet with no head (the dim page sheet) is a body alone.
278
+ the content white while the head keeps the sheet's colour (`tone`, as a card).
279
+ The same prop on a `StackSheet`, or on a `Card` in a stack: the head keeps the
280
+ tone, the body and the foot are white, and the gap under the head stays the tone.
281
+ While that sheet is closed, the corners the next sheet does not cover show the
282
+ card's colour. That colour fades in as the sheet returns, and is done when it stops.
283
+ A sheet with no head (the dim page sheet) is a body alone.
280
284
  - **The step follows its top bar directly, and touches it.** `full` means
281
285
  the sheet's top edge at the bar's bottom edge — nothing above it but the
282
286
  bar. So the room the screen would have left between the bar and the step
package/css/sheet.css CHANGED
@@ -203,16 +203,19 @@
203
203
  The flex gap under the head is outside the body, so it stays the sheet's tint.
204
204
  The first field would sit on that colour seam. The white inset is --sp-6 (24px at
205
205
  the default spacing), the body's own top padding, and only when the sheet is paper.
206
- A plain sheet keeps padding-top 0. */
206
+ A plain sheet keeps padding-top 0. A sheet in a stack wears the same class and the same
207
+ inset: the stack's own gap under the head is the card's colour, so the row still needs this white.
208
+ The ink falls back to the wireframe word colour: an unset --color-ink would otherwise
209
+ inherit a dark card's light ink, and the words would vanish on the white. */
207
210
  .sheet--paper > .sheet__body {
208
211
  --card-bg: var(--color-paper, #fff);
209
- --card-ink: var(--color-ink);
210
- --card-muted: var(--_muted-on-paper);
212
+ --card-ink: var(--color-ink, #141414);
213
+ --card-muted: var(--_muted-on-paper, #555555);
211
214
  background: var(--card-bg);
212
215
  color: var(--card-ink);
213
216
  padding-top: var(--sp-6);
214
217
  }
215
- .sheet--paper > .card__foot { --card-bg: var(--color-paper, #fff); color: var(--color-ink); }
218
+ .sheet--paper > .card__foot { --card-bg: var(--color-paper, #fff); color: var(--color-ink, #141414); }
216
219
  .sheet__handle--dots {
217
220
  --_dot: var(--sp-1);
218
221
  --_step: calc(var(--_dot) * 2.5);
package/css/stack.css CHANGED
@@ -175,7 +175,9 @@
175
175
  }
176
176
  .sheet-stack--tap > .card.is-open.is-dragging { transition: none; }
177
177
  .sheet-stack--tap > .card > .card__head { touch-action: none; }
178
- /* a pull in the content, already at the top: the words move down, the card stays. --_refresh is the finger, private. */
178
+ /* a pull in the content, already at the top: the words move down, the card stays. --_refresh is the finger, private.
179
+ A paper body adds its own --sp-6 on top of this (the rule below): the stack's gap under the head is the
180
+ card's colour, so without the white inset the first row sits on that seam. */
179
181
  .sheet-stack > .card > .sheet__body { padding-top: var(--_refresh, 0px); transition: padding-top var(--motion-sheet) ease; }
180
182
  .sheet-stack--tap > .card.is-open:not(:has(> .sheet__body)) {
181
183
  padding-top: calc(var(--card-pad) + var(--_refresh, 0px));
@@ -311,6 +313,42 @@
311
313
  .sheet-stack--tap > .card:has(> .sheet__body).is-open { overflow: clip; }
312
314
  .sheet-stack > .card:has(> .sheet__body) > :not(.sheet__body) { flex-shrink: 0; }
313
315
  .sheet-stack > .card > .sheet__body { --_cover: 0rem; } /* nothing slid under here: the stack's sheet is always whole */
316
+ /* a closed paper sheet's body stays clear (Lh 2026-10-06). The next sheet's round top does not
317
+ cover the corners, and a white body showed there beside the head. Clear, the card's own colour
318
+ shows in that pocket. Open, the body is white, and the first row sits --sp-6 down, the same white
319
+ inset a single paper sheet keeps: the flex gap under the head is the card's colour, so the row
320
+ would otherwise sit on that seam. A pull adds --_refresh on top of the inset. On the way back
321
+ into the stack the card colour fades in quickly (--motion-quick) and that fade ends with the
322
+ sheet's own slide (--motion-sheet, plus the same stagger), so the corner is the head colour
323
+ at the moment the sheet stops. Rising, the body is white at once. */
324
+ .sheet-stack > .card.sheet--paper > .sheet__body {
325
+ padding-top: calc(var(--sp-6) + var(--_refresh, 0px));
326
+ transition: padding-top var(--motion-sheet) ease, background-color 0s linear;
327
+ }
328
+ .sheet-stack > .card.sheet--paper:not(.is-open) > .sheet__body {
329
+ background-color: transparent;
330
+ transition:
331
+ padding-top var(--motion-sheet) ease,
332
+ background-color var(--motion-quick) ease calc(var(--stagger, 0) * 70ms + var(--motion-sheet) - var(--motion-quick));
333
+ }
334
+ @media (prefers-reduced-motion: reduce) {
335
+ .sheet-stack > .card.sheet--paper:not(.is-open) > .sheet__body {
336
+ transition: padding-top var(--motion-sheet) ease, background-color 0s linear;
337
+ }
338
+ }
339
+ /* a paper stack's foot is white to the card's edges, and it covers the tinted flex gap above it so the
340
+ button does not sit on a colour stripe. The head's gap stays: it is outside this foot. The button stays
341
+ where it was — the padding gives back what the bleed takes. */
342
+ .sheet-stack > .card.sheet--paper > .card__foot {
343
+ background: var(--color-paper, #fff);
344
+ color: var(--color-ink, #141414);
345
+ margin-top: calc(-1 * var(--card-gap));
346
+ margin-inline: calc(-1 * var(--card-pad));
347
+ margin-bottom: calc(-1 * var(--card-pad));
348
+ padding-top: var(--card-gap);
349
+ padding-inline: var(--card-pad);
350
+ padding-bottom: var(--card-pad);
351
+ }
314
352
 
315
353
  /* ---- StackSheet's tabs (Lh 2026-09-23): the head's end is a row of small icon buttons, the sheet's pages — the chosen one
316
354
  filled (.icon-btn--invert) only while the sheet is open; a count is a small circle over the icon's top right corner ---- */
package/dist/cardds.css CHANGED
@@ -1176,7 +1176,9 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
1176
1176
  }
1177
1177
  .sheet-stack--tap > .card.is-open.is-dragging { transition: none; }
1178
1178
  .sheet-stack--tap > .card > .card__head { touch-action: none; }
1179
- /* a pull in the content, already at the top: the words move down, the card stays. --_refresh is the finger, private. */
1179
+ /* a pull in the content, already at the top: the words move down, the card stays. --_refresh is the finger, private.
1180
+ A paper body adds its own --sp-6 on top of this (the rule below): the stack's gap under the head is the
1181
+ card's colour, so without the white inset the first row sits on that seam. */
1180
1182
  .sheet-stack > .card > .sheet__body { padding-top: var(--_refresh, 0px); transition: padding-top var(--motion-sheet) ease; }
1181
1183
  .sheet-stack--tap > .card.is-open:not(:has(> .sheet__body)) {
1182
1184
  padding-top: calc(var(--card-pad) + var(--_refresh, 0px));
@@ -1312,6 +1314,42 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
1312
1314
  .sheet-stack--tap > .card:has(> .sheet__body).is-open { overflow: clip; }
1313
1315
  .sheet-stack > .card:has(> .sheet__body) > :not(.sheet__body) { flex-shrink: 0; }
1314
1316
  .sheet-stack > .card > .sheet__body { --_cover: 0rem; } /* nothing slid under here: the stack's sheet is always whole */
1317
+ /* a closed paper sheet's body stays clear (Lh 2026-10-06). The next sheet's round top does not
1318
+ cover the corners, and a white body showed there beside the head. Clear, the card's own colour
1319
+ shows in that pocket. Open, the body is white, and the first row sits --sp-6 down, the same white
1320
+ inset a single paper sheet keeps: the flex gap under the head is the card's colour, so the row
1321
+ would otherwise sit on that seam. A pull adds --_refresh on top of the inset. On the way back
1322
+ into the stack the card colour fades in quickly (--motion-quick) and that fade ends with the
1323
+ sheet's own slide (--motion-sheet, plus the same stagger), so the corner is the head colour
1324
+ at the moment the sheet stops. Rising, the body is white at once. */
1325
+ .sheet-stack > .card.sheet--paper > .sheet__body {
1326
+ padding-top: calc(var(--sp-6) + var(--_refresh, 0px));
1327
+ transition: padding-top var(--motion-sheet) ease, background-color 0s linear;
1328
+ }
1329
+ .sheet-stack > .card.sheet--paper:not(.is-open) > .sheet__body {
1330
+ background-color: transparent;
1331
+ transition:
1332
+ padding-top var(--motion-sheet) ease,
1333
+ background-color var(--motion-quick) ease calc(var(--stagger, 0) * 70ms + var(--motion-sheet) - var(--motion-quick));
1334
+ }
1335
+ @media (prefers-reduced-motion: reduce) {
1336
+ .sheet-stack > .card.sheet--paper:not(.is-open) > .sheet__body {
1337
+ transition: padding-top var(--motion-sheet) ease, background-color 0s linear;
1338
+ }
1339
+ }
1340
+ /* a paper stack's foot is white to the card's edges, and it covers the tinted flex gap above it so the
1341
+ button does not sit on a colour stripe. The head's gap stays: it is outside this foot. The button stays
1342
+ where it was — the padding gives back what the bleed takes. */
1343
+ .sheet-stack > .card.sheet--paper > .card__foot {
1344
+ background: var(--color-paper, #fff);
1345
+ color: var(--color-ink, #141414);
1346
+ margin-top: calc(-1 * var(--card-gap));
1347
+ margin-inline: calc(-1 * var(--card-pad));
1348
+ margin-bottom: calc(-1 * var(--card-pad));
1349
+ padding-top: var(--card-gap);
1350
+ padding-inline: var(--card-pad);
1351
+ padding-bottom: var(--card-pad);
1352
+ }
1315
1353
 
1316
1354
  /* ---- StackSheet's tabs (Lh 2026-09-23): the head's end is a row of small icon buttons, the sheet's pages — the chosen one
1317
1355
  filled (.icon-btn--invert) only while the sheet is open; a count is a small circle over the icon's top right corner ---- */
@@ -1599,16 +1637,19 @@ button:enabled { cursor: pointer; } /* a disabled one keeps the arrow */
1599
1637
  The flex gap under the head is outside the body, so it stays the sheet's tint.
1600
1638
  The first field would sit on that colour seam. The white inset is --sp-6 (24px at
1601
1639
  the default spacing), the body's own top padding, and only when the sheet is paper.
1602
- A plain sheet keeps padding-top 0. */
1640
+ A plain sheet keeps padding-top 0. A sheet in a stack wears the same class and the same
1641
+ inset: the stack's own gap under the head is the card's colour, so the row still needs this white.
1642
+ The ink falls back to the wireframe word colour: an unset --color-ink would otherwise
1643
+ inherit a dark card's light ink, and the words would vanish on the white. */
1603
1644
  .sheet--paper > .sheet__body {
1604
1645
  --card-bg: var(--color-paper, #fff);
1605
- --card-ink: var(--color-ink);
1606
- --card-muted: var(--_muted-on-paper);
1646
+ --card-ink: var(--color-ink, #141414);
1647
+ --card-muted: var(--_muted-on-paper, #555555);
1607
1648
  background: var(--card-bg);
1608
1649
  color: var(--card-ink);
1609
1650
  padding-top: var(--sp-6);
1610
1651
  }
1611
- .sheet--paper > .card__foot { --card-bg: var(--color-paper, #fff); color: var(--color-ink); }
1652
+ .sheet--paper > .card__foot { --card-bg: var(--color-paper, #fff); color: var(--color-ink, #141414); }
1612
1653
  .sheet__handle--dots {
1613
1654
  --_dot: var(--sp-1);
1614
1655
  --_step: calc(var(--_dot) * 2.5);
@@ -7,6 +7,8 @@ export type Tone = 1 | 2 | 3 | 4 | 5;
7
7
  export interface CardProps extends ComponentProps<'article'> {
8
8
  /** the tone slot — see `Tone` */
9
9
  tone?: Tone;
10
+ /** the content is white paper and the head keeps the card's colour. The same look as `Sheet paper`. Omit it and the content matches the head */
11
+ paper?: boolean;
10
12
  /** compact: a small card inside a card or a sheet body (a note, a promo) */
11
13
  sm?: boolean;
12
14
  /** a list row that is its own card: thumb · body · end, in a CardList */
@@ -45,7 +47,7 @@ export interface CardProps extends ComponentProps<'article'> {
45
47
  * boundary). The order is the card's, never the writer's. A head of its own shape: write `<CardHead>` as the first child instead.
46
48
  * A page with one feature and one CTA may be a single card. Keep everything big.
47
49
  */
48
- export declare function Card({ tone, sm, row, cover, fold, centre, band, as, heading, caption, end, level, foot, footLink, stack, className, style, children, onClick, ref, ...rest }: CardProps): import("react").DetailedReactHTMLElement<{
50
+ export declare function Card({ tone, paper, sm, row, cover, fold, centre, band, as, heading, caption, end, level, foot, footLink, stack, className, style, children, onClick, ref, ...rest }: CardProps): import("react").DetailedReactHTMLElement<{
49
51
  onClick: import("react").MouseEventHandler<HTMLElement> | undefined;
50
52
  "aria-busy"?: (boolean | "true" | "false") | undefined;
51
53
  ref: (node: HTMLElement | null) => void;
@@ -12,7 +12,7 @@ import { StackHeadCtx, StackPullCtx, stackPaint, useStackCard } from '../sheets/
12
12
  * boundary). The order is the card's, never the writer's. A head of its own shape: write `<CardHead>` as the first child instead.
13
13
  * A page with one feature and one CTA may be a single card. Keep everything big.
14
14
  */
15
- export function Card({ tone, sm, row, cover, fold, centre, band, as = 'article', heading, caption, end, level, foot, footLink, stack, className, style, children, onClick, ref, ...rest }) {
15
+ export function Card({ tone, paper, sm, row, cover, fold, centre, band, as = 'article', heading, caption, end, level, foot, footLink, stack, className, style, children, onClick, ref, ...rest }) {
16
16
  const head = heading != null || caption != null || end != null;
17
17
  const tail = foot != null || footLink != null;
18
18
  if (head || tail) {
@@ -54,7 +54,7 @@ export function Card({ tone, sm, row, cover, fold, centre, band, as = 'article',
54
54
  const props = {
55
55
  ...rest,
56
56
  ref: setRef,
57
- className: cx('card', tone && tone !== 1 && `card--${tone}`, sm && 'card--sm', row && 'card--row', cover && 'card--cover', fold && 'card--fold', centre && 'card--centre', band && 'card--band', painted.className, className),
57
+ className: cx('card', tone && tone !== 1 && `card--${tone}`, paper && 'sheet--paper', sm && 'card--sm', row && 'card--row', cover && 'card--cover', fold && 'card--fold', centre && 'card--centre', band && 'card--band', painted.className, className),
58
58
  style: painted.style || style ? { ...painted.style, ...style } : undefined,
59
59
  ...(stack ? { 'aria-busy': painted.busy } : {}),
60
60
  onClick: stack ? click : onClick,
@@ -25,7 +25,7 @@ export interface SheetProps extends Omit<ComponentProps<'article'>, 'onChange'>
25
25
  mark?: 'line' | 'dots';
26
26
  /** the card tone slot, as `Card tone` — 2 and up add `card--N`. The head shows it; with `paper` the content does not */
27
27
  tone?: 1 | 2 | 3 | 4 | 5;
28
- /** the content is white paper and the head keeps the sheet's colour. Omit it and the content is the same colour as the head */
28
+ /** the content is white paper and the head keeps the sheet's colour. The same prop on a `StackSheet` or a `Card` in a stack. Omit it and the content is the same colour as the head */
29
29
  paper?: boolean;
30
30
  }
31
31
  /**
@@ -13,8 +13,10 @@ export interface StackSheetTab {
13
13
  export interface StackSheetProps extends Omit<ComponentProps<'article'>, 'title'> {
14
14
  /** the SHEET HEAD's title — an h2 (the page's h1 is its own) */
15
15
  title: ReactNode;
16
- /** the paper — see `Tone` */
16
+ /** the tone slot — see `Tone`. The head shows it */
17
17
  tone?: Tone;
18
+ /** the content is white paper and the head keeps the sheet's colour. The same look as `Sheet paper`. Omit it and the content matches the head */
19
+ paper?: boolean;
18
20
  /** the head's end when the sheet has no tabs: an Icon, an IconRow */
19
21
  icon?: ReactNode;
20
22
  /** 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 */
@@ -40,4 +42,4 @@ export interface StackSheetProps extends Omit<ComponentProps<'article'>, 'title'
40
42
  * A count shows as a small circle over its icon. The body is the app's: render the page of the chosen tab (and nothing while the sheet
41
43
  * is closed — see `Home`). A direct child of `SheetStack`.
42
44
  */
43
- export declare function StackSheet({ title, tone, icon, tabs, tab: tabProp, defaultTab, onTabChange, foot, backLabel, backAt, stack, className, children, ...rest }: StackSheetProps): import("react").JSX.Element;
45
+ export declare function StackSheet({ title, tone, paper, icon, tabs, tab: tabProp, defaultTab, onTabChange, foot, backLabel, backAt, stack, className, children, ...rest }: StackSheetProps): import("react").JSX.Element;
@@ -19,7 +19,7 @@ import { word } from '../words.js';
19
19
  * A count shows as a small circle over its icon. The body is the app's: render the page of the chosen tab (and nothing while the sheet
20
20
  * is closed — see `Home`). A direct child of `SheetStack`.
21
21
  */
22
- export function StackSheet({ title, tone, icon, tabs, tab: tabProp, defaultTab, onTabChange, foot, backLabel = word('back'), backAt = 'none', stack, className, children, ...rest }) {
22
+ export function StackSheet({ title, tone, paper, icon, tabs, tab: tabProp, defaultTab, onTabChange, foot, backLabel = word('back'), backAt = 'none', stack, className, children, ...rest }) {
23
23
  const [tab, pick] = useControlled(tabProp, defaultTab ?? tabs?.[0]?.id, onTabChange);
24
24
  // a title longer than its room does not wrap: it runs sideways, like a song title in a short slot — the room it overflows by
25
25
  // is measured here (the tabs may grow with the text size) and handed to the CSS as --_over
@@ -38,5 +38,5 @@ export function StackSheet({ title, tone, icon, tabs, tab: tabProp, defaultTab,
38
38
  measure();
39
39
  return watchSize([h, run], measure);
40
40
  }, [title]);
41
- return (_jsxs(Card, { stack: stack, tone: tone, className: cx('stack-sheet', className), ...rest, children: [_jsxs(CardHead, { children: [backAt === 'start' && _jsx(StackBack, { label: backLabel }), _jsx(Text, { level: "h2", ref: titleRef, className: cx('stack-sheet__title', long && 'is-long'), children: _jsx("span", { className: "stack-sheet__run", children: title }) }), tabs?.length ? (_jsx("span", { className: "stack-sheet__tabs", role: "tablist", children: tabs.map((t) => (_jsxs(IconBtn, { sm: true, invert: t.id === tab, role: "tab", "aria-selected": t.id === tab, label: t.label, className: "stack-sheet__tab", onClick: () => pick(t.id), children: [_jsx(Icon, { name: t.icon }), t.count ? _jsx(Badge, { className: "stack-sheet__count", children: t.count > 99 ? '99+' : t.count }) : null] }, t.id))) })) : icon, backAt === 'end' && _jsx(StackBack, { end: true, label: backLabel })] }), _jsx(SheetBody, { role: tabs?.length ? 'tabpanel' : undefined, children: children }), foot != null && _jsx(CardFoot, { children: foot })] }));
41
+ return (_jsxs(Card, { stack: stack, tone: tone, paper: paper, className: cx('stack-sheet', className), ...rest, children: [_jsxs(CardHead, { children: [backAt === 'start' && _jsx(StackBack, { label: backLabel }), _jsx(Text, { level: "h2", ref: titleRef, className: cx('stack-sheet__title', long && 'is-long'), children: _jsx("span", { className: "stack-sheet__run", children: title }) }), tabs?.length ? (_jsx("span", { className: "stack-sheet__tabs", role: "tablist", children: tabs.map((t) => (_jsxs(IconBtn, { sm: true, invert: t.id === tab, role: "tab", "aria-selected": t.id === tab, label: t.label, className: "stack-sheet__tab", onClick: () => pick(t.id), children: [_jsx(Icon, { name: t.icon }), t.count ? _jsx(Badge, { className: "stack-sheet__count", children: t.count > 99 ? '99+' : t.count }) : null] }, t.id))) })) : icon, backAt === 'end' && _jsx(StackBack, { end: true, label: backLabel })] }), _jsx(SheetBody, { role: tabs?.length ? 'tabpanel' : undefined, children: children }), foot != null && _jsx(CardFoot, { children: foot })] }));
42
42
  }
@@ -7,8 +7,10 @@ export interface HomeSheet {
7
7
  title: ReactNode;
8
8
  /** the sheet head's end when it has no tabs: an Icon, an IconRow */
9
9
  icon?: ReactNode;
10
- /** the paper — see `Tone` (default: 2, 3, 1, 2, 3 by place) */
10
+ /** the tone slot — see `Tone` (default: 2, 3, 1, 2, 3 by place). The head shows it */
11
11
  tone?: Tone;
12
+ /** white content, the head keeps `tone`. The same look as `Sheet paper` */
13
+ paper?: boolean;
12
14
  /** the sheet's pages as icon tabs in its head (a count shows as a small circle over the icon) — see `StackSheet` */
13
15
  tabs?: StackSheetTab[];
14
16
  /** the tab shown first (default: the first) */
@@ -50,5 +50,5 @@ export function Home({ top, title, sheets, open: openProp, defaultOpen = null, o
50
50
  }, [leaving]);
51
51
  const [tabs, setTabs] = useState(() => Object.fromEntries(sheets.map((x, i) => [i, x.defaultTab ?? x.tabs?.[0]?.id])));
52
52
  const shows = (i) => i === shown || i === leaving || (keep && seen.has(i));
53
- return (_jsxs(Screen, { fill: true, top: top, ...rest, children: [_jsx(Text, { level: "h1", as: "h1", sr: true, children: title }), _jsx(SheetStack, { closed: true, open: shown, onOpenChange: request, onRefresh: onRefresh, refreshing: refreshing, base: base, children: sheets.map((s, i) => (_jsx(StackSheet, { tone: s.tone ?? TONES[i], title: s.title, icon: s.icon, tabs: s.tabs, tab: tabs[i], onTabChange: (t) => setTabs((v) => ({ ...v, [i]: t })), backLabel: backLabel, backAt: backAt, foot: typeof s.foot === 'function' ? s.foot(tabs[i]) : s.foot, children: shows(i) ? (typeof s.body === 'function' ? s.body(tabs[i]) : s.body) : null }, i))) }), children] }));
53
+ return (_jsxs(Screen, { fill: true, top: top, ...rest, children: [_jsx(Text, { level: "h1", as: "h1", sr: true, children: title }), _jsx(SheetStack, { closed: true, open: shown, onOpenChange: request, onRefresh: onRefresh, refreshing: refreshing, base: base, children: sheets.map((s, i) => (_jsx(StackSheet, { tone: s.tone ?? TONES[i], paper: s.paper, title: s.title, icon: s.icon, tabs: s.tabs, tab: tabs[i], onTabChange: (t) => setTabs((v) => ({ ...v, [i]: t })), backLabel: backLabel, backAt: backAt, foot: typeof s.foot === 'function' ? s.foot(tabs[i]) : s.foot, children: shows(i) ? (typeof s.body === 'function' ? s.body(tabs[i]) : s.body) : null }, i))) }), children] }));
54
54
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usableapp/cardds",
3
- "version": "0.7.56",
3
+ "version": "0.7.58",
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.",