Longrun — build notes

Generative Assets · Industry demonstration

A day, drawn once— how the Longrun page was built.

Longrun Energy is a fictional Osborne Park home-battery business. Its landing page has one job: turn “should I get a battery” into a booked site visit, with the honest answer — including “that one’s too big for your roof” — already on the screen. These are the notes: the palette with measured ratios, the drawing, the two models behind it, and what changed across three passes.

01 — THE CONCEPTYour evening is a fixed length. The battery either covers it or it doesn’t.

A home battery is sold on capacity, and capacity is the wrong number. What a household actually wants to know is how far into the night it gets before the meter starts spinning again — and whether the thing it is being sold can even be filled by the roof it already has.

So the page is a night dashboard with one fixed 24-hour axis running across it: the day’s solar in mint, the household load as a pale stepped line, the 3–9 pm peak washed in violet floor to ceiling, and the battery’s state of charge filling and draining underneath. The audience is the Duncraig household exporting all day for two and a half cents, the Como couple who lost the fridge in the last outage, and the Hammond Park family being quoted 30 kWh by somebody who never asked what their evening looks like.

Two of the three are conversion arguments. The third is a refusal, and it is the most valuable thing on the page.

02 — PALETTEA Perth sky after sunset, and two accents that mean something.

Every ratio below was computed with WCAG arithmetic from the shipped hexes and re-measured against the tokens actually in the stylesheet. The site is deliberately dark, which keeps it off the cream-and-serif default; it carries two argued accents rather than one acid note, which keeps it off the near-black-plus-accent default; and the ground is blue-tinted evening, not near-black.

Evening#131A24The page ground. Cards lift to #1B2430, hairlines #2C3949. Blue-tinted rather than black, because the subject is dusk, not night.
Cool light — body ink#E6EBF0 · 14.58:1 / 13.05:1On the ground and on cards. Captions use #9FAEBE at 7.72:1 and 6.91:1.
Stored mint#54C79A · 8.34:1 / 7.46:1Charge, generation, and the primary CTA. It clears as text unminted, so no second ink was needed. As a button fill it carries the ground ink, not white; hover #74DBB2 reads at 10.42:1.
Peak violet — marks only#8A7CE0 · 5.03:1 / 4.50:1The 3–9 pm wash and the tariff marks. On cards it measures 4.502:1, which clears the floor by two thousandths and is not a margin, so violet copy uses the pre-minted lighter ink below.
Violet ink#A99CEC · 7.21:1 / 6.45:1Every violet word on the page. The two-token remedy on a dark ground runs lighter, not darker.
Import coral#E0796B · 5.93:1 / 5.30:1Grid-import bars and the “back on the grid” band. Never a call to action — the colour means you are paying peak rates.

Scene fills, each measured against the light ink

Every fill in the drawing carries labels, so every fill had to clear 4.5:1 against #E6EBF0 before it was allowed into the scene. None needed a separate label ink.

FillHexInk ratioWhere
Peak wash#241F3D13.08:13–9 pm window, floor to ceiling
State-of-charge band#1D3A3310.27:1Under the charge curve
Grid band#33222A12.48:1The hours the house is back on the network
Roof steel#2A333D10.68:1The changeover board in the left gutter

Map labels are body-ink class, not accent class: the suburb names on the service-area map are set in #E6EBF0 with a 4.4 px evening-ground halo via paint-order: stroke, so they hold their ratio wherever they cross the drawn coastline or the river.

03 — TYPEA clock face, laid flat.

Outfit at 700 carries the display voice — a geometric sans with even, circular bowls, chosen because the whole page is a clock face laid out horizontally and the headline should share its geometry. Rubik at 400/500 does the reading: a workhorse with slightly softened corners that stays comfortable at 17 px on a dark ground.

One third face appears in exactly one role. JetBrains Mono at 500 sets clock strings and energy strings only — 00:20, 11.5 kWh, 3–9 PM PEAK — because a figure that changes as you tap should not reflow the words around it. Every label inside the drawing is mono for the same reason.

The typographic moment is the coverage time set enormous in mono at −0.07em tracking, with the installed price stamped beside it and COVERED FROM 3 PM ruled underneath. It is the only place on the page where type is allowed to be loud, and it is loud about the one number the customer actually asked for.

