|
340 | 340 | font-weight: 400; |
341 | 341 | } |
342 | 342 |
|
| 343 | + /* Burger Menu */ |
| 344 | + .burger-menu { |
| 345 | + display: none; |
| 346 | + flex-direction: column; |
| 347 | + justify-content: space-around; |
| 348 | + width: 2rem; |
| 349 | + height: 2rem; |
| 350 | + background: transparent; |
| 351 | + border: none; |
| 352 | + cursor: pointer; |
| 353 | + padding: 0; |
| 354 | + z-index: 1001; |
| 355 | + margin-left: auto; |
| 356 | + } |
| 357 | + |
| 358 | + .burger-menu span { |
| 359 | + width: 2rem; |
| 360 | + height: 0.2rem; |
| 361 | + background: var(--text-primary); |
| 362 | + border-radius: 10px; |
| 363 | + transition: all 0.3s linear; |
| 364 | + position: relative; |
| 365 | + transform-origin: 1px; |
| 366 | + } |
| 367 | + |
| 368 | + .burger-menu.active span:nth-child(1) { |
| 369 | + transform: rotate(45deg); |
| 370 | + } |
| 371 | + |
| 372 | + .burger-menu.active span:nth-child(2) { |
| 373 | + opacity: 0; |
| 374 | + transform: translateX(20px); |
| 375 | + } |
| 376 | + |
| 377 | + .burger-menu.active span:nth-child(3) { |
| 378 | + transform: rotate(-45deg); |
| 379 | + } |
| 380 | + |
343 | 381 | .header-nav { |
344 | 382 | display: flex; |
345 | 383 | align-items: center; |
|
835 | 873 | gap: 0.75rem; |
836 | 874 | } |
837 | 875 |
|
838 | | - .sort-label { |
839 | | - color: var(--text-muted); |
840 | | - font-size: 0.85rem; |
841 | | - } |
842 | | - |
843 | 876 | .sort-select { |
844 | | - padding: 0.5rem 2rem 0.5rem 0.875rem; |
| 877 | + width: 100%; |
| 878 | + padding: 0.75rem 2.5rem 0.75rem 0.875rem; |
845 | 879 | border-radius: 8px; |
846 | 880 | border: 1px solid var(--border-color); |
847 | 881 | background: var(--bg-secondary); |
|
853 | 887 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23606070' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); |
854 | 888 | background-repeat: no-repeat; |
855 | 889 | background-position: right 0.75rem center; |
| 890 | + transition: all var(--transition-base); |
| 891 | + } |
| 892 | + |
| 893 | + .sort-select:hover { |
| 894 | + border-color: var(--accent-primary); |
856 | 895 | } |
857 | 896 |
|
858 | 897 | .sort-select:focus { |
859 | 898 | outline: none; |
860 | 899 | border-color: var(--accent-primary); |
| 900 | + box-shadow: 0 0 0 3px var(--shadow-color); |
861 | 901 | } |
862 | 902 |
|
863 | 903 | .view-toggle { |
|
999 | 1039 | } |
1000 | 1040 | } |
1001 | 1041 |
|
1002 | | - /* Mobile navigation responsive fixes */ |
1003 | | - @media (max-width: 640px) { |
| 1042 | + /* Mobile burger menu and navigation */ |
| 1043 | + @media (max-width: 768px) { |
| 1044 | + /* Show burger menu on mobile */ |
| 1045 | + .burger-menu { |
| 1046 | + display: flex; |
| 1047 | + } |
| 1048 | + |
| 1049 | + /* Hide and transform navigation into slide-out menu */ |
1004 | 1050 | .header-nav { |
1005 | | - gap: 0.375rem; |
| 1051 | + position: fixed; |
| 1052 | + top: 0; |
| 1053 | + right: -100%; |
| 1054 | + height: 100vh; |
| 1055 | + width: 280px; |
| 1056 | + background: var(--bg-secondary); |
| 1057 | + flex-direction: column; |
| 1058 | + align-items: stretch; |
| 1059 | + gap: 0; |
| 1060 | + padding: 5rem 1.5rem 2rem; |
| 1061 | + box-shadow: -4px 0 20px var(--shadow-color); |
| 1062 | + transition: right 0.3s ease-in-out; |
| 1063 | + z-index: 1000; |
| 1064 | + overflow-y: auto; |
| 1065 | + } |
| 1066 | + |
| 1067 | + .header-nav.active { |
| 1068 | + right: 0; |
1006 | 1069 | } |
1007 | 1070 |
|
1008 | 1071 | .nav-btn { |
1009 | | - padding: 0.5rem 0.75rem; |
1010 | | - font-size: 0.85rem; |
| 1072 | + padding: 1rem; |
| 1073 | + font-size: 1rem; |
| 1074 | + width: 100%; |
| 1075 | + justify-content: flex-start; |
| 1076 | + border-radius: 8px; |
| 1077 | + margin-bottom: 0.5rem; |
1011 | 1078 | } |
1012 | 1079 |
|
1013 | 1080 | .nav-btn .count { |
1014 | | - font-size: 0.7rem; |
1015 | | - padding: 0.1rem 0.4rem; |
| 1081 | + margin-left: auto; |
| 1082 | + } |
| 1083 | + |
| 1084 | + .github-link { |
| 1085 | + padding: 1rem; |
| 1086 | + width: 100%; |
| 1087 | + justify-content: flex-start; |
| 1088 | + border-radius: 8px; |
| 1089 | + margin-bottom: 0.5rem; |
1016 | 1090 | } |
1017 | 1091 |
|
1018 | 1092 | .github-link span { |
1019 | | - display: none; |
| 1093 | + display: inline; |
1020 | 1094 | } |
1021 | 1095 |
|
1022 | | - .github-link { |
1023 | | - padding: 0.5rem; |
| 1096 | + .theme-switcher { |
| 1097 | + width: 100%; |
| 1098 | + margin-top: 0.5rem; |
| 1099 | + } |
| 1100 | + |
| 1101 | + .theme-btn { |
| 1102 | + width: 100%; |
| 1103 | + padding: 1rem; |
| 1104 | + justify-content: center; |
| 1105 | + } |
| 1106 | + |
| 1107 | + .theme-dropdown { |
| 1108 | + position: static; |
| 1109 | + width: 100%; |
| 1110 | + margin-top: 0.5rem; |
1024 | 1111 | } |
1025 | 1112 | } |
1026 | 1113 |
|
| 1114 | + /* Mobile overlay for burger menu */ |
| 1115 | + .mobile-overlay { |
| 1116 | + display: none; |
| 1117 | + position: fixed; |
| 1118 | + top: 0; |
| 1119 | + left: 0; |
| 1120 | + width: 100%; |
| 1121 | + height: 100%; |
| 1122 | + background: rgba(0, 0, 0, 0.5); |
| 1123 | + z-index: 998; |
| 1124 | + opacity: 0; |
| 1125 | + transition: opacity 0.3s ease-in-out; |
| 1126 | + pointer-events: none; |
| 1127 | + } |
| 1128 | + |
| 1129 | + .mobile-overlay.active { |
| 1130 | + display: block; |
| 1131 | + opacity: 1; |
| 1132 | + } |
| 1133 | + |
1027 | 1134 | /* Project card */ |
1028 | 1135 | .project-card { |
1029 | 1136 | background: var(--bg-card); |
|
1851 | 1958 | <body> |
1852 | 1959 | <div class="bg-gradient"></div> |
1853 | 1960 |
|
| 1961 | + <!-- Mobile Menu Overlay --> |
| 1962 | + <div class="mobile-overlay" id="mobile-overlay"></div> |
| 1963 | + |
1854 | 1964 | <!-- Header --> |
1855 | 1965 | <header class="header"> |
1856 | 1966 | <div class="header-content"> |
1857 | 1967 | <a href="#" class="logo"> |
1858 | 1968 | <div class="logo-icon">☁️</div> |
1859 | 1969 | <div class="logo-text">CloudProjects <span>Index</span></div> |
1860 | 1970 | </a> |
1861 | | - |
1862 | | - <nav class="header-nav"> |
| 1971 | + |
| 1972 | + <!-- Burger Menu Button (Mobile Only) --> |
| 1973 | + <button class="burger-menu" id="burger-menu" aria-label="Toggle menu"> |
| 1974 | + <span></span> |
| 1975 | + <span></span> |
| 1976 | + <span></span> |
| 1977 | + </button> |
| 1978 | + |
| 1979 | + <nav class="header-nav" id="header-nav"> |
1863 | 1980 | <button class="nav-btn active" data-view="all"> |
1864 | 1981 | All Projects |
1865 | 1982 | <span class="count" id="all-count">0</span> |
|
2006 | 2123 | </div> |
2007 | 2124 | </div> |
2008 | 2125 |
|
| 2126 | + <!-- Sort --> |
| 2127 | + <div class="sidebar-section"> |
| 2128 | + <div class="sidebar-title">Sort By</div> |
| 2129 | + <select class="sort-select" id="sort-select"> |
| 2130 | + <option value="name-asc">Name (A-Z)</option> |
| 2131 | + <option value="name-desc">Name (Z-A)</option> |
| 2132 | + <option value="difficulty-asc">Difficulty (Easy first)</option> |
| 2133 | + <option value="difficulty-desc">Difficulty (Hard first)</option> |
| 2134 | + <option value="duration-asc">Duration (Quick first)</option> |
| 2135 | + <option value="duration-desc">Duration (Long first)</option> |
| 2136 | + <option value="provider">Provider</option> |
| 2137 | + </select> |
| 2138 | + </div> |
| 2139 | + |
2009 | 2140 | <!-- Categories --> |
2010 | 2141 | <div class="sidebar-section"> |
2011 | 2142 | <div class="sidebar-title">Categories</div> |
|
2052 | 2183 | </svg> |
2053 | 2184 | </button> |
2054 | 2185 | </div> |
2055 | | - <span class="sort-label">Sort by</span> |
2056 | | - <select class="sort-select" id="sort-select"> |
2057 | | - <option value="name-asc">Name (A-Z)</option> |
2058 | | - <option value="name-desc">Name (Z-A)</option> |
2059 | | - <option value="difficulty-asc">Difficulty (Easy first)</option> |
2060 | | - <option value="difficulty-desc">Difficulty (Hard first)</option> |
2061 | | - <option value="duration-asc">Duration (Quick first)</option> |
2062 | | - <option value="duration-desc">Duration (Long first)</option> |
2063 | | - <option value="provider">Provider</option> |
2064 | | - </select> |
2065 | 2186 | </div> |
2066 | 2187 | </div> |
2067 | 2188 |
|
@@ -2750,13 +2871,66 @@ <h3 class="learning-path-title">${path.name}</h3> |
2750 | 2871 | loadTheme(); |
2751 | 2872 | } |
2752 | 2873 |
|
| 2874 | + function initBurgerMenu() { |
| 2875 | + const burgerBtn = document.getElementById('burger-menu'); |
| 2876 | + const headerNav = document.getElementById('header-nav'); |
| 2877 | + const mobileOverlay = document.getElementById('mobile-overlay'); |
| 2878 | + |
| 2879 | + function toggleMenu() { |
| 2880 | + burgerBtn.classList.toggle('active'); |
| 2881 | + headerNav.classList.toggle('active'); |
| 2882 | + mobileOverlay.classList.toggle('active'); |
| 2883 | + document.body.style.overflow = headerNav.classList.contains('active') ? 'hidden' : ''; |
| 2884 | + } |
| 2885 | + |
| 2886 | + function closeMenu() { |
| 2887 | + burgerBtn.classList.remove('active'); |
| 2888 | + headerNav.classList.remove('active'); |
| 2889 | + mobileOverlay.classList.remove('active'); |
| 2890 | + document.body.style.overflow = ''; |
| 2891 | + } |
| 2892 | + |
| 2893 | + // Toggle menu on burger button click |
| 2894 | + burgerBtn.addEventListener('click', (e) => { |
| 2895 | + e.stopPropagation(); |
| 2896 | + toggleMenu(); |
| 2897 | + }); |
| 2898 | + |
| 2899 | + // Close menu when clicking outside of navigation |
| 2900 | + document.addEventListener('click', (e) => { |
| 2901 | + if (headerNav.classList.contains('active')) { |
| 2902 | + // Check if click is outside both burger button and navigation menu |
| 2903 | + if (!headerNav.contains(e.target) && !burgerBtn.contains(e.target)) { |
| 2904 | + closeMenu(); |
| 2905 | + } |
| 2906 | + } |
| 2907 | + }); |
| 2908 | + |
| 2909 | + // Close menu when navigation items are clicked (except theme switcher) |
| 2910 | + document.querySelectorAll('.nav-btn').forEach(btn => { |
| 2911 | + btn.addEventListener('click', () => { |
| 2912 | + if (window.innerWidth <= 768) { |
| 2913 | + closeMenu(); |
| 2914 | + } |
| 2915 | + }); |
| 2916 | + }); |
| 2917 | + |
| 2918 | + // Close menu on window resize if screen becomes larger |
| 2919 | + window.addEventListener('resize', () => { |
| 2920 | + if (window.innerWidth > 768) { |
| 2921 | + closeMenu(); |
| 2922 | + } |
| 2923 | + }); |
| 2924 | + } |
| 2925 | + |
2753 | 2926 | // ===================================================== |
2754 | 2927 | // INITIALIZATION |
2755 | 2928 | // ===================================================== |
2756 | 2929 |
|
2757 | 2930 | function init() { |
2758 | 2931 | loadFromStorage(); |
2759 | 2932 | initThemeSwitcher(); |
| 2933 | + initBurgerMenu(); |
2760 | 2934 |
|
2761 | 2935 | // Render initial state |
2762 | 2936 | updateProviderCounts(); |
|
0 commit comments