Generative Assets · Industry demo guide · Site 254

How Kilnlit Sign Co. was made

A fictional Malaga signage fabricator — shopfront signs, lightboxes and vehicle graphics — built as a single conversion-focused landing page. The page's one job: get a shop owner to type their own name, see it lit, and send the quote form.

Concept

Kilnlit Sign Co. is the dark site of Wave 19: the workshop doorway at dusk, a finished lightbox glowing on the bench for its first switch-on. Signage is the one trade whose product is typography, so the signature element hands the visitor the fabricator's own moment — type your business name, watch it appear lit on a procedural SVG shopfront. The audience is café owners three weeks from opening, tradies whose ute is their only ad, and strip landlords due a facelift; every scene, price and FAQ answer is pointed at getting them into the quote form with a warm, specific enquiry.

Palette — first-light-up dusk

#221F2BWorkshop dusk — the violet hour through the roller door. Page ground.
#F2EFE9Lightbox white — the lit acrylic face. Body ink on dusk (14.1:1).
#FF6B5ANeon coral — the warm tube. LINE/MARK only: glow, rules, CTA, prices. Never long body text.
#4FC1D8Tube cyan — the cold OPEN sign in the window. Links, focus, eyebrows.
#BCB5C7Derived body-ink for secondary copy (7.9:1 on dusk) — the coral is a mark, not a text colour.

A warm plum-violet dusk, deliberately different from the collection's other dark trades (locksmith's navy night, earthmoving's iron dusk, concreter's wet-slab charcoal). The coral carries every conversion mark — sign glow, section rules, the CTA — and it measures 5.8:1 on the dusk ground, so short marks like prices stay legible; long copy still goes to the white and lavender inks per the ink/line token split.

Type

Big Shoulders

Display. Condensed American-signpainter capitals — this trade is typography, so the bravery budget went here: the masthead, the h1, and the sign faces in the studio itself all set in it. The typed name renders in the same face a fabricator would proof it in.

Work Sans

Body and UI. A plain-spoken workhorse that keeps quotes, FAQs and trust copy legible at 16px+ on a phone — professional beats expressive on a conversion page.

Chivo Mono

Dimensions, lm rates and prices. Every number on the page — $850/lm, 4.0 m, $3,400 — is set in mono so figures read as workshop measurements, not marketing.

The Shopfront Studio

The signature is one procedural SVG shopfront at dusk (960×560): gradient sky, neighbouring rooflines, fascia band, shop window, door with a flickering cyan OPEN tube, kerb and road. A text input (maxlength 24) drives the sign — the value is sanitised (control characters stripped, sliced to 24) and written with textContent onto SVG <text> nodes only, never innerHTML, so a typed <script> renders as inert glyphs on the fascia. Four sign-type chips swap nested <g> groups via the hidden attribute (with the [hidden]{display:none !important} guard): the lightbox draws a lit acrylic face with a blurred coral glow rect; the acrylic letters render as a white text layer over a blurred coral halo copy; window vinyl arcs the name across the glass on a textPath whose arc chord is recomputed per width; the A-frame stands a trapezoid board on the kerb. A 2–8 m slider scales the lightbox geometry and the estimate; a lit/unlit toggle switches scene classes. Text is fitted with getComputedTextLength() (re-run on document.fonts.ready), so 24-character names compress honestly instead of overflowing the box.

Motion discipline: the glow flickers on once at load (1.15s, like a warming tube), then pulses on a CSS keyframe whose floor is opacity 0.72 — the never-invisible floor from LEARNINGS W18, so the signature is alive at any thumbnail capture instant. Position and animation live on separate nested elements (SVG presentation attributes never share an element with CSS animation, per LEARNINGS W16/W17). A moth orbits the glow — but only when the sign is lit and glowing; reduced motion kills the flicker, pulse and moth and renders the settled, fully-lit scene. No canvas, no rAF loop: the whole page is SVG + CSS, cheap on a 4G phone.

