@crewlethq/ui 0.4.4 → 0.5.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 (231) hide show
  1. package/README.md +888 -24
  2. package/dist/Accordion/index.js +2 -2
  3. package/dist/AddPill/index.js +1 -1
  4. package/dist/{AddPill-DFWXYLIQ.css → AddPill-IJQYCY6C.css} +9 -0
  5. package/dist/AppShell/AppShell.d.ts +26 -5
  6. package/dist/AppShell/index.js +3 -3
  7. package/dist/{AppShell-NVE6LHNI.css → AppShell-XARELGIH.css} +178 -25
  8. package/dist/Avatar/Avatar.d.ts +85 -40
  9. package/dist/Avatar/AvatarStack.d.ts +76 -0
  10. package/dist/Avatar/index.d.ts +5 -2
  11. package/dist/Avatar/index.js +1 -1
  12. package/dist/Avatar-XID7Z74C.css +200 -0
  13. package/dist/AvatarStack-GEJBNV7E.css +72 -0
  14. package/dist/BrandLockup/index.js +1 -1
  15. package/dist/{BrandLockup-6ISDEHPJ.css → BrandLockup-JKGXFCZF.css} +25 -19
  16. package/dist/Button/Button.d.ts +7 -2
  17. package/dist/Button/index.js +1 -1
  18. package/dist/{Button-D4J6B4MA.css → Button-X4B2TJAQ.css} +50 -19
  19. package/dist/Callout/index.js +1 -1
  20. package/dist/Canvas/index.js +4 -4
  21. package/dist/Card/Card.d.ts +9 -5
  22. package/dist/Card/index.js +1 -1
  23. package/dist/{Card-RLR254LD.css → Card-GLP7SUV6.css} +25 -18
  24. package/dist/Charts/BarList.d.ts +18 -1
  25. package/dist/Charts/ChartTooltip.d.ts +68 -0
  26. package/dist/Charts/StackedBar.d.ts +25 -7
  27. package/dist/Charts/StackedColumns.d.ts +112 -0
  28. package/dist/Charts/TimeSeries.d.ts +33 -2
  29. package/dist/Charts/dataColor.d.ts +22 -14
  30. package/dist/Charts/index.d.ts +6 -0
  31. package/dist/Charts/index.js +1 -1
  32. package/dist/Charts/useChartHover.d.ts +56 -0
  33. package/dist/Charts-B3YEF7R4.css +742 -0
  34. package/dist/Checkbox/index.js +1 -1
  35. package/dist/{Checkbox-VGW26YLQ.css → Checkbox-BOXQ747I.css} +2 -2
  36. package/dist/CodeBlock/index.js +4 -4
  37. package/dist/Combobox/index.js +5 -5
  38. package/dist/CommandPalette/CommandPalette.d.ts +97 -6
  39. package/dist/CommandPalette/index.d.ts +1 -1
  40. package/dist/CommandPalette/index.js +9 -7
  41. package/dist/CommandPalette-C5AMKGN2.css +259 -0
  42. package/dist/Copyable/index.js +3 -3
  43. package/dist/DataTable/index.js +7 -7
  44. package/dist/{DataTable-37UWTRN6.css → DataTable-OLHPF7D4.css} +35 -38
  45. package/dist/DataView/index.js +15 -15
  46. package/dist/{DataView-256YF32J.css → DataView-N6JX464S.css} +5 -4
  47. package/dist/DateTimePicker/index.js +5 -5
  48. package/dist/DiffList/index.js +1 -1
  49. package/dist/Disclosure/index.js +2 -2
  50. package/dist/EntityChip/EntityChip.d.ts +9 -12
  51. package/dist/EntityChip/index.d.ts +1 -1
  52. package/dist/EntityChip/index.js +2 -2
  53. package/dist/ErrorBoundary/index.js +2 -2
  54. package/dist/{ErrorBoundary-ME36CQTA.css → ErrorBoundary-U2PA3LY2.css} +4 -4
  55. package/dist/IconButton/index.js +1 -1
  56. package/dist/{IconButton-VQGNMJDI.css → IconButton-TVEUWK6L.css} +2 -2
  57. package/dist/ImageUpload/ImageUpload.d.ts +10 -7
  58. package/dist/ImageUpload/index.js +2 -2
  59. package/dist/{ImageUpload-HKFIZR6D.css → ImageUpload-YCHJMUGX.css} +24 -10
  60. package/dist/Input/index.js +2 -2
  61. package/dist/Kbd/Kbd.d.ts +14 -4
  62. package/dist/Kbd/index.js +1 -1
  63. package/dist/Kbd-JPLDVJIP.css +71 -0
  64. package/dist/Layer/index.js +1 -1
  65. package/dist/Link/index.js +1 -1
  66. package/dist/List/index.js +1 -1
  67. package/dist/{List-XTHESXLR.css → List-MYJIV6MP.css} +12 -2
  68. package/dist/ListInput/index.js +6 -6
  69. package/dist/Listbox/index.js +2 -2
  70. package/dist/Listbox/useListbox.d.ts +2 -0
  71. package/dist/{Listbox-ZXYYNN6U.css → Listbox-6WJNJQVQ.css} +32 -7
  72. package/dist/Menu/index.js +4 -4
  73. package/dist/Meter/Meter.d.ts +103 -16
  74. package/dist/Meter/index.d.ts +2 -2
  75. package/dist/Meter/index.js +1 -1
  76. package/dist/{Meter-SKOOXQBC.css → Meter-5VCSFMZW.css} +46 -7
  77. package/dist/Modal/index.js +4 -4
  78. package/dist/{Modal-XYQJ4BL6.css → Modal-JAYBS2KS.css} +13 -4
  79. package/dist/OrgLabel/OrgLabel.d.ts +60 -24
  80. package/dist/OrgLabel/index.d.ts +1 -1
  81. package/dist/OrgLabel/index.js +2 -1
  82. package/dist/{OrgLabel-D7U6QJZD.css → OrgLabel-CR233G34.css} +9 -18
  83. package/dist/OrgNode/index.js +3 -2
  84. package/dist/OrgTable/OrgTable.d.ts +2 -2
  85. package/dist/OrgTable/index.js +8 -7
  86. package/dist/Popover/index.js +2 -2
  87. package/dist/PricingCard/index.js +3 -3
  88. package/dist/{PricingCard-JFI7RYXP.css → PricingCard-7EFXRSD2.css} +4 -5
  89. package/dist/SearchTrigger/SearchTrigger.d.ts +23 -4
  90. package/dist/SearchTrigger/index.d.ts +1 -1
  91. package/dist/SearchTrigger/index.js +1 -1
  92. package/dist/SearchTrigger-Z5D4AAY7.css +112 -0
  93. package/dist/SegmentedControl/index.js +2 -2
  94. package/dist/SegmentedMeter/SegmentedMeter.d.ts +107 -0
  95. package/dist/SegmentedMeter/index.d.ts +3 -0
  96. package/dist/SegmentedMeter/index.js +2 -0
  97. package/dist/SegmentedMeter-KQNML2TW.css +109 -0
  98. package/dist/Select/index.js +3 -3
  99. package/dist/Shortcut/index.js +2 -2
  100. package/dist/SidebarNav/SidebarNav.d.ts +85 -25
  101. package/dist/SidebarNav/index.d.ts +1 -1
  102. package/dist/SidebarNav/index.js +1 -1
  103. package/dist/SidebarNav-X5NLZNWA.css +424 -0
  104. package/dist/StatCard/StatCard.d.ts +59 -12
  105. package/dist/StatCard/index.d.ts +1 -1
  106. package/dist/StatCard/index.js +1 -1
  107. package/dist/StatCard-KPAFD4E2.css +204 -0
  108. package/dist/StatGroup/index.js +1 -1
  109. package/dist/{StatGroup-TGB6AEKM.css → StatGroup-HVG6O62W.css} +8 -9
  110. package/dist/StatusDot/StatusDot.d.ts +24 -6
  111. package/dist/StatusDot/index.js +1 -1
  112. package/dist/StatusDot-7OMCQCZF.css +186 -0
  113. package/dist/Stepper/Stepper.d.ts +78 -0
  114. package/dist/Stepper/index.d.ts +3 -0
  115. package/dist/Stepper/index.js +4 -0
  116. package/dist/Stepper-HW4JM3YH.css +176 -0
  117. package/dist/Tabs/index.js +1 -1
  118. package/dist/{Tabs-MJ2E3VPK.css → Tabs-XCNPHA7B.css} +46 -26
  119. package/dist/Tag/Tag.d.ts +29 -22
  120. package/dist/Tag/index.js +2 -2
  121. package/dist/{Tag-VNZEYLB6.css → Tag-GBE7LQJP.css} +82 -83
  122. package/dist/TagsInput/index.js +7 -7
  123. package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +53 -21
  124. package/dist/ThemeSwitcher/index.d.ts +3 -3
  125. package/dist/ThemeSwitcher/index.js +4 -3
  126. package/dist/ThemeSwitcher/preferences.d.ts +19 -5
  127. package/dist/ThemeToggle/ThemeToggle.d.ts +40 -0
  128. package/dist/ThemeToggle/index.d.ts +2 -0
  129. package/dist/ThemeToggle/index.js +5 -0
  130. package/dist/TimeWindowPicker/index.js +8 -8
  131. package/dist/Toaster/index.js +2 -2
  132. package/dist/Toolbar/index.js +2 -2
  133. package/dist/{Toolbar-IP6LXN45.css → Toolbar-HUOSMNTH.css} +3 -1
  134. package/dist/Tooltip/index.js +2 -2
  135. package/dist/Tree/index.d.ts +2 -2
  136. package/dist/Tree/index.js +1 -1
  137. package/dist/Tree/layout.d.ts +103 -28
  138. package/dist/TreeCanvas/TreeCanvas.d.ts +60 -14
  139. package/dist/TreeCanvas/index.d.ts +1 -1
  140. package/dist/TreeCanvas/index.js +6 -6
  141. package/dist/TreeCanvas/motion.d.ts +3 -2
  142. package/dist/{TreeCanvas-WBNQPHC7.css → TreeCanvas-HVOV4SQN.css} +154 -30
  143. package/dist/TreeGrid/index.js +4 -4
  144. package/dist/{chunk-F6OE5FH3.js → chunk-2FPENTCF.js} +1 -1
  145. package/dist/chunk-4AK52VHB.js +88 -0
  146. package/dist/{chunk-7EM5T4ME.js → chunk-4IQD3HUQ.js} +2 -2
  147. package/dist/{chunk-YODNNSZL.js → chunk-4PZ6FJKW.js} +43 -13
  148. package/dist/{chunk-F27EPQ7D.js → chunk-4UQ7SMPK.js} +1 -1
  149. package/dist/chunk-5QWIJSQM.js +73 -0
  150. package/dist/{chunk-KIC7BZYJ.js → chunk-6MU7HNB4.js} +6 -5
  151. package/dist/{chunk-S2XHHEW4.js → chunk-74KMX7YH.js} +4 -4
  152. package/dist/{chunk-WNI2WSJF.js → chunk-7KBNFFM3.js} +1 -1
  153. package/dist/{chunk-EFSG7HNU.js → chunk-AUS5FNQE.js} +1 -1
  154. package/dist/{chunk-CMEE37QJ.js → chunk-BMYPGGPV.js} +4 -4
  155. package/dist/{chunk-H4FBTAYS.js → chunk-BNCCEER3.js} +8 -8
  156. package/dist/chunk-C5WJUZVR.js +56 -0
  157. package/dist/{chunk-5WS6L6FA.js → chunk-CAIHUYXV.js} +9 -9
  158. package/dist/{chunk-5KSRXHOW.js → chunk-CQY5NTRS.js} +1 -1
  159. package/dist/{chunk-MW356IVK.js → chunk-D6EVJUGU.js} +2 -2
  160. package/dist/{chunk-7PEFUMQJ.js → chunk-DHPUMOTX.js} +2 -2
  161. package/dist/{chunk-HZ5XZNPS.js → chunk-DS2C73RJ.js} +3 -3
  162. package/dist/{chunk-GKHAKGOF.js → chunk-DSUY5F4E.js} +3 -3
  163. package/dist/{chunk-Q4ZPPART.js → chunk-EFYPAJT3.js} +3 -3
  164. package/dist/{chunk-PATXSJGR.js → chunk-ERVO6OUF.js} +17 -17
  165. package/dist/{chunk-BZYDZBAN.js → chunk-ETYEBKR4.js} +3 -3
  166. package/dist/{chunk-CC67MUUO.js → chunk-FD5UEN6X.js} +30 -30
  167. package/dist/{chunk-5SDBMKUO.js → chunk-FIFNP6PL.js} +3 -3
  168. package/dist/{chunk-7HPRF5XN.js → chunk-FUF52K7E.js} +98 -16
  169. package/dist/{chunk-5KPQ6D7N.js → chunk-FZVJDJFN.js} +2 -2
  170. package/dist/chunk-IA232OTU.js +156 -0
  171. package/dist/{chunk-2EOKFKHX.js → chunk-IG27QX7Q.js} +7 -7
  172. package/dist/chunk-IKB6HFGK.js +55 -0
  173. package/dist/{chunk-T43A26SD.js → chunk-IPVQKAHO.js} +6 -6
  174. package/dist/{chunk-3EYF6HKB.js → chunk-IVFJD7WY.js} +28 -9
  175. package/dist/{chunk-XJWXPRSK.js → chunk-JGRNTBF2.js} +11 -11
  176. package/dist/chunk-K3OWD7BJ.js +121 -0
  177. package/dist/{chunk-6KCO2D5C.js → chunk-KD4H66L6.js} +7 -20
  178. package/dist/{chunk-SFZOKW2G.js → chunk-KJ34ZBBI.js} +8 -3
  179. package/dist/{chunk-AQTBF4EB.js → chunk-LFHCXZO5.js} +5 -5
  180. package/dist/{chunk-LWKJQTOM.js → chunk-MICH6QSJ.js} +1 -1
  181. package/dist/chunk-N3DPO6HG.js +226 -0
  182. package/dist/{chunk-S4GZWSKR.js → chunk-OM5E3TTK.js} +1 -1
  183. package/dist/{chunk-3QRYCPXQ.js → chunk-OPKIKM35.js} +6 -6
  184. package/dist/{chunk-5EKIWVOR.js → chunk-PGRPNDWM.js} +2 -2
  185. package/dist/{chunk-FSOW3ARP.js → chunk-PQNILU27.js} +9 -9
  186. package/dist/{chunk-QNCVHRZL.js → chunk-QVAFL2LE.js} +1 -1
  187. package/dist/{chunk-Q3B66TJM.js → chunk-QY7UU5ZB.js} +1 -1
  188. package/dist/{chunk-ITHXJHBB.js → chunk-R25RGPUB.js} +1 -0
  189. package/dist/{chunk-KLJCCMF3.js → chunk-R6735B37.js} +2 -2
  190. package/dist/{chunk-3ZP55QZE.js → chunk-R6FBDTP3.js} +4 -4
  191. package/dist/{chunk-7FZ53WDJ.js → chunk-RIAZM6L3.js} +1 -1
  192. package/dist/chunk-RJM4QCGG.js +550 -0
  193. package/dist/{chunk-NTRZGNEX.js → chunk-S3BCVWTU.js} +215 -46
  194. package/dist/chunk-S7KW47IQ.js +121 -0
  195. package/dist/{chunk-KNYYCWMK.js → chunk-SJQ546ID.js} +4 -4
  196. package/dist/{chunk-D35VTV2Z.js → chunk-SV7QAONL.js} +1 -1
  197. package/dist/{chunk-IAJLHVUA.js → chunk-TIWAHZZ6.js} +1 -1
  198. package/dist/{chunk-2PRH365R.js → chunk-UA7O3KKJ.js} +1 -1
  199. package/dist/{chunk-NPZY6YYL.js → chunk-UG5ZMAXW.js} +6 -6
  200. package/dist/{chunk-NDCATSW7.js → chunk-V34H2YCY.js} +1 -1
  201. package/dist/chunk-WIATRXEJ.js +22 -0
  202. package/dist/{chunk-5C5YMZQU.js → chunk-WOFOMTGB.js} +16 -10
  203. package/dist/{chunk-QYOFACSP.js → chunk-WSOFKOLP.js} +3 -3
  204. package/dist/{chunk-MNAXYY3R.js → chunk-WUVZDFHS.js} +31 -11
  205. package/dist/{chunk-DB2VDLVR.js → chunk-YIMOT5OO.js} +10 -10
  206. package/dist/{chunk-2ZQMA2WB.js → chunk-ZPSOF6VL.js} +2 -2
  207. package/dist/generated/index.d.ts +3 -0
  208. package/dist/generated/index.js +69 -65
  209. package/dist/index.js +69 -65
  210. package/dist/styles.css +2538 -741
  211. package/dist/utils/index.d.ts +1 -1
  212. package/dist/utils/tone.d.ts +7 -12
  213. package/package.json +4 -4
  214. package/scripts/check-css-literals.mjs +159 -23
  215. package/scripts/check-css-variables.mjs +5 -3
  216. package/scripts/css-source.mjs +97 -5
  217. package/dist/Avatar-P2KRQM2B.css +0 -156
  218. package/dist/Charts-D7G2BSXH.css +0 -277
  219. package/dist/CommandPalette-CSJDUCQA.css +0 -115
  220. package/dist/Kbd-W66MXQI5.css +0 -61
  221. package/dist/SearchTrigger-QXOYAUUY.css +0 -79
  222. package/dist/SidebarNav-QGSFKZYA.css +0 -319
  223. package/dist/StatCard-KYPKZUWX.css +0 -111
  224. package/dist/StatusDot-HA2L2FSX.css +0 -84
  225. package/dist/chunk-22O7LAW2.js +0 -41
  226. package/dist/chunk-AJNCATWZ.js +0 -144
  227. package/dist/chunk-F4PJZ4ED.js +0 -245
  228. package/dist/chunk-PNFASD6F.js +0 -98
  229. package/dist/chunk-PZSWF74H.js +0 -15
  230. package/dist/chunk-R66KLW7S.js +0 -143
  231. /package/dist/{chunk-ZCR6YGQ4.js → chunk-PKIN4IMB.js} +0 -0
