| |
| function initIcons() { |
| if (typeof lucide !== 'undefined') { |
| lucide.createIcons(); |
| } |
| } |
| initIcons(); |
|
|
| |
| (function () { |
| const root = document.documentElement; |
| const toggle = document.getElementById('theme-toggle'); |
| const stored = localStorage.getItem('omniverse-theme'); |
|
|
| |
| const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; |
| const initialTheme = stored || (prefersDark ? 'dark' : 'dark'); |
|
|
| if (initialTheme === 'light') { |
| root.classList.remove('dark'); |
| } else { |
| root.classList.add('dark'); |
| } |
|
|
| toggle?.addEventListener('click', () => { |
| root.classList.toggle('dark'); |
| const isDark = root.classList.contains('dark'); |
| localStorage.setItem('omniverse-theme', isDark ? 'dark' : 'light'); |
| initIcons(); |
| }); |
| })(); |
|
|
| |
| (function () { |
| const navbar = document.getElementById('navbar'); |
| let ticking = false; |
|
|
| function updateNavbar() { |
| if (window.scrollY > 20) { |
| navbar.classList.add('scrolled'); |
| } else { |
| navbar.classList.remove('scrolled'); |
| } |
| ticking = false; |
| } |
|
|
| window.addEventListener('scroll', () => { |
| if (!ticking) { |
| requestAnimationFrame(updateNavbar); |
| ticking = true; |
| } |
| }); |
| })(); |
|
|
| |
| (function () { |
| const toggle = document.getElementById('mobile-toggle'); |
| const menu = document.getElementById('mobile-menu'); |
| const menuIcon = document.getElementById('menu-icon'); |
| let isOpen = false; |
|
|
| function toggleMenu() { |
| isOpen = !isOpen; |
| if (isOpen) { |
| menu.classList.remove('hidden'); |
| menuIcon.setAttribute('data-lucide', 'x'); |
| } else { |
| menu.classList.add('hidden'); |
| menuIcon.setAttribute('data-lucide', 'menu'); |
| } |
| initIcons(); |
| } |
|
|
| toggle?.addEventListener('click', toggleMenu); |
|
|
| |
| menu?.querySelectorAll('a').forEach((link) => { |
| link.addEventListener('click', () => { |
| if (isOpen) toggleMenu(); |
| }); |
| }); |
|
|
| |
| document.addEventListener('click', (e) => { |
| if (isOpen && !menu.contains(e.target) && !toggle.contains(e.target)) { |
| toggleMenu(); |
| } |
| }); |
| })(); |
|
|
| |
| (function () { |
| const reveals = document.querySelectorAll('.reveal'); |
|
|
| const observer = new IntersectionObserver( |
| (entries) => { |
| entries.forEach((entry) => { |
| if (entry.isIntersecting) { |
| entry.target.classList.add('revealed'); |
| observer.unobserve(entry.target); |
| } |
| }); |
| }, |
| { threshold: 0.12, rootMargin: '0px 0px -60px 0px' } |
| ); |
|
|
| reveals.forEach((el) => observer.observe(el)); |
| })(); |
|
|
| |
| (function () { |
| const faqItems = document.querySelectorAll('.faq-item'); |
|
|
| faqItems.forEach((item) => { |
| const trigger = item.querySelector('.faq-trigger'); |
| trigger?.addEventListener('click', () => { |
| const isActive = item.classList.contains('active'); |
|
|
| |
| faqItems.forEach((other) => { |
| other.classList.remove('active'); |
| const otherTrigger = other.querySelector('.faq-trigger'); |
| if (otherTrigger) otherTrigger.setAttribute('aria-expanded', 'false'); |
| }); |
|
|
| |
| if (!isActive) { |
| item.classList.add('active'); |
| trigger.setAttribute('aria-expanded', 'true'); |
| } |
| }); |
| }); |
| })(); |
|
|
| |
| (function () { |
| const form = document.getElementById('contact-form'); |
|
|
| form?.addEventListener('submit', (e) => { |
| e.preventDefault(); |
|
|
| const name = document.getElementById('name')?.value.trim() || ''; |
| const clientType = document.getElementById('client-type')?.value || ''; |
| const service = document.getElementById('service')?.value || ''; |
| const notes = document.getElementById('notes')?.value.trim() || ''; |
|
|
| if (!name) return; |
|
|
| const message = [ |
| `Halo Omniverse One,`, |
| ``, |
| `Nama: ${name}`, |
| `Kategori Klien: ${clientType}`, |
| `Layanan: ${service}`, |
| notes ? `Catatan: ${notes}` : '', |
| ] |
| .filter(Boolean) |
| .join('\n'); |
|
|
| const encoded = encodeURIComponent(message); |
| window.open(`https://wa.me/?text=${encoded}`, '_blank'); |
| }); |
| })(); |
|
|
| |
| (function () { |
| const btn = document.getElementById('back-to-top'); |
| let ticking = false; |
|
|
| function updateBtn() { |
| if (window.scrollY > 600) { |
| btn?.classList.remove('hidden'); |
| btn?.classList.add('flex'); |
| } else { |
| btn?.classList.add('hidden'); |
| btn?.classList.remove('flex'); |
| } |
| ticking = false; |
| } |
|
|
| window.addEventListener('scroll', () => { |
| if (!ticking) { |
| requestAnimationFrame(updateBtn); |
| ticking = true; |
| } |
| }); |
|
|
| btn?.addEventListener('click', () => { |
| window.scrollTo({ top: 0, behavior: 'smooth' }); |
| }); |
| })(); |
|
|
| |
| document.getElementById('year').textContent = new Date().getFullYear(); |
|
|
| |
| (function () { |
| const sections = document.querySelectorAll('section[id]'); |
| const navLinks = document.querySelectorAll('.nav-link'); |
|
|
| const observer = new IntersectionObserver( |
| (entries) => { |
| entries.forEach((entry) => { |
| if (entry.isIntersecting) { |
| const id = entry.target.getAttribute('id'); |
| navLinks.forEach((link) => { |
| const href = link.getAttribute('href'); |
| if (href === `#${id}`) { |
| link.style.color = 'var(--foreground)'; |
| } else { |
| link.style.color = ''; |
| } |
| }); |
| } |
| }); |
| }, |
| { threshold: 0.3, rootMargin: '-80px 0px -50% 0px' } |
| ); |
|
|
| sections.forEach((sec) => observer.observe(sec)); |
| })(); |
|
|
| |
| document.querySelectorAll('a[href^="#"]').forEach((anchor) => { |
| anchor.addEventListener('click', function (e) { |
| const href = this.getAttribute('href'); |
| if (href === '#') return; |
| const target = document.querySelector(href); |
| if (target) { |
| e.preventDefault(); |
| const offset = 80; |
| const top = target.getBoundingClientRect().top + window.scrollY - offset; |
| window.scrollTo({ top, behavior: 'smooth' }); |
| } |
| }); |
| }); |
|
|
| |
| setTimeout(initIcons, 100); |