Tankline — build notes

Generative Assets · Industry demonstration

A depot at night— how the Tankline page was built.

Tankline Fuel Services is a fictional Kewdale bulk fuel carrier. Its landing page has one job: turn “what do you charge to deliver” into an account, with the cents per litre, the delivery charge and the monitoring plan already on the screen — and the fuel price honestly left out of it. These are the notes: the palette with measured ratios, the drawing, the pricing model and its oracle, and what changed across three passes.

01 — THE CONCEPTThe one number a fuel supplier can’t honestly quote, and every number they can.

Bulk fuel is the rare trade where the biggest line on the invoice is not the supplier’s to set. Diesel is priced off the published terminal gate price — the wholesale price at the terminal on the day the truck loads — which moves daily with the product market and the exchange rate. What a carrier actually sells is the cents per litre they put on top, the delivery charge, and the monitoring that stops you running out.

So this page prices the service and refuses to price the product. The estimator computes the delivery margin and the delivery charge; wherever a total appears, a pinned declaration appears with it: the fuel is billed at the terminal gate price on the day of delivery — we don’t set it, and we show it on the invoice. Choose AdBlue and that declaration is replaced, not supplemented, because AdBlue is not a terminal gate product at all. Any implication that Tankline sets the fuel price would be a defect, and the verification harness asserts the absence of the terminal-gate line in the AdBlue state as hard as it asserts its presence everywhere else.

The audience is four people: the Forrestfield transport yard filling twelve trucks off a 10,000 L tank, the Gingin farm that runs out mid-harvest every second year, the Canning Vale civil contractor whose site tank sits behind a gate a semi can’t turn into, and the Welshpool workshop buying AdBlue in drums who never realised it comes bulk. The page is designed at 375 px first, because all four of them read it standing next to a tank.

02 — PALETTENight hardstand, a placard, and two products that will not take white type.

Argued from the yard: the graphite of wet hardstand under a light mast, the orange of an ADG placard, the blue of AdBlue, and the straw of clean diesel. Every ratio below was computed with WCAG arithmetic from the shipped token, and re-measured in Pass 1 against the surfaces the token actually lands on.

Depot graphite#15181A · groundNot black. A graphite ground keeps the page off the near-black-plus-one-acid-accent default and lets two argued product colours coexist. Cards lift to #1E2225, hairlines #31373B.
Yard light#E9ECEC · 15.01:1 ground, 13.48:1 cardBody ink. Captions use the muted #A6AFB2 at 7.98:1 on the ground and 7.17:1 on cards — still miles above the floor.
Placard orange#E8912F · 7.24:1 ground, 6.50:1 cardClears as text unminted on this dark ground, so no second ink was needed. As a CTA fill it carries the GROUND ink at 7.24:1 (hover #F4A957, 9.05:1). White on this orange is 2.46:1 and never ships. It never sets copy on the hairline tint, where it drops to 4.90:1.
AdBlue blue#3FA0D8 · 6.14:1 ground, 5.52:1 cardThe second product accent and the telemetry line. It measures only 4.16:1 on the hairline tint, so blue copy is never set on a tinted row — a rule the page keeps rather than a colour it re-mints.
Diesel straw#C8B27A · 1.75:1 light ink, 8.58:1 ground inkFails the light ink outright. Every label sitting on this fluid is set in the dark ground ink #15181A. The fill is not darkened to make the light ink work — clean diesel is that colour.
AdBlue fluid#8FCBE8 · 1.49:1 light ink, 10.09:1 ground inkSame remedy, same reason. Labels on the fluid are ground ink; the fluid keeps its real pale blue.
Tank steel#5A6367 · 5.17:1 light inkScene fill. Clears the body ink, so tank labels outside the fluid stay in yard light.
Bund & hardstand#3A4045 (8.84:1) · #23282B (12.54:1)Both clear the light ink comfortably; the tanker body #454C50 measures 7.36:1. Map labels use the body ink with a graphite halo wherever they cross a fill.

The gate-post grey #6C777C is a LINES-ONLY token. The body ink measures 3.87:1 against it, so nothing is ever set in type on a gate post — the 8 m dimension is drawn as a leader with its label on the hardstand instead.

