Overview

Espressa template home pages

A warm, animated HTML template for coffee roasters, espresso bars and specialty coffee brands. Espressa ships three home pages, a light and a dark theme, right-to-left support, and coffee logic that is worked out rather than typed in: every bag priced by roast, grind and size, a coffee club builder that prices each delivery, a brew-ratio calculator and timer, every bar’s hours with open now, classes with their next dates and seats, and a wholesale estimator.

What’s included

  • 3 home pages, each with its own scroll moment: Green To Roasted (a tray of beans darkens through the roast as the band travels), The 25-Second Shot (the dial, the yield and the phases of one espresso) and the Origins Strip (seven origin cards slide sideways)
  • Light and dark mode on one switch in every header, remembered between visits and applied before the page paints
  • Right-to-left stylesheets and a flag language picker in every header: a right-to-left language turns any page around
  • WebGL layers — grind grain at the dark bands’ edges and a roasted bean turning in light in the footer — tinted by the theme colours
  • The bean shop: filters by type and roast, a price ceiling, search and sort; the product page prices roast, grind, bag size and quantity
  • The coffee club builder in six steps, with a live price per delivery, every four weeks, the saving and the first dates
  • The brew guide: seven methods, dose and ratio to water, cup, grind and temperature, and a stage-by-stage timer
  • Bar hours with open now, a bar menu with filters and search, classes with seats and booking, origins with a harvest calendar, a wholesale estimator
  • Bag, coupon, free-shipping meter, tax, checkout with an order number and roast date, wishlist
  • Team and profile, services, gallery, FAQ with search, journal with post formats, account pages, coming soon, 404
  • Bean Pile preloader, Diagonal Pour reveals, word-by-word titles, Swiper sliders and Fancybox galleries
  • Fully responsive, W3C-valid, zero console errors
📄 31 HTML files

Getting Started

Thank you for choosing Espressa. Follow the steps below to get your site live.

1. Open locally

Unzip the downloaded package and open espressa/index.html in any modern browser (Chrome, Firefox, Edge, Safari). No build tools or server are required — the shop, the club builder, the brew timer, the classes and the estimators all work straight from the files.

2. Deploy to a server

Upload the contents of the espressa/ folder to your hosting provider using an FTP client (such as FileZilla) or your hosting control panel. Once uploaded, navigate to your domain and the template will load immediately.

3. Customise

All custom styling lives in assets/css/style.css (with a numbered Table of CSS at the top) and assets/css/responsive.css. Colours and fonts are controlled by CSS variables — see Colors & Fonts. Beans, prices, the club, brew methods, bars, the menu and classes live in one place — see Coffee Logic.

Tip: Replace the neutral placeholder images in assets/img/ with your own photography at the same dimensions for the best result. The bean bags in img/shop/ are transparent PNGs on a pale grey card; keep yours square and transparent.

File Structure

Below is an overview of the key files and folders included in this template.

index.html / homepage-2.html / homepage-3.htmlThree home pages: Roastery (Green To Roasted), Espresso Bar with the side header (The 25-Second Shot), Coffee Club (the origins strip)
shop.html / product-single.htmlThe bean shop with filters, roast, price, search and sort; a bean with roast, grind and bag size
subscription.htmlThe coffee club builder: six steps and a live summary
cart.html / checkout.html / wishlist.htmlBag, checkout with an order number and roast date, wishlist
origins.html / origin-details.htmlSeven origins and the harvest calendar; one origin with its facts and bean
brew-guide.htmlThe brew-ratio calculator and timer, and the grind size guide
menu.htmlThe bar menu with filters and search, extras, the bars today
classes.html / class-details.htmlClasses sorted by their next date; one class with the seat booking
locations.htmlThe three bars with their week of hours, open now and the map
about.htmlThe roastery’s story, numbers, how we roast, a tour band and the team
team.html / team-details.htmlThe team and open roles; a roaster profile
services.html / service-details.htmlWhat we offer; wholesale with the estimator and a tasting enquiry
gallery.htmlPhotographs with filters and a lightbox
faq.htmlQuestions by topic with search
blog.html / blog-details.htmlThe journal with post formats; an article with reading time, share and comments
contact.htmlContact cards with live hours, the contact form and the map
login.html / register.html / forgot-password.htmlAccount pages
coming-soon.html / 404.htmlCountdown to the new bar’s first morning, error page
sendmail.phpAJAX mail handler for the contact and comment forms (see Contact Form)
assets/css/style.cssAll custom styles, numbered Table of CSS (18 sections)
assets/css/responsive.cssDesktop-first breakpoints 1399 / 1199 / 991 / 767 / 575, plus wide screens from 1600 and 1960 and the side header from 1200
assets/css/style.rtl.css / responsive.rtl.cssThe right-to-left twins (see RTL)
assets/css/plugins/Bootstrap (LTR and RTL), Swiper, Fancybox (vendor CSS)
assets/js/main.jsAll custom scripts, numbered JS INDEX (33 blocks)
assets/js/plugins/jQuery, Bootstrap, Swiper, Fancybox, GSAP, ScrollTrigger
assets/img/Images, one folder per section (see Images)
assets/fonts/theme-icons/The sun and moon of the theme switch, loaded locally
assets/webfonts/ + assets/css/fontawesome-all.cssFont Awesome Free, loaded locally