@@ -0,0 +1,204 @@
1
+ /*
2
+ * The stat tile.
3
+ *
4
+ * THE TONE PAINTS THE VALUE, which is what the props always said and what the
5
+ * stylesheet never did: 0.2.0 tinted the ICON, so a caller who passed a tone
6
+ * and no icon got a tile identical to a neutral one. Ink only, and never a
7
+ * fill: a tinted block behind a 28px number reads as a button.
8
+ */
9
+
10
+ .crewlet-statcard {
11
+ /*
12
+ * The width of the figure at the end of the value's line. 96px is the
13
+ * approved design's sparkline, and its meters and state bars stand within
14
+ * four pixels of it: wide enough that a fortnight of points reads as a
15
+ * shape, narrow enough that five tiles in a row still leave the number its
16
+ * room.
17
+ */
18
+ --crewlet-statcard-trend-width: 96px;
19
+
20
+ display: flex;
21
+ flex-direction: column;
22
+ /* The design's 10px between the three lines, and its 16px inset with 14px
23
+ under the last line: half a scale step each, derived from the steps so
24
+ they follow the density with everything else. */
25
+ gap: calc(var(--spacing-2) + var(--spacing-1) / 2);
26
+ padding: var(--spacing-4) var(--spacing-4) calc(var(--spacing-3) + var(--spacing-1) / 2);
27
+ /*
28
+ * The card recipe: the card's surface, its hairline and its 12px corner,
29
+ * FLAT, as every card is, so a lone tile is the same object as the panel
30
+ * beside it rather than a raised cousin of it.
31
+ */
32
+ background: var(--color-surface-subtle);
33
+ border: 1px solid var(--color-border-default);
34
+ border-radius: var(--radius-lg);
35
+ color: var(--color-text-primary);
36
+ font-family: var(--font-family-sans);
37
+ min-width: 0;
38
+ }
39
+
40
+ /* Inside a StatGroup the row is one card and the tiles are its columns, so a
41
+ tile brings no surface of its own. */
42
+ .crewlet-statcard--flush {
43
+ background: transparent;
44
+ border: 0;
45
+ border-radius: var(--radius-none);
46
+ }
47
+
48
+ /*
49
+ * The label: SENTENCE CASE at the caption step, as the design sets it and as
50
+ * the caller wrote it. The uppercased, tracked-open micro-caps it used to wear
51
+ * are a table's column head: five of them over five numbers put a heading on
52
+ * every tile, and uppercasing is a transform a caller's own words should not
53
+ * have to survive.
54
+ */
55
+ .crewlet-statcard__label {
56
+ display: flex;
57
+ align-items: center;
58
+ gap: var(--spacing-1);
59
+ font-size: var(--font-size-xs);
60
+ font-weight: var(--font-weight-regular);
61
+ letter-spacing: var(--font-letter-spacing-normal);
62
+ color: var(--color-text-tertiary);
63
+ min-width: 0;
64
+ }
65
+
66
+ .crewlet-statcard__icon {
67
+ display: inline-flex;
68
+ flex: none;
69
+ }
70
+
71
+ /*
72
+ * The value's line: the number at its start, the figure at its end, both on
73
+ * the line's FOOT, so a 28px number and a 28px sparkline share a baseline
74
+ * rather than centring on each other.
75
+ */
76
+ .crewlet-statcard__reading {
77
+ display: flex;
78
+ align-items: flex-end;
79
+ justify-content: space-between;
80
+ gap: calc(var(--spacing-2) + var(--spacing-1) / 2);
81
+ min-width: 0;
82
+ }
83
+
84
+ /*
85
+ * THE SCREEN'S ONE DISPLAY NUMBER. The display step, semibold, on the tight
86
+ * track, with tabular figures so a number that ticks up moves nothing beside
87
+ * it.
88
+ *
89
+ * ITS LINE IS THE GLYPH'S OWN HEIGHT (a leading of 1). The value is one line
90
+ * that never wraps, and any leading over it is air under the digits that
91
+ * opens between the number and the line below it and stands the number
92
+ * higher than the figure it shares a foot with.
93
+ *
94
+ * A BLOCK, NOT A FLEX ROW, because it is one line of text that has to END
95
+ * rather than stop: `text-overflow` acts on a block container only, and as a
96
+ * flex row the number and its unit were anonymous flex items no rule could
97
+ * reach, so a value too long for its tile was cut mid-digit with nothing to
98
+ * say a digit was lost. The unit sits on the same line as inline text, on
99
+ * the number's baseline.
100
+ */
101
+ .crewlet-statcard__value {
102
+ display: block;
103
+ flex: 1 1 auto;
104
+ min-width: 0;
105
+ font-size: var(--font-size-display);
106
+ font-weight: var(--font-weight-semibold);
107
+ letter-spacing: var(--font-letter-spacing-tight);
108
+ line-height: 1;
109
+ font-variant-numeric: tabular-nums;
110
+ overflow: hidden;
111
+ text-overflow: ellipsis;
112
+ white-space: nowrap;
113
+ }
114
+
115
+ /* The unit, "/ 7" after the 4: the quiet ink at a text step, medium, so it
116
+ reads as part of the figure rather than as a second one. */
117
+ .crewlet-statcard__unit {
118
+ margin-inline-start: var(--spacing-1);
119
+ font-size: var(--font-size-sm);
120
+ font-weight: var(--font-weight-medium);
121
+ letter-spacing: var(--font-letter-spacing-normal);
122
+ color: var(--color-text-tertiary);
123
+ }
124
+
125
+ /*
126
+ * The figure at the end of the line. A figure (a sparkline, a meter, a state
127
+ * bar) FILLS the slot, because none of them has a width of its own to offer.
128
+ * A control keeps its own and stands at the slot's end: "Review" is a small
129
+ * button beside the number it acts on, not a bar the width of a sparkline.
130
+ */
131
+ .crewlet-statcard__trend {
132
+ display: flex;
133
+ flex-direction: column;
134
+ justify-content: flex-end;
135
+ flex: none;
136
+ width: var(--crewlet-statcard-trend-width);
137
+ min-width: 0;
138
+ }
139
+
140
+ .crewlet-statcard__trend > :where(button, a) {
141
+ align-self: flex-end;
142
+ }
143
+
144
+ /*
145
+ * The placeholder is a line, not a pair of dashes. `--` is read aloud as
146
+ * "dash dash" and looks exactly like a measured value of nothing; the tile
147
+ * carries aria-busy instead, and the line says the number is on its way.
148
+ */
149
+ .crewlet-statcard__placeholder {
150
+ display: inline-block;
151
+ width: 3ch;
152
+ height: 0.7em;
153
+ border-radius: var(--radius-xs);
154
+ background: var(--color-surface-inset);
155
+ }
156
+
157
+ /*
158
+ * The second line keeps its space whether or not there is one, so a row of
159
+ * tiles where only some carry one still stands at one height: its leading is
160
+ * set here and the reserve is exactly one line of it, where a reserve in `em`
161
+ * was a line shorter than the one a sub actually draws.
162
+ */
163
+ .crewlet-statcard__sub {
164
+ min-height: calc(1em * var(--font-line-height-body));
165
+ font-size: var(--font-size-xs);
166
+ line-height: var(--font-line-height-body);
167
+ /* The quiet step, with the label. The line qualifies the number rather than
168
+ being a second one. */
169
+ color: var(--color-text-tertiary);
170
+ overflow: hidden;
171
+ text-overflow: ellipsis;
172
+ white-space: nowrap;
173
+ }
174
+
175
+ /*
176
+ * A CHANGE IS COLOURED BY WHETHER IT WAS WANTED, not by its direction: the
177
+ * sign already says which way the number moved. Good news takes the success
178
+ * ink and bad news the danger ink, the steps measured as TEXT on every rung;
179
+ * a change that is neither takes the secondary ink, a step up from the words
180
+ * after it, so the figure still leads the sentence.
181
+ */
182
+ .crewlet-statcard__delta {
183
+ font-variant-numeric: tabular-nums;
184
+ }
185
+
186
+ .crewlet-statcard__delta--good { color: var(--color-feedback-success-ink); }
187
+ .crewlet-statcard__delta--bad { color: var(--color-feedback-danger-ink); }
188
+ .crewlet-statcard__delta--neutral { color: var(--color-text-secondary); }
189
+
190
+ /*
191
+ * A SECOND LINE THAT REPORTS A STATE takes that state's ink ("Oldest waiting
192
+ * 2h 10m" is a person kept waiting: warning), the step measured as text on
193
+ * every rung, as the value's tone does. The delta inside the line keeps its
194
+ * own ink, which is a class on the delta and outranks this one on the line.
195
+ */
196
+ .crewlet-statcard__sub--success { color: var(--color-feedback-success-ink); }
197
+ .crewlet-statcard__sub--warning { color: var(--color-feedback-warning-ink); }
198
+ .crewlet-statcard__sub--danger { color: var(--color-feedback-danger-ink); }
199
+ .crewlet-statcard__sub--info { color: var(--color-feedback-info-ink); }
200
+
201
+ .crewlet-statcard--success .crewlet-statcard__value { color: var(--color-feedback-success-ink); }
202
+ .crewlet-statcard--warning .crewlet-statcard__value { color: var(--color-feedback-warning-ink); }
203
+ .crewlet-statcard--danger .crewlet-statcard__value { color: var(--color-feedback-danger-ink); }
204
+ .crewlet-statcard--info .crewlet-statcard__value { color: var(--color-feedback-info-ink); }
@@ -1,2 +1,2 @@
1
- export { StatGroup } from '../chunk-QNCVHRZL.js';
1
+ export { StatGroup } from '../chunk-QVAFL2LE.js';
2
2
  import '../chunk-ODEQTPFM.js';
