anentrypoint-design 0.0.381 → 0.0.382

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.
Files changed (49) hide show
  1. package/dist/247420.css +228 -162
  2. package/dist/247420.js +24 -24
  3. package/package.json +1 -1
  4. package/src/components/content/avatar.js +31 -0
  5. package/src/components/content/charts.js +50 -0
  6. package/src/components/content/cli.js +46 -0
  7. package/src/components/content/feedback.js +77 -0
  8. package/src/components/content/fields.js +136 -0
  9. package/src/components/content/hero.js +146 -0
  10. package/src/components/content/lists.js +85 -0
  11. package/src/components/content/panel.js +79 -0
  12. package/src/components/content/row.js +115 -0
  13. package/src/components/content/table.js +97 -0
  14. package/src/components/content/views.js +81 -0
  15. package/src/components/content.js +29 -861
  16. package/src/components/editor-primitives/batch.js +60 -0
  17. package/src/components/editor-primitives/chrome.js +146 -0
  18. package/src/components/editor-primitives/collapse.js +46 -0
  19. package/src/components/editor-primitives/context-menu.js +127 -0
  20. package/src/components/editor-primitives/diagnostics.js +44 -0
  21. package/src/components/editor-primitives/focus-trap.js +26 -0
  22. package/src/components/editor-primitives/json-viewer.js +123 -0
  23. package/src/components/editor-primitives/layout.js +89 -0
  24. package/src/components/editor-primitives/modals.js +89 -0
  25. package/src/components/editor-primitives/pager.js +74 -0
  26. package/src/components/editor-primitives/property-grid.js +57 -0
  27. package/src/components/editor-primitives/shared.js +18 -0
  28. package/src/components/editor-primitives/split-panel.js +101 -0
  29. package/src/components/editor-primitives/toast.js +59 -0
  30. package/src/components/editor-primitives/tree.js +75 -0
  31. package/src/components/editor-primitives.js +35 -1048
  32. package/src/components/overlay-primitives/approval-prompt.js +38 -0
  33. package/src/components/overlay-primitives/auth-modal.js +89 -0
  34. package/src/components/overlay-primitives/command-palette.js +101 -0
  35. package/src/components/overlay-primitives/emoji-picker.js +103 -0
  36. package/src/components/overlay-primitives/floating.js +146 -0
  37. package/src/components/overlay-primitives/full-screen.js +45 -0
  38. package/src/components/overlay-primitives/menus.js +131 -0
  39. package/src/components/overlay-primitives/popover.js +51 -0
  40. package/src/components/overlay-primitives/roving-menu.js +73 -0
  41. package/src/components/overlay-primitives/settings-popover.js +85 -0
  42. package/src/components/overlay-primitives/tooltip.js +55 -0
  43. package/src/components/overlay-primitives.js +33 -855
  44. package/src/css/app-shell/chat-polish.css +39 -32
  45. package/src/css/app-shell/data-density.css +25 -21
  46. package/src/css/app-shell/files.css +37 -29
  47. package/src/css/app-shell/kits-appended.css +73 -50
  48. package/src/css/app-shell/responsive.css +47 -29
  49. package/src/kits/os/freddie-dashboard.css +2 -2
@@ -8,7 +8,7 @@
8
8
  flex: 1; min-height: 0; gap: var(--space-3);
9
9
  }
