@crewlethq/ui 0.38.0 → 0.40.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 +79 -3
  2. package/dist/AgentHandoffPanel/index.js +3 -3
  3. package/dist/AppShell/AppShell.d.ts +13 -2
  4. package/dist/AppShell/index.js +1 -1
  5. package/dist/{AppShell-NDU4XMGF.css → AppShell-NPSWZ3XW.css} +45 -4
  6. package/dist/ArtifactBar/index.js +6 -5
  7. package/dist/{ArtifactBar-FWPBBKQ5.css → ArtifactBar-6PGWGKN2.css} +13 -1
  8. package/dist/ArtifactCard/index.js +2 -2
  9. package/dist/AuthLayout/index.js +2 -2
  10. package/dist/AvatarPicker/index.js +10 -6
  11. package/dist/Card/Card.d.ts +14 -2
  12. package/dist/Card/index.js +1 -1
  13. package/dist/{Card-G2ZGT5Z6.css → Card-JR2UPQH7.css} +20 -0
  14. package/dist/CatalogTile/CatalogTile.d.ts +47 -0
  15. package/dist/CatalogTile/index.d.ts +3 -0
  16. package/dist/CatalogTile/index.js +3 -0
  17. package/dist/CatalogTile-XL4XLFUH.css +135 -0
  18. package/dist/CharacterPicker/index.js +2 -2
  19. package/dist/Charts/Histogram.d.ts +71 -0
  20. package/dist/Charts/index.d.ts +2 -0
  21. package/dist/Charts/index.js +1 -1
  22. package/dist/{Charts-MBJG72BS.css → Charts-TZ744HT6.css} +118 -0
  23. package/dist/CodeBlock/index.js +1 -1
  24. package/dist/{CodeBlock-GYNJ2HI6.css → CodeBlock-N5ETJF24.css} +13 -0
  25. package/dist/CommandPalette/index.js +3 -3
  26. package/dist/CommentThread/index.js +3 -3
  27. package/dist/Composer/index.js +2 -2
  28. package/dist/DataGrid/DataGrid.d.ts +267 -0
  29. package/dist/DataGrid/index.d.ts +3 -0
  30. package/dist/DataGrid/index.js +7 -0
  31. package/dist/DataGrid-AQKPJD7W.css +482 -0
  32. package/dist/DataTable/index.js +2 -2
  33. package/dist/DataView/index.js +4 -4
  34. package/dist/DatasetSource/DatasetSource.d.ts +7 -1
  35. package/dist/DatasetSource/index.js +1 -1
  36. package/dist/HuePicker/index.js +11 -4
  37. package/dist/LayersList/index.js +2 -2
  38. package/dist/LinkInterstitial/index.js +2 -2
  39. package/dist/List/List.d.ts +8 -0
  40. package/dist/List/index.js +1 -1
  41. package/dist/{List-MYJIV6MP.css → List-YHLIZFK4.css} +46 -0
  42. package/dist/ListInput/ListInput.d.ts +9 -1
  43. package/dist/ListInput/index.js +2 -2
  44. package/dist/LockedLabel/LockedLabel.d.ts +34 -0
  45. package/dist/LockedLabel/index.d.ts +3 -0
  46. package/dist/LockedLabel/index.js +3 -0
  47. package/dist/LockedLabel-VQEGEB7G.css +16 -0
  48. package/dist/MarkdownEditor/index.js +8 -5
  49. package/dist/MergeConflicts/index.js +11 -5
  50. package/dist/Modal/index.js +1 -1
  51. package/dist/{Modal-7MWRCWAI.css → Modal-TOEWHDCQ.css} +5 -0
  52. package/dist/ObjectHeader/index.js +1 -1
  53. package/dist/{ObjectHeader-D7GU7QNI.css → ObjectHeader-ZOS22FKX.css} +7 -8
  54. package/dist/PageNote/PageNote.d.ts +14 -0
  55. package/dist/PageNote/index.d.ts +3 -0
  56. package/dist/PageNote/index.js +2 -0
  57. package/dist/PageNote-RHLXH3ML.css +12 -0
  58. package/dist/PropertyList/PropertyList.d.ts +88 -0
  59. package/dist/PropertyList/index.d.ts +3 -0
  60. package/dist/PropertyList/index.js +7 -0
  61. package/dist/PropertyList-SCYM66LL.css +96 -0
  62. package/dist/RelatedRow/RelatedRow.d.ts +27 -0
  63. package/dist/RelatedRow/index.d.ts +3 -0
  64. package/dist/RelatedRow/index.js +9 -0
  65. package/dist/RelatedRow-2FVS6QQA.css +6 -0
  66. package/dist/RichEditor/index.js +1 -1
  67. package/dist/SectionFrame/SectionFrame.d.ts +76 -0
  68. package/dist/SectionFrame/index.d.ts +3 -0
  69. package/dist/SectionFrame/index.js +7 -0
  70. package/dist/SectionFrame-M62UUVFQ.css +164 -0
  71. package/dist/SegmentedControl/index.js +11 -4
  72. package/dist/SettingsTable/SettingsTable.d.ts +66 -0
  73. package/dist/SettingsTable/index.d.ts +3 -0
  74. package/dist/SettingsTable/index.js +3 -0
  75. package/dist/SettingsTable-6DUFAFXG.css +160 -0
  76. package/dist/ShareDialog/index.js +2 -2
  77. package/dist/SheetColumnEditor/index.js +7 -6
  78. package/dist/SheetGrid/index.js +3 -3
  79. package/dist/SidebarNav/SidebarNav.d.ts +35 -2
  80. package/dist/SidebarNav/index.js +2 -1
  81. package/dist/{SidebarNav-7SGUZYKK.css → SidebarNav-YI74SPDC.css} +10 -0
  82. package/dist/StatCard/index.js +1 -1
  83. package/dist/{StatCard-4T7TMWMN.css → StatCard-HAA3F5GX.css} +8 -3
  84. package/dist/StatGroup/index.js +1 -1
  85. package/dist/{StatGroup-DOFHX5QJ.css → StatGroup-ZMW7VQWP.css} +27 -0
  86. package/dist/Switcher/index.js +2 -2
  87. package/dist/Tabs/Tabs.d.ts +55 -1
  88. package/dist/Tabs/fold.d.ts +54 -0
  89. package/dist/Tabs/index.d.ts +1 -1
  90. package/dist/Tabs/index.js +9 -2
  91. package/dist/Tabs/roving.d.ts +3 -3
  92. package/dist/{Tabs-WIF7457H.css → Tabs-S7F4RWAN.css} +77 -0
  93. package/dist/TagsInput/index.js +1 -1
  94. package/dist/ThemeGallery/index.js +2 -2
  95. package/dist/ThemeSwitcher/index.js +12 -5
  96. package/dist/TileGrid/TileGrid.d.ts +33 -0
  97. package/dist/TileGrid/index.d.ts +3 -0
  98. package/dist/TileGrid/index.js +2 -0
  99. package/dist/TileGrid-I6LNYD2H.css +52 -0
  100. package/dist/VersionCompare/index.js +12 -5
  101. package/dist/{chunk-B5J23C73.js → chunk-2PEXZ7L4.js} +1 -1
  102. package/dist/{chunk-S27UBCVX.js → chunk-2VOHUGUA.js} +2 -2
  103. package/dist/{chunk-XBURIXHO.js → chunk-3TXY3PJZ.js} +1 -1
  104. package/dist/{chunk-2QZ2VPHR.js → chunk-4OK4DX3V.js} +2 -2
  105. package/dist/chunk-4RKTZSEW.js +64 -0
  106. package/dist/{chunk-ECGGQX2H.js → chunk-A44YHLCQ.js} +2 -2
  107. package/dist/{chunk-F4LPQA4E.js → chunk-BA32AVKS.js} +1 -1
  108. package/dist/chunk-CV4NES3P.js +9 -0
  109. package/dist/{chunk-PPHTIKZO.js → chunk-E4BOVKNJ.js} +1 -1
  110. package/dist/{chunk-W7PAIVAP.js → chunk-E7QLG3PG.js} +30 -9
  111. package/dist/{chunk-RKKO7QHH.js → chunk-EGMQURBR.js} +5 -4
  112. package/dist/{chunk-GMW4ZHST.js → chunk-EX22Q5SH.js} +2 -2
  113. package/dist/{chunk-A23KDROH.js → chunk-FXBGEANQ.js} +1 -1
  114. package/dist/{chunk-4L2BWSHR.js → chunk-GFYQKMQZ.js} +2 -2
  115. package/dist/{chunk-HG5VF3TZ.js → chunk-HMVQQEHW.js} +91 -2
  116. package/dist/{chunk-IPWU6ERC.js → chunk-HQJ24WPM.js} +4 -2
  117. package/dist/{chunk-SVGARBDY.js → chunk-IAGYPTEJ.js} +2 -2
  118. package/dist/{chunk-ZK3VYY7L.js → chunk-INHXF2CL.js} +24 -11
  119. package/dist/chunk-INVSUFJK.js +71 -0
  120. package/dist/{chunk-6NNY5WBF.js → chunk-JKAGN4V4.js} +1 -1
  121. package/dist/{chunk-4LRAJXHL.js → chunk-JSWOXRRE.js} +1 -1
  122. package/dist/{chunk-DYB66CNM.js → chunk-KKNHMXTE.js} +6 -3
  123. package/dist/{chunk-UWRBD2YO.js → chunk-KNHUBHFX.js} +1 -1
  124. package/dist/{chunk-ZMDYQ2HH.js → chunk-KWWP3D7M.js} +1 -1
  125. package/dist/{chunk-46RL3E54.js → chunk-M6NQ4XGK.js} +1 -1
  126. package/dist/{chunk-PT6WKXKW.js → chunk-MMPKN7WV.js} +1 -1
  127. package/dist/{chunk-NRBAXRWE.js → chunk-N3TFYBN3.js} +1 -1
  128. package/dist/chunk-NNTO3TNC.js +9 -0
  129. package/dist/{chunk-DS2C73RJ.js → chunk-NZWX27J7.js} +2 -2
  130. package/dist/{chunk-VGE3G3T4.js → chunk-ODOJJGXH.js} +1 -1
  131. package/dist/chunk-OHGH7O6T.js +19 -0
  132. package/dist/{chunk-4ISUIS6F.js → chunk-OOC7Q67K.js} +1 -1
  133. package/dist/{chunk-BT5H2THK.js → chunk-OUD75UB2.js} +1 -1
  134. package/dist/chunk-PCT47E7O.js +48 -0
  135. package/dist/{chunk-X3UYTAOG.js → chunk-PFZOFAQ6.js} +1 -1
  136. package/dist/{chunk-YQG4PZGC.js → chunk-QRKT4XTT.js} +2 -2
  137. package/dist/{chunk-BJI3RFXG.js → chunk-S4DREXGM.js} +1 -1
  138. package/dist/{chunk-GDDE4UM7.js → chunk-SEC2GR2V.js} +1 -1
  139. package/dist/{chunk-YEVG2X5R.js → chunk-SNQRGH4A.js} +1 -1
  140. package/dist/chunk-T6MXORP5.js +116 -0
  141. package/dist/{chunk-OTCXRJ7D.js → chunk-U2XAJONO.js} +1 -1
  142. package/dist/{chunk-3ZUINC7C.js → chunk-WYYCPV46.js} +6 -1
  143. package/dist/chunk-X4IXXLWM.js +306 -0
  144. package/dist/{chunk-PAQXOP2M.js → chunk-XGBUUQDU.js} +2 -2
  145. package/dist/chunk-XIDD7PJO.js +416 -0
  146. package/dist/{chunk-XO7PUL4F.js → chunk-YPTTSJPM.js} +1 -1
  147. package/dist/chunk-ZUTUI27P.js +21 -0
  148. package/dist/generated/index.d.ts +9 -0
  149. package/dist/generated/index.js +83 -74
  150. package/dist/index.js +83 -74
  151. package/dist/styles.css +1627 -104
  152. package/package.json +3 -3
  153. package/dist/chunk-7SDUKCNW.js +0 -141
  154. package/dist/{Editor-QV4JP242.js → Editor-IRDQ3JDZ.js} +1 -1
  155. package/dist/{chunk-JZPK4IXR.js → chunk-3PR65I3H.js} +2 -2
  156. package/dist/{chunk-ETVEGR2Y.js → chunk-ISA2O2BK.js} +1 -1
  157. /package/dist/{chunk-4QQ3MND5.js → chunk-S3QTFUJX.js} +0 -0
package/dist/styles.css CHANGED
@@ -702,7 +702,7 @@
702
702
  }
703
703
 
704
704
 
