CLAUDE.md
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Academic personal website for Alec Glisman, built with Jekyll on the Academic Pages template (fork of Minimal Mistakes). Hosted on GitHub Pages at https://alec-glisman.github.io/.
Environment Setup
Requirements
- Docker Desktop (recommended — no Ruby/Python setup required)
- Alternative: Ruby 3.1+, Python 3.9+, Bundler (see
SETUP.md)
Installation
See SETUP.md for detailed setup instructions.
Quick start with Docker (recommended):
# Start development server (http://localhost:4000)
docker compose up dev
# Run test suite
docker compose run test
Quick start without Docker (requires Ruby 3.1+ and Bundler):
# Install Ruby dependencies
bundle install
# Create Python virtual environment
python3 -m venv venv
source venv/bin/activate
# Install test dependencies
pip install -r tests/requirements.txt
playwright install chromium
Build & Development Commands
Docker (recommended)
# Start dev server with live reload
docker compose up dev
# Run all tests
docker compose run test
# Run fast unit tests only
docker compose run test make test-unit
Native
# Install dependencies
bundle install
# Local development with live reload
bundle exec jekyll liveserve
# Build static site
bundle exec jekyll build
# Minify JavaScript assets
npm run build:js
# Watch JS for changes during development
npm run watch:js
# Run test suite
source venv/bin/activate # Activate virtual environment
cd tests && make test # All tests
cd tests && make test-unit # Fast unit tests only
Development server runs at http://localhost:4000. Use _config.dev.yml for local overrides (expanded SCSS, no analytics).
GitHub Pages automatically builds and deploys on push to main.
Repository Structure
Site Source Files
- _config.yml: Main Jekyll configuration (site title, author, collections, plugins)
- _config.dev.yml: Development overrides (expanded SCSS, no analytics)
- _pages/: Core pages (about.md, research.md, experience.md, projects.md, skills.md, publications.md, talks.md, teaching.md, 404.md, plus archive/utility pages)
- _publications/: Publication collection (5 entries with front matter: title, venue, date, DOI, excerpt)
- _talks/: Talk/seminar collection
- _teaching/: Teaching/course collection
- _layouts/: Page templates (default.html, single.html, archive.html, compress.html)
- _includes/: Reusable Liquid partials (head/, footer/, masthead, scripts, etc.)
- _sass/: SCSS source files
- _variables.scss: Color, font, spacing overrides (Navy #1B2A4A, Teal #0EA5C9, Syne/Outfit/Inter fonts)
- _custom.scss: Custom styles for design system (masthead, footer, animations, cards, buttons)
- Theme partials: _base.scss, _buttons.scss, _footer.scss, _masthead.scss, _navigation.scss, etc.
- assets/: Compiled CSS and JS
- css/main.scss: Primary stylesheet (imports all SCSS files)
- js/main.min.js: Minified JavaScript bundle
- js/_main.js: jQuery plugins (FitVids, Stickyfill, smooth scroll, lightbox, sidebar toggle)
- _data/: YAML data files
- navigation.yml: Main navigation menu (7 items)
- authors.yml: Author profile (Alec Glisman)
- ui-text.yml: Localization strings
- files/: Downloadable PDFs (publications)
- images/: Site images (profile.png, publication figures, icons)
Test Suite
- tests/: Comprehensive Python test suite (13 test files, 5 categories)
- conftest.py: Pytest configuration and session fixtures (Jekyll build, HTTP server, Playwright browser)
- requirements.txt: Python dependencies (pytest, playwright, beautifulsoup4, etc.)
- pytest.ini: Pytest configuration
- Makefile: Convenience commands (make test, make test-unit, etc.)
- README.md: Full test documentation
- fixtures/: Axe-core JS for accessibility testing (auto-downloaded)
- unit/: Source file validation (build process, YAML, front matter)
- integration/: HTML parsing (structure, links, content)
- acceptance/: HTTP server tests (page accessibility, WCAG compliance)
- regression/: Change detection (CSS classes, color system, snapshots)
- e2e/: Browser automation (navigation, animations, responsive design)
Project Configuration Files
- Gemfile: Ruby dependencies (github-pages, jekyll-feed, hawkins)
- Gemfile.lock: Locked gem versions (auto-generated by
bundle install) - package.json: Node.js dependencies (minimal-mistakes theme, uglify-js for JS minification)
- .ruby-version: Specifies Ruby version for rbenv (3.1)
- venv/: Python virtual environment (created by
python3 -m venv venv)
Architecture
- Jekyll static site using Liquid templates, Markdown content, and SCSS styling
- Design system:
- Colors: Navy (
#1B2A4A) primary, Teal (#0EA5C9) accent, body background#F8FAFC - Fonts: Syne (headings, h1-h6,
.page__title), Outfit (body, nav, buttons), Inter (fallback) — loaded via Google Fonts in_includes/head/custom.html - Component classes:
.research-card,.experience-entry,.project-card,.skill-group,.hero-intro,.pub-card-inner - Buttons:
.btn--primary-cta(teal fill),.btn--outline-cta(navy outline) - Badges:
.research-badge--ai,--physics,--drug,--sim - Tags:
.skill-tag(pill-shaped),.achievement(inline highlight) - Animation:
.revealclass + IntersectionObserver in_includes/scripts.html(adds.is-visibleon scroll) - Timeline:
.experience-entry--industry(navy dot) /--lab(emerald dot)
- Colors: Navy (
- CSS: Cascading imports from Minimal Mistakes theme base (
_sass/), overridden by_variables.scss(colors, fonts, breakpoints) then_custom.scss(all custom component styles) - JavaScript: jQuery 1.12.4 plugins in
assets/js/_main.js(FitVids, Stickyfill, smooth scroll, Magnific Popup); scroll-reveal and heading anchor-link scripts inline in_includes/scripts.html - Collections: Publications (5), talks (2), teaching (2) — all output as individual pages. Portfolio collection defined in
_config.ymlbut has no content.
Key Details
- Markdown engine: kramdown with GFM
- Syntax highlighting: Rouge
- Plugins: jekyll-paginate, jekyll-sitemap, jekyll-gist, jekyll-feed, jekyll-redirect-from
- No CI/CD pipelines — relies entirely on GitHub Pages built-in Jekyll compilation
- VS Code workspace includes cSpell dictionary for academic/research terminology
Gotchas / Non-obvious Patterns
- Build excludes:
_config.ymlexcludes CLAUDE.md, SETUP.md, Dockerfile, docker-compose.yml, tests/, and other non-site files from the Jekyll build. New documentation files must be added to this exclude list. - Jekyll MIME type bug: The Dockerfile patches a Jekyll 3.10.0 bug where
@mime_types_charsetcan be nil, usingsedto add safe-navigation (&.). This patch is in both thebaseandtestDocker stages. - LiveReload port: Docker dev server requires both port 4000 (Jekyll) and port 35729 (LiveReload WebSocket) mapped.
- JS minification is manual: After editing
assets/js/_main.js, runnpm run build:jsto regenerateassets/js/main.min.js. Usenpm run watch:jsduring active JS development. - Snapshot baselines auto-create: Regression tests in
tests/regression/test_snapshots.pycreate JSON baselines on first run (intests/regression/snapshots/). They skip on first run — re-run to get results. Usepytest regression/ --update-snapshotsto intentionally update baselines. - axe-core auto-downloaded: Accessibility tests download
axe-core.min.jsfrom CDN and cache it intests/fixtures/. No manual download needed. - Portfolio collection is dormant:
_config.ymldefines aportfoliocollection and_pages/portfolio.htmlexists, but there is no_portfolio/content directory. _config.ymlnot hot-reloaded: Jekyll does not hot-reload_config.ymlchanges — restartjekyll serveafter editing.
Content Editing Guide
Adding a Publication
- Create a new file in
_publications/namedYYYY-slug.md - Required front matter (validated by
tests/unit/test_front_matter.py):title,collection: publications,permalink: /publications/YYYY-slug/excerpt(one-line summary),date(YYYY-MM-DD),venuepaperurl(HTTPS DOI or journal URL),citation(full formatted citation)
- Optional: Add a figure image to
images/and PDF tofiles/ - Run
make test-unitintests/to validate front matter
Adding a Talk
- Create a new file in
_talks/namedYYYY-slug.md - Required front matter:
title,collection: talks,type(e.g., “Conference proceedings talk”),excerpt,permalink,venue,date,location
Adding a Teaching Entry
- Create a new file in
_teaching/namedYYYY-term-slug.md - Required front matter:
title,collection: teaching,type(e.g., “Graduate course”),permalink,venue,date,location
Editing Pages
- Core content pages are in
_pages/as Markdown files with YAML front matter - Front matter specifies
layout,title,permalink, andauthor_profile - Pages use Liquid template syntax (e.g., ``)
- Refer to Scientific Writer Guidelines for tone, style, and citation formatting
Code Style / Conventions
- Markdown front matter: YAML between
---delimiters. Date format:YYYY-MM-DD. Permalinks end with/. - SCSS: Custom styles go in
_sass/_custom.scss. Variable overrides go in_sass/_variables.scss. Never edit theme partials directly. - Liquid templates: Use `` at top of includes. Use
https://alec-glisman.github.ioprefix for asset URLs. - File naming: Publications:
YYYY-slug.md. Images: descriptive names inimages/. PDFs: infiles/. - HTML classes: BEM-like naming for custom components (e.g.,
.research-badge--ai,.experience-entry--industry).
Testing
Test Suite Overview
A comprehensive Python test suite with 13 test files covering 5 categories:
- Unit Tests (~5-10s) — Source file validation
- Jekyll build succeeds with no errors
- YAML data files are valid (navigation, authors)
- Publication front matter is complete and unique
- Integration Tests (~10-15s) — HTML parsing and verification
- HTML structure is correct (lang, title, nav, footer, meta tags)
- Internal links resolve to existing files
- Expected content is present on each page
- Acceptance Tests (~30-40s) — HTTP server verification
- All pages return HTTP 200
- Pages load within performance baseline
- WCAG accessibility compliance (axe-core)
- Regression Tests (~10-15s) — Change detection
- Custom CSS classes are present (
.reveal,.research-card, etc.) - Design colors are applied (Navy, Teal)
- Navigation and publication structure unchanged
- Custom CSS classes are present (
- End-to-End Tests (~60-90s) — Browser automation
- Navigation between pages works
- Scroll-reveal animations trigger
- Responsive design works (mobile, tablet, desktop)
Running Tests
Docker (recommended)
docker compose run test # All tests
docker compose run test make test-unit # Fast unit tests only
docker compose run test make test-integration # HTML parsing
docker compose run test make test-acceptance # HTTP server + accessibility
docker compose run test make test-regression # Snapshots and CSS
docker compose run test make test-e2e # Browser automation
docker compose run test make clean # Clean cache
Native
source venv/bin/activate
cd tests
make test # All tests
make test-unit # Fast unit tests only
make test-integration # HTML parsing
make test-acceptance # HTTP server + accessibility
make test-regression # Snapshots and CSS
make test-e2e # Browser automation
pytest unit/test_build.py -v
pytest -k "navigation" -v
pytest regression/ --update-snapshots # Update snapshots
make clean
Test Requirements
- Docker (recommended — all dependencies bundled)
- Native: Python 3.9+, Playwright Chromium, pytest, Jekyll (Ruby 3.1+)
See tests/README.md for full test documentation.
Testing Best Practices
- Run
make test-unitfrequently during development (takes ~5-10 seconds) - Run full
make testbefore committing to catch integration issues - When adding new pages, add assertions to
tests/integration/test_content.pyto verify content - When changing CSS/design, check regression tests for class presence
- When modifying navigation, snapshots detect structure changes automatically
Additional Configuration
- If you are modifying or writing new content, please refer to the Scientific Writer Guidelines for best practices on tone, style, and formatting as well as how to do proper citations and maintain consistency across the site.
- For environment setup details, see
SETUP.md
Agent skills
Issue tracker
Issues and specs live as GitHub issues in this repo (alec-glisman/alec-glisman.github.io), managed via the gh CLI. See docs/agents/issue-tracker.md.
Domain docs
Single-context layout — a root CONTEXT.md + docs/adr/ (created lazily as terms/decisions are resolved; none exist yet). See docs/agents/domain.md.
