diff --git a/dark-mode-toggle.html b/dark-mode-toggle.html new file mode 100644 index 00000000..adafd5c6 --- /dev/null +++ b/dark-mode-toggle.html @@ -0,0 +1,805 @@ + + + + + + Dark Mode Toggle - CodeClip + + + + + + + + + + Back to Home + + +
+
+
🌓
+ +
+
+

Dark Mode Toggle

+

Experience smooth theme transitions with beautiful effects

+
+ +
+ + + Light Mode + + + + + Dark Mode + +
+ +
+ +
+
+ +
+

Theme Customization

+

+ Seamlessly switch between light and dark themes with smooth animations and transitions. +

+
    +
  • Instant theme switching
  • +
  • Smooth color transitions
  • +
  • Persistent user preferences
  • +
  • System theme detection
  • +
+ +
+ + +
+
+ +
+

Eye Comfort

+

+ Dark mode reduces eye strain during nighttime browsing and extends battery life on OLED displays. +

+
    +
  • Reduced eye strain
  • +
  • Better for low light
  • +
  • Battery conservation
  • +
  • Modern aesthetic
  • +
+ +
+ + +
+
+ +
+

Advanced Features

+

+ Built with CSS custom properties, smooth transitions, and particle effects for enhanced user experience. +

+
    +
  • CSS custom properties
  • +
  • Particle animations
  • +
  • Responsive design
  • +
  • Accessibility support
  • +
+ +
+
+
+ + + + diff --git a/login-form.html b/login-form.html new file mode 100644 index 00000000..28d42c3b --- /dev/null +++ b/login-form.html @@ -0,0 +1,716 @@ + + + + + + Modern Login Form - CodeClip + + + + + + + + + + + + + + ← Back to Challenges + +
+
+

Welcome Back

+

Sign in to your account to continue

+
+ +
+
Login
+
Sign Up
+
+ +
+ + +
+ + + +
Please enter a valid email address
+
+ +
+ + + +
Password must be at least 8 characters long
+
+ + + + + + +
+ +
+ or continue with +
+ +
+ + +
+
+ + + + diff --git a/pricing-card.html b/pricing-card.html new file mode 100644 index 00000000..d2886c10 --- /dev/null +++ b/pricing-card.html @@ -0,0 +1,519 @@ + + + + + + Modern Pricing Cards - CodeClip + + + + + + + + + + + + + + ← Back to Home + +
+
+

Modern Pricing Cards

+

Choose the perfect plan for your needs

+
+ +
+ Flexbox + + Grid +
+ + +
+
+
Starter
+
Perfect for individuals getting started
+
+ $9 + /month +
+
    +
  • 5 Projects
  • +
  • 10GB Storage
  • +
  • Email Support
  • +
  • Basic Analytics
  • +
  • Advanced Features
  • +
  • Priority Support
  • +
+ +
+ + + +
+
Enterprise
+
For large organizations with custom needs
+
+ $99 + /month +
+
    +
  • Unlimited Projects
  • +
  • Unlimited Storage
  • +
  • 24/7 Phone Support
  • +
  • Advanced Analytics
  • +
  • Custom Integrations
  • +
  • Dedicated Manager
  • +
+ +
+
+ + + +
+ + + + diff --git a/profile-card.html b/profile-card.html new file mode 100644 index 00000000..3c38b94b --- /dev/null +++ b/profile-card.html @@ -0,0 +1,652 @@ + + + + + + Profile Card UI - CodeClip + + + + + + + + + + Back to Home + + + + +
+
+

Profile Card UI

+

Modern profile cards with glassmorphism effects

+
+ +
+ +
+
+ Alex Johnson +
+
+

Alex Johnson

+

Full Stack Developer

+

Passionate developer with 5+ years of experience in creating amazing web applications. Love working with modern technologies.

+ +
+
+ 127 + Projects +
+
+ 2.3k + Followers +
+
+ 892 + Following +
+
+ + + + + + Contact Me + +
+
+ + +
+
+ Sarah Chen +
+
+

Sarah Chen

+

UI/UX Designer

+

Creative designer focused on crafting beautiful and intuitive user experiences. Specializing in mobile and web design.

+ +
+
+ 89 + Designs +
+
+ 1.8k + Likes +
+
+ 456 + Following +
+
+ + + + + + View Portfolio + +
+
+ + +
+
+ Mike Torres +
+
+

Mike Torres

+

Product Manager

+

Strategic product leader with expertise in bringing innovative digital products from concept to market. Love solving complex problems.

+ +
+
+ 15 + Products +
+
+ 3.2k + Connections +
+
+ 1.1k + Following +
+
+ + + + + + Let's Connect + +
+
+
+
+ + + + diff --git a/responsive-navbar.html b/responsive-navbar.html new file mode 100644 index 00000000..9bfe61c4 --- /dev/null +++ b/responsive-navbar.html @@ -0,0 +1,897 @@ + + + + + + Responsive Navbar - CodeClip + + + + + + + + + + + + + + + + + +
+
+

Responsive Navbar

+

A modern navigation bar with dropdown menus and mobile hamburger menu

+
+ +
+

Features

+
+
    +
  • Responsive design that adapts to all screen sizes
  • +
  • Smooth hamburger menu animation for mobile
  • +
  • Dropdown menus with hover effects
  • +
  • Glassmorphism effect with backdrop blur
  • +
  • Active link highlighting
  • +
  • Scroll-based navbar styling changes
  • +
  • Accessibility features with keyboard navigation
  • +
+
+
+ +
+

How It Works

+
+

Desktop View: The navbar displays all menu items horizontally with dropdown functionality on hover.

+
+

Mobile View: The hamburger menu appears, and clicking it reveals a full-screen mobile menu with collapsible dropdowns.

+
+

Responsive Breakpoints: The navbar automatically switches to mobile mode at 768px viewport width.

+
+
+ +
+

Technical Implementation

+
+

CSS Features:

+
    +
  • Flexbox layout for perfect alignment
  • +
  • CSS transitions for smooth animations
  • +
  • Media queries for responsive behavior
  • +
  • Transform effects for hamburger animation
  • +
+
+

JavaScript Features:

+
    +
  • Event listeners for menu interactions
  • +
  • Scroll detection for navbar styling
  • +
  • Mobile dropdown toggle functionality
  • +
  • Active link management
  • +
