← The library

Volea

Court booking site for a padel club

Full template Members only Open the demo Unlock the library
Preview of the Volea template: hero section over a photo of a padel player at golden hour, the heading “Play Padel Without the Hassle” and a membership button.
  • 12 photos regeneratedNot one image of the original site remains. Twelve photographs produced for this template, free of rights.
  • 17 animations measuredPulled out of the original’s animation engine, not guessed by eye: durations, curves, offsets, thresholds.
  • 0 external requestsNo dependency, no CDN, no build step. Open the file and it works.

What it is

The site of a padel club that takes its bookings online: announcement strip, full-height hero, an intro with counters, three services, four steps, a full-page call to action, five coaches, eight questions, a footer with a newsletter sign-up. One page, one HTML file.

The design follows that of a commercial template of which nothing has been kept — neither the photos nor the code. The original came to 91 kB of minified CSS, jQuery, three Webflow bundles totalling 2.4 MB, GSAP with ScrollTrigger and SplitText, and a proprietary animation engine. Unreadable, and therefore useless for learning from.

That's the whole point: this template isn't here to be admired, it's here to be read, broken and rebuilt.

What you change first

The colours — three lines

Right at the top of assets/css/style.css:

--accent:      #3bf0c8;  /* buttons, indicators, figures */
--accent-deep: #16c9a2;  /* the same, darkened for hover */
--accent-soft: #8ff8df;  /* the same, lightened for text over photos */

One thing to grasp before touching anything else: there are three aquas, not one. The solid accent carries 14.5:1 on black, but it vanishes into a bright photo — hence the lightened version. Change one, change all three. And the accent is light by construction: it carries black text, never white.

The name

Search for “Volea” in index.html: seven occurrences. No CSS class carries the brand name, so a find-and-replace can't break anything.

The sizes

The type scale is declared once, then redeclared at every breakpoint. So a heading never gets its own media query: you change --t-h2 and the whole page follows.

The 16 effects, and how they’re built

All taken from the data of the original's animation engine — the site runs on Webflow IX3, which writes its 17 interactions and 17 timelines in plain text inside the page bundle. Extracted by script, then measured in the browser, never by eye.

EffectWhereHow
Heading that writes itselfherosplit into words, 0.03 s offset — words and not letters, so a screen reader still reads a sentence
Drifting photohero, call to actionthe JS writes a progress variable, the CSS applies the translation
Parallax7 photossame mechanism, ±10% inside a frame scaled up by 20%
Frame that unrolls2 photosclip-path rather than a height: nothing reflows
Staggered revealservices, steps, coaches, FAQIntersectionObserver, firing 15% up from the bottom of the screen
Paragraph that lights upintrothe JS writes the progress, the CSS computes each word's opacity with clamp()
Bar that settlesnavigationone class, one transition — the original scrubbed this value against scroll
Countersintro0 → 10K and 0 → 500, rounded to a step so they don't flicker
Rolling linksmenu, footertwo copies of the label in a one-line window
Button arrowseverywherethe first flies out, the second comes in from bottom-left
Accordions8 questionsnative <details>, height animated by a grid track
Drop-down menu≤ 991 pxtranslated panel, hamburger folding into a cross

What you should know

  • No external requests. Every resource is local, fonts included. The original loaded jQuery, three bundles and Google Fonts from three domains.
  • Scroll reveals can't hide the content. The hidden state only exists once the JavaScript has run. Checked by removing the <script> tags: 22 headings out of 22 stay visible, both framed photos are unrolled, all 8 accordions open.
  • Zero inline styles, zero inline scripts. The template honours the site's strict security policy — the very one the original broke with a <style> hiding fourteen selectors at once.
  • The trigger sits 15% up from the bottom of the screen, and is measured on the screen, never on the element: a threshold expressed as a percentage of the element leaves anything taller than the viewport hidden for good.
  • Accessibility: skip link, menu state announced, native FAQ, visible focus, decorations hidden from screen readers, animations switched off if the system asks — delays included.
  • Checked at 390, 1440 and 2560 px, on load and after scrolling all the way down, with no horizontal overflow. The bench ships with it: node _mesures/banc.mjs.

What isn’t perfect

Better said here than left for you to find out.

  • The newsletter form sends nothing. It answers inside the page rather than navigating to an address that doesn't exist. Where to plug your fetch() in is marked in main.js.
  • “Sign in” and “Book a Court” point at the footer. The original sent you to the editor; a one-page template has no honest destination other than an anchor.
  • The stagger offset was cut by two thirds (0.3 s → 0.1 s). At the original value the fifth coach card finished three seconds after the first: you had scrolled past before it arrived.
  • The footer is 10.7% taller than the original at 479 px: the address and the phone number take two lines in capitals there. Across the whole page the gap falls to −0.1%.
  • The club, the coaches and the figures are made up. It says so in the demo's footer.

It’s waiting for you in the library.

Volea comes with the subscription, alongside the rest of the library and the full course.

Immediate access · No commitment · Cancel in one click