Files
llm-bench-test/index.html

663 lines
26 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DriftDB — The Database That Learns</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=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #05050f;
--bg2: #0a0a1a;
--bg3: #0f0f25;
--bg4: #141430;
--accent: #6366f1;
--accent2: #818cf8;
--cyan: #22d3ee;
--cyan2: #67e8f9;
--pink: #ec4899;
--text: #f1f5f9;
--muted: #64748b;
--muted2: #94a3b8;
--border: rgba(99,102,241,0.15);
--radius: 12px;
}
html { scroll-behavior: smooth; }
body {
font-family: 'Inter', system-ui, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.6;
overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
.container { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
/* Nav */
nav {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
background: rgba(5,5,15,0.8);
backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border);
padding: 16px 0;
}
nav .container {
display: flex; align-items: center; justify-content: space-between;
}
.logo {
font-size: 1.4rem; font-weight: 800; letter-spacing: -0.5px;
background: linear-gradient(135deg, var(--accent2), var(--cyan));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.logo-icon {
display: inline-block; vertical-align: middle; margin-right: 8px;
}
.nav-links { display: flex; gap: 32px; align-items: center; }
.nav-links a { color: var(--muted2); font-size: 0.9rem; font-weight: 500; transition: color 0.2s; }
.nav-links a:hover { color: var(--text); }
.btn-nav {
background: var(--accent); color: #fff; padding: 8px 20px;
border-radius: 8px; font-weight: 600; font-size: 0.875rem;
transition: background 0.2s, transform 0.2s;
}
.btn-nav:hover { background: var(--accent2); transform: translateY(-1px); }
/* Hero */
.hero {
position: relative; padding: 160px 0 100px;
text-align: center; overflow: hidden;
}
.hero::before {
content: '';
position: absolute; inset: 0;
background: radial-gradient(ellipse 80% 60% at 50% 0%, rgba(99,102,241,0.2) 0%, transparent 70%),
radial-gradient(ellipse 60% 40% at 20% 80%, rgba(34,211,238,0.1) 0%, transparent 60%),
radial-gradient(ellipse 50% 30% at 80% 60%, rgba(236,72,153,0.08) 0%, transparent 60%);
pointer-events: none;
}
.hero-grid {
position: absolute; inset: 0; pointer-events: none;
background-image:
linear-gradient(rgba(99,102,241,0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(99,102,241,0.05) 1px, transparent 1px);
background-size: 60px 60px;
mask-image: radial-gradient(ellipse 70% 60% at 50% 0%, black 0%, transparent 70%);
}
.hero-badge {
display: inline-flex; align-items: center; gap: 8px;
background: rgba(99,102,241,0.1); border: 1px solid rgba(99,102,241,0.3);
padding: 6px 16px; border-radius: 100px; font-size: 0.8rem;
color: var(--accent2); font-weight: 500; margin-bottom: 24px;
animation: pulse-badge 3s ease-in-out infinite;
}
@keyframes pulse-badge {
0%, 100% { box-shadow: 0 0 0 0 rgba(99,102,241,0.3); }
50% { box-shadow: 0 0 0 8px rgba(99,102,241,0); }
}
.hero h1 {
font-size: clamp(2.8rem, 7vw, 5rem);
font-weight: 900; line-height: 1.05; letter-spacing: -2px;
margin-bottom: 24px;
background: linear-gradient(135deg, #fff 30%, var(--accent2) 60%, var(--cyan) 100%);
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.hero p {
font-size: clamp(1.1rem, 2.5vw, 1.35rem);
color: var(--muted2); max-width: 640px; margin: 0 auto 40px;
font-weight: 400;
}
.hero-ctas { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
.btn-primary {
background: linear-gradient(135deg, var(--accent), #4f46e5);
color: #fff; padding: 14px 32px; border-radius: 10px;
font-weight: 700; font-size: 1rem; border: none; cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
box-shadow: 0 4px 20px rgba(99,102,241,0.4);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 30px rgba(99,102,241,0.5); }
.btn-secondary {
background: rgba(255,255,255,0.05); border: 1px solid var(--border);
color: var(--muted2); padding: 14px 32px; border-radius: 10px;
font-weight: 600; font-size: 1rem; cursor: pointer; transition: all 0.2s;
}
.btn-secondary:hover { background: rgba(255,255,255,0.1); color: var(--text); }
.hero-stats {
display: flex; gap: 48px; justify-content: center; margin-top: 64px;
flex-wrap: wrap;
}
.hero-stat-num {
font-size: 2rem; font-weight: 800; background: linear-gradient(135deg, var(--accent2), var(--cyan));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.hero-stat-label { font-size: 0.85rem; color: var(--muted); margin-top: 4px; }
/* Features */
.section { padding: 100px 0; }
.section-tag {
display: inline-block; font-size: 0.75rem; font-weight: 600;
letter-spacing: 2px; text-transform: uppercase; color: var(--cyan);
margin-bottom: 12px;
}
.section-title {
font-size: clamp(2rem, 4vw, 2.8rem); font-weight: 800;
letter-spacing: -1px; margin-bottom: 16px;
}
.section-sub { color: var(--muted2); font-size: 1.1rem; max-width: 560px; }
.section-header { text-align: center; margin-bottom: 64px; }
.features-grid {
display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px;
}
.feature-card {
background: var(--bg2); border: 1px solid var(--border);
border-radius: var(--radius); padding: 32px;
transition: border-color 0.3s, transform 0.3s;
}
.feature-card:hover {
border-color: rgba(99,102,241,0.5);
transform: translateY(-4px);
}
.feature-icon {
width: 52px; height: 52px; border-radius: 12px;
background: linear-gradient(135deg, rgba(99,102,241,0.2), rgba(34,211,238,0.1));
display: flex; align-items: center; justify-content: center;
margin-bottom: 20px;
}
.feature-icon svg { width: 26px; height: 26px; }
.feature-title { font-size: 1.1rem; font-weight: 700; margin-bottom: 10px; }
.feature-desc { color: var(--muted2); font-size: 0.9rem; line-height: 1.7; }
/* Charts */
.charts-section { background: var(--bg2); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.charts-grid {
display: grid; grid-template-columns: 1fr 1fr; gap: 32px;
}
@media (max-width: 768px) { .charts-grid { grid-template-columns: 1fr; } }
.chart-card {
background: var(--bg3); border: 1px solid var(--border);
border-radius: var(--radius); padding: 32px;
}
.chart-title { font-size: 1rem; font-weight: 600; margin-bottom: 24px; color: var(--muted2); }
.chart-wrap { position: relative; height: 260px; }
/* Testimonials */
.testimonials-grid {
display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px;
}
.testimonial {
background: var(--bg2); border: 1px solid var(--border);
border-radius: var(--radius); padding: 28px;
}
.testimonial-stars { color: #fbbf24; margin-bottom: 16px; font-size: 0.9rem; letter-spacing: 2px; }
.testimonial-text { font-size: 0.95rem; color: var(--muted2); margin-bottom: 20px; line-height: 1.8; font-style: italic; }
.testimonial-author { display: flex; align-items: center; gap: 12px; }
.testimonial-avatar {
width: 40px; height: 40px; border-radius: 50%;
background: linear-gradient(135deg, var(--accent), var(--cyan));
display: flex; align-items: center; justify-content: center;
font-weight: 700; font-size: 0.85rem; color: #fff; flex-shrink: 0;
}
.testimonial-name { font-weight: 600; font-size: 0.9rem; }
.testimonial-role { color: var(--muted); font-size: 0.8rem; }
/* Stats Banner */
.stats-banner {
background: linear-gradient(135deg, rgba(99,102,241,0.15), rgba(34,211,238,0.1));
border: 1px solid rgba(99,102,241,0.3); border-radius: 20px;
padding: 60px 40px; text-align: center;
}
.stats-grid { display: flex; justify-content: center; gap: 64px; flex-wrap: wrap; margin-top: 40px; }
.stat-item {}
.stat-num { font-size: 3rem; font-weight: 900; line-height: 1; margin-bottom: 8px; }
.stat-num .accent { background: linear-gradient(135deg, var(--accent2), var(--cyan)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.stat-num .pink { background: linear-gradient(135deg, var(--pink), var(--accent)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.stat-label { color: var(--muted2); font-size: 0.9rem; }
/* CTA */
.cta-section {
text-align: center; padding: 120px 0;
background: radial-gradient(ellipse 80% 50% at 50% 100%, rgba(99,102,241,0.15), transparent);
}
.cta-section h2 {
font-size: clamp(2rem, 5vw, 3.2rem); font-weight: 900;
letter-spacing: -1.5px; margin-bottom: 16px;
}
.cta-section p { color: var(--muted2); font-size: 1.15rem; margin-bottom: 40px; }
/* Footer */
footer {
border-top: 1px solid var(--border);
padding: 48px 0 32px;
background: var(--bg);
}
.footer-grid {
display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 48px;
margin-bottom: 48px;
}
@media (max-width: 768px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
.footer-brand p { color: var(--muted); font-size: 0.875rem; margin-top: 12px; }
.footer-col h4 { font-size: 0.8rem; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); margin-bottom: 16px; }
.footer-col a { display: block; color: var(--muted2); font-size: 0.875rem; margin-bottom: 10px; transition: color 0.2s; }
.footer-col a:hover { color: var(--text); }
.footer-bottom {
border-top: 1px solid var(--border); padding-top: 24px;
display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px;
}
.footer-bottom p { color: var(--muted); font-size: 0.8rem; }
@media (max-width: 640px) {
.nav-links { display: none; }
.hero-stats { gap: 24px; }
.hero-ctas { flex-direction: column; align-items: center; }
.hero-ctas button { width: 100%; max-width: 300px; }
.stats-grid { gap: 32px; }
.stat-num { font-size: 2.2rem; }
}
</style>
</head>
<body>
<!-- NAV -->
<nav>
<div class="container">
<div class="logo">
<svg class="logo-icon" width="28" height="28" viewBox="0 0 28 28" fill="none">
<rect width="28" height="28" rx="8" fill="url(#logo-grad)"/>
<path d="M8 20 L14 8 L20 20 M10.5 15.5 H17.5" stroke="white" stroke-width="2.5" stroke-linecap="round"/>
<defs>
<linearGradient id="logo-grad" x1="0" y1="0" x2="28" y2="28">
<stop offset="0%" stop-color="#6366f1"/>
<stop offset="100%" stop-color="#22d3ee"/>
</linearGradient>
</defs>
</svg>
DriftDB
</div>
<div class="nav-links">
<a href="#features">Features</a>
<a href="#performance">Performance</a>
<a href="#testimonials">Testimonials</a>
<a href="#pricing">Pricing</a>
<a href="#" class="btn-nav">Get Early Access</a>
</div>
</div>
</nav>
<!-- HERO -->
<section class="hero">
<div class="hero-grid"></div>
<div class="container">
<div class="hero-badge">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="7" r="3" fill="#22d3ee"/><circle cx="7" cy="7" r="6" stroke="#22d3ee" stroke-width="1" opacity="0.4"/></svg>
Now in Public Beta — v0.9
</div>
<h1>The Database That<br>Never Stops Learning</h1>
<p>DriftDB observes your query patterns, pre-computes results, auto-creates indexes, and adapts its schema in real time — so your app stays fast without you lifting a finger.</p>
<div class="hero-ctas">
<button class="btn-primary">Start Free Trial</button>
<button class="btn-secondary">Read the Docs</button>
</div>
<div class="hero-stats">
<div>
<div class="hero-stat-num">10M+</div>
<div class="hero-stat-label">queries / day</div>
</div>
<div>
<div class="hero-stat-num">3.8×</div>
<div class="hero-stat-label">avg speedup</div>
</div>
<div>
<div class="hero-stat-num">99.99%</div>
<div class="hero-stat-label">uptime SLA</div>
</div>
<div>
<div class="hero-stat-num">&lt;2ms</div>
<div class="hero-stat-label">p99 latency</div>
</div>
</div>
</div>
</section>
<!-- FEATURES -->
<section class="section" id="features">
<div class="container">
<div class="section-header">
<div class="section-tag">Core Features</div>
<h2 class="section-title">Built-in intelligence,<br>not an afterthought</h2>
<p class="section-sub">DriftDB runs a lightweight ML model alongside your data, continuously optimizing without human intervention.</p>
</div>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="#6366f1" stroke-width="2" stroke-linecap="round">
<path d="M12 2a7 7 0 0 1 7 7c0 5-7 13-7 13S5 14 5 9a7 7 0 0 1 7-7z"/>
<circle cx="12" cy="9" r="2.5"/>
</svg>
</div>
<h3 class="feature-title">Pattern-Aware Caching</h3>
<p class="feature-desc">DriftDB learns which queries run most often and pre-computes their results. Hot paths get served from memory, not disk — transparently.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="#22d3ee" stroke-width="2" stroke-linecap="round">
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>
</svg>
</div>
<h3 class="feature-title">Zero-Latency Indexing</h3>
<p class="feature-desc">Drop an index on a hot column and DriftDB accelerates it instantly. Unused indexes are flagged and removed automatically — no more stale bloat.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="#ec4899" stroke-width="2" stroke-linecap="round">
<ellipse cx="12" cy="5" rx="9" ry="3"/>
<path d="M3 5v6c0 1.66 4 3 9 3s9-1.34 9-3V5"/>
<path d="M3 11v6c0 1.66 4 3 9 3s9-1.34 9-3v-6"/>
</svg>
</div>
<h3 class="feature-title">Adaptive Schema Evolution</h3>
<p class="feature-desc">Add columns, change types, or restructure tables mid-flight. DriftDB migrates data incrementally and serves queries throughout the process.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="#a78bfa" stroke-width="2" stroke-linecap="round">
<circle cx="12" cy="12" r="3"/>
<path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/>
</svg>
</div>
<h3 class="feature-title">Predictive Auto-Tuning</h3>
<p class="feature-desc">During low-traffic windows, DriftDB runs what-if analysis on your query plans and pre-allocates resources before traffic spikes arrive.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
</svg>
</div>
<h3 class="feature-title">Consistent Snapshot Isolation</h3>
<p class="feature-desc">Multi-version concurrency with serializable isolation guarantees. DriftDB never reads stale data, even under heavy write pressure.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round">
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
</svg>
</div>
<h3 class="feature-title">Real-Time Analytics</h3>
<p class="feature-desc">OLAP and OLTP in one engine. Run analytical queries alongside transactional ones without impacting each other's performance.</p>
</div>
</div>
</div>
</section>
<!-- CHARTS -->
<section class="section charts-section" id="performance">
<div class="container">
<div class="section-header">
<div class="section-tag">Performance</div>
<h2 class="section-title">Numbers that speak<br>for themselves</h2>
<p class="section-sub">Real-world benchmarks from production workloads migrated to DriftDB.</p>
</div>
<div class="charts-grid">
<div class="chart-card">
<div class="chart-title">Query Speed — Baseline vs DriftDB (ms, p99)</div>
<div class="chart-wrap">
<canvas id="barChart"></canvas>
</div>
</div>
<div class="chart-card">
<div class="chart-title">Index Efficiency Score Over 30 Days</div>
<div class="chart-wrap">
<canvas id="lineChart"></canvas>
</div>
</div>
</div>
</div>
</section>
<!-- TESTIMONIALS -->
<section class="section" id="testimonials">
<div class="container">
<div class="section-header">
<div class="section-tag">Testimonials</div>
<h2 class="section-title">Loved by engineers<br>at fast-moving teams</h2>
</div>
<div class="testimonials-grid">
<div class="testimonial">
<div class="testimonial-stars">★★★★★</div>
<p class="testimonial-text">"We migrated our 500GB analytics DB to DriftDB and cut our dashboard load time from 4.2s to 890ms — without touching a single query. The auto-indexing alone saved us three sprint weeks."</p>
<div class="testimonial-author">
<div class="testimonial-avatar">SR</div>
<div>
<div class="testimonial-name">Sara Reinholt</div>
<div class="testimonial-role">Head of Data, Meridian Health</div>
</div>
</div>
</div>
<div class="testimonial">
<div class="testimonial-stars">★★★★★</div>
<p class="testimonial-text">"DriftDB is the first database I've used that actually gets faster the longer it runs. Our e-commerce platform handles 6× the Black Friday traffic now, no ops involvement."</p>
<div class="testimonial-author">
<div class="testimonial-avatar">KL</div>
<div>
<div class="testimonial-name">Kai Lindström</div>
<div class="testimonial-role">CTO, Nord Commerce</div>
</div>
</div>
</div>
<div class="testimonial">
<div class="testimonial-stars">★★★★★</div>
<p class="testimonial-text">"The schema evolution feature is magic. We added a JSONB column to a 200M-row table and DriftDB served reads throughout — zero downtime, zero incidents. That used to be a weekend project."</p>
<div class="testimonial-author">
<div class="testimonial-avatar">AP</div>
<div>
<div class="testimonial-name">Anya Petrov</div>
<div class="testimonial-role">Principal Engineer, Flock Payments</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- STATS BANNER -->
<section class="section">
<div class="container">
<div class="stats-banner">
<div class="section-tag">By the Numbers</div>
<h2 class="section-title">Trusted at scale</h2>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-num"><span class="accent">2,400+</span></div>
<div class="stat-label">companies in beta</div>
</div>
<div class="stat-item">
<div class="stat-num"><span class="pink">14B</span></div>
<div class="stat-label">queries served daily</div>
</div>
<div class="stat-item">
<div class="stat-num"><span class="accent">3.8×</span></div>
<div class="stat-label">avg query speedup</div>
</div>
<div class="stat-item">
<div class="stat-num"><span class="pink">82%</span></div>
<div class="stat-label">less DBA intervention</div>
</div>
</div>
</div>
</div>
</section>
<!-- CTA -->
<section class="cta-section">
<div class="container">
<h2>Ready to stop tuning<br>by hand?</h2>
<p>Join 2,400+ teams already running smarter databases.</p>
<div class="hero-ctas">
<button class="btn-primary">Start Free Trial — No CC Required</button>
<button class="btn-secondary">Talk to Sales</button>
</div>
</div>
</section>
<!-- FOOTER -->
<footer>
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<div class="logo">DriftDB</div>
<p>The self-optimizing database for teams that ship fast. Built on Postgres-compatible foundations with a layer of real-time intelligence.</p>
</div>
<div class="footer-col">
<h4>Product</h4>
<a href="#">Features</a>
<a href="#">Pricing</a>
<a href="#">Changelog</a>
<a href="#">Roadmap</a>
</div>
<div class="footer-col">
<h4>Developers</h4>
<a href="#">Documentation</a>
<a href="#">API Reference</a>
<a href="#">SDKs</a>
<a href="#">GitHub</a>
</div>
<div class="footer-col">
<h4>Company</h4>
<a href="#">About</a>
<a href="#">Blog</a>
<a href="#">Careers</a>
<a href="#">Security</a>
</div>
</div>
<div class="footer-bottom">
<p>© 2026 DriftDB, Inc. All rights reserved.</p>
<p>
<a href="#">Privacy</a> &nbsp;·&nbsp;
<a href="#">Terms</a> &nbsp;·&nbsp;
<a href="#">Status</a>
</p>
</div>
</div>
</footer>
<script>
// Chart.js defaults for dark theme
Chart.defaults.color = '#94a3b8';
Chart.defaults.borderColor = 'rgba(99,102,241,0.1)';
// BAR CHART
const barCtx = document.getElementById('barChart').getContext('2d');
new Chart(barCtx, {
type: 'bar',
data: {
labels: ['User Lookup', 'Order Search', 'Report Gen', 'Feed Query', 'Analytics'],
datasets: [
{
label: 'Baseline Postgres',
data: [420, 890, 2340, 1100, 1870],
backgroundColor: 'rgba(100,116,139,0.6)',
borderColor: 'rgba(100,116,139,1)',
borderWidth: 1,
borderRadius: 6,
},
{
label: 'DriftDB Optimized',
data: [85, 210, 580, 290, 490],
backgroundColor: 'rgba(99,102,241,0.7)',
borderColor: 'rgba(99,102,241,1)',
borderWidth: 1,
borderRadius: 6,
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { position: 'top', labels: { padding: 16, usePointStyle: true, pointStyleWidth: 8 } },
tooltip: {
callbacks: { label: ctx => ` ${ctx.dataset.label}: ${ctx.raw}ms` }
}
},
scales: {
x: { grid: { display: false } },
y: {
beginAtZero: true,
grid: { color: 'rgba(99,102,241,0.06)' },
ticks: { callback: v => v + 'ms' }
}
}
}
});
// LINE CHART
const lineCtx = document.getElementById('lineChart').getContext('2d');
const gradient = lineCtx.createLinearGradient(0, 0, 0, 260);
gradient.addColorStop(0, 'rgba(34,211,238,0.35)');
gradient.addColorStop(1, 'rgba(34,211,238,0)');
new Chart(lineCtx, {
type: 'line',
data: {
labels: ['Day 1','Day 4','Day 8','Day 12','Day 16','Day 20','Day 24','Day 28','Day 30'],
datasets: [{
label: 'Index Efficiency Score',
data: [22, 31, 44, 58, 67, 74, 80, 85, 91],
borderColor: '#22d3ee',
backgroundColor: gradient,
borderWidth: 2.5,
pointRadius: 4,
pointBackgroundColor: '#22d3ee',
fill: true,
tension: 0.4,
},
{
label: 'Baseline Postgres',
data: [20, 20, 19, 21, 20, 22, 19, 21, 20],
borderColor: 'rgba(100,116,139,0.6)',
backgroundColor: 'transparent',
borderWidth: 1.5,
borderDash: [5, 5],
pointRadius: 0,
tension: 0.4,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { position: 'top', labels: { padding: 16, usePointStyle: true, pointStyleWidth: 8 } },
tooltip: { callbacks: { label: ctx => ` ${ctx.dataset.label}: ${ctx.raw}` } }
},
scales: {
x: { grid: { display: false } },
y: {
beginAtZero: true,
max: 100,
grid: { color: 'rgba(99,102,241,0.06)' },
ticks: { callback: v => v }
}
}
}
});
// Smooth scroll for nav
document.querySelectorAll('a[href^="#"]').forEach(a => {
a.addEventListener('click', e => {
const target = document.querySelector(a.getAttribute('href'));
if (target) { e.preventDefault(); target.scrollIntoView({ behavior: 'smooth', block: 'start' }); }
});
});
</script>
</body>
</html>