Add a mobile section rail that follows the scroll, jumps between cards and folds the one you are on

This commit is contained in:
Jonathan Sykes
2026-09-22 13:47:26 +08:00
parent 987697e759
commit 530d07d920
4 changed files with 333 additions and 3 deletions

View File

@@ -4135,3 +4135,101 @@ body.landscape-fs .player-stage { touch-action: none; } /* fullscreen (real or t
@media (prefers-reduced-motion: reduce) {
.sync-spinner { animation-duration: 2.4s; }
}
/* ==========================================================================
Foldable cards + the mobile section rail
========================================================================== */
/* Folding hides a card's body but never its header, so the card stays a
visible landmark (and a tap target) when collapsed. */
#notesPanel.folded .notes-pane,
#nowPlayingMeta.folded .np-actions,
#relatedPanel.folded .related-list { display: none !important; }
#notesPanel.folded .notes-tabs { border-bottom: 0; margin-bottom: 0; }
.notes-fold {
margin-left: 6px;
background: transparent;
border: 1px solid transparent;
color: var(--text-dim);
border-radius: 8px;
width: 30px; height: 30px;
font-size: 13px;
cursor: pointer;
flex: none;
transition: transform 0.16s var(--ease), color 0.16s var(--ease);
}
.notes-fold:hover { color: var(--text); border-color: var(--line); }
#notesPanel.folded .notes-fold { transform: rotate(-90deg); }
/* --- the rail ------------------------------------------------------------ */
.sec-rail {
position: fixed;
right: 8px;
top: 50%;
transform: translateY(-50%);
z-index: 60;
display: flex;
flex-direction: column;
gap: 6px;
padding: 6px 5px;
border-radius: 999px;
background: color-mix(in srgb, var(--bg-1) 84%, transparent);
border: 1px solid var(--line);
box-shadow: var(--shadow);
backdrop-filter: blur(10px);
}
.sec-rail-btn {
width: 36px; height: 36px;
border-radius: 50%;
border: 1px solid transparent;
background: transparent;
color: var(--text-2);
font-size: 15px;
line-height: 1;
display: flex; align-items: center; justify-content: center;
cursor: pointer;
position: relative;
padding: 0;
transition: background 0.16s var(--ease), color 0.16s var(--ease);
}
.sec-rail-btn:active { transform: scale(0.94); }
.sec-rail-btn.active {
background: color-mix(in srgb, var(--accent) 20%, transparent);
color: var(--text);
border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
/* A folded card's icon is dimmed and marked, so the rail doubles as a map of
what is currently collapsed. */
.sec-rail-btn.folded { opacity: 0.55; }
.sec-rail-btn.folded::after {
content: "";
position: absolute;
left: 8px; right: 8px; bottom: 6px;
height: 2px;
border-radius: 2px;
background: var(--text-dim);
}
.sec-rail-label {
position: absolute;
right: 44px;
white-space: nowrap;
background: var(--bg-1);
border: 1px solid var(--line);
color: var(--text);
font-size: 12px;
padding: 4px 9px;
border-radius: 8px;
opacity: 0;
pointer-events: none;
transition: opacity 0.16s var(--ease);
box-shadow: var(--shadow);
}
.sec-rail-btn.show-label .sec-rail-label { opacity: 1; }
/* Phones only — on desktop the whole page is visible at once. */
@media (min-width: 861px) { .sec-rail { display: none !important; } }
@media (max-width: 860px) {
/* clear of the bottom nav / mini player */
.sec-rail { top: auto; bottom: 132px; transform: none; }
}