anentrypoint-design 0.0.211 → 0.0.213

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
@@ -450,7 +450,7 @@ body.canvas-host { background: transparent !important; }
450
450
  .ds-icon-btn-primary { background: var(--accent); color: var(--accent-fg); }
451
451
  .ds-icon-btn-primary:hover { background: var(--fg); color: var(--bg); }
452
452
  /* warn = destructive ACTION tone; flame stays exclusively error STATUS. */
453
- .ds-icon-btn-danger { background: var(--warn); color: var(--paper); }
453
+ .ds-icon-btn-danger { background: var(--warn); color: var(--on-color); }
454
454
  .ds-icon-btn-danger:hover { filter: brightness(1.1); }
455
455
  .ds-icon-btn:active { transform: translateY(1px); }
456
456
  .ds-icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@@ -472,10 +472,10 @@ body.canvas-host { background: transparent !important; }
472
472
  .ds-badge.tone-purple { background: var(--purple-tint); color: var(--purple-deep); }
473
473
  .ds-badge.tone-mascot { background: var(--mascot-tint); color: var(--ink); }
474
474
  .ds-badge.tone-sun { background: var(--sun); color: var(--ink); }
475
- .ds-badge.tone-flame { background: var(--flame); color: var(--paper); }
475
+ .ds-badge.tone-flame { background: var(--flame); color: var(--on-color); }
476
476
  .ds-badge.tone-live { background: var(--green-tint); color: var(--green-deep); }
477
477
  .ds-badge.tone-wip { background: var(--bg-3); color: var(--fg-2); }
478
- .ds-badge.tone-error { background: var(--flame); color: var(--paper); }
478
+ .ds-badge.tone-error { background: var(--flame); color: var(--on-color); }
479
479
  .ds-badge.tone-success { background: var(--green-tint); color: var(--green-deep); }
480
480
  .ds-badge.tone-neutral { background: var(--bg-3); color: var(--fg-2); }
481
481
 
@@ -492,14 +492,14 @@ body.canvas-host { background: transparent !important; }
492
492
  .chip.tone-purple { background: var(--purple-tint); color: var(--purple-deep); }
493
493
  .chip.tone-mascot { background: var(--mascot-tint); color: var(--ink); }
494
494
  .chip.tone-sun { background: var(--sun); color: var(--ink); }
495
- .chip.tone-flame { background: var(--flame); color: var(--paper); }
495
+ .chip.tone-flame { background: var(--flame); color: var(--on-color); }
496
496
  .chip.tone-live { background: var(--green-tint); color: var(--green-deep); }
497
497
  .chip.tone-wip { background: var(--bg-3); color: var(--fg-2); }
498
- .chip.tone-error { background: var(--flame); color: var(--paper); }
498
+ .chip.tone-error { background: var(--flame); color: var(--on-color); }
499
499
  .chip.tone-success { background: var(--green-tint); color: var(--green-deep); }
500
500
  .chip.tone-disabled { background: var(--bg-3); color: var(--fg-3); }
501
501
  .chip.tone-ok { background: var(--green-tint); color: var(--green-deep); }
502
- .chip.tone-miss { background: var(--flame); color: var(--paper); }
502
+ .chip.tone-miss { background: var(--flame); color: var(--on-color); }
503
503
  .chip.tone-neutral { background: var(--bg-3); color: var(--fg-2); }
504
504
 
505
505
  .glyph {
@@ -538,6 +538,8 @@ body.canvas-host { background: transparent !important; }
538
538
  font-family: var(--ff-mono); letter-spacing: 0;
539
539
  }
540
540
  .panel-body { padding: var(--space-2) var(--space-3) var(--space-3); }
541
+ .panel-body > * { margin: 0; }
542
+ .panel-body > * + * { margin-top: var(--space-3); }
541
543
  .panel.panel-wide .panel-body { padding: 0; }
542
544
 
