anentrypoint-design 0.0.207 → 0.0.209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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
 
@@ -787,13 +820,21 @@
787
820
  width: 100%;
788
821
  min-height: var(--app-status-h);
789
822
  padding: 10px var(--pad-x);
790
- font-family: var(--ff-mono); font-size: var(--fs-xs);
823
+ /* Status chrome is prose, not code - mono is reserved for code/paths. */
824
+ font-family: var(--ff-body); font-size: var(--fs-xs);
791
825
  color: var(--fg-3);
792
826
  border-top: 1px solid var(--rule);
793
827
  }
794
- .ds-247420 .app-status .item { color: inherit; }
828
+ .ds-247420 .app-status .item { color: inherit; white-space: nowrap; }
795
829
  .ds-247420 .app-status .item:first-of-type { color: var(--accent); }
796
830
  .ds-247420 .app-status .spread { flex: 1; }
831
+ /* The status bar NEVER wraps: at narrow widths the trailing items (hints,
832
+ agent target) drop in priority order instead of breaking mid-word onto a
833
+ second line. */
834
+ .ds-247420 .app-status { flex-wrap: nowrap; overflow: hidden; }
835
+ @media (max-width: 1100px) {
836
+ .ds-247420 .app-status .item:last-of-type:not(:only-of-type) { display: none; }
837
+ }
797
838
 
798
839
  /* ============================================================
799
840
  Primitives
@@ -840,7 +881,8 @@
840
881
  .ds-247420 .ds-icon-btn-ghost:hover { background: var(--bg-2); }
841
882
  .ds-247420 .ds-icon-btn-primary { background: var(--accent); color: var(--accent-fg); }
842
883
  .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); }
884
+ /* warn = destructive ACTION tone; flame stays exclusively error STATUS. */
885
+ .ds-247420 .ds-icon-btn-danger { background: var(--warn); color: var(--paper); }
844
886
  .ds-247420 .ds-icon-btn-danger:hover { filter: brightness(1.1); }
845
887
  .ds-247420 .ds-icon-btn:active { transform: translateY(1px); }
846
888
  .ds-247420 .ds-icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@@ -904,21 +946,25 @@
904
946
  ============================================================ */
905
947
  .ds-247420 .panel {
906
948
  background: var(--panel-1, var(--bg-2));
907
- border-radius: var(--r-3);
949
+ border: var(--bw-hair) solid var(--rule);
950
+ border-radius: var(--r-2);
908
951
  margin: 0 0 var(--space-5);
909
952
  padding: var(--space-3);
910
- box-shadow: var(--panel-shadow);
911
953
  position: relative;
912
954
  }
913
955
  .ds-247420 .panel.panel-inline { background: var(--bg-2); padding: var(--space-3) var(--space-3); }
914
956
  .ds-247420 .panel.panel-wide { background: transparent; }
915
957
  .ds-247420 .panel-head {
916
958
  display: flex; align-items: baseline; justify-content: space-between;
917
- padding: var(--space-4) var(--space-5) var(--space-3);
959
+ /* Shares the .panel-body 16px side padding so the caps label and the body
960
+ rows sit on ONE left axis (the old 24/32 padding was authored for the
961
+ pre-padding .panel-wide era and indented the label 16px past its content). */
962
+ padding: var(--space-2) var(--space-3);
918
963
  font-size: var(--fs-xs); font-weight: 600;
919
964
  color: var(--fg-3);
920
965
  letter-spacing: var(--tr-caps); text-transform: uppercase;
921
966
  }
967
+ .ds-247420 .panel.panel-wide .panel-head { padding-left: 0; padding-right: 0; }
922
968
  .ds-247420 .panel-head > :last-child {
923
969
  font-weight: 500; color: var(--fg-3);
924
970
  font-family: var(--ff-mono); letter-spacing: 0;
@@ -986,6 +1032,12 @@
986
1032
  .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
1033
  .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
1034
  .ds-247420 .row .title .sub { font-family: var(--ff-body); font-weight: 400; font-size: var(--fs-sm); color: var(--fg-3); }
1035
+ /* App typescale: list rows are quiet working chrome (the 18px/600 default is a
1036
+ marketing-surface voice). One size for ALL app list rows - matches
1037
+ .ds-file-row/.ds-session-title at fs-sm/500; values mirror the kit's own
1038
+ mobile block below. Marketing pages without data-typescale keep the default. */
1039
+ .ds-247420[data-typescale="app"] .row { padding: 12px 16px; }
1040
+ .ds-247420[data-typescale="app"] .row .title { font-size: var(--fs-sm); font-weight: 500; }
989
1041
  .ds-247420 .row .sub { font-family: var(--ff-body); font-weight: 400; font-size: var(--fs-sm); color: var(--fg-3); }
990
1042
  .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
1043
  /* WorksList meta pairs a label with a disclosure chevron, inline-aligned. */
@@ -1296,10 +1348,10 @@
1296
1348
  gap: 3px;
1297
1349
  }
1298
1350
  .ds-247420 .ds-file-row {
1299
- grid-template-columns: 22px minmax(0, 1fr) auto;
1300
- gap: 10px; padding: 10px 12px;
1351
+ gap: 8px; padding: 10px 12px;
1301
1352
  font-size: var(--fs-xs);
1302
1353
  }
1354
+ .ds-247420 .ds-file-open { gap: 10px; }
1303
1355
  /* On mobile, fold meta under the title and keep actions inline. */
1304
1356
  .ds-247420 .ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
1305
1357
  .ds-247420 .ds-file-row .ds-file-actions { opacity: 1; }
@@ -1307,6 +1359,7 @@
1307
1359
  reachable by touch (cohesion sweep). */
1308
1360
  .ds-247420 .ds-file-act, .ds-247420 .ds-file-sort-btn, .ds-247420 .ds-crumb-seg { min-height: 44px; }
1309
1361
  .ds-247420 .ds-file-filter-input { min-height: 44px; }
1362
+ .ds-247420 .ds-file-check, .ds-247420 .ds-file-selectall, .ds-247420 .ds-density-btn { min-height: 44px; min-width: 44px; }
1310
1363
 
1311
1364
  /* Chat */
1312
1365
  .ds-247420 .chat-stack { max-width: 100%; min-width: 0; }
@@ -1430,8 +1483,8 @@
1430
1483
  padding: 12px 18px; font-size: var(--fs-sm);
1431
1484
  }
1432
1485
 
1433
- /* Panel */
1434
- .ds-247420 .panel-head { padding: var(--space-4) var(--space-4); }
1486
+ /* Panel - keep the head on the body's left axis at laptop widths too. */
1487
+ .ds-247420 .panel-head { padding: var(--space-2) var(--space-3); }
1435
1488
  .ds-247420 .panel-body { padding: var(--space-2) var(--space-3); }
1436
1489
 
1437
1490
  /* Hero — fluid base font-size; only width unconstrained on tablet. */
@@ -1503,13 +1556,15 @@
1503
1556
 
1504
1557
  /* Listing wrapper holds the optional filter + sort header above the grid. */
1505
1558
  .ds-247420 .ds-file-listing { display: flex; flex-direction: column; gap: var(--space-2); min-height: 0; }
1506
- .ds-247420 .ds-file-filter { padding: 0 0 var(--space-1); }
1559
+ /* The quick filter is a compact control, not a full-width form row - a giant
1560
+ input above the grid reads as a search page and costs fold height. */
1561
+ .ds-247420 .ds-file-filter { padding: 0 0 var(--space-1); display: flex; justify-content: flex-end; }
1507
1562
  .ds-247420 .ds-file-filter-input {
1508
- width: 100%; padding: 8px 12px; font-size: var(--fs-sm);
1563
+ width: min(280px, 100%); padding: 6px 12px; font-size: var(--fs-sm);
1509
1564
  background: var(--bg); color: var(--fg);
1510
- border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
1565
+ border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
1511
1566
  }
1512
- .ds-247420 .ds-file-filter-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
1567
+ .ds-247420 .ds-file-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
1513
1568
  .ds-247420 .ds-file-sort { display: flex; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); }