10
10
  .chat-head {
11
- display: flex; align-items: baseline; gap: 8px;
11
+ display: flex; align-items: baseline; gap: var(--space-2);
12
12
  padding: var(--space-3) 0 var(--space-2);
13
13
  font-family: var(--ff-mono); font-size: var(--fs-xs);
14
14
  color: var(--fg-3); text-transform: lowercase; letter-spacing: 0.02em;
@@ -46,10 +46,10 @@
46
46
  .chat-empty-title { font-size: var(--fs-sm); margin: 0 0 var(--space-1); }
47
47
  .chat-empty-sub { font-size: var(--fs-tiny); margin: 0; opacity: .7; }
48
48
 
49
- .chat-msg { display: flex; gap: 12px; align-items: flex-start; padding: 6px 0; position: relative; min-width: 0; }
49
+ .chat-msg { display: flex; gap: var(--space-2-75); align-items: flex-start; padding: var(--space-1-75) 0; position: relative; min-width: 0; }
50
50
  .chat-msg.you { flex-direction: row-reverse; }
51
51
  .chat-msg.you .chat-stack { align-items: flex-end; }
52
- .chat-msg:hover { background: color-mix(in oklab, var(--fg) 4%, transparent); padding: 6px 0; margin: 0; border-radius: var(--r-0); transition: background var(--dur-base) var(--ease); }
52
+ .chat-msg:hover { background: color-mix(in oklab, var(--fg) 4%, transparent); padding: var(--space-1-75) 0; margin: 0; border-radius: var(--r-0); transition: background var(--dur-base) var(--ease); }
53
53
 
54
54
  .chat-avatar {
55
55
  width: 36px; height: 36px; flex-shrink: 0;
@@ -71,13 +71,16 @@
71
71
  }
72
72
 
73
73
  .chat-stack {
74
- display: flex; flex-direction: column; gap: 4px;
74
+ display: flex; flex-direction: column; gap: var(--space-1);
75
75
  max-width: min(70%, 56ch); min-width: 0;
76
76
  flex: 0 1 auto; overflow: hidden;
77
77
  }
78
78
 
79
79
  .chat-bubble {
80
- padding: 10px 14px; background: var(--bg-2); color: var(--fg);
80
+ /* 14px inline has no tier (--space-2-75 is 12, --space-3 is 16). It is the
81
+ shared bubble/attachment inset used by .chat-file/.chat-pdf-head below;
82
+ snapping only this one would visibly desync the bubble from its cards. */
83
+ padding: var(--space-2-5) 14px; background: var(--bg-2); color: var(--fg);
81
84
  max-width: 100%;
82
85
  border-radius: var(--r-2); line-height: 1.55;
83
86
  word-wrap: break-word; overflow-wrap: anywhere;
@@ -95,7 +98,9 @@
95
98
  .chat-bubble code {
96
99
  font-family: var(--ff-mono); font-size: 0.92em;
97
100
  background: color-mix(in oklab, var(--fg) 10%, transparent);
98
- padding: 1px 6px; border-radius: var(--r-0);
101
+ /* 1px block is deliberately under --space-hair (2px): inline <code> must not
102
+ grow the line box of the prose it sits inside. */
103
+ padding: 1px var(--space-1-75); border-radius: var(--r-0);
99
104
  }
100
105
  .chat-msg.you .chat-bubble code { background: color-mix(in oklab, var(--fg) 10%, transparent); }
101
106
  .chat-bubble a {
@@ -122,10 +127,12 @@
122
127
  .chat-bubble.chat-md h3 { font-size: 1.04em; }
123
128
  .chat-bubble.chat-md p { margin: var(--space-2) 0; }
124
129
  .chat-bubble.chat-md ul,
130
+ /* 22px is the list-marker hang, matched to the mono digit+period width so
131
+ ordered markers align with the bubble text edge - not a spacing-scale value. */
125
132
  .chat-bubble.chat-md ol { margin: var(--space-2) 0; padding-left: 22px; }
126
133
  .chat-bubble.chat-md li { margin: var(--space-1) 0; }
127
134
  .chat-bubble.chat-md blockquote {
128
- margin: var(--space-2) 0; padding: 4px 12px;
135
+ margin: var(--space-2) 0; padding: var(--space-1) var(--space-2-75);
129
136
  /* DELIBERATE, but slimmed to the --bw-rule tier. This is a real markdown
130
137
  <blockquote> inside a chat bubble: the left rule is the standard
131
138
  typographic quotation mark, not a colored alert stripe (the tone is a
@@ -137,7 +144,7 @@
137
144
  .chat-bubble.chat-md pre {
138
145
  background: var(--bg);
139
146
  border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
140
- padding: 12px 16px; border-radius: var(--r-1); overflow-x: auto;
147
+ padding: var(--space-2-75) var(--space-3); border-radius: var(--r-1); overflow-x: auto;
141
148
  font-family: var(--ff-mono); font-size: var(--fs-xs); line-height: 1.55;
142
149
  color: var(--fg); margin: var(--space-2) 0;
143
150
  }
@@ -151,11 +158,11 @@
151
158
  }
152
159
  /* Markdown tables + horizontal rules: agents routinely emit them, but they were
153
160
  unstyled (bare unspaced cells, vanished rules). */
154
- .chat-bubble.chat-md table { border-collapse: collapse; width: auto; max-width: 100%; margin: 8px 0; font-size: .95em; display: block; overflow-x: auto; }
161
+ .chat-bubble.chat-md table { border-collapse: collapse; width: auto; max-width: 100%; margin: var(--space-2) 0; font-size: .95em; display: block; overflow-x: auto; }
155
162
  .chat-bubble.chat-md th,
156
- .chat-bubble.chat-md td { border: var(--bw-hair) solid var(--rule); padding: 4px 10px; text-align: left; }
163
+ .chat-bubble.chat-md td { border: var(--bw-hair) solid var(--rule); padding: var(--space-1) var(--space-2-5); text-align: left; }
157
164
  .chat-bubble.chat-md th { background: color-mix(in oklab, var(--fg) 5%, transparent); font-weight: 600; }
158
- .chat-bubble.chat-md hr { border: 0; border-top: var(--bw-hair) solid var(--rule); margin: 12px 0; }
165
+ .chat-bubble.chat-md hr { border: 0; border-top: var(--bw-hair) solid var(--rule); margin: var(--space-2-75) 0; }
159
166
 
160
167
  /* Mermaid diagram blocks — rendered SVG swapped in over the fenced source by
161
168
  src/mermaid.js's renderMermaidBlocksUnder(); the source .pre stays in the
@@ -163,7 +170,7 @@
163
170
  .ds-mermaid-block {
164
171
  position: relative; margin: var(--space-2) 0;
165
172
  border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
166
- border-radius: var(--r-1); background: var(--bg); padding: 12px 16px;
173
+ border-radius: var(--r-1); background: var(--bg); padding: var(--space-2-75) var(--space-3);
167
174
  }
168
175
  .ds-mermaid-diagram { overflow-x: auto; display: flex; justify-content: center; }
169
176
  .ds-mermaid-diagram svg { max-width: 100%; height: auto; }
@@ -172,7 +179,7 @@
172
179
  font: inherit; font-size: var(--fs-xs); line-height: 1;
173
180
  background: color-mix(in oklab, var(--fg) 8%, transparent);
174
181
  color: var(--fg); border: none; border-radius: var(--r-1);
175
- padding: 4px 8px; cursor: pointer;
182
+ padding: var(--space-1) var(--space-2); cursor: pointer;
176
183
  }
177
184
  .ds-mermaid-toggle:hover { background: color-mix(in oklab, var(--fg) 14%, transparent); }
178
185
 
@@ -205,8 +212,8 @@
205
212
  min-width: 0;
206
213
  }
207
214
  .chat-code-head {
208
- display: flex; align-items: center; gap: 10px;
209
- padding: 8px 12px;
215
+ display: flex; align-items: center; gap: var(--space-2-5);
216
+ padding: var(--space-2) var(--space-2-75);
210
217
  background: color-mix(in oklab, var(--fg) 6%, var(--bg-2));
211
218
  border-bottom: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
212
219
  font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3);
@@ -216,7 +223,7 @@
216
223
  .chat-code-head .name { color: var(--fg-2); font-weight: 500; }
217
224
  .chat-code-head .spread { flex: 1; }
218
225
  .chat-bubble.chat-code pre {
219
- margin: 0; padding: 12px 16px; background: transparent;
226
+ margin: 0; padding: var(--space-2-75) var(--space-3); background: transparent;
220
227
  font-family: var(--ff-mono); font-size: var(--fs-xs); line-height: 1.55;
221
228
  overflow-x: auto; color: var(--fg); border-radius: 0;
222
229
  }
@@ -248,12 +255,12 @@
248
255
  }
249
256
  .chat-image img { display: block; width: 100%; height: auto; max-height: 360px; object-fit: cover; }
250
257
  .chat-image .cap,
251
- .chat-image .caption { display: block; padding: 8px 12px; font-size: var(--fs-xs); color: var(--fg-3); font-family: var(--ff-mono); }
258
+ .chat-image .caption { display: block; padding: var(--space-2) var(--space-2-75); font-size: var(--fs-xs); color: var(--fg-3); font-family: var(--ff-mono); }
252
259
 
253
260
  .chat-msg.you .chat-file,
254
261
  .chat-msg .chat-file,
255
262
  .chat-file {
256
- display: flex; align-items: center; gap: 12px; padding: 12px 14px;
263
+ display: flex; align-items: center; gap: var(--space-2-75); padding: var(--space-2-75) 14px;
257
264
  background: var(--bg-2); border: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
258
265
  border-radius: var(--r-1); text-decoration: none; color: var(--fg);
259
266
  max-width: min(100%, 360px);
@@ -266,12 +273,12 @@
266
273
  background: var(--bg-3);
267
274
  color: var(--fg-2); border-radius: var(--r-0); flex-shrink: 0; font-family: var(--ff-mono);
268
275
  }
269
- .chat-file > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
276
+ .chat-file > div { display: flex; flex-direction: column; gap: var(--space-hair); min-width: 0; }
270
277
  .chat-file .name {
271
278
  font-weight: 600; font-size: var(--fs-sm);
272
279
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
273
280
  }
274
- .chat-file .meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
281
+ .chat-file .meta { display: flex; flex-direction: column; gap: var(--space-hair); min-width: 0; flex: 1; }
275
282
  .chat-file .size { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); }
276
283
  .chat-file .go { font-family: var(--ff-mono); font-size: 16px; color: var(--fg-3); flex-shrink: 0; }
277
284
  .chat-file:hover .go { color: var(--accent-ink); }
@@ -287,7 +294,7 @@
287
294
  }
288
295
  .chat-msg:hover .chat-pdf { border-color: var(--rule); }
289
296
  .chat-pdf-head {
290
- display: flex; align-items: center; gap: 10px; padding: 10px 14px;
297
+ display: flex; align-items: center; gap: var(--space-2-5); padding: var(--space-2-5) 14px;
291
298
  background: color-mix(in oklab, var(--fg) 5%, var(--bg-2));
292
299
  border-bottom: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
293
300
  }
@@ -302,7 +309,7 @@
302
309
  .chat-msg.you .chat-link,
303
310
  .chat-msg .chat-link,
304
311
  .chat-link {
305
- display: grid; grid-template-columns: 80px 1fr; gap: 12px; padding: 10px;
312
+ display: grid; grid-template-columns: 80px 1fr; gap: var(--space-2-75); padding: var(--space-2-5);
306
313
  background: var(--bg-2);
307
314
  border: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
308
315
  border-radius: var(--r-1); text-decoration: none; color: var(--fg);
@@ -316,28 +323,28 @@
316
323
  .chat-link:not(:has(.thumb)):not(:has(img)) { grid-template-columns: 1fr; }
317
324
  .chat-link .thumb,
318
325
  .chat-link img.thumb { width: 80px; height: 80px; border-radius: var(--r-0); object-fit: cover; background: var(--bg-3) center/cover no-repeat; }
319
- .chat-link .meta { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
326
+ .chat-link .meta { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
320
327
  .chat-link .host { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); text-transform: lowercase; }
321
328
  .chat-link .title { font-weight: 600; font-size: var(--fs-sm); line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
322
329
  .chat-link .desc { font-size: var(--fs-xs); color: var(--fg-2); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
323
330
 
324
331
  .chat-meta {
325
- display: flex; align-items: center; gap: 6px;
332
+ display: flex; align-items: center; gap: var(--space-1-75);
326
333
  font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3);
327
- padding: 0 6px; letter-spacing: 0.02em;
334
+ padding: 0 var(--space-1-75); letter-spacing: 0.02em;
328
335
  }
329
336
  .chat-meta .who { font-weight: 600; color: var(--fg-2); }
330
337
  .chat-meta .who::after { content: ' ·'; color: var(--fg-3); font-weight: 400; }
331
338
  .chat-meta .t { color: var(--fg-3); }
332
- .chat-meta .tick { color: var(--fg-3); margin-left: 2px; letter-spacing: -2px; font-family: var(--ff-mono); }
339
+ .chat-meta .tick { color: var(--fg-3); margin-left: var(--space-hair); letter-spacing: -2px; font-family: var(--ff-mono); }
333
340
  .chat-meta .tick.read { color: var(--accent-ink); }
334
341
 
335
342
  .chat-reactions {
336
- display: flex; gap: 4px; flex-wrap: wrap; margin-top: 2px;
343
+ display: flex; gap: var(--space-1); flex-wrap: wrap; margin-top: var(--space-hair);
337
344
  }
338
345
  .chat-reactions .rxn {
339
- display: inline-flex; align-items: center; gap: 4px;
340
- padding: 2px 8px; background: var(--bg-2);
346
+ display: inline-flex; align-items: center; gap: var(--space-1);
347
+ padding: var(--space-hair) var(--space-2); background: var(--bg-2);
341
348
  border: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
342
349
  border-radius: var(--r-pill); font-size: var(--fs-xs);
343
350
  cursor: pointer; user-select: none;
@@ -354,7 +361,7 @@
354
361
  .chat-reactions .rxn .n { font-family: var(--ff-mono); font-weight: 600; font-size: 11px; color: var(--fg-2); }
355
362
  .chat-reactions .rxn.you .n { color: var(--accent-ink); }
356
363
 
357
- .chat-typing { display: inline-flex; gap: 4px; align-items: center; }
364
+ .chat-typing { display: inline-flex; gap: var(--space-1); align-items: center; }
358
365
  .chat-typing span {
359
366
  width: 6px; height: 6px; border-radius: 50%; background: var(--fg-3);
360
367
  }
@@ -422,7 +429,7 @@
422
429
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--flame) 22%, transparent);
423
430
  }
424
431
  .chat-composer textarea {
425
- flex: 1; min-width: 0; padding: 8px 4px;
432
+ flex: 1; min-width: 0; padding: var(--space-2) var(--space-1);
426
433
  background: none; color: var(--fg);
427
434
  border: none; border-radius: 0;
428
435
  font-family: inherit; font-size: var(--fs-sm);
@@ -476,7 +483,7 @@
476
483
  .composer-btn { transition: none; }
477
484
  }
478
485
 
479
- .aicat-portrait { display: inline-flex; align-items: center; gap: 10px; padding: 4px 0; }
486
+ .aicat-portrait { display: inline-flex; align-items: center; gap: var(--space-2-5); padding: var(--space-1) 0; }
480
487
  .aicat-face {
481
488
  width: 32px; height: 32px; font-size: 24px;
482
489
  display: inline-flex; align-items: center; justify-content: center;
@@ -13,7 +13,7 @@
13
13
  }
14
14
 
15
15
  /* PhaseWalk */
16
- .ds-phasewalk { display: inline-flex; gap: 2px; vertical-align: middle; }
16
+ .ds-phasewalk { display: inline-flex; gap: var(--space-hair); vertical-align: middle; }
17
17
  .ds-phasewalk-seg {
18
18
  width: 18px; height: 10px; border-radius: var(--r-hair);
19
19
  background: var(--bg-3); position: relative;
@@ -22,6 +22,10 @@
22
22
  .ds-phasewalk-seg.is-gap { background: var(--warn); }
23
23
  /* Standalone PhaseWalk reserves headroom for the labels instead of letting
24
24
  them escape upward and overlap the element above. */
25
+ /* 15px is load-bearing, not off-scale drift: it must equal the absolute
26
+ `top: -15px` the label below is lifted by, so the label clears the segments
27
+ without a gap. Snapping the pad to --space-3 (16px) alone would desync the
28
+ pair. */
25
29
  .ds-phasewalk { padding-top: 15px; }
26
30
  .ds-phasewalk-lbl {
27
31
  position: absolute; top: -15px; left: 0;
@@ -34,25 +38,25 @@
34
38
 
35
39
  /* TreeNode */
36
40
  .ds-tree-node {
37
- padding: 5px 10px; border-left: var(--bw-rule) solid var(--bg-3);
38
- margin: 2px 0 2px 16px; font-size: var(--fs-tiny);
41
+ padding: var(--space-1-5) var(--space-2-5); border-left: var(--bw-rule) solid var(--bg-3);
42
+ margin: var(--space-hair) 0 var(--space-hair) var(--space-3); font-size: var(--fs-tiny);
39
43
  min-width: 0; overflow-wrap: anywhere;
40
44
  }
41
45
  @media (max-width: 400px) {
42
- .ds-tree-node { margin-left: 8px; padding-left: 8px; }
46
+ .ds-tree-node { margin-left: var(--space-2); padding-left: var(--space-2); }
43
47
  }
44
48
  .ds-tree-node.is-phase { border-color: var(--accent); background: var(--bg-3); font-weight: 600; }
45
49
  .ds-tree-node.is-deviation { border-color: var(--warn); background: var(--danger-surface); color: var(--warn); }
46
50
  .ds-tree-node.is-mutable-resolve { border-color: var(--success); }
47
51
  .ds-tree-node.is-prd-add { border-color: var(--amber); }
48
- .ds-tree-node-ts { margin-right: 8px; color: var(--fg-3); }
49
- .ds-tree-node-pills { margin-left: 6px; }
50
- .ds-tree-node-reason { margin-top: 2px; color: var(--fg-2); }
51
- .ds-tree-node-deviation { margin-top: 2px; }
52
- .ds-tree-node-residuals { margin-top: 2px; color: var(--fg-3); }
52
+ .ds-tree-node-ts { margin-right: var(--space-2); color: var(--fg-3); }
53
+ .ds-tree-node-pills { margin-left: var(--space-1-75); }
54
+ .ds-tree-node-reason { margin-top: var(--space-hair); color: var(--fg-2); }
55
+ .ds-tree-node-deviation { margin-top: var(--space-hair); }
56
+ .ds-tree-node-residuals { margin-top: var(--space-hair); color: var(--fg-3); }
53
57
 
54
58
  /* BarRow */
55
- .ds-bar-row { display: flex; align-items: center; gap: 8px; margin: 3px 0; font-size: var(--fs-tiny); }
59
+ .ds-bar-row { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-half) 0; font-size: var(--fs-tiny); }
56
60
  .ds-bar-row-label { width: 100px; flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
57
61
  .ds-bar-bg { flex: 1; min-width: 60px; background: var(--bg-3); border-radius: var(--r-hair); height: 6px; overflow: hidden; }
58
62
  .ds-bar-fill { background: var(--fg-3); height: 100%; border-radius: var(--r-hair); }
@@ -71,11 +75,11 @@
71
75
  .ds-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-1); }
72
76
  }
73
77
  .ds-stats-grid-empty { padding: var(--space-3); color: var(--fg-3); font-size: var(--fs-tiny); }
74
- .ds-stat { min-width: 0; background: var(--bg-3); border-radius: var(--r-0); padding: 10px 12px; }
78
+ .ds-stat { min-width: 0; background: var(--bg-3); border-radius: var(--r-0); padding: var(--space-2-5) var(--space-2-75); }
75
79
  .ds-stat-val { font-size: clamp(18px, 5cqi, 22px); font-weight: 700; color: var(--accent-ink); overflow-wrap: anywhere; }
76
80
  .ds-stat-val.rate-big { font-size: clamp(24px, 7cqi, 32px); color: var(--success); }
77
81
  .ds-stat-val.err-rate { font-size: clamp(24px, 7cqi, 32px); color: var(--warn); }
78
- .ds-stat-lbl { font-size: var(--fs-micro); color: var(--fg-3); margin-top: 2px; }
82
+ .ds-stat-lbl { font-size: var(--fs-micro); color: var(--fg-3); margin-top: var(--space-hair); }
79
83
 
80
84
  /* RateCell — tone-colored numeric table cell (success-rate / percentile-latency
81
85
  columns), ported from docstudio's endpointsView() success-rate coloring.
@@ -92,10 +96,10 @@
92
96
  .ds-inline-row { display: flex; align-items: center; gap: var(--space-2, 8px); }
93
97
 
94
98
  /* SubGrid */
95
- .ds-sub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 6px; margin-top: 8px; }
99
+ .ds-sub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: var(--space-1-75); margin-top: var(--space-2); }
96
100
  .ds-sub-grid-empty { padding: var(--space-3); color: var(--fg-3); font-size: var(--fs-tiny); }
97
101
  .ds-sub-btn {
98
- padding: 6px 10px; background: var(--bg-3); border: var(--bw-hair) solid var(--bg-3);
102
+ padding: var(--space-1-75) var(--space-2-5); background: var(--bg-3); border: var(--bw-hair) solid var(--bg-3);
99
103
  border-radius: var(--r-0); font-size: var(--fs-tiny); cursor: pointer; color: var(--fg);
100
104
  text-align: left; font-family: var(--ff-body);
101
105
  }
@@ -114,7 +118,7 @@
114
118
  identical to the ones there, so a kit loading both gets the same result. */
115
119
  .ds-session-row {
116
120
  position: relative; display: flex; align-items: center; gap: var(--space-2);
117
- width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: 2px;
121
+ width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: var(--space-hair);
118
122
  background: transparent; border: none; border-radius: var(--r-1);
119
123
  text-align: left; color: var(--fg);
120
124
  }
@@ -142,7 +146,7 @@
142
146
  /* DevRow */
143
147
  .ds-dev-row {
144
148
  background: var(--danger-surface); border-left: var(--bw-chunk) solid var(--warn);
145
- padding: 8px 12px; margin: 4px 0; border-radius: var(--r-hair); font-size: var(--fs-tiny);
149
+ padding: var(--space-2) var(--space-2-75); margin: var(--space-1) 0; border-radius: var(--r-hair); font-size: var(--fs-tiny);
146
150
  }
147
151
  .ds-dev-row strong { color: var(--warn); }
148
152
 
@@ -159,17 +163,17 @@
159
163
  /* Embedded in a WM window the viewport calc is meaningless — fill the container. */
160
164
  .fd-root .ds-live-log { height: 100%; max-height: none; min-height: 0; flex: 1 1 auto; }
161
165
  .ds-live-log-empty { height: auto; min-height: 0; padding: var(--space-3); color: var(--fg-3); }
162
- .ds-live-log-entry { padding: 2px 8px; border-bottom: var(--bw-hair) solid var(--bg-3); overflow-wrap: anywhere; }
166
+ .ds-live-log-entry { padding: var(--space-hair) var(--space-2); border-bottom: var(--bw-hair) solid var(--bg-3); overflow-wrap: anywhere; }
163
167
  .ds-live-log-entry:hover { background: var(--bg-3); }
164
- .ds-live-log-ts { margin-right: 6px; color: var(--fg-3); }
165
- .ds-live-log-subtag { margin-right: 6px; padding: 0 5px; border-radius: var(--r-hair); font-size: var(--fs-micro); }
166
- .ds-live-log-preview { margin-left: 6px; color: var(--fg-3); word-break: break-word; }
168
+ .ds-live-log-ts { margin-right: var(--space-1-75); color: var(--fg-3); }
169
+ .ds-live-log-subtag { margin-right: var(--space-1-75); padding: 0 var(--space-1-5); border-radius: var(--r-hair); font-size: var(--fs-micro); }
170
+ .ds-live-log-preview { margin-left: var(--space-1-75); color: var(--fg-3); word-break: break-word; }
167
171
 
168
172
  /* Touch floors for the dense controls (not covered by the mobile width blocks). */
169
173
  @media (pointer: coarse) {
170
174
  .ds-sub-btn { min-height: 44px; }
171
175
  .ds-session-row { min-height: 44px; }
172
- .ds-live-log-entry { padding-block: 6px; }
176
+ .ds-live-log-entry { padding-block: var(--space-1-75); }
173
177
  }
174
178
 
175
179
 
@@ -8,7 +8,7 @@
8
8
  .ds-file-grid {
9
9
  display: flex;
10
10
  flex-direction: column;
11
- gap: 4px;
11
+ gap: var(--space-1);
12
12
  }
13
13
  .ds-file-grid:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); border-radius: var(--r-2); }
