@crewlethq/ui 0.39.0 → 0.40.1

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 (90) hide show
  1. package/README.md +47 -1
  2. package/dist/AppShell/AppShell.d.ts +13 -2
  3. package/dist/AppShell/index.js +1 -1
  4. package/dist/{AppShell-NDU4XMGF.css → AppShell-VE2MAV42.css} +71 -7
  5. package/dist/ArtifactBar/index.js +6 -5
  6. package/dist/AvatarPicker/index.js +10 -6
  7. package/dist/CatalogTile/index.js +1 -1
  8. package/dist/{CatalogTile-TGR2ZZVQ.css → CatalogTile-XL4XLFUH.css} +8 -4
  9. package/dist/CharacterPicker/index.js +2 -2
  10. package/dist/Charts/Histogram.d.ts +71 -0
  11. package/dist/Charts/index.d.ts +2 -0
  12. package/dist/Charts/index.js +1 -1
  13. package/dist/{Charts-MBJG72BS.css → Charts-TZ744HT6.css} +118 -0
  14. package/dist/DataGrid/DataGrid.d.ts +267 -0
  15. package/dist/DataGrid/index.d.ts +3 -0
  16. package/dist/DataGrid/index.js +7 -0
  17. package/dist/DataGrid-AQKPJD7W.css +482 -0
  18. package/dist/HuePicker/index.js +11 -4
  19. package/dist/LayersList/index.js +2 -2
  20. package/dist/LockedLabel/LockedLabel.d.ts +34 -0
  21. package/dist/LockedLabel/index.d.ts +3 -0
  22. package/dist/LockedLabel/index.js +3 -0
  23. package/dist/LockedLabel-VQEGEB7G.css +16 -0
  24. package/dist/MarkdownEditor/index.js +8 -5
  25. package/dist/MergeConflicts/index.js +11 -5
  26. package/dist/PageNote/PageNote.d.ts +14 -0
  27. package/dist/PageNote/index.d.ts +3 -0
  28. package/dist/PageNote/index.js +2 -0
  29. package/dist/PageNote-RHLXH3ML.css +12 -0
  30. package/dist/PropertyList/PropertyList.d.ts +88 -0
  31. package/dist/PropertyList/index.d.ts +3 -0
  32. package/dist/PropertyList/index.js +7 -0
  33. package/dist/PropertyList-SCYM66LL.css +96 -0
  34. package/dist/RelatedRow/RelatedRow.d.ts +27 -0
  35. package/dist/RelatedRow/index.d.ts +3 -0
  36. package/dist/RelatedRow/index.js +9 -0
  37. package/dist/RelatedRow-2FVS6QQA.css +6 -0
  38. package/dist/SectionFrame/SectionFrame.d.ts +76 -0
  39. package/dist/SectionFrame/index.d.ts +3 -0
  40. package/dist/SectionFrame/index.js +7 -0
  41. package/dist/SectionFrame-M62UUVFQ.css +164 -0
  42. package/dist/SegmentedControl/index.js +11 -4
  43. package/dist/SheetColumnEditor/index.js +6 -5
  44. package/dist/SheetGrid/index.js +2 -2
  45. package/dist/SidebarNav/SidebarNav.d.ts +35 -2
  46. package/dist/SidebarNav/index.js +2 -1
  47. package/dist/{SidebarNav-7SGUZYKK.css → SidebarNav-YI74SPDC.css} +10 -0
  48. package/dist/Tabs/Tabs.d.ts +55 -1
  49. package/dist/Tabs/fold.d.ts +54 -0
  50. package/dist/Tabs/index.d.ts +1 -1
  51. package/dist/Tabs/index.js +9 -2
  52. package/dist/Tabs/roving.d.ts +3 -3
  53. package/dist/{Tabs-WIF7457H.css → Tabs-S7F4RWAN.css} +77 -0
  54. package/dist/TagsInput/index.js +1 -1
  55. package/dist/ThemeGallery/index.js +2 -2
  56. package/dist/ThemeSwitcher/index.js +12 -5
  57. package/dist/VersionCompare/index.js +12 -5
  58. package/dist/{chunk-B5J23C73.js → chunk-2PEXZ7L4.js} +1 -1
  59. package/dist/{chunk-TZYFTC4M.js → chunk-2VOHUGUA.js} +1 -1
  60. package/dist/{chunk-2QZ2VPHR.js → chunk-4OK4DX3V.js} +2 -2
  61. package/dist/{chunk-ECGGQX2H.js → chunk-A44YHLCQ.js} +2 -2
  62. package/dist/{chunk-F4LPQA4E.js → chunk-BA32AVKS.js} +1 -1
  63. package/dist/chunk-CV4NES3P.js +9 -0
  64. package/dist/{chunk-PPHTIKZO.js → chunk-E4BOVKNJ.js} +1 -1
  65. package/dist/{chunk-W7PAIVAP.js → chunk-E7QLG3PG.js} +30 -9
  66. package/dist/{chunk-RKKO7QHH.js → chunk-EGMQURBR.js} +5 -4
  67. package/dist/{chunk-GMW4ZHST.js → chunk-EX22Q5SH.js} +2 -2
  68. package/dist/{chunk-F3WZ5AKM.js → chunk-GFYQKMQZ.js} +1 -1
  69. package/dist/{chunk-DYB66CNM.js → chunk-GR4YM7HT.js} +6 -3
  70. package/dist/{chunk-HG5VF3TZ.js → chunk-HMVQQEHW.js} +91 -2
  71. package/dist/chunk-INVSUFJK.js +71 -0
  72. package/dist/{chunk-4LRAJXHL.js → chunk-JSWOXRRE.js} +1 -1
  73. package/dist/{chunk-ZMDYQ2HH.js → chunk-KWWP3D7M.js} +1 -1
  74. package/dist/{chunk-46RL3E54.js → chunk-M6NQ4XGK.js} +1 -1
  75. package/dist/chunk-OHGH7O6T.js +19 -0
  76. package/dist/{chunk-4ISUIS6F.js → chunk-OOC7Q67K.js} +1 -1
  77. package/dist/{chunk-XNXK5MA4.js → chunk-PCT47E7O.js} +1 -1
  78. package/dist/{chunk-YEVG2X5R.js → chunk-SNQRGH4A.js} +1 -1
  79. package/dist/chunk-T6MXORP5.js +116 -0
  80. package/dist/chunk-X4IXXLWM.js +306 -0
  81. package/dist/chunk-XIDD7PJO.js +416 -0
  82. package/dist/chunk-ZUTUI27P.js +21 -0
  83. package/dist/generated/index.d.ts +6 -0
  84. package/dist/generated/index.js +62 -56
  85. package/dist/index.js +62 -56
  86. package/dist/styles.css +1087 -20
  87. package/package.json +3 -3
  88. package/dist/chunk-7SDUKCNW.js +0 -141
  89. package/dist/{chunk-JZPK4IXR.js → chunk-DKNBGL26.js} +1 -1
  90. /package/dist/{chunk-QRLIWCLX.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-VE2MAV42.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,15 +850,48 @@
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
- above it rather than sitting further out. */
879
+ above it rather than sitting further out.
880
+
881
+ THE FOOT IS THE COMPACT STEP. It holds what a reader reaches for rarely (a
882
+ settings link, the engine's state, who they are), so its rows stand on the
883
+ small control step (`--crewlet-rail-foot-row`, 26px, never under the 24px
884
+ target) on a half-step gap and a one-step inset, where the nav above keeps
885
+ its 30px rows. Only heights change: every row keeps its order, columns,
886
+ glyphs and words. */
853
887
  .crewlet-app-shell__rail-foot {
854
- --crewlet-rail-foot-gap: var(--spacing-1);
888
+ --crewlet-rail-foot-gap: calc(var(--spacing-1) / 2);
889
+ --crewlet-rail-foot-row: var(--size-control-sm);
855
890
  flex: none;
856
891
  display: flex;
857
892
  flex-direction: column;
858
893
  gap: var(--crewlet-rail-foot-gap);
859
- padding: var(--spacing-2) var(--size-nav-gutter);
894
+ padding: var(--spacing-1) var(--size-nav-gutter);
860
895
  border-top: 1px solid var(--color-border-default);
861
896
  }
862
897
 
@@ -957,6 +992,14 @@
957
992
  min-width: 14px;
958
993
  }
959
994
 
995
+ /* The foot's own step (see `.crewlet-app-shell__rail-foot`), for its rows and
996
+ for a navigation dropped into it, whose rows keep the rail's columns. */
997
+ .crewlet-app-shell__rail-foot > .crewlet-app-shell__rail-row--action:not(.crewlet-app-shell__rail-row--block),
998
+ .crewlet-app-shell__rail-foot > .crewlet-btn,
999
+ .crewlet-app-shell__rail-foot .crewlet-nav-item__row {
1000
+ min-height: var(--crewlet-rail-foot-row);
1001
+ }
1002
+
960
1003
  /*
961
1004
  * OPEN IS POINTED AT. The row a panel is open from keeps the hover's lift for
962
1005
  * as long as the panel is open, drawn from `aria-expanded` so the picture and
@@ -1193,6 +1236,15 @@
1193
1236
  overflow-y: auto;
1194
1237
  overflow-x: hidden;
1195
1238
  scrollbar-gutter: stable;
1239
+ /*
1240
+ * A SIZE CONTAINER, so a box inside the screen can be as tall as the view
1241
+ * it scrolls in (`100cqb`): a column that sticks beside the screen
1242
+ * (`SectionFrame`), a record bounded by the window. The scroller's size is
1243
+ * the shell's, never its content's, so containing it costs nothing. A box
1244
+ * inside an inline-size container (a card, a stat row) reaches past it to
1245
+ * this one for the block axis.
1246
+ */
1247
+ container-type: size;
1196
1248
  }