04 — THE DAYWhy the axis does not move.

The signature is a single SVG assembled synchronously from the state, redrawn on every control change. It runs a fixed axis from 06:00 to 06:00 horizontally and a fixed 0–30 kWh scale vertically, and both of those decisions are the argument rather than a convenience.

The fixed 24-hour axis

A zoom-to-fit frame would rescale as the battery grew, and rescaling is exactly the lie the page exists to refuse: it would make every battery look like it covers the same amount of evening. Your evening is a fixed length. So the axis holds still and the drawing changes underneath it.

The fixed 0–30 kWh energy scale

Same reason, and it costs legibility only at the bottom of the range. The smallest drawn state — a 5 kWh battery — fills 16.7 % of the chart height, which at every tested width is a band tens of pixels tall with its own capacity rule and label. That fraction was computed before the chart was drawn, precisely so the fixed scale could be defended rather than assumed.

Four layers, drawn in this order

  • The peak wash. 15:00 to 21:00, floor to ceiling, in #241F3D with violet edges. It sits behind everything so the eye reads the expensive hours as a place, not a legend entry.
  • The roof. A half-sine from 06:45 to 18:15 peaking at 3.4 kW, filled with a mint gradient. It carries no kilowatt-hour total, deliberately — see the honesty note below.
  • The load. A two-level step at exactly the values the coverage model uses: 0.48 kW outside the peak, 1.4 kW from 3 to 9. The drawing and the arithmetic are the same two numbers, so the picture cannot disagree with the ledger.
  • The charge. A filled band under the state-of-charge curve, with a dashed rule at the selected capacity. Where the roof cannot reach that rule, the gap between them is hatched and labelled.

Where the badge goes, and how tall the scene is

At 641 px and up the price badge sits on the scene at the upper left. The drawing does not assume a height for it: it measures dayBadge.offsetHeight and reserves that plus 18 px as a strip above the charts, so the badge can never intersect the drawn subject at any width. At 640 px and below it docks directly beneath the artwork, still inside the signature’s container. Both regimes are asserted at 375, 1000 and 1200 by comparing the badge’s client rect against the transformed bounding boxes of the solar, load and charge groups.

Motion

Three mint dots travel the state-of-charge path using getPointAtLength, so the animation traces the actual computed curve rather than decorating it; the coverage rule breathes and the peak wash swells. Every animated opacity has a floor of 0.55 or higher, so the signature is visibly alive at any capture instant rather than being phased to a particular screenshot time. The rAF delta is clamped at zero as well as capped, and the loop stops when the tab is hidden. Under prefers-reduced-motion the entrance duration is zero, the scene renders fully drawn on the first frame, and no loop starts at all.

The one thing the drawing does not claim

The arc is the shape of a day, not a measurement. No daily generation total is printed anywhere, because printing one would invite arithmetic that the pinned 11.5 kWh charge figure is not derived from. The 11.5 kWh is stated as what it is: an assumption about what an average Perth day puts into a battery from a typical 6.6 kW system after the house has taken its share. Stating an assumption is honest; drawing a curve and letting the reader integrate it into a different number is not.

05 — THE NUMBERSTwo models, both integer-safe, both oracle-checked.

The page runs two independent models. Both were reimplemented from the specification in a separate script (oracle-batterystorage.mjs) and every figure below was checked against that reimplementation before it shipped — 109 assertions, zero corrections, including all 108 cells of the price grid and both branches of the coverage table.

Price

total = 2400 + 620 × kWh + backup + switchboard + inverter. Every anchor is a whole dollar and every multiplier is a whole number of kilowatt-hours, so no cell in the grid can produce a fraction of a cent. The enumeration confirms it: 108 cells, 0 non-integer totals.

LineRateNote
Base$2,400Install, isolation, metering and the Western Power application
Battery$620 / kWh5 to 30 kWh usable, in 5 kWh steps
Essential-circuits backup$1,450Backup sub-board and changeover
Whole-home changeover$3,900Automatic transfer switch on the main switch
Switchboard upgrade$980Forced by the two clauses below
Hybrid inverter changeover$2,150Where the existing string inverter can’t coexist

