feat: draw covers for books without one

Full-bleed serif title on a woven ground, drawn in the browser rather than
stored, sized with container queries so one component works from 36px to full
page. Colour is hashed into a list of bookcloth tones instead of the hue wheel.

The grid and search were falling back to default_cover.jpg because a missing
cover made the src "/api/undefined"; they now check for one first.
This commit is contained in:
2026-08-12 13:44:14 -04:00
parent 96789620bb
commit 7e04826fa5
4 changed files with 203 additions and 30 deletions
@@ -10,6 +10,7 @@
import { getLibraryState } from '$lib/state/library.svelte';
import type { PaginatedResponse, Book } from '$lib/schema';
import BookImage from '../view/book-image.svelte';
import GeneratedCover from '../view/generated-cover.svelte';
import { goto } from '$app/navigation';
const libraryState = getLibraryState();
@@ -104,10 +105,16 @@
class="cursor-pointer"
>
<div class="hover:bg-base-200 flex gap-4 p-3">
<BookImage
src="/api/{book.cover_image}"
class="w-24 rounded object-cover shadow-lg"
/>
{#if book.cover_image}
<BookImage
src="/api/{book.cover_image}"
class="w-24 rounded object-cover shadow-lg"
/>
{:else}
<div class="aspect-9/12 w-24 shrink-0 overflow-hidden rounded shadow-lg">
<GeneratedCover {book} />
</div>
{/if}
<div class="flex-top flex flex-col">
<span class="font-serif text-lg">{book.title}</span>
<span class=" text-md">{book.subtitle}</span>