anentrypoint-design 0.0.379 → 0.0.381

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
@@ -22,3 +22,19 @@
22
22
  @import url('./src/css/app-shell/row-print.css');
23
23
  @import url('./src/css/app-shell/data-density.css');
24
24
  @import url('./src/css/app-shell/kits-appended.css');
25
+ /* The four below were bundled into dist by the appShellSplitFiles list in
26
+ scripts/build.mjs but were never imported here, so the two delivery paths
27
+ disagreed: the dist bundle carried their rules while every consumer that
28
+ links this barrel directly -- the preview pages and the per-kit index pages
29
+ -- rendered those components unstyled. 113 class names across 471 lines,
30
+ used by the skills-config, plugins-config, models-config and git-status
31
+ components under src/components/. Importing them here makes the barrel the
32
+ complete set again, which is the invariant the header comment above already
33
+ claims. scripts/lint-tokens.mjs now enforces that every sheet in
34
+ src/css/app-shell/ is reachable from this file, so the set cannot silently
35
+ diverge again. Order matches appShellSplitFiles exactly; the two must stay
36
+ identical or a page cascades differently depending on which path loaded it. */
37
+ @import url('./src/css/app-shell/git-status.css');
38
+ @import url('./src/css/app-shell/plugins-config.css');
39
+ @import url('./src/css/app-shell/models-config.css');
40
+ @import url('./src/css/app-shell/skills-config.css');
package/chat.css CHANGED
@@ -30,8 +30,12 @@
30
30
  .agentchat-controls .ds-select { min-width: 130px; max-width: 240px; }
31
31
  /* One shared control metric for the most-seen chrome row (mirrors the
32
32
  .ds-dash-toolbar precedent): selects, buttons, export acts all 32px / r-1. */
33
- .agentchat-controls .ds-select { min-height: 32px; padding: 4px 28px 4px 10px; font-size: var(--fs-sm); border-radius: var(--r-1); }
34
- .agentchat-controls .btn, .agentchat-controls .btn-primary { padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500; }
33
+ /* The 28px right pad is OFF-SCALE ON PURPOSE: it is not rhythm but clearance
34
+ for the native select's dropdown arrow, which the UA draws at a fixed inset.
35
+ Snapping to --space-5 (32px) or --space-4 (24px) either wastes a column of
36
+ text width or lets long option labels run under the arrow. */
37
+ .agentchat-controls .ds-select { min-height: 32px; padding: var(--space-1) 28px var(--space-1) var(--space-2-5); font-size: var(--fs-sm); border-radius: var(--r-1); }
38
+ .agentchat-controls .btn, .agentchat-controls .btn-primary { padding: var(--space-1-5) var(--space-2-75); min-height: 32px; border-radius: var(--r-1); font-weight: 500; }
35
39
  @media (pointer: coarse) {
36
40
  .agentchat-controls .ds-select, .agentchat-controls .btn, .agentchat-controls .btn-primary { min-height: 44px; }
37
41
  }
@@ -51,6 +55,12 @@
51
55
  .agentchat-controls [role="combobox"] { flex-basis: 100%; }
52
56
  }
53
57
 
58
+ /* The .4em/.5em gaps on this status line, .agentchat-head below, and the
59
+ narrow-viewport .agentchat-controls override are em-based ON PURPOSE, not
60
+ un-migrated literals: each is the gap between a label and its own inline
61
+ text/disc, so it must track that element's font-size (these rows are scaled
62
+ by font-size alone at narrow widths). A --space-* px rung would hold the gap
63
+ fixed while the type around it shrank. */
54
64
  .agentchat-status {
55
65
  display: inline-flex;
56
66
  align-items: center;
@@ -101,7 +111,7 @@
101
111
  border: 1px solid var(--rule);
102
112
  color: inherit;
103
113
  border-radius: var(--r-1);
104
- padding: 2px 8px;
114
+ padding: var(--space-hair) var(--space-2);
105
115
  cursor: pointer;
106
116
  font: inherit;
107
117
  }
@@ -114,7 +124,7 @@
114
124
  border: var(--bw-hair) solid var(--rule);
115
125
  color: var(--fg);
116
126
  border-radius: var(--r-1);
117
- padding: 4px 8px;
127
+ padding: var(--space-1) var(--space-2);
118
128
  font: inherit;
119
129
  }
120
130
  .agentchat-cwd-input:focus-visible { outline: none; box-shadow: var(--focus-ring-inset); }
@@ -127,12 +137,12 @@
127
137
  .agentchat-cwd-editing { flex-direction: column; align-items: stretch; }
128
138
  .agentchat-cwd-row { display: flex; align-items: center; gap: var(--space-2, 8px); flex-wrap: wrap; }
129
139
  .agentchat-cwd-roots, .agentchat-cwd-recent {
130
- display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
140
+ display: flex; align-items: center; gap: var(--space-1-75); flex-wrap: wrap;
131
141
  }
132
142
  .agentchat-cwd-recent-label { font-size: var(--fs-tiny); color: var(--fg-3); }
133
143
  .agentchat-cwd-chip {
134
144
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
135
- border-radius: var(--r-pill); padding: 3px 10px; font: inherit; font-size: var(--fs-tiny);
145
+ border-radius: var(--r-pill); padding: var(--space-half) var(--space-2-5); font: inherit; font-size: var(--fs-tiny);
136
146
  cursor: pointer;
137
147
  }
