PRobe / frontend /style.css
Thakur, Mahipal
UI Integration
44bd7bd
/* ═══════════════════════════════════════════════════════════════
PRobe Dashboard β€” stylesheet
Design tokens: dark IDE theme, accent #4f9eff
═══════════════════════════════════════════════════════════════ */
/* ── Reset & base ─────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg-0: #0d1117; /* deepest background */
--bg-1: #161b22; /* panel background */
--bg-2: #21262d; /* card / input background */
--bg-3: #30363d; /* hover / border */
--text-main: #e6edf3;
--text-dim: #8b949e;
--accent: #4f9eff;
--green: #3fb950;
--red: #f85149;
--yellow: #d29922;
--orange: #db6d28;
--purple: #a371f7;
--radius: 8px;
--font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
--font-ui: 'Inter', system-ui, sans-serif;
--topbar-h: 52px;
}
html, body {
height: 100%;
background: var(--bg-0);
color: var(--text-main);
font-family: var(--font-ui);
font-size: 14px;
line-height: 1.5;
}
/* ── Top bar ──────────────────────────────────────────────── */
.topbar {
position: fixed;
top: 0; left: 0; right: 0;
height: var(--topbar-h);
background: var(--bg-1);
border-bottom: 1px solid var(--bg-3);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 1.25rem;
z-index: 100;
}
.topbar-left { display: flex; align-items: center; gap: 1rem; }
.logo { font-size: 1.15rem; font-weight: 700; color: var(--accent); }
.tagline { color: var(--text-dim); font-size: 0.8rem; }
.topbar-right { display: flex; align-items: center; gap: 0.75rem; }
.badge {
font-size: 0.78rem;
padding: 3px 10px;
border-radius: 12px;
background: var(--bg-2);
border: 1px solid var(--bg-3);
white-space: nowrap;
}
.badge.connected { color: var(--green); border-color: var(--green); }
.badge.disconnected { color: var(--text-dim); }
/* ── Buttons ──────────────────────────────────────────────── */
.btn {
padding: 6px 16px;
border-radius: var(--radius);
border: 1px solid transparent;
font-size: 0.82rem;
font-weight: 600;
cursor: pointer;
transition: opacity 0.15s, background 0.15s;
}
.btn:disabled { opacity: 0.35; cursor: not-allowed; }
.btn-primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn-secondary{ background: var(--bg-2); color: var(--text-main); border-color: var(--bg-3); }
.btn-action { width: 100%; margin-bottom: 0.4rem; background: var(--bg-2); color: var(--text-main); border-color: var(--bg-3); }
.btn-info { border-color: var(--accent); color: var(--accent); }
.btn-warn { border-color: var(--yellow); color: var(--yellow); }
.btn-success { border-color: var(--green); color: var(--green); }
.btn-danger { border-color: var(--red); color: var(--red); background: rgba(248,81,73,0.1); }
.btn-escalate { border-color: var(--purple); color: var(--purple); background: rgba(163,113,247,0.1); }
.btn:not(:disabled):hover { opacity: 0.82; }
/* ── Main three-column layout ─────────────────────────────── */
.layout {
display: grid;
grid-template-columns: 1fr 310px 310px;
grid-template-rows: calc(100vh - var(--topbar-h));
gap: 0;
margin-top: var(--topbar-h);
overflow: hidden;
}
/* ── Generic panel ────────────────────────────────────────── */
.panel {
background: var(--bg-1);
border-right: 1px solid var(--bg-3);
overflow-y: auto;
padding: 1rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.panel:last-child { border-right: none; }
.panel-header {
font-weight: 700;
font-size: 0.85rem;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 0.06em;
display: flex;
align-items: center;
gap: 0.75rem;
flex-wrap: wrap;
}
.section-title {
font-size: 0.78rem;
font-weight: 600;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 0.05em;
}
/* ── Task metadata ────────────────────────────────────────── */
#task-label { color: var(--accent); font-size: 0.9rem; }
.difficulty-badge {
font-size: 0.72rem;
padding: 2px 8px;
border-radius: 10px;
background: var(--bg-2);
border: 1px solid var(--bg-3);
text-transform: capitalize;
}
.difficulty-badge.ultra-easy { color: var(--green); border-color: var(--green); }
.difficulty-badge.easy { color: var(--accent); border-color: var(--accent); }
.difficulty-badge.medium { color: var(--yellow); border-color: var(--yellow); }
.difficulty-badge.hard { color: var(--orange); border-color: var(--orange); }
.difficulty-badge.adversarial{ color: var(--red); border-color: var(--red); }
.steps-counter { margin-left: auto; font-size: 0.8rem; color: var(--text-dim); }
.task-desc {
font-size: 0.82rem;
color: var(--text-dim);
line-height: 1.6;
background: var(--bg-2);
border: 1px solid var(--bg-3);
border-radius: var(--radius);
padding: 0.6rem 0.8rem;
}
.adversarial-hint {
font-size: 0.8rem;
background: rgba(163,113,247,0.1);
border: 1px solid var(--purple);
border-radius: var(--radius);
padding: 0.5rem 0.75rem;
color: var(--purple);
}
/* ── Code viewer ──────────────────────────────────────────── */
.code-wrapper {
flex: 1;
overflow: auto;
border: 1px solid var(--bg-3);
border-radius: var(--radius);
background: var(--bg-0);
}
.code-block {
font-family: var(--font-mono);
font-size: 0.78rem;
line-height: 1.65;
padding: 0.75rem 1rem;
white-space: pre;
counter-reset: line-counter;
}
.code-line { display: block; }
.code-line-num {
user-select: none;
display: inline-block;
width: 2.8em;
color: var(--text-dim);
text-align: right;
margin-right: 1em;
font-size: 0.72rem;
}
/* Highlighted lines (comment target or scanner finding) */
.code-line.hl-comment { background: rgba(79,158,255,0.12); border-left: 3px solid var(--accent); }
.code-line.hl-issue { background: rgba(248,81,73,0.10); border-left: 3px solid var(--red); }
.code-line.hl-scanner { background: rgba(210,153,34,0.10); border-left: 3px solid var(--yellow); }
.code-line.hl-context { background: rgba(63,185,80,0.08); border-left: 3px solid var(--green); }
.placeholder-text { color: var(--text-dim); font-style: italic; }
/* ── Hints ────────────────────────────────────────────────── */
.hints-list {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.hint-item {
font-size: 0.8rem;
background: rgba(63,185,80,0.08);
border: 1px solid var(--green);
border-radius: var(--radius);
padding: 0.5rem 0.75rem;
color: var(--text-main);
white-space: pre-wrap;
}
/* ── Action cards ─────────────────────────────────────────── */
.action-card {
background: var(--bg-2);
border: 1px solid var(--bg-3);
border-radius: var(--radius);
padding: 0.8rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.action-title {
font-size: 0.8rem;
font-weight: 700;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 0.25rem;
}
.form-row {
display: flex;
flex-direction: column;
gap: 3px;
}
.form-row label { font-size: 0.75rem; color: var(--text-dim); }
.form-row input,
.form-row select,
.form-row textarea {
background: var(--bg-0);
border: 1px solid var(--bg-3);
border-radius: 5px;
color: var(--text-main);
font-family: var(--font-ui);
font-size: 0.82rem;
padding: 5px 8px;
resize: vertical;
}
.form-row input:focus,
.form-row select:focus,
.form-row textarea:focus {
outline: none;
border-color: var(--accent);
}
.quick-actions {
background: var(--bg-2);
border: 1px solid var(--bg-3);
border-radius: var(--radius);
padding: 0.8rem;
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.separator { height: 1px; background: var(--bg-3); margin: 0.3rem 0; }
/* ── Reward ring ──────────────────────────────────────────── */
.reward-ring-wrap {
position: relative;
width: 120px;
margin: 0 auto;
}
.reward-ring { width: 120px; height: 120px; transform: rotate(-90deg); }
.ring-bg { fill: none; stroke: var(--bg-2); stroke-width: 10; }
.ring-track {
fill: none;
stroke: var(--accent);
stroke-width: 10;
stroke-linecap: round;
stroke-dasharray: 314; /* 2Ο€ Γ— r=50 */
stroke-dashoffset: 314;
transition: stroke-dashoffset 0.5s ease, stroke 0.5s ease;
}
.ring-label {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 1.1rem;
}
.ring-label small { font-size: 0.65rem; color: var(--text-dim); font-weight: 400; }
/* ── Component bar chart ──────────────────────────────────── */
.component-bars { display: flex; flex-direction: column; gap: 6px; }
.bar-row { display: flex; align-items: center; gap: 6px; }
.bar-label { font-size: 0.72rem; color: var(--text-dim); width: 90px; flex-shrink: 0; }
.bar-track { flex: 1; height: 7px; background: var(--bg-2); border-radius: 4px; overflow: hidden; }
.bar-fill { height: 100%; border-radius: 4px; width: 0; transition: width 0.4s ease; }
.bar-fill.positive { background: var(--green); }
.bar-fill.negative { background: var(--red); }
.bar-fill.neutral { background: var(--yellow); }
.bar-val { font-size: 0.72rem; width: 36px; text-align: right; color: var(--text-dim); }
/* ── Issues progress ──────────────────────────────────────── */
.issues-progress { display: flex; align-items: center; gap: 8px; }
.issues-bar-wrap {
flex: 1; height: 8px;
background: var(--bg-2);
border-radius: 4px;
overflow: hidden;
}
.issues-bar-fill {
height: 100%;
background: var(--accent);
border-radius: 4px;
width: 0;
transition: width 0.4s ease;
}
/* ── History feed ─────────────────────────────────────────── */
.history-feed {
display: flex;
flex-direction: column;
gap: 0.4rem;
max-height: 320px;
overflow-y: auto;
}
.history-empty { color: var(--text-dim); font-size: 0.8rem; font-style: italic; }
.history-item {
background: var(--bg-2);
border: 1px solid var(--bg-3);
border-radius: 6px;
padding: 0.45rem 0.65rem;
font-size: 0.78rem;
border-left: 3px solid var(--bg-3);
}
.history-item.positive { border-left-color: var(--green); }
.history-item.negative { border-left-color: var(--red); }
.history-item.neutral { border-left-color: var(--yellow); }
.history-item .h-action { font-weight: 700; color: var(--accent); }
.history-item .h-reward { font-weight: 700; }
.history-item .h-reward.pos { color: var(--green); }
.history-item .h-reward.neg { color: var(--red); }
.history-item .h-explain { color: var(--text-dim); margin-top: 2px; line-height: 1.4; }
/* ── Episode-end modal ────────────────────────────────────── */
.modal-overlay {
position: fixed; inset: 0;
background: rgba(0,0,0,0.7);
display: flex; align-items: center; justify-content: center;
z-index: 200;
}
.modal {
background: var(--bg-1);
border: 1px solid var(--bg-3);
border-radius: 12px;
padding: 2rem;
max-width: 440px;
width: 90%;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
}
.modal-icon { font-size: 3rem; }
.modal h2 { font-size: 1.3rem; }
.modal p { color: var(--text-dim); font-size: 0.88rem; line-height: 1.6; }
.modal-stats {
width: 100%;
background: var(--bg-2);
border-radius: var(--radius);
padding: 0.75rem 1rem;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.4rem 1rem;
text-align: left;
font-size: 0.82rem;
}
.modal-stats .stat-label { color: var(--text-dim); }
.modal-stats .stat-value { font-weight: 700; }
/* ── Scrollbar styling ────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--bg-1); }
::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: 3px; }