Back to work Case study  ·  Patrick James Bathrooms

Everything that went into the rebuild.

Patrick James Bathrooms has 32 years of clients who come back and bring their friends. They needed a website that matched that standard. Here is a full account of what I designed, how I built it, and every decision along the way.

ClientPatrick James Bathrooms
IndustryBathroom renovations
ScopeDesign, Build, SEO
Year2026
Live sitepjbathrooms.com.au ↗
The rebuilt Patrick James Bathrooms homepage: a navy and champagne hero reading Sydney Bathroom Renovations, Built Properly, beside a renovated bathroom
The rebuilt homepage. The live build even credits me at /credits.html as its designer and developer.
38+
HTML pages
24
Suburb pages
8
Blog articles
11
Homepage features
0
JS frameworks

A site as good as the work.

Patrick James Bathrooms has renovated bathrooms across Sydney since 1994, with more than 2,000 projects to their name. Their reputation was built on word of mouth, but the old website did not reflect the quality of the work. It was slow, awkward on a phone, and gave a new customer no easy way to gauge cost or get in touch.

The goal: a website that looks as premium as the bathrooms, earns trust instantly, and makes it effortless for a homeowner to picture the project and request a quote. Everything below is custom. No plugins, no themes, no templates. Here is what that actually amounts to.

Built by hand, hour by hour.

A builder site is dragged together in an afternoon. This was not. Every page was written, every feature coded, every detail decided on purpose. Here is the scale of it.

40+
Pages hand-written
18k+
Words of original copy
6k+
Lines of code
11
Features from scratch
0
Templates used

Where the hours went

Roughly, across the project. Close to 200 hours of real work.

Homepage and 11 interactive features~45 hrs
24 suburb pages, each written~40 hrs
Design system and UI design~30 hrs
Testing, accessibility and polish~25 hrs
8 long-form articles, each written~24 hrs
SEO, schema and metadata~18 hrs
Discovery and strategy~12 hrs

The full inventory.

Eleven interactive features on the homepage alone, each built by hand and each there to answer a real question a client has.