138
148
  .agentchat-cwd-chip:hover { border-color: var(--accent); color: var(--fg); }
@@ -140,17 +150,17 @@
140
150
  .agentchat-cwd-browse {
141
151
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
142
152
  padding: var(--space-2, 8px); background: var(--bg-2);
143
- display: flex; flex-direction: column; gap: 6px;
153
+ display: flex; flex-direction: column; gap: var(--space-1-75);
144
154
  max-height: 220px;
145
155
  }
146
156
  .agentchat-cwd-browse-list { overflow-y: auto; display: flex; flex-direction: column; max-height: 160px; }
147
157
  .agentchat-cwd-browse-item {
148
158
  background: none; border: none; color: var(--fg-2); text-align: left;
149
- padding: 6px 8px; border-radius: var(--r-1); font: inherit; font-size: var(--fs-tiny);
159
+ padding: var(--space-1-75) var(--space-2); border-radius: var(--r-1); font: inherit; font-size: var(--fs-tiny);
150
160
  cursor: pointer;
151
161
  }
152
162
  .agentchat-cwd-browse-item:hover, .agentchat-cwd-browse-item:focus-visible { background: var(--bg-3, var(--bg)); color: var(--fg); }
153
- .agentchat-cwd-browse-loading, .agentchat-cwd-browse-empty { padding: 6px 8px; font-size: var(--fs-tiny); color: var(--fg-3); }
163
+ .agentchat-cwd-browse-loading, .agentchat-cwd-browse-empty { padding: var(--space-1-75) var(--space-2); font-size: var(--fs-tiny); color: var(--fg-3); }
154
164
 
155
165
  /* head + thread */
156
166
  .agentchat-head {
@@ -171,14 +181,14 @@
171
181
  .agentchat-side-panel { display: flex; flex-direction: column; height: 100%; min-height: 0; border-left: var(--bw-hair) solid var(--bg-3); }
172
182
  .agentchat-side-panel-head {
173
183
  display: flex; align-items: center; justify-content: space-between;
174
- padding: var(--space-2, 8px) var(--space-3, 12px); border-bottom: var(--bw-hair) solid var(--bg-3);
184
+ padding: var(--space-2, 8px) var(--space-3, 16px); border-bottom: var(--bw-hair) solid var(--bg-3);
175
185
  flex: 0 0 auto;
176
186
  }
177
187
  .agentchat-side-panel-title { font-size: var(--fs-tiny); font-weight: 600; color: var(--fg-2); text-transform: uppercase; letter-spacing: var(--tr-label); }
178
188
  .agentchat-side-panel-close {
179
189
  display: inline-flex; align-items: center; justify-content: center;
180
190
  background: none; border: none; color: var(--fg-3); cursor: pointer;
181
- padding: 4px; border-radius: var(--r-1);
191
+ padding: var(--space-1); border-radius: var(--r-1);
182
192
  }
183
193
  .agentchat-side-panel-close:hover { background: var(--bg-2); color: var(--fg); }
184
194
  .agentchat-side-panel-close:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
@@ -202,8 +212,11 @@
202
212
 
203
213
  /* Jump-to-latest: hidden until the thread scroll listener adds .show. */
204
214
  .agentchat-jump {
205
- position: absolute; right: 16px; bottom: 12px; z-index: 3;
215
+ position: absolute; right: 16px; bottom: 12px; z-index: var(--z-raised);
206
216
  display: none; align-items: center; gap: .35em;
217
+ /* em, not --space-*: this pill must scale with its own --fs-tiny text so the
218
+ capsule stays proportional when a host overrides the chat font size. A px
219
+ rung would fix the padding while the label grew/shrank inside it. */
207
220
  padding: .4em .8em; font: inherit; font-size: var(--fs-tiny); cursor: pointer;
208
221
  border-radius: var(--r-pill); border: var(--bw-hair) solid var(--rule);
209
222
  background: var(--bg-2); color: var(--fg-2, var(--fg));
@@ -215,6 +228,9 @@
215
228
 
216
229
  /* Streaming caret: a thin blinking bar at the live edge of an assistant turn. */
217
230
  .chat-stream-caret {
231
+ /* margin-left:1px is OFF-SCALE ON PURPOSE — a hairline optical nudge that
232
+ separates the caret bar from the last glyph without reading as a space
233
+ character. --space-hair (2px) is already wide enough to look like one. */
218
234
  display: inline-block; width: 2px; height: 1.05em; margin-left: 1px;
219
235
  vertical-align: text-bottom; background: var(--accent, var(--fg));
220
236
  animation: chat-caret-blink 1s step-end infinite;
@@ -223,11 +239,11 @@
223
239
  @media (prefers-reduced-motion: reduce) { .chat-stream-caret { animation: none; opacity: .8; } }
224
240
 
225
241
  /* Per-message hover-revealed action row (copy / retry / edit). */
226
- .chat-msg-actions { display: flex; gap: 2px; margin-top: 3px; opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease); }
242
+ .chat-msg-actions { display: flex; gap: var(--space-hair); margin-top: var(--space-half); opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease); }
227
243
  .chat-msg:hover .chat-msg-actions, .chat-msg:focus-within .chat-msg-actions { opacity: 1; }
228
244
  .chat-msg-action {
229
- display: inline-flex; align-items: center; justify-content: center; gap: 4px;
230
- min-width: 26px; height: 26px; padding: 0 6px; cursor: pointer;
245
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1);
246
+ min-width: 26px; height: 26px; padding: 0 var(--space-1-75); cursor: pointer;
231
247
  border: none; border-radius: var(--r-1, 4px); background: none; color: var(--fg-3);
232
248
  font-family: var(--ff-body); font-size: var(--fs-tiny);
233
249
  }
