buglens / buglens-ui /BugLens.html
Claude
Serve custom frontend on gradio.Server with mock analyze pipeline
85ebe4a unverified
Raw
History Blame Contribute Delete
20 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BugLens</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
<style>
/* ───────────────────── tokens ───────────────────── */
.bl-app[data-theme="dark"]{
--bg:#0b0c0f; --surface:#15171d; --surface-2:#1c1f27; --surface-3:#23262f;
--border:#2a2e38; --border-soft:#1f222a;
--text:#edeff3; --text-dim:#9aa1ae; --text-faint:#646b78;
--shadow:0 18px 48px rgba(0,0,0,.45);
}
.bl-app[data-theme="light"]{
--bg:#eef0f4; --surface:#ffffff; --surface-2:#f6f7f9; --surface-3:#eef0f4;
--border:#e1e4ea; --border-soft:#eceef3;
--text:#171c25; --text-dim:#586072; --text-faint:#929aa7;
--shadow:0 14px 40px rgba(20,30,60,.12);
}
.bl-app{
--sev-critical:#f5544f; --sev-high:#ff9233; --sev-medium:#e0b020; --sev-low:#4c8dff;
--r:14px;
--pad:20px; --gap:16px;
}
.bl-app[data-density="compact"]{ --pad:15px; --gap:11px; }
.bl-app[data-density="comfy"]{ --pad:26px; --gap:22px; }
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background:var(--bg-fallback,#0b0c0f);}
.bl-app{
font-family:'Space Grotesk',system-ui,sans-serif;
background:var(--bg); color:var(--text);
min-height:100vh; display:flex; flex-direction:column;
-webkit-font-smoothing:antialiased;
}
.bl-app ::selection{background:color-mix(in oklab,var(--accent) 35%,transparent)}
/* ───────────────────── header ───────────────────── */
.bl-top{
flex:0 0 auto; height:58px; display:flex; align-items:center; gap:22px;
padding:0 24px; border-bottom:1px solid var(--border);
background:color-mix(in oklab,var(--surface) 70%,transparent);
backdrop-filter:blur(12px); position:sticky; top:0; z-index:40;
}
.bl-top-brand{background:none;border:0;padding:0;cursor:pointer;display:flex}
.bl-word{display:flex;align-items:center;gap:9px;font-size:18px;font-weight:500;color:var(--text);letter-spacing:-.01em}
.bl-word b{font-weight:700}
.bl-top-tag{font-size:12.5px;color:var(--text-dim);font-family:'JetBrains Mono',monospace;letter-spacing:-.01em}
.bl-top-right{margin-left:auto;display:flex;align-items:center;gap:12px}
.bl-model-chip{display:inline-flex;align-items:center;gap:7px;font-family:'JetBrains Mono',monospace;
font-size:11px;color:var(--text-dim);border:1px solid var(--border);border-radius:999px;padding:6px 11px;background:var(--surface)}
.bl-live{width:7px;height:7px;border-radius:50%;background:#37c99e;box-shadow:0 0 0 3px color-mix(in oklab,#37c99e 22%,transparent)}
.bl-stage-wrap{flex:1;overflow-y:auto;min-height:0}
/* ───────────────────── idle / hero ───────────────────── */
.bl-idle{max-width:1180px;margin:0 auto;padding:54px 24px 80px}
.bl-hero{text-align:center;max-width:680px;margin:0 auto 56px}
.bl-hero-lens{display:inline-flex;padding:18px;border-radius:50%;
background:radial-gradient(circle at 50% 40%,color-mix(in oklab,var(--accent) 18%,transparent),transparent 70%);
margin-bottom:22px}
.bl-hero-h{font-size:40px;line-height:1.08;font-weight:600;letter-spacing:-.025em;margin:0 0 16px;text-wrap:balance}
.bl-hero-sub{font-size:16px;line-height:1.55;color:var(--text-dim);margin:0 auto 34px;max-width:560px;text-wrap:pretty}
.bl-hero-sub b{color:var(--text);font-weight:600}
.bl-drop{
border:1.5px dashed var(--border); border-radius:18px; background:var(--surface);
padding:34px; cursor:pointer; transition:.18s; max-width:460px; margin:0 auto;
}
.bl-drop:hover{border-color:var(--accent);background:color-mix(in oklab,var(--accent) 5%,var(--surface));transform:translateY(-1px)}
.bl-drop-ic{font-size:26px;color:var(--accent);margin-bottom:8px}
.bl-drop-t{font-size:16px;font-weight:600}
.bl-drop-s{font-size:12px;color:var(--text-faint);margin-top:5px;font-family:'JetBrains Mono',monospace}
/* ───────────────────── gallery ───────────────────── */
.bl-gallery-h{display:flex;align-items:baseline;justify-content:space-between;
font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint);
padding-bottom:14px;margin-bottom:20px;border-bottom:1px solid var(--border)}
.bl-gallery-hint{font-family:'JetBrains Mono',monospace;font-weight:500;letter-spacing:0;text-transform:none}
.bl-gallery-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:18px}
.bl-ex{text-align:left;background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
padding:0;overflow:hidden;cursor:pointer;transition:.18s;display:flex;flex-direction:column}
.bl-ex:hover{border-color:color-mix(in oklab,var(--accent) 55%,var(--border));transform:translateY(-2px);box-shadow:var(--shadow)}
.bl-ex-thumb{position:relative;aspect-ratio:16/9;overflow:hidden;border-bottom:1px solid var(--border)}
.bl-ex-thumb .bl-sev{position:absolute;top:10px;right:10px;z-index:3}
.bl-ex-scrim{position:absolute;inset:0;z-index:2;
background:linear-gradient(to top,color-mix(in oklab,var(--surface) 30%,transparent),transparent 38%);pointer-events:none}
.bl-ex-meta{padding:14px 16px 16px}
.bl-ex-app{font-family:'JetBrains Mono',monospace;font-size:10.5px;color:var(--accent);font-weight:600;text-transform:uppercase;letter-spacing:.06em}
.bl-ex-title{font-size:15px;font-weight:600;margin:5px 0 4px;letter-spacing:-.01em}
.bl-ex-blurb{font-size:12.5px;color:var(--text-dim);line-height:1.45}
/* ───────────────────── loading ───────────────────── */
.bl-loading{max-width:980px;margin:0 auto;padding:60px 24px;display:grid;
grid-template-columns:1.3fr 1fr;gap:36px;align-items:center;min-height:60vh}
.bl-loading-shot{position:relative;aspect-ratio:16/10;border-radius:var(--r);overflow:hidden;
border:1px solid var(--border);box-shadow:var(--shadow)}
.bl-scan{position:absolute;left:0;right:0;height:42%;z-index:5;pointer-events:none;
background:linear-gradient(to bottom,transparent,color-mix(in oklab,var(--accent) 26%,transparent),transparent);
animation:scan 1.8s ease-in-out infinite}
@keyframes scan{0%{top:-42%}100%{top:100%}}
.bl-loading-side{}
.bl-load-file{font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--text-faint);margin-bottom:22px}
.bl-stages{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.bl-stages li{display:flex;gap:13px;align-items:center;padding:11px 0;opacity:.4;transition:.3s}
.bl-stages li[data-state="active"]{opacity:1}
.bl-stages li[data-state="done"]{opacity:.85}
.bl-stage-dot{width:24px;height:24px;flex:0 0 24px;border-radius:50%;border:1.5px solid var(--border);
display:flex;align-items:center;justify-content:center;font-size:12px;color:#37c99e}
.bl-stages li[data-state="active"] .bl-stage-dot{border-color:var(--accent)}
.bl-stages li[data-state="done"] .bl-stage-dot{border-color:#37c99e;background:color-mix(in oklab,#37c99e 14%,transparent)}
.bl-stage-l{font-size:14px;font-weight:600}
.bl-stage-sub{font-size:11px;color:var(--text-faint);font-family:'JetBrains Mono',monospace;margin-top:2px}
.bl-mini-spin,.bl-stage-dot .bl-mini-spin{width:13px;height:13px;border-radius:50%;
border:2px solid color-mix(in oklab,var(--accent) 30%,transparent);border-top-color:var(--accent);
animation:mkspin .8s linear infinite}
@keyframes mkspin{to{transform:rotate(360deg)}}
/* ───────────────────── results ───────────────────── */
.bl-results{max-width:1320px;margin:0 auto;padding:28px 24px 60px;
display:grid;grid-template-columns:360px 1fr;gap:28px;align-items:start}
.bl-lens{position:sticky;top:86px;display:flex;flex-direction:column;gap:14px}
.bl-lens-shot{position:relative;aspect-ratio:16/11;border-radius:var(--r);overflow:hidden;
border:1px solid var(--border);box-shadow:var(--shadow)}
.bl-lens-file{font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--text-faint);
margin-top:-4px;text-align:center}
.bl-vision{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:16px 17px}
.bl-vision-h{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;color:var(--text);margin-bottom:12px}
.bl-vision-ic{color:var(--accent);font-size:14px}
.bl-vision ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
.bl-vision li{font-size:12.5px;line-height:1.5;color:var(--text-dim);padding-left:15px;position:relative}
.bl-vision li::before{content:"";position:absolute;left:0;top:7px;width:5px;height:5px;border-radius:50%;background:var(--accent);opacity:.7}
/* cards container */
.bl-output{min-width:0}
.bl-cards{display:grid;gap:var(--gap)}
.bl-cards-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
.bl-cards-column{grid-template-columns:1fr}
.bl-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
overflow:hidden;display:flex;flex-direction:column;--card-accent:var(--text-dim)}
.bl-card-h{display:flex;align-items:flex-start;gap:12px;padding:var(--pad);padding-bottom:13px;
border-bottom:1px solid var(--border-soft)}
.bl-card-ic{width:34px;height:34px;flex:0 0 34px;border-radius:9px;display:flex;align-items:center;justify-content:center;
font-size:16px;background:color-mix(in oklab,var(--card-accent) 14%,transparent);color:var(--card-accent)}
.bl-card-ht{flex:1;min-width:0}
.bl-kicker{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text-faint);
text-transform:uppercase;letter-spacing:.05em;margin-bottom:3px}
.bl-card-h h3{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em}
.bl-card-b{padding:var(--pad);display:flex;flex-direction:column;gap:14px}
/* card kind accents */
.bl-card[data-kind="report"]{--card-accent:var(--accent)}
.bl-card[data-kind="tests"]{--card-accent:#37c99e}
.bl-card[data-kind="edges"]{--card-accent:#4c8dff}
.bl-card[data-kind="missing"]{--card-accent:var(--accent);
border-color:color-mix(in oklab,var(--accent) 45%,var(--border));
background:linear-gradient(180deg,color-mix(in oklab,var(--accent) 7%,var(--surface)),var(--surface) 120px);
box-shadow:0 0 0 1px color-mix(in oklab,var(--accent) 20%,transparent),var(--shadow)}
.bl-copy{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text-dim);
background:var(--surface-2);border:1px solid var(--border);border-radius:7px;padding:6px 10px;cursor:pointer;transition:.15s;white-space:nowrap}
.bl-copy:hover{color:var(--text);border-color:var(--text-faint)}
.bl-copy.is-done{color:#37c99e;border-color:#37c99e}
.bl-progress{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--accent);white-space:nowrap;
border:1px solid color-mix(in oklab,var(--accent) 40%,transparent);border-radius:7px;padding:6px 10px}
/* ── report card internals ── */
.bl-rep-top{display:flex;align-items:center;gap:11px;flex-wrap:wrap}
.bl-rep-why{font-size:12px;color:var(--text-dim);line-height:1.4}
.bl-summary{margin:0;font-size:13.5px;line-height:1.6;color:var(--text-dim)}
.bl-sublabel{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint)}
.bl-steps{margin:0;padding-left:0;list-style:none;counter-reset:s;display:flex;flex-direction:column;gap:8px}
.bl-steps li{counter-increment:s;position:relative;padding-left:28px;font-size:13px;line-height:1.45;color:var(--text)}
.bl-steps li::before{content:counter(s);position:absolute;left:0;top:0;width:19px;height:19px;border-radius:6px;
background:var(--surface-3);color:var(--text-dim);font-family:'JetBrains Mono',monospace;font-size:11px;
display:flex;align-items:center;justify-content:center;font-weight:600}
.bl-ea{display:grid;grid-template-columns:1fr 1fr;gap:11px}
.bl-ea-col{border:1px solid var(--border-soft);border-radius:10px;padding:12px;background:var(--surface-2)}
.bl-ea-lbl{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;margin-bottom:7px}
.bl-ea-exp .bl-ea-lbl{color:#37c99e}
.bl-ea-act .bl-ea-lbl{color:var(--sev-high)}
.bl-ea-col p{margin:0;font-size:12.5px;line-height:1.5;color:var(--text-dim)}
.bl-env{display:flex;flex-direction:column;border:1px solid var(--border-soft);border-radius:10px;overflow:hidden}
.bl-env-row{display:flex;justify-content:space-between;gap:14px;padding:9px 12px;font-size:12px;border-bottom:1px solid var(--border-soft)}
.bl-env-row:last-child{border-bottom:0}
.bl-env-k{color:var(--text-dim);font-weight:500}
.bl-env-v{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text);text-align:right}
.bl-env-row[data-known="0"] .bl-env-v{color:var(--sev-high)}
/* ── missing info card ── */
.bl-honest{margin:0;font-size:13px;line-height:1.55;color:var(--text-dim)}
.bl-honest b{color:var(--accent);font-weight:700}
.bl-missing{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.bl-missing li{display:flex;gap:12px;align-items:flex-start;padding:12px 13px;border-radius:11px;
border:1px solid var(--border-soft);background:var(--surface-2);transition:.18s}
.bl-missing li.is-on{opacity:.62;background:transparent}
.bl-check{flex:0 0 20px;width:20px;height:20px;margin-top:1px;border-radius:6px;cursor:pointer;
border:1.5px solid var(--border);background:var(--surface);color:#fff;font-size:12px;font-weight:700;
display:flex;align-items:center;justify-content:center;transition:.15s}
.bl-missing li.is-on .bl-check{background:var(--accent);border-color:var(--accent)}
.bl-missing-q{font-size:13px;font-weight:600;line-height:1.4}
.bl-missing li.is-on .bl-missing-q{text-decoration:line-through;text-decoration-color:var(--text-faint)}
.bl-missing-w{font-size:12px;color:var(--text-dim);line-height:1.5;margin-top:4px}
/* ── tests card ── */
.bl-tests{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
.bl-test{border:1px solid var(--border-soft);border-radius:11px;padding:13px;background:var(--surface-2)}
.bl-test-h{display:flex;align-items:center;gap:9px;margin-bottom:10px}
.bl-test-id{font-family:'JetBrains Mono',monospace;font-size:10.5px;font-weight:600;color:#37c99e;
border:1px solid color-mix(in oklab,#37c99e 35%,transparent);border-radius:5px;padding:2px 6px}
.bl-test-title{font-size:13px;font-weight:600;line-height:1.3}
.bl-gwt{margin:0;display:flex;flex-direction:column;gap:5px}
.bl-gwt>div{display:flex;gap:9px;font-size:12.5px;line-height:1.45}
.bl-gwt dt{flex:0 0 42px;font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:600;color:var(--text-faint);text-transform:uppercase}
.bl-gwt dd{margin:0;color:var(--text-dim)}
/* ── edges card ── */
.bl-edges{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:0}
.bl-edges li{display:flex;gap:12px;align-items:flex-start;padding:12px 0;border-bottom:1px solid var(--border-soft)}
.bl-edges li:first-child{padding-top:0}
.bl-edges li:last-child{border-bottom:0;padding-bottom:0}
.bl-edge-marker{flex:0 0 7px;width:7px;height:7px;margin-top:6px;border-radius:2px;
background:#4c8dff;transform:rotate(45deg)}
.bl-edge-t{font-size:13px;font-weight:600}
.bl-edge-d{font-size:12.5px;color:var(--text-dim);line-height:1.5;margin-top:3px}
/* ── tabs layout ── */
.bl-tabs{display:flex;gap:4px;background:var(--surface);border:1px solid var(--border);border-radius:11px;padding:4px;margin-bottom:var(--gap)}
.bl-tabs button{flex:1;border:0;background:none;color:var(--text-dim);font-family:inherit;font-size:13px;font-weight:600;
padding:9px;border-radius:8px;cursor:pointer;transition:.15s}
.bl-tabs button:hover{color:var(--text)}
.bl-tabs button.is-on{background:color-mix(in oklab,var(--accent) 16%,transparent);color:var(--accent)}
.bl-tabpane .bl-card{animation:fade .25s ease}
@keyframes fade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
/* ── export bar ── */
.bl-export{display:flex;align-items:center;gap:10px;margin-top:var(--gap);padding:16px 18px;
background:var(--surface);border:1px solid var(--border);border-radius:var(--r);flex-wrap:wrap}
.bl-export-l{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.07em;color:var(--text-faint);margin-right:4px}
/* ── buttons ── */
.bl-btn{font-family:inherit;font-size:13px;font-weight:600;border-radius:9px;padding:9px 15px;cursor:pointer;
display:inline-flex;align-items:center;gap:8px;transition:.15s;border:1px solid transparent}
.bl-btn-ic{font-size:13px;opacity:.85}
.bl-btn-primary{background:var(--accent);color:#1a1205;border-color:var(--accent)}
.bl-btn-primary:hover{filter:brightness(1.08)}
.bl-btn-ghost{background:var(--surface-2);color:var(--text);border-color:var(--border)}
.bl-btn-ghost:hover{border-color:var(--text-faint);background:var(--surface-3)}
.bl-btn-full{width:100%;justify-content:center}
/* ── badges ── */
.bl-sev{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:600;
padding:4px 9px;border-radius:999px;color:var(--sc);background:color-mix(in oklab,var(--sc) 15%,transparent);
border:1px solid color-mix(in oklab,var(--sc) 35%,transparent)}
.bl-sev i{width:6px;height:6px;border-radius:50%;background:var(--sc)}
/* ── toasts ── */
.bl-toasts{position:fixed;bottom:22px;left:50%;transform:translateX(-50%);z-index:60;display:flex;flex-direction:column;gap:8px;align-items:center}
.bl-toast{background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:10px;
padding:11px 17px;font-size:13px;font-weight:500;box-shadow:var(--shadow);animation:toastin .25s ease}
@keyframes toastin{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
/* responsive */
@media (max-width:980px){
.bl-results{grid-template-columns:1fr}
.bl-lens{position:static}
.bl-cards-grid{grid-template-columns:1fr}
.bl-gallery-grid{grid-template-columns:1fr}
.bl-loading{grid-template-columns:1fr}
.bl-hero-h{font-size:32px}
}
</style>
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
<script type="text/babel" src="/static/tweaks-panel.jsx"></script>
<script type="text/babel" src="/static/buglens-data.jsx"></script>
<script type="text/babel" src="/static/buglens-screens.jsx"></script>
<script type="text/babel" src="/static/buglens-components.jsx"></script>
<script type="text/babel" src="/static/buglens-cards.jsx"></script>
<script type="text/babel" src="/static/buglens-app.jsx"></script>
<script>
// inject the mock-screen styles once React/Babel have defined MOCK_STYLE
window.addEventListener('DOMContentLoaded', () => {
const tryInject = () => {
if (window.MOCK_STYLE && !document.getElementById('mk-style')) {
const s = document.createElement('style');
s.id = 'mk-style';
s.textContent = window.MOCK_STYLE;
document.head.appendChild(s);
} else if (!window.MOCK_STYLE) {
setTimeout(tryInject, 60);
}
};
tryInject();
});
</script>
</body>
</html>