Folder Structure

The package unzips to two folders: Documentation/ (this guide) and espressa/, the template. Every page sits in the template’s root; everything the pages load sits under assets/:

espressa/
├── *.html                              the 31 pages, all in the root (see File Structure)
├── sendmail.php                        the AJAX mail handler for the forms
└── assets/
    ├── css/
    │   ├── style.css                   all custom styles, numbered Table of CSS
    │   ├── style.rtl.css               the right-to-left twin of style.css
    │   ├── responsive.css              breakpoints 1399 / 1199 / 991 / 767 / 575
    │   ├── responsive.rtl.css          the right-to-left twin of responsive.css
    │   ├── fontawesome-all.css         Font Awesome Free, loaded locally
    │   └── plugins/                    vendor stylesheets
    │       ├── bootstrap.min.css
    │       ├── bootstrap.rtl.min.css   Bootstrap for right-to-left pages
    │       ├── jquery.fancybox.min.css
    │       └── swiper-bundle.min.css
    ├── js/
    │   ├── main.js                     all custom scripts, numbered JS INDEX (33 blocks)
    │   └── plugins/                    vendor scripts
    │       ├── bootstrap.bundle.min.js
    │       ├── gsap.min.js
    │       ├── jquery-3.7.1.min.js
    │       ├── jquery.fancybox.min.js
    │       ├── ScrollTrigger.min.js
    │       └── swiper-bundle.min.js
    ├── fonts/
    │   └── theme-icons/                the sun and moon of the theme switch
    ├── webfonts/                       Font Awesome Free font files
    └── img/                            images, one folder per section
        ├── banner/                      13 files
        ├── blog/                        11 files
        ├── flags/                       6 files
        ├── gallery/                     24 files
        ├── home/                        16 files
        ├── icons/                       42 files
        ├── logo/                        4 files
        ├── menu/                        3 files
        ├── ornaments/                   4 files
        ├── shop/                        14 files
        ├── team/                        11 files
        └── textures/                    1 files

To publish the site, upload the contents of espressa/ to your web root. Photos keep their folder, file name and size when you replace them, so no page needs editing.

Colors & Fonts

The whole design is driven by CSS variables declared at the top of style.css. Change a token once and every section, button and card updates. Colours used with transparency have an -rgb twin (for example --es-tan-rgb) — change both together.

Tan--es-tan
Tan Deep--es-tan-deep
Tan Text--es-tan-text
Espresso--es-espresso
Cream--es-cream
White Ground--es-bg
Kraft Paper--es-kraft
Paper--es-paper
Heading--es-heading
Body--es-text
Muted--es-muted
Packshot Ground--es-product

Tan fills the buttons, the bean divider under every title and the active states; buttons carry espresso text on tan. Tan Text is tan’s partner for small text on light grounds. Espresso is the ink of the hero washes, the night bands and the footer; cream is the copy on them. White and kraft paper alternate as the section grounds, and the packshot ground sits behind every bag. --es-bg, --es-surface, --es-heading and --es-text are the semantic names the components use — the dark theme swaps those (see Light & Dark Mode).

Fonts

Two Google Fonts are loaded in the head of each page: Marcellus (the caps headings, the menu, prices and figures) and Open Sans (body text, labels and buttons). Swap them by editing the Google Fonts link and the --es-ff-head / --es-ff-body variables.

Logo

