CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

# Install dependencies
bundle install

# Local dev server with live reload at http://localhost:4000
bundle exec jekyll serve --livereload

# Production build (outputs to ./build)
bundle exec jekyll build

# Clean build artifacts
bundle exec jekyll clean

# Local CMS admin UI at http://localhost:4000/admin
# (available automatically when serving locally via jekyll-admin gem)

Architecture

This is a Jekyll 4.x static blog based on the devlopr-jekyll theme, hosted at https://www.co3dex.com. It is a pure static site — no backend, no database.

Key directories

  • _posts/ — blog posts as Markdown, named YYYY-MM-DD-slug.md
  • _layouts/ — page templates (post.html, home.html, page.html, etc.)
  • _includes/ — reusable HTML partials injected into layouts
  • _authors/ — author profile pages (one file per author, e.g. hogjonny.md)
  • categories/ — one Markdown file per category (see below)
  • _data/ — YAML data files consumed by layouts/includes
  • assets/ — images, CSS, JS, bower components
  • _sass/ — Sass stylesheets
  • build/ — Jekyll output directory (gitignored)

Post front matter

---
layout: post
title: "Post Title"
summary: "Short summary"
author: hogjonny
date: "YYYY-MM-DD 00:00:00 -0600"
modified_date: "YYYY-MM-DD 00:00:00 -0600"
category: <category-slug>
thumbnail: /assets/img/posts/YYYY-MM-DD-slug.png
keywords: comma,separated,keywords
permalink: /blog/slug/
usemathjax: false
---

Post date (REQUIRED — must not be in the future)

Jekyll silently skips posts whose date: is in the future — no error, the post simply won’t appear after build. Always set date: to today or earlier before publishing.

Category pages (REQUIRED for every new category)

Jekyll does not auto-generate category pages — _config.yml has jekyll-archives disabled. Every unique category: value in any post must have a matching file in categories/ or clicking the category link returns a 404.

Check for missing categories before publishing:

grep -h "^category:" _posts/*.md | sort -u
ls categories/

Create categories/<slug>.md for any missing category:

---
layout: page
title: <Display Name>
permalink: /blog/categories/<slug>/
---

<h5> Posts by Category : CLAUDE.md </h5>

<div class="card">

</div>

The site.categories.<slug> tag must exactly match the category: slug used in posts. The permalink must match the pattern in _includes/blog_post_article.html: /blog/categories/.

Currently defined categories

Slug File
info categories/info.md
jekyll categories/jekyll.md
life categories/life.md
guides categories/guides.md
python categories/python.md
techart categories/techart.md
gamedev categories/gamedev.md

categories/all.md and categories/sample_category.md exist as structural/demo files — not real post categories.

Update this table when adding a new category.

How layouts and includes connect

  • _layouts/post.html — wraps all blog posts; includes blog_post_article.html, blog_sidebar.html, blog_post_comments.html
  • _includes/blog_post_article.html — renders post content, category links, share buttons
  • _includes/blog_sidebar.html — sidebar with recent posts, categories, author info
  • _includes/head.html — SEO tags via jekyll-seo-tag; reads thumbnail, keywords, and description from post front matter
  • _layouts/home.html — paginated blog index (uses jekyll-paginate, 8 posts/page)

Authors

Author pages live in _authors/<slug>.md and are rendered via _layouts/author.html. Posts reference authors by the author: field matching the author’s filename slug.

Draft workflow

There are four distinct draft holding areas — they are not interchangeable.

.docs/wip/ — live free-form drafts

Early writing that isn’t post-shaped yet. Tracked in git, ignored by Jekyll entirely (outside its source tree).

This repository is PUBLIC. Anything committed to .docs/wip/ is immediately readable by anyone on GitHub. Only put drafts here that you are comfortable publishing in their current state. Work material, employer or partner strategy, and anything under NDA goes in .docs/private/ instead.

.docs/private/ — work material, never published

Gitignored by the .docs/* rule in .gitignore, which has explicit exceptions only for wip/ and archive/. Files here live on disk and never enter git. Use for anything work-related, commercially sensitive, or not yet cleared to be public.

Do not add a negation rule for this directory. Its whole purpose is staying untracked.

.docs/archive/ — retired drafts

Working drafts whose posts are already published, plus editorial process artifacts. Tracked, never built. See .docs/archive/README.md for the draft-to-post mapping. Move a draft here after publishing so wip/ only ever shows live work.

_drafts/ — Jekyll native drafts

Fully post-shaped files (complete front matter, permalink, etc.) that are not built or previewed by jekyll serve/build, because neither the Makefile nor scripts/serve.ps1 passes --drafts. To preview them, run bundle exec jekyll serve --livereload --drafts. Use for finished posts staged ahead of their publish date.

Publishing

Move the file to _posts/YYYY-MM-DD-slug.md and set date: to today or earlier (see the future-date rule above). Then move the source draft to .docs/archive/ and add a row to its README.

_posts_archive/ and _archive/ are separate legacy locations holding retired posts and brand image assets — do not publish from these without review.

Windows scripts

scripts/ contains PowerShell equivalents of the Makefile targets (serve.ps1, build.ps1, clean.ps1, install.ps1). Use these on Windows if make is unavailable.

Deployment

The DEPLOY_STRATEGY file controls CI/CD target (none, gh-pages, or firebase). Currently set to none. The site builds to ./build/. Docker Compose files exist for containerized dev/prod if needed.

Universal AI Agent Instructions

For universal guidelines across coding assistants (GitHub Copilot, Cursor, Windsurf, OpenAI, Claude, etc.), refer to: