ClearwaterBuild guide

Generative Assets · Industry Demos XXV · site 339

How the Clearwater Speech Pathology demo was built

A fictional Como speech pathology clinic — paediatric and adult, in clinic, at home and school, and by telehealth across Perth's southern suburbs. The page has one job: an initial-appointment booking with the term plan already priced, and because the audience is NDIS-adjacent, the accessibility floor was written into the spec rather than left to judgement.

Concept

Parents of a four-year-old nobody outside the family can follow, plan-managed teens without a therapist, adults finding words again after a stroke, and teachers saying "get that checked". They ring around three clinics and book the one that tells them what a term costs before they've dialled. So the signature is a Term Board — a drawn ten-week strip that fills with speech-bubble sessions as you plan, with the price badge pinned to the week-zero clipboard — and every control on it pre-fills the booking form.

Palette

Argued from a bright clinic room: warm paper on the wall, deep-indigo ink, the violet of a speech-bubble sticker, and a sun sticker for marks. Contrast figures below are measured from the shipped tokens by WCAG arithmetic (spec-time hypotheses in brackets).

#FBF8F1 warm paperpage ground
#2A2F4A deep indigobody ink · 12.34:1 on paper (≈12) · telehealth bubbles
#6D4BAF speech violetCTAs, 45-min bubbles · white labels 6.41:1 (≈6.4) · links on paper 6.04:1 (≈6)
#F0B23F sun stickermarks, ticks, 30-min bubbles, focus glow · 1.78:1 — lines only, never text
#8A5E00 sun inksun-coloured small copy · 5.38:1 on paper (spec ≈6 — passes AA, recorded honestly) · 5.09:1 on sun-tint
#4E5470 ink-softsecondary copy · 7.01:1 on paper
#4F3488 violet inkeyebrows, prices · 8.11:1 on violet-tint
#A7ACC4 footer mutedcolophon on #20243A · 5.82:1 on indigo

The ink/line split holds throughout: sun is for ticks, tails, rules and the outer glow of the focus ring; anything set in type at sun hue is sun-ink. Violet is deep enough that no two-token remedy was needed for white-on-violet buttons; the deeper #5A3C97 is a hover state, not a contrast fix.

Type

Outfit 700 for display and buttons — a rounded geometric that reads to a child and a grandparent at the same size, with a wordmark that sits comfortably in a 62px masthead. Nunito for body at 17px on mobile and 18px from 760px (the a11y floor is ≥17px). The typographic moment is the term line set huge in uppercase Outfit over the board — EIGHT SESSIONS, ONE TERM — with the count re-set in words by the planner (Two … Ten). Scale: 0.86 / 0.95 / 1.04 / 1.35 / 2.3 / 2.75 rem, with the badge price at 1.75rem so it never fights the term line.

Techniques

Pricing model (pinned anchors)

Private fee schedule; every fee sits under the current NDIS price limit for speech pathology, stated on the page. Totals are integer by construction (the weeks stepper is 4–10 in twos, so fortnightly sessions are always whole).

LineAnchorRule
Initial assessment & written report (60 min)$290Toggle, live at every combination, ON at rest
Therapy 45 min, in clinic$145 / sessionSessions = weeks (weekly) or weeks ÷ 2 (fortnightly)
Therapy 30 min, in clinic$100 / sessionCheapest priced output: 2 sessions fortnightly over 4 weeks, no assessment = $200 → grid floor "from $100"
Telehealth 45 min$135 / sessionLocks the visit toggle OFF with reason "no travel — it's a video call"; switching back to an in-clinic service RESTORES the prior visit choice
Home / school visit+$40 per visited appointmentMultiplies every session AND the assessment when it's on; ledger prints "N visits — $X"
Funding: PrivateNo declaration
Funding: NDIS (plan- or self-managed)no repricingBadge appends "claimable against your plan — no gap"; ledger and mirror print "NDIS: billed under the price limit for each item"
Funding: Medicare CDM referralno repricing, never a numberBadge appends "less your Medicare rebate on up to five sessions a calendar year"; ledger prints "Medicare rebate: at the MBS schedule, processed on the day — up to 5 sessions per calendar year with a GP referral"
Groups & school programsno number"Priced per program — tell us the group size" (designed price-less card, not on the board)

Worked examples — measured from the running page against an independent oracle

ScenarioArithmeticSpecMeasured
Rest: 45 min · weekly · 8 weeks · assessment ON · visit OFF · private8 × 145 + 290$1,450$1,450
Telehealth · fortnightly · 10 weeks (5 sessions) · assessment OFF5 × 135$675, visit disabled$675, visit locked
30 min · weekly · 6 weeks · assessment ON600 + 290$890$890
45 min · weekly · 4 weeks · assessment ON · visit ON580 + 290 + 5 × 40$1,070, "5 visits — $200"$1,070, ledger reads "5 visits — $200"
Rest + NDIS chipunchanged$1,450 + declaration on badge and ledger$1,450, both surfaces
Rest + Medicare chipunchanged$1,450 + declaration on badge and ledger$1,450, both surfaces
Cheapest: 30 min · fortnightly · 4 weeks · assessment OFF2 × 100$200$200
Lock/restore: 45 min · 8 wk · visit ON → telehealth → 30 min1,810 → 8 × 135 + 290 → 8 × 100 + 290 + 9 × 40restore prior visit$1,810 → $1,370 → $1,450, visit restored ON

