@cloudgrid-io/ui 0.21.0 → 0.23.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.
@@ -1,3 +1,4 @@
1
+ import * as React from "react";
1
2
  /**
2
3
  * The card an entity gets everywhere it is listed: a preview, a name, an
3
4
  * address, a line about it, whatever state it is in, and a stat or two.
@@ -31,7 +32,8 @@
31
32
  * **One recommended grid track per size**, because a card sized for a track it
32
33
  * is not in is the failure this axis exists to prevent:
33
34
  *
34
- * default the 1200/630 media card this file already was. Track:
35
+ * default the 159/92 media card this file already was, at the draft's own
36
+ * ratio (#196; it was 1200/630). Track:
35
37
  * `repeat(auto-fill, minmax(320px, 1fr))`, which is the 360px the
36
38
  * console's Discover grid renders today.
37
39
  * compact the same card at the console's 260 and 280 tracks. Track:
@@ -45,12 +47,12 @@
45
47
  * between 420 and 640 the description is truncated to a few words.
46
48
  * Under 640, `compact` is the right form — not a narrower row.
47
49
  *
48
- * **Rest and hover are identical on `default` and `compact`.** The reveal panel,
49
- * its scrim, the ink surface it declares and the tap-target rule below all carry
50
- * across unchanged. Compact reduces the type and the padding and nothing else.
50
+ * **Rest and open are identical on `default` and `compact`.** The panel, the
51
+ * white ground it lays down and the tap-target rule below all carry across
52
+ * unchanged. Compact reduces the type and the padding and nothing else.
51
53
  *
52
- * Two things compact does drop, and both are about height rather than taste. The
53
- * description is clamped to one line whatever `descriptionLines` says, and the
54
+ * Two things compact does drop, and both are about height rather than taste. Its
55
+ * panel clamps the description to one line, and on a card with no panel the
54
56
  * stats collapse to the first: at 260px a second stat wraps, which takes that
55
57
  * card a line taller than the ones beside it and breaks the row it sits in.
56
58
  *
@@ -67,17 +69,19 @@
67
69
  * rendered, on the creator's line, because the console's residence line is one
68
70
  * line and belongs next to who made the thing.
69
71
  *
70
- * ## The open mode is NOT here
72
+ * ## THE OPEN MODE IS THE PANEL
71
73
  *
72
- * #182 names a second axis as well: `open`, the card expanded in place with the
73
- * full information description unclamped, the residence grid, the owner, the
74
- * tags without navigating anywhere. It is deliberately not built. Its content
75
- * comes from Figma frames that have not been shared yet, and a mode invented
76
- * ahead of them is a second thing to unpick rather than a head start.
74
+ * #182 named a second axis and left it unbuilt, because the frames had not been
75
+ * drawn. They were, on 2026-09-09, and the founder's ruling with them: the panel
76
+ * IS the open state. There is no `mode` prop and there is nothing left parked —
77
+ * a card is at rest or it is open, and open is what hover and focus bring.
77
78
  *
78
- * The seam is `size`'s own: a `mode` prop beside it, resolved in the same place,
79
- * with `SIZE_STYLE` below gaining a column rather than this component gaining a
80
- * branch. Nothing here forecloses it, and nothing here pretends it exists.
79
+ * What that costs the rest state is the point rather than the price. At rest a
80
+ * media card is a picture, a name and a 10px dot: no line about the thing, no
81
+ * creator, no stats, no chip, no controls. All of it is in the panel, one hover
82
+ * away, and a grid of these reads as a wall of work rather than a wall of text.
83
+ * `minimal` below is where that is decided, and it is tied to whether a panel
84
+ * exists — so a card that cannot open keeps every field it ever had.
81
85
  *
82
86
  * ## Two tiers of preview, and neither can fail dark
83
87
  *
@@ -99,11 +103,13 @@
99
103
  *
100
104
  * ## The kind badge says WHAT the thing is
101
105
  *
102
- * `kind` is agent, inspiration or app, and it paints a circular badge on the
106
+ * `kind` is agent, inspiration or app, and it paints a 20px badge at the
103
107
  * preview's top-right corner — and beside the title when there is no preview to
104
108
  * put it on. Founder request 2026-09-08 (#165): the console once carried it, a
105
109
  * build dropped it, and every thumbnail had been showing the same badge
106
- * regardless of what the entity was.
110
+ * regardless of what the entity was. Redrawn to the founder's 2026-09-09 draft
111
+ * (#196): a tinted square with a 6px corner in place of a neutral disc, and
112
+ * three new marks.
107
113
  *
108
114
  * Three deliberate choices in it.
109
115
  *
@@ -114,26 +120,33 @@
114
120
  * for its ten statuses.
115
121
  *
116
122
  * The badge does NOT flip per surface, which is the identity tile's rule applied
117
- * to a mark. Its ground is `--cg-surface-raised` and its glyph is
118
- * `--cg-text-on-accent`, both declared at `:root` only, so a light disc with an
119
- * ink glyph is what renders on white, on the purple panel and on ink alike. The
120
- * alternative — a badge painted with `--cg-surface-card` and `--cg-text-primary`
121
- * — inverts to white-on-white the moment the card sits inside
122
- * `data-cg-surface="ink"`, because half of what it reads flips and the picture
123
- * under it does not. Its hairline is mixed from `--cg-ink` for the same reason:
124
- * `--cg-border-hairline` is a white wash on both dark surfaces and would leave
125
- * the badge with no edge at all.
123
+ * to a mark. Its ground is a `--cg-kind-*` tint and its glyph is
124
+ * `--cg-text-on-accent`, all four declared at `:root` only, so a tinted square
125
+ * with an ink glyph is what renders on white, on the purple panel and on ink
126
+ * alike. The alternative — a badge painted with `--cg-surface-card` and
127
+ * `--cg-text-primary` — inverts to white-on-white the moment the card sits
128
+ * inside `data-cg-surface="ink"`, because half of what it reads flips and the
129
+ * picture under it does not. The old mixed hairline is gone with the neutral
130
+ * disc: an edge existed to separate white from a light screenshot, and a tint
131
+ * over `--cg-shadow-mark` does that without drawing a line.
126
132
  *
127
133
  * The kind is announced. The glyph is `aria-hidden` and the word rides along in
128
134
  * an `sr-only` span, because "agent" is information and a decorative mark is not
129
135
  * a way to convey it.
130
136
  *
131
- * ## The hover reveal, and the rule it supersedes
137
+ * ## The panel, and the rule it supersedes
132
138
  *
133
- * `reveal` puts a panel over the preview carrying the title, one line of
134
- * description, the creator, the status and two real links: Open and Dashboard.
135
- * It shows on hover and on `:focus-within`, and it respects
136
- * `prefers-reduced-motion` by arriving without the fade rather than not at all.
139
+ * `reveal` puts a WHITE panel over the bottom of the card carrying the title,
140
+ * the state dot, two real links (Open and Dashboard), the description, the
141
+ * creator and the card's own controls. It shows on hover and on `:focus-within`,
142
+ * and it respects `prefers-reduced-motion` by arriving without the fade rather
143
+ * than not at all.
144
+ *
145
+ * It is white and not a scrim as of #196, and the dark treatment is retired for
146
+ * this card. A wash over a screenshot made the picture a texture behind grey
147
+ * text and every card looked like every other one; on white the panel is paper
148
+ * laid over the lower half of the picture, the type is the page's own ink, and
149
+ * the picture above it stays a picture.
137
150
  *
138
151
  * **The second action is Dashboard, and it is not a gear.** Founder direction
139
152
  * 2026-09-08 (#182). The door it opens is the entity's page in the console,
@@ -148,6 +161,42 @@
148
161
  * this minor and maps straight to it, so no caller breaks on the rename — see
149
162
  * the note on the prop.
150
163
  *
164
+ * ## The reveal never depends on data
165
+ *
166
+ * Founder direction, via #193 and cloudgrid-console#657: *a card whose entity
167
+ * has no serving URL still reveals, with Open disabled and a reason, never a
168
+ * whole-card link.*
169
+ *
170
+ * `revealed` therefore asks for `seed` and not for `href`. It used to ask for
171
+ * both, and the cost was not theoretical: an entity the platform is not serving
172
+ * — `charged`, `draft`, a build that has not landed — has no URL on the wire, so
173
+ * the console had no `href` to pass, so the panel silently did not mount. The
174
+ * card beside it, same page, same grid track, hovered. Two cards, one component,
175
+ * and which behaviour you got was decided by the wire.
176
+ *
177
+ * What the state changes is what is INSIDE the panel, which is the only place a
178
+ * difference belongs:
179
+ *
180
+ * Open renders as a disabled control — no `href`, `role="link"` with
181
+ * `aria-disabled="true"`, out of the tab order by construction, at
182
+ * half opacity with a not-allowed cursor. It is visibly not a live
183
+ * link and it is announced as one that cannot be used.
184
+ * the reason `openDisabledReason`, a node, above the pair. The copy is the
185
+ * product's — the console owns the state vocabulary and this
186
+ * library deliberately does not — so it arrives the way `status`
187
+ * does. §23 voice: one plain sentence, "Not serving yet."
188
+ * Dashboard unchanged as a door, and it becomes the panel's stretched hit
189
+ * area, because with Open disabled it is the only place the card
190
+ * can go. See the note on `actionPair` for why that is safe.
191
+ *
192
+ * The same rule reaches the `row`, where the reveal is the action cluster rather
193
+ * than a panel: that cluster used to be gated on `href` too, and now is not. A
194
+ * row has no panel to put a reason on and shows `status` and `meta` at rest, so
195
+ * a row's reason goes there.
196
+ *
197
+ * Nothing changes for a card that has an `href`. Every assertion written before
198
+ * #193 about the live state still holds unedited.
199
+ *
151
200
  * **This supersedes the "cards are visually static" rule of the console's
152
201
  * 2026-08-16 card spec, for the media variant only.** Founder direction
153
202
  * 2026-09-08 (#165). The rest of that rule stands and is unchanged: no lift, no
@@ -164,7 +213,9 @@
164
213
  * link surface instead: Open stretches across the whole panel with an
165
214
  * `::after`, so a click anywhere on the thumbnail opens the entity, and
166
215
  * Dashboard sits above it. Every existing caller is unaffected — `reveal`
167
- * defaults off and the wrapper behaves exactly as it did.
216
+ * defaults off and the wrapper behaves exactly as it did. (With no `href` at
217
+ * all, Open is disabled and the stretched layer moves to Dashboard — see "The
218
+ * reveal never depends on data" below.)
168
219
  *
169
220
  * **The panel stays clickable while it is invisible — except Dashboard.**
170
221
  * `opacity-0` is a paint state, not a pointer state, so a touch user with no
@@ -180,26 +231,39 @@
180
231
  * overlay is untouched, so a tap anywhere on the thumbnail — the second pill
181
232
  * included — opens the entity, and the touch fallback is exactly as it was.
182
233
  *
183
- * **It is an ink surface, declared.** The panel carries
184
- * `data-cg-surface="ink"`, so the status chip, the hairlines and the two links
185
- * inside it resolve to their on-dark values without this file knowing what any
186
- * of them are. It also declares `text-ink` itself, because text is the one thing
187
- * that does not flip by inheritance.
234
+ * **It declares the DEFAULT surface, and that is not tidiness.** The panel is
235
+ * `--cg-surface-card` with the page's ink and secondary rungs on it, 15.91:1 and
236
+ * 7:1. But `--cg-surface-card` is `transparent` inside a purple panel and a 4%
237
+ * wash on ink right for a card, fatal for something that has to cover a
238
+ * screenshot so the panel carries `data-theme="default"`, which tokens.css
239
+ * declares alongside `:root`. Every token inside it resolves to its default
240
+ * value, on every surface: paper stays paper.
188
241
  *
189
- * **The radii cannot disagree.** The preview carries `rounded-t-xl` the same
190
- * `--cg-radius-xl` the card rounds to and the panel is `inset-0` inside it
191
- * with no radius of its own, so there is no inner corner to mismatch when the
192
- * panel appears. An e2e assertion compares the two computed radii rather than
193
- * trusting that.
242
+ * **The radii cannot disagree.** The card rounds to `--cg-radius-md` and carries
243
+ * a 1px pad; the preview and the panel both round to that value less one pixel,
244
+ * written as the arithmetic rather than as a second token. An e2e assertion
245
+ * compares the computed radii rather than trusting that.
194
246
  *
195
- * ## Status is a slot
247
+ * ## Status is a slot, and on a media card it is a dot
196
248
  *
197
249
  * `status` takes a node, not a status name. `EntityStatus` is a separate
198
- * component with the nine-status CloudGrid vocabulary in it; putting that
250
+ * component with the ten-status CloudGrid vocabulary in it; putting that
199
251
  * vocabulary in the card would mean the card knows what an entity can BE, which
200
252
  * is product knowledge. The console maps its wire status through its own table
201
253
  * and drops the result in here.
202
254
  *
255
+ * A card that opens shows the state as a 10px dot instead of a chip, at the end
256
+ * of the name row and again on the panel's title row (#196). Which dot is
257
+ * `statusDot`'s answer, and usually nobody passes it: `statusDotFrom` below
258
+ * recognises the library's OWN chip and takes the state off it, so a caller
259
+ * already passing `<EntityStatus status="live" />` gets the new card with no
260
+ * edit. Anything else the card cannot read — a console chip, a string — falls
261
+ * back to rendering the node in the panel, because a state the card silently
262
+ * dropped is worse than a chip in the wrong shape.
263
+ *
264
+ * The dot is supplementary and never the only carrier: `EntityStateDot` puts the
265
+ * word inside it as `sr-only`, so the state is announced wherever it is drawn.
266
+ *
203
267
  * ## `headerActions` is the OTHER slot, and the difference is where it renders
204
268
  *
205
269
  * `status` is one node rendered in TWO places: the header row and the reveal
@@ -217,18 +281,22 @@
217
281
  * below where the design puts them for a library reason rather than a design
218
282
  * one.
219
283
  *
220
- * `headerActions` is that slot. It renders **once**, in the header row, to the
221
- * right of `status`, and never in the reveal panel. Nothing else about the card
222
- * changes and no existing caller is affected.
284
+ * `headerActions` is that slot. It renders **once** and #196 moved WHERE.
285
+ *
286
+ * On a card that opens, the controls are at the end of the panel's creator line,
287
+ * because the rest state no longer has a header row to put them in. On a text
288
+ * card and on a row they are where they always were, at the right of the header.
289
+ * One copy either way, which is the whole of #176's rule; the placement is the
290
+ * founder's, from the 2026-09-09 draft.
223
291
  *
224
292
  * Three things about it:
225
293
  *
226
- * **The panel deliberately has no equivalent.** The reveal already carries the
227
- * two actions it can carry — Open, and Dashboard and its own hit model is one
228
- * stretched anchor with a single exception lifted above it. A third control in
229
- * there would need the same `pointer-events` gating Dashboard carries, for the
230
- * same reason (#171), and would be invisible on a phone. The panel's actions are
231
- * a fixed pair by design; the header's are the caller's.
294
+ * **In the panel they carry Dashboard's gating, and for #171's reason.** They
295
+ * are lifted above Open's stretched layer with `relative z-10` so a tap on the
296
+ * save toggle reaches the toggle, and they are `pointer-events-none` until the
297
+ * panel is revealed invisible at rest means inert at rest, or the card has a
298
+ * region that behaves differently from every pixel around it with nothing to
299
+ * see.
232
300
  *
233
301
  * **Interactive controls inside a whole-card link are the caller's problem, and
234
302
  * they are a real one.** With `href` set and `reveal` off, this card is wrapped
@@ -247,10 +315,10 @@
247
315
  *
248
316
  * ## Surfaces
249
317
  *
250
- * The chrome flips: ground, hairlines, title, body text and the stat rule all
251
- * come from tokens, so `data-cg-surface="panel"` on any ancestor moves them
252
- * together. The identity tile and the kind badge deliberately do not flip — see
253
- * their notes; they are pictures, and a picture does not flip.
318
+ * The chrome flips: ground, hairlines, title, body text, the stat rule and the
319
+ * panel all come from tokens, so `data-cg-surface="panel"` on any ancestor moves
320
+ * them together. The identity tile and the kind badge deliberately do not flip —
321
+ * see their notes; they are pictures, and a picture does not flip.
254
322
  */