@@ -236,7 +252,12 @@
236
252
  .chat-msg-action:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: 1px; opacity: 1; }
237
253
  .chat-msg-action.is-copied { color: var(--accent-ink); opacity: 1; }
238
254
 
239
- /* Empty state: a fresh thread is an invitation, not a void. */
255
+ /* Empty state: a fresh thread is an invitation, not a void.
256
+ The em-based gap/padding through this block and the suggestion chips below
257
+ are OFF the --space-* px scale ON PURPOSE: the empty state is typeset copy
258
+ whose rhythm must track its own font-size (hosts scale this panel down on
259
+ narrow viewports via font-size alone). Fixed px rungs here would decouple
260
+ the chip padding from the label and break the capsule proportions. */
240
261
  .agentchat-empty {
241
262
  margin: auto;
242
263
  display: flex;
@@ -300,7 +321,7 @@
300
321
  font-family: var(--ff-mono); font-size: var(--fs-sm); color: var(--fg-2, var(--fg));
301
322
  }
302
323
  .agentchat-install-copy {
303
- flex: 0 0 auto; cursor: pointer; padding: 2px 8px; min-height: 24px;
324
+ flex: 0 0 auto; cursor: pointer; padding: var(--space-hair) var(--space-2); min-height: 24px;
304
325
  border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
305
326
  background: none; color: var(--fg-3);
306
327
  font-family: var(--ff-body); font-size: var(--fs-tiny);
@@ -311,7 +332,7 @@
311
332
 
312
333
  /* Host-supplied transcript export actions riding the controls row. */
313
334
  .agentchat-export-act {
314
- cursor: pointer; padding: 4px 10px; min-height: 32px;
335
+ cursor: pointer; padding: var(--space-1) var(--space-2-5); min-height: 32px;
315
336
  border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
316
337
  background: none; color: var(--fg-3);
317
338
  font-family: var(--ff-body); font-size: var(--fs-tiny);
@@ -319,7 +340,10 @@
319
340
  .agentchat-export-act:hover { background: var(--bg-2); color: var(--fg); }
320
341
  .agentchat-export-act:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: 1px; }
321
342
 
322
- /* "working" tail: a long silent tool call shouldn't read as frozen. */
343
+ /* "working" tail: a long silent tool call shouldn't read as frozen.
344
+ em gap/padding here and on .chat-thinking below is deliberate — both tails
345
+ are inline status text sized off --fs-tiny, and their inset must shrink with
346
+ the type, not sit on a fixed px rung. */
323
347
  .agentchat-working {
324
348
  display: flex;
325
349
  align-items: center;
@@ -331,7 +355,7 @@
331
355
  .agentchat-working-text { color: var(--fg-3); }
332
356
  /* Self-contained dots (chat-thinking-dots lives in a kit sheet not bundled
333
357
  into this DS distribution, so the agentchat tail draws its own). */
334
- .agentchat-working .chat-thinking-dots { display: inline-flex; gap: 3px; }
358
+ .agentchat-working .chat-thinking-dots { display: inline-flex; gap: var(--space-half); }
335
359
  .agentchat-working .chat-thinking-dots span {
336
360
  width: 5px; height: 5px; border-radius: 50%;
337
361
  background: var(--fg); opacity: .4;
@@ -352,7 +376,7 @@
352
376
  no muted tone. Reuse the agentchat-dot-bounce keyframe. */
353
377
  .chat-thinking { display: flex; align-items: center; gap: .5em; color: var(--fg-3); font-size: var(--fs-tiny); background: none; padding: .3em .2em; }
354
378
  .chat-thinking-text { color: var(--fg-3); }
355
- .chat-thinking-dots { display: inline-flex; gap: 3px; }
379
+ .chat-thinking-dots { display: inline-flex; gap: var(--space-half); }
356
380
  .chat-thinking-dots span {
357
381
  width: 5px; height: 5px; border-radius: 50%;
358
382
  background: var(--fg); opacity: .4;
@@ -453,7 +477,7 @@
453
477
  .ds-session-new:hover { background: var(--bg-2); color: var(--fg); }
454
478
  /* Rail filter uses the shared .ds-search-input primitive (provides bg/border/
455
479
  radius/focus-ring); only the rail layout + touch floor live here. */
456
- .ds-session-head .ds-search-input { order: 1; flex: 1 1 auto; min-width: 0; min-height: 36px; padding: 0 10px; }
480
+ .ds-session-head .ds-search-input { order: 1; flex: 1 1 auto; min-width: 0; min-height: 36px; padding: 0 var(--space-2-5); }
457
481
  .ds-session-new:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
458
482
  /* Touch floor (must FOLLOW the base rules - same specificity, order decides). */
459
483
  @media (pointer: coarse) {
@@ -462,7 +486,7 @@
462
486
  }
463
487
  .ds-session-list, .ds-session-groups { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-2); }
464
488
  .ds-session-loadmore {
465
- width: 100%; margin-top: var(--space-1); padding: 8px 12px;
489
+ width: 100%; margin-top: var(--space-1); padding: var(--space-2) var(--space-2-75);
466
490
  font-size: var(--fs-sm); font-family: inherit; color: var(--fg-3);
467
491
  background: none; border: var(--bw-hair) dashed var(--rule); border-radius: var(--r-1);
468
492
  cursor: pointer; text-align: center;
@@ -473,11 +497,11 @@
473
497
  /* Grouped rows (Today/Yesterday/...) lay out like the flat list; the section
474
498
  label sticks to the top of the scroll area for Claude-Desktop-style headers. */
475
499
  .ds-session-group { display: flex; flex-direction: column; }
476
- .ds-session-group-rows { display: flex; flex-direction: column; gap: 2px; }
477
- .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-label); padding: var(--space-2) var(--space-2) var(--space-1); }
500
+ .ds-session-group-rows { display: flex; flex-direction: column; gap: var(--space-hair); }
501
+ .ds-session-group-label { position: sticky; top: 0; z-index: var(--z-sticky); 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-label); padding: var(--space-2) var(--space-2) var(--space-1); }
478
502
  .ds-session-row {
479
503
  position: relative; display: flex; align-items: center; gap: var(--space-2);
480
- width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: 2px;
504
+ width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: var(--space-hair);
481
505
  background: transparent; border: none; border-radius: var(--r-1);
482
506
  cursor: pointer; text-align: left; color: var(--fg);
483
507
  }
@@ -492,7 +516,7 @@
492
516
  .ds-session-row.rail-green::before { background: var(--accent-ink); }
493
517
  .ds-session-row.rail-purple::before { background: var(--purple-2); }
494
518
  .ds-session-row.rail-flame::before { background: var(--flame); }
495
- .ds-session-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
519
+ .ds-session-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-hair); }
496
520
  .ds-session-title { font-size: var(--fs-sm); color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
497
521
  .ds-session-sub { font-size: var(--fs-tiny); color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
498
522
  .ds-session-meta { display: flex; align-items: center; gap: var(--space-2); flex: 0 0 auto; }
@@ -562,7 +586,7 @@
562
586
  it only goes loud while ARMED (the one-shot press-again confirm). */
563
587
  .ds-dash-header .btn, .ds-dash-header .btn-primary {
564
588
  margin-left: 0;
565
- padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
589
+ padding: var(--space-1-5) var(--space-2-75); min-height: 32px; border-radius: var(--r-1); font-weight: 500;
566
590
  }
567
591
  .ds-dash-header .btn-primary.danger {
568
592
  background: transparent; color: var(--warn);
@@ -583,7 +607,7 @@
583
607
  .ds-dash-status.is-error { color: var(--flame); }
584
608
  .ds-dash-agent { font-size: var(--fs-body); font-weight: 600; color: var(--fg); }
585
609
  .ds-dash-model { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3); margin-left: auto; }
586
- .ds-dash-meta { display: flex; flex-direction: column; gap: 2px; }
610
+ .ds-dash-meta { display: flex; flex-direction: column; gap: var(--space-hair); }
587
611
  .ds-dash-cwd { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
588
612
  .ds-dash-stat { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-2); }
589
613
  .ds-dash-stat-cost { color: var(--fg); font-weight: 600; }
@@ -614,7 +638,7 @@
614
638
  letter-spacing: var(--tr-caps); text-transform: uppercase;
615
639
  padding: 0 0 var(--space-2);
616
640
  }
617
- .ds-context-group .row + .row { margin-top: 2px; }
641
+ .ds-context-group .row + .row { margin-top: var(--space-hair); }
618
642
 
619
643
  /* ============================================================================
620
644
  Cohesion sweep (gui-cohesion.js): one-product polish across surfaces.
@@ -628,7 +652,7 @@
628
652
  .chat-code-copy {
629
653
  position: absolute; top: 6px; right: 6px;
630
654
  display: inline-flex; align-items: center; justify-content: center;
631
- min-width: 48px; min-height: 24px; padding: 2px 8px;
655
+ min-width: 48px; min-height: 24px; padding: var(--space-hair) var(--space-2);
632
656
  border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
633
657
  background: var(--bg-2); color: var(--fg-2); cursor: pointer;
634
658
  font-family: var(--ff-body); font-size: var(--fs-tiny);
@@ -671,7 +695,7 @@
671
695
 
672
696
  /* --- A5: composer context line (agent / model / cwd at point of typing). --- */
673
697
  .chat-composer-context {
674
- display: block; width: 100%; text-align: left; padding: 4px var(--space-3) 0;
698
+ display: block; width: 100%; text-align: left; padding: var(--space-1) var(--space-3) 0;
675
699
  background: none; border: none; cursor: default; color: var(--fg-3);
676
700
  font-family: var(--ff-mono); font-size: var(--fs-tiny);
677
701
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
@@ -713,11 +737,11 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
713
737
  height, never a stacked full-width form column. */
714
738
  .ds-dash-toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
715
739
  .ds-dash-toolbar .ds-search-input {
716
- width: 200px; min-height: 32px; padding: 5px 10px;
740
+ width: 200px; min-height: 32px; padding: var(--space-1-5) var(--space-2-5);
717
741
  font-size: var(--fs-sm); border-radius: var(--r-1);
718
742
  }
719
743
  .ds-dash-toolbar .ds-select, .ds-dash-toolbar select {
720
- min-height: 32px; padding: 4px 10px; font-size: var(--fs-sm);
744
+ min-height: 32px; padding: var(--space-1) var(--space-2-5); font-size: var(--fs-sm);
721
745
  width: auto; border-radius: var(--r-1);
722
746
  }
723
747
  .ds-dash-stream { font-size: var(--fs-tiny); color: var(--fg-3); }
@@ -726,7 +750,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
726
750
  .ds-dash-stream.is-connecting { color: var(--amber); }
727
751
  .ds-dash-header .spread { flex: 1; }
728
752
  .ds-dash-errors-toggle {
729
- padding: 4px 10px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
753
+ padding: var(--space-1) var(--space-2-5); min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
730
754
  border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2);
731
755
  cursor: pointer; font-family: var(--ff-body); font-size: var(--fs-tiny);
732
756
  }
@@ -769,14 +793,14 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
769
793
  .ds-preview-code-wrap { display: flex; flex-direction: column; min-height: 0; }
770
794
  .ds-preview-code-head { flex: 0 0 auto; }
771
795
  /* --- E2: prev/next stepper in preview head. --- */
772
- .ds-preview-step { display: inline-flex; gap: 2px; }
773
- .ds-preview-step .ds-file-act { min-width: 40px; padding: 0 6px; font-family: var(--ff-body); font-size: var(--fs-tiny); }
796
+ .ds-preview-step { display: inline-flex; gap: var(--space-hair); }
797
+ .ds-preview-step .ds-file-act { min-width: 40px; padding: 0 var(--space-1-75); font-family: var(--ff-body); font-size: var(--fs-tiny); }
774
798
 
775
799
  /* --- D1: file grid "show more" row. --- */
776
800
  .ds-file-more { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); justify-content: center; }
