Construction & Development

Iconic Centre

Modular homes website with scroll-wipe hero effects, 171+ suburb landing pages, Sanity CMS, and an eligibility assessment flow.

Astro 5 + Svelte 5Sanity CMSGSAP AnimationsLocal SEOLead CaptureCloudflare Pages
Iconic Centre website hero

GSAP Hero Experience

Two-phase scroll-wipe hero — project showcase with stats transitions into brand messaging with ScrollTrigger-driven animation

171+ Suburb Pages

Dynamically generated landing pages for every LMR-eligible suburb in NSW, each with localised content and eligibility data

Sanity CMS + Blog

Content-managed blog with MDX components (callouts, comparison tables, key stats) and automatic article feeds

Lead Qualification

Multi-step eligibility assessment flow that qualifies prospects before the sales call — suburb lookup, site assessment, consultation booking


The Challenge

Iconic Centre operates in NSW’s modular construction sector — a market created by the state government’s Low & Mid-Rise (LMR) housing policy. The policy enables faster residential development through pattern book compliance and CDC (Complying Development Certificate) fast-track approval: instead of a traditional DA process that takes 12-18 months and involves council negotiation, eligible projects achieve approval in weeks through private certification.

The market opportunity is substantial but unusually complex for a website to communicate. Three specific problems made this project different from a standard construction site:

Eligibility is suburb-specific. LMR policy designates which suburbs qualify for fast-track development. A landowner in Pagewood might be eligible; a landowner in Mosman might not. The website needed to answer “does my suburb qualify?” before anything else — because if the answer is no, nothing else on the site matters.

The product requires education. Modular construction with regulatory compliance isn’t intuitive. Most property owners have never heard of CDC approval, pattern book compliance, or factory-built construction. The site needed to move prospects from “what is this?” to “my site might qualify” to “I should talk to someone” — and that’s a content challenge, not just a design challenge.

The sales team’s time is expensive. Not every enquiry is a real prospect. A site qualification call takes 30-45 minutes. Spending that time on a landowner whose suburb isn’t eligible, or whose site doesn’t meet setback requirements, is wasted capacity. The website needed to filter leads before they reached a human.

Why This Tech Stack

Astro 5 + Svelte 5 + Sanity CMS

The decision to use Astro with Svelte instead of Next.js or WordPress came down to one requirement: 171+ suburb pages generated at build time without a Node.js server or ongoing compute costs.

FactorNext.jsWordPressAstro + Svelte
171+ dynamic pagesISR or SSR — requires server, cold starts, Vercel costs scale with page countWould need a plugin for bulk page generation, each page as a WP postgetStaticPaths() generates all 171+ at build time — zero runtime cost
Interactive componentsReact runtime ships to client (~40KB+ min)Plugin dependency for interactive elementsSvelte 5 islands hydrate independently — only interactive components ship JS
Content managementHeadless CMS needed anywayBuilt-in but fragile with this many pagesSanity Studio embedded at /studio — same domain, content-managed
Build costVercel pricing scales with ISR revalidationHosting + plugins + managed updatesCloudflare Pages free tier — 171+ static pages cost nothing to serve

Svelte 5 specifically (not Svelte 4) was chosen because runes ($state, $derived, $effect) provide reactive state without stores or subscriptions. The interactive components — project gallery cards, form analytics, custom cursor, cookie consent — are cleaner and more predictable with runes than with Svelte 4’s reactive declarations.

GSAP Over CSS Animations

The homepage hero uses GSAP ScrollTrigger, not CSS scroll-driven animations. The decision was practical: the hero requires a two-phase pin-and-wipe sequence where one full-viewport section pins, then wipes horizontally to reveal a second section. CSS scroll-timeline can handle simple parallax but breaks down with pinning, coordinated multi-element staggering, and scroll-position-dependent state changes. GSAP handles this natively with pin: true and timeline sequencing.

The trade-off: GSAP is a 27KB dependency. For a site with one complex scroll interaction, that’s acceptable. If the animation were simpler (fade-in on scroll, basic parallax), CSS would have been the right choice.

The GSAP Scroll-Wipe Hero

This is the site’s signature interaction — the first thing a visitor experiences, designed to communicate three things in under 10 seconds: “we build premium projects”, “we deliver fast”, and “here’s how to start.”

Phase 1: Project Showcase

A featured development render fills the viewport. Three statistics animate in — residences count, construction timeline (6-9 months), and approval type (Fast Track CDC). The image is pulled from the typed project data system, so it updates automatically when the featured project changes. The stats use the formatProjectStats() helper to parse timeline strings consistently.

Phase 2: Brand Messaging

As the user scrolls, the project showcase wipes horizontally to reveal the value proposition underneath. Three badges stagger in (“Pattern Book Compliant”, “Private Certification Pathway”, “Modular Delivery in 6-9 Months”), followed by two CTAs: “Check If Your Site Qualifies” (primary) and “Book a Free Site Feasibility Call” (secondary).

Custom Cursor

A custom cursor (Cursor.svelte) tracks across both phases, replacing the default pointer with a branded element. This is a small detail that signals design sophistication — the kind of thing a property developer notices, even subconsciously, when evaluating whether this company delivers premium work.

