anentrypoint-design 0.0.209 → 0.0.211

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/dist/247420.css CHANGED
@@ -199,22 +199,31 @@
199
199
  --size-sm: 32px;
200
200
  --size-base: 42px;
201
201
  --size-lg: 56px;
202
+
203
+ /* Unified focus-ring tokens (single source for the design system). Outset
204
+ rings (the default) tokenize colour+width+offset; bordered text fields use
205
+ the inset variant. Deliberate negative offsets on edge-flush/clipping
206
+ containers stay literal. */
207
+ --focus-color: var(--accent);
208
+ --focus-w: 2px;
209
+ --focus-offset: 2px;
210
+ --focus-ring-inset: inset 0 0 0 var(--focus-w) var(--focus-color);
202
211
  }
203
212
 
204
213
  /* ============================================================
205
214
  Focus-visible styles for keyboard navigation
206
215
  ============================================================ */
207
216
  .ds-247420 :focus-visible {
208
- outline: 2px solid var(--accent);
209
- outline-offset: 2px;
217
+ outline: var(--focus-w) solid var(--focus-color);
218
+ outline-offset: var(--focus-offset);
210
219
  }
211
220
 
212
221
  /* Button variants with focus-visible */
213
222
  .ds-247420 .btn:focus-visible,
214
223
  .ds-247420 .btn-primary:focus-visible,
215
224
  .ds-247420 .btn-ghost:focus-visible {
216
- outline: 2px solid var(--accent);
217
- outline-offset: 2px;
225
+ outline: var(--focus-w) solid var(--focus-color);
226
+ outline-offset: var(--focus-offset);
218
227
  }
219
228
 
220
229
  /* Link focus-visible */
@@ -262,6 +271,10 @@
262
271
  --danger: oklch(0.68 0.19 25);
263
272
  --flame: #FF5A1F;
264
273
  --amber: #D9A93A;
274
+ /* warn/sky dark-tuned pairs (mirror flame/amber): the :root paper values
275
+ (#E0241A / #3A6EFF) are too dark on ink; these clear AA 4.5:1 on --ink. */
276
+ --warn: #FF5A52;
277
+ --sky: #6E9BFF;
265
278
  --code-string: var(--green-2);
266
279
  --code-keyword: var(--sky);
267
280
  --code-fn: var(--flame);
@@ -295,6 +308,8 @@
295
308
  --accent-bright: var(--green-2);
296
309
  --flame: #FF5A1F;
297
310
  --amber: #D9A93A;
311
+ --warn: #FF5A52;
312
+ --sky: #6E9BFF;
298
313
  --code-string: var(--green-2);
299
314
  --code-keyword: var(--sky);
300
315
  --code-fn: var(--flame);
@@ -624,7 +639,7 @@
624
639
  .ds-247420 body.canvas-host { background: transparent !important; }
625
640
 
626
641
  .ds-247420 {
627
- --app-status-h: var(--size-base);
642
+ --app-status-h: 26px;
628
643
  --app-topbar-h: var(--size-lg);
629
644
  --app-crumb-h: var(--size-sm);
630
645
  }
@@ -818,14 +833,15 @@
818
833
  .ds-247420 .app-status {
819
834
  display: flex; align-items: center; gap: var(--space-3);
820
835
  width: 100%;
821
- min-height: var(--app-status-h);
822
- padding: 10px var(--pad-x);
836
+ height: var(--app-status-h); min-height: var(--app-status-h);
837
+ /* A thin desktop status strip, not a webpage footer band. */
838
+ padding: 0 var(--space-4);
823
839
  /* Status chrome is prose, not code - mono is reserved for code/paths. */
824
- font-family: var(--ff-body); font-size: var(--fs-xs);
840
+ font-family: var(--ff-body); font-size: var(--fs-xs); line-height: 1.2;
825
841
  color: var(--fg-3);
826
842
  border-top: 1px solid var(--rule);
827
843
  }
