Web player general changes #22

Merged
NotS1mp merged 27 commits from web-player-general-changes into master 2026-09-23 22:37:30 +00:00
17 changed files with 27 additions and 28 deletions
Showing only changes of commit cbbde95773 - Show all commits
+1 -1
View File
@@ -55,7 +55,7 @@ The design system lives in `src/routes/layout.css` (`@theme` tokens plus `@utili
- **Colors:** always use `--mf-*`/`text-*`/`bg-*`/`border-*` from `theme.css`/`tokens.ts`. Never a literal hex or `rgba()` inside a `.svelte` file; those literals only belong in `theme.css`/`tokens.ts` as the source of truth.
- **Inline `style="…"` and arbitrary `-[…]` values:** only the ones whitelisted in `scripts/check-tokens.mjs` (the stagger variable `--i`, tile hue, menu position, progress width, `text-[clamp(…)]`, `leading-[…]` on login's display type, `grid-cols-[auto_1fr]`, `max-h-[85dvh]`, `my-`/`py-[Ndvh]` for vertical centering, `transition-[filter]` on genre tiles, and `bg-[image:var(--mf-*)]`). Everything else should become a token.
- Reach for these base components before creating a new one: `Artwork`, `Avatar`, `ListRow`, `MediaIdentity`, `TrackList`, `MediaCard`, `PageHeader`, `ContextMenu`, `ConfirmDialog`, `PlayButton`, `Slider`, `Logo`, `Chip`, `SegmentedControl`, `CoverForm`.
- Known and accepted gap (documented in `scripts/check-tokens.mjs`): icon `strokeWidth={n}` isn't unified yet. There are 13 different values spread across almost every component, and migrating them to `stroke-thin/regular/bold` recipes safely would require visually confirming that `lucide-svelte` actually respects `stroke-width` through CSS, so that was left out of the last pass.
- **Icon stroke:** one global rule (`svg.lucide { stroke-width: 1.25 }` in `layout.css`) sets the stroke for every icon. Never pass `strokeWidth` to an icon, since any CSS rule overrides the SVG attribute and it would do nothing. For a different stroke on one icon, use a Tailwind `stroke-*` utility.
## Motion
@@ -44,7 +44,7 @@
</AccountMenu>
{:else}
<IconButton href="/auth/login" reload label="Iniciar sesión" shape="round" size="md">
<LogIn class="size-icon-lg" strokeWidth={2} />
<LogIn class="size-icon-lg" />
</IconButton>
{/if}
</header>
@@ -48,7 +48,7 @@
? 'bg-surface-2 text-fg'
: 'text-fg-2 hover:bg-hover hover:text-fg'}"
>
<link.icon class="size-icon-md shrink-0" strokeWidth={1.5} />
<link.icon class="size-icon-md shrink-0" />
<span class="flex-1 truncate">{link.label}</span>
{#if link.count}
<span class="text-xs text-fg-2 tabular-nums">{link.count}</span>
@@ -68,7 +68,7 @@
size="xs"
onclick={() => createPlaylistModal.show()}
>
<Plus class="size-icon-sm text-fg-2" strokeWidth={1.25} />
<Plus class="size-icon-sm text-fg-2" />
</IconButton>
{/if}
</div>
@@ -93,7 +93,7 @@
onclick={() => createPlaylistModal.show()}
class="flex items-center gap-2 rounded-control px-3 py-2 text-xs text-fg-2 transition-colors hover:bg-hover hover:text-fg-2"
>
<Plus class="size-3.5" strokeWidth={1.8} />
<Plus class="size-3.5" />
Crear tu primera lista
</button>
{/each}
@@ -30,7 +30,7 @@
? 'text-fg'
: 'text-fg-2'}"
>
<link.icon class="size-4" strokeWidth={1.6} />
<link.icon class="size-4" />
<span class="text-xs font-medium">{link.label}</span>
</a>
{/each}
@@ -62,14 +62,14 @@
size="xs"
onclick={() => history.back()}
>
<ChevronLeft class="size-icon-sm" strokeWidth={1.9} />
<ChevronLeft class="size-icon-sm" />
</IconButton>
<form onsubmit={onSubmit} class="max-w-search min-w-0 flex-1">
<label
class="flex h-9.5 w-full items-center gap-2.5 rounded-control bg-surface-2 px-3.5 transition focus-within:bg-surface-hover"
>
<Search class="size-4 shrink-0 text-fg-2" strokeWidth={1.8} />
<Search class="size-4 shrink-0 text-fg-2" />
<input
type="text"
bind:this={searchInput}
@@ -57,11 +57,11 @@
onclick={() => player.toggleMute()}
>
{#if player.muted || player.volume === 0}
<VolumeX class="size-icon-sm" strokeWidth={1.8} />
<VolumeX class="size-icon-sm" />
{:else if player.volume < 50}
<Volume1 class="size-icon-sm" strokeWidth={1.8} />
<Volume1 class="size-icon-sm" />
{:else}
<Volume2 class="size-icon-sm" strokeWidth={1.8} />
<Volume2 class="size-icon-sm" />
{/if}
</IconButton>
<Slider
@@ -78,7 +78,7 @@
pressed={queuePanel.open}
onclick={() => queuePanel.toggle()}
>
<ListMusic class="size-icon-sm" strokeWidth={1.8} />
<ListMusic class="size-icon-sm" />
</IconButton>
</div>
</div>
@@ -56,11 +56,11 @@
<IconButton
label={isLiked ? 'Quitar de Me gusta' : 'Añadir a Me gusta'}
tone="plain"
size="xs"
size="md"
pressed={isLiked}
onclick={toggleLike}
>
<Heart class="size-icon-md" fill={isLiked ? 'currentColor' : 'none'} strokeWidth={1.25} />
<Heart class="size-icon-md" fill={isLiked ? 'currentColor' : 'none'} />
</IconButton>
{/if}
</div>
@@ -26,7 +26,7 @@
aria-label="Aleatorio"
class="transition-colors hover:text-fg {player.shuffle ? 'text-accent' : 'text-fg-2'}"
>
<Shuffle class="size-4" strokeWidth={1.8} />
<Shuffle class="size-4" />
</button>
{/if}
@@ -58,7 +58,7 @@
aria-label="Repetir"
class="transition-colors hover:text-fg {player.repeat ? 'text-accent' : 'text-fg-2'}"
>
<Repeat class="size-4" strokeWidth={1.8} />
<Repeat class="size-4" />
</button>
{/if}
</div>
@@ -68,6 +68,6 @@
class="h-full w-full object-cover"
/>
{:else}
<Icon class="size-icon-xl {gradient ? 'text-on-art/70' : 'text-fg-2'}" strokeWidth={1.3} />
<Icon class="size-icon-xl {gradient ? 'text-on-art/70' : 'text-fg-2'}" />
{/if}
</label>
@@ -95,7 +95,7 @@
style="--mf-track-cols:{gridColumns}; --mf-track-cols-mobile:{gridColumnsMobile}"
>
{#if index}
<Hash size={16} strokeWidth={1.5} />
<Hash size={16} />
{/if}
<span>Título</span>
{#each columns as column (column)}
@@ -24,7 +24,7 @@
>
{#if tone === 'danger'}
<span class="mb-4 grid size-10 place-items-center rounded-full bg-danger/12 text-danger-fg">
<CircleAlert class="size-icon-md" strokeWidth={2} />
<CircleAlert class="size-icon-md" />
</span>
{/if}
<h2 class="text-display-3 text-fg">{title}</h2>
@@ -22,7 +22,6 @@
/>
<Check
class="pointer-events-none absolute size-3.5 text-ink opacity-0 transition peer-checked:opacity-100"
strokeWidth={3}
/>
</span>
<span class="cursor-pointer">{@render children()}</span>
@@ -15,7 +15,7 @@
<div class="flex flex-col items-center rounded-panel px-6 py-16 text-center {klass}">
{#if Icon}
<Icon class="size-icon-xl text-fg-2" strokeWidth={1.25} />
<Icon class="size-icon-xl text-fg-2" />
{/if}
{#if title}
<h3 class="mt-6 text-display-3 text-fg">
@@ -27,7 +27,7 @@
{#snippet actions()}
{#if items.length > 0}
<Button onclick={() => (creating = true)}>
<Plus class="size-4" strokeWidth={2.5} />
<Plus class="size-4" />
Nuevo álbum
</Button>
{/if}
@@ -39,7 +39,7 @@
<div
class="grid size-cover-hero shrink-0 place-items-center rounded-art-lg bg-[image:var(--mf-liked-grad)] sm:size-cover-hero-sm"
>
<Heart class="size-icon-xl text-on-art/90" fill="currentColor" strokeWidth={0} />
<Heart class="size-icon-xl text-on-art/90" fill="currentColor" />
</div>
{/snippet}
{#snippet actions()}
@@ -130,7 +130,7 @@
: 'bg-accent-btn text-accent-soft'}"
>
{#if stepStates[i] === 'done'}
<Check class="size-3.5" strokeWidth={2.5} />
<Check class="size-3.5" />
{:else}
{i + 1}
{/if}
@@ -146,7 +146,7 @@
{#if status === 'done'}
<Surface padding="lg" class="mt-10 bg-accent-tint text-center">
<span class="mx-auto grid size-14 place-items-center rounded-full bg-accent-soft text-ink">
<Check class="size-7" strokeWidth={2.5} />
<Check class="size-7" />
</span>
<h2 class="mt-6 font-display text-2xl font-semibold tracking-display text-fg">¡Subida!</h2>
<p class="mt-3 text-sm text-fg-2">
@@ -207,9 +207,9 @@
aria-label="Seleccionar archivo de audio"
/>
{#if audioName === ''}
<Headphones class="size-9 text-fg-2 sm:size-10" strokeWidth={1.4} />
<Headphones class="size-9 text-fg-2 sm:size-10" />
{:else}
<Music class="size-9 text-accent-soft sm:size-10" strokeWidth={1.4} />
<Music class="size-9 text-accent-soft sm:size-10" />
{/if}
{#if audioName === ''}
<p class="mt-4 text-sm font-medium text-fg">
+1 -1
View File
@@ -261,7 +261,7 @@
@layer base {
svg.lucide {
stroke-width: 1.8;
stroke-width: 1.5;
}
}