anentrypoint-design 0.0.208 → 0.0.210

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
@@ -37,9 +37,21 @@
37
37
 
38
38
  /* Signals */
39
39
  --sun: #F5C344;
40
- --flame: #FF5A1F;
40
+ /* Error/status tones are theme-tuned: the root values are the LIGHT (paper)
41
+ pair (flame 4.74:1, amber 4.5+:1 on paper); the dark blocks below restore
42
+ the originals (#FF5A1F / #D9A93A) which were tuned on ink and fail on
43
+ paper (2.9:1 / 2.0:1). */
44
+ --flame: #C53E00;
45
+ --amber: #8A6512;
41
46
  --sky: #3A6EFF;
42
47
  --warn: #E0241A;
48
+ /* Syntax-token aliases: light values pass 4.5:1 on paper; the dark blocks
49
+ restore the bright dark-tuned originals. Components reference ONLY these. */
50
+ --code-string: var(--green);
51
+ --code-keyword: #2453C9;
52
+ --code-fn: #B84300;
53
+ --code-str-alt: var(--mascot-deep);
54
+ --code-num: #946300;
43
55
  --danger: oklch(0.55 0.18 25);
44
56
  --success: var(--green-2);
45
57
  --live: var(--green);
@@ -248,6 +260,13 @@
248
260
  --accent-fg: var(--ink);
249
261
  --accent-bright: var(--green-2);
250
262
  --danger: oklch(0.68 0.19 25);
263
+ --flame: #FF5A1F;
264
+ --amber: #D9A93A;
265
+ --code-string: var(--green-2);
266
+ --code-keyword: var(--sky);
267
+ --code-fn: var(--flame);
268
+ --code-str-alt: var(--mascot);
269
+ --code-num: var(--sun);
251
270
  }
252
271
 
253
272
  /* NOTE: the [data-theme="auto"] block below intentionally duplicates the
@@ -274,6 +293,13 @@
274
293
  --accent: var(--accent-bright, var(--green-2));
275
294
  --accent-fg: var(--ink);
276
295
  --accent-bright: var(--green-2);
296
+ --flame: #FF5A1F;
297
+ --amber: #D9A93A;
298
+ --code-string: var(--green-2);
299
+ --code-keyword: var(--sky);
300
+ --code-fn: var(--flame);
301
+ --code-str-alt: var(--mascot);
302
+ --code-num: var(--sun);
277
303
  }
278
304
  }
279
305
 
@@ -312,6 +338,11 @@
312
338
  --cat-sun: inherit;
313
339
  --cat-flame: inherit;
314
340
  --cat-sky: inherit;
341
+ --code-string: inherit;
342
+ --code-keyword: inherit;
343
+ --code-fn: inherit;
344
+ --code-str-alt: inherit;
345
+ --code-num: inherit;
315
346
  }
316
347
 
317
348
  /* ============================================================
@@ -328,6 +359,8 @@
328
359
  --bg: var(--paper); --bg-2: var(--paper-2); --bg-3: var(--paper-3);
329
360
  --fg: var(--ink); --fg-2: var(--ink-2); --fg-3: var(--ink-3);
330
361
  --accent: var(--green); --accent-fg: var(--paper);
362
+ /* A paper island under a dark ancestor must not inherit the dark signal pair. */
363
+ --flame: #C53E00; --amber: #8A6512;
331
364
  }
332
365
 
333
366
  /* thebird — warm-paper brand preset. A first-class swappable theme: it lives
@@ -544,8 +577,8 @@
544
577
  margin: 0;
545
578
  border-radius: var(--r-3);
546
579
  }
547
- .ds-247420 pre .k { color: var(--mascot); }
548
- .ds-247420 pre .s { color: var(--sun); }
580
+ .ds-247420 pre .k { color: var(--code-str-alt, var(--mascot)); }
581
+ .ds-247420 pre .s { color: var(--code-string, var(--green)); }
549
582
  .ds-247420 pre .c { color: var(--fg-3); }
550
583
  .ds-247420 pre .n { color: var(--green-2); }
551
584
 
@@ -591,7 +624,7 @@
591
624
  .ds-247420 body.canvas-host { background: transparent !important; }
592
625
 
593
626
  .ds-247420 {
594
- --app-status-h: var(--size-base);
627
+ --app-status-h: 26px;
595
628
  --app-topbar-h: var(--size-lg);
596
629
  --app-crumb-h: var(--size-sm);
597
630
  }
@@ -785,27 +818,37 @@
785
818
  .ds-247420 .app-status {
786
819
  display: flex; align-items: center; gap: var(--space-3);
787
820
  width: 100%;
788
- min-height: var(--app-status-h);
789
- padding: 10px var(--pad-x);
790
- font-family: var(--ff-mono); font-size: var(--fs-xs);
821
+ height: var(--app-status-h); min-height: var(--app-status-h);
822
+ /* A thin desktop status strip, not a webpage footer band. */
823
+ padding: 0 var(--space-4);
824
+ /* Status chrome is prose, not code - mono is reserved for code/paths. */
825
+ font-family: var(--ff-body); font-size: var(--fs-xs); line-height: 1.2;
791
826
  color: var(--fg-3);
792
827
  border-top: 1px solid var(--rule);
793
828
  }
