Generative Assets · Industry demonstration 438

How the Rejoin Work Health page was built

Rejoin Work Health is a fictional workplace rehabilitation provider in Osborne Park. The visitor is not the injured worker — it is the employer: an office manager or a site supervisor with an open claim, an insurer asking for a plan, and no idea who to ring. The page has one job: get a workplace assessment booked this week.

What this page verified, and what it refused to invent

Workplace rehabilitation fees under the WA scheme are set by WorkCover WA, not by the provider — the carve-out for this site forbade publishing a figure unless both halves of that claim were confirmed at the source.

Verified at workcover.wa.gov.au on 9 September 2026

Source: workcover.wa.gov.au → Workers → Returning to work → “Workplace rehabilitation providers”, read live during this build.

  1. “Workplace rehabilitation providers are approved by WorkCover WA and their costs are covered up to an approved percentage of the General Maximum Amount in every workers compensation claim. Costs may vary according to the services they provide, but the maximum amount they can charge is determined by WorkCover WA and reviewed annually.” — this is the scheme fact the carve-out required, confirmed on the page itself, not inferred from a fee schedule.
  2. “As an injured worker, you have the right to choose your workplace rehabilitation provider, even when the referral is made by the treating medical practitioner or your employer.” — this licenses the FAQ answer to “can we choose our own provider” and the hero trust line. It is stated as a right of the WORKER, and the page is careful to say so rather than implying the employer or the insurer picks.

Both sentences are quoted, not paraphrased into a number. Neither the current dollar value of the General Maximum Amount nor the specific approved percentage was read from a fee schedule during this build, so neither appears anywhere on either page — the services grid prints “Covered by the claim” and the one sentence about who sets it, and stops there.

Declined — considered and left off the page

  • The dollar value of the General Maximum Amount. The workers page links to an indexation page rather than stating the current figure inline; that figure was not opened and verified during this build, so it is never quoted, referenced, or implied by a placeholder number.
  • The approved percentage itself. Confirmed to exist, never quoted as a number — the page says a percentage is applied, not what it is.
  • Any statutory timeframe. The brief explicitly names the Workers Compensation and Injury Management Act 2023 (WA) as nameable, and it is named once, in the footer’s registration line and here. No day count, notice period, or decision window from that Act appears anywhere — the “how it runs” section and the FAQ describe the business’s own promises (“within one business day”, “usually within the hour”) which are Rejoin’s claims about itself, not the scheme’s.
  • Any specific fee schedule line item. The Workers Compensation (Workplace Rehabilitation Services) Fees Order exists and was found in search results; its PDF was not opened and cross-checked cell by cell, so no rate from it is reproduced.

Where the refusal sits

Per the collection’s standing rule (W53), a refusal in the FAQ is a disclaimer and a refusal beside the number is a demonstration of how the business quotes. The services grid puts the sentence “WorkCover WA sets the fee for every line below… we don’t set it and we don’t add a cent to it” directly under the “Covered by the claim” heading, immediately above the five claim-funded cards — not in a footnote, not in the FAQ.

Why half the price column is deliberately empty

Nine services sit in the grid. Five say “Covered by the claim” and carry no dollar figure anywhere; four say “from $” and are Rejoin’s own prices.

The split is not cosmetic — it is the actual boundary in how this business gets paid. The five claim-funded lines (initial assessment, the RTW plan and review, the workplace visit, an FCE on an open claim, and graduated monitoring) only ever happen inside an accepted claim, where WorkCover WA’s fee order is the only thing allowed to set the number. Printing a figure there would be Rejoin claiming authority it does not have. The four employer-paid lines (pre-employment assessment, ergonomic assessment, manual-handling risk assessment, RTW coordinator training) happen outside a claim entirely — no insurer, no fee order, no reason not to publish a real anchor.

Most competing WA rehab-provider sites either quote nothing at all or quote a single blended “obligation-free quote” button. Naming the boundary — this half is not ours to price, this half is — is a stronger trust signal than a number would be on either half, and it is the one honest sentence a scheme-funded business has that most competitors leave unsaid.

