Sitios web
Webs corporativas y páginas de aterrizaje que cargan al instante, preparadas para posicionar en Google y para funcionar en varios idiomas desde el primer día.
Webs y apps
Diseñamos y programamos sitios web rápidos y aplicaciones para iOS y Android. Sin plantillas y sin ataduras: el código, el dominio y las cuentas quedan a tu nombre.
Webs corporativas y páginas de aterrizaje que cargan al instante, preparadas para posicionar en Google y para funcionar en varios idiomas desde el primer día.
iOS y Android desde una sola base de código: cada función se programa una vez y funciona en ambos sistemas. Publicación en App Store y Google Play incluida.
Base de datos, cuentas de usuario, roles y permisos, cobros con Stripe, envío de correos, notificaciones push y conexión con servicios externos por API.
Un proyecto no termina el día del lanzamiento. Nos quedamos: corregimos, medimos, añadimos funciones y mantenemos la infraestructura.
Antes de escribir una línea entendemos qué proceso te come tiempo o dinero. A veces la respuesta no es una aplicación, y lo decimos.
No reinventamos autenticación, pagos ni notificaciones. Usamos herramientas probadas y dedicamos el tiempo a lo que es único de tu negocio.
Código, dominio, hosting y base de datos son tuyos. Puedes llevártelo a otro equipo cuando quieras, sin pedirnos permiso.
Webs, sistemas web y apps para iOS y Android: trabajos para clientes y productos propios. Cada uno con su caso detallado: el problema, qué hay dentro, las pantallas y las tecnologías.

Set Hub, en el centro de Los Ángeles, alquila dieciséis sets bajo un mismo techo, una azotea sobre la ciudad y un plató con un Mercedes de época. Le hemos construido al estudio el sistema entero — CRM, web con reserva y pago en línea, área de cliente y dos apps — y las reservas de todos los canales han acabado en una sola base.

Una app para iPhone y Android con la que los clientes habituales reservan sets directamente, sin la comisión de las plataformas: una cinta de horas con la disponibilidad en vivo, reservas que esquivan una hora ocupada, búsqueda del set a partir de una foto de referencia, la hora dorada en la azotea y la entrada al estudio con Face ID, incluso en un sótano sin cobertura.

Un CRM web en el que un estudio del centro de Los Ángeles lo lleva todo: reservas de cuatro canales, consultas, tareas del equipo, dinero, conversaciones con los clientes y diecinueve calendarios. Los correos de las plataformas, los pagos de Stripe y los mensajes de Telegram se convierten solos en registros, el texto normal se lee sin IA, mientras que ChatGPT y Claude operan sobre los datos con los mismos permisos que las personas.

Una app nativa para iPhone y Android: el equipo ve su día, confirma reservas y tareas desde la propia notificación y graba las reuniones con clientes. Face ID al entrar, datos de clientes solo en memoria, y el widget y la pantalla de bloqueo muestran el rodaje sin nombres de clientes ni importes.

Reconstruida desde cero: cuatro idiomas, páginas que pesan menos que una foto y un formulario que llega al correo en segundos.

El cliente deja el equipo y recibe un enlace donde ve en qué paso va, con fotos del antes y el después. Se acabaron las llamadas de «¿cómo va lo mío?».

Enviamos al cliente un enlace, lo abre en el móvil, firma con el dedo y los dos recibimos el documento por correo. Sin imprimir, sin escanear, sin instalar nada.

Para agencias que venden inmuebles a compradores extranjeros y luego se los gestionan. El sistema lleva el inmueble por toda su vida: venta, entrada en gestión, alquiler, mantenimiento.

Aplicación móvil y portal web completo desde una sola base de código, para agencias y propietarios que gestionan varios apartamentos a la vez.
Ingeniería
Fragmentos tal cual están en el repositorio: el formulario, la firma de contratos, el estado de las reparaciones y el horario del taller. Lo recortado está marcado con «// …».
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);
}Trampa para bots y comprobación de Turnstile: a tu correo llegan solicitudes de personas y el spam se descarta en silencio.
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();Registramos la hora, la IP, el dispositivo y el SHA-256 del texto que la persona vio al firmar: la firma se puede demostrar y el documento no se puede cambiar.
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,
});
}Cada cambio de estado queda en el historial que el cliente ve en su enlace, y el correo sale una sola vez: cuando la reparación está lista.
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] };
// …
}La web sabe sola si el taller está abierto: hora de Tenerife con horario de verano y festivos, del mismo origen que los datos para Google.
Solo lo que de verdad mueve HostBase, Hourgrid, Mansaria y esta web. Nada puesto para aparentar.
¿Ya sabes lo que necesitas? Marca las tareas, el stack y la forma de trabajar: la solicitud se arma sola.
Arma tu proyecto en el configuradorCuéntanoslo por WhatsApp. La primera conversación es gratuita y sirve para ver si merece la pena hacerlo.