794
- .ds-247420 .app-status .item { color: inherit; }
829
+ .ds-247420 .app-status .item { color: inherit; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
795
830
  .ds-247420 .app-status .item:first-of-type { color: var(--accent); }
796
831
  .ds-247420 .app-status .spread { flex: 1; }
832
+ /* The status bar NEVER wraps: at narrow widths the trailing items (hints,
833
+ agent target) drop in priority order instead of breaking mid-word onto a
834
+ second line. */
835
+ .ds-247420 .app-status { flex-wrap: nowrap; overflow: hidden; }
836
+ @media (max-width: 1100px) {
837
+ .ds-247420 .app-status .item:last-of-type:not(:only-of-type) { display: none; }
838
+ }
797
839
 
798
840
  /* ============================================================
799
841
  Primitives
800
842
  ============================================================ */
801
843
  .ds-247420 .btn, .ds-247420 .btn-primary, .ds-247420 .btn-ghost {
802
- display: inline-flex; align-items: center; gap: 8px;
803
- padding: 13px 22px;
844
+ display: inline-flex; align-items: center; justify-content: center; gap: 6px;
845
+ padding: 8px 14px; min-height: 32px;
804
846
  font-family: var(--ff-body);
805
847
  font-weight: 600; font-size: var(--fs-sm);
806
848
  text-decoration: none;
807
849
  cursor: pointer;
808
- border-radius: var(--r-pill);
850
+ /* Rounded-rect app chrome, not a marketing-page stadium CTA. */
851
+ border-radius: var(--r-1);
809
852
  border: 0;
810
853
  transition: transform var(--dur-snap) var(--ease), background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
811
854
  }
@@ -840,7 +883,8 @@
840
883
  .ds-247420 .ds-icon-btn-ghost:hover { background: var(--bg-2); }
841
884
  .ds-247420 .ds-icon-btn-primary { background: var(--accent); color: var(--accent-fg); }
842
885
  .ds-247420 .ds-icon-btn-primary:hover { background: var(--fg); color: var(--bg); }
843
- .ds-247420 .ds-icon-btn-danger { background: var(--flame); color: var(--paper); }
886
+ /* warn = destructive ACTION tone; flame stays exclusively error STATUS. */
887
+ .ds-247420 .ds-icon-btn-danger { background: var(--warn); color: var(--paper); }
844
888
  .ds-247420 .ds-icon-btn-danger:hover { filter: brightness(1.1); }
845
889
  .ds-247420 .ds-icon-btn:active { transform: translateY(1px); }
846
890
  .ds-247420 .ds-icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@@ -914,11 +958,15 @@
914
958
  .ds-247420 .panel.panel-wide { background: transparent; }
915
959
  .ds-247420 .panel-head {
916
960
  display: flex; align-items: baseline; justify-content: space-between;
917
- padding: var(--space-4) var(--space-5) var(--space-3);
961
+ /* Shares the .panel-body 16px side padding so the caps label and the body
962
+ rows sit on ONE left axis (the old 24/32 padding was authored for the
963
+ pre-padding .panel-wide era and indented the label 16px past its content). */
964
+ padding: var(--space-2) var(--space-3);
918
965
  font-size: var(--fs-xs); font-weight: 600;
919
966
  color: var(--fg-3);
920
967
  letter-spacing: var(--tr-caps); text-transform: uppercase;
921
968
  }
969
+ .ds-247420 .panel.panel-wide .panel-head { padding-left: 0; padding-right: 0; }
922
970
  .ds-247420 .panel-head > :last-child {
923
971
  font-weight: 500; color: var(--fg-3);
924
972
  font-family: var(--ff-mono); letter-spacing: 0;
@@ -986,6 +1034,12 @@
986
1034
  .ds-247420 .row .code { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }
987
1035
  .ds-247420 .row .title { font-family: var(--ff-body); font-weight: 600; font-size: var(--fs-lg); line-height: var(--lh-snug, 1.3); display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; min-width: 0; }
988
1036
  .ds-247420 .row .title .sub { font-family: var(--ff-body); font-weight: 400; font-size: var(--fs-sm); color: var(--fg-3); }
1037
+ /* App typescale: list rows are quiet working chrome (the 18px/600 default is a
1038
+ marketing-surface voice). One size for ALL app list rows - matches
1039
+ .ds-file-row/.ds-session-title at fs-sm/500; values mirror the kit's own
1040
+ mobile block below. Marketing pages without data-typescale keep the default. */
1041
+ .ds-247420[data-typescale="app"] .row { padding: 12px 16px; }
1042
+ .ds-247420[data-typescale="app"] .row .title { font-size: var(--fs-sm); font-weight: 500; }
989
1043
  .ds-247420 .row .sub { font-family: var(--ff-body); font-weight: 400; font-size: var(--fs-sm); color: var(--fg-3); }
990
1044
  .ds-247420 .row .meta { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; align-self: center; }
991
1045
  /* WorksList meta pairs a label with a disclosure chevron, inline-aligned. */
@@ -1431,8 +1485,8 @@
1431
1485
  padding: 12px 18px; font-size: var(--fs-sm);
1432
1486
  }
1433
1487
 
1434
- /* Panel */
1435
- .ds-247420 .panel-head { padding: var(--space-4) var(--space-4); }
1488
+ /* Panel - keep the head on the body's left axis at laptop widths too. */
1489
+ .ds-247420 .panel-head { padding: var(--space-2) var(--space-3); }
1436
1490
  .ds-247420 .panel-body { padding: var(--space-2) var(--space-3); }
1437
1491
 
1438
1492
  /* Hero — fluid base font-size; only width unconstrained on tablet. */
@@ -1504,13 +1558,15 @@
1504
1558
 
1505
1559
  /* Listing wrapper holds the optional filter + sort header above the grid. */
1506
1560
  .ds-247420 .ds-file-listing { display: flex; flex-direction: column; gap: var(--space-2); min-height: 0; }
1507
- .ds-247420 .ds-file-filter { padding: 0 0 var(--space-1); }
1561
+ /* The quick filter is a compact control, not a full-width form row - a giant
1562
+ input above the grid reads as a search page and costs fold height. */
1563
+ .ds-247420 .ds-file-filter { padding: 0 0 var(--space-1); display: flex; justify-content: flex-end; }
1508
1564
  .ds-247420 .ds-file-filter-input {
1509
- width: 100%; padding: 8px 12px; font-size: var(--fs-sm);
1565
+ width: min(280px, 100%); padding: 6px 12px; font-size: var(--fs-sm);
1510
1566
  background: var(--bg); color: var(--fg);
1511
- border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
1567
+ border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
1512
1568
  }
1513
- .ds-247420 .ds-file-filter-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
1569
+ .ds-247420 .ds-file-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
1514
1570
  .ds-247420 .ds-file-sort { display: flex; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); }
