// narrative.jsx — camada narrativa da landing (PAS: dor → virada → jornada → prova) // // Estrutura de leitura, não de decoração: // 1. Agitação — as 3 mentiras que contaram pro vendedor + a negação // 2. Problema/Diagnóstico — dois blocos rotulados, tipografia diferente no rótulo // 3. Diferenciador — "a maioria das ferramentas" vs "o Comissa" // 4. Jornada — 01/02/03 com a linha preenchendo conforme o scroll // 5. Segmentos — cards por ICP // 6. Garantia + FAQ — remove risco e responde objeção real // // FORA DA PÁGINA (definidos aqui, não chamados por ninguém): PlataformasStrip // e MobPlataformas — a faixa "Integrações nativas" com os 12 logos, removida a // pedido. Ficam no arquivo porque voltar é uma linha em landing-page.jsx / // mobile-site.jsx; o mesmo tratamento que VendedorTicker e SegmentosSection. // // COR: nada de paleta nova. A virada emocional usa o que o site já tem — // o fundo desce pra um preto mais fechado na dor (#F1F5F9) e volta pro // --bg-2 com glow índigo (o mesmo --indigo/--cyan da barra de progresso) // na resolução. Rosa (--rose) marca o que está errado; verde (--green) o que // está certo. Tudo já existia no tema. const { useEffect: nFx, useRef: nRefHook, useState: nSt } = React; // ── Motion helpers ─────────────────────────────────────────── // Uma checagem só de prefers-reduced-motion, compartilhada por tudo aqui. function useCalmMotion() { const [calm, setCalm] = nSt(false); nFx(() => { const mq = window.matchMedia('(prefers-reduced-motion: reduce)'); const on = () => setCalm(mq.matches); on(); mq.addEventListener ? mq.addEventListener('change', on) : mq.addListener(on); return () => { mq.removeEventListener ? mq.removeEventListener('change', on) : mq.removeListener(on); }; }, []); return calm; } // Progresso 0→1 de um elemento atravessando a viewport. // `trigger` = altura (fração da viewport) onde a conta começa; // `span` = quanto da altura do elemento precisa passar pra chegar em 1. function useScrollPass(ref, { trigger = 0.8, span = 0.85 } = {}) { const [p, setP] = nSt(0); nFx(() => { const el = ref.current; if (!el) return; let raf = 0; const calc = () => { const r = el.getBoundingClientRect(); const vh = window.innerHeight || 1; const line = vh * trigger; const total = Math.max(1, r.height * span); const v = (line - r.top) / total; setP(v < 0 ? 0 : v > 1 ? 1 : v); }; const onScroll = () => { cancelAnimationFrame(raf); raf = requestAnimationFrame(calc); }; window.addEventListener('scroll', onScroll, { passive: true }); window.addEventListener('resize', onScroll); calc(); return () => { window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); cancelAnimationFrame(raf); }; }, [trigger, span]); return p; } // Reveal escalonado — fade + translateY(16px), 90ms entre irmãos. // Cada filho entra sozinho; o gatilho é a entrada do container. // // `stretch` só pra quando o Stagger embrulha UM card que precisa herdar a // altura da linha do grid pai (a Virada, os Segmentos). Fora desse caso o // `height: 100%` é veneno: num grid item esticado, filho com altura // percentual e linha de altura automática se resolvem em círculo, o wrapper // colapsa e o texto que passa dele fica cortado por baixo — era isso que // comia a segunda linha de "Ninguém rastreia a venda. Todo mundo…". // Qual item da lista está na faixa de leitura (o meio da tela). Existe pra a // seção poder acender UM item por vez conforme o visitante desce: o olho é // levado item a item em vez de bater numa parede de três blocos iguais. function useItemNaFaixa(n) { const refs = nRefHook([]); const [ativo, setAtivo] = nSt(-1); nFx(() => { const els = refs.current.filter(Boolean); if (!els.length) return; // Sem animação: acende tudo e não observa nada. if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { setAtivo(n - 1); return; } const io = new IntersectionObserver((entradas) => { entradas.forEach((e) => { if (e.isIntersecting) setAtivo(Number(e.target.dataset.idx)); }); }, { rootMargin: '-40% 0px -40% 0px', threshold: 0 }); els.forEach((el) => io.observe(el)); return () => io.disconnect(); }, [n]); return [refs, ativo]; } function Stagger({ children, step = 90, y = 16, delay = 0, style, stretch = false }) { const ref = nRefHook(null); const [shown, setShown] = nSt(false); const calm = useCalmMotion(); nFx(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver((es) => { es.forEach((e) => { if (e.isIntersecting) { setShown(true); io.unobserve(el); } }); // Antes disparava com 15% do bloco visível e a borda de baixo puxada em // 8%: na prática, a animação rodava quando só a primeira linha tinha // aparecido no rodapé da tela — quem descia via o bloco JÁ montado, sem // nunca ter visto a entrada. Puxando a borda de baixo em 26%, o gatilho // só acontece quando o bloco entrou de verdade no campo de leitura. }, { threshold: 0, rootMargin: '0px 0px -26% 0px' }); io.observe(el); return () => io.disconnect(); }, []); const items = React.Children.toArray(children); return (
{items.map((c, i) => (
{c}
))}
); } // Rótulo que nomeia a etapa antes do parágrafo ("PROBLEMA", "DIAGNÓSTICO"). // Placa de sinalização: o leitor sabe o que vem antes de ler a frase. function NarrLabel({ children, tone = 'muted' }) { // Rótulo é texto de 11px com tracking largo — o caso mais frágil que existe // pra contraste. Todos os tons vêm da escala `-text`, não da de // preenchimento: em `--cyan` puro este rótulo dava 2:1 e sumia. const color = tone === 'rose' ? 'var(--rose-text)' : tone === 'indigo' ? 'var(--indigo-text)' : tone === 'cyan' ? 'var(--cyan-text)' : 'var(--muted-2)'; return (
{/* Saiu o tracinho de 18px que vinha antes do rótulo. Não era caractere, era uma com fundo, mas lia como travessão na tela ("— A MENTIRA") e era exatamente disso que o Arthur reclamou. O rótulo se vira sozinho com o uppercase e o tracking. */} {children}
); } // ───────────────────────────────────────────────────────────── // 1. Agitação — "Comissão não é sorte" // Fundo mais fechado que o resto da página: a dor é o ponto mais escuro // da narrativa, e a virada logo depois é sentida antes de ser lida. // ───────────────────────────────────────────────────────────── const MENTIRAS = [ { n: '01', t: 'vender mais', d: 'Como se o buraco fosse o volume, e não o que some entre fechar a venda e receber por ela.', }, { n: '02', t: 'confiar na planilha do financeiro', d: 'A planilha que ninguém confere, todo mundo edita e nenhuma pessoa assina embaixo.', }, { n: '03', t: 'esperar o fechamento do mês', d: 'Trinta dias no escuro pra saber o valor exatamente no dia em que já não dá pra contestar.', }, ]; function AgitacaoSection() { // O palco: três mentiras, uma por vez, presas no meio da tela enquanto o // visitante rola. Cada volta do scroll risca a que ele acabou de ler e traz // a próxima. É leitura forçada em ordem — impossível pular — e o risco // acontece na frente dele, que é o que faz a negação pesar. const palcoRef = nRefHook(null); const calm = useCalmMotion(); // `span` casa com a janela em que o bloco fica grudado: 0 quando ele cola no // topo, 1 quando descola. Sem isso a conta gastava metade do percurso antes // de o sticky sequer engatar, e a primeira mentira passava batida. const p = useScrollPass(palcoRef, { trigger: 0.14, span: 0.75 }); const idx = calm ? MENTIRAS.length - 1 : Math.max(0, Math.min(MENTIRAS.length - 1, Math.floor(p * MENTIRAS.length * 0.999))); return (
{/* vinheta rosa entrando de cima o mesmo --rose dos indicadores negativos. Presa às bordas laterais (sem os -10%) porque a seção não pode mais recortar o próprio conteúdo: `overflow` diferente de `visible` — `hidden` OU `clip` — tira o palco sticky das mentiras do relógio da janela e ele para de grudar. */}
A mentira

