<script lang="ts"> import type { ImageFragment } from '$gql/graphql'; import { src } from '$lib/Utils'; import Star from '$lib/icons/Star.svelte'; import type { Snippet } from 'svelte'; interface CardDetails { title: string; favourite?: boolean; subtitle?: string | null; cover?: ImageFragment; } interface Props { href: string; details: CardDetails; compact?: boolean; coverOnly?: boolean; overlay?: Snippet; children?: Snippet; footer?: Snippet; onclick?: (event: MouseEvent) => void; } let { href, details, compact = false, coverOnly = false, overlay, children, footer, onclick }: Props = $props(); </script> <a {href} class="grid-card-v sm:grid-card-h relative grid overflow-hidden rounded-sm bg-slate-900 shadow-md shadow-slate-950/30 focus-visible:outline-4 focus-visible:outline-blue-600" class:compact class:grid-card-cover-only={coverOnly} {onclick} > {@render overlay?.()} {#if details.cover} <img class="h-full w-full object-cover object-[left_top]" width={details.cover.width} height={details.cover.height} src={src(details.cover)} alt="" title={details.title} /> {/if} {#if !coverOnly} <article class="p flex h-full flex-col p-2 pb-1"> <header class="mb-2"> <h2 class="self-center text-sm font-medium [grid-area:title]" title={details.title}> {details.title} </h2> {#if details.subtitle} <h3 class="ellipsis-nowrap text-xs opacity-60 [grid-area:subtitle]" title={details.subtitle} > {details.subtitle} </h3> {/if} {#if details.favourite} <div class="flex items-center text-lg [grid-area:fav]"> <Star favourite /> </div> {/if} </header> <section class="max-h-full grow overflow-auto border-y border-slate-800/80 pt-2 text-xs"> {@render children?.()} </section> {#if footer} <div class="mt-1 text-xs"> {@render footer()} </div> {/if} </article> {/if} </a> <style> a.compact { grid-template-columns: 175px 1fr; grid-template-rows: 250px; } img { border-start-start-radius: inherit; border-end-start-radius: inherit; } article > header { display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto; grid-template-areas: 'title fav' 'subtitle fav'; } </style>