- 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.
| Effect | Where | How |
|---|---|---|
| Heading that writes itself | hero | split into words, 0.03 s offset — words and not letters, so a screen reader still reads a sentence |
| Drifting photo | hero, call to action | the JS writes a progress variable, the CSS applies the translation |
| Parallax | 7 photos | same mechanism, ±10% inside a frame scaled up by 20% |
| Frame that unrolls | 2 photos | clip-path rather than a height: nothing reflows |
| Staggered reveal | services, steps, coaches, FAQ | IntersectionObserver, firing 15% up from the bottom of the screen |
| Paragraph that lights up | intro | the JS writes the progress, the CSS computes each word's opacity with clamp() |
| Bar that settles | navigation | one class, one transition — the original scrubbed this value against scroll |
| Counters | intro | 0 → 10K and 0 → 500, rounded to a step so they don't flicker |
| Rolling links | menu, footer | two copies of the label in a one-line window |
| Button arrows | everywhere | the first flies out, the second comes in from bottom-left |
| Accordions | 8 questions | native <details>, height animated by a grid track |
| Drop-down menu | ≤ 991 px | translated 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 inmain.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