@xera-ai/core 0.9.6 → 0.9.8

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,88 +1,342 @@
1
1
  * {
2
2
  box-sizing: border-box;
3
3
  }
4
+
4
5
  body {
5
6
  margin: 0;
6
7
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
7
8
  height: 100vh;
9
+ background: #050810;
8
10
  display: grid;
9
- grid-template-rows: 56px 1fr 32px;
10
- grid-template-columns: 1fr 320px;
11
+ grid-template-rows: 52px 1fr 26px;
12
+ grid-template-columns: 1fr 280px;
11
13
  }
14
+
15
+ /* ─── Topbar ─────────────────────────────────────── */
12
16
  #topbar {
13
17
  grid-column: 1 / -1;
14
18
  display: flex;
15
19
  align-items: center;
16
- gap: 16px;
20
+ gap: 0;
17
21
  padding: 0 16px;
18
- background: #1f2937;
19
- color: #f9fafb;
20
- border-bottom: 1px solid #374151;
22
+ background: #080c14;
23
+ border-bottom: 1px solid #1a2035;
21
24
  }
22
- #topbar .title {
23
- font-weight: 600;
24
- font-size: 16px;
25
+
26
+ .topbar-brand {
27
+ display: flex;
28
+ align-items: center;
29
+ gap: 8px;
30
+ padding-right: 20px;
31
+ border-right: 1px solid #1a2035;
32
+ margin-right: 16px;
25
33
  }
26
- #topbar .stats {
27
- color: #9ca3af;
34
+
35
+ .topbar-brand .logo {
36
+ width: 18px;
37
+ height: 18px;
38
+ border-radius: 4px;
39
+ background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ flex-shrink: 0;
44
+ }
45
+
46
+ .topbar-brand .logo::after {
47
+ content: "";
48
+ display: block;
49
+ width: 6px;
50
+ height: 6px;
51
+ border-radius: 50%;
52
+ background: white;
53
+ opacity: 0.9;
54
+ }
55
+
56
+ .topbar-brand .title {
57
+ font-weight: 600;
28
58
  font-size: 13px;
59
+ color: #e2e8f0;
60
+ letter-spacing: -0.01em;
61
+ }
62
+
63
+ #stats-bar {
64
+ display: flex;
65
+ gap: 6px;
66
+ align-items: center;
29
67
  flex: 1;
30
68
  }
31
- #topbar .filters {
69
+
70
+ .stat-chip {
71
+ display: inline-flex;
72
+ align-items: center;
73
+ gap: 5px;
74
+ font-size: 11px;
75
+ font-weight: 500;
76
+ color: #64748b;
77
+ background: #0f1624;
78
+ border: 1px solid #1e2d45;
79
+ border-radius: 20px;
80
+ padding: 2px 9px;
81
+ line-height: 1.6;
82
+ transition:
83
+ color 0.15s,
84
+ border-color 0.15s;
85
+ }
86
+
87
+ .stat-chip .dot {
88
+ width: 6px;
89
+ height: 6px;
90
+ border-radius: 50%;
91
+ flex-shrink: 0;
92
+ }
93
+
94
+ .topbar-controls {
32
95
  display: flex;
33
96
  gap: 8px;
34
97
  align-items: center;
35
- font-size: 13px;
98
+ padding-left: 16px;
99
+ border-left: 1px solid #1a2035;
36
100
  }
37
- #topbar input[type="text"] {
38
- background: #111827;
39
- color: #f9fafb;
40
- border: 1px solid #374151;
41
- border-radius: 4px;
42
- padding: 4px 8px;
101
+
102
+ #search {
103
+ background: #0f1624;
104
+ color: #c9d1d9;
105
+ border: 1px solid #1e2d45;
106
+ border-radius: 6px;
107
+ padding: 4px 10px 4px 28px;
43
108
  width: 160px;
109
+ font-size: 12px;
110
+ outline: none;
111
+ transition:
112
+ border-color 0.15s,
113
+ box-shadow 0.15s;
114
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%234b5563' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
115
+ background-repeat: no-repeat;
116
+ background-position: 10px center;
44
117
  }