777
801
  .ds-file-more-count { font-size: var(--fs-tiny); color: var(--fg-3); }
778
802
  .ds-file-more-btn {
779
- padding: 4px 12px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
803
+ padding: var(--space-1) var(--space-2-75); min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
780
804
  border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2); cursor: pointer;
781
805
  font-family: var(--ff-body); font-size: var(--fs-tiny);
782
806
  }
@@ -785,9 +809,9 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
785
809
  .ds-file-row.is-locked { opacity: .6; }
786
810
 
787
811
  /* --- D4: roots picker segmented control. --- */
788
- .ds-roots-picker { display: inline-flex; gap: 2px; padding: 2px; background: var(--bg-2); border-radius: var(--r-1); }
812
+ .ds-roots-picker { display: inline-flex; gap: var(--space-hair); padding: var(--space-hair); background: var(--bg-2); border-radius: var(--r-1); }
789
813
  .ds-roots-tab {
790
- padding: 4px 10px; min-height: 32px; border: none; border-radius: var(--r-1);
814
+ padding: var(--space-1) var(--space-2-5); min-height: 32px; border: none; border-radius: var(--r-1);
791
815
  background: none; color: var(--fg-3); cursor: pointer;
792
816
  font-family: var(--ff-body); font-size: var(--fs-tiny);
793
817
  }
