anentrypoint-design 0.0.207 → 0.0.209
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.
- package/app-shell.css +358 -96
- package/chat.css +99 -26
- package/colors_and_type.css +34 -1
- package/dist/247420.css +490 -123
- package/dist/247420.js +14 -14
- package/package.json +4 -2
- package/src/components/agent-chat.js +8 -2
- package/src/components/chat.js +26 -9
- package/src/components/content.js +28 -3
- package/src/components/context-pane.js +9 -9
- package/src/components/files-modals.js +3 -3
- package/src/components/files.js +181 -30
- package/src/components/freddie.js +25 -25
- package/src/components/sessions.js +37 -23
- package/src/components/shell.js +7 -1
- package/src/components/theme-toggle.js +12 -5
- package/src/components.js +1 -1
package/app-shell.css
CHANGED
|
@@ -143,8 +143,8 @@ pre {
|
|
|
143
143
|
margin: 0;
|
|
144
144
|
border-radius: var(--r-3);
|
|
145
145
|
}
|
|
146
|
-
pre .k { color: var(--mascot); }
|
|
147
|
-
pre .s { color: var(--
|
|
146
|
+
pre .k { color: var(--code-str-alt, var(--mascot)); }
|
|
147
|
+
pre .s { color: var(--code-string, var(--green)); }
|
|
148
148
|
pre .c { color: var(--fg-3); }
|
|
149
149
|
pre .n { color: var(--green-2); }
|
|
150
150
|
|
|
@@ -386,13 +386,21 @@ body.canvas-host { background: transparent !important; }
|
|
|
386
386
|
width: 100%;
|
|
387
387
|
min-height: var(--app-status-h);
|
|
388
388
|
padding: 10px var(--pad-x);
|
|
389
|
-
|
|
389
|
+
/* Status chrome is prose, not code - mono is reserved for code/paths. */
|
|
390
|
+
font-family: var(--ff-body); font-size: var(--fs-xs);
|
|
390
391
|
color: var(--fg-3);
|
|
391
392
|
border-top: 1px solid var(--rule);
|
|
392
393
|
}
|
|
393
|
-
.app-status .item { color: inherit; }
|
|
394
|
+
.app-status .item { color: inherit; white-space: nowrap; }
|
|
394
395
|
.app-status .item:first-of-type { color: var(--accent); }
|
|
395
396
|
.app-status .spread { flex: 1; }
|
|
397
|
+
/* The status bar NEVER wraps: at narrow widths the trailing items (hints,
|
|
398
|
+
agent target) drop in priority order instead of breaking mid-word onto a
|
|
399
|
+
second line. */
|
|
400
|
+
.app-status { flex-wrap: nowrap; overflow: hidden; }
|
|
401
|
+
@media (max-width: 1100px) {
|
|
402
|
+
.app-status .item:last-of-type:not(:only-of-type) { display: none; }
|
|
403
|
+
}
|
|
396
404
|
|
|
397
405
|
/* ============================================================
|
|
398
406
|
Primitives
|
|
@@ -439,7 +447,8 @@ body.canvas-host { background: transparent !important; }
|
|
|
439
447
|
.ds-icon-btn-ghost:hover { background: var(--bg-2); }
|
|
440
448
|
.ds-icon-btn-primary { background: var(--accent); color: var(--accent-fg); }
|
|
441
449
|
.ds-icon-btn-primary:hover { background: var(--fg); color: var(--bg); }
|
|
442
|
-
|
|
450
|
+
/* warn = destructive ACTION tone; flame stays exclusively error STATUS. */
|
|
451
|
+
.ds-icon-btn-danger { background: var(--warn); color: var(--paper); }
|
|
443
452
|
.ds-icon-btn-danger:hover { filter: brightness(1.1); }
|
|
444
453
|
.ds-icon-btn:active { transform: translateY(1px); }
|
|
445
454
|
.ds-icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
@@ -503,21 +512,25 @@ body.canvas-host { background: transparent !important; }
|
|
|
503
512
|
============================================================ */
|
|
504
513
|
.panel {
|
|
505
514
|
background: var(--panel-1, var(--bg-2));
|
|
506
|
-
border
|
|
515
|
+
border: var(--bw-hair) solid var(--rule);
|
|
516
|
+
border-radius: var(--r-2);
|
|
507
517
|
margin: 0 0 var(--space-5);
|
|
508
518
|
padding: var(--space-3);
|
|
509
|
-
box-shadow: var(--panel-shadow);
|
|
510
519
|
position: relative;
|
|
511
520
|
}
|
|
512
521
|
.panel.panel-inline { background: var(--bg-2); padding: var(--space-3) var(--space-3); }
|
|
513
522
|
.panel.panel-wide { background: transparent; }
|
|
514
523
|
.panel-head {
|
|
515
524
|
display: flex; align-items: baseline; justify-content: space-between;
|
|
516
|
-
|
|
525
|
+
/* Shares the .panel-body 16px side padding so the caps label and the body
|
|
526
|
+
rows sit on ONE left axis (the old 24/32 padding was authored for the
|
|
527
|
+
pre-padding .panel-wide era and indented the label 16px past its content). */
|
|
528
|
+
padding: var(--space-2) var(--space-3);
|
|
517
529
|
font-size: var(--fs-xs); font-weight: 600;
|
|
518
530
|
color: var(--fg-3);
|
|
519
531
|
letter-spacing: var(--tr-caps); text-transform: uppercase;
|
|
520
532
|
}
|
|
533
|
+
.panel.panel-wide .panel-head { padding-left: 0; padding-right: 0; }
|
|
521
534
|
.panel-head > :last-child {
|
|
522
535
|
font-weight: 500; color: var(--fg-3);
|
|
523
536
|
font-family: var(--ff-mono); letter-spacing: 0;
|
|
@@ -585,6 +598,12 @@ body.canvas-host { background: transparent !important; }
|
|
|
585
598
|
.row .code { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }
|
|
586
599
|
.row .title { font-family: var(--ff-body); font-weight: 600; font-size: var(--fs-lg); line-height: var(--lh-snug, 1.3); display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; min-width: 0; }
|
|
587
600
|
.row .title .sub { font-family: var(--ff-body); font-weight: 400; font-size: var(--fs-sm); color: var(--fg-3); }
|
|
601
|
+
/* App typescale: list rows are quiet working chrome (the 18px/600 default is a
|
|
602
|
+
marketing-surface voice). One size for ALL app list rows - matches
|
|
603
|
+
.ds-file-row/.ds-session-title at fs-sm/500; values mirror the kit's own
|
|
604
|
+
mobile block below. Marketing pages without data-typescale keep the default. */
|
|
605
|
+
[data-typescale="app"] .row { padding: 12px 16px; }
|
|
606
|
+
[data-typescale="app"] .row .title { font-size: var(--fs-sm); font-weight: 500; }
|
|
588
607
|
.row .sub { font-family: var(--ff-body); font-weight: 400; font-size: var(--fs-sm); color: var(--fg-3); }
|
|
589
608
|
.row .meta { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; align-self: center; }
|
|
590
609
|
/* WorksList meta pairs a label with a disclosure chevron, inline-aligned. */
|
|
@@ -895,10 +914,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
895
914
|
gap: 3px;
|
|
896
915
|
}
|
|
897
916
|
.ds-file-row {
|
|
898
|
-
|
|
899
|
-
gap: 10px; padding: 10px 12px;
|
|
917
|
+
gap: 8px; padding: 10px 12px;
|
|
900
918
|
font-size: var(--fs-xs);
|
|
901
919
|
}
|
|
920
|
+
.ds-file-open { gap: 10px; }
|
|
902
921
|
/* On mobile, fold meta under the title and keep actions inline. */
|
|
903
922
|
.ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
|
|
904
923
|
.ds-file-row .ds-file-actions { opacity: 1; }
|
|
@@ -906,6 +925,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
906
925
|
reachable by touch (cohesion sweep). */
|
|
907
926
|
.ds-file-act, .ds-file-sort-btn, .ds-crumb-seg { min-height: 44px; }
|
|
908
927
|
.ds-file-filter-input { min-height: 44px; }
|
|
928
|
+
.ds-file-check, .ds-file-selectall, .ds-density-btn { min-height: 44px; min-width: 44px; }
|
|
909
929
|
|
|
910
930
|
/* Chat */
|
|
911
931
|
.chat-stack { max-width: 100%; min-width: 0; }
|
|
@@ -1029,8 +1049,8 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1029
1049
|
padding: 12px 18px; font-size: var(--fs-sm);
|
|
1030
1050
|
}
|
|
1031
1051
|
|
|
1032
|
-
/* Panel */
|
|
1033
|
-
.panel-head { padding: var(--space-
|
|
1052
|
+
/* Panel - keep the head on the body's left axis at laptop widths too. */
|
|
1053
|
+
.panel-head { padding: var(--space-2) var(--space-3); }
|
|
1034
1054
|
.panel-body { padding: var(--space-2) var(--space-3); }
|
|
1035
1055
|
|
|
1036
1056
|
/* Hero — fluid base font-size; only width unconstrained on tablet. */
|
|
@@ -1102,13 +1122,15 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1102
1122
|
|
|
1103
1123
|
/* Listing wrapper holds the optional filter + sort header above the grid. */
|
|
1104
1124
|
.ds-file-listing { display: flex; flex-direction: column; gap: var(--space-2); min-height: 0; }
|
|
1105
|
-
|
|
1125
|
+
/* The quick filter is a compact control, not a full-width form row - a giant
|
|
1126
|
+
input above the grid reads as a search page and costs fold height. */
|
|
1127
|
+
.ds-file-filter { padding: 0 0 var(--space-1); display: flex; justify-content: flex-end; }
|
|
1106
1128
|
.ds-file-filter-input {
|
|
1107
|
-
width: 100
|
|
1129
|
+
width: min(280px, 100%); padding: 6px 12px; font-size: var(--fs-sm);
|
|
1108
1130
|
background: var(--bg); color: var(--fg);
|
|
1109
|
-
border: var(--bw-hair) solid var(--rule); border-radius: var(--r-
|
|
1131
|
+
border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
|
|
1110
1132
|
}
|
|
1111
|
-
.ds-file-filter-input:focus-visible { outline: 2px
|
|
1133
|
+
.ds-file-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
|
|
1112
1134
|
.ds-file-sort { display: flex; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); }
|
|
1113
1135
|
.ds-file-sort-btn {
|
|
1114
1136
|
font-size: var(--fs-tiny); font-family: var(--ff-mono); color: var(--fg-3);
|
|
@@ -1120,6 +1142,16 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1120
1142
|
|
|
1121
1143
|
/* Skeleton shimmer rows shown while a directory loads. */
|
|
1122
1144
|
.ds-file-row-skeleton { cursor: default; pointer-events: none; }
|
|
1145
|
+
/* In-place refresh: dim the populated grid instead of swapping it for shimmer
|
|
1146
|
+
rows (the rows stay; the round-trip reads as a settle, not a reload). */
|
|
1147
|
+
.ds-file-grid.is-refreshing { opacity: .6; }
|
|
1148
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
1149
|
+
.ds-file-grid { transition: opacity .15s var(--ease); }
|
|
1150
|
+
}
|
|
1151
|
+
/* EventList loading skeleton (shares the .ds-skel shimmer base above). */
|
|
1152
|
+
.ds-event-row-skeleton { display: flex; align-items: center; gap: var(--space-3); padding: 12px 16px; pointer-events: none; }
|
|
1153
|
+
.ds-skel-rank { height: 12px; width: 2.5ch; }
|
|
1154
|
+
.ds-event-state { padding: var(--space-2) 16px; }
|
|
1123
1155
|
.ds-skel { display: inline-block; border-radius: var(--r-1); background: var(--bg-2); position: relative; overflow: hidden; }
|
|
1124
1156
|
.ds-skel::after {
|
|
1125
1157
|
content: ''; position: absolute; inset: 0;
|
|
@@ -1132,10 +1164,13 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1132
1164
|
@keyframes ds-skel-shimmer { 100% { transform: translateX(100%); } }
|
|
1133
1165
|
@media (prefers-reduced-motion: reduce) { .ds-skel::after { animation: none; } }
|
|
1134
1166
|
|
|
1135
|
-
/* File row — linear layout (icon · title · meta · actions)
|
|
1167
|
+
/* File row — linear layout (checkbox? · open-button[code · icon · title · meta] · actions).
|
|
1168
|
+
The row is a flex strip; the open <button> is the stretching member and lays
|
|
1169
|
+
out the entry's own columns. It needs a full reset (UA button chrome off)
|
|
1170
|
+
because FileRow wraps the row content in a real button for native keyboard
|
|
1171
|
+
semantics. */
|
|
1136
1172
|
.ds-file-row {
|
|
1137
|
-
display:
|
|
1138
|
-
gap: 14px; align-items: center;
|
|
1173
|
+
display: flex; align-items: center; gap: 10px;
|
|
1139
1174
|
padding: 11px 16px; background: var(--bg);
|
|
1140
1175
|
border: var(--bw-hair) solid transparent;
|
|
1141
1176
|
border-radius: var(--r-2); color: var(--fg);
|
|
@@ -1144,6 +1179,14 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1144
1179
|
border-color var(--dur-snap) var(--ease),
|
|
1145
1180
|
transform var(--dur-snap) var(--ease);
|
|
1146
1181
|
}
|
|
1182
|
+
.ds-file-open {
|
|
1183
|
+
display: flex; align-items: center; gap: 14px;
|
|
1184
|
+
flex: 1 1 auto; min-width: 0;
|
|
1185
|
+
background: none; border: 0; padding: 0; margin: 0;
|
|
1186
|
+
color: inherit; font: inherit; text-align: left; cursor: pointer;
|
|
1187
|
+
}
|
|
1188
|
+
.ds-file-open[disabled] { cursor: default; }
|
|
1189
|
+
.ds-file-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-1); }
|
|
1147
1190
|
.ds-file-row:hover {
|
|
1148
1191
|
background: var(--bg-2);
|
|
1149
1192
|
border-color: var(--rule);
|
|
@@ -1157,7 +1200,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1157
1200
|
.ds-file-row[data-file-type="code"] { border-left-width: 3px; border-left-color: var(--green-2); }
|
|
1158
1201
|
.ds-file-row[data-file-type="text"] { border-left-width: 3px; border-left-color: var(--ink-3); }
|
|
1159
1202
|
.ds-file-row[data-file-type="archive"] { border-left-width: 3px; border-left-color: var(--flame); }
|
|
1160
|
-
.ds-file-row[data-file-type="document"] { border-left-width: 3px; border-left-color: var(--sun); }
|
|
1203
|
+
.ds-file-row[data-file-type="document"] { border-left-width: 3px; border-left-color: var(--amber, var(--sun)); }
|
|
1161
1204
|
.ds-file-row[data-file-type="symlink"] { border-left-width: 3px; border-left-color: var(--purple); }
|
|
1162
1205
|
.ds-file-row[data-file-type="other"] { border-left-width: 3px; border-left-color: var(--fg-3); }
|
|
1163
1206
|
|
|
@@ -1165,7 +1208,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1165
1208
|
.ds-file-row .title {
|
|
1166
1209
|
font-weight: 500; font-size: var(--fs-sm);
|
|
1167
1210
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
1168
|
-
min-width: 0;
|
|
1211
|
+
min-width: 0; flex: 1 1 auto;
|
|
1169
1212
|
}
|
|
1170
1213
|
.ds-file-row .code {
|
|
1171
1214
|
font-family: var(--ff-mono); font-size: var(--fs-micro);
|
|
@@ -1188,7 +1231,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1188
1231
|
.ds-file-row[data-file-type="audio"] .ds-file-icon { color: var(--sky); }
|
|
1189
1232
|
.ds-file-row[data-file-type="code"] .ds-file-icon { color: var(--green-2); }
|
|
1190
1233
|
.ds-file-row[data-file-type="archive"] .ds-file-icon { color: var(--flame); }
|
|
1191
|
-
.ds-file-row[data-file-type="document"] .ds-file-icon { color: var(--sun); }
|
|
1234
|
+
.ds-file-row[data-file-type="document"] .ds-file-icon { color: var(--amber, var(--sun)); }
|
|
1192
1235
|
|
|
1193
1236
|
/* Row actions — hidden until hover/focus, revealed without layout shift. */
|
|
1194
1237
|
.ds-file-actions {
|
|
@@ -1207,6 +1250,112 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1207
1250
|
.ds-file-act:hover { background: var(--bg-3); color: var(--fg); }
|
|
1208
1251
|
.ds-file-act-warn:hover { background: color-mix(in oklab, var(--warn) 18%, var(--bg)); color: var(--warn); }
|
|
1209
1252
|
|
|
1253
|
+
/* Multi-select — per-row checkbox, header tri-state, bulk action strip. */
|
|
1254
|
+
.ds-file-check {
|
|
1255
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
1256
|
+
min-width: 28px; height: 28px; padding: 0 4px;
|
|
1257
|
+
background: transparent; border: 0; border-radius: var(--r-1);
|
|
1258
|
+
font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3);
|
|
1259
|
+
cursor: pointer;
|
|
1260
|
+
transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
|
|
1261
|
+
}
|
|
1262
|
+
.ds-file-check:hover { background: var(--bg-3); color: var(--fg); }
|
|
1263
|
+
.ds-file-check.is-marked { color: var(--accent); }
|
|
1264
|
+
.ds-file-check:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
1265
|
+
.ds-file-check[disabled] { opacity: 0.4; cursor: default; }
|
|
1266
|
+
.ds-file-row.is-marked { background: var(--accent-tint); border-color: var(--accent); }
|
|
1267
|
+
.ds-file-selectall {
|
|
1268
|
+
display: inline-flex; align-items: center; gap: var(--space-1);
|
|
1269
|
+
font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-2);
|
|
1270
|
+
cursor: pointer; background: none; border: none;
|
|
1271
|
+
padding: var(--space-1); border-radius: var(--r-1);
|
|
1272
|
+
}
|
|
1273
|
+
.ds-file-selectall:hover { background: var(--bg-2); color: var(--fg); }
|
|
1274
|
+
.ds-file-selectall:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
1275
|
+
.ds-file-controls { display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); flex-wrap: wrap; }
|
|
1276
|
+
.ds-file-controls .spread { flex: 1 1 auto; }
|
|
1277
|
+
.ds-file-controls .ds-file-sort { padding: 0; }
|
|
1278
|
+
.ds-bulkbar {
|
|
1279
|
+
display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
|
|
1280
|
+
padding: var(--space-1) var(--space-2);
|
|
1281
|
+
background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
|
|
1282
|
+
}
|
|
1283
|
+
.ds-bulkbar-count { font-size: var(--fs-tiny); color: var(--fg-2); }
|
|
1284
|
+
/* BulkBar is a toolbar (it even declares role=toolbar): compact rect buttons,
|
|
1285
|
+
quiet destructive outline - the app arm-confirms destructive bulk actions
|
|
1286
|
+
via ConfirmDialog, so the strip never needs a loud CTA. */
|
|
1287
|
+
.ds-bulkbar .btn, .ds-bulkbar .btn-primary {
|
|
1288
|
+
padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
|
|
1289
|
+
}
|
|
1290
|
+
.ds-bulkbar .btn { background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2); }
|
|
1291
|
+
.ds-bulkbar .btn:hover { background: var(--bg-2); color: var(--fg); }
|
|
1292
|
+
.ds-bulkbar .btn-primary.danger { background: transparent; color: var(--warn); border: var(--bw-hair) solid var(--warn); }
|
|
1293
|
+
.ds-bulkbar .btn-primary.danger:hover { background: color-mix(in oklab, var(--warn) 12%, transparent); color: var(--warn); }
|
|
1294
|
+
@media (pointer: coarse) {
|
|
1295
|
+
.ds-bulkbar .btn, .ds-bulkbar .btn-primary { min-height: 44px; }
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
/* Density picker — list / compact / thumbnails. */
|
|
1299
|
+
.ds-density {
|
|
1300
|
+
display: inline-flex; gap: 2px; padding: 2px;
|
|
1301
|
+
background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
|
|
1302
|
+
}
|
|
1303
|
+
.ds-density-btn {
|
|
1304
|
+
font-size: var(--fs-tiny); color: var(--fg-2);
|
|
1305
|
+
background: none; border: none; cursor: pointer;
|
|
1306
|
+
padding: 2px var(--space-2); border-radius: calc(var(--r-1) - 2px);
|
|
1307
|
+
transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
|
|
1308
|
+
}
|
|
1309
|
+
.ds-density-btn:hover { color: var(--fg); }
|
|
1310
|
+
.ds-density-btn.active { background: var(--accent-tint); color: var(--accent); }
|
|
1311
|
+
.ds-density-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
1312
|
+
|
|
1313
|
+
/* Compact density — tighter rows for long listings. */
|
|
1314
|
+
.ds-file-grid[data-density="compact"] { gap: 2px; }
|
|
1315
|
+
.ds-file-grid[data-density="compact"] .ds-file-row { padding: 5px 12px; gap: 10px; }
|
|
1316
|
+
.ds-file-grid[data-density="compact"] .ds-file-row .title { font-size: var(--fs-xs); }
|
|
1317
|
+
.ds-file-grid[data-density="compact"] .ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
|
|
1318
|
+
.ds-file-grid[data-density="compact"] .ds-file-icon { width: 20px; height: 20px; font-size: 13px; }
|
|
1319
|
+
|
|
1320
|
+
/* Thumbnail density — tile grid; image entries carry a real lazy thumbnail. */
|
|
1321
|
+
.ds-file-grid-thumb {
|
|
1322
|
+
display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
|
|
1323
|
+
gap: var(--space-3); align-items: start;
|
|
1324
|
+
}
|
|
1325
|
+
.ds-file-cell {
|
|
1326
|
+
position: relative;
|
|
1327
|
+
background: var(--bg); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
|
|
1328
|
+
overflow: hidden;
|
|
1329
|
+
transition: border-color var(--dur-snap) var(--ease), background var(--dur-snap) var(--ease);
|
|
1330
|
+
}
|
|
1331
|
+
.ds-file-cell:hover { border-color: var(--fg-3); }
|
|
1332
|
+
.ds-file-cell.active { border-color: var(--accent); background: var(--accent-tint); }
|
|
1333
|
+
.ds-file-cell.is-marked { border-color: var(--accent); background: var(--accent-tint); }
|
|
1334
|
+
.ds-file-cell.is-locked { opacity: 0.6; }
|
|
1335
|
+
.ds-file-cell-open {
|
|
1336
|
+
display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1);
|
|
1337
|
+
width: 100%; padding: var(--space-1); margin: 0;
|
|
1338
|
+
background: none; border: none; cursor: pointer; color: var(--fg);
|
|
1339
|
+
}
|
|
1340
|
+
.ds-file-cell-open[disabled] { cursor: default; }
|
|
1341
|
+
.ds-file-cell-open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-2); }
|
|
1342
|
+
.ds-file-cell-media {
|
|
1343
|
+
display: flex; align-items: center; justify-content: center;
|
|
1344
|
+
width: 100%; aspect-ratio: 4 / 3;
|
|
1345
|
+
background: var(--bg-2); border-radius: var(--r-1); overflow: hidden;
|
|
1346
|
+
}
|
|
1347
|
+
.ds-file-cell-media .ds-file-icon { width: 34px; height: 34px; font-size: 24px; }
|
|
1348
|
+
.ds-file-cell-thumb { width: 100%; height: 100%; object-fit: cover; }
|
|
1349
|
+
.ds-file-cell-name {
|
|
1350
|
+
font-size: var(--fs-tiny); text-align: left;
|
|
1351
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
1352
|
+
}
|
|
1353
|
+
.ds-file-cell-meta { font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--fg-3); text-align: left; }
|
|
1354
|
+
.ds-file-cell-check {
|
|
1355
|
+
position: absolute; top: 4px; left: 4px; z-index: 1;
|
|
1356
|
+
background: color-mix(in oklab, var(--bg) 78%, transparent);
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1210
1359
|
/* Card mode — opt-in via data-columns; switches the list to a grid. */
|
|
1211
1360
|
.ds-file-grid[data-columns] { display: grid; gap: var(--space-3); }
|
|
1212
1361
|
.ds-file-grid[data-columns="1"] { grid-template-columns: 1fr; }
|
|
@@ -1231,6 +1380,11 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1231
1380
|
.app-main > div > .ds-file-stage,
|
|
1232
1381
|
.app-main .ds-file-stage { padding-top: 0; }
|
|
1233
1382
|
|
|
1383
|
+
/* Full-width files stack: the stage's space-3 vertical beat without its
|
|
1384
|
+
920px cap/auto-margins, so the roots / toolbar / bulkbar / uploads / grid
|
|
1385
|
+
bands keep one consistent rhythm instead of touching edge-to-edge. */
|
|
1386
|
+
.ds-files-stack { display: flex; flex-direction: column; gap: var(--space-3); min-height: 0; }
|
|
1387
|
+
|
|
1234
1388
|
/* Breadcrumb path */
|
|
1235
1389
|
.ds-crumb-path {
|
|
1236
1390
|
display: flex; align-items: center; flex-wrap: wrap; gap: 2px;
|
|
@@ -1251,10 +1405,38 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1251
1405
|
display: flex; align-items: center; justify-content: space-between;
|
|
1252
1406
|
gap: var(--space-2); flex-wrap: wrap;
|
|
1253
1407
|
}
|
|
1408
|
+
/* Dense page header: one row, small heading, single-line muted lede. The
|
|
1409
|
+
working surfaces (files, live, history, settings) lead with content, not a
|
|
1410
|
+
display H1 + paragraph that costs the first 150px of every fold. */
|
|
1411
|
+
.ds-page-header-dense { margin: 0 0 var(--space-3); }
|
|
1412
|
+
.ds-page-header-dense-row { display: flex; align-items: baseline; gap: var(--space-3); min-width: 0; }
|
|
1413
|
+
.ds-page-header-dense-row h1 {
|
|
1414
|
+
margin: 0; font-size: var(--fs-lg); line-height: 1.3; font-weight: 600;
|
|
1415
|
+
letter-spacing: normal; flex: 0 0 auto;
|
|
1416
|
+
}
|
|
1417
|
+
.ds-page-header-dense-lede {
|
|
1418
|
+
flex: 1 1 auto; min-width: 0;
|
|
1419
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
1420
|
+
font-size: var(--fs-sm); color: var(--fg-3);
|
|
1421
|
+
}
|
|
1422
|
+
.ds-page-header-dense .ds-page-header-right { flex: 0 0 auto; margin-left: auto; }
|
|
1254
1423
|
.ds-file-toolbar-left,
|
|
1255
1424
|
.ds-file-toolbar-right {
|
|
1256
1425
|
display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
|
|
1257
1426
|
}
|
|
1427
|
+
/* Toolbar-scoped buttons: quiet, compact, rectangular - a toolbar is chrome,
|
|
1428
|
+
not a CTA row; the stadium pill stays for real page-level actions. */
|
|
1429
|
+
.ds-file-toolbar .btn, .ds-file-toolbar .btn-ghost {
|
|
1430
|
+
padding: 5px 12px; min-height: 32px;
|
|
1431
|
+
border-radius: var(--r-1);
|
|
1432
|
+
font-weight: 500;
|
|
1433
|
+
background: transparent;
|
|
1434
|
+
border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
|
|
1435
|
+
}
|
|
1436
|
+
.ds-file-toolbar .btn:hover, .ds-file-toolbar .btn-ghost:hover { background: var(--bg-2); color: var(--fg); }
|
|
1437
|
+
@media (pointer: coarse) {
|
|
1438
|
+
.ds-file-toolbar .btn, .ds-file-toolbar .btn-ghost { min-height: 44px; }
|
|
1439
|
+
}
|
|
1258
1440
|
.ds-meta-mono {
|
|
1259
1441
|
font-family: var(--ff-mono); font-size: var(--fs-xs);
|
|
1260
1442
|
color: var(--fg-3); letter-spacing: var(--tr-caps);
|
|
@@ -1295,6 +1477,20 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1295
1477
|
0%, 100% { border-color: var(--accent); }
|
|
1296
1478
|
50% { border-color: color-mix(in oklab, var(--accent) 45%, transparent); }
|
|
1297
1479
|
}
|
|
1480
|
+
/* Wrapper form (has children): no permanent chrome - the content renders as if
|
|
1481
|
+
the zone were not there, and the dashed affordance overlays it ONLY while a
|
|
1482
|
+
drag is in flight. */
|
|
1483
|
+
.ds-dropzone--wrap { position: relative; border: none; border-radius: 0; background: transparent; }
|
|
1484
|
+
.ds-dropzone--wrap > .ds-dropzone-inner { display: none; }
|
|
1485
|
+
.ds-dropzone--wrap.dragover > .ds-dropzone-inner {
|
|
1486
|
+
display: flex; position: absolute; inset: 0; z-index: 5;
|
|
1487
|
+
margin: 0; padding: var(--space-3);
|
|
1488
|
+
align-items: center; justify-content: center;
|
|
1489
|
+
background: color-mix(in srgb, var(--bg) 84%, transparent);
|
|
1490
|
+
outline: var(--bw-rule) dashed var(--accent); outline-offset: -6px;
|
|
1491
|
+
border-radius: var(--r-3);
|
|
1492
|
+
}
|
|
1493
|
+
.ds-dropzone--wrap.dragover { animation: none; }
|
|
1298
1494
|
|
|
1299
1495
|
/* Upload progress */
|
|
1300
1496
|
.ds-upload-progress { display: flex; flex-direction: column; gap: 6px; }
|
|
@@ -1488,7 +1684,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1488
1684
|
border-radius: var(--r-pill); color: var(--fg);
|
|
1489
1685
|
font-family: inherit; font-size: var(--fs-xs);
|
|
1490
1686
|
}
|
|
1491
|
-
.ds-filter-input:focus { outline: 2px
|
|
1687
|
+
.ds-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
|
|
1492
1688
|
|
|
1493
1689
|
/* Loading skeleton — placeholder rows while a directory loads. */
|
|
1494
1690
|
.ds-file-grid-loading { display: flex; flex-direction: column; gap: 4px; }
|
|
@@ -1515,44 +1711,19 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1515
1711
|
.ds-file-row[draggable="true"] { cursor: grab; }
|
|
1516
1712
|
.ds-file-row[draggable="true"]:active { cursor: grabbing; }
|
|
1517
1713
|
|
|
1518
|
-
/*
|
|
1714
|
+
/* (A stale duplicate multi-select block used to live here: an absolute-overlay
|
|
1715
|
+
.ds-file-check hidden until hover, plus .ds-file-check.on / .ds-file-row.selected
|
|
1716
|
+
/ .ds-bulk-bar rules NO component ever emits. Being later in source at equal
|
|
1717
|
+
specificity it clobbered the real in-flow checkbox at ~1243 - the shipped
|
|
1718
|
+
multi-select rendered invisible-until-hover with clipped brackets. The live
|
|
1719
|
+
rules are the earlier block; only the still-load-bearing bits remain below.) */
|
|
1519
1720
|
.ds-file-row { position: relative; }
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
display: inline-flex; align-items: center; justify-content: center;
|
|
1524
|
-
border: var(--bw-hair) solid var(--rule); border-radius: 5px;
|
|
1525
|
-
background: var(--bg); color: var(--accent-fg);
|
|
1526
|
-
font-size: var(--fs-micro); line-height: 1; cursor: pointer;
|
|
1527
|
-
opacity: 0; transition: opacity var(--dur-base) var(--ease), background var(--dur-snap) var(--ease);
|
|
1528
|
-
}
|
|
1529
|
-
.ds-file-row:hover .ds-file-check,
|
|
1530
|
-
.ds-file-row:focus-within .ds-file-check,
|
|
1531
|
-
.ds-file-check.on { opacity: 1; }
|
|
1532
|
-
/* Touch / coarse-pointer devices have no hover — keep checkboxes AND the
|
|
1533
|
-
per-row action buttons (rename/delete/download) visible so the file manager
|
|
1534
|
-
is fully reachable without a pointer (e.g. an iPad in landscape). */
|
|
1721
|
+
/* Touch / coarse-pointer devices have no hover — keep the per-row action
|
|
1722
|
+
buttons (rename/delete/download) visible so the file manager is fully
|
|
1723
|
+
reachable without a pointer (e.g. an iPad in landscape). */
|
|
1535
1724
|
@media (hover: none), (pointer: coarse) {
|
|
1536
|
-
.ds-file-check { opacity: 1; }
|
|
1537
1725
|
.ds-file-actions { opacity: 1; }
|
|
1538
1726
|
}
|
|
1539
|
-
.ds-file-check.on { background: var(--accent); border-color: var(--accent); }
|
|
1540
|
-
.ds-file-row.selected {
|
|
1541
|
-
background: var(--accent-tint);
|
|
1542
|
-
border-color: var(--accent);
|
|
1543
|
-
}
|
|
1544
|
-
.ds-file-row.selected:hover { background: color-mix(in oklab, var(--accent) 22%, var(--bg)); }
|
|
1545
|
-
|
|
1546
|
-
.ds-bulk-bar {
|
|
1547
|
-
display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
|
|
1548
|
-
padding: 10px 14px; border-radius: var(--r-2);
|
|
1549
|
-
background: var(--accent-tint);
|
|
1550
|
-
border: var(--bw-hair) solid var(--accent);
|
|
1551
|
-
position: sticky; top: var(--space-2); z-index: 2;
|
|
1552
|
-
}
|
|
1553
|
-
.ds-bulk-count {
|
|
1554
|
-
font-weight: 600; font-size: var(--fs-sm); margin-right: auto;
|
|
1555
|
-
}
|
|
1556
1727
|
|
|
1557
1728
|
/* Keyboard-shortcuts hint — compact two-column legend. */
|
|
1558
1729
|
.ds-shortcuts-hint {
|
|
@@ -1589,12 +1760,19 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1589
1760
|
.ds-segmented .ds-seg-btn:hover { color: var(--fg); }
|
|
1590
1761
|
.ds-segmented .ds-seg-btn.is-on {
|
|
1591
1762
|
background: var(--bg); color: var(--fg);
|
|
1592
|
-
box-shadow: var(--
|
|
1763
|
+
box-shadow: inset 0 0 0 var(--bw-hair, 1px) var(--rule);
|
|
1593
1764
|
}
|
|
1594
1765
|
.ds-theme-toggle.btn {
|
|
1595
1766
|
font-family: var(--ff-mono); font-size: var(--fs-xs);
|
|
1596
1767
|
display: inline-flex; align-items: center; gap: 6px;
|
|
1597
1768
|
}
|
|
1769
|
+
/* CSS-drawn half-disc mark on the compact theme toggle: keeps the control
|
|
1770
|
+
legible when its text label is hidden (icon-only rail strip). */
|
|
1771
|
+
.ds-theme-disc {
|
|
1772
|
+
flex: 0 0 auto; width: 14px; height: 14px; border-radius: 50%;
|
|
1773
|
+
border: var(--bw-hair) solid var(--fg-3);
|
|
1774
|
+
background: linear-gradient(90deg, var(--fg-3) 0 50%, transparent 50% 100%);
|
|
1775
|
+
}
|
|
1598
1776
|
|
|
1599
1777
|
/* ============================================================
|
|
1600
1778
|
Chat kit polish — styles every class emitted by Chat /
|
|
@@ -1775,10 +1953,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1775
1953
|
.chat-bubble.chat-code .token.atrule,
|
|
1776
1954
|
.chat-bubble.chat-code .token.selector { color: var(--accent); }
|
|
1777
1955
|
.chat-bubble.chat-code .token.string,
|
|
1778
|
-
.chat-bubble.chat-code .token.attr-value { color: var(--mascot); }
|
|
1956
|
+
.chat-bubble.chat-code .token.attr-value { color: var(--code-str-alt, var(--mascot)); }
|
|
1779
1957
|
.chat-bubble.chat-code .token.comment { color: var(--fg-3); font-style: italic; }
|
|
1780
1958
|
.chat-bubble.chat-code .token.number,
|
|
1781
|
-
.chat-bubble.chat-code .token.boolean { color: var(--sun); }
|
|
1959
|
+
.chat-bubble.chat-code .token.boolean { color: var(--code-num, var(--sun)); }
|
|
1782
1960
|
.chat-bubble.chat-code .token.punctuation { color: var(--fg-2); }
|
|
1783
1961
|
.chat-bubble.chat-code .token.property,
|
|
1784
1962
|
.chat-bubble.chat-code .token.attr-name { color: var(--sky); }
|
|
@@ -1795,7 +1973,6 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1795
1973
|
.chat-msg:hover .chat-image,
|
|
1796
1974
|
.chat-image:hover {
|
|
1797
1975
|
border-color: color-mix(in oklab, var(--accent) 35%, transparent);
|
|
1798
|
-
box-shadow: 0 4px 16px color-mix(in oklab, var(--fg) 12%, transparent);
|
|
1799
1976
|
}
|
|
1800
1977
|
.chat-image img { display: block; width: 100%; height: auto; max-height: 360px; object-fit: cover; }
|
|
1801
1978
|
.chat-image .cap,
|
|
@@ -1836,7 +2013,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1836
2013
|
border-radius: 12px; overflow: hidden; max-width: min(100%, 480px);
|
|
1837
2014
|
transition: box-shadow 0.12s ease, border-color 0.12s ease;
|
|
1838
2015
|
}
|
|
1839
|
-
.chat-msg:hover .chat-pdf { border-color: color-mix(in oklab, var(--accent) 30%, transparent);
|
|
2016
|
+
.chat-msg:hover .chat-pdf { border-color: color-mix(in oklab, var(--accent) 30%, transparent); }
|
|
1840
2017
|
.chat-pdf-head {
|
|
1841
2018
|
display: flex; align-items: center; gap: 10px; padding: 10px 14px;
|
|
1842
2019
|
background: color-mix(in oklab, var(--fg) 5%, var(--bg-2));
|
|
@@ -1864,7 +2041,6 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1864
2041
|
.chat-link:hover {
|
|
1865
2042
|
background: var(--bg-3);
|
|
1866
2043
|
border-color: color-mix(in oklab, var(--accent) 40%, transparent);
|
|
1867
|
-
box-shadow: 0 2px 12px color-mix(in oklab, var(--fg) 8%, transparent);
|
|
1868
2044
|
}
|
|
1869
2045
|
.chat-link:not(:has(.thumb)):not(:has(img)) { grid-template-columns: 1fr; }
|
|
1870
2046
|
.chat-link .thumb,
|
|
@@ -1949,7 +2125,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1949
2125
|
display: flex; align-items: flex-end; flex-wrap: wrap; gap: var(--space-2);
|
|
1950
2126
|
padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
|
|
1951
2127
|
background: var(--bg);
|
|
1952
|
-
|
|
2128
|
+
/* The composer sits bg-on-bg: the 14% --rule hairline is ~1.3:1 on paper,
|
|
2129
|
+
leaving the primary input near-invisible at rest - use the strong rule. */
|
|
2130
|
+
border: var(--bw-hair) solid var(--rule-strong);
|
|
1953
2131
|
border-radius: var(--r-2);
|
|
1954
2132
|
flex-shrink: 0;
|
|
1955
2133
|
transition: border-color var(--dur-snap) var(--ease), box-shadow var(--dur-snap) var(--ease);
|
|
@@ -1963,7 +2141,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
1963
2141
|
background: none; color: var(--fg);
|
|
1964
2142
|
border: none; border-radius: 0;
|
|
1965
2143
|
font-family: inherit; font-size: var(--fs-sm);
|
|
1966
|
-
|
|
2144
|
+
/* 1.5 is the value that actually renders (a later polish block used to
|
|
2145
|
+
re-declare it; the sizing block now states the truth). */
|
|
2146
|
+
line-height: 1.5; resize: none;
|
|
1967
2147
|
min-height: 28px; max-height: 200px;
|
|
1968
2148
|
box-sizing: border-box; overflow-y: auto;
|
|
1969
2149
|
scrollbar-width: thin;
|
|
@@ -2030,13 +2210,19 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
2030
2210
|
/* ── select primitive ─────────────────────────────────────────────────── */
|
|
2031
2211
|
.ds-select {
|
|
2032
2212
|
width: 100%;
|
|
2033
|
-
|
|
2213
|
+
min-width: 0;
|
|
2214
|
+
padding: 10px 30px 10px 14px; /* right gap clears the chevron */
|
|
2034
2215
|
background: var(--bg-2);
|
|
2035
2216
|
border: 0;
|
|
2036
2217
|
border-radius: var(--r-2);
|
|
2037
2218
|
font-family: inherit;
|
|
2038
2219
|
font-size: var(--fs-sm);
|
|
2039
2220
|
color: var(--fg);
|
|
2221
|
+
/* Clip long option text gracefully - a select that cuts 'Claude Sonnet
|
|
2222
|
+
(latest' mid-parenthesis reads as broken; ellipsis reads as truncated. */
|
|
2223
|
+
text-overflow: ellipsis;
|
|
2224
|
+
white-space: nowrap;
|
|
2225
|
+
overflow: hidden;
|
|
2040
2226
|
appearance: none;
|
|
2041
2227
|
background-image: linear-gradient(45deg, transparent 50%, var(--fg-3) 50%),
|
|
2042
2228
|
linear-gradient(135deg, var(--fg-3) 50%, transparent 50%);
|
|
@@ -2045,15 +2231,12 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
2045
2231
|
background-repeat: no-repeat;
|
|
2046
2232
|
cursor: pointer;
|
|
2047
2233
|
}
|
|
2048
|
-
.ds-select:focus { box-shadow: inset 0 0 0 2px var(--accent); }
|
|
2234
|
+
.ds-select:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
|
|
2049
2235
|
.ds-select:hover { background-color: var(--bg-3); }
|
|
2050
2236
|
|
|
2051
|
-
/* ── chat composer autogrow polish
|
|
2237
|
+
/* ── chat composer autogrow polish (sizing lives in the primary block) ── */
|
|
2052
2238
|
.chat-composer textarea {
|
|
2053
|
-
resize: none;
|
|
2054
|
-
overflow-y: auto;
|
|
2055
2239
|
transition: height var(--dur-snap) var(--ease);
|
|
2056
|
-
line-height: 1.5;
|
|
2057
2240
|
}
|
|
2058
2241
|
.chat-composer textarea:disabled {
|
|
2059
2242
|
opacity: 0.5;
|
|
@@ -2956,42 +3139,121 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
|
|
|
2956
3139
|
.ws-pane-toggle:hover { background: var(--bg-3); color: var(--fg); }
|
|
2957
3140
|
.ws-pane-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
2958
3141
|
|
|
2959
|
-
/*
|
|
2960
|
-
|
|
2961
|
-
|
|
3142
|
+
/* Drawer toggles and the scrim are hidden by default and revealed by the staged
|
|
3143
|
+
media blocks BELOW - these base rules must precede those blocks in source
|
|
3144
|
+
order: at equal specificity the later rule wins regardless of media, so a
|
|
3145
|
+
trailing display:none silently kills every drawer affordance (shipped bug:
|
|
3146
|
+
the mobile drawers were dead because these lines used to sit last). */
|
|
3147
|
+
.ws-drawer-toggle { display: none; align-items: center; justify-content: center; width: 40px; height: 40px; border: none; background: none; color: var(--fg-2); cursor: pointer; border-radius: var(--r-1); }
|
|
3148
|
+
.ws-scrim { display: none; }
|
|
3149
|
+
|
|
3150
|
+
/* Responsive: the columns yield to the CONTENT in stages - the main column is
|
|
3151
|
+
the product, so the right pane gives way first, the sessions list second,
|
|
3152
|
+
and only below 900px does the rail itself drop to a fixed icon strip. Yielded
|
|
3153
|
+
columns stay reachable as overlay drawers (.ws-pane-open / .ws-sessions-open,
|
|
3154
|
+
toggled from the crumb bar) over a shared fade scrim. Before this staging the
|
|
3155
|
+
4-track grid survived down to 901px and crushed the chat thread to ~245px
|
|
3156
|
+
while the 320px context pane kept its full width. */
|
|
3157
|
+
|
|
3158
|
+
/* Stage 1 (<=1480px): drop the pane TRACK; the context pane becomes a right
|
|
3159
|
+
overlay drawer. */
|
|
3160
|
+
@media (max-width: 1480px) {
|
|
3161
|
+
.ws-shell,
|
|
3162
|
+
.ws-shell.ws-no-pane,
|
|
3163
|
+
.ws-shell.ws-pane-collapsed,
|
|
3164
|
+
.ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions) {
|
|
3165
|
+
grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) minmax(0, 1fr);
|
|
3166
|
+
grid-template-areas: "rail sessions content";
|
|
3167
|
+
}
|
|
3168
|
+
.ws-shell.ws-no-sessions,
|
|
3169
|
+
.ws-shell.ws-no-pane.ws-no-sessions,
|
|
3170
|
+
.ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions {
|
|
3171
|
+
grid-template-columns: var(--ws-rail-w) minmax(0, 1fr);
|
|
3172
|
+
grid-template-areas: "rail content";
|
|
3173
|
+
}
|
|
3174
|
+
/* Drawer width is a literal: --ws-pane-w is 0px while pane-collapsed, and a
|
|
3175
|
+
desktop-collapsed pane must still open as a full drawer. */
|
|
3176
|
+
.ws-pane {
|
|
3177
|
+
position: fixed; inset: 0 0 0 auto;
|
|
3178
|
+
width: min(340px, 85vw);
|
|
3179
|
+
z-index: 42; transform: translateX(110%);
|
|
3180
|
+
transition: transform var(--dur-base) var(--ease);
|
|
3181
|
+
}
|
|
3182
|
+
.ws-shell.ws-pane-open .ws-pane { transform: translateX(0); width: min(340px, 85vw); }
|
|
3183
|
+
.ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane { border-left: var(--bw-hair) solid var(--bg-3); }
|
|
3184
|
+
.ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane > :not(.ws-pane-toggle) { display: revert; }
|
|
3185
|
+
/* The desktop collapse chevron is meaningless in drawer mode. */
|
|
3186
|
+
.ws-pane-toggle { display: none; }
|
|
3187
|
+
.ws-pane-drawer-toggle { display: inline-flex; }
|
|
3188
|
+
/* Scrim is always present from this stage down so it FADES with the drawer
|
|
3189
|
+
instead of hard-appearing; pointer-events gate keeps it inert while closed. */
|
|
3190
|
+
.ws-scrim { display: block; opacity: 0; pointer-events: none; position: fixed; inset: 0; z-index: 41; background: color-mix(in srgb, var(--fg) 38%, transparent); transition: opacity var(--dur-base) var(--ease); }
|
|
3191
|
+
.ws-shell.ws-sessions-open .ws-scrim, .ws-shell.ws-pane-open .ws-scrim { opacity: 1; pointer-events: auto; }
|
|
3192
|
+
}
|
|
3193
|
+
|
|
3194
|
+
/* Stage 2 (<=1100px): drop the sessions TRACK; the conversation list becomes a
|
|
3195
|
+
left overlay drawer. */
|
|
3196
|
+
@media (max-width: 1100px) {
|
|
3197
|
+
.ws-shell,
|
|
3198
|
+
.ws-shell.ws-no-pane,
|
|
3199
|
+
.ws-shell.ws-pane-collapsed,
|
|
3200
|
+
.ws-shell.ws-no-sessions,
|
|
3201
|
+
.ws-shell.ws-no-pane.ws-no-sessions,
|
|
3202
|
+
.ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions),
|
|
3203
|
+
.ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions {
|
|
3204
|
+
grid-template-columns: var(--ws-rail-w) minmax(0, 1fr);
|
|
3205
|
+
grid-template-areas: "rail content";
|
|
3206
|
+
}
|
|
3207
|
+
.ws-sessions {
|
|
3208
|
+
position: fixed; inset: 0 auto 0 0;
|
|
3209
|
+
width: min(var(--ws-sessions-w), 80vw);
|
|
3210
|
+
z-index: 42; transform: translateX(-110%);
|
|
3211
|
+
transition: transform var(--dur-base) var(--ease);
|
|
3212
|
+
border-right: var(--bw-hair) solid var(--bg-3);
|
|
3213
|
+
}
|
|
3214
|
+
.ws-shell.ws-sessions-open .ws-sessions { transform: translateX(0); }
|
|
3215
|
+
.ws-sessions-drawer-toggle { display: inline-flex; }
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
/* Stage 3 (<=900px): single content column; the rail drops to a fixed icon-only
|
|
3219
|
+
strip. Labels hide UNCONDITIONALLY here - a 60px rail showing clipped label
|
|
3220
|
+
text ('age', 'Ne') is the worst of both worlds. */
|
|
2962
3221
|
@media (max-width: 900px) {
|
|
2963
3222
|
.ws-shell,
|
|
2964
3223
|
.ws-shell.ws-no-sessions,
|
|
2965
3224
|
.ws-shell.ws-no-pane,
|
|
2966
|
-
.ws-shell.ws-
|
|
2967
|
-
|
|
3225
|
+
.ws-shell.ws-pane-collapsed,
|
|
3226
|
+
.ws-shell.ws-no-pane.ws-no-sessions,
|
|
3227
|
+
.ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions),
|
|
3228
|
+
.ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions {
|
|
3229
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2968
3230
|
grid-template-areas: "content";
|
|
2969
3231
|
}
|
|
2970
3232
|
.ws-rail { position: fixed; inset: 0 auto 0 0; width: var(--ws-rail-w-collapsed); z-index: 40; }
|
|
2971
|
-
.ws-
|
|
2972
|
-
.ws-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
.ws-
|
|
2977
|
-
.ws-
|
|
3233
|
+
.ws-rail .ws-rail-brand,
|
|
3234
|
+
.ws-rail .ws-rail-action-label,
|
|
3235
|
+
.ws-rail .ws-rail-item-label,
|
|
3236
|
+
.ws-rail .ws-rail-item-count,
|
|
3237
|
+
.ws-rail .ds-theme-toggle-label { display: none; }
|
|
3238
|
+
.ws-rail .ws-rail-item, .ws-rail .ws-rail-action { justify-content: center; gap: 0; }
|
|
3239
|
+
.ws-rail .ws-rail-head { justify-content: center; }
|
|
3240
|
+
/* Expand/collapse is meaningless on the icon strip. */
|
|
3241
|
+
.ws-rail-toggle { display: none; }
|
|
3242
|
+
.ws-rail-foot { display: flex; justify-content: center; }
|
|
3243
|
+
.ws-sessions { inset: 0 auto 0 var(--ws-rail-w-collapsed); }
|
|
2978
3244
|
.ws-content { grid-area: content; padding-left: var(--ws-rail-w-collapsed); }
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
.ws-
|
|
2986
|
-
.ws-
|
|
2987
|
-
|
|
2988
|
-
.ws-drawer-toggle { display: inline-flex; }
|
|
3245
|
+
/* The Crumb's narrow collapse elsewhere keys on the .app @container, which
|
|
3246
|
+
does not exist inside WorkspaceShell - mirror it here so the crumb bar
|
|
3247
|
+
cannot overflow a narrow viewport (trail hides, leaf ellipsizes, the
|
|
3248
|
+
right cluster wraps under instead of pushing past the edge). */
|
|
3249
|
+
.ws-crumb { padding-top: 6px; padding-bottom: 6px; }
|
|
3250
|
+
.ws-crumb .app-crumb { flex-wrap: wrap; min-width: 0; }
|
|
3251
|
+
.ws-crumb .app-crumb > .sep, .ws-crumb .app-crumb > span:not(.crumb-right):not(.leaf) { display: none; }
|
|
3252
|
+
.ws-crumb .app-crumb .leaf { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
3253
|
+
.ws-crumb .app-crumb .crumb-right { margin-left: 0; flex-wrap: wrap; min-width: 0; display: inline-flex; }
|
|
2989
3254
|
}
|
|
2990
|
-
/* Drawer toggles are mobile-only chrome; hidden on the desktop grid. */
|
|
2991
|
-
.ws-drawer-toggle { display: none; align-items: center; justify-content: center; width: 40px; height: 40px; border: none; background: none; color: var(--fg-2); cursor: pointer; border-radius: var(--r-1); }
|
|
2992
3255
|
.ws-drawer-toggle:hover { background: var(--bg-2); color: var(--fg); }
|
|
2993
3256
|
.ws-drawer-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
2994
|
-
.ws-scrim { display: none; }
|
|
2995
3257
|
|
|
2996
3258
|
/* ============================================================
|
|
2997
3259
|
Row title highlight, expanded-row actions, filter pills.
|