/* ─── Reset ──────────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } /* ─── Design tokens — THEME 01: DIGITAL GRID (Tron-inspired) ── */ :root { --bg: #000810; --bg-card: #010f20; --bg-inner: #000d1a; --bg-hover: #001a30; --bg-input: #000813; --border: #0a3060; --border-hi: rgba(0, 245, 255, 0.45); --accent: #00f5ff; --accent-dim: #002535; --danger: #ff3b3b; --danger-dim: #3b0000; --success: #00ff88; --warning: #ffaa00; --text: #c8f0ff; --text-muted: #2e6a80; --radius: 8px; --shadow: 0 0 0 1px rgba(0, 245, 255, 0.25), 0 0 60px rgba(0, 245, 255, 0.12), 0 28px 72px rgba(0, 0, 0, 0.9); } /* ─── Base ───────────────────────────────────────────────────── */ html, body { height: 100%; font-family: "Courier New", Courier, monospace; background: var(--bg); color: var(--text); font-size: 14px; overflow: hidden; display: flex; align-items: center; justify-content: center; } /* Digital grid — star field, ambient glow, horizon line */ body::before { content: ""; position: fixed; inset: 0; background: /* ── Stars: solid-core dots, varied size & tint ── */ /* Row 1 — bright feature stars (y 3–12 %) */ radial-gradient( circle 5px at 5% 8%, white 0%, white 40%, rgba(180, 245, 255, 0.3) 72%, transparent 100% ), radial-gradient( circle 3px at 15% 5%, white 0%, white 42%, transparent 100% ), radial-gradient( circle 3px at 22% 12%, rgba(180, 235, 255, 1) 0%, rgba(180, 235, 255, 1) 42%, transparent 100% ), radial-gradient( circle 6px at 31% 4%, white 0%, white 38%, rgba(150, 220, 255, 0.35) 70%, transparent 100% ), radial-gradient( circle 3px at 40% 9%, rgba(160, 230, 255, 1) 0%, rgba(160, 230, 255, 1) 42%, transparent 100% ), radial-gradient( circle 3px at 47% 6%, white 0%, white 42%, transparent 100% ), radial-gradient( circle 4px at 54% 3%, rgba(190, 245, 255, 1) 0%, rgba(190, 245, 255, 1) 42%, rgba(190, 245, 255, 0.3) 72%, transparent 100% ), radial-gradient( circle 3px at 63% 11%, white 0%, white 42%, transparent 100% ), radial-gradient( circle 5px at 71% 7%, white 0%, white 40%, rgba(180, 245, 255, 0.28) 70%, transparent 100% ), radial-gradient( circle 3px at 79% 4%, rgba(150, 215, 255, 1) 0%, rgba(150, 215, 255, 1) 42%, transparent 100% ), radial-gradient( circle 3px at 87% 9%, white 0%, white 42%, transparent 100% ), radial-gradient( circle 4px at 94% 5%, rgba(190, 245, 255, 1) 0%, rgba(190, 245, 255, 1) 42%, rgba(190, 245, 255, 0.28) 70%, transparent 100% ), /* Row 2 — mid brightness (y 14–26 %) */ radial-gradient( circle 2px at 9% 19%, rgba(255, 255, 255, 0.65) 0%, rgba(255, 255, 255, 0.65) 45%, transparent 100% ), radial-gradient( circle 3px at 18% 16%, white 0%, white 42%, transparent 100% ), radial-gradient( circle 2px at 27% 22%, rgba(180, 240, 255, 0.7) 0%, rgba(180, 240, 255, 0.7) 45%, transparent 100% ), radial-gradient( circle 3px at 37% 14%, white 0%, white 42%, transparent 100% ), radial-gradient( circle 2px at 50% 25%, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.6) 45%, transparent 100% ), radial-gradient( circle 4px at 57% 17%, rgba(180, 240, 255, 1) 0%, rgba(180, 240, 255, 1) 42%, rgba(180, 240, 255, 0.28) 70%, transparent 100% ), radial-gradient( circle 2px at 66% 23%, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0.55) 45%, transparent 100% ), radial-gradient( circle 3px at 75% 15%, white 0%, white 42%, transparent 100% ), radial-gradient( circle 2px at 83% 20%, rgba(160, 225, 255, 0.7) 0%, rgba(160, 225, 255, 0.7) 45%, transparent 100% ), radial-gradient( circle 2px at 91% 17%, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.6) 45%, transparent 100% ), radial-gradient( circle 3px at 98% 24%, rgba(180, 240, 255, 1) 0%, rgba(180, 240, 255, 1) 42%, transparent 100% ), /* Row 3 — dim background stars (y 28–42 %) */ radial-gradient( circle 2px at 3% 33%, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.4) 45%, transparent 100% ), radial-gradient( circle 2px at 13% 38%, rgba(180, 235, 255, 0.45) 0%, rgba(180, 235, 255, 0.45) 45%, transparent 100% ), radial-gradient( circle 2px at 24% 30%, rgba(255, 255, 255, 0.38) 0%, rgba(255, 255, 255, 0.38) 45%, transparent 100% ), radial-gradient( circle 3px at 33% 40%, rgba(170, 230, 255, 0.55) 0%, rgba(170, 230, 255, 0.55) 42%, transparent 100% ), radial-gradient( circle 2px at 44% 34%, rgba(255, 255, 255, 0.38) 0%, rgba(255, 255, 255, 0.38) 45%, transparent 100% ), radial-gradient( circle 2px at 53% 42%, rgba(255, 255, 255, 0.35) 0%, rgba(255, 255, 255, 0.35) 45%, transparent 100% ), radial-gradient( circle 2px at 62% 31%, rgba(180, 240, 255, 0.45) 0%, rgba(180, 240, 255, 0.45) 45%, transparent 100% ), radial-gradient( circle 3px at 69% 38%, white 0%, white 42%, transparent 100% ), radial-gradient( circle 2px at 77% 29%, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.4) 45%, transparent 100% ), radial-gradient( circle 2px at 85% 36%, rgba(180, 235, 255, 0.42) 0%, rgba(180, 235, 255, 0.42) 45%, transparent 100% ), radial-gradient( circle 2px at 96% 32%, rgba(255, 255, 255, 0.38) 0%, rgba(255, 255, 255, 0.38) 45%, transparent 100% ), /* ── Ambient glow + horizon line ── */ radial-gradient( ellipse 70% 55% at 50% 48%, rgba(0, 120, 200, 0.18) 0%, transparent 68% ), radial-gradient( ellipse 100% 4% at 50% 50%, rgba(0, 245, 255, 0.22) 0%, transparent 100% ); pointer-events: none; z-index: 0; } /* 3-D perspective grid floor — recedes to vanishing point */ body::after { content: ""; position: fixed; left: -100%; width: 300%; height: 62%; bottom: -8%; background-image: linear-gradient(rgba(0, 245, 255, 0.28) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 245, 255, 0.16) 1px, transparent 1px); background-size: 80px 40px; transform: perspective(520px) rotateX(75deg); transform-origin: center 0%; -webkit-mask-image: linear-gradient( to bottom, transparent 0%, rgba(0, 0, 0, 0.55) 22%, black 50% ); mask-image: linear-gradient( to bottom, transparent 0%, rgba(0, 0, 0, 0.55) 22%, black 50% ); pointer-events: none; z-index: 0; } /* ─── AUTH CARD ─────────────────────────────────────────────── */ .auth-card { position: relative; z-index: 10; width: min(440px, calc(100vw - 24px)); background: var(--bg-card); border: 1px solid var(--border-hi); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; animation: fadeUp 1s cubic-bezier(0.65, 0, 0.85, 0.05) 1 both; } @keyframes fadeUp { from { opacity: 0; transform: scale(0); filter: blur(6px); } to { opacity: 1; transform: scale(1); filter: blur(0); } } .auth-logo { text-align: center; padding: 36px 24px 20px; } .auth-logo-icon { display: inline-flex; align-items: center; justify-content: center; width: 56px; height: 56px; border-radius: 16px; background: var(--accent-dim); border: 1px solid rgba(79, 142, 247, 0.3); color: var(--accent); margin-bottom: 14px; } .auth-title { font-size: 22px; font-weight: 700; color: var(--text); letter-spacing: -0.3px; } .auth-sub { font-size: 13px; color: var(--text-muted); margin-top: 4px; } /* Auth tab switch */ .auth-switch { display: flex; gap: 0; margin: 4px 24px 0; background: var(--bg-inner); border: 1px solid var(--border); border-radius: 10px; padding: 3px; } .auth-switch-btn { flex: 1; padding: 8px; border: none; border-radius: 7px; background: transparent; color: var(--text-muted); font-size: 13px; font-weight: 500; cursor: pointer; transition: background 0.15s, color 0.15s; } .auth-switch-btn.active { background: var(--bg-card); color: var(--text); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } .auth-switch-btn:hover:not(.active) { color: var(--text); } /* Auth form */ .auth-form { display: flex; flex-direction: column; gap: 12px; padding: 20px 24px 28px; } .auth-error { display: none; align-items: flex-start; gap: 8px; padding: 9px 12px; background: var(--danger-dim); border: 1px solid var(--danger); border-radius: 6px; font-size: 12px; color: var(--danger); line-height: 1.5; } .auth-success { display: none; align-items: flex-start; gap: 10px; padding: 12px 14px; background: #0e2e1c; border: 1px solid var(--success); border-radius: 6px; font-size: 13px; color: var(--success); line-height: 1.55; } /* ─── APP SHELL ─────────────────────────────────────────────── */ .app-shell { position: relative; z-index: 10; display: none; /* shown by JS */ flex-direction: column; width: min(1060px, calc(100vw - 16px)); height: min(780px, calc(100vh - 16px)); background: var(--bg-card); border: 1px solid var(--border-hi); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; animation: fadeUp 1s cubic-bezier(0.65, 0, 0.85, 0.05) 1 both; } /* App header */ .app-header { display: flex; align-items: center; justify-content: space-between; height: 54px; padding: 0 22px; border-bottom: 1px solid var(--border-hi); background: linear-gradient( 90deg, rgba(0, 245, 255, 0.08) 0%, transparent 60% ); flex-shrink: 0; gap: 12px; } .app-brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; color: var(--accent); letter-spacing: 1.5px; text-shadow: 0 0 14px rgba(0, 245, 255, 0.85); flex-shrink: 0; } .header-comment { flex: 1; display: flex; justify-content: center; align-items: center; padding: 0 12px; min-width: 0; } #header-comment-display { cursor: pointer; font-size: 13px; color: var(--text); max-width: 360px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 3px 8px; border-radius: var(--radius); border: 1px solid transparent; transition: border-color 0.15s, color 0.15s; } #header-comment-display:hover { border-color: var(--border); } #header-comment-display.comment-empty { color: var(--text-muted); font-style: italic; } #header-comment-edit { align-items: center; gap: 6px; } #header-comment-input { background: var(--bg-input); border: 1px solid var(--accent); border-radius: 6px; color: var(--text); padding: 4px 10px; font-size: 13px; width: 260px; outline: none; } .app-user { display: flex; align-items: center; gap: 10px; position: relative; } .user-pill { display: flex; align-items: center; gap: 7px; padding: 4px 10px; background: var(--bg-inner); border: 1px solid var(--border); border-radius: 20px; font-size: 12px; color: var(--text-muted); cursor: pointer; transition: border-color 0.15s, color 0.15s; user-select: none; } .user-pill:hover { border-color: var(--accent); color: var(--text); } /* ─── User account panel dropdown ─────────────────────────── */ .user-panel { position: absolute; top: calc(100% + 10px); right: 0; min-width: 264px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); z-index: 200; overflow: hidden; animation: panelIn 0.15s ease; } @keyframes panelIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } } .user-panel-header { display: flex; align-items: center; gap: 7px; padding: 11px 14px 10px; font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.06em; border-bottom: 1px solid var(--border); background: var(--bg-inner); } .user-panel-row { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; gap: 12px; } .user-panel-label { font-size: 11px; color: var(--text-muted); flex-shrink: 0; } .user-panel-val { font-size: 12px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px; } .user-panel-divider { height: 1px; background: var(--border); margin: 0; } .user-panel-pw { padding: 12px 14px 14px; } .user-panel-pw .form-group { margin-bottom: 4px; } .pulse-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success); flex-shrink: 0; animation: pulse 2s ease infinite; } @keyframes pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(63, 201, 126, 0.5); } 50% { box-shadow: 0 0 0 4px rgba(63, 201, 126, 0); } } /* Agent tabs bar */ .agent-tabs-bar { display: flex; align-items: center; gap: 6px; padding: 0 20px; height: 50px; border-bottom: 1px solid var(--border); background: var(--bg-inner); flex-shrink: 0; overflow-x: auto; scrollbar-width: none; } .agent-tabs-bar::-webkit-scrollbar { display: none; } .agent-tab { display: inline-flex; align-items: center; gap: 7px; padding: 6px 14px; border-radius: 20px; border: 1px solid var(--border); background: transparent; color: var(--text-muted); font-size: 13px; font-weight: 500; cursor: pointer; white-space: nowrap; transition: border-color 0.15s, background 0.15s, color 0.15s; flex-shrink: 0; } .agent-tab:hover:not(.active) { border-color: rgba(79, 142, 247, 0.4); color: var(--text); background: var(--bg-hover); } .agent-tab.active { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); } .agent-tab-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success); flex-shrink: 0; } .agent-tab-dot--red { background: var(--danger); box-shadow: 0 0 0 2px rgba(224, 82, 82, 0.25); } .agent-tab-badge { font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 4px; background: var(--bg-hover); color: var(--text-muted); letter-spacing: 0.04em; } .agent-tab.active .agent-tab-badge { background: rgba(79, 142, 247, 0.2); color: var(--accent); } .agent-tab-add { display: inline-flex; align-items: center; gap: 7px; padding: 6px 14px; border-radius: 20px; border: 1px solid var(--border); background: transparent; color: var(--text-muted); font-size: 13px; font-weight: 500; text-decoration: none; white-space: nowrap; flex-shrink: 0; transition: border-color 0.15s, color 0.15s, background 0.15s; } .agent-tab-add:hover { border-color: rgba(79, 142, 247, 0.4); color: var(--text); background: var(--bg-hover); } .tabs-loading, .tabs-empty, .tabs-error { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-muted); padding: 0 4px; } .tabs-error { color: var(--danger); } /* App body */ .app-body { flex: 1; overflow: hidden; position: relative; display: flex; flex-direction: column; } /* Empty / no-agents state */ .empty-center { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; color: var(--text-muted); font-size: 14px; } .empty-center svg { opacity: 0.2; } /* Agent panel + content grid */ #agent-panel { flex: 1; overflow: hidden; display: flex; flex-direction: column; } .content-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding: 18px 20px; flex: 1; overflow-y: auto; align-content: start; scrollbar-width: thin; scrollbar-color: var(--border) transparent; } .content-grid::-webkit-scrollbar { width: 5px; } .content-grid::-webkit-scrollbar-track { background: transparent; } .content-grid::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; } .content-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; position: relative; } /* ─── Cards ─────────────────────────────────────────────────── */ .card { background: var(--bg-inner); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px; } .card-full { flex: 1; } .card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 10px; flex-wrap: wrap; } .card-title { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; color: var(--text); } /* ─── Keys ──────────────────────────────────────────────────── */ .key-row { display: flex; align-items: flex-start; gap: 12px; padding: 6px 0; } .key-row + .key-row { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 6px; } .key-info { flex: 1; min-width: 0; } .key-name { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .key-label { display: block; font-family: "Cascadia Code", "Fira Code", monospace; font-size: 11px; color: var(--text-muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .key-stats { display: flex; align-items: center; gap: 6px; margin-top: 5px; font-size: 12px; color: var(--text-muted); flex-wrap: wrap; } .key-stat-val { font-weight: 600; color: var(--text); } .sep-dot { color: var(--border); } /* ─── SSH ───────────────────────────────────────────────────── */ .ssh-wrap { display: flex; gap: 8px; align-items: flex-start; } .ssh-wrap textarea { flex: 1; background: var(--bg-input); border: 1px solid var(--border); border-radius: 6px; color: var(--text); padding: 8px 10px; font-size: 12px; font-family: "Cascadia Code", "Fira Code", monospace; outline: none; resize: none; transition: border-color 0.15s; line-height: 1.5; } .ssh-wrap textarea:focus { border-color: var(--accent); } /* ─── Instance Password card ────────────────────────────────── */ .pw-wrap { padding: 14px 16px 12px; } .pw-wrap .form-group { margin-bottom: 0; } .pw-input-wrap { position: relative; display: flex; align-items: center; } .pw-input-wrap input { padding-right: 36px; } .pw-save-btn { position: absolute; right: 6px; display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; background: none; border: none; border-radius: 4px; color: var(--accent); cursor: pointer; transition: color 0.15s, background 0.15s; } .pw-save-btn:hover { background: var(--bg-hover); } .ssh-hint { margin-top: 7px; font-size: 11px; color: var(--text-muted); line-height: 1.5; } .ssh-cmd-row { display: flex; align-items: center; gap: 8px; margin-top: 10px; background: var(--bg-input); border: 1px solid var(--border); border-radius: 6px; padding: 7px 10px; } .ssh-cmd-code { flex: 1; font-family: "Cascadia Code", "Fira Code", monospace; font-size: 11.5px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; user-select: all; } .ssh-copy-btn { flex-shrink: 0; } /* ─── Server info rows ─────────────────────────────────────── */ .server-info-row { display: flex; justify-content: space-between; align-items: center; padding: 5px 0; border-top: 1px solid var(--border); font-size: 12px; } .server-info-row--copy { cursor: pointer; } .server-info-row--copy:hover .server-info-copyval { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; } .server-info-copyval { font-family: "Cascadia Code", "Fira Code", monospace; font-size: 11.5px; transition: color 0.15s; } .server-info-row:first-child { margin-top: 4px; } .server-info-label { color: var(--text-muted); text-transform: capitalize; } .server-info-val { color: var(--text); font-family: "Cascadia Code", "Fira Code", monospace; font-size: 11.5px; } .server-info-link { color: var(--accent); text-decoration: none; } .server-info-link:hover { text-decoration: underline; } /* ─── Backups ───────────────────────────────────────────────── */ .backups-list { display: flex; flex-direction: column; gap: 0; max-height: 320px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border) transparent; } .backups-list::-webkit-scrollbar { width: 4px; } .backups-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; } .backup-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); } .backup-row:last-child { border-bottom: none; } .backup-info { flex: 1; min-width: 0; } .backup-name { font-size: 13px; font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .backup-date { font-size: 11px; color: var(--text-muted); margin-top: 2px; } .backup-empty { display: flex; flex-direction: column; align-items: center; padding: 28px 0; color: var(--text-muted); font-size: 13px; gap: 6px; } /* ─── Buttons ───────────────────────────────────────────────── */ .btn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 6px; border: none; cursor: pointer; font-size: 13px; font-weight: 500; white-space: nowrap; text-decoration: none; transition: opacity 0.15s, background 0.15s, box-shadow 0.15s, border-color 0.15s, transform 0.1s; flex-shrink: 0; } .btn:hover { opacity: 0.85; } .btn:active { opacity: 0.7; transform: scale(0.97); } .btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none; } .btn-primary { background: transparent; color: #fff; border: 1px solid var(--accent); box-shadow: 0 0 8px rgba(0, 245, 255, 0.35), inset 0 0 8px rgba(0, 245, 255, 0.04); } .btn-primary:hover { opacity: 1; background: rgba(0, 245, 255, 0.08); border-color: var(--accent); box-shadow: 0 0 18px rgba(0, 245, 255, 0.55), inset 0 0 12px rgba(0, 245, 255, 0.07); } .btn-danger { background: var(--danger); color: #fff; } .btn-success { background: var(--success); color: #000; } .btn-ghost { background: var(--bg-hover); color: var(--text); border: 1px solid var(--border); } .btn-sm { padding: 5px 10px; font-size: 12px; } .btn-block { width: 100%; justify-content: center; padding: 10px 14px; font-size: 14px; } /* ─── Forms ─────────────────────────────────────────────────── */ .form-row { display: flex; gap: 10px; flex-wrap: wrap; } .form-group { display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 130px; } .form-group label { font-size: 12px; color: var(--text-muted); font-weight: 500; } .form-group input, .form-group select, .form-group textarea { background: var(--bg-input); border: 1px solid var(--border); border-radius: 6px; color: var(--text); padding: 9px 11px; font-size: 13px; outline: none; transition: border-color 0.15s; width: 100%; } .form-group input:focus, .form-group select:focus, .form-group textarea:focus { border-color: var(--accent); } .form-group select option { background: var(--bg-card); } .form-group textarea { resize: vertical; font-family: monospace; font-size: 12px; box-sizing: border-box; line-height: 1.5; } /* ─── Progress bar ──────────────────────────────────────────── */ .prog-wrap { background: var(--bg-input); border-radius: 4px; height: 4px; margin-top: 6px; overflow: hidden; } .prog-bar { height: 100%; border-radius: 4px; transition: width 0.5s ease; min-width: 3px; } .prog-low { background: var(--success); } .prog-mid { background: var(--warning); } .prog-high { background: var(--danger); } /* ─── Loading rows ──────────────────────────────────────────── */ .loading-row { display: flex; align-items: center; justify-content: center; padding: 20px; color: var(--text-muted); gap: 8px; font-size: 13px; } .inline-error { font-size: 12px; color: var(--danger); padding: 6px 0; } /* ─── Spinner ───────────────────────────────────────────────── */ .spinner { width: 18px; height: 18px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.6s linear infinite; display: inline-block; flex-shrink: 0; } .spinner-sm { width: 13px; height: 13px; border: 2px solid rgba(255, 255, 255, 0.2); border-top-color: #fff; border-radius: 50%; animation: spin 0.6s linear infinite; display: inline-block; flex-shrink: 0; } @keyframes spin { to { transform: rotate(360deg); } } /* ─── Toast ─────────────────────────────────────────────────── */ #toast-container { position: fixed; bottom: 22px; right: 22px; display: flex; flex-direction: column; gap: 8px; z-index: 9999; } .toast { background: var(--bg-card); border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: var(--radius); padding: 11px 16px; min-width: 240px; max-width: 360px; box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5); font-size: 13px; line-height: 1.45; animation: toastIn 0.2s ease; transition: opacity 0.3s, transform 0.3s; } .toast-error { border-left-color: var(--danger); } .toast-success { border-left-color: var(--success); } .toast-warning { border-left-color: var(--warning); } @keyframes toastIn { from { transform: translateX(50px); opacity: 0; } to { transform: translateX(0); opacity: 1; } } /* ─── Modal / Confirm ───────────────────────────────────────── */ .modal-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.65); z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 20px; opacity: 0; pointer-events: none; transition: opacity 0.2s; backdrop-filter: blur(3px); } .modal-backdrop.open { opacity: 1; pointer-events: all; } .modal { background: var(--bg-card); border: 1px solid var(--border-hi); border-radius: 12px; width: 100%; max-width: 400px; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6); transform: translateY(16px); transition: transform 0.2s; } .modal-backdrop.open .modal { transform: translateY(0); } .modal-header { padding: 18px 22px 14px; border-bottom: 1px solid var(--border); } .modal-title { font-size: 15px; font-weight: 600; } .modal-body { padding: 18px 22px; } .modal-body p { font-size: 14px; line-height: 1.65; color: var(--text-muted); } .modal-footer { padding: 14px 22px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 10px; } /* ─── Account Modal ────────────────────────────────────────────────── */ .account-modal { max-width: 760px; width: 100%; } .account-modal .modal-header { display: flex; align-items: center; justify-content: space-between; } .modal-close-btn { background: none; border: none; color: var(--text-muted); font-size: 16px; cursor: pointer; padding: 0 2px; line-height: 1; transition: color 0.15s; } .modal-close-btn:hover { color: var(--text); } .account-modal-body { display: flex; min-height: 320px; } .account-col { display: flex; flex-direction: column; } .modal-header-row { display: flex; align-items: center; width: 100%; gap: 12px; } .modal-header-row .modal-title { flex-shrink: 0; } .modal-header-tabs { display: flex; gap: 0; flex: 1; justify-content: center; } .acct-settings-tab { background: none; border: none; color: var(--text-muted); font-family: inherit; font-size: 12px; padding: 6px 14px; cursor: pointer; transition: color 0.15s; } .acct-settings-tab:hover { color: var(--text); } .acct-settings-tab.active { color: var(--accent); } .modal-header-row .modal-close-btn { flex-shrink: 0; } .account-col--settings { width: 260px; flex-shrink: 0; padding: 18px 20px; } .acct-tab-content { display: flex; flex-direction: column; } .account-col-divider { width: 1px; background: var(--border); flex-shrink: 0; } .account-col--invoices { flex: 1; padding: 18px 20px; min-width: 0; overflow: hidden; } .acct-section { padding: 4px 0 10px; } .acct-divider { height: 1px; background: var(--border); margin: 6px 0 14px; } .acct-field-label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 4px; } .acct-field-val { font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .acct-affiliate-row { display: flex; align-items: center; gap: 10px; margin-top: 4px; } .acct-affiliate-code { font-size: 13px; font-weight: 600; color: var(--accent); letter-spacing: 0.06em; font-family: "Courier New", monospace; } .acct-invoices-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; gap: 10px; } .acct-invoices-title { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.06em; flex-shrink: 0; } .acct-invoices-actions { display: flex; align-items: center; gap: 8px; flex: 1; justify-content: flex-end; } .invoice-filter-input { background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius); padding: 4px 8px; font-size: 11px; color: var(--text); width: 140px; outline: none; transition: border-color 0.15s; } .invoice-filter-input:focus { border-color: var(--accent); } .invoice-list { display: flex; flex-direction: column; gap: 2px; max-height: 360px; overflow-y: auto; } .invoice-row { display: grid; grid-template-columns: 100px 1fr 1fr 80px 60px; gap: 10px; align-items: center; padding: 7px 10px; border-radius: var(--radius); font-size: 12px; } .invoice-row--head { color: var(--text-muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; background: none; padding-bottom: 4px; margin-bottom: 2px; border-bottom: 1px solid var(--border); } .invoice-row:not(.invoice-row--head) { background: var(--bg-inner); border: 1px solid var(--border); color: var(--text); } .invoice-row:not(.invoice-row--head):hover { border-color: var(--border-hi); } .invoice-date { color: var(--text-muted); white-space: nowrap; } .invoice-uuid { color: var(--accent); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .invoice-product { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .invoice-price { text-align: right; font-weight: 600; color: var(--success); white-space: nowrap; } .invoice-dl { text-align: center; } .invoice-dl-link { color: var(--accent); text-decoration: none; font-size: 11px; transition: opacity 0.15s; } .invoice-dl-link:hover { opacity: 0.7; } .invoice-dl-link--disabled { color: var(--text-muted); cursor: default; } /* ─── Credits Modal ────────────────────────────────────────── */ .credits-key-label { font-size: 12px; color: var(--text-muted); margin: 0 0 14px; } .credits-key-label span { color: var(--accent); font-weight: 600; } .credits-options { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 14px; } .credits-option { display: flex; align-items: center; gap: 10px; padding: 11px 14px; background: var(--bg-inner); border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; transition: border-color 0.15s, background 0.15s; user-select: none; } .credits-option:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); } .credits-option input[type="radio"] { accent-color: var(--accent); width: 15px; height: 15px; flex-shrink: 0; cursor: pointer; } .credits-option-label { font-size: 15px; font-weight: 600; color: var(--text); letter-spacing: 0.02em; } .credits-fee-note { font-size: 12px; color: var(--text-muted); line-height: 1.55; background: var(--bg-inner); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin: 0; } /* ─── Utility ───────────────────────────────────────────────── */ .text-muted { color: var(--text-muted); } /* ─── Responsive ────────────────────────────────────────────── */ @media (max-width: 700px) { .content-grid { grid-template-columns: 1fr; } .app-shell { border-radius: 0; width: 100vw; height: 100vh; } .app-user .user-pill { display: none; } } @media (max-height: 680px) { .app-shell { border-radius: 0; height: 100vh; } } /* ─── Talk to Us panel ──────────────────────────────────────────── */ .talk-wrap { border-top: 1px solid var(--border-hi); flex-shrink: 0; background: var(--bg-inner); box-shadow: 0 -4px 20px rgba(0, 245, 255, 0.08); } .talk-toggle { width: 100%; display: flex; align-items: center; gap: 8px; padding: 9px 22px; background: linear-gradient( 90deg, rgba(0, 245, 255, 0.08) 0%, transparent 70% ); border: none; color: var(--accent); font-size: 12px; font-weight: 600; cursor: pointer; transition: background 0.15s, color 0.15s; letter-spacing: 0.3px; } .talk-toggle:hover { background: linear-gradient( 90deg, rgba(0, 245, 255, 0.16) 0%, transparent 70% ); color: var(--text); } .talk-toggle.active { color: var(--text); background: linear-gradient( 90deg, rgba(0, 245, 255, 0.14) 0%, transparent 70% ); } .talk-panel { display: grid; grid-template-columns: 1fr 1fr; max-height: 0; overflow: hidden; transition: max-height 0.28s ease; } .talk-panel.open { max-height: 270px; } .talk-col { padding: 12px 20px 14px; display: flex; flex-direction: column; gap: 8px; } .talk-chat-col { border-right: 1px solid var(--border); } .talk-col-title { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.6px; } .chat-msgs { flex: 1; overflow-y: auto; max-height: 150px; display: flex; flex-direction: column; gap: 5px; padding-right: 2px; } .chat-msg { max-width: 82%; padding: 5px 10px; border-radius: 10px; font-size: 12px; line-height: 1.45; word-break: break-word; } .chat-msg-user { align-self: flex-end; background: var(--bg-hover); color: var(--text); border-bottom-right-radius: 3px; } .chat-msg-bot { align-self: flex-start; background: var(--bg-hover); color: var(--text); border-bottom-left-radius: 3px; } .chat-input-row { display: flex; gap: 6px; } .chat-input-row input { flex: 1; background: var(--bg-input); border: 1px solid var(--border); border-radius: 6px; color: var(--text); padding: 5px 10px; font-size: 12px; outline: none; min-width: 0; } .chat-input-row input:focus { border-color: var(--accent); } .refer-desc { font-size: 12px; color: var(--text-muted); line-height: 1.55; flex: 1; } .refer-desc strong { color: var(--text); } .refer-form { display: flex; flex-direction: column; gap: 6px; } .refer-input-row { display: flex; gap: 6px; } .refer-input-row input { flex: 1; background: var(--bg-input); border: 1px solid var(--border); border-radius: 6px; color: var(--text); padding: 5px 10px; font-size: 12px; outline: none; min-width: 0; } .refer-input-row input:focus { border-color: var(--accent); } .refer-result { font-size: 12px; color: var(--success); margin: 0; line-height: 1.4; } /* ─── Auth-layout: auth card ABOVE demo shell, stacked ──────── */ body.auth-layout { flex-direction: column; gap: 14px; align-items: center; justify-content: center; } /* Auth card matches the app-shell width */ body.auth-layout .auth-card { width: min(1060px, calc(100vw - 16px)); } /* Logo visibility: top logo for narrow, pane logo for dual */ .auth-logo-pane { display: none; } body.auth-layout .auth-logo-top { display: none; } body.auth-layout .auth-logo-pane { display: flex; align-items: center; gap: 14px; padding: 22px 24px 16px; text-align: left; border-bottom: 1px solid var(--border); } body.auth-layout .auth-logo-pane .auth-logo-icon { flex-shrink: 0; } body.auth-layout .auth-logo-pane .auth-title { font-size: 18px; margin-bottom: 2px; } body.auth-layout .auth-logo-pane .auth-sub { font-size: 12px; margin-top: 0; } /* Hide the tab toggle when both panes are visible */ body.auth-layout .auth-switch { display: none; } /* Dual-pane form wrapper */ .auth-forms-wrap { display: block; } body.auth-layout .auth-forms-wrap { display: flex; flex-direction: row; align-items: stretch; /* equal height for both panes */ } body.auth-layout .auth-pane { flex: 1 1 0; /* equal widths */ min-width: 0; display: flex; flex-direction: column; } /* Right pane: badge at top, form pushed to bottom */ body.auth-layout .auth-pane:last-child { justify-content: center; } /* Pricing badge */ /* ─── Hire Agent CTA (replaces signup form) ──────────────────────────── */ .hire-cta { display: flex; flex-direction: column; gap: 14px; padding: 20px 24px 28px; } .hire-link { display: block; text-align: center; font-size: 12px; color: var(--text-muted); text-decoration: none; letter-spacing: 0.2px; transition: color 0.15s; } .hire-link:hover { color: var(--accent); } .hire-note { margin: auto 0 0; font-size: 12px; color: var(--text-muted); text-align: center; line-height: 1.5; } body.auth-layout .auth-forms-divider { width: 1px; align-self: stretch; background: var(--border); margin: 0; flex-shrink: 0; } .auth-pane-title { display: none; } body.auth-layout #signup-form { display: flex !important; flex-direction: column; gap: 14px; padding: 24px; } /* Sign-in form stretches and pushes its button to the bottom so it aligns with the Create Account button on the right */ body.auth-layout #signin-form { flex: 1; } body.auth-layout #signin-btn { margin-top: auto; } /* Demo shell is always hidden — we no longer show a preview on the auth screen */ #app-shell.demo-mode { display: none !important; } .demo-notice { display: none; position: absolute; inset: 0; z-index: 20; align-items: center; justify-content: center; flex-direction: column; gap: 10px; background: transparent; /* no tint — content stays fully visible */ color: var(--text); font-size: 13px; font-weight: 500; text-align: center; border-radius: 4px; } .demo-notice span { display: inline-flex; align-items: center; gap: 9px; background: var(--danger-dim); border: 1px solid var(--danger); border-radius: 24px; padding: 11px 22px; color: var(--danger); font-size: 15px; font-weight: 600; box-shadow: 0 4px 28px rgba(224, 82, 82, 0.35); letter-spacing: 0.1px; } #app-shell.demo-mode .demo-notice { display: flex; } /* ─── Login animations ───────────────────────────────────────── */ @keyframes authLeave { to { opacity: 0; transform: translateY(-28px); filter: blur(8px); } } .auth-card.auth-leaving { animation: authLeave 0.3s ease-in forwards; pointer-events: none; } @keyframes shellEnter { from { opacity: 0; transform: scale(0); filter: blur(6px); } to { opacity: 1; transform: scale(1); filter: blur(0); } } #app-shell.app-entering { animation: shellEnter 1s cubic-bezier(0.65, 0, 0.85, 0.05) 1 forwards; } /* On screens too narrow for the dual layout, fall back to single column */ @media (max-width: 960px) { #app-shell.demo-mode { display: none !important; } body.auth-layout .auth-card { width: min(440px, calc(100vw - 16px)); } body.auth-layout .auth-logo-top { display: block; } body.auth-layout .auth-logo-pane { display: none; } body.auth-layout .auth-switch { display: flex; } body.auth-layout .auth-forms-wrap { display: block; } body.auth-layout #signup-form { display: none !important; } body.auth-layout .auth-pane-title { display: none; } } /* ─── Contract card ──────────────────────────────────────── */ .contract-row { display: flex; align-items: center; gap: 12px; padding: 14px 16px; } .contract-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; } .contract-dot--green { background: var(--success); box-shadow: 0 0 0 3px rgba(63, 201, 126, 0.2); } .contract-dot--yellow { background: var(--warning); box-shadow: 0 0 0 3px rgba(240, 160, 75, 0.2); } .contract-dot--red { background: var(--danger); box-shadow: 0 0 0 3px rgba(224, 82, 82, 0.2); } .contract-info { display: flex; flex-direction: column; gap: 3px; } .contract-type { font-size: 13px; color: var(--text); font-weight: 500; } .contract-expires { font-size: 11px; color: var(--text-muted); } .contract-extend-link { display: inline-block; margin-left: auto; font-size: 12px; font-weight: 600; color: var(--danger); text-decoration: none; flex-shrink: 0; } .contract-extend-link:hover { text-decoration: underline; } .contract-cancel-link { margin-left: auto; flex-shrink: 0; font-size: 12px; font-weight: 500; color: var(--text-muted); text-decoration: none; padding: 3px 10px; border: 1px solid var(--border); border-radius: var(--radius); transition: color 0.15s, border-color 0.15s; } .contract-cancel-link:hover { color: var(--danger); border-color: var(--danger); } .contract-cancel-link--danger { color: var(--danger); border-color: var(--danger); } .contract-cancel-link--danger:hover { color: var(--danger); border-color: var(--danger); } /* ─── Wizard (Integrations setup) ─────────────────────────────── */ #wizard-card { position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 5; display: flex; flex-direction: column; overflow: hidden; margin: 0; } #wizard-body { flex: 1; overflow-y: auto; min-height: 0; } .wizard-step-label { font-size: 11px; font-weight: 500; color: var(--text-muted); letter-spacing: 0.04em; white-space: nowrap; } .wizard-search { display: block; width: 100%; box-sizing: border-box; background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-size: 13px; padding: 7px 10px; outline: none; margin-bottom: 8px; } .wizard-search:focus { border-color: var(--accent); } .wizard-search::placeholder { color: var(--text-muted); } .wizard-list { display: flex; flex-direction: column; max-height: 240px; overflow-y: auto; gap: 1px; } .wizard-list::-webkit-scrollbar { width: 4px; } .wizard-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; } .wizard-list-item { display: flex; align-items: flex-start; gap: 10px; padding: 7px 10px; border-radius: var(--radius); cursor: pointer; transition: background 0.1s; user-select: none; } .wizard-list-item:hover { background: var(--bg-hover); } .wizard-list-item input[type="checkbox"] { width: 14px; height: 14px; accent-color: var(--accent); cursor: pointer; flex-shrink: 0; margin: 2px 0 0; } .wizard-list-item-content { display: flex; flex-direction: column; gap: 2px; } .wizard-list-item-name { font-size: 13px; color: var(--text); line-height: 1.3; } .wizard-list-item-desc { font-size: 11px; color: var(--text-muted); line-height: 1.4; } .wizard-footer { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 10px 16px; border-top: 1px solid var(--border); margin-top: 4px; } .wizard-fields { display: flex; flex-direction: column; gap: 12px; } .wizard-signup-hint { font-size: 11px; color: var(--text-muted); margin: 0; } .wizard-signup-hint a { color: var(--text-muted); text-decoration: none; } .wizard-signup-hint a:hover { color: var(--text); } .wizard-review-area { display: flex; flex-direction: column; gap: 10px; } .wizard-review-intro { font-size: 12px; color: var(--text-muted); margin: 0; } .wizard-review-textarea { display: block; width: 100%; min-height: 180px; box-sizing: border-box; background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-size: 12px; font-family: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, monospace; padding: 10px 12px; resize: vertical; outline: none; line-height: 1.5; } .wizard-review-textarea:focus { border-color: var(--accent); } /* ─── Password reset section ───────────────────────────────────── */ @keyframes resetSlideIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } } .reset-pw-wrap { border: 1px solid rgba(0, 245, 255, 0.22); border-left: 3px solid var(--accent); border-radius: var(--radius); background: rgba(0, 245, 255, 0.03); overflow: hidden; animation: resetSlideIn 0.25s cubic-bezier(0.22, 1, 0.36, 1) both; } .reset-pw-idle { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; flex-wrap: wrap; } .reset-pw-hint { font-size: 12px; color: var(--text-muted); letter-spacing: 0.1px; } .reset-pw-btn { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border: 1px solid var(--accent); border-radius: 6px; background: transparent; color: var(--accent); font-family: inherit; font-size: 12px; font-weight: 500; cursor: pointer; white-space: nowrap; letter-spacing: 0.1px; box-shadow: 0 0 8px rgba(0, 245, 255, 0.2); transition: background 0.15s, box-shadow 0.15s, color 0.15s; } .reset-pw-btn:hover { background: rgba(0, 245, 255, 0.08); box-shadow: 0 0 18px rgba(0, 245, 255, 0.45); color: #fff; } .reset-pw-btn:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; } .reset-pw-sent { display: flex; align-items: center; gap: 14px; padding: 13px 14px; animation: resetSlideIn 0.3s cubic-bezier(0.22, 1, 0.36, 1) both; } .reset-pw-sent > svg { flex-shrink: 0; color: var(--success); filter: drop-shadow(0 0 6px rgba(0, 255, 136, 0.55)); } .reset-pw-sent-text { display: flex; flex-direction: column; gap: 3px; } .reset-pw-sent-title { font-size: 13px; font-weight: 600; color: var(--success); text-shadow: 0 0 10px rgba(0, 255, 136, 0.4); } .reset-pw-sent-sub { font-size: 11px; color: var(--text-muted); line-height: 1.45; }