Personal/professional homepage for Dr Stuart Grey — Senior Lecturer in Engineering Systems Design at the University of Glasgow and founder of Student Voice AI. Built with Eleventy 3 and Tailwind CSS 4, hosted on Netlify.
Live site: stugrey.com
@11ty/eleventy)tailwind.css setup with @import "tailwindcss")@tailwindcss/typography (used via @plugin directive in tailwind.css).html layouts/includes, .md content/admin/)_redirects to avoid ad blockers).nvmrc)master branch deploys)npm install # install deps
npm run dev # Eleventy serve + Tailwind watch in parallel
npm run build:css # one-off Tailwind build to css/style.css
npm run dev:css # Tailwind watch only
npm run eleventy:serve # Eleventy dev server only
npm-run-all orchestrates parallel dev processes.
.eleventy.js # Eleventy config — passthrough copies, dir settings
tailwind.css # Tailwind v4 entry point (@import, @source, @plugin)
tailwind.config.js # Legacy config (content paths, typography plugin) — may be unused with v4
purgecss.config.js # Legacy PurgeCSS config — likely unused with Tailwind v4
style.css # Legacy full Tailwind build (1.8 MB) — pre-v4 artifact
index.html # Homepage (Liquid template, not in any collection)
_data/site.json # Global data: { "title": "Dr Stuart Grey" }
_includes/ # Partials: head.html, header.html, footer.html
_layouts/ # Layouts: post, page, default, publications, articles, engagement, compress
_posts/ # All content as Markdown files (~77 posts)
publications/ # Section index (index.md → publications layout)
articles/ # Section index (index.md → articles layout)
engagement/ # Section index (index.md → engagement layout)
Images/ # Media organised by date: Images/YYYY_MM_DD_event_name/
css/style.css # Tailwind build output (git-tracked, generated by build:css)
static/_redirects # Netlify redirects (Plausible proxy, short URL /3092)
admin/ # Netlify CMS (config.yml + index.html)
documents/ # PDFs (handouts, whitepapers)
templates/ # Scaffolding templates (article.md) for new posts
_site/ # Eleventy build output (gitignored)
All content lives in _posts/ as Markdown files. The tags frontmatter field determines which Eleventy collection a post belongs to, and therefore which section it appears in:
| Tag | Collection | Section page | Layout used |
|---|---|---|---|
publication |
collections.publication |
/publications/ |
publications.html |
article |
collections.article |
/articles/ |
articles.html |
engagement |
collections.engagement |
/engagement/ |
engagement.html |
Some older posts have no tag — they still render via the post layout but don't appear in section listings.
---
layout: post # always "post" for content pages
title: "Post Title"
date: YYYY-MM-DD HH:MM:SS # or ISO 8601 with T/Z
description: "One-line summary." # shown in listing pages
tags: article # one of: article, engagement, publication
permalink: "/2026/03/29/CLAUDE/index.html"
# Optional fields:
authors: "Name and Name" # publications only
journal: "Journal Name" # publications only
social_image: "YYYY_MM_DD/image.png" # relative to /Images/
overview: "OG/Twitter description" # used in meta tags
sidenote: '<img src="...">' # thumbnail HTML for listing pages
categories: # present but typically empty/null
---
Files follow the pattern: YYYY-MM-DD-slug-with-dashes.md
All posts use: /YYYY/MM/DD/slug/index.html — generated via the Liquid permalink in frontmatter.
post.html — Individual content pages. Uses prose lg:prose-xl for Tailwind Typography styling.publications.html — Lists collections.publication in reverse chronological order. Shows title, authors, journal, date.articles.html — Lists collections.article in reverse chronological order. Shows title, date, description, sidenote thumbnail.engagement.html — Lists collections.engagement chronologically (not reversed). Shows title, date, description, sidenote thumbnail.default.html — Paginated post listing (appears to be a leftover from migration, uses paginator which is a Jekyll feature).page.html — Generic page layout.compress.html — HTML compression layout (Jekyll-era artifact, currently not referenced).All layouts include head.html → header.html → content → footer.html.
Dr Stuart Grey → "Dr Stuart Grey" (from _data/site.json)site.json — resolves to empty string, which works for root-level deployment on Netlify.Configured in .eleventy.js:
Images/ — media filescss/ — compiled Tailwind CSSdocuments/ — PDFsadmin/ — Netlify CMSstatic/ contents → site root (e.g., _redirects)Images/YYYY_MM_DD_event_name/resized/ subdirectoriesthumbnails/ subdirectoriesresize_image_scripts.sh — ImageMagick-based script for batch resizing (1000px wide for resized, 400px for thumbnails)/Images/path/to/image.jpgSee .impeccable.md for full design guidelines. Key points:
Avenir, Montserrat, Corbel, 'URW Gothic', source-sans-pro, sans-serifCharter, 'Bitstream Charter', 'Sitka Text', Cambria, serifcss/style.css file is a generated artifact from npm run build:css — do not edit directly; modify tailwind.css or HTML/MD files instead.style.css (1.8 MB) is a legacy file from before the Tailwind v4 migration.footer.html currently contains only commented-out Google Analytics code — effectively empty.index.html) uses eleventyExcludeFromCollections: true to keep it out of post listings.admin/index.html and referenced in index.html for CMS login flow.