feat: enhance curated card interactions with tap-to-toggle functionality for mobile and improved hover effects for desktop
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
George Birikorang 2025-09-16 01:03:42 -07:00
parent 4baf19983a
commit 60ffd31b68
3 changed files with 140 additions and 40 deletions

View file

@ -1080,6 +1080,7 @@ if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", function () {
initHeroCarousel();
initMobileMenu();
initCuratedCardsTap();
});
// Hero Carousel Functionality
@ -1099,15 +1100,6 @@ function initHeroCarousel() {
];
let currentImageIndex = 0;
let originalHeight = null;
// Function to capture original image height on first load
function captureOriginalHeight() {
if (!originalHeight) {
originalHeight = heroImage.offsetHeight;
console.log("Original image height captured:", originalHeight + "px");
}
}
// Function to update image with fade transition
function updateImage(newIndex) {
@ -1121,15 +1113,9 @@ function initHeroCarousel() {
heroImage.src = carouselImages[newIndex];
heroImage.alt = `Carousel image ${newIndex + 1}`;
// Apply original height to maintain uniformity
if (originalHeight && newIndex !== 0) {
heroImage.style.height = originalHeight + "px";
heroImage.style.objectFit = "cover";
} else if (newIndex === 0) {
// Reset to original for the first image
heroImage.style.height = "auto";
heroImage.style.objectFit = "initial";
}
// Ensure image always fits its container uniformly
heroImage.style.height = "100%";
heroImage.style.objectFit = "cover";
// Fade in new image
heroImage.style.opacity = "1";
@ -1172,12 +1158,7 @@ function initHeroCarousel() {
}
}
// Capture original height after image loads
if (heroImage.complete) {
captureOriginalHeight();
} else {
heroImage.addEventListener("load", captureOriginalHeight);
}
// No dynamic height capture needed; CSS handles sizing
// Auto-advance carousel every 5 seconds
setInterval(() => {
@ -1186,6 +1167,36 @@ function initHeroCarousel() {
}, 5000);
}
// Tap-to-toggle for curated cards on touch devices
function initCuratedCardsTap() {
try {
const cards = document.querySelectorAll(".curated-card");
if (!cards || cards.length === 0) return;
// Only enable on coarse pointers (touch)
const isTouchLike = window.matchMedia(
"(hover: none), (pointer: coarse)"
).matches;
if (!isTouchLike) return;
cards.forEach((card) => {
card.addEventListener("click", (e) => {
// Toggle active state; second tap removes it
card.classList.toggle("is-active");
});
// Optional: remove active when tapping outside the card
document.addEventListener("click", (evt) => {
if (!card.contains(evt.target)) {
card.classList.remove("is-active");
}
});
});
} catch (err) {
console.warn("Failed to init curated card tap behavior:", err);
}
}
// Mobile Menu Functionality
function initMobileMenu() {
const mobileMenuButton = document.getElementById("mobile-menu-button");