Go to homepage 2sh

Laas

Reference rebuild of a five-star heritage boutique hotel with a decoupled direct-booking drawer: five-step reservation flow, printable folio, and a 2.99 KB client-JS budget enforced in CI against the widget-laden hotel-site norm.

view the live build
Laas hero: Hanseatic merchant-house street with fact grid and direct-reservations bar
client
Reference Architecture
service
Direct-Booking Reference Rebuild
sector
Hospitality / Heritage Boutique Hotels / Edge Architecture
year
2026

the brief

Laas is a reference rebuild of a five-star Hanseatic boutique hotel in Tallinn Old Town — the kind of property where the booking stack is a black box: a third-party widget that costs the hotel 15–25% of every direct stay, a separate PMS feed, and a page that takes 8+ seconds to become interactive on the guest's phone. The rebuild proves the alternative: a direct-booking site where the reservation flow is a small island of JavaScript on an otherwise fully static, edge-served page.

built with

Astro · Cloudflare Workers · Tailwind CSS · TypeScript

what changed

A 2.99 KB booking engine against a category norm of half a megabyte or more

Hotel booking pages often load a bundle for each widget: calendar, room matrix, upsell, and live availability. A typical page loads 500 KB to 1 MB of client JavaScript before a guest can pick a date. Laas compiles the five-step reservation flow, validation, pricing, add-ons, and folio into a 2.99 KB gzipped island. The calendar data and print stylesheet are CSS.

A CI budget check fails the build if total client JavaScript exceeds 5 KB gzipped. This keeps the 2.99 KB measurement tied to production. The room catalog, gallery, and dining room render as HTML before JavaScript runs.

five steps from dates to folio

Laas shows the direct-booking discount, priced add-ons, Estonian VAT, and total due at check-in. Guests can download an .ics calendar event and print the folio. The five steps are separated by hairline rules.

The gallery's second JavaScript island opens a keyboard-navigable lightbox. The rest of the page is static HTML and CSS served from the edge.

inside the build

hotel booking pages load third-party widgets

Laas is a reference rebuild of a heritage boutique hotel site. It lets guests book directly at the listed rate. The flow uses a channel-manager widget, review badge, live-availability iframe, and upsell banner, each adding scripts and a third-party service.

On a mid-range phone over cellular, these pages can take 8+ seconds before the booking flow responds. Iframes can repeat the hotel name or change the price between steps.

direct booking as an edge-native product

Laas serves the hotel story, room catalog, gallery, dining room, and contact paths as static HTML at the edge. The reservation drawer is a five-step flow that reads room data, applies the direct-booking discount, prices add-ons, and issues a folio.

After confirmation, guests can download a calendar event and print the folio from the same page.

the payload budget as a CI gate

The page’s selling point is quantitative, so it is enforced quantitatively. The build pipeline runs a budget check that gzips the total client payload and fails the build above 5 KB. At the moment of delivery the site sits at 2.99 KB gzipped — the booking island plus the gallery lightbox, nothing else.

Two self-hosted variable fonts (~117 KB) are the only other assets, and they are the price of the design: a display serif with true italics over a workhorse sans, served from the same edge as the HTML. There is no analytics suite, no A/B framework, no chat widget — the colophon states the payload story in plain numbers and the CI gate keeps it true.

a design system that documents itself

The visual world — deep pine section fields, a single moss accent, stamped mono data labels, square corners, 1px hairlines, real dark mode — is specified in a DESIGN.md at the repository root with machine-readable tokens and a sidecar for what the token schema cannot hold. Any screen added to the property stays on-brand by reading the spec, and the detector ignores are committed with reasons, so “why is this color allowed” has a durable answer in the repo.

the numbers

Metric Widget-laden hotel site Laas direct-booking rebuild
Client JavaScript (initial) 500–1000 KB 2.99 KB gz
Client-JS budget none 5 KB gz, CI-enforced
Hydration full-page framework zero (2 islands)
Booking transaction fee 15–25% of direct stay none
Time to interactive (mobile) 8s+ sub-second (static HTML)
Confirmation session iframe folio + .ics + print

in the details

04 views
Laas gallery film strip: property photographs in a hairline grid with plate captions
Laas gallery film strip: property photographs in a hairline grid with plate captions
Laas room catalog: four signature suites with rates, tags, and direct-booking calls
Laas room catalog: four signature suites with rates, tags, and direct-booking calls
Laas booking drawer: confirmed reservation folio with direct-booking discount and VAT line
Laas booking drawer: confirmed reservation folio with direct-booking discount and VAT line
Laas dark mode: deep pine hero field with moss accent and stamped mono data labels
Laas dark mode: deep pine hero field with moss accent and stamped mono data labels

the result

The payload story is the product story. The entire booking experience — dates, room selection, add-ons, folio with VAT line, .ics calendar download, and a print stylesheet that turns the confirmation into a document — ships in 2.99 KB gzipped of client JavaScript, behind a 5 KB ceiling that fails CI if any future change breaches it. Everything else on the page ships as zero-hydration HTML.

For the hotel, the commercial model follows the architecture: no per-booking transaction fee on direct reservations, no widget license, no PMS middleware. The site is a sales artifact that demonstrates the model end to end — a hotelier can be walked through a real stay, five steps, folio and all, on the page that sells the approach.

credits

Two Shells

Design & Engineering

building something similar?

talk to 2sh