1197
1249
 
1198
1250
  /* No focus rule of its own: `main` takes focus only from the skip link, and a
@@ -1210,12 +1262,17 @@
1210
1262
  }
1211
1263
 
1212
1264
  /* 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. */
1265
+ scrolling and the content column takes the height that is left.
1266
+
1267
+ IT KEEPS THE GUTTER RESERVED, like every other screen. The top bar's end
1268
+ inset counts the scroller's gutter (`--crewlet-app-shell-gutter`, measured
1269
+ by the shell), so a fill screen that reserved none put the bar's controls
1270
+ one gutter further out than on the screen beside it: with classic
1271
+ scrollbars, Add seat moved 11px between an org chart and its roster, two
1272
+ tabs of one page. A strip at the end edge of a full-screen canvas is the
1273
+ smaller cost than a bar that moves under the pointer. */
1216
1274
  .crewlet-app-shell--fill .crewlet-app-shell__main {
1217
1275
  overflow: hidden;
1218
- scrollbar-gutter: auto;
1219
1276
  }
1220
1277
 
1221
1278
  .crewlet-app-shell--fill .crewlet-app-shell__content {
@@ -1395,9 +1452,16 @@
1395
1452
  * whatever size of badge a caller hands the row, it is centred where a glyph
1396
1453
  * is, and the row takes the nav row's pad and its glyph-to-word gap.
1397
1454
  */
1455
+ .crewlet-app-shell__rail-foot .crewlet-account-row {
1456
+ --crewlet-account-row-pad: var(--spacing-0);
1457
+ }
1458
+
1398
1459
  .crewlet-app-shell__rail-foot .crewlet-account-row__who {
1399
1460
  --crewlet-hit-area-block-start: calc(var(--crewlet-rail-foot-gap) / 2 + var(--crewlet-account-row-pad));
1400
1461
  gap: calc(var(--spacing-2) + var(--spacing-1) / 2);
1462
+ /* On the foot's compact step: the two lines of name and detail with half a
1463
+ step above and below them, which still clears the avatar. */
1464
+ padding-block: calc(var(--spacing-1) / 2);
1401
1465
  padding-inline-start: var(--size-nav-row-pad);
1402
1466
  }
1403
1467
 
@@ -6810,7 +6874,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
6810
6874
  }
6811
6875
 
6812
6876
 
6813
- /* CatalogTile-TGR2ZZVQ.css */
6877
+ /* CatalogTile-XL4XLFUH.css */
6814
6878
  /*
6815
6879
  * CatalogTile: mark, name and state, one sentence, and a foot with a quiet
6816
6880
  * fact and one action.
@@ -6841,7 +6905,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
6841
6905
 
6842
6906
  .crewlet-catalog-tile__head {
6843
6907
  display: flex;
6844
- align-items: center;
6908
+ align-items: flex-start;
6845
6909
  gap: var(--spacing-3);
6846
6910
  min-width: 0;
6847
6911
  }
@@ -6859,13 +6923,17 @@ a.crewlet-breadcrumb__crumb:focus-visible {
6859
6923
  color: var(--color-text-primary);
6860
6924
  }
6861
6925
 
6862
- /* The name, and under it the state when there is one; centred on the mark
6863
- either way, so a tile with no state is not a tile with a hole in it. */
6926
+ /* The name, and under it the state when there is one. THE NAME STANDS ON ONE
6927
+ LINE ACROSS A ROW whether or not a tile has a state: centred on the mark, a
6928
+ name with a pill under it rose 13px above its stateless neighbour's, so the
6929
+ names of one row stood at two heights. It starts one step below the mark's
6930
+ top edge in every tile instead. */
6864
6931
  .crewlet-catalog-tile__title {
6865
6932
  display: flex;
6866
6933
  flex-direction: column;
6867
6934
  align-items: flex-start;
6868
- justify-content: center;
6935
+ justify-content: flex-start;
6936
+ padding-top: var(--spacing-1);
6869
6937
  gap: var(--spacing-1);
6870
6938
  min-width: 0;
6871
6939
  }
@@ -7014,7 +7082,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
7014
7082
  }
7015
7083
 
7016
7084
 