828
- .ds-247420 .app-status .item { color: inherit; white-space: nowrap; }
844
+ .ds-247420 .app-status .item { color: inherit; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
829
845
  .ds-247420 .app-status .item:first-of-type { color: var(--accent); }
830
846
  .ds-247420 .app-status .spread { flex: 1; }
831
847
  /* The status bar NEVER wraps: at narrow widths the trailing items (hints,
@@ -840,13 +856,14 @@
840
856
  Primitives
841
857
  ============================================================ */
842
858
  .ds-247420 .btn, .ds-247420 .btn-primary, .ds-247420 .btn-ghost {
843
- display: inline-flex; align-items: center; gap: 8px;
844
- padding: 13px 22px;
859
+ display: inline-flex; align-items: center; justify-content: center; gap: 6px;
860
+ padding: 8px 14px; min-height: 32px;
845
861
  font-family: var(--ff-body);
846
862
  font-weight: 600; font-size: var(--fs-sm);
847
863
  text-decoration: none;
848
864
  cursor: pointer;
849
- border-radius: var(--r-pill);
865
+ /* Rounded-rect app chrome, not a marketing-page stadium CTA. */
866
+ border-radius: var(--r-1);
850
867
  border: 0;
851
868
  transition: transform var(--dur-snap) var(--ease), background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
852
869
  }
@@ -1022,8 +1039,13 @@
1022
1039
  .ds-247420 .row.rail-purple::before,
1023
1040
  .ds-247420 .row.rail-flame::before { height: 56%; opacity: 1; }
1024
1041
  .ds-247420 .row.rail-green::before { background: var(--accent); }
1025
- .ds-247420 .row.rail-purple::before { background: var(--purple-2, #7F18A4); }
1042
+ .ds-247420 .row.rail-purple::before { background: var(--purple-2); }
1026
1043
  .ds-247420 .row.rail-flame::before { background: var(--flame); }
1044
+ /* Differentiate the rail by SHAPE, not hue alone (color-blind safety): error
1045
+ reads as a taller solid bar, subagent as a dashed/gapped fill, ok stays the
1046
+ short solid bar. Paired with the sr-only status word emitted by Row(). */
1047
+ .ds-247420 .row.rail-flame::before { height: 64%; }
1048
+ .ds-247420 .row.rail-purple::before { background: repeating-linear-gradient(var(--purple-2) 0 4px, transparent 4px 7px); }
1027
1049
  .ds-247420 .row-grid { /* explicit grid-template-columns set inline */ }
1028
1050
  /* A row with no leading code/index drops the empty first column so the title
1029
1051
  takes the full width instead of wrapping in the narrow code gutter. */
@@ -1259,8 +1281,8 @@
1259
1281
  border: 0; border-radius: var(--r-2);
1260
1282
  box-shadow: inset 0 0 0 1px var(--rule);
1261
1283
  }
1262
- .ds-247420 .row-form input:focus,
1263
- .ds-247420 .row-form textarea:focus { box-shadow: inset 0 0 0 2px var(--accent); }
1284
+ .ds-247420 .row-form input:focus-visible,
1285
+ .ds-247420 .row-form textarea:focus-visible { box-shadow: var(--focus-ring-inset); }
1264
1286
 
1265
1287
  /* Field char counter (TextField maxLength) */
1266
1288
  .ds-247420 .ds-field-count {
@@ -1281,9 +1303,9 @@
1281
1303
  Responsive Design — Mobile (480px), Tablet (1024px), Desktop (1440px+)
1282
1304
  ============================================================ */
1283
1305
 
1284
- /* ────────────────────────────────────────────────────────────────────
1306
+ /* --------------------------------------------------------------------
1285
1307
  Mobile Portrait Breakpoint (480px and below)
1286
- ────────────────────────────────────────────────────────────────────── */
1308
+ ---------------------------------------------------------------------- */
1287
1309
  @media (max-width: 480px) {
1288
1310
  /* App Layout: single-column + drawer is handled once in the ≤900px block;
1289
1311
  no need to re-declare grid-template-columns here (was a redundant !important). */
@@ -1407,9 +1429,9 @@
1407
1429
  .ds-247420 .cli .copy { padding: 6px 12px; font-size: var(--fs-micro); }
1408
1430
  }
1409
1431
 
1410
- /* ────────────────────────────────────────────────────────────────────
1432
+ /* --------------------------------------------------------------------
1411
1433
  Container Query Responsive (720px and below)
1412
- ────────────────────────────────────────────────────────────────────── */
1434
+ ---------------------------------------------------------------------- */
1413
1435
  @container (max-width: 760px) {
1414
1436
  .ds-247420 .app-body { grid-template-columns: 1fr !important; }
1415
1437
  .ds-247420 .app-side-shell { border-right: 0; border-bottom: 1px solid var(--rule); }
@@ -1419,9 +1441,9 @@
1419
1441
  .ds-247420 .row .sub { grid-column: 1 / -1; order: 3; }
1420
1442
  }
1421
1443
 
1422
- /* ────────────────────────────────────────────────────────────────────
1444
+ /* --------------------------------------------------------------------
1423
1445
  Tablet Landscape Breakpoint (768px to 1024px)
1424
- ────────────────────────────────────────────────────────────────────── */
1446
+ ---------------------------------------------------------------------- */
1425
1447
  @media (min-width: 481px) and (max-width: 1024px) {
1426
1448
  /* App Layout — side handled by 900px drawer block; restore for 901-1024 */
1427
1449
  .ds-247420 .app-side a {
@@ -1498,9 +1520,9 @@
1498
1520
  }
1499
1521
  }
1500
1522
 
1501
- /* ────────────────────────────────────────────────────────────────────
1523
+ /* --------------------------------------------------------------------
1502
1524
  Mid Breakpoint (768px and below) — collapse sidebar + simplify row grid
1503
- ────────────────────────────────────────────────────────────────────── */
1525
+ ---------------------------------------------------------------------- */
1504
1526
  @media (max-width: 768px) {
1505
1527
  /* Sidebar stacks above main rather than sitting beside it */
1506
1528
  .ds-247420 .app-body { grid-template-columns: 1fr; }
@@ -1515,9 +1537,9 @@
1515
1537
  .ds-247420 .row .sub { grid-column: 1 / -1; }
1516
1538
  }
1517
1539
 
1518
- /* ────────────────────────────────────────────────────────────────────
1540
+ /* --------------------------------------------------------------------
1519
1541
  Desktop Breakpoint Enhancements (1025px and up)
1520
- ────────────────────────────────────────────────────────────────────── */
1542
+ ---------------------------------------------------------------------- */
1521
1543
  @media (min-width: 1025px) {
1522
1544
  /* Chat Bubbles */
1523
1545
  .ds-247420 .chat-stack { max-width: min(70%, 480px); }
@@ -1538,7 +1560,7 @@
1538
1560
  .ds-247420 .ds-chat-md { font-size: var(--fs-sm); line-height: 1.6; }
1539
1561
  .ds-247420 .ds-chat-composer { display: flex; gap: 8px; padding: var(--space-4); }
1540
1562
  .ds-247420 .ds-chat-composer input { flex: 1; padding: 13px 18px; background: var(--bg-2); border: 0; border-radius: var(--r-pill); font-family: inherit; font-size: var(--fs-sm); color: var(--fg); }
1541
- .ds-247420 .ds-chat-composer input:focus { box-shadow: inset 0 0 0 2px var(--accent); }
1563
+ .ds-247420 .ds-chat-composer input:focus-visible { box-shadow: var(--focus-ring-inset); }
1542
1564
 
1543
1565
  /* ============================================================
1544
1566
  File surface — responsive grid + row layouts
@@ -1564,7 +1586,7 @@
1564
1586
  background: var(--bg); color: var(--fg);
1565
1587
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
1566
1588
  }
1567
- .ds-247420 .ds-file-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
1589
+ .ds-247420 .ds-file-filter-input:focus-visible { outline: none; box-shadow: var(--focus-ring-inset); }
1568
1590
  .ds-247420 .ds-file-sort { display: flex; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); }
1569
1591
  .ds-247420 .ds-file-sort-btn {
1570
1592
  font-size: var(--fs-tiny); font-family: var(--ff-mono); color: var(--fg-3);
@@ -1685,6 +1707,29 @@
1685
1707
  .ds-247420 .ds-file-act-warn:hover { background: color-mix(in oklab, var(--warn) 18%, var(--bg)); color: var(--warn); }
1686
1708
 
1687
1709
  /* Multi-select — per-row checkbox, header tri-state, bulk action strip. */
1710
+ /* CSS-drawn multi-select checkbox: a bordered box that fills with the accent +
1711
+ a border-drawn tick when its parent button is .is-marked or aria-checked.
1712
+ Shared by FileRow/FileCell (.is-marked) and the file/session select-all +
1713
+ SessionCard select (aria-checked true/mixed) since the bundle concatenates
1714
+ all CSS. Replaces the old [x]/[ ] bracket text - no glyphs, AT keeps the
1715
+ role=checkbox/aria-checked name+state. */
1716
+ .ds-247420 .ds-check-box {
1717
+ width: 15px; height: 15px; box-sizing: border-box; flex: 0 0 auto; position: relative;
1718
+ border: 1.5px solid var(--rule); border-radius: 4px;
1719
+ transition: background var(--dur-snap) var(--ease), border-color var(--dur-snap) var(--ease);
1720
+ }
1721
+ .ds-247420 .is-marked > .ds-check-box,
1722
+ .ds-247420[aria-checked="true"] > .ds-check-box { background: var(--accent); border-color: var(--accent); }
1723
+ .ds-247420 .is-marked > .ds-check-box::after,
1724
+ .ds-247420[aria-checked="true"] > .ds-check-box::after {
1725
+ content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
1726
+ border: solid var(--bg); border-width: 0 1.5px 1.5px 0; transform: rotate(45deg);
1727
+ }
1728
+ .ds-247420[aria-checked="mixed"] > .ds-check-box { background: var(--accent); border-color: var(--accent); }
1729
+ .ds-247420[aria-checked="mixed"] > .ds-check-box::after {
1730
+ content: ""; position: absolute; left: 2px; right: 2px; top: 50%; height: 1.5px; margin-top: -0.75px; background: var(--bg);
1731
+ }
1732
+
1688
1733
  .ds-247420 .ds-file-check {
1689
1734
  display: inline-flex; align-items: center; justify-content: center;
1690
1735
  min-width: 28px; height: 28px; padding: 0 4px;
@@ -1714,7 +1759,7 @@
1714
1759
  padding: var(--space-1) var(--space-2);
1715
1760
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
1716
1761
  }
1717
- .ds-247420 .ds-bulkbar-count { font-size: var(--fs-tiny); color: var(--fg-2); }
1762
+ .ds-247420 .ds-bulkbar-count { font-size: var(--fs-sm); font-weight: 600; color: var(--fg-2); }
1718
1763
  /* BulkBar is a toolbar (it even declares role=toolbar): compact rect buttons,
1719
1764
  quiet destructive outline - the app arm-confirms destructive bulk actions
1720
1765
  via ConfirmDialog, so the strip never needs a loud CTA. */
@@ -1975,7 +2020,7 @@
1975
2020
  .ds-247420 .ds-file-empty-glyph { font-size: 34px; opacity: 0.55; }
1976
2021
  .ds-247420 .ds-file-empty-text { font-size: var(--fs-sm); }
1977
2022
 
1978
- /* ── Modals ───────────────────────────────────────────────── */
2023
+ /* -- Modals ------------------------------------------------- */
1979
2024
  .ds-247420 .ds-modal-backdrop {
1980
2025
  position: fixed; inset: 0; z-index: var(--z-modal, 800);
1981
2026
  display: flex; align-items: center; justify-content: center;
@@ -2021,7 +2066,7 @@
2021
2066
  border-radius: var(--r-2); color: var(--fg);
2022
2067
  font-family: inherit; font-size: var(--fs-sm);
2023
2068
  }
2024
- .ds-247420 .ds-modal-input:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
2069
+ .ds-247420 .ds-modal-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2025
2070
  /* In-body modal error (role=alert): mutation failures (409/403) surface INSIDE
2026
2071
  the dialog, not behind the fixed overlay. */
2027
2072
  .ds-247420 .ds-modal-error {
@@ -2036,7 +2081,7 @@
2036
2081
  color: var(--on-color);
2037
2082
  }
2038
2083
 
2039
- /* ── Preview ──────────────────────────────────────────────── */
2084
+ /* -- Preview ------------------------------------------------ */
2040
2085
  .ds-247420 .ds-preview-head {
2041
2086
  display: flex; align-items: center; gap: var(--space-3);
2042
2087
  padding: var(--space-3) var(--space-4);
@@ -2109,7 +2154,7 @@
2109
2154
  .ds-247420 .ds-file-stage { padding: var(--space-3) var(--space-2); }
2110
2155
  }
2111
2156
 
2112
- /* ── File browser UX affordances ──────────────────────────── */
2157
+ /* -- File browser UX affordances ---------------------------- */
2113
2158
  /* Toolbar filter input — compact search box. */
2114
2159
  .ds-247420 .ds-filter-input {
2115
2160
  width: clamp(120px, 22vw, 220px);
@@ -2118,7 +2163,7 @@
2118
2163
  border-radius: var(--r-pill); color: var(--fg);
2119
2164
  font-family: inherit; font-size: var(--fs-xs);
2120
2165
  }
2121
- .ds-247420 .ds-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
2166
+ .ds-247420 .ds-filter-input:focus-visible { outline: none; box-shadow: var(--focus-ring-inset); }
2122
2167
 
2123
2168
  /* Loading skeleton — placeholder rows while a directory loads. */
2124
2169
  .ds-247420 .ds-file-grid-loading { display: flex; flex-direction: column; gap: 4px; }
@@ -2641,7 +2686,7 @@
2641
2686
  .ds-247420 .app-side a .glyph { font-family: var(--ff-mono); font-size: 13px; font-weight: 600; color: var(--fg-3); text-align: center; }
2642
2687
  .ds-247420 .app-side a.active .glyph { color: var(--accent); }
2643
2688
 
2644
- /* ── select primitive ─────────────────────────────────────────────────── */
2689
+ /* -- select primitive --------------------------------------------------- */
2645
2690
  .ds-247420 .ds-select {
2646
2691
  width: 100%;
2647
2692
  min-width: 0;
@@ -2665,10 +2710,10 @@
2665
2710
  background-repeat: no-repeat;
2666
2711
  cursor: pointer;
2667
2712
  }
2668
- .ds-247420 .ds-select:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
2713
+ .ds-247420 .ds-select:focus-visible { box-shadow: var(--focus-ring-inset); }
2669
2714
  .ds-247420 .ds-select:hover { background-color: var(--bg-3); }
2670
2715
 
2671
- /* ── chat composer autogrow polish (sizing lives in the primary block) ── */
2716
+ /* -- chat composer autogrow polish (sizing lives in the primary block) -- */
2672
2717
  .ds-247420 .chat-composer textarea {
2673
2718
  transition: height var(--dur-snap) var(--ease);
2674
2719
  }
@@ -2677,7 +2722,7 @@
2677
2722
  cursor: not-allowed;
2678
2723
  }
2679
2724
 
2680
- /* ── mobile responsive: chat ──────────────────────────────────────────── */
2725
+ /* -- mobile responsive: chat -------------------------------------------- */
2681
2726
  @media (max-width: 768px) {
2682
2727
  .ds-247420 .chat-stack { max-width: 100%; }
2683
2728
  .ds-247420 .chat-msg { padding: 4px 0; }
@@ -2702,9 +2747,9 @@
2702
2747
  Comprehensive improvements for perfect UX across all surfaces
2703
2748
  ============================================================ */
2704
2749
 
2705
- /* ────────────────────────────────────────────────────────────
2750
+ /* ------------------------------------------------------------
2706
2751
  Component States — Disabled, Loading, Error, Success
2707
- ────────────────────────────────────────────────────────────── */
2752
+ -------------------------------------------------------------- */
2708
2753
 
2709
2754
  /* Disabled state for all interactive elements */
2710
2755
  .ds-247420 .btn:disabled, .ds-247420 .btn-primary:disabled, .ds-247420 .btn-ghost:disabled, .ds-247420 button:disabled, .ds-247420[disabled] {
@@ -2752,9 +2797,9 @@
2752
2797
  opacity: 0.8;
2753
2798
  }
2754
2799
 
2755
- /* ────────────────────────────────────────────────────────────
2800
+ /* ------------------------------------------------------------
2756
2801
  Enhanced Button Micro-Interactions
2757
- ────────────────────────────────────────────────────────────── */
2802
+ -------------------------------------------------------------- */
2758
2803
 
2759
2804
  /* Button scale feedback on active */
2760
2805
  .ds-247420 .btn:active:not(:disabled),
@@ -2781,9 +2826,9 @@
2781
2826
  -webkit-touch-callout: none;
2782
2827
  }
2783
2828
 
2784
- /* ────────────────────────────────────────────────────────────
2829
+ /* ------------------------------------------------------------
2785
2830
  Drag-and-Drop Styles
2786
- ────────────────────────────────────────────────────────────── */
2831
+ -------------------------------------------------------------- */
2787
2832
 
2788
2833
  /* Draggable element */
2789
2834
  .ds-247420[draggable="true"], .ds-247420 .draggable {
@@ -2840,9 +2885,9 @@
2840
2885
  50% { opacity: 1; }
2841
2886
  }
2842
2887
 
2843
- /* ────────────────────────────────────────────────────────────
2888
+ /* ------------------------------------------------------------
2844
2889
  Context Menu Styles
2845
- ────────────────────────────────────────────────────────────── */
2890
+ -------------------------------------------------------------- */
2846
2891
 
2847
2892
  .ds-247420 .ds-context-menu {
2848
2893
  position: absolute;
@@ -2904,9 +2949,9 @@
2904
2949
  cursor: context-menu;
2905
2950
  }
2906
2951
 
2907
- /* ────────────────────────────────────────────────────────────
2952
+ /* ------------------------------------------------------------
2908
2953
  Enhanced Form Inputs
2909
- ────────────────────────────────────────────────────────────── */
2954
+ -------------------------------------------------------------- */
2910
2955
 
2911
2956
  .ds-247420 input[type="text"],
2912
2957
  .ds-247420 input[type="email"],
@@ -2932,7 +2977,7 @@
2932
2977
  color: var(--fg-3);
2933
2978
  }
2934
2979
 
2935
- /* ── Field controls: themed base for TextField / Select / SearchInput ──
2980
+ /* -- Field controls: themed base for TextField / Select / SearchInput --
2936
2981
  Root fix: previously only `transition` was set, so themed apps got
2937
2982
  browser-default white boxes in dark mode and labels collided with inputs
2938
2983
  because `.ds-field` had no layout. */
@@ -2981,7 +3026,7 @@
2981
3026
  .ds-247420 .ds-field .ds-select:focus-visible,
2982
3027
  .ds-247420 .ds-search-input:focus-visible {
2983
3028
  outline: none;
2984
- box-shadow: inset 0 0 0 2px var(--accent);
3029
+ box-shadow: var(--focus-ring-inset);
2985
3030
  }
2986
3031
  .ds-247420 .ds-field input:disabled,
2987
3032
  .ds-247420 .ds-field textarea:disabled,
@@ -3019,9 +3064,9 @@
3019
3064
  color: var(--fg);
3020
3065
  }
3021
3066
 
3022
- /* ────────────────────────────────────────────────────────────
3067
+ /* ------------------------------------------------------------
3023
3068
  Accessibility Enhancements
3024
- ────────────────────────────────────────────────────────────── */
3069
+ -------------------------------------------------------------- */
3025
3070
 
3026
3071
  /* Enhanced focus-visible for all interactive elements */
3027
3072
  .ds-247420[role="button"]:focus-visible,
@@ -3050,11 +3095,17 @@
3050
3095
  animation-iteration-count: 1 !important;
3051
3096
  transition-duration: 0.01ms !important;
3052
3097
  }
