/* v2 Primitives — shared tokens for the new design system */
const V2_PHOTOS = {
/* Curated Unsplash forest imagery — wired by URL. If a photo fails to load,
the dark card chrome behind makes it look intentional. */
heroForest: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=1920&q=80&auto=format&fit=crop",
forestMist: "https://images.unsplash.com/photo-1448375240586-882707db888b?w=1600&q=80&auto=format&fit=crop",
forestAerial: "https://images.unsplash.com/photo-1473773508845-188df298d2d1?w=1600&q=80&auto=format&fit=crop",
forestAutumn: "https://images.unsplash.com/photo-1500382017468-9049fed747ef?w=1600&q=80&auto=format&fit=crop",
forestPath: "https://images.unsplash.com/photo-1542273917363-3b1817f69a2d?w=1600&q=80&auto=format&fit=crop",
forestMtn: "https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=1600&q=80&auto=format&fit=crop",
forestRoad: "https://images.unsplash.com/photo-1511497584788-876760111969?w=1600&q=80&auto=format&fit=crop",
forestDense: "https://images.unsplash.com/photo-1518495973542-4542c06a5843?w=1600&q=80&auto=format&fit=crop",
/* operational imagery — workers, gear, drones */
workCamp: "https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=80&auto=format&fit=crop",
workMachine: "https://images.unsplash.com/photo-1581094288338-2314dddb7ece?w=1200&q=80&auto=format&fit=crop",
drone: "https://images.unsplash.com/photo-1473968512647-3e447244af8f?w=1200&q=80&auto=format&fit=crop",
sensorTrees: "https://images.unsplash.com/photo-1465146344425-f00d5f5c8f07?w=1200&q=80&auto=format&fit=crop",
};
const V2Mark = ({ size = 28 }) => (
);
const V2Eyebrow = ({ children, className = "" }) => {children};
const V2Button = ({ variant = "primary", children, href = "#", icon = true, ...rest }) => (
{children}
{icon && →}
);
function v2UseCountUp(target, { duration = 1500, start = 0, decimals = 0 } = {}) {
const [v, setV] = React.useState(start);
React.useEffect(() => {
let raf, t0;
const tick = (t) => {
if (t0 == null) t0 = t;
const p = Math.min(1, (t - t0) / duration);
const eased = 1 - Math.pow(1 - p, 3);
setV(start + (target - start) * eased);
if (p < 1) raf = requestAnimationFrame(tick);
};
raf = requestAnimationFrame(tick);
return () => cancelAnimationFrame(raf);
}, [target, duration, start]);
return Number(v).toLocaleString("ca-ES", { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
}
/* Live clock — shown in hero HUD */
function v2UseClock() {
const [d, setD] = React.useState(() => new Date());
React.useEffect(() => {
const id = setInterval(() => setD(new Date()), 1000);
return () => clearInterval(id);
}, []);
const pad = (n) => String(n).padStart(2, "0");
return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
}
Object.assign(window, { V2_PHOTOS, V2Mark, V2Eyebrow, V2Button, v2UseCountUp, v2UseClock });