45
- #topbar button {
46
- background: #374151;
47
- color: #f9fafb;
48
- border: none;
118
+
119
+ #search:focus {
120
+ border-color: #3b82f6;
121
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
122
+ }
123
+
124
+ #search::placeholder {
125
+ color: #374151;
126
+ }
127
+
128
+ .filter-group {
129
+ display: flex;
130
+ gap: 2px;
131
+ background: #0f1624;
132
+ border: 1px solid #1e2d45;
133
+ border-radius: 6px;
134
+ padding: 3px;
135
+ }
136
+
137
+ .filter-group label {
138
+ cursor: pointer;
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 4px;
142
+ font-size: 11px;
143
+ font-weight: 500;
144
+ color: #4b5563;
145
+ padding: 2px 7px;
49
146
  border-radius: 4px;
50
- padding: 4px 12px;
147
+ transition:
148
+ background 0.1s,
149
+ color 0.1s;
150
+ user-select: none;
151
+ }
152
+
153
+ .filter-group label:hover {
154
+ background: #1a2540;
155
+ color: #9ca3af;
156
+ }
157
+
158
+ .filter-group label input {
159
+ display: none;
160
+ }
161
+
162
+ .filter-group label.active {
163
+ color: #e2e8f0;
164
+ background: #1a2540;
165
+ }
166
+
167
+ .filter-group label .indicator {
168
+ width: 6px;
169
+ height: 6px;
170
+ border-radius: 2px;
171
+ }
172
+
173
+ #reset-btn {
174
+ background: transparent;
175
+ color: #4b5563;
176
+ border: 1px solid #1e2d45;
177
+ border-radius: 6px;
178
+ padding: 4px 10px;
51
179
  cursor: pointer;
180
+ font-size: 11px;
181
+ font-weight: 500;
182
+ transition:
183
+ background 0.15s,
184
+ color 0.15s,
185
+ border-color 0.15s;
186
+ white-space: nowrap;
52
187
  }
53
- #topbar button:hover {
54
- background: #4b5563;
188
+
189
+ #reset-btn:hover {
190
+ background: #1a2035;
191
+ color: #9ca3af;
192
+ border-color: #2d3f5f;
55
193
  }
194
+
195
+ /* ─── Canvas ──────────────────────────────────────── */
56
196
  #canvas {
57
- background: #fafbfc;
197
+ background-color: #050810;
198
+ background-image: radial-gradient(rgba(148, 163, 184, 0.06) 1px, transparent 1px);
199
+ background-size: 28px 28px;
58
200
  position: relative;
201
+ min-height: 0;
202
+ overflow: hidden;
203
+ }
204
+
205
+ #progress-wrap {
206
+ position: fixed;
207
+ top: 52px;
208
+ left: 0;
209
+ right: 0;
210
+ height: 2px;
211
+ z-index: 100;
212
+ pointer-events: none;
213
+ overflow: hidden;
59
214
  }
215
+
216
+ #progress-bar {
217
+ height: 100%;
218
+ width: 0%;
219
+ background: linear-gradient(90deg, #3b82f6, #6366f1);
220
+ transition: width 0.1s linear;
221
+ box-shadow: 0 0 6px rgba(99, 102, 241, 0.6);
222
+ }
223
+
224
+ /* ─── Side panel ──────────────────────────────────── */
60
225
  #sidepanel {
61
- background: #ffffff;
62
- border-left: 1px solid #e5e7eb;
63
- padding: 16px;
226
+ background: #080c14;
227
+ border-left: 1px solid #1a2035;
64
228
  overflow-y: auto;
229
+ color: #e2e8f0;
230
+ display: flex;
231
+ flex-direction: column;
232
+ transition: opacity 0.2s;
65
233
  }
234
+
66
235
  #sidepanel.hidden {
67
- display: none;
236
+ visibility: hidden;
237
+ opacity: 0;
238
+ pointer-events: none;
239
+ }
240
+
241
+ .sp-header {
242
+ padding: 16px 16px 12px;
243
+ border-bottom: 1px solid #1a2035;
244
+ }
245
+
246
+ .sp-group-badge {
247
+ display: inline-block;
248
+ font-size: 9px;
249
+ font-weight: 700;
250
+ letter-spacing: 0.08em;
251
+ text-transform: uppercase;
252
+ border-radius: 3px;
253
+ padding: 2px 6px;
254
+ margin-bottom: 8px;
255
+ }
256
+
257
+ .sp-group-badge.ticket {
258
+ background: rgba(59, 130, 246, 0.15);
259
+ color: #60a5fa;
260
+ border: 1px solid rgba(59, 130, 246, 0.25);
261
+ }
262
+ .sp-group-badge.scenario {
263
+ background: rgba(16, 185, 129, 0.12);
264
+ color: #34d399;
265
+ border: 1px solid rgba(16, 185, 129, 0.2);
266
+ }
267
+ .sp-group-badge.scenario-fail {
268
+ background: rgba(239, 68, 68, 0.12);
269
+ color: #f87171;
270
+ border: 1px solid rgba(239, 68, 68, 0.2);
68
271
  }
69
- #sidepanel h3 {
70
- margin: 0 0 8px;
272
+ .sp-group-badge.pom {
273
+ background: rgba(245, 158, 11, 0.12);
274
+ color: #fbbf24;
275
+ border: 1px solid rgba(245, 158, 11, 0.2);
276
+ }
277
+
278
+ .sp-title {
71
279
  font-size: 14px;
280
+ font-weight: 600;
281
+ color: #f1f5f9;
282
+ line-height: 1.4;
283
+ margin: 0;
72
284
  }
