Files
website/src/lib/components/tcg/DeckCardTile.svelte
T

97 lines
1.8 KiB
Svelte

<script lang="ts">
import type { DeckCard } from '#lib/content';
import type { TcgCard } from '#lib/tcg/types';
let {
deckCard,
card,
onopen
}: {
deckCard: DeckCard;
card: TcgCard | null | undefined;
onopen: (card: TcgCard) => void;
} = $props();
</script>
<button class="tile" disabled={!card} title={deckCard.name} onclick={() => card && onopen(card)}>
<span class="art">
{#if card}
<img src={card.images.small} alt={deckCard.name} loading="lazy" data-no-viewer />
{:else}
<span class="placeholder muted">{card === null ? 'not found' : 'loading...'}</span>
{/if}
<span class="count">x{deckCard.count}</span>
</span>
<span class="name">{deckCard.name}</span>
</button>
<style>
.tile {
display: flex;
flex-direction: column;
gap: 0.3rem;
width: 100%;
padding: 0;
background: none;
border: none;
text-align: left;
}
.tile:disabled {
cursor: default;
}
.art {
position: relative;
display: grid;
place-items: center;
width: 100%;
aspect-ratio: 63 / 88;
background: color-mix(in srgb, var(--foreground) 5%, transparent);
border: 2px solid transparent;
transition:
transform 0.12s,
border-color 0.12s;
}
.tile:hover:not(:disabled) .art,
.tile:focus-visible .art {
border-color: var(--accent);
transform: translateY(-3px);
}
.tile:focus-visible {
outline: none;
}
img {
width: 100%;
height: 100%;
object-fit: contain;
}
.placeholder {
padding: 0.5rem;
font-size: 0.7rem;
text-align: center;
}
.count {
position: absolute;
right: 6px;
bottom: 6px;
padding: 0 0.4rem;
background: var(--accent);
color: var(--background);
font-size: 0.85rem;
font-weight: 700;
}
.name {
overflow: hidden;
font-size: 0.78rem;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>