Boronia & Bay

Design & engineering guide · Industry demonstration

How Boronia & Bay was built

The concept

Boronia & Bay is a fictional Subiaco flower studio, named for brown boronia — the WA winter flower whose scent sells out every July. The audience is someone who needs flowers somewhere today: birthday, sympathy, anniversary, apology. The page has one job — an order enquiry, with the 1 pm same-day cutoff doing the urgency work honestly — and one signature, the Bouquet Bench, a procedural SVG bouquet that composes itself stem by stem while the ticket beside it stays as disciplined as an invoice.

Palette — botanical warmth against studio cream

Studio cream#FAF5EC — the ground; kraft paper's paler cousin.
Stem-brown ink#37322A — all body text, 11.6:1 on cream.
Bay-leaf green#4C6B4F — foliage fills, links, ticks.
Boronia blush#D98A80 — petals and CTAs; marks and blooms, never small text.
Boronia maroon#8C4A52 — the flower's deep bell; eyebrows and accents.
Kraft#C4A171 — the wrap tone, inside the illustration and the occasion word.

The ink/line split rule applies throughout: blush and kraft carry marks and blooms; text sits in stem-brown (or green-ink for links) at ≥4.5:1. The blush CTA carries stem-brown ink text at ≈4.8:1 rather than white at ≈2.8:1.

Type

Gloock (display) has the high-contrast, hand-lettered elegance of a flower-shop window — it carries the wordmark, headings, the ticket total, and the typographic bravery moment: the occasion word set huge in the bench, crossfading as you change occasion. Karla does the working text; the order ticket uses its tabular figures so every price lines up like an invoice.

The signature — the Bouquet Bench

The bouquet is pure procedural SVG, deterministic per selection. A seed hashed from size + palette + occasion feeds a mulberry32 PRNG, so the same choices always compose the same bouquet, and changing the occasion genuinely changes the stems — never the price, which the ticket states outright.

The honest pricing model

Every figure is pinned anchor arithmetic, cross-checked in the verification harness against an independently reimplemented oracle across all 24 size × add-on combinations.

ItemRuleWorked example (measured)
Posy$65Posy + chocolates = $83 + $15 = $98
Classic$95Rest state: $95 + $15 delivery = $110
Abundant$140$140 ≥ $120 → delivery free → $140
Glass vase+$25Classic + vase = exactly $120 → delivery flips FREE → $120 total
Chocolates+$18Classic + chocolates = $113 → still $15 delivery → $128 (below threshold)
Handwritten cardfreeChanges the ticket and the card copy, never the total
Delivery$15 same-day metro, order by 1 pm; free at $120+ subtotal (add-ons count)Threshold asserted at precisely $120, and at $113 just below

Conversion decisions

Local SEO we'd implement for the real business

This demonstration page deliberately ships only WebPage schema naming it a demonstration — fictional structured data in a real index would be dishonest markup. For a real florist we would ship:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Florist",
  "name": "Boronia & Bay",
  "telephone": "+61-8-XXXX-XXXX",
  "priceRange": "$65–$140",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "…",
    "addressLocality": "Subiaco",
    "addressRegion": "WA",
    "postalCode": "6008",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.95, "longitude": 115.82 },
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
      "opens": "08:00", "closes": "17:00" },
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday", "opens": "08:00", "closes": "14:00" }
  ],
  "areaServed": { "@type": "City", "name": "Perth" },
  "aggregateRating": { "@type": "AggregateRating",
    "ratingValue": "4.9", "reviewCount": "180" },
  "review": [{
    "@type": "Review",
    "author": { "@type": "Person", "name": "…" },
    "reviewRating": { "@type": "Rating", "ratingValue": "5" },
    "reviewBody": "…"
  }]
}
</script>

— fed by the real Google Business Profile and a live reviews feed, never hand-written.

What would change for the real client

Their bouquet photography (or this procedural art kept as a brand system), their reviews feed, and real commerce: a florist POS/e-commerce platform such as Floranext, Lovingly or Shopify + Square for orders and payment; relay membership (Interflora/Petals) if they take network orders; delivery-run routing via Locate2u or Zoom2u with SMS "it's at the door" notifications; an address/suburb autocomplete on the form; and a live cutoff clock wired to the studio's actual run schedule — the demo keeps the 1 pm rule static rather than faking a countdown.

Iteration log

Pass 1 — Craft

The first bouquet read as sparse sticks: fan-angle stem placement scattered small blooms with big gaps, and a long narrow kraft cone dominated the frame. Rebuilt the composition — golden-angle phyllotaxis dome sampling, back-to-front y-sorting, a wider/shorter wrap, bloom scale up ~1.7–2.2×, larger gum/sprig foliage, and a greenery collar ring. Fixed a truncated services line ("delivery in" → "delivery included"). Harness after the pass: 89/90 (the one failure was this guide not existing yet).

Pass 2 — Depth

Added the second-read details: a kraft care tag ("cut 6 am") swinging off the twine on its own CSS-animated nested group; a petal-drift micro-interaction — tapping the bouquet releases five palette-matched petals that fall, sway and clean themselves up (reduced-motion-guarded); the occasion word now crossfades instead of hard-swapping; and the delivery line strikes through the $15 when the $120 threshold flips it to FREE. New asserts: tag present, petals spawn and self-remove — 92/93.

Pass 3 — Hardening

375 px sweep: masthead measured wordmark-right vs phone-left (no collision), sticky-bar targets ≥56 px, scrollWidth 375 on both pages, h1 + CTA + trust chip inside the first viewport. Reduced-motion path renders the fully-composed settled frame with all animation killed. Rapid-fire nine-click drive confirmed the compose token holds under abuse. Chanel rule: removed the twine knot-cross ornament (two twine bands and the tag carry it) and gave the ticket aria-live="polite". Final sweep with this guide included: 100/100 asserts, zero console errors, every displayed figure matching the independent oracle.

Techniques