Build notes · Industry demo · Wholesale & distribution

How the Daybreak Foods WA demo was made

A conversion-focused landing page for a fictional Perth foodservice wholesaler, built to show distribution businesses what their site could do. One page, one job: open a trade account. Every visual is procedural — no photography, no raster images.

Concept

Daybreak Foods WA is a fictional foodservice wholesaler working out of Canning Vale — the 4am run, the coolroom hush, invoices that match the order. The audience is café and restaurant owners sick of missed deliveries and surprise substitutions, plus caterers and institutional kitchens comparing suppliers. The page's single job is the trade-account form, and everything above it exists to make that form feel like a safe decision: the delivery-run planner answers "do you even come to my street?", the logistics card answers "on what terms?", and the honesty copy answers "will you mess me around?".

Palette — the dock at 4am

#F2F4F6Coolroom white — ground; the chiller's LED-lit panels.
#1F2A3CPre-dawn navy — structure and primary ink; the sky over the depot.
#2F5FA8Crate blue — LINE/MARK only: route lines, zone fills, CTA. Never body text.
#C44536Tomato — the first colour on the dock: focus rings, cut-off countdown, depot marker.

Per the collection's ink/line rule, the bright accents never carry small text. Body ink is the navy itself; secondary copy uses a derived #51607A (5.8:1 on coolroom white); tomato text demotes to a derived #A63325 ink (6.1:1); links use #24487E. On the navy hero, secondary copy is #B8C4D6 (8.2:1).

Type

The signature — Delivery-Run Planner

A procedural SVG Perth metro map divided into five named zones (CBD & inner, coastal north, hills & east, south metro, Mandurah run). Each zone is an SVG <g role="button" tabindex="0" aria-pressed> — tappable, keyboard-operable (Enter/Space), and screen-reader labelled with its delivery mornings. Selecting a zone (or a suburb chip) plots that run in crate blue from the Canning Vale depot: the path's stroke-dasharray/-dashoffset animates over 850ms with a cubic ease-out, stop dots pop in as the line passes, and — after the draw — a tomato "truck" dot loops the route at 46 px/s via getPointAtLength, paused on document.hidden and parked entirely under reduced motion. Routes use butt caps, so no stray round-cap dot appears at zero drawn length (a W15 lesson). The logistics card re-renders in mono: your zone's mornings, the 5pm cut-off, the $150 minimum, free delivery over $300 ($25 metro fee under), the ring-first substitution policy and 14-day terms. At rest the page is mid-demonstration — south metro lit, chilled & produce selected, run plotted, countdown to the next 5:00pm cut-off ticking live.

Choosing a zone or suburb pre-fills the account form's suburb; category chips sync its interest checkboxes — the demo interaction becomes a warmer lead. The pre-fill fires only on user interaction, never at rest, so a fresh page load still validates every empty field. The planner exposes window.__wholesaler (zone, days, categories, form status, route state, interaction count) so QA gates on state, not wall-clock.

One source of truth

All logistics facts live in a single FACTS object; the card renders from it, and the FAQ, "Ordering, honestly" strip and footer repeat the same figures verbatim. The verification harness asserts the displayed card against an independently-typed facts table — never against the page's own object — across zones driven by dispatched MouseEvents and by keyboard.

Zone-day model (documented derivation)

The spec pins two anchors: CBD & inner runs six mornings, and Mandurah runs Tue/Thu/Sat. The rest is derived and held flat: south metro also gets six mornings because it is the depot's home zone (trucks start and end in Canning Vale); coastal north gets four (Mon/Wed/Fri plus a Saturday for weekend café trade); hills & east gets three (Mon/Wed/Fri — longest drive time per drop). There is deliberately no pricing gradient anywhere: a wholesaler's terms don't vary by zone, so the $150 minimum, $300 free-delivery threshold, $25 under-threshold metro fee, 5pm cut-off and 14-day terms are stated once and held identical on every surface. The flatness is the pricing statement.