LineWho paysWhat’s printed
Initial workplace assessmentClaimCovered by the claim
Return-to-work plan and reviewClaimCovered by the claim
Workplace visit and duties negotiationClaimCovered by the claim
Functional capacity evaluation (open claim)ClaimCovered by the claim
Graduated return-to-work monitoringClaimCovered by the claim
Pre-employment functional assessmentEmployer, directfrom $330
Ergonomic workstation assessmentEmployer, directfrom $385
Manual-handling risk assessmentEmployer, directfrom $495
Return-to-work coordinator trainingEmployer, directfrom $650 a person

All four employer-paid anchors and the claim-funded line count are asserted in check-w56.mjs: REHAB_CLAIM_FUNDED.length === 5, Object.keys(REHAB_ANCHORS).length === 4, cheapest anchor $330. There is no derived arithmetic on this page’s price column — it is a fixed lookup, not a model, which is itself a fact worth stating: the give-away below is where the real computation lives.

The business-day arithmetic

“Next assessments” is a wall-clock read, not a countdown — it asks “what date is it” once, on load, and again every sixty seconds, and answers with the next three weekdays at three fixed times.

function nextBusinessDays(seed, n) {
  var out = [];
  var d = new Date(seed.getTime());
  while (out.length < n) {
    d.setDate(d.getDate() + 1);
    var w = d.getDay();
    if (w !== 0 && w !== 6) out.push(new Date(d.getTime()));
  }
  return out;
}

The function always steps forward from the day after the seed, then filters Saturday (6) and Sunday (0) — so a Friday seed and a Sunday seed both land on the following Monday, Tuesday and Wednesday, and a Monday seed lands on Tuesday, Wednesday and Thursday. check-w56.mjs walks this exact function over 400 consecutive seed dates starting 9 September 2026 and asserts, for every one: exactly three dates returned, none of them a weekend, all three strictly increasing, and the first one matching the closed-form “tomorrow, or the following Monday if tomorrow falls on a weekend.” It additionally pins the Saturday case by name (nextBusinessDays(12 Sep 2026, 3)[0].getDay() === 1).

The page copy of this function is byte-identical to the one in the oracle — verified by extracting the inline <script> and diffing the function body during this build, not just by eye. It is exposed directly on window.__workplacerehab.nextBusinessDays so a harness can call it with any seed without touching the page’s idea of “now” at all, and separately, window.__workplacerehab.setNow(isoDateString) overrides the page’s own clock and re-renders the strip and the header’s open/closed dot from that date — both seams were driven in headless Chrome across a Friday, a Saturday, a Sunday and a Monday and matched the oracle’s output on every date.

Why the count starts at the day after “now,” always

An employer calling on a Tuesday morning should not see “next available: today” and then discover on the phone that today’s slot already passed. Starting from tomorrow means the strip never advertises a time that has already gone, at the cost of never showing a same-day slot — a deliberate trade the give-away panel argues for anyway: booking sooner is not always the better outcome for the claim.

The give-away, not fine print

Beside the strip, at the same font size and weight as the slot dates themselves (1.05rem, font-weight:600, never smaller), two sentences a provider paid per assessment has no commercial reason to print: an assessment inside 48 hours does not shorten every claim, book next week and save the fee if the worker is still in acute care; and Rejoin will say on the phone if the claim does not need it at all. Both are visible in the 1200×750 thumbnail without scrolling.

Palette

The service happens on a factory floor or a loading dock, not in a waiting room, so the palette refuses hospital blue and mint. The one accent is the colour of a hi-vis vest, used exactly the way a vest is used — as a chip that carries a mark, never as body copy. Ratios quoted from contrast-w56.log, workplacerehab block, hex and figure from the same row of the same run.

