fix: button focus ring, playlist reorder mode, edit modal mobile, backdrop-filter
- button:focus{outline:none} — removes the blue tap-highlight box in WebView
- Playlist reorder: replaced always-on drag handles with explicit 'Neu anordnen'
mode. Handles only appear after tapping the button; a sticky Speichern/Abbrechen
bar appears above the list. Touch drag is now fully supported. Context-menu
(long-press) is blocked while reorder mode is active to prevent conflicts.
- styles.css: .pl-drag-handle always visible when pl-draggable (no hover needed)
- Edit modal footer: wrap buttons on small screens so Save doesn't overflow
- Edit modal overlay: remove backdrop-filter:blur — causes WebView compositor
glitch where 3/4 of the modal disappears after returning from background
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
68bec67880
commit
9d8a5a22bb
4 files changed
+112
-36
No files matched your search
@@ -260,6 +260,7 @@
|
|||||||
<button class="btn-play-all" id="btn-play-playlist"><svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>Abspielen</button>
|
<button class="btn-play-all" id="btn-play-playlist"><svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>Abspielen</button>
|
||||||
<button class="btn-outline" id="btn-shuffle-playlist"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/><polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/></svg>Shuffle</button>
|
<button class="btn-outline" id="btn-shuffle-playlist"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/><polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/></svg>Shuffle</button>
|
||||||
<button class="btn-outline" id="btn-edit-playlist"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>Bearbeiten</button>
|
<button class="btn-outline" id="btn-edit-playlist"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>Bearbeiten</button>
|
||||||
|
<button class="btn-outline" id="btn-reorder-playlist"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>Neu anordnen</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -267,6 +268,13 @@
|
|||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||||
<input id="playlist-search" class="list-search" type="text" placeholder="In Playlist suchen…" oninput="filterPlaylist(this.value)">
|
<input id="playlist-search" class="list-search" type="text" placeholder="In Playlist suchen…" oninput="filterPlaylist(this.value)">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="pl-reorder-bar" id="pl-reorder-bar" style="display:none">
|
||||||
|
<span>Reihenfolge ändern</span>
|
||||||
|
<div style="display:flex;gap:8px">
|
||||||
|
<button class="edit-pl-btn-cancel" onclick="plReorderCancel()">Abbrechen</button>
|
||||||
|
<button class="edit-pl-btn-save" onclick="plReorderSave()">Speichern</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="song-list" id="playlist-songs"></div>
|
<div class="song-list" id="playlist-songs"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -16,6 +16,7 @@ import {
|
|||||||
onGlobalSearch, s_goArtist, s_goAlbum, playerBarGoArtist, playerBarGoAlbum,
|
onGlobalSearch, s_goArtist, s_goAlbum, playerBarGoArtist, playerBarGoAlbum,
|
||||||
searchSimilarArtist, searchAndPreview, loadItunesAlbum, expandArtistBio,
|
searchSimilarArtist, searchAndPreview, loadItunesAlbum, expandArtistBio,
|
||||||
loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist,
|
loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist,
|
||||||
|
plReorderEnter, plReorderSave, plReorderCancel,
|
||||||
} from './views.js';
|
} from './views.js';
|
||||||
import { loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll } from './spotify.js';
|
import { loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll } from './spotify.js';
|
||||||
import {
|
import {
|
||||||
@@ -282,7 +283,9 @@ Object.assign(window, {
|
|||||||
openSettings, closeSettings, saveSettings, confirmDisconnect, checkBackend,
|
openSettings, closeSettings, saveSettings, confirmDisconnect, checkBackend,
|
||||||
openSidebar, closeSidebar, switchNavMode, showCtxMenu,
|
openSidebar, closeSidebar, switchNavMode, showCtxMenu,
|
||||||
// Views
|
// Views
|
||||||
loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist, loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll,
|
loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist,
|
||||||
|
plReorderEnter, plReorderSave, plReorderCancel,
|
||||||
|
loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll,
|
||||||
executeSpotifyDownload,
|
executeSpotifyDownload,
|
||||||
openPlModal, closePlModal, addSongsToPlaylist, createAndAddPlaylist, createPlaylistPrompt,
|
openPlModal, closePlModal, addSongsToPlaylist, createAndAddPlaylist, createPlaylistPrompt,
|
||||||
showSongInfo, closeInfoModal,
|
showSongInfo, closeInfoModal,
|
||||||
|
|||||||
+89
-32
@@ -557,11 +557,10 @@ export async function loadPlaylistDetail(pl) {
|
|||||||
playQueue(shuffled, 0);
|
playQueue(shuffled, 0);
|
||||||
};
|
};
|
||||||
sl.innerHTML = '';
|
sl.innerHTML = '';
|
||||||
sl.classList.add('pl-draggable');
|
|
||||||
const plSearch = document.getElementById('playlist-search');
|
const plSearch = document.getElementById('playlist-search');
|
||||||
if (plSearch) plSearch.value = '';
|
if (plSearch) plSearch.value = '';
|
||||||
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noArtistLink: true, noAlbumLink: true })));
|
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noArtistLink: true, noAlbumLink: true })));
|
||||||
_initPlaylistDragDrop(sl, songs, S._currentPlaylist);
|
_setupReorderMode(sl, songs, S._currentPlaylist);
|
||||||
} catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
|
} catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,9 +573,28 @@ export function filterPlaylist(val) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function _initPlaylistDragDrop(container, songs, pl) {
|
// ─── PLAYLIST REORDER MODE ───────────────────────────────────────────────
|
||||||
let dragSrc = null;
|
let _reorderCtx = null;
|
||||||
let saveTimer = null;
|
|
||||||
|
function _setupReorderMode(container, songs, pl) {
|
||||||
|
// Exit any previous reorder mode silently when loading a new playlist.
|
||||||
|
if (_reorderCtx) _exitReorderMode(false);
|
||||||
|
_reorderCtx = { container, songs, pl };
|
||||||
|
const btn = document.getElementById('btn-reorder-playlist');
|
||||||
|
if (btn) btn.onclick = plReorderEnter;
|
||||||
|
const bar = document.getElementById('pl-reorder-bar');
|
||||||
|
if (bar) bar.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function plReorderEnter() {
|
||||||
|
if (!_reorderCtx) return;
|
||||||
|
const { container, songs } = _reorderCtx;
|
||||||
|
container.classList.add('pl-draggable');
|
||||||
|
// Block context-menu (long-press) on all items while reordering.
|
||||||
|
container.addEventListener('contextmenu', _blockCtxMenu, true);
|
||||||
|
|
||||||
|
let dragSrc = null;
|
||||||
|
let touchDragSrc = null;
|
||||||
|
|
||||||
Array.from(container.children).forEach((item, i) => {
|
Array.from(container.children).forEach((item, i) => {
|
||||||
const handle = document.createElement('div');
|
const handle = document.createElement('div');
|
||||||
@@ -585,54 +603,93 @@ function _initPlaylistDragDrop(container, songs, pl) {
|
|||||||
item.insertBefore(handle, item.firstChild);
|
item.insertBefore(handle, item.firstChild);
|
||||||
item._songRef = songs[i];
|
item._songRef = songs[i];
|
||||||
|
|
||||||
// Track whether drag started from the handle (e.target in dragstart is always the item, not the handle)
|
// ── Desktop drag ──
|
||||||
let fromHandle = false;
|
let fromHandle = false;
|
||||||
handle.addEventListener('mousedown', () => { fromHandle = true; item.draggable = true; });
|
handle.addEventListener('mousedown', () => { fromHandle = true; item.draggable = true; });
|
||||||
|
|
||||||
item.addEventListener('dragstart', e => {
|
item.addEventListener('dragstart', e => {
|
||||||
if (!fromHandle) { e.preventDefault(); item.draggable = false; return; }
|
if (!fromHandle) { e.preventDefault(); item.draggable = false; return; }
|
||||||
fromHandle = false;
|
fromHandle = false; dragSrc = item;
|
||||||
dragSrc = item;
|
|
||||||
e.dataTransfer.effectAllowed = 'move';
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
e.dataTransfer.setData('text/plain', ''); // required by Firefox
|
e.dataTransfer.setData('text/plain', '');
|
||||||
setTimeout(() => item.classList.add('dragging'), 0);
|
setTimeout(() => item.classList.add('dragging'), 0);
|
||||||
});
|
});
|
||||||
item.addEventListener('dragend', () => {
|
item.addEventListener('dragend', () => {
|
||||||
fromHandle = false;
|
fromHandle = false; item.draggable = false; dragSrc = null;
|
||||||
item.draggable = false;
|
|
||||||
dragSrc = null;
|
|
||||||
item.classList.remove('dragging');
|
item.classList.remove('dragging');
|
||||||
container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));
|
container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));
|
||||||
});
|
});
|
||||||
item.addEventListener('dragover', e => {
|
item.addEventListener('dragover', e => {
|
||||||
e.preventDefault();
|
e.preventDefault(); e.dataTransfer.dropEffect = 'move';
|
||||||
e.dataTransfer.dropEffect = 'move';
|
|
||||||
if (item === dragSrc) return;
|
if (item === dragSrc) return;
|
||||||
container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));
|
container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));
|
||||||
item.classList.add('drag-over');
|
item.classList.add('drag-over');
|
||||||
});
|
});
|
||||||
item.addEventListener('dragleave', e => {
|
item.addEventListener('dragleave', e => { if (!item.contains(e.relatedTarget)) item.classList.remove('drag-over'); });
|
||||||
if (!item.contains(e.relatedTarget)) item.classList.remove('drag-over');
|
|
||||||
});
|
|
||||||
item.addEventListener('drop', e => {
|
item.addEventListener('drop', e => {
|
||||||
e.preventDefault();
|
e.preventDefault(); e.stopPropagation();
|
||||||
e.stopPropagation();
|
|
||||||
if (!dragSrc || item === dragSrc) return;
|
if (!dragSrc || item === dragSrc) return;
|
||||||
item.classList.remove('drag-over');
|
item.classList.remove('drag-over');
|
||||||
const allItems = Array.from(container.children);
|
_doReorder(container, songs, dragSrc, item);
|
||||||
const fromIdx = allItems.indexOf(dragSrc);
|
|
||||||
const toIdx = allItems.indexOf(item);
|
|
||||||
container.insertBefore(dragSrc, fromIdx < toIdx ? item.nextSibling : item);
|
|
||||||
const newOrder = Array.from(container.children).map(el => el._songRef);
|
|
||||||
songs.splice(0, songs.length, ...newOrder);
|
|
||||||
Array.from(container.children).forEach((el, idx) => {
|
|
||||||
const n = el.querySelector('.song-num');
|
|
||||||
if (n) n.textContent = idx + 1;
|
|
||||||
});
|
|
||||||
clearTimeout(saveTimer);
|
|
||||||
saveTimer = setTimeout(() => _savePlaylistOrder(pl, songs), 800);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── Touch drag ──
|
||||||
|
handle.addEventListener('touchstart', e => {
|
||||||
|
e.preventDefault(); e.stopPropagation();
|
||||||
|
touchDragSrc = item; item.classList.add('dragging');
|
||||||
|
}, { passive: false });
|
||||||
|
handle.addEventListener('touchmove', e => {
|
||||||
|
if (!touchDragSrc) return;
|
||||||
|
e.preventDefault();
|
||||||
|
const t = e.touches[0];
|
||||||
|
container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));
|
||||||
|
const over = _itemAtPoint(container, t.clientX, t.clientY, touchDragSrc);
|
||||||
|
if (over) over.classList.add('drag-over');
|
||||||
|
}, { passive: false });
|
||||||
|
handle.addEventListener('touchend', e => {
|
||||||
|
if (!touchDragSrc) return;
|
||||||
|
const t = e.changedTouches[0];
|
||||||
|
touchDragSrc.classList.remove('dragging');
|
||||||
|
container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));
|
||||||
|
const over = _itemAtPoint(container, t.clientX, t.clientY, touchDragSrc);
|
||||||
|
if (over) _doReorder(container, songs, touchDragSrc, over);
|
||||||
|
touchDragSrc = null;
|
||||||
|
}, { passive: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const bar = document.getElementById('pl-reorder-bar');
|
||||||
|
if (bar) bar.style.display = 'flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
function _blockCtxMenu(e) { e.preventDefault(); e.stopPropagation(); }
|
||||||
|
|
||||||
|
function _itemAtPoint(container, x, y, exclude) {
|
||||||
|
return (document.elementsFromPoint(x, y) || [])
|
||||||
|
.find(el => el.classList?.contains('song-item') && el !== exclude && container.contains(el)) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _doReorder(container, songs, src, target) {
|
||||||
|
const all = Array.from(container.children);
|
||||||
|
const from = all.indexOf(src), to = all.indexOf(target);
|
||||||
|
container.insertBefore(src, from < to ? target.nextSibling : target);
|
||||||
|
const newOrder = Array.from(container.children).map(el => el._songRef);
|
||||||
|
songs.splice(0, songs.length, ...newOrder);
|
||||||
|
Array.from(container.children).forEach((el, i) => {
|
||||||
|
const n = el.querySelector('.song-num'); if (n) n.textContent = i + 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function plReorderSave() { _exitReorderMode(true); }
|
||||||
|
export function plReorderCancel() { _exitReorderMode(false); }
|
||||||
|
|
||||||
|
function _exitReorderMode(save) {
|
||||||
|
if (!_reorderCtx) return;
|
||||||
|
const { container, songs, pl } = _reorderCtx;
|
||||||
|
container.classList.remove('pl-draggable');
|
||||||
|
container.removeEventListener('contextmenu', _blockCtxMenu, true);
|
||||||
|
container.querySelectorAll('.pl-drag-handle').forEach(h => h.remove());
|
||||||
|
const bar = document.getElementById('pl-reorder-bar');
|
||||||
|
if (bar) bar.style.display = 'none';
|
||||||
|
if (save) _savePlaylistOrder(pl, songs);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _savePlaylistOrder(pl, songs) {
|
async function _savePlaylistOrder(pl, songs) {
|
||||||
|
|||||||
+11
-3
@@ -165,6 +165,8 @@ nav{flex:1;overflow-y:auto;padding:4px 10px}
|
|||||||
.gtrack-actions{display:flex;align-items:center;gap:6px;opacity:0;transition:opacity .15s}
|
.gtrack-actions{display:flex;align-items:center;gap:6px;opacity:0;transition:opacity .15s}
|
||||||
.gtrack-item:hover .gtrack-actions{opacity:1}
|
.gtrack-item:hover .gtrack-actions{opacity:1}
|
||||||
|
|
||||||
|
button:focus{outline:none}
|
||||||
|
|
||||||
/* ── ICON BTN ── */
|
/* ── ICON BTN ── */
|
||||||
.icon-btn{background:none;border:none;color:var(--text2);cursor:pointer;padding:6px;border-radius:6px;display:flex;align-items:center;transition:color .15s,background .15s}
|
.icon-btn{background:none;border:none;color:var(--text2);cursor:pointer;padding:6px;border-radius:6px;display:flex;align-items:center;transition:color .15s,background .15s}
|
||||||
.icon-btn:hover{color:var(--accent);background:var(--accent-dim)}
|
.icon-btn:hover{color:var(--accent);background:var(--accent-dim)}
|
||||||
@@ -193,8 +195,9 @@ nav{flex:1;overflow-y:auto;padding:4px 10px}
|
|||||||
/* ── PLAYLIST DRAG & DROP ── */
|
/* ── PLAYLIST DRAG & DROP ── */
|
||||||
.song-list.pl-draggable .song-item{grid-template-columns:18px 32px 44px 1fr auto}
|
.song-list.pl-draggable .song-item{grid-template-columns:18px 32px 44px 1fr auto}
|
||||||
.pl-drag-handle{display:flex;align-items:center;justify-content:center;color:var(--text3);opacity:0;cursor:grab;transition:opacity .15s;touch-action:none}
|
.pl-drag-handle{display:flex;align-items:center;justify-content:center;color:var(--text3);opacity:0;cursor:grab;transition:opacity .15s;touch-action:none}
|
||||||
.song-list.pl-draggable .song-item:hover .pl-drag-handle{opacity:1}
|
.song-list.pl-draggable .pl-drag-handle{opacity:1}
|
||||||
.pl-drag-handle:active{cursor:grabbing}
|
.pl-drag-handle:active{cursor:grabbing}
|
||||||
|
.pl-reorder-bar{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--surface);border-radius:10px;margin-bottom:8px;font-size:13px;color:var(--text2);gap:10px}
|
||||||
.song-item.dragging{opacity:0.35}
|
.song-item.dragging{opacity:0.35}
|
||||||
.song-item.drag-over{box-shadow:0 -2px 0 var(--accent)}
|
.song-item.drag-over{box-shadow:0 -2px 0 var(--accent)}
|
||||||
|
|
||||||
@@ -389,7 +392,7 @@ nav{flex:1;overflow-y:auto;padding:4px 10px}
|
|||||||
.pl-btns button{flex:1;padding:10px;border-radius:8px;font-family:var(--font);font-size:13px;font-weight:600;cursor:pointer;border:none}
|
.pl-btns button{flex:1;padding:10px;border-radius:8px;font-family:var(--font);font-size:13px;font-weight:600;cursor:pointer;border:none}
|
||||||
|
|
||||||
/* ── EDIT PLAYLIST MODAL ── */
|
/* ── EDIT PLAYLIST MODAL ── */
|
||||||
.edit-pl-overlay{position:fixed;inset:0;background:rgba(0,0,0,.72);backdrop-filter:blur(5px);z-index:500;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .2s}
|
.edit-pl-overlay{position:fixed;inset:0;background:rgba(0,0,0,.8);z-index:500;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .2s}
|
||||||
.edit-pl-overlay.open{opacity:1;pointer-events:all}
|
.edit-pl-overlay.open{opacity:1;pointer-events:all}
|
||||||
.edit-pl-box{width:min(580px,calc(100vw - 24px));background:var(--surface);border:1px solid var(--border2);border-radius:18px;box-shadow:0 40px 80px rgba(0,0,0,.8);overflow:hidden}
|
.edit-pl-box{width:min(580px,calc(100vw - 24px));background:var(--surface);border:1px solid var(--border2);border-radius:18px;box-shadow:0 40px 80px rgba(0,0,0,.8);overflow:hidden}
|
||||||
.edit-pl-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px 16px;font-size:18px;font-weight:700;border-bottom:1px solid var(--border)}
|
.edit-pl-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px 16px;font-size:18px;font-weight:700;border-bottom:1px solid var(--border)}
|
||||||
@@ -422,7 +425,12 @@ nav{flex:1;overflow-y:auto;padding:4px 10px}
|
|||||||
.confirm-title{font-size:17px;font-weight:700;margin-bottom:10px}
|
.confirm-title{font-size:17px;font-weight:700;margin-bottom:10px}
|
||||||
.confirm-msg{font-size:14px;color:var(--text2);line-height:1.5;margin-bottom:24px}
|
.confirm-msg{font-size:14px;color:var(--text2);line-height:1.5;margin-bottom:24px}
|
||||||
.confirm-footer{display:flex;justify-content:flex-end;gap:10px}
|
.confirm-footer{display:flex;justify-content:flex-end;gap:10px}
|
||||||
@media(max-width:480px){.edit-pl-body{flex-direction:column;align-items:center}.edit-pl-cover-wrap{width:140px;height:140px}}
|
@media(max-width:480px){
|
||||||
|
.edit-pl-body{flex-direction:column;align-items:center}
|
||||||
|
.edit-pl-cover-wrap{width:140px;height:140px}
|
||||||
|
.edit-pl-footer{flex-wrap:wrap;padding:12px 16px;gap:8px}
|
||||||
|
.edit-pl-footer>div{margin-left:auto}
|
||||||
|
}
|
||||||
|
|
||||||
/* ── SONG INFO MODAL ── */
|
/* ── SONG INFO MODAL ── */
|
||||||
.info-modal{position:fixed;inset:0;background:rgba(0,0,0,.65);backdrop-filter:blur(4px);z-index:400;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .2s}
|
.info-modal{position:fixed;inset:0;background:rgba(0,0,0,.65);backdrop-filter:blur(4px);z-index:400;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .2s}
|
||||||
|
|||||||
Reference in new issue
Block a user