705
- /* AppShell-NDU4XMGF.css */
705
+ /* AppShell-NPSWZ3XW.css */
706
706
  /*
707
707
  * The application frame: a rail on the FRAME, and the screen on a SHEET that
708
708
  * floats beside it.
@@ -835,6 +835,8 @@
835
835
  .crewlet-app-shell__rail-head {
836
836
  display: flex;
837
837
  align-items: center;
838
+ gap: var(--spacing-2);
839
+ min-width: 0;
838
840
  flex: none;
839
841
  box-sizing: border-box;
840
842
  min-height: calc(var(--size-shell-inset) + var(--crewlet-app-shell-topbar));
@@ -848,6 +850,31 @@
848
850
  scrollbar-color: var(--color-scrollbar) transparent;
849
851
  }
850
852
 
853
+ /*
854
+ * THE HEAD'S FIRST CHILD TAKES ITS WIDTH: a lockup alone on its line, whose
855
+ * name truncates at the rail's edge rather than wrapping or pushing the head
856
+ * wider. It was every application's own wrapper and rule.
857
+ */
858
+ .crewlet-app-shell__rail-head > :first-child {
859
+ flex: 1 1 auto;
860
+ min-width: 0;
861
+ }
862
+
863
+ /*
864
+ * THE RAIL'S FIELD ON THE NAV'S COLUMNS. It stands on the nav's gutter, so
865
+ * its right edge is where every row's background ends; and its glyph stands
866
+ * on the nav's glyph column: a row's glyph is the gutter and the row's pad
867
+ * in, the field's is the gutter, its own 1px edge and its pad
868
+ * (`SearchTrigger`'s two steps and a half), so the inset at its start makes
869
+ * up the difference from those measures.
870
+ */
871
+ .crewlet-app-shell__rail-search {
872
+ padding: 0 var(--size-nav-gutter) var(--spacing-3);
873
+ padding-inline-start: calc(
874
+ var(--size-nav-gutter) + var(--size-nav-row-pad) - (var(--spacing-2) + var(--spacing-1) / 2) - 1px
875
+ );
876
+ }
877
+
851
878
  /* The same gutter the nav takes, so what the foot says lines up with the rows
852
879
  above it rather than sitting further out. */
853
880
  .crewlet-app-shell__rail-foot {
@@ -1193,6 +1220,15 @@
1193
1220
  overflow-y: auto;
1194
1221
  overflow-x: hidden;
1195
1222
  scrollbar-gutter: stable;
1223
+ /*
1224
+ * A SIZE CONTAINER, so a box inside the screen can be as tall as the view
1225
+ * it scrolls in (`100cqb`): a column that sticks beside the screen
1226
+ * (`SectionFrame`), a record bounded by the window. The scroller's size is
1227
+ * the shell's, never its content's, so containing it costs nothing. A box
1228
+ * inside an inline-size container (a card, a stat row) reaches past it to
1229
+ * this one for the block axis.
1230
+ */
1231
+ container-type: size;
1196
1232
  }
1197
1233
 
1198
1234
  /* No focus rule of its own: `main` takes focus only from the skip link, and a
@@ -1210,12 +1246,17 @@
1210
1246
  }
1211
1247
 
1212
1248
  /* A screen that draws to the bottom of the window: the scroller stops
1213
- scrolling and the content column takes the height that is left. It
1214
- reserves no scrollbar gutter either, since nothing in it scrolls: the
1215
- reserved strip was a dead band down the screen's end edge. */
1249
+ scrolling and the content column takes the height that is left.
1250
+
1251
+ IT KEEPS THE GUTTER RESERVED, like every other screen. The top bar's end
1252
+ inset counts the scroller's gutter (`--crewlet-app-shell-gutter`, measured
1253
+ by the shell), so a fill screen that reserved none put the bar's controls
1254
+ one gutter further out than on the screen beside it: with classic
1255
+ scrollbars, Add seat moved 11px between an org chart and its roster, two
1256
+ tabs of one page. A strip at the end edge of a full-screen canvas is the
1257
+ smaller cost than a bar that moves under the pointer. */
1216
1258
  .crewlet-app-shell--fill .crewlet-app-shell__main {
1217
1259
  overflow: hidden;
1218
- scrollbar-gutter: auto;
1219
1260
  }
1220
1261
 
1221
1262
  .crewlet-app-shell--fill .crewlet-app-shell__content {
@@ -2291,7 +2332,7 @@ button.crewlet-account-row__who:focus-visible {
2291
2332
  }
2292
2333
 
2293
2334
 
2294
- /* ArtifactBar-FWPBBKQ5.css */
2335
+ /* ArtifactBar-6PGWGKN2.css */
2295
2336
  /*
2296
2337
  * One row, one hairline under it, the height of a large row. The lead (the
2297
2338
  * way back, the glyph, the title, the version) takes what the end leaves it
@@ -2323,7 +2364,12 @@ button.crewlet-account-row__who:focus-visible {
2323
2364
  its place, and at a row's height of its own the line under it jumped by
2324
2365
  three pixels between the gallery and the artifact opened from it. */
2325
2366
  height: calc(var(--size-shell-topbar) - 1px);
2326
- padding: 0 var(--spacing-3);
2367
+ /* THE SHELL TOP BAR'S INSET, the scroller's gutter at its end included: the
2368
+ bar stands in that bar's place, and at a 12px inset of its own a create
2369
+ page's controls ended 19px past the content under them, where every other
2370
+ page's end over it. The same two steps as the top bar, 20px wide and 16px
2371
+ under the shell's breakpoint (below). */
2372
+ padding: 0 calc(var(--spacing-5) + var(--crewlet-app-shell-gutter, 0px)) 0 var(--spacing-5);
2327
2373
  min-width: 0;
2328
2374
  }
2329
2375
 
@@ -2708,6 +2754,13 @@ button.crewlet-account-row__who:focus-visible {
2708
2754
  }
2709
2755
  }
2710
2756
 
2757
+ /* The shell's breakpoint, where its top bar and content take 16px. */
2758
+ @media (width < 1024px) {
2759
+ .crewlet-artifact-bar__row {
2760
+ padding: 0 calc(var(--spacing-4) + var(--crewlet-app-shell-gutter, 0px)) 0 var(--spacing-4);
2761
+ }
2762
+ }
2763
+
2711
2764
 
2712
2765
  /* ArtifactCard-OGTMO2KI.css */
