Android v1 polish + Web UI flavor pass #65
@@ -28,12 +28,16 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="card relative">
|
<div class="card group relative">
|
||||||
<a
|
<a
|
||||||
href={`/albums/${album.id}`}
|
href={`/albums/${album.id}`}
|
||||||
class="group block rounded focus-visible:ring-2 focus-visible:ring-accent"
|
class="block rounded focus-visible:ring-2 focus-visible:ring-accent"
|
||||||
>
|
>
|
||||||
<div class="art-wrap relative aspect-square w-full overflow-hidden rounded-md">
|
<div
|
||||||
|
class="art-wrap relative aspect-square w-full overflow-hidden rounded-md
|
||||||
|
shadow-sm transition-all duration-150
|
||||||
|
group-hover:shadow-lg group-hover:ring-1 group-hover:ring-accent/40"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src={album.cover_url}
|
src={album.cover_url}
|
||||||
alt=""
|
alt=""
|
||||||
@@ -54,9 +58,6 @@
|
|||||||
{#if album.artist_name}
|
{#if album.artist_name}
|
||||||
<div class="truncate text-xs text-text-secondary">{album.artist_name}</div>
|
<div class="truncate text-xs text-text-secondary">{album.artist_name}</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if album.year}
|
|
||||||
<div class="text-xs text-text-secondary">{album.year}</div>
|
|
||||||
{/if}
|
|
||||||
</a>
|
</a>
|
||||||
<CardActionCluster
|
<CardActionCluster
|
||||||
likeEntityType="album"
|
likeEntityType="album"
|
||||||
|
|||||||
@@ -42,10 +42,10 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="card relative">
|
<div class="card group relative">
|
||||||
<a
|
<a
|
||||||
href={`/artists/${artist.id}`}
|
href={`/artists/${artist.id}`}
|
||||||
class="group block rounded focus-visible:ring-2 focus-visible:ring-accent"
|
class="block rounded focus-visible:ring-2 focus-visible:ring-accent"
|
||||||
>
|
>
|
||||||
<div class="art-wrap relative mx-auto aspect-square w-full overflow-hidden rounded-full bg-surface-hover">
|
<div class="art-wrap relative mx-auto aspect-square w-full overflow-hidden rounded-full bg-surface-hover">
|
||||||
{#if artist.cover_url}
|
{#if artist.cover_url}
|
||||||
|
|||||||
@@ -34,9 +34,17 @@
|
|||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- Like + Add to queue + Menu cluster. Hover-revealed so the
|
||||||
|
default tile state is just the cover artwork — controls fade in
|
||||||
|
when the user hovers the card or focuses any of the buttons
|
||||||
|
(focus-within keeps it visible during keyboard navigation). -->
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div class="absolute right-2 top-2 z-10 flex gap-1" onclick={(e) => e.stopPropagation()}>
|
<div
|
||||||
|
class="absolute right-2 top-2 z-10 flex gap-1 opacity-0 transition-opacity duration-150
|
||||||
|
group-hover:opacity-100 focus-within:opacity-100"
|
||||||
|
onclick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
<LikeButton entityType={likeEntityType} entityId={likeEntityId} />
|
<LikeButton entityType={likeEntityType} entityId={likeEntityId} />
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -50,6 +58,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div class="absolute right-2 bottom-2 z-10" onclick={(e) => e.stopPropagation()}>
|
<div
|
||||||
|
class="absolute right-2 bottom-2 z-10 opacity-0 transition-opacity duration-150
|
||||||
|
group-hover:opacity-100 focus-within:opacity-100"
|
||||||
|
onclick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
{@render menu()}
|
{@render menu()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -62,7 +62,14 @@
|
|||||||
<div class="section" aria-label={ariaLabel}>
|
<div class="section" aria-label={ariaLabel}>
|
||||||
<header class="section-header">
|
<header class="section-header">
|
||||||
{#if title}
|
{#if title}
|
||||||
<h2 class="font-display text-2xl font-medium text-text-primary">{title}</h2>
|
<!-- Section header: Fraunces (font-display) at 24px with an
|
||||||
|
inline accent rule that bleeds out from the title — gives
|
||||||
|
each shelf a clear chapter break without adding chrome. -->
|
||||||
|
<h2
|
||||||
|
class="font-display text-2xl font-medium text-text-primary
|
||||||
|
flex items-baseline gap-3 after:h-[2px] after:w-12 after:flex-shrink-0
|
||||||
|
after:rounded-full after:bg-accent/60 after:content-['']"
|
||||||
|
>{title}</h2>
|
||||||
{:else}
|
{:else}
|
||||||
<span></span>
|
<span></span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -104,9 +104,14 @@
|
|||||||
|
|
||||||
<svelte:window onclick={() => { menuOpen = false; }} />
|
<svelte:window onclick={() => { menuOpen = false; }} />
|
||||||
|
|
||||||
<div class="card relative">
|
<div class="card group relative">
|
||||||
{#if refreshable}
|
{#if refreshable}
|
||||||
<div class="kebab-wrap absolute right-1 top-1 z-10">
|
<!-- Kebab is hover/focus-revealed so the default tile state is
|
||||||
|
just the cover. Same pattern as CardActionCluster. -->
|
||||||
|
<div
|
||||||
|
class="kebab-wrap absolute right-1 top-1 z-10 transition-opacity duration-150
|
||||||
|
{menuOpen ? 'opacity-100' : 'opacity-0 group-hover:opacity-100 focus-within:opacity-100'}"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
aria-label="Playlist actions"
|
aria-label="Playlist actions"
|
||||||
|
|||||||
Reference in New Issue
Block a user