The cheapest reachable output is $5,500 (5 kWh, no backup, board fine, existing compatible solar), which is exactly the “from” price on the services grid — the estimator’s floor and the grid’s floor are the same number by construction, not by coincidence. The dearest is $28,030 (30 kWh, whole-home, hybrid), and there are 52 distinct totals in the grid.

Coverage

The evening block runs 15:00 → 21:00 at 1.4 kW (8.4 kWh); the night block runs 21:00 → 07:00 at 0.48 kW (4.8 kWh). On a solar day the battery can only take what the roof puts in, so available = min(capacity, 11.5 kWh). With no solar it charges off-peak overnight and available = capacity.

All of this is held in watt-hours and minutes, as integers. 0.48 kW and 11.5 kWh in floating point produce exactly the class of drift the wave’s money-in-cents rule exists to prevent — 11.5 − 8.4 evaluates to 3.0999999999999996, and the 03:27 clock reading is one rounding decision away from becoming 03:28. Watt-hours divided by watts, times sixty, floored, never touches a decimal.

UsableSolar day — covered untilNo solar — covered untilUnfilled on a solar day
5 kWh18:3418:34
10 kWh00:2000:20
15 kWh03:27the whole night, 07:003.5 kWh
20 kWh03:27the whole night, 07:008.5 kWh
25 kWh03:27the whole night, 07:0013.5 kWh
30 kWh03:27the whole night, 07:0018.5 kWh

The saturation is the point

Look at the third column. Above 11.5 kWh the coverage time stops moving. Fifteen, twenty, twenty-five and thirty kilowatt-hours all land on 03:27, because on a solar day they are all the same 11.5 kWh battery with progressively more empty space bolted on. The chart hatches that empty space and a note prints beside the price: your roof put 11.5 kWh in today — the top 18.5 kWh of this battery never filled.

It would have been trivial to smooth this — a small efficiency gradient, a bit of assumed grid top-up, and the number would keep improving forever. It is shipped exactly as designed, because a page that keeps rewarding a bigger purchase is a page that is selling, and the whole positioning of this fictional business is that it will tell you when to buy less. The verification drives all six capacities and asserts the note’s absence at 5 and 10 kWh as strictly as its presence at 15 and above.

Choosing “no solar” replaces the headroom note entirely with a different declaration — charged off-peak overnight — this battery is shifting load out of the 3–9 pm peak, not storing your own solar — because in that scenario the battery genuinely does fill, and the argument changes from capacity to tariff arbitrage. The harness asserts that the headroom wording is absent in that branch, not merely that the new line is present.

What forces the switchboard, and what happens on the way back

Two independent clauses force the $980 upgrade and disable “board is fine as-is” with an on-page reason. A whole-home changeover lands on the main switch, which an old board cannot carry. And 25 kWh or more needs a second sub-board and a properly rated main switch. Either one alone is enough.

The pre-force value is remembered. It is restored only when both constraints release, and it is cleared outright if you explicitly change the switchboard chip while it is free — an explicit choice always beats a remembered one. On a partial unwind, where one constraint relaxes but the other still bites, the forced value is held, not stepped down:

StepCapacityBackupSwitchboardMemory
Rest10 kWhEssentialFine (free)
Raise to 2525 kWhEssentialForced upgrade“fine”
Add whole-home25 kWhWhole-homeForced (both clauses)“fine”
Drop to essential25 kWhEssentialHELD — capacity still bites“fine”
Drop to 20 kWh20 kWhEssentialFine — restoredcleared

The last row lands on $16,250, and both halves of that unwind are driven separately in the verification — the backup half and the capacity half — because a chain that only ever relaxes one constraint cannot see a hold-versus-restore bug.

Worked figures, measured from the running page

ConfigurationTotalCovered untilNote
10 kWh, essential, board fine, compatible solar (rest state)$10,05000:20none
10 kWh, no backup, board fine, compatible solar$8,60000:20none
15 kWh, essential, board fine, hybrid inverter$15,30003:273.5 kWh unfilled
20 kWh, whole-home (board forced)$19,68003:278.5 kWh unfilled
25 kWh, no backup (board forced by capacity)$18,88003:2713.5 kWh unfilled
5 kWh, no backup, board fine, compatible solar (floor)$5,50018:34none

The number that is deliberately absent

