CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Overview
This is a Jekyll-based blog/portfolio site built with a custom theme called “pivoine”. The site combines Ruby (Jekyll) for static site generation with a modern JavaScript/TypeScript build system using webpack and pnpm workspaces.
Build & Development Commands
Jekyll (Ruby) Commands
# Install Ruby dependencies
bundle install
# Serve the site locally (development mode)
bundle exec jekyll serve
# Build the site with LSI (latent semantic indexing) for related posts
bundle exec jekyll build --lsi
# Note: The site uses KaTeX for math rendering which requires Node.js runtime
JavaScript/CSS Build Commands
# Install all dependencies (including workspace packages)
pnpm install
# Build everything (JS + CSS + scripts)
pnpm run build
# Build only JavaScript (modern + legacy bundles)
pnpm run build:js
# Build only CSS
pnpm run build:css
# Build workspace dependencies first, then main project
pnpm run build:all
# Development mode with auto-rebuild
pnpm run dev
# or
pnpm run watch
# Watch JS only
pnpm run watch:js
# Watch CSS only
pnpm run watch:css
# Format JavaScript code
pnpm run format
# Clean built JS files
pnpm run clean
Architecture
Monorepo Structure
The project uses pnpm workspaces with local packages under packages/:
packages/hydecorp/component- Base web component librarypackages/hydecorp/drawer- Drawer componentpackages/hydecorp/push-state- Push state navigationpackages/honeymachine/search- Search functionality
These workspace packages are referenced with workspace:* protocol in package.json.
JavaScript Build System
The webpack configuration (webpack.config.js) creates two bundles:
- Modern bundle (
pivoine-{version}.js) - Targets ES modules-compatible browsers - Legacy bundle (
LEGACY-pivoine-{version}.js) - Targets IE11+ with full polyfills
Entry point: _js/src/entry.js
JavaScript source files in _js/src/ include:
common.js- Shared utilitiesdrawer.js- Drawer navigationpush-state.js- SPA-like navigationsearch.js- Search integrationdark-mode.js- Theme switchingsound.js- Sound effectslightbox.js- Image lightboxclap-button.js- GetClaps integration
CSS Build System
CSS is built via .scripts/build-css.js which processes SCSS files from _sass/:
- Main entry points:
html.scss,my-style.scss,my-inline.scss - Uses inline/link comments to control how CSS is included
- Custom variables in
_sass/my-variables.scss - Theme SCSS in
_sass/pivoine/and_sass/pooleparty/
Jekyll Structure
_config.yml- Main Jekyll configuration with pivoine theme settings_layouts/- Page templates (base, post, page, blog, etc.)_includes/- Reusable HTML partials_posts/- Blog posts organized by category folders (devilish, palina, odinsland, souls, sketches, music)_pages/- Static pages_data/- YAML data files (authors, strings, variables, social, countries, sounds)_sass/- SCSS stylesheets
Content Organization
Posts are organized into featured categories defined in _config.yml:
- Palina
- Odinsland
- Devilish
- Souls
- Sketches
- Music
Each post’s URL follows the pattern: /:categories/:slug
Key Configuration Details
- Math rendering: Uses
kramdown-math-katex(requires Node.js runtime) - Search: Disabled in development, enabled in production via
JEKYLL_ENV=production - Dark mode: Dynamic based on OS settings with manual toggle
- Pagination: 5 posts per page using jekyll-paginate-v2
- Analytics: Umami integration configured
- Related posts: LSI-based (use
--lsiflag when building)
Development Workflow
- Initial setup:
bundle install pnpm install pnpm run build:all - Development:
# Terminal 1: Watch and rebuild JS/CSS pnpm run dev # Terminal 2: Run Jekyll server bundle exec jekyll serve - Production build:
pnpm run build:all JEKYLL_ENV=production bundle exec jekyll build --lsi
Deployment
The site deploys to GitHub Pages via .github/workflows/jekyll-gh-pages.yml. The workflow builds both the JavaScript assets and the Jekyll site, then deploys to pivoine.art (configured via CNAME).
Important Notes
- The site uses Node.js version specified in
.nvmrc - JavaScript builds create versioned filenames based on package.json version
- Some files are auto-generated (look for “AUTOGENERATED” headers)
- Custom scripts in
.scripts/directory handle specialized build tasks - Prettier is configured for JS formatting (
.prettierrc) - RuboCop is configured for Ruby linting (
.rubocop.yml)