alignscope 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,663 @@
1
+ /* ==========================================================================
2
+ AlignScope — Design System
3
+ Clean, minimal, academic aesthetic. Research-grade observability tool.
4
+ Inspired by Observable HQ and scientific dashboards.
5
+ Environment-agnostic: works with any MARL configuration.
6
+ ========================================================================== */
7
+
8
+ /* ---------- Design Tokens ---------- */
9
+ :root {
10
+ /* Surfaces */
11
+ --bg-primary: #0f1117;
12
+ --bg-surface: #161922;
13
+ --bg-elevated: #1c1f2e;
14
+ --bg-hover: #222638;
15
+
16
+ /* Borders */
17
+ --border-subtle: #252836;
18
+ --border-default: #2e3245;
19
+ --border-strong: #3d4160;
20
+
21
+ /* Text */
22
+ --text-primary: #e4e4e7;
23
+ --text-secondary: #9ca3af;
24
+ --text-tertiary: #6b7280;
25
+ --text-muted: #4b5563;
26
+
27
+ /* Accent colors — restrained, purposeful */
28
+ --color-accent: #6d9eeb;
29
+ --color-defection: #dc4a4a;
30
+ --color-success: #4abe7d;
31
+ --color-warning: #d4a843;
32
+ --color-reciprocity-drop: #c97b3a;
33
+ --color-stability-drop: #b06ec7;
34
+ --color-coalition-frag: #d4a843;
35
+
36
+ /* Typography */
37
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
38
+ --font-mono: 'JetBrains Mono', 'Consolas', monospace;
39
+
40
+ /* Spacing */
41
+ --space-xs: 4px;
42
+ --space-sm: 8px;
43
+ --space-md: 12px;
44
+ --space-lg: 16px;
45
+ --space-xl: 24px;
46
+ --space-2xl: 32px;
47
+
48
+ /* Radii */
49
+ --radius-sm: 4px;
50
+ --radius-md: 6px;
51
+ --radius-lg: 8px;
52
+
53
+ /* Transitions */
54
+ --transition-fast: 120ms ease;
55
+ --transition-default: 200ms ease;
56
+ --transition-slow: 400ms ease;
57
+ }
58
+
59
+ /* ---------- Reset & Base ---------- */
60
+ *, *::before, *::after {
61
+ box-sizing: border-box;
62
+ margin: 0;
63
+ padding: 0;
64
+ }
65
+
66
+ html, body {
67
+ height: 100%;
68
+ overflow: hidden;
69
+ }
70
+
71
+ body {
72
+ font-family: var(--font-sans);
73
+ font-size: 13px;
74
+ line-height: 1.5;
75
+ color: var(--text-primary);
76
+ background: var(--bg-primary);
77
+ -webkit-font-smoothing: antialiased;
78
+ -moz-osx-font-smoothing: grayscale;
79
+ }
80
+
81
+ .mono {
82
+ font-family: var(--font-mono);
83
+ font-size: 12px;
84
+ }
85
+
86
+ /* ---------- Header ---------- */
87
+ #header {
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: space-between;
91
+ height: 48px;
92
+ padding: 0 var(--space-xl);
93
+ background: var(--bg-surface);
94
+ border-bottom: 1px solid var(--border-subtle);
95
+ user-select: none;
96
+ flex-shrink: 0;
97
+ }
98
+
99
+ .header-left {
100
+ display: flex;
101
+ align-items: center;
102
+ gap: var(--space-md);
103
+ }
104
+
105
+ .logo {
106
+ font-size: 15px;
107
+ font-weight: 600;
108
+ letter-spacing: -0.02em;
109
+ color: var(--text-primary);
110
+ }
111
+
112
+ .logo-accent {
113
+ color: var(--color-accent);
114
+ }
115
+
116
+ .header-divider {
117
+ width: 1px;
118
+ height: 20px;
119
+ background: var(--border-default);
120
+ }
121
+
122
+ .header-subtitle {
123
+ font-size: 12px;
124
+ color: var(--text-tertiary);
125
+ letter-spacing: 0.04em;
126
+ text-transform: uppercase;
127
+ font-weight: 500;
128
+ }
129
+
130
+ .header-center {
131
+ display: flex;
132
+ align-items: center;
133
+ }
134
+
135
+ .status-group {
136
+ display: flex;
137
+ gap: var(--space-xl);
138
+ }
139
+
140
+ .status-item {
141
+ display: flex;
142
+ align-items: center;
143
+ gap: var(--space-sm);
144
+ }
145
+
146
+ .status-label {
147
+ font-size: 11px;
148
+ color: var(--text-tertiary);
149
+ text-transform: uppercase;
150
+ letter-spacing: 0.06em;
151
+ font-weight: 500;
152
+ }
153
+
154
+ .status-value {
155
+ font-size: 14px;
156
+ font-weight: 600;
157
+ color: var(--text-primary);
158
+ }
159
+
160
+ .status-max {
161
+ color: var(--text-muted);
162
+ font-size: 12px;
163
+ }
164
+
165
+ .header-right {
166
+ display: flex;
167
+ align-items: center;
168
+ gap: var(--space-lg);
169
+ }
170
+
171
+ /* ---------- Buttons ---------- */
172
+ .btn {
173
+ display: inline-flex;
174
+ align-items: center;
175
+ gap: var(--space-xs);
176
+ padding: 5px 12px;
177
+ font-family: var(--font-sans);
178
+ font-size: 12px;
179
+ font-weight: 500;
180
+ border: 1px solid var(--border-default);
181
+ border-radius: var(--radius-md);
182
+ cursor: pointer;
183
+ transition: all var(--transition-fast);
184
+ white-space: nowrap;
185
+ }
186
+
187
+ .btn-secondary {
188
+ background: var(--bg-elevated);
189
+ color: var(--text-secondary);
190
+ }
191
+
192
+ .btn-secondary:hover {
193
+ background: var(--bg-hover);
194
+ color: var(--text-primary);
195
+ border-color: var(--border-strong);
196
+ }
197
+
198
+ .btn-close {
199
+ background: none;
200
+ border: none;
201
+ color: var(--text-tertiary);
202
+ cursor: pointer;
203
+ font-size: 16px;
204
+ padding: 2px 6px;
205
+ border-radius: var(--radius-sm);
206
+ transition: all var(--transition-fast);
207
+ }
208
+
209
+ .btn-close:hover {
210
+ color: var(--text-primary);
211
+ background: var(--bg-hover);
212
+ }
213
+
214
+ /* ---------- Connection Status ---------- */
215
+ .connection-status {
216
+ display: flex;
217
+ align-items: center;
218
+ gap: 6px;
219
+ font-size: 11px;
220
+ color: var(--text-tertiary);
221
+ }
222
+
223
+ .connection-dot {
224
+ width: 6px;
225
+ height: 6px;
226
+ border-radius: 50%;
227
+ background: var(--text-muted);
228
+ transition: background var(--transition-default);
229
+ }
230
+
231
+ .connection-status.connected .connection-dot {
232
+ background: var(--color-success);
233
+ }
234
+
235
+ .connection-status.disconnected .connection-dot {
236
+ background: var(--color-defection);
237
+ }
238
+
239
+ /* ---------- Main Layout ---------- */
240
+ #main-layout {
241
+ display: grid;
242
+ grid-template-columns: 1fr 300px;
243
+ gap: 0;
244
+ height: calc(100vh - 48px - 160px);
245
+ overflow: hidden;
246
+ }
247
+
248
+ /* ---------- Panels ---------- */
249
+ .panel {
250
+ display: flex;
251
+ flex-direction: column;
252
+ background: var(--bg-surface);
253
+ overflow: hidden;
254
+ }
255
+
256
+ .panel-topology {
257
+ border-right: 1px solid var(--border-subtle);
258
+ }
259
+
260
+ .panel-metrics {
261
+ overflow-y: auto;
262
+ }
263
+
264
+ .panel-timeline {
265
+ height: 160px;
266
+ border-top: 1px solid var(--border-subtle);
267
+ flex-shrink: 0;
268
+ }
269
+
270
+ .panel-header {
271
+ display: flex;
272
+ align-items: center;
273
+ justify-content: space-between;
274
+ padding: var(--space-sm) var(--space-lg);
275
+ border-bottom: 1px solid var(--border-subtle);
276
+ flex-shrink: 0;
277
+ min-height: 36px;
278
+ }
279
+
280
+ .panel-title {
281
+ font-size: 12px;
282
+ font-weight: 600;
283
+ color: var(--text-secondary);
284
+ letter-spacing: 0.02em;
285
+ text-transform: uppercase;
286
+ }
287
+
288
+ .panel-badge {
289
+ font-family: var(--font-mono);
290
+ font-size: 11px;
291
+ color: var(--text-tertiary);
292
+ padding: 2px 8px;
293
+ background: var(--bg-primary);
294
+ border-radius: var(--radius-sm);
295
+ border: 1px solid var(--border-subtle);
296
+ }
297
+
298
+ .panel-body {
299
+ flex: 1;
300
+ position: relative;
301
+ overflow: hidden;
302
+ }
303
+
304
+ /* ---------- Topology Graph ---------- */
305
+ #topology-svg {
306
+ width: 100%;
307
+ height: 100%;
308
+ }
309
+
310
+ .topology-legend {
311
+ position: absolute;
312
+ bottom: var(--space-lg);
313
+ left: var(--space-lg);
314
+ display: flex;
315
+ gap: var(--space-xl);
316
+ padding: var(--space-sm) var(--space-md);
317
+ background: rgba(15, 17, 23, 0.85);
318
+ border: 1px solid var(--border-subtle);
319
+ border-radius: var(--radius-md);
320
+ font-size: 11px;
321
+ color: var(--text-secondary);
322
+ backdrop-filter: blur(4px);
323
+ }
324
+
325
+ .legend-section {
326
+ display: flex;
327
+ flex-direction: column;
328
+ gap: 3px;
329
+ }
330
+
331
+ .legend-title {
332
+ font-size: 10px;
333
+ font-weight: 600;
334
+ color: var(--text-tertiary);
335
+ text-transform: uppercase;
336
+ letter-spacing: 0.06em;
337
+ margin-bottom: 2px;
338
+ }
339
+
340
+ .legend-item {
341
+ display: flex;
342
+ align-items: center;
343
+ gap: 6px;
344
+ }
345
+
346
+ .legend-dot {
347
+ width: 8px;
348
+ height: 8px;
349
+ border-radius: 50%;
350
+ }
351
+
352
+ .legend-shape {
353
+ font-size: 10px;
354
+ width: 12px;
355
+ text-align: center;
356
+ color: var(--text-secondary);
357
+ }
358
+
359
+ .legend-line {
360
+ width: 18px;
361
+ height: 2px;
362
+ background: var(--text-secondary);
363
+ border-radius: 1px;
364
+ }
365
+
366
+ /* ---------- Metrics Sidebar ---------- */
367
+ #metrics-container {
368
+ padding: var(--space-md);
369
+ display: flex;
370
+ flex-direction: column;
371
+ gap: var(--space-md);
372
+ overflow-y: auto;
373
+ }
374
+
375
+ .metric-card {
376
+ padding: var(--space-md);
377
+ background: var(--bg-primary);
378
+ border: 1px solid var(--border-subtle);
379
+ border-radius: var(--radius-md);
380
+ }
381
+
382
+ .metric-header {
383
+ display: flex;
384
+ justify-content: space-between;
385
+ align-items: center;
386
+ margin-bottom: var(--space-sm);
387
+ }
388
+
389
+ .metric-name {
390
+ font-size: 12px;
391
+ font-weight: 500;
392
+ color: var(--text-secondary);
393
+ }
394
+
395
+ .metric-value {
396
+ font-size: 20px;
397
+ font-weight: 600;
398
+ color: var(--text-primary);
399
+ }
400
+
401
+ .metric-bar-container {
402
+ height: 4px;
403
+ background: var(--bg-hover);
404
+ border-radius: 2px;
405
+ overflow: hidden;
406
+ }
407
+
408
+ .metric-bar {
409
+ height: 100%;
410
+ width: 0%;
411
+ background: var(--color-accent);
412
+ border-radius: 2px;
413
+ transition: width var(--transition-default);
414
+ }
415
+
416
+ .metric-group {
417
+ padding: var(--space-md);
418
+ background: var(--bg-primary);
419
+ border: 1px solid var(--border-subtle);
420
+ border-radius: var(--radius-md);
421
+ }
422
+
423
+ .metric-group-header {
424
+ display: flex;
425
+ align-items: center;
426
+ gap: var(--space-sm);
427
+ margin-bottom: var(--space-sm);
428
+ padding-bottom: var(--space-sm);
429
+ border-bottom: 1px solid var(--border-subtle);
430
+ }
431
+
432
+ .team-dot {
433
+ width: 8px;
434
+ height: 8px;
435
+ border-radius: 50%;
436
+ flex-shrink: 0;
437
+ }
438
+
439
+ .metric-group-title {
440
+ font-size: 12px;
441
+ font-weight: 600;
442
+ color: var(--text-primary);
443
+ }
444
+
445
+ .metric-row {
446
+ display: flex;
447
+ justify-content: space-between;
448
+ align-items: center;
449
+ padding: 3px 0;
450
+ }
451
+
452
+ .metric-label {
453
+ font-size: 11px;
454
+ color: var(--text-tertiary);
455
+ }
456
+
457
+ .metric-val {
458
+ font-size: 12px;
459
+ font-weight: 500;
460
+ color: var(--text-primary);
461
+ }
462
+
463
+ .metric-mini-bar-container {
464
+ height: 3px;
465
+ background: var(--bg-hover);
466
+ border-radius: 2px;
467
+ overflow: hidden;
468
+ margin: 2px 0 4px;
469
+ }
470
+
471
+ .metric-mini-bar {
472
+ height: 100%;
473
+ width: 0%;
474
+ border-radius: 2px;
475
+ transition: width var(--transition-default);
476
+ }
477
+
478
+ /* Agent detail */
479
+ .agent-detail {
480
+ border-color: var(--color-accent);
481
+ }
482
+
483
+ .hidden {
484
+ display: none !important;
485
+ }
486
+
487
+ /* ---------- Timeline ---------- */
488
+ .timeline-body {
489
+ padding: var(--space-sm) var(--space-lg);
490
+ }
491
+
492
+ #timeline-canvas {
493
+ width: 100%;
494
+ height: 100%;
495
+ display: block;
496
+ }
497
+
498
+ .timeline-tooltip {
499
+ position: absolute;
500
+ bottom: 100%;
501
+ left: 0;
502
+ margin-bottom: 8px;
503
+ padding: var(--space-sm) var(--space-md);
504
+ background: var(--bg-elevated);
505
+ border: 1px solid var(--border-default);
506
+ border-radius: var(--radius-md);
507
+ font-size: 11px;
508
+ max-width: 320px;
509
+ pointer-events: none;
510
+ z-index: 100;
511
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
512
+ }
513
+
514
+ .tooltip-header {
515
+ font-weight: 600;
516
+ color: var(--text-primary);
517
+ margin-bottom: 4px;
518
+ }
519
+
520
+ .tooltip-body {
521
+ color: var(--text-secondary);
522
+ line-height: 1.4;
523
+ }
524
+
525
+ /* Sparkline canvas */
526
+ .sparkline-container {
527
+ width: 100%;
528
+ overflow-x: auto;
529
+ overflow-y: hidden;
530
+ scrollbar-color: var(--text-muted) transparent; /* Firefox */
531
+ scrollbar-width: thin;
532
+ }
533
+
534
+ .sparkline-container::-webkit-scrollbar {
535
+ height: 4px; /* Thin horizontal line */
536
+ background: transparent; /* Remove native white background */
537
+ }
538
+ .sparkline-container::-webkit-scrollbar-track {
539
+ background: transparent;
540
+ }
541
+ .sparkline-container::-webkit-scrollbar-thumb {
542
+ background: var(--text-muted); /* Dark grey thumb */
543
+ border-radius: 4px;
544
+ }
545
+ .sparkline-container::-webkit-scrollbar-thumb:hover {
546
+ background: var(--text-secondary); /* Lighter on hover */
547
+ }
548
+ .sparkline-container::-webkit-scrollbar-corner {
549
+ background: transparent;
550
+ }
551
+
552
+ #alignment-sparkline {
553
+ display: block;
554
+ height: 80px;
555
+ }
556
+
557
+ /* ---------- Scrollbar ---------- */
558
+ .panel-metrics::-webkit-scrollbar,
559
+ #metrics-container::-webkit-scrollbar {
560
+ width: 4px;
561
+ }
562
+
563
+ .panel-metrics::-webkit-scrollbar-track,
564
+ #metrics-container::-webkit-scrollbar-track {
565
+ background: transparent;
566
+ }
567
+
568
+ .panel-metrics::-webkit-scrollbar-thumb,
569
+ #metrics-container::-webkit-scrollbar-thumb {
570
+ background: var(--border-default);
571
+ border-radius: 2px;
572
+ }
573
+
574
+ /* ---------- Defection marker highlight ---------- */
575
+ .defection-marker {
576
+ fill: var(--color-defection);
577
+ }
578
+
579
+ /* Node styles */
580
+ @keyframes defectorPulse {
581
+ 0% { filter: drop-shadow(0 0 2px var(--color-defection)); transform: scale(1); }
582
+ 50% { filter: drop-shadow(0 0 12px var(--color-defection)); transform: scale(1.15); }
583
+ 100% { filter: drop-shadow(0 0 2px var(--color-defection)); transform: scale(1); }
584
+ }
585
+ .node-defector {
586
+ animation: defectorPulse 1.2s infinite ease-in-out;
587
+ transform-origin: center;
588
+ }
589
+
590
+ .node-circle {
591
+ stroke-width: 1.5;
592
+ cursor: pointer;
593
+ transition: r var(--transition-fast);
594
+ }
595
+
596
+ .node-circle:hover {
597
+ filter: brightness(1.3);
598
+ }
599
+
600
+ .node-label {
601
+ font-family: var(--font-mono);
602
+ font-size: 10px;
603
+ fill: var(--text-tertiary);
604
+ pointer-events: none;
605
+ user-select: none;
606
+ }
607
+
608
+ .link-line {
609
+ stroke: var(--text-muted);
610
+ fill: none;
611
+ }
612
+
613
+ /* Defector node pulsing */
614
+ @keyframes defector-pulse {
615
+ 0%, 100% { opacity: 1; }
616
+ 50% { opacity: 0.4; }
617
+ }
618
+
619
+ .node-defector {
620
+ animation: defector-pulse 1.5s ease-in-out infinite;
621
+ }
622
+
623
+ /* ---------- Responsive ---------- */
624
+ @media (max-width: 900px) {
625
+ #main-layout {
626
+ grid-template-columns: 1fr;
627
+ grid-template-rows: 1fr auto;
628
+ }
629
+
630
+ .panel-metrics {
631
+ max-height: 250px;
632
+ }
633
+
634
+ .panel-topology {
635
+ border-right: none;
636
+ border-bottom: 1px solid var(--border-subtle);
637
+ }
638
+ }
639
+
640
+ /* Timeline Horizontal Scroll support */
641
+ #timeline-container {
642
+ overflow-x: auto;
643
+ overflow-y: hidden;
644
+ padding-bottom: 8px; /* Lift canvas slightly off bottom */
645
+ }
646
+
647
+ /* Custom thin scrollbar for timeline */
648
+ #timeline-container::-webkit-scrollbar {
649
+ height: 8px; /* Thin line */
650
+ }
651
+
652
+ #timeline-container::-webkit-scrollbar-track {
653
+ background: transparent;
654
+ }
655
+
656
+ #timeline-container::-webkit-scrollbar-thumb {
657
+ background-color: rgba(255, 255, 255, 0.15);
658
+ border-radius: 4px;
659
+ }
660
+
661
+ #timeline-container::-webkit-scrollbar-thumb:hover {
662
+ background-color: rgba(255, 255, 255, 0.3);
663
+ }