// Landing.jsx — public showcase landing page for ConstructHub. // Revolut-style relaunch: dark cinematic hero, scroll-driven feature // chapters powered by the live demos in ./demos/, dark AI band, dark // newsletter finale. Madeira-first copy per the 2026-06-11 relaunch spec // (no "ERP" wording, no beta/registration — newsletter is the single CTA). // // i18n: PT (canonical) / EN / ES via the I18N dictionary below and the // switcher in the nav pill. Language persists in localStorage ('ch-lang') // and can be forced with ?lang=en. The product demos stay PT-PT — they // show real Portuguese documents (faturas, NIFs, ATCUD), which is the // honest representation of the product. // // Hosts: showcase.html (design-canvas artboard) and home.html (standalone // full page). Demo components are read from window[name] with a graceful // placeholder, so the page still renders if a demo script isn't loaded. const INDIGO = '#4F6EF7'; const INDIGO_SOFT = '#EEF1FF'; const DISPLAY_FONT = "'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"; const INVITE_EMAIL = 'equipa@constructhub.services'; function mailtoHref({ subject, body }) { return `mailto:${INVITE_EMAIL}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body.join('\r\n'))}`; } // ─── Copy — PT is canonical; EN/ES mirror it ────────────────────────── const I18N = { pt: { nav: { links: [['Produto', '#produto'], ['Assistente IA', '#ia'], ['Planos', '#planos'], ['FAQ', '#faq']], cta: 'Receber novidades' }, hero: { chip: 'Lançamento · outono de 2026 · Madeira primeiro', rotor: ['stock', 'encomendas', 'faturação', 'obras'], h1Pre: 'Gestão de', h1Mid: 'pensada para quem', h1End: 'constrói na Madeira.', sub: <>Stock em tempo real, encomendas sem papel e faturação AT com ATCUD, QR e SAF-T — uma plataforma de gestão feita de raiz para distribuidores e retalhistas de materiais de construção., ctaProduct: 'Ver o produto', ctaNews: 'Receber novidades', trust: ['AT e-fatura', 'SAF-T PT', 'PT · EN · ES', 'RGPD'], frame: 'ConstructHub · Faturação', }, badge: 'demo', numbers: [ { n: 'PT·EN·ES', l: 'disponível em três idiomas' }, { n: '4/12/22', l: 'IVA da Madeira nativo' }, { n: '1 clique', l: 'exportação SAF-T PT' }, { n: '0 €', l: 'para começar, sem cartão' }, ], problem: { kicker: 'O problema', h2: 'Software genérico não percebe o seu negócio.', p1: 'As plataformas internacionais foram desenhadas para vender livros ou software — não cimento, areia ou aço. Não falam com a AT, não exportam SAF-T PT, não percebem IVA reduzido em obras de reabilitação, e tratam um empreiteiro como se fosse um consumidor final.', p2: 'Os sistemas antigos portugueses falam o idioma — mas vivem em janelas Windows dos anos 2000, não funcionam no telemóvel do chefe de obra, e o catálogo é uma folha de Excel.', p3: 'O ConstructHub é uma terceira opção. Uma plataforma de gestão moderna, na nuvem, em PT-PT, feita de raiz para a forma como o sector trabalha — a começar pela Madeira.', }, chaptersIntro: { chip: 'Produto', h2: 'O ConstructHub em ação.', sub: 'Seis demonstrações dos fluxos principais — do orçamento à fatura pronta para a AT. Para o ver com os dados da sua empresa, peça uma demonstração.', cta: 'Pedir uma demonstração', }, chapters: [ { kicker: 'Faturação AT', title: 'Da venda ao ATCUD em segundos.', body: 'E-fatura nativo, sem exportações nem software intermédio. Cada documento sai com série registada na AT, hash imutável e QR — pronto para a AT.', points: ['Séries registadas na AT e hash RSA imutável', 'ATCUD + QR em cada documento', 'SAF-T PT num clique'] }, { kicker: 'Stock multi-armazém', title: 'Stock em que pode confiar.', body: 'Cada movimento fica registado num livro-razão imutável. Transferências entre lojas, armazéns e estaleiros com pedido e aprovação — e visão em tempo real do que existe em cada local.', points: ['Multi-loja, multi-armazém, estaleiros', 'Transferências com pedido e aprovação', 'Movimentos auditáveis, em tempo real'] }, { kicker: 'Fluxo de vendas', title: 'Do orçamento à fatura, sem reescrever.', body: 'Um documento, quatro estados — orçamento, encomenda, guia e fatura. Os dados seguem o negócio; ninguém volta a introduzi-los.', points: ['Orçamento → encomenda → guia → fatura', 'Sem reintroduzir dados em cada passo', 'Margem visível em todas as fases'] }, { kicker: 'Pipeline comercial', title: 'O funil de vendas, à vista de todos.', body: 'Oportunidades arrastam-se entre fases — contagens e totais atualizam ao largar. A equipa comercial sabe sempre o que está em jogo.', points: ['Fases configuráveis por equipa', 'Totais e contagens em tempo real', 'Do contacto à encomenda ganha'] }, { kicker: 'Calendários de obra', title: 'A obra manda no calendário.', body: 'Semanas de trabalho, folgas e feriados regionais — mude o calendário e o agendamento reorganiza as atividades da obra automaticamente.', points: ['Feriados do Continente, Madeira e Açores', 'Agendamento CPM que reage a mudanças', 'Equipas e cargas de trabalho visíveis'] }, { kicker: 'Portal B2B · em desenvolvimento', title: 'Os seus clientes encomendam sozinhos.', body: 'Empreiteiros e construtoras entram no portal, vêem os preços acordados e o stock em tempo real, e encomendam sem um único telefonema.', points: ['Preços por contrato, por cliente', 'Stock em tempo real', 'Histórico e estado das entregas'] }, ], ai: { chip: 'Assistente IA', h2a: 'Pergunte em português.', h2b: 'Ele conhece as suas obras.', sub: 'O assistente tem contexto das suas encomendas, faturas, fornecedores e obras. Pergunte naturalmente. Peça-lhe para agir. Confirma sempre antes de escrever.', frame: 'ConstructHub · Assistente', points: [ { i: 'message-circle-question', t: 'Pergunte qualquer coisa', s: '“Que obra teve mais margem no último trimestre?” “Quem aprovou a EC-0241?”' }, { i: 'wand-2', t: 'Peça acções', s: '“Repete a encomenda do Machico para a próxima semana.” “Compõe email à Tabique sobre o IVA.”' }, { i: 'shield-check', t: 'Privado por padrão', s: 'O assistente vê apenas os módulos que autorizar, definidos por papel.' }, { i: 'check-circle-2', t: 'Confirma antes de escrever', s: 'Encomendas, faturas, emails — o resultado é-lhe sempre apresentado para aprovação.' }, ], }, pricing: { kicker: 'Planos', h2: 'Três planos. Sem surpresas.', sub: <>Os preços finais serão anunciados com o lançamento público, no outono de 2026. Subscreva as novidades e seja o primeiro a saber., price: 'Sob consulta', priceNote: 'A anunciar no lançamento', ctaNews: 'Receber novidades', ctaTalk: 'Falar connosco', recommended: 'Recomendado', footnote: 'Todos os planos incluem AT e-fatura, SAF-T PT, RGPD, suporte em português, actualizações grátis.', plans: [ { name: 'Loja', sub: 'Para uma loja única, equipa pequena.', points: ['Build + Portal', 'Facturação AT', 'Assistente IA — uso básico', 'Suporte por email'] }, { name: 'Distribuidor', sub: 'Multi-armazém, multi-loja.', recommended: true, points: ['Tudo do plano Loja', 'Equipa alargada', 'Multi-armazém', 'Assistente IA — uso intensivo', 'Suporte prioritário'] }, { name: 'Grupo', sub: 'Cadeias e grupos com SLA dedicado.', points: ['Implementação acompanhada', 'Assistente IA dedicado', 'Suporte dedicado', 'SLA contratual'] }, ], }, faq: { kicker: 'Perguntas frequentes', h2: 'Tudo o que precisa de saber.', qs: [ { q: 'Funciona com a Autoridade Tributária?', a: 'Sim. Comunicação directa com a AT — séries, faturas e guias de transporte — com ATCUD e QR em cada documento e SAF-T PT exportável em 1 clique. A certificação de software AT está em curso para o lançamento.' }, { q: 'Posso migrar do Primavera / Sage / PHC?', a: 'A migração é acompanhada pela equipa: importamos catálogo e clientes a partir de Excel durante o onboarding. Ligações directas a Primavera, Sage ou PHC estão no roadmap.' }, { q: 'O assistente IA vê os meus dados?', a: 'Apenas o que autoriza. Pode definir por papel a que módulos o assistente tem acesso — e antes de qualquer alteração, o assistente apresenta-lhe sempre o resultado para aprovação.' }, { q: 'Funciona offline na obra?', a: 'É uma aplicação web leve, pensada para o 3G/4G da obra. O modo offline do Portal está no roadmap.' }, { q: 'Quantos utilizadores posso ter?', a: 'Os limites por plano serão anunciados com os preços, no lançamento. Em todos os planos terá papéis e permissões — admin, comprador, chefe de obra, financeiro.' }, ], }, news: { chip: 'Novidades · lançamento', h2a: 'Avisamos quando', h2b: 'lançarmos.', sub: <>O ConstructHub chega no outono de 2026 — primeiro na Madeira. Deixe o seu email para receber as novidades do produto e a data de lançamento. Sem spam; pode cancelar a qualquer momento., placeholder: 'o-seu@email.pt', button: 'Avisar-me', sending: '…', consent: 'Aceito receber novidades por email (RGPD). Pode cancelar a qualquer momento.', done: 'Verifique o seu email para confirmar a subscrição.', error: 'Verifique o email e o consentimento.', prefer: 'Prefere falar connosco?', book: 'Marcar 30 minutos', }, footer: { tagline: 'A plataforma de gestão para quem vende materiais de construção. Feita na Madeira, em português.', cols: [ { t: 'Produto', items: [['Faturação AT', '#produto'], ['Stock multi-armazém', '#produto'], ['Portal B2B', '#produto'], ['Assistente IA', '#ia'], ['Planos', '#planos']] }, { t: 'Sector', items: [['Distribuidores', '#'], ['Retalhistas', '#'], ['Fabricantes', '#'], ['Empreiteiros', '#'], ['Sucessos', '#']] }, { t: 'Empresa', items: [['Sobre nós', '#'], ['Carreiras', '#'], ['Imprensa', '#'], ['Contacto', '#novidades'], ['Novidades', '#novidades']] }, { t: 'Legal', items: [['Privacidade', '#'], ['Termos', '#'], ['RGPD', '#'], ['Segurança', '#'], ['SAF-T PT', '#']] }, ], copyright: '© 2026 ConstructHub · Madeira, Portugal', status: 'Sistema operacional', }, mail: { demo: { subject: 'ConstructHub · pedido de demonstração', body: ['Olá equipa ConstructHub,', '', 'Gostaria de marcar uma demonstração do produto.', '', 'Nome: ', 'Empresa: ', 'Disponibilidade (datas/horas): ', 'Telefone (opcional): ', '', 'Obrigado.'] }, talk: { subject: 'ConstructHub · marcar 30 minutos', body: ['Olá equipa ConstructHub,', '', 'Gostaria de marcar uma conversa de 30 minutos para conhecer melhor o produto.', '', 'Nome: ', 'Empresa: ', 'Disponibilidade (datas/horas): ', 'Telefone (opcional): ', '', 'Obrigado.'] }, }, }, en: { nav: { links: [['Product', '#produto'], ['AI Assistant', '#ia'], ['Plans', '#planos'], ['FAQ', '#faq']], cta: 'Get updates' }, hero: { chip: 'Launching · autumn 2026 · Madeira first', rotor: ['stock', 'orders', 'invoicing', 'projects'], h1Pre: 'Managing', h1Mid: 'built for those who', h1End: 'build in Madeira.', sub: <>Real-time stock, paperless ordering and AT invoicing with ATCUD, QR and SAF-T — a management platform built from scratch for construction-material distributors and retailers., ctaProduct: 'See the product', ctaNews: 'Get updates', trust: ['AT e-fatura', 'SAF-T PT', 'PT · EN · ES', 'GDPR'], frame: 'ConstructHub · Invoicing', }, badge: 'demo', numbers: [ { n: 'PT·EN·ES', l: 'available in three languages' }, { n: '4/12/22', l: 'native Madeira VAT rates' }, { n: '1 click', l: 'SAF-T PT export' }, { n: '€0', l: 'to get started, no card' }, ], problem: { kicker: 'The problem', h2: 'Generic software doesn’t understand your business.', p1: 'International platforms were designed to sell books or software — not cement, sand or steel. They don’t talk to the Portuguese tax authority (AT), don’t export SAF-T PT, don’t understand reduced VAT on renovation work, and treat a contractor like a retail consumer.', p2: 'The legacy Portuguese systems speak the language — but they live in Windows-2000-era screens, don’t work on a site manager’s phone, and the catalogue is an Excel sheet.', p3: 'ConstructHub is a third option. A modern, cloud-based management platform in European Portuguese, built from scratch for how the sector works — starting in Madeira.', }, chaptersIntro: { chip: 'Product', h2: 'ConstructHub in action.', sub: 'Six demos of the core flows — from quote to AT-ready invoice. To see it with your company’s data, request a demo.', cta: 'Request a demo', }, chapters: [ { kicker: 'AT invoicing', title: 'From sale to ATCUD in seconds.', body: 'Native e-fatura — no exports, no middleware. Every document ships with an AT-registered series, immutable hash and QR code, ready for the tax authority.', points: ['AT-registered series with immutable RSA hash', 'ATCUD + QR on every document', 'SAF-T PT in one click'] }, { kicker: 'Multi-warehouse stock', title: 'Stock you can trust.', body: 'Every movement is recorded in an immutable ledger. Transfers between stores, warehouses and site yards with request and approval — and a live view of what’s where.', points: ['Multi-store, multi-warehouse, site yards', 'Transfers with request and approval', 'Auditable movements, in real time'] }, { kicker: 'Sales flow', title: 'From quote to invoice, nothing retyped.', body: 'One document, four states — quote, order, delivery note, invoice. The data follows the deal; nobody enters it twice.', points: ['Quote → order → delivery note → invoice', 'No re-entering data at any step', 'Margin visible at every stage'] }, { kicker: 'Sales pipeline', title: 'The sales funnel, visible to everyone.', body: 'Drag opportunities between stages — counts and totals update on drop. The sales team always knows what’s in play.', points: ['Stages configurable per team', 'Live totals and counts', 'From first contact to won order'] }, { kicker: 'Project calendars', title: 'The job site sets the schedule.', body: 'Working weeks, days off and regional holidays — change the calendar and the schedule reorganises the project’s activities automatically.', points: ['Mainland, Madeira and Azores holidays', 'CPM scheduling that reacts to change', 'Teams and workloads at a glance'] }, { kicker: 'B2B portal · in development', title: 'Your customers order by themselves.', body: 'Contractors and builders log into the portal, see their agreed prices and live stock, and place orders without a single phone call.', points: ['Contract pricing per customer', 'Real-time stock', 'Order history and delivery status'] }, ], ai: { chip: 'AI Assistant', h2a: 'Ask in plain language.', h2b: 'It knows your projects.', sub: 'The assistant has context on your orders, invoices, suppliers and projects. Ask naturally. Ask it to act. It always confirms before writing anything.', frame: 'ConstructHub · Assistant', points: [ { i: 'message-circle-question', t: 'Ask anything', s: '“Which project had the best margin last quarter?” “Who approved EC-0241?”' }, { i: 'wand-2', t: 'Ask for actions', s: '“Repeat the Machico order for next week.” “Draft an email to Tabique about the VAT.”' }, { i: 'shield-check', t: 'Private by default', s: 'The assistant only sees the modules you authorise, defined per role.' }, { i: 'check-circle-2', t: 'Confirms before writing', s: 'Orders, invoices, emails — the result is always shown to you for approval first.' }, ], }, pricing: { kicker: 'Plans', h2: 'Three plans. No surprises.', sub: <>Final pricing will be announced at the public launch, in autumn 2026. Subscribe to updates and be the first to know., price: 'On request', priceNote: 'Announced at launch', ctaNews: 'Get updates', ctaTalk: 'Talk to us', recommended: 'Recommended', footnote: 'All plans include AT e-fatura, SAF-T PT, GDPR, support in Portuguese, free updates.', plans: [ { name: 'Store', sub: 'For a single store, small team.', points: ['Build + Portal', 'AT invoicing', 'AI Assistant — basic usage', 'Email support'] }, { name: 'Distributor', sub: 'Multi-warehouse, multi-store.', recommended: true, points: ['Everything in Store', 'Larger team', 'Multi-warehouse', 'AI Assistant — heavy usage', 'Priority support'] }, { name: 'Group', sub: 'Chains and groups with a dedicated SLA.', points: ['Guided implementation', 'Dedicated AI Assistant', 'Dedicated support', 'Contractual SLA'] }, ], }, faq: { kicker: 'Frequently asked questions', h2: 'Everything you need to know.', qs: [ { q: 'Does it work with the Portuguese tax authority (AT)?', a: 'Yes. Direct communication with the AT — series, invoices and transport documents — with ATCUD and QR on every document and SAF-T PT exportable in one click. AT software certification is underway for launch.' }, { q: 'Can I migrate from Primavera / Sage / PHC?', a: 'Migration is guided by our team: we import your catalogue and customers from Excel during onboarding. Direct connections to Primavera, Sage or PHC are on the roadmap.' }, { q: 'Does the AI assistant see my data?', a: 'Only what you authorise. You can define per role which modules the assistant can access — and before any change, the assistant always shows you the result for approval.' }, { q: 'Does it work offline on site?', a: 'It’s a lightweight web app, built for the 3G/4G you get on site. Offline mode for the Portal is on the roadmap.' }, { q: 'How many users can I have?', a: 'Per-plan limits will be announced with pricing at launch. Every plan includes roles and permissions — admin, buyer, site manager, finance.' }, ], }, news: { chip: 'Updates · launch', h2a: 'We’ll let you know', h2b: 'when we launch.', sub: <>ConstructHub arrives in autumn 2026 — Madeira first. Leave your email to get product updates and the launch date. No spam; unsubscribe anytime., placeholder: 'your@email.com', button: 'Notify me', sending: '…', consent: 'I agree to receive updates by email (GDPR). You can unsubscribe at any time.', done: 'Check your inbox to confirm the subscription.', error: 'Please check the email and the consent box.', prefer: 'Prefer to talk to us?', book: 'Book 30 minutes', }, footer: { tagline: 'The management platform for construction-material sellers. Made in Madeira, in Portuguese.', cols: [ { t: 'Product', items: [['AT invoicing', '#produto'], ['Multi-warehouse stock', '#produto'], ['B2B portal', '#produto'], ['AI Assistant', '#ia'], ['Plans', '#planos']] }, { t: 'Sector', items: [['Distributors', '#'], ['Retailers', '#'], ['Manufacturers', '#'], ['Contractors', '#'], ['Stories', '#']] }, { t: 'Company', items: [['About us', '#'], ['Careers', '#'], ['Press', '#'], ['Contact', '#novidades'], ['Updates', '#novidades']] }, { t: 'Legal', items: [['Privacy', '#'], ['Terms', '#'], ['GDPR', '#'], ['Security', '#'], ['SAF-T PT', '#']] }, ], copyright: '© 2026 ConstructHub · Madeira, Portugal', status: 'All systems operational', }, mail: { demo: { subject: 'ConstructHub · demo request', body: ['Hello ConstructHub team,', '', 'I would like to book a product demo.', '', 'Name: ', 'Company: ', 'Availability (dates/times): ', 'Phone (optional): ', '', 'Thank you.'] }, talk: { subject: 'ConstructHub · book 30 minutes', body: ['Hello ConstructHub team,', '', 'I would like to book a 30-minute call to learn more about the product.', '', 'Name: ', 'Company: ', 'Availability (dates/times): ', 'Phone (optional): ', '', 'Thank you.'] }, }, }, es: { nav: { links: [['Producto', '#produto'], ['Asistente IA', '#ia'], ['Planes', '#planos'], ['FAQ', '#faq']], cta: 'Recibir novedades' }, hero: { chip: 'Lanzamiento · otoño de 2026 · Madeira primero', rotor: ['stock', 'pedidos', 'facturación', 'obras'], h1Pre: 'Gestión de', h1Mid: 'pensada para quien', h1End: 'construye en Madeira.', sub: <>Stock en tiempo real, pedidos sin papel y facturación AT con ATCUD, QR y SAF-T — una plataforma de gestión hecha desde cero para distribuidores y minoristas de materiales de construcción., ctaProduct: 'Ver el producto', ctaNews: 'Recibir novedades', trust: ['AT e-fatura', 'SAF-T PT', 'PT · EN · ES', 'RGPD'], frame: 'ConstructHub · Facturación', }, badge: 'demo', numbers: [ { n: 'PT·EN·ES', l: 'disponible en tres idiomas' }, { n: '4/12/22', l: 'IVA de Madeira nativo' }, { n: '1 clic', l: 'exportación SAF-T PT' }, { n: '0 €', l: 'para empezar, sin tarjeta' }, ], problem: { kicker: 'El problema', h2: 'El software genérico no entiende su negocio.', p1: 'Las plataformas internacionales fueron diseñadas para vender libros o software — no cemento, arena o acero. No hablan con la agencia tributaria portuguesa (AT), no exportan SAF-T PT, no entienden el IVA reducido en obras de rehabilitación, y tratan a un contratista como si fuera un consumidor final.', p2: 'Los sistemas portugueses antiguos hablan el idioma — pero viven en ventanas de Windows de los años 2000, no funcionan en el móvil del jefe de obra, y el catálogo es una hoja de Excel.', p3: 'ConstructHub es una tercera opción. Una plataforma de gestión moderna, en la nube, hecha desde cero para la forma en que trabaja el sector — empezando por Madeira.', }, chaptersIntro: { chip: 'Producto', h2: 'ConstructHub en acción.', sub: 'Seis demostraciones de los flujos principales — del presupuesto a la factura lista para la AT. Para verlo con los datos de su empresa, pida una demostración.', cta: 'Pedir una demostración', }, chapters: [ { kicker: 'Facturación AT', title: 'De la venta al ATCUD en segundos.', body: 'E-fatura nativo, sin exportaciones ni software intermedio. Cada documento sale con serie registrada en la AT, hash inmutable y QR — listo para la AT.', points: ['Series registradas en la AT y hash RSA inmutable', 'ATCUD + QR en cada documento', 'SAF-T PT en un clic'] }, { kicker: 'Stock multi-almacén', title: 'Stock fiable.', body: 'Cada movimiento queda registrado en un libro mayor inmutable. Transferencias entre tiendas, almacenes y obras con solicitud y aprobación — y visión en tiempo real de lo que hay en cada sitio.', points: ['Multi-tienda, multi-almacén, obras', 'Transferencias con solicitud y aprobación', 'Movimientos auditables, en tiempo real'] }, { kicker: 'Flujo de ventas', title: 'Del presupuesto a la factura, sin reescribir.', body: 'Un documento, cuatro estados — presupuesto, pedido, albarán y factura. Los datos siguen al negocio; nadie vuelve a introducirlos.', points: ['Presupuesto → pedido → albarán → factura', 'Sin reintroducir datos en cada paso', 'Margen visible en todas las fases'] }, { kicker: 'Pipeline comercial', title: 'El embudo de ventas, a la vista de todos.', body: 'Las oportunidades se arrastran entre fases — los recuentos y totales se actualizan al soltar. El equipo comercial siempre sabe qué está en juego.', points: ['Fases configurables por equipo', 'Totales y recuentos en tiempo real', 'Del contacto al pedido ganado'] }, { kicker: 'Calendarios de obra', title: 'La obra manda en el calendario.', body: 'Semanas de trabajo, descansos y festivos regionales — cambie el calendario y la planificación reorganiza las actividades de la obra automáticamente.', points: ['Festivos del continente, Madeira y Azores', 'Planificación CPM que reacciona a los cambios', 'Equipos y cargas de trabajo visibles'] }, { kicker: 'Portal B2B · en desarrollo', title: 'Sus clientes piden solos.', body: 'Contratistas y constructoras entran en el portal, ven los precios acordados y el stock en tiempo real, y hacen pedidos sin una sola llamada.', points: ['Precios por contrato, por cliente', 'Stock en tiempo real', 'Histórico y estado de las entregas'] }, ], ai: { chip: 'Asistente IA', h2a: 'Pregunte con naturalidad.', h2b: 'Conoce sus obras.', sub: 'El asistente tiene contexto de sus pedidos, facturas, proveedores y obras. Pregunte con naturalidad. Pídale que actúe. Siempre confirma antes de escribir.', frame: 'ConstructHub · Asistente', points: [ { i: 'message-circle-question', t: 'Pregunte cualquier cosa', s: '“¿Qué obra tuvo más margen el último trimestre?” “¿Quién aprobó la EC-0241?”' }, { i: 'wand-2', t: 'Pida acciones', s: '“Repite el pedido de Machico para la próxima semana.” “Redacta un email a Tabique sobre el IVA.”' }, { i: 'shield-check', t: 'Privado por defecto', s: 'El asistente solo ve los módulos que usted autorice, definidos por rol.' }, { i: 'check-circle-2', t: 'Confirma antes de escribir', s: 'Pedidos, facturas, emails — el resultado siempre se le presenta para su aprobación.' }, ], }, pricing: { kicker: 'Planes', h2: 'Tres planes. Sin sorpresas.', sub: <>Los precios finales se anunciarán con el lanzamiento público, en otoño de 2026. Suscríbase a las novedades y sea el primero en saberlo., price: 'A consultar', priceNote: 'Se anunciará en el lanzamiento', ctaNews: 'Recibir novedades', ctaTalk: 'Hablar con nosotros', recommended: 'Recomendado', footnote: 'Todos los planes incluyen AT e-fatura, SAF-T PT, RGPD, soporte en portugués y actualizaciones gratis.', plans: [ { name: 'Tienda', sub: 'Para una tienda única, equipo pequeño.', points: ['Build + Portal', 'Facturación AT', 'Asistente IA — uso básico', 'Soporte por email'] }, { name: 'Distribuidor', sub: 'Multi-almacén, multi-tienda.', recommended: true, points: ['Todo lo del plan Tienda', 'Equipo ampliado', 'Multi-almacén', 'Asistente IA — uso intensivo', 'Soporte prioritario'] }, { name: 'Grupo', sub: 'Cadenas y grupos con SLA dedicado.', points: ['Implantación acompañada', 'Asistente IA dedicado', 'Soporte dedicado', 'SLA contractual'] }, ], }, faq: { kicker: 'Preguntas frecuentes', h2: 'Todo lo que necesita saber.', qs: [ { q: '¿Funciona con la agencia tributaria portuguesa (AT)?', a: 'Sí. Comunicación directa con la AT — series, facturas y documentos de transporte — con ATCUD y QR en cada documento y SAF-T PT exportable en un clic. La certificación de software AT está en curso para el lanzamiento.' }, { q: '¿Puedo migrar desde Primavera / Sage / PHC?', a: 'La migración la acompaña nuestro equipo: importamos el catálogo y los clientes desde Excel durante el onboarding. Las conexiones directas a Primavera, Sage o PHC están en el roadmap.' }, { q: '¿El asistente IA ve mis datos?', a: 'Solo lo que usted autorice. Puede definir por rol a qué módulos accede el asistente — y antes de cualquier cambio, el asistente siempre le presenta el resultado para su aprobación.' }, { q: '¿Funciona sin conexión en la obra?', a: 'Es una aplicación web ligera, pensada para el 3G/4G de la obra. El modo sin conexión del Portal está en el roadmap.' }, { q: '¿Cuántos usuarios puedo tener?', a: 'Los límites por plan se anunciarán con los precios, en el lanzamiento. Todos los planes incluyen roles y permisos — admin, comprador, jefe de obra, financiero.' }, ], }, news: { chip: 'Novedades · lanzamiento', h2a: 'Le avisamos cuando', h2b: 'lancemos.', sub: <>ConstructHub llega en otoño de 2026 — primero en Madeira. Deje su email para recibir las novedades del producto y la fecha de lanzamiento. Sin spam; puede cancelar en cualquier momento., placeholder: 'su@email.es', button: 'Avisarme', sending: '…', consent: 'Acepto recibir novedades por email (RGPD). Puede cancelar en cualquier momento.', done: 'Revise su email para confirmar la suscripción.', error: 'Compruebe el email y el consentimiento.', prefer: '¿Prefiere hablar con nosotros?', book: 'Reservar 30 minutos', }, footer: { tagline: 'La plataforma de gestión para quien vende materiales de construcción. Hecha en Madeira, en portugués.', cols: [ { t: 'Producto', items: [['Facturación AT', '#produto'], ['Stock multi-almacén', '#produto'], ['Portal B2B', '#produto'], ['Asistente IA', '#ia'], ['Planes', '#planos']] }, { t: 'Sector', items: [['Distribuidores', '#'], ['Minoristas', '#'], ['Fabricantes', '#'], ['Contratistas', '#'], ['Casos', '#']] }, { t: 'Empresa', items: [['Sobre nosotros', '#'], ['Empleo', '#'], ['Prensa', '#'], ['Contacto', '#novidades'], ['Novedades', '#novidades']] }, { t: 'Legal', items: [['Privacidad', '#'], ['Términos', '#'], ['RGPD', '#'], ['Seguridad', '#'], ['SAF-T PT', '#']] }, ], copyright: '© 2026 ConstructHub · Madeira, Portugal', status: 'Sistema en funcionamiento', }, mail: { demo: { subject: 'ConstructHub · solicitud de demostración', body: ['Hola equipo de ConstructHub,', '', 'Me gustaría reservar una demostración del producto.', '', 'Nombre: ', 'Empresa: ', 'Disponibilidad (fechas/horas): ', 'Teléfono (opcional): ', '', 'Gracias.'] }, talk: { subject: 'ConstructHub · reservar 30 minutos', body: ['Hola equipo de ConstructHub,', '', 'Me gustaría reservar una llamada de 30 minutos para conocer mejor el producto.', '', 'Nombre: ', 'Empresa: ', 'Disponibilidad (fechas/horas): ', 'Teléfono (opcional): ', '', 'Gracias.'] }, }, }, }; const LANGS = ['pt', 'en', 'es']; const HTML_LANG = { pt: 'pt-PT', en: 'en', es: 'es' }; const LangCtx = React.createContext({ lang: 'pt', t: I18N.pt, setLang: () => {} }); function useT() { return React.useContext(LangCtx); } function initialLang() { try { const q = new URLSearchParams(window.location.search).get('lang'); if (q && LANGS.includes(q)) return q; const saved = window.localStorage.getItem('ch-lang'); if (saved && LANGS.includes(saved)) return saved; } catch (_) { /* sandboxed iframe etc. */ } return 'pt'; } // ─── Page-scoped CSS ────────────────────────────────────────────────── // Lives inside the component tree so every host (artboard or full page) // gets the motion primitives — including the demo-* keyframes the ./demos // components require — without editing the host's . function LandingStyles() { return ( ); } // ─── Motion helpers ─────────────────────────────────────────────────── // Adds .ch-on when the element enters the viewport (once). Children get // the .ch-reveal class; `delay` staggers via transition-delay. function Reveal({ as = 'div', className = '', delay = 0, children, ...rest }) { const ref = React.useRef(null); React.useEffect(() => { const el = ref.current; if (!el) return; if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { el.classList.add('ch-on'); return; } const io = new IntersectionObserver(([e]) => { if (!e.isIntersecting) return; io.disconnect(); el.classList.add('ch-on'); }, { threshold: 0.15 }); io.observe(el); return () => io.disconnect(); }, []); return React.createElement(as, { ref, className: 'ch-reveal ' + className, style: delay ? { transitionDelay: delay + 'ms' } : undefined, ...rest, }, children); } // Counts from 0 when scrolled into view; honours prefers-reduced-motion. function CountUp({ to, render, duration = 1400 }) { const ref = React.useRef(null); const [val, setVal] = React.useState(0); React.useEffect(() => { const el = ref.current; if (!el) return; if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { setVal(to); return; } const io = new IntersectionObserver(([e]) => { if (!e.isIntersecting) return; io.disconnect(); const t0 = performance.now(); const tick = (t) => { const p = Math.min(1, (t - t0) / duration); setVal(Math.round(to * (1 - Math.pow(1 - p, 3)))); if (p < 1) requestAnimationFrame(tick); }; requestAnimationFrame(tick); }, { threshold: 0.4 }); io.observe(el); return () => io.disconnect(); }, [to, duration]); return {render(val)}; } // Vertically rotating word for the hero H1. function RotorWord({ words, interval = 2600 }) { const [i, setI] = React.useState(0); React.useEffect(() => { setI(0); // restart cleanly when the language (word list) changes if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; const id = setInterval(() => setI((v) => (v + 1) % words.length), interval); return () => clearInterval(id); }, [words, interval]); return ( {words.map((w, k) => ( {w} ))} ); } // Live demo from ./demos, read off window with a graceful placeholder. function LiveDemo({ name }) { const C = window[name]; if (typeof C !== 'function') { return (
demo «{name}» não carregada
); } return ; } // Browser-style frame around a demo, with the "demo" badge. function DemoFrame({ title, name, badge }) { return (
{title} {badge}
); } // ─── Floating nav pill (with language switcher) ─────────────────────── function LangSwitch() { const { lang, setLang } = useT(); return (
{LANGS.map((l) => ( ))}
); } function NavPill() { const { t } = useT(); return (
); } // ─── Hero — dark, cinematic, with the live invoice demo ────────────── function HeroDark() { const { t } = useT(); return (
{/* blueprint grid */} {/* drifting glows */}
{/* Copy */}
{t.hero.chip}

