Filters are essential tools in web development, allowing developers to manipulate and display data dynamically. They enhance user experience by providing customized views and streamlined interactions.
In this article, we will explore 10 filter examples that can elevate your web projects, showcasing their versatility and practical applications.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Subframe's drag-and-drop interface and intuitive, responsive canvas make it effortless to design pixel-perfect filters. Loved by designers and developers alike, it ensures stunning UI every time.
Start for free and elevate your web projects with Subframe 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 transform your web projects? With Subframe, you can design pixel-perfect UIs, including filters, in minutes. Our drag-and-drop editor ensures efficiency and stunning results every time.
Don't wait—start for free and begin creating immediately. Elevate your designs with Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>The Chronicle - News Filter</title> <style> :root { --primary: #1A1A1A; --secondary: #8B0000; --accent: #F5F5DC; --light: #F9F9F9; --gray: #6B6B6B; --transition: 0.3s ease-in-out; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Georgia', serif; } body { background-color: var(--light); color: var(--primary); width: 100%; height: 100%; overflow-x: hidden; padding: 1.5rem; max-width: 700px; margin: 0 auto; } .container { display: flex; flex-direction: column; height: 100%; max-height: 700px; } header { display: flex; flex-direction: column; border-bottom: 2px solid var(--primary); margin-bottom: 1rem; } .site-title { font-family: 'Times New Roman', serif; font-size: 2.5rem; font-weight: 900; letter-spacing: -1px; text-align: center; margin-bottom: 0.5rem; position: relative; } .site-title::after { content: "Est. 2023"; position: absolute; bottom: -5px; right: 0; font-size: 0.6rem; font-style: italic; font-weight: normal; color: var(--gray); } .filter-section { display: flex; flex-direction: column; margin-bottom: 1rem; background-color: var(--accent); padding: 1rem; border-radius: 4px; position: relative; overflow: hidden; } .filter-section::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 4px; background: var(--secondary); } .filter-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem; } .filter-title { font-size: 1.2rem; font-weight: bold; } .filter-reset { background: transparent; border: none; color: var(--secondary); font-size: 0.9rem; cursor: pointer; font-family: 'Helvetica', sans-serif; transition: var(--transition); font-weight: bold; } .filter-reset:hover { text-decoration: underline; } .filter-group { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 0.75rem; } .filter-group-title { font-family: 'Helvetica', sans-serif; font-size: 0.8rem; font-weight: bold; color: var(--gray); margin-bottom: 0.25rem; width: 100%; } .filter-btn { padding: 0.4rem 0.8rem; background-color: transparent; border: 1px solid var(--primary); border-radius: 50px; cursor: pointer; font-family: 'Helvetica', sans-serif; font-size: 0.85rem; transition: var(--transition); } .filter-btn:hover { background-color: var(--primary); color: var(--light); } .filter-btn.active { background-color: var(--secondary); color: var(--light); border-color: var(--secondary); font-weight: bold; } .filter-info { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem 0; font-family: 'Helvetica', sans-serif; } .filter-count { font-size: 0.85rem; color: var(--gray); } .sort-control { display: flex; align-items: center; gap: 0.5rem; } .sort-label { font-size: 0.85rem; color: var(--gray); } .sort-select { padding: 0.25rem 0.5rem; border: 1px solid var(--gray); border-radius: 4px; background-color: var(--light); font-size: 0.85rem; font-family: 'Helvetica', sans-serif; } .news-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; overflow-y: auto; height: 100%; padding-right: 0.25rem; } .article { background-color: var(--light); border: 1px solid #e0e0e0; border-radius: 4px; overflow: hidden; transition: transform 0.3s ease, box-shadow 0.3s ease; opacity: 0; transform: translateY(20px); animation: fadeIn 0.6s forwards; position: relative; } .article:hover { transform: translateY(-5px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } @keyframes fadeIn { to { opacity: 1; transform: translateY(0); } } .article-category { position: absolute; top: 10px; right: 10px; background-color: var(--secondary); color: var(--light); padding: 0.2rem 0.6rem; border-radius: 50px; font-size: 0.75rem; font-family: 'Helvetica', sans-serif; font-weight: bold; z-index: 1; } .article-image { width: 100%; height: 150px; object-fit: cover; transition: var(--transition); } .article:hover .article-image { transform: scale(1.05); } .article-content { padding: 1rem; } .article-date { font-family: 'Helvetica', sans-serif; font-size: 0.75rem; color: var(--gray); display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; } .article-popularity { display: flex; align-items: center; gap: 0.25rem; } .popularity-dot { width: 6px; height: 6px; border-radius: 50%; background-color: #ddd; } .popularity-dot.filled { background-color: var(--secondary); } .article-title { font-size: 1.1rem; margin-bottom: 0.5rem; line-height: 1.4; } .article-excerpt { font-size: 0.9rem; color: var(--gray); line-height: 1.4; margin-bottom: 0.75rem; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } .read-more { font-family: 'Helvetica', sans-serif; color: var(--secondary); font-size: 0.85rem; font-weight: bold; cursor: pointer; display: inline-block; position: relative; } .read-more::after { content: ''; position: absolute; width: 100%; height: 1px; bottom: -2px; left: 0; background-color: var(--secondary); transform: scaleX(0); transform-origin: bottom right; transition: transform 0.3s ease; } .read-more:hover::after { transform: scaleX(1); transform-origin: bottom left; } .no-articles { grid-column: 1 / -1; padding: 2rem; text-align: center; border: 1px dashed var(--gray); border-radius: 4px; } .no-articles h3 { margin-bottom: 0.5rem; color: var(--secondary); } .no-articles p { color: var(--gray); font-family: 'Helvetica', sans-serif; } /* Custom scrollbar */ .news-grid::-webkit-scrollbar { width: 5px; } .news-grid::-webkit-scrollbar-track { background: #f1f1f1; } .news-grid::-webkit-scrollbar-thumb { background: var(--gray); border-radius: 10px; } .news-grid::-webkit-scrollbar-thumb:hover { background: var(--secondary); } /* Animation for filter updates */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.03); } 100% { transform: scale(1); } } .pulse { animation: pulse 0.5s ease-in-out; } /* Media Queries */ @media (max-width: 700px) { .news-grid { grid-template-columns: 1fr; } .site-title { font-size: 2rem; } .filter-group { gap: 0.5rem; } .filter-btn { padding: 0.3rem 0.6rem; font-size: 0.8rem; } } @media (max-width: 400px) { body { padding: 1rem; } .filter-info { flex-direction: column; align-items: flex-start; gap: 0.5rem; } .sort-control { width: 100%; } } </style> </head> <body> <div class="container"> <header> <h1 class="site-title">The Chronicle</h1> </header> <section class="filter-section"> <div class="filter-header"> <h2 class="filter-title">Filter Articles</h2> <button class="filter-reset" id="reset-filters">Reset Filters</button> </div> <div class="filter-group"> <p class="filter-group-title">Categories</p> <button class="filter-btn active" data-filter="category" data-value="all">All</button> <button class="filter-btn" data-filter="category" data-value="politics">Politics</button> <button class="filter-btn" data-filter="category" data-value="technology">Technology</button> <button class="filter-btn" data-filter="category" data-value="science">Science</button> <button class="filter-btn" data-filter="category" data-value="culture">Culture</button> <button class="filter-btn" data-filter="category" data-value="economy">Economy</button> </div> <div class="filter-group"> <p class="filter-group-title">Time Period</p> <button class="filter-btn active" data-filter="date" data-value="all">All Time</button> <button class="filter-btn" data-filter="date" data-value="today">Today</button> <button class="filter-btn" data-filter="date" data-value="week">This Week</button> <button class="filter-btn" data-filter="date" data-value="month">This Month</button> </div> <div class="filter-group"> <p class="filter-group-title">Popularity</p> <button class="filter-btn active" data-filter="popularity" data-value="all">All</button> <button class="filter-btn" data-filter="popularity" data-value="trending">Trending</button> <button class="filter-btn" data-filter="popularity" data-value="popular">Most Popular</button> </div> <div class="filter-info"> <p class="filter-count" id="article-count">Showing <span>12</span> articles</p> <div class="sort-control"> <label for="sort-by" class="sort-label">Sort by:</label> <select id="sort-by" class="sort-select"> <option value="newest">Newest First</option> <option value="oldest">Oldest First</option> <option value="popular">Most Popular</option> </select> </div> </div> </section> <main class="news-grid" id="news-grid"> <!-- Articles will be generated by JavaScript --> </main> </div> <script> document.addEventListener('DOMContentLoaded', function() { // News articles data const articles = [ { id: 1, title: "Senate Passes Landmark Climate Bill After Marathon Session", excerpt: "The bill introduces unprecedented measures to combat climate change, with billions allocated for renewable energy infrastructure.", category: "politics", image: "https://source.unsplash.com/random/600x400?politics,climate", date: new Date(2023, 8, 28), popularity: 5 }, { id: 2, title: "Scientists Discover Potential Breakthrough in Cancer Treatment", excerpt: "Researchers have identified a novel protein that could revolutionize how we treat aggressive forms of breast cancer.", category: "science", image: "https://source.unsplash.com/random/600x400?science,laboratory", date: new Date(2023, 8, 30), popularity: 4 }, { id: 3, title: "Global Tech Giant Unveils Revolutionary AI Assistant", excerpt: "The new AI system can understand and respond to complex human emotions, marking a significant leap in artificial intelligence development.", category: "technology", image: "https://source.unsplash.com/random/600x400?technology,ai", date: new Date(2023, 9, 1), popularity: 5 }, { id: 4, title: "Historic Art Collection Returns to National Museum", excerpt: "After decades abroad, the renowned Renaissance collection returns home, featuring newly restored masterpieces never before seen by the public.", category: "culture", image: "https://source.unsplash.com/random/600x400?art,museum", date: new Date(2023, 8, 15), popularity: 3 }, { id: 5, title: "Central Bank Signals Interest Rate Relief Amid Economic Concerns", excerpt: "Policy makers hint at potential rate cuts as inflation shows signs of cooling and employment numbers stabilize.", category: "economy", image: "https://source.unsplash.com/random/600x400?economy,finance", date: new Date(2023, 9, 2), popularity: 4 }, { id: 6, title: "New Constitutional Amendment Proposed to Protect Digital Privacy", excerpt: "Bipartisan group of legislators introduces sweeping reforms aimed at preventing government surveillance of citizens' online activities.", category: "politics", image: "https://source.unsplash.com/random/600x400?privacy,government", date: new Date(2023, 8, 20), popularity: 3 }, { id: 7, title: "Quantum Computing Milestone: 1000 Qubit Processor Developed", excerpt: "Tech researchers have created the most powerful quantum computer to date, potentially solving problems impossible for conventional machines.", category: "technology", image: "https://source.unsplash.com/random/600x400?quantum,computing", date: new Date(2023, 8, 25), popularity: 4 }, { id: 8, title: "Unprecedented Arctic Ice Recovery Puzzles Climate Scientists", excerpt: "This year's surprising ice formation challenges predictions and prompts researchers to revisit climate models.", category: "science", image: "https://source.unsplash.com/random/600x400?arctic,ice", date: new Date(2023, 9, 3), popularity: 5 }, { id: 9, title: "Global Supply Chain Recovers as Port Congestion Eases", excerpt: "After two years of disruption, shipping routes normalize, bringing potential relief to consumer goods pricing and availability.", category: "economy", image: "https://source.unsplash.com/random/600x400?shipping,port", date: new Date(2023, 8, 18), popularity: 2 }, { id: 10, title: "Revolutionary Film Technique Transforms Independent Cinema", excerpt: "The award-winning approach combines traditional methods with digital innovation, allowing filmmakers to achieve studio-quality results on minimal budgets.", category: "culture", image: "https://source.unsplash.com/random/600x400?film,cinema", date: new Date(2023, 9, 4), popularity: 3 }, { id: 11, title: "Cryptocurrency Regulation Framework Released by Treasury Department", excerpt: "The long-awaited guidelines provide clarity for investors while establishing consumer protections in the volatile digital currency space.", category: "economy", image: "https://source.unsplash.com/random/600x400?cryptocurrency,bitcoin", date: new Date(2023, 9, 5), popularity: 4 }, { id: 12, title: "Archeologists Uncover Ancient City Beneath Mediterranean Sea", excerpt: "The remarkably preserved underwater discovery could rewrite our understanding of early Mediterranean civilizations and trade networks.", category: "science", image: "https://source.unsplash.com/random/600x400?archeology,underwater", date: new Date(2023, 8, 10), popularity: 4 } ]; // Filter state let filters = { category: 'all', date: 'all', popularity: 'all', sort: 'newest' }; // DOM elements const newsGrid = document.getElementById('news-grid'); const articleCount = document.getElementById('article-count').querySelector('span'); const sortSelect = document.getElementById('sort-by'); const resetButton = document.getElementById('reset-filters'); const filterButtons = document.querySelectorAll('.filter-btn'); // Initialize the page renderArticles(); // Event listeners filterButtons.forEach(button => { button.addEventListener('click', function() { const filterType = this.dataset.filter; const filterValue = this.dataset.value; // Update active buttons document.querySelectorAll(`.filter-btn[data-filter="${filterType}"]`).forEach(btn => { btn.classList.remove('active'); }); this.classList.add('active'); // Update filters filters[filterType] = filterValue; // Render filtered articles newsGrid.classList.add('pulse'); setTimeout(() => { newsGrid.classList.remove('pulse'); }, 500); renderArticles(); }); }); sortSelect.addEventListener('change', function() { filters.sort = this.value; renderArticles(); }); resetButton.addEventListener('click', function() { // Reset all filters to default filters = { category: 'all', date: 'all', popularity: 'all', sort: 'newest' }; // Reset active buttons filterButtons.forEach(button => { if (button.dataset.value === 'all') { button.classList.add('active'); } else { button.classList.remove('active'); } }); // Reset sort select sortSelect.value = 'newest'; // Render all articles renderArticles(); // Add animation newsGrid.classList.add('pulse'); setTimeout(() => { newsGrid.classList.remove('pulse'); }, 500); }); // Function to render articles based on filters function renderArticles() { // Clear the grid newsGrid.innerHTML = ''; // Filter articles let filteredArticles = [...articles]; // Apply category filter if (filters.category !== 'all') { filteredArticles = filteredArticles.filter(article => article.category === filters.category); } // Apply date filter if (filters.date !== 'all') { const now = new Date(); if (filters.date === 'today') { filteredArticles = filteredArticles.filter(article => article.date.toDateString() === now.toDateString() ); } else if (filters.date === 'week') { const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); filteredArticles = filteredArticles.filter(article => article.date >= weekAgo ); } else if (filters.date === 'month') { const monthAgo = new Date(now.getFullYear(), now.getMonth() - 1, now.getDate()); filteredArticles = filteredArticles.filter(article => article.date >= monthAgo ); } } // Apply popularity filter if (filters.popularity !== 'all') { if (filters.popularity === 'trending') { filteredArticles = filteredArticles.filter(article => article.popularity >= 3 ); } else if (filters.popularity === 'popular') { filteredArticles = filteredArticles.filter(article => article.popularity >= 4 ); } } // Sort articles if (filters.sort === 'newest') { filteredArticles.sort((a, b) => b.date - a.date); } else if (filters.sort === 'oldest') { filteredArticles.sort((a, b) => a.date - b.date); } else if (filters.sort === 'popular') { filteredArticles.sort((a, b) => b.popularity - a.popularity); } // Update article count articleCount.textContent = filteredArticles.length; // Render articles if (filteredArticles.length === 0) { const noArticles = document.createElement('div'); noArticles.className = 'no-articles'; noArticles.innerHTML = ` <h3>No articles found</h3> <p>Try adjusting your filters to see more results.</p> `; newsGrid.appendChild(noArticles); } else { filteredArticles.forEach((article, index) => { const articleEl = document.createElement('article'); articleEl.className = 'article'; articleEl.style.animationDelay = `${index * 0.1}s`; const formatDate = (date) => { const options = { month: 'short', day: 'numeric', year: 'numeric' }; return date.toLocaleDateString('en-US', options); }; articleEl.innerHTML = ` <span class="article-category">${article.category.charAt(0).toUpperCase() + article.category.slice(1)}</span> <img src="${article.image}" alt="${article.title}" class="article-image"> <div class="article-content"> <div class="article-date"> ${formatDate(article.date)} <div class="article-popularity"> ${getPopularityDots(article.popularity)} </div> </div> <h3 class="article-title">${article.title}</h3> <p class="article-excerpt">${article.excerpt}</p> <span class="read-more">Read Full Story</span> </div> `; newsGrid.appendChild(articleEl); }); } } // Helper function to generate popularity dots function getPopularityDots(popularity) { let dots = ''; for (let i = 1; i <= 5; i++) { if (i <= popularity) { dots += '<span class="popularity-dot filled"></span>'; } else { dots += '<span class="popularity-dot"></span>'; } } return dots; } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Advanced Analytics Dashboard Filter</title> <style> :root { --bg-primary: #121212; --bg-secondary: #1e1e1e; --bg-tertiary: #2d2d2d; --text-primary: #f0f0f0; --text-secondary: #b0b0b0; --accent-primary: #00e5ff; --accent-secondary: #7b61ff; --accent-tertiary: #ff4081; --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif; } body { background-color: var(--bg-primary); color: var(--text-primary); display: flex; flex-direction: column; width: 100%; height: 100vh; overflow: hidden; } .dashboard-container { display: flex; flex-direction: column; width: 100%; height: 100%; max-width: 700px; max-height: 700px; margin: 0 auto; padding: 20px; gap: 20px; overflow: hidden; } .dashboard-header { display: flex; justify-content: space-between; align-items: center; } .dashboard-title { font-size: 1.5rem; font-weight: 700; display: flex; align-items: center; } .pulse-icon { width: 10px; height: 10px; background-color: var(--accent-primary); border-radius: 50%; margin-right: 10px; animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(0, 229, 255, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(0, 229, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(0, 229, 255, 0); } } .filter-panel { background-color: var(--bg-secondary); border-radius: 10px; padding: 20px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); display: flex; flex-direction: column; gap: 20px; transition: var(--transition); position: relative; overflow: hidden; } .filter-panel::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 2px; background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary), var(--accent-tertiary)); animation: gradientMove 3s linear infinite; } @keyframes gradientMove { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } .filter-section { display: flex; flex-direction: column; gap: 12px; } .filter-section-title { font-size: 0.9rem; font-weight: 600; color: var(--text-secondary); display: flex; align-items: center; gap: 6px; } .filter-section-title svg { width: 16px; height: 16px; } .date-range-selector { display: flex; gap: 10px; flex-wrap: wrap; } .date-option { padding: 8px 14px; background-color: var(--bg-tertiary); border: 1px solid #3a3a3a; border-radius: 6px; color: var(--text-secondary); font-size: 0.85rem; cursor: pointer; transition: var(--transition); user-select: none; } .date-option:hover { background-color: #353535; transform: translateY(-2px); } .date-option.active { background-color: rgba(0, 229, 255, 0.15); color: var(--accent-primary); border-color: var(--accent-primary); box-shadow: 0 0 10px rgba(0, 229, 255, 0.3); } .custom-date-range { display: flex; gap: 10px; margin-top: 10px; transition: var(--transition); max-height: 0; overflow: hidden; opacity: 0; } .custom-date-range.active { max-height: 50px; opacity: 1; margin-top: 10px; } .date-input { background-color: var(--bg-tertiary); border: 1px solid #3a3a3a; border-radius: 6px; color: var(--text-primary); font-size: 0.85rem; padding: 8px; flex: 1; } .date-input::-webkit-calendar-picker-indicator { filter: invert(1); } .region-selector { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; } .region-option { display: flex; align-items: center; gap: 8px; padding: 10px; background-color: var(--bg-tertiary); border: 1px solid #3a3a3a; border-radius: 6px; color: var(--text-secondary); font-size: 0.85rem; cursor: pointer; transition: var(--transition); user-select: none; } .region-option:hover { background-color: #353535; transform: translateY(-2px); } .region-option.active { background-color: rgba(123, 97, 255, 0.15); color: var(--accent-secondary); border-color: var(--accent-secondary); box-shadow: 0 0 10px rgba(123, 97, 255, 0.3); } .region-checkbox { width: 16px; height: 16px; border: 1px solid #5a5a5a; border-radius: 4px; display: flex; justify-content: center; align-items: center; transition: var(--transition); position: relative; } .region-option.active .region-checkbox { border-color: var(--accent-secondary); background-color: var(--accent-secondary); } .region-checkbox::after { content: ""; width: 8px; height: 8px; background-color: var(--text-primary); border-radius: 2px; opacity: 0; transition: var(--transition); } .region-option.active .region-checkbox::after { opacity: 1; } .metrics-selector { display: flex; flex-wrap: wrap; gap: 10px; } .metric-option { flex: 1; min-width: 100px; padding: 10px 15px; background-color: var(--bg-tertiary); border: 1px solid #3a3a3a; border-radius: 6px; color: var(--text-secondary); font-size: 0.85rem; cursor: pointer; transition: var(--transition); user-select: none; text-align: center; position: relative; overflow: hidden; } .metric-option::before { content: ""; position: absolute; left: 0; bottom: 0; width: 0; height: 2px; background-color: var(--accent-tertiary); transition: var(--transition); } .metric-option:hover::before { width: 30%; } .metric-option.active::before { width: 100%; } .metric-option:hover { background-color: #353535; transform: translateY(-2px); } .metric-option.active { background-color: rgba(255, 64, 129, 0.15); color: var(--accent-tertiary); border-color: var(--accent-tertiary); box-shadow: 0 0 10px rgba(255, 64, 129, 0.3); } .filter-actions { display: flex; justify-content: space-between; margin-top: 10px; } .filter-apply { padding: 10px 20px; background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary)); border: none; border-radius: 6px; color: var(--text-primary); font-weight: 600; cursor: pointer; transition: var(--transition); display: flex; align-items: center; gap: 8px; } .filter-apply:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 229, 255, 0.3); } .filter-apply:active { transform: translateY(1px); } .filter-reset { padding: 10px 20px; background-color: transparent; border: 1px solid #3a3a3a; border-radius: 6px; color: var(--text-secondary); cursor: pointer; transition: var(--transition); } .filter-reset:hover { background-color: rgba(255, 255, 255, 0.05); color: var(--text-primary); } .data-preview { flex: 1; background-color: var(--bg-secondary); border-radius: 10px; padding: 20px; display: flex; flex-direction: column; gap: 15px; overflow: hidden; position: relative; } .data-preview-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 10px; border-bottom: 1px solid #3a3a3a; } .active-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; } .filter-tag { display: flex; align-items: center; gap: 5px; padding: 5px 10px; border-radius: 20px; font-size: 0.8rem; animation: fadeIn 0.3s ease-in-out; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .filter-tag.date { background-color: rgba(0, 229, 255, 0.15); color: var(--accent-primary); border: 1px solid var(--accent-primary); } .filter-tag.region { background-color: rgba(123, 97, 255, 0.15); color: var(--accent-secondary); border: 1px solid var(--accent-secondary); } .filter-tag.metric { background-color: rgba(255, 64, 129, 0.15); color: var(--accent-tertiary); border: 1px solid var(--accent-tertiary); } .remove-tag { cursor: pointer; display: flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.1); transition: var(--transition); } .remove-tag:hover { background-color: rgba(255, 255, 255, 0.2); } .data-visualization { flex: 1; overflow: hidden; display: flex; align-items: center; justify-content: center; position: relative; } .data-placeholder { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 15px; color: var(--text-secondary); text-align: center; } .data-placeholder svg { width: 50px; height: 50px; opacity: 0.7; } .chart-container { position: relative; width: 100%; height: 100%; display: none; } .chart-container.active { display: block; animation: fadeIn 0.5s ease-in-out; } .chart { width: 100%; height: 100%; position: relative; } .chart-bar { position: absolute; bottom: 0; width: 20px; background: linear-gradient(to top, var(--accent-primary), var(--accent-secondary)); border-radius: 5px 5px 0 0; transition: height 1s cubic-bezier(0.34, 1.56, 0.64, 1); } .chart-label { position: absolute; bottom: -25px; font-size: 10px; color: var(--text-secondary); transform: translateX(-50%); text-align: center; } .chart-value { position: absolute; top: -25px; font-size: 10px; color: var(--text-primary); transform: translateX(-50%); background-color: var(--bg-tertiary); padding: 2px 6px; border-radius: 10px; opacity: 0; transition: opacity 0.3s ease; } .chart-bar:hover .chart-value { opacity: 1; } .loading-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(18, 18, 18, 0.8); display: flex; align-items: center; justify-content: center; z-index: 10; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .loading-overlay.active { opacity: 1; pointer-events: all; } .loading-spinner { width: 40px; height: 40px; border: 3px solid transparent; border-top-color: var(--accent-primary); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @media (max-width: 600px) { .dashboard-container { padding: 15px; gap: 15px; } .dashboard-title { font-size: 1.2rem; } .filter-panel { padding: 15px; } .date-range-selector { overflow-x: auto; padding-bottom: 5px; scroll-snap-type: x mandatory; } .date-option { scroll-snap-align: start; flex: 0 0 auto; } .region-selector { grid-template-columns: repeat(auto-fill, minmax(95px, 1fr)); } } </style> </head> <body> <div class="dashboard-container"> <div class="dashboard-header"> <div class="dashboard-title"> <div class="pulse-icon"></div> QuantumViz Analytics </div> </div> <div class="filter-panel"> <div class="filter-section"> <div class="filter-section-title"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> </svg> Time Period </div> <div class="date-range-selector"> <div class="date-option" data-value="today">Today</div> <div class="date-option" data-value="week">Last 7 days</div> <div class="date-option" data-value="month">Last 30 days</div> <div class="date-option" data-value="quarter">Last quarter</div> <div class="date-option" data-value="year">Last year</div> <div class="date-option" data-value="custom">Custom range</div> </div> <div class="custom-date-range"> <input type="date" class="date-input" id="date-from" placeholder="From"> <input type="date" class="date-input" id="date-to" placeholder="To"> </div> </div> <div class="filter-section"> <div class="filter-section-title"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg> Regions </div> <div class="region-selector"> <div class="region-option" data-value="north-america"> <div class="region-checkbox"></div> North America </div> <div class="region-option" data-value="europe"> <div class="region-checkbox"></div> Europe </div> <div class="region-option" data-value="asia-pacific"> <div class="region-checkbox"></div> Asia Pacific </div> <div class="region-option" data-value="latin-america"> <div class="region-checkbox"></div> Latin America </div> <div class="region-option" data-value="middle-east"> <div class="region-checkbox"></div> Middle East </div> <div class="region-option" data-value="africa"> <div class="region-checkbox"></div> Africa </div> </div> </div> <div class="filter-section"> <div class="filter-section-title"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" /> </svg> Key Metrics </div> <div class="metrics-selector"> <div class="metric-option" data-value="revenue">Revenue</div> <div class="metric-option" data-value="conversion">Conversion Rate</div> <div class="metric-option" data-value="users">Active Users</div> <div class="metric-option" data-value="sessions">Sessions</div> <div class="metric-option" data-value="bounces">Bounce Rate</div> </div> </div> <div class="filter-actions"> <button class="filter-reset">Reset</button> <button class="filter-apply"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm3.5 7.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5z"/> </svg> Apply Filters </button> </div> </div> <div class="data-preview"> <div class="data-preview-header"> <h3>Data Visualization</h3> </div> <div class="active-filters"></div> <div class="data-visualization"> <div class="data-placeholder"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" /> </svg> <p>Apply filters to visualize your data</p> </div> <div class="chart-container"> <div class="chart"></div> </div> <div class="loading-overlay"> <div class="loading-spinner"></div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Elements const dateOptions = document.querySelectorAll('.date-option'); const customDateRange = document.querySelector('.custom-date-range'); const regionOptions = document.querySelectorAll('.region-option'); const metricOptions = document.querySelectorAll('.metric-option'); const applyButton = document.querySelector('.filter-apply'); const resetButton = document.querySelector('.filter-reset'); const activeFilters = document.querySelector('.active-filters'); const dataPlaceholder = document.querySelector('.data-placeholder'); const chartContainer = document.querySelector('.chart-container'); const chart = document.querySelector('.chart'); const loadingOverlay = document.querySelector('.loading-overlay'); // State let selectedDate = null; let selectedRegions = []; let selectedMetrics = []; let customDateFrom = ''; let customDateTo = ''; // Date range selection dateOptions.forEach(option => { option.addEventListener('click', function() { dateOptions.forEach(opt => opt.classList.remove('active')); this.classList.add('active'); selectedDate = this.dataset.value; if (selectedDate === 'custom') { customDateRange.classList.add('active'); } else { customDateRange.classList.remove('active'); } }); }); // Custom date range inputs const dateFromInput = document.getElementById('date-from'); const dateToInput = document.getElementById('date-to'); dateFromInput.addEventListener('change', function() { customDateFrom = this.value; }); dateToInput.addEventListener('change', function() { customDateTo = this.value; }); // Region selection regionOptions.forEach(option => { option.addEventListener('click', function() { this.classList.toggle('active'); const region = this.dataset.value; if (this.classList.contains('active')) { selectedRegions.push(region); } else { selectedRegions = selectedRegions.filter(r => r !== region); } }); }); // Metrics selection metricOptions.forEach(option => { option.addEventListener('click', function() { this.classList.toggle('active'); const metric = this.dataset.value; if (this.classList.contains('active')) { selectedMetrics.push(metric); } else { selectedMetrics = selectedMetrics.filter(m => m !== metric); } }); }); // Apply filters applyButton.addEventListener('click', function() { if (!selectedDate) { alert('Please select a date range'); return; } if (selectedDate === 'custom' && (!customDateFrom || !customDateTo)) { alert('Please select both start and end dates for custom range'); return; } if (selectedRegions.length === 0) { alert('Please select at least one region'); return; } if (selectedMetrics.length === 0) { alert('Please select at least one metric'); return; } // Show loading state loadingOverlay.classList.add('active'); // Simulate API call with timeout setTimeout(() => { updateFilters(); generateChart(); loadingOverlay.classList.remove('active'); }, 1000); }); // Reset filters resetButton.addEventListener('click', function() { // Reset date selection dateOptions.forEach(opt => opt.classList.remove('active')); selectedDate = null; customDateRange.classList.remove('active'); dateFromInput.value = ''; dateToInput.value = ''; customDateFrom = ''; customDateTo = ''; // Reset region selection regionOptions.forEach(opt => opt.classList.remove('active')); selectedRegions = []; // Reset metrics selection metricOptions.forEach(opt => opt.classList.remove('active')); selectedMetrics = []; // Clear active filters activeFilters.innerHTML = ''; // Hide chart dataPlaceholder.style.display = 'flex'; chartContainer.classList.remove('active'); }); // Update active filters display function updateFilters() { activeFilters.innerHTML = ''; // Date filter tag let dateText = ''; switch(selectedDate) { case 'today': dateText = 'Today'; break; case 'week': dateText = 'Last 7 days'; break; case 'month': dateText = 'Last 30 days'; break; case 'quarter': dateText = 'Last quarter'; break; case 'year': dateText = 'Last year'; break; case 'custom': dateText = `${formatDate(customDateFrom)} - ${formatDate(customDateTo)}`; break; } const dateTag = document.createElement('div'); dateTag.className = 'filter-tag date'; dateTag.innerHTML = ` <span>Time: ${dateText}</span> <div class="remove-tag" data-type="date">×</div> `; activeFilters.appendChild(dateTag); // Region filter tags selectedRegions.forEach(region => { let regionText = ''; switch(region) { case 'north-america': regionText = 'North America'; break; case 'europe': regionText = 'Europe'; break; case 'asia-pacific': regionText = 'Asia Pacific'; break; case 'latin-america': regionText = 'Latin America'; break; case 'middle-east': regionText = 'Middle East'; break; case 'africa': regionText = 'Africa'; break; } const regionTag = document.createElement('div'); regionTag.className = 'filter-tag region'; regionTag.innerHTML = ` <span>${regionText}</span> <div class="remove-tag" data-type="region" data-value="${region}">×</div> `; activeFilters.appendChild(regionTag); }); // Metric filter tags selectedMetrics.forEach(metric => { let metricText = ''; switch(metric) { case 'revenue': metricText = 'Revenue'; break; case 'conversion': metricText = 'Conversion Rate'; break; case 'users': metricText = 'Active Users'; break; case 'sessions': metricText = 'Sessions'; break; case 'bounces': metricText = 'Bounce Rate'; break; } const metricTag = document.createElement('div'); metricTag.className = 'filter-tag metric'; metricTag.innerHTML = ` <span>${metricText}</span> <div class="remove-tag" data-type="metric" data-value="${metric}">×</div> `; activeFilters.appendChild(metricTag); }); // Add event listeners to remove tags document.querySelectorAll('.remove-tag').forEach(tag => { tag.addEventListener('click', function() { const type = this.dataset.type; const value = this.dataset.value; if (type === 'date') { dateOptions.forEach(opt => opt.classList.remove('active')); selectedDate = null; customDateRange.classList.remove('active'); dateFromInput.value = ''; dateToInput.value = ''; customDateFrom = ''; customDateTo = ''; } else if (type === 'region') { selectedRegions = selectedRegions.filter(r => r !== value); document.querySelector(`.region-option[data-value="${value}"]`).classList.remove('active'); } else if (type === 'metric') { selectedMetrics = selectedMetrics.filter(m => m !== value); document.querySelector(`.metric-option[data-value="${value}"]`).classList.remove('active'); } this.parentElement.remove(); // Update chart if we still have valid filters if (selectedDate && selectedRegions.length > 0 && selectedMetrics.length > 0) { generateChart(); } else { // Hide chart dataPlaceholder.style.display = 'flex'; chartContainer.classList.remove('active'); } }); }); } // Format date for display function formatDate(dateString) { const date = new Date(dateString); return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`; } // Generate chart data function generateChart() { dataPlaceholder.style.display = 'none'; chartContainer.classList.add('active'); chart.innerHTML = ''; // Simulate data generation const data = []; const numPoints = 12; for (let i = 0; i < numPoints; i++) { const value = Math.floor(Math.random() * 80) + 20; // Random value between 20 and 100 data.push({ label: `P${i+1}`, value: value }); } // Calculate bar width based on number of data points const barWidth = (chart.offsetWidth / numPoints) * 0.6; const spacing = (chart.offsetWidth - (barWidth * numPoints)) / (numPoints + 1); // Create chart bars data.forEach((item, index) => { const barHeight = (item.value / 100) * chart.offsetHeight; const leftPosition = spacing + (index * (barWidth + spacing)); const bar = document.createElement('div'); bar.className = 'chart-bar'; bar.style.left = `${leftPosition}px`; bar.style.width = `${barWidth}px`; bar.style.height = '0'; const label = document.createElement('div'); label.className = 'chart-label'; label.textContent = item.label; label.style.left = `${leftPosition + (barWidth / 2)}px`; const value = document.createElement('div'); value.className = 'chart-value'; value.textContent = item.value; value.style.left = `${leftPosition + (barWidth / 2)}px`; bar.appendChild(value); chart.appendChild(bar); chart.appendChild(label); // Animate height after a short delay setTimeout(() => { bar.style.height = `${barHeight}px`; }, 50 * index); }); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Travel Booking Filter</title> <style> :root { --primary: #ff6b00; --secondary: #0081ff; --accent: #ffcc00; --light: #f8f9fa; --dark: #343a40; --success: #20c997; --error: #ff3860; --white: #ffffff; --shadow: 0 4px 12px rgba(0, 0, 0, 0.1); --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif; } body { background-color: var(--light); color: var(--dark); overflow-x: hidden; height: 100%; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; } .container { width: 100%; max-width: 680px; padding: 15px; margin: 0 auto; position: relative; } .adventure-header { text-align: center; margin-bottom: 20px; position: relative; } .adventure-header h1 { font-size: 30px; font-weight: 700; margin-bottom: 5px; color: var(--dark); position: relative; display: inline-block; } .adventure-header h1::after { content: ''; position: absolute; width: 50%; height: 4px; background: var(--primary); bottom: -5px; left: 25%; border-radius: 2px; transform-origin: center; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scaleX(1); opacity: 1; } 50% { transform: scaleX(1.2); opacity: 0.7; } 100% { transform: scaleX(1); opacity: 1; } } .adventure-header p { font-size: 16px; font-weight: 400; color: #666; max-width: 500px; margin: 0 auto; margin-top: 15px; } .tab-container { display: flex; justify-content: space-between; margin-bottom: 20px; border-radius: 10px; overflow: hidden; box-shadow: var(--shadow); border: 2px solid var(--light); background: var(--white); } .tab { flex: 1; padding: 15px 0; text-align: center; cursor: pointer; transition: var(--transition); position: relative; border: none; background: var(--white); color: var(--dark); font-weight: 600; font-size: 14px; z-index: 1; } .tab:hover { color: var(--primary); } .tab.active { color: var(--white); } .tab.active::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--primary); z-index: -1; animation: slideIn 0.3s ease forwards; } @keyframes slideIn { from { transform: translateY(100%); } to { transform: translateY(0); } } .tab-content { display: none; background: var(--white); padding: 25px; border-radius: 12px; box-shadow: var(--shadow); margin-bottom: 20px; animation: fadeIn 0.5s ease; position: relative; overflow: hidden; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .tab-content.active { display: block; } .decoration-dots { position: absolute; top: 10px; right: 10px; display: flex; } .dot { width: 8px; height: 8px; border-radius: 50%; margin: 0 3px; } .dot:nth-child(1) { background-color: var(--primary); } .dot:nth-child(2) { background-color: var(--secondary); } .dot:nth-child(3) { background-color: var(--accent); } .form-group { margin-bottom: 20px; } .form-row { display: flex; flex-wrap: wrap; margin: -8px; } .form-col { flex: 1; padding: 8px; min-width: 200px; } .form-col-small { flex: 0 0 auto; width: calc(50% - 16px); padding: 8px; } label { display: block; margin-bottom: 8px; font-size: 14px; font-weight: 600; color: var(--dark); } input, select { width: 100%; padding: 12px 15px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 14px; transition: var(--transition); outline: none; background: var(--white); } input:focus, select:focus { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(255, 107, 0, 0.2); } .date-input { position: relative; } .date-input input { padding-right: 40px; } .date-input::after { content: '📅'; position: absolute; right: 15px; top: 50%; transform: translateY(-50%); font-size: 16px; pointer-events: none; } .select-wrapper { position: relative; } .select-wrapper::after { content: '▼'; position: absolute; right: 15px; top: 50%; transform: translateY(-50%); color: var(--primary); font-size: 12px; pointer-events: none; } .btn { background: var(--primary); color: var(--white); border: none; padding: 14px 30px; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: var(--transition); text-align: center; width: 100%; box-shadow: 0 4px 10px rgba(255, 107, 0, 0.3); position: relative; overflow: hidden; } .btn:hover { background: #ff8124; transform: translateY(-2px); box-shadow: 0 6px 15px rgba(255, 107, 0, 0.4); } .btn:active { transform: translateY(0); box-shadow: 0 2px 5px rgba(255, 107, 0, 0.4); } .btn::after { content: ''; position: absolute; top: 50%; left: 50%; width: 5px; height: 5px; background: rgba(255, 255, 255, 0.5); opacity: 0; border-radius: 100%; transform: scale(1, 1) translate(-50%, -50%); transform-origin: 50% 50%; } .btn:focus:not(:active)::after { animation: ripple 1s ease-out; } @keyframes ripple { 0% { transform: scale(0, 0); opacity: 1; } 20% { transform: scale(25, 25); opacity: 0.8; } 100% { transform: scale(50, 50); opacity: 0; } } .popular-filters { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 25px; } .popular-filter-item { padding: 8px 15px; background: rgba(255, 107, 0, 0.1); border-radius: 20px; font-size: 13px; cursor: pointer; transition: var(--transition); border: 1px solid transparent; color: var(--primary); display: flex; align-items: center; } .popular-filter-item:hover { background: rgba(255, 107, 0, 0.2); transform: translateY(-2px); } .popular-filter-item.active { background: var(--primary); color: var(--white); } .popular-filter-item svg { margin-right: 5px; width: 14px; height: 14px; } .results-summary { background: linear-gradient(135deg, var(--primary), var(--secondary)); color: var(--white); padding: 15px 20px; border-radius: 10px; margin-top: 25px; box-shadow: var(--shadow); display: flex; justify-content: space-between; align-items: center; font-weight: 600; transition: var(--transition); transform: translateY(0); opacity: 0; pointer-events: none; } .results-summary.show { opacity: 1; transform: translateY(0); pointer-events: all; } .result-count { font-size: 18px; } .view-results { background: rgba(255, 255, 255, 0.2); padding: 8px 15px; border-radius: 5px; cursor: pointer; transition: var(--transition); } .view-results:hover { background: rgba(255, 255, 255, 0.3); } .badge { position: absolute; top: -10px; right: -10px; background: var(--accent); color: var(--dark); font-size: 12px; font-weight: 700; padding: 4px 8px; border-radius: 12px; z-index: 2; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); animation: bounce 2s infinite; } @keyframes bounce { 0%, 20%, 50%, 80%, 100% { transform: translateY(0); } 40% { transform: translateY(-5px); } 60% { transform: translateY(-3px); } } .pattern-bg { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; opacity: 0.05; background-image: radial-gradient(var(--primary) 1px, transparent 1px), radial-gradient(var(--primary) 1px, transparent 1px); background-size: 20px 20px; background-position: 0 0, 10px 10px; } .toggle-advanced { text-align: center; margin-top: 15px; margin-bottom: -5px; font-size: 14px; cursor: pointer; color: var(--primary); font-weight: 600; display: flex; align-items: center; justify-content: center; } .toggle-advanced svg { transition: var(--transition); margin-right: 5px; } .toggle-advanced.open svg { transform: rotate(180deg); } .advanced-options { overflow: hidden; max-height: 0; transition: max-height 0.5s ease; } .advanced-options.open { max-height: 500px; } @media (max-width: 600px) { .tab { font-size: 12px; padding: 12px 0; } .form-col, .form-col-small { min-width: 100%; width: 100%; } .adventure-header h1 { font-size: 24px; } .adventure-header p { font-size: 14px; } .popular-filters { justify-content: center; } .results-summary { flex-direction: column; text-align: center; gap: 10px; } .tab-content { padding: 20px 15px; } } /* Range Slider Styling */ .range-slider { width: 100%; margin: 10px 0; } .range-slider-inner { position: relative; height: 6px; background: #e0e0e0; border-radius: 3px; margin: 0 10px; } .range-slider-progress { position: absolute; height: 100%; background: var(--primary); border-radius: 3px; } .range-slider-thumb { width: 20px; height: 20px; background: var(--white); border: 2px solid var(--primary); border-radius: 50%; position: absolute; top: 50%; transform: translate(-50%, -50%); cursor: pointer; box-shadow: 0 1px 3px rgba(0,0,0,0.2); transition: var(--transition); } .range-slider-thumb:hover { transform: translate(-50%, -50%) scale(1.1); box-shadow: 0 2px 6px rgba(0,0,0,0.25); } .range-slider-thumb.active { transform: translate(-50%, -50%) scale(1.15); box-shadow: 0 3px 8px rgba(0,0,0,0.3); } .range-labels { display: flex; justify-content: space-between; margin-top: 10px; padding: 0 10px; font-size: 12px; color: #666; } .checkbox-container { display: flex; align-items: center; margin-bottom: 8px; cursor: pointer; } .checkbox-custom { width: 18px; height: 18px; border: 2px solid #e0e0e0; border-radius: 4px; display: inline-flex; align-items: center; justify-content: center; margin-right: 8px; transition: var(--transition); position: relative; } .checkbox-container input { position: absolute; opacity: 0; cursor: pointer; height: 0; width: 0; } .checkbox-container input:checked ~ .checkbox-custom { background-color: var(--primary); border-color: var(--primary); } .checkbox-custom::after { content: ''; position: absolute; display: none; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } .checkbox-container input:checked ~ .checkbox-custom::after { display: block; } .time-selector { display: flex; align-items: center; gap: 10px; } .time-selector span { color: #888; font-size: 14px; } .discount-tag { position: absolute; top: 15px; right: -30px; background: var(--accent); color: var(--dark); transform: rotate(45deg); padding: 5px 30px; font-size: 12px; font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.1); z-index: 1; } </style> </head> <body> <div class="container"> <div class="adventure-header"> <h1>Wanderlust Explorer</h1> <p>Unlock your next adventure with our advanced filters designed to find your perfect travel match.</p> </div> <div class="tab-container"> <button class="tab active" data-tab="flights"> <i class="fas fa-plane"></i> Flights </button> <button class="tab" data-tab="hotels"> <i class="fas fa-hotel"></i> Accommodations </button> <button class="tab" data-tab="cars"> <i class="fas fa-car"></i> Car Rentals </button> </div> <!-- Flights Tab --> <div id="flights" class="tab-content active"> <div class="decoration-dots"> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div> <div class="pattern-bg"></div> <span class="badge">20% OFF</span> <div class="form-group"> <div class="form-row"> <div class="form-col"> <label for="flight-from">From</label> <div class="select-wrapper"> <select id="flight-from"> <option value="">Select departure city</option> <option value="NYC">New York (NYC)</option> <option value="LAX">Los Angeles (LAX)</option> <option value="SFO">San Francisco (SFO)</option> <option value="MIA">Miami (MIA)</option> <option value="LHR">London (LHR)</option> <option value="CDG">Paris (CDG)</option> <option value="NRT">Tokyo (NRT)</option> </select> </div> </div> <div class="form-col"> <label for="flight-to">To</label> <div class="select-wrapper"> <select id="flight-to"> <option value="">Select destination city</option> <option value="NYC">New York (NYC)</option> <option value="LAX">Los Angeles (LAX)</option> <option value="SFO">San Francisco (SFO)</option> <option value="MIA">Miami (MIA)</option> <option value="LHR">London (LHR)</option> <option value="CDG">Paris (CDG)</option> <option value="NRT">Tokyo (NRT)</option> <option value="BKK">Bangkok (BKK)</option> <option value="SYD">Sydney (SYD)</option> </select> </div> </div> </div> </div> <div class="form-group"> <div class="form-row"> <div class="form-col-small"> <label for="flight-depart">Departure Date</label> <div class="date-input"> <input type="text" id="flight-depart" placeholder="MM/DD/YYYY" onfocus="(this.type='date')" onblur="if(!this.value)this.type='text'"> </div> </div> <div class="form-col-small"> <label for="flight-return">Return Date</label> <div class="date-input"> <input type="text" id="flight-return" placeholder="MM/DD/YYYY" onfocus="(this.type='date')" onblur="if(!this.value)this.type='text'"> </div> </div> </div> </div> <div class="form-group"> <div class="form-row"> <div class="form-col"> <label for="flight-passengers">Passengers</label> <div class="select-wrapper"> <select id="flight-passengers"> <option value="1">1 Adult</option> <option value="2">2 Adults</option> <option value="3">3 Adults</option> <option value="4">4 Adults</option> <option value="5">5 Adults</option> <option value="6">6 Adults</option> </select> </div> </div> <div class="form-col"> <label for="flight-class">Class</label> <div class="select-wrapper"> <select id="flight-class"> <option value="economy">Economy</option> <option value="premium">Premium Economy</option> <option value="business">Business</option> <option value="first">First Class</option> </select> </div> </div> </div> </div> <div class="toggle-advanced"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7 10L12 15L17 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Advanced Options </div> <div class="advanced-options"> <div class="form-group"> <label>Price Range</label> <div class="range-slider"> <div class="range-slider-inner"> <div class="range-slider-progress"></div> <div class="range-slider-thumb" id="minThumb" data-value="0"></div> <div class="range-slider-thumb" id="maxThumb" data-value="100"></div> </div> <div class="range-labels"> <span>$0</span> <span>$2000+</span> </div> </div> </div> <div class="form-group"> <label>Airlines</label> <div class="form-row"> <div class="form-col-small"> <label class="checkbox-container"> <input type="checkbox" name="airlines" value="delta"> <span class="checkbox-custom"></span> Delta Air Lines </label> <label class="checkbox-container"> <input type="checkbox" name="airlines" value="united"> <span class="checkbox-custom"></span> United Airlines </label> </div> <div class="form-col-small"> <label class="checkbox-container"> <input type="checkbox" name="airlines" value="american"> <span class="checkbox-custom"></span> American Airlines </label> <label class="checkbox-container"> <input type="checkbox" name="airlines" value="southwest"> <span class="checkbox-custom"></span> Southwest </label> </div> </div> </div> <div class="form-group"> <label>Time of Day (Outbound)</label> <div class="time-selector"> <label class="checkbox-container"> <input type="checkbox" name="time-outbound" value="morning"> <span class="checkbox-custom"></span> Morning </label> <span>|</span> <label class="checkbox-container"> <input type="checkbox" name="time-outbound" value="afternoon"> <span class="checkbox-custom"></span> Afternoon </label> <span>|</span> <label class="checkbox-container"> <input type="checkbox" name="time-outbound" value="evening"> <span class="checkbox-custom"></span> Evening </label> </div> </div> </div> <button class="btn search-btn" id="flight-search-btn">Find My Adventure</button> <div class="popular-filters"> <div class="popular-filter-item" data-value="nonstop"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M22 16.92v3a1 1 0 0 1-1.09 1 11 11 0 0 1-8.71-4.3A17.73 17.73 0 0 1 8 10.5a17.72 17.72 0 0 1-4.3-8.75A1 1 0 0 1 4.77 1h3a1 1 0 0 1 1 .86c.06.61.28 1.69.5 2.39a1 1 0 0 1-.14.85l-1.37 1.37a16.29 16.29 0 0 0 4.98 4.98l1.34-1.35a1 1 0 0 1 .86-.14c.7.22 1.78.44 2.39.5a1 1 0 0 1 .86 1v3Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Non-stop only </div> <div class="popular-filter-item" data-value="luggage"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M6 8v12m12-12v12M4 8h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2Zm4-4v4m8-4v4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Includes baggage </div> <div class="popular-filter-item" data-value="morning"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="12" cy="12" r="5" stroke="currentColor" stroke-width="2"/> <path d="M12 1v2m0 18v2M4.22 4.22l1.42 1.42m12.72 12.72 1.42 1.42M1 12h2m18 0h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> </svg> Morning departures </div> <div class="popular-filter-item" data-value="price"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Best price </div> </div> </div> <!-- Hotels Tab --> <div id="hotels" class="tab-content"> <div class="decoration-dots"> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div> <div class="pattern-bg"></div> <div class="discount-tag">15% OFF</div> <div class="form-group"> <label for="hotel-destination">Destination</label> <div class="select-wrapper"> <select id="hotel-destination"> <option value="">Where are you going?</option> <option value="NYC">New York, USA</option> <option value="PAR">Paris, France</option> <option value="TYO">Tokyo, Japan</option> <option value="ROM">Rome, Italy</option> <option value="LON">London, UK</option> <option value="BKK">Bangkok, Thailand</option> <option value="SYD">Sydney, Australia</option> <option value="CAI">Cairo, Egypt</option> </select> </div> </div> <div class="form-group"> <div class="form-row"> <div class="form-col-small"> <label for="hotel-checkin">Check-in Date</label> <div class="date-input"> <input type="text" id="hotel-checkin" placeholder="MM/DD/YYYY" onfocus="(this.type='date')" onblur="if(!this.value)this.type='text'"> </div> </div> <div class="form-col-small"> <label for="hotel-checkout">Check-out Date</label> <div class="date-input"> <input type="text" id="hotel-checkout" placeholder="MM/DD/YYYY" onfocus="(this.type='date')" onblur="if(!this.value)this.type='text'"> </div> </div> </div> </div> <div class="form-group"> <div class="form-row"> <div class="form-col"> <label for="hotel-guests">Guests</label> <div class="select-wrapper"> <select id="hotel-guests"> <option value="1">1 Guest</option> <option value="2">2 Guests</option> <option value="3">3 Guests</option> <option value="4">4 Guests</option> <option value="5">5+ Guests</option> </select> </div> </div> <div class="form-col"> <label for="hotel-rooms">Rooms</label> <div class="select-wrapper"> <select id="hotel-rooms"> <option value="1">1 Room</option> <option value="2">2 Rooms</option> <option value="3">3 Rooms</option> <option value="4">4+ Rooms</option> </select> </div> </div> </div> </div> <div class="toggle-advanced"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7 10L12 15L17 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Advanced Options </div> <div class="advanced-options"> <div class="form-group"> <label>Price Range per Night</label> <div class="range-slider"> <div class="range-slider-inner"> <div class="range-slider-progress"></div> <div class="range-slider-thumb" id="hotelMinThumb" data-value="0"></div> <div class="range-slider-thumb" id="hotelMaxThumb" data-value="100"></div> </div> <div class="range-labels"> <span>$0</span> <span>$1000+</span> </div> </div> </div> <div class="form-group"> <label>Hotel Star Rating</label> <div class="form-row"> <div class="form-col"> <label class="checkbox-container"> <input type="checkbox" name="stars" value="5"> <span class="checkbox-custom"></span> 5 Stars - Luxury </label> <label class="checkbox-container"> <input type="checkbox" name="stars" value="4"> <span class="checkbox-custom"></span> 4 Stars - Excellent </label> <label class="checkbox-container"> <input type="checkbox" name="stars" value="3"> <span class="checkbox-custom"></span> 3 Stars - Good </label> </div> </div> </div> <div class="form-group"> <label>Amenities</label> <div class="form-row"> <div class="form-col-small"> <label class="checkbox-container"> <input type="checkbox" name="amenities" value="pool"> <span class="checkbox-custom"></span> Swimming Pool </label> <label class="checkbox-container"> <input type="checkbox" name="amenities" value="wifi"> <span class="checkbox-custom"></span> Free WiFi </label> </div> <div class="form-col-small"> <label class="checkbox-container"> <input type="checkbox" name="amenities" value="breakfast"> <span class="checkbox-custom"></span> Breakfast Included </label> <label class="checkbox-container"> <input type="checkbox" name="amenities" value="parking"> <span class="checkbox-custom"></span> Free Parking </label> </div> </div> </div> </div> <button class="btn search-btn" id="hotel-search-btn">Find Perfect Stay</button> <div class="popular-filters"> <div class="popular-filter-item" data-value="breakfast"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M18 8h1a4 4 0 0 1 0 8h-1M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8zm4-3v3m4-3v3m4-3v3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Breakfast included </div> <div class="popular-filter-item" data-value="pool"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M2 12h20M2 12c0 5.523 4.477 10 10 10s10-4.477 10-10M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10m-10-2v4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Pool access </div> <div class="popular-filter-item" data-value="price"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Best value
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Real Estate Filter</title> <style> @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Montserrat', sans-serif; } :root { --primary: #3a86ff; --secondary: #ff006e; --accent: #8338ec; --light: #f8f9fa; --dark: #212529; --success: #38b000; --border-radius: 12px; --shadow: 0 4px 20px rgba(0, 0, 0, 0.08); --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } body { background-color: var(--light); color: var(--dark); padding: 20px; max-width: 700px; margin: 0 auto; height: 100vh; overflow-x: hidden; } .container { display: flex; flex-direction: column; height: 100%; max-height: 700px; } header { text-align: center; margin-bottom: 20px; } h1 { font-size: 28px; font-weight: 700; margin-bottom: 10px; background: linear-gradient(90deg, var(--primary), var(--accent)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; position: relative; } h1::after { content: ""; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); width: 100px; height: 3px; background: linear-gradient(90deg, var(--primary), var(--accent)); border-radius: 3px; } .subheading { font-size: 14px; color: #666; max-width: 80%; margin: 0 auto; } .filter-section { background-color: white; border-radius: var(--border-radius); box-shadow: var(--shadow); padding: 25px; margin-bottom: 20px; transition: var(--transition); position: relative; overflow: hidden; } .filter-section::before { content: ""; position: absolute; top: 0; left: 0; width: 5px; height: 100%; background: linear-gradient(to bottom, var(--primary), var(--accent)); border-top-left-radius: var(--border-radius); border-bottom-left-radius: var(--border-radius); } .filter-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; } .filter-group { margin-bottom: 20px; } .filter-label { display: block; font-weight: 600; margin-bottom: 10px; color: var(--dark); font-size: 14px; position: relative; padding-left: 20px; } .filter-label::before { content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 10px; height: 10px; background-color: var(--primary); border-radius: 50%; } .price-filter .filter-label::before { background-color: var(--primary); } .bedrooms-filter .filter-label::before { background-color: var(--secondary); } .neighborhood-filter .filter-label::before { background-color: var(--accent); } .property-filter .filter-label::before { background-color: var(--success); } .range-slider { position: relative; height: 5px; background-color: #e9ecef; border-radius: 5px; margin: 30px 0; } .range-slider .track { position: absolute; height: 100%; background: linear-gradient(to right, var(--primary), var(--accent)); border-radius: 5px; } .range-slider input[type="range"] { -webkit-appearance: none; width: 100%; position: absolute; background: transparent; top: -5px; height: 15px; margin: 0; } .range-slider input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 24px; height: 24px; background: white; border: 2px solid var(--primary); border-radius: 50%; cursor: pointer; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); transition: transform 0.2s; } .range-slider input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.1); } .range-values { display: flex; justify-content: space-between; margin-top: 10px; font-size: 14px; color: #6c757d; } .checkbox-group { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; } .checkbox-wrapper { position: relative; padding-left: 30px; cursor: pointer; font-size: 14px; margin-bottom: 10px; transition: var(--transition); display: flex; align-items: center; } .checkbox-wrapper input { position: absolute; opacity: 0; cursor: pointer; height: 0; width: 0; } .checkmark { position: absolute; left: 0; height: 20px; width: 20px; background-color: #f1f3f5; border-radius: 5px; transition: var(--transition); } .neighborhood-filter .checkmark { border: 1px solid var(--accent); } .property-filter .checkmark { border: 1px solid var(--success); } .checkbox-wrapper:hover input ~ .checkmark { background-color: #e9ecef; } .checkbox-wrapper input:checked ~ .checkmark { background-color: var(--accent); } .property-filter .checkbox-wrapper input:checked ~ .checkmark { background-color: var(--success); } .checkmark:after { content: ""; position: absolute; display: none; } .checkbox-wrapper input:checked ~ .checkmark:after { display: block; } .checkbox-wrapper .checkmark:after { left: 7px; top: 3px; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } .bed-buttons { display: flex; gap: 10px; margin-top: 10px; } .bed-button { flex: 1; padding: 10px; background-color: #f1f3f5; border: 1px solid #ced4da; border-radius: 8px; cursor: pointer; text-align: center; transition: var(--transition); font-weight: 500; font-size: 14px; } .bed-button:hover { background-color: #e9ecef; } .bed-button.active { background-color: var(--secondary); color: white; border-color: var(--secondary); transform: scale(1.05); box-shadow: 0 4px 10px rgba(255, 0, 110, 0.2); } .actions { display: flex; justify-content: space-between; margin-top: 15px; gap: 15px; } .btn { flex: 1; padding: 12px 20px; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; transition: var(--transition); text-align: center; font-size: 15px; } .btn-reset { background-color: #f1f3f5; color: #495057; } .btn-reset:hover { background-color: #e9ecef; } .btn-apply { background: linear-gradient(to right, var(--primary), var(--accent)); color: white; position: relative; overflow: hidden; } .btn-apply:hover { transform: translateY(-2px); box-shadow: 0 7px 14px rgba(58, 134, 255, 0.2); } .btn-apply::after { content: ""; position: absolute; top: 50%; left: 50%; width: 5px; height: 5px; background: rgba(255, 255, 255, 0.5); opacity: 0; border-radius: 100%; transform: scale(1, 1) translate(-50%); transform-origin: 50% 50%; } .btn-apply:focus:not(:active)::after { animation: ripple 1s ease-out; } .results-section { background-color: white; border-radius: var(--border-radius); box-shadow: var(--shadow); padding: 25px; flex: 1; overflow-y: auto; transition: var(--transition); position: relative; } .results-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #e9ecef; } .results-count { font-weight: 700; color: var(--primary); } .sort-by { display: flex; align-items: center; gap: 10px; font-size: 14px; } .sort-by select { padding: 8px 12px; border-radius: 6px; border: 1px solid #ced4da; background-color: #f8f9fa; font-size: 14px; cursor: pointer; transition: var(--transition); } .sort-by select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(58, 134, 255, 0.2); } .results-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; animation: fadeIn 0.5s ease-out; } .property-card { border-radius: 12px; overflow: hidden; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); transition: var(--transition); position: relative; background-color: white; } .property-card:hover { transform: translateY(-5px); box-shadow: 0 12px 20px rgba(0, 0, 0, 0.1); } .property-image { height: 150px; background-size: cover; background-position: center; position: relative; } .property-type { position: absolute; top: 10px; left: 10px; background-color: rgba(0, 0, 0, 0.6); color: white; padding: 5px 10px; border-radius: 20px; font-size: 12px; font-weight: 500; } .property-price { position: absolute; bottom: 10px; right: 10px; background: linear-gradient(to right, var(--primary), var(--accent)); color: white; padding: 5px 10px; border-radius: 20px; font-size: 14px; font-weight: 600; } .property-details { padding: 15px; } .property-title { font-weight: 600; font-size: 16px; margin-bottom: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .property-address { color: #6c757d; font-size: 13px; margin-bottom: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .property-features { display: flex; gap: 15px; color: #495057; font-size: 13px; } .feature { display: flex; align-items: center; gap: 5px; } .feature-icon { color: var(--primary); font-size: 14px; } #empty-state { text-align: center; padding: 40px 20px; display: none; } #empty-state img { width: 120px; margin-bottom: 20px; opacity: 0.7; } #empty-state h3 { font-size: 18px; margin-bottom: 10px; color: #495057; } #empty-state p { color: #6c757d; font-size: 14px; max-width: 300px; margin: 0 auto; } .highlight { animation: highlight 2s ease-in-out; } .tooltip { position: absolute; background-color: #212529; color: white; padding: 8px 12px; border-radius: 6px; font-size: 12px; z-index: 100; opacity: 0; pointer-events: none; transition: opacity 0.3s; } .tooltip::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: #212529 transparent transparent transparent; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes highlight { 0% { background-color: rgba(131, 56, 236, 0.1); } 100% { background-color: transparent; } } @keyframes ripple { 0% { transform: scale(0, 0); opacity: 1; } 20% { transform: scale(25, 25); opacity: 1; } 100% { opacity: 0; transform: scale(40, 40); } } @media (max-width: 700px) { .filter-grid { grid-template-columns: 1fr; } .checkbox-group { grid-template-columns: 1fr; } .results-grid { grid-template-columns: 1fr; } .bed-buttons { flex-wrap: wrap; } .bed-button { min-width: 60px; } .subheading { max-width: 95%; } .filter-section, .results-section { padding: 15px; } } /* Custom Scrollbar */ ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } ::-webkit-scrollbar-thumb { background: #c1c1c1; border-radius: 10px; } ::-webkit-scrollbar-thumb:hover { background: #a8a8a8; } /* Toggle filter panel on mobile */ .filter-toggle { display: none; align-items: center; justify-content: center; padding: 10px; background: linear-gradient(to right, var(--primary), var(--accent)); color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; margin-bottom: 15px; } @media (max-width: 700px) { .filter-toggle { display: flex; } .filter-section { max-height: 0; padding: 0 15px; overflow: hidden; transition: max-height 0.5s ease, padding 0.5s ease; } .filter-section.open { max-height: 1000px; padding: 15px; } } </style> </head> <body> <div class="container"> <header> <h1>Prime Property Finder</h1> <p class="subheading">Discover your dream home with our advanced filtering system tailored to your precise needs</p> </header> <button class="filter-toggle" id="filter-toggle"> <span>Show Filters</span> </button> <section class="filter-section" id="filter-section"> <div class="filter-grid"> <div class="filter-group price-filter"> <label class="filter-label">Price Range</label> <div class="range-slider"> <div class="track" id="price-track"></div> <input type="range" id="min-price" min="100000" max="2000000" value="100000" step="50000"> <input type="range" id="max-price" min="100000" max="2000000" value="1500000" step="50000"> </div> <div class="range-values"> <span id="min-price-value">$100,000</span> <span id="max-price-value">$1,500,000</span> </div> </div> <div class="filter-group bedrooms-filter"> <label class="filter-label">Bedrooms</label> <div class="bed-buttons" id="bed-buttons"> <div class="bed-button" data-value="any">Any</div> <div class="bed-button" data-value="1">1+</div> <div class="bed-button" data-value="2">2+</div> <div class="bed-button" data-value="3">3+</div> <div class="bed-button" data-value="4">4+</div> </div> </div> </div> <div class="filter-grid"> <div class="filter-group neighborhood-filter"> <label class="filter-label">Neighborhoods</label> <div class="checkbox-group"> <label class="checkbox-wrapper"> Downtown <input type="checkbox" checked="checked" value="Downtown"> <span class="checkmark"></span> </label> <label class="checkbox-wrapper"> Riverside <input type="checkbox" checked="checked" value="Riverside"> <span class="checkmark"></span> </label> <label class="checkbox-wrapper"> Highland Park <input type="checkbox" checked="checked" value="Highland Park"> <span class="checkmark"></span> </label> <label class="checkbox-wrapper"> Brookside <input type="checkbox" checked="checked" value="Brookside"> <span class="checkmark"></span> </label> <label class="checkbox-wrapper"> Oakwood <input type="checkbox" checked="checked" value="Oakwood"> <span class="checkmark"></span> </label> <label class="checkbox-wrapper"> Pine Hills <input type="checkbox" checked="checked" value="Pine Hills"> <span class="checkmark"></span> </label> </div> </div> <div class="filter-group property-filter"> <label class="filter-label">Property Type</label> <div class="checkbox-group"> <label class="checkbox-wrapper"> Single Family <input type="checkbox" checked="checked" value="Single Family"> <span class="checkmark"></span> </label> <label class="checkbox-wrapper"> Condo <input type="checkbox" checked="checked" value="Condo"> <span class="checkmark"></span> </label> <label class="checkbox-wrapper"> Townhouse <input type="checkbox" checked="checked" value="Townhouse"> <span class="checkmark"></span> </label> <label class="checkbox-wrapper"> Multi-Family <input type="checkbox" checked="checked" value="Multi-Family"> <span class="checkmark"></span> </label> </div> </div> </div> <div class="actions"> <button class="btn btn-reset" id="reset-filters">Reset Filters</button> <button class="btn btn-apply" id="apply-filters">Apply Filters</button> </div> </section> <section class="results-section"> <div class="results-header"> <div class="results-count" id="results-count">24 properties found</div> <div class="sort-by"> <span>Sort by:</span> <select id="sort-select"> <option value="price-asc">Price (Low to High)</option> <option value="price-desc">Price (High to Low)</option> <option value="newest">Newest</option> <option value="bedrooms">Bedrooms</option> </select> </div> </div> <div class="results-grid" id="results-grid"> <!-- Property cards will be dynamically inserted here --> </div> <div id="empty-state"> <img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTEwMCAxODBDMTQ0LjE4MyAxODAgMTgwIDE0NC4xODMgMTgwIDEwMEMxODAgNTUuODE3MyAxNDQuMTgzIDIwIDEwMCAyMEM1NS44MTczIDIwIDIwIDU1LjgxNzMgMjAgMTAwQzIwIDE0NC4xODMgNTUuODE3MyAxODAgMTAwIDE4MFoiIGZpbGw9IiNGMUYzRjUiLz4KICA8cGF0aCBkPSJNNjAgMTIwTDg1IDk1TDExMCAxMjBMMTQwIDkwIiBzdHJva2U9IiM2Qzc1N0QiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CiAgPHBhdGggZD0iTTYwIDcwSDE0MCIgc3Ryb2tlPSIjM0E4NkZGIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik04MCA2MEgxMjAiIHN0cm9rZT0iI0ZGMDA2RSIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNNzAgMTMwSDEzMCIgc3Ryb2tlPSIjODMzOEVDIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik04NSAxNDBIMTE1IiBzdHJva2U9IiMzOEIwMDAiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+Cjwvc3ZnPg==" alt="No results"> <h3>No properties found</h3> <p>Try adjusting your filters to see more properties that match your criteria.</p> </div> </section> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Filter toggle for mobile const filterToggle = document.getElementById('filter-toggle'); const filterSection = document.getElementById('filter-section'); filterToggle.addEventListener('click', function() { filterSection.classList.toggle('open'); filterToggle.querySelector('span').textContent = filterSection.classList.contains('open') ? 'Hide Filters' : 'Show Filters'; }); // Price range slider const minPrice = document.getElementById('min-price'); const maxPrice = document.getElementById('max-price'); const minPriceValue = document.getElementById('min-price-value'); const maxPriceValue = document.getElementById('max-price-value'); const priceTrack = document.getElementById('price-track'); function formatCurrency(value) { return '$' + parseInt(value).toLocaleString(); } function updatePriceTrack() { const min = (minPrice.value - minPrice.min) / (minPrice.max - minPrice.min) * 100; const max = (maxPrice.value - maxPrice.min) / (maxPrice.max - maxPrice.min) * 100; priceTrack.style.left = min + '%'; priceTrack.style.width = (max - min) + '%'; minPriceValue.textContent = formatCurrency(minPrice.value); maxPriceValue.textContent = formatCurrency(maxPrice.value); } minPrice.addEventListener('input', function() { if (parseInt(minPrice.value) > parseInt(maxPrice.value)) { minPrice.value = maxPrice.value; } updatePriceTrack(); }); maxPrice.addEventListener('input', function() { if (parseInt(maxPrice.value) < parseInt(minPrice.value)) { maxPrice.value = minPrice.value; } updatePriceTrack(); }); updatePriceTrack(); // Bedroom selection const bedButtons = document.querySelectorAll('.bed-button'); let selectedBedrooms = 'any'; bedButtons.forEach(button => { button.addEventListener('click', function() { bedButtons.forEach(b => b.classList.remove('active')); this.classList.add('active'); selectedBedrooms = this.getAttribute('data-value'); }); }); // Set default active bed button bedButtons[0].classList.add('active'); // Sample property data const properties = [ { id: 1, title: "Modern Loft with City Views", address: "123 Downtown Ave, Downtown", price: 450000, bedrooms: 1, bathrooms: 1, sqft: 850, type: "Condo", neighborhood: "Downtown", image: "https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NHx8YXBhcnRtZW50fGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60" }, { id: 2, title: "Spacious Family Home", address: "456 Oakwood Blvd, Oakwood", price: 850000, bedrooms: 4, bathrooms: 3, sqft: 2200, type: "Single Family", neighborhood: "Oakwood", image: "https://images.unsplash.com/photo-1570129477492-45c003edd2be?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8aG91c2V8ZW58MHx8MHx8&auto=format&fit=crop&w=500&q=60" }, { id: 3, title: "Riverside Townhouse", address: "789 River Walk, Riverside", price: 575000, bedrooms: 3, bathrooms: 2.5, sqft: 1800, type: "Townhouse", neighborhood: "Riverside", image: "https://images.unsplash.com/photo-1592595896616-c37162298647?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NXx8dG93bmhvdXNlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60" }, { id: 4, title: "Highland Craftsman", address: "101 Park View, Highland Park", price: 1200000, bedrooms: 5, bathrooms: 4, sqft: 3100, type: "Single Family", neighborhood: "Highland Park", image: "https://images.unsplash.com/photo-1513584684374-8bab748fbf90?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTh8fGhvdXNlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60" }, { id: 5, title: "Brookside Bungalow", address: "222 Creek Lane, Brookside", price: 520000, bedrooms: 2, bathrooms: 2, sqft: 1200, type: "Single Family", neighborhood: "Brookside", image: "https://images.unsplash.com/photo-1568605114967-8130f3a36994?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NXx8aG91c2V8ZW58MHx8MHx8&auto=format&fit=crop&w=500&q=60" }, { id: 6, title: "Pine Hills Estate", address: "333 Forest Road, Pine Hills", price: 1800000, bedrooms: 6, bathrooms: 5.5, sqft: 4500, type: "Single Family", neighborhood: "Pine Hills", image: "https://images.unsplash.com/photo-1564013799919-ab600027ffc6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTB8fGhvdXNlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60" }, { id: 7, title: "Downtown Penthouse", address: "444 High Rise Blvd, Downtown", price: 1650000, bedrooms: 3, bathrooms: 3.5, sqft: 2800, type: "Condo", neighborhood: "Downtown", image: "https://images.unsplash.com/photo-1512917774080-9991f1c4c750?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTJ8fGhvdXNlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60" }, { id: 8, title: "Riverside Duplex", address: "555 Marina Way, Riverside", price: 750000, bedrooms: 4, bathrooms: 3, sqft: 2400, type: "Multi-Family", neighborhood: "Riverside", image: "https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTR8fGhvdXNlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60" }, { id: 9, title: "Highland Park Residence", address: "666 Summit Ave, Highland Park", price: 925000, bedrooms: 4, bathrooms: 3, sqft: 2600, type: "Single Family", neighborhood: "Highland Park", image: "https://images.unsplash.com/photo-1583608205776-bfd35f0d9f83?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTF8fGhvdXNlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=500&q=60" }, { id: 10, title: "Brookside Studio", address: "777 Mill St, Brookside", price: 270000, bedrooms: 0, bathrooms: 1, sqft: 550, type: "Condo", neighborhood: "Brookside", image: "https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MjB8fGFwYXJ0bWVudHxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=500&q=60" }, { id: 11, title: "Pine Hills Cabin", address: "888 Timber Lane, Pine Hills", price: 320000, bedrooms: 2, bathrooms: 1, sqft: 900, type: "Single Family", neighborhood: "Pine Hills", image: "https://images.unsplash.com/photo-1587061949462-49b0ebd35b4c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NXx8Y2FiaW58ZW58MHx8MHx8&auto=format&fit=crop&w
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Recipe Filter</title> <style> :root { --primary: #FF6B4A; --secondary: #FFD166; --accent: #06D6A0; --dark: #1A535C; --light: #FEF9EF; --mid: #F3DFC1; --shadow: rgba(0, 0, 0, 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--light); color: var(--dark); width: 100%; height: 100vh; padding: 20px; display: flex; flex-direction: column; overflow-x: hidden; } .container { max-width: 700px; width: 100%; margin: 0 auto; height: 100%; display: flex; flex-direction: column; } header { text-align: center; margin-bottom: 20px; position: relative; } h1 { font-size: 2rem; margin-bottom: 5px; color: var(--dark); position: relative; display: inline-block; } h1::after { content: ""; position: absolute; bottom: -5px; left: 0; width: 100%; height: 8px; background: url("data:image/svg+xml,%3Csvg width='100' height='8' viewBox='0 0 100 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 5.5C20.5 0.5 29.5 7.5 50 5.5C70.5 3.5 80.5 0.5 99 5.5' stroke='%23FF6B4A' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat: repeat-x; background-size: 100px 8px; } .subtitle { color: var(--primary); font-weight: 500; margin-bottom: 20px; } .search-box { display: flex; align-items: center; background-color: white; border-radius: 50px; padding: 10px 20px; margin-bottom: 25px; box-shadow: 0 4px 15px var(--shadow); border: 2px solid transparent; transition: all 0.3s ease; position: relative; } .search-box:focus-within { border-color: var(--primary); transform: translateY(-2px); box-shadow: 0 6px 20px rgba(255, 107, 74, 0.15); } .search-icon { color: var(--primary); margin-right: 10px; font-size: 20px; } .search-input { flex: 1; border: none; outline: none; font-size: 16px; color: var(--dark); background: transparent; } .search-input::placeholder { color: #BBB; } .filter-container { background-color: white; border-radius: 20px; padding: 25px; box-shadow: 0 4px 15px var(--shadow); margin-bottom: 25px; position: relative; overflow: hidden; } .filter-container::before { content: ""; position: absolute; top: 0; right: 0; width: 120px; height: 120px; background: url("data:image/svg+xml,%3Csvg width='120' height='120' viewBox='0 0 120 120' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M120 0C120 66.2741 66.2741 120 0 120L0 0L120 0Z' fill='%23F3DFC1' fill-opacity='0.4'/%3E%3C/svg%3E%0A"); z-index: 0; } .filter-section { margin-bottom: 20px; position: relative; z-index: 1; } .filter-title { font-size: 1rem; margin-bottom: 12px; display: flex; align-items: center; font-weight: 600; color: var(--dark); } .filter-title svg { margin-right: 8px; width: 22px; height: 22px; } .pill-container { display: flex; flex-wrap: wrap; gap: 10px; } .pill { background-color: var(--mid); color: var(--dark); border: none; border-radius: 50px; padding: 8px 15px; font-size: 14px; cursor: pointer; transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); position: relative; overflow: hidden; font-weight: 500; } .pill:hover { transform: translateY(-3px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .pill.active { background-color: var(--primary); color: white; font-weight: 600; } .pill.active::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at center, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0) 70%); transform: scale(0); border-radius: 50%; animation: ripple 0.6s ease-out; } @keyframes ripple { 0% { transform: scale(0); opacity: 1; } 100% { transform: scale(2); opacity: 0; } } .time-slider { width: 100%; margin: 15px 0; } .time-range { -webkit-appearance: none; appearance: none; width: 100%; height: 8px; background: var(--mid); border-radius: 10px; outline: none; } .time-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; background: var(--primary); border-radius: 50%; cursor: pointer; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1); transition: all 0.2s; } .time-range::-webkit-slider-thumb:hover { transform: scale(1.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } .time-range::-moz-range-thumb { width: 24px; height: 24px; background: var(--primary); border-radius: 50%; cursor: pointer; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1); border: none; transition: all 0.2s; } .time-range::-moz-range-thumb:hover { transform: scale(1.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } .time-display { text-align: center; font-weight: 600; color: var(--primary); margin-top: 5px; font-size: 0.9rem; } .checkbox-container { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-top: 10px; } .checkbox-item { display: flex; align-items: center; cursor: pointer; } .checkbox-item input[type="checkbox"] { display: none; } .checkbox-item label { display: flex; align-items: center; font-size: 14px; cursor: pointer; } .checkbox-item .custom-checkbox { width: 20px; height: 20px; border: 2px solid var(--mid); border-radius: 6px; margin-right: 8px; display: flex; align-items: center; justify-content: center; transition: all 0.2s; position: relative; } .checkbox-item input[type="checkbox"]:checked + label .custom-checkbox { background-color: var(--accent); border-color: var(--accent); } .checkbox-item input[type="checkbox"]:checked + label .custom-checkbox::after { content: ""; width: 10px; height: 5px; border-left: 2px solid white; border-bottom: 2px solid white; transform: rotate(-45deg) translate(0, -1px); position: absolute; } .apply-button { background-color: var(--dark); color: white; border: none; border-radius: 50px; padding: 14px 30px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: block; width: 100%; margin-top: 20px; box-shadow: 0 4px 12px rgba(26, 83, 92, 0.3); position: relative; overflow: hidden; } .apply-button::before { content: ""; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: all 0.6s; } .apply-button:hover { transform: translateY(-3px); box-shadow: 0 6px 16px rgba(26, 83, 92, 0.4); } .apply-button:hover::before { left: 100%; } .recipe-results { flex: 1; overflow-y: auto; padding-right: 5px; position: relative; } .recipe-card { background: white; border-radius: 15px; padding: 15px; margin-bottom: 15px; box-shadow: 0 4px 8px var(--shadow); display: flex; transition: all 0.3s ease; position: relative; overflow: hidden; transform: translateY(20px); opacity: 0; animation: fade-in 0.5s forwards; } @keyframes fade-in { to { transform: translateY(0); opacity: 1; } } .recipe-card:hover { transform: translateY(-3px); box-shadow: 0 6px 14px rgba(0, 0, 0, 0.12); } .recipe-img { width: 80px; height: 80px; border-radius: 10px; object-fit: cover; margin-right: 15px; } .recipe-content { flex: 1; } .recipe-title { font-weight: 600; margin-bottom: 5px; color: var(--dark); } .recipe-stats { display: flex; align-items: center; gap: 12px; font-size: 12px; margin-bottom: 8px; } .stat-item { display: flex; align-items: center; color: #666; } .stat-item svg { width: 14px; height: 14px; margin-right: 3px; } .recipe-tags { display: flex; flex-wrap: wrap; gap: 5px; } .recipe-tag { font-size: 11px; padding: 3px 8px; border-radius: 12px; background-color: var(--mid); color: var(--dark); } .no-results { text-align: center; padding: 30px; color: #888; } @media (max-width: 500px) { .checkbox-container { grid-template-columns: 1fr; } .recipe-card { flex-direction: column; } .recipe-img { width: 100%; height: 150px; margin-right: 0; margin-bottom: 15px; } h1 { font-size: 1.6rem; } .filter-title { font-size: 0.9rem; } .pill { font-size: 13px; padding: 6px 12px; } } /* Custom scrollbar */ .recipe-results::-webkit-scrollbar { width: 6px; } .recipe-results::-webkit-scrollbar-track { background: var(--light); border-radius: 10px; } .recipe-results::-webkit-scrollbar-thumb { background: var(--mid); border-radius: 10px; } .recipe-results::-webkit-scrollbar-thumb:hover { background: var(--primary); } /* Ingredient drawer */ .drawer-button { position: absolute; right: 20px; top: 10px; background: var(--primary); color: white; border: none; border-radius: 50px; padding: 8px 15px; font-size: 13px; cursor: pointer; display: flex; align-items: center; gap: 5px; z-index: 10; transition: all 0.3s ease; } .drawer-button:hover { background: #ff5436; } .pantry-drawer { position: fixed; top: 0; right: -350px; width: 350px; height: 100%; background: white; box-shadow: -5px 0 20px rgba(0, 0, 0, 0.15); z-index: 100; padding: 25px; transition: right 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); display: flex; flex-direction: column; } .pantry-drawer.open { right: 0; } .drawer-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .drawer-close { background: none; border: none; font-size: 24px; cursor: pointer; color: var(--dark); transition: all 0.2s; } .drawer-close:hover { color: var(--primary); transform: rotate(90deg); } .ingredient-input-container { display: flex; margin-bottom: 15px; } .ingredient-input { flex: 1; border: 2px solid var(--mid); border-radius: 10px 0 0 10px; padding: 10px 15px; font-size: 14px; outline: none; transition: all 0.3s; } .ingredient-input:focus { border-color: var(--primary); } .add-ingredient-btn { background: var(--primary); color: white; border: none; border-radius: 0 10px 10px 0; padding: 0 15px; cursor: pointer; transition: all 0.2s; } .add-ingredient-btn:hover { background: #ff5436; } .ingredients-list { flex: 1; overflow-y: auto; padding-right: 5px; } .ingredient-item { background: var(--light); border-radius: 8px; padding: 10px 15px; margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center; animation: slide-in 0.3s ease forwards; transform: translateX(-20px); opacity: 0; } @keyframes slide-in { to { transform: translateX(0); opacity: 1; } } .ingredient-item button { background: none; border: none; color: #ff5436; cursor: pointer; font-size: 16px; opacity: 0.7; transition: all 0.2s; } .ingredient-item button:hover { opacity: 1; transform: scale(1.1); } .overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 99; opacity: 0; visibility: hidden; transition: all 0.3s; backdrop-filter: blur(3px); } .overlay.open { opacity: 1; visibility: visible; } /* Animation for recipe cards */ .recipe-card:nth-child(1) { animation-delay: 0.1s; } .recipe-card:nth-child(2) { animation-delay: 0.2s; } .recipe-card:nth-child(3) { animation-delay: 0.3s; } .recipe-card:nth-child(4) { animation-delay: 0.4s; } </style> </head> <body> <div class="container"> <header> <h1>FreshFinder</h1> <p class="subtitle">Discover recipes tailored to your pantry and preferences</p> <button class="drawer-button" id="open-pantry"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 2C6.5 2 2 6.5 2 12C2 17.5 6.5 22 12 22C17.5 22 22 17.5 22 12C22 6.5 17.5 2 12 2ZM16 13H13V16C13 16.6 12.6 17 12 17C11.4 17 11 16.6 11 16V13H8C7.4 13 7 12.6 7 12C7 11.4 7.4 11 8 11H11V8C11 7.4 11.4 7 12 7C12.6 7 13 7.4 13 8V11H16C16.6 11 17 11.4 17 12C17 12.6 16.6 13 16 13Z" fill="currentColor"/> </svg> My Pantry </button> </header> <div class="search-box"> <div class="search-icon"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M21.71 20.29L18 16.61C19.4401 14.8144 20.1375 12.5353 19.9488 10.2413C19.7601 7.94733 18.6997 5.81281 16.9855 4.27667C15.2714 2.74053 13.0338 1.91954 10.7329 1.9825C8.43203 2.04546 6.24272 2.98759 4.61514 4.61517C2.98756 6.24275 2.04543 8.43207 1.98247 10.7329C1.91951 13.0338 2.7405 15.2714 4.27664 16.9855C5.81278 18.6997 7.9473 19.7601 10.2413 19.9488C12.5353 20.1375 14.8144 19.4401 16.61 18L20.29 21.68C20.383 21.7737 20.4936 21.8481 20.6154 21.8989C20.7373 21.9497 20.868 21.9758 21 21.9758C21.132 21.9758 21.2627 21.9497 21.3846 21.8989C21.5064 21.8481 21.617 21.7737 21.71 21.68C21.8037 21.587 21.8781 21.4764 21.9289 21.3546C21.9797 21.2327 22.0058 21.102 22.0058 20.97C22.0058 20.838 21.9797 20.7073 21.9289 20.5854C21.8781 20.4636 21.8037 20.353 21.71 20.26V20.29ZM11 18C9.61553 18 8.26216 17.5895 7.11101 16.8203C5.95987 16.0511 5.06266 14.9579 4.53285 13.6788C4.00303 12.3997 3.86441 10.9922 4.13451 9.63437C4.4046 8.2765 5.07129 7.02922 6.05026 6.05025C7.02922 5.07128 8.27651 4.4046 9.63438 4.1345C10.9922 3.86441 12.3997 4.00303 13.6788 4.53284C14.9579 5.06266 16.0511 5.95986 16.8203 7.11101C17.5895 8.26215 18 9.61553 18 11C18 12.8565 17.2625 14.637 15.9497 15.9497C14.637 17.2625 12.8565 18 11 18Z" fill="currentColor"/> </svg> </div> <input type="text" class="search-input" placeholder="Search for recipes..." id="recipe-search"> </div> <div class="filter-container"> <div class="filter-section"> <h3 class="filter-title"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M17 12C17 11.4477 17.4477 11 18 11C18.5523 11 19 11.4477 19 12V19C19 20.1046 18.1046 21 17 21H7C5.89543 21 5 20.1046 5 19V12C5 11.4477 5.44772 11 6 11C6.55228 11 7 11.4477 7 12V19H17V12Z" fill="#FF6B4A"/> <path d="M12.7071 3.29289C12.3166 2.90237 11.6834 2.90237 11.2929 3.29289L7.29289 7.29289C6.90237 7.68342 6.90237 8.31658 7.29289 8.70711C7.68342 9.09763 8.31658 9.09763 8.70711 8.70711L11 6.41421V16C11 16.5523 11.4477 17 12 17C12.5523 17 13 16.5523 13 16V6.41421L15.2929 8.70711C15.6834 9.09763 16.3166 9.09763 16.7071 8.70711C17.0976 8.31658 17.0976 7.68342 16.7071 7.29289L12.7071 3.29289Z" fill="#FF6B4A"/> </svg> Cooking Time </h3> <div class="time-slider"> <input type="range" min="5" max="120" value="30" class="time-range" id="time-range"> <div class="time-display" id="time-display">Up to 30 minutes</div> </div> </div> <div class="filter-section"> <h3 class="filter-title"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12.8199 3.02912C12.5466 2.98 12.2699 3.00912 12.0099 3.12912C11.6566 3.28912 11.3832 3.58245 11.2232 3.92578C11.0166 4.39912 11.0799 4.95245 11.3932 5.35912L13.6532 8.15912L13.2366 8.67245C12.9366 8.35912 12.5366 8.14578 12.0899 8.05245C12.0366 7.61912 11.9166 7.20578 11.7266 6.82578C11.3732 6.15912 10.7932 5.63912 10.0899 5.35912C8.30657 4.75912 6.38657 5.89245 5.97324 7.72578C5.6066 9.32578 6.65324 10.8925 8.1666 11.3458C9.3466 11.6991 10.4899 11.2791 11.1999 10.4724C11.3466 10.7124 11.5399 10.9324 11.7599 11.1191L9.0599 14.5058C9.01324 14.5591 8.97324 14.6125 8.93324 14.6724C8.35324 15.7858 8.79991 17.1525 9.91991 17.7325C11.0399 18.3125 12.4066 17.8658 12.9866 16.7458C13.5666 15.6258 13.1199 14.2591 11.9999 13.6791C11.9466 13.6524 11.8866 13.6258 11.8266 13.6058L14.5266 10.2191C14.5732 10.1658 14.6132 10.1124 14.6532 10.0524C14.8466 10.1525 15.0532 10.2258 15.2732 10.2658L14.8566 10.7791C14.7299 10.9458 14.6532 11.1391 14.6399 11.3324C14.6266 11.5258 14.6799 11.7258 14.7866 11.8924L16.6266 14.6658C16.8132 14.9458 17.0999 15.1258 17.4266 15.1858C17.5532 15.2124 17.6799 15.2124 17.8066 15.1858C18.1266 15.1191 18.3999 14.9258 18.5466 14.6458C18.7599 14.2591 18.7732 13.7991 18.5732 13.3991L16.7332 10.6258C16.6332 10.4658 16.5066 10.3391 16.3599 10.2458C16.2132 10.1525 16.0532 10.0858 15.8766 10.0658L16.2932 9.55245C16.5666 9.85245 16.9399 10.0524 17.3466 10.1325C17.5999 11.3058 18.5466 12.2658 19.7599 12.5458C21.2599 12.8925 22.7199 11.9458 23.1132 10.4658C23.5066 8.98578 22.5599 7.52578 21.0799 7.13245C19.8732 6.81245 18.6999 7.25245 17.9999 8.09245C17.8399 7.84578 17.6266 7.63245 17.3932 7.45912L19.0399 5.39245C19.8066 4.45245 20.0266 3.19912 19.6266 2.05245C19.2066 0.872448 18.1932 -0.0342195 16.9732 0.00244722C15.8332 0.0391139 14.8599 0.825781 14.4399 1.89245C14.0132 2.95912 14.2066 4.19245 14.9732 5.13245L13.3266 7.19912C13.0866 7.00578 12.8132 6.85245 12.5132 6.74578L12.8199 3.02912ZM10.9999 8.55245C11.4932 8.69245 11.9132 9.01245 12.1699 9.45245C12.4266 9.89245 12.4866 10.4258 12.3466 10.9191C11.9599 12.2125 10.5866 12.9258 9.29324 12.5391C7.99991 12.1525 7.28657 10.7858 7.67324 9.49245C8.05991 8.19912 9.42657 7.48578 10.7199 7.87245C10.8199 8.07245 10.9132 8.30578 10.9999 8.55245ZM10.4399 15.9991C10.1866 16.4658 10.4932 17.0458 10.9866 17.2991C11.4666 17.5525 12.0466 17.2724 12.2999 16.7791C12.5532 16.2991 12.2732 15.7191 11.7799 15.4658C11.2999 15.2124 10.7199 15.4925 10.4666 15.9858L10.4399 15.9991ZM16.3999 1.57245C17.0799 1.55245 17.6799 2.02578 17.8999 2.67245C18.1332 3.35912 17.9599 4.12578 17.4532 4.72578L15.7266 6.87245L15.3199 6.26578C15.0066 5.84578 15.0132 5.30578 15.2066 4.84578L15.2332 4.78578C15.3866 4.45245 15.6466 4.17245 15.9799 4.02578C16.1466 3.94578 16.3199 3.90578 16.4932 3.90578L16.3999 1.57245ZM19.6532 8.85912C20.5199 9.07245 21.0466 9.95245 20.8332 10.8191C20.6199 11.6858 19.7399 12.2125 18.8732 11.9991C18.0066 11.7858 17.4799 10.9058 17.6932 10.0391C17.9066 9.17245 18.7866 8.64578 19.6532 8.85912ZM8.67991 9.42578C8.51991 9.89912 8.79991 10.4124 9.27324 10.5725C9.74658 10.7325 10.2599 10.4524 10.4199 9.97912C10.5799 9.50578 10.2999 8.99245 9.82658 8.83245C9.35324 8.67245 8.83991 8.95245 8.67991 9.42578Z" fill="#06D6A0"/> </svg> Meal Type </h3> <div class="pill-container" id="meal-type"> <button class="pill" data-value="breakfast">Breakfast</button> <button class="pill" data-value="lunch">Lunch</button> <button class="pill" data-value="dinner">Dinner</button> <button class="pill" data-value="snack">Snack</button> <button class="pill" data-value="dessert">Dessert</button> </div> </div> <div class="filter-section"> <h3 class="filter-title"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20.8889 3.11111H17.7778V2.05556C17.7778 1.51111 17.6444 1.02222 17.3889 0.6C17.1333 0.177778 16.7778 0 16.3333 0H7.66667C7.22222 0 6.86667 0.177778 6.61111 0.6C6.35556 1.02222 6.22222 1.51111 6.22222 2.05556V3.11111H3.11111C2.22222 3.11111 1.47778 3.42222 0.877778 4.02222C0.288889 4.62222 0 5.37778 0 6.22222V8.77778C0 9.62222 0.288889 10.3667 0.877778 10.9778C1.46667 11.5889 2.22222 11.8889 3.11111 11.8889H3.66667V21.7778C3.66667 22.5667 3.95556 23.2444 4.55556 23.8222C5.15556 24.3889 5.87778 24.6667 6.73333 24.6667H17.2667C18.1111 24.6667 18.8333 24.3889 19.4444 23.8222C20.0444 23.2444 20.3333 22.5667 20.3333 21.7778V11.8889H20.8889C21.7778 11.8889 22.5333 11.5889 23.1222 10.9778C23.7111 10.3667 24 9.62222 24 8.77778V6.22222C24 5.37778 23.7111 4.62222 23.1222 4.02222C22.5333 3.42222 21.7778 3.11111 20.8889 3.11111ZM8.33333 2.05556C8.33333 1.96667 8.35556 1.88889 8.38889 1.85556C8.42222 1.82222 8.5 1.77778 8.64444 1.77778H15.3556C15.5 1.77778 15.5778 1.82222 15.6111 1.85556C15.6444 1.88889 15.6667 1.96667 15.6667 2.05556V3.11111H8.33333V2.05556ZM18.2222 21.7778C18.2222 22.0889 18.1111 22.3333 17.8778 22.5667C17.6444 22.8 17.3889 22.8889 17.0778 22.8889H6.92222
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Music Library Filter</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; } :root { --primary: #8E2DE2; --secondary: #4A00E0; --tertiary: #5E60CE; --background: #121212; --text: #f8f8f8; --dark-text: #999; --panel: rgba(30, 30, 30, 0.7); --shadow: 0 8px 30px rgba(0, 0, 0, 0.25); --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } body { background-color: var(--background); color: var(--text); height: 700px; width: 700px; overflow: hidden; display: flex; flex-direction: column; } .container { max-width: 700px; width: 100%; height: 100%; margin: 0 auto; padding: 1.5rem; position: relative; overflow-y: auto; display: flex; flex-direction: column; gap: 1.5rem; } .container::-webkit-scrollbar { width: 6px; } .container::-webkit-scrollbar-track { background: var(--background); } .container::-webkit-scrollbar-thumb { background: var(--tertiary); border-radius: 6px; } .background-gradient { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, var(--primary), var(--secondary)); opacity: 0.08; z-index: -1; pointer-events: none; } .background-blob { position: fixed; width: 700px; height: 700px; background: radial-gradient(circle, var(--tertiary) 0%, transparent 70%); filter: blur(80px); opacity: 0.15; z-index: -1; animation: blob-move 25s infinite alternate ease-in-out; pointer-events: none; } @keyframes blob-move { 0% { transform: translate(-40%, -40%); } 100% { transform: translate(40%, 40%); } } .header { display: flex; flex-direction: column; gap: 0.5rem; } .header h1 { font-size: 2.2rem; font-weight: 800; background: linear-gradient(to right, var(--text), var(--tertiary)); -webkit-background-clip: text; background-clip: text; color: transparent; margin-bottom: 0.5rem; } .header p { color: var(--dark-text); font-size: 1rem; line-height: 1.5; margin-bottom: 1rem; } .filter-section { background: var(--panel); border-radius: 16px; padding: 1.5rem; box-shadow: var(--shadow); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); margin-bottom: 1rem; transition: var(--transition); } .filter-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .filter-title { font-size: 1.2rem; font-weight: 600; display: flex; align-items: center; gap: 0.5rem; } .filter-title svg { width: 20px; height: 20px; fill: currentColor; opacity: 0.8; } .filter-reset { background: none; border: none; color: var(--tertiary); font-size: 0.875rem; cursor: pointer; padding: 0.25rem 0.5rem; border-radius: 4px; transition: var(--transition); opacity: 0.8; } .filter-reset:hover { opacity: 1; background: rgba(94, 96, 206, 0.1); } .tag-cloud { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1rem; } .tag { padding: 0.5rem 1rem; border-radius: 100px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: var(--transition); background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); display: flex; align-items: center; gap: 0.5rem; position: relative; overflow: hidden; } .tag:hover { background: rgba(255, 255, 255, 0.1); transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } .tag.selected { background: linear-gradient(135deg, var(--primary), var(--secondary)); color: white; border: 1px solid rgba(255, 255, 255, 0.2); box-shadow: 0 5px 15px rgba(142, 45, 226, 0.3); } .tag::before { content: ''; position: absolute; top: 50%; left: 50%; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.1); border-radius: 100px; transform: translate(-50%, -50%) scale(0); transition: transform 0.4s ease; } .tag:active::before { transform: translate(-50%, -50%) scale(1.5); opacity: 0; } .tag svg { width: 16px; height: 16px; opacity: 0.8; } .mood-tags { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 0.75rem; margin-top: 1rem; } .mood-tag { padding: 0.75rem 0.5rem; border-radius: 12px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: var(--transition); background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); text-align: center; display: flex; flex-direction: column; align-items: center; gap: 0.5rem; position: relative; overflow: hidden; } .mood-tag:hover { background: rgba(255, 255, 255, 0.1); transform: translateY(-2px); } .mood-tag.selected { background: linear-gradient(135deg, var(--primary), var(--secondary)); color: white; border: 1px solid rgba(255, 255, 255, 0.2); box-shadow: 0 5px 15px rgba(142, 45, 226, 0.3); } .mood-tag svg { width: 24px; height: 24px; opacity: 0.8; } .artist-filter { display: flex; flex-direction: column; gap: 1rem; margin-top: 1rem; } .search-input { position: relative; width: 100%; } .search-input input { width: 100%; padding: 0.75rem 1rem 0.75rem 2.5rem; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.1); background: rgba(255, 255, 255, 0.05); color: var(--text); font-size: 0.875rem; transition: var(--transition); } .search-input input:focus { outline: none; border-color: var(--tertiary); background: rgba(255, 255, 255, 0.08); box-shadow: 0 0 0 3px rgba(94, 96, 206, 0.2); } .search-input svg { position: absolute; left: 0.75rem; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--dark-text); pointer-events: none; } .artist-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 1rem; margin-top: 0.5rem; } .artist-card { border-radius: 12px; overflow: hidden; position: relative; cursor: pointer; transition: var(--transition); height: 130px; box-shadow: var(--shadow); } .artist-card:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3); } .artist-card.selected::after { content: '✓'; position: absolute; top: 0.5rem; right: 0.5rem; width: 24px; height: 24px; background: var(--primary); color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.75rem; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); z-index: 2; } .artist-image { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; transition: var(--transition); } .artist-card.selected .artist-image { filter: brightness(0.7); } .artist-overlay { position: absolute; bottom: 0; left: 0; right: 0; padding: 0.75rem; background: linear-gradient(to top, rgba(0, 0, 0, 0.8), transparent); z-index: 2; } .artist-name { font-size: 0.875rem; font-weight: 600; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .artist-genres { color: rgba(255, 255, 255, 0.7); font-size: 0.75rem; margin-top: 0.25rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .apply-filters { background: linear-gradient(135deg, var(--primary), var(--secondary)); color: white; border: none; border-radius: 100px; padding: 1rem 2rem; font-size: 1rem; font-weight: 600; cursor: pointer; transition: var(--transition); display: flex; align-items: center; justify-content: center; gap: 0.5rem; box-shadow: 0 8px 20px rgba(142, 45, 226, 0.3); position: relative; overflow: hidden; margin-top: 0.5rem; } .apply-filters:hover { transform: translateY(-2px); box-shadow: 0 12px 25px rgba(142, 45, 226, 0.4); } .apply-filters:active { transform: translateY(1px); } .apply-filters::before { content: ''; position: absolute; top: 50%; left: 50%; width: 300px; height: 300px; background: rgba(255, 255, 255, 0.1); border-radius: 50%; transform: translate(-50%, -50%) scale(0); transition: transform 0.4s ease; } .apply-filters:active::before { transform: translate(-50%, -50%) scale(1); opacity: 0; } .apply-filters svg { width: 20px; height: 20px; } .collapse-panel { display: flex; justify-content: space-between; align-items: center; width: 100%; background: none; border: none; color: var(--text); cursor: pointer; padding: 0; } .collapse-panel svg { transition: var(--transition); } .collapsed .collapse-panel svg { transform: rotate(180deg); } .filter-content { overflow: hidden; max-height: 500px; transition: max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1); } .collapsed .filter-content { max-height: 0; } .filter-count { display: inline-flex; background: var(--primary); color: white; border-radius: 100px; padding: 0.25rem 0.6rem; font-size: 0.75rem; font-weight: 600; margin-left: 0.5rem; } .selected-count { display: flex; align-items: center; justify-content: flex-end; color: var(--dark-text); font-size: 0.875rem; margin-top: 1rem; } .selected-count span { color: var(--tertiary); font-weight: 600; margin-left: 0.25rem; } .results-section { background: var(--panel); border-radius: 16px; padding: 1.5rem; box-shadow: var(--shadow); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); margin-top: auto; overflow: hidden; } .results-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .results-title { font-size: 1.2rem; font-weight: 600; display: flex; align-items: center; gap: 0.5rem; } .results-info { display: flex; align-items: center; gap: 0.5rem; } .results-count { background: var(--tertiary); color: white; border-radius: 100px; padding: 0.25rem 0.6rem; font-size: 0.75rem; font-weight: 600; } .wave-animation { height: 20px; display: flex; align-items: center; gap: 2px; } .wave-bar { background: var(--tertiary); width: 2px; border-radius: 2px; animation: wave 1.2s ease-in-out infinite; } @keyframes wave { 0%, 100% { height: 5px; } 50% { height: 15px; } } .wave-bar:nth-child(2) { animation-delay: 0.2s; } .wave-bar:nth-child(3) { animation-delay: 0.4s; } .wave-bar:nth-child(4) { animation-delay: 0.6s; } .wave-bar:nth-child(5) { animation-delay: 0.8s; } @media (max-width: 600px) { .header h1 { font-size: 1.8rem; } .filter-section { padding: 1rem; } .tag-cloud, .mood-tags, .artist-list { gap: 0.5rem; } .mood-tags { grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); } .artist-list { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); } .apply-filters { padding: 0.75rem 1.5rem; } } .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(142, 45, 226, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(142, 45, 226, 0); } 100% { box-shadow: 0 0 0 0 rgba(142, 45, 226, 0); } } .no-artists { padding: 1.5rem; text-align: center; color: var(--dark-text); font-size: 0.875rem; background: rgba(255, 255, 255, 0.05); border-radius: 8px; } </style> </head> <body> <div class="background-gradient"></div> <div class="background-blob"></div> <div class="container"> <div class="header"> <h1>Discover Your Sound</h1> <p>Customize your musical journey with advanced filters to find the perfect soundtrack for any moment.</p> </div> <div class="filter-section" id="genreSection"> <button class="collapse-panel"> <div class="filter-title"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM7.5 10.5L10.5 13.5L16.5 7.5L18 9L10.5 16.5L6 12L7.5 10.5Z"/> </svg> Genres <span class="filter-count" id="genreCount">0</span> </div> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="18 15 12 9 6 15"></polyline> </svg> </button> <div class="filter-content"> <div class="tag-cloud" id="genreTags"> <div class="tag" data-genre="pop"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M8 10a4 4 0 1 0 8 0a4 4 0 0 0-8 0zm0-6a4 4 0 0 0-4 4v12a4 4 0 0 0 4 4h8a4 4 0 0 0 4-4V8a4 4 0 0 0-4-4H8z"/> </svg> Pop </div> <div class="tag" data-genre="rock"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M19.93 8.35l-3.6 1.68L14 7.7V4h1c.55 0 1-.45 1-1s-.45-1-1-1H9c-.55 0-1 .45-1 1s.45 1 1 1h1v3.7L7.67 10l-3.6-1.68c-.38-.18-.82-.01-1.03.36c-.21.37-.08.82.27 1.03L6.93 12l-3.63 2.29c-.35.22-.48.67-.27 1.03c.21.38.66.55 1.03.36l3.6-1.68L10 16.3V20H9c-.55 0-1 .45-1 1s.45 1 1 1h6c.55 0 1-.45 1-1s-.45-1-1-1h-1v-3.7l2.33-2.3l3.6 1.68c.38.18.82.01 1.03-.36c.21-.37.08-.82-.27-1.03L17.07 12l3.63-2.29c.35-.22.48-.67.27-1.03c-.21-.37-.66-.54-1.04-.33z"/> </svg> Rock </div> <div class="tag" data-genre="electronic"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M7 4v16h10V4H7zM5 2h14c1.1 0 2 .9 2 2v16c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2zm8 6h-2v2h2V8zm0 4h-2v2h2v-2zm0 4h-2v2h2v-2zm4-8h-2v2h2V8zm0 4h-2v2h2v-2zm0 4h-2v2h2v-2zM9 8H7v2h2V8zm0 4H7v2h2v-2zm0 4H7v2h2v-2z"/> </svg> Electronic </div> <div class="tag" data-genre="hiphop"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/> </svg> Hip Hop </div> <div class="tag" data-genre="rnb"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/> </svg> R&B </div> <div class="tag" data-genre="jazz"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/> </svg> Jazz </div> <div class="tag" data-genre="classical"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/> </svg> Classical </div> <div class="tag" data-genre="folk"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/> </svg> Folk </div> <div class="tag" data-genre="country"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/> </svg> Country </div> <div class="tag" data-genre="metal"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M19.93 8.35l-3.6 1.68L14 7.7V4h1c.55 0 1-.45 1-1s-.45-1-1-1H9c-.55 0-1 .45-1 1s.45 1 1 1h1v3.7L7.67 10l-3.6-1.68c-.38-.18-.82-.01-1.03.36c-.21.37-.08.82.27 1.03L6.93 12l-3.63 2.29c-.35.22-.48.67-.27 1.03c.21.38.66.55 1.03.36l3.6-1.68L10 16.3V20H9c-.55 0-1 .45-1 1s.45 1 1 1h6c.55 0 1-.45 1-1s-.45-1-1-1h-1v-3.7l2.33-2.3l3.6 1.68c.38.18.82.01 1.03-.36c.21-.37.08-.82-.27-1.03L17.07 12l3.63-2.29c.35-.22.48-.67.27-1.03c-.21-.37-.66-.54-1.04-.33z"/> </svg> Metal </div> <div class="tag" data-genre="ambient"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/> </svg> Ambient </div> <div class="tag" data-genre="world"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/> </svg> World </div> </div> <div class="selected-count" id="genreSelectedCount">Selected: <span>0</span></div> </div> </div> <div class="filter-section" id="moodSection"> <button class="collapse-panel"> <div class="filter-title"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/> </svg> Mood <span class="filter-count" id="moodCount">0</span> </div> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="18 15 12 9 6 15"></polyline> </svg> </button> <div class="filter-content"> <div class="mood-tags" id="moodTags"> <div class="mood-tag" data-mood="energetic"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M7 2v11h3v9l7-12h-4l4-8H7z"/> </svg> Energetic </div> <div class="mood-tag" data-mood="chill"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14h-2v-2h2v2zm0-4h-2V7h2v5z"/> </svg> Chill </div> <div class="mood-tag" data-mood="happy"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/> </svg> Happy </div> <div class="mood-tag" data-mood="melancholic"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm6.5 5.5H7.01c-.13 0-.25.07-.29.18-.12.29.11.61.41.61h9.74c.3 0 .53-.32.41-.61-.04-.11-.16-.18-.29-.18z"/> </svg> Melancholic </div> <div class="mood-tag" data-mood="romantic"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Social Media Content Filter</title> <style> :root { --primary: #4d68ff; --secondary: #ff6b6b; --tertiary: #02c39a; --dark: #1a1a2e; --light: #f8f9fa; --gray: #e0e0e0; --text: #333; --shadow: 0 4px 12px rgba(0, 0, 0, 0.1); --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--light); color: var(--text); padding: 20px; height: 700px; max-width: 700px; margin: 0 auto; overflow-x: hidden; } .container { max-width: 100%; height: 100%; display: flex; flex-direction: column; gap: 15px; } header { display: flex; justify-content: space-between; align-items: center; padding: 15px 0; } h1 { font-size: 1.5rem; font-weight: 700; color: var(--dark); margin: 0; } .theme-toggle { background: none; border: none; cursor: pointer; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background-color: var(--light); box-shadow: var(--shadow); transition: var(--transition); } .theme-toggle:hover { transform: translateY(-2px); box-shadow: 0 6px 14px rgba(0, 0, 0, 0.15); } .theme-toggle svg { width: 20px; height: 20px; fill: var(--dark); } .filter-container { display: flex; flex-wrap: wrap; gap: 10px; padding: 5px 0; position: relative; } .filter-container::after { content: ''; position: absolute; bottom: -5px; left: 0; width: 100%; height: 2px; background: linear-gradient(90deg, var(--primary) 0%, var(--secondary) 50%, var(--tertiary) 100%); border-radius: 2px; } .filter-btn { padding: 8px 16px; background-color: var(--light); border: 2px solid var(--gray); border-radius: 20px; font-weight: 600; font-size: 0.9rem; cursor: pointer; transition: var(--transition); display: flex; align-items: center; gap: 6px; color: var(--text); } .filter-btn:hover { transform: translateY(-2px); box-shadow: var(--shadow); } .filter-btn.active { background-color: var(--primary); color: white; border-color: var(--primary); } .type-btn.active[data-type="image"] { background-color: var(--secondary); border-color: var(--secondary); } .type-btn.active[data-type="video"] { background-color: var(--tertiary); border-color: var(--tertiary); } .type-btn.active[data-type="text"] { background-color: var(--dark); border-color: var(--dark); } .filter-btn svg { width: 16px; height: 16px; fill: currentColor; } .search-bar { position: relative; margin: 5px 0 15px; } .search-input { width: 100%; padding: 12px 45px 12px 15px; border-radius: 10px; border: 2px solid var(--gray); background-color: var(--light); font-size: 0.95rem; transition: var(--transition); } .search-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(77, 104, 255, 0.2); } .search-icon { position: absolute; right: 15px; top: 50%; transform: translateY(-50%); width: 20px; height: 20px; fill: var(--text); } .feed { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 15px; padding-right: 5px; scrollbar-width: thin; scrollbar-color: var(--gray) transparent; } .feed::-webkit-scrollbar { width: 6px; } .feed::-webkit-scrollbar-track { background: transparent; } .feed::-webkit-scrollbar-thumb { background-color: var(--gray); border-radius: 6px; } .post { background-color: white; border-radius: 12px; padding: 15px; box-shadow: var(--shadow); transition: var(--transition); transform: translateY(20px); opacity: 0; animation: fadeIn 0.5s forwards; position: relative; overflow: hidden; } .post:hover { transform: translateY(-2px); box-shadow: 0 6px 14px rgba(0, 0, 0, 0.12); } .post-header { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; } .post-avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; } .post-info { flex: 1; } .post-author { font-weight: 600; margin-bottom: 2px; color: var(--dark); } .post-meta { display: flex; align-items: center; font-size: 0.8rem; color: #777; gap: 8px; } .post-meta-item { display: flex; align-items: center; gap: 4px; } .post-meta-item svg { width: 14px; height: 14px; fill: currentColor; } .post-type-badge { font-size: 0.7rem; font-weight: 600; padding: 3px 8px; border-radius: 4px; text-transform: uppercase; } .post-type-badge[data-type="image"] { background-color: rgba(255, 107, 107, 0.15); color: var(--secondary); } .post-type-badge[data-type="video"] { background-color: rgba(2, 195, 154, 0.15); color: var(--tertiary); } .post-type-badge[data-type="text"] { background-color: rgba(26, 26, 46, 0.15); color: var(--dark); } .post-content { margin-bottom: 12px; font-size: 0.95rem; line-height: 1.5; } .post-image { width: 100%; max-height: 250px; border-radius: 8px; object-fit: cover; margin-bottom: 12px; } .post-video { width: 100%; height: 200px; border-radius: 8px; margin-bottom: 12px; background-color: #000; display: flex; align-items: center; justify-content: center; position: relative; } .post-video-play { width: 50px; height: 50px; background-color: rgba(255, 255, 255, 0.8); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); transition: var(--transition); } .post-video-play:hover { transform: scale(1.1); background-color: white; } .post-video-play svg { width: 20px; height: 20px; fill: var(--dark); margin-left: 4px; } .post-video-thumbnail { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 8px; } .post-actions { display: flex; justify-content: space-between; padding-top: 10px; border-top: 1px solid var(--gray); } .post-action { display: flex; align-items: center; gap: 6px; font-size: 0.85rem; color: #555; padding: 5px 10px; border-radius: 5px; cursor: pointer; transition: var(--transition); } .post-action:hover { background-color: var(--gray); } .post-action svg { width: 18px; height: 18px; fill: currentColor; } .post-likes-active { color: var(--secondary); } .no-results { text-align: center; padding: 30px; color: #777; font-size: 0.95rem; display: flex; flex-direction: column; align-items: center; gap: 15px; } .no-results svg { width: 50px; height: 50px; fill: var(--gray); } .filter-chip { background-color: var(--primary); color: white; border-radius: 15px; padding: 3px 10px; font-size: 0.8rem; font-weight: 600; margin-left: 5px; display: inline-flex; align-items: center; } .filter-chip svg { width: 14px; height: 14px; fill: currentColor; margin-left: 4px; cursor: pointer; } @keyframes fadeIn { to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .loading { text-align: center; padding: 30px; color: #777; } .loading-spinner { display: inline-block; width: 30px; height: 30px; border: 3px solid rgba(77, 104, 255, 0.3); border-radius: 50%; border-top-color: var(--primary); animation: spin 1s ease-in-out infinite; margin-bottom: 10px; } @keyframes spin { to { transform: rotate(360deg); } } .tooltip { position: absolute; background-color: rgba(0, 0, 0, 0.8); color: white; padding: 5px 10px; border-radius: 4px; font-size: 0.8rem; pointer-events: none; opacity: 0; transition: opacity 0.2s; z-index: 100; white-space: nowrap; } @media (max-width: 480px) { h1 { font-size: 1.2rem; } .filter-btn { padding: 6px 12px; font-size: 0.8rem; } .post { padding: 12px; } .post-content { font-size: 0.9rem; } } /* Dark mode styles */ body.dark-mode { background-color: #121212; color: #e0e0e0; } body.dark-mode h1 { color: white; } body.dark-mode .theme-toggle { background-color: #2d2d2d; } body.dark-mode .theme-toggle svg { fill: white; } body.dark-mode .filter-btn { background-color: #2d2d2d; border-color: #444; color: #e0e0e0; } body.dark-mode .post { background-color: #1e1e1e; } body.dark-mode .search-input { background-color: #2d2d2d; border-color: #444; color: #e0e0e0; } body.dark-mode .search-icon { fill: #e0e0e0; } body.dark-mode .post-author { color: #f0f0f0; } body.dark-mode .post-actions { border-top-color: #444; } body.dark-mode .post-action:hover { background-color: #333; } .like-animation { animation: pulse 0.4s; } </style> </head> <body> <div class="container"> <header> <h1>FeedFilter</h1> <button class="theme-toggle" aria-label="Toggle dark mode"> <svg viewBox="0 0 24 24"> <path d="M12,18C11.11,18 10.26,17.8 9.5,17.45C11.56,16.5 13,14.42 13,12C13,9.58 11.56,7.5 9.5,6.55C10.26,6.2 11.11,6 12,6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31L23.31,12L20,8.69Z"></path> </svg> </button> </header> <div class="filter-container"> <button class="filter-btn sort-btn active" data-sort="popular"> <svg viewBox="0 0 24 24"> <path d="M7.5,21.5L8.85,20.16L12.66,23.97L12,24C5.71,24 0.56,19.16 0.05,13H1.55C1.91,16.76 4.25,19.94 7.5,21.5M16.5,2.5L15.15,3.84L11.34,0.03L12,0C18.29,0 23.44,4.84 23.95,11H22.45C22.09,7.24 19.75,4.07 16.5,2.5M6,17C6,15 10,13.9 12,13.9C14,13.9 18,15 18,17V18H6V17M15,9A3,3 0 0,1 12,12A3,3 0 0,1 9,9A3,3 0 0,1 12,6A3,3 0 0,1 15,9Z"></path> </svg> Popular </button> <button class="filter-btn sort-btn" data-sort="recent"> <svg viewBox="0 0 24 24"> <path d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z"></path> </svg> Recent </button> <button class="filter-btn type-btn" data-type="image"> <svg viewBox="0 0 24 24"> <path d="M5,3A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3H5M19,19H5V5H19V19M10,14L12,12L14,14V17H10V14M17,8.5A1.5,1.5 0 0,1 15.5,10A1.5,1.5 0 0,1 14,8.5A1.5,1.5 0 0,1 15.5,7A1.5,1.5 0 0,1 17,8.5M10,6.5A3.5,3.5 0 0,1 13.5,10A3.5,3.5 0 0,1 10,13.5A3.5,3.5 0 0,1 6.5,10A3.5,3.5 0 0,1 10,6.5Z"></path> </svg> Images </button> <button class="filter-btn type-btn" data-type="video"> <svg viewBox="0 0 24 24"> <path d="M17,10.5V7A1,1 0 0,0 16,6H4A1,1 0 0,0 3,7V17A1,1 0 0,0 4,18H16A1,1 0 0,0 17,17V13.5L21,17.5V6.5L17,10.5Z"></path> </svg> Videos </button> <button class="filter-btn type-btn" data-type="text"> <svg viewBox="0 0 24 24"> <path d="M20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20M4,6V18H20V6H4M6,9H18V11H6V9M6,13H16V15H6V13Z"></path> </svg> Text </button> </div> <div class="search-bar"> <input type="text" class="search-input" placeholder="Search by keyword or author..."> <svg class="search-icon" viewBox="0 0 24 24"> <path d="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z"></path> </svg> </div> <div class="feed"> <!-- Posts will be loaded here dynamically --> <div class="loading"> <div class="loading-spinner"></div> <p>Loading your personalized feed...</p> </div> </div> <div class="tooltip" style="display: none;"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Mock data for posts const posts = [ { id: 1, author: "Alex Chen", avatar: "https://randomuser.me/api/portraits/women/44.jpg", content: "Just finished my latest photography project exploring urban landscapes at night. The way city lights transform mundane structures is absolutely fascinating!", image: "https://images.unsplash.com/photo-1519501025264-65ba15a82390?w=600&h=400&fit=crop", type: "image", time: "2 hours ago", likes: 247, comments: 43, shares: 12, popularity: 9.4 }, { id: 2, author: "Jamie Rivera", avatar: "https://randomuser.me/api/portraits/men/32.jpg", content: "I'm curious—what productivity apps are you all using these days? I'm looking to streamline my workflow and would love some real-world recommendations.", type: "text", time: "30 minutes ago", likes: 58, comments: 134, shares: 5, popularity: 7.8 }, { id: 3, author: "Taylor Morgan", avatar: "https://randomuser.me/api/portraits/women/22.jpg", content: "Check out this quick demo of the motion tracking system we've been developing for independent filmmakers. Affordable cinema tools for everyone!", video: "https://images.unsplash.com/photo-1536240478700-b869070f9279?w=600&h=400&fit=crop", type: "video", time: "5 hours ago", likes: 432, comments: 67, shares: 89, popularity: 9.8 }, { id: 4, author: "Sam Wilson", avatar: "https://randomuser.me/api/portraits/men/52.jpg", content: "Finally tried that new ramen place downtown. The broth was rich with 48-hour bone marrow and the hand-pulled noodles had the perfect chew. Definitely worth the wait!", image: "https://images.unsplash.com/photo-1623341214825-9f4f963727da?w=600&h=400&fit=crop", type: "image", time: "1 day ago", likes: 187, comments: 23, shares: 7, popularity: 8.2 }, { id: 5, author: "Jordan Lee", avatar: "https://randomuser.me/api/portraits/women/68.jpg", content: "Just published my analysis on how open-source contribution affects developer hiring prospects. Key finding: Quality over quantity matters more than ever in 2023.", type: "text", time: "3 hours ago", likes: 312, comments: 56, shares: 97, popularity: 9.1 }, { id: 6, author: "Casey Zhang", avatar: "https://randomuser.me/api/portraits/men/77.jpg", content: "Behind-the-scenes of our latest commercial shoot. Amazing what you can accomplish with a small crew and creative lighting!", video: "https://images.unsplash.com/photo-1585373683920-671416330a58?w=600&h=400&fit=crop", type: "video", time: "7 hours ago", likes: 298, comments: 42, shares: 31, popularity: 8.7 }, { id: 7, author: "Robin Patel", avatar: "https://randomuser.me/api/portraits/women/90.jpg", content: "Mental health tip: Schedule true downtime without screens. I've started 'analog evenings' once a week and it's dramatically improved my sleep quality and creative thinking.", type: "text", time: "20 minutes ago", likes: 412, comments: 87, shares: 103, popularity: 9.6 } ]; // State variables let activeSort = 'popular'; let activeTypes = []; let searchQuery = ''; const feed = document.querySelector('.feed'); let likedPosts = []; // Initialize tooltips initTooltips(); // Theme toggle functionality const themeToggle = document.querySelector('.theme-toggle'); themeToggle.addEventListener('click', () => { document.body.classList.toggle('dark-mode'); // Change the icon based on theme const svgPath = themeToggle.querySelector('svg path'); if (document.body.classList.contains('dark-mode')) { svgPath.setAttribute('d', 'M12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,2L14.39,5.42C13.65,5.15 12.84,5 12,5C11.16,5 10.35,5.15 9.61,5.42L12,2M3.34,7L7.5,6.65C6.9,7.16 6.36,7.78 5.94,8.5C5.5,9.24 5.25,10 5.11,10.79L3.34,7M3.36,17L5.12,13.23C5.26,14 5.53,14.78 5.95,15.5C6.37,16.24 6.91,16.86 7.5,17.37L3.36,17M20.65,7L18.88,10.79C18.74,10 18.47,9.23 18.05,8.5C17.63,7.78 17.1,7.15 16.5,6.64L20.65,7M20.64,17L16.5,17.36C17.09,16.85 17.62,16.22 18.04,15.5C18.46,14.77 18.73,14 18.87,13.21L20.64,17M12,22L9.59,18.56C10.33,18.83 11.14,19 12,19C12.82,19 13.63,18.83 14.37,18.56L12,22Z'); } else { svgPath.setAttribute('d', 'M12,18C11.11,18 10.26,17.8 9.5,17.45C11.56,16.5 13,14.42 13,12C13,9.58 11.56,7.5 9.5,6.55C10.26,6.2 11.11,6 12,6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31L23.31,12L20,8.69Z'); } }); // Sort button functionality const sortBtns = document.querySelectorAll('.sort-btn'); sortBtns.forEach(btn => { btn.addEventListener('click', () => { sortBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); activeSort = btn.dataset.sort; renderPosts(); }); }); // Content type filter functionality const typeBtns = document.querySelectorAll('.type-btn'); typeBtns.forEach(btn => { btn.addEventListener('click', () => { btn.classList.toggle('active'); const type = btn.dataset.type; if (btn.classList.contains('active')) { activeTypes.push(type); } else { activeTypes = activeTypes.filter(t => t !== type); } renderPosts(); }); }); // Search functionality const searchInput = document.querySelector('.search-input'); searchInput.addEventListener('input', () => { searchQuery = searchInput.value.toLowerCase().trim(); renderPosts(); }); // Initialize tooltip functionality function initTooltips() { const tooltip = document.querySelector('.tooltip'); document.addEventListener('mouseover', (e) => { const target = e.target.closest('[data-tooltip]'); if (target) { const tooltipText = target.getAttribute('data-tooltip'); tooltip.textContent = tooltipText; tooltip.style.display = 'block'; tooltip.style.opacity = '1'; // Position the tooltip const rect = target.getBoundingClientRect(); tooltip.style.top = `${rect.top - tooltip.offsetHeight - 10}px`; tooltip.style.left = `${rect.left + (rect.width / 2) - (tooltip.offsetWidth / 2)}px`; } }); document.addEventListener('mouseout', (e) => { if (e.target.closest('[data-tooltip]')) { tooltip.style.opacity = '0'; setTimeout(() => { tooltip.style.display = 'none'; }, 200); } }); } // Filter posts based on current filters function filterPosts() { return posts.filter(post => { // Apply type filter if any types are selected if (activeTypes.length > 0 && !activeTypes.includes(post.type)) { return false; } // Apply search filter if (searchQuery) { const authorMatch = post.author.toLowerCase().includes(searchQuery); const contentMatch = post.content.toLowerCase().includes(searchQuery); return authorMatch || contentMatch; } return true; }); } // Sort posts based on current sort option function sortPosts(filteredPosts) { if (activeSort === 'popular') { return [...filteredPosts].sort((a, b) => b.popularity - a.popularity); } else if (activeSort === 'recent') { return [...filteredPosts].sort((a, b) => { // Convert the time strings to a numeric value for comparison // For this demo we'll use a simple approach const timeA = a.time.includes('minutes') ? 1 : a.time.includes('hours') ? 2 : 3; const timeB = b.time.includes('minutes') ? 1 : b.time.includes('hours') ? 2 : 3; return timeA - timeB; }); } return filteredPosts; } // Render posts to the feed function renderPosts() { const filteredPosts = filterPosts(); const sortedPosts = sortPosts(filteredPosts); // Show loading state feed.innerHTML = ` <div class="loading"> <div class="loading-spinner"></div> <p>Updating your feed...</p> </div> `; // Simulate network delay setTimeout(() => { if (sortedPosts.length === 0) { feed.innerHTML = ` <div class="no-results"> <svg viewBox="0 0 24 24"> <path d="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z"></path> </svg> <p>No posts match your current filters</p> <button class="filter-btn" id="clear-filters">Clear all filters</button> </div> `; document.getElementById('clear-filters').addEventListener('click', () => { activeTypes = []; searchQuery = ''; searchInput.value = ''; document.querySelectorAll('.type-btn').forEach(btn => { btn.classList.remove('active'); }); renderPosts(); }); return; } feed.innerHTML = ''; // Add posts with staggered animation sortedPosts.forEach((post, index) => { const postElement = createPostElement(post); postElement.style.animationDelay = `${index * 0.1}s`; feed.appendChild(postElement); }); // Setup post interactions setupPostInteractions(); }, 500); } // Create a post element function createPostElement(post) { const postElement = document.createElement('div'); postElement.className = 'post'; postElement.dataset.id = post.id; let mediaContent = ''; if (post.type === 'image') { mediaContent = `<img src="${post.image}" alt="Post image" class="post-image">`; } else if (post.type === 'video') { mediaContent = ` <div class="post-video"> <img src="${post.video}" alt="Video thumbnail" class="post-video-thumbnail"> <div class="post-video-play" data-tooltip="Play video"> <svg viewBox="0 0 24 24"> <path d="M8,5.14V19.14L19,12.14L8,5.14Z"></path> </svg> </div> </div> `; } const isLiked = likedPosts.includes(post.id); const likeClass = isLiked ? 'post-likes-active' : ''; postElement.innerHTML = ` <div class="post-header"> <img src="${post.avatar}" alt="${post.author}" class="post-avatar"> <div class="post-info"> <div class="post-author">${post.author}</div> <div class="post-meta"> <span class="post-meta-item"> <svg viewBox="0 0 24 24"> <path d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #6b8faf; --secondary: #f2c9c9; --accent: #8fb396; --text: #3a4454; --background: #f5f5f7; --white: #ffffff; --shadow: rgba(0, 0, 0, 0.04); --shadow-hover: rgba(0, 0, 0, 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Georgia', serif; } body { background-color: var(--background); color: var(--text); display: flex; justify-content: center; align-items: center; min-height: 700px; } .container { width: 100%; max-width: 700px; padding: 2rem; height: 700px; display: flex; flex-direction: column; overflow: hidden; } .header { text-align: center; margin-bottom: 1.5rem; } .header h1 { font-size: 2rem; margin-bottom: 0.5rem; color: var(--primary); letter-spacing: -0.5px; } .header p { font-size: 1rem; color: var(--text); opacity: 0.8; line-height: 1.5; } .filter-section { background-color: var(--white); padding: 1.5rem; border-radius: 12px; box-shadow: 0 4px 20px var(--shadow); margin-bottom: 1rem; } .filter-row { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 1rem; } .filter-group { flex: 1; min-width: 180px; } .filter-group h3 { margin-bottom: 0.75rem; font-size: 1.1rem; display: flex; align-items: center; gap: 0.5rem; } .filter-group h3 i { color: var(--primary); font-size: 1rem; } .dropdown-container { position: relative; } .dropdown-select { width: 100%; padding: 0.75rem 1rem; border: 1px solid #e0e0e0; border-radius: 8px; background-color: var(--white); cursor: pointer; font-size: 0.9rem; display: flex; justify-content: space-between; align-items: center; transition: all 0.2s ease; color: var(--text); } .dropdown-select:hover { border-color: var(--primary); box-shadow: 0 2px 10px var(--shadow-hover); } .dropdown-select:focus { outline: none; border-color: var(--primary); box-shadow: 0 2px 10px var(--shadow-hover); } .dropdown-select i { transition: transform 0.3s ease; } .dropdown-select.active i { transform: rotate(180deg); } .dropdown-options { position: absolute; top: calc(100% + 5px); left: 0; width: 100%; background-color: var(--white); border-radius: 8px; box-shadow: 0 4px 20px var(--shadow); max-height: 0; overflow: hidden; opacity: 0; transition: all 0.3s ease; z-index: 10; } .dropdown-options.active { max-height: 300px; opacity: 1; } .dropdown-option { padding: 0.75rem 1rem; cursor: pointer; transition: background-color 0.2s ease; } .dropdown-option:hover { background-color: var(--background); } .dropdown-option.selected { background-color: rgba(107, 143, 175, 0.1); font-weight: bold; color: var(--primary); } .checkbox-group { display: flex; flex-direction: column; gap: 0.5rem; } .checkbox-item { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; padding: 0.3rem 0; } .checkbox { position: relative; width: 20px; height: 20px; border: 2px solid #e0e0e0; border-radius: 4px; transition: all 0.2s ease; } .checkbox.checked { background-color: var(--primary); border-color: var(--primary); } .checkbox.checked:after { content: ''; position: absolute; top: 2px; left: 6px; width: 5px; height: 10px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } .toggle-group { display: flex; gap: 1rem; } .toggle-option { flex: 1; padding: 0.6rem 0.5rem; text-align: center; border-radius: 8px; cursor: pointer; font-size: 0.85rem; transition: all 0.2s ease; border: 1px solid transparent; } .toggle-option:hover { background-color: rgba(107, 143, 175, 0.05); } .toggle-option.selected { background-color: rgba(107, 143, 175, 0.1); border-color: var(--primary); color: var(--primary); font-weight: bold; } .slider-container { width: 100%; padding: 0.5rem 0; } .slider-range { width: 100%; -webkit-appearance: none; height: 6px; border-radius: 5px; background: #e0e0e0; outline: none; margin: 0.75rem 0; } .slider-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 50%; background: var(--primary); cursor: pointer; border: 2px solid white; box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); transition: transform 0.2s ease; } .slider-range::-webkit-slider-thumb:hover { transform: scale(1.2); } .slider-labels { display: flex; justify-content: space-between; font-size: 0.8rem; color: var(--text); opacity: 0.7; } .button-group { display: flex; gap: 1rem; margin-top: 1rem; justify-content: flex-end; } .btn { padding: 0.75rem 1.5rem; border: none; border-radius: 8px; cursor: pointer; font-size: 1rem; transition: all 0.2s ease; } .btn-reset { background-color: transparent; color: var(--text); border: 1px solid #e0e0e0; } .btn-reset:hover { background-color: rgba(0, 0, 0, 0.05); } .btn-apply { background-color: var(--primary); color: white; } .btn-apply:hover { background-color: #5a7b99; transform: translateY(-2px); box-shadow: 0 4px 10px rgba(107, 143, 175, 0.3); } .results-section { flex: 1; overflow-y: auto; padding-right: 5px; } .results-section h2 { margin-bottom: 1rem; display: flex; justify-content: space-between; align-items: center; padding-bottom: 0.5rem; border-bottom: 1px solid #e0e0e0; } .results-count { font-size: 0.9rem; color: var(--primary); background-color: rgba(107, 143, 175, 0.1); padding: 0.3rem 0.8rem; border-radius: 20px; } .course-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1.5rem; padding-bottom: 2rem; } .course-card { background-color: var(--white); border-radius: 12px; overflow: hidden; box-shadow: 0 4px 12px var(--shadow); transition: all 0.3s ease; display: flex; flex-direction: column; height: 100%; } .course-card:hover { transform: translateY(-5px); box-shadow: 0 10px 25px var(--shadow-hover); } .course-image { height: 120px; position: relative; overflow: hidden; } .course-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .course-card:hover .course-image img { transform: scale(1.05); } .difficulty-badge { position: absolute; bottom: 10px; left: 10px; padding: 0.2rem 0.75rem; border-radius: 20px; font-size: 0.7rem; font-weight: bold; text-transform: uppercase; letter-spacing: 0.5px; } .difficulty-beginner { background-color: #a8e6cf; color: #2d6a4f; } .difficulty-intermediate { background-color: #ffd3b6; color: #8a5a44; } .difficulty-advanced { background-color: #ffaaa5; color: #8b2e28; } .course-details { padding: 1rem; flex: 1; display: flex; flex-direction: column; } .course-title { font-size: 1rem; margin-bottom: 0.5rem; line-height: 1.3; } .course-subject { font-size: 0.8rem; color: var(--text); opacity: 0.7; margin-bottom: 0.75rem; } .course-footer { display: flex; justify-content: space-between; align-items: center; margin-top: auto; } .course-rating { display: flex; align-items: center; gap: 0.3rem; } .rating-stars { color: #ffc107; font-size: 0.9rem; } .rating-value { font-size: 0.8rem; font-weight: bold; } .course-duration { font-size: 0.8rem; color: var(--text); opacity: 0.8; } /* Animated dot dots */ .dot-pulse { position: relative; left: -9999px; width: 8px; height: 8px; border-radius: 5px; background-color: var(--primary); color: var(--primary); box-shadow: 9999px 0 0 -5px; animation: dot-pulse 1.5s infinite linear; animation-delay: 0.25s; display: inline-block; margin-left: 5px; } .dot-pulse::before, .dot-pulse::after { content: ''; display: inline-block; position: absolute; top: 0; width: 8px; height: 8px; border-radius: 5px; background-color: var(--primary); color: var(--primary); } .dot-pulse::before { box-shadow: 9984px 0 0 -5px; animation: dot-pulse-before 1.5s infinite linear; animation-delay: 0s; } .dot-pulse::after { box-shadow: 10014px 0 0 -5px; animation: dot-pulse-after 1.5s infinite linear; animation-delay: 0.5s; } @keyframes dot-pulse-before { 0% { box-shadow: 9984px 0 0 -5px; } 30% { box-shadow: 9984px 0 0 2px; } 60%, 100% { box-shadow: 9984px 0 0 -5px; } } @keyframes dot-pulse { 0% { box-shadow: 9999px 0 0 -5px; } 30% { box-shadow: 9999px 0 0 2px; } 60%, 100% { box-shadow: 9999px 0 0 -5px; } } @keyframes dot-pulse-after { 0% { box-shadow: 10014px 0 0 -5px; } 30% { box-shadow: 10014px 0 0 2px; } 60%, 100% { box-shadow: 10014px 0 0 -5px; } } .loading { display: flex; justify-content: center; align-items: center; height: 100px; } .loading span { margin-right: 10px; } /* Scrollbar styling */ .results-section::-webkit-scrollbar { width: 8px; } .results-section::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.03); border-radius: 4px; } .results-section::-webkit-scrollbar-thumb { background-color: rgba(107, 143, 175, 0.3); border-radius: 4px; } .results-section::-webkit-scrollbar-thumb:hover { background-color: rgba(107, 143, 175, 0.5); } /* Soft animations */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .course-card { animation: fadeIn 0.5s ease-out forwards; } .course-card:nth-child(2) { animation-delay: 0.1s; } .course-card:nth-child(3) { animation-delay: 0.2s; } .course-card:nth-child(4) { animation-delay: 0.3s; } .course-card:nth-child(5) { animation-delay: 0.4s; } .course-card:nth-child(6) { animation-delay: 0.5s; } .filters-applied { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 1rem; } .filter-tag { background-color: rgba(107, 143, 175, 0.1); border: 1px solid rgba(107, 143, 175, 0.3); padding: 0.3rem 0.6rem; border-radius: 20px; font-size: 0.8rem; display: flex; align-items: center; gap: 0.3rem; animation: fadeIn 0.3s ease forwards; } .filter-tag i { font-size: 0.7rem; cursor: pointer; color: var(--primary); } .filter-tag i:hover { color: #d13c3c; } @media (max-width: 600px) { .filter-row { flex-direction: column; gap: 1rem; } .filter-group { min-width: 100%; } .course-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } .header h1 { font-size: 1.7rem; } } /* Toast notification */ .toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%) translateY(100px); background-color: var(--primary); color: white; padding: 0.75rem 1.5rem; border-radius: 8px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15); z-index: 1000; opacity: 0; transition: all 0.3s ease; } .toast.show { transform: translateX(-50%) translateY(0); opacity: 1; } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"> </head> <body> <div class="container"> <div class="header"> <h1>Find Your Perfect Learning Path</h1> <p>Filter through our carefully curated courses designed to meet your educational needs</p> </div> <div class="filter-section"> <div class="filter-row"> <div class="filter-group"> <h3><i class="fas fa-layer-group"></i> Difficulty Level</h3> <div class="checkbox-group"> <div class="checkbox-item" data-value="beginner"> <div class="checkbox"></div> <span>Beginner</span> </div> <div class="checkbox-item" data-value="intermediate"> <div class="checkbox"></div> <span>Intermediate</span> </div> <div class="checkbox-item" data-value="advanced"> <div class="checkbox"></div> <span>Advanced</span> </div> </div> </div> <div class="filter-group"> <h3><i class="fas fa-book"></i> Subject</h3> <div class="dropdown-container"> <div class="dropdown-select"> <span>All Subjects</span> <i class="fas fa-chevron-down"></i> </div> <div class="dropdown-options"> <div class="dropdown-option selected" data-value="all">All Subjects</div> <div class="dropdown-option" data-value="computer-science">Computer Science</div> <div class="dropdown-option" data-value="mathematics">Mathematics</div> <div class="dropdown-option" data-value="literature">Literature</div> <div class="dropdown-option" data-value="science">Science</div> <div class="dropdown-option" data-value="history">History</div> <div class="dropdown-option" data-value="arts">Arts</div> <div class="dropdown-option" data-value="language">Language</div> </div> </div> </div> </div> <div class="filter-row"> <div class="filter-group"> <h3><i class="fas fa-star"></i> Minimum Rating</h3> <div class="slider-container"> <input type="range" min="1" max="5" value="3" step="0.5" class="slider-range" id="rating-slider"> <div class="slider-labels"> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> </div> </div> </div> <div class="filter-group"> <h3><i class="fas fa-clock"></i> Course Duration</h3> <div class="toggle-group"> <div class="toggle-option" data-value="short">Short</div> <div class="toggle-option selected" data-value="any">Any</div> <div class="toggle-option" data-value="long">Long</div> </div> </div> </div> <div class="button-group"> <button class="btn btn-reset" id="reset-filters">Reset</button> <button class="btn btn-apply" id="apply-filters">Apply Filters</button> </div> </div> <div class="results-section"> <h2> <span>Course Results</span> <span class="results-count">12 courses</span> </h2> <div class="filters-applied" id="filters-applied"> <!-- Filter tags will be added here dynamically --> </div> <div class="course-grid" id="course-grid"> <!-- Course cards will be inserted here --> </div> </div> </div> <div class="toast" id="toast">Filters applied successfully!</div> <script> document.addEventListener('DOMContentLoaded', function() { // Elements const checkboxItems = document.querySelectorAll('.checkbox-item'); const dropdownSelects = document.querySelectorAll('.dropdown-select'); const dropdownOptions = document.querySelectorAll('.dropdown-option'); const toggleOptions = document.querySelectorAll('.toggle-option'); const applyFiltersBtn = document.getElementById('apply-filters'); const resetFiltersBtn = document.getElementById('reset-filters'); const ratingSlider = document.getElementById('rating-slider'); const courseGrid = document.getElementById('course-grid'); const toast = document.getElementById('toast'); const filtersApplied = document.getElementById('filters-applied'); // Initialize active filters object let activeFilters = { difficulty: [], subject: 'all', rating: 3, duration: 'any' }; // Sample course data const courseData = [ { id: 1, title: "Introduction to Python Programming", subject: "Computer Science", subjectCode: "computer-science", difficulty: "beginner", rating: 4.8, duration: "4 weeks", durationType: "short", image: "https://images.unsplash.com/photo-1515879218367-8466d910aaa4?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 2, title: "Advanced Calculus and Linear Algebra", subject: "Mathematics", subjectCode: "mathematics", difficulty: "advanced", rating: 4.5, duration: "12 weeks", durationType: "long", image: "https://images.unsplash.com/photo-1635070041078-e363dbe005cb?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 3, title: "Classical Literature Analysis", subject: "Literature", subjectCode: "literature", difficulty: "intermediate", rating: 4.2, duration: "8 weeks", durationType: "medium", image: "https://images.unsplash.com/photo-1491841550275-ad7854e35ca6?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 4, title: "Fundamentals of Physics", subject: "Science", subjectCode: "science", difficulty: "beginner", rating: 4.7, duration: "6 weeks", durationType: "medium", image: "https://images.unsplash.com/photo-1636466497217-26a8cbeaf0aa?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 5, title: "Medieval European History", subject: "History", subjectCode: "history", difficulty: "intermediate", rating: 3.9, duration: "10 weeks", durationType: "long", image: "https://images.unsplash.com/photo-1461360370896-922624d12aa1?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 6, title: "Digital Painting Techniques", subject: "Arts", subjectCode: "arts", difficulty: "beginner", rating: 4.6, duration: "3 weeks", durationType: "short", image: "https://images.unsplash.com/photo-1547891654-e66ed7ebb968?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 7, title: "Machine Learning for Data Science", subject: "Computer Science", subjectCode: "computer-science", difficulty: "advanced", rating: 4.9, duration: "14 weeks", durationType: "long", image: "https://images.unsplash.com/photo-1620712943543-bcc4688e7485?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 8, title: "Spanish for Beginners", subject: "Language", subjectCode: "language", difficulty: "beginner", rating: 4.3, duration: "5 weeks", durationType: "short", image: "https://images.unsplash.com/photo-1551018612-9715965c6742?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 9, title: "Introduction to Graphic Design", subject: "Arts", subjectCode: "arts", difficulty: "beginner", rating: 4.0, duration: "6 weeks", durationType: "medium", image: "https://images.unsplash.com/photo-1626785774573-4b799315345d?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 10, title: "Organic Chemistry", subject: "Science", subjectCode: "science", difficulty: "advanced", rating: 3.8, duration: "16 weeks", durationType: "long", image: "https://images.unsplash.com/photo-1603126857599-f6e157fa2fe6?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 11, title: "Modern World History", subject: "History", subjectCode: "history", difficulty: "intermediate", rating: 4.4, duration: "8 weeks", durationType: "medium", image: "https://images.unsplash.com/photo-1447069387593-a5de0862481e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" }, { id: 12, title: "Web Development Bootcamp", subject: "Computer Science", subjectCode: "computer-science", difficulty: "intermediate", rating: 4.7, duration: "10 weeks", durationType: "long", image: "https://images.unsplash.com/photo-1593720213428-28a5b9e94613?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80" } ]; // Initialize the course grid renderCourses(courseData); // Checkbox functionality checkboxItems.forEach(item => { item.addEventListener('click', () => { const checkbox = item.querySelector('.checkbox'); const value = item.dataset.value; checkbox.classList.toggle('checked'); if (checkbox.classList.contains('checked')) { if (!activeFilters.difficulty.includes(value)) { activeFilters.difficulty.push(value); } } else { activeFilters.difficulty = activeFilters.difficulty.filter(v => v !== value); } }); }); // Dropdown functionality dropdownSelects.forEach(select => { select.addEventListener('click', () => { const options = select.nextElementSibling; select.classList.toggle('active'); options.classList.toggle('active'); document.addEventListener('click', function closeDropdown(e) { if (!select.contains(e.target) && !options.contains(e.target)) { select.classList.remove('active'); options.classList.remove('active'); document.removeEventListener('click', closeDropdown); } }); }); }); dropdownOptions.forEach(option => { option.addEventListener('click', () => { const select = option.closest('.dropdown-container').querySelector('.dropdown-select'); const selectText = select.querySelector('span'); const options = option.closest('.dropdown-options'); const allOptions = options.querySelectorAll('.dropdown-option'); allOptions.forEach(opt => opt.classList.remove('selected')); option.classList.add('selected'); selectText.textContent = option.textContent; select.classList.remove('active'); options.classList.remove('active'); activeFilters.subject = option.dataset.value; }); }); // Toggle options functionality toggleOptions.forEach(option => { option.addEventListener('click', () => { const parent = option.closest('.toggle-group'); parent.querySelectorAll('.toggle-option').forEach(opt => { opt.classList.remove('selected'); }); option.classList.add('selected'); activeFilters.duration = option.dataset.value; }); }); // Slider functionality ratingSlider.addEventListener('input', function() { activeFilters.rating = parseFloat(this.value); }); // Apply filters button applyFiltersBtn.addEventListener('click', () => { const filteredCourses = filterCourses(courseData, activeFilters); showLoading(); setTimeout(() => { renderCourses(filteredCourses); renderAppliedFilters(); showToast("Filters applied successfully!"); document.querySelector('.results-count').textContent = `${filteredCourses.length} courses`; }, 800); }); // Reset filters button resetFiltersBtn.addEventListener('click', () => { // Reset all filters checkboxItems.forEach(item => { item.querySelector('.checkbox').classList.remove('checked'); }); document.querySelector('.dropdown-select span').textContent = 'All Subjects'; document.querySelectorAll('.dropdown-option').forEach(option => { option.classList.remove('selected'); if (option.dataset.value === 'all') { option.classList.add('selected'); } }); toggleOptions.forEach(option => { option.classList.remove('selected'); if (option.dataset.value === 'any') { option.classList.add('selected'); } }); ratingSlider.value = 3; // Reset active filters activeFilters = { difficulty: [], subject: 'all', rating: 3, duration: 'any' }; // Show all courses showLoading(); setTimeout(() => { renderCourses(courseData); renderAppliedFilters(); showToast("Filters have been reset!"); document.querySelector('.results-count').textContent = `${courseData.length} courses`; }, 800); }); // Filter courses based on active filters function filterCourses(courses, filters) { return courses.filter(course => { // Filter by difficulty if (filters.difficulty.length > 0 && !filters.difficulty.includes(course.difficulty)) { return false; } // Filter by subject if (filters.subject !== 'all' && course.subjectCode !== filters.subject) { return false; } // Filter by rating if (course.rating < filters.rating) { return false; } // Filter by duration if (filters.duration !== 'any') { if (filters.duration === 'short' && course.durationType !== 'short') { return false; } if (filters.duration === 'long' && course.durationType !== 'long') { return false; } } return true; }); } // Render courses to the grid function renderCourses(courses) { courseGrid.innerHTML = ''; if (courses.length === 0) { courseGrid.innerHTML = ` <div class="no-results" style="grid-column: 1/-1; text-align: center; padding: 2rem;"> <i class="fas fa-search" style="font-size: 2rem; color: var(--primary); opacity: 0.3; margin-bottom: 1rem;"></i> <h3>No courses match your filters</h3> <p style="margin-top: 0.5rem; opacity: 0.7;">Try adjusting your search criteria</p> </div> `; return; } courses.forEach((course, index) => { const card = document.createElement('div'); card.className = 'course-card'; card.style.animationDelay = `${index * 0.1}s`; card.innerHTML = ` <div class="course-image"> <img src="${course.image}" alt="${course.title}"> <div class="difficulty-badge difficulty-${course.difficulty}">${course.difficulty}</div> </div> <div class="course-details"> <h3 class="course-title">${course.title}</h3> <div class="course-subject">${course.subject}</div> <div class="course-footer"> <div class="course-rating"> <div class="rating-stars"> ${getRatingStars(course.rating)} </div> <div class="rating-value">${course.rating}</div> </div> <div class="course-duration"> <i class="far fa-clock"></i> ${course.duration} </div> </div> </div> `; courseGrid.appendChild(card); }); } // Helper function to generate rating stars function getRatingStars(rating) { const fullStars = Math.floor(rating); const halfStar = rating % 1 >= 0.5; const emptyStars = 5 - fullStars - (halfStar ? 1 : 0); let stars = ''; for (let i =
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vibrant Event Finder</title> <style> :root { --primary: #FF3E6C; --secondary: #4B56D2; --tertiary: #FFB100; --dark: #1E1E2C; --light: #F8F9FA; --accent: #00C2CB; --success: #57CC99; --background: #f6f7f9; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } body { background-color: var(--background); color: var(--dark); max-width: 700px; max-height: 700px; overflow-x: hidden; margin: 0 auto; } .container { padding: 20px; width: 100%; height: 100vh; max-height: 700px; display: flex; flex-direction: column; } header { margin-bottom: 15px; } h1 { font-size: 2rem; font-weight: 700; background: linear-gradient(to right, var(--primary), var(--secondary)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 8px; } .tagline { font-size: 1rem; color: #666; margin-bottom: 15px; } /* Filter section */ .filter-container { display: flex; flex-direction: column; gap: 15px; margin-bottom: 20px; } .filter-section { background-color: white; border-radius: 12px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.07); padding: 15px; transition: all 0.3s ease; } .filter-section:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1); } .filter-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; cursor: pointer; } .filter-title { font-weight: 600; color: var(--dark); display: flex; align-items: center; gap: 8px; } .filter-title i { font-size: 1.2rem; color: var(--primary); } .toggle-icon { transition: transform 0.3s ease; } .filter-content { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; } .filter-section.active .filter-content { max-height: 300px; } .filter-section.active .toggle-icon { transform: rotate(180deg); } /* Date filter */ .date-picker { display: flex; gap: 10px; flex-wrap: wrap; } .date-picker input { flex: 1; min-width: 130px; padding: 10px; border: 1px solid #ddd; border-radius: 8px; font-size: 14px; } /* Category filter */ .category-options { display: flex; flex-wrap: wrap; gap: 10px; } .category-tag { padding: 8px 15px; border-radius: 50px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; background-color: #f0f0f0; } .category-tag:hover { transform: scale(1.05); } .category-tag.active { color: white; animation: pulse 1.5s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(255, 62, 108, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(255, 62, 108, 0); } 100% { box-shadow: 0 0 0 0 rgba(255, 62, 108, 0); } } /* Location filter */ .location-search { position: relative; } .location-search input { width: 100%; padding: 12px 15px; border: 1px solid #ddd; border-radius: 8px; font-size: 14px; padding-left: 35px; } .location-search i { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: #666; } .recent-locations { margin-top: 10px; } .recent-location { display: inline-block; padding: 6px 12px; background-color: #f0f0f0; border-radius: 4px; margin-right: 8px; margin-bottom: 8px; font-size: 13px; cursor: pointer; transition: all 0.2s ease; } .recent-location:hover { background-color: #e0e0e0; } /* Apply filters button */ .apply-filters { background: linear-gradient(to right, var(--primary), var(--secondary)); color: white; border: none; padding: 14px 20px; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: 5px; position: relative; overflow: hidden; } .apply-filters:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(75, 86, 210, 0.4); } .apply-filters::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: 0.5s; } .apply-filters:hover::before { left: 100%; } /* Results section */ .results-container { flex: 1; overflow-y: auto; scrollbar-width: thin; padding-right: 5px; } .results-container::-webkit-scrollbar { width: 5px; } .results-container::-webkit-scrollbar-track { background: #f1f1f1; } .results-container::-webkit-scrollbar-thumb { background: #ddd; border-radius: 5px; } .results-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .results-count { font-weight: 600; color: var(--dark); } .sort-options { position: relative; } .sort-btn { display: flex; align-items: center; gap: 5px; background: none; border: none; color: var(--secondary); cursor: pointer; font-weight: 500; } .sort-dropdown { position: absolute; top: 100%; right: 0; background: white; border-radius: 8px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); min-width: 150px; z-index: 10; transform-origin: top right; transform: scale(0); opacity: 0; transition: all 0.2s ease; } .sort-dropdown.active { transform: scale(1); opacity: 1; } .sort-option { padding: 10px 15px; cursor: pointer; transition: background 0.2s ease; } .sort-option:hover { background-color: #f5f5f5; } /* Event cards */ .event-cards { display: grid; grid-template-columns: 1fr; gap: 15px; margin-top: 10px; } .event-card { background-color: white; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.07); display: flex; transition: all 0.3s ease; position: relative; } .event-card:hover { transform: translateY(-3px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12); } .event-image { width: 100px; min-width: 100px; height: 100%; object-fit: cover; border-radius: 12px 0 0 12px; } .event-details { padding: 15px; flex: 1; } .event-category { display: inline-block; padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: 500; margin-bottom: 8px; color: white; } .event-title { font-weight: 600; margin-bottom: 5px; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; } .event-info { display: flex; align-items: center; gap: 15px; font-size: 13px; color: #666; margin-top: 5px; } .event-info div { display: flex; align-items: center; gap: 5px; } .event-info i { font-size: 14px; } .event-price { position: absolute; top: 15px; right: 15px; font-weight: 600; color: var(--primary); } /* Category colors */ .cat-music { background-color: var(--primary); } .cat-sports { background-color: var(--secondary); } .cat-food { background-color: var(--tertiary); } .cat-arts { background-color: var(--accent); } .cat-tech { background-color: var(--success); } /* Loading animation */ .loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.8); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 0; visibility: hidden; transition: all 0.3s ease; } .loading-overlay.active { opacity: 1; visibility: visible; } .spinner { width: 50px; height: 50px; border: 5px solid rgba(255, 62, 108, 0.2); border-radius: 50%; border-top-color: var(--primary); animation: spin 0.8s linear infinite; } @keyframes spin { 100% { transform: rotate(360deg); } } /* Active filters indicator */ .active-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 15px; } .active-filter-tag { display: flex; align-items: center; gap: 5px; padding: 5px 10px; background: var(--primary); color: white; border-radius: 4px; font-size: 13px; animation: fadeIn 0.3s; } .active-filter-tag i { cursor: pointer; } @keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } } /* Empty state */ .empty-state { display: none; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 30px; color: #666; } .empty-state i { font-size: 3rem; color: var(--primary); margin-bottom: 15px; } .empty-state h3 { margin-bottom: 10px; color: var(--dark); } /* Responsive adjustments */ @media (max-width: 500px) { .event-image { width: 80px; min-width: 80px; } h1 { font-size: 1.7rem; } .filter-title, .results-count { font-size: 0.9rem; } } @media (max-width: 400px) { .container { padding: 15px; } .event-image { width: 70px; min-width: 70px; } .event-details { padding: 10px; } .event-info { flex-direction: column; align-items: flex-start; gap: 5px; } } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet"> </head> <body> <div class="container"> <header> <h1>Find Your Vibe</h1> <p class="tagline">Discover local events perfectly matched to your interests</p> </header> <div class="filter-container"> <div class="filter-section" id="dateFilter"> <div class="filter-header"> <div class="filter-title"> <i class="fas fa-calendar-alt"></i> When do you want to go? </div> <i class="fas fa-chevron-down toggle-icon"></i> </div> <div class="filter-content"> <div class="date-picker"> <input type="date" id="startDate" placeholder="Start Date"> <input type="date" id="endDate" placeholder="End Date"> </div> </div> </div> <div class="filter-section" id="categoryFilter"> <div class="filter-header"> <div class="filter-title"> <i class="fas fa-tags"></i> What are you into? </div> <i class="fas fa-chevron-down toggle-icon"></i> </div> <div class="filter-content"> <div class="category-options"> <div class="category-tag" data-category="music">Music</div> <div class="category-tag" data-category="sports">Sports</div> <div class="category-tag" data-category="food">Food & Drink</div> <div class="category-tag" data-category="arts">Arts & Culture</div> <div class="category-tag" data-category="tech">Tech & Innovation</div> </div> </div> </div> <div class="filter-section" id="locationFilter"> <div class="filter-header"> <div class="filter-title"> <i class="fas fa-map-marker-alt"></i> Where's the action? </div> <i class="fas fa-chevron-down toggle-icon"></i> </div> <div class="filter-content"> <div class="location-search"> <i class="fas fa-search"></i> <input type="text" id="locationInput" placeholder="Search by city or neighborhood"> </div> <div class="recent-locations"> <div class="recent-location">Downtown</div> <div class="recent-location">Midtown</div> <div class="recent-location">East Side</div> <div class="recent-location">West End</div> </div> </div> </div> <button class="apply-filters" id="applyFiltersBtn"> <i class="fas fa-filter"></i> Apply Filters </button> </div> <div class="active-filters" id="activeFilters"></div> <div class="results-container"> <div class="results-header"> <div class="results-count">12 events found</div> <div class="sort-options"> <button class="sort-btn" id="sortBtn"> <span>Date: Soonest</span> <i class="fas fa-caret-down"></i> </button> <div class="sort-dropdown" id="sortDropdown"> <div class="sort-option" data-sort="date-asc">Date: Soonest</div> <div class="sort-option" data-sort="date-desc">Date: Latest</div> <div class="sort-option" data-sort="price-asc">Price: Low to High</div> <div class="sort-option" data-sort="price-desc">Price: High to Low</div> </div> </div> </div> <div class="event-cards" id="eventCards"> <!-- Event cards will be populated here by JS --> </div> <div class="empty-state" id="emptyState"> <i class="fas fa-search"></i> <h3>No events match your filters</h3> <p>Try adjusting your filters or search criteria to find more events</p> </div> </div> </div> <div class="loading-overlay" id="loadingOverlay"> <div class="spinner"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Sample event data const events = [ { id: 1, title: "Summer Block Party Festival", category: "music", date: "2023-07-15", time: "17:00", location: "Downtown", price: "$25", image: "https://images.unsplash.com/photo-1459749411175-04bf5292ceea?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3" }, { id: 2, title: "Championship Basketball Finals", category: "sports", date: "2023-07-18", time: "19:30", location: "Midtown Arena", price: "$40", image: "https://images.unsplash.com/photo-1504450758481-7338eba7524a?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3" }, { id: 3, title: "Craft Beer & Food Truck Rally", category: "food", date: "2023-07-22", time: "12:00", location: "East Side Park", price: "$10", image: "https://images.unsplash.com/photo-1555658636-6e4a36218be7?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3" }, { id: 4, title: "Pop-Up Art Gallery Opening", category: "arts", date: "2023-07-25", time: "18:00", location: "West End", price: "Free", image: "https://images.unsplash.com/photo-1531058020387-3be344556be6?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3" }, { id: 5, title: "Tech Startup Pitch Competition", category: "tech", date: "2023-07-27", time: "13:00", location: "Innovation Hub", price: "$15", image: "https://images.unsplash.com/photo-1551818255-e6e10975bc17?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3" }, { id: 6, title: "Underground Jazz Club Night", category: "music", date: "2023-07-29", time: "21:00", location: "Downtown", price: "$20", image: "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3" }, { id: 7, title: "Weekend Kayaking Excursion", category: "sports", date: "2023-08-05", time: "09:00", location: "Riverfront", price: "$35", image: "https://images.unsplash.com/photo-1472745942893-4b9f730c7668?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3" }, { id: 8, title: "Rooftop Cocktail Masterclass", category: "food", date: "2023-08-10", time: "18:30", location: "Midtown", price: "$50", image: "https://images.unsplash.com/photo-1536935338788-846bb9981813?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3" } ]; // Initialize elements const filterSections = document.querySelectorAll('.filter-section'); const categoryTags = document.querySelectorAll('.category-tag'); const recentLocations = document.querySelectorAll('.recent-location'); const sortBtn = document.getElementById('sortBtn'); const sortDropdown = document.getElementById('sortDropdown'); const sortOptions = document.querySelectorAll('.sort-option'); const applyFiltersBtn = document.getElementById('applyFiltersBtn'); const loadingOverlay = document.getElementById('loadingOverlay'); const activeFiltersContainer = document.getElementById('activeFilters'); const eventCardsContainer = document.getElementById('eventCards'); const emptyState = document.getElementById('emptyState'); const resultsCount = document.querySelector('.results-count'); const locationInput = document.getElementById('locationInput'); const startDate = document.getElementById('startDate'); const endDate = document.getElementById('endDate'); // Set initial active filter states let activeFilters = { categories: [], locations: [], dateRange: { start: null, end: null } }; // Initialize event display displayEvents(events); // Toggle filter sections filterSections.forEach(section => { const header = section.querySelector('.filter-header'); header.addEventListener('click', () => { section.classList.toggle('active'); }); }); // Category tag selection categoryTags.forEach(tag => { tag.addEventListener('click', () => { tag.classList.toggle('active'); const category = tag.dataset.category; if (tag.classList.contains('active')) { // Add category style based on data attribute tag.style.backgroundColor = getCategoryColor(category); // Add to active filters if not already there if (!activeFilters.categories.includes(category)) { activeFilters.categories.push(category); } } else { tag.style.backgroundColor = ''; // Remove from active filters activeFilters.categories = activeFilters.categories.filter(cat => cat !== category); } }); }); // Location selection recentLocations.forEach(loc => { loc.addEventListener('click', () => { const location = loc.textContent; locationInput.value = location; // Update active filters if (!activeFilters.locations.includes(location)) { activeFilters.locations = [location]; // Replace with new location } }); }); // Location input handling locationInput.addEventListener('keyup', (e) => { if (e.key === 'Enter' && locationInput.value.trim() !== '') { const location = locationInput.value.trim(); // Update active filters if (!activeFilters.locations.includes(location)) { activeFilters.locations = [location]; // Replace with new location } } }); // Date range selection startDate.addEventListener('change', () => { activeFilters.dateRange.start = startDate.value || null; }); endDate.addEventListener('change', () => { activeFilters.dateRange.end = endDate.value || null; }); // Sort functionality sortBtn.addEventListener('click', (e) => { e.stopPropagation(); sortDropdown.classList.toggle('active'); }); // Close sort dropdown when clicking outside document.addEventListener('click', (e) => { if (!sortBtn.contains(e.target)) { sortDropdown.classList.remove('active'); } }); // Handle sort option selection sortOptions.forEach(option => { option.addEventListener('click', () => { const sortValue = option.dataset.sort; const sortText = option.textContent; sortBtn.querySelector('span').textContent = sortText; sortDropdown.classList.remove('active'); // Apply sorting sortEvents(sortValue); }); }); // Apply filters button applyFiltersBtn.addEventListener('click', () => { // Show loading state loadingOverlay.classList.add('active'); // Update active filters display updateActiveFiltersDisplay(); // Simulate loading delay setTimeout(() => { // Apply filters to events const filteredEvents = filterEvents(events, activeFilters); // Display filtered events displayEvents(filteredEvents); // Hide loading state loadingOverlay.classList.remove('active'); // Open all sections filterSections.forEach(section => { section.classList.remove('active'); }); }, 800); }); // Function to filter events based on active filters function filterEvents(eventsList, filters) { return eventsList.filter(event => { // Category filter if (filters.categories.length > 0 && !filters.categories.includes(event.category)) { return false; } // Location filter if (filters.locations.length > 0 && !filters.locations.some(loc => event.location.includes(loc))) { return false; } // Date range filter if (filters.dateRange.start && new Date(event.date) < new Date(filters.dateRange.start)) { return false; } if (filters.dateRange.end && new Date(event.date) > new Date(filters.dateRange.end)) { return false; } return true; }); } // Function to sort events function sortEvents(sortValue) { const currentEvents = Array.from(eventCardsContainer.querySelectorAll('.event-card')); currentEvents.sort((a, b) => { const aDate = new Date(a.dataset.date); const bDate = new Date(b.dataset.date); const aPrice = parsePrice(a.dataset.price); const bPrice = parsePrice(b.dataset.price); switch(sortValue) { case 'date-asc': return aDate - bDate; case 'date-desc': return bDate - aDate; case 'price-asc': return aPrice - bPrice; case 'price-desc': return bPrice - aPrice; default: return 0; } }); // Clear and re-append sorted events eventCardsContainer.innerHTML = ''; currentEvents.forEach(event => { eventCardsContainer.appendChild(event); }); } // Function to parse price string to number function parsePrice(priceStr) { if (priceStr === 'Free') return 0; return parseInt(priceStr.replace('$', '')) || 0; } // Function to update active filters display function updateActiveFiltersDisplay() { activeFiltersContainer.innerHTML = ''; // Add category filters activeFilters.categories.forEach(category => { addActiveFilterTag(getCategoryName(category), 'category', category); }); // Add location filters activeFilters.locations.forEach(location => { addActiveFilterTag(location, 'location'); }); // Add date range filter if (activeFilters.dateRange.start || activeFilters.dateRange.end) { let dateText = ''; if (activeFilters.dateRange.start && activeFilters.dateRange.end) { dateText = `${formatDate(activeFilters.dateRange.start)} - ${formatDate(activeFilters.dateRange.end)}`; } else if (activeFilters.dateRange.start) { dateText = `From ${formatDate(activeFilters.dateRange.start)}`; } else if (activeFilters.dateRange.end) { dateText = `Until ${formatDate(activeFilters.dateRange.end)}`; } addActiveFilterTag(dateText, 'date'); } } // Function to add an active filter tag function addActiveFilterTag(text, type, value) { const tag = document.createElement('div'); tag.className = 'active-filter-tag'; tag.innerHTML = `${text} <i class="fas fa-times"></i>`; // Handle remove filter tag.querySelector('i').addEventListener('click', () => { tag.remove(); // Remove from active filters if (type === 'category' && value) { activeFilters.categories = activeFilters.categories.filter(cat => cat !== value); // Unselect category tag in UI document.querySelector(`.category-tag[data-category="${value}"]`).classList.remove('active'); document.querySelector(`.category-tag[data-category="${value}"]`).style.backgroundColor = ''; } if (type === 'location') { activeFilters.locations = activeFilters.locations.filter(loc => loc !== text); locationInput.value = ''; } if (type === 'date') { activeFilters.dateRange.start = null; activeFilters.dateRange.end = null; startDate.value = ''; endDate.value = ''; } // Apply filters immediately on removal applyFiltersBtn.click(); }); activeFiltersContainer.appendChild(tag); } // Function to display events function displayEvents(eventsList) { eventCardsContainer.innerHTML = ''; if (eventsList.length === 0) { emptyState.style.display = 'flex'; resultsCount.textContent = '0 events found'; } else { emptyState.style.display = 'none'; resultsCount.textContent = `${eventsList.length} events found`; eventsList.forEach((event, index) => { const card = createEventCard(event); // Add staggered fade-in animation setTimeout(() => { eventCardsContainer.appendChild(card); card.style.opacity = 1; }, index * 100); }); } } // Function to create an event card function createEventCard(event) { const card = document.createElement('div'); card.className = 'event-card'; card.style.opacity = 0; card.style.transition = 'opacity 0.3s ease'; card.dataset.date = event.date; card.dataset.price = event.price; card.innerHTML = ` <img src="${event.image}" alt="${event.title}" class="event-image"> <div class="event-details"> <span class="event-category cat-${event.category}">${getCategoryName(event.category)}</span> <h3 class="event-title">${event.title}</h3> <div class="event-info"> <div> <i class="far fa-calendar"></i> <span>${formatDate(event.date)}</span> </div> <div> <i class="far fa-clock"></i> <span>${formatTime(event.time)}</span> </div> <div> <i class="fas fa-map-marker-alt"></i> <span>${event.location}</span> </div> </div> <div class="event-price">${event.price}</div> </div> `; return card; } // Helper functions function getCategoryName(category) { const categoryMap = { 'music': 'Music', 'sports': 'Sports', 'food': 'Food & Drink', 'arts': 'Arts & Culture', 'tech': 'Tech & Innovation' }; return categoryMap[category] || category; } function getCategoryColor(category) { const colorMap = { 'music': '#FF3E6C', 'sports': '#4B56D2', 'food': '#FFB100', 'arts': '#00C2CB', 'tech': '#57CC99' }; return colorMap[category] || '#666'; } function formatDate(dateString) { const options = { month: 'short', day: 'numeric' }; return new Date(dateString).toLocaleDateString('en-US', options); } function formatTime(timeString) { const [hours, minutes] = timeString.split(':'); const hour = parseInt(hours); const ampm = hour >= 12 ? 'PM' : 'AM'; const formattedHour = hour % 12 || 12; return `${formattedHour}:${minutes} ${ampm}`; } // Initial setup - open first filter by default if (filterSections[0]) { filterSections[0].classList.add('active'); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Financial News Filter</title> <style> :root { --primary-dark: #1a1f2b; --secondary-dark: #232837; --accent-blue: #4da6ff; --accent-green: #3dd598; --accent-red: #f25f5c; --accent-yellow: #ffce52; --text-primary: #e9ecef; --text-secondary: #adb5bd; --shadow: 0 4px 20px rgba(0, 0, 0, 0.2); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', 'Segoe UI', Roboto, Arial, sans-serif; } body { background-color: var(--primary-dark); color: var(--text-primary); display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; } .container { width: 100%; max-width: 700px; height: 700px; padding: 25px; border-radius: 12px; background-color: var(--secondary-dark); box-shadow: var(--shadow); display: flex; flex-direction: column; overflow: hidden; position: relative; } .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .logo { display: flex; align-items: center; gap: 10px; } .logo-icon { width: 40px; height: 40px; background: linear-gradient(135deg, var(--accent-blue), var(--accent-green)); border-radius: 8px; display: flex; align-items: center; justify-content: center; } .logo-text { font-size: 24px; font-weight: 700; letter-spacing: -0.5px; } .reset-button { background: transparent; color: var(--accent-blue); border: 1px solid var(--accent-blue); padding: 8px 16px; border-radius: 6px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; } .reset-button:hover { background-color: rgba(77, 166, 255, 0.1); } .search-bar { display: flex; margin-bottom: 24px; position: relative; } .search-input { flex: 1; background-color: rgba(26, 31, 43, 0.5); border: 1px solid rgba(173, 181, 189, 0.2); border-radius: 8px; padding: 12px 16px 12px 45px; color: var(--text-primary); font-size: 15px; transition: all 0.3s ease; } .search-input:focus { outline: none; border-color: var(--accent-blue); box-shadow: 0 0 0 2px rgba(77, 166, 255, 0.2); } .search-icon { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: var(--text-secondary); } .filter-tabs { display: flex; margin-bottom: 24px; border-bottom: 1px solid rgba(173, 181, 189, 0.2); } .filter-tab { padding: 12px 24px; cursor: pointer; font-weight: 600; color: var(--text-secondary); position: relative; transition: all 0.3s ease; } .filter-tab.active { color: var(--accent-blue); } .filter-tab::after { content: ''; position: absolute; bottom: -1px; left: 0; width: 100%; height: 2px; background-color: var(--accent-blue); transform: scaleX(0); transition: transform 0.3s ease; } .filter-tab.active::after { transform: scaleX(1); } .filter-section { display: none; flex: 1; overflow-y: auto; padding-right: 10px; } .filter-section.active { display: block; } .filter-group { margin-bottom: 24px; } .filter-group-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .filter-group-title { font-size: 16px; font-weight: 600; } .filter-items { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; } .filter-item { background-color: rgba(26, 31, 43, 0.5); border-radius: 8px; padding: 12px; cursor: pointer; transition: all 0.3s ease; border: 1px solid transparent; position: relative; } .filter-item:hover { background-color: rgba(26, 31, 43, 0.8); } .filter-item.selected { border-color: var(--accent-blue); background-color: rgba(77, 166, 255, 0.1); } .filter-item-title { font-weight: 500; margin-bottom: 4px; display: flex; align-items: center; gap: 8px; } .filter-item-description { font-size: 12px; color: var(--text-secondary); } .filter-item-indicator { position: absolute; top: 12px; right: 12px; width: 16px; height: 16px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 9px; background-color: var(--accent-blue); opacity: 0; transform: scale(0); transition: all 0.3s ease; } .filter-item.selected .filter-item-indicator { opacity: 1; transform: scale(1); } .slider-container { padding: 5px 0 20px; } .slider { -webkit-appearance: none; appearance: none; width: 100%; height: 4px; background: rgba(173, 181, 189, 0.2); border-radius: 2px; outline: none; } .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; background-color: var(--accent-blue); border-radius: 50%; cursor: pointer; box-shadow: var(--shadow); transition: all 0.2s ease; } .slider::-webkit-slider-thumb:hover { transform: scale(1.1); } .slider-values { display: flex; justify-content: space-between; margin-top: 8px; font-size: 13px; color: var(--text-secondary); } .footer { margin-top: auto; display: flex; justify-content: space-between; align-items: center; padding-top: 20px; border-top: 1px solid rgba(173, 181, 189, 0.2); } .saved-filters-btn { background: transparent; color: var(--text-primary); border: 1px solid rgba(173, 181, 189, 0.3); padding: 10px 16px; border-radius: 6px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; gap: 8px; } .saved-filters-btn:hover { background-color: rgba(173, 181, 189, 0.1); } .apply-filters-btn { background: linear-gradient(135deg, var(--accent-blue), #2d8eff); color: white; border: none; padding: 12px 24px; border-radius: 6px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; gap: 8px; } .apply-filters-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(77, 166, 255, 0.3); } .apply-filters-btn .count { background-color: rgba(255, 255, 255, 0.2); padding: 2px 8px; border-radius: 12px; font-size: 12px; } .tooltip { position: absolute; background-color: var(--primary-dark); border: 1px solid rgba(173, 181, 189, 0.3); border-radius: 6px; padding: 10px 14px; font-size: 13px; max-width: 250px; z-index: 100; box-shadow: var(--shadow); opacity: 0; transform: translateY(10px); pointer-events: none; transition: all 0.3s ease; } .tooltip.visible { opacity: 1; transform: translateY(0); } .tooltip-title { font-weight: 600; margin-bottom: 5px; color: var(--accent-blue); } .tooltip-description { color: var(--text-secondary); } .toggle-switch { position: relative; display: inline-block; width: 40px; height: 20px; } .toggle-switch input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(173, 181, 189, 0.2); transition: .4s; border-radius: 34px; } .toggle-slider:before { position: absolute; content: ""; height: 16px; width: 16px; left: 2px; bottom: 2px; background-color: var(--text-primary); transition: .4s; border-radius: 50%; } input:checked + .toggle-slider { background-color: var(--accent-blue); } input:checked + .toggle-slider:before { transform: translateX(20px); } /* Custom scrollbar */ .filter-section::-webkit-scrollbar { width: 5px; } .filter-section::-webkit-scrollbar-track { background: rgba(173, 181, 189, 0.1); border-radius: 5px; } .filter-section::-webkit-scrollbar-thumb { background: rgba(173, 181, 189, 0.3); border-radius: 5px; } .filter-section::-webkit-scrollbar-thumb:hover { background: rgba(173, 181, 189, 0.5); } /* Chip styling */ .filter-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; } .filter-chip { background-color: rgba(77, 166, 255, 0.1); border: 1px solid rgba(77, 166, 255, 0.3); color: var(--accent-blue); padding: 6px 12px; border-radius: 16px; font-size: 13px; display: flex; align-items: center; gap: 8px; animation: chipEntrance 0.3s ease forwards; } .filter-chip-remove { cursor: pointer; color: var(--accent-blue); opacity: 0.7; transition: all 0.2s ease; display: flex; align-items: center; } .filter-chip-remove:hover { opacity: 1; } /* Pulse animation for new articles indicator */ .pulse { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background-color: var(--accent-green); margin-right: 6px; position: relative; } .pulse:before { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: var(--accent-green); opacity: 0.7; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.7; } 70% { transform: scale(2); opacity: 0; } 100% { transform: scale(2); opacity: 0; } } @keyframes chipEntrance { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } } /* Badge */ .badge { display: inline-flex; align-items: center; justify-content: center; padding: 2px 8px; border-radius: 12px; font-size: 11px; font-weight: 600; margin-left: 8px; } .badge-blue { background-color: rgba(77, 166, 255, 0.2); color: var(--accent-blue); } .badge-green { background-color: rgba(61, 213, 152, 0.2); color: var(--accent-green); } .badge-red { background-color: rgba(242, 95, 92, 0.2); color: var(--accent-red); } .badge-yellow { background-color: rgba(255, 206, 82, 0.2); color: var(--accent-yellow); } /* Responsive design */ @media (max-width: 600px) { .container { padding: 16px; height: 100%; border-radius: 0; } .filter-tabs { overflow-x: auto; white-space: nowrap; margin-bottom: 16px; } .filter-tab { padding: 10px 16px; font-size: 14px; } .filter-items { grid-template-columns: 1fr; } .filter-group { margin-bottom: 16px; } .footer { flex-direction: column; gap: 16px; } .saved-filters-btn, .apply-filters-btn { width: 100%; justify-content: center; } } /* Ticker Tape */ .ticker-tape { position: relative; background-color: rgba(26, 31, 43, 0.7); padding: 8px 0; overflow: hidden; margin-bottom: 20px; border-radius: 6px; } .ticker-items { display: flex; animation: tickerTape 30s linear infinite; white-space: nowrap; } .ticker-item { margin-right: 40px; display: flex; align-items: center; } .ticker-symbol { font-weight: 600; margin-right: 8px; } .ticker-price { margin-right: 5px; } .ticker-change.positive { color: var(--accent-green); } .ticker-change.negative { color: var(--accent-red); } @keyframes tickerTape { 0% { transform: translateX(0); } 100% { transform: translateX(-100%); } } /* Animations */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .animate-fade-in { animation: fadeIn 0.5s ease forwards; } </style> </head> <body> <div class="container"> <div class="header"> <div class="logo"> <div class="logo-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 20v-6M6 20V10M18 20V4"></path> </svg> </div> <div class="logo-text">FinSight</div> </div> <button class="reset-button" id="reset-filters">Reset Filters</button> </div> <div class="search-bar"> <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> <input type="text" class="search-input" placeholder="Search financial news, companies, or sectors..."> </div> <div class="ticker-tape"> <div class="ticker-items"> <div class="ticker-item"> <span class="ticker-symbol">NASDAQ</span> <span class="ticker-price">16,780.51</span> <span class="ticker-change positive">+1.24%</span> </div> <div class="ticker-item"> <span class="ticker-symbol">S&P 500</span> <span class="ticker-price">4,812.38</span> <span class="ticker-change positive">+0.87%</span> </div> <div class="ticker-item"> <span class="ticker-symbol">DOW</span> <span class="ticker-price">38,215.76</span> <span class="ticker-change positive">+0.61%</span> </div> <div class="ticker-item"> <span class="ticker-symbol">TSLA</span> <span class="ticker-price">242.18</span> <span class="ticker-change negative">-2.34%</span> </div> <div class="ticker-item"> <span class="ticker-symbol">AAPL</span> <span class="ticker-price">198.45</span> <span class="ticker-change positive">+1.08%</span> </div> <div class="ticker-item"> <span class="ticker-symbol">BTC</span> <span class="ticker-price">65,425.78</span> <span class="ticker-change positive">+3.12%</span> </div> <div class="ticker-item"> <span class="ticker-symbol">ETH</span> <span class="ticker-price">3,435.92</span> <span class="ticker-change positive">+2.75%</span> </div> <div class="ticker-item"> <span class="ticker-symbol">NVIDIA</span> <span class="ticker-price">880.32</span> <span class="ticker-change positive">+4.21%</span> </div> </div> </div> <div class="filter-chips" id="filter-chips"> <!-- Selected filters will appear here --> </div> <div class="filter-tabs"> <div class="filter-tab active" data-target="topics">Topics</div> <div class="filter-tab" data-target="regions">Regions</div> <div class="filter-tab" data-target="sectors">Market Sectors</div> <div class="filter-tab" data-target="advanced">Advanced Filters</div> </div> <div class="filter-section active" id="topics-section"> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-group-title">News Categories</div> </div> <div class="filter-items"> <div class="filter-item" data-tooltip="Breaking financial news covering major market movements, earnings reports, and economic indicators"> <div class="filter-item-title"> <span class="pulse"></span> Market News <span class="badge badge-blue">New</span> </div> <div class="filter-item-description">Latest market updates & movements</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="In-depth analysis of market trends, sector performance, and investment strategies"> <div class="filter-item-title">Analysis</div> <div class="filter-item-description">Expert insights & interpretations</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Breaking news about corporate earnings reports, mergers, acquisitions, and major business developments"> <div class="filter-item-title">Corporate News</div> <div class="filter-item-description">Company events & announcements</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Major economic indicators, central bank decisions, and policy changes that affect financial markets"> <div class="filter-item-title">Economic Data</div> <div class="filter-item-description">GDP, inflation, employment data</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Government regulations, legislative changes, and political events impacting financial markets"> <div class="filter-item-title"> Regulatory News <span class="badge badge-red">Important</span> </div> <div class="filter-item-description">Policy changes & compliance</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="News about cryptocurrency markets, blockchain technology, and digital asset investments"> <div class="filter-item-title"> Cryptocurrency <span class="badge badge-yellow">Volatile</span> </div> <div class="filter-item-description">Bitcoin, Ethereum & DeFi news</div> <div class="filter-item-indicator">✓</div> </div> </div> </div> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-group-title">Special Reports</div> </div> <div class="filter-items"> <div class="filter-item" data-tooltip="Comprehensive quarterly reporting on global market performance across all major sectors"> <div class="filter-item-title">Quarterly Outlooks</div> <div class="filter-item-description">Q1, Q2, Q3, Q4 market reviews</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="In-depth spotlights on emerging sectors with high growth potential"> <div class="filter-item-title"> Industry Spotlights <span class="badge badge-green">Premium</span> </div> <div class="filter-item-description">Sector-specific deep dives</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Expert insights on long-term investment trends and strategies from leading financial analysts"> <div class="filter-item-title">Expert Opinions</div> <div class="filter-item-description">Market strategist viewpoints</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Breaking stories about major IPOs, SPACs, and other public offerings"> <div class="filter-item-title">IPO Coverage</div> <div class="filter-item-description">New listings & public offerings</div> <div class="filter-item-indicator">✓</div> </div> </div> </div> </div> <div class="filter-section" id="regions-section"> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-group-title">Global Markets</div> </div> <div class="filter-items"> <div class="filter-item" data-tooltip="Financial news covering North American markets including the NYSE, NASDAQ, and TSX"> <div class="filter-item-title">North America</div> <div class="filter-item-description">US, Canada, Mexico</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Updates from European financial hubs including London, Frankfurt, Paris, and Zurich"> <div class="filter-item-title">Europe</div> <div class="filter-item-description">FTSE, DAX, CAC 40, STOXX</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Coverage of major Asian financial markets including Tokyo, Shanghai, Hong Kong, and Singapore"> <div class="filter-item-title"> Asia-Pacific <span class="badge badge-blue">Active</span> </div> <div class="filter-item-description">Nikkei, Hang Seng, Shanghai</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="News from Middle Eastern and African financial markets and economies"> <div class="filter-item-title">MENA Region</div> <div class="filter-item-description">TASI, EGX, JSE</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Financial updates from Latin American markets and economies"> <div class="filter-item-title">Latin America</div> <div class="filter-item-description">Bovespa, IPC, MERVAL</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="News and analysis on global trade, capital flows, and international economic relations"> <div class="filter-item-title">Global Trade</div> <div class="filter-item-description">Cross-border financial flows</div> <div class="filter-item-indicator">✓</div> </div> </div> </div> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-group-title">Emerging Markets</div> </div> <div class="filter-items"> <div class="filter-item" data-tooltip="Financial news covering the rapidly growing Indian economy and markets"> <div class="filter-item-title"> India <span class="badge badge-green">Growth</span> </div> <div class="filter-item-description">SENSEX, NIFTY 50</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="News from the Brazilian financial system and Bovespa stock exchange"> <div class="filter-item-title">Brazil</div> <div class="filter-item-description">Bovespa, Brazilian Real</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Updates on Southeast Asian economies including Indonesia, Thailand, Vietnam, and Malaysia"> <div class="filter-item-title">Southeast Asia</div> <div class="filter-item-description">JCI, SET, KLCI</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Financial news from Russia and former Soviet states"> <div class="filter-item-title">Russia & CIS</div> <div class="filter-item-description">MOEX, RTS Index</div> <div class="filter-item-indicator">✓</div> </div> </div> </div> </div> <div class="filter-section" id="sectors-section"> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-group-title">Primary Sectors</div> </div> <div class="filter-items"> <div class="filter-item" data-tooltip="News covering banks, investment firms, insurance companies, and financial service providers"> <div class="filter-item-title"> Financial Services <span class="badge badge-yellow">Volatile</span> </div> <div class="filter-item-description">Banks, insurers, fintech</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Updates on hardware, software, IT services, and semiconductor industries"> <div class="filter-item-title"> Technology <span class="badge badge-blue">Trending</span> </div> <div class="filter-item-description">Software, hardware, services</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="News on pharmaceutical companies, medical devices, healthcare providers, and biotech"> <div class="filter-item-title">Healthcare</div> <div class="filter-item-description">Pharma, biotech, providers</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Coverage of oil & gas, utilities, renewables, and mining companies"> <div class="filter-item-title">Energy</div> <div class="filter-item-description">Oil, gas, renewables</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="News about food & beverage companies, personal care products, and household goods"> <div class="filter-item-title">Consumer Staples</div> <div class="filter-item-description">FMCG, household goods</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Updates on automotive, aerospace, construction, and industrial equipment manufacturers"> <div class="filter-item-title">Industrials</div> <div class="filter-item-description">Manufacturing, aerospace</div> <div class="filter-item-indicator">✓</div> </div> </div> </div> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-group-title">Specialized Sectors</div> </div> <div class="filter-items"> <div class="filter-item" data-tooltip="News on artificial intelligence, machine learning, robotics, and advanced computing technologies"> <div class="filter-item-title"> AI & Robotics <span class="badge badge-green">Growth</span> </div> <div class="filter-item-description">ML, automation, chips</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Updates on clean energy, electric vehicles, sustainable manufacturing, and environmental services"> <div class="filter-item-title"> Sustainable Investing <span class="badge badge-blue">ESG</span> </div> <div class="filter-item-description">Green bonds, clean tech</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Coverage of online retail, e-commerce platforms, and digital marketplaces"> <div class="filter-item-title">E-commerce</div> <div class="filter-item-description">Online retail, marketplaces</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="News about blockchains, digital currencies, NFTs, and decentralized finance"> <div class="filter-item-title">Blockchain & DeFi</div> <div class="filter-item-description">Crypto, smart contracts</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Updates on cybersecurity firms, data protection, and digital security solutions"> <div class="filter-item-title">Cybersecurity</div> <div class="filter-item-description">Data protection, threats</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="News on life sciences, biotechnology startups, and genetic research companies"> <div class="filter-item-title">Biotechnology</div> <div class="filter-item-description">Genomics, life sciences</div> <div class="filter-item-indicator">✓</div> </div> </div> </div> </div> <div class="filter-section" id="advanced-section"> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-group-title">News Timeframe</div> </div> <div class="slider-container"> <input type="range" min="1" max="30" value="7" class="slider" id="days-slider"> <div class="slider-values"> <span>1 day</span> <span id="days-value">7 days</span> <span>30 days</span> </div> </div> </div> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-group-title">News Sources</div> </div> <div class="filter-items"> <div class="filter-item" data-tooltip="Major financial news publications recognized for high-quality reporting and analysis"> <div class="filter-item-title">Premium Sources</div> <div class="filter-item-description">WSJ, FT, Bloomberg</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Market analysis and commentary from investment banks, research firms, and asset managers"> <div class="filter-item-title">Research Publications</div> <div class="filter-item-description">Goldman Sachs, JPM, Morgan Stanley</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Free access financial news sites, market blogs, and open financial information"> <div class="filter-item-title">Free Sources</div> <div class="filter-item-description">CNBC, Yahoo Finance</div> <div class="filter-item-indicator">✓</div> </div> <div class="filter-item" data-tooltip="Official company press releases, earnings calls, and regulatory filings"> <div class="filter-item-title">Primary Sources</div> <div class="filter-item-description">SEC filings, press releases</div> <div class="filter-item-indicator">✓</div> </div> </div> </div> <div class="filter-group"> <div class="filter-group-header"> <div class="filter-