Simon van Dyk

CLAUDE.md - simonvandyk.info Repository Guide

Overview

This is a Jekyll-based personal portfolio website for Simon van Dyk. The site showcases writing, speaking engagements, and photography. It’s a clean, minimalist design with a focus on performance, accessibility, and responsive design patterns.

Repository: simonvandyk.info
Build Tool: Jekyll 4.x (GitHub Pages)
Language: Ruby 3.2.3
Hosting: GitHub Pages
Domain: simonvandyk.info


1. Overall File and Directory Structure

simonvandyk.info/
├── _layouts/              # Jekyll layout templates (4 files)
│   ├── post.html         # Post/article pages with header/footer
│   ├── album.html        # Photo album pages with gallery
│   ├── basic.html        # General page layout
│   └── error.html        # 404/500 error pages
│
├── _includes/            # Reusable template components
│   ├── head.html         # Common <head> content
│   ├── critical-css.html # Inlined CSS for above-the-fold
│   ├── image-viewer.html # Lightbox modal with JS (282 lines)
│   ├── gallery-controls.html # Image size slider component
│   ├── post-sign-off.html    # Post footer signature
│   ├── anonymous-analytics.html # Analytics script
│   └── components/       # Reusable UI components
│       ├── nav-links.html
│       ├── footer.html
│       ├── intro-blurb.html
│       ├── feed-item.html
│       ├── figure.html
│       ├── button.html
│       ├── icon.html
│       ├── profile-mark.html
│       ├── decorative-mark.html
│       ├── title-mark.html
│       └── design-system/ # Design documentation components
│           ├── color-swatch.html
│           ├── contrast-example.html
│           ├── size-example.html
│           └── text-style-example.html
│
├── assets/               # Static assets
│   ├── css/
│   │   ├── main.css          # Main stylesheet (imports all)
│   │   ├── tokens.css        # Design tokens (colors, typography, spacing)
│   │   ├── typography.css    # Text style classes
│   │   ├── reset.css         # CSS reset (based on Josh Comeau's reset)
│   │   ├── fonts.css         # Font face declarations
│   │   ├── layout.css        # Body/layout spacing
│   │   ├── form.css          # Form element styles
│   │   ├── feed.css          # Feed/list styles
│   │   ├── syntax-highlighting.css # Code blocks
│   │   ├── components/       # Component-specific CSS
│   │   │   ├── nav-links.css
│   │   │   ├── footer.css
│   │   │   ├── feed-item.css
│   │   │   ├── figure.css
│   │   │   ├── button.css
│   │   │   ├── icon.css
│   │   │   ├── intro-blurb.css
│   │   │   ├── profile-mark.css
│   │   │   ├── decorative-mark.css
│   │   │   └── title-mark.css
│   │   └── pages/            # Page-specific CSS
│   │       ├── post.css
│   │       └── album.css
│   │
│   ├── fonts/            # Self-hosted fonts
│   │   ├── Karla-Regular.ttf    # Sans-serif body font (preloaded)
│   │   ├── Karla-Bold.ttf
│   │   ├── Karla-Medium.ttf
│   │   ├── Karla-Italic.ttf
│   │   ├── Karla-MediumItalic.ttf
│   │   └── YoungSerif-Regular.otf # Serif display font (preloaded)
│   │
│   ├── img/              # Image assets
│   │   ├── albums/       # Photo albums (date-based directories)
│   │   │   ├── 2023-03-19-belgravia-photo-walk/
│   │   │   ├── 2023-11-04-weekend-in-brighton/
│   │   │   ├── 2024-08-31-the-barbican-conservatory/
│   │   │   └── ... (10 albums total)
│   │   │
│   │   ├── posts/        # Post-related images
│   │   │   └── (various post images)
│   │   │
│   │   ├── components/   # Component graphics
│   │   │   └── (icon/decorator assets)
│   │   │
│   │   └── seo/          # SEO-related images
│   │       └── site--profile.jpeg
│   │
├── collections/          # Jekyll collections directory
│   ├── _posts/           # Published articles (30+ posts)
│   ├── _drafts/          # Draft posts (not published)
│   └── _ui-library/      # UI component showcase pages
│       ├── colours.html
│       ├── typography.html
│       ├── button.html
│       ├── figure.html
│       └── ... (14 pages total)
│
├── bin/                  # Utility scripts
│   ├── build            # Production build script
│   ├── dev              # Development server (livereload)
│   ├── setup            # Initial setup (installs dependencies)
│   ├── compose          # Create new posts/drafts
│   └── dimensions       # Python script to get image dimensions
│
├── _config.yml          # Jekyll configuration
├── Gemfile              # Ruby dependencies
├── Gemfile.lock         # Locked dependency versions
├── .tool-versions       # asdf version manager config (Ruby 3.2.3)
├── .gitignore          # Excludes _site, .jekyll-cache, vendor, etc.
│
├── Root-level pages     # HTML/Markdown pages
│   ├── index.html       # Home page (uses feed layout)
│   ├── writing.html     # Writing posts page
│   ├── photos.html      # Photo albums page
│   ├── speaking.html    # Speaking engagements page
│   ├── ui-library.html  # UI component showcase
│   ├── 404.html         # Not found error page
│   ├── 500.html         # Server error page
│   ├── cover.html       # Cover/splash page
│   └── coming-soon.html # Coming soon placeholder
│
└── README.md            # Project setup and documentation


