Skip to content
Open
65 changes: 56 additions & 9 deletions _includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,61 @@
</span>
</a>

<!-- Navigation (Desktop) -->
<nav class="hidden md:flex gap-8 text-sm font-medium text-gray-600">
{% for item in site.navigation %}
<a href="{{ item.url | relative_url }}" class="{% if page.url == item.url %}
text-bltRed border-b-2 border-bltRed pb-1
{% else %}
hover:text-gray-900 transition-colors
{% endif %}">
{{ item.title }}
</a>
{% endfor %}
</nav>


<div class=" flex items-center gap-2 ">
<!-- Theme Toggle -->
<button id="theme-toggle"
aria-label="Toggle Dark Mode"
class="rounded-lg p-2 text-gray-500 transition hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-white">
<i id="theme-icon" class="fas fa-sun hidden dark:block"></i>
<i id="theme-icon-dark" class="fas fa-moon block dark:hidden"></i>
</button>

<!-- Mobile Menu Button -->
<button id="mobile-menu-button" type="button"
class="md:hidden p-2 text-gray-600 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-bltRed/20 rounded-md transition-all duration-200"
aria-label="Toggle navigation"
aria-controls="mobile-menu"
aria-expanded="false">
<svg id="menu-icon" class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
</svg>
<svg id="close-icon" class="hidden w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>

</div>

</div>

<!-- Mobile Menu -->
<div id="mobile-menu"
class="hidden md:hidden absolute top-16 left-0 w-full bg-white border-b border-gray-100 shadow-xl overflow-hidden transition-all duration-300 ease-in-out opacity-0 max-h-0">
<nav class="flex flex-col gap-1 p-4 text-sm font-medium text-gray-600">
{% for item in site.navigation %}
<a href="{{ item.url | relative_url }}" class="px-4 py-3 rounded-lg transition-all duration-200 {% if page.url == item.url %}
bg-bltRedLight text-bltRed font-semibold
{% else %}
hover:bg-gray-50 hover:text-gray-900
{% endif %}">
{{ item.title }}
</a>
{% endfor %}
</nav>
<nav class="hidden items-center gap-8 md:flex">
{% for item in site.navigation %}
<a href="{{ item.url | relative_url }}"
Expand All @@ -24,14 +79,6 @@
{% endfor %}
</nav>

<div class="flex items-center gap-4">
<!-- Theme Toggle -->
<button id="theme-toggle"
aria-label="Toggle Dark Mode"
class="rounded-lg p-2 text-gray-500 transition hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-white">
<i id="theme-icon" class="fas fa-sun hidden dark:block"></i>
<i id="theme-icon-dark" class="fas fa-moon block dark:hidden"></i>
</button>
</div>

</div>
</header>
18 changes: 12 additions & 6 deletions _layouts/default.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<!DOCTYPE html>
<html lang="en" class="scroll-smooth">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% if page.title %}{{ page.title }} - {% endif %}{{ site.title | default: "BLT University" }}</title>
<meta name="description" content="{{ page.description | default: site.description }}">

{% seo %}

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
Expand Down Expand Up @@ -37,18 +38,23 @@
float: '0 30px 60px -15px rgba(0,0,0,0.08)'
}
}
}
},
safelist: [
'max-h-[500px]',
'opacity-100'
]
}
</script>
</head>
<body class="bg-[#fafafa] dark:bg-gray-900 text-gray-900 dark:text-gray-100 font-sans antialiased selection:bg-bltRed selection:text-white flex flex-col min-h-screen">

{% include header.html %}

{{ content }}

{% include footer.html %}

<script src="{{ '/assets/js/main.js' | relative_url }}"></script>
</body>

</html>
77 changes: 70 additions & 7 deletions assets/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ document.addEventListener('DOMContentLoaded', function() {

if (categoryFilter && levelFilter && searchFilter && coursesGrid) {
function filterCourses() {
const categoryValue = (categoryFilter.value || '').toLowerCase();
const levelValue = (levelFilter.value || '').toLowerCase();
const searchValue = (searchFilter.value || '').toLowerCase().trim();
const categoryValue = categoryFilter.value.toLowerCase();
const levelValue = levelFilter.value.toLowerCase();
const searchValue = searchFilter.value.trim().toLowerCase();

const courses = coursesGrid.getElementsByClassName('course-card');
let visibleCount = 0;

Array.from(courses).forEach(course => {
const courseCategory = course.getAttribute('data-category') || '';
const courseLevel = course.getAttribute('data-level') || '';
const courseSearch = course.getAttribute('data-search') || '';
const courseCategory = course.getAttribute('data-category');
const courseLevel = course.getAttribute('data-level');
const courseSearch = course.getAttribute('data-search') ?? '';

const categoryMatch = !categoryValue || courseCategory === categoryValue;
const levelMatch = !levelValue || courseLevel === levelValue;
Expand Down Expand Up @@ -109,9 +109,72 @@ document.addEventListener('DOMContentLoaded', function() {
});
});

// Mobile Menu Toggle
const mobileMenuButton = document.getElementById('mobile-menu-button');
const mobileMenu = document.getElementById('mobile-menu');
const menuIcon = document.getElementById('menu-icon');
const closeIcon = document.getElementById('close-icon');
let mobileMenuTimer = null;

if (mobileMenuButton && mobileMenu && menuIcon && closeIcon) {
const openMenu = () => {
if (mobileMenuTimer) {
clearTimeout(mobileMenuTimer);
mobileMenuTimer = null;
}
mobileMenu.classList.remove('hidden');
// Trigger reflow for transition
mobileMenu.offsetHeight;
mobileMenu.classList.remove('max-h-0', 'opacity-0');
mobileMenu.classList.add('max-h-[500px]', 'opacity-100');
menuIcon.classList.add('hidden');
closeIcon.classList.remove('hidden');
mobileMenuButton.setAttribute('aria-expanded', 'true');
};

const closeMenu = () => {
mobileMenu.classList.remove('max-h-[500px]', 'opacity-100');
mobileMenu.classList.add('max-h-0', 'opacity-0');
menuIcon.classList.remove('hidden');
closeIcon.classList.add('hidden');
mobileMenuButton.setAttribute('aria-expanded', 'false');

if (mobileMenuTimer) clearTimeout(mobileMenuTimer);
mobileMenuTimer = setTimeout(() => {
mobileMenu.classList.add('hidden');
mobileMenuTimer = null;
}, 300); // Wait for transition to finish
};

mobileMenuButton.addEventListener('click', () => {
if (mobileMenuButton.getAttribute('aria-expanded') === 'true') {
closeMenu();
} else {
openMenu();
}
});

// Close menu on resize if screen becomes desktop-sized
window.addEventListener('resize', () => {
if (window.innerWidth >= 768) {
if (mobileMenuTimer) {
clearTimeout(mobileMenuTimer);
mobileMenuTimer = null;
}

mobileMenu.classList.add('hidden');
mobileMenu.classList.add('max-h-0', 'opacity-0');
mobileMenu.classList.remove('max-h-[500px]', 'opacity-100');
menuIcon.classList.remove('hidden');
closeIcon.classList.add('hidden');
mobileMenuButton.setAttribute('aria-expanded', 'false');
}
});
}

// Add active class to current navigation item
const currentPath = window.location.pathname;
document.querySelectorAll('.site-navigation a').forEach(link => {
document.querySelectorAll('.site-navigation a, #mobile-menu a').forEach(link => {
if (link.getAttribute('href') === currentPath) {
link.classList.add('active');
}
Expand Down
Loading