14
14
 
@@ -19,7 +19,7 @@
19
19
  /* The filter is now an inline item in the single .ds-file-controls toolbar row
20
20
  (the standalone right-aligned .ds-file-filter strip was removed). */
21
21
  .ds-file-filter-input {
22
- width: min(280px, 100%); padding: 6px 12px; font-size: var(--fs-sm);
22
+ width: min(280px, 100%); padding: var(--space-1-75) var(--space-2-75); font-size: var(--fs-sm);
23
23
  background: var(--bg); color: var(--fg);
24
24
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
25
25
  }
@@ -29,7 +29,7 @@
29
29
  .ds-file-sort { display: flex; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); }
30
30
  .ds-file-sort-btn {
31
31
  font-size: var(--fs-tiny); font-family: var(--ff-mono); color: var(--fg-3);
32
- background: none; border: none; cursor: pointer; padding: 2px 4px; border-radius: var(--r-1);
32
+ background: none; border: none; cursor: pointer; padding: var(--space-hair) var(--space-1); border-radius: var(--r-1);
33
33
  }
34
34
  .ds-file-sort-btn:hover { color: var(--fg-2); background: var(--bg-2); }
35
35
  .ds-file-sort-btn.active { color: var(--accent-ink); }
@@ -44,9 +44,9 @@
44
44
  .ds-file-grid { transition: opacity .15s var(--ease); }
45
45
  }
46
46
  /* EventList loading skeleton (shares the .ds-skel shimmer base above). */
47
- .ds-event-row-skeleton { display: flex; align-items: center; gap: var(--space-3); padding: 12px 16px; pointer-events: none; }
47
+ .ds-event-row-skeleton { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2-75) var(--space-3); pointer-events: none; }
48
48
  .ds-skel-rank { height: 12px; width: 2.5ch; }
49
- .ds-event-state { padding: var(--space-2) 16px; }
49
+ .ds-event-state { padding: var(--space-2) var(--space-3); }
50
50
  .ds-skel { display: inline-block; border-radius: var(--r-1); background: var(--bg-2); position: relative; overflow: hidden; }
51
51
  .ds-skel::after {
52
52
  content: ''; position: absolute; inset: 0;
@@ -65,8 +65,13 @@
65
65
  because FileRow wraps the row content in a real button for native keyboard
66
66
  semantics. */
67
67
  .ds-file-row {
68
- display: flex; align-items: center; gap: 10px;
69
- padding: 11px 16px; background: var(--bg);
68
+ display: flex; align-items: center; gap: var(--space-2-5);
69
+ /* 11px vertical is an optical half-step between --space-2-5 (10) and
70
+ --space-2-75 (12), deliberately off-scale: with the 26px .ds-file-icon
71
+ and the hairline borders it lands the row at ~50px, comfortably over the
72
+ 44px touch floor without the 52px a 12px pad would give. Snapping either
73
+ way visibly re-pitches every row in a long listing. */
74
+ padding: 11px var(--space-3); background: var(--bg);
70
75
  border: var(--bw-hair) solid transparent;
71
76
  border-radius: var(--r-2); color: var(--fg);
72
77
  cursor: pointer;
@@ -75,7 +80,7 @@
75
80
  transform var(--dur-snap) var(--ease);
76
81
  }
77
82
  .ds-file-open {
78
- display: flex; align-items: center; gap: 14px;
83
+ display: flex; align-items: center; gap: var(--space-2-75);
79
84
  flex: 1 1 auto; min-width: 0;
80
85
  background: none; border: 0; padding: 0; margin: 0;
81
86
  color: inherit; font: inherit; text-align: left; cursor: pointer;
@@ -138,7 +143,7 @@
138
143
  hidden, which left mouse/trackpad users unable to find rename/move/delete
139
144
  without accidentally hovering a row), full opacity on hover/focus. */
140
145
  .ds-file-actions {
141
- display: inline-flex; gap: 2px; align-items: center;
146
+ display: inline-flex; gap: var(--space-hair); align-items: center;
142
147
  opacity: 0.35; transition: opacity var(--dur-base) var(--ease);
143
148
  }
144
149
  .ds-file-row:hover .ds-file-actions,
@@ -183,7 +188,7 @@
183
188
 
184
189
  .ds-file-check {
185
190
  display: inline-flex; align-items: center; justify-content: center;
186
- min-width: 28px; height: 28px; padding: 0 4px;
191
+ min-width: 28px; height: 28px; padding: 0 var(--space-1);
187
192
  background: transparent; border: 0; border-radius: var(--r-1);
188
193
  color: var(--fg-3);
189
194
  cursor: pointer;
@@ -215,7 +220,7 @@
215
220
  quiet destructive outline - the app arm-confirms destructive bulk actions
216
221
  via ConfirmDialog, so the strip never needs a loud CTA. */
217
222
  .ds-bulkbar .btn, .ds-bulkbar .btn-primary {
218
- padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
223
+ padding: var(--space-1-5) var(--space-2-75); min-height: 32px; border-radius: var(--r-1); font-weight: 500;
219
224
  }
220
225
  .ds-bulkbar .btn { background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2); }
221
226
  .ds-bulkbar .btn:hover { background: var(--bg-2); color: var(--fg); }
@@ -227,7 +232,7 @@
227
232
 
228
233
  /* Density picker — list / compact / thumbnails. */
229
234
  .ds-density {
230
- display: inline-flex; gap: 2px; padding: 2px;
235
+ display: inline-flex; gap: var(--space-hair); padding: var(--space-hair);
231
236
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
232
237
  }
233
238
  .ds-density-btn {
@@ -242,8 +247,8 @@
242
247
  .ds-density-btn:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
243
248
 
244
249
  /* Compact density — tighter rows for long listings. */
245
- .ds-file-grid[data-density="compact"] { gap: 2px; }
246
- .ds-file-grid[data-density="compact"] .ds-file-row { padding: 5px 12px; gap: 10px; }
250
+ .ds-file-grid[data-density="compact"] { gap: var(--space-hair); }
251
+ .ds-file-grid[data-density="compact"] .ds-file-row { padding: var(--space-1-5) var(--space-2-75); gap: var(--space-2-5); }
247
252
  .ds-file-grid[data-density="compact"] .ds-file-row .title { font-size: var(--fs-xs); }
248
253
  .ds-file-grid[data-density="compact"] .ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
249
254
  .ds-file-grid[data-density="compact"] .ds-file-icon { width: 20px; height: 20px; font-size: 13px; }
@@ -265,11 +270,14 @@
265
270
  .ds-file-cell.is-locked { opacity: 0.6; }
266
271
  .ds-file-row.is-locked { opacity: 0.6; }
267
272
  .ds-file-row.is-restricted .title { color: var(--fg-2); }
268
- /* A fourth, deliberately bordered/mono tag variant for file-permission tags
273
+ /* 1px vertical pad is deliberately below --space-hair (2px): this mono tag
274
+ sits inline in a file row and must not add height to it; --space-hair would
275
+ double the vertical pad and push the tag past the row cap height.
276
+ A fourth, deliberately bordered/mono tag variant for file-permission tags
269
277
  specifically (distinct from .ds-badge for numeric counts and .chip for
270
278
  status/label words) - is-noaccess reuses the shared --flame tone token
271
279
  so 'no access' reads the same red as chip.tone-error/miss elsewhere. */
272
- .ds-file-perm-tag { font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--fg-3); padding: 1px 6px; border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1); white-space: nowrap; }
280
+ .ds-file-perm-tag { font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--fg-3); padding: 1px var(--space-1-75); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1); white-space: nowrap; }
273
281
  .ds-file-perm-tag.is-noaccess { color: var(--flame); border-color: var(--flame); }
