- Public site: replace the always-hidden mobile nav with a hamburger toggle (index.php, menu.php, main.js, styles.css) - Admin: render the Menu/Announcements/Users tables as labeled cards below ~760px instead of squeezing descriptions into unreadable single-word-per-line columns - Admin menu: replace the manual "Order" number (which allowed duplicates and never reflected in real time) with ↑/↓ buttons that reorder items and categories immediately and renumber sort_order sequentially on every move, self-healing any stale duplicates Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
67 lines
1.7 KiB
JavaScript
67 lines
1.7 KiB
JavaScript
// Shared public-site behavior: scroll-reveal animations and the mobile
|
|
// nav toggle. Loaded by both index.php and menu.php.
|
|
|
|
// Reveal-on-scroll
|
|
(() => {
|
|
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
|
|
|
const els = document.querySelectorAll('.reveal');
|
|
if (!('IntersectionObserver' in window)) {
|
|
els.forEach((el) => el.classList.add('is-visible'));
|
|
return;
|
|
}
|
|
|
|
const io = new IntersectionObserver((entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('is-visible');
|
|
io.unobserve(entry.target);
|
|
}
|
|
});
|
|
}, { threshold: 0.15 });
|
|
|
|
els.forEach((el) => io.observe(el));
|
|
})();
|
|
|
|
// Mobile nav toggle
|
|
(() => {
|
|
const toggle = document.getElementById('nav-toggle');
|
|
const nav = document.getElementById('primary-nav');
|
|
if (!toggle || !nav) return;
|
|
|
|
function closeNav() {
|
|
nav.classList.remove('is-open');
|
|
toggle.setAttribute('aria-expanded', 'false');
|
|
}
|
|
|
|
function openNav() {
|
|
nav.classList.add('is-open');
|
|
toggle.setAttribute('aria-expanded', 'true');
|
|
}
|
|
|
|
toggle.addEventListener('click', () => {
|
|
if (nav.classList.contains('is-open')) {
|
|
closeNav();
|
|
} else {
|
|
openNav();
|
|
}
|
|
});
|
|
|
|
// Close after following a link
|
|
nav.querySelectorAll('a').forEach((link) => {
|
|
link.addEventListener('click', closeNav);
|
|
});
|
|
|
|
// Close on Escape
|
|
window.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape') closeNav();
|
|
});
|
|
|
|
// Close on outside click
|
|
document.addEventListener('click', (e) => {
|
|
if (!nav.classList.contains('is-open')) return;
|
|
if (nav.contains(e.target) || toggle.contains(e.target)) return;
|
|
closeNav();
|
|
});
|
|
})();
|