anentrypoint-design 0.0.199 → 0.0.201

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 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
 
@@ -2896,3 +2907,45 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2896
2907
  .ws-drawer-toggle:hover { background: var(--bg-2); color: var(--fg); }
2897
2908
  .ws-drawer-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2898
2909
  .ws-scrim { display: none; }
2910
+
2911
+ /* ============================================================
2912
+ Row title highlight, expanded-row actions, filter pills.
2913
+ ============================================================ */
2914
+
2915
+ /* Highlighted match inside a Row title (Row `highlight` prop). */
2916
+ .ds-hl { background: color-mix(in oklab, var(--accent) 25%, transparent); color: inherit; border-radius: 2px; }
2917
+
2918
+ /* Action strip rendered inside an EXPANDED Row (Row `actions` prop). The
2919
+ buttons stop propagation so they never fire the row onClick. */
2920
+ .row-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); width: 100%; padding-top: var(--space-2); }
2921
+ .row-act {
2922
+ display: inline-flex; align-items: center; justify-content: center;
2923
+ padding: 4px 10px; min-height: 28px;
2924
+ background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1);
2925
+ color: var(--fg-2); font-family: var(--ff-body); font-size: var(--fs-tiny); cursor: pointer;
2926
+ transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
2927
+ }
2928
+ .row-act:hover { background: var(--bg-3); color: var(--fg); }
2929
+ .row-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
2930
+
2931
+ /* FilterPills - a group of pill toggle buttons (aria-pressed). */
2932
+ .ds-filter-pills { display: flex; flex-wrap: wrap; gap: var(--space-2); }
2933
+ .ds-filter-pill {
2934
+ display: inline-flex; align-items: center; justify-content: center;
2935
+ padding: 4px 12px; min-height: 28px;
2936
+ background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); border-radius: 999px;
2937
+ color: var(--fg-2); font-family: var(--ff-body); font-size: var(--fs-tiny); cursor: pointer;
2938
+ transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
2939
+ }
2940
+ .ds-filter-pill:hover { background: var(--bg-3); color: var(--fg); }
2941
+ .ds-filter-pill.active { background: var(--accent-tint); color: var(--accent); border-color: var(--accent); }
2942
+ .ds-filter-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
2943
+
2944
+ /* Touch floor for the new small controls. */
2945
+ @media (pointer: coarse) {
2946
+ .row-act, .ds-filter-pill { min-height: 44px; }
2947
+ }
2948
+
2949
+ /* Disabled file actions (read-only row / in-flight mutation) stay visible but inert. */
2950
+ .ds-file-act:disabled { opacity: .45; cursor: default; }
2951
+ .ds-file-act:disabled:hover { background: transparent; color: var(--fg-3); }
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
 
@@ -188,6 +190,50 @@
188
190
  .agentchat-empty-suggestion:hover { background: color-mix(in srgb, var(--accent, var(--fg)) 12%, transparent); }
189
191
  .agentchat-empty-suggestion:focus-visible { outline: 2px solid var(--accent, var(--fg)); outline-offset: 2px; }
190
192
 
193
+ /* Guided install path in the empty state: copy line + monospaced command rows
194
+ (each with its own copy button) + a recheck button. No animation. */
195
+ .agentchat-install {
196
+ margin-top: var(--space-4, 16px);
197
+ display: flex;
198
+ flex-direction: column;
199
+ gap: var(--space-2, 8px);
200
+ text-align: left;
201
+ width: 100%;
202
+ }
203
+ .agentchat-install-text { margin: 0; font-size: .9em; color: var(--fg-3); }
204
+ .agentchat-install-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--space-1, 4px); }
205
+ .agentchat-install-row {
206
+ display: flex; align-items: center; gap: var(--space-2, 8px);
207
+ padding: var(--space-1, 4px) var(--space-2, 8px);
208
+ border: var(--bw-hair) solid var(--rule);
209
+ border-radius: var(--r-1, 4px);
210
+ background: var(--bg-2);
211
+ }
212
+ .agentchat-install-agent { flex: 0 0 auto; font-size: var(--fs-tiny); color: var(--fg-3); min-width: 8ch; }
213
+ .agentchat-install-cmd {
214
+ flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
215
+ font-family: var(--ff-mono); font-size: var(--fs-sm); color: var(--fg-2, var(--fg));
216
+ }
217
+ .agentchat-install-copy {
218
+ flex: 0 0 auto; cursor: pointer; padding: 2px 8px; min-height: 24px;
219
+ border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
220
+ background: none; color: var(--fg-3);
221
+ font-family: var(--ff-body); font-size: var(--fs-tiny);
222
+ }
223
+ .agentchat-install-copy:hover { background: var(--bg-3); color: var(--fg); }
224
+ .agentchat-install-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
225
+ .agentchat-install-actions { display: flex; justify-content: flex-start; }
226
+
227
+ /* Host-supplied transcript export actions riding the controls row. */
228
+ .agentchat-export-act {
229
+ cursor: pointer; padding: 4px 10px; min-height: 32px;
230
+ border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
231
+ background: none; color: var(--fg-3);
232
+ font-family: var(--ff-body); font-size: var(--fs-tiny);
233
+ }
234
+ .agentchat-export-act:hover { background: var(--bg-2); color: var(--fg); }
235
+ .agentchat-export-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
236
+
191
237
  /* "working" tail: a long silent tool call shouldn't read as frozen. */