The logo is the name ESPRESSA in caps inside a rounded plate, with a roasted bean sitting in a gap of the plate’s top edge. It ships as ready-made PNG files in assets/img/logo/:

  • logo.png — espresso ink for light grounds: the kraft headers, the offcanvas, light mode
  • logo-light.png — cream ink for dark grounds: the headers over photographs, the footer, dark mode
  • seal.png — the round ESPRESSA · COFFEE ROASTERS · EST. 2009 stamp on the heroes and banners
  • favicon.png — the browser tab icon

The logo’s lettering appears only inside the images. To use your own logo, replace these files; the header sizes the logo by its height, so a wider or narrower file needs no CSS change.

Light & Dark Mode

Every header (and the mobile menu) has a theme switch. The choice is saved in the browser under the key espressa-theme and applied by a one-line script in the <head> before the page paints, so a dark visitor never sees a light flash. The switch sets data-theme="dark" on the <html> tag.

Dark Ground--es-bg
Dark Surface--es-surface
Dark Kraft--es-kraft
Dark Night Band--es-night
Dark Heading--es-heading
  • Tokens — the dark values sit in one block, [data-theme="dark"] { … }, right after :root in style.css. Change a dark colour there.
  • Bands that stay dark — sections with the class is-night (The 25-Second Shot, the hours band, the brew timer, the footer) are dark in both themes. A light card placed inside one takes es-on-light to keep its own ink.
  • Illustrated icons and ornaments — each ships in a day and a night ink; the right one shows by theme and ground on its own.
  • Start dark — to open the site dark for first-time visitors, add data-theme="dark" to the <html> tag of each page; the switch still works and is still remembered.

Coffee Logic

The figures on every page come from one data block, JS block 09 Roast Data near the top of main.js (var ROAST). Edit it once and the cards, prices, timers, calendars and totals follow. Prices are in US dollars.

productsThe beans with origin, region, farm, altitude, process, varietal, notes, the default roast, the roasts offered and a price for each bag size; brew gear with one price.
roasts / grinds / sizesRoast levels with their drop temperature and bean colour; grind sizes in microns with what they suit; bag sizes.
clubThe coffee club’s styles (each tied to a bean), frequencies with their discount, and the most bags in one box (4).
roastDays / shipDaysThe roaster fires on Tuesday and Friday; orders ship the same day and arrive 2 days later. Checkout and the club show these dates.
methodsBrew methods with a default dose, a ratio range and timed stages; each stage says when it starts and how much of the water is in by its end.
barsThe espresso bars with address, phone and hours for each weekday in minutes after midnight (420 = 7:00 am); null is a closed day.
menu / menuGroupsThe bar menu: drink, group (the filter tabs), price and photo.
classesClasses repeating weekly on a weekday or monthly on the first of a weekday, with the start time, length, seats and price.
roastStages / extractionThe stages of a 12-minute roast (Home 1’s tray) and the phases of a 25-second shot (Home 2’s dial).
originsThe seven origins with altitude, process, harvest months (the harvest calendar) and their bean.
wholesaleWholesale coffees with a price a kilo, tier discounts by kilos a week, free delivery from 20 kg.
shopThe shop rules: free shipping from $45, otherwise $6.50 (express $14.00), tax 8%, coupon FIRSTCRACK for 15% off.

Pricing a bag

Worked example: Yirgacheffe Kochere at 500 g is $29.00 a bag; two bags make a line of $58.00. The roast and the grind travel with the line, so the same bean ground two ways sits on two lines.

The coffee club

Worked example: House Espresso, two 500 g bags every week: $25.00 × 2 less 15% = $42.50 a delivery, $170.00 every four weeks.

The brew timer

Worked example: V60 with 15 g of coffee at 1 : 16 = 240 g of water, about 210 ml in the cup. The timer runs Bloom at 0:00, First Pour at 0:45, Second Pour at 1:15, Drawdown at 1:45 and tells you how much water should be in at every second.

How the shop totals

Worked example: House Espresso 250 g ($14.00) and Yirgacheffe Kochere 500 g ($29.00) = $43.00; shipping $6.50; tax 8% $3.44 — $52.94. With the coupon FIRSTCRACK: $43.00 − $6.45, shipping $6.50, tax $2.92 — $45.97.

Wholesale

Worked example: 30 kg a week of House Espresso at $38.00 a kilo, 8% tier discount = $1,048.80 a week.

