anentrypoint-design 0.0.209 → 0.0.211

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/app-shell.css CHANGED
@@ -190,7 +190,7 @@ pre .n { color: var(--green-2); }
190
190
  body.canvas-host { background: transparent !important; }
191
191
 
192
192
  :root {
193
- --app-status-h: var(--size-base);
193
+ --app-status-h: 26px;
194
194
  --app-topbar-h: var(--size-lg);
195
195
  --app-crumb-h: var(--size-sm);
196
196
  }
@@ -384,14 +384,15 @@ body.canvas-host { background: transparent !important; }
384
384
  .app-status {
385
385
  display: flex; align-items: center; gap: var(--space-3);
386
386
  width: 100%;
387
- min-height: var(--app-status-h);
388
- padding: 10px var(--pad-x);
387
+ height: var(--app-status-h); min-height: var(--app-status-h);
388
+ /* A thin desktop status strip, not a webpage footer band. */
389
+ padding: 0 var(--space-4);
389
390
  /* Status chrome is prose, not code - mono is reserved for code/paths. */
390
- font-family: var(--ff-body); font-size: var(--fs-xs);
391
+ font-family: var(--ff-body); font-size: var(--fs-xs); line-height: 1.2;
391
392
  color: var(--fg-3);
392
393
  border-top: 1px solid var(--rule);
393
394
  }
