Add music platform with DGDN album player

- Create /music landing page with artist grid
- Add /music/Darnea artist page with album listing
- Build /music/Darnea/DGDN album player with clickable tracklist
- Auto-play next track on completion
- Dangrubb-branded styling with cyan accent colors
- FLAC player pulls from /src/audio/DGDN
- Move landing page links to bottom with yellow announcement box
This commit is contained in:
dangrubbb
2026-02-28 09:31:48 -05:00
parent 025fe8a80b
commit 9afda9a01a
41 changed files with 524 additions and 2 deletions

View File

@ -238,13 +238,19 @@
<p> <p>
dangrubb.net dangrubb.net
</p> </p>
<p>
<div class="announcement">
<a href="https://dangrubb.net/music">EXCLUSIVE: Leaked mixtape from Darnea's vault</a>
</div>
<div class="links-bottom">
<a target="_parent" href="https://ai.dangrubb.net">ai</a> <a target="_parent" href="https://ai.dangrubb.net">ai</a>
<a target="_parent" href="https://dangrubb.net/blog">blog</a> <a target="_parent" href="https://dangrubb.net/blog">blog</a>
<a target="_parent" href="https://pi.dangrubb.net/jellyfin">media</a> <a target="_parent" href="https://pi.dangrubb.net/jellyfin">media</a>
<a target="_parent" href="https://pi.dangrubb.net/nextcloud">storage</a> <a target="_parent" href="https://pi.dangrubb.net/nextcloud">storage</a>
<a target="_parent" href="https://dangrubb.net/cv">cv</a> <a target="_parent" href="https://dangrubb.net/cv">cv</a>
<a target="_parent" href="https://pi.dangrubb.net/dangit">git</a></p> <a target="_parent" href="https://pi.dangrubb.net/dangit">git</a>
</div>
<div class="debug"> <div class="debug">
<div class="code"></div> <div class="code"></div>
</div> </div>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DGDN - Darnea | dangrubb.net</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="../../../style.css">
<link rel="stylesheet" href="../../music.css">
<link rel="stylesheet" href="./player.css">
</head>
<body>
<div class="music-container">
<div class="music-header">
<h1><a href="/music">Music</a> / <a href="/music/Darnea">Darnea</a> / DGDN</h1>
</div>
<div class="album-player">
<div class="album-header">
<div class="album-artwork">🔥</div>
<div class="album-info">
<h2>DGDN</h2>
<p class="artist-name">Darnea</p>
<p class="album-desc">Leaked from the vault</p>
</div>
</div>
<div class="player-section">
<div id="now-playing" class="now-playing">
<p>Select a track to play</p>
</div>
<audio id="audio-player" controls></audio>
</div>
<div class="tracklist">
<h3>Tracklist</h3>
<ol id="tracks-list"></ol>
</div>
</div>
<div class="music-footer">
<p><a href="/music/Darnea">← back to artist</a></p>
</div>
</div>
<script src="./player.js"></script>
</body>
</html>

View File

@ -0,0 +1,139 @@
/* Album Player */
.album-player {
margin: 40px 0;
}
.album-header {
display: flex;
gap: 30px;
margin-bottom: 40px;
padding: 30px;
background: rgba(107, 225, 233, 0.05);
border-radius: 8px;
align-items: center;
}
.album-artwork {
font-size: 5rem;
min-width: 150px;
text-align: center;
}
.album-info h2 {
margin: 0 0 5px 0;
font-size: 2rem;
color: #9d9aa4;
}
.album-info .artist-name {
margin: 0 0 5px 0;
color: #6be1e9;
font-size: 1.1rem;
}
.album-info .album-desc {
margin: 0;
color: #6be1e9;
font-size: 0.9rem;
font-style: italic;
}
/* Now Playing */
.now-playing {
text-align: center;
padding: 20px;
background: rgba(107, 225, 233, 0.1);
border: 1px solid rgba(107, 225, 233, 0.3);
border-radius: 6px;
margin-bottom: 20px;
min-height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
.now-playing p {
margin: 0;
color: #9d9aa4;
}
.now-playing.playing p {
color: #6be1e9;
font-weight: bold;
}
/* Audio Player */
#audio-player {
width: 100%;
margin-bottom: 30px;
accent-color: #6be1e9;
}
/* Tracklist */
.tracklist {
margin-top: 40px;
}
.tracklist h3 {
margin: 0 0 20px 0;
font-size: 1.3rem;
color: #9d9aa4;
}
.tracklist ol {
list-style-position: inside;
padding: 0;
margin: 0;
}
.tracklist li {
padding: 12px;
margin-bottom: 8px;
background: rgba(157, 154, 164, 0.05);
border: 1px solid rgba(107, 225, 233, 0.2);
border-radius: 4px;
cursor: pointer;
transition: all 0.2s ease;
color: #9d9aa4;
}
.tracklist li:hover {
background: rgba(107, 225, 233, 0.1);
border-color: rgba(107, 225, 233, 0.5);
}
.tracklist li.active {
background: rgba(107, 225, 233, 0.2);
border-color: #6be1e9;
color: #6be1e9;
font-weight: bold;
}
.track-duration {
float: right;
color: #6be1e9;
font-size: 0.9rem;
}
/* Responsive */
@media (max-width: 768px) {
.album-header {
flex-direction: column;
gap: 15px;
text-align: center;
}
.album-artwork {
font-size: 3rem;
}
.album-info h2 {
font-size: 1.5rem;
}
.tracklist li {
padding: 10px;
font-size: 0.9rem;
}
}

