GradicAI / index.html
asna14's picture
Upload folder using huggingface_hub
e671eb4 verified
Raw
History Blame Contribute Delete
20.3 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GradicAI β€” AI Proctoring Model</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<style>
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--bg-primary: #0f0f1a;
--bg-secondary: #1a1a2e;
--bg-card: rgba(30, 30, 50, 0.7);
--text-primary: #f0f0f5;
--text-secondary: #a0a0b8;
--accent-indigo: #667eea;
--accent-purple: #764ba2;
--accent-cyan: #06d6a0;
--accent-amber: #f59e0b;
--accent-red: #ef4444;
--border-color: rgba(102, 126, 234, 0.2);
--glow-indigo: rgba(102, 126, 234, 0.15);
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.7;
min-height: 100vh;
overflow-x: hidden;
}
/* Animated background */
body::before {
content: '';
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background:
radial-gradient(ellipse at 20% 20%, rgba(102, 126, 234, 0.08) 0%, transparent 50%),
radial-gradient(ellipse at 80% 80%, rgba(118, 75, 162, 0.08) 0%, transparent 50%),
radial-gradient(ellipse at 50% 50%, rgba(6, 214, 160, 0.03) 0%, transparent 50%);
z-index: -1;
animation: bgPulse 8s ease-in-out infinite alternate;
}
@keyframes bgPulse {
0% { opacity: 0.7; }
100% { opacity: 1; }
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 2rem 1.5rem;
}
/* Hero Section */
.hero {
text-align: center;
padding: 3rem 0 2.5rem;
position: relative;
}
.hero-badge {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.4rem 1rem;
background: rgba(102, 126, 234, 0.1);
border: 1px solid rgba(102, 126, 234, 0.3);
border-radius: 50px;
font-size: 0.8rem;
font-weight: 500;
color: var(--accent-indigo);
margin-bottom: 1.5rem;
letter-spacing: 0.05em;
text-transform: uppercase;
}
.hero-badge .dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent-cyan);
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(0.8); }
}
.hero h1 {
font-size: 3rem;
font-weight: 800;
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #06d6a0 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 0.75rem;
letter-spacing: -0.02em;
}
.hero p {
font-size: 1.15rem;
color: var(--text-secondary);
max-width: 600px;
margin: 0 auto;
}
/* Model Stats Bar */
.stats-bar {
display: flex;
justify-content: center;
gap: 2rem;
margin: 2rem 0;
flex-wrap: wrap;
}
.stat {
text-align: center;
padding: 0.75rem 1.25rem;
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 12px;
backdrop-filter: blur(10px);
min-width: 120px;
transition: transform 0.2s, border-color 0.3s;
}
.stat:hover {
transform: translateY(-2px);
border-color: var(--accent-indigo);
}
.stat-value {
font-size: 1.4rem;
font-weight: 700;
color: var(--accent-indigo);
}
.stat-label {
font-size: 0.75rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-top: 0.15rem;
}
/* Cards */
.card {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 16px;
padding: 1.75rem;
margin-bottom: 1.5rem;
backdrop-filter: blur(10px);
transition: border-color 0.3s;
}
.card:hover {
border-color: rgba(102, 126, 234, 0.4);
}
.card h2 {
font-size: 1.3rem;
font-weight: 700;
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.6rem;
}
.card h2 .icon {
font-size: 1.4rem;
}
/* Detection Table */
.detection-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 0.75rem;
}
.detection-item {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.85rem 1rem;
background: rgba(15, 15, 26, 0.5);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 10px;
transition: all 0.2s;
}
.detection-item:hover {
background: rgba(102, 126, 234, 0.08);
border-color: rgba(102, 126, 234, 0.2);
transform: translateX(4px);
}
.detection-icon {
font-size: 1.5rem;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
flex-shrink: 0;
}
.detection-icon.warning { background: rgba(245, 158, 11, 0.15); }
.detection-icon.danger { background: rgba(239, 68, 68, 0.15); }
.detection-icon.info { background: rgba(102, 126, 234, 0.15); }
.detection-label {
font-weight: 500;
font-size: 0.9rem;
}
.detection-desc {
font-size: 0.78rem;
color: var(--text-secondary);
}
/* Code Block */
.code-block {
background: #0d0d1a;
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: 12px;
overflow: hidden;
}
.code-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.6rem 1rem;
background: rgba(255, 255, 255, 0.03);
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.code-lang {
font-size: 0.75rem;
color: var(--accent-indigo);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.copy-btn {
background: none;
border: 1px solid rgba(255, 255, 255, 0.1);
color: var(--text-secondary);
padding: 0.25rem 0.6rem;
border-radius: 6px;
font-size: 0.72rem;
cursor: pointer;
transition: all 0.2s;
font-family: inherit;
}
.copy-btn:hover {
background: rgba(102, 126, 234, 0.15);
color: var(--accent-indigo);
border-color: var(--accent-indigo);
}
.code-content {
padding: 1rem 1.25rem;
overflow-x: auto;
}
.code-content pre {
font-family: 'SF Mono', 'Fira Code', 'JetBrains Mono', monospace;
font-size: 0.82rem;
line-height: 1.6;
color: #c9d1d9;
white-space: pre;
}
.code-content .keyword { color: #ff7b72; }
.code-content .string { color: #a5d6ff; }
.code-content .comment { color: #8b949e; font-style: italic; }
.code-content .func { color: #d2a8ff; }
.code-content .var { color: #ffa657; }
/* Violation Flow */
.flow {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
flex-wrap: wrap;
padding: 1rem 0;
}
.flow-step {
padding: 0.5rem 1rem;
background: rgba(102, 126, 234, 0.1);
border: 1px solid rgba(102, 126, 234, 0.25);
border-radius: 8px;
font-size: 0.85rem;
font-weight: 500;
}
.flow-step.danger {
background: rgba(239, 68, 68, 0.1);
border-color: rgba(239, 68, 68, 0.25);
color: var(--accent-red);
}
.flow-arrow {
color: var(--text-secondary);
font-size: 1.2rem;
}
/* CTA / Download */
.cta-row {
display: flex;
gap: 1rem;
flex-wrap: wrap;
margin-top: 1.25rem;
}
.btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.7rem 1.5rem;
border-radius: 10px;
font-size: 0.9rem;
font-weight: 600;
text-decoration: none;
transition: all 0.2s;
border: none;
cursor: pointer;
font-family: inherit;
}
.btn-primary {
background: linear-gradient(135deg, var(--accent-indigo), var(--accent-purple));
color: white;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}
.btn-secondary {
background: rgba(255, 255, 255, 0.05);
color: var(--text-primary);
border: 1px solid var(--border-color);
}
.btn-secondary:hover {
background: rgba(102, 126, 234, 0.1);
border-color: var(--accent-indigo);
}
/* Footer */
.footer {
text-align: center;
padding: 2rem 0 1rem;
color: var(--text-secondary);
font-size: 0.82rem;
}
.footer a {
color: var(--accent-indigo);
text-decoration: none;
}
.footer a:hover {
text-decoration: underline;
}
/* Responsive */
@media (max-width: 640px) {
.hero h1 { font-size: 2rem; }
.stats-bar { gap: 0.75rem; }
.stat { min-width: 90px; padding: 0.5rem 0.75rem; }
.stat-value { font-size: 1.1rem; }
.detection-grid { grid-template-columns: 1fr; }
.container { padding: 1rem; }
}
</style>
</head>
<body>
<div class="container">
<!-- Hero -->
<div class="hero">
<div class="hero-badge">
<span class="dot"></span>
YOLOv8n Object Detection Model
</div>
<h1>πŸŽ“ GradicAI</h1>
<p>AI-powered exam proctoring with real-time object detection β€” detects phones, books, and multiple persons during online exams</p>
</div>
<!-- Stats -->
<div class="stats-bar">
<div class="stat">
<div class="stat-value">3.2M</div>
<div class="stat-label">Parameters</div>
</div>
<div class="stat">
<div class="stat-value">~6 MB</div>
<div class="stat-label">Model Size</div>
</div>
<div class="stat">
<div class="stat-value">80</div>
<div class="stat-label">COCO Classes</div>
</div>
<div class="stat">
<div class="stat-value">3</div>
<div class="stat-label">Used in Proctoring</div>
</div>
<div class="stat">
<div class="stat-value">640px</div>
<div class="stat-label">Input Size</div>
</div>
</div>
<!-- What It Detects -->
<div class="card">
<h2><span class="icon">πŸ”</span> What It Detects</h2>
<div class="detection-grid">
<div class="detection-item">
<div class="detection-icon warning">πŸ“±</div>
<div>
<div class="detection-label">Mobile Phone</div>
<div class="detection-desc">COCO class #67</div>
</div>
</div>
<div class="detection-item">
<div class="detection-icon warning">πŸ“–</div>
<div>
<div class="detection-label">Book / Notes</div>
<div class="detection-desc">COCO class #73</div>
</div>
</div>
<div class="detection-item">
<div class="detection-icon danger">πŸ‘₯</div>
<div>
<div class="detection-label">Multiple Persons</div>
<div class="detection-desc">COCO class #0 (count > 1)</div>
</div>
</div>
<div class="detection-item">
<div class="detection-icon info">🚫</div>
<div>
<div class="detection-label">No Person</div>
<div class="detection-desc">COCO class #0 (count = 0)</div>
</div>
</div>
</div>
</div>
<!-- Violation Flow -->
<div class="card">
<h2><span class="icon">⚑</span> Violation Flow</h2>
<p style="color: var(--text-secondary); margin-bottom: 0.75rem;">
The proctoring system issues up to 3 warnings before terminating the exam.
</p>
<div class="flow">
<span class="flow-step">Detection</span>
<span class="flow-arrow">β†’</span>
<span class="flow-step">⚠️ Warning 1</span>
<span class="flow-arrow">β†’</span>
<span class="flow-step">⚠️ Warning 2</span>
<span class="flow-arrow">β†’</span>
<span class="flow-step danger">🚫 Warning 3 β€” Terminated</span>
</div>
</div>
<!-- Usage -->
<div class="card">
<h2><span class="icon">πŸš€</span> Quick Start</h2>
<div class="code-block" style="margin-bottom: 1rem;">
<div class="code-header">
<span class="code-lang">bash</span>
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
</div>
<div class="code-content">
<pre>pip install ultralytics</pre>
</div>
</div>
<div class="code-block">
<div class="code-header">
<span class="code-lang">python</span>
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
</div>
<div class="code-content">
<pre><span class="keyword">from</span> ultralytics <span class="keyword">import</span> YOLO
<span class="keyword">from</span> huggingface_hub <span class="keyword">import</span> hf_hub_download
<span class="comment"># Download model from Hugging Face</span>
model_path = <span class="func">hf_hub_download</span>(
repo_id=<span class="string">"asna14/yolov8n-proctoring"</span>,
filename=<span class="string">"yolov8n.pt"</span>
)
<span class="comment"># Load and run inference</span>
model = <span class="func">YOLO</span>(model_path)
results = model(<span class="string">"exam_frame.jpg"</span>, conf=<span class="var">0.25</span>)
<span class="comment"># Process detections</span>
<span class="keyword">for</span> box <span class="keyword">in</span> results[<span class="var">0</span>].boxes:
cls = <span class="func">int</span>(box.cls[<span class="var">0</span>])
conf = <span class="func">float</span>(box.conf[<span class="var">0</span>])
label = results[<span class="var">0</span>].names[cls]
<span class="func">print</span>(<span class="string">f"Detected: </span>{label} ({conf:.2f})<span class="string">"</span>)</pre>
</div>
</div>
<div class="cta-row">
<a href="https://huggingface.co/asna14/yolov8n-proctoring" class="btn btn-primary" target="_blank">
πŸ“₯ Download Model
</a>
<a href="https://docs.ultralytics.com/" class="btn btn-secondary" target="_blank">
πŸ“š Ultralytics Docs
</a>
</div>
</div>
<!-- Tech Stack -->
<div class="card">
<h2><span class="icon">πŸ› </span> Part of GradicAI Platform</h2>
<p style="color: var(--text-secondary); margin-bottom: 1rem;">
This model powers the proctoring feature of <strong style="color: var(--text-primary);">GradicAI</strong> β€”
a full-stack AI exam & grading platform.
</p>
<div class="detection-grid">
<div class="detection-item">
<div class="detection-icon info">πŸ€–</div>
<div>
<div class="detection-label">AI Grading</div>
<div class="detection-desc">GPT-4o powered</div>
</div>
</div>
<div class="detection-item">
<div class="detection-icon info">πŸ“Ή</div>
<div>
<div class="detection-label">Live Proctoring</div>
<div class="detection-desc">YOLOv8 + WebSocket</div>
</div>
</div>
<div class="detection-item">
<div class="detection-icon info">πŸ“</div>
<div>
<div class="detection-label">Structured Exams</div>
<div class="detection-desc">Forms-style UI</div>
</div>
</div>
<div class="detection-item">
<div class="detection-icon info">πŸ“š</div>
<div>
<div class="detection-label">AI Quizzes</div>
<div class="detection-desc">Auto-generated</div>
</div>
</div>
</div>
</div>
<!-- Footer -->
<div class="footer">
<p>
<strong>GradicAI</strong> Β· Model: <a href="https://huggingface.co/asna14/yolov8n-proctoring">YOLOv8n</a> by
<a href="https://docs.ultralytics.com/">Ultralytics</a> Β·
Licensed under AGPL-3.0
</p>
</div>
</div>
<script>
function copyCode(btn) {
const codeBlock = btn.closest('.code-block');
const code = codeBlock.querySelector('pre').textContent;
navigator.clipboard.writeText(code).then(() => {
btn.textContent = 'Copied!';
btn.style.color = '#06d6a0';
btn.style.borderColor = '#06d6a0';
setTimeout(() => {
btn.textContent = 'Copy';
btn.style.color = '';
btn.style.borderColor = '';
}, 2000);
});
}
</script>
</body>
</html>