chore(deps): Tailwind 4 (#5021)
release / govulncheck (push) Successful in 42s
release / web (push) Successful in 1m39s
release / go (push) Successful in 1m53s
release / integration (push) Successful in 5m37s
release / android (push) Successful in 6m54s
release / Build signed APK (releases and dev) (push) Successful in 7m27s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Failing after 34s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 42s
release / web (push) Successful in 1m39s
release / go (push) Successful in 1m53s
release / integration (push) Successful in 5m37s
release / android (push) Successful in 6m54s
release / Build signed APK (releases and dev) (push) Successful in 7m27s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Failing after 34s
release / Verify release artifacts (tag releases only) (push) Skipped
Renovate's tailwindcss bump (PR #150) plus the migration it needs: - Theme moves from tailwind.config.js into app.css as `@theme inline`, mapping the same FabledSword tokens. tailwind.config.js is gone. - PostCSS runs @tailwindcss/postcss; autoprefixer is dropped, since Tailwind 4 prefixes through Lightning CSS. - Class renames from @tailwindcss/upgrade 4.3.3, reviewed: outline-none -> outline-hidden, focus-visible:outline -> outline-solid, shadow -> shadow-sm, shadow-sm -> shadow-xs, flex-shrink-0 -> shrink-0. Bare `rounded` stays: v4 keeps it at 0.25rem, as before. - Three v3 preflight defaults kept in a base layer so nothing changes on screen: gray-200 default border colour, gray-400 placeholder text and the pointer cursor on buttons. - The unused class-based dark variant is not carried over; no template uses `dark:`. Clears the five high and two moderate npm audit findings that came in through Tailwind 3 (braces, chokidar, micromatch, fast-glob, postcss-selector-parser). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -285,7 +285,7 @@
|
||||
class="flex items-start gap-2 border-b border-border bg-surface-hover px-4 py-3 text-xs text-text-secondary"
|
||||
data-testid="title-mismatch"
|
||||
>
|
||||
<TriangleAlert size={14} class="mt-0.5 flex-shrink-0 text-warning-fg" aria-hidden="true" />
|
||||
<TriangleAlert size={14} class="mt-0.5 shrink-0 text-warning-fg" aria-hidden="true" />
|
||||
<span>
|
||||
The audio is identical, but the copies are titled {quotedList(titles)}. If those
|
||||
name different recordings, one file is mislabelled and the other recording isn't in
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
type="text"
|
||||
bind:value={baseUrl}
|
||||
placeholder="http://lidarr.lan:8686"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</label>
|
||||
|
||||
@@ -448,7 +448,7 @@
|
||||
placeholder={config.data?.api_key === '***'
|
||||
? '••• (saved — leave empty to keep)'
|
||||
: 'Paste API key'}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</label>
|
||||
|
||||
@@ -457,7 +457,7 @@
|
||||
<select
|
||||
bind:value={qualityId}
|
||||
disabled={!profilesEnabled && testQualityProfiles.length === 0}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-accent disabled:opacity-50"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary focus:outline-hidden focus:ring-2 focus:ring-accent disabled:opacity-50"
|
||||
>
|
||||
{#each (testQualityProfiles.length ? testQualityProfiles : (profiles.data ?? [])) as p (p.id)}
|
||||
<option value={p.id}>{p.name}</option>
|
||||
@@ -475,7 +475,7 @@
|
||||
<select
|
||||
bind:value={metadataId}
|
||||
disabled={!profilesEnabled && testMetadataProfiles.length === 0}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-accent disabled:opacity-50"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary focus:outline-hidden focus:ring-2 focus:ring-accent disabled:opacity-50"
|
||||
>
|
||||
{#each (testMetadataProfiles.length ? testMetadataProfiles : (metadataProfiles.data ?? [])) as p (p.id)}
|
||||
<option value={p.id}>{p.name}</option>
|
||||
@@ -493,7 +493,7 @@
|
||||
<select
|
||||
bind:value={rootPath}
|
||||
disabled={!profilesEnabled && testRootFolders.length === 0}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-accent disabled:opacity-50"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary focus:outline-hidden focus:ring-2 focus:ring-accent disabled:opacity-50"
|
||||
>
|
||||
{#each (testRootFolders.length ? testRootFolders : (folders.data ?? [])) as f (f.path)}
|
||||
<option value={f.path}
|
||||
@@ -597,7 +597,7 @@
|
||||
<input id="key-{provider.id}" type="password"
|
||||
placeholder={provider.api_key_set ? '••• (saved — leave empty to keep)' : 'Leave blank to use the public test key'}
|
||||
bind:value={coverLocalState[provider.id].apiKey}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent flex-1" />
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent flex-1" />
|
||||
{#if provider.api_key_set}
|
||||
<span class="text-xs text-text-secondary whitespace-nowrap">✓ Set</span>
|
||||
{/if}
|
||||
@@ -694,7 +694,7 @@
|
||||
<input id="tag-key-{provider.id}" type="password"
|
||||
placeholder={provider.api_key_set ? '••• (saved — leave empty to keep)' : 'Paste your API key to enable this source'}
|
||||
bind:value={tagLocalState[provider.id].apiKey}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent flex-1" />
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent flex-1" />
|
||||
{#if provider.api_key_set}
|
||||
<span class="text-xs text-text-secondary whitespace-nowrap">✓ Set</span>
|
||||
{/if}
|
||||
@@ -768,30 +768,30 @@
|
||||
<div class="grid gap-3 sm:grid-cols-[auto_1fr] items-center">
|
||||
<label for="smtp-host" class="text-sm text-text-secondary">Host</label>
|
||||
<input id="smtp-host" type="text" bind:value={smtpForm.host}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent" />
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent" />
|
||||
|
||||
<label for="smtp-port" class="text-sm text-text-secondary">Port</label>
|
||||
<input id="smtp-port" type="number" min="1" max="65535"
|
||||
bind:value={smtpForm.port}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent" />
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent" />
|
||||
|
||||
<label for="smtp-username" class="text-sm text-text-secondary">Username</label>
|
||||
<input id="smtp-username" type="text" bind:value={smtpForm.username}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent" />
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent" />
|
||||
|
||||
<label for="smtp-password" class="text-sm text-text-secondary">Password</label>
|
||||
<input id="smtp-password" type="password"
|
||||
placeholder={smtpForm.password === '***' ? 'Leave blank to keep current' : ''}
|
||||
bind:value={smtpPasswordInput}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent" />
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent" />
|
||||
|
||||
<label for="smtp-from" class="text-sm text-text-secondary">From address</label>
|
||||
<input id="smtp-from" type="email" bind:value={smtpForm.from_address}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent" />
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent" />
|
||||
|
||||
<label for="smtp-from-name" class="text-sm text-text-secondary">From name</label>
|
||||
<input id="smtp-from-name" type="text" bind:value={smtpForm.from_name}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent" />
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent" />
|
||||
|
||||
<span class="text-sm text-text-secondary">TLS</span>
|
||||
<label class="flex items-center gap-2 text-sm">
|
||||
@@ -837,7 +837,7 @@
|
||||
bind:value={disconnectInput}
|
||||
placeholder="DISCONNECT"
|
||||
aria-label="Type DISCONNECT to confirm"
|
||||
class="mt-3 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-3 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
{#if disconnectError}
|
||||
<p class="mt-2 text-sm text-error-fg">Disconnect failed — {disconnectError}</p>
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
<button
|
||||
type="button"
|
||||
class="rounded border border-border px-3 py-1.5 text-sm text-text-primary
|
||||
hover:bg-surface-hover focus-visible:outline focus-visible:outline-2
|
||||
hover:bg-surface-hover focus-visible:outline-solid focus-visible:outline-2
|
||||
focus-visible:outline-accent disabled:cursor-not-allowed disabled:opacity-40"
|
||||
disabled={offset === 0}
|
||||
onclick={() => (offset = Math.max(0, offset - PAGE_SIZE))}
|
||||
@@ -187,7 +187,7 @@
|
||||
<button
|
||||
type="button"
|
||||
class="rounded border border-border px-3 py-1.5 text-sm text-text-primary
|
||||
hover:bg-surface-hover focus-visible:outline focus-visible:outline-2
|
||||
hover:bg-surface-hover focus-visible:outline-solid focus-visible:outline-2
|
||||
focus-visible:outline-accent disabled:cursor-not-allowed disabled:opacity-40"
|
||||
disabled={!hasMore}
|
||||
onclick={() => (offset += PAGE_SIZE)}
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
type="text"
|
||||
bind:value={deleteLidarrInput}
|
||||
placeholder="DELETE"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
aria-label="Type DELETE to confirm"
|
||||
/>
|
||||
</label>
|
||||
|
||||
@@ -291,7 +291,7 @@
|
||||
<span class="block text-sm text-text-secondary">Quality profile</span>
|
||||
<select
|
||||
bind:value={qualityOverride}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
>
|
||||
<option value="">Use default</option>
|
||||
{#each profiles.data ?? [] as p (p.id)}
|
||||
@@ -304,7 +304,7 @@
|
||||
<span class="block text-sm text-text-secondary">Root folder</span>
|
||||
<select
|
||||
bind:value={rootOverride}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 font-mono text-sm text-text-primary focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
>
|
||||
<option value="">Use default</option>
|
||||
{#each folders.data ?? [] as f (f.path)}
|
||||
@@ -346,7 +346,7 @@
|
||||
bind:value={rejectNotes}
|
||||
rows="3"
|
||||
placeholder="Optional — why this is being set aside"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
></textarea>
|
||||
</label>
|
||||
<div class="mt-5 flex justify-end gap-2">
|
||||
|
||||
@@ -293,7 +293,7 @@
|
||||
type="number"
|
||||
step="0.1"
|
||||
bind:value={form[p.scope][f.key]}
|
||||
class="w-full rounded border border-border bg-background px-2 py-1 text-right text-sm tabular-nums outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-2 py-1 text-right text-sm tabular-nums outline-hidden focus:border-accent"
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
@@ -346,7 +346,7 @@
|
||||
type="number"
|
||||
step={f.key === 'half_life_days' ? '1' : '0.05'}
|
||||
bind:value={form.taste[f.key]}
|
||||
class="w-full rounded border border-border bg-background px-2 py-1 text-right text-sm tabular-nums outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-2 py-1 text-right text-sm tabular-nums outline-hidden focus:border-accent"
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
@@ -402,7 +402,7 @@
|
||||
step={f.key === 'snooze_days' ? '1' : '0.1'}
|
||||
min="0"
|
||||
bind:value={form.discover[f.key]}
|
||||
class="w-full rounded border border-border bg-background px-2 py-1 text-right text-sm tabular-nums outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-2 py-1 text-right text-sm tabular-nums outline-hidden focus:border-accent"
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
@@ -369,7 +369,7 @@
|
||||
minlength="3"
|
||||
maxlength="32"
|
||||
bind:value={createForm.username}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -381,7 +381,7 @@
|
||||
type="text"
|
||||
maxlength="64"
|
||||
bind:value={createForm.display_name}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -392,7 +392,7 @@
|
||||
required
|
||||
minlength="8"
|
||||
bind:value={createForm.password}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -403,7 +403,7 @@
|
||||
required
|
||||
minlength="8"
|
||||
bind:value={createForm.confirmPassword}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</div>
|
||||
<label class="flex items-center gap-2 text-sm text-text-secondary">
|
||||
@@ -447,7 +447,7 @@
|
||||
required
|
||||
minlength="8"
|
||||
bind:value={resetPasswordValue}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -458,7 +458,7 @@
|
||||
required
|
||||
minlength="8"
|
||||
bind:value={resetPasswordConfirm}
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="mt-1 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-end gap-2 pt-2">
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
aria-label={`Play ${detail.name}`}
|
||||
onclick={onPlay}
|
||||
disabled={isStartingPlay || detail.album_count === 0}
|
||||
class="flex h-12 w-12 items-center justify-center rounded-full bg-accent text-text-primary shadow transition-transform hover:scale-105 focus-visible:ring-2 focus-visible:ring-accent disabled:opacity-50 disabled:hover:scale-100"
|
||||
class="flex h-12 w-12 items-center justify-center rounded-full bg-accent text-text-primary shadow-sm transition-transform hover:scale-105 focus-visible:ring-2 focus-visible:ring-accent disabled:opacity-50 disabled:hover:scale-100"
|
||||
>
|
||||
<Play size={24} strokeWidth={1.5} fill="currentColor" class="ml-0.5" />
|
||||
</button>
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
aria-label="Search Lidarr"
|
||||
placeholder="Search artists, albums, or tracks"
|
||||
bind:value={inputValue}
|
||||
class="w-full rounded-md border border-border bg-background px-3 py-2 text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
class="w-full rounded-md border border-border bg-background px-3 py-2 text-text-primary placeholder:text-text-muted focus:outline-hidden focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
|
||||
{#if debouncedQ === ''}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<svelte:head><title>{pageTitle('Forgot password')}</title></svelte:head>
|
||||
|
||||
<main class="flex min-h-screen items-center justify-center bg-background text-text-primary">
|
||||
<div class="w-full max-w-sm rounded-lg border border-border bg-surface p-6 shadow">
|
||||
<div class="w-full max-w-sm rounded-lg border border-border bg-surface p-6 shadow-sm">
|
||||
<h1 class="mb-6 text-center text-2xl font-semibold">Forgot password</h1>
|
||||
|
||||
{#if !submitted}
|
||||
@@ -48,7 +48,7 @@
|
||||
required
|
||||
autocomplete="email"
|
||||
bind:value={email}
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
/>
|
||||
</label>
|
||||
<button
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
bind:value={sortMode}
|
||||
aria-label="Sort genres"
|
||||
class="rounded border border-border bg-surface px-2 py-1 text-sm text-text-primary
|
||||
focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent"
|
||||
focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-accent"
|
||||
>
|
||||
<option value="count">Most tracks</option>
|
||||
<option value="name">A–Z</option>
|
||||
@@ -242,7 +242,7 @@
|
||||
focus-visible:ring-2 focus-visible:ring-accent"
|
||||
>
|
||||
<span class="truncate text-text-primary">{g.genre}</span>
|
||||
<span class="flex-shrink-0 text-sm text-text-secondary">
|
||||
<span class="shrink-0 text-sm text-text-secondary">
|
||||
{g.track_count}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<svelte:head><title>{pageTitle('Sign in')}</title></svelte:head>
|
||||
|
||||
<main class="flex min-h-screen items-center justify-center bg-background text-text-primary">
|
||||
<div class="w-full max-w-sm rounded-lg border border-border bg-surface p-6 shadow">
|
||||
<div class="w-full max-w-sm rounded-lg border border-border bg-surface p-6 shadow-sm">
|
||||
<h1 class="mb-6 text-center text-2xl font-semibold">Minstrel</h1>
|
||||
<form class="space-y-4" onsubmit={handleSubmit}>
|
||||
<label class="block">
|
||||
@@ -56,7 +56,7 @@
|
||||
<input
|
||||
type="text"
|
||||
autocomplete="username"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
bind:value={username}
|
||||
required
|
||||
/>
|
||||
@@ -66,7 +66,7 @@
|
||||
<input
|
||||
type="password"
|
||||
autocomplete="current-password"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
bind:value={password}
|
||||
required
|
||||
/>
|
||||
|
||||
@@ -262,7 +262,7 @@
|
||||
</section>
|
||||
<aside
|
||||
aria-label="Queue"
|
||||
class="hidden lg:flex w-96 xl:w-[28rem] flex-col border-l border-border bg-surface"
|
||||
class="hidden lg:flex w-96 xl:w-md flex-col border-l border-border bg-surface"
|
||||
>
|
||||
<QueueList />
|
||||
</aside>
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
type="button"
|
||||
onclick={onReloadStale}
|
||||
disabled={reloadingStale}
|
||||
class="flex-shrink-0 rounded-md bg-action-secondary px-3 py-1 text-xs font-medium
|
||||
class="shrink-0 rounded-md bg-action-secondary px-3 py-1 text-xs font-medium
|
||||
text-action-fg disabled:opacity-50"
|
||||
>
|
||||
{reloadingStale ? 'Refreshing…' : 'Refresh'}
|
||||
@@ -244,7 +244,7 @@
|
||||
{/if}
|
||||
{#if !editing}
|
||||
<header class="mb-6 flex items-start gap-4">
|
||||
<div class="h-32 w-32 flex-shrink-0 overflow-hidden rounded-md bg-surface-hover">
|
||||
<div class="h-32 w-32 shrink-0 overflow-hidden rounded-md bg-surface-hover">
|
||||
{#if pl.cover_url}
|
||||
<img src={pl.cover_url} alt="" class="h-full w-full object-cover" />
|
||||
{/if}
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<svelte:head><title>{pageTitle('Register')}</title></svelte:head>
|
||||
|
||||
<main class="flex min-h-screen items-center justify-center bg-background text-text-primary">
|
||||
<div class="w-full max-w-sm rounded-lg border border-border bg-surface p-6 shadow">
|
||||
<div class="w-full max-w-sm rounded-lg border border-border bg-surface p-6 shadow-sm">
|
||||
<h1 class="mb-6 text-center text-2xl font-semibold">Create account</h1>
|
||||
<form class="space-y-4" onsubmit={handleSubmit}>
|
||||
<label class="block">
|
||||
@@ -86,7 +86,7 @@
|
||||
required
|
||||
minlength="3"
|
||||
maxlength="32"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
bind:value={username}
|
||||
/>
|
||||
</label>
|
||||
@@ -98,7 +98,7 @@
|
||||
type="text"
|
||||
autocomplete="name"
|
||||
maxlength="64"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
bind:value={displayName}
|
||||
/>
|
||||
</label>
|
||||
@@ -109,7 +109,7 @@
|
||||
autocomplete="new-password"
|
||||
required
|
||||
minlength="8"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
bind:value={password}
|
||||
/>
|
||||
</label>
|
||||
@@ -120,7 +120,7 @@
|
||||
autocomplete="new-password"
|
||||
required
|
||||
minlength="8"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
bind:value={confirmPassword}
|
||||
/>
|
||||
</label>
|
||||
@@ -132,7 +132,7 @@
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
required
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 font-mono outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 font-mono outline-hidden focus:border-accent"
|
||||
bind:value={setupToken}
|
||||
/>
|
||||
<span class="mt-1 block text-xs text-text-secondary">
|
||||
@@ -148,7 +148,7 @@
|
||||
<input
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
bind:value={inviteToken}
|
||||
/>
|
||||
</label>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<svelte:head><title>{pageTitle('Reset password')}</title></svelte:head>
|
||||
|
||||
<main class="flex min-h-screen items-center justify-center bg-background text-text-primary">
|
||||
<div class="w-full max-w-sm rounded-lg border border-border bg-surface p-6 shadow">
|
||||
<div class="w-full max-w-sm rounded-lg border border-border bg-surface p-6 shadow-sm">
|
||||
<h1 class="mb-6 text-center text-2xl font-semibold">Set a new password</h1>
|
||||
<form class="space-y-4" onsubmit={onSubmit}>
|
||||
<label class="block">
|
||||
@@ -61,7 +61,7 @@
|
||||
minlength="8"
|
||||
autocomplete="new-password"
|
||||
bind:value={newPassword}
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
/>
|
||||
</label>
|
||||
<label class="block">
|
||||
@@ -73,7 +73,7 @@
|
||||
minlength="8"
|
||||
autocomplete="new-password"
|
||||
bind:value={confirmPassword}
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent"
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent"
|
||||
/>
|
||||
</label>
|
||||
{#if error}
|
||||
|
||||
@@ -467,7 +467,7 @@
|
||||
{#if (m.breakdown ?? []).length > 0}
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center gap-1 rounded outline-none focus-visible:ring-1 focus-visible:ring-accent"
|
||||
class="inline-flex items-center gap-1 rounded outline-hidden focus-visible:ring-1 focus-visible:ring-accent"
|
||||
aria-expanded={expandedBreakdowns.has(m.key)}
|
||||
onclick={() => toggleBreakdown(m.key)}
|
||||
>
|
||||
@@ -564,12 +564,12 @@
|
||||
<label class="text-sm text-text-secondary" for="profile-displayname">Display name</label>
|
||||
<input id="profile-displayname" type="text" maxlength="64"
|
||||
bind:value={profileForm.displayName}
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent" />
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent" />
|
||||
|
||||
<label class="text-sm text-text-secondary" for="profile-email">Email</label>
|
||||
<input id="profile-email" type="email" autocomplete="email"
|
||||
bind:value={profileForm.email}
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent" />
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent" />
|
||||
</div>
|
||||
<button type="button" disabled={profileSaving}
|
||||
onclick={onSaveProfile}
|
||||
@@ -587,18 +587,18 @@
|
||||
<input id="password-current" type="password" required minlength="8"
|
||||
autocomplete="current-password"
|
||||
bind:value={passwordForm.current}
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent" />
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent" />
|
||||
|
||||
<label class="text-sm text-text-secondary" for="password-new">New password</label>
|
||||
<input id="password-new" type="password" required minlength="8"
|
||||
autocomplete="new-password"
|
||||
bind:value={passwordForm.new}
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent" />
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent" />
|
||||
|
||||
<label class="text-sm text-text-secondary" for="password-confirm">Confirm</label>
|
||||
<input id="password-confirm" type="password" required minlength="8"
|
||||
bind:value={passwordForm.confirm}
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-none focus:border-accent" />
|
||||
class="w-full rounded border border-border bg-background px-3 py-2 outline-hidden focus:border-accent" />
|
||||
</div>
|
||||
<button type="submit" disabled={passwordSaving}
|
||||
class="rounded bg-accent px-3 py-2 text-sm font-medium text-background disabled:opacity-60">
|
||||
|
||||
Reference in New Issue
Block a user