7017
- /* Charts-MBJG72BS.css */
7085
+ /* Charts-TZ744HT6.css */
7018
7086
  /* The chart kit: a legend, a ranked bar list, a stacked bar, stacked
7019
7087
  columns, an activity strip, a time series and the reading layer they share. Hand-drawn rather than a charting library, for one reason that
7020
7088
  decides it: every mark here reads tokens, in two themes, at the contrast
@@ -7996,6 +8064,124 @@ a.crewlet-breadcrumb__crumb:focus-visible {
7996
8064
  pointer-events: none;
7997
8065
  }
7998
8066
 
8067
+ /* ─── Histogram, a log's own time axis ─────────────────────────── */
8068
+
8069
+ /*
8070
+ * Time runs left to right on this axis in every writing direction, as it does
8071
+ * on every chart, and the ticks are placed on physical sides to match.
8072
+ */
8073
+ .crewlet-histogram {
8074
+ display: flex;
8075
+ flex-direction: column;
8076
+ min-width: 0;
8077
+ direction: ltr;
8078
+ }
8079
+
8080
+ /* The plot's bottom border is the axis line the ticks hang under. */
8081
+ .crewlet-histogram__plot {
8082
+ display: flex;
8083
+ align-items: flex-end;
8084
+ gap: 1px;
8085
+ width: 100%;
8086
+ height: var(--crewlet-histogram-height, 96px);
8087
+ padding: var(--spacing-1) 0;
8088
+ border-bottom: 1px solid var(--color-border-hover);
8089
+ }
8090
+
8091
+ /* The slot is the control, and the whole of it is the target. */
8092
+ .crewlet-histogram__bar {
8093
+ all: unset;
8094
+ flex: 1 1 0;
8095
+ min-width: 2px;
8096
+ height: 100%;
8097
+ display: flex;
8098
+ align-items: flex-end;
8099
+ justify-content: center;
8100
+ }
8101
+
8102
+ button.crewlet-histogram__bar {
8103
+ cursor: pointer;
8104
+ }
8105
+
8106
+ /* A slot draws no edge, so its ring stands off it. `all: unset` takes the
8107
+ baseline ring away; this states it again at a weight the reset cannot
8108
+ out-rank. */
8109
+ .crewlet-histogram__bar:focus-visible {
8110
+ outline: 2px solid var(--color-focus);
8111
+ outline-offset: 2px;
8112
+ }
8113
+
8114
+ /*
8115
+ * A count is data, so it is drawn in the data ramp; the accent is kept for the
8116
+ * bar the reader is pointing at, the selection a click is about to make. The
8117
+ * fill stacks from its foot, so the failed share sits at its bottom. Floors in
8118
+ * pixels: an empty bucket at two, the smallest real count at three.
8119
+ */
8120
+ .crewlet-histogram__fill {
8121
+ display: flex;
8122
+ flex-direction: column;
8123
+ justify-content: flex-end;
8124
+ overflow: hidden;
8125
+ width: 63%;
8126
+ min-width: 2px;
8127
+ max-width: var(--spacing-7);
8128
+ height: var(--crewlet-histogram-fill, 0%);
8129
+ min-height: 3px;
8130
+ background: var(--color-data-1);
8131
+ border-radius: var(--radius-sm) var(--radius-sm) 0 0;
8132
+ transition: background var(--motion-duration-fast) var(--motion-easing-default);
8133
+ }
8134
+
8135
+ .crewlet-histogram__part {
8136
+ display: block;
8137
+ width: 100%;
8138
+ height: var(--crewlet-histogram-part, 0%);
8139
+ background: var(--color-feedback-danger);
8140
+ }
8141
+
8142
+ button.crewlet-histogram__bar:hover > .crewlet-histogram__fill,
8143
+ button.crewlet-histogram__bar:focus-visible > .crewlet-histogram__fill {
8144
+ background: var(--color-brand-accent);
8145
+ }
8146
+
8147
+ /* An empty bucket is a visible floor in the tone an axis is ruled in:
8148
+ present, and plainly not a quantity. */
8149
+ .crewlet-histogram__bar[data-empty] > .crewlet-histogram__fill {
8150
+ min-height: 2px;
8151
+ background: var(--color-border-strong);
8152
+ }
8153
+
8154
+ button.crewlet-histogram__bar[data-empty]:hover > .crewlet-histogram__fill,
8155
+ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fill {
8156
+ background: var(--color-border-strong-hover);
8157
+ }
8158
+
8159
+ /*
8160
+ * The dates under the bars. Absolutely placed, so a tick sits over the bucket
8161
+ * it names; the row states its own height because absolutely placed children
8162
+ * contribute none.
8163
+ */
8164
+ .crewlet-histogram__axis {
8165
+ position: relative;
8166
+ height: calc(var(--font-size-2xs) * var(--font-line-height-normal));
8167
+ margin-top: 2px;
8168
+ }
8169
+
8170
+ .crewlet-histogram__tick {
8171
+ position: absolute;
8172
+ top: 0;
8173
+ font-size: var(--font-size-2xs);
8174
+ color: var(--color-text-tertiary);
8175
+ font-variant-numeric: tabular-nums;
8176
+ white-space: nowrap;
8177
+ }
8178
+
8179
+ @media (prefers-reduced-motion: reduce) {
8180
+ .crewlet-histogram__fill {
8181
+ transition: none;
8182
+ }
8183
+ }
8184
+
7999
8185
 
8000
8186
  /* Checkbox-ALWG3WV2.css */
