084

Multi-Page Developer Portfolio

Templates Pass or Vault: not sold separately £50 or the whole Vault, £99

An eleven-page portfolio website template for frontend developers, design engineers, product designers and freelance consultants. Every project has its own case study in its own colour, whole sections turn selected, and every page change runs as a text selection that lands on the next title in the destination's colour.

ScrollTrigger advanced
10 more details
page-transitionsoft-navigationdirectional-transitionclip-pathscroll-revealstaggerhover-effectkeyboard-navigationfocus-managementprogressive-enhancement

This template reads better at your own screen size than in the frame below:

About this template

A portfolio for someone who designs and builds: home, a work index, five case studies, about and stack, a writing index, an essay and contact, eleven pages in all. Ama Owusu, a fictional design engineer in Rotterdam, is the worked example, with five projects written up in full, product screens and photographs of the work in use, essays and short notes. The same pages suit a frontend developer, full-stack developer, product designer or independent consultant once the name, work and copy are yours.

Read the full template overview

The whole site is built on one material: selection. A paper-grey ground, near-black ink and a small family of saturated colours that mean selected: a true blue for the site and one colour per project. Small things are selected (a project name, the current page, a row under the pointer) and so are whole sections, set into the page as rounded panels: each case study's head, figures and footer turn the page's colour with the text reversed out, every page opens on a hero panel in its own colour with the navigation pill set into it, and the Contact page is one panel from top to bottom, in the colour of the last project you read. On the home page the Selected work panel turns the colour of the project under the pointer, and the page transition draws its selection in the destination's colour, so moving between projects visibly changes colour.

The home page sets the statement on a ruled title line beside a stack of product screens. Hover, focus or drag-select a project name in the introduction and the selection hops to it, in that project's colour, as its screen comes to the front. On the work list a highlight bar follows the pointer and the keyboard across the projects with a large preview beside them.

Page changes are the signature, in under a second with the next page prefetched. The clicked link is selected like text and the selection grows into a page-sized panel in the destination's colour, the next title appears on it, and the panel settles onto the new page's hero as the title deselects with one blink of a caret. Back and Forward grow the panel from the screen edge. Everything is static HTML, CSS and JavaScript with bundled images and no build step.

Multi-Page Developer Portfolio - website template preview

What's included

12 items
  • Eleven standalone HTML pages: home, work, five case studies, about and stack, writing index, essay and contact
  • Text-selection page transition on every internal link: the selection grows into a page-sized panel in the destination's colour, holds the next title, then settles onto the new page, in about a second
  • Selected sections: bands with reversed-out text for selected work, case study heads and figures, talks, principles and the footer, and a fully selected Contact page
  • A colour family of nine tokens: a true blue for the site, one colour per project and three page colours, each measured for white text and as text on the ground
  • Home hero with a stack of product screens that reorders as you hover, focus or drag-select project names
  • Project list with a highlight bar that follows hover and keyboard focus, a large live preview, and the highlight carried into the transition
  • Five case studies from one kit of sections (wide screen, photograph, split, pair, figures band, quote, decisions, code, changelog) with previous and next project links
  • Photographs of the work in use and the process alongside designed product screens, with credits
  • Back and Forward reverse the direction and restore scroll; the arriving heading is focused and announced
  • Writing index with essays and notes, filterable by topic through ?topic= links, and an essay with a live ::selection demo
  • Contact page with copy-to-clipboard email and an unwired enquiry form
  • Real links and complete pages without JavaScript; instant page swaps under reduced motion

Perfect for

4 use cases
  • Frontend and full-stack developer portfolios with a few deep case studies
  • Design engineer and product designer portfolios that mix work, writing and an about page
  • Freelance consultants and independent developers taking enquiries
  • Personal sites that publish essays and short notes alongside client work

How it works

5 sections

Eleven pages, one title line

Each page is its own HTML file with the same header and page head: a small label above and the page title on a ruled line at a fixed height. Five case studies share one kit of sections, mixed differently per project, with previous and next links between them. Without JavaScript the links are ordinary links and every page is complete.

Selection as structure, in colour

Six colours mean selected: a core blue for the site and one per project, each holding white text. A page names its colour with one attribute, and inside a selected block every colour token flips, so lists, links, the highlight bar, figures and form fields reverse out without extra rules. Case studies open on a head in the project's colour.

The selection transition

Internal links fetch the next page and swap its content in place, with the exit starting on the click while the page loads underneath. The link is highlighted like selected text, and the selection grows into a rounded panel the size of the page, in the destination's colour, with the next title held on it until the page is ready. The title deselects with a caret blink as the panel settles onto the new page's own hero panel, under a header that stays put.

Work you can handle