@@ -821,7 +845,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
821
845
  .ds-session-meta-label { color: var(--fg-3); }
822
846
  .ds-session-meta-value { font-family: var(--ff-mono); color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
823
847
  .ds-session-meta-copy, .ds-session-meta-action {
824
- padding: 2px 8px; min-height: 24px; cursor: pointer;
848
+ padding: var(--space-hair) var(--space-2); min-height: 24px; cursor: pointer;
825
849
  background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1);
826
850
  color: var(--fg-3); font-family: var(--ff-body); font-size: var(--fs-micro);
827
851
  }
@@ -840,7 +864,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
840
864
  can discover Enter-vs-Shift+Enter without having to focus it first;
841
865
  hidden under 420px to save rows. */
842
866
  .chat-composer-hint {
843
- display: block; width: 100%; order: 5; padding: 2px var(--space-1) 0;
867
+ display: block; width: 100%; order: 5; padding: var(--space-hair) var(--space-1) 0;
844
868
  font-size: var(--fs-micro); color: var(--fg-3);
845
869
  }
846
870
  @media (max-width: 420px) {
@@ -849,13 +873,13 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
849
873
 
850
874
  /* Transient composer note (paste/drop not supported), aria-live polite. */
851
875
  .chat-composer-note {
852
- padding: 4px var(--space-3); font-size: var(--fs-tiny); color: var(--fg-2);
876
+ padding: var(--space-1) var(--space-3); font-size: var(--fs-tiny); color: var(--fg-2);
853
877
  }
854
878
 
855
879
  /* Streaming elapsed-time counter: ticks m:ss while a turn is in flight.
856
880
  Tabular-nums so the digits don't jitter the layout every second. */
857
881
  .chat-composer-elapsed {
858
- order: 5; padding: 2px var(--space-1) 0;
882
+ order: 5; padding: var(--space-hair) var(--space-1) 0;
859
883
  font-size: var(--fs-micro); color: var(--fg-3);
860
884
  font-variant-numeric: tabular-nums; font-feature-settings: 'tnum';
861
885
  }
@@ -865,7 +889,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
865
889
  new chrome. */
866
890
  .chat-composer-detected-badge {
867
891
  display: flex; align-items: center; gap: var(--space-2, 8px);
868
- padding: 4px var(--space-3); font-size: var(--fs-tiny); color: var(--fg-2);
892
+ padding: var(--space-1) var(--space-3); font-size: var(--fs-tiny); color: var(--fg-2);
869
893
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule);
870
894
  border-radius: var(--r-1); width: 100%; order: -1;
871
895
  }