1514
1569
  .ds-247420 .ds-file-sort-btn {
1515
1570
  font-size: var(--fs-tiny); font-family: var(--ff-mono); color: var(--fg-3);
@@ -1521,6 +1576,16 @@
1521
1576
 
1522
1577
  /* Skeleton shimmer rows shown while a directory loads. */
1523
1578
  .ds-247420 .ds-file-row-skeleton { cursor: default; pointer-events: none; }
1579
+ /* In-place refresh: dim the populated grid instead of swapping it for shimmer
1580
+ rows (the rows stay; the round-trip reads as a settle, not a reload). */
1581
+ .ds-247420 .ds-file-grid.is-refreshing { opacity: .6; }
1582
+ @media (prefers-reduced-motion: no-preference) {
1583
+ .ds-247420 .ds-file-grid { transition: opacity .15s var(--ease); }
1584
+ }
1585
+ /* EventList loading skeleton (shares the .ds-skel shimmer base above). */
1586
+ .ds-247420 .ds-event-row-skeleton { display: flex; align-items: center; gap: var(--space-3); padding: 12px 16px; pointer-events: none; }
1587
+ .ds-247420 .ds-skel-rank { height: 12px; width: 2.5ch; }
1588
+ .ds-247420 .ds-event-state { padding: var(--space-2) 16px; }
1524
1589
  .ds-247420 .ds-skel { display: inline-block; border-radius: var(--r-1); background: var(--bg-2); position: relative; overflow: hidden; }
1525
1590
  .ds-247420 .ds-skel::after {
1526
1591
  content: ''; position: absolute; inset: 0;
@@ -1533,10 +1598,13 @@
1533
1598
  @keyframes ds-skel-shimmer { 100% { transform: translateX(100%); } }
1534
1599
  @media (prefers-reduced-motion: reduce) { .ds-247420 .ds-skel::after { animation: none; } }
1535
1600
 
1536
- /* File row — linear layout (icon · title · meta · actions) */
1601
+ /* File row — linear layout (checkbox? · open-button[code · icon · title · meta] · actions).
1602
+ The row is a flex strip; the open <button> is the stretching member and lays
1603
+ out the entry's own columns. It needs a full reset (UA button chrome off)
1604
+ because FileRow wraps the row content in a real button for native keyboard
1605
+ semantics. */
1537
1606
  .ds-247420 .ds-file-row {
1538
- display: grid; grid-template-columns: 26px minmax(0, 1fr) auto auto;
1539
- gap: 14px; align-items: center;
1607
+ display: flex; align-items: center; gap: 10px;
1540
1608
  padding: 11px 16px; background: var(--bg);
1541
1609
  border: var(--bw-hair) solid transparent;
1542
1610
  border-radius: var(--r-2); color: var(--fg);
@@ -1545,6 +1613,14 @@
1545
1613
  border-color var(--dur-snap) var(--ease),
1546
1614
  transform var(--dur-snap) var(--ease);
1547
1615
  }
1616
+ .ds-247420 .ds-file-open {
1617
+ display: flex; align-items: center; gap: 14px;
1618
+ flex: 1 1 auto; min-width: 0;
1619
+ background: none; border: 0; padding: 0; margin: 0;
1620
+ color: inherit; font: inherit; text-align: left; cursor: pointer;
1621
+ }
1622
+ .ds-247420 .ds-file-open[disabled] { cursor: default; }
1623
+ .ds-247420 .ds-file-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-1); }
1548
1624
  .ds-247420 .ds-file-row:hover {
1549
1625
  background: var(--bg-2);
1550
1626
  border-color: var(--rule);
@@ -1558,7 +1634,7 @@
1558
1634
  .ds-247420 .ds-file-row[data-file-type="code"] { border-left-width: 3px; border-left-color: var(--green-2); }
1559
1635
  .ds-247420 .ds-file-row[data-file-type="text"] { border-left-width: 3px; border-left-color: var(--ink-3); }
1560
1636
  .ds-247420 .ds-file-row[data-file-type="archive"] { border-left-width: 3px; border-left-color: var(--flame); }
1561
- .ds-247420 .ds-file-row[data-file-type="document"] { border-left-width: 3px; border-left-color: var(--sun); }
1637
+ .ds-247420 .ds-file-row[data-file-type="document"] { border-left-width: 3px; border-left-color: var(--amber, var(--sun)); }
1562
1638
  .ds-247420 .ds-file-row[data-file-type="symlink"] { border-left-width: 3px; border-left-color: var(--purple); }
1563
1639
  .ds-247420 .ds-file-row[data-file-type="other"] { border-left-width: 3px; border-left-color: var(--fg-3); }
1564
1640
 
@@ -1566,7 +1642,7 @@
1566
1642
  .ds-247420 .ds-file-row .title {
1567
1643
  font-weight: 500; font-size: var(--fs-sm);
1568
1644
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1569
- min-width: 0;
1645
+ min-width: 0; flex: 1 1 auto;
1570
1646
  }
1571
1647
  .ds-247420 .ds-file-row .code {
1572
1648
  font-family: var(--ff-mono); font-size: var(--fs-micro);
@@ -1589,7 +1665,7 @@
1589
1665
  .ds-247420 .ds-file-row[data-file-type="audio"] .ds-file-icon { color: var(--sky); }
1590
1666
  .ds-247420 .ds-file-row[data-file-type="code"] .ds-file-icon { color: var(--green-2); }
1591
1667
  .ds-247420 .ds-file-row[data-file-type="archive"] .ds-file-icon { color: var(--flame); }
1592
- .ds-247420 .ds-file-row[data-file-type="document"] .ds-file-icon { color: var(--sun); }
1668
+ .ds-247420 .ds-file-row[data-file-type="document"] .ds-file-icon { color: var(--amber, var(--sun)); }
1593
1669
 
1594
1670
  /* Row actions — hidden until hover/focus, revealed without layout shift. */
1595
1671
  .ds-247420 .ds-file-actions {
@@ -1608,6 +1684,112 @@
1608
1684
  .ds-247420 .ds-file-act:hover { background: var(--bg-3); color: var(--fg); }
1609
1685
  .ds-247420 .ds-file-act-warn:hover { background: color-mix(in oklab, var(--warn) 18%, var(--bg)); color: var(--warn); }
1610
1686
 
1687
+ /* Multi-select — per-row checkbox, header tri-state, bulk action strip. */
1688
+ .ds-247420 .ds-file-check {
1689
+ display: inline-flex; align-items: center; justify-content: center;
1690
+ min-width: 28px; height: 28px; padding: 0 4px;
1691
+ background: transparent; border: 0; border-radius: var(--r-1);
1692
+ font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3);
1693
+ cursor: pointer;
1694
+ transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
1695
+ }
1696
+ .ds-247420 .ds-file-check:hover { background: var(--bg-3); color: var(--fg); }
1697
+ .ds-247420 .ds-file-check.is-marked { color: var(--accent); }
1698
+ .ds-247420 .ds-file-check:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
1699
+ .ds-247420 .ds-file-check[disabled] { opacity: 0.4; cursor: default; }
1700
+ .ds-247420 .ds-file-row.is-marked { background: var(--accent-tint); border-color: var(--accent); }
1701
+ .ds-247420 .ds-file-selectall {
1702
+ display: inline-flex; align-items: center; gap: var(--space-1);
1703
+ font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-2);
1704
+ cursor: pointer; background: none; border: none;
1705
+ padding: var(--space-1); border-radius: var(--r-1);
1706
+ }
1707
+ .ds-247420 .ds-file-selectall:hover { background: var(--bg-2); color: var(--fg); }
1708
+ .ds-247420 .ds-file-selectall:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
1709
+ .ds-247420 .ds-file-controls { display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); flex-wrap: wrap; }
1710
+ .ds-247420 .ds-file-controls .spread { flex: 1 1 auto; }
1711
+ .ds-247420 .ds-file-controls .ds-file-sort { padding: 0; }
1712
+ .ds-247420 .ds-bulkbar {
1713
+ display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
1714
+ padding: var(--space-1) var(--space-2);
1715
+ background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
1716
+ }
1717
+ .ds-247420 .ds-bulkbar-count { font-size: var(--fs-tiny); color: var(--fg-2); }
1718
+ /* BulkBar is a toolbar (it even declares role=toolbar): compact rect buttons,
1719
+ quiet destructive outline - the app arm-confirms destructive bulk actions
1720
+ via ConfirmDialog, so the strip never needs a loud CTA. */
1721
+ .ds-247420 .ds-bulkbar .btn, .ds-247420 .ds-bulkbar .btn-primary {
1722
+ padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
1723
+ }
1724
+ .ds-247420 .ds-bulkbar .btn { background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2); }
1725
+ .ds-247420 .ds-bulkbar .btn:hover { background: var(--bg-2); color: var(--fg); }
1726
+ .ds-247420 .ds-bulkbar .btn-primary.danger { background: transparent; color: var(--warn); border: var(--bw-hair) solid var(--warn); }
1727
+ .ds-247420 .ds-bulkbar .btn-primary.danger:hover { background: color-mix(in oklab, var(--warn) 12%, transparent); color: var(--warn); }
1728
+ @media (pointer: coarse) {
1729
+ .ds-247420 .ds-bulkbar .btn, .ds-247420 .ds-bulkbar .btn-primary { min-height: 44px; }
1730
+ }
1731
+
1732
+ /* Density picker — list / compact / thumbnails. */
1733
+ .ds-247420 .ds-density {
1734
+ display: inline-flex; gap: 2px; padding: 2px;
1735
+ background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
1736
+ }
1737
+ .ds-247420 .ds-density-btn {
1738
+ font-size: var(--fs-tiny); color: var(--fg-2);
1739
+ background: none; border: none; cursor: pointer;
1740
+ padding: 2px var(--space-2); border-radius: calc(var(--r-1) - 2px);
1741
+ transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
1742
+ }
1743
+ .ds-247420 .ds-density-btn:hover { color: var(--fg); }
1744
+ .ds-247420 .ds-density-btn.active { background: var(--accent-tint); color: var(--accent); }
1745
+ .ds-247420 .ds-density-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
1746
+
1747
+ /* Compact density — tighter rows for long listings. */
1748
+ .ds-247420 .ds-file-grid[data-density="compact"] { gap: 2px; }
1749
+ .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-row { padding: 5px 12px; gap: 10px; }
1750
+ .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-row .title { font-size: var(--fs-xs); }
1751
+ .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
1752
+ .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-icon { width: 20px; height: 20px; font-size: 13px; }
1753
+
1754
+ /* Thumbnail density — tile grid; image entries carry a real lazy thumbnail. */
1755
+ .ds-247420 .ds-file-grid-thumb {
1756
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
1757
+ gap: var(--space-3); align-items: start;
1758
+ }
1759
+ .ds-247420 .ds-file-cell {
1760
+ position: relative;
1761
+ background: var(--bg); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
1762
+ overflow: hidden;
1763
+ transition: border-color var(--dur-snap) var(--ease), background var(--dur-snap) var(--ease);
1764
+ }
1765
+ .ds-247420 .ds-file-cell:hover { border-color: var(--fg-3); }
1766
+ .ds-247420 .ds-file-cell.active { border-color: var(--accent); background: var(--accent-tint); }
1767
+ .ds-247420 .ds-file-cell.is-marked { border-color: var(--accent); background: var(--accent-tint); }
1768
+ .ds-247420 .ds-file-cell.is-locked { opacity: 0.6; }
1769
+ .ds-247420 .ds-file-cell-open {
1770
+ display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1);
1771
+ width: 100%; padding: var(--space-1); margin: 0;
1772
+ background: none; border: none; cursor: pointer; color: var(--fg);
1773
+ }
1774
+ .ds-247420 .ds-file-cell-open[disabled] { cursor: default; }
1775
+ .ds-247420 .ds-file-cell-open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-2); }
1776
+ .ds-247420 .ds-file-cell-media {
1777
+ display: flex; align-items: center; justify-content: center;
1778
+ width: 100%; aspect-ratio: 4 / 3;
1779
+ background: var(--bg-2); border-radius: var(--r-1); overflow: hidden;
1780
+ }
1781
+ .ds-247420 .ds-file-cell-media .ds-file-icon { width: 34px; height: 34px; font-size: 24px; }
1782
+ .ds-247420 .ds-file-cell-thumb { width: 100%; height: 100%; object-fit: cover; }
1783
+ .ds-247420 .ds-file-cell-name {
1784
+ font-size: var(--fs-tiny); text-align: left;
1785
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1786
+ }
1787
+ .ds-247420 .ds-file-cell-meta { font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--fg-3); text-align: left; }
1788
+ .ds-247420 .ds-file-cell-check {
1789
+ position: absolute; top: 4px; left: 4px; z-index: 1;
1790
+ background: color-mix(in oklab, var(--bg) 78%, transparent);
1791
+ }
1792
+
1611
1793
  /* Card mode — opt-in via data-columns; switches the list to a grid. */