394
- .app-status .item { color: inherit; white-space: nowrap; }
395
+ .app-status .item { color: inherit; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
395
396
  .app-status .item:first-of-type { color: var(--accent); }
396
397
  .app-status .spread { flex: 1; }
397
398
  /* The status bar NEVER wraps: at narrow widths the trailing items (hints,
@@ -406,13 +407,14 @@ body.canvas-host { background: transparent !important; }
406
407
  Primitives
407
408
  ============================================================ */
408
409
  .btn, .btn-primary, .btn-ghost {
409
- display: inline-flex; align-items: center; gap: 8px;
410
- padding: 13px 22px;
410
+ display: inline-flex; align-items: center; justify-content: center; gap: 6px;
411
+ padding: 8px 14px; min-height: 32px;
411
412
  font-family: var(--ff-body);
412
413
  font-weight: 600; font-size: var(--fs-sm);
413
414
  text-decoration: none;
414
415
  cursor: pointer;
415
- border-radius: var(--r-pill);
416
+ /* Rounded-rect app chrome, not a marketing-page stadium CTA. */
417
+ border-radius: var(--r-1);
416
418
  border: 0;
417
419
  transition: transform var(--dur-snap) var(--ease), background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
418
420
  }
@@ -588,8 +590,13 @@ body.canvas-host { background: transparent !important; }
588
590
  .row.rail-purple::before,
589
591
  .row.rail-flame::before { height: 56%; opacity: 1; }
590
592
  .row.rail-green::before { background: var(--accent); }
591
- .row.rail-purple::before { background: var(--purple-2, #7F18A4); }
593
+ .row.rail-purple::before { background: var(--purple-2); }
592
594
  .row.rail-flame::before { background: var(--flame); }
595
+ /* Differentiate the rail by SHAPE, not hue alone (color-blind safety): error
596
+ reads as a taller solid bar, subagent as a dashed/gapped fill, ok stays the
597
+ short solid bar. Paired with the sr-only status word emitted by Row(). */
598
+ .row.rail-flame::before { height: 64%; }
599
+ .row.rail-purple::before { background: repeating-linear-gradient(var(--purple-2) 0 4px, transparent 4px 7px); }
593
600
  .row-grid { /* explicit grid-template-columns set inline */ }
594
601
  /* A row with no leading code/index drops the empty first column so the title
595
602
  takes the full width instead of wrapping in the narrow code gutter. */
@@ -825,8 +832,8 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
825
832
  border: 0; border-radius: var(--r-2);
826
833
  box-shadow: inset 0 0 0 1px var(--rule);
827
834
  }
828
- .row-form input:focus,
829
- .row-form textarea:focus { box-shadow: inset 0 0 0 2px var(--accent); }
835
+ .row-form input:focus-visible,
836
+ .row-form textarea:focus-visible { box-shadow: var(--focus-ring-inset); }
830
837
 
831
838
  /* Field char counter (TextField maxLength) */
832
839
  .ds-field-count {
@@ -847,9 +854,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
847
854
  Responsive Design — Mobile (480px), Tablet (1024px), Desktop (1440px+)
848
855
  ============================================================ */
849
856
 
850
- /* ────────────────────────────────────────────────────────────────────
857
+ /* --------------------------------------------------------------------
851
858
  Mobile Portrait Breakpoint (480px and below)
852
- ────────────────────────────────────────────────────────────────────── */
859
+ ---------------------------------------------------------------------- */
853
860
  @media (max-width: 480px) {
854
861
  /* App Layout: single-column + drawer is handled once in the ≤900px block;
855
862
  no need to re-declare grid-template-columns here (was a redundant !important). */
@@ -973,9 +980,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
973
980
  .cli .copy { padding: 6px 12px; font-size: var(--fs-micro); }
974
981
  }
975
982
 
976
- /* ────────────────────────────────────────────────────────────────────
983
+ /* --------------------------------------------------------------------
977
984
  Container Query Responsive (720px and below)
978
- ────────────────────────────────────────────────────────────────────── */
985
+ ---------------------------------------------------------------------- */
979
986
  @container (max-width: 760px) {
980
987
  .app-body { grid-template-columns: 1fr !important; }
981
988
  .app-side-shell { border-right: 0; border-bottom: 1px solid var(--rule); }
@@ -985,9 +992,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
985
992
  .row .sub { grid-column: 1 / -1; order: 3; }
986
993
  }
987
994
 
988
- /* ────────────────────────────────────────────────────────────────────
995
+ /* --------------------------------------------------------------------
989
996
  Tablet Landscape Breakpoint (768px to 1024px)
990
- ────────────────────────────────────────────────────────────────────── */
997
+ ---------------------------------------------------------------------- */
991
998
  @media (min-width: 481px) and (max-width: 1024px) {
992
999
  /* App Layout — side handled by 900px drawer block; restore for 901-1024 */
993
1000
  .app-side a {
@@ -1064,9 +1071,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1064
1071
  }
1065
1072
  }
1066
1073
 
1067
- /* ────────────────────────────────────────────────────────────────────
1074
+ /* --------------------------------------------------------------------
1068
1075
  Mid Breakpoint (768px and below) — collapse sidebar + simplify row grid
1069
- ────────────────────────────────────────────────────────────────────── */
1076
+ ---------------------------------------------------------------------- */
1070
1077
  @media (max-width: 768px) {
1071
1078
  /* Sidebar stacks above main rather than sitting beside it */
1072
1079
  .app-body { grid-template-columns: 1fr; }
@@ -1081,9 +1088,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1081
1088
  .row .sub { grid-column: 1 / -1; }
1082
1089
  }
1083
1090
 
1084
- /* ────────────────────────────────────────────────────────────────────
1091
+ /* --------------------------------------------------------------------
1085
1092
  Desktop Breakpoint Enhancements (1025px and up)
1086
- ────────────────────────────────────────────────────────────────────── */
1093
+ ---------------------------------------------------------------------- */
1087
1094
  @media (min-width: 1025px) {
1088
1095
  /* Chat Bubbles */
1089
1096
  .chat-stack { max-width: min(70%, 480px); }
@@ -1104,7 +1111,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1104
1111
  .ds-chat-md { font-size: var(--fs-sm); line-height: 1.6; }
1105
1112
  .ds-chat-composer { display: flex; gap: 8px; padding: var(--space-4); }
1106
1113
  .ds-chat-composer input { flex: 1; padding: 13px 18px; background: var(--bg-2); border: 0; border-radius: var(--r-pill); font-family: inherit; font-size: var(--fs-sm); color: var(--fg); }
1107
- .ds-chat-composer input:focus { box-shadow: inset 0 0 0 2px var(--accent); }
1114
+ .ds-chat-composer input:focus-visible { box-shadow: var(--focus-ring-inset); }
1108
1115
 
1109
1116
  /* ============================================================
1110
1117
  File surface — responsive grid + row layouts
@@ -1130,7 +1137,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1130
1137
  background: var(--bg); color: var(--fg);
1131
1138
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
1132
1139
  }
1133
- .ds-file-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
1140
+ .ds-file-filter-input:focus-visible { outline: none; box-shadow: var(--focus-ring-inset); }
1134
1141
  .ds-file-sort { display: flex; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); }
1135
1142
  .ds-file-sort-btn {
1136
1143
  font-size: var(--fs-tiny); font-family: var(--ff-mono); color: var(--fg-3);
@@ -1251,6 +1258,29 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1251
1258
  .ds-file-act-warn:hover { background: color-mix(in oklab, var(--warn) 18%, var(--bg)); color: var(--warn); }
1252
1259
 
1253
1260
  /* Multi-select — per-row checkbox, header tri-state, bulk action strip. */
1261
+ /* CSS-drawn multi-select checkbox: a bordered box that fills with the accent +
1262
+ a border-drawn tick when its parent button is .is-marked or aria-checked.
1263
+ Shared by FileRow/FileCell (.is-marked) and the file/session select-all +
1264
+ SessionCard select (aria-checked true/mixed) since the bundle concatenates
1265
+ all CSS. Replaces the old [x]/[ ] bracket text - no glyphs, AT keeps the
1266
+ role=checkbox/aria-checked name+state. */
1267
+ .ds-check-box {
1268
+ width: 15px; height: 15px; box-sizing: border-box; flex: 0 0 auto; position: relative;
1269
+ border: 1.5px solid var(--rule); border-radius: 4px;
1270
+ transition: background var(--dur-snap) var(--ease), border-color var(--dur-snap) var(--ease);
1271
+ }
1272
+ .is-marked > .ds-check-box,
1273
+ [aria-checked="true"] > .ds-check-box { background: var(--accent); border-color: var(--accent); }
1274
+ .is-marked > .ds-check-box::after,
1275
+ [aria-checked="true"] > .ds-check-box::after {
1276
+ content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
1277
+ border: solid var(--bg); border-width: 0 1.5px 1.5px 0; transform: rotate(45deg);
1278
+ }
1279
+ [aria-checked="mixed"] > .ds-check-box { background: var(--accent); border-color: var(--accent); }
1280
+ [aria-checked="mixed"] > .ds-check-box::after {
1281
+ content: ""; position: absolute; left: 2px; right: 2px; top: 50%; height: 1.5px; margin-top: -0.75px; background: var(--bg);
1282
+ }
1283
+
1254
1284
  .ds-file-check {
1255
1285
  display: inline-flex; align-items: center; justify-content: center;
1256
1286
  min-width: 28px; height: 28px; padding: 0 4px;
@@ -1280,7 +1310,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1280
1310
  padding: var(--space-1) var(--space-2);
1281
1311
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
1282
1312
  }
1283
- .ds-bulkbar-count { font-size: var(--fs-tiny); color: var(--fg-2); }
1313
+ .ds-bulkbar-count { font-size: var(--fs-sm); font-weight: 600; color: var(--fg-2); }
1284
1314
  /* BulkBar is a toolbar (it even declares role=toolbar): compact rect buttons,
1285
1315
  quiet destructive outline - the app arm-confirms destructive bulk actions
1286
1316
  via ConfirmDialog, so the strip never needs a loud CTA. */
@@ -1541,7 +1571,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1541
1571
  .ds-file-empty-glyph { font-size: 34px; opacity: 0.55; }
1542
1572
  .ds-file-empty-text { font-size: var(--fs-sm); }
1543
1573
 
1544
- /* ── Modals ───────────────────────────────────────────────── */
1574
+ /* -- Modals ------------------------------------------------- */
1545
1575
  .ds-modal-backdrop {
1546
1576
  position: fixed; inset: 0; z-index: var(--z-modal, 800);
1547
1577
  display: flex; align-items: center; justify-content: center;
@@ -1587,7 +1617,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1587
1617
  border-radius: var(--r-2); color: var(--fg);
1588
1618
  font-family: inherit; font-size: var(--fs-sm);
1589
1619
  }
1590
- .ds-modal-input:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
1620
+ .ds-modal-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
1591
1621
  /* In-body modal error (role=alert): mutation failures (409/403) surface INSIDE
1592
1622
  the dialog, not behind the fixed overlay. */
1593
1623
  .ds-modal-error {
@@ -1602,7 +1632,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1602
1632
  color: var(--on-color);
1603
1633
  }
1604
1634
 
1605
- /* ── Preview ──────────────────────────────────────────────── */
1635
+ /* -- Preview ------------------------------------------------ */
1606
1636
  .ds-preview-head {
1607
1637
  display: flex; align-items: center; gap: var(--space-3);
1608
1638
  padding: var(--space-3) var(--space-4);
@@ -1675,7 +1705,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1675
1705
  .ds-file-stage { padding: var(--space-3) var(--space-2); }
1676
1706
  }
1677
1707
 
1678
- /* ── File browser UX affordances ──────────────────────────── */
1708
+ /* -- File browser UX affordances ---------------------------- */
1679
1709
  /* Toolbar filter input — compact search box. */
1680
1710
  .ds-filter-input {
1681
1711
  width: clamp(120px, 22vw, 220px);
@@ -1684,7 +1714,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1684
1714
  border-radius: var(--r-pill); color: var(--fg);
1685
1715
  font-family: inherit; font-size: var(--fs-xs);
1686
1716
  }
1687
- .ds-filter-input:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
1717
+ .ds-filter-input:focus-visible { outline: none; box-shadow: var(--focus-ring-inset); }
1688
1718
 
1689
1719
  /* Loading skeleton — placeholder rows while a directory loads. */
1690
1720
  .ds-file-grid-loading { display: flex; flex-direction: column; gap: 4px; }
@@ -2207,7 +2237,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2207
2237
  .app-side a .glyph { font-family: var(--ff-mono); font-size: 13px; font-weight: 600; color: var(--fg-3); text-align: center; }
2208
2238
  .app-side a.active .glyph { color: var(--accent); }
2209
2239
 
2210
- /* ── select primitive ─────────────────────────────────────────────────── */
2240
+ /* -- select primitive --------------------------------------------------- */
2211
2241
  .ds-select {
2212
2242
  width: 100%;
2213
2243
  min-width: 0;
@@ -2231,10 +2261,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2231
2261
  background-repeat: no-repeat;
2232
2262
  cursor: pointer;
2233
2263
  }
2234
- .ds-select:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
2264
+ .ds-select:focus-visible { box-shadow: var(--focus-ring-inset); }
2235
2265
  .ds-select:hover { background-color: var(--bg-3); }
2236
2266
 
2237
- /* ── chat composer autogrow polish (sizing lives in the primary block) ── */
2267
+ /* -- chat composer autogrow polish (sizing lives in the primary block) -- */
2238
2268
  .chat-composer textarea {
2239
2269
  transition: height var(--dur-snap) var(--ease);
2240
2270
  }
@@ -2243,7 +2273,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2243
2273
  cursor: not-allowed;
2244
2274
  }
2245
2275
 
2246
- /* ── mobile responsive: chat ──────────────────────────────────────────── */
2276
+ /* -- mobile responsive: chat -------------------------------------------- */
2247
2277
  @media (max-width: 768px) {
2248
2278
  .chat-stack { max-width: 100%; }
2249
2279
  .chat-msg { padding: 4px 0; }
@@ -2268,9 +2298,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2268
2298
  Comprehensive improvements for perfect UX across all surfaces
2269
2299
  ============================================================ */
2270
2300
 
2271
- /* ────────────────────────────────────────────────────────────
2301
+ /* ------------------------------------------------------------
2272
2302
  Component States — Disabled, Loading, Error, Success
2273
- ────────────────────────────────────────────────────────────── */
2303
+ -------------------------------------------------------------- */
2274
2304
 
2275
2305
  /* Disabled state for all interactive elements */
2276
2306
  .btn:disabled, .btn-primary:disabled, .btn-ghost:disabled,
@@ -2322,9 +2352,9 @@ textarea.error {
2322
2352
  opacity: 0.8;
2323
2353
  }
2324
2354
 
2325
- /* ────────────────────────────────────────────────────────────
2355
+ /* ------------------------------------------------------------
2326
2356
  Enhanced Button Micro-Interactions
2327
- ────────────────────────────────────────────────────────────── */
2357
+ -------------------------------------------------------------- */
2328
2358
 
2329
2359
  /* Button scale feedback on active */
2330
2360
  .btn:active:not(:disabled),
@@ -2354,9 +2384,9 @@ input[type="checkbox"], input[type="radio"] {
2354
2384
  -webkit-touch-callout: none;
2355
2385
  }
2356
2386
 
2357
- /* ────────────────────────────────────────────────────────────
2387
+ /* ------------------------------------------------------------
2358
2388
  Drag-and-Drop Styles
2359
- ────────────────────────────────────────────────────────────── */
2389
+ -------------------------------------------------------------- */
2360
2390
 
2361
2391
  /* Draggable element */
2362
2392
  [draggable="true"], .draggable {
@@ -2413,9 +2443,9 @@ input[type="checkbox"], input[type="radio"] {
2413
2443
  50% { opacity: 1; }
2414
2444
  }
2415
2445
 
2416
- /* ────────────────────────────────────────────────────────────
2446
+ /* ------------------------------------------------------------
2417
2447
  Context Menu Styles
2418
- ────────────────────────────────────────────────────────────── */
2448
+ -------------------------------------------------------------- */
2419
2449
 
2420
2450
  .ds-context-menu {
2421
2451
  position: absolute;
@@ -2477,9 +2507,9 @@ input[type="checkbox"], input[type="radio"] {
2477
2507
  cursor: context-menu;
2478
2508
  }
2479
2509
 
2480
- /* ────────────────────────────────────────────────────────────
2510
+ /* ------------------------------------------------------------
2481
2511
  Enhanced Form Inputs
2482
- ────────────────────────────────────────────────────────────── */
2512
+ -------------------------------------------------------------- */
2483
2513
 
2484
2514
  input[type="text"],
2485
2515
  input[type="email"],
@@ -2505,7 +2535,7 @@ textarea::placeholder {
2505
2535
  color: var(--fg-3);
2506
2536
  }
2507
2537
 
2508
- /* ── Field controls: themed base for TextField / Select / SearchInput ──
2538
+ /* -- Field controls: themed base for TextField / Select / SearchInput --
2509
2539
  Root fix: previously only `transition` was set, so themed apps got
2510
2540
  browser-default white boxes in dark mode and labels collided with inputs
2511
2541
  because `.ds-field` had no layout. */
@@ -2554,7 +2584,7 @@ textarea::placeholder {
2554
2584
  .ds-field .ds-select:focus-visible,
2555
2585
  .ds-search-input:focus-visible {
2556
2586
  outline: none;
2557
- box-shadow: inset 0 0 0 2px var(--accent);
2587
+ box-shadow: var(--focus-ring-inset);
2558
2588
  }
2559
2589
  .ds-field input:disabled,
2560
2590
  .ds-field textarea:disabled,
@@ -2592,9 +2622,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2592
2622
  color: var(--fg);
2593
2623
  }
2594
2624
 
2595
- /* ────────────────────────────────────────────────────────────
2625
+ /* ------------------------------------------------------------
2596
2626
  Accessibility Enhancements
2597
- ────────────────────────────────────────────────────────────── */
2627
+ -------------------------------------------------------------- */
2598
2628
 
2599
2629
  /* Enhanced focus-visible for all interactive elements */
2600
2630
  [role="button"]:focus-visible,
@@ -2623,11 +2653,17 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2623
2653
  animation-iteration-count: 1 !important;
2624
2654
  transition-duration: 0.01ms !important;
2625
2655
  }
2656
+ /* Kill the residual paint frame of looping skeleton/shimmer placeholders and
2657
+ give reduced-motion users a steady placeholder fill instead. */
2658
+ .skeleton, .ds-skeleton, .ds-session-row-skeleton .ds-skel {
2659
+ animation: none !important;
2660
+ background: var(--bg-2) !important;
2661
+ }
2626
2662
  }
2627
2663
 
2628
- /* ────────────────────────────────────────────────────────────
2664
+ /* ------------------------------------------------------------
2629
2665
  Performance
2630
- ────────────────────────────────────────────────────────────── */
2666
+ -------------------------------------------------------------- */
2631
2667
 
2632
2668
  /* Limit layout/style containment to self-contained components. `paint` is
2633
2669
  intentionally omitted — it clips focus rings, tooltips and dropdowns that
@@ -2636,9 +2672,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2636
2672
  contain: layout style;
2637
2673
  }
2638
2674
 
2639
- /* ────────────────────────────────────────────────────────────
2675
+ /* ------------------------------------------------------------
2640
2676
  Mobile Touch Optimizations
2641
- ────────────────────────────────────────────────────────────── */
2677
+ -------------------------------------------------------------- */
2642
2678
 
2643
2679
  @media (hover: none) and (pointer: coarse) {
2644
2680
  /* Mobile devices: larger touch targets, faster responses */
@@ -2669,9 +2705,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2669
2705
  }
2670
2706
  }
2671
2707
 
2672
- /* ────────────────────────────────────────────────────────────
2708
+ /* ------------------------------------------------------------
2673
2709
  Theme Transition Smoothness
2674
- ────────────────────────────────────────────────────────────── */
2710
+ -------------------------------------------------------------- */
2675
2711
 
2676
2712
  /* Scoped to the DS wrapper so the design system never reaches out and
2677
2713
  animates the host document's html/body. */
@@ -2680,9 +2716,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2680
2716
  color var(--dur-base) var(--ease);
2681
2717
  }
2682
2718
 
2683
- /* ────────────────────────────────────────────────────────────
2719
+ /* ------------------------------------------------------------
2684
2720
  Empty State & Loading States
2685
- ────────────────────────────────────────────────────────────── */
2721
+ -------------------------------------------------------------- */
2686
2722
 
2687
2723
  .empty-state {
2688
2724
  display: flex; flex-direction: column; align-items: center; gap: var(--space-4);
@@ -2720,9 +2756,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2720
2756
  .skeleton-line { height: 12px; margin-bottom: 12px; }
2721
2757
  .skeleton-title { height: 24px; margin-bottom: 16px; width: 60%; }
2722
2758
 
2723
- /* ────────────────────────────────────────────────────────────
2759
+ /* ------------------------------------------------------------
2724
2760
  Toast Notification Styles
2725
- ────────────────────────────────────────────────────────────── */
2761
+ -------------------------------------------------------------- */
2726
2762
 
2727
2763
  .toast {
2728
2764
  position: fixed;
@@ -3007,10 +3043,13 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3007
3043
  All sizing/colour from kit tokens; no hardcoded palette.
3008
3044
  ---------------------------------------------------------------------------- */
3009
3045
  .ws-shell {
3010
- --ws-rail-w: 232px;
3046
+ /* Fluid chrome columns: shrink on small laptops, breathe on ultrawide, so the
3047
+ ~848px of fixed chrome no longer eats a constant slab. An inline --ws-*-w
3048
+ written by a resize drag overrides these (inline wins), pinning the width. */
3049
+ --ws-rail-w: clamp(200px, 16vw, 260px);
3011
3050
  --ws-rail-w-collapsed: 60px;
3012
- --ws-sessions-w: 296px;
3013
- --ws-pane-w: 320px;
3051
+ --ws-sessions-w: clamp(248px, 22vw, 360px);
3052
+ --ws-pane-w: clamp(288px, 24vw, 420px);
3014
3053
  display: grid;
3015
3054
  grid-template-columns: var(--ws-rail-w) var(--ws-sessions-w) 1fr var(--ws-pane-w);
3016
3055
  grid-template-areas: "rail sessions content pane";
@@ -3031,6 +3070,21 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3031
3070
  .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"; }
3032
3071
  .ws-shell.ws-rail-collapsed { --ws-rail-w: var(--ws-rail-w-collapsed); }
3033
3072
  .ws-shell.ws-pane-collapsed { --ws-pane-w: 0px; }
3073
+ /* Sessions column desktop collapse (parity with the pane collapse), reclaiming
3074
+ its width for a full-width thread/grid. */
3075
+ .ws-shell.ws-sessions-collapsed { --ws-sessions-w: 0px; }
3076
+ .ws-sessions-collapsed .ws-sessions { overflow: hidden; border-right: none; }
3077
+ .ws-sessions-collapsed .ws-sessions > * { display: none; }
3078
+ /* Column resize handles: a thin keyboard-accessible separator pinned to the
3079
+ right edge of each chrome track; drag (or ArrowLeft/Right) writes a clamped
3080
+ inline --ws-*-w. */
3081
+ .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; }
3082
+ .ws-resizer::after { content: ""; display: block; width: 2px; height: 100%; margin: 0 auto; background: transparent; transition: background var(--dur-snap) var(--ease); }
3083
+ .ws-resizer:hover::after, .ws-resizer:focus-visible::after { background: var(--accent); }
3084
+ .ws-resizer:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
3085
+ .ws-resizer.ws-resizer-rail { grid-column: 1; }
3086
+ .ws-resizer.ws-resizer-sessions { grid-column: 2; }
3087
+ .ws-resizer.ws-resizer-pane { grid-column: 3; justify-self: end; }
3034
3088
  /* Ease the rail/pane collapse. Track COUNT stays stable on collapse (only a
3035
3089
  width var flips), so grid-template-columns is animatable; reduced-motion
3036
3090
  drops it to an instant swap. */
@@ -3110,7 +3164,7 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3110
3164
  /* Crumb band is the top chrome of the content column: a stable height so the
3111
3165
  top edge aligns with the rail head, and a left gutter matching .ws-main so
3112
3166
  the trail text is not flush against the rail border. */
3113
- .ws-crumb { flex: 0 0 auto; min-height: 48px; padding: 0 var(--space-4); display: flex; align-items: center; gap: var(--space-1); border-bottom: var(--bw-hair) solid var(--bg-3); }
3167
+ .ws-crumb { flex: 0 0 auto; min-height: 48px; padding: 0 var(--space-5); display: flex; align-items: center; gap: var(--space-1); border-bottom: var(--bw-hair) solid var(--bg-3); }
3114
3168
  .ws-crumb-main { flex: 1 1 auto; min-width: 0; }
3115
3169
  /* Content column gutter. Claude-Code-class calm: file grid / dashboard / event
3116
3170
  list / history get a generous, consistent inner gutter instead of butting
@@ -3145,6 +3199,11 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3145
3199
  trailing display:none silently kills every drawer affordance (shipped bug:
3146
3200
  the mobile drawers were dead because these lines used to sit last). */
3147
3201
  .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); }
3202
+ /* Desktop-only chrome toggle (sessions collapse): inverse of the mobile drawer-toggle. */
3203
+ .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); }
3204
+ .ws-desktop-toggle:hover { background: var(--bg-2); color: var(--fg); }
3205
+ .ws-desktop-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3206
+ @media (max-width: 900px) { .ws-desktop-toggle { display: none; } }
3148
3207
  .ws-scrim { display: none; }
3149
3208
 
3150
3209
  /* Responsive: the columns yield to the CONTENT in stages - the main column is