1515
1571
  .ds-247420 .ds-file-sort-btn {
1516
1572
  font-size: var(--fs-tiny); font-family: var(--ff-mono); color: var(--fg-3);
@@ -1522,6 +1578,16 @@
1522
1578
 
1523
1579
  /* Skeleton shimmer rows shown while a directory loads. */
1524
1580
  .ds-247420 .ds-file-row-skeleton { cursor: default; pointer-events: none; }
1581
+ /* In-place refresh: dim the populated grid instead of swapping it for shimmer
1582
+ rows (the rows stay; the round-trip reads as a settle, not a reload). */
1583
+ .ds-247420 .ds-file-grid.is-refreshing { opacity: .6; }
1584
+ @media (prefers-reduced-motion: no-preference) {
1585
+ .ds-247420 .ds-file-grid { transition: opacity .15s var(--ease); }
1586
+ }
1587
+ /* EventList loading skeleton (shares the .ds-skel shimmer base above). */
1588
+ .ds-247420 .ds-event-row-skeleton { display: flex; align-items: center; gap: var(--space-3); padding: 12px 16px; pointer-events: none; }
1589
+ .ds-247420 .ds-skel-rank { height: 12px; width: 2.5ch; }
1590
+ .ds-247420 .ds-event-state { padding: var(--space-2) 16px; }
1525
1591
  .ds-247420 .ds-skel { display: inline-block; border-radius: var(--r-1); background: var(--bg-2); position: relative; overflow: hidden; }
1526
1592
  .ds-247420 .ds-skel::after {
1527
1593
  content: ''; position: absolute; inset: 0;
@@ -1570,7 +1636,7 @@
1570
1636
  .ds-247420 .ds-file-row[data-file-type="code"] { border-left-width: 3px; border-left-color: var(--green-2); }
1571
1637
  .ds-247420 .ds-file-row[data-file-type="text"] { border-left-width: 3px; border-left-color: var(--ink-3); }
1572
1638
  .ds-247420 .ds-file-row[data-file-type="archive"] { border-left-width: 3px; border-left-color: var(--flame); }
1573
- .ds-247420 .ds-file-row[data-file-type="document"] { border-left-width: 3px; border-left-color: var(--sun); }
1639
+ .ds-247420 .ds-file-row[data-file-type="document"] { border-left-width: 3px; border-left-color: var(--amber, var(--sun)); }
1574
1640
  .ds-247420 .ds-file-row[data-file-type="symlink"] { border-left-width: 3px; border-left-color: var(--purple); }
1575
1641
  .ds-247420 .ds-file-row[data-file-type="other"] { border-left-width: 3px; border-left-color: var(--fg-3); }
1576
1642
 
@@ -1601,7 +1667,7 @@
1601
1667
  .ds-247420 .ds-file-row[data-file-type="audio"] .ds-file-icon { color: var(--sky); }
1602
1668
  .ds-247420 .ds-file-row[data-file-type="code"] .ds-file-icon { color: var(--green-2); }
1603
1669
  .ds-247420 .ds-file-row[data-file-type="archive"] .ds-file-icon { color: var(--flame); }
1604
- .ds-247420 .ds-file-row[data-file-type="document"] .ds-file-icon { color: var(--sun); }
1670
+ .ds-247420 .ds-file-row[data-file-type="document"] .ds-file-icon { color: var(--amber, var(--sun)); }
1605
1671
 
1606
1672
  /* Row actions — hidden until hover/focus, revealed without layout shift. */
1607
1673
  .ds-247420 .ds-file-actions {
@@ -1651,6 +1717,19 @@
1651
1717
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
1652
1718
  }
1653
1719
  .ds-247420 .ds-bulkbar-count { font-size: var(--fs-tiny); color: var(--fg-2); }
1720
+ /* BulkBar is a toolbar (it even declares role=toolbar): compact rect buttons,
1721
+ quiet destructive outline - the app arm-confirms destructive bulk actions
1722
+ via ConfirmDialog, so the strip never needs a loud CTA. */
1723
+ .ds-247420 .ds-bulkbar .btn, .ds-247420 .ds-bulkbar .btn-primary {
1724
+ padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
1725
+ }
1726
+ .ds-247420 .ds-bulkbar .btn { background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2); }
1727
+ .ds-247420 .ds-bulkbar .btn:hover { background: var(--bg-2); color: var(--fg); }
1728
+ .ds-247420 .ds-bulkbar .btn-primary.danger { background: transparent; color: var(--warn); border: var(--bw-hair) solid var(--warn); }
1729
+ .ds-247420 .ds-bulkbar .btn-primary.danger:hover { background: color-mix(in oklab, var(--warn) 12%, transparent); color: var(--warn); }
1730
+ @media (pointer: coarse) {
1731
+ .ds-247420 .ds-bulkbar .btn, .ds-247420 .ds-bulkbar .btn-primary { min-height: 44px; }
1732
+ }
1654
1733
 
1655
1734
  /* Density picker — list / compact / thumbnails. */
1656
1735
  .ds-247420 .ds-density {
@@ -1737,6 +1816,11 @@
1737
1816
  .ds-247420 .app-main > div > .ds-file-stage,
1738
1817
  .ds-247420 .app-main .ds-file-stage { padding-top: 0; }
1739
1818
 
1819
+ /* Full-width files stack: the stage's space-3 vertical beat without its
1820
+ 920px cap/auto-margins, so the roots / toolbar / bulkbar / uploads / grid
1821
+ bands keep one consistent rhythm instead of touching edge-to-edge. */
1822
+ .ds-247420 .ds-files-stack { display: flex; flex-direction: column; gap: var(--space-3); min-height: 0; }
1823
+
1740
1824
  /* Breadcrumb path */
1741
1825
  .ds-247420 .ds-crumb-path {
1742
1826
  display: flex; align-items: center; flex-wrap: wrap; gap: 2px;
@@ -1757,10 +1841,38 @@
1757
1841
  display: flex; align-items: center; justify-content: space-between;
1758
1842
  gap: var(--space-2); flex-wrap: wrap;
1759
1843
  }
1844
+ /* Dense page header: one row, small heading, single-line muted lede. The
1845
+ working surfaces (files, live, history, settings) lead with content, not a
1846
+ display H1 + paragraph that costs the first 150px of every fold. */
1847
+ .ds-247420 .ds-page-header-dense { margin: 0 0 var(--space-3); }
1848
+ .ds-247420 .ds-page-header-dense-row { display: flex; align-items: baseline; gap: var(--space-3); min-width: 0; }
1849
+ .ds-247420 .ds-page-header-dense-row h1 {
1850
+ margin: 0; font-size: var(--fs-lg); line-height: 1.3; font-weight: 600;
1851
+ letter-spacing: normal; flex: 0 0 auto;
1852
+ }
1853
+ .ds-247420 .ds-page-header-dense-lede {
1854
+ flex: 1 1 auto; min-width: 0;
1855
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1856
+ font-size: var(--fs-sm); color: var(--fg-3);
1857
+ }
1858
+ .ds-247420 .ds-page-header-dense .ds-page-header-right { flex: 0 0 auto; margin-left: auto; }
1760
1859
  .ds-247420 .ds-file-toolbar-left,
1761
1860
  .ds-247420 .ds-file-toolbar-right {
1762
1861
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
1763
1862
  }
1863
+ /* Toolbar-scoped buttons: quiet, compact, rectangular - a toolbar is chrome,
1864
+ not a CTA row; the stadium pill stays for real page-level actions. */
1865
+ .ds-247420 .ds-file-toolbar .btn, .ds-247420 .ds-file-toolbar .btn-ghost {
1866
+ padding: 5px 12px; min-height: 32px;
1867
+ border-radius: var(--r-1);
1868
+ font-weight: 500;
1869
+ background: transparent;
1870
+ border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
1871
+ }
1872
+ .ds-247420 .ds-file-toolbar .btn:hover, .ds-247420 .ds-file-toolbar .btn-ghost:hover { background: var(--bg-2); color: var(--fg); }
1873
+ @media (pointer: coarse) {
1874
+ .ds-247420 .ds-file-toolbar .btn, .ds-247420 .ds-file-toolbar .btn-ghost { min-height: 44px; }
1875
+ }
1764
1876
  .ds-247420 .ds-meta-mono {
1765
1877
  font-family: var(--ff-mono); font-size: var(--fs-xs);
1766
1878
  color: var(--fg-3); letter-spacing: var(--tr-caps);
@@ -1801,6 +1913,20 @@
1801
1913
  0%, 100% { border-color: var(--accent); }
1802
1914
  50% { border-color: color-mix(in oklab, var(--accent) 45%, transparent); }
1803
1915
  }
1916
+ /* Wrapper form (has children): no permanent chrome - the content renders as if
1917
+ the zone were not there, and the dashed affordance overlays it ONLY while a
1918
+ drag is in flight. */
1919
+ .ds-247420 .ds-dropzone--wrap { position: relative; border: none; border-radius: 0; background: transparent; }
1920
+ .ds-247420 .ds-dropzone--wrap > .ds-dropzone-inner { display: none; }
1921
+ .ds-247420 .ds-dropzone--wrap.dragover > .ds-dropzone-inner {
1922
+ display: flex; position: absolute; inset: 0; z-index: 5;
1923
+ margin: 0; padding: var(--space-3);
1924
+ align-items: center; justify-content: center;
1925
+ background: color-mix(in srgb, var(--bg) 84%, transparent);
1926
+ outline: var(--bw-rule) dashed var(--accent); outline-offset: -6px;
1927
+ border-radius: var(--r-3);
1928
+ }
1929
+ .ds-247420 .ds-dropzone--wrap.dragover { animation: none; }
1804
1930
 
1805
1931
  /* Upload progress */
1806
1932
  .ds-247420 .ds-upload-progress { display: flex; flex-direction: column; gap: 6px; }
@@ -1994,7 +2120,7 @@
1994
2120
  border-radius: var(--r-pill); color: var(--fg);
1995
2121
  font-family: inherit; font-size: var(--fs-xs);
1996
2122
  }
1997
- .ds-247420 .ds-filter-input:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
2123
+ .ds-247420 .ds-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
1998
2124
 
1999
2125
  /* Loading skeleton — placeholder rows while a directory loads. */
2000
2126
  .ds-247420 .ds-file-grid-loading { display: flex; flex-direction: column; gap: 4px; }
@@ -2021,44 +2147,19 @@
2021
2147
  .ds-247420 .ds-file-row[draggable="true"] { cursor: grab; }
2022
2148
  .ds-247420 .ds-file-row[draggable="true"]:active { cursor: grabbing; }
2023
2149
 
2024
- /* Multi-select per-row checkbox overlay + selected state + bulk bar. */
2150
+ /* (A stale duplicate multi-select block used to live here: an absolute-overlay
2151
+ .ds-file-check hidden until hover, plus .ds-file-check.on / .ds-file-row.selected
2152
+ / .ds-bulk-bar rules NO component ever emits. Being later in source at equal
2153
+ specificity it clobbered the real in-flow checkbox at ~1243 - the shipped
2154
+ multi-select rendered invisible-until-hover with clipped brackets. The live
2155
+ rules are the earlier block; only the still-load-bearing bits remain below.) */
2025
2156
  .ds-247420 .ds-file-row { position: relative; }
2026
- .ds-247420 .ds-file-check {
2027
- position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
2028
- width: 18px; height: 18px; padding: 0; z-index: 1;
2029
- display: inline-flex; align-items: center; justify-content: center;
2030
- border: var(--bw-hair) solid var(--rule); border-radius: 5px;
2031
- background: var(--bg); color: var(--accent-fg);
2032
- font-size: var(--fs-micro); line-height: 1; cursor: pointer;
2033
- opacity: 0; transition: opacity var(--dur-base) var(--ease), background var(--dur-snap) var(--ease);
2034
- }
2035
- .ds-247420 .ds-file-row:hover .ds-file-check,
2036
- .ds-247420 .ds-file-row:focus-within .ds-file-check,
2037
- .ds-247420 .ds-file-check.on { opacity: 1; }
2038
- /* Touch / coarse-pointer devices have no hover — keep checkboxes AND the
2039
- per-row action buttons (rename/delete/download) visible so the file manager
2040
- is fully reachable without a pointer (e.g. an iPad in landscape). */
2157
+ /* Touch / coarse-pointer devices have no hover — keep the per-row action
2158
+ buttons (rename/delete/download) visible so the file manager is fully
2159
+ reachable without a pointer (e.g. an iPad in landscape). */
2041
2160
  @media (hover: none), (pointer: coarse) {
2042
- .ds-247420 .ds-file-check { opacity: 1; }
2043
2161
  .ds-247420 .ds-file-actions { opacity: 1; }
2044
2162
  }
2045
- .ds-247420 .ds-file-check.on { background: var(--accent); border-color: var(--accent); }
2046
- .ds-247420 .ds-file-row.selected {
2047
- background: var(--accent-tint);
2048
- border-color: var(--accent);
2049
- }
2050
- .ds-247420 .ds-file-row.selected:hover { background: color-mix(in oklab, var(--accent) 22%, var(--bg)); }
2051
-
2052
- .ds-247420 .ds-bulk-bar {
2053
- display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
2054
- padding: 10px 14px; border-radius: var(--r-2);
2055
- background: var(--accent-tint);
2056
- border: var(--bw-hair) solid var(--accent);
2057
- position: sticky; top: var(--space-2); z-index: 2;
2058
- }
2059
- .ds-247420 .ds-bulk-count {
2060
- font-weight: 600; font-size: var(--fs-sm); margin-right: auto;
2061
- }
2062
2163
 
2063
2164
  /* Keyboard-shortcuts hint — compact two-column legend. */
2064
2165
  .ds-247420 .ds-shortcuts-hint {
@@ -2101,6 +2202,13 @@
2101
2202
  font-family: var(--ff-mono); font-size: var(--fs-xs);
2102
2203
  display: inline-flex; align-items: center; gap: 6px;
2103
2204
  }
2205
+ /* CSS-drawn half-disc mark on the compact theme toggle: keeps the control
2206
+ legible when its text label is hidden (icon-only rail strip). */
2207
+ .ds-247420 .ds-theme-disc {
2208
+ flex: 0 0 auto; width: 14px; height: 14px; border-radius: 50%;
2209
+ border: var(--bw-hair) solid var(--fg-3);
2210
+ background: linear-gradient(90deg, var(--fg-3) 0 50%, transparent 50% 100%);
2211
+ }
2104
2212
 
2105
2213
  /* ============================================================
2106
2214
  Chat kit polish — styles every class emitted by Chat /
@@ -2281,10 +2389,10 @@
2281
2389
  .ds-247420 .chat-bubble.chat-code .token.atrule,
2282
2390
  .ds-247420 .chat-bubble.chat-code .token.selector { color: var(--accent); }
2283
2391
  .ds-247420 .chat-bubble.chat-code .token.string,
2284
- .ds-247420 .chat-bubble.chat-code .token.attr-value { color: var(--mascot); }
2392
+ .ds-247420 .chat-bubble.chat-code .token.attr-value { color: var(--code-str-alt, var(--mascot)); }
2285
2393
  .ds-247420 .chat-bubble.chat-code .token.comment { color: var(--fg-3); font-style: italic; }
2286
2394
  .ds-247420 .chat-bubble.chat-code .token.number,
2287
- .ds-247420 .chat-bubble.chat-code .token.boolean { color: var(--sun); }
2395
+ .ds-247420 .chat-bubble.chat-code .token.boolean { color: var(--code-num, var(--sun)); }
2288
2396
  .ds-247420 .chat-bubble.chat-code .token.punctuation { color: var(--fg-2); }
2289
2397
  .ds-247420 .chat-bubble.chat-code .token.property,
2290
2398
  .ds-247420 .chat-bubble.chat-code .token.attr-name { color: var(--sky); }
@@ -2453,7 +2561,9 @@
2453
2561
  display: flex; align-items: flex-end; flex-wrap: wrap; gap: var(--space-2);
2454
2562
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
2455
2563
  background: var(--bg);
2456
- border: var(--bw-hair) solid var(--rule);
2564
+ /* The composer sits bg-on-bg: the 14% --rule hairline is ~1.3:1 on paper,
2565
+ leaving the primary input near-invisible at rest - use the strong rule. */
2566
+ border: var(--bw-hair) solid var(--rule-strong);
2457
2567
  border-radius: var(--r-2);
2458
2568
  flex-shrink: 0;
2459
2569
  transition: border-color var(--dur-snap) var(--ease), box-shadow var(--dur-snap) var(--ease);
@@ -2467,7 +2577,9 @@
2467
2577
  background: none; color: var(--fg);
2468
2578
  border: none; border-radius: 0;
2469
2579
  font-family: inherit; font-size: var(--fs-sm);
2470
- line-height: 1.45; resize: none;
2580
+ /* 1.5 is the value that actually renders (a later polish block used to
2581
+ re-declare it; the sizing block now states the truth). */
2582
+ line-height: 1.5; resize: none;
2471
2583
  min-height: 28px; max-height: 200px;
2472
2584
  box-sizing: border-box; overflow-y: auto;
2473
2585
  scrollbar-width: thin;
@@ -2534,13 +2646,19 @@
2534
2646
  /* ── select primitive ─────────────────────────────────────────────────── */
2535
2647
  .ds-247420 .ds-select {
2536
2648
  width: 100%;
2537
- padding: 10px 14px;
2649
+ min-width: 0;
2650
+ padding: 10px 30px 10px 14px; /* right gap clears the chevron */
2538
2651
  background: var(--bg-2);
2539
2652
  border: 0;
2540
2653
  border-radius: var(--r-2);
2541
2654
  font-family: inherit;
2542
2655
  font-size: var(--fs-sm);
2543
2656
  color: var(--fg);
2657
+ /* Clip long option text gracefully - a select that cuts 'Claude Sonnet
2658
+ (latest' mid-parenthesis reads as broken; ellipsis reads as truncated. */
2659
+ text-overflow: ellipsis;
2660
+ white-space: nowrap;
2661
+ overflow: hidden;
2544
2662
  appearance: none;
2545
2663
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-3) 50%),
2546
2664
  linear-gradient(135deg, var(--fg-3) 50%, transparent 50%);
