13Componentes
Quatro pilares. Counter animado no scroll.
Use stats em grupos de 4, mono no número, mono em CAPS no label. O counter anima de 0 ao valor com cubic-out 1.8s no momento que entra no viewport.
Grupo padrão de 4
0ANOS DE CLÍNICA
0PSICÓLOGAS IMPACTADAS
0PERTENCIMENTO
0VERTICAIS DE ATUAÇÃO
Quando usar
- Hero: 4 stats logo após CTAs primários, ancoram autoridade rápido.
- Comunidade: 4 stats sobre a rede (cidades, encontros, pertencimento).
- Co-fundadoras: 2 stats por fundadora (anos de clínica, formação, etc.).
Variante numérica vs textual
Use .stat-num-text em italic-serif quando o "número" é uma credencial mais forte que um valor (ex: "USP", "CRP 06/117883", "Mestra"). Mantém o ritmo visual.
Honestidade dos números. Nunca arredondar para enganar (3.000+ é honesto se há 2.847; 5.000+ não). Stats da Entrelaços são verificáveis.
Snippet · pronto pra colar
HTML · cole no seu projeto
<div class="e-stats">
<div class="e-stat">
<span class="stat-num" data-count="11">0</span>
<span class="stat-label">ANOS DE CLÍNICA</span>
</div>
<div class="e-stat">
<span class="stat-num" data-count="3000" data-suffix="+">0</span>
<span class="stat-label">PSICÓLOGAS IMPACTADAS</span>
</div>
<div class="e-stat">
<span class="stat-num" data-count="98" data-suffix="%">0</span>
<span class="stat-label">PERTENCIMENTO</span>
</div>
<div class="e-stat">
<span class="stat-num-text">USP</span>
<span class="stat-label">FORMAÇÃO · DOUTORADO</span>
</div>
</div>
<script>
// Counter animado on-scroll (cubic-out 1800ms)
const animateCount = (el) => {
const target = parseInt(el.dataset.count);
const suffix = el.dataset.suffix || '';
const dur = 1800;
const start = performance.now();
const tick = (now) => {
const t = Math.min((now - start) / dur, 1);
const eased = 1 - Math.pow(1 - t, 3);
const v = Math.round(target * eased);
el.textContent = (target >= 1000 ? v.toLocaleString('pt-BR') : v) + suffix;
if (t < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
};
const ioCounter = new IntersectionObserver(es =>
es.forEach(en => en.isIntersecting && (animateCount(en.target), ioCounter.unobserve(en.target))),
{ threshold: 0.4 }
);
document.querySelectorAll('[data-count]').forEach(el => ioCounter.observe(el));
</script>