Case study

Pallas

A portfolio site made to show people what I do, my skills and my work.

Previously I could only show live examples of projects I built, but now I can display them on a visual, interactive project. I have always found technology easiest to learn during real use cases, so I built pallas.cloud to learn new tools on the fly.

Role
Design and development
Studio
Independent
Sector
Portfolio
Timeline
2026 to present
Stack
  • Next.js
  • React
  • GraphQL
  • Tailwind
Live site
  • Headless build
  • Design system
  • WebGL
  • Motion
  • Performance
  • Modern tools
  • SEO

01 / The brief

A portfolio with nowhere to hide

A portfolio is a poor place to fake a set of skills. The site had to be something I would send to a client, an employer, friends, family and be something I could update with new ideas whenever I wanted. I wrote about that decision in why I push to learn new technology.

Pallas is built on headless WordPress, with a Next.js frontend hosted on Vercel, served through Cloudflare. WordPress stays where it's useful: pages, posts and media. The public site is a Next.js app that asks the CMS for content and renders it. This keeps content editable and the front end open to the best next.js has to offer: lightweight, responsive, and modern performance & styling improvements.

02 / Architecture

Two halves and the connection between them

Most content is pulled from WordPress where HTML is sanitised, upload URLs are rewritten & optimised, and the menu has a fallback if the CMS loses connection.

Published edits are automatically revalidated within 60 seconds. This allows me to update the site without logging into SFTP.

Utilising content from the CMS means changing a paragraph in WordPress does not mean rebuilding the design. However some case studies that need a designed layout, like this one, live in the Next.js app.

  1. WriteWordPress
    • Pages and posts
    • Media uploads
    • Menus
    • Site settings
  2. GraphQL
  3. RenderNext.js
    • Page layouts
    • Design
    • Performance
    • Components
  4. GitHub
  5. ServeVercel
    • Preview on every push
    • Revisions & reviews
    • Hosted & packaged
    • Cache & revalidate

Cloudflare

03 / Introduction

Handing the logo to the navigation

The first view is the logo in the center of the screen, moving to the island navbar, revealing the site name "Pallas". This is designed to draw the eye to the top left of the screen and get users familiar with the branding before the content is revealed.

