Mobile: sidebar polish (Commit 1/4)

- Move hamburger click + backdrop click out of inline onclick into app.js
- Add aria-label/aria-expanded/aria-controls to hamburger button
- Close drawer on Escape keypress
- Bump hamburger button to 44px, nav-link min-height to 44px (tap targets)
- Bump .content top padding to 68px on mobile to match 44px hamburger

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
ScreenTinker 2026-04-21 15:49:49 -05:00
parent 2d3bb55db4
commit 09dbb4b199
3 changed files with 26 additions and 10 deletions

View file

@ -885,8 +885,8 @@ body {
top: 12px; top: 12px;
left: 12px; left: 12px;
z-index: 200; z-index: 200;
width: 40px; width: 44px;
height: 40px; height: 44px;
background: var(--bg-secondary); background: var(--bg-secondary);
border: 1px solid var(--border); border: 1px solid var(--border);
border-radius: var(--radius); border-radius: var(--radius);
@ -915,7 +915,8 @@ body {
z-index: 140; z-index: 140;
} }
.sidebar-backdrop.open { display: block; } .sidebar-backdrop.open { display: block; }
.content { margin-left: 0; padding: 16px; padding-top: 60px; } .nav-link { min-height: 44px; padding: 10px 14px; }
.content { margin-left: 0; padding: 16px; padding-top: 68px; }
.page-header { flex-direction: column; gap: 12px; align-items: flex-start; } .page-header { flex-direction: column; gap: 12px; align-items: flex-start; }
.device-grid { grid-template-columns: 1fr; } .device-grid { grid-template-columns: 1fr; }
.content-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } .content-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }

View file

@ -17,11 +17,11 @@
<!-- OAuth providers loaded on-demand by login.js when needed --> <!-- OAuth providers loaded on-demand by login.js when needed -->
</head> </head>
<body> <body>
<button class="mobile-menu-btn" id="mobileMenuBtn" onclick="document.querySelector('.sidebar').classList.toggle('open');document.getElementById('sidebarBackdrop').classList.toggle('open')"> <button class="mobile-menu-btn" id="mobileMenuBtn" aria-label="Toggle navigation menu" aria-expanded="false" aria-controls="sidebar">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
</button> </button>
<div class="sidebar-backdrop" id="sidebarBackdrop" onclick="document.querySelector('.sidebar').classList.remove('open');this.classList.remove('open')"></div> <div class="sidebar-backdrop" id="sidebarBackdrop"></div>
<nav class="sidebar"> <nav class="sidebar" id="sidebar">
<div class="sidebar-header"> <div class="sidebar-header">
<div class="logo"> <div class="logo">
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">

View file

@ -206,10 +206,25 @@ if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-admin.js').catch(() => {}); navigator.serviceWorker.register('/sw-admin.js').catch(() => {});
} }
// Close mobile menu on navigation // Mobile sidebar: open/close via hamburger, backdrop, nav tap, Escape
window.addEventListener('hashchange', () => { const sidebarEl = document.querySelector('.sidebar');
document.querySelector('.sidebar')?.classList.remove('open'); const backdropEl = document.getElementById('sidebarBackdrop');
document.getElementById('sidebarBackdrop')?.classList.remove('open'); const menuBtn = document.getElementById('mobileMenuBtn');
function setMobileNav(open) {
if (!sidebarEl || !backdropEl) return;
sidebarEl.classList.toggle('open', open);
backdropEl.classList.toggle('open', open);
menuBtn?.setAttribute('aria-expanded', open ? 'true' : 'false');
}
menuBtn?.addEventListener('click', () => {
setMobileNav(!sidebarEl.classList.contains('open'));
});
backdropEl?.addEventListener('click', () => setMobileNav(false));
window.addEventListener('hashchange', () => setMobileNav(false));
window.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && sidebarEl?.classList.contains('open')) setMobileNav(false);
}); });
// Auto-reload on frontend update (no more hard refresh needed) // Auto-reload on frontend update (no more hard refresh needed)