2. Key Configuration Files

_config.yml

The main Jekyll configuration file (~150 lines) defines:

Site Identity:

Email & Contact:

Navigation & Routes:

SEO:

Collections:

Plugins:

Jekyll Compose Config:

Build Exclusions:

Gemfile

Minimal Ruby dependencies focused on GitHub Pages:


3. Layout Files in _layouts/

post.html - Blog/Article Posts

- Includes critical CSS and syntax highlighting
- Header with nav links
- Article with date, title, subtitle
- Post body content
- Footer with intro blurb included
- Used for: blog posts, photo albums
- Extends post.html structure
- Additional CSS for album layouts
- Conditionally renders photo gallery if `page.photos` exists
- Gallery items use figure component with dimensions
- Lazy-loaded images with data-width/height attributes
- Includes image-viewer modal for lightbox

basic.html - General Pages

- Minimal template for generic content
- Just head + content (no nav/footer)
- Used for: home, writing, photos, speaking, ui-library pages
- Allows pages to include their own nav/footer as needed

error.html - Error Pages (404/500)

- Special error page layout
- Different background color (--color-bg-error)
- Centered article with max-width: 85ch
- Used for 404.html and 500.html

4. Include Files in _includes/

Core Includes:

head.html - Standard <head> content

critical-css.html - Inlined CSS

image-viewer.html - Lightbox Modal (282 lines)

gallery-controls.html - Gallery Size Controller

post-sign-off.html - Simple footer signature marker

anonymous-analytics.html - Privacy-focused analytics snippet

Component System (_includes/components/)

A modular component library with 11 base components + design-system variants:

Structural Components:

Content Components:

UI Components:

Design System Components (_includes/components/design-system/)


5. Asset Organization

CSS Architecture

Design Tokens (tokens.css - ~200 lines):

Responsive Breakpoints:

Component-Based CSS:

View Transitions:

Fonts

Self-hosted fonts in assets/fonts/:

No Google Fonts or external dependencies - entirely self-hosted.

Images

Album Structure (assets/img/albums/):

Post Images (assets/img/posts/):

Component Images (assets/img/components/):

SEO Images (assets/img/seo/):

Image Optimization Pattern

From README:

  1. Export from Lightroom at 2048px longest edge, 240 DPI
  2. Optimize with ImageOptim (5% file reduction)
  3. Resample in Preview with “Resample image” checked (40% reduction)
  4. Lazy-load images with loading=”lazy” attribute
  5. Use responsive dimensions with data-width/height for gallery scaling

6. Content Organization in Collections/

Collections Structure

All content lives in collections/ directory (not root _posts, _drafts):

_posts/ (30+ published articles)

_drafts/ (unpublished)

_ui-library/ (component showcase)

Post Frontmatter

Blog Posts (type: post)

---
layout: post
title: "Article Title"
subtitle: "Brief description"
type: post
---

Photo Albums (type: album)

---
layout: album
title: "Album Title"
subtitle: "Description"
type: album
image: /assets/img/albums/[date]-[slug]/photo-1.jpeg
photos:
  - src: /assets/img/albums/.../photo-1.jpeg
    alt: "Descriptive alt text"
    width: 1365
    height: 2048
    caption: "Optional caption"
  - ... (more photos)
---

Speaking (type: presentation)

---
layout: post
title: "Talk Title"
subtitle: "Description"
type: presentation
---

Post/Page Filtering

Pages filter posts by type:


7. Build Scripts in bin/

bin/build (6 lines)

#!/bin/sh
set -e
JEKYLL_ENV=production bundle exec jekyll build