@@ -873,7 +897,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
873
897
  .chat-composer-detected-dismiss {
874
898
  flex: 0 0 auto; background: none; border: none; cursor: pointer;
875
899
  color: var(--fg-3); font: inherit; font-size: var(--fs-tiny);
876
- padding: 2px 6px; border-radius: var(--r-1);
900
+ padding: var(--space-hair) var(--space-1-75); border-radius: var(--r-1);
877
901
  }
878
902
  .chat-composer-detected-dismiss:hover { color: var(--fg); }
879
903
  .chat-composer-detected-dismiss:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
@@ -926,7 +950,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
926
950
  /* Out-of-band turn notices: neutral tone (NOT error red) — a stopped or
927
951
  incomplete turn must not read as a finished answer. */
928
952
  .chat-msg-notice {
929
- margin-top: var(--space-1); padding: 6px 10px;
953
+ margin-top: var(--space-1); padding: var(--space-1-75) var(--space-2-5);
930
954
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
931
955
  background: var(--bg-2); color: var(--fg-2); font-size: var(--fs-tiny);
932
956
  }
@@ -941,14 +965,14 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
941
965
  .chat-msg-retry-btn {
942
966
  border: var(--bw-hair) solid var(--danger); border-radius: var(--r-1);
943
967
  background: transparent; color: var(--danger-ink, var(--danger));
944
- font: inherit; font-size: var(--fs-tiny); padding: 2px 10px; cursor: pointer;
968
+ font: inherit; font-size: var(--fs-tiny); padding: var(--space-hair) var(--space-2-5); cursor: pointer;
945
969
  }
946
970
  .chat-msg-retry-btn:hover { background: var(--danger); color: var(--bg); }
947
971
  .chat-msg-retry-btn:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
948
972
 
949
973
  /* Tail-window streaming head ('streaming · N KB so far'). */
950
974
  .chat-stream-head {
951
- padding: 2px 0 6px; font-family: var(--ff-mono);
975
+ padding: var(--space-hair) 0 var(--space-1-75); font-family: var(--ff-mono);
952
976
  font-size: var(--fs-micro); color: var(--fg-3);
953
977
  }
954
978
 
@@ -959,7 +983,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
959
983
  }
960
984
  .agentchat-earlier-count { font-size: var(--fs-tiny); color: var(--fg-3); }
961
985
  .agentchat-earlier-btn {
962
- padding: 4px 12px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
986
+ padding: var(--space-1) var(--space-2-75); min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
963
987
  border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2); cursor: pointer;
964
988
  font-family: var(--ff-body); font-size: var(--fs-tiny);
965
989
  }
@@ -985,7 +1009,10 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
985
1009
 
986
1010
  /* External (observed, not owned) session card: no stop control exists. */
987
1011
  .ds-dash-external {
988
- padding: 1px 6px; border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-pill);
1012
+ /* 1px vertical is OFF-SCALE ON PURPOSE — a --fs-micro uppercase pill whose
1013
+ height must stay inside the card's meta row. --space-hair (2px) tips it
1014
+ past the row and pushes the card taller. Horizontal snaps normally. */
1015
+ padding: 1px var(--space-1-75); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-pill);
989
1016
  font-size: var(--fs-micro); color: var(--fg-3); text-transform: uppercase; letter-spacing: var(--tr-caps);
990
1017
  }
991
1018
  .ds-dash-card.is-external { border-style: dashed; }
@@ -1024,11 +1051,18 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1024
1051
  .chat-msg-flat .chat-role { margin-bottom: var(--space-2); }
1025
1052
  .chat-msg-flat .chat-md { line-height: var(--lh-long); }
1026
1053
  .chat-msg-flat .chat-md p { margin: var(--space-2) 0; }
1054
+ /* The `+ 2px` is an OFF-SCALE optical correction, not a rhythm step: the tinted
1055
+ assistant row needs marginally more inset than the untinted .you row so the
1056
+ fill does not appear to crowd the text. Expressing it as a --space-* rung
1057
+ would make it a visible step rather than the sub-perceptual nudge intended. */
1027
1058
  .chat-msg-flat.them { padding-block: calc(var(--space-3) * var(--density, 1) + 2px); }
1028
1059
  /* Inline backtick code (renderInline tags <code class=chat-tick>) - was a dead
1029
1060
  class relying on the generic .chat-bubble code rule, so notices / non-bubble
1030
1061
  surfaces got unstyled monospace. Self-style it regardless of container. */
1031
- .chat-tick { font-family: var(--ff-mono); font-size: .92em; background: color-mix(in oklab, var(--fg) 10%, transparent); padding: 1px 6px; border-radius: var(--r-1); }
1062
+ /* 1px vertical is OFF-SCALE ON PURPOSE inline code sits INSIDE a line of running
1063
+ prose; any larger vertical pad makes the tinted box overlap the lines above and
1064
+ below. Horizontal is on the scale. */
1065
+ .chat-tick { font-family: var(--ff-mono); font-size: .92em; background: color-mix(in oklab, var(--fg) 10%, transparent); padding: 1px var(--space-1-75); border-radius: var(--r-1); }
1032
1066
  /* Structured tool/code output earns more width than running prose (claude.ai/code
1033
1067
  lets diffs/tables break out wider than the reading measure). A flat turn that
1034
1068
  contains a tool card or code block widens itself AND its stack past --measure;
@@ -1080,7 +1114,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1080
1114
  margin-left: auto; flex: 0 0 auto;
1081
1115
  font-size: var(--fs-micro); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tr-caps);
1082
1116
  color: var(--fg-3);
1083
- padding: 2px var(--space-2); border-radius: var(--r-pill);
1117
+ padding: var(--space-hair) var(--space-2); border-radius: var(--r-pill);
1084
1118
  background: color-mix(in oklab, var(--fg) 6%, transparent);
1085
1119
  }
1086
1120
  .chat-msg .chat-tool.tool-running .chat-tool-status { color: var(--accent-ink); background: color-mix(in oklab, var(--accent) 12%, transparent); }
@@ -1108,8 +1142,8 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1108
1142
  structured CodeNode). injectCodeCopy reads the language- class. */
1109
1143
  .chat-code-block { position: relative; }
1110
1144
  .chat-code-lang {
1111
- position: absolute; top: 0; left: 0; z-index: 2;
1112
- padding: 2px var(--space-2); border-bottom-right-radius: var(--r-1);
1145
+ position: absolute; top: 0; left: 0; z-index: var(--z-raised);
1146
+ padding: var(--space-hair) var(--space-2); border-bottom-right-radius: var(--r-1);
1113
1147
  font-family: var(--ff-mono); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tr-caps);
1114
1148
  color: var(--fg-3); background: color-mix(in oklab, var(--fg) 6%, transparent);
1115
1149
  pointer-events: none;
@@ -1169,7 +1203,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1169
1203
  .ds-dash-clear:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: 1px; border-radius: var(--r-1); }
1170
1204
 
1171
1205
  /* Conversation-rail loading skeleton (cold ccsniff walk). */
1172
- .ds-session-row-skeleton { display: flex; flex-direction: column; gap: 6px; padding: var(--space-2) var(--space-3); }
1206
+ .ds-session-row-skeleton { display: flex; flex-direction: column; gap: var(--space-1-75); padding: var(--space-2) var(--space-3); }
1173
1207
  .ds-session-row-skeleton .ds-skel { background: var(--bg-3); border-radius: var(--r-1); }
1174
1208
  .ds-session-row-skeleton .ds-skel-title { height: 12px; width: 70%; }
1175
1209
  .ds-session-row-skeleton .ds-skel-meta { height: 9px; width: 45%; }
@@ -1220,7 +1254,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1220
1254
  Hover/focus/active-state rules on the originals still apply.
1221
1255
  ---------------------------------------------------------------------------- */
1222
1256
  .row-act, .ds-dash-errors-toggle, .agentchat-export-act, .ds-file-more-btn {
1223
- min-height: 32px; padding: 5px 12px; border-radius: var(--r-1);
1257
+ min-height: 32px; padding: var(--space-1-5) var(--space-2-75); border-radius: var(--r-1);
1224
1258
  font-family: var(--ff-body); font-size: var(--fs-tiny); font-weight: 500;
1225
1259
  background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
1226
1260
  cursor: pointer;
@@ -1229,7 +1263,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1229
1263
  background: var(--bg-2); color: var(--fg);
1230
1264
  }
1231
1265
  .agentchat-install-copy, .ds-upload-act, .ds-session-meta-copy {
1232
- min-height: 24px; padding: 2px 8px; border-radius: var(--r-1);
1266
+ min-height: 24px; padding: var(--space-hair) var(--space-2); border-radius: var(--r-1);
1233
1267
  font-family: var(--ff-body); font-size: var(--fs-tiny);
1234
1268
  background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-3);
1235
1269
  cursor: pointer;
@@ -1284,7 +1318,10 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1284
1318
  border-top: var(--bw-hair) solid var(--rule);
1285
1319
  border-bottom: var(--bw-hair) solid var(--rule);
1286
1320
  pointer-events: none;
1287
- z-index: 1;
1321
+ /* Minimap internal order: centerline < viewport < dot < tooltip. All four
1322
+ live inside the one raised widget, so they share its rung and differ
1323
+ only by a local offset. */
1324
+ z-index: calc(var(--z-raised) + 1);
1288
1325
  }
1289
1326
  .chat-minimap-centerline {
1290
1327
  position: absolute;
@@ -1294,7 +1331,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1294
1331
  width: 1px;
1295
1332
  background: var(--rule);
1296
1333
  transform: translateX(-50%);
1297
- z-index: 0;
1334
+ z-index: var(--z-raised);
1298
1335
  }
1299
1336
  .chat-minimap-dot {
1300
1337
  position: absolute;
@@ -1304,7 +1341,7 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1304
1341
  border-radius: var(--r-pill, 999px);
1305
1342
  transform: translate(-50%, -50%) scale(1);
1306
1343
  transition: transform 0.1s;
1307
- z-index: 2;
1344
+ z-index: calc(var(--z-raised) + 2);
1308
1345
  }