543
545
  /* ============================================================
@@ -560,6 +562,21 @@ body.canvas-host { background: transparent !important; }
560
562
  transition: background var(--dur-snap) var(--ease);
561
563
  }
562
564
  .row + .row { margin-top: 2px; }
565
+ /* `detail` drops to its own full-width line. The row is a grid, so span every
566
+ track (grid-column 1/-1); flex-basis:100% covers the flex-row fallback. */
567
+ .ds-row-detail {
568
+ white-space: pre-wrap;
569
+ font-family: var(--ff-mono);
570
+ font-size: var(--fs-sm);
571
+ line-height: var(--lh-snug, 1.3);
572
+ margin-top: 8px;
573
+ padding: 10px 12px;
574
+ background: var(--bg);
575
+ border-radius: var(--r-1);
576
+ overflow-x: auto;
577
+ flex-basis: 100%;
578
+ grid-column: 1 / -1;
579
+ }
563
580
  .row::before {
564
581
  content: '';
565
582
  position: absolute; left: 7px; top: 0; bottom: 0; width: 3px;
@@ -943,8 +960,6 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
943
960
  .chat-msg:hover { padding: 4px 0; margin: 0; background: transparent; }
944
961
  .chat-composer { padding: 8px; gap: 6px; }
945
962
  .chat-composer textarea { padding: 10px 12px; font-size: var(--fs-sm); }
946
- .chat-composer .send,
947
- .chat-composer button { width: 40px; height: 40px; font-size: 16px; }
948
963
 
949
964
  /* KPI Cards */
950
965
  .kpi {
@@ -1131,12 +1146,14 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1131
1146
  .ds-file-listing { display: flex; flex-direction: column; gap: var(--space-2); min-height: 0; }
1132
1147
  /* The quick filter is a compact control, not a full-width form row - a giant
1133
1148
  input above the grid reads as a search page and costs fold height. */
1134
- .ds-file-filter { padding: 0 0 var(--space-1); display: flex; justify-content: flex-end; }
1149
+ /* The filter is now an inline item in the single .ds-file-controls toolbar row
1150
+ (the standalone right-aligned .ds-file-filter strip was removed). */
1135
1151
  .ds-file-filter-input {
1136
1152
  width: min(280px, 100%); padding: 6px 12px; font-size: var(--fs-sm);
1137
1153
  background: var(--bg); color: var(--fg);
1138
1154
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
1139
1155
  }
1156
+ .ds-file-controls .ds-file-filter-input { flex: 0 1 220px; }
1140
1157
  .ds-file-filter-input:focus-visible { outline: none; box-shadow: var(--focus-ring-inset); }
1141
1158
  .ds-file-sort { display: flex; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); }
1142
1159
  .ds-file-sort-btn {
@@ -1266,7 +1283,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1266
1283
  role=checkbox/aria-checked name+state. */
1267
1284
  .ds-check-box {
1268
1285
  width: 15px; height: 15px; box-sizing: border-box; flex: 0 0 auto; position: relative;
1269
- border: 1.5px solid var(--rule); border-radius: 4px;
1286
+ border: 1.5px solid var(--fg-3); border-radius: 4px;
1270
1287
  transition: background var(--dur-snap) var(--ease), border-color var(--dur-snap) var(--ease);
1271
1288
  }
1272
1289
  .is-marked > .ds-check-box,
@@ -1278,14 +1295,14 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1278
1295
  }
1279
1296
  [aria-checked="mixed"] > .ds-check-box { background: var(--accent); border-color: var(--accent); }
1280
1297
  [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);
1298
+ content: ""; position: absolute; left: 3px; right: 3px; top: 6px; height: 2px; background: var(--bg); border-radius: 1px;
1282
1299
  }
1283
1300
 
1284
1301
  .ds-file-check {
1285
1302
  display: inline-flex; align-items: center; justify-content: center;
1286
1303
  min-width: 28px; height: 28px; padding: 0 4px;
1287
1304
  background: transparent; border: 0; border-radius: var(--r-1);
1288
- font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3);
1305
+ color: var(--fg-3);
1289
1306
  cursor: pointer;
1290
1307
  transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
