@crewlethq/ui 0.35.1 → 0.36.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.
Files changed (164) hide show
  1. package/README.md +73 -0
  2. package/dist/AgentHandoffPanel/AgentHandoffPanel.d.ts +99 -0
  3. package/dist/AgentHandoffPanel/index.d.ts +3 -0
  4. package/dist/AgentHandoffPanel/index.js +16 -0
  5. package/dist/AgentHandoffPanel-JWSW62GU.css +151 -0
  6. package/dist/ArrangeFrame/index.js +1 -1
  7. package/dist/{ArrangeFrame-3PLZAG22.css → ArrangeFrame-QXOQTFAH.css} +22 -5
  8. package/dist/ArrangeList/index.js +4 -3
  9. package/dist/ArtifactBar/ArtifactBar.d.ts +2 -1
  10. package/dist/ArtifactBar/index.js +2 -2
  11. package/dist/{ArtifactBar-HV5AT4RG.css → ArtifactBar-FWPBBKQ5.css} +8 -0
  12. package/dist/ArtifactCard/index.js +3 -3
  13. package/dist/ArtifactCover/index.js +3 -2
  14. package/dist/ArtifactKindIllustration/ArtifactKindIllustration.d.ts +16 -7
  15. package/dist/ArtifactKindIllustration/index.js +1 -1
  16. package/dist/{ArtifactKindIllustration-5FPRJQ3P.css → ArtifactKindIllustration-5KTP43QS.css} +36 -0
  17. package/dist/ArtifactMakeRow/ArtifactMakeRow.d.ts +39 -0
  18. package/dist/ArtifactMakeRow/index.d.ts +4 -0
  19. package/dist/ArtifactMakeRow/index.js +4 -0
  20. package/dist/ArtifactMakeRow-RWUTS5MC.css +167 -0
  21. package/dist/ArtifactPanel/ArtifactPanel.d.ts +8 -1
  22. package/dist/ArtifactPanel/index.js +1 -1
  23. package/dist/{ArtifactPanel-HW3SU7CP.css → ArtifactPanel-KKUUIPEU.css} +9 -0
  24. package/dist/AuthLayout/index.js +2 -2
  25. package/dist/AvatarPicker/index.js +2 -2
  26. package/dist/Canvas/index.js +2 -2
  27. package/dist/CanvasBoard/CanvasBoard.d.ts +27 -13
  28. package/dist/CanvasBoard/index.d.ts +1 -1
  29. package/dist/CanvasBoard/index.js +4 -4
  30. package/dist/{CanvasBoard-5NNSKY6A.css → CanvasBoard-TS4P356F.css} +13 -6
  31. package/dist/CanvasToolbar/index.js +3 -3
  32. package/dist/Card/index.js +1 -1
  33. package/dist/{Card-KJOYHDTJ.css → Card-QOVASQNU.css} +17 -12
  34. package/dist/Checkbox/index.js +3 -2
  35. package/dist/ChoiceButtons/index.js +1 -1
  36. package/dist/{ChoiceButtons-DJ5EOGUA.css → ChoiceButtons-FLIFXFFS.css} +10 -0
  37. package/dist/ChoiceList/index.js +1 -1
  38. package/dist/{ChoiceList-RBL7FNQL.css → ChoiceList-EA2W6MOS.css} +36 -5
  39. package/dist/Combobox/index.js +3 -2
  40. package/dist/CommandPalette/index.js +3 -2
  41. package/dist/CommentThread/index.js +6 -5
  42. package/dist/Composer/Composer.d.ts +4 -0
  43. package/dist/Composer/index.js +3 -2
  44. package/dist/{Composer-ABGJIAIR.css → Composer-PXITWNEK.css} +26 -15
  45. package/dist/ConfirmField/index.js +3 -2
  46. package/dist/DataTable/index.js +5 -4
  47. package/dist/DataView/index.js +9 -8
  48. package/dist/DatasetSource/DatasetSource.d.ts +4 -0
  49. package/dist/DatasetSource/index.js +1 -1
  50. package/dist/{DatasetSource-XFPZBRXL.css → DatasetSource-SMGX4PS5.css} +38 -4
  51. package/dist/DateTimePicker/index.js +2 -1
  52. package/dist/{DateTimePicker-HG2KQXQ6.css → DateTimePicker-2IVTKFV2.css} +15 -2
  53. package/dist/DocTabsEditor/index.js +4 -3
  54. package/dist/Document/Document.d.ts +15 -3
  55. package/dist/Document/index.js +2 -1
  56. package/dist/{Document-JUGCSQ4L.css → Document-YFWTWXJP.css} +34 -2
  57. package/dist/{Editor-BVQHBF7L.js → Editor-HORWMUM3.js} +2 -1
  58. package/dist/FilterChip/index.js +1 -1
  59. package/dist/{FilterChip-EZ4QMW4E.css → FilterChip-VL33P3JL.css} +5 -1
  60. package/dist/Input/index.js +2 -1
  61. package/dist/{Input-GBZSFXLU.css → Input-ABGOFENS.css} +46 -10
  62. package/dist/LayersList/index.js +1 -1
  63. package/dist/{LayersList-NQZEIPZB.css → LayersList-TBNF4XGL.css} +16 -3
  64. package/dist/LinkInterstitial/index.js +2 -2
  65. package/dist/ListInput/index.js +4 -3
  66. package/dist/LivePreview/LivePreview.d.ts +105 -25
  67. package/dist/LivePreview/budget.d.ts +64 -20
  68. package/dist/LivePreview/index.d.ts +5 -3
  69. package/dist/LivePreview/index.js +1 -1
  70. package/dist/LivePreview/stills.d.ts +57 -0
  71. package/dist/LivePreview-BROGKR4N.css +113 -0
  72. package/dist/PresenterView/index.js +2 -2
  73. package/dist/PrincipalPicker/index.js +4 -3
  74. package/dist/RichEditor/index.js +1 -1
  75. package/dist/Select/index.js +2 -1
  76. package/dist/{Select-A54YS5EP.css → Select-W3CHTZXP.css} +18 -2
  77. package/dist/ShareDialog/index.js +5 -4
  78. package/dist/SheetColumnEditor/index.js +6 -5
  79. package/dist/SheetGrid/index.js +4 -4
  80. package/dist/SlideCompare/index.js +2 -2
  81. package/dist/SlideFilmstrip/index.js +3 -3
  82. package/dist/{SlideFilmstrip-4ITZLMO4.css → SlideFilmstrip-PAT7P4OG.css} +26 -7
  83. package/dist/SlideGrid/index.js +2 -2
  84. package/dist/{SlideGrid-S4LTJ4UU.css → SlideGrid-FJA33DV4.css} +11 -1
  85. package/dist/SlideStage/index.js +1 -1
  86. package/dist/{SlideStage-S2FISF4C.css → SlideStage-ZTTEQSS2.css} +4 -2
  87. package/dist/SourceEditor/index.js +2 -1
  88. package/dist/{SourceEditor-G2C3STPX.css → SourceEditor-QAYE2JS6.css} +19 -12
  89. package/dist/Switcher/index.js +5 -4
  90. package/dist/TagsInput/index.js +3 -2
  91. package/dist/{TagsInput-XMXTI5Q4.css → TagsInput-7EGBBXHS.css} +7 -1
  92. package/dist/ThemeGallery/index.js +1 -1
  93. package/dist/{ThemeGallery-HSUKBDWY.css → ThemeGallery-X35Y25EX.css} +26 -5
  94. package/dist/TimeWindowPicker/index.js +4 -3
  95. package/dist/{TimeWindowPicker-T763GLXH.css → TimeWindowPicker-DEFDV77Z.css} +15 -2
  96. package/dist/TreeCanvas/index.js +3 -3
  97. package/dist/VersionTimeline/index.js +2 -2
  98. package/dist/{chunk-V43UVX4H.js → chunk-27GD7LVR.js} +1 -1
  99. package/dist/{chunk-CCLNGVCM.js → chunk-2DV4THNQ.js} +2 -2
  100. package/dist/{chunk-2CQLNML5.js → chunk-3PTUDKSR.js} +4 -2
  101. package/dist/{chunk-ONL54WMH.js → chunk-46RL3E54.js} +1 -1
  102. package/dist/{chunk-UHJQDFKQ.js → chunk-4ZJLOKSS.js} +1 -1
  103. package/dist/{chunk-ACA27MZH.js → chunk-5QXRI35B.js} +1 -1
  104. package/dist/{chunk-LL5AFXU7.js → chunk-5RT5O4JR.js} +1 -1
  105. package/dist/chunk-66ADEPFB.js +51 -0
  106. package/dist/{chunk-3Y56GQPM.js → chunk-7VAUGG6B.js} +1 -1
  107. package/dist/{chunk-NKZCJRKO.js → chunk-APDKUGSH.js} +2 -2
  108. package/dist/{chunk-YSJC7AZC.js → chunk-BWOIUOO3.js} +1 -1
  109. package/dist/{chunk-PI7HKLIT.js → chunk-D7GNNID2.js} +3 -1
  110. package/dist/{chunk-THROPJZC.js → chunk-DEMALFHY.js} +1 -1
  111. package/dist/chunk-EOQFPZEE.js +138 -0
  112. package/dist/{chunk-QFNWMWWY.js → chunk-ES4RKQ7B.js} +4 -4
  113. package/dist/{chunk-J6YZ4IYV.js → chunk-FG4O64DV.js} +3 -3
  114. package/dist/{chunk-E35CMI5D.js → chunk-FHHYXZSP.js} +31 -13
  115. package/dist/{chunk-AYB6AYNH.js → chunk-GMLAKNFY.js} +1 -1
  116. package/dist/{chunk-ZB5O3ELS.js → chunk-GRYZ5EP3.js} +4 -2
  117. package/dist/{chunk-ILAEBSLJ.js → chunk-H5NOLRGH.js} +2 -2
  118. package/dist/{chunk-W3UVOZKL.js → chunk-IPAU6FLH.js} +6 -2
  119. package/dist/{chunk-Z6VW6CXX.js → chunk-IQH3DDZ2.js} +2 -2
  120. package/dist/{chunk-6QFAK2WV.js → chunk-IUYUS2SO.js} +4 -1
  121. package/dist/{chunk-AXBRWRGV.js → chunk-JQLS3MZB.js} +1 -1
  122. package/dist/{chunk-FGYET26P.js → chunk-KJW2AS57.js} +1 -1
  123. package/dist/{chunk-QIXMNOBD.js → chunk-KYZMN6I6.js} +2 -2
  124. package/dist/{chunk-73A7D5CE.js → chunk-L4WZSVMT.js} +3 -1
  125. package/dist/{chunk-W7QBBKUE.js → chunk-MJW6SQYB.js} +7 -3
  126. package/dist/{chunk-GMU6SQ6B.js → chunk-MRMHZ437.js} +3 -3
  127. package/dist/{chunk-ULPL26BU.js → chunk-N5SKHIAP.js} +1 -1
  128. package/dist/{chunk-LV4APO72.js → chunk-NQGPD6NX.js} +1 -1
  129. package/dist/{chunk-7UYONN6K.js → chunk-OSZDHN5Z.js} +2 -2
  130. package/dist/chunk-P6WFZDKS.js +111 -0
  131. package/dist/{chunk-CPEPST4S.js → chunk-PJIPUEJ3.js} +1 -1
  132. package/dist/{chunk-QS4ZGTEU.js → chunk-PPFX6GRK.js} +1 -1
  133. package/dist/{chunk-7DZDSSJS.js → chunk-RH2NCQBZ.js} +5 -4
  134. package/dist/{chunk-3VD3G3IL.js → chunk-T5RQGI6O.js} +1 -1
  135. package/dist/{chunk-F2KY4RLI.js → chunk-TVRBQMIX.js} +5 -3
  136. package/dist/{chunk-QEFHYUCY.js → chunk-UWGUKMBK.js} +1 -1
  137. package/dist/{chunk-5YLON2PW.js → chunk-UYZZV4DZ.js} +1 -1
  138. package/dist/{chunk-BQ7AKL2N.js → chunk-VKKUGZ3G.js} +3 -1
  139. package/dist/{chunk-DEJHAOC5.js → chunk-WMXAX6VA.js} +1 -1
  140. package/dist/{chunk-6JVRY5DQ.js → chunk-WNAYQQ6Y.js} +2 -2
  141. package/dist/{chunk-VDPJGP4Q.js → chunk-WX2NIG4G.js} +1 -1
  142. package/dist/{chunk-ZU3DUXD2.js → chunk-WZGYIVYH.js} +1 -1
  143. package/dist/chunk-XGBLRDSU.js +446 -0
  144. package/dist/{chunk-22CQQDFW.js → chunk-XMRTFPWX.js} +2 -2
  145. package/dist/{chunk-HUVG2FFT.js → chunk-Y5BD4MTE.js} +4 -2
  146. package/dist/chunk-YSGLEHND.js +56 -0
  147. package/dist/generated/index.d.ts +2 -0
  148. package/dist/generated/index.js +95 -92
  149. package/dist/index.js +95 -92
  150. package/dist/styles.css +862 -130
  151. package/dist/utils/focusModality.d.ts +41 -0
  152. package/dist/utils/index.d.ts +2 -0
  153. package/dist/utils/index.js +2 -1
  154. package/package.json +3 -3
  155. package/dist/LivePreview-SRO7KHO4.css +0 -65
  156. package/dist/chunk-KF6YGL4B.js +0 -160
  157. package/dist/chunk-TYKQ33CL.js +0 -35
  158. package/dist/{chunk-3P4Y5RX6.js → chunk-4BYHAOHH.js} +1 -1
  159. package/dist/{chunk-3WCNHYXE.js → chunk-5BP6IS3N.js} +0 -0
  160. package/dist/{chunk-KD2IRYCT.js → chunk-5WDXPHEW.js} +1 -1
  161. package/dist/{chunk-OSFA5ROT.js → chunk-FEJANUZK.js} +0 -0
  162. package/dist/{chunk-FJJHD73S.js → chunk-GYBDPCRC.js} +1 -1
  163. package/dist/{chunk-VHZ3AXJD.js → chunk-NQCY44B3.js} +1 -1
  164. package/dist/{chunk-FF5OZV77.js → chunk-W3HYWD63.js} +2 -2
