# Law Firm

> A fifteen-page law firm website template for solicitors, lawyers, accountants and consultancies. Each page opens on one giant serif word cut through the middle by two flat colours, and every page change carries the next page's word in on a block of its colour.

Canonical: https://gsapvault.com/templates/law-firm-template
Live demo: https://gsapvault.com/demos/law-firm-template/index.html

| Property | Value |
|----------|-------|
| Type | template |
| Tier | paid |
| Price | Not sold singly; comes with the Templates Pass or the Vault |
| Difficulty | advanced |
| Plugins | ScrollTrigger |
| Techniques | page-transition, text-animation, typesetting, pinning, scrub, scroll-linked-color, load-sequence, click-toggle, scroll-reveal, stagger, hover-effect, keyboard-navigation, progressive-enhancement |
| Uses Lenis | No |

## Lighthouse, as measured

Google Lighthouse on the demo (15 pages, lowest score shown), 9 October 2026. A measurement of the demo as shipped, not a promise for your page.

| Category | Score |
|----------|-------|
| Accessibility | 100 |
| Best practices | 100 |

No performance score is published: it depends on the deployment (server compression, caching, CDN, connection and device) rather than on the code, so measure it where it will live.

## Overview

A law firm website has to look settled before it says anything. This fifteen-page template does it with type: every page opens on one giant serif word cut through the middle by two flat colour fields, so the home page reads SETTLED. across vermilion and saffron, the expertise page EXPERTISE, a partner's profile her surname. Black portraits, hairline-ruled lists, tracked small caps and outlined buttons keep the rest of the site quiet. Hollis Arden, a fictional independent firm in Manchester and Bristol, is the worked example; the same pages suit a solicitors' practice, barristers' chambers, accountancy firm, consultancy or architecture practice.

The colour system is deliberate rather than decorative. Vermilion is the firm, saffron is expertise, sage is people and lilac is insights, each measured for black text. A page's masthead, its swatch in the navigation and its page transition all use the same colour, so a visitor always knows which part of the site they are in.

Every internal link runs the signature transition. A block in the destination's colour rises over the page while the next one loads, the destination's word arrives in two halves that lock together on the colour seam, and the block then splits: the coloured half shrinks into the new page's masthead and the word lands exactly on the masthead word. On the home page, a pinned "Who we act for" sequence lets the visitor scroll four giant words into alignment while the seam cuts through the palette.

The pages cover the firm, six practice areas with expandable rows, a practice page with fixed fees and a four-step process, a filterable people index, a partner profile, an insights index with eight full articles, and a contact page with two offices and an enquiry form. Change four colour tokens, the word on each masthead, the copy and the portraits to make it yours. Everything is static HTML, CSS and JavaScript with bundled images and no build step.

## Features

- Fifteen standalone HTML pages: home, expertise, a practice page, people, a partner profile, insights, contact and eight full articles
- A masthead on every page made of one giant serif word cut through the middle by two flat colours, sized to fill the width
- Signature page transition on every internal link: a block in the destination's colour rises, the destination's word locks together on the seam, and the block splits into the new page's masthead
- Back and Forward close the block from both edges and part it again, with scroll positions restored and the new heading focused and announced
- Home hero whose two word halves slide in from opposite sides and lock on first load
- Pinned "Who we act for" sequence: four giant split words scrolled into alignment one after another as the seam cuts through the palette
- Six expandable practice rows that open as a saffron block with matters, fee basis and lead partner; a #practice link opens that row
- People index filtered by practice with a live count, pre-selected from a ?practice= link
- Practice page with both-sides lists, a four-step process, a fixed-fee table, team cards and related insights
- Partner profile, insights index with a featured article, eight full article pages and a contact page with two offices
- Enquiry form with matter-type chips that validates and states plainly that it is not connected
- Four destination colours, each measured for black text, with their roles documented in the stylesheet
- Fourteen bundled, graded WebP photographs: nine black-and-white portraits and five office and studio scenes, with credits
- Real links and complete pages without JavaScript; instant page swaps and static words under reduced motion

## Use Cases