Homepage features
01
Cinematic hero
Ken Burns slow-pan on the hero image. A custom cursor blob that tracks your pointer with spring physics on desktop. Hero glow that follows the mouse. Floating particles. Scroll cue at the bottom. All of it switches off cleanly for prefers-reduced-motion.
02
Photo gallery with lightbox
Eleven project photos in a masonry-style grid. Click any image to open a full-screen lightbox with backdrop blur. Close by clicking outside, pressing Escape, or using the close button. Fully keyboard accessible with focus return on close.
03
Before/after drag slider
Drag a handle to reveal before and after states of a completed renovation. Works on both mouse and touch. CSS clip-path handles the reveal. Carousel dots for navigating multiple comparisons. Data-driven from a separate JS file so Patrick can add new pairs without touching the main HTML.
04
Renovation cost calculator
Real-time estimate tool with four bathroom size options, three finish tiers (Bronze, Silver, Gold), and six optional add-ons: freestanding bath, heated floor, tiled niche, LED mirror, frameless screen, accessible features. Calculates a price range and updates instantly. Runs entirely in the browser with no server or API.
05
Style picker
Five distinct bathroom aesthetics: Modern Minimalist, Hamptons Coastal, Coastal Natural, Industrial Edge, and Luxe Statement. Each tab shows a colour palette, signature finishes, and a description of the style. Helps prospective clients identify what they actually want before they pick up the phone.
06
Package cards
Bronze, Silver, and Gold renovation packages with full feature lists, pricing, and a "Most Popular" badge on Silver. Clicking "Enquire" on any package pre-fills the contact form message with that package name and scrolls to the contact section, reducing friction for someone who has already decided.
07
NDIS accessible bathrooms
A dedicated section covering step-free showers, grab rails, non-slip tiles, wall-hung fixtures, lever taps, reinforced walls, and wider doorways. Structured to rank for NDIS bathroom renovation searches in Sydney, and written in the same tone as the rest of the site rather than defaulting to clinical language.
08
FAQ accordion
Six questions covering cost, timeline, NDIS, warranty, areas served, and the online calculator. Each question expands and collapses with a smooth transition. ARIA attributes on the toggle buttons keep it fully accessible to screen readers. The same questions are in the page's JSON-LD FAQ schema for Google rich snippets.
09
Testimonials with marquee
Four testimonials in glassmorphism cards with hover lift. Below that, an auto-scrolling marquee of short review snippets that pauses on hover and stops entirely for reduced-motion users. Cards include the client name, date, and star rating. The reviews are in the schema markup so they can appear in Google results.
10
Contact form with send modal
Name, email, phone, service type, and message. On submit, the form builds a pre-addressed email and an SMS draft in real time, then presents a modal asking whether to open email or SMS. Patrick gets the full enquiry however he prefers to receive it. Zero server required. A buyer's guide lead magnet captures emails too.
11
Mobile sticky call bar
On mobile, a bar fixed to the bottom of the screen shows a call button and a WhatsApp button at all times. Both are tap-to-contact with no intermediate steps. The bar has a soft shadow separator from page content and sits above the system navigation bar on iOS and Android.
Pages
1
Homepage
Eleven interactive sections. Every feature listed above lives here, fully integrated and consistent.
24
Suburb pages
Unique pages for every major Sydney suburb served: Bondi, Manly, Mosman, Paddington, Chatswood, Northern Beaches, and 18 more. Each has tailored copy, a unique H1, suburb-specific schema, and its own canonical URL. Not template spinners. Actually written.
8
Blog articles
Renovation cost guide, best tiles for small bathrooms, frameless vs semi-frameless screens, Hamptons style, renovation timeline, NDIS modifications, apartment renovations, and a full renovation checklist. Each written to rank and to be genuinely useful.
1
Careers page
A hiring page for tilers, plumbers, and coordinators with a JobPosting schema so listings show up in Google Jobs directly. Consistent with the main site's design and tone.
2
Index pages
A blog listing index with article previews, and a suburbs directory linking all 24 suburb pages. Both linked in the sitemap and footer.
1
404 page
A custom error page in the same design language. Tells lost users where they are and gives them a way back without feeling abandoned.

Six choices that
shaped the rebuild.

Good design is mostly the absence of bad decisions. Here is where the thinking went.

01
Typography

An editorial type pairing

Playfair Display at 900 weight carries the headlines, with italic applied deliberately to the key phrase in every heading and never by default. DM Sans handles all UI and body text. Tight tracking at display sizes, loose on eyebrows. The pairing reads like a magazine spread before it reads like a tradie website. That order matters.

02
Colour

A palette that restrains itself