192
238
  .agentchat-working {
193
239
  display: flex;
@@ -232,12 +278,27 @@
232
278
  Global status disc — a CSS-drawn status indicator (no text glyph) usable
233
279
  outside .agentchat-status (session rows, dashboard cards). Tone via modifier.
234
280
  ---------------------------------------------------------------------------- */
281
+ /* Single canonical status disc — one source for live/error/connecting/stale
282
+ everywhere (crumb dot, conversation row, dashboard card, composer status).
283
+ The app's index.html disc/pulse override is deleted in favour of this. Only
284
+ the -live disc pulses; -stale is deliberately static (a stuck session must NOT
285
+ read as busy). Pulse colour is derived from --accent via color-mix so it
286
+ tracks the theme instead of a hardcoded rgba. */
235
287
  .status-dot-disc {
236
288
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
237
289
  background: var(--fg-3); flex: 0 0 auto;
238
290
  }
239
- .status-dot-disc.status-dot-live { background: var(--green); }
291
+ .status-dot-disc.status-dot-live { background: var(--accent); animation: status-disc-pulse 1.8s ease-in-out infinite; }
240
292
  .status-dot-disc.status-dot-error { background: var(--flame); }
293
+ .status-dot-disc.status-dot-connecting { background: var(--amber, #d9a93a); }
294
+ .status-dot-disc.status-dot-stale { background: var(--amber, #d9a93a); }
295
+ @keyframes status-disc-pulse {
296
+ 0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 55%, transparent); }
297
+ 50% { box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent) 0%, transparent); }
298
+ }
299
+ @media (prefers-reduced-motion: reduce) {
300
+ .status-dot-disc.status-dot-live { animation: none; }
301
+ }
241
302
 
242
303
  /* ----------------------------------------------------------------------------
243
304
  ConversationList — left-rail "Chats" column.
@@ -277,8 +338,10 @@
277
338
  .ds-session-row.rail-green::before, .ds-session-row.rail-purple::before, .ds-session-row.rail-flame::before {
278
339
  content: ''; position: absolute; left: 0; top: 8px; bottom: 8px; width: 3px; border-radius: 3px;
279
340
  }
280
- .ds-session-row.rail-green::before { background: var(--green); }
281
- .ds-session-row.rail-purple::before { background: var(--purple, var(--accent)); }
341
+ /* Rail tones MUST match .row.rail-* in app-shell.css so the same semantic state
342
+ reads as one colour across the conversation list and content rows. */
343
+ .ds-session-row.rail-green::before { background: var(--accent); }
344
+ .ds-session-row.rail-purple::before { background: var(--purple-2, #7F18A4); }
282
345
  .ds-session-row.rail-flame::before { background: var(--flame); }
283
346
  .ds-session-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
284
347
  .ds-session-title { font-size: var(--fs-sm); color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@@ -326,3 +389,155 @@
326
389
  .ds-context .row .meta { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-2); }
327
390
  .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
391
  .ds-context-actions { display: flex; gap: var(--space-2); }
392
+
393
+ /* ============================================================================
394
+ Cohesion sweep (gui-cohesion.js): one-product polish across surfaces.
395
+ ============================================================================ */
396
+
397
+ /* --- A1/A2/E3: per-block code copy. The <pre> is wrapped in .chat-code-block
398
+ (position:relative) so the copy button sits top-right and reveals on hover/
399
+ focus-within, matching the .chat-msg-actions pattern. The structured CodeNode
400
+ head + preview head place the button inline (always visible). --- */
401
+ .chat-code-block { position: relative; }
402
+ .chat-code-copy {
403
+ position: absolute; top: 6px; right: 6px;
404
+ display: inline-flex; align-items: center; justify-content: center;
405
+ min-width: 48px; min-height: 24px; padding: 2px 8px;
406
+ border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
407
+ background: var(--bg-2); color: var(--fg-2); cursor: pointer;
408
+ font-family: var(--ff-body); font-size: var(--fs-tiny);
409
+ opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease);
410
+ }
411
+ .chat-code-block:hover .chat-code-copy, .chat-code-block:focus-within .chat-code-copy { opacity: 1; }
412
+ .chat-code-copy.is-copied { color: var(--accent); border-color: var(--accent); }
413
+ .chat-code-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; opacity: 1; }
414
+ /* Head-placed copy (structured CodeNode + FilePreviewCode) is always visible. */
415
+ .chat-code-head .spread { flex: 1; }
416
+ .chat-code-copy-head { position: static; opacity: 1; }
417
+
418
+ /* --- B1: streaming pre shell — monospaced bubble while a fenced block streams,
419
+ so it does not reflow prose->block on settle. --- */
420
+ .chat-stream-pre pre { margin: 0; white-space: pre-wrap; word-break: break-word; font-family: var(--ff-mono); font-size: var(--fs-sm); }
421
+
422
+ /* --- A5: composer context line (agent / model / cwd at point of typing). --- */
423
+ .chat-composer-context {
424
+ display: block; width: 100%; text-align: left; padding: 4px var(--space-3) 0;
425
+ background: none; border: none; cursor: default; color: var(--fg-3);
426
+ font-family: var(--ff-mono); font-size: var(--fs-tiny);
427
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
428
+ }
429
+ button.chat-composer-context { cursor: pointer; }
430
+ button.chat-composer-context:hover { color: var(--fg-2); }
431
+ button.chat-composer-context:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
432
+
433
+ /* --- B2: follow-up chips below the last settled assistant turn. --- */
434
+ .agentchat-followups { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-2) var(--space-3); }
435
+
436
+ /* --- C1: stale/idle dashboard status (static, NOT pulsing). --- */
437
+ .ds-dash-status.is-stale { color: var(--amber, #d9a93a); }
438
+ .ds-dash-status.is-running { color: var(--accent); }
439
+
440
+ /* --- C2: dashboard sort/filter toolbar + stream-state line. --- */
441
+ .ds-dash-toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
442
+ .ds-dash-stream { font-size: var(--fs-tiny); color: var(--fg-3); }
443
+ .ds-dash-stream.is-lost { color: var(--flame); }
444
+ .ds-dash-stream.is-connecting { color: var(--amber, #d9a93a); }
445
+ .ds-dash-header .spread { flex: 1; }
446
+ .ds-dash-errors-toggle {
447
+ padding: 4px 10px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
448
+ border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2);
449
+ cursor: pointer; font-family: var(--ff-body); font-size: var(--fs-tiny);
450
+ }
451
+ .ds-dash-errors-toggle.active { background: var(--accent-tint); color: var(--accent); border-color: var(--accent); }
452
+ .ds-dash-errors-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
453
+
454
+ /* --- C3: per-card select checkbox. --- */
455
+ .ds-dash-select {
456
+ display: inline-flex; align-items: center; justify-content: center;
457
+ min-width: 24px; min-height: 24px; padding: 0; cursor: pointer;
458
+ border: none; background: none; color: var(--fg-3);
459
+ font-family: var(--ff-mono); font-size: var(--fs-sm);
460
+ }
461
+ .ds-dash-select[aria-checked="true"] { color: var(--accent); }
462
+ .ds-dash-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
463
+
464
+ /* --- C5: active dashboard card (current conversation). --- */
465
+ .ds-dash-card.is-active { box-shadow: inset 2px 0 0 var(--accent); }
466
+ .ds-dash-card.is-selected { background: var(--accent-tint); }
467
+ .ds-dash-card.is-stale { opacity: .92; }
468
+
469
+ /* --- H3: dashboard live disc pulses; stale/error do not (handled by H1). --- */
470
+
471
+ /* --- C6: per-tab conversation-list caption. --- */
472
+ .ds-session-caption { padding: var(--space-2) var(--space-3) 0; font-size: var(--fs-tiny); color: var(--fg-3); }
473
+
474
+ /* --- F1: context-pane empty state. --- */
475
+ .ds-context-empty { padding: var(--space-4) var(--space-3); color: var(--fg-3); font-size: var(--fs-sm); line-height: 1.5; }
476
+
477
+ /* --- E1: inline file preview pane (split view, non-modal). --- */
478
+ .ds-preview-pane { display: flex; flex-direction: column; min-height: 0; height: 100%; overflow: hidden; }
479
+ .ds-preview-pane:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
480
+ .ds-preview-pane .ds-preview-body { flex: 1; min-height: 0; overflow: auto; }
481
+ .ds-preview-pane-empty { align-items: center; justify-content: center; color: var(--fg-3); font-size: var(--fs-sm); }
482
+ .ds-preview-code-wrap { display: flex; flex-direction: column; min-height: 0; }
483
+ .ds-preview-code-head { flex: 0 0 auto; }
484
+ /* --- E2: prev/next stepper in preview head. --- */
485
+ .ds-preview-step { display: inline-flex; gap: 2px; }
486
+ .ds-preview-step .ds-file-act { min-width: 40px; padding: 0 6px; font-family: var(--ff-body); font-size: var(--fs-tiny); }
487
+
488
+ /* --- D1: file grid "show more" row. --- */
489
+ .ds-file-more { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); justify-content: center; }
490
+ .ds-file-more-count { font-size: var(--fs-tiny); color: var(--fg-3); }
491
+ .ds-file-more-btn {
492
+ padding: 4px 12px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
493
+ border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2); cursor: pointer;
494
+ font-family: var(--ff-body); font-size: var(--fs-tiny);
495
+ }
496
+ .ds-file-more-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
497
+ /* --- D3: locked/no-access file row. --- */
498
+ .ds-file-row.is-locked { opacity: .6; }
499
+
500
+ /* --- D4: roots picker segmented control. --- */
501
+ .ds-roots-picker { display: inline-flex; gap: 2px; padding: 2px; background: var(--bg-2); border-radius: var(--r-1); }
502
+ .ds-roots-tab {
503
+ padding: 4px 10px; min-height: 32px; border: none; border-radius: var(--r-1);
504
+ background: none; color: var(--fg-3); cursor: pointer;
505
+ font-family: var(--ff-body); font-size: var(--fs-tiny);
506
+ }
507
+ .ds-roots-tab.active { background: var(--bg); color: var(--fg); }
508
+ .ds-roots-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
509
+
510
+ /* --- H4: touch targets. On a coarse pointer / narrow screen the hover-revealed
511
+ action rows are made permanently visible and small controls floor to 44px so
512
+ they are reachable by finger. --- */
513
+ @media (pointer: coarse), (max-width: 640px) {
514
+ .chat-msg-actions { opacity: 1; }
515
+ .chat-code-copy { opacity: 1; }
516
+ .chat-msg-action { min-width: 44px; height: 44px; }
517
+ .ds-dash-select { min-width: 44px; min-height: 44px; }
518
+ .ds-file-more-btn, .ds-roots-tab, .ds-dash-errors-toggle { min-height: 44px; }
519
+ .agentchat-export-act { min-height: 44px; }
520
+ .agentchat-install-copy { min-height: 44px; min-width: 44px; }
521
+ }
522
+
523
+ /* --- SessionMeta: middot-separated session metadata strip. Class is
524
+ .ds-session-meta-strip (.ds-session-meta is taken by ConversationList row
525
+ meta above). Wraps at narrow widths. --- */
526
+ .ds-session-meta-strip {
527
+ display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
528
+ font-size: var(--fs-tiny); color: var(--fg-3);
529
+ }
530
+ .ds-session-meta-item { display: inline-flex; align-items: center; gap: var(--space-1); min-width: 0; }
531
+ .ds-session-meta-item + .ds-session-meta-item::before { content: '\00B7'; color: var(--fg-3); margin-right: var(--space-1); }
532
+ .ds-session-meta-label { color: var(--fg-3); }
533
+ .ds-session-meta-value { font-family: var(--ff-mono); color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
534
+ .ds-session-meta-copy {
535
+ padding: 2px 8px; min-height: 24px; cursor: pointer;
536
+ background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1);
537
+ color: var(--fg-3); font-family: var(--ff-body); font-size: var(--fs-micro);
538
+ }
539
+ .ds-session-meta-copy:hover { background: var(--bg-3); color: var(--fg); }
540
+ .ds-session-meta-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
541
+ @media (pointer: coarse), (max-width: 640px) {
542
+ .ds-session-meta-copy { min-height: 44px; min-width: 44px; }
543
+ }