update design

This commit is contained in:
John Gatward committed 2026-10-08 11:59:24 +01:00
1 parent a8fde951a6
commit 874ea1f8bf
10 files changed
+1266 -835

No files matched your search

+312 -240
View File
@@ -11,6 +11,13 @@
<meta name="theme-color" content="#1e1e2e" />
<link rel="icon" href="icons/favicon.ico" sizes="any" />
<link rel="apple-touch-icon" href="icons/apple-touch-icon.png" />
<link
rel="preload"
href="fonts/geist-variable.ttf"
as="font"
type="font/ttf"
crossorigin
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,700;1,400&family=Fraunces:ital,opsz,wght@0,9..144,300;0,9..144,600;1,9..144,300&display=swap"
@@ -30,56 +37,61 @@
<li><a href="#projects">projects</a></li>
<li><a href="#contact">contact</a></li>
</ul>
<details class="nav-menu">
<summary>Menu</summary>
<ul class="mobile-nav-links">
<li><a href="#about">about</a></li>
<li><a href="#skills">skills</a></li>
<li><a href="#projects">projects</a></li>
<li><a href="#contact">contact</a></li>
</ul>
</details>
</nav>
<main id="main-content" tabindex="-1">
<!-- ─── Hero ─────────────────────────────────────────────────── -->
<section id="hero">
<p class="hero-eyebrow">// havox.org - v4</p>
<h1 class="hero-name">John <em>Gatward</em></h1>
<p class="hero-subtitle">Software Engineer</p>
<p class="hero-desc">
<span class="hero-by-line"
><span class="hero-by">Backend engineer</span
><span class="hero-by-role">by trade</span></span
>
<span class="hero-by-line"
><span class="hero-by">Developer enthusiast</span
><span class="hero-by-role">by curiosity</span></span
>
<span class="hero-by-line"
><span class="hero-by">Unofficial family cloud engineer</span
><span class="hero-by-role">by necessity</span></span
>
</p>
<div class="hero-links">
<a href="#projects" class="btn btn-primary">View projects</a>
<a href="#contact" class="btn btn-ghost">Contact me</a>
<div class="hero-copy">
<h1 class="hero-name">John <em>Gatward</em></h1>
<p class="hero-subtitle">Backend engineer. Curious builder.</p>
<p class="hero-desc">
I build services, interactive experiments, and things my family
actually uses.
</p>
<div class="hero-links">
<a href="#projects" class="btn btn-primary">View projects</a>
<a href="#contact" class="btn btn-ghost">Contact me</a>
</div>
</div>
</section>
<div class="divider"></div>
<!-- ─── About ─────────────────────────────────────────────────── -->
<section id="about" class="about-section">
<div class="reveal">
<p class="section-label">about</p>
<h2 class="section-heading">Havox & <em>me</em></h2>
<h2 class="section-heading">Havox &amp; me</h2>
</div>
<div class="about-lead reveal">
<img
class="about-portrait"
src="images/headshot.jpeg"
alt="John Gatward"
width="800"
height="800"
loading="lazy"
decoding="async"
/>
<p class="about-intro">
Havox started in 2017 as a place to dump whatever projects I had
written. Four redesigns and several dead domains later, it's still
going. Less a portfolio, more a scrapbook.
</p>
</div>
<div class="about-columns">
<!-- Bio blocks -->
<div class="about-grid reveal" style="transition-delay: 0.05s">
<div class="about-details reveal" style="transition-delay: 0.05s">
<div class="about-block">
<p>
Havox started in 2017 as a place to dump whatever projects I had
written. Four redesigns and several dead domains later, it's
still going. Less a portfolio, more a scrapbook.
</p>
</div>
<div class="about-block">
<span class="about-block-tag tag tag-blue">day job</span>
<h3>Day job</h3>
<p>
Backend engineer at <strong>Sainsbury's</strong> Supply Chain
&amp; Logistics. It's good fun.
@@ -87,7 +99,7 @@
</div>
<div class="about-block">
<span class="about-block-tag tag tag-teal">dev</span>
<h3>Always learning</h3>
<p>
Fascinated with new languages, frameworks, and shiny tech I
probably don’t need. Constantly learning just enough to build
@@ -96,7 +108,7 @@
</div>
<div class="about-block">
<span class="about-block-tag tag tag-yellow">linux</span>
<h3>Off the clock</h3>
<p>
Long-time Linux user and distro-hopper. Self-hosted server
running 24/7 for friends and family who didn't ask for it but
@@ -107,7 +119,7 @@
<!-- Version timeline -->
<div class="reveal" style="transition-delay: 0.15s">
<p class="section-label">version history</p>
<h3 class="about-subheading">Version history</h3>
<div class="version-timeline">
<div class="version-item">
<div class="v-dot v-dot--current"></div>
@@ -177,13 +189,10 @@
</div>
</section>
<div class="divider"></div>
<!-- ─── Skills ─────────────────────────────────────────────────── -->
<section id="skills">
<p class="section-label reveal">skills</p>
<h2 class="section-heading reveal" style="transition-delay: 0.05s">
What I <em>know</em>
What I know
</h2>
<div class="skills-grid">
@@ -233,7 +242,7 @@
<span class="skill-card-icon">
<img
src="icons/docker-logo.svg"
alt="React"
alt="Docker"
class="skill-card-icon-image"
/>
</span>
@@ -249,14 +258,11 @@
<span class="tag tag-peach">Wireguard</span>
</div>
</div>
<div
class="skill-card skill-card--wide reveal"
style="transition-delay: 0.24s"
>
<div class="skill-card reveal" style="transition-delay: 0.24s">
<span class="skill-card-icon">
<img
src="icons/haskell-logo.svg"
alt="React"
alt="Haskell"
class="skill-card-icon-image"
/>
</span>
@@ -277,13 +283,10 @@
</div>
</section>
<div class="divider"></div>
<!-- ─── Projects ──────────────────────────────────────────────── -->
<section id="projects">
<p class="section-label reveal">projects</p>
<h2 class="section-heading reveal" style="transition-delay: 0.05s">
Things I <em>built</em>
Things I built
</h2>
<p class="section-intro reveal" style="transition-delay: 0.1s">
A timeline of my projects and an overview of my journey as a
@@ -291,131 +294,216 @@
recreate.
</p>
<div class="projects-subheading reveal" style="transition-delay: 0.12s">
<span>Featured projects</span>
</div>
<h3 class="projects-subheading reveal" style="transition-delay: 0.12s">
Featured projects
</h3>
<div
class="card-grid card-grid--featured reveal"
style="transition-delay: 0.14s"
>
<article
class="card card-link"
data-href="https://wordlesolver.umbra.mom"
>
<span class="card-date">9 Feb 2025</span>
<span class="project-status project-status--active"
>Active development</span
>
<span class="card-title">Wordle Solver</span>
<span class="card-desc"
>Built after one too many missed 3-guess games. Now it plays
marginally better than me. Uses information theory to recommend
the next best guess.</span
>
<span class="card-source">
Source code:
<a
href="https://github.com/jayo60013/wordle-solver-api"
target="_blank"
rel="noopener noreferrer"
>API</a
<article class="card featured-card">
<img
class="project-preview"
src="images/wordle-solver-preview.webp"
alt="Wordle Solver showing a colour-coded guess and suggested next words"
width="1200"
height="800"
loading="lazy"
decoding="async"
/>
<div class="featured-card-content">
<a class="card-title" href="https://wordlesolver.umbra.mom">
Wordle Solver
<span class="card-action">Open solver (external)</span>
</a>
<span class="card-desc"
>Built after one too many missed 3-guess games. Now it plays
marginally better than me. Uses information theory to recommend
the next best guess.</span
>
·
<a
href="https://github.com/jayo60013/wordle-solver-frontend"
target="_blank"
rel="noopener noreferrer"
>Frontend</a
>
</span>
<span class="tag-row">
<span class="tag tag-yellow">Rust</span>
<span class="tag tag-teal">React</span>
<span class="tag tag-peach">TypeScript</span>
</span>
<div class="project-meta">
<span class="card-date">9 Feb 2025</span>
<span class="project-status project-status--active"
>Active development</span
>
</div>
<span class="tag-row">
<span class="tag tag-yellow">Rust</span>
<span class="tag tag-teal">React</span>
<span class="tag tag-peach">TypeScript</span>
</span>
<span class="card-source">
Source code:
<a
href="https://github.com/jayo60013/wordle-solver-api"
target="_blank"
rel="noopener noreferrer"
>API</a
>
·
<a
href="https://github.com/jayo60013/wordle-solver-frontend"
target="_blank"
rel="noopener noreferrer"
>Frontend</a
>
</span>
</div>
</article>
<article
class="card card-link"
data-href="https://crackthequote.umbra.mom"
>
<span class="card-date">13 Apr 2024</span>
<span class="project-status project-status--active"
>Active development</span
>
<span class="card-title">Crack the Quote</span>
<span class="card-desc"
>A substitution-cipher puzzle game with a daily challenge. Built
for me and my family to play after getting bored with NYT
games.</span
>
<span class="card-source">
Source code:
<a
href="https://github.com/jayo60013/crack-the-quote-api"
target="_blank"
rel="noopener noreferrer"
>API</a
<article class="card featured-card">
<img
class="project-preview"
src="images/crack-the-quote-preview.webp"
alt="Crack the Quote showing the daily cipher puzzle and letter controls"
width="1200"
height="800"
loading="lazy"
decoding="async"
/>
<div class="featured-card-content">
<a class="card-title" href="https://crackthequote.umbra.mom">
Crack the Quote
<span class="card-action">Play game (external)</span>
</a>
<span class="card-desc"
>A substitution-cipher puzzle game with a daily challenge. Built
for me and my family to play after getting bored with NYT
games.</span
>
</span>
<span class="tag-row">
<span class="tag tag-yellow">Rust</span>
<span class="tag tag-teal">React</span>
<span class="tag tag-green">JavaScript</span>
</span>
<div class="project-meta">
<span class="card-date">13 Apr 2024</span>
<span class="project-status project-status--active"
>Active development</span
>
</div>
<span class="tag-row">
<span class="tag tag-yellow">Rust</span>
<span class="tag tag-teal">React</span>
<span class="tag tag-green">JavaScript</span>
</span>
<span class="card-source">
Source code:
<a
href="https://github.com/jayo60013/crack-the-quote-api"
target="_blank"
rel="noopener noreferrer"
>API</a
>
</span>
</div>
</article>
</div>
<div class="projects-subheading reveal" style="transition-delay: 0.16s">
<span>All projects</span>
</div>
<h3 class="projects-subheading reveal" style="transition-delay: 0.16s">
All projects
</h3>
<fieldset
class="project-filters reveal"
style="transition-delay: 0.18s"
aria-label="Filter projects by tech stack"
hidden
>
<button type="button" class="filter-chip active" data-filter="all">
<button
type="button"
class="filter-chip active"
data-filter="all"
aria-pressed="true"
>
All
</button>
<button type="button" class="filter-chip" data-filter="javascript">
<button
type="button"
class="filter-chip"
data-filter="javascript"
aria-pressed="false"
>
JavaScript
</button>
<button type="button" class="filter-chip" data-filter="python">
<button
type="button"
class="filter-chip"
data-filter="python"
aria-pressed="false"
>
Python
</button>
<button type="button" class="filter-chip" data-filter="rust">
<button
type="button"
class="filter-chip"
data-filter="rust"
aria-pressed="false"
>
Rust
</button>
<button type="button" class="filter-chip" data-filter="react">
<button
type="button"
class="filter-chip"
data-filter="react"
aria-pressed="false"
>
React
</button>
<button type="button" class="filter-chip" data-filter="webassembly">
<button
type="button"
class="filter-chip"
data-filter="webassembly"
aria-pressed="false"
>
WebAssembly
</button>
<button type="button" class="filter-chip" data-filter="p5">
<button
type="button"
class="filter-chip"
data-filter="p5"
aria-pressed="false"
>
p5.js
</button>
<button type="button" class="filter-chip" data-filter="zig">
<button
type="button"
class="filter-chip"
data-filter="zig"
aria-pressed="false"
>
Zig
</button>
<button type="button" class="filter-chip" data-filter="cpp">
<button
type="button"
class="filter-chip"
data-filter="cpp"
aria-pressed="false"
>
C / C++
</button>
</fieldset>
<p
id="project-count"
class="project-count"
role="status"
aria-atomic="true"
hidden
></p>
<div id="projects-empty" class="projects-empty" hidden>
<h3>No projects match this filter</h3>
<p>Choose another technology or browse all projects.</p>
<button id="projects-reset" class="btn btn-ghost" type="button">
Show all projects
</button>
</div>
<div
id="project-grid"
class="card-grid reveal"
style="transition-delay: 0.2s"
>
<article
class="card project-card card-link"
data-tech="python"
data-href="https://pubquiz.umbra.mom"
>
<article class="card project-card" data-tech="python">
<span class="card-date">03 Apr 2025</span>
<span class="card-title">Pub Quiz Dashboard</span>
<a class="card-title" href="https://pubquiz.umbra.mom">
Pub Quiz Dashboard
<span class="card-action">Open dashboard (external)</span>
</a>
<span class="card-desc"
>A Python dashboard to track our local pub quiz
performances.</span
@@ -424,13 +512,12 @@
<span class="tag tag-red">Python</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="cpp webassembly"
data-href="projects/thin_ice/thin_ice.html"
>
<article class="card project-card" data-tech="cpp webassembly">
<span class="card-date">14 Nov 2024</span>
<span class="card-title">Thin Ice</span>
<a class="card-title" href="projects/thin_ice/thin_ice.html">
Thin Ice
<span class="card-action">Play game</span>
</a>
<span class="card-desc"
>A small browser tile game inspired by one I played growing
up.</span
@@ -441,13 +528,12 @@
<span class="tag tag-peach">Raylib</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="zig webassembly"
data-href="projects/tsp/index.html"
>
<article class="card project-card" data-tech="zig webassembly">
<span class="card-date">20 Mar 2024</span>
<span class="card-title">Travelling Salesman Problem</span>
<a class="card-title" href="projects/tsp/index.html">
Travelling Salesman Problem
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>A nearest-neighbor + 2-opt visualiser. Wanted to revisit one of
my first projects with an optimised tech stack and
@@ -459,13 +545,12 @@
<span class="tag tag-teal">WebAssembly</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="rust"
data-href="projects/flocking/index.html"
>
<article class="card project-card" data-tech="rust">
<span class="card-date">31 Jan 2024</span>
<span class="card-title">Flocking</span>
<a class="card-title" href="projects/flocking/index.html">
Flocking
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>Rewrote the project from Go to Rust, compiling it to WebAssembly.
Was fun being able to use DOM controls to affect the
@@ -476,16 +561,15 @@
<span class="tag tag-peach">Raylib</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript"
data-href="https://samstoreymusic.com"
>
<article class="card project-card" data-tech="javascript">
<span class="card-date">1 Nov 2023</span>
<span class="project-status project-status--active"
>Active development</span
>
<span class="card-title">samstoreymusic.com</span>
<a class="card-title" href="https://samstoreymusic.com">
samstoreymusic.com
<span class="card-action">Visit website (external)</span>
</a>
<span class="card-desc"
>A website design and build for a friend working in music. Saving
him the hosting fees :)</span
@@ -495,13 +579,12 @@
<span class="tag tag-green">JavaScript</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript react"
data-href="projects/cellular_automata/index.html"
>
<article class="card project-card" data-tech="javascript react">
<span class="card-date">21 Jul 2023</span>
<span class="card-title">Game of Life</span>
<a class="card-title" href="projects/cellular_automata/index.html">
Game of Life
<span class="card-action">Open simulator</span>
</a>
<span class="card-desc"
>After building Conway's Game of Life in p5.js as one of my first
projects, I expanded it into a generic automata simulator.</span
@@ -511,13 +594,12 @@
<span class="tag tag-green">JavaScript</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="cpp webassembly"
data-href="projects/percolation/index.html"
>
<article class="card project-card" data-tech="cpp webassembly">
<span class="card-date">5 Feb 2022</span>
<span class="card-title">Percolation</span>
<a class="card-title" href="projects/percolation/index.html">
Percolation
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>Watched a brilliant video by
<a
@@ -534,13 +616,12 @@
<span class="tag tag-teal">WebAssembly</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript p5"
data-href="projects/cubic_bezier_curve/index.html"
>
<article class="card project-card" data-tech="javascript p5">
<span class="card-date">1 Oct 2021</span>
<span class="card-title">Drawing Bézier curves</span>
<a class="card-title" href="projects/cubic_bezier_curve/index.html">
Drawing Bézier curves
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>An interactive animation for how cubic Bézier curves are
constructed. Inspired by this beautiful video by
@@ -556,13 +637,12 @@
<span class="tag tag-red">p5.js</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript p5"
data-href="projects/marching_squares.html"
>
<article class="card project-card" data-tech="javascript p5">
<span class="card-date">17 Sep 2021</span>
<span class="card-title">2D Marching Squares</span>
<a class="card-title" href="projects/marching_squares.html">
2D Marching Squares
<span class="card-action">Open generator</span>
</a>
<span class="card-desc"
>I saw the 3D version of this algorithm in a game dev log and was
inspired to create this 2D land-and-sea map generator.</span
@@ -572,13 +652,12 @@
<span class="tag tag-red">p5.js</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript p5"
data-href="projects/warping_lines.html"
>
<article class="card project-card" data-tech="javascript p5">
<span class="card-date">2 Apr 2020</span>
<span class="card-title">Müller-Lyer illusion</span>
<a class="card-title" href="projects/warping_lines.html">
Müller-Lyer illusion
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>JavaScript visualisation of the Müller-Lyer optical
illusion.</span
@@ -588,13 +667,12 @@
<span class="tag tag-red">p5.js</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript p5"
data-href="projects/fourier_series.html"
>
<article class="card project-card" data-tech="javascript p5">
<span class="card-date">27 Feb 2019</span>
<span class="card-title">Fourier series</span>
<a class="card-title" href="projects/fourier_series.html">
Fourier series
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>Builds a square wave from sine components to show Fourier series
in motion.</span
@@ -604,13 +682,12 @@
<span class="tag tag-red">p5.js</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript p5"
data-href="projects/ellipse_construction.html"
>
<article class="card project-card" data-tech="javascript p5">
<span class="card-date">23 Feb 2019</span>
<span class="card-title">Constructing an ellipse</span>
<a class="card-title" href="projects/ellipse_construction.html">
Constructing an ellipse
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>A geometric construction demo inspired by
<a
@@ -626,13 +703,12 @@
<span class="tag tag-red">p5.js</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript p5"
data-href="projects/pi_approximation.html"
>
<article class="card project-card" data-tech="javascript p5">
<span class="card-date">18 Mar 2018</span>
<span class="card-title">Calculating Pi</span>
<a class="card-title" href="projects/pi_approximation.html">
Calculating Pi
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>A Monte Carlo approximation of pi using random sampling.</span
>
@@ -641,13 +717,12 @@
<span class="tag tag-red">p5.js</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript p5"
data-href="projects/oscillations_in_3d.html"
>
<article class="card project-card" data-tech="javascript p5">
<span class="card-date">17 Dec 2017</span>
<span class="card-title">Oscillations in 3D</span>
<a class="card-title" href="projects/oscillations_in_3d.html">
Oscillations in 3D
<span class="card-action">Open visualiser</span>
</a>
<span class="card-desc"
>A JavaScript recreation of a Bees and Bombs animation.</span
>
@@ -656,13 +731,12 @@
<span class="tag tag-red">p5.js</span>
</span>
</article>
<article
class="card project-card card-link"
data-tech="javascript p5"
data-href="projects/maze_generation/index.html"
>
<article class="card project-card" data-tech="javascript p5">
<span class="card-date">13 Nov 2017</span>
<span class="card-title">Maze generator</span>
<a class="card-title" href="projects/maze_generation/index.html">
Maze generator
<span class="card-action">Open generator</span>
</a>
<span class="card-desc"
>Discovered the
<a
@@ -686,20 +760,19 @@
type="button"
class="projects-more-btn"
aria-expanded="false"
aria-controls="project-grid"
hidden
>
See more
Show more projects
</button>
</div>
</section>
<div class="divider"></div>
<!-- ─── Contact ───────────────────────────────────────────────── -->
<section id="contact">
<p class="section-label reveal">contact</p>
<div class="contact-inner reveal" style="transition-delay: 0.1s">
<div>
<h2>Let's <em>talk</em></h2>
<h2>Let's talk</h2>
<p>
I am currently employed and open to the right software engineering
opportunity, particularly backend or full-stack roles with
@@ -708,31 +781,30 @@
<p>For professional enquiries, connect with me on LinkedIn.</p>
</div>
<div class="contact-links">
<a
href="https://github.com/jayo60013"
class="contact-link"
target="_blank"
rel="noopener"
>
<span
class="contact-link-icon contact-link-icon--github"
aria-hidden="true"
></span>
<span class="contact-link-label">GitHub</span>
<span class="contact-link-handle">jayo60013</span>
</a>
<a
href="https://www.linkedin.com/in/jaygatward"
class="contact-link"
class="btn btn-primary contact-link"
target="_blank"
rel="noopener"
rel="noopener noreferrer"
>
<span
class="contact-link-icon contact-link-icon--linkedin"
aria-hidden="true"
></span>
<span class="contact-link-label">LinkedIn</span>
<span class="contact-link-handle">jaygatward</span>
<span>Connect on LinkedIn</span>
</a>
<a
href="https://github.com/jayo60013"
class="contact-link contact-link--secondary"
aria-label="Explore my code on GitHub"
target="_blank"
rel="noopener noreferrer"
>
<span
class="contact-link-icon contact-link-icon--github"
aria-hidden="true"
></span>
<span>Explore my code</span>
</a>
</div>
</div>