View File

@ -0,0 +1,71 @@
// Album player for DGDN
const tracks = [
{ title: "Dan Beat (bonus)", filename: "Dan Beat (bonus).flac" },
{ title: "Neigh V3", filename: "Neigh V3.flac" },
{ title: "On Ice", filename: "On Ice.flac" },
{ title: "Otish", filename: "Otish.flac" },
{ title: "Scan V2", filename: "Scan V2.flac" },
{ title: "balance v2", filename: "balance v2.flac" },
{ title: "eh ee uhn V2", filename: "eh ee uhn V2.flac" },
{ title: "held v3", filename: "held v3.flac" }
];
const audioPlayer = document.getElementById('audio-player');
const tracksList = document.getElementById('tracks-list');
const nowPlaying = document.getElementById('now-playing');
let currentTrackIndex = 0;
// Build tracklist
function initTracklist() {
tracks.forEach((track, index) => {
const li = document.createElement('li');
li.textContent = track.title;
li.dataset.index = index;
li.addEventListener('click', () => playTrack(index));
tracksList.appendChild(li);
});
}
// Play track
function playTrack(index) {
currentTrackIndex = index;
const track = tracks[index];
// Update audio source
audioPlayer.src = `/src/audio/DGDN/${track.filename}`;
audioPlayer.play();
// Update UI
updateNowPlaying(track.title);
updateActiveTrack();
}
// Update now playing display
function updateNowPlaying(title) {
nowPlaying.classList.add('playing');
nowPlaying.innerHTML = `<p>▶ Now playing: ${title}</p>`;
}
// Update active track in list
function updateActiveTrack() {
document.querySelectorAll('.tracklist li').forEach((li, i) => {
li.classList.toggle('active', i === currentTrackIndex);
});
}
// Auto-play next track when current ends
audioPlayer.addEventListener('ended', () => {
if (currentTrackIndex < tracks.length - 1) {
playTrack(currentTrackIndex + 1);
}
});
// Update active track when manually seeking/playing
audioPlayer.addEventListener('play', () => {
updateActiveTrack();
});
// Initialize
initTracklist();

35
music/Darnea/index.html Normal file
View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Darnea - dangrubb.net</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="../../style.css">
<link rel="stylesheet" href="../music.css">
</head>
<body>
<div class="music-container">
<div class="music-header">
<h1><a href="/music">Music</a> / Darnea</h1>
</div>
<div class="artist-detail">
<div class="artist-banner">🎤</div>
<h2>Darnea</h2>
</div>
<div class="albums-grid">
<div class="album-card">
<div class="album-cover">🔥</div>
<h3><a href="/music/Darnea/DGDN">DGDN</a></h3>
<p class="album-meta">8 tracks</p>
</div>
</div>
<div class="music-footer">
<p><a href="/music">← back to music</a></p>
</div>
</div>
</body>
</html>

30
music/index.html Normal file
View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dangrubb.net Music</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="../style.css">
<link rel="stylesheet" href="./music.css">
</head>
<body>
<div class="music-container">
<div class="music-header">
<h1><a href="/">dangrubb</a>.net/music</h1>
</div>
<div class="artists-grid">
<div class="artist-card">
<div class="artist-cover">🎤</div>
<h2><a href="/music/Darnea">Darnea</a></h2>
<p class="artist-meta">1 album</p>
</div>
</div>
<div class="music-footer">
<p><a href="/">← back home</a></p>
</div>
</div>
</body>
</html>

