Tooltips are essential for enhancing user experience by providing additional information without cluttering the interface. They offer a seamless way to guide users through complex functionalities.
In this article, we will explore 10 exemplary tooltip designs that can inspire your next project. Each example showcases unique approaches to delivering helpful, unobtrusive information.
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
Designers and developers love Subframe for its drag-and-drop interface and intuitive, responsive canvas. Create pixel-perfect UI effortlessly, ensuring every tooltip is both functional and beautiful.
Ready to elevate your design game? Start for free 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
Unlock the power of Subframe and design stunning UIs with ease. Our drag-and-drop editor and beautifully crafted components make creating pixel-perfect tooltips and interfaces a breeze.
Experience unparalleled efficiency and start designing immediately. Ready to elevate your projects? Start for free today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Analytics Dashboard</title> <style> :root { --primary: #4361ee; --primary-light: #4895ef; --secondary: #560bad; --success: #0ead69; --warning: #f9c74f; --danger: #ef476f; --light: #f8f9fa; --dark: #212529; --gray: #6c757d; --gray-light: #e9ecef; --shadow: 0 4px 15px rgba(0, 0, 0, 0.05); --shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.1); --transition: all 0.25s cubic-bezier(0.645, 0.045, 0.355, 1); } * { 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 { background-color: #fafafa; color: var(--dark); width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; } .dashboard { width: 100%; max-width: 700px; min-height: 600px; background-color: white; border-radius: 12px; box-shadow: var(--shadow); padding: 1.5rem; position: relative; overflow: hidden; display: flex; flex-direction: column; gap: 1.5rem; } .dashboard-header { display: flex; justify-content: space-between; align-items: center; } .dashboard-title { font-size: 1.5rem; font-weight: 700; color: var(--dark); } .time-filter { display: flex; gap: 0.5rem; background: var(--gray-light); border-radius: 8px; padding: 0.25rem; } .time-filter button { background: none; border: none; padding: 0.5rem 0.75rem; border-radius: 6px; cursor: pointer; font-size: 0.875rem; font-weight: 500; color: var(--gray); transition: var(--transition); } .time-filter button.active { background-color: white; color: var(--primary); box-shadow: 0 2px 8px rgba(67, 97, 238, 0.15); } .dashboard-content { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; } .dashboard-card { background: white; border-radius: 10px; box-shadow: var(--shadow); padding: 1.25rem; transition: var(--transition); cursor: pointer; position: relative; overflow: hidden; border: 1px solid var(--gray-light); } .dashboard-card:hover { box-shadow: var(--shadow-hover); transform: translateY(-2px); } .card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem; } .card-title { font-size: 0.875rem; font-weight: 600; color: var(--gray); } .card-icon { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; border-radius: 8px; color: white; } .card-value { font-size: 1.75rem; font-weight: 700; margin-bottom: 0.5rem; } .card-description { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--gray); } .card-trend { display: flex; align-items: center; gap: 0.25rem; font-weight: 600; font-size: 0.75rem; padding: 0.25rem 0.5rem; border-radius: 12px; } .trend-up { background-color: rgba(14, 173, 105, 0.1); color: var(--success); } .trend-down { background-color: rgba(239, 71, 111, 0.1); color: var(--danger); } .chart-container { height: 100px; margin-top: 1rem; position: relative; } .chart-line { position: absolute; bottom: 0; left: 0; width: 100%; height: 50px; stroke: var(--primary-light); stroke-width: 2px; stroke-linecap: round; stroke-linejoin: round; fill: none; } .tooltip { position: absolute; background: white; border-radius: 6px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); padding: 0.75rem 1rem; max-width: 200px; opacity: 0; transform: translateY(10px); pointer-events: none; transition: opacity 0.2s ease, transform 0.2s ease; z-index: 10; } .tooltip.visible { opacity: 1; transform: translateY(0); } .tooltip-title { font-size: 0.75rem; font-weight: 600; color: var(--gray); margin-bottom: 0.25rem; } .tooltip-value { font-size: 1.125rem; font-weight: 700; margin-bottom: 0.25rem; } .tooltip-date { font-size: 0.75rem; color: var(--gray); } .data-point { position: absolute; width: 10px; height: 10px; background: white; border: 2px solid var(--primary); border-radius: 50%; cursor: pointer; transition: transform 0.2s ease; } .data-point:hover { transform: scale(1.5); } .chart-area { position: absolute; bottom: 0; left: 0; width: 100%; height: 50px; fill: url(#gradient); opacity: 0.2; } .activity-grid { display: grid; grid-template-columns: 1fr; margin-top: 1rem; } .activity-item { display: flex; align-items: center; padding: 0.75rem 0; border-bottom: 1px solid var(--gray-light); } .activity-icon { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: 8px; margin-right: 0.75rem; } .activity-details { flex: 1; } .activity-title { font-size: 0.875rem; font-weight: 600; margin-bottom: 0.25rem; } .activity-description { font-size: 0.75rem; color: var(--gray); } .activity-time { font-size: 0.75rem; color: var(--gray); } @media (max-width: 640px) { .dashboard { padding: 1rem; gap: 1rem; } .dashboard-content { grid-template-columns: 1fr; } .dashboard-title { font-size: 1.25rem; } .time-filter button { padding: 0.375rem 0.5rem; font-size: 0.75rem; } } /* Sparkles animation */ .sparkle { position: absolute; background: var(--primary-light); border-radius: 50%; animation: sparkle 2s ease-in-out infinite; opacity: 0; } @keyframes sparkle { 0% { transform: scale(0); opacity: 0; } 50% { opacity: 0.5; } 100% { transform: scale(1); opacity: 0; } } /* Pulse effect */ .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(67, 97, 238, 0.4); } 70% { box-shadow: 0 0 0 8px rgba(67, 97, 238, 0); } 100% { box-shadow: 0 0 0 0 rgba(67, 97, 238, 0); } } </style> </head> <body> <div class="dashboard"> <div class="dashboard-header"> <h1 class="dashboard-title">Analytics Overview</h1> <div class="time-filter"> <button class="time-btn" data-time="day">Day</button> <button class="time-btn active" data-time="week">Week</button> <button class="time-btn" data-time="month">Month</button> <button class="time-btn" data-time="year">Year</button> </div> </div> <div class="dashboard-content"> <div class="dashboard-card" data-metric="active-users"> <div class="card-header"> <div class="card-title">ACTIVE USERS</div> <div class="card-icon" style="background-color: var(--primary);"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c0-.001-.001-.002-.001-.004H3c0 .002-.001.003-.001.004"></path> </svg> </div> </div> <div class="card-value">14,273</div> <div class="card-description"> <div class="card-trend trend-up"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="m7.247 4.86-4.796 5.481c-.566.647-.106 1.659.753 1.659h9.592a1 1 0 0 0 .753-1.659l-4.796-5.48a1 1 0 0 0-1.506 0z"/> </svg> 8.3% </div> <span>vs previous period</span> </div> <div class="chart-container"> <svg width="100%" height="100%"> <defs> <linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" stop-color="var(--primary)" stop-opacity="0.5"/> <stop offset="100%" stop-color="var(--primary)" stop-opacity="0.05"/> </linearGradient> </defs> <path class="chart-line" d="M 0,40 Q 30,35 60,25 T 120,30 T 180,10 T 240,15 T 300,5"></path> <path class="chart-area" d="M 0,40 Q 30,35 60,25 T 120,30 T 180,10 T 240,15 T 300,5 V 50 H 0 Z"></path> </svg> <span class="data-point" style="bottom: 25px; left: 60px;" data-value="12,850" data-date="Aug 24, 2023"></span> <span class="data-point" style="bottom: 20px; left: 120px;" data-value="13,246" data-date="Aug 25, 2023"></span> <span class="data-point pulse" style="bottom: 40px; left: 180px;" data-value="14,273" data-date="Aug 26, 2023"></span> <span class="data-point" style="bottom: 35px; left: 240px;" data-value="13,854" data-date="Aug 27, 2023"></span> </div> </div> <div class="dashboard-card" data-metric="conversion-rate"> <div class="card-header"> <div class="card-title">CONVERSION RATE</div> <div class="card-icon" style="background-color: var(--success);"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/> </svg> </div> </div> <div class="card-value">3.42%</div> <div class="card-description"> <div class="card-trend trend-up"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="m7.247 4.86-4.796 5.481c-.566.647-.106 1.659.753 1.659h9.592a1 1 0 0 0 .753-1.659l-4.796-5.48a1 1 0 0 0-1.506 0z"/> </svg> 1.2% </div> <span>vs previous period</span> </div> <div class="chart-container"> <svg width="100%" height="100%"> <path class="chart-line" d="M 0,30 Q 30,25 60,20 T 120,25 T 180,15 T 240,5 T 300,10"></path> <path class="chart-area" d="M 0,30 Q 30,25 60,20 T 120,25 T 180,15 T 240,5 T 300,10 V 50 H 0 Z"></path> </svg> <span class="data-point" style="bottom: 30px; left: 60px;" data-value="2.98%" data-date="Aug 24, 2023"></span> <span class="data-point" style="bottom: 25px; left: 120px;" data-value="3.15%" data-date="Aug 25, 2023"></span> <span class="data-point" style="bottom: 35px; left: 180px;" data-value="3.24%" data-date="Aug 26, 2023"></span> <span class="data-point pulse" style="bottom: 45px; left: 240px;" data-value="3.42%" data-date="Aug 27, 2023"></span> </div> </div> <div class="dashboard-card" data-metric="avg-session"> <div class="card-header"> <div class="card-title">AVG. SESSION TIME</div> <div class="card-icon" style="background-color: var(--warning);"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0z"/> </svg> </div> </div> <div class="card-value">4m 32s</div> <div class="card-description"> <div class="card-trend trend-down"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/> </svg> 0.8% </div> <span>vs previous period</span> </div> <div class="chart-container"> <svg width="100%" height="100%"> <path class="chart-line" d="M 0,20 Q 30,25 60,15 T 120,25 T 180,20 T 240,30 T 300,25"></path> <path class="chart-area" d="M 0,20 Q 30,25 60,15 T 120,25 T 180,20 T 240,30 T 300,25 V 50 H 0 Z"></path> </svg> <span class="data-point" style="bottom: 35px; left: 60px;" data-value="4m 38s" data-date="Aug 24, 2023"></span> <span class="data-point" style="bottom: 25px; left: 120px;" data-value="4m 51s" data-date="Aug 25, 2023"></span> <span class="data-point" style="bottom: 30px; left: 180px;" data-value="4m 42s" data-date="Aug 26, 2023"></span> <span class="data-point pulse" style="bottom: 20px; left: 240px;" data-value="4m 32s" data-date="Aug 27, 2023"></span> </div> </div> <div class="dashboard-card" data-metric="bounce-rate"> <div class="card-header"> <div class="card-title">BOUNCE RATE</div> <div class="card-icon" style="background-color: var(--danger);"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5ZM11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3A1.5 1.5 0 0 0 5 1.5v1H2.506a.58.58 0 0 0-.01 0H1.5a.5.5 0 0 0 0 1h.538l.853 10.66A2 2 0 0 0 4.885 16h6.23a2 2 0 0 0 1.994-1.84l.853-10.66h.538a.5.5 0 0 0 0-1h-.995a.59.59 0 0 0-.01 0H11Zm1.958 1-.846 10.58a1 1 0 0 1-.997.92h-6.23a1 1 0 0 1-.997-.92L3.042 3.5h9.916Zm-7.487 1a.5.5 0 0 1 .528.47l.5 8.5a.5.5 0 0 1-.998.06L5 5.03a.5.5 0 0 1 .47-.53Zm5.058 0a.5.5 0 0 1 .47.53l-.5 8.5a.5.5 0 1 1-.998-.06l.5-8.5a.5.5 0 0 1 .528-.47ZM8 4.5a.5.5 0 0 1 .5.5v8.5a.5.5 0 0 1-1 0V5a.5.5 0 0 1 .5-.5Z"/> </svg> </div> </div> <div class="card-value">51.2%</div> <div class="card-description"> <div class="card-trend trend-up"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="m7.247 4.86-4.796 5.481c-.566.647-.106 1.659.753 1.659h9.592a1 1 0 0 0 .753-1.659l-4.796-5.48a1 1 0 0 0-1.506 0z"/> </svg> 2.7% </div> <span>vs previous period</span> </div> <div class="chart-container"> <svg width="100%" height="100%"> <path class="chart-line" d="M 0,25 Q 30,20 60,25 T 120,15 T 180,20 T 240,5 T 300,15"></path> <path class="chart-area" d="M 0,25 Q 30,20 60,25 T 120,15 T 180,20 T 240,5 T 300,15 V 50 H 0 Z"></path> </svg> <span class="data-point" style="bottom: 25px; left: 60px;" data-value="48.4%" data-date="Aug 24, 2023"></span> <span class="data-point" style="bottom: 35px; left: 120px;" data-value="45.8%" data-date="Aug 25, 2023"></span> <span class="data-point" style="bottom: 30px; left: 180px;" data-value="47.5%" data-date="Aug 26, 2023"></span> <span class="data-point pulse" style="bottom: 45px; left: 240px;" data-value="51.2%" data-date="Aug 27, 2023"></span> </div> </div> </div> <div class="tooltip"> <div class="tooltip-title">Active Users</div> <div class="tooltip-value">14,273</div> <div class="tooltip-date">Aug 26, 2023</div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Handle time filter buttons const timeButtons = document.querySelectorAll('.time-btn'); timeButtons.forEach(button => { button.addEventListener('click', function() { // Remove active class from all buttons timeButtons.forEach(btn => btn.classList.remove('active')); // Add active class to clicked button this.classList.add('active'); // Animate data change animateDataChange(); }); }); // Handle tooltips const dataPoints = document.querySelectorAll('.data-point'); const tooltip = document.querySelector('.tooltip'); dataPoints.forEach(point => { point.addEventListener('mouseenter', function(e) { const rect = this.getBoundingClientRect(); const dashboardRect = document.querySelector('.dashboard').getBoundingClientRect(); const value = this.getAttribute('data-value'); const date = this.getAttribute('data-date'); const metric = this.closest('.dashboard-card').getAttribute('data-metric'); // Update tooltip content let metricName = ''; switch(metric) { case 'active-users': metricName = 'Active Users'; break; case 'conversion-rate': metricName = 'Conversion Rate'; break; case 'avg-session': metricName = 'Avg. Session Time'; break; case 'bounce-rate': metricName = 'Bounce Rate'; break; } tooltip.querySelector('.tooltip-title').textContent = metricName; tooltip.querySelector('.tooltip-value').textContent = value; tooltip.querySelector('.tooltip-date').textContent = date; // Position tooltip tooltip.style.left = (rect.left - dashboardRect.left + rect.width/2 - tooltip.offsetWidth/2) + 'px'; tooltip.style.top = (rect.top - dashboardRect.top - tooltip.offsetHeight - 10) + 'px'; // Show tooltip with animation tooltip.classList.add('visible'); // Create sparkle effect createSparkles(this); }); point.addEventListener('mouseleave', function() { tooltip.classList.remove('visible'); }); }); // Create sparkle effects function createSparkles(element) { const numberOfSparkles = 5; const rect = element.getBoundingClientRect(); const parent = element.closest('.dashboard-card'); for (let i = 0; i < numberOfSparkles; i++) { const sparkle = document.createElement('div'); sparkle.classList.add('sparkle'); // Random size between 3px and 6px const size = Math.random() * 3 + 3; sparkle.style.width = `${size}px`; sparkle.style.height = `${size}px`; // Position around the data point const angle = Math.random() * Math.PI * 2; // Random angle const distance = Math.random() * 30 + 10; // Random distance from 10px to 40px const left = (rect.left - parent.getBoundingClientRect().left) + rect.width/2 + Math.cos(angle) * distance; const top = (rect.top - parent.getBoundingClientRect().top) + rect.height/2 + Math.sin(angle) * distance; sparkle.style.left = `${left}px`; sparkle.style.top = `${top}px`; // Random delay so they don't all animate at once sparkle.style.animationDelay = `${Math.random() * 0.5}s`; parent.appendChild(sparkle); // Remove sparkle after animation completes setTimeout(() => { if (parent.contains(sparkle)) { parent.removeChild(sparkle); } }, 2000); } } // Animate data changes when time filter changes function animateDataChange() { const cards = document.querySelectorAll('.dashboard-card'); cards.forEach(card => { const valueElement = card.querySelector('.card-value'); const currentValue = valueElement.textContent; // Generate a new value based on the metric let newValue = ''; const metric = card.getAttribute('data-metric'); switch(metric) { case 'active-users': // Random value between 12000 and 16000 newValue = Math.floor(Math.random() * 4000 + 12000).toLocaleString(); break; case 'conversion-rate': // Random value between 2.5 and 4.5 newValue = (Math.random() * 2 + 2.5).toFixed(2) + '%'; break; case 'avg-session': // Random minutes between 3 and 6, random seconds between 0 and 59 const minutes = Math.floor(Math.random() * 3 + 3); const seconds = Math.floor(Math.random() * 60); newValue = `${minutes}m ${seconds}s`; break; case 'bounce-rate': // Random value between 40 and 60 newValue = (Math.random() * 20 + 40).toFixed(1) + '%'; break; } // Animate the transition valueElement.style.transition = 'opacity 0.3s ease-out'; valueElement.style.opacity = 0; setTimeout(() => { valueElement.textContent = newValue; valueElement.style.opacity = 1; }, 300); // Update trend indicators const trend = card.querySelector('.card-trend'); const isUp = Math.random() > 0.5; if (isUp) { trend.classList.remove('trend-down'); trend.classList.add('trend-up'); trend.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="m7.247 4.86-4.796 5.481c-.566.647-.106 1.659.753 1.659h9.592a1 1 0 0 0 .753-1.659l-4.796-5.48a1 1 0 0 0-1.506 0z"/> </svg> ${(Math.random() * 10).toFixed(1)}% `; } else { trend.classList.remove('trend-up'); trend.classList.add('trend-down'); trend.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"> <path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/> </svg> ${(Math.random() * 10).toFixed(1)}% `; } }); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>E-commerce Product Page with Tooltips</title> <style> /* Reset and Base Styles */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } :root { --primary: #FF6B6B; --secondary: #4ECDC4; --accent: #FFE66D; --dark: #292F36; --light: #F7F9F9; --gradient: linear-gradient(135deg, var(--primary), var(--secondary)); --shadow: 0 10px 20px rgba(0, 0, 0, 0.15); --tooltip-shadow: 0 15px 30px rgba(0, 0, 0, 0.2); } body { background-color: var(--light); width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; overflow-x: hidden; padding: 20px; } .container { width: 100%; max-width: 660px; margin: 0 auto; background: white; border-radius: 16px; overflow: hidden; box-shadow: var(--shadow); } /* Product Grid */ .product-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; padding: 20px; } .product-card { position: relative; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15); } .product-image { position: relative; overflow: hidden; height: 250px; } .product-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .product-card:hover .product-image img { transform: scale(1.05); } .product-content { padding: 15px; background: white; } .product-title { font-weight: 600; font-size: 1.1rem; margin-bottom: 8px; color: var(--dark); } .product-price { font-size: 1.2rem; font-weight: 700; color: var(--primary); margin-bottom: 10px; } .product-meta { display: flex; justify-content: space-between; align-items: center; } .product-rating { display: flex; align-items: center; gap: 4px; color: var(--dark); } .product-rating svg { fill: var(--accent); } /* Tooltip Styles */ .tooltip-trigger { position: absolute; width: 28px; height: 28px; border-radius: 50%; background: var(--primary); color: white; display: flex; justify-content: center; align-items: center; cursor: pointer; z-index: 2; box-shadow: 0 2px 8px rgba(255, 107, 107, 0.4); transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), background-color 0.3s; } .tooltip-trigger:hover { transform: scale(1.1); background: var(--secondary); } .tooltip-trigger.material { top: 20px; left: 20px; } .tooltip-trigger.features { bottom: 20px; right: 20px; } .tooltip-trigger.sizing { top: 120px; right: 20px; } .tooltip { position: absolute; background: white; border-radius: 10px; padding: 15px; width: 220px; box-shadow: var(--tooltip-shadow); opacity: 0; visibility: hidden; transition: all 0.3s ease; z-index: 10; pointer-events: none; transform: translateY(10px); border-left: 4px solid var(--primary); } .tooltip::before { content: ''; position: absolute; width: 12px; height: 12px; background: white; transform: rotate(45deg); z-index: -1; } .tooltip-trigger.material + .tooltip { left: 40px; top: 10px; } .tooltip-trigger.material + .tooltip::before { left: -6px; top: 15px; } .tooltip-trigger.features + .tooltip { right: 40px; bottom: 10px; } .tooltip-trigger.features + .tooltip::before { right: -6px; bottom: 15px; } .tooltip-trigger.sizing + .tooltip { right: 40px; top: 110px; } .tooltip-trigger.sizing + .tooltip::before { right: -6px; top: 15px; } .tooltip.active { opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto; } .tooltip-title { font-weight: 600; font-size: 1rem; color: var(--dark); margin-bottom: 8px; display: flex; align-items: center; gap: 5px; } .tooltip-title svg { width: 18px; height: 18px; fill: var(--primary); } .tooltip-content { font-size: 0.85rem; color: #555; margin-bottom: 10px; line-height: 1.4; } .tooltip-cta { display: inline-flex; align-items: center; background: var(--gradient); color: white; font-size: 0.8rem; font-weight: 600; padding: 6px 12px; border-radius: 20px; text-decoration: none; gap: 5px; transition: transform 0.2s ease, box-shadow 0.2s ease; box-shadow: 0 3px 10px rgba(255, 107, 107, 0.3); cursor: pointer; } .tooltip-cta:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4); } .tooltip-cta svg { width: 16px; height: 16px; fill: white; transition: transform 0.2s ease; } .tooltip-cta:hover svg { transform: translateX(3px); } /* Badge Style */ .badge { position: absolute; top: 15px; right: 15px; background: var(--secondary); color: white; padding: 5px 10px; border-radius: 20px; font-size: 0.75rem; font-weight: 600; z-index: 2; box-shadow: 0 3px 6px rgba(78, 205, 196, 0.3); } /* Add to Cart Button */ .add-to-cart { width: 100%; background: var(--gradient); color: white; border: none; border-radius: 8px; padding: 10px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; display: flex; justify-content: center; align-items: center; gap: 8px; } .add-to-cart:hover { box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4); } .add-to-cart svg { width: 18px; height: 18px; fill: white; } /* Header */ .header { padding: 20px; background: var(--dark); color: white; text-align: center; } .header h1 { font-size: 1.5rem; margin-bottom: 5px; } .header p { font-size: 0.9rem; opacity: 0.8; } /* Responsive Adjustments */ @media (max-width: 576px) { .product-grid { grid-template-columns: 1fr; padding: 15px; } .tooltip { width: 180px; padding: 10px; } .product-image { height: 200px; } } /* Pulse Animation for Tooltips */ @keyframes pulse { 0% { transform: scale(1); box-shadow: 0 2px 8px rgba(255, 107, 107, 0.4); } 50% { transform: scale(1.1); box-shadow: 0 4px 12px rgba(255, 107, 107, 0.6); } 100% { transform: scale(1); box-shadow: 0 2px 8px rgba(255, 107, 107, 0.4); } } .tooltip-trigger { animation: pulse 2s infinite; } .tooltip-trigger:hover { animation: none; } </style> </head> <body> <div class="container"> <div class="header"> <h1>Premium Collection</h1> <p>Discover our finest eco-friendly apparel</p> </div> <div class="product-grid"> <div class="product-card"> <div class="product-image"> <img src="https://images.unsplash.com/photo-1576566588028-4147f3842f27?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=600&q=80" alt="Organic Cotton Hoodie"> <div class="badge">New Arrival</div> <!-- Material Tooltip --> <div class="tooltip-trigger material"> <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><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg> </div> <div class="tooltip"> <div class="tooltip-title"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.54 9c-.49-.49-1.05-.83-1.64-1.03C15.1 7.46 12.9 8.1 12 9c-.9-.9-3.1-1.54-4.9-1.03-.59.2-1.15.54-1.64 1.03-2.73 2.73-2.73 7.17 0 9.9C6.97 20.42 8.93 21 10.9 21c1.1 0 2.2-.23 3.1-.67.9.43 2 .67 3.1.67 1.97 0 3.93-.58 5.44-2.1 2.73-2.73 2.73-7.17 0-9.9z"/></svg> Organic Materials </div> <div class="tooltip-content"> Made with 100% GOTS-certified organic cotton sourced from sustainable farms with no harmful chemicals or pesticides. </div> <a class="tooltip-cta"> Learn about our sourcing <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.025 1l-2.847 2.828 6.176 6.176h-16.354v3.992h16.354l-6.176 6.176 2.847 2.828 10.975-11z"/></svg> </a> </div> <!-- Features Tooltip --> <div class="tooltip-trigger features"> <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="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg> </div> <div class="tooltip"> <div class="tooltip-title"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 1l2.7 8.3h8.7l-7 5.1 2.7 8.3-7-5.1-7 5.1 2.7-8.3-7-5.1h8.7z"/></svg> Key Features </div> <div class="tooltip-content"> Double-lined hood, kangaroo pocket, ribbed cuffs and hem. Specially treated to maintain color after 50+ washes. </div> <a class="tooltip-cta"> View all details <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.025 1l-2.847 2.828 6.176 6.176h-16.354v3.992h16.354l-6.176 6.176 2.847 2.828 10.975-11z"/></svg> </a> </div> <!-- Sizing Tooltip --> <div class="tooltip-trigger sizing"> <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"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="3" y1="9" x2="21" y2="9"></line><line x1="9" y1="21" x2="9" y2="9"></line></svg> </div> <div class="tooltip"> <div class="tooltip-title"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 4h-3V3a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1v1H3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1zm-11 1v1h4V5h-4z"/></svg> True-to-Size Fit </div> <div class="tooltip-content"> Relaxed fit runs true to size. For a looser feel, size up. Model is 5'10" wearing size M. </div> <a class="tooltip-cta"> Size guide <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.025 1l-2.847 2.828 6.176 6.176h-16.354v3.992h16.354l-6.176 6.176 2.847 2.828 10.975-11z"/></svg> </a> </div> </div> <div class="product-content"> <h3 class="product-title">Eco-Friendly Comfort Hoodie</h3> <div class="product-price">$79.95</div> <div class="product-meta"> <div class="product-rating"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z"/></svg> <span>4.8 (124)</span> </div> </div> <button class="add-to-cart"> <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="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg> Add to Cart </button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Get all tooltip triggers const tooltipTriggers = document.querySelectorAll('.tooltip-trigger'); // Add click event listeners to each trigger tooltipTriggers.forEach(trigger => { const tooltip = trigger.nextElementSibling; // Toggle tooltip on click trigger.addEventListener('click', function(e) { e.stopPropagation(); // Close all other tooltips document.querySelectorAll('.tooltip.active').forEach(activeTooltip => { if (activeTooltip !== tooltip) { activeTooltip.classList.remove('active'); } }); // Toggle current tooltip tooltip.classList.toggle('active'); }); // Add hover event for enhanced UX (optional) trigger.addEventListener('mouseenter', function() { tooltip.classList.add('active'); }); tooltip.addEventListener('mouseleave', function() { if (!tooltip.contains(document.activeElement)) { tooltip.classList.remove('active'); } }); }); // Close tooltips when clicking anywhere else on the page document.addEventListener('click', function() { document.querySelectorAll('.tooltip.active').forEach(tooltip => { tooltip.classList.remove('active'); }); }); // Prevent tooltip closing when clicking inside the tooltip document.querySelectorAll('.tooltip').forEach(tooltip => { tooltip.addEventListener('click', function(e) { e.stopPropagation(); }); }); // Add click handler for CTA buttons document.querySelectorAll('.tooltip-cta').forEach(cta => { cta.addEventListener('click', function(e) { e.preventDefault(); // Animation feedback for click this.style.transform = 'scale(0.95)'; setTimeout(() => { this.style.transform = ''; }, 100); // Here you would normally add logic to show more details // For demo purposes we'll just close the tooltip after a delay setTimeout(() => { this.closest('.tooltip').classList.remove('active'); }, 300); }); }); // Add to cart button effect document.querySelector('.add-to-cart').addEventListener('click', function() { this.innerHTML = ` <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="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg> Added to Cart `; this.style.background = 'linear-gradient(135deg, #4ECDC4, #26A69A)'; setTimeout(() => { this.innerHTML = ` <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="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg> Add to Cart `; this.style.background = 'var(--gradient)'; }, 1500); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Educational Chalkboard Tooltips</title> <style> @import url('https://fonts.googleapis.com/css2?family=Architects+Daughter&family=Coming+Soon&family=Patrick+Hand&display=swap'); :root { --chalk-white: #f5f5f5; --chalkboard-green: #2a3d2a; --chalkboard-dark: #1e2d1e; --chalk-dust: rgba(255, 255, 255, 0.1); --accent-yellow: #f9c846; --accent-pink: #ff7979; --accent-blue: #7ec9f5; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Patrick Hand', cursive; background-color: var(--chalkboard-green); color: var(--chalk-white); display: flex; flex-direction: column; align-items: center; justify-content: center; height: 700px; width: 700px; overflow: hidden; position: relative; } body::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: radial-gradient(var(--chalk-dust) 1px, transparent 1px), radial-gradient(var(--chalk-dust) 1px, transparent 1px); background-size: 20px 20px; background-position: 0 0, 10px 10px; pointer-events: none; z-index: 1; } .container { width: 90%; max-width: 680px; position: relative; z-index: 2; } .title { font-family: 'Architects Daughter', cursive; font-size: 2.5rem; text-align: center; margin-bottom: 1.5rem; color: var(--chalk-white); text-shadow: 2px 2px 4px var(--chalkboard-dark); position: relative; padding-bottom: 10px; } .title::after { content: ''; position: absolute; bottom: 0; left: 10%; right: 10%; height: 2px; background: var(--chalk-white); border-radius: 2px; opacity: 0.7; } .learning-area { display: grid; grid-template-columns: 1fr; gap: 1.5rem; margin-top: 2rem; } .concept { background: var(--chalkboard-dark); border: 2px solid var(--chalk-white); border-radius: 8px; padding: 1rem; position: relative; transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: help; display: flex; align-items: center; } .concept:hover { transform: translateY(-5px); box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3); } .concept-icon { width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; margin-right: 1rem; flex-shrink: 0; } .concept-content { flex-grow: 1; } .concept-title { font-family: 'Coming Soon', cursive; font-size: 1.4rem; margin-bottom: 0.5rem; position: relative; display: inline-block; } .concept-title::after { content: '?'; font-size: 0.9rem; color: var(--accent-yellow); background: rgba(255, 255, 255, 0.2); width: 20px; height: 20px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; margin-left: 8px; vertical-align: super; } .concept-description { font-size: 1rem; opacity: 0.8; } .tooltip { position: absolute; min-width: 300px; max-width: 400px; background: var(--chalkboard-dark); border: 3px solid var(--chalk-white); border-radius: 10px; padding: 1rem; box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); z-index: 100; opacity: 0; visibility: hidden; transform: translateY(20px); transition: opacity 0.4s ease, transform 0.4s ease, visibility 0.4s; font-family: 'Patrick Hand', cursive; } .tooltip.active { opacity: 1; visibility: visible; transform: translateY(0); } .tooltip::before { content: ''; position: absolute; top: -15px; left: 20px; border-width: 0 15px 15px 15px; border-style: solid; border-color: transparent transparent var(--chalk-white) transparent; } .tooltip-title { font-family: 'Architects Daughter', cursive; font-size: 1.2rem; margin-bottom: 0.5rem; color: var(--accent-yellow); border-bottom: 2px dashed var(--chalk-white); padding-bottom: 5px; } .tooltip-content { font-size: 1rem; line-height: 1.4; } .tooltip-section { margin-top: 0.8rem; } .tooltip-section-title { font-family: 'Coming Soon', cursive; color: var(--accent-blue); margin-bottom: 0.3rem; display: flex; align-items: center; } .tooltip-section-title svg { margin-right: 8px; } .tooltip-points { padding-left: 1.5rem; list-style-type: none; } .tooltip-points li { position: relative; margin-bottom: 0.5rem; } .tooltip-points li::before { content: '•'; position: absolute; left: -15px; color: var(--accent-pink); } .tooltip-footer { margin-top: 1rem; font-size: 0.9rem; font-style: italic; opacity: 0.7; text-align: right; } .concept-icon svg { width: 100%; height: 100%; } .eraser-button { position: absolute; bottom: 20px; right: 20px; background: var(--chalkboard-dark); border: 2px solid var(--chalk-white); border-radius: 8px; padding: 0.5rem 1rem; font-family: 'Coming Soon', cursive; color: var(--chalk-white); cursor: pointer; display: flex; align-items: center; transition: all 0.3s ease; } .eraser-button:hover { background: var(--chalk-white); color: var(--chalkboard-dark); } .eraser-button svg { width: 24px; height: 24px; margin-right: 8px; } .chalk-dust { position: absolute; width: 4px; height: 4px; background: var(--chalk-white); border-radius: 50%; opacity: 0.7; pointer-events: none; z-index: 5; } @media screen and (min-width: 600px) { .learning-area { grid-template-columns: repeat(2, 1fr); } } @media screen and (max-width: 600px) { .title { font-size: 2rem; } .concept-title { font-size: 1.2rem; } .tooltip { min-width: 250px; } } .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .wiggle { animation: wiggle 1s ease; } @keyframes wiggle { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-5deg); } 75% { transform: rotate(5deg); } } .click-here { position: absolute; bottom: 80px; font-family: 'Coming Soon', cursive; color: var(--accent-yellow); font-size: 1.2rem; animation: bounce 2s infinite; pointer-events: none; } @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } </style> </head> <body> <div class="container"> <h1 class="title">Interactive Learning Guide</h1> <div class="learning-area"> <div class="concept" data-tooltip="photosynthesis"> <div class="concept-icon"> <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"> <path fill="none" stroke="#f5f5f5" stroke-width="2" d="M32,10 C32,10 15,15 15,32 C15,49 32,54 32,54" stroke-dasharray="4 2"/> <path fill="none" stroke="#f5f5f5" stroke-width="2" d="M32,10 C32,10 49,15 49,32 C49,49 32,54 32,54" stroke-dasharray="4 2"/> <circle cx="32" cy="10" r="4" fill="#7ec9f5"/> <circle cx="32" cy="54" r="4" fill="#f9c846"/> <path fill="none" stroke="#ff7979" stroke-width="2" d="M20,25 C25,30 37,30 44,25" /> <path fill="none" stroke="#7ec9f5" stroke-width="2" d="M20,39 C25,34 37,34 44,39" /> </svg> </div> <div class="concept-content"> <h3 class="concept-title">Photosynthesis</h3> <p class="concept-description">How plants convert light energy into chemical energy</p> </div> </div> <div class="concept" data-tooltip="newton"> <div class="concept-icon"> <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"> <circle cx="32" cy="15" r="10" fill="none" stroke="#f5f5f5" stroke-width="2" stroke-dasharray="3 2"/> <line x1="32" y1="25" x2="32" y2="50" stroke="#f5f5f5" stroke-width="2" stroke-dasharray="3 2"/> <circle cx="32" cy="52" r="8" fill="#f9c846"/> <path d="M32,50 L42,35 L22,35 Z" fill="none" stroke="#ff7979" stroke-width="2"/> </svg> </div> <div class="concept-content"> <h3 class="concept-title">Newton's Laws</h3> <p class="concept-description">The fundamental principles of classical mechanics</p> </div> </div> <div class="concept" data-tooltip="pythagoras"> <div class="concept-icon"> <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"> <path d="M10,50 L10,20 L40,20 Z" fill="none" stroke="#f5f5f5" stroke-width="2"/> <path d="M10,50 L40,20" fill="none" stroke="#f5f5f5" stroke-width="2" stroke-dasharray="3 2"/> <text x="15" y="48" font-family="Patrick Hand" font-size="10" fill="#7ec9f5">a</text> <text x="25" y="28" font-family="Patrick Hand" font-size="10" fill="#f9c846">c</text> <text x="35" y="38" font-family="Patrick Hand" font-size="10" fill="#ff7979">b</text> </svg> </div> <div class="concept-content"> <h3 class="concept-title">Pythagorean Theorem</h3> <p class="concept-description">The relationship between sides of a right triangle</p> </div> </div> <div class="concept" data-tooltip="dna"> <div class="concept-icon"> <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"> <path d="M20,10 Q32,25 20,40 Q32,55 20,60" fill="none" stroke="#f5f5f5" stroke-width="2"/> <path d="M44,10 Q32,25 44,40 Q32,55 44,60" fill="none" stroke="#f5f5f5" stroke-width="2"/> <line x1="24" y1="15" x2="40" y2="15" stroke="#ff7979" stroke-width="2"/> <line x1="24" y1="25" x2="40" y2="25" stroke="#7ec9f5" stroke-width="2"/> <line x1="24" y1="35" x2="40" y2="35" stroke="#f9c846" stroke-width="2"/> <line x1="24" y1="45" x2="40" y2="45" stroke="#ff7979" stroke-width="2"/> <line x1="24" y1="55" x2="40" y2="55" stroke="#7ec9f5" stroke-width="2"/> </svg> </div> <div class="concept-content"> <h3 class="concept-title">DNA Structure</h3> <p class="concept-description">The double helix that carries genetic instructions</p> </div> </div> </div> </div> <div class="tooltip" id="photosynthesis-tooltip"> <h3 class="tooltip-title">Photosynthesis Explained</h3> <p class="tooltip-content">The process plants use to convert light energy from the sun into chemical energy stored as glucose.</p> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="8" cy="8" r="7" stroke="#7ec9f5" stroke-width="2" stroke-dasharray="2 1"/> </svg> Key Components </h4> <ul class="tooltip-points"> <li>Chlorophyll (captures sunlight)</li> <li>Carbon dioxide (from air)</li> <li>Water (from roots)</li> <li>Sunlight (energy source)</li> </ul> </div> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M3,8 L7,12 L13,4" stroke="#f9c846" stroke-width="2"/> </svg> Chemical Process </h4> <p class="tooltip-content">6CO₂ + 6H₂O + Light Energy → C₆H₁₂O₆ + 6O₂</p> </div> <div class="tooltip-footer">Tap anywhere to close</div> </div> <div class="tooltip" id="newton-tooltip"> <h3 class="tooltip-title">Newton's Three Laws of Motion</h3> <p class="tooltip-content">Sir Isaac Newton's fundamental principles that describe the physics of most everyday situations.</p> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="8" cy="8" r="7" stroke="#7ec9f5" stroke-width="2"/> <text x="7" y="12" font-family="Patrick Hand" font-size="10" fill="#7ec9f5">1</text> </svg> First Law (Inertia) </h4> <p class="tooltip-content">An object at rest stays at rest, and an object in motion stays in motion, unless acted upon by an external force.</p> </div> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="8" cy="8" r="7" stroke="#ff7979" stroke-width="2"/> <text x="7" y="12" font-family="Patrick Hand" font-size="10" fill="#ff7979">2</text> </svg> Second Law (F=ma) </h4> <p class="tooltip-content">The acceleration of an object is directly proportional to the force applied and inversely proportional to its mass.</p> </div> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="8" cy="8" r="7" stroke="#f9c846" stroke-width="2"/> <text x="7" y="12" font-family="Patrick Hand" font-size="10" fill="#f9c846">3</text> </svg> Third Law (Action-Reaction) </h4> <p class="tooltip-content">For every action, there is an equal and opposite reaction.</p> </div> <div class="tooltip-footer">Tap anywhere to close</div> </div> <div class="tooltip" id="pythagoras-tooltip"> <h3 class="tooltip-title">Pythagorean Theorem</h3> <p class="tooltip-content">A fundamental relation in Euclidean geometry among the three sides of a right triangle.</p> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M2,12 L2,4 L10,4 Z" fill="none" stroke="#7ec9f5" stroke-width="2"/> </svg> The Formula </h4> <p class="tooltip-content">a² + b² = c²</p> <p class="tooltip-content">Where c is the length of the hypotenuse, and a and b are the lengths of the other two sides.</p> </div> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="8" cy="8" r="7" stroke="#ff7979" stroke-width="2" stroke-dasharray="2 1"/> </svg> Real-world Applications </h4> <ul class="tooltip-points"> <li>Architecture and construction</li> <li>Navigation and GPS technology</li> <li>Computer graphics and game design</li> <li>Physics calculations</li> </ul> </div> <div class="tooltip-footer">Tap anywhere to close</div> </div> <div class="tooltip" id="dna-tooltip"> <h3 class="tooltip-title">DNA (Deoxyribonucleic Acid)</h3> <p class="tooltip-content">The molecule that carries genetic instructions for the development, functioning, growth and reproduction of all known organisms.</p> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M4,3 Q8,8 4,13" stroke="#7ec9f5" stroke-width="2"/> <path d="M12,3 Q8,8 12,13" stroke="#7ec9f5" stroke-width="2"/> </svg> Structure </h4> <ul class="tooltip-points"> <li>Double helix shape</li> <li>Made of nucleotides (A, T, G, C)</li> <li>Complementary base pairs (A-T, G-C)</li> <li>Sugar-phosphate backbone</li> </ul> </div> <div class="tooltip-section"> <h4 class="tooltip-section-title"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="8" cy="8" r="7" stroke="#f9c846" stroke-width="2"/> <path d="M5,8 L11,8 M8,5 L8,11" stroke="#f9c846" stroke-width="2"/> </svg> Fascinating Facts </h4> <ul class="tooltip-points"> <li>Human DNA contains about 3 billion base pairs</li> <li>If stretched out, one person's DNA would reach the moon 6 times</li> <li>We share about 60% of DNA with bananas</li> <li>DNA can self-replicate</li> </ul> </div> <div class="tooltip-footer">Tap anywhere to close</div> </div> <button class="eraser-button"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M18,8 L8,18 L2,12 L12,2 Z" stroke="currentColor" stroke-width="2" fill="none"/> <path d="M18,8 L22,12 L16,18 L8,18" stroke="currentColor" stroke-width="2" fill="none"/> </svg> Clear board </button> <div class="click-here">Click on topics to learn more!</div> <script> document.addEventListener('DOMContentLoaded', function() { const concepts = document.querySelectorAll('.concept'); const tooltips = document.querySelectorAll('.tooltip'); const eraserButton = document.querySelector('.eraser-button'); const clickHere = document.querySelector('.click-here'); let activeTooltip = null; function createChalkDust(x, y) { for (let i = 0; i < 8; i++) { const dust = document.createElement('div'); dust.classList.add('chalk-dust'); dust.style.left = `${x + (Math.random() * 30 - 15)}px`; dust.style.top = `${y + (Math.random() * 30 - 15)}px`; document.body.appendChild(dust); setTimeout(() => { dust.style.opacity = '0'; dust.style.transform = `translate(${Math.random() * 50 - 25}px, ${Math.random() * 50 - 25}px)`; dust.style.transition = 'opacity 1s ease, transform 1s ease'; setTimeout(() => { document.body.removeChild(dust); }, 1000); }, 50); } } function positionTooltip(concept, tooltip) { const conceptRect = concept.getBoundingClientRect(); const tooltipRect = tooltip.getBoundingClientRect(); const bodyRect = document.body.getBoundingClientRect(); let left = conceptRect.left + conceptRect.width / 2 - tooltipRect.width / 2; let top = conceptRect.bottom + 15; // Check if tooltip would go off the right edge if (left + tooltipRect.width > bodyRect.width - 20) { left = bodyRect.width - tooltipRect.width - 20; } // Check if tooltip would go off the left edge if (left < 20) { left = 20; } // Check if tooltip would go off the bottom if (top + tooltipRect.height > bodyRect.height - 20) { top = conceptRect.top - tooltipRect.height - 15; // Adjust arrow to point down instead of up tooltip.querySelector('::before').style.top = 'auto'; tooltip.querySelector('::before').style.bottom = '-15px'; tooltip.querySelector('::before').style.borderColor = `var(--chalk-white) transparent transparent transparent`; } else { tooltip.querySelector('::before').style.top = '-15px'; tooltip.querySelector('::before').style.bottom = 'auto'; tooltip.querySelector('::before').style.borderColor = `transparent transparent var(--chalk-white) transparent`; } tooltip.style.left = `${left}px`; tooltip.style.top = `${top}px`; } function closeTooltip() { if (activeTooltip) { activeTooltip.classList.remove('active'); activeTooltip = null; } } function highlightConcept() { const concepts = document.querySelectorAll('.concept'); const randomConcept = concepts[Math.floor(Math.random() * concepts.length)]; randomConcept.classList.add('pulse'); setTimeout(() => { randomConcept.classList.remove('pulse'); }, 2000); setTimeout(highlightConcept, 4000); } // Initial highlight setTimeout(highlightConcept, 2000); concepts.forEach(concept => { concept.addEventListener('click', function(e) { e.stopPropagation(); const tooltipId = this.getAttribute('data-tooltip') + '-tooltip'; const tooltip = document.getElementById(tooltipId); // Close any open tooltip closeTooltip(); // Show new tooltip with custom positioning tooltip.classList.add('active'); activeTooltip = tooltip; // Position tooltip relative to concept positionTooltip(this, tooltip); // Create chalk dust effect const rect = this.getBoundingClientRect(); createChalkDust(rect.left + rect.width / 2, rect.top + rect.height / 2); // Make the click-here disappear clickHere.style.display = 'none'; }); }); document.addEventListener('click', function(e) { if (activeTooltip && !e.target.closest('.concept')) { closeTooltip(); } }); eraserButton.addEventListener('click', function(e) { e.stopPropagation(); closeTooltip(); // Create chalk dust at click location createChalkDust(e.clientX, e.clientY); // Add wiggle animation to the concepts concepts.forEach(concept => { concept.classList.add('wiggle'); setTimeout(() => { concept.classList.remove('wiggle'); }, 1000); }); }); // Make sure tooltips are properly positioned on window resize window.addEventListener('resize', function() { if (activeTooltip) { const conceptId = activeTooltip.id.replace('-tooltip', ''); const concept = document.querySelector(`[data-tooltip="${conceptId}"]`); positionTooltip(concept, activeTooltip); } }); }); </script> </body> </html>
<html> <head> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } :root { --primary-blue: #4A90E2; --primary-teal: #40CABC; --accent-pink: #F6BBDA; --accent-yellow: #FFEEB8; --accent-mint: #D0F0E4; --text-dark: #2C3E50; --text-secondary: #5D6D7E; --bg-light: #F9FAFC; --border-light: #E5E9F2; } body { background-color: var(--bg-light); color: var(--text-dark); height: 100%; width: 100%; overflow-x: hidden; line-height: 1.5; max-width: 700px; max-height: 700px; margin: 0 auto; padding: 20px; } .container { display: flex; flex-direction: column; height: 100%; max-width: 660px; margin: 0 auto; } h1 { font-size: 28px; font-weight: 700; margin-bottom: 16px; color: var(--text-dark); } h2 { font-size: 20px; font-weight: 600; margin-bottom: 12px; color: var(--text-dark); } p { font-size: 16px; margin-bottom: 16px; color: var(--text-secondary); } .header { padding-bottom: 16px; margin-bottom: 24px; border-bottom: 1px solid var(--border-light); } .patient-card { background-color: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); padding: 18px; margin-bottom: 20px; position: relative; transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out; } .patient-card:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08); } .patient-name { font-size: 18px; font-weight: 600; margin-bottom: 8px; display: flex; align-items: center; } .patient-info { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 16px; } .info-item { display: flex; flex-direction: column; } .info-label { font-size: 14px; color: var(--text-secondary); margin-bottom: 4px; } .info-value { font-weight: 500; font-size: 16px; } .critical { color: #E74C3C; font-weight: 600; } .alert { background-color: #FFEAEA; border-left: 4px solid #E74C3C; padding: 12px; margin-top: 12px; border-radius: 6px; display: flex; align-items: flex-start; gap: 10px; } .alert svg { flex-shrink: 0; color: #E74C3C; margin-top: 2px; } .alert-text { margin-bottom: 0; font-size: 14px; color: #922B21; } .icons-row { display: flex; gap: 8px; margin-top: 16px; } .icon-btn { width: 40px; height: 40px; border-radius: 8px; background-color: var(--bg-light); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background-color 0.2s ease; position: relative; } .icon-btn:hover { background-color: #EEF2F7; } .icon-btn svg { width: 20px; height: 20px; color: var(--text-dark); } .tooltip-trigger { position: relative; display: inline-flex; margin-left: 8px; cursor: help; } .tooltip-icon { width: 18px; height: 18px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background-color: var(--accent-mint); color: var(--primary-teal); font-size: 12px; font-weight: bold; transition: all 0.2s ease; } .tooltip-trigger:hover .tooltip-icon { background-color: var(--primary-teal); color: white; } .tooltip { position: absolute; top: calc(100% + 10px); left: 50%; transform: translateX(-50%) translateY(-5px); width: 280px; padding: 12px 16px; background-color: white; border-radius: 8px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); z-index: 10; opacity: 0; visibility: hidden; transition: all 0.2s ease; pointer-events: none; } .tooltip::before { content: ''; position: absolute; top: -6px; left: 50%; transform: translateX(-50%) rotate(45deg); width: 12px; height: 12px; background-color: white; } .tooltip.left { left: 0; transform: translateX(0) translateY(-5px); } .tooltip.left::before { left: 16px; } .tooltip.right { left: auto; right: 0; transform: translateX(0) translateY(-5px); } .tooltip.right::before { left: auto; right: 16px; } .tooltip-trigger:hover .tooltip { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); pointer-events: auto; } .tooltip-trigger:hover .tooltip.left, .tooltip-trigger:hover .tooltip.right { transform: translateX(0) translateY(0); } .tooltip-title { font-weight: 600; font-size: 14px; margin-bottom: 6px; color: var(--text-dark); } .tooltip-content { font-size: 13px; color: var(--text-secondary); line-height: 1.4; } .indicator { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; } .indicator.green { background-color: #2ECC71; } .indicator.yellow { background-color: #F1C40F; } .indicator.red { background-color: #E74C3C; } .data-pill { display: inline-flex; align-items: center; background-color: var(--accent-mint); padding: 4px 10px; border-radius: 16px; font-size: 14px; font-weight: 500; color: #2C856D; margin-right: 8px; margin-bottom: 8px; } .data-pill.yellow { background-color: var(--accent-yellow); color: #B7950B; } .data-pill.pink { background-color: var(--accent-pink); color: #AF5F91; } .action-btn { display: flex; align-items: center; justify-content: center; background-color: var(--primary-blue); color: white; border: none; border-radius: 8px; padding: 12px 20px; font-size: 16px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 2px 6px rgba(74, 144, 226, 0.2); } .action-btn:hover { background-color: #3A7BC8; box-shadow: 0 4px 8px rgba(74, 144, 226, 0.3); } .action-btn svg { margin-right: 8px; width: 18px; height: 18px; } .tags { display: flex; flex-wrap: wrap; margin-bottom: 12px; } .toggle { position: relative; display: inline-block; width: 48px; height: 24px; margin-left: auto; } .toggle input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #CBD2E0; transition: .4s; border-radius: 34px; } .toggle-slider:before { position: absolute; content: ""; height: 18px; width: 18px; left: 3px; bottom: 3px; background-color: white; transition: .4s; border-radius: 50%; } input:checked + .toggle-slider { background-color: var(--primary-teal); } input:checked + .toggle-slider:before { transform: translateX(24px); } .tabs { display: flex; gap: 2px; margin-bottom: 24px; background-color: #E5E9F2; border-radius: 8px; padding: 4px; } .tab { padding: 10px 16px; flex: 1; text-align: center; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; border-radius: 6px; color: var(--text-secondary); } .tab.active { background-color: white; color: var(--text-dark); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); } .vitals-row { display: flex; gap: 12px; margin-bottom: 20px; } .vital-box { flex: 1; background-color: white; border-radius: 10px; padding: 16px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); position: relative; transition: transform 0.2s ease; } .vital-box:hover { transform: translateY(-2px); } .vital-label { font-size: 13px; color: var(--text-secondary); margin-bottom: 8px; display: flex; align-items: center; } .vital-value { font-size: 20px; font-weight: 600; color: var(--text-dark); } .vital-unit { font-size: 14px; color: var(--text-secondary); margin-left: 4px; } @keyframes pulse { 0% { opacity: 0.6; } 50% { opacity: 1; } 100% { opacity: 0.6; } } .pulse-animation { animation: pulse 2s infinite ease-in-out; } .vital-trend { display: inline-flex; align-items: center; font-size: 12px; margin-top: 4px; } .trend-up { color: #E74C3C; } .trend-down { color: #2ECC71; } .trend-stable { color: #F1C40F; } .medication-list { margin-top: 16px; } .medication-item { padding: 12px 16px; background-color: white; border-radius: 8px; margin-bottom: 8px; display: flex; align-items: center; transition: transform 0.2s ease; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03); } .medication-item:hover { transform: translateX(2px); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.07); } .medication-color { width: 8px; height: 40px; border-radius: 4px; margin-right: 12px; } .medication-info { flex: 1; } .medication-name { font-weight: 500; margin-bottom: 2px; } .medication-dosage { font-size: 13px; color: var(--text-secondary); } .medication-time { font-size: 13px; color: var(--text-secondary); padding: 2px 8px; background-color: #EEF2F7; border-radius: 4px; margin-left: 12px; } /* Responsive adjustments */ @media (max-width: 480px) { body { padding: 12px; } h1 { font-size: 24px; } .vitals-row { flex-direction: column; gap: 8px; } .patient-info { grid-template-columns: 1fr; } .tooltip { width: 240px; } } /* Extra animations and effects */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .fade-in-up { animation: fadeInUp 0.4s ease-out; } .fade-in-up-delay-1 { animation: fadeInUp 0.4s ease-out 0.1s; animation-fill-mode: both; } .fade-in-up-delay-2 { animation: fadeInUp 0.4s ease-out 0.2s; animation-fill-mode: both; } .fade-in-up-delay-3 { animation: fadeInUp 0.4s ease-out 0.3s; animation-fill-mode: both; } </style> </head> <body> <div class="container"> <div class="header fade-in-up"> <h1>Patient Monitoring</h1> <p>Real-time patient vitals and medication tracking with accessible tooltips for critical information.</p> </div> <div class="tabs fade-in-up"> <div class="tab active" data-tab="vitals">Vitals</div> <div class="tab" data-tab="medications">Medications</div> <div class="tab" data-tab="notes">Clinical Notes</div> </div> <div id="vitals-panel"> <div class="patient-card fade-in-up-delay-1"> <div class="patient-name"> Sarah Johnson <div class="tooltip-trigger"> <div class="tooltip-icon">i</div> <div class="tooltip"> <div class="tooltip-title">Patient Information</div> <div class="tooltip-content"> 54-year-old female with history of hypertension and type 2 diabetes. Recently admitted for coronary artery disease evaluation. Requires dietary restrictions and regular glucose monitoring. </div> </div> </div> <span class="toggle" style="margin-left: auto;"> <input type="checkbox" checked> <span class="toggle-slider"></span> </span> </div> <div class="tags"> <div class="data-pill">Room 302</div> <div class="data-pill yellow">Post-Op Day 2</div> <div class="data-pill pink">Fall Risk</div> </div> <div class="patient-info"> <div class="info-item"> <span class="info-label">Patient ID</span> <span class="info-value">P-78912-JK</span> </div> <div class="info-item"> <span class="info-label">Admitted</span> <span class="info-value">Feb 28, 2023</span> </div> <div class="info-item"> <span class="info-label">Physician</span> <span class="info-value">Dr. Rebecca Liu</span> </div> <div class="info-item"> <span class="info-label">Allergies</span> <span class="info-value critical">Penicillin</span> </div> </div> <div class="vitals-row"> <div class="vital-box fade-in-up-delay-1"> <div class="vital-label"> Heart Rate <div class="tooltip-trigger"> <div class="tooltip-icon">i</div> <div class="tooltip left"> <div class="tooltip-title">Heart Rate</div> <div class="tooltip-content"> <strong>Normal range:</strong> 60-100 bpm for adults<br> <strong>Monitor for:</strong> Tachycardia (>100 bpm) or bradycardia (<60 bpm), irregular rhythms </div> </div> </div> </div> <div class="vital-value">78<span class="vital-unit">bpm</span></div> <div class="vital-trend trend-stable"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 10L12 14L16 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Stable </div> </div> <div class="vital-box fade-in-up-delay-2"> <div class="vital-label"> Blood Pressure <div class="tooltip-trigger"> <div class="tooltip-icon">i</div> <div class="tooltip"> <div class="tooltip-title">Blood Pressure</div> <div class="tooltip-content"> <strong>Normal range:</strong> Systolic <120 mmHg, Diastolic <80 mmHg<br> <strong>Elevated:</strong> Systolic 120-129 mmHg, Diastolic <80 mmHg<br> <strong>Stage 1 Hypertension:</strong> Systolic 130-139 mmHg or Diastolic 80-89 mmHg </div> </div> </div> </div> <div class="vital-value critical">148/92<span class="vital-unit">mmHg</span></div> <div class="vital-trend trend-up"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 14L12 10L16 14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> +12 mmHg </div> </div> <div class="vital-box fade-in-up-delay-3"> <div class="vital-label"> Blood Glucose <div class="tooltip-trigger"> <div class="tooltip-icon">i</div> <div class="tooltip right"> <div class="tooltip-title">Blood Glucose</div> <div class="tooltip-content"> <strong>Target range:</strong> 80-130 mg/dL before meals, <180 mg/dL after meals<br> <strong>Hypoglycemia risk:</strong> <70 mg/dL<br> <strong>Action required:</strong> >250 mg/dL check for ketones </div> </div> </div> </div> <div class="vital-value">142<span class="vital-unit">mg/dL</span></div> <div class="vital-trend trend-down"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 10L12 14L16 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> -18 mg/dL </div> </div> </div> <div class="alert fade-in-up-delay-3"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-width="2"/> <path d="M12 8V12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> <circle cx="12" cy="16" r="1" fill="currentColor"/> </svg> <div class="alert-text">Hypertension alert: BP exceeds threshold of 140/90 mmHg. ACE inhibitor due at 14:00. Last dose administered 6 hours ago.</div> </div> <div class="icons-row"> <div class="icon-btn"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M9 12H15" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> <path d="M12 9L12 15" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> <path d="M3 12C3 4.5885 4.5885 3 12 3C19.4115 3 21 4.5885 21 12C21 19.4115 19.4115 21 12 21C4.5885 21 3 19.4115 3 12Z" stroke="currentColor" stroke-width="2"/> </svg> </div> <div class="icon-btn"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 12.5L11 15.5L16 9.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-width="2"/> </svg> </div> <div class="icon-btn"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 8V16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M8 12H16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-width="2"/> </svg> </div> <button class="action-btn"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M9 6L15 12L9 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> View Full Chart </button> </div> </div> </div> <div id="medications-panel" style="display: none;"> <div class="medication-list"> <div class="medication-item"> <div class="medication-color" style="background-color: var(--primary-blue);"></div> <div class="medication-info"> <div class="medication-name">Lisinopril</div> <div class="medication-dosage">20mg, oral, once daily</div> </div> <div class="medication-time">14:00</div> <div class="tooltip-trigger"> <div class="tooltip-icon">i</div> <div class="tooltip right"> <div class="tooltip-title">Lisinopril</div> <div class="tooltip-content"> <strong>Purpose:</strong> ACE inhibitor for hypertension<br> <strong>Side effects:</strong> Dry cough, dizziness, fatigue<br> <strong>Interactions:</strong> NSAIDs can reduce effectiveness<br> <strong>Administer:</strong> With or without food </div> </div> </div> </div> <div class="medication-item"> <div class="medication-color" style="background-color: var(--primary-teal);"></div> <div class="medication-info"> <div class="medication-name">Metformin</div> <div class="medication-dosage">1000mg, oral, twice daily</div> </div> <div class="medication-time">08:00</div> <div class="tooltip-trigger"> <div class="tooltip-icon">i</div> <div class="tooltip right"> <div class="tooltip-title">Metformin</div> <div class="tooltip-content"> <strong>Purpose:</strong> Antihyperglycemic for type 2 diabetes<br> <strong>Side effects:</strong> GI disturbances, metallic taste<br> <strong>Interactions:</strong> Radiographic contrast media<br> <strong>Administer:</strong> With meals to reduce GI upset </div> </div> </div> </div> <div class="medication-item"> <div class="medication-color" style="background-color: #F1C40F;"></div> <div class="medication-info"> <div class="medication-name">Atorvastatin</div> <div class="medication-dosage">40mg, oral, bedtime</div> </div> <div class="medication-time">20:00</div> <div class="tooltip-trigger"> <div class="tooltip-icon">i</div> <div class="tooltip right"> <div class="tooltip-title">Atorvastatin</div> <div class="tooltip-content"> <strong>Purpose:</strong> Statin for hyperlipidemia<br> <strong>Side effects:</strong> Muscle pain, liver effects<br> <strong>Interactions:</strong> Grapefruit juice, certain antibiotics<br> <strong>Administer:</strong> Evening or bedtime for maximum effect </div> </div> </div> </div> <div class="medication-item"> <div class="medication-color" style="background-color: #9B59B6;"></div> <div class="medication-info"> <div class="medication-name">Aspirin</div> <div class="medication-dosage">81mg, oral, once daily</div> </div> <div class="medication-time">08:00</div> <div class="tooltip-trigger"> <div class="tooltip-icon">i</div> <div class="tooltip right"> <div class="tooltip-title">Aspirin</div> <div class="tooltip-content"> <strong>Purpose:</strong> Antiplatelet for CAD prevention<br> <strong>Side effects:</strong> GI irritation, bleeding risk<br> <strong>Interactions:</strong> Anticoagulants, NSAIDs<br> <strong>Administer:</strong> With food to minimize GI irritation </div> </div> </div> </div> </div> </div> <div id="notes-panel" style="display: none;"> <div class="patient-card"> <h2>Clinical Notes</h2> <p>Patient reports mild chest discomfort (2/10) when climbing stairs. No pain at rest. Hypertension not adequately controlled with current regimen, consider medication adjustment.</p> <p>Blood glucose trending down with improved dietary compliance. Continue current insulin protocol with regular monitoring.</p> <div class="tags"> <div class="data-pill">Cardiology</div> <div class="data-pill yellow">Endocrinology</div> </div> <p><strong>Next Steps:</strong> Schedule cardiac stress test. Nutritional consult for diabetic diet education. Patient mobilizing well, physical therapy to focus on cardiac rehabilitation exercises.</p> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Tab switching functionality const tabs = document.querySelectorAll('.tab'); const panels = [ document.getElementById('vitals-panel'), document.getElementById('medications-panel'), document.getElementById('notes-panel') ]; tabs.forEach((tab, index) => { tab.addEventListener('click', () => { // Update active tab tabs.forEach(t => t.classList.remove('active')); tab.classList.add('active'); // Show corresponding panel panels.forEach(panel => panel.style.display = 'none'); panels[index].style.display = 'block'; // Add animation to newly visible panel panels[index].classList.add('fade-in-up'); setTimeout(() => { panels[index].classList.remove('fade-in-up'); }, 500); }); }); // Enable responsive tooltip positioning const tooltipTriggers = document.querySelectorAll('.tooltip-trigger'); function updateTooltipPositions() { tooltipTriggers.forEach(trigger => { const tooltip = trigger.querySelector('.tooltip'); if (!tooltip) return; const rect = trigger.getBoundingClientRect(); const windowWidth = window.innerWidth; // Check if tooltip would go off the right edge if (rect.left + tooltip.offsetWidth > windowWidth - 20) { tooltip.classList.add('right'); tooltip.classList.remove('left'); } // Check if tooltip would go off the left edge else if (rect.left - (tooltip.offsetWidth / 2) < 20) { tooltip.classList.add('left'); tooltip.classList.remove('right'); } // Reset to default centered position else { tooltip.classList.remove('left'); tooltip.classList.remove('right'); } }); } // Initial positioning updateTooltipPositions(); // Update on window resize window.addEventListener('resize', updateTooltipPositions); // Simulate real-time vital sign updates function updateVitalSigns() { const heartRate = document.querySelectorAll('.vital-value')[0]; const bloodPressure = document.querySelectorAll('.vital-value')[1]; const bloodGlucose = document.querySelectorAll('.vital-value')[2]; // Random small variations to simulate real-time monitoring const hrValue = parseInt(heartRate.textContent); const newHR = hrValue + Math.floor(Math.random() * 3) - 1; heartRate.innerHTML = newHR + '<span class="vital-unit">bpm</span>'; const bgValue = parseInt(bloodGlucose.textContent); const newBG = bgValue + Math.floor(Math.random() * 5) - 2; bloodGlucose.innerHTML = newBG + '<span class="vital-unit">mg/dL</span>'; // Add a pulse effect to simulate monitoring heartRate.classList.add('pulse-animation'); setTimeout(() => { heartRate.classList.remove('pulse-animation'); }, 1000); } // Update vitals every 8 seconds setInterval(updateVitalSigns, 8000); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Social Media Interaction Tooltips</title> <style> :root { --primary-color: #5b48ee; --secondary-color: #ff6b6b; --tertiary-color: #2ac3de; --bg-color: #fafafa; --text-color: #333; --tooltip-bg: rgba(45, 52, 75, 0.85); --tooltip-text: #fff; --card-bg: #fff; --card-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); --border-radius: 12px; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--bg-color); color: var(--text-color); display: flex; justify-content: center; align-items: center; min-height: 700px; overflow-x: hidden; padding: 20px; } .container { max-width: 660px; width: 100%; height: auto; min-height: 660px; display: flex; flex-direction: column; gap: 24px; } .title { text-align: center; margin-bottom: 10px; font-size: 28px; background: linear-gradient(135deg, var(--primary-color), var(--tertiary-color)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; position: relative; } .subtitle { text-align: center; font-size: 16px; color: #555; margin-bottom: 30px; } .feed { display: flex; flex-direction: column; gap: 20px; } .post { background-color: var(--card-bg); border-radius: var(--border-radius); padding: 20px; box-shadow: var(--card-shadow); position: relative; transition: transform 0.3s ease; } .post:hover { transform: translateY(-5px); } .post-header { display: flex; align-items: center; margin-bottom: 16px; } .avatar { width: 45px; height: 45px; border-radius: 50%; object-fit: cover; margin-right: 12px; background: linear-gradient(45deg, var(--primary-color), var(--tertiary-color)); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; } .user-info { flex: 1; } .username { font-weight: 600; font-size: 16px; margin-bottom: 3px; } .timestamp { font-size: 12px; color: #777; } .post-content { margin-bottom: 16px; line-height: 1.5; } .post-image { width: 100%; border-radius: 8px; margin-bottom: 20px; height: 180px; object-fit: cover; } .post-actions { display: flex; justify-content: space-between; border-top: 1px solid #eee; padding-top: 15px; } .action-button { display: flex; align-items: center; gap: 6px; background: none; border: none; color: #555; font-size: 14px; cursor: pointer; padding: 8px 12px; border-radius: 30px; transition: all 0.2s ease; position: relative; } .action-button:hover { background-color: rgba(0, 0, 0, 0.05); color: var(--primary-color); } .action-button.like.active { color: var(--secondary-color); } .action-button.bookmark.active { color: var(--primary-color); } .tooltip { position: absolute; bottom: 115%; left: 50%; transform: translateX(-50%) translateY(10px); background-color: var(--tooltip-bg); color: var(--tooltip-text); padding: 10px 15px; border-radius: 8px; font-size: 13px; white-space: nowrap; pointer-events: none; opacity: 0; transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.18); z-index: 10; width: max-content; max-width: 200px; backdrop-filter: blur(4px); } .tooltip::after { content: ''; position: absolute; top: 100%; left: 50%; margin-left: -6px; border-width: 6px; border-style: solid; border-color: var(--tooltip-bg) transparent transparent transparent; } .tooltip.visible { opacity: 1; transform: translateX(-50%) translateY(0); } /* Animated interactions */ .pulse { animation: pulse 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } .comment-form { display: flex; margin-top: 15px; gap: 10px; } .comment-input { flex: 1; padding: 12px 16px; border: 1px solid #ddd; border-radius: 30px; font-size: 14px; background-color: #f5f7fa; transition: all 0.2s ease; } .comment-input:focus { outline: none; border-color: var(--primary-color); background-color: #fff; box-shadow: 0 0 0 3px rgba(91, 72, 238, 0.1); } .send-button { background-color: var(--primary-color); color: white; border: none; border-radius: 30px; padding: 12px 20px; font-size: 14px; cursor: pointer; transition: all 0.2s ease; } .send-button:hover { background-color: #4a3ad6; transform: translateY(-2px); } .reactions-panel { display: flex; gap: 8px; background-color: var(--tooltip-bg); padding: 8px; border-radius: 30px; position: absolute; bottom: 100%; left: 10px; margin-bottom: 10px; transform: translateY(10px); opacity: 0; pointer-events: none; transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); z-index: 10; } .reactions-panel.visible { transform: translateY(0); opacity: 1; pointer-events: auto; } .reaction-emoji { background: none; border: none; font-size: 20px; cursor: pointer; transition: all 0.2s ease; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: 50%; } .reaction-emoji:hover { transform: scale(1.2); background-color: rgba(255, 255, 255, 0.1); } .notification { position: fixed; top: 20px; left: 50%; transform: translateX(-50%) translateY(-100px); background-color: var(--primary-color); color: white; padding: 12px 18px; border-radius: 8px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); font-size: 14px; z-index: 100; transition: transform 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55); } .notification.show { transform: translateX(-50%) translateY(0); } @media (max-width: 600px) { .container { padding: 10px; } .post { padding: 15px; } .title { font-size: 24px; } .tooltip { font-size: 12px; padding: 8px 12px; } .post-actions { flex-wrap: wrap; } } </style> </head> <body> <div class="container"> <h1 class="title">Friendly Feed</h1> <p class="subtitle">Discover new ways to interact with your social content</p> <div class="feed"> <div class="post"> <div class="post-header"> <div class="avatar">JD</div> <div class="user-info"> <p class="username">Jamie Diaz</p> <p class="timestamp">Posted 5 hours ago</p> </div> </div> <div class="post-content"> <p>Just finished my morning hike at Mount Rainier! The view was absolutely breathtaking with the fog rolling over the valleys. Nature really puts everything into perspective. ✨🏔️</p> </div> <img src="https://images.unsplash.com/photo-1542224566-6e85f2e6772f?auto=format&fit=crop&q=80&w=600" alt="Mountain landscape" class="post-image"> <div class="post-actions"> <button class="action-button like" data-tooltip="Show your appreciation"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path> </svg> <span>543</span> <div class="tooltip">Show your appreciation</div> <div class="reactions-panel"> <button class="reaction-emoji" data-reaction="❤️">❤️</button> <button class="reaction-emoji" data-reaction="👍">👍</button> <button class="reaction-emoji" data-reaction="🔥">🔥</button> <button class="reaction-emoji" data-reaction="😮">😮</button> <button class="reaction-emoji" data-reaction="🙌">🙌</button> </div> </button> <button class="action-button comment" data-tooltip="Join the conversation"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path> </svg> <span>42</span> <div class="tooltip">Join the conversation</div> </button> <button class="action-button share" data-tooltip="Share this with friends"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="18" cy="5" r="3"></circle> <circle cx="6" cy="12" r="3"></circle> <circle cx="18" cy="19" r="3"></circle> <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line> <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line> </svg> <span>Share</span> <div class="tooltip">Share this with friends</div> </button> <button class="action-button bookmark" data-tooltip="Save for later"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path> </svg> <div class="tooltip">Save for later</div> </button> </div> <div class="comment-form"> <input type="text" class="comment-input" placeholder="Add a comment..." data-tooltip="Express yourself"> <button class="send-button">Post</button> </div> </div> <div class="post"> <div class="post-header"> <div class="avatar">AK</div> <div class="user-info"> <p class="username">Alex Kim</p> <p class="timestamp">Posted yesterday</p> </div> </div> <div class="post-content"> <p>Just launched our new product after 6 months of development! So excited to share this with everyone. Check out the link in my profile for more details! 🚀 #ProductLaunch #TechStartup</p> </div> <img src="https://images.unsplash.com/photo-1569012871812-f38ee64cd54c?auto=format&fit=crop&q=80&w=600" alt="Product launch" class="post-image"> <div class="post-actions"> <button class="action-button like" data-tooltip="Show your appreciation"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path> </svg> <span>187</span> <div class="tooltip">Show your appreciation</div> <div class="reactions-panel"> <button class="reaction-emoji" data-reaction="❤️">❤️</button> <button class="reaction-emoji" data-reaction="👍">👍</button> <button class="reaction-emoji" data-reaction="🔥">🔥</button> <button class="reaction-emoji" data-reaction="😮">😮</button> <button class="reaction-emoji" data-reaction="🙌">🙌</button> </div> </button> <button class="action-button comment" data-tooltip="Join the conversation"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path> </svg> <span>26</span> <div class="tooltip">Join the conversation</div> </button> <button class="action-button share" data-tooltip="Share this with friends"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="18" cy="5" r="3"></circle> <circle cx="6" cy="12" r="3"></circle> <circle cx="18" cy="19" r="3"></circle> <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line> <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line> </svg> <span>Share</span> <div class="tooltip">Share this with friends</div> </button> <button class="action-button bookmark" data-tooltip="Save for later"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path> </svg> <div class="tooltip">Save for later</div> </button> </div> <div class="comment-form"> <input type="text" class="comment-input" placeholder="Add a comment..." data-tooltip="Express yourself"> <button class="send-button">Post</button> </div> </div> </div> </div> <div class="notification">Action completed successfully!</div> <script> document.addEventListener('DOMContentLoaded', function() { // Tooltip functionality const actionButtons = document.querySelectorAll('.action-button'); actionButtons.forEach(button => { const tooltip = button.querySelector('.tooltip'); button.addEventListener('mouseenter', () => { tooltip.classList.add('visible'); }); button.addEventListener('mouseleave', () => { tooltip.classList.remove('visible'); }); // Like button reactions panel if (button.classList.contains('like')) { const reactionsPanel = button.querySelector('.reactions-panel'); button.addEventListener('mouseenter', () => { setTimeout(() => { reactionsPanel.classList.add('visible'); }, 300); }); button.addEventListener('mouseleave', () => { reactionsPanel.classList.remove('visible'); }); // Prevent reactions panel from closing when mouse is over it reactionsPanel.addEventListener('mouseenter', () => { reactionsPanel.classList.add('visible'); }); reactionsPanel.addEventListener('mouseleave', () => { reactionsPanel.classList.remove('visible'); }); } // Like button functionality if (button.classList.contains('like')) { button.addEventListener('click', () => { if (!button.classList.contains('active')) { button.classList.add('pulse', 'active'); const countElement = button.querySelector('span'); countElement.textContent = (parseInt(countElement.textContent) + 1).toString(); setTimeout(() => { button.classList.remove('pulse'); }, 500); showNotification('You liked this post!'); } else { button.classList.remove('active'); const countElement = button.querySelector('span'); countElement.textContent = (parseInt(countElement.textContent) - 1).toString(); showNotification('You unliked this post'); } }); } // Bookmark functionality if (button.classList.contains('bookmark')) { button.addEventListener('click', () => { button.classList.toggle('active'); if (button.classList.contains('active')) { button.classList.add('pulse'); showNotification('Post saved to your bookmarks'); setTimeout(() => { button.classList.remove('pulse'); }, 500); } else { showNotification('Post removed from your bookmarks'); } }); } // Share functionality if (button.classList.contains('share')) { button.addEventListener('click', () => { button.classList.add('pulse'); showNotification('Share options opened'); setTimeout(() => { button.classList.remove('pulse'); }, 500); }); } // Comment functionality if (button.classList.contains('comment')) { button.addEventListener('click', () => { const commentInput = button.closest('.post').querySelector('.comment-input'); commentInput.focus(); }); } }); // Reaction emojis const reactionEmojis = document.querySelectorAll('.reaction-emoji'); reactionEmojis.forEach(emoji => { emoji.addEventListener('click', (e) => { e.stopPropagation(); const reaction = emoji.getAttribute('data-reaction'); const likeButton = emoji.closest('.like'); // Hide panel after selection const reactionsPanel = emoji.closest('.reactions-panel'); reactionsPanel.classList.remove('visible'); // Update like button if (!likeButton.classList.contains('active')) { likeButton.classList.add('active'); const countElement = likeButton.querySelector('span'); countElement.textContent = (parseInt(countElement.textContent) + 1).toString(); } // Show notification with the emoji showNotification(`You reacted with ${reaction}`); emoji.classList.add('pulse'); setTimeout(() => { emoji.classList.remove('pulse'); }, 500); }); }); // Comment form functionality const commentForms = document.querySelectorAll('.comment-form'); commentForms.forEach(form => { const input = form.querySelector('.comment-input'); const button = form.querySelector('.send-button'); button.addEventListener('click', () => { if (input.value.trim() !== '') { showNotification('Comment posted successfully!'); // Increment comment count const commentButton = form.closest('.post').querySelector('.action-button.comment'); const countElement = commentButton.querySelector('span'); countElement.textContent = (parseInt(countElement.textContent) + 1).toString(); input.value = ''; button.classList.add('pulse'); setTimeout(() => { button.classList.remove('pulse'); }, 500); } else { showNotification('Please enter a comment first'); } }); // Allow Enter key to submit comment input.addEventListener('keypress', (e) => { if (e.key === 'Enter' && input.value.trim() !== '') { e.preventDefault(); button.click(); } }); // Input tooltip const tooltip = document.createElement('div'); tooltip.classList.add('tooltip'); tooltip.textContent = input.getAttribute('data-tooltip'); input.insertAdjacentElement('afterend', tooltip); input.addEventListener('focus', () => { tooltip.classList.add('visible'); setTimeout(() => { tooltip.classList.remove('visible'); }, 2000); }); }); // Notification system function showNotification(message) { const notification = document.querySelector('.notification'); notification.textContent = message; notification.classList.add('show'); setTimeout(() => { notification.classList.remove('show'); }, 3000); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --neon-primary: #00f3ff; --neon-secondary: #ff00e6; --neon-tertiary: #0aff0a; --dark-bg: #0a0a14; --darker-bg: #050508; --glow-spread: 15px; --transition-speed: 0.3s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Rajdhani', 'Orbitron', sans-serif; } body { background: var(--dark-bg); background-image: radial-gradient(circle at 10% 20%, rgba(0, 243, 255, 0.03) 0%, transparent 20%), radial-gradient(circle at 90% 80%, rgba(255, 0, 230, 0.03) 0%, transparent 20%), radial-gradient(circle at 50% 50%, rgba(10, 255, 10, 0.03) 0%, transparent 30%); color: #fff; height: 100vh; width: 100%; overflow-x: hidden; display: flex; justify-content: center; align-items: center; position: relative; } body::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%231a1a2a' fill-opacity='0.2' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='1'/%3E%3Ccircle cx='13' cy='13' r='1'/%3E%3C/g%3E%3C/svg%3E"); z-index: -1; } .container { width: 95%; max-width: 650px; padding: 20px; background: var(--darker-bg); border-radius: 10px; box-shadow: 0 0 30px rgba(0, 243, 255, 0.1); position: relative; overflow: hidden; } .container::before { content: ''; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; background: linear-gradient(45deg, var(--neon-primary), var(--neon-secondary), var(--neon-tertiary), var(--neon-primary)); border-radius: 12px; z-index: -1; animation: borderGlow 8s linear infinite; } .header { text-align: center; margin-bottom: 30px; position: relative; } h1 { font-size: 2.5rem; margin-bottom: 10px; background: linear-gradient(90deg, var(--neon-primary), var(--neon-secondary)); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: 0 0 5px rgba(0, 243, 255, 0.5); position: relative; letter-spacing: 2px; } .tagline { font-size: 1rem; color: rgba(255, 255, 255, 0.7); margin-bottom: 15px; } .game-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 20px; margin-bottom: 30px; } .game-card { background: rgba(10, 10, 20, 0.8); border-radius: 8px; overflow: hidden; transition: all var(--transition-speed); cursor: pointer; position: relative; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); } .game-card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 243, 255, 0.2); } .game-card:hover::before { opacity: 1; } .game-card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(45deg, rgba(0, 243, 255, 0.2), rgba(255, 0, 230, 0.2)); opacity: 0; transition: opacity var(--transition-speed); z-index: 1; pointer-events: none; } .game-image { width: 100%; height: 120px; object-fit: cover; display: block; background-size: cover; background-position: center; position: relative; z-index: 0; } .game-image img { width: 100%; height: 100%; object-fit: cover; position: relative; z-index: 0; } .game-details { padding: 15px 10px; position: relative; z-index: 2; } .game-title { font-size: 1rem; font-weight: 600; margin-bottom: 5px; color: white; } .game-genre { font-size: 0.8rem; color: var(--neon-primary); opacity: 0.8; } .tooltip-container { position: relative; } .tooltip { visibility: hidden; position: absolute; bottom: 120%; left: 50%; transform: translateX(-50%) scale(0.9); width: 200px; background: rgba(5, 5, 10, 0.95); color: white; text-align: center; border-radius: 8px; padding: 15px; z-index: 10; opacity: 0; transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); box-shadow: 0 0 20px rgba(0, 243, 255, 0.3), 0 0 30px rgba(0, 243, 255, 0.1), inset 0 0 15px rgba(0, 243, 255, 0.1); } .tooltip::after { content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border-width: 8px; border-style: solid; border-color: rgba(5, 5, 10, 0.95) transparent transparent transparent; } .tooltip-container:hover .tooltip { visibility: visible; opacity: 1; transform: translateX(-50%) scale(1); animation: pulsateGlow 2s infinite; } .tooltip-title { font-size: 1rem; font-weight: 600; margin-bottom: 8px; color: var(--neon-primary); text-shadow: 0 0 8px var(--neon-primary); } .tooltip-content { font-size: 0.85rem; line-height: 1.4; } .tooltip-stat { display: flex; justify-content: space-between; margin-top: 8px; font-size: 0.8rem; } .tooltip-stat span:first-child { color: rgba(255, 255, 255, 0.7); } .tooltip-stat span:last-child { color: var(--neon-tertiary); font-weight: 600; } .feature-section { margin-top: 30px; } .features-container { display: flex; justify-content: space-around; gap: 15px; flex-wrap: wrap; } .feature-item { background: rgba(10, 10, 20, 0.7); padding: 20px; border-radius: 8px; text-align: center; flex: 1; min-width: 180px; transition: all var(--transition-speed); position: relative; overflow: hidden; cursor: pointer; } .feature-item:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 243, 255, 0.2); } .feature-item::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 5px; background: linear-gradient(90deg, var(--neon-primary), var(--neon-secondary)); z-index: 1; transition: height 0.5s ease; } .feature-item:hover::before { height: 100%; opacity: 0.1; } .feature-icon { font-size: 2rem; margin-bottom: 15px; color: var(--neon-secondary); position: relative; } .feature-icon::after { content: ''; position: absolute; width: 30px; height: 30px; background: rgba(255, 0, 230, 0.1); border-radius: 50%; z-index: -1; top: 50%; left: 50%; transform: translate(-50%, -50%); } .feature-title { font-size: 1.1rem; font-weight: 600; margin-bottom: 8px; color: white; } .feature-desc { font-size: 0.85rem; color: rgba(255, 255, 255, 0.7); line-height: 1.4; } .action-button { display: inline-block; padding: 12px 30px; background: linear-gradient(45deg, var(--neon-primary), var(--neon-secondary)); color: white; border: none; border-radius: 30px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all var(--transition-speed); position: relative; overflow: hidden; z-index: 1; margin-top: 25px; text-transform: uppercase; letter-spacing: 1px; box-shadow: 0 0 15px rgba(0, 243, 255, 0.3); } .action-button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: all 0.5s; z-index: -1; } .action-button:hover::before { left: 100%; } .action-button:hover { transform: translateY(-3px); box-shadow: 0 10px 25px rgba(0, 243, 255, 0.4); } .button-container { display: flex; justify-content: center; } .floating-particles { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: hidden; z-index: -1; } .particle { position: absolute; width: 3px; height: 3px; background: var(--neon-primary); border-radius: 50%; pointer-events: none; opacity: 0.5; } .navbar { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; margin-bottom: 20px; border-bottom: 1px solid rgba(0, 243, 255, 0.2); } .nav-link { color: rgba(255, 255, 255, 0.8); margin: 0 15px; text-decoration: none; font-size: 0.9rem; letter-spacing: 1px; transition: all var(--transition-speed); position: relative; } .nav-link::after { content: ''; position: absolute; bottom: -5px; left: 0; width: 0; height: 2px; background: var(--neon-primary); transition: width var(--transition-speed); } .nav-link:hover { color: white; text-shadow: 0 0 8px var(--neon-primary); } .nav-link:hover::after { width: 100%; } .nav-icon { color: var(--neon-primary); margin-right: 10px; } @keyframes pulsateGlow { 0% { box-shadow: 0 0 5px rgba(0, 243, 255, 0.3), 0 0 10px rgba(0, 243, 255, 0.1), inset 0 0 5px rgba(0, 243, 255, 0.1); } 50% { box-shadow: 0 0 15px rgba(0, 243, 255, 0.5), 0 0 20px rgba(0, 243, 255, 0.2), inset 0 0 10px rgba(0, 243, 255, 0.2); } 100% { box-shadow: 0 0 5px rgba(0, 243, 255, 0.3), 0 0 10px rgba(0, 243, 255, 0.1), inset 0 0 5px rgba(0, 243, 255, 0.1); } } @keyframes borderGlow { 0% { opacity: 0.2; } 50% { opacity: 0.5; } 100% { opacity: 0.2; } } @keyframes floatParticle { 0% { transform: translateY(0) translateX(0); opacity: 1; } 100% { transform: translateY(-100px) translateX(20px); opacity: 0; } } @media screen and (max-width: 600px) { .game-cards { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); } .features-container { flex-direction: column; } h1 { font-size: 1.8rem; } .feature-item { min-width: unset; } .tooltip { width: 160px; padding: 10px; } } </style> </head> <body> <div class="floating-particles" id="particles"></div> <div class="container"> <div class="navbar"> <div class="nav-links"> <a href="#" class="nav-link"><i class="nav-icon">⚡</i>Discover</a> <a href="#" class="nav-link"><i class="nav-icon">🔥</i>Rankings</a> </div> <div class="nav-links"> <a href="#" class="nav-link"><i class="nav-icon">👤</i>Profile</a> <a href="#" class="nav-link"><i class="nav-icon">🔍</i>Search</a> </div> </div> <div class="header"> <h1>NEXUS ARCADE</h1> <p class="tagline">Enter the realm of next-gen gaming experiences</p> </div> <div class="game-cards"> <div class="game-card tooltip-container"> <div class="game-image" style="background-color: #171723;"></div> <div class="game-details"> <div class="game-title">Cyber Pulse</div> <div class="game-genre">Cyberpunk RPG</div> </div> <div class="tooltip"> <div class="tooltip-title">Cyber Pulse</div> <div class="tooltip-content">A neon-drenched cyberpunk RPG where your neural implants determine your fate in Night City.</div> <div class="tooltip-stat"> <span>Players:</span> <span>127,842 online</span> </div> <div class="tooltip-stat"> <span>Rating:</span> <span>9.2/10</span> </div> </div> </div> <div class="game-card tooltip-container"> <div class="game-image" style="background-color: #2a1a36;"></div> <div class="game-details"> <div class="game-title">Quantum Break</div> <div class="game-genre">Sci-Fi Shooter</div> </div> <div class="tooltip"> <div class="tooltip-title">Quantum Break</div> <div class="tooltip-content">Manipulate time in this reality-bending shooter with parallel timeline mechanics.</div> <div class="tooltip-stat"> <span>Players:</span> <span>86,315 online</span> </div> <div class="tooltip-stat"> <span>Rating:</span> <span>8.7/10</span> </div> </div> </div> <div class="game-card tooltip-container"> <div class="game-image" style="background-color: #0f2433;"></div> <div class="game-details"> <div class="game-title">Neo Drift</div> <div class="game-genre">Racing</div> </div> <div class="tooltip"> <div class="tooltip-title">Neo Drift</div> <div class="tooltip-content">Ultra-fast anti-gravity racing with customizable hover vehicles and psychedelic neon tracks.</div> <div class="tooltip-stat"> <span>Players:</span> <span>62,739 online</span> </div> <div class="tooltip-stat"> <span>Rating:</span> <span>9.0/10</span> </div> </div> </div> </div> <div class="feature-section"> <div class="features-container"> <div class="feature-item"> <div class="feature-icon">🎮</div> <div class="feature-title">Cloud Gaming</div> <div class="feature-desc">Play AAA titles instantly with no downloads on any device with our quantum streaming tech.</div> </div> <div class="feature-item"> <div class="feature-icon">🏆</div> <div class="feature-title">Neural Matchmaking</div> <div class="feature-desc">Our AI pairs you with players that match your skill level and playstyle perfectly.</div> </div> <div class="feature-item"> <div class="feature-icon">💎</div> <div class="feature-title">Holo Rewards</div> <div class="feature-desc">Earn exclusive holographic skins and digital collectibles as you level up your profile.</div> </div> </div> </div> <div class="button-container"> <button class="action-button">Access The Grid</button> </div> </div> <script> // Create and animate floating particles const particlesContainer = document.getElementById('particles'); const numParticles = 30; const colors = ['#00f3ff', '#ff00e6', '#0aff0a']; function createParticles() { for (let i = 0; i < numParticles; i++) { const particle = document.createElement('div'); particle.classList.add('particle'); // Random position const left = Math.random() * 100; const top = Math.random() * 100; // Random size const size = Math.random() * 3 + 1; // Random color const colorIndex = Math.floor(Math.random() * colors.length); particle.style.left = `${left}%`; particle.style.top = `${top}%`; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.backgroundColor = colors[colorIndex]; // Animation const duration = Math.random() * 10 + 5; particle.style.animation = `floatParticle ${duration}s linear infinite`; particle.style.animationDelay = `${Math.random() * 5}s`; particlesContainer.appendChild(particle); } } // Generate image backgrounds for game cards function generateGameCardBackgrounds() { const gameImages = document.querySelectorAll('.game-image'); gameImages.forEach((image, index) => { const colors = [ ['#6a1b9a', '#4a148c'], // Purple shades ['#1a237e', '#0d47a1'], // Blue shades ['#004d40', '#006064'] // Teal shades ]; const gradientIndex = index % colors.length; const angle = Math.floor(Math.random() * 360); image.style.background = `linear-gradient(${angle}deg, ${colors[gradientIndex][0]}, ${colors[gradientIndex][1]})`; // Add dynamic pattern overlay const patternType = Math.floor(Math.random() * 3); if (patternType === 0) { image.style.backgroundImage = `${image.style.backgroundImage}, repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 0px, rgba(255,255,255,0.05) 2px, transparent 2px, transparent 4px)`; } else if (patternType === 1) { image.style.backgroundImage = `${image.style.backgroundImage}, radial-gradient(circle at 50% 50%, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0.08) 1px, transparent 1px, transparent)`; image.style.backgroundSize = `100%, 10px 10px`; } else { image.style.backgroundImage = `${image.style.backgroundImage}, linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px), linear-gradient(0deg, rgba(255,255,255,0.03) 1px, transparent 1px)`; image.style.backgroundSize = `100%, 20px 20px, 20px 20px`; } }); } // Tooltip animation enhancement function setupTooltipAnimations() { const tooltips = document.querySelectorAll('.tooltip'); tooltips.forEach(tooltip => { const container = tooltip.parentElement; container.addEventListener('mouseenter', () => { tooltip.style.animation = 'pulsateGlow 2s infinite'; }); container.addEventListener('mouseleave', () => { tooltip.style.animation = 'none'; }); }); } // Initialize when the document is loaded document.addEventListener('DOMContentLoaded', () => { createParticles(); generateGameCardBackgrounds(); setupTooltipAnimations(); // Button click animation const actionButton = document.querySelector('.action-button'); actionButton.addEventListener('click', function(e) { const x = e.clientX - e.target.getBoundingClientRect().left; const y = e.clientY - e.target.getBoundingClientRect().top; const ripple = document.createElement('span'); ripple.style.position = 'absolute'; ripple.style.width = '1px'; ripple.style.height = '1px'; ripple.style.borderRadius = '50%'; ripple.style.backgroundColor = 'rgba(255, 255, 255, 0.7)'; ripple.style.transform = 'scale(0)'; ripple.style.animation = 'ripple 0.6s linear'; ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 700); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Corporate Intranet Tooltips</title> <style> :root { --primary: #2c3e50; --secondary: #34495e; --accent: #3498db; --light: #ecf0f1; --border: #bdc3c7; --text: #2c3e50; --text-light: #7f8c8d; --shadow: rgba(0, 0, 0, 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 700px; background-color: #f5f7fa; padding: 20px; color: var(--text); } .intranet-header { width: 100%; max-width: 600px; text-align: center; margin-bottom: 30px; } .intranet-header h1 { font-size: 28px; margin-bottom: 10px; color: var(--primary); font-weight: 500; } .intranet-header p { font-size: 16px; color: var(--text-light); line-height: 1.5; } .dashboard { display: flex; flex-wrap: wrap; justify-content: center; width: 100%; max-width: 640px; gap: 20px; margin-bottom: 40px; } .dashboard-item { position: relative; background-color: white; border-radius: 6px; padding: 24px; width: calc(50% - 20px); min-width: 250px; box-shadow: 0 2px 10px var(--shadow); cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; border-top: 3px solid var(--accent); } .dashboard-item:hover { transform: translateY(-2px); box-shadow: 0 4px 15px var(--shadow); } .dashboard-item h3 { font-size: 18px; margin-bottom: 12px; color: var(--primary); display: flex; align-items: center; } .dashboard-item p { font-size: 14px; color: var(--text-light); line-height: 1.4; } .info-icon { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background-color: var(--accent); color: white; font-size: 12px; font-weight: bold; margin-left: 8px; cursor: help; transition: background-color 0.2s ease; } .info-icon:hover { background-color: #2980b9; } .tooltip { position: absolute; visibility: hidden; opacity: 0; width: 280px; background-color: white; color: var(--text); border-radius: 4px; padding: 12px 16px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15); font-size: 13px; line-height: 1.5; z-index: 100; transition: opacity 0.25s ease, transform 0.25s ease; transform: translateY(10px); border: 1px solid var(--border); left: calc(100% - 40px); top: calc(100% - 20px); pointer-events: none; } .tooltip.show { visibility: visible; opacity: 1; transform: translateY(0); } .tooltip::before { content: ""; position: absolute; top: -8px; left: 20px; border-width: 0 8px 8px 8px; border-style: solid; border-color: transparent transparent var(--border) transparent; } .tooltip::after { content: ""; position: absolute; top: -7px; left: 20px; border-width: 0 8px 8px 8px; border-style: solid; border-color: transparent transparent white transparent; } .tooltip-header { font-weight: 600; margin-bottom: 8px; color: var(--primary); border-bottom: 1px solid var(--border); padding-bottom: 6px; } .tooltip-content { margin-bottom: 10px; } .tooltip-footer { font-size: 12px; color: var(--text-light); display: flex; justify-content: space-between; align-items: center; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); } .tooltip-footer a { color: var(--accent); text-decoration: none; font-weight: 500; transition: color 0.2s ease; } .tooltip-footer a:hover { color: #2980b9; text-decoration: underline; } .tooltip-icon { color: var(--accent); margin-right: 6px; } .tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; } .tag { font-size: 11px; background-color: #edf2f7; color: var(--text-light); padding: 3px 8px; border-radius: 20px; } @media (max-width: 600px) { .dashboard-item { width: 100%; } .tooltip { width: 220px; left: 50%; transform: translateX(-50%) translateY(10px); } .tooltip.show { transform: translateX(-50%) translateY(0); } .tooltip::before, .tooltip::after { left: 50%; margin-left: -8px; } } .note { background-color: #f8f9fa; border-left: 3px solid var(--accent); padding: 10px 15px; margin-top: 20px; font-size: 13px; color: var(--text-light); width: 100%; max-width: 640px; border-radius: 0 4px 4px 0; } .note strong { color: var(--primary); } .icon { display: inline-block; width: 16px; height: 16px; margin-right: 8px; vertical-align: text-bottom; } </style> </head> <body> <div class="intranet-header"> <h1>Enterprise Resource Dashboard</h1> <p>Access your departmental resources and track key metrics. Hover over information icons for detailed descriptions.</p> </div> <div class="dashboard"> <div class="dashboard-item"> <h3> Q4 Expense Reports <span class="info-icon" id="expense-info">i</span> </h3> <p>Submit and track departmental expense approvals through the automated workflow system.</p> <div class="tags"> <span class="tag">Finance</span> <span class="tag">Approvals</span> </div> <div class="tooltip" id="expense-tooltip"> <div class="tooltip-header"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path></svg> Expense Reporting System </div> <div class="tooltip-content"> Submit expenses for approval using the standard GL codes. All expenses over $500 require director approval, while those over $2,000 need VP sign-off. </div> <div class="tooltip-footer"> <span>Updated: Oct 15, 2023</span> <a href="#">View Policy</a> </div> </div> </div> <div class="dashboard-item"> <h3> Document Repository <span class="info-icon" id="document-info">i</span> </h3> <p>Access, store, and collaborate on shared departmental documents with version control.</p> <div class="tags"> <span class="tag">Knowledge Base</span> <span class="tag">Collaboration</span> </div> <div class="tooltip" id="document-tooltip"> <div class="tooltip-header"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg> Document Management </div> <div class="tooltip-content"> All corporate templates and SOP documentation are stored here. Documents follow the naming convention: DEPT-TYPE-YYYYMMDD. Check out is required for editing. </div> <div class="tooltip-footer"> <span>Storage: 785GB/1TB</span> <a href="#">Access Guide</a> </div> </div> </div> <div class="dashboard-item"> <h3> Project Tracker <span class="info-icon" id="project-info">i</span> </h3> <p>Monitor timelines, resource allocation, and dependencies for active departmental initiatives.</p> <div class="tags"> <span class="tag">Project Management</span> <span class="tag">Gantt</span> </div> <div class="tooltip" id="project-tooltip"> <div class="tooltip-header"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg> Project Management Tool </div> <div class="tooltip-content"> Update project status by EOD each Friday. Red/Amber/Green status indicators follow enterprise PMO methodology. Use the resource calculator when requesting new allocations. </div> <div class="tooltip-footer"> <span>Active Projects: 17</span> <a href="#">Project Template</a> </div> </div> </div> <div class="dashboard-item"> <h3> Compliance Training <span class="info-icon" id="training-info">i</span> </h3> <p>Complete required annual training modules and track completion status for your team.</p> <div class="tags"> <span class="tag">HR</span> <span class="tag">Required</span> </div> <div class="tooltip" id="training-tooltip"> <div class="tooltip-header"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 14l9-5-9-5-9 5 9 5z"></path><path d="M12 14l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14z"></path><path d="M12 14l-6 3.5V21"></path></svg> Learning Management System </div> <div class="tooltip-content"> Q4 compliance deadlines: Cybersecurity (Nov 15), Ethics (Dec 1), Privacy (Dec 10). All modules require assessment scores of 80%+ to be marked complete. </div> <div class="tooltip-footer"> <span>Your completion: 2/4</span> <a href="#">View Courses</a> </div> </div> </div> </div> <div class="note"> <strong>Pro Tip:</strong> Hover over the information icons <span class="info-icon" style="width: 14px; height: 14px; font-size: 10px; margin: 0 3px;">i</span> throughout the intranet for helpful context and detailed instructions for each enterprise system. </div> <script> // Tooltip functionality document.addEventListener('DOMContentLoaded', function() { const infoIcons = document.querySelectorAll('.info-icon'); const tooltips = document.querySelectorAll('.tooltip'); // Tooltip position adjustment function function adjustTooltipPosition(tooltip) { const rect = tooltip.getBoundingClientRect(); const viewportWidth = window.innerWidth; // If tooltip would go off the right side of the screen if (rect.right > viewportWidth && viewportWidth > 600) { tooltip.style.left = 'auto'; tooltip.style.right = 'calc(100% - 40px)'; tooltip.style.top = '0'; // Move arrow to the right side tooltip.style.setProperty('--arrow-left', 'auto'); tooltip.style.setProperty('--arrow-right', '20px'); } // Reset if window resizes and tooltip would fit again if (rect.right <= viewportWidth && tooltip.style.right) { tooltip.style.left = 'calc(100% - 40px)'; tooltip.style.right = 'auto'; tooltip.style.top = 'calc(100% - 20px)'; } } // Set up event listeners for each info icon infoIcons.forEach(icon => { const tooltipId = icon.id.replace('-info', '-tooltip'); const tooltip = document.getElementById(tooltipId); // Show tooltip on mouseover icon.addEventListener('mouseover', function() { // Hide all other tooltips tooltips.forEach(t => t.classList.remove('show')); // Show this tooltip tooltip.classList.add('show'); adjustTooltipPosition(tooltip); }); // Hide tooltip on mouseout icon.addEventListener('mouseout', function() { tooltip.classList.remove('show'); }); // For touch devices icon.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); if (tooltip.classList.contains('show')) { tooltip.classList.remove('show'); } else { // Hide all other tooltips tooltips.forEach(t => t.classList.remove('show')); // Show this tooltip tooltip.classList.add('show'); adjustTooltipPosition(tooltip); } }); }); // Hide tooltips when clicking elsewhere document.addEventListener('click', function() { tooltips.forEach(tooltip => { tooltip.classList.remove('show'); }); }); // Adjust tooltip positions on window resize window.addEventListener('resize', function() { tooltips.forEach(tooltip => { if (tooltip.classList.contains('show')) { adjustTooltipPosition(tooltip); } }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Global Discovery Tooltips</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f7f9fc; display: flex; flex-direction: column; justify-content: center; align-items: center; min-height: 100vh; padding: 1rem; overflow-x: hidden; } .container { width: 100%; max-width: 700px; padding: 1.5rem; border-radius: 12px; background: linear-gradient(135deg, #ffffff, #f0f4f8); box-shadow: 0 8px 32px rgba(31, 38, 135, 0.1); position: relative; overflow: hidden; } h1 { font-size: 2.2rem; color: #2d3748; margin-bottom: 1rem; text-align: center; background: linear-gradient(135deg, #3a7bd5, #3a6073); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 800; } .subtitle { text-align: center; color: #4a5568; margin-bottom: 2rem; font-size: 1.1rem; line-height: 1.5; } .map-container { position: relative; width: 100%; height: 400px; overflow: hidden; border-radius: 10px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); margin-bottom: 1rem; background: url('https://images.unsplash.com/photo-1531737212413-667205e1cdb7?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80') center/cover no-repeat; } .location-point { position: absolute; width: 24px; height: 24px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.9); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; z-index: 10; } .location-point:before { content: ""; position: absolute; width: 12px; height: 12px; border-radius: 50%; background: linear-gradient(135deg, #ff7e5f, #feb47b); animation: pulse 2s infinite; } .location-point:hover { transform: scale(1.2); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); } .tooltip { position: absolute; width: 280px; background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); border-radius: 10px; padding: 1rem; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); opacity: 0; visibility: hidden; transform: translateY(10px); transition: all 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55); z-index: 100; overflow: hidden; } .tooltip::after { content: ''; position: absolute; width: 100%; height: 5px; background: linear-gradient(to right, #ff7e5f, #feb47b); top: 0; left: 0; } .tooltip.active { opacity: 1; visibility: visible; transform: translateY(0); } .tooltip-header { width: 100%; height: 120px; background-size: cover; background-position: center; border-radius: 6px; margin-bottom: 0.8rem; position: relative; overflow: hidden; } .tooltip-header::before { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 40%; background: linear-gradient(to top, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0)); } .tooltip-name { position: absolute; bottom: 10px; left: 10px; color: white; font-size: 1.2rem; font-weight: 600; z-index: 2; } .tooltip-content p { color: #4a5568; font-size: 0.9rem; line-height: 1.5; margin-bottom: 0.8rem; } .tooltip-tag { display: inline-block; padding: 4px 10px; background: rgba(58, 123, 213, 0.1); color: #3a7bd5; border-radius: 20px; font-size: 0.75rem; margin-right: 5px; margin-bottom: 5px; } .controls { display: flex; justify-content: center; margin-top: 1rem; } .region-btn { padding: 0.6rem 1.2rem; margin: 0 0.5rem; background: linear-gradient(135deg, #3a7bd5, #3a6073); color: white; border: none; border-radius: 25px; cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; font-weight: 500; box-shadow: 0 4px 15px rgba(58, 123, 213, 0.2); } .region-btn:hover { transform: translateY(-3px); box-shadow: 0 7px 20px rgba(58, 123, 213, 0.3); } .region-btn:active { transform: translateY(1px); } @keyframes pulse { 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 126, 95, 0.7); } 70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(255, 126, 95, 0); } 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 126, 95, 0); } } @media (max-width: 600px) { h1 { font-size: 1.8rem; } .map-container { height: 350px; } .tooltip { width: 240px; } .controls { flex-wrap: wrap; } .region-btn { margin-bottom: 0.5rem; font-size: 0.9rem; } } </style> </head> <body> <div class="container"> <h1>Destination Discovery</h1> <p class="subtitle">Hover over the points to discover hidden gems and local insights across the globe.</p> <div class="map-container" id="mapContainer"> <!-- Location points will be dynamically added here --> </div> <div class="controls"> <button class="region-btn" data-region="asia">Asia</button> <button class="region-btn" data-region="europe">Europe</button> <button class="region-btn" data-region="americas">Americas</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const mapContainer = document.getElementById('mapContainer'); const regionButtons = document.querySelectorAll('.region-btn'); // Location data organized by region const locations = { asia: [ { name: "Hoi An, Vietnam", x: 70, y: 50, image: "https://images.unsplash.com/photo-1552465011-b4e21bf6e79a?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "Visit during the Full Moon Lantern Festival when the ancient town turns off all electric lights, creating a magical atmosphere with thousands of colorful lanterns.", tags: ["Cultural Heritage", "Local Cuisine", "Photography"] }, { name: "Hitachi Seaside Park, Japan", x: 85, y: 35, image: "https://images.unsplash.com/photo-1576675466969-38eeae4b41f6?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "Time your visit for late April to see the stunning blue nemophila flowers in full bloom, creating a sea of blue that perfectly mirrors the sky above.", tags: ["Natural Beauty", "Seasonal", "Off-Beat"] }, { name: "Jaipur, India", x: 30, y: 65, image: "https://images.unsplash.com/photo-1477586957327-847a0f3f4fe3?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "The locals recommend visiting Patrika Gate at sunrise for the best photos without crowds and perfect lighting for the intricate painted arches.", tags: ["Architecture", "History", "Photography"] } ], europe: [ { name: "Sintra, Portugal", x: 25, y: 40, image: "https://images.unsplash.com/photo-1574612267701-306070fb8970?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "Arrive at Pena Palace before 9am to avoid crowds and catch the morning fog lifting from the fairytale castle - a sight that feels straight out of a storybook.", tags: ["Architecture", "Historical", "Day Trip"] }, { name: "Lake Bled, Slovenia", x: 50, y: 25, image: "https://images.unsplash.com/photo-1534522804661-92edc364986f?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "Take the hidden trail starting near Vila Bled for the most breathtaking panoramic view that most tourists never discover.", tags: ["Nature", "Hiking", "Photography"] }, { name: "Hallstatt, Austria", x: 65, y: 55, image: "https://images.unsplash.com/photo-1547131889-79fc78e83ff7?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "The salt mines offer more than just history - book the slide experience to travel between mining levels the way miners did centuries ago.", tags: ["Alpine Village", "UNESCO Site", "Cultural"] } ], americas: [ { name: "Oaxaca, Mexico", x: 40, y: 70, image: "https://images.unsplash.com/photo-1580275266018-32b090fbac6e?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "Visit the Hierve el Agua petrified waterfalls at dawn when the morning light creates the illusion that the calcium formations are actually flowing water.", tags: ["Culinary Heaven", "Indigenous Culture", "Natural Wonders"] }, { name: "Banff National Park, Canada", x: 20, y: 30, image: "https://images.unsplash.com/photo-1576418601862-0e935cee7cc8?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "For a unique perspective of Moraine Lake without the crowds, take the lesser-known Consolation Lakes trail that branches off from the main viewpoint.", tags: ["Wilderness", "Photography", "Hiking"] }, { name: "Cartagena, Colombia", x: 60, y: 80, image: "https://images.unsplash.com/photo-1561716536-567f9060662c?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", description: "The locals' secret for the best ceviche is at the small stands in Mercado Bazurto - far from tourist areas but worth the adventure for authentic flavors.", tags: ["Colonial Architecture", "Caribbean Culture", "Gastronomy"] } ] }; // Set initial region let currentRegion = 'asia'; displayLocations(currentRegion); // Map background images for each region const regionMaps = { asia: "https://images.unsplash.com/photo-1493780474015-ba834fd0ce2f?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", europe: "https://images.unsplash.com/photo-1467269204594-9661b134dd2b?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80", americas: "https://images.unsplash.com/photo-1531737212413-667205e1cdb7?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80" }; // Handle region button clicks regionButtons.forEach(button => { button.addEventListener('click', () => { const region = button.dataset.region; if (region !== currentRegion) { currentRegion = region; mapContainer.style.backgroundImage = `url('${regionMaps[region]}')`; // Fade out effect mapContainer.style.opacity = 0; setTimeout(() => { // Clear existing locations and tooltips mapContainer.innerHTML = ''; // Display new locations displayLocations(currentRegion); // Fade in effect mapContainer.style.opacity = 1; }, 300); } }); }); function displayLocations(region) { // Update map background mapContainer.style.backgroundImage = `url('${regionMaps[region]}')`; mapContainer.style.transition = 'opacity 0.3s ease'; // Add location points locations[region].forEach(location => { // Create location point const point = document.createElement('div'); point.className = 'location-point'; point.style.left = `${location.x}%`; point.style.top = `${location.y}%`; // Create tooltip const tooltip = document.createElement('div'); tooltip.className = 'tooltip'; // Position tooltip based on location point position if (location.x > 70) { tooltip.style.right = '30px'; tooltip.style.left = 'auto'; } else if (location.x < 30) { tooltip.style.left = '30px'; tooltip.style.right = 'auto'; } else { tooltip.style.left = '50%'; tooltip.style.transform = 'translateX(-50%) translateY(10px)'; } if (location.y > 70) { tooltip.style.bottom = '30px'; tooltip.style.top = 'auto'; } else { tooltip.style.top = '30px'; tooltip.style.bottom = 'auto'; } // Tooltip content const tooltipHeader = document.createElement('div'); tooltipHeader.className = 'tooltip-header'; tooltipHeader.style.backgroundImage = `url('${location.image}')`; const tooltipName = document.createElement('div'); tooltipName.className = 'tooltip-name'; tooltipName.textContent = location.name; const tooltipContent = document.createElement('div'); tooltipContent.className = 'tooltip-content'; const description = document.createElement('p'); description.textContent = location.description; const tagsContainer = document.createElement('div'); tagsContainer.className = 'tooltip-tags'; location.tags.forEach(tag => { const tagElement = document.createElement('span'); tagElement.className = 'tooltip-tag'; tagElement.textContent = tag; tagsContainer.appendChild(tagElement); }); tooltipHeader.appendChild(tooltipName); tooltipContent.appendChild(description); tooltipContent.appendChild(tagsContainer); tooltip.appendChild(tooltipHeader); tooltip.appendChild(tooltipContent); // Mouse events point.addEventListener('mouseenter', () => { tooltip.classList.add('active'); if (tooltip.style.transform.includes('translateX')) { tooltip.style.transform = 'translateX(-50%) translateY(0)'; } }); point.addEventListener('mouseleave', () => { tooltip.classList.remove('active'); if (tooltip.style.transform.includes('translateX')) { tooltip.style.transform = 'translateX(-50%) translateY(10px)'; } }); point.addEventListener('touchstart', (e) => { e.preventDefault(); const allTooltips = document.querySelectorAll('.tooltip'); allTooltips.forEach(t => { if (t !== tooltip) t.classList.remove('active'); }); tooltip.classList.toggle('active'); }); // Add elements to map point.appendChild(tooltip); mapContainer.appendChild(point); }); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>QuantEdge Trading Platform</title> <style> /* Reset & Base Styles */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } :root { --primary: #2962ff; --primary-dark: #0039cb; --success: #00c853; --danger: #ff1744; --neutral: #263238; --neutral-light: #546e7a; --bg: #f5f7fa; --card-bg: #ffffff; --card-hover: #f0f4f8; --border: rgba(0, 0, 0, 0.08); } body { background-color: var(--bg); color: var(--neutral); width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; overflow-x: hidden; } .container { width: 100%; max-width: 680px; padding: 1.5rem; border-radius: 12px; background-color: var(--card-bg); box-shadow: 0 8px 30px rgba(0, 0, 0, 0.07); } .platform-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; } .platform-header h1 { font-size: 1.4rem; font-weight: 600; display: flex; align-items: center; gap: 8px; } .logo-dot { display: inline-block; width: 8px; height: 8px; background-color: var(--primary); border-radius: 50%; } .status-indicator { font-size: 0.85rem; color: var(--success); display: flex; align-items: center; gap: 0.5rem; } .status-dot { width: 8px; height: 8px; background-color: var(--success); border-radius: 50%; display: inline-block; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(0, 200, 83, 0.7); } 70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(0, 200, 83, 0); } 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(0, 200, 83, 0); } } .market-summary { display: flex; gap: 1rem; margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid var(--border); } .market-card { flex: 1; padding: 1rem; border-radius: 8px; background-color: var(--bg); position: relative; cursor: pointer; overflow: hidden; transition: transform 0.2s ease, box-shadow 0.2s ease; } .market-card:hover { transform: translateY(-4px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.05); } .market-card::before { content: ''; position: absolute; left: 0; top: 0; height: 100%; width: 4px; } .market-card.up::before { background-color: var(--success); } .market-card.down::before { background-color: var(--danger); } .market-card h3 { font-size: 0.85rem; font-weight: 500; margin-bottom: 0.5rem; color: var(--neutral-light); } .price { font-size: 1.25rem; font-weight: 700; margin-bottom: 0.5rem; } .change { font-size: 0.85rem; font-weight: 600; display: flex; align-items: center; gap: 4px; } .change.positive { color: var(--success); } .change.negative { color: var(--danger); } .change i { font-size: 0.75rem; } .trading-section { margin-bottom: 1.5rem; } .section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .section-header h2 { font-size: 1rem; font-weight: 600; } .refresh-btn { background: none; border: none; color: var(--primary); font-size: 0.9rem; cursor: pointer; display: flex; align-items: center; gap: 4px; transition: color 0.2s ease; } .refresh-btn:hover { color: var(--primary-dark); } .refresh-btn i { font-size: 0.9rem; transition: transform 0.3s ease; } .refresh-btn:hover i { transform: rotate(180deg); } .watchlist { width: 100%; border-collapse: collapse; } .watchlist th { text-align: left; padding: 0.75rem 1rem; font-size: 0.8rem; font-weight: 500; color: var(--neutral-light); background-color: var(--bg); } .watchlist tr { border-bottom: 1px solid var(--border); position: relative; } .watchlist tr:hover { background-color: var(--card-hover); } .watchlist td { padding: 0.75rem 1rem; font-size: 0.9rem; position: relative; } .watchlist .symbol { font-weight: 600; } .watchlist .price-cell { font-weight: 600; cursor: pointer; position: relative; } .tooltip { position: absolute; top: -75px; left: 50%; transform: translateX(-50%) scale(0.95); width: 220px; background-color: var(--neutral); color: white; border-radius: 6px; padding: 0.75rem; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); z-index: 100; opacity: 0; pointer-events: none; transition: opacity 0.15s ease, transform 0.15s ease; } .tooltip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border-width: 6px; border-style: solid; border-color: var(--neutral) transparent transparent transparent; } .price-cell:hover .tooltip { opacity: 1; transform: translateX(-50%) scale(1); } .tooltip-heading { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; font-size: 0.9rem; color: rgba(255, 255, 255, 0.7); } .tooltip-data { display: flex; justify-content: space-between; font-size: 0.8rem; margin-bottom: 0.35rem; } .tooltip-data .label { color: rgba(255, 255, 255, 0.7); } .tooltip-data .value { font-weight: 600; } .tooltip-divider { height: 1px; background-color: rgba(255, 255, 255, 0.1); margin: 0.5rem 0; } .tooltip-footer { display: flex; justify-content: space-between; font-size: 0.75rem; color: rgba(255, 255, 255, 0.6); } .watchlist .change-cell.positive { color: var(--success); } .watchlist .change-cell.negative { color: var(--danger); } .watchlist .actions { display: flex; gap: 0.5rem; } .action-btn { background: none; border: none; cursor: pointer; color: var(--neutral-light); transition: color 0.2s ease; padding: 4px; border-radius: 4px; } .action-btn:hover { color: var(--primary); background-color: rgba(41, 98, 255, 0.1); } .action-btn.buy-btn:hover { color: var(--success); background-color: rgba(0, 200, 83, 0.1); } .quick-trade { background-color: var(--bg); border-radius: 8px; padding: 1rem; } .trade-header { display: flex; justify-content: space-between; margin-bottom: 1rem; } .trade-header h3 { font-size: 0.95rem; font-weight: 600; } .trade-header .trade-type { display: flex; gap: 0.5rem; } .trade-type button { background: none; border: none; padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.85rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; } .trade-type button.active { background-color: var(--primary); color: white; } .trade-type button:not(.active) { color: var(--neutral-light); } .trade-type button:not(.active):hover { background-color: rgba(41, 98, 255, 0.1); color: var(--primary); } .trade-form { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 1rem; } .input-group { position: relative; } .input-group label { display: block; font-size: 0.75rem; font-weight: 500; margin-bottom: 0.25rem; color: var(--neutral-light); } .input-group input { width: 100%; padding: 0.6rem; border: 1px solid var(--border); border-radius: 6px; font-size: 0.9rem; transition: border-color 0.2s ease, box-shadow 0.2s ease; } .input-group input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(41, 98, 255, 0.2); } .input-group input:hover { border-color: rgba(0, 0, 0, 0.2); } .trade-btn { grid-column: span 2; background-color: var(--primary); color: white; border: none; border-radius: 6px; padding: 0.75rem; font-size: 0.9rem; font-weight: 600; cursor: pointer; transition: background-color 0.2s ease, transform 0.1s ease; margin-top: 0.5rem; display: flex; justify-content: center; align-items: center; gap: 0.5rem; } .trade-btn.buy { background-color: var(--success); } .trade-btn.sell { background-color: var(--danger); } .trade-btn:hover { opacity: 0.9; transform: translateY(-2px); } .trade-btn:active { transform: translateY(0); } .trade-btn .success-indicator { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; background-color: white; color: var(--success); font-size: 0.6rem; opacity: 0; transform: scale(0); transition: transform 0.3s ease, opacity 0.3s ease; } .trade-btn .success-indicator.show { opacity: 1; transform: scale(1); } .spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top-color: white; animation: spin 0.8s ease-in-out infinite; opacity: 0; transition: opacity 0.2s ease; } .spinner.show { opacity: 1; } @keyframes spin { to { transform: rotate(360deg); } } .grid-span-2 { grid-column: span 2; } .success-toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%) translateY(100px); background-color: var(--success); color: white; padding: 0.75rem 1rem; border-radius: 6px; font-size: 0.9rem; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); display: flex; align-items: center; gap: 0.5rem; opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; z-index: 1000; } .success-toast.show { transform: translateX(-50%) translateY(0); opacity: 1; } .mini-chart { width: 80px; height: 30px; display: inline-block; margin-left: 10px; vertical-align: middle; } .chart-tooltip { width: 100%; height: 40px; margin-top: 0.5rem; } /* Responsive adjustments */ @media (max-width: 640px) { .market-summary { flex-direction: column; } .market-card { width: 100%; } .watchlist th, .watchlist td { padding: 0.5rem; } .trade-form { grid-template-columns: 1fr; } .trade-btn { grid-column: span 1; } .container { border-radius: 0; box-shadow: none; padding: 1rem; } } /* Additional Fancy Effects */ .glow-effect { position: absolute; bottom: 0; left: 0; width: 100%; height: 1px; background: linear-gradient(90deg, transparent, var(--primary), transparent); animation: glow-animation 2s infinite; } @keyframes glow-animation { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 0; } } .ticker-progress { position: absolute; bottom: 0; left: 0; height: 2px; background-color: var(--primary); width: 0%; } .ticker-row:hover .ticker-progress { animation: ticker-progress 2s ease-in-out; } @keyframes ticker-progress { 0% { width: 0%; } 100% { width: 100%; } } /* Icon styles */ .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; font-size: 1rem; line-height: 1; letter-spacing: normal; text-transform: none; display: inline-block; white-space: nowrap; word-wrap: normal; direction: ltr; -webkit-font-feature-settings: 'liga'; -webkit-font-smoothing: antialiased; } </style> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> </head> <body> <div class="container"> <div class="platform-header"> <h1> <span class="logo-dot"></span> QuantEdge Trader </h1> <div class="status-indicator"> <span class="status-dot"></span> Markets Open </div> </div> <div class="market-summary"> <div class="market-card up" data-ticker="SPY"> <h3>S&P 500</h3> <div class="price">$452.78</div> <div class="change positive"> <i class="material-icons">arrow_upward</i> +1.34% </div> </div> <div class="market-card down" data-ticker="QQQ"> <h3>NASDAQ</h3> <div class="price">$378.12</div> <div class="change negative"> <i class="material-icons">arrow_downward</i> -0.86% </div> </div> <div class="market-card up" data-ticker="BTC"> <h3>Bitcoin</h3> <div class="price">$63,495</div> <div class="change positive"> <i class="material-icons">arrow_upward</i> +2.10% </div> </div> </div> <div class="trading-section"> <div class="section-header"> <h2>Market Watchlist</h2> <button class="refresh-btn"> <i class="material-icons">refresh</i> Refresh </button> </div> <table class="watchlist"> <thead> <tr> <th>Symbol</th> <th>Price</th> <th>Change</th> <th>Actions</th> </tr> </thead> <tbody> <tr class="ticker-row"> <td class="symbol">AAPL</td> <td class="price-cell"> $188.92 <div class="tooltip"> <div class="tooltip-heading"> <span>AAPL</span> <span>Apple Inc</span> </div> <div class="tooltip-data"> <span class="label">Open</span> <span class="value">$187.03</span> </div> <div class="tooltip-data"> <span class="label">High</span> <span class="value">$189.45</span> </div> <div class="tooltip-data"> <span class="label">Low</span> <span class="value">$186.89</span> </div> <div class="tooltip-data"> <span class="label">Volume</span> <span class="value">32.4M</span> </div> <div class="tooltip-divider"></div> <div class="chart-tooltip" id="apple-chart"></div> <div class="tooltip-footer"> <span>Updated 42s ago</span> <span>Click to trade</span> </div> </div> <div class="ticker-progress"></div> </td> <td class="change-cell positive">+1.22%</td> <td class="actions"> <button class="action-btn buy-btn" data-symbol="AAPL" data-price="188.92"> <i class="material-icons">add_circle_outline</i> </button> <button class="action-btn" data-symbol="AAPL"> <i class="material-icons">notifications_none</i> </button> </td> </tr> <tr class="ticker-row"> <td class="symbol">MSFT</td> <td class="price-cell"> $415.72 <div class="tooltip"> <div class="tooltip-heading"> <span>MSFT</span> <span>Microsoft Corp</span> </div> <div class="tooltip-data"> <span class="label">Open</span> <span class="value">$412.91</span> </div> <div class="tooltip-data"> <span class="label">High</span> <span class="value">$417.28</span> </div> <div class="tooltip-data"> <span class="label">Low</span> <span class="value">$410.13</span> </div> <div class="tooltip-data"> <span class="label">Volume</span> <span class="value">15.7M</span> </div> <div class="tooltip-divider"></div> <div class="chart-tooltip" id="msft-chart"></div> <div class="tooltip-footer"> <span>Updated 37s ago</span> <span>Click to trade</span> </div> </div> <div class="ticker-progress"></div> </td> <td class="change-cell positive">+0.68%</td> <td class="actions"> <button class="action-btn buy-btn" data-symbol="MSFT" data-price="415.72"> <i class="material-icons">add_circle_outline</i> </button> <button class="action-btn" data-symbol="MSFT"> <i class="material-icons">notifications_none</i> </button> </td> </tr> <tr class="ticker-row"> <td class="symbol">TSLA</td> <td class="price-cell"> $237.43 <div class="tooltip"> <div class="tooltip-heading"> <span>TSLA</span> <span>Tesla Inc</span> </div> <div class="tooltip-data"> <span class="label">Open</span> <span class="value">$241.13</span> </div> <div class="tooltip-data"> <span class="label">High</span> <span class="value">$242.56</span> </div> <div class="tooltip-data"> <span class="label">Low</span> <span class="value">$235.42</span> </div> <div class="tooltip-data"> <span class="label">Volume</span> <span class="value">78.9M</span> </div> <div class="tooltip-divider"></div> <div class="chart-tooltip" id="tesla-chart"></div> <div class="tooltip-footer"> <span>Updated 15s ago</span> <span>Click to trade</span> </div> </div> <div class="ticker-progress"></div> </td> <td class="change-cell negative">-1.53%</td> <td class="actions"> <button class="action-btn buy-btn" data-symbol="TSLA" data-price="237.43"> <i class="material-icons">add_circle_outline</i> </button> <button class="action-btn" data-symbol="TSLA"> <i class="material-icons">notifications_none</i> </button> </td> </tr> </tbody> </table> </div> <div class="quick-trade"> <div class="trade-header"> <h3 id="trade-title">Quick Trade</h3> <div class="trade-type"> <button class="buy-tab active">Buy</button> <button class="sell-tab">Sell</button> </div> </div> <div class="trade-form"> <div class="input-group"> <label for="symbol">Symbol</label> <input type="text" id="symbol" placeholder="e.g. AAPL"> </div> <div class="input-group"> <label for="quantity">Quantity</label> <input type="number" id="quantity" placeholder="Shares" min="1"> </div> <div class="input-group"> <label for="price">Price ($)</label> <input type="number" id="price" placeholder="Market price" step="0.01"> </div> <div class="input-group"> <label for="value">Est. Value</label> <input type="text" id="value" placeholder="$0.00" readonly> </div> <button class="trade-btn buy"> <span class="spinner"></span> <span class="btn-text">Buy Now</span> <span class="success-indicator">✓</span> </button> </div> </div> </div> <div class="success-toast"> <i class="material-icons">check_circle_outline</i> <span class="toast-message">Order executed successfully!</span> </div> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script> // DOM elements const refreshBtn = document.querySelector('.refresh-btn'); const buyTab = document.querySelector('.buy-tab'); const sellTab = document.querySelector('.sell-tab'); const tradeBtn = document.querySelector('.trade-btn'); const tradeTitle = document.getElementById('trade-title'); const btnText = document.querySelector('.btn-text'); const spinner = document.querySelector('.spinner'); const successIndicator = document.querySelector('.success-indicator'); const symbolInput = document.getElementById('symbol'); const priceInput = document.getElementById('price'); const quantityInput = document.getElementById('quantity'); const valueInput = document.getElementById('value'); const successToast = document.querySelector('.success-toast'); const toastMessage = document.querySelector('.toast-message'); const buyButtons = document.querySelectorAll('.buy-btn'); // Event Listeners refreshBtn.addEventListener('click', () => { refreshBtn.querySelector('i').style.transform = 'rotate(180deg)'; setTimeout(() => { refreshBtn.querySelector('i').style.transform = ''; updatePrices(); }, 500); }); buyTab.addEventListener('click', () => { buyTab.classList.add('active'); sellTab.classList.remove('active'); tradeBtn.classList.add('buy'); tradeBtn.classList.remove('sell'); btnText.textContent = 'Buy Now'; }); sellTab.addEventListener('click', () => { sellTab.classList.add('active'); buyTab.classList.remove('active'); tradeBtn.classList.add('sell'); tradeBtn.classList.remove('buy'); btnText.textContent = 'Sell Now'; }); // Quick buy from watchlist buyButtons.forEach(btn => { btn.addEventListener('click', () => { const symbol = btn.getAttribute('data-symbol'); const price = btn.getAttribute('data-price'); symbolInput.value = symbol; priceInput.value = price; quantityInput.value = '10'; calculateValue(); // Smooth scroll to form document.querySelector('.quick-trade').scrollIntoView({ behavior: 'smooth' }); // Highlight form const quickTrade = document.querySelector('.quick-trade'); quickTrade.style.boxShadow = '0 0 0 2px var(--primary)'; setTimeout(() => { quickTrade.style.boxShadow = ''; }, 1500); // Update title tradeTitle.textContent = `Trade ${symbol}`; }); }); // Calculate estimated value const calculateValue = () => { const quantity = parseFloat(quantityInput.value) || 0; const price = parseFloat(priceInput.value) || 0; const total = quantity * price; valueInput.value = total > 0 ? `$${total.toFixed(2)}` : '$0.00'; }; quantityInput.addEventListener('input', calculateValue); priceInput.addEventListener('input', calculateValue); // Trade button execution tradeBtn.addEventListener('click', () => { if (!symbolInput.value || !quantityInput.value || !priceInput.value) { showToast('Please fill in all fields', true); return; } // Show loading state spinner.classList.add('show'); btnText.textContent = buyTab.classList.contains('active') ? 'Buying...' : 'Selling...'; // Simulate API call setTimeout(() => { spinner.classList.remove('show'); successIndicator.classList.add('show'); const action = buyTab.classList.contains('active') ? 'bought' : 'sold'; const symbol = symbolInput.value.toUpperCase(); const quantity = quantityInput.value; btnText.textContent = 'Success'; // Show success toast showToast(`Successfully ${action} ${quantity} shares of ${symbol}!`); // Reset form after delay setTimeout(() => { successIndicator.classList.remove('show'); btnText.textContent = buyTab.classList.contains('active') ? 'Buy Now' : 'Sell Now'; symbolInput.value = ''; priceInput.value = ''; quantityInput.value = ''; valueInput.value = ''; tradeTitle.textContent = 'Quick Trade'; }, 2000); }, 1500); }); // Update random prices to simulate market movement function updatePrices() { const priceElements = document.querySelectorAll('.price-cell'); const changeElements = document.querySelectorAll('.change-cell'); priceElements.forEach((el, index) => { const currentPrice = parseFloat(el.textContent.replace('$', '')); const changePercent = Math.random() * 2 - 1; // Random between -1% and +1% const newPrice = currentPrice * (1 + changePercent / 100); // Update price el.textContent = `$${newPrice.toFixed(2)}`; // Update change percentage changeElements[index].textContent = changePercent >= 0 ? `+${changePercent.toFixed(2)}%` : `${changePercent.toFixed(2)}%`; // Update color if (changePercent >= 0) { changeElements[index].classList.add('positive'); changeElements[index].classList.remove('negative'); } else { changeElements[index].classList.add('negative'); changeElements[index].classList.remove('positive'); } }); } // Show toast message function showToast(message, isError = false) { const toast = document.querySelector('.success-toast'); toast.style.backgroundColor = isError ? 'var(--danger)' : 'var(--success)'; toastMessage.textContent = message; toast.classList.add('show'); setTimeout(() => { toast.classList.remove('show'); }, 3000); } // Create mini charts function createCharts() { const appleChartData = { labels: Array(24).fill(''), datasets: [{ data: [183, 184, 185, 185.5, 186, 186.2, 185.8, 186.5, 187, 186.8, 187.5, 187.2, 187.8, 188, 188.5, 188.3, 188.7, 188.9, 188.5, 189, 189.2, 188.9, 189.1, 188.92], fill: false, borderColor: '#00c853', tension: 0.4, borderWidth: 2, pointRadius: 0 }] }; const msftChartData = { labels: Array(24).fill(''), datasets: [{ data: [410, 411, 412, 413, 412.5, 413.2, 414, 413.8, 414.5, 415, 415.3, 414.8, 415.2, 416, 416.5, 417, 416.8, 417.1, 416.5, 416, 415.5, 415.8, 416, 415.72], fill: false, borderColor: '#00c853', tension: 0.4, borderWidth: 2, pointRadius: 0 }] }; const teslaChartData = { labels: Array(24).fill(''), datasets: [{ data: [241, 242, 242.5, 241.8, 241.5, 241, 240.5, 240, 239.5, 239, 238.5, 239, 239.5, 239, 238.5, 238, 237.5, 237, 236.5, 236, 236.5, 237, 237.5, 237.43], fill: false, borderColor: '#ff1744', tension: 0.4, borderWidth: 2, pointRadius: 0 }] }; const chartOptions = { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { enabled: false } }, scales: { x: { display: false }, y: { display: false } }, elements: { line: { tension: 0.4 } } }; new Chart(document.getElementById('apple-chart'), { type: 'line', data: appleChartData, options: chartOptions }); new Chart(document.getElementById('msft-chart'), { type: 'line', data: msftChartData, options: chartOptions }); new Chart(document.getElementById('tesla-chart'), { type: 'line', data: teslaChartData, options: chartOptions }); } // Initialize document.addEventListener('DOMContentLoaded', () => { createCharts(); // Auto refresh prices every 30 seconds setInterval(updatePrices, 30000); // Simulate real-time price updates by randomly updating one ticker every few seconds setInterval(() => { const randomIndex = Math.floor(Math.random() * document.querySelectorAll('.price-cell').length); const priceCell = document.querySelectorAll('.price-cell')[randomIndex]; const changeCell = document.querySelectorAll('.change-cell')[randomIndex]; const currentPrice = parseFloat(priceCell.textContent.replace('$', '')); const changePercent = (Math.random() * 0.4 - 0.2).toFixed(2); // Random
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Touch-Friendly Tooltips</title> <style> :root { --primary: #5466ff; --secondary: #ff54a1; --dark: #2a2d3e; --light: #f8f9fa; --tooltip-bg: rgba(42, 45, 62, 0.92); --tooltip-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); --success: #4cd964; --warning: #ffcc00; --info: #5ac8fa; --danger: #ff3b30; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', sans-serif; } body { background: linear-gradient(145deg, #f6f9ff, #f0f5ff); height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; overflow-x: hidden; padding: 1rem; } .container { width: 100%; max-width: 600px; padding: 2rem; background-color: #fff; border-radius: 16px; box-shadow: 0 8px 30px rgba(84, 102, 255, 0.08); position: relative; overflow: hidden; } .container::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 6px; background: linear-gradient(90deg, var(--primary), var(--secondary)); } h1 { font-size: 1.6rem; margin-bottom: 1.5rem; color: var(--dark); position: relative; display: inline-block; } h1::after { content: ""; position: absolute; bottom: -8px; left: 0; width: 60px; height: 3px; border-radius: 3px; background: var(--primary); } p { font-size: 0.95rem; line-height: 1.6; color: #555; margin-bottom: 1.5rem; } .tooltip-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 1rem; margin-top: 2rem; } .tooltip-trigger { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; background-color: #fff; border-radius: 14px; padding: 1.2rem 0.8rem; min-height: 110px; transition: all 0.3s ease; border: 1px solid rgba(84, 102, 255, 0.15); cursor: pointer; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03); -webkit-tap-highlight-color: transparent; } .tooltip-trigger:active { transform: scale(0.97); } .tooltip-trigger::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(84, 102, 255, 0.03); border-radius: 14px; transform: scale(0); transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); z-index: 0; } .tooltip-trigger:hover::before { transform: scale(1); } .icon { font-size: 1.8rem; margin-bottom: 0.8rem; position: relative; z-index: 1; transition: transform 0.3s ease; } .tooltip-trigger:hover .icon { transform: translateY(-3px); } .tooltip-trigger.primary .icon { color: var(--primary); } .tooltip-trigger.success .icon { color: var(--success); } .tooltip-trigger.warning .icon { color: var(--warning); } .tooltip-trigger.info .icon { color: var(--info); } .tooltip-trigger.danger .icon { color: var(--danger); } .tooltip-trigger-text { font-size: 0.85rem; font-weight: 500; color: var(--dark); position: relative; z-index: 1; text-align: center; } .tooltip { position: absolute; background: var(--tooltip-bg); color: #fff; padding: 0.7rem 1rem; border-radius: 10px; font-size: 0.85rem; line-height: 1.5; max-width: 200px; width: max-content; z-index: 100; box-shadow: var(--tooltip-shadow); pointer-events: none; opacity: 0; transform: translateY(10px); transition: opacity 0.3s ease, transform 0.3s ease; top: calc(100% + 15px); left: 50%; transform: translateX(-50%) translateY(0); } .tooltip::before { content: ''; position: absolute; width: 12px; height: 12px; background: var(--tooltip-bg); top: -6px; left: 50%; transform: translateX(-50%) rotate(45deg); } .tooltip.visible { opacity: 1; transform: translateX(-50%) translateY(0); } .help-text { text-align: center; color: #888; font-size: 0.85rem; margin-top: 2rem; margin-bottom: 0; animation: pulse 2s infinite; } @keyframes pulse { 0% { opacity: 0.6; } 50% { opacity: 1; } 100% { opacity: 0.6; } } .feedback { position: fixed; bottom: 0; left: 0; width: 100%; background: linear-gradient(90deg, var(--primary), var(--secondary)); color: white; padding: 0.8rem; font-size: 0.9rem; text-align: center; transform: translateY(100%); transition: transform 0.3s ease; z-index: 1000; } .feedback.visible { transform: translateY(0); } @media (max-width: 500px) { .tooltip-container { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 400px) { .container { padding: 1.5rem; } h1 { font-size: 1.4rem; } } /* Ripple Effect */ .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.5); transform: scale(0); animation: ripple 0.8s linear; pointer-events: none; } @keyframes ripple { to { transform: scale(2.5); opacity: 0; } } </style> </head> <body> <div class="container"> <h1>Mobile App Controls</h1> <p>Explore these touch-optimized controls designed for mobile interactions. Tap on any icon to see its enhanced tooltip with a slight delay, designed to provide context without obscuring content.</p> <div class="tooltip-container"> <div class="tooltip-trigger primary" data-tooltip="Save your progress to the cloud and access it from any device."> <div class="icon"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 2a5.53 5.53 0 0 0-3.594 1.342c-.766.66-1.321 1.52-1.464 2.383C1.266 6.095 0 7.555 0 9.318 0 11.366 1.708 13 3.781 13h8.906C14.502 13 16 11.57 16 9.773c0-1.636-1.242-2.969-2.834-3.194C12.923 3.999 10.69 2 8 2zm2.354 5.146a.5.5 0 0 1-.708.708L8.5 6.707V10.5a.5.5 0 0 1-1 0V6.707L6.354 7.854a.5.5 0 1 1-.708-.708l2-2a.5.5 0 0 1 .708 0l2 2z"/> </svg> </div> <span class="tooltip-trigger-text">Save</span> </div> <div class="tooltip-trigger success" data-tooltip="Share your content via messaging apps, email, or social media with a single tap."> <div class="icon"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16"> <path d="M13.5 1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM11 2.5a2.5 2.5 0 1 1 .603 1.628l-6.718 3.12a2.499 2.499 0 0 1 0 1.504l6.718 3.12a2.5 2.5 0 1 1-.488.876l-6.718-3.12a2.5 2.5 0 1 1 0-3.256l6.718-3.12A2.5 2.5 0 0 1 11 2.5zm-8.5 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm11 5.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z"/> </svg> </div> <span class="tooltip-trigger-text">Share</span> </div> <div class="tooltip-trigger warning" data-tooltip="Access notification settings, select which alerts to receive, and customize delivery preferences."> <div class="icon"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2zm.995-14.901a1 1 0 1 0-1.99 0A5.002 5.002 0 0 0 3 6c0 1.098-.5 6-2 7h14c-1.5-1-2-5.902-2-7 0-2.42-1.72-4.44-4.005-4.901z"/> </svg> </div> <span class="tooltip-trigger-text">Notifications</span> </div> <div class="tooltip-trigger info" data-tooltip="Access advanced filtering options to sort and find content exactly how you need it."> <div class="icon"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16"> <path d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2zm1 .5v1.308l4.372 4.858A.5.5 0 0 1 7 8.5v5.306l2-.666V8.5a.5.5 0 0 1 .128-.334L13.5 3.308V2h-11z"/> </svg> </div> <span class="tooltip-trigger-text">Filter</span> </div> <div class="tooltip-trigger danger" data-tooltip="Permanently delete selected items. This action cannot be undone."> <div class="icon"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16"> <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/> <path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/> </svg> </div> <span class="tooltip-trigger-text">Delete</span> </div> <div class="tooltip-trigger primary" data-tooltip="Adjust display settings including contrast, brightness, and text size for better readability."> <div class="icon"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z"/> <path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115l.094-.319z"/> </svg> </div> <span class="tooltip-trigger-text">Settings</span> </div> </div> <p class="help-text">Tap any icon to view its tooltip</p> </div> <div class="feedback"> Tooltip activated successfully </div> <script> document.addEventListener('DOMContentLoaded', function() { const triggers = document.querySelectorAll('.tooltip-trigger'); let activeTooltip = null; let tooltipTimeout = null; let feedbackTimeout = null; // Create tooltip element only once and reuse it const tooltip = document.createElement('div'); tooltip.className = 'tooltip'; document.body.appendChild(tooltip); // Touch/click event for all triggers triggers.forEach(trigger => { trigger.addEventListener('click', handleInteraction); trigger.addEventListener('touchstart', createRippleEffect, false); trigger.addEventListener('mousedown', createRippleEffect, false); }); // Handle touch outside to close tooltip document.addEventListener('click', function(event) { if (!event.target.closest('.tooltip-trigger') && activeTooltip) { hideTooltip(); } }); function handleInteraction(event) { event.preventDefault(); const trigger = this; // Show feedback message const feedback = document.querySelector('.feedback'); feedback.textContent = `"${trigger.querySelector('.tooltip-trigger-text').textContent}" info displayed`; feedback.classList.add('visible'); clearTimeout(feedbackTimeout); feedbackTimeout = setTimeout(() => { feedback.classList.remove('visible'); }, 2000); // Hide any existing tooltip if (activeTooltip) { hideTooltip(); // If clicked the same trigger, just hide and return if (activeTooltip === trigger) { activeTooltip = null; return; } } // Set active trigger activeTooltip = trigger; // Clear any pending tooltip display clearTimeout(tooltipTimeout); // Set the content and position the tooltip tooltip.textContent = trigger.getAttribute('data-tooltip'); // Show tooltip with a slight delay (mobile-friendly) tooltipTimeout = setTimeout(() => { const triggerRect = trigger.getBoundingClientRect(); const tooltipRect = tooltip.getBoundingClientRect(); // Position tooltip centered below the trigger const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const top = triggerRect.bottom + scrollTop + 10; const left = triggerRect.left + triggerRect.width / 2; tooltip.style.top = `${top}px`; tooltip.style.left = `${left}px`; // Make tooltip visible tooltip.classList.add('visible'); }, 100); // Slight delay for mobile } function hideTooltip() { clearTimeout(tooltipTimeout); tooltip.classList.remove('visible'); activeTooltip = null; } function createRippleEffect(event) { const trigger = this; // Remove any existing ripples const existingRipple = trigger.querySelector('.ripple'); if (existingRipple) { existingRipple.remove(); } const ripple = document.createElement('span'); ripple.classList.add('ripple'); trigger.appendChild(ripple); // Get the position of the click/touch let pos; if (event.type === 'touchstart') { pos = event.touches[0]; } else { pos = event; } const rect = trigger.getBoundingClientRect(); const x = pos.clientX - rect.left; const y = pos.clientY - rect.top; // Set ripple size and position ripple.style.width = ripple.style.height = `${Math.max(rect.width, rect.height) * 1.5}px`; ripple.style.left = `${x - (parseFloat(ripple.style.width) / 2)}px`; ripple.style.top = `${y - (parseFloat(ripple.style.height) / 2)}px`; // Remove ripple after animation completes setTimeout(() => { ripple.remove(); }, 800); } }); </script> </body> </html>