2713
2766
  /*
@@ -6266,7 +6319,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
6266
6319
  }
6267
6320
 
6268
6321
 
6269
- /* Card-G2ZGT5Z6.css */
6322
+ /* Card-JR2UPQH7.css */
6270
6323
  /*
6271
6324
  * Card, THE surface. Everything on a screen is a card, a row inside one, or a
6272
6325
  * control.
@@ -6764,6 +6817,26 @@ a.crewlet-breadcrumb__crumb:focus-visible {
6764
6817
  }
6765
6818
  }
6766
6819
 
6820
+ /*
6821
+ * STACKED, ASKED FOR: the subtitle under the title at every width, the shape
6822
+ * the narrow step above draws, for a row of cards of different widths whose
6823
+ * heads have to stand at one height rather than one inline and one stacked.
6824
+ */
6825
+ .crewlet-card__header--stacked {
6826
+ flex-wrap: wrap;
6827
+ row-gap: var(--spacing-1);
6828
+ }
6829
+
6830
+ .crewlet-card__header--stacked > .crewlet-card__header-main {
6831
+ flex: 1 1 0;
6832
+ }
6833
+
6834
+ .crewlet-card__header--stacked > .crewlet-card__subtitle {
6835
+ order: 1;
6836
+ flex: 1 1 100%;
6837
+ white-space: normal;
6838
+ }
6839
+
6767
6840
  .crewlet-card__description {
6768
6841
  margin: 0;
6769
6842
  font-size: var(--font-size-compact);
@@ -6778,6 +6851,144 @@ a.crewlet-breadcrumb__crumb:focus-visible {
6778
6851
  }
6779
6852
 
6780
6853
 
6854
+ /* CatalogTile-XL4XLFUH.css */
6855
+ /*
6856
+ * CatalogTile: mark, name and state, one sentence, and a foot with a quiet
6857
+ * fact and one action.
6858
+ *
6859
+ * ONE WELL FOR EVERY MARK. A vendor's mark is drawn in the vendor's colours,
6860
+ * so the box it stands in is the one thing a catalogue can hold constant: the
6861
+ * same size, the same raised ground and the same hairline for every tile,
6862
+ * set up or not. A drained mark on a grey box read as a placeholder image
6863
+ * (a white plate on grey is not a logo), so a tile not yet set up says so by
6864
+ * its ground, never by its mark.
6865
+ */
6866
+
6867
+ .crewlet-catalog-tile {
6868
+ display: flex;
6869
+ flex-direction: column;
6870
+ gap: var(--spacing-3);
6871
+ min-width: 0;
6872
+ padding: var(--spacing-4);
6873
+ background: var(--color-surface-subtle);
6874
+ border: 1px solid var(--color-border-default);
6875
+ border-radius: var(--radius-lg);
6876
+ color: var(--color-text-primary);
6877
+ }
6878
+
6879
+ .crewlet-catalog-tile--quiet {
6880
+ background: var(--color-surface-background);
6881
+ }
6882
+
6883
+ .crewlet-catalog-tile__head {
6884
+ display: flex;
6885
+ align-items: flex-start;
6886
+ gap: var(--spacing-3);
6887
+ min-width: 0;
6888
+ }
6889
+
6890
+ .crewlet-catalog-tile__mark {
6891
+ display: inline-flex;
6892
+ flex: none;
6893
+ align-items: center;
6894
+ justify-content: center;
6895
+ width: var(--size-row-lg);
6896
+ height: var(--size-row-lg);
6897
+ border-radius: var(--radius-md);
6898
+ background: var(--color-surface-elevated);
6899
+ border: 1px solid var(--color-border-default);
6900
+ color: var(--color-text-primary);
6901
+ }
6902
+
6903
+ /* The name, and under it the state when there is one. THE NAME STANDS ON ONE
6904
+ LINE ACROSS A ROW whether or not a tile has a state: centred on the mark, a
6905
+ name with a pill under it rose 13px above its stateless neighbour's, so the
6906
+ names of one row stood at two heights. It starts one step below the mark's
6907
+ top edge in every tile instead. */
6908
+ .crewlet-catalog-tile__title {
6909
+ display: flex;
6910
+ flex-direction: column;
6911
+ align-items: flex-start;
6912
+ justify-content: flex-start;
6913
+ padding-top: var(--spacing-1);
6914
+ gap: var(--spacing-1);
6915
+ min-width: 0;
6916
+ }
6917
+
6918
+ .crewlet-catalog-tile__name {
6919
+ margin: 0;
6920
+ font-family: var(--font-family-sans);
6921
+ font-size: var(--font-size-sm);
6922
+ font-weight: var(--font-weight-semibold);
6923
+ line-height: var(--font-line-height-snug);
6924
+ color: var(--color-text-primary);
6925
+ overflow-wrap: anywhere;
6926
+ }
6927
+
6928
+ .crewlet-catalog-tile__status {
6929
+ display: inline-flex;
6930
+ }
6931
+
6932
+ .crewlet-catalog-tile__description {
6933
+ flex: 1;
6934
+ margin: 0;
6935
+ /* Two lines reserved, so a tile saying what it is for and one saying what
6936
+ is owed keep their feet on one line in a row. */
6937
+ min-height: calc(2em * var(--font-line-height-body));
6938
+ font-size: var(--font-size-compact);
6939
+ line-height: var(--font-line-height-body);
6940
+ color: var(--color-text-secondary);
6941
+ }
6942
+
6943
+ .crewlet-catalog-tile__foot {
6944
+ display: flex;
6945
+ align-items: center;
6946
+ gap: var(--spacing-2);
6947
+ /* A SMALL CONTROL'S HEIGHT OF CONTENT, under the rule and the padding: a
6948
+ foot holding only a fact stands as tall as one holding a button, so the
6949
+ rules of every foot in a row sit on one line. Measured on the content
6950
+ box, since under border-box sizing the padding spent the floor and a
6951
+ fact-only foot stood 8px shorter. */
6952
+ box-sizing: content-box;
6953
+ min-height: var(--size-control-sm);
6954
+ padding-top: var(--spacing-3);
6955
+ border-top: 1px solid var(--color-border-default);
6956
+ }
6957
+
6958
+ .crewlet-catalog-tile__meta {
6959
+ flex: 1;
6960
+ min-width: 0;
6961
+ overflow: hidden;
6962
+ text-overflow: ellipsis;
6963
+ white-space: nowrap;
6964
+ font-size: var(--font-size-xs);
6965
+ color: var(--color-text-tertiary);
6966
+ }
6967
+
6968
+ .crewlet-catalog-tile__action {
6969
+ display: inline-flex;
6970
+ flex: none;
6971
+ }
6972
+
6973
+ /*
6974
+ * ONE TILE A ROW RESERVES NOTHING. The two reserved lines exist to keep the
6975
+ * feet of tiles side by side on one line; a grid folded to one track has no
6976
+ * neighbours to line up with, and on a phone the reserve was a blank line in
6977
+ * every short tile.
6978
+ */
6979
+ @container crewlet-tile-grid (width < 40rem) {
6980
+ .crewlet-tile-grid[data-columns='3'] .crewlet-catalog-tile__description {
6981
+ min-height: 0;
6982
+ }
6983
+ }
6984
+
6985
+ @container crewlet-tile-grid (width < 28rem) {
6986
+ .crewlet-tile-grid .crewlet-catalog-tile__description {
6987
+ min-height: 0;
6988
+ }
6989
+ }
6990
+
6991
+
6781
6992
  /* ChangeMark-3VMTW7MT.css */
6782
6993
  /*
6783
6994
  * A change mark (ChangeMark.tsx): a notch in the top end corner of whatever
@@ -6848,7 +7059,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
6848
7059
  }
6849
7060
 
6850
7061
 
6851
- /* Charts-MBJG72BS.css */
7062
+ /* Charts-TZ744HT6.css */
6852
7063
  /* The chart kit: a legend, a ranked bar list, a stacked bar, stacked
6853
7064
  columns, an activity strip, a time series and the reading layer they share. Hand-drawn rather than a charting library, for one reason that
6854
7065
  decides it: every mark here reads tokens, in two themes, at the contrast
@@ -7830,6 +8041,124 @@ a.crewlet-breadcrumb__crumb:focus-visible {
7830
8041
  pointer-events: none;
7831
8042
  }
7832
8043
 
8044
+ /* ─── Histogram, a log's own time axis ─────────────────────────── */
8045
+
8046
+ /*
8047
+ * Time runs left to right on this axis in every writing direction, as it does
8048
+ * on every chart, and the ticks are placed on physical sides to match.
8049
+ */
8050
+ .crewlet-histogram {
8051
+ display: flex;
8052
+ flex-direction: column;
8053
+ min-width: 0;
8054
+ direction: ltr;
8055
+ }
8056
+
8057
+ /* The plot's bottom border is the axis line the ticks hang under. */
8058
+ .crewlet-histogram__plot {
8059
+ display: flex;
8060
+ align-items: flex-end;
8061
+ gap: 1px;
8062
+ width: 100%;
8063
+ height: var(--crewlet-histogram-height, 96px);
8064
+ padding: var(--spacing-1) 0;
8065
+ border-bottom: 1px solid var(--color-border-hover);
8066
+ }
8067
+
8068
+ /* The slot is the control, and the whole of it is the target. */
8069
+ .crewlet-histogram__bar {
8070
+ all: unset;
8071
+ flex: 1 1 0;
8072
+ min-width: 2px;
8073
+ height: 100%;
8074
+ display: flex;
8075
+ align-items: flex-end;
8076
+ justify-content: center;
8077
+ }
8078
+
8079
+ button.crewlet-histogram__bar {
8080
+ cursor: pointer;
8081
+ }
8082
+
8083
+ /* A slot draws no edge, so its ring stands off it. `all: unset` takes the
8084
+ baseline ring away; this states it again at a weight the reset cannot
8085
+ out-rank. */
8086
+ .crewlet-histogram__bar:focus-visible {
8087
+ outline: 2px solid var(--color-focus);
8088
+ outline-offset: 2px;
8089
+ }
8090
+
8091
+ /*
8092
+ * A count is data, so it is drawn in the data ramp; the accent is kept for the
8093
+ * bar the reader is pointing at, the selection a click is about to make. The
8094
+ * fill stacks from its foot, so the failed share sits at its bottom. Floors in
8095
+ * pixels: an empty bucket at two, the smallest real count at three.
8096
+ */
8097
+ .crewlet-histogram__fill {
8098
+ display: flex;
8099
+ flex-direction: column;
8100
+ justify-content: flex-end;
8101
+ overflow: hidden;
8102
+ width: 63%;
8103
+ min-width: 2px;
8104
+ max-width: var(--spacing-7);
8105
+ height: var(--crewlet-histogram-fill, 0%);
8106
+ min-height: 3px;
8107
+ background: var(--color-data-1);
8108
+ border-radius: var(--radius-sm) var(--radius-sm) 0 0;
8109
+ transition: background var(--motion-duration-fast) var(--motion-easing-default);
8110
+ }
8111
+
8112
+ .crewlet-histogram__part {
8113
+ display: block;
8114
+ width: 100%;
8115
+ height: var(--crewlet-histogram-part, 0%);
8116
+ background: var(--color-feedback-danger);
8117
+ }
8118
+
8119
+ button.crewlet-histogram__bar:hover > .crewlet-histogram__fill,
8120
+ button.crewlet-histogram__bar:focus-visible > .crewlet-histogram__fill {
8121
+ background: var(--color-brand-accent);
8122
+ }
8123
+
8124
+ /* An empty bucket is a visible floor in the tone an axis is ruled in:
8125
+ present, and plainly not a quantity. */
8126
+ .crewlet-histogram__bar[data-empty] > .crewlet-histogram__fill {
8127
+ min-height: 2px;
8128
+ background: var(--color-border-strong);
8129
+ }
8130
+
8131
+ button.crewlet-histogram__bar[data-empty]:hover > .crewlet-histogram__fill,
8132
+ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fill {
8133
+ background: var(--color-border-strong-hover);
8134
+ }
8135
+
8136
+ /*
8137
+ * The dates under the bars. Absolutely placed, so a tick sits over the bucket
8138
+ * it names; the row states its own height because absolutely placed children
8139
+ * contribute none.
8140
+ */
8141
+ .crewlet-histogram__axis {
8142
+ position: relative;
8143
+ height: calc(var(--font-size-2xs) * var(--font-line-height-normal));
8144
+ margin-top: 2px;
8145
+ }
8146
+
8147
+ .crewlet-histogram__tick {
8148
+ position: absolute;
8149
+ top: 0;
8150
+ font-size: var(--font-size-2xs);
8151
+ color: var(--color-text-tertiary);
8152
+ font-variant-numeric: tabular-nums;
8153
+ white-space: nowrap;
8154
+ }
8155
+
8156
+ @media (prefers-reduced-motion: reduce) {
8157
+ .crewlet-histogram__fill {
8158
+ transition: none;
8159
+ }
8160
+ }
8161
+
7833
8162
 
7834
8163
  /* Checkbox-ALWG3WV2.css */
7835
8164
  /*
@@ -8340,7 +8669,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
8340
8669
  }
8341
8670
 
8342
8671
 
8343
- /* CodeBlock-GYNJ2HI6.css */
8672
+ /* CodeBlock-N5ETJF24.css */
8344
8673
  /*
8345
8674
  * CodeBlock, a monospace command, config or record surface. One step off the
8346
8675
  * page, with an optional header carrying a filename and the copy control.
@@ -8359,6 +8688,19 @@ a.crewlet-breadcrumb__crumb:focus-visible {
8359
8688
  min-width: 0;
8360
8689
  }
8361
8690
 
8691
+ /*
8692
+ * A BLOCK THAT IS A CARD'S CONTENT IS THAT CARD'S SURFACE. Placed straight in
8693
+ * a card (with `padding="none"`), it gives up its own edge, corner and ground,
8694
+ * so the card's head rule is the only line over the code and there is no box
8695
+ * inside a box. In a padded body it stays a well, which is what tells code
8696
+ * from the prose beside it.
8697
+ */
8698
+ .crewlet-card > .crewlet-codeblock {
8699
+ border: 0;
8700
+ border-radius: var(--radius-none);
8701
+ background: transparent;
8702
+ }
8703
+
8362
8704
  .crewlet-codeblock__header {
8363
8705
  display: flex;
8364
8706
  align-items: center;
@@ -9614,51 +9956,536 @@ a.crewlet-breadcrumb__crumb:focus-visible {
9614
9956
  }
9615
9957
 
9616
9958
 
9617
- /* DataTable-NL2YWAIA.css */
9618
- /* ─────────────────────────────────────────────────────────────────
9619
- * Default variant.
9959
+ /* DataGrid-AQKPJD7W.css */
9960
+ /*
9961
+ * DataGrid: a list as columns, one track list on the grid.
9620
9962
  *
9621
- * Every rule is scoped under the variant root, so the table's
9622
- * internals never match an application's own class names and the
9623
- * compact variant's rules further down never leak into this one.
9624
- * ───────────────────────────────────────────────────────────────── */
9625
- .crewlet-data-table--default {
9626
- /*
9627
- * The two knobs the compact root declares, so a host that rebinds either one
9628
- * reaches both variants. The hover is the OVERLAY step rather than an opaque
9629
- * surface: a table sits on the page, on a card and inside a dialog, and only
9630
- * an overlay composites correctly onto all three.
9631
- */
9632
- --crewlet-data-table-row-hover-bg: var(--color-surface-hover);
9633
- --crewlet-data-table-active-sort-color: var(--color-brand-accent-ink);
9634
- width: 100%;
9635
- position: relative;
9636
- /* NO SCROLLER HERE. This carried `overflow-x: auto` and its own
9637
- `overscroll-behavior-x`, and neither could act: `.crewlet-data-table__scroll`
9638
- is rendered inside it for BOTH variants at `width: 100%`, so it absorbs
9639
- the table's width and the root never has anything to scroll. What the
9640
- declaration did still do is make this a scroll container — and per CSS
9641
- Overflow that pulls `overflow-y` to `auto` as well — so it quietly became
9642
- the scrollport a `position: sticky` descendant resolves against. The inner
9643
- wrapper carries the real scrolling and the gesture containment, which is
9644
- what the layout comment further down already describes. */
9645
- }
9963
+ * THE GRID MAKES NO SCROLLPORT OF ITS OWN. `overflow: clip` rounds the rows off
9964
+ * at the corner exactly as `hidden` would, and it is the difference between a
9965
+ * sticky head that works and one that cannot: `hidden` makes a scroll
9966
+ * container, a sticky box is confined to its nearest scrollport, and this one
9967
+ * grows to its rows, so its offset is always 0. The head sticks against the
9968
+ * page's own scroller; an application whose scroller carries a sticky bar of
9969
+ * its own sets `--crewlet-data-grid-sticky-top` to that bar's height.
9970
+ *
9971
+ * THE COLUMNS BELONG TO THE GRID, NOT TO A ROW. The tracks are declared once,
9972
+ * on the grid (its inline `grid-template-columns`), and the head, the body,
9973
+ * the bands and the rows are `subgrid` passthroughs, so a head cell and a cell
9974
+ * twenty rows down size the same track. Everything that is not a row of cells
9975
+ * spans the whole width.
9976
+ */
9646
9977
 
9647
- .crewlet-data-table--default .crewlet-data-table__table {
9648
- width: 100%;
9649
- border-collapse: collapse;
9650
- background: transparent;
9651
- display: table;
9652
- table-layout: auto;
9653
- /* The table register: a cell is scanned down a column rather than read as a
9654
- sentence, and the compact step is where a row of them still lines up with
9655
- the row token the cells are sized to. */
9656
- font-size: var(--font-size-compact);
9978
+ .crewlet-data-grid {
9979
+ display: grid;
9980
+ min-width: 0;
9981
+ border: 1px solid var(--color-border-hover);
9982
+ border-radius: var(--radius-md);
9983
+ overflow: clip;
9984
+ background: var(--color-surface-subtle);
9657
9985
  }
9658
9986
 
9659
9987
  /*
9660
- * THE RULE UNDER THE HEADER IS THE HEADER'S. It used to sit on `thead`, which
9661
- * a sticky header carries nowhere: the group does not stick, its cells do, so
9988
+ * A CARD'S BODY (`flush`, and every grid straight in a Card or its body, told
9989
+ * or not): the card is the frame, so the grid draws none of its own and one
9990
+ * rule parts it from the card's head. Under the card's header, the header's
9991
+ * own rule is that one.
9992
+ */
9993
+ .crewlet-data-grid[data-flush],
9994
+ .crewlet-card > .crewlet-data-grid,
9995
+ .crewlet-card__body > .crewlet-data-grid {
9996
+ border: 0;
9997
+ border-top: 1px solid var(--color-border-default);
9998
+ border-radius: var(--radius-none);
9999
+ background: transparent;
10000
+ }
10001
+
10002
+ .crewlet-card__header + .crewlet-data-grid {
10003
+ border-top: 0;
10004
+ }
10005
+
10006
+ /* A full-width band by default: the head, the body, the foot, the reset and
10007
+ the empty state, which is the one child when the grid carries no tracks. */
10008
+ .crewlet-data-grid > * {
10009
+ grid-column: 1 / -1;
10010
+ }
10011
+
10012
+ .crewlet-data-grid__head,
10013
+ .crewlet-data-grid__body,
10014
+ .crewlet-data-grid__band,
10015
+ .crewlet-data-grid__row {
10016
+ display: grid;
10017
+ grid-template-columns: subgrid;
10018
+ grid-column: 1 / -1;
10019
+ }
10020
+
10021
+ .crewlet-data-grid__band-head,
10022
+ .crewlet-data-grid__band-foot {
10023
+ grid-column: 1 / -1;
10024
+ }
10025
+
10026
+ /*
10027
+ * The head: a floor at the row height (density shrinks the padding, not the
10028
+ * label), on the raised ground, sticky at the application's offset.
10029
+ */
10030
+ .crewlet-data-grid__head {
10031
+ align-items: center;
10032
+ min-height: var(--size-row-md);
10033
+ border-bottom: 1px solid var(--color-border-hover);
10034
+ background: var(--color-surface-elevated);
10035
+ position: sticky;
10036
+ top: var(--crewlet-data-grid-sticky-top, var(--spacing-0));
10037
+ z-index: var(--z-index-sticky);
10038
+ }
10039
+
10040
+ /*
10041
+ * THE LIST TABLE'S HEAD: the micro-label register every table takes, 11/500
10042
+ * uppercase. A sortable head is a button with its chrome reset; the reset
10043
+ * takes the focus ring with it, so the ring is restated below.
10044
+ */
10045
+ .crewlet-data-grid__th {
10046
+ display: flex;
10047
+ align-items: center;
10048
+ gap: var(--spacing-1);
10049
+ padding: var(--spacing-2) var(--spacing-3);
10050
+ font-size: var(--font-size-2xs);
10051
+ font-weight: var(--font-weight-medium);
10052
+ text-transform: uppercase;
10053
+ letter-spacing: var(--font-letter-spacing-wide);
10054
+ color: var(--color-text-tertiary);
10055
+ cursor: pointer;
10056
+ min-width: 0;
10057
+ transition: color var(--motion-duration-fast) var(--motion-easing-default);
10058
+ }
10059
+
10060
+ .crewlet-data-grid__th--plain {
10061
+ cursor: default;
10062
+ }
10063
+
10064
+ /* A sortable head's control fills the head: the whole cell is the target. */
10065
+ .crewlet-data-grid__sort {
10066
+ all: unset;
10067
+ display: flex;
10068
+ align-items: center;
10069
+ gap: var(--spacing-1);
10070
+ flex: 1 1 auto;
10071
+ min-width: 0;
10072
+ margin: calc(-1 * var(--spacing-2)) calc(-1 * var(--spacing-3));
10073
+ padding: var(--spacing-2) var(--spacing-3);
10074
+ cursor: pointer;
10075
+ }
10076
+
10077
+ .crewlet-data-grid__th--right .crewlet-data-grid__sort {
10078
+ justify-content: flex-end;
10079
+ }
10080
+
10081
+ .crewlet-data-grid__th:not(.crewlet-data-grid__th--plain):hover,
10082
+ .crewlet-data-grid__th--sorted {
10083
+ color: var(--color-text-primary);
10084
+ }
10085
+
10086
+ .crewlet-data-grid__th--right {
10087
+ justify-content: flex-end;
10088
+ }
10089
+
10090
+ .crewlet-data-grid__sort:focus-visible,
10091
+ .crewlet-data-grid__cols-reset:focus-visible {
10092
+ outline: 2px solid var(--color-focus);
10093
+ outline-offset: var(--size-focus-ring-inset-offset);
10094
+ }
10095
+
10096
+ .crewlet-data-grid__body {
10097
+ min-width: 0;
10098
+ }
10099
+
10100
+ .crewlet-data-grid__row {
10101
+ align-items: center;
10102
+ min-height: var(--size-row-md);
10103
+ border-bottom: 1px solid var(--color-border-default);
10104
+ color: inherit;
10105
+ cursor: pointer;
10106
+ /* The containing block for the row's link. */
10107
+ position: relative;
10108
+ transition: background var(--motion-duration-fast) var(--motion-easing-default);
10109
+ }
10110
+
10111
+ /* THE ROW'S OWN LINK, STRETCHED OVER IT, out of flow so it takes no track. */
10112
+ .crewlet-data-grid__row-link {
10113
+ position: absolute;
10114
+ inset: 0;
10115
+ }
10116
+
10117
+ /* A button overlay (a row that acts and has no address) gives up the chrome a
10118
+ button brings, and draws the focus ring inside the row. */
10119
+ button.crewlet-data-grid__row-link {
10120
+ all: unset;
10121
+ position: absolute;
10122
+ inset: 0;
10123
+ cursor: pointer;
10124
+ }
10125
+
10126
+ .crewlet-data-grid__row-link:focus-visible {
10127
+ outline: 2px solid var(--color-focus);
10128
+ outline-offset: var(--size-focus-ring-inset-offset);
10129
+ }
10130
+
10131
+ /*
10132
+ * AND THE CELLS' OWN CONTROLS SIT ABOVE IT: positioned and later in the
10133
+ * document than the overlay, they win the hit test in the same stacking
10134
+ * context, with no z-index to reason about against the sticky head. A cell's
10135
+ * element that is not a link or a button but must take its own clicks (a
10136
+ * refusal sentence a reader selects) carries `data-above-row`.
10137
+ */
10138
+ .crewlet-data-grid__row a:not(.crewlet-data-grid__row-link),
10139
+ .crewlet-data-grid__row button:not(.crewlet-data-grid__row-link),
10140
+ .crewlet-data-grid__row [data-above-row] {
10141
+ position: relative;
10142
+ }
10143
+
10144
+ .crewlet-data-grid__row:last-child {
10145
+ border-bottom: none;
10146
+ }
10147
+
10148
+ .crewlet-data-grid__row:hover {
10149
+ background: var(--color-surface-hover);
10150
+ }
10151
+
10152
+ .crewlet-data-grid__row--selected,
10153
+ .crewlet-data-grid__row--selected:hover {
10154
+ background: var(--color-brand-accent-soft);
10155
+ }
10156
+
10157
+ .crewlet-data-grid__row--cursor {
10158
+ box-shadow: inset 2px 0 0 var(--color-brand-accent);
10159
+ }
10160
+
10161
+ /* A FAILED ROW IS MARKED ON ITS EDGE, not tinted: the status column already
10162
+ says so, and two signals for one fact teach a reader to trust neither. */
10163
+ .crewlet-data-grid__row--failed {
10164
+ box-shadow: inset 2px 0 0 var(--color-feedback-danger-ink);
10165
+ }
10166
+
10167
+ .crewlet-data-grid__cell {
10168
+ padding: var(--spacing-1) var(--spacing-3);
10169
+ font-size: var(--font-size-compact);
10170
+ min-width: 0;
10171
+ display: flex;
10172
+ align-items: center;
10173
+ gap: var(--spacing-2);
10174
+ }
10175
+
10176
+ /*
10177
+ * A SHRINK COLUMN does not wrap inside its capped track, and does not paint
10178
+ * outside it: a nowrap cell narrower than its content would spill over the
10179
+ * column beside it. `clip`, since a scrollport here would cut the sticky head.
10180
+ */
10181
+ .crewlet-data-grid__th--shrink,
10182
+ .crewlet-data-grid__cell--shrink {
10183
+ white-space: nowrap;
10184
+ overflow: clip;
10185
+ }
10186
+
10187
+ .crewlet-data-grid__cell--right {
10188
+ justify-content: flex-end;
10189
+ }
10190
+
10191
+ .crewlet-data-grid__truncate {
10192
+ min-width: 0;
10193
+ overflow: hidden;
10194
+ text-overflow: ellipsis;
10195
+ white-space: nowrap;
10196
+ }
10197
+
10198
+ .crewlet-data-grid__band + .crewlet-data-grid__band {
10199
+ border-top: 1px solid var(--color-border-hover);
10200
+ }
10201
+
10202
+ .crewlet-data-grid__band-head,
10203
+ .crewlet-data-grid__band-foot {
10204
+ display: flex;
10205
+ }
10206
+
10207
+ /* The band row's one cell lays its parts out on the row's own flex line. */
10208
+ .crewlet-data-grid__band-cell {
10209
+ display: contents;
10210
+ }
10211
+
10212
+ .crewlet-data-grid__band-head {
10213
+ display: flex;
10214
+ align-items: center;
10215
+ gap: var(--spacing-2);
10216
+ padding: var(--spacing-2) var(--spacing-3);
10217
+ background: var(--color-surface-elevated);
10218
+ font-size: var(--font-size-xs);
10219
+ font-weight: var(--font-weight-semibold);
10220
+ position: sticky;
10221
+ /* Under the column heads, which are a row tall and parked at the offset;
10222
+ confined to its own band, so it leaves with the band. Above the rows
10223
+ (positioned for the row link) and below the heads. */
10224
+ top: calc(var(--crewlet-data-grid-sticky-top, var(--spacing-0)) + var(--size-row-md));
10225
+ z-index: var(--z-index-raised);
10226
+ }
10227
+
10228
+ /* A SECOND AXIS IS A BAND INSIDE A BAND, inset and quieter, so it does not
10229
+ read as its parent's sibling; and it draws no rule above itself. */
10230
+ .crewlet-data-grid__band .crewlet-data-grid__band > .crewlet-data-grid__band-head {
10231
+ padding-left: calc(var(--spacing-3) + var(--spacing-4));
10232
+ background: var(--color-surface-subtle);
10233
+ font-weight: var(--font-weight-medium);
10234
+ color: var(--color-text-tertiary);
10235
+ }
10236
+
10237
+ .crewlet-data-grid__band .crewlet-data-grid__band + .crewlet-data-grid__band {
10238
+ border-top: none;
10239
+ }
10240
+
10241
+ .crewlet-data-grid__band-count {
10242
+ margin-left: auto;
10243
+ color: var(--color-text-tertiary);
10244
+ font-weight: var(--font-weight-regular);
10245
+ font-variant-numeric: tabular-nums;
10246
+ }
10247
+
10248
+ .crewlet-data-grid__band-foot {
10249
+ padding: var(--spacing-1) var(--spacing-3);
10250
+ font-size: var(--font-size-2xs);
10251
+ color: var(--color-text-tertiary);
10252
+ background: var(--color-surface-elevated);
10253
+ }
10254
+
10255
+ .crewlet-data-grid__band-foot a {
10256
+ color: var(--color-brand-accent-ink);
10257
+ }
10258
+
10259
+ .crewlet-data-grid__band-foot a:hover {
10260
+ color: var(--color-text-primary);
10261
+ }
10262
+
10263
+ .crewlet-data-grid__foot {
10264
+ display: flex;
10265
+ align-items: center;
10266
+ gap: var(--spacing-2);
10267
+ padding: var(--spacing-2) var(--spacing-3);
10268
+ border-top: 1px solid var(--color-border-hover);
10269
+ background: var(--color-surface-elevated);
10270
+ font-size: var(--font-size-xs);
10271
+ }
10272
+
10273
+ .crewlet-data-grid__foot-spacer {
10274
+ flex: 1 1 auto;
10275
+ }
10276
+
10277
+ .crewlet-data-grid__note {
10278
+ font-size: var(--font-size-xs);
10279
+ color: var(--color-text-tertiary);
10280
+ }
10281
+
10282
+ .crewlet-data-grid__cols-reset {
10283
+ all: unset;
10284
+ /* After the reset, which takes `grid-column` too. */
10285
+ grid-column: 1 / -1;
10286
+ padding: var(--spacing-1) var(--spacing-3);
10287
+ font-size: var(--font-size-2xs);
10288
+ color: var(--color-brand-accent-ink);
10289
+ cursor: pointer;
10290
+ text-align: left;
10291
+ }
10292
+
10293
+ /* ---- The column chooser ------------------------------------------------ */
10294
+
10295
+ .crewlet-column-chooser__label {
10296
+ font-size: var(--font-size-2xs);
10297
+ font-weight: var(--font-weight-medium);
10298
+ letter-spacing: var(--font-letter-spacing-wide);
10299
+ text-transform: uppercase;
10300
+ color: var(--color-text-tertiary);
10301
+ }
10302
+
10303
+ /* TWO COLUMNS: a single file of short words makes a menu as tall as the grid
10304
+ has columns. */
10305
+ .crewlet-column-chooser__choices {
10306
+ display: grid;
10307
+ grid-template-columns: repeat(2, minmax(0, 1fr));
10308
+ gap: var(--spacing-1) var(--spacing-3);
10309
+ }
10310
+
10311
+ /* The pointer target is the row, not the 13px box. */
10312
+ .crewlet-column-chooser__choice {
10313
+ display: flex;
10314
+ align-items: center;
10315
+ gap: var(--spacing-2);
10316
+ min-height: var(--size-target-min);
10317
+ font-size: var(--font-size-compact);
10318
+ color: var(--color-text-secondary);
10319
+ cursor: pointer;
10320
+ }
10321
+
10322
+ @media (prefers-reduced-motion: reduce) {
10323
+ .crewlet-data-grid__th,
10324
+ .crewlet-data-grid__row {
10325
+ transition: none;
10326
+ }
10327
+ }
10328
+
10329
+ /* ---- A ROW IS A CARD ON A PHONE -----------------------------------------
10330
+ A GRID IS COLUMNS, AND A PHONE DOES NOT HAVE THEM: the grid clips (for its
10331
+ sticky head), so the columns past the edge were cut off with nothing to
10332
+ scroll to, and a sideways scroller resolves every flexible track to zero. So
10333
+ the head goes and each cell draws its own name beside its value
10334
+ (`data-label`); the subgrid chain is unwound to blocks and each cell is a
10335
+ flex line, label then value. A cell with nothing in it is no line
10336
+ (`:empty`), and a cell that draws a marked absence has content and stays.
10337
+ The sort is in the application's state, so a sorted list still arrives
10338
+ sorted. */
10339
+ @media (width < 640px) {
10340
+ .crewlet-data-grid {
10341
+ display: block;
10342
+ }
10343
+
10344
+ .crewlet-data-grid__head {
10345
+ display: none;
10346
+ }
10347
+
10348
+ .crewlet-data-grid__body,
10349
+ .crewlet-data-grid__band {
10350
+ display: block;
10351
+ }
10352
+
10353
+ .crewlet-data-grid__row {
10354
+ display: block;
10355
+ padding: var(--spacing-2) var(--spacing-3);
10356
+ min-height: 0;
10357
+ }
10358
+
10359
+ /* A FIXED BASIS lines the names up without a track, and the name wraps
10360
+ inside it rather than pushing its value past every other card line. */
10361
+ .crewlet-data-grid__cell {
10362
+ display: flex;
10363
+ align-items: baseline;
10364
+ gap: var(--spacing-3);
10365
+ padding: 1px 0;
10366
+ min-width: 0;
10367
+ }
10368
+
10369
+ .crewlet-data-grid__cell:empty {
10370
+ display: none;
10371
+ }
10372
+
10373
+ .crewlet-data-grid__cell[data-label]::before {
10374
+ content: attr(data-label);
10375
+ flex: 0 0 7rem;
10376
+ overflow-wrap: anywhere;
10377
+ font-size: var(--font-size-2xs);
10378
+ text-transform: uppercase;
10379
+ letter-spacing: var(--font-letter-spacing-wide);
10380
+ color: var(--color-text-tertiary);
10381
+ }
10382
+
10383
+ /* `shrink` and `right` are column shapes, and there are no columns here. */
10384
+ .crewlet-data-grid__cell--shrink,
10385
+ .crewlet-data-grid__cell--right {
10386
+ white-space: normal;
10387
+ justify-content: flex-start;
10388
+ }
10389
+
10390
+ .crewlet-data-grid__cell .crewlet-data-grid__truncate {
10391
+ white-space: normal;
10392
+ overflow: visible;
10393
+ text-overflow: clip;
10394
+ overflow-wrap: anywhere;
10395
+ }
10396
+
10397
+ /* ---- THE COMPACT ROW (`phoneRows="compact"`) ---------------------------
10398
+ TWO LINES, NO LABELS: what the row is, then its marks. One flex run that
10399
+ breaks once: the lead cells first, a zero-height full-width `::after`
10400
+ between them and the rest, then every other cell in column order. */
10401
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__row {
10402
+ display: flex;
10403
+ flex-wrap: wrap;
10404
+ align-items: center;
10405
+ gap: var(--spacing-1) var(--spacing-2);
10406
+ }
10407
+
10408
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__row::after {
10409
+ content: '';
10410
+ order: 1;
10411
+ flex-basis: 100%;
10412
+ height: 0;
10413
+ }
10414
+
10415
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__cell {
10416
+ order: 2;
10417
+ padding: 0;
10418
+ align-items: center;
10419
+ gap: var(--spacing-1);
10420
+ }
10421
+
10422
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__cell[data-lead] {
10423
+ order: 0;
10424
+ }
10425
+
10426
+ /* The title takes the rest of the first line, beside the key. */
10427
+ .crewlet-data-grid[data-phone-rows='compact']
10428
+ .crewlet-data-grid__cell[data-lead]:not(.crewlet-data-grid__cell--shrink) {
10429
+ flex: 1 1 0;
10430
+ min-width: 0;
10431
+ font-weight: var(--font-weight-medium);
10432
+ }
10433
+
10434
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__cell[data-label]::before {
10435
+ content: none;
10436
+ }
10437
+
10438
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__cell[data-phone-omit] {
10439
+ display: none;
10440
+ }
10441
+ }
10442
+
10443
+
10444
+ /* DataTable-NL2YWAIA.css */
10445
+ /* ─────────────────────────────────────────────────────────────────
10446
+ * Default variant.
10447
+ *
10448
+ * Every rule is scoped under the variant root, so the table's
10449
+ * internals never match an application's own class names and the
10450
+ * compact variant's rules further down never leak into this one.
10451
+ * ───────────────────────────────────────────────────────────────── */
10452
+ .crewlet-data-table--default {
10453
+ /*
10454
+ * The two knobs the compact root declares, so a host that rebinds either one
10455
+ * reaches both variants. The hover is the OVERLAY step rather than an opaque
10456
+ * surface: a table sits on the page, on a card and inside a dialog, and only
10457
+ * an overlay composites correctly onto all three.
10458
+ */
10459
+ --crewlet-data-table-row-hover-bg: var(--color-surface-hover);
10460
+ --crewlet-data-table-active-sort-color: var(--color-brand-accent-ink);
10461
+ width: 100%;
10462
+ position: relative;
10463
+ /* NO SCROLLER HERE. This carried `overflow-x: auto` and its own
10464
+ `overscroll-behavior-x`, and neither could act: `.crewlet-data-table__scroll`
10465
+ is rendered inside it for BOTH variants at `width: 100%`, so it absorbs
10466
+ the table's width and the root never has anything to scroll. What the
10467
+ declaration did still do is make this a scroll container — and per CSS
10468
+ Overflow that pulls `overflow-y` to `auto` as well — so it quietly became
10469
+ the scrollport a `position: sticky` descendant resolves against. The inner
10470
+ wrapper carries the real scrolling and the gesture containment, which is
10471
+ what the layout comment further down already describes. */
10472
+ }
10473
+
10474
+ .crewlet-data-table--default .crewlet-data-table__table {
10475
+ width: 100%;
10476
+ border-collapse: collapse;
10477
+ background: transparent;
10478
+ display: table;
10479
+ table-layout: auto;
10480
+ /* The table register: a cell is scanned down a column rather than read as a
10481
+ sentence, and the compact step is where a row of them still lines up with
10482
+ the row token the cells are sized to. */
10483
+ font-size: var(--font-size-compact);
10484
+ }
10485
+
10486
+ /*
10487
+ * THE RULE UNDER THE HEADER IS THE HEADER'S. It used to sit on `thead`, which
10488
+ * a sticky header carries nowhere: the group does not stick, its cells do, so
9662
10489
  * the line stayed at the top of the table and the column names scrolled over
9663
10490
  * the rows with nothing under them.
9664
10491
  */
@@ -16557,7 +17384,7 @@ button.crewlet-finding-list__row:focus-visible {
16557
17384
  }
16558
17385
 
16559
17386
 
16560
- /* List-MYJIV6MP.css */
17387
+ /* List-YHLIZFK4.css */
16561
17388
  /*
16562
17389
  * The non-tabular list. One row recipe, four framings.
16563
17390
  *
@@ -16680,6 +17507,52 @@ button.crewlet-finding-list__row:focus-visible {
16680
17507
  padding-inline: 0;
16681
17508
  }
16682
17509
 
17510
+ /*
17511
+ * NUMBERED AND DIVIDED: the divided list's hairlines, with the number in a
17512
+ * column of its own rather than in the margin, so a statement that runs to a
17513
+ * second line wraps under its own first word and not under its number. The
17514
+ * row grows with its text (no row height), at the body's leading, and the
17515
+ * number stands on the first line's baseline.
17516
+ *
17517
+ * The number is the list's counter, drawn by the row. The `ol` already
17518
+ * announces each item's position, so the drawn figure is given empty
17519
+ * alternative text and is not read a second time.
17520
+ */
17521
+ .crewlet-list--numbered-divided {
17522
+ counter-reset: crewlet-list-item;
17523
+ }
17524
+
17525
+ .crewlet-list--numbered-divided .crewlet-list__item {
17526
+ counter-increment: crewlet-list-item;
17527
+ border-bottom: 1px solid var(--color-border-default);
17528
+ }
17529
+
17530
+ .crewlet-list--numbered-divided .crewlet-list__item:last-child {
17531
+ border-bottom: none;
17532
+ }
17533
+
17534
+ .crewlet-list--numbered-divided .crewlet-list__row {
17535
+ align-items: baseline;
17536
+ min-height: 0;
17537
+ /* At a card's own inset, since a card is where these stand: the numbers
17538
+ line up under the card head's glyph rather than 4px left of it. */
17539
+ padding: var(--spacing-3) var(--spacing-4);
17540
+ border-radius: 0;
17541
+ line-height: var(--font-line-height-body);
17542
+ }
17543
+
17544
+ .crewlet-list--numbered-divided .crewlet-list__row::before {
17545
+ content: counter(crewlet-list-item);
17546
+ content: counter(crewlet-list-item) / '';
17547
+ flex: none;
17548
+ min-width: 2ch;
17549
+ text-align: end;
17550
+ font-size: var(--font-size-xs);
17551
+ font-weight: var(--font-weight-medium);
17552
+ font-variant-numeric: tabular-nums;
17553
+ color: var(--color-text-tertiary);
17554
+ }
17555
+
16683
17556
  /* ---- States ------------------------------------------------------------ */
16684
17557
 
16685
17558
  /*
@@ -17229,6 +18102,25 @@ button.crewlet-finding-list__row:focus-visible {
17229
18102
  }
17230
18103
 
17231
18104
 
18105
+ /* LockedLabel-VQEGEB7G.css */
18106
+ /*
18107
+ * LockedLabel: a place's words with the key after them. The words keep their
18108
+ * own ink and size; the key takes the quiet step, a step closer to the words
18109
+ * than the words are to anything else.
18110
+ */
18111
+ .crewlet-locked-label {
18112
+ display: inline-flex;
18113
+ align-items: center;
18114
+ gap: var(--spacing-1);
18115
+ min-width: 0;
18116
+ }
18117
+
18118
+ .crewlet-locked-label__key {
18119
+ flex: none;
18120
+ color: var(--color-text-tertiary);
18121
+ }
18122
+
18123
+
17232
18124
  /* MarkdownEditor-WOKV7CLK.css */
17233
18125
  /*
17234
18126
  * Writing markdown (MarkdownEditor.tsx): the bar, the source or its preview,
@@ -17876,7 +18768,7 @@ button.crewlet-finding-list__row:focus-visible {
17876
18768
  }
17877
18769
 
17878
18770
 
17879
- /* Modal-7MWRCWAI.css */
18771
+ /* Modal-TOEWHDCQ.css */
17880
18772
  /*
17881
18773
  * The modal surface: the veil, the frame, and the three bands inside it.
17882
18774
  *
@@ -18258,6 +19150,11 @@ button.crewlet-finding-list__row:focus-visible {
18258
19150
  */
18259
19151
  .crewlet-modal__title {
18260
19152
  margin: 0;
19153
+ /* The text face at its own tracking, never the display face every heading
19154
+ element takes from the baseline: the title is an h1 for the outline, at
19155
+ the dialog's own register. */
19156
+ font-family: var(--font-family-sans);
19157
+ letter-spacing: var(--font-letter-spacing-normal);
18261
19158
  font-size: var(--font-size-sm);
18262
19159
  font-weight: var(--font-weight-semibold);
18263
19160
  line-height: var(--font-line-height-tight);
@@ -18610,9 +19507,14 @@ button.crewlet-finding-list__row:focus-visible {
18610
19507
  }
18611
19508
 
18612
19509
 
18613
- /* ObjectHeader-D7GU7QNI.css */
19510
+ /* ObjectHeader-ZOS22FKX.css */
18614
19511
  /*
18615
19512
  * The header of an object: its eyebrow, its head row and its fact line.
19513
+ *
19514
+ * SENTENCE CASE, both the eyebrow and the fact labels, as `StatCard`'s label
19515
+ * is: the uppercase, tracked-open micro-caps are a table's column head, and
19516
+ * over an object's name ("UNIT", then TYPE, LEAD and SEATS under it) they put
19517
+ * a heading on every fact and read as a form rather than a record.
18616
19518
  */
18617
19519
  .crewlet-object-header {
18618
19520
  display: flex;
@@ -18631,9 +19533,7 @@ button.crewlet-finding-list__row:focus-visible {
18631
19533
  align-items: center;
18632
19534
  gap: var(--spacing-2);
18633
19535
  min-width: 0;
18634
- font-size: var(--font-size-2xs);
18635
- letter-spacing: var(--font-letter-spacing-wide);
18636
- text-transform: uppercase;
19536
+ font-size: var(--font-size-xs);
18637
19537
  color: var(--color-text-tertiary);
18638
19538
  }
18639
19539
 
@@ -18648,8 +19548,6 @@ button.crewlet-finding-list__row:focus-visible {
18648
19548
  overflow: hidden;
18649
19549
  text-overflow: ellipsis;
18650
19550
  white-space: nowrap;
18651
- letter-spacing: normal;
18652
- text-transform: none;
18653
19551
  }
18654
19552
 
18655
19553
  .crewlet-object-header__id--mono {
@@ -18751,9 +19649,7 @@ button.crewlet-finding-list__row:focus-visible {
18751
19649
  }
18752
19650
 
18753
19651
  .crewlet-fact-line__label {
18754
- font-size: var(--font-size-2xs);
18755
- letter-spacing: var(--font-letter-spacing-wide);
18756
- text-transform: uppercase;
19652
+ font-size: var(--font-size-xs);
18757
19653
  color: var(--color-text-tertiary);
18758
19654
  }
18759
19655
 
@@ -19952,6 +20848,21 @@ button.crewlet-finding-list__row:focus-visible {
19952
20848
  }
19953
20849
 
19954
20850
 
20851
+ /* PageNote-RHLXH3ML.css */
20852
+ /*
20853
+ * PageNote: the screen's one quiet sentence. No word alone on its last line
20854
+ * (`pretty`), which reads as a sentence that stopped rather than one that
20855
+ * ended. No margin of its own: the column it stands in sets the gap.
20856
+ */
20857
+ .crewlet-page-note {
20858
+ margin: 0;
20859
+ max-width: var(--size-measure);
20860
+ font-size: var(--font-size-compact);
20861
+ color: var(--color-text-tertiary);
20862
+ text-wrap: pretty;
20863
+ }
20864
+
20865
+
19955
20866
  /* PeopleRail-SZGHZXVT.css */
19956
20867
  /* PeopleRail: a raised column of everybody present, one row a person, the
19957
20868
  name over what they are doing and the controls at the row's end. */
@@ -20992,6 +21903,105 @@ button.crewlet-presence-stack__member:focus-visible {
20992
21903
  }
20993
21904
 
20994
21905
 
21906
+ /* PropertyList-SCYM66LL.css */
21907
+ /*
21908
+ * An object's properties, in sections, on one grid.
21909
+ *
21910
+ * ONE TERM COLUMN DOWN THE WHOLE LIST. Every section is a description list of
21911
+ * its own, laid out as a SUBGRID of this one, so its terms and details sit on
21912
+ * this grid's two tracks and every section's labels start and end where the
21913
+ * others' do. The term track is the description list's own measure,
21914
+ * `--crewlet-description-list-term`, so a page that sets it once lines a list
21915
+ * of properties up with every key-value card on it. Unset, it is the rail's
21916
+ * own: as wide as the longest label, and never under 92px, which a one-word
21917
+ * label ("Due") would otherwise shrink the column to.
21918
+ *
21919
+ * SIDE BY SIDE AT EVERY WIDTH. A list of properties sits in a rail or a card
21920
+ * of its own width, so the window's width says nothing about the room it has;
21921
+ * the description list's narrow step (term over detail) is cancelled below.
21922
+ */
21923
+
21924
+ .crewlet-property-list {
21925
+ display: grid;
21926
+ grid-template-columns: var(--crewlet-description-list-term, minmax(92px, max-content)) minmax(0, 1fr);
21927
+ gap: var(--spacing-2) var(--spacing-3);
21928
+ align-items: baseline;
21929
+ min-width: 0;
21930
+ font-size: var(--font-size-compact);
21931
+ }
21932
+
21933
+ /* Two classes, so the description list's own track and narrow step (one
21934
+ class, in a media query) give way to the subgrid at every width. */
21935
+ .crewlet-property-list > .crewlet-property-list__group {
21936
+ grid-column: 1 / -1;
21937
+ grid-template-columns: subgrid;
21938
+ gap: inherit;
21939
+ font-size: inherit;
21940
+ }
21941
+
21942
+ .crewlet-property-list .crewlet-description-list__detail {
21943
+ margin-bottom: 0;
21944
+ }
21945
+
21946
+ /* THE LABEL IS AN IDENTIFIER (an environment variable's name, a tag's key),
21947
+ set in the mono face; a word stays in the list's own. */
21948
+ .crewlet-property-list__identifier {
21949
+ font-family: var(--font-family-mono);
21950
+ }
21951
+
21952
+ /*
21953
+ * A SECTION'S HEADING, with a hairline above it that separates it from the
21954
+ * section before. The list's FIRST heading has nothing to be separated from,
21955
+ * so it alone loses the hairline; a list that opens with rows of no section
21956
+ * keeps it on its first heading, which has rows above it.
21957
+ */
21958
+ .crewlet-property-list__heading {
21959
+ grid-column: 1 / -1;
21960
+ margin-top: var(--spacing-2);
21961
+ padding-top: var(--spacing-2);
21962
+ border-top: 1px solid var(--color-border-default);
21963
+ color: var(--color-text-tertiary);
21964
+ }
21965
+
21966
+ .crewlet-property-list__heading:first-child {
21967
+ margin-top: 0;
21968
+ padding-top: 0;
21969
+ border-top: none;
21970
+ }
21971
+
21972
+ .crewlet-property-list--eyebrow .crewlet-property-list__heading {
21973
+ font-size: var(--font-size-2xs);
21974
+ font-weight: var(--font-weight-medium);
21975
+ letter-spacing: var(--font-letter-spacing-wide);
21976
+ text-transform: uppercase;
21977
+ }
21978
+
21979
+ .crewlet-property-list--sentence .crewlet-property-list__heading {
21980
+ font-size: var(--font-size-xs);
21981
+ font-weight: var(--font-weight-medium);
21982
+ }
21983
+
21984
+ /* A SECTION NOBODY HAS FILLED IN, said once across both tracks in the words
21985
+ its caller wrote. It is a sentence a reader has to read, so it takes the
21986
+ tertiary rung, never the muted one (a floor for a mark). */
21987
+ .crewlet-property-list__empty {
21988
+ grid-column: 1 / -1;
21989
+ margin: 0;
21990
+ font-size: var(--font-size-xs);
21991
+ color: var(--color-text-tertiary);
21992
+ }
21993
+
21994
+ /* WHO SET IT, under the value rather than beside it: the value is what the
21995
+ reader came for. A line of its own, so a long actor name cannot push the
21996
+ value out of its track. */
21997
+ .crewlet-property-list__set-by {
21998
+ display: block;
21999
+ margin-top: 2px;
22000
+ font-size: var(--font-size-2xs);
22001
+ color: var(--color-text-tertiary);
22002
+ }
22003
+
22004
+
20995
22005
  /* Prose-BTXNFT2Q.css */
20996
22006
  /*
20997
22007
  * Natural language: the proportional face, real leading, a bounded measure.
@@ -21313,6 +22323,15 @@ button.crewlet-presence-stack__member:focus-visible {
21313
22323
  }
21314
22324
 
21315
22325
 
22326
+ /* RelatedRow-2FVS6QQA.css */
22327
+ /* RelatedRow: the glyphs in the quiet ink; everything else is the kit's card. */
22328
+ .crewlet-related-row__glyph {
22329
+ display: inline-flex;
22330
+ flex: none;
22331
+ color: var(--color-text-tertiary);
22332
+ }
22333
+
22334
+
21316
22335
  /* RelativeTime-EBAQPGO2.css */
21317
22336
  /*
21318
22337
  * A relative time is text, so it takes the register around it. Its one rule is
@@ -22050,49 +23069,216 @@ button.crewlet-presence-stack__member:focus-visible {
22050
23069
  gap: var(--spacing-3);
22051
23070
  }
22052
23071
 
22053
- @media (max-width: 768px) {
22054
- .crewlet-section--sm {
22055
- padding-block: var(--spacing-7);
22056
- }
22057
-
22058
- .crewlet-section--md {
22059
- padding-block: var(--spacing-9);
22060
- }
23072
+ @media (max-width: 768px) {
23073
+ .crewlet-section--sm {
23074
+ padding-block: var(--spacing-7);
23075
+ }
23076
+
23077
+ .crewlet-section--md {
23078
+ padding-block: var(--spacing-9);
23079
+ }
23080
+
23081
+ .crewlet-section--lg {
23082
+ padding-block: var(--spacing-10);
23083
+ }
23084
+
23085
+ .crewlet-section__header {
23086
+ flex-wrap: wrap;
23087
+ row-gap: var(--spacing-1);
23088
+ }
23089
+
23090
+ .crewlet-section__description {
23091
+ order: 1;
23092
+ white-space: normal;
23093
+ flex-basis: 100%;
23094
+ }
23095
+ }
23096
+
23097
+ /*
23098
+ * NARROW: the sentence moves under the heading rather than competing with it
23099
+ * for a line that has room for neither, and the actions stay on the heading's
23100
+ * line. Measured on the column the section sits in where it sits in a size
23101
+ * container (a side panel, a screen's content column), since a panel beside a
23102
+ * wide window is as narrow as a phone; the window's width above is the answer
23103
+ * where there is no container to ask.
23104
+ */
23105
+ @container (width < 36rem) {
23106
+ .crewlet-section__header {
23107
+ flex-wrap: wrap;
23108
+ row-gap: var(--spacing-1);
23109
+ }
23110
+
23111
+ .crewlet-section__description {
23112
+ order: 1;
23113
+ white-space: normal;
23114
+ flex-basis: 100%;
23115
+ }
23116
+ }
23117
+
23118
+
23119
+ /* SectionFrame-M62UUVFQ.css */
23120
+ /*
23121
+ * SectionFrame: a column of sections beside the screen, and the one-row
23122
+ * picker it folds to.
23123
+ */
23124
+
23125
+ /* THE FRAME TAKES THE CONTENT COLUMN'S PADDING BACK and gives it to the body,
23126
+ so the column is flush with the sheet and the section keeps the inset. */
23127
+ .crewlet-app-shell__content:has(> .crewlet-section-frame) {
23128
+ min-height: 100%;
23129
+ padding: 0;
23130
+ }
23131
+
23132
+ .crewlet-section-frame {
23133
+ display: grid;
23134
+ flex: 1 1 auto;
23135
+ grid-template-columns: var(--crewlet-section-frame-column) minmax(0, 1fr);
23136
+ min-height: 100%;
23137
+ }
23138
+
23139
+ /*
23140
+ * AS TALL AS THE VIEW, NEVER AS THE GRID. A sticky box moves only inside its
23141
+ * grid area, which the section beside it makes as tall as its content; sized
23142
+ * against that area the column was exactly as tall as the section, had
23143
+ * nowhere to stick, and a wheel over a long section carried the list off the
23144
+ * top. At the view's height (`100cqb`: the shell's scroller is a size
23145
+ * container) it sticks for the whole scroll and a long list scrolls in itself.
23146
+ *
23147
+ * IT KEEPS THE WHEEL AT ITS ENDS. A box whose bottom is below the fold traps
23148
+ * the wheel; this one is exactly the view and always all on screen, so what
23149
+ * chaining would do is move the section beside it at the list's end, which
23150
+ * is not what the pointer is over.
23151
+ */
23152
+ .crewlet-section-frame__nav {
23153
+ position: sticky;
23154
+ top: 0;
23155
+ align-self: start;
23156
+ height: 100cqb;
23157
+ overflow-y: auto;
23158
+ overscroll-behavior: contain;
23159
+ padding: var(--spacing-4) 0;
23160
+ border-right: 1px solid var(--color-border-default);
23161
+ }
23162
+
23163
+ .crewlet-section-frame__body {
23164
+ display: flex;
23165
+ flex-direction: column;
23166
+ gap: var(--spacing-5);
23167
+ min-width: 0;
23168
+ padding: var(--spacing-5) var(--spacing-5) var(--spacing-10);
23169
+ }
23170
+
23171
+ /* BESIDE THE SECTION there is room for the whole list: no toggle, and the
23172
+ list is always drawn. */
23173
+ .crewlet-section-frame__toggle {
23174
+ display: none;
23175
+ }
23176
+
23177
+ /*
23178
+ * FOLDED: one pane, the picker above the section. The picker's row is its
23179
+ * own height and the section takes the rest: two `auto` rows split a short
23180
+ * section's spare height and opened a band of nothing between the picker
23181
+ * and the section it names.
23182
+ */
23183
+ .crewlet-section-frame[data-folded] {
23184
+ grid-template-columns: minmax(0, 1fr);
23185
+ grid-template-rows: auto 1fr;
23186
+ }
23187
+
23188
+ /* IN THE FLOW, as tall as it is, on the section's own gutter: the list it
23189
+ unfolds is part of the page rather than a pane of its own. */
23190
+ .crewlet-section-frame[data-folded] > .crewlet-section-frame__nav {
23191
+ position: static;
23192
+ height: auto;
23193
+ overflow-y: visible;
23194
+ padding: var(--spacing-2) var(--spacing-5);
23195
+ border-right: none;
23196
+ border-bottom: 1px solid var(--color-border-default);
23197
+ }
23198
+
23199
+ /* ONE ROW NAMING WHERE THE READER IS, which unfolds the list. Its glyph and
23200
+ name stand over the glyphs and names of the rows: the rows' own inset,
23201
+ less the toggle's border. */
23202
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__toggle {
23203
+ display: flex;
23204
+ align-items: center;
23205
+ gap: var(--spacing-2);
23206
+ width: 100%;
23207
+ min-height: var(--size-target-min);
23208
+ padding: 0 calc(var(--size-nav-row-pad) - 1px);
23209
+ border: 1px solid var(--color-border-default);
23210
+ border-radius: var(--radius-sm);
23211
+ background: var(--color-surface-elevated);
23212
+ color: var(--color-text-primary);
23213
+ font: inherit;
23214
+ font-weight: var(--font-weight-medium);
23215
+ text-align: left;
23216
+ cursor: pointer;
23217
+ }
23218
+
23219
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__toggle:hover {
23220
+ background: var(--color-surface-hover);
23221
+ }
23222
+
23223
+ /* INSIDE ITS OWN EDGE, as every control that draws one rings. */
23224
+ .crewlet-section-frame__toggle:focus-visible {
23225
+ outline: 2px solid var(--color-focus);
23226
+ outline-offset: var(--size-focus-ring-inset-offset);
23227
+ }
23228
+
23229
+ .crewlet-section-frame__toggle-icon {
23230
+ display: inline-flex;
23231
+ flex: none;
23232
+ }
23233
+
23234
+ .crewlet-section-frame__toggle-name {
23235
+ flex: 1 1 auto;
23236
+ min-width: 0;
23237
+ overflow: hidden;
23238
+ text-overflow: ellipsis;
23239
+ white-space: nowrap;
23240
+ }
23241
+
23242
+ /* "Section ·" BEFORE THE NAME, in the quiet ink, so the row reads as a
23243
+ control holding the other sections rather than as the page's title. */
23244
+ .crewlet-section-frame__toggle-prefix {
23245
+ color: var(--color-text-tertiary);
23246
+ font-weight: var(--font-weight-regular);
23247
+ }
23248
+
23249
+ .crewlet-section-frame__chevron {
23250
+ flex: none;
23251
+ color: var(--color-text-tertiary);
23252
+ }
23253
+
23254
+ .crewlet-section-frame__nav[data-open] .crewlet-section-frame__chevron {
23255
+ transform: rotate(180deg);
23256
+ }
22061
23257
 
22062
- .crewlet-section--lg {
22063
- padding-block: var(--spacing-10);
22064
- }
23258
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__nav:not([data-open]) .crewlet-section-frame__list {
23259
+ display: none;
23260
+ }
22065
23261
 
22066
- .crewlet-section__header {
22067
- flex-wrap: wrap;
22068
- row-gap: var(--spacing-1);
22069
- }
23262
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__nav[data-open] .crewlet-section-frame__list {
23263
+ padding-top: var(--spacing-2);
23264
+ }
22070
23265
 
22071
- .crewlet-section__description {
22072
- order: 1;
22073
- white-space: normal;
22074
- flex-basis: 100%;
22075
- }
23266
+ /* THE LIST TAKES NO GUTTER OF ITS OWN inside the folded picker, which is
23267
+ inset already: with the rail's gutter on top, its glyphs sat 11px right of
23268
+ the toggle's. */
23269
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__list > .crewlet-sidebar-nav {
23270
+ padding-inline: 0;
22076
23271
  }
22077
23272
 
22078
- /*
22079
- * NARROW: the sentence moves under the heading rather than competing with it
22080
- * for a line that has room for neither, and the actions stay on the heading's
22081
- * line. Measured on the column the section sits in where it sits in a size
22082
- * container (a side panel, a screen's content column), since a panel beside a
22083
- * wide window is as narrow as a phone; the window's width above is the answer
22084
- * where there is no container to ask.
22085
- */
22086
- @container (width < 36rem) {
22087
- .crewlet-section__header {
22088
- flex-wrap: wrap;
22089
- row-gap: var(--spacing-1);
23273
+ /* A PHONE'S ONE GUTTER: the section and the picker start where every other
23274
+ screen's content does. */
23275
+ @media (width < 640px) {
23276
+ .crewlet-section-frame__body {
23277
+ padding: var(--spacing-4) var(--spacing-4) var(--spacing-9);
22090
23278
  }
22091
23279
 
22092
- .crewlet-section__description {
22093
- order: 1;
22094
- white-space: normal;
22095
- flex-basis: 100%;
23280
+ .crewlet-section-frame[data-folded] > .crewlet-section-frame__nav {
23281
+ padding-inline: var(--spacing-4);
22096
23282
  }
22097
23283
  }
22098
23284
 
@@ -22893,6 +24079,169 @@ svg.crewlet-select__chevron {
22893
24079
  }
22894
24080
 
22895
24081
 
24082
+ /* SettingsTable-6DUFAFXG.css */
24083
+ /*
24084
+ * SettingsTable: a read-only table of settings, one row each, on one grid.
24085
+ *
24086
+ * THE TRACKS ARE FRACTIONS OF THE TABLE, so every table of one width shares
24087
+ * them: a page that stacks a table per group puts each column on one line
24088
+ * down the page with nothing to coordinate. `--crewlet-settings-table-columns`
24089
+ * is inherited, so a page that wants other proportions sets it once.
24090
+ *
24091
+ * Each row is its own grid on those tracks rather than a subgrid of the
24092
+ * table's, because the tracks are fractions: one row's long label can never
24093
+ * move another row's value, which is what a content-sized track would do.
24094
+ */
24095
+
24096
+ .crewlet-settings-table {
24097
+ container: crewlet-settings-table / inline-size;
24098
+ display: flex;
24099
+ flex-direction: column;
24100
+ min-width: 0;
24101
+ font-size: var(--font-size-compact);
24102
+ /* The flush-panel recipe, standing on its own: the card's surface, its
24103
+ hairline and its corner. Inside a card it gives them up (below). */
24104
+ background: var(--color-surface-subtle);
24105
+ border: 1px solid var(--color-border-default);
24106
+ border-radius: var(--radius-lg);
24107
+ overflow: hidden;
24108
+ }
24109
+
24110
+ /*
24111
+ * A TABLE THAT IS A CARD'S CONTENT IS THAT CARD'S TABLE. It draws no edge or
24112
+ * corner of its own inside one, so a card never holds a box inside a box; its
24113
+ * rows' hairlines run to the card's edges under the card's own head rule.
24114
+ */
24115
+ .crewlet-card > .crewlet-settings-table,
24116
+ .crewlet-card__body > .crewlet-settings-table {
24117
+ background: transparent;
24118
+ border: 0;
24119
+ border-radius: var(--radius-none);
24120
+ }
24121
+
24122
+ .crewlet-settings-table__row {
24123
+ display: grid;
24124
+ grid-template-columns: var(
24125
+ --crewlet-settings-table-columns,
24126
+ minmax(0, 5fr) minmax(0, 3fr) minmax(0, 2fr)
24127
+ );
24128
+ column-gap: var(--spacing-6);
24129
+ /* ONE BASELINE PER ROW: the name, the value and the source sit on the
24130
+ first line's baseline, whatever the name's key adds under it. */
24131
+ align-items: baseline;
24132
+ min-height: var(--size-row-md);
24133
+ padding: var(--spacing-3) var(--spacing-4);
24134
+ }
24135
+
24136
+ .crewlet-settings-table__body > .crewlet-settings-table__row + .crewlet-settings-table__row {
24137
+ border-top: 1px solid var(--color-border-default);
24138
+ }
24139
+
24140
+ /*
24141
+ * The column names, in the micro-label register a table's header takes
24142
+ * across the system, on the panel's own ground. Hidden by default (see the
24143
+ * component): still the table's column headers for assistive technology.
24144
+ */
24145
+ .crewlet-settings-table__head .crewlet-settings-table__row {
24146
+ min-height: 0;
24147
+ padding-block: var(--spacing-2);
24148
+ border-bottom: 1px solid var(--color-border-default);
24149
+ }
24150
+
24151
+ .crewlet-settings-table__name {
24152
+ font-size: var(--font-size-2xs);
24153
+ font-weight: var(--font-weight-medium);
24154
+ letter-spacing: var(--font-letter-spacing-wide);
24155
+ text-transform: uppercase;
24156
+ color: var(--color-text-tertiary);
24157
+ white-space: nowrap;
24158
+ }
24159
+
24160
+ .crewlet-settings-table__head--hidden {
24161
+ position: absolute;
24162
+ width: 1px;
24163
+ height: 1px;
24164
+ margin: -1px;
24165
+ padding: 0;
24166
+ border: 0;
24167
+ overflow: hidden;
24168
+ clip-path: inset(50%);
24169
+ white-space: nowrap;
24170
+ }
24171
+
24172
+ .crewlet-settings-table__setting {
24173
+ display: flex;
24174
+ flex-direction: column;
24175
+ gap: var(--spacing-1);
24176
+ min-width: 0;
24177
+ }
24178
+
24179
+ .crewlet-settings-table__label {
24180
+ color: var(--color-text-primary);
24181
+ line-height: var(--font-line-height-snug);
24182
+ }
24183
+
24184
+ /*
24185
+ * THE KEY IS FOR THE READER WHO WILL GO AND CHANGE IT, so it is there and
24186
+ * quiet: the monospace face at the smallest step, in the tertiary ink, and
24187
+ * free to break anywhere, since a dotted path is one word to a line breaker.
24188
+ */
24189
+ .crewlet-settings-table__key {
24190
+ font-family: var(--font-family-mono);
24191
+ font-size: var(--font-size-2xs);
24192
+ line-height: var(--font-line-height-snug);
24193
+ color: var(--color-text-tertiary);
24194
+ overflow-wrap: anywhere;
24195
+ }
24196
+
24197
+ /* Tabular figures, so a column of numbers reads down its digits. */
24198
+ .crewlet-settings-table__value {
24199
+ min-width: 0;
24200
+ color: var(--color-text-primary);
24201
+ font-weight: var(--font-weight-medium);
24202
+ font-variant-numeric: tabular-nums;
24203
+ overflow-wrap: anywhere;
24204
+ }
24205
+
24206
+ .crewlet-settings-table__source {
24207
+ display: inline-flex;
24208
+ align-items: baseline;
24209
+ gap: var(--spacing-2);
24210
+ min-width: 0;
24211
+ font-size: var(--font-size-xs);
24212
+ color: var(--color-text-tertiary);
24213
+ }
24214
+
24215
+ /* A value that differs from its default is the row a reader came to find. */
24216
+ .crewlet-settings-table__source--changed {
24217
+ color: var(--color-text-secondary);
24218
+ }
24219
+
24220
+ .crewlet-settings-table__source--changed .crewlet-status-dot {
24221
+ align-self: center;
24222
+ }
24223
+
24224
+ /*
24225
+ * NARROW: the name takes the row's first line, and the value and its source
24226
+ * share the second. Three columns at this width leave a name column a word
24227
+ * wide, which wraps every name into a stack of single words.
24228
+ */
24229
+ @container crewlet-settings-table (width < 32rem) {
24230
+ .crewlet-settings-table__row {
24231
+ grid-template-columns: minmax(0, 1fr) auto;
24232
+ row-gap: var(--spacing-1);
24233
+ }
24234
+
24235
+ .crewlet-settings-table__setting {
24236
+ grid-column: 1 / -1;
24237
+ }
24238
+
24239
+ .crewlet-settings-table__source {
24240
+ justify-self: end;
24241
+ }
24242
+ }
24243
+
24244
+
22896
24245
  /* ShareDialog-4QDCBWMH.css */
22897
24246
  /*
22898
24247
  * Three blocks under the title: who to add and at what role, who has access,
@@ -23991,7 +25340,7 @@ svg.crewlet-select__chevron {
23991
25340
  }
23992
25341
 
23993
25342
 
23994
- /* SidebarNav-7SGUZYKK.css */
25343
+ /* SidebarNav-YI74SPDC.css */
23995
25344
  /*
23996
25345
  * The rail's navigation.
23997
25346
  *
@@ -24421,6 +25770,16 @@ svg.crewlet-select__chevron {
24421
25770
  }
24422
25771
  }
24423
25772
 
25773
+ /*
25774
+ * A GROUP THE READER HOLDS NONE OF: the key once, after its label (see
25775
+ * `NavGroup`'s `locked`), and its resting rows in the quiet ink, so a closed
25776
+ * column reads as closed at a glance without a key on every row. A pointed
25777
+ * row and the reader's own still lift to the primary step, as every row does.
25778
+ */
25779
+ .crewlet-nav-group--locked .crewlet-nav-item__row:not([aria-current]):not(:hover) {
25780
+ color: var(--color-text-tertiary);
25781
+ }
25782
+
24424
25783
 
24425
25784
  /* Skeleton-V735HRGM.css */
24426
25785
  /*
@@ -25603,7 +26962,7 @@ svg.crewlet-select__chevron {
25603
26962
  }
25604
26963
 
25605
26964
 
25606
- /* StatCard-4T7TMWMN.css */
26965
+ /* StatCard-HAA3F5GX.css */
25607
26966
  /*
25608
26967
  * The stat tile.
25609
26968
  *
@@ -25792,6 +27151,12 @@ svg.crewlet-select__chevron {
25792
27151
  * tiles where only some carry one still stands at one height: its leading is
25793
27152
  * set here and the reserve is exactly one line of it, where a reserve in `em`
25794
27153
  * was a line shorter than the one a sub actually draws.
27154
+ *
27155
+ * IT WRAPS, balanced, rather than ending in an ellipsis. The line qualifies
27156
+ * the number, so its end is the half that says what the number means, and
27157
+ * `nowrap` cut it: "6 seats idle and waiting for ..." on a phone, a caption
27158
+ * mid-clause at 1440. A grid of tiles (a StatGroup, or a caller's own) gives
27159
+ * every tile in a row one height, so a second line costs no alignment.
25795
27160
  */
25796
27161
  .crewlet-statcard__sub {
25797
27162
  min-height: calc(1em * var(--font-line-height-body));
@@ -25800,9 +27165,8 @@ svg.crewlet-select__chevron {
25800
27165
  /* The quiet step, with the label. The line qualifies the number rather than
25801
27166
  being a second one. */
25802
27167
  color: var(--color-text-tertiary);
25803
- overflow: hidden;
25804
- text-overflow: ellipsis;
25805
- white-space: nowrap;
27168
+ overflow-wrap: anywhere;
27169
+ text-wrap: balance;
25806
27170
  }
25807
27171
 
25808
27172
  /*
@@ -25837,7 +27201,7 @@ svg.crewlet-select__chevron {
25837
27201
  .crewlet-statcard--info .crewlet-statcard__value { color: var(--color-feedback-info-ink); }
25838
27202
 
25839
27203
 
25840
- /* StatGroup-DOFHX5QJ.css */
27204
+ /* StatGroup-ZMW7VQWP.css */
25841
27205
  /*
25842
27206
  * A row of stat tiles.
25843
27207
  *
@@ -25915,6 +27279,33 @@ svg.crewlet-select__chevron {
25915
27279
  border-radius: var(--radius-none);
25916
27280
  }
25917
27281
 
27282
+ /*
27283
+ * A ROW OF TILES SHARES ITS LINES. A tile stacks its label, its number and its
27284
+ * sub in a column of its own, so a label that wrapped pushed its own number
27285
+ * down and no other: beside a node's peek at 1440, "Behind on config" broke
27286
+ * over two lines and its figure sat 18px below the other three. Inside a row
27287
+ * each tile is a SUBGRID over the row's lines, one per line the tile renders
27288
+ * (StatCard always renders three, an absent sub included), so a line is as
27289
+ * tall as the tallest of it across the row and every figure starts together.
27290
+ *
27291
+ * A LABEL SITS ON ITS NUMBER: where one label in the row takes two lines, the
27292
+ * others end at the foot of the label row, one gap above their figure, rather
27293
+ * than floating at its top a line away from what they name.
27294
+ *
27295
+ * These were the engine dashboard's own rules over this component, held there
27296
+ * with a note that the kit should carry them; they are the kit's now, with the
27297
+ * sub's wrap (see StatCard), which the engine applied to every tile.
27298
+ */
27299
+ .crewlet-stat-group > .crewlet-statcard {
27300
+ display: grid;
27301
+ grid-template-rows: subgrid;
27302
+ grid-row: span 3;
27303
+ }
27304
+
27305
+ .crewlet-stat-group > .crewlet-statcard > .crewlet-statcard__label {
27306
+ align-self: end;
27307
+ }
27308
+
25918
27309
  /*
25919
27310
  * Each tile spans its share of the twelve tracks: the row's `columns`, set on
25920
27311
  * it as `--crewlet-stat-group-cols`, a row.
@@ -27185,7 +28576,7 @@ b.crewlet-switcher__match {
27185
28576
  }
27186
28577
 
27187
28578
 
27188
- /* Tabs-WIF7457H.css */
28579
+ /* Tabs-S7F4RWAN.css */
27189
28580
  /*
27190
28581
  * The pill register: Tabs and SegmentedControl.
27191
28582
  *
@@ -27588,6 +28979,83 @@ b.crewlet-switcher__match {
27588
28979
  display: contents;
27589
28980
  }
27590
28981
 
28982
+ /* ─── Fold (overflow: menu) ───────────────────────────────────── */
28983
+ /*
28984
+ * THE ROW NEVER SCROLLS: what does not fit has already left it for "More".
28985
+ * A scroll with its bar hidden cut a whole tab off at a phone's edge with
28986
+ * nothing to say it was there, and a fade at the edge is too quiet to read as
28987
+ * "there is more"; a menu that says More is not.
28988
+ */
28989
+ .crewlet-tabs--fold {
28990
+ position: relative;
28991
+ min-width: 0;
28992
+ overflow: visible;
28993
+ }
28994
+
28995
+ /*
28996
+ * A FOLDED ITEM STAYS IN THE DOCUMENT, out of the flow and invisible, so it
28997
+ * can be measured again when the row grows. Pinned to the row's start, inside
28998
+ * it, so it can never widen the page. A tab, "More" with nothing in it, and a
28999
+ * note with no room alike.
29000
+ */
29001
+ .crewlet-tabs--fold > .crewlet-tabs__tab.is-folded,
29002
+ .crewlet-tabs__more.is-folded,
29003
+ .crewlet-tabs__note.is-folded {
29004
+ position: absolute;
29005
+ inset-block-start: 0;
29006
+ inset-inline-start: 0;
29007
+ visibility: hidden;
29008
+ pointer-events: none;
29009
+ }
29010
+
29011
+ /* "More" is the quiet menu button, centred on the tabs' line. */
29012
+ .crewlet-tabs__more {
29013
+ display: inline-flex;
29014
+ flex: none;
29015
+ align-items: center;
29016
+ }
29017
+
29018
+ /* The note sits at the row's far end, a sentence about every tab and never
29019
+ one of them. */
29020
+ .crewlet-tabs__note {
29021
+ flex: none;
29022
+ align-self: center;
29023
+ margin-inline-start: auto;
29024
+ font-size: var(--font-size-xs);
29025
+ color: var(--color-text-tertiary);
29026
+ white-space: nowrap;
29027
+ }
29028
+
29029
+ .crewlet-tabs__trailing {
29030
+ display: inline-flex;
29031
+ flex: none;
29032
+ align-items: center;
29033
+ }
29034
+
29035
+ /*
29036
+ * A TAB LIST HOLDS TABS ALONE, so its "More" stands beside it in a box. The
29037
+ * row is as wide as the tabs it draws, and the underline's rule is the box's,
29038
+ * painted on its last pixel row (the one the row's own border sits on), so
29039
+ * it runs on under "More" to the edge.
29040
+ */
29041
+ .crewlet-tabs-fold {
29042
+ position: relative;
29043
+ display: flex;
29044
+ align-items: stretch;
29045
+ gap: var(--spacing-2);
29046
+ min-width: 0;
29047
+ }
29048
+
29049
+ .crewlet-tabs-fold > .crewlet-tabs {
29050
+ flex: 0 1 auto;
29051
+ width: auto;
29052
+ min-width: 0;
29053
+ }
29054
+
29055
+ .crewlet-tabs-fold--underline {
29056
+ box-shadow: inset 0 -1px 0 var(--color-border-default);
29057
+ }
29058
+
27591
29059
  /*
27592
29060
  * The slider ARRIVES rather than travels, and a chip changes without a fade.
27593
29061
  * The indicator still moves; what stops is the animation between the two
@@ -28953,6 +30421,61 @@ b.crewlet-switcher__match {
28953
30421
  }
28954
30422
 
28955
30423
 
30424
+ /* TileGrid-I6LNYD2H.css */
30425
+ /*
30426
+ * TileGrid: tiles on a fixed track count that folds by the grid's own width.
30427
+ *
30428
+ * Equal tracks, so two grids of one count and one width put every tile edge
30429
+ * on the same line; the tiles in a row stretch to the tallest of them. The
30430
+ * folds are steps of the grid's own width (see the component): three tracks
30431
+ * go straight to one, so a set of three never strands a tile.
30432
+ */
30433
+
30434
+ .crewlet-tile-grid {
30435
+ container: crewlet-tile-grid / inline-size;
30436
+ min-width: 0;
30437
+ }
30438
+
30439
+ .crewlet-tile-grid__track {
30440
+ --crewlet-tile-grid-tracks: 3;
30441
+
30442
+ display: grid;
30443
+ grid-template-columns: repeat(var(--crewlet-tile-grid-tracks), minmax(0, 1fr));
30444
+ gap: var(--spacing-3);
30445
+ margin: 0;
30446
+ padding: 0;
30447
+ list-style: none;
30448
+ }
30449
+
30450
+ .crewlet-tile-grid[data-columns='2'] > .crewlet-tile-grid__track {
30451
+ --crewlet-tile-grid-tracks: 2;
30452
+ }
30453
+
30454
+ .crewlet-tile-grid[data-columns='4'] > .crewlet-tile-grid__track {
30455
+ --crewlet-tile-grid-tracks: 4;
30456
+ }
30457
+
30458
+ /* Four tracks fold to two where a tile would be narrower than its content. */
30459
+ @container crewlet-tile-grid (width < 56rem) {
30460
+ .crewlet-tile-grid[data-columns='4'] > .crewlet-tile-grid__track {
30461
+ --crewlet-tile-grid-tracks: 2;
30462
+ }
30463
+ }
30464
+
30465
+ /* Three fold to one: two up would leave the third tile alone on a row. */
30466
+ @container crewlet-tile-grid (width < 40rem) {
30467
+ .crewlet-tile-grid[data-columns='3'] > .crewlet-tile-grid__track {
30468
+ --crewlet-tile-grid-tracks: 1;
30469
+ }
30470
+ }
30471
+
30472
+ @container crewlet-tile-grid (width < 28rem) {
30473
+ .crewlet-tile-grid > .crewlet-tile-grid__track {
30474
+ --crewlet-tile-grid-tracks: 1;
30475
+ }
30476
+ }
30477
+
30478
+
28956
30479
  /* TimeWindowPicker-I3HXC74I.css */
28957
30480
  /*
28958
30481
  * TimeWindowPicker: one trigger over one panel.