{t.hero.h1Pre}{' '}
{' '} {t.hero.h1Mid}{' '} {t.hero.h1End}

{t.hero.sub}

{[['shield-check', t.hero.trust[0]], ['file-text', t.hero.trust[1]], ['languages', t.hero.trust[2]], ['lock', t.hero.trust[3]]].map(([icon, label]) => ( {label} ))}
{/* Live invoice demo, floating */}
); } // ─── Numbers strip (counts up on scroll) ────────────────────────────── function Numbers() { const { t } = useT(); return (
{t.numbers.map((s, i) => (
{s.to ? : s.n}
{s.l}
))}
); } // ─── Problem ────────────────────────────────────────────────────────── function Problem() { const { t } = useT(); return (
{t.problem.kicker}

{t.problem.h2}

{t.problem.p1}

{t.problem.p2}

{t.problem.p3}

); } // ─── Feature chapters — one live demo per section ───────────────────── // Structural metadata; copy comes from t.chapters (same order). const CHAPTER_META = [ { n: '01', demo: 'DemoFatura', icon: 'shield-check' }, { n: '02', demo: 'DemoStock', icon: 'sparkles', flip: true }, { n: '03', demo: 'DemoVendas', icon: 'arrow-right-left' }, { n: '04', demo: 'DemoKanban', icon: 'kanban', flip: true }, { n: '05', demo: 'DemoCalendar', icon: 'calendar-days' }, { n: '06', demo: 'DemoPortal', icon: 'building-2', flip: true }, ]; function Chapter({ meta, c, badge, first }) { return (
{/* ghost chapter number */}
{/* Copy */}
{meta.n} {c.kicker}

