README: project overview, stack, dev/build commands, content import workflow, design tokens, deployment notes. CLAUDE.md: Claude Code guidance — commands, CSS pipeline, content model, layout hierarchy, JS architecture, data flow. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
pnpm dev # Tailwind watch + Hugo dev server in parallel
pnpm build # build:css then hugo --minify → public/
pnpm build:css # Tailwind only → static/css/main.css
pnpm watch:css # Tailwind watch (CSS only)
hugo server -D # Hugo dev server (drafts included)
hugo --minify # Production build
python3 scripts/import-posts.py # Import posts from ~/projects/ginger/posts.csv
CSS must be compiled before Hugo runs. pnpm build does both in order. In dev, pnpm dev runs both concurrently.
Architecture
Hugo Extended static site with Tailwind CSS v4 (no config file — design tokens live in @theme {} in assets/css/main.css).
CSS pipeline
Tailwind reads assets/css/main.css and writes to static/css/main.css (gitignored — build artefact). The @theme {} block defines all design tokens (--color-paper, --color-roux, --font-display, etc.). Global resets are in @layer base so Tailwind utility classes correctly override them.
Content model
content/posts/<slug>/index.md— page bundles; each has aplatenumber,issues,categories(single item),tags,featuredflag, and a.pngimage resource.content/issues/<id>/_index.md— branch bundle for an issue; metadata (title,description,issueNumber,season,status) drives the homepage hero and issue list page.content/imprint.md— standalone page usinglayout: imprint.
Taxonomies: categories, tags, issues (defined in hugo.toml).
Layout hierarchy
layouts/baseof.html ← shell: head, header, main, footer, lightbox, roux-data JSON
layouts/index.html ← homepage: current-issue hero + 5 featured plates
layouts/_default/list.html ← two branches: kind="taxonomy" (term cards) | kind="term"/section (paginated post grid)
layouts/_default/single.html ← post plate page (triggers lightbox via window.__ROUX_OPEN_SLUG)
layouts/_default/imprint.html← prose page layout
layouts/issues/list.html ← paginated post grid scoped to an issue
layouts/issues/terms.html ← issue index, reads issueIds from hugo.toml params
layouts/404.html ← editorial 404 page
Key partials: header.html, footer.html, card.html (reusable post card), lightbox.html, pagination.html, logo.html.
JavaScript (static/js/app.js)
Single vanilla JS file, no build step. Loaded from baseof.html. Reads #roux-data (JSON injected by Hugo containing all posts) at runtime.
Responsibilities:
- Inverted search index — weighted token scoring across title, tags, categories, description; prefix matching; renders into
#searchpop. - Lightbox — full-screen plate viewer with keyboard nav, thumbnail strip, share/copy URL, meta panel. Opened automatically when
window.__ROUX_OPEN_SLUGis set (direct URL to a post). - Ribbon dismiss, tab sync, view transitions (
document.startViewTransition), masthead date.
Data flow: homepage featured plates
The homepage shows exactly the posts with featured: true in frontmatter. Mark posts via featured: true; the template filters with where .Site.RegularPages ".Params.featured" true.
Content import
scripts/import-posts.py reads ~/projects/ginger/posts.csv and ~/projects/ginger/images/final/selected/. It creates/updates page bundles deterministically (sorted by filename → stable plate numbers). Run it from the repo root after updating the upstream CSV or image set.
Hugo params (hugo.toml)
issueNumber, issueName, issueSeason, issueBlurb are fallback values used when $.Site.GetPage "/issues/01" returns nil. issueIds drives the issues terms page. umamiSrc/umamiId are injected only in production (hugo.IsProduction).
nginx
nginx.conf at repo root is the production server config (used in Docker). error_page 404 /404.html is already wired.