diff --git a/main.js b/main.js index 1917ba1..d241206 100644 --- a/main.js +++ b/main.js @@ -154,6 +154,32 @@ function initTestimonials() { }); } +// ===== PARALLAX EFFECT FOR DECORATIVE ELEMENTS ===== +function initParallax() { + const floatingElements = document.querySelectorAll('.floating-bean, .floating-cup'); + if (!floatingElements.length) return; + + let ticking = false; + + window.addEventListener('scroll', () => { + if (!ticking) { + window.requestAnimationFrame(() => { + const scrolled = window.scrollY; + + floatingElements.forEach((el, index) => { + const speed = 0.05 + (index * 0.02); // Vary speed per element + const yPos = -(scrolled * speed); + // Use CSS variable to avoid overwriting the float animation transform + el.style.transform = `translateY(${yPos}px)`; + }); + + ticking = false; + }); + ticking = true; + } + }, { passive: true }); +} + // ===== INITIALIZE ALL ===== document.addEventListener('DOMContentLoaded', () => { initTypewriter(); @@ -161,4 +187,5 @@ document.addEventListener('DOMContentLoaded', () => { initSkillBars(); initParticles(); initTestimonials(); + initParallax(); }); diff --git a/styles.css b/styles.css index 0971608..0e5c1d1 100644 --- a/styles.css +++ b/styles.css @@ -139,7 +139,8 @@ body { position: absolute; opacity: 0.04; color: var(--color-coffee-dark); - animation: float-cup 18s infinite ease-in-out; + animation: float-rotate 18s infinite ease-in-out; + transition: transform 0.1s linear; } @media (prefers-color-scheme: dark) { @@ -151,10 +152,17 @@ body { .cup-1 { width: 120px; top: 25%; right: 10%; animation-delay: -2s; } -@keyframes float-cup { - 0% { transform: translate(0, 0) rotate(-5deg); } - 50% { transform: translate(-20px, 30px) rotate(5deg); } - 100% { transform: translate(0, 0) rotate(-5deg); } +@keyframes float-rotate { + 0% { transform: rotate(-5deg); } + 50% { transform: rotate(5deg); } + 100% { transform: rotate(-5deg); } +} + + +@keyframes float-rotate { + 0% { transform: rotate(-5deg); } + 50% { transform: rotate(5deg); } + 100% { transform: rotate(-5deg); } } /* Coffee Stains */ @@ -257,12 +265,25 @@ a { color: var(--color-primary); text-decoration: none; font-weight: 600; - transition: text-decoration-color 0.2s; + position: relative; + transition: color 0.3s ease; + + /* Coffee Drip Underline Animation */ + background-image: linear-gradient(to right, var(--color-coffee-medium) 0%, var(--color-gold) 100%); + background-size: 0% 2px; + background-position: left bottom; + background-repeat: no-repeat; + padding-bottom: 2px; &:hover { - text-decoration: underline; - text-decoration-thickness: 2px; - text-underline-offset: 4px; + background-size: 100% 2px; + color: var(--color-coffee-dark); + } +} + +@media (prefers-color-scheme: dark) { + a:hover { + color: var(--color-gold); } } @@ -398,10 +419,11 @@ section { backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid var(--border-subtle); - border-radius: 16px; /* Increased radius */ + border-radius: 16px; overflow: hidden; transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); height: 100%; + position: relative; /* Scroll Animation Entry */ view-timeline-name: --card-entry; @@ -413,15 +435,38 @@ section { &:hover { transform: translateY(-8px) scale(1.02); box-shadow: var(--shadow-glass); - border-color: var(--color-gold); /* Gold Accent */ + border-color: var(--color-gold); background-color: color-mix(in srgb, var(--bg-surface), var(--color-cream) 10%); } + /* Shine Effect */ + &::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient( + 90deg, + transparent, + rgba(255, 255, 255, 0.2), + transparent + ); + transition: 0.5s; + pointer-events: none; + } + + &:hover::after { + left: 100%; + transition: 0.7s ease-in-out; + } + .card-img-top { aspect-ratio: 16/9; object-fit: cover; transition: transform 0.6s ease; - filter: sepia(20%) contrast(1.1); /* Subtle coffee tint */ + filter: sepia(20%) contrast(1.1); } &:hover .card-img-top { @@ -435,7 +480,7 @@ section { flex-direction: column; h5.card-title { - font-size: 1.5rem; /* Larger */ + font-size: 1.5rem; margin-bottom: 0.75rem; font-family: var(--font-display); letter-spacing: -0.02em;