Comissão não é sorte.
Você só foi treinado pra torcer.

Toda vez que o número veio menor, a resposta foi a mesma: o problema é você. Bastava:

{/* 260vh e não 170vh: o palco preso só dura `altura - altura do filho`, então 170vh deixava ~600px de curso pra três passos — 200px por mentira, menos de um giro de roda, e a 02 passava sem ser vista. Com 260vh cada passo ganha ~330px, e o span 0.75 faz o último fechar no mesmo instante em que o sticky solta (sem seção vazia depois). */}
{/* contador: quantas já caíram */}
{MENTIRAS.map((m, i) => ( ))}
{MENTIRAS.map((m, i) => { const passou = i < idx; const atual = i === idx; return (
{m.n}
{/* O risco corre da esquerda pra direita no instante em que o visitante rola pra próxima: ele vê a frase ser riscada, não encontra uma frase já riscada. */} {m.t}
{m.d}
); })}

E quando a comissão vinha errada, a culpa voltava pra você: {' '} “deve ter anotado errado”.

{/* A conta que dá nome ao prejuízo. Sem número, a seção é reclamação; com número, é uma perda que o leitor consegue reconhecer na própria carteira. Hipótese declarada, não estatística. */}

Uma venda não contada por mês, a 3% de um ticket de {' '} R$ 8.000, são {' '} R$ 2.880 {' '} por ano que você nunca vai cobrar, porque nunca soube que existiu.

); } // ───────────────────────────────────────────────────────────── // 2. Problema — uma frase só // ───────────────────────────────────────────────────────────── // Eram duas colunas rotuladas "Problema" e "Diagnóstico" com um título grande // cada. Lado a lado elas competiam, e a segunda só fazia sentido depois da // primeira — ou seja, era uma frase quebrada em duas caixas. Agora é uma // sentença só, que é como ela se lê em voz alta. function ProblemaDiagnostico() { return (
O problema

