Web Development1 June 2026 · 5 min read

Behind the build: Helia, a solar installer site that feels alive

Most solar installer sites are stock panels and a quote form. Helia is the fifth in a five-template marketplace — a Framer Motion + Boomerang-video build that earns attention without selling sustainability theater.

Behind the build: Helia, a solar installer site that feels alive

Solar installer websites have a problem: they all look the same. A wide hero photo of glistening panels on a tile roof, three "trusted by" badges, a calculator that asks for your zip code, a quote form below the fold. The category sells a product that physically moves the sun's output into a homeowner's wall outlet — and every site about it looks static.

Helia is the fifth and final template in a five-site marketplace I shipped this week. The brief: a solar installer site that reads as a living system, not a brochure.

Stack

Static HTML per page (Helia Landing.html, Helia Solar.html, Helia Storage.html...). React 18 UMD. In-browser Babel. Tailwind via CDN. The new piece for this template: Framer Motion, loaded via the window.Motion UMD bundle.

Why bring in a motion library for one site when the other four ship without it? Because Helia's hero needs a boomerang-style video loop — play forward, play reverse, repeat — and the OrbitImages component needs to animate concentric arcs of imagery. WAAPI plus CSS keyframes could do it, but Motion's animate + useReveal patterns made the orbit logic one component instead of three.

The hero

The hero is a full-bleed BoomerangVideoBg of an aerial solar farm shot at golden hour. A green-tinted gradient overlay softens it for legibility. A pill at the top reads "Powering tomorrow · 24.6 MW live" — a fake live counter, but the format is real and the same pattern works wired to a metrics endpoint.

Below: a serif headline ("Renewable power for tomorrow, infinite clean solutions"), a calm subtitle, two CTAs stacked on mobile. The primary is a soft gradient pill ("Explore options") with a play icon; the secondary is a clean white pill ("Start network") with an arrow.

OrbitImages

The "powered by" section is six concentric rings of imagery rotating around a center logo. Each ring is a Motion.div with animate={{ rotate: 360 }} and a per-ring duration. The trick: the images inside each ring are themselves rotated counter to the parent rotation, so they stay upright relative to the viewer while their ring orbits.

CSS variables (--gx, --gy) feed a radial glow that follows the cursor inside the center logo card — pure onMouseMove updating two custom properties.

Two bugs I caught in QA

1. The "infi nite" word break. The hero headline uses a StaggeredFade component that splits the string into per-character spans for the entrance animation. Those spans were display: inline-block, which meant any non-breaking space between them broke at the word boundary instead of staying glued. "infinite" wrapped as "infi nite" on the 375-wide viewport. Fix: switch the chars to display: inline and use real spaces — the inline-block was inherited from an older variant of the same component that needed independent transforms.

2. The helia/ subdir ghost references. When I flattened the source layout (originally everything lived in helia/), 16 HTML files still pointed at helia/lib.jsx, helia/primitives.jsx, and so on. The first deploy 404'd half the scripts. A sed pass over every HTML file stripped the prefix and the next deploy was clean.

Reveal animation

Helia uses a lighter reveal than the other four templates — WAAPI element.animate([{opacity: 0}, {opacity: 1}], {duration: 300, ...}). Opacity only, no transform. The reason: the hero is so dense with motion already (boomerang loop, orbit rings, gradient drift) that adding rise-up sections to every block read as twitchy. Cutting the per-section motion to a 300ms fade let the always-on background motion carry the energy.

What I would change

The OrbitImages performance dips below 60fps on the lowest-end Android I tested (a 3-year-old Moto G). Six rings × ~8 images = 48 transformed elements at 30Hz. A future pass would pre-bake a sprite atlas and animate a single canvas — fewer reflows, identical visual.

Live

helia-template-05.netlify.app

DL

Dusko Licanin

Full-Stack Developer · Banja Luka, Bosnia

Senior full-stack developer shipping SaaS MVPs, web apps, and mobile apps 2× faster than agencies using AI-augmented workflows. Live portfolio: BookBed, Callidus, Pizzeria Bestek.