diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..4b9578b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,73 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Commands + +```bash +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//index.md` — page bundles; each has a `plate` number, `issues`, `categories` (single item), `tags`, `featured` flag, and a `.png` image resource. +- `content/issues//_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 using `layout: 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_SLUG` is 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7e4793e --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# Roux + +A slow-publishing fashion journal — one hundred photographs at a time. +Editorial, couture, beauty and backstage plates. + +**Live:** [roux.pivoine.art](https://roux.pivoine.art) + +--- + +## Stack + +| Layer | Tool | +|---|---| +| Static site generator | Hugo Extended | +| CSS | Tailwind CSS v4 | +| JavaScript | Vanilla (no framework) | +| Package manager | pnpm | +| Server | nginx (Docker) | + +## Development + +```bash +pnpm install +pnpm dev # Tailwind watch + Hugo dev server (http://localhost:1313) +``` + +## Build + +```bash +pnpm build # compile CSS → hugo --minify → public/ +``` + +The compiled CSS at `static/css/main.css` is a build artefact and gitignored. Always run `pnpm build:css` (or `pnpm build`) before committing changes that affect Tailwind output. + +## Content + +Posts live in `content/posts//` as Hugo page bundles. Each bundle contains: +- `index.md` — frontmatter with `plate`, `title`, `description`, `categories`, `tags`, `issues`, optional `featured: true` +- `.png` — the plate image (used for thumbnails, lightbox, og:image) + +Issues are defined in `content/issues//_index.md`. + +### Importing posts + +Content is sourced from `~/projects/ginger/posts.csv` and matching images in `~/projects/ginger/images/final/selected/`: + +```bash +python3 scripts/import-posts.py +``` + +This creates or updates page bundles, assigns plate numbers (sorted alphabetically by filename for stability), normalises descriptions, and copies images. + +## Design tokens + +All colours, fonts, and spacing are defined in `assets/css/main.css` inside `@theme {}` and mirrored as CSS custom properties in `:root`. Edit there — not in a Tailwind config file (v4 has none). + +Key tokens: `--color-paper` `--color-ink` `--color-roux` `--font-display` `--font-serif` `--font-sans` `--pad` `--gap` + +## Deployment + +The repo includes `nginx.conf` and a `Dockerfile` for containerised deployment. Build the image and serve `public/` via nginx. Analytics (Umami) are injected only when `HUGO_ENVIRONMENT=production`. + +## License + +All editorial content, photographs, and design © Roux MMXXVI. All rights reserved. +Contents are explicitly excluded from AI/ML training use without written consent.