1291
1308
  }
@@ -1331,9 +1348,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1331
1348
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
1332
1349
  }
1333
1350
  .ds-density-btn {
1334
- font-size: var(--fs-tiny); color: var(--fg-2);
1351
+ display: inline-flex; align-items: center; justify-content: center;
1352
+ width: 28px; height: 28px; color: var(--fg-2);
1335
1353
  background: none; border: none; cursor: pointer;
1336
- padding: 2px var(--space-2); border-radius: calc(var(--r-1) - 2px);
1354
+ padding: 0; border-radius: calc(var(--r-1) - 2px);
1337
1355
  transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
1338
1356
  }
1339
1357
  .ds-density-btn:hover { color: var(--fg); }
@@ -1376,6 +1394,16 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1376
1394
  }
1377
1395
  .ds-file-cell-media .ds-file-icon { width: 34px; height: 34px; font-size: 24px; }
1378
1396
  .ds-file-cell-thumb { width: 100%; height: 100%; object-fit: cover; }
1397
+ /* Per-type icon tints on thumb tiles so the grid keeps the colour-coding the
1398
+ list rows already carry (mirrors .ds-file-row[data-file-type] .ds-file-icon). */
1399
+ .ds-file-cell[data-file-type="dir"] .ds-file-icon { color: var(--accent); }
1400
+ .ds-file-cell[data-file-type="image"] .ds-file-icon { color: var(--mascot); }
1401
+ .ds-file-cell[data-file-type="video"] .ds-file-icon { color: var(--purple-2); }
1402
+ .ds-file-cell[data-file-type="audio"] .ds-file-icon { color: var(--sky); }
1403
+ .ds-file-cell[data-file-type="code"] .ds-file-icon { color: var(--green-2); }
1404
+ .ds-file-cell[data-file-type="archive"] .ds-file-icon { color: var(--flame); }
1405
+ .ds-file-cell[data-file-type="document"] .ds-file-icon { color: var(--amber); }
1406
+ .ds-file-cell[data-file-type="symlink"] .ds-file-icon { color: var(--purple); }
1379
1407
  .ds-file-cell-name {
1380
1408
  font-size: var(--fs-tiny); text-align: left;
1381
1409
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
@@ -1386,13 +1414,6 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1386
1414
  background: color-mix(in oklab, var(--bg) 78%, transparent);
1387
1415
  }
1388
1416
 
1389
- /* Card mode — opt-in via data-columns; switches the list to a grid. */
1390
- .ds-file-grid[data-columns] { display: grid; gap: var(--space-3); }
1391
- .ds-file-grid[data-columns="1"] { grid-template-columns: 1fr; }
1392
- .ds-file-grid[data-columns="2"] { grid-template-columns: repeat(2, 1fr); }
1393
- .ds-file-grid[data-columns="3"] { grid-template-columns: repeat(3, 1fr); }
1394
- .ds-file-grid[data-columns="4"] { grid-template-columns: repeat(4, 1fr); }
1395
-
1396
1417
  /* ============================================================
1397
1418
  File browser surface — stage, toolbar, breadcrumb, dropzone,
1398
1419
  upload progress, empty state, modals, preview. Authored for
@@ -1716,21 +1737,12 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1716
1737
  }
1717
1738
  .ds-filter-input:focus-visible { outline: none; box-shadow: var(--focus-ring-inset); }
1718
1739
 
1719
- /* Loading skeleton placeholder rows while a directory loads. */
1720
- .ds-file-grid-loading { display: flex; flex-direction: column; gap: 4px; }
1721
- .ds-file-skeleton {
1722
- height: 48px; border-radius: var(--r-2);
1723
- background: linear-gradient(90deg,
1724
- var(--bg) 0%, var(--bg-2) 50%, var(--bg) 100%);
1725
- background-size: 200% 100%;
1726
- }
1727
- @media (prefers-reduced-motion: no-preference) {
1728
- .ds-file-skeleton { animation: ds-skeleton-shimmer 1.2s var(--ease) infinite; }
1729
- }
1730
- @keyframes ds-skeleton-shimmer {
1731
- 0% { background-position: 200% 0; }
1732
- 100% { background-position: -200% 0; }
1733
- }
1740
+ /* Loading skeleton: FileSkeleton renders `.ds-file-grid.ds-file-skeleton` with
1741
+ `.ds-file-row.ds-file-row-skeleton` rows whose inner `.ds-skel` children shimmer
1742
+ (via .ds-skel::after). The container therefore inherits the .ds-file-grid layout
1743
+ and must NOT be a single 48px gradient bar (that collapsed every row and double-
1744
+ shimmered). The dead .ds-file-grid-loading rule + unused ds-skeleton-shimmer
1745
+ keyframe were removed; only the inner .ds-skel children animate. */
1734
1746
 