State is exposed on window.__signage (name, type, width, lit, price, formStatus) and the studio pre-fills the quote form — typed name into the business-name field, chip into the sign-type select (both with dirty-guards so a visitor's own edits are never clobbered), and a live "From the studio" line carrying name + type + width + estimate into the enquiry.

The pricing model, honestly

Sign typeModelWorked example
LED lightbox fasciarun × $850/lm, slider floored at the 2 m minimum4 m = $3,400 (rest state); 2 m floor = $1,700, matching the services grid
3D acrylic lettersflat from $2,600 — deliberately flat: letter count and height set the real price, quoted from artwork. The width slider scales the preview and the card says so on-pageany width shows from $2,600
Window vinyl$190/m² × (run × 0.6 m lettering band), floored at the $380 minimum supply-and-install visit4 m run ≈ 2.4 m² = $456; 2 m run computes $228 → floors to $380, with the floor stated on-card
A-frameflat $290; the width slider disables with the on-page reason "A-frames are a standard size — $290, pavement-ready"$290 — the studio's cheapest possible output, equal to the services grid floor

Derivations the spec left to the builder: the vinyl area model uses a 600 mm lettering band (the same 600 mm the lightbox is deep — one workshop dimension) times the run, and the $380 minimum visit exists so no studio output ever undercuts the $290 A-frame floor dishonestly. The acrylic flatness is shipped as a documented pricing statement, not an invented gradient — a control that can't honestly move a figure explains itself instead (LEARNINGS W15/W18). Every displayed figure was verified against an independently reimplemented oracle in the QA harness across eight driven scenarios, and the cheapest output across the whole model measures $290 — the grid's A-frame anchor.

Conversion decisions

Local SEO we'd implement for the real business

This demo page carries only WebPage schema naming it a demonstration — fictional structured data in a real index is dishonest markup. For a real signage client we would ship LocalBusiness + Review schema like this, wired to their real NAP, ABN, hours and review feed:

{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Their Sign Co.",
  "description": "Shopfront signs, LED lightboxes, acrylic letters and vehicle graphics. Fabricated in Malaga, installed across Perth.",
  "url": "https://www.theirsignco.com.au",
  "telephone": "+61 8 XXXX XXXX",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "Unit X / XX Example Road",
    "addressLocality": "Malaga",
    "addressRegion": "WA",
    "postalCode": "6090",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.85, "longitude": 115.89 },
  "openingHoursSpecification": [{
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
    "opens": "07:30", "closes": "16:30"
  }],
  "areaServed": ["Malaga","Wangara","Balcatta","Morley","Osborne Park","Perth"],
  "priceRange": "$$",
  "review": {
    "@type": "Review",
    "author": { "@type": "Person", "name": "Real Customer" },
    "reviewRating": { "@type": "Rating", "ratingValue": "5" },
    "reviewBody": "Pulled from their real Google reviews feed — never invented."
  },
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.9", "reviewCount": "87" }
}

Plus: Google Business Profile with the workshop's service-area settings, per-suburb landing sections only where there's real work to show, and review acquisition through the Podium flow below.

What would change for the real client

Iteration log

Pass 1 — Craft

  • Drove the full harness (headless Chrome, port 6504): 49 asserts — rest state ($3,400 card vs probe vs oracle), eight priced scenarios against an independently reimplemented oracle, chips/slider/toggle, fresh-load empty submit (4/4 fields flagged), filled submit (lexicon confirmation), FAQ, sticky bar. All green — then the screenshots found what asserts can't.
  • Looked at the 375px masthead first (LEARNINGS W18): the header "Get a quote" button wrapped to two lines. Fixed with white-space:nowrap; flex:none on .btn.
  • Phantom accent over "VEHICLE" in the h1 — the comma of "SIGNS," on the line above descended into line 2 at line-height .96 and read as an acute accent. Diagnosed by isolating the font in a test page (clean) then hiding the h1 (mark vanished). Fixed: line-height 1.02.
  • The 1200×750 7s-settle screenshot showed only hero text — the lit sign was below the fold. Compacted the hero (h1 84→64px, tighter rhythm) so the glowing lightbox is in frame at the capture instant.

Pass 2 — Depth

  • Price-tick micro-interaction: the estimate figure scales and flares briefly whenever the number actually changes (guarded so re-renders without a price change stay still; disabled under reduced motion).
  • Warmed the window's interior glow for the vinyl and A-frame scenes (the shop light is what makes unlit signage readable at dusk).
  • Second-read details: a moth orbits the glow — only when the sign is lit; the cyan OPEN tube hums on its own slower cycle; the caption strip reads DUSK · 17:12.
  • XSS-probed the name input with a <script> payload set programmatically (bypassing maxlength): it renders as inert uppercase text on the fascia, sliced to 24 characters, zero script nodes injected.

Pass 3 — Hardening

  • 375px fold review: the trust chips sat behind the sticky call bar. Hid the secondary hero CTA at mobile (the studio is one scroll below), so name + value prop + primary CTA + trust chips are all clear of the bar at 375×667. Eyebrow dropped to 11px so it holds one line.
  • Reduced-motion verified by emulation: every animation reports none, the glow settles at opacity 1, the moth is display:none, hero copy fully visible.
  • Re-ran the full suite after all edits: 49/49 green, zero console errors, scrollWidth 375 at mobile, exactly one h1 per page, reserved (08) 9000 0254 the only business number, WebPage-only JSON-LD on the index.
  • Chanel rule: cut a planned streetlamp from the scene — the lightbox is the only light source that matters, and the kerb reflection already carries it.