Navy (#0a1628) as the primary ink. Blue (#1d4ed8) for interactive elements only. Champagne gold (#c9a84c) as the single accent that earns its place rather than repeating freely. Paper (#fafaf7) replaces cold white. Everything structural lives in hairlines and shadows. The colour does not do the heavy lifting.

03
Motion

Animation that holds back

A slow Ken Burns on the hero. A reading-progress bar in the brand gradient. Scroll-triggered fade-ups via IntersectionObserver. The easing curve is custom: cubic-bezier(0.22, 1, 0.36, 1), which overshoots slightly then settles. Nothing bounces, nothing loops indefinitely, nothing demands attention. prefers-reduced-motion is respected throughout.

04
Function

Every feature earns its place

The calculator, lightbox, before/after slider, FAQ, style picker, and contact forms all run without a backend. Everything is client-side JS or a well-formed mailto link. Zero server dependency, zero hosting lock-in. Patrick can move this site to any host tomorrow and nothing breaks. Features were added because they answer real questions, not to pad the page.

05
Performance

Honest, durable markup

Static HTML throughout. No framework, no build pipeline, no CMS. Markup you can read top to bottom and understand in a sitting. AVIF and WebP images with JPEG fallback. Compiled Tailwind rather than a 3 MB CDN script. Far-future cache headers in .htaccess. The goal was a site that loads fast on the first visit in a Mosman kitchen with mediocre NBN.

06
SEO

Local presence, built in

Twenty-four suburb landing pages covering the Northern Beaches, North Shore, Eastern Suburbs, Inner West, Hills District, and more. Each has unique written copy and its own structured data. Eight blog articles on renovation topics people actually search for. The authority signals are built into the site structure, not bolted on with a plugin after launch.

The colour palette.

Seven tokens. Every colour decision on the site traces back here. Click any swatch to copy the hex code.

The fonts that carry it.

Two typefaces. One rule: if Playfair and DM Sans feel incongruent, the design is not working.

Playfair Display · Display & Headlines
A bathroom
built to last.
Weights: 400, 700, 900
Styles: Regular, Italic
Usage: H1, H2, H3, quotes, eyebrow numbers
Tracking: -0.018em on headings
DM Sans · Body & UI
We have been renovating Sydney bathrooms since 1994. Every project starts and ends with one question: would we put our own name on it?
Weights: 300, 400, 500, 600
Optical size: 9 to 40 axis active
Usage: Body, nav, labels, buttons
Body size: 1.0625rem / line-height 1.78

What it runs on.

Plain web. The kind that does not need maintenance. The kind that lasts ten years and still works.

Structure
HTML5: semantic markup
Proper landmark elements throughout. header, main, footer, nav, section, article, no div soup. Accessible to screen readers out of the box.
Schema.org JSON-LD
LocalBusiness, FAQPage, BlogPosting, JobPosting, BreadcrumbList on every relevant page. Hand-written and validated.
Open Graph + Twitter Cards
Full social metadata on all pages. Clean share previews on Facebook, LinkedIn, iMessage, and X.
Styling
Tailwind CSS, compiled
Compiled to a single tailwind.css for production. Utility-first layout; custom CSS handles the design system tokens. No 3 MB CDN script on every page load.
CSS Custom Properties
Seven colour tokens, one easing curve, the full typography scale, all centralised in :root. Change one value and it cascades everywhere.
Google Fonts, preconnected
Playfair Display and DM Sans. Preconnect tags in the head reduce font load latency. display=swap for a graceful fallback before fonts arrive.
Behaviour
Vanilla JavaScript
No frameworks, no bundles, no dependencies. IntersectionObserver for scroll animations, scroll listener for the nav and progress bar, pointer events for the drag slider.
Cinematic engine (pj-cinematic)
Cursor blob, hero particles, 3D card tilt, and package spotlight effects extracted into separate CSS and JS files. Loads after the main content so it never blocks the first paint.
Data-driven components
Before/after comparisons are driven from data.js so new project pairs can be added without touching the main HTML. Clean separation of content from presentation.
Forms & contact
Mailto pattern with send modal
All forms encode directly to mailto and SMS links, no server, no middleware, no monthly form service. Patrick gets enquiries in whatever app he has open.
WhatsApp CTAs
wa.me links with pre-filled context messages. The mobile sticky bar and WhatsApp buttons send the right message for each page context.
Real-time cost calculator
Size, tier, and add-on inputs update a price range in real time. Pure client-side arithmetic. No API, no rounding surprises, no dependency on anything external staying online.
Performance
AVIF + WebP + JPEG fallback
All photography served in AVIF where supported, WebP as the fallback, JPEG as the last resort. Preload tags in the head for the hero image to minimise LCP time.
Lazy-loaded gallery
loading="lazy" on all below-fold images. The browser fetches them as the user scrolls rather than all at once on page load.
Apache .htaccess
Gzip compression, far-future cache headers for static assets, HTTPS redirect, and clean URL handling in the live environment.
Accessibility
prefers-reduced-motion
All animations and transitions check this media query and switch off or simplify for users who need it. The site does not punish people for having a vestibular disorder.
Focus-visible outlines
:focus-visible with gold outlines on every interactive element. Every interactive feature is fully keyboard navigable, including the lightbox, mobile menu, FAQ accordion, and send modal.
ARIA attributes
aria-label, aria-expanded, aria-hidden, aria-checked, aria-pressed used throughout. Decorative elements and background images marked aria-hidden so screen readers skip them.

Engineered to score.

A heavy template can look fine and still fail where it counts: speed and search. Because this build ships almost nothing the browser does not need, it is made to ace the audits Google actually uses. The best part is you can run it through Lighthouse and check for yourself.

99/100
Performance
100/100
Accessibility
100/100
Best Practices
100/100
SEO
Under 1.2sLargest Contentful Paint
Near zeroCumulative Layout Shift
InstantInteraction response

Real figures move a little with network and device, which is exactly why the site is engineered with this much headroom. A generic builder site rarely gets close.

This build versus a generic site.

The same business, two very different websites. This is what hand-coding buys that a template never will.

A generic site

Template or builder
  • Loads a heavy theme and scripts the visitor never asked for.
  • One generic page or two, and maybe a contact form.
  • Thin or duplicated location text that Google quietly ignores.
  • SEO limited to whatever a plugin will let you change.
  • A monthly fee, and you never actually own it.
  • Looks like a thousand other businesses.

This build

Hand-coded for PJ
  • Ships only the code each page needs, so it loads in under a second.
  • 40 pages, 24 written suburb pages, a cost calculator and more.
  • Unique copy on every page, the way Google actually rewards.
  • Structured data hand-written for rich results in search.
  • Paid once, owned outright, hosted anywhere.
  • A custom identity that looks like nobody else.

From first
conversation to live.

Six chapters. No agency overhead, no compromise by committee, no one else to blame if it was wrong.

01 · Discovery

Listening before drawing

Sat with Patrick. Read every review. Understood what kind of clients the business actually attracts and what they care about: no-surprises pricing, clean communication, showing up when they say they will. That became the brief. Not aesthetics: character.

02 · Positioning

Editorial, not tradie generic

The benchmark for this site was not other bathroom renovation websites. It was architecture magazines, high-end property listings, and luxury hospitality. The layout language, the type hierarchy, the photography treatment, the way the page breathes, all of it aimed at that register. Because Patrick's work lives in homes at that level.

03 · Design system

Tokens first, screens second

Seven colour tokens. Two typefaces. One easing curve. A spacing scale and an elevation scale. All defined in CSS custom properties before a single page section was designed. Every downstream decision (buttons, cards, dividers, form inputs) flows from those choices rather than being made up each time.

04 · Build

Vanilla, deliberate, nothing wasted

Static HTML, compiled Tailwind for utility classes, custom CSS for the design system, hand-written vanilla JS for every interactive feature. No framework. No bundler. No CMS. The homepage alone is a complete, considered document. The suburb pages and blog articles were each written individually, not generated.

05 · Polish

The work nobody notices

Reduced-motion paths for every animation. Focus rings on every interactive element. Descender breathing room on italic Playfair headings so letters like y and g never clip. Schema markup on every page type. AVIF images for every photograph. Keyboard navigation for the lightbox, the FAQ, the mobile menu, the send modal. The last twenty percent of effort that separates finished from done.

06 · Handoff

A site Patrick owns outright

No vendor lock-in. No monthly platform fee. No CMS account to manage or subscription to maintain. Files in a folder. Hosted anywhere. Editable by anyone who can open a text editor. The before/after slider pulls its content from a separate data file so new project pairs can be added without touching the main HTML. In ten years, it will still work exactly as built.

The feature that does the selling.

The finished bathrooms are the client's craft. The website is mine. So instead of more photos of tiling, here is the work that actually earns its keep: a custom cost calculator, structured data for search, and a build tuned to load in under a second.

The instant cost calculator live on the Patrick James Bathrooms site: a visitor picks bathroom size, finish level and optional extras, and a price range updates instantly
The instant cost calculator I built, live on the site. Pick a size, a finish level and any extras, and the estimate updates in the browser, with no callback and no waiting.
Patrick and the crew own the work.
The website is a wrapper around 32 years of bathrooms.

Patrick and his crew own the bathrooms. The website is mine. If you want one built with the same care for your trade, your practice, or any small business where the online presence does not yet match the actual work, write to me at zac@zacwebsites.com.au or call 0461 519 696.

Want a site that works this hard?

I take on a handful of projects at a time. If you have something in mind, let's talk.