Close buttons are a fundamental part of user interface design, providing a simple way for users to exit or dismiss content. Their design can significantly impact user experience, making it essential to get them right.
In this article, we will explore 10 close button examples that showcase a variety of styles and functionalities. These examples will help you understand the best practices and inspire your own designs.
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
Designing your own close button has never been easier with Subframe. Its drag-and-drop interface and intuitive, responsive canvas ensure you create pixel-perfect UI every time. Loved by designers and developers alike, Subframe makes the design process seamless and efficient.
Start for free and experience the difference 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 UI design game? With Subframe, you can create stunning, pixel-perfect interfaces, including close buttons, in minutes. Its drag-and-drop editor ensures efficiency and precision.
Don't wait—start for free and begin designing immediately!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Media Gallery Popup</title> <style> :root { --primary-color: #111827; --accent-color: #10b981; --light-color: #ffffff; --hover-color: #f472b6; --transition-speed: 0.3s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; } body { background-color: #f9fafb; height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; overflow: hidden; } .gallery-container { max-width: 650px; width: 100%; display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 16px; padding: 20px; background-color: var(--light-color); border-radius: 12px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.05); } .gallery-header { grid-column: 1 / -1; margin-bottom: 10px; } .gallery-header h2 { color: var(--primary-color); font-size: 24px; margin-bottom: 8px; font-weight: 700; } .gallery-header p { color: #6b7280; font-size: 14px; line-height: 1.5; } .gallery-item { position: relative; border-radius: 8px; overflow: hidden; cursor: pointer; aspect-ratio: 1/1; transition: transform var(--transition-speed); } .gallery-item:hover { transform: translateY(-5px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } .gallery-item img, .gallery-item video { width: 100%; height: 100%; object-fit: cover; } .popup-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.85); backdrop-filter: blur(5px); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; visibility: hidden; transition: opacity var(--transition-speed), visibility var(--transition-speed); } .popup-overlay.active { opacity: 1; visibility: visible; } .popup-content { position: relative; max-width: 90%; max-height: 85vh; display: flex; align-items: center; justify-content: center; border-radius: 8px; overflow: hidden; opacity: 0; transform: scale(0.9); transition: opacity 0.4s ease, transform 0.4s ease; } .popup-overlay.active .popup-content { opacity: 1; transform: scale(1); } .popup-content img, .popup-content video { max-width: 100%; max-height: 85vh; object-fit: contain; border-radius: 4px; } .close-button { position: absolute; top: 20px; right: 20px; width: 48px; height: 48px; border-radius: 50%; background-color: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 1001; border: 2px solid rgba(255, 255, 255, 0.15); backdrop-filter: blur(4px); transition: all var(--transition-speed); transform: translateY(0); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); } .close-button::before, .close-button::after { content: ''; position: absolute; width: 22px; height: 3px; background-color: var(--light-color); border-radius: 2px; transition: all var(--transition-speed); } .close-button::before { transform: rotate(45deg); } .close-button::after { transform: rotate(-45deg); } .close-button:hover { background-color: rgba(244, 114, 182, 0.8); transform: translateY(-3px) scale(1.05); box-shadow: 0 6px 16px rgba(244, 114, 182, 0.4); } .close-button:hover::before, .close-button:hover::after { background-color: var(--light-color); width: 24px; } .media-nav { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); display: flex; gap: 12px; z-index: 1001; } .nav-button { width: 40px; height: 40px; border-radius: 50%; background-color: rgba(0, 0, 0, 0.5); border: 1px solid rgba(255, 255, 255, 0.15); color: var(--light-color); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all var(--transition-speed); } .nav-button:hover { background-color: var(--hover-color); transform: scale(1.1); } .media-counter { background-color: rgba(0, 0, 0, 0.5); color: var(--light-color); padding: 6px 12px; border-radius: 20px; font-size: 14px; position: absolute; bottom: 30px; right: 30px; z-index: 1001; backdrop-filter: blur(4px); border: 1px solid rgba(255, 255, 255, 0.15); } @media (max-width: 600px) { .gallery-container { grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 10px; padding: 15px; } .close-button { width: 40px; height: 40px; top: 15px; right: 15px; } .close-button::before, .close-button::after { width: 18px; height: 2px; } .media-nav { bottom: 20px; } .media-counter { bottom: 20px; right: 20px; font-size: 12px; padding: 4px 10px; } } .loading-spinner { width: 40px; height: 40px; border: 3px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top-color: var(--hover-color); animation: spin 1s linear infinite; position: absolute; } @keyframes spin { to { transform: rotate(360deg); } } .media-caption { position: absolute; bottom: -50px; left: 0; width: 100%; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 12px; text-align: center; transform: translateY(0); transition: transform 0.3s ease; backdrop-filter: blur(4px); } .popup-overlay.active .media-caption { transform: translateY(-50px); } .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(244, 114, 182, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(244, 114, 182, 0); } 100% { box-shadow: 0 0 0 0 rgba(244, 114, 182, 0); } } </style> </head> <body> <div class="gallery-container"> <div class="gallery-header"> <h2>Creative Portfolio</h2> <p>Click on any thumbnail to open the media viewer with our custom close button. Navigate between items with arrow keys or touch controls.</p> </div> <div class="gallery-item" data-type="image" data-src="https://images.unsplash.com/photo-1553356084-58ef4a67b2a7?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" data-caption="Abstract Architecture"> <img src="https://images.unsplash.com/photo-1553356084-58ef4a67b2a7?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Abstract Architecture"> </div> <div class="gallery-item" data-type="video" data-src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" data-caption="Animation Demo"> <video src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" muted loop></video> </div> <div class="gallery-item" data-type="image" data-src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" data-caption="Digital Art Exploration"> <img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Digital Art"> </div> <div class="gallery-item" data-type="image" data-src="https://images.unsplash.com/photo-1579546929662-711aa81148cf?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" data-caption="Gradient Composition"> <img src="https://images.unsplash.com/photo-1579546929662-711aa81148cf?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Gradient"> </div> <div class="gallery-item" data-type="image" data-src="https://images.unsplash.com/photo-1620121692029-d088224ddc74?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" data-caption="Geometric Patterns"> <img src="https://images.unsplash.com/photo-1620121692029-d088224ddc74?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Geometric"> </div> <div class="gallery-item" data-type="video" data-src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4" data-caption="Creative Commons Film"> <video src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4" muted loop></video> </div> <div class="gallery-item" data-type="image" data-src="https://images.unsplash.com/photo-1547891654-e66ed7ebb968?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" data-caption="Neon City Lights"> <img src="https://images.unsplash.com/photo-1547891654-e66ed7ebb968?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Neon"> </div> <div class="gallery-item" data-type="image" data-src="https://images.unsplash.com/photo-1573096108468-702f6014ef28?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" data-caption="Minimalist Design Study"> <img src="https://images.unsplash.com/photo-1573096108468-702f6014ef28?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Minimalist"> </div> </div> <div class="popup-overlay"> <div class="close-button pulse"></div> <div class="popup-content"> <div class="loading-spinner"></div> </div> <div class="media-nav"> <div class="nav-button prev">←</div> <div class="nav-button next">→</div> </div> <div class="media-counter">1/8</div> <div class="media-caption"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const galleryItems = document.querySelectorAll('.gallery-item'); const popupOverlay = document.querySelector('.popup-overlay'); const popupContent = document.querySelector('.popup-content'); const closeButton = document.querySelector('.close-button'); const prevButton = document.querySelector('.nav-button.prev'); const nextButton = document.querySelector('.nav-button.next'); const mediaCounter = document.querySelector('.media-counter'); const mediaCaption = document.querySelector('.media-caption'); let currentIndex = 0; let mediaElements = []; let isLoading = false; // Initialize gallery items galleryItems.forEach((item, index) => { mediaElements.push({ type: item.dataset.type, src: item.dataset.src, caption: item.dataset.caption }); // Play/pause video thumbnails on hover if (item.dataset.type === 'video') { const video = item.querySelector('video'); item.addEventListener('mouseenter', () => { video.play(); }); item.addEventListener('mouseleave', () => { video.pause(); video.currentTime = 0; }); } // Open popup on click item.addEventListener('click', () => { openPopup(index); }); }); // Function to open popup function openPopup(index) { currentIndex = index; showLoading(); popupOverlay.classList.add('active'); updateMedia(); } // Update media content in popup function updateMedia() { const media = mediaElements[currentIndex]; popupContent.innerHTML = ''; showLoading(); if (media.type === 'image') { const img = document.createElement('img'); img.src = media.src; img.addEventListener('load', hideLoading); popupContent.appendChild(img); } else if (media.type === 'video') { const video = document.createElement('video'); video.src = media.src; video.controls = true; video.autoplay = true; video.addEventListener('loadeddata', hideLoading); popupContent.appendChild(video); } // Update counter and caption mediaCounter.textContent = `${currentIndex + 1}/${mediaElements.length}`; mediaCaption.textContent = media.caption || ''; // Remove pulse effect after first open closeButton.classList.remove('pulse'); } function showLoading() { isLoading = true; if (!popupContent.querySelector('.loading-spinner')) { const spinner = document.createElement('div'); spinner.classList.add('loading-spinner'); popupContent.appendChild(spinner); } } function hideLoading() { isLoading = false; const spinner = popupContent.querySelector('.loading-spinner'); if (spinner) { spinner.remove(); } } // Event listeners for navigation closeButton.addEventListener('click', () => { popupOverlay.classList.remove('active'); setTimeout(() => { const video = popupContent.querySelector('video'); if (video) { video.pause(); } }, 300); }); prevButton.addEventListener('click', () => { if (isLoading) return; currentIndex = (currentIndex - 1 + mediaElements.length) % mediaElements.length; updateMedia(); }); nextButton.addEventListener('click', () => { if (isLoading) return; currentIndex = (currentIndex + 1) % mediaElements.length; updateMedia(); }); // Keyboard navigation document.addEventListener('keydown', (e) => { if (!popupOverlay.classList.contains('active')) return; if (e.key === 'Escape') { closeButton.click(); } else if (e.key === 'ArrowLeft') { prevButton.click(); } else if (e.key === 'ArrowRight') { nextButton.click(); } }); // Touch swipe for mobile let startX, startY; popupOverlay.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; startY = e.touches[0].clientY; }, { passive: true }); popupOverlay.addEventListener('touchend', (e) => { if (!startX || !startY) return; const endX = e.changedTouches[0].clientX; const endY = e.changedTouches[0].clientY; const diffX = startX - endX; const diffY = startY - endY; // Horizontal swipe detection with threshold if (Math.abs(diffX) > Math.abs(diffY) && Math.abs(diffX) > 50) { if (diffX > 0) { nextButton.click(); // Swipe left } else { prevButton.click(); // Swipe right } } startX = null; startY = null; }, { passive: true }); // Prevent background scrolling when popup is open popupOverlay.addEventListener('touchmove', (e) => { e.preventDefault(); }, { passive: false }); // Close when clicking outside the content popupOverlay.addEventListener('click', (e) => { if (e.target === popupOverlay) { closeButton.click(); } }); // Initialize video previews (autoplay on mouseover) document.querySelectorAll('.gallery-item video').forEach(video => { video.addEventListener('mouseenter', () => { video.play(); }); video.addEventListener('mouseleave', () => { video.pause(); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dashboard Widget Close Button</title> <style> :root { --primary-color: #3A36FF; --secondary-color: #FF3EA5; --tertiary-color: #42DDCD; --dark-bg: #1E1E2E; --medium-bg: #2A2A3A; --light-bg: #3A3A4A; --text-light: #F7F7F9; --text-medium: #AFAFBF; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #F5F7FA; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; padding: 20px; } .dashboard-container { width: 100%; max-width: 700px; height: 650px; background-color: #fff; border-radius: 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: auto auto; gap: 20px; padding: 20px; position: relative; overflow: hidden; } .dashboard-header { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; } .dashboard-header h1 { font-size: 24px; color: #2A2A3A; font-weight: 700; } .widget { background-color: white; border-radius: 12px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06); padding: 15px; position: relative; transition: transform 0.3s ease, box-shadow 0.3s ease; overflow: hidden; } .widget:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1); } .widget-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .widget-title { font-size: 16px; font-weight: 600; color: #333; } .close-button { width: 32px; height: 32px; border-radius: 8px; display: flex; justify-content: center; align-items: center; cursor: pointer; position: relative; overflow: hidden; transition: background-color 0.2s ease; } .close-button::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: transparent; border-radius: 8px; transition: background-color 0.2s ease; } .close-button:hover::before { background-color: rgba(0, 0, 0, 0.05); } .close-button-icon { position: relative; width: 14px; height: 14px; z-index: 2; } .close-button-icon::before, .close-button-icon::after { content: ""; position: absolute; width: 14px; height: 2px; top: 6px; left: 0; transition: background-color 0.2s ease; } .close-button-icon::before { transform: rotate(45deg); } .close-button-icon::after { transform: rotate(-45deg); } .ripple { position: absolute; border-radius: 50%; transform: scale(0); animation: ripple 0.6s linear; z-index: 1; } @keyframes ripple { to { transform: scale(2.5); opacity: 0; } } /* Specific widget styling */ .widget-1 .widget-content { height: 180px; display: flex; flex-direction: column; } .widget-1 .close-button-icon::before, .widget-1 .close-button-icon::after { background-color: var(--primary-color); } .widget-1 .close-button .ripple { background-color: rgba(58, 54, 255, 0.2); } .widget-2 .widget-content { height: 180px; display: flex; flex-direction: column; } .widget-2 .close-button-icon::before, .widget-2 .close-button-icon::after { background-color: var(--secondary-color); } .widget-2 .close-button .ripple { background-color: rgba(255, 62, 165, 0.2); } .widget-3 .widget-content { height: 180px; display: flex; flex-direction: column; } .widget-3 .close-button-icon::before, .widget-3 .close-button-icon::after { background-color: var(--tertiary-color); } .widget-3 .close-button .ripple { background-color: rgba(66, 221, 205, 0.2); } .widget-4 { background: var(--dark-bg); } .widget-4 .widget-title { color: var(--text-light); } .widget-4 .widget-content { height: 180px; display: flex; flex-direction: column; color: var(--text-medium); } .widget-4 .close-button-icon::before, .widget-4 .close-button-icon::after { background-color: #FF5B79; } .widget-4 .close-button:hover::before { background-color: rgba(255, 255, 255, 0.1); } .widget-4 .close-button .ripple { background-color: rgba(255, 91, 121, 0.3); } /* Chart styles */ .chart-container { width: 100%; height: 140px; margin-top: 10px; position: relative; } .bar-chart { height: 100%; display: flex; align-items: flex-end; gap: 8px; } .bar { flex: 1; transition: height 0.5s ease; border-radius: 4px 4px 0 0; position: relative; } .widget-1 .bar { background-color: var(--primary-color); opacity: 0.8; } .widget-2 .bar { background-color: var(--secondary-color); opacity: 0.8; } .widget-3 .bar { background-color: var(--tertiary-color); opacity: 0.8; } .widget-4 .bar { background-color: #FF5B79; opacity: 0.8; } .donut-chart { position: absolute; width: 140px; height: 140px; left: 50%; top: 40%; transform: translate(-50%, -50%); } .line-chart { height: 100%; display: flex; align-items: center; padding-bottom: 20px; position: relative; } .line { position: absolute; height: 3px; bottom: 30px; left: 0; right: 0; background: linear-gradient(90deg, var(--tertiary-color) 0%, var(--primary-color) 100%); z-index: 1; } .dot { width: 10px; height: 10px; border-radius: 50%; background-color: white; border: 2px solid var(--primary-color); position: absolute; bottom: 26.5px; z-index: 2; transition: transform 0.2s ease; } .dot:hover { transform: scale(1.3); } /* Responsive adjustments */ @media (max-width: 600px) { .dashboard-container { grid-template-columns: 1fr; height: auto; } } /* Reset button */ .reset-button { grid-column: 1 / -1; background-color: #F0F0F5; border: none; border-radius: 10px; padding: 12px; font-weight: 600; color: #555; cursor: pointer; transition: all 0.2s ease; margin-top: 10px; } .reset-button:hover { background-color: #E5E5F0; } /* Notification */ .notification { position: fixed; top: 20px; right: 20px; background-color: #333; color: white; padding: 12px 20px; border-radius: 8px; opacity: 0; transform: translateY(-20px); transition: opacity 0.3s ease, transform 0.3s ease; z-index: 1000; font-size: 14px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } .notification.show { opacity: 1; transform: translateY(0); } </style> </head> <body> <div class="dashboard-container"> <div class="dashboard-header"> <h1>Data Metrics Dashboard</h1> </div> <div class="widget widget-1"> <div class="widget-header"> <div class="widget-title">Daily Revenue</div> <div class="close-button" data-widget="1"> <div class="close-button-icon"></div> </div> </div> <div class="widget-content"> <p>Revenue trending +12% week-over-week</p> <div class="chart-container"> <div class="bar-chart"> <div class="bar" style="height: 40%"></div> <div class="bar" style="height: 65%"></div> <div class="bar" style="height: 35%"></div> <div class="bar" style="height: 80%"></div> <div class="bar" style="height: 60%"></div> <div class="bar" style="height: 75%"></div> <div class="bar" style="height: 90%"></div> </div> </div> </div> </div> <div class="widget widget-2"> <div class="widget-header"> <div class="widget-title">User Engagement</div> <div class="close-button" data-widget="2"> <div class="close-button-icon"></div> </div> </div> <div class="widget-content"> <p>Active users up 8.3% since last month</p> <div class="chart-container"> <div class="donut-chart"> <canvas id="donutChart" width="140" height="140"></canvas> </div> </div> </div> </div> <div class="widget widget-3"> <div class="widget-header"> <div class="widget-title">Conversion Rates</div> <div class="close-button" data-widget="3"> <div class="close-button-icon"></div> </div> </div> <div class="widget-content"> <p>Checkout conversion improved to 4.7%</p> <div class="chart-container"> <div class="line-chart"> <div class="line"></div> <div class="dot" style="left: 10%"></div> <div class="dot" style="left: 25%"></div> <div class="dot" style="left: 40%"></div> <div class="dot" style="left: 55%"></div> <div class="dot" style="left: 70%"></div> <div class="dot" style="left: 85%"></div> </div> </div> </div> </div> <div class="widget widget-4"> <div class="widget-header"> <div class="widget-title">Performance Metrics</div> <div class="close-button" data-widget="4"> <div class="close-button-icon"></div> </div> </div> <div class="widget-content"> <p>Page load time reduced by 23% this week</p> <div class="chart-container"> <div class="bar-chart"> <div class="bar" style="height: 75%"></div> <div class="bar" style="height: 55%"></div> <div class="bar" style="height: 85%"></div> <div class="bar" style="height: 45%"></div> <div class="bar" style="height: 35%"></div> <div class="bar" style="height: 25%"></div> <div class="bar" style="height: 15%"></div> </div> </div> </div> </div> <button class="reset-button">Restore All Widgets</button> </div> <div class="notification" id="notification">Widget closed successfully</div> <script> document.addEventListener('DOMContentLoaded', function() { // Create donut chart const donutChart = document.getElementById('donutChart'); const ctx = donutChart.getContext('2d'); // Draw donut chart function drawDonut() { const centerX = donutChart.width / 2; const centerY = donutChart.height / 2; const radius = 60; const innerRadius = 40; // Clear canvas ctx.clearRect(0, 0, donutChart.width, donutChart.height); // Data segments const segments = [ { color: '#FF3EA5', value: 45 }, { color: '#3A36FF', value: 30 }, { color: '#42DDCD', value: 25 } ]; let startAngle = -0.5 * Math.PI; const totalValue = segments.reduce((sum, segment) => sum + segment.value, 0); segments.forEach(segment => { const segmentAngle = (segment.value / totalValue) * (2 * Math.PI); const endAngle = startAngle + segmentAngle; ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.arc(centerX, centerY, radius, startAngle, endAngle); ctx.closePath(); ctx.fillStyle = segment.color; ctx.fill(); // Draw inner circle for donut ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.arc(centerX, centerY, innerRadius, startAngle, endAngle); ctx.closePath(); ctx.fillStyle = '#fff'; ctx.fill(); startAngle = endAngle; }); // Add center circle with white background ctx.beginPath(); ctx.arc(centerX, centerY, innerRadius - 1, 0, 2 * Math.PI); ctx.fillStyle = 'white'; ctx.fill(); // Add percentage text ctx.font = 'bold 20px Arial'; ctx.fillStyle = '#333'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText('78%', centerX, centerY); } drawDonut(); // Close button functionality with ripple effect const closeButtons = document.querySelectorAll('.close-button'); const widgets = document.querySelectorAll('.widget'); const notification = document.getElementById('notification'); const resetButton = document.querySelector('.reset-button'); // Store original widget states const widgetStates = {}; widgets.forEach((widget, index) => { widgetStates[index + 1] = { element: widget, display: widget.style.display }; }); closeButtons.forEach(button => { button.addEventListener('click', function(e) { // Create ripple effect const ripple = document.createElement('span'); ripple.classList.add('ripple'); this.appendChild(ripple); const rect = button.getBoundingClientRect(); const size = Math.max(rect.width, rect.height) * 2; ripple.style.width = ripple.style.height = `${size}px`; ripple.style.left = `${e.clientX - rect.left - size/2}px`; ripple.style.top = `${e.clientY - rect.top - size/2}px`; // Close widget const widgetId = this.getAttribute('data-widget'); const widget = document.querySelector(`.widget-${widgetId}`); // Animate closing widget.style.transition = 'all 0.3s ease-out'; widget.style.transform = 'scale(0.9)'; widget.style.opacity = '0'; setTimeout(() => { widget.style.display = 'none'; // Show notification showNotification(); }, 300); // Remove ripple after animation completes setTimeout(() => { ripple.remove(); }, 600); }); // Add hover sound effect button.addEventListener('mouseenter', () => { button.style.transform = 'scale(1.1)'; }); button.addEventListener('mouseleave', () => { button.style.transform = 'scale(1)'; }); }); // Notification function function showNotification() { notification.classList.add('show'); setTimeout(() => { notification.classList.remove('show'); }, 3000); } // Reset button functionality resetButton.addEventListener('click', () => { for (const id in widgetStates) { const widget = widgetStates[id].element; widget.style.display = ''; widget.style.opacity = '0'; widget.style.transform = 'scale(0.9)'; setTimeout(() => { widget.style.opacity = '1'; widget.style.transform = 'translateY(0) scale(1)'; }, 10); } notification.textContent = 'All widgets restored'; showNotification(); }); // Adding animation to bars const bars = document.querySelectorAll('.bar'); bars.forEach(bar => { const originalHeight = bar.style.height; bar.style.height = '0'; setTimeout(() => { bar.style.height = originalHeight; }, 300); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Enhanced Mobile Close Button</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; background-color: #f5f7fa; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; color: #333; padding: 20px; } .demo-container { width: 100%; max-width: 700px; height: 700px; position: relative; overflow: hidden; border-radius: 24px; box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); background-color: #fff; display: flex; flex-direction: column; } .header { background: linear-gradient(135deg, #6e45e1, #88a0f9); color: white; padding: 20px; text-align: center; border-radius: 24px 24px 0 0; } .mock-content { padding: 30px; flex-grow: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; } .demo-button { background: linear-gradient(135deg, #6e45e1, #88a0f9); border: none; color: white; padding: 16px 32px; font-size: 18px; border-radius: 50px; cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; box-shadow: 0 4px 12px rgba(110, 69, 225, 0.3); font-weight: 600; } .demo-button:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(110, 69, 225, 0.4); } .demo-button:active { transform: translateY(1px); box-shadow: 0 2px 8px rgba(110, 69, 225, 0.3); } .popup-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.75); display: flex; align-items: center; justify-content: center; opacity: 0; visibility: hidden; transition: opacity 0.4s ease, visibility 0.4s ease; backdrop-filter: blur(4px); z-index: 100; } .popup-overlay.active { opacity: 1; visibility: visible; } .popup { width: 85%; max-width: 400px; background-color: white; border-radius: 24px; padding: 30px; position: relative; transform: scale(0.9); opacity: 0; transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.5s ease; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); } .popup-overlay.active .popup { transform: scale(1); opacity: 1; } .close-button-container { position: absolute; top: -25px; right: -25px; z-index: 101; perspective: 1000px; } .close-button { width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(145deg, #ff575f, #ff3a44); border: none; color: white; font-size: 24px; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 5px 15px rgba(255, 58, 68, 0.4); transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.3s ease, background 0.3s ease; transform-style: preserve-3d; position: relative; } .close-button:hover { transform: translateY(-2px) scale(1.05) rotateY(10deg); box-shadow: 0 8px 20px rgba(255, 58, 68, 0.5); background: linear-gradient(145deg, #ff6b73, #ff4b55); } .close-button:active { transform: translateY(1px) scale(0.98); box-shadow: 0 2px 10px rgba(255, 58, 68, 0.4); } .close-button::before { content: "×"; position: absolute; font-size: 32px; font-weight: 300; top: 50%; left: 50%; transform: translate(-50%, -50%); transition: transform 0.3s ease; } .close-button:hover::before { transform: translate(-50%, -50%) rotate(90deg); } .close-button-ripple { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%; background-color: rgba(255, 255, 255, 0.4); transform: scale(0); opacity: 1; pointer-events: none; } .popup-title { font-size: 24px; font-weight: 700; margin-bottom: 15px; color: #333; } .popup-content { margin-bottom: 25px; line-height: 1.5; color: #666; } .info-badge { display: inline-block; background: linear-gradient(135deg, #6e45e1, #88a0f9); color: white; padding: 6px 12px; border-radius: 50px; font-size: 12px; font-weight: 600; margin-bottom: 15px; } .tap-hint { position: absolute; top: -5px; right: -5px; padding: 3px 10px; background-color: #6e45e1; color: white; font-size: 12px; border-radius: 20px; opacity: 0; transform: translateY(10px); transition: opacity 0.3s ease, transform 0.3s ease; pointer-events: none; white-space: nowrap; } .mobile-annotation { position: absolute; bottom: 20px; left: 0; width: 100%; text-align: center; font-size: 14px; color: #888; padding: 0 20px; } .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(255, 58, 68, 0.6); } 70% { box-shadow: 0 0 0 15px rgba(255, 58, 68, 0); } 100% { box-shadow: 0 0 0 0 rgba(255, 58, 68, 0); } } @keyframes ripple { to { transform: scale(2); opacity: 0; } } @media (max-width: 500px) { .close-button { width: 70px; height: 70px; } .close-button::before { font-size: 36px; } .popup { width: 90%; padding: 25px; } } </style> </head> <body> <div class="demo-container"> <div class="header"> <h2>Enhanced Mobile Close Button</h2> </div> <div class="mock-content"> <h3>Tap to show the popup with our enhanced close button</h3> <p style="margin: 20px 0; text-align: center;">Experience a touch-friendly close button designed specifically for mobile interfaces with a generous hit area and smooth animations.</p> <button class="demo-button" id="showPopup">Show Mobile Popup</button> </div> <div class="popup-overlay" id="popupOverlay"> <div class="popup"> <div class="close-button-container"> <button class="close-button pulse" id="closeButton" aria-label="Close popup"> <div class="close-button-ripple" id="ripple"></div> </button> <div class="tap-hint" id="tapHint">Tap to close</div> </div> <div class="info-badge">Mobile-Optimized UI</div> <h3 class="popup-title">Touch-Friendly Design</h3> <p class="popup-content"> This close button has a 60px hit area—making it 3x easier to tap accurately on mobile devices. The generous size and clear visual feedback help reduce "fat finger" frustration. </p> <p class="popup-content"> Notice the subtle gradient, shadow effects, and smooth animations that provide clear feedback when interacting with the button. </p> </div> </div> <div class="mobile-annotation"> Try tapping the large close button (×) in the top-right corner of the popup </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const showPopupBtn = document.getElementById('showPopup'); const popupOverlay = document.getElementById('popupOverlay'); const closeButton = document.getElementById('closeButton'); const ripple = document.getElementById('ripple'); const tapHint = document.getElementById('tapHint'); showPopupBtn.addEventListener('click', function() { popupOverlay.classList.add('active'); // Show tap hint after a brief delay setTimeout(() => { tapHint.style.opacity = '1'; tapHint.style.transform = 'translateY(0)'; }, 1500); // Hide tap hint after a while setTimeout(() => { tapHint.style.opacity = '0'; tapHint.style.transform = 'translateY(10px)'; }, 4000); }); closeButton.addEventListener('click', function(e) { // Create ripple effect ripple.style.left = (e.offsetX || 30) + 'px'; ripple.style.top = (e.offsetY || 30) + 'px'; ripple.style.animation = 'ripple 0.6s linear'; // Remove pulse animation when clicked closeButton.classList.remove('pulse'); // Delay hiding the popup slightly to allow for visual feedback setTimeout(() => { popupOverlay.classList.remove('active'); // Reset ripple animation setTimeout(() => { ripple.style.animation = ''; // Add pulse back after popup is closed setTimeout(() => { closeButton.classList.add('pulse'); }, 500); }, 600); }, 200); }); // Click outside to close popupOverlay.addEventListener('click', function(e) { if (e.target === popupOverlay) { popupOverlay.classList.remove('active'); // Reset the hint for next time tapHint.style.opacity = '0'; tapHint.style.transform = 'translateY(10px)'; } }); // Hover effects for desktop closeButton.addEventListener('mouseenter', function() { tapHint.style.opacity = '1'; tapHint.style.transform = 'translateY(0)'; }); closeButton.addEventListener('mouseleave', function() { tapHint.style.opacity = '0'; tapHint.style.transform = 'translateY(10px)'; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary-color: #00b4d8; --secondary-color: #0077b6; --highlight-color: #ff6b6b; --text-color: #333; --light-text: #fff; --bg-color: #f8f9fa; } * { 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: var(--bg-color); padding: 20px; } .app-container { position: relative; width: 100%; max-width: 700px; height: 650px; background-color: #fff; border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); overflow: hidden; } .app-header { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: var(--light-text); padding: 20px; text-align: center; position: relative; } .app-content { padding: 20px; height: calc(100% - 70px); overflow-y: auto; background-color: #f5f7f9; } .feature-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-top: 20px; } .feature-card { background-color: #fff; border-radius: 8px; padding: 20px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); transition: transform 0.3s, box-shadow 0.3s; cursor: pointer; } .feature-card:hover { transform: translateY(-4px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); } .feature-card h3 { color: var(--primary-color); margin-bottom: 10px; } .feature-card p { color: var(--text-color); font-size: 14px; line-height: 1.5; } /* Tutorial Modal Styles */ .tutorial-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.65); z-index: 1000; display: flex; justify-content: center; align-items: center; opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0.3s; } .tutorial-overlay.active { opacity: 1; visibility: visible; } .tutorial-modal { width: 90%; max-width: 500px; background-color: #fff; border-radius: 12px; overflow: hidden; position: relative; transform: scale(0.9); opacity: 0; transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.3s; box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2); } .tutorial-overlay.active .tutorial-modal { transform: scale(1); opacity: 1; } .tutorial-header { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); padding: 20px; color: var(--light-text); position: relative; } .tutorial-title { font-size: 18px; font-weight: 600; margin-right: 30px; } .tutorial-content { padding: 25px; } .tutorial-step { display: none; } .tutorial-step.active { display: block; animation: fadeIn 0.5s forwards; } .tutorial-step h3 { color: var(--secondary-color); margin-bottom: 15px; font-size: 18px; } .tutorial-step p { color: var(--text-color); line-height: 1.6; margin-bottom: 20px; font-size: 15px; } .tutorial-image { width: 100%; border-radius: 8px; margin-bottom: 20px; height: 180px; object-fit: cover; border: 1px solid #e0e5e9; } .tutorial-footer { padding: 20px; display: flex; justify-content: space-between; align-items: center; border-top: 1px solid rgba(0, 0, 0, 0.1); } .step-indicator { display: flex; gap: 8px; } .step-dot { width: 8px; height: 8px; border-radius: 50%; background-color: rgba(0, 123, 182, 0.3); transition: background-color 0.3s, transform 0.3s; } .step-dot.active { background-color: var(--primary-color); transform: scale(1.3); } .tutorial-btn { background-color: var(--primary-color); color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer; font-weight: 500; transition: background-color 0.3s, transform 0.2s; } .tutorial-btn:hover { background-color: var(--secondary-color); transform: translateY(-2px); } .tutorial-btn.prev { background-color: transparent; color: var(--text-color); border: 1px solid #ddd; } .tutorial-btn.prev:hover { background-color: #f5f5f5; } /* Close Button - The Heart of the Design */ .close-btn { position: absolute; top: 15px; right: 15px; width: 30px; height: 30px; background-color: transparent; border-radius: 50%; cursor: pointer; z-index: 10; display: flex; justify-content: center; align-items: center; transition: transform 0.3s ease; } .close-btn:hover { transform: rotate(90deg); } .close-btn:before, .close-btn:after { content: ''; position: absolute; width: 18px; height: 2px; background-color: white; border-radius: 2px; box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); } .close-btn:before { transform: rotate(45deg); } .close-btn:after { transform: rotate(-45deg); } .close-btn::after, .close-btn::before { transition: background-color 0.3s; } .close-btn:hover::after, .close-btn:hover::before { background-color: var(--highlight-color); } /* Pulsating Effect for Close Button */ .pulse-ring { position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: rgba(255, 255, 255, 0.3); opacity: 0; transform: scale(1); animation: pulse 2s ease-out infinite; } @keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 70% { transform: scale(1.5); opacity: 0; } 100% { transform: scale(1.5); opacity: 0; } } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } /* Skip Tutorial Link */ .skip-tutorial { position: absolute; bottom: 20px; left: 20px; color: rgba(255, 255, 255, 0.7); font-size: 13px; text-decoration: none; transition: color 0.3s; } .skip-tutorial:hover { color: white; text-decoration: underline; } @media (max-width: 600px) { .feature-grid { grid-template-columns: 1fr; } .tutorial-modal { width: 95%; } .tutorial-btn { padding: 8px 15px; font-size: 14px; } } /* Adding an educational theme with color accents */ .educational-element { position: absolute; width: 80px; height: 80px; top: -30px; right: -30px; background-color: var(--highlight-color); border-radius: 50%; opacity: 0.1; z-index: 0; } .educational-accent { position: absolute; bottom: -20px; left: -20px; width: 60px; height: 60px; background-color: var(--primary-color); border-radius: 50%; opacity: 0.1; z-index: 0; } </style> </head> <body> <div class="app-container"> <div class="app-header"> <h1>Data Insights Dashboard</h1> </div> <div class="app-content"> <h2>Welcome to your analytics dashboard</h2> <p>Explore your data with our powerful visualization tools</p> <div class="feature-grid"> <div class="feature-card" id="feature-reports"> <h3>Custom Reports</h3> <p>Create tailored reports with drag-and-drop simplicity to visualize exactly what matters to your team.</p> </div> <div class="feature-card" id="feature-realtime"> <h3>Real-Time Data</h3> <p>Monitor key metrics as they happen with sub-second updates and smart anomaly detection.</p> </div> <div class="feature-card" id="feature-export"> <h3>Data Export</h3> <p>Schedule automated exports to your preferred format and destination including cloud storage integration.</p> </div> <div class="feature-card" id="feature-alerts"> <h3>Smart Alerts</h3> <p>Set up custom notifications when metrics cross defined thresholds to stay on top of important changes.</p> </div> </div> </div> </div> <!-- Tutorial Modal --> <div class="tutorial-overlay" id="tutorialOverlay"> <div class="tutorial-modal"> <div class="tutorial-header"> <h2 class="tutorial-title">Getting Started with Data Insights</h2> <div class="close-btn" id="closeBtn"> <div class="pulse-ring"></div> </div> <a href="#" class="skip-tutorial" id="skipTutorial">Skip tutorial</a> <div class="educational-element"></div> </div> <div class="tutorial-content"> <!-- Step 1 --> <div class="tutorial-step active" data-step="1"> <h3>Welcome to Your Analytics Command Center</h3> <img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1770&q=80" alt="Dashboard Overview" class="tutorial-image"> <p>Your dashboard shows a real-time snapshot of your key performance indicators. We've pre-configured the most essential metrics based on your industry benchmarks.</p> <p>The color-coded tiles represent performance against targets—green is exceeding goals, yellow is meeting goals, and red indicates areas needing attention.</p> </div> <!-- Step 2 --> <div class="tutorial-step" data-step="2"> <h3>Creating Your First Custom Report</h3> <img src="https://images.unsplash.com/photo-1543286386-713bdd548da4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1770&q=80" alt="Custom Reports" class="tutorial-image"> <p>Click the "Custom Reports" tile to begin building visualizations that answer your specific business questions. Our AI assistant will suggest relevant metrics based on your recent searches.</p> <p>Pro tip: Save your most-used report configurations as templates to quickly generate up-to-date insights with one click.</p> </div> <!-- Step 3 --> <div class="tutorial-step" data-step="3"> <h3>Setting Up Smart Alerts</h3> <img src="https://images.unsplash.com/photo-1551434678-e076c223a692?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1770&q=80" alt="Smart Alerts" class="tutorial-image"> <p>Navigate to the "Smart Alerts" section to ensure you're notified about significant changes instantly. You can set thresholds based on absolute values or percentage changes.</p> <p>Our pattern recognition system will also suggest alert configurations based on historical volatility in your metrics.</p> </div> <!-- Step 4 --> <div class="tutorial-step" data-step="4"> <h3>You're Ready to Go!</h3> <img src="https://images.unsplash.com/photo-1552664730-d307ca884978?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1770&q=80" alt="Ready to Go" class="tutorial-image"> <p>You've completed the essential onboarding steps! Your dashboard is now fully configured for your specific needs.</p> <p>Remember that our support team is available 24/7 via the chat icon in the bottom right corner if you need any assistance. Happy analyzing!</p> </div> <div class="educational-accent"></div> </div> <div class="tutorial-footer"> <div class="step-indicator"> <div class="step-dot active" data-step="1"></div> <div class="step-dot" data-step="2"></div> <div class="step-dot" data-step="3"></div> <div class="step-dot" data-step="4"></div> </div> <div class="tutorial-nav"> <button class="tutorial-btn prev" id="prevBtn" style="display: none;">Previous</button> <button class="tutorial-btn next" id="nextBtn">Next</button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Show tutorial on page load setTimeout(() => { document.getElementById('tutorialOverlay').classList.add('active'); }, 500); // Tutorial navigation const steps = document.querySelectorAll('.tutorial-step'); const dots = document.querySelectorAll('.step-dot'); const nextBtn = document.getElementById('nextBtn'); const prevBtn = document.getElementById('prevBtn'); const closeBtn = document.getElementById('closeBtn'); const skipTutorial = document.getElementById('skipTutorial'); let currentStep = 1; const totalSteps = steps.length; // Update UI based on current step function updateStepUI() { // Hide all steps steps.forEach(step => step.classList.remove('active')); dots.forEach(dot => dot.classList.remove('active')); // Show current step document.querySelector(`.tutorial-step[data-step="${currentStep}"]`).classList.add('active'); document.querySelector(`.step-dot[data-step="${currentStep}"]`).classList.add('active'); // Update buttons if (currentStep === 1) { prevBtn.style.display = 'none'; } else { prevBtn.style.display = 'inline-block'; } if (currentStep === totalSteps) { nextBtn.textContent = 'Finish'; } else { nextBtn.textContent = 'Next'; } } // Event listeners for navigation nextBtn.addEventListener('click', () => { if (currentStep < totalSteps) { currentStep++; updateStepUI(); } else { // Close tutorial on finish document.getElementById('tutorialOverlay').classList.remove('active'); } }); prevBtn.addEventListener('click', () => { if (currentStep > 1) { currentStep--; updateStepUI(); } }); // Click on dots to navigate dots.forEach(dot => { dot.addEventListener('click', () => { currentStep = parseInt(dot.getAttribute('data-step')); updateStepUI(); }); }); // Close button closeBtn.addEventListener('click', () => { document.getElementById('tutorialOverlay').classList.remove('active'); }); // Skip tutorial skipTutorial.addEventListener('click', (e) => { e.preventDefault(); document.getElementById('tutorialOverlay').classList.remove('active'); }); // Feature cards to trigger tutorial document.querySelectorAll('.feature-card').forEach(card => { card.addEventListener('click', () => { currentStep = 1; // Reset to first step updateStepUI(); document.getElementById('tutorialOverlay').classList.add('active'); }); }); }); </script> </body> </html>
<html> <head> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #000; display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100vh; overflow: hidden; color: #fff; perspective: 1000px; } .ar-environment { position: relative; width: 100%; height: 100%; max-width: 700px; max-height: 700px; background: linear-gradient(135deg, #0a0a1a, #1a1a3a); overflow: hidden; display: flex; justify-content: center; align-items: center; } .grid { position: absolute; width: 200%; height: 200%; background: radial-gradient(circle, transparent 60%, rgba(0, 255, 255, 0.1) 60.5%), linear-gradient(transparent 98%, rgba(0, 255, 255, 0.1) 98.5%), linear-gradient(90deg, transparent 98%, rgba(0, 255, 255, 0.1) 98.5%); background-size: 100px 100px, 50px 50px, 50px 50px; transform: perspective(500px) rotateX(60deg) translateZ(-100px) translateY(-100px); opacity: 0.3; pointer-events: none; } .ar-info-card { position: absolute; width: 80%; max-width: 400px; background: rgba(15, 20, 35, 0.8); backdrop-filter: blur(10px); border-radius: 15px; border: 1px solid rgba(100, 220, 255, 0.3); padding: 25px; box-shadow: 0 0 30px rgba(0, 255, 255, 0.2); transform-style: preserve-3d; transform: translateZ(20px); z-index: 10; } .card-title { font-size: 1.6rem; font-weight: 700; margin-bottom: 15px; color: #fff; text-shadow: 0 0 10px rgba(0, 200, 255, 0.5); } .card-content { font-size: 0.9rem; line-height: 1.5; margin-bottom: 20px; color: rgba(255, 255, 255, 0.9); } .close-button-container { position: absolute; top: -30px; right: -30px; width: 60px; height: 60px; display: flex; justify-content: center; align-items: center; cursor: pointer; transform-style: preserve-3d; perspective: 1000px; z-index: 100; } .close-button { position: relative; width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(145deg, #002040, #004080); display: flex; justify-content: center; align-items: center; transform-style: preserve-3d; transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.3s ease; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 180, 255, 0.5), inset 0 -3px 10px rgba(0, 50, 100, 0.5); } .close-button::before, .close-button::after { content: ''; position: absolute; width: 18px; height: 2px; background: #00f0ff; border-radius: 1px; box-shadow: 0 0 5px #00f0ff, 0 0 10px rgba(0, 240, 255, 0.5); transition: all 0.3s ease; } .close-button::before { transform: rotate(45deg); } .close-button::after { transform: rotate(-45deg); } .close-button:hover { transform: translateZ(5px) rotateY(10deg) rotateX(-10deg); box-shadow: 0 15px 30px rgba(0, 0, 0, 0.4), 0 0 0 2px rgba(0, 200, 255, 0.6), inset 0 -3px 10px rgba(0, 80, 150, 0.6); } .close-button:hover::before, .close-button:hover::after { background: #fff; box-shadow: 0 0 10px #00f0ff, 0 0 20px rgba(0, 240, 255, 0.8); } .close-ring { position: absolute; width: 55px; height: 55px; border-radius: 50%; border: 2px solid transparent; border-top: 2px solid rgba(0, 240, 255, 0.8); border-left: 2px solid rgba(0, 240, 255, 0.4); animation: ring-rotate 8s linear infinite; pointer-events: none; } .hologram-effect { position: absolute; width: 70px; height: 70px; border-radius: 50%; background: radial-gradient(circle, rgba(0, 240, 255, 0) 40%, rgba(0, 240, 255, 0.1) 70%, rgba(0, 240, 255, 0) 71%); pointer-events: none; opacity: 0; transform: scale(0.8); animation: pulse 3s ease-in-out infinite; } @keyframes ring-rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes pulse { 0%, 100% { opacity: 0; transform: scale(0.8); } 50% { opacity: 0.5; transform: scale(1.2); } } .floating-particles { position: absolute; width: 100%; height: 100%; pointer-events: none; } .particle { position: absolute; width: 3px; height: 3px; background-color: rgba(0, 200, 255, 0.6); border-radius: 50%; box-shadow: 0 0 10px rgba(0, 200, 255, 0.8); pointer-events: none; transform-style: preserve-3d; } .instruction { position: absolute; bottom: 25px; text-align: center; color: rgba(255, 255, 255, 0.7); font-size: 0.9rem; letter-spacing: 1px; width: 80%; pointer-events: none; } .closed { transform: scale(0); opacity: 0; transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55), opacity 0.5s ease; } .reopen-area { position: absolute; bottom: 30px; right: 30px; padding: 15px 25px; background: rgba(0, 40, 80, 0.6); backdrop-filter: blur(5px); border-radius: 30px; border: 1px solid rgba(0, 180, 255, 0.3); color: #00e6ff; font-weight: 600; cursor: pointer; opacity: 0; transform: translateY(20px); transition: all 0.4s ease; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); display: none; } .reopen-area:hover { background: rgba(0, 60, 100, 0.8); } .appear { opacity: 1; transform: translateY(0); display: block; } @media (max-width: 600px) { .ar-info-card { width: 90%; padding: 20px; } .close-button-container { top: -25px; right: -25px; width: 50px; height: 50px; } .close-button { width: 35px; height: 35px; } .card-title { font-size: 1.3rem; } .card-content { font-size: 0.8rem; } } </style> </head> <body> <div class="ar-environment"> <div class="grid"></div> <div class="floating-particles" id="particles"></div> <div class="ar-info-card" id="arCard"> <div class="card-title">Spatial Navigation Controls</div> <div class="card-content"> This augmented reality overlay provides real-time information about your surroundings. The closest points of interest are highlighted with depth-sensitive markers that respond to your movement and gaze. <br><br> The spatial audio indicators will guide you with 3D sound cues, becoming louder as you face relevant points of interest. <br><br> Voice command "details" will expand any focused element for additional information. </div> <div class="close-button-container" id="closeBtn"> <div class="close-button"></div> <div class="close-ring"></div> <div class="hologram-effect"></div> </div> </div> <div class="instruction" id="instruction"> Hover and click the circular close button to dismiss this overlay </div> <div class="reopen-area" id="reopenBtn"> Reopen AR Overlay </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const closeBtn = document.getElementById('closeBtn'); const arCard = document.getElementById('arCard'); const reopenBtn = document.getElementById('reopenBtn'); const instruction = document.getElementById('instruction'); const particlesContainer = document.getElementById('particles'); // Create floating particles for (let i = 0; i < 30; i++) { createParticle(); } function createParticle() { const particle = document.createElement('div'); particle.classList.add('particle'); // Random position const x = Math.random() * 100; const y = Math.random() * 100; const z = Math.random() * 100 - 50; particle.style.left = `${x}%`; particle.style.top = `${y}%`; particle.style.transform = `translateZ(${z}px)`; // Random size const size = Math.random() * 3 + 1; particle.style.width = `${size}px`; particle.style.height = `${size}px`; // Random opacity particle.style.opacity = Math.random() * 0.5 + 0.3; // Animation const duration = Math.random() * 20 + 10; particle.style.animation = `pulse ${duration}s ease-in-out infinite`; particle.style.animationDelay = `${Math.random() * 5}s`; particlesContainer.appendChild(particle); } // 3D effect on mouse move document.addEventListener('mousemove', function(e) { const containerRect = document.querySelector('.ar-environment').getBoundingClientRect(); const mouseX = e.clientX - containerRect.left; const mouseY = e.clientY - containerRect.top; // Calculate mouse position relative to center of container const centerX = containerRect.width / 2; const centerY = containerRect.height / 2; const moveX = (mouseX - centerX) / 30; const moveY = (mouseY - centerY) / 30; if (!arCard.classList.contains('closed')) { arCard.style.transform = `translateZ(20px) rotateX(${-moveY}deg) rotateY(${moveX}deg)`; } closeBtn.addEventListener('mousemove', function(e) { e.stopPropagation(); const buttonRect = closeBtn.getBoundingClientRect(); const btnCenterX = buttonRect.width / 2; const btnCenterY = buttonRect.height / 2; const btnMouseX = e.clientX - buttonRect.left; const btnMouseY = e.clientY - buttonRect.top; const btnMoveX = (btnMouseX - btnCenterX) / 2; const btnMoveY = (btnMouseY - btnCenterY) / 2; closeBtn.querySelector('.close-button').style.transform = `translateZ(5px) rotateX(${-btnMoveY}deg) rotateY(${btnMoveX}deg)`; }); }); // Close button hover effect closeBtn.addEventListener('mouseenter', function() { const button = closeBtn.querySelector('.close-button'); button.style.transform = 'translateZ(10px) scale(1.1)'; const hologram = closeBtn.querySelector('.hologram-effect'); hologram.style.animation = 'pulse 1.5s ease-in-out infinite'; hologram.style.opacity = '1'; }); closeBtn.addEventListener('mouseleave', function() { const button = closeBtn.querySelector('.close-button'); button.style.transform = 'translateZ(0) scale(1)'; const hologram = closeBtn.querySelector('.hologram-effect'); hologram.style.animation = 'pulse 3s ease-in-out infinite'; hologram.style.opacity = '0'; }); // Close button click effect closeBtn.addEventListener('click', function() { const button = closeBtn.querySelector('.close-button'); // Rotation animation button.style.transition = 'transform 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275)'; button.style.transform = 'translateZ(15px) rotateZ(180deg) scale(0.9)'; // Close the AR card setTimeout(() => { arCard.classList.add('closed'); instruction.style.opacity = '0'; setTimeout(() => { reopenBtn.classList.add('appear'); }, 500); }, 300); }); // Reopen button reopenBtn.addEventListener('click', function() { reopenBtn.classList.remove('appear'); setTimeout(() => { arCard.classList.remove('closed'); arCard.style.transform = 'translateZ(20px)'; instruction.style.opacity = '1'; // Reset close button const button = closeBtn.querySelector('.close-button'); button.style.transform = 'translateZ(0) scale(1)'; }, 300); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Corporate Intranet Notification</title> <style> :root { --primary-color: #2c3e50; --secondary-color: #3498db; --accent-color: #e74c3c; --background-color: #f8f9fa; --text-color: #333; --shadow-color: rgba(0, 0, 0, 0.1); --close-size: 28px; --notification-width: 420px; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: var(--background-color); padding: 20px; color: var(--text-color); } .notification-container { width: 100%; max-width: var(--notification-width); position: relative; perspective: 1000px; } .notification { background: white; border-radius: 8px; box-shadow: 0 4px 15px var(--shadow-color); padding: 25px; position: relative; overflow: hidden; transform-origin: top center; animation: slideIn 0.4s ease-out forwards; } .notification-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .notification-title { font-size: 18px; font-weight: 600; color: var(--primary-color); display: flex; align-items: center; } .notification-title-icon { margin-right: 10px; color: var(--secondary-color); } .close-button { width: var(--close-size); height: var(--close-size); border: 2px solid var(--primary-color); border-radius: 50%; position: relative; cursor: pointer; transition: all 0.3s ease; background: transparent; display: flex; justify-content: center; align-items: center; outline: none; } .close-button::before, .close-button::after { content: ''; position: absolute; width: 14px; height: 2px; background-color: var(--primary-color); transition: all 0.3s ease; } .close-button::before { transform: rotate(45deg); } .close-button::after { transform: rotate(-45deg); } .close-button:hover { border-color: var(--accent-color); transform: rotate(90deg); } .close-button:hover::before, .close-button:hover::after { background-color: var(--accent-color); } .close-button:active { transform: rotate(90deg) scale(0.9); border-color: var(--accent-color); background-color: rgba(231, 76, 60, 0.1); } .notification-content { line-height: 1.6; } .notification-highlight { color: var(--secondary-color); font-weight: 600; } .notification-footer { margin-top: 20px; display: flex; justify-content: space-between; align-items: center; } .notification-link { color: var(--secondary-color); text-decoration: none; display: flex; align-items: center; font-size: 14px; font-weight: 500; transition: color 0.2s ease; } .notification-link:hover { color: var(--primary-color); text-decoration: underline; } .notification-link span { margin-right: 5px; } .notification-timestamp { font-size: 12px; color: #7f8c8d; } .notification-progress { position: absolute; bottom: 0; left: 0; width: 100%; height: 3px; background: #e0e0e0; } .notification-progress-bar { height: 100%; width: 100%; background: var(--secondary-color); transform-origin: left; animation: progress 10s linear forwards; } .notification.closing { animation: slideOut 0.4s ease-in forwards; } @keyframes slideIn { 0% { opacity: 0; transform: translateY(-20px) rotateX(10deg); } 100% { opacity: 1; transform: translateY(0) rotateX(0); } } @keyframes slideOut { 0% { opacity: 1; transform: translateY(0) scale(1); } 100% { opacity: 0; transform: translateY(-20px) scale(0.95); } } @keyframes progress { 0% { transform: scaleX(1); } 100% { transform: scaleX(0); } } @media (max-width: 480px) { .notification { padding: 20px; } .notification-title { font-size: 16px; } .close-button { --close-size: 24px; } } /* Pulse animation for the notification dot */ .notification-dot { display: inline-block; width: 8px; height: 8px; background-color: var(--accent-color); border-radius: 50%; margin-left: 8px; position: relative; } .notification-dot::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%; background-color: var(--accent-color); opacity: 0.5; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.5; } 50% { transform: scale(2); opacity: 0; } 100% { transform: scale(1); opacity: 0; } } </style> </head> <body> <div class="notification-container"> <div class="notification" id="notification"> <div class="notification-header"> <div class="notification-title"> <svg class="notification-title-icon" 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="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path> <path d="M13.73 21a2 2 0 0 1-3.46 0"></path> </svg> System Maintenance Alert <span class="notification-dot"></span> </div> <button class="close-button" id="closeBtn" aria-label="Close notification"></button> </div> <div class="notification-content"> <p>The <span class="notification-highlight">Enterprise Resource Portal</span> will be undergoing scheduled maintenance tonight from <span class="notification-highlight">11:00 PM - 2:00 AM EST</span>. Please save your work and log out before this window to prevent data loss.</p> </div> <div class="notification-footer"> <a href="#" class="notification-link" id="learnMoreLink"> <span>View maintenance schedule</span> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M5 12h14"></path> <path d="M12 5l7 7-7 7"></path> </svg> </a> <div class="notification-timestamp">Just now</div> </div> <div class="notification-progress"> <div class="notification-progress-bar" id="progressBar"></div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const notification = document.getElementById('notification'); const closeBtn = document.getElementById('closeBtn'); const progressBar = document.getElementById('progressBar'); const learnMoreLink = document.getElementById('learnMoreLink'); // Auto-close after progress bar completes let autoCloseTimeout = setTimeout(() => { closeNotification(); }, 10000); // Close button click event closeBtn.addEventListener('click', () => { clearTimeout(autoCloseTimeout); closeNotification(); }); // Learn more link click event learnMoreLink.addEventListener('click', (e) => { e.preventDefault(); // In a real implementation, this could open a modal or load content console.log('View maintenance schedule clicked'); // For demo purposes, change the link text to indicate action learnMoreLink.innerHTML = ` <span>Schedule details loaded</span> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M5 12l5 5 9-9"></path> </svg> `; }); // Restart progress when hovering the notification notification.addEventListener('mouseenter', () => { clearTimeout(autoCloseTimeout); progressBar.style.animationPlayState = 'paused'; }); notification.addEventListener('mouseleave', () => { // Calculate remaining time based on width const computedStyle = window.getComputedStyle(progressBar); const width = parseFloat(computedStyle.width) / parseFloat(computedStyle.parentElement.offsetWidth); const remainingTime = width * 10000; progressBar.style.animationPlayState = 'running'; // Set new timeout with remaining time autoCloseTimeout = setTimeout(() => { closeNotification(); }, remainingTime); }); function closeNotification() { notification.classList.add('closing'); // After animation completes, you could remove the element setTimeout(() => { notification.style.display = 'none'; // In a real implementation, you might want to remove the element // notification.parentNode.removeChild(notification); }, 400); } }); </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: #9900ff; --dark-bg: #0a0a0a; --button-size: 60px; } * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: rgba(0, 0, 0, 0.7); font-family: 'Rajdhani', 'Orbitron', sans-serif; height: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; overflow: hidden; position: relative; } .game-environment { width: 700px; height: 700px; position: relative; overflow: hidden; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%230a0a0a"/><path d="M0 50 L100 50" stroke="%23222" stroke-width="0.5"/><path d="M50 0 L50 100" stroke="%23222" stroke-width="0.5"/></svg>'); display: flex; justify-content: center; align-items: center; } .popup { width: 500px; background: rgba(10, 10, 10, 0.9); border: 2px solid var(--neon-blue); box-shadow: 0 0 15px var(--neon-blue), 0 0 30px rgba(0, 255, 255, 0.3); border-radius: 5px; padding: 30px; position: relative; color: white; z-index: 100; backdrop-filter: blur(5px); transform: perspective(800px) rotateX(0deg); transition: transform 0.5s ease-out; } .popup-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 1px solid rgba(0, 255, 255, 0.3); padding-bottom: 10px; } .popup-title { font-size: 24px; font-weight: 700; color: var(--neon-blue); text-transform: uppercase; letter-spacing: 2px; text-shadow: 0 0 5px var(--neon-blue); } .popup-content { margin-bottom: 20px; line-height: 1.6; } .popup-content p { margin-bottom: 15px; } .close-button { width: var(--button-size); height: var(--button-size); border-radius: 50%; background: var(--dark-bg); border: 2px solid var(--neon-pink); position: relative; cursor: pointer; display: flex; justify-content: center; align-items: center; transition: all 0.3s ease; box-shadow: 0 0 10px var(--neon-pink), 0 0 20px rgba(255, 0, 255, 0.3) inset; overflow: hidden; outline: none; } .close-button::before, .close-button::after { content: ''; position: absolute; width: 60%; height: 3px; background-color: var(--neon-pink); border-radius: 5px; transition: all 0.3s ease; box-shadow: 0 0 5px var(--neon-pink); } .close-button::before { transform: rotate(45deg); } .close-button::after { transform: rotate(-45deg); } .close-button:hover { transform: scale(1.1) rotate(5deg); border-color: var(--neon-blue); } .close-button:hover::before, .close-button:hover::after { background-color: var(--neon-blue); box-shadow: 0 0 10px var(--neon-blue), 0 0 20px var(--neon-blue); } .close-button:active { transform: scale(0.9); transition: transform 0.1s ease; } .ripple { position: absolute; border-radius: 50%; background: linear-gradient(135deg, var(--neon-pink) 0%, var(--neon-blue) 100%); opacity: 0; transform: scale(0); pointer-events: none; animation: ripple-effect 0.8s ease-out; } .glitch-container { position: absolute; width: 100%; height: 100%; top: 0; left: 0; overflow: hidden; pointer-events: none; } .glitch-effect { position: absolute; width: 100%; height: 100%; top: 0; left: 0; opacity: 0; background: linear-gradient(45deg, var(--neon-pink), var(--neon-purple), var(--neon-blue)); mix-blend-mode: screen; pointer-events: none; } .scan-line { position: absolute; width: 100%; height: 2px; background: rgba(0, 255, 255, 0.3); top: 0; left: 0; opacity: 0.5; animation: scan 3s linear infinite; pointer-events: none; } .hex-grid { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="56" height="100" viewBox="0 0 56 100"><path d="M28 0 L56 16 L56 50 L28 66 L0 50 L0 16 Z" stroke="%2300ffff33" fill="none" stroke-width="0.5"/></svg>'); background-size: 60px 60px; opacity: 0.1; pointer-events: none; } .action-buttons { display: flex; justify-content: flex-end; gap: 15px; margin-top: 20px; } .action-btn { background: rgba(0, 0, 0, 0.6); color: var(--neon-blue); border: 1px solid var(--neon-blue); padding: 10px 20px; border-radius: 4px; font-family: inherit; font-size: 14px; text-transform: uppercase; letter-spacing: 1px; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .action-btn:hover { background: rgba(0, 255, 255, 0.1); box-shadow: 0 0 10px var(--neon-blue); } .action-btn.confirm { background: rgba(0, 255, 255, 0.2); color: white; } .close-label { position: absolute; font-size: 10px; color: var(--neon-pink); text-transform: uppercase; letter-spacing: 1px; top: -20px; right: 10px; opacity: 0; transition: opacity 0.3s ease; } .close-button:hover + .close-label { opacity: 1; } @keyframes ripple-effect { 0% { transform: scale(0); opacity: 0.8; } 100% { transform: scale(2); opacity: 0; } } @keyframes glitch { 0% { clip-path: polygon(0 0, 100% 0, 100% 5%, 0 5%); transform: translate(10px); } 10% { clip-path: polygon(0 15%, 100% 15%, 100% 25%, 0 25%); transform: translate(-10px); } 20% { clip-path: polygon(0 40%, 100% 40%, 100% 45%, 0 45%); transform: translate(10px); } 30% { clip-path: polygon(0 60%, 100% 60%, 100% 70%, 0 70%); transform: translate(-10px); } 40% { clip-path: polygon(0 80%, 100% 80%, 100% 85%, 0 85%); transform: translate(10px); } 50% { clip-path: polygon(0 90%, 100% 90%, 100% 95%, 0 95%); transform: translate(-10px); } 60% { clip-path: polygon(0 5%, 100% 5%, 100% 30%, 0 30%); transform: translate(10px); } 70% { clip-path: polygon(0 40%, 100% 40%, 100% 50%, 0 50%); transform: translate(-10px); } 80% { clip-path: polygon(0 60%, 100% 60%, 100% 70%, 0 70%); transform: translate(10px); } 90% { clip-path: polygon(0 80%, 100% 80%, 100% 90%, 0 90%); transform: translate(-10px); } 100% { clip-path: polygon(0 0, 0 0, 0 0, 0 0); } } @keyframes scan { 0% { top: -5%; } 100% { top: 105%; } } @keyframes pulse { 0% { box-shadow: 0 0 10px var(--neon-pink), 0 0 20px rgba(255, 0, 255, 0.3) inset; } 50% { box-shadow: 0 0 15px var(--neon-pink), 0 0 30px rgba(255, 0, 255, 0.5) inset; } 100% { box-shadow: 0 0 10px var(--neon-pink), 0 0 20px rgba(255, 0, 255, 0.3) inset; } } .close-button { animation: pulse 2s infinite; } .popup.closing { transform: perspective(800px) rotateX(10deg); opacity: 0; transition: transform 0.5s ease-out, opacity 0.5s ease-out; } @media (max-width: 700px) { .popup { width: 90%; padding: 20px; } .close-button { --button-size: 50px; } .popup-title { font-size: 20px; } } </style> </head> <body> <div class="game-environment"> <div class="hex-grid"></div> <div class="scan-line"></div> <div class="popup" id="gamePopup"> <div class="popup-header"> <h2 class="popup-title">NEURAL SURGE DETECTED</h2> <button class="close-button" id="closeButton" aria-label="Close pop-up"> <div class="glitch-container"> <div class="glitch-effect"></div> </div> </button> <span class="close-label">terminate</span> </div> <div class="popup-content"> <p>Commander, we've traced a <strong>cyberspace anomaly</strong> in sector VI-341. Our scanners indicate it's emanating from the quantum network node.</p> <p>Warning: Hostile neuroviruses detected. Cybernetic defense systems activated. Proceed with caution.</p> <p>Server status: <span style="color: var(--neon-pink);">UNSTABLE</span></p> </div> <div class="action-buttons"> <button class="action-btn">Deploy Firewalls</button> <button class="action-btn confirm">Initiate Countermeasure</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const closeButton = document.getElementById('closeButton'); const popup = document.getElementById('gamePopup'); const actionButtons = document.querySelectorAll('.action-btn'); // Function to create ripple effect function createRipple(e) { const button = e.currentTarget; const ripple = document.createElement('span'); const rect = button.getBoundingClientRect(); const diameter = Math.max(rect.width, rect.height); const radius = diameter / 2; ripple.style.width = ripple.style.height = `${diameter}px`; ripple.style.left = `${e.clientX - rect.left - radius}px`; ripple.style.top = `${e.clientY - rect.top - radius}px`; ripple.classList.add('ripple'); // Remove existing ripples const existingRipple = button.querySelector('.ripple'); if (existingRipple) { existingRipple.remove(); } button.appendChild(ripple); // Remove the ripple after animation completes setTimeout(() => { ripple.remove(); }, 800); } // Function to create glitch effect function createGlitch(element) { const glitchElement = element.querySelector('.glitch-effect'); glitchElement.style.opacity = '0.7'; glitchElement.style.animation = 'glitch 0.5s ease-out forwards'; setTimeout(() => { glitchElement.style.opacity = '0'; glitchElement.style.animation = 'none'; }, 500); } // Close button events closeButton.addEventListener('mouseenter', (e) => { createGlitch(e.currentTarget); }); closeButton.addEventListener('click', (e) => { createRipple(e); createGlitch(e.currentTarget); popup.classList.add('closing'); // Reset after animation setTimeout(() => { popup.classList.remove('closing'); }, 1000); }); // Action button events actionButtons.forEach(button => { button.addEventListener('click', (e) => { createRipple(e); }); }); // Add key event listener to close with ESC key document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { createGlitch(closeButton); popup.classList.add('closing'); setTimeout(() => { popup.classList.remove('closing'); }, 1000); } }); // Random glitch effect occasionally function randomGlitch() { const interval = Math.random() * 5000 + 2000; // Random interval between 2-7 seconds setTimeout(() => { if (Math.random() > 0.5) { // 50% chance to trigger glitch createGlitch(closeButton); } randomGlitch(); }, interval); } randomGlitch(); }); </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: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { width: 100%; height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; background-color: #f9f7fe; overflow: hidden; } .app-container { width: 100%; max-width: 680px; height: 680px; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; } .modal-container { width: 100%; max-width: 500px; background-color: #ffffff; border-radius: 24px; box-shadow: 0 10px 30px rgba(176, 190, 224, 0.3); padding: 32px; position: relative; opacity: 0; transform: translateY(20px) scale(0.98); transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); } .modal-container.visible { opacity: 1; transform: translateY(0) scale(1); } .modal-header { text-align: center; margin-bottom: 24px; } .modal-header h2 { font-size: 24px; color: #3d4d6b; font-weight: 600; margin-bottom: 12px; } .modal-header p { font-size: 16px; color: #6b7b99; line-height: 1.5; } .modal-content { margin-bottom: 32px; } .wellness-input { width: 100%; padding: 16px; border: 2px solid #e8ecf4; border-radius: 12px; font-size: 16px; color: #3d4d6b; transition: border-color 0.3s ease; margin-bottom: 16px; resize: none; } .wellness-input:focus { outline: none; border-color: #b8c4e0; } .wellness-input::placeholder { color: #a9b4cb; } .button-container { display: flex; justify-content: center; } .close-button { position: relative; padding: 14px 32px; background: linear-gradient(135deg, #e2f0ff, #d8e7fa); border: none; border-radius: 50px; color: #5278b7; font-size: 16px; font-weight: 600; cursor: pointer; overflow: hidden; z-index: 1; transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease; box-shadow: 0 4px 16px rgba(176, 190, 224, 0.4); outline: none; } .close-button:before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, #d2e4f7, #c8dcf5); opacity: 0; transition: opacity 0.3s ease; border-radius: 50px; z-index: -1; } .close-button:hover { transform: translateY(-3px) scale(1.02); box-shadow: 0 8px 20px rgba(176, 190, 224, 0.5); } .close-button:hover:before { opacity: 1; } .close-button:active { transform: translateY(1px) scale(0.98); box-shadow: 0 2px 10px rgba(176, 190, 224, 0.3); } .button-icon { display: inline-block; margin-right: 8px; width: 20px; height: 20px; vertical-align: middle; position: relative; top: -1px; } .open-modal { position: absolute; top: 20px; right: 20px; background: #a9c5e9; border: none; border-radius: 50%; width: 50px; height: 50px; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease, background-color 0.3s ease; } .open-modal:hover { background: #94b6e2; transform: scale(1.05); } .open-modal i { color: white; font-size: 24px; } .app-illustration { width: 320px; height: 320px; margin-bottom: 20px; opacity: 0.9; } .app-title { font-size: 32px; color: #3d4d6b; margin-bottom: 12px; text-align: center; } .app-subtitle { font-size: 18px; color: #6b7b99; text-align: center; max-width: 420px; line-height: 1.5; } .ripple-effect { position: absolute; border-radius: 50%; background-color: rgba(255, 255, 255, 0.7); transform: scale(0); animation: ripple 0.6s linear; pointer-events: none; } @keyframes ripple { to { transform: scale(2.5); opacity: 0; } } .success-checkmark { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0); width: 80px; height: 80px; background: #e8f6ed; border-radius: 50%; display: flex; align-items: center; justify-content: center; z-index: 10; transition: transform 0.5s cubic-bezier(0.17, 0.67, 0.83, 0.67); opacity: 0; box-shadow: 0 5px 25px rgba(101, 213, 157, 0.5); } .success-checkmark svg { width: 40px; height: 40px; } .success-checkmark.show { transform: translate(-50%, -50%) scale(1); opacity: 1; } .pattern-bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0.04; pointer-events: none; background: radial-gradient(circle at 10% 20%, #b1c8e8 0%, transparent 20%), radial-gradient(circle at 90% 80%, #a9c5e9 0%, transparent 20%), radial-gradient(circle at 50% 50%, #94b6e2 0%, transparent 30%); z-index: -1; } </style> </head> <body> <div class="pattern-bg"></div> <div class="app-container"> <div class="app-illustration"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600" fill="none"> <circle cx="300" cy="300" r="280" fill="#EDF4FC" /> <path d="M300 150C218.2 150 150 218.2 150 300C150 381.8 218.2 450 300 450C381.8 450 450 381.8 450 300C450 218.2 381.8 150 300 150ZM300 420C234.7 420 180 365.3 180 300C180 234.7 234.7 180 300 180C365.3 180 420 234.7 420 300C420 365.3 365.3 420 300 420Z" fill="#A9C5E9" fill-opacity="0.6" /> <path d="M345 270C357.7 270 368 259.7 368 247C368 234.3 357.7 224 345 224C332.3 224 322 234.3 322 247C322 259.7 332.3 270 345 270Z" fill="#7FA3D8" /> <path d="M255 270C267.7 270 278 259.7 278 247C278 234.3 267.7 224 255 224C242.3 224 232 234.3 232 247C232 259.7 242.3 270 255 270Z" fill="#7FA3D8" /> <path d="M300 360C334.1 360 362.5 342.6 376 316.7C378.4 312.1 374.9 306.2 369.8 306.9C345.2 310.5 323.1 312 300 312C276.9 312 254.8 310.5 230.2 306.9C225.1 306.2 221.6 312.1 224 316.7C237.5 342.6 265.9 360 300 360Z" fill="#7FA3D8" /> </svg> </div> <h1 class="app-title">MindfulMe</h1> <p class="app-subtitle">Your daily companion for mental wellness tracking and mindful reflection.</p> <button class="open-modal" id="openModalBtn"> <i>+</i> </button> <div class="modal-container" id="modal"> <div class="modal-header"> <h2>Daily Reflection</h2> <p>Take a moment to reflect on your emotions and mental state today.</p> </div> <div class="modal-content"> <textarea class="wellness-input" rows="4" placeholder="How are you feeling today? What made you smile? What challenged you?"></textarea> <textarea class="wellness-input" rows="2" placeholder="Note one thing you're grateful for today..."></textarea> </div> <div class="button-container"> <button class="close-button" id="closeModalBtn"> <span class="button-icon"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="stroke: #5278b7; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;"> <path d="M20 6L9 17L4 12"></path> </svg> </span> Save & Close </button> </div> </div> </div> <div class="success-checkmark" id="successCheckmark"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20 6L9 17L4 12" stroke="#65D59D" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/> </svg> </div> <script> document.addEventListener('DOMContentLoaded', function() { const modal = document.getElementById('modal'); const openModalBtn = document.getElementById('openModalBtn'); const closeModalBtn = document.getElementById('closeModalBtn'); const successCheckmark = document.getElementById('successCheckmark'); openModalBtn.addEventListener('click', function() { modal.classList.add('visible'); }); // Add ripple effect to the close button closeModalBtn.addEventListener('click', function(e) { const button = e.currentTarget; const x = e.clientX - button.getBoundingClientRect().left; const y = e.clientY - button.getBoundingClientRect().top; const ripple = document.createElement('span'); ripple.classList.add('ripple-effect'); ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; button.appendChild(ripple); // Show success checkmark successCheckmark.classList.add('show'); // Hide modal with animation setTimeout(() => { modal.style.transform = 'translateY(10px) scale(0.98)'; modal.style.opacity = '0'; setTimeout(() => { modal.classList.remove('visible'); // Reset modal style after animation modal.style.transform = ''; modal.style.opacity = ''; // Hide checkmark after a delay setTimeout(() => { successCheckmark.classList.remove('show'); }, 1000); }, 300); }, 200); setTimeout(() => { ripple.remove(); }, 600); }); // Add hover effect to the close button closeModalBtn.addEventListener('mousemove', function(e) { const button = e.currentTarget; const rect = button.getBoundingClientRect(); // Calculate position relative to the button's center const x = e.clientX - rect.left - rect.width / 2; const y = e.clientY - rect.top - rect.height / 2; // Apply subtle tilt effect const tiltX = y / 10; const tiltY = -x / 10; button.style.transform = `perspective(300px) rotateX(${tiltX}deg) rotateY(${tiltY}deg) translateY(-3px) scale(1.02)`; }); closeModalBtn.addEventListener('mouseleave', function(e) { e.currentTarget.style.transform = ''; }); // Make textarea auto-resize const textareas = document.querySelectorAll('.wellness-input'); textareas.forEach(textarea => { textarea.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = (this.scrollHeight) + 'px'; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary-color: #4A90E2; --secondary-color: #F3B562; --tertiary-color: #6BD5E1; --bg-color: #FFFFFF; --text-color: #333333; --success-color: #4CAF50; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f9f9f9; display: flex; justify-content: center; align-items: center; min-height: 700px; overflow: hidden; padding: 20px; } .container { width: 100%; max-width: 650px; height: 650px; display: flex; flex-direction: column; justify-content: center; align-items: center; position: relative; } .popup-trigger { background-color: var(--primary-color); color: white; border: none; padding: 15px 30px; border-radius: 50px; font-size: 18px; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 4px 12px rgba(74, 144, 226, 0.3); outline: none; position: relative; overflow: hidden; } .popup-trigger:hover { transform: translateY(-3px); box-shadow: 0 6px 15px rgba(74, 144, 226, 0.4); } .popup-trigger:active { transform: translateY(0); } .popup-trigger::after { content: ''; position: absolute; top: 50%; left: 50%; width: 5px; height: 5px; background: rgba(255, 255, 255, 0.7); opacity: 0; border-radius: 100%; transform: scale(1, 1) translate(-50%); transform-origin: 50% 50%; } .popup-trigger:focus:not(:active)::after { animation: ripple 1s ease-out; } @keyframes ripple { 0% { transform: scale(0, 0); opacity: 0.5; } 100% { transform: scale(30, 30); opacity: 0; } } .backdrop { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(3px); opacity: 0; transition: opacity 0.4s ease; visibility: hidden; z-index: 10; } .backdrop.active { opacity: 1; visibility: visible; } .module-popup { position: absolute; width: 90%; max-width: 600px; background: var(--bg-color); border-radius: 20px; padding: 30px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); transform: scale(0.8); opacity: 0; transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); visibility: hidden; z-index: 20; overflow: hidden; } .module-popup.active { transform: scale(1); opacity: 1; visibility: visible; } .popup-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; position: relative; } .popup-title { font-size: 24px; color: var(--text-color); font-weight: 600; } .close-btn { position: relative; width: 40px; height: 40px; border: none; background: transparent; cursor: pointer; outline: none; transition: all 0.3s ease; } .close-btn-circle { position: absolute; top: 0; left: 0; width: 40px; height: 40px; border-radius: 50%; background: #f0f0f0; transition: all 0.3s ease; } .close-btn:hover .close-btn-circle { background: #e0e0e0; transform: scale(1.1); } .close-btn-x { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 24px; height: 24px; } .close-btn-line { position: absolute; width: 100%; height: 3px; background: none; top: 50%; left: 0; margin-top: -1.5px; stroke: var(--text-color); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 30; stroke-dashoffset: 0; transition: all 0.3s ease; } .close-btn:hover .close-btn-line { stroke: var(--primary-color); } .close-btn-line1 { transform: rotate(45deg); } .close-btn-line2 { transform: rotate(-45deg); } .popup-content { margin-bottom: 20px; } .module-title { font-size: 20px; color: var(--text-color); margin-bottom: 15px; font-weight: 500; } .module-description { color: #666; line-height: 1.6; margin-bottom: 20px; } .module-progress { background: #f0f0f0; height: 8px; border-radius: 20px; margin-bottom: 10px; overflow: hidden; } .progress-bar { height: 100%; background: var(--primary-color); width: 0; border-radius: 20px; transition: width 1.5s ease-in-out; } .progress-text { font-size: 14px; color: #777; text-align: right; } .module-sections { margin-top: 20px; } .section-item { display: flex; align-items: center; padding: 12px 15px; border-radius: 10px; background: #f9f9f9; margin-bottom: 10px; cursor: pointer; transition: all 0.3s ease; } .section-item:hover { background: #f0f0f0; transform: translateX(5px); } .section-icon { width: 30px; height: 30px; border-radius: 50%; display: flex; justify-content: center; align-items: center; margin-right: 12px; flex-shrink: 0; } .section-icon.video { background: rgba(74, 144, 226, 0.15); color: var(--primary-color); } .section-icon.quiz { background: rgba(243, 181, 98, 0.15); color: var(--secondary-color); } .section-icon.reading { background: rgba(107, 213, 225, 0.15); color: var(--tertiary-color); } .section-icon.completed { background: rgba(76, 175, 80, 0.15); color: var(--success-color); } .section-content { flex-grow: 1; } .section-title { font-weight: 500; color: var(--text-color); margin-bottom: 4px; } .section-meta { display: flex; justify-content: space-between; font-size: 13px; color: #888; } .continue-btn { display: inline-block; background: var(--primary-color); color: white; border: none; padding: 12px 25px; border-radius: 50px; margin-top: 20px; cursor: pointer; transition: all 0.3s ease; font-weight: 500; } .continue-btn:hover { background: #3a7bc8; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(74, 144, 226, 0.3); } .pen-sparkle { position: absolute; width: 20px; height: 20px; background: rgba(255, 255, 255, 0.8); border-radius: 50%; pointer-events: none; opacity: 0; } @keyframes float { 0% { transform: translateY(0) rotate(0deg); opacity: 1; } 100% { transform: translateY(-50px) rotate(360deg); opacity: 0; } } .doodle { position: absolute; z-index: 1; opacity: 0.1; pointer-events: none; } .doodle-1 { top: 30px; right: 20px; width: 100px; height: 100px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 24 24' fill='none' stroke='%234A90E2' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'%3E%3C/circle%3E%3Cpath d='M 8 8 Q 12 4 16 8 Q 20 12 16 16 Q 12 20 8 16 Q 4 12 8 8'%3E%3C/path%3E%3C/svg%3E") no-repeat; } .doodle-2 { bottom: 40px; left: 30px; width: 80px; height: 80px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 24 24' fill='none' stroke='%23F3B562' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M 4 12 Q 8 4 12 12 Q 16 20 20 12'%3E%3C/path%3E%3Cpath d='M 4 17 Q 8 9 12 17 Q 16 25 20 17'%3E%3C/path%3E%3C/svg%3E") no-repeat; } .close-animation { animation: closeAnim 0.4s forwards; } @keyframes closeAnim { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(0.8); opacity: 0; } } .notification { position: fixed; top: 20px; right: 20px; background: white; border-left: 4px solid var(--success-color); padding: 15px 20px; border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); transform: translateX(120%); transition: transform 0.4s ease; z-index: 100; } .notification.active { transform: translateX(0); } @media (max-width: 600px) { .popup-title { font-size: 20px; } .module-title { font-size: 18px; } .section-item { padding: 10px; } .module-popup { padding: 20px; width: 95%; } } @media (max-width: 400px) { .section-meta { flex-direction: column; } .popup-title { font-size: 18px; } } </style> </head> <body> <div class="container"> <button class="popup-trigger">Open Module Overview</button> <div class="backdrop"></div> <div class="module-popup"> <div class="doodle doodle-1"></div> <div class="doodle doodle-2"></div> <div class="popup-header"> <h2 class="popup-title">Module Overview</h2> <button class="close-btn" aria-label="Close module popup"> <div class="close-btn-circle"></div> <div class="close-btn-x"> <svg class="close-btn-line close-btn-line1" viewBox="0 0 24 24"> <path d="M 4 4 L 20 20" fill="none" stroke-linecap="round"></path> </svg> <svg class="close-btn-line close-btn-line2" viewBox="0 0 24 24"> <path d="M 20 4 L 4 20" fill="none" stroke-linecap="round"></path> </svg> </div> </button> </div> <div class="popup-content"> <h3 class="module-title">Introduction to User Experience Design</h3> <p class="module-description">Explore the foundations of UX design through practical examples and guided exercises. You'll learn core principles and apply them to real-world scenarios.</p> <div class="module-progress"> <div class="progress-bar"></div> </div> <div class="progress-text">2 of 5 sections completed (40%)</div> <div class="module-sections"> <div class="section-item"> <div class="section-icon completed"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 6L9 17l-5-5"></path> </svg> </div> <div class="section-content"> <div class="section-title">Core UX Principles</div> <div class="section-meta"> <span>Video Lecture • 12 mins</span> <span>Completed</span> </div> </div> </div> <div class="section-item"> <div class="section-icon completed"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 6L9 17l-5-5"></path> </svg> </div> <div class="section-content"> <div class="section-title">User Research Methods</div> <div class="section-meta"> <span>Reading • 10 mins</span> <span>Completed</span> </div> </div> </div> <div class="section-item current"> <div class="section-icon quiz"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" 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> <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path> <line x1="12" y1="17" x2="12.01" y2="17"></line> </svg> </div> <div class="section-content"> <div class="section-title">Persona Development Quiz</div> <div class="section-meta"> <span>Quiz • 5 questions</span> <span>In Progress</span> </div> </div> </div> <div class="section-item"> <div class="section-icon video"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polygon points="5 3 19 12 5 21 5 3"></polygon> </svg> </div> <div class="section-content"> <div class="section-title">Wireframing Basics</div> <div class="section-meta"> <span>Video Workshop • 18 mins</span> <span>Not started</span> </div> </div> </div> <div class="section-item"> <div class="section-icon reading"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path> <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path> </svg> </div> <div class="section-content"> <div class="section-title">Case Study: UX Redesign</div> <div class="section-meta"> <span>Reading • 15 mins</span> <span>Not started</span> </div> </div> </div> </div> <button class="continue-btn">Continue Learning</button> </div> </div> <div class="notification"> Module progress saved! You can continue later. </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const popup = document.querySelector('.module-popup'); const backdrop = document.querySelector('.backdrop'); const closeBtn = document.querySelector('.close-btn'); const trigger = document.querySelector('.popup-trigger'); const continueBtn = document.querySelector('.continue-btn'); const progressBar = document.querySelector('.progress-bar'); const notification = document.querySelector('.notification'); // Function to open popup with animation function openPopup() { backdrop.classList.add('active'); popup.classList.add('active'); // Animate progress bar setTimeout(() => { progressBar.style.width = '40%'; }, 300); // Add sparkles to the close button createSparkleEffect(closeBtn); } // Function to close popup with animation function closePopup() { popup.classList.add('close-animation'); backdrop.classList.remove('active'); setTimeout(() => { popup.classList.remove('active'); popup.classList.remove('close-animation'); }, 400); } // Function to create sparkle effect function createSparkleEffect(element) { for (let i = 0; i < 3; i++) { setTimeout(() => { const sparkle = document.createElement('div'); sparkle.classList.add('pen-sparkle'); // Random position around the element const angle = Math.random() * Math.PI * 2; const radius = 25 + Math.random() * 10; const xPos = Math.cos(angle) * radius; const yPos = Math.sin(angle) * radius; sparkle.style.left = `calc(50% + ${xPos}px)`; sparkle.style.top = `calc(50% + ${yPos}px)`; sparkle.style.width = `${5 + Math.random() * 8}px`; sparkle.style.height = sparkle.style.width; element.appendChild(sparkle); // Animate and remove sparkle sparkle.style.animation = `float ${0.8 + Math.random() * 0.6}s forwards`; setTimeout(() => { sparkle.remove(); }, 1500); }, i * 300); } } // Show notification function function showNotification() { notification.classList.add('active'); setTimeout(() => { notification.classList.remove('active'); }, 3000); } // Event listeners trigger.addEventListener('click', openPopup); closeBtn.addEventListener('click', () => { closePopup(); showNotification(); }); backdrop.addEventListener('click', closePopup); continueBtn.addEventListener('click', closePopup); // Hover effect for section items const sectionItems = document.querySelectorAll('.section-item'); sectionItems.forEach(item => { item.addEventListener('mouseenter', () => { if (!item.classList.contains('current')) return; createSparkleEffect(item); }); }); // Sketch-like hover effect for close button closeBtn.addEventListener('mousemove', (e) => { const btn = closeBtn.querySelector('.close-btn-circle'); const rect = btn.getBoundingClientRect(); const x = e.clientX - rect.left - rect.width / 2; const y = e.clientY - rect.top - rect.height / 2; const distance = Math.sqrt(x * x + y * y); if (distance < 30) { const scale = 1 + (30 - distance) / 100; btn.style.transform = `scale(${scale})`; } else { btn.style.transform = 'scale(1)'; } }); closeBtn.addEventListener('mouseleave', () => { const btn = closeBtn.querySelector('.close-btn-circle'); btn.style.transform = 'scale(1)'; }); // Pen-sketching effect const lines = document.querySelectorAll('.close-btn-line path'); lines.forEach(line => { const length = line.getTotalLength(); line.style.strokeDasharray = length; line.style.strokeDashoffset = length; }); closeBtn.addEventListener('mouseenter', () => { lines.forEach(line => { line.style.strokeDashoffset = 0; line.style.transition = 'stroke-dashoffset 0.6s ease'; }); }); closeBtn.addEventListener('mouseleave', () => { lines.forEach(line => { const length = line.getTotalLength(); line.style.strokeDashoffset = length; }); }); // Current section highlight const currentSection = document.querySelector('.section-item.current'); if (currentSection) { currentSection.style.borderLeft = '3px solid var(--secondary-color)'; currentSection.style.paddingLeft = '12px'; } }); </script> </body> </html>
<html> <head> <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: 700px; background-color: #f0f3f8; background-image: radial-gradient(#2c3e50 1px, transparent 1px), radial-gradient(#2c3e50 1px, transparent 1px); background-size: 40px 40px; background-position: 0 0, 20px 20px; background-repeat: repeat; opacity: 1; padding: 20px; } .dashboard { width: 100%; max-width: 650px; height: 600px; background-color: #1a2233; border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); padding: 20px; display: flex; flex-direction: column; position: relative; overflow: hidden; } .dashboard-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .dashboard-title { color: #fff; font-size: 1.5rem; font-weight: 600; display: flex; align-items: center; } .dashboard-title svg { margin-right: 12px; } .dashboard-user { display: flex; align-items: center; color: rgba(255, 255, 255, 0.7); font-size: 0.9rem; } .user-avatar { width: 30px; height: 30px; background-color: #3498db; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; margin-right: 8px; font-weight: bold; } .dashboard-content { display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(2, 1fr); gap: 15px; flex-grow: 1; } .widget { background-color: rgba(255, 255, 255, 0.05); border-radius: 8px; padding: 15px; display: flex; flex-direction: column; position: relative; } .widget-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; font-size: 0.9rem; color: rgba(255, 255, 255, 0.7); } .widget-value { font-size: 1.6rem; font-weight: 700; color: #fff; margin-top: auto; } .widget-change { font-size: 0.85rem; margin-top: 5px; } .positive { color: #2ecc71; } .negative { color: #e74c3c; } /* Alert Modal */ .alert-modal { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; max-width: 500px; background-color: #2c3e50; border-radius: 10px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3), 0 0 0 1000px rgba(0, 0, 0, 0.6); z-index: 100; padding: 25px; border-left: 5px solid #e74c3c; animation: alertAppear 0.3s ease-out forwards; opacity: 0; transform: translate(-50%, -50%) scale(0.9); } @keyframes alertAppear { to { opacity: 1; transform: translate(-50%, -50%) scale(1); } } .alert-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px; } .alert-title { display: flex; align-items: center; color: #fff; font-size: 1.3rem; font-weight: 700; } .alert-icon { margin-right: 10px; background-color: rgba(231, 76, 60, 0.2); width: 30px; height: 30px; border-radius: 50%; display: flex; justify-content: center; align-items: center; } /* Close Button - Key Component */ .close-button { position: relative; width: 40px; height: 40px; border-radius: 8px; background-color: #e74c3c; border: none; cursor: pointer; outline: none; display: flex; justify-content: center; align-items: center; transition: all 0.2s cubic-bezier(0.165, 0.84, 0.44, 1); transform-origin: center; overflow: hidden; box-shadow: 0 2px 8px rgba(231, 76, 60, 0.4); } .close-button:before, .close-button:after { content: ''; position: absolute; width: 20px; height: 2px; background-color: #fff; border-radius: 1px; transition: all 0.2s cubic-bezier(0.165, 0.84, 0.44, 1); } .close-button:before { transform: rotate(45deg); } .close-button:after { transform: rotate(-45deg); } .close-button:hover { transform: scale(1.05); background-color: #ff5546; box-shadow: 0 4px 12px rgba(231, 76, 60, 0.6); } .close-button:focus { box-shadow: 0 0 0 3px rgba(231, 76, 60, 0.5), 0 4px 12px rgba(231, 76, 60, 0.6); } .close-button:active { transform: scale(0.95); background-color: #d44637; box-shadow: 0 2px 4px rgba(231, 76, 60, 0.4); } .close-button:hover:before, .close-button:hover:after { width: 22px; } .close-button:active:before, .close-button:active:after { width: 18px; } .close-button .ripple { position: absolute; width: 5px; height: 5px; background-color: rgba(255, 255, 255, 0.5); border-radius: 50%; transform: scale(0); animation: ripple 0.6s linear forwards; } @keyframes ripple { to { transform: scale(30); opacity: 0; } } .alert-content { color: rgba(255, 255, 255, 0.8); margin-bottom: 20px; line-height: 1.5; } .alert-metadata { background-color: rgba(255, 255, 255, 0.05); border-radius: 6px; padding: 12px; color: rgba(255, 255, 255, 0.7); font-size: 0.9rem; } .alert-actions { display: flex; justify-content: flex-end; gap: 12px; margin-top: 20px; } .btn { padding: 10px 16px; border-radius: 6px; font-weight: 600; font-size: 0.95rem; cursor: pointer; transition: all 0.2s; border: none; outline: none; } .btn-primary { background-color: #3498db; color: white; } .btn-primary:hover { background-color: #2980b9; } .btn-secondary { background-color: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.8); } .btn-secondary:hover { background-color: rgba(255, 255, 255, 0.15); } /* Responsive adjustments */ @media (max-width: 600px) { .dashboard-content { grid-template-columns: 1fr; grid-template-rows: repeat(4, 1fr); } .alert-actions { flex-direction: column; } .btn { width: 100%; } .alert-modal { width: 95%; } } .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.6); z-index: 50; } </style> </head> <body> <div class="dashboard"> <div class="dashboard-header"> <div class="dashboard-title"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M4 13H10C10.55 13 11 12.55 11 12V4C11 3.45 10.55 3 10 3H4C3.45 3 3 3.45 3 4V12C3 12.55 3.45 13 4 13ZM4 21H10C10.55 21 11 20.55 11 20V16C11 15.45 10.55 15 10 15H4C3.45 15 3 15.45 3 16V20C3 20.55 3.45 21 4 21ZM14 21H20C20.55 21 21 20.55 21 20V12C21 11.45 20.55 11 20 11H14C13.45 11 13 11.45 13 12V20C13 20.55 13.45 21 14 21ZM13 4V8C13 8.55 13.45 9 14 9H20C20.55 9 21 8.55 21 8V4C21 3.45 20.55 3 20 3H14C13.45 3 13 3.45 13 4Z" fill="#3498db"/> </svg> Apex Financial Dashboard </div> <div class="dashboard-user"> <div class="user-avatar">JD</div> <span>John Doe</span> </div> </div> <div class="dashboard-content"> <div class="widget"> <div class="widget-header"> <span>PORTFOLIO VALUE</span> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M13 7H11V9H13V7ZM13 11H11V17H13V11ZM12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12 20C7.59 20 4 16.41 4 12C4 7.59 7.59 4 12 4C16.41 4 20 7.59 20 12C20 16.41 16.41 20 12 20Z" fill="#3498db"/> </svg> </div> <div class="widget-value">$1,342,568</div> <div class="widget-change positive">+2.4% ($31,254)</div> </div> <div class="widget"> <div class="widget-header"> <span>TODAY'S GAINS/LOSSES</span> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M13 7H11V9H13V7ZM13 11H11V17H13V11ZM12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12 20C7.59 20 4 16.41 4 12C4 7.59 7.59 4 12 4C16.41 4 20 7.59 20 12C20 16.41 16.41 20 12 20Z" fill="#3498db"/> </svg> </div> <div class="widget-value negative">-$4,285</div> <div class="widget-change negative">-0.32% today</div> </div> <div class="widget"> <div class="widget-header"> <span>CASH BALANCE</span> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M13 7H11V9H13V7ZM13 11H11V17H13V11ZM12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12 20C7.59 20 4 16.41 4 12C4 7.59 7.59 4 12 4C16.41 4 20 7.59 20 12C20 16.41 16.41 20 12 20Z" fill="#3498db"/> </svg> </div> <div class="widget-value">$78,542</div> <div class="widget-change">Available for investment</div> </div> <div class="widget"> <div class="widget-header"> <span>OPEN POSITIONS</span> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M13 7H11V9H13V7ZM13 11H11V17H13V11ZM12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12 20C7.59 20 4 16.41 4 12C4 7.59 7.59 4 12 4C16.41 4 20 7.59 20 12C20 16.41 16.41 20 12 20Z" fill="#3498db"/> </svg> </div> <div class="widget-value">24</div> <div class="widget-change">12 up, 12 down</div> </div> </div> </div> <div class="overlay" id="overlay"></div> <div class="alert-modal" id="alert-modal"> <div class="alert-header"> <div class="alert-title"> <div class="alert-icon"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 5.99L19.53 19H4.47L12 5.99ZM12 2L1 21H23L12 2ZM13 16H11V18H13V16ZM13 10H11V14H13V10Z" fill="#e74c3c"/> </svg> </div> <span>Margin Call Alert</span> </div> <button class="close-button" id="closeButton" aria-label="Close alert"></button> </div> <div class="alert-content"> <p>Your margin level has fallen below the required maintenance margin of 25%. Immediate action is required to avoid automatic liquidation of positions.</p> <p>Current margin level: <strong>19.8%</strong></p> </div> <div class="alert-metadata"> <p>Account: #87259413 • Time: 14:32:45 GMT • Risk level: HIGH</p> <p>Estimated liquidation threshold: $1,232,504</p> </div> <div class="alert-actions"> <button class="btn btn-secondary">View Positions</button> <button class="btn btn-primary">Deposit Funds Now</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const closeButton = document.getElementById('closeButton'); const alertModal = document.getElementById('alert-modal'); const overlay = document.getElementById('overlay'); // Add ripple effect to close button on click closeButton.addEventListener('click', function(e) { const ripple = document.createElement('span'); ripple.classList.add('ripple'); // Get position relative to button const rect = closeButton.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; closeButton.appendChild(ripple); // Remove the alert modal with animation alertModal.style.animation = 'alertAppear 0.3s ease-in-out reverse forwards'; overlay.style.opacity = '0'; // Clean up DOM after animation setTimeout(() => { alertModal.remove(); overlay.remove(); ripple.remove(); }, 300); }); // Focus accessibility closeButton.addEventListener('focus', function() { closeButton.style.boxShadow = '0 0 0 3px rgba(231, 76, 60, 0.5), 0 4px 12px rgba(231, 76, 60, 0.6)'; }); closeButton.addEventListener('blur', function() { closeButton.style.boxShadow = '0 2px 8px rgba(231, 76, 60, 0.4)'; }); // Add keyboard functionality document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { closeButton.click(); } }); // Enable overlay click to dismiss overlay.addEventListener('click', function() { closeButton.click(); }); }); </script> </body> </html>