principles-design-site

Private repository powering principles.design. The site is built with Jekyll and deployed via GitHub Pages.

Architecture

This project uses a two-repo setup:

Repo Visibility Purpose
benbrignell/principles-design-site Private Full site code, layouts, styles, config. Serves GitHub Pages.
benbrignell/principles.design Public Examples only (.md files). Accepts community contributions.

The public repo is included as a git submodule at _examples/. Jekyll reads the example .md files from there and builds them as a collection.

Prerequisites

  • Ruby (version compatible with GitHub Pages)
  • Bundler (gem install bundler)
  • Git

Getting started

# Clone the repo
git clone https://github.com/benbrignell/principles-design-site.git
cd principles-design-site

# Initialise the examples submodule
git submodule update --init

# Install dependencies
bundle install

# Run locally
./scripts/dev.sh

The site will be available at http://localhost:4000.

For direct Jekyll commands (if submodule is already initialized):

bundle exec jekyll serve

Branches

Branch Purpose
master Live site. Deployed automatically via GitHub Pages.
backup-master Safety snapshot of master taken during repo split (Feb 2026).
submodule-examples Examples loaded via submodule instead of regular files.
field-guide Field guide product pages and layouts.

Working with the examples submodule

Switching branches

The submodule must be deinitialized before switching branches, then reinitialized after:

git submodule deinit _examples
git checkout <branch>
git submodule update --init

After cloning

The submodule won’t be populated automatically. Run:

git submodule update --init

Updating examples to latest

When new examples are merged into the public repo:

cd _examples
git pull origin master
cd ..
git add _examples
git commit -m "Update examples submodule"
git push

Editing an example

Work inside the submodule directory, test with the full site, then push changes back to the public repo:

# Edit the file
vim _examples/example-name.md

# Test locally
bundle exec jekyll serve

# Push the change to the public repo
cd _examples
git add example-name.md
git commit -m "Fix example"
git push origin master

# Update the submodule reference in the private repo
cd ..
git add _examples
git commit -m "Update examples submodule"
git push

Adding a new example

Same workflow as editing. Create a new .md file in _examples/ with the required front matter:

---
title: Example Title
author: Author Name
overview: |
  Brief description of the principles.
link: https://example.com
principles:
- principle: First Principle
  summary: |
    Explanation of the principle.
tags: [tag1, tag2]
---

Community contributions

Contributors submit PRs to the public repo (benbrignell/principles.design). To test a contribution locally:

cd _examples
git fetch origin
git checkout origin/pr-branch-name
cd ..
bundle exec jekyll serve
# Review at localhost:4000

If it looks good, merge the PR on GitHub, then update the submodule reference.

GitHub Pages deployment

  • Source: master branch, root directory
  • Custom domain: principles.design
  • CNAME file: Must exist in the repo root with principles.design
  • Pushes to master trigger an automatic build and deploy

If something breaks

  1. Check the Actions tab on GitHub for build errors
  2. To rollback: git revert HEAD and push, or reset to backup-master

Key files

Path Description
_config.yml Jekyll configuration, collections, permalinks
_examples/ Submodule — example .md files from public repo
_articles/ Articles/writing content
_layouts/ Page templates (home, example, page, etc.)
_includes/ Reusable components (header, footer, nav, etc.)
_pages/ Static pages (about, contribute, book, etc.)
_includes/css/ CSS design system (tokens, components, utilities)
assets/js/ JavaScript (e.g. cookie-free ConvertKit form handler)
Gemfile Ruby dependencies (github-pages, jekyll-last-modified-at)
CNAME Custom domain for GitHub Pages

Collections

Defined in _config.yml:

  • examples — Design principle examples. Output to /examples/:name. Layout: example.
  • articles — Writing/articles. Output to /articles/:name. Layout: page.
  • components — Internal, not output.

Design System

CSS uses plain custom properties (no Sass). See:

  • DESIGN-SYSTEM.md — Full documentation of tokens, typography, spacing, components
  • /design-system/ — Live documentation page with visual examples
  • _includes/css/tokens.css — All design tokens (colors, typography, spacing)

CSS Architecture

_includes/css/
├── fonts.css        # @font-face (if using custom font)
├── tokens.css       # Design tokens
├── reset.css        # Modern CSS reset
├── typography.css   # Type scale, vertical rhythm
├── layout.css       # Grid, wrapper, content areas
├── utilities.css    # Spacing, visibility helpers
└── components/      # Header, footer, tile, forms, etc.

CSS Loading

  • Development: <link> to /assets/css/site.css (concatenated via Liquid)
  • Production: All CSS inlined into <style> block (zero HTTP requests)

Performance Goals

  • Target payload: 30-40KB per page
  • No custom fonts on master (adds ~100-300KB)
  • font-update branch has Inter font if needed later

Notes

  • The public repo (principles.design) contains only example .md files, README.md, and LICENSE.txt. It has no Jekyll config, layouts, or styles.
  • The contribute-url in _config.yml still points to the public repo for community contributions.
  • The site uses jekyll-seo-tag for meta tags and Open Graph data.
  • Email signup forms use a cookie-free ConvertKit implementation (assets/js/kit-signup.js).
  • The _sass/ directory is legacy and no longer used.