CLAUDE.md
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
Cole Frank’s personal site — a Jekyll site published via GitHub Pages at colevfrank.github.io. Originally forked from the contrast theme (the upstream README.md is still the theme’s README, not project-specific docs); the visual layer has been substantially rewritten on top of those bones.
Common commands
bundle install # install gems (first run / after Gemfile change)
bundle exec jekyll serve # local dev server with live reload at http://localhost:4000
bundle exec jekyll build # produce static site into _site/
There are no tests or linters configured.
Architecture notes
Theming
- CSS custom properties drive runtime colors and type scale.
_sass/index.sassdeclares:rootwith--bg,--fg,--fg-muted,--accent,--rule,--code-bg,--fs-base,--fs-h1,--fs-h2,--measure. Two override blocks flip palette:@media (prefers-color-scheme: dark) :root:not([data-theme="light"])and:root[data-theme="dark"]. Always reach forvar(--accent)etc. — the bare Sass$dark/$lightvariables are kept only because the theme-agnosticreduce()mixin still uses them at compile time for borders/code-block tints. - Manual theme toggle is wired in
_layouts/default.html: an inline FOUC-blocker readslocalStorage.themeand setsdata-themeon<html>before the stylesheet loads;assets/js/theme.jswires the header<button class="theme-toggle">to flip and persist. - Variable fonts (IBM Plex Sans + JetBrains Mono) live in
assets/fonts/*.woff2and are declared in_sass/font.sasswithformat('woff2-variations'). The Roman variant is<link rel="preload">-ed indefault.html; italic and mono are not preloaded by design.
Content surfaces
- Site config lives in
_config.yml. Top nav and footer socials are arrays (navigation,external); the resume PDF is anavigationentry.extra_icons:holds icon glyph IDs needed by the layouts/components but not by any nav entry (e.g. the toggle’ssun/moon). - Projects page is data-driven. Edit
_data/projects.ymlto add an entry — required keys aretitleandblurb; everything else (date,tags,links.{paper,demo,code,post,video,slides},featured) is optional. Cards render via_includes/project-card.html, sorted bydatedesc. - Home page is
index.htmlat repo root. The_includes/home.htmltemplate is only used when a page setslayout: home; currentindex.htmluseslayout: pageand bypasses it. Post listing isblog.md. - Layout chain: pages declare
layout: pageorlayout: post(in_layouts/), both extend_layouts/default.html.default.htmlloadsassets/css/index.css(theshow_frame: truebranch /frame.sassare disabled — the file has been renamed to_frame.sass.bak). - Reading column is constrained to
var(--measure)(68ch) on prose elements via_sass/layout.sass. Full-bleed components like.profile-sectionand.project-gridlive as direct children of<article>and so escape the cap.
Styling
- Entry stylesheet is
assets/css/index.sasswhich@imports the partials in_sass/. Project-specific overrides go in_sass/custom.sass; theme-inherited bones live inbasic.sass,layout.sass,classes.sass,font.sass,index.sass. - Posts in
_posts/follow Jekyll’sYYYY-MM-DD-slug.mdconvention. Front matter:layout: post,title, optionalmathjax: true(for KaTeX),categories. Reading time and date are emitted by_includes/meta.html→_includes/reading-time.html.
Gotchas
jekyll-sass-converteris pinned to~> 2.2.0(libsass). Several modern CSS features need to be hidden from the compiler::rootand:focus-visibleselectors must be escaped as\:root/\:focus-visiblein indented.sassfiles (libsass mistakes them for property declarations).min()/max()calls in regular property values must be wrapped in interpolation:minmax(#{"min(100%, 22rem)"}, 1fr)— libsass otherwise tries to evaluate them as Sass arithmetic and errors on mixed units.clamp()is fine inside CSS custom-property values (--fs-h1: clamp(...)), but using it as a Sass variable value triggers unit-incompat errors. Define fluid sizes as custom properties, not Sass vars.- Do not migrate to
@use/@forward(Dart Sass-only); stay on@import.
- Ruby 3.3 compat gems (
csv,base64,bigdecimal,logger,ostruct,webrick) are explicitly listed because they were removed from the stdlib default set; keep them in the Gemfile when modifying dependencies. - FontAwesome sprite is build-time generated.
assets/fontawesome/icons.svgis a Liquid template that walkssite.navigation,site.external, andsite.extra_icons, deduping. Icons referenced from layouts/components but not present in any nav entry must be added toextra_icons:in_config.ymlto make it into the sprite. _site/,.jekyll-cache/, andGemfile.lockare gitignored — don’t commit build output.