Initializing Experience

A marketing and booking-info website for a luxury transit hotel near Bandaranaike International Airport (Katunayake, Sri Lanka), built for travelers booking day-use rooms and short layover stays.
Ceylanro Villa
2026
Ceylanro Villa is a transit hotel positioned around a specific niche: travelers with layovers at CMB airport who need day-use rooms, express check-in, and airport shuttles rather than a standard overnight stay. The business needed a web presence that could communicate this positioning, showcase rooms and pricing (including a separate day-use rate), and be discoverable in search for airport-hotel and layover-hotel queries.
Build a production-ready marketing site covering the full guest journey — homepage, room listings with detail pages, services, about, and contact — with strong SEO/structured data for local and travel search, a distinct visual identity (custom typography, video hero), and a containerized deployment pipeline the client's infra could run without a Vercel dependency.
Built on Next.js 16 (App Router), React 19, and TypeScript, with rooms and services modeled as typed static data rather than a CMS, since the catalog is small. Styling uses Tailwind CSS v4 with self-hosted fonts and Framer Motion for a video-gated preloader and a scroll-aware navbar theme. SEO was data-first: JSON-LD, sitemap, and robots.txt all generate from the same room data that renders the UI. Deployment runs through a multi-stage Docker build, GitLab CI, and CapRover — a self-hosted path rather than Vercel.
The site is live at ceylanrovilla.com with the full guest-facing flow (home, rooms, room detail, services, about, contact) and SEO infrastructure (sitemap, robots, JSON-LD, OpenGraph) in place. Development ran as a single condensed build spanning navigation/theming, hero, galleries, room and service catalogs, about/contact pages, and finally SEO — all committed in one day per the repo's git history. No analytics, uptime, or booking-conversion data is present in the repository, so no usage metrics can be reported.
Most hotel sites sell a night's stay. Ceylanro Villa sells a layover — day-use rooms priced separately from overnight rates, express check-in, and 24/7 airport shuttles as the core amenities. That positioning is baked into the data model itself: every room in data/rooms.ts carries both a pricePerNight and an optional dayUsePrice, and the copy throughout ('quick rest between flights', 'built for exactly what you need on a short stopover') is written around transit guests rather than leisure travelers.
The technical backbone is deliberately simple: no database, no CMS, no auth. Room and service content lives as typed TypeScript arrays, which keeps the room catalog type-safe end-to-end (a Room type shared between the listing grid, detail page, and sitemap generator) without the overhead of a headless CMS for a catalog of four rooms. The more interesting engineering is in the delivery pipeline: rather than deploying to Vercel, the project ships as a standalone Next.js build inside a multi-stage Alpine Docker image, pushed through GitLab CI to a self-hosted CapRover instance — a deployment path suited to a client wanting infrastructure ownership rather than a managed platform. SEO was built data-first: the sitemap and JSON-LD schema both derive from the same ROOMS array that renders the UI, so the search-facing surface can't drift out of sync with the actual room catalog.
Visual identity: The site pairs a custom display typeface ('Amore') with the Orkney family across four weights, both self-hosted via next/font/local rather than pulled from Google Fonts — avoiding a third-party request and FOUC on a site where first impression matters. A full-bleed hero video (separate desktop/mobile encodes, swapped by breakpoint) sits behind a preloader that holds first paint until the video is ready, so the animated reveal never stutters on load.
Motion and theming: Framer Motion powers page transitions and staggered content reveals, all gated behind useReducedMotion checks for accessibility. A bespoke scroll-tracking hook (useNavTheme) reads data-navtheme attributes on page sections to flip the navbar between light and dark styling as the user scrolls past the video hero into lighter content sections — a common visual trick usually hardcoded per-page, implemented here as a reusable, route-aware hook.

Next Project — Marketing Website