// Pre-launch landing page for Minilands — converts web visitors to registered leads.
// Hero (key art + email/nickname/class form) → Trailer → Founder rewards → Final CTA + socials.
const CLASSES = [
{ id: 'warrior', name: 'GUERREIRO', color: '#e55a3a', icon: '⚔️', desc: 'Tank corpo-a-corpo' },
{ id: 'mage', name: 'MAGO', color: '#a566ff', icon: '🔮', desc: 'Magia devastadora' },
{ id: 'archer', name: 'ARQUEIRO', color: '#6abe30', icon: '🏹', desc: 'Precisão letal' },
{ id: 'healer', name: 'CURANDEIRO', color: '#5dabe8', icon: '✨', desc: 'Suporte e cura' },
];
// Wordmark SVG defined in wordmark.jsx (window.Wordmark) — alias here for convenience.
const Wordmark = window.Wordmark;
const Nav = () => {
return (
);
};
// BlockLogo defined in block-logo.jsx (window.BlockLogo)
const BlockLogo = window.BlockLogo;
// =================== HERO + REGISTER FORM ===================
const Hero = () => {
const [form, setForm] = React.useState({ email: '', nickname: '', classId: 'warrior' });
const [submitted, setSubmitted] = React.useState(false);
const [touched, setTouched] = React.useState(false);
const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email);
const nickValid = form.nickname.length >= 3 && form.nickname.length <= 16 && /^[a-zA-Z0-9_]+$/.test(form.nickname);
const canSubmit = emailValid && nickValid;
const handleSubmit = (e) => {
e.preventDefault();
setTouched(true);
if (canSubmit) setSubmitted(true);
};
const selectedClass = CLASSES.find(c => c.id === form.classId);
return (
{/* Background key art — full bleed, blurred + tinted */}
{/* Coming soon ribbon at top */}
EM BREVE • PRÉ-REGISTRO ABERTO
{/* LEFT — copy */}
CONSTRUA
SUA LENDA
ANTES DE TODOS!
Reserve agora seu nickname exclusivo, ganhe acesso antecipado ao beta e desbloqueie itens de Fundador que ninguém mais terá!
{/* Perks chips */}
{[
{ icon: '🎮', label: 'BETA EXCLUSIVO', color: '#7cd23e' },
{ icon: '👑', label: 'TÍTULO FUNDADOR', color: '#f7c93b' },
{ icon: '🏷️', label: 'NICKNAME GARANTIDO', color: '#5dabe8' },
{ icon: '🐉', label: 'PET ÚNICO', color: '#c266ff' },
].map(p => (
{p.icon}
{p.label}
))}
{/* RIGHT — register form card */}
{/* Top tab */}
🎉 GRÁTIS
{!submitted ? (
<>
RESERVE SEU LUGAR
Leva menos de 30 segundos. Sem compromisso.
>
) : (
)}
);
};
// Helper components
const Field = ({ label, hint, hintColor = '#e55a3a', children }) => (
{children}
{hint && (
{hint}
)}
);
const labelStyle = {
display: 'block', marginBottom: 6,
fontFamily: 'Fredoka, sans-serif', fontWeight: 700, fontSize: 11,
letterSpacing: '0.12em', textTransform: 'uppercase', color: '#a8b8d4',
};
const inputStyle = (error) => ({
width: '100%', boxSizing: 'border-box',
padding: '13px 14px',
background: 'rgba(0,0,0,0.4)',
border: error ? '2px solid #e55a3a' : '2px solid rgba(255,255,255,0.15)',
borderRadius: 8,
fontFamily: 'Fredoka, sans-serif', fontSize: 15, fontWeight: 500,
color: '#fff',
outline: 'none',
transition: 'border-color 150ms',
});
// Tiny shade helper for class buttons
function shade(hex, amount) {
const num = parseInt(hex.replace('#', ''), 16);
const r = Math.max(0, Math.min(255, ((num >> 16) & 0xff) + amount));
const g = Math.max(0, Math.min(255, ((num >> 8) & 0xff) + amount));
const b = Math.max(0, Math.min(255, (num & 0xff) + amount));
return '#' + ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0');
}
const SuccessState = ({ form, selectedClass }) => (
✓
VOCÊ ESTÁ DENTRO!
Bem-vindo, {form.nickname} o {selectedClass.icon}!
Enviamos a confirmação para {form.email}.
SEU CÓDIGO DE FUNDADOR
ML-{form.nickname.toUpperCase().padEnd(8, 'X').slice(0, 8)}-{Math.floor(Math.random() * 9000 + 1000)}
Compartilhe e ganhe +1 dia de beta para cada amigo inscrito!
);
// =================== TRAILER ===================
const Trailer = () => (
🎬 TRAILER OFICIAL
VEJA O QUE VEM POR AÍ
{/* Backdrop using key art */}
{/* Play button */}
{/* Bottom label */}
MINILANDS — Reveal Trailer • 2:14
);
// =================== FOUNDER REWARDS ===================
const Rewards = () => {
const rewards = [
{
icon: '🎮',
title: 'ACESSO ANTECIPADO',
desc: 'Entre no beta fechado semanas antes do público geral. Sua opinião molda o jogo final.',
color: '#7cd23e',
},
{
icon: '👑',
title: 'TÍTULO DE FUNDADOR',
desc: 'Distintivo dourado permanente no perfil. Todos vão saber que você esteve aqui no começo.',
color: '#f7c93b',
},
{
icon: '🏷️',
title: 'NICKNAME RESERVADO',
desc: 'Seu nome único é reservado e protegido. Nenhum outro jogador pode pegar.',
color: '#5dabe8',
},
{
icon: '🐲',
title: 'PET LENDÁRIO',
desc: 'Companheiro voador exclusivo de Fundador. Nunca será vendido na loja, garantido.',
color: '#c266ff',
},
];
return (
🎁 RECOMPENSAS DE FUNDADOR
SÓ PRA QUEM CHEGOU PRIMEIRO
Tudo isso GRÁTIS. Não vai voltar nunca mais. Quem entrou, entrou.
{rewards.map((r, i) => (
e.currentTarget.style.transform = 'translateY(-4px)'}
onMouseLeave={e => e.currentTarget.style.transform = 'translateY(0)'}
>
{/* Number badge */}
{i + 1}
{r.icon}
{r.title}
{r.desc}
))}
);
};
// =================== FINAL CTA + SOCIALS ===================
const FinalCTA = () => (
{/* Floating gems decoration */}
NÃO FIQUE
DE FORA!
Cada dia que passa, mais gente reserva os melhores nicknames. Garante o seu agora — leva menos de 30 segundos.
🎮 RESERVAR MINHA VAGA
{/* Socials */}
SIGA E FIQUE POR DENTRO
{[
{ name: 'Discord', icon: '💬', color: '#5865F2', handle: '/minilands' },
{ name: 'YouTube', icon: '▶', color: '#ff0033', handle: '@minilands' },
{ name: 'TikTok', icon: '♪', color: '#fe2c55', handle: '@minilands' },
{ name: 'Instagram', icon: '◉', color: '#e4405f', handle: '@minilands' },
{ name: 'X / Twitter', icon: '𝕏', color: '#1d9bf0', handle: '@minilands' },
].map(s => (
{ e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.background = s.color + '33'; }}
onMouseLeave={e => { e.currentTarget.style.transform = 'none'; e.currentTarget.style.background = 'rgba(0,0,0,0.55)'; }}
>
{s.icon}
{s.handle}
))}
);
// =================== FOOTER ===================
const Footer = () => (
);
// =================== MAIN ===================
const PreRegisterApp = () => (
<>
>
);
ReactDOM.createRoot(document.getElementById('root')).render();