Summary
The site header has no mobile-responsive navigation. On smaller screens, the nav buttons (Mods, Tools, Info) stack awkwardly below the logo with no hamburger menu or collapsible drawer. This makes the site feel broken on phones and small tablets.
Current Behavior
Looking at app/views/layouts/_header.html.erb:
<div class="... md:pt-4 md:pb-12 md:px-5 md:flex md:flex-auto md:items-center md:justify-between">
<div class="flex items-center justify-start flex-1 min-w-0">
<%= image_tag "daedalus-logo.png", width: "64", alt: "Daedalus Logo" %>
<%= link_to "Project Daedalus", home_path, class: "... text-icarus-500 ..." %>
</div>
<div class="flex mt-4 md:mt-0 md:ml-4">
<button type="button" id="mods-button" class="button">
<%= link_to "Mods", mods_path, class: "... text-icarus-500 hover:text-blue-500" %>
</button>
<!-- Tools, Info buttons same pattern -->
</div>
</div>
Problems on mobile:
- The nav buttons
<div class="flex mt-4 md:mt-0"> just stacks below the logo with mt-4 — no intentional mobile layout
- No hamburger menu or drawer
- The header padding (
md:pt-4 md:pb-12 md:px-5) only applies at md+ — below that, no padding at all
- On the mods page, the author dropdown is
invisible md:visible — completely hidden on mobile with no alternative
- Adding a theme toggle button (from the pending PR) would make the header even more crowded on mobile
Proposed Solution
1. Hamburger Button (Mobile Only)
Add a hamburger icon that's only visible below the md breakpoint:
<button type="button"
data-action="click->navigation#toggle"
data-navigation-target="button"
class="md:hidden inline-flex items-center justify-center w-10 h-10 rounded-lg text-icarus-500 hover:text-icarus-400 hover:bg-slate-700/50 transition-colors"
aria-label="Toggle navigation menu"
aria-expanded="false">
<span data-navigation-target="icon" class="text-2xl">☰</span>
</button>
2. Collapsible Mobile Menu
Wrap the nav links in a container that toggles visibility:
<div data-navigation-target="menu"
class="hidden md:flex mt-4 md:mt-0 md:ml-4"
role="navigation"
aria-label="Main navigation">
<!-- Existing Mods, Tools, Info buttons -->
<!-- On mobile: displayed as vertical stack when menu is open -->
</div>
Mobile open state: Full-width dropdown below the header with vertical link stack:
<div class="flex flex-col md:flex-row w-full md:w-auto">
<a href="/mods" class="px-4 py-3 text-icarus-500 hover:bg-slate-700/50 border-b border-slate-700 md:border-0">Mods</a>
<a href="/tools" class="px-4 py-3 text-icarus-500 hover:bg-slate-700/50 border-b border-slate-700 md:border-0">Tools</a>
<a href="/info" class="px-4 py-3 text-icarus-500 hover:bg-slate-700/50 md:border-0">Info</a>
</div>
3. New Stimulus Controller
Create app/javascript/controllers/navigation_controller.js:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["menu", "button", "icon"]
toggle() {
const isOpen = !this.menuTarget.classList.contains("hidden")
if (isOpen) {
this.close()
} else {
this.open()
}
}
open() {
this.menuTarget.classList.remove("hidden")
this.buttonTarget.setAttribute("aria-expanded", "true")
this.iconTarget.textContent = "✕"
// Close on click outside
document.addEventListener("click", this.closeOnClickOutside)
// Close on Escape
document.addEventListener("keydown", this.closeOnEscape)
}
close() {
this.menuTarget.classList.add("hidden")
this.buttonTarget.setAttribute("aria-expanded", "false")
this.iconTarget.textContent = "☰"
document.removeEventListener("click", this.closeOnClickOutside)
document.removeEventListener("keydown", this.closeOnEscape)
}
closeOnClickOutside = (event) => {
if (!this.element.contains(event.target)) this.close()
}
closeOnEscape = (event) => {
if (event.key === "Escape") this.close()
}
// Auto-close after Turbo navigation
disconnect() {
this.close()
}
}
4. Desktop Layout Unchanged
On md+ screens, everything stays exactly as it is — the hamburger is md:hidden and the nav links container is md:flex. Zero changes to desktop experience.
Files to Modify
| File |
Change |
app/views/layouts/_header.html.erb |
Add hamburger button, wrap nav in data-controller="navigation", restructure for responsive layout |
app/javascript/controllers/navigation_controller.js |
New file — Stimulus controller for menu toggle |
app/views/layouts/application.html.erb |
May need z-index adjustment on <main> so mobile menu overlays content |
Design Notes
- Hamburger icon:
text-icarus-500 gold to match nav links
- Mobile menu background: Same gradient as header (
bg-gradient-to-b from-slate-600 via-slate-500 to-slate-200 dark:from-slate-900 dark:via-slate-900 dark:to-slate-800)
- Menu items:
text-icarus-500 hover:text-blue-500 matching existing nav link colors
- Each item gets
py-3 for comfortable 44px+ touch targets
- Subtle gold dividers between items:
border-b border-slate-700
- Smooth transition:
transition-all duration-200 on the menu container
- If the theme toggle PR is merged, include the toggle button in the mobile menu too
Accessibility
- Hamburger:
aria-label="Toggle navigation menu", aria-expanded toggled by JS
- Menu container:
role="navigation", aria-label="Main navigation"
- Escape key closes menu
- Click outside closes menu
- Focus returns to hamburger button when menu closes
- Menu closes automatically on Turbo navigation (Stimulus
disconnect())
Testing
Summary
The site header has no mobile-responsive navigation. On smaller screens, the nav buttons (Mods, Tools, Info) stack awkwardly below the logo with no hamburger menu or collapsible drawer. This makes the site feel broken on phones and small tablets.
Current Behavior
Looking at
app/views/layouts/_header.html.erb:Problems on mobile:
<div class="flex mt-4 md:mt-0">just stacks below the logo withmt-4— no intentional mobile layoutmd:pt-4 md:pb-12 md:px-5) only applies atmd+— below that, no padding at allinvisible md:visible— completely hidden on mobile with no alternativeProposed Solution
1. Hamburger Button (Mobile Only)
Add a hamburger icon that's only visible below the
mdbreakpoint:2. Collapsible Mobile Menu
Wrap the nav links in a container that toggles visibility:
Mobile open state: Full-width dropdown below the header with vertical link stack:
3. New Stimulus Controller
Create
app/javascript/controllers/navigation_controller.js:4. Desktop Layout Unchanged
On
md+screens, everything stays exactly as it is — the hamburger ismd:hiddenand the nav links container ismd:flex. Zero changes to desktop experience.Files to Modify
app/views/layouts/_header.html.erbdata-controller="navigation", restructure for responsive layoutapp/javascript/controllers/navigation_controller.jsapp/views/layouts/application.html.erb<main>so mobile menu overlays contentDesign Notes
text-icarus-500gold to match nav linksbg-gradient-to-b from-slate-600 via-slate-500 to-slate-200 dark:from-slate-900 dark:via-slate-900 dark:to-slate-800)text-icarus-500 hover:text-blue-500matching existing nav link colorspy-3for comfortable 44px+ touch targetsborder-b border-slate-700transition-all duration-200on the menu containerAccessibility
aria-label="Toggle navigation menu",aria-expandedtoggled by JSrole="navigation",aria-label="Main navigation"disconnect())Testing
mdbreakpointmd+(hamburger hidden)