8001
8187
  /*
@@ -9786,10 +9972,495 @@ a.crewlet-breadcrumb__crumb:focus-visible {
9786
9972
  opacity: 0.5;
9787
9973
  }
9788
9974
 
9789
- .crewlet-dashboard-cover--empty {
9790
- display: flex;
9791
- align-items: center;
9792
- justify-content: center;
9975
+ .crewlet-dashboard-cover--empty {
9976
+ display: flex;
9977
+ align-items: center;
9978
+ justify-content: center;
9979
+ }
9980
+
9981
+
9982
+ /* DataGrid-AQKPJD7W.css */
9983
+ /*
9984
+ * DataGrid: a list as columns, one track list on the grid.
9985
+ *
9986
+ * THE GRID MAKES NO SCROLLPORT OF ITS OWN. `overflow: clip` rounds the rows off
9987
+ * at the corner exactly as `hidden` would, and it is the difference between a
9988
+ * sticky head that works and one that cannot: `hidden` makes a scroll
9989
+ * container, a sticky box is confined to its nearest scrollport, and this one
9990
+ * grows to its rows, so its offset is always 0. The head sticks against the
9991
+ * page's own scroller; an application whose scroller carries a sticky bar of
9992
+ * its own sets `--crewlet-data-grid-sticky-top` to that bar's height.
9993
+ *
9994
+ * THE COLUMNS BELONG TO THE GRID, NOT TO A ROW. The tracks are declared once,
9995
+ * on the grid (its inline `grid-template-columns`), and the head, the body,
9996
+ * the bands and the rows are `subgrid` passthroughs, so a head cell and a cell
9997
+ * twenty rows down size the same track. Everything that is not a row of cells
9998
+ * spans the whole width.
9999
+ */
10000
+
10001
+ .crewlet-data-grid {
10002
+ display: grid;
10003
+ min-width: 0;
10004
+ border: 1px solid var(--color-border-hover);
10005
+ border-radius: var(--radius-md);
10006
+ overflow: clip;
10007
+ background: var(--color-surface-subtle);
10008
+ }
10009
+
10010
+ /*
10011
+ * A CARD'S BODY (`flush`, and every grid straight in a Card or its body, told
10012
+ * or not): the card is the frame, so the grid draws none of its own and one
10013
+ * rule parts it from the card's head. Under the card's header, the header's
10014
+ * own rule is that one.
10015
+ */
10016
+ .crewlet-data-grid[data-flush],
10017
+ .crewlet-card > .crewlet-data-grid,
10018
+ .crewlet-card__body > .crewlet-data-grid {
10019
+ border: 0;
10020
+ border-top: 1px solid var(--color-border-default);
10021
+ border-radius: var(--radius-none);
10022
+ background: transparent;
10023
+ }
10024
+
10025
+ .crewlet-card__header + .crewlet-data-grid {
10026
+ border-top: 0;
10027
+ }
10028
+
10029
+ /* A full-width band by default: the head, the body, the foot, the reset and
10030
+ the empty state, which is the one child when the grid carries no tracks. */
10031
+ .crewlet-data-grid > * {
10032
+ grid-column: 1 / -1;
10033
+ }
10034
+
10035
+ .crewlet-data-grid__head,
10036
+ .crewlet-data-grid__body,
10037
+ .crewlet-data-grid__band,
10038
+ .crewlet-data-grid__row {
10039
+ display: grid;
10040
+ grid-template-columns: subgrid;
10041
+ grid-column: 1 / -1;
10042
+ }
10043
+
10044
+ .crewlet-data-grid__band-head,
10045
+ .crewlet-data-grid__band-foot {
10046
+ grid-column: 1 / -1;
10047
+ }
10048
+
10049
+ /*
10050
+ * The head: a floor at the row height (density shrinks the padding, not the
10051
+ * label), on the raised ground, sticky at the application's offset.
10052
+ */
10053
+ .crewlet-data-grid__head {
10054
+ align-items: center;
10055
+ min-height: var(--size-row-md);
10056
+ border-bottom: 1px solid var(--color-border-hover);
10057
+ background: var(--color-surface-elevated);
10058
+ position: sticky;
10059
+ top: var(--crewlet-data-grid-sticky-top, var(--spacing-0));
10060
+ z-index: var(--z-index-sticky);
10061
+ }
10062
+
10063
+ /*
10064
+ * THE LIST TABLE'S HEAD: the micro-label register every table takes, 11/500
10065
+ * uppercase. A sortable head is a button with its chrome reset; the reset
10066
+ * takes the focus ring with it, so the ring is restated below.
10067
+ */
10068
+ .crewlet-data-grid__th {
10069
+ display: flex;
10070
+ align-items: center;
10071
+ gap: var(--spacing-1);
10072
+ padding: var(--spacing-2) var(--spacing-3);
10073
+ font-size: var(--font-size-2xs);
10074
+ font-weight: var(--font-weight-medium);
10075
+ text-transform: uppercase;
10076
+ letter-spacing: var(--font-letter-spacing-wide);
10077
+ color: var(--color-text-tertiary);
10078
+ cursor: pointer;
10079
+ min-width: 0;
10080
+ transition: color var(--motion-duration-fast) var(--motion-easing-default);
10081
+ }
10082
+
10083
+ .crewlet-data-grid__th--plain {
10084
+ cursor: default;
10085
+ }
10086
+
10087
+ /* A sortable head's control fills the head: the whole cell is the target. */
10088
+ .crewlet-data-grid__sort {
10089
+ all: unset;
10090
+ display: flex;
10091
+ align-items: center;
10092
+ gap: var(--spacing-1);
10093
+ flex: 1 1 auto;
10094
+ min-width: 0;
10095
+ margin: calc(-1 * var(--spacing-2)) calc(-1 * var(--spacing-3));
10096
+ padding: var(--spacing-2) var(--spacing-3);
10097
+ cursor: pointer;
10098
+ }
10099
+
10100
+ .crewlet-data-grid__th--right .crewlet-data-grid__sort {
10101
+ justify-content: flex-end;
10102
+ }
10103
+
10104
+ .crewlet-data-grid__th:not(.crewlet-data-grid__th--plain):hover,
10105
+ .crewlet-data-grid__th--sorted {
10106
+ color: var(--color-text-primary);
10107
+ }
10108
+
10109
+ .crewlet-data-grid__th--right {
10110
+ justify-content: flex-end;
10111
+ }
10112
+
10113
+ .crewlet-data-grid__sort:focus-visible,
10114
+ .crewlet-data-grid__cols-reset:focus-visible {
10115
+ outline: 2px solid var(--color-focus);
10116
+ outline-offset: var(--size-focus-ring-inset-offset);
10117
+ }
10118
+
10119
+ .crewlet-data-grid__body {
10120
+ min-width: 0;
10121
+ }
10122
+
10123
+ .crewlet-data-grid__row {
10124
+ align-items: center;
10125
+ min-height: var(--size-row-md);
10126
+ border-bottom: 1px solid var(--color-border-default);
10127
+ color: inherit;
10128
+ cursor: pointer;
10129
+ /* The containing block for the row's link. */
10130
+ position: relative;
10131
+ transition: background var(--motion-duration-fast) var(--motion-easing-default);
10132
+ }
10133
+
10134
+ /* THE ROW'S OWN LINK, STRETCHED OVER IT, out of flow so it takes no track. */
10135
+ .crewlet-data-grid__row-link {
10136
+ position: absolute;
10137
+ inset: 0;
10138
+ }
10139
+
10140
+ /* A button overlay (a row that acts and has no address) gives up the chrome a
10141
+ button brings, and draws the focus ring inside the row. */
10142
+ button.crewlet-data-grid__row-link {
10143
+ all: unset;
10144
+ position: absolute;
10145
+ inset: 0;
10146
+ cursor: pointer;
10147
+ }
10148
+
10149
+ .crewlet-data-grid__row-link:focus-visible {
10150
+ outline: 2px solid var(--color-focus);
10151
+ outline-offset: var(--size-focus-ring-inset-offset);
10152
+ }
10153
+
10154
+ /*
10155
+ * AND THE CELLS' OWN CONTROLS SIT ABOVE IT: positioned and later in the
10156
+ * document than the overlay, they win the hit test in the same stacking
10157
+ * context, with no z-index to reason about against the sticky head. A cell's
10158
+ * element that is not a link or a button but must take its own clicks (a
10159
+ * refusal sentence a reader selects) carries `data-above-row`.
10160
+ */
10161
+ .crewlet-data-grid__row a:not(.crewlet-data-grid__row-link),
10162
+ .crewlet-data-grid__row button:not(.crewlet-data-grid__row-link),
10163
+ .crewlet-data-grid__row [data-above-row] {
10164
+ position: relative;
10165
+ }
10166
+
10167
+ .crewlet-data-grid__row:last-child {
10168
+ border-bottom: none;
10169
+ }
10170
+
10171
+ .crewlet-data-grid__row:hover {
10172
+ background: var(--color-surface-hover);
10173
+ }
10174
+
10175
+ .crewlet-data-grid__row--selected,
10176
+ .crewlet-data-grid__row--selected:hover {
10177
+ background: var(--color-brand-accent-soft);
10178
+ }
10179
+
10180
+ .crewlet-data-grid__row--cursor {
10181
+ box-shadow: inset 2px 0 0 var(--color-brand-accent);
10182
+ }
10183
+
10184
+ /* A FAILED ROW IS MARKED ON ITS EDGE, not tinted: the status column already
10185
+ says so, and two signals for one fact teach a reader to trust neither. */
10186
+ .crewlet-data-grid__row--failed {
10187
+ box-shadow: inset 2px 0 0 var(--color-feedback-danger-ink);
10188
+ }
10189
+
10190
+ .crewlet-data-grid__cell {
10191
+ padding: var(--spacing-1) var(--spacing-3);
10192
+ font-size: var(--font-size-compact);
10193
+ min-width: 0;
10194
+ display: flex;
10195
+ align-items: center;
10196
+ gap: var(--spacing-2);
10197
+ }
10198
+
10199
+ /*
10200
+ * A SHRINK COLUMN does not wrap inside its capped track, and does not paint
10201
+ * outside it: a nowrap cell narrower than its content would spill over the
10202
+ * column beside it. `clip`, since a scrollport here would cut the sticky head.
10203
+ */
10204
+ .crewlet-data-grid__th--shrink,
10205
+ .crewlet-data-grid__cell--shrink {
10206
+ white-space: nowrap;
10207
+ overflow: clip;
10208
+ }
10209
+
10210
+ .crewlet-data-grid__cell--right {
10211
+ justify-content: flex-end;
10212
+ }
10213
+
10214
+ .crewlet-data-grid__truncate {
10215
+ min-width: 0;
10216
+ overflow: hidden;
10217
+ text-overflow: ellipsis;
10218
+ white-space: nowrap;
10219
+ }
10220
+
10221
+ .crewlet-data-grid__band + .crewlet-data-grid__band {
10222
+ border-top: 1px solid var(--color-border-hover);
10223
+ }
10224
+
10225
+ .crewlet-data-grid__band-head,
10226
+ .crewlet-data-grid__band-foot {
10227
+ display: flex;
10228
+ }
10229
+
10230
+ /* The band row's one cell lays its parts out on the row's own flex line. */
10231
+ .crewlet-data-grid__band-cell {
10232
+ display: contents;
10233
+ }
10234
+
10235
+ .crewlet-data-grid__band-head {
10236
+ display: flex;
10237
+ align-items: center;
10238
+ gap: var(--spacing-2);
10239
+ padding: var(--spacing-2) var(--spacing-3);
10240
+ background: var(--color-surface-elevated);
10241
+ font-size: var(--font-size-xs);
10242
+ font-weight: var(--font-weight-semibold);
10243
+ position: sticky;
10244
+ /* Under the column heads, which are a row tall and parked at the offset;
10245
+ confined to its own band, so it leaves with the band. Above the rows
10246
+ (positioned for the row link) and below the heads. */
10247
+ top: calc(var(--crewlet-data-grid-sticky-top, var(--spacing-0)) + var(--size-row-md));
10248
+ z-index: var(--z-index-raised);
10249
+ }
10250
+
10251
+ /* A SECOND AXIS IS A BAND INSIDE A BAND, inset and quieter, so it does not
10252
+ read as its parent's sibling; and it draws no rule above itself. */
10253
+ .crewlet-data-grid__band .crewlet-data-grid__band > .crewlet-data-grid__band-head {
10254
+ padding-left: calc(var(--spacing-3) + var(--spacing-4));
10255
+ background: var(--color-surface-subtle);
10256
+ font-weight: var(--font-weight-medium);
10257
+ color: var(--color-text-tertiary);
10258
+ }
10259
+
10260
+ .crewlet-data-grid__band .crewlet-data-grid__band + .crewlet-data-grid__band {
10261
+ border-top: none;
10262
+ }
10263
+
10264
+ .crewlet-data-grid__band-count {
10265
+ margin-left: auto;
10266
+ color: var(--color-text-tertiary);
10267
+ font-weight: var(--font-weight-regular);
10268
+ font-variant-numeric: tabular-nums;
10269
+ }
10270
+
10271
+ .crewlet-data-grid__band-foot {
10272
+ padding: var(--spacing-1) var(--spacing-3);
10273
+ font-size: var(--font-size-2xs);
10274
+ color: var(--color-text-tertiary);
10275
+ background: var(--color-surface-elevated);
10276
+ }
10277
+
10278
+ .crewlet-data-grid__band-foot a {
10279
+ color: var(--color-brand-accent-ink);
10280
+ }
10281
+
10282
+ .crewlet-data-grid__band-foot a:hover {
10283
+ color: var(--color-text-primary);
10284
+ }
10285
+
10286
+ .crewlet-data-grid__foot {
10287
+ display: flex;
10288
+ align-items: center;
10289
+ gap: var(--spacing-2);
10290
+ padding: var(--spacing-2) var(--spacing-3);
10291
+ border-top: 1px solid var(--color-border-hover);
10292
+ background: var(--color-surface-elevated);
10293
+ font-size: var(--font-size-xs);
10294
+ }
10295
+
10296
+ .crewlet-data-grid__foot-spacer {
10297
+ flex: 1 1 auto;
10298
+ }
10299
+
10300
+ .crewlet-data-grid__note {
10301
+ font-size: var(--font-size-xs);
10302
+ color: var(--color-text-tertiary);
10303
+ }
10304
+
10305
+ .crewlet-data-grid__cols-reset {
10306
+ all: unset;
10307
+ /* After the reset, which takes `grid-column` too. */
10308
+ grid-column: 1 / -1;
10309
+ padding: var(--spacing-1) var(--spacing-3);
10310
+ font-size: var(--font-size-2xs);
10311
+ color: var(--color-brand-accent-ink);
10312
+ cursor: pointer;
10313
+ text-align: left;
10314
+ }
10315
+
10316
+ /* ---- The column chooser ------------------------------------------------ */
10317
+
10318
+ .crewlet-column-chooser__label {
10319
+ font-size: var(--font-size-2xs);
10320
+ font-weight: var(--font-weight-medium);
10321
+ letter-spacing: var(--font-letter-spacing-wide);
10322
+ text-transform: uppercase;
10323
+ color: var(--color-text-tertiary);
10324
+ }
10325
+
10326
+ /* TWO COLUMNS: a single file of short words makes a menu as tall as the grid
10327
+ has columns. */
10328
+ .crewlet-column-chooser__choices {
10329
+ display: grid;
10330
+ grid-template-columns: repeat(2, minmax(0, 1fr));
10331
+ gap: var(--spacing-1) var(--spacing-3);
10332
+ }
10333
+
10334
+ /* The pointer target is the row, not the 13px box. */
10335
+ .crewlet-column-chooser__choice {
10336
+ display: flex;
10337
+ align-items: center;
10338
+ gap: var(--spacing-2);
10339
+ min-height: var(--size-target-min);
10340
+ font-size: var(--font-size-compact);
10341
+ color: var(--color-text-secondary);
10342
+ cursor: pointer;
10343
+ }
10344
+
10345
+ @media (prefers-reduced-motion: reduce) {
10346
+ .crewlet-data-grid__th,
10347
+ .crewlet-data-grid__row {
10348
+ transition: none;
10349
+ }
10350
+ }
10351
+
10352
+ /* ---- A ROW IS A CARD ON A PHONE -----------------------------------------
10353
+ A GRID IS COLUMNS, AND A PHONE DOES NOT HAVE THEM: the grid clips (for its
10354
+ sticky head), so the columns past the edge were cut off with nothing to
10355
+ scroll to, and a sideways scroller resolves every flexible track to zero. So
10356
+ the head goes and each cell draws its own name beside its value
10357
+ (`data-label`); the subgrid chain is unwound to blocks and each cell is a
10358
+ flex line, label then value. A cell with nothing in it is no line
10359
+ (`:empty`), and a cell that draws a marked absence has content and stays.
10360
+ The sort is in the application's state, so a sorted list still arrives
10361
+ sorted. */
10362
+ @media (width < 640px) {
10363
+ .crewlet-data-grid {
10364
+ display: block;
10365
+ }
10366
+
10367
+ .crewlet-data-grid__head {
10368
+ display: none;
10369
+ }
10370
+
10371
+ .crewlet-data-grid__body,
10372
+ .crewlet-data-grid__band {
10373
+ display: block;
10374
+ }
10375
+
10376
+ .crewlet-data-grid__row {
10377
+ display: block;
10378
+ padding: var(--spacing-2) var(--spacing-3);
10379
+ min-height: 0;
10380
+ }
10381
+
10382
+ /* A FIXED BASIS lines the names up without a track, and the name wraps
10383
+ inside it rather than pushing its value past every other card line. */
10384
+ .crewlet-data-grid__cell {
10385
+ display: flex;
10386
+ align-items: baseline;
10387
+ gap: var(--spacing-3);
10388
+ padding: 1px 0;
10389
+ min-width: 0;
10390
+ }
10391
+
10392
+ .crewlet-data-grid__cell:empty {
10393
+ display: none;
10394
+ }
10395
+
10396
+ .crewlet-data-grid__cell[data-label]::before {
10397
+ content: attr(data-label);
10398
+ flex: 0 0 7rem;
10399
+ overflow-wrap: anywhere;
10400
+ font-size: var(--font-size-2xs);
10401
+ text-transform: uppercase;
10402
+ letter-spacing: var(--font-letter-spacing-wide);
10403
+ color: var(--color-text-tertiary);
10404
+ }
10405
+
10406
+ /* `shrink` and `right` are column shapes, and there are no columns here. */
10407
+ .crewlet-data-grid__cell--shrink,
10408
+ .crewlet-data-grid__cell--right {
10409
+ white-space: normal;
10410
+ justify-content: flex-start;
10411
+ }
10412
+
10413
+ .crewlet-data-grid__cell .crewlet-data-grid__truncate {
10414
+ white-space: normal;
10415
+ overflow: visible;
10416
+ text-overflow: clip;
10417
+ overflow-wrap: anywhere;
10418
+ }
10419
+
10420
+ /* ---- THE COMPACT ROW (`phoneRows="compact"`) ---------------------------
10421
+ TWO LINES, NO LABELS: what the row is, then its marks. One flex run that
10422
+ breaks once: the lead cells first, a zero-height full-width `::after`
10423
+ between them and the rest, then every other cell in column order. */
10424
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__row {
10425
+ display: flex;
10426
+ flex-wrap: wrap;
10427
+ align-items: center;
10428
+ gap: var(--spacing-1) var(--spacing-2);
10429
+ }
10430
+
10431
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__row::after {
10432
+ content: '';
10433
+ order: 1;
10434
+ flex-basis: 100%;
10435
+ height: 0;
10436
+ }
10437
+
10438
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__cell {
10439
+ order: 2;
10440
+ padding: 0;
10441
+ align-items: center;
10442
+ gap: var(--spacing-1);
10443
+ }
10444
+
10445
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__cell[data-lead] {
10446
+ order: 0;
10447
+ }
10448
+
10449
+ /* The title takes the rest of the first line, beside the key. */
10450
+ .crewlet-data-grid[data-phone-rows='compact']
10451
+ .crewlet-data-grid__cell[data-lead]:not(.crewlet-data-grid__cell--shrink) {
10452
+ flex: 1 1 0;
10453
+ min-width: 0;
10454
+ font-weight: var(--font-weight-medium);
10455
+ }
10456
+
10457
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__cell[data-label]::before {
10458
+ content: none;
10459
+ }
10460
+
10461
+ .crewlet-data-grid[data-phone-rows='compact'] .crewlet-data-grid__cell[data-phone-omit] {
10462
+ display: none;
10463
+ }
9793
10464
  }
