:root { --bg: #0f1216; --panel: #181d24; --panel-2: #1f2630; --border: #2a323d; --text: #e6e9ee; --muted: #8a94a3; --accent: #5b9dff; --accent-2: #7c5bff; --ok: #3ddc97; --in: #3ddc97; --out: #5b9dff; --danger: #ff6b6b; font-synthesis: none; text-rendering: optimizeLegibility; } * { box-sizing: border-box; } body { margin: 0; font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; background: var(--bg); color: var(--text); line-height: 1.5; } code { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 0.85em; background: rgba(255, 255, 255, 0.06); padding: 1px 5px; border-radius: 4px; } .app { max-width: 1100px; margin: 0 auto; padding: 20px 16px 60px; } /* ---------- header ---------- */ .header { display: flex; flex-wrap: wrap; gap: 16px; justify-content: space-between; align-items: flex-start; border-bottom: 1px solid var(--border); padding-bottom: 18px; margin-bottom: 18px; } .header-title h1 { margin: 0 0 4px; font-size: 1.5rem; } .subtitle { margin: 0; color: var(--muted); max-width: 52ch; font-size: 0.9rem; } .identity { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; } .field { display: flex; flex-direction: column; gap: 4px; } .field-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); text-align: right; } .name-input { background: var(--panel-2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 1rem; min-width: 180px; text-align: right; } .name-input:focus { outline: none; border-color: var(--accent); } .identity-meta { display: flex; flex-wrap: wrap; gap: 10px 14px; justify-content: flex-end; font-size: 0.8rem; color: var(--muted); } .dot::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--muted); margin-right: 6px; } .dot.ok::before { background: var(--ok); } /* ---------- layout ---------- */ .layout { display: grid; grid-template-columns: 280px 1fr; gap: 16px; align-items: start; } @media (max-width: 760px) { .layout { grid-template-columns: 1fr; } .identity { align-items: flex-start; } .identity-meta, .field-label, .name-input { text-align: left; justify-content: flex-start; } } .col-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; } /* ---------- panel ---------- */ .panel { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; } .panel-title { margin: 0 0 12px; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); display: flex; align-items: center; gap: 10px; } /* ---------- peer list ---------- */ .peer-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; } .peer { width: 100%; display: grid; grid-template-columns: 34px 1fr auto; align-items: center; gap: 4px 10px; background: var(--panel-2); border: 1px solid transparent; border-radius: 10px; padding: 8px 10px; color: var(--text); cursor: pointer; text-align: left; transition: border-color 0.12s, background 0.12s; } .peer:hover { border-color: var(--border); } .peer.selected { border-color: var(--accent); background: rgba(91, 157, 255, 0.12); } .peer-avatar { grid-row: span 2; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: white; font-weight: 700; font-size: 0.8rem; } .peer.broadcast .peer-avatar { background: linear-gradient(135deg, #ffae57, #ff6b6b); } .peer-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .peer-sub { grid-column: 2 / 4; font-size: 0.75rem; color: var(--muted); } .empty { color: var(--muted); font-size: 0.85rem; margin: 10px 2px 2px; } /* ---------- composer ---------- */ .composer-row { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; flex-wrap: wrap; } .text-input { flex: 1; min-width: 160px; background: var(--panel-2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 10px 12px; font-size: 0.95rem; } .text-input:focus { outline: none; border-color: var(--accent); } .file-input { flex: 1; min-width: 160px; color: var(--muted); font-size: 0.85rem; } .file-input::file-selector-button { background: var(--panel-2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 7px 12px; margin-right: 10px; cursor: pointer; } .select { background: var(--panel-2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 8px 10px; } .btn { background: var(--panel-2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 9px 16px; font-size: 0.9rem; cursor: pointer; white-space: nowrap; transition: border-color 0.12s, background 0.12s, opacity 0.12s; } .btn:hover:not(:disabled) { border-color: var(--accent); } .btn.primary { background: var(--accent); border-color: var(--accent); color: #08121f; font-weight: 600; } .btn.primary:hover:not(:disabled) { background: #6fabff; } .btn:disabled { opacity: 0.45; cursor: not-allowed; } .btn.tiny { padding: 3px 10px; font-size: 0.75rem; margin-left: auto; } .to-badge { color: var(--accent); text-transform: none; letter-spacing: 0; font-weight: 600; } .divider { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; margin: 14px 0 12px; } .divider::before, .divider::after { content: ''; flex: 1; height: 1px; background: var(--border); } .hint { font-size: 0.82rem; color: var(--muted); margin: 4px 2px 12px; } .hint.subtle { font-size: 0.78rem; opacity: 0.8; margin-bottom: 0; } /* ---------- transfers ---------- */ .transfer-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; } .transfer-head { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; margin-bottom: 5px; } .transfer-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40%; } .transfer-meta { color: var(--muted); font-size: 0.8rem; } .transfer-pct { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--accent); font-weight: 600; } .progress { height: 8px; background: var(--panel-2); border-radius: 999px; overflow: hidden; } .progress-bar { height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-2)); transition: width 0.15s ease; } .progress-bar.done { background: var(--ok); } /* ---------- log ---------- */ .log-panel { display: flex; flex-direction: column; } .log { display: flex; flex-direction: column; gap: 7px; max-height: 360px; overflow-y: auto; padding-right: 4px; } .log-row { display: flex; gap: 10px; font-size: 0.88rem; align-items: baseline; } .log-time { color: var(--muted); font-size: 0.72rem; font-variant-numeric: tabular-nums; flex-shrink: 0; padding-top: 1px; } .log-body { min-width: 0; } .log-row.system .log-body { color: var(--muted); font-style: italic; } .log-who { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; margin-right: 8px; } .log-row.in .log-who { color: var(--in); } .log-row.out .log-who { color: var(--out); } .log-text { word-break: break-word; } .log-binary { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; } .dl { color: var(--accent); text-decoration: none; border: 1px solid var(--border); border-radius: 6px; padding: 1px 8px; font-size: 0.78rem; } .dl:hover { border-color: var(--accent); } .sha { color: var(--muted); }