+
+
+
+ + + + + + + + + diff --git a/scripts/dark-mode-toggle.js b/scripts/dark-mode-toggle.js new file mode 100644 index 00000000..2f26546e --- /dev/null +++ b/scripts/dark-mode-toggle.js @@ -0,0 +1,364 @@ +// Dark Mode Toggle JavaScript +class DarkModeToggle { + constructor() { + this.toggleSwitch = document.querySelector('#checkbox'); + this.currentTheme = localStorage.getItem('theme') || 'light'; + this.particles = []; + this.init(); + } + + init() { + // Set initial theme + document.documentElement.setAttribute('data-theme', this.currentTheme); + if (this.toggleSwitch) { + this.toggleSwitch.checked = this.currentTheme === 'dark'; + + // Add event listeners + this.toggleSwitch.addEventListener('change', () => this.switchTheme()); + } + + // Initialize particles + this.createParticles(); + + // Detect system theme preference + this.detectSystemTheme(); + + // Initialize scroll behavior + this.initScrollBehavior(); + + // Initialize other interactive features + this.initRippleEffects(); + this.initKeyboardNavigation(); + this.initIntersectionObserver(); + + console.log('Dark Mode Toggle initialized!'); + } + + switchTheme() { + const isChecked = this.toggleSwitch.checked; + const newTheme = isChecked ? 'dark' : 'light'; + + this.showTransitionEffect(newTheme); + + setTimeout(() => { + document.documentElement.setAttribute('data-theme', newTheme); + localStorage.setItem('theme', newTheme); + this.currentTheme = newTheme; + + // Update particles color + this.updateParticles(); + + // Show completion feedback + this.showToggleProgress(); + + // Emit custom event for other components + document.dispatchEvent(new CustomEvent('themeChanged', { + detail: { theme: newTheme } + })); + + }, 200); + } + + showTransitionEffect(theme) { + const transition = document.getElementById('themeTransition'); + if (transition) { + transition.classList.add('active'); + + setTimeout(() => { + transition.classList.remove('active'); + }, 600); + } + } + + showToggleProgress() { + const progress = document.getElementById('toggleProgress'); + if (progress) { + progress.innerHTML = this.currentTheme === 'dark' ? '🌙' : '☀️'; + progress.classList.add('show'); + + setTimeout(() => { + progress.classList.remove('show'); + }, 1000); + } + } + + createParticles() { + const particleContainer = document.getElementById('particles'); + if (!particleContainer) return; + + const particleCount = window.innerWidth < 768 ? 10 : 20; + + for (let i = 0; i < particleCount; i++) { + const particle = document.createElement('div'); + particle.classList.add('particle'); + + // Random positioning and size + const size = Math.random() * 4 + 2; + const startX = Math.random() * window.innerWidth; + const startY = Math.random() * window.innerHeight; + const animationDelay = Math.random() * 6; + + particle.style.width = `${size}px`; + particle.style.height = `${size}px`; + particle.style.left = `${startX}px`; + particle.style.top = `${startY}px`; + particle.style.animationDelay = `${animationDelay}s`; + + particleContainer.appendChild(particle); + this.particles.push(particle); + } + } + + updateParticles() { + this.particles.forEach(particle => { + particle.style.opacity = this.currentTheme === 'dark' ? '0.3' : '0.6'; + }); + } + + detectSystemTheme() { + // Set initial theme based on system preference if no saved preference + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches && !localStorage.getItem('theme')) { + this.currentTheme = 'dark'; + document.documentElement.setAttribute('data-theme', 'dark'); + if (this.toggleSwitch) { + this.toggleSwitch.checked = true; + } + } + + // Listen for system theme changes + if (window.matchMedia) { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { + // Only auto-switch if user hasn't manually set a preference + if (!localStorage.getItem('theme')) { + const newTheme = e.matches ? 'dark' : 'light'; + this.currentTheme = newTheme; + document.documentElement.setAttribute('data-theme', newTheme); + if (this.toggleSwitch) { + this.toggleSwitch.checked = e.matches; + } + this.updateParticles(); + } + }); + } + } + + initScrollBehavior() { + let lastScrollY = window.scrollY; + const backButton = document.querySelector('.back-home'); + + if (backButton) { + window.addEventListener('scroll', () => { + const currentScrollY = window.scrollY; + + if (currentScrollY > lastScrollY && currentScrollY > 100) { + backButton.classList.add('hidden-on-scroll'); + } else { + backButton.classList.remove('hidden-on-scroll'); + } + + lastScrollY = currentScrollY; + }); + } + } + + initRippleEffects() { + // Add ripple effects to buttons + document.addEventListener('click', function(e) { + if (e.target.classList.contains('card-button')) { + const ripple = document.createElement('span'); + const rect = e.target.getBoundingClientRect(); + const size = Math.max(rect.width, rect.height); + const x = e.clientX - rect.left - size / 2; + const y = e.clientY - rect.top - size / 2; + + ripple.style.width = ripple.style.height = size + 'px'; + ripple.style.left = x + 'px'; + ripple.style.top = y + 'px'; + ripple.style.position = 'absolute'; + ripple.style.borderRadius = '50%'; + ripple.style.background = 'rgba(255, 255, 255, 0.3)'; + ripple.style.transform = 'scale(0)'; + ripple.style.animation = 'ripple 0.6s linear'; + ripple.style.pointerEvents = 'none'; + + e.target.style.position = 'relative'; + e.target.style.overflow = 'hidden'; + e.target.appendChild(ripple); + + setTimeout(() => { + ripple.remove(); + }, 600); + } + }); + + // Add CSS for ripple animation if not already present + if (!document.querySelector('#ripple-styles')) { + const style = document.createElement('style'); + style.id = 'ripple-styles'; + style.textContent = ` + @keyframes ripple { + to { + transform: scale(4); + opacity: 0; + } + } + `; + document.head.appendChild(style); + } + } + + initKeyboardNavigation() { + // Keyboard navigation for toggle switch + document.addEventListener('keydown', (e) => { + if ((e.key === 'Enter' || e.key === ' ') && e.target.id === 'checkbox') { + e.preventDefault(); + e.target.checked = !e.target.checked; + e.target.dispatchEvent(new Event('change')); + } + }); + + // Enhanced focus management + const focusableElements = document.querySelectorAll( + 'a, button, input, [tabindex]:not([tabindex="-1"])' + ); + + focusableElements.forEach(element => { + element.addEventListener('focus', function() { + this.style.outline = '2px solid var(--accent-color)'; + this.style.outlineOffset = '2px'; + }); + + element.addEventListener('blur', function() { + this.style.outline = ''; + this.style.outlineOffset = ''; + }); + }); + } + + initIntersectionObserver() { + // Add intersection observer for animations + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.style.opacity = '1'; + entry.target.style.transform = 'translateY(0)'; + } + }); + }, observerOptions); + + // Observe all demo cards + document.querySelectorAll('.demo-card').forEach(card => { + observer.observe(card); + }); + } + + // Public method to get current theme + getCurrentTheme() { + return this.currentTheme; + } + + // Public method to set theme programmatically + setTheme(theme) { + if (theme === 'dark' || theme === 'light') { + this.currentTheme = theme; + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); + + if (this.toggleSwitch) { + this.toggleSwitch.checked = theme === 'dark'; + } + + this.updateParticles(); + this.showToggleProgress(); + } + } + + // Public method to toggle theme programmatically + toggle() { + const newTheme = this.currentTheme === 'dark' ? 'light' : 'dark'; + this.setTheme(newTheme); + } + + // Cleanup method + destroy() { + // Remove event listeners and clean up + this.particles.forEach(particle => particle.remove()); + this.particles = []; + + // Remove other event listeners if needed + console.log('Dark Mode Toggle destroyed'); + } +} + +// Auto-initialize when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + // Make DarkModeToggle globally available + window.darkModeToggle = new DarkModeToggle(); +}); + +// Export for module usage +if (typeof module !== 'undefined' && module.exports) { + module.exports = DarkModeToggle; +} + +// Additional utility functions +const ThemeUtils = { + // Get system preference + getSystemTheme: () => { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + return 'dark'; + } + return 'light'; + }, + + // Check if dark mode is supported + isDarkModeSupported: () => { + return window.matchMedia && window.matchMedia('(prefers-color-scheme)').media !== 'not all'; + }, + + // Apply theme to specific element + applyThemeToElement: (element, theme) => { + if (element) { + element.setAttribute('data-theme', theme); + } + }, + + // Get contrast ratio (simplified) + getContrastColor: (theme) => { + return theme === 'dark' ? '#e2e8f0' : '#2d3748'; + } +}; + +// Make utilities globally available +window.ThemeUtils = ThemeUtils; + +// Handle page visibility changes (pause animations when not visible) +document.addEventListener('visibilitychange', () => { + const particles = document.querySelectorAll('.particle'); + if (document.hidden) { + particles.forEach(particle => { + particle.style.animationPlayState = 'paused'; + }); + } else { + particles.forEach(particle => { + particle.style.animationPlayState = 'running'; + }); + } +}); + +// Handle window resize for particles +window.addEventListener('resize', () => { + if (window.darkModeToggle) { + // Recreate particles on resize for better distribution + window.darkModeToggle.particles.forEach(particle => particle.remove()); + window.darkModeToggle.particles = []; + window.darkModeToggle.createParticles(); + } +}); + +console.log('Dark Mode Toggle script loaded successfully!'); diff --git a/scripts/login-form.js b/scripts/login-form.js new file mode 100644 index 00000000..540aca75 --- /dev/null +++ b/scripts/login-form.js @@ -0,0 +1,514 @@ +/** + * Modern Login Form JavaScript + * CodeClip Project - Login/Signup Form Component + */ + +// DOM Elements +let toggleOptions, formTitle, formSubtitle, signupFields, forgotPassword; +let submitBtn, btnText, authForm, passwordToggles; +let currentMode = 'login'; + +// Initialize when DOM is loaded +document.addEventListener('DOMContentLoaded', function() { + initializeElements(); + setupEventListeners(); + setupPasswordToggles(); + setupFormValidation(); + setupAccessibility(); +}); + +/** + * Initialize DOM elements + */ +function initializeElements() { + toggleOptions = document.querySelectorAll('.toggle-option'); + formTitle = document.querySelector('.form-title'); + formSubtitle = document.querySelector('.form-subtitle'); + signupFields = document.querySelectorAll('.signup-fields'); + forgotPassword = document.getElementById('forgotPassword'); + submitBtn = document.getElementById('submitBtn'); + btnText = document.querySelector('.btn-text'); + authForm = document.getElementById('authForm'); + passwordToggles = document.querySelectorAll('.password-toggle'); +} + +/** + * Setup all event listeners + */ +function setupEventListeners() { + // Mode toggle listeners + toggleOptions.forEach(option => { + option.addEventListener('click', handleModeToggle); + }); + + // Form submission + authForm.addEventListener('submit', handleFormSubmit); + + // Social login buttons + const googleBtn = document.getElementById('googleBtn'); + const githubBtn = document.getElementById('githubBtn'); + + if (googleBtn) googleBtn.addEventListener('click', handleSocialLogin); + if (githubBtn) githubBtn.addEventListener('click', handleSocialLogin); + + // Forgot password link + const forgotLink = document.getElementById('forgotLink'); + if (forgotLink) forgotLink.addEventListener('click', handleForgotPassword); + + // Real-time validation + const inputs = document.querySelectorAll('.form-input'); + inputs.forEach(input => { + input.addEventListener('input', handleInputChange); + input.addEventListener('blur', handleInputBlur); + }); +} + +/** + * Handle mode toggle between login/signup + */ +function handleModeToggle(e) { + const mode = e.target.dataset.mode; + if (mode === currentMode) return; + + currentMode = mode; + updateFormMode(mode, e.target); +} + +/** + * Update form appearance based on mode + */ +function updateFormMode(mode, activeElement) { + // Update active toggle + toggleOptions.forEach(opt => opt.classList.remove('active')); + activeElement.classList.add('active'); + + // Update form content with smooth transitions + if (mode === 'signup') { + formTitle.style.opacity = '0'; + formSubtitle.style.opacity = '0'; + + setTimeout(() => { + formTitle.textContent = 'Create Account'; + formSubtitle.textContent = 'Sign up to get started with CodeClip'; + btnText.textContent = 'Create Account'; + formTitle.style.opacity = '1'; + formSubtitle.style.opacity = '1'; + }, 150); + + signupFields.forEach(field => field.classList.add('show')); + forgotPassword.style.display = 'none'; + } else { + formTitle.style.opacity = '0'; + formSubtitle.style.opacity = '0'; + + setTimeout(() => { + formTitle.textContent = 'Welcome Back'; + formSubtitle.textContent = 'Sign in to your account to continue'; + btnText.textContent = 'Sign In'; + formTitle.style.opacity = '1'; + formSubtitle.style.opacity = '1'; + }, 150); + + signupFields.forEach(field => field.classList.remove('show')); + forgotPassword.style.display = 'block'; + } + + // Clear form validation states + clearAllValidationStates(); +} + +/** + * Setup password toggle functionality + */ +function setupPasswordToggles() { + passwordToggles.forEach(toggle => { + toggle.addEventListener('click', function() { + const input = this.parentElement.querySelector('.form-input'); + const isPassword = input.type === 'password'; + + input.type = isPassword ? 'text' : 'password'; + this.classList.toggle('fa-eye', !isPassword); + this.classList.toggle('fa-eye-slash', isPassword); + }); + }); +} + +/** + * Setup form validation + */ +function setupFormValidation() { + const form = document.getElementById('authForm'); + if (form) { + form.setAttribute('novalidate', 'true'); + } +} + +/** + * Handle input changes for real-time feedback + */ +function handleInputChange(e) { + const field = e.target; + clearFieldError(field); + + // Provide real-time validation feedback for certain fields + if (field.name === 'email' && field.value.length > 0) { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (emailRegex.test(field.value)) { + field.classList.add('success'); + } else { + field.classList.remove('success'); + } + } + + // Password confirmation real-time check + if (field.name === 'confirmPassword' && currentMode === 'signup') { + const password = document.getElementById('password').value; + if (field.value && field.value === password) { + field.classList.add('success'); + } else { + field.classList.remove('success'); + } + } +} + +/** + * Handle input blur for validation + */ +function handleInputBlur(e) { + validateField(e.target); +} + +/** + * Validate individual field + */ +function validateField(field) { + const value = field.value.trim(); + const fieldName = field.name; + let isValid = true; + let errorMessage = ''; + + // Clear previous states + field.classList.remove('error', 'success'); + + // Skip validation for hidden fields + if (field.offsetParent === null) return true; + + switch(fieldName) { + case 'fullName': + if (currentMode === 'signup') { + if (value.length < 2) { + errorMessage = 'Please enter your full name (at least 2 characters)'; + isValid = false; + } else if (!/^[a-zA-Z\s]+$/.test(value)) { + errorMessage = 'Name should only contain letters and spaces'; + isValid = false; + } + } + break; + + case 'email': + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!value) { + errorMessage = 'Email address is required'; + isValid = false; + } else if (!emailRegex.test(value)) { + errorMessage = 'Please enter a valid email address'; + isValid = false; + } + break; + + case 'password': + if (!value) { + errorMessage = 'Password is required'; + isValid = false; + } else if (value.length < 8) { + errorMessage = 'Password must be at least 8 characters long'; + isValid = false; + } else if (!/(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/.test(value)) { + errorMessage = 'Password should contain uppercase, lowercase, and number'; + isValid = false; + } + break; + + case 'confirmPassword': + if (currentMode === 'signup') { + const password = document.getElementById('password').value; + if (!value) { + errorMessage = 'Please confirm your password'; + isValid = false; + } else if (value !== password) { + errorMessage = 'Passwords do not match'; + isValid = false; + } + } + break; + } + + if (!isValid) { + showFieldError(field, errorMessage); + } else if (value) { + field.classList.add('success'); + } + + return isValid; +} + +/** + * Show field error + */ +function showFieldError(field, message) { + field.classList.add('error'); + const errorElement = field.parentElement.querySelector('.error-message'); + if (errorElement) { + errorElement.textContent = message; + errorElement.classList.add('show'); + } +} + +/** + * Clear field error + */ +function clearFieldError(field) { + field.classList.remove('error'); + const errorElement = field.parentElement.querySelector('.error-message'); + if (errorElement) { + errorElement.classList.remove('show'); + } +} + +/** + * Clear all validation states + */ +function clearAllValidationStates() { + const inputs = document.querySelectorAll('.form-input'); + inputs.forEach(input => { + input.classList.remove('error', 'success'); + input.value = ''; + clearFieldError(input); + }); +} + +/** + * Handle form submission + */ +function handleFormSubmit(e) { + e.preventDefault(); + + // Validate all visible fields + const inputs = document.querySelectorAll('.form-input'); + let isFormValid = true; + + inputs.forEach(input => { + if (input.offsetParent !== null) { // Only validate visible fields + if (!validateField(input)) { + isFormValid = false; + } + } + }); + + if (!isFormValid) { + // Focus on first error field + const firstError = document.querySelector('.form-input.error'); + if (firstError) { + firstError.focus(); + } + return; + } + + // Show loading state + setLoadingState(true); + + // Simulate API call + setTimeout(() => { + setLoadingState(false); + showSuccessMessage(); + }, 2000); +} + +/** + * Set loading state for submit button + */ +function setLoadingState(isLoading) { + if (isLoading) { + submitBtn.classList.add('loading'); + submitBtn.disabled = true; + } else { + submitBtn.classList.remove('loading'); + submitBtn.disabled = false; + } +} + +/** + * Show success message + */ +function showSuccessMessage() { + const successMessage = currentMode === 'login' ? + 'Successfully signed in!' : + 'Account created successfully!'; + + // Create success indicator + const checkmark = document.createElement('div'); + checkmark.className = 'success-checkmark'; + checkmark.innerHTML = ''; + + const container = document.querySelector('.form-container'); + container.insertBefore(checkmark, container.firstChild); + + // Animate success indicator + setTimeout(() => { + checkmark.classList.add('show'); + }, 100); + + // Show success message + setTimeout(() => { + showNotification( + `🎉 ${successMessage}`, + 'This would normally redirect you to the dashboard.', + 'success' + ); + checkmark.remove(); + + // Reset form after success + setTimeout(() => { + clearAllValidationStates(); + }, 2000); + }, 1500); +} + +/** + * Handle social login + */ +function handleSocialLogin(e) { + e.preventDefault(); + const provider = e.currentTarget.id === 'googleBtn' ? 'Google' : 'GitHub'; + + // Add loading state to social button + const button = e.currentTarget; + button.style.pointerEvents = 'none'; + button.style.opacity = '0.7'; + + setTimeout(() => { + showNotification( + `Redirecting to ${provider} authentication...`, + `This would normally open ${provider}'s OAuth flow.`, + 'info' + ); + + button.style.pointerEvents = 'auto'; + button.style.opacity = '1'; + }, 1000); +} + +/** + * Handle forgot password + */ +function handleForgotPassword(e) { + e.preventDefault(); + const emailInput = document.getElementById('email'); + const email = emailInput.value.trim(); + + if (!email) { + showNotification( + 'Email Required', + 'Please enter your email address first.', + 'warning' + ); + emailInput.focus(); + return; + } + + if (!validateField(emailInput)) { + showNotification( + 'Invalid Email', + 'Please enter a valid email address.', + 'error' + ); + return; + } + + showNotification( + 'Password Reset Sent!', + `Password reset link sent to ${email}. This would normally send a real email.`, + 'success' + ); +} + +/** + * Setup accessibility features + */ +function setupAccessibility() { + // Add proper ARIA labels + const form = document.getElementById('authForm'); + if (form) { + form.setAttribute('aria-label', 'Authentication form'); + } + + // Add keyboard navigation for toggles + toggleOptions.forEach((option, index) => { + option.setAttribute('tabindex', '0'); + option.setAttribute('role', 'button'); + option.setAttribute('aria-pressed', option.classList.contains('active')); + + option.addEventListener('keydown', function(e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + this.click(); + } + }); + }); + + // Update ARIA attributes when mode changes + const observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === 'attributes' && mutation.attributeName === 'class') { + const element = mutation.target; + if (element.classList.contains('toggle-option')) { + element.setAttribute('aria-pressed', element.classList.contains('active')); + } + } + }); + }); + + toggleOptions.forEach(option => { + observer.observe(option, { attributes: true }); + }); +} + +/** + * Show notification (alternative to alert) + */ +function showNotification(title, message, type = 'info') { + // For now, use alert, but this could be replaced with a custom notification system + alert(`${title}\n\n${message}`); +} + +/** + * Utility function to get form data + */ +function getFormData() { + const formData = new FormData(authForm); + const data = {}; + + for (let [key, value] of formData.entries()) { + data[key] = value; + } + + return data; +} + +/** + * Utility function to reset form + */ +function resetForm() { + authForm.reset(); + clearAllValidationStates(); +} + +// Export functions for potential external use +window.LoginForm = { + validateField, + resetForm, + getFormData, + setLoadingState, + showNotification +}; diff --git a/scripts/pricing-card.js b/scripts/pricing-card.js new file mode 100644 index 00000000..f502dec1 --- /dev/null +++ b/scripts/pricing-card.js @@ -0,0 +1,338 @@ +/** + * Modern Pricing Cards JavaScript + * CodeClip Project - Pricing Card Component + */ + +// DOM Content Loaded Event Listener +document.addEventListener('DOMContentLoaded', function() { + initializePricingCards(); +}); + +/** + * Initialize all pricing card functionality + */ +function initializePricingCards() { + setupLayoutToggle(); + setupButtonHandlers(); + setupAnimations(); + setupKeyboardNavigation(); + setupBackButtonScroll(); +} + +/** + * Setup the layout toggle functionality + */ +function setupLayoutToggle() { + const layoutToggle = document.getElementById('layoutToggle'); + const flexLayout = document.getElementById('flexLayout'); + const gridLayout = document.getElementById('gridLayout'); + + if (!layoutToggle || !flexLayout || !gridLayout) return; + + layoutToggle.addEventListener('change', function() { + const isGridLayout = this.checked; + + // Add transition class for smooth switching + flexLayout.style.transition = 'opacity 0.3s ease'; + gridLayout.style.transition = 'opacity 0.3s ease'; + + if (isGridLayout) { + flexLayout.style.opacity = '0'; + setTimeout(() => { + flexLayout.classList.add('hidden'); + gridLayout.classList.remove('hidden'); + gridLayout.style.opacity = '0'; + + // Force reflow + gridLayout.offsetHeight; + + gridLayout.style.opacity = '1'; + }, 150); + } else { + gridLayout.style.opacity = '0'; + setTimeout(() => { + gridLayout.classList.add('hidden'); + flexLayout.classList.remove('hidden'); + flexLayout.style.opacity = '0'; + + // Force reflow + flexLayout.offsetHeight; + + flexLayout.style.opacity = '1'; + }, 150); + } + + // Track layout change for analytics (if implemented) + trackLayoutChange(isGridLayout ? 'grid' : 'flexbox'); + }); +} + +/** + * Setup button click handlers + */ +function setupButtonHandlers() { + const buttons = document.querySelectorAll('.cta-button'); + + buttons.forEach(button => { + button.addEventListener('click', function() { + const planCard = this.closest('.pricing-card'); + const planName = planCard.querySelector('.plan-name').textContent; + const planPrice = planCard.querySelector('.price-amount').textContent; + + handlePlanSelection(planName, planPrice, this); + }); + + // Add ripple effect on click + button.addEventListener('click', createRippleEffect); + }); +} + +/** + * Handle plan selection + * @param {string} planName - Name of the selected plan + * @param {string} planPrice - Price of the selected plan + * @param {HTMLElement} button - Clicked button element + */ +function handlePlanSelection(planName, planPrice, button) { + // Show loading state + const originalText = button.textContent; + button.textContent = 'Processing...'; + button.disabled = true; + + // Simulate API call or processing + setTimeout(() => { + button.textContent = originalText; + button.disabled = false; + + // Show success message or redirect + showPlanSelectionModal(planName, planPrice); + }, 1500); + + // Track plan selection for analytics + trackPlanSelection(planName, planPrice); +} + +/** + * Show plan selection modal/alert + * @param {string} planName - Selected plan name + * @param {string} planPrice - Selected plan price + */ +function showPlanSelectionModal(planName, planPrice) { + // For demo purposes, show an alert + // In a real application, this would show a proper modal + const message = `🎉 Great choice!\n\nYou selected: ${planName} Plan\nPrice: ${planPrice}/month\n\nThis would normally redirect you to the signup process.`; + + if (confirm(message + '\n\nWould you like to continue to signup? (Demo)')) { + // Simulate redirect to signup + console.log(`Redirecting to signup for ${planName} plan...`); + // window.location.href = `/signup?plan=${encodeURIComponent(planName.toLowerCase())}`; + } +} + +/** + * Create ripple effect on button click + * @param {Event} e - Click event + */ +function createRippleEffect(e) { + const button = e.currentTarget; + const rect = button.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + + const ripple = document.createElement('span'); + ripple.style.position = 'absolute'; + ripple.style.borderRadius = '50%'; + ripple.style.background = 'rgba(255, 255, 255, 0.6)'; + ripple.style.transform = 'scale(0)'; + ripple.style.animation = 'ripple 0.6s linear'; + ripple.style.left = x + 'px'; + ripple.style.top = y + 'px'; + ripple.style.width = ripple.style.height = '20px'; + ripple.style.marginLeft = ripple.style.marginTop = '-10px'; + + button.style.position = 'relative'; + button.style.overflow = 'hidden'; + button.appendChild(ripple); + + setTimeout(() => { + ripple.remove(); + }, 600); +} + +/** + * Setup scroll animations + */ +function setupAnimations() { + const cards = document.querySelectorAll('.pricing-card'); + const observer = new IntersectionObserver( + (entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('animate-in'); + } + }); + }, + { threshold: 0.1 } + ); + + cards.forEach(card => observer.observe(card)); + + // Add CSS for animation + const style = document.createElement('style'); + style.textContent = ` + @keyframes ripple { + to { + transform: scale(4); + opacity: 0; + } + } + + .pricing-card { + opacity: 0; + transform: translateY(50px); + transition: all 0.6s ease-out; + } + + .pricing-card.animate-in { + opacity: 1; + transform: translateY(0); + } + `; + document.head.appendChild(style); +} + +/** + * Setup keyboard navigation + */ +function setupKeyboardNavigation() { + const buttons = document.querySelectorAll('.cta-button'); + + buttons.forEach(button => { + button.addEventListener('keydown', function(e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + this.click(); + } + }); + }); + + // Add keyboard navigation between cards + const cards = document.querySelectorAll('.pricing-card'); + cards.forEach((card, index) => { + card.tabIndex = 0; + card.addEventListener('keydown', function(e) { + let targetIndex; + + switch(e.key) { + case 'ArrowRight': + targetIndex = (index + 1) % cards.length; + cards[targetIndex].focus(); + e.preventDefault(); + break; + case 'ArrowLeft': + targetIndex = (index - 1 + cards.length) % cards.length; + cards[targetIndex].focus(); + e.preventDefault(); + break; + } + }); + }); +} + +/** + * Setup back button scroll behavior + */ +function setupBackButtonScroll() { + let lastScrollTop = 0; + const backButton = document.querySelector('.back-button'); + + if (!backButton) return; + + window.addEventListener('scroll', function() { + let scrollTop = window.pageYOffset || document.documentElement.scrollTop; + + if (scrollTop > 100) { // Hide after scrolling 100px + if (scrollTop > lastScrollTop) { + // Scrolling down - hide button + backButton.classList.add('hidden-on-scroll'); + } else { + // Scrolling up - show button + backButton.classList.remove('hidden-on-scroll'); + } + } else { + // At top of page - always show + backButton.classList.remove('hidden-on-scroll'); + } + + lastScrollTop = scrollTop; + }); +} + +/** + * Track layout change for analytics + * @param {string} layout - Layout type ('grid' or 'flexbox') + */ +function trackLayoutChange(layout) { + // Placeholder for analytics tracking + console.log(`Layout changed to: ${layout}`); + + // Example: Send to analytics service + // if (typeof gtag !== 'undefined') { + // gtag('event', 'layout_change', { + // layout_type: layout, + // page_title: document.title + // }); + // } +} + +/** + * Track plan selection for analytics + * @param {string} planName - Selected plan name + * @param {string} planPrice - Selected plan price + */ +function trackPlanSelection(planName, planPrice) { + // Placeholder for analytics tracking + console.log(`Plan selected: ${planName} - ${planPrice}`); + + // Example: Send to analytics service + // if (typeof gtag !== 'undefined') { + // gtag('event', 'plan_selection', { + // plan_name: planName, + // plan_price: planPrice, + // page_title: document.title + // }); + // } +} + +/** + * Utility function to format currency + * @param {number} amount - Amount to format + * @param {string} currency - Currency code + * @returns {string} Formatted currency string + */ +function formatCurrency(amount, currency = 'USD') { + return new Intl.NumberFormat('en-US', { + style: 'currency', + currency: currency, + minimumFractionDigits: 0 + }).format(amount); +} + +/** + * Utility function to validate plan data + * @param {Object} planData - Plan data object + * @returns {boolean} True if valid + */ +function validatePlanData(planData) { + const required = ['name', 'price', 'features']; + return required.every(field => planData.hasOwnProperty(field)); +} + +// Export functions for potential use in other modules +window.PricingCards = { + initializePricingCards, + trackLayoutChange, + trackPlanSelection, + formatCurrency, + validatePlanData +}; diff --git a/scripts/profile-card.js b/scripts/profile-card.js new file mode 100644 index 00000000..9eb7aff7 --- /dev/null +++ b/scripts/profile-card.js @@ -0,0 +1,259 @@ +// Profile Card UI JavaScript +document.addEventListener('DOMContentLoaded', function() { + // Layout Toggle Functionality + function toggleLayout() { + const container = document.querySelector('.cards-container'); + const icon = document.querySelector('.layout-toggle i'); + + container.classList.toggle('compact-layout'); + + if (container.classList.contains('compact-layout')) { + icon.className = 'fas fa-th'; + } else { + icon.className = 'fas fa-th-large'; + } + } + + // Make toggleLayout function globally available + window.toggleLayout = toggleLayout; + + // Scroll behavior for back button + let lastScrollY = window.scrollY; + const backButton = document.querySelector('.back-home'); + + window.addEventListener('scroll', () => { + const currentScrollY = window.scrollY; + + if (currentScrollY > lastScrollY && currentScrollY > 100) { + // Scrolling down + backButton.classList.add('hidden-on-scroll'); + } else { + // Scrolling up + backButton.classList.remove('hidden-on-scroll'); + } + + lastScrollY = currentScrollY; + }); + + // Add intersection observer for smooth animations + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.style.opacity = '1'; + entry.target.style.transform = 'translateY(0)'; + } + }); + }, observerOptions); + + // Observe all profile cards + document.querySelectorAll('.profile-card').forEach(card => { + observer.observe(card); + }); + + // Add click ripple effect + document.querySelectorAll('.contact-btn, .social-link').forEach(button => { + button.addEventListener('click', function(e) { + const ripple = document.createElement('span'); + const rect = this.getBoundingClientRect(); + const size = Math.max(rect.width, rect.height); + const x = e.clientX - rect.left - size / 2; + const y = e.clientY - rect.top - size / 2; + + ripple.style.width = ripple.style.height = size + 'px'; + ripple.style.left = x + 'px'; + ripple.style.top = y + 'px'; + ripple.style.position = 'absolute'; + ripple.style.borderRadius = '50%'; + ripple.style.background = 'rgba(255, 255, 255, 0.3)'; + ripple.style.transform = 'scale(0)'; + ripple.style.animation = 'ripple 0.6s linear'; + ripple.style.pointerEvents = 'none'; + + this.style.position = 'relative'; + this.style.overflow = 'hidden'; + this.appendChild(ripple); + + setTimeout(() => { + ripple.remove(); + }, 600); + }); + }); + + // Keyboard navigation for accessibility + document.querySelectorAll('.social-link, .contact-btn').forEach(element => { + element.addEventListener('keydown', function(e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + this.click(); + } + }); + }); + + // Add focus management for layout toggle + const layoutToggle = document.querySelector('.layout-toggle'); + if (layoutToggle) { + layoutToggle.addEventListener('keydown', function(e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + toggleLayout(); + } + }); + } + + // Smooth scrolling for back to home button + const backHomeButton = document.querySelector('.back-home'); + if (backHomeButton) { + backHomeButton.addEventListener('click', function(e) { + // If it's a same-page link, add smooth scrolling + if (this.getAttribute('href').startsWith('#')) { + e.preventDefault(); + const target = document.querySelector(this.getAttribute('href')); + if (target) { + target.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + } + } + }); + } + + // Add hover sound effect simulation (visual feedback) + document.querySelectorAll('.social-link').forEach(link => { + link.addEventListener('mouseenter', function() { + this.style.transform = 'translateY(-3px) scale(1.1)'; + }); + + link.addEventListener('mouseleave', function() { + this.style.transform = 'translateY(0) scale(1)'; + }); + }); + + // Add loading animation for profile images + document.querySelectorAll('.profile-image img').forEach(img => { + img.addEventListener('load', function() { + this.style.opacity = '1'; + this.parentElement.style.borderColor = 'rgba(255, 255, 255, 0.3)'; + }); + + // Handle image load errors + img.addEventListener('error', function() { + this.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiBmaWxsPSIjRjNGNEY2Ii8+CjxjaXJjbGUgY3g9IjEwMCIgY3k9IjgwIiByPSIzMCIgZmlsbD0iI0Q2REFERiIvPgo8cGF0aCBkPSJNNTAgMTQwQzUwIDEyMC45IDY1LjkgMTA1IDg1IDEwNUgxMTVDMTM0LjEgMTA1IDE1MCAxMjAuOSAxNTAgMTQwVjE2MEg1MFYxNDBaIiBmaWxsPSIjRDZEQURGIi8+Cjwvc3ZnPgo='; + this.alt = 'Profile image not available'; + }); + }); + + // Add copy-to-clipboard functionality for contact info (demo) + document.querySelectorAll('.contact-btn').forEach(btn => { + btn.addEventListener('click', function(e) { + e.preventDefault(); + + // Simulate copying email to clipboard + const email = `contact@${this.closest('.profile-card').querySelector('.profile-name').textContent.toLowerCase().replace(' ', '.')}.com`; + + // Show toast notification + showToast(`Email copied: ${email}`); + }); + }); + + // Toast notification function + function showToast(message) { + // Remove existing toast if any + const existingToast = document.querySelector('.toast'); + if (existingToast) { + existingToast.remove(); + } + + const toast = document.createElement('div'); + toast.className = 'toast'; + toast.textContent = message; + toast.style.cssText = ` + position: fixed; + top: 100px; + right: 20px; + background: rgba(0, 0, 0, 0.8); + color: white; + padding: 12px 20px; + border-radius: 8px; + z-index: 10000; + font-size: 0.9rem; + backdrop-filter: blur(10px); + transform: translateX(300px); + transition: transform 0.3s ease; + `; + + document.body.appendChild(toast); + + // Show toast + requestAnimationFrame(() => { + toast.style.transform = 'translateX(0)'; + }); + + // Hide toast after 3 seconds + setTimeout(() => { + toast.style.transform = 'translateX(300px)'; + setTimeout(() => toast.remove(), 300); + }, 3000); + } + + // Add parallax effect to background + let ticking = false; + + function updateBackground() { + const scrolled = window.pageYOffset; + const rate = scrolled * -0.5; + + document.body.style.backgroundPosition = `center ${rate}px`; + ticking = false; + } + + function requestTick() { + if (!ticking) { + requestAnimationFrame(updateBackground); + ticking = true; + } + } + + window.addEventListener('scroll', requestTick); + + // Initialize AOS-like animation system + function initScrollAnimations() { + const elements = document.querySelectorAll('.profile-card'); + + function checkScroll() { + elements.forEach((element, index) => { + const elementTop = element.getBoundingClientRect().top; + const elementVisible = 150; + + if (elementTop < window.innerHeight - elementVisible) { + setTimeout(() => { + element.style.opacity = '1'; + element.style.transform = 'translateY(0)'; + }, index * 100); + } + }); + } + + // Set initial state + elements.forEach(element => { + element.style.opacity = '0'; + element.style.transform = 'translateY(30px)'; + element.style.transition = 'all 0.6s ease'; + }); + + // Check on scroll + window.addEventListener('scroll', checkScroll); + + // Check on load + checkScroll(); + } + + initScrollAnimations(); + + console.log('Profile Card UI initialized successfully!'); +}); diff --git a/scripts/responsive-navbar.js b/scripts/responsive-navbar.js new file mode 100644 index 00000000..e4e16b2f --- /dev/null +++ b/scripts/responsive-navbar.js @@ -0,0 +1,462 @@ +/** + * Responsive Navbar JavaScript + * CodeClip Project - Navigation Bar Component + */ + +// DOM Elements +let navbar, mobileMenuToggle, mobileMenu, mobileServicesToggle; +let mobileServicesDropdown, navLinks, demoSections; + +// State +let isMenuOpen = false; +let isDropdownOpen = false; + +// Initialize when DOM is loaded +document.addEventListener('DOMContentLoaded', function() { + initializeElements(); + setupEventListeners(); + setupScrollAnimations(); + setupAccessibility(); +}); + +/** + * Initialize DOM elements + */ +function initializeElements() { + navbar = document.getElementById('navbar'); + mobileMenuToggle = document.getElementById('mobileMenuToggle'); + mobileMenu = document.getElementById('mobileMenu'); + mobileServicesToggle = document.getElementById('mobileServicesToggle'); + mobileServicesDropdown = document.getElementById('mobileServicesDropdown'); + navLinks = document.querySelectorAll('.navbar-link, .mobile-menu-link'); + demoSections = document.querySelectorAll('.demo-section'); +} + +/** + * Setup all event listeners + */ +function setupEventListeners() { + // Mobile menu toggle + if (mobileMenuToggle) { + mobileMenuToggle.addEventListener('click', toggleMobileMenu); + } + + // Mobile dropdown toggle + if (mobileServicesToggle) { + mobileServicesToggle.addEventListener('click', function(e) { + e.preventDefault(); + toggleMobileDropdown(); + }); + } + + // Close mobile menu when clicking on links + document.querySelectorAll('.mobile-menu-link').forEach(link => { + link.addEventListener('click', function(e) { + if (this.getAttribute('href').startsWith('#')) { + closeMobileMenu(); + updateActiveLink(this); + } + }); + }); + + // Update active links for desktop menu + document.querySelectorAll('.navbar-link').forEach(link => { + link.addEventListener('click', function(e) { + if (this.getAttribute('href').startsWith('#')) { + updateActiveLink(this); + } + }); + }); + + // Scroll event for navbar styling + window.addEventListener('scroll', throttle(handleScroll, 16)); + + // Close mobile menu when clicking outside + document.addEventListener('click', function(e) { + if (navbar && !navbar.contains(e.target)) { + closeMobileMenu(); + } + }); + + // Handle window resize + window.addEventListener('resize', function() { + if (window.innerWidth > 768) { + closeMobileMenu(); + } + }); + + // Smooth scrolling for anchor links + setupSmoothScrolling(); +} + +/** + * Toggle mobile menu state + */ +function toggleMobileMenu() { + if (isMenuOpen) { + closeMobileMenu(); + } else { + openMobileMenu(); + } +} + +/** + * Open mobile menu + */ +function openMobileMenu() { + if (!mobileMenuToggle || !mobileMenu) return; + + isMenuOpen = true; + mobileMenuToggle.classList.add('active'); + mobileMenu.classList.add('active'); + mobileMenuToggle.setAttribute('aria-expanded', 'true'); + document.body.style.overflow = 'hidden'; + + // Focus first menu item for accessibility + const firstMenuItem = mobileMenu.querySelector('.mobile-menu-link'); + if (firstMenuItem) { + setTimeout(() => firstMenuItem.focus(), 100); + } +} + +/** + * Close mobile menu + */ +function closeMobileMenu() { + if (!mobileMenuToggle || !mobileMenu) return; + + isMenuOpen = false; + mobileMenuToggle.classList.remove('active'); + mobileMenu.classList.remove('active'); + mobileMenuToggle.setAttribute('aria-expanded', 'false'); + document.body.style.overflow = ''; + + // Close any open dropdowns + closeMobileDropdown(); +} + +/** + * Toggle mobile dropdown + */ +function toggleMobileDropdown() { + if (!mobileServicesDropdown) return; + + isDropdownOpen = !isDropdownOpen; + const toggle = document.querySelector('.mobile-dropdown-toggle'); + + if (isDropdownOpen) { + mobileServicesDropdown.classList.add('active'); + if (toggle) toggle.classList.add('active'); + } else { + mobileServicesDropdown.classList.remove('active'); + if (toggle) toggle.classList.remove('active'); + } +} + +/** + * Close mobile dropdown + */ +function closeMobileDropdown() { + if (!mobileServicesDropdown) return; + + isDropdownOpen = false; + mobileServicesDropdown.classList.remove('active'); + const toggle = document.querySelector('.mobile-dropdown-toggle'); + if (toggle) toggle.classList.remove('active'); +} + +/** + * Handle scroll events with navbar styling changes + */ +function handleScroll() { + if (!navbar) return; + + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + + if (scrollTop > 50) { + navbar.classList.add('scrolled'); + } else { + navbar.classList.remove('scrolled'); + } +} + +/** + * Update active link highlighting + */ +function updateActiveLink(activeLink) { + // Remove active class from all links + navLinks.forEach(link => link.classList.remove('active')); + + // Add active class to clicked link + activeLink.classList.add('active'); + + // Also update corresponding link in other menu + const href = activeLink.getAttribute('href'); + const correspondingLink = document.querySelector( + activeLink.classList.contains('navbar-link') ? + `.mobile-menu-link[href="${href}"]` : + `.navbar-link[href="${href}"]` + ); + + if (correspondingLink) { + correspondingLink.classList.add('active'); + } +} + +/** + * Setup smooth scrolling for anchor links + */ +function setupSmoothScrolling() { + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + const targetId = this.getAttribute('href'); + const target = document.querySelector(targetId); + + if (target) { + e.preventDefault(); + const navbarHeight = navbar ? navbar.offsetHeight : 70; + const targetPosition = target.offsetTop - navbarHeight - 20; + + window.scrollTo({ + top: targetPosition, + behavior: 'smooth' + }); + } + }); + }); +} + +/** + * Setup scroll animations for demo sections + */ +function setupScrollAnimations() { + if (!demoSections.length) return; + + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver(function(entries) { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('visible'); + } + }); + }, observerOptions); + + demoSections.forEach(section => { + observer.observe(section); + }); +} + +/** + * Setup accessibility features + */ +function setupAccessibility() { + // Mobile menu toggle keyboard support + if (mobileMenuToggle) { + mobileMenuToggle.addEventListener('keydown', function(e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + toggleMobileMenu(); + } + }); + + // Set initial ARIA attributes + mobileMenuToggle.setAttribute('aria-expanded', 'false'); + mobileMenuToggle.setAttribute('aria-controls', 'mobileMenu'); + } + + // Escape key to close mobile menu + document.addEventListener('keydown', function(e) { + if (e.key === 'Escape') { + closeMobileMenu(); + } + }); + + // Arrow key navigation for menu items + setupArrowKeyNavigation(); + + // Focus management for dropdowns + setupDropdownFocusManagement(); +} + +/** + * Setup arrow key navigation + */ +function setupArrowKeyNavigation() { + const menuItems = document.querySelectorAll('.navbar-link, .mobile-menu-link'); + + menuItems.forEach((item, index) => { + item.addEventListener('keydown', function(e) { + let targetIndex; + + switch(e.key) { + case 'ArrowDown': + e.preventDefault(); + targetIndex = (index + 1) % menuItems.length; + menuItems[targetIndex].focus(); + break; + case 'ArrowUp': + e.preventDefault(); + targetIndex = (index - 1 + menuItems.length) % menuItems.length; + menuItems[targetIndex].focus(); + break; + case 'Home': + e.preventDefault(); + menuItems[0].focus(); + break; + case 'End': + e.preventDefault(); + menuItems[menuItems.length - 1].focus(); + break; + } + }); + }); +} + +/** + * Setup dropdown focus management + */ +function setupDropdownFocusManagement() { + const dropdownTriggers = document.querySelectorAll('.dropdown .navbar-link'); + + dropdownTriggers.forEach(trigger => { + const dropdown = trigger.parentElement; + const dropdownContent = dropdown.querySelector('.dropdown-content'); + const dropdownItems = dropdownContent ? dropdownContent.querySelectorAll('.dropdown-item') : []; + + trigger.addEventListener('keydown', function(e) { + if (e.key === 'ArrowDown' && dropdownItems.length > 0) { + e.preventDefault(); + dropdownItems[0].focus(); + } + }); + + dropdownItems.forEach((item, index) => { + item.addEventListener('keydown', function(e) { + switch(e.key) { + case 'ArrowDown': + e.preventDefault(); + const nextIndex = (index + 1) % dropdownItems.length; + dropdownItems[nextIndex].focus(); + break; + case 'ArrowUp': + e.preventDefault(); + if (index === 0) { + trigger.focus(); + } else { + dropdownItems[index - 1].focus(); + } + break; + case 'Escape': + e.preventDefault(); + trigger.focus(); + break; + } + }); + }); + }); +} + +/** + * Throttle function to limit event frequency + */ +function throttle(func, limit) { + let inThrottle; + return function() { + const args = arguments; + const context = this; + if (!inThrottle) { + func.apply(context, args); + inThrottle = true; + setTimeout(() => inThrottle = false, limit); + } + } +} + +/** + * Debounce function for resize events + */ +function debounce(func, wait, immediate) { + let timeout; + return function executedFunction() { + const context = this; + const args = arguments; + const later = function() { + timeout = null; + if (!immediate) func.apply(context, args); + }; + const callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; +} + +/** + * Get current active section based on scroll position + */ +function getCurrentSection() { + const sections = document.querySelectorAll('section[id], div[id]'); + const scrollPos = window.pageYOffset + 100; + + for (let i = sections.length - 1; i >= 0; i--) { + const section = sections[i]; + if (section.offsetTop <= scrollPos) { + return section.id; + } + } + return null; +} + +/** + * Highlight active section in navigation + */ +function highlightActiveSection() { + const currentSection = getCurrentSection(); + if (!currentSection) return; + + const activeLink = document.querySelector(`a[href="#${currentSection}"]`); + if (activeLink) { + updateActiveLink(activeLink); + } +} + +/** + * Handle focus trap for mobile menu + */ +function trapFocus(element) { + const focusableElements = element.querySelectorAll( + 'a[href], button, textarea, input, select, details, [tabindex]:not([tabindex="-1"])' + ); + const firstFocusableElement = focusableElements[0]; + const lastFocusableElement = focusableElements[focusableElements.length - 1]; + + element.addEventListener('keydown', function(e) { + if (e.key === 'Tab') { + if (e.shiftKey) { + if (document.activeElement === firstFocusableElement) { + lastFocusableElement.focus(); + e.preventDefault(); + } + } else { + if (document.activeElement === lastFocusableElement) { + firstFocusableElement.focus(); + e.preventDefault(); + } + } + } + }); +} + +// Export functions for external use +window.ResponsiveNavbar = { + toggleMobileMenu, + openMobileMenu, + closeMobileMenu, + updateActiveLink, + highlightActiveSection, + getCurrentSection +}; diff --git a/styles/dark-mode-toggle.css b/styles/dark-mode-toggle.css new file mode 100644 index 00000000..c4b17411 --- /dev/null +++ b/styles/dark-mode-toggle.css @@ -0,0 +1,490 @@ +/* Dark Mode Toggle Styles */ + +:root { + /* Light mode colors */ + --bg-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --bg-secondary: rgba(255, 255, 255, 0.9); + --bg-card: rgba(255, 255, 255, 0.15); + --text-primary: #2d3748; + --text-secondary: #4a5568; + --text-light: rgba(255, 255, 255, 0.9); + --border-color: rgba(255, 255, 255, 0.2); + --shadow-light: rgba(0, 0, 0, 0.1); + --shadow-medium: rgba(0, 0, 0, 0.15); + --shadow-heavy: rgba(0, 0, 0, 0.25); + --accent-color: #667eea; + --success-color: #48bb78; + --warning-color: #ed8936; +} + +[data-theme="dark"] { + /* Dark mode colors */ + --bg-primary: linear-gradient(135deg, #2d3748 0%, #1a202c 100%); + --bg-secondary: rgba(45, 55, 72, 0.95); + --bg-card: rgba(45, 55, 72, 0.8); + --text-primary: #e2e8f0; + --text-secondary: #a0aec0; + --text-light: rgba(226, 232, 240, 0.9); + --border-color: rgba(226, 232, 240, 0.1); + --shadow-light: rgba(0, 0, 0, 0.3); + --shadow-medium: rgba(0, 0, 0, 0.4); + --shadow-heavy: rgba(0, 0, 0, 0.6); + --accent-color: #63b3ed; + --success-color: #68d391; + --warning-color: #fbb036; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', sans-serif; + background: var(--bg-primary); + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 20px; + position: relative; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + overflow-x: hidden; +} + +.back-home { + position: fixed; + top: 20px; + left: 20px; + background: var(--bg-card); + backdrop-filter: blur(10px); + border: 1px solid var(--border-color); + padding: 12px 20px; + border-radius: 50px; + color: var(--text-light); + text-decoration: none; + font-weight: 500; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + z-index: 1000; + display: flex; + align-items: center; + gap: 8px; + transform: translateY(0); + opacity: 1; +} + +.back-home:hover { + background: rgba(255, 255, 255, 0.3); + transform: translateY(-2px); + box-shadow: 0 10px 25px var(--shadow-light); +} + +.back-home.hidden-on-scroll { + transform: translateY(-100px); + opacity: 0; +} + +.container { + max-width: 1200px; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + gap: 3rem; +} + +.page-title { + text-align: center; + color: var(--text-light); + margin-bottom: 2rem; +} + +.page-title h1 { + font-size: 3.5rem; + font-weight: 700; + margin-bottom: 0.5rem; + text-shadow: 0 4px 15px var(--shadow-medium); + background: linear-gradient(45deg, var(--accent-color), var(--success-color)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.page-title p { + font-size: 1.3rem; + opacity: 0.9; + font-weight: 400; +} + +/* Dark Mode Toggle Switch */ +.theme-switch-wrapper { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 2rem; +} + +.theme-switch { + display: inline-block; + height: 60px; + position: relative; + width: 120px; +} + +.theme-switch input { + display: none; +} + +.slider { + background: var(--bg-secondary); + bottom: 0; + cursor: pointer; + left: 0; + position: absolute; + right: 0; + top: 0; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + border-radius: 50px; + border: 2px solid var(--border-color); + backdrop-filter: blur(10px); + box-shadow: 0 8px 25px var(--shadow-light); +} + +.slider:before { + content: ""; + position: absolute; + left: 4px; + top: 4px; + width: 48px; + height: 48px; + background: linear-gradient(135deg, #fbbf24, #f59e0b); + border-radius: 50%; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 4px 15px rgba(251, 191, 36, 0.4); + display: flex; + align-items: center; + justify-content: center; +} + +.slider:after { + content: "☀️"; + position: absolute; + left: 4px; + top: 4px; + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + z-index: 2; +} + +input:checked + .slider { + background: var(--bg-secondary); +} + +input:checked + .slider:before { + transform: translateX(60px); + background: linear-gradient(135deg, #4f46e5, #7c3aed); + box-shadow: 0 4px 15px rgba(79, 70, 229, 0.4); +} + +input:checked + .slider:after { + content: "🌙"; + transform: translateX(60px); +} + +.theme-label { + font-size: 1.1rem; + font-weight: 600; + color: var(--text-light); + display: flex; + align-items: center; + gap: 0.5rem; +} + +/* Demo Content */ +.demo-content { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); + gap: 2rem; + width: 100%; + max-width: 1200px; +} + +.demo-card { + background: var(--bg-card); + backdrop-filter: blur(20px); + border: 1px solid var(--border-color); + border-radius: 24px; + padding: 2.5rem; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + overflow: hidden; +} + +.demo-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, var(--accent-color), var(--success-color)); + opacity: 0; + transition: opacity 0.4s ease; + pointer-events: none; + border-radius: 24px; +} + +.demo-card:hover { + transform: translateY(-10px); + box-shadow: 0 25px 50px var(--shadow-heavy); + border-color: var(--accent-color); +} + +.demo-card:hover::before { + opacity: 0.1; +} + +.card-icon { + width: 80px; + height: 80px; + border-radius: 20px; + background: linear-gradient(135deg, var(--accent-color), var(--success-color)); + display: flex; + align-items: center; + justify-content: center; + font-size: 2rem; + color: white; + margin-bottom: 1.5rem; + transition: all 0.3s ease; +} + +.demo-card:hover .card-icon { + transform: scale(1.1) rotate(5deg); +} + +.card-title { + font-size: 1.5rem; + font-weight: 700; + color: var(--text-light); + margin-bottom: 0.8rem; +} + +.card-description { + color: var(--text-secondary); + line-height: 1.6; + margin-bottom: 1.5rem; +} + +.card-features { + list-style: none; + margin-bottom: 2rem; +} + +.card-features li { + color: var(--text-secondary); + margin-bottom: 0.5rem; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.card-features li::before { + content: "✨"; + font-size: 0.9rem; +} + +.card-button { + background: linear-gradient(135deg, var(--accent-color), var(--success-color)); + color: white; + padding: 12px 24px; + border: none; + border-radius: 50px; + font-weight: 600; + font-size: 1rem; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 8px; + box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3); +} + +.card-button:hover { + transform: translateY(-2px); + box-shadow: 0 15px 35px rgba(102, 126, 234, 0.4); + filter: brightness(1.1); +} + +/* Theme transition effects */ +.theme-transition { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient(circle, var(--accent-color) 0%, transparent 70%); + opacity: 0; + pointer-events: none; + z-index: 9999; + transition: opacity 0.6s ease; +} + +.theme-transition.active { + opacity: 0.3; +} + +/* Progress indicators */ +.toggle-progress { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 100px; + height: 100px; + border-radius: 50%; + background: var(--bg-card); + backdrop-filter: blur(20px); + border: 2px solid var(--border-color); + display: flex; + align-items: center; + justify-content: center; + font-size: 2.5rem; + opacity: 0; + scale: 0.5; + transition: all 0.3s ease; + z-index: 10000; +} + +.toggle-progress.show { + opacity: 1; + scale: 1; +} + +/* Floating particles effect */ +.particles { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; +} + +.particle { + position: absolute; + background: var(--accent-color); + border-radius: 50%; + pointer-events: none; + opacity: 0.6; + animation: float 6s infinite ease-in-out; +} + +@keyframes float { + 0%, 100% { transform: translateY(0) rotate(0deg); } + 25% { transform: translateY(-20px) rotate(90deg); } + 50% { transform: translateY(-10px) rotate(180deg); } + 75% { transform: translateY(-30px) rotate(270deg); } +} + +/* Animations */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.demo-card { + animation: fadeInUp 0.6s ease-out; +} + +.demo-card:nth-child(2) { animation-delay: 0.1s; } +.demo-card:nth-child(3) { animation-delay: 0.2s; } +.demo-card:nth-child(4) { animation-delay: 0.3s; } + +@keyframes ripple { + to { + transform: scale(4); + opacity: 0; + } +} + +/* Loading animation */ +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +.loading { + animation: pulse 1.5s infinite; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .page-title h1 { + font-size: 2.5rem; + } + + .page-title p { + font-size: 1.1rem; + } + + .demo-content { + grid-template-columns: 1fr; + gap: 1.5rem; + } + + .demo-card { + padding: 2rem; + } + + .theme-switch-wrapper { + flex-direction: column; + gap: 1rem; + } + + .back-home { + top: 10px; + left: 10px; + padding: 10px 16px; + font-size: 0.9rem; + } +} + +@media (max-width: 480px) { + .demo-card { + padding: 1.5rem; + } + + .card-title { + font-size: 1.3rem; + } + + .theme-switch { + width: 100px; + height: 50px; + } + + .slider:before, + .slider:after { + width: 40px; + height: 40px; + } + + input:checked + .slider:before, + input:checked + .slider:after { + transform: translateX(50px); + } +} diff --git a/styles/login-form.css b/styles/login-form.css new file mode 100644 index 00000000..212d9a1a --- /dev/null +++ b/styles/login-form.css @@ -0,0 +1,488 @@ +/* Modern Login Form CSS */ + +/* ================ Reset and Base Styles ================ */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 2rem 1rem; +} + +/* ================ Form Container Styles ================ */ +.form-container { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + border-radius: 20px; + box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15); + width: 100%; + max-width: 450px; + padding: 3rem 2.5rem; + position: relative; + overflow: hidden; + animation: slideUp 0.6s ease-out; +} + +.form-container::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, #667eea, #764ba2); +} + +@keyframes slideUp { + from { + opacity: 0; + transform: translateY(50px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* ================ Form Header Styles ================ */ +.form-header { + text-align: center; + margin-bottom: 2.5rem; +} + +.form-title { + font-size: 2.2rem; + font-weight: 700; + color: #2d3748; + margin-bottom: 0.5rem; + transition: all 0.3s ease; +} + +.form-subtitle { + color: #718096; + font-size: 1rem; + font-weight: 400; +} + +/* ================ Toggle Switch Styles ================ */ +.form-toggle { + display: flex; + background: #f7fafc; + border-radius: 12px; + padding: 0.25rem; + margin-bottom: 2rem; + position: relative; +} + +.toggle-option { + flex: 1; + padding: 0.75rem 1rem; + text-align: center; + border-radius: 10px; + cursor: pointer; + font-weight: 500; + transition: all 0.3s ease; + position: relative; + z-index: 2; +} + +.toggle-option.active { + color: white; + background: linear-gradient(135deg, #667eea, #764ba2); + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3); +} + +/* ================ Form Field Styles ================ */ +.form-group { + margin-bottom: 1.5rem; + position: relative; +} + +.form-label { + display: block; + margin-bottom: 0.5rem; + font-weight: 500; + color: #4a5568; + font-size: 0.9rem; +} + +.form-input { + width: 100%; + padding: 1rem 1.25rem; + border: 2px solid #e2e8f0; + border-radius: 12px; + font-size: 1rem; + transition: all 0.3s ease; + background: white; + font-family: inherit; +} + +.form-input:focus { + outline: none; + border-color: #667eea; + box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); + transform: translateY(-2px); +} + +.form-input.error { + border-color: #e53e3e; + box-shadow: 0 0 0 3px rgba(229, 62, 62, 0.1); +} + +.form-input.success { + border-color: #38a169; + box-shadow: 0 0 0 3px rgba(56, 161, 105, 0.1); +} + +.input-icon { + position: absolute; + right: 1rem; + top: 50%; + transform: translateY(-50%); + color: #a0aec0; + transition: all 0.3s ease; + pointer-events: none; +} + +.form-input:focus + .input-icon { + color: #667eea; +} + +/* ================ Password Toggle Styles ================ */ +.password-toggle { + position: absolute; + right: 1rem; + top: 50%; + transform: translateY(-50%); + cursor: pointer; + color: #a0aec0; + transition: all 0.3s ease; +} + +.password-toggle:hover { + color: #667eea; +} + +/* ================ Error Message Styles ================ */ +.error-message { + color: #e53e3e; + font-size: 0.85rem; + margin-top: 0.5rem; + opacity: 0; + transform: translateY(-10px); + transition: all 0.3s ease; +} + +.error-message.show { + opacity: 1; + transform: translateY(0); +} + +/* ================ Forgot Password Styles ================ */ +.forgot-password { + text-align: right; + margin-bottom: 2rem; +} + +.forgot-password a { + color: #667eea; + text-decoration: none; + font-size: 0.9rem; + font-weight: 500; + transition: all 0.3s ease; +} + +.forgot-password a:hover { + color: #5a6fd8; + text-decoration: underline; +} + +/* ================ Submit Button Styles ================ */ +.submit-btn { + width: 100%; + padding: 1rem 2rem; + background: linear-gradient(135deg, #667eea, #764ba2); + color: white; + border: none; + border-radius: 12px; + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.submit-btn:hover { + transform: translateY(-2px); + box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4); +} + +.submit-btn:active { + transform: translateY(0); +} + +.submit-btn.loading { + pointer-events: none; +} + +.btn-text { + transition: all 0.3s ease; +} + +.loading-spinner { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 20px; + height: 20px; + border: 2px solid rgba(255, 255, 255, 0.3); + border-radius: 50%; + border-top-color: white; + animation: spin 1s ease-in-out infinite; + opacity: 0; +} + +.submit-btn.loading .btn-text { + opacity: 0; +} + +.submit-btn.loading .loading-spinner { + opacity: 1; +} + +@keyframes spin { + to { transform: translate(-50%, -50%) rotate(360deg); } +} + +/* ================ Social Login Styles ================ */ +.social-login { + margin-top: 2rem; + text-align: center; +} + +.social-divider { + position: relative; + margin: 2rem 0; + text-align: center; +} + +.social-divider::before { + content: ''; + position: absolute; + top: 50%; + left: 0; + right: 0; + height: 1px; + background: #e2e8f0; +} + +.social-divider span { + background: rgba(255, 255, 255, 0.95); + padding: 0 1rem; + color: #a0aec0; + font-size: 0.9rem; +} + +.social-buttons { + display: flex; + gap: 1rem; +} + +.social-btn { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 0.75rem 1rem; + border: 2px solid #e2e8f0; + border-radius: 10px; + background: white; + color: #4a5568; + text-decoration: none; + font-weight: 500; + transition: all 0.3s ease; +} + +.social-btn:hover { + border-color: #667eea; + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); + color: #4a5568; + text-decoration: none; +} + +/* ================ Navigation Styles ================ */ +.back-button { + position: fixed; + top: 2rem; + left: 2rem; + background: rgba(255, 255, 255, 0.2); + color: white; + border: 2px solid rgba(255, 255, 255, 0.3); + padding: 0.5rem 1rem; + border-radius: 25px; + text-decoration: none; + font-weight: 500; + backdrop-filter: blur(10px); + transition: all 0.3s ease; + z-index: 1000; +} + +.back-button:hover { + background: rgba(255, 255, 255, 0.3); + color: white; + text-decoration: none; + transform: translateX(-5px); +} + +/* ================ Signup Fields Styles ================ */ +.signup-fields { + opacity: 0; + max-height: 0; + overflow: hidden; + transition: all 0.4s ease; +} + +.signup-fields.show { + opacity: 1; + max-height: 200px; +} + +/* ================ Success Animation Styles ================ */ +.success-checkmark { + width: 50px; + height: 50px; + border-radius: 50%; + background: #38a169; + margin: 0 auto 1rem; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 1.5rem; + opacity: 0; + transform: scale(0); + transition: all 0.3s ease; +} + +.success-checkmark.show { + opacity: 1; + transform: scale(1); +} + +/* ================ Responsive Design ================ */ +@media (max-width: 480px) { + body { + padding: 1rem 0.5rem; + } + + .form-container { + padding: 2rem 1.5rem; + margin: 1rem; + } + + .form-title { + font-size: 1.8rem; + } + + .social-buttons { + flex-direction: column; + } + + .back-button { + position: static; + margin-bottom: 1rem; + display: inline-block; + } + + .form-input { + padding: 0.875rem 1rem; + } +} + +@media (max-width: 320px) { + .form-container { + padding: 1.5rem 1rem; + } + + .form-title { + font-size: 1.6rem; + } + + .form-toggle { + padding: 0.2rem; + } + + .toggle-option { + padding: 0.6rem 0.8rem; + font-size: 0.9rem; + } +} + +/* ================ Accessibility Enhancements ================ */ +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} + +/* High contrast mode support */ +@media (prefers-contrast: high) { + .form-container { + border: 2px solid #000; + } + + .form-input:focus { + border-color: #000; + box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.2); + } +} + +/* Dark mode support */ +@media (prefers-color-scheme: dark) { + .form-container { + background: rgba(26, 32, 44, 0.95); + color: #e2e8f0; + } + + .form-title { + color: #f7fafc; + } + + .form-subtitle { + color: #a0aec0; + } + + .form-label { + color: #e2e8f0; + } + + .form-input { + background: #2d3748; + border-color: #4a5568; + color: #e2e8f0; + } + + .form-input:focus { + border-color: #667eea; + } + + .social-btn { + background: #2d3748; + color: #e2e8f0; + border-color: #4a5568; + } +} diff --git a/styles/pricing-card.css b/styles/pricing-card.css new file mode 100644 index 00000000..ff48d271 --- /dev/null +++ b/styles/pricing-card.css @@ -0,0 +1,413 @@ +/* Modern Pricing Cards CSS */ + +/* ================ Reset and Base Styles ================ */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + padding: 2rem 1rem; + color: #333; +} + +.container { + max-width: 1200px; + margin: 0 auto; +} + +/* ================ Header Styles ================ */ +.header { + text-align: center; + margin-bottom: 3rem; +} + +.header h1 { + color: white; + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 0.5rem; +} + +.header p { + color: rgba(255, 255, 255, 0.8); + font-size: 1.1rem; + font-weight: 300; +} + +/* ================ Toggle Switch Styles ================ */ +.layout-toggle { + display: flex; + justify-content: center; + align-items: center; + gap: 1rem; + margin-bottom: 2rem; +} + +.toggle-label { + color: white; + font-weight: 500; +} + +.toggle-switch { + position: relative; + display: inline-block; + width: 60px; + height: 34px; +} + +.toggle-switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: .4s; + border-radius: 34px; +} + +.slider:before { + position: absolute; + content: ""; + height: 26px; + width: 26px; + left: 4px; + bottom: 4px; + background-color: white; + transition: .4s; + border-radius: 50%; +} + +input:checked + .slider { + background-color: #2196F3; +} + +input:checked + .slider:before { + transform: translateX(26px); +} + +/* ================ Layout Styles ================ */ +/* Flexbox Layout */ +.pricing-cards-flex { + display: flex; + gap: 2rem; + justify-content: center; + flex-wrap: wrap; +} + +/* Grid Layout */ +.pricing-cards-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + max-width: 1000px; + margin: 0 auto; +} + +/* ================ Pricing Card Styles ================ */ +.pricing-card { + background: white; + border-radius: 20px; + padding: 2.5rem 2rem; + text-align: center; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); + position: relative; + transition: all 0.3s ease; + overflow: hidden; + min-height: 500px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.pricing-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, #667eea, #764ba2); +} + +.pricing-card:hover { + transform: translateY(-10px); + box-shadow: 0 30px 60px rgba(0, 0, 0, 0.15); +} + +.pricing-card.featured { + border: 2px solid #667eea; + transform: scale(1.05); +} + +.pricing-card.featured::before { + height: 6px; +} + +.featured-badge { + position: absolute; + top: 20px; + right: -30px; + background: #667eea; + color: white; + padding: 5px 40px; + font-size: 0.8rem; + font-weight: 600; + transform: rotate(45deg); + text-transform: uppercase; +} + +/* ================ Card Content Styles ================ */ +.plan-name { + font-size: 1.5rem; + font-weight: 600; + color: #333; + margin-bottom: 0.5rem; +} + +.plan-description { + color: #666; + margin-bottom: 2rem; + font-size: 0.95rem; +} + +.price { + margin-bottom: 2rem; +} + +.price-amount { + font-size: 3rem; + font-weight: 700; + color: #333; + line-height: 1; +} + +.price-period { + font-size: 1rem; + color: #666; + font-weight: 400; +} + +/* ================ Features List Styles ================ */ +.features-list { + list-style: none; + margin-bottom: 2.5rem; + text-align: left; + flex-grow: 1; +} + +.features-list li { + padding: 0.75rem 0; + display: flex; + align-items: center; + font-size: 0.95rem; +} + +.features-list li i { + color: #667eea; + margin-right: 0.75rem; + font-size: 1.1rem; + width: 16px; +} + +.features-list li.unavailable { + color: #ccc; +} + +.features-list li.unavailable i { + color: #ccc; +} + +/* ================ Button Styles ================ */ +.cta-button { + width: 100%; + padding: 1rem 2rem; + border: none; + border-radius: 50px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-top: auto; +} + +.cta-button.primary { + background: linear-gradient(135deg, #667eea, #764ba2); + color: white; +} + +.cta-button.primary:hover { + background: linear-gradient(135deg, #5a6fd8, #6a4190); + transform: translateY(-2px); + box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3); +} + +.cta-button.secondary { + background: transparent; + color: #667eea; + border: 2px solid #667eea; +} + +.cta-button.secondary:hover { + background: #667eea; + color: white; + transform: translateY(-2px); + box-shadow: 0 10px 20px rgba(102, 126, 234, 0.2); +} + +/* ================ Navigation Styles ================ */ +.back-button { + position: fixed; + top: 2rem; + left: 2rem; + background: rgba(255, 255, 255, 0.2); + color: white; + border: 2px solid rgba(255, 255, 255, 0.3); + padding: 0.5rem 1rem; + border-radius: 25px; + text-decoration: none; + font-weight: 500; + backdrop-filter: blur(10px); + transition: all 0.3s ease; + z-index: 1000; + opacity: 1; + transform: translateY(0); +} + +.back-button:hover { + background: rgba(255, 255, 255, 0.3); + color: white; + text-decoration: none; + transform: translateX(-5px); +} + +.back-button.hidden-on-scroll { + opacity: 0; + transform: translateY(-100px); + pointer-events: none; +} + +/* ================ Utility Classes ================ */ +.hidden { + display: none; +} + +/* ================ Responsive Design ================ */ +@media (max-width: 768px) { + body { + padding: 1rem 0.5rem; + } + + .pricing-cards-flex { + flex-direction: column; + align-items: center; + } + + .pricing-cards-grid { + grid-template-columns: 1fr; + padding: 0 1rem; + } + + .pricing-card { + max-width: 350px; + min-height: auto; + } + + .pricing-card.featured { + transform: scale(1); + margin: 1rem 0; + } + + .header h1 { + font-size: 2rem; + } + + .header p { + font-size: 1rem; + } + + .price-amount { + font-size: 2.5rem; + } + + .back-button { + position: static; + display: inline-block; + margin-bottom: 2rem; + } +} + +@media (max-width: 480px) { + .pricing-card { + padding: 2rem 1.5rem; + margin: 0 0.5rem; + } + + .layout-toggle { + flex-direction: column; + gap: 0.5rem; + } + + .featured-badge { + font-size: 0.7rem; + padding: 3px 35px; + } +} + +/* ================ Animation Enhancements ================ */ +.pricing-card { + animation: fadeInUp 0.6s ease-out; +} + +.pricing-card:nth-child(2) { + animation-delay: 0.2s; +} + +.pricing-card:nth-child(3) { + animation-delay: 0.4s; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* ================ Dark Mode Support (Optional) ================ */ +@media (prefers-color-scheme: dark) { + .pricing-card { + background: #1a1a2e; + color: #eee; + } + + .plan-name { + color: #fff; + } + + .price-amount { + color: #fff; + } + + .plan-description { + color: #ccc; + } +} diff --git a/styles/profile-card.css b/styles/profile-card.css new file mode 100644 index 00000000..7ec6a75a --- /dev/null +++ b/styles/profile-card.css @@ -0,0 +1,416 @@ +/* Profile Card UI Styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 20px; + position: relative; +} + +.back-home { + position: fixed; + top: 20px; + left: 20px; + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.3); + padding: 12px 20px; + border-radius: 50px; + color: white; + text-decoration: none; + font-weight: 500; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + z-index: 1000; + display: flex; + align-items: center; + gap: 8px; + transform: translateY(0); + opacity: 1; +} + +.back-home:hover { + background: rgba(255, 255, 255, 0.3); + transform: translateY(-2px); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); +} + +.back-home.hidden-on-scroll { + transform: translateY(-100px); + opacity: 0; +} + +.container { + max-width: 1200px; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + gap: 2rem; +} + +.page-title { + text-align: center; + color: white; + margin-bottom: 2rem; +} + +.page-title h1 { + font-size: 3rem; + font-weight: 700; + margin-bottom: 0.5rem; + text-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); +} + +.page-title p { + font-size: 1.2rem; + opacity: 0.9; + font-weight: 400; +} + +.cards-container { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); + gap: 2rem; + width: 100%; + max-width: 1200px; +} + +.profile-card { + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(20px); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 24px; + padding: 2.5rem; + text-align: center; + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + overflow: hidden; +} + +.profile-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%); + border-radius: 24px; + opacity: 0; + transition: opacity 0.4s ease; + pointer-events: none; +} + +.profile-card:hover { + transform: translateY(-10px); + box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25); + border-color: rgba(255, 255, 255, 0.4); +} + +.profile-card:hover::before { + opacity: 1; +} + +.profile-image { + width: 120px; + height: 120px; + border-radius: 50%; + margin: 0 auto 1.5rem; + position: relative; + overflow: hidden; + border: 4px solid rgba(255, 255, 255, 0.3); + transition: all 0.3s ease; +} + +.profile-card:hover .profile-image { + transform: scale(1.05); + border-color: rgba(255, 255, 255, 0.5); +} + +.profile-image img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.3s ease; +} + +.profile-card:hover .profile-image img { + transform: scale(1.1); +} + +.profile-name { + font-size: 1.8rem; + font-weight: 700; + color: white; + margin-bottom: 0.5rem; + text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); +} + +.profile-title { + font-size: 1rem; + color: rgba(255, 255, 255, 0.8); + margin-bottom: 1.5rem; + font-weight: 500; +} + +.profile-bio { + font-size: 0.95rem; + color: rgba(255, 255, 255, 0.7); + line-height: 1.6; + margin-bottom: 2rem; + max-width: 280px; + margin-left: auto; + margin-right: auto; +} + +.profile-stats { + display: flex; + justify-content: space-around; + margin-bottom: 2rem; + padding: 1rem 0; + border-radius: 16px; + background: rgba(255, 255, 255, 0.1); +} + +.stat { + text-align: center; +} + +.stat-number { + font-size: 1.5rem; + font-weight: 700; + color: white; + display: block; +} + +.stat-label { + font-size: 0.8rem; + color: rgba(255, 255, 255, 0.7); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.social-links { + display: flex; + justify-content: center; + gap: 1rem; + margin-bottom: 1.5rem; +} + +.social-link { + width: 50px; + height: 50px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.2); + display: flex; + align-items: center; + justify-content: center; + color: white; + text-decoration: none; + font-size: 1.2rem; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + border: 1px solid rgba(255, 255, 255, 0.3); +} + +.social-link:hover { + transform: translateY(-3px) scale(1.1); + background: rgba(255, 255, 255, 0.3); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); +} + +.social-link.twitter:hover { background: rgba(29, 161, 242, 0.8); } +.social-link.linkedin:hover { background: rgba(0, 119, 181, 0.8); } +.social-link.github:hover { background: rgba(88, 96, 105, 0.8); } +.social-link.dribbble:hover { background: rgba(234, 76, 137, 0.8); } +.social-link.instagram:hover { + background: linear-gradient(45deg, #f09433 0%,#e6683c 25%,#dc2743 50%,#cc2366 75%,#bc1888 100%); +} + +.contact-btn { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 12px 30px; + border: none; + border-radius: 50px; + font-weight: 600; + font-size: 1rem; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 8px; + box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3); +} + +.contact-btn:hover { + transform: translateY(-2px); + box-shadow: 0 15px 35px rgba(102, 126, 234, 0.4); + filter: brightness(1.1); +} + +.layout-toggle { + position: fixed; + top: 20px; + right: 20px; + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.3); + padding: 12px; + border-radius: 50%; + color: white; + cursor: pointer; + font-size: 1.2rem; + transition: all 0.3s ease; + z-index: 1000; +} + +.layout-toggle:hover { + background: rgba(255, 255, 255, 0.3); + transform: rotate(180deg); +} + +/* Compact Layout */ +.compact-layout .profile-card { + padding: 1.5rem; + display: flex; + text-align: left; + align-items: center; + gap: 1.5rem; +} + +.compact-layout .profile-image { + width: 80px; + height: 80px; + margin: 0; + flex-shrink: 0; +} + +.compact-layout .profile-info { + flex: 1; +} + +.compact-layout .profile-name { + font-size: 1.4rem; + margin-bottom: 0.25rem; +} + +.compact-layout .profile-title { + margin-bottom: 0.75rem; +} + +.compact-layout .profile-bio { + margin-bottom: 1rem; + max-width: none; + margin-left: 0; + margin-right: 0; +} + +.compact-layout .profile-stats { + margin-bottom: 1rem; + padding: 0.5rem 0; +} + +.compact-layout .social-links { + margin-bottom: 0; + justify-content: flex-start; +} + +.compact-layout .social-link { + width: 40px; + height: 40px; + font-size: 1rem; +} + +/* Animations */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.profile-card { + animation: fadeInUp 0.6s ease-out; +} + +.profile-card:nth-child(2) { animation-delay: 0.1s; } +.profile-card:nth-child(3) { animation-delay: 0.2s; } +.profile-card:nth-child(4) { animation-delay: 0.3s; } + +@keyframes ripple { + to { + transform: scale(4); + opacity: 0; + } +} + +/* Responsive Design */ +@media (max-width: 768px) { + .page-title h1 { + font-size: 2rem; + } + + .page-title p { + font-size: 1rem; + } + + .cards-container { + grid-template-columns: 1fr; + gap: 1.5rem; + } + + .profile-card { + padding: 2rem; + } + + .back-home { + top: 10px; + left: 10px; + padding: 10px 16px; + font-size: 0.9rem; + } + + .layout-toggle { + top: 10px; + right: 10px; + } + + .compact-layout .profile-card { + flex-direction: column; + text-align: center; + gap: 1rem; + } + + .compact-layout .social-links { + justify-content: center; + } +} + +@media (max-width: 480px) { + .profile-card { + padding: 1.5rem; + } + + .profile-name { + font-size: 1.5rem; + } + + .social-links { + flex-wrap: wrap; + gap: 0.75rem; + } +} diff --git a/styles/responsive-navbar.css b/styles/responsive-navbar.css new file mode 100644 index 00000000..80600777 --- /dev/null +++ b/styles/responsive-navbar.css @@ -0,0 +1,535 @@ +/* Responsive Navbar CSS */ + +/* ================ Reset and Base Styles ================ */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', sans-serif; + line-height: 1.6; + color: #333; + background: #f8fafc; +} + +/* ================ Navbar Styles ================ */ +.navbar { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + transition: all 0.3s ease; +} + +.navbar.scrolled { + background: rgba(255, 255, 255, 0.98); + box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1); +} + +.navbar-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 1rem; + display: flex; + align-items: center; + justify-content: space-between; + height: 70px; +} + +/* ================ Logo Styles ================ */ +.navbar-logo { + display: flex; + align-items: center; + text-decoration: none; + font-size: 1.8rem; + font-weight: 700; + color: #667eea; + transition: all 0.3s ease; +} + +.navbar-logo:hover { + color: #5a6fd8; + text-decoration: none; +} + +.navbar-logo span { + color: #2d3748; +} + +.logo-icon { + width: 35px; + height: 35px; + margin-right: 0.5rem; + background: linear-gradient(135deg, #667eea, #764ba2); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 1.2rem; +} + +/* ================ Navigation Menu Styles ================ */ +.navbar-menu { + display: flex; + align-items: center; + list-style: none; + gap: 0.5rem; +} + +.navbar-item { + position: relative; +} + +.navbar-link { + display: flex; + align-items: center; + padding: 0.75rem 1rem; + text-decoration: none; + color: #4a5568; + font-weight: 500; + border-radius: 8px; + transition: all 0.3s ease; + position: relative; +} + +.navbar-link:hover { + color: #667eea; + background: rgba(102, 126, 234, 0.1); + text-decoration: none; + transform: translateY(-1px); +} + +.navbar-link.active { + color: #667eea; + background: rgba(102, 126, 234, 0.15); +} + +.navbar-link i { + margin-right: 0.5rem; + font-size: 1rem; +} + +/* ================ Dropdown Styles ================ */ +.dropdown { + position: relative; +} + +.dropdown-content { + position: absolute; + top: 100%; + left: 0; + background: white; + min-width: 200px; + border-radius: 12px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); + border: 1px solid rgba(0, 0, 0, 0.1); + opacity: 0; + visibility: hidden; + transform: translateY(-10px); + transition: all 0.3s ease; + z-index: 1001; +} + +.dropdown:hover .dropdown-content { + opacity: 1; + visibility: visible; + transform: translateY(0); +} + +.dropdown-item { + display: block; + padding: 0.75rem 1rem; + color: #4a5568; + text-decoration: none; + transition: all 0.2s ease; + border-radius: 8px; + margin: 0.25rem; +} + +.dropdown-item:hover { + background: rgba(102, 126, 234, 0.1); + color: #667eea; + text-decoration: none; +} + +.dropdown-item i { + margin-right: 0.5rem; + width: 16px; + text-align: center; +} + +/* ================ CTA Button Styles ================ */ +.navbar-cta { + background: linear-gradient(135deg, #667eea, #764ba2); + color: white; + padding: 0.6rem 1.5rem; + border-radius: 25px; + text-decoration: none; + font-weight: 600; + margin-left: 1rem; + transition: all 0.3s ease; + border: 2px solid transparent; +} + +.navbar-cta:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); + color: white; + text-decoration: none; +} + +/* ================ Mobile Menu Toggle ================ */ +.mobile-menu-toggle { + display: none; + flex-direction: column; + cursor: pointer; + padding: 0.5rem; + border: none; + background: transparent; + border-radius: 6px; + transition: all 0.3s ease; +} + +.mobile-menu-toggle:hover { + background: rgba(102, 126, 234, 0.1); +} + +.hamburger { + width: 25px; + height: 3px; + background: #4a5568; + margin: 3px 0; + transition: all 0.3s ease; + border-radius: 2px; +} + +.mobile-menu-toggle.active .hamburger:nth-child(1) { + transform: rotate(45deg) translate(5px, 5px); + background: #667eea; +} + +.mobile-menu-toggle.active .hamburger:nth-child(2) { + opacity: 0; +} + +.mobile-menu-toggle.active .hamburger:nth-child(3) { + transform: rotate(-45deg) translate(7px, -6px); + background: #667eea; +} + +/* ================ Mobile Menu Styles ================ */ +.mobile-menu { + position: fixed; + top: 70px; + left: 0; + right: 0; + background: rgba(255, 255, 255, 0.98); + backdrop-filter: blur(10px); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + transform: translateY(-100%); + opacity: 0; + transition: all 0.4s ease; + z-index: 999; + max-height: calc(100vh - 70px); + overflow-y: auto; +} + +.mobile-menu.active { + transform: translateY(0); + opacity: 1; +} + +.mobile-menu-list { + list-style: none; + padding: 1rem 0; +} + +.mobile-menu-item { + margin: 0; +} + +.mobile-menu-link { + display: flex; + align-items: center; + padding: 1rem 1.5rem; + color: #4a5568; + text-decoration: none; + font-weight: 500; + transition: all 0.3s ease; + border-left: 3px solid transparent; +} + +.mobile-menu-link:hover, +.mobile-menu-link.active { + color: #667eea; + background: rgba(102, 126, 234, 0.1); + border-left-color: #667eea; + text-decoration: none; +} + +.mobile-menu-link i { + margin-right: 1rem; + font-size: 1.1rem; + width: 20px; +} + +/* Mobile Dropdown */ +.mobile-dropdown-content { + background: rgba(102, 126, 234, 0.05); + padding-left: 2rem; + max-height: 0; + overflow: hidden; + transition: all 0.3s ease; +} + +.mobile-dropdown-content.active { + max-height: 300px; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.mobile-dropdown-item { + display: block; + padding: 0.75rem 1rem; + color: #718096; + text-decoration: none; + font-size: 0.9rem; + transition: all 0.2s ease; +} + +.mobile-dropdown-item:hover { + color: #667eea; + text-decoration: none; +} + +.mobile-dropdown-item i { + margin-right: 0.5rem; + width: 16px; +} + +.mobile-dropdown-toggle { + margin-left: auto; + transition: transform 0.3s ease; +} + +.mobile-dropdown-toggle.active { + transform: rotate(180deg); +} + +/* ================ Back Button ================ */ +.back-button { + position: fixed; + bottom: 2rem; + right: 2rem; + background: linear-gradient(135deg, #667eea, #764ba2); + color: white; + width: 60px; + height: 60px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + text-decoration: none; + font-size: 1.2rem; + box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4); + transition: all 0.3s ease; + z-index: 1000; +} + +.back-button:hover { + transform: translateY(-5px); + box-shadow: 0 15px 35px rgba(102, 126, 234, 0.5); + color: white; + text-decoration: none; +} + +/* ================ Demo Content Styles ================ */ +.demo-content { + margin-top: 70px; + padding: 2rem 1rem; + max-width: 1200px; + margin-left: auto; + margin-right: auto; +} + +.hero-section { + background: linear-gradient(135deg, #667eea, #764ba2); + color: white; + padding: 4rem 2rem; + text-align: center; + border-radius: 20px; + margin: 2rem 0; +} + +.hero-title { + font-size: 3rem; + font-weight: 700; + margin-bottom: 1rem; +} + +.hero-subtitle { + font-size: 1.2rem; + opacity: 0.9; + margin-bottom: 2rem; +} + +.demo-section { + background: white; + padding: 3rem 2rem; + border-radius: 15px; + margin: 2rem 0; + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1); + opacity: 0; + transform: translateY(30px); + transition: all 0.6s ease; +} + +.demo-section.visible { + opacity: 1; + transform: translateY(0); +} + +.section-title { + font-size: 2rem; + font-weight: 600; + color: #2d3748; + margin-bottom: 1rem; +} + +.section-content { + color: #718096; + line-height: 1.8; +} + +/* ================ Responsive Styles ================ */ +@media (max-width: 768px) { + .navbar-menu { + display: none; + } + + .mobile-menu-toggle { + display: flex; + } + + .navbar-cta { + display: none; + } + + .hero-title { + font-size: 2rem; + } + + .hero-subtitle { + font-size: 1rem; + } + + .demo-section { + padding: 2rem 1.5rem; + } + + .back-button { + bottom: 1rem; + right: 1rem; + width: 50px; + height: 50px; + font-size: 1rem; + } +} + +@media (max-width: 480px) { + .navbar-container { + padding: 0 0.75rem; + } + + .navbar-logo { + font-size: 1.5rem; + } + + .logo-icon { + width: 30px; + height: 30px; + font-size: 1rem; + } + + .hero-section { + padding: 3rem 1.5rem; + } + + .demo-section { + padding: 1.5rem 1rem; + } +} + +/* ================ Accessibility ================ */ +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} + +/* ================ Dark Mode Support ================ */ +@media (prefers-color-scheme: dark) { + body { + background: #1a202c; + color: #e2e8f0; + } + + .navbar { + background: rgba(26, 32, 44, 0.95); + border-bottom-color: rgba(255, 255, 255, 0.1); + } + + .navbar.scrolled { + background: rgba(26, 32, 44, 0.98); + } + + .mobile-menu { + background: rgba(26, 32, 44, 0.98); + } + + .navbar-link, + .mobile-menu-link { + color: #a0aec0; + } + + .navbar-link:hover, + .navbar-link.active, + .mobile-menu-link:hover, + .mobile-menu-link.active { + color: #667eea; + } + + .dropdown-content { + background: #2d3748; + border-color: rgba(255, 255, 255, 0.1); + } + + .dropdown-item { + color: #a0aec0; + } + + .dropdown-item:hover { + color: #667eea; + } + + .demo-section { + background: #2d3748; + } + + .section-title { + color: #f7fafc; + } + + .section-content { + color: #a0aec0; + } +} diff --git a/uiChallenges.html b/uiChallenges.html index 6fbe8462..45456acb 100644 --- a/uiChallenges.html +++ b/uiChallenges.html @@ -32,22 +32,37 @@

UI Design Tasks

Profile Card UI
Design and build a profile card with image, name, and social links.
+
+ View Solution +
Pricing Table
Create a clean and responsive pricing component for a SaaS app.
+
+ View Solution +
Login Page UI
Design a modern login form with input validation UI.
+
+ View Solution +
Navbar with Dropdown
Build a responsive navigation bar with dropdown support.
+
+ View Solution +
Dark Mode Toggle
Add a dark mode toggle switch with a smooth transition effect.
+
+ View Solution +