Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 162 additions & 6 deletions static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,165 @@ body {
margin-top: 0.5rem;
}

.volume-wrapper .slider-panel {
max-width: 160px !important;
opacity: 1 !important;
visibility: visible !important;
}
}
}



.song-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 1rem;
}


.song-card-grid {
background: var(--bg-elev);
border: 1px solid var(--border);
border-radius: 14px;
overflow: hidden;
cursor: pointer;
transition: border-color 0.2s, transform 0.2s;
display: flex;
flex-direction: column;
}

.song-card-grid:hover {
border-color: var(--accent);
transform: translateY(-3px);
}


.song-card-grid__art {
position: relative;
aspect-ratio: 1 / 1;
background: linear-gradient(135deg, #3a2a4e, #2a1a3a);
display: flex;
align-items: center;
justify-content: center;
font-size: 2.5rem;
overflow: hidden;
}


.song-card-grid__art--orange { background: linear-gradient(135deg, var(--accent), var(--accent-2)); }
.song-card-grid__art--purple { background: linear-gradient(135deg, #7c3aed, #4f46e5); }
.song-card-grid__art--teal { background: linear-gradient(135deg, #0d9488, #0891b2); }
.song-card-grid__art--pink { background: linear-gradient(135deg, #ec4899, #a855f7); }


.song-card-grid__art img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}


.song-card-grid__overlay {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.2s;
}

.song-card-grid:hover .song-card-grid__overlay {
opacity: 1;
}

.song-card-grid__play-btn {
width: 52px;
height: 52px;
border-radius: 50%;
background: var(--accent);
border: none;
color: #fff;
font-size: 1.2rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.15s, background 0.15s;
box-shadow: 0 4px 20px rgba(255, 107, 61, 0.45);
}

.song-card-grid__play-btn:hover {
transform: scale(1.08);
background: var(--accent-2);
}


.song-card-grid--playing .song-card-grid__art::before {
content: "";
position: absolute;
inset: -3px;
border-radius: inherit;
border: 2px solid var(--accent);
animation: pulse-ring 1.8s ease-out infinite;
pointer-events: none;
}

@keyframes pulse-ring {
0% { opacity: 0.9; transform: scale(1); }
100% { opacity: 0; transform: scale(1.06); }
}


.song-card-grid__info {
padding: 0.75rem 0.875rem 0.875rem;
display: flex;
flex-direction: column;
gap: 0.2rem;
flex: 1;
}

.song-card-grid__title {
font-size: 0.9rem;
font-weight: 600;
color: var(--text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.song-card-grid__genre {
font-size: 0.78rem;
color: var(--text-dim);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}


.song-card-grid__footer {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 0.5rem;
}

.song-card-grid__duration {
font-size: 0.78rem;
color: var(--text-dim);
}

.song-card-grid__like {
background: none;
border: none;
cursor: pointer;
color: var(--text-dim);
font-size: 0.95rem;
padding: 0;
line-height: 1;
transition: color 0.15s, transform 0.15s;
}

.song-card-grid__like:hover,
.song-card-grid__like--liked {
color: var(--accent) ;
transform: scale(1.15);
}

58 changes: 21 additions & 37 deletions static/js/script.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,28 @@
console.log("RustTune loaded");
document.addEventListener("DOMContentLoaded", () => {
console.log("RustTune volume controller initialized");

const muteBtn = document.getElementById("mute-btn");
const volumeSlider = document.getElementById("volume-slider");

let savedVolume = parseFloat(volumeSlider.value) || 0.8;

function toggleLike(btn) {
const liked = btn.classList.toggle("song-card-grid__like--liked");
btn.textContent = liked ? "♥" : "♡";
btn.setAttribute("aria-pressed", String(liked));
const title = btn.closest(".song-card-grid").querySelector(".song-card-grid__title").textContent;
btn.setAttribute("aria-label", `${liked ? "Unlike" : "Like"} ${title}`);
}

function updateIcon(volumeValue) {
if (volumeValue == 0) {
muteBtn.textContent = "🔇";
} else if (volumeValue >= 0.5) {
muteBtn.textContent = "🔊";
} else {
muteBtn.textContent = "🔉";
}
}
function playSong(btn) {
const card = btn.closest(".song-card-grid");
document.querySelectorAll(".song-card-grid--playing")
.forEach(c => c.classList.remove("song-card-grid--playing"));
card.classList.add("song-card-grid--playing");
document.getElementById("now-title").textContent = card.querySelector(".song-card-grid__title").textContent;
document.getElementById("now-artist").textContent = card.querySelector(".song-card-grid__genre").textContent + " • RustTune";
}

volumeSlider.addEventListener("input", (e) => {
const val = parseFloat(e.target.value);

if (val > 0) {
savedVolume = val;
}

updateIcon(val);
});
document.querySelectorAll(".song-card-grid__like").forEach(btn => {
btn.addEventListener("click", () => toggleLike(btn));
});

muteBtn.addEventListener("click", (e) => {
e.stopPropagation();

const currentVal = parseFloat(volumeSlider.value);

if (currentVal > 0) {
savedVolume = currentVal;
volumeSlider.value = 0;
updateIcon(0);
} else {
volumeSlider.value = savedVolume;
updateIcon(savedVolume);
}
});
document.querySelectorAll(".song-card-grid__play-btn").forEach(btn => {
btn.addEventListener("click", () => playSong(btn));
});
123 changes: 85 additions & 38 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,52 +80,99 @@ <h1 class="track-title">Feel The Music</h1>

</section>

<section class="songs-section">


<div class="section-head">
<h2>Popular Songs</h2>
<a href="#" class="see-all">See all</a>
</div>

<ul class="song-list">

<li class="song-card">
<div class="song-cover">🎶</div>

<div class="song-meta">
<p class="song-title">Midnight Echo</p>
<p class="song-artist">Electronic Vibes</p>
</div>

<span class="song-duration">3:24</span>
</li>

<li class="song-card">
<div class="song-cover">🎧</div>
<section class="songs-section" style="margin-top: 2.5rem;">

<div class="song-meta">
<p class="song-title">Neon Waves</p>
<p class="song-artist">Synth Pop</p>
</div>

<span class="song-duration">4:05</span>
</li>
<div class="section-head">
<h2>Popular Songs</h2>
<a href="#" class="see-all">See all</a>
</div>

<li class="song-card">
<div class="song-cover">🎤</div>
<ul class="song-grid" role="list" aria-label="Popular songs">

<div class="song-meta">
<p class="song-title">Dream Runner</p>
<p class="song-artist">Lo-Fi Beats</p>
</div>
<!-- Card 1 Midnight Echo -->
<li class="song-card-grid song-card-grid--playing" data-id="1">
<div class="song-card-grid__art song-card-grid__art--orange">
🎵
<div class="song-card-grid__overlay" aria-hidden="true">
<button class="song-card-grid__play-btn" aria-label="Play Midnight Echo">▶</button>
</div>
</div>
<div class="song-card-grid__info">
<p class="song-card-grid__title">Midnight Echo</p>
<p class="song-card-grid__genre">Electronic Vibes</p>
<div class="song-card-grid__footer">
<span class="song-card-grid__duration">3:24</span>
<button class="song-card-grid__like song-card-grid__like--liked"
aria-label="Unlike Midnight Echo" aria-pressed="true">♥</button>
</div>
</div>
</li>

<!-- Card 2 Neon Waves -->
<li class="song-card-grid" data-id="2">
<div class="song-card-grid__art song-card-grid__art--purple">
🎧
<div class="song-card-grid__overlay" aria-hidden="true">
<button class="song-card-grid__play-btn" aria-label="Play Neon Waves">▶</button>
</div>
</div>
<div class="song-card-grid__info">
<p class="song-card-grid__title">Neon Waves</p>
<p class="song-card-grid__genre">Synth Pop</p>
<div class="song-card-grid__footer">
<span class="song-card-grid__duration">4:05</span>
<button class="song-card-grid__like" aria-label="Like Neon Waves"
aria-pressed="false">♡</button>
</div>
</div>
</li>

<!-- Card 3 Dream Runner -->
<li class="song-card-grid" data-id="3">
<div class="song-card-grid__art song-card-grid__art--teal">
🎤
<div class="song-card-grid__overlay" aria-hidden="true">
<button class="song-card-grid__play-btn" aria-label="Play Dream Runner">▶</button>
</div>
</div>
<div class="song-card-grid__info">
<p class="song-card-grid__title">Dream Runner</p>
<p class="song-card-grid__genre">Lo-Fi Beats</p>
<div class="song-card-grid__footer">
<span class="song-card-grid__duration">2:58</span>
<button class="song-card-grid__like" aria-label="Like Dream Runner"
aria-pressed="false">♡</button>
</div>
</div>
</li>

<!-- Card 4 Solar Drift -->
<li class="song-card-grid" data-id="4">
<div class="song-card-grid__art song-card-grid__art--pink">
🎼
<div class="song-card-grid__overlay" aria-hidden="true">
<button class="song-card-grid__play-btn" aria-label="Play Solar Drift">▶</button>
</div>
</div>
<div class="song-card-grid__info">
<p class="song-card-grid__title">Solar Drift</p>
<p class="song-card-grid__genre">Ambient</p>
<div class="song-card-grid__footer">
<span class="song-card-grid__duration">5:10</span>
<button class="song-card-grid__like" aria-label="Like Solar Drift"
aria-pressed="false">♡</button>
</div>
</div>
</li>

<span class="song-duration">2:58</span>
</li>
</ul>

</ul>
</section>

</section>

<script src="script.js"></script>
</main>

<footer class="site-footer">
Expand Down