@@ -2549,15 +2667,12 @@
2549
2667
  background-repeat: no-repeat;
2550
2668
  cursor: pointer;
2551
2669
  }
2552
- .ds-247420 .ds-select:focus { box-shadow: inset 0 0 0 2px var(--accent); }
2670
+ .ds-247420 .ds-select:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
2553
2671
  .ds-247420 .ds-select:hover { background-color: var(--bg-3); }
2554
2672
 
2555
- /* ── chat composer autogrow polish ────────────────────────────────────── */
2673
+ /* ── chat composer autogrow polish (sizing lives in the primary block) ── */
2556
2674
  .ds-247420 .chat-composer textarea {
2557
- resize: none;
2558
- overflow-y: auto;
2559
2675
  transition: height var(--dur-snap) var(--ease);
2560
- line-height: 1.5;
2561
2676
  }
2562
2677
  .ds-247420 .chat-composer textarea:disabled {
2563
2678
  opacity: 0.5;
@@ -3319,10 +3434,13 @@
3319
3434
  All sizing/colour from kit tokens; no hardcoded palette.
3320
3435
  ---------------------------------------------------------------------------- */
3321
3436
  .ds-247420 .ws-shell {
3322
- --ws-rail-w: 232px;
3437
+ /* Fluid chrome columns: shrink on small laptops, breathe on ultrawide, so the
3438
+ ~848px of fixed chrome no longer eats a constant slab. An inline --ws-*-w
3439
+ written by a resize drag overrides these (inline wins), pinning the width. */
3440
+ --ws-rail-w: clamp(200px, 16vw, 260px);
3323
3441
  --ws-rail-w-collapsed: 60px;
3324
- --ws-sessions-w: 296px;
3325
- --ws-pane-w: 320px;
3442
+ --ws-sessions-w: clamp(248px, 22vw, 360px);
3443
+ --ws-pane-w: clamp(288px, 24vw, 420px);
3326
3444
  display: grid;
3327
3445
  grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) 1fr var(--ws-pane-w);
3328
3446
  grid-template-areas: "rail sessions content pane";
@@ -3343,6 +3461,21 @@
3343
3461
  .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"; }
3344
3462
  .ds-247420 .ws-shell.ws-rail-collapsed { --ws-rail-w: var(--ws-rail-w-collapsed); }
3345
3463
  .ds-247420 .ws-shell.ws-pane-collapsed { --ws-pane-w: 0px; }
3464
+ /* Sessions column desktop collapse (parity with the pane collapse), reclaiming
3465
+ its width for a full-width thread/grid. */
3466
+ .ds-247420 .ws-shell.ws-sessions-collapsed { --ws-sessions-w: 0px; }
3467
+ .ds-247420 .ws-sessions-collapsed .ws-sessions { overflow: hidden; border-right: none; }
3468
+ .ds-247420 .ws-sessions-collapsed .ws-sessions > * { display: none; }
3469
+ /* Column resize handles: a thin keyboard-accessible separator pinned to the
3470
+ right edge of each chrome track; drag (or ArrowLeft/Right) writes a clamped
3471
+ inline --ws-*-w. */
3472
+ .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; }
3473
+ .ds-247420 .ws-resizer::after { content: ""; display: block; width: 2px; height: 100%; margin: 0 auto; background: transparent; transition: background var(--dur-snap) var(--ease); }
3474
+ .ds-247420 .ws-resizer:hover::after, .ds-247420 .ws-resizer:focus-visible::after { background: var(--accent); }
3475
+ .ds-247420 .ws-resizer:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
3476
+ .ds-247420 .ws-resizer.ws-resizer-rail { grid-column: 1; }
3477
+ .ds-247420 .ws-resizer.ws-resizer-sessions { grid-column: 2; }
3478
+ .ds-247420 .ws-resizer.ws-resizer-pane { grid-column: 3; justify-self: end; }
3346
3479
  /* Ease the rail/pane collapse. Track COUNT stays stable on collapse (only a
3347
3480
  width var flips), so grid-template-columns is animatable; reduced-motion
3348
3481
  drops it to an instant swap. */
