fix: Mobile hamburger menu and iPad sidebar visibility

Mobile fixes:
- Add click toggle handler for hamburger menu (was hover-only)
- Menu now opens/closes on tap and closes when clicking outside
- Keep hover support for desktop

iPad fixes:
- Sidebar content now visible on touch devices (901-1280px)
- Added (hover: hover) media query to prevent hide-on-hover on tablets

Security improvements:
- Replace exec.CommandContext with go-git library for git operations
- Add path traversal and command injection prevention
- Fix race condition in template hot reload
- Add environment-based cookie Secure flag

Code quality:
- Add constants.go for magic numbers
- Remove unused code (ParsePreferenceToggleRequest, DomainError)
- Add FOUC prevention with inline critical CSS
- Add Makefile dev/run/clean targets
- Fix README git clone URL
- Add doc/DECISIONS.md for architectural decisions

Tests:
- Add hamburger menu click toggle tests
- Add iPad sidebar visibility tests
- Update security tests for go-git implementation
- Add cookie Secure flag tests
This commit is contained in:
juanatsap
2025-11-30 09:29:35 +00:00
parent 60c1b5ac2b
commit eb92f64e93
18 changed files with 874 additions and 183 deletions
+9 -15
View File
@@ -104,11 +104,20 @@
gap: 0.5rem;
}
}
/* ========================================
Sidebar Hide-on-Hover: ONLY for devices with hover support
Prevents hiding on iPad/tablets where hover doesn't work
======================================== */
@media (min-width: 901px) and (max-width: 1280px) and (hover: hover) {
/* ========== Sidebar Content - Hide Text, Show on Hover ========== */
/* Only apply on devices that support hover (not touch devices) */
.sidebar-content {
max-height: 0 !important;
overflow: hidden !important;
opacity: 0 !important;
transition: max-height 0.3s ease, opacity 0.3s ease;
}
/* Show sidebar content on hover */
@@ -221,21 +230,6 @@
padding: 0.65rem 1.5rem;
gap: 0.5rem;
}
/* ========== Sidebar Content - Hide Text, Show on Hover ========== */
.sidebar-content {
max-height: 0 !important;
overflow: hidden !important;
opacity: 0 !important;
}
/* Show sidebar content on hover */
.skill-category:hover .sidebar-content,
.cv-sidebar-section:hover .sidebar-content {
max-height: 1000px !important;
opacity: 1 !important;
margin-top: 10px !important;
}
}
/* ========================================
+16 -2
View File
@@ -24,7 +24,8 @@
/**
* Initialize minimal menu control system
* CSS handles most logic, JS just bridges hamburger to menu
* CSS handles most logic, JS bridges hamburger to menu
* Click toggle for mobile, hover for desktop
*/
function initMenuSystem() {
const hamburgerBtn = document.querySelector('.hamburger-btn');
@@ -32,7 +33,20 @@
if (!hamburgerBtn || !menu) return;
// Show menu on hamburger hover - CSS handles the rest
// Click handler for mobile - toggles menu-open class
hamburgerBtn.addEventListener('click', (e) => {
e.stopPropagation();
menu.classList.toggle('menu-open');
});
// Close menu when clicking outside (for mobile)
document.addEventListener('click', (e) => {
if (!menu.contains(e.target) && !hamburgerBtn.contains(e.target)) {
menu.classList.remove('menu-open');
}
});
// Desktop hover support - show menu on hamburger hover
hamburgerBtn.addEventListener('mouseenter', () => menu.classList.add('menu-hover'));
// Hide menu when leaving hamburger if not hovering menu