cbom-builder / index.html
gpetrizey's picture
Adjust layout and spacing for consistency in navigation and sidebar components.
61e0718
Raw
History Blame Contribute Delete
36.4 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quantum Safe - Your Quantum-Safe Migration Journey</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');
html {
scroll-behavior: smooth;
overflow-x: hidden;
}
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #334155 100%);
min-height: 100vh;
overflow-x: hidden;
overflow-y: auto;
margin: 0;
padding: 0;
}
.gradient-text {
background: linear-gradient(135deg, #F59E0B, #FBBF24, #FCD34D);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.phase-card {
backdrop-filter: blur(20px);
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.phase-card:hover {
background: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(245, 158, 11, 0.3);
transform: translateY(-8px);
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}
.phase-card.active {
background: rgba(245, 158, 11, 0.1);
border: 2px solid #F59E0B;
box-shadow: 0 0 30px rgba(245, 158, 11, 0.3);
}
.timeline-connector {
background: linear-gradient(90deg, #475569, #F59E0B, #475569);
height: 4px;
position: relative;
}
.timeline-progress {
background: linear-gradient(90deg, #F59E0B, #FBBF24);
height: 100%;
transition: width 1s ease-in-out;
position: relative;
}
.timeline-progress::after {
content: '';
position: absolute;
right: -8px;
top: -6px;
width: 16px;
height: 16px;
background: #F59E0B;
border-radius: 50%;
border: 3px solid #0f172a;
box-shadow: 0 0 20px rgba(245, 158, 11, 0.6);
}
.floating-element {
animation: float 6s ease-in-out infinite;
}
.floating-element:nth-child(2) {
animation-delay: -2s;
}
.floating-element:nth-child(3) {
animation-delay: -4s;
}
@keyframes float {
0%,
100% {
transform: translateY(0px) rotate(0deg);
}
50% {
transform: translateY(-20px) rotate(180deg);
}
}
.particle {
position: absolute;
width: 2px;
height: 2px;
background: #F59E0B;
border-radius: 50%;
animation: particle-float 8s linear infinite;
opacity: 0.7;
}
@keyframes particle-float {
0% {
transform: translateY(100vh) translateX(0px);
opacity: 0;
}
10% {
opacity: 0.7;
}
90% {
opacity: 0.7;
}
100% {
transform: translateY(-100px) translateX(100px);
opacity: 0;
}
}
.stat-card {
backdrop-filter: blur(15px);
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.08);
transition: all 0.3s ease;
}
.stat-card:hover {
background: rgba(255, 255, 255, 0.06);
transform: scale(1.02);
}
.action-button {
background: linear-gradient(135deg, #F59E0B, #FBBF24);
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(245, 158, 11, 0.3);
}
.action-button:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(245, 158, 11, 0.4);
}
.nav-item {
transition: all 0.3s ease;
position: relative;
}
.nav-item::after {
content: '';
position: absolute;
bottom: -2px;
left: 50%;
width: 0;
height: 2px;
background: #F59E0B;
transition: all 0.3s ease;
transform: translateX(-50%);
}
.nav-item:hover::after {
width: 100%;
}
/* Mobile-specific adjustments */
@media (max-width: 640px) {
.particle {
width: 1px;
height: 1px;
}
.floating-element {
transform: scale(0.6);
}
.phase-card {
padding: 1.5rem;
}
.timeline-progress::after {
width: 12px;
height: 12px;
}
}
/* Smooth scrolling for the entire page */
html {
scroll-behavior: smooth;
}
/* Back to top button */
.back-to-top {
position: fixed;
bottom: 2rem;
right: 2rem;
width: 48px;
height: 48px;
background: linear-gradient(135deg, #F59E0B, #FBBF24);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
z-index: 1000;
box-shadow: 0 4px 15px rgba(245, 158, 11, 0.3);
}
.back-to-top:hover {
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(245, 158, 11, 0.4);
}
.back-to-top.show {
opacity: 1;
visibility: visible;
}
.back-to-top svg {
width: 20px;
height: 20px;
stroke: #0f172a;
stroke-width: 3;
}
@media (max-width: 640px) {
.back-to-top {
bottom: 1.5rem;
right: 1.5rem;
width: 40px;
height: 40px;
}
.back-to-top svg {
width: 16px;
height: 16px;
}
}
/* Fix select dropdown styling */
select option {
background-color: #1e293b;
color: #ffffff;
}
select option:hover {
background-color: #334155;
}
/* For better cross-browser compatibility */
select {
background-color: rgba(255, 255, 255, 0.1);
}
select:focus {
background-color: rgba(255, 255, 255, 0.15);
}
</style>
</head>
<body>
<!-- Animated Background Particles -->
<div class="fixed inset-0 pointer-events-none">
<div class="particle" style="left: 10%; animation-delay: 0s;"></div>
<div class="particle" style="left: 20%; animation-delay: 1s;"></div>
<div class="particle" style="left: 30%; animation-delay: 2s;"></div>
<div class="particle" style="left: 40%; animation-delay: 3s;"></div>
<div class="particle" style="left: 50%; animation-delay: 4s;"></div>
<div class="particle" style="left: 60%; animation-delay: 5s;"></div>
<div class="particle" style="left: 70%; animation-delay: 6s;"></div>
<div class="particle" style="left: 80%; animation-delay: 7s;"></div>
<div class="particle" style="left: 90%; animation-delay: 8s;"></div>
</div>
<!-- Navigation - Add mobile menu button -->
<nav class="relative z-50 backdrop-filter backdrop-blur-lg bg-white/5 border-b border-white/10">
<div class="max-w-7xl mx-auto px-4 sm:px-6 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<div
class="w-10 h-10 rounded-full bg-gradient-to-r from-yellow-400 to-yellow-500 flex items-center justify-center">
<i data-feather="shield" class="text-gray-900 w-5 h-5"></i>
</div>
<h1 class="text-xl font-bold text-white"><span class="gradient-text">Quantum Safe</span></h1>
</div>
<!-- Mobile menu button -->
<button class="md:hidden text-white" onclick="toggleMobileMenu()">
<i data-feather="menu" class="w-6 h-6"></i>
</button>
<!-- Desktop menu -->
<div class="hidden md:flex items-center space-x-4 lg:space-x-8">
<a href="dashboard.html"
class="nav-item text-gray-300 hover:text-yellow-400 font-medium">Dashboard</a>
<a href="#phases" class="nav-item text-gray-300 hover:text-yellow-400 font-medium">Migration
Journey</a>
<a href="analytics.html"
class="nav-item text-gray-300 hover:text-yellow-400 font-medium">Analytics</a>
</div>
</div>
<!-- Mobile menu -->
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4">
<a href="dashboard.html"
class="block py-2 text-gray-300 hover:text-yellow-400 font-medium">Dashboard</a>
<a href="#phases" class="block py-2 text-gray-300 hover:text-yellow-400 font-medium">Migration
Journey</a>
<a href="analytics.html"
class="block py-2 text-gray-300 hover:text-yellow-400 font-medium">Analytics</a>
</div>
</div>
</nav>
<!-- Hero Section -->
<section class="relative min-h-screen flex items-center justify-center px-4 sm:px-6 py-12 sm:py-0">
<!-- Floating Elements -->
<div class="absolute inset-0 overflow-hidden pointer-events-none">
<div
class="floating-element absolute top-20 left-10 w-20 h-20 rounded-full bg-gradient-to-r from-yellow-400/20 to-yellow-600/20 blur-xl">
</div>
<div
class="floating-element absolute top-40 right-20 w-32 h-32 rounded-full bg-gradient-to-r from-blue-400/20 to-purple-600/20 blur-xl">
</div>
<div
class="floating-element absolute bottom-32 left-1/4 w-24 h-24 rounded-full bg-gradient-to-r from-green-400/20 to-teal-600/20 blur-xl">
</div>
</div>
<div class="relative z-10 max-w-6xl mx-auto text-center">
<h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl xl:text-8xl font-black text-white mb-6 leading-tight"
data-aos="fade-up">
Your <span class="gradient-text">Quantum-Safe</span><br>
Migration Journey
</h1>
<p class="text-base sm:text-lg md:text-xl lg:text-2xl text-gray-300 mb-8 sm:mb-12 max-w-4xl mx-auto leading-relaxed"
data-aos="fade-up" data-aos-delay="100">
Navigate the quantum threat landscape with confidence. Our comprehensive platform guides you through
discovery, assessment, and modernization of your cryptographic infrastructure.
</p>
<!-- Current Status Card -->
<div class="inline-block mb-8 sm:mb-16 w-full max-w-sm sm:max-w-md" data-aos="fade-up" data-aos-delay="200">
<a href="#discoveryninventory" class="block transition-transform hover:scale-105">
<div class="phase-card rounded-2xl p-6 sm:p-8 mx-auto cursor-pointer hover:border-yellow-400">
<div class="flex items-center justify-center mb-4">
<div
class="w-16 h-16 rounded-full bg-gradient-to-r from-yellow-400 to-yellow-500 flex items-center justify-center">
<i data-feather="target" class="text-gray-900 w-8 h-8"></i>
</div>
</div>
<h3 class="text-2xl font-bold text-white mb-2">Current Phase</h3>
<p class="text-yellow-400 text-lg font-semibold mb-2">Discovery & Inventory</p>
<p class="text-gray-300 text-sm">67% Complete</p>
<div class="mt-4 bg-gray-700 rounded-full h-2">
<div class="bg-gradient-to-r from-yellow-400 to-yellow-500 h-2 rounded-full"
style="width: 67%">
</div>
</div>
</div>
</a>
</div>
<!-- Quick Stats -->
<div class="grid grid-cols-2 sm:grid-cols-2 md:grid-cols-4 gap-4 sm:gap-6 mb-8 sm:mb-12" data-aos="fade-up"
data-aos-delay="300">
<div class="stat-card rounded-xl p-4 sm:p-6 text-center">
<div class="text-2xl sm:text-3xl font-bold text-white mb-1 sm:mb-2">24</div>
<div class="text-gray-400 text-xs sm:text-sm">Active CBOMs</div>
</div>
<div class="stat-card rounded-xl p-6 text-center">
<div class="text-3xl font-bold text-white mb-2">1,284</div>
<div class="text-gray-400 text-sm">Crypto Assets</div>
</div>
<div class="stat-card rounded-xl p-6 text-center">
<div class="text-3xl font-bold text-yellow-400 mb-2">154</div>
<div class="text-gray-400 text-sm">High Risk</div>
</div>
<div class="stat-card rounded-xl p-6 text-center">
<div class="text-3xl font-bold text-green-400 mb-2">693</div>
<div class="text-gray-400 text-sm">Quantum Secure</div>
</div>
</div>
<!-- Action Button -->
<a href="dashboard.html"
class="action-button text-gray-900 font-bold py-3 px-6 sm:py-4 sm:px-8 rounded-xl text-base sm:text-lg"
data-aos="fade-up" data-aos-delay="400">
<i data-feather="arrow-right" class="w-4 h-4 sm:w-5 sm:h-5 inline mr-2"></i>
Continue Journey
</a>
</div>
</section>
<!-- Migration Timeline -->
<section id="phases" class="py-12 sm:py-20 px-4 sm:px-6">
<div class="max-w-7xl mx-auto">
<div class="text-center mb-12 sm:mb-16" data-aos="fade-up">
<h2 class="text-3xl sm:text-4xl md:text-5xl font-black text-white mb-4 sm:mb-6">Migration <span
class="gradient-text">Phases</span></h2>
<p class="text-base sm:text-lg md:text-xl text-gray-300 max-w-3xl mx-auto">
A structured approach to quantum-safe transformation, from discovery through modernization
</p>
</div>
<!-- Progress Timeline -->
<div class="mb-12 sm:mb-16" data-aos="fade-up" data-aos-delay="100">
<div class="timeline-connector mx-auto max-w-4xl rounded-full">
<div class="timeline-progress rounded-full" style="width: 67%"></div>
</div>
<div class="flex justify-between max-w-4xl mx-auto mt-4 text-center text-sm sm:text-base">
<div class="text-yellow-400 font-semibold">Phase 1</div>
<div class="text-gray-500 font-semibold hidden sm:block">Phase 2</div>
<div class="text-gray-500 font-semibold">Phase 3</div>
</div>
</div>
<!-- Phase Cards -->
<div id="discoveryninventory" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8">
<!-- Phase 1: Discovery & Inventory -->
<div class="phase-card active rounded-2xl p-8 transition-all duration-500" data-aos="fade-up"
data-aos-delay="150">
<div class="flex items-center justify-between mb-6">
<div
class="w-16 h-16 rounded-full bg-gradient-to-r from-blue-400 to-blue-500 flex items-center justify-center">
<i data-feather="search" class="text-white w-8 h-8"></i>
</div>
<span
class="text-yellow-400 font-bold text-sm px-3 py-1 bg-yellow-400/20 rounded-full">ACTIVE</span>
</div>
<h3 class="text-2xl font-bold text-white mb-4">Discovery & Inventory</h3>
<p class="text-gray-300 mb-6 leading-relaxed">
Comprehensive identification and cataloging of all cryptographic assets across your
infrastructure using automated discovery tools.
</p>
<div class="mb-6">
<div class="flex justify-between text-sm text-gray-400 mb-2">
<span>Progress</span>
<span>67%</span>
</div>
<div class="bg-gray-700 rounded-full h-2">
<div class="bg-gradient-to-r from-blue-400 to-blue-500 h-2 rounded-full" style="width: 67%">
</div>
</div>
</div>
<div class="space-y-3 mb-8">
<div class="flex items-center space-x-3">
<i data-feather="check-circle" class="text-green-400 w-5 h-5"></i>
<span class="text-gray-300">CBOMs Management</span>
</div>
<div class="flex items-center space-x-3">
<i data-feather="check-circle" class="text-green-400 w-5 h-5"></i>
<span class="text-gray-300">Assets Cataloging</span>
</div>
<div class="flex items-center space-x-3">
<i data-feather="clock" class="text-yellow-400 w-5 h-5"></i>
<span class="text-gray-300">Tool Integrations</span>
</div>
</div>
<div class="space-y-2">
<a href="cboms.html"
class="block w-full text-center py-2 px-4 bg-blue-600 hover:bg-blue-500 text-white rounded-lg transition-colors">
<i data-feather="file-text" class="w-4 h-4 inline mr-2"></i>
CBOMs
</a>
<a href="assets.html"
class="block w-full text-center py-2 px-4 bg-blue-600 hover:bg-blue-500 text-white rounded-lg transition-colors">
<i data-feather="lock" class="w-4 h-4 inline mr-2"></i>
Assets
</a>
<a href="integrations.html"
class="block w-full text-center py-2 px-4 bg-blue-600 hover:bg-blue-500 text-white rounded-lg transition-colors">
<i data-feather="link" class="w-4 h-4 inline mr-2"></i>
Integrations
</a>
</div>
</div>
<!-- Phase 2: Risk Assessment -->
<div class="phase-card rounded-2xl p-8 transition-all duration-500" data-aos="fade-up"
data-aos-delay="200">
<div class="flex items-center justify-between mb-6">
<div
class="w-16 h-16 rounded-full bg-gradient-to-r from-red-400 to-red-500 flex items-center justify-center">
<i data-feather="alert-triangle" class="text-white w-8 h-8"></i>
</div>
<span
class="text-gray-500 font-bold text-sm px-3 py-1 bg-gray-500/20 rounded-full">PENDING</span>
</div>
<h3 class="text-2xl font-bold text-white mb-4">Risk Assessment</h3>
<p class="text-gray-300 mb-6 leading-relaxed">
Quantum-aware risk scoring and analysis of discovered cryptographic assets to prioritize
migration efforts.
</p>
<div class="mb-6">
<div class="flex justify-between text-sm text-gray-400 mb-2">
<span>Progress</span>
<span>0%</span>
</div>
<div class="bg-gray-700 rounded-full h-2">
<div class="bg-gray-600 h-2 rounded-full" style="width: 0%"></div>
</div>
</div>
<div class="space-y-3 mb-8">
<div class="flex items-center space-x-3">
<i data-feather="circle" class="text-gray-500 w-5 h-5"></i>
<span class="text-gray-400">Quantum Threat Analysis</span>
</div>
<div class="flex items-center space-x-3">
<i data-feather="circle" class="text-gray-500 w-5 h-5"></i>
<span class="text-gray-400">Risk Scoring</span>
</div>
<div class="flex items-center space-x-3">
<i data-feather="circle" class="text-gray-500 w-5 h-5"></i>
<span class="text-gray-400">Priority Matrix</span>
</div>
</div>
<div class="space-y-2">
<a href="assets.html"
class="block w-full text-center py-2 px-4 bg-gray-700 text-gray-400 rounded-lg">
<i data-feather="bar-chart-2" class="w-4 h-4 inline mr-2"></i>
Risk Assessment
</a>
<a href="analytics.html"
class="block w-full text-center py-2 px-4 bg-gray-700 text-gray-400 rounded-lg">
<i data-feather="trending-up" class="w-4 h-4 inline mr-2"></i>
Analytics
</a>
</div>
</div>
<!-- Phase 3: Migration & Modernization -->
<div class="phase-card rounded-2xl p-8 transition-all duration-500" data-aos="fade-up"
data-aos-delay="250">
<div class="flex items-center justify-between mb-6">
<div
class="w-16 h-16 rounded-full bg-gradient-to-r from-green-400 to-green-500 flex items-center justify-center">
<i data-feather="refresh-cw" class="text-white w-8 h-8"></i>
</div>
<span
class="text-gray-500 font-bold text-sm px-3 py-1 bg-gray-500/20 rounded-full">FUTURE</span>
</div>
<h3 class="text-2xl font-bold text-white mb-4">Migration & Modernization</h3>
<p class="text-gray-300 mb-6 leading-relaxed">
Automated replacement of quantum-vulnerable assets with quantum-resistant alternatives through
intelligent tooling.
</p>
<div class="mb-6">
<div class="flex justify-between text-sm text-gray-400 mb-2">
<span>Progress</span>
<span>0%</span>
</div>
<div class="bg-gray-700 rounded-full h-2">
<div class="bg-gray-600 h-2 rounded-full" style="width: 0%"></div>
</div>
</div>
<div class="space-y-3 mb-8">
<div class="flex items-center space-x-3">
<i data-feather="circle" class="text-gray-500 w-5 h-5"></i>
<span class="text-gray-400">Automated Migration</span>
</div>
<div class="flex items-center space-x-3">
<i data-feather="circle" class="text-gray-500 w-5 h-5"></i>
<span class="text-gray-400">Quantum-Resistant Deployment</span>
</div>
<div class="flex items-center space-x-3">
<i data-feather="circle" class="text-gray-500 w-5 h-5"></i>
<span class="text-gray-400">Validation & Testing</span>
</div>
</div>
<div class="space-y-2">
<a href="modernization-tools.html"
class="block w-full text-center py-2 px-4 bg-gray-700 text-gray-400 rounded-lg">
<i data-feather="tool" class="w-4 h-4 inline mr-2"></i>
Modernization Tools
</a>
<a href="validation.html"
class="block w-full text-center py-2 px-4 bg-gray-700 text-gray-400 rounded-lg">
<i data-feather="check-square" class="w-4 h-4 inline mr-2"></i>
Validation
</a>
</div>
</div>
</div>
</div>
</section>
<!-- Quick Actions Section -->
<section class="py-12 sm:py-20 px-4 sm:px-6 bg-gradient-to-r from-gray-900/50 to-gray-800/50">
<div class="max-w-7xl mx-auto">
<div class="text-center mb-12 sm:mb-16" data-aos="fade-up">
<h2 class="text-3xl sm:text-4xl font-black text-white mb-4 sm:mb-6">Quick <span
class="gradient-text">Actions</span>
</h2>
<p class="text-base sm:text-lg text-gray-300">Jump directly to key tasks in your current phase</p>
</div>
<div class="grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6" data-aos="fade-up"
data-aos-delay="100">
<button
class="action-button text-gray-900 font-semibold py-4 px-3 sm:py-6 sm:px-6 rounded-xl text-center transition-all hover:scale-105">
<div class="flex flex-col items-center">
<i data-feather="plus" class="w-6 h-6 sm:w-8 sm:h-8 mb-2 sm:mb-3"></i>
<span class="text-sm sm:text-base">New CBOM</span>
</div>
</button>
<a href="assets.html"
class="action-button text-gray-900 font-semibold py-4 px-3 sm:py-6 sm:px-6 rounded-xl text-center transition-all hover:scale-105">
<div class="flex flex-col items-center">
<i data-feather="download" class="w-6 h-6 sm:w-8 sm:h-8 mb-2 sm:mb-3"></i>
<span>Import Assets</span>
</div>
</a>
<a href="integrations.html"
class="action-button text-gray-900 font-semibold py-4 px-3 sm:py-6 sm:px-6 rounded-xl text-center transition-all hover:scale-105">
<div class="flex flex-col items-center">
<i data-feather="link" class="w-6 h-6 sm:w-8 sm:h-8 mb-2 sm:mb-3"></i>
<span>Connect Tools</span>
</div>
</a>
<a href="analytics.html"
class="action-button text-gray-900 font-semibold py-4 px-3 sm:py-6 sm:px-6 rounded-xl text-center transition-all hover:scale-105">
<div class="flex flex-col items-center">
<i data-feather="bar-chart-2" class="w-6 h-6 sm:w-8 sm:h-8 mb-2 sm:mb-3"></i>
<span>View Analytics</span>
</div>
</a>
</div>
</div>
</section>
<!-- Back to Top Button -->
<button class="back-to-top" onclick="scrollToTop()" aria-label="Back to top">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M5 10l7-7m0 0l7 7m-7-7v18" />
</svg>
</button>
<script>
// Initialize AOS animations with faster settings
AOS.init({
duration: 400, // Reduced from 600ms to 400ms
once: false, // Changed to false so animations replay on scroll
offset: 20, // Reduced from 50 to trigger animations sooner
easing: 'ease-out-cubic', // Smoother easing function
anchorPlacement: 'top-bottom'
});
// Initialize Feather icons
feather.replace();
// Smooth scrolling for navigation links with improved performance
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const target = document.querySelector(targetId);
if (target) {
// Calculate offset for fixed navigation
const navHeight = document.querySelector('nav').offsetHeight;
const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - navHeight - 20;
// Smooth scroll with custom duration based on distance
const startPosition = window.pageYOffset;
const distance = targetPosition - startPosition;
const duration = Math.min(Math.max(Math.abs(distance) / 3, 400), 1000);
smoothScrollTo(targetPosition, duration);
}
});
});
// Custom smooth scroll function
function smoothScrollTo(targetPosition, duration) {
const startPosition = window.pageYOffset;
const distance = targetPosition - startPosition;
const startTime = performance.now();
function scrollAnimation(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
// Easing function for smooth deceleration
const easeProgress = 1 - Math.pow(1 - progress, 3);
window.scrollTo(0, startPosition + (distance * easeProgress));
if (progress < 1) {
requestAnimationFrame(scrollAnimation);
}
}
requestAnimationFrame(scrollAnimation);
}
// Back to top button functionality
const backToTopButton = document.querySelector('.back-to-top');
// Show/hide back to top button
window.addEventListener('scroll', () => {
if (window.pageYOffset > 300) {
backToTopButton.classList.add('show');
} else {
backToTopButton.classList.remove('show');
}
});
// Scroll to top function
function scrollToTop() {
smoothScrollTo(0, 600);
}
// Phase progress simulation
function updatePhaseProgress() {
const phases = [
{ id: 'phase1', progress: 67, status: 'active' },
{ id: 'phase2', progress: 0, status: 'pending' },
{ id: 'phase3', progress: 0, status: 'future' }
];
// Simulate real-time updates (in a real app, this would come from your backend)
setInterval(() => {
if (phases[0].progress < 100) {
phases[0].progress += Math.random() * 2;
if (phases[0].progress > 100) phases[0].progress = 100;
}
}, 5000);
}
updatePhaseProgress();
// Add dynamic background gradient based on scroll with throttling
let ticking = false;
function updateBackgroundPosition() {
if (!ticking) {
window.requestAnimationFrame(() => {
const scrolled = window.pageYOffset;
const rate = scrolled * -0.1;
document.body.style.backgroundPositionY = rate + 'px';
ticking = false;
});
ticking = true;
}
}
window.addEventListener('scroll', updateBackgroundPosition);
// Add click handlers for action buttons
document.querySelectorAll('.action-button').forEach(button => {
button.addEventListener('click', function () {
// Add ripple effect
const ripple = document.createElement('span');
const rect = this.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
ripple.style.width = ripple.style.height = size + 'px';
ripple.style.left = (event.clientX - rect.left - size / 2) + 'px';
ripple.style.top = (event.clientY - rect.top - size / 2) + 'px';
ripple.classList.add('ripple');
this.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
});
});
// Mobile menu toggle
function toggleMobileMenu() {
const menu = document.getElementById('mobileMenu');
menu.classList.toggle('hidden');
}
// Close mobile menu when clicking outside
document.addEventListener('click', function (event) {
const nav = document.querySelector('nav');
const menu = document.getElementById('mobileMenu');
if (!nav.contains(event.target) && !menu.classList.contains('hidden')) {
menu.classList.add('hidden');
}
});
// Optimize scroll performance with passive listeners
window.addEventListener('scroll', updateBackgroundPosition, { passive: true });
// Preload animations for sections about to come into view
const observerOptions = {
root: null,
rootMargin: '50px',
threshold: 0
};
const animationObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// Force AOS to check this element
AOS.refreshHard();
}
});
}, observerOptions);
// Observe all AOS elements
document.querySelectorAll('[data-aos]').forEach(el => {
animationObserver.observe(el);
});
</script>
<style>
.ripple {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
transform: scale(0);
animation: ripple-animation 0.6s linear;
pointer-events: none;
}
@keyframes ripple-animation {
to {
transform: scale(4);
opacity: 0;
}
}
</style>
</body>
</html>