03 — TYPETanker lettering, a workshop form, and a meter readout.

Saira 700 carries the display. It is a squared industrial grotesque with the proportions of the lettering that actually goes on a tanker barrel and a placard — narrow apertures, flat terminals, no warmth. Work Sans 400/500/600/700 is the workhorse: it has the plainness of a delivery docket and stays legible at 17 px on a phone in the sun.

One third face in exactly one role: Inconsolata 600, for litre and rate strings only — 6,000 L · 6.5 c/L. Monospace is doing a job here rather than decorating: a meter readout is a fixed-width thing, and the tabular figures stop the rate string reflowing as the number changes under a stepper.

The typographic moment is the delivery charge set enormous over the hardstand with the rate string beneath it in mono at wide tracking: $390 over 6,000 L AT 6.5 C/L. Because the signature is taller than 600 px, that figure prints in both the hero column and the on-scene badge, so the thumbnail’s commercial argument is satisfied with margin rather than by luck.

04 — THE DROPHow the signature is built.

The Drop is a single inline SVG, redrawn from scratch on every state change. It is a scale section of the customer’s tank bank standing on its bund, with the tanker reversed in alongside, the hose run drawn to the fill point, and the swept path the vehicle needs painted on the hardstand in front. A 1.7 m figure stands on the hardstand holding the scale. No canvas, no WebGL, no libraries at all — the whole page is one file with zero external JavaScript.

The view-fit rule

The frame is zoom-to-fit on the tank count: frame = 4 + 5 × tanks metres, so 9 m at one tank and 34 m at six. Each tank is drawn 2.6 m wide with a 0.5 m gap and a 0.7 m bund lip, so the bank grows at 3.1 m per tank while the frame grows at 5 m — which means the space left for the tanker grows with the tank count. At one tank you see the rear of the vehicle cropped at the frame edge, like a detail view; at six the whole 19 m semi fits.

The figure never changes size relative to the scale. At the 34 m frame it is 5.0 % of the frame width, which is small, so at four tanks and up it is drawn with its own leader and a 1.7 m dimension rather than left to read alone. There is no drawn cap: six tanks is the enumerated maximum and it draws at 375 px.

Litres as geometry

Each tank has a 9,500 L safe fill and a pinned resting level of 3,500 L, which is where the 6,000 L of ullage per tank comes from. Fluid height is 0.8 + (litres ÷ 9500) × 2.4 metres of usable internal height. The resting stock draws at half opacity; this drop stacks on top of it at full opacity with a bright surface line in the product mark colour, and a dashed safe-fill line sits above both. The drop fills sequentially — tank one to its ullage, then tank two — which is what makes the ullage clamp legible: when every tank is brimmed, you can see there is nowhere for the rest to go.

The swept path

The hardstand in front of the bund is a foreshortened ground plane (a 0.30 vertical squash). The swept path is drawn in it as a true circular band — a 12 m centreline radius with the vehicle’s half-width either side, plus a dashed 0.5 m clearance envelope — sampled to a polyline so the non-uniform projection never has to be expressed as an SVG arc flag. Two gate posts sit 8.0 m apart across the path.

This is where the access chip earns its keep. A rigid sweeps 6.4 m; with 0.5 m of clearance either side that is 7.4 m through an 8 m gate, and the dashed envelope lands inside the posts. A 19 m semi sweeps 7.4 m; the envelope is 8.4 m and visibly crosses both posts, which the drawing marks with a clash ring. That is the honest reason the rigid caps at 10,000 L: a tight site takes more, smaller drops at a higher band, and that is usually still cheaper than widening a gate. Yard layouts are checked against AS 2890.2, the off-street commercial vehicle standard.

Assembly, entrance and liveness

The whole drawing is assembled synchronously and the entrance choreography is driven from the animation loop itself — never by post-hoc DOM insertion or class toggles on a scene the loop already owns, which is a failure mode that can leave groups unpainted in headless Chrome while every state assert stays green. First draw gets a staggered entrance capped at 1.5 s; every subsequent state change redraws snappy at a ~520 ms cap, via a firstDraw flag, so a stepper tap reads as polish rather than lag.