3098
+ /* Kill the residual paint frame of looping skeleton/shimmer placeholders and
3099
+ give reduced-motion users a steady placeholder fill instead. */
3100
+ .ds-247420 .skeleton, .ds-247420 .ds-skeleton, .ds-247420 .ds-session-row-skeleton .ds-skel {
3101
+ animation: none !important;
3102
+ background: var(--bg-2) !important;
3103
+ }
3053
3104
  }
3054
3105
 
3055
- /* ────────────────────────────────────────────────────────────
3106
+ /* ------------------------------------------------------------
3056
3107
  Performance
3057
- ────────────────────────────────────────────────────────────── */
3108
+ -------------------------------------------------------------- */
3058
3109
 
3059
3110
  /* Limit layout/style containment to self-contained components. `paint` is
3060
3111
  intentionally omitted — it clips focus rings, tooltips and dropdowns that
@@ -3063,9 +3114,9 @@
3063
3114
  contain: layout style;
3064
3115
  }
3065
3116
 
3066
- /* ────────────────────────────────────────────────────────────
3117
+ /* ------------------------------------------------------------
3067
3118
  Mobile Touch Optimizations
3068
- ────────────────────────────────────────────────────────────── */
3119
+ -------------------------------------------------------------- */
3069
3120
 
3070
3121
  @media (hover: none) and (pointer: coarse) {
3071
3122
  /* Mobile devices: larger touch targets, faster responses */
@@ -3094,9 +3145,9 @@
3094
3145
  }
