CLAUDE.md
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
Lewis Blake’s personal/professional website (statistician, ML/optimization background), hosted at www.lewisblake.com via GitHub Pages (repo: lewisblake/lewisblake.github.io). Built with Jekyll, forked from AcademicPages, which itself forks the Minimal Mistakes theme. The theme is fully vendored into this repo (not pulled via remote_theme), so _layouts, _includes, and _sass are all directly editable.
Local development
No Ruby/Jekyll needs to be installed on the host — everything runs in a container.
# First time / after Gemfile changes
docker build -t jekyll-site . # scripts say `podman`, but plain `docker` works identically
# (same CLI syntax) if podman isn't installed
# Start/stop/manage
./jekyll.sh start # serve at http://localhost:4000, live-reloads on file changes
./jekyll.sh stop
./jekyll.sh restart
./jekyll.sh status # recent logs
./jekyll.sh logs # follow logs
./jekyll.sh shell # shell inside the container
./setup.sh # convenience wrapper: builds image if missing, starts server
The scripts hardcode podman; swap in docker if that’s what’s installed (as of this writing, docker is available and podman is not). If invoking Docker directly instead of via jekyll.sh:
docker run -d -p 4000:4000 -p 35729:35729 -v "$(pwd):/site:Z" --name jekyll-server jekyll-site
There is no automated test suite or linter — verification means building the site and checking pages render correctly (visually and via curl/HTTP status).
Deployment
Deployed via GitHub Pages’ legacy “deploy from a branch” build (Settings → Pages → Source), not GitHub Actions. This means:
- Jekyll version is whatever the
github-pagesgem in theGemfilepins (currently Jekyll 3.10 — old, but this is GitHub’s own build environment and is not something to “fix” casually). - Only plugins on GitHub Pages’ whitelist can be used (see
plugins:in_config.yml: jekyll-paginate, jekyll-sitemap, jekyll-gist, jekyll-feed, jekyll-redirect-from). - A GitHub Actions-based deploy was tried and reverted by deliberate choice — the owner prioritizes “keep it working with minimal upkeep” over engineering flexibility. Don’t re-propose migrating the deploy mechanism or bumping the Jekyll version unless asked; both were explicitly weighed and declined.
- If Actions is ever revisited:
ruby/setup-ruby’sbundler-cache: trueinstalls gems intovendor/bundle/inside the repo, and Jekyll’s defaultsource: .will then try to build the vendored gem source as site content (this broke the build once — a Jekyll gem’s own_poststemplate file has an unparsable ERB placeholder date).vendoris already in_config.yml’sexclude:list to guard against this regardless.
_config.yml’s url must stay https://www.lewisblake.com (matching CNAME) — GitHub Pages 301s the apex domain to www, so canonical tags/sitemap/feed should point at www directly, not the apex.
Content architecture
Content lives in Jekyll collections, each with output: true and its own permalink in _config.yml:
_talks,_publications,_publications_technotes,_publications_posters— filename conventionYYYY-MM-DD-slug.md._teaching— courses taught._pages— standalone pages (about/home, cv, projects, publications index, contact, etc.). The home page is_pages/about.md(permalink: /)._data/authors.yml,_data/navigation.yml,_data/ui-text.yml— site-wide author/nav/string data referenced viasite.data.*in Liquid templates.markdown_generator/— Jupyter notebooks/scripts that historically bulk-generated_talks/_publicationsentries from TSV files. Content is now maintained by hand; these are not part of the build.
Styling
assets/css/main.scss is the entry point; it @imports theme partials from _sass/ in a specific order (base → layout → components). Custom additions layered on top of the stock theme, all imported at the end of main.scss:
_animations.scss— restrained fade/slide-in entrance animations (respectsprefers-reduced-motion). Don’t add more without reason; this was a deliberate “just enough” ceiling._dark-mode.scss— dark theme via[data-theme="dark"]attribute + CSS custom properties (--link-color,--border-color, etc.), toggled byassets/js/dark-mode.js(vanilla JS, reads/writeslocalStorage['theme'], independent of the jQuery bundle below)._skills-badges.scss— styles the.skill-tagpill elements on the About page (see below).
Font Awesome is fully self-hosted (vendored SCSS + woff files in assets/fonts/), but _includes/head.html also loads Font Awesome 5.15.4 from cdnjs. This looks redundant but isn’t: the vendored copy is an old version (5.5.0) missing some brand icons actually used in the sidebar (e.g. fa-orcid), so the CDN link is a deliberate, SRI-pinned fallback. Don’t remove it without first checking every fa-/fab fa- icon used in _includes/_data against _sass/vendor/font-awesome/_icons.scss.
JavaScript
assets/js/main.min.js is a pre-built, minified bundle (jQuery 1.12.4 core + plugins + _main.js), assembled by the uglify/build:js npm script in package.json. Node/npm is not installed in the Docker dev image — editing assets/js/_main.js or the plugin files under assets/js/plugins/ will not take effect until someone rebuilds the bundle with Node available elsewhere. Every plugin currently bundled is in active use (_main.js calls all of them): fitVids (video embeds), Stickyfill (sticky author sidebar polyfill), smoothScroll (anchor links), magnificPopup (image lightboxes), and greedy-nav (collapsing mobile menu). None of it is dead code to trim.
Images
Check dimensions/file size before adding images, especially page headers/banners — this repo has shipped multi-megabyte, camera-resolution images as page banners before (a 5991×2350, 4.5MB JPEG mislabeled with a .png extension was used as the homepage hero for some time). Resize to roughly 2× the largest on-page display size and compress before committing.
Skill tags
The About page’s “Technical Skills” section (_pages/about.md) uses local <span class="skill-tag"> elements, not img.shields.io badge images — this was a deliberate change to drop 14 external network requests per page load and keep the visual style consistent with the rest of the site. Follow the same pattern (plain <div class="skill-tags"><span class="skill-tag">Name</span>...</div>) rather than reintroducing shields.io images.