274
282
  .ds-file-cell-open {
275
283
  display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1);
@@ -338,12 +346,12 @@
338
346
 
339
347
  /* Breadcrumb path */
340
348
  .ds-crumb-path {
341
- display: flex; align-items: center; flex-wrap: wrap; gap: 2px;
349
+ display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-hair);
342
350
  font-size: var(--fs-sm);
343
351
  }
344
352
  .ds-crumb-seg {
345
353
  background: transparent; border: 0; cursor: pointer;
346
- padding: 4px 8px; border-radius: var(--r-1);
354
+ padding: var(--space-1) var(--space-2); border-radius: var(--r-1);
347
355
  color: var(--fg-3); font-family: inherit; font-size: var(--fs-sm);
348
356
  transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
349
357
  /* A single long unbroken segment (hash-named dir) must never force the
@@ -391,7 +399,7 @@
391
399
  /* Toolbar-scoped buttons: quiet, compact, rectangular - a toolbar is chrome,
392
400
  not a CTA row; the stadium pill stays for real page-level actions. */
393
401
  .ds-file-toolbar .btn, .ds-file-toolbar .btn-ghost {
394
- padding: 5px 12px; min-height: 32px;
402
+ padding: var(--space-1-5) var(--space-2-75); min-height: 32px;
395
403
  border-radius: var(--r-1);
396
404
  font-weight: 500;
397
405
  background: transparent;
@@ -408,7 +416,7 @@
408
416
 
409
417
  /* Error banner — dismissible toast row. */
410
418
  .ds-error-banner {
411
- padding: 10px 14px; border-radius: var(--r-2);
419
+ padding: var(--space-2-5) var(--space-2-75); border-radius: var(--r-2);
412
420
  background: color-mix(in oklab, var(--warn) 14%, var(--bg));
413
421
  border: var(--bw-hair) solid color-mix(in oklab, var(--warn) 40%, transparent);
414
422
  color: var(--warn); font-size: var(--fs-sm); cursor: pointer;
@@ -465,11 +473,11 @@
465
473
  }
466
474
 
467
475
  /* Upload progress */
468
- .ds-upload-progress { display: flex; flex-direction: column; gap: 6px; }
476
+ .ds-upload-progress { display: flex; flex-direction: column; gap: var(--space-1-75); }
469
477
  .ds-upload-item {
470
478
  display: grid; grid-template-columns: minmax(0, 1fr) 120px 44px;
471
479
  gap: var(--space-2); align-items: center;
472
- padding: 8px 12px; border-radius: var(--r-2);
480
+ padding: var(--space-2) var(--space-2-75); border-radius: var(--r-2);
473
481
  background: var(--bg-2); font-size: var(--fs-xs);
474
482
  }
475
483
  .ds-upload-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -513,7 +521,7 @@
513
521
  }
514
522
  .ds-upload-actions { display: inline-flex; gap: var(--space-1); justify-content: flex-end; }
515
523
  .ds-upload-act {
516
- padding: 2px 10px; min-height: 24px; cursor: pointer;
524
+ padding: var(--space-hair) var(--space-2-5); min-height: 24px; cursor: pointer;
517
525
  background: var(--bg); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
518
526
  color: var(--fg-2); font-family: var(--ff-body); font-size: var(--fs-micro);
519
527
  }
@@ -583,7 +591,7 @@
583
591
  border-top: var(--bw-hair) solid var(--rule);
584
592
  }
