// prumo-ui.jsx — componentes base da landing (nav, botões, badges, ícones, footer, reveal) const Logo = ({size=19}) => ( {/* marca oficial do Prumo: fio de prumo (var(--text)) + losango (var(--accent)). Geometria idêntica ao brand/Mark_Symbol.svg, mas inline para acompanhar tema e acento. */} Prumo ); const Btn = ({children, variant='primary', lg=false, href='#', onClick, style={}, className=''}) => ( {children} ); const Badge = ({children, tone=''}) => {children}; const Eyebrow = ({children}) =>
{children}
; // ---- minimal line icons (simple strokes only) ---- const I = { grid: "M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z", rocket: "M12 3c3 1.5 5 4.5 5 8l-3 3-4 0-3-3c0-3.5 2-6.5 5-8zM12 8.5h.01M9 16l-2 4M15 16l2 4", receipt:"M6 3h12v18l-2-1.4L14 21l-2-1.4L10 21l-2-1.4L6 21zM9 8h6M9 12h6", folder: "M3 6h6l2 2h10v11H3zM3 8h18", calendar:"M4 5h16v15H4zM4 9h16M8 3v4M16 3v4", building:"M5 21V5l7-2 7 2v16M5 21h14M9 9h.01M9 13h.01M9 17h.01M15 9h.01M15 13h.01M15 17h.01", users: "M16 19v-1a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v1M9.5 10.5a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM21 19v-1a4 4 0 0 0-3-3.8M16 4.7a3 3 0 0 1 0 5.8", team: "M9 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM3 20a6 6 0 0 1 12 0M17 11a3 3 0 1 0-2-5.2M21 20a5.5 5.5 0 0 0-5-5", chart: "M4 4v16h16M8 16v-4M12 16V9M16 16v-7M20 16v-2", wallet: "M3 7h15a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h11M16 13h.01", gear: "M12 9.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM19 12a7 7 0 0 0-.1-1.2l2-1.5-2-3.4-2.3.9a7 7 0 0 0-2-1.2l-.4-2.5H8.8l-.4 2.5a7 7 0 0 0-2 1.2l-2.3-.9-2 3.4 2 1.5A7 7 0 0 0 4 12c0 .4 0 .8.1 1.2l-2 1.5 2 3.4 2.3-.9a7 7 0 0 0 2 1.2l.4 2.5h6.4l.4-2.5a7 7 0 0 0 2-1.2l2.3.9 2-3.4-2-1.5c.1-.4.1-.8.1-1.2z", check: "M4 12.5l5 5 11-12", arrow: "M5 12h14M13 6l6 6-6 6", spark: "M12 3v6M12 15v6M3 12h6M15 12h6M6 6l3 3M15 15l3 3M18 6l-3 3M9 15l-3 3", layers: "M12 3l9 5-9 5-9-5zM3 13l9 5 9-5M3 17l9 5 9-5", }; const Icon = ({name, size=20, style={}}) => ( ); // ---- screenshot real do produto ---- // Substitui os mockups desenhados em
: as imagens em img/ são capturas do // app rodando com dados fictícios (Estúdio Lumen). width/height são os pixels // reais do arquivo — sem eles a página reflui quando a imagem carrega (CLS). // `priority` marca a imagem do hero, que é o LCP da página. function Shot({src, alt, width, height, priority=false, style={}}){ return (
{/* fetchpriority em minúsculo: o React 18 não reconhece a forma camelCase e emite warning no console. */} {alt}
); } // ---- waitlist: captura de beta testers (lista de espera / newsletter) ---- // Ainda não estamos abertos ao público — todo CTA de "começar" cai aqui em vez // de ir pro app, até o produto sair do beta fechado. const WAITLIST_ENDPOINT = 'https://api.prumotech.com/api/waitlist'; // Botão que abre o modal de lista de espera. `source` identifica o botão/página // de origem (ex: "hero", "pricing_escritorio") pra dar contexto no futuro CRM. function WaitlistBtn({children, source, ...props}){ const openModal = (e)=>{ e.preventDefault(); window.dispatchEvent(new CustomEvent('prumo:waitlist-open',{detail:{source}})); }; return {children}; } // Campo com rótulo acima do input. O placeholder some quando o usuário digita, // então ele nunca é o único rótulo — leitor de tela e usuário vidente precisam // dos dois. function Field({id, label, hint, ...inputProps}){ return (
); } // Modal de captura — ouve o evento global 'prumo:waitlist-open' disparado por // qualquer WaitlistBtn da página. Renderizado uma única vez dentro do