feat(ui): rebuild shared chrome and core browse/read pages
- Header: sticky app-wide, active nav highlighting, data-driven theme picker with active swatch, unified SVG icons, deduped login fragment (was duplicated verbatim for desktop + mobile), removed stray console.log - LibrarySwitcher: cleaner sticky bar, SVG action icons, theme-aware - BookCard: the atomic unit now has a real surface (was floating text when wood-paneling was off due to an undefined --wood-border), with cohesive shadow + hover lift; reused across dashboard/bookshelf/series - Dashboard: calmer section headers, snap carousels with SVG chevrons - Bookshelf: recompose the filter wall into a search toolbar + collapsible Filters panel (all 9 filters + save/load/clear preserved), redesigned empty state and pagination - Book detail, series, collections, browse: cohesive cards, SVG action icons, uppercase muted labels, theme-aware badges/links
This commit is contained in:
@@ -16,32 +16,33 @@ templ BrowseDetail(user User, badgeIcon string, badgeLabel string, title string,
|
||||
</head>
|
||||
<body class="theme-{ user.Theme }">
|
||||
@Header(user, backUrl)
|
||||
<div class="sticky top-0 z-40 bg-opacity-95 backdrop-blur border-b" style="background-color: var(--bg-primary);">
|
||||
<div class="w-full px-4 py-3 flex items-center gap-4">
|
||||
<a href={ backUrl } class="text-sm hover:opacity-80 transition-opacity" style="color: var(--text-secondary); text-decoration: none;">
|
||||
← { backLabel }
|
||||
<div class="sticky top-16 z-30 border-b border-line bg-surface/95 backdrop-blur">
|
||||
<div class="w-full px-4 sm:px-6 lg:px-8 py-2.5">
|
||||
<a href={ backUrl } class="inline-flex items-center gap-1.5 text-sm font-medium text-content-muted transition-colors hover:text-content">
|
||||
@Icon("arrow-left", "h-4 w-4")
|
||||
{ backLabel }
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full px-4 py-8">
|
||||
<div class="flex items-center gap-4 mb-6">
|
||||
<span class="px-3 py-1 rounded-full text-sm font-semibold" style="background-color: var(--accent); color: white;">
|
||||
{ badgeIcon } { badgeLabel }
|
||||
</span>
|
||||
<h1 class="text-3xl font-bold" style="color: var(--text-primary)">{ title }</h1>
|
||||
<span class="text-sm" style="color: var(--text-secondary)">{ fmt.Sprintf("%d", len(books)) } books</span>
|
||||
<div class="w-full px-4 sm:px-6 lg:px-8 py-8">
|
||||
<div class="mb-6 flex flex-wrap items-center gap-3">
|
||||
<span class="chip">{ badgeIcon } { badgeLabel }</span>
|
||||
<h1 class="text-2xl font-bold tracking-tight text-content">{ title }</h1>
|
||||
<span class="text-sm text-content-muted">{ fmt.Sprintf("%d", len(books)) } books</span>
|
||||
</div>
|
||||
if len(books) > 0 {
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4">
|
||||
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6">
|
||||
for _, book := range books {
|
||||
@BookCard(book)
|
||||
}
|
||||
</div>
|
||||
} else {
|
||||
<div class="text-center py-16" style="color: var(--text-secondary)">
|
||||
<div class="text-6xl mb-4">{ emptyIcon }</div>
|
||||
<h3 class="text-xl font-semibold mb-2" style="color: var(--text-primary)">No Books Found</h3>
|
||||
<p>{ emptyMessage }</p>
|
||||
<div class="flex flex-col items-center justify-center rounded-2xl border border-dashed border-line py-20 text-center">
|
||||
<div class="mb-3 flex h-14 w-14 items-center justify-center rounded-full bg-surface-hover text-content-muted">
|
||||
@Icon("book", "h-7 w-7")
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-content">No Books Found</h3>
|
||||
<p class="mt-1 text-sm text-content-muted">{ emptyMessage }</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user