3095
3146
  }
3096
3147
 
3097
- /* ────────────────────────────────────────────────────────────
3148
+ /* ------------------------------------------------------------
3098
3149
  Theme Transition Smoothness
3099
- ────────────────────────────────────────────────────────────── */
3150
+ -------------------------------------------------------------- */
3100
3151
 
3101
3152
  /* Scoped to the DS wrapper so the design system never reaches out and
3102
3153
  animates the host document's html/body. */
@@ -3105,9 +3156,9 @@
3105
3156
  color var(--dur-base) var(--ease);
3106
3157
  }
3107
3158
 
3108
- /* ────────────────────────────────────────────────────────────
3159
+ /* ------------------------------------------------------------
3109
3160
  Empty State & Loading States
3110
- ────────────────────────────────────────────────────────────── */
3161
+ -------------------------------------------------------------- */
3111
3162
 
3112
3163
  .ds-247420 .empty-state {
3113
3164
  display: flex; flex-direction: column; align-items: center; gap: var(--space-4);
@@ -3145,9 +3196,9 @@
3145
3196
  .ds-247420 .skeleton-line { height: 12px; margin-bottom: 12px; }
3146
3197
  .ds-247420 .skeleton-title { height: 24px; margin-bottom: 16px; width: 60%; }
3147
3198
 
3148
- /* ────────────────────────────────────────────────────────────
3199
+ /* ------------------------------------------------------------
3149
3200
  Toast Notification Styles
3150
- ────────────────────────────────────────────────────────────── */
3201
+ -------------------------------------------------------------- */
3151
3202
 
3152
3203
  .ds-247420 .toast {
3153
3204
  position: fixed;
@@ -3432,10 +3483,13 @@
3432
3483
  All sizing/colour from kit tokens; no hardcoded palette.
3433
3484
  ---------------------------------------------------------------------------- */
3434
3485
  .ds-247420 .ws-shell {
3435
- --ws-rail-w: 232px;
3486
+ /* Fluid chrome columns: shrink on small laptops, breathe on ultrawide, so the
3487
+ ~848px of fixed chrome no longer eats a constant slab. An inline --ws-*-w
3488
+ written by a resize drag overrides these (inline wins), pinning the width. */
3489
+ --ws-rail-w: clamp(200px, 16vw, 260px);
3436
3490
  --ws-rail-w-collapsed: 60px;
3437
- --ws-sessions-w: 296px;
3438
- --ws-pane-w: 320px;
3491
+ --ws-sessions-w: clamp(248px, 22vw, 360px);
3492
+ --ws-pane-w: clamp(288px, 24vw, 420px);
3439
3493
  display: grid;
3440
3494
  grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) 1fr var(--ws-pane-w);
3441
3495
  grid-template-areas: "rail sessions content pane";
@@ -3456,6 +3510,21 @@
3456
3510
  .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"; }
3457
3511
  .ds-247420 .ws-shell.ws-rail-collapsed { --ws-rail-w: var(--ws-rail-w-collapsed); }
3458
3512
  .ds-247420 .ws-shell.ws-pane-collapsed { --ws-pane-w: 0px; }
3513
+ /* Sessions column desktop collapse (parity with the pane collapse), reclaiming
3514
+ its width for a full-width thread/grid. */
3515
+ .ds-247420 .ws-shell.ws-sessions-collapsed { --ws-sessions-w: 0px; }
3516
+ .ds-247420 .ws-sessions-collapsed .ws-sessions { overflow: hidden; border-right: none; }
3517
+ .ds-247420 .ws-sessions-collapsed .ws-sessions > * { display: none; }
3518
+ /* Column resize handles: a thin keyboard-accessible separator pinned to the
3519
+ right edge of each chrome track; drag (or ArrowLeft/Right) writes a clamped
3520
+ inline --ws-*-w. */
3521
+ .ds-247420 .ws-resizer { grid-row: 1 / -1; align-self: stretch; justify-self: end; width: 8px; margin-right: -4px; z-index: 5; cursor: col-resize; background: transparent; border: none; padding: 0; touch-action: none; }
3522
+ .ds-247420 .ws-resizer::after { content: ""; display: block; width: 2px; height: 100%; margin: 0 auto; background: transparent; transition: background var(--dur-snap) var(--ease); }
3523
+ .ds-247420 .ws-resizer:hover::after, .ds-247420 .ws-resizer:focus-visible::after { background: var(--accent); }
3524
+ .ds-247420 .ws-resizer:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
3525
+ .ds-247420 .ws-resizer.ws-resizer-rail { grid-column: 1; }
3526
+ .ds-247420 .ws-resizer.ws-resizer-sessions { grid-column: 2; }
3527
+ .ds-247420 .ws-resizer.ws-resizer-pane { grid-column: 3; justify-self: end; }
3459
3528
  /* Ease the rail/pane collapse. Track COUNT stays stable on collapse (only a
3460
3529
  width var flips), so grid-template-columns is animatable; reduced-motion
3461
3530
  drops it to an instant swap. */
@@ -3535,7 +3604,7 @@
3535
3604
  /* Crumb band is the top chrome of the content column: a stable height so the
3536
3605
  top edge aligns with the rail head, and a left gutter matching .ws-main so
3537
3606
  the trail text is not flush against the rail border. */
3538
- .ds-247420 .ws-crumb { flex: 0 0 auto; min-height: 48px; padding: 0 var(--space-4); display: flex; align-items: center; gap: var(--space-1); border-bottom: var(--bw-hair) solid var(--bg-3); }
3607
+ .ds-247420 .ws-crumb { flex: 0 0 auto; min-height: 48px; padding: 0 var(--space-5); display: flex; align-items: center; gap: var(--space-1); border-bottom: var(--bw-hair) solid var(--bg-3); }
3539
3608
  .ds-247420 .ws-crumb-main { flex: 1 1 auto; min-width: 0; }
3540
3609
  /* Content column gutter. Claude-Code-class calm: file grid / dashboard / event
3541
3610
  list / history get a generous, consistent inner gutter instead of butting
@@ -3570,6 +3639,11 @@
3570
3639
  trailing display:none silently kills every drawer affordance (shipped bug:
3571
3640
  the mobile drawers were dead because these lines used to sit last). */
3572
3641
  .ds-247420 .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); }
