Bénin Horizons is a fictional tour operator with one job: turn a visitor into a WhatsApp conversation. No booking system, no accounts, no backend — just a fast, mobile-first page built entirely around getting someone to send that first message, in whichever of French or English they read.
What makes it work
- No stock photography, anywhere. Every visual accent — the gallery, the dividers, the hero — comes from one wax-print pattern designed by hand. The whole page loads in about 38 KB, instantly, even on a slow connection.
- The WhatsApp button never breaks. Every link works straight out of the HTML, before any script even runs — JavaScript only adds a tour-specific message on top. If anything else on the page fails, the one thing that matters still works.
- Checked the way a visitor actually sees it. Every color was tested against how it actually renders in a browser, not just the numbers in a design file — three labels that looked fine on paper were caught and fixed before launch.
Design at a glance
- indigo · #182A4D
- indigo-light · #2C4372
- sand · #FBF6ED
- gold · #E7A93E
- lagoon · #1C8C86
- hibiscus · #D6396B
- Tour cards — pending capture
Built to last
- Loads almost instantly — about 38 KB for the whole page, even on a slow connection
- Works with a keyboard alone, and reads correctly with a screen reader
- No cookies, no tracking, no data collected from visitors
- The WhatsApp button keeps working even if a script fails to load
For developers — the full technical breakdown
01. Zero photography, one hand-drawn pattern
- Problem
- A fictional operator has no real destinations to shoot, and no budget even if it did.
- Choice
- One reusable wax-print SVG pattern and CSS gradients, standing in for every image on the page.
- Result
- A distinct identity and a ~38 KB page — instant load on any connection.
02. WhatsApp works with JavaScript off
- Problem
- The one conversion path couldn’t depend on a script loading successfully.
- Choice
- Every WhatsApp link is real HTML from the start; JavaScript only upgrades it with a tour-specific message.
- Result
- The page’s one job survives even when almost everything else about it doesn’t.
03. Contrast checked against what renders
- Problem
- Hex values that look fine on paper aren’t the same as what a browser actually renders.
- Choice
- Checked every text/background pairing against computed styles, not source values.
- Result
- Three failing labels caught and fixed before launch — numbers that are true, not just documented.
Accessibility & performance
- Skip-to-content link, semantic landmarks, real focus rings throughout
prefers-reduced-motionrespected- ~38 KB total, zero runtime dependencies
- CSP meta tag, plus
rel="noopener"on every external link - Placeholder contact info uses RFC 2606’s
.exampleTLD — can never resolve to a real inbox
What I’d do differently
Self-host the three font families the way I later did on Nova Home Care — Google Fonts is the one external request left on an otherwise fully self-contained page.
Stack
- HTML5
- CSS3 (custom properties, clamp(), Grid)
- Vanilla JavaScript
- IntersectionObserver
- localStorage