Three things stay alive at rest: the flow dashes running along the hose, the fluid surface rocking on the delivered band, and the light mast’s glow breathing. All three have a never-invisible floor — the hose flow’s opacity oscillates between 0.78 and 0.98, never toward zero — so the seven-second thumbnail settle captures a visibly live scene at any instant, with no phase arithmetic. The rAF delta is clamped at zero as well as capped (min(max(now − last, 0) ÷ 1000, 0.05)), because a vsync timestamp can precede the performance.now() that scheduled the frame and a negative accumulated t would drive geometry negative.

The badge

The badge is an HTML overlay, not SVG text, so it can wrap and reflow. It is in the FULL text regime because the frame grows with the tank count: at 641 px and up it carries line 1, line 2, the declaration and any note. At 640 px and below it docks directly beneath the artwork, still inside the signature container, and drops to short forms with the declaration and note falling back to the ledger and the a11y mirror — which carry the full templates at every width regardless.

The scene’s height is a function of the badge’s measured height, never a fixed aspect ratio: the sky band is grown to (badge.offsetHeight + 26) ÷ k metres whenever that exceeds the base 1.7 m. The binding contract is the rectangle-intersection assert — the badge’s box never intersects the tanks’ or the tanker’s box — tested at 375, 1000 and 1200.

05 — THE NUMBERSMoney in cents, rates in tenths of a cent, and one exact coincidence.

Every rate is held as an integer. Cents-per-litre lives in tenths of a cent — 95, 75, 65, 55, and a flat 120 for AdBlue, with premium adding 15 — and money lives in cents. The delivery charge is billed × tenths ÷ 10 cents, divided once, at display. This is not fussiness: 400 * 4.6 evaluates to 1839.9999999999998 in IEEE doubles, and a naive toFixed(0) hides that until a later comparison fails. The price function ends by asserting Number.isInteger on every field it returns and throws if one is not.

The model, in full. billed = min(volume, tanks × 6000); the band is read off the billed litres, not the ordered litres.

LineRuleNote
Delivery margin9.5 / 7.5 / 6.5 / 5.5 c/LBands by billed litres: under 2,000 / 2,000–4,999 / 5,000–9,999 / 10,000 and over.
Premium additisedband + 1.5 c/LAdded to whichever band the drop lands in.
AdBlueflat 12.0 c/LNo bands. Capped at 10,000 L — it goes out in the small tanker.
Minimum delivery$150 a dropThe truck, the driver, the licence and the meter cost the same at 500 L as at 5,000.
Travel$0 / +$120 / quotedMetro within 60 km; Peel and Avon 60–150 km; beyond 150 km the travel is quoted, never guessed.
Monitoring$28 per tank per monthA genuine recurring charge, quoted as its own line and never folded into the delivery total.
The fuelNever priced on this page. Terminal gate price on the day of delivery, shown on the invoice.

The exact-coincidence cell

At 2,000 L of diesel the computed margin is 2,000 × 7.5 c = $150.00 — equal to the minimum delivery charge to the cent. The minimum does not bind there, and the page must not label it as a minimum, because it is earned rather than floored. The estimator carries a separate minimumCoincides flag and prints a note that says so out loud. One step down, at 1,500 L, the 9.5 c band computes $142.50 and the minimum genuinely does bind — that is the only place on the whole grid where a cents figure is ever displayed, and it is displayed deliberately.

Every other charged total on the reachable grid is a whole number of dollars by construction, not by rounding: billed litres are always a multiple of 500, so 50 × (billed ÷ 500) × tenths is a whole number of cents, and the only sub-dollar results sit below the minimum where the floor takes over.

Worked figures. Every one was re-derived by an independently written oracle before the page was built, and again by the verification harness driving the running page.

ScenarioBilledRateDeliveryMonitoring
Rest: 6,000 L diesel, semi, metro, 2 tanks6,000 L6.5 c/L$390$56/mo
8,000 L diesel, semi, metro, 2 tanks8,000 L6.5 c/L$520$56/mo
Same order on 1 tank — ullage clamp6,000 L6.5 c/L$390$28/mo
2,000 L diesel — exact coincidence2,000 L7.5 c/L$150.00 earned$56/mo
1,500 L diesel — minimum binds1,500 L9.5 c/L$142.50 → $150$56/mo
1,000 L AdBlue — minimum binds1,000 L12.0 c/L$120 → $150$56/mo
1,500 L AdBlue1,500 L12.0 c/L$180$56/mo
25,000 L diesel, semi, metro, 5 tanks25,000 L5.5 c/L$1,375$140/mo
25,000 L premium25,000 L7.0 c/L$1,750$140/mo
25,000 L diesel into the Peel/Avon25,000 L5.5 c/L$1,495$140/mo