The bag, the wishlist and the applied coupon are kept in the browser (localStorage), so they follow the visitor from page to page. The first visit starts with a small demo bag and wishlist so every shop page has something to show; to start empty, set the two demo lists in doShop() (block 24 Bean Shop) to []. Checkout, the club, class bookings and the wholesale enquiry confirm on screen with a reference — connect them to your own systems to take real orders and bookings.

WebGL Layers

Two small WebGL shaders draw the moving layers: the grain — a fine speckle of coffee grounds drifting at the dark bands’ edges (the shot band, the club band, the hours band, the footer, coming soon, 404) — and the bean — a ray-marched roasted bean, its crease cut down the flat face, turning in a warm key light in the footer. Each is one canvas:

<canvas class="es-gl" data-gl="grain" aria-hidden="true"></canvas>
  • Colours — each layer reads three colours and an opacity from CSS variables on its canvas or section: --gl-1, --gl-2, --gl-3 and --gl-alpha. The theme switch repaints them.
  • Performance — a layer only runs while its section is on screen and the tab is visible. Visitors who prefer reduced motion get one still frame. Without WebGL, the section’s own background shows.
  • Remove one — delete the canvas; nothing else depends on it.

RTL (Right To Left)

Espressa is RTL-ready: the layout with its paddings and margins, the side header, the sliders and the animations all mirror. Right to left comes from the stylesheets, not from separate pages: the language picker (a flag and a code) lists the languages that read left to right and right to left. Choosing Arabic stores the language and the direction (keys espressa-lang and espressa-dir) and reloads; the one-line script in <head> then sets dir="rtl" and swaps the three stylesheets for the files named in their data-rtl attribute before the page paints. Nothing is translated — you bring your own right-to-left copy. To make a page right to left for good:

1. Set The Direction

Add dir="rtl" to the page’s <html> tag (and set lang to your language):

<html lang="en" class="no-js" dir="rtl">

2. Swap Three Stylesheets

assets/css/plugins/bootstrap.min.css→ assets/css/plugins/bootstrap.rtl.min.css
assets/css/style.css→ assets/css/style.rtl.css
assets/css/responsive.css→ assets/css/responsive.rtl.css

The scripts read the direction from the dir attribute: sliders, the origins strip and every move that must mirror follow it on their own. The harvest calendar keeps January on the left.

Editing the styles: style.rtl.css and responsive.rtl.css are mirrored twins of the LTR files, made with RTLCSS. A few hand-made rules at the end of style.rtl.css (after RTL fixes) keep what must not mirror. If you change style.css, regenerate the twin with npx rtlcss style.css style.rtl.css and copy the RTL fixes block back to its end.

JavaScript Guide

All custom behaviour lives in assets/js/main.js, wrapped in a jQuery IIFE and organised into 33 numbered blocks (see the JS INDEX comment at the top of the file):

  • 01–08 — Preloader, Sticky Header, Offcanvas Menu, Scroll Reveals, Back To Top, Anchor Scroll, Light & Dark Mode, Direction, WebGL Layers. The core every page shares: the Bean Pile preloader, the header, the reveals, the theme and direction switch and the WebGL layers.
  • 09–10 — Roast Data, Bar Hours. Roast Data holds every figure; Bar Hours works out open now and the next opening of every bar.
  • 11–19 — Custom Select, Counters & Rings, Hero Sliders, Card Sliders, Accordion, Filter Tabs, Grid Search, Newsletter, Choice Cards. Shared components: selects, counters, sliders, accordions, filters, search, forms.
  • 20–22 — Green To Roasted, The 25-Second Shot, Origins Strip. The three home pages’ scroll moments.
  • 23–33 — Contact Form, Bean Shop, Account Forms, Article Tools, Demo Forms, Launch Countdown, Coffee Club Builder, Brew Ratio Timer, Classes & Cuppings, Wholesale Estimator, FAQ Search. The feature pages: contact, the bean shop, accounts, the coffee club builder, the brew timer, classes, the wholesale estimator, FAQ.

Each block is a self-contained doSomething() function that safely skips pages where its section is not present — you can delete any block you do not need. Every animation respects prefers-reduced-motion automatically: content appears in its final state and the scrubbed scenes rest in place.

