|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Portfolio website for Adam Jolicoeur (adamjolicoeur.com) built with Eleventy (11ty) static site generator. The site showcases UX/UI design work, development projects, and professional content. Deployed to GitHub Pages from the `docs/` directory. |
| 8 | + |
| 9 | +**Current Version**: 10.0.2 |
| 10 | +**Repository**: https://github.com/AdamJ/adamj.github.io |
| 11 | +**Live Site**: https://adamjolicoeur.com |
| 12 | +**Node.js**: v25.2.1 required (runs on 20+, see `.nvmrc`) |
| 13 | + |
| 14 | +## Critical Build Commands |
| 15 | + |
| 16 | +All commands include expected timings. **NEVER CANCEL** builds—they complete within specified timeouts. |
| 17 | + |
| 18 | +### Development Workflow |
| 19 | +```bash |
| 20 | +# Initial setup (first time only) |
| 21 | +npm install # 60 seconds - installs dependencies |
| 22 | + |
| 23 | +# Start development server |
| 24 | +npm run start # Starts watchers + BrowserSync on http://localhost:8081 |
| 25 | + # NOT port 8080 - this is hardcoded |
| 26 | + |
| 27 | +# Full production build |
| 28 | +npm run build # 20 seconds - runs all build steps in sequence |
| 29 | +``` |
| 30 | + |
| 31 | +### Individual Build Steps |
| 32 | +```bash |
| 33 | +npm run clean # 1 second - removes docs/ directory |
| 34 | +npm run images:optimize # 14 seconds - processes images with Sharp |
| 35 | +npm run build:sass # 2 seconds - compiles SCSS to CSS |
| 36 | +npm run build:eleventy # 2 seconds - static site generation |
| 37 | +npm run postbuild # Auto-runs after build (Autoprefixer + CSSNano) |
| 38 | +``` |
| 39 | + |
| 40 | +### Linting & Validation |
| 41 | +```bash |
| 42 | +npm run lint # 5 seconds - Stylelint check (expect 176+ legacy errors) |
| 43 | +npm run lint:fix # Auto-fix Stylelint issues |
| 44 | +npm run webhint # 30 seconds - accessibility/performance audit |
| 45 | +``` |
| 46 | + |
| 47 | +**Expected Build Warnings (Safe to Ignore)**: |
| 48 | +- 144 Sass deprecation warnings from Bootstrap's `@import` syntax |
| 49 | +- 74+ npm audit vulnerabilities (non-critical for static site) |
| 50 | +- 176+ Stylelint errors (legacy code, non-blocking) |
| 51 | +- 245+ WebHint warnings (accessibility/compatibility, non-blocking) |
| 52 | +- Node version warnings (package requires 22, runs fine on 20+) |
| 53 | + |
| 54 | +## Architecture |
| 55 | + |
| 56 | +### Build Pipeline |
| 57 | +1. **Content** (Markdown/HTML) → **Templates** (Nunjucks) → **Static HTML** |
| 58 | +2. **SCSS** → **Sass compiler** → **PostCSS** (Autoprefixer + minify) → **CSS** |
| 59 | +3. **Raw images** → **Sharp processor** → **WebP + JPEG variants** |
| 60 | +4. **Output**: `docs/` directory (GitHub Pages requirement) |
| 61 | + |
| 62 | +### Directory Structure |
| 63 | +``` |
| 64 | +src/ # Source files (EDIT HERE) |
| 65 | +├── pages/ # Markdown pages (31 total) |
| 66 | +│ ├── designs/ # Design case studies (5 projects) |
| 67 | +│ ├── development/ # Dev projects & code examples |
| 68 | +│ ├── about/ # About & resume pages |
| 69 | +│ └── *.md # Index pages (portfolio.md, etc.) |
| 70 | +├── _includes/ # Nunjucks templates |
| 71 | +│ ├── base.njk # HTML5 shell (nav, meta, footer) |
| 72 | +│ ├── markdown.njk # Markdown wrapper |
| 73 | +│ └── carousel.njk # Image carousel component |
| 74 | +├── _data/ |
| 75 | +│ └── meta.js # Site metadata & social links |
| 76 | +├── assets/ |
| 77 | +│ ├── img/ # Processed images (650+ files, ~21MB) |
| 78 | +│ ├── img-raw/ # Original high-res images (~66MB) |
| 79 | +│ └── AdamJolicoeur-Resume.pdf |
| 80 | +├── sass/ # SCSS stylesheets (22 files, ~2000 lines) |
| 81 | +│ ├── style.scss # Main (imports Bootstrap + custom) |
| 82 | +│ ├── _colors.scss # Color variables |
| 83 | +│ ├── _typography.scss # Font & text styles |
| 84 | +│ └── *.scss # Component partials |
| 85 | +└── js/ # JavaScript files (vanilla JS) |
| 86 | +
|
| 87 | +docs/ # Generated output (DO NOT EDIT) |
| 88 | +└── [build artifacts] # 20-30MB, auto-generated |
| 89 | +
|
| 90 | +scripts/ |
| 91 | +└── image-optimizer.js # Sharp-based image processor |
| 92 | +
|
| 93 | +.eleventy.js # Eleventy configuration (163 lines) |
| 94 | +.github/ |
| 95 | +├── workflows/ |
| 96 | +│ └── eleventy_build.yml # CI/CD: push to main → build → gh-pages |
| 97 | +└── copilot-instructions.md # Comprehensive build guide (190 lines) |
| 98 | +``` |
| 99 | + |
| 100 | +### Template System |
| 101 | +- **Base Layout** (`base.njk`): HTML5 shell with navigation, meta tags, OG tags, Service Worker registration, "Go to Top" button |
| 102 | +- **Template Hierarchy**: `base.njk` → `page.njk` → `markdown.njk` |
| 103 | +- **Markdown Processing**: `markdown-it` with plugins: |
| 104 | + - `markdown-it-anchor`: Auto-heading anchors with `#` symbols |
| 105 | + - `markdown-it-highlightjs`: Syntax highlighting |
| 106 | + - `markdown-it-eleventy-img`: Image optimization |
| 107 | + |
| 108 | +### Eleventy Plugins Active |
| 109 | +1. `@11ty/eleventy-plugin-syntaxhighlight` - Code block highlighting |
| 110 | +2. `@11ty/eleventy-plugin-rss` - RSS feed generation |
| 111 | +3. `@11ty/eleventy-navigation` - Navigation helper |
| 112 | +4. `@11ty/eleventy-plugin-inclusive-language` - Inclusive language linting |
| 113 | +5. `@11tyrocks/eleventy-plugin-emoji-readtime` - Reading time + emoji |
| 114 | +6. `@11tyrocks/eleventy-plugin-sass-lightningcss` - Sass → Lightning CSS |
| 115 | +7. `eleventy-plugin-toc` - Table of contents (h2-h4) |
| 116 | +8. `eleventy-plugin-dropcap` - Drop cap styling |
| 117 | +9. Custom category collections (development, general, design, portfolio) |
| 118 | + |
| 119 | +### Styling Architecture |
| 120 | +- **Framework**: Bootstrap 5.3.8 (grid + components) |
| 121 | +- **Preprocessor**: Sass/SCSS v1.89.2 |
| 122 | +- **Post-Processing**: Autoprefixer v10.4.21 + CSSNano v7.0.7 (minification) |
| 123 | +- **CSS Methodology**: Standard CSS with element-based naming (`.card`, `.btn-primary`) |
| 124 | +- **No utility frameworks** (no Tailwind) |
| 125 | +- **Fonts**: Google Fonts (Inter, Pirata One, Playfair Display) |
| 126 | +- **Icons**: Font Awesome v6+ (CDN + Kit) |
| 127 | + |
| 128 | +### Image Processing Pipeline |
| 129 | +1. Place originals in `src/assets/img-raw/` (high-res source) |
| 130 | +2. Run `npm run images:optimize` (14 seconds) |
| 131 | +3. Sharp generates: |
| 132 | + - Full-size: 1200px width, WebP (80%) + JPEG (85%) |
| 133 | + - Thumbnail: 300px width, WebP (70%) + JPEG (75%) |
| 134 | +4. Output to `src/assets/img/` (~650+ files, ~21MB, committed to repo) |
| 135 | + |
| 136 | +### PWA Features |
| 137 | +- **Service Worker**: `src/sw.js` (offline support, cache-polyfill) |
| 138 | +- **Web Manifest**: `manifest.json` (installable app metadata) |
| 139 | +- **Icons**: Multiple favicon sizes (16, 32, 180, 192, 512px) |
| 140 | + |
| 141 | +### Collections & Data |
| 142 | +**Auto-Generated Collections** (via Eleventy): |
| 143 | +- `development` - Articles tagged with design/development |
| 144 | +- `general` - General articles |
| 145 | +- `design` - Design case studies |
| 146 | +- `portfolio` - Portfolio pieces |
| 147 | +- `specialCollection` - Items with custom "type" field (Bluesky integration) |
| 148 | + |
| 149 | +**Site Metadata** (`src/_data/meta.js`): |
| 150 | +- Site name, description, URL |
| 151 | +- Author info |
| 152 | +- Social links (GitHub, LinkedIn, Bluesky, Mastodon, Dev.to, CodePen, Figma) |
| 153 | +- Environment detection (dev/prod) |
| 154 | + |
| 155 | +### Custom Filters & Shortcodes |
| 156 | +- **Slug Filter**: Removes emoji, sanitizes for URLs (uses `slugify`) |
| 157 | +- **Year Shortcode**: Dynamic copyright year |
| 158 | +- **Package Version Shortcode**: Auto-inserted version from package.json |
| 159 | + |
| 160 | +## Adding Content |
| 161 | + |
| 162 | +### New Page |
| 163 | +Create `.md` file in `src/pages/` with YAML front matter: |
| 164 | +```yaml |
| 165 | +--- |
| 166 | +title: "Page Title" |
| 167 | +layout: markdown.njk |
| 168 | +eleventyNavigation: |
| 169 | + key: unique-key |
| 170 | + title: Nav Title |
| 171 | + order: 10 |
| 172 | +categories: [development, design] |
| 173 | +--- |
| 174 | +``` |
| 175 | + |
| 176 | +### New Design Case Study |
| 177 | +1. Create subfolder in `src/pages/designs/` |
| 178 | +2. Add `index.md` with front matter |
| 179 | +3. Place images in `src/assets/img-raw/[project-name]/` |
| 180 | +4. Run `npm run images:optimize` |
| 181 | + |
| 182 | +### Modify Site Navigation |
| 183 | +Edit `eleventyNavigation` in page front matter: |
| 184 | +- `key`: Unique identifier |
| 185 | +- `title`: Display text in nav |
| 186 | +- `order`: Menu position (lower numbers first) |
| 187 | + |
| 188 | +## Working with Styles |
| 189 | + |
| 190 | +### SCSS File Organization |
| 191 | +- **Main**: `src/sass/style.scss` (imports Bootstrap + custom partials) |
| 192 | +- **Colors**: `src/sass/_colors.scss` |
| 193 | +- **Typography**: `src/sass/_typography.scss` |
| 194 | +- **Layout**: `src/sass/_layout.scss` |
| 195 | +- **Components**: Individual `_component.scss` files (buttons, cards, gallery, etc.) |
| 196 | + |
| 197 | +### CSS Build Process |
| 198 | +- **Development**: Auto-compiles via `npm run start` watcher |
| 199 | +- **Production**: `npm run build:sass` → PostCSS → minified output |
| 200 | +- **Output**: `docs/css/style.css` (~98KB) |
| 201 | + |
| 202 | +## Environment Variables |
| 203 | + |
| 204 | +- **`ELEVENTY_ENV=prod`**: Excludes `src/posts/` from build (production) |
| 205 | +- **`ELEVENTY_ENV=dev`**: Includes all content (development, default) |
| 206 | + |
| 207 | +## CI/CD Pipeline |
| 208 | + |
| 209 | +**GitHub Actions** (`.github/workflows/eleventy_build.yml`): |
| 210 | +1. **Trigger**: Push to `main` branch |
| 211 | +2. **Node.js**: v25.x |
| 212 | +3. **Steps**: |
| 213 | + - Checkout code |
| 214 | + - `npm ci` (with Font Awesome token) |
| 215 | + - `npm run build` |
| 216 | + - Deploy `docs/` to `gh-pages` branch |
| 217 | +4. **Live Site**: Auto-deploys to GitHub Pages |
| 218 | + |
| 219 | +**Cloudflare**: Creates pull request previews |
| 220 | + |
| 221 | +## Configuration Files |
| 222 | + |
| 223 | +### `.eleventy.js` (163 lines) |
| 224 | +- Input: `src/`, Output: `docs/` |
| 225 | +- Markdown library setup (markdown-it with plugins) |
| 226 | +- Plugin registration (9+ plugins) |
| 227 | +- Watch targets (monitors SCSS changes) |
| 228 | +- Pass-through copy (assets, icons, CNAME, resume PDF, service worker) |
| 229 | +- Custom filters (slug, year, packageVersion) |
| 230 | +- BrowserSync middleware (404 handling) |
| 231 | +- Category collections |
| 232 | +- Environment detection |
| 233 | + |
| 234 | +### `.stylelintrc.json` |
| 235 | +- Config: `stylelint-config-standard-scss` |
| 236 | +- Plugin: `stylelint-order` (property ordering) |
| 237 | +- Custom rules: Disabled empty line requirements, color function notation |
| 238 | + |
| 239 | +### `.hintrc` |
| 240 | +- WebHint rules for accessibility (axe), best practices, security |
| 241 | +- Expected: 245+ warnings (non-blocking) |
| 242 | + |
| 243 | +## Common Development Tasks |
| 244 | + |
| 245 | +### Add New Images |
| 246 | +```bash |
| 247 | +# 1. Place original files in src/assets/img-raw/ |
| 248 | +# 2. Process with Sharp |
| 249 | +npm run images:optimize # 14 seconds |
| 250 | + |
| 251 | +# 3. Reference in templates with Eleventy Image filter |
| 252 | +# Generated files appear in src/assets/img/ |
| 253 | +``` |
| 254 | + |
| 255 | +### Modify Site Metadata |
| 256 | +Edit `src/_data/meta.js`: |
| 257 | +- Site name, description, URL |
| 258 | +- Social links |
| 259 | +- Author information |
| 260 | + |
| 261 | +### Update Navigation Menu |
| 262 | +Edit `eleventyNavigation` in page front matter (see "Adding Content" above) |
| 263 | + |
| 264 | +### Test Responsive Design |
| 265 | +```bash |
| 266 | +npm run start # Opens BrowserSync on :8081 |
| 267 | +# Resize browser window or use DevTools device emulation |
| 268 | +``` |
| 269 | + |
| 270 | +## Validation & Testing |
| 271 | + |
| 272 | +### Manual Validation Checklist |
| 273 | +After changes, ALWAYS test: |
| 274 | +1. **Home page**: http://localhost:8081 - verify portfolio cards load |
| 275 | +2. **Design portfolio**: http://localhost:8081/designs/ - test case studies |
| 276 | +3. **Development showcase**: http://localhost:8081/development/ - verify links |
| 277 | +4. **Responsive behavior**: Resize browser, test mobile |
| 278 | +5. **Navigation menu**: All links functional |
| 279 | +6. **Images**: Load correctly, WebP with JPEG fallbacks |
| 280 | + |
| 281 | +### Quick Validation Commands |
| 282 | +```bash |
| 283 | +# Verify site builds and serves |
| 284 | +npm run build && npm run start & |
| 285 | + |
| 286 | +# Check key files exist |
| 287 | +ls -la docs/css/style.css # Main CSS (~98KB) |
| 288 | +ls -la docs/assets/img/ | wc -l # 650+ images |
| 289 | + |
| 290 | +# Test pages respond |
| 291 | +curl -I http://localhost:8081/ # Should return 200 OK |
| 292 | +curl -I http://localhost:8081/designs/ # Should return 200 OK |
| 293 | +``` |
| 294 | + |
| 295 | +## Troubleshooting |
| 296 | + |
| 297 | +### Common Issues |
| 298 | +- **Build hangs during image optimization**: Check `src/assets/img-raw/` for valid images |
| 299 | +- **Port 8081 in use**: Kill existing process or change port in `package.json` |
| 300 | +- **Missing Sharp module**: Run `npm install` again (CPU architecture specific) |
| 301 | +- **CSS not updating**: Clear browser cache, check Sass compilation warnings |
| 302 | +- **404 on navigation**: Verify Eleventy generated HTML in `docs/` |
| 303 | + |
| 304 | +### Recovery Commands |
| 305 | +```bash |
| 306 | +# Nuclear option - clean restart |
| 307 | +npm run clean |
| 308 | +rm -rf node_modules |
| 309 | +npm install |
| 310 | +npm run build |
| 311 | + |
| 312 | +# Verify build output |
| 313 | +ls -la docs/ |
| 314 | +ls -la docs/css/ |
| 315 | +ls -la docs/assets/img/ |
| 316 | +``` |
| 317 | + |
| 318 | +## Tech Stack Reference |
| 319 | + |
| 320 | +**Core**: |
| 321 | +- Eleventy (11ty) v3.1.2 - Static site generator |
| 322 | +- Node.js v25.2.1 (runs on 20+) |
| 323 | +- Nunjucks + Liquid - Templating |
| 324 | +- Markdown + YAML - Content format |
| 325 | + |
| 326 | +**Frontend**: |
| 327 | +- Bootstrap v5.3.8 - Grid + components |
| 328 | +- Sass/SCSS v1.89.2 - Styles |
| 329 | +- Vanilla JavaScript - No framework |
| 330 | +- Font Awesome v6+ - Icons |
| 331 | +- Prism.js - Syntax highlighting |
| 332 | + |
| 333 | +**Build Tools**: |
| 334 | +- Sharp - Image processing |
| 335 | +- Autoprefixer v10.4.21 - CSS vendor prefixes |
| 336 | +- CSSNano v7.0.7 - CSS minification |
| 337 | +- Stylelint v16.20.0 - SCSS linting |
| 338 | +- WebHint v7.1.13 - Accessibility audits |
| 339 | + |
| 340 | +## External Documentation |
| 341 | +- **Eleventy**: https://www.11ty.dev/docs/ |
| 342 | +- **Bootstrap**: https://getbootstrap.com/docs/5.3/ |
| 343 | +- **Sass**: https://sass-lang.com/documentation/ |
| 344 | +- **Sharp**: https://sharp.pixelplumbing.com/ |
| 345 | +- **11ty Recipes**: https://11ty.recipes/ |
| 346 | +- **The 11ty Bundle**: https://11tybundle.dev/ |
0 commit comments