Ironstone Bend — the site

Generative Assets · Industry Demos XXVI · site 342

Ironstone Bend Wines — how it was made

The concept: a fictional family winery and cellar door on a bend of the Swan River in Herne Hill — five-wine flights at the bar, seated tastings with a board, a three-course long lunch, winemaker walk-throughs and a return coach from Perth. The audience is the couple planning a Sunday drive, the friend organising a fortieth for twelve, the office booking an end-of-quarter lunch, and the wine-club regular bringing visitors. The page has one job — a cellar-door booking request with the experience, head-count and add-ons already priced. It is the wave's dark site: the cellar door at 6pm, the last hour of light on the long table under the vines.

Palette — argued from the cellar at dusk

A shiraz-stained cellar for the ground, a parchment label for the ink, the gold foil on that label for the CTA, and the vine for the linework. It stays clear of the banned defaults: the accent is old gold on plum, not acid on black; there is no cream page with a terracotta serif; and the rules are vine-coloured, not broadsheet hairlines.

#1F1418 cellar plumPage ground. Dark site.
#F1E7DA parchmentBody ink — measured 14.67:1 on plum.
#C9A24E old goldCTA fill with plum labels (7.48:1), marks, ribbon, star. Gold copy on plum 7.48:1.
#E2C27A gold inkPre-minted lighter variant — links, eyebrows and accent copy on lifted panels (9.38:1) and the italic display words.
#6E8B5E vine leafTrellis wires, leaves, ledger rules. Lines and marks ONLY — 4.71:1, never small type.
#A6BF97 leaf inkPre-minted leaf-coloured copy: the flight declaration on badge and ledger — 8.98:1 on plum, 8.07:1 on panel.
#CFC1B6 soft parchmentDerived secondary ink — 10.21:1 on plum, 9.17:1 on panel.

Measured contrast (WCAG arithmetic on the shipped hex, Pass 1)

14.67:1parchment #F1E7DA on plum #1F1418 — spec hypothesis ≈14, passes
7.48:1old gold #C9A24E on plum — spec ≈8.5, measured 7.48; still well over 4.5, no remedy needed. Same figure for plum labels on gold buttons (spec ≈7.5)
6.72:1old gold on the #2B1D24 card panel · 6.06:1 on the #352430 total panel — passes, but accent copy on panels uses the pre-minted #E2C27A anyway
10.44:1gold ink #E2C27A on plum (spec ≈11) · 9.38:1 on panel · 8.46:1 on the total panel
8.98:1leaf ink #A6BF97 on plum (spec ≈9) · 8.07:1 on panel
4.71:1vine leaf #6E8B5E on plum — lines and marks only; no leaf-coloured small type anywhere
9.00:1error ink #F3B39C on the form panel

Type

Cormorant Garamond (600 for the h1, 700 for the display line, badge and cards, 600 italic for the promise) is the serif on a good label — high contrast, long ascenders, a little grand without being stiff. Lato carries everything a guest has to actually read — chips, ledger, form, FAQ — at 17px on mobile, with 900 weight reserved for the scene tags. The typographic moment is the head-count set huge in Cormorant caps, "EIGHT GUESTS at the long table", the number word swapping live with the stepper and the italic tail changing to "at the bar" on the flight and "across two long tables" from thirteen.

Techniques

Honest numbers — the pricing contract

Every figure is pinned in the wave spec from Swan Valley cellar-door pricing, GST-inclusive, and every booking is a request confirmed by phone or email (stated on-card). All totals are whole dollars by construction.

LineRateRule
Cellar-door flight$15 ppFive wines at the bar, 30 min. Bookings from 2. Declaration on badge + ledger: "the flight fee comes off any two bottles you take home" — a statement, never a subtraction.
Seated tasting with a board$38 ppSix wines, cheese & charcuterie board, 75 min. From 2.
Long lunch$95 ppMinimum 4 covers billed on the LUNCH LINE only (2–3 guests → note "billed at four covers — the kitchen sets the table for four", priced 4 × 95; at 4 no note). ≥16 guests → NOTE only "sixteen and up is a private function…" — no price change, no disable.
Guests2–40, ×1Second table drawn from 13, guests split evenly.
Winemaker walk-through+$12 pp × actual guestsLIVE on seated and lunch; DISABLED on the flight with the reason "the walk-through pairs with a seated booking — pick seated or lunch". Restore semantics: flight locks it OFF; back to seated/lunch RESTORES the prior choice.
Return coach from Perth CBD / Fremantle+$45 pp × actual guestsLIVE (default OFF) at ≥8 on every experience; OFF and DISABLED below 8 with "the coach runs for eight and up — under that a rideshare is the cheaper trip". Stepping back up to ≥8 RESTORES the prior choice.
Celebration set-up+$40 flatLive at every combination. Cake, ribbon and reserved sign drawn.
Private functions, weddings, corporateno number"Quoted on the brief — tell us the date and the head-count" — grid, ledger foot and FAQ. Bottles appear in copy only as the range $22–$48.

Worked examples (all measured from the page and against a separately coded oracle)

Conversion decisions

Local SEO we'd implement for the real business

