@mingozhou/dsh-replay 0.3.3

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 (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +164 -0
  3. package/README.zh.md +164 -0
  4. package/cordis.patch.yml +6 -0
  5. package/lib/client.js +2478 -0
  6. package/lib/core.js +720 -0
  7. package/lib/index.js +111 -0
  8. package/lib/types/demo/main.d.ts +1 -0
  9. package/lib/types/demo/samples.d.ts +21 -0
  10. package/lib/types/src/client/api.d.ts +43 -0
  11. package/lib/types/src/client/components/AuditView.d.ts +8 -0
  12. package/lib/types/src/client/components/CompareView.d.ts +9 -0
  13. package/lib/types/src/client/components/ForkTreeView.d.ts +7 -0
  14. package/lib/types/src/client/components/ItemDetail.d.ts +6 -0
  15. package/lib/types/src/client/components/OverviewView.d.ts +8 -0
  16. package/lib/types/src/client/components/ReplayApp.d.ts +12 -0
  17. package/lib/types/src/client/components/ReplayModal.d.ts +8 -0
  18. package/lib/types/src/client/components/SessionPicker.d.ts +6 -0
  19. package/lib/types/src/client/components/TimelineView.d.ts +6 -0
  20. package/lib/types/src/client/export.d.ts +13 -0
  21. package/lib/types/src/client/i18n.d.ts +24 -0
  22. package/lib/types/src/client/index.d.ts +12 -0
  23. package/lib/types/src/client/mascot-image.d.ts +1 -0
  24. package/lib/types/src/client/mascot.d.ts +17 -0
  25. package/lib/types/src/client/viewer-entry.d.ts +1 -0
  26. package/lib/types/src/core/audit.d.ts +39 -0
  27. package/lib/types/src/core/compare.d.ts +31 -0
  28. package/lib/types/src/core/cost.d.ts +30 -0
  29. package/lib/types/src/core/decode.d.ts +25 -0
  30. package/lib/types/src/core/forktree.d.ts +33 -0
  31. package/lib/types/src/core/index.d.ts +7 -0
  32. package/lib/types/src/core/timeline.d.ts +96 -0
  33. package/lib/types/src/core/types.d.ts +88 -0
  34. package/lib/types/src/index.d.ts +20 -0
  35. package/lib/viewer.js +812 -0
  36. package/package.json +107 -0
  37. package/scripts/build.mjs +131 -0
  38. package/src/client/api.ts +119 -0
  39. package/src/client/components/AuditView.tsx +57 -0
  40. package/src/client/components/CompareView.tsx +186 -0
  41. package/src/client/components/ForkTreeView.tsx +123 -0
  42. package/src/client/components/ItemDetail.tsx +117 -0
  43. package/src/client/components/OverviewView.tsx +258 -0
  44. package/src/client/components/ReplayApp.tsx +205 -0
  45. package/src/client/components/ReplayModal.tsx +53 -0
  46. package/src/client/components/SessionPicker.tsx +60 -0
  47. package/src/client/components/TimelineView.tsx +296 -0
  48. package/src/client/export.ts +43 -0
  49. package/src/client/i18n.ts +360 -0
  50. package/src/client/index.ts +146 -0
  51. package/src/client/mascot-image.ts +1 -0
  52. package/src/client/mascot.tsx +192 -0
  53. package/src/client/styles.css +719 -0
  54. package/src/client/viewer-entry.tsx +66 -0
  55. package/src/core/audit.ts +227 -0
  56. package/src/core/compare.ts +0 -0
  57. package/src/core/cost.ts +61 -0
  58. package/src/core/decode.ts +125 -0
  59. package/src/core/forktree.ts +104 -0
  60. package/src/core/index.ts +7 -0
  61. package/src/core/timeline.ts +396 -0
  62. package/src/core/types.ts +90 -0
  63. package/src/index.ts +157 -0
  64. package/tsconfig.json +18 -0
  65. package/types.d.ts +15 -0
@@ -0,0 +1,719 @@
1
+ /* dsh-replay UI — chrome rides the harness alias tokens (--dsw-alias-*) with
2
+ standalone fallbacks so the same components render in the demo page.
3
+ Series colors are role-scoped custom properties, stepped per mode. */
4
+
5
+ .dshr-root {
6
+ --dshr-bg: var(--dsw-alias-bg-base, #fcfcfb);
7
+ --dshr-bg-1: var(--dsw-alias-bg-layer-1, #f4f4f2);
8
+ --dshr-bg-2: var(--dsw-alias-bg-layer-2, #ececea);
9
+ --dshr-border: var(--dsw-alias-border-l2, #e1e0d9);
10
+ --dshr-ink: var(--dsw-alias-label-primary, #0b0b0b);
11
+ --dshr-ink-2: var(--dsw-alias-label-secondary, #52514e);
12
+ --dshr-ink-3: var(--dsw-alias-label-tertiary, #898781);
13
+ --dshr-accent: var(--dsw-alias-brand-primary, #4d6bfe);
14
+ --dshr-hover: var(--dsw-alias-interactive-bg-hover, rgba(11, 11, 11, 0.05));
15
+
16
+ /* categorical (fixed order, validated): assistant / tool / user */
17
+ --dshr-s-assistant: #2a78d6;
18
+ --dshr-s-tool: #eb6834;
19
+ --dshr-s-user: #1baf7a;
20
+ --dshr-s-meta: #898781;
21
+ /* status (reserved, never series) */
22
+ --dshr-critical: #d03b3b;
23
+ --dshr-serious: #ec835a;
24
+ --dshr-warning: #fab219;
25
+ --dshr-good: #0ca30c;
26
+
27
+ color: var(--dshr-ink);
28
+ font-size: 13px;
29
+ line-height: 1.45;
30
+ height: 100%;
31
+ display: flex;
32
+ flex-direction: column;
33
+ min-height: 0;
34
+ background: var(--dshr-bg);
35
+ }
36
+
37
+ body[data-ds-dark-theme] .dshr-root,
38
+ [data-theme='dark'] .dshr-root {
39
+ --dshr-bg: var(--dsw-alias-bg-base, #1a1a19);
40
+ --dshr-bg-1: var(--dsw-alias-bg-layer-1, #222221);
41
+ --dshr-bg-2: var(--dsw-alias-bg-layer-2, #2c2c2a);
42
+ --dshr-border: var(--dsw-alias-border-l2, #2c2c2a);
43
+ --dshr-ink: var(--dsw-alias-label-primary, #ffffff);
44
+ --dshr-ink-2: var(--dsw-alias-label-secondary, #c3c2b7);
45
+ --dshr-ink-3: var(--dsw-alias-label-tertiary, #898781);
46
+ --dshr-hover: var(--dsw-alias-interactive-bg-hover, rgba(255, 255, 255, 0.06));
47
+ --dshr-s-assistant: #3987e5;
48
+ --dshr-s-tool: #d95926;
49
+ --dshr-s-user: #199e70;
50
+ }
51
+
52
+ .dshr-root *,
53
+ .dshr-root *::before,
54
+ .dshr-root *::after { box-sizing: border-box; }
55
+
56
+ .dshr-root button {
57
+ font: inherit;
58
+ color: inherit;
59
+ background: none;
60
+ border: none;
61
+ cursor: pointer;
62
+ padding: 0;
63
+ }
64
+
65
+ /* ---- header / nav ---- */
66
+ .dshr-header {
67
+ display: flex;
68
+ align-items: center;
69
+ gap: 12px;
70
+ padding: 8px 14px;
71
+ border-bottom: 1px solid var(--dshr-border);
72
+ flex: none;
73
+ }
74
+ .dshr-title { font-weight: 600; }
75
+ .dshr-tabs { display: flex; gap: 6px; }
76
+ .dshr-tab {
77
+ padding: 4px 10px;
78
+ border-radius: 6px;
79
+ color: var(--dshr-ink-2);
80
+ }
81
+ .dshr-tab:hover { background: var(--dshr-hover); }
82
+ .dshr-tab[data-active='true'] {
83
+ background: var(--dshr-bg-2);
84
+ color: var(--dshr-ink);
85
+ font-weight: 600;
86
+ }
87
+ .dshr-spacer { flex: 1; }
88
+ .dshr-header-stat { color: var(--dshr-ink-3); font-variant-numeric: tabular-nums; }
89
+
90
+ /* ---- states ---- */
91
+ .dshr-center {
92
+ flex: 1;
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ color: var(--dshr-ink-3);
97
+ padding: 32px;
98
+ text-align: center;
99
+ }
100
+
101
+ /* ---- timeline layout ---- */
102
+ .dshr-timeline { flex: 1; display: flex; min-height: 0; }
103
+ .dshr-rail {
104
+ width: 46%;
105
+ min-width: 280px;
106
+ max-width: 560px;
107
+ overflow-y: auto;
108
+ border-right: 1px solid var(--dshr-border);
109
+ padding: 6px 0;
110
+ }
111
+ .dshr-detail { flex: 1; overflow-y: auto; padding: 14px 16px; min-width: 0; }
112
+
113
+ .dshr-item {
114
+ display: flex;
115
+ gap: 8px;
116
+ width: 100%;
117
+ text-align: left;
118
+ padding: 5px 12px 5px 10px;
119
+ border-left: 3px solid transparent;
120
+ align-items: baseline;
121
+ }
122
+ .dshr-item:hover { background: var(--dshr-hover); }
123
+ .dshr-item[data-selected='true'] { background: var(--dshr-bg-2); }
124
+ .dshr-item[data-future='true'] { opacity: 0.32; }
125
+ .dshr-item[data-shadowed='true'] .dshr-item-label { text-decoration: line-through; }
126
+ .dshr-item[data-kind='user'] { border-left-color: var(--dshr-s-user); }
127
+ .dshr-item[data-kind='assistant'] { border-left-color: var(--dshr-s-assistant); }
128
+ .dshr-item[data-kind='tool'] { border-left-color: var(--dshr-s-tool); }
129
+ .dshr-item[data-kind='meta'] { border-left-color: var(--dshr-s-meta); }
130
+
131
+ .dshr-item-kind {
132
+ flex: none;
133
+ width: 62px;
134
+ font-size: 11px;
135
+ color: var(--dshr-ink-3);
136
+ text-transform: uppercase;
137
+ letter-spacing: 0.04em;
138
+ }
139
+ .dshr-item-label {
140
+ flex: 1;
141
+ min-width: 0;
142
+ white-space: nowrap;
143
+ overflow: hidden;
144
+ text-overflow: ellipsis;
145
+ }
146
+ .dshr-item-time {
147
+ flex: none;
148
+ color: var(--dshr-ink-3);
149
+ font-size: 11px;
150
+ font-variant-numeric: tabular-nums;
151
+ }
152
+ .dshr-turn-head {
153
+ padding: 8px 12px 3px;
154
+ font-size: 11px;
155
+ font-weight: 600;
156
+ color: var(--dshr-ink-3);
157
+ text-transform: uppercase;
158
+ letter-spacing: 0.05em;
159
+ display: flex;
160
+ gap: 8px;
161
+ align-items: baseline;
162
+ }
163
+ .dshr-turn-head .dshr-turn-reason { font-weight: 400; text-transform: none; letter-spacing: 0; }
164
+ .dshr-seed-marker {
165
+ margin: 6px 12px;
166
+ padding: 4px 8px;
167
+ border: 1px dashed var(--dshr-border);
168
+ border-radius: 6px;
169
+ color: var(--dshr-ink-3);
170
+ font-size: 11px;
171
+ }
172
+
173
+ /* ---- playback ---- */
174
+ .dshr-playbar {
175
+ display: flex;
176
+ align-items: center;
177
+ gap: 10px;
178
+ padding: 8px 14px;
179
+ border-bottom: 1px solid var(--dshr-border);
180
+ flex: none;
181
+ }
182
+ .dshr-play-btn {
183
+ width: 26px;
184
+ height: 26px;
185
+ border-radius: 50%;
186
+ background: var(--dshr-bg-2);
187
+ display: inline-flex;
188
+ align-items: center;
189
+ justify-content: center;
190
+ font-size: 12px;
191
+ }
192
+ .dshr-play-btn:hover { background: var(--dshr-hover); }
193
+ .dshr-scrub { flex: 1; accent-color: var(--dshr-s-assistant); min-width: 60px; }
194
+ .dshr-speed {
195
+ font-variant-numeric: tabular-nums;
196
+ color: var(--dshr-ink-2);
197
+ padding: 2px 8px;
198
+ border-radius: 6px;
199
+ background: var(--dshr-bg-1);
200
+ }
201
+ .dshr-clock { color: var(--dshr-ink-3); font-variant-numeric: tabular-nums; font-size: 12px; }
202
+
203
+ /* ---- token strip ---- */
204
+ .dshr-tokenstrip { padding: 8px 14px 4px; border-bottom: 1px solid var(--dshr-border); flex: none; }
205
+ .dshr-tokenstrip-head {
206
+ display: flex;
207
+ gap: 14px;
208
+ align-items: baseline;
209
+ font-size: 11px;
210
+ color: var(--dshr-ink-3);
211
+ margin-bottom: 4px;
212
+ }
213
+ .dshr-legend { display: inline-flex; gap: 12px; }
214
+ .dshr-legend-item { display: inline-flex; align-items: center; gap: 5px; color: var(--dshr-ink-2); }
215
+ .dshr-legend-swatch { width: 9px; height: 9px; border-radius: 2px; flex: none; }
216
+ .dshr-bars { display: flex; align-items: flex-end; gap: 2px; height: 48px; }
217
+ .dshr-bar {
218
+ flex: 1;
219
+ min-width: 3px;
220
+ max-width: 26px;
221
+ display: flex;
222
+ flex-direction: column;
223
+ justify-content: flex-end;
224
+ gap: 2px;
225
+ height: 100%;
226
+ background: none;
227
+ }
228
+ .dshr-bar:hover .dshr-bar-in, .dshr-bar:hover .dshr-bar-out { filter: brightness(1.15); }
229
+ .dshr-bar[data-current='true'] .dshr-bar-in,
230
+ .dshr-bar[data-current='true'] .dshr-bar-out { outline: 2px solid var(--dshr-bg); box-shadow: 0 0 0 3px var(--dshr-accent); }
231
+ .dshr-bar-out { background: var(--dshr-s-tool); border-radius: 4px 4px 0 0; min-height: 1px; }
232
+ .dshr-bar-in { background: var(--dshr-s-assistant); border-radius: 0; min-height: 1px; }
233
+
234
+ /* ---- detail panel ---- */
235
+ .dshr-detail h3 {
236
+ margin: 0 0 6px;
237
+ font-size: 13px;
238
+ display: flex;
239
+ gap: 8px;
240
+ align-items: baseline;
241
+ }
242
+ .dshr-badge {
243
+ display: inline-block;
244
+ font-size: 10px;
245
+ padding: 1px 7px;
246
+ border-radius: 999px;
247
+ color: #fff;
248
+ text-transform: uppercase;
249
+ letter-spacing: 0.05em;
250
+ }
251
+ .dshr-detail-meta { color: var(--dshr-ink-3); font-size: 11px; margin-bottom: 10px; font-variant-numeric: tabular-nums; }
252
+ .dshr-pre {
253
+ background: var(--dshr-bg-1);
254
+ border: 1px solid var(--dshr-border);
255
+ border-radius: 8px;
256
+ padding: 10px 12px;
257
+ overflow-x: auto;
258
+ white-space: pre-wrap;
259
+ word-break: break-word;
260
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
261
+ font-size: 12px;
262
+ margin: 0 0 10px;
263
+ max-height: 40vh;
264
+ overflow-y: auto;
265
+ }
266
+ .dshr-kv { display: grid; grid-template-columns: auto 1fr; gap: 3px 14px; margin: 0 0 12px; }
267
+ .dshr-kv dt { color: var(--dshr-ink-3); }
268
+ .dshr-kv dd { margin: 0; font-variant-numeric: tabular-nums; }
269
+ .dshr-section-label {
270
+ font-size: 11px;
271
+ font-weight: 600;
272
+ color: var(--dshr-ink-3);
273
+ text-transform: uppercase;
274
+ letter-spacing: 0.05em;
275
+ margin: 12px 0 5px;
276
+ }
277
+
278
+ /* ---- audit ---- */
279
+ .dshr-audit { flex: 1; overflow-y: auto; padding: 12px 16px; }
280
+ .dshr-audit-summary { display: flex; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
281
+ .dshr-audit-tile {
282
+ border: 1px solid var(--dshr-border);
283
+ border-radius: 10px;
284
+ padding: 8px 14px;
285
+ min-width: 96px;
286
+ }
287
+ .dshr-audit-tile .dshr-count { font-size: 20px; font-weight: 600; }
288
+ .dshr-audit-tile .dshr-cap { font-size: 11px; color: var(--dshr-ink-2); display: flex; align-items: center; gap: 5px; }
289
+ .dshr-finding {
290
+ display: flex;
291
+ gap: 10px;
292
+ width: 100%;
293
+ text-align: left;
294
+ padding: 7px 10px;
295
+ border-radius: 8px;
296
+ align-items: baseline;
297
+ }
298
+ .dshr-finding:hover { background: var(--dshr-hover); }
299
+ .dshr-finding-title { flex: 1; min-width: 0; }
300
+ .dshr-finding-detail {
301
+ color: var(--dshr-ink-3);
302
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
303
+ font-size: 11px;
304
+ white-space: nowrap;
305
+ overflow: hidden;
306
+ text-overflow: ellipsis;
307
+ max-width: 45%;
308
+ }
309
+ .dshr-sev { flex: none; display: inline-flex; align-items: center; gap: 5px; width: 92px; font-size: 11px; }
310
+ .dshr-sev-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
311
+
312
+ /* ---- fork tree ---- */
313
+ .dshr-forks { flex: 1; overflow: auto; padding: 16px; }
314
+ .dshr-fork-svg { min-width: 100%; }
315
+ .dshr-fork-node { cursor: pointer; }
316
+ .dshr-fork-node rect {
317
+ fill: var(--dshr-bg-1);
318
+ stroke: var(--dshr-border);
319
+ rx: 8;
320
+ }
321
+ .dshr-fork-node[data-current='true'] rect { stroke: var(--dshr-accent); stroke-width: 2; }
322
+ .dshr-fork-node:hover rect { fill: var(--dshr-bg-2); }
323
+ .dshr-fork-node text { fill: var(--dshr-ink); font-size: 12px; }
324
+ .dshr-fork-node .dshr-fork-sub { fill: var(--dshr-ink-3); font-size: 10px; }
325
+ .dshr-fork-edge { stroke: var(--dshr-border); stroke-width: 1.5; fill: none; }
326
+ .dshr-fork-edge-label { fill: var(--dshr-ink-3); font-size: 10px; }
327
+
328
+ /* ---- compare ---- */
329
+ .dshr-compare { flex: 1; overflow-y: auto; padding: 14px 16px; }
330
+ .dshr-compare-picker { display: flex; gap: 8px; align-items: center; margin-bottom: 14px; flex-wrap: wrap; }
331
+ .dshr-select {
332
+ font: inherit;
333
+ color: var(--dshr-ink);
334
+ background: var(--dshr-bg-1);
335
+ border: 1px solid var(--dshr-border);
336
+ border-radius: 6px;
337
+ padding: 4px 8px;
338
+ max-width: 340px;
339
+ }
340
+ .dshr-table { border-collapse: collapse; width: 100%; max-width: 720px; }
341
+ .dshr-table th, .dshr-table td {
342
+ text-align: left;
343
+ padding: 5px 12px;
344
+ border-bottom: 1px solid var(--dshr-border);
345
+ font-variant-numeric: tabular-nums;
346
+ }
347
+ .dshr-table th { color: var(--dshr-ink-3); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
348
+ .dshr-table td:not(:first-child) { text-align: right; }
349
+ .dshr-divergence {
350
+ margin: 12px 0;
351
+ padding: 8px 12px;
352
+ border-left: 3px solid var(--dshr-warning);
353
+ background: var(--dshr-bg-1);
354
+ border-radius: 0 8px 8px 0;
355
+ }
356
+
357
+ /* ---- overview dashboard ---- */
358
+ .dshr-overview { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 14px; }
359
+ .dshr-tiles { display: flex; gap: 10px; flex-wrap: wrap; }
360
+ .dshr-tile {
361
+ border: 1px solid var(--dshr-border);
362
+ border-radius: 12px;
363
+ padding: 12px 16px 10px;
364
+ min-width: 118px;
365
+ text-align: left;
366
+ display: flex;
367
+ flex-direction: column;
368
+ gap: 2px;
369
+ background: var(--dshr-bg-1);
370
+ transition: border-color 0.15s ease, transform 0.15s ease;
371
+ }
372
+ .dshr-tile:not([data-static]):hover { border-color: var(--dshr-accent); transform: translateY(-1px); }
373
+ .dshr-tile[data-static] { cursor: default; }
374
+ .dshr-tile-value {
375
+ font-size: 22px;
376
+ font-weight: 650;
377
+ font-variant-numeric: tabular-nums;
378
+ letter-spacing: -0.01em;
379
+ display: flex;
380
+ align-items: baseline;
381
+ gap: 8px;
382
+ }
383
+ .dshr-tile-flag { font-size: 11px; font-weight: 600; color: var(--dshr-critical); }
384
+ .dshr-tile[data-alert] { border-color: color-mix(in srgb, var(--dshr-critical) 45%, var(--dshr-border)); }
385
+ .dshr-tile-label {
386
+ font-size: 11px;
387
+ color: var(--dshr-ink-3);
388
+ text-transform: uppercase;
389
+ letter-spacing: 0.05em;
390
+ }
391
+
392
+ .dshr-panel {
393
+ border: 1px solid var(--dshr-border);
394
+ border-radius: 12px;
395
+ background: var(--dshr-bg-1);
396
+ padding: 12px 14px;
397
+ }
398
+ .dshr-panel-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 8px; }
399
+ .dshr-panel-title {
400
+ font-size: 11px;
401
+ font-weight: 600;
402
+ color: var(--dshr-ink-3);
403
+ text-transform: uppercase;
404
+ letter-spacing: 0.05em;
405
+ }
406
+ .dshr-chart-wrap { position: relative; }
407
+ .dshr-chart { width: 100%; height: auto; display: block; }
408
+ .dshr-grid { stroke: var(--dshr-border); stroke-width: 1; }
409
+ .dshr-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
410
+ .dshr-crosshair { stroke: var(--dshr-ink-3); stroke-width: 1; }
411
+ .dshr-axis-label { fill: var(--dshr-ink-3); font-size: 10px; font-variant-numeric: tabular-nums; }
412
+ .dshr-tooltip {
413
+ position: absolute;
414
+ top: 8px;
415
+ pointer-events: none;
416
+ background: var(--dshr-bg);
417
+ border: 1px solid var(--dshr-border);
418
+ border-radius: 8px;
419
+ padding: 7px 10px;
420
+ font-size: 11px;
421
+ line-height: 1.6;
422
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
423
+ white-space: nowrap;
424
+ font-variant-numeric: tabular-nums;
425
+ }
426
+ .dshr-tooltip-title { color: var(--dshr-ink-3); margin-bottom: 2px; }
427
+ .dshr-tooltip .dshr-legend-swatch { display: inline-block; vertical-align: baseline; }
428
+
429
+ .dshr-hbars { display: flex; flex-direction: column; gap: 6px; }
430
+ .dshr-hbar-row { display: flex; align-items: center; gap: 10px; }
431
+ .dshr-hbar-name {
432
+ width: 110px;
433
+ flex: none;
434
+ text-align: right;
435
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
436
+ font-size: 11px;
437
+ color: var(--dshr-ink-2);
438
+ white-space: nowrap;
439
+ overflow: hidden;
440
+ text-overflow: ellipsis;
441
+ }
442
+ .dshr-hbar-track { flex: 1; height: 14px; display: flex; align-items: center; }
443
+ .dshr-hbar-fill {
444
+ display: block;
445
+ height: 100%;
446
+ max-height: 14px;
447
+ background: var(--dshr-s-assistant);
448
+ border-radius: 0 4px 4px 0;
449
+ min-width: 2px;
450
+ transition: width 0.3s ease;
451
+ }
452
+ .dshr-hbar-value { flex: none; width: 90px; font-variant-numeric: tabular-nums; font-size: 11px; }
453
+ .dshr-hbar-calls { color: var(--dshr-ink-3); }
454
+
455
+ /* ---- polish ---- */
456
+ .dshr-title {
457
+ background: linear-gradient(120deg, var(--dshr-accent), var(--dshr-s-assistant));
458
+ -webkit-background-clip: text;
459
+ background-clip: text;
460
+ -webkit-text-fill-color: transparent;
461
+ color: transparent;
462
+ }
463
+ .dshr-tab[data-active='true'] { box-shadow: inset 0 -2px 0 var(--dshr-accent); border-radius: 6px 6px 2px 2px; }
464
+ .dshr-item { transition: background 0.12s ease; }
465
+ .dshr-bar-in, .dshr-bar-out { transition: height 0.25s ease; }
466
+ .dshr-play-btn[data-playing='true'] { animation: dshr-pulse 1.6s ease-in-out infinite; }
467
+ @keyframes dshr-pulse {
468
+ 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--dshr-accent) 45%, transparent); }
469
+ 50% { box-shadow: 0 0 0 6px transparent; }
470
+ }
471
+
472
+ /* ---- sidebar button / modal / picker / filter / mascot ---- */
473
+ /* Matches the official sidebar footer entries (e.g. the settings trigger):
474
+ font, size, and color are fully INHERITED from the surrounding sidebar,
475
+ icon is 16×16 like the settings gear. */
476
+ .dshr-sidebar-btn {
477
+ display: flex;
478
+ align-items: center;
479
+ gap: 8px;
480
+ width: 100%;
481
+ padding: 6px 8px;
482
+ border-radius: 8px;
483
+ font: inherit;
484
+ color: inherit;
485
+ background: none;
486
+ border: none;
487
+ cursor: pointer;
488
+ text-align: left;
489
+ }
490
+ .dshr-sidebar-btn:hover {
491
+ background: var(--dsw-alias-interactive-bg-hover, rgba(11, 11, 11, 0.05));
492
+ }
493
+
494
+ .dshr-modal-backdrop {
495
+ position: fixed;
496
+ inset: 0;
497
+ background: rgba(10, 12, 24, 0.45);
498
+ backdrop-filter: blur(3px);
499
+ z-index: 1000;
500
+ display: flex;
501
+ align-items: center;
502
+ justify-content: center;
503
+ pointer-events: auto;
504
+ }
505
+ .dshr-modal {
506
+ width: min(1240px, 94vw);
507
+ height: min(820px, 92vh);
508
+ background: var(--dsw-alias-bg-base, #fcfcfb);
509
+ border: 1px solid var(--dsw-alias-border-l2, #e1e0d9);
510
+ border-radius: 14px;
511
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.35);
512
+ display: flex;
513
+ flex-direction: column;
514
+ overflow: hidden;
515
+ animation: dshr-modal-in 0.18s ease;
516
+ }
517
+ @keyframes dshr-modal-in {
518
+ from { transform: translateY(10px) scale(0.985); opacity: 0; }
519
+ to { transform: none; opacity: 1; }
520
+ }
521
+ .dshr-modal-chrome {
522
+ display: flex;
523
+ align-items: center;
524
+ gap: 8px;
525
+ padding: 8px 14px;
526
+ border-bottom: 1px solid var(--dsw-alias-border-l2, #e1e0d9);
527
+ flex: none;
528
+ font-size: 13px;
529
+ font-weight: 600;
530
+ color: var(--dsw-alias-label-primary, #0b0b0b);
531
+ }
532
+ .dshr-modal-chrome .dshr-spacer { flex: 1; }
533
+ .dshr-modal-close {
534
+ border: none;
535
+ background: none;
536
+ cursor: pointer;
537
+ font-size: 14px;
538
+ color: var(--dsw-alias-label-tertiary, #898781);
539
+ padding: 4px 8px;
540
+ border-radius: 6px;
541
+ }
542
+ .dshr-modal-close:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(11, 11, 11, 0.05)); }
543
+ .dshr-modal-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
544
+ .dshr-modal-body > .dshr-root { flex: 1; }
545
+
546
+ .dshr-picker { flex: 1; overflow-y: auto; padding: 12px 16px; }
547
+ .dshr-picker-row {
548
+ display: grid;
549
+ grid-template-columns: 1fr auto;
550
+ grid-template-areas: 'title age' 'sub age';
551
+ gap: 1px 12px;
552
+ width: 100%;
553
+ text-align: left;
554
+ padding: 8px 12px;
555
+ border-radius: 10px;
556
+ align-items: center;
557
+ }
558
+ .dshr-picker-row:hover { background: var(--dshr-hover); }
559
+ .dshr-picker-title { grid-area: title; font-weight: 550; display: flex; gap: 8px; align-items: baseline; }
560
+ .dshr-picker-tag {
561
+ font-size: 10px;
562
+ padding: 0 7px;
563
+ border-radius: 999px;
564
+ background: var(--dshr-bg-2);
565
+ color: var(--dshr-ink-3);
566
+ text-transform: uppercase;
567
+ letter-spacing: 0.04em;
568
+ }
569
+ .dshr-picker-sub {
570
+ grid-area: sub;
571
+ color: var(--dshr-ink-3);
572
+ font-size: 11px;
573
+ white-space: nowrap;
574
+ overflow: hidden;
575
+ text-overflow: ellipsis;
576
+ }
577
+ .dshr-picker-age { grid-area: age; color: var(--dshr-ink-3); font-size: 11px; font-variant-numeric: tabular-nums; }
578
+
579
+ .dshr-filter-input {
580
+ font: inherit;
581
+ font-size: 12px;
582
+ color: var(--dshr-ink);
583
+ background: var(--dshr-bg-1);
584
+ border: 1px solid var(--dshr-border);
585
+ border-radius: 999px;
586
+ padding: 3px 12px;
587
+ width: 150px;
588
+ outline: none;
589
+ }
590
+ .dshr-filter-input:focus { border-color: var(--dshr-accent); }
591
+ .dshr-kind-chips { display: inline-flex; gap: 4px; }
592
+ .dshr-kind-chip {
593
+ display: inline-flex;
594
+ align-items: center;
595
+ gap: 5px;
596
+ font-size: 11px;
597
+ padding: 2px 9px;
598
+ border-radius: 999px;
599
+ border: 1px solid var(--dshr-border);
600
+ color: var(--dshr-ink-3);
601
+ opacity: 0.55;
602
+ }
603
+ .dshr-kind-chip[data-on] { opacity: 1; color: var(--dshr-ink-2); background: var(--dshr-bg-1); }
604
+ .dshr-kind-chip .dshr-kind-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dshr-s-meta); }
605
+ .dshr-kind-chip[data-kind='user'] .dshr-kind-dot { background: var(--dshr-s-user); }
606
+ .dshr-kind-chip[data-kind='assistant'] .dshr-kind-dot { background: var(--dshr-s-assistant); }
607
+ .dshr-kind-chip[data-kind='tool'] .dshr-kind-dot { background: var(--dshr-s-tool); }
608
+
609
+ .dshr-mascot { flex: none; }
610
+ .dshr-mascot-state .dshr-mascot { animation: dshr-float 2.6s ease-in-out infinite; }
611
+ .dshr-mascot-state > div { text-align: center; }
612
+ .dshr-mascot-text { margin-top: 6px; color: var(--dshr-ink-3); }
613
+ @keyframes dshr-float {
614
+ 0%, 100% { transform: translateY(0); }
615
+ 50% { transform: translateY(-5px); }
616
+ }
617
+
618
+ /* ---- v0.3 layout fixes ---- */
619
+ .dshr-compare-grid { display: flex; gap: 28px; flex-wrap: wrap; align-items: flex-start; }
620
+ .dshr-compare-grid > table, .dshr-compare-grid > div { flex: 1 1 420px; max-width: 640px; }
621
+ .dshr-compare-grid .dshr-section-label { margin-top: 0; }
622
+ .dshr-modal-github {
623
+ display: inline-flex;
624
+ align-items: center;
625
+ gap: 6px;
626
+ font-size: 12px;
627
+ font-weight: 500;
628
+ color: var(--dsw-alias-label-secondary, #52514e);
629
+ text-decoration: none;
630
+ padding: 4px 10px;
631
+ border-radius: 6px;
632
+ }
633
+ .dshr-modal-github:hover {
634
+ background: var(--dsw-alias-interactive-bg-hover, rgba(11, 11, 11, 0.05));
635
+ color: var(--dsw-alias-label-primary, #0b0b0b);
636
+ }
637
+
638
+ /* ---- fork view v2: family trees + card grid ---- */
639
+ .dshr-forks { flex: 1; overflow-y: auto; padding: 14px 16px; }
640
+ .dshr-forks-hint {
641
+ color: var(--dshr-ink-3);
642
+ font-size: 12px;
643
+ margin-bottom: 12px;
644
+ padding: 8px 12px;
645
+ background: var(--dshr-bg-1);
646
+ border-radius: 8px;
647
+ border: 1px solid var(--dshr-border);
648
+ }
649
+ .dshr-forkgrid {
650
+ display: grid;
651
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
652
+ gap: 10px;
653
+ }
654
+ .dshr-family { margin-bottom: 14px; }
655
+ .dshr-family-node > .dshr-forkcard { display: flex; }
656
+ .dshr-branch {
657
+ margin-left: 22px;
658
+ padding-left: 18px;
659
+ border-left: 2px solid var(--dshr-border);
660
+ margin-top: 8px;
661
+ position: relative;
662
+ }
663
+ .dshr-branch::before {
664
+ content: '';
665
+ position: absolute;
666
+ left: 0;
667
+ top: 22px;
668
+ width: 14px;
669
+ border-top: 2px solid var(--dshr-border);
670
+ }
671
+ .dshr-forkcard {
672
+ display: flex;
673
+ flex-direction: column;
674
+ gap: 2px;
675
+ text-align: left;
676
+ width: 100%;
677
+ max-width: 560px;
678
+ padding: 10px 14px;
679
+ border: 1px solid var(--dshr-border);
680
+ border-radius: 10px;
681
+ background: var(--dshr-bg-1);
682
+ transition: border-color 0.15s ease, transform 0.15s ease;
683
+ }
684
+ .dshr-forkcard:hover { border-color: var(--dshr-accent); transform: translateY(-1px); }
685
+ .dshr-forkcard[data-current] { border-color: var(--dshr-accent); box-shadow: 0 0 0 1px var(--dshr-accent); }
686
+ .dshr-forkcard-title {
687
+ font-weight: 550;
688
+ white-space: nowrap;
689
+ overflow: hidden;
690
+ text-overflow: ellipsis;
691
+ }
692
+ .dshr-forkcard-sub {
693
+ color: var(--dshr-ink-3);
694
+ font-size: 11px;
695
+ font-variant-numeric: tabular-nums;
696
+ white-space: nowrap;
697
+ overflow: hidden;
698
+ text-overflow: ellipsis;
699
+ }
700
+
701
+ /* specificity override: the .dshr-root button reset must not strip card chrome */
702
+ .dshr-root .dshr-forkcard {
703
+ border: 1px solid var(--dshr-border);
704
+ background: var(--dshr-bg-1);
705
+ padding: 10px 14px;
706
+ border-radius: 10px;
707
+ }
708
+ .dshr-root .dshr-forkcard[data-current] {
709
+ border-color: var(--dshr-accent);
710
+ box-shadow: 0 0 0 1px var(--dshr-accent);
711
+ }
712
+ .dshr-root .dshr-picker-row {
713
+ border: 1px solid var(--dshr-border);
714
+ background: var(--dshr-bg-1);
715
+ border-radius: 10px;
716
+ padding: 8px 12px;
717
+ margin-bottom: 8px;
718
+ }
719
+ .dshr-root .dshr-picker-row:hover { border-color: var(--dshr-accent); }