# Coffee Roaster Template

> A complete one-page shop for a small coffee roaster, built on an espresso ground with one acid-green accent, and a working demo basket with a fly-to-basket arc, grind selection and a live subtotal as its signature.

Canonical: https://gsapvault.com/templates/coffee-roaster-template
Live demo: https://gsapvault.com/demos/coffee-roaster-template/index.html

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

## Overview

A production-ready shop for an independent coffee roaster, and the first multi-product commerce template in the library. It refuses the kraft-brown-and-tan packaging look the category defaults to: the whole site runs on a deep espresso ground with oat type and a single acid-green accent, set in a high-contrast serif against a grotesk and a mono that carries nothing but roast data. The hero is the shop rather than a picture of one: there is no hero photograph, just all six coffees standing at scale on a drawn shelf, with this week's lot written out as its real roast log and buyable above the fold. The product range is the spine of the page rather than a grid bolted onto a marketing landing page, and the signature is a genuinely working basket. Adding a bag flies a ghost of the bag artwork on an arc into the basket button, the count bumps, and a slide-out drawer holds real line items with quantity steppers, a per-bag grind choice, remove controls and a live subtotal with a free-delivery threshold. The bags themselves are drawn in CSS, so a buyer's own products need no photography, while the roastery imagery is bundled as art-directed WebP derivatives baked to a warm espresso duotone. The copy is written for a fictional Leeds roaster in a plain, technical voice, with a real roast log on every bag.

## Features

- Complete deployable one-page shop: nav with basket, shelf hero with a buyable featured lot, six-product range, roasting explainer, subscriptions, visit details, footer
- Signature demo basket: a slide-out drawer with line items, quantity steppers, per-bag grind selection, remove controls and a live subtotal
- Fly-to-basket arc built from two tweens of the same duration with different eases, so the ghost lobs over rather than sliding, with no extra plugin to load
- One Map is the entire state: the drawer, the header count, the subtotal, the delivery bar and the in-basket badges are all written from it, so they cannot disagree
- Grind changes merge rows rather than duplicating them, so the same coffee ground the same way is always one line
- Free-delivery progress bar that counts down the amount still needed
- Coffee bags drawn entirely in CSS, with a crimped seam, a degassing valve, the coffee's initial and a roast-level meter: change a letter and a data attribute for a new product
- Real roast logs on every bag (charge, first crack, drop, development ratio) and a roasting section that explains what the four numbers mean
- Bundled roastery photography baked to a warm espresso duotone, around 390KB total
- Three-colour token block: change espresso, oat and acid green and the whole site reskins
- Lenis smooth scrolling wired in and fully optional
- Accessible: focus trap, Escape to close, focus returned to the trigger, a polite live region for every basket change, and a full keyboard path through the drawer
- Degrades completely: with JavaScript off there is no basket UI on the page at all, and every product carries a phone and email ordering route instead

## Use Cases

- Coffee roasters, tea merchants and other small-batch producers selling several products
- Any independent shop with a short, curated product range rather than a catalogue
- Bakeries, delis, breweries and farm shops taking orders for a handful of lines
- Subscription products where a plan sits alongside one-off purchases
- A front end to hand to a developer wiring up Stripe, Shopify or Snipcart behind it

## 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 basket deliberately sits outside that context and does not depend on GSAP at all, so a blocked CDN costs the shop its animation and nothing else. Its state is one Map keyed by SKU and grind, because the same coffee ground two ways is two things to pick and pack; every other number on the page is derived from that Map by a single render pass that rebuilds the drawer list from a <template> in the markup, so the classes stay in the HTML and no selector is ever built at runtime. Product facts are read once from data attributes on the cards, so editing a price in the HTML is enough. The fly-to-basket arc clones the CSS bag artwork, positions it from a measured rect, and runs two same-duration tweens with different eases, which bows the path above the straight line without a motion-path plugin; under reduced motion the ghost is skipped entirely and the state simply changes. The drawer traps Tab in both directions, closes on Escape, returns focus to the trigger, stops Lenis while open and carries data-lenis-prevent on its scrolling list. 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 whole folder to your server. It is static — no build step, no bundler, no dependencies to install.
2. Open `index.html` and replace the copy, prices and contact details.
3. Open `assets/style.css` and change the nine values in the `:root` palette block to reskin the site.
4. Replace the photographs in `assets/img/` (see [Photography](#photography)).

The page loads GSAP, ScrollTrigger and Lenis from a CDN in `index.html`. It works without any of them — see [Degradation](#degradation).

---

### Accessibility

- The drawer is a `role="dialog"` with `aria-modal="true"`, traps Tab in both directions (including pulling focus back if it starts outside), closes on Escape, and **returns focus to the button that opened it**.
- Its scrolling list carries `data-lenis-prevent`, so a mouse wheel scrolls the basket rather than the page behind it. That hands the wheel event back to the browser, so the list also carries `overscroll-behavior: contain` and the document is pinned while the drawer is open — otherwise a scroll that runs off the end of the list chains onto the page behind.
- A polite live region announces every basket change: what was added, the new quantity, a grind change, a removal, and the running total.
- The basket button's own `aria-label` carries the count and subtotal, so the green badge is decoration rather than the only signal.
- Focus is moved deliberately after every rebuild of the list — changing a grind hands focus to the same control on the row's replacement rather than dropping it to the body.
- Quantity steppers carry per-product `aria-label`s ("Increase quantity of Kirinyaga AB"), not bare "+" and "−".
- Visible focus rings throughout, a skip link, and the roast curve has a text alternative describing what it shows.

### Dependencies

| | | |
|---|---|---|
| GSAP 3.14.2 | required for animation only | https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js |
| ScrollTrigger 3.14.2 | scroll reveals and the photo drift | https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/ScrollTrigger.min.js |
| Lenis 1.3.17 | optional smooth scroll | https://unpkg.com/lenis@1.3.17/dist/lenis.min.js |

Remove the Lenis tag and the page uses native scrolling; the script checks for it before use.

## 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 Coffee Roaster Template](https://gsapvault.com/templates/coffee-roaster-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