bin/dev (5 lines)

#!/bin/sh
set -e
bundle exec jekyll serve --livereload -H 0.0.0.0 "$@"

bin/setup (5 lines)

#!/bin/sh
set -e
asdf install
bundle install

bin/compose (5 lines)

#!/bin/sh
set -e
bundle exec jekyll "$@"

bin/dimensions (Python 3 script)


8. CSS/Styling Approach

Methodology: Design Tokens + Component CSS

Design Token System:

Color Palette:

Typography System:

Spacing System:

Performance Optimizations:

  1. Critical CSS inlined in head (prevents CLS)
  2. Font preloading with rel=”preload”
  3. Lazy image loading (loading=”lazy”)
  4. Responsive images with data-width/height for scaling
  5. View transitions with @view-transition
  6. Self-hosted fonts (no external requests)

Special CSS Features:

Wavy Links on hover/focus:

a:hover, a:focus {
  text-decoration-style: wavy;
}

Dark Mode Image Inversion:

.invert-image-dark-mode {
  filter: invert(1);
}

Applied conditionally to images in dark mode.

CSS Reset: Based on Josh Comeau’s modern CSS reset:


9. JavaScript Usage

Client-Side JavaScript Features

The site uses minimal, vanilla JavaScript - no frameworks or jQuery.

image-viewer.html (~280 lines, embedded script):

gallery-controls.html (~50 lines, embedded script):

Footer Component:

No External JavaScript

HTML5 Standards


10. Image Handling and Optimization Patterns

Documented Photo Preparation Workflow

From README - optimized for Fujifilm X-T1 JPEG output:

Export Phase (Lightroom):

Optimization Phase 1 - ImageOptim:

Optimization Phase 2 - Preview App:

Total Savings: 45% file size reduction from original export

Front-End Image Handling

Responsive Images:

<img 
  src="/path/to/image.jpeg"
  alt="Descriptive text"
  width="1365"
  height="2048"
  data-width="1365"
  data-height="2048"
  loading="lazy"
/>

Lazy Loading:

Dynamic Scaling (JavaScript):

Lightbox Pattern:

Responsive Image Markup:










<figure class="figure" >
  
  <img alt="" loading="lazy"   src=""    />
  

  
</figure>

Album Structure:

Image SEO


Development Workflow

Setup

bin/setup  # Install Ruby 3.2.3 + gem dependencies

Development

bin/dev              # Start livereload server on localhost:4000
bin/dev --drafts     # Include draft posts

Creating Content

bin/compose draft "Post Title"      # Create draft
bin/compose post "Post Title"       # Create published post
bin/compose publish _drafts/NAME    # Move draft to _posts
bin/dimensions path/to/album        # Get image dimensions

Build & Deploy

bin/build  # Production build to _site/
# Push to main branch → GitHub Actions → Deploy to GitHub Pages

Key Patterns & Best Practices

  1. Performance First
    • Critical CSS inlined
    • Fonts preloaded
    • Images lazy-loaded
    • View transitions for smooth navigation
    • No heavy dependencies
  2. Accessibility
    • Semantic HTML
    • ARIA labels
    • Keyboard navigation
    • High contrast support
    • Respects prefers-color-scheme
    • Respects prefers-contrast
  3. Modular Design
    • Reusable components (11 base components)
    • Design system documentation in UI library
    • CSS organized by component
    • Easy to maintain and extend
  4. Content-Focused
    • Clean typography with modular scale
    • Generous whitespace
    • No ads, minimal tracking
    • Image quality prioritized
  5. Responsive Design
    • Mobile-first CSS
    • Fluid scaling from 375px to 1440px+
    • Touch-friendly interactions
    • Viewport-aware layout (vi/vw units)
  6. Image Strategy
    • Batch optimization workflow
    • Lazy loading for performance
    • Alt text on all images
    • Responsive dimensions in frontmatter
    • Dynamic scaling UI for galleries

Tech Stack Summary

Component Technology
Static Site Generator Jekyll 4.x
Language Ruby 3.2.3
Package Manager Bundler
Version Manager asdf
Hosting GitHub Pages
CI/CD GitHub Actions
Fonts Self-hosted (Karla, YoungSerif)
JavaScript Vanilla ES6+
CSS Modern CSS (Grid, Flexbox, Custom Properties)
Plugins jekyll-feed, jekyll-seo-tag, jekyll-sitemap, jekyll-compose
Analytics Privacy-focused (server-side only)

Important Notes for AI Assistants