initial: four-collection content pipeline for unique.rzen.dev

A small Astro + MDX blog for delightful, daily-use finds. The architecture
separates capture from publication and supports reuse:

- find/    captured items, hidden from indexes
- finds/   editorial superposts referencing find slugs in a grid
- reviews/ full-length writeups; can graduate from a find via fromFind
- posts/   regular essays

Three project-local skills under .claude/skills/ drive the pipeline:
daily-finds (capture-only sweep across sources.json), build-finds (draft
a thematic superpost), build-review (graduate a find).

sources.json carries 47 curated feeds with per-source fetch strategy
(webfetch / curl / skip) so Cloudflare-blocked sites and Reddit JSON
endpoints are handled deterministically. /sources renders a 3-column
card stream with a "Recent finds" cross-reference per source.

Seeds: 17 reviews and one superpost referencing 5 finds.
This commit is contained in:
2026-05-03 11:48:03 -04:00
commit 9858abedc2
95 changed files with 10230 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
---
interface Props {
title: string;
description?: string;
wide?: boolean;
}
const { title, description = 'Unique — a blog about delightful things.', wide = false } = Astro.props;
const siteName = 'Unique';
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content={description} />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<title>{title === siteName ? siteName : `${title} — ${siteName}`}</title>
</head>
<body class:list={[{ wide }]}>
<header>
<a href="/" class="brand">{siteName}</a>
<p class="tagline">A small log of delightful things.</p>
</header>
<main>
<slot />
</main>
<footer>
<p>© {new Date().getFullYear()} Unique</p>
</footer>
<style is:global>
:root {
--fg: #1a1a1a;
--bg: #fafaf7;
--muted: #6b6b6b;
--accent: #b34700;
--rule: #e6e3dc;
--max: 42rem;
}
@media (prefers-color-scheme: dark) {
:root {
--fg: #ececea;
--bg: #161613;
--muted: #8d8d88;
--accent: #ff9c5b;
--rule: #2a2a26;
}
}
* { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
background: var(--bg);
color: var(--fg);
font-family: ui-serif, Georgia, 'Iowan Old Style', 'Apple Garamond', 'Palatino Linotype', serif;
font-size: 18px;
line-height: 1.55;
-webkit-font-smoothing: antialiased;
}
body {
max-width: var(--max);
margin: 0 auto;
padding: 2.5rem 1.25rem 4rem;
}
body.wide { max-width: 76rem; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
header {
margin-bottom: 2.5rem;
border-bottom: 1px solid var(--rule);
padding-bottom: 1.25rem;
}
header .brand {
font-family: ui-sans-serif, system-ui, -apple-system, 'Helvetica Neue', sans-serif;
font-weight: 700;
font-size: 1.5rem;
color: var(--fg);
letter-spacing: -0.01em;
}
header .tagline {
margin: 0.25rem 0 0;
color: var(--muted);
font-size: 0.95rem;
font-style: italic;
}
main { min-height: 60vh; }
footer {
margin-top: 4rem;
padding-top: 1.25rem;
border-top: 1px solid var(--rule);
color: var(--muted);
font-size: 0.85rem;
}
footer p { margin: 0; }
h1, h2, h3 {
font-family: ui-sans-serif, system-ui, -apple-system, 'Helvetica Neue', sans-serif;
letter-spacing: -0.015em;
line-height: 1.2;
}
h1 { font-size: 1.85rem; margin: 0 0 0.5rem; }
code {
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 0.9em;
background: var(--rule);
padding: 0.1em 0.35em;
border-radius: 3px;
}
pre {
background: var(--rule);
padding: 1rem;
border-radius: 6px;
overflow-x: auto;
}
pre code { background: none; padding: 0; }
blockquote {
margin: 1.25rem 0;
padding-left: 1rem;
border-left: 3px solid var(--rule);
color: var(--muted);
font-style: italic;
}
hr { border: 0; border-top: 1px solid var(--rule); margin: 2rem 0; }
</style>
</body>
</html>