anentrypoint-design 0.0.199 → 0.0.200
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 +11 -0
- package/chat.css +152 -5
- package/dist/247420.css +163 -5
- package/dist/247420.js +12 -12
- package/package.json +1 -1
- package/src/components/agent-chat.js +31 -3
- package/src/components/chat.js +65 -5
- package/src/components/context-pane.js +11 -1
- package/src/components/files-modals.js +66 -14
- package/src/components/files.js +61 -12
- package/src/components/sessions.js +70 -12
- package/src/components/shell.js +14 -4
- package/src/components.js +2 -2
package/app-shell.css
CHANGED
|
@@ -879,6 +879,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
|
|
|
879
879
|
/* On mobile, fold meta under the title and keep actions inline. */
|
|
880
880
|
.ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
|
|
881
881
|
.ds-file-row .ds-file-actions { opacity: 1; }
|
|
882
|
+
/* H4: floor finger-sized controls so file actions/sort/filter/breadcrumb are
|
|
883
|
+
reachable by touch (cohesion sweep). */
|
|
884
|
+
.ds-file-act, .ds-file-sort-btn, .ds-crumb-seg { min-height: 44px; }
|
|
885
|
+
.ds-file-filter-input { min-height: 44px; }
|
|
882
886
|
|
|
883
887
|
/* Chat */
|
|
884
888
|
.chat-stack { max-width: 100%; min-width: 0; }
|
|
@@ -2767,6 +2771,13 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
|
|
|
2767
2771
|
.ws-shell.ws-no-sessions { grid-template-columns: var(--ws-rail-w) 1fr var(--ws-pane-w); grid-template-areas: "rail content pane"; }
|
|
2768
2772
|
.ws-shell.ws-no-pane.ws-no-sessions { grid-template-columns: var(--ws-rail-w) 1fr; grid-template-areas: "rail content"; }
|
|
2769
2773
|
.ws-shell.ws-no-pane:not(.ws-no-sessions) { grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) 1fr; grid-template-areas: "rail sessions content"; }
|
|
2774
|
+
/* G1 stable frame: when a tab has no pane but asks to keep the column geometry
|
|
2775
|
+
(ws-no-pane + ws-pane-collapsed), KEEP the 4-track grid with the pane track
|
|
2776
|
+
at width 0 instead of collapsing to a 3-track layout - so the shell does not
|
|
2777
|
+
re-flow its column count on tab switch. The pane track stays present (0px),
|
|
2778
|
+
so chat/history/files/live/settings share one geometry. */
|
|
2779
|
+
.ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions) { grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) 1fr var(--ws-pane-w); grid-template-areas: "rail sessions content pane"; }
|
|
2780
|
+
.ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions { grid-template-columns: var(--ws-rail-w) 1fr var(--ws-pane-w); grid-template-areas: "rail content pane"; }
|
|
2770
2781
|
.ws-shell.ws-rail-collapsed { --ws-rail-w: var(--ws-rail-w-collapsed); }
|
|
2771
2782
|
.ws-shell.ws-pane-collapsed { --ws-pane-w: 0px; }
|
|
2772
2783
|
|
package/chat.css
CHANGED
|
@@ -147,10 +147,12 @@
|
|
|
147
147
|
.chat-msg-actions { display: flex; gap: 2px; margin-top: 3px; opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease); }
|
|
148
148
|
.chat-msg:hover .chat-msg-actions, .chat-msg:focus-within .chat-msg-actions { opacity: 1; }
|
|
149
149
|
.chat-msg-action {
|
|
150
|
-
display: inline-flex; align-items: center; justify-content: center;
|
|
151
|
-
width: 26px; height: 26px; padding: 0; cursor: pointer;
|
|
150
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 4px;
|
|
151
|
+
min-width: 26px; height: 26px; padding: 0 6px; cursor: pointer;
|
|
152
152
|
border: none; border-radius: var(--r-1, 4px); background: none; color: var(--fg-3);
|
|
153
|
+
font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
153
154
|
}
|
|
155
|
+
.chat-msg-action-label { font-size: var(--fs-tiny); }
|
|
154
156
|
.chat-msg-action:hover { background: var(--bg-2); color: var(--fg); }
|
|
155
157
|
.chat-msg-action:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; opacity: 1; }
|
|
156
158
|
|
|
@@ -232,12 +234,27 @@
|
|
|
232
234
|
Global status disc — a CSS-drawn status indicator (no text glyph) usable
|
|
233
235
|
outside .agentchat-status (session rows, dashboard cards). Tone via modifier.
|
|
234
236
|
---------------------------------------------------------------------------- */
|
|
237
|
+
/* Single canonical status disc — one source for live/error/connecting/stale
|
|
238
|
+
everywhere (crumb dot, conversation row, dashboard card, composer status).
|
|
239
|
+
The app's index.html disc/pulse override is deleted in favour of this. Only
|
|
240
|
+
the -live disc pulses; -stale is deliberately static (a stuck session must NOT
|
|
241
|
+
read as busy). Pulse colour is derived from --accent via color-mix so it
|
|
242
|
+
tracks the theme instead of a hardcoded rgba. */
|
|
235
243
|
.status-dot-disc {
|
|
236
244
|
display: inline-block; width: 8px; height: 8px; border-radius: 50%;
|
|
237
245
|
background: var(--fg-3); flex: 0 0 auto;
|
|
238
246
|
}
|
|
239
|
-
.status-dot-disc.status-dot-live { background: var(--
|
|
247
|
+
.status-dot-disc.status-dot-live { background: var(--accent); animation: status-disc-pulse 1.8s ease-in-out infinite; }
|
|
240
248
|
.status-dot-disc.status-dot-error { background: var(--flame); }
|
|
249
|
+
.status-dot-disc.status-dot-connecting { background: var(--amber, #d9a93a); }
|
|
250
|
+
.status-dot-disc.status-dot-stale { background: var(--amber, #d9a93a); }
|
|
251
|
+
@keyframes status-disc-pulse {
|
|
252
|
+
0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 55%, transparent); }
|
|
253
|
+
50% { box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent) 0%, transparent); }
|
|
254
|
+
}
|
|
255
|
+
@media (prefers-reduced-motion: reduce) {
|
|
256
|
+
.status-dot-disc.status-dot-live { animation: none; }
|
|
257
|
+
}
|
|
241
258
|
|
|
242
259
|
/* ----------------------------------------------------------------------------
|
|
243
260
|
ConversationList — left-rail "Chats" column.
|
|
@@ -277,8 +294,10 @@
|
|
|
277
294
|
.ds-session-row.rail-green::before, .ds-session-row.rail-purple::before, .ds-session-row.rail-flame::before {
|
|
278
295
|
content: ''; position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px; border-radius: 3px;
|
|
279
296
|
}
|
|
280
|
-
.
|
|
281
|
-
|
|
297
|
+
/* Rail tones MUST match .row.rail-* in app-shell.css so the same semantic state
|
|
298
|
+
reads as one colour across the conversation list and content rows. */
|
|
299
|
+
.ds-session-row.rail-green::before { background: var(--accent); }
|
|
300
|
+
.ds-session-row.rail-purple::before { background: var(--purple-2, #7F18A4); }
|
|
282
301
|
.ds-session-row.rail-flame::before { background: var(--flame); }
|
|
283
302
|
.ds-session-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
284
303
|
.ds-session-title { font-size: var(--fs-sm); color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
@@ -326,3 +345,131 @@
|
|
|
326
345
|
.ds-context .row .meta { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-2); }
|
|
327
346
|
.ds-context .row .sub { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
328
347
|
.ds-context-actions { display: flex; gap: var(--space-2); }
|
|
348
|
+
|
|
349
|
+
/* ============================================================================
|
|
350
|
+
Cohesion sweep (gui-cohesion.js): one-product polish across surfaces.
|
|
351
|
+
============================================================================ */
|
|
352
|
+
|
|
353
|
+
/* --- A1/A2/E3: per-block code copy. The <pre> is wrapped in .chat-code-block
|
|
354
|
+
(position:relative) so the copy button sits top-right and reveals on hover/
|
|
355
|
+
focus-within, matching the .chat-msg-actions pattern. The structured CodeNode
|
|
356
|
+
head + preview head place the button inline (always visible). --- */
|
|
357
|
+
.chat-code-block { position: relative; }
|
|
358
|
+
.chat-code-copy {
|
|
359
|
+
position: absolute; top: 6px; right: 6px;
|
|
360
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
361
|
+
min-width: 48px; min-height: 24px; padding: 2px 8px;
|
|
362
|
+
border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
|
|
363
|
+
background: var(--bg-2); color: var(--fg-2); cursor: pointer;
|
|
364
|
+
font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
365
|
+
opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease);
|
|
366
|
+
}
|
|
367
|
+
.chat-code-block:hover .chat-code-copy, .chat-code-block:focus-within .chat-code-copy { opacity: 1; }
|
|
368
|
+
.chat-code-copy.is-copied { color: var(--accent); border-color: var(--accent); }
|
|
369
|
+
.chat-code-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; opacity: 1; }
|
|
370
|
+
/* Head-placed copy (structured CodeNode + FilePreviewCode) is always visible. */
|
|
371
|
+
.chat-code-head .spread { flex: 1; }
|
|
372
|
+
.chat-code-copy-head { position: static; opacity: 1; }
|
|
373
|
+
|
|
374
|
+
/* --- B1: streaming pre shell — monospaced bubble while a fenced block streams,
|
|
375
|
+
so it does not reflow prose->block on settle. --- */
|
|
376
|
+
.chat-stream-pre pre { margin: 0; white-space: pre-wrap; word-break: break-word; font-family: var(--ff-mono); font-size: var(--fs-sm); }
|
|
377
|
+
|
|
378
|
+
/* --- A5: composer context line (agent / model / cwd at point of typing). --- */
|
|
379
|
+
.chat-composer-context {
|
|
380
|
+
display: block; width: 100%; text-align: left; padding: 4px var(--space-3) 0;
|
|
381
|
+
background: none; border: none; cursor: default; color: var(--fg-3);
|
|
382
|
+
font-family: var(--ff-mono); font-size: var(--fs-tiny);
|
|
383
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
384
|
+
}
|
|
385
|
+
button.chat-composer-context { cursor: pointer; }
|
|
386
|
+
button.chat-composer-context:hover { color: var(--fg-2); }
|
|
387
|
+
button.chat-composer-context:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
388
|
+
|
|
389
|
+
/* --- B2: follow-up chips below the last settled assistant turn. --- */
|
|
390
|
+
.agentchat-followups { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-2) var(--space-3); }
|
|
391
|
+
|
|
392
|
+
/* --- C1: stale/idle dashboard status (static, NOT pulsing). --- */
|
|
393
|
+
.ds-dash-status.is-stale { color: var(--amber, #d9a93a); }
|
|
394
|
+
.ds-dash-status.is-running { color: var(--accent); }
|
|
395
|
+
|
|
396
|
+
/* --- C2: dashboard sort/filter toolbar + stream-state line. --- */
|
|
397
|
+
.ds-dash-toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
|
|
398
|
+
.ds-dash-stream { font-size: var(--fs-tiny); color: var(--fg-3); }
|
|
399
|
+
.ds-dash-stream.is-lost { color: var(--flame); }
|
|
400
|
+
.ds-dash-stream.is-connecting { color: var(--amber, #d9a93a); }
|
|
401
|
+
.ds-dash-header .spread { flex: 1; }
|
|
402
|
+
.ds-dash-errors-toggle {
|
|
403
|
+
padding: 4px 10px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
|
|
404
|
+
border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2);
|
|
405
|
+
cursor: pointer; font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
406
|
+
}
|
|
407
|
+
.ds-dash-errors-toggle.active { background: var(--accent-tint); color: var(--accent); border-color: var(--accent); }
|
|
408
|
+
.ds-dash-errors-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
409
|
+
|
|
410
|
+
/* --- C3: per-card select checkbox. --- */
|
|
411
|
+
.ds-dash-select {
|
|
412
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
413
|
+
min-width: 24px; min-height: 24px; padding: 0; cursor: pointer;
|
|
414
|
+
border: none; background: none; color: var(--fg-3);
|
|
415
|
+
font-family: var(--ff-mono); font-size: var(--fs-sm);
|
|
416
|
+
}
|
|
417
|
+
.ds-dash-select[aria-checked="true"] { color: var(--accent); }
|
|
418
|
+
.ds-dash-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
419
|
+
|
|
420
|
+
/* --- C5: active dashboard card (current conversation). --- */
|
|
421
|
+
.ds-dash-card.is-active { box-shadow: inset 2px 0 0 var(--accent); }
|
|
422
|
+
.ds-dash-card.is-selected { background: var(--accent-tint); }
|
|
423
|
+
.ds-dash-card.is-stale { opacity: .92; }
|
|
424
|
+
|
|
425
|
+
/* --- H3: dashboard live disc pulses; stale/error do not (handled by H1). --- */
|
|
426
|
+
|
|
427
|
+
/* --- C6: per-tab conversation-list caption. --- */
|
|
428
|
+
.ds-session-caption { padding: var(--space-2) var(--space-3) 0; font-size: var(--fs-tiny); color: var(--fg-3); }
|
|
429
|
+
|
|
430
|
+
/* --- F1: context-pane empty state. --- */
|
|
431
|
+
.ds-context-empty { padding: var(--space-4) var(--space-3); color: var(--fg-3); font-size: var(--fs-sm); line-height: 1.5; }
|
|
432
|
+
|
|
433
|
+
/* --- E1: inline file preview pane (split view, non-modal). --- */
|
|
434
|
+
.ds-preview-pane { display: flex; flex-direction: column; min-height: 0; height: 100%; overflow: hidden; }
|
|
435
|
+
.ds-preview-pane:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
436
|
+
.ds-preview-pane .ds-preview-body { flex: 1; min-height: 0; overflow: auto; }
|
|
437
|
+
.ds-preview-pane-empty { align-items: center; justify-content: center; color: var(--fg-3); font-size: var(--fs-sm); }
|
|
438
|
+
.ds-preview-code-wrap { display: flex; flex-direction: column; min-height: 0; }
|
|
439
|
+
.ds-preview-code-head { flex: 0 0 auto; }
|
|
440
|
+
/* --- E2: prev/next stepper in preview head. --- */
|
|
441
|
+
.ds-preview-step { display: inline-flex; gap: 2px; }
|
|
442
|
+
.ds-preview-step .ds-file-act { min-width: 40px; padding: 0 6px; font-family: var(--ff-body); font-size: var(--fs-tiny); }
|
|
443
|
+
|
|
444
|
+
/* --- D1: file grid "show more" row. --- */
|
|
445
|
+
.ds-file-more { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); justify-content: center; }
|
|
446
|
+
.ds-file-more-count { font-size: var(--fs-tiny); color: var(--fg-3); }
|
|
447
|
+
.ds-file-more-btn {
|
|
448
|
+
padding: 4px 12px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
|
|
449
|
+
border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2); cursor: pointer;
|
|
450
|
+
font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
451
|
+
}
|
|
452
|
+
.ds-file-more-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
453
|
+
/* --- D3: locked/no-access file row. --- */
|
|
454
|
+
.ds-file-row.is-locked { opacity: .6; }
|
|
455
|
+
|
|
456
|
+
/* --- D4: roots picker segmented control. --- */
|
|
457
|
+
.ds-roots-picker { display: inline-flex; gap: 2px; padding: 2px; background: var(--bg-2); border-radius: var(--r-1); }
|
|
458
|
+
.ds-roots-tab {
|
|
459
|
+
padding: 4px 10px; min-height: 32px; border: none; border-radius: var(--r-1);
|
|
460
|
+
background: none; color: var(--fg-3); cursor: pointer;
|
|
461
|
+
font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
462
|
+
}
|
|
463
|
+
.ds-roots-tab.active { background: var(--bg); color: var(--fg); }
|
|
464
|
+
.ds-roots-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
465
|
+
|
|
466
|
+
/* --- H4: touch targets. On a coarse pointer / narrow screen the hover-revealed
|
|
467
|
+
action rows are made permanently visible and small controls floor to 44px so
|
|
468
|
+
they are reachable by finger. --- */
|
|
469
|
+
@media (pointer: coarse), (max-width: 640px) {
|
|
470
|
+
.chat-msg-actions { opacity: 1; }
|
|
471
|
+
.chat-code-copy { opacity: 1; }
|
|
472
|
+
.chat-msg-action { min-width: 44px; height: 44px; }
|
|
473
|
+
.ds-dash-select { min-width: 44px; min-height: 44px; }
|
|
474
|
+
.ds-file-more-btn, .ds-roots-tab, .ds-dash-errors-toggle { min-height: 44px; }
|
|
475
|
+
}
|
package/dist/247420.css
CHANGED
|
@@ -1280,6 +1280,10 @@
|
|
|
1280
1280
|
/* On mobile, fold meta under the title and keep actions inline. */
|
|
1281
1281
|
.ds-247420 .ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
|
|
1282
1282
|
.ds-247420 .ds-file-row .ds-file-actions { opacity: 1; }
|
|
1283
|
+
/* H4: floor finger-sized controls so file actions/sort/filter/breadcrumb are
|
|
1284
|
+
reachable by touch (cohesion sweep). */
|
|
1285
|
+
.ds-247420 .ds-file-act, .ds-247420 .ds-file-sort-btn, .ds-247420 .ds-crumb-seg { min-height: 44px; }
|
|
1286
|
+
.ds-247420 .ds-file-filter-input { min-height: 44px; }
|
|
1283
1287
|
|
|
1284
1288
|
/* Chat */
|
|
1285
1289
|
.ds-247420 .chat-stack { max-width: 100%; min-width: 0; }
|
|
@@ -3159,6 +3163,13 @@
|
|
|
3159
3163
|
.ds-247420 .ws-shell.ws-no-sessions { grid-template-columns: var(--ws-rail-w) 1fr var(--ws-pane-w); grid-template-areas: "rail content pane"; }
|
|
3160
3164
|
.ds-247420 .ws-shell.ws-no-pane.ws-no-sessions { grid-template-columns: var(--ws-rail-w) 1fr; grid-template-areas: "rail content"; }
|
|
3161
3165
|
.ds-247420 .ws-shell.ws-no-pane:not(.ws-no-sessions) { grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) 1fr; grid-template-areas: "rail sessions content"; }
|
|
3166
|
+
/* G1 stable frame: when a tab has no pane but asks to keep the column geometry
|
|
3167
|
+
(ws-no-pane + ws-pane-collapsed), KEEP the 4-track grid with the pane track
|
|
3168
|
+
at width 0 instead of collapsing to a 3-track layout - so the shell does not
|
|
3169
|
+
re-flow its column count on tab switch. The pane track stays present (0px),
|
|
3170
|
+
so chat/history/files/live/settings share one geometry. */
|
|
3171
|
+
.ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions) { grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) 1fr var(--ws-pane-w); grid-template-areas: "rail sessions content pane"; }
|
|
3172
|
+
.ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions { grid-template-columns: var(--ws-rail-w) 1fr var(--ws-pane-w); grid-template-areas: "rail content pane"; }
|
|
3162
3173
|
.ds-247420 .ws-shell.ws-rail-collapsed { --ws-rail-w: var(--ws-rail-w-collapsed); }
|
|
3163
3174
|
.ds-247420 .ws-shell.ws-pane-collapsed { --ws-pane-w: 0px; }
|
|
3164
3175
|
|
|
@@ -4967,10 +4978,12 @@
|
|
|
4967
4978
|
.ds-247420 .chat-msg-actions { display: flex; gap: 2px; margin-top: 3px; opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease); }
|
|
4968
4979
|
.ds-247420 .chat-msg:hover .chat-msg-actions, .ds-247420 .chat-msg:focus-within .chat-msg-actions { opacity: 1; }
|
|
4969
4980
|
.ds-247420 .chat-msg-action {
|
|
4970
|
-
display: inline-flex; align-items: center; justify-content: center;
|
|
4971
|
-
width: 26px; height: 26px; padding: 0; cursor: pointer;
|
|
4981
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 4px;
|
|
4982
|
+
min-width: 26px; height: 26px; padding: 0 6px; cursor: pointer;
|
|
4972
4983
|
border: none; border-radius: var(--r-1, 4px); background: none; color: var(--fg-3);
|
|
4984
|
+
font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
4973
4985
|
}
|
|
4986
|
+
.ds-247420 .chat-msg-action-label { font-size: var(--fs-tiny); }
|
|
4974
4987
|
.ds-247420 .chat-msg-action:hover { background: var(--bg-2); color: var(--fg); }
|
|
4975
4988
|
.ds-247420 .chat-msg-action:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; opacity: 1; }
|
|
4976
4989
|
|
|
@@ -5052,12 +5065,27 @@
|
|
|
5052
5065
|
Global status disc — a CSS-drawn status indicator (no text glyph) usable
|
|
5053
5066
|
outside .agentchat-status (session rows, dashboard cards). Tone via modifier.
|
|
5054
5067
|
---------------------------------------------------------------------------- */
|
|
5068
|
+
/* Single canonical status disc — one source for live/error/connecting/stale
|
|
5069
|
+
everywhere (crumb dot, conversation row, dashboard card, composer status).
|
|
5070
|
+
The app's index.html disc/pulse override is deleted in favour of this. Only
|
|
5071
|
+
the -live disc pulses; -stale is deliberately static (a stuck session must NOT
|
|
5072
|
+
read as busy). Pulse colour is derived from --accent via color-mix so it
|
|
5073
|
+
tracks the theme instead of a hardcoded rgba. */
|
|
5055
5074
|
.ds-247420 .status-dot-disc {
|
|
5056
5075
|
display: inline-block; width: 8px; height: 8px; border-radius: 50%;
|
|
5057
5076
|
background: var(--fg-3); flex: 0 0 auto;
|
|
5058
5077
|
}
|
|
5059
|
-
.ds-247420 .status-dot-disc.status-dot-live { background: var(--
|
|
5078
|
+
.ds-247420 .status-dot-disc.status-dot-live { background: var(--accent); animation: status-disc-pulse 1.8s ease-in-out infinite; }
|
|
5060
5079
|
.ds-247420 .status-dot-disc.status-dot-error { background: var(--flame); }
|
|
5080
|
+
.ds-247420 .status-dot-disc.status-dot-connecting { background: var(--amber, #d9a93a); }
|
|
5081
|
+
.ds-247420 .status-dot-disc.status-dot-stale { background: var(--amber, #d9a93a); }
|
|
5082
|
+
@keyframes status-disc-pulse {
|
|
5083
|
+
0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 55%, transparent); }
|
|
5084
|
+
50% { box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent) 0%, transparent); }
|
|
5085
|
+
}
|
|
5086
|
+
@media (prefers-reduced-motion: reduce) {
|
|
5087
|
+
.ds-247420 .status-dot-disc.status-dot-live { animation: none; }
|
|
5088
|
+
}
|
|
5061
5089
|
|
|
5062
5090
|
/* ----------------------------------------------------------------------------
|
|
5063
5091
|
ConversationList — left-rail "Chats" column.
|
|
@@ -5097,8 +5125,10 @@
|
|
|
5097
5125
|
.ds-247420 .ds-session-row.rail-green::before, .ds-247420 .ds-session-row.rail-purple::before, .ds-247420 .ds-session-row.rail-flame::before {
|
|
5098
5126
|
content: ''; position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px; border-radius: 3px;
|
|
5099
5127
|
}
|
|
5100
|
-
|
|
5101
|
-
|
|
5128
|
+
/* Rail tones MUST match .row.rail-* in app-shell.css so the same semantic state
|
|
5129
|
+
reads as one colour across the conversation list and content rows. */
|
|
5130
|
+
.ds-247420 .ds-session-row.rail-green::before { background: var(--accent); }
|
|
5131
|
+
.ds-247420 .ds-session-row.rail-purple::before { background: var(--purple-2, #7F18A4); }
|
|
5102
5132
|
.ds-247420 .ds-session-row.rail-flame::before { background: var(--flame); }
|
|
5103
5133
|
.ds-247420 .ds-session-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
5104
5134
|
.ds-247420 .ds-session-title { font-size: var(--fs-sm); color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
@@ -5147,6 +5177,134 @@
|
|
|
5147
5177
|
.ds-247420 .ds-context .row .sub { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
5148
5178
|
.ds-247420 .ds-context-actions { display: flex; gap: var(--space-2); }
|
|
5149
5179
|
|
|
5180
|
+
/* ============================================================================
|
|
5181
|
+
Cohesion sweep (gui-cohesion.js): one-product polish across surfaces.
|
|
5182
|
+
============================================================================ */
|
|
5183
|
+
|
|
5184
|
+
/* --- A1/A2/E3: per-block code copy. The <pre> is wrapped in .chat-code-block
|
|
5185
|
+
(position:relative) so the copy button sits top-right and reveals on hover/
|
|
5186
|
+
focus-within, matching the .chat-msg-actions pattern. The structured CodeNode
|
|
5187
|
+
head + preview head place the button inline (always visible). --- */
|
|
5188
|
+
.ds-247420 .chat-code-block { position: relative; }
|
|
5189
|
+
.ds-247420 .chat-code-copy {
|
|
5190
|
+
position: absolute; top: 6px; right: 6px;
|
|
5191
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
5192
|
+
min-width: 48px; min-height: 24px; padding: 2px 8px;
|
|
5193
|
+
border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
|
|
5194
|
+
background: var(--bg-2); color: var(--fg-2); cursor: pointer;
|
|
5195
|
+
font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
5196
|
+
opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease);
|
|
5197
|
+
}
|
|
5198
|
+
.ds-247420 .chat-code-block:hover .chat-code-copy, .ds-247420 .chat-code-block:focus-within .chat-code-copy { opacity: 1; }
|
|
5199
|
+
.ds-247420 .chat-code-copy.is-copied { color: var(--accent); border-color: var(--accent); }
|
|
5200
|
+
.ds-247420 .chat-code-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; opacity: 1; }
|
|
5201
|
+
/* Head-placed copy (structured CodeNode + FilePreviewCode) is always visible. */
|
|
5202
|
+
.ds-247420 .chat-code-head .spread { flex: 1; }
|
|
5203
|
+
.ds-247420 .chat-code-copy-head { position: static; opacity: 1; }
|
|
5204
|
+
|
|
5205
|
+
/* --- B1: streaming pre shell — monospaced bubble while a fenced block streams,
|
|
5206
|
+
so it does not reflow prose->block on settle. --- */
|
|
5207
|
+
.ds-247420 .chat-stream-pre pre { margin: 0; white-space: pre-wrap; word-break: break-word; font-family: var(--ff-mono); font-size: var(--fs-sm); }
|
|
5208
|
+
|
|
5209
|
+
/* --- A5: composer context line (agent / model / cwd at point of typing). --- */
|
|
5210
|
+
.ds-247420 .chat-composer-context {
|
|
5211
|
+
display: block; width: 100%; text-align: left; padding: 4px var(--space-3) 0;
|
|
5212
|
+
background: none; border: none; cursor: default; color: var(--fg-3);
|
|
5213
|
+
font-family: var(--ff-mono); font-size: var(--fs-tiny);
|
|
5214
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
5215
|
+
}
|
|
5216
|
+
.ds-247420 button.chat-composer-context { cursor: pointer; }
|
|
5217
|
+
.ds-247420 button.chat-composer-context:hover { color: var(--fg-2); }
|
|
5218
|
+
.ds-247420 button.chat-composer-context:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
5219
|
+
|
|
5220
|
+
/* --- B2: follow-up chips below the last settled assistant turn. --- */
|
|
5221
|
+
.ds-247420 .agentchat-followups { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-2) var(--space-3); }
|
|
5222
|
+
|
|
5223
|
+
/* --- C1: stale/idle dashboard status (static, NOT pulsing). --- */
|
|
5224
|
+
.ds-247420 .ds-dash-status.is-stale { color: var(--amber, #d9a93a); }
|
|
5225
|
+
.ds-247420 .ds-dash-status.is-running { color: var(--accent); }
|
|
5226
|
+
|
|
5227
|
+
/* --- C2: dashboard sort/filter toolbar + stream-state line. --- */
|
|
5228
|
+
.ds-247420 .ds-dash-toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
|
|
5229
|
+
.ds-247420 .ds-dash-stream { font-size: var(--fs-tiny); color: var(--fg-3); }
|
|
5230
|
+
.ds-247420 .ds-dash-stream.is-lost { color: var(--flame); }
|
|
5231
|
+
.ds-247420 .ds-dash-stream.is-connecting { color: var(--amber, #d9a93a); }
|
|
5232
|
+
.ds-247420 .ds-dash-header .spread { flex: 1; }
|
|
5233
|
+
.ds-247420 .ds-dash-errors-toggle {
|
|
5234
|
+
padding: 4px 10px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
|
|
5235
|
+
border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2);
|
|
5236
|
+
cursor: pointer; font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
5237
|
+
}
|
|
5238
|
+
.ds-247420 .ds-dash-errors-toggle.active { background: var(--accent-tint); color: var(--accent); border-color: var(--accent); }
|
|
5239
|
+
.ds-247420 .ds-dash-errors-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
5240
|
+
|
|
5241
|
+
/* --- C3: per-card select checkbox. --- */
|
|
5242
|
+
.ds-247420 .ds-dash-select {
|
|
5243
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
5244
|
+
min-width: 24px; min-height: 24px; padding: 0; cursor: pointer;
|
|
5245
|
+
border: none; background: none; color: var(--fg-3);
|
|
5246
|
+
font-family: var(--ff-mono); font-size: var(--fs-sm);
|
|
5247
|
+
}
|
|
5248
|
+
.ds-247420 .ds-dash-select[aria-checked="true"] { color: var(--accent); }
|
|
5249
|
+
.ds-247420 .ds-dash-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
5250
|
+
|
|
5251
|
+
/* --- C5: active dashboard card (current conversation). --- */
|
|
5252
|
+
.ds-247420 .ds-dash-card.is-active { box-shadow: inset 2px 0 0 var(--accent); }
|
|
5253
|
+
.ds-247420 .ds-dash-card.is-selected { background: var(--accent-tint); }
|
|
5254
|
+
.ds-247420 .ds-dash-card.is-stale { opacity: .92; }
|
|
5255
|
+
|
|
5256
|
+
/* --- H3: dashboard live disc pulses; stale/error do not (handled by H1). --- */
|
|
5257
|
+
|
|
5258
|
+
/* --- C6: per-tab conversation-list caption. --- */
|
|
5259
|
+
.ds-247420 .ds-session-caption { padding: var(--space-2) var(--space-3) 0; font-size: var(--fs-tiny); color: var(--fg-3); }
|
|
5260
|
+
|
|
5261
|
+
/* --- F1: context-pane empty state. --- */
|
|
5262
|
+
.ds-247420 .ds-context-empty { padding: var(--space-4) var(--space-3); color: var(--fg-3); font-size: var(--fs-sm); line-height: 1.5; }
|
|
5263
|
+
|
|
5264
|
+
/* --- E1: inline file preview pane (split view, non-modal). --- */
|
|
5265
|
+
.ds-247420 .ds-preview-pane { display: flex; flex-direction: column; min-height: 0; height: 100%; overflow: hidden; }
|
|
5266
|
+
.ds-247420 .ds-preview-pane:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
5267
|
+
.ds-247420 .ds-preview-pane .ds-preview-body { flex: 1; min-height: 0; overflow: auto; }
|
|
5268
|
+
.ds-247420 .ds-preview-pane-empty { align-items: center; justify-content: center; color: var(--fg-3); font-size: var(--fs-sm); }
|
|
5269
|
+
.ds-247420 .ds-preview-code-wrap { display: flex; flex-direction: column; min-height: 0; }
|
|
5270
|
+
.ds-247420 .ds-preview-code-head { flex: 0 0 auto; }
|
|
5271
|
+
/* --- E2: prev/next stepper in preview head. --- */
|
|
5272
|
+
.ds-247420 .ds-preview-step { display: inline-flex; gap: 2px; }
|
|
5273
|
+
.ds-247420 .ds-preview-step .ds-file-act { min-width: 40px; padding: 0 6px; font-family: var(--ff-body); font-size: var(--fs-tiny); }
|
|
5274
|
+
|
|
5275
|
+
/* --- D1: file grid "show more" row. --- */
|
|
5276
|
+
.ds-247420 .ds-file-more { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); justify-content: center; }
|
|
5277
|
+
.ds-247420 .ds-file-more-count { font-size: var(--fs-tiny); color: var(--fg-3); }
|
|
5278
|
+
.ds-247420 .ds-file-more-btn {
|
|
5279
|
+
padding: 4px 12px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
|
|
5280
|
+
border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2); cursor: pointer;
|
|
5281
|
+
font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
5282
|
+
}
|
|
5283
|
+
.ds-247420 .ds-file-more-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
5284
|
+
/* --- D3: locked/no-access file row. --- */
|
|
5285
|
+
.ds-247420 .ds-file-row.is-locked { opacity: .6; }
|
|
5286
|
+
|
|
5287
|
+
/* --- D4: roots picker segmented control. --- */
|
|
5288
|
+
.ds-247420 .ds-roots-picker { display: inline-flex; gap: 2px; padding: 2px; background: var(--bg-2); border-radius: var(--r-1); }
|
|
5289
|
+
.ds-247420 .ds-roots-tab {
|
|
5290
|
+
padding: 4px 10px; min-height: 32px; border: none; border-radius: var(--r-1);
|
|
5291
|
+
background: none; color: var(--fg-3); cursor: pointer;
|
|
5292
|
+
font-family: var(--ff-body); font-size: var(--fs-tiny);
|
|
5293
|
+
}
|
|
5294
|
+
.ds-247420 .ds-roots-tab.active { background: var(--bg); color: var(--fg); }
|
|
5295
|
+
.ds-247420 .ds-roots-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
5296
|
+
|
|
5297
|
+
/* --- H4: touch targets. On a coarse pointer / narrow screen the hover-revealed
|
|
5298
|
+
action rows are made permanently visible and small controls floor to 44px so
|
|
5299
|
+
they are reachable by finger. --- */
|
|
5300
|
+
@media (pointer: coarse), (max-width: 640px) {
|
|
5301
|
+
.ds-247420 .chat-msg-actions { opacity: 1; }
|
|
5302
|
+
.ds-247420 .chat-code-copy { opacity: 1; }
|
|
5303
|
+
.ds-247420 .chat-msg-action { min-width: 44px; height: 44px; }
|
|
5304
|
+
.ds-247420 .ds-dash-select { min-width: 44px; min-height: 44px; }
|
|
5305
|
+
.ds-247420 .ds-file-more-btn, .ds-247420 .ds-roots-tab, .ds-247420 .ds-dash-errors-toggle { min-height: 44px; }
|
|
5306
|
+
}
|
|
5307
|
+
|
|
5150
5308
|
/* editor-primitives.css */
|
|
5151
5309
|
/* editor-primitives.css — chrome for in-engine editors, inspectors, IDEs,
|
|
5152
5310
|
debug HUDs. All rules under .ds-247420 scope (build prefixes). Tokens
|