1612
1794
  .ds-247420 .ds-file-grid[data-columns] { display: grid; gap: var(--space-3); }
1613
1795
  .ds-247420 .ds-file-grid[data-columns="1"] { grid-template-columns: 1fr; }
@@ -1632,6 +1814,11 @@
1632
1814
  .ds-247420 .app-main > div > .ds-file-stage,
1633
1815
  .ds-247420 .app-main .ds-file-stage { padding-top: 0; }
1634
1816
 
1817
+ /* Full-width files stack: the stage's space-3 vertical beat without its
1818
+ 920px cap/auto-margins, so the roots / toolbar / bulkbar / uploads / grid
1819
+ bands keep one consistent rhythm instead of touching edge-to-edge. */
1820
+ .ds-247420 .ds-files-stack { display: flex; flex-direction: column; gap: var(--space-3); min-height: 0; }
1821
+
1635
1822
  /* Breadcrumb path */
1636
1823
  .ds-247420 .ds-crumb-path {
1637
1824
  display: flex; align-items: center; flex-wrap: wrap; gap: 2px;
@@ -1652,10 +1839,38 @@
1652
1839
  display: flex; align-items: center; justify-content: space-between;
1653
1840
  gap: var(--space-2); flex-wrap: wrap;
1654
1841
  }
1842
+ /* Dense page header: one row, small heading, single-line muted lede. The
1843
+ working surfaces (files, live, history, settings) lead with content, not a
1844
+ display H1 + paragraph that costs the first 150px of every fold. */
1845
+ .ds-247420 .ds-page-header-dense { margin: 0 0 var(--space-3); }
1846
+ .ds-247420 .ds-page-header-dense-row { display: flex; align-items: baseline; gap: var(--space-3); min-width: 0; }
1847
+ .ds-247420 .ds-page-header-dense-row h1 {
1848
+ margin: 0; font-size: var(--fs-lg); line-height: 1.3; font-weight: 600;
1849
+ letter-spacing: normal; flex: 0 0 auto;
1850
+ }
1851
+ .ds-247420 .ds-page-header-dense-lede {
1852
+ flex: 1 1 auto; min-width: 0;
1853
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1854
+ font-size: var(--fs-sm); color: var(--fg-3);
1855
+ }
1856
+ .ds-247420 .ds-page-header-dense .ds-page-header-right { flex: 0 0 auto; margin-left: auto; }
1655
1857
  .ds-247420 .ds-file-toolbar-left,
1656
1858
  .ds-247420 .ds-file-toolbar-right {
1657
1859
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
1658
1860
  }
1861
+ /* Toolbar-scoped buttons: quiet, compact, rectangular - a toolbar is chrome,
1862
+ not a CTA row; the stadium pill stays for real page-level actions. */
1863
+ .ds-247420 .ds-file-toolbar .btn, .ds-247420 .ds-file-toolbar .btn-ghost {
1864
+ padding: 5px 12px; min-height: 32px;
1865
+ border-radius: var(--r-1);
1866
+ font-weight: 500;
1867
+ background: transparent;
1868
+ border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
1869
+ }
1870
+ .ds-247420 .ds-file-toolbar .btn:hover, .ds-247420 .ds-file-toolbar .btn-ghost:hover { background: var(--bg-2); color: var(--fg); }
1871
+ @media (pointer: coarse) {
1872
+ .ds-247420 .ds-file-toolbar .btn, .ds-247420 .ds-file-toolbar .btn-ghost { min-height: 44px; }
1873
+ }
1659
1874
  .ds-247420 .ds-meta-mono {
1660
1875
  font-family: var(--ff-mono); font-size: var(--fs-xs);
1661
1876
  color: var(--fg-3); letter-spacing: var(--tr-caps);
@@ -1696,6 +1911,20 @@
1696
1911
  0%, 100% { border-color: var(--accent); }
1697
1912
  50% { border-color: color-mix(in oklab, var(--accent) 45%, transparent); }
1698
1913
  }
