/* Warpgate Dashboard — unified stylesheet */ :root { --bg: #0f1117; --surface: #1a1d27; --border: #2a2d3a; --text: #e1e4ed; --text-muted: #8b8fa3; --accent: #6c8aff; --green: #4ade80; --red: #f87171; --yellow: #fbbf24; --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace; --mono: "SF Mono", "Fira Code", "Cascadia Code", monospace; } * { box-sizing: border-box; margin: 0; padding: 0; } body { background: var(--bg); color: var(--text); font-family: var(--font); padding: 0; margin: 0; } a { color: var(--accent); text-decoration: none; } a:hover { text-decoration: underline; } .mono { font-family: var(--mono); } /* ─── Shell layout ─────────────────────────────────────── */ .shell { max-width: 1080px; margin: 0 auto; padding: 24px; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0; padding-bottom: 16px; } .header h1 { font-size: 1.4em; } .header .status-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--green); margin-right: 8px; } .meta { color: var(--text-muted); font-size: 0.85em; } /* ─── Tab navigation ───────────────────────────────────── */ .tabs { display: flex; gap: 0; border-bottom: 1px solid var(--border); margin-bottom: 24px; } .tab-btn { padding: 10px 20px; background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-muted); font-family: var(--font); font-size: 0.9em; font-weight: 500; cursor: pointer; transition: color 0.15s, border-color 0.15s; } .tab-btn:hover { color: var(--text); } .tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); } /* ─── Stat cards (dashboard) ───────────────────────────── */ .stat-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 24px; } .stat-card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 16px; } .stat-card .label { font-size: 0.8em; color: var(--text-muted); margin-bottom: 4px; } .stat-card .value { font-size: 1.3em; font-weight: 600; } /* ─── Share cards ──────────────────────────────────────── */ .cards { display: flex; flex-direction: column; gap: 12px; margin-bottom: 24px; } .card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 16px; } .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .card-header h2 { font-size: 1.1em; } .card-header h2 a { color: var(--accent); text-decoration: none; } .card-header h2 a:hover { text-decoration: underline; } /* ─── Badges ───────────────────────────────────────────── */ .badge { font-size: 0.75em; padding: 2px 8px; border-radius: 4px; font-weight: 600; vertical-align: middle; } .badge-ok { background: rgba(74,222,128,0.15); color: var(--green); } .badge-error { background: rgba(248,113,113,0.15); color: var(--red); } .badge-ro { background: rgba(251,191,36,0.15); color: var(--yellow); } .badge-warn { background: rgba(251,191,36,0.15); color: var(--yellow); } /* ─── Stats row (inside share cards) ──────────────────── */ .stats { display: flex; gap: 24px; font-size: 0.9em; color: var(--text-muted); flex-wrap: wrap; } .stats span { white-space: nowrap; } .stats .label { color: var(--text-muted); } .stats .value { color: var(--text); } .error-msg { margin-top: 8px; padding: 8px 12px; background: rgba(248,113,113,0.08); border-radius: 4px; color: var(--red); font-size: 0.85em; } /* ─── Protocol badges ──────────────────────────────────── */ .protocols { display: flex; gap: 16px; margin-bottom: 20px; font-size: 0.9em; } .proto-badge { padding: 4px 12px; border-radius: 4px; font-weight: 600; } .proto-on { background: rgba(74,222,128,0.15); color: var(--green); } .proto-off { background: rgba(248,113,113,0.1); color: var(--text-muted); } /* ─── Share table (shares tab) ─────────────────────────── */ .share-table { width: 100%; border-collapse: collapse; margin-bottom: 24px; } .share-table th { text-align: left; padding: 8px 12px; border-bottom: 2px solid var(--border); color: var(--text-muted); font-size: 0.8em; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; } .share-table td { padding: 10px 12px; border-bottom: 1px solid var(--border); } .share-row { cursor: pointer; transition: background 0.1s; } .share-row:hover { background: rgba(108,138,255,0.05); } .detail-row td { padding: 0; border-bottom: 1px solid var(--border); } .detail-panel { background: var(--surface); padding: 16px 20px; } .detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; } .detail-card { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 12px 16px; } .detail-card .label { font-size: 0.8em; color: var(--text-muted); margin-bottom: 4px; } .detail-card .value { font-size: 1.2em; font-weight: 600; } .info-table { width: 100%; border-collapse: collapse; } .info-table td { padding: 6px 12px; border-bottom: 1px solid var(--border); font-size: 0.9em; } .info-table td:first-child { color: var(--text-muted); width: 140px; } .error-text { color: var(--red); } /* ─── Config editor ────────────────────────────────────── */ .message { padding: 12px 16px; border-radius: 6px; margin-bottom: 16px; font-size: 0.9em; } .message-error { background: rgba(248,113,113,0.15); color: var(--red); border: 1px solid rgba(248,113,113,0.3); } .message-ok { background: rgba(74,222,128,0.15); color: var(--green); border: 1px solid rgba(74,222,128,0.3); } textarea { width: 100%; min-height: 500px; background: var(--surface); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 16px; font-family: var(--mono); font-size: 0.85em; line-height: 1.5; resize: vertical; tab-size: 4; } textarea:focus { outline: none; border-color: var(--accent); } .form-actions { margin-top: 12px; display: flex; gap: 12px; } /* ─── Config form (interactive editor) ─────────────────── */ .config-section { margin-bottom: 16px; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; } .section-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; background: var(--surface); cursor: pointer; user-select: none; } .section-header h3 { font-size: 1em; display: flex; align-items: center; gap: 8px; } .section-body { padding: 16px; } .tier-badge { font-size: 0.7em; padding: 2px 8px; border-radius: 4px; font-weight: 600; } .tier-live { background: rgba(74,222,128,0.15); color: var(--green); } .tier-protocol { background: rgba(251,191,36,0.15); color: var(--yellow); } .tier-pershare { background: rgba(251,191,36,0.15); color: var(--yellow); } .tier-global { background: rgba(248,113,113,0.15); color: var(--red); } .tier-none { background: rgba(74,222,128,0.15); color: var(--green); } .field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } .field-row { margin-bottom: 12px; } .field-grid .field-row { margin-bottom: 0; } .field-row label:not(.toggle) { display: block; font-size: 0.8em; color: var(--text-muted); margin-bottom: 4px; } .field-row input[type="text"], .field-row input[type="password"], .field-row input[type="number"], .field-row select { width: 100%; padding: 8px 12px; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 6px; font-family: var(--font); font-size: 0.9em; } .field-row input:focus, .field-row select:focus { outline: none; border-color: var(--accent); } .field-row input.mono { font-family: var(--mono); } .array-item { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px; margin-bottom: 12px; position: relative; } .array-item .item-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .remove-btn { background: none; border: 1px solid rgba(248,113,113,0.3); color: var(--red); padding: 4px 12px; border-radius: 4px; cursor: pointer; font-size: 0.8em; } .remove-btn:hover { background: rgba(248,113,113,0.1); } .add-btn { width: 100%; padding: 8px; background: none; border: 1px dashed var(--border); border-radius: 8px; color: var(--text-muted); cursor: pointer; font-size: 0.9em; } .add-btn:hover { border-color: var(--accent); color: var(--accent); } /* Toggle switch */ .toggle { position: relative; display: inline-flex; align-items: center; cursor: pointer; gap: 8px; font-size: 0.9em; color: var(--text); } .toggle input { display: none; } .toggle .slider { width: 36px; height: 20px; background: var(--border); border-radius: 10px; position: relative; transition: background 0.2s; flex-shrink: 0; } .toggle .slider::after { content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; background: var(--text-muted); border-radius: 50%; transition: transform 0.2s; } .toggle input:checked + .slider { background: var(--accent); } .toggle input:checked + .slider::after { transform: translateX(16px); background: #fff; } .chevron { font-size: 0.9em; color: var(--text-muted); } /* ─── Buttons ──────────────────────────────────────────── */ .btn { display: inline-block; padding: 8px 20px; border-radius: 6px; font-size: 0.9em; font-weight: 500; cursor: pointer; border: none; text-decoration: none; text-align: center; } .btn-primary { background: var(--accent); color: #fff; } .btn-primary:hover { opacity: 0.9; } .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; } .btn-secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); } .btn-secondary:hover { border-color: var(--accent); color: var(--accent); } /* ─── Log viewer ──────────────────────────────────────── */ .log-viewer { background: #0a0c10; border: 1px solid var(--border); border-radius: 8px; padding: 16px; font-family: var(--mono); font-size: 0.8em; line-height: 1.6; height: 70vh; overflow-y: auto; overflow-x: hidden; word-break: break-all; } .log-viewer .log-line { color: var(--text-muted); } .log-viewer .log-ts { color: var(--accent); margin-right: 8px; opacity: 0.7; } .log-viewer .log-msg { color: var(--text); } .log-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; font-size: 0.85em; color: var(--text-muted); } .log-toolbar .log-count { font-family: var(--mono); } .empty-state { text-align: center; padding: 48px 24px; color: var(--text-muted); } .empty-state h2 { font-size: 1.2em; margin-bottom: 8px; color: var(--text); } /* ─── Responsive ───────────────────────────────────────── */ @media (max-width: 768px) { .stat-cards { grid-template-columns: repeat(2, 1fr); } .detail-grid { grid-template-columns: 1fr; } .field-grid { grid-template-columns: 1fr; } .share-table th:nth-child(n+5), .share-table td:nth-child(n+5) { display: none; } } @media (max-width: 480px) { .shell { padding: 12px; } .stat-cards { grid-template-columns: 1fr; } .tabs { overflow-x: auto; } .tab-btn { padding: 8px 14px; font-size: 0.85em; } }