Task 4: Build final design skeleton with floating pill nav and typography
- Add floating pill nav bar (fixed, centered, 600px max-width, pill-shaped) - Add nav links for all 6 sections: About, Skills, Experience, Education, Projects, Contact - Add active state with teal dot indicator via ::after pseudo-element - Add IntersectionObserver for active section tracking (threshold 0.3, rootMargin -20%/0/-60%/0) - Add smooth scroll on nav link click (offset -70px for nav clearance) - Add main container with max-width 1000px and section padding - Add .section-heading utility class for consistent section titles - Add responsive breakpoints: 768px (scrollable nav, 20px padding) and 480px (compact nav, 16px padding) - Initialize nav tracking after ECG phase reveal completes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+213
-1
@@ -162,6 +162,126 @@
|
||||
opacity: 1;
|
||||
transition: opacity 600ms ease;
|
||||
}
|
||||
|
||||
/* =========================================
|
||||
FLOATING PILL NAV
|
||||
========================================= */
|
||||
|
||||
.pill-nav {
|
||||
position: fixed;
|
||||
top: 16px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 100;
|
||||
max-width: 600px;
|
||||
width: auto;
|
||||
background: var(--card-bg);
|
||||
border-radius: 999px;
|
||||
padding: 8px 24px;
|
||||
box-shadow: var(--shadow-md);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.pill-nav a {
|
||||
position: relative;
|
||||
font-family: var(--font-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
padding: 6px 14px;
|
||||
border-radius: 999px;
|
||||
transition: color 0.3s ease, background 0.3s ease;
|
||||
}
|
||||
|
||||
.pill-nav a:hover {
|
||||
color: var(--teal);
|
||||
background: var(--teal-light);
|
||||
}
|
||||
|
||||
.pill-nav a.active {
|
||||
color: var(--teal);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.pill-nav a.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: var(--teal);
|
||||
}
|
||||
|
||||
/* =========================================
|
||||
MAIN CONTAINER & SECTIONS
|
||||
========================================= */
|
||||
|
||||
.cv-main {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
.cv-main section {
|
||||
padding: 80px 0;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
font-family: var(--font-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: var(--heading);
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
/* =========================================
|
||||
RESPONSIVE: 768px
|
||||
========================================= */
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.pill-nav {
|
||||
max-width: 100%;
|
||||
width: calc(100% - 32px);
|
||||
overflow-x: auto;
|
||||
padding: 6px 12px;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.pill-nav::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cv-main {
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* =========================================
|
||||
RESPONSIVE: 480px
|
||||
========================================= */
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.pill-nav a {
|
||||
font-size: 11px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.cv-main {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.cv-main section {
|
||||
padding: 48px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -176,7 +296,50 @@
|
||||
|
||||
<!-- Final CV Content (hidden behind boot screen until transition) -->
|
||||
<div id="cv-content">
|
||||
<!-- CV sections will be built in subsequent tasks -->
|
||||
|
||||
<!-- Floating Pill Navigation -->
|
||||
<nav class="pill-nav" id="pill-nav">
|
||||
<a href="#about" data-section="about">About</a>
|
||||
<a href="#skills" data-section="skills">Skills</a>
|
||||
<a href="#experience" data-section="experience">Experience</a>
|
||||
<a href="#education" data-section="education">Education</a>
|
||||
<a href="#projects" data-section="projects">Projects</a>
|
||||
<a href="#contact" data-section="contact">Contact</a>
|
||||
</nav>
|
||||
|
||||
<!-- Main CV Content -->
|
||||
<main class="cv-main">
|
||||
|
||||
<section id="about">
|
||||
<!-- Task 5: Hero section with vital sign cards -->
|
||||
</section>
|
||||
|
||||
<section id="skills">
|
||||
<!-- Task 6: Skills with circular SVG progress gauges -->
|
||||
</section>
|
||||
|
||||
<section id="experience">
|
||||
<!-- Task 7: Experience timeline with ECG decoration -->
|
||||
</section>
|
||||
|
||||
<section id="education">
|
||||
<!-- Task 8: Education section -->
|
||||
</section>
|
||||
|
||||
<section id="projects">
|
||||
<!-- Task 8: Projects section -->
|
||||
</section>
|
||||
|
||||
<section id="contact">
|
||||
<!-- Task 8: Contact section -->
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<footer id="cv-footer">
|
||||
<!-- Task 8: Footer with ECG decoration -->
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -571,9 +734,58 @@
|
||||
// Reveal CV content
|
||||
var cvContent = document.getElementById('cv-content');
|
||||
cvContent.classList.add('revealed');
|
||||
|
||||
// Initialize nav tracking and smooth scroll after reveal
|
||||
initNavTracking();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
/* =========================================
|
||||
NAV: Active Section Tracking & Smooth Scroll
|
||||
========================================= */
|
||||
|
||||
function initNavTracking() {
|
||||
var navLinks = document.querySelectorAll('.pill-nav a');
|
||||
var sections = document.querySelectorAll('.cv-main section');
|
||||
|
||||
// Smooth scroll on nav click
|
||||
navLinks.forEach(function(link) {
|
||||
link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
var targetId = link.getAttribute('data-section');
|
||||
var target = document.getElementById(targetId);
|
||||
if (target) {
|
||||
window.scrollTo({
|
||||
top: target.offsetTop - 70,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// IntersectionObserver for active section tracking
|
||||
var observer = new IntersectionObserver(function(entries) {
|
||||
entries.forEach(function(entry) {
|
||||
if (entry.isIntersecting) {
|
||||
var id = entry.target.getAttribute('id');
|
||||
navLinks.forEach(function(link) {
|
||||
link.classList.remove('active');
|
||||
if (link.getAttribute('data-section') === id) {
|
||||
link.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.3,
|
||||
rootMargin: '-20% 0px -60% 0px'
|
||||
});
|
||||
|
||||
sections.forEach(function(section) {
|
||||
observer.observe(section);
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user