Create a modern, attractive SaaS website landing page with the use of smart gradients and slick animations including appealing, modern mouse hover animations.
0bfd444 verified Download script.js from wanderingcloud/gradientflow-saas: direct link, hf CLI and curl.
- Browser
- Download file 4.01 kB
-
https://huggingface.co/spaces/wanderingcloud/gradientflow-saas/resolve/main/script.js
- Command line
-
hf download hf://spaces/wanderingcloud/gradientflow-saas/script.js
-
curl -L -o script.js https://huggingface.co/spaces/wanderingcloud/gradientflow-saas/resolve/main/script.js
4.01 kB
| // Theme management | |
| const themeManager = { | |
| init() { | |
| this.loadTheme(); | |
| this.bindEvents(); | |
| }, | |
| loadTheme() { | |
| const savedTheme = localStorage.getItem('theme') || 'system'; | |
| this.applyTheme(savedTheme); | |
| }, | |
| applyTheme(theme) { | |
| const root = document.documentElement; | |
| if (theme === 'dark') { | |
| root.classList.add('dark'); | |
| } else if (theme === 'light') { | |
| root.classList.remove('dark'); | |
| } else { | |
| // System preference | |
| const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; | |
| if (prefersDark) { | |
| root.classList.add('dark'); | |
| } else { | |
| root.classList.remove('dark'); | |
| } | |
| } | |
| // Update theme toggle | |
| const themeToggle = document.querySelector('custom-theme-toggle'); | |
| if (themeToggle) { | |
| themeToggle.setAttribute('current-theme', theme); | |
| } | |
| }, | |
| setTheme(theme) { | |
| localStorage.setItem('theme', theme); | |
| this.applyTheme(theme); | |
| }, | |
| bindEvents() { | |
| window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { | |
| if (localStorage.getItem('theme') === 'system') { | |
| this.applyTheme('system'); | |
| } | |
| }); | |
| } | |
| }; | |
| // Pricing toggle functionality | |
| const pricingManager = { | |
| init() { | |
| this.isYearly = false; | |
| this.bindEvents(); | |
| }, | |
| bindEvents() { | |
| const monthlyBtn = document.getElementById('monthly-btn'); | |
| const yearlyBtn = document.getElementById('yearly-btn'); | |
| const toggle = document.getElementById('billing-toggle'); | |
| if (monthlyBtn && yearlyBtn) { | |
| monthlyBtn.addEventListener('click', () => this.setBilling(false)); | |
| yearlyBtn.addEventListener('click', () => this.setBilling(true)); | |
| } | |
| }, | |
| setBilling(yearly) { | |
| this.isYearly = yearly; | |
| const monthlyBtn = document.getElementById('monthly-btn'); | |
| const yearlyBtn = document.getElementById('yearly-btn'); | |
| const toggle = document.getElementById('billing-toggle'); | |
| if (yearly) { | |
| toggle.classList.add('yearly'); | |
| monthlyBtn.classList.remove('text-white'); | |
| yearlyBtn.classList.add('text-white'); | |
| } else { | |
| toggle.classList.remove('yearly'); | |
| monthlyBtn.classList.add('text-white'); | |
| yearlyBtn.classList.remove('text-white'); | |
| } | |
| // Update pricing cards | |
| const pricingCards = document.querySelectorAll('custom-pricing-card'); | |
| pricingCards.forEach(card => { | |
| card.setAttribute('yearly', yearly); | |
| }); | |
| } | |
| }; | |
| // Smooth scrolling | |
| const smoothScroll = { | |
| init() { | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| const target = document.querySelector(this.getAttribute('href')); | |
| if (target) { | |
| target.scrollIntoView({ | |
| behavior: 'smooth', | |
| block: 'start' | |
| }); | |
| } | |
| }); | |
| }); | |
| } | |
| }; | |
| // Initialize everything | |
| document.addEventListener('DOMContentLoaded', () => { | |
| themeManager.init(); | |
| pricingManager.init(); | |
| smoothScroll.init(); | |
| }); | |
| // Intersection Observer for animations | |
| const observerOptions = { | |
| threshold: 0.1, | |
| rootMargin: '0px 0px -100px 0px' | |
| }; | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add('animate-in'); | |
| } | |
| }); | |
| }, observerOptions); | |
| document.addEventListener('DOMContentLoaded', () => { | |
| document.querySelectorAll('.feature-card').forEach(el => observer.observe(el)); | |
| }); |