Reachability, checked rather than asserted. 25,000 L only bills 25,000 L at five tanks or more — ⌈25000 ÷ 6000⌉ = 5 — so the worked example above states the tank count rather than leaving it to the rest state. On two tanks the same order clamps to 12,000 L and prices at $660. The oracle enumerates the full control grid: 1,188 reachable priced cells (1,404 including the cells the caps force down before pricing), 252 of them minimum-charge cells, 90 ullage-clamped, and zero non-integer results.

The cheapest reachable output is $150, which is exactly the services grid’s “from $150 a drop” floor — the page does not argue with itself. The dearest single drop on the grid is $1,870: 25,000 L of premium into the Peel/Avon zone.

Clamps, forces and unwinds

  • Ullage is a note, not a disable. Order more than tanks × 6,000 and we bill what actually fits, with a note naming the ordered litres, the ullage, the tank count and the billed litres. The band is read off the billed figure — 8,000 L on one tank bills 6,000 L at 6.5 c, not at 6.5 c on 8,000.
  • Two controls impose the same 10,000 L cap. AdBlue caps it because the product goes out in the small tanker; a rigid caps it because that is what a rigid carries. Volume steps above the cap are disabled with the reason printed on the page, and a volume above the cap is forced down with the pre-force value remembered.
  • Partial unwind: hold, don’t step down. From 20,000 L with AdBlue and a rigid, switching the fuel back to diesel relaxes one constraint but the rigid still caps at 10,000 — so the forced value holds and the memory survives. Switching access to a semi then restores the full 20,000. Both halves are driven in the verification pass, from both directions.
  • Restore memory is cleared by an explicit move. Touch the volume stepper yourself while it is forced and the remembered value is discarded — you have overruled it. Otherwise the memory survives until the lock lifts.

06 — CONVERSIONWhy the page is shaped like this.

  • The honest thing is the hook. “We don’t set the fuel price. We tell you what we charge on top of it” is the headline because it is the exact sentence a fleet manager has been trying to get out of three suppliers. Refusing to quote the fuel is not a gap in the page; it is the page’s argument.
  • The price lives inside the artwork. The rest total prints in the hero column and on the badge painted on the night sky, so the 1200×750 thumbnail carries the commercial argument either way. A ledger below the fold does not make the capture.
  • Click-to-call in three places. Masthead, hero CTA row, and a fixed sticky bar at the bottom on anything under 861 px. All tap targets are at least 44 px, and the sticky bar is a solid background rather than a blurred one, because backdrop-filter composites differently in headless Chrome and the thumbnails are headless captures.
  • Form fields the trade actually needs. Name, phone, business, suburb, tank capacity, wanted-by date, and a free-text field that asks specifically about the gate — because access is the question that decides which truck comes and what the drop costs. The Drop’s “send this order through” button pre-fills the tank size and the scope from the current scenario, turning the demo into a warmer lead.
  • A consent checkbox that carries the honesty clause. Required, and its label is the terminal-gate declaration — so nobody can submit an enquiry without having read the one thing this page insists on.
  • The confirmation is local and says so. Hidden on load and on an empty submit, shown only after a valid filled submit, and it tells you plainly that nothing was sent anywhere. No fake network round-trip.
  • An a11y mirror beside every visual. The ledger is mirrored as a plain-text aria-live paragraph carrying the full templates — the rate, the delivery, the travel, the total, the declaration, the monitoring, and any active note — at every width, including the widths where the badge has dropped to short forms.

07 — THE THREE PASSESWhat each pass actually found.

Three fine-tooth-comb passes, each one driving the page rather than loading it: empty and filled submits, every chip and stepper, the estimator driven to twelve pinned scenarios against an independently written oracle, both halves of the partial unwind from both directions, a rapid-fire drive with no settle between clicks, and a native-resolution screenshot review at 375, 1000 and 1200 plus DPR 2. The harness ends at 272 asserts, all green, with zero console errors.