1914
+ /* Wrapper form (has children): no permanent chrome - the content renders as if
1915
+ the zone were not there, and the dashed affordance overlays it ONLY while a
1916
+ drag is in flight. */
1917
+ .ds-247420 .ds-dropzone--wrap { position: relative; border: none; border-radius: 0; background: transparent; }
1918
+ .ds-247420 .ds-dropzone--wrap > .ds-dropzone-inner { display: none; }
1919
+ .ds-247420 .ds-dropzone--wrap.dragover > .ds-dropzone-inner {
1920
+ display: flex; position: absolute; inset: 0; z-index: 5;
1921
+ margin: 0; padding: var(--space-3);
1922
+ align-items: center; justify-content: center;
1923
+ background: color-mix(in srgb, var(--bg) 84%, transparent);
1924
+ outline: var(--bw-rule) dashed var(--accent); outline-offset: -6px;
1925
+ border-radius: var(--r-3);
1926
+ }
1927
+ .ds-247420 .ds-dropzone--wrap.dragover { animation: none; }
1699
1928
 
1700
1929
  /* Upload progress */
1701
1930
  .ds-247420 .ds-upload-progress { display: flex; flex-direction: column; gap: 6px; }
@@ -1889,7 +2118,7 @@
1889
2118
  border-radius: var(--r-pill); color: var(--fg);
1890
2119
  font-family: inherit; font-size: var(--fs-xs);
1891
2120
  }
1892
- .ds-247420 .ds-filter-input:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
2121
+ .ds-247420 .ds-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
1893
2122
 
1894
2123
  /* Loading skeleton — placeholder rows while a directory loads. */
1895
2124
  .ds-247420 .ds-file-grid-loading { display: flex; flex-direction: column; gap: 4px; }
@@ -1916,44 +2145,19 @@
1916
2145
  .ds-247420 .ds-file-row[draggable="true"] { cursor: grab; }
1917
2146
  .ds-247420 .ds-file-row[draggable="true"]:active { cursor: grabbing; }
1918
2147
 
1919
- /* Multi-select per-row checkbox overlay + selected state + bulk bar. */
2148
+ /* (A stale duplicate multi-select block used to live here: an absolute-overlay
2149
+ .ds-file-check hidden until hover, plus .ds-file-check.on / .ds-file-row.selected
2150
+ / .ds-bulk-bar rules NO component ever emits. Being later in source at equal
2151
+ specificity it clobbered the real in-flow checkbox at ~1243 - the shipped
2152
+ multi-select rendered invisible-until-hover with clipped brackets. The live
2153
+ rules are the earlier block; only the still-load-bearing bits remain below.) */
1920
2154
  .ds-247420 .ds-file-row { position: relative; }
1921
- .ds-247420 .ds-file-check {
1922
- position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
1923
- width: 18px; height: 18px; padding: 0; z-index: 1;
1924
- display: inline-flex; align-items: center; justify-content: center;
1925
- border: var(--bw-hair) solid var(--rule); border-radius: 5px;
1926
- background: var(--bg); color: var(--accent-fg);
1927
- font-size: var(--fs-micro); line-height: 1; cursor: pointer;
1928
- opacity: 0; transition: opacity var(--dur-base) var(--ease), background var(--dur-snap) var(--ease);
1929
- }
1930
- .ds-247420 .ds-file-row:hover .ds-file-check,
1931
- .ds-247420 .ds-file-row:focus-within .ds-file-check,
1932
- .ds-247420 .ds-file-check.on { opacity: 1; }
1933
- /* Touch / coarse-pointer devices have no hover — keep checkboxes AND the
1934
- per-row action buttons (rename/delete/download) visible so the file manager
1935
- is fully reachable without a pointer (e.g. an iPad in landscape). */
2155
+ /* Touch / coarse-pointer devices have no hover — keep the per-row action
2156
+ buttons (rename/delete/download) visible so the file manager is fully
2157
+ reachable without a pointer (e.g. an iPad in landscape). */
1936
2158
  @media (hover: none), (pointer: coarse) {
1937
- .ds-247420 .ds-file-check { opacity: 1; }
1938
2159
  .ds-247420 .ds-file-actions { opacity: 1; }
1939
2160
  }
1940
- .ds-247420 .ds-file-check.on { background: var(--accent); border-color: var(--accent); }
1941
- .ds-247420 .ds-file-row.selected {
1942
- background: var(--accent-tint);
1943
- border-color: var(--accent);
1944
- }
1945
- .ds-247420 .ds-file-row.selected:hover { background: color-mix(in oklab, var(--accent) 22%, var(--bg)); }
1946
-
1947
- .ds-247420 .ds-bulk-bar {
1948
- display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
1949
- padding: 10px 14px; border-radius: var(--r-2);
1950
- background: var(--accent-tint);
1951
- border: var(--bw-hair) solid var(--accent);
1952
- position: sticky; top: var(--space-2); z-index: 2;
1953
- }
1954
- .ds-247420 .ds-bulk-count {
1955
- font-weight: 600; font-size: var(--fs-sm); margin-right: auto;
1956
- }
1957
2161
 
1958
2162
  /* Keyboard-shortcuts hint — compact two-column legend. */
