A static website for the Computational Multiphase Physics Laboratory, built with Jekyll and designed for hosting on GitHub Pages.
.
βββ _config.yml # Site-wide configuration
βββ _data # YAML data sources for data-driven pages
β βββ hero.yml # homepage hero (slides, copy)
β βββ news.yml # news feed (homepage + /news/ archive)
β βββ team.yml # team page (present, collaborators, alumni)
β βββ research_themes.yml # research themes block
βββ _includes # Reusable Jekyll fragments
β βββ footer-v2.html # site footer (v2)
β βββ theme-init.html # early theme persistence (avoids FOUC)
β βββ tokens-bridge.html # v2 token wiring
β βββ tokens-head.html # <head> token primer
βββ _layouts # Page templates
β βββ default.html # base layout used by most pages
β βββ research.html # research collection layout
β βββ teaching.html # teaching landing layout (sortable)
β βββ teaching-course.html # individual course layout
β βββ team.html # team page layout
β βββ join-us.html # join page layout
β βββ history.html # news history layout
βββ _research # Research project and publication entries
βββ _team # Team page (renders from _data/team.yml)
βββ _teaching # Teaching course entries and pages
βββ _join-us # Join Us page entries
βββ assets # Static files (images, css, js, logos, favicon)
β βββ css # Stylesheets
β β βββ tokens.css # v2 design tokens (single source of truth)
β β βββ bridge.css # maps legacy --color-* names to v2 tokens,
β β β # declares shared component primitives
β β βββ styles.css # legacy global stylesheet
β β βββ home.css # homepage v2 styles
β β βββ team-v2.css # team page v2 styles
β β βββ research-v2.css # research page v2 styles
β β βββ footer-v2.css # footer v2 styles
β β βββ about-layout.css # about-layout styles
β β βββ join-us.css # join page styles
β β βββ shared-news-history.css # news + history shared styles
β β βββ research.css # legacy research page styles
β β βββ team.css # legacy team page styles
β β βββ teaching.css # teaching page styles
β β βββ command-palette.css # βK command palette
β β βββ vendor.css # third-party CSS bundle
β βββ js # JavaScript files
β β βββ main.js # main JS (preloader, news loader, etc.)
β β βββ command-data.js # command palette data + behaviour
β β βββ platform-utils.js # platform detection / UI utilities
β β βββ shortcut-key.js # keyboard shortcut handling
β β βββ search_db.json # generated search index
β βββ favicon # Favicon files
β βββ images # Image assets (team, teaching, covers, β¦)
β βββ logos # Brand logos
βββ scripts # Build and utility scripts (see "Scripts Documentation")
βββ tests # Jest unit tests
βββ .github # CI workflows, issue/PR templates
βββ about.html # /about/ β JS redirect to /
βββ contact.html # /contact/ β JS redirect to /join
βββ join.html # /join/ β Join Us page
βββ index.html # / β Homepage
βββ News.md # /news/ feed legacy bullet list
βββ history.md # /history/ β full news archive
βββ Gemfile # Ruby dependencies
βββ _site # Generated site (ignored by Git)-
Quick Setup (Recommended)
For both fresh machines and existing development environments:
./scripts/setup.sh
This script will:
- Check for Ruby/Node.js and install them if missing (via rbenv/nvm)
- Install the repo-pinned Bundler version from
Gemfile.lock - Run a Ruby/Bundler preflight before installing dependencies
- Install all Ruby gems and npm packages
- Build the site and generate search database
- Install Git hooks for pre-commit checks (via Husky)
- Run validation tests
-
Manual Setup (Alternative)
Prerequisites:
- Ruby
3.2.2(matches.ruby-version) - Bundler
2.5.23(gem install bundler -v 2.5.23) - Node.js and npm (for linting and testing)
Install Dependencies:
# Ruby/Bundler preflight bash scripts/check-ruby-toolchain.sh # Ruby dependencies bundle _2.5.23_ install # JavaScript dependencies npm install
- Ruby
-
Build and Run
Quick Start (Recommended):
# Automatically finds available port and starts Jekyll with live reload ./scripts/deploy.shThis script will:
- Find an available port (4001-4999) to avoid conflicts
- Start Jekyll development server with live reload
- Display the local URL (e.g., http://localhost:4001)
- Auto-refresh browser on file changes
Manual Build (Alternative):
# Build the site and search database ./scripts/build.sh # Run local server bundle exec jekyll serve
- Visit http://localhost:4000 in the browser
- Changes require rebuilding with
./scripts/build.sh
-
Testing
# Run all tests npm test # Run tests with code coverage npm test -- --coverage # Run simple tests without Jest node scripts/simple-test.js # Run tests via wrapper script ./scripts/runTests.sh
-
Code Quality and Maintenance
# Run all linters and auto-fix issues ./scripts/lint-check.sh # Fix JavaScript line length issues (80 chars max) ./scripts/fix-js-line-length.sh # Convert single quotes to double quotes in JS files ./scripts/fix-quotes.sh # Fix script loading order (command-palette.js before command-data.js) ./scripts/fix-script-order.sh
-
Deployment
- Typically managed via GitHub Pages when merged/pushed to the main branch
- Local testing is recommended before committing changes
- Cloudflare cache is automatically purged on deployment via GitHub Actions
- Requires
CLOUDFLARE_ZONE_IDandCLOUDFLARE_API_TOKENsecrets in repository settings
- Requires
The homepage hero, news feed, team page, and research themes are
data-driven from YAML files in _data/. Edit the data file rather
than hand-writing HTML.
_data/hero.yml drives the hero section (slides, eyebrow, copy, video
poster). Add or reorder slides there; layout adapts automatically.
_data/news.yml: source of truth for the homepage feed and/news/archive. Each item hasdate,kind(paper|talk|people|move|award),title,meta,action_label,action_href.News.md: legacy short-form list, kept to 5 most recent items plus the pinned Durham announcement.history.md: full archive, never trimmed.- Years descend in
history.md; months descend within each year. Pinned items have no month/year header. - Use the
/add-newsslash command (in agent-driven workflows) or manually edit all three files together.
about.html(Jekyll permalink/about/): redirects to/via JS with a visible fallback link.contact.html(Jekyll permalink/contact/): redirects to/join.- Both mirror the same redirect pattern; keep them aligned if you change one.
The team page renders from _data/team.yml β three sections (present,
collaborators, alumni), each with name, role, photo, bio,
optional links. Photo files go under assets/images/team/ (1:1 crop,
used at --r-md radius). Bio is line-clamped per section (3 lines
present, 4 collaborators, unset alumni).
present:
- name: Member Name
role: Current position, Institution
photo: /assets/images/team/N.webp
bio: Brief research interest summary.
links:
- { kind: github, href: "https://github.com/username" }
- { kind: scholar, href: "https://scholar.google.com/citations?user=ID" }- Each paper should be added to
_research/index.mdin the following format:
<h3 id="NUMBER">[NUMBER] Author1, A., **Author2, B.**, & Author3, C. Title. _Journal_, Volume, Pages (Year).</h3>
<div class="tags"><span>Tag1</span><span>Tag2</span><span>Featured</span></div>
[](URL)
[](URL)
<iframe width="560" height="315" src="YOUTUBE_EMBED_URL" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>-
Important elements:
id="NUMBER": Unique ID for direct linking (e.g.,/research/#12)[NUMBER]: Paper number in square brackets- Author names: Use
<strong>for lab members - Journal names: Use italics with underscores
- Tags: Include relevant topic tags
- Badges: Use shields.io style badges for links
- Videos: Use YouTube embed code with privacy-enhanced mode
-
Featured Papers:
- Add
<span>Featured</span>to the tags to display the paper on the main page - Maximum 2 papers can be featured at any time
- Featured papers will automatically appear in the featured section of the homepage
- Add
-
Available Tags:
- Bubbles
- Drops
- Jets
- Sheets
- Non-Newtonian
- Coalescence
- Superamphiphobic-surfaces
- Impact forces
- Dissipative anomaly
- Soft-matter-singularities
- Featured
- (Add new tags as needed)
-
Common Badge Types:
[](URL) [](URL) [](URL) [](URL) [](https://blogs.comphy-lab.org)
-
Main Teaching Page
- Located at
_teaching/index.md - Lists all available courses
- Uses the
teachinglayout with sorting functionality
- Located at
-
Individual Course Pages
- Located in
_teaching/directory (e.g.,_teaching/2025-Basilisk101-Madrid.md) - Use the
teaching-courselayout (optimized for single course display without sorting functionality) - Follow this basic format:
--- layout: teaching-course title: "Course Title" permalink: /teaching/course-permalink --- <div class="course-image"> <img src="/path/to/banner-image.jpg" alt="Course Title" loading="lazy"> </div> # Course Title <div class="course-details"> <div class="course-details__item"> <h4><i class="fa-solid fa-calendar-days"></i> Dates</h4> <p>Date range</p> </div> <div class="course-details__item"> <h4><i class="fa-solid fa-location-dot"></i> Location</h4> <p>Location information</p> </div> </div> ## Course content...
- Located in
-
Course Images
- Store in
/assets/images/teaching/directory - Card images (600x400px): Used on the main teaching page
- Banner images (1200x400px): Used on individual course pages
- Follow naming convention:
[course-name]-[location].[extension]
- Store in
The website includes a powerful search feature that allows users to:
- Search through all content including titles, text, and tags
- Get instant search results with highlighted matching text
- See match percentage for each result
- Navigate directly to specific sections using anchor links
- Access search via keyboard shortcut (βK on Mac, ctrl+K on Windows) or by clicking the magnifying glass icon in the navigation
Search results are prioritized and filtered as follows:
- Team Members (highest priority)
- Direct matches in names
- Research interests and affiliations
- Social media links and profile information
- Teaching Content
- Course titles and descriptions
- Course details (dates, locations, prerequisites)
- Course schedules and topics
- Research Papers
- Titles and authors
- Tags and categories
- Blog Posts from blogs.comphy-lab.org
- Indexed directly from the GitHub repository (comphy-lab/CoMPhy-Lab-Blogs)
- Only indexes markdown files where the publish flag is not set to false
- Excludes todo markdown files (case-insensitive)
- Updated automatically every 12 hours via GitHub Actions
- Regular content (headings and paragraphs)
The search database is maintained in a separate repository comphy-lab/comphy-search and is automatically updated in this website via GitHub Actions. This approach:
- Centralizes search database generation in a dedicated repository
- Ensures consistent search functionality across the website
- Automatically updates the search database daily or when content changes
- Simplifies maintenance by separating search logic from the website code
Search results are prioritized using a two-step process:
-
Priority Field: Each entry in the search database has a priority field (1-5, with 1 being highest priority)
- Priority 1: Team members
- Priority 2: Featured papers and teaching content
- Priority 3: Regular papers and blog posts
- Priority 4-5: Other content
-
Relevance Scoring: Within each priority level, results are further ranked by relevance using:
- Title matches (70% weight)
- Content matches (20% weight)
- Tag and category matches (10% weight)
This ensures that higher-priority content (like team members) always appears before lower-priority content, even if the lower-priority content has a better text match.
The website includes a command palette feature that provides quick access to actions and navigation through keyboard shortcuts:
- Keyboard Shortcut: Access via βK on Mac, ctrl+K on Windows, or by clicking the terminal icon in the navigation
- Navigation Commands: Quickly navigate to any section of the website
- External Link Commands: Direct access to GitHub, Google Scholar, YouTube, and Bluesky
- Tool Commands: Scroll to top/bottom and other utility functions
- Context-Aware Commands: Additional commands appear based on current page
- Search Integration: Search is available separately via the βK shortcut
- Keyboard Navigation: Use arrow keys to navigate through commands, Enter to select, and Esc to close
Key features:
- Custom implementation with vanilla JavaScript for better control and performance
- Different visual styling from search to avoid confusion (indigo accent color vs blue for search)
- Grouping of commands by section for easy discoverability
- Shortcuts for common tasks (g h = go home, g r = go to research, etc.)
- Full keyboard navigation with arrow keys, Enter, and Escape
- Footer with keyboard shortcut hints for better usability
The command palette is built with:
- Custom vanilla JavaScript implementation
- Responsive and accessible design
- Integration with the site search database for content discovery
- Complete keyboard navigation support
Files:
/assets/js/command-data.js: Defines all available commands and search database integration/assets/css/command-palette.css: Styling for the command palette
Search behavior and features:
- Minimum query length: 3 characters
- Keyboard shortcut (βK / ctrl+K) opens a command palette style search interface on all pages
- Magnifying glass icon in navigation opens the search interface when clicked
- Search input in navigation shows the full "βK (search)" text by default
- Custom command palette implementation provides a modern command palette experience
- Search results appear instantly as you type
- Results are ranked by relevance and match percentage
The search functionality includes content from our external blog at blogs.comphy-lab.org:
- Blog posts are fetched and indexed in the comphy-search repository
- Each post's title and content are searchable
- Results link directly to the blog post
- Blog content is refreshed with each update to the search database
Research papers can be tagged with multiple topics. Tags are defined in the markdown files using the following format:
<div class="tags"><span>Tag1</span><span>Tag2</span></div>These tags are:
- Displayed with each paper
- Searchable through the search interface
- Used for filtering papers by topic
- Included in search match percentage calculations
_config.yml: Site-wide settings, collections, build options- Layout Templates in
_layouts/ - Partial Includes in
_includes/ - Assets in
assets/
The website supports both light and dark themes with an easy toggle switch in the header navigation:
-
Theme Preferences
- Automatically detects user's system preference (light/dark mode)
- Remembers user's manual selection using localStorage
- Maintains theme consistency across page navigation
-
Implementation Details
- Theme toggle button in the header of all layouts (default, team, research, teaching, teaching-course, join-us, history)
- Brand colours and theme variables live in
assets/css/tokens.css(single source of truth for the v2 design system) bridge.cssmaps legacy--color-*names onto the v2 tokens, so legacy stylesheets continue to work- Early theme persistence via
_includes/theme-init.htmlto avoid FOUC
-
Customizing Theme Colors
- Brand and theme tokens:
assets/css/tokens.css - Legacy variable bridge (kept for compatibility):
assets/css/bridge.css - Legacy globals:
assets/css/styles.css; legacy page styles inresearch.css,teaching.css,team.css - v2 page styles:
home.css,team-v2.css,research-v2.css,footer-v2.css - Theme is applied via the
data-themeattribute on the HTML element
- Brand and theme tokens:
- Color Scheme
- Gradient text (Red to Blue) for lab name
- Warm orange tint + blur for header
- Dark theme support with adjusted colors for better night viewing
- Theme Toggle
- Located in the header next to the Google Scholar icon
- Switches between light (default) and dark themes
- Uses SVG icons (moon/sun) with smooth transitions
- Persists user preference via localStorage
- Falls back to system preference when no user selection exists
- Typography
- Libre Baskerville, Open Sans
- Gradients for emphasis
- White text in dark theme for improved readability
- Favicon
- Located in
/assets/favicon/ - Multiple sizes for different devices and browsers
- Generated from CoMPhy Lab logo
- Located in
- Academicons 1.7.0 (SIL OFL 1.1, MIT)
- Font Awesome
- Fontello (Various licenses)
- Libre Baskerville (SIL Open Font License)
- Open Sans (Apache License 2.0)
| Workflow | Purpose |
|---|---|
jekyll.yml |
Builds and deploys the Jekyll site to GitHub Pages on push/PR to main. |
pages-build-deployment (GitHub-managed) |
Final deploy to GitHub's edge. |
update-search.yml |
Pulls the search index from comphy-lab/comphy-search daily at 04:00 UTC and on content changes. |
rebuild-on-search-update.yml |
Re-runs the build when the search index changes. |
content-rules-checks.yml |
Runs validate-content-rules.sh and the trigger-parity check. |
maintenance-regression-checks.yml |
Regression suite for housekeeping scripts (deploy, validators). |
teaching-content-checks.yml |
markdownlint + Prettier gate for _teaching/ pages. |
pr-hygiene-check.yml |
PR hygiene β blocks mixed dependency/security PRs. |
cloudflare-purge.yml |
Purges Cloudflare cache after deploy (needs CLOUDFLARE_ZONE_ID and CLOUDFLARE_API_TOKEN secrets). |
sync-org-profile-publications.yml |
Syncs publications to the org profile README. |
weekly-tests.yml |
Scheduled weekly smoke tests. |
Together these ensure the site builds, the search index stays fresh, and content invariants hold across PRs.
Blog content from blogs.comphy-lab.org is indexed in the comphy-search repository, sourced from comphy-lab/CoMPhy-Lab-Blogs.
Filtering rules:
- Only indexes markdown files where
publish: falseis not set in frontmatter. - Excludes any file with "todo" in the filename (case-insensitive).
Index refresh:
- Daily via GitHub Actions.
- On pushes that change markdown/HTML.
- Manually via the Actions tab.
The split-repo approach centralises search generation, reads raw
markdown from source, respects publish: flags, and avoids web-scraping
rate limits.
The scripts/ directory contains various utility scripts for development, testing, and maintenance:
-
setup.sh- Complete environment setup for both fresh and existing installations- Installs Ruby via rbenv and Node.js via nvm if not present
- Installs the repo-pinned Bundler version and runs a Ruby/Bundler preflight
- Installs all dependencies (Ruby gems and npm packages)
- Builds the site and runs validation tests
- Handles version conflicts gracefully
-
build.sh- Main build script- Builds the Jekyll site
- Generates the search database
- Updates SEO tags
- Creates filtered research pages by tags
-
deploy.sh- Local development server with smart port detection- Automatically finds available ports (4001-4999)
- Starts Jekyll development server with live reload
- Handles port conflicts gracefully
- Auto-refreshes browser on file changes
-
lint-check.sh- Code quality and formatting- Runs all linters (ESLint, Stylelint, markdownlint)
- Auto-fixes issues when possible
- Ensures code consistency across the project
-
check-ruby-toolchain.sh- Ruby/Bundler preflight- Verifies Ruby version matches
.ruby-version - Verifies the repo-pinned Bundler is available
- Used by
setup.sh; also runnable on its own when chasing "wrong Ruby" install errors
- Verifies Ruby version matches
-
validate-content-rules.sh- Content invariants- Checks
history.mdchronological ordering - Checks
_research/index.mdtag-markup format - Checks
CLAUDE.mdandREADME.mddon't reintroduce the deprecated baretagselement (replaced bydiv.tagsblocks) - Run by the
content-rulesCI workflow
- Checks
-
check-content-rules-trigger-parity.py- Workflow guard- Ensures the file paths that trigger the
content-rulesworkflow match the validated-file set, so the validator never silently skips a file by mistake
- Ensures the file paths that trigger the
-
fix-js-line-length.sh- JavaScript line length fixer- Ensures JavaScript files don't exceed 80 characters per line
- Automatically wraps long lines while preserving functionality
- Uses the Node.js script
fix-line-length.js
-
fix-quotes.sh- Quote standardization- Converts single quotes to double quotes in JavaScript files
- Platform-aware (handles macOS/Linux sed differences)
- Processes all JS files in
assets/js/
-
fix-script-order.sh- Script dependency ordering- Ensures
command-palette.jsloads beforecommand-data.js - Scans HTML files in
_layouts/and_includes/ - Automatically reorders script tags when needed
- Ensures
-
generate_seo_tags.rb- SEO optimization- Generates meta tags for better search engine visibility
- Creates Open Graph and Twitter Card metadata
- Processes all research papers and pages
-
generate_filtered_research.rb- Research filtering- Creates tag-based filtered pages for research papers
- Generates individual pages for each research tag
- Updates navigation and search functionality
sync_org_profile_publications.py- Org profile sync- Pulls the publications block from
_research/index.mdinto the GitHub org profile README (kept in_org_profile/) - Run periodically; not part of the regular build
- Pulls the publications block from
-
simple-test.js- Lightweight test runner- Runs basic tests without external dependencies
- Validates project structure and file existence
- Checks build outputs and syntax
- Provides colored terminal output
-
runTests.sh- Test wrapper- Simple wrapper for
npm test - Returns appropriate exit codes for CI/CD
- Displays success/failure messages
- Simple wrapper for
fix-line-length.js- Line breaking utility- Core logic for breaking long JavaScript lines
- Handles strings, comments, and code intelligently
- Preserves code functionality while improving readability
This project uses Jest for unit testing JavaScript functionality with comprehensive coverage:
- fix-line-length.js - Line breaking utilities and string processing
- command-data.js - Command palette functionality and search integration
- platform-utils.js - Platform detection and UI utilities
- shortcut-key.js - Keyboard shortcut handling
- teaching.js - Teaching page course sorting and filtering
- setup.js - Browser environment mocks and test setup
# Install dependencies
npm install
# Run all tests
npm test
# Run tests with code coverage
npm test -- --coverage
# Run tests in watch mode (re-runs on file changes)
npm test -- --watch
# Run a specific test file
npm test -- command-data.test.js
# Run simple validation tests (no dependencies)
node scripts/simple-test.js- Tests are located in the
/testsdirectory - Test files follow the naming pattern:
[module-name].test.js - Browser environment is mocked in
setup.jsfor DOM-dependent code - Tests use Jest's built-in assertions and mocking capabilities
- Coverage reports are generated in the
/coveragedirectory
- Unit Tests - Test individual functions and modules
- Integration Tests - Test component interactions
- Validation Tests - Check file structure and build outputs
- Mock Tests - Verify browser API mocks work correctly
-
Create a new test file in the
/testsdirectory -
Import the module or function to test:
const { functionName } = require("../path/to/module");
-
Structure tests using
describeanditblocks:describe("Module Name", () => { it("should do something specific", () => { expect(functionName(input)).toBe(expectedOutput); }); });
-
Run tests to ensure they pass
-
Check coverage with
npm test -- --coverage
- Maintain at least 80% code coverage
- Focus on critical path testing
- Mock external dependencies appropriately
- Test edge cases and error handling
The repository includes several issue templates to streamline the process of reporting problems or requesting changes:
- π Report a Bug: Use this template to report website issues or malfunctions
- π€ Add Team Member: Template for requesting addition of new team members
- π Add Publication: Template for adding new research publications
- β¨ Suggest Enhancement: For suggesting improvements or new features
To create a new issue:
- Click on one of the links above to use a template directly
- Or go to the Issues tab and click "New Issue"
- Choose the appropriate template
- Fill in the required information
- Submit the issue
When submitting changes, use the provided PR template which includes:
- Description of changes
- Type of change (bug fix, feature, content update, etc.)
- Testing checklist
- Related issues
- Screenshots (if applicable)
To submit a PR:
- Fork the repository
- Make your changes in a new branch
- Test changes locally
- Create a PR using the template
- Link any related issues
- Wait for review
- Use 2-space indentation across all files
- Follow DRY principles: reuse components, variables, and styles
- Add comments for complex logic, but keep code self-documenting
- Use semantic HTML elements
- Follow BEM naming convention for CSS classes (e.g.,
s-header__nav-list) - Keep content files in markdown format where possible
- Use CSS variables for colors and typography (defined in
:root) - Use responsive breakpoints at 1700px, 1300px, 900px, 768px, 500px
- Use
remunits for font sizes and spacing - Follow mobile-first approach for media queries
- Leverage CSS custom properties for theme switching
- Organize media queries by breakpoint for better maintainability
- Use standardized variable naming for consistent styling
- Use ES6+ features (arrow functions, const/let, template literals)
- Always include 'use strict' mode
- Use async/await for asynchronous operations
- Implement error handling with try/catch blocks
- Use camelCase for variable and function names
- Prefer event delegation for multiple similar elements
- Optimize images for web (compress to reduce file size)
- Follow naming convention:
[name]-[descriptor].[extension] - Include alt text for all images
The repository uses automated tools to ensure code quality and consistency:
-
Install dependencies (automatically includes pre-commit hooks):
./scripts/setup.sh
Or manually:
npm install npx husky install
This repository uses Husky and lint-staged to automatically check and format code before commits:
- JavaScript files: ESLint (with auto-fix) + Prettier
- CSS files: Prettier formatting
- Markdown files: markdownlint-cli2
- JSON/YAML files: Prettier formatting
When you commit, these checks run automatically on staged files only. If any issues are found that can't be auto-fixed, the commit will be blocked.
- JavaScript: ESLint with recommended rules
- Run manually:
npm run lint:js
- Run manually:
- CSS: Stylelint with standard configuration
- Run manually:
npm run lint:css
- Run manually:
- Markdown: markdownlint-cli2 for consistent documentation
- Run manually:
npm run lint:md
- Run manually:
- Code Formatting: Prettier
- Run manually:
npm run format
- Run manually:
- Tests: Jest
- Run manually:
npm test
- Run manually:
- Stage your changes:
git add . - Commit:
git commit -m "your message" - Pre-commit hooks automatically:
- Run ESLint on JavaScript files (auto-fixes when possible)
- Format all files with Prettier
- Check Markdown files with markdownlint
- If all checks pass, the commit proceeds
- If any check fails, the commit is blocked with error details
If needed, hooks can be bypassed with:
git commit --no-verifyThe site is mid-migration to a "v2" design system. New work composes from the v2 layer; legacy styles remain so older pages keep rendering.
-
Design tokens (
assets/css/tokens.css)- Single source of truth for the v2 layer
- Brand colours (
--c-brand-*,--c-accent-*) - Typography (
--t-*), spacing (--s-*), radii (--r-*) - Light theme by default; dark overrides under
[data-theme="dark"]
-
Bridge layer (
assets/css/bridge.css)- Loaded after
tokens.cssandstyles.cssso its:rootdeclarations win the cascade - Maps legacy
--color-*/--font-*/--shadow-*names onto v2 tokens β legacy pages pick up the new palette without rewrites - Declares shared component primitives reused across v2 pages
(panel, eyebrow, lede, chip, btn-ghost, paper-card, news-row,
team-tile,
.visually-hidden)
- Loaded after
-
v2 page stylesheets
home.css,team-v2.css,research-v2.css,footer-v2.css,about-layout.css,shared-news-history.css,join-us.css- Compose from bridge primitives; only add page-specific rules
-
Legacy stylesheets
styles.css,research.css,team.css,teaching.css- Kept for pages not yet migrated; bridged into the v2 token system
-
Consolidated media queries
- Breakpoints: 1700, 1300, 1200, 900, 768, 500 (mobile-first)
- Organised by breakpoint for cache-friendly delivery