Pass 1 — Craft

Six defects the asserts could not see, and one the fold could.

  • The resting stock failed its own ink rule. Older stock was drawn at 0.5 opacity over the tank’s dark interior, which put the pinned dark ground ink at 3.22:1 on diesel straw and 3.63:1 on AdBlue — under the floor, on the exact labels the palette says must be dark. Raised to 0.72, measured 5.15:1 and 5.93:1. The fluids themselves were not darkened; the transparency was the bug.
  • The hose ran through the tank. The delivery hose sagged below both of its ends, so the curve rose steeply from the reel and passed straight through tank one’s shell and fluid on its way to the fill point. It now arcs over the bank and lands on the fill dome. Every state assert was green throughout.
  • Half the swept path was buried. The arc’s centre was placed so the band’s near half fell behind the ground line, hidden under the bund — and because the centre was tied to the tanker’s position, at low tank counts the whole turn ran off the left edge of the frame. The centre is now anchored at Rc + 4.6 (so the outer gate post lands 0.6 m in front of the ground line) with its x set as a fraction of the frame rather than of the tanker, so both gate posts are drawn at every tank count. Fence wings were added either side of the opening so 8.0 m reads as a gate rather than two sticks.
  • The apron was too shallow for its own geometry. An 8 m opening drawn across a radial line spans about 10.2 m of plan depth, and the ground band was only 7.5 m. Raised to 11 m of drawn yard (3.3 screen-metres at the 0.30 squash).
  • The prime mover read as a second barrel. It was one long low box. Redrawn as a cab at the nose with chassis rails running back to the fifth wheel — which is also what finally makes the rigid and the semi tell apart at a glance.
  • Two labels overran their frames. The 1.7 m figure dimension sat to the right of its own dimension line, inside the bund lip, clipped by tank one; it moved to the clear air above the head. The full swept-path clause overran the SVG’s right edge at 375 px; the scene now carries a short form below 560 px while the ledger and the a11y mirror keep the full statement at every width.
  • The drawn subject missed the fold. At 1200 px the badge, the docket and the hero all made the first 750 px — and the actual drawing did not, so the thumbnail was an argument about typography. The hero lost about 60 px (padding, h1 clamp, stamp scale) and the badge was widened from 340 to 430 px so its declaration wraps to two lines instead of three, which shortens the sky the clearance rule has to reserve. The tanks and the tanker now cross the fold with room.
Pass 2 — Depth

The drop rises, the tanks report, and the clearance rule earns its keep.

  • The fuel goes in. The delivered band now tweens from the previous state’s litres to the new one over 460 ms on a cubic ease-out, driven from the same animation loop rather than a separate timer. On first load it rises from empty — so the seven-second settle catches a filled tank, and every stepper tap shows fuel arriving instead of a number changing. The panel’s own promise is “watch it go into your tanks”; until this pass it didn’t.
  • Every tank on the bund is a monitored tank, so it says so. Each tank grew a telemetry aerial with a pip that blinks in sequence along the bank, floored at 0.42 opacity so it is never dark at a capture instant. This moves the $28-per-tank-per-month line out of the ledger and into the artwork, where the tank count is already the thing you are adjusting.
  • Second read: the gauge. Three tick marks on each tank’s near wall at 25, 50 and 75 % of the safe fill, the half-mark brighter than the quarters. Nothing points at them; they reward looking twice and they make the ullage line mean something.
  • The rectangle-intersection assert caught the consequence immediately. The aerials extended each tank group 0.62 m above the tank tops, and the badge promptly landed on one — three width bands failed at once. The clearance reserve is now (badge height + 26) ÷ k + 0.62, which is the real lesson: the badge-vs-scene rule is a function of what is drawn, not of the tank shell. The tank-count label then collided with a pip and was lifted above the aerials.
  • Reduced motion had to learn the tween. The settled frame now writes every band’s final geometry and every pip’s full opacity directly, so the no-motion path renders the finished drop rather than an empty tank.
  • Easing. The entrance opacity ramp went from linear to a cubic ease-out, which is the difference between parts appearing and parts arriving.