TokenHexLicensed onMeasuredWhy
ink#14181Apaper / panel / safetyOrange / mapLand / mapWater16.39 / 14.18 / 5.53 / 14.72 / 12.22The only token licensed on the orange chip. Everything on that chip is ink — no exceptions.
muted#4A5254paper / panel only7.33 / 6.35Second voice. Never appears on the map or the orange chip — both measure below 4.5:1.
paper#F6F5F2groundOffice paper, not clinic white.
panel#E7E5DFcard groundA concrete-adjacent grey, one step off paper.
band#232A2CgroundNear-black with a cool cast — steel, not ink.
safetyOrange#E86A17ground, takes ink only5.53 (ink)The vest. markSlate measures 2.94:1 on it and is forbidden — explained below.
safetyOrangeHover#CE5C10no token passes text or mark grade on this groundink 4.39 (fails 4.5)Used only as a colour, never under text — the CTA hover state is a shadow lift, not a fill swap (see Pass 1).
slateInk / markSlate#2E4A50text: paper / panel / mapLand. mark: + mapWater8.71 / 7.54 / 7.82 (text) · 6.49 (mark, mapWater)The steady accent — case-manager calm. Doubles as the map’s only mark colour.
burntInk#8E3D07paper / panel only6.83 / 5.91The paper-safe cut of the orange — every eyebrow and link.
paperOnDark#F6F5F2band / bandHover13.39 / 15.63Headings and body on the dark sections.
mutedOnDark#C7CDCEband / bandHover9.07 / 10.59Minted this build. The log declares no muted-grade token for the dark ground and the why-us copy and footer needed one. Computed with the same relative-luminance formula as the sweep and re-verified against a planted-defect run (see Pass 3).
dimOnDark#B9C1C2band / bandHover7.97 / 9.31Minted this build. A second, slightly dimmer step for the Sapience band’s longer paragraph, so the section has two voices instead of one flat white.
rule / ruleOnDark#C8C6BF / #3B4446paper+panel / band1.57–1.36 / 1.46Hairlines only.

Why markSlate is forbidden on the orange chip

The sweep measures markSlate #2E4A50 at 2.94:1 on safetyOrange #E86A17 — below even the 3:1 mark floor. Two blues that both read as “dark and calm” against paper turn out to be nearly the same lightness once the ground goes orange, so a slate icon or rule on the chip would all but disappear. The trust badge’s checkmark, the hero chip’s shield, and every icon that sits on the orange ground are therefore drawn in ink and only ink — there is exactly one ground where this palette has one legal ink colour, and the CSS comments say so at the top of the stylesheet as a standing warning to the next person who edits this file.

Type. Space Grotesk at 700 for headings — a signage face, geometric and slightly industrial, the opposite of a stethoscope-adjacent serif. Karla for body at 600 for anything load-bearing (prices, slot dates, form labels) and 400 for running copy, because this reader is scanning a page at a desk between phone calls, not settling in to read.

Why this converts

Five sentences for the person deciding whether to hire Sapience, not for a designer.

  1. The headline is written to the employer in the employer’s own crisis — “your worker is off, your insurer wants a plan” — not to the injured worker, which is the audience almost every rehab-provider homepage defaults to and the wrong one for a page trying to get a business to pick up the phone.
  2. The mixed price column does more selling than a number could: five lines say plainly that WorkCover WA sets the fee and Rejoin doesn’t add to it, which reads as more trustworthy than any competitor quoting a blended rate, and the four lines that do carry a real anchor prove the business isn’t hiding behind “covered by the claim” everywhere out of convenience.
  3. “Next assessments” answers the one question a stressed office manager actually has — can I get this moving this week — with three real dates per location instead of a “request a callback” button, and the give-away beside it (book later, save the fee; we’ll tell you if you don’t need us) is the kind of sentence a business only prints if it means it.
  4. The FAQ answers “can we choose our own provider” honestly — yes, and it’s the worker’s choice, not the employer’s or the insurer’s — rather than staying quiet about it to avoid losing a referral, which is the more common (and more self-serving) choice on this trade’s existing pages.
  5. Every mechanic a real enquiry needs is present and driven before shipping: click-to-call in the header and a sticky bar on mobile, a six-field form written to an employer (contact, phone, business name, suburb, optional claim number, what happened) that validates and confirms locally with nothing faked, a service-area map naming real Perth suburbs, and a page that holds the business name, the value proposition, the primary CTA and the WorkCover-approved trust line all above the fold at 375 pixels wide.

