# Barber Shop Template

> A complete one-page site for a barber shop, built on an aubergine ground with heavy slab type, and a three-step booking flow with a running summary as its signature.

Canonical: https://gsapvault.com/templates/barber-shop-template
Live demo: https://gsapvault.com/demos/barber-shop-template/index.html

| Property | Value |
|----------|-------|
| Type | template |
| Tier | paid |
| Price | £5 |
| Difficulty | intermediate |
| Plugins | ScrollTrigger |
| Techniques | scroll-reveal, stagger, text-animation, click-toggle, timeline-control |
| Uses Lenis | Yes |

## Overview

A production-ready site for a barber shop that deliberately refuses everything the category usually does. There are no poles, no crossed razors, no gold script and no dark wood: the whole thing runs on an aubergine ground with oat type and one burnt orange accent, set in a heavy slab display face, so it reads as a modern graphic identity rather than a vintage pastiche. The signature is the booking flow: a visitor picks a barber, then a service, then a slot, with the panel animating its own height between the three steps and a paper ticket alongside keeping a running summary of the choices and the price. Slot availability is read from the chosen barber's diary, so changing barber genuinely changes which times are free, and the final step issues a booking reference. It is a front-end demo with no backend behind it, but every part of it behaves as though there is one. The copy is written for a fictional Newcastle shop in a dry, unsentimental voice, and the photography is bundled as art-directed WebP derivatives baked to a punchy, high-contrast, full-colour grade.

## Features

- Complete deployable one-page site: nav, hero, price list, booking flow, barbers, the shop, hours and visit details, footer
- Signature booking flow: barber, service and slot chosen across three animated steps, with back and forward movement and nothing confirmed until the last screen
- Running summary ticket that updates as choices are made, works out the end time from the service length and totals the price
- Slot availability driven by the chosen barber's diary: change barber and the taken times change with it, releasing a slot that is no longer available
- Confirmation step issues a booking reference and lists what was booked, with a Book another control that resets the flow
- Book with this barber buttons on the barber cards fill step one in and drop the visitor onto the service step
- Built on native radio groups, so keyboard support comes from the browser: arrow keys move within a step, Enter moves the flow on, focus follows the step and a live region announces each one
- Bundled shop and barber photography baked to a punchy full-colour grade, around 600KB total
- Three-colour token block: change aubergine, oat and burnt orange and the whole site reskins
- Lenis smooth scrolling wired in and fully optional
- Accessible: the whole booking flow reads as three plain lists with a phone number when JavaScript is unavailable, and keeps working with no animation under reduced motion

## Use Cases

- Barber shops, salons and grooming studios
- Tattoo studios, nail bars and piercing shops that book by artist
- Any appointment business where the customer picks a person, a service and a time
- Independent clinics and treatment rooms with a short price list
- Small venues that want a booking enquiry flow without a booking platform

## How It Works

One script initialises each section inside a single gsap.context with gsap.matchMedia, keyed only on reduced motion so exactly one branch runs on every device, and every section is guarded so a buyer can delete any of them. The booking flow's entire data model is three native radio groups: without JavaScript all three render as readable lists, and with it the script hides all but one step and takes over the chrome. Moving between steps measures the panel, swaps the hidden attributes, measures again and tweens the panel between the two heights so the page below never jumps, while the incoming step slides and fades in. The summary is derived from the checked inputs rather than a parallel state object, so it can never disagree with the form; the end time is worked out by adding the service's data-mins to the slot's data-time. Each slot carries a data-taken list of barber keys, and the slot step re-reads it every time it is shown, disabling the times taken in that chair and releasing a chosen slot that is no longer available. Focus moves to each step as it appears and a polite live region announces the step number and its prompt. Every JavaScript hook is a data attribute or a single plain class, and every masked reveal tweens the same transform property its CSS start state sets.

## Integration Preview

How this effect integrates into a page. The full documentation (examples, events, programmatic API, customization guide) ships with the download.

### Quick Start

**1. Copy the folder** into your project or straight onto your host. That is the whole deploy — there is nothing to build and nothing to install.

```
barber-shop-template/
├── index.html
├── README.md          ← these notes
├── LICENSE.txt        ← your licence, keep it
└── assets/
    ├── style.css
    ├── script.js
    ├── img-manifest.json   ← a record of where the photographs came from
    └── img/                ← eight WebP photographs
```

`README.md` and `img-manifest.json` are notes rather than site files, so nothing breaks if you delete them once you are done reading. Keep `LICENSE.txt`.

**2. Replace the copy** in `index.html`. Every section is a plain `<section>` with a comment header, so search for the section name and edit the text in place.

