Skip to content

Repository files navigation

Performance Engineering

A dark-themed, bilingual (EN/IT) single-page Jekyll site for a three-person performance engineering team in Venice. The "Proven Results" section profiles four real research codes — Fulgor, COSMICA, MiThyCA and Line-Laser INR — each with an animation built from inline SVG and metrics traceable to the published papers.

The site deliberately carries no brand name: page titles and descriptions come from _data/i18n.yml, and the header has no wordmark.


Requirements

Tool Version Needed for
Ruby 3.x Jekyll
Bundler 2.x gem install
Node.js 18+ Tailwind CLI

Node is only required if you intend to change the styles. The compiled stylesheet is committed, so a plain bundle install && bundle exec jekyll serve is enough to run the site.

Running locally

bundle install
bundle exec jekyll serve --livereload

The site is then at http://localhost:4000. Edits to .html, .md and _data/*.yml trigger a rebuild automatically.

Working on the styles

Tailwind compiles src/input.css into assets/css/main.css. Install once:

npm install

Then run the watcher in a second terminal, alongside jekyll serve:

npm run css:watch

For a one-off minified build:

npm run css

Commit assets/css/main.css whenever you change src/input.css — the deployment does not run Tailwind, so an uncommitted rebuild means the live site keeps the old styles.

Deploying

The output is a fully static _site/ directory — any static host will serve it.

GitHub Pages

Set url and baseurl in _config.yml first. For a project page served from https://<user>.github.io/<repo>/, baseurl must be "/<repo>"; for a user or custom-domain site leave it as "". Every internal link already runs through relative_url, so setting it correctly is all that is required.

Then add .github/workflows/pages.yml:

name: Deploy
on:
  push: { branches: [master] }
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ruby/setup-ruby@v1
        with: { ruby-version: '3.3', bundler-cache: true }
      - run: bundle exec jekyll build
        env: { JEKYLL_ENV: production }
      - uses: actions/upload-pages-artifact@v3
        with: { path: _site }
  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: github-pages
    steps:
      - uses: actions/deploy-pages@v4

Then set Settings → Pages → Source to GitHub Actions.

Netlify, Vercel, Cloudflare Pages

Build command bundle exec jekyll build, publish directory _site.

Any other host

JEKYLL_ENV=production bundle exec jekyll build

and upload the contents of _site/.


How the files are organised

.
├── _config.yml              Site metadata. `exclude` keeps the toolchain out of _site.
├── index.html               English page: front matter only (lang: en), includes home.html.
├── it/index.html            Italian page: same, with lang: it.
│
├── _layouts/
│   └── default.html         <head>, header, {{ content }}, footer, script tags.
│
├── _data/                   All copy lives here — edit these, not the markup.
│   ├── i18n.yml             UI strings per locale, plus the nav links.
│   ├── capabilities.yml     The four capability cards.
│   └── case_studies.yml     The four projects: copy, metrics, papers, animation.
│
├── _includes/
│   ├── home.html            The whole page body, shared by both locales.
│   ├── header.html          Sticky nav, language switcher, mobile disclosure.
│   ├── footer.html
│   ├── icons.html           Inline SVG sprite, selected by name.
│   ├── case-visual.html     Maps a `visual:` key to one of the four below.
│   ├── visual-dna.html      Fulgor — scrolling DNA double helix.
│   ├── visual-heliosphere.html  COSMICA — cosmic rays lensed around Earth.
│   ├── visual-histology.html    MiThyCA — slide scan with nuclei detection.
│   ├── visual-laser.html    Line-Laser INR — laser sweep, level-set closing.
│   └── visual-hero.html     Hero circuit board.
│
├── src/input.css            Tailwind source: @theme tokens + component layer.
├── assets/
│   ├── css/main.css         BUILD OUTPUT — generated, but committed.
│   └── js/
│       ├── carousel.js      Slides, arrows, autoplay. Progressive enhancement.
│       └── motion.js        Pauses SVG animation under prefers-reduced-motion.
│
├── package.json             Tailwind CLI + the css / css:watch scripts.
└── Gemfile                  jekyll + webrick.