Ninguém rastreia a venda — todo mundo lança a venda. E conta certa em cima de dado digitado herda o erro do dado.

Lançar é memória, e memória falha. Quando falha, quem paga a conta é sempre quem vendeu: é a sua palavra contra uma célula de planilha. Por isso comissão certa não começa na fórmula — começa no clique que gerou a venda.

); } // ───────────────────────────────────────────────────────────── // 3. Diferenciador — a virada. // Aqui o fundo muda: sai do preto fechado da dor e volta pro --bg-2 com // um glow índigo que cresce conforme a seção entra. O corpo sente a virada // antes do cérebro processar que o argumento mudou. // ───────────────────────────────────────────────────────────── function ViradaGlow({ progress }) { return (
); } function DiferenciadorSection() { const ref = nRefHook(null); const calm = useCalmMotion(); const p = useScrollPass(ref, { trigger: 0.9, span: 0.6 }); // A seção entra com UM lado só: a planilha que o vendedor já conhece. // O lado do Comissa só existe depois que o leitor desce — ele precisa // terminar de sentir o problema antes de receber a resposta, senão a // comparação vira duas caixas lado a lado e ninguém lê a da esquerda. // // O gatilho é medido no grid, não na seção: o `p` da seção começa a contar // com o título ainda entrando, e a essa altura a planilha nem apareceu. // Aqui o lado direito só nasce quando o esquerdo já está no meio da tela. const gridRef = nRefHook(null); // A comparação volta a ter dois tempos, mas agora com folga pra ler: o lado // do Comissa só entra depois que a planilha já passou pelo meio da tela. // Quem desce lê a planilha, sente o erro, e só então a resposta sobe ao lado. // O quadro do Comissa entra antes da metade do percurso: quem chega na seção // deve encontrar a comparação pronta pra ler, não esperar por ela. const pGrid = useScrollPass(gridRef, { trigger: 0.62, span: 0.8 }); const revelado = calm || pGrid >= 0.12; // Os dois lados falam da MESMA venda (Honda Civic, R$ 118.900). Na planilha // ela aparece com a comissão errada e um comentário de quem desconfia; no // Comissa, com o rastro que prova o número. Mesmo caso dos dois lados é o // que faz a comparação morder, em vez de virar duas listas genéricas. const PLANILHA = [ { c: '14', p: 'Curso Trading Pro', v: '2.970,00', com: '891,00' }, { c: '15', p: 'Honda Civic 2024', v: '118.900,00', com: '2.378,00', erro: true }, { c: '16', p: 'Rolex Submariner', v: '89.400,00', com: '2.682,00' }, ]; const RASTRO = [ { t: 'Clique no seu link', carimbo: '14:02 · Fortaleza · Instagram', v: '#a91f' }, { t: 'Checkout na Hotmart', carimbo: '14:09 · cartão 3x', v: 'R$ 118.900' }, { t: 'Pagamento aprovado', carimbo: '14:11 · webhook da plataforma', v: 'confirmado' }, { t: 'Comissão 3% calculada', carimbo: 'na hora, sem ninguém digitar', v: 'R$ 3.567', destaque: true }, ]; return (
A virada

A conta certa em cima do dado errado continua errada.

{/* Três colunas, não duas: a do meio é o conector que desenha quando o lado do Comissa entra. É a virada acontecendo na tela — o único movimento que esta seção se dá o direito de fazer. */}
{/* Antes eram duas listas simétricas de ✗ contra ✓, que é o cartão de comparação que toda landing tem e por isso lê como template. Agora cada lado mostra o ARTEFATO de verdade: aqui, o pedaço de planilha que o vendedor conhece, com a célula divergente e o comentário de quem não confia nela. Concreto vence adjetivo. */}
Hoje, na planilha

Alguém digita, no fim do mês, torcendo pra não ter errado.

Três vendas, três chances de errar. E a linha que sai errada nunca é a do financeiro.

{/* Cabeçalho de planilha de verdade. Sem ele a tabela é uma lista de números; com ele o leitor reconhece o artefato e consegue apontar QUAL célula está errada. */}
# Produto Valor Comissão
{PLANILHA.map((l, i) => (
{l.c} {l.p} {l.v} {l.com}
))}
{/* O prejuízo com nome e valor. A tabela acima já contém a prova (2.378 é 2% de 118.900; a regra do produto é 3%), mas número sozinho não acusa ninguém — esta linha faz a conta pro leitor. */}
Linha 15: a regra é 3%, foi digitado 2%. Faltam {' '} R$ 1.189 nessa venda — e a planilha não vai avisar. Comentário na célula: “esse valor tá certo? confere aí”
{/* O gradiente daqui terminava em rgba(22,19,31,0.9), herança do tema escuro: no tema claro virava um bloco quase preto com texto `--ink` (escuro) por cima, ilegível. Agora é superfície clara com o calor do acento só na borda e no topo. E o conteúdo deixou de ser lista de ✓: é a MESMA venda da planilha ao lado, mostrada como rastro, com carimbo de origem em cada passo. O argumento da seção é "o dado certo", então o lado certo precisa mostrar de onde o dado veio. */} {/* O conector. Risco que desenha da planilha até o Comissa no momento em que o segundo lado entra: a virada acontecendo, não ilustrada. Rosa de um lado, índigo do outro. */}
No Comissa, a mesma venda

Ninguém digita. Cada passo deixa carimbo, e a comissão nasce do rastro.

{RASTRO.map((r, i) => (
{i < RASTRO.length - 1 && ( )}
{r.t}
{r.carimbo}
{r.v}
))}
Mesma venda da planilha ao lado, {' '} R$ 1.189 de diferença — só que aqui cada passo tem carimbo, então o número não depende da palavra de ninguém.
); } // ───────────────────────────────────────────────────────────── // 4. Jornada — 01/02/03. // A linha preenche em índigo→ciano conforme o scroll: o "rastreio" // acontecendo na tela, não uma decoração. O traço pontilhado por trás // segue o cursor de leve (parallax ~12px) — mesma ideia. // ───────────────────────────────────────────────────────────── const ETAPAS = [ { n: '01', t: 'Seu link', d: 'Você gera o link rastreável do produto ou recebe o link já vinculado pela empresa. Cada clique entra identificado, com origem e horário.', code: 'track-click', }, { n: '02', t: 'A venda acontece', d: 'Hotmart, Kiwify, Eduzz, Guru, Cakto, Asaas e outras: a própria plataforma avisa quando o pagamento é aprovado. Você não precisa contar pra ninguém.', code: 'webhook → sale_events', }, { n: '03', t: 'Comissão rastreada', d: 'Ela aparece no painel com origem, valor e status antes mesmo do dinheiro cair. Se for estornada, o mesmo caminho desfaz sozinho.', code: 'resolve_commission', }, ]; function JornadaSection() { const ref = nRefHook(null); const pilhaRef = nRefHook(null); const fill = useScrollPass(pilhaRef, { trigger: 0.12, span: 0.75 }); const calm = useCalmMotion(); return (
Como o dado anda

