···11# CLAUDE.md
2233-This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
44-55-## Development Commands
33+Guidance for AI agents working on madoka.systems - a personal blog built with Zola.
6477-**Primary workflow (via Nix):**
55+## Quick Start
8697```bash
1010-nix develop # Enter development shell
1111-zola serve # Start dev server with hot reload on http://127.0.0.1:1111
88+nix develop # Enter dev shell
99+zola serve # Dev server at http://127.0.0.1:1111
1210zola build --output-dir public # Production build
1311```
14121515-**Font optimization workflow:**
1313+## Architecture
16141717-```bash
1818-pyftsubset static/fonts/HostGrotesk-Italic-VariableFont.ttf \
1919- --unicodes="U+0000-00FF,U+0100-017F,U+0180-024F,U+1E00-1EFF,U+2000-206F,U+2070-209F,U+20A0-20CF,U+2100-214F,U+2190-21FF" \
2020- --output-file=static/fonts/HostGrotesk-Italic-VariableFont.woff2 \
2121- --flavor=woff2
1515+**Stack:** Zola (Rust) + Tera templates + SCSS + Nix
1616+1717+**Key directories:**
1818+- `content/` - Markdown with frontmatter
1919+- `templates/` - Tera HTML templates
2020+- `sass/` - SCSS stylesheets
2121+- `static/` - Unprocessed assets
2222+- `syntax_themes/` - Custom Oxocarbon highlighting themes
2323+2424+## Content Patterns
2525+2626+### Creating Blog Posts
2727+2828+Add to `content/blog/` with frontmatter:
2929+3030+```markdown
3131+---
3232+title: "Post Title"
3333+description: "Brief description for SEO/previews"
3434+date: 2024-01-15
3535+updated: 2024-01-16 # Optional
3636+[extra]
3737+bsky_uri: "at://did:plc:.../app.bsky.feed.post/..." # For comments
3838+---
2239```
23402424-## Architecture Overview
4141+### Images
25422626-**Static Site Generator:** Zola (Rust-based) with Tera templating (Jinja2-like syntax)
4343+Use the `image` shortcode for responsive images:
27442828-**Development Environment:** NixOS flake with direnv for reproducible builds
4545+```markdown
4646+{{ image(src="photo.jpg", alt="Description", caption="Optional caption", eager=false) }}
4747+```
29483030-**Content Structure:**
4949+- Place images in same directory as post (colocated assets)
5050+- Shortcode auto-generates AVIF, WebP, and original formats
5151+- Use `eager=true` for above-fold images only
31523232-- `/content/` - Markdown files with frontmatter
3333-- `/content/blog/` - Blog posts with pagination (6 posts per page)
3434-- Section-based organization with `_index.md` files defining templates
5353+### Pages
35543636-**Template Hierarchy:**
5555+- `content/_index.md` - Homepage
5656+- `content/uses.md` - Static page example
5757+- Add nav links in `config.toml` under `[extra]`
37583838-- `base.html` - Root layout importing macros and includes
3939-- `lander.html` - Base template for homepage and blog listing
4040-- Specialized templates: `blog.html`, `post.html`, `index.html`, `page.html`, `header.html`, `404.html`
4141-- Reusable macros in `/templates/macros/post_macros.html`
4242-- SEO meta tags in `meta.html`
5959+## Template System
43604444-**Styling Architecture:**
6161+**Hierarchy:**
6262+- `base.html` - Root layout, includes header/footer
6363+- `lander.html` - For homepage and blog listing
6464+- `post.html` - Individual blog posts (extends `page.html`)
6565+- `page.html` - Generic content pages
45664646-- Modular SCSS: `_variables.scss`, `_base.scss`, `_layout.scss`
4747-- Variable font implementation with system font fallbacks
4848-- Automatic dark/light theme switching via CSS media queries
4949-- Giallo syntax highlighting (Zola's built-in theme system, generates CSS automatically)
6767+**Key macros:** `templates/macros/post_macros.html`
6868+- `post_list(posts)` - Renders list of posts
6969+- `post_preview(post)` - Single post preview card
7070+- `post_meta(post)` - Date and reading time
50715151-**Build Process:**
7272+**Shortcodes:**
7373+- `image` - Responsive images with AVIF/WebP
52745353-1. Git commit hash substitution (`__GIT_COMMIT__` placeholders in config.toml)
5454-2. SASS compilation to CSS
5555-3. Markdown processing with syntax highlighting
5656-4. RSS feed and sitemap generation
5757-5. Static output to `/public/` directory
7575+## Styling
58765959-## Key Configuration Files
7777+**SCSS files:**
7878+- `_variables.scss` - CSS variables, colors, spacing
7979+- `_base.scss` - Typography and base elements
8080+- `_layout.scss` - Layout structures
8181+- `_bsky-comments.scss` - Bluesky comments widget
8282+- `main.scss` - Entry point
60836161-- `/config.toml` - Main Zola configuration with git commit templating
6262-- `/flake.nix` - Nix development environment and build pipeline
6363-- `/sass/_variables.scss` - Design tokens and theme variables
8484+**Patterns:**
8585+- CSS custom properties for theming (`--bg-primary`, `--text-primary`, etc.)
8686+- Automatic dark/light mode via `prefers-color-scheme`
8787+- Host Grotesk variable font with system fallbacks
64886565-## Content Management Patterns
8989+## Bluesky Comments
66906767-**Frontmatter conventions:**
9191+Posts can include Bluesky-powered comments by adding `bsky_uri` in extra frontmatter. The widget:
9292+- Fetches thread from `public.api.bsky.app`
9393+- Renders nested replies sorted by likes
9494+- Shows stats (likes, reposts, replies) linking to original post
68956969-- `title`, `description` for SEO
7070-- `template` for template override
7171-- `sort_by: "date"` for chronological ordering
7272-- `paginate_by` for pagination control
9696+## Build System
73977474-**Template patterns:**
9898+**Nix flake handles:**
9999+- Git commit substitution (`__GIT_COMMIT__` → actual hash)
100100+- Zola build
101101+- PurgeCSS for unused styles
751027676-- Block inheritance: `{% block title %}`, `{% block main %}`
7777-- Includes: `{% include "header.html" %}`
7878-- Macros: `{{ post_macros::post_preview(post=post) }}`
103103+**Formatting:**
104104+- `nix fmt` runs treefmt (djlint for HTML, nixfmt for Nix)
791058080-This is a content-focused static site without complex logic requiring testing frameworks.
106106+## Common Tasks
107107+108108+### Add new blog post
109109+1. Create `content/blog/YYYY-MM-DD-slug.md`
110110+2. Add frontmatter with title, description, date
111111+3. Optional: Add `bsky_uri` for comments
112112+4. Use `{{ image(...) }}` for images
113113+114114+### Modify templates
115115+- Follow Tera syntax: `{% extends %}`, `{% block %}`, `{{ variable }}`
116116+- Import macros: `{% import "macros/post_macros.html" as post_macros %}`
117117+118118+### Update styles
119119+- Edit SCSS files in `sass/`
120120+- Zola compiles automatically in dev mode
121121+- Uses CSS nesting (modern browsers)
122122+123123+### Font optimization
124124+125125+```bash
126126+pyftsubset static/fonts/HostGrotesk-VariableFont.ttf \
127127+ --unicodes="U+0000-00FF,U+0100-017F" \
128128+ --output-file=static/fonts/HostGrotesk-Regular-subset.woff2 \
129129+ --flavor=woff2
130130+```
131131+132132+## Configuration Notes
133133+134134+**config.toml:**
135135+- `base_url = "https://madoka.systems"`
136136+- Custom syntax themes: Oxocarbon Light/Dark
137137+- Git commit placeholders replaced at build time
138138+- Nav links defined in `[extra]`
139139+140140+## Tips
141141+142142+- Blog pagination: 6 posts per page (set in `content/blog/_index.md`)
143143+- Reading time auto-calculated by Zola
144144+- Anchor links auto-generated on headings
145145+- RSS feed at `/rss.xml`
146146+- No testing framework - this is a static content site