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); |