From 11554ed790e63ff5ec8ba778c2161923b2c4fcf8 Mon Sep 17 00:00:00 2001 From: Tyler Hoang Date: Wed, 6 May 2026 16:45:56 -0700 Subject: Add hamburger menu for mobile navigation Hide nav-actions on mobile (<= 760px) and show a hamburger menu button instead. Menu opens/closes on click and closes when a link is clicked or when clicking outside. Hamburger icon created with CSS pseudo-elements. Co-Authored-By: Claude Haiku 4.5 --- static/app.js | 27 +++++++++++++++++++ static/styles.css | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 1 deletion(-) (limited to 'static') diff --git a/static/app.js b/static/app.js index 02f70f8..7b5a88f 100644 --- a/static/app.js +++ b/static/app.js @@ -1,3 +1,30 @@ +// Hamburger menu toggle +const menuToggle = document.querySelector("#menu-toggle"); +const navActions = document.querySelector("#nav-actions"); + +if (menuToggle && navActions) { + menuToggle.addEventListener("click", () => { + const isOpen = navActions.classList.toggle("is-open"); + menuToggle.setAttribute("aria-expanded", isOpen ? "true" : "false"); + }); + + // Close menu when a link is clicked + navActions.querySelectorAll("a").forEach((link) => { + link.addEventListener("click", () => { + navActions.classList.remove("is-open"); + menuToggle.setAttribute("aria-expanded", "false"); + }); + }); + + // Close menu when clicking outside + document.addEventListener("click", (event) => { + if (!navActions.contains(event.target) && !menuToggle.contains(event.target)) { + navActions.classList.remove("is-open"); + menuToggle.setAttribute("aria-expanded", "false"); + } + }); +} + const tmdbQuery = document.querySelector("#tmdb-query"); const tmdbButton = document.querySelector("#tmdb-search"); const tmdbResults = document.querySelector("#tmdb-results"); diff --git a/static/styles.css b/static/styles.css index bc5c2e2..724d1d9 100644 --- a/static/styles.css +++ b/static/styles.css @@ -57,6 +57,7 @@ textarea { gap: 18px; padding: 24px 0; border-bottom: 1px solid var(--line); + position: relative; } .brand { @@ -943,8 +944,82 @@ textarea:focus { } .topbar { - align-items: flex-start; + align-items: center; + flex-direction: row; + } + + .menu-toggle { + display: block !important; + width: 28px; + height: 22px; + margin-left: auto; + background: none; + border: none; + cursor: pointer; + position: relative; + padding: 0; + } + + .menu-toggle::before, + .menu-toggle::after { + content: ""; + position: absolute; + width: 100%; + height: 2px; + background: var(--text); + left: 0; + } + + .menu-toggle::before { + top: 0; + box-shadow: 0 10px 0 var(--text); + } + + .menu-toggle::after { + bottom: 0; + } + + .nav-actions { + position: absolute; + top: 100%; + left: 0; + right: 0; flex-direction: column; + gap: 0; + border-bottom: 1px solid var(--line); + background: var(--bg); + padding: 12px 0; + max-height: 0; + overflow: hidden; + transition: max-height 0.3s ease; + } + + .nav-actions.is-open { + max-height: 400px; + } + + .nav-actions a, + .nav-actions button { + padding: 12px 16px; + text-align: left; + border: none; + border-radius: 0; + background: none; + color: var(--muted); + } + + .nav-actions a.is-active, + .nav-actions a:hover, + .nav-actions button:hover { + background: var(--panel); + color: var(--text); + } + + .nav-actions .button-link { + color: #0e0a04; + background: var(--accent); + margin: 8px 16px; + border: none; } .page-heading, -- cgit v1.3-2-g0d8e