Give the empty-home playlist grid the full pane height instead of a clipped 16:9 box

This commit is contained in:
Jonathan Sykes
2026-08-16 08:52:18 +00:00
parent 4fd68ae88e
commit 5a9304780a
2 changed files with 37 additions and 1 deletions

View File

@@ -1995,8 +1995,10 @@ function renderHomePlaylists() {
wrap.classList.toggle('hidden', !lists.length);
hero.classList.toggle('hidden', !!lists.length);
// The hero is centered art; the grid wants the full box, so the placeholder
// switches from centering to stretching (and tightens its padding).
// switches from centering to stretching (and tightens its padding), and the
// stage drops its 16:9 lock so the grid gets the pane's real height.
if (els.placeholder) els.placeholder.classList.toggle('showing-playlists', !!lists.length);
if (els.playerPane) els.playerPane.classList.toggle('home-playlists', !!lists.length);
if (!lists.length) { grid.innerHTML = ''; return; }
grid.innerHTML = '';
@@ -2024,6 +2026,20 @@ function renderHomePlaylists() {
});
grid.appendChild(card);
}
// Measure after layout — scrollHeight is meaningless until the cards lay out.
requestAnimationFrame(updateHomeGridScrollState);
}
// With enough playlists the grid still has to scroll. Flag when it genuinely
// overflows (and whether it's at the end) so the CSS fades the bottom edge
// instead of slicing the last row against a hard border.
function updateHomeGridScrollState() {
const grid = document.getElementById('homePlGrid');
if (!grid) return;
const overflows = grid.scrollHeight > grid.clientHeight + 1;
grid.classList.toggle('is-scrollable', overflows);
grid.classList.toggle('at-end', !overflows ||
grid.scrollTop + grid.clientHeight >= grid.scrollHeight - 2);
}
function currentList() {
@@ -3353,6 +3369,8 @@ function wireUI() {
// ---- Empty-home playlist grid ----
$('homePlNewBtn').addEventListener('click', () => newPlaylist(null));
$('homePlGrid').addEventListener('scroll', updateHomeGridScrollState, { passive: true });
window.addEventListener('resize', updateHomeGridScrollState);
els.searchForm.addEventListener('submit', async (e) => {
e.preventDefault();

View File

@@ -366,6 +366,21 @@ body::after {
/* Empty home: the playlist grid takes the hero's place once playlists exist */
.player-placeholder.showing-playlists { padding: 16px; align-items: stretch; }
/* The 16:9 stage exists to hold a video, and on the empty home there isn't one
(controls / now-meta / up-next are hidden too). Constraining the playlist
grid to that short box clipped it mid-card, so let the stage take the pane's
height instead. Reverts the moment something plays — `.empty` comes off. */
.player-pane.empty.home-playlists .player-stage {
aspect-ratio: auto;
flex: 1 1 auto;
min-height: 260px;
}
/* Bottom fade, applied only while the grid actually overflows and isn't
scrolled to the end — a half-row under a hard edge reads as broken. */
.home-pl-grid.is-scrollable:not(.at-end) {
-webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 30px), transparent 100%);
mask-image: linear-gradient(180deg, #000 calc(100% - 30px), transparent 100%);
}
.home-pl {
flex: 1 1 auto; align-self: stretch; min-width: 0; max-height: 100%;
display: flex; flex-direction: column; gap: 10px;
@@ -1425,6 +1440,9 @@ input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.25); }
/* Empty-home playlist grid: the player stage is short on phones, so pack in
more, smaller cards rather than one oversized full-width column. */
.player-placeholder.showing-playlists { padding: 12px; }
/* …but don't let it eat the whole screen — the list pane must stay reachable
without scrolling past a full-height board. */
.player-pane.empty.home-playlists .player-stage { max-height: 58vh; }
.home-pl-grid { grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 10px; }
.home-pl-title { font-size: 15px; }
.home-pl-name { font-size: 12px; }