@@ -3451,36 +3584,114 @@
3451
3584
  .ds-247420 .ws-pane-toggle:hover { background: var(--bg-3); color: var(--fg); }
3452
3585
  .ds-247420 .ws-pane-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3453
3586
 
3454
- /* Responsive: below 900px collapse to a single content column; rail+sessions+pane
3455
- become overlay drawers the host can toggle, or simply hide on mobile. We keep it
3456
- honest: stack rail (icon row) over content, hide sessions+pane unless toggled. */
3587
+ /* Drawer toggles and the scrim are hidden by default and revealed by the staged
3588
+ media blocks BELOW - these base rules must precede those blocks in source
3589
+ order: at equal specificity the later rule wins regardless of media, so a
3590
+ trailing display:none silently kills every drawer affordance (shipped bug:
3591
+ the mobile drawers were dead because these lines used to sit last). */
3592
+ .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); }
3593
+ /* Desktop-only chrome toggle (sessions collapse): inverse of the mobile drawer-toggle. */
3594
+ .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); }
3595
+ .ds-247420 .ws-desktop-toggle:hover { background: var(--bg-2); color: var(--fg); }
3596
+ .ds-247420 .ws-desktop-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3597
+ @media (max-width: 900px) { .ds-247420 .ws-desktop-toggle { display: none; } }
3598
+ .ds-247420 .ws-scrim { display: none; }
3599
+
3600
+ /* Responsive: the columns yield to the CONTENT in stages - the main column is
3601
+ the product, so the right pane gives way first, the sessions list second,
3602
+ and only below 900px does the rail itself drop to a fixed icon strip. Yielded
3603
+ columns stay reachable as overlay drawers (.ws-pane-open / .ws-sessions-open,
3604
+ toggled from the crumb bar) over a shared fade scrim. Before this staging the
3605
+ 4-track grid survived down to 901px and crushed the chat thread to ~245px
3606
+ while the 320px context pane kept its full width. */
3607
+
3608
+ /* Stage 1 (<=1480px): drop the pane TRACK; the context pane becomes a right
3609
+ overlay drawer. */
3610
+ @media (max-width: 1480px) {
3611
+ .ds-247420 .ws-shell,
3612
+ .ds-247420 .ws-shell.ws-no-pane,
3613
+ .ds-247420 .ws-shell.ws-pane-collapsed,
3614
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions) {
3615
+ grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) minmax(0, 1fr);
3616
+ grid-template-areas: "rail sessions content";
3617
+ }
3618
+ .ds-247420 .ws-shell.ws-no-sessions,
3619
+ .ds-247420 .ws-shell.ws-no-pane.ws-no-sessions,
3620
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions {
3621
+ grid-template-columns: var(--ws-rail-w) minmax(0, 1fr);
3622
+ grid-template-areas: "rail content";
3623
+ }
3624
+ /* Drawer width is a literal: --ws-pane-w is 0px while pane-collapsed, and a
3625
+ desktop-collapsed pane must still open as a full drawer. */
3626
+ .ds-247420 .ws-pane {
3627
+ position: fixed; inset: 0 0 0 auto;
3628
+ width: min(340px, 85vw);
3629
+ z-index: 42; transform: translateX(110%);
3630
+ transition: transform var(--dur-base) var(--ease);
3631
+ }
3632
+ .ds-247420 .ws-shell.ws-pane-open .ws-pane { transform: translateX(0); width: min(340px, 85vw); }
3633
+ .ds-247420 .ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane { border-left: var(--bw-hair) solid var(--bg-3); }
3634
+ .ds-247420 .ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane > :not(.ws-pane-toggle) { display: revert; }
3635
+ /* The desktop collapse chevron is meaningless in drawer mode. */
3636
+ .ds-247420 .ws-pane-toggle { display: none; }
3637
+ .ds-247420 .ws-pane-drawer-toggle { display: inline-flex; }
3638
+ /* Scrim is always present from this stage down so it FADES with the drawer
3639
+ instead of hard-appearing; pointer-events gate keeps it inert while closed. */
3640
+ .ds-247420 .ws-scrim { display: block; opacity: 0; pointer-events: none; position: fixed; inset: 0; z-index: 41; background: color-mix(in srgb, var(--fg) 38%, transparent); transition: opacity var(--dur-base) var(--ease); }
3641
+ .ds-247420 .ws-shell.ws-sessions-open .ws-scrim, .ds-247420 .ws-shell.ws-pane-open .ws-scrim { opacity: 1; pointer-events: auto; }
3642
+ }
3643
+
3644
+ /* Stage 2 (<=1100px): drop the sessions TRACK; the conversation list becomes a
3645
+ left overlay drawer. */
3646
+ @media (max-width: 1100px) {
3647
+ .ds-247420 .ws-shell,
3648
+ .ds-247420 .ws-shell.ws-no-pane,
3649
+ .ds-247420 .ws-shell.ws-pane-collapsed,
3650
+ .ds-247420 .ws-shell.ws-no-sessions,
3651
+ .ds-247420 .ws-shell.ws-no-pane.ws-no-sessions,
3652
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions),
3653
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions {
3654
+ grid-template-columns: var(--ws-rail-w) minmax(0, 1fr);
3655
+ grid-template-areas: "rail content";
3656
+ }
3657
+ .ds-247420 .ws-sessions {
3658
+ position: fixed; inset: 0 auto 0 0;
3659
+ width: min(var(--ws-sessions-w), 80vw);
3660
+ z-index: 42; transform: translateX(-110%);
3661
+ transition: transform var(--dur-base) var(--ease);
3662
+ border-right: var(--bw-hair) solid var(--bg-3);
3663
+ }
3664
+ .ds-247420 .ws-shell.ws-sessions-open .ws-sessions { transform: translateX(0); }
3665
+ .ds-247420 .ws-sessions-drawer-toggle { display: inline-flex; }
3666
+ }
3667
+
3668
+ /* Stage 3 (<=900px): single content column; the rail drops to a fixed icon-only
3669
+ strip. Labels hide UNCONDITIONALLY here - a 60px rail showing clipped label
3670
+ text ('age', 'Ne') is the worst of both worlds. */
3457
3671
  @media (max-width: 900px) {
3458
3672
  .ds-247420 .ws-shell,
3459
3673
  .ds-247420 .ws-shell.ws-no-sessions,
3460
3674
  .ds-247420 .ws-shell.ws-no-pane,
3461
- .ds-247420 .ws-shell.ws-no-pane.ws-no-sessions {
3462
- grid-template-columns: 1fr;
3675
+ .ds-247420 .ws-shell.ws-pane-collapsed,
3676
+ .ds-247420 .ws-shell.ws-no-pane.ws-no-sessions,
3677
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions),
3678
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions {
3679
+ grid-template-columns: minmax(0, 1fr);
3463
3680
  grid-template-areas: "content";
3464
3681
  }
3465
3682
  .ds-247420 .ws-rail { position: fixed; inset: 0 auto 0 0; width: var(--ws-rail-w-collapsed); z-index: 40; }
3466
- .ds-247420 .ws-sessions { position: fixed; inset: 0 auto 0 var(--ws-rail-w-collapsed); width: min(var(--ws-sessions-w), 80vw); z-index: 42; transform: translateX(-110%); transition: transform var(--dur-base) var(--ease); }
3467
- .ds-247420 .ws-shell.ws-sessions-open .ws-sessions { transform: translateX(0); }
3468
- /* On mobile the pane is a drawer driven by .ws-pane-open (an explicit open
3469
- intent), NOT by :not(.ws-pane-collapsed) - the desktop collapse default is
3470
- "open" which would otherwise pop the pane over the thread on every load. */
3471
- .ds-247420 .ws-pane { position: fixed; inset: 0 0 0 auto; width: min(var(--ws-pane-w), 85vw); z-index: 42; transform: translateX(110%); transition: transform var(--dur-base) var(--ease); }
3472
- .ds-247420 .ws-shell.ws-pane-open .ws-pane { transform: translateX(0); }
3683
+ .ds-247420 .ws-rail .ws-rail-brand,
3684
+ .ds-247420 .ws-rail .ws-rail-action-label,
3685
+ .ds-247420 .ws-rail .ws-rail-item-label,
3686
+ .ds-247420 .ws-rail .ws-rail-item-count,
3687
+ .ds-247420 .ws-rail .ds-theme-toggle-label { display: none; }
3688
+ .ds-247420 .ws-rail .ws-rail-item, .ds-247420 .ws-rail .ws-rail-action { justify-content: center; gap: 0; }
3689
+ .ds-247420 .ws-rail .ws-rail-head { justify-content: center; }
3690
+ /* Expand/collapse is meaningless on the icon strip. */
3691
+ .ds-247420 .ws-rail-toggle { display: none; }
3692
+ .ds-247420 .ws-rail-foot { display: flex; justify-content: center; }
3693
+ .ds-247420 .ws-sessions { inset: 0 auto 0 var(--ws-rail-w-collapsed); }
3473
3694
  .ds-247420 .ws-content { grid-area: content; padding-left: var(--ws-rail-w-collapsed); }
3474
- .ds-247420 .ws-rail-collapsed .ws-rail-item-label, .ds-247420 .ws-rail-collapsed .ws-rail-brand { display: none; }
3475
- /* Tap-scrim behind an open drawer; dismiss on click. Hidden unless a drawer
3476
- is open so it never blocks the content area on desktop. */
3477
- /* Scrim is always present on mobile so it can FADE with the drawer instead of
3478
- hard-appearing via a display toggle; pointer-events gate keeps it inert
3479
- while closed. Reduced-motion users get the global transition kill -> instant. */
3480
- .ds-247420 .ws-scrim { display: block; opacity: 0; pointer-events: none; position: fixed; inset: 0; z-index: 41; background: color-mix(in srgb, var(--fg) 38%, transparent); transition: opacity var(--dur-base) var(--ease); }
3481
- .ds-247420 .ws-shell.ws-sessions-open .ws-scrim, .ds-247420 .ws-shell.ws-pane-open .ws-scrim { opacity: 1; pointer-events: auto; }
3482
- /* The mobile drawer-toggle affordances live in the crumb bar. */
3483
- .ds-247420 .ws-drawer-toggle { display: inline-flex; }
3484
3695
  /* The Crumb's narrow collapse elsewhere keys on the .app @container, which
3485
3696
  does not exist inside WorkspaceShell - mirror it here so the crumb bar
3486
3697
  cannot overflow a narrow viewport (trail hides, leaf ellipsizes, the
@@ -3491,11 +3702,8 @@
3491
3702
  .ds-247420 .ws-crumb .app-crumb .leaf { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
3492
3703
  .ds-247420 .ws-crumb .app-crumb .crumb-right { margin-left: 0; flex-wrap: wrap; min-width: 0; display: inline-flex; }
3493
3704
  }
3494
- /* Drawer toggles are mobile-only chrome; hidden on the desktop grid. */
3495
- .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); }
3496
3705
  .ds-247420 .ws-drawer-toggle:hover { background: var(--bg-2); color: var(--fg); }
