Neha Singh
resume-screening-system
263eb11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HireScope AI — Intelligent Resume Screening</title>
<meta name="description" content="AI-powered resume screening system with semantic matching, skill extraction, and audio transcription.">
<!-- Google Fonts -->
<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">
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
colors: {
brand: {
50: '#eef2ff',
100: '#e0e7ff',
200: '#c7d2fe',
300: '#a5b4fc',
400: '#818cf8',
500: '#6366f1',
600: '#4f46e5',
700: '#4338ca',
800: '#3730a3',
900: '#312e81',
},
sky: {
50: '#f0f9ff',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
}
}
}
}
}
</script>
<style>
* { font-family: 'Inter', system-ui, sans-serif; }
body {
background: linear-gradient(135deg, #f0f4f8 0%, #e8edf5 50%, #f0f0ff 100%);
min-height: 100vh;
}
.glass-card {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.9);
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
}
.glass-card:hover {
box-shadow: 0 8px 40px rgba(99, 102, 241, 0.08), 0 2px 8px rgba(0, 0, 0, 0.06);
}
.gradient-text {
background: linear-gradient(135deg, #6366f1, #0ea5e9);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.nav-glass {
background: rgba(255, 255, 255, 0.92);
backdrop-filter: blur(24px);
-webkit-backdrop-filter: blur(24px);
border-bottom: 1px solid rgba(226, 232, 240, 0.8);
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes slideInRight {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes pulse-soft {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.animate-fade-in-up { animation: fadeInUp 0.5s ease-out forwards; }
.animate-fade-in-up-delay { animation: fadeInUp 0.5s ease-out 0.1s forwards; opacity: 0; }
.animate-fade-in-up-delay-2 { animation: fadeInUp 0.5s ease-out 0.2s forwards; opacity: 0; }
.animate-slide-in { animation: slideInRight 0.4s ease-out forwards; }
.animate-pulse-soft { animation: pulse-soft 2s ease-in-out infinite; }
/* Custom scrollbar */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
/* Smooth transitions for interactive elements */
.btn-primary {
background: linear-gradient(135deg, #6366f1, #4f46e5);
transition: all 0.3s ease;
}
.btn-primary:hover {
background: linear-gradient(135deg, #818cf8, #6366f1);
box-shadow: 0 8px 25px rgba(99, 102, 241, 0.3);
transform: translateY(-1px);
}
.btn-secondary {
background: linear-gradient(135deg, #0ea5e9, #0284c7);
transition: all 0.3s ease;
}
.btn-secondary:hover {
background: linear-gradient(135deg, #38bdf8, #0ea5e9);
box-shadow: 0 8px 25px rgba(14, 165, 233, 0.3);
transform: translateY(-1px);
}
/* Flash message styles */
.flash-success { background: linear-gradient(135deg, #ecfdf5, #d1fae5); border-left: 4px solid #10b981; }
.flash-error { background: linear-gradient(135deg, #fef2f2, #fecaca); border-left: 4px solid #ef4444; }
.flash-info { background: linear-gradient(135deg, #eff6ff, #dbeafe); border-left: 4px solid #3b82f6; }
.flash-warning { background: linear-gradient(135deg, #fffbeb, #fef3c7); border-left: 4px solid #f59e0b; }
/* Mobile menu */
.mobile-menu { display: none; }
.mobile-menu.open { display: flex; }
/* Modal backdrop */
.modal-backdrop {
background: rgba(15, 23, 42, 0.5);
backdrop-filter: blur(4px);
}
/* Skill tag animation */
.skill-tag {
transition: all 0.2s ease;
}
.skill-tag:hover {
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(99, 102, 241, 0.2);
}
</style>
</head>
<body class="min-h-screen flex flex-col font-sans antialiased text-slate-800">
<!-- Navigation -->
<nav class="nav-glass sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<!-- Logo -->
<div class="flex items-center gap-3">
<div class="bg-gradient-to-br from-brand-500 to-sky-500 p-2 rounded-xl shadow-lg shadow-brand-200">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
</div>
<a href="/" class="text-xl font-extrabold gradient-text tracking-tight">HireScope AI</a>
</div>
<!-- Desktop Navigation -->
<div class="hidden md:flex items-center gap-2">
{% if session.get('user_id') %}
<a href="/" class="px-4 py-2 text-slate-600 hover:text-brand-600 hover:bg-brand-50 rounded-lg transition font-medium text-sm">
<span class="flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"></path></svg>
Upload
</span>
</a>
<a href="/results" class="px-4 py-2 text-slate-600 hover:text-brand-600 hover:bg-brand-50 rounded-lg transition font-medium text-sm">
<span class="flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path></svg>
Results
</span>
</a>
<a href="/ranking" class="px-4 py-2 text-slate-600 hover:text-brand-600 hover:bg-brand-50 rounded-lg transition font-medium text-sm flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"></path></svg>
Leaderboard
{% if candidate_count is defined and candidate_count > 0 %}
<span class="bg-brand-500 text-white text-xs px-2 py-0.5 rounded-full font-semibold">{{ candidate_count }}</span>
{% endif %}
</a>
<div class="pl-3 ml-2 border-l border-slate-200 flex items-center gap-3">
<div class="flex items-center gap-2 bg-slate-100 px-3 py-1.5 rounded-lg">
<div class="w-7 h-7 bg-gradient-to-br from-brand-500 to-sky-500 rounded-full flex items-center justify-center text-white text-xs font-bold">
{{ session.username[0]|upper }}
</div>
<span class="text-sm font-medium text-slate-700">{{ session.username }}</span>
</div>
<a href="/logout" class="text-sm text-red-500 hover:text-red-600 hover:bg-red-50 px-3 py-1.5 rounded-lg transition font-medium">Log out</a>
</div>
{% else %}
<a href="/login" class="px-4 py-2 text-slate-600 hover:text-brand-600 font-medium text-sm rounded-lg hover:bg-brand-50 transition">Sign In</a>
<a href="/register" class="btn-primary text-white px-5 py-2 rounded-lg text-sm font-semibold shadow-md">Sign Up Free</a>
{% endif %}
</div>
<!-- Mobile Hamburger -->
<button onclick="document.getElementById('mobile-nav').classList.toggle('open')" class="md:hidden p-2 rounded-lg hover:bg-slate-100 transition">
<svg class="w-6 h-6 text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
</button>
</div>
<!-- Mobile Menu -->
<div id="mobile-nav" class="mobile-menu flex-col gap-2 pb-4 md:hidden">
{% if session.get('user_id') %}
<a href="/" class="px-4 py-2 text-slate-600 hover:bg-brand-50 rounded-lg font-medium text-sm">Upload</a>
<a href="/results" class="px-4 py-2 text-slate-600 hover:bg-brand-50 rounded-lg font-medium text-sm">Results</a>
<a href="/ranking" class="px-4 py-2 text-slate-600 hover:bg-brand-50 rounded-lg font-medium text-sm">Leaderboard</a>
<a href="/logout" class="px-4 py-2 text-red-500 hover:bg-red-50 rounded-lg font-medium text-sm">Log out</a>
{% else %}
<a href="/login" class="px-4 py-2 text-slate-600 hover:bg-brand-50 rounded-lg font-medium text-sm">Sign In</a>
<a href="/register" class="px-4 py-2 text-brand-600 hover:bg-brand-50 rounded-lg font-medium text-sm">Sign Up</a>
{% endif %}
</div>
</div>
</nav>
<!-- Flash Messages -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="max-w-5xl mx-auto mt-6 px-4 w-full space-y-3">
{% for category, message in messages %}
<div class="flash-{{ category }} px-5 py-4 rounded-xl flex items-center gap-3 animate-slide-in shadow-sm">
{% if category == 'success' %}
<svg class="w-5 h-5 text-emerald-600 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="text-emerald-800 font-medium text-sm">{{ message }}</span>
{% elif category == 'error' %}
<svg class="w-5 h-5 text-red-600 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="text-red-800 font-medium text-sm">{{ message }}</span>
{% elif category == 'warning' %}
<svg class="w-5 h-5 text-amber-600 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"></path></svg>
<span class="text-amber-800 font-medium text-sm">{{ message }}</span>
{% else %}
<svg class="w-5 h-5 text-blue-600 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span class="text-blue-800 font-medium text-sm">{{ message }}</span>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<!-- Main Content -->
<main class="flex-grow flex flex-col pt-6 pb-16">
{% block content %}{% endblock %}
</main>
<!-- Footer -->
<footer class="border-t border-slate-200 bg-white/60 backdrop-blur py-6">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
<div class="flex items-center gap-2">
<div class="bg-gradient-to-br from-brand-500 to-sky-500 p-1.5 rounded-lg">
<svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
</div>
<span class="text-sm font-semibold gradient-text">HireScope AI</span>
</div>
<p class="text-xs text-slate-400">Built with Semantic AI, Whisper & Sentence-Transformers</p>
</div>
</div>
</footer>
</body>
</html>