Border animations can add a dynamic and engaging touch to any user interface. They enhance the visual appeal and can guide user interactions seamlessly.
In this article, we will explore 10 stunning border animation examples that can elevate your design projects. Each example showcases unique styles and techniques to inspire your next UI creation.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Subframe's drag-and-drop interface and intuitive, responsive canvas make it effortless to create pixel-perfect UI, including stunning border animations. Loved by designers and developers alike, Subframe ensures your designs are both beautiful and functional.
Start for free and elevate your design projects today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your design projects? With Subframe, you can create pixel-perfect UIs, including stunning border animations, in minutes. Our drag-and-drop interface ensures efficiency and precision.
Don't wait! Start for free and begin designing immediately. Experience the ease and power of Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SaaS Dashboard Interactive Buttons</title> <style> :root { --primary: #2c7be5; --primary-light: #4d95ff; --dark: #1e293b; --gray-light: #f1f5f9; --gray: #64748b; --white: #ffffff; --shadow: rgba(0, 0, 0, 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } body { width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; background-color: var(--gray-light); overflow: hidden; } .dashboard { width: 650px; height: 650px; background-color: var(--white); border-radius: 16px; box-shadow: 0 10px 25px var(--shadow); padding: 24px; display: flex; flex-direction: column; overflow: hidden; position: relative; } .dashboard::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, var(--primary), var(--primary-light)); } .dashboard-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; } .logo { display: flex; align-items: center; gap: 8px; } .logo-icon { width: 32px; height: 32px; background-color: var(--primary); border-radius: 8px; display: flex; justify-content: center; align-items: center; color: white; font-weight: bold; } .dashboard-title { font-size: 20px; font-weight: 600; color: var(--dark); } .user-avatar { width: 40px; height: 40px; border-radius: 50%; background-color: var(--gray-light); display: flex; justify-content: center; align-items: center; color: var(--primary); font-weight: bold; cursor: pointer; transition: all 0.3s ease; } .user-avatar:hover { box-shadow: 0 0 0 2px var(--primary-light); } .dashboard-content { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 24px; } .metric-card { background-color: var(--gray-light); border-radius: 12px; padding: 16px; display: flex; flex-direction: column; gap: 8px; } .metric-title { font-size: 14px; color: var(--gray); } .metric-value { font-size: 24px; font-weight: 600; color: var(--dark); } .metric-change { font-size: 12px; color: #10b981; } .negative { color: #ef4444; } .interactive-button { position: relative; padding: 12px 20px; border-radius: 8px; background-color: var(--white); color: var(--dark); font-weight: 500; border: none; cursor: pointer; overflow: hidden; transition: transform 0.2s ease, box-shadow 0.3s ease; margin: 8px; } .interactive-button::before { content: ""; position: absolute; inset: 0; border: 2px solid transparent; border-radius: 8px; background: linear-gradient(90deg, var(--primary), var(--primary-light)) border-box; -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0.7; transition: all 0.3s ease; } .interactive-button::after { content: ""; position: absolute; inset: -5px; border-radius: 12px; background: linear-gradient(90deg, var(--primary), var(--primary-light)); opacity: 0; z-index: -1; filter: blur(8px); transition: opacity 0.3s ease; } .interactive-button:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(44, 123, 229, 0.2); } .interactive-button:hover::before { opacity: 1; } .interactive-button:hover::after { opacity: 0.6; } .interactive-button:active { transform: translateY(0); } .interactive-button-primary { background-color: var(--primary); color: var(--white); } .interactive-button-primary::before { background: linear-gradient(90deg, var(--primary-light), #6aa8ff) border-box; } .button-section { display: flex; flex-direction: column; gap: 16px; } .button-group { display: flex; flex-wrap: wrap; gap: 12px; } .section-title { font-size: 16px; font-weight: 600; color: var(--dark); margin-bottom: 8px; } .action-panel { background-color: var(--gray-light); border-radius: 12px; padding: 20px; margin-top: auto; } .action-title { font-size: 18px; font-weight: 600; color: var(--dark); margin-bottom: 16px; } .action-content { display: flex; justify-content: space-between; align-items: center; } .action-buttons { display: flex; gap: 12px; } .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.5); transform: scale(0); animation: ripple 0.6s linear; pointer-events: none; } @keyframes ripple { to { transform: scale(4); opacity: 0; } } @media (max-width: 700px) { .dashboard { width: 100%; height: 100%; border-radius: 0; padding: 16px; } .dashboard-content { grid-template-columns: 1fr; } .button-group { flex-direction: column; } } </style> </head> <body> <div class="dashboard"> <div class="dashboard-header"> <div class="logo"> <div class="logo-icon">P</div> <h1 class="dashboard-title">PulseMetrics</h1> </div> <div class="user-avatar">JD</div> </div> <div class="dashboard-content"> <div class="metric-card"> <div class="metric-title">Active Users</div> <div class="metric-value">1,248</div> <div class="metric-change">+12.5% from last week</div> </div> <div class="metric-card"> <div class="metric-title">Conversion Rate</div> <div class="metric-value">3.8%</div> <div class="metric-change">+0.6% from last week</div> </div> <div class="metric-card"> <div class="metric-title">Churn Rate</div> <div class="metric-value">1.2%</div> <div class="metric-change negative">+0.3% from last week</div> </div> </div> <div class="button-section"> <div class="section-title">Quick Actions</div> <div class="button-group"> <button class="interactive-button">Generate Report</button> <button class="interactive-button">User Analytics</button> <button class="interactive-button">Integrations</button> </div> </div> <div class="button-section"> <div class="section-title">Data Controls</div> <div class="button-group"> <button class="interactive-button">Export Data</button> <button class="interactive-button">View API Keys</button> <button class="interactive-button">Configure Alerts</button> </div> </div> <div class="action-panel"> <h3 class="action-title">Update Needed: Analytics Engine</h3> <div class="action-content"> <p>Your analytics engine needs an update to access new customer journey metrics.</p> <div class="action-buttons"> <button class="interactive-button">Dismiss</button> <button class="interactive-button interactive-button-primary">Update Now</button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { // Ripple effect for buttons const buttons = document.querySelectorAll('.interactive-button'); buttons.forEach(button => { button.addEventListener('click', function(e) { const x = e.clientX - e.target.getBoundingClientRect().left; const y = e.clientY - e.target.getBoundingClientRect().top; const ripple = document.createElement('span'); ripple.classList.add('ripple'); ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); }); // Simulate data update (for demo purposes) setTimeout(() => { const metrics = document.querySelectorAll('.metric-value'); metrics.forEach(metric => { const originalValue = metric.textContent; // Create animation effect const animateValue = (start, end, duration) => { let startTimestamp = null; const step = (timestamp) => { if (!startTimestamp) startTimestamp = timestamp; const progress = Math.min((timestamp - startTimestamp) / duration, 1); const value = Math.floor(progress * (end - start) + start); metric.textContent = value.toLocaleString() + (metric.textContent.includes('%') ? '%' : ''); if (progress < 1) { window.requestAnimationFrame(step); } else { metric.textContent = originalValue; } }; window.requestAnimationFrame(step); }; // Parse and animate each value type appropriately if (originalValue.includes('%')) { const value = parseFloat(originalValue); animateValue(0, value * 100, 1000); } else { const value = parseInt(originalValue.replace(/,/g, '')); animateValue(0, value, 1000); } }); }, 2000); // Initialize button pulse animation const addPulseEffect = () => { const primaryButtons = document.querySelectorAll('.interactive-button-primary'); primaryButtons.forEach(button => { button.style.animation = 'none'; button.offsetHeight; // Trigger reflow button.style.animation = null; button.classList.add('pulse'); setTimeout(() => { button.classList.remove('pulse'); }, 2000); }); }; // Add pulse effect periodically setInterval(addPulseEffect, 5000); addPulseEffect(); // Initial pulse }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Healthcare Form Input Focus</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f7f9f8; color: #2c3e50; padding: 1rem; } .form-container { width: 100%; max-width: 600px; background-color: #ffffff; padding: 2.5rem; border-radius: 1rem; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.04), 0 1px 8px rgba(0, 0, 0, 0.02); position: relative; overflow: hidden; } .form-container::before { content: ""; position: absolute; top: 0; left: 0; width: 8px; height: 100%; background: linear-gradient(to bottom, #4bb79e, #3a9d8a); border-radius: 4px 0 0 4px; opacity: 0.9; } h1 { font-size: 1.75rem; font-weight: 600; margin-bottom: 0.75rem; color: #2f4858; } .intro-text { font-size: 0.95rem; color: #607d8b; margin-bottom: 2rem; line-height: 1.5; } form { display: grid; gap: 1.5rem; } .input-group { position: relative; } label { display: block; font-size: 0.9rem; font-weight: 500; margin-bottom: 0.5rem; color: #425a70; transition: color 0.3s ease; } input, textarea, select { width: 100%; padding: 0.85rem 1rem; border: 2px solid #e1e8ed; border-radius: 0.5rem; font-size: 1rem; background-color: #fbfcfc; color: #2c3e50; transition: all 0.3s ease; outline: none; } input::placeholder, textarea::placeholder { color: #a0aec0; } .input-border { position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; border-radius: 0.5rem; pointer-events: none; border: 2px solid transparent; transition: all 0.3s ease; } .input-group:hover .input-border { border-color: rgba(75, 183, 158, 0.3); } .input-group:focus-within .input-border { border-color: #4bb79e; box-shadow: 0 0 0 4px rgba(75, 183, 158, 0.15); animation: pulsate 2s infinite; } .input-group:focus-within label { color: #4bb79e; } @keyframes pulsate { 0% { box-shadow: 0 0 0 0 rgba(75, 183, 158, 0.4); } 70% { box-shadow: 0 0 0 6px rgba(75, 183, 158, 0); } 100% { box-shadow: 0 0 0 0 rgba(75, 183, 158, 0); } } .checkbox-group { display: flex; align-items: center; gap: 0.5rem; margin: 0.5rem 0; } .checkbox-container { position: relative; display: flex; align-items: center; cursor: pointer; } .checkbox-container input { position: absolute; opacity: 0; cursor: pointer; height: 0; width: 0; } .checkmark { position: relative; height: 20px; width: 20px; background-color: #f1f5f7; border: 2px solid #e1e8ed; border-radius: 4px; transition: all 0.2s ease; flex-shrink: 0; } .checkbox-container:hover input ~ .checkmark { background-color: #e8f4f1; border-color: #4bb79e; } .checkbox-container input:checked ~ .checkmark { background-color: #4bb79e; border-color: #4bb79e; } .checkmark:after { content: ""; position: absolute; display: none; } .checkbox-container input:checked ~ .checkmark:after { display: block; } .checkbox-container .checkmark:after { left: 6px; top: 2px; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } .checkbox-label { font-size: 0.9rem; margin-left: 0.5rem; user-select: none; color: #425a70; } button { background: linear-gradient(to right, #4bb79e, #3a9d8a); color: white; border: none; padding: 0.85rem 1.5rem; border-radius: 0.5rem; font-size: 1rem; font-weight: 500; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 4px 12px rgba(75, 183, 158, 0.2); position: relative; overflow: hidden; } button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: 0.5s; } button:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(75, 183, 158, 0.3); } button:hover::before { left: 100%; } button:active { transform: translateY(0); } .form-section { margin-bottom: 1.5rem; } .form-section-title { font-size: 1.1rem; color: #3a9d8a; margin-bottom: 1rem; font-weight: 600; display: flex; align-items: center; } .form-section-title::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background-color: #4bb79e; margin-right: 0.5rem; } .info-icon { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background-color: #e8f4f1; color: #4bb79e; font-size: 12px; margin-left: 0.5rem; cursor: pointer; } .info-tooltip { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%) translateY(-10px); width: 200px; padding: 0.75rem; background-color: #2f4858; color: #ffffff; border-radius: 6px; font-size: 0.8rem; pointer-events: none; opacity: 0; transition: all 0.3s ease; z-index: 100; line-height: 1.4; visibility: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.1); } .info-tooltip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border-width: 5px; border-style: solid; border-color: #2f4858 transparent transparent transparent; } .info-icon:hover .info-tooltip { opacity: 1; transform: translateX(-50%) translateY(-5px); visibility: visible; } .input-counter { position: absolute; bottom: 10px; right: 10px; font-size: 0.75rem; color: #a0aec0; pointer-events: none; transition: color 0.3s ease; } textarea:focus ~ .input-counter, textarea:not(:placeholder-shown) ~ .input-counter { color: #4bb79e; } .is-success .input-border { border-color: #4bb79e; } .is-error .input-border { border-color: #e53e3e; } .is-error .error-message { display: block; } .error-message { display: none; font-size: 0.8rem; color: #e53e3e; margin-top: 0.5rem; } .success-banner { display: none; position: absolute; top: 20px; left: 50%; transform: translateX(-50%); background-color: #4bb79e; color: white; padding: 1rem 1.5rem; border-radius: 0.5rem; animation: slideDown 0.5s ease forwards; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); z-index: 100; width: 90%; max-width: 500px; text-align: center; } @keyframes slideDown { from { opacity: 0; transform: translateX(-50%) translateY(-20px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } } @media (max-width: 600px) { .form-container { padding: 1.5rem; } h1 { font-size: 1.5rem; } .form-section-title { font-size: 1rem; } } .progress-container { height: 4px; width: 100%; background-color: #f1f5f7; border-radius: 2px; margin-bottom: 2rem; position: relative; overflow: hidden; } .progress-bar { height: 100%; width: 0; background: linear-gradient(to right, #4bb79e, #3a9d8a); transition: width 0.5s ease-in-out; } /* Pattern decoration */ .pattern-bg { position: absolute; top: 0; right: 0; width: 100px; height: 100px; opacity: 0.05; pointer-events: none; background-image: radial-gradient(#4bb79e 2px, transparent 2px); background-size: 15px 15px; } </style> </head> <body> <div class="form-container"> <div class="pattern-bg"></div> <h1>Patient Information System</h1> <p class="intro-text">Please provide your health information to help us personalize your care. Your data is protected under HIPAA regulations and remains confidential.</p> <div class="progress-container"> <div class="progress-bar" id="progressBar"></div> </div> <form id="healthcareForm"> <div class="form-section"> <div class="form-section-title">Personal Details</div> <div class="input-group"> <label for="fullName">Full Name</label> <input type="text" id="fullName" placeholder="John Smith" required> <div class="input-border"></div> </div> <div class="input-group"> <label for="dob">Date of Birth</label> <input type="date" id="dob" required> <div class="input-border"></div> </div> <div class="input-group"> <label for="mrn">Medical Record Number <span class="info-icon">i <span class="info-tooltip">Your MRN is a unique identifier found on your patient ID card or previous medical documents.</span> </span></label> <input type="text" id="mrn" placeholder="MRN12345678" pattern="[A-Za-z0-9]{8,12}"> <div class="input-border"></div> <div class="error-message">Please enter a valid MRN (8-12 alphanumeric characters)</div> </div> </div> <div class="form-section"> <div class="form-section-title">Health Information</div> <div class="input-group"> <label for="currentMedications">Current Medications</label> <textarea id="currentMedications" placeholder="List medications including dosage and frequency" rows="3" maxlength="200"></textarea> <div class="input-border"></div> <div class="input-counter"><span id="medicationCount">0</span>/200</div> </div> <div class="input-group"> <label for="allergies">Known Allergies</label> <input type="text" id="allergies" placeholder="Medications, foods, or substances you're allergic to"> <div class="input-border"></div> </div> <div class="input-group"> <label for="primaryConcern">Primary Health Concern</label> <select id="primaryConcern" required> <option value="" disabled selected>Select your primary concern</option> <option value="preventive">Preventive Check-up</option> <option value="chronic">Chronic Condition Management</option> <option value="acute">Acute Illness</option> <option value="pain">Pain Management</option> <option value="mental">Mental Health</option> <option value="other">Other</option> </select> <div class="input-border"></div> </div> </div> <div class="form-section"> <div class="form-section-title">Communication Preferences</div> <div class="input-group"> <label for="contactPhone">Preferred Contact Number</label> <input type="tel" id="contactPhone" placeholder="(555) 123-4567" pattern="[\d\(\)\-\+ ]{10,15}"> <div class="input-border"></div> </div> <div> <label>Appointment Reminders</label> <div class="checkbox-group"> <label class="checkbox-container"> <input type="checkbox" name="reminderType" value="text"> <span class="checkmark"></span> <span class="checkbox-label">Text Message</span> </label> </div> <div class="checkbox-group"> <label class="checkbox-container"> <input type="checkbox" name="reminderType" value="email"> <span class="checkmark"></span> <span class="checkbox-label">Email</span> </label> </div> <div class="checkbox-group"> <label class="checkbox-container"> <input type="checkbox" name="reminderType" value="call"> <span class="checkmark"></span> <span class="checkbox-label">Phone Call</span> </label> </div> </div> </div> <button type="submit" id="submitButton">Submit Information</button> </form> <div class="success-banner" id="successBanner"> Your information has been successfully saved to our system. </div> </div> <script> // Input focus and validation effects const inputs = document.querySelectorAll('input, textarea, select'); const form = document.getElementById('healthcareForm'); const progressBar = document.getElementById('progressBar'); const successBanner = document.getElementById('successBanner'); const medicationTextarea = document.getElementById('currentMedications'); const medicationCount = document.getElementById('medicationCount'); // Update character count for medication textarea medicationTextarea.addEventListener('input', function() { medicationCount.textContent = this.value.length; }); // Calculate form completion progress function updateProgress() { const requiredFields = form.querySelectorAll('[required]'); const filledFields = Array.from(requiredFields).filter(field => field.value.trim() !== ''); const progress = (filledFields.length / requiredFields.length) * 100; progressBar.style.width = `${progress}%`; } // Initialize progress updateProgress(); // Add event listeners to inputs inputs.forEach(input => { // Update progress when input changes input.addEventListener('input', updateProgress); // Add validation check for specific fields if (input.id === 'mrn') { input.addEventListener('blur', function() { const parent = this.parentElement; const isValid = this.validity.valid; if (this.value && !isValid) { parent.classList.add('is-error'); parent.classList.remove('is-success'); } else if (this.value) { parent.classList.add('is-success'); parent.classList.remove('is-error'); } else { parent.classList.remove('is-success', 'is-error'); } }); } // Add pulsating animation when focused input.addEventListener('focus', function() { // Stop pulsating animation for all other inputs inputs.forEach(otherInput => { if (otherInput !== this) { const otherBorder = otherInput.nextElementSibling; if (otherBorder && otherBorder.classList.contains('input-border')) { otherBorder.style.animation = 'none'; } } }); // Start pulsating animation for this input const border = this.nextElementSibling; if (border && border.classList.contains('input-border')) { border.style.animation = 'pulsate 2s infinite'; } }); // Remove animation when blurred input.addEventListener('blur', function() { const border = this.nextElementSibling; if (border && border.classList.contains('input-border')) { border.style.animation = 'none'; } }); }); // Form submission handler form.addEventListener('submit', function(e) { e.preventDefault(); // Simulate form submission delay const submitButton = document.getElementById('submitButton'); submitButton.disabled = true; submitButton.textContent = 'Processing...'; setTimeout(() => { // Show success message successBanner.style.display = 'block'; // Reset button submitButton.disabled = false; submitButton.textContent = 'Submit Information'; // Hide success message after 4 seconds setTimeout(() => { successBanner.style.display = 'none'; }, 4000); // Optional: reset form // form.reset(); // progressBar.style.width = '0'; }, 1500); }); // Add subtle interactivity to form sections const formSections = document.querySelectorAll('.form-section'); formSections.forEach(section => { const title = section.querySelector('.form-section-title'); title.addEventListener('click', () => { // Find first input in this section and focus it const firstInput = section.querySelector('input, textarea, select'); if (firstInput) { firstInput.focus(); } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #2A3FFF; --business: #FF5733; --tech: #00BFA6; --politics: #9C27B0; --health: #FF9800; --science: #3F51B5; --background: #F8F9FA; --card-bg: #FFFFFF; --text-main: #212529; --text-secondary: #6C757D; --border-radius: 12px; --animation-speed: 0.7s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } body { background-color: var(--background); color: var(--text-main); display: flex; flex-direction: column; align-items: center; padding: 20px; min-height: 700px; max-width: 700px; margin: 0 auto; } .header { width: 100%; text-align: center; margin-bottom: 25px; } .header h1 { font-size: 28px; margin-bottom: 8px; background: linear-gradient(45deg, var(--primary), var(--tech)); -webkit-background-clip: text; background-clip: text; color: transparent; letter-spacing: -0.5px; } .header p { color: var(--text-secondary); font-size: 14px; max-width: 90%; margin: 0 auto; } .categories { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; justify-content: center; } .category { background: none; border: none; padding: 6px 12px; border-radius: 20px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; position: relative; overflow: hidden; } .category::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: currentColor; opacity: 0.1; border-radius: 20px; transition: opacity 0.2s ease; } .category:hover::before { opacity: 0.2; } .category.active::before { opacity: 0.15; } .category[data-category="all"] { color: var(--primary); } .category[data-category="business"] { color: var(--business); } .category[data-category="tech"] { color: var(--tech); } .category[data-category="politics"] { color: var(--politics); } .category[data-category="health"] { color: var(--health); } .category[data-category="science"] { color: var(--science); } .news-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; width: 100%; } .card { background-color: var(--card-bg); border-radius: var(--border-radius); overflow: hidden; position: relative; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; } .card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); } .card::before { content: ''; position: absolute; width: 100%; height: 100%; border-radius: var(--border-radius); z-index: 0; } .animated-border { position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: var(--border-radius); pointer-events: none; } .animated-border::before { content: ''; position: absolute; inset: 0; border-radius: var(--border-radius); padding: 2px; background: conic-gradient( from 0deg at 50% 50%, transparent 0%, transparent 25%, currentColor 25%, currentColor 75%, transparent 75%, transparent 100% ); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity 0.2s ease; } .card:hover .animated-border::before { opacity: 1; animation: rotate var(--animation-speed) linear infinite; } @keyframes rotate { from { background-position: 0% 0%; } to { background-position: 100% 100%; } } .card[data-category="business"] .animated-border { color: var(--business); } .card[data-category="tech"] .animated-border { color: var(--tech); } .card[data-category="politics"] .animated-border { color: var(--politics); } .card[data-category="health"] .animated-border { color: var(--health); } .card[data-category="science"] .animated-border { color: var(--science); } .card-inner { position: relative; z-index: 1; padding: 20px; height: 100%; display: flex; flex-direction: column; } .card-tag { display: inline-block; padding: 4px 10px; font-size: 10px; font-weight: 600; text-transform: uppercase; border-radius: 15px; margin-bottom: 12px; letter-spacing: 0.5px; } .card[data-category="business"] .card-tag { background-color: rgba(255, 87, 51, 0.1); color: var(--business); } .card[data-category="tech"] .card-tag { background-color: rgba(0, 191, 166, 0.1); color: var(--tech); } .card[data-category="politics"] .card-tag { background-color: rgba(156, 39, 176, 0.1); color: var(--politics); } .card[data-category="health"] .card-tag { background-color: rgba(255, 152, 0, 0.1); color: var(--health); } .card[data-category="science"] .card-tag { background-color: rgba(63, 81, 181, 0.1); color: var(--science); } .card-title { font-size: 18px; font-weight: 700; margin-bottom: 12px; line-height: 1.3; } .card-excerpt { font-size: 14px; color: var(--text-secondary); margin-bottom: 16px; line-height: 1.5; flex-grow: 1; } .card-meta { display: flex; justify-content: space-between; align-items: center; font-size: 12px; color: var(--text-secondary); margin-top: auto; } .card-meta .time { display: flex; align-items: center; gap: 4px; } .card-meta .time svg { width: 12px; height: 12px; opacity: 0.7; } .card-meta .source { font-weight: 500; } @media (max-width: 600px) { .news-container { grid-template-columns: 1fr; } .header h1 { font-size: 24px; } .categories { gap: 6px; } .category { padding: 5px 10px; font-size: 12px; } } /* Tooltip styles */ .tooltip { position: absolute; background: rgba(0, 0, 0, 0.8); color: white; padding: 8px 12px; border-radius: 4px; font-size: 12px; pointer-events: none; opacity: 0; transition: opacity 0.2s; z-index: 100; max-width: 200px; text-align: center; } .pulse-dot { position: absolute; width: 6px; height: 6px; border-radius: 50%; top: 12px; right: 12px; animation: pulse 2s infinite; } .card[data-category="business"] .pulse-dot { background-color: var(--business); } .card[data-category="tech"] .pulse-dot { background-color: var(--tech); } .card[data-category="politics"] .pulse-dot { background-color: var(--politics); } .card[data-category="health"] .pulse-dot { background-color: var(--health); } .card[data-category="science"] .pulse-dot { background-color: var(--science); } @keyframes pulse { 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.3); } 70% { transform: scale(1); box-shadow: 0 0 0 5px rgba(0, 0, 0, 0); } 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); } } </style> </head> <body> <div class="header"> <h1>Pulse News</h1> <p>Today's top stories with real-time updates across categories</p> </div> <div class="categories"> <button class="category active" data-category="all">All Stories</button> <button class="category" data-category="business">Business</button> <button class="category" data-category="tech">Technology</button> <button class="category" data-category="politics">Politics</button> <button class="category" data-category="health">Health</button> <button class="category" data-category="science">Science</button> </div> <div class="news-container"> <div class="card" data-category="business"> <div class="animated-border"></div> <div class="pulse-dot"></div> <div class="card-inner"> <span class="card-tag">Business</span> <h3 class="card-title">Global Markets Rally as Central Banks Signal Rate Cuts</h3> <p class="card-excerpt">Major indices surge following coordinated announcements from Federal Reserve and ECB about upcoming policy adjustments in response to cooling inflation data.</p> <div class="card-meta"> <div class="time"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>2 hours ago</span> </div> <div class="source">Bloomberg</div> </div> </div> </div> <div class="card" data-category="tech"> <div class="animated-border"></div> <div class="pulse-dot"></div> <div class="card-inner"> <span class="card-tag">Technology</span> <h3 class="card-title">Quantum Computing Breakthrough Achieves 128 Qubit Stability</h3> <p class="card-excerpt">Researchers announce unprecedented quantum coherence time, marking a significant milestone toward practical quantum computing applications in cryptography and drug discovery.</p> <div class="card-meta"> <div class="time"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>35 minutes ago</span> </div> <div class="source">Wired</div> </div> </div> </div> <div class="card" data-category="politics"> <div class="animated-border"></div> <div class="pulse-dot"></div> <div class="card-inner"> <span class="card-tag">Politics</span> <h3 class="card-title">Senate Passes Landmark Climate Legislation with Bipartisan Support</h3> <p class="card-excerpt">Historic bill allocates $380 billion toward renewable energy infrastructure and establishes ambitious carbon reduction targets over the next decade.</p> <div class="card-meta"> <div class="time"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>4 hours ago</span> </div> <div class="source">Washington Post</div> </div> </div> </div> <div class="card" data-category="health"> <div class="animated-border"></div> <div class="pulse-dot"></div> <div class="card-inner"> <span class="card-tag">Health</span> <h3 class="card-title">New mRNA Vaccine Shows 93% Efficacy Against Multiple Cancer Types</h3> <p class="card-excerpt">Clinical trials reveal promising results for personalized immunotherapy approach that targets specific tumor mutations across breast, lung, and colorectal cancers.</p> <div class="card-meta"> <div class="time"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>Yesterday</span> </div> <div class="source">Nature Medicine</div> </div> </div> </div> <div class="card" data-category="science"> <div class="animated-border"></div> <div class="pulse-dot"></div> <div class="card-inner"> <span class="card-tag">Science</span> <h3 class="card-title">Webb Telescope Discovers Earth-like Exoplanet with Atmospheric Water</h3> <p class="card-excerpt">Astronomers identify habitable zone planet orbiting red dwarf star 40 light-years away with spectral signatures suggesting liquid water oceans and oxygen-rich atmosphere.</p> <div class="card-meta"> <div class="time"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>3 hours ago</span> </div> <div class="source">Science Daily</div> </div> </div> </div> <div class="card" data-category="tech"> <div class="animated-border"></div> <div class="pulse-dot"></div> <div class="card-inner"> <span class="card-tag">Technology</span> <h3 class="card-title">European AI Regulation Framework Comes Into Effect</h3> <p class="card-excerpt">Comprehensive legislation establishes tiered risk-based approach to AI governance, setting global precedent for ethical development and deployment of autonomous systems.</p> <div class="card-meta"> <div class="time"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> <span>7 hours ago</span> </div> <div class="source">TechCrunch</div> </div> </div> </div> </div> <div class="tooltip" id="tooltip"></div> <script> document.addEventListener('DOMContentLoaded', function() { const categoryButtons = document.querySelectorAll('.category'); const cards = document.querySelectorAll('.card'); const tooltip = document.getElementById('tooltip'); // Category filtering categoryButtons.forEach(button => { button.addEventListener('click', function() { // Update active state categoryButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); const category = this.getAttribute('data-category'); // Filter cards cards.forEach(card => { if (category === 'all' || card.getAttribute('data-category') === category) { card.style.display = 'block'; } else { card.style.display = 'none'; } }); }); }); // Custom tooltip functionality cards.forEach(card => { card.addEventListener('mousemove', function(e) { const cardRect = card.getBoundingClientRect(); const category = card.getAttribute('data-category'); let tooltipText; switch(category) { case 'business': tooltipText = 'Breaking financial news'; break; case 'tech': tooltipText = 'Latest in technology'; break; case 'politics': tooltipText = 'Current political developments'; break; case 'health': tooltipText = 'Health and wellness updates'; break; case 'science': tooltipText = 'Scientific discoveries'; break; default: tooltipText = 'News story'; } tooltip.textContent = tooltipText; tooltip.style.opacity = '1'; // Position tooltip above the card const tooltipX = e.clientX; const tooltipY = e.clientY - 40; // Position above cursor tooltip.style.left = `${tooltipX}px`; tooltip.style.top = `${tooltipY}px`; }); card.addEventListener('mouseleave', function() { tooltip.style.opacity = '0'; }); // Add click interaction card.addEventListener('click', function() { // Visual feedback on click card.style.transform = 'scale(0.98)'; setTimeout(() => { card.style.transform = ''; }, 200); // You could expand card details here instead of navigating away const title = card.querySelector('.card-title').textContent; console.log(`Reading: ${title}`); }); }); // Random animation offsets for more natural feel cards.forEach(card => { const border = card.querySelector('.animated-border'); const randomDelay = Math.random() * 0.5; border.style.animationDelay = `${randomDelay}s`; }); }); </script> </body> </html>
<html> <head> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 700px; width: 100%; max-width: 700px; margin: 0 auto; background-color: #0F0F1A; color: #FFFFFF; padding: 20px; } .container { width: 100%; max-width: 600px; text-align: center; } h1 { font-size: 2.2rem; margin-bottom: 25px; background: linear-gradient(90deg, #FF3E6C, #FF9E3E, #38CAFF); -webkit-background-clip: text; background-clip: text; color: transparent; font-weight: 800; } .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 20px; margin-top: 30px; } .thumbnail-container { position: relative; width: 100%; aspect-ratio: 16/9; border-radius: 10px; overflow: hidden; cursor: pointer; background: #1A1A2A; transition: transform 0.3s ease; } .thumbnail-container:hover { transform: scale(1.03); } .thumbnail { width: 100%; height: 100%; object-fit: cover; opacity: 0.85; transition: opacity 0.3s ease; } .thumbnail-container:hover .thumbnail { opacity: 1; } .loading-border { position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; pointer-events: none; border-radius: 12px; background: conic-gradient( from 0deg, transparent 0%, rgba(255, 62, 108, 0.8) 30%, rgba(255, 158, 62, 0.8) 60%, rgba(56, 202, 255, 0.8) 90%, transparent 100% ); animation: spin 2s linear infinite; opacity: 0; z-index: 1; } .active .loading-border { opacity: 1; } .content { position: absolute; inset: 4px; background: #1A1A2A; border-radius: 8px; z-index: 2; display: flex; flex-direction: column; justify-content: center; align-items: center; } .title { font-size: 1rem; margin-top: 10px; font-weight: 600; } .info { font-size: 0.85rem; color: #b4b4cc; margin-top: 5px; } .category { position: absolute; bottom: 10px; left: 10px; background: rgba(56, 202, 255, 0.3); color: #38CAFF; padding: 4px 8px; border-radius: 4px; font-size: 0.7rem; font-weight: 600; z-index: 3; } .play-icon { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 40px; height: 40px; background: rgba(255, 62, 108, 0.8); border-radius: 50%; z-index: 3; display: flex; justify-content: center; align-items: center; opacity: 0; transition: opacity 0.3s ease, transform 0.3s ease; } .thumbnail-container:hover .play-icon { opacity: 1; transform: translate(-50%, -50%) scale(1.1); } .play-icon::after { content: ''; width: 0; height: 0; border-top: 8px solid transparent; border-left: 14px solid white; border-bottom: 8px solid transparent; margin-left: 2px; } .progress-bar { position: absolute; bottom: 0; left: 0; height: 3px; background: linear-gradient(90deg, #FF3E6C, #FF9E3E); width: 0; z-index: 4; transition: width 0.2s linear; } .active .progress-bar { animation: progressAnimation 8s linear forwards; } .status { position: absolute; top: 10px; right: 10px; font-size: 0.75rem; padding: 4px 8px; border-radius: 20px; background: rgba(15, 15, 26, 0.7); z-index: 3; display: none; } .active .status { display: block; } .loading-pulse { display: inline-block; position: relative; width: 60px; text-align: center; font-weight: 600; } .loading-pulse::after { content: "●●●"; display: inline-block; animation: pulse 1.5s infinite; letter-spacing: 3px; } @keyframes pulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes progressAnimation { 0% { width: 0; } 100% { width: 100%; } } .controls { margin-top: 30px; display: flex; gap: 15px; justify-content: center; } button { background: #2A2A3A; border: none; color: white; padding: 10px 18px; border-radius: 6px; cursor: pointer; font-weight: 500; transition: all 0.3s ease; } button:hover { background: #3A3A4A; transform: translateY(-2px); } button.load-all { background: linear-gradient(90deg, #FF3E6C, #FF9E3E); color: white; } button.load-all:hover { box-shadow: 0 4px 12px rgba(255, 62, 108, 0.3); } @media (max-width: 500px) { h1 { font-size: 1.8rem; } .grid { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 15px; } .controls { flex-wrap: wrap; } } </style> </head> <body> <div class="container"> <h1>StreamFlow</h1> <p>Discover what's trending and ready to stream right now</p> <div class="grid"> <div class="thumbnail-container" data-title="Neon Riders" data-category="Sci-Fi"> <div class="loading-border"></div> <div class="content"> <img src="https://source.unsplash.com/random/400x225/?cyberpunk" alt="Neon Riders" class="thumbnail"> </div> <div class="category">Sci-Fi</div> <div class="play-icon"></div> <div class="progress-bar"></div> <div class="status"><span class="loading-pulse"></span></div> </div> <div class="thumbnail-container" data-title="Wild Journeys" data-category="Documentary"> <div class="loading-border"></div> <div class="content"> <img src="https://source.unsplash.com/random/400x225/?nature" alt="Wild Journeys" class="thumbnail"> </div> <div class="category">Documentary</div> <div class="play-icon"></div> <div class="progress-bar"></div> <div class="status"><span class="loading-pulse"></span></div> </div> <div class="thumbnail-container" data-title="Midnight Shadows" data-category="Horror"> <div class="loading-border"></div> <div class="content"> <img src="https://source.unsplash.com/random/400x225/?dark" alt="Midnight Shadows" class="thumbnail"> </div> <div class="category">Horror</div> <div class="play-icon"></div> <div class="progress-bar"></div> <div class="status"><span class="loading-pulse"></span></div> </div> <div class="thumbnail-container" data-title="Skyfall Chronicles" data-category="Action"> <div class="loading-border"></div> <div class="content"> <img src="https://source.unsplash.com/random/400x225/?action" alt="Skyfall Chronicles" class="thumbnail"> </div> <div class="category">Action</div> <div class="play-icon"></div> <div class="progress-bar"></div> <div class="status"><span class="loading-pulse"></span></div> </div> </div> <div class="controls"> <button class="load-random">Load Random</button> <button class="load-all">Load All Media</button> <button class="reset">Reset</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const thumbnails = document.querySelectorAll('.thumbnail-container'); const loadRandomBtn = document.querySelector('.load-random'); const loadAllBtn = document.querySelector('.load-all'); const resetBtn = document.querySelector('.reset'); // Function to simulate loading a single item function loadItem(item) { if (!item.classList.contains('active')) { item.classList.add('active'); // After loading completes (8 seconds as per the animation) setTimeout(() => { item.classList.remove('active'); }, 8000); } } // Load individual item on click thumbnails.forEach(item => { item.addEventListener('click', function() { loadItem(this); }); }); // Load a random item loadRandomBtn.addEventListener('click', function() { const randomIndex = Math.floor(Math.random() * thumbnails.length); loadItem(thumbnails[randomIndex]); }); // Load all items loadAllBtn.addEventListener('click', function() { thumbnails.forEach((item, index) => { // Stagger the start of each animation setTimeout(() => { loadItem(item); }, index * 300); }); }); // Reset all items resetBtn.addEventListener('click', function() { thumbnails.forEach(item => { item.classList.remove('active'); }); }); // Add hover effect that follows cursor position thumbnails.forEach(item => { item.addEventListener('mousemove', function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; // Update the conic gradient position const angle = Math.atan2(y - rect.height/2, x - rect.width/2) * (180 / Math.PI); if (!this.classList.contains('active')) { this.querySelector('.loading-border').style.background = `conic-gradient(from ${angle}deg, rgba(15, 15, 26, 0.5) 0%, rgba(255, 62, 108, 0.3) 30%, rgba(255, 158, 62, 0.3) 60%, rgba(56, 202, 255, 0.3) 90%, rgba(15, 15, 26, 0.5) 100%)`; } }); item.addEventListener('mouseleave', function() { if (!this.classList.contains('active')) { this.querySelector('.loading-border').style.background = ''; } }); }); // Add subtle auto-rotation to thumbnails that aren't being loaded setInterval(() => { thumbnails.forEach(item => { if (!item.classList.contains('active')) { const border = item.querySelector('.loading-border'); border.style.opacity = '0.2'; border.style.animation = 'spin 8s linear infinite'; } }); }, 1000); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', 'Helvetica Neue', sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: linear-gradient(135deg, #2c3e50, #1a1a2e); padding: 20px; overflow-x: hidden; } .container { max-width: 700px; width: 100%; height: 600px; display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 30px; padding: 20px; perspective: 1000px; } .product-card { position: relative; background: rgba(255, 255, 255, 0.03); border-radius: 12px; overflow: hidden; transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1); cursor: pointer; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); display: flex; flex-direction: column; transform-style: preserve-3d; padding: 5px; } .product-card:hover { transform: translateY(-10px) rotateX(3deg); z-index: 10; } .border-animation { position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 12px; z-index: -1; opacity: 0; transition: opacity 0.3s ease; background: linear-gradient(45deg, transparent 5%, #d4af37 5%, #d4af37 10%, transparent 10%, transparent 20%, #d4af37 20%, #d4af37 25%, transparent 25%, transparent 35%, #d4af37 35%, #d4af37 40%, transparent 40%, transparent 50%, #d4af37 50%, #d4af37 55%, transparent 55%, transparent 65%, #d4af37 65%, #d4af37 70%, transparent 70%, transparent 80%, #d4af37 80%, #d4af37 85%, transparent 85%, transparent 95%, #d4af37 95%, #d4af37 100%); background-size: 200% 200%; animation: gradientBorder 3s linear infinite; filter: drop-shadow(0 0 10px rgba(212, 175, 55, 0.5)); } .product-card:hover .border-animation { opacity: 1; } @keyframes gradientBorder { 0% { background-position: 0% 0%; } 100% { background-position: 200% 200%; } } .product-image-container { position: relative; height: 180px; width: 100%; overflow: hidden; border-radius: 8px; background: #0a0a0a; display: flex; justify-content: center; align-items: center; border: 1px solid rgba(212, 175, 55, 0.1); } .product-image { height: 100%; width: 100%; object-fit: cover; transition: transform 0.6s ease; transform-origin: center; } .product-card:hover .product-image { transform: scale(1.1); } .product-details { padding: 15px 10px; flex-grow: 1; display: flex; flex-direction: column; justify-content: space-between; background: rgba(0, 0, 0, 0.2); border-radius: 0 0 8px 8px; } .product-title { color: #FFFFFF; font-size: 16px; font-weight: 600; margin-bottom: 8px; letter-spacing: 0.5px; line-height: 1.3; } .product-description { color: rgba(255, 255, 255, 0.7); font-size: 12px; margin-bottom: 12px; line-height: 1.5; } .price-container { display: flex; justify-content: space-between; align-items: center; margin-top: auto; } .product-price { color: #d4af37; font-size: 18px; font-weight: 700; text-shadow: 0 0 10px rgba(212, 175, 55, 0.4); } .add-to-cart { background: linear-gradient(45deg, #a67c00, #d4af37, #f4e5b5, #d4af37); background-size: 300% 300%; animation: gradientButton 6s ease infinite; color: #000; border: none; border-radius: 30px; padding: 8px 15px; font-size: 11px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; letter-spacing: 0.5px; box-shadow: 0 5px 15px rgba(212, 175, 55, 0.3); text-transform: uppercase; } .add-to-cart:hover { box-shadow: 0 10px 20px rgba(212, 175, 55, 0.5); transform: translateY(-2px); } @keyframes gradientButton { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } .tag { position: absolute; top: 10px; right: 10px; background: #d4af37; color: #000; font-size: 10px; font-weight: 700; padding: 4px 8px; border-radius: 20px; z-index: 10; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3); transform: rotate(5deg); letter-spacing: 0.5px; } .premium-badge { position: absolute; bottom: 40px; left: -15px; background: #d4af37; color: #000; font-size: 9px; font-weight: 700; padding: 2px 12px; transform: rotate(-45deg); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2); z-index: 5; text-transform: uppercase; letter-spacing: 1px; } .glow-effect { position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 12px; background: radial-gradient(circle at var(--x) var(--y), rgba(212, 175, 55, 0.2) 0%, transparent 60%); opacity: 0; pointer-events: none; transition: opacity 0.3s ease; z-index: -1; } .product-card:hover .glow-effect { opacity: 1; } .header { grid-column: 1 / 3; text-align: center; position: relative; } .title { font-size: 24px; font-weight: 800; color: white; margin-bottom: 5px; letter-spacing: 1px; position: relative; display: inline-block; } .title::after { content: ''; position: absolute; bottom: -8px; left: 50%; transform: translateX(-50%); width: 60px; height: 3px; background: linear-gradient(90deg, transparent, #d4af37, transparent); } .subtitle { font-size: 14px; color: rgba(255, 255, 255, 0.6); margin-bottom: 20px; } @media (max-width: 600px) { .container { grid-template-columns: 1fr; height: auto; } .header { grid-column: 1; } .product-card { margin-bottom: 20px; } } .product-grid { grid-column: 1 / 3; display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 30px; } @media (max-width: 600px) { .product-grid { grid-template-columns: 1fr; grid-column: 1; } } /* Product Hover Animation */ .product-card::before { content: ''; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; z-index: -2; border-radius: 16px; background: linear-gradient(45deg, #d4af37, transparent, #a67c00, transparent, #d4af37); background-size: 400%; opacity: 0; transition: opacity 0.6s ease; } .product-card:hover::before { opacity: 1; animation: animateBorder 3s linear infinite; } @keyframes animateBorder { 0% { background-position: 0%; } 100% { background-position: 300%; } } </style> </head> <body> <div class="container"> <div class="header"> <h1 class="title">Luxe Essentials</h1> <p class="subtitle">Discover our handpicked premium collection</p> </div> <div class="product-grid"> <div class="product-card"> <div class="tag">NEW</div> <div class="border-animation"></div> <div class="glow-effect"></div> <div class="product-image-container"> <img class="product-image" src="https://images.unsplash.com/photo-1523275335684-37898b6baf30?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Premium Watch"> </div> <div class="product-details"> <h3 class="product-title">Chronomaster Elite Watch</h3> <p class="product-description">Swiss-made precision timepiece with genuine leather band and sapphire crystal face.</p> <div class="price-container"> <span class="product-price">$1,299</span> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="product-card"> <div class="tag">BESTSELLER</div> <div class="premium-badge">Premium</div> <div class="border-animation"></div> <div class="glow-effect"></div> <div class="product-image-container"> <img class="product-image" src="https://images.unsplash.com/photo-1491897554428-130a60dd4757?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Luxury Headphones"> </div> <div class="product-details"> <h3 class="product-title">Audiophile X7 Headphones</h3> <p class="product-description">Handcrafted with lambskin ear cushions and 24K gold-plated connectors for audiophiles.</p> <div class="price-container"> <span class="product-price">$849</span> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="product-card"> <div class="tag">LIMITED</div> <div class="border-animation"></div> <div class="glow-effect"></div> <div class="product-image-container"> <img class="product-image" src="https://images.unsplash.com/photo-1547949003-9792a18a2601?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Luxury Perfume"> </div> <div class="product-details"> <h3 class="product-title">Midnight Ember Parfum</h3> <p class="product-description">Exclusive fragrance with notes of rare Moroccan amber and Japanese yuzu.</p> <div class="price-container"> <span class="product-price">$329</span> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> <div class="product-card"> <div class="premium-badge">Exclusive</div> <div class="border-animation"></div> <div class="glow-effect"></div> <div class="product-image-container"> <img class="product-image" src="https://images.unsplash.com/photo-1560343090-f0409e92791a?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Designer Sunglasses"> </div> <div class="product-details"> <h3 class="product-title">Riviera Elite Sunglasses</h3> <p class="product-description">Italian-crafted frames with polarized lenses and 24K gold accents.</p> <div class="price-container"> <span class="product-price">$549</span> <button class="add-to-cart">Add to Cart</button> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const cards = document.querySelectorAll('.product-card'); cards.forEach(card => { const glowEffect = card.querySelector('.glow-effect'); card.addEventListener('mousemove', function(e) { const rect = card.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; glowEffect.style.setProperty('--x', `${x}px`); glowEffect.style.setProperty('--y', `${y}px`); }); card.addEventListener('click', function(e) { if (e.target.classList.contains('add-to-cart')) { e.preventDefault(); e.stopPropagation(); const button = e.target; const originalText = button.textContent; button.textContent = 'Added ✓'; button.style.background = '#27ae60'; setTimeout(() => { button.textContent = originalText; button.style.background = ''; }, 1500); } }); // Create ripple effect when clicking on the card card.addEventListener('mousedown', function(e) { if (!e.target.classList.contains('add-to-cart')) { const rect = card.getBoundingClientRect(); const ripple = document.createElement('div'); ripple.style.position = 'absolute'; ripple.style.width = '10px'; ripple.style.height = '10px'; ripple.style.borderRadius = '50%'; ripple.style.backgroundColor = 'rgba(212, 175, 55, 0.4)'; ripple.style.left = (e.clientX - rect.left) + 'px'; ripple.style.top = (e.clientY - rect.top) + 'px'; ripple.style.transform = 'scale(0)'; ripple.style.transition = 'transform 0.6s, opacity 0.6s'; ripple.style.pointerEvents = 'none'; card.appendChild(ripple); setTimeout(() => { ripple.style.transform = 'scale(20)'; ripple.style.opacity = '0'; setTimeout(() => { ripple.remove(); }, 600); }, 10); } }); }); }); </script> </body> </html>
<html> <head> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f8f9fa; overflow-x: hidden; } .site-container { width: 100%; max-width: 700px; height: 700px; display: flex; flex-direction: column; background-color: #ffffff; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.05); border-radius: 8px; overflow: hidden; } header { padding: 25px 40px; display: flex; justify-content: space-between; align-items: center; background-color: #fff; border-bottom: 1px solid rgba(0, 0, 0, 0.06); } .logo { display: flex; align-items: center; font-weight: 600; font-size: 1.4rem; color: #333; } .logo-icon { width: 28px; height: 28px; margin-right: 10px; background-color: #1D59F2; border-radius: 6px; position: relative; overflow: hidden; } .logo-icon::before { content: ""; position: absolute; width: 16px; height: 16px; background-color: white; border-radius: 50%; top: 6px; left: 6px; } .nav-container { position: relative; } .nav-menu { display: flex; list-style-type: none; gap: 32px; } .nav-item { position: relative; cursor: pointer; } .nav-link { color: #333; font-size: 16px; font-weight: 500; text-decoration: none; padding: 8px 0; display: inline-block; transition: color 0.3s ease; } .nav-link:hover { color: #1D59F2; } .nav-item::after { content: ''; position: absolute; width: 0; height: 2px; bottom: 0; left: 0; background-color: #1D59F2; transition: width 0.4s cubic-bezier(0.16, 1, 0.3, 1); transform-origin: left; } .nav-item:hover::after { width: 100%; } .content { flex: 1; padding: 40px; display: flex; flex-direction: column; justify-content: center; align-items: center; background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); } .hero { text-align: center; max-width: 600px; } h1 { font-size: 2.4rem; color: #222; margin-bottom: 16px; line-height: 1.2; } .highlight { color: #1D59F2; position: relative; } .highlight::after { content: ""; position: absolute; height: 6px; width: 100%; bottom: 4px; left: 0; background-color: rgba(29, 89, 242, 0.1); z-index: -1; } p.subtitle { color: #666; font-size: 1.1rem; line-height: 1.6; margin-bottom: 32px; } .cta-button { background-color: #1D59F2; color: white; border: none; padding: 14px 36px; border-radius: 30px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 6px 20px rgba(29, 89, 242, 0.2); position: relative; overflow: hidden; } .cta-button:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(29, 89, 242, 0.3); } .cta-button::after { content: ""; position: absolute; top: 50%; left: 50%; width: 150px; height: 150px; background: rgba(255, 255, 255, 0.1); border-radius: 50%; transform: translate(-50%, -50%) scale(0); transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1); } .cta-button:hover::after { transform: translate(-50%, -50%) scale(1); } .dropdown-content { display: none; position: absolute; min-width: 180px; background-color: white; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); border-radius: 6px; z-index: 10; top: 40px; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity 0.3s ease, transform 0.3s ease; padding: 12px 0; } .nav-item:hover .dropdown-content { display: block; opacity: 1; } .dropdown-content a { display: block; padding: 10px 20px; color: #333; text-decoration: none; transition: all 0.2s ease; font-size: 15px; } .dropdown-content a:hover { background-color: rgba(29, 89, 242, 0.05); color: #1D59F2; padding-left: 24px; } .dropdown-content::before { content: ""; position: absolute; top: -6px; left: 50%; transform: translateX(-50%); width: 12px; height: 12px; background-color: white; transform-origin: center; transform: translateX(-50%) rotate(45deg); } .mobile-menu-button { display: none; background: none; border: none; cursor: pointer; padding: 8px; } .line { display: block; width: 24px; height: 2px; background-color: #333; margin: 5px 0; transition: all 0.3s ease; } /* Responsive adjustments */ @media (max-width: 768px) { .mobile-menu-button { display: block; } .nav-menu { position: absolute; flex-direction: column; background-color: white; top: 60px; right: 0; width: 240px; gap: 0; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); border-radius: 8px; padding: 20px 0; transform: translateX(100%); transition: transform 0.3s ease; z-index: 100; } .nav-menu.active { transform: translateX(0); } .nav-item { width: 100%; padding: 0 20px; } .nav-link { width: 100%; padding: 15px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .dropdown-content { position: static; box-shadow: none; transform: none; padding: 0 0 10px 20px; margin-top: -5px; background: transparent; } .dropdown-content::before { display: none; } h1 { font-size: 2rem; } p.subtitle { font-size: 1rem; } .content { padding: 30px 20px; } } /* Thematic elements for corporate feel */ .decorative-circle { position: absolute; background-color: rgba(29, 89, 242, 0.03); border-radius: 50%; } .circle1 { width: 300px; height: 300px; bottom: -150px; right: -100px; } .circle2 { width: 200px; height: 200px; top: -80px; left: -100px; } </style> </head> <body> <div class="site-container"> <header> <div class="logo"> <div class="logo-icon"></div> Nexify </div> <nav class="nav-container"> <ul class="nav-menu"> <li class="nav-item"> <a href="#" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="#" class="nav-link">Solutions</a> <div class="dropdown-content"> <a href="#">Digital Transformation</a> <a href="#">Cloud Services</a> <a href="#">Enterprise AI</a> <a href="#">Data Analytics</a> </div> </li> <li class="nav-item"> <a href="#" class="nav-link">Products</a> <div class="dropdown-content"> <a href="#">Nexify Platform</a> <a href="#">Analytics Suite</a> <a href="#">Secure Connect</a> <a href="#">CloudSync Pro</a> </div> </li> <li class="nav-item"> <a href="#" class="nav-link">About</a> </li> <li class="nav-item"> <a href="#" class="nav-link">Contact</a> </li> </ul> <button class="mobile-menu-button"> <span class="line"></span> <span class="line"></span> <span class="line"></span> </button> </nav> </header> <div class="content"> <div class="decorative-circle circle1"></div> <div class="decorative-circle circle2"></div> <div class="hero"> <h1>Transform your business with <span class="highlight">intelligent solutions</span></h1> <p class="subtitle">Enterprise-grade technology that scales with your business, providing actionable insights and streamlining operations across your organization.</p> <button class="cta-button">Schedule a Demo</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Mobile menu toggle const mobileMenuButton = document.querySelector('.mobile-menu-button'); const navMenu = document.querySelector('.nav-menu'); mobileMenuButton.addEventListener('click', function() { navMenu.classList.toggle('active'); // Animate burger menu lines const lines = document.querySelectorAll('.line'); lines.forEach(line => line.classList.toggle('active')); if (navMenu.classList.contains('active')) { lines[0].style.transform = 'rotate(45deg) translate(5px, 5px)'; lines[1].style.opacity = '0'; lines[2].style.transform = 'rotate(-45deg) translate(7px, -6px)'; } else { lines[0].style.transform = 'none'; lines[1].style.opacity = '1'; lines[2].style.transform = 'none'; } }); // Enhanced hover animation for nav items const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('mouseenter', function() { const line = document.createElement('div'); line.style.position = 'absolute'; line.style.height = '2px'; line.style.width = '0'; line.style.bottom = '0'; line.style.left = '0'; line.style.backgroundColor = '#1D59F2'; line.style.transition = 'width 0.4s cubic-bezier(0.16, 1, 0.3, 1)'; // Remove existing line if any const existingLine = item.querySelector('.animated-line'); if (existingLine) { item.removeChild(existingLine); } line.classList.add('animated-line'); item.appendChild(line); // Trigger animation setTimeout(() => { line.style.width = '100%'; }, 10); }); item.addEventListener('mouseleave', function() { const line = item.querySelector('.animated-line'); if (line) { line.style.width = '0'; line.style.right = '0'; line.style.left = 'auto'; line.style.transformOrigin = 'right'; // Remove line after animation completes setTimeout(() => { if (line.parentNode === item) { item.removeChild(line); } }, 400); } }); }); // Prevent form submission, page refreshes on buttons/links document.querySelectorAll('a, button').forEach(element => { element.addEventListener('click', function(e) { e.preventDefault(); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --neon-pink: #ff00ff; --neon-blue: #00ffff; --neon-purple: #9d4edd; --neon-green: #39ff14; --neon-yellow: #ffff00; --dark-bg: #12121f; --badge-size: 120px; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--dark-bg); min-height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; padding: 20px; } .container { width: 100%; max-width: 700px; padding: 2rem; color: white; } h1 { font-size: 2.5rem; background: linear-gradient(to right, var(--neon-blue), var(--neon-purple)); -webkit-background-clip: text; background-clip: text; color: transparent; text-align: center; margin-bottom: 1.5rem; letter-spacing: 1px; text-transform: uppercase; font-weight: 800; text-shadow: 0 0 10px rgba(157, 78, 221, 0.5); } .subtitle { text-align: center; margin-bottom: 2rem; color: #ccc; font-weight: 300; font-size: 1.1rem; } .badges-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(var(--badge-size), 1fr)); gap: 2rem; justify-items: center; margin-top: 2rem; } .badge { position: relative; width: var(--badge-size); height: var(--badge-size); border-radius: 50%; background-color: #1f1f2f; display: flex; flex-direction: column; align-items: center; justify-content: center; cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); overflow: hidden; } .badge::before { content: ''; position: absolute; inset: -2px; background: conic-gradient(transparent, transparent, transparent, var(--badge-color)); border-radius: 50%; z-index: -1; opacity: 0; transition: opacity 0.3s ease; } .badge-icon { font-size: 2.5rem; margin-bottom: 0.5rem; color: var(--badge-color); transition: transform 0.3s ease, filter 0.3s ease; } .badge-title { font-size: 0.8rem; font-weight: bold; text-align: center; color: #fff; padding: 0 0.5rem; transition: transform 0.3s ease; } .badge-level { font-size: 0.7rem; color: var(--badge-color); margin-top: 0.2rem; font-weight: 600; transition: transform 0.3s ease; } /* Badge border animation and effects */ .badge::after { content: ''; position: absolute; inset: -4px; background: conic-gradient(var(--badge-color), transparent 120deg, var(--badge-color) 180deg); border-radius: 50%; animation: rotateBorder 5s linear infinite; z-index: -1; opacity: 0; transition: opacity 0.4s ease; } .badge:hover, .badge.active { transform: scale(1.1); box-shadow: 0 0 30px var(--badge-color); } .badge:hover::before, .badge.active::before { opacity: 0.5; animation: pulse 2s infinite; } .badge:hover::after, .badge.active::after { opacity: 1; } .badge:hover .badge-icon, .badge.active .badge-icon { transform: scale(1.2); filter: drop-shadow(0 0 5px var(--badge-color)); } .badge:hover .badge-title, .badge.active .badge-title { transform: translateY(-2px); } .badge:hover .badge-level, .badge.active .badge-level { transform: translateY(-2px); } /* Starburst effect */ .starburst { position: absolute; width: 100%; height: 100%; pointer-events: none; z-index: 10; opacity: 0; mix-blend-mode: screen; } .starburst span { position: absolute; top: 50%; left: 50%; width: 4px; height: 4px; background: var(--badge-color); border-radius: 50%; box-shadow: 0 0 10px var(--badge-color), 0 0 20px var(--badge-color); opacity: 0; transform-origin: center; } .badge-explorer { --badge-color: var(--neon-blue); } .badge-genius { --badge-color: var(--neon-purple); } .badge-challenger { --badge-color: var(--neon-green); } .badge-innovator { --badge-color: var(--neon-pink); } .badge-legend { --badge-color: var(--neon-yellow); } /* Progress bar underneath each badge */ .progress-container { width: 80%; height: 8px; background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; margin-top: 10px; overflow: hidden; } .progress-bar { height: 100%; background-color: var(--badge-color); border-radius: 4px; transition: width 0.5s ease; } @keyframes rotateBorder { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.8; } } @keyframes fadeIn { from { opacity: 0; transform: scale(0.8); } to { opacity: 1; transform: scale(1); } } .badge { animation: fadeIn 0.5s ease forwards; animation-delay: calc(var(--index) * 0.1s); opacity: 0; } @media (max-width: 600px) { h1 { font-size: 2rem; } .badges-container { grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 1.5rem; } :root { --badge-size: 100px; } .badge-icon { font-size: 2rem; } .badge-title { font-size: 0.7rem; } } /* Background particles */ .particles { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: -10; } .particle { position: absolute; width: 3px; height: 3px; background-color: rgba(255, 255, 255, 0.5); border-radius: 50%; } </style> </head> <body> <div class="particles" id="particles"></div> <div class="container"> <h1>Achievement Nexus</h1> <p class="subtitle">Level up your skills and unlock your potential with each achievement</p> <div class="badges-container"> <div class="badge badge-explorer" style="--index: 1;"> <div class="badge-icon">🧭</div> <div class="badge-title">Explorer</div> <div class="badge-level">Level 3</div> <div class="progress-container"> <div class="progress-bar" style="width: 60%;"></div> </div> <div class="starburst"></div> </div> <div class="badge badge-genius" style="--index: 2;"> <div class="badge-icon">💡</div> <div class="badge-title">Code Genius</div> <div class="badge-level">Level 2</div> <div class="progress-container"> <div class="progress-bar" style="width: 40%;"></div> </div> <div class="starburst"></div> </div> <div class="badge badge-challenger" style="--index: 3;"> <div class="badge-icon">🏆</div> <div class="badge-title">Challenger</div> <div class="badge-level">Level 5</div> <div class="progress-container"> <div class="progress-bar" style="width: 100%;"></div> </div> <div class="starburst"></div> </div> <div class="badge badge-innovator" style="--index: 4;"> <div class="badge-icon">🚀</div> <div class="badge-title">Innovator</div> <div class="badge-level">Level 1</div> <div class="progress-container"> <div class="progress-bar" style="width: 20%;"></div> </div> <div class="starburst"></div> </div> <div class="badge badge-legend" style="--index: 5;"> <div class="badge-icon">⭐</div> <div class="badge-title">Legend</div> <div class="badge-level">Level 4</div> <div class="progress-container"> <div class="progress-bar" style="width: 80%;"></div> </div> <div class="starburst"></div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const badges = document.querySelectorAll('.badge'); // Create starburst effects badges.forEach(badge => { const starburst = badge.querySelector('.starburst'); // Create 24 rays for starburst for (let i = 0; i < 24; i++) { const ray = document.createElement('span'); const angle = (i * 15) * Math.PI / 180; const distance = Math.random() * 60 + 40; ray.style.transform = `translate(-50%, -50%) rotate(${i * 15}deg) translateY(-${distance}px)`; starburst.appendChild(ray); } // Add click and hover event listeners badge.addEventListener('click', () => { toggleActiveBadge(badge); triggerStarburst(badge); }); badge.addEventListener('mouseenter', () => { if (!badge.classList.contains('active')) { triggerStarburst(badge); } }); }); function toggleActiveBadge(badge) { badge.classList.toggle('active'); } function triggerStarburst(badge) { const starburst = badge.querySelector('.starburst'); const rays = starburst.querySelectorAll('span'); starburst.style.opacity = '1'; rays.forEach((ray, index) => { ray.style.animation = 'none'; ray.offsetHeight; // Force reflow ray.style.animation = `shootRay 0.8s ease-out ${index * 0.03}s`; }); setTimeout(() => { starburst.style.opacity = '0'; }, 800); } // Create CSS animation for rays const style = document.createElement('style'); style.textContent = ` @keyframes shootRay { 0% { opacity: 1; transform: translate(-50%, -50%) rotate(var(--angle)) translateY(0); } 70% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%, -50%) rotate(var(--angle)) translateY(-80px); } } `; document.head.appendChild(style); // Initialize ray angles const rays = document.querySelectorAll('.starburst span'); rays.forEach((ray, index) => { const angle = (index * 15); ray.style.setProperty('--angle', `${angle}deg`); }); // Create background particles createBackgroundParticles(); }); function createBackgroundParticles() { const particlesContainer = document.getElementById('particles'); const numberOfParticles = 50; for (let i = 0; i < numberOfParticles; i++) { const particle = document.createElement('div'); particle.classList.add('particle'); // Random position const posX = Math.random() * 100; const posY = Math.random() * 100; // Random size const size = Math.random() * 2 + 1; // Random opacity const opacity = Math.random() * 0.5 + 0.1; // Random color const colors = ['#ff00ff33', '#00ffff33', '#9d4edd33', '#39ff1433', '#ffff0033']; const color = colors[Math.floor(Math.random() * colors.length)]; particle.style.left = `${posX}%`; particle.style.top = `${posY}%`; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.opacity = opacity; particle.style.backgroundColor = color; // Add animation particle.style.animation = `floatParticle ${Math.random() * 20 + 10}s linear infinite`; particle.style.animationDelay = `${Math.random() * 10}s`; particlesContainer.appendChild(particle); } // Create CSS animation for particles const style = document.createElement('style'); style.textContent = ` @keyframes floatParticle { 0% { transform: translate(0, 0); } 25% { transform: translate(${Math.random() * 30 - 15}px, ${Math.random() * 30 - 15}px); } 50% { transform: translate(${Math.random() * 30 - 15}px, ${Math.random() * 30 - 15}px); } 75% { transform: translate(${Math.random() * 30 - 15}px, ${Math.random() * 30 - 15}px); } 100% { transform: translate(0, 0); } } `; document.head.appendChild(style); } </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Focus Flow - Smart Productivity Sidepanel</title> <style> :root { --primary-color: #6c5ce7; --secondary-color: #a29bfe; --tertiary-color: #81ecec; --text-color: #2d3436; --light-color: #f8f9fa; --panel-width: 230px; --main-width: calc(100% - var(--panel-width)); --pulse-animation-duration: 2.5s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; height: 700px; width: 700px; background-color: var(--light-color); color: var(--text-color); overflow: hidden; position: relative; } .sidebar { width: var(--panel-width); height: 100%; background-color: #ffffff; box-shadow: 0 0 15px rgba(0, 0, 0, 0.05); display: flex; flex-direction: column; overflow: hidden; position: relative; transition: width 0.3s ease-in-out; } .sidebar-header { padding: 20px 15px; display: flex; align-items: center; justify-content: space-between; background-color: #ffffff; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .logo { display: flex; align-items: center; gap: 10px; font-weight: 600; font-size: 18px; color: var(--primary-color); } .logo svg { width: 24px; height: 24px; } .menu-toggle { background: none; border: none; cursor: pointer; color: var(--text-color); opacity: 0.6; transition: opacity 0.2s; } .menu-toggle:hover { opacity: 1; } .sidebar-menu { padding: 15px 0; flex-grow: 1; overflow-y: auto; } .menu-item { padding: 12px 20px; display: flex; align-items: center; gap: 12px; cursor: pointer; position: relative; margin: 4px 8px; border-radius: 8px; transition: background-color 0.2s; overflow: hidden; } .menu-item:hover { background-color: rgba(108, 92, 231, 0.06); } .menu-item.active { background-color: rgba(108, 92, 231, 0.1); font-weight: 500; } .menu-item.active::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background-color: var(--primary-color); animation: pulseBorder var(--pulse-animation-duration) infinite alternate; } @keyframes pulseBorder { 0% { box-shadow: 0 0 0 0 rgba(108, 92, 231, 0.7); background-color: var(--primary-color); } 50% { background-color: var(--secondary-color); } 100% { box-shadow: 0 0 0 10px rgba(108, 92, 231, 0); background-color: var(--tertiary-color); } } .menu-item i { width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; color: var(--text-color); opacity: 0.7; } .menu-item.active i { color: var(--primary-color); opacity: 1; } .menu-label { flex-grow: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .menu-badge { background-color: var(--tertiary-color); color: var(--text-color); font-size: 11px; padding: 2px 6px; border-radius: 10px; font-weight: 500; } .category-label { padding: 16px 20px 8px; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #9ba0a6; font-weight: 600; } .content-area { flex-grow: 1; padding: 30px; overflow-y: auto; background-color: var(--light-color); position: relative; } .content-header { margin-bottom: 25px; } .content-header h1 { font-size: 24px; margin-bottom: 10px; color: var(--text-color); } .content-header p { color: #666; line-height: 1.5; } .card { background-color: white; border-radius: 10px; padding: 20px; margin-bottom: 20px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); transition: transform 0.2s, box-shadow 0.2s; } .card:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08); } .card-title { margin-bottom: 15px; font-size: 18px; display: flex; align-items: center; gap: 10px; } .card-title i { color: var(--primary-color); } .task-item { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .task-item:last-child { border-bottom: none; } .task-checkbox { width: 18px; height: 18px; border-radius: 4px; border: 2px solid var(--secondary-color); display: flex; align-items: center; justify-content: center; cursor: pointer; position: relative; transition: background-color 0.2s, border-color 0.2s; } .task-checkbox.checked { background-color: var(--primary-color); border-color: var(--primary-color); } .task-checkbox.checked::after { content: "✓"; color: white; font-size: 12px; position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; } .task-text { flex-grow: 1; transition: opacity 0.2s; } .task-checkbox.checked + .task-text { text-decoration: line-through; opacity: 0.6; } .task-priority { font-size: 12px; padding: 3px 8px; border-radius: 4px; font-weight: 500; } .priority-high { background-color: rgba(255, 107, 107, 0.15); color: #ff6b6b; } .priority-medium { background-color: rgba(250, 176, 5, 0.15); color: #fab005; } .priority-low { background-color: rgba(46, 204, 113, 0.15); color: #2ecc71; } .progress-chart { width: 100%; height: 10px; background-color: rgba(0, 0, 0, 0.05); border-radius: 5px; overflow: hidden; margin-top: 20px; } .progress-bar { height: 100%; background-color: var(--primary-color); width: 65%; border-radius: 5px; position: relative; overflow: hidden; } .progress-bar::after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient( 90deg, transparent, rgba(255, 255, 255, 0.4), transparent ); animation: progressShimmer 2s infinite; } @keyframes progressShimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } .progress-label { display: flex; justify-content: space-between; margin-top: 8px; font-size: 13px; color: #666; } .stats-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-top: 15px; } .stat-item { background-color: rgba(108, 92, 231, 0.06); padding: 15px; border-radius: 8px; transition: transform 0.2s; } .stat-item:hover { transform: translateY(-2px); } .stat-number { font-size: 24px; font-weight: 600; color: var(--primary-color); margin-bottom: 5px; } .stat-label { font-size: 13px; color: #666; } .sidebar-footer { padding: 15px; border-top: 1px solid rgba(0, 0, 0, 0.05); display: flex; align-items: center; gap: 10px; } .user-avatar { width: 32px; height: 32px; border-radius: 50%; background-color: var(--secondary-color); display: flex; align-items: center; justify-content: center; color: white; font-weight: 500; font-size: 14px; } .user-info { flex-grow: 1; overflow: hidden; } .user-name { font-weight: 500; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .user-role { font-size: 12px; color: #666; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .user-menu { cursor: pointer; opacity: 0.6; transition: opacity 0.2s; } .user-menu:hover { opacity: 1; } /* Responsive adjustments */ @media (max-width: 700px) { .sidebar { width: 70px; } .menu-label, .menu-badge, .logo span, .category-label, .user-info { display: none; } .sidebar-header { justify-content: center; padding: 15px 0; } .menu-toggle { display: none; } .menu-item { justify-content: center; padding: 12px; } .menu-item.active::before { width: 3px; } .sidebar-footer { justify-content: center; padding: 15px 0; } .user-menu { display: none; } .content-area { width: calc(100% - 70px); } } /* Special animations */ .wave-effect { position: relative; overflow: hidden; } .wave-effect:after { content: ""; display: block; position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; background-image: radial-gradient(circle, #fff 10%, transparent 10.01%); background-repeat: no-repeat; background-position: 50%; transform: scale(10, 10); opacity: 0; transition: transform 0.5s, opacity 1s; } .wave-effect:active:after { transform: scale(0, 0); opacity: 0.3; transition: 0s; } .menu-item.active .sparkle { position: absolute; background: rgba(255, 255, 255, 0.7); border-radius: 50%; width: 3px; height: 3px; pointer-events: none; z-index: 2; opacity: 0; } /* Status indicator pulse */ .status-indicator { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background-color: #2ecc71; position: relative; margin-left: 6px; } .status-indicator::before { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: #2ecc71; opacity: 0.5; animation: pulse 2s infinite; top: 0; left: 0; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.5; } 70% { transform: scale(2); opacity: 0; } 100% { transform: scale(1); opacity: 0; } } /* Collapsed sidebar styles */ .sidebar.collapsed { width: 70px; } .sidebar.collapsed .menu-label, .sidebar.collapsed .menu-badge, .sidebar.collapsed .logo span, .sidebar.collapsed .category-label, .sidebar.collapsed .user-info { display: none; } .sidebar.collapsed .sidebar-header { justify-content: center; padding: 15px 0; } .sidebar.collapsed .menu-toggle { display: none; } .sidebar.collapsed .menu-item { justify-content: center; padding: 12px; } .sidebar.collapsed .sidebar-footer { justify-content: center; padding: 15px 0; } .sidebar.collapsed .user-menu { display: none; } </style> </head> <body> <div class="sidebar"> <div class="sidebar-header"> <div class="logo"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20 7H4C2.89543 7 2 7.89543 2 9V19C2 20.1046 2.89543 21 4 21H20C21.1046 21 22 20.1046 22 19V9C22 7.89543 21.1046 7 20 7Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M16 21V5C16 3.89543 15.1046 3 14 3H10C8.89543 3 8 3.89543 8 5V21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> <span>FocusFlow</span> </div> <button class="menu-toggle"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="3" y1="12" x2="21" y2="12"></line> <line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="18" x2="21" y2="18"></line> </svg> </button> </div> <div class="sidebar-menu"> <div class="category-label">Workspace</div> <div class="menu-item wave-effect active" data-menu="dashboard"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="3" width="7" height="7"></rect> <rect x="14" y="3" width="7" height="7"></rect> <rect x="14" y="14" width="7" height="7"></rect> <rect x="3" y="14" width="7" height="7"></rect> </svg> </i> <span class="menu-label">Dashboard</span> </div> <div class="menu-item wave-effect" data-menu="tasks"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M9 11l3 3L22 4"></path> <path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"></path> </svg> </i> <span class="menu-label">Tasks</span> <span class="menu-badge">5</span> </div> <div class="menu-item wave-effect" data-menu="calendar"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect> <line x1="16" y1="2" x2="16" y2="6"></line> <line x1="8" y1="2" x2="8" y2="6"></line> <line x1="3" y1="10" x2="21" y2="10"></line> </svg> </i> <span class="menu-label">Calendar</span> </div> <div class="menu-item wave-effect" data-menu="notes"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> </i> <span class="menu-label">Notes</span> </div> <div class="category-label">Insights</div> <div class="menu-item wave-effect" data-menu="analytics"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="18" y1="20" x2="18" y2="10"></line> <line x1="12" y1="20" x2="12" y2="4"></line> <line x1="6" y1="20" x2="6" y2="14"></line> </svg> </i> <span class="menu-label">Analytics</span> </div> <div class="menu-item wave-effect" data-menu="reports"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21.21 15.89A10 10 0 1 1 8 2.83"></path> <path d="M22 12A10 10 0 0 0 12 2v10z"></path> </svg> </i> <span class="menu-label">Reports</span> </div> <div class="category-label">Settings</div> <div class="menu-item wave-effect" data-menu="preferences"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="3"></circle> <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path> </svg> </i> <span class="menu-label">Preferences</span> </div> </div> <div class="sidebar-footer"> <div class="user-avatar">AJ</div> <div class="user-info"> <div class="user-name">Alex Johnson<span class="status-indicator"></span></div> <div class="user-role">Product Manager</div> </div> <div class="user-menu"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="1"></circle> <circle cx="19" cy="12" r="1"></circle> <circle cx="5" cy="12" r="1"></circle> </svg> </div> </div> </div> <div class="content-area"> <div class="content-header"> <h1>Your Dashboard</h1> <p>Track your progress, manage tasks, and optimize productivity</p> </div> <div class="card"> <div class="card-title"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> <polyline points="22 4 12 14.01 9 11.01"></polyline> </svg> </i> Today's Priority Tasks </div> <div class="task-item"> <div class="task-checkbox" data-completed="false"></div> <div class="task-text">Finalize Q3 marketing strategy document</div> <div class="task-priority priority-high">High</div> </div> <div class="task-item"> <div class="task-checkbox" data-completed="false"></div> <div class="task-text">Schedule team sync for product launch</div> <div class="task-priority priority-medium">Medium</div> </div> <div class="task-item"> <div class="task-checkbox checked" data-completed="true"></div> <div class="task-text">Review developer pull requests</div> <div class="task-priority priority-high">High</div> </div> <div class="task-item"> <div class="task-checkbox" data-completed="false"></div> <div class="task-text">Prepare monthly expense report</div> <div class="task-priority priority-low">Low</div> </div> <div class="progress-chart"> <div class="progress-bar"></div> </div> <div class="progress-label"> <span>Daily progress: 65%</span> <span>3/8 tasks completed</span> </div> </div> <div class="card"> <div class="card-title"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21.21 15.89A10 10 0 1 1 8 2.83"></path> <path d="M22 12A10 10 0 0 0 12 2v10z"></path> </svg> </i> Productivity Insights </div> <div class="stats-grid"> <div class="stat-item"> <div class="stat-number">3.5h</div> <div class="stat-label">Deep focus time</div> </div> <div class="stat-item"> <div class="stat-number">24</div> <div class="stat-label">Weekly tasks completed</div> </div> <div class="stat-item"> <div class="stat-number">87%</div> <div class="stat-label">Efficiency rate</div> </div> <div class="stat-item"> <div class="stat-number">12</div> <div class="stat-label">Hours saved this month</div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Sidebar toggle functionality const menuToggle = document.querySelector('.menu-toggle'); const sidebar = document.querySelector('.sidebar'); menuToggle.addEventListener('click', function() { sidebar.classList.toggle('collapsed'); }); // Menu item selection const menuItems = document.querySelectorAll('.menu-item'); menuItems.forEach(item => { item.addEventListener('click', function() { // Remove active class from all menu items menuItems.forEach(i => i.classList.remove('active')); // Add active class to clicked menu item this.classList.add('active'); // Add sparkle animation addSparkleEffect(this); }); }); // Task checkbox toggling const taskCheckboxes = document.querySelectorAll('.task-checkbox'); taskCheckboxes.forEach(checkbox => { checkbox.addEventListener('click', function() { this.classList.toggle('checked'); // Update data attribute const isCompleted = this.classList.contains('checked'); this.setAttribute('data-completed', isCompleted); // Update progress calculation updateProgress(); }); }); // Update progress calculation function updateProgress() { const totalTasks = taskCheckboxes.length; const completedTasks = document.querySelectorAll('.task-checkbox.checked').length; const progressPercentage = Math.round((completedTasks / totalTasks) * 100); // Update progress bar const progressBar = document.querySelector('.progress-bar'); progressBar.style.width = `${progressPercentage}%`; // Update progress label text const progressLabel = document.querySelector('.progress-label span:first-child'); progressLabel.textContent = `Daily progress: ${progressPercentage}%`; const taskCountLabel = document.querySelector('.progress-label span:last-child'); taskCountLabel.textContent = `${completedTasks}/${totalTasks} tasks completed`; } // Sparkle effect when selecting menu items function addSparkleEffect(element) { // Clear any existing sparkles const existingSparkles = element.querySelectorAll('.sparkle'); existingSparkles.forEach(s => s.remove()); // Create 5 sparkles for (let i = 0; i < 5; i++) { createSparkle(element); } } function createSparkle(parent) { const sparkle = document.createElement('span'); sparkle.classList.add('sparkle'); // Random positioning within the element const posX = Math.random() * parent.offsetWidth; const posY = Math.random() * parent.offsetHeight; sparkle.style.left = `${posX}px`; sparkle.style.top = `${posY}px`; // Random size between 2-4px const size = 2 + Math.random() * 2; sparkle.style.width = `${size}px`; sparkle.style.height = `${size}px`; // Add to parent element parent.appendChild(sparkle); // Animate and then remove setTimeout(() => { sparkle.style.opacity = '1'; // Random animation sparkle.style.transform = `translate(${-20 + Math.random() * 40}px, ${-20 + Math.random() * 40}px)`; setTimeout(() => { sparkle.style.opacity = '0'; setTimeout(() => { sparkle.remove(); }, 300); }, 300 + Math.random() * 300); }, 10); } // Initial progress calculation updateProgress(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>FinDash Widget</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } body { background-color: #0a0e17; color: #e9ecef; display: flex; justify-content: center; align-items: center; min-height: 700px; overflow: hidden; } .dashboard { width: 680px; display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: auto auto; gap: 20px; padding: 20px; } .widget { background-color: #131b2c; border-radius: 12px; position: relative; overflow: hidden; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); transition: transform 0.3s ease; } .widget:hover { transform: translateY(-5px); } .widget-content { padding: 20px; z-index: 5; position: relative; } .widget-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .widget-title { font-size: 16px; font-weight: 600; color: #8a94a8; } .widget-value { font-size: 28px; font-weight: 700; margin-bottom: 5px; } .value-change { display: flex; align-items: center; font-size: 14px; margin-bottom: 15px; } .positive { color: #34D399; } .negative { color: #F87171; } .neutral { color: #94A3B8; } .widget-badge { padding: 4px 8px; border-radius: 12px; font-size: 12px; font-weight: 600; } .ticker-badge { background-color: rgba(59, 130, 246, 0.15); color: #3B82F6; } .alert-badge { background-color: rgba(249, 115, 22, 0.15); color: #F97316; } .info-badge { background-color: rgba(99, 102, 241, 0.15); color: #6366F1; } .success-badge { background-color: rgba(16, 185, 129, 0.15); color: #10B981; } .border-animation { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } .border-line { position: absolute; background: transparent; } .market-chart { height: 80px; margin-top: 10px; position: relative; } .chart-line { stroke-width: 2; fill: none; stroke-linecap: round; } .up { stroke: #34D399; } .down { stroke: #F87171; } .chart-area { opacity: 0.1; } .chart-point { opacity: 0; r: 4; transition: opacity 0.3s ease; } .chart-svg:hover .chart-point { opacity: 1; } .tooltip { position: absolute; background: #1E293B; border-radius: 6px; padding: 8px 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); font-size: 12px; pointer-events: none; opacity: 0; transition: opacity 0.2s ease; z-index: 100; border: 1px solid #2D3748; } .indicator { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; } .live-dot { display: inline-block; width: 8px; height: 8px; background-color: #10B981; border-radius: 50%; margin-right: 5px; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); } 70% { transform: scale(1); box-shadow: 0 0 0 5px rgba(16, 185, 129, 0); } 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); } } .widget-large { grid-column: span 2; } .stats-row { display: flex; justify-content: space-between; margin-top: 15px; } .stat-item { display: flex; flex-direction: column; } .stat-label { font-size: 12px; color: #8a94a8; margin-bottom: 5px; } .stat-value { font-size: 18px; font-weight: 600; } .range-selector { display: flex; gap: 8px; margin-top: 15px; } .range-btn { background: #1E293B; border: none; color: #94A3B8; padding: 6px 12px; border-radius: 6px; font-size: 12px; cursor: pointer; transition: all 0.2s ease; } .range-btn.active { background: #3B82F6; color: white; } .range-btn:hover:not(.active) { background: #2D3748; } .watchlist-item { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid #1E293B; } .watchlist-item:last-child { border-bottom: none; } .stock-info { display: flex; align-items: center; } .stock-icon { width: 30px; height: 30px; border-radius: 8px; background: #2D3748; display: flex; align-items: center; justify-content: center; margin-right: 10px; font-weight: bold; font-size: 14px; } .stock-name { display: flex; flex-direction: column; } .stock-ticker { font-weight: 600; font-size: 14px; } .stock-company { font-size: 12px; color: #8a94a8; } .stock-price { display: flex; flex-direction: column; align-items: flex-end; } .price-value { font-weight: 600; font-size: 14px; } @media (max-width: 700px) { .dashboard { grid-template-columns: 1fr; width: 100%; padding: 15px; } .widget-large { grid-column: span 1; } } </style> </head> <body> <div class="dashboard"> <div class="widget" id="portfolio-widget"> <div class="widget-content"> <div class="widget-header"> <div class="widget-title">PORTFOLIO VALUE</div> <div class="widget-badge ticker-badge">LIVE</div> </div> <div class="widget-value">$64,892.75</div> <div class="value-change positive"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 4L12.6464 8.64645L11.9393 9.35355L8.5 5.91421L8.5 12L7.5 12L7.5 5.91421L4.06066 9.35355L3.35355 8.64645L8 4Z" fill="currentColor"/> </svg> <span>+2.37% ($1,502.21 today)</span> </div> <div class="market-chart"> <svg class="chart-svg" width="100%" height="100%" viewBox="0 0 300 80" preserveAspectRatio="none"> <path class="chart-line up" id="portfolio-line"></path> <path class="chart-area up" id="portfolio-area" fill="#34D399"></path> </svg> </div> <div class="range-selector"> <button class="range-btn">1D</button> <button class="range-btn active">1W</button> <button class="range-btn">1M</button> <button class="range-btn">3M</button> <button class="range-btn">1Y</button> <button class="range-btn">ALL</button> </div> </div> <div class="border-animation" id="portfolio-border"></div> </div> <div class="widget" id="sp500-widget"> <div class="widget-content"> <div class="widget-header"> <div class="widget-title">S&P 500</div> <div class="widget-badge info-badge"><span class="live-dot"></span>MARKET OPEN</div> </div> <div class="widget-value">4,783.45</div> <div class="value-change positive"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 4L12.6464 8.64645L11.9393 9.35355L8.5 5.91421L8.5 12L7.5 12L7.5 5.91421L4.06066 9.35355L3.35355 8.64645L8 4Z" fill="currentColor"/> </svg> <span>+0.86% (40.83 pts)</span> </div> <div class="market-chart"> <svg class="chart-svg" width="100%" height="100%" viewBox="0 0 300 80" preserveAspectRatio="none"> <path class="chart-line up" id="sp500-line"></path> <path class="chart-area up" id="sp500-area" fill="#34D399"></path> </svg> </div> <div class="stats-row"> <div class="stat-item"> <div class="stat-label">DAY RANGE</div> <div class="stat-value">4,742.62 - 4,793.30</div> </div> </div> </div> <div class="border-animation" id="sp500-border"></div> </div> <div class="widget" id="nasdaq-widget"> <div class="widget-content"> <div class="widget-header"> <div class="widget-title">NASDAQ</div> <div class="widget-badge alert-badge">VOLATILITY ALERT</div> </div> <div class="widget-value">15,107.38</div> <div class="value-change negative"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 12L3.35355 7.35355L4.06066 6.64645L7.5 10.0858L7.5 4L8.5 4L8.5 10.0858L11.9393 6.64645L12.6464 7.35355L8 12Z" fill="currentColor"/> </svg> <span>-0.54% (82.83 pts)</span> </div> <div class="market-chart"> <svg class="chart-svg" width="100%" height="100%" viewBox="0 0 300 80" preserveAspectRatio="none"> <path class="chart-line down" id="nasdaq-line"></path> <path class="chart-area down" id="nasdaq-area" fill="#F87171"></path> </svg> </div> <div class="stats-row"> <div class="stat-item"> <div class="stat-label">DAY RANGE</div> <div class="stat-value">15,007.22 - 15,233.45</div> </div> </div> </div> <div class="border-animation" id="nasdaq-border"></div> </div> <div class="widget widget-large" id="watchlist-widget"> <div class="widget-content"> <div class="widget-header"> <div class="widget-title">WATCHLIST</div> <div class="widget-badge success-badge">TOP MOVERS</div> </div> <div class="watchlist-item"> <div class="stock-info"> <div class="stock-icon" style="background-color:rgba(79, 70, 229, 0.1); color: #6366F1;">AAPL</div> <div class="stock-name"> <div class="stock-ticker">AAPL</div> <div class="stock-company">Apple Inc.</div> </div> </div> <div class="stock-price"> <div class="price-value">$193.42</div> <div class="value-change positive">+1.74%</div> </div> </div> <div class="watchlist-item"> <div class="stock-info"> <div class="stock-icon" style="background-color:rgba(219, 39, 119, 0.1); color: #DB2777;">TSLA</div> <div class="stock-name"> <div class="stock-ticker">TSLA</div> <div class="stock-company">Tesla, Inc.</div> </div> </div> <div class="stock-price"> <div class="price-value">$247.58</div> <div class="value-change negative">-2.15%</div> </div> </div> <div class="watchlist-item"> <div class="stock-info"> <div class="stock-icon" style="background-color:rgba(236, 72, 153, 0.1); color: #EC4899;">NVDA</div> <div class="stock-name"> <div class="stock-ticker">NVDA</div> <div class="stock-company">NVIDIA Corporation</div> </div> </div> <div class="stock-price"> <div class="price-value">$492.98</div> <div class="value-change positive">+3.89%</div> </div> </div> <div class="watchlist-item"> <div class="stock-info"> <div class="stock-icon" style="background-color:rgba(16, 185, 129, 0.1); color: #10B981;">MSFT</div> <div class="stock-name"> <div class="stock-ticker">MSFT</div> <div class="stock-company">Microsoft Corporation</div> </div> </div> <div class="stock-price"> <div class="price-value">$376.17</div> <div class="value-change positive">+0.72%</div> </div> </div> </div> <div class="border-animation" id="watchlist-border"></div> </div> </div> <div class="tooltip" id="chart-tooltip"></div> <script> // Market data simulation function generateTimeSeries(length, isPositive) { let data = []; let value = 100; let trend = isPositive ? 1 : -1; for (let i = 0; i < length; i++) { // Random walk with trend let change = (Math.random() * 3 - 1) + (trend * 0.5); value += change; value = Math.max(80, value); // Ensure we don't go below 80 data.push(value); } return data; } // Generate chart paths function generateChartPath(data, svgWidth, svgHeight) { const maxValue = Math.max(...data); const minValue = Math.min(...data); const range = maxValue - minValue; const xStep = svgWidth / (data.length - 1); // Generate line path let linePath = `M 0,${svgHeight - ((data[0] - minValue) / range) * svgHeight}`; for (let i = 1; i < data.length; i++) { const x = i * xStep; const y = svgHeight - ((data[i] - minValue) / range) * svgHeight; linePath += ` L ${x},${y}`; } // Generate area path (extends to bottom) let areaPath = linePath + ` L ${svgWidth},${svgHeight} L 0,${svgHeight} Z`; return { linePath, areaPath }; } // Initialize charts function initializeCharts() { const portfolioData = generateTimeSeries(50, true); const sp500Data = generateTimeSeries(50, true); const nasdaqData = generateTimeSeries(50, false); const paths1 = generateChartPath(portfolioData, 300, 80); document.getElementById('portfolio-line').setAttribute('d', paths1.linePath); document.getElementById('portfolio-area').setAttribute('d', paths1.areaPath); const paths2 = generateChartPath(sp500Data, 300, 80); document.getElementById('sp500-line').setAttribute('d', paths2.linePath); document.getElementById('sp500-area').setAttribute('d', paths2.areaPath); const paths3 = generateChartPath(nasdaqData, 300, 80); document.getElementById('nasdaq-line').setAttribute('d', paths3.linePath); document.getElementById('nasdaq-area').setAttribute('d', paths3.areaPath); } // Border animation function createBorderAnimation(elementId, isPositive) { const element = document.getElementById(elementId); const borderContainer = document.getElementById(`${elementId}-border`); if (!element || !borderContainer) return; // Clean previous animation borderContainer.innerHTML = ''; // Create new border lines const borderTop = document.createElement('div'); borderTop.className = 'border-line'; borderTop.style.top = '0'; borderTop.style.left = '0'; borderTop.style.width = '100%'; borderTop.style.height = '2px'; const borderRight = document.createElement('div'); borderRight.className = 'border-line'; borderRight.style.top = '0'; borderRight.style.right = '0'; borderRight.style.width = '2px'; borderRight.style.height = '100%'; const borderBottom = document.createElement('div'); borderBottom.className = 'border-line'; borderBottom.style.bottom = '0'; borderBottom.style.left = '0'; borderBottom.style.width = '100%'; borderBottom.style.height = '2px'; const borderLeft = document.createElement('div'); borderLeft.className = 'border-line'; borderLeft.style.top = '0'; borderLeft.style.left = '0'; borderLeft.style.width = '2px'; borderLeft.style.height = '100%'; // Append border lines borderContainer.appendChild(borderTop); borderContainer.appendChild(borderRight); borderContainer.appendChild(borderBottom); borderContainer.appendChild(borderLeft); // Set border colors const color = isPositive ? '#34D399' : '#F87171'; borderTop.style.background = `linear-gradient(90deg, transparent, ${color}, transparent)`; borderRight.style.background = `linear-gradient(180deg, transparent, ${color}, transparent)`; borderBottom.style.background = `linear-gradient(270deg, transparent, ${color}, transparent)`; borderLeft.style.background = `linear-gradient(0deg, transparent, ${color}, transparent)`; // Animate borders animateBorder(borderTop, 'translateX', -100, 100, 4000); animateBorder(borderRight, 'translateY', -100, 100, 3500); animateBorder(borderBottom, 'translateX', 100, -100, 4000); animateBorder(borderLeft, 'translateY', 100, -100, 3500); } function animateBorder(element, transform, fromValue, toValue, duration) { element.animate( [ { transform: `${transform}(${fromValue}%)`, opacity: 0.2 }, { transform: `${transform}(0%)`, opacity: 1, offset: 0.5 }, { transform: `${transform}(${toValue}%)`, opacity: 0.2 } ], { duration: duration, iterations: Infinity, easing: 'ease-in-out' } ); } // Range buttons functionality function setupRangeButtons() { const buttons = document.querySelectorAll('.range-btn'); buttons.forEach(button => { button.addEventListener('click', () => { // Remove active class from all buttons buttons.forEach(btn => btn.classList.remove('active')); // Add active class to clicked button button.classList.add('active'); // You would typically fetch new data here // For this demo, we'll just regenerate random charts initializeCharts(); }); }); } // Initialize and run animations document.addEventListener('DOMContentLoaded', () => { initializeCharts(); createBorderAnimation('portfolio-widget', true); createBorderAnimation('sp500-widget', true); createBorderAnimation('nasdaq-widget', false); createBorderAnimation('watchlist-widget', true); setupRangeButtons(); // Simulate live data updates setInterval(() => { // Randomly update one of the widgets const widgets = ['portfolio-widget', 'sp500-widget', 'nasdaq-widget']; const randomWidget = widgets[Math.floor(Math.random() * widgets.length)]; const isPositive = Math.random() > 0.3; // 70% chance of being positive createBorderAnimation(randomWidget, isPositive); // You would update actual data here }, 8000); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Artisanal Portfolio</title> <style> @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@300;400;500;600&family=Work+Sans:wght@300;400;500&display=swap'); :root { --color-bg: #f8f5f2; --color-text: #2d2a27; --color-accent-1: #9b8d7a; --color-accent-2: #665e53; --color-accent-3: #a9c3bc; --color-accent-4: #d1b48c; --color-accent-5: #e7d6c4; } * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: var(--color-bg); color: var(--color-text); font-family: 'Work Sans', sans-serif; line-height: 1.6; padding: 2rem; max-width: 700px; margin: 0 auto; height: 100vh; overflow-x: hidden; } header { margin-bottom: 2rem; } h1 { font-family: 'Cormorant Garamond', serif; font-weight: 500; font-size: 2.2rem; position: relative; display: inline-block; margin-bottom: 0.5rem; color: var(--color-accent-2); } h1::after { content: ""; position: absolute; width: 30%; height: 2px; background-color: var(--color-accent-4); bottom: -5px; left: 0; } p.intro { font-size: 0.95rem; margin-bottom: 2rem; max-width: 90%; color: var(--color-accent-2); font-weight: 300; } .portfolio-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1.5rem; margin-bottom: 2rem; } .portfolio-item { position: relative; overflow: hidden; border-radius: 2px; background-color: #fff; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); transition: transform 0.5s ease; cursor: pointer; } .portfolio-item:hover { transform: translateY(-5px); } .portfolio-item::before { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border: 2px solid transparent; z-index: 2; pointer-events: none; transition: border-color 0.3s ease; } .portfolio-image { aspect-ratio: 1 / 1; object-fit: cover; width: 100%; height: 100%; display: block; background-color: var(--color-accent-5); } .portfolio-details { padding: 1rem; position: relative; background-color: #fff; } .portfolio-title { font-family: 'Cormorant Garamond', serif; font-weight: 500; font-size: 1.1rem; margin-bottom: 0.3rem; color: var(--color-accent-2); } .portfolio-category { font-size: 0.8rem; color: var(--color-accent-1); font-weight: 500; text-transform: uppercase; letter-spacing: 0.05em; } .sketch-border { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 3; } .sketch-border path { stroke: var(--color-accent-3); stroke-width: 3; fill: none; stroke-dasharray: 10; stroke-dashoffset: 1000; stroke-linecap: round; stroke-linejoin: round; transition: all 0.8s ease; } .portfolio-item:hover .sketch-border path { stroke-dashoffset: 0; stroke-dasharray: 0; stroke: var(--color-accent-4); stroke-width: 3; animation: sketch-animation 0.8s ease forwards; } .filter-controls { display: flex; gap: 0.8rem; margin-bottom: 2rem; flex-wrap: wrap; } .filter-btn { background: none; border: 1px solid var(--color-accent-1); color: var(--color-accent-2); padding: 0.4rem 1rem; border-radius: 30px; font-size: 0.85rem; cursor: pointer; transition: all 0.3s ease; font-family: 'Work Sans', sans-serif; } .filter-btn:hover { background-color: var(--color-accent-5); border-color: var(--color-accent-4); } .filter-btn.active { background-color: var(--color-accent-3); color: #fff; border-color: var(--color-accent-3); } @keyframes sketch-animation { 0% { stroke-dasharray: 10; stroke-dashoffset: 1000; } 40% { stroke-dasharray: 5; } 100% { stroke-dasharray: 0; stroke-dashoffset: 0; } } .featured-badge { position: absolute; top: 10px; right: 10px; background-color: var(--color-accent-4); color: white; font-size: 0.7rem; padding: 0.2rem 0.5rem; border-radius: 3px; z-index: 4; opacity: 0; transform: translateY(-10px); transition: all 0.4s ease; } .portfolio-item:hover .featured-badge { opacity: 1; transform: translateY(0); } footer { margin-top: 3rem; font-size: 0.85rem; color: var(--color-accent-1); text-align: center; } @media (max-width: 550px) { .portfolio-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1rem; } .portfolio-details { padding: 0.75rem; } .portfolio-title { font-size: 1rem; } .portfolio-category { font-size: 0.75rem; } h1 { font-size: 1.8rem; } p.intro { font-size: 0.9rem; } body { padding: 1.5rem; } } </style> </head> <body> <header> <h1>Kenji Takahashi</h1> <p class="intro">In my 12-year journey as a mixed media artist, I blend traditional painting techniques with experimental materials to capture those fleeting moments between the tangible and abstract.</p> </header> <div class="filter-controls"> <button class="filter-btn active" data-filter="all">All Works</button> <button class="filter-btn" data-filter="painting">Paintings</button> <button class="filter-btn" data-filter="mixed-media">Mixed Media</button> <button class="filter-btn" data-filter="installation">Installations</button> </div> <div class="portfolio-grid"> <div class="portfolio-item" data-category="painting"> <svg class="sketch-border" viewBox="0 0 200 200" preserveAspectRatio="none"> <path d="M10,10 L190,10 L190,190 L10,190 L10,10" /> </svg> <img src="https://images.unsplash.com/photo-1547891654-e66ed7ebb968?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Autumn Reflections" class="portfolio-image"> <div class="portfolio-details"> <h3 class="portfolio-title">Autumn Reflections</h3> <p class="portfolio-category">Painting</p> </div> <div class="featured-badge">Featured</div> </div> <div class="portfolio-item" data-category="mixed-media"> <svg class="sketch-border" viewBox="0 0 200 200" preserveAspectRatio="none"> <path d="M10,10 L190,10 L190,190 L10,190 L10,10" /> </svg> <img src="https://images.unsplash.com/photo-1574182245530-967d9b3831af?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Fractured Memory" class="portfolio-image"> <div class="portfolio-details"> <h3 class="portfolio-title">Fractured Memory</h3> <p class="portfolio-category">Mixed Media</p> </div> </div> <div class="portfolio-item" data-category="installation"> <svg class="sketch-border" viewBox="0 0 200 200" preserveAspectRatio="none"> <path d="M10,10 L190,10 L190,190 L10,190 L10,10" /> </svg> <img src="https://images.unsplash.com/photo-1597423244036-ef5570692257?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Temporal Nodes" class="portfolio-image"> <div class="portfolio-details"> <h3 class="portfolio-title">Temporal Nodes</h3> <p class="portfolio-category">Installation</p> </div> </div> <div class="portfolio-item" data-category="painting"> <svg class="sketch-border" viewBox="0 0 200 200" preserveAspectRatio="none"> <path d="M10,10 L190,10 L190,190 L10,190 L10,10" /> </svg> <img src="https://images.unsplash.com/photo-1578301978693-85fa9c0320b9?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Distant Shore" class="portfolio-image"> <div class="portfolio-details"> <h3 class="portfolio-title">Distant Shore</h3> <p class="portfolio-category">Painting</p> </div> <div class="featured-badge">Featured</div> </div> <div class="portfolio-item" data-category="mixed-media"> <svg class="sketch-border" viewBox="0 0 200 200" preserveAspectRatio="none"> <path d="M10,10 L190,10 L190,190 L10,190 L10,10" /> </svg> <img src="https://images.unsplash.com/photo-1536924940846-227afb31e2a5?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Ethereal Fragments" class="portfolio-image"> <div class="portfolio-details"> <h3 class="portfolio-title">Ethereal Fragments</h3> <p class="portfolio-category">Mixed Media</p> </div> </div> <div class="portfolio-item" data-category="installation"> <svg class="sketch-border" viewBox="0 0 200 200" preserveAspectRatio="none"> <path d="M10,10 L190,10 L190,190 L10,190 L10,10" /> </svg> <img src="https://images.unsplash.com/photo-1543857778-c4a1a3e0b2eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Liminal Space" class="portfolio-image"> <div class="portfolio-details"> <h3 class="portfolio-title">Liminal Space</h3> <p class="portfolio-category">Installation</p> </div> </div> </div> <footer> <p>© 2023 Kenji Takahashi • Tokyo-based Mixed Media Artist</p> </footer> <script> document.addEventListener('DOMContentLoaded', () => { // Filter functionality const filterButtons = document.querySelectorAll('.filter-btn'); const portfolioItems = document.querySelectorAll('.portfolio-item'); filterButtons.forEach(button => { button.addEventListener('click', () => { // Update active button filterButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); const filterValue = button.getAttribute('data-filter'); // Filter items portfolioItems.forEach(item => { if (filterValue === 'all' || item.getAttribute('data-category') === filterValue) { item.style.display = 'block'; // Add animation when item appears setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'translateY(0)'; }, 50); } else { item.style.display = 'none'; } }); }); }); // Random sketch path variations for each border document.querySelectorAll('.sketch-border path').forEach(path => { // Add some randomness to the path's drawing const pathEl = path; const randomStart = Math.random() * 1000; pathEl.style.strokeDashoffset = randomStart; // Random drawing direction if (Math.random() > 0.5) { pathEl.style.strokeDashoffset = -randomStart; } }); // Staggered animation on page load portfolioItems.forEach((item, index) => { item.style.opacity = '0'; item.style.transform = 'translateY(20px)'; setTimeout(() => { item.style.transition = 'opacity 0.5s ease, transform 0.5s ease'; item.style.opacity = '1'; item.style.transform = 'translateY(0)'; }, 100 + (index * 100)); }); }); </script> </body> </html>