3497
3706
  .ds-247420 .ws-drawer-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3498
- .ds-247420 .ws-scrim { display: none; }
3499
3707
 
3500
3708
  /* ============================================================
3501
3709
  Row title highlight, expanded-row actions, filter pills.
@@ -5090,6 +5298,13 @@
5090
5298
  .ds-247420 .agentchat-controls .select,
5091
5299
  .ds-247420 .agentchat-controls [role="combobox"] { min-width: 130px; max-width: 240px; }
5092
5300
  .ds-247420 .agentchat-controls .ds-select { min-width: 130px; max-width: 240px; }
5301
+ /* One shared control metric for the most-seen chrome row (mirrors the
5302
+ .ds-dash-toolbar precedent): selects, buttons, export acts all 32px / r-1. */
5303
+ .ds-247420 .agentchat-controls .ds-select { min-height: 32px; padding: 4px 28px 4px 10px; font-size: var(--fs-sm); border-radius: var(--r-1); }
5304
+ .ds-247420 .agentchat-controls .btn, .ds-247420 .agentchat-controls .btn-primary { padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500; }
5305
+ @media (pointer: coarse) {
5306
+ .ds-247420 .agentchat-controls .ds-select, .ds-247420 .agentchat-controls .btn, .ds-247420 .agentchat-controls .btn-primary { min-height: 44px; }
5307
+ }
5093
5308
 
5094
5309
  /* Narrow viewports: let the agent/model selects share the row two-up, then
5095
5310
  stack full-width on the smallest screens, and drop the status to its own
@@ -5112,7 +5327,7 @@
5112
5327
  gap: .4em;
5113
5328
  white-space: nowrap;
5114
5329
  margin-left: auto;
5115
- font-size: .85em;
5330
+ font-size: var(--fs-tiny);
5116
5331
  color: var(--fg-3);
5117
5332
  }
5118
5333
  /* status disc — a CSS-drawn dot, not a glyph; pulses while streaming */
@@ -5138,7 +5353,7 @@
5138
5353
  display: flex;
5139
5354
  align-items: center;
5140
5355
  gap: var(--space-2, 8px);
5141
- font-size: .85em;
5356
+ font-size: var(--fs-tiny);
5142
5357
  color: var(--fg-3);
5143
5358
  flex-wrap: wrap;
5144
5359
  }
@@ -5179,7 +5394,7 @@
5179
5394
  gap: .5em;
5180
5395
  }
5181
5396
  .ds-247420 .agentchat-title { font-size: 1em; margin: 0; }
5182
- .ds-247420 .agentchat-sub { font-size: .85em; color: var(--fg-3); }
5397
+ .ds-247420 .agentchat-sub { font-size: var(--fs-tiny); color: var(--fg-3); }
5183
5398
  /* Thread wrapper hosts the absolutely-positioned jump-to-latest button. */
5184
5399
  .ds-247420 .agentchat-thread-wrap { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
5185
5400
  .ds-247420 .agentchat-thread {
@@ -5188,14 +5403,14 @@
5188
5403
  overflow-y: auto;
5189
5404
  display: flex;
5190
5405
  flex-direction: column;
5191
- gap: var(--space-2, 8px);
5406
+ gap: calc(var(--space-2, 8px) * var(--density, 1));
5192
5407
  }
5193
5408
 
5194
5409
  /* Jump-to-latest: hidden until the thread scroll listener adds .show. */
5195
5410
  .ds-247420 .agentchat-jump {
5196
5411
  position: absolute; right: 16px; bottom: 12px; z-index: 3;
5197
5412
  display: none; align-items: center; gap: .35em;
5198
- padding: .4em .8em; font: inherit; font-size: .8em; cursor: pointer;
5413
+ padding: .4em .8em; font: inherit; font-size: var(--fs-tiny); cursor: pointer;
5199
5414
  border-radius: 999px; border: var(--bw-hair) solid var(--rule);
5200
5415
  background: var(--bg-2); color: var(--fg-2, var(--fg));
5201
5416
  box-shadow: 0 2px 8px color-mix(in srgb, var(--fg) 14%, transparent);
@@ -5239,7 +5454,7 @@
5239
5454
  max-width: 46ch;
5240
5455
  }
5241
5456
  .ds-247420 .agentchat-empty-title { margin: 0; font-size: 1.05em; color: var(--fg-2, var(--fg)); }
5242
- .ds-247420 .agentchat-empty-sub { margin: 0; font-size: .9em; }
5457
+ .ds-247420 .agentchat-empty-sub { margin: 0; font-size: var(--fs-sm); }
5243
5458
  .ds-247420 .agentchat-empty-suggestions {
5244
5459
  display: flex;
5245
5460
  flex-wrap: wrap;
@@ -5250,7 +5465,7 @@
5250
5465
  .ds-247420 .agentchat-empty-suggestion {
5251
5466
  cursor: pointer;
5252
5467
  font: inherit;
5253
- font-size: .85em;
5468
+ font-size: var(--fs-tiny);
5254
5469
  padding: .4em .8em;
5255
5470
  border-radius: 999px;
5256
5471
  border: 1px solid color-mix(in srgb, var(--fg) 16%, transparent);
@@ -5270,7 +5485,7 @@
5270
5485
  text-align: left;
5271
5486
  width: 100%;
5272
5487
  }
5273
- .ds-247420 .agentchat-install-text { margin: 0; font-size: .9em; color: var(--fg-3); }
5488
+ .ds-247420 .agentchat-install-text { margin: 0; font-size: var(--fs-sm); color: var(--fg-3); }
5274
5489
  .ds-247420 .agentchat-install-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--space-1, 4px); }