9794
10465
 
9795
10466
 
@@ -17454,6 +18125,25 @@ button.crewlet-finding-list__row:focus-visible {
17454
18125
  }
17455
18126
 
17456
18127
 
18128
+ /* LockedLabel-VQEGEB7G.css */
18129
+ /*
18130
+ * LockedLabel: a place's words with the key after them. The words keep their
18131
+ * own ink and size; the key takes the quiet step, a step closer to the words
18132
+ * than the words are to anything else.
18133
+ */
18134
+ .crewlet-locked-label {
18135
+ display: inline-flex;
18136
+ align-items: center;
18137
+ gap: var(--spacing-1);
18138
+ min-width: 0;
18139
+ }
18140
+
18141
+ .crewlet-locked-label__key {
18142
+ flex: none;
18143
+ color: var(--color-text-tertiary);
18144
+ }
18145
+
18146
+
17457
18147
  /* MarkdownEditor-WOKV7CLK.css */
17458
18148
  /*
17459
18149
  * Writing markdown (MarkdownEditor.tsx): the bar, the source or its preview,
@@ -20181,6 +20871,21 @@ button.crewlet-finding-list__row:focus-visible {
20181
20871
  }
20182
20872
 
20183
20873
 
20874
+ /* PageNote-RHLXH3ML.css */
20875
+ /*
20876
+ * PageNote: the screen's one quiet sentence. No word alone on its last line
20877
+ * (`pretty`), which reads as a sentence that stopped rather than one that
20878
+ * ended. No margin of its own: the column it stands in sets the gap.
20879
+ */
20880
+ .crewlet-page-note {
20881
+ margin: 0;
20882
+ max-width: var(--size-measure);
20883
+ font-size: var(--font-size-compact);
20884
+ color: var(--color-text-tertiary);
20885
+ text-wrap: pretty;
20886
+ }
20887
+
20888
+
20184
20889
  /* PeopleRail-SZGHZXVT.css */