Do clique ao valor na sua tela, em três passos que rodam sem você.

{/* 900 e não 1120: o card mais longo tem duas linhas de texto, e numa caixa de 1050px de largura elas viram uma faixa fina no meio de um deserto branco. */} {/* O empilhamento é UM elemento grudado com três cards dentro, movidos pelo progresso do scroll — e não três `position: sticky` irmãos. Sticky irmão no mesmo container não se sobrepõe: o navegador empurra o de cima pra fora pra não encostar no de baixo, que é o oposto do que esta seção precisa (a etapa 02 tem que COBRIR a 01, e a 03 a 02). Com um palco só, quem manda é a conta abaixo. */}
{ETAPAS.map((e, i) => { // Cada etapa entra por baixo e para em cima da anterior, deixando // à vista só a faixa superior dela. O passo de 0.42 espalha as // três por quase todo o curso do sticky — com 0.3 tudo terminava // em 60% dele e o resto era rolagem morta. const t = calm ? 1 : Math.max(0, Math.min(1, (fill - (i - 1) * 0.42) / 0.42)); const on = t > 0.6; return (
{/* O nó do trilho. Fica fora do card, encostado na linha, pra ligar visualmente o card ao caminho. */}

{/* O numeral é o único marcador de ordem que sobrou. O rótulo "Etapa 01" repetia exatamente o que este número já dizia, duas vezes na mesma linha. */} {e.n} {e.t}

{/* O carimbo técnico: o nome real da peça que roda esse passo. Vive no canto, como etiqueta de equipamento — é prova de que existe código atrás, não um chip colorido de enfeite no meio do texto. */} {e.code}

{e.d}

); })}