On the home page the project names in the introduction can be hovered, focused or drag-selected; the selection hops to the name and that project's screen comes to the front of the stack beside the title. On the work list a highlight bar follows pointer and keyboard focus with a large preview, and a lit row carries its highlight straight into the transition. Touch screens show each project's screen inline.

Calm when it needs to be

Reduced motion swaps pages instantly and shows every section without animation. Keyboard navigation lands focus on each new page's heading and announces it. A second click during a transition is honoured without the old page flashing back. With the animation library blocked, the site falls back to plain page loads.

Plugins ScrollTrigger
Difficulty Advanced
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this template's demo (11 pages, lowest score shown), from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Questions about this template

Who is this portfolio template for besides design engineers?

It suits anyone who shows a handful of projects and writes about how they work: frontend developers, full-stack developers, product and UX designers, design engineers and freelance consultants. Replace Ama Owusu's name, projects, screenshots and essays with yours; the case study structure works for code-heavy and design-heavy projects alike.

How do I add more case studies or essays?

Duplicate one of the five work pages, change the title, label, meta and sections, and point a row on the work page and the previous and next links at it. Each case study is built from the same kit of sections, so you can drop or reorder them freely. The transition picks up any new page's title from its h1.

Can I use my own screenshots and photographs?

Yes. Each project row has its own 16:10 screenshot, which also feeds the large preview and the home page stack, so replacing one file updates all three. Case study photographs sit in ordinary figures with captions. The README lists every bundled image and how to regenerate optimised WebP versions from the manifest.

Does the contact form send email?

No. The enquiry form is an unwired static front end: it collects a name, email, company, type of work, rough budget and a message, checks the required fields and shows a confirmation that nothing was sent. Connect it to Formspree, Netlify Forms, Basin or your own endpoint before launch. The copy-email button works as shipped.

Can I change the colours?

Yes. The colour family is nine tokens at the top of the stylesheet: --c-core for the site, one per project and three page colours (--c-night, --c-ochre, --c-plum), each with an RGB triple. A case study picks its colour with data-hue on the page wrapper and on links that point to it. Keep every colour dark enough for 4.5:1 with white text and on the page ground; the stylesheet records the measured pairs.

Can I keep some links as normal page loads?

Yes. Add data-native-navigation to any link, or to a container such as the footer, and those links load the next page normally without the selection transition. Links to other folders, external sites, downloads and same-page anchors already behave normally, so a blog hosted elsewhere or a PDF CV needs no changes.

Templates Pass or Vault

Get the Templates Pass or the Vault to use this template.

The Templates Pass and the Vault both include Multi-Page Developer Portfolio, the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate. This template is not sold on its own.

£50 Templates Pass: every current and future premium template

Browse templates

Or the whole library: the Vault, £99, one payment.

Documentation

Quick Start

Upload the folder to any static host and open index.html. Keep the eleven HTML files beside assets/ so relative links keep working. There is no build step, framework or package to install.

Serve the files over HTTP or HTTPS to see the page transitions. While editing, run any local static server in the folder (for example python3 -m http.server) and open http://localhost:8000/index.html. Opening a file straight from disk works too, but links then load pages normally without the transition.

GSAP and ScrollTrigger load from a CDN and the fonts (Host Grotesk and Google Sans Code) from Google Fonts. Images, styles and scripts are bundled locally.

Using It With Your Own Design

  1. Identity. Replace "Ama Owusu", "Design engineer" and "Booking from January" in the header of each page, and the line and links in each footer. They are repeated in all eleven files so every page stands alone.
  2. Titles. Each page's h1 sits on the shared title line. Keep titles short (one or two lines); the home statement can hold a permanently selected phrase in <span class="sel">.
  3. Projects. Edit the rows in index.html and work.html, the project names in the home introduction, and the five work-*.html case studies. Replace the screenshots and photographs in assets/img/ (see Images).
  4. Writing. Replace the essay in writing-selection.html and the notes on writing.html. Give each note an id and its topics in data-topics.
  5. Colour and type. Edit the colour tokens at the top of assets/style.css (see Palette). Change the Google Fonts link in each page if you change typefaces.
  6. Contact. Change the email address and connect the enquiry form before launch (see Contact Form).

Everything visual lives in assets/style.css; everything interactive lives in assets/script.js, organised as one function per feature that returns early when its markup is absent. assets/page-router.js is the small shared page router underneath the transition (link handling, fetching, history, scroll and focus); you should not need to edit it. Delete a section from the HTML and the rest keeps working.

Pages and Configuration

