// shared.jsx — atoms used by all LP variations // Exports to window: Countdown, Ornament, CTAPrimary, GuaranteeBadge, LotTable, // WhatsAppPrint, LogoMark, NathPhoto, useCountdown, PriceBlock, // VagasProgress, FloatingWhatsApp, SectionCTA, IGLink const EVENT_DATE = new Date('2026-06-06T14:00:00-03:00'); // 6 jun 2026, 14h BRT const CHECKOUT_URL = 'https://lastlink.com/p/CFE40E0A2?cp=lote01'; const WHATSAPP_URL = 'https://wa.me/5549999317000'; const IG_URL = 'https://instagram.com/nathaliapriscoo'; const ORIGINAL_PRICE = 197; const LOT_PRICES_MAP = { L0: 19, L1: 29, L2: 59, L3: 99 }; const LOT_PRICE_NEXT = { L0: 29, L1: 59, L2: 99, L3: 99 }; /* ============================================================ COUNTDOWN HOOKS ============================================================ */ function useCountdown(target = EVENT_DATE) { const [now, setNow] = React.useState(() => new Date()); React.useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []); let diff = Math.max(0, target.getTime() - now.getTime()); const d = Math.floor(diff / 86400000); diff -= d * 86400000; const h = Math.floor(diff / 3600000); diff -= h * 3600000; const m = Math.floor(diff / 60000); diff -= m * 60000; const s = Math.floor(diff / 1000); return { d, h, m, s }; } // 24h lot urgency countdown — persists in localStorage, rotates every 24h function use24hLotCountdown() { const KEY = 'm1pct_lot24h_end'; const compute = () => { let end = parseInt(localStorage.getItem(KEY) || '0', 10); const now = Date.now(); if (!end || end < now) { end = now + 24 * 3600 * 1000; localStorage.setItem(KEY, String(end)); } return end; }; const [endTime, setEndTime] = React.useState(compute); const [now, setNow] = React.useState(Date.now()); React.useEffect(() => { const id = setInterval(() => { const t = Date.now(); setNow(t); if (endTime - t <= 0) { const ne = t + 24 * 3600 * 1000; localStorage.setItem(KEY, String(ne)); setEndTime(ne); } }, 1000); return () => clearInterval(id); }, [endTime]); const diff = Math.max(0, endTime - now); const h = Math.floor(diff / 3600000); const m = Math.floor((diff % 3600000) / 60000); const s = Math.floor((diff % 60000) / 1000); return { h, m, s }; } /* ============================================================ COUNTDOWN BANDS ============================================================ */ function Countdown({ compact = false }) { const { d, h, m, s } = useCountdown(); const pad = (n) => String(n).padStart(2, '0'); return (
{compact ? 'Imersão · 6/jun' : 'Começa em'}
{pad(d)}d {pad(h)}h {pad(m)}m {pad(s)}s
); } function Ornament({ heart = false }) { return (
{heart ? : }
); } /* ============================================================ CTA — primary gold button ============================================================ */ function CTAPrimary({ price = 29, label = 'Quero meu lugar na imersão', href = CHECKOUT_URL, sub }) { return (
{label} — R${price} {sub !== false && (
{sub || <>Lote especial · vagas limitadas · garantia 7 dias · pagamento único}
)}
); } /* ============================================================ SECTION CTA — inline CTA at end of long content blocks ============================================================ */ function SectionCTA({ hint, label = 'Quero minha vaga', price = 29 }) { return (
{hint &&
{hint}
} {label} — R${price}
Garantia 7 dias · Acesso imediato
); } /* ============================================================ LOGO MARK — uses uploaded PNG ============================================================ */ function LogoMark({ size = 'sm' }) { const width = size === 'lg' ? 230 : size === 'md' ? 160 : 120; return ( Imersão Mulher 1% ); } function NathPhoto({ src, alt = 'Nathalia Prisco', style, className = 'nath-portrait' }) { return {alt}; } /* ============================================================ LOT TABLE v2 — active lot bigger, hover, no "order bump" subtitle ============================================================ */ function LotTable({ active = 'L1' }) { const lots = [ { id: 'L0', name: 'Lote 0', price: 19, tag: 'Lote zero' }, { id: 'L1', name: 'Lote 1', price: 29, tag: 'Lote especial' }, { id: 'L2', name: 'Lote 2', price: 59, tag: 'Segundo lote' }, { id: 'L3', name: 'Lote 3', price: 99, tag: 'Último lote' }, ]; const activeIdx = lots.findIndex(l => l.id === active); return (
{lots.map((l, i) => { const state = i < activeIdx ? 'sold-out' : i === activeIdx ? 'active' : 'upcoming'; const label = state === 'sold-out' ? 'Esgotado' : state === 'active' ? 'Aberto agora' : 'Em breve'; return (
{label}
{l.name} {state === 'active' && ( Especial )}
{state === 'active' && (
pagamento único · acesso imediato
)}
R${l.price}
); })}
); } /* ============================================================ VAGAS PROGRESS — 87% sold bar with warn label ============================================================ */ function VagasProgress({ percent = 87 }) { return (
{percent}% das vagas preenchidas vagas finais
); } /* ============================================================ PRICE BLOCK — full offer card with countdown ============================================================ */ function PriceBlock({ activeLot = 'L1', label = 'Garantir minha vaga' }) { const price = LOT_PRICES_MAP[activeLot] || 29; const nextPrice = LOT_PRICE_NEXT[activeLot] || 59; const { h, m, s } = use24hLotCountdown(); const pad = (n) => String(n).padStart(2, '0'); return (
Lote especial
Investimento
R${ORIGINAL_PRICE}
R$ {price}
pagamento único · acesso imediato
Imersão ao vivo · 3 horas com Nathalia Prisco
Acesso direto · sem intermediários
Grupo de WhatsApp com o link da aula
Garantia incondicional de 7 dias
{label} — R${price}
100% seguro Acesso imediato Sem cobrança automática
Lote de R${price} vira em:
{pad(h)}horas
{pad(m)}min
{pad(s)}seg
Depois desse prazo, o ingresso sobe para R${nextPrice}
); } /* ============================================================ FLOATING WHATSAPP — bottom right, persistent ============================================================ */ function FloatingWhatsApp() { return ( Falar com o suporte ); } /* ============================================================ GUARANTEE BADGE — uses uploaded image ============================================================ */ function GuaranteeBadge({ width = 200 }) { return ( Garantia incondicional de 7 dias ); } /* ============================================================ IG link ============================================================ */ function IGLink({ children = '@nathaliapriscoo', className = 'ig-link' }) { return {children}; } /* ============================================================ WHATSAPP PRINT — fake testimonial messages ============================================================ */ function WhatsAppPrint({ name, initial, time = '14:32', messages = [] }) { return (
{initial}
{name}
online
{time}
{messages.map((m, i) => (
{m.text} {m.right && ✓✓}
))}
); } const TESTIMONIALS = [ { name: 'Camila R.', initial: 'C', time: '21:14', messages: [ { text: 'Nath… eu chorei na metade da aula.' }, { text: 'Você descreveu exatamente o que eu vivi nos últimos 2 anos. Eu nunca vi ninguém colocar em palavras desse jeito.' }, { text: 'Como você sabia? 😭' }, ]}, { name: 'Júlia M.', initial: 'J', time: '09:47', messages: [ { text: 'Acabei de relacionar tudo que você falou sobre "esperar definição" com a minha história inteira.' }, { text: 'Eu achava que era falta de sorte. Agora entendi que era um padrão meu.' }, { text: 'Tô sem palavras. Obrigada de verdade.' }, ]}, { name: 'Bia S.', initial: 'B', time: '16:02', messages: [ { text: 'Vc é a única que fala sobre isso desse jeito.' }, { text: 'Sem culpar homem, sem culpar mulher. Só explicando o mecanismo.' }, { text: 'Mudou meu jeito de olhar pras coisas em 1 aula.' }, ]}, { name: 'Larissa P.', initial: 'L', time: '22:38', messages: [ { text: 'Acabei a aula de 25 e vim direto te falar:' }, { text: 'Eu parei de me sentir burra. Era exatamente isso que eu precisava entender.' }, { text: 'Tô esperando a imersão de 6 de junho. Já garanti minha vaga ❤️' }, ]}, ]; /* ============================================================ HEADLINE COPY — 3 variations (C is default — provocativo) ============================================================ */ const HEADLINES = { A: { title: <>Ele foi embora. Voltou. Você ficou. E agora está aqui lendo isso., plain: 'Ele foi embora. Voltou. Você ficou. E agora está aqui lendo isso.', kicker: <>Não é coincidência. É padrão. E padrão tem explicação., }, B: { title: <>A Mulher 1% não espera ser escolhida., plain: 'A Mulher 1% não espera ser escolhida.', kicker: <>Ela entende o que a fazia aceitar menos — e para de aceitar., }, C: { title: <>O problema não é que os homens são uma merda., plain: 'O problema não é que os homens são uma merda.', // updated per user request — quoted phrase in destaque kicker: <>O problema é "O que em você continua atraindo esse tipo de canalha.", }, }; // Expose to window Object.assign(window, { EVENT_DATE, CHECKOUT_URL, WHATSAPP_URL, IG_URL, ORIGINAL_PRICE, LOT_PRICES_MAP, useCountdown, use24hLotCountdown, Countdown, Ornament, CTAPrimary, SectionCTA, LogoMark, NathPhoto, LotTable, GuaranteeBadge, WhatsAppPrint, PriceBlock, VagasProgress, FloatingWhatsApp, IGLink, TESTIMONIALS, HEADLINES, });