ZoneRun codeMorningsStatus
CBD & innerRUN C-10Mon–Sat · six morningsspec-pinned
Coastal northRUN N-20Mon · Wed · Fri · Satderived
Hills & eastRUN E-30Mon · Wed · Friderived
South metroRUN S-40Mon–Sat · six morningsderived (home zone)
Mandurah runRUN M-50Tue · Thu · Satspec-pinned

Conversion decisions

Honesty rules applied

Local SEO we'd implement for the real business

For a real wholesaler this schema would ship on the live site (with their real NAP, ABN and review feed), alongside a Google Business Profile for the depot, suburb-level landing content per delivery zone, and review harvesting from account managers' happiest kitchens:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WholesaleStore",
  "name": "Daybreak Foods WA",
  "description": "Foodservice wholesale & distribution across Perth metro.",
  "telephone": "+61-8-XXXX-XXXX",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "[real street address]",
    "addressLocality": "Canning Vale",
    "addressRegion": "WA",
    "postalCode": "6155",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": "...", "longitude": "..." },
  "openingHoursSpecification": [{
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
    "opens": "03:30", "closes": "13:00"
  }],
  "areaServed": ["Perth CBD","Coastal north","Hills & east","South metro","Mandurah"],
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "[from real review feed]",
    "reviewCount": "[from real review feed]"
  }
}
</script>

What would change for the real client

Their photography (the dock at 4am is a real scene worth shooting), their live review feed, and real systems behind the form: Ordermentum or FoodByUs for trade ordering, Cin7 Core or Unleashed for inventory, MYOB Exo or Xero for accounts and 14-day terms, Routific/OptimoRoute feeding real run plans into the zone map, Geotab cold-chain telematics powering a genuine "probe reading on your docket" feature, and Power BI sales dashboards for the account managers. The planner would read live cut-offs and zone schedules from the routing system instead of a static table.

Techniques

Iteration log

Pass 1 — Craft

Headless drive (91 asserts) plus real screenshot review at 1280 and 375. Two ship-blockers found: (1) the resting-state selectZone('south') ran before the form section's DOM refs were assigned, throwing on load and silently killing the form-submit and FAQ wiring — caught because the fresh-load empty-submit probe returned 0 flagged fields; the resting demonstration moved to the end of the script and the empty submit now flags all six required fields. (2) the 375px screenshot showed the header's call pill as an empty oval — the phone-icon SVG collapsed to 0 width (max-width:100% inside a shrink-to-fit inline-flex pill); fixed with flex-shrink:0; max-width:none, then the wider pill overflowed 375 and the mobile header was tightened (subtitle tracking, gaps). Also removed a dead display:none day label in the south zone.

Pass 2 — Depth

Added the second-read detail: after the route draws, a tomato truck dot loops the plotted run at 46 px/s, pausing when the tab hides and staying parked under reduced motion — asserted live at rest (position sampled twice, 800ms apart) and asserted absent in the reduced-motion run. Added the chip press micro-interaction (:active scale). The live cut-off countdown already carried the depth beat on the card, so nothing else was added — one signature, disciplined everywhere else.

Pass 3 — Hardening

Chanel rule: removed the map's north-arrow ornament — a stylised zone map claims no compass accuracy. Full re-verification: all five zones driven by dispatched MouseEvent AND keyboard (Enter and Space), displayed mornings/cut-off/minimums asserted against an independently-typed facts table; filled submit renders the confirmation with the run code attached; every category chip toggled with form-checkbox sync asserted; sticky-bar tap scrolls to the form (the smooth scroll needed a 2.4s settle before asserting); 375px wordmark/nav/CTA verified by bounding box, not just scrollWidth; reduced-motion draws the route instantly with the hero fully visible; zero console errors on every load. Final state: 91/91 asserts, screenshots reviewed at desktop, 375 and reduced-motion.