@crewlethq/ui 0.12.0 → 0.14.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 (157) hide show
  1. package/README.md +82 -5
  2. package/dist/AppShell/index.js +2 -1
  3. package/dist/Avatar/index.js +1 -1
  4. package/dist/{Avatar-QHYOFID3.css → Avatar-BPJ36QZR.css} +1 -1
  5. package/dist/AvatarPicker/index.js +5 -5
  6. package/dist/Breadcrumb/Breadcrumb.d.ts +68 -0
  7. package/dist/Breadcrumb/index.d.ts +3 -0
  8. package/dist/Breadcrumb/index.js +3 -0
  9. package/dist/Breadcrumb-YMWVM3SV.css +193 -0
  10. package/dist/ChoiceButtons/ChoiceButtons.d.ts +43 -0
  11. package/dist/ChoiceButtons/index.d.ts +3 -0
  12. package/dist/ChoiceButtons/index.js +3 -0
  13. package/dist/ChoiceButtons-DJ5EOGUA.css +127 -0
  14. package/dist/Combobox/index.js +2 -2
  15. package/dist/CommandPalette/CommandPalette.d.ts +48 -1
  16. package/dist/CommandPalette/index.js +3 -3
  17. package/dist/{CommandPalette-C5AMKGN2.css → CommandPalette-HBTNKHZQ.css} +55 -2
  18. package/dist/DataTable/index.js +4 -4
  19. package/dist/DataView/index.js +11 -11
  20. package/dist/DateTimePicker/index.js +2 -2
  21. package/dist/{DateTimePicker-4AZBTODT.css → DateTimePicker-NJ6XH2TE.css} +4 -3
  22. package/dist/Document/Document.d.ts +56 -0
  23. package/dist/Document/index.d.ts +3 -0
  24. package/dist/Document/index.js +2 -0
  25. package/dist/Document-PQGXJHB7.css +288 -0
  26. package/dist/EntityChip/index.js +1 -1
  27. package/dist/Highlight/Highlight.d.ts +45 -0
  28. package/dist/Highlight/index.d.ts +3 -0
  29. package/dist/Highlight/index.js +2 -0
  30. package/dist/Highlight-DXLV2R6L.css +29 -0
  31. package/dist/HuePicker/index.js +3 -3
  32. package/dist/ImageUpload/index.js +2 -2
  33. package/dist/{ImageUpload-L2GE4JUM.css → ImageUpload-NVGMN7DP.css} +9 -6
  34. package/dist/InboxList/InboxList.d.ts +116 -0
  35. package/dist/InboxList/index.d.ts +3 -0
  36. package/dist/InboxList/index.js +5 -0
  37. package/dist/InboxList-YMFWKGGS.css +252 -0
  38. package/dist/KeyChip/KeyChip.d.ts +21 -0
  39. package/dist/KeyChip/index.d.ts +3 -0
  40. package/dist/KeyChip/index.js +2 -0
  41. package/dist/KeyChip-4XJU4BBE.css +30 -0
  42. package/dist/Link/Link.d.ts +17 -2
  43. package/dist/Link/index.js +1 -1
  44. package/dist/{Link-6BEFNMN2.css → Link-WPMVLKLY.css} +36 -1
  45. package/dist/Listbox/index.d.ts +2 -0
  46. package/dist/Listbox/index.js +1 -1
  47. package/dist/Listbox/useHighlightRest.d.ts +35 -0
  48. package/dist/MarkdownEditor/MarkdownEditor.d.ts +93 -0
  49. package/dist/MarkdownEditor/format.d.ts +34 -0
  50. package/dist/MarkdownEditor/index.d.ts +5 -0
  51. package/dist/MarkdownEditor/index.js +12 -0
  52. package/dist/MarkdownEditor-ZLSHTOIZ.css +146 -0
  53. package/dist/Modal/Modal.d.ts +5 -1
  54. package/dist/Modal/index.js +1 -1
  55. package/dist/{Modal-BNT3TDV2.css → Modal-RQAYGG4L.css} +34 -1
  56. package/dist/OrgLabel/index.js +1 -1
  57. package/dist/OrgNode/index.js +1 -1
  58. package/dist/OrgTable/index.js +4 -4
  59. package/dist/Outline/Outline.d.ts +72 -0
  60. package/dist/Outline/index.d.ts +3 -0
  61. package/dist/Outline/index.js +2 -0
  62. package/dist/Outline-VCXKKU3E.css +78 -0
  63. package/dist/Popover/Popover.d.ts +21 -1
  64. package/dist/Popover/index.js +1 -1
  65. package/dist/ReadingPane/ReadingPane.d.ts +95 -0
  66. package/dist/ReadingPane/index.d.ts +3 -0
  67. package/dist/ReadingPane/index.js +4 -0
  68. package/dist/ReadingPane-5UOLPWY5.css +194 -0
  69. package/dist/SegmentedControl/SegmentedControl.d.ts +9 -1
  70. package/dist/SegmentedControl/index.js +3 -3
  71. package/dist/{SegmentedControl-76HODRBT.css → SegmentedControl-PKBLJVSA.css} +18 -0
  72. package/dist/Select/Select.d.ts +22 -0
  73. package/dist/Select/index.js +2 -2
  74. package/dist/{Select-4ANVLHUY.css → Select-2P7AWUE4.css} +56 -6
  75. package/dist/SidebarNav/index.js +2 -1
  76. package/dist/{SidebarNav-X5NLZNWA.css → SidebarNav-KF66MLOM.css} +4 -19
  77. package/dist/Switcher/Switcher.d.ts +151 -0
  78. package/dist/Switcher/index.d.ts +3 -0
  79. package/dist/Switcher/index.js +16 -0
  80. package/dist/Switcher-B44Q4WF4.css +346 -0
  81. package/dist/Tabs/Tabs.d.ts +7 -1
  82. package/dist/Tabs/index.js +1 -1
  83. package/dist/{Tabs-5I5Q5KKM.css → Tabs-ITJYJFMU.css} +49 -0
  84. package/dist/TagsInput/index.js +2 -2
  85. package/dist/ThemeGallery/ThemeGallery.d.ts +65 -0
  86. package/dist/ThemeGallery/index.d.ts +3 -0
  87. package/dist/ThemeGallery/index.js +6 -0
  88. package/dist/ThemeGallery-NITASULQ.css +93 -0
  89. package/dist/ThemeSwatch/ThemeSwatch.d.ts +71 -0
  90. package/dist/ThemeSwatch/index.d.ts +3 -0
  91. package/dist/ThemeSwatch/index.js +2 -0
  92. package/dist/ThemeSwatch-4DL457ZB.css +256 -0
  93. package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +5 -1
  94. package/dist/ThemeSwitcher/index.js +4 -4
  95. package/dist/ThemeToggle/ThemeToggle.d.ts +1 -1
  96. package/dist/ThemeToggle/index.js +1 -1
  97. package/dist/TimeWindowPicker/index.js +4 -4
  98. package/dist/{TimeWindowPicker-GBF4JDFI.css → TimeWindowPicker-BZ5HHATU.css} +5 -4
  99. package/dist/Toaster/index.js +1 -1
  100. package/dist/{Toaster-NVDCEIP5.css → Toaster-VZKISP2S.css} +81 -87
  101. package/dist/Tree/index.d.ts +1 -1
  102. package/dist/Tree/index.js +1 -1
  103. package/dist/Tree/useTreeState.d.ts +37 -7
  104. package/dist/TreeCanvas/index.js +2 -2
  105. package/dist/TreeGrid/TreeGrid.d.ts +22 -2
  106. package/dist/TreeGrid/index.js +2 -2
  107. package/dist/{TreeGrid-NSW7VMOX.css → TreeGrid-FBX3MSJA.css} +19 -0
  108. package/dist/{chunk-EBBAAQDY.js → chunk-26PEPONN.js} +3 -1
  109. package/dist/{chunk-GOUKOXJK.js → chunk-3VVKJ7AZ.js} +3 -3
  110. package/dist/{chunk-HV6IZFBK.js → chunk-4FFHJBEN.js} +2 -2
  111. package/dist/{chunk-JHQUT4WJ.js → chunk-4LDTQWS7.js} +1 -1
  112. package/dist/{chunk-GXYNEDNA.js → chunk-4Y7WKXAW.js} +1 -1
  113. package/dist/{chunk-IINFVK3W.js → chunk-5IXMLWGW.js} +6 -6
  114. package/dist/{chunk-MCPKHYMC.js → chunk-6LXMLQUM.js} +17 -4
  115. package/dist/{chunk-3UK4VFSK.js → chunk-6NIZCQUM.js} +1 -1
  116. package/dist/{chunk-ORNOOMVY.js → chunk-6TSZCBID.js} +2 -2
  117. package/dist/{chunk-ZMJHK7DR.js → chunk-75WOCYGC.js} +2 -2
  118. package/dist/chunk-77IEHFY4.js +299 -0
  119. package/dist/chunk-A5YKNRG6.js +94 -0
  120. package/dist/{chunk-JCNUQ3US.js → chunk-AXNQCAFC.js} +2 -2
  121. package/dist/{chunk-UG5ZMAXW.js → chunk-CBZSSKH3.js} +5 -5
  122. package/dist/{chunk-LAQK4V3Z.js → chunk-DJMLHCLD.js} +1 -1
  123. package/dist/{chunk-6MU7HNB4.js → chunk-F73MC7EZ.js} +47 -2
  124. package/dist/{chunk-ZPSOF6VL.js → chunk-FBSEJO2C.js} +1 -1
  125. package/dist/chunk-FYTIJM2T.js +40 -0
  126. package/dist/chunk-H6VKCIWV.js +41 -0
  127. package/dist/{chunk-HLBRPES3.js → chunk-IFM63LAG.js} +3 -3
  128. package/dist/chunk-IG75YMUN.js +22 -0
  129. package/dist/{chunk-SEFMO2EV.js → chunk-IXUU5DLZ.js} +55 -6
  130. package/dist/{chunk-ZHOM65MI.js → chunk-JCO3SIST.js} +1 -1
  131. package/dist/chunk-KLIEPFEZ.js +95 -0
  132. package/dist/{chunk-7LD6P32I.js → chunk-L3CTFFLZ.js} +2 -18
  133. package/dist/chunk-MNFU2RNT.js +74 -0
  134. package/dist/{chunk-S3BCVWTU.js → chunk-MY374UUD.js} +49 -31
  135. package/dist/{chunk-K5Q2DK3P.js → chunk-NXDEPUVG.js} +1 -1
  136. package/dist/{chunk-PDUZO35I.js → chunk-O2ZDZZS7.js} +15 -6
  137. package/dist/{chunk-5WEVLIB6.js → chunk-RZ7RGECB.js} +1 -1
  138. package/dist/{chunk-WEIINZPA.js → chunk-SBRE7IML.js} +6 -2
  139. package/dist/{chunk-TEEJSTFG.js → chunk-TFMJH2E6.js} +1 -1
  140. package/dist/{chunk-IVFJD7WY.js → chunk-UCCC7YVZ.js} +3 -2
  141. package/dist/chunk-VWNC2L6W.js +110 -0
  142. package/dist/chunk-VYY56AMX.js +2 -0
  143. package/dist/chunk-WI6K5M5X.js +24 -0
  144. package/dist/{chunk-XV65NTIT.js → chunk-WYQOHFML.js} +94 -41
  145. package/dist/chunk-XYCADWZN.js +100 -0
  146. package/dist/chunk-Y6NR7QJ3.js +336 -0
  147. package/dist/chunk-YSJC7AZC.js +62 -0
  148. package/dist/chunk-ZAJHGDAW.js +93 -0
  149. package/dist/generated/index.d.ts +12 -0
  150. package/dist/generated/index.js +64 -51
  151. package/dist/index.js +64 -51
  152. package/dist/styles.css +2711 -402
  153. package/dist/utils/highlight.d.ts +17 -0
  154. package/dist/utils/useMediaMatch.d.ts +12 -0
  155. package/package.json +3 -3
  156. package/dist/chunk-UAQIUSSK.js +0 -2
  157. /package/dist/{chunk-74OVQWA5.js → chunk-6AR2T5Y4.js} +0 -0
package/dist/styles.css CHANGED
@@ -1088,7 +1088,7 @@
1088
1088
  }
1089
1089
 
1090
1090
 
1091
- /* Avatar-QHYOFID3.css */
1091
+ /* Avatar-BPJ36QZR.css */
1092
1092
  /*
1093
1093
  * The identity badge.
1094
1094
  *
@@ -1233,7 +1233,7 @@
1233
1233
  }
1234
1234
 
1235
1235
  .crewlet-avatar--seeded {
1236
- color: var(--color-text-on-accent);
1236
+ color: var(--color-text-on-scrim);
1237
1237
  }
1238
1238
 
1239
1239
  .crewlet-avatar--tint-0 { background: var(--color-avatar-tint-0); }
@@ -1662,6 +1662,202 @@ button.crewlet-avatar-picker:hover .crewlet-avatar-picker__pip {
1662
1662
  }
1663
1663
 
1664
1664
 
1665
+ /* Breadcrumb-YMWVM3SV.css */
1666
+ /*
1667
+ * The trail in a top bar.
1668
+ *
1669
+ * IT IS WHAT GIVES WAY, AND WHAT TAKES THE SLACK. `flex-grow: 1` is the spacer
1670
+ * a bar would otherwise need: the trail absorbs the free space, so the
1671
+ * controls after it stay in the bar's far corner. Its BASIS is 0, which is
1672
+ * what lets a wrapping bar break by what it holds rather than at a width, and
1673
+ * `flex-shrink: 100` puts it ahead of anything else on the bar that can give.
1674
+ *
1675
+ * ITS FLOOR IS THE WAY BACK OUT, measured by the component
1676
+ * (`--crewlet-breadcrumb-floor`): the ancestors at their width and the last
1677
+ * crumb's stub, at least 20ch, and never more than the whole bar. A fixed 20ch
1678
+ * alone let a seat's trail share a phone's line with its one button and cut
1679
+ * "Engineering · Co" mid-letter under it; measured, a trail that cannot show
1680
+ * its ancestry beside the controls makes the bar break a line instead.
1681
+ *
1682
+ * Past the whole bar the trail SCROLLS rather than clipping as a box: the
1683
+ * ancestors never shrink, so once they alone are wider than the bar there is
1684
+ * nothing left to ellipsise, and a clip lands wherever the pixels ran out.
1685
+ */
1686
+ .crewlet-breadcrumb {
1687
+ display: flex;
1688
+ align-items: center;
1689
+ gap: 2px;
1690
+ flex: 1 100 0;
1691
+ min-width: min(100%, max(20ch, var(--crewlet-breadcrumb-floor, 0px)));
1692
+ overflow-x: auto;
1693
+ overflow-y: hidden;
1694
+ overscroll-behavior-x: contain;
1695
+ scrollbar-width: none;
1696
+ font-size: var(--font-size-sm);
1697
+ }
1698
+
1699
+ .crewlet-breadcrumb::-webkit-scrollbar {
1700
+ display: none;
1701
+ }
1702
+
1703
+ /* A trail that overflows is a tab stop (see Breadcrumb.tsx), and shows it. */
1704
+ .crewlet-breadcrumb:focus-visible {
1705
+ outline: 2px solid var(--color-focus);
1706
+ outline-offset: var(--size-focus-ring-inset-offset);
1707
+ }
1708
+
1709
+ .crewlet-breadcrumb__part {
1710
+ display: inline-flex;
1711
+ align-items: center;
1712
+ gap: 2px;
1713
+ min-width: 0;
1714
+ }
1715
+
1716
+ /*
1717
+ * THE OBJECT'S OWN NAME TAKES THE CUT, never the way back out. The reader
1718
+ * knows which object they are on, because the page below says so; what they
1719
+ * cannot reconstruct is the links out of it. So the ancestors keep their width
1720
+ * and the last part is the one that ellipsises.
1721
+ */
1722
+ .crewlet-breadcrumb__part:not(:last-child) {
1723
+ flex: 0 0 auto;
1724
+ }
1725
+
1726
+ svg.crewlet-breadcrumb__separator {
1727
+ flex: none;
1728
+ margin: 0 var(--spacing-1);
1729
+ color: var(--color-text-muted);
1730
+ }
1731
+
1732
+ .crewlet-breadcrumb__crumb,
1733
+ .crewlet-breadcrumb__here {
1734
+ display: inline-flex;
1735
+ align-items: center;
1736
+ gap: calc(var(--spacing-1) * 1.5);
1737
+ min-width: 0;
1738
+ white-space: nowrap;
1739
+ overflow: hidden;
1740
+ text-overflow: ellipsis;
1741
+ }
1742
+
1743
+ /*
1744
+ * The ancestors in the quiet ink: a link lifts to the primary ink under the
1745
+ * pointer, and one with nothing to press stays where it is. NO UNDERLINE: a
1746
+ * crumb is a piece of chrome, not a word in a sentence, and the step between
1747
+ * two measured text rungs is its hover in both themes.
1748
+ */
1749
+ .crewlet-breadcrumb__crumb {
1750
+ border-radius: var(--radius-xs);
1751
+ color: var(--color-text-tertiary);
1752
+ text-decoration: none;
1753
+ transition: color var(--motion-duration-fast) var(--motion-easing-default);
1754
+ }
1755
+
1756
+ a.crewlet-breadcrumb__crumb:hover {
1757
+ color: var(--color-text-primary);
1758
+ text-decoration: none;
1759
+ }
1760
+
1761
+ a.crewlet-breadcrumb__crumb:focus-visible {
1762
+ outline: 2px solid var(--color-focus);
1763
+ outline-offset: var(--size-focus-ring-inset-offset);
1764
+ }
1765
+
1766
+ /* FORCED COLOURS paints a link LinkText hovered or not, so the ink step cannot
1767
+ be seen there: the rule under the words is the hover in that mode. */
1768
+ @media (forced-colors: active) {
1769
+ a.crewlet-breadcrumb__crumb:hover {
1770
+ text-decoration: underline;
1771
+ }
1772
+ }
1773
+
1774
+ /* A glyph sits a step further from its word than a chip does from its name. */
1775
+ .crewlet-breadcrumb__icon {
1776
+ display: inline-flex;
1777
+ flex: none;
1778
+ margin-right: calc(var(--spacing-1) / 2);
1779
+ }
1780
+
1781
+ .crewlet-breadcrumb__badge,
1782
+ .crewlet-breadcrumb__key {
1783
+ flex: none;
1784
+ }
1785
+
1786
+ /*
1787
+ * THE LABEL IS THE BOX THAT ELLIPSISES. The crumb around it is a flex
1788
+ * container, and `text-overflow` never reaches the anonymous item text inside
1789
+ * one makes; a span is a real flex item, and its `min-width: 0` is what lets
1790
+ * it shrink below its text at all.
1791
+ */
1792
+ .crewlet-breadcrumb__text {
1793
+ min-width: 0;
1794
+ overflow: hidden;
1795
+ white-space: nowrap;
1796
+ text-overflow: ellipsis;
1797
+ }
1798
+
1799
+ /* THE LAST CRUMB IS THE PAGE'S `h1`, so the heading's own margins and size are
1800
+ the bar's, not the document's. */
1801
+ .crewlet-breadcrumb__here {
1802
+ margin: 0;
1803
+ color: var(--color-text-primary);
1804
+ font-size: inherit;
1805
+ font-weight: var(--font-weight-medium);
1806
+ line-height: inherit;
1807
+ }
1808
+
1809
+ /*
1810
+ * AND IT NEVER COLLAPSES TO NOTHING: a floor of a few characters keeps an
1811
+ * ellipsised stub, which is what tells a reader the trail has a last part at
1812
+ * all. The floor is the last part's alone; an ancestor never shrinks.
1813
+ */
1814
+ .crewlet-breadcrumb__part:last-child > .crewlet-breadcrumb__here {
1815
+ min-width: 5ch;
1816
+ }
1817
+
1818
+ /*
1819
+ * A CONTROL AS THE HEADING'S WORDS draws its own edges: its hover fill and its
1820
+ * focus ring run to its own box, so the heading around it clips nothing.
1821
+ */
1822
+ .crewlet-breadcrumb__here--control {
1823
+ overflow: visible;
1824
+ }
1825
+
1826
+ /* An identifier still waiting for its name, in the mono face a step down. */
1827
+ .crewlet-breadcrumb__crumb.is-mono,
1828
+ .crewlet-breadcrumb__here.is-mono {
1829
+ font-family: var(--font-family-mono);
1830
+ font-size: var(--font-size-compact);
1831
+ }
1832
+
1833
+ /*
1834
+ * ON A PHONE AN ANCESTOR WITH A GLYPH IS ITS GLYPH. The workspace's mark is
1835
+ * the one sign of where the reader is that survives a sidebar folded into a
1836
+ * drawer, and the line it shares with the drawer toggle and the page's primary
1837
+ * action has no room for its word as well. The word stays, out of sight, so
1838
+ * the crumb is still named.
1839
+ */
1840
+ @media (width < 640px) {
1841
+ .crewlet-breadcrumb__part:not(:last-child) > .crewlet-breadcrumb__crumb:has(> .crewlet-breadcrumb__icon) > .crewlet-breadcrumb__text {
1842
+ position: absolute;
1843
+ width: 1px;
1844
+ height: 1px;
1845
+ margin: -1px;
1846
+ padding: 0;
1847
+ border: 0;
1848
+ overflow: hidden;
1849
+ clip-path: inset(50%);
1850
+ white-space: nowrap;
1851
+ }
1852
+ }
1853
+
1854
+ @media (prefers-reduced-motion: reduce) {
1855
+ .crewlet-breadcrumb__crumb {
1856
+ transition: none;
1857
+ }
1858
+ }
1859
+
1860
+
1665
1861
  /* Button-UWKBTKYD.css */