There is no payback figure anywhere on this page, and that is a designed refusal. Payback depends on your tariff, your export credit under Synergy’s Distributed Energy Buyback Scheme, and what your house actually does between 3 and 9 pm — three things a web page cannot know and a quarter of interval data can settle in ten minutes. Every battery site in the country prints a payback year; almost none of them can defend it. The page says so out loud beside the prices, and the verification asserts that no year-shaped payback claim appears in the rendered text. Rebates get the same treatment: the federal battery discount is described as applied at installation and is already in the figures, and the WA state rebate is named as claimed separately and explicitly not included — never folded into a total to make it look smaller.

06 — CONVERSIONWhy the page is shaped like this.

  • The clock is the hero, not the price. Nobody wakes up wanting a 10 kWh battery. They want the fridge on at nine. So the enormous figure in the hero is 00:20 and the price is stamped beside it — the answer first, the cost second.
  • The price appears in two places above the fold. Once in the hero stamp and once on the badge painted on the scene, because the 1200 × 750 preview is the commercial argument and a ledger below the fold does not make the capture. Both are asserted to sit inside the first 750 px at 1200 wide.
  • The refusal is a conversion tool. “The top 18.5 kWh never filled” is the single most persuasive sentence on the page, because it is the one sentence a salesperson would never write. It earns the phone call that the price alone would not.
  • Four controls, no more. Capacity, backup, switchboard, inverter. Everything else a real quote needs — roof orientation, tariff, meter type, fire separation — is what the site visit is for, and the page says so rather than pretending to model it.
  • The signature hands off to the form. “Send this configuration through” writes the whole scenario, the total, the coverage and the headroom note into the enquiry, so the office receives a warm lead instead of “how much for a battery”.
  • A required consent checkbox, not a pre-ticked one. The call-back promise sits beside the submit as static copy; the designed confirmation panel is hidden on load and on an empty submit, and appears only after a valid filled submit. Nothing is ever sent anywhere, and the panel says so.
  • Every control changes the drawing. The switchboard chip is the only one that moves money without moving much on the scene — so the backup chip draws its circuits on the changeover board, the inverter chip removes the solar arc entirely, and capacity moves the dashed rule the hatching hangs from.

07 — THE THREE PASSESWhat each pass actually found.

Pass 1 — Craft

The thumbnail was mostly hero, and the legend argued with the chart.

  • The scene started at y = 677 at 1200 wide, leaving 73 px of drawing inside the 750 px preview. The hero was a two-column grid with the headline, lede, buttons and trust line all stacked in the left column and a short stamp alone on the right — a tall left column and 200 px of dead space beside it. Rebalanced so the left column carries eyebrow, headline and lede while the right carries the stamp, the buttons and the trust line. With tighter hero padding, a shorter headline and a 348 px drawing ceiling, the scene now begins at 477 and the badge sits at 488.
  • The legend contradicted the drawing. The coral band in the chart is labelled ON THE GRID and the legend read “Off the grid” — the exact opposite of what coral means. Changed to “Back on the grid”. A colour that means “you are paying peak rates” cannot have a legend that reads like an off-grid brochure.
  • The right-hand axis read as a column of orphaned digits5 / kW / 30 / 20 / 10 / kWh — with the unit floating away from the number it belonged to. Rewritten as 5 kW at the top of the power band, 0 at each baseline and 30 kWh on the top charge line, and the power baseline label was nudged 5 px clear of the charge scale’s top label.
  • The trust strip was built as an inline-flex row with a gap, which is how the previous wave shipped “AS 1288 , barriers to” with a space before the comma. Rebuilt as normal inline flow: the item is a block, the dot is an inline-block ::before with a right margin. Running prose is never a flex container.
  • All 21 contrast pairs were recomputed from the shipped tokens rather than trusted from the spec. Every one matched to two decimal places, including the violet-on-card figure of 4.502:1 that justified minting the lighter violet ink.
Pass 2 — Depth

