/* global React, ReactDOM, LunaMascot, PortariaScene */ const { useEffect, useState, useRef, useCallback } = React; /* ─────────────────── Hook: auto-playing timeline ─────────────────── * Plays from 0→1 over `duration` ms. Starts when section becomes visible. * Exposes progress + controls. */ function useTimeline(ref, duration = 26000) { const [progress, setProgress] = useState(0); const [playing, setPlaying] = useState(false); const [hasAutoStarted, setHasAutoStarted] = useState(false); // Auto-start when scrolled into view useEffect(() => { const el = ref.current; if (!el || hasAutoStarted) return; const obs = new IntersectionObserver( (entries) => { entries.forEach((e) => { if (e.isIntersecting && e.intersectionRatio > 0.45 && !hasAutoStarted) { setHasAutoStarted(true); setPlaying(true); } }); }, { threshold: [0, 0.25, 0.5, 0.75, 1] } ); obs.observe(el); return () => obs.disconnect(); }, [ref, hasAutoStarted]); // Animation loop useEffect(() => { if (!playing) return; let cancelled = false; // start so that current progress maps to "now" const startedAt = performance.now() - progress * duration; const tick = (now) => { if (cancelled) return; const elapsed = now - startedAt; if (elapsed >= duration) { setProgress(1); setPlaying(false); return; } setProgress(elapsed / duration); requestAnimationFrame(tick); }; requestAnimationFrame(tick); return () => { cancelled = true; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [playing]); const toggle = useCallback(() => { setPlaying((p) => { if (!p && progress >= 1) setProgress(0); return !p; }); }, [progress]); const restart = useCallback(() => { setProgress(0); setPlaying(true); }, []); const scrubTo = useCallback((t) => { setProgress(Math.max(0, Math.min(1, t))); setPlaying(false); }, []); return { progress, playing, toggle, restart, scrubTo }; } /* ─────────────────── Phase captions ─────────────────── */ const PHASES = [ { from: 0.00, to: 0.10, step: '01 / 06', title: 'Toda portaria começa o dia em silêncio.', sub: 'Um porteiro, uma cancela e uma decisão a cada veículo que chega.' }, { from: 0.10, to: 0.32, step: '02 / 06', title: 'Aí o movimento aperta.', sub: 'Moradores, visitantes, entregas e prestadores chegam ao mesmo tempo. A fila cresce e a decisão tem que ser rápida.' }, { from: 0.32, to: 0.50, step: '03 / 06', title: 'O porteiro sozinho não dá conta.', sub: 'Reconhecer placas, conferir cadastros, atender o interfone — tudo em segundos, com pressão de quem está esperando.' }, { from: 0.50, to: 0.72, step: '04 / 06', title: 'É aí que a Luna chega.', sub: 'Um sistema de visão computacional acoplado à câmera da portaria — sem trocar equipamentos, sem obra.' }, { from: 0.72, to: 0.82, step: '05 / 06', title: 'Câmera conectada ao porteiro.', sub: 'A Luna lê a placa, consulta o cadastro do condomínio e devolve a decisão antes do carro parar de fato.' }, { from: 0.82, to: 1.00, step: '06 / 06', title: 'O fluxo volta — agora com retaguarda.', sub: 'O porteiro continua no comando. A Luna só acelera, sinaliza riscos e registra tudo.' }, ]; function getPhase(p) { return PHASES.find((ph) => p >= ph.from && p < ph.to) || PHASES[PHASES.length - 1]; } /* ─────────────────── Nav ─────────────────── */ function Nav() { return ( ); } /* ─────────────────── Hero ─────────────────── */ function Hero() { return (
Sistema online · v1.4

A IA que fica
ao lado
do porteiro.

A Luna é uma assistente de visão computacional para portarias de condomínio. Ela reconhece o carro antes do interfone tocar e devolve ao porteiro a decisão de abrir, parar ou conferir — em segundos.

Pedir uma demonstração Ver como funciona
≈ 0,4 s por placa · +47 condomínios · 0 obra na portaria
mascote · idle
UNIT-L01
Veja a Luna em ação
); } /* ─────────────────── Cinematic auto-playing scene ─────────────────── */ function Cinematic() { const ref = useRef(null); const { progress, playing, toggle, restart, scrubTo } = useTimeline(ref, 26000); const phase = getPhase(progress); const phaseIdx = PHASES.indexOf(phase); // HUD telemetry that changes with phase const queueLen = (() => { if (progress < 0.10) return 0; if (progress < 0.32) return Math.min(5, Math.floor((progress - 0.10) / 0.045) + 1); if (progress < 0.45) return 5; if (progress < 0.78) return 0; return Math.floor(1 + (Math.sin(progress * 70) + 1)); })(); const avgWait = (() => { if (progress < 0.10) return '0:00'; if (progress < 0.45) return `${Math.floor(lerp(0, 4, (progress - 0.10) / 0.32))}:${String(Math.floor(lerp(0, 58, (progress - 0.10) / 0.32))).padStart(2, '0')}`; if (progress < 0.78) return '—'; return '0:08'; })(); const sysStatus = progress < 0.50 ? 'OFFLINE' : progress < 0.72 ? 'CONECTANDO' : 'ATIVO'; // scrubber click → seek const scrubRef = useRef(null); const handleScrub = (e) => { const r = scrubRef.current.getBoundingClientRect(); const t = (e.clientX - r.left) / r.width; scrubTo(t); }; return (
{/* HUD left */}
setorPORTARIA · NORTE
dataSÁB 21·MAI · 18:42
sistema {sysStatus}
{/* HUD right */}
fila atual: 3 ? '#E74C3C' : queueLen > 0 ? '#f4c34d' : '#5fd29a' }}>{queueLen}
espera média: {avgWait}
câmera-01: 0.72 ? '#5fd29a' : '#E74C3C' }}>{progress > 0.72 ? '◉ rec' : '○ off'}
{/* Caption */}
{phase.step}
{phase.title}
{phase.sub}
{/* Playback controls */}
{PHASES.map((ph, i) => ( = ph.from ? 'passed' : ''}`} style={{ left: `${ph.from * 100}%` }} /> ))}
{String(Math.floor(progress * 26)).padStart(2, '0')}s
); } const lerp = (a, b, t) => a + (b - a) * t; /* ─────────────────── Como funciona ─────────────────── */ function ComoFunciona() { return (
como funciona

Três passos. Zero obra na portaria.

A Luna se conecta à câmera que o condomínio já tem. Em uma manhã, a portaria passa a ler placas, consultar cadastros e sugerir decisões — sem trocar equipamento, sem tirar o porteiro do comando.

01
instalação

Conectamos à câmera existente

Nosso técnico aponta a câmera para a entrada e plugga a Luna ao circuito atual do condomínio. Sem obra, sem cabo novo passando pela laje.

02
cadastro

Carregamos o cadastro do prédio

Placas de moradores, frota de serviço, lista de visitantes recorrentes. A Luna aprende quem é quem em menos de uma semana.

03
rotina

O porteiro segue no comando

A Luna sugere — autorizar, reter para conferência, alertar. O porteiro confirma com um toque. Tudo fica registrado em vídeo e log.

); } /* ─────────────────── Recursos ─────────────────── */ function Recursos() { const items = [ { num: 'F1', title: 'Leitura de placa em tempo real', desc: 'Reconhecimento de placas Mercosul e modelo antigo, mesmo com chuva, sol baixo ou farol aceso.' }, { num: 'F2', title: 'Cadastro vivo de moradores', desc: 'Painel para a administração liberar visitantes, frota fixa e prestadores recorrentes sem ligar para a portaria.' }, { num: 'F3', title: 'Decisão sugerida ao porteiro', desc: 'A tela do porteiro recebe verde, amarelo ou vermelho. A palavra final continua humana.' }, { num: 'F4', title: 'Log auditável de cada entrada', desc: 'Vídeo, placa, horário e quem autorizou — pronto para conferência de síndico ou seguradora.' }, { num: 'F5', title: 'Alerta de carro suspeito', desc: 'Placa fora do cadastro, veículo rondando o quarteirão ou tentativa de entrada em horário incomum disparam aviso imediato.' }, { num: 'F6', title: 'Integra com o que já existe', desc: 'Funciona com câmeras IP da maioria dos fornecedores e interfones digitais. Sem amarração com fabricante.' }, ]; return (
recursos

O que a Luna entrega na portaria.

{items.map((it) => (
{it.num}

{it.title}

{it.desc}

))}
); } /* ─────────────────── Numbers ─────────────────── */ function Numeros() { return (
números do piloto

Menos fila. Menos chamada. Mais registro.

Resultados médios após 60 dias em condomínios residenciais de médio porte (entre 80 e 240 unidades).

−68%
tempo médio de espera na cancela em horário de pico
0,4s
para ler a placa e cruzar com o cadastro do condomínio
+47
condomínios já em operação no Sul e Sudeste do país
100%
das entradas registradas em vídeo, com placa e horário
); } /* ─────────────────── CTA ─────────────────── */ function CTA() { const [sent, setSent] = useState(false); return (
próximo passo

Quer ver a Luna na sua portaria?

Marcamos uma visita técnica de 40 minutos. Mapeamos a câmera atual, o fluxo da entrada e devolvemos uma proposta sob medida — sem compromisso e sem trocar nada do que já está instalado.

+55 (51) 99999·0000
seg–sex · 9h–18h
ola@luna.cam
resposta em até 4h úteis
{ e.preventDefault(); setSent(true); }}> {sent ? (
Recebido. ✓
A Luna te chama no próximo dia útil.
) : (
)}
); } /* ─────────────────── Footer ─────────────────── */ function Footer() { return ( ); } /* ─────────────────── App ─────────────────── */ function App() { return (