package/README.md CHANGED
@@ -204,6 +204,79 @@ places:
204
204
  - A surface that pans or zooms dispatches `LAYER_REPOSITION_EVENT` on its host
205
205
  when the content beneath it moves, and every panel anchored inside follows.
206
206
 
207
+ ## Changes in 0.36.0
208
+
209
+ ### New on a create page and in the gallery
210
+
211
+ **`AgentHandoffPanel` hands the work to an agent beside what is being made.** A create page is the direct way to make something; asking an agent is a panel at its side rather than a mode that swaps the page for a form, so a person can lay out a slide, ask, and lay out another. It is an `ArtifactPanel` (titled "Ask an agent"), so inside an `ArtifactWorkspace` it is a column where there is room, a drawer over the page's end where there is not, and the screen on a phone. Top to bottom: an `intro` line, the brief (a `Composer` with its visible `briefLabel`, `briefPlaceholder`, `briefHelper` and `briefMaxLength`), `starters` offered as one-press chips while the brief is empty (`onStarter`), the kind's own fields (`children`), **Who builds it** (`agent`, the host's picker), **Goes with it** (`carried`: what the reader already made, each with an icon, a label and a detail) with the task exactly as it is filed behind a disclosure (`task`), and **What happens next** (`steps`, a `Timeline`). A `notice` (a refusal) sits above the commit. The commit is the panel's foot (`send`: its label, the chosen agent's picture as `media`, `busy` and `disabledReason`), always in reach however far the panel scrolls; a held send says why in words beside the button as well as in its tooltip, and the picture is hidden from the button's name. Command+Enter from any field in the panel sends, and the press is answered there, so a page-wide shortcut behind the panel never also fires. Every heading and label is in `labels` (`AGENT_HANDOFF_LABELS`).
212
+
213
+ **An artifact panel takes a `footer`** (`ArtifactPanel`): what stays under the body however far it scrolls, on a hairline at the panel's foot and outside the scrolling body, such as a hand-off's Send. A panel without one is unchanged.
214
+
215
+ **`ArtifactMakeRow` is the gallery's Make something new row, a quiet tray rather than a row of pictures.** Each kind is its glyph on the kind's own tint, its name and a few words on what it is for (`detail`), the whole item one link named by the kind with the words as its description; with `disabledReason` an item stays a focusable stop that says why it cannot start one. The tray is Crewlet's dotted field in a hairline ring, and an item lifts off it as a card under the pointer while nothing inside it moves. It lays itself out by its own width: under 560px three across in two lines, each mark over its name; from 560px the six in one line, still mark over name, so a long name is never cut; from 920px the mark beside the name with what the kind is for under it. At 1440 the row is 52px tall where the tiles were 166px. `ArtifactKindTile` stays, for a create page's starting points.
216
+
217
+ ### Chosen options and focus
218
+
219
+ **A chosen option is calm, and the focus ring is the one accent line on a page.** Two tokens name what a chosen option draws: `--color-border-selected`, the accent at 0.6 (the full accent in a high-contrast theme), so a tint mixed toward its ground, and `--color-surface-selected`, the soft fill. Every component that marks a pick takes them, at one pixel, and pairs them with a mark of its own that clears 3:1, so the state never rests on the tint:
220
+
221
+ - `ThemeGallery`: the chosen card's edge is the selected edge over the selected fill, and a check stands beside its name. It was a full accent border.
222
+ - `SlideFilmstrip` and `SlideGrid`: the slide being edited keeps its one-pixel edge in the selected edge, with the selected fill as a 3px band outside it, and its number in the accent ink. It was a 2px ring in the full accent, the focus ring's weight and colour.
223
+ - `DatasetSource`: an open source is one card. The selected edge rings the whole entry, its preview included, over the selected fill on its summary, which is the card's head; the preview is a well under it on the inset ground, parted from the head by one line in the same edge, so the settings and figures it shows read as the entry's own rather than as loose items of the rail. It was the full accent around the summary alone. Selected without a preview it is the selected edge and fill around the summary; closed, it is unchanged.
224
+ - `ChoiceList` and `LayersList`: the picked row stands on the selected fill. A layer used to take the accent rail of a current row (the outline's heading, the page in the rail), which beside a canvas read as a second selection; the rail's room is kept, and forced colours draw it in `Highlight`.
225
+ - `SlideFilmstrip`'s focus ring grows outward from the thumbnail's edge. It sat on the inset offset, inside the thumbnail, where a dark slide swallowed it and tabbing through the strip showed nothing.
226
+ - `Card`: a chosen card (`selected`) takes the selected edge over the selected fill, laid over its own surface. It was the full accent border under `--shadow-selection`, a second 2px accent ring.
227
+ - `ArtifactKindTile`: a tile that is a button takes `selected` (announced as a pressed button): the selected edge on its frame over the selected fill, and a check beside its name. Its ground no longer draws a tinted inner line, which with the frame's edge and the focus ring read as three nested rings; the frame is the tile's one edge.
228
+ - `ArrangeFrame`: the block under the pointer, or holding focus in one of its fields, takes the selected edge; the block itself in keyboard focus takes a 2px focus ring (it was one pixel); a picked or resizing block keeps one crisp pixel of the accent.
229
+ - `FilterChip`: a pressed chip stands on the selected fill, keeping its lighter line and the accent ink.
230
+ - `ChoiceList`: the radio is drawn rather than the platform's, an empty ring on the control boundary until chosen and an accent dot when it is, because the platform's dark radio filled every unchosen answer with a grey disc that read as a second choice; forced colours hand it back to the platform. A tag ("Suggested") is set in the tertiary ink, no longer a second accent mark on the chosen row.
231
+ - `SlideFilmstrip`'s thumbnails take the strong line at rest and its hover step under the pointer: on the dark page the plain hairline left a strip of dark slides with no edges.
232
+ - `CanvasBoard`: hover is one screen pixel of the selected edge, and a pick one crisp pixel of the full accent with its four corners. It was two pixels, so a picked board and the live board ([data-active], which keeps the 2px focus ring) read alike.
233
+
234
+ **A field rings at 2px for the keyboard and at its own hairline for a pointer.** `trackFocusModality` (and `useFocusModality`, exported with `FOCUS_MODALITY_ATTRIBUTE`) writes `data-crewlet-focus="keyboard" | "pointer"` on the root: Tab, or any key pressed outside a text-entry control, is the keyboard, a pointer press is the pointer, and typing in a field is neither. Every field (`Input`, `Textarea`, `Select` and its search box, `TagsInput`, `DateTimePicker`, `TimeWindowPicker`, `Composer`, `DocumentTitleField`) starts it while mounted, and an application may call `trackFocusModality()` at boot so the first key a reader presses is seen before any field mounts. A boxed field's ring is now 2px in `--color-focus` over its boundary, the area WCAG 2.2's focus appearance asks of a keyboard indicator, and where a pointer put the caret it narrows to one pixel in `--color-border-selected`, so a page that focuses its first field on load no longer rings it in the focus colour before anybody has touched a key. A refused field keeps its danger colour under either. A document that tracks nothing keeps the 2px ring. `Input.test.tsx` holds every boxed ring to one narrowing rule. `SourceEditor` rings as a field does too, in place of its accent border and soft halo.
235
+
236
+ **`Composer` rings as a field does.** Its box takes the field ring above, keyed on the field so tabbing onto the send action shows that button's ring. It used to recolour its border to the accent and lay a 2px soft halo outside it: two highlights for one state.
237
+
238
+ **A composer's footer is drawn only with something in it** (`Composer`). With no send shortcut, counter or actions there is no strip under the field, and a footer holding only the shortcut's hint goes on a phone, where the hint is not drawn, instead of leaving an empty strip. A footer with actions or a counter stays on every width.
239
+
240
+ ### Titles
241
+
242
+ **`DocumentTitleField` wraps.** It is a textarea of one row that grows with the title, so a long title, or a long example in its placeholder, wraps on a phone as the title it becomes does, where the input it replaced cut it mid-word. It is still one line of text: Enter inserts nothing (its keydown reaches the caller and the page as an input's does, and in a form with a submit button it submits, as an input's Enter does), a pasted, dropped or autofilled line break becomes a space before `onChange` reads the value, and it is named to assistive technology as a single-line field (`aria-multiline="false"`). It forwards a ref to the textarea. A caller that typed its handlers or ref for `HTMLInputElement` types them for `HTMLTextAreaElement`.
243
+
244
+ **`DocumentTitleField` underlines in a tint for a pointer and in two focus pixels for the keyboard.** The line along its foot is one pixel (the hairline under the pointer, the selected edge once a click has put the caret in it), and two pixels in the focus colour for the keyboard, drawn as the border and a shadow under it with a transparent outline that forced colours paint. The padding takes the pixel the border no longer reserves, so the title sits where it did. A page that focuses its title on load no longer draws a 2px accent bar under it before anybody has touched anything.
245
+
246
+ ### Live previews
247
+
248
+ **A live preview is a snapshot: rendered once, then a still copy with nothing live behind it** (`LivePreview`). Scrolling a gallery up and down tore every card down as it left and drew it again from its stand-in as it came back, so the kind's drawing flickered over content the reader had just seen, and every redraw read its data again. Now the content renders once, out of sight behind the stand-in; when it calls `useLivePreview().ready()` and the page's fonts have loaded, what it drew is copied (its DOM, cloned: a canvas as an image of what it drew, and nothing that would load again, such as a frame, a video or an embedded object), the copy fades in over the stand-in, which is hidden only once the fade is done (fading both at once showed a double exposure), and the content is unmounted in the same commit. From then on the preview holds no React tree, query, subscription, observer of its own or timer, and it never reads, polls or redraws again; nothing inside a copy animates. A copy laid out at `width` is rescaled when its box changes size by one ResizeObserver the provider shares; one with no `width` is drawn again only if its box changes size. A render that has not drawn within `LIVE_PREVIEW_RENDER_MS` (15 seconds, past the ten a framed page is given to answer) gives up and keeps its stand-in.
249
+
250
+ **A snapshot is kept by key for the provider's life** (`snapshot`, new). Previews under one `LivePreviewBudgetProvider` with the same key share one copy, so a card mounted again (a filter, a change of shape, a page of results) shows it at once with nothing read or rendered, and no fade. A key names a version of the content: a new key is a new snapshot, and a provider mounted afresh (the page loaded again) takes new ones. The provider keeps up to `LIVE_PREVIEW_STILLS_KEPT` copies (200, four pages of a listing at fifty; `kept` changes it), the one used longest ago dropped first. A preview that failed is remembered under its key too. `createLivePreviewStills` is the store, exported for a host that measures.
251
+
252
+ **A frame is kept, not copied** (`frame`). A page in a frame lives in another document, which nothing can clone and a clone of the frame would load again, so a framed preview keeps its frame once drawn and fades it in. Kept frames are capped apart (`LIVE_PREVIEW_MAX_FRAMES`, twelve, the pages a design's canvas runs at once): one the reader has left is parked, and taken back only when a frame coming near needs its place, the one left longest ago first; one on screen is never taken back for another.
253
+
254
+ **The budget bounds renders at once, six by default** (`LIVE_PREVIEW_MAX`, from twelve). A slot is held only while content renders, and given to the next box the moment the content says it has drawn, so six is enough for any gallery: six is the number of connections a browser opens to one host over HTTP/1.1, which is how a preview's reads reach their server, so a seventh render would only queue behind them. `LivePreviewBudgetProvider` takes `maxFrames` and `kept` beside `max`.
255
+
256
+ **A preview starts a screen ahead** (`LIVE_PREVIEW_MARGIN`, `'100% 0px'`, from `'200px 0px'`). A snapshot costs nothing once taken, so drawing a screen ahead in each direction is paid once and lets a reader scrolling at any pace meet every card already drawn.
257
+
258
+ Measured on a gallery of 44 cards at 1440 by 900, scrolling down and back at reading pace, in flings, then to the foot and twice over again, against 0.36.0's earlier preview (a parked slot and a still copy only on reclaim): visible cards drawn again after they had drawn stayed at 0; cards seen before their first draw fell from 18 samples to 0 (from about 50 to 0 with the CPU slowed fourfold); teardowns of a drawn card fell from 93 to 0; requests and socket questions after every card had drawn fell from 7 and 2 to none, and over the whole visit from 106 and 27 to 57 and 12, every board, dataset and sheet read exactly once; long tasks at fourfold slowdown fell from about 40 (2.4 seconds in all) to 2 (150 milliseconds); the heap after the visit from 15.1 to 13.7 MB and the document's nodes from 6,356 to 5,994. The first screen draws within about 15 milliseconds of the time it took before (about 70 with the CPU slowed fourfold).
259
+
260
+ **A preview's margin is measured against its scroll container.** The observer was rooted at the window, and a page that scrolls inside a frame clips its content at the frame's edge, so `rootMargin` never applied and every card started drawing only once it was on screen. It now observes against the nearest ancestor that scrolls.
261
+
262
+ **`createLivePreviewBudget().request` answers a slot** (`LivePreviewSlot`: `release`, `drawn`, `park` and `resume`) in place of a give-back function, and takes the holder's `reclaim` and whether it is a `frame`. `drawn()` ends a render: it gives a page's slot back for good and keeps a frame among the frames. A host that called the answer to give a slot back calls `release()`.
263
+
264
+ ### Artifact kit
265
+
266
+ **A kit sheet reads the page's capabilities again once the runtime's handshake lands** (`@crewlethq/artifact-kit`: `<crewlet-sheet>`, `mountSheet`). Before the handshake the runtime answers `capabilities.has` from what the origin told it as the page loaded, and from the handshake on the host's word is the authority. The sheet read the answer once, when it was first drawn, and kept it, so a sheet drawn on one answer and handed another by the handshake kept the first: a page whose host said `db` at the handshake could still show "This sheet cannot load" for good. The sheet now reads the declaration again when `ready` resolves, its subscriptions following what it reads, and says a page has no datastore only once the handshake has said so; before then it draws nothing. `mountSheet` and the element still wait for the handshake before they draw, so a page sees no change unless a host's handshake disagrees with what its page loaded with.
267
+
268
+ ### Smaller fixes
269
+
270
+ **A framed slide keeps its edge on the dark theme** (`SlideStage` with `framed`). The slide's outline takes `--color-border-strong` rather than `--color-border-default`. On the dark theme the default border is a step off the page, so a dark slide (most themes are dark) on a dark page drew no edge and read as a hole in the page; the strong border is the third step of the ramp and clears the page in both themes. Hosts that recolour the outline for a marked stage are unchanged.
271
+
272
+ **An artifact bar's status is quiet by default** (`ArtifactBar`'s `status`). Plain words handed to it ("Creating…", "25 words", "4 slides · Nightshade") are drawn in the compact step and the secondary ink, with tabular figures, as `EditingStatus` draws itself, rather than at the bar title's size and ink. A host that styled its own status span for this can drop the span; one that wants a stronger status passes an element with its own colour.
273
+
274
+ **An option with a detail starts at its top** (`ChoiceButtons`). Laid out as tiles by a host's grid, the options in one row stretch to the tallest, and centred text set a label with a one-line detail lower than its neighbour with a two-line one. An option that has a detail now aligns its label, detail and mark to its top edge, so every label in a row starts on one line. An option without a detail, and a column of options, look as they did.
275
+
276
+ **A narrow board keeps a readable name** (`CanvasBoard`). A name with too little room above its board is shortened to at least three letters and an ellipsis; a board narrower than that is called by its number in the design ("3"), and only a board narrower than a digit goes unnamed. A shortened name or a number carries the whole name as a tooltip, and the board's region is still named in full. The name row counts the room the move handle and the open control take, so a touch screen's open control no longer cuts the name to nothing. `boardName(title, position, room)` is that rule, and `BOARD_NAME_MIN_CHARS` the letters it keeps. `boardRoom(width, height)` now answers the placeholder's `lines` alone, and `BOARD_TITLE_MIN_WIDTH` is gone: a host that read `boardRoom(...).title` asks `boardName` instead.
277
+
278
+ Beyond what is named above (a `DocumentTitleField` handler or ref typed for a textarea, a budget's `request` answering a slot, and `boardRoom(...).title` read through `boardName`), a host has nothing else to change. A host stylesheet that drew its own chosen state in `--color-brand-accent` can take the two selected tokens in its place, and one that drew a title underline of its own can follow `DocumentTitleField`.
279
+
207
280
  ## Changes in 0.35.1
208
281
 
209
282
  **A column given another type keeps only what every type has** (`SheetColumnEditor`, and `retypeColumn` in the sheet model). Its field, name, width, freezing, read-only flag and Required stay, and so does its length cap between text and long text, which both read it. Every other setting belongs to the old type and is dropped: a number's bounds, decimals and format, a choice's options, a date's time of day. The column is built up from what is kept rather than pared down from the old one, so a setting a type adds later is dropped without the editor having to name it. Before, a date's time of day and a text's length cap rode along, unseen, into a type that ignores them, and came back if the old type was picked again. A host that relied on a setting surviving a type change sets it again on the column it is handed.
@@ -0,0 +1,99 @@
1
+ import { type ReactNode, type Ref } from 'react';
2
+ /** One thing that goes to the agent with the brief: the draft, the slides laid out, the board. */
3
+ export interface AgentHandoffItem {
4
+ key: string;
5
+ /** A small glyph before the words. */
6
+ icon?: ReactNode;
7
+ /** What it is, in a line: "Your draft", "4 slides in Nightshade". */
8
+ label: ReactNode;
9
+ /** A second, quieter line: how much of it, or what the agent does with it. */
10
+ detail?: ReactNode;
11
+ }
12
+ /** A brief to start from, offered while the brief is empty. */
13
+ export interface AgentHandoffStarter {
14
+ key: string;
15
+ /** Its name on the chip: "Incident review". */
16
+ label: string;
17
+ }
18
+ /** The panel's commit: the press that files the work. */
19
+ export interface AgentHandoffSend {
20
+ /** Its words: "Ask SRE Lead". */
21
+ label: string;
22
+ /** Drawn before the words and hidden from the name: the chosen agent's character. */
23
+ media?: ReactNode;
24
+ onSend: () => void;
25
+ /** Unavailable, and why. Said on the button and, in words, beside it. */
26
+ disabledReason?: string | undefined;
27
+ /** Filing the work now. */
28
+ busy?: boolean | undefined;
29
+ }
30
+ export interface AgentHandoffLabels {
31
+ title: string;
32
+ brief: string;
33
+ starters: string;
34
+ agent: string;
35
+ carried: string;
36
+ task: string;
37
+ next: string;
38
+ step: string;
39
+ }
40
+ export declare const AGENT_HANDOFF_LABELS: AgentHandoffLabels;
41
+ export interface AgentHandoffPanelProps {
42
+ onClose: () => void;
43
+ /** A glyph before the title: the one on the control that opened the panel. */
44
+ icon?: ReactNode;
45
+ /** See [ArtifactPanel]: false for a panel that is open on arrival. */
46
+ focusOnOpen?: boolean | undefined;
47
+ /** A line under the title saying what the panel does, in the kind's words. */
48
+ intro?: ReactNode;
49
+ brief: string;
50
+ onBriefChange: (brief: string) => void;
51
+ /** The brief field's visible name, asked as a question where that reads better. */
52
+ briefLabel?: string | undefined;
53
+ briefPlaceholder?: string | undefined;
54
+ /** Under the field: what a good brief says. */
55
+ briefHelper?: ReactNode;
56
+ briefMaxLength?: number | undefined;
57
+ briefRef?: Ref<HTMLTextAreaElement> | undefined;
58
+ /** Briefs to start from, drawn while the brief is empty. */
59
+ starters?: readonly AgentHandoffStarter[] | undefined;
60
+ onStarter?: ((key: string) => void) | undefined;
61
+ /** The kind's own fields, under the brief: what a page may do, references. */
62
+ children?: ReactNode;
63
+ /** Who builds it: the host's agent picker, and the project it files in. */
64
+ agent: ReactNode;
65
+ /** What goes to the agent with the brief, so nothing the reader made is lost. */
66
+ carried?: readonly AgentHandoffItem[] | undefined;
67
+ /** The task exactly as it is filed, behind a disclosure. */
68
+ task?: {
69
+ title: string;
70
+ body: string;
71
+ } | undefined;
72
+ /** What happens after the press, step by step. */
73
+ steps?: readonly ReactNode[] | undefined;
74
+ /** A refusal or a warning, said above the commit. */
75
+ notice?: ReactNode;
76
+ send: AgentHandoffSend;
77
+ labels?: Partial<AgentHandoffLabels> | undefined;
78
+ className?: string | undefined;
79
+ }
80
+ /**
81
+ * Handing the work to an agent, at the side of what the reader is making.
82
+ *
83
+ * A PANEL, NOT A MODE. The page beside it is the direct way to make the thing,
84
+ * and stays live and editable while the brief is written, so a person can lay
85
+ * out a slide, then ask, then lay out another. What they made goes with the
86
+ * brief (`carried`), and the panel says so, so moving between the two ways
87
+ * loses nothing. Built on [ArtifactPanel], so it is a column where there is
88
+ * room, a drawer over the page's end where there is not, and the screen on a
89
+ * phone, exactly as an open artifact's panels are.
90
+ *
91
+ * THE BRIEF FIRST, as every agent composer puts it: the field the reader came
92
+ * to fill, with briefs to start from while it is empty. Then who builds it,
93
+ * what goes with it, the task as it is filed and what happens next, so nothing
94
+ * about the ask is hidden. The commit sits in the panel's foot, always in
95
+ * reach, with the chosen agent's character beside its words; Command+Enter
96
+ * anywhere in the panel presses it. A send that is held says why in words
97
+ * beside it, not only in the button's tooltip.
98
+ */
99
+ export declare function AgentHandoffPanel({ onClose, icon, focusOnOpen, intro, brief, onBriefChange, briefLabel, briefPlaceholder, briefHelper, briefMaxLength, briefRef, starters, onStarter, children, agent, carried, task, steps, notice, send, labels, className, }: AgentHandoffPanelProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './AgentHandoffPanel.css';
2
+ export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from './AgentHandoffPanel.js';
3
+ export type { AgentHandoffItem, AgentHandoffLabels, AgentHandoffPanelProps, AgentHandoffSend, AgentHandoffStarter, } from './AgentHandoffPanel.js';
@@ -0,0 +1,16 @@
1
+ export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-EOQFPZEE.js';
2
+ import '../chunk-AUQPBL4O.js';
3
+ import '../chunk-3TFDQLW3.js';
4
+ import '../chunk-MICH6QSJ.js';
5
+ import '../chunk-RH2NCQBZ.js';
6
+ import '../chunk-Y5BD4MTE.js';
7
+ import '../chunk-IUYUS2SO.js';
8
+ import '../chunk-SMBKXWML.js';
9
+ import '../chunk-YSGLEHND.js';
10
+ import '../chunk-FZVJDJFN.js';
11
+ import '../chunk-BHHIIK3M.js';
12
+ import '../chunk-PQADV6P6.js';
13
+ import '../chunk-OG6CL3EB.js';
14
+ import '../chunk-4FQT6ZAY.js';
15
+ import '../chunk-BZFWDIV6.js';
16
+ import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,151 @@
1
+ /*
2
+ * Handing work to an agent, at the side of what is being made. The panel is
3
+ * an ArtifactPanel; this is its inside: the brief, its starters, the agent,
4
+ * what goes with it and the steps after, on one rhythm, and the commit in the
5
+ * panel's foot.
6
+ *
7
+ * ONE STEP BETWEEN SECTIONS (spacing-6) and one inside them (spacing-2): the
8
+ * brief and its helper read as one block, the next question as the next.
9
+ */
10
+
11
+ .crewlet-agent-handoff__body {
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: var(--spacing-6);
15
+ min-width: 0;
16
+ }
17
+
18
+ .crewlet-agent-handoff__intro {
19
+ margin: 0;
20
+ color: var(--color-text-secondary);
21
+ font-size: var(--font-size-sm);
22
+ line-height: var(--font-line-height-normal);
23
+ }
24
+
25
+ .crewlet-agent-handoff__brief {
26
+ display: flex;
27
+ flex-direction: column;
28
+ gap: var(--spacing-2);
29
+ min-width: 0;
30
+ }
31
+
32
+ /* THE BRIEF'S NAME is a section's name, at a section heading's size, since
33
+ it heads the panel's first question. */
34
+ .crewlet-agent-handoff__label {
35
+ color: var(--color-text-primary);
36
+ font-size: var(--font-size-sm);
37
+ font-weight: var(--font-weight-semibold);
38
+ line-height: var(--font-line-height-snug);
39
+ }
40
+
41
+ .crewlet-agent-handoff__helper {
42
+ margin: 0;
43
+ color: var(--color-text-tertiary);
44
+ font-size: var(--font-size-xs);
45
+ line-height: var(--font-line-height-normal);
46
+ }
47
+
48
+ .crewlet-agent-handoff__starters {
49
+ display: flex;
50
+ flex-wrap: wrap;
51
+ gap: var(--spacing-2);
52
+ }
53
+
54
+ .crewlet-agent-handoff__section {
55
+ min-width: 0;
56
+ }
57
+
58
+ .crewlet-agent-handoff__carried {
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: var(--spacing-1);
62
+ margin: 0 0 var(--spacing-2);
63
+ padding: 0;
64
+ list-style: none;
65
+ }
66
+
67
+ .crewlet-agent-handoff__item {
68
+ display: flex;
69
+ align-items: flex-start;
70
+ gap: var(--spacing-2);
71
+ padding: var(--spacing-2) var(--spacing-3);
72
+ border-radius: var(--radius-md);
73
+ background: var(--color-surface-subtle);
74
+ }
75
+
76
+ .crewlet-agent-handoff__item-icon {
77
+ display: inline-flex;
78
+ flex: none;
79
+ /* On the first line's centre, whatever the glyph's own box. */
80
+ margin-top: 1px;
81
+ color: var(--color-text-tertiary);
82
+ }
83
+
84
+ .crewlet-agent-handoff__item-words {
85
+ display: flex;
86
+ flex-direction: column;
87
+ gap: 2px;
88
+ min-width: 0;
89
+ }
90
+
91
+ .crewlet-agent-handoff__item-label {
92
+ overflow-wrap: anywhere;
93
+ color: var(--color-text-primary);
94
+ font-size: var(--font-size-sm);
95
+ line-height: var(--font-line-height-snug);
96
+ }
97
+
98
+ .crewlet-agent-handoff__item-detail {
99
+ overflow-wrap: anywhere;
100
+ color: var(--color-text-tertiary);
101
+ font-size: var(--font-size-xs);
102
+ line-height: var(--font-line-height-normal);
103
+ }
104
+
105
+ .crewlet-agent-handoff__task {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: var(--spacing-2);
109
+ padding-top: var(--spacing-2);
110
+ }
111
+
112
+ .crewlet-agent-handoff__task-title {
113
+ margin: 0;
114
+ color: var(--color-text-primary);
115
+ font-size: var(--font-size-sm);
116
+ font-weight: var(--font-weight-medium);
117
+ }
118
+
119
+ /* THE BODY AS SENT, wrapped rather than scrolled sideways: a reader checks it
120
+ line by line, and a panel's width is narrower than its longest line. */
121
+ .crewlet-agent-handoff__task-body {
122
+ max-height: 16rem;
123
+ margin: 0;
124
+ overflow: auto;
125
+ padding: var(--spacing-2) var(--spacing-3);
126
+ border-radius: var(--radius-md);
127
+ background: var(--color-surface-inset);
128
+ color: var(--color-text-secondary);
129
+ font-family: var(--font-family-mono);
130
+ font-size: var(--font-size-xs);
131
+ line-height: var(--font-line-height-normal);
132
+ white-space: pre-wrap;
133
+ overflow-wrap: anywhere;
134
+ }
135
+
136
+ .crewlet-agent-handoff__foot {
137
+ display: flex;
138
+ flex-direction: column;
139
+ gap: var(--spacing-2);
140
+ }
141
+
142
+ .crewlet-agent-handoff__media {
143
+ display: inline-flex;
144
+ }
145
+
146
+ .crewlet-agent-handoff__reason {
147
+ margin: 0;
148
+ color: var(--color-text-tertiary);
149
+ font-size: var(--font-size-xs);
150
+ line-height: var(--font-line-height-normal);
151
+ }
@@ -1,4 +1,4 @@
1
- export { ArrangeFrame, useGridResize } from '../chunk-DEJHAOC5.js';
1
+ export { ArrangeFrame, useGridResize } from '../chunk-WMXAX6VA.js';
2
2
  import '../chunk-RSAQOKH3.js';
3
3
  import '../chunk-4FQT6ZAY.js';
4
4
  import '../chunk-BZFWDIV6.js';
@@ -59,9 +59,8 @@
59
59
 
60
60
  /*
61
61
  * THE ONE RING, over the block's own edge, on the innermost block the
62
- * pointer or the focus is in. A hairline drawn exactly over the block's own
63
- * 1px border, so the border turns to the accent rather than a second, heavier
64
- * line appearing around it.
62
+ * pointer or the focus is in. Drawn exactly over the block's own 1px border,
63
+ * so the border changes colour rather than a second line appearing around it.
65
64
  *
66
65
  * IT IS A LAYER OF ITS OWN, above the content. An outline is painted with the
67
66
  * block, under any content that is positioned or scrolls (a card with a fixed
@@ -78,14 +77,32 @@
78
77
  border-radius: inherit;
79
78
  pointer-events: none;
80
79
  }
81
- .crewlet-arrange-frame.is-editing:is(:hover, :focus-visible, :has(:focus-visible)):not(
80
+ /*
81
+ * THREE STRENGTHS ON THE ONE LAYER. The innermost block under the pointer, or
82
+ * holding the focus in one of its fields, takes the selected edge, the accent
83
+ * mixed toward the page: it says where the reader is working, and in the full
84
+ * accent a caret in a cell's field drew a frame in the focus ring's own hue
85
+ * round the whole block. The block ITSELF in keyboard focus takes the focus
86
+ * ring, two pixels in the focus colour, the area a keyboard indicator needs.
87
+ * A picked or resizing block takes one crisp pixel of the full accent, as a
88
+ * picked board on a canvas does, its handles saying the rest.
89
+ */
90
+ .crewlet-arrange-frame.is-editing:is(:hover, :has(:focus-visible)):not(:focus-visible, .is-selected, .is-resizing):not(
82
91
  :has(.crewlet-arrange-frame:is(:hover, :focus-visible, :has(:focus-visible)))
83
- )::after,
92
+ )::after {
93
+ border-color: var(--color-border-selected);
94
+ }
95
+
84
96
  .crewlet-arrange-frame.is-selected::after,
85
97
  .crewlet-arrange-frame.is-resizing::after {
86
98
  border-color: var(--color-brand-accent);
87
99
  }
88
100
 
101
+ .crewlet-arrange-frame.is-editing:focus-visible::after {
102
+ border-width: 2px;
103
+ border-color: var(--color-focus);
104
+ }
105
+
89
106
  /* A block with no surface of its own takes its ring a step outside it. */
90
107
  .crewlet-arrange-frame.is-bare {
91
108
  --crewlet-arrange-frame-radius: var(--radius-md);
@@ -1,8 +1,9 @@
1
- export { ArrangeList, DEFAULT_ARRANGE_LABELS } from '../chunk-V43UVX4H.js';
1
+ export { ArrangeList, DEFAULT_ARRANGE_LABELS } from '../chunk-27GD7LVR.js';
2
2
  import '../chunk-A722MUNR.js';
3
3
  import '../chunk-XJ2QEBMM.js';
4
- import '../chunk-CPEPST4S.js';
5
- import '../chunk-6QFAK2WV.js';
4
+ import '../chunk-PJIPUEJ3.js';
5
+ import '../chunk-IUYUS2SO.js';
6
+ import '../chunk-YSGLEHND.js';
6
7
  import '../chunk-PQADV6P6.js';
7
8
  import '../chunk-RSAQOKH3.js';
8
9
  import '../chunk-4FQT6ZAY.js';
@@ -100,7 +100,8 @@ export interface ArtifactBarProps {
100
100
  presence?: ReactNode;
101
101
  /**
102
102
  * What the kind is doing now, said before its tools: an `EditingStatus`
103
- * while a doc is edited. Never folded away; a status that has words to
103
+ * while a doc is edited, or plain words ("Creating…"), which the bar draws
104
+ * in its quiet small step. Never folded away; a status that has words to
104
105
  * spare folds them itself.
105
106
  */
106
107
  status?: ReactNode;
@@ -1,12 +1,12 @@
1
- export { ARTIFACT_BAR_LABELS, ArtifactBar, ArtifactVersionChip } from '../chunk-NKZCJRKO.js';
1
+ export { ARTIFACT_BAR_LABELS, ArtifactBar, ArtifactVersionChip } from '../chunk-APDKUGSH.js';
2
2
  import '../chunk-WKEPORNM.js';
3
- import '../chunk-SMBKXWML.js';
4
3
  import '../chunk-6ZJ3N7QI.js';
5
4
  import '../chunk-CCAXYHQS.js';
6
5
  import '../chunk-VL6CUNSX.js';
7
6
  import '../chunk-RKKO7QHH.js';
8
7
  import '../chunk-ILDNJHRU.js';
9
8
  import '../chunk-CE2THTQR.js';
9
+ import '../chunk-SMBKXWML.js';
10
10
  import '../chunk-BHHIIK3M.js';
11
11
  import '../chunk-BUVCV3WI.js';
12
12
  import '../chunk-OMV5W53A.js';
@@ -198,11 +198,19 @@
198
198
  margin-inline-start: var(--spacing-1);
199
199
  }
200
200
 
201
+ /* THE STATUS IS QUIET by default, in the bar's small step and the secondary
202
+ ink that `EditingStatus` takes, so a host that hands it words ("Creating…",
203
+ "25 words") draws them as the open artifact draws its own, never at the
204
+ title's weight. Its figures are tabular, so a count does not jitter. */
201
205
  .crewlet-artifact-bar__status {
202
206
  display: inline-flex;
203
207
  align-items: center;
204
208
  min-width: 0;
205
209
  margin-inline-end: var(--spacing-2);
210
+ color: var(--color-text-secondary);
211
+ font-size: var(--font-size-compact);
212
+ font-variant-numeric: tabular-nums;
213
+ white-space: nowrap;
206
214
  }
207
215
 
208
216
  .crewlet-artifact-bar__presence {
@@ -1,10 +1,10 @@
1
- export { ArtifactCard, ArtifactCardSkeleton, ArtifactPreviewGlyph } from '../chunk-7UYONN6K.js';
1
+ export { ArtifactCard, ArtifactCardSkeleton, ArtifactPreviewGlyph } from '../chunk-OSZDHN5Z.js';
2
2
  import '../chunk-TEUQWOWZ.js';
3
3
  import '../chunk-CI3VPIJN.js';
4
4
  import '../chunk-3CZ7XAVY.js';
5
5
  import '../chunk-EUCC37WY.js';
6
- import '../chunk-W7QBBKUE.js';
7
- import '../chunk-ACA27MZH.js';
6
+ import '../chunk-MJW6SQYB.js';
7
+ import '../chunk-5QXRI35B.js';
8
8
  import '../chunk-AV2DXAEL.js';
9
9
  import '../chunk-5AQBPHZD.js';
10
10
  import '../chunk-PZKHBB7D.js';
@@ -1,4 +1,5 @@
1
- export { DashboardCover, DocCover, SHEET_COVER_COLUMNS, SHEET_COVER_ROWS, SheetCover } from '../chunk-AXBRWRGV.js';
2
- import '../chunk-TYKQ33CL.js';
1
+ export { DashboardCover, DocCover, SHEET_COVER_COLUMNS, SHEET_COVER_ROWS, SheetCover } from '../chunk-JQLS3MZB.js';
2
+ import '../chunk-P6WFZDKS.js';
3
3
  import '../chunk-CE2THTQR.js';
4
+ import '../chunk-YSGLEHND.js';
4
5
  import '../chunk-ODEQTPFM.js';
@@ -20,8 +20,8 @@ export declare function ArtifactKindIllustration({ kind, className }: {
20
20
  }): import("react").JSX.Element;
21
21
  /**
22
22
  * A kind's drawing on its tinted ground: the stand-in a preview shows while
23
- * nothing live is drawn (off screen, still loading, over the live budget,
24
- * failed or empty), and the face of a Make something new tile.
23
+ * nothing live is drawn (never yet near, still loading, over the live budget,
24
+ * failed or empty), and the face of a kind tile.
25
25
  */
26
26
  export declare function ArtifactKindGround({ kind, className, children, }: {
27
27
  kind: ArtifactKind;
@@ -31,7 +31,7 @@ export declare function ArtifactKindGround({ kind, className, children, }: {
31
31
  }): import("react").JSX.Element;
32
32
  export interface ArtifactKindTileProps {
33
33
  kind: ArtifactKind;
34
- /** The kind's name, under the tile: "Docs". */
34
+ /** The name under the tile: "Docs", or a starting point's "Landing page". */
35
35
  label: string;
36
36
  /** Where starting one goes. Left out with `disabledReason`, the tile starts nothing. */
37
37
  href?: string | undefined;
@@ -41,6 +41,13 @@ export interface ArtifactKindTileProps {
41
41
  * button. `href` wins where both are given.
42
42
  */
43
43
  onSelect?: (() => void) | undefined;
44
+ /**
45
+ * For a tile that is a button: whether it is the one chosen (a starting
46
+ * layout already picked). Drawn as every chosen option is, the selected
47
+ * edge over the selected fill with a check beside the name, and announced
48
+ * as a pressed button. Left out, the tile is an action with no state.
49
+ */
50
+ selected?: boolean | undefined;
44
51
  /**
45
52
  * Drawn on the kind's ground in place of its drawing: a picture of this
46
53
  * particular starting point, such as a design layout's schematic.
@@ -55,12 +62,14 @@ export interface ArtifactKindTileProps {
55
62
  className?: string | undefined;
56
63
  }
57
64
  /**
58
- * One kind on a "Make something new" row: the kind's drawing on its tinted
59
- * ground, framed, with its name under it. The whole tile is one link named by
60
- * the kind's name.
65
+ * One kind, or one starting point of a kind, as a tile: the kind's drawing on
66
+ * its tinted ground (or the starting point's own `face`), framed, with its
67
+ * name under it, such as a create page's starting layouts. The whole tile is
68
+ * one link or button named by the name. The gallery's Make something new row
69
+ * is the quieter `ArtifactMakeRow`, a toolbar of glyphs rather than pictures.
61
70
  *
62
71
  * A TILE THAT CANNOT START is still a stop on the row, so a reader moving
63
72
  * through it by keyboard hears why (`disabledReason`) rather than finding a
64
73
  * kind missing.
65
74
  */
66
- export declare function ArtifactKindTile({ kind, label, href, onSelect, face, detail, badge, disabledReason, className, }: ArtifactKindTileProps): import("react").JSX.Element;
75
+ export declare function ArtifactKindTile({ kind, label, href, onSelect, selected, face, detail, badge, disabledReason, className, }: ArtifactKindTileProps): import("react").JSX.Element;
@@ -1,3 +1,3 @@
1
- export { ArtifactKindGround, ArtifactKindIllustration, ArtifactKindTile } from '../chunk-W7QBBKUE.js';
1
+ export { ArtifactKindGround, ArtifactKindIllustration, ArtifactKindTile } from '../chunk-MJW6SQYB.js';
2
2
  import '../chunk-BZFWDIV6.js';
3
3
  import '../chunk-ODEQTPFM.js';
@@ -201,6 +201,42 @@ a.crewlet-kind-tile:hover .crewlet-kind-tile__frame,
201
201
  outline-offset: var(--size-focus-ring-inset-offset);
202
202
  }
203
203
 
204
+ /*
205
+ * A TILE THAT STARTS SOMETHING IN PLACE (a create page's starting layouts)
206
+ * DRAWS ONE EDGE. Its face is a picture of the layout, with boards of its
207
+ * own, so the ground's tinted inner line was a second outline a few pixels
208
+ * inside the frame's, and with the focus ring over the frame the tile read as
209
+ * three nested rings. The frame is the tile's one edge; the ground keeps its
210
+ * tint.
211
+ */
212
+ .crewlet-kind-tile--button .crewlet-kind-tile__ground {
213
+ box-shadow: none;
214
+ }
215
+
216
+ /*
217
+ * CHOSEN, as every chosen option is drawn: the selected edge (the accent
218
+ * mixed toward the page) on the frame, over the selected fill, and a check
219
+ * beside the name, the mark that clears 3:1. Under the pointer it keeps its
220
+ * edge, and the focus ring is drawn over it for the keyboard alone.
221
+ */
222
+ .crewlet-kind-tile--button.is-selected .crewlet-kind-tile__frame,
223
+ .crewlet-kind-tile--button.is-selected:hover .crewlet-kind-tile__frame {
224
+ border-color: var(--color-border-selected);
225
+ background-image: linear-gradient(var(--color-surface-selected), var(--color-surface-selected));
226
+ }
227
+
228
+ .crewlet-kind-tile__check {
229
+ flex: none;
230
+ margin-inline-start: auto;
231
+ color: var(--color-brand-accent-ink);
232
+ }
233
+
234
+ @media (forced-colors: active) {
235
+ .crewlet-kind-tile--button.is-selected .crewlet-kind-tile__frame {
236
+ border-color: Highlight;
237
+ }
238
+ }
239
+
204
240
  .crewlet-kind-tile--disabled {
205
241
  cursor: not-allowed;
206
242
  }