For a real cellar door we'd ship Winery — the exact schema.org organization subtype under FoodEstablishment, which Google reads as a local business with opening hours and menu — rather than Restaurant (a winery's primary product is wine, not the kitchen; Winery keeps that signal while still carrying servesCuisine and hasMenu for the lunch). Aggregate rating and reviews would be fed from the live Google Business Profile, never typed in. This panel is the sample; it is not live on this demonstration.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Winery",
  "name": "Ironstone Bend Wines",
  "url": "https://www.example-cellar-door.com.au/",
  "telephone": "+61 8 9000 0342",
  "image": "https://www.example-cellar-door.com.au/og/cellar-door.jpg",
  "priceRange": "$15 – $95 per person",
  "servesCuisine": "Modern Australian",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "(real street address)",
    "addressLocality": "Herne Hill",
    "addressRegion": "WA",
    "postalCode": "6056",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.83, "longitude": 116.0 },
  "areaServed": ["Swan Valley", "Perth", "Fremantle"],
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification", "dayOfWeek": ["Thursday","Friday","Saturday","Sunday","Monday"], "opens": "10:00", "closes": "17:00" }
  ],
  "hasMenu": "https://www.example-cellar-door.com.au/long-lunch",
  "makesOffer": [
    { "@type": "Offer", "name": "Cellar-door flight", "price": "15", "priceCurrency": "AUD" },
    { "@type": "Offer", "name": "Seated tasting with a board", "price": "38", "priceCurrency": "AUD" },
    { "@type": "Offer", "name": "Long lunch, three courses", "price": "95", "priceCurrency": "AUD" }
  ],
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.9", "reviewCount": "184" },
  "review": [
    {
      "@type": "Review",
      "author": { "@type": "Person", "name": "(from the live reviews feed)" },
      "reviewRating": { "@type": "Rating", "ratingValue": "5" },
      "reviewBody": "(from the live reviews feed)"
    }
  ],
  "sameAs": ["https://www.facebook.com/…", "https://www.instagram.com/…"]
}
</script>

Alongside the schema: a Google Business Profile with the tasting and lunch as bookable services, "Swan Valley cellar door", "long lunch Swan Valley" and "winery Herne Hill" as the title/H1 targets, an Event schema for the release weekends, and a suburb-level page set for the coach pick-ups (Perth CBD, Fremantle) rather than one thin "areas we serve" page.

What would change for the real client

Iteration log

Pass 1 — Craft

Measured every contrast pair with WCAG arithmetic on the shipped hex (figures above): gold on plum 7.48 against a ≈8.5 hypothesis and plum-on-gold 7.48 against ≈7.5 — both comfortably over 4.5, so no two-token remedy was needed for gold; the pre-minted #E2C27A still carries links, eyebrows and accent copy on lifted panels, and the pre-minted #A6BF97 carries the flight declaration. Two real defects surfaced in the first driven pass: the seeded leaf paths produced a doubled minus (--7) on flipped leaves, throwing SVG path errors on load — rebuilt the path string from explicit numbers; and the tables group had no fade class, so the bar-flight chip faded the bar in without fading the tables out (the state asserts were green while the scene overdrew). Screenshot review at 2×: front-row chairs were drawn at the table's front edge and read as pinned under it; the table slab was too shallow for two rows of glasses plus boards; the winemaker's label was struck through by the table's end. Deepened the slab to 30, shortened the table to clear the barrel-hall door, moved the front chairs below the front face, drew boards before glasses so the front glasses sit on them, moved the barrel in front of the door and the WINEMAKER label into the arch, and re-spaced the second table so the head-count tag clears the front chairs at 40. Copy read over the FAQ, the ledger foot (it now names the walk-through, coach and celebration in a sentence) and the trust strip.

Pass 2 — Depth

Enriched the signature: grape bunches on five of the forty leaves, the barrel-hall glow pulsing 0.7–1.0 behind the winemaker, the lit candle's flicker and glow disc on the lunch, a bow on the celebration ribbon at the head of the table and a reserved sign at the far end, and the second table's guests split evenly so "across two long tables" reads true. Second-read details: the chalkboard title "TONIGHT ON THE BEND" and its chalk rules; the display line's italic tail changing per experience; the stepper readout's small scale bump; the ledger foot's closing sentence swapping between the fifteen-minute hold and "walk in any day we're open" on the flight. Micro-interaction: the badge menu lines animate in and out with the toggles because they are the same DOM the ledger reads, so the board, the ledger and the pre-filled message never disagree — asserted as the three-surface declaration check on the flight. Refined the pop-in ease (cubic-bezier(.2,.9,.25,1.15)) and moved the celebration ribbon in bar mode onto the counter's front face, shortened to the counter's length, and the bar-mode cake beside the bottle so it never crowds the fifth glass.

Pass 3 — Hardening

375 masthead checked first: wordmark right edge (178) < phone-icon left (188) < CTA left (238), CTA right 340, one row, no wrap; scrollWidth 375, zero offenders outside SVGs; sticky Call / Book bar present; h1, gold CTA and the trust line all inside the first 740px. Badge tight variant at 375 measured 44 × 26 px price on an 80px board — sub-line dropped to 2.15cqw and allowed to wrap after the native-res review showed it a few pixels wider than the board. Label-collision sweep at native resolution across rest, flight-4, lunch-16 (walk-through + coach + celebration), seated-40, lunch-3 and flight-12: badge clear of the board title and rule, WINEMAKER inside the arch, COACH · PERTH RETURN under the coach and clear of the head-count tag, tag clear of the second table's front chairs at 40, cake clear of the first glass at 8 (touching at 40, by design). Reduced-motion path: no rAF loop, chairs and glasses placed at once, leaves and flame static, route static. Focus rings on every chip, toggle, stepper, field and link; keyboard arrows move the experience chips. rAF dt clamped at zero and capped. Rapid-fire drives (ten clicks in one evaluate, twice) settled clean with the token invalidation. Chanel rule: removed a second decorative chalk rule under the price and the lawn-grass strokes near the gate. Guide tables in .table-scroll, guide 375 clean, one h1 on both pages, colophon on both pages, JSON-LD allowlist on index, no console errors, no backdrop-filter. Final copy read over the confirmation panel, the coach FAQ and the private-function line.