1959
2163
  .ds-247420 .ds-shortcuts-hint {
@@ -1990,12 +2194,19 @@
1990
2194
  .ds-247420 .ds-segmented .ds-seg-btn:hover { color: var(--fg); }
1991
2195
  .ds-247420 .ds-segmented .ds-seg-btn.is-on {
1992
2196
  background: var(--bg); color: var(--fg);
1993
- box-shadow: var(--shadow-1);
2197
+ box-shadow: inset 0 0 0 var(--bw-hair, 1px) var(--rule);
1994
2198
  }
1995
2199
  .ds-247420 .ds-theme-toggle.btn {
1996
2200
  font-family: var(--ff-mono); font-size: var(--fs-xs);
1997
2201
  display: inline-flex; align-items: center; gap: 6px;
1998
2202
  }
2203
+ /* CSS-drawn half-disc mark on the compact theme toggle: keeps the control
2204
+ legible when its text label is hidden (icon-only rail strip). */
2205
+ .ds-247420 .ds-theme-disc {
2206
+ flex: 0 0 auto; width: 14px; height: 14px; border-radius: 50%;
2207
+ border: var(--bw-hair) solid var(--fg-3);
2208
+ background: linear-gradient(90deg, var(--fg-3) 0 50%, transparent 50% 100%);
2209
+ }
1999
2210
 
2000
2211
  /* ============================================================
2001
2212
  Chat kit polish — styles every class emitted by Chat /
@@ -2176,10 +2387,10 @@
2176
2387
  .ds-247420 .chat-bubble.chat-code .token.atrule,
2177
2388
  .ds-247420 .chat-bubble.chat-code .token.selector { color: var(--accent); }
2178
2389
  .ds-247420 .chat-bubble.chat-code .token.string,
2179
- .ds-247420 .chat-bubble.chat-code .token.attr-value { color: var(--mascot); }
2390
+ .ds-247420 .chat-bubble.chat-code .token.attr-value { color: var(--code-str-alt, var(--mascot)); }
2180
2391
  .ds-247420 .chat-bubble.chat-code .token.comment { color: var(--fg-3); font-style: italic; }
2181
2392
  .ds-247420 .chat-bubble.chat-code .token.number,
2182
- .ds-247420 .chat-bubble.chat-code .token.boolean { color: var(--sun); }
2393
+ .ds-247420 .chat-bubble.chat-code .token.boolean { color: var(--code-num, var(--sun)); }
2183
2394
  .ds-247420 .chat-bubble.chat-code .token.punctuation { color: var(--fg-2); }
2184
2395
  .ds-247420 .chat-bubble.chat-code .token.property,
2185
2396
  .ds-247420 .chat-bubble.chat-code .token.attr-name { color: var(--sky); }
@@ -2196,7 +2407,6 @@
2196
2407
  .ds-247420 .chat-msg:hover .chat-image,
2197
2408
  .ds-247420 .chat-image:hover {
2198
2409
  border-color: color-mix(in oklab, var(--accent) 35%, transparent);
2199
- box-shadow: 0 4px 16px color-mix(in oklab, var(--fg) 12%, transparent);
2200
2410
  }
2201
2411
  .ds-247420 .chat-image img { display: block; width: 100%; height: auto; max-height: 360px; object-fit: cover; }
2202
2412
  .ds-247420 .chat-image .cap,
@@ -2237,7 +2447,7 @@
2237
2447
  border-radius: 12px; overflow: hidden; max-width: min(100%, 480px);
2238
2448
  transition: box-shadow 0.12s ease, border-color 0.12s ease;
2239
2449
  }
2240
- .ds-247420 .chat-msg:hover .chat-pdf { border-color: color-mix(in oklab, var(--accent) 30%, transparent); box-shadow: 0 2px 12px color-mix(in oklab, var(--fg) 6%, transparent); }
2450
+ .ds-247420 .chat-msg:hover .chat-pdf { border-color: color-mix(in oklab, var(--accent) 30%, transparent); }
2241
2451
  .ds-247420 .chat-pdf-head {
2242
2452
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
2243
2453
  background: color-mix(in oklab, var(--fg) 5%, var(--bg-2));
@@ -2265,7 +2475,6 @@
2265
2475
  .ds-247420 .chat-link:hover {
2266
2476
  background: var(--bg-3);
2267
2477
  border-color: color-mix(in oklab, var(--accent) 40%, transparent);
2268
- box-shadow: 0 2px 12px color-mix(in oklab, var(--fg) 8%, transparent);
2269
2478
  }
2270
2479
  .ds-247420 .chat-link:not(:has(.thumb)):not(:has(img)) { grid-template-columns: 1fr; }
2271
2480
  .ds-247420 .chat-link .thumb,
@@ -2350,7 +2559,9 @@
2350
2559
  display: flex; align-items: flex-end; flex-wrap: wrap; gap: var(--space-2);
2351
2560
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
2352
2561
  background: var(--bg);
2353
- border: var(--bw-hair) solid var(--rule);
2562
+ /* The composer sits bg-on-bg: the 14% --rule hairline is ~1.3:1 on paper,
2563
+ leaving the primary input near-invisible at rest - use the strong rule. */
2564
+ border: var(--bw-hair) solid var(--rule-strong);
2354
2565
  border-radius: var(--r-2);
2355
2566
  flex-shrink: 0;
2356
2567
  transition: border-color var(--dur-snap) var(--ease), box-shadow var(--dur-snap) var(--ease);
@@ -2364,7 +2575,9 @@
2364
2575
  background: none; color: var(--fg);
2365
2576
  border: none; border-radius: 0;
2366
2577
  font-family: inherit; font-size: var(--fs-sm);
2367
- line-height: 1.45; resize: none;
2578
+ /* 1.5 is the value that actually renders (a later polish block used to
2579
+ re-declare it; the sizing block now states the truth). */
2580
+ line-height: 1.5; resize: none;
2368
2581
  min-height: 28px; max-height: 200px;
2369
2582
  box-sizing: border-box; overflow-y: auto;
2370
2583
  scrollbar-width: thin;
@@ -2431,13 +2644,19 @@
2431
2644
  /* ── select primitive ─────────────────────────────────────────────────── */
2432
2645
  .ds-247420 .ds-select {
2433
2646
  width: 100%;
2434
- padding: 10px 14px;
2647
+ min-width: 0;
2648
+ padding: 10px 30px 10px 14px; /* right gap clears the chevron */
2435
2649
  background: var(--bg-2);
2436
2650
  border: 0;
2437
2651
  border-radius: var(--r-2);
2438
2652
  font-family: inherit;
2439
2653
  font-size: var(--fs-sm);
2440
2654
  color: var(--fg);
2655
+ /* Clip long option text gracefully - a select that cuts 'Claude Sonnet
2656
+ (latest' mid-parenthesis reads as broken; ellipsis reads as truncated. */
2657
+ text-overflow: ellipsis;
2658
+ white-space: nowrap;
2659
+ overflow: hidden;
2441
2660
  appearance: none;
2442
2661
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-3) 50%),
2443
2662
  linear-gradient(135deg, var(--fg-3) 50%, transparent 50%);
@@ -2446,15 +2665,12 @@
2446
2665
  background-repeat: no-repeat;
2447
2666
  cursor: pointer;
2448
2667
  }
2449
- .ds-247420 .ds-select:focus { box-shadow: inset 0 0 0 2px var(--accent); }
2668
+ .ds-247420 .ds-select:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
2450
2669
  .ds-247420 .ds-select:hover { background-color: var(--bg-3); }
2451
2670
 
2452
- /* ── chat composer autogrow polish ────────────────────────────────────── */
2671
+ /* ── chat composer autogrow polish (sizing lives in the primary block) ── */
2453
2672
  .ds-247420 .chat-composer textarea {
2454
- resize: none;
2455
- overflow-y: auto;
2456
2673
  transition: height var(--dur-snap) var(--ease);
2457
- line-height: 1.5;
2458
2674
  }
