A premium laser clinic with two UK locations needed to move off their old website onto something faster, darker, and built around their brand — moody, minimal, with a single cream accent. The design existed in Figma. Twelve pages, media-heavy, integrated with their booking system.
Rather than hand-build every section in a visual editor — slow, fiddly, and hard to match pixel-for-pixel — I drove the whole build with an AI coding agent and a tight human review loop. What follows is how that actually went: the workflow, the decisions that shaped it, and the gotchas that bit us anyway.
The decision: static first, Liquid later
The call that shaped the entire project was made on day one: build the site as plain HTML and CSS first, get it client-approved, then convert it into a proper Shopify theme with Liquid sections.
This sounds like extra work. It isn't. Here's why it's faster:
- Speed. Hand-authored HTML/CSS matches a dense custom design far faster than dragging through a section editor, fighting defaults, and guessing at spacing values. You write exactly what you need.
- Fidelity. When you control the markup directly, you hit the design exactly instead of compromising with a builder's opinion about how a hero section should work.
- Cheaper revisions. A client change to a static page is a ten-minute edit. A client change to a Liquid section with schema settings and metafield bindings is a thirty-minute edit. Get the look signed off while it's cheap to change.
- Better client sign-off. Showing a client a live URL they can open on their phone is more convincing than a Figma link. They see the real thing — real images, real text, real responsive layout — before you've committed to the CMS structure.
The plan: lock the visual design in static files, deliver a live preview URL for sign-off, then convert each page into a Shopify theme with editable Liquid sections and proper Online Store 2.0 blocks so the client can update copy and swap images themselves.
For marketing sites on Shopify — clinics, studios, agencies, SaaS companies — this workflow consistently saves a week compared to building directly in Liquid from the start. The conversion from HTML to Liquid is mechanical once the design is locked.
How the build actually went
Pulling the design apart
The first step was extracting the raw ingredients from Figma: the colour palette (ink black, brand cream, two neutrals), the type scale (two heading fonts, one body font), spacing values, and every component pattern. These became a set of CSS custom properties — design tokens — so the entire site referenced one source of truth. Change the cream value once and it updates everywhere.
All images and video were exported at this stage and immediately put through compression. More on why that matters in the gotchas section.
Section by section, page by page
The homepage alone had eighteen distinct sections: hero with background video, treatment card grid, an offer banner, a "how it works" flow, clinic gallery, technology showcase, before/after sliders, testimonials, loyalty scheme, app download block, Instagram feed, booking form, and contact details. Each section got built, reviewed against the Figma frame, and refined before moving on.
The same component patterns then propagated across the other eleven pages — treatments, the two clinic location pages, loyalty programme, credit system, FAQ, results gallery, blog index, and contact. Shared elements (header, footer, booking call-to-action band) were built once and included everywhere, so they stayed consistent automatically.
The AI handled the initial markup for each section: structure, rough layout, class names, spacing. What it produced was typically 70–80% right on the first pass — correct structure, wrong details.
The human-in-the-loop review
This is the part that made the whole thing work. The reliable rhythm was:
- Screenshot the Figma section
- Screenshot the live built version
- Compare them side by side and flag specific differences
- AI fixes the diff
- Redeploy and check the next section
Real corrections caught this way on this project:
- A heading using the wrong font — serif where the brand heading should have been the sans-serif
- A hero section with a photo background it shouldn't have had (video only)
- Treatment cards grouped under the wrong category labels
- A full CTA band that didn't exist in the design, invented by the AI
- Sections needing lighter backgrounds, restructured layouts, or corrected copy hierarchy
The key lesson here: AI is a fast pair of hands, not a substitute for a designer's eye. The feedback loop is what closes the gap between "roughly right" and "actually matches the design". Without it, the 70% turns into the shipped version.
Real content from day one
Rather than lorem ipsum, we used real content as it arrived: clinic addresses, phone numbers, opening hours, practitioner names, and direct booking links for each team member into the clinic's booking platform. Team headshots were converted from HEIC phone photos into compressed WebP. The hero used the client's own brand video.
This matters for sign-off. A preview with placeholder text invites clients to imagine what the real version might look like. A preview with their actual content, their actual team, and their actual booking links gets a clean yes or a specific set of change requests — not "it depends on how the real content looks".
The gotchas (and how we fixed them)
No build is clean. These are the snags worth documenting because they show up on nearly every Shopify site — AI-assisted or not.
Gotcha 1: Aggressive CDN caching
We'd push an update and the live site would show the old version. The files on the server were correct — the CDN was serving stale cached copies, sometimes for hours.
The fix: append a version query string (?v=timestamp) to every CSS, image, and video URL on each deploy. The CDN treats it as a new URL, fetches fresh, and the update appears immediately. This got baked into the deploy script so it happens automatically.
On Shopify specifically: Shopify's own CDN handles theme assets, and theme asset URLs include a version hash that updates when you push new code. But if you're hosting external assets — fonts, video, scripts on a separate server — you need to manage cache-busting yourself.
The principle: caching is a performance feature, not a bug. But during active development it fools you into thinking your changes didn't work. Cache-busting query strings fix it without manually purging the cache every time.
Gotcha 2: Giant unoptimised images
Design exports are built for print. One hero image was 6.4 MB — fine in Figma, a disaster on a web page. Multiply that across a twelve-page site with a gallery, before/after sliders, and a team section and you have a page that crawls on mobile.
The fix: batch compression of every image — resize to a sensible maximum width, re-encode at web-appropriate quality, convert to WebP. The result: roughly 90% reduction in total image weight with no visible quality loss at normal viewing distances. The hero video got the same treatment, down from 68 MB to under 4 MB.
On Shopify, the platform does compress images you upload through the admin — but it doesn't always resize them to sensible dimensions, and it doesn't convert to WebP automatically on all plans. Uploading a 6 MB image and letting Shopify handle it still results in a larger-than-necessary file being served. Pre-compress before upload.
The principle: image weight is the single biggest lever on perceived performance. A 100ms JavaScript optimisation is invisible. A 90% reduction in image file size is not.
Gotcha 3: Mobile text overflow
One long word in a large heading — "Accreditation's" — pushed the entire layout sideways on phones, creating horizontal scroll across the whole page.
The fix: fluid font sizes that scale with the viewport using clamp(), overflow-wrap: break-word on headings, and a global guard against horizontal overflow applied to the body element. Applied once, site-wide, it can't happen again anywhere.
On Shopify, this is especially important because clients will add their own content later. You can ship a theme with no overflow issues and a client can introduce one by typing a single long word in a heading field. overflow-wrap: break-word on all heading elements in your theme CSS is not optional — it's defensive infrastructure.
The principle: test on a real phone, early. Desktop-perfect does not mean mobile-perfect. Emulators lie. Your thumb knows the truth.
Where the build landed
By the end of the focused build, we had a fully deployed twelve-page preview the client could click through on their own device — every page responsive, real booking links live, media optimised, hosted in the real environment, loading in under two seconds on mobile.
That preview became the sign-off artifact. The client reviewed the look and feel, requested three specific changes (all cosmetic, all quick), and signed off before any Liquid conversion work began. The CMS port — converting each HTML page into a proper Shopify theme with editable sections and metafield bindings — happened against a locked design, which made it fast and predictable.
What the AI-assisted workflow actually gives you
Not speed at the expense of quality — speed and quality, if the review loop is tight. Here's what I took away from this build:
- Static-first is the right strategy for complex Shopify marketing sites. Lock the design cheaply, get sign-off, then build the "real" Liquid theme once everyone agrees. You avoid reworking Shopify sections because the client changed their mind about a layout.
- AI produces a strong 70–80% first draft. The section structure, the class naming, the spacing — usually close. The typography choices, the specific design details, the "does this actually look like the Figma?" — those need a human.
- The screenshot-and-flag loop is the whole game. It's what turns an AI-generated approximation into a faithful build. Without it, the 70% ships as the final product.
- The classic gotchas don't go away. Caching, image weight, and mobile overflow are timeless. AI lets you fix them faster once you find them. It doesn't stop them from happening.
- Automate the boring parts of deployment. Cache-busting and compression baked into the deploy process means you stop tripping over the same issue twice.
The tools changed. The craft didn't.