@gtadi/k8s-node-debugger 1.0.0

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,866 @@
1
+ :root {
2
+ --bg: #0e1116;
3
+ --bg-2: #161b22;
4
+ --bg-3: #1c2330;
5
+ --border: #2a3240;
6
+ --fg: #d7dde6;
7
+ --fg-dim: #8b95a3;
8
+ --accent: #4f9dff;
9
+ --accent-2: #2dd4bf;
10
+ --ok: #3fb950;
11
+ --err: #f85149;
12
+ --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
13
+ }
14
+
15
+ * { box-sizing: border-box; }
16
+
17
+ html, body {
18
+ margin: 0;
19
+ height: 100%;
20
+ background: var(--bg);
21
+ color: var(--fg);
22
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
23
+ font-size: 14px;
24
+ }
25
+
26
+ #topbar {
27
+ display: flex;
28
+ align-items: center;
29
+ gap: 20px;
30
+ padding: 0 20px;
31
+ height: 66px;
32
+ flex-shrink: 0;
33
+ background: linear-gradient(160deg, #0d1f3c 0%, #111820 55%, #0e1116 100%);
34
+ border-bottom: 2px solid var(--accent);
35
+ box-shadow: 0 3px 16px rgba(0, 0, 0, 0.5);
36
+ }
37
+
38
+ .brand {
39
+ display: flex; align-items: center; gap: 10px;
40
+ font-size: 15px; font-weight: 700; color: #fff;
41
+ white-space: nowrap; flex-shrink: 0;
42
+ border-right: 1px solid var(--border);
43
+ padding-right: 20px; height: 100%;
44
+ }
45
+ .brand .logo { color: var(--accent-2); font-size: 22px; line-height: 1; }
46
+
47
+ /* two-line session block */
48
+ .session { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 5px; }
49
+
50
+ .session-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
51
+ .tb-ctx {
52
+ background: #0d1e38; color: #79c0ff; border: 1px solid #1a3a6a;
53
+ padding: 3px 10px; border-radius: 12px;
54
+ font-size: 11.5px; font-family: var(--mono); font-weight: 600;
55
+ white-space: nowrap; flex-shrink: 0;
56
+ }
57
+ .tb-arrow { color: #3a4a60; font-size: 14px; flex-shrink: 0; }
58
+ .tb-node {
59
+ font-family: var(--mono); font-size: 15px; font-weight: 700;
60
+ color: var(--accent-2); white-space: nowrap;
61
+ overflow: hidden; text-overflow: ellipsis;
62
+ letter-spacing: .01em;
63
+ }
64
+
65
+ .session-sub { display: flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 11.5px; }
66
+ .tb-badge {
67
+ background: var(--bg-3); border: 1px solid var(--border);
68
+ padding: 1px 8px; border-radius: 8px; color: var(--fg-dim);
69
+ white-space: nowrap;
70
+ }
71
+ .tb-badge b { color: #9aa5b8; font-weight: 600; }
72
+ .tb-dot { color: var(--border); font-size: 10px; }
73
+
74
+ .actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
75
+ .actions button {
76
+ background: var(--bg-3); color: var(--fg-dim); border: 1px solid var(--border);
77
+ padding: 7px 16px; border-radius: 7px; cursor: pointer;
78
+ font-size: 13px; font-weight: 500; white-space: nowrap;
79
+ transition: border-color .15s, color .15s, background .15s;
80
+ }
81
+ .actions button:hover { border-color: var(--accent); color: var(--fg); }
82
+ #snapshot-btn { background: #0c2218; border-color: #1a4a30; color: #4ade80; }
83
+ #snapshot-btn:hover { background: #132e20; border-color: var(--ok); color: #6ee89b; }
84
+
85
+ .tb-gh-link {
86
+ display: flex; align-items: center; gap: 6px;
87
+ color: var(--fg-dim); text-decoration: none;
88
+ background: var(--bg-3); border: 1px solid var(--border);
89
+ padding: 7px 14px; border-radius: 7px;
90
+ font-size: 13px; font-weight: 500; white-space: nowrap;
91
+ transition: border-color .15s, color .15s;
92
+ }
93
+ .tb-gh-link:hover { border-color: var(--accent); color: var(--fg); }
94
+ .tb-gh-link svg { flex-shrink: 0; }
95
+
96
+ .term-toolbar button {
97
+ background: var(--bg-3); color: var(--fg); border: 1px solid var(--border);
98
+ padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 13px;
99
+ }
100
+ .term-toolbar button:hover { border-color: var(--accent); }
101
+
102
+ #layout { display: flex; height: calc(100vh - 67px); }
103
+
104
+ #sidebar {
105
+ width: 220px; flex-shrink: 0; background: var(--bg-2);
106
+ border-right: 1px solid var(--border); overflow-y: auto; padding: 10px 0;
107
+ }
108
+ .nav-group {
109
+ display: flex; align-items: center; gap: 10px;
110
+ padding: 18px 14px 6px;
111
+ color: #8fa3be;
112
+ font-size: 12px; font-weight: 700;
113
+ text-transform: uppercase; letter-spacing: .1em;
114
+ }
115
+ .nav-group::before {
116
+ content: ''; flex: 1; height: 1px;
117
+ background: linear-gradient(90deg, var(--border), transparent);
118
+ order: 2;
119
+ }
120
+ .nav-group:first-child { padding-top: 10px; }
121
+ .nav-item {
122
+ padding: 7px 16px; cursor: pointer; color: var(--fg);
123
+ display: flex; align-items: center; justify-content: space-between; gap: 8px;
124
+ border-left: 2px solid transparent;
125
+ }
126
+ .nav-item:hover { background: var(--bg-3); }
127
+ .nav-item.active { background: var(--bg-3); border-left-color: var(--accent); color: #fff; }
128
+ .nav-item .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fg-dim); flex-shrink: 0; }
129
+ .nav-item .dot.ok { background: var(--ok); }
130
+ .nav-item .dot.err { background: var(--err); }
131
+ .nav-item .dot.loading { background: var(--accent); animation: pulse 1s infinite; }
132
+ @keyframes pulse { 50% { opacity: .3; } }
133
+
134
+ #main { flex: 1; overflow-y: auto; padding: 22px 26px; }
135
+
136
+ .panel { display: none; }
137
+ .panel.active { display: block; }
138
+ .panel h2 { margin: 0 0 14px; font-size: 18px; font-weight: 600; }
139
+ .panel h2 small { color: var(--fg-dim); font-weight: 400; font-size: 13px; }
140
+
141
+ .card {
142
+ background: var(--bg-2); border: 1px solid var(--border);
143
+ border-radius: 8px; padding: 16px;
144
+ }
145
+
146
+ .kv { display: grid; grid-template-columns: 160px 1fr; gap: 6px 16px; font-size: 13.5px; }
147
+ .kv .k { color: var(--fg-dim); }
148
+ .kv .v { font-family: var(--mono); word-break: break-all; }
149
+
150
+ .probe-head {
151
+ display: flex; align-items: center; gap: 12px; margin-bottom: 10px; flex-wrap: wrap;
152
+ }
153
+ .probe-head .cmd {
154
+ font-family: var(--mono); font-size: 12px; color: var(--accent-2);
155
+ background: var(--bg-3); padding: 3px 8px; border-radius: 5px;
156
+ }
157
+ .probe-head .desc { color: var(--fg-dim); font-size: 13px; }
158
+ .probe-head button {
159
+ margin-left: auto; background: var(--bg-3); color: var(--fg);
160
+ border: 1px solid var(--border); padding: 5px 10px; border-radius: 6px; cursor: pointer;
161
+ }
162
+ .probe-head button:hover { border-color: var(--accent); }
163
+
164
+ pre.output {
165
+ background: #0a0d12; border: 1px solid var(--border); border-radius: 8px;
166
+ padding: 14px 16px; overflow: auto; max-height: calc(100vh - 230px);
167
+ font-family: var(--mono); font-size: 12.5px; line-height: 1.5;
168
+ white-space: pre; color: #c9d4e2; margin: 0;
169
+ }
170
+ pre.output.error { color: var(--err); }
171
+ .empty { color: var(--fg-dim); font-style: italic; }
172
+
173
+ /* ── iptables fancy view ─────────────────────────────────────────────── */
174
+
175
+ .ipt-container { min-height: 40px; }
176
+
177
+ .ipt-wrap { display: flex; flex-direction: column; gap: 10px; }
178
+
179
+ /* top bar */
180
+ .ipt-bar {
181
+ display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
182
+ background: var(--bg-2); border: 1px solid var(--border);
183
+ padding: 9px 14px; border-radius: 8px;
184
+ }
185
+ .ipt-stats { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
186
+ .ipt-stat { font-size: 13px; color: var(--fg-dim); }
187
+ .ipt-stat b { color: var(--fg); font-weight: 600; }
188
+ .ipt-sep { color: var(--border); }
189
+ .ipt-search {
190
+ flex: 1; min-width: 180px; background: #0a0d12; border: 1px solid var(--border);
191
+ color: var(--fg); padding: 6px 10px; border-radius: 6px;
192
+ font-size: 13px; font-family: var(--mono);
193
+ }
194
+ .ipt-search:focus { outline: none; border-color: var(--accent); }
195
+ .ipt-bar-actions { display: flex; gap: 6px; }
196
+ .ipt-btn {
197
+ background: var(--bg-3); color: var(--fg); border: 1px solid var(--border);
198
+ padding: 5px 10px; border-radius: 6px; cursor: pointer; font-size: 12px;
199
+ white-space: nowrap;
200
+ }
201
+ .ipt-btn:hover { border-color: var(--accent); color: var(--accent); }
202
+
203
+ /* table tabs */
204
+ .ipt-tabs { display: flex; gap: 4px; flex-wrap: wrap; }
205
+ .ipt-tab {
206
+ background: var(--bg-2); color: var(--fg-dim); border: 1px solid var(--border);
207
+ padding: 6px 14px; border-radius: 6px 6px 0 0; cursor: pointer;
208
+ font-size: 13px; font-weight: 500; border-bottom-color: transparent;
209
+ }
210
+ .ipt-tab:hover { background: var(--bg-3); color: var(--fg); }
211
+ .ipt-tab.active {
212
+ background: var(--bg-3); color: var(--fg);
213
+ border-color: var(--accent) var(--accent) transparent;
214
+ }
215
+ .ipt-tab small { color: var(--fg-dim); font-size: 11px; margin-left: 4px; }
216
+
217
+ /* body */
218
+ .ipt-body {
219
+ background: var(--bg-2); border: 1px solid var(--border);
220
+ border-radius: 0 8px 8px 8px; overflow: hidden; display: flex; flex-direction: column; gap: 1px;
221
+ }
222
+ .ipt-raw-view { margin: 0; border-radius: 0 8px 8px 8px !important; }
223
+
224
+ /* chain card */
225
+ .ipt-chain { background: var(--bg); border-bottom: 1px solid var(--border); }
226
+ .ipt-chain:last-child { border-bottom: none; }
227
+
228
+ .ipt-chain-hdr {
229
+ display: flex; align-items: center; gap: 8px; padding: 9px 14px;
230
+ cursor: pointer; user-select: none;
231
+ background: var(--bg-2);
232
+ transition: background .1s;
233
+ }
234
+ .ipt-chain-hdr:hover { background: var(--bg-3); }
235
+ .ipt-chain-chevron { font-size: 11px; color: var(--fg-dim); flex-shrink: 0; width: 12px; }
236
+ .ipt-chain-name { font-family: var(--mono); font-weight: 600; font-size: 14px; color: var(--fg); }
237
+
238
+ /* chain badges */
239
+ .ipt-badge {
240
+ font-size: 10px; font-weight: 600; padding: 1px 6px;
241
+ border-radius: 10px; letter-spacing: .03em;
242
+ }
243
+ .ipt-badge-k8s { background: #0d3344; color: var(--accent-2); border: 1px solid #1a5566; }
244
+ .ipt-badge-docker { background: #0a2d4a; color: #58a6ff; border: 1px solid #1a3d6a; }
245
+
246
+ /* policy badge */
247
+ .ipt-policy {
248
+ font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 10px;
249
+ letter-spacing: .04em; flex-shrink: 0;
250
+ }
251
+ .ipt-policy-accept { background: #0d3321; color: var(--ok); border: 1px solid #1a4a32; }
252
+ .ipt-policy-drop { background: #3d1515; color: var(--err); border: 1px solid #6a2525; }
253
+ .ipt-policy-other { background: var(--bg-3); color: var(--fg-dim); border: 1px solid var(--border); }
254
+
255
+ .ipt-chain-rcount { font-size: 12px; color: var(--fg-dim); }
256
+ .ipt-chain-counter {
257
+ font-size: 11px; color: var(--fg-dim); font-family: var(--mono);
258
+ margin-left: auto;
259
+ }
260
+
261
+ /* collapsed state */
262
+ .ipt-chain.collapsed .ipt-chain-body { display: none; }
263
+
264
+ /* no-rules placeholder */
265
+ .ipt-no-rules {
266
+ padding: 10px 18px; font-size: 13px; color: var(--fg-dim); font-style: italic;
267
+ }
268
+
269
+ /* rules table */
270
+ .ipt-rules {
271
+ width: 100%; border-collapse: collapse; font-size: 13px;
272
+ }
273
+ .ipt-rules thead tr {
274
+ background: #0e1319; border-bottom: 1px solid var(--border);
275
+ }
276
+ .ipt-rules thead th {
277
+ padding: 6px 12px; text-align: left; font-size: 11px;
278
+ color: var(--fg-dim); font-weight: 500; letter-spacing: .04em;
279
+ text-transform: uppercase;
280
+ }
281
+ .ipt-rule {
282
+ cursor: pointer; border-bottom: 1px solid #1a2030;
283
+ transition: background .08s;
284
+ }
285
+ .ipt-rule:last-child { border-bottom: none; }
286
+ .ipt-rule:hover { background: #161d2a; }
287
+ .ipt-rule td { padding: 8px 12px; vertical-align: top; }
288
+
289
+ .col-num { width: 36px; }
290
+ .col-target { width: 120px; }
291
+ .col-proto { width: 64px; }
292
+ .col-addr { width: 130px; }
293
+
294
+ .ipt-rule-num { color: var(--fg-dim); font-family: var(--mono); font-size: 12px; text-align: right; }
295
+
296
+ /* target badges */
297
+ .ipt-target {
298
+ display: inline-block; padding: 3px 9px; border-radius: 5px;
299
+ font-size: 11.5px; font-weight: 700; font-family: var(--mono);
300
+ letter-spacing: .02em; cursor: help; white-space: nowrap;
301
+ }
302
+ .ipt-target-accept { background:#0d2b1e; color:#3fb950; border:1px solid #1e5c3a; }
303
+ .ipt-target-drop { background:#2d0f0f; color:#f85149; border:1px solid #5c2020; }
304
+ .ipt-target-reject { background:#3a1010; color:#ff7b72; border:1px solid #6a2828; }
305
+ .ipt-target-log { background:#2a2000; color:#d29922; border:1px solid #5a4500; }
306
+ .ipt-target-masq { background:#200d38; color:#bc8cff; border:1px solid #4a2070; }
307
+ .ipt-target-nat { background:#0d1e3a; color:#58a6ff; border:1px solid #1a3a6a; }
308
+ .ipt-target-redirect { background:#2a1800; color:#ff9e2c; border:1px solid #5a3800; }
309
+ .ipt-target-return { background:#1a1e26; color:#8b97a8; border:1px solid #2a3040; }
310
+ .ipt-target-mark { background:#222000; color:#e3b341; border:1px solid #4a4000; }
311
+ .ipt-target-k8s { background:#0d2d2d; color:#2dd4bf; border:1px solid #1a5555; }
312
+ .ipt-target-docker { background:#0a1e38; color:#79c0ff; border:1px solid #1a3a60; }
313
+ .ipt-target-jump { background:#1a1e2a; color:#79c0ff; border:1px solid #2a3048; }
314
+
315
+ /* rule description cell */
316
+ .ipt-rule-summary { color: var(--fg); line-height: 1.4; }
317
+ .ipt-rule-tags { margin-top: 4px; display: flex; flex-wrap: wrap; gap: 4px; }
318
+ .ipt-tag {
319
+ font-family: var(--mono); font-size: 11px; padding: 1px 6px; border-radius: 4px;
320
+ background: var(--bg-3); color: var(--fg-dim); border: 1px solid var(--border);
321
+ }
322
+ .ipt-tag-state { color: #58a6ff; border-color: #1a3a6a; background: #0d1e38; }
323
+ .ipt-tag-port { color: var(--accent-2); border-color: #1a4a44; background: #0d2828; }
324
+ .ipt-tag-addr { color: #e3b341; border-color: #4a4000; background: #222000; }
325
+ .ipt-tag-iface { color: #bc8cff; border-color: #4a2070; background: #200d38; }
326
+ .ipt-tag-proto { color: #ff9e2c; border-color: #5a3800; background: #2a1800; }
327
+ .ipt-tag-comment { color: var(--fg-dim); font-style: italic; }
328
+
329
+ /* raw rule (revealed on click) */
330
+ .ipt-rule-raw {
331
+ display: none; margin-top: 6px; padding: 6px 10px;
332
+ background: #0a0d12; border-radius: 5px;
333
+ font-family: var(--mono); font-size: 11.5px; color: #6e7f95;
334
+ border: 1px solid var(--border); word-break: break-all;
335
+ }
336
+ .ipt-rule-raw.visible { display: block; }
337
+
338
+ /* protocol chip */
339
+ .ipt-proto {
340
+ display: inline-block; padding: 2px 7px; border-radius: 4px;
341
+ font-family: var(--mono); font-size: 11px; font-weight: 600;
342
+ }
343
+ .ipt-proto-tcp { background:#0d1e38; color:#58a6ff; }
344
+ .ipt-proto-udp { background:#2a1800; color:#ff9e2c; }
345
+ .ipt-proto-icmp { background:#222000; color:#e3b341; }
346
+ .ipt-proto-all { background:var(--bg-3); color:var(--fg-dim); }
347
+
348
+ .col-addr code {
349
+ font-family: var(--mono); font-size: 12px;
350
+ background: var(--bg-3); padding: 1px 5px; border-radius: 4px;
351
+ color: var(--accent-2);
352
+ }
353
+ .dim { color: var(--fg-dim); }
354
+
355
+ /* legend */
356
+ .ipt-legend {
357
+ display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 0;
358
+ }
359
+ .ipt-legend .ipt-target { font-size: 11px; padding: 2px 8px; cursor: default; }
360
+
361
+ .ipt-empty { padding: 20px; color: var(--fg-dim); font-style: italic; }
362
+
363
+ /* ── conntrack rich views ────────────────────────────────────────────── */
364
+
365
+ .ct-wrap { display:flex; flex-direction:column; gap:12px; }
366
+ .ct-empty-msg { padding:20px; color:var(--fg-dim); font-style:italic; }
367
+
368
+ /* stat cards */
369
+ .ct-cards {
370
+ display:flex; gap:10px; flex-wrap:wrap;
371
+ }
372
+ .ct-card {
373
+ background:var(--bg-2); border:1px solid var(--border);
374
+ border-radius:8px; padding:14px 18px; flex:1; min-width:110px;
375
+ border-top-width:3px;
376
+ }
377
+ .ct-card-total { border-top-color:#58a6ff; }
378
+ .ct-card-estab { border-top-color:#3fb950; }
379
+ .ct-card-tw { border-top-color:#d29922; }
380
+ .ct-card-udp { border-top-color:#ff9e2c; }
381
+ .ct-card-icmp { border-top-color:#e3b341; }
382
+ .ct-card-other { border-top-color:#8b97a8; }
383
+ .ct-card-bytes { border-top-color:#bc8cff; }
384
+
385
+ .ct-card-val { font-size:22px; font-weight:700; font-family:var(--mono); color:var(--fg); }
386
+ .ct-card-lbl { font-size:11.5px; color:var(--fg-dim); margin-top:4px; text-transform:uppercase; letter-spacing:.04em; }
387
+
388
+ /* distribution bars */
389
+ .ct-dist { background:var(--bg-2); border:1px solid var(--border); border-radius:8px; padding:14px 16px; display:flex; flex-direction:column; gap:10px; }
390
+ .ct-dist-row { display:flex; flex-direction:column; gap:5px; }
391
+ .ct-dist-label { font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--fg-dim); }
392
+ .ct-segbar { height:12px; border-radius:6px; background:#0a0d12; overflow:hidden; display:flex; }
393
+ .ct-seg { height:100%; transition:width .3s; }
394
+ .ct-seglegend { display:flex; flex-wrap:wrap; gap:10px; margin-top:2px; }
395
+ .ct-segleg { display:flex; align-items:center; gap:5px; font-size:12px; color:var(--fg); }
396
+ .ct-segleg b { color:var(--fg); }
397
+ .ct-segleg em { color:var(--fg-dim); font-style:normal; }
398
+ .ct-segdot { width:10px; height:10px; border-radius:3px; flex-shrink:0; }
399
+
400
+ /* segment colors — protocol */
401
+ .ct-seg-tcp, .ct-segdot.ct-seg-tcp { background:#1a4a8a; }
402
+ .ct-seg-udp, .ct-segdot.ct-seg-udp { background:#7a4000; }
403
+ .ct-seg-icmp, .ct-segdot.ct-seg-icmp { background:#5a4500; }
404
+ .ct-seg-icmpv6, .ct-segdot.ct-seg-icmpv6 { background:#6a4000; }
405
+ .ct-seg-other, .ct-segdot.ct-seg-other { background:#2a3040; }
406
+
407
+ /* segment colors — tcp state */
408
+ .ct-seg-state-est, .ct-segdot.ct-seg-state-est { background:#1e5c3a; }
409
+ .ct-seg-state-tw, .ct-segdot.ct-seg-state-tw { background:#5a4500; }
410
+ .ct-seg-state-syn, .ct-segdot.ct-seg-state-syn { background:#1a3a6a; }
411
+ .ct-seg-state-fin, .ct-segdot.ct-seg-state-fin { background:#5a3800; }
412
+ .ct-seg-state-cw, .ct-segdot.ct-seg-state-cw { background:#5a2800; }
413
+ .ct-seg-state-close, .ct-segdot.ct-seg-state-close { background:#5c2020; }
414
+ .ct-seg-state-none, .ct-segdot.ct-seg-state-none { background:#2a3040; }
415
+
416
+ /* top tables */
417
+ .ct-tops { display:flex; gap:10px; flex-wrap:wrap; }
418
+ .ct-top-box {
419
+ flex:1; min-width:200px; background:var(--bg-2); border:1px solid var(--border);
420
+ border-radius:8px; overflow:hidden;
421
+ }
422
+ .ct-top-title { padding:8px 14px; font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--fg-dim); background:var(--bg-3); border-bottom:1px solid var(--border); }
423
+ .ct-mini-table { width:100%; border-collapse:collapse; font-size:13px; }
424
+ .ct-mini-table tr:nth-child(even) td { background:#0e1319; }
425
+ .ct-mini-table td { padding:5px 14px; }
426
+ .ct-mini-table code { font-family:var(--mono); color:var(--accent-2); font-size:12px; }
427
+ .ct-top-n { text-align:right; font-family:var(--mono); font-weight:600; color:var(--fg); width:60px; }
428
+ .ct-empty { color:var(--fg-dim); font-style:italic; }
429
+
430
+ /* filter controls */
431
+ .ct-filter { display:flex; align-items:center; flex-wrap:wrap; gap:8px; }
432
+ .ct-search {
433
+ flex:1; min-width:180px; background:#0a0d12; border:1px solid var(--border);
434
+ color:var(--fg); padding:6px 10px; border-radius:6px;
435
+ font-size:13px; font-family:var(--mono);
436
+ }
437
+ .ct-search:focus { outline:none; border-color:var(--accent); }
438
+ .ct-filter-group { display:flex; gap:4px; flex-wrap:wrap; }
439
+ .ct-filter-btn {
440
+ background:var(--bg-3); color:var(--fg-dim); border:1px solid var(--border);
441
+ padding:4px 10px; border-radius:5px; cursor:pointer; font-size:12px; font-weight:500;
442
+ }
443
+ .ct-filter-btn:hover { color:var(--fg); border-color:var(--accent); }
444
+ .ct-filter-btn.active { background:var(--bg-3); color:#fff; border-color:var(--accent); }
445
+
446
+ /* state-coloured filter buttons */
447
+ .ct-filter-state-est.active { border-color:#3fb950; color:#3fb950; }
448
+ .ct-filter-state-tw.active { border-color:#d29922; color:#d29922; }
449
+ .ct-filter-state-syn.active { border-color:#58a6ff; color:#58a6ff; }
450
+ .ct-filter-state-fin.active,
451
+ .ct-filter-state-cw.active { border-color:#ff9e2c; color:#ff9e2c; }
452
+ .ct-filter-state-close.active{ border-color:#f85149; color:#f85149; }
453
+
454
+ /* connection table */
455
+ .ct-table-wrap { overflow-x:auto; }
456
+ .ct-table {
457
+ width:100%; border-collapse:collapse; font-size:13px;
458
+ background:var(--bg-2); border:1px solid var(--border); border-radius:8px;
459
+ overflow:hidden;
460
+ }
461
+ .ct-table thead tr { background:#0e1319; border-bottom:1px solid var(--border); }
462
+ .ct-table thead th { padding:7px 12px; text-align:left; font-size:11px; color:var(--fg-dim); font-weight:500; text-transform:uppercase; letter-spacing:.04em; white-space:nowrap; }
463
+ .ct-row { border-bottom:1px solid #1a2030; }
464
+ .ct-row:last-child { border-bottom:none; }
465
+ .ct-row td { padding:8px 12px; vertical-align:middle; }
466
+
467
+ /* tcp state badge */
468
+ .ct-state {
469
+ display:inline-block; padding:2px 8px; border-radius:5px;
470
+ font-family:var(--mono); font-size:11px; font-weight:700;
471
+ white-space:nowrap; letter-spacing:.02em;
472
+ }
473
+ .ct-state-est { background:#0d2b1e; color:#3fb950; border:1px solid #1e5c3a; }
474
+ .ct-state-tw { background:#2a2000; color:#d29922; border:1px solid #5a4500; }
475
+ .ct-state-syn { background:#0d1e38; color:#58a6ff; border:1px solid #1a3a6a; }
476
+ .ct-state-fin { background:#2a1800; color:#ff9e2c; border:1px solid #5a3800; }
477
+ .ct-state-cw { background:#3a1800; color:#ff7b42; border:1px solid #6a3800; }
478
+ .ct-state-close { background:#2d0f0f; color:#f85149; border:1px solid #5c2020; }
479
+ .ct-state-listen { background:#0d2028; color:#2dd4bf; border:1px solid #1a4a44; }
480
+ .ct-state-none { background:#1a1e26; color:#8b97a8; border:1px solid #2a3040; }
481
+
482
+ /* protocol badge */
483
+ .ct-proto {
484
+ display:inline-block; padding:2px 7px; border-radius:4px;
485
+ font-family:var(--mono); font-size:11px; font-weight:600;
486
+ }
487
+ .ct-proto-tcp { background:#0d1e38; color:#58a6ff; }
488
+ .ct-proto-udp { background:#2a1800; color:#ff9e2c; }
489
+ .ct-proto-icmp,
490
+ .ct-proto-icmpv6{ background:#222000; color:#e3b341; }
491
+
492
+ /* flag indicators */
493
+ .ct-flag { font-size:12px; margin-left:4px; }
494
+ .ct-flag-assured { color:#3fb950; }
495
+ .ct-flag-unr { color:#d29922; }
496
+
497
+ /* connection cell */
498
+ .ct-orig { font-family:var(--mono); font-size:12.5px; }
499
+ .ct-orig code { color:var(--fg); background:var(--bg-3); padding:1px 4px; border-radius:3px; }
500
+ .ct-arrow { color:var(--fg-dim); margin:0 2px; }
501
+ .ct-svc { color:var(--accent-2); font-size:11px; margin-left:4px; }
502
+ .ct-nat {
503
+ display:inline-block; margin-left:6px; font-size:11px; padding:1px 6px;
504
+ background:#200d38; color:#bc8cff; border:1px solid #4a2070; border-radius:4px;
505
+ }
506
+
507
+ .ct-ttl-cell { font-family:var(--mono); font-size:12px; color:var(--fg-dim); white-space:nowrap; }
508
+ .ct-bytes { font-family:var(--mono); font-size:12px; color:var(--fg-dim); white-space:nowrap; }
509
+ .ct-dir { color:var(--fg-dim); font-size:10px; }
510
+
511
+ /* footer */
512
+ .ct-footer { display:flex; align-items:center; gap:12px; padding:8px 0; }
513
+ .ct-footer-count { font-size:13px; color:var(--fg-dim); }
514
+ .ct-footer-count b { color:var(--fg); }
515
+ .ct-showmore {
516
+ background:var(--bg-3); color:var(--fg); border:1px solid var(--border);
517
+ padding:5px 12px; border-radius:6px; cursor:pointer; font-size:12px;
518
+ }
519
+ .ct-showmore:hover { border-color:var(--accent); }
520
+
521
+ /* ── conntrack -S stats table ────────────────────────────────────── */
522
+ .ct-stats-wrap { display:flex; flex-direction:column; gap:10px; }
523
+ .ct-stats-note { font-size:13px; color:var(--fg-dim); padding:8px 12px; background:var(--bg-2); border:1px solid var(--border); border-radius:6px; }
524
+ .ct-stats-table { border-collapse:collapse; font-size:13px; width:100%; }
525
+ .ct-stats-table th { background:#0e1319; padding:7px 12px; text-align:right; font-size:11px; color:var(--fg-dim); text-transform:uppercase; border-bottom:1px solid var(--border); white-space:nowrap; }
526
+ .ct-stats-table th:first-child { text-align:left; }
527
+ .ct-stats-table td { padding:6px 12px; text-align:right; font-family:var(--mono); border-bottom:1px solid #1a2030; }
528
+ .ct-stats-table td:first-child { text-align:left; }
529
+ .ct-stats-table tr:last-child td { border-bottom:none; }
530
+ .ct-stats-total td { background:#0e1319; font-weight:700; }
531
+ .ct-stats-bad { color:var(--err) !important; font-weight:700; }
532
+ .ct-stats-nonzero { color:var(--accent); }
533
+
534
+ /* ── conntrack count gauge ───────────────────────────────────────── */
535
+ .ct-gauge-wrap {
536
+ background:var(--bg-2); border:1px solid var(--border); border-radius:8px;
537
+ padding:20px 24px; display:flex; flex-direction:column; gap:10px; max-width:600px;
538
+ }
539
+ .ct-gauge-row { display:flex; align-items:baseline; gap:8px; }
540
+ .ct-gauge-count { font-size:32px; font-weight:700; font-family:var(--mono); color:var(--fg); }
541
+ .ct-gauge-sep { font-size:22px; color:var(--fg-dim); }
542
+ .ct-gauge-max { font-size:22px; font-family:var(--mono); color:var(--fg-dim); }
543
+ .ct-gauge-pct { font-size:18px; font-family:var(--mono); font-weight:700; margin-left:auto; }
544
+ .ct-gauge-ok { color:var(--ok); }
545
+ .ct-gauge-warn { color:#d29922; }
546
+ .ct-gauge-crit { color:var(--err); }
547
+
548
+ .ct-gauge-bar { height:18px; background:#0a0d12; border-radius:9px; overflow:hidden; border:1px solid var(--border); }
549
+ .ct-gauge-fill { height:100%; border-radius:9px; transition:width .5s; }
550
+ .ct-gauge-fill.ct-gauge-ok { background:linear-gradient(90deg,#1e5c3a,#3fb950); }
551
+ .ct-gauge-fill.ct-gauge-warn { background:linear-gradient(90deg,#5a4500,#d29922); }
552
+ .ct-gauge-fill.ct-gauge-crit { background:linear-gradient(90deg,#5c2020,#f85149); }
553
+
554
+ .ct-gauge-labels { display:flex; justify-content:space-between; font-size:11px; color:var(--fg-dim); font-family:var(--mono); }
555
+ .ct-gauge-msg { font-size:13.5px; padding:8px 12px; border-radius:6px; }
556
+ .ct-gauge-msg.ct-gauge-ok { background:#0d2b1e; border:1px solid #1e5c3a; }
557
+ .ct-gauge-msg.ct-gauge-warn { background:#2a2000; border:1px solid #5a4500; }
558
+ .ct-gauge-msg.ct-gauge-crit { background:#2d0f0f; border:1px solid #5c2020; }
559
+ .ct-gauge-meta { display:flex; gap:20px; font-size:13px; color:var(--fg-dim); }
560
+ .ct-gauge-meta b { color:var(--fg); }
561
+
562
+ /* terminal */
563
+ .term-toolbar { display: flex; gap: 8px; margin-bottom: 10px; }
564
+ #term-input {
565
+ flex: 1; background: #0a0d12; border: 1px solid var(--border); color: var(--fg);
566
+ padding: 9px 12px; border-radius: 6px; font-family: var(--mono); font-size: 13px;
567
+ }
568
+ #term-input:focus { outline: none; border-color: var(--accent); }
569
+ #term {
570
+ background: #0a0d12; border: 1px solid var(--border); border-radius: 8px;
571
+ padding: 8px; height: calc(100vh - 240px);
572
+ }
573
+ .hint { color: var(--fg-dim); font-size: 12px; margin-top: 8px; }
574
+ kbd {
575
+ background: var(--bg-3); border: 1px solid var(--border); border-radius: 4px;
576
+ padding: 1px 5px; font-family: var(--mono); font-size: 11px;
577
+ }
578
+
579
+ /* ── combined health page ────────────────────────────────────────────── */
580
+
581
+ .hp-header {
582
+ display: flex; align-items: center; gap: 14px; margin-bottom: 20px;
583
+ }
584
+ .hp-header h2 { margin: 0; }
585
+ .hp-header button {
586
+ background: var(--bg-3); color: var(--fg-dim); border: 1px solid var(--border);
587
+ padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500;
588
+ }
589
+ .hp-header button:hover { border-color: var(--accent); color: var(--fg); }
590
+
591
+ /* tab strip */
592
+ .hp-tabs {
593
+ display: flex; flex-wrap: wrap; gap: 4px;
594
+ margin-bottom: 0; border-bottom: 2px solid var(--border);
595
+ padding-bottom: 0;
596
+ }
597
+ .hp-tab {
598
+ display: flex; align-items: center; gap: 7px;
599
+ background: var(--bg-2); color: var(--fg-dim);
600
+ border: 1px solid var(--border); border-bottom: none;
601
+ padding: 8px 16px; border-radius: 7px 7px 0 0;
602
+ cursor: pointer; font-size: 13px; font-weight: 500;
603
+ position: relative; bottom: -2px;
604
+ transition: background .12s, color .12s;
605
+ }
606
+ .hp-tab:hover { background: var(--bg-3); color: var(--fg); }
607
+ .hp-tab.active {
608
+ background: var(--bg-3); color: #fff;
609
+ border-color: var(--border); border-bottom-color: var(--bg-3);
610
+ border-top: 2px solid var(--accent);
611
+ }
612
+ .hp-tab .dot { flex-shrink: 0; }
613
+
614
+ /* pane area */
615
+ .hp-panes {
616
+ background: var(--bg-2); border: 1px solid var(--border);
617
+ border-top: none; border-radius: 0 0 10px 10px;
618
+ }
619
+ .hp-pane { display: none; }
620
+ .hp-pane.active { display: block; }
621
+
622
+ /* meta bar inside each pane */
623
+ .hp-pane-meta {
624
+ display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
625
+ padding: 10px 16px; background: var(--bg-3);
626
+ border-bottom: 1px solid var(--border);
627
+ }
628
+ .hp-pane-desc { font-size: 12px; color: var(--fg-dim); flex: 1; min-width: 0; }
629
+ .hp-section-cmd { font-family: var(--mono); font-size: 11px; }
630
+ .hp-section-cmd .cmd {
631
+ color: var(--accent-2); background: var(--bg); border: 1px solid var(--border);
632
+ padding: 2px 7px; border-radius: 4px;
633
+ }
634
+ .hp-section-rerun {
635
+ background: transparent; color: var(--fg-dim); border: 1px solid var(--border);
636
+ padding: 4px 10px; border-radius: 5px; cursor: pointer; font-size: 12px; flex-shrink: 0;
637
+ }
638
+ .hp-section-rerun:hover { border-color: var(--accent); color: var(--fg); }
639
+
640
+ /* content inside pane */
641
+ .hp-pane > .ipt-container { padding: 16px; }
642
+
643
+ /* ── health view ─────────────────────────────────────────────────────── */
644
+
645
+ .hv-wrap { display: flex; flex-direction: column; gap: 14px; }
646
+
647
+ /* gauge header row */
648
+ .hv-gauge-hdr { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
649
+ .hv-gauge-pct-lbl { font-family: var(--mono); font-weight: 700; font-size: 16px; }
650
+
651
+ /* info / note box */
652
+ .hv-info-note {
653
+ background: var(--bg-2); border: 1px solid var(--border); border-radius: 6px;
654
+ padding: 10px 14px; font-size: 13px; color: var(--fg-dim); line-height: 1.6;
655
+ }
656
+ .hv-info-note code { font-family: var(--mono); color: var(--accent-2); }
657
+ .hv-info-note b { color: var(--fg); }
658
+
659
+ /* gauge (memory, pressure) */
660
+ .hv-gauge-wrap {
661
+ background: var(--bg-2); border: 1px solid var(--border);
662
+ border-radius: 8px; padding: 18px 20px; display: flex; flex-direction: column; gap: 12px;
663
+ }
664
+ .hv-gauge-row { display: flex; align-items: baseline; gap: 8px; }
665
+ .hv-gauge-title { font-size: 13px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: .05em; margin-bottom: 4px; }
666
+ .hv-gauge-val { font-size: 26px; font-weight: 700; font-family: var(--mono); }
667
+ .hv-gauge-unit { font-size: 14px; color: var(--fg-dim); }
668
+ .hv-gauge-bar { height: 14px; background: #0a0d12; border-radius: 7px; overflow: hidden; border: 1px solid var(--border); }
669
+ .hv-gauge-fill { height: 100%; border-radius: 7px; transition: width .4s; }
670
+ .hv-ok { color: var(--ok); }
671
+ .hv-warn { color: #d29922; }
672
+ .hv-crit { color: var(--err); }
673
+ .hv-gauge-fill.hv-ok { background: linear-gradient(90deg, #1e5c3a, #3fb950); }
674
+ .hv-gauge-fill.hv-warn { background: linear-gradient(90deg, #5a4500, #d29922); }
675
+ .hv-gauge-fill.hv-crit { background: linear-gradient(90deg, #5c2020, #f85149); }
676
+ .hv-gauge-labels { display: flex; justify-content: space-between; font-size: 11px; color: var(--fg-dim); font-family: var(--mono); }
677
+
678
+ /* memory grid */
679
+ .hv-gauges { display: flex; gap: 12px; flex-wrap: wrap; }
680
+ .hv-gauges .hv-gauge-wrap { flex: 1; min-width: 220px; }
681
+ .hv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; }
682
+ .hv-grid-item {
683
+ background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px;
684
+ padding: 12px 14px;
685
+ }
686
+ .hv-grid-label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--fg-dim); margin-bottom: 4px; }
687
+ .hv-grid-val { font-size: 18px; font-weight: 700; font-family: var(--mono); color: var(--fg); }
688
+ .hv-grid-sub { font-size: 11px; color: var(--fg-dim); margin-top: 2px; }
689
+
690
+ /* PSI box status borders */
691
+ .hv-psi-box-ok { border-top: 3px solid var(--ok); }
692
+ .hv-psi-box-warn { border-top: 3px solid #d29922; }
693
+ .hv-psi-box-crit { border-top: 3px solid var(--err); }
694
+
695
+ /* PSI boxes */
696
+ .hv-psi-boxes { display: flex; gap: 10px; flex-wrap: wrap; }
697
+ .hv-psi-box {
698
+ flex: 1; min-width: 180px; background: var(--bg-2); border: 1px solid var(--border);
699
+ border-radius: 8px; overflow: hidden;
700
+ }
701
+ .hv-psi-title {
702
+ padding: 7px 12px; font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
703
+ color: var(--fg-dim); background: var(--bg-3); border-bottom: 1px solid var(--border);
704
+ }
705
+ .hv-psi-rows { padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
706
+ .hv-psi-row { display: flex; justify-content: space-between; font-size: 13px; }
707
+ .hv-psi-key { color: var(--fg-dim); }
708
+ .hv-psi-val { font-family: var(--mono); font-weight: 600; }
709
+ .hv-psi-na { padding: 10px 12px; font-size: 13px; color: var(--fg-dim); font-style: italic; }
710
+
711
+ /* OOM count badge */
712
+ .hv-oom-count-badge {
713
+ font-size: 14px; font-weight: 600; color: var(--err);
714
+ background: #2d0f0f; border: 1px solid #5c2020; border-radius: 6px;
715
+ padding: 8px 14px;
716
+ }
717
+
718
+ /* OOM events */
719
+ .hv-oom-ok {
720
+ background: #0d2b1e; border: 1px solid #1e5c3a; border-radius: 8px;
721
+ padding: 14px 18px; color: #3fb950; font-size: 15px; font-weight: 600;
722
+ }
723
+ .hv-oom-list { display: flex; flex-direction: column; gap: 8px; }
724
+ .hv-oom-event {
725
+ background: #2d0f0f; border: 1px solid #5c2020; border-radius: 8px;
726
+ padding: 12px 16px;
727
+ }
728
+ .hv-oom-header { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; flex-wrap: wrap; }
729
+ .hv-oom-process {
730
+ font-family: var(--mono); font-weight: 700; font-size: 14px; color: #ff7b72;
731
+ }
732
+ .hv-oom-pid { font-family: var(--mono); font-size: 12px; color: var(--fg-dim); }
733
+ .hv-oom-ts { font-size: 11px; color: var(--fg-dim); margin-left: auto; }
734
+ .hv-oom-mems { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 4px; }
735
+ .hv-oom-mem-item { font-size: 13px; }
736
+ .hv-oom-mem-label { color: var(--fg-dim); }
737
+ .hv-oom-mem-val { font-family: var(--mono); font-weight: 600; color: var(--fg); }
738
+ .hv-oom-raw { font-family: var(--mono); font-size: 11px; color: #8b97a8; margin-top: 6px; word-break: break-all; }
739
+
740
+ /* kubelet log view */
741
+ .hv-log-summary { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
742
+ .hv-log-pill {
743
+ font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 10px;
744
+ }
745
+ .hv-log-pill-error { background: #2d0f0f; color: var(--err); border: 1px solid #5c2020; }
746
+ .hv-log-pill-warn { background: #2a2000; color: #d29922; border: 1px solid #5a4500; }
747
+ .hv-log-pill-evict { background: #2a1800; color: #ff9e2c; border: 1px solid #5a3800; }
748
+ .hv-log-pill-ok { background: #0d2b1e; color: var(--ok); border: 1px solid #1e5c3a; }
749
+ .hv-log-lines { display: flex; flex-direction: column; gap: 1px; font-family: var(--mono); font-size: 12px; max-height: 60vh; overflow-y: auto; background: #0a0d12; border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; }
750
+ .hv-log-line { line-height: 1.5; word-break: break-all; white-space: pre-wrap; }
751
+ .hv-log-error { color: var(--err); }
752
+ .hv-log-warn { color: #d29922; }
753
+ .hv-log-evict { color: #ff9e2c; }
754
+ .hv-log-normal { color: #8b97a8; }
755
+
756
+ /* disk bars */
757
+ .hv-disk-list { display: flex; flex-direction: column; gap: 8px; }
758
+ .hv-disk-row {
759
+ background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px; padding: 12px 16px;
760
+ }
761
+ .hv-disk-header { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
762
+ .hv-disk-mount { font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--fg); }
763
+ .hv-disk-star { font-size: 11px; padding: 1px 6px; background: #0d2d2d; color: var(--accent-2); border: 1px solid #1a5555; border-radius: 4px; }
764
+ .hv-disk-fs { font-size: 11px; color: var(--fg-dim); }
765
+ .hv-disk-sizes { display: flex; gap: 14px; flex-wrap: wrap; font-size: 13px; margin-left: auto; }
766
+ .hv-disk-pct { font-family: var(--mono); font-weight: 700; }
767
+ .hv-disk-nums { color: var(--fg-dim); font-family: var(--mono); font-size: 12px; }
768
+ .hv-disk-bar { height: 10px; background: #0a0d12; border-radius: 5px; overflow: hidden; border: 1px solid var(--border); }
769
+ .hv-disk-fill { height: 100%; border-radius: 5px; transition: width .4s; }
770
+ .hv-disk-fill.hv-ok { background: linear-gradient(90deg, #1e5c3a, #3fb950); }
771
+ .hv-disk-fill.hv-warn { background: linear-gradient(90deg, #5a4500, #d29922); }
772
+ .hv-disk-fill.hv-crit { background: linear-gradient(90deg, #5c2020, #f85149); }
773
+
774
+ /* CPU info row */
775
+ .hv-cpu-info {
776
+ display: flex; gap: 18px; align-items: center; flex-wrap: wrap;
777
+ background: var(--bg-2); border: 1px solid var(--border); border-radius: 6px;
778
+ padding: 10px 14px; font-size: 13px; color: var(--fg-dim);
779
+ }
780
+ .hv-cpu-info b { color: var(--fg); }
781
+ .hv-steal-val { font-family: var(--mono); }
782
+
783
+ /* load status note */
784
+ .hv-load-note { font-size: 13.5px; padding: 8px 12px; border-radius: 6px; }
785
+ .hv-note-ok { background: #0d2b1e; border: 1px solid #1e5c3a; color: #3fb950; }
786
+ .hv-note-warn { background: #2a2000; border: 1px solid #5a4500; color: #d29922; }
787
+ .hv-note-crit { background: #2d0f0f; border: 1px solid #5c2020; color: var(--err); }
788
+
789
+ /* process table command column */
790
+ .hv-proc-cmd { font-family: var(--mono); color: var(--fg-dim); word-break: break-all; max-width: 320px; }
791
+
792
+ /* CPU / load */
793
+ .hv-load-cards { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
794
+ .hv-load-card {
795
+ flex: 1; min-width: 100px; background: var(--bg-2); border: 1px solid var(--border);
796
+ border-radius: 8px; padding: 14px 16px; text-align: center; border-top-width: 3px;
797
+ }
798
+ .hv-load-card-ok { border-top-color: var(--ok); }
799
+ .hv-load-card-warn { border-top-color: #d29922; }
800
+ .hv-load-card-crit { border-top-color: var(--err); }
801
+ .hv-load-val { font-size: 26px; font-weight: 700; font-family: var(--mono); }
802
+ .hv-load-lbl { font-size: 11px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: .04em; margin-top: 2px; }
803
+ .hv-steal-row {
804
+ font-size: 13px; padding: 8px 12px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 6px;
805
+ }
806
+ .hv-top-table-wrap { overflow-x: auto; }
807
+ .hv-top-table {
808
+ width: 100%; border-collapse: collapse; font-size: 13px; background: var(--bg-2);
809
+ border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
810
+ }
811
+ .hv-top-table thead tr { background: #0e1319; border-bottom: 1px solid var(--border); }
812
+ .hv-top-table thead th { padding: 7px 12px; text-align: left; font-size: 11px; color: var(--fg-dim); font-weight: 500; text-transform: uppercase; letter-spacing: .04em; }
813
+ .hv-top-table tbody tr { border-bottom: 1px solid #1a2030; }
814
+ .hv-top-table tbody tr:last-child { border-bottom: none; }
815
+ .hv-top-table td { padding: 7px 12px; font-family: var(--mono); font-size: 12.5px; }
816
+ .hv-top-table td:first-child { color: var(--fg-dim); }
817
+
818
+ /* ── connectivity prober ─────────────────────────────────────────────── */
819
+
820
+ .conn-form {
821
+ display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
822
+ margin-bottom: 8px;
823
+ }
824
+ .conn-form input, .conn-form select {
825
+ background: #0a0d12; border: 1px solid var(--border); color: var(--fg);
826
+ padding: 8px 12px; border-radius: 6px; font-family: var(--mono); font-size: 13px;
827
+ }
828
+ .conn-form input { flex: 1; min-width: 200px; }
829
+ .conn-form input:focus, .conn-form select:focus { outline: none; border-color: var(--accent); }
830
+ .conn-form select { background: #0a0d12; }
831
+ #conn-run {
832
+ background: var(--accent); color: #fff; border: none;
833
+ padding: 8px 18px; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 600;
834
+ white-space: nowrap;
835
+ }
836
+ #conn-run:hover { filter: brightness(1.15); }
837
+ #conn-run:disabled { opacity: .5; cursor: not-allowed; filter: none; }
838
+ .conn-hint { font-size: 12px; color: var(--fg-dim); margin-bottom: 14px; }
839
+
840
+ /* result sections */
841
+ .conn-results-wrap { display: flex; flex-direction: column; gap: 10px; }
842
+ .conn-section {
843
+ background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
844
+ }
845
+ .conn-section-hdr {
846
+ display: flex; align-items: center; gap: 10px; padding: 9px 14px;
847
+ background: var(--bg-3); border-bottom: 1px solid var(--border);
848
+ }
849
+ .conn-section-title { font-size: 13px; font-weight: 600; color: var(--fg); }
850
+ .conn-badge {
851
+ font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 10px;
852
+ letter-spacing: .03em; font-family: var(--mono);
853
+ }
854
+ .conn-badge-ok { background: #0d2b1e; color: var(--ok); border: 1px solid #1e5c3a; }
855
+ .conn-badge-fail { background: #2d0f0f; color: var(--err); border: 1px solid #5c2020; }
856
+ .conn-badge-skip { background: var(--bg-3); color: var(--fg-dim); border: 1px solid var(--border); }
857
+ .conn-section-body { padding: 10px 14px; }
858
+ .conn-pre {
859
+ margin: 0; font-family: var(--mono); font-size: 12px; color: #c9d4e2;
860
+ white-space: pre-wrap; word-break: break-all; max-height: 220px; overflow-y: auto;
861
+ background: #0a0d12; border: 1px solid var(--border); border-radius: 6px;
862
+ padding: 8px 10px;
863
+ }
864
+ .conn-empty { color: var(--fg-dim); font-style: italic; font-size: 13px; padding: 6px 0; }
865
+ .conn-loading { color: var(--accent); font-size: 14px; padding: 20px; text-align: center; }
866
+ .conn-error { color: var(--err); font-size: 13px; padding: 10px; }