summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/style.css
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/style.css')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/style.css141
1 files changed, 141 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/style.css b/packages/meshbay-hub/src/meshbay_hub/static/style.css
index f46e5c2..5642262 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/style.css
+++ b/packages/meshbay-hub/src/meshbay_hub/static/style.css
@@ -4167,6 +4167,8 @@ h2 .gn-owner, h3 .gn-owner { font-size: 0.55em; }
.music-tile-slot { min-height: 200px; }
.music-card {
+ /* The dots button floats over the cover's top-right corner. */
+ position: relative;
cursor: pointer;
border-radius: 8px;
overflow: hidden;
@@ -4288,6 +4290,25 @@ h2 .gn-owner, h3 .gn-owner { font-size: 0.55em; }
cursor: pointer;
text-align: left;
}
+/* The row holds two controls — play it, and its menu — so it is a div, and
+ the play action is the button inside it. A button cannot contain another
+ button: the browser reparents the inner one and the row comes apart.
+ music-player.js's queue panel has no menu and is still a plain button, which
+ is why `cursor` stays on the row rather than moving to the child. */
+.music-track-main {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ flex: 1;
+ min-width: 0;
+ padding: 0;
+ border: none;
+ background: none;
+ color: inherit;
+ font: inherit;
+ text-align: left;
+ cursor: pointer;
+}
.music-track-row:hover { background: var(--bg-raised); border-color: var(--border); }
.music-track-row.active { border-color: var(--accent); color: var(--accent); }
.music-track-no { width: 24px; flex-shrink: 0; color: var(--text-dim); text-align: right; }
@@ -5000,3 +5021,123 @@ h2 .gn-owner, h3 .gn-owner { font-size: 0.55em; }
white-space: nowrap;
border: 0;
}
+
+/* ── Pop-up menus (menu.js) ────────────────────────────────────────────────
+ One panel, opened at a point, for right-click on a cover and for the dots
+ button beside a track. `position: fixed` because the coordinates come from
+ a pointer or a `getBoundingClientRect()` — both viewport-relative, and an
+ absolutely-positioned panel would be offset by whatever happens to be
+ scrolled. menu.js measures and flips it; nothing here knows where it goes.
+ docs/playlists.md §10.1. */
+
+.ctx-menu {
+ position: fixed;
+ /* Above everything, modals included: this menu is opened *from* the album
+ detail overlay, and `.video-overlay` is itself `position: fixed` at 200.
+ Equal values would leave it to DOM order, which is not a decision. */
+ z-index: 300;
+ min-width: 220px;
+ max-width: calc(100vw - 16px);
+ /* A playlist's tracklist expands inside this panel rather than flying out
+ sideways, so it can be far taller than the window. Same answer the
+ account menu's language list already has. */
+ max-height: calc(100vh - 16px);
+ overflow-x: hidden;
+ overflow-y: auto;
+ padding: 4px 0;
+ background: var(--bg-surface);
+ border: 1px solid var(--border);
+ border-radius: 10px;
+ box-shadow: var(--shadow-lg);
+}
+
+.ctx-menu-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ width: 100%;
+ padding: 9px 14px;
+ border: none;
+ background: none;
+ color: var(--text);
+ font: inherit;
+ font-size: 0.9em;
+ text-align: left;
+ cursor: pointer;
+}
+.ctx-menu-item:hover:not(:disabled) { background: var(--sidebar-hover); }
+.ctx-menu-item:disabled { color: var(--text-dim); cursor: default; }
+.ctx-menu-item.danger { color: var(--error); }
+
+.ctx-menu-icon { width: 16px; height: 16px; flex-shrink: 0; }
+.ctx-menu-label {
+ flex: 1;
+ /* A track title is arbitrarily long and the panel is not: one line, cut,
+ rather than a menu as wide as the longest filename in the library. */
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.ctx-menu-hint { color: var(--text-dim); font-size: 0.85em; flex-shrink: 0; }
+.ctx-menu-caret {
+ width: 14px; height: 14px; flex-shrink: 0;
+ color: var(--text-dim);
+ transition: transform 0.15s;
+}
+.ctx-menu-caret.flip { transform: rotate(180deg); }
+
+.ctx-menu-divider { height: 1px; background: var(--border); margin: 4px 0; }
+
+.ctx-menu-empty {
+ padding: 8px 14px;
+ color: var(--text-dim);
+ font-size: 0.85em;
+}
+
+/* The dots button on a cover or a track row. Revealed on hover where there is
+ a pointer to hover with, and permanently visible where there is not — a
+ touchscreen has no hover state, and this is the *only* way in there. */
+.ctx-dots {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ width: 28px; height: 28px;
+ padding: 0;
+ border: none;
+ border-radius: 6px;
+ background: none;
+ color: var(--text-dim);
+ cursor: pointer;
+ opacity: 0;
+ transition: opacity 0.12s, background 0.12s;
+}
+.ctx-dots svg { width: 18px; height: 18px; }
+.ctx-dots:hover { background: var(--sidebar-hover); color: var(--text); }
+.ctx-dots:focus-visible { opacity: 1; outline: 2px solid var(--border-focus); }
+.music-card:hover .ctx-dots,
+.music-track-row:hover .ctx-dots { opacity: 1; }
+
+@media (hover: none), (pointer: coarse) {
+ .ctx-dots { opacity: 1; }
+}
+
+/* On a cover, floated over the top-right corner rather than taking a row of
+ its own — the grid's tiles are sized by their art. */
+.music-card-dots {
+ position: absolute;
+ top: 6px; right: 6px;
+ background: rgba(0, 0, 0, 0.55);
+ color: #fff;
+ backdrop-filter: blur(2px);
+}
+.music-card-dots:hover { background: rgba(0, 0, 0, 0.75); color: #fff; }
+
+/* A flat folder row expands on click; its menu button sits in the same row and
+ must not take the whole width with it. */
+.video-flat-row .ctx-dots { margin-left: auto; }
+.video-flat-row .ctx-dots + .video-flat-chevron { margin-left: 8px; }
+
+/* "Play all" and the album's menu, side by side under the cover. */
+.music-detail-actions { display: flex; align-items: center; gap: 6px; }
+.music-detail-actions .ctx-dots { opacity: 1; }