gandora: lyrics on the back of the cover (tap the cover or LYRICS to flip)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K6897PWcUEwHiqZMcVnNF6
This commit is contained in:
1 parent
df98581056
commit
c54522678b
1 file changed
+18
-11
+18
-11
@@ -59,8 +59,13 @@ input,textarea{font:inherit;color:inherit}
|
||||
#top .station{letter-spacing:0;font:400 13px var(--sans);color:var(--ink);max-width:60%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
#top button{color:var(--dim);letter-spacing:.08em}
|
||||
#stage{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;padding:14px 0}
|
||||
#cover{width:min(78vw,380px);aspect-ratio:1;border-radius:18px;overflow:hidden;background:var(--card);box-shadow:0 30px 80px -30px rgba(0,0,0,.9);position:relative}
|
||||
#cover{width:min(78vw,380px);aspect-ratio:1;position:relative;perspective:1200px}
|
||||
#cover .card{position:absolute;inset:0;transform-style:preserve-3d;transition:transform .7s cubic-bezier(.4,.1,.2,1)}
|
||||
#cover.flipped .card{transform:rotateY(180deg)}
|
||||
#cover .face{position:absolute;inset:0;border-radius:18px;overflow:hidden;background:var(--card);box-shadow:0 30px 80px -30px rgba(0,0,0,.9);backface-visibility:hidden;-webkit-backface-visibility:hidden}
|
||||
#cover .back{transform:rotateY(180deg);background:#121216;border:1px solid var(--line);display:flex;flex-direction:column}
|
||||
#cover canvas{width:100%;height:100%;display:block}
|
||||
#cover .back .backTitle{font:600 10px var(--font);letter-spacing:.22em;color:var(--dim);padding:14px 16px 6px;text-align:center}
|
||||
#cover .veil{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(11,11,14,.55);backdrop-filter:blur(2px);font:12px var(--font);letter-spacing:.2em;color:var(--ink);opacity:0;transition:opacity .3s;pointer-events:none}
|
||||
#cover.cooking .veil{opacity:1}
|
||||
#meta{text-align:center;max-width:520px}
|
||||
@@ -69,7 +74,8 @@ input,textarea{font:inherit;color:inherit}
|
||||
#lyric{color:var(--dim);font-size:13px;margin:10px 0 0;min-height:1.5em;font-style:italic}
|
||||
#lyricsBtn{display:block;margin:8px auto 0;font:600 11px var(--font);letter-spacing:.18em;color:var(--dim);text-decoration:underline;text-underline-offset:3px}
|
||||
#lyricsBtn.on{color:var(--acc)}
|
||||
#lyrics{white-space:pre-wrap;text-align:center;font-size:14px;line-height:1.7;margin:14px 0 0;color:var(--ink);max-height:40dvh;overflow:auto;padding:0 8px;font-family:var(--sans)}
|
||||
#lyrics{white-space:pre-wrap;text-align:center;font-size:13px;line-height:1.65;margin:0;color:var(--ink);flex:1;overflow:auto;padding:4px 16px 18px;font-family:var(--sans);-webkit-mask-image:linear-gradient(#000 85%,transparent);mask-image:linear-gradient(#000 85%,transparent)}
|
||||
#lyrics.none{color:var(--dim);font-style:italic;display:grid;place-items:center}
|
||||
#lyrics .sec{display:block;color:var(--dim);font:600 10px var(--font);letter-spacing:.2em;margin:12px 0 2px}
|
||||
#lyrics .sec:first-child{margin-top:0}
|
||||
#cover{cursor:pointer}
|
||||
@@ -146,8 +152,11 @@ input,textarea{font:inherit;color:inherit}
|
||||
<button id="libBtn">LIBRARY</button>
|
||||
</div>
|
||||
<div id="stage">
|
||||
<div id="cover"><canvas width="760" height="760"></canvas><div class="veil">COOKING</div></div>
|
||||
<div id="meta"><h1 id="title">…</h1><p id="tags"></p><p id="lyric"></p><button id="lyricsBtn" class="hidden">LYRICS</button><pre id="lyrics" class="hidden"></pre></div>
|
||||
<div id="cover"><div class="card">
|
||||
<div class="face"><canvas width="760" height="760"></canvas><div class="veil">COOKING</div></div>
|
||||
<div class="face back"><div class="backTitle">LYRICS</div><pre id="lyrics"></pre></div>
|
||||
</div></div>
|
||||
<div id="meta"><h1 id="title">…</h1><p id="tags"></p><p id="lyric"></p><button id="lyricsBtn">LYRICS · FLIP</button></div>
|
||||
<div id="bar"><i></i></div>
|
||||
<div id="controls">
|
||||
<button id="prev" title="replay">
|
||||
@@ -518,21 +527,19 @@ $("#seedForm").addEventListener("submit", (e) => {
|
||||
});
|
||||
/* lyrics: the DJ's words for the track, under the title; tap LYRICS or the cover */
|
||||
function showLyrics(spec) {
|
||||
const has = !!(spec.lyrics && spec.lyrics.trim()), b = $("#lyricsBtn"), p = $("#lyrics");
|
||||
b.classList.toggle("hidden", !has); b.textContent = has ? "LYRICS" : "";
|
||||
p.innerHTML = "";
|
||||
if (!has) { p.classList.add("hidden"); b.classList.remove("on"); return; }
|
||||
const has = !!(spec.lyrics && spec.lyrics.trim()), p = $("#lyrics");
|
||||
p.innerHTML = ""; p.classList.toggle("none", !has);
|
||||
if (!has) { p.textContent = "instrumental"; return; }
|
||||
for (const line of spec.lyrics.split(/\r?\n/)) {
|
||||
const m = line.match(/^\s*\[([^\]]+)\]\s*$/);
|
||||
if (m) p.append(Object.assign(document.createElement("span"), { className: "sec", textContent: m[1].toUpperCase() }));
|
||||
else p.append(document.createTextNode(line + "\n"));
|
||||
}
|
||||
if (state.lyricsOpen) { p.classList.remove("hidden"); b.classList.add("on"); }
|
||||
}
|
||||
function toggleLyrics() {
|
||||
if ($("#lyricsBtn").classList.contains("hidden")) return;
|
||||
state.lyricsOpen = !state.lyricsOpen;
|
||||
$("#lyrics").classList.toggle("hidden", !state.lyricsOpen); $("#lyricsBtn").classList.toggle("on", state.lyricsOpen);
|
||||
$("#cover").classList.toggle("flipped", state.lyricsOpen); $("#lyricsBtn").classList.toggle("on", state.lyricsOpen);
|
||||
$("#lyricsBtn").textContent = state.lyricsOpen ? "COVER · FLIP" : "LYRICS · FLIP";
|
||||
}
|
||||
$("#lyricsBtn").addEventListener("click", toggleLyrics);
|
||||
$("#cover").addEventListener("click", toggleLyrics);
|
||||
|
||||
Reference in new issue
Block a user