feat: Localize content to European Portuguese, enhance integration section visuals, and restructure page sections.

This commit is contained in:
2026-03-18 16:38:16 +00:00
parent b75b607b5d
commit 910a30c2ea
13 changed files with 322 additions and 254 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules

21
package-lock.json generated
View File

@@ -122,6 +122,7 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -4764,6 +4765,7 @@
"integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@@ -4774,6 +4776,7 @@
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -4784,6 +4787,7 @@
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"devOptional": true,
"license": "MIT",
"peer": true,
"peerDependencies": {
"@types/react": "^19.2.0"
}
@@ -4833,6 +4837,7 @@
"integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.52.0",
"@typescript-eslint/types": "8.52.0",
@@ -5084,6 +5089,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -5347,6 +5353,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -5795,7 +5802,8 @@
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
"integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/embla-carousel-react": {
"version": "8.6.0",
@@ -5890,6 +5898,7 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -6481,6 +6490,7 @@
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"jiti": "bin/jiti.js"
}
@@ -6935,6 +6945,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -6982,6 +6993,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -7188,6 +7200,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -7218,6 +7231,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -7230,6 +7244,7 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.70.0.tgz",
"integrity": "sha512-COOMajS4FI3Wuwrs3GPpi/Jeef/5W1DRR84Yl5/ShlT3dKVFUfoGiEZ/QE6Uw8P4T2/CLJdcTVYKvWBMQTEpvw==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -7741,6 +7756,7 @@
"integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
@@ -7897,6 +7913,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -8121,6 +8138,7 @@
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -8241,6 +8259,7 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz",
"integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==",
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}

View File

