Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Tracks - Mr.FLEN</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <link rel="stylesheet" href="style.css"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: '#0B2D2F', | |
| accent: '#FF914D', | |
| magenta: '#C5427A', | |
| paper: '#0A0F10' | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| </head> | |
| <body class="bg-paper text-white min-h-screen flex flex-col"> | |
| <custom-navbar></custom-navbar> | |
| <main class="flex-1 py-12 px-4"> | |
| <div class="max-w-6xl mx-auto"> | |
| <div class="text-center mb-12"> | |
| <h1 class="text-4xl md:text-5xl font-bold mb-4"> | |
| <span class="bg-gradient-to-r from-accent to-magenta bg-clip-text text-transparent"> | |
| ALL TRACKS | |
| </span> | |
| </h1> | |
| <p class="text-lg text-gray-400 max-w-2xl mx-auto"> | |
| Explore the complete collection of 15 tracks from "Still Lie Right Next to Me" | |
| </p> | |
| </div> | |
| <!-- View Toggle --> | |
| <div class="flex justify-end mb-6"> | |
| <div class="flex gap-2 bg-primary/20 rounded-full p-1 backdrop-blur-sm"> | |
| <button id="gridView" class="px-4 py-2 rounded-full bg-accent text-paper transition-all duration-300"> | |
| <i data-feather="grid" class="w-4 h-4"></i> | |
| </button> | |
| <button id="listView" class="px-4 py-2 rounded-full text-gray-400 hover:text-white transition-all duration-300"> | |
| <i data-feather="list" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Search and Filter --> | |
| <div class="mb-8 grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <div class="relative"> | |
| <input type="text" id="searchInput" placeholder="Search tracks..." | |
| class="w-full bg-primary/20 border border-accent/20 rounded-full py-3 px-6 backdrop-blur-sm focus:border-accent focus:outline-none transition-all duration-300"> | |
| <i data-feather="search" class="absolute right-6 top-1/2 transform -translate-y-1/2 text-gray-400"> | |
| </div> | |
| <select id="tagFilter" class="w-full bg-primary/20 border border-accent/20 rounded-full py-3 px-6 backdrop-blur-sm focus:border-accent focus:outline-none transition-all duration-300"> | |
| <option value="">All Tags</option> | |
| <option value="Deep House">Deep House</option> | |
| <option value="Melodic House">Melodic House</option> | |
| <option value="AfterHours">AfterHours</option> | |
| <option value="Hypnotic">Hypnotic</option> | |
| <option value="Atmospheric">Atmospheric</option> | |
| <option value="Melodic">Melodic</option> | |
| <option value="Urban">Urban</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Tracks Container --> | |
| <div id="tracksContainer" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |
| <!-- Tracks will be populated by JavaScript --> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <custom-footer></custom-footer> | |
| <script src="components/navbar.js"></script> | |
| <script src="components/footer.js"></script> | |
| <script src="script.js"></script> | |
| <script> | |
| feather.replace(); | |
| document.addEventListener('DOMContentLoaded', function() { | |
| loadAllTracks(); | |
| initializeViewToggle(); | |
| initializeSearch(); | |
| }); | |
| function loadAllTracks() { | |
| const container = document.getElementById('tracksContainer'); | |
| if (!container) return; | |
| container.innerHTML = ` | |
| <div class="col-span-full text-center py-8"> | |
| <div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-accent"></div> | |
| </div> | |
| `; | |
| setTimeout(() => { | |
| renderTrackCards(albumData.tracks, container); | |
| }, 1000); | |
| } | |
| function initializeViewToggle() { | |
| const gridView = document.getElementById('gridView'); | |
| const listView = document.getElementById('listView'); | |
| const container = document.getElementById('tracksContainer'); | |
| gridView.addEventListener('click', () => { | |
| gridView.classList.add('bg-accent', 'text-paper'); | |
| listView.classList.remove('bg-accent', 'text-paper'); | |
| container.className = 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'); | |
| }); | |
| listView.addEventListener('click', () => { | |
| listView.classList.add('bg-accent', 'text-paper'); | |
| gridView.classList.remove('bg-accent', 'text-paper'); | |
| container.className = 'grid grid-cols-1 gap-4'; | |
| }); | |
| } | |
| function initializeSearch() { | |
| const searchInput = document.getElementById('searchInput'); | |
| const tagFilter = document.getElementById('tagFilter'); | |
| const filterTracks = () => { | |
| const searchTerm = searchInput.value.toLowerCase(); | |
| const selectedTag = tagFilter.value; | |
| const filteredTracks = albumData.tracks.filter(track => { | |
| const matchesSearch = track.title.toLowerCase().includes(searchTerm) || | |
| (track.desc && track.desc.toLowerCase().includes(searchTerm)); | |
| const matchesTag = !selectedTag || | |
| (track.tags && track.tags.includes(selectedTag)); | |
| return matchesSearch && matchesTag; | |
| }); | |
| const container = document.getElementById('tracksContainer'); | |
| renderTrackCards(filteredTracks, container); | |
| }; | |
| searchInput.addEventListener('input', filterTracks); | |
| tagFilter.addEventListener('change', filterTracks); | |
| } | |
| </script> | |
| </body> | |
| </html> |