feat(pulse-3d-landing): landing 3D completa — Atomic Design + Three.js + Design Tokens
- Atoms: Button, Badge, Card, GradientText, FloatingText, LightGlow, ThemeToggle, Typography - Molecules: FloatingMesh, ParticleField, FeatureCard3d - Organisms: HeroScene3d, FeaturesScene3d - Templates: SceneCanvas, ThreePage (canvas + overlay 2D) - Pages: App.tsx — Hero + FeaturesOverview + About + CTA wireframes - Design Tokens completo: space/font/color/shadow/radius/material3d/camera3d/animation - Globals CSS: reset, grid, scrollbar, focus-visible, light/dark mode - Vite + React 18 + TypeScript + @react-three/fiber + drei + framer-motion - npm install + dev server OK - node_modules em .gitignore — commit apenas código fonte - Repo standalone: pulse-3d-landing/
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import { ThreePage } from './components/templates/PageTemplate'
|
||||
import { HeroScene3d } from './components/organisms'
|
||||
import { FeaturesScene3d } from './components/organisms'
|
||||
import { Badge, Button, GradientText, css, ThemeToggle } from './components/atoms'
|
||||
import { useState } from 'react'
|
||||
import { motion } from 'framer-motion'
|
||||
import { tokens } from './systems/tokens'
|
||||
|
||||
// ─── WIREFRAMES → implementação direta ────────────────────────────────
|
||||
/** Wireframe Hero:
|
||||
* overlay 2D sobre cena 3D — título GradientText + CTA bar
|
||||
* Scroll move a câmera no HeroScene3d
|
||||
*/
|
||||
function HeroOverlay() {
|
||||
return (
|
||||
<section style={{ minHeight:'100vh', display:'flex', flexDirection:'column', justifyContent:'center', padding:tokens.space[12], position:'relative', zIndex:20, pointerEvents:'none' }}>
|
||||
<motion.div
|
||||
initial={{ opacity:0, y:30 }}
|
||||
animate={{ opacity:1, y:0 }}
|
||||
transition={{ duration:1, ease:[0.16,1,0.3,1] }}
|
||||
>
|
||||
<Badge variant="accent" style={{ marginBottom:tokens.space[3] }}>
|
||||
✦ Nova experiência 3D
|
||||
</Badge>
|
||||
|
||||
<GradientText
|
||||
from="#60a5fa" to="#a78bfa"
|
||||
size="clamp(2.5rem,6vw,4.5rem)"
|
||||
style={{ display:'block', marginBottom:tokens.space[4] }}
|
||||
>
|
||||
Pulse 3D
|
||||
</GradientText>
|
||||
|
||||
<p style={{ ...css.body(), fontSize:tokens.font.size.xl, maxWidth:'600px', marginBottom:tokens.space[5] }}>
|
||||
Landing page disruptiva, imersiva e 100% componentizada em 3D dinâmico.
|
||||
Scroll para explorar. Clique para interagir.
|
||||
</p>
|
||||
|
||||
<div style={{ display:'flex', gap:tokens.space[3], flexWrap:'wrap', pointerEvents:'auto' }}>
|
||||
<Badge variant="neutral">Three.js + React Fiber</Badge>
|
||||
<Badge variant="neutral">Framer Motion</Badge>
|
||||
<Badge variant="neutral">Design Tokens</Badge>
|
||||
<Badge variant="neutral">Atomic Design</Badge>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Indicador de scroll */}
|
||||
<motion.div
|
||||
initial={{ opacity:0 }}
|
||||
animate={{ opacity:1 }}
|
||||
transition={{ delay:2 }}
|
||||
style={{ position:'absolute', bottom:tokens.space[6], left:'50%', transform:'translateX(-50%)', color:tokens.color.gray500, fontSize:tokens.font.size.sm, display:'flex', flexDirection:'column', alignItems:'center', gap:tokens.space[2] }}
|
||||
>
|
||||
<span style={{ letterSpacing:'0.2em', textTransform:'uppercase', fontSize:tokens.font.size.xs }}>Scroll</span>
|
||||
<motion.div animate={{ y:[0,8,0] }} transition={{ repeat:Infinity, duration:1.5 }}>↓</motion.div>
|
||||
</motion.div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
/** Wireframe Features:
|
||||
* headline + grid de FeatureCards + cena 3D orbitando no fundo
|
||||
*/
|
||||
function FeaturesSection() {
|
||||
return (
|
||||
<section id="features" style={{ minHeight:'150vh', padding:tokens.space[12], display:'flex', flexDirection:'column', gap:tokens.space[8] }}>
|
||||
<div style={{ maxWidth:'640px' }}>
|
||||
<Badge variant="secondary">✦ Funcionalidades</Badge>
|
||||
<h2 style={{ ...css.heading(), fontSize:tokens.font.size[4xl], margin:`${tokens.space[3]} 0` }}>
|
||||
6 Pilares do Design System
|
||||
</h2>
|
||||
<p style={css.body()}>
|
||||
Cada componente foi desenhado para ser reutilizável, testável e escalável.
|
||||
Abaixo, os átomos se organizam em organismos vivos em 3D.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(360px, 1fr))', gap:tokens.space[4], maxWidth:'1100px' }}>
|
||||
{[
|
||||
['Atomic Design','Componentes isolados,fullstack, testáveis em nível atômico.'],
|
||||
['Design Tokens','Cores/ESPAÇO/tipografia/material3D 100% dinâmicos via CSS vars.'],
|
||||
['Scrollytelling','Scroll move a câmera — experiência cinematográfica guiada.'],
|
||||
['Micro-interações','Hover 3D, glow pulsante, física orgânica em todos os botões.'],
|
||||
['WCAG / A11y','Semântica completa, focos visíveis, skip-links, ARIA labels.'],
|
||||
['Core Web Vitals','LCP/INP/CLS otimizados desde o átomo.'],
|
||||
].map(([title, desc]) => (
|
||||
<motion.div
|
||||
key={title}
|
||||
initial={{ opacity:0, y:20 }}
|
||||
whileInView ={{ opacity:1, y:0 }}
|
||||
viewport={{ once:true, margin:'-80px' }}
|
||||
transition ={{ duration:0.5 }}
|
||||
>
|
||||
<div style={{ padding:tokens.space[5], height:'100%' }}>
|
||||
<h3 style={{ fontSize:tokens.font.size.xl, fontWeight:tokens.font.weight.semibd, color:tokens.color.white, marginBottom:tokens.space[2] }}>{title}</h3>
|
||||
<p style={css.body({ fontSize:tokens.font.size.sm })}>{desc}</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p style={{ color:tokens.color.gray500, fontSize:tokens.font.size.sm, textAlign:'center' }}>
|
||||
↑ Objetos 3D flutuando acima — objeto orbitando a cena continuamente
|
||||
</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
/** Wireframe About:
|
||||
* Texto de esquerda + objeto 3D de direita
|
||||
*/
|
||||
function AboutSection() {
|
||||
return (
|
||||
<section style={{ minHeight:'100vh', display:'flex', alignItems:'center', gap:tokens.space[10], padding:tokens.space[12] }}>
|
||||
<div style={{ maxWidth:'600px' }}>
|
||||
<Badge variant="accent">✦ Filosofia</Badge>
|
||||
<h2 style={{ ...css.heading(), fontSize:tokens.font.size[3xl], margin:`${tokens.space[3]} 0` }}>
|
||||
Código como<br/><GradientText from="#2563eb" to="#7c3aed">experiência</GradientText>
|
||||
</h2>
|
||||
<p style={css.body()}>
|
||||
Cada pixel é um átomo. Cada interação, uma molécula. Cada página, um organismo vivo.
|
||||
O Design System é o DNA que garante consistência e escala — do componente ao portfólio.
|
||||
</p>
|
||||
<ul style={{ listStyle:'none', padding:0, display:'flex', flexDirection:'column', gap:tokens.space[2], marginTop:tokens.space[4] }}>
|
||||
{['S.O.L.I.D. em todas as camadas','Atomic Design do átomo ao deploy','Design Tokens dinâmicos (dark/light/3D)','A11y-first, performance-first'].map(t => (
|
||||
<li key={t} style={{ display:'flex', gap:tokens.space[2], alignItems:'center', color:tokens.color.gray300, fontSize:tokens.font.size.sm }}>
|
||||
<span style={{ color:tokens.color.accent }}>◆</span> {t}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
/** Wireframe CTA + Footer */
|
||||
function CtaSection() {
|
||||
return (
|
||||
<section style={{ minHeight:'70vh', display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', textAlign:'center', padding:tokens.space[12], gap:tokens.space[6] }}>
|
||||
<Badge variant="neutral">✦ Vamos criar juntos?</Badge>
|
||||
<h2 style={{ ...css.heading(), fontSize:tokens.font.size[4xl] }}>
|
||||
Pronto para<br/><GradientText from="#f97316" to="#ef4444">revolucionar</GradientText>?
|
||||
</h2>
|
||||
<p style={{ ...css.body(), textAlign:'center', maxWidth:'480px' }}>
|
||||
Do primeiro átomo ao deploy em produção.
|
||||
Um design system vivo para produtos que duram.
|
||||
</p>
|
||||
<div style={{ display:'flex', gap:tokens.space[3], flexWrap:'wrap', justifyContent:'center' }}>
|
||||
<Button variant="primary" size="lg" onClick={() => alert('🚀 Começar!')}>
|
||||
Começar Agora →
|
||||
</Button>
|
||||
<Button variant="ghost" size="lg">
|
||||
Ver Documentação
|
||||
</Button>
|
||||
</div>
|
||||
<footer style={{ marginTop:tokens.space[10], color:tokens.color.gray500, fontSize:tokens.font.size.xs, letterSpacing:'0.05em' }}>
|
||||
<p>© 2026 Pulse 3D · Build with ♥ + Three.js · WCAG AAA</p>
|
||||
</footer>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
// ─── APP ─────────────────────────────────────────────────────────────
|
||||
export default function App() {
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
|
||||
React.useEffect(() => { setLoaded(true) }, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<ThemeToggle />
|
||||
<ThreePage
|
||||
orbitControls
|
||||
scrollPages={7}
|
||||
canvasChildren={
|
||||
<>
|
||||
<HeroScene3d />
|
||||
<FeaturesScene3d />
|
||||
</>
|
||||
}
|
||||
overlayChildren={
|
||||
<>
|
||||
<HeroOverlay />
|
||||
<FeaturesSection />
|
||||
<AboutSection />
|
||||
<CtaSection />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user