1:root {
2 --bg: #0f1216;
3 --panel: #181d24;
4 --panel-2: #1f2630;
5 --border: #2a323d;
6 --text: #e6e9ee;
7 --muted: #8a94a3;
8 --accent: #5b9dff;
9 --accent-2: #7c5bff;
10 --ok: #3ddc97;
11 --in: #3ddc97;
12 --out: #5b9dff;
13 --danger: #ff6b6b;
14 font-synthesis: none;
15 text-rendering: optimizeLegibility;
16}
18* {
19 box-sizing: border-box;
20}
22body {
23 margin: 0;
24 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
25 background: var(--bg);
26 color: var(--text);
27 line-height: 1.5;
28}
30code {
31 font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
32 font-size: 0.85em;
33 background: rgba(255, 255, 255, 0.06);
34 padding: 1px 5px;
35 border-radius: 4px;
36}
38.app {
39 max-width: 1100px;
40 margin: 0 auto;
41 padding: 20px 16px 60px;
42}
44/* ---------- header ---------- */
45.header {
46 display: flex;
47 flex-wrap: wrap;
48 gap: 16px;
49 justify-content: space-between;
50 align-items: flex-start;
51 border-bottom: 1px solid var(--border);
52 padding-bottom: 18px;
53 margin-bottom: 18px;
54}
56.header-title h1 {
57 margin: 0 0 4px;
58 font-size: 1.5rem;
59}
61.subtitle {
62 margin: 0;
63 color: var(--muted);
64 max-width: 52ch;
65 font-size: 0.9rem;
66}
68.identity {
69 display: flex;
70 flex-direction: column;
71 gap: 8px;
72 align-items: flex-end;
73}
75.field {
76 display: flex;
77 flex-direction: column;
78 gap: 4px;
79}
81.field-label {
82 font-size: 0.72rem;
83 text-transform: uppercase;
84 letter-spacing: 0.05em;
85 color: var(--muted);
86 text-align: right;
87}
89.name-input {
90 background: var(--panel-2);
91 border: 1px solid var(--border);
92 color: var(--text);
93 border-radius: 8px;
94 padding: 8px 10px;
95 font-size: 1rem;
96 min-width: 180px;
97 text-align: right;
98}
100.name-input:focus {
101 outline: none;
102 border-color: var(--accent);
103}
105.identity-meta {
106 display: flex;
107 flex-wrap: wrap;
108 gap: 10px 14px;
109 justify-content: flex-end;
110 font-size: 0.8rem;
111 color: var(--muted);
112}
114.dot::before {
115 content: '';
116 display: inline-block;
117 width: 8px;
118 height: 8px;
119 border-radius: 50%;
120 background: var(--muted);
121 margin-right: 6px;
122}
124.dot.ok::before {
125 background: var(--ok);
126}
128/* ---------- layout ---------- */
129.layout {
130 display: grid;
131 grid-template-columns: 280px 1fr;
132 gap: 16px;
133 align-items: start;
134}
136@media (max-width: 760px) {
137 .layout {
138 grid-template-columns: 1fr;
139 }
140 .identity {
141 align-items: flex-start;
142 }
143 .identity-meta,
144 .field-label,
145 .name-input {
146 text-align: left;
147 justify-content: flex-start;
148 }
149}
151.col-main {
152 display: flex;
153 flex-direction: column;
154 gap: 16px;
155 min-width: 0;
156}
158/* ---------- panel ---------- */
159.panel {
160 background: var(--panel);
161 border: 1px solid var(--border);
162 border-radius: 12px;
163 padding: 14px 16px;
164}
166.panel-title {
167 margin: 0 0 12px;
168 font-size: 0.82rem;
169 text-transform: uppercase;
170 letter-spacing: 0.06em;
171 color: var(--muted);
172 display: flex;
173 align-items: center;
174 gap: 10px;
175}
177/* ---------- peer list ---------- */
178.peer-list {
179 list-style: none;
180 margin: 0;
181 padding: 0;
182 display: flex;
183 flex-direction: column;
184 gap: 6px;
185}
187.peer {
188 width: 100%;
189 display: grid;
190 grid-template-columns: 34px 1fr auto;
191 align-items: center;
192 gap: 4px 10px;
193 background: var(--panel-2);
194 border: 1px solid transparent;
195 border-radius: 10px;
196 padding: 8px 10px;
197 color: var(--text);
198 cursor: pointer;
199 text-align: left;
200 transition: border-color 0.12s, background 0.12s;
201}
203.peer:hover {
204 border-color: var(--border);
205}
207.peer.selected {
208 border-color: var(--accent);
209 background: rgba(91, 157, 255, 0.12);
210}
212.peer-avatar {
213 grid-row: span 2;
214 width: 34px;
215 height: 34px;
216 border-radius: 50%;
217 display: grid;
218 place-items: center;
219 background: linear-gradient(135deg, var(--accent), var(--accent-2));
220 color: white;
221 font-weight: 700;
222 font-size: 0.8rem;
223}
225.peer.broadcast .peer-avatar {
226 background: linear-gradient(135deg, #ffae57, #ff6b6b);
227}
229.peer-name {
230 font-weight: 600;
231 overflow: hidden;
232 text-overflow: ellipsis;
233 white-space: nowrap;
234}
236.peer-sub {
237 grid-column: 2 / 4;
238 font-size: 0.75rem;
239 color: var(--muted);
240}
242.empty {
243 color: var(--muted);
244 font-size: 0.85rem;
245 margin: 10px 2px 2px;
246}
248/* ---------- composer ---------- */
249.composer-row {
250 display: flex;
251 gap: 8px;
252 align-items: center;
253 margin-bottom: 10px;
254 flex-wrap: wrap;
255}
257.text-input {
258 flex: 1;
259 min-width: 160px;
260 background: var(--panel-2);
261 border: 1px solid var(--border);
262 color: var(--text);
263 border-radius: 8px;
264 padding: 10px 12px;
265 font-size: 0.95rem;
266}
268.text-input:focus {
269 outline: none;
270 border-color: var(--accent);
271}
273.file-input {
274 flex: 1;
275 min-width: 160px;
276 color: var(--muted);
277 font-size: 0.85rem;
278}
280.file-input::file-selector-button {
281 background: var(--panel-2);
282 border: 1px solid var(--border);
283 color: var(--text);
284 border-radius: 8px;
285 padding: 7px 12px;
286 margin-right: 10px;
287 cursor: pointer;
288}
290.select {
291 background: var(--panel-2);
292 border: 1px solid var(--border);
293 color: var(--text);
294 border-radius: 8px;
295 padding: 8px 10px;
296}
298.btn {
299 background: var(--panel-2);
300 border: 1px solid var(--border);
301 color: var(--text);
302 border-radius: 8px;
303 padding: 9px 16px;
304 font-size: 0.9rem;
305 cursor: pointer;
306 white-space: nowrap;
307 transition: border-color 0.12s, background 0.12s, opacity 0.12s;
308}
310.btn:hover:not(:disabled) {
311 border-color: var(--accent);
312}
314.btn.primary {
315 background: var(--accent);
316 border-color: var(--accent);
317 color: #08121f;
318 font-weight: 600;
319}
321.btn.primary:hover:not(:disabled) {
322 background: #6fabff;
323}
325.btn:disabled {
326 opacity: 0.45;
327 cursor: not-allowed;
328}
330.btn.tiny {
331 padding: 3px 10px;
332 font-size: 0.75rem;
333 margin-left: auto;
334}
336.to-badge {
337 color: var(--accent);
338 text-transform: none;
339 letter-spacing: 0;
340 font-weight: 600;
341}
343.divider {
344 display: flex;
345 align-items: center;
346 gap: 10px;
347 color: var(--muted);
348 font-size: 0.72rem;
349 text-transform: uppercase;
350 letter-spacing: 0.06em;
351 margin: 14px 0 12px;
352}
354.divider::before,
355.divider::after {
356 content: '';
357 flex: 1;
358 height: 1px;
359 background: var(--border);
360}
362.hint {
363 font-size: 0.82rem;
364 color: var(--muted);
365 margin: 4px 2px 12px;
366}
368.hint.subtle {
369 font-size: 0.78rem;
370 opacity: 0.8;
371 margin-bottom: 0;
372}
374/* ---------- transfers ---------- */
375.transfer-list {
376 list-style: none;
377 margin: 0;
378 padding: 0;
379 display: flex;
380 flex-direction: column;
381 gap: 12px;
382}
384.transfer-head {
385 display: flex;
386 align-items: center;
387 gap: 8px;
388 font-size: 0.85rem;
389 margin-bottom: 5px;
390}
392.transfer-name {
393 font-weight: 600;
394 overflow: hidden;
395 text-overflow: ellipsis;
396 white-space: nowrap;
397 max-width: 40%;
398}
400.transfer-meta {
401 color: var(--muted);
402 font-size: 0.8rem;
403}
405.transfer-pct {
406 margin-left: auto;
407 font-variant-numeric: tabular-nums;
408 color: var(--accent);
409 font-weight: 600;
410}
412.progress {
413 height: 8px;
414 background: var(--panel-2);
415 border-radius: 999px;
416 overflow: hidden;
417}
419.progress-bar {
420 height: 100%;
421 background: linear-gradient(90deg, var(--accent), var(--accent-2));
422 transition: width 0.15s ease;
423}
425.progress-bar.done {
426 background: var(--ok);
427}
429/* ---------- log ---------- */
430.log-panel {
431 display: flex;
432 flex-direction: column;
433}
435.log {
436 display: flex;
437 flex-direction: column;
438 gap: 7px;
439 max-height: 360px;
440 overflow-y: auto;
441 padding-right: 4px;
442}
444.log-row {
445 display: flex;
446 gap: 10px;
447 font-size: 0.88rem;
448 align-items: baseline;
449}
451.log-time {
452 color: var(--muted);
453 font-size: 0.72rem;
454 font-variant-numeric: tabular-nums;
455 flex-shrink: 0;
456 padding-top: 1px;
457}
459.log-body {
460 min-width: 0;
461}
463.log-row.system .log-body {
464 color: var(--muted);
465 font-style: italic;
466}
468.log-who {
469 font-size: 0.72rem;
470 text-transform: uppercase;
471 letter-spacing: 0.04em;
472 margin-right: 8px;
473}
475.log-row.in .log-who {
476 color: var(--in);
477}
479.log-row.out .log-who {
480 color: var(--out);
481}
483.log-text {
484 word-break: break-word;
485}
487.log-binary {
488 display: inline-flex;
489 flex-wrap: wrap;
490 gap: 8px;
491 align-items: center;
492}
494.dl {
495 color: var(--accent);
496 text-decoration: none;
497 border: 1px solid var(--border);
498 border-radius: 6px;
499 padding: 1px 8px;
500 font-size: 0.78rem;
501}
503.dl:hover {
504 border-color: var(--accent);
505}
507.sha {
508 color: var(--muted);
509}