Home/ Work/Paintball Bled
Lead dev · 2026 · Live

Paintball Bled

A brand-new, video-first marketing site for a forest paintball venue outside Bled — Vite build, hand-rolled 5-language i18n, autoplay hero, and a booking flow tuned for groups rather than individuals.

Role Lead Developer
Year 2026
Stack Vite · vanilla JS · custom i18n
Languages SLO · ENG · DEU · ITA · ESP
Location Radovljica, Slovenia
Paintball Bled screenshot
Languages shipped
5
SLO · ENG · DEU · ITA · ESP
Bundle output
2 files
one JS · one CSS (Vite)
i18n elements
44
runtime language switch
Sections
5
hero · packages · reviews · location · contact

Overview

This is the fresh Vite rebuild. The previous paintball-bled.com was a WordPress + Divi site that had served the business for years — but it had accumulated the usual WordPress weight (slow, heavy CSS, clumsy on mobile). The client wanted a clean restart: a fast, modern marketing page that reads in five languages, runs on a single video-backed hero, and still sends every serious visitor into a booking conversation.

I built the whole thing as a static Vite bundle — plain HTML, vanilla JavaScript, no React, no Vue, no CMS. Every translatable string lives in JSON; every element in the DOM that needs translating carries a data-i18n=“keypath” attribute. A small runtime swaps copy on the fly when the visitor picks SLO / ENG / DEU / ITA / ESP in the header. Package cards are rendered dynamically so they stay translation-first instead of hard-coded per locale.

The staging site lives at nova.paintball-bled.com. Once the client signs off, it moves to the main domain with a straightforward static upload. No server-side runtime, no plugin updates, nothing to monitor beyond the DNS and the SSL cert.

Architecture

~/paintball-bled/architecture/static-site.svg
01 — SOURCEHTML templatedata-i18n=“key.path”JS entry (vanilla)i18n · menu · scroll5 locale JSONssl · en · de · it · esMedia assetspaintball3.mp4 · imagesVite buildbundling · hashing · tree-shake · minifyindex-[hash].js · index-[hash].csszero server runtime02 — OUTPUT & HOSTINGdist/ bundlestatic HTML + JS + CSSStaging hostnova.paintball-bled.comMain domainpaintball-bled.com (cutover)Visitor browserruntime locale · video heroBebas Neue · Plus Jakarta Sans · Google Fonts preconnect · video poster · playsinline03 — TYPOGRAPHY & MEDIA

Reading the diagram: Four source inputs — the HTML template marked up with data-i18n attributes, a single vanilla JS entry, five locale JSON files, and the media assets — feed into a single Vite build. The output is a content-hashed dist/ bundle that’s served statically from the staging host today and will cut over to the main domain when the client approves. There is no server runtime, no CMS, no backend: every locale switch happens in the visitor’s browser against the already-delivered JSON. Typography is Bebas Neue (display) + Plus Jakarta Sans (body), preconnected to Google Fonts for sub-second first paint.

03 What I delivered · challenges solved

Six things shipped,
three hard ones solved.

Key contributions

  • Hand-rolled the entire front-end — Vite as the bundler, vanilla HTML + JavaScript, no framework overhead. Final bundle: one JS file + one CSS file, both cache-busted via content hash.
  • Built a data-i18n-driven translation system from scratch — 44 elements swap copy at runtime across five languages with zero page reload, including dynamically-rendered package cards.
  • Designed the video-first hero: muted autoplay forest footage behind a Bebas Neue display title (ADRENALINE FUN IN THE FOREST) and a dual CTA — Book now + View packages.
  • Built the location-chip hero badge (RADOVLJICA, SLOVENIA) to disambiguate the venue from the Paintball Bled brand, which is physically in Radovljica despite the name.
  • Wired the mobile experience: hamburger-triggered full-screen menu, touch-friendly phone CTA pinned in the header, and breakpoint-aware section padding that keeps the hero video readable on small screens.
  • Set up staging at nova.paintball-bled.com ahead of the main-domain switchover so the client can preview and approve before production cut-over.

Challenges solved

  • Multilingual tourism audience — a paintball venue in Slovenia draws Slovenian, English, German, Italian, and Spanish visitors. Shipping five languages without a CMS meant building a lightweight JSON-backed i18n layer that reads attribute keys at runtime rather than pre-rendering five site copies.
  • Video hero that doesn't kill mobile performance — <video autoplay muted loop playsinline> works everywhere, but the source (paintball3.mp4) had to be encoded small enough to start playing on 4G before the user scrolls, with a static poster fallback on data-saver connections.
  • Booking flow for groups, not individuals — the venue sells birthday parties, stag and hen-dos, and team-buildings. Copy, package tiers, and CTAs are tuned for a group organiser making one reservation on behalf of many, not a solo visitor picking a single slot.
Scope discipline is the real craft on a small site. No CMS, no framework, no booking plugin — a Vite bundle, five languages, one form, one CTA, shipped in days. The client gets fast; the visitor gets a working funnel.
Davor Majc, Lead Developer / Paintball Bled
04 Tech stack

What's under the hood.

ViteVanilla JSCustom i18nBebas NeuePlus Jakarta SansHTML5CSS GridVideo heroResponsiveRuntime locale switch
Let's talk

Ready to fix, build,
or scale?

30 minutes, with me personally. I'll read your system like a log file and tell you what I'd do first. No pitch deck, no sales funnel.

Davor Majc, founder, Numen

What you get on call
→ a one-page diagnosis
→ 2–3 fix shapes, ranked by leverage
→ rough cost + timeline for each
→ yes/no — am I the right fit
+386 40 828 474 · Blejska Dobrava, SI