@@ -7,7 +7,7 @@ import { Features } from './sections/Features';
import { Integration } from './sections/Integration';
import { Colors } from './sections/Colors';
import { Specs } from './sections/Specs';
import { FutureUpdates } from './sections/FutureUpdates';
import { DeepDive } from './sections/DeepDive';
import { Footer } from './sections/Footer';
function App() {
@@ -23,7 +23,7 @@ function App() {
<Integration />
<Colors />
<Specs />
<FutureUpdates />
<DeepDive />
</main>
<Footer />
</div>

View File

@@ -11,13 +11,13 @@ const features = [
{
icon: Wifi,
title: 'Conectado',
description: 'Sincronização perfeita com seu smartphone para análise completa dos seus treinos e progresso.',
description: 'Sincronização perfeita com o seu telemóvel para análise completa dos seus treinos e progresso.',
color: 'teal',
},
{
icon: Eye,
title: 'Em Tempo Real',
description: 'Visualize suas métricas sem tirar os olhos do caminho. Display HUD de alta definição sempre visível.',
description: 'Visualize as suas métricas sem tirar os olhos do caminho. Ecrã HUD de alta definição sempre visível.',
color: 'cyan',
},
];
@@ -109,7 +109,7 @@ export function About() {
<div className="mt-16 reveal-card opacity-0">
<div className="bg-gradient-to-r from-slate-800/80 to-slate-800/40 border border-slate-700 rounded-2xl p-8 lg:p-10">
<p className="text-slate-300 text-center text-lg leading-relaxed max-w-4xl mx-auto">
O <span className="text-orange-400 font-semibold">VisionRun Pro</span> é um óculos inteligente desenvolvido para auxiliar corredores durante seus treinos. Ele permite visualizar informações importantes em tempo real, sem a necessidade de olhar para o celular.
O <span className="text-orange-400 font-semibold">VisionRun Pro</span> coloca métricas de treino diretamente no seu campo de visão: velocidade, distância, tempo, mapa do trajeto e estado da bateria tudo sem desviar o olhar da corrida. Projeto concebido para corredores que exigem informação imediata, confiável e discreta.
</p>
</div>
</div>

164
src/sections/DeepDive.tsx Normal file
View File

@@ -0,0 +1,164 @@
import { useEffect, useRef } from 'react';
import { Battery, Zap, Database, Clock } from 'lucide-react';
import { Badge } from '@/components/ui/badge';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
const calculations = [
{
icon: Battery,
title: 'Energia Útil (Wh)',
formula: 'Capacidade (Ah) × Tensão (V)',
steps: [
'Capacidade: 500 mAh = 0,500 Ah',
'Tensão Nominal: 3,7 V',
'0,500 Ah × 3,7 V = 1,85 Wh'
],
result: '1,85 Wh de energia armazenada',
color: 'orange'
},
{
icon: Zap,
title: 'Consumo por Modo',
formula: 'Autonomia = mAh / mA',
modes: [
{ name: 'Standby', current: '6,94 mA', autonomy: '72,0 h' },
{ name: 'Otimizado (Light)', current: '60 mA', autonomy: '8,33 h' },
{ name: 'Uso Normal', current: '125 mA', autonomy: '4,0 h' },
{ name: 'Performance', current: '260 mA', autonomy: '1,92 h' }
],
color: 'teal'
},
{
icon: Database,
title: 'Armazenamento GPS',
formula: 'Flash / Sample Size',
steps: [
'Flash: 4 MB (4.194.304 bytes)',
'Sample: ~32 bytes (lat, lon, spd...)',
'Capacidade Bruta: 131.072 amostras',
'Realista (50% útil): ~18h @ 1Hz'
],
result: 'Espaço para múltiplas sessões locais',
color: 'blue'
},
{
icon: Clock,
title: 'Ciclo de Carga',
formula: 'Capacidade / Corrente de Carga',
steps: [
'Carga Típica (0,5C): 250 mA',
'Tempo Teórico: 2,0 h',
'Com Overhead (CC-CV): ~2,2 h',
'Carga Rápida (1C): ~1,2 h'
],
result: '2h para carga completa segura',
color: 'green'
}
];
export function DeepDive() {
const sectionRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const elements = entry.target.querySelectorAll('.reveal-dive');
elements.forEach((el, index) => {
setTimeout(() => {
el.classList.add('animate-fade-in-up');
}, index * 100);
});
observer.unobserve(entry.target);
}
});
},
{ threshold: 0.1 }
);
if (sectionRef.current) {
observer.observe(sectionRef.current);
}
return () => observer.disconnect();
}, []);
return (
<section id="deep-dive" ref={sectionRef} className="py-24 lg:py-32 bg-slate-900">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16 reveal-dive opacity-0">
<Badge className="mb-4 bg-orange-500/10 text-orange-400 border-orange-500/30 hover:bg-orange-500/20 px-4 py-1.5 text-xs font-semibold tracking-wider uppercase">
Deep Dive Técnico
</Badge>
<h2 className="font-display font-bold text-3xl sm:text-4xl lg:text-5xl text-white mb-4">
Cálculos e Estimativas Reais
</h2>
<div className="w-16 h-1 bg-gradient-to-r from-orange-500 to-teal-500 mx-auto rounded-full mb-6" />
<p className="text-slate-400 text-lg max-w-2xl mx-auto">
Transparência total: veja como chegamos às cifras de autonomia, carregamento e armazenamento do VisionRun Pro.
</p>
</div>
<div className="grid md:grid-cols-2 gap-6 lg:gap-8">
{calculations.map((calc, index) => {
const Icon = calc.icon;
return (
<Card key={index} className="reveal-dive opacity-0 bg-slate-800/40 border-slate-700 hover:border-slate-500 transition-all duration-300">
<CardHeader className="flex flex-row items-center gap-4 space-y-0">
<div className={`w-12 h-12 rounded-lg bg-slate-700/50 flex items-center justify-center`}>
<Icon className="w-6 h-6 text-white" />
</div>
<div>
<CardTitle className="text-white text-xl">{calc.title}</CardTitle>
<p className="text-slate-500 text-sm font-mono">{calc.formula}</p>
</div>
</CardHeader>
<CardContent>
{calc.modes ? (
<div className="space-y-3">
<div className="grid grid-cols-3 text-xs font-semibold text-slate-500 uppercase tracking-wider pb-2 border-b border-slate-700/50">
<span>Modo</span>
<span>Corrente</span>
<span className="text-right">Autonomia</span>
</div>
{calc.modes.map((mode, mIdx) => (
<div key={mIdx} className="grid grid-cols-3 text-sm py-1">
<span className="text-slate-300">{mode.name}</span>
<span className="text-slate-400 font-mono">{mode.current}</span>
<span className="text-orange-400 font-mono text-right">{mode.autonomy}</span>
</div>
))}
</div>
) : (
<div className="space-y-4">
<ul className="space-y-2">
{calc.steps?.map((step, sIdx) => (
<li key={sIdx} className="flex items-center gap-2 text-sm text-slate-400">
<div className="w-1.5 h-1.5 rounded-full bg-slate-600" />
{step}
</li>
))}
</ul>
<div className="pt-4 border-t border-slate-700/50">
<p className="text-teal-400 font-semibold">{calc.result}</p>
</div>
</div>
)}
</CardContent>
</Card>
);
})}
</div>
<div className="mt-12 reveal-dive opacity-0">
<div className="bg-orange-500/5 border border-orange-500/20 rounded-2xl p-6 text-center">
<p className="text-slate-400 text-sm italic">
* Nota: 8h em modo otimizado (GPS 1 Hz, brilho reduzido). Em sessões com GPS em alta taxa de atualização e sincronização Wi-Fi contínua, a autonomia média é de 24 h.
</p>
</div>
</div>
</div>
</section>
);
}

