:root { --bg-primary: #0f0f23; --bg-secondary: #1a1a2e; --bg-card: #16213e; --accent: #00d4ff; --accent-secondary: #7b2cbf; --text-primary: #ffffff; --text-secondary: #a0a0b0; --success: #00e676; --warning: #ffab00; --error: #ff5252; --border: #2a2a4a; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: var(--bg-primary); color: var(--text-primary); line-height: 1.6; } .app { display: flex; min-height: 100vh; } /* Sidebar */ .sidebar { width: 260px; background: var(--bg-secondary); border-right: 1px solid var(--border); padding: 24px 16px; display: flex; flex-direction: column; } .logo { font-size: 24px; font-weight: 700; color: var(--accent); margin-bottom: 40px; display: flex; align-items: center; gap: 10px; } .logo span { background: linear-gradient(135deg, var(--accent), var(--accent-secondary)); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .nav-menu { list-style: none; } .nav-item { margin-bottom: 8px; } .nav-link { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-radius: 8px; color: var(--text-secondary); text-decoration: none; transition: all 0.2s ease; } .nav-link:hover, .nav-link.active { background: rgba(0, 212, 255, 0.1); color: var(--accent); } /* Main Content */ .main-content { flex: 1; padding: 32px; overflow-y: auto; } .page-header { margin-bottom: 32px; } .page-title { font-size: 28px; font-weight: 600; margin-bottom: 8px; } .page-subtitle { color: var(--text-secondary); } /* Stats Cards */ .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 24px; margin-bottom: 32px; } .stat-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 16px; padding: 24px; transition: transform 0.2s ease, box-shadow 0.2s ease; } .stat-card:hover { transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0, 212, 255, 0.1); } .stat-label { font-size: 14px; color: var(--text-secondary); margin-bottom: 8px; } .stat-value { font-size: 36px; font-weight: 700; } .stat-value.accent { color: var(--accent); } .stat-value.success { color: var(--success); } .stat-value.warning { color: var(--warning); } .stat-value.error { color: var(--error); } /* Table */ .table-container { background: var(--bg-card); border: 1px solid var(--border); border-radius: 16px; overflow: hidden; } .table-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid var(--border); } .table-title { font-size: 18px; font-weight: 600; } table { width: 100%; border-collapse: collapse; } th, td { padding: 16px 24px; text-align: left; } th { background: rgba(0, 0, 0, 0.2); color: var(--text-secondary); font-weight: 500; font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px; } tr { border-bottom: 1px solid var(--border); transition: background 0.2s ease; } tr:hover { background: rgba(0, 212, 255, 0.05); } /* Status Badge */ .status-badge { display: inline-block; padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; text-transform: uppercase; } .status-NEW { background: rgba(0, 212, 255, 0.2); color: var(--accent); } .status-PENDING_FIX { background: rgba(255, 171, 0, 0.2); color: var(--warning); } .status-FIXING { background: rgba(123, 44, 191, 0.2); color: var(--accent-secondary); } .status-FIXED { background: rgba(0, 230, 118, 0.2); color: var(--success); } .status-VERIFIED { background: rgba(0, 230, 118, 0.3); color: var(--success); } .status-DEPLOYED { background: rgba(0, 230, 118, 0.4); color: var(--success); } .status-FIX_FAILED { background: rgba(255, 82, 82, 0.2); color: var(--error); } .status-CANNOT_REPRODUCE { background: rgba(160, 160, 176, 0.2); color: var(--text-secondary); } /* Filters */ .filters { display: flex; gap: 16px; margin-bottom: 24px; } .filter-select { background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 10px 16px; color: var(--text-primary); font-size: 14px; cursor: pointer; } .filter-select:focus { outline: none; border-color: var(--accent); } /* Project Tabs (breadcrumb navigation) */ .project-tabs { display: flex; align-items: center; gap: 4px; margin-bottom: 16px; padding: 6px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; overflow-x: auto; } .project-tab { position: relative; background: none; border: none; padding: 10px 20px; color: var(--text-secondary); font-size: 14px; font-weight: 500; cursor: pointer; border-radius: 8px; white-space: nowrap; transition: all 0.2s ease; } .project-tab:hover { color: var(--text-primary); background: rgba(255, 255, 255, 0.05); } .project-tab.active { background: var(--accent); color: var(--bg-primary); font-weight: 600; } /* Status Tabs */ .status-tabs { display: flex; align-items: center; gap: 6px; margin-bottom: 20px; overflow-x: auto; padding-bottom: 4px; } .status-tab { background: none; border: 1px solid var(--border); padding: 6px 14px; color: var(--text-secondary); font-size: 12px; font-weight: 500; cursor: pointer; border-radius: 20px; white-space: nowrap; transition: all 0.2s ease; text-transform: uppercase; letter-spacing: 0.3px; } .status-tab:hover { border-color: var(--text-secondary); color: var(--text-primary); } .status-tab.active { border-color: var(--accent); background: rgba(0, 212, 255, 0.15); color: var(--accent); } .status-tab.active.status-color-NEW { border-color: var(--accent); background: rgba(0, 212, 255, 0.15); color: var(--accent); } .status-tab.active.status-color-FIXED, .status-tab.active.status-color-VERIFIED, .status-tab.active.status-color-DEPLOYED { border-color: var(--success); background: rgba(0, 230, 118, 0.15); color: var(--success); } .status-tab.active.status-color-PENDING_FIX { border-color: var(--warning); background: rgba(255, 171, 0, 0.15); color: var(--warning); } .status-tab.active.status-color-FIX_FAILED { border-color: var(--error); background: rgba(255, 82, 82, 0.15); color: var(--error); } .status-tab.active.status-color-FIXING, .status-tab.active.status-color-VERIFYING { border-color: var(--accent-secondary); background: rgba(123, 44, 191, 0.15); color: #b388ff; } .status-tab.active.status-color-CANNOT_REPRODUCE { border-color: var(--text-secondary); background: rgba(160, 160, 176, 0.15); color: var(--text-secondary); } /* Project link in table */ .project-link { background: none; border: none; color: var(--text-primary); font-size: inherit; font-family: inherit; cursor: pointer; padding: 2px 8px; border-radius: 4px; transition: all 0.2s ease; } .project-link:hover { background: rgba(0, 212, 255, 0.1); color: var(--accent); } /* Empty state */ .empty-state { display: flex; justify-content: center; align-items: center; height: 200px; color: var(--text-secondary); font-size: 15px; gap: 4px; } /* Bug Detail */ .detail-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 16px; padding: 24px; margin-bottom: 24px; } .detail-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 24px; } .detail-title { font-size: 20px; font-weight: 600; margin-bottom: 8px; } .detail-meta { display: flex; gap: 16px; color: var(--text-secondary); font-size: 14px; } .stack-trace { background: var(--bg-primary); border-radius: 8px; padding: 16px; font-family: 'Fira Code', monospace; font-size: 13px; overflow-x: auto; white-space: pre-wrap; color: var(--error); } .back-link { display: inline-flex; align-items: center; gap: 8px; color: var(--accent); text-decoration: none; margin-bottom: 24px; } .back-link:hover { text-decoration: underline; } /* Pagination */ .pagination { display: flex; justify-content: center; gap: 8px; padding: 20px; } .pagination button { background: var(--bg-secondary); border: 1px solid var(--border); color: var(--text-primary); padding: 8px 16px; border-radius: 6px; cursor: pointer; transition: all 0.2s ease; } .pagination button:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); } .pagination button:disabled { opacity: 0.5; cursor: not-allowed; } /* Loading */ .loading { display: flex; justify-content: center; align-items: center; height: 200px; color: var(--text-secondary); } .spinner { width: 40px; height: 40px; border: 3px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } }