Crystal Palace Osteopathy.
osteopathcrystalpalace.co.uk
An established practice, a site that
wasn't carrying its weight.
Crystal Palace Osteopathy has been treating patients in SE19 for years. Virginia has a waiting list. The website hadn't kept up. Hard to read on a phone, slow to load, and buried on page three of Google for osteopath Crystal Palace. Patients were finding her by word of mouth, which is great until it isn't.
Rebuild it from the ground up.
Keep what worked.
Editorial, not clinical.
Warm palette. Instrument Serif for the display headings. One signature photograph of a woman holding her lower back, stopping the scroll where every other physio site fades into stock imagery.
Hand-coded, no bloat.
No CMS, no plugins, no tracking bloat. Ships as static HTML and a handful of WebP assets. Lighthouse 98 on mobile. Under 300KB on first load.
Full MedicalBusiness schema.
Geo coordinates, opening hours, areas served, practitioner credentials. Everything Google needs to show her at the top of the local pack for osteopath Crystal Palace.
The same page,
two views.
What Google sees is different. Every card in that grid, every treatment category, every address line and opening hour is typed directly into a hand-written MedicalBusiness JSON-LD block in the <head>. No plugin, no generator, no CMS plumbing. Four separate schema blocks totaling 272 lines of structured data, wired by hand and validated against the Rich Results Test.
-
Dual @type:
["MedicalBusiness", "HealthAndBeautyBusiness"]. Covers both health intent and local services intent without keyword stuffing. -
16
areaServedentries. Crystal Palace, Dulwich, Sydenham, Penge, Bromley, Croydon and 10 more. Primary location carriesGeoCoordinates(51.4186, -0.0765). -
4
EducationalOccupationalCredentialentries on the practitioner. BSc(Hons), ITEC, APNT, NLSMR. Each withrecognizedBy. Registered with the General Osteopathic Council. -
Explicit
openingHoursSpecification.dayOfWeekas an array. No string parsing, no ambiguity for the crawler. -
Four separate blocks.
MedicalBusiness,FAQPage,BreadcrumbList,WebSite. Split so Google can index each independently. - Zero runtime JavaScript for the schema. Ships static in the initial HTML. First byte already contains everything the crawler needs.
// index.html · head · schema[0]
{
"@type": ["MedicalBusiness",
"HealthAndBeautyBusiness"],
"medicalSpecialty": [
"Musculoskeletal",
"PhysicalTherapy",
"RehabilitativeMedicine"
],
"geo": {
"@type": "GeoCoordinates",
"latitude": 51.4186,
"longitude": -0.0765
},
"openingHoursSpecification": [{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday",
"Wednesday",
"Friday"],
"opens": "10:00",
"closes": "20:00"
}],
"employee": {
"@type": "Person",
"name": "Virginia Spencer-Smith",
"hasCredential": [
{ "name": "BSc(Hons) Osteopathy" },
{ "name": "ITEC Massage Therapy" },
{ "name": "APNT Sports Injury" },
{ "name": "NLSMR Remedial" }
]
}
}
- Schema blocks
- 4
- Structured data
- 272 lines
- Runtime JS
- 0 KB
- Initial HTML
- 66 KB
- CSS
- 42 KB
- Hero image
- 116 KB WebP
The photograph
that stops the scroll.
Every other physio site in SE London fades into stock imagery — latex gloves, neon adjustment tables, a pair of hands on a spine no patient can see their own body in. This one stops on a single photograph: a woman holding her lower back. She isn't a clinician. She's the reason someone Googles "osteopath" at 11pm on a Tuesday. The editorial sits on warm cream, serif display at Instrument Serif, body at Space Grotesk. No overlay, no gradient, no gimmick.
- Two fonts, doing real work. Instrument Serif Italic for the display phrase. Space Grotesk for the body. The tension between the two IS the editorial voice.
-
Warm off-white, never
#FFF.#FAFAF8on the section,#1A1A1Aon the text. Pure white is a stock-site tell. -
Art-directed for mobile.
Desktop shot is landscape, anchored right. Mobile serves a recropped portrait at 390×844 through
<picture>with amax-width: 768pxsource — not a squashed version of the desktop frame. -
Clip-path wipe on reveal.
The photograph is "wiped" into view from left to right on scroll using
clip-path: inset(0 100% 0 0)→inset(0). Cinematic, not generic. Zero GSAP. -
Text wraps, never widows.
text-wrap: balanceon the display line.max-width: 65chon the body paragraph. One long word at the end is a design bug, not a feature. - One image, 38 KB. Full-width WebP, quality 82, lazy-loaded. No DOM elements around it waiting for JavaScript.
/* editorial.css */
.editorial__display {
font-family: 'Instrument Serif',
serif;
font-style: italic;
font-size: clamp(2.25rem,
5vw, 4.5rem);
line-height: 0.95;
letter-spacing: -0.02em;
text-wrap: balance;
}
.editorial__body {
font-family: 'Space Grotesk',
sans-serif;
max-width: 65ch;
line-height: 1.6;
}
.editorial__figure img {
/* clip-path wipe */
clip-path: inset(0 100% 0 0);
transition: clip-path 700ms
cubic-bezier(0.16, 1,
0.3, 1);
}
.editorial__figure.revealed img {
clip-path: inset(0);
}
- Fonts
- 2, self-hosted
- Display type
- Instrument Serif
- Body type
- Space Grotesk
- Mobile art direction
- Portrait recrop
- Reveal
- Clip-path wipe
- Editorial image
- 38 KB WebP
Live in under two weeks.
- 98
- Lighthouse, mobile
- 12days
- Brief to live
- 0
- Templates used
The site is live at osteopathcrystalpalace.co.uk. Virginia got a site she can send people to without a wince. I got my first case study.
If you run a local business in Crystal Palace, East Dulwich, Peckham, Herne Hill, Forest Hill, or anywhere across South East London and your website isn't doing its job, get in touch. The process is the same. See pricing for the full breakdown.
Your business could be
case study 02.
Got a local practice or studio that needs a proper website? I'm taking on new projects now.
Start a conversation