1
0
mirror of https://github.com/avinal/avinal.github.io.git synced 2026-07-04 07:40:09 +05:30

remove bookmarks page, add glibc contributions

Assisted by Claude Code

Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
This commit is contained in:
2026-05-19 11:46:11 +05:30
parent 4f942563c1
commit f03f57f064
54 changed files with 66 additions and 849 deletions
-327
View File
@@ -1,327 +0,0 @@
---
import BaseLayout from "@/layouts/BaseLayout.astro";
import bookmarksData from "@/data/bookmarks.json";
interface Bookmark {
title: string;
author: string;
type: "book" | "movie" | "show" | "anime";
year: number;
url?: string;
image?: string;
note?: string;
favorite?: boolean;
}
const bookmarks = (bookmarksData as Bookmark[]).sort((a, b) => b.year - a.year);
const typeLabels: Record<string, string> = {
book: "Books",
movie: "Movies",
show: "Shows",
anime: "Anime",
};
const types = ["book", "movie", "show", "anime"] as const;
const bookCount = bookmarks.filter((b) => b.type === "book").length;
const movieCount = bookmarks.filter((b) => b.type === "movie").length;
const showCount = bookmarks.filter((b) => b.type === "show").length;
const animeCount = bookmarks.filter((b) => b.type === "anime").length;
---
<BaseLayout title="Bookmarks" description="Books, movies, and shows I've enjoyed">
<div class="bookmarks-page">
<header class="bookmarks-header">
<h1>Bookmarks</h1>
<p class="bookmarks-desc">
Books, movies, shows, and anime I think are worth your time. Starred entries are personal favorites.
</p>
</header>
<div class="stats-bar">
<button class="stat stat-total active" data-filter="all">
<svg class="stat-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
<span class="stat-value">{bookmarks.length}</span>
<span class="stat-label">all</span>
</button>
<button class="stat stat-books" data-filter="book">
<svg class="stat-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
<span class="stat-value">{bookCount}</span>
<span class="stat-label">books</span>
</button>
<button class="stat stat-movies" data-filter="movie">
<svg class="stat-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="20" rx="2.18" ry="2.18"/><line x1="7" y1="2" x2="7" y2="22"/><line x1="17" y1="2" x2="17" y2="22"/><line x1="2" y1="12" x2="22" y2="12"/><line x1="2" y1="7" x2="7" y2="7"/><line x1="2" y1="17" x2="7" y2="17"/><line x1="17" y1="7" x2="22" y2="7"/><line x1="17" y1="17" x2="22" y2="17"/></svg>
<span class="stat-value">{movieCount}</span>
<span class="stat-label">movies</span>
</button>
<button class="stat stat-shows" data-filter="show">
<svg class="stat-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="7" width="20" height="15" rx="2" ry="2"/><polyline points="17 2 12 7 7 2"/></svg>
<span class="stat-value">{showCount}</span>
<span class="stat-label">shows</span>
</button>
<button class="stat stat-anime" data-filter="anime">
<svg class="stat-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
<span class="stat-value">{animeCount}</span>
<span class="stat-label">anime</span>
</button>
</div>
<div class="bookmarks-grid">
{bookmarks.map((b) => (
<a
class="bookmark-card"
data-type={b.type}
href={b.url}
target="_blank"
rel="noopener noreferrer"
>
{b.image && (
<div class="bookmark-cover">
<img src={b.image} alt={b.title} loading="lazy" decoding="async" />
{b.favorite && (
<span class="bookmark-fav" title="Personal favorite">
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1.5"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</span>
)}
</div>
)}
<div class="bookmark-body">
<div class="bookmark-top">
<span class="badge bookmark-type">{b.type}</span>
<span class="bookmark-year">{b.year}</span>
</div>
<h3 class="bookmark-title">{b.title}</h3>
<p class="bookmark-author">{b.author}</p>
</div>
</a>
))}
</div>
</div>
</BaseLayout>
<style>
.bookmarks-page {
max-width: var(--max-w-page);
margin-inline: auto;
}
.bookmarks-header {
margin-bottom: var(--space-8);
}
.bookmarks-header h1 {
margin-bottom: var(--space-3);
}
.bookmarks-desc {
font-size: var(--text-lg);
color: var(--text-secondary);
line-height: var(--leading-relaxed);
max-width: var(--max-w-prose);
}
.stats-bar {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: var(--space-3);
margin-bottom: var(--space-6);
}
.stat {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-2);
padding: var(--space-4) var(--space-3);
border: 1px solid var(--border);
background: var(--bg-surface);
cursor: pointer;
font-family: inherit;
transition: border-color var(--duration-fast) var(--ease-out),
box-shadow var(--duration-fast) var(--ease-out),
background var(--duration-fast) var(--ease-out);
}
.stat:hover {
border-color: var(--stat-color);
box-shadow: var(--shadow);
}
.stat-icon {
opacity: 0.4;
transition: opacity var(--duration-fast) var(--ease-out),
color var(--duration-fast) var(--ease-out);
}
.stat:hover .stat-icon,
.stat.active .stat-icon {
opacity: 1;
color: var(--stat-color);
}
.stat-total { --stat-color: var(--accent); }
.stat-books { --stat-color: #10b981; }
.stat-movies { --stat-color: #f59e0b; }
.stat-shows { --stat-color: #8b5cf6; }
.stat-anime { --stat-color: #ef4444; }
.stat-value {
font-size: var(--text-2xl);
font-weight: 800;
font-variant-numeric: tabular-nums;
color: var(--text);
line-height: 1;
transition: color var(--duration-fast) var(--ease-out);
}
.stat:hover .stat-value,
.stat.active .stat-value {
color: var(--stat-color);
}
.stat-label {
font-size: var(--text-xs);
font-weight: 500;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.stat.active {
border-color: var(--stat-color);
background: color-mix(in srgb, var(--stat-color) 8%, var(--bg-surface));
}
@media (max-width: 600px) {
.stats-bar {
grid-template-columns: repeat(3, 1fr);
}
}
.bookmarks-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: var(--space-4);
}
@media (max-width: 900px) {
.bookmarks-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 500px) {
.bookmarks-grid {
grid-template-columns: 1fr;
}
}
.bookmark-card {
border: 1px solid var(--border);
background: var(--bg-surface);
overflow: hidden;
display: flex;
flex-direction: column;
text-decoration: none;
color: inherit;
cursor: pointer;
transition: border-color var(--duration-fast) var(--ease-out),
box-shadow var(--duration-fast) var(--ease-out);
}
.bookmark-card:hover {
border-color: var(--border-strong);
box-shadow: var(--shadow);
}
.bookmark-card[data-hidden] {
display: none;
}
.bookmark-cover {
aspect-ratio: 2 / 3;
overflow: hidden;
background-color: var(--bg-surface-hover);
position: relative;
}
.bookmark-cover img {
width: 100%;
height: 100%;
object-fit: cover;
filter: grayscale(100%);
transition: filter var(--duration-normal) var(--ease-out);
}
.bookmark-card:hover .bookmark-cover img {
filter: grayscale(0%);
}
.bookmark-fav {
position: absolute;
top: var(--space-2);
right: var(--space-2);
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
background: rgba(0, 0, 0, 0.6);
color: #f59e0b;
border-radius: 50%;
}
.bookmark-body {
padding: var(--space-4) var(--space-5) var(--space-5);
}
.bookmark-top {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--space-3);
}
.bookmark-type {
text-transform: capitalize;
}
.bookmark-year {
font-size: var(--text-xs);
color: var(--text-muted);
font-variant-numeric: tabular-nums;
}
.bookmark-title {
font-size: var(--text-base);
font-weight: 600;
margin-bottom: var(--space-1);
}
.bookmark-author {
font-size: var(--text-sm);
color: var(--text-secondary);
}
</style>
<script>
const stats = document.querySelectorAll<HTMLButtonElement>('.stat[data-filter]');
const cards = document.querySelectorAll<HTMLAnchorElement>('.bookmark-card');
stats.forEach((stat) => {
stat.addEventListener('click', () => {
stats.forEach((s) => s.classList.remove('active'));
stat.classList.add('active');
const filter = stat.dataset.filter;
cards.forEach((card) => {
if (filter === 'all' || card.dataset.type === filter) {
card.removeAttribute('data-hidden');
} else {
card.setAttribute('data-hidden', '');
}
});
});
});
</script>