Não é fluxograma de apresentação: é o caminho que o dado percorre de verdade dentro do Comissa. Os três carimbos acima são as três peças que fazem isso rodar.

); } // ───────────────────────────────────────────────────────────── // 5. Marquee de plataformas — loop infinito, pausa no hover. // Quem tem logo próprio usa BrandLogo; o resto entra como monograma // no mesmo formato. Tudo dessaturado até o hover, pra não virar // carnaval de cor no meio de uma página índigo. // ───────────────────────────────────────────────────────────── const PLATAFORMAS = [ { id: 'hotmart', n: 'Hotmart' }, { id: 'kiwify', n: 'Kiwify' }, { id: null, n: 'Eduzz', c: '#F5A623' }, { id: null, n: 'Guru', c: '#00C2A8' }, { id: null, n: 'Cakto', c: '#7C6BFF' }, { id: null, n: 'Monetizze', c: '#00A0DF' }, { id: null, n: 'Ticto', c: '#2563EB' }, { id: 'asaas', n: 'Asaas' }, { id: 'mercadopago', n: 'Mercado Pago' }, { id: null, n: 'Pagar.me', c: '#65A300' }, { id: null, n: 'Stripe', c: '#635BFF' }, { id: 'pix', n: 'Pix' }, ]; function PlatformMark({ p }) { if (p.id) return ; return ( {p.n[0]} ); } // Faixa de plataformas — logo abaixo do hero. // // Era um marquee infinito no MEIO da página, com um rótulo de 11px ("a venda // confirma sozinha em") como única explicação. Duas coisas mudaram: // // • Subiu pro começo. É a prova mais concreta que a página tem — o visitante // que chega pelo anúncio quer saber "funciona com a MINHA plataforma?" // antes de ler qualquer narrativa. Deixar isso na metade da página é // responder tarde. // • Parou de andar. Logo abaixo do hero, texto correndo sozinho disputa // atenção com a headline em vez de sustentá-la — e a barra de progresso do // topo saiu pelo mesmo motivo. Grade estática lê mais rápido que marquee: // dá pra procurar a própria plataforma com o olho parado. // // A frase virou afirmação com explicação ao lado, não rótulo solto: "confirma // sozinha" sem dizer COMO é promessa; com o webhook explicado, é mecanismo. function PlataformasStrip() { return (
Integrações nativas

A venda confirma sozinha.

O webhook oficial da plataforma avisa o Comissa no segundo em que o pagamento é aprovado. A venda entra paga, com o valor, a taxa retida e a sua comissão já calculada — você não digita nada.