**3. Pick a palette.** The template ships with five (see [Palettes](#palettes) below). To use one of the four alternates, set `data-palette` on the `<html>` tag; to stay on the default aubergine, do nothing.

**4. Or change the palette outright** in `assets/style.css`. The whole site reskins from the first token block:

```css
:root {
    --ground: #33203A;        /* the page */
    --ground-deep: #251729;   /* the deeper band */
    --lift: #402849;          /* raised surfaces: rail chips, image beds, ghost wordmark */
    --hover: #2B1A31;         /* hover beds */
    --type: #F0E9DC;          /* every piece of type on the ground */
    --accent: #EC6733;        /* the one accent */
    --on-accent: #1E1223;     /* type sitting on a solid accent fill */
    --paper: #F0E9DC;         /* the booking ticket */
    --on-paper: #1E1223;      /* type on the ticket */
}
```

Three colours do all the work: a ground, a type colour and one accent. The other six are those three at a different value, which is what keeps the page to three. Everything after them (`--rule`, `--dim`, `--accent-wash`, `--nav-bg` and the rest) is derived and needs no editing.

Two things to know if you change these:

- **Keep the RGB triples in step.** The translucent tokens are built from `--type-rgb`, `--accent-rgb`, `--on-accent-rgb`, `--on-paper-rgb` and `--ground-deep-rgb`, which restate five of the colours as `R, G, B`. Change a colour, change its triple.
- **`--hover` moves away from the accent, not towards it.** Accent-coloured type sits on hovered rows, so on a dark ground `--hover` is slightly *darker* than `--ground`, and on a light ground it is slightly *lighter*. Going the other way is what quietly drops a hovered price below AA.

Contrast to check after any change: body type on the ground, the small mono annotation type (`--dim`, the most at-risk thing on the page), `--on-accent` on a solid `--accent` fill, and `--accent` used as small text on the ground. All four want 4.5:1 or better. The five shipped palettes are all measured at that bar, so they double as worked examples.

#### Optional: minify before you go live

`assets/script.js` is the readable source and is what `index.html` loads. It is around 22KB, which is fine to ship as-is. If you would rather serve it minified, produce it yourself once your edits are done:

```bash
bunx terser assets/script.js -c -m -o assets/script.min.js
```

Then point the last `<script>` tag in `index.html` at `assets/script.min.js`. Keep `script.js` as the file you edit and re-run the command after each change, otherwise the two quietly drift apart.

---

### Accessibility

- **No JavaScript**: the booking flow renders as three readable lists of barbers, services and times, with the shop's phone number and email as the way to book. The step rail, the Next and Back controls and the ticket all stand down, because none of them can do anything without the script. Reveal targets are only hidden once GSAP is confirmed present, so a blocked CDN leaves a fully visible page rather than a blank one.
- **Reduced motion**: handled in both the CSS media query and a `gsap.matchMedia` branch. The booking flow keeps working exactly as it does otherwise — it simply swaps steps instantly instead of animating. Nothing is hidden and nothing is unreachable.
- **Keyboard**: the options are native radios, so arrow keys move within a step and Enter moves the flow on. Focus moves to each step as it appears, the focus ring is drawn on the option itself, and there is a skip link.
- **Screen readers**: each step is a `<fieldset>` with a `<legend>`, the rail marks the active step with `aria-current="step"`, and a polite live region announces "Step 2 of 3, choose a service" and the confirmation. Unavailable slots are genuinely `disabled`, not just styled.
- **Touch**: nothing in the flow depends on hover. The hover states on the price list and the options are decoration only.
- **Colour**: every shipped palette was measured at 4.5:1 or better for body type, the small mono annotation type, type on a solid accent fill, and the accent used as small text — on each surface those actually land on, hover and chosen states included. No state in the booking flow is signalled by colour alone: a chosen slot takes a solid accent fill *and* reads "Chosen", and an unavailable one is `disabled`, dashed and struck through as well as dimmed.

---

### Dependencies

Loaded from CDN in `index.html`:

- GSAP 3.14.2
- ScrollTrigger 3.14.2
- Lenis 1.3.17 (optional smooth scroll)

To drop Lenis, delete its `<script>` tag. The script checks for it and carries on without it.

Fonts: Alfa Slab One (display), Plus Jakarta Sans (body), Overpass Mono (annotation), all from Google Fonts.

## 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
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This is a premium template. The standard license costs £5 one-time and covers unlimited personal and commercial projects with no attribution required. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Barber Shop Template](https://gsapvault.com/templates/barber-shop-template)
- [All-Access Bundle (£29 one-time, best value): every current and future effect and template](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
