A fictional reformer & mat studio in South Perth, built as a conversion-first landing page for the kind of studio owner who knows her product is excellent and her website isn't. One job: a first-visit booking request with the plan and weekly rhythm already priced.
The concept
Most studio sites hide the maths: a grid of pack prices and a "join now" button, leaving the visitor to do per-class arithmetic on the bus. True Form leads with the Week Planner — a drawn reformer room where you pick a plan, set how many classes a week you'll actually make, and read the honest per-class figure off the front-desk card inside the scene. The page's rhetoric is the studio's own: quiet, precise, no locked doors — the membership card literally says "no lock-in" on it.
Palette — argued from the room, measured with WCAG arithmetic
Sage-washed wall, potted eucalyptus, deep moss shadow, the oiled timber of a reformer frame. Every ratio below was measured from the shipped tokens during Pass 1 (they matched the spec-time computations):
Sage#EEF1EA — page ground; the wall at 7am.
Moss#262B24 — body ink. 12.66:1 on sage.
Eucalypt#3F6B54 — CTA fill (white labels 6.10:1), links on sage 5.35:1. Hover #33573F: white 8.15:1.
Eucalypt ink#33573F — the pre-minted text twin for eucalypt-coloured copy. 7.15:1 on sage, 6.63:1 on the tint.
Timber#B9915E — reformer rails, springs, rules, leader lines. 2.53:1 — lines and marks only, never text.
Timber ink#7A5A2E — timber-coloured small copy. 5.53:1 on sage, 6.31:1 on white.
Support figures: soft ink #4C554A measures 6.80:1 on sage and 7.76:1 on white; the Sapience band runs sage-on-moss at 12.66:1 with its subline #B9C2B4 at 7.87:1; form error red #8C2F1F at 8.26:1 on white. The two-token accent rule (line/mark colour split from text ink) is why the timber ever gets to be as warm as it is.
Type
Fraunces (variable, weight ~550, optical sizing on) carries the display voice — a soft serif with just enough wonk to feel hand-finished, like the studio's timber. Karla does the workhorse duty: grotesque warmth, wide counters, legible at 16px+ on a phone in one hand. The typographic bravery moment is the rhythm set huge beside the drawn reformer: "TWENTY DOLLARS A CLASS, THREE MORNINGS A WEEK" — eucalypt ink with the timber ink taking the second phrase, the whole pricing argument in ten words.
The signature — the Week Planner
One inline SVG scene (780×520 viewBox): a side-view reformer in timber linework with a moss figure mid-footwork, a seven-day week rail above it, a light shaft with drifting dust motes, and per-plan still-lifes (ticket stub on the shelf, welcome tag on the headrest, punch card pinned low on the door, studio key tag, instructor figure). The carriage glides on a ~6.5-second breathing loop driven by one rAF loop with the delta clamped at zero and capped (dt = min(max(now−last,0), 50)/1000); the three springs are re-pathed every frame from the carriage's live edge, and the legs are solved with two-segment IK (thigh 95, shin 100 units) from the moving hip to the fixed footbar, so the knees genuinely bend as the carriage returns. Reduced motion renders a settled mid-glide frame and never starts the loop.
The price badge is drawn as the studio's front-desk card — an HTML overlay pinned on the scene's empty wall (solid white, no backdrop-filter), so its type stays crisp at every width and its text participates in DOM asserts. Plan chips and the classes-per-week stepper re-render badge, ledger, a11y mirror, week rail and still-lifes from one compute() source of truth; entrance choreography runs once (staggered fades, ~1.15s), and every subsequent change redraws snappy (≤480ms) behind a firstDraw-style settled flag. Chip handlers bump an invalidation token before the state swap, so a rapid-fire volley of clicks can never leave a stale animation indexing dead scene data. Live state (plan, n, figure, note, declarations, lit days, settled) is exposed on window.__pilates for QA.
The pricing model (pinned, then measured)
Plan
Badge line 1
Badge line 2 (presence pinned)
Stepper
Casual $32
"$32×n this week"
Only at n ≥ 2 — the suggestion note
Live (badge prices the week)
Intro pack $48
"$48 — your first three"
"= $16 a class" + new clients, once
Disabled with reason
10-pack $290
"$290"
"= $29 a class"
Disabled with reason
Unlimited week $60/wk
"$60 a week"
"= $(60÷n) a class at n classes a week"
Live (drives the per-class line)
Private $95
"$95 a session"
None — absence asserted
Disabled with reason
Private 5-pack $430
"$430"
"= $86 a session"
Disabled with reason
Measured rest state: unlimited week at 3 classes → "$60 a week" + "= $20 a class at 3 classes a week", membership declarations present on all three surfaces, no suggestion note. The stepper's per-class line is integer-safe by construction: 60/30/20/15/12 for n = 1…5 — all five driven and asserted against an independently reimplemented oracle.
Suggestion note (casual, n ≥ 2): template "<n> casual classes is $<32×n> — the $60 week wins" (32n > 60 for every n ≥ 2). Short form on the badge at ≤640px only: "casuals $<32×n> — the $60 week wins"; the ledger and a11y mirror always carry the full template. Driven at n = 1 (absent), 2 ($64) and 5 ($160).
Membership declarations ("pause any two weeks a year — just tell us" / "no lock-in, cancel with a week's notice") appear on exactly three surfaces — badge subline, ledger, and the visually-hidden a11y mirror — when the membership chip is selected, and are asserted absent on every other plan.
Disable semantics: packs and privates disable the stepper with the on-page reason "packs don't run to a week — come when it suits you"; the week rail ghosts to dashed outlines. Unlocking (chip back to membership or casual) restores the prior stepper value — driven and asserted (set 4 → 10-pack → back → still 4).
Designed price-less states: clinical pilates and mums-and-bubs print no number ("after an assessment" / "term dates on request"), and the FAQ answers the health-fund question honestly: group classes aren't claimable; some funds rebate physio-supervised clinical sessions — no figure quoted, because none would be honest.
Grid floors = cheapest outputs: intro $48, casual $32, 10-pack $290 ($29), week $60 ("classes from $12 each on the week", the n = 5 figure), privates from $86 (5-pack) / $95 single.
Grammar note: at n = 1 the badge reads "…at 1 class a week" (singular) — the pinned template's dollar figures are what the harness asserts.
Above the fold at 375px: name, "Reformer & mat pilates in South Perth — stronger, quietly", book CTA, phone CTA and the est. 2017 / capped-at-8 / $48-intro trust line — all measured inside the first viewport. The planner sits directly under them; on desktop it shares the 1200×750 thumbnail with the hero copy, and the harness asserts the scene, the front-desk card and the display moment all intersect the first 750px.
Click-to-call everywhere: header tel link (number visible ≥1000px, icon below), a ghost-button phone CTA in the hero, and a fixed call/book bar in the bottom 140px on mobile with ≥44px targets.
Planner → form handoff: the selected plan and rhythm pre-fill the booking textarea ("Unlimited week ($60 a week) — 3 classes a week, about $20 a class…"), and stop auto-updating the moment the visitor edits it themselves.
Form fields fit the trade: name, phone, suburb, an experience select (first time / returning / clinical enquiry — choosing clinical reveals the priced-after-assessment note), preferred times, and the pre-filled plan. Front-end validation only; the confirmation panel is hidden on load and on an empty submit, and appears only after a valid submit — with a plain line saying no details were sent anywhere.
Mobile front-desk card: below 641px the scene is too small for an overlay card to avoid the drawn reformer, so the card docks just under the scene, lapping its bottom edge — same pin, same rotation-free tight variant, zero collisions by construction. At ≥641px (including the 900–1100px band) it stays pinned on the wall with the full templates.
Local SEO we'd implement for the real business
This demo page ships only WebPage/BreadcrumbList schema naming it a demonstration — fictional structured data in a real index would be dishonest markup. For a real studio we'd ship ExerciseGym (the exact schema.org organization subtype: SportsActivityLocation → ExerciseGym — a pilates studio is a gym-family business, not a medical one) with real NAP, geo, hours and review feed:
What else changes for the real client: their photography replacing the drawn scene (or keeping it — it converts), a live class timetable and real booking through Momence or Mindbody, a ClassPass feed if they want the marketplace traffic, Stripe billing behind the weekly membership, and a Mailchimp automation on the intro offer (book class one → nudge before class three → membership offer in week two).
Techniques
Single inline SVG scene; all positioning via attribute transforms on outer groups, all animation via CSS opacity/transform on separate inner elements or JS attribute writes — never both on one element (the W16/W17 rule).
rAF loop with zero-clamped, capped delta; paused on document.hidden; reduced-motion gets a designed settled frame.
Two-segment IK for the legs; springs re-pathed per frame from the live carriage edge.
HTML badge over SVG (solid fills — headless Chrome composites backdrop-filter unreliably, so conversion chrome never uses it).
Procedural SVG service-area map (Perth Water, ferry line, star, dashed reach ring) — stylised and labelled as such.
Measured every palette pair with WCAG arithmetic from the shipped tokens — all landed on the spec-time figures (moss 12.66:1, CTA white 6.10:1, hover 8.15:1, euc-ink 7.15:1, timber-ink 5.53:1); timber stays lines-only at 2.53:1.
Screenshot review caught the front-desk card covering the SAT/SUN day tabs at 1200px — compressed the rail (44-unit tabs, 6-unit gaps, rail ends at 400 units) so all seven days clear the card at every ≥641px width.
A second collision at 1000px (narrower planner column) was fixed by making the card width scale with the scene: clamp(200px, 42%, 252px).
The clinical service card's nowrap price forced ugly hyphen breaks — allowed it to wrap. Redrew the shelf plant as a potted eucalyptus (the first version read as a stray glyph) and moved the casual ticket stub off it.
Pass 2 — Depth
Fold-glyph figures now scale-in (0.55 → 1) as their day lights, so changing the rhythm reads as people arriving, not pixels toggling.
The front-desk card does a small settle "bump" when its figure changes — animated with the CSS translate property so it can't clobber the card's rotation transform.
Non-breaking spaces keep "just tell us" together on the membership declaration — no more orphaned "us" on the card.
Drove every worked example against the independent oracle: per-class 60/30/20/15/12, casual notes at $64 and $160 (template scales), intro/10-pack/private/private-5 figures, and both rapid-fire volleys.
Pass 3 — Hardening
375px masthead measured edge-to-edge (wordmark right edge vs call-button left edge, book CTA inside the viewport); sticky call/book bar confirmed fixed in the bottom 140px with a tel: link.
Decided and documented the mobile badge placement: below 641px the card docks under the scene rather than overlaying it — an overlay at phone scale must cover either the rail, the door still-lifes or the reformer, and covering the drawn subject is the one thing a badge may never do.
Chanel rule: removed the unreadable 7.5px "ONE" micro-text from the ticket stub.
Reduced-motion path verified headlessly (scene visible, probe settled, no loop); empty submit leaves the confirmation hidden and marks 5 fields invalid on a fresh navigation; filled submit shows the designed panel; zero console errors across every drive.
True Form Pilates is a fictional business — a pilates studio industry demonstration designed & built by Sapience Analytics, part of the Generative Assets collection.