Skip to content

Commit fba8acb

Browse files
committed
feat: dramatic hero animations, static demo default, fast-forward fetch
- Animated gradient sweep, floating orbs, pulsing grid, shimmer title - Badges fade-slide-up with stagger, hover glow effects - DEMO_METRICS constant loads pallets/flask data on page open - Demo banner with dismiss link, auto-removed on live analysis - Progress bar fast-forward: aggressive percentage + 0.15s transition - Both index.html (v0.1.0) and v2-demo.html (v0.2.0) updated
1 parent af9611c commit fba8acb

2 files changed

Lines changed: 306 additions & 16 deletions

File tree

docs/index.html

Lines changed: 149 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,83 @@
3030
background: linear-gradient(135deg, #0d1117 0%, #161b22 40%, #1a2332 100%);
3131
border-bottom:1px solid var(--border); position:relative; overflow:hidden;
3232
}
33+
/* Animated gradient sweep */
3334
.hero::before {
3435
content:''; position:absolute; top:-50%; left:-50%; width:200%; height:200%;
35-
background: radial-gradient(ellipse at 30% 50%, rgba(88,166,255,0.06) 0%, transparent 60%),
36-
radial-gradient(ellipse at 70% 30%, rgba(63,185,80,0.04) 0%, transparent 50%);
37-
pointer-events:none;
36+
background: radial-gradient(ellipse at 30% 50%, rgba(88,166,255,0.12) 0%, transparent 50%),
37+
radial-gradient(ellipse at 70% 30%, rgba(63,185,80,0.10) 0%, transparent 40%),
38+
radial-gradient(ellipse at 50% 80%, rgba(163,113,247,0.08) 0%, transparent 50%);
39+
pointer-events:none; animation: heroSweep 8s ease-in-out infinite alternate;
3840
}
41+
/* Floating orb 1 */
42+
.hero::after {
43+
content:''; position:absolute; width:300px; height:300px; border-radius:50%;
44+
background: radial-gradient(circle, rgba(88,166,255,0.15) 0%, transparent 70%);
45+
top:-60px; right:-80px; pointer-events:none;
46+
animation: orbFloat1 6s ease-in-out infinite alternate;
47+
}
48+
@keyframes heroSweep {
49+
0% { transform:translate(0,0) rotate(0deg); }
50+
100% { transform:translate(3%,-3%) rotate(2deg); }
51+
}
52+
@keyframes orbFloat1 {
53+
0% { transform:translate(0,0) scale(1); opacity:0.7; }
54+
100% { transform:translate(-40px,50px) scale(1.2); opacity:1; }
55+
}
56+
@keyframes orbFloat2 {
57+
0% { transform:translate(0,0) scale(1); opacity:0.5; }
58+
100% { transform:translate(30px,-40px) scale(1.15); opacity:0.9; }
59+
}
60+
@keyframes shimmer {
61+
0% { background-position:200% center; }
62+
100% { background-position:-200% center; }
63+
}
64+
@keyframes fadeSlideUp {
65+
0% { opacity:0; transform:translateY(18px); }
66+
100% { opacity:1; transform:translateY(0); }
67+
}
68+
@keyframes gridPulse {
69+
0%,100% { opacity:0.03; }
70+
50% { opacity:0.08; }
71+
}
72+
/* Floating orb 2 (extra layer) */
73+
.hero-orb {
74+
position:absolute; width:200px; height:200px; border-radius:50%;
75+
background: radial-gradient(circle, rgba(63,185,80,0.12) 0%, transparent 70%);
76+
bottom:-40px; left:-60px; pointer-events:none;
77+
animation: orbFloat2 7s ease-in-out infinite alternate;
78+
}
79+
/* Animated grid lines */
80+
.hero-grid {
81+
position:absolute; top:0; left:0; width:100%; height:100%; pointer-events:none;
82+
background-image:
83+
linear-gradient(rgba(88,166,255,0.05) 1px, transparent 1px),
84+
linear-gradient(90deg, rgba(88,166,255,0.05) 1px, transparent 1px);
85+
background-size:60px 60px;
86+
animation: gridPulse 4s ease-in-out infinite;
87+
}
88+
/* Shimmering gradient title */
3989
.hero h1 {
40-
font-size:2.6em; background:linear-gradient(135deg,var(--accent),var(--green));
90+
font-size:2.6em;
91+
background:linear-gradient(90deg,var(--accent),var(--green),var(--purple),var(--accent));
92+
background-size:300% auto;
4193
-webkit-background-clip:text; -webkit-text-fill-color:transparent;
4294
background-clip:text; margin-bottom:10px; position:relative;
95+
animation: shimmer 6s linear infinite;
96+
}
97+
.hero .subtitle {
98+
color:var(--text-muted); font-size:1.1em; max-width:600px; margin:0 auto 24px; line-height:1.7; position:relative;
99+
animation: fadeSlideUp 0.8s ease-out 0.2s both;
100+
}
101+
.hero .badges {
102+
display:flex; gap:8px; justify-content:center; flex-wrap:wrap; margin-bottom:24px; position:relative;
103+
animation: fadeSlideUp 0.8s ease-out 0.4s both;
43104
}
44-
.hero .subtitle { color:var(--text-muted); font-size:1.1em; max-width:600px; margin:0 auto 24px; line-height:1.7; position:relative; }
45-
.hero .badges { display:flex; gap:8px; justify-content:center; flex-wrap:wrap; margin-bottom:24px; position:relative; }
46105
.badge {
47106
background:var(--surface); border:1px solid var(--border); border-radius:20px;
48-
padding:5px 13px; font-size:0.82em; color:var(--text); transition:all 0.2s;
107+
padding:5px 13px; font-size:0.82em; color:var(--text); transition:all 0.3s;
49108
}
50-
.badge:hover { border-color:var(--accent); color:var(--accent); }
109+
.badge:hover { border-color:var(--accent); color:var(--accent); transform:translateY(-2px); box-shadow:0 4px 12px rgba(88,166,255,0.15); }
51110
.badge.accent { border-color:var(--accent); color:var(--accent); }
52111
.badge.green { border-color:var(--green); color:var(--green); }
53112