3642
+ /* Desktop-only chrome toggle (sessions collapse): inverse of the mobile drawer-toggle. */
3643
+ .ds-247420 .ws-desktop-toggle { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: none; background: none; color: var(--fg-2); cursor: pointer; border-radius: var(--r-1); }
3644
+ .ds-247420 .ws-desktop-toggle:hover { background: var(--bg-2); color: var(--fg); }
3645
+ .ds-247420 .ws-desktop-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3646
+ @media (max-width: 900px) { .ds-247420 .ws-desktop-toggle { display: none; } }
3573
3647
  .ds-247420 .ws-scrim { display: none; }
3574
3648
 
3575
3649
  /* Responsive: the columns yield to the CONTENT in stages - the main column is
@@ -5378,7 +5452,7 @@
5378
5452
  overflow-y: auto;
5379
5453
  display: flex;
5380
5454
  flex-direction: column;
5381
- gap: var(--space-2, 8px);
5455
+ gap: calc(var(--space-2, 8px) * var(--density, 1));
5382
5456
  }
5383
5457
 
5384
5458
  /* Jump-to-latest: hidden until the thread scroll listener adds .show. */
@@ -5430,14 +5504,14 @@
5430
5504
  }
5431
5505
  .ds-247420 .agentchat-empty-title { margin: 0; font-size: 1.05em; color: var(--fg-2, var(--fg)); }
5432
5506
  .ds-247420 .agentchat-empty-sub { margin: 0; font-size: var(--fs-sm); }
5433
- .ds-247420 .agentchat-empty-suggestions {
5507
+ .ds-247420 .agentchat-empty-suggestions, .ds-247420 .chat-empty-suggestions {
5434
5508
  display: flex;
5435
5509
  flex-wrap: wrap;
5436
5510
  gap: .5em;
5437
5511
  justify-content: center;
5438
5512
  margin-top: .5em;
5439
5513
  }
5440
- .ds-247420 .agentchat-empty-suggestion {
5514
+ .ds-247420 .agentchat-empty-suggestion, .ds-247420 .chat-empty-suggestion {
5441
5515
  cursor: pointer;
5442
5516
  font: inherit;
5443
5517
  font-size: var(--fs-tiny);
@@ -5447,8 +5521,8 @@
5447
5521
  background: color-mix(in srgb, var(--fg) 5%, transparent);
5448
5522
  color: var(--fg-2, var(--fg));
5449
5523
  }
5450
- .ds-247420 .agentchat-empty-suggestion:hover { background: color-mix(in srgb, var(--accent, var(--fg)) 12%, transparent); }
5451
- .ds-247420 .agentchat-empty-suggestion:focus-visible { outline: 2px solid var(--accent, var(--fg)); outline-offset: 2px; }
5524
+ .ds-247420 .agentchat-empty-suggestion:hover, .ds-247420 .chat-empty-suggestion:hover { background: color-mix(in srgb, var(--accent, var(--fg)) 12%, transparent); }
5525
+ .ds-247420 .agentchat-empty-suggestion:focus-visible, .ds-247420 .chat-empty-suggestion:focus-visible { outline: 2px solid var(--accent, var(--fg)); outline-offset: 2px; }
5452
5526
 
5453
5527
  /* Guided install path in the empty state: copy line + monospaced command rows
5454
5528
  (each with its own copy button) + a recheck button. No animation. */
@@ -5550,8 +5624,8 @@
5550
5624
  }
5551
5625
  .ds-247420 .status-dot-disc.status-dot-live { background: var(--accent); animation: status-disc-pulse 1.8s ease-in-out infinite; }
5552
5626
  .ds-247420 .status-dot-disc.status-dot-error { background: var(--flame); }
5553
- .ds-247420 .status-dot-disc.status-dot-connecting { background: var(--amber, #d9a93a); }
5554
- .ds-247420 .status-dot-disc.status-dot-stale { background: var(--amber, #d9a93a); }
5627
+ .ds-247420 .status-dot-disc.status-dot-connecting { background: var(--amber); }
5628
+ .ds-247420 .status-dot-disc.status-dot-stale { background: var(--amber); }
5555
5629
  @keyframes status-disc-pulse {
5556
5630
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 55%, transparent); }
5557
5631
  50% { box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent) 0%, transparent); }
@@ -5613,7 +5687,7 @@
5613
5687
  /* Rail tones MUST match .row.rail-* in app-shell.css so the same semantic state
5614
5688
  reads as one colour across the conversation list and content rows. */
5615
5689
  .ds-247420 .ds-session-row.rail-green::before { background: var(--accent); }
5616
- .ds-247420 .ds-session-row.rail-purple::before { background: var(--purple-2, #7F18A4); }
5690
+ .ds-247420 .ds-session-row.rail-purple::before { background: var(--purple-2); }
5617
5691
  .ds-247420 .ds-session-row.rail-flame::before { background: var(--flame); }
5618
5692
  .ds-247420 .ds-session-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
5619
5693
  .ds-247420 .ds-session-title { font-size: var(--fs-sm); color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@@ -5644,7 +5718,8 @@
5644
5718
  background: color-mix(in oklab, var(--warn) 12%, transparent); color: var(--warn);
5645
5719
  }
5646
5720
  .ds-247420 .ds-dash-header .btn-primary.danger.is-armed { background: var(--warn); color: var(--paper); border-color: var(--warn); }
5647
- .ds-247420 .ds-dash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-3); padding: var(--space-4); }
5721
+ .ds-247420 .ds-dash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-2); padding: var(--space-3); }
5722
+ @media (min-width: 1500px) { .ds-247420 .ds-dash-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); } }
5648
5723
  .ds-247420 .ds-dash-card { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-2); }
5649
5724
  .ds-247420 .ds-dash-card.is-error { border-color: var(--flame); }
5650
5725
  .ds-247420 .ds-dash-card-head { display: flex; align-items: center; gap: var(--space-2); }
@@ -5714,11 +5789,16 @@
5714
5789
  .ds-247420 button.chat-composer-context:hover { color: var(--fg-2); }
5715
5790
  .ds-247420 button.chat-composer-context:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
5716
5791
 
5792
+ /* Composer send/cancel button row: a non-wrapping cluster pinned to the
5793
+ bottom-right of the flex-end composer (was unstyled, so the send button
5794
+ could wrap below the textarea instead of anchoring like claude.ai/code). */
5795
+ .ds-247420 .chat-composer-toolbar { display: flex; align-items: center; gap: var(--space-1); flex: 0 0 auto; margin-left: auto; align-self: flex-end; }
5796
+
5717
5797
  /* --- B2: follow-up chips below the last settled assistant turn. --- */
5718
5798
  .ds-247420 .agentchat-followups { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-2) var(--space-3); }
5719
5799
 
5720
5800
  /* --- C1: stale/idle dashboard status (static, NOT pulsing). --- */