- Solicitors and independent law firms presenting practice areas, people and insights
- Barristers' chambers and specialist legal practices with member profiles
- Accountancy, tax and financial advisory firms with several partners
- Management consultancies and architecture practices that want a typographic, confident site

## Questions about this template

### Which kinds of firm can use this law firm template?

It is built as a professional-services website: solicitors and law firms first, but barristers' chambers, accountants, tax advisers, consultancies and architecture practices keep the same structure of practice areas, people, insights and contact. Replace Hollis Arden's practices, portraits and copy, and choose a new word for each masthead, for example BALANCED. for an accountancy or BUILT. for an architect.

### How do I change the giant word on a page?

Each masthead has the word twice, once in the h1 above the seam and once in the hidden copy below it, plus a data-word attribute on the page wrapper that the page transition reads. Change all three to the same word and adjust --chars on the masthead, roughly its letter count, which sizes the word before the script measures and fits it exactly.

### Does the enquiry form send messages?

No. The contact page form is an unwired front end: it collects a name, email, optional phone number, nearest office, matter type and a description, validates them in the browser, and then shows a message saying nothing was sent. Point it at Formspree, Netlify Forms, your practice management system or your own endpoint before taking real enquiries.

### How do I add profiles for the rest of the team?

Duplicate adaeze-okafor.html for each person, change the surname masthead word, portrait, biography and quotes, and link their card's button to the new file with data-tone="sage". In the demo only one partner has a full profile and the other cards offer an email link. Each card's data-practices attribute decides which filter chips show it.

### Can I change the colours or add another practice page?

Yes. The four colours are tokens at the top of the stylesheet, each with a documented role and measured for black text; keep text on the colour fields at full ink strength. To add a practice page, copy employment.html, change its word and content, and link it from its expertise row with data-tone="saffron" so the transition arrives in the right colour.

### Are the people and figures real?

No. Hollis Arden, its offices, phone numbers, fees, quotes and people are fictional. The portraits are stock photographs of models, converted to black and white, and the footer carries a note saying the firm is fictional. Replace them with your own team, regulatory details, prices and testimonials before launch, and check your regulator's rules on publishing fees and reviews.

## Vibe-Code Ready Setup

This template includes `START-HERE-AI.md`, a product-specific copy-paste setup prompt for Cursor, Claude Code, ChatGPT, GitHub Copilot, Windsurf, and other coding assistants. It tells the assistant to inspect the existing stack, integrate the supplied files, preserve the design, scope selectors, retain accessibility and responsive behaviour, add framework-appropriate GSAP cleanup, and report what it tested.