Animation is handled by GSAP measuring the end navbar logo location (it's possible for the user to refresh partly-scrolled, meaning it could be docked) and moves the intro logo to it. While this starts when components are ready, each step is on a set delay, so it never falls out of time. Reduced motion skips the sequence. Without JavaScript, a style rule hides the overlay, and the page is just the site.

04 / Design

A design system the whole site follows

Many effects and styles were written and then removed. I started with simple ideas, created them, and if they didn't fit the style I wanted, they were dropped. Colours were the same idea: I wanted to be able to refer to the theme as "black pearlescence", so I created a design system that followed it.

A dark base with no light backgrounds. Bright shimmering outlines and accents. White text with two heading styles for consistency and to draw the eye to things that matter. I had to ensure the pearlescence wasn't overused, so after every section was built, I had to make a choice on whether it was too much.

I also wanted every pearl feature on the site to focus on the navbar logo, giving the impression of a prism casting light on the page. This was a huge challenge to implement with several bugs along the way.

Variables

Base#0d0e10#ffffffSurface#161b22#ffffffText#f0f6fc#050607Muted#b8c0c8#0c0e12

The first hex is dark mode and the second is light mode. They invert between the two themes.

Secondary accents

Blue#6bb3ffMagenta#d059d3Yellow#fbf998Purple#8b5cf6
Navy#09162eBlue#6bb3ffCyan#1ba0e3Pink#f96edeInk#0e1333Blush#fff0f0Sand#f7cd9bYellow#fbf998Magenta#d059d3Rose#f4acbaViolet#6769e6Lilac#ffbfff

05 / Accents

The backgrounds of Pallas

Rain

The homepage opens on fine coloured streaks, angled at 60 degrees to match the triangle logo. They are drawn on a canvas behind the content and they hold still when reduced motion is on.

Topography

Contour lines signify the portfolio and work area of the site. WebGL is used to create a completely random pattern on every refresh.

Dots

The about page and quote sections have a grid of soft dots, with a few randomly selected to shine in the same iridescent colours as the theme.

Gradient

A pearlescent wash gathers in the bottom right of the contact blocks. The colours drift, then fade into the page, so the writing on the left remains clear.

06 / Under the surface

The parts nobody sees

  1. 01

    Contact forms

    Built with Next.js server actions and enabled with Resend, contact forms keep spam out of the inbox and make a simple hello easier.

  2. 02

    Performance

    All pages are constantly performance-reviewed and optimised for FCP, LCP, and TTFB, without compromising on accessibility or user experience.

  3. 03

    Accessibility

    Every element is built with accessibility in mind. Buttons have correct focus states, and content has appropriate aria labels. The site is keyboard-navigable.

  4. 04

    SEO/AEO

    Each page and the site as a whole are built with a consistent SEO/AEO strategy, targeting web development, but not appearing as an agency.

  5. 05

    Strict testing

    Every change is tested during development for speed, visibility, devices, browsers and edge cases. It's then reviewed as a whole after each live deployment.

  6. 06

    Discarded revisions

    Even if something worked initially, further development of the site often reveals improvements and consistency. The original elements are updated to suit, or removed.

07 / The memory bug

Tracing a 4.6GB memory leak

The primary concept for Pallas was to have every pearlescent accent to focus on the navbar logo. I had never seen it done before, so I had to figure it out as I went.

After completing the initial homepage build with the bulk of the animations & effects applied, the homepage render memory climbed from 140MB to over 4GB in 60 seconds. This visibly slowed the page. The heap lingered and continued to climb until the device ran out of memory.

Roughly 1,700 variables were inheriting a custom property for the pearlescent effect that forced style recalculation on every frame. Old calculations didn't get discarded properly, and continued to grow unchecked.

Several fixes were applied, only measuring when necessary, deferring the calculation until it's needed, and resetting the variable when it's no longer needed. Commit 253e7cf on 8 October stopped the climb. Idle memory now holds around 160-200MB. The main thread is busy about 34% of the time instead of 99%, and style work is about 20% of idle time instead of 80%. The problem was solved and no longer grows.

Browser memory when idle

BeforeAfter 253e7cf
Before the fix, memory passed 4.6GB after 60 seconds and kept climbing to 8GB, when the browser runs out of memory. After commit 253e7cf it stays between 160 and 200MB.02GB4GB6GB8GB0 s30 s60 s90 s120 s150 sBefore: 4.6GB+ after 60sAfter: 160-200MB, stableBrowser runs out of memory
Idle homepage, 8 October 2026. Before the fix, memory passed 4.6GB after 60 seconds and kept climbing until the browser ran out of memory. After 253e7cf it stays between 160 and 200MB.
Idle render memory
0-0MB4.6GB within 70s
Main thread busy at idle
0%99%
Idle time spent restyling
0%80%

08 / Performance

Pagespeed Insights

Mobile
  • 0
    Performance
  • 0
    Accessibility
  • 0
    Best Practices
  • 0
    SEO
  • 0/2
    Agentic Browsing
Desktop
  • 0
    Performance
  • 0
    Accessibility
  • 0
    Best Practices
  • 0
    SEO
  • 0/2
    Agentic Browsing
Homepage Lighthouse, lab scores. Simulated throttling, not field data.

09 / Process

Project timeline

Because the purpose of this site was to learn and develop new skills, I did not plan the whole site out from the beginning. I built it commit by commit, a section at a time, Reviewing what was possible, reading up on new technologies, and building the site as I went - keeping what looked best.

  1. 10 to 12 Sep

    Foundations

    The app shell, the CMS, and the first deploy.

  2. 13 Sep to 5 Oct

    The homepage

    The intro, the docked logo, and the visual rules the rest of the site had to follow.

  3. 6 to 8 Oct

    Structure and the leak

    Content, contact, and the fix to the CSS memory leak.

  4. 9 Oct to Nov and beyond

    Pages and proof

    Work, about, news, and this case study. Work will continue to be added as I have new ideas or projects to share.

10 / By the numbers

What the build added up to

0+Commits and revisions, 10 September to 1 November 2026
0Components used on the site
0Days since the project began
0Pages on the site
Built with
  • Next.js
  • React
  • GraphQL
  • WordPress
  • Tailwind
  • SCSS
  • Vercel
  • GitHub
  • TypeScript
  • GSAP
  • Lenis
  • Cloudflare
  • Resend
  • Lucide
  • ShadCN/Radix

11 / Outcome

Conclusion

Pallas is the proof. It is the stack I wanted to learn and use. And is a personal testbed for new ideas and concepts I want to bring to my daily work.

This site is and forever will be a work in progress. I will continue to add new pages, features and improvements as long as I have new ideas or projects to share.

If you've spotted any bugs, anything that can be improved, or have ideas for new features, I'd love to hear from you.

Contact

If you're interested in learning more about me and what I do, or to discuss a project, email is the fastest way.

Typical response within 1 working day.