|
19 | 19 | </a> |
20 | 20 | </nav> |
21 | 21 | <div class="md:hidden"> |
22 | | - <button id="mobile-menu-button" class="text-gray-700 hover:text-primary"> |
23 | | - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 22 | + <button id="mobile-menu-button" class="text-gray-700 hover:text-primary" aria-label="Toggle menu" aria-expanded="false"> |
| 23 | + <svg id="menu-icon-bars" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
24 | 24 | <line x1="3" y1="12" x2="21" y2="12"></line> |
25 | 25 | <line x1="3" y1="6" x2="21" y2="6"></line> |
26 | 26 | <line x1="3" y1="18" x2="21" y2="18"></line> |
27 | 27 | </svg> |
| 28 | + <svg id="menu-icon-close" class="hidden" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 29 | + <line x1="18" y1="6" x2="6" y2="18"></line> |
| 30 | + <line x1="6" y1="6" x2="18" y2="18"></line> |
| 31 | + </svg> |
28 | 32 | </button> |
29 | 33 | </div> |
30 | 34 | </div> |
31 | 35 | <!-- Mobile menu (hidden by default) --> |
32 | | -<div id="mobile-menu" class="hidden md:hidden"> |
33 | | - <nav class="container mx-auto px-4 py-4 flex flex-col space-y-4 bg-white border-t"> |
| 36 | +<div id="mobile-menu" class="hidden md:hidden fixed top-[60px] left-0 right-0 z-50 bg-white border-t border-b"> |
| 37 | + <nav class="container mx-auto flex flex-col bg-white"> |
34 | 38 | {% for item in site.navigation %} |
35 | | - <a href="{{ site.baseurl }}{{ item.url }}" class="text-gray-700 hover:text-primary font-medium py-2">{{ item.title }}</a> |
| 39 | + <a href="{{ site.baseurl }}{{ item.url }}" class="text-gray-700 hover:text-primary hover:bg-gray-50 font-medium py-3 px-6">{{ item.title }}</a> |
36 | 40 | {% endfor %} |
37 | | - <a href="{{ site.github_repo }}" class="text-gray-700 hover:text-primary font-medium py-2 flex items-center" target="_blank" rel="noopener"> |
38 | | - <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" class="mr-1"> |
| 41 | + <a href="{{ site.github_repo }}" class="text-gray-700 hover:text-primary hover:bg-gray-50 font-medium py-3 px-6 flex items-center" target="_blank" rel="noopener"> |
| 42 | + <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" class="mr-2"> |
39 | 43 | <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/> |
40 | 44 | </svg> |
41 | 45 | GitHub |
42 | 46 | </a> |
43 | 47 | </nav> |
| 48 | + <!-- Backdrop for mobile menu --> |
| 49 | + <div class="fixed inset-0 bg-black bg-opacity-25 z-[-1]"></div> |
44 | 50 | </div> |
45 | 51 | <script> |
46 | 52 | document.addEventListener('DOMContentLoaded', function() { |
47 | 53 | const mobileMenuButton = document.getElementById('mobile-menu-button'); |
48 | 54 | const mobileMenu = document.getElementById('mobile-menu'); |
| 55 | + const menuIconBars = document.getElementById('menu-icon-bars'); |
| 56 | + const menuIconClose = document.getElementById('menu-icon-close'); |
49 | 57 |
|
50 | 58 | if (mobileMenuButton && mobileMenu) { |
51 | 59 | mobileMenuButton.addEventListener('click', function() { |
| 60 | + const isExpanded = mobileMenuButton.getAttribute('aria-expanded') === 'true'; |
| 61 | + |
| 62 | + // Toggle menu visibility |
52 | 63 | mobileMenu.classList.toggle('hidden'); |
| 64 | + |
| 65 | + // Toggle aria-expanded attribute |
| 66 | + mobileMenuButton.setAttribute('aria-expanded', !isExpanded); |
| 67 | + |
| 68 | + // Toggle menu icons |
| 69 | + menuIconBars.classList.toggle('hidden'); |
| 70 | + menuIconClose.classList.toggle('hidden'); |
| 71 | + |
| 72 | + // Prevent scrolling when menu is open |
| 73 | + document.body.style.overflow = isExpanded ? '' : 'hidden'; |
| 74 | + }); |
| 75 | + |
| 76 | + // Close menu when clicking outside |
| 77 | + document.addEventListener('click', function(event) { |
| 78 | + if (!mobileMenu.classList.contains('hidden') && |
| 79 | + !mobileMenu.contains(event.target) && |
| 80 | + !mobileMenuButton.contains(event.target)) { |
| 81 | + mobileMenu.classList.add('hidden'); |
| 82 | + mobileMenuButton.setAttribute('aria-expanded', 'false'); |
| 83 | + menuIconBars.classList.remove('hidden'); |
| 84 | + menuIconClose.classList.add('hidden'); |
| 85 | + document.body.style.overflow = ''; |
| 86 | + } |
| 87 | + }); |
| 88 | + |
| 89 | + // Close menu when pressing Escape key |
| 90 | + document.addEventListener('keydown', function(event) { |
| 91 | + if (event.key === 'Escape' && !mobileMenu.classList.contains('hidden')) { |
| 92 | + mobileMenu.classList.add('hidden'); |
| 93 | + mobileMenuButton.setAttribute('aria-expanded', 'false'); |
| 94 | + menuIconBars.classList.remove('hidden'); |
| 95 | + menuIconClose.classList.add('hidden'); |
| 96 | + document.body.style.overflow = ''; |
| 97 | + } |
53 | 98 | }); |
54 | 99 | } |
55 | 100 | }); |
|
0 commit comments