| |
| (function initTheme() { |
| const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; |
| const saved = localStorage.getItem('theme'); |
| const root = document.documentElement; |
|
|
| const setTheme = (mode) => { |
| if (mode === 'dark') { |
| root.classList.add('dark'); |
| } else { |
| root.classList.remove('dark'); |
| } |
| localStorage.setItem('theme', mode); |
| |
| const iconEl = document.querySelector('#themeToggle i'); |
| if (iconEl) { |
| iconEl.setAttribute('data-feather', mode === 'dark' ? 'sun' : 'moon'); |
| if (window.feather) feather.replace(); |
| } |
| }; |
|
|
| setTheme(saved || (prefersDark ? 'dark' : 'light')); |
| })(); |
|
|
| document.getElementById('themeToggle')?.addEventListener('click', () => { |
| const isDark = document.documentElement.classList.contains('dark'); |
| const next = isDark ? 'light' : 'dark'; |
| if (next === 'dark') { |
| document.documentElement.classList.add('dark'); |
| } else { |
| document.documentElement.classList.remove('dark'); |
| } |
| localStorage.setItem('theme', next); |
| const iconEl = document.querySelector('#themeToggle i'); |
| if (iconEl) { |
| iconEl.setAttribute('data-feather', next === 'dark' ? 'sun' : 'moon'); |
| if (window.feather) feather.replace(); |
| } |
| }); |
|
|
| |
| document.getElementById('year').textContent = new Date().getFullYear(); |
|
|
| |
| document.querySelectorAll('button[data-copy]').forEach((btn) => { |
| btn.addEventListener('click', async () => { |
| const sel = btn.getAttribute('data-copy'); |
| const codeEl = document.querySelector(sel); |
| const text = codeEl?.innerText || ''; |
| try { |
| await navigator.clipboard.writeText(text); |
| const label = btn.querySelector('.copy-label'); |
| if (label) label.textContent = 'Copied!'; |
| setTimeout(() => { |
| if (label) label.textContent = 'Copy'; |
| }, 1500); |
| } catch (e) { |
| console.error('Copy failed', e); |
| } |
| }); |
| }); |
|
|
| |
| function handleSignup(formId, messageId) { |
| const form = document.getElementById(formId); |
| const msg = document.getElementById(messageId); |
| if (!form) return; |
|
|
| form.addEventListener('submit', async (e) => { |
| e.preventDefault(); |
| const email = form.querySelector('input[type="email"]')?.value?.trim(); |
| const password = form.querySelector('input[type="password"]')?.value; |
|
|
| if (!email) return; |
| if (formId === 'signupModalForm' && password && password.length < 8) { |
| if (msg) msg.textContent = 'Password must be at least 8 characters.'; |
| return; |
| } |
|
|
| |
| if (msg) msg.textContent = 'Creating your workspace...'; |
| await new Promise((r) => setTimeout(r, 900)); |
| if (msg) msg.textContent = 'Success! Check your email to verify your account.'; |
|
|
| |
| if (formId === 'signupModalForm') closeSignupModal(); |
|
|
| |
| form.reset(); |
| }); |
| } |
|
|
| handleSignup('signupForm', 'formMessage'); |
| handleSignup('signupModalForm', 'modalMessage'); |
|
|
| |
| const openSignupButtons = ['openSignupTop', 'openSignupHero', 'openSignupPricing'] |
| .map((id) => document.getElementById(id)) |
| .filter(Boolean); |
|
|
| const modal = document.getElementById('signupModal'); |
| const closeBtn = document.getElementById('closeSignup'); |
|
|
| function openSignupModal() { |
| modal?.classList.remove('hidden'); |
| modal?.classList.add('flex'); |
| document.getElementById('modalEmail')?.focus(); |
| } |
| function closeSignupModal() { |
| modal?.classList.add('hidden'); |
| modal?.classList.remove('flex'); |
| } |
|
|
| openSignupButtons.forEach((btn) => btn.addEventListener('click', openSignupModal)); |
| closeBtn?.addEventListener('click', closeSignupModal); |
| modal?.addEventListener('click', (e) => { |
| if (e.target === modal) closeSignupModal(); |
| }); |
| document.addEventListener('keydown', (e) => { |
| if (e.key === 'Escape') closeSignupModal(); |
| }); |
|
|
| |
| const heroVideo = document.getElementById('heroVideo'); |
| const observer = new MutationObserver(() => { |
| if (modal?.classList.contains('hidden') === false && !heroVideo?.paused) { |
| heroVideo?.pause(); |
| } |
| }); |
| observer.observe(modal, { attributes: true, attributeFilter: ['class'] }); |