@@ -10,14 +10,13 @@
10
10
  .crewlet-stat-group {
11
11
  display: grid;
12
12
  grid-template-columns: repeat(var(--crewlet-stat-group-cols, 4), minmax(0, 1fr));
13
- /* The flush-panel recipe: the surface, the hairline, the 12px corner and
14
- `overflow: hidden`, which is what lets the tiles inside sit against the
15
- corners without their own hairlines escaping past them. The engine puts
16
- its stat row inside exactly this. */
13
+ /* The flush-panel recipe: the card's surface, its hairline and its 12px
14
+ corner, flat as every card is, and `overflow: hidden`, which is what lets
15
+ the tiles inside sit against the corners without their own hairlines
16
+ escaping past them. */
17
17
  background: var(--color-surface-subtle);
18
18
  border: 1px solid var(--color-border-default);
19
19
  border-radius: var(--radius-lg);
20
- box-shadow: var(--shadow-xs), var(--shadow-hairline);
21
20
  overflow: hidden;
22
21
  }
23
22
 
@@ -38,7 +37,6 @@
38
37
  background: transparent;
39
38
  border: 0;
40
39
  border-radius: var(--radius-none);
41
- box-shadow: none;
42
40
  }
43
41
 
44
42
  /*
@@ -57,13 +55,14 @@
57
55
 
58
56
  /*
59
57
  * Two columns under the shell breakpoint, which is where the engine drops its
60
- * own stat row: 900px is a 280px rail plus a 620px content column, so it is
61
- * the width at which a four-up row of numbers stops having a column each. The
58
+ * own stat row, and strictly under it, as the shell switches. The step is
59
+ * 1024px, a 236px rail, the 8px inset and a 780px floor for the sheet, and it
60
+ * is the width at which the shell stops holding the page beside the rail. The
62
61
  * rules are written for the general case rather than per column count: the
63
62
  * first tile of each pair loses its left hairline, and everything on the
64
63
  * second row and below gains a top one.
65
64
  */