152
music/music.css Normal file
View File

@ -0,0 +1,152 @@
/* Music Platform Styling */
.music-container {
max-width: 900px;
margin: 0 auto;
padding: 40px 20px;
}
.music-header {
text-align: center;
margin-bottom: 50px;
border-bottom: 2px solid rgba(107, 225, 233, 0.3);
padding-bottom: 20px;
}
.music-header h1 {
margin: 0;
font-size: 2rem;
color: #9d9aa4;
font-weight: bold;
}
.music-header h1 a {
color: #6be1e9;
text-decoration: none;
}
.music-header h1 a:hover {
opacity: 0.8;
}
/* Artists Grid */
.artists-grid,
.albums-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 30px;
margin: 40px 0;
}
.artist-card,
.album-card {
text-align: center;
padding: 20px;
background: rgba(157, 154, 164, 0.05);
border: 1px solid rgba(107, 225, 233, 0.2);
border-radius: 8px;
transition: all 0.3s ease;
}
.artist-card:hover,
.album-card:hover {
background: rgba(107, 225, 233, 0.1);
border-color: rgba(107, 225, 233, 0.5);
transform: translateY(-4px);
}
.artist-cover,
.album-cover {
font-size: 4rem;
margin-bottom: 15px;
}
.artist-card h2,
.album-card h3 {
margin: 10px 0;
font-size: 1.3rem;
color: #9d9aa4;
}
.artist-card h2 a,
.album-card h3 a {
color: #6be1e9;
text-decoration: none;
}
.artist-card h2 a:hover,
.album-card h3 a:hover {
opacity: 0.8;
}
.artist-meta,
.album-meta {
color: #6be1e9;
font-size: 0.9rem;
margin: 0;
}
/* Artist Detail */
.artist-detail {
text-align: center;
margin: 40px 0;
padding: 40px 20px;
background: rgba(107, 225, 233, 0.05);
border-radius: 8px;
}
.artist-banner {
font-size: 5rem;
margin-bottom: 20px;
}
.artist-detail h2 {
margin: 0;
font-size: 2.5rem;
color: #9d9aa4;
}
/* Footer */
.music-footer {
text-align: center;
margin-top: 60px;
padding-top: 20px;
border-top: 2px solid rgba(107, 225, 233, 0.3);
}
.music-footer p {
margin: 0;
}
.music-footer a {
color: #6be1e9;
text-decoration: none;
}
.music-footer a:hover {
opacity: 0.8;
}
/* Responsive */
@media (max-width: 768px) {
.music-container {
padding: 20px 10px;
}
.music-header h1 {
font-size: 1.5rem;
}
.artists-grid,
.albums-grid {
grid-template-columns: 1fr;
}
.artist-banner {
font-size: 3rem;
}
.artist-detail h2 {
font-size: 1.8rem;
}
}

BIN
src/audio/._DGDN Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/audio/DGDN/._Otish.flac Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/audio/DGDN/On Ice.flac Normal file

Binary file not shown.

Binary file not shown.

BIN
src/audio/DGDN/Otish.flac Normal file

Binary file not shown.

Binary file not shown.

BIN
src/audio/DGDN/Scan V2.flac Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/audio/DGDN/held v3.flac Normal file

Binary file not shown.

Binary file not shown.

View File

@ -156,6 +156,46 @@ p {
font-size: 0.875rem; font-size: 0.875rem;
} }
.announcement {
margin: 30px auto 0;
padding: 20px;
max-width: 500px;
background: #ffeb3b;
border: 3px solid #fbc02d;
border-radius: 8px;
text-align: center;
box-shadow: 0 4px 12px rgba(255, 235, 59, 0.3);
}
.announcement a {
color: #000;
font-weight: bold;
text-decoration: none;
font-size: 1rem;
}
.announcement a:hover,
.announcement a:focus {
text-decoration: underline;
opacity: 0.85;
}
.links-bottom {
margin: 60px auto 0;
position: relative;
max-width: 400px;
text-align: center;
padding-bottom: 20px;
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
}
.links-bottom a {
color: #6be1e9;
}
a { a {
color: #6be1e9; color: #6be1e9;
} }