255
323
  export interface EntityCardStat {
256
324
  /**
@@ -288,6 +356,25 @@ export declare const ENTITY_KIND_ICON: Record<EntityKind, React.ComponentType<{
288
356
  * Plain nouns, no adjective: this names a thing, it does not sell it.
289
357
  */
290
358
  export declare const ENTITY_KIND_LABEL: Record<EntityKind, string>;
359
+ /**
360
+ * THE TINTS. What a kind's badge sits on.
361
+ *
362
+ * A third table beside the marks and the words, added with the founder's
363
+ * 2026-09-09 draft (#196): the badge used to be one neutral disc for all three
364
+ * kinds, so the mark was the only thing telling them apart and it is 16px wide.
365
+ * A tint is legible from across a listing; a glyph is not.
366
+ *
367
+ * Every entry is a utility over a `--cg-kind-*` token, and those three are
368
+ * declared at `:root` ONLY. That is the identity tile's rule applied to a mark:
369
+ * the badge sits on a screenshot, and a picture does not flip. The glyph stays
370
+ * `--cg-text-on-accent`, which is ink at every scope, and it measures 12.74:1,
371
+ * 14.65:1 and 10.24:1 on the three grounds.
372
+ *
373
+ * `agent` is a PROPOSAL. The draft never draws an agent badge; #d1c9ff is its
374
+ * own "Secondary2 30" style, which is the nearest thing in the same set to the
375
+ * two it does draw. Founder may veto, and a veto is one value in tokens.
376
+ */
377
+ export declare const ENTITY_KIND_TINT: Record<EntityKind, string>;
291
378
  /**
292
379
  * The sizes, in the order they get smaller. Read from the console census
293
380
  * (2026-09-08) rather than invented: `default` is the 360px track, `compact`
@@ -304,21 +391,44 @@ export type EntityCardSize = (typeof ENTITY_CARD_SIZE_ORDER)[number];
304
391
  * The kind badge on its own, exported because a listing header, a detail page or
305
392
  * a row may want the same mark without a card around it.
306
393
  *
307
- * `size` is the only variant: `md` is the 28px disc that sits on a preview,
308
- * `sm` the 20px one that sits beside a title. Both render a 16px-class glyph,
309
- * which is what the marks were picked to survive.
394
+ * 20 x 20 at a 6px corner with a 16px glyph, tinted per kind, lifted off the
395
+ * picture by `shadow-mark` the founder's 2026-09-09 draft (#196). It was a
396
+ * 28px neutral disc with a mixed hairline; what changed is that the ground now
397
+ * says which kind it is and the mark is small enough to stop competing with the
398
+ * thumbnail it sits on.
399
+ *
400
+ * `size` is the only variant: `md` is the badge that sits on a preview, `sm` the
401
+ * 16px one that sits beside a title, where a 20px disc leads the line rather
402
+ * than following it.
403
+ *
404
+ * The badge does NOT flip per surface, and that is the identity tile's rule
405
+ * applied to a mark. Its ground is a `--cg-kind-*` tint and its glyph is
406
+ * `--cg-text-on-accent`, all four declared at `:root` only, so a tinted square
407
+ * with an ink glyph is what renders on white, on the purple panel and on ink
408
+ * alike. The alternative — a badge painted with `--cg-surface-card` and
409
+ * `--cg-text-primary` — inverts to white-on-white the moment the card sits
410
+ * inside `data-cg-surface="ink"`, because half of what it reads flips and the
411
+ * picture under it does not.
412
+ *
413
+ * The hairline is gone with the neutral disc: an edge existed to separate a
414
+ * white disc from a light screenshot, and a tint plus a drop shadow does that
415
+ * job without drawing a line the draft does not have.
416
+ *
417
+ * The kind is announced. The glyph is `aria-hidden` and the word rides along in
418
+ * an `sr-only` span, because "agent" is information and a decorative mark is not
419
+ * a way to convey it.
310
420
  */
311
421
  declare function EntityKindBadge({ kind, size, className, ...props }: Omit<React.ComponentProps<"span">, "children"> & {
312
422
  kind: EntityKind;
313
423
  size?: "sm" | "md";
314
- }): import("react").JSX.Element;
315
- declare function EntityCard({ title, slug, description, size, titleLines, descriptionLines, status, headerActions, stats, seed, previewUrl, kind, reveal, dashboardHref, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }: Omit<React.ComponentProps<"div">, "ref" | "title"> & {
424
+ }): React.JSX.Element;
425
+ declare function EntityCard({ title, slug, description, size, titleLines, descriptionLines, status, statusDot, headerActions, stats, seed, previewUrl, kind, reveal, openDisabledReason, dashboardHref, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }: Omit<React.ComponentProps<"div">, "ref" | "title"> & {
316
426
  title: string;
317
427
  /** The entity's address, in the mono utility face. */
318
428
  slug?: string;
319
429
  description?: string;
320
430
  /**
321
- * How big, and which way up. `default` is the 1200/630 media card, `compact`
431
+ * How big, and which way up. `default` is the 159/92 media card, `compact`
322
432
  * the same card at the console's 260 and 280 tracks, `row` the horizontal
323
433
  * list form. See the note at the top of this file for the grid track each one
324
434
  * is meant for, and for what `row` deliberately does differently.
@@ -332,15 +442,35 @@ declare function EntityCard({ title, slug, description, size, titleLines, descri
332
442
  */
333
443
  descriptionLines?: 1 | 2;
334
444
  /**
335
- * Top right of the header row, and ALSO inside the reveal panel. One node,
336
- * two places, so it can only carry something true in both: drop an
337
- * `EntityStatus` in. Row controls go in `headerActions`.
445
+ * What the entity currently IS, as a node. Drop an `EntityStatus` in.
446
+ *
447
+ * Where it renders depends on the form the card takes. On a `row`, and on a
448
+ * card with no reveal panel, it is the chip it always was, at the right of the
449
+ * header row. On a card that HAS a panel it becomes a dot (#196) — see
450
+ * `statusDot`, which is what the dot is read from.
338
451
  */
339
452
  status?: React.ReactNode;
340
453
  /**
341
- * The header row's own controls a save toggle, an overflow menu to the
342
- * right of `status`. Rendered **once**, in the header, never in the reveal
343
- * panel (#176).
454
+ * The state as a 10px dot, for the two places the founder's card shows one:
455
+ * the name row at rest and the panel's title row (#196).
456
+ *
457
+ * Usually you do not pass this. If `status` is an `EntityStatus`, the card
458
+ * derives the dot from it, so a caller who already passes the library's chip
459
+ * gets the new card with no edit. Pass it explicitly when your state chip is
460
+ * your own — `EntityStateDot` is exported for exactly that — or when the card
461
+ * should show a dot and no chip anywhere.
462
+ *
463
+ * With neither a dot nor a derivable one, a panel falls back to rendering the
464
+ * `status` node itself, and the rest row shows nothing rather than a chip.
465
+ */
466
+ statusDot?: React.ReactNode;
467
+ /**
468
+ * The card's own controls — a save toggle, an overflow menu.
469
+ *
470
+ * They render **once**, and where depends on the form again: in the header row
471
+ * on a text card and on a row, and INSIDE the panel, at the end of the
472
+ * creator's line, on a card that reveals (#196, superseding #176's placement
473
+ * while keeping its rule — one copy, never two).
344
474
  *
345
475
  * Read the note above before passing an interactive control together with
346
476
  * `href`: this card wraps itself in an anchor, and it cannot intercept the
@@ -367,16 +497,39 @@ declare function EntityCard({ title, slug, description, size, titleLines, descri
367
497
  */
368
498
  kind?: EntityKind;
369
499
  /**
370
- * Turns the hover reveal on. Needs `seed`, since the panel covers the preview.
500
+ * Turns the hover reveal on. Needs `seed`, since the panel covers the preview,
501
+ * and nothing else — an `href` is NOT required (#193). A card whose entity is
502
+ * not being served reveals exactly like the card beside it, with Open
503
+ * disabled.
371
504
  *
372
505
  * Off by default, and it changes what `href` does: a revealed card is NOT
373
506
  * wrapped in a whole-card link, because the panel's own actions are anchors
374
507
  * and an anchor inside an anchor is invalid HTML. See the note above.
375
508
  */
376
509
  reveal?: boolean;
510
+ /**
511
+ * Why Open cannot be used, shown on the reveal panel above the actions and
512
+ * announced as the disabled control's own reason. Read **only when there is no
513
+ * `href`**; a card that can be opened has nothing to explain.
514
+ *
515
+ * A node, the way `status` is, because the copy is the product's. The console
516
+ * has a state vocabulary — "Not serving yet.", and the eight others — and this
517
+ * library deliberately does not know it. One sentence in §23 voice; pass text
518
+ * rather than a control, since the visible copy is `aria-hidden` so the
519
+ * announcement can ride on Open instead of arriving twice.
520
+ *
521
+ * Not rendered on a `row`: a row has no panel, and it already shows `status`
522
+ * and `meta` at rest, which is where a row's reason belongs.
523
+ */
524
+ openDisabledReason?: React.ReactNode;
377
525
  /**
378
526
  * The Dashboard action's target: the entity's page in the console, where the
379
- * analytics and what runs under the hood live. Only read when `reveal` is on.
527
+ * analytics and what runs under the hood live.
528
+ *
529
+ * Read wherever the action pair renders — the panel on a stacked card, the end
530
+ * of the cluster on a `row` (#182). It is load-bearing rather than decorative
531
+ * when there is no `href`: it is then the card's only door, and the one that
532
+ * takes the stretched hit area (#193).
380
533
  */
381
534
  dashboardHref?: string;
382
535
  /**
@@ -411,6 +564,6 @@ declare function EntityCard({ title, slug, description, size, titleLines, descri
411
564
  footer?: React.ReactNode;
412
565
  /** Replaces the whole body. The preview and the card chrome still render. */
413
566
  children?: React.ReactNode;
414
- }): import("react").JSX.Element;
567
+ }): React.JSX.Element;
415
568
  export { EntityCard, EntityKindBadge };
416
569
  //# sourceMappingURL=entity-card.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity-card.d.ts","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity-card.d.ts","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":"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"}