{PLATAFORMAS.map((p) => (
{p.n}
))}
); } // ───────────────────────────────────────────────────────────── // 6. Segmentos — cards por ICP, cada um com a dor específica // ───────────────────────────────────────────────────────────── function SegmentosSection() { const segs = [ { icon: , t: 'Representante autônomo', dor: 'Vende por 4 plataformas e não sabe qual pagou o quê.', fix: 'Um painel só, com a origem de cada venda e a data prevista de cada repasse.', }, { icon: , t: 'Corretor de seguros', dor: 'Comissão parcelada por 12 meses e renovação que ninguém lembra.', fix: 'Parcela por parcela no calendário, com a que ainda está em aberto marcada.', }, { icon: , t: 'Corretor de imóveis', dor: 'Uma venda grande, várias mãos: quanto sobra pra você mesmo?', fix: 'Divisão registrada na venda e contrato preenchido com o seu documento.', }, { icon: , t: 'Closer / SDR comissionado', dor: 'A meta muda no meio do mês e o cálculo do variável some.', fix: 'Meta, atingimento e comissão na mesma tela atualizando a cada venda paga.', }, ]; return (
{segs.map((s, i) => (
{s.icon}

{s.t}

{s.dor}

{s.fix}

))}
); } // ───────────────────────────────────────────────────────────── // 7. Custo diário + garantia — sem ancoragem de desconto (isso é curso). // O framing é de custo por dia comparado ao que uma comissão perdida custa. // ───────────────────────────────────────────────────────────── function CustoDiario() { return (
R$ 1,60 por dia

É o que custa o Comissa Pro {' '} R$ 47,90/mês. Uma comissão perdida por falta de rastreio costuma pagar o ano inteiro.

); } function GarantiaSection() { return (
Sem risco

14 dias grátis, sem cartão.

Você entra, conecta uma plataforma e vê a primeira venda chegar sozinha. Se não fizer sentido pro seu dia, você não paga nada — não existe cobrança pra cancelar depois.

{['Sem cartão pra começar', 'Sem fidelidade', 'Cancela em um clique'].map((x) => ( {x} ))}
); } // ───────────────────────────────────────────────────────────── // 8. FAQ — objeção real de configuração e uso, não pergunta de vitrine // ───────────────────────────────────────────────────────────── const FAQ = [ { q: 'Preciso trocar minha plataforma de pagamento?', a: 'Não. Hotmart, Kiwify, Eduzz, Guru, Cakto, Monetizze, Ticto, Asaas, Mercado Pago, Pagar.me e Stripe funcionam do jeito que já estão: você cola a URL de webhook do Comissa no painel da plataforma e pronto. Nada muda pro seu comprador.', }, { q: 'E se eu vender fora de plataforma — Pix na mão, carro, imóvel?', a: 'Aí a venda entra manual, em três campos, e a comissão sai igual. O rastreio por link é pra quem vende online; quem vende de perto usa o mesmo painel de comissão, meta e follow-up sem precisar de link nenhum.', }, { q: 'Quanto tempo pra deixar configurado?', a: 'Cerca de cinco minutos: cadastra o produto, define a regra de comissão (percentual, valor fixo ou por forma de pagamento) e gera o link. A partir daí a venda entra sozinha.', }, { q: 'A empresa em que eu vendo precisa usar o Comissa?', a: 'Não. Você pode usar sozinho e acompanhar a sua comissão. Se a empresa também usar, ela te manda um link único de acesso: você entra já vinculado e os dois lados olham pro mesmo número, sem conferir planilha um do outro.', }, { q: 'E quando a venda é estornada?', a: 'A mesma plataforma que avisou a aprovação avisa o estorno. O Comissa marca a venda como estornada e desfaz a comissão sem você precisar caçar o lançamento pra corrigir na mão.', }, { q: 'Meus dados de venda ficam visíveis pra outra pessoa?', a: 'Cada conta enxerga só o que é dela. Vendedor comissionado vê a própria comissão e o próprio histórico; a empresa vê o time dela. Não existe painel comum entre contas diferentes.', }, ]; function FaqItem({ item, open, onToggle }) { return (
{/* `inert` na resposta fechada: `max-height: 0` com `overflow: hidden` esconde do olho, mas o texto continua na árvore de acessibilidade — um leitor de tela lia as onze respostas seguidas, como se o acordeão estivesse todo aberto. O `aria-expanded` do botão acima já diz o estado; isto faz o conteúdo obedecer. */}

