// Shared components and icons for Farmatric landing
const { useState, useEffect, useRef } = React;
/* ---------- ICONS (line, no slop) ---------- */
const Icon = {
arrow: (p) => ,
arrowRightSmall: (p) => ,
play: (p) => ,
plus: (p) => ,
close: (p) => ,
menu: (p) => ,
whatsapp: (p) => ,
globe: (p) => ,
// problem icons
noBuyer: (p) => ,
notebook: (p) => ,
water: (p) => ,
// feature icons
field: (p) => ,
handshake: (p) => ,
chart: (p) => ,
drop: (p) => ,
coin: (p) => ,
link: (p) => ,
// training icons
phone: (p) => ,
video: (p) => ,
tractor: (p) => ,
book: (p) => ,
// dashboard sidebar icons
layout: (p) => ,
leaf: (p) => ,
check: (p) => ,
basket: (p) => ,
wallet: (p) => ,
report: (p) => ,
bell: (p) => ,
trend: (p) => ,
// misc
spark: (p) => ,
};
/* ---------- ANIMATED COUNTER ---------- */
function Counter({ to, suffix = "", duration = 1800 }) {
const [val, setVal] = useState(0);
const ref = useRef(null);
const started = useRef(false);
useEffect(() => {
const obs = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting && !started.current) {
started.current = true;
const start = performance.now();
const tick = (now) => {
const t = Math.min(1, (now - start) / duration);
const eased = 1 - Math.pow(1 - t, 3);
setVal(Math.round(to * eased));
if (t < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
}
});
}, { threshold: 0.4 });
if (ref.current) obs.observe(ref.current);
return () => obs.disconnect();
}, [to, duration]);
return {val}{suffix};
}
/* ---------- REVEAL ON SCROLL ---------- */
function Reveal({ children, delay = 0, as: As = "div", className = "", ...rest }) {
const ref = useRef(null);
const [shown, setShown] = useState(false);
useEffect(() => {
const obs = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting) { setShown(true); obs.disconnect(); }
});
}, { threshold: 0.12, rootMargin: "0px 0px -60px 0px" });
if (ref.current) obs.observe(ref.current);
return () => obs.disconnect();
}, []);
const cls = `reveal ${shown ? "in" : ""} ${delay ? `delay-${delay}` : ""} ${className}`.trim();
return