Make the small states worth reading, and give the charge somewhere to go.

  • At 375 px the drawing was 198 px tall and had been stripped of almost every label — no peak marker, no capacity rule label, no board caption, no axis numbers. The phone user got a shape. Raised the mobile drawing floor to 236 px and gave the four load-bearing labels tiny-width variants instead of suppressing them: 3–9 PM, 10 kWh, ESS. and 3 WAYS. Only the decorative ones (YOUR ROOF, 1.4 kW, EMPTY) still drop below 420 px.
  • The second read: the energy is drawn moving. Three mint dots travel the state-of-charge path itself via getPointAtLength — so they climb slowly through the solar morning, hang at the plateau, and accelerate down the discharge. Nobody notices on the first visit; on the second it is obvious that the dots are reading the same curve the ledger is.
  • The hatched headroom got a label of its own on the scene, separate from the badge note: 18.5 kWh NEVER FILLED set inside the hatching, suppressed when the band is too short or too narrow to carry it. The badge tells you; the drawing shows you where.
  • The whole-night state runs past the right edge of a fixed axis, because the model’s night block ends at 07:00 and the axis stops at 06:00. Rather than stretch the axis (which would break the fixed-frame argument for every other state), the coverage rule pins to the right edge with an arrow and reads ALL NIGHT — 7:00. The badge switches from a clock time to “covered to 7:00 am” in the same state, so the two surfaces agree.
  • Micro-interaction: the capacity stepper repeats on press-and-hold after 440 ms, so getting from 5 to 30 is one gesture rather than five taps — and the click that ends a hold is swallowed so the value never overshoots by one.
Pass 3 — Hardening

375, the keyboard, the rapid-fire race, and one ornament removed.

  • At 375 the call button and the trust line were the last things above the fold, and only just. Below the two-column break the hero’s right column now reorders: buttons first, trust line second, the stamp third. The value proposition, a 48 px call button and a trust signal all clear the fold at 375 × 812 with the sticky bar in place, and the stamp follows immediately after.
  • The masthead was measured explicitly at 375 — the wordmark’s right edge against the call chip’s left edge, not just a page scroll width — because that is the collision that keeps shipping. The wordmark drops to “LONGRUN” and the tagline hides below 560 px.
  • Rapid-fire driven twice. Eleven control clicks dispatched in a single evaluate with no settle between, then a second seven-click burst. Every handler bumps the scene token before the state swap, so an in-flight entrance whose token no longer matches simply returns instead of indexing a rebuilt array. Zero errors, and the settled state matched the oracle both times.
  • Every form pattern was proved by driving checkValidity on a deliberately invalid value, not by reading the attribute. Chrome compiles pattern as a v-flag regex, which rejects unescaped literals that older flavours accepted and leaves the field silently validating nothing; every literal special in every class here is escaped, and the zero-console-error assert is the net underneath.
  • The label-collision sweep found two defects no assert could see. Every state assert was green and every ratio measured, but at 30 kWh with no solar the battery holds full all day — and the coral “back on the grid” band was drawn before the state-of-charge band, so a full battery buried it and its label under the mint fill. It now draws in its own group after the charge, with a grid-band halo on the label. In the same screenshot, the capacity rule at 30 kWh sits on the top edge of the chart, and the 30 kWh USABLE label hung above it escaped the plot entirely into the gap between the two charts. The label now flips under the rule whenever there is less than 14 px above it. Asserts prove state; only pixels prove composition.
  • The excess ornament removed: the drawing originally carried a second violet glow behind the hero on the right as well as the mint one on the left, plus a .wide size variant for the stamp clock that no state ever reached. Both are gone. One evening sky, one clock size.
  • Reduced motion renders the scene fully drawn on the first frame with no rAF loop started at all, and the state probe reports settled: true immediately — asserted, along with no group left at opacity 0.

08 — LOCAL SEOWhat we’d implement for the real business.

The live page carries only WebPage, CreativeWork, WebSite and BreadcrumbList schema that names itself a demonstration. Marking a fictional business up as a real local business would pollute a real index, and the testimonials on the page are demonstration copy — they are never emitted as structured review data. For a real client we would ship the block below.