5275
5490
  .ds-247420 .agentchat-install-row {
5276
5491
  display: flex; align-items: center; gap: var(--space-2, 8px);
@@ -5311,7 +5526,7 @@
5311
5526
  gap: .5em;
5312
5527
  padding: .3em .2em;
5313
5528
  color: var(--fg-3);
5314
- font-size: .85em;
5529
+ font-size: var(--fs-tiny);
5315
5530
  }
5316
5531
  .ds-247420 .agentchat-working-text { color: var(--fg-3); }
5317
5532
  /* Self-contained dots (chat-thinking-dots lives in a kit sheet not bundled
@@ -5374,28 +5589,40 @@
5374
5589
  ConversationList — left-rail "Chats" column.
5375
5590
  ---------------------------------------------------------------------------- */
5376
5591
  .ds-247420 .ds-sessions { display: flex; flex-direction: column; min-height: 0; height: 100%; }
5377
- .ds-247420 .ds-session-head { flex: 0 0 auto; display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); border-bottom: var(--bw-hair) solid var(--bg-3); }
5592
+ /* One row: quiet icon new-chat beside the search. The list's new-chat must not
5593
+ repeat the rail's primary CTA - two identical green buttons on screen at
5594
+ once read as a layout mistake, and the rail action already owns 'new'. */
5595
+ .ds-247420 .ds-session-head { flex: 0 0 auto; display: flex; flex-direction: row; align-items: center; gap: var(--space-2); padding: var(--space-3); border-bottom: var(--bw-hair) solid var(--bg-3); }
5378
5596
  .ds-247420 .ds-session-new {
5379
- display: flex; align-items: center; gap: var(--space-2); justify-content: center;
5380
- padding: var(--space-2) var(--space-3); min-height: 44px;
5381
- background: var(--accent); color: var(--accent-fg, var(--bg)); border: none;
5597
+ display: inline-flex; align-items: center; justify-content: center; gap: 0;
5598
+ flex: 0 0 auto; order: 2;
5599
+ width: 36px; min-height: 36px; padding: 0;
5600
+ background: transparent; color: var(--fg-2);
5601
+ border: var(--bw-hair) solid var(--rule);
5382
5602
  border-radius: var(--r-1); cursor: pointer; font-family: var(--ff-body);
5383
- font-size: var(--fs-sm); font-weight: 600;
5603
+ font-size: var(--fs-sm); font-weight: 500;
5384
5604
  }
5385
- .ds-247420 .ds-session-new:hover { filter: brightness(1.08); }
5605
+ .ds-247420 .ds-session-new > span { display: none; }
5606
+ .ds-247420 .ds-session-new:hover { background: var(--bg-2); color: var(--fg); }
5607
+ .ds-247420 .ds-session-search { order: 1; flex: 1 1 auto; min-width: 0; }
5386
5608
  .ds-247420 .ds-session-new:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
5387
5609
  .ds-247420 .ds-session-search {
5388
- width: 100%; padding: var(--space-2) var(--space-3); min-height: 44px;
5610
+ width: 100%; padding: var(--space-1) var(--space-3); min-height: 36px;
5389
5611
  background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); color: var(--fg);
5390
5612
  border-radius: var(--r-1); font-family: var(--ff-body); font-size: var(--fs-sm);
5391
5613
  }
5392
- .ds-247420 .ds-session-search:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
5614
+ .ds-247420 .ds-session-search:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
5615
+ /* Touch floor (must FOLLOW the base rules - same specificity, order decides). */
5616
+ @media (pointer: coarse) {
5617
+ .ds-247420 .ds-session-new { width: 44px; min-height: 44px; }
5618
+ .ds-247420 .ds-session-search { min-height: 44px; }
5619
+ }
5393
5620
  .ds-247420 .ds-session-list, .ds-247420 .ds-session-groups { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-2); }
5394
5621
  /* Grouped rows (Today/Yesterday/...) lay out like the flat list; the section
5395
5622
  label sticks to the top of the scroll area for Claude-Desktop-style headers. */
5396
5623
  .ds-247420 .ds-session-group { display: flex; flex-direction: column; }
5397
5624
  .ds-247420 .ds-session-group-rows { display: flex; flex-direction: column; gap: 2px; }
5398
- .ds-247420 .ds-session-group-label { position: sticky; top: 0; z-index: 1; background: var(--bg-1, var(--bg)); font-size: var(--fs-tiny); color: var(--fg-3); text-transform: uppercase; letter-spacing: .04em; padding: var(--space-2) var(--space-2) var(--space-1); }
5625
+ .ds-247420 .ds-session-group-label { position: sticky; top: 0; z-index: 1; background: var(--bg-1, var(--bg)); font-size: var(--fs-tiny); font-weight: 600; color: var(--fg-3); text-transform: uppercase; letter-spacing: var(--tr-caps); padding: var(--space-2) var(--space-2) var(--space-1); }
5399
5626
  .ds-247420 .ds-session-row {
5400
5627
  position: relative; display: flex; align-items: center; gap: var(--space-2);
5401
5628
  width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: 2px;
@@ -5426,10 +5653,24 @@
5426
5653
  SessionDashboard — grid of live-session cards.
5427
5654
  ---------------------------------------------------------------------------- */
5428
5655
  .ds-247420 .ds-dash { display: flex; flex-direction: column; min-height: 0; }
5429
- .ds-247420 .ds-dash-header { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4) 0; }
5656
+ .ds-247420 .ds-dash-header { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-3); row-gap: var(--space-2); flex-wrap: wrap; padding: var(--space-3) var(--space-4) 0; }
5430
5657
  .ds-247420 .ds-dash-count { font-size: var(--fs-sm); color: var(--fg-2); font-weight: 600; }
5431
- .ds-247420 .ds-dash-header .btn, .ds-247420 .ds-dash-header .btn-primary { margin-left: auto; }
5432
- .ds-247420 .ds-dash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-3); padding: var(--space-4); }
5658
+ /* Stop is a quiet destructive control in chrome, not a page-level red CTA;
5659
+ it only goes loud while ARMED (the one-shot press-again confirm). */
5660
+ .ds-247420 .ds-dash-header .btn, .ds-247420 .ds-dash-header .btn-primary {
5661
+ margin-left: 0;
5662
+ padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
5663
+ }
5664
+ .ds-247420 .ds-dash-header .btn-primary.danger {
5665
+ background: transparent; color: var(--warn);
5666
+ border: var(--bw-hair) solid var(--warn);
5667
+ }
5668
+ .ds-247420 .ds-dash-header .btn-primary.danger:hover {
5669
+ background: color-mix(in oklab, var(--warn) 12%, transparent); color: var(--warn);
5670
+ }
5671
+ .ds-247420 .ds-dash-header .btn-primary.danger.is-armed { background: var(--warn); color: var(--paper); border-color: var(--warn); }
5672
+ .ds-247420 .ds-dash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-2); padding: var(--space-3); }
5673
+ @media (min-width: 1500px) { .ds-247420 .ds-dash-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); } }
5433
5674
  .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); }
5434
5675
  .ds-247420 .ds-dash-card.is-error { border-color: var(--flame); }
5435
5676
  .ds-247420 .ds-dash-card-head { display: flex; align-items: center; gap: var(--space-2); }
@@ -5455,7 +5696,6 @@
5455
5696
  ---------------------------------------------------------------------------- */
5456
5697
  .ds-247420 .ds-context { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3); }
5457
5698
  .ds-247420 .ds-context .panel { background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-2); }
5458
- .ds-247420 .ds-context .row { font-size: var(--fs-sm); }
5459
5699
  .ds-247420 .ds-context .row .meta { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-2); }
5460
5700
  .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; }
5461
5701
  .ds-247420 .ds-context-actions { display: flex; gap: var(--space-2); }
@@ -5508,7 +5748,18 @@
5508
5748
  .ds-247420 .ds-dash-status.is-running { color: var(--accent); }
5509
5749
 
5510
5750
  /* --- C2: dashboard sort/filter toolbar + stream-state line. --- */
5751
+ /* The toolbar is part of the ONE header row (count | heartbeat ... filter,
5752
+ sort, errors-only, stop): compact controls that align on a shared 32px
5753
+ height, never a stacked full-width form column. */
5511
5754
  .ds-247420 .ds-dash-toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
5755
+ .ds-247420 .ds-dash-toolbar .ds-search-input {
5756
+ width: 200px; min-height: 32px; padding: 5px 10px;
5757
+ font-size: var(--fs-sm); border-radius: var(--r-1);
5758
+ }
5759
+ .ds-247420 .ds-dash-toolbar .ds-select, .ds-247420 .ds-dash-toolbar select {
5760
+ min-height: 32px; padding: 4px 10px; font-size: var(--fs-sm);
5761
+ width: auto; border-radius: var(--r-1);
5762
+ }
5512
5763
  .ds-247420 .ds-dash-stream { font-size: var(--fs-tiny); color: var(--fg-3); }