Pass 3 — Hardening

375 first, the keyboard path, and one ornament removed.

  • The keyboard path, driven not assumed. Arrow keys move through the chip sets, change the state and carry a measured 3 px :focus-visible outline; Home and End jump the ends, and disabled chips are skipped rather than focused.
  • Two label collisions only the pixels found. At 375 px the 7.4 m sweep tag was anchored at the arc’s deepest radius and clipped by the frame’s bottom edge; it moved in to Rc − 3.2 and is clamped to Hpx − 6. At 1000 px with five tanks the badge’s bottom-right corner overlapped the tank-count label; the label is now anchored to the bank’s right edge, which is structurally the far side from the left-anchored badge.
  • The light mast read as a stray mark. Its pole was #31373B against a sky that runs #101315 to #1B2023 — effectively invisible — so the lamp head floated unattached in the corner. Pole re-inked #4A5257 and the mast reads as a mast.
  • Chanel rule: one glow removed. The page carried three radial glows — the hero’s, the scene’s light mast and the map’s. The hero’s went. The scene’s mast is the argued light source for a depot at night; the hero glow was decoration, and at 375 px it was decoration nobody could see.
  • Copy read, with the arithmetic checked. The FAQ claimed AdBlue “crosses the $150 floor at 1,250 litres”. The arithmetic is right (1,250 × 12 c = $150.00 exactly) but 1,250 L is not one of the order steps, so the sentence now says so and names the two reachable neighbours instead: 1,000 L bills the minimum, 1,500 L bills $180. A true number about an unreachable state is still a claim a reader can’t check on the page.
  • Checked and already clean. No backdrop-filter anywhere on the header, the sticky bar or the cards. Every SVG toggle goes through setAttribute, never the non-existent hidden IDL. The [hidden]{display:none !important} guard is present. The rAF delta is clamped at zero as well as capped, and the loop is cancelled on visibilitychange. Every masthead line clears at 375, 1000 and 1200 with the wordmark’s right edge compared explicitly against the call button’s left edge.
  • The rapid-fire drive. Fifteen control clicks dispatched in a single evaluate with no settle between them — chips, steppers and zone changes interleaved — twice over. No errors, and the settled figures still matched the oracle, because every handler bumps the scene token before the state swap rather than inside the deferred rebuild.

One thing worth flagging. The concept pins the ullage-clamped cell count at 126 and the priced grid at 1,404; the oracle here counts 90 and 1,188, because it prices only the cells the caps leave reachable and excludes the 216 combinations the volume force pushes down before pricing. No priced figure differs — every worked total, band, clamp and minimum matched to the cent — it is a difference in what gets counted, not in what gets charged.

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

The live page emits only WebPage, CreativeWork, WebSite, BreadcrumbList and ListItem structured data, all of it naming the page a demonstration. Tankline is fictional, so shipping LocalBusiness or Review markup for it would be dishonest markup in a real index — the demo testimonials on the page are prose and are never marked up as review data.