20185
20890
  /* PeopleRail: a raised column of everybody present, one row a person, the
20186
20891
  name over what they are doing and the controls at the row's end. */
@@ -21221,6 +21926,105 @@ button.crewlet-presence-stack__member:focus-visible {
21221
21926
  }
21222
21927
 
21223
21928
 
21929
+ /* PropertyList-SCYM66LL.css */
21930
+ /*
21931
+ * An object's properties, in sections, on one grid.
21932
+ *
21933
+ * ONE TERM COLUMN DOWN THE WHOLE LIST. Every section is a description list of
21934
+ * its own, laid out as a SUBGRID of this one, so its terms and details sit on
21935
+ * this grid's two tracks and every section's labels start and end where the
21936
+ * others' do. The term track is the description list's own measure,
21937
+ * `--crewlet-description-list-term`, so a page that sets it once lines a list
21938
+ * of properties up with every key-value card on it. Unset, it is the rail's
21939
+ * own: as wide as the longest label, and never under 92px, which a one-word
21940
+ * label ("Due") would otherwise shrink the column to.
21941
+ *
21942
+ * SIDE BY SIDE AT EVERY WIDTH. A list of properties sits in a rail or a card
21943
+ * of its own width, so the window's width says nothing about the room it has;
21944
+ * the description list's narrow step (term over detail) is cancelled below.
21945
+ */
21946
+
21947
+ .crewlet-property-list {
21948
+ display: grid;
21949
+ grid-template-columns: var(--crewlet-description-list-term, minmax(92px, max-content)) minmax(0, 1fr);
21950
+ gap: var(--spacing-2) var(--spacing-3);
21951
+ align-items: baseline;
21952
+ min-width: 0;
21953
+ font-size: var(--font-size-compact);
21954
+ }
21955
+
21956
+ /* Two classes, so the description list's own track and narrow step (one
21957
+ class, in a media query) give way to the subgrid at every width. */
21958
+ .crewlet-property-list > .crewlet-property-list__group {
21959
+ grid-column: 1 / -1;
21960
+ grid-template-columns: subgrid;
21961
+ gap: inherit;
21962
+ font-size: inherit;
21963
+ }
21964
+
21965
+ .crewlet-property-list .crewlet-description-list__detail {
21966
+ margin-bottom: 0;
21967
+ }
21968
+
21969
+ /* THE LABEL IS AN IDENTIFIER (an environment variable's name, a tag's key),
21970
+ set in the mono face; a word stays in the list's own. */
21971
+ .crewlet-property-list__identifier {
21972
+ font-family: var(--font-family-mono);
21973
+ }
21974
+
21975
+ /*
21976
+ * A SECTION'S HEADING, with a hairline above it that separates it from the
21977
+ * section before. The list's FIRST heading has nothing to be separated from,
21978
+ * so it alone loses the hairline; a list that opens with rows of no section
21979
+ * keeps it on its first heading, which has rows above it.
21980
+ */
21981
+ .crewlet-property-list__heading {
21982
+ grid-column: 1 / -1;
21983
+ margin-top: var(--spacing-2);
21984
+ padding-top: var(--spacing-2);
21985
+ border-top: 1px solid var(--color-border-default);
21986
+ color: var(--color-text-tertiary);
21987
+ }
21988
+
21989
+ .crewlet-property-list__heading:first-child {
21990
+ margin-top: 0;
21991
+ padding-top: 0;
21992
+ border-top: none;
21993
+ }
21994
+
21995
+ .crewlet-property-list--eyebrow .crewlet-property-list__heading {
21996
+ font-size: var(--font-size-2xs);
21997
+ font-weight: var(--font-weight-medium);
21998
+ letter-spacing: var(--font-letter-spacing-wide);
21999
+ text-transform: uppercase;
22000
+ }
22001
+
22002
+ .crewlet-property-list--sentence .crewlet-property-list__heading {
22003
+ font-size: var(--font-size-xs);
22004
+ font-weight: var(--font-weight-medium);
22005
+ }
22006
+
22007
+ /* A SECTION NOBODY HAS FILLED IN, said once across both tracks in the words
22008
+ its caller wrote. It is a sentence a reader has to read, so it takes the
22009
+ tertiary rung, never the muted one (a floor for a mark). */
22010
+ .crewlet-property-list__empty {
22011
+ grid-column: 1 / -1;
22012
+ margin: 0;
22013
+ font-size: var(--font-size-xs);
22014
+ color: var(--color-text-tertiary);
22015
+ }
22016
+
22017
+ /* WHO SET IT, under the value rather than beside it: the value is what the
22018
+ reader came for. A line of its own, so a long actor name cannot push the
22019
+ value out of its track. */
22020
+ .crewlet-property-list__set-by {
22021
+ display: block;
22022
+ margin-top: 2px;
22023
+ font-size: var(--font-size-2xs);
22024
+ color: var(--color-text-tertiary);
22025
+ }
22026
+
22027
+
21224
22028
  /* Prose-BTXNFT2Q.css */
