<div class="timeline-wrapper">
<div class="header-space">Scroll to Trace</div>
<div class="timeline-content" id="timeline-container">
<svg class="timeline-svg" viewBox="0 0 100 1000" preserveAspectRatio="none">
<path id="base-path" d="M 50 0 C 90 200, 10 400, 50 600 C 90 800, 10 900, 50 1000" fill="none" stroke="rgba(255, 255, 255, 0.05)" stroke-width="4"></path>
<path id="glow-path" d="M 50 0 C 90 200, 10 400, 50 600 C 90 800, 10 900, 50 1000" fill="none" stroke="#10b981" stroke-width="4"></path>
</svg>
<div class="timeline-item" style="top: 20%;">
<h3>Planning Phase</h3>
<p>We strategize and outline the core architecture flawlessly.</p>
</div>
<div class="timeline-item right-side" style="top: 50%;">
<h3>Development</h3>
<p>We build out the structural components gracefully.</p>
</div>
<div class="timeline-item" style="top: 80%;">
<h3>Launch Ready</h3>
<p>The project finally goes live to the entire world.</p>
</div>
</div>
<div class="header-space">End of Journey</div>
</div>
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
margin: 0;
background: #0f172a;
color: #ffffff;
}
.header-space {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 2rem;
font-weight: 700;
color: #64748b;
text-transform: uppercase;
letter-spacing: 4px;
}
.timeline-wrapper {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.timeline-content {
position: relative;
width: 100%;
max-width: 800px;
height: 1500px;
margin: 0 auto;
}
.timeline-svg {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 100px;
height: 100%;
overflow: visible;
}
#glow-path {
stroke-linecap: round;
filter: drop-shadow(0 0 12px #10b981);
transition: stroke-dashoffset 0.1s linear;
}
.timeline-item {
position: absolute;
left: calc(50% + 80px);
width: 300px;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
padding: 24px;
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
.timeline-item.right-side {
left: auto;
right: calc(50% + 80px);
text-align: right;
}
.timeline-item h3 {
margin: 0 0 8px 0;
color: #10b981;
font-size: 1.5rem;
}
.timeline-item p {
margin: 0;
color: #cbd5e1;
line-height: 1.6;
}
@media (max-width: 800px) {
.timeline-svg { left: 40px; transform: none; }
.timeline-item, .timeline-item.right-side { left: 120px; right: auto; text-align: left; width: calc(100% - 160px); }
}
const path = document.getElementById("glow-path");
const container = document.getElementById("timeline-container");
const pathLength = path.getTotalLength();
// Setup the initial drawing state
path.style.strokeDasharray = pathLength;
path.style.strokeDashoffset = pathLength;
window.addEventListener("scroll", function() {
const rect = container.getBoundingClientRect();
const top = rect.top;
const height = rect.height;
const windowHeight = window.innerHeight;
// Calculate how much of the container is visible
let progress = (windowHeight - top) / (height + windowHeight);
if (progress < 0) progress = 0;
if (progress > 1) progress = 1;
// Update the dash offset to draw the SVG naturally
const drawLength = pathLength * progress;
path.style.strokeDashoffset = pathLength - drawLength;
});