This is the schema we would ship on day one for a real bulk fuel carrier, with the real ABN, the real dangerous goods licence, the real depot address and reviews pulled from a live feed rather than written by us. FuelStation is not the right type — that is a retail forecourt — so the top-level type is LocalBusiness with the delivery area and the product catalogue attached.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "@id": "https://tankline.example.com.au/#business",
  "name": "Tankline Fuel Services",
  "description": "On-site bulk diesel, premium additised diesel and AdBlue delivery
                  across Perth, the Peel and the Avon, with tank monitoring and
                  auto-replenish.",
  "url": "https://tankline.example.com.au/",
  "telephone": "+61 8 XXXX XXXX",
  "email": "orders@tankline.example.com.au",
  "priceRange": "$$",
  "image": "https://tankline.example.com.au/img/depot-kewdale.jpg",
  "logo": "https://tankline.example.com.au/img/logo.png",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "REAL STREET ADDRESS",
    "addressLocality": "Kewdale",
    "addressRegion": "WA",
    "postalCode": "6105",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.98, "longitude": 115.97 },
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
      "opens": "05:00", "closes": "17:00" },
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday", "opens": "06:00", "closes": "12:00" }
  ],
  "areaServed": [
    { "@type": "GeoCircle",
      "geoMidpoint": { "@type": "GeoCoordinates", "latitude": -31.98, "longitude": 115.97 },
      "geoRadius": "60000",
      "description": "Metro delivery, no travel charge" },
    { "@type": "GeoCircle",
      "geoMidpoint": { "@type": "GeoCoordinates", "latitude": -31.98, "longitude": 115.97 },
      "geoRadius": "150000",
      "description": "Peel and Avon delivery, flat travel charge" }
  ],
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Bulk fuel delivery",
    "itemListElement": [
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "On-site diesel delivery, metro" },
        "description": "Delivery margin from 5.5 c/L. Fuel billed at the terminal
                        gate price on the day of delivery." },
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Bulk AdBlue delivery" } },
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Tank monitoring and auto-replenish" },
        "priceSpecification": {
          "@type": "UnitPriceSpecification",
          "price": "28.00", "priceCurrency": "AUD",
          "unitText": "per tank per month",
          "billingIncrement": 1
        } }
    ]
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.8", "reviewCount": "63"
  },
  "review": [
    { "@type": "Review",
      "author": { "@type": "Person", "name": "REAL REVIEWER NAME" },
      "datePublished": "2026-07-14",
      "reviewRating": { "@type": "Rating", "ratingValue": "5", "bestRating": "5" },
      "reviewBody": "REAL REVIEW TEXT PULLED FROM THE LIVE FEED" }
  ]
}
</script>

The two lines that only belong on a real business. aggregateRating and review are the whole reason this panel is a code sample rather than live markup — they must be fed by genuine reviews from a real profile, never authored. On the live demo they are absent entirely, and the harness asserts that every @type in a live JSON-LD block is on the five-value allowlist.

Beyond schema, the real build would carry: a Google Business Profile with the depot verified and the delivery radius set; suburb landing pages that are genuinely different pages rather than one template with the noun swapped (a Kwinana industrial page and a Northam farming page are different sales arguments); a live terminal-gate-price widget, which is the single highest-value organic asset a fuel carrier can own because people search for it weekly; and internal links from the FAQ into the fuel tax credit content, which is the query that brings the accountant in.

09 — FOR A REAL CLIENTWhat changes on day one.

  • Their rate card, not ours. The band table, the minimum, the zone flats and the monitoring fee are five constants at the top of one function. A real carrier’s margins are commercially sensitive and often account-specific, so the public estimator would usually show indicative bands with a “your account rate applies” line, and the logged-in portal would show the real one.
  • A live terminal gate price. Pulled daily from the refiner’s published TGP feed and printed beside the estimate, so the page can show the full landed cost while still being explicit about which half is the market’s and which half is theirs. This is the feature that would sell the build.
  • Their telemetry. Most WA carriers run one of a handful of tank monitoring platforms — the integration is a webhook per tank plus a dashboard embed, and the auto-replenish trigger already exists in their system. The page just needs to stop describing it and start showing the customer’s own tank level.
  • Their operational stack. Bulk fuel runs on fuel-management and dispatch systems rather than trade job software: order capture into their existing dispatch, delivery dockets off the truck’s meter and printer, and invoices into Xero or MYOB with the gate price and margin as separate lines. Where the fleet side matters, telematics from Geotab or MTData, and fuel-card and tank data reconciled through Smartfill. Compliance paperwork — ADG load documentation, driver licences, DGL renewals — belongs in whatever they already use, not a new system.
  • Fuel tax credit reporting. The one genuinely valuable report: litres by tank, by date, by delivery address, split on-road and off-road, exported in the shape a BAS working paper wants. We build the export; the client’s accountant makes the eligibility call. The page says that out loud and so would the product.
  • Their photographs. Every visual here is procedural, which proves the design carries without stock photography — but a real fuel carrier has genuinely good photos: a tanker at dawn on a farm, a bunded tank bank, a driver in hi-vis with a meter ticket. Those replace the illustration in the hero and the drawing stays, because the drawing is the estimator.
  • What we would not change. The honesty clause. If a real client asked us to put a fixed cents-per-litre pump price on the page, we would tell them what we told the fictional one: the moment the market moves, that number makes you a liar to every customer who wrote it down.