-```
-
-Bridgy reads this content when syndicating to Bluesky/Mastodon. Interaction types (bookmarks, likes, replies, reposts) include emoji prefix and target URL.
-
-## Code Style
-
-### TypeScript/JavaScript
-
-- **ESM modules:** `"type": "module"` in package.json
-- **Async data files:** `export default async function () { ... }`
-- **Data source pattern:** Return `{ source: "indiekit" | "api" | "error", ...data }`
-- **Date handling:** Always use ISO 8601 strings (`new Date().toISOString()`)
-
-### Nunjucks Templates
-
-- **Property name compatibility:** Support both camelCase and underscore names:
-
-```nunjucks
-{% set bookmarkedUrl = bookmarkOf or bookmark_of %}
-{% set replyTo = inReplyTo or in_reply_to %}
-```
-
-- **Date filter guards:** Always check for null/undefined:
-
-```nunjucks
-{% if published %}
- {{ published | date("PPp") }}
-{% endif %}
-```
-
-- **Markdown engine disabled:** `markdownTemplateEngine: false` to prevent parsing `{{` in content
-- **Safe filter usage:** Use `| safe` for trusted HTML content only
-- **Microformats classes:** Follow IndieWeb conventions (h-entry, p-name, dt-published, e-content, u-photo, etc.)
-
-### CSS
-
-- **Tailwind CSS** for all styling
-- **Dark mode:** `dark:` variants, controlled by `.dark` class on ``
-- **Custom color palette:** `primary` (blue) and `surface` (neutral)
-- **Typography plugin:** `prose` classes for content rendering
-- **Responsive design:** Mobile-first, breakpoints: `sm:`, `md:`, `lg:`
-
-## Common Tasks
-
-### Adding a New Post Type
-
-1. **Create collection** in `eleventy.config.js`:
-
-```javascript
-eleventyConfig.addCollection("checkins", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/checkins/**/*.md")
- .sort((a, b) => b.date - a.date);
-});
-```
-
-2. **Create collection page** (e.g., `checkins.njk`):
-
-```nunjucks
---
-layout: layouts/page.njk
-title: Check-ins
-withBlogSidebar: true
-permalink: /checkins/
+
+## Key custom systems
+
+### Digital Garden (`gardenStage`)
+Posts carry a `gardenStage` front-matter value: `seedling`, `budding`, `cultivating`, or `evergreen`. Stage can also be derived from nested tags (`garden/cultivate` → `cultivating`, etc.).
+
+**Garden badge component** (`_includes/components/garden-badge.njk`):
+- In post-list templates, set `gardenStage` from `post.data.gardenStage` before including, or rely on the component's own fallback.
+- The badge is included **once per post-type branch** (`{% if post.type == "article" %}...{% elif %}...{% endif %}`). Do not add it outside those branches — it will render for every post regardless of type and produce duplicate badges.
+
+### AI Disclosure
+Posts declare AI involvement level in front matter (e.g. `aiCode: T1/C2`). Rendered as a badge below post content and as a hidden `.p-ai-code-level` span in list cards.
+
+### Nested tags
+Categories use Obsidian-style path notation (`lang/de`, `tech/programming`). The `nestedSlugify()` function in `eleventy.config.js` preserves `/` separators during slug generation. Slugification is applied per segment.
+
+### Unfurl shortcode
+`{% unfurl url %}` generates a rich link preview card with caching. Cache lives in `.cache/unfurl/`. The shortcode is registered from `lib/unfurl-shortcode.js`.
+
+### OG image generation
+`lib/og.js` + `lib/og-cli.js` — generates Open Graph images at build time using Satori and resvg-js. Avatar is pulled from `AUTHOR_AVATAR` env var.
+
+### Upstream drift check
+```bash
+npm run check:upstream-widgets # Report widget drift vs theme remote
+npm run check:upstream-widgets:strict # Exit 1 if any drift found
+```
+
---
-{% for post in collections.checkins %}
- {# render post #}
-{% endfor %}
+
+## Templates — things to know
+
+### `blog.njk`
+The main blog listing. Each post type (article, note, bookmark, like, repost, reply, photo) has its own `{% if/elif %}` branch. The AI badge and pagination are **outside** those branches at the `