585
593
  .ds-modal-input {
586
- width: 100%; padding: 10px 12px;
594
+ width: 100%; padding: var(--space-2-5) var(--space-2-75);
587
595
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule);
588
596
  border-radius: var(--r-2); color: var(--fg);
589
597
  font-family: inherit; font-size: var(--fs-sm);
@@ -595,10 +603,10 @@
595
603
  }
596
604
  /* PromptDialog's optional roots-chip row (destination-path prompts with more
597
605
  than one allowed root) - same chip idiom the cwd editor's roots row uses. */
598
- .ds-prompt-roots { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
606
+ .ds-prompt-roots { display: flex; align-items: center; gap: var(--space-1-75); flex-wrap: wrap; margin-top: var(--space-2); }
599
607
  .ds-prompt-root-chip {
600
608
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
601
- border-radius: var(--r-pill); padding: 3px 10px; font: inherit; font-size: var(--fs-tiny);
609
+ border-radius: var(--r-pill); padding: var(--space-half) var(--space-2-5); font: inherit; font-size: var(--fs-tiny);
602
610
  cursor: pointer;
603
611
  }
604
612
  .ds-prompt-root-chip:hover { border-color: var(--accent); color: var(--fg); }
@@ -607,7 +615,7 @@
607
615
  /* In-body modal error (role=alert): mutation failures (409/403) surface INSIDE
608
616
  the dialog, not behind the fixed overlay. */
609
617
  .ds-modal-error {
610
- margin: var(--space-2) 0 0; padding: 8px 10px;
618
+ margin: var(--space-2) 0 0; padding: var(--space-2) var(--space-2-5);
611
619
  border: var(--bw-hair) solid var(--flame); border-radius: var(--r-2);
612
620
  background: color-mix(in oklab, var(--flame) 12%, var(--bg));
613
621
  color: var(--flame); font-size: var(--fs-xs);
@@ -635,7 +643,7 @@
635
643
  color: var(--fg-3); white-space: nowrap;
636
644
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
637
645
  }
638
- .ds-preview-actions { display: inline-flex; gap: 2px; margin-left: auto; }
646
+ .ds-preview-actions { display: inline-flex; gap: var(--space-hair); margin-left: auto; }
639
647
  .ds-preview-body {
640
648
  flex: 1; min-height: 0; overflow: auto;
641
649
  padding: var(--space-3) var(--space-4);
@@ -722,6 +730,6 @@
722
730
  .ds-file-stage { padding: var(--space-3) var(--space-2); }
723
731
  /* Preview head: let it wrap and drop the nowrap meta (duplicated in body)
724
732
  so the close button can never be pushed past the modal edge. */
725
- .ds-preview-head { flex-wrap: wrap; row-gap: 4px; }
733
+ .ds-preview-head { flex-wrap: wrap; row-gap: var(--space-1); }
726
734
  .ds-preview-meta { display: none; }
727
735
  }