66
- @media (max-width: 900px) {
65
+ @media (width < 1024px) {
67
66
  .crewlet-stat-group {
68
67
  grid-template-columns: repeat(2, minmax(0, 1fr));
69
68
  }
@@ -1,12 +1,30 @@
1
- import type { PhaseTone, Tone } from '../utils/tone.js';
1
+ import type { ReactNode } from 'react';
2
+ import type { Tone } from '../utils/tone.js';
2
3
  export interface StatusDotProps {
3
- /** Which state, or which phase. Neutral says "nothing in particular". */
4
- tone?: Tone | PhaseTone | undefined;
5
4
  /**
6
- * A slow pulse, for a state that is still happening. Held still under a
7
- * reduced-motion preference, where the mark still reads as its tone.
5
+ * Which state. Neutral says "nothing in particular", and it is also the dot
6
+ * beside a category's word, such as a phase's: a category has no hue.
7
+ */
8
+ tone?: Tone | undefined;
9
+ /**
10
+ * A halo that breathes out round the dot and back, in the tone's soft step,
11
+ * for a state that is still happening: the approved design pulses the
12
+ * `info` dot, which is working. One round is `--motion-duration-breath`. The
13
+ * dot itself never fades, and the halo never touches it: it is cast from a
14
+ * ring 2px out, so the dot always stands on the surface its fill clears 3:1
15
+ * against. Held still under a reduced-motion preference, where the dot rests
16
+ * at its fill with no halo and the word beside it still says the work is
17
+ * under way. The ring is drawn on the dot's `::after`, and a `position` of
18
+ * your own on the dot still wins over the one the ring needs.
8
19
  */
9
20
  pulse?: boolean | undefined;
21
+ /**
22
+ * The word the dot belongs to: "Reviewing !231". Given one, the dot and the
23
+ * word are drawn as one line, `.crewlet-status`, with the room between them
24
+ * the kit decides rather than the caller (see the stylesheet), and
25
+ * `className` goes on that line. The word is read; the dot still is not.
26
+ */
27
+ children?: ReactNode;
10
28
  className?: string | undefined;
11
29
  }
12
30
  /**
@@ -22,4 +40,4 @@ export interface StatusDotProps {
22
40
  * it can sit on, because a mark is read the way a glyph is rather than the way
23
41
  * text is.
24
42
  */
25
- export declare function StatusDot({ tone, pulse, className }: StatusDotProps): import("react").JSX.Element;
43
+ export declare function StatusDot({ tone, pulse, children, className }: StatusDotProps): import("react").JSX.Element;
@@ -1,2 +1,2 @@
1
- export { StatusDot } from '../chunk-PZSWF74H.js';
1
+ export { StatusDot } from '../chunk-WIATRXEJ.js';
2
2
  import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,186 @@
1
+ /*
2
+ * The status dot: a 7px mark in its tone's fill, beside the word it belongs
3
+ * to. See the component doc for why it is hidden from assistive technology.
4
+ *
5
+ * 7px is the approved design's dot. The size is written out rather than
6
+ * taken from a scale because it is the measure of one mark, not a step
7
+ * anything else shares, and it is fixed at every density: a mark read the
8
+ * way a glyph is does not shrink with the gaps around it.
9
+ *
10
+ * TWO VALUES PER TONE: the fill the dot is painted in, and the HALO a pulsing
11
+ * dot breathes out in, which is the same tone's soft step. The halo is held to
12
+ * being SEEN rather than to a contrast ratio: it never touches the dot (see the
13
+ * pulse below), so the dot clears 3:1 against the surface it stands on at every
14
+ * point of the round, and the word beside it says the state. The halo only has
15
+ * to stand off its ground by the dE 3 the palette suite holds every "can a
16
+ * reader notice it" difference to. Every soft step does, by 4.48 at the least.
17
+ */
18
+
19
+ .crewlet-status-dot {
20
+ display: inline-block;
21
+ width: 7px;
22
+ height: 7px;
23
+ border-radius: var(--radius-circle);
24
+ /*
25
+ * The quiet state is still a mark, so it takes the tertiary step rather than
26
+ * the decoration one the engine spends here: a 7px dot has to clear 3:1 to
27
+ * be seen at all, and --color-text-muted measures 2.33:1 on a light page and
28
+ * 2.25:1 on a dark one at their worst grounds. The tertiary step measures
29
+ * 4.87:1 and 4.65:1 on the same pair, and is the nearest step that holds.
30
+ */
31
+ background: var(--color-text-tertiary);
32
+ /*
33
+ * The neutral family has no soft step, because it has no hue to tint with,
34
+ * so its halo is a translucent overlay. Pressed is the one that reads like
35
+ * the tones' halos: it stands dE 6.09 off its faintest ground (the light
36
+ * frame) and 8.84 in dark, inside the 4.48 to 8.50 the soft steps span. The
37
+ * hover overlay stands 3.03, on the floor, and the inset well 1.79, under it.
38
+ */
39
+ --crewlet-status-dot-halo: var(--color-surface-pressed);
40
+ flex: none;
41
+ }
42
+
43
+ .crewlet-status-dot--info {
44
+ background: var(--color-feedback-info);
45
+ --crewlet-status-dot-halo: var(--color-feedback-info-soft);
46
+ }
47
+
48
+ .crewlet-status-dot--success {
49
+ background: var(--color-feedback-success);
50
+ --crewlet-status-dot-halo: var(--color-feedback-success-soft);
51
+ }
52
+
53
+ .crewlet-status-dot--warning {
54
+ background: var(--color-feedback-warning);
55
+ --crewlet-status-dot-halo: var(--color-feedback-warning-soft);
56
+ }
57
+
58
+ .crewlet-status-dot--danger {
59
+ background: var(--color-feedback-danger);
60
+ --crewlet-status-dot-halo: var(--color-feedback-danger-soft);
61
+ }
62
+
63
+ .crewlet-status-dot--brand {
64
+ background: var(--color-brand-accent);
65
+ --crewlet-status-dot-halo: var(--color-brand-accent-soft);
66
+ }
67
+
68
+ /*
69
+ * STILL HAPPENING: a halo breathes out round the dot and back in, the approved
70
+ * design's working pulse. Five things are deliberate.
71
+ *
72
+ * THE DOT NEVER FADES. The halo is a box-shadow and it is the only property
73
+ * the keyframes touch, so the fill stays at the step measured to 3:1 through
74
+ * the whole round. The pulse this replaced faded the dot itself to 0.35, and
75
+ * at the bottom of that fade every fill measured 1.35:1 to 2.17:1 against the
76
+ * surfaces it sits on: for part of every round, a mark under its own floor.
77
+ *
78
+ * NOR DOES THE HALO TOUCH IT. The design casts the halo from the dot itself,
79
+ * and a spread shadow starts at the edge of the box that casts it, so for the
80
+ * whole round the dot's ground would be its own soft step on the surface
81
+ * rather than the surface. On that ground the light info, success and warning
82
+ * fills measure 2.65:1 to 2.95:1 (warning and success on the frame, where they
83
+ * clear 3.00:1 and 3.01:1 bare): the same fault as the fade, smaller. So the
84
+ * halo is cast by a RING BOX 2px outside the dot, the offset the Avatar state
85
+ * ring and the outer focus ring stand at, and an outer shadow is never painted
86
+ * inside the box that casts it: a band of the real ground always stands
87
+ * between the dot and its halo, so the dot always stands on the surface its
88
+ * fill was measured against. The fill does not move. Nothing in this kit
89
+ * holds a mark to its own soft step, which is also why a Tag draws its dot in
90
+ * its ink.
91
+ *
92
+ * A SHADOW ON A PSEUDO-ELEMENT, not an outline at the same offset, because an
93
+ * outline's width is snapped to whole device pixels, as a border's is: at 1x
94
+ * a width breathing to 3px is drawn 1px and then 2px and reaches 3px for an
95
+ * instant, a flicker between two rings rather than a breath, where a spread
96
+ * shadow grows smoothly. The ring box is absolutely positioned, so it takes
97
+ * no room, and the pulsing dot is its containing block through a rule written
98
+ * in :where(), which weighs nothing, so a position of your own on the dot
99
+ * still wins, and any position but static keeps the ring on it.
100
+ *
101
+ * IT REACHES THE DESIGN'S 5PX, 2 of ground and 3 of halo, painted outside
102
+ * every box, so it moves nothing beside the dot. Like the 7px it surrounds,
103
+ * it is the measure of this one mark and is fixed at every density.
104
+ *
105
+ * ONE ROUND IS --motion-duration-breath, which is a PERIOD rather than a
106
+ * transition: out by the half, back by the end, and no `alternate`, which
107
+ * would play each half as a whole duration and take twice as long. That is
108
+ * 0.45 rounds a second, far under the three flashes a second that are a
109
+ * seizure risk, and the in-out ease makes both ends a rest. The halo is read
110
+ * through the custom property each tone sets above, which the ring box
111
+ * inherits, so whichever tone pulses breathes in its own soft step.
112
+ */
113
+ :where(.crewlet-status-dot.is-pulsing) {
114
+ position: relative;
115
+ }
116
+
117
+ .crewlet-status-dot.is-pulsing::after {
118
+ content: '';
119
+ position: absolute;
120
+ inset: -2px;
121
+ border-radius: var(--radius-circle);
122
+ /* Paint, never a target: the box reaches 2px past the dot. */
123
+ pointer-events: none;
124
+ animation: crewlet-status-dot-pulse var(--motion-duration-breath) var(--motion-easing-in-out) infinite;
125
+ }
126
+
127
+ /*
128
+ * The spread moves and nothing else: the rests and the peak are one shadow in
129
+ * one colour, so the only thing that interpolates is how far it reaches.
130
+ */
131
+ @keyframes crewlet-status-dot-pulse {
132
+ 0%,
133
+ 100% {
134
+ box-shadow: 0 0 0 0 var(--crewlet-status-dot-halo);
135
+ }
136
+
137
+ 50% {
138
+ box-shadow: 0 0 0 3px var(--crewlet-status-dot-halo);
139
+ }
140
+ }
141
+
142
+ /*
143
+ * A DOT WITH ITS WORD: one line, the dot and then the word, the way every
144
+ * dot in this kit is meant to be read.
145
+ *
146
+ * THE GAP CLEARS THE HALO. A pulsing dot's halo reaches 5px past its edge, 2
147
+ * of ground and 3 of halo, painted outside every box, so it takes no room and
148
+ * a gap narrower than that puts the halo on the first letter at every peak:
149
+ * at the 4px an ordinary mark stands off its word, it struck the R of
150
+ * "Reviewing". 7px is that reach and 2px of ground on the far side of it, the
151
+ * same band that stands between the dot and its halo, so at the peak the word
152
+ * stands off the halo exactly as the halo stands off the dot. It is written in
153
+ * pixels, not a spacing step, because what it clears is fixed at every
154
+ * density like the dot and the halo themselves, and it is the same for EVERY
155
+ * tone, pulsing or not, so a column of statuses starts its words on one line
156
+ * whichever of them is breathing.
157
+ */
158
+ .crewlet-status {
159
+ display: inline-flex;
160
+ align-items: center;
161
+ gap: 7px;
162
+ min-width: 0;
163
+ max-width: 100%;
164
+ }
165
+
166
+ /* A status is one line, and the word is what gives way: the dot never does. */
167
+ .crewlet-status__label {
168
+ min-width: 0;
169
+ overflow: hidden;
170
+ text-overflow: ellipsis;
171
+ white-space: nowrap;
172
+ }
173
+
174
+ /*
175
+ * HELD, not slowed: a mark that loops for as long as the work runs is exactly
176
+ * what the setting is for. The stop names the selector that starts the pulse
177
+ * and comes after it, so it wins on source order at the same specificity,
178
+ * which is the pairing the package's literal check holds every stylesheet to.
179
+ * The dot rests at its own fill with no halo, and the word beside it still
180
+ * says the work is under way.
181
+ */
182
+ @media (prefers-reduced-motion: reduce) {
183
+ .crewlet-status-dot.is-pulsing::after {
184
+ animation: none;
185
+ }
186
+ }
@@ -0,0 +1,78 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ import type { Tone } from '../utils/tone.js';
3
+ /**
4
+ * The state the CURRENT step is in, drawn as its chip's soft tint under its
5
+ * ink. `info` is the default: work under way, the design's working step. A
6
+ * run parked on a question is `warning`, one that stopped at this step is
7
+ * `danger`, and `brand` is where the reader is, for a sequence the reader is
8
+ * walking themselves.
9
+ *
10
+ * NOT `neutral`. The quiet chip is what every step that is not current already
11
+ * is, so a neutral current step would be told from its neighbours by nothing
12
+ * but `aria-current`, which nobody sees.
13
+ */
14
+ export type StepperTone = Exclude<Tone, 'neutral'>;
15
+ /** One step of the sequence. */
16
+ export interface StepperStep {
17
+ /** What tells two steps apart, unique within the stepper: `execute`, `review`. */
18
+ id: string;
19
+ /**
20
+ * The step's words, and anything the step carries beside them: "Execute ·
21
+ * round 7 of 25", "Context 0.8s".
22
+ */
23
+ label: ReactNode;
24
+ }
25
+ export interface StepperProps extends Omit<HTMLAttributes<HTMLOListElement>, 'children'> {
26
+ /** Every step, in order. */
27
+ steps: readonly StepperStep[];
28
+ /**
29
+ * The step under way, by its id. Every step before it is done and every
30
+ * step after it is still to come. `null` once EVERY step is done, which is
31
+ * how a finished run is drawn: a turn's history in a task's timeline reads
32
+ * "Execute ✓ — Review ✓" with nothing current.
33
+ */
34
+ current: string | null;
35
+ /**
36
+ * What the sequence is, for a screen reader: "Turn progress". REQUIRED,
37
+ * because a list of four short words with nothing to say what they are the
38
+ * steps OF is a riddle to somebody who cannot see the row it stands in.
39
+ */
40
+ label: string;
41
+ /** The current step's state. `info` by default. */
42
+ tone?: StepperTone | undefined;
43
+ /**
44
+ * The current step's dot breathes, for a step still under way: the approved
45
+ * design pulses a working turn's. It is `StatusDot`'s own pulse, so it
46
+ * never fades the dot, never touches it, and is held still under a reduced
47
+ * motion preference.
48
+ */
49
+ pulse?: boolean | undefined;
50
+ /**
51
+ * Said before a finished step's words, where the check glyph stands for a
52
+ * reader who sees it: "Done Context".
53
+ */
54
+ doneLabel?: string | undefined;
55
+ }
56
+ /**
57
+ * Where a sequence has got to: the phases of a turn, the stages of a run.
58
+ *
59
+ * AN ORDERED LIST, because the order IS the information: a step's position
60
+ * says whether it is behind the current one or ahead of it, and a list says
61
+ * how many there are before a reader has heard any of them. The step under
62
+ * way carries `aria-current="step"`, the one value ARIA gives this exact
63
+ * meaning, and it is on exactly one step while the sequence is running and on
64
+ * none once it has finished.
65
+ *
66
+ * THREE STATES, EACH DRAWN TWO WAYS, so colour is never the only carrier. A
67
+ * finished step is the secondary ink with a check, and says "Done" before its
68
+ * words to a screen reader, where the check stands for a reader who sees it.
69
+ * The current step is its tone's soft tint under the tone's ink with the
70
+ * tone's dot, and is `aria-current`. A step still to come is the tertiary ink
71
+ * and nothing else. The hairline round the chips, and the short rule between
72
+ * two of them, are the design's quiet furniture.
73
+ *
74
+ * THE TONE IS DRAWN, NEVER SPOKEN: a reader hears which step is current, not
75
+ * that it is in the warning hue. A current step whose state is anything but
76
+ * ordinary work says so in its own words ("Review · sent back").
77
+ */
78
+ export declare function Stepper({ steps, current, label, tone, pulse, doneLabel, className, ...rest }: StepperProps): import("react").JSX.Element | null;
@@ -0,0 +1,3 @@
1
+ import './Stepper.css';
2
+ export { Stepper } from './Stepper.js';
3
+ export type { StepperProps, StepperStep, StepperTone } from './Stepper.js';
@@ -0,0 +1,4 @@
1
+ export { Stepper } from '../chunk-5QWIJSQM.js';
2
+ import '../chunk-WIATRXEJ.js';
3
+ import '../chunk-BZFWDIV6.js';
4
+ import '../chunk-ODEQTPFM.js';