View File

@@ -4,28 +4,28 @@ import { Gauge, Route, Smartphone, Map, TrendingUp } from 'lucide-react';
const features = [
{
icon: Gauge,
title: 'Cálculo da velocidade em tempo real',
description: 'Acompanhe sua velocidade instantânea durante toda a corrida',
title: 'Velocidade em Tempo Real',
description: 'Acompanhe a sua velocidade instantânea diretamente no HUD.',
},
{
icon: Route,
title: 'Cálculo da distância percorrida',
description: 'Saiba exatamente quantos quilômetros você já completou',
title: 'Distância Percorrida',
description: 'Saiba exatamente quantos quilómetros já completou.',
},
{
icon: Smartphone,
title: 'Monitoramento pelo celular',
description: 'Sincronização automática com o aplicativo móvel',
title: 'Sincronização BLE/Wi-Fi',
description: 'Transferência automática de dados para a aplicação VisionRun.',
},
{
icon: Map,
title: 'Exibição do circuito percorrido',
description: 'Visualize todo o trajeto no aplicativo após o treino',
title: 'Análise de Trajeto',
description: 'Visualize o seu percurso completo com mapas detalhados.',
},
{
icon: TrendingUp,
title: 'Acompanhamento de desempenho',
description: 'Análise completa do seu progresso durante a corrida',
title: 'Métricas de Performance',
description: 'Análise completa do seu ritmo e evolução por trecho.',
},
];
@@ -109,7 +109,7 @@ export function Features() {
Funcionalidades Completamente Operacionais
</h4>
<p className="text-slate-400 text-sm leading-relaxed">
Todas as funcionalidades listadas acima estão implementadas e funcionando perfeitamente no VisionRun Pro. O sistema foi testado extensivamente para garantir precisão e confiabilidade durante suas corridas.
Todas as funcionalidades listadas acima estão implementadas e a funcionar perfeitamente no VisionRun Pro. O sistema foi testado extensivamente para garantir precisão e fiabilidade durante as suas corridas.
</p>
</div>
</div>

View File

@@ -10,9 +10,9 @@ const quickLinks = [
];
const contactInfo = [
{ icon: Mail, label: 'contato@visionrun.com' },
{ icon: Phone, label: '+55 (11) 4000-1234' },
{ icon: MapPin, label: 'São Paulo, SP - Brasil' },
{ icon: Mail, label: 'contacto@visionrun.pt' },
{ icon: Phone, label: '+351 210 000 000' },
{ icon: MapPin, label: 'Lisboa, Portugal' },
];
const socialLinks = [
@@ -37,10 +37,10 @@ export function Footer() {
{/* CTA Section */}
<div className="py-16 text-center border-b border-slate-800">
<h2 className="font-display font-bold text-3xl sm:text-4xl text-white mb-4">
Pronto para Revolucionar suas Corridas?
Pronto para Revolucionar as suas Corridas?
</h2>
<p className="text-slate-400 text-lg max-w-2xl mx-auto mb-8">
Adquira o VisionRun Pro hoje e experimente o futuro da tecnologia wearable para corrida.
Adquira o VisionRun Pro hoje e experimente o futuro da tecnologia portátil para corrida.
</p>
<Button
size="lg"
@@ -49,7 +49,7 @@ export function Footer() {
<svg className="w-5 h-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
Fale Conosco
Fale Connosco
</Button>
</div>
@@ -110,7 +110,7 @@ export function Footer() {
{/* Contact */}
<div>
<h3 className="font-display font-semibold text-white mb-4">Contato</h3>
<h3 className="font-display font-semibold text-white mb-4">Contacto</h3>
<ul className="space-y-3">
{contactInfo.map((item, index) => {
const Icon = item.icon;

View File

@@ -1,158 +0,0 @@
import { useEffect, useRef } from 'react';
import { Headphones, Moon, Activity, Volume2, Music, Bell } from 'lucide-react';
import { Badge } from '@/components/ui/badge';
const upcomingFeatures = [
{
icon: Headphones,
title: 'Áudio Integrado',
subtitle: 'Tecnologia de condução óssea para máxima segurança',
features: [
{ icon: Volume2, title: 'Notificações por Voz', desc: 'Receba métricas importantes em áudio sem olhar para nada' },
{ icon: Music, title: 'Reprodução de Música', desc: 'Ouça suas playlists favoritas durante a corrida' },
{ icon: Bell, title: 'Alertas Inteligentes', desc: 'Notificações de frequência cardíaca e zona de treino' },
],
},
];
const roadmapItems = [
{
icon: Moon,
title: 'Display Noturno',
description: 'Modo de visualização otimizado para corridas noturnas com ajuste automático de brilho e contraste adaptativo.',
quarter: 'Q3 2026',
color: 'pink',
},
{
icon: Activity,
title: 'Integração com Sensores',
description: 'Conexão com monitores de frequência cardíaca, pods de corrida e outros dispositivos ANT+ para métricas completas.',
quarter: 'Q4 2026',
color: 'teal',
},
];
export function FutureUpdates() {
const sectionRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const elements = entry.target.querySelectorAll('.reveal-future');
elements.forEach((el, index) => {
setTimeout(() => {
el.classList.add('animate-fade-in-up');
}, index * 100);
});
observer.unobserve(entry.target);
}
});
},
{ threshold: 0.15 }
);
if (sectionRef.current) {
observer.observe(sectionRef.current);
}
return () => observer.disconnect();
}, []);
return (
<section ref={sectionRef} className="py-24 lg:py-32 bg-slate-900/50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Section Header */}
<div className="text-center mb-16 reveal-future opacity-0">
<Badge className="mb-4 bg-slate-800 text-pink-400 border-pink-500/30 hover:bg-slate-700 px-4 py-1.5 text-xs font-semibold tracking-wider uppercase">
<svg className="w-3 h-3 mr-1 inline" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
Em Breve
</Badge>
<h2 className="font-display font-bold text-3xl sm:text-4xl lg:text-5xl text-white mb-4">
Futuras Atualizações
</h2>
<div className="w-16 h-1 bg-gradient-to-r from-orange-500 to-orange-400 mx-auto rounded-full mb-6" />
<p className="text-slate-400 text-lg max-w-2xl mx-auto">
O VisionRun Pro está em constante evolução. Confira as próximas funcionalidades que estão sendo desenvolvidas.
</p>
</div>
{/* Audio Feature Card */}
<div className="mb-12 reveal-future opacity-0">
<div className="bg-gradient-to-br from-slate-800/80 to-slate-800/40 border border-slate-700 rounded-2xl p-6 lg:p-8">
<div className="flex items-center gap-4 mb-6">
<div className="w-12 h-12 rounded-xl bg-slate-700/50 border border-slate-600 flex items-center justify-center">
<Headphones className="w-6 h-6 text-white" />
</div>
<div>
<h3 className="font-display font-semibold text-xl text-white">
Áudio Integrado
</h3>
<p className="text-slate-400 text-sm">
Tecnologia de condução óssea para máxima segurança
</p>
</div>
</div>
<div className="grid sm:grid-cols-3 gap-4">
{upcomingFeatures[0].features.map((feature, index) => {
const Icon = feature.icon;
return (
<div
key={index}
className="bg-slate-800/50 border border-slate-700 rounded-xl p-4 hover:border-slate-500 transition-colors"
>
<Icon className="w-5 h-5 text-slate-400 mb-2" />
<h4 className="font-semibold text-white text-sm mb-1">
{feature.title}
</h4>
<p className="text-slate-400 text-xs leading-relaxed">
{feature.desc}
</p>
</div>
);
})}
</div>
</div>
</div>
{/* Roadmap Grid */}
<div className="grid md:grid-cols-2 gap-6">
{roadmapItems.map((item, index) => {
const Icon = item.icon;
const colorClasses =
item.color === 'pink'
? 'bg-pink-500/10 text-pink-400 border-pink-500/30'
: 'bg-teal-500/10 text-teal-400 border-teal-500/30';
return (
<div
key={index}
className="reveal-future opacity-0 bg-slate-800/50 border border-slate-700 rounded-2xl p-6 hover:border-slate-500 transition-all duration-300"
>
<div className="flex items-start justify-between mb-4">
<div className="w-10 h-10 rounded-lg bg-slate-700/50 flex items-center justify-center">
<Icon className="w-5 h-5 text-white" />
</div>
<Badge className={`${colorClasses} text-xs font-semibold`}>
{item.quarter}
</Badge>
</div>
<h3 className="font-display font-semibold text-lg text-white mb-2">
{item.title}
</h3>
<p className="text-slate-400 text-sm leading-relaxed">
{item.description}
</p>
</div>
);
})}
</div>
</div>
</section>
);
}

View File

@@ -59,7 +59,7 @@ export function Hero() {
<div className="absolute bottom-1/4 -right-32 w-96 h-96 bg-orange-500/20 rounded-full blur-[120px] animate-pulse-glow" style={{ animationDelay: '1s' }} />
</div>
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 lg:py-0">
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-32 pb-20 lg:pt-0 lg:pb-0">
<div className="grid lg:grid-cols-2 gap-12 lg:gap-8 items-center">
{/* Product Image - Left Side */}
<div className="relative order-2 lg:order-1 reveal opacity-0">
@@ -123,26 +123,25 @@ export function Hero() {
</div>
</div>
</div>
{/* Content - Right Side */}
<div className="order-1 lg:order-2 text-center lg:text-left">
<div className="order-1 lg:order-2 text-center lg:text-left mt-12 lg:mt-0">
<div className="reveal opacity-0" style={{ animationDelay: '100ms' }}>
<Badge className="mb-6 bg-slate-800 text-teal-400 border-teal-500/30 hover:bg-slate-700 px-4 py-1.5 text-xs font-semibold tracking-wider uppercase">
<Badge className="mb-8 bg-slate-800 text-teal-400 border-teal-500/30 hover:bg-slate-700 px-4 py-1.5 text-xs font-semibold tracking-wider uppercase">
Tecnologia de Ponta
</Badge>
</div>
<h1 className="reveal opacity-0 font-display font-bold text-5xl sm:text-6xl lg:text-7xl text-white leading-[1.1] mb-6" style={{ animationDelay: '200ms' }}>
<h1 className="reveal font-display font-bold text-3xl sm:text-4xl lg:text-5xl text-white leading-[1.2] mb-6" style={{ animationDelay: '200ms' }}>
VisionRun
<span className="text-gradient"> Pro</span>
<span className="text-gradient"> Pro</span> Óculos Inteligentes para Corrida
</h1>
<p className="reveal opacity-0 text-xl sm:text-2xl text-slate-300 font-medium mb-4" style={{ animationDelay: '300ms' }}>
Óculos de Corrida de Alta Performance!!!!!!
<p className="reveal opacity-0 text-lg sm:text-xl text-slate-300 font-medium mb-4" style={{ animationDelay: '300ms' }}>
Tecnologia e desempenho à vista: HUD em tempo real, GPS de alta precisão e 8 horas de autonomia no modo corrida otimizado.
</p>
<p className="reveal opacity-0 text-slate-400 text-base sm:text-lg max-w-xl mx-auto lg:mx-0 mb-8" style={{ animationDelay: '400ms' }}>
Tecnologia e desempenho ao alcance da sua visão. Experimente o futuro da corrida com dados em tempo real sem tirar os olhos do caminho.
Leves como uma pena (35 g), desenhados para quem não quer tirar os olhos do caminho.
</p>
<div className="reveal opacity-0 flex flex-col sm:flex-row gap-4 justify-center lg:justify-start mb-8" style={{ animationDelay: '500ms' }}>
@@ -161,7 +160,7 @@ export function Hero() {
className="border-slate-600 text-slate-300 hover:border-orange-500 hover:text-white bg-transparent px-8 py-6 text-base transition-all duration-300"
>
<Play className="w-5 h-5 mr-2" />
Saiba Mais
Saber Mais
</Button>
</div>

View File

@@ -6,17 +6,17 @@ const integrationFeatures = [
{
icon: MapIcon,
title: 'Visualização do Trajeto',
description: 'O trajeto completo é exibido no aplicativo do smartphone com mapa interativo e detalhes de elevação.',
description: 'O trajeto completo é exibido na aplicação do telemóvel com mapa interativo e detalhes de elevação.',
},
{
icon: BarChart3,
title: 'Acompanhamento do Percurso',
description: 'Após finalizar a corrida, você pode acompanhar o percurso completo com análise detalhada de cada trecho.',
description: 'Após finalizar a corrida, pode acompanhar o percurso completo com análise detalhada de cada trecho.',
},
{
icon: Database,
title: 'Dados Registrados',
description: 'Todos os dados ficam registrados no aplicativo para análise de desempenho e acompanhamento de evolução.',
title: 'Dados Registados',
description: 'Todos os dados ficam registados na aplicação para análise de desempenho e acompanhamento de evolução.',
},
];
@@ -57,7 +57,7 @@ export function Integration() {
Conectividade
</Badge>
<h2 className="font-display font-bold text-3xl sm:text-4xl lg:text-5xl text-white mb-4">
Integração com Smartphone
Integração com Telemóvel
</h2>
<div className="w-16 h-1 bg-gradient-to-r from-orange-500 to-orange-400 mx-auto rounded-full mb-6" />
</div>
@@ -89,35 +89,77 @@ export function Integration() {
{/* Map Placeholder */}
<div className="bg-slate-800 rounded-xl aspect-square mb-4 relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-slate-700 to-slate-800">
{/* Map Grid */}
<div className="absolute inset-0 bg-slate-900">
{/* Map Grid - City Style */}
<div
className="absolute inset-0 opacity-20"
className="absolute inset-0 opacity-[0.15]"
style={{
backgroundImage: `linear-gradient(rgba(255,255,255,0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.1) 1px, transparent 1px)`,
backgroundSize: '20px 20px',
backgroundImage: `linear-gradient(#475569 1px, transparent 1px),
linear-gradient(90deg, #475569 1px, transparent 1px)`,
backgroundSize: '40px 40px',
}}
/>
{/* Route Line */}
<svg className="absolute inset-0 w-full h-full" viewBox="0 0 100 100" preserveAspectRatio="none">
<div
className="absolute inset-0 opacity-[0.05]"
style={{
backgroundImage: `linear-gradient(#475569 1px, transparent 1px),
linear-gradient(90deg, #475569 1px, transparent 1px)`,
backgroundSize: '10px 10px',
}}
/>
{/* Park Area */}
<div className="absolute top-1/4 left-1/4 w-1/3 h-1/4 bg-teal-900/20 rounded-lg rotate-12 border border-teal-800/30" />
{/* Route Line - More Complex */}
<svg className="absolute inset-0 w-full h-full p-6" viewBox="0 0 100 100">
<defs>
<linearGradient id="routeGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#22d3ee" />
<stop offset="100%" stopColor="#f97316" />
</linearGradient>
</defs>
<path
d="M20,80 Q30,60 40,65 T60,50 T80,30"
d="M 10,85 L 25,85 L 25,60 L 45,60 L 45,40 L 70,40 L 70,20 L 85,20"
fill="none"
stroke="#f97316"
strokeWidth="2"
stroke="url(#routeGradient)"
strokeWidth="3"
strokeLinecap="round"
strokeLinejoin="round"
className="drop-shadow-[0_0_8px_rgba(249,115,22,0.5)]"
/>
{/* Mile Markers */}
<circle cx="25" cy="85" r="1.5" fill="white" />
<circle cx="45" cy="60" r="1.5" fill="white" />
<circle cx="70" cy="40" r="1.5" fill="white" />
{/* Start Point */}
<circle cx="20" cy="80" r="3" fill="#0d9488" />
<g>
<circle cx="10" cy="85" r="4" fill="#22d3ee" className="animate-pulse" />
<circle cx="10" cy="85" r="2" fill="white" />
</g>
{/* End Point */}
<circle cx="80" cy="30" r="3" fill="#f97316" />
<g>
<circle cx="85" cy="20" r="5" fill="#f97316" />
<MapIcon className="w-3 h-3 text-white" x="83.5" y="18.5" />
</g>
</svg>
{/* Location Pin */}
<div className="absolute top-1/3 right-1/4">
<div className="w-6 h-6 bg-orange-500 rounded-full flex items-center justify-center shadow-lg">
<MapIcon className="w-3 h-3 text-white" />
</div>
{/* Elevation Sparkline Placeholder */}
<div className="absolute bottom-10 left-2 right-2 h-8 bg-slate-900/80 backdrop-blur-sm border border-slate-700/50 rounded-md p-1 flex items-end gap-1 px-2">
{[20, 40, 35, 50, 65, 45, 60, 80].map((h, i) => (
<div key={i} className="flex-1 bg-teal-500/40 rounded-t-[1px]" style={{ height: `${h}%` }} />
))}
<span className="absolute top-1 left-2 text-[8px] text-teal-400 uppercase font-bold tracking-tighter">Elevation Gain: 42m</span>
</div>
{/* Pace Sparkline Placeholder */}
<div className="absolute bottom-2 left-2 right-2 h-8 bg-slate-900/80 backdrop-blur-sm border border-slate-700/50 rounded-md p-1 flex items-end gap-1 px-2">
{[60, 55, 70, 45, 40, 50, 45, 30].map((h, i) => (
<div key={i} className="flex-1 bg-orange-500/40 rounded-t-[1px]" style={{ height: `${h}%` }} />
))}
<span className="absolute top-1 left-2 text-[8px] text-orange-400 uppercase font-bold tracking-tighter">Average Pace: 5:25 min/km</span>
</div>
</div>
</div>

View File

@@ -8,7 +8,8 @@ const navLinks = [
{ label: 'Design', href: '#design' },
{ label: 'Funcionalidades', href: '#funcionalidades' },
{ label: 'Especificações', href: '#especificacoes' },
{ label: 'Contato', href: '#contato' },
{ label: 'Deep Dive', href: '#deep-dive' },
{ label: 'Contacto', href: '#contacto' },
];
export function Navigation() {
@@ -81,7 +82,7 @@ export function Navigation() {
{/* CTA Button */}
<div className="hidden lg:block">
<Button
onClick={() => scrollToSection('#contato')}
onClick={() => scrollToSection('#contacto')}
className="bg-orange-500 hover:bg-orange-400 text-white font-semibold px-6 transition-all duration-300 hover:shadow-lg hover:shadow-orange-500/30"
>
Comprar Agora
@@ -118,7 +119,7 @@ export function Navigation() {
</button>
))}
<Button
onClick={() => scrollToSection('#contato')}
onClick={() => scrollToSection('#contacto')}
className="mt-2 bg-orange-500 hover:bg-orange-400 text-white font-semibold"
>
Comprar Agora

View File

@@ -4,32 +4,32 @@ import { Cpu, Battery, Wifi } from 'lucide-react';
const specCategories = [
{
icon: Cpu,
title: 'Processador',
title: 'Processamento',
specs: [
{ label: 'Microcontrolador', value: 'ESP32 Dual-Core' },
{ label: 'Frequência', value: '240 MHz' },
{ label: 'Memória RAM', value: '520 KB SRAM' },
{ label: 'Flash', value: '4 MB' },
{ label: 'Memória Flash', value: '4 MB' },
],
},
{
icon: Battery,
title: 'Energia',
specs: [
{ label: 'Bateria', value: 'Li-Po 500mAh' },
{ label: 'Autonomia', value: '8 horas' },
{ label: 'Carregamento', value: 'USB-C (2h)' },
{ label: 'Standby', value: '72 horas' },
{ label: 'Bateria Li-Po', value: '500 mAh (3.7V)' },
{ label: 'Autonomia (Light)', value: '8 h' },
{ label: 'Standby', value: '~72 h' },
{ label: 'Carga USB-C', value: '2 h' },
],
},
{
icon: Wifi,
title: 'Conectividade',
title: 'Conexões',
specs: [
{ label: 'Bluetooth', value: '4.2 BLE' },
{ label: 'Wi-Fi', value: '802.11 b/g/n' },
{ label: 'GPS', value: 'Multi-GNSS' },
{ label: 'ANT+', value: 'Compatível' },
{ label: 'Bluetooth', value: 'LE / Wi-Fi OTA' },
{ label: 'GPS', value: 'Multi-GNSS 1-10Hz' },
{ label: 'Sensores', value: 'IMU 6-Eixos' },
{ label: 'Certificação', value: 'IPX4' },
],
},
];
@@ -42,10 +42,10 @@ const dimensions = [
];
const resistance = [
{ label: 'À água', value: 'IPX4' },
{ label: 'À poeira', value: 'IP5X' },
{ label: 'Resistência à água', value: 'IPX4' },
{ label: 'Resistência ao pó', value: 'IP5X' },
{ label: 'Temperatura', value: '-10°C a 45°C' },
{ label: 'Umidade', value: '10% a 90%' },
{ label: 'Humidade', value: '10% a 90%' },
];
const display = [

View File

@@ -5,49 +5,49 @@ import { Badge } from '@/components/ui/badge';
const techCards = [
{
icon: Cpu,
title: 'Microcontrolador ESP32',
description: 'Processador dual-core de 240MHz com conectividade Wi-Fi e Bluetooth integrada para máxima performance.',
title: 'Processador ESP32',
description: 'Microcontrolador Dual-Core a processar a 240 MHz com 520 KB SRAM. Potência de processamento ideal para HUD e sensores.',
tags: [
{ label: 'Dual-core Xtensa', color: 'slate' },
{ label: '520KB SRAM', color: 'slate' },
{ label: 'Wi-Fi 802.11 b/g/n', color: 'slate' },
{ label: 'Bluetooth 4.2', color: 'slate' },
{ label: 'Dual-Core 240 MHz', color: 'slate' },
{ label: '520 KB SRAM', color: 'slate' },
{ label: '4 MB Flash', color: 'slate' },
{ label: 'BLE + Wi-Fi', color: 'slate' },
],
color: 'blue',
},
{
icon: Box,
title: 'Impressão 3D Avançada',
description: 'Estrutura fabricada com tecnologia de impressão 3D de alta precisão, garantindo design ergonômico e peso reduzido.',
title: 'Design Premium PLA+',
description: 'Estrutura 3D impressa em PLA+ com reforços e acabamento premium. Apenas 35 g para máximo conforto.',
tags: [
{ label: 'Material PLA+', color: 'orange' },
{ label: 'Resistente a UV', color: 'orange' },
{ label: 'Ultra-leve', color: 'orange' },
{ label: 'Design customizável', color: 'orange' },
{ label: '35 g', color: 'orange' },
{ label: 'PLA+ Reforçado', color: 'orange' },
{ label: 'Hidrogrip', color: 'orange' },
{ label: 'IPX4', color: 'orange' },
],
color: 'orange',
},
{
icon: MapPin,
title: 'Módulo GPS',
description: 'GPS de alta precisão para rastreamento exato de localização, velocidade e distância em tempo real.',
title: 'GPS Multi-GNSS',
description: 'Módulo Multi-GNSS com atualização configurável (110 Hz) para um seguimento ultra-preciso.',
tags: [
{ label: 'Precisão <3m', color: 'slate' },
{ label: 'Atualização 10Hz', color: 'slate' },
{ label: '110 Hz Refresh', color: 'slate' },
{ label: 'Multi-GNSS', color: 'slate' },
{ label: 'Cold start <30s', color: 'slate' },
{ label: 'Seguimento Real-time', color: 'slate' },
],
color: 'teal',
},
{
icon: Battery,
title: 'Bateria Inteligente',
description: 'Sistema de energia otimizado com bateria de lítio recarregável via USB-C para até 8 horas de uso contínuo.',
title: 'Autonomia Realista',
description: 'Bateria Li-Po de 500 mAh (3.7 V) com até 8 horas de uso no modo otimizado e carregamento rápido USB-C.',
tags: [
{ label: 'Li-Po 500mAh', color: 'orange' },
{ label: 'USB-C Fast Charge', color: 'orange' },
{ label: '8h autonomia', color: 'orange' },
{ label: 'Carregamento 2h', color: 'orange' },
{ label: '500 mAh (3.7 V)', color: 'orange' },
{ label: '8h Modo Light', color: 'orange' },
{ label: 'USB-C Charging', color: 'orange' },
{ label: 'Modo Otimizado', color: 'orange' },
],
color: 'green',
},