the panel tops speak one language: 28px discs, white glyphs, one veil

Kyle put four crops side by side and asked why the top chrome disagrees
with itself. The audit found five variants across three panel tops: the
glass bar's arrows (28px circle, white, 17px glyph, 0.12 white-veil
hover), the sidebar toggle and both Now Playing chevrons (28px 6px-radius
squares, grey, 16px, opaque --bg-highlight hover that slabs under glass
and a --glass-hover override that reads as nothing up here), the
add-to-playlist trigger (grey square, 15px glyph), and the save button
(34px 8px-radius square, 18px glyph).

One spec now, the arrows' language: 28x28 circle, 16px glyph, #fff at
rest, rgba(255,255,255,.12) hover in BOTH modes. This commit carries the
Now Playing header set — np-icon (head collapse + rail expand), the
plm-trigger override, and a new np-head override pulling SaveMenu's
trigger down from its 34px playbar size (SaveMenu grows an iconSize prop;
the playbar keeps 18, the head passes 16). The glass-hover overrides for
these buttons are gone — the base veil is mode-independent — except one
glass-scoped rule kept solely to outrank SaveMenu's own glass hover on
specificity. The bar arrows' 17->16 and the sidebar toggle's disc ride the
hub commit; their files carry that rework and split poorly.

Verified by computed style across all five controls: identical to the
pixel, and the disabled arrows stay dimmed white rather than grey so even
the off state is the same hue family.
This commit is contained in:
KeelrLeek committed 2026-08-31 15:13:24 -05:00
1 parent 2d8c385a2e
commit 913289a297
2 files changed
+34 -17

No files matched your search

+29 -15
View File
@@ -1291,7 +1291,7 @@
<PlaylistMenu <PlaylistMenu
compact compact
align="right" align="right"
iconSize={15} iconSize={16}
title="Add this track to a playlist" title="Add this track to a playlist"
tracks={() => [ tracks={() => [
{ {
@@ -1315,7 +1315,7 @@
only ACTION that did, so it comes up here rather than being only ACTION that did, so it comes up here rather than being
lost with it. --> lost with it. -->
{#if isStream && currentItem?.stream} {#if isStream && currentItem?.stream}
<SaveMenu align="down" /> <SaveMenu align="down" iconSize={16} />
{/if} {/if}
{#if isStream} {#if isStream}
<span class="hairline" class:seek={hairlineSeeking} class:done={cached} style="--buf:{bufferPct}%"><i></i></span> <span class="hairline" class:seek={hairlineSeeking} class:done={cached} style="--buf:{bufferPct}%"><i></i></span>
@@ -1855,11 +1855,16 @@
background: var(--glass-surface); background: var(--glass-surface);
box-shadow: var(--glass-ring); box-shadow: var(--glass-ring);
} }
:global(:root.glass) .np-icon:hover, :global(:root.glass) .row:hover {
:global(:root.glass) .row:hover,
:global(:root.glass) .np-head :global(.plm-trigger:hover) {
background: var(--glass-hover); background: var(--glass-hover);
} }
/* The header chrome keeps its 0.12 veil under glass too (the spec above)
— this exists only to outrank SaveMenu's own glass hover rule, which
otherwise wins on specificity and dims the save disc to 0.08. */
:global(:root.glass) .np-head :global(.save-icon:hover),
:global(:root.glass) .np-head :global(.save-icon.on) {
background: rgba(255, 255, 255, 0.12);
}
/* Artwork wells: what is visible while a cover loads, or in place of one /* Artwork wells: what is visible while a cover loads, or in place of one
that never arrives. */ that never arrives. */
:global(:root.glass) .cover, :global(:root.glass) .cover,
@@ -2239,25 +2244,34 @@
text-overflow: ellipsis; text-overflow: ellipsis;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35); text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
} }
/* Panel-top chrome spec (2026-08-31, Kyle's consistency audit): every
28px CIRCLE, white glyph at rest, white-veil hover — byte-for-byte the
glass bar's .arrow language, in both modes (0.12 is the established
chrome-position veil; --bg-highlight was an opaque slab under glass
and --glass-hover reads as nothing up here). */
.np-icon { .np-icon {
display: grid; display: grid;
place-items: center; place-items: center;
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 6px; border-radius: 50%;
color: var(--text-secondary); color: #fff;
} }
.np-icon:hover { background: var(--bg-highlight); color: var(--text-primary); } .np-icon:hover { background: rgba(255, 255, 255, 0.12); }
/* The add-to-playlist trigger wears the header-icon look exactly. */ /* The add-to-playlist and save triggers wear the header-icon look
.np-head :global(.plm-trigger) { exactly (SaveMenu's own 34px box is the playbar's — overridden here). */
.np-head :global(.plm-trigger),
.np-head :global(.save-icon) {
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 6px; border-radius: 50%;
color: var(--text-secondary); color: #fff;
} }
.np-head :global(.plm-trigger:hover) { .np-head :global(.plm-trigger:hover),
background: var(--bg-highlight); .np-head :global(.save-icon:hover),
color: var(--text-primary); .np-head :global(.save-icon.on) {
background: rgba(255, 255, 255, 0.12);
color: #fff;
} }
.np-scroll { .np-scroll {
+5 -2
View File
@@ -3,7 +3,10 @@
import Icon from "./Icon.svelte"; import Icon from "./Icon.svelte";
// align hint: "down" (panel) or "up" (player bar). Auto-flips if needed. // align hint: "down" (panel) or "up" (player bar). Auto-flips if needed.
let { align = "down" } = $props(); // iconSize: the playbar keeps the 18px transport glyph; the Now Playing
// header passes 16 to match the panel-top chrome spec (28px circle,
// 16px glyph — see the np-head overrides there).
let { align = "down", iconSize = 18 } = $props();
const currentItem = $derived(player.queue[player.queueIndex] ?? null); const currentItem = $derived(player.queue[player.queueIndex] ?? null);
const isStream = $derived(!!currentItem?.stream); const isStream = $derived(!!currentItem?.stream);
@@ -84,7 +87,7 @@
title="Save to library" title="Save to library"
onclick={onClick} onclick={onClick}
> >
<Icon name="download" size={18} /> <Icon name="download" size={iconSize} />
</button> </button>
</span> </span>