[How AI-assisted setup works](https://gsapvault.com/vibe-coding)

## How It Works

### A word on a seam

Every page's masthead is one word set in a sharp display serif and cut horizontally through its middle where two flat colour fields meet: the page's colour above, paper below. The word is sized to fill the content width at any screen size. Change the word in the masthead markup and on the page wrapper and the layout follows; the home page uses two colours, vermilion over saffron.

### The page transition carries the word

Internal links fetch the next page and swap it in instead of reloading. A block in the destination's colour rises over the current page, the destination's word arrives in two halves from opposite sides and locks on the seam, and the block splits: the coloured half shrinks into the new masthead while the word lands on the masthead word, and the lower half drops away. Back and Forward close the block from both edges instead.

### Who we act for

On wide screens the home page pins a stage split into two colours. Scrolling slides each of four giant words into alignment, passes it on and cuts the seam to the next pair of colours, so the palette relays through the section. On phones and with reduced motion the four words simply stack, already aligned, with their captions.

### Practices, people and the enquiry

Practice rows are native disclosure elements that open as a saffron block with the matters covered, the fee basis and the lead partner. The people index filters by practice with buttons and announces the count. The enquiry form validates in the browser and then says plainly that nothing was sent, ready to connect to your form service.

### Fallbacks

Without JavaScript, from a local file or with the CDN blocked, every link loads its page normally and every word, list and form is visible. Reduced motion swaps pages instantly, shows the hero and the act-for words aligned and still, and removes the reveals.

## Documentation

How this template works and how it goes into a page. The reference you use once you own the files (worked examples, events, the programmatic API, the class list) ships with the download.

### Quick Start

Upload the folder to any static host and open `index.html`. Keep the fifteen 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, use any local static server (for example `python3 -m http.server` in the folder) 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 (Rufina and Red Hat Text) from Google Fonts. Images, styles and scripts are bundled locally.

### Using It With Your Own Design

1. **Identity.** Replace "Hollis Arden", the offices, phone numbers, email addresses and the fictional-firm note in the header and footer of each page (they are repeated in all fifteen files so each page stands alone). The footer ends on the top half of the firm name; change that word too.
2. **Words.** Choose the word each page opens on (see The Split Word). Short, confident words work best: SETTLED., EXPERTISE, a partner's surname.
3. **Photographs.** Swap the files in `assets/img/` keeping the names, or change the paths, and rewrite the alt text to describe your photographs.
4. **Practices and people.** Rename the six practice rows in `expertise.html`, copy `employment.html` for each practice that needs its own page, and copy `adaeze-okafor.html` for each person who needs a profile.
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, then remeasure the two metrics described under The Split Word.
6. **Enquiries.** Connect the contact form to your own service before taking real enquiries (see Enquiry 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 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` | SETTLED. hero on vermilion and saffron, the firm with four figures and a studio photograph, Who we act for, practices and sectors on saffron, three people, three insights, call to action |
| `expertise.html` | Six expandable practice rows (matters, fee basis, lead partner), eight sectors, call to action |
| `employment.html` | A practice page: both-sides lists, four-step process, fixed-fee table, team, related insights |
| `people.html` | Nine people with a practice filter; `?practice=employment` pre-selects a chip |
| `adaeze-okafor.html` | A partner profile: surname masthead, portrait, biography, contact, two client quotes, recent insights |
| `insights.html` | Featured article and a ruled list of eight, each linking to its article |
| `who-owns-the-work.html` | An article with author, list, pull quote and related reads |
| `fixed-term-contracts.html`, `shareholders-agreement-clauses.html`, `lasting-powers-of-attorney.html`, `letter-before-action.html`, `leasing-a-studio.html`, `separating-with-a-business.html`, `directory-rankings.html` | Seven more articles in the same layout, each with its own masthead word, byline and two related reads. To add one, copy an article, change the word and `--chars`, the copy and the row in `insights.html` |
| `contact.html` | Two offices with photographs, enquiry form |

Hooks you will meet in the markup:

- `data-page` wraps each page's header, main and footer. Its `data-word`, `data-label`, `data-tone` and `data-low` attributes are what the transition carries while that page loads: the word, the small caps label, the colour above the seam and the colour below it (`paper` unless set).
- `data-mast` is the masthead; `data-mast-top` is its coloured upper part and `data-mast-word` the h1 the arriving word lands on. `data-mast-chrome` marks the header and text blocks that fade in after a landing.
- `data-fit-scope` with `style="--chars: 8.1"` sizes a split word (see The Split Word). Optional `--word-max` caps it (default `18rem`).
- `data-tone="saffron"` on a link tells the transition which colour to rise in before the next page has loaded; `data-low` sets the lower colour (the home link uses `saffron`). Header links carry it already, so links to those pages without the attribute still get the right colour.
- `data-actfor`, `data-actfor-item` with `data-top` and `data-bot` colour names: the Who we act for sequence.
- `data-practice` on a `<details>` row; its `id` (`#employment`) opens it from a link.
- `data-filter`, `data-filter-chip="employment"` and `data-practices="employment"` on each person card: the people filter.
- `data-reveal` and `data-reveal-group` give a gentle rise on scroll; `data-hero-fade` and `data-split-in` mark the home hero's opening.

### The Split Word

A split word is the same word twice. The upper copy (the page's `h1`) hangs from the bottom edge of its box and the lower copy (marked `aria-hidden`) from the top edge of its box; both place the middle of their capitals exactly on that edge. Put the two boxes on different colours and the seam runs through the word.

To change a page's word, edit the `h1`, the hidden copy below it and the `data-word` on the page wrapper, then set `--chars`. It is the word's width in average Rufina capitals: start from the letter count, then adjust until the page looks the same with JavaScript off (narrow letters like I and L count for less, M and W for more; SETTLED. is 7.03, EMPLOYMENT 10.67). With JavaScript the script measures the word and fits it exactly, but a close estimate matters: Back restores scroll before the script refits, so a wrong estimate shifts the restored position by the difference.

The two metrics `--m` (0.4935) and `--cap-half` (0.334) at the top of the stylesheet are Rufina's: where the middle of a capital sits in a line-height 1 box, and half a capital's height. A different display face needs both remeasured, or the seam will miss the middle of the letters.

### Page Transition

Every same-origin link to a sibling `.html` page runs the same transition:

1. **Out.** A block rises from the bottom of the window: the destination's colour above, paper (or the page's lower colour) below. The colour comes from the link's `data-tone`.
2. **Hold.** The destination's word arrives in two halves from opposite sides and locks together on the seam, with its label above, while the next page is fetched and swapped in underneath.
3. **In.** The block splits. When the new page's masthead is in view, the coloured half shrinks until its edge sits on the masthead's seam and the word moves and resizes onto the masthead word, while the lower half drops away to reveal the page; the header and intro text then fade in. When the masthead is out of view (a link to `#fees`, or Back to a scrolled page) the two halves part off the top and bottom of the screen.

Back and Forward close the block from both edges instead of rising. Scroll positions are restored and the arriving page's heading receives focus and is announced.

Notes for editing:

- Pages are fetched, not reloaded, so scripts inside a fetched page do not run. Put new behaviour in `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` (`raise`, `showWord` and `split`); 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.
- With the next page already fetched (links prefetch on hover and focus) a transition takes about two seconds. On a slow connection the word holds until the page is ready. A second click before the new page is in place goes straight to that page from the covered screen.

### Who We Act For

On screens wider than 820px with motion allowed, the section pins for a few screens of scrolling. The first word slides into alignment as the section arrives; each further step passes the word on, cuts the seam to the next pair of colours and scrolls the next word into place. Edit the four `data-actfor-item` blocks: the word (twice), `--chars`, the caption, the practice line and the `data-top`/`data-bot` colours. On phones and with reduced motion the items stack, each on its own two colours, already aligned.

### Practice Rows and People Filter

Practice rows are native `<details>` elements, so they open and close with or without JavaScript. With motion allowed they open as a saffron block rising from the row's base. A link to `expertise.html#property` opens that row on arrival.

The people filter shows the cards whose `data-practices` contains the chip's key, updates the count in a polite live region and writes `?practice=` into the address so the filtered view can be shared. Give a person several practices with a space-separated list.

### Enquiry Form

The form on `contact.html` collects a name, email, optional phone, nearest office, matter type and a description. It uses the browser's own validation, then shows a status message saying nothing was sent. It is not connected to anything. Set the form's `action` and `method` for your form service (Formspree, Netlify Forms or your practice management system) and remove the `initEnquiry` call in `assets/script.js` if the service handles the response page.

### Palette

| Token | Default | Role |
| --- | --- | --- |
| `--paper` | `#FBFAF6` | Reading ground |
| `--ink` | `#161514` | All text, rules and outlined buttons |
| `--vermilion` | `#F0603F` | The firm: home, contact, calls to action (ink 5.6:1) |
| `--saffron` | `#F2B441` | Expertise and practice pages (ink 9.9:1) |
| `--sage` | `#A8C9B0` | People: index, profiles, card panels (ink 10.1:1) |
| `--lilac` | `#C6B7EA` | Insights and articles (ink 9.9:1) |

Each colour has a matching `-rgb` triple; change both. Secondary text is ink at 74% (7.6:1 on paper, 5.5:1 or better on saffron, sage and lilac). Vermilion takes ink at full strength only: dimmed text fails on it. Colours are always flat fields with ink on them; the template uses no tints, gradients or shadows. A new colour needs at least 4.5:1 against the ink.

Type is Rufina for the split words and serif statements and Red Hat Text for labels, rows, buttons and body copy.

### Accessibility and Fallbacks

- Real links everywhere, a skip link, visible focus, labelled form controls and one `h1` per page. The lower copy of each split word is `aria-hidden`; the `h1` carries a visually hidden continuation where the word alone would be unclear.
- The transition layer is `aria-hidden`. The arriving heading is focused and announced through a polite live region.
- Practice rows are native disclosures; filter chips are buttons with `aria-pressed`; the filter count is announced.
- Reduced motion swaps pages instantly, shows the hero and the act-for words aligned and still, and removes reveals.
- 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 fourteen cropped, graded WebP derivatives in `assets/img/`, listed with their sources in `assets/img-manifest.json`. Regenerate them from the manifest with the asset script used to build the template, or replace the files directly at the same names and sizes (portraits 800 × 1000, scenes 1600 × 1067).

All photographs are licensed through [Pexels](https://www.pexels.com/license/), which permits use in website templates. The portraits show models, not Hollis Arden's staff; the names are fictional.

| File | Source | Subject |
| --- | --- | --- |
| `person-adaeze-okafor.webp` | [Pexels 36439572](https://www.pexels.com/photo/36439572/) | Woman with curly hair laughing, black roll-neck |
| `person-tom-brennan.webp` | [Pexels 37148308](https://www.pexels.com/photo/37148308/) | Man in a dark suit and tie |
| `person-rohan-mehta.webp` | [Pexels 39974547](https://www.pexels.com/photo/39974547/) | Man in a tweed jacket |
| `person-ruth-calder.webp` | [Pexels 15780889](https://www.pexels.com/photo/15780889/) | Woman with grey hair in a black jacket |
| `person-sofia-marquez.webp` | [Pexels 38197025](https://www.pexels.com/photo/38197025/) | Woman with short hair smiling |
| `person-daniel-asante.webp` | [Pexels 12311581](https://www.pexels.com/photo/12311581/) | Man in a dark jacket |
| `person-jia-chen.webp` | [Pexels 20051635](https://www.pexels.com/photo/20051635/) | Woman in a black roll-neck, arms folded |
| `person-niamh-doyle.webp` | [Pexels 12421121](https://www.pexels.com/photo/12421121/) | Woman with hair up in a black jacket |
| `person-geoffrey-arden.webp` | [Pexels 29598496](https://www.pexels.com/photo/29598496/) | Older man with a grey beard in a suit |
| `office-manchester.webp` | [Pexels 34443169](https://www.pexels.com/photo/34443169/) | Red-brick and terracotta building, Manchester |
| `office-bristol.webp` | [Pexels 31005383](https://www.pexels.com/photo/31005383/) | Harbourside warehouses and bridge, Bristol |
| `studio-fitting.webp` | [Pexels 36731577](https://www.pexels.com/photo/36731577/) | Two women at a cutting table in a fashion studio |
| `meeting-window.webp` | [Pexels 12903168](https://www.pexels.com/photo/12903168/) | Two women planning at a window and whiteboard |
| `designer-desk.webp` | [Pexels 7147665](https://www.pexels.com/photo/7147665/) | Designer at a laptop with an open sketchbook |

The portraits were converted to black and white so a mixed set of studio backdrops reads as one series against the flat colour panels; the scenes are lightly desaturated.

## What You Get

- `index.html`: working demo page
- `assets/script.js`: commented, readable source
- `assets/style.css`: effect styles
- `README.md`: full documentation with examples and framework integration notes
- `START-HERE-AI.md`: product-specific copy-paste prompt for AI-assisted setup
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This is a premium template, not sold individually: it comes with the Templates Pass or the Vault. The standard licence covers unlimited personal and commercial projects with no attribution required for our code. Bundled third-party assets retain their own licences and attribution requirements. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Templates Pass (£50 one-time): every current and future premium template](https://gsapvault.com/pricing)
- [The Vault (£99 one-time, best value): every collection in the Vault library, plus future items added to those collections](https://gsapvault.com/effects)

---

From [GSAP Vault](https://gsapvault.com): production-ready GSAP animation effects. Full catalog for agents: https://gsapvault.com/llms-full.txt
