Skip to content
Live Revamp · Solar installer

Solar DNA

A revamp of an existing site. Keep the brand, colours and fonts; rebuild everything under them.

The Solar DNA website

The live site

  • BRAND SCRAPED
  • CONTRAST MEASURED
  • PHOTOS SELF-HOSTED
  • 14 ROUTES BUILT
  • FORM BUG FIXED
  • SHIPPED

Solar DNA already had a website. The job was a revamp, not a replacement, so the brand had to survive it. I scraped their live site for the exact hex codes rather than sampling colours off screenshots. Fjalla One and Source Sans 3, self-hosted through Fontsource. Their own photography, downloaded and served from the build instead of pulled from wherever it was sitting before. Fourteen routes.

Then I measured the brand orange. #FE9700 comes in at 2.18:1 as text. The accepted floor for body copy is 4.5:1, so their own brand colour was unreadable in the place a brand colour gets used most. I split it into two tokens: #FE9700 stays as a fill — bars, icon shapes, where it is a shape and not a sentence — and a darker #AB6600 at 4.53:1 carries any orange word. On screen it still reads as their orange.

The WhatsApp enquiry buttons are WhatsApp green, not Solar DNA orange. The gallery opens in a lightbox. And going through the contact form I found an error box that could never appear: the script toggled a class on it but left the hidden attribute in place, and hidden wins. Anyone who mistyped a field got no error message back. A silent form is a lost enquiry.

The site is an Astro 5 static build with Tailwind CSS 4 and vanilla JavaScript. No UI framework. It ships as a container served by nginx on Google Cloud Run, europe-west1. Images go through astro:assets and sharp. I check the built output rather than the source: headless Chrome driven by Puppeteer, looking for horizontal overflow at 320, 390, 768 and 1440, and pixel-sampling the real rendered background behind text to get the actual contrast ratio instead of the one a design file promised.

Judgement

Calls I made

  • 01

    Scraped the brand colours instead of eyeballing screenshots

    Their orange is #FE9700. I took it from their live site, not from a screen grab. Their fonts are Fjalla One and Source Sans 3. A colour picked off a compressed image comes back a few values out, and a few values out is a brand colour that is almost right, which reads as wrong to the person who owns it.

  • 02

    Split the brand orange into a fill and a text colour

    #FE9700 measures 2.18:1 as text. The minimum for body copy is 4.5:1, so the colour they lean on hardest was the one nobody could read. I kept #FE9700 as a fill-only token and derived #AB6600 at 4.53:1 for any orange word. Nothing about the brand changed, only the job each token is allowed to do.

  • 03

    WhatsApp green on the enquiry buttons, not brand orange

    The enquiry buttons use WhatsApp's own brand green, which on paper fights an orange-and-white palette. It is worth it. A green WhatsApp button is recognised before it is read, and on a phone that is the whole decision. Matching the palette would have cost me that.

  • 04

    Fixed an error message that could never be seen

    The contact form had an error box that was impossible to display. The script toggled a class on it but never removed the hidden attribute, and hidden wins. Anyone who mistyped a field got no error message back. I fixed it so the box can appear.

Outcome

A 14-route site live at https://solardna-u5rriq3m6q-ew.a.run.app, running as a container on Cloud Run in europe-west1. Same orange, same fonts, same photographs, now self-hosted and measured: #AB6600 at 4.53:1 for orange text. Checked for horizontal overflow at 320, 390, 768 and 1440. WhatsApp enquiry buttons on the pages that need them, a gallery lightbox, and a contact form that tells you when it fails.