Zero spec corrections: every worked figure was pure anchor arithmetic and matched the oracle first time. The one measured deviation from the spec is a contrast hypothesis, not a price — sun-ink measures 5.38:1 rather than the estimated ≈6:1 and still clears AA.

Toggle matrix

ControlTherapy 45 minTherapy 30 minTelehealth 45 min
Assessment & reportlive, +$290live, +$290live, +$290 (no visit fee on it — no travel)
Home / school visitlive, +$40 × (sessions + assessment)live, +$40 × (sessions + assessment)DISABLED — "no travel — it's a video call"; prior choice remembered and restored on the way back
Weekly / fortnightlysessions = weeks / weeks ÷ 2samesame
Funding chipsdeclaration onlydeclaration onlydeclaration only

Conversion decisions

Above the fold at 375

Wordmark, phone chip and (from 640px) a Book button in the masthead; eyebrow, h1 naming trade and area, "Book an initial appointment" + "Call" buttons, and three trust ticks all land inside 740px on a 375 screen. The paragraph is re-ordered below the CTAs on mobile so the promise beats the prose.

Board before form

The Term Board sits in the hero at desktop widths (board and badge inside the first 750px) because the price is the argument; the controls follow immediately below, and "Book this plan" hands the whole scenario — service, frequency, weeks, funding, total — into the form's textarea and funding select.

Form fields

Name, phone (v-flag-safe pattern), suburb, who it's for (child / teen / adult — a clinic triages by that first), funding select, preferred times, and the pre-filled plan textarea. Only the four the receptionist actually needs to ring back are required. Confirmation is a designed panel hidden until a valid submit; the callback promise near the form is static copy and not the confirmation.

Sticky bar

Sun "Call now" + violet "Book" fixed to the bottom under 760px; the footer carries extra bottom padding so nothing hides behind it. Speech-bubble tails on the primary buttons tie the CTAs to the board's tokens.

Local SEO we'd implement for the real business

The live page emits only WebPage / WebSite / BreadcrumbList schema naming it a demonstration — fictional business data in a real index is dishonest markup. For a real clinic we would ship the block below. The top-level type is MedicalClinic, an actual schema.org organization subtype (LocalBusiness → MedicalBusiness → MedicalClinic); Speech-style specialty tokens are MedicalSpecialty enumerations, not organization types, and belong in medicalSpecialty, never in @type.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "MedicalClinic",
  "name": "Clearwater Speech Pathology",
  "url": "https://www.example-clinic.com.au/",
  "telephone": "+61 8 9000 0339",
  "image": "https://www.example-clinic.com.au/clinic-room.jpg",
  "priceRange": "$100–$290",
  "medicalSpecialty": "SpeechPathology",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "[street address]",
    "addressLocality": "Como",
    "addressRegion": "WA",
    "postalCode": "6152",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.99, "longitude": 115.86 },
  "areaServed": ["Como", "South Perth", "Manning", "Applecross", "Victoria Park", "Bentley", "Booragoon", "Melville", "Rossmoyne", "Bull Creek", "Willetton", "Cannington"],
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification", "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"], "opens": "08:00", "closes": "18:00" },
    { "@type": "OpeningHoursSpecification", "dayOfWeek": "Saturday", "opens": "08:30", "closes": "13:00" }
  ],
  "availableService": [
    { "@type": "MedicalTherapy", "name": "Initial speech pathology assessment and report" },
    { "@type": "MedicalTherapy", "name": "Speech and language therapy sessions" },
    { "@type": "MedicalTherapy", "name": "Telehealth speech pathology" }
  ],
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.9", "reviewCount": "63" },
  "review": [
    {
      "@type": "Review",
      "author": { "@type": "Person", "name": "[verified client]" },
      "reviewRating": { "@type": "Rating", "ratingValue": "5" },
      "reviewBody": "[pulled from the practice's verified reviews feed]"
    }
  ]
}
</script>

Plus: a Google Business Profile with the Como pin and telehealth service area, suburb-level FAQ answers marked up as FAQPage, and an NDIS/Medicare page each targeting the query the parent actually types ("speech pathologist NDIS Como").

What would change for the real client

Iteration log

Pass 1 — Craft

Pass 2 — Depth

Pass 3 — Hardening

This is a demonstration build by Sapience Analytics. Want one pointed at your customers?