From 8e623e3d8d2b634c66e182c1cee9e50012ad2f3f Mon Sep 17 00:00:00 2001 From: KeelrLeek <156356974+KeelrLeek@users.noreply.github.com> Date: Sat, 25 Jul 2026 20:20:17 -0500 Subject: [PATCH] artist page: put the load status in the chip row it hands over to The floating pill worked but sat in the wrong place and at the wrong scale: top right of the pane, far from the content it describes, 30px tall with 12px text against a row of 27px chips at 11.5px. The stat chips are gated on `!page.art_preview` -- they do not exist yet while the page resolves. So the status simply takes their slot and hands the row over when they arrive: same container, same `.chip` metrics, with only a spinning accent ring and a softer label colour of its own. Measured across the handover, the status chip and the first real chip occupy the identical box (x 230, y 1145, height 27), and neither the row top nor the play button moves. That also keeps the property the floating version was chosen for. Nothing reflows when the status goes, because it is the only thing in the row and the chips that replace it start at the same origin -- no absolute positioning, no z-index fight with the sticky .results-head, and no element parked outside the layout it belongs to. --- src/views/CatalogArtist.svelte | 72 +++++++++++++--------------------- 1 file changed, 27 insertions(+), 45 deletions(-) diff --git a/src/views/CatalogArtist.svelte b/src/views/CatalogArtist.svelte index ac404c9..d61b15e 100644 --- a/src/views/CatalogArtist.svelte +++ b/src/views/CatalogArtist.svelte @@ -3423,14 +3423,6 @@ single pixel of content. It must NOT live in .fade-flow with the rest of the body: that carries a transform and sits inside the clipped .fade-frame, which would both re-anchor and mask it. --> - {#if page.art_preview} -
- - {page.albums.length || popularTracks.length - ? "Refining release details" - : "Loading songs and releases"} -
- {/if} +
+ + + {page.albums.length || popularTracks.length + ? "Refining release details" + : "Loading songs and releases"} + +
{/if} {/if} @@ -6259,61 +6267,35 @@ contain-intrinsic-size: auto 360px; } - /* Transient load status, pinned to the pane's top-right and out of flow. - It shares the top band with the sticky .results-head (z-index 40), which - is why this has to clear 40 rather than merely clearing .scrollbody's 3 — - at any lower value the bar paints straight over it and the pill is - invisible with no other symptom. */ - .stage-pill { - position: absolute; - top: 16px; - right: 20px; - z-index: 41; - display: inline-flex; - align-items: center; - gap: 9px; - height: 30px; - padding: 0 14px; - border-radius: 15px; - background: rgba(14, 14, 16, 0.72); - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0 6px 22px rgba(0, 0, 0, 0.4); - backdrop-filter: blur(14px); - color: var(--text-secondary); - font-size: 12px; - font-weight: 500; - white-space: nowrap; + /* Load status wearing the stat chip's own metrics — it stands in for those + chips while they resolve, so it must measure exactly like them or the row + changes height as it hands over. Inherits .chip for everything but the + spinner and the slightly softer label colour. */ + .stage-chip { + gap: 8px; + color: rgba(255, 255, 255, 0.62); pointer-events: none; - animation: stage-pill-in 180ms ease-out; } - .stage-pill .ring { + .stage-chip .ring { width: 11px; height: 11px; border-radius: 50%; border: 2px solid var(--accent); border-right-color: transparent; - animation: stage-pill-spin 0.9s linear infinite; + animation: stage-chip-spin 0.9s linear infinite; } - @keyframes stage-pill-spin { + @keyframes stage-chip-spin { to { transform: rotate(360deg); } } - @keyframes stage-pill-in { - from { - opacity: 0; - transform: translateY(-4px); - } - } - /* The spinner is decoration; honour a reduced-motion preference by holding it still rather than removing the only signal that work is happening. */ @media (prefers-reduced-motion: reduce) { - .stage-pill, - .stage-pill .ring { + .stage-chip .ring { animation: none; } }