Generaltoa's picture
Create a yoga studio website with calming hero section, class types with descriptions, instructor bios with photos, weekly schedule calendar, pricing packages, meditation tips blog, studio location map, and booking form.
e50934a verified
class CustomNavbar extends HTMLElement {
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
width: 100%;
position: sticky;
top: 0;
z-index: 1000;
}
nav {
background: rgba(17, 24, 39, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.nav-container {
max-width: 1280px;
margin: 0 auto;
padding: 0 1rem;
}
.nav-content {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 0;
}
.logo {
display: flex;
align-items: center;
gap: 0.75rem;
text-decoration: none;
}
.logo-text {
font-size: 1.5rem;
font-weight: 700;
background: linear-gradient(135deg, #0ea5e9 0%, #ec4899 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.nav-links {
display: flex;
gap: 2rem;
align-items: center;
}
.nav-link {
color: #d1d5db;
text-decoration: none;
font-weight: 500;
transition: color 0.3s;
position: relative;
}
.nav-link:hover {
color: #ffffff;
}
.nav-link::after {
content: '';
position: absolute;
bottom: -4px;
left: 0;
width: 0;
height: 2px;
background: linear-gradient(90deg, #0ea5e9, #ec4899);
transition: width 0.3s;
}
.nav-link:hover::after {
width: 100%;
}
.mobile-menu-btn {
display: none;
background: none;
border: none;
color: #d1d5db;
cursor: pointer;
padding: 0.5rem;
}
.mobile-menu {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
background: rgba(17, 24, 39, 0.98);
padding: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.mobile-nav-links {
display: flex;
flex-direction: column;
gap: 1rem;
}
.mobile-nav-link {
color: #d1d5db;
text-decoration: none;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
transition: background 0.3s;
}
.mobile-nav-link:hover {
background: rgba(255, 255, 255, 0.1);
}
@media (max-width: 768px) {
.nav-links {
display: none;
}
.mobile-menu-btn {
display: block;
}
.mobile-menu.active {
display: block;
}
}
@media (min-width: 769px) {
.mobile-menu {
display: none !important;
}
}
.book-now-btn {
background: linear-gradient(135deg, #0ea5e9 0%, #ec4899 100%);
color: white;
padding: 0.75rem 1.5rem;
border-radius: 9999px;
font-weight: 600;
text-decoration: none;
transition: transform 0.3s, box-shadow 0.3s;
}
.book-now-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(14, 165, 233, 0.3);
}
.theme-toggle {
background: none;
border: none;
color: #d1d5db;
cursor: pointer;
padding: 0.5rem;
border-radius: 0.5rem;
transition: background 0.3s;
}
.theme-toggle:hover {
background: rgba(255, 255, 255, 0.1);
}
</style>
<nav>
<div class="nav-container">
<div class="nav-content">
<a href="/" class="logo">
<i data-feather="activity"></i>
<span class="logo-text">ZenFlow Harmony</span>
</a>
<div class="nav-links">
<a href="#classes" class="nav-link">Classes</a>
<a href="#instructors" class="nav-link">Instructors</a>
<a href="#schedule" class="nav-link">Schedule</a>
<a href="#pricing" class="nav-link">Pricing</a>
<a href="#blog" class="nav-link">Blog</a>
<a href="#location" class="nav-link">Location</a>
<button class="theme-toggle" id="themeToggle">
<i data-feather="moon"></i>
</button>
<a href="#booking" class="book-now-btn">Book Now</a>
</div>
<button class="mobile-menu-btn" id="mobileMenuBtn">
<i data-feather="menu"></i>
</button>
</div>
<div class="mobile-menu" id="mobileMenu">
<div class="mobile-nav-links">
<a href="#classes" class="mobile-nav-link">Classes</a>
<a href="#instructors" class="mobile-nav-link">Instructors</a>
<a href="#schedule" class="mobile-nav-link">Schedule</a>
<a href="#pricing" class="mobile-nav-link">Pricing</a>
<a href="#blog" class="mobile-nav-link">Blog</a>
<a href="#location" class="mobile-nav-link">Location</a>
<button class="mobile-nav-link theme-toggle" id="mobileThemeToggle">
<span style="display: flex; align-items: center; gap: 0.5rem;">
<i data-feather="moon"></i> Toggle Theme
</span>
</button>
<a href="#booking" class="mobile-nav-link" style="background: linear-gradient(135deg, #0ea5e9 0%, #ec4899 100%); color: white; text-align: center;">Book Now</a>
</div>
</div>
</div>
</nav>
`;
// Initialize mobile menu
const mobileMenuBtn = this.shadowRoot.getElementById('mobileMenuBtn');
const mobileMenu = this.shadowRoot.getElementById('mobileMenu');
const themeToggle = this.shadowRoot.getElementById('themeToggle');
const mobileThemeToggle = this.shadowRoot.getElementById('mobileThemeToggle');
mobileMenuBtn.addEventListener('click', () => {
mobileMenu.classList.toggle('active');
const icon = mobileMenuBtn.querySelector('i');
if (mobileMenu.classList.contains('active')) {
icon.setAttribute('data-feather', 'x');
} else {
icon.setAttribute('data-feather', 'menu');
}
feather.replace();
});
// Theme toggle functionality
const toggleTheme = () => {
const html = document.documentElement;
if (html.classList.contains('dark')) {
html.classList.remove('dark');
localStorage.setItem('theme', 'light');
} else {
html.classList.add('dark');
localStorage.setItem('theme', 'dark');
}
// Update icons
feather.replace();
};
if (themeToggle) {
themeToggle.addEventListener('click', toggleTheme);
}
if (mobileThemeToggle) {
mobileThemeToggle.addEventListener('click', toggleTheme);
}
// Close mobile menu when clicking outside
document.addEventListener('click', (e) => {
if (!this.shadowRoot.contains(e.target) && mobileMenu.classList.contains('active')) {
mobileMenu.classList.remove('active');
const icon = mobileMenuBtn.querySelector('i');
icon.setAttribute('data-feather', 'menu');
feather.replace();
}
});
// Close mobile menu when clicking a link
const mobileLinks = this.shadowRoot.querySelectorAll('.mobile-nav-link');
mobileLinks.forEach(link => {
link.addEventListener('click', () => {
mobileMenu.classList.remove('active');
const icon = mobileMenuBtn.querySelector('i');
icon.setAttribute('data-feather', 'menu');
feather.replace();
});
});
// Initialize feather icons in shadow DOM
const featherScript = document.createElement('script');
featherScript.src = 'https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js';
this.shadowRoot.appendChild(featherScript);
featherScript.onload = () => {
feather.replace();
};
}
}
customElements.define('custom-navbar', CustomNavbar);