5513
5764
  .ds-247420 .ds-dash-stream.is-lost { color: var(--flame); }
5514
5765
  .ds-247420 .ds-dash-stream.is-connecting { color: var(--amber, #d9a93a); }
@@ -5714,12 +5965,15 @@
5714
5965
  avatar-disc + colored-bubble layout. AgentChat passes flat:true; the demo
5715
5966
  Chat keeps the bubble layout. Turns are full-width to --measure; the user vs
5716
5967
  assistant distinction is a role label + a faint assistant background. */
5717
- .ds-247420 .chat-msg-flat { display: block; padding: var(--space-3) var(--space-4); margin: 0; background: none; border-radius: var(--r-2); }
5968
+ /* Center the flat turn at the reading measure so a wide content column does not
5969
+ dump a one-sided dead gutter (claude.ai/code centers the thread). Padding
5970
+ scales through --density so data-density=compact tightens the thread. */
5971
+ .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); }
5718
5972
  .ds-247420 .chat-msg-flat.them { background: color-mix(in oklab, var(--fg) 3%, transparent); }
5719
5973
  .ds-247420 .chat-msg-flat.you { background: none; }
5720
5974
  .ds-247420 .chat-msg-flat .chat-stack { max-width: var(--measure); width: 100%; margin: 0; align-items: stretch; }
5721
5975
  .ds-247420 .chat-msg-flat.you .chat-stack { align-items: stretch; }
5722
- .ds-247420 .chat-role { font-size: var(--fs-tiny); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--fg-3); margin-bottom: var(--space-1); }
5976
+ .ds-247420 .chat-role { font-size: var(--fs-tiny); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tr-caps); color: var(--fg-3); margin-bottom: var(--space-1); }
5723
5977
  .ds-247420 .chat-msg-flat.you .chat-role { color: var(--accent); }
5724
5978
  .ds-247420 .chat-msg-flat .chat-bubble { background: none; border: none; border-radius: 0; padding: 0; max-width: 100%; box-shadow: none; transform: none; }
5725
5979
  .ds-247420 .chat-msg-flat.you .chat-bubble { background: none; color: inherit; }
@@ -5760,7 +6014,7 @@
5760
6014
  .ds-247420 .chat-msg .chat-tool.tool-error .chat-tool-status { color: var(--flame); background: color-mix(in oklab, var(--flame) 12%, transparent); }
5761
6015
  .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); }
5762
6016
  .ds-247420 .chat-tool-section { display: flex; flex-direction: column; gap: var(--space-1); }
5763
- .ds-247420 .chat-tool-section-label { font-size: var(--fs-micro); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--fg-3); }
6017
+ .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); }
5764
6018
  .ds-247420 .chat-tool-pre { margin: 0; padding: var(--space-2); background: var(--bg-2); border-radius: var(--r-1); font-family: var(--ff-mono); font-size: var(--fs-tiny); line-height: 1.45; overflow-x: auto; max-height: 320px; overflow-y: auto; }
5765
6019
  .ds-247420 .chat-tool-pre.is-error { color: var(--flame); }
5766
6020
  .ds-247420 .chat-tool-pre.chat-tool-empty { color: var(--fg-3); }
@@ -5799,7 +6053,7 @@
5799
6053
 
5800
6054
  /* Live command-center: status-bucket groups + header breakdown + heartbeat. */
5801
6055
  .ds-247420 .ds-dash-group { display: flex; flex-direction: column; gap: var(--space-2); }
5802
- .ds-247420 .ds-dash-group-label { font-size: var(--fs-micro); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--fg-3); padding: 0 var(--space-1); }
6056
+ .ds-247420 .ds-dash-group-label { font-size: var(--fs-tiny); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tr-caps); color: var(--fg-3); padding: 0 var(--space-1); }
5803
6057
  .ds-247420 .ds-dash-breakdown { display: flex; align-items: center; gap: var(--space-1); font-size: var(--fs-sm); color: var(--fg-2); }
5804
6058
  .ds-247420 .ds-dash-breakdown .seg.is-running { color: var(--green); font-weight: 600; }
5805
6059
  .ds-247420 .ds-dash-breakdown .seg.is-error { color: var(--flame); font-weight: 600; }
@@ -5825,9 +6079,9 @@
5825
6079
  .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); }
5826
6080
  .ds-247420 .ds-preview-code .token.punctuation { color: var(--fg-2); }
5827
6081
  .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); }
5828
- .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(--green-2, #3A9A34); }
5829
- .ds-247420 .ds-preview-code .token.atrule, .ds-247420 .ds-preview-code .token.attr-value, .ds-247420 .ds-preview-code .token.keyword { color: var(--sky, #3A6EFF); }
5830
- .ds-247420 .ds-preview-code .token.function, .ds-247420 .ds-preview-code .token.class-name { color: var(--flame); }
6082
+ .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)); }
6083
+ .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)); }
6084
+ .ds-247420 .ds-preview-code .token.function, .ds-247420 .ds-preview-code .token.class-name { color: var(--code-fn, var(--flame)); }
5831
6085
  .ds-247420 .ds-preview-code.has-gutter { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0 var(--space-2); }
5832
6086
  .ds-247420 .ds-preview-code.has-gutter code { display: block; min-width: 0; overflow-x: auto; }
5833
6087
  .ds-247420 .ds-preview-gutter { user-select: none; text-align: right; padding: 0 var(--space-2) 0 0; color: var(--fg-3); border-right: var(--bw-hair) solid var(--rule); font-family: var(--ff-mono); white-space: pre; line-height: inherit; }
@@ -5840,6 +6094,41 @@
5840
6094
  }
5841
6095
  .ds-247420 .ds-preview-media.is-actual { max-width: none; max-height: none; }
5842
6096
 
6097
+ /* ----------------------------------------------------------------------------
6098
+ Compact-button tiers — ONE spec for the small quiet rect buttons that eight
6099
+ surfaces used to clone with drifting metrics/tones. chat.css loads after
6100
+ app-shell.css in the bundle, so these same-specificity rules win by order.
6101
+ Tier A (toolbar-grade, 32px) matches .ds-file-toolbar .btn, the reference;
6102
+ tier B (inline-row-grade, 24px) for actions inside dense row strips.
6103
+ Hover/focus/active-state rules on the originals still apply.
6104
+ ---------------------------------------------------------------------------- */
6105
+ .ds-247420 .row-act, .ds-247420 .ds-dash-errors-toggle, .ds-247420 .agentchat-export-act, .ds-247420 .ds-file-more-btn {
6106
+ min-height: 32px; padding: 5px 12px; border-radius: var(--r-1);
6107
+ font-family: var(--ff-body); font-size: var(--fs-tiny); font-weight: 500;
6108
+ background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
6109
+ cursor: pointer;
6110
+ }
6111
+ .ds-247420 .row-act:hover, .ds-247420 .ds-dash-errors-toggle:hover, .ds-247420 .agentchat-export-act:hover, .ds-247420 .ds-file-more-btn:hover {
6112
+ background: var(--bg-2); color: var(--fg);
6113
+ }
6114
+ .ds-247420 .agentchat-install-copy, .ds-247420 .ds-upload-act, .ds-247420 .ds-session-meta-copy {
6115
+ min-height: 24px; padding: 2px 8px; border-radius: var(--r-1);
6116
+ font-family: var(--ff-body); font-size: var(--fs-tiny);
6117
+ background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-3);
6118
+ cursor: pointer;
6119
+ }
6120
+ .ds-247420 .agentchat-install-copy:hover, .ds-247420 .ds-upload-act:hover, .ds-247420 .ds-session-meta-copy:hover {
6121
+ background: var(--bg-2); color: var(--fg);
6122
+ }
6123
+ @media (pointer: coarse) {
6124
+ .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; }
6125
+ }
6126
+
6127
+ /* 11th run: ultrawide widens the reading measure where there is room. */
6128
+ @media (min-width: 1600px) {
6129
+ .ds-247420 .agentchat-thread { --measure: 84ch; }
6130
+ }
6131
+
5843
6132
  /* editor-primitives.css */
5844
6133
  /* editor-primitives.css — chrome for in-engine editors, inspectors, IDEs,
5845
6134
  debug HUDs. All rules under .ds-247420 scope (build prefixes). Tokens