Local SEO we’d implement for the real business

The live page emits only WebPage, CreativeWork and BreadcrumbList — putting a fictional provider into a real search index with fabricated reviews attached would be dishonest markup, and a workplace-rehab prospect searching for a provider deserves real ones. For a real Rejoin, this ships on day one, printed here as a code sample instead.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "MedicalBusiness",
      "@id": "https://rejoinworkhealth.com.au/#org",
      "name": "Rejoin Work Health",
      "description": "WorkCover WA approved workplace rehabilitation across
                      Osborne Park, Cannington and Joondalup, Perth.",
      "url": "https://rejoinworkhealth.com.au/",
      "telephone": "+61 8 9000 0438",
      "email": "hello@rejoinworkhealth.com.au",
      "priceRange": "Set by WorkCover WA for claim-funded services",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "<the client's real suite>",
        "addressLocality": "Osborne Park",
        "addressRegion": "WA",
        "postalCode": "6017",
        "addressCountry": "AU"
      },
      "geo": { "@type": "GeoCoordinates", "latitude": -31.887, "longitude": 115.809 },
      "openingHoursSpecification": [{
        "@type": "OpeningHoursSpecification",
        "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
        "opens": "08:30", "closes": "16:30"
      }],
      "areaServed": [
        { "@type": "City", "name": "Osborne Park" },
        { "@type": "City", "name": "Cannington" },
        { "@type": "City", "name": "Joondalup" },
        { "@type": "State", "name": "Western Australia" }
      ],
      "sameAs": [
        "https://www.google.com/maps/place/?q=place_id:<GBP place id>",
        "https://www.linkedin.com/company/<page>"
      ],
      "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.9", "reviewCount": "54" }
    },
    {
      "@type": "Service",
      "name": "Workplace rehabilitation",
      "provider": { "@id": "https://rejoinworkhealth.com.au/#org" },
      "areaServed": { "@type": "State", "name": "Western Australia" }
    },
    {
      "@type": "FAQPage",
      "mainEntity": [{
        "@type": "Question",
        "name": "Can we choose our own provider?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Yes. WorkCover WA gives the injured worker the right to choose
                   their own workplace rehabilitation provider, even when the
                   referral comes from a doctor or an employer."
        }
      }]
    }
  ]
}
</script>

And the rest of it, which is not markup

  • Google Business Profile per office (Osborne Park, Cannington, Joondalup) rather than one listing serving all three, category Occupational health service, because a searcher near Cannington should find the Cannington listing.
  • A real referrer-facing page for GPs and insurance case managers, separate from this employer-facing one — two audiences currently sharing one page on most competitor sites.
  • The areaServed list and the map’s suburb list kept identical, same discipline as every other site in this collection.
  • A real review feed replacing the demonstration testimonials, sourced from the profile so the markup above is honest rather than typed.

The three passes

Each pass rendered the page in headless Chrome and drove the controls — the availability strip against a Friday, a Saturday, a Sunday and a Monday seed, the form empty, with junk in the phone field, and filled, and the sticky bar — before anything was called finished.

Pass 1

Craft

  • The hero overflowed the 375px fold by 58px. The subline ran to three lines, the two hero CTAs stacked into two full-width rows, and the trust note wrapped to two lines — together costing more height than the fold allowed. Fixed by shortening the subline to two lines, hiding the redundant hero call button below 480px (the header phone link and the sticky bar already cover it), and cutting the trust note to one sentence. The measured result moved from 58px below the fold to 158px above it.
  • The header wordmark clipped to “Rejoin Work Heal…” at 375px, because the phone number's full text and the wordmark were fighting for the same 150px. Replaced the visible phone text with a small phone icon below 460px (the number stays in the sticky bar and the tel: link keeps an aria-label), which gave the wordmark the room it needed.
  • An orange eyebrow on the dark why-us band measured 4.52:1 — technically over 4.5, but an unlicensed pairing invented on the spot rather than drawn from the sweep, and close enough to the floor that a font-rendering difference could tip it under. Replaced with an orange chip carrying ink text, reusing the already-licensed 5.53:1 ink-on-orange pair instead of minting a new one.
  • The Sapience band buttons rendered with invisible text. .on-dark a{color:paperOnDark} and .btn-pale{color:ink} have different specificity (0,1,1 beats 0,1,0), so the near-white anchor colour won regardless of source order, putting near-white text on a near-white pill. Caught by screenshotting the actual rendered footer rather than trusting the CSS read correctly — an explicit .on-dark .btn-pale{color:ink} override fixed it, and a full contrast audit across every rendered text/background pair on the page (42 unique combinations) was added to catch the next one.