The top-level type is Electrician, which is a genuine LocalBusiness subtype rather than a specialty token that merely looks like one; the battery specialisation is carried through knowsAbout and a real hasOfferCatalog, which is what actually earns service-level rich results.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Electrician",
  "@id": "https://longrunenergy.com.au/#business",
  "name": "Longrun Energy",
  "description": "Home battery retrofit across the Perth metropolitan area: batteries onto existing rooftop solar, hybrid inverter changeovers, essential-circuits and whole-home backup, and switchboard upgrades.",
  "url": "https://longrunenergy.com.au/",
  "telephone": "+61 8 9XXX XXXX",
  "image": "https://longrunenergy.com.au/img/battery-osborne-park.jpg",
  "priceRange": "$$$",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "Unit N, Example Road",
    "addressLocality": "Osborne Park",
    "addressRegion": "WA",
    "postalCode": "6017",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.90, "longitude": 115.81 },
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
      "opens": "07:00", "closes": "16:00" }
  ],
  "areaServed": [
    { "@type": "City", "name": "Perth" },
    { "@type": "AdministrativeArea", "name": "Peel region, Western Australia" }
  ],
  "hasCredential": [
    { "@type": "EducationalOccupationalCredential",
      "credentialCategory": "Clean Energy Council accreditation — battery storage" },
    { "@type": "EducationalOccupationalCredential",
      "credentialCategory": "WA electrical contractor licence" }
  ],
  "knowsAbout": [
    "home battery storage", "hybrid inverter changeover",
    "AS/NZS 5139 battery system installation", "AS/NZS 4777.1 grid connection",
    "Western Power embedded generation connection",
    "Synergy Distributed Energy Buyback Scheme", "switchboard upgrades"
  ],
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Battery services",
    "itemListElement": [
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Battery retrofit onto existing solar" },
        "priceSpecification": { "@type": "PriceSpecification",
          "minPrice": "5500", "priceCurrency": "AUD",
          "valueAddedTaxIncluded": true } },
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Whole-home changeover" },
        "priceSpecification": { "@type": "PriceSpecification",
          "price": "3900", "priceCurrency": "AUD",
          "valueAddedTaxIncluded": true } },
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Switchboard upgrade" },
        "priceSpecification": { "@type": "PriceSpecification",
          "price": "980", "priceCurrency": "AUD",
          "valueAddedTaxIncluded": true } }
    ]
  },
  "review": [
    { "@type": "Review",
      "author": { "@type": "Person", "name": "(a real, consented customer)" },
      "datePublished": "2026-08-11",
      "reviewRating": { "@type": "Rating", "ratingValue": "5", "bestRating": "5" },
      "reviewBody": "Talked us down from 30 kWh to 15 and showed us why." }
  ],
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.9", "reviewCount": "—",
    "description": "fed from the live Google Business Profile, never hand-written"
  }
}
</script>

Beside the markup: a Google Business Profile with the Osborne Park base, the service radius and the CEC accreditation attribute set; one page per real search intent rather than per keyword (“home battery Perth cost”, “is my inverter battery ready”, “what stays on in a blackout”, “WA battery rebate”); and suburb pages only where there is a completed install to put on them. The rebate page in particular has to be maintained like a live document, because a stale rebate figure is the fastest way for a battery installer to lose trust.

09 — FOR A REAL CLIENTWhat changes on day one.

  • The rates come out of the job-costing system, not the HTML. simPRO or Tradify for job costing and quoting: the base, the per-kWh rate and the flat lines live there, the estimator reads them, and a price rise is one field rather than a deploy.
  • The enquiry becomes a job. The form posts into simPRO or ServiceM8 as a lead with the configured scenario attached, so the office is not retyping a web enquiry into a scheduler — and the switchboard photo request goes out automatically.
  • The coverage model runs on real interval data. This is the big one. A customer’s NMI data from Synergy, or a live feed from an existing inverter, replaces the assumed 1.4 kW evening and 0.48 kW night with their actual load, and replaces the assumed 11.5 kWh charge with their measured surplus. The same drawing, the same axis, their numbers — and at that point the payback figure the page currently refuses to print becomes defensible.
  • Live monitoring after the install. Fronius Solar.web, SolarEdge or Tesla’s API on the commissioned system, so the page the customer already trusts becomes the page they check — and the business sees a failing cell before the customer does.
  • Compliance is evidence, not a claim. CEC accreditation currency and the EC licence pulled from the register, so the trust strip links to something live rather than asserting it.
  • Their photographs. Every drawing here is procedural because that is the collection’s constraint, but a real installer’s best asset is a photograph of a tidy switchboard and a neatly mounted battery. The Day stays, because a photo cannot show you where the charge stops.
  • Real reviews, fed live. The Google Business Profile feed replaces the demonstration testimonials — and only then does the review markup above go anywhere near production.