File Content
index.html Statement on the title line beside a stack of product screens, introduction with selectable project names, facts row, selected work band, writing, Now with a photograph
work.html All five projects with a highlight bar and large preview, talks and workshops band
work-ledgerline.html, work-tidepool.html, work-kiln.html, work-sedge.html, work-halyard.html Case studies from one kit: head and meta, wide screen, then a mix of text, photograph, split (text beside a photo), pair, figures band, quote, decisions, code and changelog, ending in previous and next project links
about.html Portrait and biography, a working photograph, stack, experience, a band of working habits
writing.html Topic filter, a selected essay band and dated notes; ?topic=css filters on arrival
writing-selection.html Essay with a live ::selection demo, code, footnotes and links onward
contact.html A fully selected page: email with a copy button, enquiry form, availability, time zone and elsewhere

Hooks you will meet in the markup:

  • data-page wraps each page's content and footer; the header stays outside it and persists across page changes. data-nav="work" on that wrapper names the navigation item to mark as current (case studies mark Work, the essay marks Writing). The is-selected class on that wrapper makes a whole page one panel, as on Contact.
  • is-selected on any block (the band sections, the footer, every page's page-top hero) flips every colour token inside it: the page's colour as the ground, white text, white selection. Components need no extra rules to sit inside one.
  • data-hue="kiln" on a page wrapper gives that page its colour; on a link (nav links, work rows, home project names, previous and next) it tells the transition, and the nav hover fill, which colour to draw in. Values match the --c-* tokens.
  • data-hero-words holds the home introduction; each a[data-project="tidepool"] matches an img[data-shot="tidepool"] in data-hero-stack. Add or remove pairs together.
  • .page-head holds the small label (.eyebrow) and the h1.title. Keep this structure on every page: the transition reads the next page's title from it and lands on its first baseline.
  • data-work-list with data-work-row links: the project list. Each row's .work-thumb image (16:10) is shown inline on touch screens and also feeds the preview panel (data-work-preview) on desktop. Wrap the words the transition should select in data-select-text.
  • data-topic links and data-topics="css motion" items: the writing filter. It works in place, counts each topic on its chip and writes what matched into data-filter-status.
  • data-copy / data-copy-source: the copy-email button and the text it copies. data-contact-form: the enquiry form.
  • data-intro marks a page's opening block; data-reveal and data-reveal-group give a gentle rise on scroll.

Page Transitions

Every same-origin link to a sibling .html page runs the same transition, and the next page is fetched while it plays. With the page prefetched (links prefetch on hover and focus) the whole change takes about one second:

  1. Leave (about 0.5s). The clicked link's words are highlighted from left to right, like pressing Shift+End. The highlight then grows into a rounded panel the size of the window, inset like every other panel, while the old page fades out under it and the header floats on top. A lit project row skips the first step: its highlight bar is already the selection. The panel is drawn in the destination's colour: a link's data-hue, the project named in a work-<project>.html address, the last project visited (for Contact), or the core blue.
  2. Hold. The next page's title appears on the panel, in white, on the title line. The only wait is the genuine fetch and image decode.
  3. Enter (about 0.6s). The title deselects with one caret blink while the panel settles onto the new page's hero panel (on Contact, the whole page), stopping short of a case study's first screen; the held title hands over to the real heading underneath. The header floats over the panel throughout, and its selection slides to the new page.

Back and Forward grow the panel from the bottom or top edge instead of from a link. Scroll positions are restored, and the arriving heading receives focus and is announced. In the navigation pill the current page is a white selection that slides to the new link, and hovering or focusing a link fills it in the colour of the page it leads to; click, and that fill is what grows into the next page's panel.

Notes for editing:

  • Pages are fetched, not reloaded, so scripts inside a fetched page do not run. Add new behaviour to assets/script.js as another init function called from initPage. Every page loads assets/page-router.js before assets/script.js; keep that order on a new page.
  • The transition is the leave, hold and enter functions passed to PageRouter.create at the end of assets/script.js. The header comment of assets/page-router.js lists everything they receive.
  • Any sibling HTML file with a data-page wrapper joins the transition automatically. Add data-native-navigation to a link or container to opt out; downloads, new-tab clicks, external links and same-page anchors already behave normally.
  • Timings live in leave, showTitle and enter. On a slow connection the title is held on the panel until the page and its main image are ready; nothing is added on top of the network time.
  • The latest click wins: a second link chosen before the new page is in place goes straight there from the covered screen.

Contact Form

The enquiry form is a static front end. It collects name, email, company, type of work, a rough budget and a message, checks the required fields and then says plainly that nothing was sent. Point the form's action at Formspree, Netlify Forms, Basin or your own endpoint and remove the submit handler in initContact, or post the fields from that handler.

Palette

Token Value Use
--ground #F1F1EE Page ground and the transition cover
--surface #FBFBF9 Image frames, form fields, demo panel
--ink #15151A Text; dimmed at 0.70 and 0.60 for secondary text and labels
--c-core #0A5FD1 The site's selection colour and the home page's: highlights, links, focus, selected sections
--c-ledgerline #137547 Ledgerline's case study, row highlight and transition colour
--c-tidepool #0A6878 Tidepool
--c-kiln #A93F1D Kiln & Co.
--c-sedge #B5234C Sedge
--c-halyard #5B45E0 Halyard
--c-night / --c-ochre / --c-plum #1D1D24 / #735C00 / #7B2D6E Page colours: the heads of Work, About and Writing (Home is core blue)
--hue / --select per page The current page's colour (from data-hue) and the selection drawn with it; inside is-selected blocks the selection becomes white
--on-select #FFFFFF Text inside a selection
--inset / --r-panel clamp() The gap round a panel and its corner radius; the transition reads both
--r-media / --r-control clamp() / 6px Corners on screens and photographs, and on buttons, fields and bars

Every page opens on a hero panel, <div class="page-top is-selected"> around its head, in the page's data-hue; the header sits on it with the navigation as a pill whose current page is a white selection. Nav links carry their page's data-hue too, so the transition knows the destination's colour before the page arrives: give a new page and its nav link the same one. A section turns selected with class="band is-selected"; add data-hue="kiln" (or any family name) to paint it in that colour instead of the page's. On the home page the Selected work panel takes the colour of the project under the pointer or focus.

Measured contrast pairs are recorded at the top of assets/style.css: white on each colour is 5.7:1 or better, and each colour as text on the ground is 5.1:1 or better. A replacement or extra project colour must keep 4.5:1 both ways; add its token, its RGB triple and a [data-hue="name"] line beside the others.

Accessibility and Fallbacks

  • Real links everywhere, a skip link, visible focus in the selection colour, labelled form controls and one h1 per page.
  • The project highlight bar and the home project names follow keyboard focus as well as the pointer; the preview panel and the screen stack are decorative and hidden from assistive technology.
  • Text inside selected blocks is white, or white at 0.92 and 0.86 (4.7:1 at the lowest, on Ledgerline green); the navigation is full white.
  • The transition layer is aria-hidden. Scrolling is held while it runs, and the arriving heading is focused and announced through a polite live region.
  • Reduced motion swaps pages instantly and shows every section without animation.
  • No JavaScript, an unavailable GSAP CDN or opening from file://: links load pages normally and all content is visible.

Dependencies

The demo is pinned to GSAP 3.15.0 with ScrollTrigger. Compatibility floor: GSAP 3.12+, with core and plugin on matching versions. No Lenis, no other plugins, no backend.

Images and Credits

The download contains WebP derivatives in assets/img/, generated by assets/img-manifest.json (bun scripts/build-template-assets.ts <folder> in the Vault repository, or any image tool at the listed sizes). Product screens are 1600 by 1000 for the stack, list previews and case study heads; photographs are lazy-loaded below the fold.

The product screens (ledgerline-*.webp, tidepool*.webp, kiln*.webp, sedge*.webp, halyard*.webp) are designed mock-ups of fictional products, made for this template from HTML and CSS; their JPEG masters are in assets/img-src/. Replace them with screenshots of your own work.

Photographs are licensed through Pexels, which permits use in website templates. They show unrelated people and places, not Ama Owusu, her clients or their users; captions describe the scene, not a real project.

File Source Subject
portrait.webp Pexels 10159280 Smiling woman in a white T-shirt against a pale wall
photo-ledgerline-whiteboard.webp Pexels 1181343 Man at a whiteboard of wireframe sketches
photo-ledgerline-paper.webp Pexels 11780441 Hand on a phone over grid-paper wireframes
photo-tidepool-deck.webp Pexels 39199081 Woman checking a phone on deck, yachts behind
photo-tidepool-helm.webp Pexels 5416429 Sailor at the wheel of a yacht
photo-kiln-studio.webp Pexels 9304491 Teacher throwing a bowl while a student watches
photo-kiln-hands.webp Pexels 31848846 Hands shaping a vase on a wheel
photo-sedge-mudflat.webp Pexels 17688199 Figure walking across a mudflat towards reeds
photo-sedge-wading.webp Pexels 14244617 Person wading among plants in still water
photo-halyard-desk.webp Pexels 574073 Laptop with code beside a notebook
photo-talk.webp Pexels 18935245 Speaker facing an audience at tables
photo-about-call.webp Pexels 7014931 Over-the-shoulder view of a video call and drawing tablet
photo-sketch.webp Pexels 4959784 Hands sketching beside a laptop

Replace the portrait with your own photograph before launch.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.