Case study / 05

One apartment in Lviv whose whole argument is the window — so the site is built to prove the view is real, and to let a guest ask for it in under a minute.

RoleResearch, product, brand redraw, design, build, deploy — solo
TimeframeBuilt and deployed · waiting on the domain move
  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind 4
  • next-intl
  • Zod
  • sharp
  • Vercel

The problem

The view was the product, and nobody could see it.

The apartment's entire web presence was one Google Sites page carrying seventy-nine words of original text, published unchanged to two different domains. Both were indexable, neither pointed at the other, and the photographs were capped at 1280 pixels on someone else's CDN.

One owner lets one apartment. No front desk, no agency, no channel manager and no budget for one. Whatever replaced that page had to be editable by him, cheap to run, and honest about what it does not yet know.

The system

A prospect plate and its numbered key.

Lviv has been drawn for centuries as a horizontal band of silhouette with a key underneath naming each tower. The product's argument is a view, so the site takes that form instead of the rental-portal arrangement of search widget, three cards and a map at the bottom.

01

The Panorama Key

  • The real photograph from the windows pans sideways as you scroll, on a track that widens on small screens so a phone still reveals new city.
  • Seven landmarks pinned at their true compass bearing computed from coordinates: High Castle 79.8°, Rynok Square 102.6°, the university 124.0° — all inside an arc of 76° to 129°.
  • St George's Cathedral sits in the content file at 178.8° and is deliberately absent from the key, because it cannot be seen from those windows.
02

Booking without a backend

  • A real form with a server action: it submits before hydration and with JavaScript switched off.
  • Spam defence without a CAPTCHA — a honeypot, a three-second minimum on the form, five requests a minute per address. A trapped submission gets the same success screen a real one does.
  • Email is optional. Unconfigured, the request is logged in full and the guest is handed Viber or Telegram with the message already written.
03

Photographs and restraint

  • Twenty-eight photographs become 306 derivatives in AVIF and WebP at five widths, with real dimensions recorded so nothing shifts on load.
  • One frame is excluded by filename because identifiable children are in it — the exclusion is code in the build script, not a note in a document.
  • No runtime image optimiser: every derivative already exists on disk, so one would add latency and billing for nothing.

Production workflows

Three decisions that shaped the build.

Open a flow to see the reasoning. Each is a place where the obvious option was rejected for a stated reason.

01Coordinates → a key you can checkThe panorama asserts something verifiable rather than something decorative.
  1. Geocode ten landmarks and compute the true bearing and distance from the window.
  2. Keep only what falls inside the visible arc, and record the rest with the reason it is excluded.
  3. Calibrate walking time at 72 metres a minute against two routed figures published for this address, and always show it as approximate.
02Motion → three honest fallbacksRemoving the motion never removes the meaning.
  1. With no JavaScript the section composes one static frame with every label in place.
  2. Under reduced motion the panorama stops and sits fitted, labels unchanged.
  3. On a narrow screen the track widens so the pan still reveals city rather than crawling.
03A request → a reply the owner will seeNothing is silently dropped while the owner decides how he wants to be contacted.
  1. One schema validates on the client for feedback and on the server as the only gate that counts.
  2. With no email account configured the request is written where it can be retrieved, and the guest still sees success.
  3. Viber and Telegram links carry the dates and message already typed, because that is how these bookings actually close.

Interactive preview

The key, driven by hand.

This is the production hero with one change. On the site the city pans as you scroll; inside a page that is itself scrolling that would fight the reader, so here you drive it. The photograph, the plate treatment, the arc and every bearing are the real ones.

P1

The Panorama Key

Pan the view and watch the centre bearing move. Jump to St George's to see why it is not in the key.

Real photograph and real bearings · a slider replaces the scrollThe bearings come from the production content file. The proof that the key is computed rather than drawn is the landmark it leaves out.

What was built

Small surface, deliberate everywhere.

These describe the build, not the business. The site has not launched, so it has produced no results yet and none are claimed here.

statically prerendered pages
14
Seven routes in two languages
landmarks on the key / geocoded
7 / 10
Arc 76° to 129°
image derivatives
306
From 28 photographs, one excluded by rule
server action in the project
1
Everything else is static
third-party requests on most pages
0
Ten of fourteen; a lazy map on two

What this proves

A small brief is not a small problem.

01

A site can be shaped by its argument

The form follows what the product actually sells, instead of the default arrangement every rental portal uses.

02

Working software before configuration

The booking form is useful before an email account exists, and says so rather than failing quietly.

03

Content a non-technical owner can hold

Everything he is likely to edit is plain typed files with both languages side by side — no CMS and no admin login to learn.