{c.title}

{c.body}

    {c.points.map((pt) => (
  • {pt}
  • ))}
{/* Live demo */}
); } function Chapters() { const { t } = useT(); return (
{t.chaptersIntro.chip}

{t.chaptersIntro.h2}

{t.chaptersIntro.sub}

{CHAPTER_META.map((meta, i) => ( ))}
); } // ─── AI band — dark spotlight with the live chat demo ───────────────── function AIBand() { const { t } = useT(); return (
{t.ai.chip}

{t.ai.h2a}
{t.ai.h2b}

{t.ai.sub}

{t.ai.points.map((p, k) => (
{p.t}
{p.s}
))}
); } // ─── Pricing tease ──────────────────────────────────────────────────── function Pricing() { const { t } = useT(); return (
{t.pricing.kicker}

{t.pricing.h2}

{t.pricing.sub}

{t.pricing.plans.map((p, i) => ( {p.recommended && ( {t.pricing.recommended} )}
{p.name}
{p.sub}
{t.pricing.price}
{t.pricing.priceNote}
{i === 2 ? t.pricing.ctaTalk : t.pricing.ctaNews}
    {p.points.map((pt) => (
  • {pt}
  • ))}
))}
{t.pricing.footnote}
); } // ─── FAQ ────────────────────────────────────────────────────────────── function FAQ() { const { t } = useT(); return (
{t.faq.kicker}

