Generative Assets · Industry Demos · how it was made
How the Greenlane Nutrition demo was built
Greenlane Nutrition is a fictional Victoria Park clinic of Accredited Practising Dietitians — gut health and IBS, weight and metabolic health, sports performance, pregnancy and family nutrition, in the clinic or by telehealth, with GP care-plan and NDIS billing. The page exists for one reader: the person a GP has just referred, or the runner chasing a PB, who wants to know what a program costs and what Medicare gives back before they ring. Its single job is a booking request with the program, format, focus and add-ons already priced — to the whole dollar, GST-free, rebates declared and never subtracted.
The Plan Builder
The signature element is a drawn SVG plate seen from above — the "healthy plate": half vegetables, a quarter protein, a quarter wholegrains, drawn as segments with simple food glyphs — with a ring of appointment dots around the rim over week ticks. Every control redraws the scene honestly and reprices the program from the pinned fees:
- Program chip sets the appointment ring: initial consult only (one filled dot), Kickstart (four dots over six week ticks — the initial at week 0 and reviews at weeks 2, 4 and 6), Transform (seven dots over twelve ticks). Dots are labelled "wk N" where they sit clear of the horizontal; a small legend (filled = initial, hollow = review) sits top-left.
- Format chip swaps the fee table ($170 / $95 in clinic, $160 / $90 by telehealth) and on telehealth draws a phone frame around the plate and its ring with a "TELEHEALTH · LIVE" dot — and switches the two in-clinic add-ons off with their reasons (below).
- Focus chip redraws the foods and is price-neutral: gut & IBS (the rest — carrot and zucchini coins, kiwifruit, sweet potato, yoghurt, oats, a kefir glass beside), weight & metabolic (a bigger veg half with leaves, broccoli and tomatoes, chicken and egg, a smaller rice quarter, a water glass), sports performance (a bigger grains quarter of pasta and rice, salmon and two eggs, a recovery shaker), pregnancy & family (leafy greens, salmon and cheese, wholegrain bread, a small second plate). The declaration "same fee whatever we're working on" prints on the appointment card, the ledger and the screen-reader mirror.
- Add-on toggles each draw their object: the personalised meal plan a notebook with a plum tab peeking from under the plate's left edge; body-composition scans the clinic scale bottom-left; the pantry & supermarket session a shelf of jars behind the plate; the GP care plan a Medicare-green tick in the ring's open gap — a note only, the fee never moves.
- The price badge is drawn as an appointment card with a leaf stem: two lines always — the total and the program line ("4 appointments over 6 weeks") — plus the focus declaration and, with a GP care plan, the rebate note. On-scene upper-right beside the plate at ≥641 px (never over the plate, the ring or the glyphs), docked beneath the plate inside the signature's container at ≤640 px, where a phone-width
viewBoxcrop (0 0 860 720) enlarges the plate. - A slow loop lifts three steam wisps off the food (opacity never below .55 — alive at any capture instant) and drifts a highlight around the rim; reduced motion parks the wisps mid-rise. Chip and toggle changes redraw snappy; the loop token is bumped in every handler before the state swap.
Pinned anchors (health fees, GST-free — rebates declared, never subtracted)
| Line | In clinic | Telehealth | Multiplies | Notes |
|---|---|---|---|---|
| Initial consult (60 min) | $170 | $160 | once | always present |
| Review appointment (30 min) | $95 | $90 | appointments − 1 (0 / 3 / 6) | Kickstart 1 + 3, Transform 1 + 6 |
| Personalised meal plan | $120 | $120 | flat | live at every combination |
| Pantry & supermarket session | $150 | — | flat | in clinic only — disabled "in person only" on telehealth, forced off, restored on chipping back |
| Body-composition scans | $40 × appointments | — | the ACTUAL count (1 / 4 / 7) | in clinic only — disabled "needs the clinic scanner", same restore rule |
| GP care plan | fee unchanged | fee unchanged | note: $60 × min(appointments, 5) | "about $60 / $240 / $300 back across this program"; short form ≤640 px "GP care plan: about $N back from Medicare" |
| NDIS / private-health extras | no number | no number | — | "NDIS participants — billed to your plan at the NDIS rate, ask us" on ledger and mirror; extras in the FAQ |
Every rate is a whole dollar and every count a whole number, so no total ever needs rounding. A program, a format and a focus chip are always selected — there is no empty state, and the grid floors are the cheapest priced outputs per program (telehealth, nothing added). The restore memory for the two locked toggles is cleared by any explicit change to that toggle; because a disabled toggle cannot be changed, the memory survives until the format lock lifts — exactly the wave-wide rule.
Worked examples measured from the running page
| Scenario | Arithmetic | Total | Line 2 | GP note |
|---|---|---|---|---|
| Rest state — Kickstart, in clinic, gut & IBS, meal plan on, scans on | 170 + 3 × 95 + 120 + 4 × 40 | $735 | 4 appointments over 6 weeks | absent |
| Initial only, telehealth, nothing on (grid floor) | 160 | $160 | one 60-minute appointment | absent |
| Initial only, in clinic | 170 | $170 | one 60-minute appointment | absent |
| Kickstart, telehealth · Transform, telehealth | 160 + 270 · 160 + 540 | $430 · $700 | — | absent |
| Transform, in clinic, meal plan + pantry + scans | 170 + 570 + 120 + 150 + 280 | $1,290 | 7 appointments over 12 weeks | absent; with the GP toggle on: "about $300 back across this program", total unchanged |
| Format lock drive — Kickstart, in clinic, pantry + scans → telehealth → in clinic | 455 + 150 + 160 → 430 → restored | $765 → $430 → $765 | — | both toggles disabled with reasons, then restored |
| Initial only, in clinic, scans → + meal plan | 170 + 40 → + 120 | $210 → $330 | — | absent |
| GP note on initial only, telehealth | 160 | $160 | — | "about $60 back" |
| Focus neutrality from rest — every focus in turn | — | $735 each | — | declaration on badge, ledger and mirror |
| Rapid-fire — in clinic, meal + scans, program initial → Transform → Kickstart → Transform in one evaluate | 170 + 570 + 120 + 280 | $1,140 | — | steam loop settles to exactly one |
Every worked figure, the three grid floors ($160 / $430 / $700, equal to the services grid), the lock/restore sequence and 32 random control vectors were cross-checked against an oracle reimplemented from the anchors inside the verification harness — not from the page's own code. The final harness run: 397 assertions, all green (the index page plus this guide; the run count is printed in the pass log below).
Palette — a mint-white clinic wall, forest ink, a plum CTA
Argued from the subject: a clinical page that feels like a kitchen table. Leaf green for lines and marks only, apricot only in the drawn plate. Ratios below were computed with WCAG arithmetic from the shipped tokens in Pass 1 (role, hex and ratio from the same script row); every spec figure held.
No token moved in Pass 1: the pre-minted leaf / leaf-ink pair meant the leaf was never asked to carry text, and the plum clears 8:1 everywhere it prints. The form's invalid state uses a deep rose #8E2A3A on #FBEEF1 (7.32:1) rather than the plum, so an error never reads as a call to action.
Type
The display moment is the rest-state line set over the plate — "$735 · KICKSTART · 6 WEEKS · IN CLINIC" — rebuilt from state on every change so the figure is always the live total; the separators travel with the token that follows them so a wrap never strands a middle dot at a line end.
Techniques
- Procedural SVG scene, no libraries. A linen cloth with a faint woven check and the plate's shadow are drawn once; the plate, segments, food glyphs, side object, ring, extras and the live layer are rebuilt into one dynamic group on every state change. Segments are arc sectors whose angles change with the focus (gut 180/90/90°, weight 200/90/70°, sport 150/100/110°); glyphs are placed by a fraction along the segment and a fraction of the well radius, so they re-flow when the angles do. Foods are small parametric drawers — coins, kiwi slices, leaves, broccoli, oats, yoghurt, salmon, eggs, rice, pasta, bread, cheese, tomatoes — in the palette's greens, creams and apricot.
- Dual-speed redraw (W21). First paint staggers each drawn part at 26 ms (1.4 s cap); every later change redraws at 10 ms per part with a 500 ms cap via a
firstDrawflag. Parts animate opacity only, never a property they also set as an SVG attribute. - Token-invalidated loop (W25). The three wisps (a quadratic path rebuilt each frame, rising ~120 units over a 4 s cycle with a .55 opacity floor) and the rim highlight (a 34° arc drifting 9°/s) run in one requestAnimationFrame loop whose token is bumped in every control handler before the state swap; the loop exits on the next frame, the rebuilt scene starts a fresh one, and the probe's
loopscount settles back to exactly one — asserted after two rapid-fire bursts. Delta time is clamped at zero and capped at 50 ms (W29); the loop idles while the tab is hidden. - Appointment card placement. A CSS-positioned HTML badge at the scene's upper-right (right 14 px, top 14 px) at ≥641 px; the scene's right column is composed so nothing drawn sits under the card's worst case (the GP note makes it ≈ 481 scene units tall at 641 px) — the side object starts at 490 units, the legend moved top-left, the scale bottom-left. At ≤640 px the badge becomes a two-column strip docked beneath the plate and the viewBox crops to the plate.
- Reduced motion. CSS media query plus a
matchMediacheck: no loop starts, the wisps and highlight are painted once at a settled phase (t = 1.7 s), entrance transitions are disabled, the hero's rise animation is off. - State probe.
window.__dietitiancarries program, format, focus, the four toggles, every ledger line, the total, line 2, the note strings (full and short), the rebate figure, the disabled / forced flags and restore memory for the two locked toggles, the declaration strings,loopsand asettledflag set after the redraw cap — QA gates on state, never on seconds. Aset()helper applies a full control vector (format first, so the lock semantics run) for the oracle drives.
Conversion decisions
- Above the fold at 375 px: business name, "Accredited Practising Dietitians in Victoria Park — gut health, metabolic health, sport and pregnancy nutrition, in the clinic or by telehealth", Book an appointment + Call us, and the est. 2016 / APD / GP care-plan & NDIS trust line — all inside the first 667 px viewport, measured (the trust line first landed at 737 px and was pulled up by a 28 px h1, a shorter mobile lede and a short call label).
- Book vs call: dietitian bookings are diary work, so the primary CTA is "Book an appointment" with the phone a ghost button; on phones a sticky bar carries Call now + Book now above the thumb, solid white, no backdrop filter, 48 px taps.
- The Builder feeds the form. Program, format, focus, add-ons, the GST-free fee and the GP note pre-fill the booking textarea; "Book this program" refreshes it and focuses the name field. Fields are what a clinic needs to find a time: name, mobile, suburb (the nine service suburbs plus "Elsewhere — telehealth") and a referral select (GP care plan / NDIS / Private / Not sure) that shapes the confirmation copy.
- Honest floors. The services grid's "from" prices are the Builder's cheapest outputs — $160 / $430 / $700 — and the focus declaration, the GP note and the NDIS price-less line appear wherever the total does. Rebates are declared, never subtracted; fees are GST-free and say so on the card hint, the ledger total and the services copy.
- Local confirmation, no fake network. Empty submit flags the required fields inline and keeps the confirmation hidden; a valid submit shows the designed panel ("Thanks — booking request received. We'd call you back within one business day…") naming the program and fee, clearly marked as a demonstration.
Local SEO we'd implement for the real business
The live page carries only WebPage, WebSite and BreadcrumbList structured data naming it a demonstration — a fictional clinic must not mark itself up as a real one. For the real client we would ship the block below. The top-level type is MedicalBusiness — the schema.org organisation subtype for a clinic (there is no Dietitian organisation type; "Dietitian" is not a type at all, and a specialty enumeration would be the wrong family), with the dietetics speciality carried by medicalSpecialty and knowsAbout. Real reviews would be pulled from Google Business Profile and marked up only with the reviewer's consent.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "MedicalBusiness",
"name": "Greenlane Nutrition",
"description": "Accredited Practising Dietitians in Victoria Park — gut health, metabolic health, sport and pregnancy nutrition, in the clinic or by telehealth.",
"url": "https://www.example-greenlane.com.au/",
"telephone": "+61 8 9000 0370",
"image": "https://www.example-greenlane.com.au/clinic.jpg",
"priceRange": "$$",
"medicalSpecialty": "Dietetic",
"address": {
"@type": "PostalAddress",
"streetAddress": "Albany Highway",
"addressLocality": "Victoria Park",
"addressRegion": "WA",
"postalCode": "6100",
"addressCountry": "AU"
},
"geo": { "@type": "GeoCoordinates", "latitude": -31.976, "longitude": 115.905 },
"areaServed": ["Victoria Park", "Carlisle", "Como", "Bentley", "Kensington", "South Perth", "Belmont", "Cannington", "Perth"],
"openingHoursSpecification": [
{ "@type": "OpeningHoursSpecification", "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday"], "opens": "08:00", "closes": "18:00" },
{ "@type": "OpeningHoursSpecification", "dayOfWeek": "Friday", "opens": "08:00", "closes": "16:00" }
],
"knowsAbout": ["dietetics", "irritable bowel syndrome", "low-FODMAP diet", "type 2 diabetes", "sports nutrition", "pregnancy nutrition", "NDIS dietetics", "telehealth"],
"isAcceptingNewPatients": true,
"availableService": [
{ "@type": "MedicalTherapy", "name": "Initial dietitian consultation (60 min)" },
{ "@type": "MedicalTherapy", "name": "Kickstart 6-week program" },
{ "@type": "MedicalTherapy", "name": "Transform 12-week program" }
],
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Appointments and programs",
"itemListElement": [
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Initial consult" }, "priceSpecification": { "@type": "PriceSpecification", "price": "160", "priceCurrency": "AUD", "description": "from, telehealth; $170 in clinic; GST-free" } },
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Kickstart 6-week program" }, "priceSpecification": { "@type": "PriceSpecification", "price": "430", "priceCurrency": "AUD", "description": "from, telehealth; GST-free" } },
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Transform 12-week program" }, "priceSpecification": { "@type": "PriceSpecification", "price": "700", "priceCurrency": "AUD", "description": "from, telehealth; GST-free" } }
]
},
"aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.9", "reviewCount": "112" },
"review": [
{
"@type": "Review",
"author": { "@type": "Person", "name": "Real client, with consent" },
"datePublished": "2026-03-02",
"reviewRating": { "@type": "Rating", "ratingValue": "5" },
"reviewBody": "Pulled from the live Google Business Profile feed — never hand-written."
}
]
}
</script>
Alongside the schema: a Google Business Profile with the clinic pinned on the Albany Highway strip, "dietitian Victoria Park" / "IBS dietitian Perth" / "NDIS dietitian Perth" / "telehealth dietitian WA" as the page's core phrases with the suburbs above as secondary, NAP consistency across HealthEngine, Hotdoc and the Dietitians Australia "Find a Dietitian" directory, and a reviews feed that updates without anyone touching the page.
What changes for the real client
- Bookings: Halaxy or Cliniko behind "Book an appointment" — real diary slots, the new-client questionnaire, reminders, and the Builder's scenario written into the appointment note instead of a textarea.
- Claiming: Medicare / DVA online claiming from the practice software so the care-plan rebate is processed on the day, NDIS service agreements and invoices to plan managers, and private-health extras receipts with item numbers.
- Telehealth: the video link (Coviu or the practice software's built-in room is the kind we'd wire) sent with the booking confirmation, and the telehealth fee table kept in step with the in-clinic one.
- Xero for the invoice and the month's GST-free reporting; the Builder's lines map onto the invoice line items.
- Meal plans: a hand-off to the clinic's meal-plan app (Foodzone or Nutrium named as the kind) so the $120 personalised plan is delivered and revised in the client's app, not a PDF.
- The clinic's own photographs of the rooms and the team, a Google reviews feed, the real APD numbers, ABN and provider number in place of the placeholder patterns, and the real phone number in place of the reserved one.
Iteration log
- Pass 1 — Craft. Contrast measured from the shipped tokens (forest 12.15 / 13.17, white on plum 8.96, plum on the ground 8.27, leaf-ink 5.80 / 6.28, map labels 9.89 on the river and 11.15 on land, apricot 1.69 as fill only) — every spec figure held and no token moved. The first scene read small: 12-unit labels rendered at ~6 px at 1200 wide, so the plate grew from a 200 to a 220-unit rim, the ring from 244 to 262, the glyphs ×1.2 and the labels to 18 units; the long dot labels ("review · wk 4") collided with the appointment card at 1200 and became "wk N" with a legend; the rim's percentage captions (which summed to 101 % on the sports plate) became plain segment names; a drawn fork and knife in the backdrop came out. At 375 the trust line measured 737 px (below the 667 px fold): the h1 dropped to 28 px, the mobile lede lost its second clause, the call button reads "Call us" and the sticky bar "Book now" — the trust line now measures inside the first viewport. Drove the rest state, all eleven worked examples and the form; 382 asserts green on the index before the guide existed.
- Pass 2 — Depth. The appointment card with the GP note on was ≈ 495 scene units tall at 1200 and covered the water glass and the legend — caught on a native screenshot, not by any state assert. Recomposed the right column: the card lost its redundant footer line (the GST-free / rebates statement stays on the card hint and the ledger), the legend moved top-left, the scale moved bottom-left, the side object starts below the card's worst case (≈ 481 units at 641 px). The GP label then struck the scale caption and, on telehealth, the phone frame — it is now a single "GP care plan" beside the tick with the rebate sentence on the card, ledger and mirror. Second-read details: the kefir foam line, the "TELEHEALTH · LIVE" dot on the phone frame, the plum PLAN tab on the notebook, the rim highlight that circles once every 40 s. Pass 2 drove the lock/restore sequence ($765 → $430 → $765 with both reasons on control, ledger and mirror), a restore with mixed prior state ($605), focus neutrality on all four chips, the GP note on all three programs ($60 / $240 / $300), two rapid-fire bursts (one loop after each) and 32 random oracle vectors plus the exhaustive floors — all green.
- Pass 3 — Hardening. 375 px: masthead wordmark right edge 229 px vs call button left edge 239 px (clear), scrollWidth 375 with zero offenders outside the cropped SVG, sticky bar solid at 598–667 px with 48 px taps, h1 bottom 302 px, CTA bottom 493 px and trust line bottom 603 px — all inside the first 667 px viewport; badge docked at 375 and 640, on-scene at 641, 1000 and 1200; FULL note form at 641 and 1000, SHORT form at 640 and 375 while the ledger and mirror keep the full template; reduced motion verified (no loop, wisps parked, every part at opacity 1, controls still work — Transform from rest = $1,140); keyboard Enter and Space drive the chips and the FAQ; the v-flag form patterns compile with zero console errors; live JSON-LD is WebPage / WebSite / BreadcrumbList / ListItem only; reserved-exchange phone sweep clean; the guide's tables sit in
.table-scrolland the guide passes the same 375 probe. The Chanel rule removed the scene's drawn cutlery. Final copy read in Australian English.
One composition call resolved by the builder and worth naming: the spec's "ring of appointment dots" pins four dots over six ticks and seven over twelve; the ring is drawn as a 270° arc opening at the bottom so the GP care-plan tick has a place on the ring's line without sitting on a dot, and so the last review dot never lands exactly where the initial one started.
This is a demonstration build by Sapience Analytics. Want one pointed at your customers?