omkit 0.8.14 → 0.8.16

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.
@@ -1,376 +1,480 @@
1
- :root {
2
- --bg: #0b1020;
3
- --panel: #111831;
4
- --panel-2: #0e152b;
5
- --raise: #18213f;
6
- --line: #222c4d;
7
- --line-soft: #1a2342;
8
- --text: #e6eaf5;
9
- --text-2: #a9b2cc;
10
- --text-3: #6f7a99;
11
- --accent: #3b82f6;
12
- --accent-soft: rgba(59, 130, 246, 0.18);
13
- --ok: #22c55e;
14
- --fail: #ef4444;
15
- --cancel: #f59e0b;
16
- --running: #38bdf8;
17
- --c1: #4f8ff7;
18
- --c2: #8b5cf6;
19
- --c3: #22c55e;
20
- --c4: #f59e0b;
21
- --c5: #f0568c;
22
- --c6: #22d3ee;
23
- --c7: #a3e635;
24
- --c8: #fb7185;
25
- --bar-text: #0b1020;
26
- --shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
27
- --mono: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;
28
- --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
29
- color-scheme: dark;
30
- }
31
- :root[data-theme="light"] {
32
- --bg: #f4f6fb;
33
- --panel: #ffffff;
34
- --panel-2: #f8f9fc;
35
- --raise: #eef1f8;
36
- --line: #dde2ee;
37
- --line-soft: #e9ecf4;
38
- --text: #182033;
39
- --text-2: #4b5672;
40
- --text-3: #8590ab;
41
- --accent: #2563eb;
42
- --accent-soft: rgba(37, 99, 235, 0.12);
43
- --bar-text: #0b1020;
44
- --shadow: 0 10px 30px rgba(20, 30, 60, 0.15);
45
- color-scheme: light;
46
- }
47
- @media (prefers-color-scheme: light) {
48
- :root:not([data-theme="dark"]) {
49
- --bg: #f4f6fb;
50
- --panel: #ffffff;
51
- --panel-2: #f8f9fc;
52
- --raise: #eef1f8;
53
- --line: #dde2ee;
54
- --line-soft: #e9ecf4;
55
- --text: #182033;
56
- --text-2: #4b5672;
57
- --text-3: #8590ab;
58
- --accent: #2563eb;
59
- --accent-soft: rgba(37, 99, 235, 0.12);
60
- --shadow: 0 10px 30px rgba(20, 30, 60, 0.15);
61
- color-scheme: light;
62
- }
63
- }
64
-
65
- * { box-sizing: border-box; }
66
- html, body { margin: 0; height: 100%; }
67
- body {
68
- background: var(--bg);
69
- color: var(--text);
70
- font: 13px/1.4 var(--sans);
71
- overflow: hidden;
72
- }
73
- button { font: inherit; color: inherit; }
74
- [hidden] { display: none !important; }
75
-
76
- /* ── loader ─────────────────────────────────────────────── */
77
- #loader {
78
- position: fixed; inset: 0; display: grid; place-items: center;
79
- background: var(--bg); z-index: 100;
80
- }
81
- .loader-card { display: grid; justify-items: center; gap: 14px; }
82
- .loader-spin {
83
- width: 42px; height: 42px; border-radius: 50%;
84
- border: 3px solid var(--line); border-top-color: var(--accent);
85
- animation: spin 0.9s linear infinite;
86
- }
87
- .loader-title { font-size: 16px; font-weight: 600; }
88
- .loader-step { color: var(--text-3); font-size: 12px; }
89
- @keyframes spin { to { transform: rotate(360deg); } }
90
-
91
- /* ── shell ──────────────────────────────────────────────── */
92
- #app {
93
- height: 100vh; display: grid; gap: 10px; padding: 12px 14px 14px;
94
- grid-template-rows: auto minmax(0, 1fr) 230px;
95
- }
96
- .top { display: flex; align-items: center; gap: 14px; min-width: 0; }
97
- .top .titles { min-width: 0; flex: 1; }
98
- .top h1 { margin: 0; font-size: 19px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
99
- .top .meta { color: var(--text-2); display: flex; gap: 10px; align-items: center; margin-top: 3px; flex-wrap: wrap; }
100
- .top .meta .sep { color: var(--text-3); }
101
- .dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; }
102
- .dot.ok { background: var(--ok); }
103
- .dot.failed { background: var(--fail); }
104
- .dot.cancelled { background: var(--cancel); }
105
- .dot.running { background: var(--running); }
106
-
107
- .btn-group { display: flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--panel); }
108
- .btn {
109
- border: 0; background: transparent; padding: 7px 12px; cursor: pointer;
110
- display: inline-flex; align-items: center; gap: 7px; color: var(--text-2); white-space: nowrap;
111
- }
112
- .btn + .btn { border-left: 1px solid var(--line); }
113
- .btn:hover { background: var(--raise); color: var(--text); }
114
- .btn.active { background: var(--accent); color: #fff; }
115
- .btn svg { width: 15px; height: 15px; }
116
- .btn.solo { border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
117
-
118
- .main {
119
- display: grid; gap: 10px; min-height: 0;
120
- grid-template-columns: minmax(0, 1fr) 320px;
121
- }
122
- .main.no-details { grid-template-columns: minmax(0, 1fr); }
123
- .card { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; min-height: 0; min-width: 0; }
124
-
125
- /* ── timeline: tree + chart share one vertical scroll ──── */
126
- .timeline { display: grid; grid-template-rows: 34px minmax(0, 1fr); overflow: hidden; }
127
- .tl-head { display: grid; grid-template-columns: var(--tree-w, 420px) minmax(0, 1fr); border-bottom: 1px solid var(--line); }
128
- .tl-head .cols { display: grid; grid-template-columns: minmax(0, 1fr) 84px 82px; align-items: center; border-right: 1px solid var(--line); }
129
- .tl-head .cols > div { padding: 0 12px; color: var(--text-2); font-weight: 600; font-size: 12px; }
130
- .tl-head .cols > div + div { border-left: 1px solid var(--line-soft); height: 100%; display: flex; align-items: center; }
131
- .tl-head svg { display: block; width: 100%; height: 34px; }
132
- .tl-body { overflow: auto; display: grid; grid-template-columns: var(--tree-w, 420px) minmax(0, 1fr); align-items: start; position: relative; }
133
- .timeline.no-tree .tl-head, .timeline.no-tree .tl-body { grid-template-columns: minmax(0, 1fr); }
134
- .timeline.no-tree .tree, .timeline.no-tree .tl-head .cols { display: none; }
135
-
136
- .tree { border-right: 1px solid var(--line); position: sticky; left: 0; background: var(--panel); z-index: 2; }
137
- .row {
138
- height: var(--row-h); display: grid; grid-template-columns: minmax(0, 1fr) 84px 82px;
139
- align-items: center; cursor: pointer; border-bottom: 1px solid transparent;
140
- }
141
- .row:hover { background: var(--raise); }
142
- .row.selected { background: var(--accent-soft); }
143
- .row .name { display: flex; align-items: center; gap: 7px; min-width: 0; padding-right: 8px; }
144
- .row .name .label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
145
- .row .name .tagchip { color: var(--text-3); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
146
- .row .twist { width: 16px; height: 16px; flex: none; display: grid; place-items: center; color: var(--text-3); border: 0; background: none; padding: 0; cursor: pointer; }
147
- .row .twist svg { width: 12px; height: 12px; transition: transform 0.12s; }
148
- .row .twist.open svg { transform: rotate(90deg); }
149
- .row .icon { width: 22px; height: 22px; flex: none; display: grid; place-items: center; border-radius: 6px; }
150
- .row .icon svg { width: 14px; height: 14px; }
151
- .row .status, .row .dur { padding: 0 12px; display: flex; align-items: center; gap: 7px; color: var(--text-2); font-variant-numeric: tabular-nums; }
152
- .guide { width: 14px; flex: none; align-self: stretch; position: relative; }
153
- .guide::before { content: ""; position: absolute; left: 7px; top: 0; bottom: 0; border-left: 1px solid var(--line); }
154
-
155
- .chart { position: relative; min-width: 0; }
156
- .chart svg { display: block; overflow: hidden; }
157
- .chart .bar-label { font-size: 12px; fill: var(--bar-text); font-weight: 500; cursor: pointer; }
158
- .chart .hit { fill: transparent; cursor: pointer; }
159
- .chart .hit:hover + .bar { filter: brightness(1.15); }
160
- .chart .bar-label.outside { fill: var(--text); }
161
- .chart .mark-label { font-size: 11px; fill: var(--text-2); cursor: pointer; }
162
- .chart .mark-label:hover { fill: var(--text); }
163
- .chart .grid line { stroke: var(--line-soft); }
164
- .chart .cursor { stroke: var(--text-2); stroke-dasharray: 3 3; pointer-events: none; }
165
- .chart .link { fill: none; stroke: var(--text-3); stroke-width: 1.2; }
166
- .chart .bar { cursor: pointer; }
167
- .chart .bar.selected { stroke: var(--text); stroke-width: 2; }
168
- .chart .mark { cursor: pointer; stroke: var(--panel); stroke-width: 1.5; }
169
- .axis text { fill: var(--text-2); font-size: 11px; }
170
- .axis line, .axis path { stroke: var(--line); }
171
-
172
- .flow-view, .flame-view { position: absolute; inset: 0; }
173
- .flow-view svg, .flame-view svg { width: 100%; height: 100%; display: block; cursor: grab; }
174
- .flow-card rect.box { fill: var(--raise); stroke: var(--line); rx: 8; }
175
- .flow-card.selected rect.box { stroke: var(--accent); stroke-width: 2; }
176
- .flow-card text { fill: var(--text); font-size: 12px; }
177
- .flow-card text.sub { fill: var(--text-3); font-size: 11px; }
178
- .flow-link { fill: none; stroke: var(--text-3); stroke-width: 1.3; }
179
- .flame-rect { cursor: pointer; stroke: var(--panel); stroke-width: 1; }
180
- .flame-rect.selected { stroke: var(--text); stroke-width: 2; }
181
- .flame-text { font-size: 11px; fill: var(--bar-text); cursor: pointer; }
182
-
183
- /* ── details ────────────────────────────────────────────── */
184
- .details { display: grid; grid-template-rows: auto auto minmax(0, 1fr); overflow: hidden; }
185
- .details .dh { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; font-weight: 600; }
186
- .details .x { border: 0; background: none; cursor: pointer; color: var(--text-2); padding: 2px; }
187
- .details .who { display: flex; align-items: center; gap: 10px; padding: 4px 14px 10px; }
188
- .details .who .icon { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; flex: none; }
189
- .details .who .icon svg { width: 16px; height: 16px; }
190
- .details .who .nm { font-size: 16px; font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
191
- .pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; background: var(--raise); font-size: 12px; }
192
- .details .scroll { overflow: auto; padding: 0 14px 14px; }
193
- .kv { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 6px 10px; margin: 2px 0 12px; }
194
- .kv .k { color: var(--text-2); }
195
- .kv .v { min-width: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
196
- a { color: var(--accent); text-decoration: none; }
197
- a:hover { text-decoration: underline; }
198
- .tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); margin: 0 0 10px; overflow-x: auto; }
199
- .tab { border: 0; background: none; padding: 7px 9px; cursor: pointer; color: var(--text-2); border-bottom: 2px solid transparent; white-space: nowrap; }
200
- .tab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; }
201
- .section-title { font-weight: 600; margin: 14px 0 8px; }
202
- .ev-list { list-style: none; margin: 0; padding: 0; position: relative; }
203
- .ev-list li { display: grid; grid-template-columns: 64px 18px minmax(0, 1fr); gap: 8px; align-items: start; padding: 4px 0; }
204
- .ev-list .t { color: var(--text-2); font-variant-numeric: tabular-nums; text-align: right; }
205
- .ev-list .m { overflow-wrap: anywhere; }
206
- .ev-ico { width: 16px; height: 16px; border-radius: 50%; display: grid; place-items: center; margin-top: 1px; }
207
- .ev-ico svg { width: 10px; height: 10px; }
208
- pre.code {
209
- margin: 0; padding: 10px; background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 8px;
210
- font: 12px/1.45 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; max-height: 60vh; overflow: auto;
211
- }
212
- .muted { color: var(--text-3); }
213
- .thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; }
214
- .thumb { border: 1px solid var(--line); border-radius: 6px; overflow: hidden; cursor: pointer; background: var(--panel-2); aspect-ratio: 16 / 10; display: grid; place-items: center; }
215
- .thumb:hover { border-color: var(--accent); }
216
- .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
217
- .thumb .json-ico { font: 600 12px var(--mono); color: var(--text-3); }
218
-
219
- /* ── bottom strip ───────────────────────────────────────── */
220
- .bottom { display: grid; gap: 10px; grid-template-columns: minmax(0, 1fr) 270px 250px; min-height: 0; }
221
- .lower { display: grid; grid-template-rows: auto minmax(0, 1fr); overflow: hidden; }
222
- .lower .tabs { margin: 0; padding: 0 10px; align-items: center; }
223
- .lower .tabs .spacer { flex: 1; }
224
- .filter { border: 1px solid var(--line); background: var(--panel-2); border-radius: 7px; padding: 5px 9px; color: var(--text); width: 200px; margin: 4px 0; }
225
- .lower .body { overflow: auto; padding: 10px 12px; }
226
- .gallery { display: flex; gap: 12px; }
227
- .gal-item { flex: none; width: 160px; cursor: pointer; border: 1px solid transparent; border-radius: 8px; padding: 4px; }
228
- .gal-item:hover, .gal-item.active { border-color: var(--accent); background: var(--accent-soft); }
229
- .gal-item .thumb { aspect-ratio: 16 / 10; }
230
- .gal-item .cap { display: flex; gap: 8px; margin-top: 5px; font-size: 12px; }
231
- .gal-item .cap .t { color: var(--text-2); font-variant-numeric: tabular-nums; }
232
- .gal-item .cap .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
233
- .gal-item .sz { color: var(--text-3); font-size: 11px; }
234
- table.list { width: 100%; border-collapse: collapse; font-size: 12px; }
235
- table.list td { padding: 3px 8px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
236
- table.list td.t { color: var(--text-2); white-space: nowrap; font-variant-numeric: tabular-nums; width: 1%; }
237
- table.list td.p { color: var(--text-3); white-space: nowrap; max-width: 260px; overflow: hidden; text-overflow: ellipsis; width: 1%; }
238
- table.list td.m { font-family: var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
239
- table.list tr.err td.m { color: var(--fail); }
240
- table.list tr { cursor: pointer; }
241
- table.list tr:hover td { background: var(--raise); }
242
- .legend { padding: 10px 14px; }
243
- .legend h3, .overview h3 { margin: 0 0 10px; font-size: 13px; font-weight: 600; }
244
- .legend .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 12px; }
245
- .legend .li { display: flex; align-items: center; gap: 8px; color: var(--text-2); font-size: 12px; }
246
- .overview { padding: 10px 14px; display: grid; grid-template-rows: auto auto minmax(0, 1fr); }
247
- .overview .range { color: var(--text-2); font-size: 11px; text-align: right; margin-bottom: 4px; font-variant-numeric: tabular-nums; }
248
- .overview svg { width: 100%; height: 100%; display: block; }
249
- .overview .brush .selection { fill: var(--accent-soft); stroke: var(--text-2); }
250
-
251
- /* ── floating ───────────────────────────────────────────── */
252
- .tip {
253
- position: fixed; pointer-events: none; z-index: 50; background: var(--panel); border: 1px solid var(--line);
254
- border-radius: 8px; padding: 8px 10px; box-shadow: var(--shadow); max-width: 360px; font-size: 12px;
255
- }
256
- .tip .tt { font-weight: 600; margin-bottom: 2px; }
257
- .tip .ts { color: var(--text-2); }
258
- .tip.wide { max-width: 420px; min-width: 260px; }
259
- .tip .mono { font-family: var(--mono); font-size: 11px; overflow-wrap: anywhere; }
260
- .tip .small { color: var(--text-2); }
261
- .tip .badges { display: flex; flex-wrap: wrap; gap: 5px; margin: 6px 0; }
262
- .tip .badge { display: inline-flex; align-items: center; gap: 5px; padding: 1px 8px; border-radius: 999px; background: var(--raise); font-size: 11px; color: var(--text-2); }
263
- .tip .badge.mcp { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
264
- .tip .summary { margin: 4px 0 8px; line-height: 1.45; }
265
- .tip .tkv { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 10px; font-variant-numeric: tabular-nums; }
266
- .tip .tkv .k, .tip .sec { color: var(--text-3); }
267
- .tip .sec { margin: 8px 0 3px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
268
- .tip .sec.fail { color: var(--fail); }
269
- .params { display: grid; gap: 3px; }
270
- .param { font: 11px/1.4 var(--mono); }
271
- .param .pn { color: var(--text); }
272
- .param .pt { color: var(--accent); margin-left: 6px; }
273
- .param .pd { color: var(--text-3); margin-left: 6px; }
274
- .param .pdesc { font-family: var(--sans); color: var(--text-2); margin-left: 10px; }
275
- .kv .v.defined { display: flex; align-items: center; gap: 6px; }
276
- .kv .v.defined a { min-width: 0; overflow-wrap: anywhere; font-family: var(--mono); font-size: 12px; }
277
- .icon-btn { flex: none; border: 1px solid var(--line); background: var(--panel-2); color: var(--text-2); border-radius: 6px; width: 24px; height: 22px; display: grid; place-items: center; cursor: pointer; padding: 0; }
278
- .icon-btn:hover { color: var(--text); border-color: var(--accent); }
279
- .icon-btn svg { width: 13px; height: 13px; }
280
- .tip .hint { margin-top: 8px; color: var(--text-3); font-size: 11px; }
281
- .tip kbd { font: 600 10px var(--mono); border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px; padding: 0 4px; color: var(--text-2); }
282
- .badge-inline { display: inline-block; padding: 0 7px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); font-size: 11px; font-weight: 600; }
283
- .tip img { display: block; max-width: 240px; max-height: 150px; border-radius: 4px; margin: 6px 0; border: 1px solid var(--line); }
284
- .modal { position: fixed; inset: 0; background: rgba(5, 8, 18, 0.72); z-index: 60; display: grid; place-items: center; padding: 28px; }
285
- .modal .box { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow); max-width: min(1200px, 100%); max-height: 100%; display: grid; grid-template-rows: auto minmax(0, 1fr); overflow: hidden; }
286
- .modal .mh { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--line); }
287
- .modal .mh .nm { font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
288
- .modal .mb { overflow: auto; padding: 14px; }
289
- .modal img { max-width: 100%; display: block; margin: auto; }
290
- .menu { position: fixed; z-index: 55; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow); padding: 4px; min-width: 200px; }
291
- .menu button { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 7px 10px; border-radius: 6px; cursor: pointer; }
292
- .menu button:hover { background: var(--raise); }
293
- .toast { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); background: var(--raise); border: 1px solid var(--line); padding: 7px 14px; border-radius: 8px; z-index: 70; }
294
-
295
- /* ── title info, locate, defined-at, code popover ───────── */
296
- .title-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
297
- .title-row h1 { min-width: 0; }
298
- .info-btn { flex: none; width: 22px; height: 22px; border: 0; border-radius: 50%; background: none; color: var(--text-3); display: grid; place-items: center; cursor: help; padding: 0; }
299
- .info-btn:hover, .info-btn:focus-visible { color: var(--accent); background: var(--accent-soft); }
300
- .info-btn svg { width: 17px; height: 17px; }
301
- .gal-item .cap .locate { margin-left: auto; width: 22px; height: 20px; }
302
- .kv .v.defined { flex-wrap: wrap; }
303
- .kv .v.defined .defined-name { color: var(--text-2); font-family: var(--mono); font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
304
- a.icon-btn { text-decoration: none; }
305
- .chart .code-btn, .flow-card .code-btn { cursor: pointer; opacity: 0; transition: opacity 0.12s; }
306
- .chart g.r:hover .code-btn, .chart g.r.sel .code-btn, .flow-card:hover .code-btn, .flow-card.selected .code-btn { opacity: 1; }
307
- .code-btn circle { fill: var(--panel); stroke: var(--text-3); stroke-width: 1.2; }
308
- .code-btn text { fill: var(--text-2); font: 700 9px var(--mono); pointer-events: none; }
309
- .code-btn:hover circle { stroke: var(--accent); }
310
- .code-btn:hover text { fill: var(--accent); }
311
- .chart line.pin.flash, .flame-view line.pin.flash { animation: pin-flash 0.6s ease-in-out 3; }
312
- .chart circle.mark.flash { animation: mark-flash 0.6s ease-in-out 3; transform-box: fill-box; transform-origin: center; }
313
- @keyframes pin-flash { 50% { stroke-width: 5; } }
314
- @keyframes mark-flash { 50% { transform: scale(1.9); } }
315
- .code-pop {
316
- position: fixed; z-index: 58; width: 640px; max-width: 92vw; max-height: 70vh; display: flex; flex-direction: column;
317
- background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); overflow: hidden;
318
- }
319
- .code-pop .cp-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px 6px 12px; background: var(--panel-2); border-bottom: 1px solid var(--line); }
320
- .code-pop .cp-path { font: 12px var(--mono); color: var(--text-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
321
- .code-pop .cp-name { flex: 1; text-align: right; color: var(--text-3); font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
322
- .code-pop .cp-body { overflow: auto; min-height: 0; }
323
- .code-pop .cp-code { font: 11.5px/1.65 var(--mono); padding: 8px 0; min-width: max-content; }
324
- .code-pop .cl { display: grid; grid-template-columns: 48px auto; white-space: pre; }
325
- .code-pop .cl.at { background: var(--accent-soft); }
326
- .code-pop .ln { color: var(--text-3); text-align: right; padding-right: 14px; user-select: none; }
327
- .code-pop .lc { padding-right: 16px; }
328
- .code-pop .cp-more { padding: 6px 14px 10px; font-size: 12px; }
329
- :root { --tk-c: #6f7a99; --tk-s: #7ee0a3; --tk-n: #f0b26b; --tk-k: #c792ea; --tk-f: #82aaff; --tk-t: #ffcb6b; }
330
- :root[data-theme="light"] { --tk-c: #6a737d; --tk-s: #116329; --tk-n: #b35900; --tk-k: #cf222e; --tk-f: #6639ba; --tk-t: #953800; }
331
- @media (prefers-color-scheme: light) {
332
- :root:not([data-theme="dark"]) { --tk-c: #6a737d; --tk-s: #116329; --tk-n: #b35900; --tk-k: #cf222e; --tk-f: #6639ba; --tk-t: #953800; }
333
- }
334
- .tk-c { color: var(--tk-c); font-style: italic; }
335
- .tk-s { color: var(--tk-s); }
336
- .tk-n { color: var(--tk-n); }
337
- .tk-k { color: var(--tk-k); }
338
- .tk-f { color: var(--tk-f); }
339
- .tk-t { color: var(--tk-t); }
340
- .tk-p { color: var(--tk-f); }
341
-
342
- /* ── popover tabs, prompt panel, flow snapshot strip ───── */
343
- .code-pop .cp-tabs { display: flex; gap: 2px; padding: 0 8px; border-bottom: 1px solid var(--line); background: var(--panel-2); }
344
- .code-pop .cp-tabs .tab { padding: 6px 9px; font-size: 12px; }
345
- .pp { padding: 12px 14px 14px; display: grid; gap: 10px; }
346
- .pp-q { font-size: 14px; font-weight: 600; white-space: pre-wrap; }
347
- .pp-grid { display: grid; grid-template-columns: 76px minmax(0, 1fr); gap: 4px 10px; font-size: 12px; }
348
- .pp-k { color: var(--text-3); font-size: 12px; }
349
- .pp-choices { margin: 0; padding-left: 18px; }
350
- .pp-choices li.picked { color: var(--accent); font-weight: 600; }
351
- .pp-answer { display: grid; gap: 6px; justify-items: start; }
352
- .pp-answer pre { width: 100%; }
353
- .tip .tprompt { font-weight: 600; white-space: pre-wrap; margin-bottom: 4px; }
354
- .flow-shots .shot { cursor: pointer; }
355
- .flow-shots .shot rect { fill: var(--panel-2); stroke: var(--line); }
356
- .flow-shots .shot:hover rect { stroke: var(--accent); }
357
- .flow-shots .shot text { fill: var(--text-3); font: 600 9px var(--mono); pointer-events: none; }
358
-
359
- /* ── returned values ───────────────────────────────────── */
360
- .code-btn path { fill: none; stroke: var(--text-2); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
361
- .code-btn:hover path { stroke: var(--accent); }
362
- .cp-tools { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 10px 6px 14px; border-bottom: 1px solid var(--line-soft); font-size: 12px; }
363
- .btn.small { padding: 3px 9px; font-size: 12px; }
364
- .btn.small svg { width: 13px; height: 13px; }
365
- .code-box { border: 1px solid var(--line-soft); border-radius: 8px; background: var(--panel-2); overflow: auto; max-height: 60vh; }
366
- .code-box .cp-code, .code-pop .cp-code { font: 11.5px/1.65 var(--mono); padding: 8px 0; min-width: max-content; }
367
- .code-box .cl { display: grid; grid-template-columns: 40px auto; white-space: pre; }
368
- .code-box .ln { color: var(--text-3); text-align: right; padding-right: 12px; user-select: none; }
369
- .code-box .lc { padding-right: 14px; }
370
-
371
- @media (max-width: 1100px) {
372
- .bottom { grid-template-columns: minmax(0, 1fr); }
373
- .legend, .overview { display: none; }
374
- .main { grid-template-columns: minmax(0, 1fr); }
375
- .details { display: none; }
376
- }
1
+ :root {
2
+ --bg: #0b1020;
3
+ --panel: #111831;
4
+ --panel-2: #0e152b;
5
+ --raise: #18213f;
6
+ --line: #222c4d;
7
+ --line-soft: #1a2342;
8
+ --text: #e6eaf5;
9
+ --text-2: #a9b2cc;
10
+ --text-3: #6f7a99;
11
+ --accent: #3b82f6;
12
+ --accent-soft: rgba(59, 130, 246, 0.18);
13
+ --ok: #22c55e;
14
+ --fail: #ef4444;
15
+ --cancel: #f59e0b;
16
+ --running: #38bdf8;
17
+ --c1: #4f8ff7;
18
+ --c2: #8b5cf6;
19
+ --c3: #22c55e;
20
+ --c4: #f59e0b;
21
+ --c5: #f0568c;
22
+ --c6: #22d3ee;
23
+ --c7: #a3e635;
24
+ --c8: #fb7185;
25
+ --bar-text: #0b1020;
26
+ --shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
27
+ --mono: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;
28
+ --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
29
+ color-scheme: dark;
30
+ }
31
+ :root[data-theme="light"] {
32
+ --bg: #f4f6fb;
33
+ --panel: #ffffff;
34
+ --panel-2: #f8f9fc;
35
+ --raise: #eef1f8;
36
+ --line: #dde2ee;
37
+ --line-soft: #e9ecf4;
38
+ --text: #182033;
39
+ --text-2: #4b5672;
40
+ --text-3: #8590ab;
41
+ --accent: #2563eb;
42
+ --accent-soft: rgba(37, 99, 235, 0.12);
43
+ --bar-text: #0b1020;
44
+ --shadow: 0 10px 30px rgba(20, 30, 60, 0.15);
45
+ color-scheme: light;
46
+ }
47
+ @media (prefers-color-scheme: light) {
48
+ :root:not([data-theme="dark"]) {
49
+ --bg: #f4f6fb;
50
+ --panel: #ffffff;
51
+ --panel-2: #f8f9fc;
52
+ --raise: #eef1f8;
53
+ --line: #dde2ee;
54
+ --line-soft: #e9ecf4;
55
+ --text: #182033;
56
+ --text-2: #4b5672;
57
+ --text-3: #8590ab;
58
+ --accent: #2563eb;
59
+ --accent-soft: rgba(37, 99, 235, 0.12);
60
+ --shadow: 0 10px 30px rgba(20, 30, 60, 0.15);
61
+ color-scheme: light;
62
+ }
63
+ }
64
+
65
+ * { box-sizing: border-box; }
66
+ html, body { margin: 0; height: 100%; }
67
+ body {
68
+ background: var(--bg);
69
+ color: var(--text);
70
+ font: 13px/1.4 var(--sans);
71
+ overflow: hidden;
72
+ }
73
+ button { font: inherit; color: inherit; }
74
+ [hidden] { display: none !important; }
75
+
76
+ /* ── loader ─────────────────────────────────────────────── */
77
+ #loader {
78
+ position: fixed; inset: 0; display: grid; place-items: center;
79
+ background: var(--bg); z-index: 100;
80
+ }
81
+ .loader-card { display: grid; justify-items: center; gap: 14px; }
82
+ .loader-spin {
83
+ width: 42px; height: 42px; border-radius: 50%;
84
+ border: 3px solid var(--line); border-top-color: var(--accent);
85
+ animation: spin 0.9s linear infinite;
86
+ }
87
+ .loader-title { font-size: 16px; font-weight: 600; }
88
+ .loader-step { color: var(--text-3); font-size: 12px; }
89
+ @keyframes spin { to { transform: rotate(360deg); } }
90
+
91
+ /* ── shell ──────────────────────────────────────────────── */
92
+ #app {
93
+ height: 100vh; display: grid; gap: 10px; padding: 12px 14px 14px;
94
+ grid-template-rows: auto minmax(0, 1fr) 230px;
95
+ }
96
+ .top { display: flex; align-items: center; gap: 14px; min-width: 0; }
97
+ .top .titles { min-width: 0; flex: 1; }
98
+ .top h1 { margin: 0; font-size: 19px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
99
+ .top .meta { color: var(--text-2); display: flex; gap: 10px; align-items: center; margin-top: 3px; flex-wrap: wrap; }
100
+ .top .meta .sep { color: var(--text-3); }
101
+ .dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; }
102
+ .dot.ok { background: var(--ok); }
103
+ .dot.failed { background: var(--fail); }
104
+ .dot.cancelled { background: var(--cancel); }
105
+ .dot.running { background: var(--running); }
106
+
107
+ .btn-group { display: flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--panel); }
108
+ .btn {
109
+ border: 0; background: transparent; padding: 7px 12px; cursor: pointer;
110
+ display: inline-flex; align-items: center; gap: 7px; color: var(--text-2); white-space: nowrap;
111
+ }
112
+ .btn + .btn { border-left: 1px solid var(--line); }
113
+ .btn:hover { background: var(--raise); color: var(--text); }
114
+ .btn.active { background: var(--accent); color: #fff; }
115
+ .btn svg { width: 15px; height: 15px; }
116
+ .btn.solo { border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
117
+
118
+ .main {
119
+ display: grid; gap: 10px; min-height: 0;
120
+ grid-template-columns: minmax(0, 1fr) 320px;
121
+ }
122
+ .main.no-details { grid-template-columns: minmax(0, 1fr); }
123
+ .card { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; min-height: 0; min-width: 0; }
124
+
125
+ /* ── timeline: tree + chart share one vertical scroll ──── */
126
+ .timeline { display: grid; grid-template-rows: 34px minmax(0, 1fr); overflow: hidden; }
127
+ .tl-head { display: grid; grid-template-columns: var(--tree-w, 420px) minmax(0, 1fr); border-bottom: 1px solid var(--line); }
128
+ .tl-head .cols { display: grid; grid-template-columns: minmax(0, 1fr); align-items: center; border-right: 1px solid var(--line); }
129
+ .tl-head .cols > div { padding: 0 12px; color: var(--text-2); font-weight: 600; font-size: 12px; }
130
+ .tl-head .cols > div + div { border-left: 1px solid var(--line-soft); height: 100%; display: flex; align-items: center; }
131
+ .tl-head svg { display: block; width: 100%; height: 34px; }
132
+ .tl-body { overflow: auto; display: grid; grid-template-columns: var(--tree-w, 420px) minmax(0, 1fr); align-items: start; position: relative; }
133
+
134
+ .tree { border-right: 1px solid var(--line); position: sticky; left: 0; background: var(--panel); z-index: 2; }
135
+ .row {
136
+ height: var(--row-h); display: grid; grid-template-columns: minmax(0, 1fr);
137
+ align-items: center; cursor: pointer; border-bottom: 1px solid transparent;
138
+ }
139
+ .row:hover { background: var(--raise); }
140
+ .row.selected { background: var(--accent-soft); }
141
+ .row .name { display: flex; align-items: center; gap: 7px; min-width: 0; padding-right: 8px; }
142
+ /* the name keeps its room; the chips shrink (each to an ellipsis) into what is left */
143
+ /* two lines: the label (and error count), then status · duration · tags, smaller */
144
+ .row .lines { display: flex; flex-direction: column; justify-content: center; gap: 2px; flex: 1; min-width: 0; }
145
+ .row .l1, .row .l2 { display: flex; align-items: center; gap: 6px; min-width: 0; }
146
+ .row .label { flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
147
+ .row .label .tcall { font-size: 11.5px; }
148
+ .row .label .sep, .row .l2 .sep { color: var(--text-3); }
149
+ .row .l2 { font-size: 11px; color: var(--text-2); font-variant-numeric: tabular-nums; }
150
+ .row .l2 .st { display: inline-flex; align-items: center; gap: 4px; flex: none; }
151
+ .row .l2 .dot { width: 7px; height: 7px; }
152
+ .row .l2 .du { flex: none; }
153
+ .row .l2 .chips { flex: 0 1 auto; flex-wrap: nowrap; overflow: hidden; margin-left: 2px; }
154
+ .row .l2 .chip { flex: 0 1 auto; min-width: 24px; font-size: 10px; line-height: 14px; }
155
+ .row .l2 .chip.more { flex: none; }
156
+ .row .twist { width: 16px; height: 16px; flex: none; display: grid; place-items: center; color: var(--text-3); border: 0; background: none; padding: 0; cursor: pointer; }
157
+ .row .twist svg { width: 12px; height: 12px; transition: transform 0.12s; }
158
+ .row .twist.open svg { transform: rotate(90deg); }
159
+ .row .icon { width: 22px; height: 22px; flex: none; display: grid; place-items: center; border-radius: 6px; }
160
+ .row .icon svg { width: 14px; height: 14px; }
161
+ .guide { width: 14px; flex: none; align-self: stretch; position: relative; }
162
+ .guide::before { content: ""; position: absolute; left: 7px; top: 0; bottom: 0; border-left: 1px solid var(--line); }
163
+
164
+ .chart { position: relative; min-width: 0; }
165
+ .chart svg { display: block; overflow: hidden; }
166
+ .chart .bar-label { font-size: 12px; fill: var(--bar-text); font-weight: 500; cursor: pointer; }
167
+ .chart .hit { fill: transparent; cursor: pointer; }
168
+ .chart .hit:hover + .bar { filter: brightness(1.15); }
169
+ .chart .bar-label.outside { fill: var(--text); }
170
+ .chart .mark-label { font-size: 11px; fill: var(--text-2); cursor: pointer; }
171
+ .chart .mark-label:hover { fill: var(--text); }
172
+ .chart .grid line { stroke: var(--line-soft); }
173
+ .chart .cursor { stroke: var(--text-2); stroke-dasharray: 3 3; pointer-events: none; }
174
+ .chart .link { fill: none; stroke: var(--text-3); stroke-width: 1.2; }
175
+ .chart .bar { cursor: pointer; }
176
+ .chart .bar.selected { stroke: var(--text); stroke-width: 2; }
177
+ .chart .mark { cursor: pointer; stroke: var(--panel); stroke-width: 1.5; }
178
+ .axis text { fill: var(--text-2); font-size: 11px; }
179
+ .axis line, .axis path { stroke: var(--line); }
180
+
181
+ .flow-view { position: absolute; inset: 0; }
182
+ .flow-view svg { width: 100%; height: 100%; display: block; cursor: grab; }
183
+ .flow-card rect.box { fill: var(--raise); stroke: var(--line); rx: 8; }
184
+ .flow-card.selected rect.box { stroke: var(--accent); stroke-width: 2; }
185
+ .flow-card text { fill: var(--text); font-size: 12px; }
186
+ .flow-card text.nm { font-weight: 600; }
187
+ .flow-card .flow-icon { pointer-events: none; }
188
+ .flow-seq { fill: none; stroke: var(--text-3); stroke-width: 1.4; stroke-dasharray: 5 4; }
189
+ .flow-seq.parallel { stroke-dasharray: 1 4; stroke-linecap: round; stroke-width: 2; opacity: 0.8; }
190
+ .flow-arrowhead { fill: var(--text-3); }
191
+ .flow-par { fill: var(--text-3); font-size: 10px; font-style: italic; }
192
+ .flow-shot-t { fill: var(--text-3); font-size: 10.5px; pointer-events: none; }
193
+ .flow-card text.sub { fill: var(--text-3); font-size: 11px; }
194
+ .flow-card .tchip text { fill: var(--text); font-size: 10.5px; }
195
+ .flow-card .tchip.more text { fill: var(--text-3); }
196
+ .flow-link { fill: none; stroke: var(--text-3); stroke-width: 1.3; }
197
+
198
+ /* ── details ────────────────────────────────────────────── */
199
+ .details { display: grid; grid-template-rows: auto auto minmax(0, 1fr); overflow: hidden; }
200
+ .details .dh { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; font-weight: 600; }
201
+ .details .x { border: 0; background: none; cursor: pointer; color: var(--text-2); padding: 2px; }
202
+ .details .who { display: flex; align-items: center; gap: 10px; padding: 4px 14px 10px; }
203
+ .details .who .icon { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; flex: none; }
204
+ .details .who .icon svg { width: 16px; height: 16px; }
205
+ .details .who .nm { font-size: 16px; font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
206
+ .pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; background: var(--raise); font-size: 12px; }
207
+ .details .scroll { overflow: auto; padding: 0 14px 14px; }
208
+ .kv .v.mono-sm { font: 11.5px var(--mono); color: var(--text-2); }
209
+ /* details accordion */
210
+ .acc { border-top: 1px solid var(--line-soft); }
211
+ .acc-sec { border-bottom: 1px solid var(--line-soft); }
212
+ .acc-h { display: flex; align-items: center; gap: 6px; padding: 8px 2px; font-weight: 600; cursor: pointer; list-style: none; user-select: none; }
213
+ .acc-h::-webkit-details-marker { display: none; }
214
+ .acc-h svg { width: 12px; height: 12px; color: var(--text-3); transition: transform 0.12s; flex: none; }
215
+ .acc-sec[open] > .acc-h svg { transform: rotate(90deg); }
216
+ .acc-h:hover { color: var(--accent); }
217
+ .acc-n { margin-left: auto; min-width: 18px; padding: 0 6px; border-radius: 999px; background: var(--raise); color: var(--text-2); font-size: 11px; font-weight: 600; text-align: center; }
218
+ .acc-sec.errors .acc-n { background: var(--fail); color: #fff; }
219
+ .acc-sec.empty .acc-h { color: var(--text-3); font-weight: 500; cursor: default; }
220
+ .acc-sec.empty .acc-h svg { opacity: 0.35; }
221
+ .acc-sec.empty .acc-n { background: none; color: var(--text-3); }
222
+ .acc-b { padding: 0 0 12px; }
223
+ .acc-b > .params { margin-bottom: 8px; }
224
+ .acc-b .section-title:first-child { margin-top: 0; }
225
+ .acc-file { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; color: var(--text-2); }
226
+ .shots { display: grid; gap: 6px; }
227
+ .shot { display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 4px; border: 1px solid transparent; border-radius: 8px; cursor: pointer; }
228
+ .shot:hover { border-color: var(--accent); background: var(--accent-soft); }
229
+ .shot .thumb { width: 64px; }
230
+ .shot .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
231
+ .shot .t { color: var(--text-3); font-size: 11px; font-variant-numeric: tabular-nums; }
232
+ .kv { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 6px 10px; margin: 2px 0 12px; }
233
+ .kv .k { color: var(--text-2); }
234
+ .kv .v { min-width: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
235
+ a { color: var(--accent); text-decoration: none; }
236
+ a:hover { text-decoration: underline; }
237
+ .tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); margin: 0 0 10px; overflow-x: auto; }
238
+ .tab { border: 0; background: none; padding: 7px 9px; cursor: pointer; color: var(--text-2); border-bottom: 2px solid transparent; white-space: nowrap; }
239
+ .tab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; }
240
+ .section-title { font-weight: 600; margin: 14px 0 8px; }
241
+ .ev-list { list-style: none; margin: 0; padding: 0; position: relative; }
242
+ .ev-list li { display: grid; grid-template-columns: 64px 18px minmax(0, 1fr); gap: 8px; align-items: start; padding: 4px 0; }
243
+ .ev-list .t { color: var(--text-2); font-variant-numeric: tabular-nums; text-align: right; }
244
+ .ev-list .m { overflow-wrap: anywhere; }
245
+ .ev-ico { width: 16px; height: 16px; border-radius: 50%; display: grid; place-items: center; margin-top: 1px; }
246
+ .ev-ico svg { width: 10px; height: 10px; }
247
+ pre.code {
248
+ margin: 0; padding: 10px; background: var(--panel-2); border: 1px solid var(--line-soft); border-radius: 8px;
249
+ font: 12px/1.45 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; max-height: 60vh; overflow: auto;
250
+ }
251
+ .muted { color: var(--text-3); }
252
+ .thumb { border: 1px solid var(--line); border-radius: 6px; overflow: hidden; cursor: pointer; background: var(--panel-2); aspect-ratio: 16 / 10; display: grid; place-items: center; }
253
+ .thumb:hover { border-color: var(--accent); }
254
+ .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
255
+ .thumb .json-ico { font: 600 12px var(--mono); color: var(--text-3); }
256
+
257
+ /* ── bottom strip ───────────────────────────────────────── */
258
+ .bottom { display: grid; gap: 10px; grid-template-columns: minmax(0, 1fr) 250px; min-height: 0; }
259
+ .lower { display: grid; grid-template-rows: auto minmax(0, 1fr); overflow: hidden; }
260
+ .lower .tabs { margin: 0; padding: 0 10px; align-items: center; }
261
+ .lower .tabs .spacer { flex: 1; }
262
+ .filter { border: 1px solid var(--line); background: var(--panel-2); border-radius: 7px; padding: 5px 9px; color: var(--text); width: 200px; margin: 4px 0; }
263
+ .lower .body { overflow: auto; padding: 10px 12px; }
264
+ .gallery { display: flex; gap: 12px; }
265
+ .gal-item { flex: none; width: 160px; cursor: pointer; border: 1px solid transparent; border-radius: 8px; padding: 4px; }
266
+ .gal-item:hover, .gal-item.active { border-color: var(--accent); background: var(--accent-soft); }
267
+ .gal-item .thumb { aspect-ratio: 16 / 10; }
268
+ .gal-item .cap { display: flex; gap: 8px; margin-top: 5px; font-size: 12px; }
269
+ .gal-item .cap .t { color: var(--text-2); font-variant-numeric: tabular-nums; }
270
+ .gal-item .cap .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
271
+ .gal-item .sz { color: var(--text-3); font-size: 11px; }
272
+ table.list { width: 100%; border-collapse: collapse; font-size: 12px; }
273
+ table.list td { padding: 3px 8px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
274
+ table.list td.t { color: var(--text-2); white-space: nowrap; font-variant-numeric: tabular-nums; width: 1%; }
275
+ table.list td.p { color: var(--text-3); white-space: nowrap; max-width: 260px; overflow: hidden; text-overflow: ellipsis; width: 1%; }
276
+ table.list td.m { font-family: var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
277
+ table.list tr.err td.m { color: var(--fail); }
278
+ table.list tr { cursor: pointer; }
279
+ table.list tr:hover td { background: var(--raise); }
280
+ .legend { padding: 10px 14px; }
281
+ /* at the end of the tree's header cell, clear of the time axis; top-right in the flow (no axis) */
282
+ .legend-btn { position: absolute; top: 6px; left: calc(var(--tree-w, 360px) - 30px); z-index: 6; background: var(--panel); cursor: pointer; }
283
+ .timeline.is-flow .legend-btn { left: auto; right: 8px; }
284
+ .timeline.is-flow .legend-pop { left: auto; right: 8px; }
285
+ .legend-btn.active { color: var(--accent); background: var(--accent-soft); }
286
+ .legend-pop {
287
+ position: absolute; top: 34px; left: calc(var(--tree-w, 360px) - 30px); z-index: 7; width: 270px; background: var(--panel);
288
+ border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow);
289
+ }
290
+ .legend h3, .overview h3 { margin: 0 0 10px; font-size: 13px; font-weight: 600; }
291
+ .legend .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 12px; }
292
+ .legend .li { display: flex; align-items: center; gap: 8px; color: var(--text-2); font-size: 12px; }
293
+ .overview { padding: 10px 14px; display: grid; grid-template-rows: auto auto minmax(0, 1fr); }
294
+ .overview .range { color: var(--text-2); font-size: 11px; text-align: right; margin-bottom: 4px; font-variant-numeric: tabular-nums; }
295
+ .overview svg { width: 100%; height: 100%; display: block; }
296
+ .overview .brush .selection { fill: var(--accent-soft); stroke: var(--text-2); }
297
+
298
+ /* ── floating ───────────────────────────────────────────── */
299
+ .tip {
300
+ position: fixed; pointer-events: none; z-index: 50; background: var(--panel); border: 1px solid var(--line);
301
+ border-radius: 8px; padding: 8px 10px; box-shadow: var(--shadow); max-width: 360px; font-size: 12px;
302
+ }
303
+ .tip .tt { font-weight: 600; margin-bottom: 2px; }
304
+ .tip .ts { color: var(--text-2); }
305
+ .tip.wide { max-width: 420px; min-width: 260px; }
306
+ .tip .mono { font-family: var(--mono); font-size: 11px; overflow-wrap: anywhere; }
307
+ .tip .small { color: var(--text-2); }
308
+ .tip .summary { margin: 6px 0 0; line-height: 1.45; }
309
+ .tip .sec { color: var(--text-3); margin: 8px 0 3px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
310
+ .tip .sec.fail { color: var(--fail); }
311
+ .params { display: grid; gap: 3px; }
312
+ .param { font: 11px/1.4 var(--mono); }
313
+ .param .pn { color: var(--text); }
314
+ .param .pt { color: var(--accent); margin-left: 6px; }
315
+ .param .pd { color: var(--text-3); margin-left: 6px; }
316
+ .param .pdesc { font-family: var(--sans); color: var(--text-2); margin-left: 10px; }
317
+ .kv .v.defined { display: flex; align-items: center; gap: 6px; }
318
+ .kv .v.defined a { min-width: 0; overflow-wrap: anywhere; font-family: var(--mono); font-size: 12px; }
319
+ .icon-btn { flex: none; border: 1px solid var(--line); background: var(--panel-2); color: var(--text-2); border-radius: 6px; width: 24px; height: 22px; display: grid; place-items: center; cursor: pointer; padding: 0; }
320
+ .icon-btn:hover { color: var(--text); border-color: var(--accent); }
321
+ .icon-btn svg { width: 13px; height: 13px; }
322
+ .tip .hint { margin-top: 8px; color: var(--text-3); font-size: 11px; }
323
+ .tip kbd { font: 600 10px var(--mono); border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px; padding: 0 4px; color: var(--text-2); }
324
+ /* tag chips — one look everywhere a tag shows (the flow's SVG chips match it) */
325
+ .chips { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
326
+ .chip {
327
+ flex: none; max-width: 170px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 6px;
328
+ border-radius: 4px; background: var(--raise); border: 1px solid var(--line); color: var(--text); font-size: 10.5px; line-height: 16px;
329
+ }
330
+ .chip.more { background: none; color: var(--text-3); }
331
+ .badge-inline { display: inline-block; padding: 0 7px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); font-size: 11px; font-weight: 600; }
332
+ .tip img { display: block; max-width: 240px; max-height: 150px; border-radius: 4px; margin: 6px 0; border: 1px solid var(--line); }
333
+ .modal { position: fixed; inset: 0; background: rgba(5, 8, 18, 0.72); z-index: 60; display: grid; place-items: center; padding: 28px; }
334
+ .modal .box { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow); max-width: min(1200px, 100%); max-height: 100%; display: grid; grid-template-rows: auto minmax(0, 1fr); overflow: hidden; }
335
+ .modal .mh { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--line); }
336
+ .modal .mh .nm { font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
337
+ .modal .mb { overflow: auto; padding: 14px; }
338
+ .modal img { max-width: 100%; display: block; margin: auto; }
339
+ .menu { position: fixed; z-index: 55; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow); padding: 4px; min-width: 200px; }
340
+ .menu button { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 7px 10px; border-radius: 6px; cursor: pointer; }
341
+ .menu button:hover { background: var(--raise); }
342
+ .toast { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); background: var(--raise); border: 1px solid var(--line); padding: 7px 14px; border-radius: 8px; z-index: 70; }
343
+
344
+ /* ── title info, locate, defined-at, code popover ───────── */
345
+ .title-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
346
+ .title-row h1 { min-width: 0; }
347
+ .info-btn { flex: none; width: 22px; height: 22px; border: 0; border-radius: 50%; background: none; color: var(--text-3); display: grid; place-items: center; cursor: help; padding: 0; }
348
+ .info-btn:hover, .info-btn:focus-visible { color: var(--accent); background: var(--accent-soft); }
349
+ .info-btn svg { width: 17px; height: 17px; }
350
+ .gal-item .cap .locate { margin-left: auto; width: 22px; height: 20px; }
351
+ .kv .v.defined { flex-wrap: wrap; }
352
+ .kv .v.defined .defined-name { color: var(--text-2); font-family: var(--mono); font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
353
+ a.icon-btn { text-decoration: none; }
354
+ .chart .code-btn, .flow-card .code-btn { cursor: pointer; opacity: 0; transition: opacity 0.12s; }
355
+ .chart g.r:hover .code-btn, .chart g.r.sel .code-btn, .flow-card:hover .code-btn, .flow-card.selected .code-btn { opacity: 1; }
356
+ .code-btn circle { fill: var(--panel); stroke: var(--text-3); stroke-width: 1.2; }
357
+ .code-btn text { fill: var(--text-2); font: 700 9px var(--mono); pointer-events: none; }
358
+ .code-btn:hover circle { stroke: var(--accent); }
359
+ .code-btn:hover text { fill: var(--accent); }
360
+ .chart line.pin.flash { animation: pin-flash 0.6s ease-in-out 3; }
361
+ .chart circle.mark.flash { animation: mark-flash 0.6s ease-in-out 3; transform-box: fill-box; transform-origin: center; }
362
+ @keyframes pin-flash { 50% { stroke-width: 5; } }
363
+ @keyframes mark-flash { 50% { transform: scale(1.9); } }
364
+ .code-pop {
365
+ position: fixed; z-index: 58; width: 640px; max-width: 92vw; max-height: 70vh; display: flex; flex-direction: column;
366
+ background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); overflow: hidden;
367
+ }
368
+ .code-pop .cp-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px 6px 12px; background: var(--panel-2); border-bottom: 1px solid var(--line); }
369
+ .code-pop .cp-path { font: 12px var(--mono); color: var(--text-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
370
+ .code-pop .cp-name { flex: 1; text-align: right; color: var(--text-3); font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
371
+ .code-pop .cp-body { overflow: auto; min-height: 0; }
372
+ .code-pop .cp-code { font: 11.5px/1.65 var(--mono); padding: 8px 0; min-width: max-content; }
373
+ .code-pop .cl { display: grid; grid-template-columns: 48px auto; white-space: pre; }
374
+ .code-pop .cl.at { background: var(--accent-soft); }
375
+ .code-pop .ln { color: var(--text-3); text-align: right; padding-right: 14px; user-select: none; }
376
+ .code-pop .lc { padding-right: 16px; }
377
+ .code-pop .cp-more { padding: 6px 14px 10px; font-size: 12px; }
378
+ :root { --tk-c: #6f7a99; --tk-s: #7ee0a3; --tk-n: #f0b26b; --tk-k: #c792ea; --tk-f: #82aaff; --tk-t: #ffcb6b; }
379
+ :root[data-theme="light"] { --tk-c: #6a737d; --tk-s: #116329; --tk-n: #b35900; --tk-k: #cf222e; --tk-f: #6639ba; --tk-t: #953800; }
380
+ @media (prefers-color-scheme: light) {
381
+ :root:not([data-theme="dark"]) { --tk-c: #6a737d; --tk-s: #116329; --tk-n: #b35900; --tk-k: #cf222e; --tk-f: #6639ba; --tk-t: #953800; }
382
+ }
383
+ .tk-c { color: var(--tk-c); font-style: italic; }
384
+ .tk-s { color: var(--tk-s); }
385
+ .tk-n { color: var(--tk-n); }
386
+ .tk-k { color: var(--tk-k); }
387
+ .tk-f { color: var(--tk-f); }
388
+ .tk-t { color: var(--tk-t); }
389
+ .tk-p { color: var(--tk-f); }
390
+
391
+ /* ── popover tabs, prompt panel, flow snapshot strip ───── */
392
+ .code-pop .cp-tabs { display: flex; gap: 2px; padding: 0 8px; border-bottom: 1px solid var(--line); background: var(--panel-2); }
393
+ .code-pop .cp-tabs .tab { padding: 6px 9px; font-size: 12px; }
394
+ .pp { padding: 12px 14px 14px; display: grid; gap: 10px; }
395
+ .pp-q { font-size: 14px; font-weight: 600; white-space: pre-wrap; }
396
+ .pp-grid { display: grid; grid-template-columns: 76px minmax(0, 1fr); gap: 4px 10px; font-size: 12px; }
397
+ .pp-k { color: var(--text-3); font-size: 12px; }
398
+ .pp-choices { margin: 0; padding-left: 18px; }
399
+ .pp-choices li.picked { color: var(--accent); font-weight: 600; }
400
+ .pp-answer { display: grid; gap: 6px; justify-items: start; }
401
+ .pp-answer pre { width: 100%; }
402
+ .tcall { font: 12px var(--mono); color: var(--text-3); overflow-wrap: anywhere; }
403
+ .tcall .b { color: var(--accent); font-weight: 600; }
404
+ .tcall .f { color: var(--text); }
405
+ .tip .tcall { margin: 2px 0 5px; }
406
+ .details .who-call { margin: 0 0 10px; }
407
+ .tip .tmeta { display: flex; align-items: center; gap: 6px; color: var(--text-2); font-size: 11px; }
408
+ .tip .tmeta .sep { color: var(--text-3); }
409
+ .tip .tmeta .mcp { color: var(--accent); font-weight: 600; }
410
+ .tip .chips { margin-top: 6px; }
411
+ .tip .tfail { margin-top: 6px; color: var(--fail); font: 11px var(--mono); overflow-wrap: anywhere; }
412
+ .flow-shots .shot { cursor: pointer; }
413
+ .flow-shots .shot rect { fill: var(--panel-2); stroke: var(--line); }
414
+ .flow-shots .shot:hover rect { stroke: var(--accent); }
415
+ .flow-shots .shot text { fill: var(--text-3); font: 600 9px var(--mono); pointer-events: none; }
416
+
417
+ /* ── returned values ───────────────────────────────────── */
418
+ .code-btn path { fill: none; stroke: var(--text-2); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
419
+ .code-btn:hover path { stroke: var(--accent); }
420
+ .cp-tools { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 10px 6px 14px; border-bottom: 1px solid var(--line-soft); font-size: 12px; }
421
+ .btn.small { padding: 3px 9px; font-size: 12px; }
422
+ .btn.small svg { width: 13px; height: 13px; }
423
+ .code-box { border: 1px solid var(--line-soft); border-radius: 8px; background: var(--panel-2); overflow: auto; max-height: 60vh; }
424
+ .code-box .cp-code, .code-pop .cp-code { font: 11.5px/1.65 var(--mono); padding: 8px 0; min-width: max-content; }
425
+ .code-box .cl { display: grid; grid-template-columns: 40px auto; white-space: pre; }
426
+ .code-box .ln { color: var(--text-3); text-align: right; padding-right: 12px; user-select: none; }
427
+ .code-box .lc { padding-right: 14px; }
428
+
429
+ /* ── errors ────────────────────────────────────────────── */
430
+ .tab-count { display: inline-block; min-width: 18px; padding: 0 6px; border-radius: 999px; background: var(--raise); color: var(--text-2); font-size: 11px; text-align: center; }
431
+ .tab-count.bad { background: rgba(239, 68, 68, 0.16); color: var(--fail); font-weight: 700; }
432
+ .linkish { border: 0; background: none; padding: 0; cursor: pointer; font: inherit; color: var(--accent); }
433
+ .linkish.bad { color: var(--fail); }
434
+ .linkish.warn { color: var(--cancel); }
435
+ .tab-count.warn { background: rgba(245, 158, 11, 0.16); color: var(--cancel); font-weight: 700; }
436
+ .linkish:hover { text-decoration: underline; }
437
+ .err-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
438
+ .segs { display: flex; border: 1px solid var(--line); border-radius: 7px; overflow: hidden; }
439
+ .seg { border: 0; background: var(--panel); padding: 4px 10px; cursor: pointer; color: var(--text-2); font-size: 12px; }
440
+ .seg + .seg { border-left: 1px solid var(--line); }
441
+ .seg.active { background: var(--accent-soft); color: var(--text); font-weight: 600; }
442
+ .btn.small.active { background: rgba(239, 68, 68, 0.14); color: var(--fail); border-color: var(--fail); }
443
+ .err-sec { margin-bottom: 10px; }
444
+ .err-sec-h { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 12px; color: var(--text-2); margin: 6px 0 4px; }
445
+ .err-sec-h svg { width: 13px; height: 13px; color: var(--fail); }
446
+ .err-entry { border: 1px solid var(--line-soft); border-left: 3px solid var(--fail); border-radius: 6px; margin-bottom: 4px; background: var(--panel); }
447
+ .err-entry.output { border-left-color: var(--cancel); }
448
+ .err-entry.assert { border-left-color: #f97316; }
449
+ .err-row { display: flex; align-items: center; gap: 8px; padding: 4px 6px; cursor: pointer; min-width: 0; font-size: 12px; }
450
+ .err-row:hover { background: var(--raise); }
451
+ .err-row .twist { width: 14px; height: 14px; display: grid; place-items: center; color: var(--text-3); flex: none; }
452
+ .err-row .twist svg { width: 11px; height: 11px; transition: transform 0.12s; }
453
+ .err-row .twist.open svg { transform: rotate(90deg); }
454
+ .err-row .t { color: var(--text-2); font-variant-numeric: tabular-nums; flex: none; min-width: 44px; }
455
+ .err-row .who { color: var(--text); font-weight: 600; flex: none; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
456
+ .err-row .err-src { color: var(--text-3); font-family: var(--mono); font-size: 11px; flex: none; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
457
+ .err-row .msg { flex: 1; min-width: 0; font-family: var(--mono); color: var(--fail); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
458
+ .err-entry.output .err-row .msg { color: var(--text-2); }
459
+ .err-row .err-n { color: var(--text-3); font-size: 11px; flex: none; }
460
+ .err-row .icon-btn { width: 22px; height: 20px; }
461
+ .err-text { margin: 0 8px 8px 28px; max-height: 260px; }
462
+ .err-kind { color: var(--fail); }
463
+ .errbadge { flex: none; min-width: 16px; height: 16px; padding: 0 5px; border-radius: 999px; background: var(--fail); color: #fff; font-size: 10px; font-weight: 700; display: inline-grid; place-items: center; }
464
+ /* highlight mode — errored nodes in red, the path to them marked, the rest dimmed */
465
+ #app.hl-on .chart g.r:not(.err):not(.err-path),
466
+ #app.hl-on .flow-card:not(.err):not(.err-path) { opacity: 0.22; }
467
+ #app.hl-on .tree .row:not(.err):not(.err-path) { opacity: 0.4; }
468
+ #app.hl-on .chart g.r.err rect.bar { stroke: var(--fail); stroke-width: 2.5; filter: drop-shadow(0 0 5px rgba(239, 68, 68, 0.75)); }
469
+ #app.hl-on .flow-card.err rect.box { stroke: var(--fail); stroke-width: 2.5; filter: drop-shadow(0 0 5px rgba(239, 68, 68, 0.6)); }
470
+ #app.hl-on .chart g.r.err-path rect.bar,
471
+ #app.hl-on .flow-card.err-path rect.box { stroke: var(--fail); stroke-width: 1.2; stroke-dasharray: 4 3; }
472
+ #app.hl-on .tree .row.err { background: rgba(239, 68, 68, 0.1); }
473
+ .chart g.r, .flow-card, .tree .row { transition: opacity 0.15s; }
474
+
475
+ @media (max-width: 1100px) {
476
+ .bottom { grid-template-columns: minmax(0, 1fr); }
477
+ .overview { display: none; }
478
+ .main { grid-template-columns: minmax(0, 1fr); }
479
+ .details { display: none; }
480
+ }