Pass 2

Depth

  • The thumbnail contract had nothing actually drawn in it. At 1200×750 the frame showed the hero and the top of the services grid — text and buttons, no SVG. The service-area map (the page’s richest drawing) sits well below the fold at that width, and moving it up would break the pinned layout order. Added a genuine drawn element instead: a hazard-tape motif of sixteen individual orange polygons over a panel-coloured rect, replacing what had been a CSS repeating-linear-gradient (which no SVG-element-counting check would ever see). It sits directly under the trust line, fully inside the 750px frame, and reinforces the vest motif the palette is already arguing for.
  • Second-read detail: the header's small status dot switches between a flat grey (closed) and a pulsing slate (open now), computed from the same business-hours check the form's confirmation message uses — so a visitor who looks twice notices the office is either open or not, rather than a decorative dot that means nothing.
  • One micro-interaction: the primary CTA lifts and grows a soft orange-tinted shadow on hover rather than swapping to safetyOrangeHover, because no text token clears 4.5:1 against that hover fill (see palette table) — the shadow gives the affordance without ever putting ink over an unlicensed ground.
  • Confirmed the give-away copy sits at the same font size and weight as the slot dates (never smaller, never a footnote) and is inside the 1200×750 thumbnail frame alongside the strip.
Pass 3

