Checkpoint web-player design-system refactor and backend track genre tagging

Advances the ongoing token/componentization cleanup (anchored player dock,
border-based panels instead of floating shadows, corrected light-mode
accent/gradient tokens) alongside in-progress backend support for track
genre tags.
This commit is contained in:
2026-09-17 17:43:37 +02:00
parent 5ae9955bd0
commit c14db5a711
83 changed files with 1872 additions and 248 deletions
@@ -55,7 +55,7 @@
{trackIds}
{coverUrl}
size="large"
class="h-36 w-36 shrink-0 rounded-[18px] shadow-cover-lg sm:h-41 sm:w-41"
class="h-36 w-36 shrink-0 rounded-art-lg sm:h-41 sm:w-41"
/>
{/snippet}
{#snippet actions()}
@@ -10,7 +10,7 @@
import TrackIndexCell from '$lib/components/ui/TrackIndexCell.svelte';
import TrackTitleCell from '$lib/components/ui/TrackTitleCell.svelte';
type AlbumTrack = ApiTrackLike & { duration: number | string };
type AlbumTrack = ApiTrackLike & { duration: number | string; listensCount: number | string };
interface Props {
tracks: AlbumTrack[];
@@ -24,7 +24,12 @@
}
</script>
<TrackTable index action={isOwner} class="mt-6 sm:mt-8">
<TrackTable
index
action={isOwner}
meta={[{ label: 'Escuchas', width: '100px' }]}
class="mt-6 sm:mt-8"
>
{#each tracks as track, i (track.id)}
{@const active = player.current.id === track.id}
<TrackRow {active}>
@@ -38,6 +43,7 @@
{active}
onClick={() => playFrom(i)}
/>
<TrackMeta class="hidden sm:block">{Number(track.listensCount)}</TrackMeta>
<TrackMeta>{fmtTime(Number(track.duration))}</TrackMeta>
{#if isOwner}
<form
@@ -11,7 +11,7 @@
import TrackTitleCell from '$lib/components/ui/TrackTitleCell.svelte';
import NowPlaying from '$lib/components/ui/NowPlaying.svelte';
type LibraryTrack = ApiTrackLike & { duration: number | string };
type LibraryTrack = ApiTrackLike & { duration: number | string; listensCount: number | string };
interface Props {
library: LibraryTrack[];
@@ -26,7 +26,7 @@
<div class="mt-10 sm:mt-12">
<SectionHeading title="Tus canciones subidas" />
<TrackTable action>
<TrackTable action meta={[{ label: 'Escuchas', width: '100px' }]}>
{#each library as track, i (track.id)}
{@const active = player.current.id === track.id}
<TrackRow {active}>
@@ -45,6 +45,7 @@
{/if}
{/snippet}
</TrackTitleCell>
<TrackMeta class="hidden sm:block">{Number(track.listensCount)}</TrackMeta>
<TrackMeta>{fmtTime(Number(track.duration))}</TrackMeta>
<form
method="POST"
@@ -3,7 +3,7 @@
import Play from '@lucide/svelte/icons/play';
import { player } from '$lib/player/player.svelte';
import { fetchAlbumQueueItems } from '$lib/albums';
import { fmtTime } from '$lib/format';
import { fmtTime, fmtPlays } from '$lib/format';
import Page from '$lib/components/ui/Page.svelte';
import PageHeader from '$lib/components/ui/PageHeader.svelte';
import Alert from '$lib/components/ui/Alert.svelte';
@@ -30,6 +30,7 @@
targetArtist,
targetExplicit,
targetId,
targetListensCount,
targetTitle,
type TrackTarget
} from '$lib/tracks';
@@ -299,23 +300,23 @@
trackId={targetId(topResult.target)}
size="large"
alt={targetTitle(topResult.target)}
class="h-22 w-22 shrink-0 rounded-2xl shadow-art"
class="h-22 w-22 shrink-0 rounded-2xl"
/>
{:else if topResult.kind === 'album'}
<PlaylistArt
trackIds={topResult.album.coverTrackIds}
class="h-22 w-22 shrink-0 rounded-2xl shadow-art"
class="h-22 w-22 shrink-0 rounded-2xl"
/>
{:else if topResult.kind === 'playlist'}
<PlaylistArt
playlistId={topResult.playlist.id}
trackIds={topResult.playlist.coverTrackIds}
version={topResult.playlist.updatedAt}
class="h-22 w-22 shrink-0 rounded-2xl shadow-art"
class="h-22 w-22 shrink-0 rounded-2xl"
/>
{:else}
<div
class="grid h-22 w-22 shrink-0 place-items-center overflow-hidden rounded-full bg-surface-2 shadow-art"
class="grid h-22 w-22 shrink-0 place-items-center overflow-hidden rounded-full bg-surface-2"
>
{#if topResult.user.profilePictureUrl}
<img
@@ -385,7 +386,7 @@
{#if nothingFound}
<div class="mx-auto max-w-115 py-[8vh] text-center">
<h1 class="font-display text-xl font-semibold tracking-[-0.025em] text-fg">
<h1 class="font-display text-xl font-semibold tracking-tight text-fg">
Sin resultados para «{data.query}»
</h1>
<p class="mt-2.5 text-sm leading-[1.65] text-fg-2">
@@ -411,14 +412,14 @@
{#each genreTiles as genre, i (genre.query)}
<a
href={buildHref(genre.query)}
class="animate-enter group relative block h-28 overflow-hidden rounded-2xl p-4.25 transition-[filter] hover:brightness-125"
class="animate-enter group relative flex h-28 flex-col gap-1 overflow-hidden rounded-2xl p-4.25 transition-[filter] hover:brightness-125"
style="animation-delay:{Math.min(i, 10) *
40}ms; background:linear-gradient(140deg, oklch(0.24 0.07 {genre.hue}), var(--mf-tile-shade))"
40}ms; background:linear-gradient(140deg, oklch(var(--mf-tile-l) var(--mf-tile-c) {genre.hue}), oklch(var(--mf-tile-shade-l) var(--mf-tile-shade-c) {genre.hue}))"
>
<div class="font-display text-base font-semibold tracking-[-0.02em] text-fg">
<div class="font-display text-base font-medium tracking-tight text-on-art">
{genre.label}
</div>
<div class="mt-1.5 text-xs text-fg-3">{genre.tagline}</div>
<div class="text-xs text-on-art-2">{genre.tagline}</div>
</a>
{/each}
</div>
@@ -445,7 +446,7 @@
kind="track"
title={targetTitle(item)}
subtitle={targetArtist(item)}
meta={fmtTime(seconds)}
meta="{fmtTime(seconds)} · {fmtPlays(targetListensCount(item))}"
explicit={targetExplicit(item)}
onclick={() => togglePlay(i)}
oncontextmenu={(e) => openContextMenu(e, item)}
@@ -51,9 +51,9 @@
index
action
meta={[
{ label: 'Álbum', width: '160px' },
{ label: 'Subida', width: '100px' },
{ label: 'Escuchas', width: '100px' }
{ label: 'Álbum', width: '76px' },
{ label: 'Subida', width: '124px' },
{ label: 'Escuchas', width: '106px' }
]}
class="mt-7 sm:mt-8"
>
@@ -53,7 +53,7 @@
>
{#snippet cover()}
<div
class="grid h-36 w-36 shrink-0 place-items-center rounded-[18px] bg-[image:var(--mf-liked-grad)] shadow-cover-lg sm:h-41 sm:w-41"
class="grid h-36 w-36 shrink-0 place-items-center rounded-art-lg bg-[image:var(--mf-liked-grad)] sm:h-41 sm:w-41"
>
<Heart class="h-10 w-10 text-on-art/90" fill="currentColor" strokeWidth={0} />
</div>
@@ -76,8 +76,9 @@
index
action
meta={[
{ label: 'Álbum', width: '160px' },
{ label: 'Añadida', width: '140px' }
{ label: 'Álbum', width: '76px' },
{ label: 'Añadida', width: '124px' },
{ label: 'Escuchas', width: '106px' }
]}
class="mt-6 sm:mt-8"
>
@@ -101,6 +102,7 @@
/>
<TrackMeta class="hidden sm:block">—</TrackMeta>
<TrackMeta class="hidden sm:block">{fmtDate(track.likedAt)}</TrackMeta>
<TrackMeta class="hidden sm:block">{Number(track.listensCount ?? 0)}</TrackMeta>
<TrackMeta>—</TrackMeta>
<IconButton
label="Quitar de Me gusta"
@@ -26,6 +26,7 @@
queueItemForTarget,
targetArtist,
targetId,
targetListensCount,
targetTitle
} from '$lib/tracks';
@@ -74,7 +75,7 @@
meta="{items.length} {items.length === 1 ? 'canción' : 'canciones'} · {fmtTime(totalSeconds)}"
>
{#snippet cover()}
<MixArt {items} class="h-36 w-36 shrink-0 rounded-[18px] shadow-cover-lg sm:h-41 sm:w-41" />
<MixArt {items} class="h-36 w-36 shrink-0 rounded-art-lg sm:h-41 sm:w-41" />
{/snippet}
{#snippet actions()}
<Button size="sm" onclick={playAll} disabled={queue.length === 0}>
@@ -97,7 +98,7 @@
<Alert tone="danger" class="mt-4">{form.message}</Alert>
{/if}
<TrackTable index class="mt-6 sm:mt-8">
<TrackTable index meta={[{ label: 'Escuchas', width: '100px' }]} class="mt-6 sm:mt-8">
{#each items as item, i (mixItemKey(item))}
{@const active = isTargetCurrent(targets[i])}
<TrackRow {active} oncontextmenu={(e) => (contextMenu = contextMenuStateFor(e, targets[i]))}>
@@ -109,6 +110,7 @@
{active}
onClick={() => playFrom(i)}
/>
<TrackMeta class="hidden sm:block">{Number(targetListensCount(targets[i]) ?? 0)}</TrackMeta>
<TrackMeta>{fmtTime(Number(item.durationSeconds))}</TrackMeta>
</TrackRow>
{/each}
@@ -14,7 +14,7 @@
const items = $derived(data.playlists.items);
const totals = $derived(data.totals);
const summary = $derived(
`${totals.playlistCount} ${totals.playlistCount === 1 ? 'playlist' : 'playlists'} · ${totals.trackCount} ${totals.trackCount === 1 ? 'canción' : 'canciones'} · ${fmtDurationLong(totals.durationSeconds)}`
`${totals.playlistCount} ${totals.playlistCount === 1 ? 'Playlist' : 'Playlists'} · ${totals.trackCount} ${totals.trackCount === 1 ? 'Canción' : 'Canciones'} · ${fmtDurationLong(totals.durationSeconds)}`
);
</script>
@@ -30,7 +30,7 @@
}: Props = $props();
const meta = $derived(
`${trackIds.length} ${trackIds.length === 1 ? 'canción' : 'canciones'} · ${
`${trackIds.length} ${trackIds.length === 1 ? 'Canción' : 'Canciones'} · ${
visibility === 'Public' ? 'Pública' : 'Privada'
}`
);
@@ -49,16 +49,12 @@
{trackIds}
size="large"
version={updatedAt}
class="h-36 w-36 shrink-0 rounded-[18px] shadow-cover-lg sm:h-41 sm:w-41"
class="h-36 w-36 shrink-0 rounded-art-lg sm:h-41 sm:w-41"
/>
{/snippet}
{#snippet actions()}
<Button size="sm" onclick={onPlayAll} disabled={trackIds.length === 0}>
{#if playing}
Pausar
{:else}
Reproducir
{/if}
{playing ? 'Pausar' : 'Reproducir'}
</Button>
<Button size="sm" variant="secondary" onclick={onEdit}>Editar</Button>
<Button size="sm" variant="secondary" onclick={onDelete}>Eliminar</Button>
@@ -10,7 +10,11 @@
import TrackIndexCell from '$lib/components/ui/TrackIndexCell.svelte';
import TrackTitleCell from '$lib/components/ui/TrackTitleCell.svelte';
type PlaylistTrack = ApiTrackLike & { createdAt: string; duration: number | string };
type PlaylistTrack = ApiTrackLike & {
createdAt: string;
duration: number | string;
listensCount: number | string;
};
interface Props {
tracks: PlaylistTrack[];
@@ -27,8 +31,9 @@
index
action
meta={[
{ label: 'Álbum', width: '160px' },
{ label: 'Añadida', width: '140px' }
{ label: 'Álbum', width: '76px' },
{ label: 'Añadida', width: '124px' },
{ label: 'Escuchas', width: '106px' }
]}
class="mt-6 sm:mt-8"
>
@@ -47,6 +52,7 @@
/>
<TrackMeta class="hidden sm:block">—</TrackMeta>
<TrackMeta class="hidden sm:block">{fmtDate(track.createdAt)}</TrackMeta>
<TrackMeta class="hidden sm:block">{Number(track.listensCount)}</TrackMeta>
<TrackMeta>{fmtTime(Number(track.duration))}</TrackMeta>
<form
method="POST"
+67 -42
View File
@@ -1,11 +1,12 @@
<script lang="ts">
import { goto } from '$app/navigation';
import History from '@lucide/svelte/icons/history';
import Shuffle from '@lucide/svelte/icons/shuffle';
import ListMusic from '@lucide/svelte/icons/list-music';
import { player } from '$lib/player/player.svelte';
import { mergeRecentlyPlayed } from '$lib/recentlyPlayed';
import { shuffle as shuffleList } from '$lib/collections';
import { fmtTime, fmtDurationLong } from '$lib/format';
import { fmtTime, fmtDurationLong, fmtPlays } from '$lib/format';
import {
isTargetCurrent,
queueItemForTarget,
@@ -13,6 +14,7 @@
targetExplicit,
targetForQueueItem,
targetId,
targetListensCount,
targetOwnerUserId,
targetTitle,
type TrackTarget
@@ -109,6 +111,12 @@
player.playQueue(shuffleList(spotlightQueue), 0);
}
function onRowKeydown(event: KeyboardEvent, action: () => void) {
if (event.key !== 'Enter' && event.key !== ' ') return;
event.preventDefault();
action();
}
function openContextMenu(event: MouseEvent, target: TrackTarget) {
contextMenu = contextMenuStateFor(event, target);
}
@@ -126,14 +134,14 @@
<section class="page-x pt-3 sm:pt-4">
<div
class="relative overflow-hidden rounded-[24px] bg-[image:var(--mf-hero-bg)] px-6 py-8 transition-[background] duration-[600ms] sm:px-9 sm:py-8.5"
class="relative overflow-hidden rounded-3xl bg-[image:var(--mf-hero-bg)] px-6 py-8 transition-[background] duration-500 sm:px-9 sm:py-8.5"
>
<div
class="relative flex flex-col items-start gap-7 lg:flex-row lg:flex-wrap lg:items-end lg:justify-between"
>
<div class="animate-enter max-w-135 min-w-65">
<h1
class="font-display text-3xl leading-[1.1] font-semibold tracking-[-0.035em] text-pretty text-fg sm:text-4xl"
class="font-display text-3xl leading-tight font-medium tracking-tight text-pretty text-fg sm:text-4xl"
>
{data.greeting}
</h1>
@@ -144,7 +152,7 @@
{#if spotlight}
<Button
variant="accent"
class="!bg-cta-strong !font-bold !text-ink hover:!brightness-95"
class="!bg-cta-strong !text-ink hover:!brightness-95"
onclick={playSpotlight}
>
{heroPlaying ? 'Pausar' : 'Reanudar'}
@@ -158,19 +166,19 @@
{#await data.listeningStats then stats}
<div class="flex gap-6.5">
<div>
<div class="font-display text-2xl font-semibold tracking-[-0.03em] text-fg">
<div class="font-display text-2xl font-medium tracking-tight text-fg">
{stats.tracksThisWeek}
</div>
<div class="mt-1 text-xs text-fg-3">Canciones nuevas escuchadas esta semana</div>
</div>
<div>
<div class="font-display text-2xl font-semibold tracking-[-0.03em] text-fg">
<div class="font-display text-2xl font-medium tracking-tight text-fg">
{fmtDurationLong(Number(stats.secondsThisWeek))}
</div>
<div class="mt-1 text-xs text-fg-3">Tiempo de escucha esta semana</div>
</div>
<div>
<div class="font-display text-2xl font-semibold tracking-[-0.03em] text-fg">
<div class="font-display text-2xl font-medium tracking-tight text-fg">
{stats.streakDays}
</div>
<div class="mt-1 text-xs text-fg-3">Días consecutivos escuchando</div>
@@ -184,17 +192,20 @@
<div class="flex flex-col gap-11.5 page-x pt-10 pb-8 sm:pb-10">
<!-- CONTINUAR ESCUCHANDO -->
<section>
<SectionHeading title="Continuar escuchando" />
<SectionHeading title="Continuar escuchando" subtitle="Retomalo donde lo dejaste" />
{#if continueItems.length > 0}
<div class="grid grid-cols-2 gap-2.5 sm:grid-cols-3 lg:grid-cols-5">
{#each continueItems as item, i (item.id)}
{@const isCurrent = player.current.id === item.id}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="animate-enter rounded-[13px] p-2.25 pr-3.5 transition-colors {isCurrent
role="button"
tabindex="0"
class="animate-enter rounded-art p-2.25 pr-3.5 transition-colors {isCurrent
? 'bg-accent-tint'
: 'hover:bg-hover'}"
style="animation-delay:{Math.min(i, 10) * 40}ms"
onclick={() => playContinue(i)}
onkeydown={(e) => onRowKeydown(e, () => playContinue(i))}
oncontextmenu={(e) => openContextMenu(e, targetForQueueItem(item))}
>
<TrackTitleCell
@@ -202,7 +213,7 @@
title={item.title}
artist={item.artist}
ownerUserId={item.ownerUserId}
coverSize="h-13 w-13"
coverSize="h-14 w-14"
active={isCurrent}
onClick={() => playContinue(i)}
/>
@@ -226,43 +237,43 @@
{#if spotlight}
<section>
<div
class="grid grid-cols-1 overflow-hidden rounded-panel-lg bg-[image:var(--mf-spotlight-bg)] transition-[background] duration-[600ms] lg:grid-cols-2"
class="grid grid-cols-1 overflow-hidden rounded-panel-lg transition-[background] duration-500 lg:grid-cols-2"
style="background-image:var(--mf-spotlight-bg), linear-gradient(to right, transparent 50%, color-mix(in oklch, var(--mf-scrim) 22%, transparent) 61%, transparent 92.5%)"
>
<div class="flex flex-col justify-center gap-5 p-8 sm:p-9">
<div class="flex items-center gap-5">
<div class="flex flex-col justify-center p-8 sm:p-9">
<div
role="button"
tabindex="0"
class="flex w-fit items-center gap-6 self-start"
onclick={() => goto(`/playlists/${spotlight.id}`)}
onkeydown={(e) => onRowKeydown(e, () => goto(`/playlists/${spotlight.id}`))}
>
<PlaylistArt
playlistId={spotlight.id}
trackIds={spotlight.coverTrackIds}
version={spotlight.updatedAt}
size="large"
class="h-28 w-28 shrink-0 rounded-[16px] shadow-cover-md"
class="h-34 w-34 shrink-0 rounded-2xl"
/>
<div class="min-w-0">
<p class="text-xs font-semibold tracking-[0.16em] text-fg-2 uppercase">
<div class="flex min-w-0 flex-col gap-4">
<p class="text-xs font-medium tracking-widest text-fg-2 uppercase">
Playlist destacada
</p>
<h3
class="mt-2.5 truncate font-display text-2xl font-semibold tracking-[-0.03em] text-fg"
>
<h3 class="truncate font-display text-2xl font-medium text-fg">
{spotlight.name}
</h3>
<p class="mt-2 text-sm text-fg-2">{spotlightMeta}</p>
<p class="text-sm text-fg-2">{spotlightMeta}</p>
</div>
</div>
<p class="max-w-110 text-sm leading-[1.7] text-fg-2">
<p class="mt-5 max-w-110 text-sm text-fg-2">
{spotlight.description || 'Tu colección, siempre a mano.'}
</p>
<div class="mt-1 flex gap-2.5">
<div class="mt-5 flex gap-2.5">
<Button variant="accent" onclick={playSpotlight}>Reproducir</Button>
<Button variant="secondary" class="!font-normal" onclick={shuffleSpotlight}>
Aleatorio
</Button>
<Button variant="secondary" onclick={shuffleSpotlight}>Aleatorio</Button>
</div>
</div>
<div
class="flex flex-col gap-0.5 p-5.5 sm:p-6"
style="background-image:linear-gradient(to right, color-mix(in oklch, var(--mf-scrim) 26%, transparent), transparent)"
>
<div class="flex flex-col gap-0.5 p-5.5 sm:p-6">
{#each spotlightRows as { target, seconds }, i (targetId(target))}
<div
role="button"
@@ -273,7 +284,7 @@
e.preventDefault();
playSpotlightTrack(i);
}}
class="flex items-center gap-3 rounded-[10px] p-2 text-left transition-colors hover:bg-hover {isTargetCurrent(
class="flex items-center gap-3 rounded-control p-2 text-left transition-colors hover:bg-hover {isTargetCurrent(
target
)
? 'bg-accent-tint'
@@ -282,7 +293,7 @@
<span class="w-5 shrink-0 text-center text-xs text-muted tabular-nums">{i + 1}</span>
<div class="min-w-0 flex-1">
<div
class="truncate text-sm font-medium {isTargetCurrent(target)
class="truncate text-sm {isTargetCurrent(target)
? 'text-accent-soft'
: 'text-fg'}"
>
@@ -329,11 +340,14 @@
<div class="grid grid-cols-1 gap-x-8.5 gap-y-1.5 lg:grid-cols-2">
{#each popularTargets as target, i (targetId(target))}
{@const isCurrent = isTargetCurrent(target)}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="flex items-center gap-3.5 rounded-[11px] p-2 transition-colors {isCurrent
role="button"
tabindex="0"
class="flex items-center gap-3.5 rounded-control p-2 transition-colors {isCurrent
? 'bg-accent-tint'
: 'hover:bg-hover'}"
onclick={() => playPopular(i)}
onkeydown={(e) => onRowKeydown(e, () => playPopular(i))}
oncontextmenu={(e) => openContextMenu(e, target)}
>
<span class="flex h-3.5 w-4.5 shrink-0 items-end justify-center">
@@ -349,12 +363,15 @@
title={targetTitle(target)}
artist={targetArtist(target)}
ownerUserId={targetOwnerUserId(target)}
coverSize="h-9.5 w-9.5"
coverSize="h-10 w-10"
explicit={targetExplicit(target)}
active={isCurrent}
onClick={() => playPopular(i)}
/>
</div>
<span class="hidden shrink-0 text-xs text-muted tabular-nums sm:block">
{fmtPlays(targetListensCount(target))}
</span>
</div>
{/each}
</div>
@@ -378,7 +395,7 @@
{#if data.playlistsHasMore}
<a
href="/playlists"
class="shrink-0 text-xs font-semibold tracking-[0.07em] text-fg-3 uppercase transition-colors hover:text-fg"
class="shrink-0 text-xs font-medium tracking-wider text-fg-3 uppercase transition-colors hover:text-fg"
>
Ver todas
</a>
@@ -388,27 +405,35 @@
{#if playlists.length > 0}
<div class="grid grid-cols-[repeat(auto-fill,minmax(258px,1fr))] gap-3.5">
{#each playlists as playlist, i (playlist.id)}
<a
href="/playlists/{playlist.id}"
class="group/card animate-enter flex items-center gap-3.5 rounded-[15px] p-3 transition-colors hover:bg-hover"
<div
role="button"
tabindex="0"
class="group/card animate-enter flex items-center gap-3.5 rounded-2xl p-3 transition-colors hover:bg-hover"
style="animation-delay:{Math.min(i, 10) * 40}ms"
onclick={() => goto(`/playlists/${playlist.id}`)}
onkeydown={(e) => onRowKeydown(e, () => goto(`/playlists/${playlist.id}`))}
>
<PlaylistArt
playlistId={playlist.id}
trackIds={playlist.coverTrackIds}
version={playlist.updatedAt}
size="medium"
class="h-15.5 w-15.5 shrink-0 rounded-[11px] shadow-cover-sm"
class="h-15.5 w-15.5 shrink-0 rounded-control"
/>
<div class="min-w-0 flex-1">
<div class="truncate text-sm font-semibold tracking-[-0.01em] text-fg">
<div class="truncate text-sm font-medium tracking-tight text-fg">
{playlist.name}
</div>
{#if playlist.description}
<div class="mt-1 truncate text-xs text-fg-3">{playlist.description}</div>
{/if}
<ArtistLink
name={data.user?.name}
ownerUserId={data.user?.sub}
class="mt-1 text-xs text-fg-3"
/>
</div>
</a>
</div>
{/each}
</div>
{:else}
+1 -11
View File
@@ -33,6 +33,7 @@
--color-cta-strong: var(--mf-cta-strong-bg);
--color-scrim: var(--mf-scrim);
--color-on-art: var(--mf-on-art);
--color-on-art-2: var(--mf-on-art-2);
--color-danger: oklch(63.7% 0.15 25.331);
--color-danger-fg: oklch(88.5% 0.062 18.334);
@@ -42,17 +43,6 @@
--radius-art: 0.8125rem;
--radius-art-lg: 1.125rem;
--radius-art-round: 1.75rem;
--shadow-art: 0 14px 32px rgba(0, 0, 0, 0.45);
--shadow-art-lg: 0 24px 50px -16px rgba(0, 0, 0, 0.75);
--shadow-menu: 0 12px 28px -10px rgba(0, 0, 0, 0.6);
--shadow-player: 0 20px 56px rgba(0, 0, 0, 0.6);
--shadow-glow: 0 0 0 1px var(--mf-border-strong), 0 20px 45px -20px var(--mf-accent-glow);
--shadow-cover-lg: 0 24px 56px rgba(0, 0, 0, 0.55);
--shadow-cover-md: 0 16px 40px rgba(0, 0, 0, 0.5);
--shadow-cover-sm: 0 10px 24px rgba(0, 0, 0, 0.42);
--shadow-cover-xs: 0 8px 20px rgba(0, 0, 0, 0.5);
}
@utility page-x {
+1 -2
View File
@@ -16,8 +16,7 @@
<div class="relative flex w-full max-w-4xl flex-col items-center gap-12 text-center">
<div class="flex items-center gap-3">
<span class="h-8 w-8 rounded-xl bg-[image:var(--mf-logo-grad)] shadow-[var(--mf-logo-glow)]"
></span>
<span class="h-8 w-8 rounded-xl bg-[image:var(--mf-logo-grad)]"></span>
<span class="font-display text-[clamp(1.5rem,3vw,2.5rem)] font-semibold tracking-tight">
Musify
</span>