2459
2675
  .ds-247420 .chat-composer textarea:disabled {
2460
2676
  opacity: 0.5;
@@ -3348,42 +3564,121 @@
3348
3564
  .ds-247420 .ws-pane-toggle:hover { background: var(--bg-3); color: var(--fg); }
3349
3565
  .ds-247420 .ws-pane-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3350
3566
 
3351
- /* Responsive: below 900px collapse to a single content column; rail+sessions+pane
3352
- become overlay drawers the host can toggle, or simply hide on mobile. We keep it
3353
- honest: stack rail (icon row) over content, hide sessions+pane unless toggled. */
3567
+ /* Drawer toggles and the scrim are hidden by default and revealed by the staged
3568
+ media blocks BELOW - these base rules must precede those blocks in source
3569
+ order: at equal specificity the later rule wins regardless of media, so a
3570
+ trailing display:none silently kills every drawer affordance (shipped bug:
3571
+ the mobile drawers were dead because these lines used to sit last). */
3572
+ .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); }
3573
+ .ds-247420 .ws-scrim { display: none; }
3574
+
3575
+ /* Responsive: the columns yield to the CONTENT in stages - the main column is
3576
+ the product, so the right pane gives way first, the sessions list second,
3577
+ and only below 900px does the rail itself drop to a fixed icon strip. Yielded
3578
+ columns stay reachable as overlay drawers (.ws-pane-open / .ws-sessions-open,
3579
+ toggled from the crumb bar) over a shared fade scrim. Before this staging the
3580
+ 4-track grid survived down to 901px and crushed the chat thread to ~245px
3581
+ while the 320px context pane kept its full width. */
3582
+
3583
+ /* Stage 1 (<=1480px): drop the pane TRACK; the context pane becomes a right
3584
+ overlay drawer. */
3585
+ @media (max-width: 1480px) {
3586
+ .ds-247420 .ws-shell,
3587
+ .ds-247420 .ws-shell.ws-no-pane,
3588
+ .ds-247420 .ws-shell.ws-pane-collapsed,
3589
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions) {
3590
+ grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) minmax(0, 1fr);
3591
+ grid-template-areas: "rail sessions content";
3592
+ }
3593
+ .ds-247420 .ws-shell.ws-no-sessions,
3594
+ .ds-247420 .ws-shell.ws-no-pane.ws-no-sessions,
3595
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions {
3596
+ grid-template-columns: var(--ws-rail-w) minmax(0, 1fr);
3597
+ grid-template-areas: "rail content";
3598
+ }
3599
+ /* Drawer width is a literal: --ws-pane-w is 0px while pane-collapsed, and a
3600
+ desktop-collapsed pane must still open as a full drawer. */
3601
+ .ds-247420 .ws-pane {
3602
+ position: fixed; inset: 0 0 0 auto;
3603
+ width: min(340px, 85vw);
3604
+ z-index: 42; transform: translateX(110%);
3605
+ transition: transform var(--dur-base) var(--ease);
3606
+ }
3607
+ .ds-247420 .ws-shell.ws-pane-open .ws-pane { transform: translateX(0); width: min(340px, 85vw); }
3608
+ .ds-247420 .ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane { border-left: var(--bw-hair) solid var(--bg-3); }
3609
+ .ds-247420 .ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane > :not(.ws-pane-toggle) { display: revert; }
3610
+ /* The desktop collapse chevron is meaningless in drawer mode. */
3611
+ .ds-247420 .ws-pane-toggle { display: none; }
3612
+ .ds-247420 .ws-pane-drawer-toggle { display: inline-flex; }
3613
+ /* Scrim is always present from this stage down so it FADES with the drawer
3614
+ instead of hard-appearing; pointer-events gate keeps it inert while closed. */
3615
+ .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); }
3616
+ .ds-247420 .ws-shell.ws-sessions-open .ws-scrim, .ds-247420 .ws-shell.ws-pane-open .ws-scrim { opacity: 1; pointer-events: auto; }
3617
+ }
3618
+
3619
+ /* Stage 2 (<=1100px): drop the sessions TRACK; the conversation list becomes a
3620
+ left overlay drawer. */
3621
+ @media (max-width: 1100px) {
3622
+ .ds-247420 .ws-shell,
3623
+ .ds-247420 .ws-shell.ws-no-pane,
3624
+ .ds-247420 .ws-shell.ws-pane-collapsed,
3625
+ .ds-247420 .ws-shell.ws-no-sessions,
3626
+ .ds-247420 .ws-shell.ws-no-pane.ws-no-sessions,
3627
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed:not(.ws-no-sessions),
3628
+ .ds-247420 .ws-shell.ws-no-pane.ws-pane-collapsed.ws-no-sessions {
3629
+ grid-template-columns: var(--ws-rail-w) minmax(0, 1fr);
3630
+ grid-template-areas: "rail content";
3631
+ }
3632
+ .ds-247420 .ws-sessions {
3633
+ position: fixed; inset: 0 auto 0 0;
3634
+ width: min(var(--ws-sessions-w), 80vw);
3635
+ z-index: 42; transform: translateX(-110%);
3636
+ transition: transform var(--dur-base) var(--ease);
3637
+ border-right: var(--bw-hair) solid var(--bg-3);
3638
+ }
3639
+ .ds-247420 .ws-shell.ws-sessions-open .ws-sessions { transform: translateX(0); }
3640
+ .ds-247420 .ws-sessions-drawer-toggle { display: inline-flex; }
3641
+ }
3642
+
3643
+ /* Stage 3 (<=900px): single content column; the rail drops to a fixed icon-only
3644
+ strip. Labels hide UNCONDITIONALLY here - a 60px rail showing clipped label
3645
+ text ('age', 'Ne') is the worst of both worlds. */
3354
3646
  @media (max-width: 900px) {
3355
3647
  .ds-247420 .ws-shell,
3356
3648
  .ds-247420 .ws-shell.ws-no-sessions,
3357
3649
  .ds-247420 .ws-shell.ws-no-pane,
3358
- .ds-247420 .ws-shell.ws-no-pane.ws-no-sessions {
3359
- grid-template-columns: 1fr;
3650
+ .ds-247420 .ws-shell.ws-pane-collapsed,
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: minmax(0, 1fr);
3360
3655
  grid-template-areas: "content";
3361
3656
  }
3362
3657
  .ds-247420 .ws-rail { position: fixed; inset: 0 auto 0 0; width: var(--ws-rail-w-collapsed); z-index: 40; }
3363
- .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); }
3364
- .ds-247420 .ws-shell.ws-sessions-open .ws-sessions { transform: translateX(0); }
3365
- /* On mobile the pane is a drawer driven by .ws-pane-open (an explicit open
3366
- intent), NOT by :not(.ws-pane-collapsed) - the desktop collapse default is
3367
- "open" which would otherwise pop the pane over the thread on every load. */
3368
- .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); }
3369
- .ds-247420 .ws-shell.ws-pane-open .ws-pane { transform: translateX(0); }
3658
+ .ds-247420 .ws-rail .ws-rail-brand,
3659
+ .ds-247420 .ws-rail .ws-rail-action-label,
3660
+ .ds-247420 .ws-rail .ws-rail-item-label,
3661
+ .ds-247420 .ws-rail .ws-rail-item-count,
3662
+ .ds-247420 .ws-rail .ds-theme-toggle-label { display: none; }
3663
+ .ds-247420 .ws-rail .ws-rail-item, .ds-247420 .ws-rail .ws-rail-action { justify-content: center; gap: 0; }
3664
+ .ds-247420 .ws-rail .ws-rail-head { justify-content: center; }
3665
+ /* Expand/collapse is meaningless on the icon strip. */
3666
+ .ds-247420 .ws-rail-toggle { display: none; }
3667
+ .ds-247420 .ws-rail-foot { display: flex; justify-content: center; }
3668
+ .ds-247420 .ws-sessions { inset: 0 auto 0 var(--ws-rail-w-collapsed); }
3370
3669
  .ds-247420 .ws-content { grid-area: content; padding-left: var(--ws-rail-w-collapsed); }
3371
- .ds-247420 .ws-rail-collapsed .ws-rail-item-label, .ds-247420 .ws-rail-collapsed .ws-rail-brand { display: none; }
3372
- /* Tap-scrim behind an open drawer; dismiss on click. Hidden unless a drawer
3373
- is open so it never blocks the content area on desktop. */
3374
- /* Scrim is always present on mobile so it can FADE with the drawer instead of
3375
- hard-appearing via a display toggle; pointer-events gate keeps it inert
3376
- while closed. Reduced-motion users get the global transition kill -> instant. */
3377
- .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); }
3378
- .ds-247420 .ws-shell.ws-sessions-open .ws-scrim, .ds-247420 .ws-shell.ws-pane-open .ws-scrim { opacity: 1; pointer-events: auto; }
3379
- /* The mobile drawer-toggle affordances live in the crumb bar. */
3380
- .ds-247420 .ws-drawer-toggle { display: inline-flex; }
3670
+ /* The Crumb's narrow collapse elsewhere keys on the .app @container, which
3671
+ does not exist inside WorkspaceShell - mirror it here so the crumb bar
3672
+ cannot overflow a narrow viewport (trail hides, leaf ellipsizes, the
3673
+ right cluster wraps under instead of pushing past the edge). */
3674
+ .ds-247420 .ws-crumb { padding-top: 6px; padding-bottom: 6px; }
3675
+ .ds-247420 .ws-crumb .app-crumb { flex-wrap: wrap; min-width: 0; }
3676
+ .ds-247420 .ws-crumb .app-crumb > .sep, .ds-247420 .ws-crumb .app-crumb > span:not(.crumb-right):not(.leaf) { display: none; }
3677
+ .ds-247420 .ws-crumb .app-crumb .leaf { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
3678
+ .ds-247420 .ws-crumb .app-crumb .crumb-right { margin-left: 0; flex-wrap: wrap; min-width: 0; display: inline-flex; }
3381
3679
  }
3382
- /* Drawer toggles are mobile-only chrome; hidden on the desktop grid. */
3383
- .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); }
3384
3680
  .ds-247420 .ws-drawer-toggle:hover { background: var(--bg-2); color: var(--fg); }
3385
3681
  .ds-247420 .ws-drawer-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3386
- .ds-247420 .ws-scrim { display: none; }
3387
3682
 
3388
3683
  /* ============================================================
3389
3684
  Row title highlight, expanded-row actions, filter pills.
@@ -4978,6 +5273,13 @@
4978
5273
  .ds-247420 .agentchat-controls .select,
4979
5274
  .ds-247420 .agentchat-controls [role="combobox"] { min-width: 130px; max-width: 240px; }
4980
5275
  .ds-247420 .agentchat-controls .ds-select { min-width: 130px; max-width: 240px; }
5276
+ /* One shared control metric for the most-seen chrome row (mirrors the
5277
+ .ds-dash-toolbar precedent): selects, buttons, export acts all 32px / r-1. */
5278
+ .ds-247420 .agentchat-controls .ds-select { min-height: 32px; padding: 4px 28px 4px 10px; font-size: var(--fs-sm); border-radius: var(--r-1); }
5279
+ .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; }
5280
+ @media (pointer: coarse) {
5281
+ .ds-247420 .agentchat-controls .ds-select, .ds-247420 .agentchat-controls .btn, .ds-247420 .agentchat-controls .btn-primary { min-height: 44px; }
5282
+ }
4981
5283
 
4982
5284
  /* Narrow viewports: let the agent/model selects share the row two-up, then
4983
5285
  stack full-width on the smallest screens, and drop the status to its own
@@ -5000,7 +5302,7 @@
5000
5302
  gap: .4em;
5001
5303
  white-space: nowrap;
5002
5304
  margin-left: auto;
5003
- font-size: .85em;
5305
+ font-size: var(--fs-tiny);
5004
5306
  color: var(--fg-3);
5005
5307
  }
5006
5308
  /* status disc — a CSS-drawn dot, not a glyph; pulses while streaming */