{t.faq.h2}

{t.faq.qs.map((it, i) => (
{it.q}

{it.a}

))}
); } // ─── Newsletter finale — the page's single conversion point ─────────── // POSTs to /api/newsletter (same backend as the Madeira relaunch); // honeypot + RGPD consent kept. API base read from the optional // so previews can point elsewhere. function NewsletterForm() { const { t } = useT(); const [email, setEmail] = React.useState(''); const [consent, setConsent] = React.useState(false); const [hp, setHp] = React.useState(''); const [state, setState] = React.useState('idle'); // idle | sending | done | error async function submit(e) { e.preventDefault(); setState('sending'); try { const m = document.querySelector('meta[name="showcase-api-base"]'); const base = (m && m.content) || ''; const res = await fetch(base + '/api/newsletter', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, consent, hp }), }); setState(res.ok ? 'done' : 'error'); } catch (_) { setState('error'); } } if (state === 'done') { return (
{t.news.done}
); } return (
setEmail(e.target.value)} className="flex-1 h-10 px-4 rounded-full bg-transparent text-[14px] text-white placeholder-white/35 outline-none min-w-0" />
setHp(e.target.value)} style={{ position: 'absolute', left: '-9999px' }} aria-hidden="true" /> {state === 'error' &&
{t.news.error}
}
); } function NewsletterFinale() { const { t } = useT(); return (
{t.news.chip}

{t.news.h2a}
{t.news.h2b}

{t.news.sub}

{t.news.prefer} {t.news.book}
); } // ─── Footer ─────────────────────────────────────────────────────────── function Footer() { const { t, lang, setLang } = useT(); return ( ); } // ─── Page ───────────────────────────────────────────────────────────── function LandingPage() { const [lang, setLangState] = React.useState(initialLang); const setLang = React.useCallback((l) => { if (!LANGS.includes(l)) return; setLangState(l); try { window.localStorage.setItem('ch-lang', l); } catch (_) {} }, []); React.useEffect(() => { document.documentElement.lang = HTML_LANG[lang]; // The ./demos components read this on every animation tick, so they // re-present in the selected language without remounting. window.__DEMO_LANG = lang; }, [lang]); const ctx = React.useMemo(() => ({ lang, t: I18N[lang], setLang }), [lang, setLang]); return (
); } Object.assign(window, { LandingPage });