5721
- .ds-247420 .ds-dash-status.is-stale { color: var(--amber, #d9a93a); }
5801
+ .ds-247420 .ds-dash-status.is-stale { color: var(--amber); }
5722
5802
  .ds-247420 .ds-dash-status.is-running { color: var(--accent); }
5723
5803
 
5724
5804
  /* --- C2: dashboard sort/filter toolbar + stream-state line. --- */
@@ -5736,7 +5816,7 @@
5736
5816
  }
5737
5817
  .ds-247420 .ds-dash-stream { font-size: var(--fs-tiny); color: var(--fg-3); }
5738
5818
  .ds-247420 .ds-dash-stream.is-lost { color: var(--flame); }
5739
- .ds-247420 .ds-dash-stream.is-connecting { color: var(--amber, #d9a93a); }
5819
+ .ds-247420 .ds-dash-stream.is-connecting { color: var(--amber); }
5740
5820
  .ds-247420 .ds-dash-header .spread { flex: 1; }
5741
5821
  .ds-247420 .ds-dash-errors-toggle {
5742
5822
  padding: 4px 10px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
@@ -5762,7 +5842,7 @@
5762
5842
  /* Stale/idle card: a positive amber inset bar (mirrors is-active) so a stuck
5763
5843
  agent is flagged in a dense grid, not merely faded near-invisibly. The word
5764
5844
  'idle' co-carries state, so this stays colour-blind safe. */
5765
- .ds-247420 .ds-dash-card.is-stale { box-shadow: inset 2px 0 0 var(--amber, #d9a93a); }
5845
+ .ds-247420 .ds-dash-card.is-stale { box-shadow: inset 2px 0 0 var(--amber); }
5766
5846
 
5767
5847
  /* --- H3: dashboard live disc pulses; stale/error do not (handled by H1). --- */
5768
5848
 
@@ -5919,7 +5999,7 @@
5919
5999
  }
5920
6000
 
5921
6001
  /* Stopping state: in-flight cancel reads distinctly from running/error. */
5922
- .ds-247420 .ds-dash-status.is-stopping { color: var(--amber, #d9a93a); }
6002
+ .ds-247420 .ds-dash-status.is-stopping { color: var(--amber); }
5923
6003
 
5924
6004
  /* External (observed, not owned) session card: no stop control exists. */
5925
6005
  .ds-247420 .ds-dash-external {
@@ -5939,7 +6019,10 @@
5939
6019
  avatar-disc + colored-bubble layout. AgentChat passes flat:true; the demo
5940
6020
  Chat keeps the bubble layout. Turns are full-width to --measure; the user vs
5941
6021
  assistant distinction is a role label + a faint assistant background. */
5942
- .ds-247420 .chat-msg-flat { display: block; padding: var(--space-3) var(--space-4); margin: 0; background: none; border-radius: var(--r-2); }
6022
+ /* Center the flat turn at the reading measure so a wide content column does not
6023
+ dump a one-sided dead gutter (claude.ai/code centers the thread). Padding
6024
+ scales through --density so data-density=compact tightens the thread. */
6025
+ .ds-247420 .chat-msg-flat { display: block; max-width: var(--measure); margin-inline: auto; padding: calc(var(--space-3) * var(--density, 1)) var(--space-4); margin-block: 0; background: none; border-radius: var(--r-2); }
5943
6026
  .ds-247420 .chat-msg-flat.them { background: color-mix(in oklab, var(--fg) 3%, transparent); }
5944
6027
  .ds-247420 .chat-msg-flat.you { background: none; }
5945
6028
  .ds-247420 .chat-msg-flat .chat-stack { max-width: var(--measure); width: 100%; margin: 0; align-items: stretch; }
@@ -5948,8 +6031,10 @@
5948
6031
  .ds-247420 .chat-msg-flat.you .chat-role { color: var(--accent); }
5949
6032
  .ds-247420 .chat-msg-flat .chat-bubble { background: none; border: none; border-radius: 0; padding: 0; max-width: 100%; box-shadow: none; transform: none; }
5950
6033
  .ds-247420 .chat-msg-flat.you .chat-bubble { background: none; color: inherit; }
5951
- .ds-247420 .chat-msg-flat:hover { background: color-mix(in oklab, var(--fg) 3%, transparent); }
5952
- .ds-247420 .chat-msg-flat.you:hover { background: color-mix(in oklab, var(--fg) 2%, transparent); }
6034
+ /* Hover tint exceeds each role's REST tint so the row gives feedback (and the
6035
+ ladder stays monotonic): assistant 5% > its 3% rest; user 4% > transparent. */
6036
+ .ds-247420 .chat-msg-flat.them:hover { background: color-mix(in oklab, var(--fg) 5%, transparent); }
6037
+ .ds-247420 .chat-msg-flat.you:hover { background: color-mix(in oklab, var(--fg) 4%, transparent); }
5953
6038
  .ds-247420 .chat-msg-flat:hover .chat-bubble { transform: none; box-shadow: none; background: none; }
5954
6039
  .ds-247420 .chat-msg-flat .chat-avatar { display: none; }
5955
6040
 
@@ -5983,6 +6068,9 @@
5983
6068
  }
5984
6069
  .ds-247420 .chat-msg .chat-tool.tool-running .chat-tool-status { color: var(--accent); background: color-mix(in oklab, var(--accent) 12%, transparent); }
5985
6070
  .ds-247420 .chat-msg .chat-tool.tool-error .chat-tool-status { color: var(--flame); background: color-mix(in oklab, var(--flame) 12%, transparent); }
6071
+ /* Completed tool: a positive (success) tone so done reads distinctly from the
6072
+ neutral pill and from the accent-toned running pill (--success = green-2). */
6073
+ .ds-247420 .chat-msg .chat-tool.tool-done .chat-tool-status { color: var(--success); background: color-mix(in oklab, var(--success) 12%, transparent); }
5986
6074
  .ds-247420 .chat-tool-body { border-top: var(--bw-hair) solid var(--rule); padding: var(--space-2) var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
5987
6075
  .ds-247420 .chat-tool-section { display: flex; flex-direction: column; gap: var(--space-1); }
5988
6076
  .ds-247420 .chat-tool-section-label { font-size: var(--fs-tiny); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tr-caps); color: var(--fg-3); }
@@ -6017,6 +6105,10 @@
6017
6105
  }
6018
6106
  @keyframes ds-arm-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--warn) 55%, transparent); } 100% { box-shadow: 0 0 0 6px color-mix(in oklab, var(--warn) 0%, transparent); } }
6019
6107
  .ds-247420 .ds-dash-card.is-new { box-shadow: inset 2px 0 0 var(--accent), 0 0 0 1px color-mix(in oklab, var(--accent) 40%, transparent); }
6108
+ /* Error card carries the strongest left-bar tone (flame > stale amber > active
6109
+ accent), placed last so its inset bar wins source order over is-active/is-stale.
6110
+ The full-perimeter border-color (line ~396) stays for extra severity emphasis. */
6111
+ .ds-247420 .ds-dash-card.is-error { box-shadow: inset 2px 0 0 var(--flame); }
6020
6112
  @media (prefers-reduced-motion: no-preference) {
6021
6113
  .ds-247420 .ds-dash-card.is-new { animation: ds-card-in var(--dur-slow) var(--ease); }
6022
6114
  }
@@ -6028,7 +6120,7 @@
6028
6120
  .ds-247420 .ds-dash-breakdown { display: flex; align-items: center; gap: var(--space-1); font-size: var(--fs-sm); color: var(--fg-2); }
6029
6121
  .ds-247420 .ds-dash-breakdown .seg.is-running { color: var(--green); font-weight: 600; }
6030
6122
  .ds-247420 .ds-dash-breakdown .seg.is-error { color: var(--flame); font-weight: 600; }
6031
- .ds-247420 .ds-dash-breakdown .seg.is-idle { color: var(--amber, #d9a93a); }
6123
+ .ds-247420 .ds-dash-breakdown .seg.is-idle { color: var(--amber); }
6032
6124
  .ds-247420 .ds-dash-stream-disc { display: inline-flex; align-items: center; gap: var(--space-1); }
6033
6125
  .ds-247420 .ds-dash-selectall { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--fs-tiny); color: var(--fg-2); cursor: pointer; background: none; border: none; padding: var(--space-1); }
6034
6126
  .ds-247420 .ds-dash-selectall:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
@@ -6049,7 +6141,7 @@
6049
6141
  .ds-247420 .ds-preview-code code { color: var(--fg); }
6050
6142
  .ds-247420 .ds-preview-code .token.comment, .ds-247420 .ds-preview-code .token.prolog, .ds-247420 .ds-preview-code .token.doctype, .ds-247420 .ds-preview-code .token.cdata { color: var(--fg-3); }
6051
6143
  .ds-247420 .ds-preview-code .token.punctuation { color: var(--fg-2); }
6052
- .ds-247420 .ds-preview-code .token.property, .ds-247420 .ds-preview-code .token.tag, .ds-247420 .ds-preview-code .token.boolean, .ds-247420 .ds-preview-code .token.number, .ds-247420 .ds-preview-code .token.constant, .ds-247420 .ds-preview-code .token.symbol { color: var(--purple-2, #7F18A4); }
6144
+ .ds-247420 .ds-preview-code .token.property, .ds-247420 .ds-preview-code .token.tag, .ds-247420 .ds-preview-code .token.boolean, .ds-247420 .ds-preview-code .token.number, .ds-247420 .ds-preview-code .token.constant, .ds-247420 .ds-preview-code .token.symbol { color: var(--purple-2); }
6053
6145
  .ds-247420 .ds-preview-code .token.selector, .ds-247420 .ds-preview-code .token.attr-name, .ds-247420 .ds-preview-code .token.string, .ds-247420 .ds-preview-code .token.char, .ds-247420 .ds-preview-code .token.builtin { color: var(--code-string, var(--green)); }
6054
6146
  .ds-247420 .ds-preview-code .token.atrule, .ds-247420 .ds-preview-code .token.attr-value, .ds-247420 .ds-preview-code .token.keyword { color: var(--code-keyword, var(--sky)); }
6055
6147
  .ds-247420 .ds-preview-code .token.function, .ds-247420 .ds-preview-code .token.class-name { color: var(--code-fn, var(--flame)); }
@@ -6095,6 +6187,11 @@
6095
6187
  .ds-247420 .row-act, .ds-247420 .ds-dash-errors-toggle, .ds-247420 .agentchat-export-act, .ds-247420 .ds-file-more-btn, .ds-247420 .agentchat-install-copy, .ds-247420 .ds-upload-act, .ds-247420 .ds-session-meta-copy { min-height: 44px; }
6096
6188
  }
6097
6189
 
6190
+ /* 11th run: ultrawide widens the reading measure where there is room. */
6191
+ @media (min-width: 1600px) {
6192
+ .ds-247420 .agentchat-thread { --measure: 84ch; }
6193
+ }
6194
+
6098
6195
  /* editor-primitives.css */
6099
6196
  /* editor-primitives.css — chrome for in-engine editors, inspectors, IDEs,
6100
6197
  debug HUDs. All rules under .ds-247420 scope (build prefixes). Tokens
@@ -7410,6 +7507,231 @@
7410
7507
  align-content: start;
7411
7508
  }
7412
7509
 
7510
+ /* app-surfaces.css */
7511
+ /* app-surfaces.css — agentgui application-surface styling.
7512
+ *
7513
+ * Owns every design decision for the agentgui consumer app's own surfaces
7514
+ * (the bits the app composes around the flagship kit components): the project
7515
+ * filter pills, the working-directory bar, the resume banner, the backend
7516
+ * health chips, the settings two-column grid, the history empty state, the
7517
+ * boot splash, the chat control cluster, and the cross-cutting base (scrollbar
7518
+ * theming, focus rings, print). These previously lived as a hand-rolled inline
7519
+ * \3c style> block in agentgui's index.html; the kit now owns them so NO design
7520
+ * content lives in the consumer app.
7521
+ *
7522
+ * Every selector is written pre-scoped under `.ds-247420` (the consumer mounts
7523
+ * on <html class="ds-247420">), so the build's selector-prefixer leaves them
7524
+ * untouched rather than mis-compounding the `[attr]` / `*` / bare-element
7525
+ * selectors. All colour/space/radius/font values read from kit tokens
7526
+ * (colors_and_type.css) — there are no app-local colour fallbacks. */
7527
+
7528
+ /* Visually-hidden but screen-reader-available (aria-live announcer, labels). */
7529
+ .ds-247420 .sr-only {
7530
+ position: absolute !important; width: 1px; height: 1px;
7531
+ padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
7532
+ white-space: nowrap; border: 0;
7533
+ }
7534
+
7535
+ /* Base: full-height app root reading kit tokens. */
7536
+ .ds-247420, .ds-247420 body { margin: 0; height: 100%; }
7537
+ .ds-247420 body {
7538
+ background: var(--bg);
7539
+ color: var(--fg);
7540
+ font-family: var(--ff-display, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);
7541
+ }
7542
+ .ds-247420 #app { height: 100vh; height: 100dvh; }
7543
+ .ds-247420 #app > * { height: 100%; }
7544
+
7545
+ /* Themed thin scrollbars — the native chrome scrollbar is chunky/light and
7546
+ clashes with the dark theme on the history sidebar and settings column. */
7547
+ .ds-247420 * {
7548
+ scrollbar-width: thin;
7549
+ scrollbar-color: color-mix(in srgb, var(--fg) 22%, transparent) transparent;
7550
+ }
7551
+ .ds-247420 *::-webkit-scrollbar { width: 9px; height: 9px; }
7552
+ .ds-247420 *::-webkit-scrollbar-track { background: transparent; }
7553
+ .ds-247420 *::-webkit-scrollbar-thumb {
7554
+ background: color-mix(in srgb, var(--fg) 20%, transparent);
7555
+ border-radius: 999px;
7556
+ border: 2px solid transparent;
7557
+ background-clip: padding-box;
7558
+ }
7559
+ .ds-247420 *::-webkit-scrollbar-thumb:hover {
7560
+ background: color-mix(in srgb, var(--fg) 34%, transparent);
7561
+ background-clip: padding-box;
7562
+ }
7563
+
7564
+ /* We move focus to the page heading on tab change for AT users; suppress the
7565
+ resulting outline box on those programmatically-focused elements. */
7566
+ .ds-247420 [data-prog-focus]:focus,
7567
+ .ds-247420 [data-prog-focus]:focus-visible { outline: none !important; box-shadow: none !important; }
7568
+
7569
+ /* The connection-dot disc + pulse are the kit's canonical .status-dot-disc;
7570
+ only the inline-flex wrapper layout stays here. */
7571
+ .ds-247420 .status-dot { display: inline-flex; align-items: center; gap: .4em; white-space: nowrap; }
7572
+
7573
+ /* Resume banner. */
7574
+ .ds-247420 .resume-banner {
7575
+ padding: .6em .8em;
7576
+ background: color-mix(in srgb, var(--accent) 12%, transparent);
7577
+ border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
7578
+ border-radius: var(--r-1, 8px);
7579
+ display: flex; justify-content: space-between; align-items: center; gap: .75em;
7580
+ margin-bottom: .75em;
7581
+ }
7582
+
7583
+ /* History action buttons. */
7584
+ .ds-247420 .history-actions { display: flex; gap: .5em; padding: 0 0 .75em 0; flex-wrap: wrap; }
7585
+
7586
+ /* Empty / loading state. */
7587
+ .ds-247420 .empty-state { display: flex; gap: 8px; align-items: center; padding: .5em 0; white-space: normal; }
7588
+ .ds-247420 p.empty-state { text-align: left; padding: .6em 0; color: var(--fg-3); }
7589
+
7590
+ /* Project filter pills. */
7591
+ .ds-247420 .pill-row { display: flex; flex-wrap: wrap; gap: .35em; padding: .35em 0; }
7592
+ .ds-247420 .pill {
7593
+ cursor: pointer; padding: .25em .7em; border-radius: 999px;
7594
+ border: 1px solid transparent; background: transparent;
7595
+ font: inherit; color: inherit; line-height: 1.4;
7596
+ transition: background-color .15s ease, border-color .15s ease;
7597
+ min-height: 28px;
7598
+ }
7599
+ .ds-247420 .pill:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
7600
+ .ds-247420 .pill.pill-active {
7601
+ background: color-mix(in srgb, var(--accent) 18%, transparent);
7602
+ border-color: color-mix(in srgb, var(--accent) 40%, transparent);
7603
+ }
7604
+ .ds-247420 .pill:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
7605
+
7606
+ /* Subagent toggle (the control itself is the kit Checkbox). */
7607
+ .ds-247420 .subagent-toggle { padding: .4em 0; min-height: 32px; }
7608
+
7609
+ .ds-247420 .field-error { color: var(--warn); }
7610
+
7611
+ /* Boot splash: static text painted with the HTML, replaced by the first mount. */
7612
+ .ds-247420 .boot-splash { height: 100%; min-height: 60vh; display: flex; align-items: center; justify-content: center; color: var(--fg-3); font-size: .9rem; }
7613
+
7614
+ /* Chat control cluster in the crumb bar: model picker, +new, status. */
7615
+ .ds-247420 .chat-controls { display: flex; align-items: center; gap: .6em; flex-wrap: wrap; }
7616
+ .ds-247420 .chat-controls > * { flex: 0 0 auto; }
7617
+ .ds-247420 .chat-controls select,
7618
+ .ds-247420 .chat-controls .select,
7619
+ .ds-247420 .chat-controls [role="combobox"] { min-width: 130px; max-width: 220px; }
7620
+ .ds-247420 .chat-controls .status-dot { white-space: nowrap; }
7621
+
7622
+ /* Main content region layout: every tab is a min-height:0 scroll host; the
7623
+ chat tab additionally flexes as a column so the thread fills the viewport. */
7624
+ .ds-247420 .agentgui-main { min-height: 0; }
7625
+ .ds-247420 .agentgui-main-chat { display: flex; flex-direction: column; flex: 1; }
7626
+ .ds-247420 .agentgui-main .ds-section { margin: 0 0 var(--space-4, 16px); }
7627
+
7628
+ /* Readable backend health summary (replaces raw JSON dump). */
7629
+ .ds-247420 .health-summary { display: flex; flex-wrap: wrap; gap: .4em; margin: .6em 0; }
7630
+ .ds-247420 .health-chip {
7631
+ font-family: var(--ff-mono, ui-monospace, monospace);
7632
+ font-size: .8rem; padding: .15em .55em; border-radius: 6px;
7633
+ background: color-mix(in srgb, var(--fg) 8%, transparent);
7634
+ color: var(--fg-2);
7635
+ border: 1px solid color-mix(in srgb, var(--fg) 12%, transparent);
7636
+ }
7637
+ .ds-247420 .health-summary.health-ok .health-chip:first-child {
7638
+ color: var(--accent);
7639
+ border-color: color-mix(in srgb, var(--accent) 40%, transparent);
7640
+ }
7641
+
7642
+ /* Compact working-directory bar. */
7643
+ .ds-247420 .cwd-bar {
7644
+ display: flex; align-items: center; gap: .5em; flex-wrap: wrap;
7645
+ padding: .15em 0 .5em; font-size: .85rem;
7646
+ }
7647
+ .ds-247420 .cwd-bar-text {
7648
+ font-family: var(--ff-mono, ui-monospace, monospace);
7649
+ color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60vw;
7650
+ }
7651
+ .ds-247420 .cwd-bar-btn {
7652
+ cursor: pointer; font: inherit; line-height: 1.3;
7653
+ padding: .15em .55em; border-radius: 6px;
7654
+ background: color-mix(in srgb, var(--fg) 8%, transparent);
7655
+ border: 1px solid color-mix(in srgb, var(--fg) 14%, transparent);
7656
+ color: var(--fg-2);
7657
+ }
7658
+ .ds-247420 .cwd-bar-btn:hover { background: color-mix(in srgb, var(--fg) 14%, transparent); }
7659
+ .ds-247420 .cwd-bar-btn:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
7660
+
7661
+ /* History no-session empty state: fill the void with a centered prompt. */
7662
+ .ds-247420 .history-empty {
7663
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
7664
+ gap: .4em; text-align: center; min-height: 50vh; color: var(--fg-3);
7665
+ }
7666
+ .ds-247420 .history-empty-title { margin: 0; font-size: 1.05rem; color: var(--fg-2); }
7667
+ .ds-247420 .history-empty-sub { margin: 0; max-width: 42ch; }
7668
+
7669
+ /* Settings: two-column on wide screens (backend + agents). */
7670
+ .ds-247420 .settings-grid {
7671
+ display: grid; gap: var(--space-4, 16px);
7672
+ grid-template-columns: minmax(0, 1fr);
7673
+ align-items: start;
7674
+ }
7675
+ .ds-247420 .agentgui-main-settings .settings-grid { margin-top: 0; }
7676
+
7677
+ /* The kit Chat head computes its own zero-padded count and ignores our sub
7678
+ prop; hide it (streaming state shows via the title + busy banner). */
7679
+ .ds-247420 .chat-head .sub { display: none; }
7680
+
7681
+ /* Event-list row hover + search-result flash. */
7682
+ .ds-247420 .ds-event-list .row[role="button"]:hover { background: color-mix(in srgb, var(--fg) 5%, transparent); }
7683
+ .ds-247420 .ds-event-list .row.event-flash { animation: agentgui-event-flash 2s ease-out; }
7684
+
7685
+ /* Chat composer: hide the idle scrollbar on the (empty/short) textarea. */
7686
+ .ds-247420 .chat-composer textarea { overflow-y: auto; scrollbar-width: thin; }
7687
+ .ds-247420 .chat-composer textarea:not(:focus) { overflow-y: hidden; }
7688
+
7689
+ /* Generic interactive focus ring for app-emitted controls. */
7690
+ .ds-247420 button:focus-visible,
7691
+ .ds-247420 [tabindex]:focus-visible,
7692
+ .ds-247420 a:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
7693
+
7694
+ /* Settings-panel field spacing utilities (replace app.js inline style= margins). */
7695
+ .ds-247420 .agentgui-field-mb { margin: 0 0 .5em; }
7696
+ .ds-247420 .agentgui-field-my { margin: .5em 0; }
7697
+
7698
+ @keyframes agentgui-event-flash {
7699
+ 0% { background: color-mix(in srgb, var(--accent) 40%, transparent); }
7700
+ 100% { background: transparent; }
7701
+ }
7702
+
7703
+ @media (min-width: 900px) {
7704
+ .ds-247420 .settings-grid { grid-template-columns: minmax(0, 420px) minmax(0, 1fr); }
7705
+ }
7706
+
7707
+ /* Tablet: keep the chat control cluster from wrapping the status dot alone. */
7708
+ @media (max-width: 900px) {
7709
+ .ds-247420 .chat-controls select,
7710
+ .ds-247420 .chat-controls .select,
7711
+ .ds-247420 .chat-controls [role="combobox"] { min-width: 110px; max-width: 170px; }
7712
+ }
7713
+
7714
+ /* Touch targets on small screens. */
7715
+ @media (max-width: 640px) {
7716
+ .ds-247420 .pill { min-height: 36px; padding: .4em .8em; }
7717
+ .ds-247420 .history-actions { gap: .75em; }
7718
+ .ds-247420 .history-actions .btn, .ds-247420 .history-actions button { min-height: 44px; }
7719
+ .ds-247420 .cwd-bar-text { max-width: 42vw; }
7720
+ .ds-247420 .cwd-bar { gap: .3em; }
7721
+ }
7722
+
7723
+ @media (prefers-reduced-motion: reduce) {
7724
+ .ds-247420 .ds-event-list .row.event-flash { animation: none; outline: 2px solid var(--accent); }
7725
+ }
7726
+
7727
+ @media print {
7728
+ .ds-247420 #app { min-height: auto; display: block; height: auto; }
7729
+ .ds-247420 .skip-link, .ds-247420 .status-dot, .ds-247420 .history-actions, .ds-247420 .chat-composer { display: none !important; }
7730
+ .ds-247420 .app, .ds-247420 .app-main, .ds-247420 .panel, .ds-247420 .chat, .ds-247420 .chat-thread {
7731
+ background: #fff !important; color: #000 !important; box-shadow: none !important;
7732
+ }
7733
+ }
7734
+
7413
7735
  /* spoint/loading-screen.css */
7414
7736
  /* Loading-screen kit styles. Scoped under .ds-247420 at build time.
7415
7737
  All colors reference design tokens (no raw literals) per the token-lint gate. */