CLAUDE.md
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this repo is
Rohan Kapoor’s personal academic site, served by GitHub Pages at https://rkapoor1512.github.io. It is a fork of the academicpages Jekyll theme (itself a fork of Minimal Mistakes). The site is published from the master branch — pushing to master triggers a GitHub Pages rebuild.
A working to-do list of intended site changes lives in README.md (full CV, blog posts, dark mode, Twitter link, etc.). Treat that as authoritative for outstanding site work.
Running locally
bundle install # one-time, installs github-pages gem set
bundle exec jekyll serve -l -H localhost # live-reload at http://localhost:4000
_config.yml is NOT reloaded automatically — restart jekyll serve after editing it.
JavaScript bundle (only needed if editing files in assets/js/):
npm install
npm run build:js # uglifies + concatenates plugins + _main.js → assets/js/main.min.js
npm run watch:js # rebuild on change
The site itself only loads assets/js/main.min.js, so source JS edits are invisible until you re-run the uglify build and commit the regenerated min file.
Architecture
Standard Jekyll layout, but with four custom collections in addition to posts:
_publications/,_talks/,_teaching/,_portfolio/— each markdown file is one entry. Configured as Jekyll collections in_config.ymlwithoutput: trueand permalink/:collection/:path/. The landing pages for each live under_pages/(e.g._pages/publications.mditerates oversite.publications)._posts/— standard Jekyll blog posts; filename must beYYYY-MM-DD-title.md._pages/— top-level pages (about, cv, blog, teaching, talks, publications, etc.). The nav bar that surfaces these is not auto-generated from_pages/; it is hand-edited in_data/navigation.yml, which is indentation-sensitive (YAML — a stray space silently breaks it; comment in the file calls this out)._layouts/,_includes/,_sass/— theme internals._layouts/single.htmlis the default for most content;_layouts/talk.htmlis talk-specific. The author sidebar comes from_includes/author-profile.html, driven by theauthor:block in_config.yml._data/authors.yml,_data/ui-text.yml— multi-author overrides and i18n strings.images/,files/,assets/— static assets. CV PDF is referenced fromnavigation.ymlas/assets/CV_Rohan__Last_updated_Feb2025_.pdf.
Bulk-generating publications/talks
markdown_generator/ contains Jupyter notebooks and equivalent .py scripts that turn publications.tsv / talks.tsv (or a BibTeX file via pubsFromBib.py) into one markdown file per entry under _publications/ or _talks/. Use these instead of hand-writing entries when adding many at once. The generated .md files are what the site actually serves; the TSV/BibTeX is only the source.
Dark mode
Theme is toggled by a button in the masthead and persisted in localStorage under the key "theme". The plumbing:
_includes/head/theme-init.html— synchronous inline script in<head>(before the stylesheet) that readslocalStorage.theme, falls back toprefers-color-scheme, and setsdata-themeon<html>to avoid FOUC._sass/_dark.scss— all dark-mode color overrides live here, scoped underhtml[data-theme="dark"]. The academicpages SCSS uses static$variables (not CSS custom properties), so each surface that needs theming is overridden by selector here. Also contains styling for the.theme-togglebutton._includes/masthead.html— the<button class="theme-toggle">lives at the end of.greedy-nav, positioned absolutely at the right edge.assets/js/dark-mode.js— wires the button, listens for OS-preference changes (only honored if the user hasn’t picked explicitly).- Loaded
deferfrom_includes/head.html; not bundled intomain.min.js.
When adding a new themed surface, add the override inside the html[data-theme="dark"] { ... } block in _dark.scss. The dark palette ($dark-bg, $dark-text, etc.) is defined at the top of that file.
Math (MathJax)
MathJax 3 is loaded from CDN in _includes/head/custom.html. Inline delimiters are configured as both $...$ and \(...\); display is $$...$$ and \[...\]. The config object is set on window.MathJax before the script tag — order matters. Code blocks and <pre> are in skipHtmlTags so math syntax inside fenced code is preserved verbatim.
Kramdown is configured with input: GFM. That means underscores inside $...$ (e.g. $f_n$) can be eaten by kramdown’s italic parser before MathJax sees them. Workarounds: escape ($f\_n$), use display math ($$f_n$$), or use \(f_n\). % is still a LaTeX comment inside math — $70%$ will break the closing delimiter.
Known repo quirks
images/profile_pic.JPGandimages/profile_pic.jpgcollide on case-insensitive filesystems (macOS default).git clonewarns and only checks out one — keep this in mind before referencing either in front matter.author.avataris"file(1).png"— unusual filename with parentheses.descriptionin_config.ymlcurrently ends in “test” (“Mathematics PhD student at Dartmouth test”) — likely a leftover and is part of<meta>/ page titles.analytics.provideris the string"false"(quoted), not the boolean — preserve when editing unless intentionally enabling analytics.- The site is constrained to the GitHub Pages plugin whitelist (see
plugins:andwhitelist:in_config.yml). Adding a new Jekyll plugin generally won’t work on GitHub Pages unless it’s on that allowlist.
.png)