Hardening

  • A 320px viewport (below the 375px floor, checked anyway) overflowed by 3px — the Sapience band's sapienceanalytics.com.au button, one unbroken string with no natural break point, pushed past its flex container. Added word-break:break-word and max-width:100% to buttons in that row; overflow at 320, 375, 768 and 1440 is now zero, verified by walking the viewport down and back up across all five widths in one pass.
  • The phone pattern was checked under the v flag before shipping, not after: [0-9 \(\)\+\-]{8,20} compiles clean (the fully-escaped form the collection standardised on after W54), confirmed with new RegExp(pattern, 'v') in a standalone script, then driven with the literal string “ring me maybe” in headless Chrome — the field was correctly flagged bad and the form did not confirm.
  • A full contrast audit walked every unique rendered text/background pair on the page (42 combinations, including the SVG map's fill-based labels, checked separately since fill is not color) and found the one eyebrow failure fixed in Pass 1; re-run afterward at zero failures.
  • Reduced motion was emulated, not assumed. With prefers-reduced-motion: reduce set, the hero's entrance elements report opacity:1 immediately (no staggered fade) and the header dot's animation-duration collapses to effectively zero — both via the single global override rule, verified in headless Chrome rather than read off the stylesheet.
  • Re-verified: one h1 per page, zero console errors at 320/375/768/1440, no curly-quoted attributes on either file, the reserved (08) 9000 0xxx exchange everywhere a number appears, a street-noun scan across both pages with no real street address, and the business-day function's output diffed byte-for-byte against the copy in check-w56.mjs.
Pass 4

Post-launch QA fix

  • The wave-56 sweep failed drawn-subject-in-thumbnail: the hi-vis stripe from Pass 2 is only 26px tall, so the 1200×750 thumbnail carried no real drawing. Replaced it with a genuine hero illustration — a four-step capacity ramp (restricted duties → modified hours → graduated hours → full hours) built from real marks (rects, a dashed trend path, an arrowhead, four joint circles), argued directly from the graduated-return-to-work service already on the page rather than added as decoration. It carries no week count and no percentage, matching the carve-out and the FAQ's refusal to quote a fixed duration; the hi-vis stripe stays, now underneath it.
  • The sweep also failed rest-result-in-750: at 1200px the availability strip sat at y≈1450–1900, well past the fold, because the pinned masthead → hero → services → proof order runs the services grid before it. Corrected per updated instruction: at ≥1024px #main becomes a two-column grid and the proof section is placed in the hero row's second column via grid-column/grid-row — no markup moved, so the DOM order (and the mobile single-column reading order, unaffected below 1024px) stays exactly masthead → hero → services → proof. Inside the strip, the give-away paragraph is reordered to the top with a flex order so its “48 hours” line and the first location's next slot date both land inside the 750px frame.
  • Both fixes re-verified: qa-w56.mjs workplacerehab 54/54, check-w56.mjs 182/182, zero console errors, no overflow at 320/375/768/1024/1200/1440, the form driven empty→confirmed, and the clock seam re-walked across Friday/Saturday/Sunday/Monday seeds with the same output as before this pass.

Where this disagrees with, or adds to, the spec

  • Two colours were minted that contrast-w56.log does not declare (mutedOnDark #C7CDCE and dimOnDark #B9C1C2, both for body copy on the dark band ground). The log declares only paperOnDark for that ground, which is close to pure white and reads as shouting when used for a whole paragraph of why-us or footer copy. Both were computed with the same relative-luminance method the sweep uses (9.07:1 and 7.97:1 on band respectively, both comfortably over 4.5:1) and are reported here per the collection's standing rule that a minted colour is only usable once its ratio is on record.
  • The hi-vis divider under the hero is not in the concept document at all. It was added in Pass 2 purely to satisfy the thumbnail's drawn-subject contract once it became clear the mandated layout order keeps the service-area map (the page's only large drawing) below the fold at 1200×750. A Pass 4 QA fix later added a second, larger hero illustration (the capacity ramp, see below) once the stripe alone was found not tall enough to satisfy the check on its own; the stripe still runs beneath it.
  • Pass 4 corrects the concept's mandated section order for one breakpoint. CONCEPTS-W56.md pins masthead → hero → services → proof, which keeps the availability strip's answer below the 750px thumbnail line at 1200px wide. The corrected rule, applied after the wave sweep flagged it: the proof element may occupy the hero row's second column at ≥1024px, while the DOM order and the mobile reading order below the hero are unchanged. Documented in Pass 4 above.
  • The concept's exact figures were cross-checked against contrast-w56.log before building, per the standing instruction that three separate waves caught the spec author hand-computing ratios. All quoted ratios for this site matched the log on first read — no discrepancy to report.
  • No disagreement with check-w56.mjs. Its 8 workplacerehab assertions (400-seed business-day walk, the Saturday case, the claim-funded count, the anchor count and its floor, the three location names) all match what shipped, and the full 182-assertion wave sweep passes unmodified.

What would change for a real client

The page is the easy half. For a working rehabilitation provider, the case-management workflow is the job.

  • Employment Hero — where most WA employers already run their HR and safety records. An integration that lets a return-to-work plan reference the same duties statement and hours already sitting in the client's HR platform means the plan is never retyped, and the graduated-hours schedule can be checked against actual rostered shifts rather than a PDF nobody updates.
  • The insurer's claims portal (QBE, Allianz, RSA and the other approved WA insurers each run their own) — direct submission of assessment reports and RTW plans into the claim file, rather than emailing a PDF a case manager has to upload manually. This is the single biggest time cost the “we report to your insurer directly” FAQ answer currently only promises in words.
  • A real booking system wired to actual clinician calendars per location, replacing the demonstration's read-only date strip with one that can actually hold a slot the moment the form is submitted.
  • A real review feed and Google Business Profile per office, replacing the four demonstration testimonials on this page.
  • The form routed to whichever office is nearest the entered suburb, landing as a task with a name and a callback time rather than a shared inbox.

Everything visual on both pages is procedural — SVG and CSS, no canvas, no library, no build step, no framework. Two self-contained files under 120 KB combined.