Generative Assets / Boxline Self Storage / guide ← Back to the site

Boxline Self Storage — how this page was made

A conversion-first landing page for a fictional Bibra Lake self storage facility. The audience is a household mid-move, a renovator clearing rooms, or a caravan owner dodging the ranger — and the page has one job: an enquiry with the unit size and monthly rate already chosen. Everything on it, including the drawn storage unit, is procedural code — no photography, no raster images.

Concept

The aisle at mid-morning

Self storage sells calm: a clean, dry, numbered room that's yours for exactly as long as you need it. The art direction is the aisle itself — swept concrete, galvanised corrugation, and the one colour every facility owns: powdercoated roller-door orange. The signature element, the Unit Fit, answers the only question every storage customer has ("what size do I need?") by drawing the unit and stacking the customer's life inside it — then it hands the answer straight to the enquiry form.

Palette — measured, not assumed

The spec's contrast figures were treated as hypotheses and re-measured with WCAG relative-luminance arithmetic during Pass 1. The headline finding: roller-door orange #C2571F measures 3.88:1 on the concrete ground (the spec guessed ≈4.8:1) — so it carries surfaces and large marks only, never small text. Buttons deepen to #B34E18 (white label at 5.22:1), and orange text uses a minted door-ink #9C430F at 5.63:1.

#EDEFEA swept concretepage ground — the swept aisle floor
#24272B gate-code inkbody text — measured 12.95:1 on ground
#C2571F roller-door orangedoor curtain, large marks — 3.88:1, surfaces only
#B34E18 powdercoat deepbutton surface — white on it 5.22:1
#9C430F door inkorange text & links — 5.63:1 on ground
#8A94A0 galvanised zinclinework, corrugation, callouts — 2.66:1, never text
#5A626C slateminted secondary ink — 5.34:1 ground, 6.06:1 card

The ink/line split holds throughout: zinc draws the unit and the dimension callouts, slate and gate-code ink carry every word.

Type

Saira 600/700 is the display face — an industrial-signage width that sets the dimension readouts ("3 m × 3 m"), prices and unit numbers like stencilled door plates. Manrope 400–800 is the workhorse: legible at 16.5px body on mobile, with enough weight range to carry chips, labels and the trust strip without a third face. The typographic bravery moment is the dimension readout swapping live above the drawn unit as the size chips fire.

The Unit Fit — techniques

The signature is a single <svg> rebuilt entirely by DOM script (createElementNS) on every state change:

Honest pricing — the pinned model

Every figure is anchor arithmetic, verified against an independently reimplemented oracle in the test harness. Monthly, month-to-month, no lock-in. Totals are whole dollars by construction.

UnitRateStudio flat2-bed unit4-bed houseCar & garage
1.5 × 1.5 locker$95/monotenotenotenote
3 × 3$265/mo56% — easy83% — snug, no note162% — note139% — note
3 × 6$395/mo28%42%81% — no note69% — no note
3 × 9$520/mo19%28%54%46%

Conversion decisions

Iteration log

Pass 1 · Craft

Measure everything, trust nothing

Pass 2 · Depth

Second reads and snappier hands

Pass 3 · Hardening

375px, rapid fire, reduced motion

Local SEO we'd implement for the real business

This demo deliberately ships no LocalBusiness, Review or AggregateRating structured data — fictional facts don't belong in a real search index; the live pages carry only WebPage/BreadcrumbList schema naming the demonstration. For a real client, schema.org has the exact subtype — SelfStorage — and we'd ship it with real NAP, geo, hours and a genuine review feed:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "SelfStorage",
  "name": "Boxline Self Storage",
  "url": "https://www.example-boxline.com.au/",
  "telephone": "+61 8 XXXX XXXX",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "(real street address)",
    "addressLocality": "Bibra Lake",
    "addressRegion": "WA",
    "postalCode": "6163",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -32.09, "longitude": 115.82 },
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
      "opens": "08:00", "closes": "17:00" }
  ],
  "priceRange": "$95–$520/month",
  "areaServed": ["Bibra Lake","Cockburn Central","Success","Yangebup","Spearwood","Fremantle"],
  "makesOffer": [
    { "@type": "Offer", "name": "3 x 3 storage unit",
      "priceSpecification": { "@type": "UnitPriceSpecification",
        "price": 265, "priceCurrency": "AUD", "unitText": "per month" } }
  ],
  "aggregateRating": { "@type": "AggregateRating",
    "ratingValue": "4.9", "reviewCount": "180 (from the live reviews feed)" }
}
</script>

The top-level type is the point: SelfStorage is a real schema.org LocalBusiness subtype — no need to settle for the generic parent. Ratings would be wired to the client's actual Google reviews, never typed in.

What would change for the real client

← Back to Boxline Self Storage · Generative Assets index