General structure

  • Gave Claude some examples of project websites I like: Personal websites I like.
  • Clean grid of project cards, thumbnail + title + year + status. Responsive to hover over and clicking.
  • Self-contained static side.
  • Should be able to deploy as its own Netlify site.

Buildup

  • The data file, the only thing I need to edit to add projects: projects.js, index.html
  • Render script that turns the data into cards: render.js
  • Stylesheet: style.css
  • Netlify config: netlify.toml= Netlify’s configuration file. It’s optional for a plain static site, but it removes guesswork and saves clicking through settings in their dashboard.
  • Read me: README.md
  • In the folder, there’s also an images/ folder to drop thumbnails in.

To add a project

  1. Open project.js.
  2. Copy a block to the top, and fill it in:
  title: "My New Thing",
  year: "2026",
  status: "active",      // active | hiatus | archived | offline
  blurb: "One short sentence.",
  url: "https://the-project.com",
  image: "images/my-thing.png",  // or "" for a lettered placeholder
  tags: ["web", "design"],
}
 
  1. Each card shows a thumbnail, title, year, and a colour-coded status pill, an optional blurb, and tags. The whole card links out if you give it an URL.

Deploying to Netlify

See the README.mdfile.

  1. Drag the project folder onto app.netlify.com/drop.
  2. Or: Push the folder do its own Github repo, then in Netlify Add new site > Import an existing project. Build command empty, publish dir (already set in netlify.toml).

Style

All style things lin in style.css, e.g. background colour, font style, card shadows, etc.

If a Google font is used, it needs a link added to index.html. Good non-Google monospace fonts are e.g. SF Mono, Menlo, Consolas.

Dark mode has its own block with its own colours. If dark mode is not wanted, the entire block can be deleted.

Neo-brutalism: thick borders, hard offset shadows, monospace, flat bright colours. Colours: orange, teal, yellow Square corners, near black frame (#1a1a1a), hard black shadow. Cream background (#f3ece0), so the bright accent colours pop.

Thumbnails

Real project thumbnails will replace the colour blocks per-card; the flat colours only show when a project has no image. 16:10, landscape, is the default setting for thumbnails. Anything else will get cropped to that. Aim for 800 x 500 pixels for good sharpness. Keep under 200 KB.

  1. Drop the files in the images/ folder.
  2. Reference by filename in projects.js, e.g. image: "images/climate-notes.jpg".
  3. Filename tips: lowercase, no spaces (use hyphens), and be consistent — digital-garden.jpg, not Digital Garden.JPG. Netlify’s servers are case-sensitive, so Image.jpg referenced as image.jpg will 404 even though it works on your Mac.

To change to square thumbnails: Change --radius… no — change aspect-ratio: 16 / 10 to 1 / 1 in the .thumb rule (make them 800×800 then).

OR

Have images of wildly different shapes and don’t want cropping? I can switch object-fit: cover to contain (shows the whole image, letterboxed)

Some things I might want to tweak and how

  • Title colour — it’s near-black now. Change --title: var(--ink) to #fc955a if you instead want an orange heading.
  • All-caps — remove the text-transform: uppercase lines on .site-header h1 / .card-title if you’d rather keep normal casing.
  • The three placeholder colours — --accent-1/2/3. Add more and bump the % 3 in render.js if you ever want a longer rotation.

Sections

Photos

Tips

The key idea for a photo gallery: never make the visitor download full-resolution photos up front. A grid of full-size JPEGs is what makes photo pages crawl. Instead — show small thumbnails, and only load the big version when someone actually clicks a photo.

grid of small thumbnails (300-500 px wide, 30-80 KB)→ click one → it opens the full-size photo in a lightbox (dark overlay, arrow keys to move between photos). This is the standard photo-gallery UX and it’s the fastest: the page only ever loads little thumbnails; full photos load one at a time, on demand.

Lazy loadingloading="lazy" on each image means photos below the fold don’t load until you scroll near them. So a 100-photo gallery loads like a 10-photo one.

Use modern formats WebP, AVIF. 30-50% smaller than JPEG at the same quality. Export your thumbnails as WebP.

Reserve each image’s space (set width/height or aspect-ratio) so the page doesn’t jump around as photos pop in.

How to update

  1. photos.html- the gallery page
  2. photos.js- your photo list the only file to edit to add photos
  3. gallery.js- masonry tile-layout and lightbox logic
  4. gallery.css- gallery styling with the neo-brutalist style
  5. images/photos - add the photos there

Photos keep their real proportions (= masonry tile-layout), no cropping. 3 columns. Lightbox = click any photo for a full-size view. Arrow keys or on-screen arrows to move, Esc or click outside to close.

To add own photos:

  1. Drop files into images/photos/(lowercase-hyphenated names).
  2. Add a line to photos.js.:
{ file: "images/photos/my-shot.jpg", caption: "My shot", w: 1600, h: 1000 },

(w/h are optional but recommended, they stop the layout jumping as photos load)

At the top of the gallery.js, there’s

const USE_NETLIFY_IMAGES = false;

Leave it false while previewing locally. Once your site is live on Netlify, set it to true — the gallery will then auto-serve small, compressed WebP thumbnails (and larger versions in the lightbox) via Netlify’s built-in Image CDN, so you can upload full-resolution photos without making thumbnails by hand. It works on same-origin images with no extra netlify.toml config.

Convert to WebP WebP at ~2000px/quality-82 is a good recipe for any new photo. Ask Claude to convert whenever I add one.