21225
22029
  /*
21226
22030
  * Natural language: the proportional face, real leading, a bounded measure.
@@ -21542,6 +22346,15 @@ button.crewlet-presence-stack__member:focus-visible {
21542
22346
  }
21543
22347
 
21544
22348
 
22349
+ /* RelatedRow-2FVS6QQA.css */
22350
+ /* RelatedRow: the glyphs in the quiet ink; everything else is the kit's card. */
22351
+ .crewlet-related-row__glyph {
22352
+ display: inline-flex;
22353
+ flex: none;
22354
+ color: var(--color-text-tertiary);
22355
+ }
22356
+
22357
+
21545
22358
  /* RelativeTime-EBAQPGO2.css */
21546
22359
  /*
21547
22360
  * A relative time is text, so it takes the register around it. Its one rule is
@@ -22326,6 +23139,173 @@ button.crewlet-presence-stack__member:focus-visible {
22326
23139
  }
22327
23140
 
22328
23141
 
23142
+ /* SectionFrame-M62UUVFQ.css */
23143
+ /*
23144
+ * SectionFrame: a column of sections beside the screen, and the one-row
23145
+ * picker it folds to.
23146
+ */
23147
+
23148
+ /* THE FRAME TAKES THE CONTENT COLUMN'S PADDING BACK and gives it to the body,
23149
+ so the column is flush with the sheet and the section keeps the inset. */
23150
+ .crewlet-app-shell__content:has(> .crewlet-section-frame) {
23151
+ min-height: 100%;
23152
+ padding: 0;
23153
+ }
23154
+
23155
+ .crewlet-section-frame {
23156
+ display: grid;
23157
+ flex: 1 1 auto;
23158
+ grid-template-columns: var(--crewlet-section-frame-column) minmax(0, 1fr);
23159
+ min-height: 100%;
23160
+ }
23161
+
23162
+ /*
23163
+ * AS TALL AS THE VIEW, NEVER AS THE GRID. A sticky box moves only inside its
23164
+ * grid area, which the section beside it makes as tall as its content; sized
23165
+ * against that area the column was exactly as tall as the section, had
23166
+ * nowhere to stick, and a wheel over a long section carried the list off the
23167
+ * top. At the view's height (`100cqb`: the shell's scroller is a size
23168
+ * container) it sticks for the whole scroll and a long list scrolls in itself.
23169
+ *
23170
+ * IT KEEPS THE WHEEL AT ITS ENDS. A box whose bottom is below the fold traps
23171
+ * the wheel; this one is exactly the view and always all on screen, so what
23172
+ * chaining would do is move the section beside it at the list's end, which
23173
+ * is not what the pointer is over.
23174
+ */
23175
+ .crewlet-section-frame__nav {
23176
+ position: sticky;
23177
+ top: 0;
23178
+ align-self: start;
23179
+ height: 100cqb;
23180
+ overflow-y: auto;
23181
+ overscroll-behavior: contain;
23182
+ padding: var(--spacing-4) 0;
23183
+ border-right: 1px solid var(--color-border-default);
23184
+ }
23185
+
23186
+ .crewlet-section-frame__body {
23187
+ display: flex;
23188
+ flex-direction: column;
23189
+ gap: var(--spacing-5);
23190
+ min-width: 0;
23191
+ padding: var(--spacing-5) var(--spacing-5) var(--spacing-10);
23192
+ }
23193
+
23194
+ /* BESIDE THE SECTION there is room for the whole list: no toggle, and the
23195
+ list is always drawn. */
23196
+ .crewlet-section-frame__toggle {
23197
+ display: none;
23198
+ }
23199
+
23200
+ /*
23201
+ * FOLDED: one pane, the picker above the section. The picker's row is its
23202
+ * own height and the section takes the rest: two `auto` rows split a short
23203
+ * section's spare height and opened a band of nothing between the picker
23204
+ * and the section it names.
23205
+ */
23206
+ .crewlet-section-frame[data-folded] {
23207
+ grid-template-columns: minmax(0, 1fr);
23208
+ grid-template-rows: auto 1fr;
23209
+ }
23210
+
23211
+ /* IN THE FLOW, as tall as it is, on the section's own gutter: the list it
23212
+ unfolds is part of the page rather than a pane of its own. */
23213
+ .crewlet-section-frame[data-folded] > .crewlet-section-frame__nav {
23214
+ position: static;
23215
+ height: auto;
23216
+ overflow-y: visible;
23217
+ padding: var(--spacing-2) var(--spacing-5);
23218
+ border-right: none;
23219
+ border-bottom: 1px solid var(--color-border-default);
23220
+ }
23221
+
23222
+ /* ONE ROW NAMING WHERE THE READER IS, which unfolds the list. Its glyph and
23223
+ name stand over the glyphs and names of the rows: the rows' own inset,
23224
+ less the toggle's border. */
23225
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__toggle {
23226
+ display: flex;
23227
+ align-items: center;
23228
+ gap: var(--spacing-2);
23229
+ width: 100%;
23230
+ min-height: var(--size-target-min);
23231
+ padding: 0 calc(var(--size-nav-row-pad) - 1px);
23232
+ border: 1px solid var(--color-border-default);
23233
+ border-radius: var(--radius-sm);
23234
+ background: var(--color-surface-elevated);
23235
+ color: var(--color-text-primary);
23236
+ font: inherit;
23237
+ font-weight: var(--font-weight-medium);
23238
+ text-align: left;
23239
+ cursor: pointer;
23240
+ }
23241
+
23242
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__toggle:hover {
23243
+ background: var(--color-surface-hover);
23244
+ }
23245
+
23246
+ /* INSIDE ITS OWN EDGE, as every control that draws one rings. */
23247
+ .crewlet-section-frame__toggle:focus-visible {
23248
+ outline: 2px solid var(--color-focus);
23249
+ outline-offset: var(--size-focus-ring-inset-offset);
23250
+ }
23251
+
23252
+ .crewlet-section-frame__toggle-icon {
23253
+ display: inline-flex;
23254
+ flex: none;
23255
+ }
23256
+
23257
+ .crewlet-section-frame__toggle-name {
23258
+ flex: 1 1 auto;
23259
+ min-width: 0;
23260
+ overflow: hidden;
23261
+ text-overflow: ellipsis;
23262
+ white-space: nowrap;
23263
+ }
23264
+
23265
+ /* "Section ·" BEFORE THE NAME, in the quiet ink, so the row reads as a
23266
+ control holding the other sections rather than as the page's title. */
23267
+ .crewlet-section-frame__toggle-prefix {
23268
+ color: var(--color-text-tertiary);
23269
+ font-weight: var(--font-weight-regular);
23270
+ }
23271
+
23272
+ .crewlet-section-frame__chevron {
23273
+ flex: none;
23274
+ color: var(--color-text-tertiary);
23275
+ }
23276
+
23277
+ .crewlet-section-frame__nav[data-open] .crewlet-section-frame__chevron {
23278
+ transform: rotate(180deg);
23279
+ }
23280
+
23281
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__nav:not([data-open]) .crewlet-section-frame__list {
23282
+ display: none;
23283
+ }
23284
+
23285
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__nav[data-open] .crewlet-section-frame__list {
23286
+ padding-top: var(--spacing-2);
23287
+ }
23288
+
23289
+ /* THE LIST TAKES NO GUTTER OF ITS OWN inside the folded picker, which is
23290
+ inset already: with the rail's gutter on top, its glyphs sat 11px right of
23291
+ the toggle's. */
23292
+ .crewlet-section-frame[data-folded] .crewlet-section-frame__list > .crewlet-sidebar-nav {
23293
+ padding-inline: 0;
23294
+ }
23295
+
23296
+ /* A PHONE'S ONE GUTTER: the section and the picker start where every other
23297
+ screen's content does. */
23298
+ @media (width < 640px) {
23299
+ .crewlet-section-frame__body {
23300
+ padding: var(--spacing-4) var(--spacing-4) var(--spacing-9);
23301
+ }
23302
+
23303
+ .crewlet-section-frame[data-folded] > .crewlet-section-frame__nav {
23304
+ padding-inline: var(--spacing-4);
23305
+ }
23306
+ }
23307
+
23308
+
22329
23309
  /* SegmentedControl-B7XCUOML.css */