1309
1346
  .chat-minimap-dot.is-user {
1310
1347
  background: color-mix(in oklab, var(--accent) 18%, transparent);
@@ -1326,7 +1363,10 @@ button.chat-composer-context:focus-visible { outline: var(--focus-w) solid var(-
1326
1363
  border-left: 2px solid var(--fg-3);
1327
1364
  border-radius: var(--r-1);
1328
1365
  padding: calc(var(--space-1) / 2) var(--space-2);
1329
- z-index: 100;
1366
+ /* Top of the minimap's internal order. Deliberately NOT --z-tooltip: it is
1367
+ clipped to the minimap rail rather than floating over the app, so it must
1368
+ not outrank real overlays that may cover the rail. */
1369
+ z-index: calc(var(--z-raised) + 3);
1330
1370
  pointer-events: none;
1331
1371
  opacity: 0.45;
1332
1372
  font-size: var(--fs-tiny);
@@ -145,6 +145,13 @@
145
145
  --ff-body: system-ui, sans-serif;
146
146
  --ff-mono: ui-monospace, Menlo, Consolas, monospace;
147
147
 
148
+ /* Sub-12px tiers exist ONLY for dense OS/data chrome — taskbar strips,
149
+ session chips, tool-call headers, file-row metadata, ID/stat columns.
150
+ Never use them for body copy or ordinary UI text: at these sizes the
151
+ system stack loses its readable x-height, so they are reserved for
152
+ glanceable, secondary, non-prose material. --fs-pico is the floor. */
153
+ --fs-pico: 10px;
154
+ --fs-nano: 11px;
148
155
  --fs-micro: 12px;
149
156
  --fs-tiny: 13px;
150
157
  --fs-xs: 14px;
@@ -245,8 +252,61 @@
245
252
  edges (panel spine, expo numbering). A literal length, not a color. */
246
253
  --ink-offset: 3px;
247
254
 
248
- --z-header: 100;
249
- --z-overlay: 1000;
255
+ /* ============================================================
256
+ Stacking scale — the ONE ordered set of layers anything may
257
+ paint into. Rungs are 100 apart so a future layer can be
258
+ inserted between two neighbours without renumbering the rest,
259
+ and so a component may locally offset (+1/+2) within its own
260
+ rung without colliding with the next one.
261
+
262
+ Order is the contract; the numbers are just how it is spelled.
263
+ Read top to bottom as "what paints over what":
264
+
265
+ --z-below -1 decorative texture UNDER its own content
266
+ (.ds-grain/.ds-halftone print layer)
267
+ --z-base 0 in-flow content; the default plane
268
+ --z-raised 100 a thing lifted above its siblings inside
269
+ one component (code-lang tab, timeline dot,
270
+ selection checkbox, resize handle)
271
+ --z-sticky 200 sticky-within-a-scroller chrome: section
272
+ labels, sticky table headers, save bars.
273
+ Above raised content it scrolls past.
274
+ --z-header 300 the app's own sticky chrome band
275
+ (.app-topbar/.app-chrome)
276
+ --z-drawer 400 off-canvas panels (sidebar/pane/session
277
+ drawers) and their scrim, which must cover
278
+ the header they slide over
279
+ --z-window 500 free-floating window-manager surfaces —
280
+ the OS kit's .wm-root canvas of draggable
281
+ windows. Above the shell, below all
282
+ transient popups.
283
+ --z-dock 600 persistent OS shell furniture that must
284
+ stay above windows: launcher dock, menubar,
285
+ taskbar, os-root
286
+ --z-dropdown 700 menus/popovers anchored to a trigger; they
287
+ must escape the dock that spawned them
288
+ --z-modal 800 blocking dialogs, lightboxes, command
289
+ palettes and their backdrops
290
+ --z-toast 900 transient notifications — above a modal,
291
+ because they report on what the modal did
292
+ --z-tooltip 1000 pointer-following hint; never blocked
293
+ --z-top 1100 last resort: boot/loading veils and
294
+ full-screen takeovers that outrank
295
+ everything, including a tooltip
296
+ ============================================================ */
297
+ --z-below: -1;
298
+ --z-base: 0;
299
+ --z-raised: 100;
300
+ --z-sticky: 200;
301
+ --z-header: 300;
302
+ --z-drawer: 400;
303
+ --z-window: 500;
304
+ --z-dock: 600;
305
+ --z-dropdown: 700;
306
+ --z-modal: 800;
307
+ --z-toast: 900;
308
+ --z-tooltip: 1000;
309
+ --z-top: 1100;
250
310
 
251
311
  --measure: 68ch;
252
312
  --measure-wide: 940px;
@@ -589,9 +649,8 @@ select:focus-visible {
589
649
  scrim; heavier than --shadow-3 and theme-driven (was raw rgba(0,0,0,.4)). */
590
650
  --shadow-overlay: 0 12px 40px color-mix(in oklab, var(--fg) 28%, transparent),
591
651
  0 4px 12px color-mix(in oklab, var(--fg) 16%, transparent);
592
- --z-dropdown: 600;
593
- --z-popover: 700;
594
- --z-modal: 800;
595
- --z-toast: 900;
596
- --z-tooltip: 1000;
652
+ /* --z-popover is an alias, not a rung: popovers and dropdowns are the
653
+ same anchored-to-a-trigger layer and must never be able to drift
654
+ apart. The rungs themselves live with the stacking scale above. */
655
+ --z-popover: var(--z-dropdown);
597
656
  }