Editing content

Almost nothing requires touching HTML.

  • Change a capability card — edit _data/capabilities.yml. Adding an entry adds a card; the grid reflows on its own. The icon: key must match a name in _includes/icons.html.
  • Change a project — edit _data/case_studies.yml. Each entry carries its copy, its two metrics, its source papers, and a visual: key naming the animation. Adding an entry adds a carousel slide and a pagination dot.
  • Add a new animation — drop _includes/visual-<name>.html in, register it in _includes/case-visual.html, then point a project's visual: at it. Use a square viewBox: the panel is 1:1 and the SVG is drawn with preserveAspectRatio="xMidYMid slice", so a non-square viewBox gets cropped.

Adding a language

Locales are separate pages, not a runtime switch, so the site stays static and the switcher works without JavaScript.

  1. Add a top-level block to _data/i18n.yml keyed by the language code. It must define every key the en block does — a missing key renders empty rather than falling back.
  2. Add <code> entries to the title, category, description and metric label maps in _data/capabilities.yml and _data/case_studies.yml.
  3. Create <code>/index.html with front matter lang: <code>, permalink: /<code>/, and a single {% include home.html %}.

The header switcher builds itself from the locales present in i18n.yml, so no markup change is needed. _layouts/default.html hardcodes the hreflang alternates — add the new one there.

The carousel

assets/js/carousel.js drives the slides, the side arrows, the autoplay cycle and its countdown ring. Three attributes on the carousel element in _includes/home.html tune it; remove data-autoplay to disable autoplay entirely.

Attribute Default Meaning
data-autoplay 8000 Dwell per slide, in ms
data-autoplay-manual 40000 Longer dwell after the visitor navigates by hand
data-progress-window 8000 How long before the hand-off the ring appears

The countdown ring wraps the next arrow. It only shows during the final data-progress-window of whichever dwell is running — so on the default cycle it is visible throughout, while after a manual navigation the 40s cycle stays quiet for its first 32s and the countdown never becomes a distraction.

Autoplay holds to these rules, worth preserving if you touch it:

  • it never starts when the visitor prefers reduced motion;
  • it pauses on hover, on keyboard focus inside the carousel, and while the browser tab is in the background;
  • manual navigation buys the reader the long dwell rather than stopping the cycle, so a slide is never pulled away mid-read but the carousel does eventually carry on.

Where the metrics come from

Each project shows two metrics, and both are documented by a comment directly beneath the value in _data/case_studies.yml — source table, raw numbers, and arithmetic.

First metric: an estimated annual saving. These are ours, not the papers'. Each is marked estimate: true, which renders an asterisk linking to a note under the carousel. The full derivation — instance types, list prices, assumed workload — lives only in the YAML comment and is deliberately not published: the figure is a headline, the assumptions behind it are for whoever maintains the numbers. Every one rests on a load-bearing assumption about workload scale; the comment always says which, because that is what a reader would challenge.

Second metric: whatever best characterises the project — query speedup for Fulgor, concurrent simulations for COSMICA, and so on.

Two labels mark weaker evidence in the comments:

  • OUR ESTIMATE / ESTIMATE — extrapolated beyond what the paper states.
  • READ FROM PLOT — measured off a figure rather than a printed table, so the value is approximate (Line-Laser INR).

Keep that discipline when adding projects: a number on the page should always be reproducible from the comment under it, and anything softer than a table should say so.

Conventions worth knowing

  • Asset URLs carry ?v={{ site.time }} so a rebuild busts stale caches.
  • Setting exclude in _config.yml overrides Jekyll's defaults entirely, so node_modules, src and package.json are listed explicitly. Removing them from that list will publish them.
  • The carousel degrades gracefully: the first slide ships visible and the rest carry hidden, so the page is readable with JavaScript disabled.

About

sharing website proof of concept

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages