// Pilah Landing Page Components
const { useState, useEffect, useRef } = React;
// ============ ICONS ============
const Icon = {
ArrowRight: ({ size = 16 }) => (
),
ArrowUpRight: ({ size = 16 }) => (
),
Check: ({ size = 16 }) => (
),
Plus: ({ size = 16 }) => (
),
Star: ({ size = 16 }) => (
),
Sparkle: ({ size = 16 }) => (
),
TrendUp: ({ size = 16 }) => (
),
Wallet: ({ size = 20 }) => (
),
Card: ({ size = 20 }) => (
),
Target: ({ size = 20 }) => (
),
Repeat: ({ size = 20 }) => (
),
Users: ({ size = 20 }) => (
),
Chart: ({ size = 20 }) => (
),
Lock: ({ size = 20 }) => (
),
Phone: ({ size = 20 }) => (
),
Zap: ({ size = 20 }) => (
),
Sun: ({ size = 16 }) => (
),
Moon: ({ size = 16 }) => (
),
};
// ============ LOGO ============
const PilahLogo = ({ size = 28 }) => (
Pilah
);
// ============ ANIMATED NUMBER ============
const AnimatedNumber = ({ value, prefix = '', suffix = '', duration = 1800, decimals = 0 }) => {
const [display, setDisplay] = useState(0);
const ref = useRef(null);
const started = useRef(false);
useEffect(() => {
const obs = new IntersectionObserver(([e]) => {
if (e.isIntersecting && !started.current) {
started.current = true;
const start = performance.now();
const animate = (t) => {
const p = Math.min((t - start) / duration, 1);
const eased = 1 - Math.pow(1 - p, 3);
setDisplay(value * eased);
if (p < 1) requestAnimationFrame(animate);
};
requestAnimationFrame(animate);
}
}, { threshold: 0.3 });
if (ref.current) obs.observe(ref.current);
return () => obs.disconnect();
}, [value, duration]);
const formatted = decimals > 0 ? display.toFixed(decimals) : Math.floor(display).toLocaleString('pt-BR');
return {prefix}{formatted}{suffix};
};
// ============ REVEAL ============
const Reveal = ({ children, delay = 0, y = 20 }) => {
const [visible, setVisible] = useState(false);
const ref = useRef(null);
useEffect(() => {
const obs = new IntersectionObserver(([e]) => {
if (e.isIntersecting) setVisible(true);
}, { threshold: 0.1 });
if (ref.current) obs.observe(ref.current);
return () => obs.disconnect();
}, []);
return (
{children}
);
};
Object.assign(window, { Icon, PilahLogo, AnimatedNumber, Reveal });