<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
George Brook – Front-end Developer | CV & Portfolio
</title>
<meta name="description" content="Explore the CV of George Brook, a front-end developer specializing in accessible, performant, and user-focused web experiences.">
<link rel="canonical" href="https://yourdomain.com/">
<meta property="og:title" content="George Brook – Front-end Developer | CV & Portfolio">
<meta property="og:description" content="Explore the CV of George Brook, a front-end developer specializing in accessible, performant, and user-focused web experiences.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://yourdomain.com/">
<meta property="og:image" content="https://yourdomain.com/og-image.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="George Brook – Front-end Developer | CV & Portfolio">
<meta name="twitter:description" content="Explore the CV of George Brook, a front-end developer specializing in accessible, performant, and user-focused web experiences.">
<meta name="twitter:image" content="https://yourdomain.com/og-image.jpg">
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<canvas class="noise">
</canvas>
<button id="random-color-btn" class="color-toggle fun-button" aria-label="Randomise font">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="none" stroke="currentColor" stroke-dasharray="28" stroke-dashoffset="28" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3c0 0 7 6 7 12c0 2 -1 6 -7 6M12 3c0 0 -7 6 -7 12c0 2 1 6 7 6">
<animate attributeName="stroke-dashoffset" dur="3s" values="28;0;28;" repeatCount="indefinite">
</animate>
</path>
<path fill="currentColor" fill-opacity="0" d="M12 3C12 3 15.27 5.81 17.34 9.5L6 18.41C5.21 17.24 5 15.91 5 15C5 9 12 3 12 3Z">
<animate attributeName="fill-opacity" dur="3s" values="0;0.3;0" repeatCount="indefinite">
</animate>
</path>
</svg>
</button>
<label class="theme-toggle fun-button" for="themeToggle" aria-label="Toggle dark mode">
<input type="checkbox" id="themeToggle">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-dasharray="4" stroke-dashoffset="4" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
<path d="M13 4h1.5M13 4h-1.5M13 4v1.5M13 4v-1.5">
<animate id="lineMdMoonRisingFilledAltLoop0" fill="freeze" attributeName="stroke-dashoffset" begin="0.7s;lineMdMoonRisingFilledAltLoop0.begin+6s" dur="0.4s" values="4;0">
</animate>
<animate fill="freeze" attributeName="stroke-dashoffset" begin="lineMdMoonRisingFilledAltLoop0.begin+2s;lineMdMoonRisingFilledAltLoop0.begin+4s" dur="0.4s" values="4;0">
</animate>
<animate fill="freeze" attributeName="stroke-dashoffset" begin="lineMdMoonRisingFilledAltLoop0.begin+1.2s;lineMdMoonRisingFilledAltLoop0.begin+3.2s;lineMdMoonRisingFilledAltLoop0.begin+5.2s" dur="0.4s" values="0;4">
</animate>
<set fill="freeze" attributeName="d" begin="lineMdMoonRisingFilledAltLoop0.begin+1.8s" to="M12 5h1.5M12 5h-1.5M12 5v1.5M12 5v-1.5">
</set>
<set fill="freeze" attributeName="d" begin="lineMdMoonRisingFilledAltLoop0.begin+3.8s" to="M12 4h1.5M12 4h-1.5M12 4v1.5M12 4v-1.5">
</set>
<set fill="freeze" attributeName="d" begin="lineMdMoonRisingFilledAltLoop0.begin+5.8s" to="M13 4h1.5M13 4h-1.5M13 4v1.5M13 4v-1.5">
</set>
</path>
<path d="M19 11h1.5M19 11h-1.5M19 11v1.5M19 11v-1.5">
<animate id="lineMdMoonRisingFilledAltLoop1" fill="freeze" attributeName="stroke-dashoffset" begin="1.1s;lineMdMoonRisingFilledAltLoop1.begin+6s" dur="0.4s" values="4;0">
</animate>
<animate fill="freeze" attributeName="stroke-dashoffset" begin="lineMdMoonRisingFilledAltLoop1.begin+2s;lineMdMoonRisingFilledAltLoop1.begin+4s" dur="0.4s" values="4;0">
</animate>
<animate fill="freeze" attributeName="stroke-dashoffset" begin="lineMdMoonRisingFilledAltLoop1.begin+1.2s;lineMdMoonRisingFilledAltLoop1.begin+3.2s;lineMdMoonRisingFilledAltLoop1.begin+5.2s" dur="0.4s" values="0;4">
</animate>
<set fill="freeze" attributeName="d" begin="lineMdMoonRisingFilledAltLoop1.begin+1.8s" to="M17 11h1.5M17 11h-1.5M17 11v1.5M17 11v-1.5">
</set>
<set fill="freeze" attributeName="d" begin="lineMdMoonRisingFilledAltLoop1.begin+3.8s" to="M18 12h1.5M18 12h-1.5M18 12v1.5M18 12v-1.5">
</set>
<set fill="freeze" attributeName="d" begin="lineMdMoonRisingFilledAltLoop1.begin+5.8s" to="M19 11h1.5M19 11h-1.5M19 11v1.5M19 11v-1.5">
</set>
</path>
<path d="M19 4h1.5M19 4h-1.5M19 4v1.5M19 4v-1.5">
<animate id="lineMdMoonRisingFilledAltLoop2" fill="freeze" attributeName="stroke-dashoffset" begin="2s;lineMdMoonRisingFilledAltLoop2.begin+6s" dur="0.4s" values="4;0">
</animate>
<animate fill="freeze" attributeName="stroke-dashoffset" begin="lineMdMoonRisingFilledAltLoop2.begin+2s" dur="0.4s" values="4;0">
</animate>
<animate fill="freeze" attributeName="stroke-dashoffset" begin="lineMdMoonRisingFilledAltLoop2.begin+1.2s;lineMdMoonRisingFilledAltLoop2.begin+3.2s" dur="0.4s" values="0;4">
</animate>
<set fill="freeze" attributeName="d" begin="lineMdMoonRisingFilledAltLoop2.begin+1.8s" to="M20 5h1.5M20 5h-1.5M20 5v1.5M20 5v-1.5">
</set>
<set fill="freeze" attributeName="d" begin="lineMdMoonRisingFilledAltLoop2.begin+5.8s" to="M19 4h1.5M19 4h-1.5M19 4v1.5M19 4v-1.5">
</set>
</path>
</g>
<path fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 6 C7 12.08 11.92 17 18 17 C18.53 17 19.05 16.96 19.56 16.89 C17.95 19.36 15.17 21 12 21 C7.03 21 3 16.97 3 12 C3 8.83 4.64 6.05 7.11 4.44 C7.04 4.95 7 5.47 7 6 Z" transform="translate(0 22)">
<animateMotion fill="freeze" calcMode="linear" dur="0.6s" path="M0 0v-22">
</animateMotion>
</path>
</svg>
</label>
<main>
<header>
<h1>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path stroke-dasharray="64" stroke-dashoffset="64" d="M13.5 3l5.5 5.5v11.5c0 0.55 -0.45 1 -1 1h-12c-0.55 0 -1 -0.45 -1 -1v-16c0 -0.55 0.45 -1 1 -1Z">
<animate fill="freeze" attributeName="stroke-dashoffset" dur="0.6s" values="64;0">
</animate>
</path>
<path d="M14.5 3.5l2.25 2.25l2.25 2.25z" opacity="0">
<animate fill="freeze" attributeName="d" begin="0.6s" dur="0.2s" values="M14.5 3.5l2.25 2.25l2.25 2.25z;M14.5 3.5l0 4.5l4.5 0z">
</animate>
<set fill="freeze" attributeName="opacity" begin="0.6s" to="1">
</set>
</path>
<path stroke-dasharray="8" stroke-dashoffset="8" d="M9 13h6">
<animate fill="freeze" attributeName="stroke-dashoffset" begin="0.8s" dur="0.2s" values="8;0">
</animate>
</path>
<path stroke-dasharray="4" stroke-dashoffset="4" d="M9 17h3">
<animate fill="freeze" attributeName="stroke-dashoffset" begin="1s" dur="0.2s" values="4;0">
</animate>
</path>
</g>
</svg>
George Brook
</h1>
<div class="intro">
<img src="me-colour.jpg" alt="An image of me with a great view.">
<p>
I'm a Front-End Developer with over 10 years of experience building responsive, accessible, and high-performance web interfaces. I have a strong passion for structured, reusable components and maintainable front-end architecture. In my free time, I enjoy playing tennis.
</p>
</div>
</header>
<section>
<h2>
Education
</h2>
<p>
<strong>
Bachelor of Science (Physics, 2:1)
</strong>
<br>
University of Bath — 2012
</p>
<p>
<strong>
A Levels
</strong>
<br>
Wymondham High School — 2008
</p>
<p>
<strong>
Certifications
</strong>
<br>
Acquia Certified Drupal Front End Specialist (Drupal 8 & 9)
</p>
</section>
<section>
<h2>
Professional Experience
</h2>
<h3>
Company: Catch Digital (London, UK, remote)
</h3>
<p>
<strong>
Senior Front-End Developer
</strong>
· March 2022 – May 2025
</p>
<p>
<strong>
Clients:
</strong>
IOP, TTTech Auto, Framestore, Ashmore Group, Countryside Ski & Climb, My Business Stream, Norton Abrasives, Highland Park Whisky, Wyoming Whiskey, SES, IAB UK, Edrington Distilleries, The Macallan
</p>
<ul>
<li>
Built modular front-end systems for enterprise-scale sites using atomic design and Storybook.
</li>
<li>
Optimised performance across several websites using code splitting and CI/CD.
</li>
<li>
Led JWT-secured integrations with headless CMS's and REST API's.
</li>
<li>
Developed reusable e-commerce components and workflows.
</li>
<li>
Mentored junior developers and led accessibility compliance efforts.
</li>
<li>
Developed large webforms and user journeys for complex applications to large organisations.
</li>
</ul>
<p>
<strong>
Key Projects:
</strong>
</p>
<p>
<em>
My Business Stream Portal
</em>
– React-based self-service portal with JWT auth and modular components.
</p>
<p>
<em>
The Macallan Global Website
</em>
– Front-end support for scalable Drupal/Next.js JSON API build.
</p>
<p>
<strong>
Reason for Leaving:
</strong>
Company restructure / merger.
</p>
<h3>
Company: Zoocha Ltd (Hertford, UK and remote)
</h3>
<p>
<strong>
Mid/Senior Front-End Developer
</strong>
· March 2014 – May 2022
</p>
<p>
<strong>
Clients:
</strong>
Greater London Authority, Ofsted, FCA, Falmouth University, Visit Britain, BFBS, Royal Marsden, Visit Jersey, National Forest, Topdeck Travel
</p>
<ul>
<li>
Accessible front-end development (WCAG AAA) for public/financial sites.
</li>
<li>
Led prototyping efforts using modern JS/CSS stacks.
</li>
<li>
Advocated for modular UIs and component-driven workflows.
</li>
<li>
Mentored devs and championed performance tooling.
</li>
</ul>
<p>
<strong>
Reason for Leaving:
</strong>
Company returned to UK-only office model; remained in SA.
</p>
</section>
<section>
<h2>
Fun Stuff
</h2>
<ul>
<li>
<a target="_blank" href="https://devtools-ecru.vercel.app/elements">
Chrome Devtools built in VueJS/Nuxt
</a>
</li>
<li>
<a target="_blank" href="https://github.com/georgebrook/kyc-chat-app">
React/NextJS Realtime DB with QR code to chat on same Wifi
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" href="https://codepen.io/georgebrook/full/mqexXB">
CSS Seamless Animated Text
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" href="https://codepen.io/georgebrook/full/jrLXvP">
CSS Digital Countdown
</a>
</li>
<li>
<a target="_blank" href="https://codepen.io/georgebrook/full/PoPopgP">
Leaflet Map Clustering
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" href="https://codepen.io/georgebrook/full/EbxxgX">
Parallax Stars with JavaScript
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" href="https://codepen.io/georgebrook/full/MrdEbW">
JavaScript Diamond Pattern
</a>
</li>
</ul>
</section>
<section>
<h2>
Technical Proficiency
</h2>
<ul>
<li>
<strong>
Front-End:
</strong>
React, Next.js, TypeScript, JS (ES6+), VueJS, HTML, CSS, SASS, Twig
</li>
<li>
<strong>
Workflow:
</strong>
Webpack, Git, CI/CD, GitHub Actions, Agile, Atomic Design
</li>
<li>
<strong>
Platforms:
</strong>
Drupal, Headless CMS, REST/JSON APIs
</li>
<li>
<strong>
Accessibility:
</strong>
WCAG 2.1/2.2, BEM, Semantic HTML
</li>
<li>
<strong>
DevOps:
</strong>
Docker, DDEV, Linux, NGINX, PHP, MySQL
</li>
</ul>
</section>
<section class="personal-info">
<h2>
More About Me
</h2>
<p>
When I’m not coding, I enjoy running long distances, playing tennis (both competitively and for fun), and perfecting my homemade lasagne recipe. Here are some other links.
</p>
<ul>
<li>
<a href="https://imgur.com/a/artwork-drf0g" target="_blank" rel="noopener">
Artwork
</a>
</li>
<li>
<a href="https://soundcloud.com/zzxxccii" target="_blank" rel="noopener">
Music
</a>
</li>
<li>
<a href="https://www.drupal.org/u/georgebrook" target="_blank" rel="noopener">
Drupal
</a>
</li>
<li>
<a href="https://www.linkedin.com/in/georgebrook/" target="_blank" rel="noopener">
Linkedin
</a>
</li>
</ul>
</section>
<footer class="site-footer">
<p>
© George Brook. All rights reserved.
</p>
</footer>
</main>
</body>
</html>