578 lines
20 KiB
HTML
578 lines
20 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Eclectica Experimenti | PLAYLISTS</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Ribeye+Marrow&family=Rambla:wght@400;700&family=Share+Tech+Mono&display=swap" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--bg-void: #04060b;
|
|
--text-warm: #e8d5b8;
|
|
--text-muted: #7a6f5e;
|
|
--ff-primary: #a855f7;
|
|
--ff-bright: #c084fc;
|
|
--ff-deep: #6d28d9;
|
|
--ff-glow: rgba(168, 85, 247, 0.18);
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
body {
|
|
background-color: var(--bg-void);
|
|
color: var(--text-warm);
|
|
font-family: 'Rambla', sans-serif;
|
|
line-height: 1.5;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* Sticky Header */
|
|
header {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
background-color: var(--bg-void);
|
|
border-bottom: 1px solid var(--ff-deep);
|
|
padding: 1rem 2rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 2rem;
|
|
}
|
|
|
|
.header-main {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 1.5rem;
|
|
flex-grow: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
header h1 {
|
|
font-family: 'Ribeye Marrow', cursive;
|
|
color: var(--ff-primary);
|
|
font-size: 2rem;
|
|
font-weight: normal;
|
|
margin: 0;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.header-meta {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
color: var(--text-muted);
|
|
font-size: 0.9rem;
|
|
text-transform: uppercase;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.nav-links {
|
|
display: flex;
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
.back-to-hub {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
color: var(--ff-primary);
|
|
text-decoration: none;
|
|
font-size: 1rem;
|
|
white-space: nowrap;
|
|
transition: color 100ms ease;
|
|
}
|
|
|
|
.back-to-hub:hover {
|
|
color: var(--ff-bright);
|
|
}
|
|
|
|
/* Mobile Menu */
|
|
.menu-toggle {
|
|
display: none;
|
|
background: none;
|
|
border: 1px solid var(--ff-primary);
|
|
color: var(--ff-primary);
|
|
padding: 0.5rem;
|
|
font-family: 'Share Tech Mono', monospace;
|
|
cursor: pointer;
|
|
font-size: 1.2rem;
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
header {
|
|
padding: 1rem;
|
|
}
|
|
.nav-links {
|
|
display: none;
|
|
position: absolute;
|
|
top: 100%;
|
|
left: 0;
|
|
right: 0;
|
|
background: var(--bg-void);
|
|
flex-direction: column;
|
|
padding: 1rem;
|
|
border-bottom: 1px solid var(--ff-deep);
|
|
}
|
|
.nav-links.open {
|
|
display: flex;
|
|
}
|
|
.menu-toggle {
|
|
display: block;
|
|
}
|
|
header h1 {
|
|
font-size: 1.5rem;
|
|
}
|
|
}
|
|
|
|
/* Track List */
|
|
.track-list {
|
|
max-width: 1000px;
|
|
margin: 2rem auto;
|
|
padding: 0 1rem 5rem;
|
|
}
|
|
|
|
.track-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-left: 1px solid var(--ff-deep);
|
|
background: transparent;
|
|
margin-bottom: 0.5rem;
|
|
transition: background 100ms ease, border-color 100ms ease;
|
|
position: relative;
|
|
}
|
|
|
|
.track-card:hover {
|
|
background: var(--ff-glow);
|
|
border-color: var(--ff-primary);
|
|
}
|
|
|
|
.track-card::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: -0.25rem;
|
|
left: 0;
|
|
right: 0;
|
|
height: 1px;
|
|
background-color: var(--ff-deep);
|
|
opacity: 0.1;
|
|
}
|
|
|
|
.track-main-row {
|
|
display: flex;
|
|
padding: 1.5rem;
|
|
gap: 1.5rem;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
/* Zones */
|
|
.zone-meta {
|
|
width: 80px;
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-end;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.track-num {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
color: var(--text-muted);
|
|
font-size: 1.1rem;
|
|
}
|
|
|
|
.album-art {
|
|
width: 64px;
|
|
height: 64px;
|
|
background-color: #111;
|
|
object-fit: cover;
|
|
border: 1px solid rgba(255,255,255,0.05);
|
|
}
|
|
|
|
.zone-info {
|
|
flex-grow: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.track-name {
|
|
font-family: 'Rambla', sans-serif;
|
|
font-weight: 700;
|
|
font-size: 1.1rem;
|
|
color: var(--text-warm);
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.artist-name {
|
|
font-family: 'Rambla', sans-serif;
|
|
font-size: 0.95rem;
|
|
color: var(--ff-bright);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.album-meta {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.75rem;
|
|
color: var(--text-muted);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
}
|
|
|
|
/* Links Row */
|
|
.links-row {
|
|
margin-top: 1rem;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.track-link {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.75rem;
|
|
color: var(--ff-primary);
|
|
text-decoration: none;
|
|
transition: color 100ms ease;
|
|
cursor: pointer;
|
|
background: none;
|
|
border: none;
|
|
padding: 0;
|
|
}
|
|
|
|
.track-link:hover {
|
|
color: var(--ff-bright);
|
|
}
|
|
|
|
.track-link[data-available="false"] {
|
|
color: var(--text-muted);
|
|
cursor: not-allowed;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Embed Area */
|
|
.embed-container {
|
|
display: none;
|
|
width: 100%;
|
|
background: var(--ff-glow);
|
|
border-top: 1px solid var(--ff-deep);
|
|
padding: 1rem;
|
|
}
|
|
|
|
.video-wrapper {
|
|
position: relative;
|
|
padding-bottom: 56.25%; /* 16:9 */
|
|
height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.video-wrapper iframe {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
border: 0;
|
|
}
|
|
|
|
.track-card.active {
|
|
border-color: var(--ff-primary);
|
|
}
|
|
|
|
.track-card.active .embed-container {
|
|
display: block;
|
|
}
|
|
|
|
@media (max-width: 480px) {
|
|
.track-main-row {
|
|
padding: 1rem;
|
|
gap: 1rem;
|
|
}
|
|
.zone-meta {
|
|
width: 64px;
|
|
}
|
|
.album-art {
|
|
width: 48px;
|
|
height: 48px;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<header>
|
|
<div class="header-main">
|
|
<h1>Eclectica Experimenti</h1>
|
|
<span class="header-meta">92 TRACKS • 6:42:15</span>
|
|
</div>
|
|
|
|
<button class="menu-toggle" id="menuToggle">☰</button>
|
|
|
|
<nav class="nav-links" id="navLinks">
|
|
<a href="playlists.html" class="back-to-hub">← Playlists</a>
|
|
</nav>
|
|
</header>
|
|
|
|
<main class="track-list">
|
|
|
|
<!-- Track 1: Full Embed -->
|
|
<article class="track-card">
|
|
<div class="track-main-row">
|
|
<div class="zone-meta">
|
|
<span class="track-num">01</span>
|
|
<img class="album-art"
|
|
src=""
|
|
data-src="https://i.scdn.co/image/ab67616d0000b273b40049962a93144df36ca024"
|
|
alt="Album Art"
|
|
loading="lazy">
|
|
</div>
|
|
<div class="zone-info">
|
|
<div class="track-name">Midnight City</div>
|
|
<div class="artist-name">M83</div>
|
|
<div class="album-meta">Hurry Up, We're Dreaming • 2011</div>
|
|
|
|
<div class="links-row">
|
|
<a href="https://open.spotify.com/track/1eyzqe2QqGZUmfc2NWm1vI" class="track-link" target="_blank">[SPOTIFY]</a>
|
|
<a href="https://musicbrainz.org/recording/86c62c93-9c8e-4903-8874-9b5753909796" class="track-link" target="_blank">[MUSICBRAINZ]</a>
|
|
<button class="track-link youtube-toggle" data-video-id="dX3k_LHnn28">[YOUTUBE]</button>
|
|
<a href="https://ilovem83.com" class="track-link" target="_blank">[ARTIST]</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="embed-container">
|
|
<div class="video-wrapper">
|
|
<iframe src=""
|
|
data-src="https://www.youtube.com/embed/dX3k_LHnn28"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
|
allowfullscreen></iframe>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<!-- Track 2: No Artist Link -->
|
|
<article class="track-card">
|
|
<div class="track-main-row">
|
|
<div class="zone-meta">
|
|
<span class="track-num">02</span>
|
|
<img class="album-art"
|
|
src=""
|
|
data-src="https://i.scdn.co/image/ab67616d0000b2737604f56f34582f3a479a4055"
|
|
alt="Album Art"
|
|
loading="lazy">
|
|
</div>
|
|
<div class="zone-info">
|
|
<div class="track-name">Nightcall</div>
|
|
<div class="artist-name">Kavinsky</div>
|
|
<div class="album-meta">OutRun • 2013</div>
|
|
|
|
<div class="links-row">
|
|
<a href="#" class="track-link" target="_blank">[SPOTIFY]</a>
|
|
<a href="#" class="track-link" target="_blank">[MUSICBRAINZ]</a>
|
|
<button class="track-link youtube-toggle" data-video-id="MV_3Dpw-BRY">[YOUTUBE]</button>
|
|
<span class="track-link" data-available="false">[ARTIST]</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="embed-container">
|
|
<div class="video-wrapper">
|
|
<iframe src=""
|
|
data-src="https://www.youtube.com/embed/MV_3Dpw-BRY"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
|
allowfullscreen></iframe>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<!-- Track 3: YouTube Search only -->
|
|
<article class="track-card">
|
|
<div class="track-main-row">
|
|
<div class="zone-meta">
|
|
<span class="track-num">03</span>
|
|
<img class="album-art"
|
|
src=""
|
|
data-src="https://i.scdn.co/image/ab67616d0000b273413554e19576189b884d5098"
|
|
alt="Album Art"
|
|
loading="lazy">
|
|
</div>
|
|
<div class="zone-info">
|
|
<div class="track-name">Genesis</div>
|
|
<div class="artist-name">Grimes</div>
|
|
<div class="album-meta">Visions • 2012</div>
|
|
|
|
<div class="links-row">
|
|
<a href="#" class="track-link" target="_blank">[SPOTIFY]</a>
|
|
<a href="#" class="track-link" target="_blank">[MUSICBRAINZ]</a>
|
|
<a href="https://www.youtube.com/results?search_query=Grimes+Genesis" class="track-link" target="_blank">[YOUTUBE]</a>
|
|
<a href="#" class="track-link" target="_blank">[ARTIST]</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<!-- Track 4: Another example -->
|
|
<article class="track-card">
|
|
<div class="track-main-row">
|
|
<div class="zone-meta">
|
|
<span class="track-num">04</span>
|
|
<img class="album-art"
|
|
src=""
|
|
data-src="https://i.scdn.co/image/ab67616d0000b2731885440620ef0d18d45543c8"
|
|
alt="Album Art"
|
|
loading="lazy">
|
|
</div>
|
|
<div class="zone-info">
|
|
<div class="track-name">Loro</div>
|
|
<div class="artist-name">Pinback</div>
|
|
<div class="album-meta">Pinback • 1999</div>
|
|
|
|
<div class="links-row">
|
|
<a href="#" class="track-link" target="_blank">[SPOTIFY]</a>
|
|
<a href="#" class="track-link" target="_blank">[MUSICBRAINZ]</a>
|
|
<button class="track-link youtube-toggle" data-video-id="46_l1n6_q60">[YOUTUBE]</button>
|
|
<a href="#" class="track-link" target="_blank">[ARTIST]</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="embed-container">
|
|
<div class="video-wrapper">
|
|
<iframe src=""
|
|
data-src="https://www.youtube.com/embed/46_l1n6_q60"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
|
allowfullscreen></iframe>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<!-- Track 5: Deep vibes -->
|
|
<article class="track-card">
|
|
<div class="track-main-row">
|
|
<div class="zone-meta">
|
|
<span class="track-num">05</span>
|
|
<img class="album-art"
|
|
src=""
|
|
data-src="https://i.scdn.co/image/ab67616d0000b273fc61f1c2b535d8da951a808f"
|
|
alt="Album Art"
|
|
loading="lazy">
|
|
</div>
|
|
<div class="zone-info">
|
|
<div class="track-name">Small Memory</div>
|
|
<div class="artist-name">Jon Hopkins</div>
|
|
<div class="album-meta">Insides • 2009</div>
|
|
|
|
<div class="links-row">
|
|
<a href="#" class="track-link" target="_blank">[SPOTIFY]</a>
|
|
<a href="#" class="track-link" target="_blank">[MUSICBRAINZ]</a>
|
|
<button class="track-link youtube-toggle" data-video-id="xSls68pX-94">[YOUTUBE]</button>
|
|
<a href="#" class="track-link" target="_blank">[ARTIST]</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="embed-container">
|
|
<div class="video-wrapper">
|
|
<iframe src=""
|
|
data-src="https://www.youtube.com/embed/xSls68pX-94"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
|
allowfullscreen></iframe>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<!-- Track 6: Classics -->
|
|
<article class="track-card">
|
|
<div class="track-main-row">
|
|
<div class="zone-meta">
|
|
<span class="track-num">06</span>
|
|
<img class="album-art"
|
|
src=""
|
|
data-src="https://i.scdn.co/image/ab67616d0000b27376696706e57f12a233604f37"
|
|
alt="Album Art"
|
|
loading="lazy">
|
|
</div>
|
|
<div class="zone-info">
|
|
<div class="track-name">Teardrop</div>
|
|
<div class="artist-name">Massive Attack</div>
|
|
<div class="album-meta">Mezzanine • 1998</div>
|
|
|
|
<div class="links-row">
|
|
<a href="#" class="track-link" target="_blank">[SPOTIFY]</a>
|
|
<a href="#" class="track-link" target="_blank">[MUSICBRAINZ]</a>
|
|
<button class="track-link youtube-toggle" data-video-id="u7K72X4eo_s">[YOUTUBE]</button>
|
|
<a href="#" class="track-link" target="_blank">[ARTIST]</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="embed-container">
|
|
<div class="video-wrapper">
|
|
<iframe src=""
|
|
data-src="https://www.youtube.com/embed/u7K72X4eo_s"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
|
allowfullscreen></iframe>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
</main>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Mobile menu toggle
|
|
const menuToggle = document.getElementById('menuToggle');
|
|
const navLinks = document.getElementById('navLinks');
|
|
|
|
menuToggle.addEventListener('click', () => {
|
|
navLinks.classList.toggle('open');
|
|
menuToggle.textContent = navLinks.classList.contains('open') ? '✕' : '☰';
|
|
});
|
|
|
|
// Intersection Observer for lazy loading images
|
|
const imageObserver = new IntersectionObserver((entries, observer) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
const img = entry.target;
|
|
img.src = img.dataset.src;
|
|
observer.unobserve(img);
|
|
}
|
|
});
|
|
}, { rootMargin: '300px' });
|
|
|
|
document.querySelectorAll('.album-art').forEach(img => {
|
|
imageObserver.observe(img);
|
|
});
|
|
|
|
// YouTube Toggle and Lazy Loading
|
|
const youtubeToggles = document.querySelectorAll('.youtube-toggle');
|
|
const videoObserver = new IntersectionObserver((entries, observer) => {
|
|
entries.forEach(entry => {
|
|
const card = entry.target;
|
|
const iframe = card.querySelector('iframe');
|
|
|
|
if (entry.isIntersecting && card.classList.contains('active')) {
|
|
if (iframe && !iframe.src) {
|
|
iframe.src = iframe.dataset.src;
|
|
}
|
|
}
|
|
});
|
|
}, { rootMargin: '200px' });
|
|
|
|
youtubeToggles.forEach(toggle => {
|
|
toggle.addEventListener('click', () => {
|
|
const card = toggle.closest('.track-card');
|
|
const iframe = card.querySelector('iframe');
|
|
|
|
card.classList.toggle('active');
|
|
|
|
// If opening, check if we need to load the iframe
|
|
if (card.classList.contains('active')) {
|
|
videoObserver.observe(card);
|
|
// Force check immediate visibility
|
|
if (iframe && !iframe.src) {
|
|
iframe.src = iframe.dataset.src;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|