@@ -317,6 +376,8 @@
317376

318377
<!-- ═══ HERO ═══ -->
319378
<div class="hero">
379+
<div class="hero-grid"></div>
380+
<div class="hero-orb"></div>
320381
<h1>&#x1F4CA; GitHub Issue Analytics</h1>
321382
<p class="subtitle">Enter any public GitHub repo. Get instant issue intelligence &mdash;<br>
322383
funnel, heatmap, gauges, and 13-metric scorecard. All in your browser.</p>
@@ -516,8 +577,9 @@ <h2>&#x1F4C8; Filing Trend (12 months)</h2>
516577
const issues = data.filter(i => !i.pull_request);
517578
allIssues = allIssues.concat(issues);
518579

519-
// Progress
520-
const pct = Math.min(95, page / (data.length < 100 ? page : maxPages) * 100);
580+
// Progress — fast-forward style: jump aggressively
581+
const pct = Math.min(95, (page / Math.min(maxPages, page + 2)) * 100);
582+
$('progressBar').style.transition = 'width 0.15s';
521583
$('progressBar').style.width = pct + '%';
522584
$('progressText').innerHTML = `<span class="spinner"></span>Fetched <strong>${allIssues.length}</strong> issues (page ${page})...`;
523585

@@ -666,6 +728,64 @@ <h2>&#x1F4C8; Filing Trend (12 months)</h2>
666728
};
667729
}
668730