73
- #sidepanel p {
74
- margin: 0 0 12px;
75
- font-size: 13px;
76
- color: #4b5563;
285
+
286
+ .sp-desc {
287
+ padding: 12px 16px;
288
+ font-size: 12px;
289
+ color: #64748b;
290
+ line-height: 1.6;
291
+ border-bottom: 1px solid #1a2035;
292
+ flex: 1;
293
+ }
294
+
295
+ .sp-actions {
296
+ padding: 12px 16px;
297
+ }
298
+
299
+ .sp-actions button {
300
+ background: linear-gradient(135deg, #1d4ed8, #4f46e5);
301
+ color: #eff6ff;
302
+ border: none;
303
+ border-radius: 6px;
304
+ padding: 7px 12px;
305
+ font-size: 12px;
306
+ font-weight: 500;
307
+ cursor: pointer;
308
+ width: 100%;
309
+ transition:
310
+ opacity 0.15s,
311
+ transform 0.1s;
312
+ letter-spacing: 0.01em;
313
+ }
314
+
315
+ .sp-actions button:hover {
316
+ opacity: 0.9;
317
+ }
318
+
319
+ .sp-actions button:active {
320
+ transform: scale(0.98);
77
321
  }
322
+
323
+ .sp-actions button.copied {
324
+ background: linear-gradient(135deg, #065f46, #047857);
325
+ }
326
+
327
+ /* ─── Footer ──────────────────────────────────────── */
78
328
  #footer {
79
329
  grid-column: 1 / -1;
80
- background: #f3f4f6;
81
- padding: 6px 16px;
82
- font-size: 11px;
83
- color: #6b7280;
84
- border-top: 1px solid #e5e7eb;
330
+ background: #050810;
331
+ padding: 4px 16px;
332
+ font-size: 10px;
333
+ color: #1e2d45;
334
+ border-top: 1px solid #0d1117;
335
+ display: flex;
336
+ align-items: center;
337
+ gap: 12px;
85
338
  }
86
- .disputed-outline {
87
- border: 2px dashed #ef4444;
339
+
340
+ #footer span {
341
+ color: #374151;
88
342
  }
@@ -7,23 +7,35 @@
7
7
  </head>
8
8
  <body>
9
9
  <header id="topbar">
10
- <div class="title">xera graph</div>
11
- <div class="stats">{{STATS}}</div>
12
- <div class="filters">
13
- <input type="text" id="search" placeholder="search…" />
14
- <label><input type="checkbox" id="filter-pass" checked> pass</label>
15
- <label><input type="checkbox" id="filter-fail" checked> fail</label>
16
- <label><input type="checkbox" id="filter-p0" checked> P0</label>
17
- <button id="reset">reset</button>
10
+ <div class="topbar-brand">
11
+ <div class="logo"></div>
12
+ <span class="title">xera graph</span>
13
+ </div>
14
+ <div id="stats-bar" data-stats="{{STATS}}"></div>
15
+ <div class="topbar-controls">
16
+ <input type="text" id="search" placeholder="search nodes…" autocomplete="off" />
17
+ <div class="filter-group">
18
+ <label id="label-pass"><input type="checkbox" id="filter-pass" checked /><span class="indicator" style="background:#3fb950"></span>pass</label>
19
+ <label id="label-fail"><input type="checkbox" id="filter-fail" checked /><span class="indicator" style="background:#f85149"></span>fail</label>
20
+ <label id="label-p0"><input type="checkbox" id="filter-p0" checked /><span class="indicator" style="background:#e3b341"></span>P0</label>
21
+ </div>
22
+ <button id="reset-btn">fit</button>
18
23
  </div>
19
24
  </header>
25
+ <div id="progress-wrap"><div id="progress-bar"></div></div>
20
26
  <main id="canvas"></main>
21
27
  <aside id="sidepanel" class="hidden">
22
- <h3 id="sp-title"></h3>
23
- <p id="sp-desc"></p>
24
- <div id="sp-actions"></div>
28
+ <div class="sp-header">
29
+ <div id="sp-group" class="sp-group-badge"></div>
30
+ <p id="sp-title" class="sp-title"></p>
31
+ </div>
32
+ <div id="sp-desc" class="sp-desc"></div>
33
+ <div id="sp-actions" class="sp-actions"></div>
25
34
  </aside>
26
- <footer id="footer">generated {{GENERATED_AT}} · double-click a node to open · right-click for options</footer>
35
+ <footer id="footer">
36
+ generated {{GENERATED_AT}}
37
+ <span>· scroll to zoom · drag to pan · click to inspect</span>
38
+ </footer>
27
39
  <script>{{VIS_NETWORK_JS}}</script>
28
40
  <script>window.__GRAPH__ = {{GRAPH_DATA}};</script>
29
41
  <script>{{INTERACTION_JS}}</script>