22330
23310
  /*
22331
23311
  * SegmentedControl: the pill row, drawn with the Tabs classes.
@@ -24383,7 +25363,7 @@ svg.crewlet-select__chevron {
24383
25363
  }
24384
25364
 
24385
25365
 
24386
- /* SidebarNav-7SGUZYKK.css */
25366
+ /* SidebarNav-YI74SPDC.css */
24387
25367
  /*
24388
25368
  * The rail's navigation.
24389
25369
  *
@@ -24813,6 +25793,16 @@ svg.crewlet-select__chevron {
24813
25793
  }
24814
25794
  }
24815
25795
 
25796
+ /*
25797
+ * A GROUP THE READER HOLDS NONE OF: the key once, after its label (see
25798
+ * `NavGroup`'s `locked`), and its resting rows in the quiet ink, so a closed
25799
+ * column reads as closed at a glance without a key on every row. A pointed
25800
+ * row and the reader's own still lift to the primary step, as every row does.
25801
+ */
25802
+ .crewlet-nav-group--locked .crewlet-nav-item__row:not([aria-current]):not(:hover) {
25803
+ color: var(--color-text-tertiary);
25804
+ }
25805
+
24816
25806
 
24817
25807
  /* Skeleton-V735HRGM.css */
24818
25808
  /*
@@ -27609,7 +28599,7 @@ b.crewlet-switcher__match {
27609
28599
  }
27610
28600
 
27611
28601
 
27612
- /* Tabs-WIF7457H.css */
28602
+ /* Tabs-S7F4RWAN.css */
27613
28603
  /*
27614
28604
  * The pill register: Tabs and SegmentedControl.
27615
28605
  *
@@ -28012,6 +29002,83 @@ b.crewlet-switcher__match {
28012
29002
  display: contents;
28013
29003
  }
28014
29004
 
29005
+ /* ─── Fold (overflow: menu) ───────────────────────────────────── */
29006
+ /*
29007
+ * THE ROW NEVER SCROLLS: what does not fit has already left it for "More".
29008
+ * A scroll with its bar hidden cut a whole tab off at a phone's edge with
29009
+ * nothing to say it was there, and a fade at the edge is too quiet to read as
29010
+ * "there is more"; a menu that says More is not.
29011
+ */
29012
+ .crewlet-tabs--fold {
29013
+ position: relative;
29014
+ min-width: 0;
29015
+ overflow: visible;
29016
+ }
29017
+
29018
+ /*
29019
+ * A FOLDED ITEM STAYS IN THE DOCUMENT, out of the flow and invisible, so it
29020
+ * can be measured again when the row grows. Pinned to the row's start, inside
29021
+ * it, so it can never widen the page. A tab, "More" with nothing in it, and a
29022
+ * note with no room alike.
29023
+ */
29024
+ .crewlet-tabs--fold > .crewlet-tabs__tab.is-folded,
29025
+ .crewlet-tabs__more.is-folded,
29026
+ .crewlet-tabs__note.is-folded {
29027
+ position: absolute;
29028
+ inset-block-start: 0;
29029
+ inset-inline-start: 0;
29030
+ visibility: hidden;
29031
+ pointer-events: none;
29032
+ }
29033
+
29034
+ /* "More" is the quiet menu button, centred on the tabs' line. */
29035
+ .crewlet-tabs__more {
29036
+ display: inline-flex;
29037
+ flex: none;
29038
+ align-items: center;
29039
+ }
29040
+
29041
+ /* The note sits at the row's far end, a sentence about every tab and never
29042
+ one of them. */
29043
+ .crewlet-tabs__note {
29044
+ flex: none;
29045
+ align-self: center;
29046
+ margin-inline-start: auto;
29047
+ font-size: var(--font-size-xs);
29048
+ color: var(--color-text-tertiary);
29049
+ white-space: nowrap;
29050
+ }
29051
+
29052
+ .crewlet-tabs__trailing {
29053
+ display: inline-flex;
29054
+ flex: none;
29055
+ align-items: center;
29056
+ }
29057
+
29058
+ /*
29059
+ * A TAB LIST HOLDS TABS ALONE, so its "More" stands beside it in a box. The
29060
+ * row is as wide as the tabs it draws, and the underline's rule is the box's,
29061
+ * painted on its last pixel row (the one the row's own border sits on), so
29062
+ * it runs on under "More" to the edge.
29063
+ */
29064
+ .crewlet-tabs-fold {
29065
+ position: relative;
29066
+ display: flex;
29067
+ align-items: stretch;
29068
+ gap: var(--spacing-2);
29069
+ min-width: 0;
29070
+ }
29071
+
29072
+ .crewlet-tabs-fold > .crewlet-tabs {
29073
+ flex: 0 1 auto;
29074
+ width: auto;
29075
+ min-width: 0;
29076
+ }
29077
+
29078
+ .crewlet-tabs-fold--underline {
29079
+ box-shadow: inset 0 -1px 0 var(--color-border-default);
29080
+ }
29081
+
28015
29082
  /*
28016
29083
  * The slider ARRIVES rather than travels, and a chip changes without a fade.
28017
29084
  * The indicator still moves; what stops is the animation between the two