Reveals: add es-pour to a photo or card so it is uncovered along a diagonal sweep, es-fade to text so it rises, and es-words to a heading so its words rise one by one. data-delay="0.2" staggers any of them. The bean divider under a title draws its hairlines on its own.
Scroll moments: Green To Roasted colours the tray’s beans from roastStages as its band travels; The 25-Second Shot sweeps the dial and counts the yield from extraction; the Origins Strip slides its track by the band’s own scroll. None of them pins the page.
Countdown: the coming-soon page counts down to 7:00 am on the next 20 March, the first day of spring — no date to update. Change it in doLaunchCountdown().

Images

The download package ships with neutral placeholder images so you can see every layout at the correct dimensions. Replace them with your own photos using the same file names, or update the src attributes. Images are grouped inside assets/img/:

img/banner/Wide hero, page-title and photo-band photographs — 13 files: 3520×1375, 3464×1353, 3436×1346, 2560×780, 3604×1408, 3048×1353, …
img/blog/Journal posts and article photos — 11 files: 1300×1050, 1300×820
img/flags/The language picker’s flags (SVG, included) — 6 files: SVG
img/gallery/Gallery, origins and menu photos — 24 files: 1300×900, 1100×1065
img/home/Home page photos: mosaics, hours tiles, bars, story pairs — 16 files: 800×800, 1100×1100, 1038×1038, 550×550, 1100×690, 800×545, …
img/icons/Illustrated line icons, each in a day and a night ink — 42 files: 128×128
img/logo/Logo, light logo, seal and favicon — 4 files: 324×112, 64×64, 300×300
img/menu/Home previews in the mega menu — 3 files: 560×350
img/ornaments/The bean divider and the coffee sprig, day and night inks — 4 files: 88×56, 440×240
img/shop/Bean bags and brew gear packshots — 14 files: 800×800
img/team/The team and the round review portraits — 11 files: 800×800, 320×320, 1047×1047
img/textures/The kraft paper fibres laid over the kraft bands — 1 file: 900×900

The logo files, the seal, the illustrated icons and ornaments, the kraft paper texture and the language flags are included and ready to use. All demo photography shown on the live preview is for preview purposes only and is not included in the download.

Contact Form

The contact form and the comment form post to sendmail.php, a lightweight AJAX mail handler. The success or error message appears under the button without reloading the page. The newsletter, checkout, coffee club, class booking, wholesale, login, register and forgot-password forms are demo forms: they confirm on screen and are ready to connect to your own systems. To activate the mail handler on your server:

1. Set your email address

Open sendmail.php and replace the placeholder recipient at the top of the file with your own address:

$email = 'example@example.com';

2. Upload to a PHP host

The form needs a server with PHP mail() support (virtually every shared host). It will not send from your local computer or from a static-only host — there the form shows a friendly “upload to a PHP-enabled host” notice instead.

3. Optional: enable Google reCAPTCHA v3

Invisible reCAPTCHA v3 spam protection is already built into the handler. It stays dormant until the form submits a token — that is why no badge or checkbox appears out of the box. To switch it on:

  • Create v3 keys (a site key and a secret key) for your domain in the Google reCAPTCHA admin console
  • In sendmail.php, replace YOUR_RECAPTCHA_V3_SECRET_KEY with your secret key
  • In contact.html, add a hidden token field inside the form and load the reCAPTCHA script with your site key just before </body>:
<!-- inside the form -->
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response">

<!-- before the closing </body> tag -->
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
<script>
  grecaptcha.ready(function () {
    grecaptcha.execute('YOUR_SITE_KEY', { action: 'contact' }).then(function (token) {
      document.getElementById('g-recaptcha-response').value = token;
    });
  });
</script>

Once the token field is present, sendmail.php verifies every submission with Google and rejects low-score (bot) requests.

Credits

This template is built using the following open-source libraries and resources.

  • Bootstrap 5.3.3
  • jQuery 3.7.1
  • Swiper 11
  • GSAP 3 + ScrollTrigger
  • Fancybox 3.5
  • Font Awesome Free
  • RTLCSS
  • Google Fonts: Marcellus, Open Sans

All plugin files and icon fonts are loaded locally. The only external requests are the Google Fonts stylesheet, the Google Maps embeds and the video popup.

Support

If you have any questions or need help with the template, please reach out through the marketplace where you purchased the template: open the item there and send us your question from its support page. We aim to respond within 24–48 hours.