1735
1747
  /* Drag-to-move drop target highlight on a directory row. */
1736
1748
  .ds-file-row.ds-drop-target {
@@ -1788,6 +1800,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1788
1800
  transition: color var(--dur-base) var(--ease), background var(--dur-base) var(--ease);
1789
1801
  }
1790
1802
  .ds-segmented .ds-seg-btn:hover { color: var(--fg); }
1803
+ .ds-segmented .ds-seg-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
1791
1804
  .ds-segmented .ds-seg-btn.is-on {
1792
1805
  background: var(--bg); color: var(--fg);
1793
1806
  box-shadow: inset 0 0 0 var(--bw-hair, 1px) var(--rule);
@@ -1935,10 +1948,27 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1935
1948
  color: color-mix(in oklab, currentColor 75%, transparent); font-style: italic;
1936
1949
  }
1937
1950
  .chat-bubble.chat-md pre {
1938
- background: color-mix(in oklab, var(--fg) 8%, transparent);
1939
- padding: 10px 12px; border-radius: 6px; overflow-x: auto;
1940
- font-family: var(--ff-mono); font-size: 0.9em; margin: 8px 0;
1941
- }
1951
+ background: var(--bg);
1952
+ border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
1953
+ padding: 12px 16px; border-radius: var(--r-1); overflow-x: auto;
1954
+ font-family: var(--ff-mono); font-size: var(--fs-xs); line-height: 1.55;
1955
+ color: var(--fg); margin: 8px 0;
1956
+ }
1957
+ /* When injectCodeCopy has wrapped the fence (.chat-code-block), reserve room
1958
+ for the absolute .chat-code-lang tab. This selector outranks the bare
1959
+ .chat-code-block pre reservation in chat.css, which the 2-class md pre
1960
+ selector above would otherwise override. */
1961
+ .chat-code-block .chat-bubble.chat-md pre,
1962
+ .chat-bubble.chat-md .chat-code-block pre {
1963
+ padding-top: calc(var(--space-3) + 4px);
1964
+ }
1965
+ /* Markdown tables + horizontal rules: agents routinely emit them, but they were
1966
+ unstyled (bare unspaced cells, vanished rules). */
1967
+ .chat-bubble.chat-md table { border-collapse: collapse; width: auto; max-width: 100%; margin: 8px 0; font-size: .95em; display: block; overflow-x: auto; }
1968
+ .chat-bubble.chat-md th,
1969
+ .chat-bubble.chat-md td { border: var(--bw-hair) solid var(--rule); padding: 4px 10px; text-align: left; }
1970
+ .chat-bubble.chat-md th { background: color-mix(in oklab, var(--fg) 5%, transparent); font-weight: 600; }
1971
+ .chat-bubble.chat-md hr { border: 0; border-top: var(--bw-hair) solid var(--rule); margin: 12px 0; }
1942
1972
 
1943
1973
  .chat-msg .chat-bubble.chat-code,
1944
1974
  .chat-msg.you .chat-bubble.chat-code,
@@ -2166,6 +2196,14 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2166
2196
  border-color: var(--accent);
2167
2197
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent) 18%, transparent);
2168
2198
  }
