// Cost section — combines: calculator + narrative + planilha vs BinGest hint. // Lives on a dark navy cinema background. function CostSection() { // Inputs const [obras, setObras] = React.useState(4); const [func, setFunc] = React.useState(8); const [diaria, setDiaria] = React.useState(160); const [horasPlanilha, setHorasPlanilha] = React.useState(6); // Derived losses (educated heuristics) // 1) Diárias mal-lançadas: ~3% da folha mensal (24 dias úteis) const folha = func * diaria * 24; const lossDiarias = folha * 0.03; // 2) Tempo perdido em planilha — hora a R$ 65 (custo médio do gestor) const lossHoras = horasPlanilha * 4 * 65; // 3) Atraso em recebimentos: ~1.2% sobre receita estimada (R$ 22k/obra) const receita = obras * 22000; const lossRecebiveis = receita * 0.012; // 4) Retrabalho de assistência técnica não rastreada: R$ 320/obra/mês const lossAT = obras * 320; const totalLoss = lossDiarias + lossHoras + lossRecebiveis + lossAT; const yearLoss = totalLoss * 12; const planAnnual = 12 * 159.99; // Empresarial annual cost const roi = totalLoss / 159.99; return (
{/* Subtle dotted backdrop */}
); } function Slider({ label, value, setValue, min, max, step=1, fmt, last=false }) { return (
{fmt(value)}
setValue(Number(e.target.value))} style={{ width: "100%", appearance: "none", height: 4, borderRadius: 999, background: `linear-gradient(to right, var(--blue-500) 0%, var(--blue-500) ${((value-min)/(max-min))*100}%, rgba(255,255,255,.10) ${((value-min)/(max-min))*100}%, rgba(255,255,255,.10) 100%)`, outline: "none", cursor: "pointer", }} className="bg-slider" />
); } function LossRow({ icon, label, value }) { return (
{icon} {label}
); } function BigCurrency({ value, decimals = 0 }) { // Smooth tween toward value as it changes const [n, setN] = React.useState(value); React.useEffect(() => { let raf, t0; const from = n, to = value; const dur = 600; const step = (t) => { if (!t0) t0 = t; const p = Math.min(1, (t - t0) / dur); const eased = 1 - Math.pow(1 - p, 3); setN(from + (to - from) * eased); if (p < 1) raf = requestAnimationFrame(step); }; raf = requestAnimationFrame(step); return () => cancelAnimationFrame(raf); }, [value]); return <>R$ {n.toLocaleString("pt-BR", { minimumFractionDigits: decimals, maximumFractionDigits: decimals })}; } function Narrative({ loss }) { return (
História real, sem maquiagem
Com BinGest
João faz check-in da equipe no celular do mestre. O DRE fecha sozinho. Ele sabe — em 3 cliques — qual obra deu lucro.
Ver na prática
); } function StoryStep({ step, when, title, body, tone }) { const bad = tone === "bad"; return (
{step} {when}
{title}
{body}
); } window.CostSection = CostSection;