Motion Accessibility

The entire hero sequence respects prefers-reduced-motion. If the OS-level setting is enabled, the wipe transition is replaced with a simple crossfade, and statistics appear without stagger delays. The content is identical; the motion is removed.

171+ Dynamic Suburb Pages

The SEO Architecture

This is the site’s acquisition engine. When a landowner searches “modular homes Pagewood” or “townhouse development Epping”, they need to land on a page that speaks directly to their suburb.

Every LMR-eligible suburb in NSW gets its own page, generated at build time from src/data/suburbs.ts. The data file contains suburb names, postcodes, eligibility status, and any suburb-specific notes. Astro’s getStaticPaths() generates 171+ routes in a single build — each suburb becomes /suburbs/[suburb-name] with its own <title>, <meta description>, and structured content.

Each suburb page includes:

SectionContentSource
Eligibility statusWhether the suburb qualifies for LMR developmentsuburbs.ts data
Development typesWhat can be built (house-and-land, townhouse, knockdown-rebuild)Template + data
Google Maps embedMap centred on the suburbGoogle Maps API per-client project (isolated 10K free loads)
CTA”Check if your site qualifies” → Get Started flowStatic
Related suburbsLinks to nearby eligible suburbsComputed from data

Why This Approach Works

At 171+ pages, manual maintenance is impossible. When NSW policy changes (and it does — suburb eligibility can shift with legislative updates), one edit to suburbs.ts and a rebuild updates every suburb page simultaneously. No one touches 171 individual pages.

The Google Maps integration uses a per-client Google Cloud project to isolate API usage within the free tier (10K loads). This was a deliberate infrastructure decision: Google Maps on 171+ pages with shared API keys would quickly exceed free tier limits.

Typed Project Portfolio

Schema Design

The project data system demonstrates a specific architectural choice: structured JSON data with TypeScript types, rather than free-form CMS content.

src/data/
├── projects.json     # Source of truth (data)
├── projects.ts       # Types + helper functions
├── PROJECTS_README.md  # Schema documentation
└── suburbs.ts        # Suburb eligibility data

Each project record in projects.json has 12 typed fields:

FieldTypePurpose
id / internalIdstringURL slug + internal reference
namestringDisplay name
typeenumhouse-land, townhouse, knockdown-rebuild, resort, multi-dwelling
statusenumplanning, in-progress, completed, on-hold
addressobjectstreet, suburb, state, postcode, full formatted
headline / descriptionstringMarketing copy
specificationsobjectCeiling height, glass type, flooring, kitchen, heating, included features
statsobjectResidence count, timeline, approval type
featuresstring[]Feature list
partnersarrayName + role (architect, interior, landscape)
imagesobjectHero path, gallery array, total count

Helper functions in projects.ts provide filtered views:

  • getProjectsByStatus('completed') — for the portfolio grid
  • getProjectsByType('townhouse') — for type-specific pages
  • getFeaturedProjects(3) — for the homepage
  • formatProjectStats(project) — parses “6-9 months” into { value: "6-9", label: "Months" } for consistent stat rendering
  • getProjectImagePath(id, index) — generates responsive image paths from project IDs

This system was chosen over Sanity CMS for projects because project data changes infrequently (new projects are added quarterly, not daily) and the typed JSON schema provides compile-time validation. A typo in a project type field is caught at build time, not discovered by a user on the live site.

Lead Qualification Flow

Funnel, Not Form

The Get Started page (/get-started) is designed to qualify prospects, not just collect contact details. The flow:

  1. Suburb eligibility check — is their suburb LMR-eligible?
  2. Site characteristics — lot size, current structure, development goals
  3. Consultation booking — qualified leads book a feasibility call

Form analytics (FormAnalytics.svelte) instrument every step: where prospects drop off, which suburbs generate the most interest, which development types are most requested. This data feeds back into marketing — if 40% of prospects come from 5 suburbs, those suburbs get more targeted content.

A Quick Lead Capture component (QuickLeadCapture.astro) appears on content pages for prospects who want to skip the full flow. Both pathways route through cookie consent management (CookieConsent.svelte) and page-level analytics (PageAnalytics.astro).

Blog with MDX Components

Authority Through Education

In an emerging market, the company that educates wins the customer. Iconic Centre’s blog targets the knowledge gap: most landowners don’t know what CDC approval means, how modular construction differs from traditional, or whether their suburb qualifies for LMR development.

The blog is powered by Sanity CMS with 7 custom MDX components that enable richer content than standard markdown:

ComponentPurposeExample Use
CalloutHighlighted boxes for key takeaways”CDC approval can reduce your timeline from 18 months to 6 weeks”
ComparisonTableSide-by-side structured comparisonsModular vs. traditional: cost, timeline, quality
KeyStatsProminent stat blocks”171 suburbs now eligible for LMR development”
ArticleCTAContextual calls to action”Check if your suburb qualifies” mid-article
AlertTime-sensitive noticesPolicy deadline reminders, application windows
ChecklistActionable step lists”5 things to check before applying for CDC approval”
HighlightEmphasized text blocksKey policy changes or requirements