2199
+ .chat-composer.is-error,
2200
+ .chat-composer:has(textarea[aria-invalid="true"]) {
2201
+ border-color: var(--flame);
2202
+ }
2203
+ .chat-composer.is-error:focus-within,
2204
+ .chat-composer:has(textarea[aria-invalid="true"]):focus-within {
2205
+ box-shadow: 0 0 0 2px color-mix(in oklab, var(--flame) 22%, transparent);
2206
+ }
2169
2207
  .chat-composer textarea {
2170
2208
  flex: 1; min-width: 0; padding: 8px 4px;
2171
2209
  background: none; color: var(--fg);
@@ -2181,7 +2219,7 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2181
2219
  .chat-composer textarea::placeholder { color: var(--fg-3); }
2182
2220
  .chat-composer textarea:focus { background: none; border: none; box-shadow: none; outline: none; }
2183
2221
  .chat-composer .send {
2184
- width: 36px; height: 36px; border-radius: var(--r-1);
2222
+ border-radius: var(--r-1);
2185
2223
  background: var(--accent); color: var(--accent-fg);
2186
2224
  border: 0; cursor: pointer;
2187
2225
  display: inline-flex; align-items: center; justify-content: center;
@@ -2189,10 +2227,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2189
2227
  transition: background var(--dur-snap, .15s) var(--ease, ease);
2190
2228
  }
2191
2229
  .chat-composer .send:disabled { opacity: .5; cursor: not-allowed; }
2192
- /* Ghost icon buttons in the toolbar (attach / emoji / more) NOT the round
2193
- accent send button. */
2230
+ /* Ghost icon buttons in the toolbar (attach / emoji / more). Size + radius are
2231
+ owned by .chat-composer-toolbar .composer-btn in chat.css (32px / --r-1,
2232
+ 44px coarse); this base rule keeps only the shared appearance. */
2194
2233
  .composer-btn {
2195
- width: 40px; height: 40px; border-radius: 50%;
2196
2234
  background: transparent; color: var(--fg-3);
2197
2235
  border: 0; cursor: pointer;
2198
2236
  display: inline-flex; align-items: center; justify-content: center;
@@ -2288,9 +2326,6 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2288
2326
  @media (max-height: 500px) and (orientation: landscape) {
2289
2327
  .chat-composer { padding: 6px 0; }
2290
2328
  .chat-composer textarea { min-height: 44px; max-height: 120px; }
2291
- /* Keep the send button at the 44x44 minimum tap target even in the
2292
- space-constrained landscape layout. */
2293
- .chat-composer .send, .chat-composer button { width: 44px; height: 44px; font-size: 14px; }
2294
2329
  }
2295
2330
 
2296
2331
  /* ============================================================
@@ -2433,7 +2468,6 @@ input[type="checkbox"], input[type="radio"] {
2433
2468
  position: absolute;
2434
2469
  left: 0; right: 0; height: 2px;
2435
2470
  background: var(--accent);
2436
- animation: pulse-line 0.6s ease-in-out infinite;
2437
2471
  }
2438
2472
  .list-item.drag-before::before { top: -2px; }
2439
2473
  .list-item.drag-after::after { bottom: -2px; }
@@ -2442,6 +2476,10 @@ input[type="checkbox"], input[type="radio"] {
2442
2476
  0%, 100% { opacity: 0.3; }
2443
2477
  50% { opacity: 1; }
2444
2478
  }
2479
+ @media (prefers-reduced-motion: no-preference) {
2480
+ .list-item.drag-before::before,
2481
+ .list-item.drag-after::after { animation: pulse-line 0.6s ease-in-out infinite; }
2482
+ }
2445
2483
 
2446
2484
  /* ------------------------------------------------------------
2447
2485
  Context Menu Styles
@@ -2456,7 +2494,6 @@ input[type="checkbox"], input[type="radio"] {
2456
2494
  min-width: 160px;
2457
2495
  z-index: calc(var(--z-overlay, 1000) + 1);
2458
2496
  padding: 4px 0;
2459
- animation: context-menu-in 0.15s ease-out;
2460
2497
  }
2461
2498
 
2462
2499
  @keyframes context-menu-in {
@@ -2469,6 +2506,9 @@ input[type="checkbox"], input[type="radio"] {
2469
2506
  transform: scale(1) translateY(0);
2470
2507
  }
2471
2508
  }
2509
+ @media (prefers-reduced-motion: no-preference) {
2510
+ .ds-context-menu { animation: context-menu-in 0.15s ease-out; }
2511
+ }
2472
2512
 
2473
2513
  .ds-context-menu-item {
2474
2514
  display: flex; align-items: center; gap: 10px;
@@ -2725,6 +2765,10 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2725
2765
  padding: var(--space-8) var(--space-4);
2726
2766
  text-align: center; color: var(--fg-3);
2727
2767
  }
2768
+ .empty-state--inline {
2769
+ flex-direction: row; align-items: center; gap: var(--space-2);
2770
+ padding: var(--space-2) 0; text-align: left;
2771
+ }
2728
2772
  .empty-state-icon {
2729
2773
  font-size: 48px; opacity: 0.4;
2730
2774
  }
@@ -2769,7 +2813,6 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2769
2813
  padding: var(--space-3) var(--space-4);
2770
2814
  max-width: 320px;
2771
2815
  box-shadow: 0 10px 40px color-mix(in oklab, var(--fg) 20%, transparent);
2772
- animation: toast-slide-in 0.3s ease-out;
2773
2816
  z-index: calc(var(--z-overlay, 1000) + 10);
2774
2817
  }
2775
2818
 
@@ -2783,6 +2826,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2783
2826
  transform: translateX(0);
2784
2827
  }
2785
2828
  }
2829
+ @media (prefers-reduced-motion: no-preference) {
2830
+ .toast { animation: toast-slide-in 0.3s ease-out; }
2831
+ }
2786
2832
 
2787
2833
  .toast.error { border-color: var(--warn); }
2788
2834
  .toast.success { border-color: var(--green-2); }
@@ -2809,11 +2855,13 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2809
2855
  height: 4px;
2810
2856
  border-radius: 50%;
2811
2857
  background: var(--accent);
2812
- animation: ds-bounce 1.4s infinite ease-in-out;
2813
2858
  }
2814
- .ds-spinner span:nth-child(1) { animation-delay: 0s; }
2815
- .ds-spinner span:nth-child(2) { animation-delay: 0.18s; }
2816
- .ds-spinner span:nth-child(3) { animation-delay: 0.36s; }
2859
+ @media (prefers-reduced-motion: no-preference) {
2860
+ .ds-spinner span { animation: ds-bounce 1.4s infinite ease-in-out; }
2861
+ .ds-spinner span:nth-child(1) { animation-delay: 0s; }
2862
+ .ds-spinner span:nth-child(2) { animation-delay: 0.18s; }
2863
+ .ds-spinner span:nth-child(3) { animation-delay: 0.36s; }
2864
+ }
2817
2865
 
2818
2866
  .ds-spinner-lg { height: 24px; gap: 6px; }
2819
2867
  .ds-spinner-lg span { width: 6px; height: 6px; }
@@ -3085,6 +3133,22 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3085
3133
  .ws-resizer.ws-resizer-rail { grid-column: 1; }
3086
3134
  .ws-resizer.ws-resizer-sessions { grid-column: 2; }
3087
3135
  .ws-resizer.ws-resizer-pane { grid-column: 3; justify-self: end; }
3136
+ /* A resizer must vanish once its TRACK is removed by the staging media blocks,
3137
+ else dragging it writes a --ws-*-w var that no longer affects the now-fixed
3138
+ drawer (a dead handle). Mirror the 1480 / 1100 / 900 staging exactly. */
3139
+ @media (max-width: 1480px) { .ws-resizer.ws-resizer-pane { display: none; } }
3140
+ @media (max-width: 1100px) { .ws-resizer.ws-resizer-sessions { display: none; } }
3141
+ @media (max-width: 900px) { .ws-resizer { display: none; } }
3142
+ /* A resizer must also vanish once its TRACK is desktop-collapsed: a 0px (pane/
3143
+ sessions) or 60px icon-only (rail) track has no width to drag, and a drag would
3144
+ write an INLINE --ws-*-w that overrides the collapse var (inline wins), fighting
3145
+ the collapse state. Mirror the breakpoint guards for the collapse classes. */
3146
+ .ws-rail-collapsed .ws-resizer-rail,
3147
+ .ws-sessions-collapsed .ws-resizer-sessions,
3148
+ .ws-pane-collapsed .ws-resizer-pane { display: none; }
3149
+ /* Coarse-pointer hit target for hybrid touch laptops above the drawer breakpoint
3150
+ (the 8px sliver is un-grabbable by touch). */
3151
+ @media (pointer: coarse) { .ws-resizer { width: 16px; margin-right: -8px; } }
3088
3152
  /* Ease the rail/pane collapse. Track COUNT stays stable on collapse (only a
3089
3153
  width var flips), so grid-template-columns is animatable; reduced-motion
3090
3154
  drops it to an instant swap. */
@@ -3182,16 +3246,10 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3182
3246
  overflow: hidden; transition: width var(--dur-base) var(--ease);
3183
3247
  }
3184
3248
  .ws-pane-collapsed .ws-pane { width: 0; border-left: none; }
3185
- .ws-pane-collapsed .ws-pane > :not(.ws-pane-toggle) { display: none; }
3186
- .ws-pane-toggle {
3187
- position: absolute; top: var(--space-2); left: calc(-1 * var(--space-5));
3188
- width: 28px; height: 28px;
3189
- display: inline-flex; align-items: center; justify-content: center;
3190
- background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); color: var(--fg-2);
3191
- border-radius: var(--r-1); cursor: pointer; z-index: 2;
3249
+ .ws-pane-collapsed .ws-pane > * { display: none; }
3250
+ @media (pointer: coarse) {
3251
+ .ws-rail-toggle { width: 44px; height: 44px; }
3192
3252
  }
3193
- .ws-pane-toggle:hover { background: var(--bg-3); color: var(--fg); }
3194
- .ws-pane-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3195
3253
 
3196
3254
  /* Drawer toggles and the scrim are hidden by default and revealed by the staged
3197
3255
  media blocks BELOW - these base rules must precede those blocks in source
@@ -3204,6 +3262,10 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3204
3262
  .ws-desktop-toggle:hover { background: var(--bg-2); color: var(--fg); }
3205
3263
  .ws-desktop-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3206
3264
  @media (max-width: 900px) { .ws-desktop-toggle { display: none; } }
3265
+ /* The pane collapse toggle is meaningless once the pane TRACK is dropped (the
3266
+ pane becomes a mobile overlay drawer at <=1480px, reached via its own
3267
+ drawer-toggle), so hide this crumb control past that breakpoint. */
3268
+ @media (max-width: 1480px) { .ws-pane-toggle { display: none; } }
3207
3269
  .ws-scrim { display: none; }
3208
3270
 
3209
3271
  /* Responsive: the columns yield to the CONTENT in stages - the main column is
@@ -3240,9 +3302,7 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3240
3302
  }
3241
3303
  .ws-shell.ws-pane-open .ws-pane { transform: translateX(0); width: min(340px, 85vw); }
3242
3304
  .ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane { border-left: var(--bw-hair) solid var(--bg-3); }
3243
- .ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane > :not(.ws-pane-toggle) { display: revert; }
3244
- /* The desktop collapse chevron is meaningless in drawer mode. */
3245
- .ws-pane-toggle { display: none; }
3305
+ .ws-shell.ws-pane-open.ws-pane-collapsed .ws-pane > * { display: revert; }
3246
3306
  .ws-pane-drawer-toggle { display: inline-flex; }
3247
3307
  /* Scrim is always present from this stage down so it FADES with the drawer
3248
3308
  instead of hard-appearing; pointer-events gate keeps it inert while closed. */