1666
1862
  /*
1667
1863
  * The button, and the link drawn as one.
@@ -4053,6 +4249,136 @@ button.crewlet-avatar-picker:hover .crewlet-avatar-picker__pip {
4053
4249
  }
4054
4250
 
4055
4251
 
4252
+ /* ChoiceButtons-DJ5EOGUA.css */
4253
+ /*
4254
+ * One answer, sent with one press: a column of buttons as tall as a touch
4255
+ * target, the recommended one first and filled with the accent.
4256
+ *
4257
+ * The plain option is the secondary button's recipe (the card's own ground
4258
+ * inside the strong hairline), and the recommended one the primary's, so the
4259
+ * pair reads as the screen's one primary action and its alternatives.
4260
+ */
4261
+
4262
+ .crewlet-choice-buttons {
4263
+ display: grid;
4264
+ grid-template-columns: minmax(0, 1fr);
4265
+ gap: var(--spacing-2);
4266
+ }
4267
+
4268
+ .crewlet-choice-buttons__option {
4269
+ display: flex;
4270
+ align-items: center;
4271
+ justify-content: space-between;
4272
+ gap: var(--spacing-3);
4273
+ min-width: 0;
4274
+ min-height: var(--size-control-lg);
4275
+ padding: calc(var(--spacing-2) + var(--spacing-1) / 2) calc(var(--spacing-3) + var(--spacing-1) / 2);
4276
+ border: 1px solid var(--color-border-strong);
4277
+ border-radius: var(--radius-md);
4278
+ background: var(--color-surface-subtle);
4279
+ color: var(--color-text-primary);
4280
+ font: inherit;
4281
+ font-size: var(--font-size-sm);
4282
+ font-weight: var(--font-weight-medium);
4283
+ line-height: var(--font-line-height-snug);
4284
+ text-align: left;
4285
+ cursor: pointer;
4286
+ transition:
4287
+ background var(--motion-duration-fast) var(--motion-easing-default),
4288
+ border-color var(--motion-duration-fast) var(--motion-easing-default);
4289
+ }
4290
+
4291
+ .crewlet-choice-buttons__option:hover:not([aria-disabled='true']) {
4292
+ background: var(--color-surface-elevated);
4293
+ border-color: var(--color-border-strong-hover);
4294
+ }
4295
+
4296
+ .crewlet-choice-buttons__option:active:not([aria-disabled='true']) {
4297
+ background: var(--color-surface-pressed);
4298
+ }
4299
+
4300
+ /*
4301
+ * The plain option draws the strong hairline, so its ring is drawn over that
4302
+ * edge rather than a gap away from it, which would read as a second outline.
4303
+ */
4304
+ .crewlet-choice-buttons__option:focus-visible {
4305
+ outline: 2px solid var(--color-focus);
4306
+ outline-offset: var(--size-focus-ring-inset-offset);
4307
+ }
4308
+
4309
+ .crewlet-choice-buttons__option[aria-disabled='true'] {
4310
+ cursor: not-allowed;
4311
+ }
4312
+
4313
+ /* The option on its way: still this option, mid-action. */
4314
+ .crewlet-choice-buttons__option[aria-busy='true'] {
4315
+ cursor: progress;
4316
+ }
4317
+
4318
+ .crewlet-choice-buttons__option--recommended {
4319
+ background: var(--color-brand-accent);
4320
+ border-color: transparent;
4321
+ color: var(--color-text-on-accent);
4322
+ }
4323
+
4324
+ .crewlet-choice-buttons__option--recommended:hover:not([aria-disabled='true']) {
4325
+ background: var(--color-brand-accent-hover);
4326
+ border-color: transparent;
4327
+ }
4328
+
4329
+ .crewlet-choice-buttons__option--recommended:active:not([aria-disabled='true']) {
4330
+ background: var(--color-brand-accent-active);
4331
+ }
4332
+
4333
+ /*
4334
+ * The accent fill draws no edge, and an inset ring on it would be drawn in
4335
+ * nearly the fill's own colour, so its ring stands off it as a primary
4336
+ * button's does.
4337
+ */
4338
+ .crewlet-choice-buttons__option--recommended:focus-visible {
4339
+ outline-offset: 2px;
4340
+ }
4341
+
4342
+ .crewlet-choice-buttons__text {
4343
+ display: grid;
4344
+ gap: 2px;
4345
+ min-width: 0;
4346
+ overflow-wrap: anywhere;
4347
+ }
4348
+
4349
+ .crewlet-choice-buttons__detail {
4350
+ font-size: var(--font-size-xs);
4351
+ font-weight: var(--font-weight-regular);
4352
+ color: var(--color-text-tertiary);
4353
+ }
4354
+
4355
+ /*
4356
+ * On the accent fill the detail takes the label's own ink. The tertiary step
4357
+ * is measured on the surfaces, not on the accent, where it does not clear.
4358
+ */
4359
+ .crewlet-choice-buttons__option--recommended .crewlet-choice-buttons__detail {
4360
+ color: var(--color-text-on-accent);
4361
+ }
4362
+
4363
+ /*
4364
+ * The mark, in the micro-label register. Full ink rather than a faded one:
4365
+ * eleven pixels of white on the accent clears 4.5:1 only at full strength.
4366
+ */
4367
+ .crewlet-choice-buttons__note {
4368
+ flex: none;
4369
+ font-size: var(--font-size-2xs);
4370
+ font-weight: var(--font-weight-medium);
4371
+ letter-spacing: var(--font-letter-spacing-wide);
4372
+ text-transform: uppercase;
4373
+ }
4374
+
4375
+ @media (prefers-reduced-motion: reduce) {
4376
+ .crewlet-choice-buttons__option {
4377
+ transition: none;
4378
+ }
4379
+ }
4380
+
4381
+
4056
4382
  /* ChoiceList-2PQJS4DX.css */
4057
4383
  /*
4058
4384
  * A short list of answers in one bordered box: a radio, the label with a line
@@ -4439,7 +4765,7 @@ button.crewlet-avatar-picker:hover .crewlet-avatar-picker__pip {
4439
4765
  }
4440
4766
 
4441
4767
 
4442
- /* CommandPalette-C5AMKGN2.css */
4768
+ /* CommandPalette-HBTNKHZQ.css */
4443
4769
  /*
4444
4770
  * The command palette: a field, an optional row of scopes, one scroller
4445
4771
  * holding the lead and the list, and a key legend.
@@ -4498,17 +4824,70 @@ button.crewlet-avatar-picker:hover .crewlet-avatar-picker__pip {
4498
4824
  * glyph stood 24px in and the keycap 28px from the edge; at 12px they stand
4499
4825
  * 20px and 16px in, where the approved palette draws them, and the query still
4500
4826
  * starts on the line the design's does.
4827
+ *
4828
+ * The band is the BAR around the field, so a step's chip shares it: the field
4829
+ * itself draws no box and fills what the chip leaves.
4501
4830
  */
