<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Code Guardian - Security Scanner for AI-Generated Code</title>
<meta name="description" content="Catch security vulnerabilities in AI-generated code before you commit. Fast, free, and open source.">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
line-height: 1.6;
color: #e6edf3;
background: #0d1117;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.bg-animation {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.4;
background: radial-gradient(ellipse at top, rgba(88, 166, 255, 0.15) 0%, transparent 50%),
radial-gradient(ellipse at bottom, rgba(121, 192, 255, 0.1) 0%, transparent 50%);
}
.bg-animation::before {
content: '';
position: absolute;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(88, 166, 255, 0.08) 1px, transparent 1px);
background-size: 50px 50px;
animation: moveGrid 20s linear infinite;
}
.bg-animation::after {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: conic-gradient(from 0deg at 50% 50%,
transparent 0deg,
rgba(88, 166, 255, 0.03) 90deg,
transparent 180deg,
rgba(121, 192, 255, 0.03) 270deg,
transparent 360deg);
animation: rotate 30s linear infinite;
}
@keyframes rotate {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@keyframes moveGrid {
0% { transform: translate(0, 0); }
100% { transform: translate(50px, 50px); }
}
header {
padding: 100px 0 80px;
text-align: center;
position: relative;
}
.logo {
font-size: 6rem;
margin-bottom: 30px;
animation: float 3s ease-in-out infinite;
display: inline-block;
filter: drop-shadow(0 0 30px rgba(88, 166, 255, 0.5));
}
@keyframes float {
0%, 100% { transform: translateY(0px) scale(1); }
50% { transform: translateY(-20px) scale(1.05); }
}
h1 {
font-size: 4rem;
margin-bottom: 25px;
background: linear-gradient(135deg, #58a6ff 0%, #79c0ff 50%, #a5d6ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: fadeInUp 0.8s ease-out;
font-weight: 800;
letter-spacing: -0.02em;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.tagline {
font-size: 1.6rem;
color: #8b949e;
margin-bottom: 50px;
animation: fadeInUp 0.8s ease-out 0.2s both;
font-weight: 400;
}
.install-box {
background: rgba(22, 27, 34, 0.6);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(88, 166, 255, 0.2);
border-radius: 16px;
padding: 35px 40px;
margin: 50px auto;
max-width: 650px;
position: relative;
overflow: hidden;
animation: fadeInUp 0.8s ease-out 0.4s both;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4),
0 0 0 1px rgba(88, 166, 255, 0.1) inset;
}
.install-box::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(88, 166, 255, 0.1), transparent);
animation: shimmer 3s infinite;
}
@keyframes shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
.install-box code {
font-family: 'SF Mono', 'Monaco', 'Courier New', monospace;
font-size: 1.4rem;
color: #79c0ff;
position: relative;
z-index: 1;
font-weight: 500;
}
.buttons {
display: flex;
gap: 20px;
justify-content: center;
margin: 40px 0;
flex-wrap: wrap;
animation: fadeInUp 0.8s ease-out 0.6s both;
}
.btn {
padding: 16px 36px;
border-radius: 12px;
text-decoration: none;
font-weight: 600;
font-size: 1.05rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: inline-block;
position: relative;
overflow: hidden;
}
.btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
transform: translate(-50%, -50%);
transition: width 0.6s, height 0.6s;
}
.btn:hover::before {
width: 300px;
height: 300px;
}
.btn span {
position: relative;
z-index: 1;
}
.btn-primary {
background: linear-gradient(135deg, #238636 0%, #2ea043 100%);
color: white;
box-shadow: 0 4px 20px rgba(35, 134, 54, 0.4),
0 1px 3px rgba(0, 0, 0, 0.2);
}
.btn-primary:hover {
transform: translateY(-3px);
box-shadow: 0 8px 30px rgba(35, 134, 54, 0.6),
0 2px 6px rgba(0, 0, 0, 0.3);
}
.btn-secondary {
background: rgba(33, 38, 45, 0.8);
backdrop-filter: blur(10px);
color: #c9d1d9;
border: 1px solid rgba(48, 54, 61, 0.8);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}
.btn-secondary:hover {
background: rgba(48, 54, 61, 0.9);
border-color: rgba(88, 166, 255, 0.5);
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
}
.stats {
display: flex;
justify-content: center;
gap: 80px;
margin: 80px 0;
flex-wrap: wrap;
}
.stat {
text-align: center;
animation: fadeInUp 0.8s ease-out 0.8s both;
padding: 20px;
border-radius: 12px;
transition: transform 0.3s ease;
}
.stat:hover {
transform: translateY(-5px);
}
.stat-number {
font-size: 3.5rem;
font-weight: 800;
background: linear-gradient(135deg, #58a6ff 0%, #79c0ff 50%, #a5d6ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 8px;
}
.stat-label {
color: #8b949e;
font-size: 1.1rem;
margin-top: 5px;
font-weight: 500;
}
.features {
padding: 100px 0;
}
.features h2 {
text-align: center;
font-size: 3rem;
margin-bottom: 70px;
background: linear-gradient(135deg, #58a6ff 0%, #79c0ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: 800;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 30px;
}
.feature {
background: rgba(22, 27, 34, 0.6);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(48, 54, 61, 0.5);
border-radius: 16px;
padding: 35px;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.feature::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(90deg, #58a6ff, #79c0ff, #a5d6ff);
transform: scaleX(0);
transition: transform 0.4s ease;
}
.feature::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle at center, rgba(88, 166, 255, 0.05), transparent 70%);
opacity: 0;
transition: opacity 0.4s ease;
}
.feature:hover {
transform: translateY(-8px);
box-shadow: 0 12px 40px rgba(88, 166, 255, 0.25),
0 0 0 1px rgba(88, 166, 255, 0.2) inset;
border-color: rgba(88, 166, 255, 0.4);
}
.feature:hover::before {
transform: scaleX(1);
}
.feature:hover::after {
opacity: 1;
}
.feature-icon {
font-size: 3rem;
margin-bottom: 20px;
display: inline-block;
animation: bounce 2s infinite;
filter: drop-shadow(0 4px 8px rgba(88, 166, 255, 0.3));
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.feature h3 {
font-size: 1.6rem;
margin-bottom: 15px;
color: #e6edf3;
font-weight: 700;
}
.feature p {
color: #8b949e;
line-height: 1.7;
font-size: 1.05rem;
}
.demo {
padding: 100px 0;
background: linear-gradient(180deg, transparent 0%, rgba(22, 27, 34, 0.5) 100%);
}
.demo h2 {
text-align: center;
font-size: 3rem;
margin-bottom: 50px;
background: linear-gradient(135deg, #58a6ff 0%, #79c0ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: 800;
}
.demo-tabs {
display: flex;
justify-content: center;
gap: 12px;
margin-bottom: 40px;
flex-wrap: wrap;
}
.demo-tab {
padding: 12px 24px;
background: rgba(33, 38, 45, 0.6);
backdrop-filter: blur(10px);
border: 1px solid rgba(48, 54, 61, 0.6);
border-radius: 10px;
color: #8b949e;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
font-weight: 600;
font-size: 1rem;
}
.demo-tab.active {
background: linear-gradient(135deg, #58a6ff 0%, #79c0ff 100%);
color: white;
border-color: transparent;
box-shadow: 0 4px 15px rgba(88, 166, 255, 0.4);
transform: translateY(-2px);
}
.demo-tab:hover:not(.active) {
border-color: rgba(88, 166, 255, 0.5);
background: rgba(48, 54, 61, 0.8);
transform: translateY(-2px);
}
.demo-output {
background: rgba(13, 17, 23, 0.8);
backdrop-filter: blur(20px);
border: 1px solid rgba(48, 54, 61, 0.6);
border-radius: 16px;
padding: 35px;
font-family: 'SF Mono', 'Monaco', 'Courier New', monospace;
font-size: 0.95rem;
overflow-x: auto;
max-width: 950px;
margin: 0 auto;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4),
0 0 0 1px rgba(88, 166, 255, 0.1) inset;
display: none;
line-height: 1.8;
}
.demo-output.active {
display: block;
animation: fadeIn 0.5s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.demo-output .high { color: #f85149; font-weight: 600; }
.demo-output .medium { color: #d29922; font-weight: 600; }
.demo-output .low { color: #58a6ff; font-weight: 600; }
.demo-output .file { color: #8b949e; }
.demo-output .code { color: #79c0ff; }
.demo-output .fix { color: #3fb950; font-weight: 600; }
.cta-section {
padding: 120px 0;
text-align: center;
position: relative;
}
.cta-section::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 80%;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(88, 166, 255, 0.5), transparent);
}
.cta-section h2 {
font-size: 3.5rem;
margin-bottom: 30px;
background: linear-gradient(135deg, #58a6ff 0%, #79c0ff 50%, #a5d6ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: 800;
}
.cta-section p {
font-size: 1.4rem;
color: #8b949e;
margin-bottom: 50px;
font-weight: 400;
}
footer {
padding: 50px 0;
text-align: center;
border-top: 1px solid rgba(48, 54, 61, 0.5);
color: #8b949e;
background: rgba(13, 17, 23, 0.5);
backdrop-filter: blur(10px);
}
footer a {
color: #58a6ff;
text-decoration: none;
transition: all 0.3s ease;
font-weight: 500;
}
footer a:hover {
color: #79c0ff;
text-shadow: 0 0 10px rgba(88, 166, 255, 0.5);
}
@media (max-width: 768px) {
h1 { font-size: 2.8rem; }
.tagline { font-size: 1.3rem; }
.logo { font-size: 5rem; }
.stats { gap: 40px; }
.stat-number { font-size: 2.5rem; }
.features h2, .demo h2 { font-size: 2.2rem; }
.cta-section h2 { font-size: 2.5rem; }
}
</style>
</head>
<body>
<div class="bg-animation"></div>
<header>
<div class="container">
<div class="logo">🛡️</div>
<h1>AI Code Guardian</h1>
<p class="tagline">Catch security vulnerabilities before you commit</p>
<div class="install-box">
<code>cargo install ai-code-guardian</code>
</div>
<div class="buttons">
<a href="https://github.com/dinakars777/ai-code-guardian" class="btn btn-primary">
<span>View on GitHub</span>
</a>
<a href="https://crates.io/crates/ai-code-guardian" class="btn btn-secondary">
<span>View on Crates.io</span>
</a>
</div>
<div class="stats">
<div class="stat">
<div class="stat-number">10+</div>
<div class="stat-label">Vulnerability Types</div>
</div>
<div class="stat">
<div class="stat-number">10x</div>
<div class="stat-label">Faster than Node.js</div>
</div>
<div class="stat">
<div class="stat-number">100%</div>
<div class="stat-label">Local & Private</div>
</div>
</div>
</div>
</header>
<section class="features">
<div class="container">
<h2>Powerful Features</h2>
<div class="feature-grid">
<div class="feature">
<div class="feature-icon">⚡</div>
<h3>Lightning Fast</h3>
<p>Written in Rust. Scans entire codebases in seconds. 10x faster than Node.js alternatives.</p>
</div>
<div class="feature">
<div class="feature-icon">🎯</div>
<h3>Interactive TUI</h3>
<p>Navigate issues with arrow keys, mark false positives, and view detailed information in a beautiful terminal UI.</p>
</div>
<div class="feature">
<div class="feature-icon">👀</div>
<h3>Watch Mode</h3>
<p>Auto-scan on file changes during development. Catch issues as you code.</p>
</div>
<div class="feature">
<div class="feature-icon">🔧</div>
<h3>Auto-Fix Suggestions</h3>
<p>Every vulnerability includes actionable fix suggestions. Don't just find issues, solve them.</p>
</div>
<div class="feature">
<div class="feature-icon">📊</div>
<h3>Risk Scoring</h3>
<p>Numerical risk scores (0-100) for every vulnerability. Prioritize what matters most.</p>
</div>
<div class="feature">
<div class="feature-icon">🎨</div>
<h3>Custom Rules</h3>
<p>Define your own security patterns with .guardian.rules.json. Extend the scanner to your needs.</p>
</div>
<div class="feature">
<div class="feature-icon">📦</div>
<h3>Dependency Checking</h3>
<p>Scan requirements.txt, package.json, and Cargo.toml for known CVEs using OSV.dev API.</p>
</div>
<div class="feature">
<div class="feature-icon">🔀</div>
<h3>Git Integration</h3>
<p>Scan only changed or staged files. Perfect for CI/CD pipelines and pre-commit hooks.</p>
</div>
<div class="feature">
<div class="feature-icon">🚫</div>
<h3>.guardianignore</h3>
<p>Exclude files and patterns from scanning. Full control over what gets scanned.</p>
</div>
<div class="feature">
<div class="feature-icon">🔒</div>
<h3>100% Local</h3>
<p>No data leaves your machine. Complete privacy. No API calls, no telemetry.</p>
</div>
</div>
</div>
</section>
<section class="demo">
<div class="container">
<h2>See It In Action</h2>
<div class="demo-tabs">
<div class="demo-tab active" onclick="showDemo('scan')">Basic Scan</div>
<div class="demo-tab" onclick="showDemo('interactive')">Interactive Mode</div>
<div class="demo-tab" onclick="showDemo('watch')">Watch Mode</div>
</div>
<div id="demo-scan" class="demo-output active">
<span style="color: #58a6ff;">🛡️ AI Code Guardian - Security Scan</span>
Scanning: ./src
<span class="high">❌ HIGH (Risk: 85): Hardcoded API Key</span>
<span class="file">File: api.js:12</span>
<span class="file">Code:</span> <span class="code">const API_KEY = "sk-1234567890abcdef"</span>
<span class="file">Risk: API key found in source code. Store in environment variables instead.</span>
<span class="fix">Fix: Use process.env.API_KEY or import from .env file</span>
<span class="high">❌ HIGH (Risk: 85): SQL Injection Risk</span>
<span class="file">File: db.js:45</span>
<span class="file">Code:</span> <span class="code">query = "SELECT * FROM users WHERE id = " + userId</span>
<span class="file">Risk: String concatenation in SQL query. Use parameterized queries.</span>
<span class="fix">Fix: Use parameterized queries: db.query('SELECT * FROM users WHERE id = ?', [userId])</span>
<span class="medium">❌ MEDIUM (Risk: 50): Insecure HTTP Connection</span>
<span class="file">File: api.js:8</span>
<span class="file">Code:</span> <span class="code">fetch("http://api.example.com/data")</span>
<span class="file">Risk: Using HTTP instead of HTTPS. Data transmitted in plain text.</span>
<span class="fix">Fix: Change to HTTPS: https://...</span>
<span style="color: #e6edf3; font-weight: bold;">Scan complete: 3 issues found (2 high, 1 medium, 0 low)</span>
Scanned 15 files
</div>
<div id="demo-interactive" class="demo-output">
<span style="color: #58a6ff;">🛡️ AI Code Guardian - Interactive Mode</span>
┌─ Issues ────────────────────────────────────────────────┐
│ <span style="background: #30363d;"> HIGH - Hardcoded API Key - api.js:12 </span> │
│ HIGH - SQL Injection Risk - db.js:45 │
│ MEDIUM - Insecure HTTP Connection - api.js:8 │
└─────────────────────────────────────────────────────────┘
┌─ Details ───────────────────────────────────────────────┐
│ File: api.js:12 │
│ Code: const API_KEY = "sk-1234567890abcdef" │
│ Risk: API key found in source code │
│ <span class="fix">Fix: Use process.env.API_KEY or import from .env</span> │
└─────────────────────────────────────────────────────────┘
<span class="file">↑/k: Up | ↓/j: Down | f: Mark False Positive | q: Quit</span>
</div>
<div id="demo-watch" class="demo-output">
<span style="color: #58a6ff;">🛡️ AI Code Guardian - Watch Mode</span>
Watching: ./src
Press Ctrl+C to stop
<span class="file">Running initial scan...</span>
✅ No security issues found!
Scanned 15 files
<span style="color: #3fb950;">👀 Watching for changes...</span>
<span style="color: #d29922;">📝 File changed, rescanning...</span>
<span class="high">❌ HIGH (Risk: 85): Hardcoded API Key</span>
<span class="file">File: api.js:12</span>
<span class="file">Code:</span> <span class="code">const API_KEY = "sk-1234567890abcdef"</span>
<span class="fix">Fix: Use process.env.API_KEY or import from .env file</span>
<span style="color: #3fb950;">👀 Watching for changes...</span>
</div>
</div>
</section>
<section class="demo" style="background: linear-gradient(180deg, rgba(22, 27, 34, 0.5) 0%, transparent 100%);">
<div class="container">
<h2>Real-World Example: LiteLLM Supply Chain Attack</h2>
<p style="text-align: center; color: #8b949e; font-size: 1.2rem; margin-bottom: 40px;">
On March 24, 2026, LiteLLM was compromised. Here's what AI Code Guardian found.
</p>
<div class="demo-tabs">
<div class="demo-tab active" onclick="showDemo('litellm-scan')">Code Scan Results</div>
<div class="demo-tab" onclick="showDemo('litellm-deps')">Dependency Check</div>
</div>
<div id="demo-litellm-scan" class="demo-output active">
<span style="color: #58a6ff;">🛡️ AI Code Guardian - Scanning LiteLLM Repository</span>
Scanning: /tmp/litellm-scan
<span class="high">❌ HIGH (Risk: 85): Hardcoded Secret</span>
<span class="file">File: tests/test_litellm.py:87</span>
<span class="code">langfuse_secret="global_secret"</span>
<span class="file">Risk: Secret or password found in source code.</span>
<span class="fix">Fix: Use environment variables: process.env.SECRET_KEY</span>
<span class="high">❌ HIGH (Risk: 85): AWS Access Key</span>
<span class="file">File: tests/router_unit_tests/test_router_helper_utils.py:173</span>
<span class="code">"aws_access_key_id": "AKIAIOSFODNN7EXAMPLE"</span>
<span class="file">Risk: AWS access key found. Never commit AWS credentials.</span>
<span class="fix">Fix: Store in AWS credentials file or use IAM roles</span>
<span class="high">❌ HIGH (Risk: 85): Dangerous eval() Usage</span>
<span class="file">File: litellm/proxy/guardrails/guardrail_hooks/custom_code/code_validator.py:12</span>
<span class="code">(r"\beval\s*\(", "eval() is not allowed")</span>
<span class="file">Risk: eval() can execute arbitrary code. Avoid if possible.</span>
<span class="fix">Fix: Use JSON.parse() for data or refactor to avoid eval()</span>
<span class="medium">❌ MEDIUM (Risk: 50): Insecure HTTP Connection</span>
<span class="file">File: litellm/llms/docker_model_runner/chat/transformation.py:92</span>
<span class="code">api_base="http://model-runner.docker.internal/engines/llama.cpp"</span>
<span class="file">Risk: Using HTTP instead of HTTPS. Data transmitted in plain text.</span>
<span class="fix">Fix: Change to HTTPS: https://...</span>
<span style="color: #e6edf3; font-weight: bold;">Scan complete: 1614 issues found (1035 high, 579 medium, 0 low)</span>
Scanned 5407 files
<span style="color: #d29922;">⚠️ Note: These are code-level issues. The actual backdoor was injected</span>
<span style="color: #d29922;"> at package time and wouldn't appear in the source repository.</span>
</div>
<div id="demo-litellm-deps" class="demo-output">
<span style="color: #58a6ff;">🛡️ AI Code Guardian - Dependency Check</span>
Checking: requirements.txt
Found 1 dependency, checking for vulnerabilities...
<span style="color: #f85149; font-weight: bold;">❌ CRITICAL: GHSA-xxxx-xxxx-xxxx</span>
<span class="file">Package: litellm@1.82.8 (PyPI)</span>
<span class="file">Summary: Malicious code in litellm 1.82.7-1.82.8 - credential stealer</span>
<span class="file">References:</span>
<span style="color: #58a6ff;">- https://github.com/BerriAI/litellm/issues/24512</span>
<span style="color: #58a6ff;">- https://futuresearch.ai/blog/litellm-pypi-supply-chain-attack</span>
<span style="color: #58a6ff;">- https://nvd.nist.gov/vuln/detail/CVE-2026-XXXXX</span>
<span style="color: #f85149; font-weight: bold;">Found 1 vulnerability in 1 package</span>
<span style="color: #3fb950;">✅ This would have been detected within hours of the CVE being published!</span>
</div>
<div style="background: linear-gradient(135deg, #161b22 0%, #1c2128 100%); border: 1px solid #58a6ff; border-radius: 12px; padding: 30px; margin-top: 40px; max-width: 900px; margin-left: auto; margin-right: auto;">
<h3 style="color: #58a6ff; margin-bottom: 15px; font-size: 1.5rem;">Key Takeaways</h3>
<ul style="color: #8b949e; line-height: 2; list-style-position: inside;">
<li>✅ <strong style="color: #e6edf3;">Code scanning</strong> found 1614 security issues in LiteLLM's source</li>
<li>✅ <strong style="color: #e6edf3;">Dependency checking</strong> would flag compromised versions after CVE disclosure</li>
<li>⚠️ <strong style="color: #e6edf3;">Supply chain attacks</strong> require package-time detection (not just source scanning)</li>
<li>🛡️ <strong style="color: #e6edf3;">Defense in depth</strong>: Use both code scanning AND dependency checking</li>
</ul>
</div>
</div>
</section>
<section class="cta-section">
<div class="container">
<h2>Ready to Secure Your Code?</h2>
<p>Install in seconds. Start scanning immediately.</p>
<div class="buttons">
<a href="https://github.com/dinakars777/ai-code-guardian" class="btn btn-primary">
<span>Get Started →</span>
</a>
</div>
</div>
</section>
<footer>
<div class="container">
<p>Built with ❤️ by <a href="https://github.com/dinakars777">Dinakar Sarbada</a></p>
<p style="margin-top: 10px;">
<a href="https://github.com/dinakars777/ai-code-guardian">GitHub</a> •
<a href="https://crates.io/crates/ai-code-guardian">Crates.io</a> •
<a href="https://github.com/dinakars777/ai-code-guardian/issues">Report Issue</a>
</p>
</div>
</footer>
<script>
function showDemo(type) {
document.querySelectorAll('.demo-output').forEach(el => {
el.classList.remove('active');
});
document.querySelectorAll('.demo-tab').forEach(el => {
el.classList.remove('active');
});
document.getElementById('demo-' + type).classList.add('active');
event.target.classList.add('active');
}
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -100px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.animation = 'fadeInUp 0.8s ease-out both';
}
});
}, observerOptions);
document.querySelectorAll('.feature').forEach(el => {
observer.observe(el);
});
</script>
</body>
</html>