731+
// ── DEMO DATA (static — renders instantly on page load) ──────
732+
const DEMO_METRICS = {
733+
total: 6224, openCount: 2341, closedCount: 3883,
734+
medianAgeDays: 487, fixRate: 62.4, escalationRate: 8.7,
735+
noResponseRate: 14.2, staleCount: 812, untriagedRate: 31.6, dsatScore: 284, shs: 42,
736+
areas: [
737+
{name:'bug', total:1842, bugs:1842, regressions:67, age:'1.8yr', fix_rate:58.3, stale:312, dsat:89},
738+
{name:'enhancement', total:1456, bugs:0, regressions:0, age:'2.1yr', fix_rate:41.2, stale:287, dsat:42},
739+
{name:'documentation', total:389, bugs:0, regressions:0, age:'0.9yr', fix_rate:72.8, stale:48, dsat:12},
740+
{name:'security', total:124, bugs:98, regressions:14, age:'0.4yr', fix_rate:87.1, stale:8, dsat:31},
741+
{name:'performance', total:267, bugs:201, regressions:23, age:'1.4yr', fix_rate:53.6, stale:67, dsat:45},
742+
{name:'api', total:512, bugs:156, regressions:11, age:'1.6yr', fix_rate:48.9, stale:134, dsat:38},
743+
{name:'testing', total:198, bugs:42, regressions:5, age:'1.1yr', fix_rate:66.2, stale:29, dsat:14},
744+
{name:'ux', total:341, bugs:87, regressions:3, age:'1.3yr', fix_rate:55.7, stale:72, dsat:28},
745+
],
746+
ageDist: [
747+
{label:'0-7d', count:143}, {label:'7-30d', count:287}, {label:'30-90d', count:412},
748+
{label:'90-180d', count:356}, {label:'180d-1yr', count:489}, {label:'1-2yr', count:384},
749+
{label:'2-3yr', count:178}, {label:'>3yr', count:92},
750+
],
751+
monthly: [
752+
{label:'Apr', count:87}, {label:'May', count:112}, {label:'Jun', count:98},
753+
{label:'Jul', count:134}, {label:'Aug', count:121}, {label:'Sep', count:156},
754+
{label:'Oct', count:143}, {label:'Nov', count:109}, {label:'Dec', count:78},
755+
{label:'Jan', count:167}, {label:'Feb', count:142}, {label:'Mar', count:128},
756+
],
757+
statuses: [
758+
{name:'untriaged', count:740, color:'#f85149'},
759+
{name:'triaged', count:612, color:'#3fb950'},
760+
{name:'labeled', count:534, color:'#a371f7'},
761+
{name:'needs_info', count:298, color:'#d29922'},
762+
{name:'in_progress', count:157, color:'#58a6ff'},
763+
],
764+
funnel: [
765+
{label:'Total Filed', count:6224, desc:'All issues in repo', color:'#58a6ff'},
766+
{label:'Labeled', count:4892, desc:'Issues with at least one label', color:'#a371f7'},
767+
{label:'Triaged', count:2847, desc:'Has triage/priority label', color:'#3fb950'},
768+
{label:'In Progress', count:157, desc:'Actively being worked on', color:'#d29922'},
769+
{label:'Closed', count:3883, desc:'Resolved or closed', color:'#238636'},
770+
],
771+
};
772+
const DEMO_REPO = 'pallets/flask';
773+
774+
// ── Demo Banner CSS ──
775+
const demoBannerStyle = document.createElement('style');
776+
demoBannerStyle.textContent = `
777+
.demo-banner {
778+
background:linear-gradient(135deg, rgba(88,166,255,0.12), rgba(63,185,80,0.12));
779+
border:1px solid rgba(88,166,255,0.25); border-radius:10px;
780+
padding:12px 20px; margin:0 auto 18px; max-width:720px;
781+
text-align:center; font-size:0.9em; color:var(--text-muted);
782+
animation: fadeSlideUp 0.5s ease-out both;
783+
}
784+
.demo-banner strong { color:var(--accent); }
785+
.demo-banner a { color:var(--green); cursor:pointer; font-weight:600; }
786+
`;
787+
document.head.appendChild(demoBannerStyle);
788+
669789
// ── Render Engine ────────────────────────────────
670790

671791
function renderDashboard(m) {
@@ -911,6 +1031,9 @@ <h2>&#x1F4C8; Filing Trend (12 months)</h2>
9111031
async function startAnalysis(event) {
9121032
if (event) event.preventDefault();
9131033
hideError();
1034+
// Remove demo banner if present
1035+
const db = document.getElementById('demoBanner');
1036+
if (db) db.remove();
9141037
const raw = $('repoInput').value.trim();
9151038
if (!raw) return false;
9161039

@@ -960,12 +1083,28 @@ <h2>&#x1F4C8; Filing Trend (12 months)</h2>
9601083
}
9611084

9621085
// ── URL param support: ?repo=owner/repo ──────────
1086+
// ── Auto-load demo data on page open ─────────────
9631087
window.addEventListener('load', () => {
9641088
const params = new URLSearchParams(window.location.search);
9651089
const repo = params.get('repo');
9661090
if (repo) {
9671091
$('repoInput').value = repo;
9681092
startAnalysis(new Event('submit'));
1093+
} else {
1094+
// Show pre-computed demo dashboard instantly
1095+
currentRepo = DEMO_REPO;
1096+
$('repoInput').value = DEMO_REPO;
1097+
1098+
// Insert demo banner above dashboard
1099+
const banner = document.createElement('div');
1100+
banner.className = 'demo-banner';
1101+
banner.id = 'demoBanner';
1102+
banner.innerHTML = `📊 Showing <strong>demo data</strong> for <strong>${DEMO_REPO}</strong> — enter any repo above for live analysis or <a onclick="document.getElementById('demoBanner').remove()">dismiss</a>`;
1103+
const dashEl = $('dashboard');
1104+
dashEl.parentNode.insertBefore(banner, dashEl);
1105+
1106+
renderDashboard(DEMO_METRICS);
1107+
$('dashboard').scrollIntoView({ behavior: 'smooth', block: 'start' });
9691108
}
9701109
});
9711110
</script>

0 commit comments

Comments
 (0)