{item.a}

); } function FaqSection() { const [open, setOpen] = nSt(0); return (
{FAQ.map((f, i) => ( setOpen(open === i ? -1 : i)} /> ))}
); } // ───────────────────────────────────────────────────────────── // Versão mobile da mesma narrativa. // Mesmo texto e mesma virada de fundo; o que sai é o que depende de // cursor (parallax) e de duas colunas. O marquee vira dois grupos de // chips estáticos — em tela pequena, logo correndo só atrapalha a leitura. // ───────────────────────────────────────────────────────────── function MobAgitacao() { return (
A mentira

Comissão não é sorte.
Você só foi treinado pra torcer.

Toda vez que o número veio menor, a resposta foi a mesma: o problema é você. Bastava:

{MENTIRAS.map((m) => (
{m.n} {m.t}
{m.d}
))}

E quando a comissão vinha errada, a culpa voltava pra você: {' '} “deve ter anotado errado”.

Uma venda não contada por mês, a 3% de um ticket de {' '} R$ 8.000, são {' '} R$ 2.880 {' '} por ano que você nunca vai cobrar.

Mentiram pra você.
); } function MobProblemaDiagnostico() { const blocos = [ { label: 'Problema', tone: 'muted', t: 'Ninguém rastreia a venda. Todo mundo lança a venda.', d: 'Lançar é memória, e memória falha. Quando falha, quem paga a conta é sempre quem vendeu.' }, { label: 'Diagnóstico', tone: 'cyan', t: 'O erro não está na conta. Está na origem do dado.', d: 'Comissão certa não começa na fórmula — começa no clique que gerou a venda.' }, ]; return (
{blocos.map((b, i) => ( {b.label}

{b.t}

{b.d}

))}
); } function MobDiferenciador() { const ref = nRefHook(null); const p = useScrollPass(ref, { trigger: 0.9, span: 0.6 }); return (
A virada

A conta certa em cima do dado errado continua errada.

A maioria das ferramentas

Calculam em cima do que alguém lançou na mão, no fim do mês, torcendo pra não ter erro.

O Comissa

Rastreia a venda desde o link — clique, plataforma, confirmação de pagamento — e a comissão já nasce calculada certa.

); } function MobJornada() { const ref = nRefHook(null); const fill = useScrollPass(ref, { trigger: 0.75, span: 0.85 }); return (
Como o dado anda

Do clique ao valor na sua tela, em três passos que rodam sem você.

{ETAPAS.map((e, i) => { const on = fill >= (i + 0.15) / ETAPAS.length; return (
{/* Mesmo corte do desktop: o "Etapa 01" repetia o numeral que o marcador do trilho já dá. Aqui sobra o número, discreto, colado no título. */}

{e.n} {e.t}

{e.d}

{e.code}
); })}
); } function MobPlataformas() { return (
{/* Mesma mudança do desktop (ver PlataformasStrip): o rótulo virou afirmação com o mecanismo explicado, e a faixa subiu pra logo depois do hero. */}
Integrações nativas

A venda confirma sozinha.

O webhook oficial avisa o Comissa quando o pagamento é aprovado — a venda entra paga, com taxa e comissão já calculadas.

{PLATAFORMAS.map((p) => ( {p.n} ))}
); } function MobGarantiaFaq() { return (
Sem risco

14 dias grátis, sem cartão.

Se não fizer sentido pro seu dia, você não paga nada — não existe cobrança pra cancelar depois.

{['Sem cartão', 'Sem fidelidade', 'Cancela num clique'].map((x) => ( {x} ))}
Perguntas

O que perguntam antes de assinar.

); } Object.assign(window, { useCalmMotion, useScrollPass, Stagger, NarrLabel, AgitacaoSection, ProblemaDiagnostico, DiferenciadorSection, JornadaSection, PlataformasStrip, SegmentosSection, CustoDiario, GarantiaSection, FaqSection, MobAgitacao, MobProblemaDiagnostico, MobDiferenciador, MobJornada, MobPlataformas, MobGarantiaFaq, });