@@ -5026,7 +5328,7 @@
5026
5328
  display: flex;
5027
5329
  align-items: center;
5028
5330
  gap: var(--space-2, 8px);
5029
- font-size: .85em;
5331
+ font-size: var(--fs-tiny);
5030
5332
  color: var(--fg-3);
5031
5333
  flex-wrap: wrap;
5032
5334
  }
@@ -5067,7 +5369,7 @@
5067
5369
  gap: .5em;
5068
5370
  }
5069
5371
  .ds-247420 .agentchat-title { font-size: 1em; margin: 0; }
5070
- .ds-247420 .agentchat-sub { font-size: .85em; color: var(--fg-3); }
5372
+ .ds-247420 .agentchat-sub { font-size: var(--fs-tiny); color: var(--fg-3); }
5071
5373
  /* Thread wrapper hosts the absolutely-positioned jump-to-latest button. */
5072
5374
  .ds-247420 .agentchat-thread-wrap { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
5073
5375
  .ds-247420 .agentchat-thread {
@@ -5083,7 +5385,7 @@
5083
5385
  .ds-247420 .agentchat-jump {
5084
5386
  position: absolute; right: 16px; bottom: 12px; z-index: 3;
5085
5387
  display: none; align-items: center; gap: .35em;
5086
- padding: .4em .8em; font: inherit; font-size: .8em; cursor: pointer;
5388
+ padding: .4em .8em; font: inherit; font-size: var(--fs-tiny); cursor: pointer;
5087
5389
  border-radius: 999px; border: var(--bw-hair) solid var(--rule);
5088
5390
  background: var(--bg-2); color: var(--fg-2, var(--fg));
5089
5391
  box-shadow: 0 2px 8px color-mix(in srgb, var(--fg) 14%, transparent);
@@ -5127,7 +5429,7 @@
5127
5429
  max-width: 46ch;
5128
5430
  }
5129
5431
  .ds-247420 .agentchat-empty-title { margin: 0; font-size: 1.05em; color: var(--fg-2, var(--fg)); }
5130
- .ds-247420 .agentchat-empty-sub { margin: 0; font-size: .9em; }
5432
+ .ds-247420 .agentchat-empty-sub { margin: 0; font-size: var(--fs-sm); }
5131
5433
  .ds-247420 .agentchat-empty-suggestions {
5132
5434
  display: flex;
5133
5435
  flex-wrap: wrap;
@@ -5138,7 +5440,7 @@
5138
5440
  .ds-247420 .agentchat-empty-suggestion {
5139
5441
  cursor: pointer;
5140
5442
  font: inherit;
5141
- font-size: .85em;
5443
+ font-size: var(--fs-tiny);
5142
5444
  padding: .4em .8em;
5143
5445
  border-radius: 999px;
5144
5446
  border: 1px solid color-mix(in srgb, var(--fg) 16%, transparent);
@@ -5158,7 +5460,7 @@
5158
5460
  text-align: left;
5159
5461
  width: 100%;
5160
5462
  }
5161
- .ds-247420 .agentchat-install-text { margin: 0; font-size: .9em; color: var(--fg-3); }
5463
+ .ds-247420 .agentchat-install-text { margin: 0; font-size: var(--fs-sm); color: var(--fg-3); }
5162
5464
  .ds-247420 .agentchat-install-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--space-1, 4px); }
5163
5465
  .ds-247420 .agentchat-install-row {
5164
5466
  display: flex; align-items: center; gap: var(--space-2, 8px);
@@ -5199,7 +5501,7 @@
5199
5501
  gap: .5em;
5200
5502
  padding: .3em .2em;
5201
5503
  color: var(--fg-3);
5202
- font-size: .85em;
5504
+ font-size: var(--fs-tiny);
5203
5505
  }
5204
5506
  .ds-247420 .agentchat-working-text { color: var(--fg-3); }
5205
5507
  /* Self-contained dots (chat-thinking-dots lives in a kit sheet not bundled
@@ -5262,28 +5564,40 @@
5262
5564
  ConversationList — left-rail "Chats" column.
5263
5565
  ---------------------------------------------------------------------------- */
5264
5566
  .ds-247420 .ds-sessions { display: flex; flex-direction: column; min-height: 0; height: 100%; }
5265
- .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); }
5567
+ /* One row: quiet icon new-chat beside the search. The list's new-chat must not
5568
+ repeat the rail's primary CTA - two identical green buttons on screen at
5569
+ once read as a layout mistake, and the rail action already owns 'new'. */
5570
+ .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); }
5266
5571
  .ds-247420 .ds-session-new {
5267
- display: flex; align-items: center; gap: var(--space-2); justify-content: center;
5268
- padding: var(--space-2) var(--space-3); min-height: 44px;
5269
- background: var(--accent); color: var(--accent-fg, var(--bg)); border: none;
5572
+ display: inline-flex; align-items: center; justify-content: center; gap: 0;
5573
+ flex: 0 0 auto; order: 2;
5574
+ width: 36px; min-height: 36px; padding: 0;
5575
+ background: transparent; color: var(--fg-2);
5576
+ border: var(--bw-hair) solid var(--rule);
5270
5577
  border-radius: var(--r-1); cursor: pointer; font-family: var(--ff-body);
5271
- font-size: var(--fs-sm); font-weight: 600;
5578
+ font-size: var(--fs-sm); font-weight: 500;
5272
5579
  }
5273
- .ds-247420 .ds-session-new:hover { filter: brightness(1.08); }
5580
+ .ds-247420 .ds-session-new > span { display: none; }
5581
+ .ds-247420 .ds-session-new:hover { background: var(--bg-2); color: var(--fg); }
5582
+ .ds-247420 .ds-session-search { order: 1; flex: 1 1 auto; min-width: 0; }
5274
5583
  .ds-247420 .ds-session-new:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
5275
5584
  .ds-247420 .ds-session-search {
5276
- width: 100%; padding: var(--space-2) var(--space-3); min-height: 44px;
5585
+ width: 100%; padding: var(--space-1) var(--space-3); min-height: 36px;
5277
5586
  background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); color: var(--fg);
5278
5587
  border-radius: var(--r-1); font-family: var(--ff-body); font-size: var(--fs-sm);
5279
5588
  }
5280
- .ds-247420 .ds-session-search:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
5589
+ .ds-247420 .ds-session-search:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
5590
+ /* Touch floor (must FOLLOW the base rules - same specificity, order decides). */
5591
+ @media (pointer: coarse) {
5592
+ .ds-247420 .ds-session-new { width: 44px; min-height: 44px; }
5593
+ .ds-247420 .ds-session-search { min-height: 44px; }
5594
+ }
5281
5595
  .ds-247420 .ds-session-list, .ds-247420 .ds-session-groups { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-2); }
5282
5596
  /* Grouped rows (Today/Yesterday/...) lay out like the flat list; the section
5283
5597
  label sticks to the top of the scroll area for Claude-Desktop-style headers. */
5284
5598
  .ds-247420 .ds-session-group { display: flex; flex-direction: column; }
5285
5599
  .ds-247420 .ds-session-group-rows { display: flex; flex-direction: column; gap: 2px; }
5286
- .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); }
5600
+ .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); }
5287
5601
  .ds-247420 .ds-session-row {
5288
5602
  position: relative; display: flex; align-items: center; gap: var(--space-2);
5289
5603
  width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: 2px;
@@ -5314,9 +5628,22 @@
5314
5628
  SessionDashboard — grid of live-session cards.
5315
5629
  ---------------------------------------------------------------------------- */
5316
5630
  .ds-247420 .ds-dash { display: flex; flex-direction: column; min-height: 0; }
5317
- .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; }
5631
+ .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; }
5318
5632
  .ds-247420 .ds-dash-count { font-size: var(--fs-sm); color: var(--fg-2); font-weight: 600; }
