AGRICULTURAREIMAGINADA.

- CLIENTE
- KAVITA AGRO
- TIPO
- COMERCIO INTERACTIVO
- AÑO
- 2026
- ESTADO
- EN LÍNEA
02 / LA IDEA
La reventa necesitaba convertir el catálogo en conversación.
Una landing de drones agrícolas no vende sola: tiene que entregar un presupuesto listo, en el WhatsApp de la sucursal correcta, sin inventar una sola especificación. Sin framework, sin build: solo HTML, CSS y JavaScript escritos a mano.
01 / CATÁLOGO
26 equipos en 5 categorías, cada ítem con estado de confirmación por campo. Filtros de categoría y de compatibilidad con los 3 drones (T25P, T70P, T100) combinados en AND.

02 / DRONES
Tres modelos DJI Agras comparados lado a lado: pulverización, dispersión, garantía. Los contadores animados nacen del propio HTML: sin JS, el número ya está correcto.

03 / PRESUPUESTO
Un minicarrito sin tienda: drones, equipos y servicios entran en un presupuesto que persiste en localStorage entre visitas, con contador en tiempo real.

04 / ENRUTAMIENTO
Al enviar, el mensaje sale estructurado en bloques y va al WhatsApp de la unidad elegida: 4 sucursales en MG, ES y RJ, con fallback al número predeterminado.

CATÁLOGO
DRONES
PRESUPUESTO
ENRUTAMIENTO
04 / BAJO EL CAPÓ
- USUARIO→
- CATÁLOGO→
- PRESUPUESTO→
- ENRUTAMIENTO POR SUCURSAL→
SIN FRAMEWORKHTML5 semántico, CSS puro y JS vanilla, sin build. Cloudflare Workers sirviendo estáticos.+
Cero framework, a propósito: HTML5 semántico, CSS puro y JavaScript vanilla, sin build step. Se abre directo el index.html en el navegador. Son ~7.200 líneas divididas en 3 archivos (script.js con 1.735 líneas, styles.css con 4.239), decisión documentada en el propio README como "landing autocontenida", separada del sistema principal de Kavita. El hosting hoy es Cloudflare Workers vía wrangler.jsonc sirviendo los archivos como static assets, con un vercel.json residual solo para redirigir permanentemente www.kavita.com.br a kavita.com.br. Es el rastro de una migración de proveedor hecha sin romper el dominio anterior.
MODELO DE DATOSCatálogo como dato gobernado: cada ítem lleva estado confirmado/pendiente. Nada es inventado.+
El catálogo de equipos (26 ítems en 5 categorías: baterías, cargadores y energía, mezcladores, motobombas y otros accesorios) vive en un array ACCESSORIES en script.js, pero se trata como dato gobernado, no como contenido suelto. Cada ítem lleva un campo status, que puede ser confirmado, pendente-imagem, pendente-especificacao o pendente-compatibilidade, y la regla del proyecto, documentada en docs, es explícita: "nada se inventa". Las specs sin fuente confirmada (manual DJI oficial o página técnica de Agrobox) quedan marcadas como pendientes en vez de rellenadas con una suposición. Los filtros de categoría y de compatibilidad con los 3 drones (T25P/T70P/T100) se combinan en AND, así que un ítem solo aparece si cumple los dos criterios al mismo tiempo.
PRESUPUESTO + ENRUTAMIENTOPresupuesto en localStorage con fallback silencioso; REPRESENTATIVES mapea 4 sucursales a 4 números.+
La cotización funciona como un minicarrito sin tienda. El visitante agrega drones, equipos y servicios a un budget que persiste en localStorage entre sesiones (con fallback silencioso si el navegador bloquea el storage) y ve un contador de ítems en tiempo real. Al enviar el formulario de lead, el sitio arma un mensaje estructurado, separado en bloques "Drones", "Equipos y accesorios" y "Servicios", y redirige vía wa.me. El número de destino cambia por sucursal: un objeto REPRESENTATIVES mapea 4 filiales (Mateus/sede, Itaperuna-RJ, Manhuaçu-MG, Cachoeiro de Itapemirim-ES) a 4 WhatsApp distintos, con fallback al número por defecto si el visitante no elige ninguna.
PERFORMANCEpreload + fetchpriority en el hero, el video se pausa fuera del viewport, contadores en rAF con easing manual, tema vía matchMedia.+
Varios detalles de performance y accesibilidad que normalmente vienen de un framework se hicieron a mano. El hero usa preload con fetchpriority="high" para la imagen crítica y preconnect para Google Fonts. El video de fondo del hero se pausa vía IntersectionObserver cuando sale del viewport, ahorrando CPU y batería, y ni siquiera se reproduce si prefers-reduced-motion está activo. Los contadores animados (cifras de DJI) usan requestAnimationFrame con easing easeOutCubic escrito a mano, calculado a partir del propio texto del HTML, así que funcionan como progressive enhancement puro: sin JS, el número final ya está correcto. Y el tema claro/oscuro respeta la preferencia del sistema (matchMedia) en la primera visita y después persiste la elección del usuario en localStorage.
CONSTRUIDO CON — HTML · CSS · JavaScript · VercelCÓDIGO ↗
05 / DETALLES
26
EQUIPOS
04
RUTAS REGIONALES
0
FRAMEWORKS
~7.200
LÍNEAS A MANO
06 / RESULTADO



DEL GRANOA LA TAZA.
