Websites
Company sites and landing pages that load instantly, ready to rank on Google and to run in several languages from day one.
Web & apps
We design and build fast websites and apps for iOS and Android. No templates and no lock-in: the code, the domain and every account are in your name.
Company sites and landing pages that load instantly, ready to rank on Google and to run in several languages from day one.
iOS and Android from a single codebase: each feature is written once and works on both. Publishing to the App Store and Google Play included.
Database, user accounts, roles and permissions, card payments through Stripe, email, push notifications and API connections to outside services.
A project does not end on launch day. We stay: we fix, measure, add features and keep the infrastructure running.
Before a line of code we work out which process is eating your time or money. Sometimes the answer is not an app, and we say so.
We do not reinvent authentication, payments or notifications. We use proven tools and spend the time on what is actually unique to your business.
Code, domain, hosting and database are yours. You can take the whole thing to another team whenever you like, without asking us.
Websites, web systems and iOS and Android apps — client work and our own products. Each comes with a detailed case study: the problem, what’s inside, the screens and the stack.

Set Hub in Downtown LA rents out sixteen sets under one roof, a rooftop above the city and a stage with a vintage Mercedes. We built the studio its entire system — a CRM, a website with online booking and payment, a guest account and two apps — and bookings from every channel now land in one database.

An app for iPhone and Android through which regular guests book sets directly, with no platform fees: a time tape driven by live availability, booking around a taken hour, finding a set from a reference photo, golden hour on the rooftop and getting into the studio with Face ID — even in a basement with no signal.

A web CRM where a studio in Downtown Los Angeles runs everything: bookings from four channels, enquiries, team tasks, money, guest conversations and nineteen calendars. Platform emails, Stripe payments and Telegram messages become records on their own, plain text is parsed without AI, and ChatGPT and Claude work with the data under the same permissions as people.

A native app for iPhone and Android: the team sees its day, confirms bookings and tasks straight from a notification, and records meetings with clients. Face ID on entry, client data only in memory, and the widget and lock screen show the shoot without guest names or amounts.

Rebuilt from scratch: four languages, pages lighter than a photo, and a form that reaches the inbox in seconds.

The client leaves a device and gets a link showing which step it is on, with before and after photos. No more calls asking how it is going.

We send the client a link, they open it on their phone, sign with a finger, and both sides get the document by email. No printing, no scanning, nothing to install.

For agencies that sell property to foreign buyers and then manage it for them. The system carries a property through its whole life: sale, handover to management, rental, upkeep.

A mobile app and a full web portal from a single codebase, for agencies and owners running several properties at once.
Engineering
Excerpts exactly as they sit in the repository: the request form, contract signing, repair status and workshop hours. Anything we cut is marked “// …”.
if (form.company) return json({ ok: true });
const name = String(form.name ?? '').trim().slice(0, 200);
const contact = String(form.contact ?? '').trim().slice(0, 200);
const about = String(form.about ?? '').trim().slice(0, MAX_LEN);
if (!name || !contact || !about || form.consent !== true) {
return json({ error: 'validation' }, 400);
}
if (env.TURNSTILE_SECRET) {
const ip = request.headers.get('cf-connecting-ip');
const ok = await verifyTurnstile(env.TURNSTILE_SECRET, form.turnstile, ip);
if (!ok) return json({ error: 'captcha' }, 400);
}A bot trap plus a Turnstile check: your inbox gets requests from people, and spam is dropped silently.
export async function sha256Hex(text) {
return toHex(await crypto.subtle.digest('SHA-256', enc.encode(text)));
}
// …
const now = new Date().toISOString();
await env.DB.prepare(
`update contracts
set status = 'signed', signed_at = ?, signer_name = ?, signer_image = ?,
signer_ip = ?, signer_ua = ?, signed_hash = ?,
signer_phone = ?, signer_address = ?
where id = ? and status <> 'signed'`,
)
.bind(
// …
await sha256Hex(row.body),
// …
)
.run();We record the time, IP, device and a SHA-256 of the text the person saw when signing: the signature can be proven and the document can’t be swapped.
const status = ALL_STATUSES.includes(b.status) ? b.status : row.status;
const now = new Date().toISOString();
// …
if (status !== row.status || clean(b.comment, 500)) {
await addEvent(env, id, status, clean(b.comment, 500), now);
}
let mailed = false;
if (status === 'ready' && row.status !== 'ready') {
mailed = await mailOrder(env, 'ready', {
email: row.client_email,
lang: row.lang,
number: row.number,
device: row.device,
url: new URL(`/o/${id}`, SITE.url).href,
});
}Every status change goes into the history the client sees on their link, and the email goes out once — when the repair is ready.
function canary(d) {
const f = new Intl.DateTimeFormat('en-CA', {
timeZone: 'Atlantic/Canary', year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', hourCycle: 'h23', weekday: 'short',
});
const p = Object.fromEntries(f.formatToParts(d).map((x) => [x.type, x.value]));
const dow = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 }[p.weekday];
return { date: `${p.year}-${p.month}-${p.day}`, dow, mins: Number(p.hour) * 60 + Number(p.minute) };
}
const toMins = (hhmm) => Number(hhmm.slice(0, 2)) * 60 + Number(hhmm.slice(3, 5));
const workday = (c) => (HOURS[c.dow] && !HOLIDAYS.has(c.date) ? HOURS[c.dow] : null);
export function shopStatus(now = new Date()) {
const c = canary(now);
const h = workday(c);
if (h && c.mins >= toMins(h[0]) && c.mins < toMins(h[1])) return { open: true, closes: h[1] };
// …
}The site knows on its own whether the workshop is open: Tenerife time, daylight saving and holidays, from the same source as the data Google reads.
Only what HostBase, Hourgrid, Mansaria and this site actually run on. Nothing listed for show.
Already know what you need? Tick the tasks, the stack and how you want to work — the request builds itself.
Build your project in the configuratorTell us on WhatsApp. The first conversation is free and exists to work out whether it is worth building at all.