Thumbnails are the unsung heroes of digital content, acting as the first impression for viewers. They can make or break the engagement of your videos, articles, or social media posts.
In this article, we will explore 10 compelling thumbnail examples that effectively capture attention and drive clicks. These examples will provide inspiration and insights into creating your own eye-catching thumbnails.
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 thumbnails effortlessly, ensuring your UI is always stunning.
Join the community of satisfied users and 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
Ready to elevate your design game? With Subframe, you can create pixel-perfect UIs and stunning thumbnails in minutes. Our drag-and-drop interface ensures efficiency and precision.
Don't wait! Start for free and begin designing immediately. Join the community of satisfied users today!
<html> <head> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', sans-serif; } body { background-color: #f8f9fc; display: flex; justify-content: center; align-items: center; min-height: 700px; padding: 20px; color: #333; } .container { width: 100%; max-width: 660px; margin: 0 auto; } .header { text-align: center; margin-bottom: 30px; } .header h1 { font-size: 28px; font-weight: 700; margin-bottom: 8px; background: linear-gradient(90deg, #2c3e50, #4a5568); -webkit-background-clip: text; background-clip: text; color: transparent; } .header p { font-size: 16px; color: #718096; max-width: 500px; margin: 0 auto; } .filter-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px; padding: 0 5px; } .category-filter { display: flex; gap: 12px; overflow-x: auto; scrollbar-width: none; padding-bottom: 5px; } .category-filter::-webkit-scrollbar { display: none; } .filter-btn { background: white; border: 1px solid #e2e8f0; padding: 8px 15px; border-radius: 20px; font-size: 14px; cursor: pointer; white-space: nowrap; transition: all 0.3s ease; } .filter-btn.active { background: #2c3e50; color: white; } .filter-btn:hover { background: #f1f5f9; transform: translateY(-2px); } .filter-btn.active:hover { background: #1a202c; } .sort-selector { position: relative; } .sort-selector select { appearance: none; background: white; border: 1px solid #e2e8f0; padding: 8px 30px 8px 15px; border-radius: 20px; font-size: 14px; cursor: pointer; outline: none; } .sort-selector::after { content: '↓'; position: absolute; right: 15px; top: 50%; transform: translateY(-50%); pointer-events: none; font-size: 12px; color: #4a5568; } .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 20px; } .product-card { position: relative; background: white; border-radius: 15px; overflow: hidden; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.02); transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; } .product-card:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.08); z-index: 10; } .product-image { position: relative; height: 150px; overflow: hidden; background: #f8fafc; } .product-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .product-card:hover .product-image img { transform: scale(1.08); } .sale-tag { position: absolute; top: 12px; right: -55px; background: #e53e3e; color: white; padding: 5px 8px; font-size: 12px; font-weight: 600; transform: rotate(45deg); width: 150px; text-align: center; box-shadow: 0 2px 5px rgba(0,0,0,0.1); opacity: 0; transition: opacity 0.3s ease, transform 0.3s ease; } .product-card.on-sale:hover .sale-tag { opacity: 1; } .product-info { padding: 15px; } .product-name { font-size: 14px; font-weight: 600; margin-bottom: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .product-price { display: flex; align-items: center; gap: 8px; } .current-price { font-size: 16px; font-weight: 700; color: #2c3e50; } .original-price { font-size: 13px; color: #a0aec0; text-decoration: line-through; } .quick-view { position: absolute; bottom: -40px; left: 0; right: 0; background: rgba(44, 62, 80, 0.9); color: white; padding: 8px 0; text-align: center; font-size: 12px; font-weight: 600; letter-spacing: 0.5px; transition: bottom 0.3s ease; } .product-card:hover .quick-view { bottom: 0; } .ratings { display: flex; align-items: center; margin-top: 5px; gap: 3px; } .star { color: #F6AD55; font-size: 12px; } .empty-star { color: #E2E8F0; font-size: 12px; } .rating-count { font-size: 11px; color: #718096; margin-left: 4px; } .loader { position: fixed; top: 0; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, transparent, #3498db, transparent); animation: loader 1.5s infinite ease-in-out; z-index: 1000; display: none; } @keyframes loader { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } @media (max-width: 600px) { .product-grid { grid-template-columns: repeat(2, 1fr); } .header h1 { font-size: 24px; } .header p { font-size: 14px; } } @media (max-width: 400px) { .product-grid { grid-template-columns: 1fr; } } </style> </head> <body> <div class="loader"></div> <div class="container"> <div class="header"> <h1>Curated Essentials</h1> <p>Explore our premium collection with minimalistic designs and exceptional quality</p> </div> <div class="filter-bar"> <div class="category-filter"> <button class="filter-btn active">All</button> <button class="filter-btn">Home</button> <button class="filter-btn">Tech</button> <button class="filter-btn">Apparel</button> <button class="filter-btn">Kitchen</button> </div> <div class="sort-selector"> <select id="sort-options"> <option value="featured">Featured</option> <option value="price-asc">Price: Low to High</option> <option value="price-desc">Price: High to Low</option> <option value="newest">Newest</option> </select> </div> </div> <div class="product-grid" id="product-grid"> <!-- Products will be populated by JavaScript --> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const products = [ { id: 1, name: "Minimalist Desk Lamp", price: 79.99, originalPrice: 99.99, image: "https://images.unsplash.com/photo-1507473885765-e6ed057f782c?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80", category: "Home", rating: 4.5, reviewCount: 128, onSale: true }, { id: 2, name: "Wireless Earbuds Pro", price: 129.99, originalPrice: 149.99, image: "https://images.unsplash.com/photo-1572569511254-d8f925fe2cbb?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80", category: "Tech", rating: 4.8, reviewCount: 432, onSale: true }, { id: 3, name: "Organic Cotton Tee", price: 34.99, originalPrice: null, image: "https://images.unsplash.com/photo-1521572163474-6864f9cf17ab?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80", category: "Apparel", rating: 4.2, reviewCount: 89, onSale: false }, { id: 4, name: "Ceramic Pour-Over Set", price: 59.99, originalPrice: 69.99, image: "https://images.unsplash.com/photo-1578943219566-4a434435caca?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80", category: "Kitchen", rating: 4.7, reviewCount: 156, onSale: true }, { id: 5, name: "Smart Home Hub", price: 149.99, originalPrice: null, image: "https://images.unsplash.com/photo-1558089687-f282ffcbc0d4?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80", category: "Tech", rating: 4.4, reviewCount: 243, onSale: false }, { id: 6, name: "Wool Throw Blanket", price: 89.99, originalPrice: 109.99, image: "https://images.unsplash.com/photo-1513519245088-0e12902e5a38?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80", category: "Home", rating: 4.9, reviewCount: 201, onSale: true }, { id: 7, name: "Minimalist Watch", price: 119.99, originalPrice: null, image: "https://images.unsplash.com/photo-1524805444758-089113d48a6d?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80", category: "Apparel", rating: 4.6, reviewCount: 178, onSale: false }, { id: 8, name: "Chef's Knife Set", price: 199.99, originalPrice: 249.99, image: "https://images.unsplash.com/photo-1593618998160-e34014e67546?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80", category: "Kitchen", rating: 4.8, reviewCount: 312, onSale: true } ]; const productGrid = document.getElementById('product-grid'); const filterButtons = document.querySelectorAll('.filter-btn'); const sortSelector = document.getElementById('sort-options'); const loader = document.querySelector('.loader'); let currentCategory = 'All'; let currentSort = 'featured'; // Render products function renderProducts() { showLoader(); // Clear the grid productGrid.innerHTML = ''; // Filter and sort products let filteredProducts = products.filter(product => { return currentCategory === 'All' || product.category === currentCategory; }); // Sort products switch (currentSort) { case 'price-asc': filteredProducts.sort((a, b) => a.price - b.price); break; case 'price-desc': filteredProducts.sort((a, b) => b.price - a.price); break; case 'newest': filteredProducts.sort((a, b) => b.id - a.id); break; default: // 'featured' - keep original order filteredProducts.sort((a, b) => a.id - b.id); } // Render each product filteredProducts.forEach(product => { const productCard = document.createElement('div'); productCard.className = `product-card ${product.onSale ? 'on-sale' : ''}`; // Generate stars based on rating const rating = product.rating; let starsHtml = ''; for (let i = 1; i <= 5; i++) { if (i <= Math.floor(rating)) { starsHtml += '<span class="star">★</span>'; } else if (i === Math.ceil(rating) && !Number.isInteger(rating)) { starsHtml += '<span class="star">★</span>'; } else { starsHtml += '<span class="empty-star">★</span>'; } } productCard.innerHTML = ` <div class="product-image"> <img src="${product.image}" alt="${product.name}"> ${product.onSale ? '<div class="sale-tag">SALE</div>' : ''} </div> <div class="product-info"> <div class="product-name">${product.name}</div> <div class="product-price"> <span class="current-price">$${product.price}</span> ${product.originalPrice ? `<span class="original-price">$${product.originalPrice}</span>` : ''} </div> <div class="ratings"> ${starsHtml} <span class="rating-count">(${product.reviewCount})</span> </div> </div> <div class="quick-view">Quick View</div> `; productGrid.appendChild(productCard); }); setTimeout(hideLoader, 400); // Simulate loading } // Filter button click event filterButtons.forEach(button => { button.addEventListener('click', () => { filterButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); currentCategory = button.textContent; renderProducts(); }); }); // Sort change event sortSelector.addEventListener('change', () => { currentSort = sortSelector.value; renderProducts(); }); // Show/hide loader function showLoader() { loader.style.display = 'block'; } function hideLoader() { loader.style.display = 'none'; } // Initial render renderProducts(); // Add click handler for product cards productGrid.addEventListener('click', (e) => { const card = e.target.closest('.product-card'); if (card) { // Create a subtle "click" animation card.style.transform = 'scale(0.98)'; setTimeout(() => { card.style.transform = ''; }, 150); // In a real app, this would open product detail page // Here we just simulate the action const productName = card.querySelector('.product-name').textContent; console.log(`Viewing details for: ${productName}`); } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Photographer Portfolio</title> <style> :root { --primary-color: #222; --light-color: #fff; --accent-color: #ff4c4c; --transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Helvetica Neue', Arial, sans-serif; } body { background-color: var(--primary-color); color: var(--light-color); width: 100%; height: 100%; overflow: hidden; } .portfolio-container { width: 100%; height: 100vh; max-width: 700px; max-height: it; margin: 0 auto; padding: 20px; overflow: hidden; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px; position: relative; } h1 { font-size: 28px; font-weight: 300; letter-spacing: 1px; opacity: 0; transform: translateY(20px); animation: fadeUp 0.8s forwards 0.3s; } .subtitle { font-size: 14px; font-weight: 300; letter-spacing: 0.5px; opacity: 0; transform: translateY(20px); animation: fadeUp 0.8s forwards 0.5s; margin-bottom: 30px; } .photography-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-auto-rows: 180px; gap: 15px; margin-top: 20px; opacity: 0; transform: translateY(20px); animation: fadeUp 0.8s forwards 0.7s; } .thumbnail { position: relative; overflow: hidden; border-radius: 2px; cursor: pointer; transition: var(--transition); transform: scale(1); height: 100%; } .thumbnail:hover { transform: scale(1.02); z-index: 10; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5); } .thumbnail img { width: 100%; height: 100%; object-fit: cover; transition: var(--transition); } .thumbnail:hover img { transform: scale(1.05); filter: brightness(0.8); } .caption-overlay { position: absolute; bottom: 0; left: 0; width: 100%; padding: 20px; background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent); opacity: 0; transform: translateY(20px); transition: var(--transition); pointer-events: none; } .thumbnail:hover .caption-overlay { opacity: 1; transform: translateY(0); } .caption-title { font-size: 16px; font-weight: 500; margin-bottom: 5px; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); } .caption-details { font-size: 12px; opacity: 0.9; margin-bottom: 5px; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); font-weight: 300; } .caption-text { font-size: 11px; line-height: 1.4; opacity: 0.8; font-weight: 300; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); } .thumbnail-special { grid-column: span 2; grid-row: span 1; } .thumbnail-tall { grid-row: span 2; } .featured { position: absolute; top: 15px; right: 15px; background-color: var(--accent-color); color: white; font-size: 10px; padding: 3px 8px; border-radius: 3px; text-transform: uppercase; letter-spacing: 1px; font-weight: 500; opacity: 0; transform: translateY(-10px); transition: var(--transition); } .thumbnail:hover .featured { opacity: 1; transform: translateY(0); } .focus-mode { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.9); display: flex; justify-content: center; align-items: center; opacity: 0; visibility: hidden; transition: var(--transition); z-index: 100; } .focus-mode.active { opacity: 1; visibility: visible; } .focus-content { max-width: 90%; max-height: 90%; position: relative; } .focus-content img { max-width: 100%; max-height: 80vh; border-radius: 3px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); } .focus-caption { position: absolute; bottom: -60px; left: 0; width: 100%; background: transparent; color: white; padding: 15px 0; text-align: center; } .close-focus { position: absolute; top: -40px; right: 0; color: white; font-size: 24px; background: none; border: none; cursor: pointer; } .category-filter { display: flex; gap: 10px; margin-bottom: 20px; overflow-x: auto; padding-bottom: 10px; opacity: 0; transform: translateY(20px); animation: fadeUp 0.8s forwards 0.6s; } .category-btn { border: none; background: transparent; color: rgba(255, 255, 255, 0.6); padding: 5px 12px; border-radius: 20px; font-size: 12px; cursor: pointer; transition: var(--transition); white-space: nowrap; } .category-btn:hover { color: var(--light-color); background: rgba(255, 255, 255, 0.1); } .category-btn.active { background: var(--accent-color); color: var(--light-color); } .thumbnail.hide { display: none; } /* Animations */ @keyframes fadeUp { to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(255, 76, 76, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(255, 76, 76, 0); } 100% { box-shadow: 0 0 0 0 rgba(255, 76, 76, 0); } } /* Make design responsive */ @media (max-width: 500px) { .photography-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); grid-auto-rows: 140px; gap: 10px; } h1 { font-size: 24px; } .subtitle { font-size: 12px; margin-bottom: 20px; } .caption-title { font-size: 14px; } .caption-details, .caption-text { font-size: 10px; } } /* Custom scrollbar */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.05); } ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.3); } </style> </head> <body> <div class="portfolio-container"> <header> <h1>Chiaroscuro Chronicles</h1> </header> <div class="subtitle">Exploring dramatic light and shadow through visual narratives</div> <div class="category-filter"> <button class="category-btn active" data-category="all">All Works</button> <button class="category-btn" data-category="portraits">Portraits</button> <button class="category-btn" data-category="landscapes">Landscapes</button> <button class="category-btn" data-category="street">Street</button> <button class="category-btn" data-category="abstract">Abstract</button> <button class="category-btn" data-category="architecture">Architecture</button> </div> <div class="photography-grid"> <div class="thumbnail thumbnail-special" data-category="portraits"> <img src="https://images.unsplash.com/photo-1503023345310-bd7c1de61c7d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Man in Shadow"> <div class="caption-overlay"> <div class="caption-title">Solitary Silhouette</div> <div class="caption-details">Portraits, 2023 • Digital</div> <div class="caption-text">Chiaroscuro technique revealing personality through extreme contrast, exploring the duality of human nature.</div> </div> <div class="featured">Featured</div> </div> <div class="thumbnail" data-category="landscapes"> <img src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Mountain Landscape"> <div class="caption-overlay"> <div class="caption-title">Ethereal Heights</div> <div class="caption-details">Landscapes, 2023 • Film</div> <div class="caption-text">Golden hour light breaks through storm clouds, captured on Kodak Portra 400 at Glacier National Park.</div> </div> </div> <div class="thumbnail thumbnail-tall" data-category="street"> <img src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Street Scene"> <div class="caption-overlay"> <div class="caption-title">Urban Crossings</div> <div class="caption-details">Street, 2023 • Digital</div> <div class="caption-text">Rain-slicked streets of Tokyo create mirrors of neon reflections, capturing fleeting moments of urban poetry.</div> </div> </div> <div class="thumbnail" data-category="abstract"> <img src="https://images.unsplash.com/photo-1541701494587-cb58502866ab?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Abstract Pattern"> <div class="caption-overlay"> <div class="caption-title">Fractured Light</div> <div class="caption-details">Abstract, 2022 • Digital</div> <div class="caption-text">Light manipulation through prismatic glass creates geometric abstractions exploring perception and reality.</div> </div> </div> <div class="thumbnail" data-category="architecture"> <img src="https://images.unsplash.com/photo-1511818966892-d7d671e672a2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Architecture"> <div class="caption-overlay"> <div class="caption-title">Concrete Canyons</div> <div class="caption-details">Architecture, 2022 • Digital</div> <div class="caption-text">Brutalist structures juxtaposed against natural light, revealing beauty in the severe angles of urban design.</div> </div> </div> <div class="thumbnail thumbnail-special" data-category="landscapes"> <img src="https://images.unsplash.com/photo-1536257104079-aa99c6460a5a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Seascape"> <div class="caption-overlay"> <div class="caption-title">Tempest Horizon</div> <div class="caption-details">Landscapes, 2022 • Film</div> <div class="caption-text">Long exposure capturing the violent dance between ocean and storm at the hour of nautical twilight.</div> </div> </div> <div class="thumbnail" data-category="portraits"> <img src="https://images.unsplash.com/photo-1544723795-3fb6469f5b39?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Portrait"> <div class="caption-overlay"> <div class="caption-title">Veiled Gaze</div> <div class="caption-details">Portraits, 2021 • Digital</div> <div class="caption-text">Single source lighting evokes Renaissance paintings, exploring intimate vulnerability in modern portraiture.</div> </div> <div class="featured">Featured</div> </div> <div class="thumbnail" data-category="street"> <img src="https://images.unsplash.com/photo-1514539079130-25950c84af65?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80" alt="Street Art"> <div class="caption-overlay"> <div class="caption-title">Transient Canvas</div> <div class="caption-details">Street, 2021 • Digital</div> <div class="caption-text">Ephemeral street art documented in harsh morning light, preserving fleeting urban expressions.</div> </div> </div> </div> </div> <div class="focus-mode"> <div class="focus-content"> <button class="close-focus">×</button> <img src="" alt=""> <div class="focus-caption"> <h3></h3> <p></p> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Variables const thumbnails = document.querySelectorAll('.thumbnail'); const focusMode = document.querySelector('.focus-mode'); const focusImg = document.querySelector('.focus-content img'); const focusCaption = document.querySelector('.focus-caption h3'); const focusDetails = document.querySelector('.focus-caption p'); const closeBtn = document.querySelector('.close-focus'); const categoryBtns = document.querySelectorAll('.category-btn'); // Stagger thumbnail animations thumbnails.forEach((thumbnail, index) => { const delay = 0.7 + (index * 0.1); thumbnail.style.animation = `fadeUp 0.8s forwards ${delay}s`; }); // Open focus mode thumbnails.forEach(thumbnail => { thumbnail.addEventListener('click', function() { const img = this.querySelector('img'); const title = this.querySelector('.caption-title').textContent; const details = this.querySelector('.caption-details').textContent; focusImg.src = img.src; focusImg.alt = img.alt; focusCaption.textContent = title; focusDetails.textContent = details; focusMode.classList.add('active'); document.body.style.overflow = 'hidden'; }); }); // Close focus mode closeBtn.addEventListener('click', function() { focusMode.classList.remove('active'); document.body.style.overflow = ''; }); // Close on clicking outside image focusMode.addEventListener('click', function(e) { if (e.target === focusMode) { focusMode.classList.remove('active'); document.body.style.overflow = ''; } }); // Filter categories categoryBtns.forEach(btn => { btn.addEventListener('click', function() { // Update active button categoryBtns.forEach(b => b.classList.remove('active')); this.classList.add('active'); const category = this.dataset.category; // Filter thumbnails thumbnails.forEach(thumbnail => { if (category === 'all' || thumbnail.dataset.category === category) { thumbnail.classList.remove('hide'); } else { thumbnail.classList.add('hide'); } }); }); }); // Add hover animations for featured tag thumbnails.forEach(thumbnail => { const featured = thumbnail.querySelector('.featured'); if (featured) { setTimeout(() => { featured.style.animation = 'pulse 2s infinite'; }, 2000); } }); // Keyboard navigation document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && focusMode.classList.contains('active')) { focusMode.classList.remove('active'); document.body.style.overflow = ''; } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>News Portal Thumbnails</title> <style> /* Reset and Base Styles */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --color-primary: #2a3990; --color-secondary: #e64c3c; --color-tertiary: #27ae60; --color-neutral-light: #f8f9fa; --color-neutral-dark: #212529; --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.1); --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15); --transition-fast: 0.2s ease-out; --transition-medium: 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); --font-primary: 'Playfair Display', 'Times New Roman', serif; --font-secondary: 'Montserrat', Arial, sans-serif; } body { font-family: var(--font-secondary); background-color: var(--color-neutral-light); color: var(--color-neutral-dark); line-height: 1.6; padding: 20px; height: 100%; max-width: 700px; margin: 0 auto; overflow-x: hidden; } .container { max-width: 100%; margin: 0 auto; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; border-bottom: 3px solid var(--color-primary); padding-bottom: 0.75rem; position: relative; } .header::after { content: ''; position: absolute; bottom: -3px; left: 0; width: 40%; height: 3px; background-color: var(--color-secondary); transform: translateX(0); transition: transform var(--transition-medium); } .header:hover::after { transform: translateX(150%); } .logo { font-family: var(--font-primary); font-size: 1.75rem; color: var(--color-primary); font-weight: 900; letter-spacing: -0.5px; text-transform: uppercase; } .date { font-family: var(--font-secondary); font-size: 0.875rem; color: var(--color-neutral-dark); opacity: 0.8; font-weight: 500; } /* Grid Layout */ .news-grid { display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: auto; gap: 1rem; margin-bottom: 1.5rem; } /* Featured Article */ .featured { grid-column: span 4; grid-row: span 2; position: relative; overflow: hidden; border-radius: 6px; box-shadow: var(--shadow-sm); transition: transform var(--transition-medium), box-shadow var(--transition-medium); } .featured:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); } /* Standard Articles */ .article { grid-column: span 2; position: relative; overflow: hidden; border-radius: 6px; box-shadow: var(--shadow-sm); transition: transform var(--transition-medium), box-shadow var(--transition-medium); background-color: white; } .article:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); } .article-wide { grid-column: span 3; } /* Image Containers */ .img-container { position: relative; overflow: hidden; width: 100%; height: 0; padding-bottom: 56.25%; /* 16:9 Aspect Ratio */ } .featured .img-container { padding-bottom: 75%; /* 4:3 Aspect Ratio for featured */ } .article img, .featured img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s cubic-bezier(0.33, 1, 0.68, 1); } .article:hover img, .featured:hover img { transform: scale(1.05); } /* Content Overlay */ .content-overlay { position: absolute; bottom: 0; left: 0; right: 0; padding: 1.25rem; background: linear-gradient(to top, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0)); color: white; z-index: 1; } .featured .content-overlay { padding: 2rem; } /* Article Content */ .article-content { padding: 1rem; } /* Category Tags */ .category { display: inline-block; padding: 0.35rem 0.75rem; border-radius: 3px; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 0.5rem; } .politics { background-color: var(--color-primary); color: white; } .business { background-color: var(--color-tertiary); color: white; } .technology { background-color: #3498db; color: white; } .culture { background-color: var(--color-secondary); color: white; } .health { background-color: #9b59b6; color: white; } /* Title Styles */ .title { font-family: var(--font-primary); margin-bottom: 0.5rem; line-height: 1.3; font-weight: 700; } .featured .title { font-size: 1.75rem; margin-bottom: 0.75rem; } .article .title { font-size: 1.1rem; color: var(--color-neutral-dark); } /* Excerpt */ .excerpt { font-size: 0.9rem; margin-bottom: 0.75rem; opacity: 0.9; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .featured .excerpt { font-size: 1rem; -webkit-line-clamp: 3; } /* Meta Information */ .meta { display: flex; align-items: center; font-size: 0.75rem; color: var(--color-neutral-dark); opacity: 0.7; } .featured .meta { color: white; opacity: 0.9; } .author { font-weight: 600; margin-right: 0.75rem; } .time { position: relative; padding-left: 0.75rem; } .time::before { content: '•'; position: absolute; left: 0.25rem; } /* Breaking News Ticker */ .breaking-news { padding: 0.5rem 0; margin-bottom: 1rem; overflow: hidden; background-color: #fff; border-radius: 4px; box-shadow: var(--shadow-sm); } .ticker-label { display: inline-block; padding: 0.25rem 0.5rem; background-color: var(--color-secondary); color: white; font-weight: 700; font-size: 0.8rem; margin-right: 1rem; animation: pulse 2s infinite; } .ticker-content { display: inline-block; white-space: nowrap; animation: ticker 15s linear infinite; } .ticker-item { display: inline-block; padding: 0 1rem; font-weight: 500; } /* Animations */ @keyframes ticker { 0% { transform: translateX(0); } 100% { transform: translateX(-100%); } } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.6; } 100% { opacity: 1; } } /* Bottom Row Articles */ .bottom-articles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; } .bottom-article { display: flex; background-color: white; border-radius: 6px; overflow: hidden; box-shadow: var(--shadow-sm); transition: transform var(--transition-medium), box-shadow var(--transition-medium); } .bottom-article:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); } .bottom-article-img { width: 30%; min-height: 100%; overflow: hidden; position: relative; } .bottom-article-img img { width: 100%; height: 100%; object-fit: cover; position: absolute; top: 0; left: 0; transition: transform var(--transition-medium); } .bottom-article:hover .bottom-article-img img { transform: scale(1.08); } .bottom-article-content { padding: 0.75rem; flex: 1; } .bottom-article .title { font-size: 0.9rem; margin-bottom: 0.3rem; } .bottom-article .meta { font-size: 0.7rem; } /* Responsive Adjustments */ @media (max-width: 700px) { .news-grid { grid-template-columns: repeat(2, 1fr); } .featured { grid-column: span 2; } .article { grid-column: span 2; } .article-wide { grid-column: span 2; } .bottom-articles { grid-template-columns: 1fr; } .featured .title { font-size: 1.35rem; } .header { flex-direction: column; align-items: flex-start; } .logo { margin-bottom: 0.5rem; } } @media (max-width: 500px) { .news-grid { grid-template-columns: 1fr; } .featured, .article, .article-wide { grid-column: span 1; } .featured .content-overlay { padding: 1.25rem; } } </style> </head> <body> <div class="container"> <header class="header"> <div class="logo">The Parallax</div> <div class="date">Monday, June 10, 2024</div> </header> <div class="breaking-news"> <span class="ticker-label">BREAKING</span> <div class="ticker-content"> <span class="ticker-item">Global markets surge as tech sector reports record profits</span> <span class="ticker-item">Climate summit concludes with ambitious new carbon reduction targets</span> <span class="ticker-item">Scientists announce breakthrough in quantum computing research</span> <span class="ticker-item">Space agency confirms plans for first Mars colony by 2035</span> </div> </div> <div class="news-grid"> <!-- Featured Article --> <article class="featured"> <div class="img-container"> <img src="https://images.unsplash.com/photo-1601382270349-49c15bdae829?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80" alt="Climate summit"> </div> <div class="content-overlay"> <span class="category politics">Politics</span> <h2 class="title">Historic Climate Accord: 195 Nations Commit to Net-Zero Emissions by 2050</h2> <p class="excerpt">After marathon negotiations, world leaders have reached a groundbreaking agreement that promises to transform the global economy and avert climate catastrophe with binding targets.</p> <div class="meta"> <span class="author">By Eleanor Chambers</span> <span class="time">3 hours ago</span> </div> </div> </article> <!-- Standard Articles --> <article class="article"> <div class="img-container"> <img src="https://images.unsplash.com/photo-1526304640581-d334cdbbf45e?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Tech innovation"> </div> <div class="article-content"> <span class="category technology">Technology</span> <h3 class="title">Quantum Computing Breakthrough Could Revolutionize Cybersecurity</h3> <p class="excerpt">Researchers achieve stable quantum entanglement at room temperature, paving the way for mainstream applications.</p> <div class="meta"> <span class="author">By Marcus Feng</span> <span class="time">5 hours ago</span> </div> </div> </article> <article class="article"> <div class="img-container"> <img src="https://images.unsplash.com/photo-1444653614773-995cb1ef9efa?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Financial markets"> </div> <div class="article-content"> <span class="category business">Business</span> <h3 class="title">Global Markets React as Central Banks Announce Coordinated Interest Rate Cuts</h3> <p class="excerpt">Asian and European markets rally on news of unprecedented economic intervention.</p> <div class="meta"> <span class="author">By Sarah Wellington</span> <span class="time">Yesterday</span> </div> </div> </article> <article class="article article-wide"> <div class="img-container"> <img src="https://images.unsplash.com/photo-1551076805-e1869033e561?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Medical research"> </div> <div class="article-content"> <span class="category health">Health</span> <h3 class="title">Breakthrough Cancer Treatment Shows 90% Success Rate in Clinical Trials</h3> <p class="excerpt">Personalized immunotherapy approach eliminates tumors in patients with previously untreatable forms of cancer.</p> <div class="meta"> <span class="author">By Dr. James Rodriguez</span> <span class="time">2 days ago</span> </div> </div> </article> <article class="article article-wide"> <div class="img-container"> <img src="https://images.unsplash.com/photo-1525909002-1b05e0c869d8?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Art exhibit"> </div> <div class="article-content"> <span class="category culture">Culture</span> <h3 class="title">Digital Renaissance: AI-Generated Art Sells for Record $8.3 Million at Auction</h3> <p class="excerpt">Controversial piece sparks debate about creativity, authorship, and the future of artistic expression.</p> <div class="meta"> <span class="author">By Claire Zhang</span> <span class="time">3 days ago</span> </div> </div> </article> </div> <div class="bottom-articles"> <article class="bottom-article"> <div class="bottom-article-img"> <img src="https://images.unsplash.com/photo-1504711434969-e33886168f5c?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Space exploration"> </div> <div class="bottom-article-content"> <span class="category technology">Science</span> <h3 class="title">Private Space Company Announces 2026 Lunar Mission</h3> <div class="meta"> <span class="author">By Jonathan Pierce</span> <span class="time">4 hours ago</span> </div> </div> </article> <article class="bottom-article"> <div class="bottom-article-img"> <img src="https://images.unsplash.com/photo-1548438294-1ad5d5f4f063?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Urban development"> </div> <div class="bottom-article-content"> <span class="category politics">Urban</span> <h3 class="title">Floating City Project Begins Construction in South Pacific</h3> <div class="meta"> <span class="author">By Nina Patel</span> <span class="time">Yesterday</span> </div> </div> </article> <article class="bottom-article"> <div class="bottom-article-img"> <img src="https://images.unsplash.com/photo-1593642532973-d31b6557fa68?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=80" alt="Technology device"> </div> <div class="bottom-article-content"> <span class="category technology">Gadgets</span> <h3 class="title">New Neural Interface Allows Typing with Thought Alone</h3> <div class="meta"> <span class="author">By Liam Thompson</span> <span class="time">2 days ago</span> </div> </div> </article> </div> </div> <script> // Function to duplicate ticker content for continuous scrolling function setupTicker() { const tickerContent = document.querySelector('.ticker-content'); const originalContent = tickerContent.innerHTML; tickerContent.innerHTML = originalContent + originalContent; } // Add subtle hover interactions to articles function setupArticleInteractions() { const articles = document.querySelectorAll('.article, .featured, .bottom-article'); articles.forEach(article => { article.addEventListener('mouseenter', function() { // Add slight shadow pulse on hover this.style.boxShadow = '0 8px 24px rgba(0, 0, 0, 0.2)'; }); article.addEventListener('mouseleave', function() { // Reset to original shadow this.style.boxShadow = ''; }); // Make articles feel interactive article.addEventListener('click', function(e) { // Prevent default action to avoid page navigation e.preventDefault(); // Create ripple effect on click const ripple = document.createElement('div'); ripple.classList.add('ripple'); ripple.style.position = 'absolute'; ripple.style.borderRadius = '50%'; ripple.style.backgroundColor = 'rgba(255, 255, 255, 0.4)'; ripple.style.width = '100px'; ripple.style.height = '100px'; ripple.style.transform = 'scale(0)'; ripple.style.pointerEvents = 'none'; ripple.style.top = (e.clientY - this.getBoundingClientRect().top - 50) + 'px'; ripple.style.left = (e.clientX - this.getBoundingClientRect().left - 50) + 'px'; ripple.style.transition = 'transform 0.5s ease-out, opacity 0.5s ease-out'; this.style.overflow = 'hidden'; this.style.position = 'relative'; this.appendChild(ripple); // Animate ripple setTimeout(() => { ripple.style.transform = 'scale(4)'; ripple.style.opacity = '0'; // Remove ripple element after animation setTimeout(() => { ripple.remove(); }, 500); }, 10); }); }); } // Initialize when DOM is loaded document.addEventListener('DOMContentLoaded', function() { setupTicker(); setupArticleInteractions(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Video Content Thumbnails</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } body { background-color: #121212; color: #ffffff; padding: 2rem; max-width: 700px; margin: 0 auto; display: flex; flex-direction: column; height: 100vh; } h1 { font-size: 2.2rem; margin-bottom: 1rem; background: linear-gradient(90deg, #6366f1, #8b5cf6); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 800; } p.description { color: #e5e5e5; margin-bottom: 2rem; line-height: 1.5; max-width: 600px; } .video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.5rem; width: 100%; } .video-thumbnail { position: relative; border-radius: 12px; overflow: hidden; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.35s ease; cursor: pointer; background: #191919; } .video-thumbnail:hover { transform: translateY(-8px) scale(1.02); box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4); } .thumbnail-img { width: 100%; aspect-ratio: 16/9; object-fit: cover; transition: filter 0.3s ease; } .video-thumbnail:hover .thumbnail-img { filter: brightness(0.7); } .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 60%); display: flex; justify-content: center; align-items: center; opacity: 0.8; transition: opacity 0.3s ease; } .video-thumbnail:hover .overlay { opacity: 1; } .play-button { width: 60px; height: 60px; background: linear-gradient(135deg, #6366f1, #8b5cf6); border-radius: 50%; display: flex; justify-content: center; align-items: center; transform: scale(0.9); transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease; box-shadow: 0 5px 15px rgba(99, 102, 241, 0.4); } .video-thumbnail:hover .play-button { transform: scale(1); box-shadow: 0 8px 25px rgba(99, 102, 241, 0.6); } .play-button svg { width: 24px; height: 24px; fill: white; margin-left: 4px; } .pulse { position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: rgba(99, 102, 241, 0.3); animation: pulse 2s infinite; opacity: 0; } .video-thumbnail:hover .pulse { opacity: 1; } @keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 70% { transform: scale(1.1); opacity: 0; } 100% { transform: scale(0.95); opacity: 0; } } .video-info { padding: 1rem; } .video-title { font-size: 1rem; font-weight: 600; margin-bottom: 0.5rem; transition: color 0.3s ease; } .video-thumbnail:hover .video-title { color: #8b5cf6; } .video-meta { display: flex; justify-content: space-between; color: #9ca3af; font-size: 0.85rem; } .duration-badge { position: absolute; bottom: 6.5rem; right: 10px; background: rgba(0, 0, 0, 0.75); color: white; padding: 0.2rem 0.4rem; border-radius: 4px; font-size: 0.75rem; backdrop-filter: blur(4px); transition: transform 0.3s ease, background 0.3s ease; } .video-thumbnail:hover .duration-badge { background: rgba(99, 102, 241, 0.75); transform: translateY(-2px); } .video-thumbnail:focus { outline: none; box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.5); } .category-tag { position: absolute; top: 10px; left: 10px; background: rgba(0, 0, 0, 0.75); color: white; padding: 0.3rem 0.6rem; border-radius: 4px; font-size: 0.75rem; backdrop-filter: blur(4px); transition: background 0.3s ease; } .video-thumbnail:hover .category-tag { background: rgba(139, 92, 246, 0.75); } /* Modal styles */ .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); display: flex; justify-content: center; align-items: center; z-index: 100; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; backdrop-filter: blur(8px); } .modal.active { opacity: 1; pointer-events: all; } .modal-content { width: 90%; max-width: 800px; position: relative; transform: scale(0.9); transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); } .modal.active .modal-content { transform: scale(1); } .modal-close { position: absolute; top: -40px; right: 0; background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer; transition: transform 0.3s ease, color 0.3s ease; } .modal-close:hover { color: #8b5cf6; transform: rotate(90deg); } .video-player { width: 100%; aspect-ratio: 16/9; background: #000; border-radius: 12px; overflow: hidden; } @media (max-width: 600px) { body { padding: 1rem; } h1 { font-size: 1.8rem; } .video-grid { grid-template-columns: 1fr; } } /* Custom scrollbar */ ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: #1e1e1e; } ::-webkit-scrollbar-thumb { background: #6366f1; border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: #8b5cf6; } </style> </head> <body> <h1>Trending Video Picks</h1> <p class="description">Discover the latest cinematic masterpieces curated for your viewing pleasure. Hover over thumbnails to preview and click to watch.</p> <div class="video-grid"> <div class="video-thumbnail" tabindex="0" data-video="DZ3jMuEEkYE"> <img src="https://source.unsplash.com/random/600x340?filmmaking" alt="Video about cinematic techniques" class="thumbnail-img"> <div class="category-tag">Filmmaking</div> <span class="duration-badge">12:47</span> <div class="overlay"> <div class="play-button"> <div class="pulse"></div> <svg viewBox="0 0 24 24"> <path d="M8 5v14l11-7z"></path> </svg> </div> </div> <div class="video-info"> <h3 class="video-title">Mastering Cinematic Lighting: Pro Techniques</h3> <div class="video-meta"> <span>2.4M views</span> <span>2 days ago</span> </div> </div> </div> <div class="video-thumbnail" tabindex="0" data-video="dQw4w9WgXcQ"> <img src="https://source.unsplash.com/random/600x340?animation" alt="Video about animation" class="thumbnail-img"> <div class="category-tag">Animation</div> <span class="duration-badge">8:32</span> <div class="overlay"> <div class="play-button"> <div class="pulse"></div> <svg viewBox="0 0 24 24"> <path d="M8 5v14l11-7z"></path> </svg> </div> </div> <div class="video-info"> <h3 class="video-title">Animation Principles: From Concept to Screen</h3> <div class="video-meta"> <span>1.7M views</span> <span>1 week ago</span> </div> </div> </div> <div class="video-thumbnail" tabindex="0" data-video="6ZfuNTqbHE8"> <img src="https://source.unsplash.com/random/600x340?editing" alt="Video about editing" class="thumbnail-img"> <div class="category-tag">Editing</div> <span class="duration-badge">17:05</span> <div class="overlay"> <div class="play-button"> <div class="pulse"></div> <svg viewBox="0 0 24 24"> <path d="M8 5v14l11-7z"></path> </svg> </div> </div> <div class="video-info"> <h3 class="video-title">Advanced Video Editing: Color Grading Secrets</h3> <div class="video-meta"> <span>890K views</span> <span>3 days ago</span> </div> </div> </div> <div class="video-thumbnail" tabindex="0" data-video="jNQXAC9IVRw"> <img src="https://source.unsplash.com/random/600x340?documentary" alt="Video about documentary" class="thumbnail-img"> <div class="category-tag">Documentary</div> <span class="duration-badge">22:16</span> <div class="overlay"> <div class="play-button"> <div class="pulse"></div> <svg viewBox="0 0 24 24"> <path d="M8 5v14l11-7z"></path> </svg> </div> </div> <div class="video-info"> <h3 class="video-title">Wildlife Cinematography: Capturing Nature</h3> <div class="video-meta"> <span>3.1M views</span> <span>5 days ago</span> </div> </div> </div> </div> <div class="modal"> <div class="modal-content"> <button class="modal-close">×</button> <div class="video-player"> <iframe width="100%" height="100%" frameborder="0" allowfullscreen></iframe> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const thumbnails = document.querySelectorAll('.video-thumbnail'); const modal = document.querySelector('.modal'); const modalClose = document.querySelector('.modal-close'); const iframe = document.querySelector('.video-player iframe'); thumbnails.forEach(thumbnail => { thumbnail.addEventListener('click', () => { const videoId = thumbnail.getAttribute('data-video'); iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1`; modal.classList.add('active'); document.body.style.overflow = 'hidden'; }); // Keyboard accessibility thumbnail.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); thumbnail.click(); } }); }); modalClose.addEventListener('click', () => { modal.classList.remove('active'); iframe.src = ''; document.body.style.overflow = ''; }); // Close modal when clicking outside content modal.addEventListener('click', (e) => { if (e.target === modal) { modalClose.click(); } }); // Close modal with escape key document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && modal.classList.contains('active')) { modalClose.click(); } }); // Add hover animations with JavaScript for more complex effects thumbnails.forEach(thumbnail => { thumbnail.addEventListener('mouseenter', () => { const playButton = thumbnail.querySelector('.play-button'); playButton.style.transform = 'scale(1.05)'; // Create subtle movement for the thumbnail image const thumbnailImg = thumbnail.querySelector('.thumbnail-img'); thumbnailImg.style.transition = 'transform 8s ease'; thumbnailImg.style.transform = 'scale(1.05)'; }); thumbnail.addEventListener('mouseleave', () => { const playButton = thumbnail.querySelector('.play-button'); playButton.style.transform = ''; const thumbnailImg = thumbnail.querySelector('.thumbnail-img'); thumbnailImg.style.transition = 'transform 0.5s ease'; thumbnailImg.style.transform = ''; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mobile App Gallery Thumbnails</title> <style> :root { --primary-color: #4A6AE8; --secondary-color: #F87060; --tertiary-color: #42D9C8; --dark-color: #2A3554; --light-color: #F5F7FF; --transition-speed: 0.3s; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; -webkit-tap-highlight-color: transparent; } body { background: var(--light-color); color: var(--dark-color); height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; overflow-x: hidden; padding: 20px; } .container { width: 100%; max-width: 680px; margin: 0 auto; } .gallery-header { text-align: center; margin-bottom: 25px; } .gallery-header h1 { font-size: 2rem; font-weight: 700; margin-bottom: 10px; color: var(--dark-color); position: relative; display: inline-block; } .gallery-header h1::after { content: ''; position: absolute; bottom: -8px; left: 10%; width: 80%; height: 4px; background: linear-gradient(90deg, var(--primary-color), var(--tertiary-color)); border-radius: 4px; animation: headerGlow 2s infinite alternate; } .gallery-header p { font-size: 1rem; color: #555; max-width: 500px; margin: 0 auto; padding-top: 10px; } .filter-buttons { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-bottom: 20px; } .filter-button { padding: 10px 18px; border: none; background: white; border-radius: 20px; color: var(--dark-color); font-weight: 500; font-size: 0.9rem; cursor: pointer; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08); transition: all var(--transition-speed) ease; position: relative; overflow: hidden; } .filter-button::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: rgba(255, 255, 255, 0.3); border-radius: 50%; transform: translate(-50%, -50%); transition: width 0.5s, height 0.5s; } .filter-button:active::before { width: 300px; height: 300px; opacity: 0; } .filter-button.active { background: var(--primary-color); color: white; transform: translateY(-2px); } .gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 16px; margin-bottom: 20px; } .gallery-item { position: relative; border-radius: 16px; overflow: hidden; background: white; box-shadow: 0 6px 15px rgba(0, 0, 0, 0.08); cursor: pointer; transition: transform var(--transition-speed) ease, box-shadow var(--transition-speed) ease; aspect-ratio: 1/1; transform: scale(1); isolation: isolate; } .gallery-item:active { transform: scale(0.95); } .gallery-item::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at center, rgba(255,255,255,0) 0%, rgba(0,0,0,0.2) 100%); opacity: 0; z-index: 1; transition: opacity var(--transition-speed) ease; } .gallery-item:active::before { opacity: 1; } .gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; transform-origin: center; } .gallery-item:hover img { transform: scale(1.08); } .gallery-item .item-overlay { position: absolute; bottom: 0; left: 0; width: 100%; padding: 12px; background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent); color: white; transform: translateY(100%); transition: transform var(--transition-speed) ease; z-index: 2; } .gallery-item:hover .item-overlay { transform: translateY(0); } .gallery-item .item-title { font-size: 0.85rem; font-weight: 600; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .gallery-item .item-category { font-size: 0.7rem; opacity: 0.9; } .gallery-item .item-badge { position: absolute; top: 10px; right: 10px; background: var(--secondary-color); color: white; padding: 4px 8px; border-radius: 12px; font-size: 0.7rem; font-weight: 500; z-index: 2; transform: scale(0); transform-origin: center; animation: badgePop 0.3s forwards 0.2s; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } @keyframes badgePop { 0% { transform: scale(0); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } @keyframes headerGlow { 0% { box-shadow: 0 0 5px rgba(74, 106, 232, 0.3); } 100% { box-shadow: 0 0 15px rgba(74, 106, 232, 0.6); } } .load-more { display: block; margin: 0 auto; padding: 12px 24px; background: var(--primary-color); color: white; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all var(--transition-speed) ease; box-shadow: 0 4px 12px rgba(74, 106, 232, 0.2); position: relative; overflow: hidden; } .load-more:hover { background: #3D5BD9; transform: translateY(-2px); box-shadow: 0 6px 15px rgba(74, 106, 232, 0.3); } .load-more:active { transform: translateY(0); } .load-more .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.5); transform: scale(0); animation: ripple 0.6s linear; } @keyframes ripple { to { transform: scale(2.5); opacity: 0; } } @media (max-width: 480px) { .gallery-grid { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 12px; } .gallery-header h1 { font-size: 1.6rem; } .gallery-header p { font-size: 0.9rem; } .filter-button { padding: 8px 14px; font-size: 0.8rem; } } /* Custom scroll styles */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.05); border-radius: 10px; } ::-webkit-scrollbar-thumb { background: var(--primary-color); border-radius: 10px; } .skeleton-loader { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); background-size: 200% 100%; animation: loading 1.5s infinite; border-radius: 16px; z-index: 3; } @keyframes loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } .empty-state { text-align: center; padding: 40px 20px; display: none; } .empty-state svg { width: 120px; height: 120px; margin-bottom: 20px; opacity: 0.5; } .empty-state h3 { color: var(--dark-color); margin-bottom: 10px; } .empty-state p { color: #777; max-width: 300px; margin: 0 auto; } </style> </head> <body> <div class="container"> <div class="gallery-header"> <h1>App Showcase</h1> <p>Discover our latest mobile designs and prototypes, optimized for touch interaction and visual appeal.</p> </div> <div class="filter-buttons"> <button class="filter-button active" data-category="all">All</button> <button class="filter-button" data-category="ui">UI Designs</button> <button class="filter-button" data-category="photo">Photography</button> <button class="filter-button" data-category="icon">Icons</button> <button class="filter-button" data-category="motion">Motion</button> </div> <div class="gallery-grid" id="gallery"> <!-- Gallery items will be populated here --> </div> <div class="empty-state" id="emptyState"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M21 19H3C1.89543 19 1 18.1046 1 17V7C1 5.89543 1.89543 5 3 5H21C22.1046 5 23 5.89543 23 7V17C23 18.1046 22.1046 19 21 19Z" stroke="#AAA" stroke-width="2"/> <circle cx="12" cy="12" r="3" stroke="#AAA" stroke-width="2"/> <path d="M10 12H14" stroke="#AAA" stroke-width="2"/> <path d="M12 10V14" stroke="#AAA" stroke-width="2"/> </svg> <h3>No matching items</h3> <p>Try selecting a different category or check back later for new additions.</p> </div> <button id="loadMore" class="load-more">Load More</button> </div> <script> document.addEventListener('DOMContentLoaded', () => { // Gallery data const galleryData = [ { id: 1, title: "Fitness Dashboard", category: "ui", image: "https://images.unsplash.com/photo-1609921141835-710b7fa6e438?q=80&w=300&h=300&auto=format&fit=crop", isNew: true }, { id: 2, title: "E-commerce App", category: "ui", image: "https://images.unsplash.com/photo-1571867424488-4565932edb41?q=80&w=300&h=300&auto=format&fit=crop", isNew: false }, { id: 3, title: "Mountain Landscape", category: "photo", image: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=300&h=300&auto=format&fit=crop", isNew: false }, { id: 4, title: "Travel Bookings", category: "ui", image: "https://images.unsplash.com/photo-1586105449897-20b5d6b25a6f?q=80&w=300&h=300&auto=format&fit=crop", isNew: true }, { id: 5, title: "Minimal Icons", category: "icon", image: "https://images.unsplash.com/photo-1581291518633-83b4ebd1d83e?q=80&w=300&h=300&auto=format&fit=crop", isNew: false }, { id: 6, title: "Button Animation", category: "motion", image: "https://images.unsplash.com/photo-1550684848-fac1c5b4e853?q=80&w=300&h=300&auto=format&fit=crop", isNew: true }, { id: 7, title: "City Nightscape", category: "photo", image: "https://images.unsplash.com/photo-1519501025264-65ba15a82390?q=80&w=300&h=300&auto=format&fit=crop", isNew: false }, { id: 8, title: "Emoji Set", category: "icon", image: "https://images.unsplash.com/photo-1560807707-8cc77767d783?q=80&w=300&h=300&auto=format&fit=crop", isNew: true }, { id: 9, title: "Login Flow", category: "motion", image: "https://images.unsplash.com/photo-1618005198919-d3d4b5a92ead?q=80&w=300&h=300&auto=format&fit=crop", isNew: false } ]; // Additional items that will be loaded on "Load More" const additionalItems = [ { id: 10, title: "Menu Transitions", category: "motion", image: "https://images.unsplash.com/photo-1550645612-83f5d594b671?q=80&w=300&h=300&auto=format&fit=crop", isNew: true }, { id: 11, title: "Weather Icons", category: "icon", image: "https://images.unsplash.com/photo-1590845947676-fa2576f401b3?q=80&w=300&h=300&auto=format&fit=crop", isNew: false }, { id: 12, title: "Autumn Leaves", category: "photo", image: "https://images.unsplash.com/photo-1507783548227-544c3b8fc065?q=80&w=300&h=300&auto=format&fit=crop", isNew: false } ]; let currentCategory = 'all'; let currentItems = [...galleryData]; let moreItemsLoaded = false; const gallery = document.getElementById('gallery'); const emptyState = document.getElementById('emptyState'); const loadMoreBtn = document.getElementById('loadMore'); const filterButtons = document.querySelectorAll('.filter-button'); // Render gallery items function renderGallery(items) { gallery.innerHTML = ''; if (items.length === 0) { emptyState.style.display = 'block'; loadMoreBtn.style.display = 'none'; } else { emptyState.style.display = 'none'; loadMoreBtn.style.display = moreItemsLoaded ? 'none' : 'block'; } items.forEach(item => { const galleryItem = document.createElement('div'); galleryItem.className = 'gallery-item'; galleryItem.setAttribute('data-category', item.category); galleryItem.innerHTML = ` <div class="skeleton-loader"></div> <img src="${item.image}" alt="${item.title}"> <div class="item-overlay"> <div class="item-title">${item.title}</div> <div class="item-category">${getCategoryLabel(item.category)}</div> </div> ${item.isNew ? '<span class="item-badge">NEW</span>' : ''} `; gallery.appendChild(galleryItem); // Add click effect galleryItem.addEventListener('click', function(e) { createRippleEffect(e, this); }); // Remove skeleton loader when image is loaded const img = galleryItem.querySelector('img'); const skeletonLoader = galleryItem.querySelector('.skeleton-loader'); img.onload = function() { setTimeout(() => { skeletonLoader.style.opacity = '0'; setTimeout(() => { skeletonLoader.remove(); }, 300); }, 500); // Add a slight delay to make the loading more visible }; }); } // Helper function to get readable category labels function getCategoryLabel(category) { const labels = { 'ui': 'UI Design', 'photo': 'Photography', 'icon': 'Icon Design', 'motion': 'Motion Design' }; return labels[category] || category; } // Filter gallery function filterGallery(category) { currentCategory = category; let filteredItems; if (category === 'all') { filteredItems = [...currentItems]; } else { filteredItems = currentItems.filter(item => item.category === category); } renderGallery(filteredItems); } // Initialize gallery with all items renderGallery(currentItems); // Filter button click handlers filterButtons.forEach(button => { button.addEventListener('click', function() { filterButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); filterGallery(this.getAttribute('data-category')); // Add ripple effect to filter button createRippleEffect(event, this); }); }); // Load more button handler loadMoreBtn.addEventListener('click', function(e) { createRippleEffect(e, this); // Add new items with a staggered animation additionalItems.forEach((item, index) => { setTimeout(() => { currentItems.push(item); if (index === additionalItems.length - 1) { filterGallery(currentCategory); moreItemsLoaded = true; loadMoreBtn.style.display = 'none'; } }, index * 300); }); }); // Ripple effect function function createRippleEffect(event, element) { const ripple = document.createElement('span'); ripple.classList.add('ripple'); element.appendChild(ripple); const rect = element.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); ripple.style.width = ripple.style.height = `${size}px`; ripple.style.left = `${event.clientX - rect.left - size / 2}px`; ripple.style.top = `${event.clientY - rect.top - size / 2}px`; setTimeout(() => { ripple.remove(); }, 600); } // Add touch feedback to gallery items document.querySelectorAll('.gallery-item').forEach(item => { item.addEventListener('click', function(e) { createRippleEffect(e, this); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Wanderlust Destinations</title> <style> @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;500;600;700&family=Poppins:wght@300;400;500;600&display=swap'); :root { --primary-color: #f8b195; --secondary-color: #f67280; --accent-color: #c06c84; --dark-color: #355c7d; --light-color: #f9f7f4; --overlay-light: rgba(255, 255, 255, 0.15); --overlay-dark: rgba(53, 92, 125, 0.4); --transition: all 0.4s cubic-bezier(0.645, 0.045, 0.355, 1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Poppins', sans-serif; background-color: var(--light-color); color: #333; min-height: 100vh; overflow-x: hidden; max-width: 700px; margin: 0 auto; } .container { width: 100%; height: 100%; padding: 1.5rem; max-width: 700px; } header { padding: 0 0 1rem; position: relative; } .logo { font-family: 'Cormorant Garamond', serif; font-weight: 600; font-size: 1.8rem; color: var(--dark-color); display: flex; align-items: center; margin-bottom: 1rem; } .logo svg { margin-right: 10px; width: 32px; height: 32px; } h1 { font-family: 'Cormorant Garamond', serif; font-size: 2.2rem; font-weight: 700; color: var(--dark-color); margin-bottom: 0.5rem; } .subtitle { font-size: 1rem; font-weight: 400; color: var(--accent-color); margin-bottom: 1.5rem; } .search-box { position: relative; margin-bottom: 2rem; } .search-box input { width: 100%; padding: 1rem 3rem 1rem 1.5rem; border-radius: 50px; border: none; background: white; box-shadow: 0 4px 20px rgba(0,0,0,0.05); font-family: 'Poppins', sans-serif; font-size: 0.95rem; transition: var(--transition); } .search-box input:focus { outline: none; box-shadow: 0 4px 20px rgba(0,0,0,0.1); } .search-box svg { position: absolute; right: 1.2rem; top: 50%; transform: translateY(-50%); color: var(--accent-color); } .filters { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 2rem; } .filter-btn { padding: 0.5rem 1.2rem; background: white; border: none; border-radius: 50px; color: var(--dark-color); font-family: 'Poppins', sans-serif; font-size: 0.85rem; cursor: pointer; transition: var(--transition); box-shadow: 0 2px 10px rgba(0,0,0,0.05); } .filter-btn.active { background: var(--accent-color); color: white; } .filter-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 15px rgba(0,0,0,0.1); } .destinations-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1.5rem; transition: var(--transition); } .destination-card { position: relative; border-radius: 15px; overflow: hidden; height: 280px; box-shadow: 0 10px 25px rgba(0,0,0,0.08); transition: var(--transition); cursor: pointer; } .destination-card:hover { transform: translateY(-8px); box-shadow: 0 15px 35px rgba(0,0,0,0.15); } .destination-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0) 60%); z-index: 1; opacity: 0.8; transition: var(--transition); } .destination-card:hover::before { opacity: 0.4; } .destination-img { width: 100%; height: 100%; object-fit: cover; transition: var(--transition); } .destination-card:hover .destination-img { transform: scale(1.1); } .destination-info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 1.5rem; color: white; z-index: 2; transform: translateY(0); transition: var(--transition); } .destination-card:hover .destination-info { transform: translateY(-5px); } .destination-name { font-family: 'Cormorant Garamond', serif; font-size: 1.5rem; font-weight: 600; margin-bottom: 0.3rem; transition: var(--transition); } .destination-country { font-size: 0.85rem; opacity: 0.9; display: flex; align-items: center; gap: 5px; } .country-icon { width: 16px; height: 16px; } .popup { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--overlay-dark); backdrop-filter: blur(4px); z-index: 3; display: flex; align-items: center; justify-content: center; opacity: 0; visibility: hidden; transition: var(--transition); padding: 1.5rem; border-radius: 15px; } .destination-card:hover .popup { opacity: 1; visibility: visible; } .popup-content { background: white; padding: 1rem; border-radius: 12px; width: 85%; max-width: 240px; text-align: left; transform: translateY(20px); transition: var(--transition); transition-delay: 0.1s; box-shadow: 0 15px 35px rgba(0,0,0,0.2); position: relative; } .destination-card:hover .popup-content { transform: translateY(0); } .popup-title { font-family: 'Cormorant Garamond', serif; font-size: 1.2rem; font-weight: 600; color: var(--dark-color); margin-bottom: 0.5rem; } .popup-info { font-size: 0.8rem; color: #555; margin-bottom: 0.8rem; } .popup-price { font-weight: 600; color: var(--accent-color); font-size: 1.1rem; margin-bottom: 0.8rem; } .popup-button { display: inline-block; padding: 0.4rem 1rem; background: var(--accent-color); color: white; border: none; border-radius: 20px; font-size: 0.8rem; cursor: pointer; transition: var(--transition); } .popup-button:hover { background: var(--dark-color); } .popup-close { position: absolute; top: 10px; right: 10px; cursor: pointer; color: var(--dark-color); font-size: 1rem; } .tag { position: absolute; top: 1rem; right: 1rem; background: var(--primary-color); color: white; padding: 0.3rem 0.8rem; border-radius: 20px; font-size: 0.7rem; font-weight: 500; z-index: 2; box-shadow: 0 5px 15px rgba(0,0,0,0.1); } .hot-deal { background: var(--secondary-color); } .eco-friendly { background: #6bab90; } .not-found { grid-column: 1 / -1; text-align: center; padding: 3rem 1rem; color: var(--dark-color); display: none; } .not-found img { width: 120px; margin-bottom: 1rem; opacity: 0.8; } .not-found h3 { font-family: 'Cormorant Garamond', serif; font-size: 1.5rem; margin-bottom: 0.5rem; } .not-found p { color: #777; font-size: 0.9rem; margin-bottom: 1rem; } .reset-btn { display: inline-block; padding: 0.5rem 1.2rem; background: var(--accent-color); color: white; border: none; border-radius: 20px; font-size: 0.8rem; cursor: pointer; transition: var(--transition); } .reset-btn:hover { background: var(--dark-color); transform: translateY(-2px); } /* Animation */ @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .destination-card { animation: fadeIn 0.6s ease-out forwards; opacity: 0; } .destination-card:nth-child(1) { animation-delay: 0.1s; } .destination-card:nth-child(2) { animation-delay: 0.2s; } .destination-card:nth-child(3) { animation-delay: 0.3s; } .destination-card:nth-child(4) { animation-delay: 0.4s; } .destination-card:nth-child(5) { animation-delay: 0.5s; } .destination-card:nth-child(6) { animation-delay: 0.6s; } /* Responsive Adjustments */ @media (max-width: 600px) { .destinations-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1rem; } .destination-card { height: 220px; } h1 { font-size: 1.8rem; } .popup-content { max-width: 180px; } .destination-name { font-size: 1.2rem; } } @media (max-width: 420px) { .container { padding: 1rem; } .destinations-grid { grid-template-columns: repeat(2, 1fr); } .destination-card { height: 180px; } .popup-content { padding: 0.8rem; max-width: 160px; } .destination-info { padding: 1rem; } .destination-name { font-size: 1.1rem; } } </style> </head> <body> <div class="container"> <header> <div class="logo"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z" fill="#c06c84"/> </svg> Wanderlust </div> <h1>Discover Hidden Gems</h1> <p class="subtitle">Carefully curated destinations for the discerning traveler</p> <div class="search-box"> <input type="text" id="search-input" placeholder="Search by destination or country..."> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M11 19C15.4183 19 19 15.4183 19 11C19 6.58172 15.4183 3 11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M21 21L16.65 16.65" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </div> <div class="filters"> <button class="filter-btn active" data-filter="all">All</button> <button class="filter-btn" data-filter="beach">Beaches</button> <button class="filter-btn" data-filter="mountain">Mountains</button> <button class="filter-btn" data-filter="city">Cities</button> <button class="filter-btn" data-filter="eco">Eco-Friendly</button> </div> </header> <div class="destinations-grid"> <!-- Destination 1 --> <div class="destination-card" data-category="beach eco"> <img src="https://images.unsplash.com/photo-1508957999498-e7a5e89ba28a?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80" alt="Milos, Greece" class="destination-img"> <div class="destination-info"> <h3 class="destination-name">Sarakiniko Beach</h3> <p class="destination-country"> <svg class="country-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M3 12H21M12 3C14.5013 5.73835 15.9228 9.29203 16 13C15.9228 16.708 14.5013 20.2616 12 23C9.49872 20.2616 8.07725 16.708 8 13C8.07725 9.29203 9.49872 5.73835 12 3Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Milos, Greece </p> </div> <div class="tag eco-friendly">Eco-Friendly</div> <div class="popup"> <div class="popup-content"> <div class="popup-close">×</div> <h4 class="popup-title">Sarakiniko Beach</h4> <p class="popup-info">Moonscape volcanic formations meet crystal blue waters in this otherworldly beach.</p> <p class="popup-price">From €789 / 6 nights</p> <button class="popup-button">View Details</button> </div> </div> </div> <!-- Destination 2 --> <div class="destination-card" data-category="mountain"> <img src="https://images.unsplash.com/photo-1508235181320-6703c60c27ad?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80" alt="Patagonia, Chile" class="destination-img"> <div class="destination-info"> <h3 class="destination-name">Torres del Paine</h3> <p class="destination-country"> <svg class="country-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M3 12H21M12 3C14.5013 5.73835 15.9228 9.29203 16 13C15.9228 16.708 14.5013 20.2616 12 23C9.49872 20.2616 8.07725 16.708 8 13C8.07725 9.29203 9.49872 5.73835 12 3Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Patagonia, Chile </p> </div> <div class="tag hot-deal">Hot Deal</div> <div class="popup"> <div class="popup-content"> <div class="popup-close">×</div> <h4 class="popup-title">Torres del Paine</h4> <p class="popup-info">Dramatic mountain peaks and pristine wilderness await in this Patagonian paradise.</p> <p class="popup-price">From $1,199 / 7 nights</p> <button class="popup-button">View Details</button> </div> </div> </div> <!-- Destination 3 --> <div class="destination-card" data-category="city"> <img src="https://images.unsplash.com/photo-1499856871958-5b9627545d1a?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80" alt="Kyoto, Japan" class="destination-img"> <div class="destination-info"> <h3 class="destination-name">Arashiyama</h3> <p class="destination-country"> <svg class="country-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M3 12H21M12 3C14.5013 5.73835 15.9228 9.29203 16 13C15.9228 16.708 14.5013 20.2616 12 23C9.49872 20.2616 8.07725 16.708 8 13C8.07725 9.29203 9.49872 5.73835 12 3Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Kyoto, Japan </p> </div> <div class="popup"> <div class="popup-content"> <div class="popup-close">×</div> <h4 class="popup-title">Arashiyama Bamboo Grove</h4> <p class="popup-info">Walk through enchanting bamboo forests and experience traditional Japanese culture.</p> <p class="popup-price">From ¥115,000 / 5 nights</p> <button class="popup-button">View Details</button> </div> </div> </div> <!-- Destination 4 --> <div class="destination-card" data-category="beach"> <img src="https://images.unsplash.com/photo-1546708473-5e8d1a52d228?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80" alt="Raja Ampat, Indonesia" class="destination-img"> <div class="destination-info"> <h3 class="destination-name">Raja Ampat</h3> <p class="destination-country"> <svg class="country-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M3 12H21M12 3C14.5013 5.73835 15.9228 9.29203 16 13C15.9228 16.708 14.5013 20.2616 12 23C9.49872 20.2616 8.07725 16.708 8 13C8.07725 9.29203 9.49872 5.73835 12 3Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> West Papua, Indonesia </p> </div> <div class="tag eco-friendly">Eco-Friendly</div> <div class="popup"> <div class="popup-content"> <div class="popup-close">×</div> <h4 class="popup-title">Raja Ampat Islands</h4> <p class="popup-info">Dive into the world's most biodiverse marine ecosystem with over 1,500 fish species.</p> <p class="popup-price">From $1,499 / 8 nights</p> <button class="popup-button">View Details</button> </div> </div> </div> <!-- Destination 5 --> <div class="destination-card" data-category="mountain eco"> <img src="https://images.unsplash.com/photo-1531804055935-76f44d7c3621?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80" alt="Banff, Canada" class="destination-img"> <div class="destination-info"> <h3 class="destination-name">Moraine Lake</h3> <p class="destination-country"> <svg class="country-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M3 12H21M12 3C14.5013 5.73835 15.9228 9.29203 16 13C15.9228 16.708 14.5013 20.2616 12 23C9.49872 20.2616 8.07725 16.708 8 13C8.07725 9.29203 9.49872 5.73835 12 3Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Banff, Canada </p> </div> <div class="popup"> <div class="popup-content"> <div class="popup-close">×</div> <h4 class="popup-title">Moraine Lake Lodge</h4> <p class="popup-info">Iconic turquoise waters surrounded by ten peaks in the Valley of the Ten Peaks.</p> <p class="popup-price">From CAD 1,299 / 5 nights</p> <button class="popup-button">View Details</button> </div> </div> </div> <!-- Destination 6 --> <div class="destination-card" data-category="city"> <img src="https://images.unsplash.com/photo-1562883676-8c7feb83f09b?ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80" alt="Marrakech, Morocco" class="destination-img"> <div class="destination-info"> <h3 class="destination-name">Jardin Majorelle</h3> <p class="destination-country"> <svg class="country-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M3 12H21M12 3C14.5013 5.73835 15.9228 9.29203 16 13C15.9228 16.708 14.5013 20.2616 12 23C9.49872 20.2616 8.07725 16.708 8 13C8.07725 9.29203 9.49872 5.73835 12 3Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Marrakech, Morocco </p> </div> <div class="tag hot-deal">Hot Deal</div> <div class="popup"> <div class="popup-content"> <div class="popup-close">×</div> <h4 class="popup-title">Marrakech Riad</h4> <p class="popup-info">Vibrant colors and lush gardens in this artistic oasis created by Yves Saint Laurent.</p> <p class="popup-price">From MAD 7,500 / 4 nights</p> <button class="popup-button">View Details</button> </div> </div> </div> <!-- Not Found Message --> <div class="not-found"> <img src="https://cdn.iconscout.com/icon/free/png-256/free-search-1767866-1502119.png" alt="Search icon"> <h3>No Destinations Found</h3> <p>We couldn't find any destinations matching your search. Try different keywords or browse our categories.</p> <button class="reset-btn" id="reset-search">Reset Search</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const searchInput = document.getElementById('search-input'); const resetSearchBtn = document.getElementById('reset-search'); const filterBtns = document.querySelectorAll('.filter-btn'); const destinationCards = document.querySelectorAll('.destination-card'); const notFoundMessage = document.querySelector('.not-found'); // Search functionality searchInput.addEventListener('input', filterDestinations); resetSearchBtn.addEventListener('click', resetSearch); // Filter buttons filterBtns.forEach(btn => { btn.addEventListener('click', () => { // Update active class filterBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); // Filter destinations const filterValue = btn.getAttribute('data-filter'); filterDestinationsByCategory(filterValue); }); }); // Close popup when clicking the X document.querySelectorAll('.popup-close').forEach(close => { close.addEventListener('click', (e) => { e.stopPropagation(); const popup = close.closest('.popup'); if (popup) { popup.style.opacity = '0'; popup.style.visibility = 'hidden'; // Reset visibility after animation setTimeout(() => { if (!close.closest('.destination-card').matches(':hover')) { popup.style = ''; } }, 400); } }); }); // Prevent popup from closing when clicking popup content document.querySelectorAll('.popup-content').forEach(content => { content.addEventListener('click', (e) => { e.stopPropagation(); }); }); // Functions function filterDestinations() { const searchTerm = searchInput.value.toLowerCase().trim(); let foundCount = 0; destinationCards.forEach(card => { const destinationName = card.querySelector('.destination-name').textContent.toLowerCase(); const destinationCountry = card.querySelector('.destination-country').textContent.toLowerCase(); if (destinationName.includes(searchTerm) || destinationCountry.includes(searchTerm)) { card.style.display = 'block'; foundCount++; } else { card.style.display = 'none'; } }); // Show/hide not found message notFoundMessage.style.display = foundCount === 0 ? 'block' : 'none'; // Reset category filters if searching if (searchTerm) { filterBtns.forEach(btn => btn.classList.remove('active')); filterBtns[0].classList.add('active'); // Set "All" as active } } function resetSearch() { searchInput.value = ''; filterBtns.forEach(btn => btn.classList.remove('active')); filterBtns[0].classList.add('active'); // Set "All" as active destinationCards.forEach(card => { card.style.display = 'block'; }); notFoundMessage.style.display = 'none'; } function filterDestinationsByCategory(category) { if (category === 'all') { destinationCards.forEach(card => { card.style.display = 'block'; }); notFoundMessage.style.display = 'none'; return; } let foundCount = 0; destinationCards.forEach(card => { const categories = card.getAttribute('data-category').split(' '); if (categories.includes(category)) { card.style.display = 'block'; foundCount++; } else { card.style.display = 'none'; } }); notFoundMessage.style.display = foundCount === 0 ? 'block' : 'none'; } // Add hover animation for cards destinationCards.forEach(card => { card.addEventListener('mouseenter', () => { const img = card.querySelector('.destination-img'); img.style.transform = 'scale(1.1)'; }); card.addEventListener('mouseleave', () => { const img = card.querySelector('.destination-img'); img.style.transform = 'scale(1)'; }); }); // Button click effect document.querySelectorAll('.popup-button, .filter-btn, .reset-btn').forEach(button => { button.addEventListener('click', function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.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.left = x + 'px'; ripple.style.top = y + 'px'; ripple.style.animation = 'ripple 0.6s linear'; this.style.overflow = 'hidden'; this.style.position = 'relative'; this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Educational Course Thumbnails</title> <style> :root { --primary: #2a6db5; --secondary: #2c94c8; --accent: #5dcbef; --dark: #1a365d; --light: #f0f6ff; --success: #35b37e; --warning: #ffab00; --danger: #ff5630; --card-size: 210px; --card-radius: 12px; --spacing: 20px; } * { 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: #f5f9ff; color: #333; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; min-height: 100vh; padding: 20px; overflow-x: hidden; } .container { width: 100%; max-width: 700px; margin: 0 auto; } header { margin-bottom: 24px; text-align: center; } h1 { font-size: 24px; font-weight: 700; color: var(--dark); margin-bottom: 8px; position: relative; display: inline-block; } h1::after { content: ''; position: absolute; left: 50%; bottom: -5px; width: 60px; height: 4px; background: linear-gradient(90deg, var(--primary), var(--accent)); transform: translateX(-50%); border-radius: 2px; } .filters { display: flex; justify-content: center; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; } .filter-btn { background: white; border: none; padding: 8px 16px; border-radius: 20px; font-size: 14px; font-weight: 500; color: var(--dark); cursor: pointer; transition: all 0.3s ease; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06); } .filter-btn:hover { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); transform: translateY(-2px); } .filter-btn.active { background: linear-gradient(135deg, var(--primary), var(--secondary)); color: white; } .search-bar { display: flex; margin-bottom: 24px; position: relative; max-width: 400px; margin-left: auto; margin-right: auto; } .search-bar input { flex: 1; padding: 12px 40px 12px 16px; border: 2px solid #e1ebfa; border-radius: var(--card-radius); font-size: 14px; background: white; transition: all 0.3s ease; } .search-bar input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(93, 203, 239, 0.2); } .search-icon { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); color: #94a3b8; } .courses-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(var(--card-size), 1fr)); gap: var(--spacing); margin-bottom: 20px; } .course-card { background: white; border-radius: var(--card-radius); overflow: hidden; position: relative; height: var(--card-size); display: flex; flex-direction: column; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; } .course-card:hover { transform: translateY(-5px); box-shadow: 0 12px 20px rgba(0, 0, 0, 0.12); } .course-card:hover .card-overlay { opacity: 1; transform: translateY(0); } .card-category { position: absolute; top: 12px; left: 12px; padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: 600; text-transform: uppercase; z-index: 2; } .category-design { background: linear-gradient(135deg, #5863f8, #5b48f2); color: white; } .category-programming { background: linear-gradient(135deg, #14b8a6, #0ea5e9); color: white; } .category-business { background: linear-gradient(135deg, #f59e0b, #f97316); color: white; } .category-marketing { background: linear-gradient(135deg, #ec4899, #c026d3); color: white; } .card-shape { position: absolute; background: var(--accent); opacity: 0.2; border-radius: 50%; z-index: 1; } .card-shape.circle { border-radius: 50%; } .card-shape.square { border-radius: 8px; } .card-shape.triangle { clip-path: polygon(50% 0%, 0% 100%, 100% 100%); border-radius: 0; } .card-icon { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; background: white; border-radius: 10px; margin-bottom: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .card-content { padding: 16px; position: relative; z-index: 2; background: white; flex-grow: 1; display: flex; flex-direction: column; } .card-title { font-size: 16px; font-weight: 700; color: var(--dark); margin-bottom: 6px; line-height: 1.3; } .card-stats { display: flex; font-size: 12px; color: #64748b; margin-bottom: 10px; gap: 12px; } .card-stat { display: flex; align-items: center; gap: 4px; } .card-progress { margin-top: auto; } .progress-bar { height: 4px; background: #e2e8f0; border-radius: 2px; overflow: hidden; margin-top: 4px; } .progress-fill { height: 100%; background: linear-gradient(90deg, var(--primary), var(--accent)); border-radius: 2px; transition: width 0.5s ease; } .card-overlay { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(to top, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.8)); padding: 20px; transform: translateY(100%); opacity: 0; transition: all 0.3s ease; border-top: 1px solid rgba(229, 231, 235, 0.5); z-index: 3; display: flex; flex-direction: column; gap: 12px; } .overlay-title { font-size: 16px; font-weight: 700; color: var(--dark); } .overlay-description { font-size: 13px; color: #4b5563; line-height: 1.5; } .overlay-button { background: var(--primary); color: white; border: none; padding: 8px 16px; border-radius: 6px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; margin-top: 8px; align-self: flex-start; display: flex; align-items: center; gap: 6px; } .overlay-button:hover { background: #1e5b99; } .pulse-animation { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(42, 109, 181, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(42, 109, 181, 0); } 100% { box-shadow: 0 0 0 0 rgba(42, 109, 181, 0); } } .loading-indicator { position: fixed; top: 20px; right: 20px; background: white; padding: 12px 20px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); display: flex; align-items: center; gap: 10px; opacity: 0; transform: translateY(-20px); transition: all 0.3s ease; z-index: 100; } .loading-indicator.show { opacity: 1; transform: translateY(0); } .spinner { width: 20px; height: 20px; border: 2px solid #e2e8f0; border-top-color: var(--primary); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .loading-text { font-size: 14px; color: #4b5563; } @media (max-width: 640px) { :root { --card-size: 160px; --spacing: 15px; } h1 { font-size: 20px; } .card-title { font-size: 14px; } .filter-btn { padding: 6px 12px; font-size: 12px; } } @media (max-width: 480px) { :root { --card-size: 140px; --spacing: 10px; } .courses-grid { grid-template-columns: repeat(2, 1fr); } .card-stats { display: none; } .card-progress { margin-top: 4px; } .card-category { font-size: 10px; padding: 3px 6px; } .overlay-description { font-size: 12px; } } </style> </head> <body> <div class="container"> <header> <h1>Skill Forge Academy</h1> <p>Interactive courses designed for modern learners</p> </header> <div class="filters"> <button class="filter-btn active" data-filter="all">All Courses</button> <button class="filter-btn" data-filter="design">Design</button> <button class="filter-btn" data-filter="programming">Programming</button> <button class="filter-btn" data-filter="business">Business</button> <button class="filter-btn" data-filter="marketing">Marketing</button> </div> <div class="search-bar"> <input type="text" placeholder="Search courses..." id="search-input"> <div class="search-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="11" cy="11" r="8"></circle> <line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </div> </div> <div class="courses-grid" id="courses-container"> <!-- Courses will be added here dynamically --> </div> </div> <div class="loading-indicator" id="loading-indicator"> <div class="spinner"></div> <div class="loading-text">Loading courses...</div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Course data const courses = [ { id: 1, title: "UI/UX Design Fundamentals", category: "design", progress: 75, students: 2481, duration: "8 weeks", description: "Master the core principles of user-centered design. Learn to create intuitive interfaces with advanced prototyping techniques and design systems.", shape: "circle", }, { id: 2, title: "Modern JavaScript Essentials", category: "programming", progress: 30, students: 3642, duration: "10 weeks", description: "From ES6+ features to async patterns, learn professional JavaScript techniques used in modern web development.", shape: "square", }, { id: 3, title: "Data-Driven Marketing", category: "marketing", progress: 60, students: 1859, duration: "6 weeks", description: "Learn how to analyze marketing data and create measurement frameworks that drive conversion optimization.", shape: "triangle", }, { id: 4, title: "Startup Fundamentals", category: "business", progress: 90, students: 2104, duration: "8 weeks", description: "From market validation to funding strategies, learn essential skills for launching a successful startup.", shape: "square", }, { id: 5, title: "React & Redux Masterclass", category: "programming", progress: 45, students: 3971, duration: "12 weeks", description: "Build complex, production-ready applications with React, Redux, and modern state management patterns.", shape: "circle", }, { id: 6, title: "Motion Design Principles", category: "design", progress: 20, students: 1532, duration: "7 weeks", description: "Create engaging animations that enhance user experience and bring interfaces to life with purpose.", shape: "triangle", }, { id: 7, title: "Growth Hacking Techniques", category: "marketing", progress: 65, students: 1789, duration: "5 weeks", description: "Discover rapid experimentation across marketing channels to identify the most effective ways to grow your business.", shape: "circle", }, { id: 8, title: "Financial Modeling", category: "business", progress: 50, students: 1431, duration: "9 weeks", description: "Learn to build dynamic financial models for valuation, forecasting, and business decision-making.", shape: "square", }, { id: 9, title: "Python for Data Science", category: "programming", progress: 80, students: 4210, duration: "11 weeks", description: "Master Python libraries like Pandas, NumPy and Matplotlib to analyze data and create powerful visualizations.", shape: "triangle", } ]; // DOM elements const coursesContainer = document.getElementById('courses-container'); const filterButtons = document.querySelectorAll('.filter-btn'); const searchInput = document.getElementById('search-input'); const loadingIndicator = document.getElementById('loading-indicator'); // Helper functions for UI manipulation function showLoading() { loadingIndicator.classList.add('show'); } function hideLoading() { loadingIndicator.classList.remove('show'); } // Generate course cards function renderCourses(coursesToRender) { coursesContainer.innerHTML = ''; if (coursesToRender.length === 0) { coursesContainer.innerHTML = ` <div style="grid-column: 1 / -1; text-align: center; padding: 40px;"> <p>No courses found matching your criteria.</p> </div> `; return; } coursesToRender.forEach(course => { const card = document.createElement('div'); card.className = 'course-card'; card.dataset.category = course.category; // Generate random positions and sizes for the geometric shapes const shapesCount = Math.floor(Math.random() * 3) + 2; let shapesHTML = ''; for (let i = 0; i < shapesCount; i++) { const size = Math.floor(Math.random() * 60) + 20; const top = Math.floor(Math.random() * 100); const left = Math.floor(Math.random() * 100); const opacity = (Math.random() * 0.2) + 0.05; const rotation = Math.floor(Math.random() * 360); shapesHTML += ` <div class="card-shape ${course.shape}" style=" width: ${size}px; height: ${size}px; top: ${top}%; left: ${left}%; opacity: ${opacity}; transform: rotate(${rotation}deg); "></div> `; } // Determine color based on category let categoryClass = ''; switch (course.category) { case 'design': categoryClass = 'category-design'; break; case 'programming': categoryClass = 'category-programming'; break; case 'business': categoryClass = 'category-business'; break; case 'marketing': categoryClass = 'category-marketing'; break; } card.innerHTML = ` <div class="card-category ${categoryClass}">${course.category}</div> ${shapesHTML} <div class="card-content"> <h3 class="card-title">${course.title}</h3> <div class="card-stats"> <div class="card-stat"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path> <circle cx="9" cy="7" r="4"></circle> <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path> <path d="M16 3.13a4 4 0 0 1 0 7.75"></path> </svg> ${course.students.toLocaleString()} </div> <div class="card-stat"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> ${course.duration} </div> </div> <div class="card-progress"> <div style="display: flex; justify-content: space-between; font-size: 12px;"> <span>Progress</span> <span>${course.progress}%</span> </div> <div class="progress-bar"> <div class="progress-fill" style="width: ${course.progress}%"></div> </div> </div> </div> <div class="card-overlay"> <h4 class="overlay-title">${course.title}</h4> <p class="overlay-description">${course.description}</p> <button class="overlay-button${course.progress < 100 ? ' pulse-animation' : ''}"> ${course.progress > 0 ? 'Continue Learning' : 'Start Course'} <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polygon points="5 3 19 12 5 21 5 3"></polygon> </svg> </button> </div> `; coursesContainer.appendChild(card); }); } // Filter courses based on category and search term function filterCourses() { const activeFilter = document.querySelector('.filter-btn.active').dataset.filter; const searchTerm = searchInput.value.toLowerCase().trim(); showLoading(); // Simulate loading delay setTimeout(() => { let filteredCourses = courses; if (activeFilter !== 'all') { filteredCourses = filteredCourses.filter(course => course.category === activeFilter); } if (searchTerm) { filteredCourses = filteredCourses.filter(course => course.title.toLowerCase().includes(searchTerm) || course.description.toLowerCase().includes(searchTerm) ); } renderCourses(filteredCourses); hideLoading(); }, 400); } // Set up event listeners filterButtons.forEach(button => { button.addEventListener('click', () => { filterButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); filterCourses(); }); }); searchInput.addEventListener('input', filterCourses); // Initial render showLoading(); setTimeout(() => { renderCourses(courses); hideLoading(); }, 800); // Add some interaction for demo purposes document.body.addEventListener('click', function(e) { if (e.target.classList.contains('overlay-button')) { e.preventDefault(); e.target.innerHTML = 'Loading...'; setTimeout(() => { e.target.innerHTML = ` Course Ready <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> `; e.target.style.background = 'var(--success)'; }, 1000); } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Artisan Showcase</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Courier New', Courier, monospace; } body { background-color: #f5f1e8; width: 100%; height: 100vh; padding: 20px; display: flex; flex-direction: column; align-items: center; overflow-x: hidden; } .header { text-align: center; margin-bottom: 25px; position: relative; } .header h1 { font-size: 2.2rem; color: #5a4a3f; margin-bottom: 5px; font-weight: normal; letter-spacing: -1px; font-family: 'Courier New', Courier, monospace; position: relative; display: inline-block; } .header h1::after { content: ""; position: absolute; bottom: -5px; left: 10%; width: 80%; height: 2px; background: #c69c6d; } .header p { font-size: 0.95rem; color: #7d6b5d; max-width: 600px; margin: 0 auto; font-style: italic; } .gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 25px; width: 100%; max-width: 660px; margin-top: 10px; } .thumbnail { position: relative; border-radius: 4px; overflow: hidden; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease, box-shadow 0.3s ease; background-color: #e8e1d5; height: 200px; cursor: pointer; } .thumbnail:hover { transform: translateY(-5px); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15); } .thumbnail img { width: 100%; height: 100%; object-fit: cover; transition: filter 0.4s ease; } .thumbnail:hover img { filter: brightness(1.05) contrast(1.05); } .thumb-info { position: absolute; bottom: 0; left: 0; width: 100%; padding: 10px; background: rgba(233, 227, 216, 0.9); transform: translateY(100%); transition: transform 0.3s ease; } .thumbnail:hover .thumb-info { transform: translateY(0); } .thumb-info h3 { font-size: 0.95rem; color: #5a4a3f; margin-bottom: 5px; font-family: 'Courier New', Courier, monospace; font-weight: bold; } .thumb-info p { font-size: 0.75rem; color: #7d6b5d; margin-bottom: 5px; } .badge { position: absolute; top: 15px; right: 15px; width: 60px; height: 60px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='45' fill='%23a67c52' /%3E%3Ccircle cx='50' cy='50' r='42' fill='none' stroke='%23efe5d7' stroke-width='2' stroke-dasharray='3,2' /%3E%3C/svg%3E"); background-size: contain; display: flex; justify-content: center; align-items: center; opacity: 0; transform: rotate(-10deg) scale(0.8); transition: opacity 0.3s ease, transform 0.4s ease; pointer-events: none; } .badge span { font-size: 0.7rem; color: #fff; font-weight: bold; text-transform: uppercase; transform: rotate(-10deg); text-align: center; line-height: 1; } .thumbnail:hover .badge { opacity: 1; transform: rotate(0) scale(1); } .filter-controls { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; justify-content: center; } .filter-btn { padding: 8px 15px; background: none; border: 2px solid #c69c6d; color: #5a4a3f; border-radius: 30px; cursor: pointer; font-size: 0.85rem; transition: all 0.3s ease; position: relative; overflow: hidden; font-family: 'Courier New', Courier, monospace; } .filter-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: rgba(198, 156, 109, 0.2); transition: all 0.3s ease; z-index: -1; } .filter-btn:hover::before { left: 0; } .filter-btn.active { background-color: #c69c6d; color: #fff; } .thumbnail.hide { display: none; } .thumbnail.show { display: block; animation: fadeIn 0.5s ease forwards; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .grain-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); opacity: 0.05; pointer-events: none; z-index: 10; } /* Responsive adjustments */ @media (max-width: 600px) { .gallery { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; } .header h1 { font-size: 1.8rem; } .header p { font-size: 0.85rem; } .thumbnail { height: 150px; } .filter-controls { gap: 5px; } .filter-btn { padding: 6px 12px; font-size: 0.75rem; } } </style> </head> <body> <div class="grain-overlay"></div> <div class="header"> <h1>HANDCRAFTED TREASURES</h1> <p>Each piece tells a story of skill, patience, and dedication to traditional craftsmanship</p> </div> <div class="filter-controls"> <button class="filter-btn active" data-filter="all">All Crafts</button> <button class="filter-btn" data-filter="pottery">Pottery</button> <button class="filter-btn" data-filter="textile">Textiles</button> <button class="filter-btn" data-filter="woodwork">Woodwork</button> <button class="filter-btn" data-filter="jewelry">Jewelry</button> </div> <div class="gallery"> <div class="thumbnail" data-category="pottery"> <img src="https://images.unsplash.com/photo-1565193566173-7a0ee3dbe261?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Handmade ceramic bowls"> <div class="thumb-info"> <h3>Rustic Ceramic Bowls</h3> <p>Hand-thrown on wheel with local clay</p> </div> <div class="badge"> <span>Hand Crafted</span> </div> </div> <div class="thumbnail" data-category="textile"> <img src="https://images.unsplash.com/photo-1584377334016-464803e03b80?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Indigo dyed fabrics"> <div class="thumb-info"> <h3>Indigo Dip-Dyed Textiles</h3> <p>Natural dyes on organic cotton</p> </div> <div class="badge"> <span>Natural Dyes</span> </div> </div> <div class="thumbnail" data-category="woodwork"> <img src="https://images.unsplash.com/photo-1605627079912-97c3810a11a4?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Carved wooden spoons"> <div class="thumb-info"> <h3>Carved Oak Utensils</h3> <p>Sculpted from reclaimed timber</p> </div> <div class="badge"> <span>Sustainable</span> </div> </div> <div class="thumbnail" data-category="jewelry"> <img src="https://images.unsplash.com/photo-1535632787350-4e68ef0ac584?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Handmade silver jewelry"> <div class="thumb-info"> <h3>Forged Silver Pendants</h3> <p>Hammered with traditional techniques</p> </div> <div class="badge"> <span>Artisan Made</span> </div> </div> <div class="thumbnail" data-category="pottery"> <img src="https://images.unsplash.com/photo-1610701596007-11502861dcfa?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Glazed ceramic mugs"> <div class="thumb-info"> <h3>Stoneware Coffee Mugs</h3> <p>Unique glaze patterns, no two alike</p> </div> <div class="badge"> <span>One of a Kind</span> </div> </div> <div class="thumbnail" data-category="woodwork"> <img src="https://images.unsplash.com/photo-1622377324358-d16e2e5a6439?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Wooden cutting board"> <div class="thumb-info"> <h3>Walnut Serving Boards</h3> <p>Oil-finished with bee's wax blend</p> </div> <div class="badge"> <span>Heirloom</span> </div> </div> <div class="thumbnail" data-category="textile"> <img src="https://images.unsplash.com/photo-1550383377-5d517a7d2b64?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Handwoven textile"> <div class="thumb-info"> <h3>Hand-Loomed Wall Hanging</h3> <p>Woven with merino and linen</p> </div> <div class="badge"> <span>Slow Craft</span> </div> </div> <div class="thumbnail" data-category="jewelry"> <img src="https://images.unsplash.com/photo-1602173574767-37ac01994b2a?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Beaded jewelry"> <div class="thumb-info"> <h3>Beaded Brass Earrings</h3> <p>Delicate heritage-inspired design</p> </div> <div class="badge"> <span>Small Batch</span> </div> </div> <div class="thumbnail" data-category="pottery"> <img src="https://images.unsplash.com/photo-1556760544-74068565f05c?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&h=400&q=80" alt="Ceramic vase"> <div class="thumb-info"> <h3>Minimalist Bud Vases</h3> <p>Raw clay exterior, glazed interior</p> </div> <div class="badge"> <span>Studio Made</span> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Filter functionality const filterButtons = document.querySelectorAll('.filter-btn'); const thumbnails = document.querySelectorAll('.thumbnail'); filterButtons.forEach(button => { button.addEventListener('click', function() { // Update active button filterButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); const filterValue = this.getAttribute('data-filter'); // Filter thumbnails thumbnails.forEach(thumbnail => { thumbnail.classList.remove('show'); thumbnail.classList.add('hide'); setTimeout(() => { if (filterValue === 'all' || thumbnail.getAttribute('data-category') === filterValue) { thumbnail.classList.remove('hide'); thumbnail.classList.add('show'); } }, 300); }); }); }); // Staggered animation for initial load thumbnails.forEach((thumbnail, index) => { setTimeout(() => { thumbnail.classList.add('show'); }, 100 * index); }); // Add mousemove parallax effect to badges thumbnails.forEach(thumbnail => { thumbnail.addEventListener('mousemove', function(e) { const badge = this.querySelector('.badge'); const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; const moveX = (x - centerX) / 20; const moveY = (y - centerY) / 20; badge.style.transform = `rotate(0deg) scale(1) translate(${moveX}px, ${moveY}px)`; }); thumbnail.addEventListener('mouseleave', function() { const badge = this.querySelector('.badge'); badge.style.transform = 'rotate(0) scale(1)'; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dashboard Overview Thumbnails</title> <style> :root { --primary: #4361ee; --primary-light: #4895ef; --secondary: #3a0ca3; --success: #4cc9f0; --warning: #f72585; --dark: #252525; --light: #f8f9fa; --gray: #adb5bd; --shadow: rgba(0, 0, 0, 0.1); --transition: all 0.3s ease; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } body { background-color: #f5f7fa; color: var(--dark); height: 100vh; overflow-x: hidden; display: flex; flex-direction: column; } .container { max-width: 700px; margin: 0 auto; padding: 20px; width: 100%; } header { margin-bottom: 20px; } .header-title { font-size: 24px; font-weight: 700; margin-bottom: 5px; color: var(--dark); } .header-subtitle { font-size: 14px; color: var(--gray); margin-bottom: 20px; } .search-filter-wrapper { display: flex; align-items: center; margin-bottom: 20px; gap: 10px; } .search-bar { position: relative; flex: 1; } .search-bar input { width: 100%; padding: 10px 15px 10px 40px; border-radius: 8px; border: 1px solid #e9ecef; font-size: 14px; transition: var(--transition); } .search-bar input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.1); } .search-bar i { position: absolute; left: 15px; top: 50%; transform: translateY(-50%); color: var(--gray); } .filter-dropdown { position: relative; } .filter-btn { display: flex; align-items: center; gap: 5px; background: white; border: 1px solid #e9ecef; padding: 10px 15px; border-radius: 8px; cursor: pointer; transition: var(--transition); font-size: 14px; } .filter-btn:hover { border-color: var(--primary-light); } .filter-options { position: absolute; top: 100%; right: 0; width: 180px; background: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); z-index: 10; margin-top: 5px; opacity: 0; visibility: hidden; transform: translateY(-10px); transition: var(--transition); } .filter-options.active { opacity: 1; visibility: visible; transform: translateY(0); } .filter-option { padding: 10px 15px; cursor: pointer; transition: var(--transition); font-size: 14px; border-radius: 8px; } .filter-option:hover { background: #f8f9fa; color: var(--primary); } .dashboard-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; } .dashboard-card { background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 8px var(--shadow); transition: var(--transition); cursor: pointer; position: relative; } .dashboard-card:hover { transform: translateY(-5px); box-shadow: 0 8px 16px var(--shadow); } .card-visualization { padding: 20px 15px; min-height: 120px; position: relative; overflow: hidden; display: flex; justify-content: center; align-items: center; } .card-viz-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.02); backdrop-filter: blur(2px); opacity: 0; transition: var(--transition); display: flex; justify-content: center; align-items: center; } .dashboard-card:hover .card-viz-overlay { opacity: 1; } .overlay-btn { background: var(--primary); color: white; border: none; padding: 8px 15px; border-radius: 6px; font-size: 14px; cursor: pointer; transition: var(--transition); transform: translateY(10px); opacity: 0; } .dashboard-card:hover .overlay-btn { transform: translateY(0); opacity: 1; } .overlay-btn:hover { background: var(--secondary); } .card-footer { padding: 15px; border-top: 1px solid #f1f3f5; background: #fbfbfd; } .card-title { font-size: 16px; font-weight: 600; margin-bottom: 5px; color: var(--dark); } .card-meta { display: flex; justify-content: space-between; align-items: center; } .card-updated { font-size: 12px; color: var(--gray); } .card-stats { display: flex; align-items: center; gap: 8px; } .stat { display: flex; align-items: center; gap: 3px; font-size: 12px; color: var(--gray); } .stat i { font-size: 14px; } .pulse { position: absolute; top: 10px; right: 10px; width: 10px; height: 10px; border-radius: 50%; background: var(--success); } .pulse::after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background: rgba(76, 201, 240, 0.6); animation: pulse 1.5s infinite; } @keyframes pulse { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(2.5); opacity: 0; } } .badge { position: absolute; top: 10px; left: 10px; padding: 4px 8px; border-radius: 4px; font-size: 10px; font-weight: 600; text-transform: uppercase; background: var(--warning); color: white; } .tooltip { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); padding: 10px 15px; background: rgba(37, 37, 37, 0.95); color: white; border-radius: 6px; font-size: 12px; opacity: 0; visibility: hidden; transition: var(--transition); pointer-events: none; width: 180px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); z-index: 100; } .tooltip::after { content: ''; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: rgba(37, 37, 37, 0.95) transparent transparent transparent; } .tooltip-trigger:hover .tooltip { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(-10px); } .tooltip-title { font-weight: 600; margin-bottom: 5px; color: #fff; } .tooltip-metric { display: flex; justify-content: space-between; margin-bottom: 5px; } .tooltip-metric-label { color: var(--gray); } .tooltip-metric-value { font-weight: 600; } .tooltip-trend { display: flex; align-items: center; gap: 5px; font-size: 11px; } .trend-up { color: #10b981; } .trend-down { color: #ef4444; } /* Visualization styles */ .bar-chart { height: 80px; display: flex; align-items: flex-end; justify-content: space-between; padding: 0 10px; width: 100%; } .bar { width: 8px; border-radius: 4px; background: var(--primary-light); transition: var(--transition); position: relative; } .bar::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(to bottom, rgba(255,255,255,0.2), rgba(255,255,255,0)); border-radius: 4px; } .donut-chart { width: 80px; height: 80px; position: relative; } .donut-segment { stroke-width: 10; fill: transparent; } .donut-hole { fill: white; } .donut-center-text { font-size: 16px; font-weight: bold; text-anchor: middle; dominant-baseline: middle; fill: var(--dark); } .line-chart { height: 80px; width: 100%; position: relative; } .line-path { fill: none; stroke: var(--primary); stroke-width: 2; stroke-linecap: round; } .area-path { fill: url(#lineGradient); opacity: 0.3; } .dot { fill: var(--primary); stroke: white; stroke-width: 2; } .dot:hover { fill: var(--secondary); } .heatmap { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 1fr); gap: 4px; width: 100%; height: 80px; } .heatmap-cell { border-radius: 2px; transition: var(--transition); } .heatmap-cell:hover { transform: scale(1.1); } .kpi-card { display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100%; } .kpi-value { font-size: 28px; font-weight: 700; color: var(--primary); } .kpi-label { font-size: 12px; color: var(--gray); margin-top: 5px; } .scatter-plot { height: 80px; width: 100%; position: relative; } .scatter-dot { fill: var(--primary-light); stroke: white; stroke-width: 1; transition: var(--transition); } .scatter-dot:hover { fill: var(--secondary); transform: scale(1.2); } /* Responsive styles */ @media (max-width: 600px) { .dashboard-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; } .card-visualization { min-height: 100px; } .header-title { font-size: 20px; } .search-filter-wrapper { flex-direction: column; align-items: stretch; } .search-bar, .filter-dropdown { width: 100%; } } /* Animation for dashboard cards loading */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .dashboard-card { animation: fadeInUp 0.5s ease-out forwards; } .dashboard-card:nth-child(1) { animation-delay: 0.1s; } .dashboard-card:nth-child(2) { animation-delay: 0.2s; } .dashboard-card:nth-child(3) { animation-delay: 0.3s; } .dashboard-card:nth-child(4) { animation-delay: 0.4s; } .dashboard-card:nth-child(5) { animation-delay: 0.5s; } .dashboard-card:nth-child(6) { animation-delay: 0.6s; } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> </head> <body> <div class="container"> <header> <h1 class="header-title">Analytics Dashboard Hub</h1> <p class="header-subtitle">Access your most important business insights at a glance</p> <div class="search-filter-wrapper"> <div class="search-bar"> <i class="fas fa-search"></i> <input type="text" placeholder="Search dashboards..."> </div> <div class="filter-dropdown"> <button class="filter-btn"> <span>Sort by</span> <i class="fas fa-chevron-down"></i> </button> <div class="filter-options"> <div class="filter-option">Recently Updated</div> <div class="filter-option">Most Viewed</div> <div class="filter-option">Alphabetical</div> <div class="filter-option">Data Freshness</div> </div> </div> </div> </header> <div class="dashboard-grid"> <!-- Revenue Performance Dashboard --> <div class="dashboard-card"> <div class="badge">Trending</div> <div class="card-visualization tooltip-trigger"> <div class="bar-chart"> <div class="bar" style="height: 60%;"></div> <div class="bar" style="height: 80%;"></div> <div class="bar" style="height: 50%;"></div> <div class="bar" style="height: 75%;"></div> <div class="bar" style="height: 90%;"></div> <div class="bar" style="height: 65%;"></div> </div> <div class="tooltip"> <div class="tooltip-title">Revenue Snapshot</div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Q3 Total:</span> <span class="tooltip-metric-value">$2.4M</span> </div> <div class="tooltip-metric"> <span class="tooltip-metric-label">vs Q2:</span> <span class="tooltip-metric-value trend-up">+12.8% <i class="fas fa-arrow-up"></i></span> </div> </div> <div class="card-viz-overlay"> <button class="overlay-btn">View Details</button> </div> </div> <div class="card-footer"> <h3 class="card-title">Revenue Performance</h3> <div class="card-meta"> <div class="card-updated">Updated 2h ago</div> <div class="card-stats"> <div class="stat"> <i class="fas fa-eye"></i> <span>28</span> </div> </div> </div> </div> </div> <!-- Customer Acquisition Dashboard --> <div class="dashboard-card"> <div class="pulse"></div> <div class="card-visualization tooltip-trigger"> <svg class="donut-chart" viewBox="0 0 100 100"> <defs> <linearGradient id="donutGradient1" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" stop-color="#4361ee" /> <stop offset="100%" stop-color="#4895ef" /> </linearGradient> <linearGradient id="donutGradient2" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" stop-color="#f72585" /> <stop offset="100%" stop-color="#ff758f" /> </linearGradient> </defs> <circle class="donut-segment" cx="50" cy="50" r="40" stroke="url(#donutGradient1)" stroke-dasharray="188.5 62.8" stroke-dashoffset="0"></circle> <circle class="donut-segment" cx="50" cy="50" r="40" stroke="url(#donutGradient2)" stroke-dasharray="62.8 188.5" stroke-dashoffset="-188.5"></circle> <circle class="donut-hole" cx="50" cy="50" r="35"></circle> <text class="donut-center-text" x="50" y="50">75%</text> </svg> <div class="tooltip"> <div class="tooltip-title">Customer Acquisition</div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Conversion Rate:</span> <span class="tooltip-metric-value">75%</span> </div> <div class="tooltip-metric"> <span class="tooltip-metric-label">New Users:</span> <span class="tooltip-metric-value trend-up">+42 <i class="fas fa-arrow-up"></i></span> </div> </div> <div class="card-viz-overlay"> <button class="overlay-btn">View Details</button> </div> </div> <div class="card-footer"> <h3 class="card-title">Customer Acquisition</h3> <div class="card-meta"> <div class="card-updated">Updated 10m ago</div> <div class="card-stats"> <div class="stat"> <i class="fas fa-eye"></i> <span>36</span> </div> </div> </div> </div> </div> <!-- Product Sales Dashboard --> <div class="dashboard-card"> <div class="card-visualization tooltip-trigger"> <svg class="line-chart" viewBox="0 0 200 100"> <defs> <linearGradient id="lineGradient" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" stop-color="#4361ee" stop-opacity="0.7" /> <stop offset="100%" stop-color="#4361ee" stop-opacity="0.1" /> </linearGradient> </defs> <path class="area-path" d="M0,80 L40,60 L80,70 L120,30 L160,40 L200,20 L200,100 L0,100 Z"></path> <path class="line-path" d="M0,80 L40,60 L80,70 L120,30 L160,40 L200,20"></path> <circle class="dot" cx="0" cy="80" r="4"></circle> <circle class="dot" cx="40" cy="60" r="4"></circle> <circle class="dot" cx="80" cy="70" r="4"></circle> <circle class="dot" cx="120" cy="30" r="4"></circle> <circle class="dot" cx="160" cy="40" r="4"></circle> <circle class="dot" cx="200" cy="20" r="4"></circle> </svg> <div class="tooltip"> <div class="tooltip-title">Product Sales Trends</div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Peak Sales:</span> <span class="tooltip-metric-value">1,842 units</span> </div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Growth Rate:</span> <span class="tooltip-metric-value trend-up">+18.3% <i class="fas fa-arrow-up"></i></span> </div> </div> <div class="card-viz-overlay"> <button class="overlay-btn">View Details</button> </div> </div> <div class="card-footer"> <h3 class="card-title">Product Sales Trends</h3> <div class="card-meta"> <div class="card-updated">Updated 4h ago</div> <div class="card-stats"> <div class="stat"> <i class="fas fa-eye"></i> <span>19</span> </div> </div> </div> </div> </div> <!-- Marketing ROI Dashboard --> <div class="dashboard-card"> <div class="card-visualization tooltip-trigger"> <div class="heatmap"> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.1);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.2);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.3);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.1);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.4);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.6);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.7);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.3);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.5);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.8);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.9);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.5);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.2);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.4);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.5);"></div> <div class="heatmap-cell" style="background-color: rgba(76, 201, 240, 0.3);"></div> </div> <div class="tooltip"> <div class="tooltip-title">Marketing ROI</div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Top Channel:</span> <span class="tooltip-metric-value">Email (4.2x)</span> </div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Campaign Efficiency:</span> <span class="tooltip-metric-value trend-up">+8.5% <i class="fas fa-arrow-up"></i></span> </div> </div> <div class="card-viz-overlay"> <button class="overlay-btn">View Details</button> </div> </div> <div class="card-footer"> <h3 class="card-title">Marketing ROI</h3> <div class="card-meta"> <div class="card-updated">Updated 1d ago</div> <div class="card-stats"> <div class="stat"> <i class="fas fa-eye"></i> <span>24</span> </div> </div> </div> </div> </div> <!-- Operational KPIs Dashboard --> <div class="dashboard-card"> <div class="card-visualization tooltip-trigger"> <div class="kpi-card"> <div class="kpi-value">97.8%</div> <div class="kpi-label">Operational Efficiency</div> </div> <div class="tooltip"> <div class="tooltip-title">Operational KPIs</div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Uptime:</span> <span class="tooltip-metric-value">99.99%</span> </div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Response Time:</span> <span class="tooltip-metric-value trend-down">-12ms <i class="fas fa-arrow-down"></i></span> </div> </div> <div class="card-viz-overlay"> <button class="overlay-btn">View Details</button> </div> </div> <div class="card-footer"> <h3 class="card-title">Operational KPIs</h3> <div class="card-meta"> <div class="card-updated">Updated 30m ago</div> <div class="card-stats"> <div class="stat"> <i class="fas fa-eye"></i> <span>17</span> </div> </div> </div> </div> </div> <!-- Customer Segmentation Dashboard --> <div class="dashboard-card"> <div class="card-visualization tooltip-trigger"> <svg class="scatter-plot" viewBox="0 0 200 100"> <circle class="scatter-dot" cx="30" cy="60" r="6"></circle> <circle class="scatter-dot" cx="60" cy="40" r="7"></circle> <circle class="scatter-dot" cx="90" cy="70" r="5"></circle> <circle class="scatter-dot" cx="120" cy="30" r="8"></circle> <circle class="scatter-dot" cx="150" cy="50" r="6"></circle> <circle class="scatter-dot" cx="180" cy="20" r="7"></circle> </svg> <div class="tooltip"> <div class="tooltip-title">Customer Segmentation</div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Key Segment:</span> <span class="tooltip-metric-value">Enterprise (38%)</span> </div> <div class="tooltip-metric"> <span class="tooltip-metric-label">Growth Segment:</span> <span class="tooltip-metric-value trend-up">SMB +15.2% <i class="fas fa-arrow-up"></i></span> </div> </div> <div class="card-viz-overlay"> <button class="overlay-btn">View Details</button> </div> </div> <div class="card-footer"> <h3 class="card-title">Customer Segmentation</h3> <div class="card-meta"> <div class="card-updated">Updated 12h ago</div> <div class="card-stats"> <div class="stat"> <i class="fas fa-eye"></i> <span>21</span> </div> </div> </div> </div> </div> </div> </div> <script> // Filter dropdown functionality const filterBtn = document.querySelector('.filter-btn'); const filterOptions = document.querySelector('.filter-options'); filterBtn.addEventListener('click', () => { filterOptions.classList.toggle('active'); }); document.addEventListener('click', (e) => { if (!e.target.closest('.filter-dropdown')) { filterOptions.classList.remove('active'); } }); // Filter options functionality const filterOptionElements = document.querySelectorAll('.filter-option'); filterOptionElements.forEach(option => { option.addEventListener('click', () => { filterBtn.querySelector('span').textContent = option.textContent; filterOptions.classList.remove('active'); // Simulate reordering (in real app would sort the dashboard cards) const dashboardCards = [...document.querySelectorAll('.dashboard-card')]; const dashboardGrid = document.querySelector('.dashboard-grid'); // Remove all cards dashboardCards.forEach(card => dashboardGrid.removeChild(card)); // Shuffle and reinsert for demo purposes if (option.textContent === 'Most Viewed') { const sorted = [...dashboardCards].sort(() => Math.random() - 0.5); sorted.forEach(card => dashboardGrid.appendChild(card)); } else if (option.textContent === 'Recently Updated') { const sorted = [...dashboardCards].sort(() => Math.random() - 0.5); sorted.forEach(card => dashboardGrid.appendChild(card)); } else { dashboardCards.forEach(card => dashboardGrid.appendChild(card)); } }); }); // Search functionality const searchInput = document.querySelector('.search-bar input'); searchInput.addEventListener('input', (e) => { const searchTerm = e.target.value.toLowerCase(); const cards = document.querySelectorAll('.dashboard-card'); cards.forEach(card => { const title = card.querySelector('.card-title').textContent.toLowerCase(); if (title.includes(searchTerm)) { card.style.display = 'block'; } else { card.style.display = 'none'; } }); }); // Card hover animations const bars = document.querySelectorAll('.bar'); bars.forEach(bar => { const originalHeight = bar.style.height; bar.addEventListener('mouseenter', () => { bar.style.height = `${parseInt(originalHeight) + 10}%`; }); bar.addEventListener('mouseleave', () => { bar.style.height = originalHeight; }); }); // Simulate real-time data updates for the pulse element setInterval(() => { const pulse = document.querySelector('.pulse'); pulse.style.opacity = '0'; setTimeout(() => { pulse.style.opacity = '1'; }, 500); }, 5000); // Add click handlers for buttons const overlayBtns = document.querySelectorAll('.overlay-btn'); overlayBtns.forEach(btn => { btn.addEventListener('click', (e) => { e.stopPropagation(); const card = btn.closest('.dashboard-card'); const title = card.querySelector('.card-title').textContent; console.log(`Opening detailed view for ${title}`); // In a real app, this would navigate to a detailed dashboard or show a modal // For demo purposes, animate the button btn.style.transform = 'scale(0.95)'; setTimeout(() => { btn.style.transform = 'scale(1)'; }, 100); }); }); // Animated donut chart const donutSegments = document.querySelectorAll('.donut-segment'); donutSegments.forEach(segment => { const originalDashArray = segment.getAttribute('stroke-dasharray'); const originalDashOffset = segment.getAttribute('stroke-dashoffset'); // Reset to zero segment.setAttribute('stroke-dasharray', '0 251.3'); segment.setAttribute('stroke-dashoffset', '0'); // Animate to final value setTimeout(() => { segment.style.transition = 'stroke-dasharray 1.5s ease-in-out'; segment.setAttribute('stroke-dasharray', originalDashArray); segment.setAttribute('stroke-dashoffset', originalDashOffset); }, 300); }); // Simulating data freshness setInterval(() => { const updatedTexts = document.querySelectorAll('.card-updated'); const randomIndex = Math.floor(Math.random() * updatedTexts.length); updatedTexts[randomIndex].textContent = 'Updated just now'; // Flash animation updatedTexts[randomIndex].style.color = '#4361ee'; updatedTexts[randomIndex].style.fontWeight = 'bold'; setTimeout(() => { updatedTexts[randomIndex].style.color = ''; updatedTexts[randomIndex].style.fontWeight = ''; }, 2000); }, 10000); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Event & Concert Thumbnails</title> <style> :root { --primary-color: #ff3e6c; --secondary-color: #4a2fb3; --accent-color: #ffca28; --dark-color: #1a1a2e; --light-color: #f7f7f9; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--dark-color); color: var(--light-color); display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; overflow-x: hidden; padding: 1.5rem; } .container { max-width: 700px; width: 100%; } header { text-align: center; margin-bottom: 2rem; position: relative; } h1 { font-size: 2.5rem; font-weight: 900; background: linear-gradient(45deg, var(--primary-color), var(--accent-color)); -webkit-background-clip: text; background-clip: text; color: transparent; margin-bottom: 0.5rem; position: relative; display: inline-block; } h1::after { content: ''; position: absolute; bottom: -5px; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); transform: scaleX(0); transform-origin: left; transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1); } h1:hover::after { transform: scaleX(1); } .subtitle { font-size: 1rem; opacity: 0.8; max-width: 600px; margin: 0 auto; } .filter-tabs { display: flex; justify-content: center; gap: 0.5rem; margin-bottom: 2rem; flex-wrap: wrap; } .filter-tab { background: rgba(255, 255, 255, 0.1); border: none; color: var(--light-color); padding: 0.6rem 1.2rem; border-radius: 50px; cursor: pointer; transition: all 0.3s ease; font-weight: 600; font-size: 0.9rem; } .filter-tab:hover { background: rgba(255, 255, 255, 0.2); transform: translateY(-2px); } .filter-tab.active { background: var(--primary-color); color: white; box-shadow: 0 5px 15px rgba(255, 62, 108, 0.3); } .event-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1.5rem; width: 100%; } .event-card { position: relative; border-radius: 12px; overflow: hidden; cursor: pointer; height: 300px; transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); perspective: 1000px; } .event-card:hover { transform: translateY(-10px); box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3); } .card-front, .card-back { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .card-front { transform: rotateY(0deg); } .card-back { transform: rotateY(180deg); background: linear-gradient(135deg, var(--secondary-color), var(--primary-color)); display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 1.5rem; text-align: center; } .event-card:hover .card-front { transform: rotateY(180deg); } .event-card:hover .card-back { transform: rotateY(0deg); } .thumb-image { width: 100%; height: 100%; object-fit: cover; position: absolute; top: 0; left: 0; } .date-badge { position: absolute; top: 15px; left: 15px; background: var(--accent-color); color: var(--dark-color); padding: 0.5rem; border-radius: 8px; font-weight: 700; font-size: 0.9rem; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); opacity: 0; transform: translateY(-20px); transition: all 0.4s ease; z-index: 1; } .event-card:hover .date-badge { opacity: 1; transform: translateY(0); } .event-info { position: absolute; bottom: 0; left: 0; width: 100%; background: linear-gradient(0deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 100%); padding: 1.5rem; transform: translateY(20px); opacity: 0; transition: all 0.4s ease; } .event-card:hover .event-info { transform: translateY(0); opacity: 1; } .event-title { font-size: 1.2rem; font-weight: 800; margin-bottom: 0.5rem; background: linear-gradient(to right, #fff, #ddd); -webkit-background-clip: text; background-clip: text; color: transparent; } .event-venue { font-size: 0.9rem; opacity: 0.9; display: flex; align-items: center; gap: 5px; } .venue-icon { width: 14px; height: 14px; } .card-back-title { font-size: 1.4rem; font-weight: 800; margin-bottom: 1rem; } .event-details { margin-bottom: 1.5rem; font-size: 0.9rem; line-height: 1.6; } .ticket-btn { background: var(--accent-color); color: var(--dark-color); border: none; padding: 0.7rem 1.5rem; border-radius: 50px; font-weight: 700; cursor: pointer; transition: all 0.3s ease; transform: scale(1); box-shadow: 0 5px 15px rgba(255, 202, 40, 0.3); } .ticket-btn:hover { transform: scale(1.05); box-shadow: 0 8px 20px rgba(255, 202, 40, 0.4); } .sold-out { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(-25deg); background-color: var(--primary-color); color: white; padding: 0.5rem 2rem; font-weight: 800; font-size: 1.2rem; text-transform: uppercase; z-index: 2; box-shadow: 0 5px 15px rgba(255, 62, 108, 0.5); } .featured-badge { position: absolute; top: 15px; right: 15px; background: var(--secondary-color); color: white; padding: 0.4rem 0.8rem; border-radius: 50px; font-size: 0.8rem; font-weight: 700; z-index: 2; transform: translateY(-20px); opacity: 0; transition: all 0.4s ease 0.1s; } .event-card:hover .featured-badge { transform: translateY(0); opacity: 1; } .price-tag { position: absolute; bottom: 15px; right: 15px; background: rgba(255, 255, 255, 0.9); color: var(--dark-color); padding: 0.3rem 0.6rem; border-radius: 4px; font-weight: 700; z-index: 1; transform: translateX(20px); opacity: 0; transition: all 0.4s ease 0.2s; } .event-card:hover .price-tag { transform: translateX(0); opacity: 1; } .loading-shimmer { position: relative; overflow: hidden; background: #333; } .loading-shimmer::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transform: translateX(-100%); animation: shimmer 1.5s infinite; } @keyframes shimmer { 100% { transform: translateX(100%); } } .category-label { display: inline-block; margin-right: 0.5rem; background: rgba(255, 255, 255, 0.2); padding: 0.2rem 0.5rem; border-radius: 4px; font-size: 0.8rem; margin-bottom: 0.5rem; } .ticket-tier { display: flex; justify-content: space-between; width: 100%; margin-bottom: 0.5rem; font-size: 0.85rem; } .ribbon { position: absolute; top: 0; right: 0; width: 150px; height: 150px; overflow: hidden; z-index: 1; } .ribbon-content { position: absolute; display: block; width: 225px; padding: 0.5rem 0; background-color: var(--primary-color); color: white; text-align: center; font-size: 0.8rem; font-weight: bold; transform: rotate(45deg); right: -25%; top: 20%; box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); } @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } } .pulse { animation: pulse 2s infinite; } @media (max-width: 768px) { .event-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 1rem; } h1 { font-size: 2rem; } .event-card { height: 250px; } } @media (max-width: 480px) { .event-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); } h1 { font-size: 1.8rem; } .subtitle { font-size: 0.9rem; } .filter-tabs { gap: 0.3rem; } .filter-tab { padding: 0.4rem 0.8rem; font-size: 0.8rem; } } .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .modal.active { opacity: 1; pointer-events: all; } .modal-content { background: var(--dark-color); max-width: 500px; width: 90%; border-radius: 15px; padding: 2rem; box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3); position: relative; transform: translateY(50px); opacity: 0; transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .modal.active .modal-content { transform: translateY(0); opacity: 1; } .close-modal { position: absolute; top: 1rem; right: 1rem; background: none; border: none; color: var(--light-color); font-size: 1.5rem; cursor: pointer; transition: transform 0.3s ease; } .close-modal:hover { transform: rotate(90deg); } .modal-title { font-size: 1.8rem; margin-bottom: 1rem; background: linear-gradient(45deg, var(--primary-color), var(--accent-color)); -webkit-background-clip: text; background-clip: text; color: transparent; } .modal-details { margin-bottom: 1.5rem; } .modal-details p { margin-bottom: 0.5rem; line-height: 1.6; } .modal-actions { display: flex; gap: 1rem; } .modal-btn { flex: 1; padding: 0.8rem; border: none; border-radius: 8px; font-weight: 700; cursor: pointer; transition: all 0.3s ease; } .primary-btn { background: var(--primary-color); color: white; } .secondary-btn { background: rgba(255, 255, 255, 0.1); color: var(--light-color); } .modal-btn:hover { transform: translateY(-3px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); } </style> </head> <body> <div class="container"> <header> <h1>LIVE PULSE</h1> <p class="subtitle">Discover the hottest events and concerts happening in your city. From underground indie shows to arena-filling spectacles.</p> </header> <div class="filter-tabs"> <button class="filter-tab active">All Events</button> <button class="filter-tab">Music</button> <button class="filter-tab">Art & Theater</button> <button class="filter-tab">Comedy</button> <button class="filter-tab">This Weekend</button> </div> <div class="event-grid"> <!-- Event 1 --> <div class="event-card" data-category="music"> <div class="card-front"> <img src="https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Electric Skyline Festival" class="thumb-image"> <div class="date-badge">APR 15-17</div> <div class="featured-badge">HOT TICKET</div> <div class="price-tag">$89+</div> <div class="event-info"> <h3 class="event-title">Electric Skyline Festival</h3> <p class="event-venue"> <svg class="venue-icon" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path> </svg> Riverside Arena </p> </div> </div> <div class="card-back"> <h3 class="card-back-title">Electric Skyline Festival</h3> <p class="event-details"> <span class="category-label">EDM</span> <span class="category-label">3-Day Event</span> <br> The city's biggest electronic music festival returns with headliners from around the globe. Featuring immersive art installations and five stages. </p> <div class="ticket-tier"> <span>General Admission</span> <span>$89</span> </div> <div class="ticket-tier"> <span>VIP Experience</span> <span>$199</span> </div> <button class="ticket-btn pulse">Get Tickets</button> </div> </div> <!-- Event 2 --> <div class="event-card" data-category="music"> <div class="card-front"> <img src="https://images.unsplash.com/photo-1499364615650-ec38552f4f34?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Lunar Symphony" class="thumb-image"> <div class="date-badge">MAY 12</div> <div class="price-tag">$45</div> <div class="event-info"> <h3 class="event-title">Lunar Symphony</h3> <p class="event-venue"> <svg class="venue-icon" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path> </svg> Grand Concert Hall </p> </div> </div> <div class="card-back"> <h3 class="card-back-title">Lunar Symphony</h3> <p class="event-details"> <span class="category-label">Classical</span> <span class="category-label">Evening</span> <br> Experience Debussy's "Clair de Lune" and other celestial-inspired compositions performed by the City Philharmonic under a projection-mapped night sky. </p> <div class="ticket-tier"> <span>Orchestra Seating</span> <span>$65</span> </div> <div class="ticket-tier"> <span>Balcony</span> <span>$45</span> </div> <button class="ticket-btn">Get Tickets</button> </div> </div> <!-- Event 3 --> <div class="event-card" data-category="comedy"> <div class="card-front"> <img src="https://images.unsplash.com/photo-1527224538127-2104bb71c51b?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Laugh Factory: Comedy Showcase" class="thumb-image"> <div class="date-badge">APR 22</div> <div class="price-tag">$30</div> <div class="event-info"> <h3 class="event-title">Laugh Factory: Comedy Showcase</h3> <p class="event-venue"> <svg class="venue-icon" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path> </svg> Downtown Comedy Club </p> </div> </div> <div class="card-back"> <h3 class="card-back-title">Laugh Factory: Comedy Showcase</h3> <p class="event-details"> <span class="category-label">Stand-up</span> <span class="category-label">21+</span> <br> Five of the funniest up-and-coming comics take the stage for a night of unfiltered comedy. Hosted by local favorite Jamie Larson. </p> <div class="ticket-tier"> <span>General Admission</span> <span>$30</span> </div> <div class="ticket-tier"> <span>Front Row + Meet & Greet</span> <span>$55</span> </div> <button class="ticket-btn">Get Tickets</button> </div> </div> <!-- Event 4 --> <div class="event-card" data-category="art"> <div class="card-front"> <img src="https://images.unsplash.com/photo-1492684223066-81342ee5ff30?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Digital Dreams: Art Exhibition" class="thumb-image"> <div class="date-badge">JUN 5-30</div> <div class="price-tag">$15</div> <div class="event-info"> <h3 class="event-title">Digital Dreams: Art Exhibition</h3> <p class="event-venue"> <svg class="venue-icon" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path> </svg> Contemporary Art Museum </p> </div> </div> <div class="card-back"> <h3 class="card-back-title">Digital Dreams: Art Exhibition</h3> <p class="event-details"> <span class="category-label">Interactive</span> <span class="category-label">Modern Art</span> <br> Explore the intersection of technology and art at this groundbreaking exhibition featuring interactive installations, VR experiences, and digital paintings. </p> <div class="ticket-tier"> <span>Day Pass</span> <span>$15</span> </div> <div class="ticket-tier"> <span>Season Pass</span> <span>$40</span> </div> <button class="ticket-btn">Get Tickets</button> </div> </div> <!-- Event 5 --> <div class="event-card" data-category="music"> <div class="card-front"> <img src="https://images.unsplash.com/photo-1501386761578-eac5c94b800a?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Neon Nights: 80s Tribute" class="thumb-image"> <div class="date-badge">APR 28</div> <div class="price-tag">$25</div> <div class="event-info"> <h3 class="event-title">Neon Nights: 80s Tribute</h3> <p class="event-venue"> <svg class="venue-icon" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path> </svg> Retro Lounge </p> </div> </div> <div class="card-back"> <h3 class="card-back-title">Neon Nights: 80s Tribute</h3> <p class="event-details"> <span class="category-label">Throwback</span> <span class="category-label">Live Music</span> <br> Break out your legwarmers and hairspray! "The Synthetics" perform faithful renditions of your favorite 80s hits at this all-night dance party. </p> <div class="ticket-tier"> <span>General Admission</span> <span>$25</span> </div> <div class="ticket-tier"> <span>VIP (includes 2 drinks)</span> <span>$45</span> </div> <button class="ticket-btn">Get Tickets</button> </div> </div> <!-- Event 6 --> <div class="event-card" data-category="theater"> <div class="card-front"> <img src="https://images.unsplash.com/photo-1503095396549-807759245b35?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80" alt="Hamlet: Reimagined" class="thumb-image"> <div class="date-badge">MAY 19-21</div> <div class="price-tag">$35+</div> <div class="sold-out">SOLD OUT</div> <div class="event-info"> <h3 class="event-title">Hamlet: Reimagined</h3> <p class="event-venue"> <svg class="venue-icon" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path> </svg> Civic Theater </p> </div> </div> <div class="card-back"> <h3 class="card-back-title">Hamlet: Reimagined</h3> <p class="event-details"> <span class="category-label">Theater</span> <span class="category-label">Drama</span> <br> This bold reinterpretation sets Shakespeare's classic in a dystopian near-future, with stunning visuals and a contemporary electronic score. </p> <div class="ticket-tier"> <span>Standard Seating</span> <span>$35</span> </div> <div class="ticket-tier"> <span>Premium + Program</span> <span>$55</span> </div> <button class="ticket-btn" disabled style="opacity: 0.6; cursor: not-allowed; box-shadow: none;">Sold Out</button> </div> </div> </div> </div> <div class="modal" id="eventModal"> <div class="modal-content"> <button class="close-modal">×</button> <h2 class="modal-title">Event Details</h2> <div class="modal-details"> <p><strong>Event:</strong> <span id="modalEventName"></span></p> <p><strong>Date:</strong> <span id="modalEventDate"></span></p> <p><strong>Venue:</strong> <span id="modalEventVenue"></span></p> <p><strong>Description:</strong> <span id="modalEventDesc"></span></p> </div> <div class="modal-actions"> <button class="modal-btn secondary-btn">Add to Calendar</button> <button class="modal-btn primary-btn">Purchase Tickets</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Filter functionality const filterTabs = document.querySelectorAll('.filter-tab'); const eventCards = document.querySelectorAll('.event-card'); filterTabs.forEach(tab => { tab.addEventListener('click', function() { // Remove active class from all tabs filterTabs.forEach(t => t.classList.remove('active')); // Add active class to clicked tab this.classList.add('active'); // Get filter category const filterCategory = this.textContent.toLowerCase(); // Filter events eventCards.forEach(card => { if (filterCategory === 'all events') { card.style.display = 'block'; // Add entrance animation setTimeout(() => { card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100); } else if (filterCategory === 'this weekend') { // For demo purposes, showing only first 3 events for "This Weekend" const index = Array.from(eventCards).indexOf(card); if (index < 3) { card.style.display = 'block'; setTimeout(() => { card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100 * index); } else { card.style.display = 'none'; } } else if (card.dataset.category && card.dataset.category.includes(filterCategory.split(' ')[0])) { card.style.display = 'block'; setTimeout(() => { card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100); } else { card.style.display = 'none'; } }); }); }); // Ticket button functionality const ticketButtons = document.querySelectorAll('.ticket-btn'); const modal = document.getElementById('eventModal'); const closeModal = document.querySelector('.close-modal'); ticketButtons.forEach(button => { if (!button.disabled) { button.addEventListener('click', function(e) { e.stopPropagation(); // Get event details from parent event card const card = this.closest('.event-card'); const eventName = card.querySelector('.card-back-title').textContent; const eventDate = card.querySelector('.date-badge').textContent; const eventVenue = card.querySelector('.event-venue').textContent.trim(); const eventDesc = card.querySelector('.event-details').textContent.trim(); // Populate modal with event details document.getElementById('modalEventName').textContent = eventName; document.getElementById('modalEventDate').textContent = eventDate; document.getElementById('modalEventVenue').textContent = eventVenue; document.getElementById('modalEventDesc').textContent = eventDesc; // Show modal modal.classList.add('active'); }); } }); // Close modal on button click closeModal.addEventListener('click', function() { modal.classList.remove('active'); }); // Close modal on outside click window.addEventListener('click', function(e) { if (e.target === modal) { modal.classList.remove('active'); } }); // Card hover effect for better mobile experience eventCards.forEach(card => { card.addEventListener('click', function() { // Toggle the hover effect for mobile devices if (window.innerWidth < 768) { this.classList.toggle('touch-hover'); if (this.classList.contains('touch-hover')) { const frontCard = this.querySelector('.card-front'); const backCard = this.querySelector('.card-back'); frontCard.style.transform = 'rotateY(180deg)'; backCard.style.transform = 'rotateY(0deg)'; } else { const frontCard = this.querySelector('.card-front'); const backCard = this.querySelector('.card-back'); frontCard.style.transform = 'rotateY(0deg)'; backCard.style.transform = 'rotateY(180deg)'; } } }); }); // Prevent ticket button click from triggering card click on mobile document.querySelectorAll('.card-back').forEach(back => { back.addEventListener('click', function(e) { if (window.innerWidth < 768) { e.stopPropagation(); } }); }); // Add automatic filter animation effect on load setTimeout(() => { filterTabs[0].click(); }, 500); }); </script> </body> </html>