A LatestArticles component on the homepage automatically surfaces the most recent posts, keeping the site current without manual homepage updates.

Analytics and Infrastructure

Layered Measurement

LayerToolPurpose
TrafficGoogle Analytics (GA4)Page views, acquisition channels, user demographics
BehaviourMicrosoft ClaritySession recordings, heatmaps, rage clicks
FunnelCustom FormAnalytics.svelteGet Started flow progression, drop-off points, suburb interest
Page-levelPageAnalytics.astroPer-page engagement metrics
PrivacyCookieConsent.svelteGDPR/Privacy Act compliance, consent management

Deployment

Cloudflare Pages via Wrangler CLI, with edge functions configured through wrangler.toml. Sanity Studio embedded at /studio — content editors access the CMS at the same domain, no separate admin URL. Builds triggered by content changes via Sanity webhook.

Technical Specifications

CategoryDetail
FrameworkAstro 5 (Static Site Generation)
Interactive layerSvelte 5 (Runes: $state, $derived, $effect)
CMSSanity CMS v5 (embedded studio at /studio)
AnimationGSAP + ScrollTrigger (27KB, scroll-wipe hero)
StylingTailwind CSS v4
TypographyClash Display (headings) + Inter (body)
HostingCloudflare Pages + Edge Functions
MapsGoogle Maps API (per-client Cloud project, isolated free tier)
BlogMDX with 7 custom components
AnalyticsGA4 + Clarity + custom form analytics
Pages14 core + 171+ dynamic suburb + blog
Project dataTyped JSON schema + TypeScript helpers

The Result

A modular construction platform where every architectural decision serves a specific business purpose. The GSAP hero creates premium positioning within seconds. 171+ suburb pages capture the long-tail search traffic that a manual approach could never maintain. The typed project system ensures portfolio data is consistent and validated at build time. The qualification flow filters leads before they reach the sales team.

  • 171+ suburb landing pages generated from structured data, each with localised eligibility content and Google Maps integration
  • 2-phase GSAP scroll-wipe hero with ScrollTrigger, stat overlays, and custom cursor — accessible with reduced-motion fallback
  • Typed project system with JSON schema, TypeScript interfaces, 5 helper functions, and Svelte 5 gallery cards
  • Sanity CMS with embedded studio, MDX blog with 7 custom components, and automatic homepage article feeds
  • Lead qualification funnel with suburb eligibility check, form analytics instrumentation, and quick capture alternative
  • Design system — Clash Display + Inter typography, terracotta/walnut/cream/sage palette drawn from construction materials
  • Full analytics stack — GA4, Clarity session recordings, custom form funnel tracking, cookie consent management
  • Edge-delivered via Cloudflare Pages with isolated Google Maps API project per client
  • Zero server maintenance — 171+ pages are static HTML, no Node.js runtime, no database, no security patches

Screenshots

Iconic Centre homepage with GSAP scroll-wipe hero revealing project render and key statistics
Two-phase hero: project showcase wipes into brand messaging with scroll-triggered GSAP animation
Dynamic suburb landing page for Pagewood showing local project data and eligibility information
171+ dynamically generated suburb pages targeting LMR-eligible areas across NSW
Project gallery card with responsive images, location, and key statistics
Data-driven project portfolio with typed JSON schema and responsive gallery cards
Multi-step eligibility assessment form with suburb lookup and site qualification
Lead qualification flow: suburb eligibility check, site assessment, and consultation booking

Tech Stack

Astro 5 (SSG)Svelte 5 (Runes)Sanity CMS v5GSAP + ScrollTriggerTailwind CSS v4Cloudflare Pages + Edge FunctionsGoogle Maps APIMDX Blog ComponentsClash Display + Inter (Typography)

Project Highlights

Scroll-Wipe Hero

GSAP ScrollTrigger powers a two-phase hero: a project render with key stats pins on scroll, then wipes away to reveal brand messaging with badge animations. Custom cursor tracks across both phases.

2-phase animation

Dynamic Suburb SEO

171+ suburb landing pages generated from a structured data file at build time. Each page includes localised content, eligibility data, and Google Maps integration — targeting the long-tail of 'modular homes [suburb]' searches.

171+ pages

Typed Project System

Projects defined in a JSON schema with TypeScript types, helper functions, and responsive image pipelines. Gallery cards render from data with stats formatting, partner credits, and specification details.

Typed JSON + TS helpers

Blog with MDX Components

Sanity-powered blog with custom MDX components — callouts, comparison tables, key stats blocks, and article CTAs. Latest articles feed automatically into the homepage.

Form Analytics & Lead Capture

Get Started eligibility flow with form analytics tracking, quick lead capture components, and cookie consent management. Every interaction is instrumented.

Full funnel tracking

Automated Deployment

Cloudflare Pages with Wrangler CLI deployment, edge functions support via wrangler.toml, and a Sanity Studio embedded at /studio for content editing.

Edge-delivered

Ready to build something like this?

Let's discuss your project requirements and how we can help.

Start a Project