5319
- .ds-247420 .ds-dash-header .btn, .ds-247420 .ds-dash-header .btn-primary { margin-left: auto; }
5633
+ /* Stop is a quiet destructive control in chrome, not a page-level red CTA;
5634
+ it only goes loud while ARMED (the one-shot press-again confirm). */
5635
+ .ds-247420 .ds-dash-header .btn, .ds-247420 .ds-dash-header .btn-primary {
5636
+ margin-left: 0;
5637
+ padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
5638
+ }
5639
+ .ds-247420 .ds-dash-header .btn-primary.danger {
5640
+ background: transparent; color: var(--warn);
5641
+ border: var(--bw-hair) solid var(--warn);
5642
+ }
5643
+ .ds-247420 .ds-dash-header .btn-primary.danger:hover {
5644
+ background: color-mix(in oklab, var(--warn) 12%, transparent); color: var(--warn);
5645
+ }
5646
+ .ds-247420 .ds-dash-header .btn-primary.danger.is-armed { background: var(--warn); color: var(--paper); border-color: var(--warn); }
5320
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); }
5321
5648
  .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); }
5322
5649
  .ds-247420 .ds-dash-card.is-error { border-color: var(--flame); }
@@ -5343,7 +5670,6 @@
5343
5670
  ---------------------------------------------------------------------------- */
5344
5671
  .ds-247420 .ds-context { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3); }
5345
5672
  .ds-247420 .ds-context .panel { background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-2); }
5346
- .ds-247420 .ds-context .row { font-size: var(--fs-sm); }
5347
5673
  .ds-247420 .ds-context .row .meta { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-2); }
5348
5674
  .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; }
5349
5675
  .ds-247420 .ds-context-actions { display: flex; gap: var(--space-2); }
@@ -5396,7 +5722,18 @@
5396
5722
  .ds-247420 .ds-dash-status.is-running { color: var(--accent); }
5397
5723
 
5398
5724
  /* --- C2: dashboard sort/filter toolbar + stream-state line. --- */
5725
+ /* The toolbar is part of the ONE header row (count | heartbeat ... filter,
5726
+ sort, errors-only, stop): compact controls that align on a shared 32px
5727
+ height, never a stacked full-width form column. */
5399
5728
  .ds-247420 .ds-dash-toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
5729
+ .ds-247420 .ds-dash-toolbar .ds-search-input {
5730
+ width: 200px; min-height: 32px; padding: 5px 10px;
5731
+ font-size: var(--fs-sm); border-radius: var(--r-1);
5732
+ }
5733
+ .ds-247420 .ds-dash-toolbar .ds-select, .ds-247420 .ds-dash-toolbar select {
5734
+ min-height: 32px; padding: 4px 10px; font-size: var(--fs-sm);
5735
+ width: auto; border-radius: var(--r-1);
5736
+ }
5400
5737
  .ds-247420 .ds-dash-stream { font-size: var(--fs-tiny); color: var(--fg-3); }
5401
5738
  .ds-247420 .ds-dash-stream.is-lost { color: var(--flame); }
5402
5739
  .ds-247420 .ds-dash-stream.is-connecting { color: var(--amber, #d9a93a); }
@@ -5607,7 +5944,7 @@
5607
5944
  .ds-247420 .chat-msg-flat.you { background: none; }
5608
5945
  .ds-247420 .chat-msg-flat .chat-stack { max-width: var(--measure); width: 100%; margin: 0; align-items: stretch; }
5609
5946
  .ds-247420 .chat-msg-flat.you .chat-stack { align-items: stretch; }
5610
- .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); }
5947
+ .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); }
5611
5948
  .ds-247420 .chat-msg-flat.you .chat-role { color: var(--accent); }
5612
5949
  .ds-247420 .chat-msg-flat .chat-bubble { background: none; border: none; border-radius: 0; padding: 0; max-width: 100%; box-shadow: none; transform: none; }
5613
5950
  .ds-247420 .chat-msg-flat.you .chat-bubble { background: none; color: inherit; }
@@ -5648,7 +5985,7 @@
5648
5985
  .ds-247420 .chat-msg .chat-tool.tool-error .chat-tool-status { color: var(--flame); background: color-mix(in oklab, var(--flame) 12%, transparent); }
5649
5986
  .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); }
5650
5987
  .ds-247420 .chat-tool-section { display: flex; flex-direction: column; gap: var(--space-1); }
5651
- .ds-247420 .chat-tool-section-label { font-size: var(--fs-micro); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--fg-3); }
5988
+ .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); }
5652
5989
  .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; }
5653
5990
  .ds-247420 .chat-tool-pre.is-error { color: var(--flame); }
5654
5991
  .ds-247420 .chat-tool-pre.chat-tool-empty { color: var(--fg-3); }
@@ -5687,7 +6024,7 @@
5687
6024
 
5688
6025
  /* Live command-center: status-bucket groups + header breakdown + heartbeat. */
5689
6026
  .ds-247420 .ds-dash-group { display: flex; flex-direction: column; gap: var(--space-2); }
5690
- .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); }
6027
+ .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); }
5691
6028
  .ds-247420 .ds-dash-breakdown { display: flex; align-items: center; gap: var(--space-1); font-size: var(--fs-sm); color: var(--fg-2); }
5692
6029
  .ds-247420 .ds-dash-breakdown .seg.is-running { color: var(--green); font-weight: 600; }
5693
6030
  .ds-247420 .ds-dash-breakdown .seg.is-error { color: var(--flame); font-weight: 600; }
@@ -5713,9 +6050,9 @@
5713
6050
  .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); }
5714
6051
  .ds-247420 .ds-preview-code .token.punctuation { color: var(--fg-2); }
5715
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); }
5716
- .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); }
5717
- .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); }
5718
- .ds-247420 .ds-preview-code .token.function, .ds-247420 .ds-preview-code .token.class-name { color: var(--flame); }
6053
+ .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
+ .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
+ .ds-247420 .ds-preview-code .token.function, .ds-247420 .ds-preview-code .token.class-name { color: var(--code-fn, var(--flame)); }
5719
6056
  .ds-247420 .ds-preview-code.has-gutter { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0 var(--space-2); }
5720
6057
  .ds-247420 .ds-preview-code.has-gutter code { display: block; min-width: 0; overflow-x: auto; }
5721
6058
  .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; }
@@ -5728,6 +6065,36 @@
5728
6065
  }
5729
6066
  .ds-247420 .ds-preview-media.is-actual { max-width: none; max-height: none; }
5730
6067
 
6068
+ /* ----------------------------------------------------------------------------
6069
+ Compact-button tiers — ONE spec for the small quiet rect buttons that eight
6070
+ surfaces used to clone with drifting metrics/tones. chat.css loads after
6071
+ app-shell.css in the bundle, so these same-specificity rules win by order.
6072
+ Tier A (toolbar-grade, 32px) matches .ds-file-toolbar .btn, the reference;
6073
+ tier B (inline-row-grade, 24px) for actions inside dense row strips.
6074
+ Hover/focus/active-state rules on the originals still apply.
6075
+ ---------------------------------------------------------------------------- */
6076
+ .ds-247420 .row-act, .ds-247420 .ds-dash-errors-toggle, .ds-247420 .agentchat-export-act, .ds-247420 .ds-file-more-btn {
6077
+ min-height: 32px; padding: 5px 12px; border-radius: var(--r-1);
6078
+ font-family: var(--ff-body); font-size: var(--fs-tiny); font-weight: 500;
6079
+ background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
6080
+ cursor: pointer;
6081
+ }
6082
+ .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 {
6083
+ background: var(--bg-2); color: var(--fg);
6084
+ }
6085
+ .ds-247420 .agentchat-install-copy, .ds-247420 .ds-upload-act, .ds-247420 .ds-session-meta-copy {
6086
+ min-height: 24px; padding: 2px 8px; border-radius: var(--r-1);
6087
+ font-family: var(--ff-body); font-size: var(--fs-tiny);
6088
+ background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-3);
6089
+ cursor: pointer;
6090
+ }
6091
+ .ds-247420 .agentchat-install-copy:hover, .ds-247420 .ds-upload-act:hover, .ds-247420 .ds-session-meta-copy:hover {
6092
+ background: var(--bg-2); color: var(--fg);
6093
+ }
6094
+ @media (pointer: coarse) {
6095
+ .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
+ }
6097
+
5731
6098
  /* editor-primitives.css */
5732
6099
  /* editor-primitives.css — chrome for in-engine editors, inspectors, IDEs,
5733
6100
  debug HUDs. All rules under .ds-247420 scope (build prefixes). Tokens