4502
- .crewlet-input.crewlet-palette__field {
4831
+ .crewlet-palette__bar {
4832
+ display: flex;
4833
+ align-items: center;
4834
+ gap: var(--spacing-2);
4503
4835
  flex-shrink: 0;
4504
4836
  min-height: var(--size-row-lg);
4505
4837
  padding-inline: var(--spacing-3);
4506
- border: none;
4507
4838
  border-bottom: 1px solid var(--color-border-default);
4839
+ }
4840
+
4841
+ .crewlet-input.crewlet-palette__field {
4842
+ flex: 1;
4843
+ min-width: 0;
4844
+ align-self: stretch;
4845
+ padding-inline: 0;
4846
+ border: none;
4508
4847
  border-radius: 0;
4509
4848
  background: transparent;
4510
4849
  }
4511
4850
 
4851
+ /*
4852
+ * THE STEP'S CHIP: where the reader is, and the way back. It wears the
4853
+ * accent's soft tint and ink, the kit's mark for "this is on", because a step
4854
+ * is a narrowing the reader chose, as a filter that is on is; it is a control,
4855
+ * so it takes the pointer and draws its own ring.
4856
+ */
4857
+ .crewlet-palette__step {
4858
+ display: inline-flex;
4859
+ align-items: center;
4860
+ gap: var(--spacing-1);
4861
+ flex: none;
4862
+ min-height: var(--size-target-min);
4863
+ padding: 0 var(--spacing-2) 0 var(--spacing-1);
4864
+ border: none;
4865
+ border-radius: var(--radius-sm);
4866
+ background: var(--color-brand-accent-soft);
4867
+ color: var(--color-brand-accent-ink);
4868
+ font: inherit;
4869
+ font-size: var(--font-size-xs);
4870
+ font-weight: var(--font-weight-medium);
4871
+ white-space: nowrap;
4872
+ cursor: pointer;
4873
+ }
4874
+
4875
+ /* Under the pointer it draws the line the soft tint is paired with, rather
4876
+ than a stronger fill its ink was never measured on. */
4877
+ .crewlet-palette__step:hover {
4878
+ box-shadow: inset 0 0 0 1px var(--color-brand-accent-soft-strong);
4879
+ }
4880
+
4881
+ .crewlet-palette__step:focus-visible {
4882
+ outline: 2px solid var(--color-focus);
4883
+ outline-offset: 1px;
4884
+ }
4885
+
4886
+ /* In a step the query starts a gap after the chip, not a text inset after it. */
4887
+ .crewlet-palette__bar.is-step .crewlet-input__control {
4888
+ padding-left: 0;
4889
+ }
4890
+
4512
4891
  .crewlet-input.crewlet-palette__field .crewlet-input__control {
4513
4892
  font-size: var(--font-size-md);
4514
4893
  }
@@ -7478,11 +7857,12 @@ body.crewlet-data-table-resizing {
7478
7857
  }
7479
7858
 
7480
7859
 
7481
- /* DateTimePicker-4AZBTODT.css */
7860
+ /* DateTimePicker-NJ6XH2TE.css */
7482
7861
  /*
7483
7862
  * DateTimePicker: a Select-shaped trigger over a calendar dialog.
7484
7863
  *
7485
- * The trigger borrows the Select's geometry so a date box and a picker line
7864
+ * The trigger borrows the Select's geometry and its button boundary
7865
+ * (--color-border-strong; see Select.css) so a date box and a picker line
7486
7866
  * up in the same toolbar; the panel holds the shared CalendarGrid, so the
7487
7867
  * month looks and behaves the same here as in every other picker.
7488
7868
  */
@@ -7498,7 +7878,7 @@ body.crewlet-data-table-resizing {
7498
7878
  height. */
7499
7879
  padding: 0 var(--spacing-2) 0 var(--spacing-3);
7500
7880
  background: var(--color-surface-subtle);
7501
- border: 1px solid var(--color-border-control);
7881
+ border: 1px solid var(--color-border-strong);
7502
7882
  border-radius: var(--radius-md);
7503
7883
  color: var(--color-text-primary);
7504
7884
  font-family: inherit;
@@ -7515,7 +7895,7 @@ body.crewlet-data-table-resizing {
7515
7895
  }
7516
7896
 
7517
7897
  .crewlet-datetime:hover:not(:disabled) {
7518
- border-color: var(--color-border-hover);
7898
+ border-color: var(--color-border-strong-hover);
7519
7899
  }
7520
7900
 
7521
7901
  /*
@@ -8023,9 +8403,300 @@ svg.crewlet-datetime__chevron {
8023
8403
  }
8024
8404
 
8025
8405
 
8026
- /* EmptyState-C6HRBGT7.css */
8406
+ /* Document-PQGXJHB7.css */
8027
8407
  /*
8028
- * The empty state.
8408
+ * Rendered markdown, set as a document (Document.tsx).
8409
+ *
8410
+ * Every size here is a step on the type ramp and every gap a spacing step,
8411
+ * because a reading column set in sizes of its own (32, 20, 18, 15 and 14.5px
8412
+ * were measured on one) is a column that drifts from every other surface.
8413
+ */
8414
+
8415
+ .crewlet-document {
8416
+ /* The two rhythms a size sets: between blocks, and above a section. */
8417
+ --crewlet-document-gap: var(--spacing-4);
8418
+ --crewlet-document-section-gap: var(--spacing-6);
8419
+ margin: 0;
8420
+ min-width: 0;
8421
+ font-family: var(--font-family-sans);
8422
+ font-size: var(--font-size-sm);
8423
+ line-height: var(--font-line-height-relaxed);
8424
+ color: var(--color-text-secondary);
8425
+ /* The renderer decides what a break is, so the whitespace rule is normal. */
8426
+ white-space: normal;
8427
+ overflow-wrap: break-word;
8428
+ }
8429
+
8430
+ .crewlet-document--sm {
8431
+ --crewlet-document-gap: var(--spacing-3);
8432
+ --crewlet-document-section-gap: var(--spacing-5);
8433
+ font-size: var(--font-size-compact);
8434
+ line-height: var(--font-line-height-normal);
8435
+ }
8436
+
8437
+ .crewlet-document--measure {
8438
+ max-width: var(--size-measure);
8439
+ }
8440
+
8441
+ /*
8442
+ * EVERY BLOCK'S OWN MARGIN IS ZEROED FIRST, and the rhythm is one rule over
8443
+ * siblings. The other way round, a margin reset per element after the sibling
8444
+ * rule, is how a rhythm dies: the shorthand resets the top margin too, at the
8445
+ * same specificity and later in the file, and every block runs into the next.
8446
+ */
8447
+ .crewlet-document :where(p, h1, h2, h3, h4, h5, h6, ul, ol, pre, blockquote, table, figure) {
8448
+ margin: 0;
8449
+ }
8450
+
8451
+ .crewlet-document > * + * {
8452
+ margin-block-start: var(--crewlet-document-gap);
8453
+ }
8454
+
8455
+ .crewlet-document :where(h1, h2, h3, h4, h5, h6) {
8456
+ font-weight: var(--font-weight-semibold);
8457
+ line-height: var(--font-line-height-tight);
8458
+ letter-spacing: var(--font-letter-spacing-snug);
8459
+ color: var(--color-text-primary);
8460
+ /* An outline that scrolls a heading into view leaves it a little air. */
8461
+ scroll-margin-block-start: var(--spacing-6);
8462
+ }
8463
+
8464
+ /* A heading opens a section, so it gets more air above it than a paragraph. */
8465
+ .crewlet-document > * + :where(h1, h2, h3, h4, h5, h6) {
8466
+ margin-block-start: var(--crewlet-document-section-gap);
8467
+ }
8468
+
8469
+ .crewlet-document h1 {
8470
+ font-size: var(--font-size-2xl);
8471
+ }
8472
+
8473
+ .crewlet-document h2 {
8474
+ font-size: var(--font-size-xl);
8475
+ }
8476
+
8477
+ .crewlet-document h3 {
8478
+ font-size: var(--font-size-lg);
8479
+ }
8480
+
8481
+ .crewlet-document :where(h4, h5, h6) {
8482
+ font-size: var(--font-size-md);
8483
+ }
8484
+
8485
+ .crewlet-document--sm h1 {
8486
+ font-size: var(--font-size-lg);
8487
+ }
8488
+
8489
+ .crewlet-document--sm h2 {
8490
+ font-size: var(--font-size-md);
8491
+ }
8492
+
8493
+ .crewlet-document--sm h3 {
8494
+ font-size: var(--font-size-sm);
8495
+ }
8496
+
8497
+ .crewlet-document--sm :where(h4, h5, h6) {
8498
+ font-size: var(--font-size-compact);
8499
+ color: var(--color-text-secondary);
8500
+ }
8501
+
8502
+ /*
8503
+ * A HEADING AN OUTLINE MOVED TO takes focus, so a keyboard carries on from it.
8504
+ * A press draws no ring (`:focus-visible` does not match one); a keyboard's is
8505
+ * drawn off the text, because the heading is not a control.
8506
+ */
8507
+ .crewlet-document :where(h1, h2, h3, h4, h5, h6):focus-visible {
8508
+ outline: 2px solid var(--color-focus);
8509
+ outline-offset: var(--spacing-1);
8510
+ border-radius: var(--radius-xs);
8511
+ }
8512
+
8513
+ .crewlet-document :where(strong, b) {
8514
+ font-weight: var(--font-weight-semibold);
8515
+ color: var(--color-text-primary);
8516
+ }
8517
+
8518
+ .crewlet-document :where(ul, ol) {
8519
+ padding-inline-start: var(--spacing-5);
8520
+ }
8521
+
8522
+ .crewlet-document li + li,
8523
+ .crewlet-document li > :where(ul, ol) {
8524
+ margin-block-start: var(--spacing-1);
8525
+ }
8526
+
8527
+ .crewlet-document li::marker {
8528
+ color: var(--color-text-tertiary);
8529
+ }
8530
+
8531
+ /*
8532
+ * A TASK LIST keeps its box on the line rather than in the marker's place: the
8533
+ * marker is what says "list", and the box is what says "done". The item's
8534
+ * content is ONE column beside the box, never a second cell of the row, so a
8535
+ * sublist hangs under the line it belongs to.
8536
+ */
8537
+ .crewlet-document ul:has(> li > input[type='checkbox']) {
8538
+ list-style: none;
8539
+ padding-inline-start: 0;
8540
+ }
8541
+
8542
+ .crewlet-document li:has(> input[type='checkbox']) {
8543
+ display: flex;
8544
+ align-items: flex-start;
8545
+ gap: var(--spacing-2);
8546
+ }
8547
+
8548
+ .crewlet-document li:has(> input[type='checkbox']) > :not(input) {
8549
+ flex: 1;
8550
+ min-width: 0;
8551
+ }
8552
+
8553
+ .crewlet-document li > input[type='checkbox'] {
8554
+ flex: none;
8555
+ margin: 0;
8556
+ /* On the first line's centre rather than on the top of its box. */
8557
+ margin-block-start: 0.35em;
8558
+ accent-color: var(--color-brand-accent);
8559
+ }
8560
+
8561
+ /*
8562
+ * A FENCED BLOCK WRAPS RATHER THAN SCROLLING. One long line of JSON in a body
8563
+ * otherwise pushes the whole page sideways, and a block that scrolled instead
8564
+ * would owe a tab stop, since a scroller no keyboard reaches is content no
8565
+ * keyboard reads. `anywhere` because these lines have no spaces to break at.
8566
+ */
8567
+ .crewlet-document pre {
8568
+ padding: var(--spacing-2) var(--spacing-3);
8569
+ border-radius: var(--radius-sm);
8570
+ background: var(--color-surface-inset);
8571
+ font-family: var(--font-family-mono);
8572
+ font-size: var(--font-size-xs);
8573
+ line-height: var(--font-line-height-normal);
8574
+ color: var(--color-text-primary);
8575
+ white-space: pre-wrap;
8576
+ overflow-wrap: anywhere;
8577
+ }
8578
+
8579
+ .crewlet-document pre code {
8580
+ padding: 0;
8581
+ background: none;
8582
+ font: inherit;
8583
+ }
8584
+
8585
+ .crewlet-document :not(pre) > code {
8586
+ padding: 0 var(--spacing-1);
8587
+ border-radius: var(--radius-xs);
8588
+ background: var(--color-surface-inset);
8589
+ font-family: var(--font-family-mono);
8590
+ font-size: var(--font-size-xs);
8591
+ color: var(--color-text-primary);
8592
+ overflow-wrap: anywhere;
8593
+ }
8594
+
8595
+ .crewlet-document blockquote {
8596
+ padding-inline-start: var(--spacing-3);
8597
+ border-inline-start: 2px solid var(--color-border-strong);
8598
+ color: var(--color-text-secondary);
8599
+ }
8600
+
8601
+ .crewlet-document hr {
8602
+ margin-block: var(--crewlet-document-section-gap);
8603
+ border: 0;
8604
+ border-block-start: 1px solid var(--color-border-default);
8605
+ }
8606
+
8607
+ /*
8608
+ * A link in running prose keeps a permanent underline, through hover too:
8609
+ * colour alone is not what says "link" (WCAG 1.4.1). The pointer is answered
8610
+ * by the ink moving to the primary step.
8611
+ */
8612
+ .crewlet-document a,
8613
+ .crewlet-document a:hover {
8614
+ text-decoration: underline;
8615
+ text-underline-offset: 2px;
8616
+ }
8617
+
8618
+ .crewlet-document a {
8619
+ color: var(--color-brand-accent-ink);
8620
+ }
8621
+
8622
+ .crewlet-document a:hover {
8623
+ color: var(--color-text-primary);
8624
+ }
8625
+
8626
+ .crewlet-document a:focus-visible {
8627
+ outline: 2px solid var(--color-focus);
8628
+ outline-offset: 2px;
8629
+ border-radius: var(--radius-xs);
8630
+ }
8631
+
8632
+ .crewlet-document img {
8633
+ max-width: 100%;
8634
+ height: auto;
8635
+ border-radius: var(--radius-sm);
8636
+ }
8637
+
8638
+ /*
8639
+ * A TABLE WRITTEN FOR A DOCUMENT can be wider than the column it lands in, so
8640
+ * the element a renderer wraps it in scrolls rather than the page. The table
8641
+ * itself keeps its display, because a table set `display: block` loses its
8642
+ * table semantics to more than one screen reader.
8643
+ */
8644
+ .crewlet-document :where(div):has(> table) {
8645
+ overflow-x: auto;
8646
+ }
8647
+
8648
+ /* The scroller is a tab stop (see Document.tsx), so it draws the ring inside
8649
+ its own box, where the table's edge would otherwise clip an outset one. */
8650
+ .crewlet-document :where(div):has(> table):focus-visible {
8651
+ outline: 2px solid var(--color-focus);
8652
+ outline-offset: var(--size-focus-ring-inset-offset);
8653
+ border-radius: var(--radius-xs);
8654
+ }
8655
+
8656
+ .crewlet-document table {
8657
+ width: 100%;
8658
+ border-collapse: collapse;
8659
+ font-size: var(--font-size-compact);
8660
+ line-height: var(--font-line-height-snug);
8661
+ }
8662
+
8663
+ .crewlet-document--sm table {
8664
+ font-size: var(--font-size-xs);
8665
+ }
8666
+
8667
+ .crewlet-document :where(th, td) {
8668
+ padding: var(--spacing-1) var(--spacing-2);
8669
+ border-block-end: 1px solid var(--color-border-default);
8670
+ text-align: start;
8671
+ vertical-align: top;
8672
+ }
8673
+
8674
+ .crewlet-document th {
8675
+ font-weight: var(--font-weight-semibold);
8676
+ color: var(--color-text-primary);
8677
+ white-space: nowrap;
8678
+ }
8679
+
8680
+ /*
8681
+ * The title above a body. The largest step a reading screen spends, at the
8682
+ * tight tracking every title on the ramp takes, and it wraps anywhere because
8683
+ * a title is an address somebody typed and may hold no space at all.
8684
+ */
8685
+ .crewlet-document-title {
8686
+ margin: 0;
8687
+ font-family: var(--font-family-sans);
8688
+ font-size: var(--font-size-3xl);
8689
+ font-weight: var(--font-weight-semibold);
8690
+ line-height: var(--font-line-height-tight);
8691
+ letter-spacing: var(--font-letter-spacing-tight);
8692
+ color: var(--color-text-primary);
8693
+ overflow-wrap: anywhere;
8694
+ }
8695
+
8696
+
8697
+ /* EmptyState-C6HRBGT7.css */
8698
+ /*
8699
+ * The empty state.
8029
8700
  *
8030
8701
  * ITS MARK IS DECORATION and takes the decoration ink, which is the one place
8031
8702
  * that step is allowed: a 32px glyph a reader does not have to make out. Every
@@ -8465,6 +9136,38 @@ svg.crewlet-datetime__chevron {
8465
9136
  }
8466
9137
 
8467
9138
 
9139
+ /* Highlight-DXLV2R6L.css */
9140
+ /*
9141
+ * Words a search matched (Highlight.tsx).
9142
+ */
9143
+
9144
+ /*
9145
+ * A GROUND, NEVER AN INK. The marked word keeps the ink of the text around it,
9146
+ * so it reads at the contrast that text was measured at, and the accent's soft
9147
+ * step behind it says "this is what you searched for" without making the word
9148
+ * louder than its sentence. The accent is the one colour that means "where the
9149
+ * reader is", and a match is exactly that: the reader's own question, found.
9150
+ */
9151
+ .crewlet-highlight__match {
9152
+ border-radius: var(--radius-xs);
9153
+ background: var(--color-brand-accent-soft-strong);
9154
+ color: inherit;
9155
+ }
9156
+
9157
+ /*
9158
+ * Forced colours replaces every author ground with the canvas, which would
9159
+ * leave a match drawn exactly like the words beside it. The system's own pair
9160
+ * for a mark is what that mode reserves for this job.
9161
+ */
9162
+ @media (forced-colors: active) {
9163
+ .crewlet-highlight__match {
9164
+ forced-color-adjust: none;
9165
+ background: Mark;
9166
+ color: MarkText;
9167
+ }
9168
+ }
9169
+
9170
+
8468
9171
  /* HuePicker-5QIUR6L7.css */
8469
9172
  /*
8470
9173
  * A hue's swatch: the hue itself, as a dot beside its name. The name carries
@@ -8662,14 +9365,17 @@ svg.crewlet-datetime__chevron {
8662
9365
  }
8663
9366
 
8664
9367
 
8665
- /* ImageUpload-L2GE4JUM.css */
9368
+ /* ImageUpload-NVGMN7DP.css */
8666
9369
  /*
8667
9370
  * ImageUpload, the click-to-upload affordance built on Avatar.
8668
9371
  *
8669
- * WHITE ON THE SCRIM, from tokens, in both palettes. The overlay used to spell
9372
+ * WHITE ON THE SCRIM, from tokens, in every theme. The overlay used to spell
8670
9373
  * its own rgba(0, 0, 0, 0.5) and three shades of white; the scrim and the
8671
- * on-accent step are the two values the palette already measures for exactly
8672
- * this, which is a label drawn on something dark whatever is behind it.
9374
+ * on-scrim step are the two values the palette measures for exactly this,
9375
+ * which is a label drawn on something dark whatever is behind it. The
9376
+ * on-accent step is not: a theme whose accent is light labels it dark. The
9377
+ * remove button is the danger fill, and takes the on-danger step for the
9378
+ * same reason.
8673
9379
  *
8674
9380
  * NO LITERAL FALLBACKS INSIDE var(). A fallback is what renders whenever the
8675
9381
  * token name is misspelt, so it hides the very failure it looks like
@@ -8756,7 +9462,7 @@ svg.crewlet-datetime__chevron {
8756
9462
  justify-content: center;
8757
9463
  gap: 2px;
8758
9464
  background: var(--color-surface-scrim);
8759
- color: var(--color-text-on-accent);
9465
+ color: var(--color-text-on-scrim);
8760
9466
  opacity: 0;
8761
9467
  transition: opacity var(--motion-duration-base) var(--motion-easing-default);
8762
9468
  pointer-events: none;
@@ -8801,7 +9507,7 @@ svg.crewlet-datetime__chevron {
8801
9507
  height: calc(var(--crewlet-image-upload-size) * 0.3);
8802
9508
  border-radius: var(--radius-circle);
8803
9509
  border: 2px solid var(--color-surface-scrim);
8804
- border-top-color: var(--color-text-on-accent);
9510
+ border-top-color: var(--color-text-on-scrim);
8805
9511
  animation: crewlet-image-upload-spin calc(var(--motion-duration-slow) * 2.5) linear infinite;
8806
9512
  }
8807
9513
 
@@ -8831,7 +9537,7 @@ svg.crewlet-datetime__chevron {
8831
9537
  border-radius: var(--radius-circle);
8832
9538
  background: var(--color-feedback-danger);
8833
9539
  border: 2px solid var(--color-surface-background);
8834
- color: var(--color-text-on-accent);
9540
+ color: var(--color-text-on-danger);
8835
9541
  cursor: pointer;
8836
9542
  opacity: 0;
8837
9543
  transition: opacity var(--motion-duration-fast) var(--motion-easing-default);
@@ -8876,48 +9582,303 @@ svg.crewlet-datetime__chevron {
8876
9582
  }
8877
9583
 
8878
9584
 
8879
- /* InlineCode-6WSR5COL.css */
9585
+ /* InboxList-YMFWKGGS.css */
8880
9586
  /*
8881
- * One identifier inside a sentence: a mono chip on the inset surface.
9587
+ * The inbox's column: groups of rows, each row a control with the task it is
9588
+ * about under it, and the quiet toggles at the end.
8882
9589
  *
8883
- * The size is relative (0.92em) rather than a step off the scale, because the
8884
- * chip has to sit inside whatever register its sentence is set in. A fixed
8885
- * size makes it either a shout inside a caption or a whisper inside a lead.
9590
+ * EVERY TRACK IS minmax(0, 1fr). An `auto` track grows to its widest content,
9591
+ * and a row holding a long unbroken word pushed the whole column past its
9592
+ * edge, cutting every row off at the right.
8886
9593
  */
8887
9594
 
8888
- .crewlet-inline-code {
8889
- /*
8890
- * RELATIVE, so it is deliberately not a step off the type scale: the chip
8891
- * sits inside whatever register its sentence is set in, and an absolute size
8892
- * makes it a shout inside a caption or a whisper inside a lead. The mono
8893
- * face also runs larger than the sans at the same nominal size, which is
8894
- * what the reduction corrects.
8895
- */
8896
- --crewlet-inline-code-size: 0.92em;
8897
- font-family: var(--font-family-mono);
8898
- /* An identifier is read character by character; a ligature joins two of them
8899
- into a drawing of something nobody typed. */
8900
- font-variant-ligatures: none;
8901
- font-size: var(--crewlet-inline-code-size);
8902
- background: var(--color-surface-inset);
8903
- border-radius: var(--radius-xs);
8904
- padding: 1px var(--spacing-1);
8905
- color: var(--color-text-secondary);
8906
- /* A URL IS ONE UNBREAKABLE WORD to a line breaker. Without this the chip is
8907
- pushed whole onto its own line and the sentence around it is torn up. */
8908
- overflow-wrap: anywhere;
9595
+ .crewlet-inbox-list {
9596
+ display: grid;
9597
+ grid-template-columns: minmax(0, 1fr);
9598
+ align-content: start;
9599
+ gap: 2px;
9600
+ min-width: 0;
9601
+ font-size: var(--font-size-compact);
9602
+ line-height: var(--font-line-height-body);
8909
9603
  }
8910
9604
 
8911
- /*
8912
- * A `${NAME}` pointer. It is one token a reader copies, so it keeps its braces
8913
- * together. THE SAME INK AS ANY OTHER CHIP: a pointer is the name of a sealed
8914
- * entry, and drawn a step quieter than the identifiers around it, it read as
8915
- * decoration rather than as the thing an operator has to type back.
8916
- */
8917
- .crewlet-inline-code--reference {
8918
- overflow-wrap: normal;
8919
- white-space: nowrap;
8920
- }
9605
+ .crewlet-inbox-list__group {
9606
+ display: grid;
9607
+ grid-template-columns: minmax(0, 1fr);
9608
+ gap: 2px;
9609
+ min-width: 0;
9610
+ }
9611
+
9612
+ /* The heading's own line box is the label's, so the label sits where it is drawn. */
9613
+ .crewlet-inbox-list__label {
9614
+ margin: 0;
9615
+ padding: var(--spacing-3) var(--spacing-2) var(--spacing-1);
9616
+ font: inherit;
9617
+ font-size: var(--font-size-2xs);
9618
+ line-height: var(--font-line-height-snug);
9619
+ }
9620
+
9621
+ .crewlet-inbox-list__rows {
9622
+ display: grid;
9623
+ grid-template-columns: minmax(0, 1fr);
9624
+ gap: 2px;
9625
+ margin: 0;
9626
+ padding: 0;
9627
+ list-style: none;
9628
+ }
9629
+
9630
+ /* ---- The row ------------------------------------------------------------ */
9631
+
9632
+ /*
9633
+ * The ITEM takes the hover and the selected fill, so the control and the task
9634
+ * under it read as one row. The selected fill is the neutral pressed step, and
9635
+ * a selected row takes no hover on top of it: both are a background on the
9636
+ * same element, and a composite of the two is a colour nothing has measured.
9637
+ */
9638
+ .crewlet-inbox-row {
9639
+ min-width: 0;
9640
+ border-radius: var(--radius-md);
9641
+ transition: background var(--motion-duration-fast) var(--motion-easing-default);
9642
+ }
9643
+
9644
+ .crewlet-inbox-row:hover {
9645
+ background: var(--color-surface-hover);
9646
+ }
9647
+
9648
+ .crewlet-inbox-row--selected,
9649
+ .crewlet-inbox-row--selected:hover {
9650
+ background: var(--color-surface-pressed);
9651
+ }
9652
+
9653
+ /*
9654
+ * FORCED COLORS repaints every author background to Canvas, which takes the
9655
+ * open row's fill with it, so the row the pane is showing would look like
9656
+ * every other. An outline is the one mark the mode keeps, drawn inside the row
9657
+ * so the scroller does not clip it, in the system's colour for exactly this.
9658
+ */
9659
+ @media (forced-colors: active) {
9660
+ .crewlet-inbox-row--selected {
9661
+ outline: 2px solid Highlight;
9662
+ outline-offset: -2px;
9663
+ }
9664
+ }
9665
+
9666
+ .crewlet-inbox-row__control {
9667
+ display: flex;
9668
+ align-items: flex-start;
9669
+ gap: calc(var(--spacing-2) + var(--spacing-1) / 2);
9670
+ width: 100%;
9671
+ min-width: 0;
9672
+ padding: calc(var(--spacing-2) + var(--spacing-1) / 2) var(--spacing-2) var(--spacing-1);
9673
+ border: 0;
9674
+ border-radius: var(--radius-md);
9675
+ background: none;
9676
+ color: inherit;
9677
+ font: inherit;
9678
+ text-align: left;
9679
+ text-decoration: none;
9680
+ cursor: pointer;
9681
+ }
9682
+
9683
+ /* With no task under it, the control closes the row at the same padding it opened with. */
9684
+ .crewlet-inbox-row__control:only-child {
9685
+ padding-bottom: calc(var(--spacing-2) + var(--spacing-1) / 2);
9686
+ }
9687
+
9688
+ /*
9689
+ * The ring is drawn INSIDE: the list sits in a clipping scroller, where an
9690
+ * outset ring is cut off on the first and last rows and painted over by the
9691
+ * row below.
9692
+ */
9693
+ .crewlet-inbox-row__control:focus-visible {
9694
+ outline: 2px solid var(--color-focus);
9695
+ outline-offset: var(--size-focus-ring-inset-offset);
9696
+ }
9697
+
9698
+ .crewlet-inbox-row__leading {
9699
+ display: inline-flex;
9700
+ flex: none;
9701
+ justify-content: center;
9702
+ width: var(--size-target-min);
9703
+ margin-top: 1px;
9704
+ }
9705
+
9706
+ .crewlet-inbox-row__main {
9707
+ display: grid;
9708
+ flex: 1;
9709
+ gap: 2px;
9710
+ min-width: 0;
9711
+ }
9712
+
9713
+ .crewlet-inbox-row__head {
9714
+ display: flex;
9715
+ align-items: baseline;
9716
+ gap: var(--spacing-1);
9717
+ min-width: 0;
9718
+ }
9719
+
9720
+ .crewlet-inbox-row__title {
9721
+ min-width: 0;
9722
+ overflow: hidden;
9723
+ text-overflow: ellipsis;
9724
+ white-space: nowrap;
9725
+ font-weight: var(--font-weight-medium);
9726
+ color: var(--color-text-primary);
9727
+ }
9728
+
9729
+ .crewlet-inbox-row__qualifier {
9730
+ flex: none;
9731
+ font-size: var(--font-size-xs);
9732
+ color: var(--color-text-tertiary);
9733
+ }
9734
+
9735
+ .crewlet-inbox-row__qualifier--danger {
9736
+ color: var(--color-feedback-danger-ink);
9737
+ }
9738
+
9739
+ .crewlet-inbox-row__meta {
9740
+ flex: none;
9741
+ margin-inline-start: auto;
9742
+ font-size: var(--font-size-xs);
9743
+ font-variant-numeric: tabular-nums;
9744
+ white-space: nowrap;
9745
+ color: var(--color-text-tertiary);
9746
+ }
9747
+
9748
+ .crewlet-inbox-row__text {
9749
+ display: -webkit-box;
9750
+ -webkit-box-orient: vertical;
9751
+ -webkit-line-clamp: 3;
9752
+ line-clamp: 3;
9753
+ overflow: hidden;
9754
+ overflow-wrap: anywhere;
9755
+ line-height: var(--font-line-height-snug);
9756
+ color: var(--color-text-secondary);
9757
+ }
9758
+
9759
+ .crewlet-inbox-row__excerpt {
9760
+ color: var(--color-text-tertiary);
9761
+ }
9762
+
9763
+ /* Unread: a heavier name, and the words in the primary ink. */
9764
+ .crewlet-inbox-row__control--unread .crewlet-inbox-row__title {
9765
+ font-weight: var(--font-weight-semibold);
9766
+ }
9767
+
9768
+ .crewlet-inbox-row__control--unread .crewlet-inbox-row__text,
9769
+ .crewlet-inbox-row__control--actionable .crewlet-inbox-row__text {
9770
+ color: var(--color-text-primary);
9771
+ }
9772
+
9773
+ /*
9774
+ * Settled. The strike is drawn in the strong hairline rather than the text's
9775
+ * own ink, so the words under it stay legible; the state is also read out,
9776
+ * because a line through a word says nothing to somebody listening.
9777
+ */
9778
+ .crewlet-inbox-row__control--done .crewlet-inbox-row__text {
9779
+ text-decoration: line-through;
9780
+ text-decoration-color: var(--color-border-strong);
9781
+ color: var(--color-text-tertiary);
9782
+ }
9783
+
9784
+ /*
9785
+ * The task, under the words and lined up with them: the control's start pad,
9786
+ * the leading slot and the gap after it.
9787
+ */
9788
+ .crewlet-inbox-row__aside {
9789
+ min-width: 0;
9790
+ padding:
9791
+ 0 var(--spacing-2) calc(var(--spacing-2) + var(--spacing-1) / 2)
9792
+ calc(var(--spacing-2) + var(--size-target-min) + var(--spacing-2) + var(--spacing-1) / 2);
9793
+ overflow-wrap: anywhere;
9794
+ font-size: var(--font-size-xs);
9795
+ line-height: var(--font-line-height-snug);
9796
+ }
9797
+
9798
+ /* ---- The end of the list ---------------------------------------------- */
9799
+
9800
+ .crewlet-inbox-list__more {
9801
+ display: flex;
9802
+ flex-wrap: wrap;
9803
+ gap: calc(var(--spacing-4) + var(--spacing-1) / 2);
9804
+ padding: calc(var(--spacing-3) + var(--spacing-1) / 2) var(--spacing-2) 0;
9805
+ }
9806
+
9807
+ .crewlet-inbox-list__toggle {
9808
+ padding: 0;
9809
+ border: 0;
9810
+ border-radius: var(--radius-xs);
9811
+ background: none;
9812
+ font: inherit;
9813
+ font-size: var(--font-size-xs);
9814
+ color: var(--color-text-tertiary);
9815
+ cursor: pointer;
9816
+ transition: color var(--motion-duration-fast) var(--motion-easing-default);
9817
+ }
9818
+
9819
+ .crewlet-inbox-list__toggle:hover,
9820
+ .crewlet-inbox-list__toggle[aria-expanded='true'] {
9821
+ color: var(--color-text-primary);
9822
+ }
9823
+
9824
+ .crewlet-inbox-list__toggle:focus-visible {
9825
+ outline: 2px solid var(--color-focus);
9826
+ outline-offset: 2px;
9827
+ }
9828
+
9829
+ @media (prefers-reduced-motion: reduce) {
9830
+ .crewlet-inbox-row {
9831
+ transition: none;
9832
+ }
9833
+
9834
+ .crewlet-inbox-list__toggle {
9835
+ transition: none;
9836
+ }
9837
+ }
9838
+
9839
+
9840
+ /* InlineCode-6WSR5COL.css */
9841
+ /*
9842
+ * One identifier inside a sentence: a mono chip on the inset surface.
9843
+ *
9844
+ * The size is relative (0.92em) rather than a step off the scale, because the
9845
+ * chip has to sit inside whatever register its sentence is set in. A fixed
9846
+ * size makes it either a shout inside a caption or a whisper inside a lead.
9847
+ */
9848
+
9849
+ .crewlet-inline-code {
9850
+ /*
9851
+ * RELATIVE, so it is deliberately not a step off the type scale: the chip
9852
+ * sits inside whatever register its sentence is set in, and an absolute size
9853
+ * makes it a shout inside a caption or a whisper inside a lead. The mono
9854
+ * face also runs larger than the sans at the same nominal size, which is
9855
+ * what the reduction corrects.
9856
+ */
9857
+ --crewlet-inline-code-size: 0.92em;
9858
+ font-family: var(--font-family-mono);
9859
+ /* An identifier is read character by character; a ligature joins two of them
9860
+ into a drawing of something nobody typed. */
9861
+ font-variant-ligatures: none;
9862
+ font-size: var(--crewlet-inline-code-size);
9863
+ background: var(--color-surface-inset);
9864
+ border-radius: var(--radius-xs);
9865
+ padding: 1px var(--spacing-1);
9866
+ color: var(--color-text-secondary);
9867
+ /* A URL IS ONE UNBREAKABLE WORD to a line breaker. Without this the chip is
9868
+ pushed whole onto its own line and the sentence around it is torn up. */
9869
+ overflow-wrap: anywhere;
9870
+ }
9871
+
9872
+ /*
9873
+ * A `${NAME}` pointer. It is one token a reader copies, so it keeps its braces
9874
+ * together. THE SAME INK AS ANY OTHER CHIP: a pointer is the name of a sealed
9875
+ * entry, and drawn a step quieter than the identifiers around it, it read as
9876
+ * decoration rather than as the thing an operator has to type back.
9877
+ */
9878
+ .crewlet-inline-code--reference {
9879
+ overflow-wrap: normal;
9880
+ white-space: nowrap;
9881
+ }
8921
9882
 
8922
9883
  /*
8923
9884
  * Inside a Callout or a field error the chip carries that message's ink, or a
@@ -9685,6 +10646,39 @@ svg.crewlet-datetime__chevron {
9685
10646
  }
9686
10647
 
9687
10648
 
10649
+ /* KeyChip-4XJU4BBE.css */
10650
+ /*
10651
+ * A project's key as a chip: the raised rung inside the plain hairline, in the
10652
+ * mono face at the micro step and the secondary ink.
10653
+ *
10654
+ * The rail's suite measures this ink on this fill against every ground a rail
10655
+ * row can have (SidebarNav.test.tsx), because the rail is where the chip sits
10656
+ * on the most grounds: the frame, a pointed row and the current row.
10657
+ */
10658
+ .crewlet-key-chip {
10659
+ display: inline-flex;
10660
+ align-items: center;
10661
+ flex: none;
10662
+ padding: 0 calc(var(--spacing-1) + 1px);
10663
+ border: 1px solid var(--color-border-default);
10664
+ border-radius: var(--radius-xs);
10665
+ background: var(--color-surface-elevated);
10666
+ color: var(--color-text-secondary);
10667
+ font-family: var(--font-family-mono);
10668
+ font-size: var(--font-size-2xs);
10669
+ font-weight: var(--font-weight-medium);
10670
+ letter-spacing: var(--font-letter-spacing-normal);
10671
+ line-height: var(--font-line-height-body);
10672
+ white-space: nowrap;
10673
+ }
10674
+
10675
+ /* The letters a search matched: the weight carries it, in the primary ink. */
10676
+ .crewlet-key-chip__match {
10677
+ font-weight: var(--font-weight-bold);
10678
+ color: var(--color-text-primary);
10679
+ }
10680
+
10681
+
9688
10682
  /* Layer-NAFSGCFA.css */
9689
10683
  /*
9690
10684
  * The portal target a LayerHost provides.
@@ -9885,9 +10879,10 @@ svg.crewlet-datetime__chevron {
9885
10879
 
9886
10880
 
9887
10881
 
9888
- /* Link-6BEFNMN2.css */
10882
+ /* Link-WPMVLKLY.css */
9889
10883
  /*
9890
- * A link, in the two registers a console needs: a navigation and an identity.
10884
+ * A link, in the three registers a console needs: a navigation, an identity
10885
+ * and a quiet reference.
9891
10886
  *
9892
10887
  * The ink is the accent's INK step, not the accent fill. The fill is a mark
9893
10888
  * and clears 3:1; text has to clear 4.5:1, and at caption size it is exactly
@@ -9920,10 +10915,44 @@ svg.crewlet-datetime__chevron {
9920
10915
  color: var(--color-brand-accent-ink);
9921
10916
  }
9922
10917
 
10918
+ /*
10919
+ * A reference among other words. Its own ink sits between the accent ink and
10920
+ * the secondary text, so a column of rows that each name a task does not read
10921
+ * as a column of links, and the hover steps it up to the full accent ink with
10922
+ * no underline. The ink is a token rather than a mix of two, because a mix is
10923
+ * a colour nobody measured; this one clears 4.5:1 on every surface and on a
10924
+ * pressed row.
10925
+ */
10926
+ .crewlet-link--quiet {
10927
+ color: var(--color-text-link-quiet);
10928
+ }
10929
+
10930
+ .crewlet-link--quiet:hover {
10931
+ color: var(--color-brand-accent-ink);
10932
+ text-decoration: none;
10933
+ }
10934
+
10935
+ /*
10936
+ * FORCED COLORS paints every link in LinkText whatever its state, so the step
10937
+ * up to the accent ink cannot be seen there, and a hover with no underline is
10938
+ * no hover at all. The rule under the words is the one mark the mode leaves to
10939
+ * the author, so it is where the quiet variant's hover goes in that mode.
10940
+ */
10941
+ @media (forced-colors: active) {
10942
+ .crewlet-link--quiet:hover {
10943
+ text-decoration: underline;
10944
+ }
10945
+ }
10946
+
9923
10947
  .crewlet-link--body {
9924
10948
  font-size: var(--font-size-sm);
9925
10949
  }
9926
10950
 
10951
+ /* Set inside a sentence: the sentence's own size, whatever it is. */
10952
+ .crewlet-link--inherit {
10953
+ font-size: inherit;
10954
+ }
10955
+
9927
10956
  /*
9928
10957
  * A caption-sized link takes the caption's SIZE and keeps the link's ink. It
9929
10958
  * is medium weight and does not wrap, because the thing it names (an event id,
@@ -10458,7 +11487,156 @@ svg.crewlet-datetime__chevron {
10458
11487
  }
10459
11488
 
10460
11489
 
10461
- /* Menu-BT5PMFJI.css */
11490
+ /* MarkdownEditor-ZLSHTOIZ.css */
11491
+ /*
11492
+ * Writing markdown (MarkdownEditor.tsx): the bar, the source or its preview,
11493
+ * and the footer, in ONE box.
11494
+ *
11495
+ * THE BOX TAKES THE RING, and only for the field. It is the package's one ring
11496
+ * for a field: the box's own hairline drawn in the focus colour, laid on the
11497
+ * boundary (see Input.css). It is asked of the FIELD rather than of
11498
+ * :focus-within, so a reader walking the bar's controls sees each control's
11499
+ * own ring and not a second one round the whole editor.
11500
+ */
11501
+
11502
+ .crewlet-markdown-editor {
11503
+ /* The height the field and the preview stand at, so switching between them
11504
+ does not move what is under the editor. */
11505
+ --crewlet-markdown-editor-height: calc(
11506
+ var(--crewlet-markdown-editor-rows, 14) * var(--font-size-compact) * var(--font-line-height-relaxed) +
11507
+ var(--spacing-3) * 2
11508
+ );
11509
+ display: flex;
11510
+ flex-direction: column;
11511
+ min-width: 0;
11512
+ border: 1px solid var(--color-border-control);
11513
+ border-radius: var(--radius-md);
11514
+ background: var(--color-surface-subtle);
11515
+ transition: border-color var(--motion-duration-fast) var(--motion-easing-default);
11516
+ }
11517
+
11518
+ .crewlet-markdown-editor:hover {
11519
+ border-color: var(--color-border-hover);
11520
+ }
11521
+
11522
+ .crewlet-markdown-editor:has(.crewlet-markdown-editor__field:focus-visible) {
11523
+ outline: 1px solid var(--color-focus);
11524
+ outline-offset: -1px;
11525
+ }
11526
+
11527
+ /* A refused body keeps its colour while the writer is in it: the ring takes
11528
+ the danger step, so "here" and "refused" stay one edge. */
11529
+ .crewlet-markdown-editor--invalid {
11530
+ border-color: var(--color-feedback-danger);
11531
+ }
11532
+
11533
+ .crewlet-markdown-editor--invalid:has(.crewlet-markdown-editor__field:focus-visible) {
11534
+ outline-color: var(--color-feedback-danger);
11535
+ }
11536
+
11537
+ .crewlet-markdown-editor--disabled {
11538
+ opacity: 0.6;
11539
+ }
11540
+
11541
+ /* The bar sits on the box's top edge, a hairline under it. Two classes, so it
11542
+ outranks the toolbar's own padding whichever stylesheet loads first. */
11543
+ .crewlet-markdown-editor .crewlet-markdown-editor__bar {
11544
+ gap: var(--spacing-1);
11545
+ padding: var(--spacing-1) var(--spacing-2);
11546
+ border-block-end: 1px solid var(--color-border-default);
11547
+ }
11548
+
11549
+ .crewlet-markdown-editor__group {
11550
+ display: inline-flex;
11551
+ align-items: center;
11552
+ gap: calc(var(--spacing-1) / 2);
11553
+ }
11554
+
11555
+ /* A hairline between groups, so nine controls read as three ideas. */
11556
+ .crewlet-markdown-editor__group + .crewlet-markdown-editor__group {
11557
+ padding-inline-start: var(--spacing-1);
11558
+ border-inline-start: 1px solid var(--color-border-default);
11559
+ }
11560
+
11561
+ .crewlet-markdown-editor__spacer {
11562
+ flex: 1;
11563
+ }
11564
+
11565
+ .crewlet-markdown-editor__panel {
11566
+ display: flex;
11567
+ flex-direction: column;
11568
+ min-width: 0;
11569
+ }
11570
+
11571
+ /*
11572
+ * THE SOURCE IS SET IN THE MONOSPACE FACE: a writer counts the hashes of a
11573
+ * heading and lines up the bars of a table, and a proportional face makes
11574
+ * both a guess.
11575
+ */
11576
+ .crewlet-markdown-editor__field {
11577
+ display: block;
11578
+ box-sizing: border-box;
11579
+ width: 100%;
11580
+ min-height: var(--crewlet-markdown-editor-height);
11581
+ margin: 0;
11582
+ padding: var(--spacing-3) var(--spacing-4);
11583
+ border: 0;
11584
+ border-radius: 0;
11585
+ background: transparent;
11586
+ font-family: var(--font-family-mono);
11587
+ font-size: var(--font-size-compact);
11588
+ line-height: var(--font-line-height-relaxed);
11589
+ color: var(--color-text-primary);
11590
+ resize: vertical;
11591
+ }
11592
+
11593
+ .crewlet-markdown-editor__field::placeholder {
11594
+ color: var(--color-text-tertiary);
11595
+ }
11596
+
11597
+ /* The ring is the box's. A transparent outline stays, because forced colours
11598
+ paints an outline where this would otherwise draw none. */
11599
+ .crewlet-markdown-editor__field:focus-visible {
11600
+ outline: 2px solid transparent;
11601
+ outline-offset: -2px;
11602
+ }
11603
+
11604
+ .crewlet-markdown-editor__field:disabled {
11605
+ cursor: not-allowed;
11606
+ }
11607
+
11608
+ .crewlet-markdown-editor__preview {
11609
+ min-height: var(--crewlet-markdown-editor-height);
11610
+ padding: var(--spacing-3) var(--spacing-4);
11611
+ min-width: 0;
11612
+ }
11613
+
11614
+ .crewlet-markdown-editor__empty {
11615
+ margin: 0;
11616
+ font-size: var(--font-size-compact);
11617
+ color: var(--color-text-tertiary);
11618
+ }
11619
+
11620
+ .crewlet-markdown-editor__footer {
11621
+ display: flex;
11622
+ flex-wrap: wrap;
11623
+ align-items: center;
11624
+ gap: var(--spacing-1) var(--spacing-3);
11625
+ padding: var(--spacing-1) var(--spacing-3);
11626
+ border-block-start: 1px solid var(--color-border-default);
11627
+ font-size: var(--font-size-xs);
11628
+ font-variant-numeric: tabular-nums;
11629
+ color: var(--color-text-tertiary);
11630
+ }
11631
+
11632
+ @media (prefers-reduced-motion: reduce) {
11633
+ .crewlet-markdown-editor {
11634
+ transition: none;
11635
+ }
11636
+ }
11637
+
11638
+
11639
+ /* Menu-BT5PMFJI.css */
10462
11640
  /*
10463
11641
  * The menu button's panel.
10464
11642
  *
@@ -10827,7 +12005,7 @@ svg.crewlet-datetime__chevron {
10827
12005
  }
10828
12006
 
10829
12007
 
10830
- /* Modal-BNT3TDV2.css */
12008
+ /* Modal-RQAYGG4L.css */
10831
12009
  /*
10832
12010
  * The modal surface: the veil, the frame, and the three bands inside it.
10833
12011
  *
@@ -10914,6 +12092,28 @@ svg.crewlet-datetime__chevron {
10914
12092
  padding-top: var(--spacing-10);
10915
12093
  }
10916
12094
 
12095
+ /*
12096
+ * THE BOTTOM SHEET: pinned to the bottom edge with no inset, so it rises from
12097
+ * where a thumb already is. Its frame takes the window's width and keeps a
12098
+ * corner on its top edge only, and its foot stays clear of a phone's home
12099
+ * indicator.
12100
+ */
12101
+ .crewlet-modal-overlay--dialog.crewlet-modal-overlay--bottom {
12102
+ align-items: flex-end;
12103
+ padding: 0;
12104
+ }
12105
+
12106
+ .crewlet-modal-overlay--bottom > .crewlet-modal--dialog {
12107
+ width: 100%;
12108
+ max-height: calc(100dvh - var(--spacing-10));
12109
+ border-bottom: none;
12110
+ border-radius: var(--radius-xl) var(--radius-xl) 0 0;
12111
+ padding-bottom: env(safe-area-inset-bottom, 0px);
12112
+ /* It rises further and sooner than a dialog drops in: a sheet arrives from
12113
+ the edge it is pinned to, and a thumb is waiting on it. */
12114
+ animation: crewlet-modal-lift var(--motion-duration-moderate) var(--motion-easing-emphasized);
12115
+ }
12116
+
10917
12117
  /*
10918
12118
  * The sheet's veil fades over the same span the sheet itself travels, so the
10919
12119
  * two are one movement rather than a ground that lands and a panel that
@@ -11097,7 +12297,7 @@ svg.crewlet-datetime__chevron {
11097
12297
  * padding is only the least it keeps when a title wraps. It was the 16px step
11098
12298
  * while the bar was 64px, which a full control step filled exactly; at 52px
11099
12299
  * the same padding stood the head 12px past the bar behind it. At the 4px step
11100
- * the head is the bar's height with the control step at every density, 36.48px
12300
+ * the head is the bar's height with the control step at every density, 37.12px
11101
12301
  * at comfortable included, and with a subtitle under the title.
11102
12302
  *
11103
12303
  * It used to be the tighter band, 49px with a close control alone, and the
@@ -11309,6 +12509,13 @@ svg.crewlet-datetime__chevron {
11309
12509
  }
11310
12510
  }
11311
12511
 
12512
+ @keyframes crewlet-modal-lift {
12513
+ from {
12514
+ opacity: 0;
12515
+ transform: translateY(var(--spacing-6));
12516
+ }
12517
+ }
12518
+
11312
12519
  /*
11313
12520
  * A SHEET TRAVELS ITS OWN WIDTH, which is what makes the motion read as a
11314
12521
  * sheet rather than as a box appearing beside the page: the frame starts
@@ -11332,6 +12539,10 @@ svg.crewlet-datetime__chevron {
11332
12539
  .crewlet-modal--sheet {
11333
12540
  animation: none;
11334
12541
  }
12542
+
12543
+ .crewlet-modal-overlay--bottom > .crewlet-modal--dialog {
12544
+ animation: none;
12545
+ }
11335
12546
  }
11336
12547
 
11337
12548
 
@@ -12373,6 +13584,87 @@ svg.crewlet-datetime__chevron {
12373
13584
  }
12374
13585
 
12375
13586
 
13587
+ /* Outline-VCXKKU3E.css */
13588
+ /*
13589
+ * A document's outline, "On this page" (Outline.tsx).
13590
+ *
13591
+ * QUIET UNTIL IT IS CURRENT. The entries are the tertiary ink at the caption
13592
+ * step, so the column beside a page reads as a map rather than as a second
13593
+ * page, and the entry the reader is in takes the primary ink and the accent
13594
+ * edge every current row in the system takes.
13595
+ */
13596
+
13597
+ .crewlet-outline {
13598
+ display: flex;
13599
+ flex-direction: column;
13600
+ gap: var(--spacing-2);
13601
+ min-width: 0;
13602
+ }
13603
+
13604
+ /* The outline's name in the register of a group label: sentence case at the
13605
+ caption step, the 4.5:1 ink. */
13606
+ .crewlet-outline__title {
13607
+ margin: 0;
13608
+ font-family: var(--font-family-sans);
13609
+ font-size: var(--font-size-xs);
13610
+ font-weight: var(--font-weight-medium);
13611
+ line-height: var(--font-line-height-tight);
13612
+ color: var(--color-text-tertiary);
13613
+ }
13614
+
13615
+ .crewlet-outline__list {
13616
+ display: flex;
13617
+ flex-direction: column;
13618
+ margin: 0;
13619
+ padding: 0;
13620
+ list-style: none;
13621
+ }
13622
+
13623
+ /*
13624
+ * One entry: the heading's text, wrapped rather than cut, because a heading
13625
+ * cut to fit is a section the reader cannot tell from its neighbour. The edge
13626
+ * the current entry draws is held on every entry in its resting colour, so
13627
+ * nothing moves when the current entry changes.
13628
+ */
13629
+ .crewlet-outline__item {
13630
+ display: block;
13631
+ width: 100%;
13632
+ min-height: var(--size-target-min);
13633
+ margin: 0;
13634
+ padding: calc(var(--spacing-1) / 2) var(--spacing-2);
13635
+ padding-inline-start: calc(var(--spacing-3) + var(--spacing-3) * var(--crewlet-outline-depth, 0));
13636
+ border: 0;
13637
+ border-inline-start: 2px solid var(--color-border-default);
13638
+ border-radius: 0;
13639
+ background: none;
13640
+ font-family: var(--font-family-sans);
13641
+ font-size: var(--font-size-xs);
13642
+ font-weight: var(--font-weight-regular);
13643
+ line-height: var(--font-line-height-snug);
13644
+ text-align: start;
13645
+ color: var(--color-text-tertiary);
13646
+ overflow-wrap: anywhere;
13647
+ cursor: pointer;
13648
+ }
13649
+
13650
+ .crewlet-outline__item:hover {
13651
+ color: var(--color-text-primary);
13652
+ }
13653
+
13654
+ /* The ring lies on the entry's own edge, never a second line beside it. */
13655
+ .crewlet-outline__item:focus-visible {
13656
+ outline: 2px solid var(--color-focus);
13657
+ outline-offset: var(--size-focus-ring-inset-offset);
13658
+ }
13659
+
13660
+ /* The weight stays the resting one: a bolder entry is a wider one, and a
13661
+ wider entry can wrap onto a second line as the reader scrolls past it. */
13662
+ .crewlet-outline__item--current {
13663
+ border-inline-start-color: var(--color-brand-accent);
13664
+ color: var(--color-text-primary);
13665
+ }
13666
+
13667
+
12376
13668
  /* PageHeader-6EYWQXRE.css */
12377
13669
  /*
12378
13670
  * The head of a screen.
@@ -13041,82 +14333,279 @@ svg.crewlet-datetime__chevron {
13041
14333
  }
13042
14334
 
13043
14335
 
13044
- /* RelativeTime-EBAQPGO2.css */
14336
+ /* ReadingPane-5UOLPWY5.css */
13045
14337
  /*
13046
- * A relative time is text, so it takes the register around it. Its one rule is
13047
- * tabular figures: the words change once a second, and proportional digits
13048
- * would move whatever sits beside them on every tick.
14338
+ * One item read in full, in one column.
14339
+ *
14340
+ * The pane is its own container, so the column narrows its margins when the
14341
+ * PANE is narrow (beside a list on a small laptop, or alone on a phone)
14342
+ * rather than when the window is.
13049
14343
  */
13050
14344
 
13051
- .crewlet-relative-time {
13052
- font-variant-numeric: tabular-nums;
13053
- white-space: nowrap;
14345
+ .crewlet-reading-pane {
14346
+ container: crewlet-reading-pane / inline-size;
14347
+ min-width: 0;
13054
14348
  }
13055
14349
 
14350
+ .crewlet-reading-pane__column {
14351
+ /* A question and its answers read best at about seventy characters a line. */
14352
+ --crewlet-reading-pane-measure: 640px;
13056
14353
 
13057
- /* SearchTrigger-KIZLWBEH.css */
13058
- /*
13059
- * A button drawn as the field it stands in for.
13060
- *
13061
- * TWO PLACES, TWO GROUNDS. The approved design draws it in the rail, the
13062
- * whole width of the sidebar on the frame, and in a screen's own bar on the
13063
- * sheet. In each it is one rung up from what it stands on, the sheet on the
13064
- * frame and the card on the sheet, inside the default hairline, so it reads
13065
- * as a field sunk into neither and lifted off both.
13066
- */
14354
+ display: grid;
14355
+ grid-template-columns: minmax(0, 1fr);
14356
+ gap: calc(var(--spacing-4) + var(--spacing-1) / 2);
14357
+ max-width: var(--crewlet-reading-pane-measure);
14358
+ margin: 0 auto;
14359
+ padding: calc(var(--spacing-6) + var(--spacing-1)) calc(var(--spacing-6) + var(--spacing-1)) var(--spacing-8);
14360
+ font-size: var(--font-size-compact);
14361
+ line-height: var(--font-line-height-body);
14362
+ color: var(--color-text-primary);
14363
+ }
13067
14364
 
13068
- .crewlet-search-trigger {
13069
- display: inline-flex;
14365
+ @container crewlet-reading-pane (width < 640px) {
14366
+ .crewlet-reading-pane__column {
14367
+ padding-inline: var(--spacing-4);
14368
+ }
14369
+ }
14370
+
14371
+ /* ---- The byline -------------------------------------------------------- */
14372
+
14373
+ .crewlet-reading-pane__byline {
14374
+ display: flex;
13070
14375
  align-items: center;
13071
14376
  gap: var(--spacing-2);
13072
- /* The design's 10px inside each end: two steps and a half. */
13073
- padding: 0 calc(var(--spacing-2) + var(--spacing-1) / 2);
13074
- border: 1px solid var(--color-border-default);
13075
- border-radius: var(--radius-md);
14377
+ min-width: 0;
14378
+ margin: 0;
13076
14379
  color: var(--color-text-tertiary);
13077
- font-family: var(--font-family-sans);
13078
- font-size: var(--font-size-compact);
13079
- text-align: start;
13080
- cursor: pointer;
13081
- transition:
13082
- border-color var(--motion-duration-fast) var(--motion-easing-default),
13083
- color var(--motion-duration-fast) var(--motion-easing-default);
13084
14380
  }
13085
14381
 
13086
- /*
13087
- * THE RAIL'S FIELD: the full width of the sidebar, on the SHEET's ground, and
13088
- * a step taller than a control. It is the rail's one field and the first
13089
- * thing in it under the company's name, and the design stands it at 34px,
13090
- * the medium control and one scale step, so it reads as the way in rather
13091
- * than as one more button.
13092
- */
13093
- .crewlet-search-trigger--rail {
13094
- display: flex;
13095
- width: 100%;
13096
- height: calc(var(--size-control-md) + var(--spacing-1));
13097
- background: var(--color-surface-background);
14382
+ .crewlet-reading-pane__start,
14383
+ .crewlet-reading-pane__leading {
14384
+ display: inline-flex;
14385
+ flex: none;
14386
+ align-items: center;
13098
14387
  }
13099
14388
 
13100
- /*
13101
- * A SCREEN'S OWN SEARCH, in a bar on the sheet: the CARD's ground, the
13102
- * control height of the buttons beside it, and a resting width of its own.
13103
- */
13104
- .crewlet-search-trigger--toolbar {
13105
- /* The resting width of the box, the design's. A bar with less room sets it. */
13106
- --crewlet-search-trigger-width: 200px;
13107
-
13108
- min-width: var(--crewlet-search-trigger-width);
13109
- height: var(--size-control-md);
13110
- background: var(--color-surface-subtle);
14389
+ .crewlet-reading-pane__by {
14390
+ min-width: 0;
14391
+ overflow-wrap: anywhere;
14392
+ color: var(--color-text-secondary);
13111
14393
  }
13112
14394
 
13113
- .crewlet-search-trigger:hover {
13114
- border-color: var(--color-border-hover);
14395
+ .crewlet-reading-pane__by strong {
14396
+ font-weight: var(--font-weight-medium);
13115
14397
  color: var(--color-text-primary);
13116
14398
  }
13117
14399
 
13118
- /* One ring, over the trigger's own boundary rather than 2px off it, which is
13119
- two edges with a gap between them: the rule every field keeps (see
14400
+ .crewlet-reading-pane__note {
14401
+ color: var(--color-text-tertiary);
14402
+ }
14403
+
14404
+ /* ---- The title and what it needs -------------------------------------- */
14405
+
14406
+ .crewlet-reading-pane__title {
14407
+ margin: 0;
14408
+ font-size: var(--font-size-2xl);
14409
+ font-weight: var(--font-weight-semibold);
14410
+ line-height: var(--font-line-height-tight);
14411
+ letter-spacing: var(--font-letter-spacing-snug);
14412
+ text-wrap: balance;
14413
+ overflow-wrap: anywhere;
14414
+ color: var(--color-text-primary);
14415
+ }
14416
+
14417
+ .crewlet-reading-pane__lead {
14418
+ display: grid;
14419
+ gap: var(--spacing-2);
14420
+ min-width: 0;
14421
+ font-size: var(--font-size-sm);
14422
+ line-height: var(--font-line-height-normal);
14423
+ overflow-wrap: anywhere;
14424
+ color: var(--color-text-secondary);
14425
+ }
14426
+
14427
+ .crewlet-reading-pane__lead > * {
14428
+ margin: 0;
14429
+ }
14430
+
14431
+ .crewlet-reading-pane__quote {
14432
+ display: grid;
14433
+ gap: var(--spacing-2);
14434
+ min-width: 0;
14435
+ margin: 0;
14436
+ font-size: var(--font-size-md);
14437
+ line-height: var(--font-line-height-normal);
14438
+ overflow-wrap: anywhere;
14439
+ color: var(--color-text-primary);
14440
+ }
14441
+
14442
+ .crewlet-reading-pane__quote > * {
14443
+ margin: 0;
14444
+ }
14445
+
14446
+ .crewlet-reading-pane__quote--verbatim {
14447
+ padding: var(--spacing-2) var(--spacing-3);
14448
+ border-left: 2px solid var(--color-border-strong);
14449
+ font-family: var(--font-family-mono);
14450
+ font-size: var(--font-size-xs);
14451
+ white-space: pre-wrap;
14452
+ }
14453
+
14454
+ /* ---- The reasoning ----------------------------------------------------- */
14455
+
14456
+ .crewlet-reading-pane__reasoning {
14457
+ display: grid;
14458
+ gap: var(--spacing-1);
14459
+ min-width: 0;
14460
+ padding: var(--spacing-3) calc(var(--spacing-3) + var(--spacing-1) / 2);
14461
+ border-radius: var(--radius-md);
14462
+ background: var(--color-surface-inset);
14463
+ }
14464
+
14465
+ .crewlet-reading-pane__reasoning-title {
14466
+ margin: 0;
14467
+ font-size: var(--font-size-xs);
14468
+ color: var(--color-text-tertiary);
14469
+ }
14470
+
14471
+ .crewlet-reading-pane__reasoning-title strong {
14472
+ font-weight: var(--font-weight-semibold);
14473
+ color: var(--color-text-primary);
14474
+ }
14475
+
14476
+ .crewlet-reading-pane__reasoning-body {
14477
+ display: grid;
14478
+ gap: var(--spacing-2);
14479
+ min-width: 0;
14480
+ overflow-wrap: anywhere;
14481
+ color: var(--color-text-secondary);
14482
+ }
14483
+
14484
+ .crewlet-reading-pane__reasoning-body > * {
14485
+ margin: 0;
14486
+ }
14487
+
14488
+ .crewlet-reading-pane__reasoning-footer {
14489
+ margin-top: calc(var(--spacing-1) / 2);
14490
+ }
14491
+
14492
+ /* ---- What the reader did ----------------------------------------------- */
14493
+
14494
+ .crewlet-reading-pane__outcome {
14495
+ display: flex;
14496
+ align-items: center;
14497
+ gap: var(--spacing-2);
14498
+ min-width: 0;
14499
+ margin: 0;
14500
+ font-size: var(--font-size-xs);
14501
+ overflow-wrap: anywhere;
14502
+ color: var(--color-feedback-success-ink);
14503
+ }
14504
+
14505
+ .crewlet-reading-pane__outcome-mark {
14506
+ flex: none;
14507
+ }
14508
+
14509
+ .crewlet-reading-pane__outcome strong {
14510
+ font-weight: var(--font-weight-medium);
14511
+ color: var(--color-text-primary);
14512
+ }
14513
+
14514
+ /* ---- A section after the answer ---------------------------------------- */
14515
+
14516
+ .crewlet-reading-pane__section {
14517
+ display: grid;
14518
+ grid-template-columns: minmax(0, 1fr);
14519
+ gap: var(--spacing-3);
14520
+ padding-top: calc(var(--spacing-4) + var(--spacing-1) / 2);
14521
+ border-top: 1px solid var(--color-border-default);
14522
+ }
14523
+
14524
+ /* The heading's own line box is the label's, so the label sits where it is drawn. */
14525
+ .crewlet-reading-pane__section-label {
14526
+ margin: 0;
14527
+ font: inherit;
14528
+ font-size: var(--font-size-2xs);
14529
+ line-height: var(--font-line-height-snug);
14530
+ }
14531
+
14532
+
14533
+ /* RelativeTime-EBAQPGO2.css */
14534
+ /*
14535
+ * A relative time is text, so it takes the register around it. Its one rule is
14536
+ * tabular figures: the words change once a second, and proportional digits
14537
+ * would move whatever sits beside them on every tick.
14538
+ */
14539
+
14540
+ .crewlet-relative-time {
14541
+ font-variant-numeric: tabular-nums;
14542
+ white-space: nowrap;
14543
+ }
14544
+
14545
+
14546
+ /* SearchTrigger-KIZLWBEH.css */
14547
+ /*
14548
+ * A button drawn as the field it stands in for.
14549
+ *
14550
+ * TWO PLACES, TWO GROUNDS. The approved design draws it in the rail, the
14551
+ * whole width of the sidebar on the frame, and in a screen's own bar on the
14552
+ * sheet. In each it is one rung up from what it stands on, the sheet on the
14553
+ * frame and the card on the sheet, inside the default hairline, so it reads
14554
+ * as a field sunk into neither and lifted off both.
14555
+ */
14556
+
14557
+ .crewlet-search-trigger {
14558
+ display: inline-flex;
14559
+ align-items: center;
14560
+ gap: var(--spacing-2);
14561
+ /* The design's 10px inside each end: two steps and a half. */
14562
+ padding: 0 calc(var(--spacing-2) + var(--spacing-1) / 2);
14563
+ border: 1px solid var(--color-border-default);
14564
+ border-radius: var(--radius-md);
14565
+ color: var(--color-text-tertiary);
14566
+ font-family: var(--font-family-sans);
14567
+ font-size: var(--font-size-compact);
14568
+ text-align: start;
14569
+ cursor: pointer;
14570
+ transition:
14571
+ border-color var(--motion-duration-fast) var(--motion-easing-default),
14572
+ color var(--motion-duration-fast) var(--motion-easing-default);
14573
+ }
14574
+
14575
+ /*
14576
+ * THE RAIL'S FIELD: the full width of the sidebar, on the SHEET's ground, and
14577
+ * a step taller than a control. It is the rail's one field and the first
14578
+ * thing in it under the company's name, and the design stands it at 34px,
14579
+ * the medium control and one scale step, so it reads as the way in rather
14580
+ * than as one more button.
14581
+ */
14582
+ .crewlet-search-trigger--rail {
14583
+ display: flex;
14584
+ width: 100%;
14585
+ height: calc(var(--size-control-md) + var(--spacing-1));
14586
+ background: var(--color-surface-background);
14587
+ }
14588
+
14589
+ /*
14590
+ * A SCREEN'S OWN SEARCH, in a bar on the sheet: the CARD's ground, the
14591
+ * control height of the buttons beside it, and a resting width of its own.
14592
+ */
14593
+ .crewlet-search-trigger--toolbar {
14594
+ /* The resting width of the box, the design's. A bar with less room sets it. */
14595
+ --crewlet-search-trigger-width: 200px;
14596
+
14597
+ min-width: var(--crewlet-search-trigger-width);
14598
+ height: var(--size-control-md);
14599
+ background: var(--color-surface-subtle);
14600
+ }
14601
+
14602
+ .crewlet-search-trigger:hover {
14603
+ border-color: var(--color-border-hover);
14604
+ color: var(--color-text-primary);
14605
+ }
14606
+
14607
+ /* One ring, over the trigger's own boundary rather than 2px off it, which is
14608
+ two edges with a gap between them: the rule every field keeps (see
13120
14609
  Input.css). */
13121
14610
  .crewlet-search-trigger:focus-visible {
13122
14611
  outline: 2px solid var(--color-focus);
@@ -13302,7 +14791,7 @@ svg.crewlet-datetime__chevron {
13302
14791
  }
13303
14792
 
13304
14793
 
13305
- /* SegmentedControl-76HODRBT.css */
14794
+ /* SegmentedControl-PKBLJVSA.css */
13306
14795
  /*
13307
14796
  * SegmentedControl: the pill row, drawn with the Tabs classes.
13308
14797
  *
@@ -13464,6 +14953,24 @@ svg.crewlet-datetime__chevron {
13464
14953
  color: var(--color-brand-accent-ink);
13465
14954
  }
13466
14955
 
14956
+ /*
14957
+ * EQUAL SHARES. The row fills the width it is given and every option takes
14958
+ * an equal column of it, so two settings stacked in one panel draw one box.
14959
+ * Two classes, for the reason the card row gives: the pill's own rules size
14960
+ * the row to its content.
14961
+ */
14962
+ .crewlet-tabs.crewlet-segmented--fill {
14963
+ display: grid;
14964
+ grid-auto-flow: column;
14965
+ grid-auto-columns: minmax(0, 1fr);
14966
+ width: 100%;
14967
+ }
14968
+
14969
+ .crewlet-segmented--fill .crewlet-segmented__option {
14970
+ justify-content: center;
14971
+ min-width: 0;
14972
+ }
14973
+
13467
14974
 
13468
14975
  /* SegmentedMeter-KQNML2TW.css */
13469
14976
  /*
@@ -13577,7 +15084,7 @@ svg.crewlet-datetime__chevron {
13577
15084
  }
13578
15085
 
13579
15086
 
13580
- /* Select-4ANVLHUY.css */
15087
+ /* Select-2P7AWUE4.css */
13581
15088
  /*
13582
15089
  * Select: one chrome over two controls, and the product's only dropdown.
13583
15090
  *
@@ -13587,9 +15094,12 @@ svg.crewlet-datetime__chevron {
13587
15094
  * into the nearest layer host and drawn with the shared listbox register, so
13588
15095
  * a list of options looks the same wherever it is offered from.
13589
15096
  *
13590
- * The boundary is --color-border-control, like every other control: the
13591
- * hairline measured 1.27:1 in light, which is a box a reader has to know is
13592
- * there already.
15097
+ * THE BOUNDARY IS A BUTTON'S, --color-border-strong, the secondary button's
15098
+ * and the date and time-window pickers'. A picker shows its value and its
15099
+ * chevron, and those are what a reader knows it by. --color-border-control,
15100
+ * at 3:1, is for the controls whose outline IS the control (a text box, a
15101
+ * checkbox, a switch; see Input.css): on a picker it drew the one bright box
15102
+ * in a row of buttons and switchers, brighter at rest than under the pointer.
13593
15103
  */
13594
15104
 
13595
15105
  .crewlet-select {
@@ -13607,7 +15117,7 @@ svg.crewlet-datetime__chevron {
13607
15117
  width: 100%;
13608
15118
  min-height: var(--size-control-md);
13609
15119
  background-color: var(--color-surface-subtle);
13610
- border: 1px solid var(--color-border-control);
15120
+ border: 1px solid var(--color-border-strong);
13611
15121
  border-radius: var(--radius-md);
13612
15122
  color: var(--color-text-primary);
13613
15123
  /* The boundary is the only thing that moves. The ring is an outline, which
@@ -13628,7 +15138,7 @@ svg.crewlet-datetime__chevron {
13628
15138
  }
13629
15139
 
13630
15140
  .crewlet-select:hover {
13631
- border-color: var(--color-border-hover);
15141
+ border-color: var(--color-border-strong-hover);
13632
15142
  }
13633
15143
 
13634
15144
  /*
@@ -13777,7 +15287,7 @@ svg.crewlet-select__chevron {
13777
15287
  display: flex;
13778
15288
  flex-direction: column;
13779
15289
  min-width: 0;
13780
- max-height: var(--crewlet-select-menu-max-height);
15290
+ max-height: min(var(--crewlet-select-menu-max-height), 60vh);
13781
15291
  /*
13782
15292
  * THE PANEL IS THE PRODUCT'S SURFACE, on the panel hairline, at the panel
13783
15293
  * corner. A list offered from a field is another panel over the one the
@@ -13804,11 +15314,25 @@ svg.crewlet-select__chevron {
13804
15314
  position: absolute;
13805
15315
  }
13806
15316
 
15317
+ /*
15318
+ * THE PANEL'S HEIGHT IS THE LIST'S. The shared listbox register caps a list
15319
+ * at min(360px, 60vh) on its own, which inside this panel made
15320
+ * `--crewlet-select-menu-max-height` a promise it could not keep past 360px:
15321
+ * a taller panel drew the same short list and scrolled it. Here the list
15322
+ * fills what the panel allows, and the panel keeps the register's cap on the
15323
+ * window (see `.crewlet-select__menu`).
15324
+ */
13807
15325
  .crewlet-select__list {
13808
15326
  flex: 1;
13809
15327
  min-height: 0;
13810
15328
  }
13811
15329
 
15330
+ /* Scoped to the panel for the weight, as the option rules below are: the
15331
+ register's cap is one class, and the bundle orders equal weights by hash. */
15332
+ .crewlet-select__menu .crewlet-select__list {
15333
+ max-height: none;
15334
+ }
15335
+
13812
15336
  .crewlet-select__group {
13813
15337
  display: flex;
13814
15338
  flex-direction: column;
@@ -13870,6 +15394,15 @@ svg.crewlet-select__chevron {
13870
15394
  color: var(--color-brand-accent-ink);
13871
15395
  }
13872
15396
 
15397
+ /*
15398
+ * AT THE ROW'S END in a list whose rows lead with a mark (see `tickAtEnd`),
15399
+ * so the mark starts at the panel's edge. After a hint it follows the hint,
15400
+ * which already takes the free space; without one it takes it itself.
15401
+ */
15402
+ .crewlet-select__option-body + .crewlet-select__option-tick--end {
15403
+ margin-left: auto;
15404
+ }
15405
+
13873
15406
  .crewlet-select__option-body {
13874
15407
  display: flex;
13875
15408
  flex-direction: column;
@@ -13877,6 +15410,30 @@ svg.crewlet-select__chevron {
13877
15410
  min-width: 0;
13878
15411
  }
13879
15412
 
15413
+ /*
15414
+ * WHAT AN OPTION DRAWS BEFORE ITS LABEL (a swatch, an avatar, a glyph),
15415
+ * centred on the label's first line rather than on the row, so a row with a
15416
+ * second line keeps its mark beside the words it belongs to. The same slot on
15417
+ * the trigger, while that option is the one chosen, sits on the value's line.
15418
+ */
15419
+ .crewlet-select__option-leading,
15420
+ .crewlet-select__leading {
15421
+ display: inline-flex;
15422
+ align-items: center;
15423
+ flex: none;
15424
+ }
15425
+
15426
+ .crewlet-select__option-leading {
15427
+ min-height: calc(var(--font-line-height-normal) * 1em);
15428
+ }
15429
+
15430
+ /* A hint ends the row's FIRST line, on the label's baseline, rather than
15431
+ sitting on the row's top edge at its own smaller size. */
15432
+ .crewlet-select__option:has(> .crewlet-listbox__hint) .crewlet-select__option-body,
15433
+ .crewlet-select__option > .crewlet-listbox__hint {
15434
+ align-self: baseline;
15435
+ }
15436
+
13880
15437
  /*
13881
15438
  * ONE LINE, WHICH IS WHAT THE ELLIPSIS BELOW WAS ALWAYS FOR. `overflow:
13882
15439
  * hidden` clips what leaves the box and `text-overflow` replaces what a LINE
@@ -13964,7 +15521,7 @@ svg.crewlet-select__chevron {
13964
15521
  }
13965
15522
 
13966
15523
 
13967
- /* SidebarNav-X5NLZNWA.css */
15524
+ /* SidebarNav-KF66MLOM.css */
13968
15525
  /*
13969
15526
  * The rail's navigation.
13970
15527
  *
@@ -14230,26 +15787,11 @@ svg.crewlet-select__chevron {
14230
15787
 
14231
15788
  /*
14232
15789
  * A PROJECT'S KEY, as a chip in the glyph's place: the prefix every item in
14233
- * the project is filed under, in mono so ENG and PROD line up by letter. It
14234
- * is the raised rung inside the plain hairline, in the secondary ink, which
14235
- * the palette suite measures on every ground a row can have; on the reader's
14236
- * own row, which is raised too, the hairline is what draws it.
15790
+ * the project is filed under, in mono so ENG and PROD line up by letter. The
15791
+ * chip is the kit's `KeyChip` (KeyChip.css); the suite below measures its ink
15792
+ * on every ground a row can have, and on the reader's own row, which is raised
15793
+ * too, its hairline is what draws it.
14237
15794
  */
14238
- .crewlet-nav-item__lead {
14239
- display: inline-flex;
14240
- align-items: center;
14241
- flex: none;
14242
- padding: 0 calc(var(--spacing-1) + 1px);
14243
- border: 1px solid var(--color-border-default);
14244
- border-radius: var(--radius-xs);
14245
- background: var(--color-surface-elevated);
14246
- color: var(--color-text-secondary);
14247
- font-family: var(--font-family-mono);
14248
- font-size: var(--font-size-2xs);
14249
- font-weight: var(--font-weight-medium);
14250
- letter-spacing: var(--font-letter-spacing-normal);
14251
- line-height: var(--font-line-height-body);
14252
- }
14253
15795
 
14254
15796
  /*
14255
15797
  * THE COUNT: how many of something the destination holds, as a quiet figure
@@ -15647,36 +17189,385 @@ svg.crewlet-select__chevron {
15647
17189
  }
15648
17190
 
15649
17191
 
15650
- /* Table-TGCS4C3F.css */
17192
+ /* Switcher-B44Q4WF4.css */
15651
17193
  /*
15652
- * Table: the operator's table, on the elements a table is made of.
17194
+ * The switcher: a button that is the page's name, and a banded panel under it
17195
+ * (a search band, a list that scrolls, and a footer that does not).
15653
17196
  *
15654
- * ONE TABLE REGISTER FOR THE WHOLE PRODUCT, and this is it: a micro-label
15655
- * header on the panel's own ground, hairline rows, cells at the compact step,
15656
- * and a row as tall as the row token every other list in the system uses. The
15657
- * DataTable below carries the same values; the two differ in what they DO
15658
- * (sorting, columns, pagination), never in what a row looks like.
17197
+ * The rows are the listbox register (`Listbox.css`), because a project in this
17198
+ * list and a result in the command palette are read the same way, and the
17199
+ * raised row that marks where the arrows are must mean the same in both. What
17200
+ * this adds is the switcher's own: a lead column every row's key lines up in,
17201
+ * the current subject outlined in the accent, and a held row that keeps its
17202
+ * reason without a hover.
15659
17203
  */
15660
- .crewlet-table {
15661
- display: flex;
15662
- flex-direction: column;
15663
- flex: 1;
15664
- min-width: 0;
15665
- /*
15666
- * THE FRAME IS THE TABLE'S, NOT THE SCROLLER'S. The boundary and the radius
15667
- * used to sit on the scroller inside, which put the action row underneath
15668
- * the frame as a loose word on the page, and let a sideways scroll carry the
15669
- * table's own edge out of view. Here the frame clips a header band that runs
15670
- * to the edge and a foot that is fenced from the rows above it, which is the
15671
- * flush panel every table on the dashboard sits in.
15672
- */
15673
- background: var(--color-surface-subtle);
15674
- border: 1px solid var(--color-border-default);
15675
- border-radius: var(--radius-lg);
15676
- overflow: hidden;
17204
+
17205
+ .crewlet-switcher {
17206
+ /* The panel's own measures: a width that holds a key, a long name and a
17207
+ count, and a height that holds eight projects with Recent above them
17208
+ without scrolling. */
17209
+ --crewlet-switcher-width: 360px;
17210
+ --crewlet-switcher-max-height: 520px;
17211
+ --crewlet-switcher-lead: 52px;
15677
17212
  }
15678
17213
 
15679
- .crewlet-table__container {
17214
+ /* ── The button ─────────────────────────────────────────────────────────── */
17215
+
17216
+ /*
17217
+ * THE PAGE'S NAME, WITH NO BOX AT REST. It is the heading of the page as much
17218
+ * as it is a control, so it reads as text in the trail until the pointer
17219
+ * reaches it; the fill appears under the pointer and stays while the panel is
17220
+ * open, and the chevron turns. The name takes the cut, never the key or the
17221
+ * chevron.
17222
+ */
17223
+ .crewlet-switcher-trigger {
17224
+ display: inline-flex;
17225
+ align-items: center;
17226
+ gap: calc(var(--spacing-1) * 1.5);
17227
+ min-width: 0;
17228
+ max-width: 100%;
17229
+ height: var(--size-row-sm);
17230
+ padding: 0 var(--spacing-1) 0 calc(var(--spacing-1) * 1.5);
17231
+ border: none;
17232
+ border-radius: var(--radius-md);
17233
+ background: transparent;
17234
+ color: var(--color-text-primary);
17235
+ font: inherit;
17236
+ font-weight: var(--font-weight-medium);
17237
+ cursor: pointer;
17238
+ transition: background-color var(--motion-duration-fast) var(--motion-easing-default);
17239
+ }
17240
+
17241
+ .crewlet-switcher-trigger:hover,
17242
+ .crewlet-switcher-trigger[aria-expanded='true'] {
17243
+ background: var(--color-surface-hover);
17244
+ }
17245
+
17246
+ .crewlet-switcher-trigger:active {
17247
+ background: var(--color-surface-pressed);
17248
+ }
17249
+
17250
+ /* Inside the button's own edge, so the trail's scrollport never clips it. */
17251
+ .crewlet-switcher-trigger:focus-visible {
17252
+ outline: 2px solid var(--color-focus);
17253
+ outline-offset: var(--size-focus-ring-inset-offset);
17254
+ }
17255
+
17256
+ .crewlet-switcher-trigger__label {
17257
+ min-width: 0;
17258
+ overflow: hidden;
17259
+ text-overflow: ellipsis;
17260
+ white-space: nowrap;
17261
+ }
17262
+
17263
+ .crewlet-switcher-trigger.is-mono .crewlet-switcher-trigger__label {
17264
+ font-family: var(--font-family-mono);
17265
+ font-size: var(--font-size-compact);
17266
+ }
17267
+
17268
+ .crewlet-switcher-trigger .crewlet-key-chip,
17269
+ .crewlet-switcher-trigger__tag {
17270
+ display: inline-flex;
17271
+ flex: none;
17272
+ }
17273
+
17274
+ svg.crewlet-switcher-trigger__chevron {
17275
+ flex: none;
17276
+ color: var(--color-text-tertiary);
17277
+ transition:
17278
+ transform var(--motion-duration-fast) var(--motion-easing-default),
17279
+ color var(--motion-duration-fast) var(--motion-easing-default);
17280
+ }
17281
+
17282
+ .crewlet-switcher-trigger:hover svg.crewlet-switcher-trigger__chevron {
17283
+ color: var(--color-text-secondary);
17284
+ }
17285
+
17286
+ .crewlet-switcher-trigger[aria-expanded='true'] svg.crewlet-switcher-trigger__chevron {
17287
+ color: var(--color-text-secondary);
17288
+ transform: rotate(180deg);
17289
+ }
17290
+
17291
+ /* ── The three surfaces ─────────────────────────────────────────────────── */
17292
+
17293
+ /*
17294
+ * ANCHORED: the popover's own surface (the subtle rung, the default hairline,
17295
+ * the large corner and the deepest shadow) at the switcher's size. The bands
17296
+ * lay themselves out inside it, so the panel itself does not scroll.
17297
+ */
17298
+ .crewlet-popover.crewlet-switcher {
17299
+ display: flex;
17300
+ flex-direction: column;
17301
+ width: var(--crewlet-switcher-width);
17302
+ min-width: 0;
17303
+ max-width: calc(100vw - var(--spacing-4));
17304
+ max-height: min(var(--crewlet-switcher-max-height), calc(100dvh - var(--spacing-10) - var(--spacing-4)));
17305
+ overflow: hidden;
17306
+ }
17307
+
17308
+ /*
17309
+ * CENTRED: the same panel as a dialog, a step lower than a dialog stands so
17310
+ * it clears the page's bar, arriving at the popover's pace rather than a
17311
+ * dialog's, because it is the same panel opened from somewhere else.
17312
+ */
17313
+ .crewlet-modal.crewlet-switcher--centered {
17314
+ --crewlet-modal-width: var(--crewlet-switcher-width);
17315
+
17316
+ max-height: min(var(--crewlet-switcher-max-height), calc(100dvh - var(--spacing-10) - var(--spacing-6)));
17317
+ margin-top: var(--spacing-2);
17318
+ animation-duration: var(--motion-duration-base);
17319
+ }
17320
+
17321
+ /* A SHEET carries a grab handle over its title, which says it came from the
17322
+ edge it is pinned to. Decoration: the close control is what closes it. */
17323
+ .crewlet-modal.crewlet-switcher--sheet::before {
17324
+ content: '';
17325
+ flex: none;
17326
+ width: calc(var(--spacing-7) + var(--spacing-1));
17327
+ height: var(--spacing-1);
17328
+ margin: var(--spacing-2) auto 0;
17329
+ border-radius: var(--radius-pill);
17330
+ background: var(--color-border-strong);
17331
+ }
17332
+
17333
+ .crewlet-switcher--sheet .crewlet-modal__header {
17334
+ min-height: var(--size-control-lg);
17335
+ padding: 0 var(--spacing-2) 0 var(--spacing-4);
17336
+ }
17337
+
17338
+ /* A dialog's body scrolls its whole content; here the list alone scrolls. */
17339
+ .crewlet-switcher .crewlet-modal__body {
17340
+ display: flex;
17341
+ flex-direction: column;
17342
+ overflow: hidden;
17343
+ }
17344
+
17345
+ .crewlet-switcher__panel {
17346
+ display: flex;
17347
+ flex: 1 1 auto;
17348
+ flex-direction: column;
17349
+ min-height: 0;
17350
+ }
17351
+
17352
+ /* ── The search band ────────────────────────────────────────────────────── */
17353
+
17354
+ /*
17355
+ * The field with no box of its own, as the command palette draws it: the band
17356
+ * is the field. It is set at the trail's size rather than the palette's
17357
+ * headline size, because the panel is a list read at a glance, and at the
17358
+ * reading size on a phone, where a smaller field zooms the page when tapped.
17359
+ */
17360
+ .crewlet-input.crewlet-switcher__search {
17361
+ flex-shrink: 0;
17362
+ min-height: var(--size-control-lg);
17363
+ padding-inline: var(--spacing-3) var(--spacing-2);
17364
+ border: none;
17365
+ border-bottom: 1px solid var(--color-border-default);
17366
+ border-radius: 0;
17367
+ background: transparent;
17368
+ }
17369
+
17370
+ .crewlet-input.crewlet-switcher__search .crewlet-input__control {
17371
+ font-size: var(--font-size-sm);
17372
+ }
17373
+
17374
+ .crewlet-switcher--sheet .crewlet-input.crewlet-switcher__search .crewlet-input__control {
17375
+ font-size: var(--font-size-md);
17376
+ }
17377
+
17378
+ /* ── The list ───────────────────────────────────────────────────────────── */
17379
+
17380
+ .crewlet-switcher__scroller {
17381
+ flex: 1 1 auto;
17382
+ min-height: 0;
17383
+ overflow-y: auto;
17384
+ overscroll-behavior: contain;
17385
+ padding: var(--spacing-1);
17386
+ scrollbar-width: thin;
17387
+ }
17388
+
17389
+ .crewlet-switcher__list {
17390
+ display: flex;
17391
+ flex-direction: column;
17392
+ }
17393
+
17394
+ /*
17395
+ * A ROW: a lead column, the name, and a figure at the end. Both classes are
17396
+ * named so this ties with nothing in `Listbox.css`, whose rows are a step
17397
+ * shorter and padded on every side.
17398
+ */
17399
+ .crewlet-listbox__option.crewlet-switcher__option {
17400
+ gap: 0;
17401
+ min-height: var(--size-row-md);
17402
+ padding-block: 0;
17403
+ font-weight: var(--font-weight-medium);
17404
+ text-decoration: none;
17405
+ }
17406
+
17407
+ .crewlet-switcher--sheet .crewlet-listbox__option.crewlet-switcher__option {
17408
+ min-height: var(--size-control-lg);
17409
+ font-size: var(--font-size-sm);
17410
+ }
17411
+
17412
+ /*
17413
+ * THE CURRENT SUBJECT, outlined by its own accent hairline inside the row: an
17414
+ * outline rather than a shadow, so forced-colours mode keeps it. The row the
17415
+ * arrows are on takes the raised fill as every listbox row does; both can land
17416
+ * on one row, and it never gains a second border.
17417
+ */
17418
+ .crewlet-listbox__option.crewlet-switcher__option.is-current {
17419
+ color: var(--color-text-primary);
17420
+ outline: 1px solid var(--color-brand-accent);
17421
+ outline-offset: -1px;
17422
+ }
17423
+
17424
+ /* A HELD ROW answers no pointer: no fill under it, and the reason in the quiet
17425
+ ink at its end says why. */
17426
+ .crewlet-listbox__option.crewlet-switcher__option[aria-disabled='true'] {
17427
+ background: transparent;
17428
+ color: var(--color-text-tertiary);
17429
+ }
17430
+
17431
+ /* Every row's key starts on one line, whatever the key's length. */
17432
+ .crewlet-switcher__lead {
17433
+ display: flex;
17434
+ flex: none;
17435
+ align-items: center;
17436
+ width: var(--crewlet-switcher-lead);
17437
+ color: var(--color-text-tertiary);
17438
+ }
17439
+
17440
+ .crewlet-switcher__label {
17441
+ flex: 1 1 auto;
17442
+ min-width: 0;
17443
+ overflow: hidden;
17444
+ text-overflow: ellipsis;
17445
+ white-space: nowrap;
17446
+ }
17447
+
17448
+ /* The letters a search matched: the weight carries it, in the primary ink. */
17449
+ b.crewlet-switcher__match {
17450
+ font-weight: var(--font-weight-bold);
17451
+ color: var(--color-text-primary);
17452
+ }
17453
+
17454
+ .crewlet-switcher__meta {
17455
+ display: inline-flex;
17456
+ flex: none;
17457
+ align-items: center;
17458
+ gap: calc(var(--spacing-1) * 1.5);
17459
+ margin-left: var(--spacing-3);
17460
+ color: var(--color-text-tertiary);
17461
+ font-size: var(--font-size-xs);
17462
+ font-weight: var(--font-weight-regular);
17463
+ font-variant-numeric: tabular-nums;
17464
+ white-space: nowrap;
17465
+ }
17466
+
17467
+ /* A group's heading carries its count at its end. */
17468
+ .crewlet-switcher__heading {
17469
+ display: flex;
17470
+ align-items: baseline;
17471
+ justify-content: space-between;
17472
+ }
17473
+
17474
+ .crewlet-switcher__count {
17475
+ font-variant-numeric: tabular-nums;
17476
+ letter-spacing: normal;
17477
+ }
17478
+
17479
+ /* A line about the list itself, on the inset rung: not a row, so not a row's
17480
+ shape. */
17481
+ .crewlet-switcher__note {
17482
+ margin: calc(var(--spacing-1) * 1.5) var(--spacing-2) var(--spacing-1);
17483
+ padding: var(--spacing-2) calc(var(--spacing-2) + var(--spacing-1) / 2);
17484
+ border-radius: var(--radius-md);
17485
+ background: var(--color-surface-inset);
17486
+ color: var(--color-text-secondary);
17487
+ font-size: var(--font-size-xs);
17488
+ }
17489
+
17490
+ /* A state of the list, said in two lines, with its actions as rows under it. */
17491
+ .crewlet-switcher__message {
17492
+ display: grid;
17493
+ gap: var(--spacing-1);
17494
+ padding: var(--spacing-3) var(--spacing-3) var(--spacing-2);
17495
+ }
17496
+
17497
+ .crewlet-switcher__message-title {
17498
+ color: var(--color-text-primary);
17499
+ font-size: var(--font-size-compact);
17500
+ font-weight: var(--font-weight-semibold);
17501
+ }
17502
+
17503
+ .crewlet-switcher__message-body {
17504
+ color: var(--color-text-secondary);
17505
+ font-size: var(--font-size-xs);
17506
+ }
17507
+
17508
+ /* Placeholder rows the shape of the rows on their way. */
17509
+ .crewlet-switcher__skeleton-row {
17510
+ display: flex;
17511
+ align-items: center;
17512
+ height: var(--size-row-md);
17513
+ padding: 0 var(--spacing-3);
17514
+ }
17515
+
17516
+ .crewlet-switcher__skeleton-row > .crewlet-switcher__meta {
17517
+ margin-left: auto;
17518
+ }
17519
+
17520
+ /* ── The footer ─────────────────────────────────────────────────────────── */
17521
+
17522
+ .crewlet-switcher__footer {
17523
+ display: flex;
17524
+ flex: none;
17525
+ flex-direction: column;
17526
+ padding: var(--spacing-1);
17527
+ border-top: 1px solid var(--color-border-default);
17528
+ }
17529
+
17530
+ @media (prefers-reduced-motion: reduce) {
17531
+ .crewlet-switcher-trigger {
17532
+ transition: none;
17533
+ }
17534
+
17535
+ svg.crewlet-switcher-trigger__chevron {
17536
+ transition: none;
17537
+ }
17538
+ }
17539
+
17540
+
17541
+ /* Table-TGCS4C3F.css */
17542
+ /*
17543
+ * Table: the operator's table, on the elements a table is made of.
17544
+ *
17545
+ * ONE TABLE REGISTER FOR THE WHOLE PRODUCT, and this is it: a micro-label
17546
+ * header on the panel's own ground, hairline rows, cells at the compact step,
17547
+ * and a row as tall as the row token every other list in the system uses. The
17548
+ * DataTable below carries the same values; the two differ in what they DO
17549
+ * (sorting, columns, pagination), never in what a row looks like.
17550
+ */
17551
+ .crewlet-table {
17552
+ display: flex;
17553
+ flex-direction: column;
17554
+ flex: 1;
17555
+ min-width: 0;
17556
+ /*
17557
+ * THE FRAME IS THE TABLE'S, NOT THE SCROLLER'S. The boundary and the radius
17558
+ * used to sit on the scroller inside, which put the action row underneath
17559
+ * the frame as a loose word on the page, and let a sideways scroll carry the
17560
+ * table's own edge out of view. Here the frame clips a header band that runs
17561
+ * to the edge and a foot that is fenced from the rows above it, which is the
17562
+ * flush panel every table on the dashboard sits in.
17563
+ */
17564
+ background: var(--color-surface-subtle);
17565
+ border: 1px solid var(--color-border-default);
17566
+ border-radius: var(--radius-lg);
17567
+ overflow: hidden;
17568
+ }
17569
+
17570
+ .crewlet-table__container {
15680
17571
  /* The overflow is a safety net for a cell that cannot wrap (a long token, a
15681
17572
  hash); the fixed layout below is what keeps a table inside the width it is
15682
17573
  given. A `maxHeight` gives it something to scroll vertically, which is
@@ -15819,7 +17710,7 @@ svg.crewlet-select__chevron {
15819
17710
  }
15820
17711
 
15821
17712
 
15822
- /* Tabs-5I5Q5KKM.css */
17713
+ /* Tabs-ITJYJFMU.css */
15823
17714
  /*
15824
17715
  * The pill register: Tabs and SegmentedControl.
15825
17716
  *
@@ -16122,8 +18013,57 @@ svg.crewlet-select__chevron {
16122
18013
  outline-offset: 0;
16123
18014
  }
16124
18015
 
16125
- .crewlet-tabs__tab.is-disabled,
16126
- .crewlet-tabs__tab:disabled {
18016
+ /* ─── Chip (a lens row) ───────────────────────────────────────── */
18017
+ /*
18018
+ * QUIET CHIPS WITH NO WELL: the lenses of an object or a scope, set beside its
18019
+ * name in a page's bar. A well round them was a second box beside the name the
18020
+ * lenses are about, and a raised chip inside it a second highlight. Here the
18021
+ * chip that is on is drawn by its own border in the accent and nothing else,
18022
+ * which is the kit's one way of saying "this one is chosen".
18023
+ */
18024
+ .crewlet-tabs--chip {
18025
+ display: inline-flex;
18026
+ align-items: center;
18027
+ gap: calc(var(--spacing-1) / 2);
18028
+ }
18029
+
18030
+ .crewlet-tabs--chip .crewlet-tabs__tab {
18031
+ min-height: var(--size-control-sm);
18032
+ padding: 0 calc(var(--spacing-2) + var(--spacing-1) / 2);
18033
+ border-radius: var(--radius-md);
18034
+ color: var(--color-text-secondary);
18035
+ font-size: var(--font-size-xs);
18036
+ }
18037
+
18038
+ .crewlet-tabs--chip .crewlet-tabs__tab:hover:not(.is-disabled):not(.is-active) {
18039
+ background: var(--color-surface-hover);
18040
+ }
18041
+
18042
+ /* A COUNT IS A QUIET FIGURE here, not a pill: a pill inside a chip is a box
18043
+ inside a box, beside a name that already has its own. */
18044
+ .crewlet-tabs--chip .crewlet-count {
18045
+ min-width: 0;
18046
+ padding: 0;
18047
+ background: none;
18048
+ }
18049
+
18050
+ /* An outline rather than a border, so a chip turning on does not move its
18051
+ neighbours by a pixel, and forced-colors mode keeps it. */
18052
+ .crewlet-tabs--chip .crewlet-tabs__tab.is-active {
18053
+ color: var(--color-text-primary);
18054
+ outline: 1px solid var(--color-brand-accent);
18055
+ outline-offset: -1px;
18056
+ }
18057
+
18058
+ /* THE RING TAKES THE BORDER'S PLACE: declared after it and of the same
18059
+ weight, so a focused chip that is on draws one edge, the ring. */
18060
+ .crewlet-tabs--chip .crewlet-tabs__tab:focus-visible {
18061
+ outline: 2px solid var(--color-focus);
18062
+ outline-offset: -2px;
18063
+ }
18064
+
18065
+ .crewlet-tabs__tab.is-disabled,
18066
+ .crewlet-tabs__tab:disabled {
16127
18067
  opacity: 0.55;
16128
18068
  cursor: not-allowed;
16129
18069
  }
@@ -16849,200 +18789,556 @@ svg.crewlet-select__chevron {
16849
18789
  color: var(--color-text-primary);
16850
18790
  }
16851
18791
 
16852
- .crewlet-tags-input__list .crewlet-listbox__option.is-highlight,
16853
- .crewlet-tags-input__list .crewlet-listbox__option:hover {
16854
- background: var(--color-surface-hover);
16855
- color: var(--color-text-primary);
18792
+ .crewlet-tags-input__list .crewlet-listbox__option.is-highlight,
18793
+ .crewlet-tags-input__list .crewlet-listbox__option:hover {
18794
+ background: var(--color-surface-hover);
18795
+ color: var(--color-text-primary);
18796
+ }
18797
+
18798
+ /* The tick column, which holds its width whether or not a row is chosen, so
18799
+ the labels line up down the list. */
18800
+ .crewlet-tags-input__option-tick {
18801
+ display: inline-flex;
18802
+ align-items: center;
18803
+ justify-content: center;
18804
+ flex: none;
18805
+ width: 16px;
18806
+ height: 16px;
18807
+ color: var(--color-brand-accent-ink);
18808
+ }
18809
+
18810
+ .crewlet-tags-input__option-label {
18811
+ overflow: hidden;
18812
+ text-overflow: ellipsis;
18813
+ white-space: nowrap;
18814
+ }
18815
+
18816
+ @media (prefers-reduced-motion: reduce) {
18817
+ .crewlet-tags-input__box {
18818
+ transition: none;
18819
+ }
18820
+ }
18821
+
18822
+
18823
+ /* Text-XIPYYZX2.css */
18824
+ /*
18825
+ * The type registers, one rule each.
18826
+ *
18827
+ * Every register states its size, its weight, its tracking and its ink
18828
+ * together, because those move as one: a caption is not "body, smaller", it is
18829
+ * a different job. The ink a register sets is its default, and the tone
18830
+ * modifiers below override it, so they are declared after.
18831
+ */
18832
+
18833
+ .crewlet-text {
18834
+ min-width: 0;
18835
+ }
18836
+
18837
+ .crewlet-text--display {
18838
+ font-family: var(--font-family-display);
18839
+ font-size: var(--font-size-3xl);
18840
+ font-weight: var(--font-weight-semibold);
18841
+ letter-spacing: var(--font-letter-spacing-tight);
18842
+ line-height: var(--font-line-height-tight);
18843
+ font-variant-numeric: tabular-nums;
18844
+ color: var(--color-text-primary);
18845
+ }
18846
+
18847
+ .crewlet-text--stat {
18848
+ font-size: var(--font-size-2xl);
18849
+ font-weight: var(--font-weight-semibold);
18850
+ letter-spacing: var(--font-letter-spacing-tight);
18851
+ line-height: var(--font-line-height-tight);
18852
+ font-variant-numeric: tabular-nums;
18853
+ color: var(--color-text-primary);
18854
+ }
18855
+
18856
+ .crewlet-text--heading {
18857
+ font-family: var(--font-family-display);
18858
+ font-size: var(--font-size-lg);
18859
+ font-weight: var(--font-weight-semibold);
18860
+ /* The tight step, which is the one every heading in the product is set on.
18861
+ Two tracking values across two heading registers is how a card title and
18862
+ the section title above it stop looking like one family. */
18863
+ letter-spacing: var(--font-letter-spacing-tight);
18864
+ line-height: var(--font-line-height-snug);
18865
+ color: var(--color-text-primary);
18866
+ }
18867
+
18868
+ .crewlet-text--lead {
18869
+ font-size: var(--font-size-md);
18870
+ font-weight: var(--font-weight-medium);
18871
+ line-height: var(--font-line-height-normal);
18872
+ color: var(--color-text-primary);
18873
+ }
18874
+
18875
+ .crewlet-text--body {
18876
+ font-size: var(--font-size-sm);
18877
+ line-height: var(--font-line-height-normal);
18878
+ color: var(--color-text-primary);
18879
+ }
18880
+
18881
+ .crewlet-text--cell {
18882
+ font-size: var(--font-size-compact);
18883
+ line-height: var(--font-line-height-snug);
18884
+ color: var(--color-text-primary);
18885
+ }
18886
+
18887
+ /*
18888
+ * Metadata: the tertiary step rather than the decoration one. A caption is
18889
+ * read, not glanced at, so it carries the 4.5:1 ink.
18890
+ */
18891
+ .crewlet-text--caption {
18892
+ font-size: var(--font-size-xs);
18893
+ line-height: var(--font-line-height-snug);
18894
+ color: var(--color-text-tertiary);
18895
+ }
18896
+
18897
+ /*
18898
+ * THE one micro-label register, declared once and never overridden. The system
18899
+ * this replaces declared it once and then redeclared it in six selectors with
18900
+ * six different tracking values.
18901
+ */
18902
+ .crewlet-text--label {
18903
+ font-size: var(--font-size-2xs);
18904
+ font-weight: var(--font-weight-medium);
18905
+ letter-spacing: var(--font-letter-spacing-wide);
18906
+ line-height: var(--font-line-height-snug);
18907
+ text-transform: uppercase;
18908
+ color: var(--color-text-tertiary);
18909
+ }
18910
+
18911
+ .crewlet-text--tone-primary {
18912
+ color: var(--color-text-primary);
18913
+ }
18914
+
18915
+ .crewlet-text--tone-secondary {
18916
+ color: var(--color-text-secondary);
18917
+ }
18918
+
18919
+ .crewlet-text--tone-tertiary {
18920
+ color: var(--color-text-tertiary);
18921
+ }
18922
+
18923
+ .crewlet-text--mono {
18924
+ font-family: var(--font-family-mono);
18925
+ /*
18926
+ * An identifier is read character by character, so a ligature that joins two
18927
+ * of them into one drawing is a drawing of something the reader did not
18928
+ * type.
18929
+ */
18930
+ font-variant-ligatures: none;
18931
+ font-variant-numeric: tabular-nums;
18932
+ }
18933
+
18934
+ .crewlet-text--numeric {
18935
+ font-variant-numeric: tabular-nums;
18936
+ font-feature-settings: 'tnum' 1;
18937
+ }
18938
+
18939
+ .crewlet-text--truncate {
18940
+ display: inline-block;
18941
+ max-width: 100%;
18942
+ overflow: hidden;
18943
+ text-overflow: ellipsis;
18944
+ white-space: nowrap;
18945
+ vertical-align: bottom;
18946
+ }
18947
+
18948
+ .crewlet-text--clamp-2,
18949
+ .crewlet-text--clamp-3 {
18950
+ display: -webkit-box;
18951
+ -webkit-box-orient: vertical;
18952
+ overflow: hidden;
18953
+ }
18954
+
18955
+ .crewlet-text--clamp-2 {
18956
+ -webkit-line-clamp: 2;
18957
+ line-clamp: 2;
18958
+ }
18959
+
18960
+ .crewlet-text--clamp-3 {
18961
+ -webkit-line-clamp: 3;
18962
+ line-clamp: 3;
18963
+ }
18964
+
18965
+ /*
18966
+ * A measure is a maximum, never a width: a bounded block still shrinks with
18967
+ * the column it sits in.
18968
+ */
18969
+ .crewlet-text--measure-normal {
18970
+ display: block;
18971
+ max-width: var(--size-measure);
18972
+ }
18973
+
18974
+ .crewlet-text--measure-narrow {
18975
+ display: block;
18976
+ max-width: var(--size-measure-narrow);
18977
+ }
18978
+
18979
+
18980
+ /* ThemeGallery-NITASULQ.css */
18981
+ /*
18982
+ * The gallery of themes: each group's heading over a grid of cards.
18983
+ *
18984
+ * A ROW HOLDS THE SAME NUMBER OF CARDS IN EVERY GROUP (`columns`, three by
18985
+ * default), so a group of one draws a card the size of every other card
18986
+ * rather than one stretched across the row, and the swatches line up from
18987
+ * group to group.
18988
+ */
18989
+
18990
+ .crewlet-theme-gallery__groups {
18991
+ display: flex;
18992
+ flex-direction: column;
18993
+ gap: var(--spacing-3);
18994
+ }
18995
+
18996
+ .crewlet-theme-gallery__group {
18997
+ display: flex;
18998
+ flex-direction: column;
18999
+ gap: var(--spacing-1);
19000
+ }
19001
+
19002
+ .crewlet-theme-gallery__heading {
19003
+ color: var(--color-text-tertiary);
19004
+ font-size: var(--font-size-2xs);
19005
+ line-height: var(--font-line-height-normal);
19006
+ }
19007
+
19008
+ .crewlet-theme-gallery__cards {
19009
+ display: grid;
19010
+ grid-template-columns: repeat(var(--crewlet-theme-gallery-columns), minmax(0, 1fr));
19011
+ gap: var(--spacing-2);
19012
+ }
19013
+
19014
+ /*
19015
+ * A CARD IS ITS BORDER. Resting, the plain hairline; under the pointer, the
19016
+ * strong one; chosen, the accent. One line round the card in every state, so
19017
+ * the chosen card is never a card inside a frame.
19018
+ */
19019
+ .crewlet-theme-gallery__card {
19020
+ display: flex;
19021
+ flex-direction: column;
19022
+ gap: var(--spacing-1);
19023
+ min-width: 0;
19024
+ padding: var(--spacing-2);
19025
+ border: 1px solid var(--color-border-default);
19026
+ border-radius: var(--radius-md);
19027
+ background: var(--color-surface-subtle);
19028
+ color: var(--color-text-primary);
19029
+ font: inherit;
19030
+ text-align: left;
19031
+ cursor: pointer;
19032
+ }
19033
+
19034
+ /* Not on the chosen card: under the pointer it keeps the accent, or the one
19035
+ card that says "this one" would stop saying it while it is being pointed at. */
19036
+ .crewlet-theme-gallery__card:hover:not(:disabled):not(.is-chosen) {
19037
+ border-color: var(--color-border-strong);
19038
+ }
19039
+
19040
+ .crewlet-theme-gallery__card.is-chosen {
19041
+ border-color: var(--color-brand-accent);
19042
+ }
19043
+
19044
+ /* The ring is drawn OVER the border, inset by its width, never a second line outside it. */
19045
+ .crewlet-theme-gallery__card:focus-visible {
19046
+ outline: 2px solid var(--color-focus);
19047
+ outline-offset: -1px;
19048
+ }
19049
+
19050
+ .crewlet-theme-gallery__card:disabled {
19051
+ cursor: not-allowed;
19052
+ opacity: 0.5;
19053
+ }
19054
+
19055
+ .crewlet-theme-gallery__name {
19056
+ overflow: hidden;
19057
+ font-size: var(--font-size-xs);
19058
+ font-weight: var(--font-weight-medium);
19059
+ line-height: var(--font-line-height-tight);
19060
+ text-overflow: ellipsis;
19061
+ white-space: nowrap;
19062
+ }
19063
+
19064
+ /*
19065
+ * FORCED COLORS keeps the border and drops the accent, so the chosen card
19066
+ * would look like every other; the system's own selected colour says it.
19067
+ */
19068
+ @media (forced-colors: active) {
19069
+ .crewlet-theme-gallery__card.is-chosen {
19070
+ border-color: Highlight;
19071
+ border-width: 2px;
19072
+ }
19073
+ }
19074
+
19075
+
19076
+ /* ThemeSwatch-4DL457ZB.css */
19077
+ /*
19078
+ * A theme's thumbnail.
19079
+ *
19080
+ * EVERY COLOUR IS THE THEME'S OWN, from the custom properties ThemeSwatch sets
19081
+ * on each half (--crewlet-swatch-*), and none is the page's except the
19082
+ * outline, which is the page's hairline because the page is where the
19083
+ * thumbnail sits. Two halves share the box equally: dark, then light.
19084
+ *
19085
+ * IT IS A PICTURE, so forced-colors mode leaves it alone: repainted to the
19086
+ * system's two colours, every theme would draw the same blank box.
19087
+ */
19088
+
19089
+ .crewlet-theme-swatch {
19090
+ display: grid;
19091
+ grid-auto-flow: column;
19092
+ grid-auto-columns: minmax(0, 1fr);
19093
+ flex: none;
19094
+ overflow: hidden;
19095
+ border: 1px solid var(--color-border-default);
19096
+ forced-color-adjust: none;
19097
+ }
19098
+
19099
+ .crewlet-theme-swatch--chip {
19100
+ width: 26px;
19101
+ height: 16px;
19102
+ border-radius: var(--radius-xs);
19103
+ }
19104
+
19105
+ .crewlet-theme-swatch--card {
19106
+ width: 100%;
19107
+ height: 38px;
19108
+ border-radius: var(--radius-sm);
19109
+ }
19110
+
19111
+ .crewlet-theme-swatch--pane {
19112
+ width: 100%;
19113
+ aspect-ratio: 4 / 3;
19114
+ border-radius: var(--radius-md);
19115
+ }
19116
+
19117
+ .crewlet-theme-swatch__half {
19118
+ display: grid;
19119
+ grid-template-columns: 26% minmax(0, 1fr);
19120
+ min-width: 0;
19121
+ background: var(--crewlet-swatch-frame);
19122
+ }
19123
+
19124
+ /* ── The chip: each palette's frame, with its accent on it ────────────── */
19125
+
19126
+ .crewlet-theme-swatch--chip .crewlet-theme-swatch__half {
19127
+ grid-template-columns: none;
19128
+ place-items: center;
19129
+ }
19130
+
19131
+ .crewlet-theme-swatch__dot {
19132
+ width: 6px;
19133
+ height: 6px;
19134
+ border-radius: var(--radius-circle);
19135
+ background: var(--crewlet-swatch-accent);
19136
+ }
19137
+
19138
+ /* ── The card: a rail, a sheet, a card on it ──────────────────────────── */
19139
+
19140
+ .crewlet-theme-swatch__rail {
19141
+ display: flex;
19142
+ flex-direction: column;
19143
+ gap: 3px;
19144
+ padding: 6px 4px;
19145
+ min-width: 0;
19146
+ }
19147
+
19148
+ .crewlet-theme-swatch__rail-row {
19149
+ display: block;
19150
+ width: 80%;
19151
+ height: 3px;
19152
+ border-radius: var(--radius-pill);
19153
+ background: var(--crewlet-swatch-muted);
16856
19154
  }
16857
19155
 
16858
- /* The tick column, which holds its width whether or not a row is chosen, so
16859
- the labels line up down the list. */
16860
- .crewlet-tags-input__option-tick {
16861
- display: inline-flex;
16862
- align-items: center;
16863
- justify-content: center;
16864
- flex: none;
16865
- width: 16px;
16866
- height: 16px;
16867
- color: var(--color-brand-accent-ink);
19156
+ /* The row the reader is on stands on the raised rung, as the rail draws it. */
19157
+ .crewlet-theme-swatch__rail-row.is-current {
19158
+ width: 100%;
19159
+ height: 6px;
19160
+ background: var(--crewlet-swatch-raised);
16868
19161
  }
16869
19162
 
16870
- .crewlet-tags-input__option-label {
16871
- overflow: hidden;
16872
- text-overflow: ellipsis;
16873
- white-space: nowrap;
19163
+ .crewlet-theme-swatch__sheet {
19164
+ display: flex;
19165
+ flex-direction: column;
19166
+ min-width: 0;
19167
+ margin: 3px 3px 3px 0;
19168
+ padding: 3px;
19169
+ border-radius: var(--radius-xs);
19170
+ background: var(--crewlet-swatch-sheet);
16874
19171
  }
16875
19172
 
16876
- @media (prefers-reduced-motion: reduce) {
16877
- .crewlet-tags-input__box {
16878
- transition: none;
16879
- }
19173
+ .crewlet-theme-swatch__card {
19174
+ display: flex;
19175
+ flex: 1;
19176
+ flex-direction: column;
19177
+ justify-content: space-between;
19178
+ min-width: 0;
19179
+ padding: 4px;
19180
+ border: 1px solid var(--crewlet-swatch-hairline);
19181
+ border-radius: var(--radius-xs);
19182
+ background: var(--crewlet-swatch-card);
16880
19183
  }
16881
19184
 
19185
+ .crewlet-theme-swatch__line {
19186
+ display: block;
19187
+ width: 60%;
19188
+ height: 3px;
19189
+ border-radius: var(--radius-pill);
19190
+ background: var(--crewlet-swatch-text);
19191
+ }
16882
19192
 
16883
- /* Text-XIPYYZX2.css */
16884
19193
  /*
16885
- * The type registers, one rule each.
16886
- *
16887
- * Every register states its size, its weight, its tracking and its ink
16888
- * together, because those move as one: a caption is not "body, smaller", it is
16889
- * a different job. The ink a register sets is its default, and the tone
16890
- * modifiers below override it, so they are declared after.
19194
+ * THE ACTION GIVES WAY BEFORE IT DISAPPEARS. A narrow thumbnail has less room
19195
+ * than the action and the four states take, so the action narrows to a floor
19196
+ * and the row clips its last states, rather than the action, which is what a
19197
+ * theme is chosen for, shrinking to nothing.
16891
19198
  */
16892
-
16893
- .crewlet-text {
16894
- min-width: 0;
19199
+ .crewlet-theme-swatch__row {
19200
+ display: flex;
19201
+ align-items: center;
19202
+ gap: 2px;
19203
+ overflow: hidden;
16895
19204
  }
16896
19205
 
16897
- .crewlet-text--display {
16898
- font-family: var(--font-family-display);
16899
- font-size: var(--font-size-3xl);
16900
- font-weight: var(--font-weight-semibold);
16901
- letter-spacing: var(--font-letter-spacing-tight);
16902
- line-height: var(--font-line-height-tight);
16903
- font-variant-numeric: tabular-nums;
16904
- color: var(--color-text-primary);
19206
+ /* The primary action: the accent's fill. */
19207
+ .crewlet-theme-swatch__action {
19208
+ display: block;
19209
+ flex: 0 1 14px;
19210
+ min-width: 6px;
19211
+ height: 6px;
19212
+ margin-right: auto;
19213
+ border-radius: var(--radius-pill);
19214
+ background: var(--crewlet-swatch-accent);
16905
19215
  }
16906
19216
 
16907
- .crewlet-text--stat {
16908
- font-size: var(--font-size-2xl);
16909
- font-weight: var(--font-weight-semibold);
16910
- letter-spacing: var(--font-letter-spacing-tight);
16911
- line-height: var(--font-line-height-tight);
16912
- font-variant-numeric: tabular-nums;
16913
- color: var(--color-text-primary);
19217
+ /* The four states, in the order the kit names them. */
19218
+ .crewlet-theme-swatch__state {
19219
+ display: block;
19220
+ flex: none;
19221
+ width: 4px;
19222
+ height: 4px;
19223
+ border-radius: var(--radius-circle);
16914
19224
  }
16915
19225
 
16916
- .crewlet-text--heading {
16917
- font-family: var(--font-family-display);
16918
- font-size: var(--font-size-lg);
16919
- font-weight: var(--font-weight-semibold);
16920
- /* The tight step, which is the one every heading in the product is set on.
16921
- Two tracking values across two heading registers is how a card title and
16922
- the section title above it stop looking like one family. */
16923
- letter-spacing: var(--font-letter-spacing-tight);
16924
- line-height: var(--font-line-height-snug);
16925
- color: var(--color-text-primary);
16926
- }
19226
+ .crewlet-theme-swatch__state--info { background: var(--crewlet-swatch-info); }
19227
+ .crewlet-theme-swatch__state--warning { background: var(--crewlet-swatch-warning); }
19228
+ .crewlet-theme-swatch__state--danger { background: var(--crewlet-swatch-danger); }
19229
+ .crewlet-theme-swatch__state--success { background: var(--crewlet-swatch-success); }
16927
19230
 
16928
- .crewlet-text--lead {
16929
- font-size: var(--font-size-md);
16930
- font-weight: var(--font-weight-medium);
16931
- line-height: var(--font-line-height-normal);
16932
- color: var(--color-text-primary);
16933
- }
19231
+ /* ── The pane: the same sketch, large enough to read as a screen ───────── */
16934
19232
 
16935
- .crewlet-text--body {
16936
- font-size: var(--font-size-sm);
16937
- line-height: var(--font-line-height-normal);
16938
- color: var(--color-text-primary);
19233
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__half {
19234
+ grid-template-columns: 26% minmax(0, 1fr);
16939
19235
  }
16940
19236
 
16941
- .crewlet-text--cell {
16942
- font-size: var(--font-size-compact);
16943
- line-height: var(--font-line-height-snug);
16944
- color: var(--color-text-primary);
19237
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__rail {
19238
+ gap: 7px;
19239
+ padding: 12px 8px;
16945
19240
  }
16946
19241
 
16947
- /*
16948
- * Metadata: the tertiary step rather than the decoration one. A caption is
16949
- * read, not glanced at, so it carries the 4.5:1 ink.
16950
- */
16951
- .crewlet-text--caption {
16952
- font-size: var(--font-size-xs);
16953
- line-height: var(--font-line-height-snug);
16954
- color: var(--color-text-tertiary);
19242
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__rail-row {
19243
+ height: 5px;
16955
19244
  }
16956
19245
 
16957
- /*
16958
- * THE one micro-label register, declared once and never overridden. The system
16959
- * this replaces declared it once and then redeclared it in six selectors with
16960
- * six different tracking values.
16961
- */
16962
- .crewlet-text--label {
16963
- font-size: var(--font-size-2xs);
16964
- font-weight: var(--font-weight-medium);
16965
- letter-spacing: var(--font-letter-spacing-wide);
16966
- line-height: var(--font-line-height-snug);
16967
- text-transform: uppercase;
16968
- color: var(--color-text-tertiary);
19246
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__rail-row.is-current {
19247
+ height: 12px;
19248
+ border: 1px solid var(--crewlet-swatch-hairline);
19249
+ border-radius: var(--radius-xs);
16969
19250
  }
16970
19251
 
16971
- .crewlet-text--tone-primary {
16972
- color: var(--color-text-primary);
19252
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__sheet {
19253
+ gap: 8px;
19254
+ margin: 6px 6px 6px 0;
19255
+ padding: 10px;
19256
+ border-radius: var(--radius-sm);
16973
19257
  }
16974
19258
 
16975
- .crewlet-text--tone-secondary {
16976
- color: var(--color-text-secondary);
19259
+ .crewlet-theme-swatch__title {
19260
+ display: block;
19261
+ flex: none;
19262
+ width: 40%;
19263
+ height: 6px;
19264
+ border-radius: var(--radius-pill);
19265
+ background: var(--crewlet-swatch-text);
16977
19266
  }
16978
19267
 
16979
- .crewlet-text--tone-tertiary {
16980
- color: var(--color-text-tertiary);
19268
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__card {
19269
+ flex: none;
19270
+ gap: 7px;
19271
+ justify-content: flex-start;
19272
+ padding: 8px;
16981
19273
  }
16982
19274
 
16983
- .crewlet-text--mono {
16984
- font-family: var(--font-family-mono);
16985
- /*
16986
- * An identifier is read character by character, so a ligature that joins two
16987
- * of them into one drawing is a drawing of something the reader did not
16988
- * type.
16989
- */
16990
- font-variant-ligatures: none;
16991
- font-variant-numeric: tabular-nums;
19275
+ .crewlet-theme-swatch__item {
19276
+ display: flex;
19277
+ align-items: center;
19278
+ gap: 6px;
16992
19279
  }
16993
19280
 
16994
- .crewlet-text--numeric {
16995
- font-variant-numeric: tabular-nums;
16996
- font-feature-settings: 'tnum' 1;
19281
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__state {
19282
+ width: 6px;
19283
+ height: 6px;
16997
19284
  }
16998
19285
 
16999
- .crewlet-text--truncate {
17000
- display: inline-block;
17001
- max-width: 100%;
17002
- overflow: hidden;
17003
- text-overflow: ellipsis;
17004
- white-space: nowrap;
17005
- vertical-align: bottom;
19286
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__line {
19287
+ width: 45%;
19288
+ height: 4px;
17006
19289
  }
17007
19290
 
17008
- .crewlet-text--clamp-2,
17009
- .crewlet-text--clamp-3 {
17010
- display: -webkit-box;
17011
- -webkit-box-orient: vertical;
17012
- overflow: hidden;
19291
+ .crewlet-theme-swatch__muted {
19292
+ display: block;
19293
+ width: 18%;
19294
+ height: 4px;
19295
+ margin-left: auto;
19296
+ border-radius: var(--radius-pill);
19297
+ background: var(--crewlet-swatch-muted);
17013
19298
  }
17014
19299
 
17015
- .crewlet-text--clamp-2 {
17016
- -webkit-line-clamp: 2;
17017
- line-clamp: 2;
19300
+ .crewlet-theme-swatch__actions {
19301
+ display: flex;
19302
+ gap: 6px;
19303
+ margin-top: auto;
17018
19304
  }
17019
19305
 
17020
- .crewlet-text--clamp-3 {
17021
- -webkit-line-clamp: 3;
17022
- line-clamp: 3;
19306
+ .crewlet-theme-swatch--pane .crewlet-theme-swatch__action {
19307
+ display: grid;
19308
+ flex: none;
19309
+ place-items: center;
19310
+ width: 40%;
19311
+ height: 16px;
19312
+ margin-right: 0;
19313
+ border-radius: var(--radius-xs);
17023
19314
  }
17024
19315
 
17025
- /*
17026
- * A measure is a maximum, never a width: a bounded block still shrinks with
17027
- * the column it sits in.
17028
- */
17029
- .crewlet-text--measure-normal {
19316
+ /* The primary action's label, in the colour the theme labels its accent with. */
19317
+ .crewlet-theme-swatch__label {
17030
19318
  display: block;
17031
- max-width: var(--size-measure);
19319
+ width: 50%;
19320
+ height: 4px;
19321
+ border-radius: var(--radius-pill);
19322
+ background: var(--crewlet-swatch-on-accent);
17032
19323
  }
17033
19324
 
17034
- .crewlet-text--measure-narrow {
19325
+ .crewlet-theme-swatch__secondary {
17035
19326
  display: block;
17036
- max-width: var(--size-measure-narrow);
19327
+ width: 26%;
19328
+ height: 16px;
19329
+ border: 1px solid var(--crewlet-swatch-hairline);
19330
+ border-radius: var(--radius-xs);
19331
+ background: var(--crewlet-swatch-card);
17037
19332
  }
17038
19333
 
17039
19334
 
17040
- /* TimeWindowPicker-GBF4JDFI.css */
19335
+ /* TimeWindowPicker-BZ5HHATU.css */
17041
19336
  /*
17042
19337
  * TimeWindowPicker: one trigger over one panel.
17043
19338
  *
17044
- * The trigger takes the same geometry as a Select and a DateTimePicker, so the
17045
- * three line up in a filter bar. The panel is a RAIL of named windows beside
19339
+ * The trigger takes the same geometry and button boundary as a Select and a
19340
+ * DateTimePicker (--color-border-strong; see Select.css), so the three line
19341
+ * up in a filter bar. The panel is a RAIL of named windows beside
17046
19342
  * the calendars, rather than two tabs with one of them hidden: the windows a
17047
19343
  * reader picks by name are the road, and the absolute range is the turning off
17048
19344
  * it, so both are on screen at once and each shows what the other chose.
@@ -17057,7 +19353,7 @@ svg.crewlet-select__chevron {
17057
19353
  /* The side inset only: see DateTimePicker's own trigger. */
17058
19354
  padding: 0 var(--spacing-2) 0 var(--spacing-3);
17059
19355
  background: var(--color-surface-subtle);
17060
- border: 1px solid var(--color-border-control);
19356
+ border: 1px solid var(--color-border-strong);
17061
19357
  border-radius: var(--radius-md);
17062
19358
  color: var(--color-text-primary);
17063
19359
  font-family: inherit;
@@ -17074,7 +19370,7 @@ svg.crewlet-select__chevron {
17074
19370
  }
17075
19371
 
17076
19372
  .crewlet-time-window:hover:not(:disabled) {
17077
- border-color: var(--color-border-hover);
19373
+ border-color: var(--color-border-strong-hover);
17078
19374
  }
17079
19375
 
17080
19376
  /*
@@ -17603,102 +19899,102 @@ svg.crewlet-time-window__tick {
17603
19899
  }
17604
19900
 
17605
19901
 
17606
- /* Toaster-NVDCEIP5.css */
19902
+ /* Toaster-VZKISP2S.css */
17607
19903
  /*
17608
- * The toast stack.
19904
+ * The toast stack, drawn as the first release drew it (24a60c3): a dark strip
19905
+ * on the page's deepest ground with the large shadow and the rim light, a
19906
+ * 12px corner, the variant said by its mark alone, never a flood of its hue,
19907
+ * and the countdown as a wash behind the words that drains from the right.
17609
19908
  *
17610
- * ITS SURFACE IS A THEME TOKEN. 0.2.0 mixed the subtle surface 60 percent with
17611
- * black, which is a dark strip whatever palette is painting: on a light page
17612
- * the toast's own text measured 1.56:1 against it.
19909
+ * IN TOKENS RATHER THAN ITS LITERALS, so it follows every theme. The strip is
19910
+ * --color-surface-background: the first release mixed the panel with black,
19911
+ * which read as a dark bar on a light page, where its words measured 1.56:1.
19912
+ * The marks are the feedback INK steps, the soft moss, amber and rose it drew,
19913
+ * measured as text on every theme. The washes are the feedback SOFT steps.
17613
19914
  *
17614
- * THE DRAIN IS A RULE ALONG THE FOOT, not a wash behind the words. A tinted
17615
- * layer under the message is a composite nothing measured, and it moves while
17616
- * the message is being read; a 2px bar at the edge says the same thing and
17617
- * touches no text at all. It is decoration either way: the dismissal is a
17618
- * timer now, so a reader who asks for reduced motion still gets the toast
17619
- * taken away.
19915
+ * The wash is decoration: the dismissal is a timer, so a reader who asks for
19916
+ * reduced motion gets no wash and still gets the toast taken away.
17620
19917
  */
17621
-
17622
19918
  .crewlet-toaster {
17623
19919
  position: fixed;
17624
19920
  z-index: var(--z-index-toast);
17625
19921
  display: flex;
17626
19922
  flex-direction: column;
17627
- gap: var(--spacing-2);
17628
- /* The engine's 420px, held under the viewport at the width a phone has.
17629
- The strip is one or two lines of 13px text and an action; at 380 the
17630
- commonest failure message wrapped onto a third. */
17631
- width: min(420px, calc(100vw - var(--spacing-9)));
19923
+ gap: calc(var(--spacing-2) + var(--spacing-1) / 2);
19924
+ width: min(380px, calc(100vw - 2 * var(--spacing-6)));
17632
19925
  /* The stack itself takes no presses, so the screen under it stays live
17633
19926
  while nothing is up; each toast takes them back for its own strip. */
17634
19927
  pointer-events: none;
17635
19928
  }
17636
19929
 
17637
19930
  .crewlet-toaster--bottom-right {
17638
- bottom: var(--spacing-4);
17639
- right: var(--spacing-4);
19931
+ bottom: var(--spacing-6);
19932
+ right: var(--spacing-6);
17640
19933
  }
17641
19934
 
17642
19935
  .crewlet-toaster--top-right {
17643
- top: var(--spacing-4);
17644
- right: var(--spacing-4);
19936
+ top: var(--spacing-6);
19937
+ right: var(--spacing-6);
17645
19938
  }
17646
19939
 
17647
19940
  .crewlet-toaster--bottom-left {
17648
- bottom: var(--spacing-4);
17649
- left: var(--spacing-4);
19941
+ bottom: var(--spacing-6);
19942
+ left: var(--spacing-6);
17650
19943
  }
17651
19944
 
17652
19945
  .crewlet-toaster--top-left {
17653
- top: var(--spacing-4);
17654
- left: var(--spacing-4);
19946
+ top: var(--spacing-6);
19947
+ left: var(--spacing-6);
17655
19948
  }
17656
19949
 
17657
19950
  .crewlet-toast {
19951
+ /* The mark and the wash are the two places a variant spends its hue. */
17658
19952
  --crewlet-toast-mark: var(--color-text-secondary);
17659
- /*
17660
- * The boundary and the two inks are variables so a tone can spend them. Only
17661
- * one does: a failure, which is the engine's one toned strip.
17662
- */
17663
- --crewlet-toast-line: var(--color-border-default);
17664
- --crewlet-toast-ink: var(--color-text-primary);
17665
- --crewlet-toast-ink-quiet: var(--color-text-secondary);
19953
+ --crewlet-toast-wash: var(--color-surface-pressed);
19954
+ /* 14px at the normal density, and the corner the dismiss sits in beside it. */
19955
+ --crewlet-toast-inset: calc(var(--spacing-3) + var(--spacing-1) / 2);
17666
19956
 
17667
19957
  pointer-events: auto;
17668
19958
  position: relative;
17669
19959
  display: flex;
17670
19960
  align-items: flex-start;
17671
- /* The panel's own gap and padding, and the panel's own surface: the engine
17672
- draws a toast as a small panel that happens to float, so it sits on the
17673
- same ground, the same hairline and the same corner as everything the
17674
- screen behind it is made of. */
17675
- gap: var(--spacing-2);
17676
- padding: var(--spacing-2) var(--spacing-8) var(--spacing-2) var(--spacing-3);
17677
- background: var(--color-surface-subtle);
17678
- border: 1px solid var(--crewlet-toast-line);
17679
- border-radius: var(--radius-md);
17680
- box-shadow: var(--shadow-md);
17681
- color: var(--crewlet-toast-ink);
19961
+ gap: var(--spacing-3);
19962
+ padding: var(--crewlet-toast-inset) calc(var(--spacing-7) + var(--spacing-1) * 1.5) var(--crewlet-toast-inset)
19963
+ var(--crewlet-toast-inset);
19964
+ background: var(--color-surface-background);
19965
+ border: 1px solid var(--color-border-default);
19966
+ border-radius: var(--radius-lg);
19967
+ /* The large shadow and the rim light, both from tokens that are a shadow in
19968
+ every palette: --shadow-hairline is `none` in light, and a `none` inside a
19969
+ list drops the whole declaration. */
19970
+ box-shadow: var(--shadow-xl), var(--shadow-rim-lit);
19971
+ color: var(--color-text-primary);
17682
19972
  font-family: var(--font-family-sans);
17683
19973
  font-size: var(--font-size-compact);
17684
- line-height: var(--font-line-height-normal);
19974
+ line-height: var(--font-line-height-body);
17685
19975
  letter-spacing: var(--font-letter-spacing-snug);
17686
19976
  overflow: hidden;
17687
- animation: crewlet-toast-in var(--motion-duration-base) var(--motion-easing-emphasized);
19977
+ animation: crewlet-toast-in var(--motion-duration-slow) var(--motion-easing-emphasized);
17688
19978
  }
17689
19979
 
17690
19980
  @keyframes crewlet-toast-in {
17691
19981
  from {
17692
19982
  opacity: 0;
17693
- transform: translateY(6px);
19983
+ transform: translateX(var(--spacing-4));
17694
19984
  }
17695
-
17696
19985
  to {
17697
19986
  opacity: 1;
17698
- transform: translateY(0);
19987
+ transform: translateX(0);
17699
19988
  }
17700
19989
  }
17701
19990
 
19991
+ /* The words sit over the wash: every child is raised, and the dismiss and the
19992
+ wash below take their own places back. */
19993
+ .crewlet-toast > * {
19994
+ position: relative;
19995
+ z-index: var(--z-index-raised);
19996
+ }
19997
+
17702
19998
  .crewlet-toast__icon {
17703
19999
  display: inline-flex;
17704
20000
  flex: none;
@@ -17706,34 +20002,26 @@ svg.crewlet-time-window__tick {
17706
20002
  color: var(--crewlet-toast-mark);
17707
20003
  }
17708
20004
 
17709
- /* The mark is the tone's FILL step, which is measured at 3:1 as a mark. The
17710
- words beside it stay in the primary ink: a coloured sentence on a coloured
17711
- strip is the pair that has to be measured, and this one does not exist. */
20005
+ /*
20006
+ * A VARIANT IS ITS MARK AND ITS WASH. The words stay in the strip's own inks
20007
+ * and the edge stays the hairline, so a failure is a rose mark on a faint rose
20008
+ * wash rather than a red strip: the outcome is said by the glyph and the title,
20009
+ * and the sentence beside them is read in the ink every sentence is read in.
20010
+ * Information is the neutral mark on the neutral wash.
20011
+ */
17712
20012
  .crewlet-toast--success {
17713
- --crewlet-toast-mark: var(--color-feedback-success);
20013
+ --crewlet-toast-mark: var(--color-feedback-success-ink);
20014
+ --crewlet-toast-wash: var(--color-feedback-success-soft);
17714
20015
  }
17715
20016
 
17716
20017
  .crewlet-toast--warning {
17717
- --crewlet-toast-mark: var(--color-feedback-warning);
20018
+ --crewlet-toast-mark: var(--color-feedback-warning-ink);
20019
+ --crewlet-toast-wash: var(--color-feedback-warning-soft);
17718
20020
  }
17719
20021
 
17720
- /*
17721
- * A FAILURE IS THE ONE TONED STRIP. It is the outcome that is news rather than
17722
- * confirmation and the one that does not take itself away, so the engine gives
17723
- * it the hue twice: the fill step on the edge, where 3:1 is the floor a
17724
- * boundary has to clear, and the INK step on every word, which is the measured
17725
- * text pair on this surface. Never the fill behind a word: that is the swap
17726
- * the whole soft-and-ink split exists to stop.
17727
- */
17728
20022
  .crewlet-toast--danger {
17729
- --crewlet-toast-mark: var(--color-feedback-danger);
17730
- --crewlet-toast-line: var(--color-feedback-danger);
17731
- --crewlet-toast-ink: var(--color-feedback-danger-ink);
17732
- --crewlet-toast-ink-quiet: var(--color-feedback-danger-ink);
17733
- }
17734
-
17735
- .crewlet-toast--info {
17736
- --crewlet-toast-mark: var(--color-feedback-info);
20023
+ --crewlet-toast-mark: var(--color-feedback-danger-ink);
20024
+ --crewlet-toast-wash: var(--color-feedback-danger-soft);
17737
20025
  }
17738
20026
 
17739
20027
  /* A usage limit notice is the application's own variant: it paints the glyph
@@ -17755,12 +20043,12 @@ svg.crewlet-time-window__tick {
17755
20043
  }
17756
20044
 
17757
20045
  .crewlet-toast__message {
17758
- color: var(--crewlet-toast-ink-quiet);
20046
+ color: var(--color-text-secondary);
17759
20047
  overflow-wrap: anywhere;
17760
20048
  }
17761
20049
 
17762
20050
  .crewlet-toast__actions {
17763
- margin-top: var(--spacing-2);
20051
+ margin-top: calc(var(--spacing-2) + var(--spacing-1) / 2);
17764
20052
  display: flex;
17765
20053
  gap: var(--spacing-2);
17766
20054
  }
@@ -17792,10 +20080,12 @@ svg.crewlet-time-window__tick {
17792
20080
  border-color: var(--color-brand-accent-hover);
17793
20081
  }
17794
20082
 
20083
+ /* A failure's one filled thing is the way out of it. */
17795
20084
  .crewlet-toast--danger .crewlet-toast__action-btn,
17796
20085
  .crewlet-toast--danger .crewlet-toast__action-link {
17797
20086
  background: var(--color-feedback-danger);
17798
20087
  border-color: var(--color-feedback-danger);
20088
+ color: var(--color-text-on-danger);
17799
20089
  }
17800
20090
 
17801
20091
  .crewlet-toast--danger .crewlet-toast__action-btn:hover,
@@ -17812,8 +20102,9 @@ svg.crewlet-time-window__tick {
17812
20102
  }
17813
20103
 
17814
20104
  /* The dismiss sits absolute in the corner so a multi-line message flows
17815
- under it rather than around it. 24px square: the smallest target
17816
- WCAG 2.2 accepts. */
20105
+ under it rather than around it, and after the body in the document, so it
20106
+ is drawn over the words at the same raised step. 24px square: the smallest
20107
+ target WCAG 2.2 accepts. */
17817
20108
  .crewlet-toast__dismiss {
17818
20109
  position: absolute;
17819
20110
  top: var(--spacing-2);
@@ -17827,10 +20118,7 @@ svg.crewlet-time-window__tick {
17827
20118
  border: 0;
17828
20119
  border-radius: var(--radius-sm);
17829
20120
  background: transparent;
17830
- /* The strip's own quiet ink rather than the neutral tertiary step, so the
17831
- close on a failure is part of the failure rather than the one grey thing
17832
- inside it. */
17833
- color: var(--crewlet-toast-ink-quiet);
20121
+ color: var(--color-text-tertiary);
17834
20122
  cursor: pointer;
17835
20123
  transition:
17836
20124
  background var(--motion-duration-fast) var(--motion-easing-default),
@@ -17838,25 +20126,28 @@ svg.crewlet-time-window__tick {
17838
20126
  }
17839
20127
 
17840
20128
  .crewlet-toast__dismiss:hover {
17841
- background: var(--color-surface-hover);
17842
- color: var(--crewlet-toast-ink);
20129
+ background: var(--color-surface-elevated);
20130
+ color: var(--color-text-primary);
17843
20131
  }
17844
20132
 
20133
+ /*
20134
+ * THE COUNTDOWN IS A WASH BEHIND THE WORDS, the variant's soft step over the
20135
+ * whole strip, draining from the right as the time runs out. It sits under
20136
+ * every raised child, and it is the timer's picture, not the timer.
20137
+ */
17845
20138
  .crewlet-toast__progress {
17846
20139
  position: absolute;
17847
- left: 0;
17848
- right: 0;
17849
- bottom: 0;
17850
- height: 2px;
20140
+ inset: 0;
20141
+ z-index: var(--z-index-base);
17851
20142
  transform-origin: left center;
17852
- background: var(--crewlet-toast-mark);
20143
+ background: var(--crewlet-toast-wash);
17853
20144
  pointer-events: none;
17854
20145
  animation-name: crewlet-toast-drain;
17855
20146
  animation-timing-function: linear;
17856
20147
  animation-fill-mode: forwards;
17857
20148
  }
17858
20149
 
17859
- /* Paused by the class rather than by :hover, so the bar and the timer that
20150
+ /* Paused by the class rather than by :hover, so the wash and the timer that
17860
20151
  actually dismisses are stopped by the same event. */
17861
20152
  .crewlet-toast__progress.is-paused {
17862
20153
  animation-play-state: paused;
@@ -17866,7 +20157,6 @@ svg.crewlet-time-window__tick {
17866
20157
  from {
17867
20158
  transform: scaleX(1);
17868
20159
  }
17869
-
17870
20160
  to {
17871
20161
  transform: scaleX(0);
17872
20162
  }
@@ -17892,8 +20182,8 @@ svg.crewlet-time-window__tick {
17892
20182
 
17893
20183
  /*
17894
20184
  * The strip still arrives and still goes; it just does not slide, and the
17895
- * countdown bar holds still. The timer is untouched: a reader who asked for
17896
- * less motion did not ask to be left with a toast that never leaves.
20185
+ * wash is not drawn. The timer is untouched: a reader who asked for less
20186
+ * motion did not ask to be left with a toast that never leaves.
17897
20187
  */
17898
20188
  @media (prefers-reduced-motion: reduce) {
17899
20189
  .crewlet-toast {
@@ -19270,7 +21560,7 @@ svg.crewlet-time-window__tick {
19270
21560
  }
19271
21561
 
19272
21562
 
19273
- /* TreeGrid-NSW7VMOX.css */
21563
+ /* TreeGrid-FBX3MSJA.css */
19274
21564
  /*
19275
21565
  * A hierarchy as rows and columns (TreeGrid.tsx).
19276
21566
  *
@@ -19399,6 +21689,25 @@ svg.crewlet-time-window__tick {
19399
21689
  outline-offset: var(--size-focus-ring-inset-offset);
19400
21690
  }
19401
21691
 
21692
+ /*
21693
+ * A HEADLESS GRID keeps its header row for a screen reader and draws no band:
21694
+ * the row is taken out of the layout the way VisuallyHidden takes text out,
21695
+ * and the first row of the body loses the hairline that would otherwise sit
21696
+ * under the frame's own edge as a second line.
21697
+ */
21698
+ .crewlet-tree-grid--headless .crewlet-tree-grid__head {
21699
+ position: absolute;
21700
+ width: 1px;
21701
+ height: 1px;
21702
+ overflow: hidden;
21703
+ clip-path: inset(50%);
21704
+ white-space: nowrap;
21705
+ }
21706
+
21707
+ .crewlet-tree-grid--headless .crewlet-tree-grid__head + [role='rowgroup'] > .crewlet-tree-grid__row:first-child {
21708
+ border-top: 0;
21709
+ }
21710
+
19402
21711
  /* The selection is where the reader is, so it takes the accent. */
19403
21712
  .crewlet-tree-grid__row[aria-selected='true'] {
19404
21713
  box-shadow: inset 2px 0 0 var(--color-brand-accent);