Primeira versão templates personal trainer
This commit is contained in:
commit
803f5b8a0b
47 changed files with 12708 additions and 0 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
20
Template-01/README.md
Normal file
20
Template-01/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<div align="center">
|
||||||
|
<img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
# Run and deploy your AI Studio app
|
||||||
|
|
||||||
|
This contains everything you need to run your app locally.
|
||||||
|
|
||||||
|
View your app in AI Studio: https://ai.studio/apps/ab70d450-2df0-4f23-86be-996339f68015
|
||||||
|
|
||||||
|
## Run Locally
|
||||||
|
|
||||||
|
**Prerequisites:** Node.js
|
||||||
|
|
||||||
|
|
||||||
|
1. Install dependencies:
|
||||||
|
`npm install`
|
||||||
|
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
|
||||||
|
3. Run the app:
|
||||||
|
`npm run dev`
|
||||||
36
Template-01/index.html
Normal file
36
Template-01/index.html
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="pt-BR">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
|
||||||
|
<!-- SEO and Meta Tags -->
|
||||||
|
<title>Alexandre Vaz | The Gold Standard Training</title>
|
||||||
|
<meta name="description" content="O fim das desculpas. Transformação corporal de alto impacto, consultoria personalizada, nutrição de precisão e performance atlética. Elite Training por Alexandre Vaz." />
|
||||||
|
<meta name="keywords" content="treino, hipertrofia, emagrecimento, consultoria fitness, alexandre vaz, bodybuilding, personal trainer online, estética, alta performance" />
|
||||||
|
<meta name="author" content="Alexandre Vaz" />
|
||||||
|
<meta name="robots" content="index, follow" />
|
||||||
|
|
||||||
|
<!-- Open Graph (Facebook / LinkedIn) -->
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="https://alexandrevaz.com/" />
|
||||||
|
<meta property="og:title" content="Alexandre Vaz | The Gold Standard Training" />
|
||||||
|
<meta property="og:description" content="O fim das desculpas. Transformação corporal de alto impacto, consultoria personalizada, nutrição de precisão e performance atlética." />
|
||||||
|
<meta property="og:image" content="https://images.unsplash.com/photo-1571019614242-c5c5dee9f50b?q=80&w=1200&auto=format&fit=crop" />
|
||||||
|
|
||||||
|
<!-- Twitter Cards -->
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:url" content="https://alexandrevaz.com/" />
|
||||||
|
<meta name="twitter:title" content="Alexandre Vaz | The Gold Standard Training" />
|
||||||
|
<meta name="twitter:description" content="O fim das desculpas. Transformação corporal de alto impacto, consultoria personalizada e performance atlética." />
|
||||||
|
<meta name="twitter:image" content="https://images.unsplash.com/photo-1571019614242-c5c5dee9f50b?q=80&w=1200&auto=format&fit=crop" />
|
||||||
|
|
||||||
|
<!-- Favicon -->
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🛡️</text></svg>">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
6
Template-01/metadata.json
Normal file
6
Template-01/metadata.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "Alexandre Vaz Elite",
|
||||||
|
"description": "High-end personal trainer premium website, single page application.",
|
||||||
|
"requestFramePermissions": [],
|
||||||
|
"majorCapabilities": []
|
||||||
|
}
|
||||||
4447
Template-01/package-lock.json
generated
Normal file
4447
Template-01/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
38
Template-01/package.json
Normal file
38
Template-01/package.json
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"name": "react-example",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --port=3000 --host=0.0.0.0",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"clean": "rm -rf dist",
|
||||||
|
"lint": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@google/genai": "^1.29.0",
|
||||||
|
"@tailwindcss/vite": "^4.1.14",
|
||||||
|
"@vitejs/plugin-react": "^5.0.4",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"dotenv": "^17.2.3",
|
||||||
|
"express": "^4.21.2",
|
||||||
|
"lucide-react": "^0.546.0",
|
||||||
|
"motion": "^12.23.24",
|
||||||
|
"react": "^19.0.1",
|
||||||
|
"react-dom": "^19.0.1",
|
||||||
|
"react-helmet-async": "^3.0.0",
|
||||||
|
"react-router-dom": "^7.15.0",
|
||||||
|
"tailwind-merge": "^3.5.0",
|
||||||
|
"vite": "^6.2.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/express": "^4.17.21",
|
||||||
|
"@types/node": "^22.14.0",
|
||||||
|
"autoprefixer": "^10.4.21",
|
||||||
|
"tailwindcss": "^4.1.14",
|
||||||
|
"tsx": "^4.21.0",
|
||||||
|
"typescript": "~5.8.2",
|
||||||
|
"vite": "^6.2.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
4
Template-01/public/robots.txt
Normal file
4
Template-01/public/robots.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
Sitemap: https://alexandrevaz.com/sitemap.xml
|
||||||
33
Template-01/public/sitemap.xml
Normal file
33
Template-01/public/sitemap.xml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>1.0</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/sobre</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/metodologia</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/blog</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>daily</changefreq>
|
||||||
|
<priority>0.9</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/contato</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
||||||
55
Template-01/src/App.tsx
Normal file
55
Template-01/src/App.tsx
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { BrowserRouter, Routes, Route, useLocation } from "react-router-dom";
|
||||||
|
import { AnimatePresence, motion } from "motion/react";
|
||||||
|
import Layout from "./components/Layout";
|
||||||
|
import Home from "./pages/Home";
|
||||||
|
import Sobre from "./pages/Sobre";
|
||||||
|
import Blog from "./pages/Blog";
|
||||||
|
import Contato from "./pages/Contato";
|
||||||
|
import BlogPost from "./pages/BlogPost";
|
||||||
|
import NotFound from "./pages/NotFound";
|
||||||
|
|
||||||
|
const PageTransition: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 15 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, y: -15 }}
|
||||||
|
transition={{ duration: 0.3, ease: "easeInOut" }}
|
||||||
|
className="flex flex-col flex-grow w-full"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AnimatedRoutes() {
|
||||||
|
const location = useLocation();
|
||||||
|
return (
|
||||||
|
<AnimatePresence mode="wait">
|
||||||
|
<Routes location={location}>
|
||||||
|
<Route path="/" element={<PageTransition key="home"><Home /></PageTransition>} />
|
||||||
|
<Route path="/sobre" element={<PageTransition key="sobre"><Sobre /></PageTransition>} />
|
||||||
|
<Route path="/blog" element={<PageTransition key="blog"><Blog /></PageTransition>} />
|
||||||
|
<Route path="/blog/:slug" element={<PageTransition key="post"><BlogPost /></PageTransition>} />
|
||||||
|
<Route path="/contato" element={<PageTransition key="contato"><Contato /></PageTransition>} />
|
||||||
|
<Route path="*" element={<PageTransition key="notfound"><NotFound /></PageTransition>} />
|
||||||
|
</Routes>
|
||||||
|
</AnimatePresence>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
return (
|
||||||
|
<BrowserRouter>
|
||||||
|
<Layout>
|
||||||
|
<AnimatedRoutes />
|
||||||
|
</Layout>
|
||||||
|
</BrowserRouter>
|
||||||
|
);
|
||||||
|
}
|
||||||
21
Template-01/src/components/Footer.tsx
Normal file
21
Template-01/src/components/Footer.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { ArrowUpRight, Instagram, Youtube, Twitter } from "lucide-react";
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className="w-full bg-[#050505] border-t border-white/5 py-4 px-6 lg:px-12 z-20 relative">
|
||||||
|
<div className="flex flex-col md:flex-row items-center justify-between text-[9px] uppercase tracking-[0.2em] font-medium text-white/30 gap-4">
|
||||||
|
<div>© {new Date().getFullYear()} Vanguard — High Performance Coaching</div>
|
||||||
|
<div className="flex space-x-8">
|
||||||
|
<a href="#" className="hover:text-white/60 transition-colors">Instagram</a>
|
||||||
|
<a href="#" className="hover:text-white/60 transition-colors">YouTube</a>
|
||||||
|
<a href="#" className="hover:text-white/60 transition-colors">LinkedIn</a>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<div className="w-1.5 h-1.5 bg-[#CCFF00] rounded-full animate-pulse"></div>
|
||||||
|
<span>Sistemas Online</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
28
Template-01/src/components/Layout.tsx
Normal file
28
Template-01/src/components/Layout.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Link, useLocation } from "react-router-dom";
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import Navbar from "./Navbar";
|
||||||
|
import Footer from "./Footer";
|
||||||
|
|
||||||
|
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||||
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}, [pathname]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen flex flex-col bg-[#050505] text-[#F5F5F5] selection:bg-[#CCFF00] selection:text-black relative overflow-hidden">
|
||||||
|
{/* Ambient backgrounds */}
|
||||||
|
<div className="fixed inset-0 opacity-20 pointer-events-none z-0">
|
||||||
|
<div className="absolute top-[-10%] left-[-10%] w-[50%] h-[50%] bg-[#FF3E00] rounded-full blur-[150px]"></div>
|
||||||
|
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-[#4A4A4A] rounded-full blur-[120px]"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col flex-grow z-10 relative">
|
||||||
|
<Navbar />
|
||||||
|
<main className="flex-grow pt-20 lg:pt-20">{children}</main>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
307
Template-01/src/components/Navbar.tsx
Normal file
307
Template-01/src/components/Navbar.tsx
Normal file
|
|
@ -0,0 +1,307 @@
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Link, useLocation } from "react-router-dom";
|
||||||
|
import { motion, AnimatePresence } from "motion/react";
|
||||||
|
import { Menu, X, Search, ChevronDown } from "lucide-react";
|
||||||
|
import { cn } from "../lib/utils";
|
||||||
|
import { posts } from "../pages/Blog";
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
{ name: "Início", path: "/" },
|
||||||
|
{ name: "Sobre o Treinador", path: "/sobre" },
|
||||||
|
{ name: "Blog", path: "/blog" },
|
||||||
|
{ name: "Contato", path: "/contato" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function Navbar() {
|
||||||
|
const [isScrolled, setIsScrolled] = useState(false);
|
||||||
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||||
|
const [searchOpen, setSearchOpen] = useState(false);
|
||||||
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
const [langMenuOpen, setLangMenuOpen] = useState(false);
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
const searchResults = searchQuery.trim() !== ""
|
||||||
|
? posts.filter(post =>
|
||||||
|
post.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
|
post.category.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
|
post.desc.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
|
).slice(0, 5) // Limits to 5 results
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const getLang = () => {
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
if (document.cookie.includes('googtrans=/pt/en')) return 'en';
|
||||||
|
if (document.cookie.includes('googtrans=/pt/es')) return 'es';
|
||||||
|
}
|
||||||
|
return 'pt';
|
||||||
|
};
|
||||||
|
const [currentLang, setCurrentLang] = useState(getLang());
|
||||||
|
|
||||||
|
const switchLang = (lang: string) => {
|
||||||
|
const host = window.location.hostname;
|
||||||
|
if (lang === 'pt') {
|
||||||
|
document.cookie = `googtrans=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
|
||||||
|
document.cookie = `googtrans=; expires=Thu, 01 Jan 1970 00:00:00 UTC; domain=.${host}; path=/;`;
|
||||||
|
} else {
|
||||||
|
document.cookie = `googtrans=/pt/${lang}; path=/`;
|
||||||
|
document.cookie = `googtrans=/pt/${lang}; domain=.${host}; path=/`;
|
||||||
|
}
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleScroll = () => {
|
||||||
|
setIsScrolled(window.scrollY > 20);
|
||||||
|
};
|
||||||
|
window.addEventListener("scroll", handleScroll);
|
||||||
|
return () => window.removeEventListener("scroll", handleScroll);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Close mobile menu on route change
|
||||||
|
useEffect(() => {
|
||||||
|
setMobileMenuOpen(false);
|
||||||
|
}, [location.pathname]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Only load script if not already present
|
||||||
|
if (!document.getElementById("google-translate-script")) {
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.id = "google-translate-script";
|
||||||
|
script.src = "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit";
|
||||||
|
|
||||||
|
const setupScript = document.createElement("script");
|
||||||
|
setupScript.innerHTML = `
|
||||||
|
function googleTranslateElementInit() {
|
||||||
|
new window.google.translate.TranslateElement({
|
||||||
|
pageLanguage: 'pt',
|
||||||
|
includedLanguages: 'pt,en,es',
|
||||||
|
autoDisplay: false
|
||||||
|
}, 'google_translate_element');
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(setupScript);
|
||||||
|
document.body.appendChild(script);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<AnimatePresence>
|
||||||
|
{searchOpen && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
exit={{ opacity: 0, scale: 0.95 }}
|
||||||
|
transition={{ duration: 0.2 }}
|
||||||
|
className="fixed inset-0 z-[100] bg-black/95 backdrop-blur-xl flex flex-col pt-32 px-6 lg:px-12"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={() => setSearchOpen(false)}
|
||||||
|
className="absolute top-8 right-6 lg:right-12 text-white/50 hover:text-white transition-colors"
|
||||||
|
aria-label="Fechar busca"
|
||||||
|
>
|
||||||
|
<X size={40} />
|
||||||
|
</button>
|
||||||
|
<div className="container mx-auto max-w-4xl w-full">
|
||||||
|
<span className="text-[#FF3E00] font-bold tracking-[0.2em] text-xs uppercase block mb-4 border-l-2 border-[#FF3E00] pl-4">Intel Search</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="PROCURAR..."
|
||||||
|
className="w-full bg-transparent border-b-2 border-white/20 text-4xl md:text-6xl text-white font-black italic uppercase outline-none py-4 placeholder:text-white/20 focus:border-[#FF3E00] transition-colors"
|
||||||
|
autoFocus
|
||||||
|
value={searchQuery}
|
||||||
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{searchQuery.trim() === "" ? (
|
||||||
|
<div className="mt-12 flex flex-wrap gap-6 items-center text-xs font-bold text-white/40 tracking-widest uppercase">
|
||||||
|
<span>Sugestões:</span>
|
||||||
|
<Link to="/blog" onClick={() => setSearchOpen(false)} className="hover:text-white transition-colors">Treinamento</Link>
|
||||||
|
<Link to="/sobre" onClick={() => setSearchOpen(false)} className="hover:text-white transition-colors">Mentoria</Link>
|
||||||
|
<Link to="/contato" onClick={() => setSearchOpen(false)} className="hover:text-white transition-colors">Consultoria</Link>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="mt-12 space-y-4 max-h-[50vh] overflow-y-auto pb-8 pr-4 custom-scrollbar">
|
||||||
|
{searchResults.length > 0 ? (
|
||||||
|
searchResults.map((post, index) => (
|
||||||
|
<Link
|
||||||
|
key={index}
|
||||||
|
to={`/blog/${posts.indexOf(post)}`}
|
||||||
|
state={{ post }}
|
||||||
|
onClick={() => {
|
||||||
|
setSearchOpen(false);
|
||||||
|
setSearchQuery("");
|
||||||
|
}}
|
||||||
|
className="block bg-white/5 border border-white/10 hover:border-[#FF3E00] p-6 transition-all group"
|
||||||
|
>
|
||||||
|
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
||||||
|
<div>
|
||||||
|
<span className="text-[#FF3E00] text-[10px] font-bold uppercase tracking-widest mb-2 block">{post.category}</span>
|
||||||
|
<h3 className="text-xl md:text-2xl font-black italic uppercase tracking-tighter group-hover:text-[#FF3E00] transition-colors">{post.title}</h3>
|
||||||
|
<p className="text-white/60 text-sm mt-2 line-clamp-1">{post.desc}</p>
|
||||||
|
</div>
|
||||||
|
<span className="text-white font-black uppercase tracking-widest text-[11px] whitespace-nowrap self-start md:self-auto border-b border-white group-hover:border-[#FF3E00] group-hover:text-[#FF3E00] transition-colors pb-1">
|
||||||
|
Ler Artigo
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="text-white/40 font-light text-xl italic mt-8 text-center uppercase tracking-widest">
|
||||||
|
Nenhum resultado encontrado para "{searchQuery}"
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
|
||||||
|
<header
|
||||||
|
className={cn(
|
||||||
|
"fixed top-0 left-0 right-0 z-50 transition-all duration-300",
|
||||||
|
isScrolled ? "bg-[#050505]/80 backdrop-blur-md border-b border-white/5 py-4" : "bg-transparent py-6"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl flex items-center justify-between">
|
||||||
|
<Link to="/" className="flex items-center gap-2 group">
|
||||||
|
<span className="text-2xl font-black tracking-tighter italic mr-1">VANGUARD</span>
|
||||||
|
<span className="text-[10px] uppercase tracking-[0.3em] font-bold text-[#FF3E00] hidden sm:block">Performance Elite</span>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{/* Desktop Nav */}
|
||||||
|
<nav className="hidden lg:flex items-center gap-10">
|
||||||
|
{links.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.path}
|
||||||
|
to={link.path}
|
||||||
|
className={cn(
|
||||||
|
"text-[11px] font-semibold tracking-widest uppercase transition-colors relative group",
|
||||||
|
location.pathname === link.path
|
||||||
|
? "text-[#FF3E00]"
|
||||||
|
: "text-[#F5F5F5] hover:text-[#FF3E00]"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{link.name}
|
||||||
|
{location.pathname === link.path && (
|
||||||
|
<motion.div
|
||||||
|
layoutId="navbar-indicator"
|
||||||
|
className="absolute -bottom-2 left-0 right-0 h-0.5 bg-primary-500"
|
||||||
|
initial={false}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div className="hidden lg:flex items-center gap-6">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-bold tracking-widest text-white/50 uppercase">
|
||||||
|
<button onClick={() => switchLang('pt')} className={`hover:text-white transition-colors ${currentLang === 'pt' ? 'text-white' : ''}`}>PT</button>
|
||||||
|
<span>/</span>
|
||||||
|
<button onClick={() => switchLang('en')} className={`hover:text-white transition-colors ${currentLang === 'en' ? 'text-white' : ''}`}>EN</button>
|
||||||
|
<span>/</span>
|
||||||
|
<button onClick={() => switchLang('es')} className={`hover:text-white transition-colors ${currentLang === 'es' ? 'text-white' : ''}`}>ES</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onClick={() => setSearchOpen(true)} className="text-white hover:text-[#FF3E00] transition-colors" aria-label="Buscar">
|
||||||
|
<Search size={20} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
to="/contato"
|
||||||
|
className="border border-white/20 px-6 py-2 rounded-full hover:bg-white hover:text-black transition-all text-[11px] uppercase tracking-widest font-semibold"
|
||||||
|
>
|
||||||
|
Consultoria
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right side controls */}
|
||||||
|
<div className="flex items-center gap-3 lg:gap-0 lg:ml-4">
|
||||||
|
<div id="google_translate_element" className="hidden"></div>
|
||||||
|
|
||||||
|
<div className="lg:hidden flex items-center gap-3">
|
||||||
|
<div className="relative text-[10px] font-bold tracking-widest text-white uppercase">
|
||||||
|
<button
|
||||||
|
onClick={() => setLangMenuOpen(!langMenuOpen)}
|
||||||
|
className="flex items-center gap-1 hover:text-[#FF3E00] transition-colors p-2"
|
||||||
|
>
|
||||||
|
{currentLang.toUpperCase()} <ChevronDown size={14} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{langMenuOpen && (
|
||||||
|
<div className="absolute top-10 left-1/2 -translate-x-1/2 bg-[#050505] border border-white/10 rounded-sm shadow-xl flex flex-col min-w-[60px] overflow-hidden z-50">
|
||||||
|
{['pt', 'en', 'es'].map(lang => (
|
||||||
|
<button
|
||||||
|
key={lang}
|
||||||
|
onClick={() => {
|
||||||
|
switchLang(lang);
|
||||||
|
setLangMenuOpen(false);
|
||||||
|
}}
|
||||||
|
className={`px-4 py-3 text-center transition-colors hover:bg-white/5 ${currentLang === lang ? 'text-[#FF3E00]' : 'text-white/60 hover:text-white'}`}
|
||||||
|
>
|
||||||
|
{lang.toUpperCase()}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onClick={() => setSearchOpen(true)} className="text-white hover:text-[#FF3E00] transition-colors p-2" aria-label="Buscar">
|
||||||
|
<Search size={20} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu Toggle */}
|
||||||
|
<button
|
||||||
|
className="lg:hidden text-white p-2 focus:outline-none"
|
||||||
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||||
|
aria-label="Toggle Menu"
|
||||||
|
>
|
||||||
|
{mobileMenuOpen ? <X size={28} /> : <Menu size={28} />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{/* Mobile Menu Content */}
|
||||||
|
<AnimatePresence>
|
||||||
|
{mobileMenuOpen && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: -20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, y: -20 }}
|
||||||
|
transition={{ duration: 0.2 }}
|
||||||
|
className="fixed inset-0 z-40 bg-[#050505] pt-24 px-6 pb-6 flex flex-col"
|
||||||
|
>
|
||||||
|
<nav className="flex flex-col gap-6 items-center justify-center flex-grow">
|
||||||
|
{links.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.path}
|
||||||
|
to={link.path}
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
className={cn(
|
||||||
|
"font-black italic uppercase tracking-tighter text-3xl md:text-5xl transition-colors",
|
||||||
|
location.pathname === link.path
|
||||||
|
? "text-[#FF3E00]"
|
||||||
|
: "text-white hover:text-[#FF3E00]"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{link.name}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
<Link
|
||||||
|
to="/contato"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
className="mt-8 px-8 py-5 border border-white/20 text-white font-black uppercase tracking-widest text-[11px] text-center w-full max-w-[280px] hover:bg-white hover:text-black transition-colors"
|
||||||
|
>
|
||||||
|
Agendar Reunião Estratégica
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
44
Template-01/src/components/SEO.tsx
Normal file
44
Template-01/src/components/SEO.tsx
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Helmet } from 'react-helmet-async';
|
||||||
|
|
||||||
|
interface SEOProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
url?: string;
|
||||||
|
image?: string;
|
||||||
|
type?: string;
|
||||||
|
schema?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SEO({ title, description, url, image, type = "website", schema }: SEOProps) {
|
||||||
|
const siteName = "MacroLojaUK | Treinamento de Elite";
|
||||||
|
const defaultImage = "https://images.unsplash.com/photo-1581009146145-b5ef050c2e1e?q=80&w=1200&auto=format&fit=crop";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Helmet>
|
||||||
|
<title>{title}</title>
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
|
||||||
|
{/* Open Graph / Facebook */}
|
||||||
|
<meta property="og:type" content={type} />
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
{url && <meta property="og:url" content={url} />}
|
||||||
|
<meta property="og:image" content={image || defaultImage} />
|
||||||
|
<meta property="og:site_name" content={siteName} />
|
||||||
|
|
||||||
|
{/* Twitter */}
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:title" content={title} />
|
||||||
|
<meta name="twitter:description" content={description} />
|
||||||
|
<meta name="twitter:image" content={image || defaultImage} />
|
||||||
|
|
||||||
|
{/* Structured Data / JSON-LD */}
|
||||||
|
{schema && (
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{JSON.stringify(schema)}
|
||||||
|
</script>
|
||||||
|
)}
|
||||||
|
</Helmet>
|
||||||
|
);
|
||||||
|
}
|
||||||
101
Template-01/src/index.css
Normal file
101
Template-01/src/index.css
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,300;0,400;0,500;0,600;0,700;0,900;1,400;1,700;1,900&display=swap');
|
||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||||
|
--font-heading: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||||
|
|
||||||
|
--color-primary-500: #FF3E00;
|
||||||
|
--color-primary-600: #CC3200;
|
||||||
|
|
||||||
|
--color-neutral-850: #1a1a1a;
|
||||||
|
--color-neutral-950: #050505;
|
||||||
|
|
||||||
|
--animate-accordion-down: accordion-down 0.2s ease-out;
|
||||||
|
--animate-accordion-up: accordion-up 0.2s ease-out;
|
||||||
|
|
||||||
|
@keyframes accordion-down {
|
||||||
|
from { height: 0 }
|
||||||
|
to { height: var(--radix-accordion-content-height) }
|
||||||
|
}
|
||||||
|
@keyframes accordion-up {
|
||||||
|
from { height: var(--radix-accordion-content-height) }
|
||||||
|
to { height: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
background-color: #050505;
|
||||||
|
color: #F5F5F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background-color: #CCFF00;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
/* Prevent horizontal scroll on mobile */
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-color: #050505;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide scrollbar for clean look */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #050505;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #333;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-stroke {
|
||||||
|
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.2);
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
.text-stroke-primary {
|
||||||
|
-webkit-text-stroke: 1px theme('colors.primary.500');
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass-panel {
|
||||||
|
background: rgba(20, 20, 20, 0.6);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading-impact {
|
||||||
|
font-family: var(--font-heading);
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Google Translate overrides */
|
||||||
|
#google_translate_element {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.goog-te-banner-frame.skiptranslate,
|
||||||
|
.skiptranslate > iframe.goog-te-banner-frame {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
top: 0px !important;
|
||||||
|
position: static !important;
|
||||||
|
}
|
||||||
|
#goog-gt-tt, .goog-te-balloon-frame {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.goog-text-highlight {
|
||||||
|
background-color: transparent !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
6
Template-01/src/lib/utils.ts
Normal file
6
Template-01/src/lib/utils.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { clsx, type ClassValue } from "clsx";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs));
|
||||||
|
}
|
||||||
13
Template-01/src/main.tsx
Normal file
13
Template-01/src/main.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import {StrictMode} from 'react';
|
||||||
|
import {createRoot} from 'react-dom/client';
|
||||||
|
import { HelmetProvider } from 'react-helmet-async';
|
||||||
|
import App from './App.tsx';
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
createRoot(document.getElementById('root')!).render(
|
||||||
|
<StrictMode>
|
||||||
|
<HelmetProvider>
|
||||||
|
<App />
|
||||||
|
</HelmetProvider>
|
||||||
|
</StrictMode>,
|
||||||
|
);
|
||||||
284
Template-01/src/pages/Blog.tsx
Normal file
284
Template-01/src/pages/Blog.tsx
Normal file
|
|
@ -0,0 +1,284 @@
|
||||||
|
import React, { useRef } from "react";
|
||||||
|
import { motion, useScroll, useTransform } from "motion/react";
|
||||||
|
import { ArrowRight, Clock, User, Tag } from "lucide-react";
|
||||||
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
export const posts = [
|
||||||
|
{
|
||||||
|
category: "Treinamento",
|
||||||
|
title: "O Fim do Platô: Técnicas Avançadas de Intensidade",
|
||||||
|
desc: "Descubra como utilizar Rest-Pause, Drop-Sets e Cluster Sets para forçar seu corpo a construir novos tecidos e quebrar estagnação.",
|
||||||
|
img: "https://images.unsplash.com/photo-1541534741688-6078c6bfb5c5?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "8 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Nutrição",
|
||||||
|
title: "Ciclo de Carboidratos para Secar Rápido",
|
||||||
|
desc: "A estratégia nutricional dos fisiculturistas adaptada para quem quer baixar o BF para menos de 10% sem perder volume muscular.",
|
||||||
|
img: "https://images.unsplash.com/photo-1490645935967-10de6ba17061?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "12 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Mindset",
|
||||||
|
title: "A Psicologia da Disciplina Inabalável",
|
||||||
|
desc: "Por que você desiste após 3 semanas? O modelo mental necessário para encarar a dieta restrita como uma vitória diária.",
|
||||||
|
img: "https://images.unsplash.com/photo-1517836357463-d25dfeac3438?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "5 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Suplementação",
|
||||||
|
title: "Guia Definitivo da Creatina",
|
||||||
|
desc: "O único suplemento que você realmente precisa. Mitos, verdades e como saturar de forma correta para aumento de força bruta.",
|
||||||
|
img: "https://images.unsplash.com/photo-1593095948071-474c5cc2989d?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "6 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Treinamento",
|
||||||
|
title: "Cardio vs. Musculação: A Ordem Importa?",
|
||||||
|
desc: "Entenda a sinalização molecular e por que fazer cardio antes do treino pesado pode estar aniquilando seus ganhos de hipertrofia.",
|
||||||
|
img: "https://images.unsplash.com/photo-1538805060514-97d9cc17730c?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "7 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Recuperação",
|
||||||
|
title: "Dormir é Anabólico: A Importância do Sono REM",
|
||||||
|
desc: "Você não cresce na academia, cresce na cama. Estratégias de higiene do sono para maximizar a liberação de GH natural.",
|
||||||
|
img: "https://images.unsplash.com/photo-1544367567-0f2fcb009e0b?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "9 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Treinamento",
|
||||||
|
title: "Falha Muscular: O Quanto é Suficiente?",
|
||||||
|
desc: "Não confunda cansaço com falha. Aprenda a atingir a falha concêntrica verdadeira sem destruir seu sistema nervoso central.",
|
||||||
|
img: "https://images.unsplash.com/photo-1571019614242-c5c5dee9f50b?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "10 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Nutrição",
|
||||||
|
title: "Proteína: Mais Não é Necessariamente Melhor",
|
||||||
|
desc: "A ciência real sobre absorção proteica. Você realmente precisa de 3g por kg corporal para construir miócitos em abundância?",
|
||||||
|
img: "https://images.unsplash.com/photo-1507398941214-572c25f4b1dc?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "8 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Mindset",
|
||||||
|
title: "Sofra o Processo, Aproveite o Resultado",
|
||||||
|
desc: "O estoicismo aplicado ao bodybuilding. Como transformar a dor do treino e a restrição da dieta em combustível mental.",
|
||||||
|
img: "https://images.unsplash.com/photo-1526506159807-1c00ba4ce19b?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "6 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Treinamento",
|
||||||
|
title: "Biomecânica Básica para Supino Inversamente Proporcional",
|
||||||
|
desc: "Dores no ombro? Seu supino provavelmente está errado. Ajustes milimétricos na pegada e na ponte que mudam o recrutamento peitoral.",
|
||||||
|
img: "https://images.unsplash.com/photo-1581009146145-b5ef050c2e1e?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "11 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Nutrição",
|
||||||
|
title: "Jejum Intermitente Funciona para Hipertrofia?",
|
||||||
|
desc: "As vias AMPK e mTOR estão em guerra no seu corpo. Como usar o jejum para otimizar a sensibilidade à insulina e evitar perda muscular.",
|
||||||
|
img: "https://images.unsplash.com/photo-1505253758473-96b7015fcd40?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "14 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Suplementação",
|
||||||
|
title: "Beta-Alanina: O Fim da Fadiga Muscular",
|
||||||
|
desc: "A biologia do ácido lático e como a carnosina gerada pela beta-alanina pode adicionar 2 reps extras na sua série mais pesada.",
|
||||||
|
img: "https://images.unsplash.com/photo-1554284126-aa88f22d8b74?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "7 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Treinamento",
|
||||||
|
title: "Treinando Costas em V: Largura vs Espessura",
|
||||||
|
desc: "Puxadas vs Remadas. A combinação exata de vetores de força que você precisa para desenvolver o shape em V perfeito.",
|
||||||
|
img: "https://images.unsplash.com/photo-1534438327276-14e5300c3a48?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "9 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Recuperação",
|
||||||
|
title: "Alongamento: Antes ou Depois do Treino?",
|
||||||
|
desc: "A ciência comprova que alongar estático antes do treino reduz sua força em até 8%. O protocolo correto de mobilidade.",
|
||||||
|
img: "https://images.unsplash.com/photo-1601422407692-ec4eeec1d9b3?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "5 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Mindset",
|
||||||
|
title: "Como Lidar com Lesões Sem Perder a Razão",
|
||||||
|
desc: "Uma lesão não é o fim do seu planejamento. Estratégias táticas para manter a dieta e treinar no entorno do problema articular.",
|
||||||
|
img: "https://images.unsplash.com/photo-1518611012118-696072aa579a?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "8 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Treinamento",
|
||||||
|
title: "Agachamento Livre: O Rei Incontestável",
|
||||||
|
desc: "Um raio X do movimento base da musculação. Como agachar pesado sem destruir a lombar e maximizando o quadríceps.",
|
||||||
|
img: "https://images.unsplash.com/photo-1434596922112-19c563067271?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "12 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Nutrição",
|
||||||
|
title: "Refeição Lixo: A Ciência do Cheat Meal",
|
||||||
|
desc: "Refeed programado não é 'festa no Mcdonalds'. Entenda como restaurar os níveis de leptina do jeito certo para continuar queimando gordura.",
|
||||||
|
img: "https://images.unsplash.com/photo-1565299624946-b28f40a0ae38?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "10 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Suplementação",
|
||||||
|
title: "Whey Protein: Concentrado, Isolado ou Hidrolisado?",
|
||||||
|
desc: "O marketing tenta te vender o mais caro. Descubra qual é a real necessidade de cada tipo de Whey de acordo com seu objetivo.",
|
||||||
|
img: "https://images.unsplash.com/photo-1579722820308-d74e571900a9?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "4 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Treinamento",
|
||||||
|
title: "Panturrilhas: Genética Maldita ou Falta de Treino?",
|
||||||
|
desc: "As panturrilhas são músculos de resistência extrema. O método de choque e altas repetições focado na fase excêntrica.",
|
||||||
|
img: "https://images.unsplash.com/photo-1583454110551-21f2fa2afe61?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "6 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Recuperação",
|
||||||
|
title: "A Verdade Sobre Banho de Gelo e Hipertrofia",
|
||||||
|
desc: "Imersão em gelo pós-treino acelera a recuperação, mas bloqueia o estresse oxidativo necessário para hipertrofia. Cuidado.",
|
||||||
|
img: "https://images.unsplash.com/photo-1515444744559-7be63e160e1d?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "7 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Mindset",
|
||||||
|
title: "A Força da Rotina Matinal Perfeita",
|
||||||
|
desc: "Como as primeiras 2 horas do seu dia definem seu sucesso. Água, sol, cardio em jejum e blindagem mental para evitar falhas.",
|
||||||
|
img: "https://images.unsplash.com/photo-1506126613408-eca07ce68773?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "10 min"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function FeaturedPost() {
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const { scrollYProgress } = useScroll({
|
||||||
|
target: ref,
|
||||||
|
offset: ["start end", "end start"]
|
||||||
|
});
|
||||||
|
const y = useTransform(scrollYProgress, [0, 1], ["-10%", "10%"]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ref} className="relative group overflow-hidden border border-white/10 bg-white/5 flex flex-col md:flex-row h-auto md:h-[500px]">
|
||||||
|
<div className="w-full md:w-1/2 h-64 md:h-full relative overflow-hidden">
|
||||||
|
<motion.div style={{ y }} className="absolute top-[-10%] left-0 w-full h-[120%]">
|
||||||
|
<img src="https://images.unsplash.com/photo-1581009146145-b5ef050c2e1e?q=80&w=1200&auto=format&fit=crop" className="w-full h-full object-cover grayscale opacity-60 group-hover:grayscale-0 group-hover:scale-105 transition-all duration-700 origin-center" alt="Featured" />
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full md:w-1/2 p-8 md:p-16 flex flex-col justify-center">
|
||||||
|
<div className="flex items-center gap-4 mb-6">
|
||||||
|
<span className="bg-black border border-white/10 text-[#FF3E00] text-[10px] font-bold uppercase tracking-widest px-3 py-1 relative z-10">Biomecânica</span>
|
||||||
|
<div className="flex items-center gap-1 text-[10px] text-white/40 uppercase tracking-widest font-bold relative z-10">
|
||||||
|
<Clock className="w-3 h-3" /> 15 Min Leitura
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Link to="/blog/1" state={{ post: { category: "Biomecânica", title: "A Mentira Sobre o Treino Fofo e o Volume Lixo", desc: "A indústria fitness quer que você passe duas horas na academia fazendo exercícios ineficientes. Aprenda a focar na progressão de carga e na falha real para estimular o crescimento verdadeiro.", img: "https://images.unsplash.com/photo-1581009146145-b5ef050c2e1e?q=80&w=1200&auto=format&fit=crop", readTime: "15 min" } }} className="text-[30px] md:text-[50px] font-black italic uppercase tracking-tighter mb-6 hover:text-[#FF3E00] transition-colors cursor-pointer leading-[0.9] block relative z-10">A Mentira Sobre o Treino Fofo e o Volume Lixo</Link>
|
||||||
|
<p className="text-white/60 font-light mb-8 line-clamp-3 text-sm relative z-10">
|
||||||
|
A indústria fitness quer que você passe duas horas na academia fazendo exercícios ineficientes. Aprenda a focar na progressão de carga e na falha real para estimular o crescimento verdadeiro.
|
||||||
|
</p>
|
||||||
|
<div className="mt-auto relative z-10">
|
||||||
|
<Link to="/blog/1" state={{ post: { category: "Biomecânica", title: "A Mentira Sobre o Treino Fofo e o Volume Lixo", desc: "A indústria fitness quer que você passe duas horas na academia fazendo exercícios ineficientes. Aprenda a focar na progressão de carga e na falha real para estimular o crescimento verdadeiro.", img: "https://images.unsplash.com/photo-1581009146145-b5ef050c2e1e?q=80&w=1200&auto=format&fit=crop", readTime: "15 min" } }} className="inline-flex items-center gap-2 text-white font-black uppercase tracking-widest text-[11px] hover:text-[#FF3E00] transition-colors border-b border-white hover:border-[#FF3E00] pb-1 cursor-pointer">
|
||||||
|
Ler Artigo Completo <ArrowRight className="w-4 h-4 ml-1" />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PostCard: React.FC<{ post: any, index: number }> = ({ post, index }) => {
|
||||||
|
const ref = useRef<HTMLAnchorElement>(null);
|
||||||
|
const { scrollYProgress } = useScroll({
|
||||||
|
target: ref,
|
||||||
|
offset: ["start end", "end start"]
|
||||||
|
});
|
||||||
|
const y = useTransform(scrollYProgress, [0, 1], ["-15%", "15%"]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link to={`/blog/${index+2}`} state={{ post }} ref={ref} className="h-full block">
|
||||||
|
<motion.article
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: (index % 3) * 0.1 }}
|
||||||
|
className="bg-transparent border border-white/10 hover:border-[#FF3E00]/50 transition-all flex flex-col group cursor-pointer overflow-hidden p-6 hover:bg-white/5 h-full"
|
||||||
|
>
|
||||||
|
<div className="relative h-56 overflow-hidden w-[calc(100%+3rem)] -mx-6 -mt-6 mb-6">
|
||||||
|
<motion.div style={{ y }} className="absolute top-[-15%] left-0 w-full h-[130%]">
|
||||||
|
<img src={post.img} className="w-full h-full object-cover grayscale opacity-70 group-hover:grayscale-0 group-hover:scale-105 transition-all duration-500 origin-center" alt={post.title} />
|
||||||
|
</motion.div>
|
||||||
|
<div className="absolute bottom-0 right-0 bg-black text-[#FF3E00] px-3 py-1 text-[10px] font-black uppercase tracking-widest z-10">
|
||||||
|
{post.category}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col flex-grow">
|
||||||
|
<h3 className="text-[22px] font-black italic uppercase tracking-tighter mb-4 group-hover:text-[#FF3E00] transition-colors line-clamp-2">{post.title}</h3>
|
||||||
|
<p className="text-xs text-white/50 font-light mb-6 flex-grow line-clamp-3">{post.desc}</p>
|
||||||
|
<div className="flex items-center justify-between mt-auto pt-4 border-t border-white/10">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] uppercase tracking-widest font-bold text-white/40">
|
||||||
|
<Clock className="w-3 h-3" /> {post.readTime}
|
||||||
|
</div>
|
||||||
|
<ArrowRight className="w-4 h-4 text-white/40 group-hover:text-[#FF3E00] transition-colors" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.article>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Blog() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col pt-10">
|
||||||
|
<SEO
|
||||||
|
title="Intel Briefing: Blog | MacroLojaUK"
|
||||||
|
description="Conteúdo tático sobre treinamento, nutrição e mindset. Artigos diretos, sem enrolação e baseados em ciência aplicável."
|
||||||
|
/>
|
||||||
|
<section className="py-32 lg:py-48 bg-[#050505] relative z-10 border-t border-white/5">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl text-center">
|
||||||
|
<span className="text-[#FF3E00] font-bold tracking-[0.2em] text-xs uppercase block mb-6">Intel Briefing</span>
|
||||||
|
<h1 className="text-6xl sm:text-[70px] md:text-[130px] leading-[0.85] font-black tracking-tighter uppercase italic mb-8">
|
||||||
|
CONTEÚDO <br/><span className="text-white/40">TÁTICO.</span>
|
||||||
|
</h1>
|
||||||
|
<p className="text-white/60 text-xl max-w-2xl mx-auto font-light leading-relaxed">
|
||||||
|
Artigos diretos, sem enrolação e baseados em ciência aplicável. A teoria por trás dos resultados extremos.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="py-20 bg-[#050505] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
{/* Featured Post (First one) */}
|
||||||
|
<div className="mb-20">
|
||||||
|
<FeaturedPost />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Grid Posts */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
|
{posts.map((post, i) => (
|
||||||
|
<PostCard post={post} index={i} key={`post-${i}`} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Newsletter */}
|
||||||
|
<section className="py-24 bg-[#050505] border-t-2 border-[#FF3E00] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-3xl text-center">
|
||||||
|
<h2 className="text-[40px] md:text-[60px] font-black italic tracking-tighter uppercase mb-4">DOSES DIÁRIAS DE <span className="text-white/40">DISCIPLINA</span></h2>
|
||||||
|
<p className="text-white/60 mb-8 font-light text-sm max-w-lg mx-auto">Junte-se a mais de 15.000 pessoas que recebem sacadas de treino, nutrição e mentalidade toda segunda-feira de manhã.</p>
|
||||||
|
<form className="flex flex-col sm:flex-row gap-2 max-w-lg mx-auto">
|
||||||
|
<input type="email" placeholder="SEU MELHOR E-MAIL" className="flex-grow bg-[#050505] border border-white/20 px-4 py-3 text-white placeholder-white/40 focus:outline-none focus:border-[#FF3E00] transition-colors uppercase text-[10px] tracking-widest font-semibold" />
|
||||||
|
<button type="button" className="bg-white text-black font-black uppercase tracking-widest hover:bg-[#FF3E00] hover:text-white transition-colors px-10 py-5 text-[11px]">
|
||||||
|
Assinar
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
141
Template-01/src/pages/BlogPost.tsx
Normal file
141
Template-01/src/pages/BlogPost.tsx
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
import { useLocation, useNavigate, Link } from "react-router-dom";
|
||||||
|
import { ArrowLeft, Clock } from "lucide-react";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { motion, useScroll, useSpring } from "motion/react";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
export default function BlogPost() {
|
||||||
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const post = location.state?.post;
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
const { scrollYProgress } = useScroll();
|
||||||
|
const scaleX = useSpring(scrollYProgress, {
|
||||||
|
stiffness: 100,
|
||||||
|
damping: 30,
|
||||||
|
restDelta: 0.001
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleCopyLink = () => {
|
||||||
|
navigator.clipboard.writeText(window.location.href);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!post) {
|
||||||
|
return (
|
||||||
|
<div className="w-full min-h-screen flex flex-col items-center justify-center bg-[#050505]">
|
||||||
|
<h1 className="text-white text-2xl font-black italic">ARTIGO NÃO ENCONTRADO</h1>
|
||||||
|
<button onClick={() => navigate("/blog")} className="mt-6 border border-white/20 px-6 py-3 text-white uppercase text-xs tracking-widest font-bold hover:border-[#FF3E00] hover:text-[#FF3E00] transition-colors">
|
||||||
|
Voltar para o Blog
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "Article",
|
||||||
|
"headline": post.title,
|
||||||
|
"image": post.img,
|
||||||
|
"author": {
|
||||||
|
"@type": "Person",
|
||||||
|
"name": "Alexandre Vaz"
|
||||||
|
},
|
||||||
|
"publisher": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "MacroLojaUK",
|
||||||
|
"logo": {
|
||||||
|
"@type": "ImageObject",
|
||||||
|
"url": "https://images.unsplash.com/photo-1570295999919-56ceb5ecca61?w=100&h=100&fit=crop"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": post.desc
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col pt-10">
|
||||||
|
<SEO
|
||||||
|
title={`${post.title} | MacroLojaUK`}
|
||||||
|
description={post.desc}
|
||||||
|
image={post.img}
|
||||||
|
type="article"
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
<motion.div
|
||||||
|
className="fixed top-0 left-0 right-0 h-1 bg-[#FF3E00] origin-left z-50"
|
||||||
|
style={{ scaleX }}
|
||||||
|
/>
|
||||||
|
<section className="py-20 bg-[#050505] relative z-10">
|
||||||
|
<div className="max-w-4xl mx-auto px-6">
|
||||||
|
<button onClick={() => navigate(-1)} className="inline-flex items-center gap-2 text-white/50 hover:text-white transition-colors mb-10 text-[10px] uppercase font-bold tracking-widest">
|
||||||
|
<ArrowLeft className="w-4 h-4" /> Voltar
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-4 mb-6">
|
||||||
|
<span className="bg-black border border-white/10 text-[#FF3E00] text-[10px] font-bold uppercase tracking-widest px-3 py-1">{post.category}</span>
|
||||||
|
<div className="flex items-center gap-1 text-[10px] text-white/40 uppercase tracking-widest font-bold">
|
||||||
|
<Clock className="w-3 h-3" /> {post.readTime}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className="text-[40px] md:text-[60px] leading-[0.9] font-black tracking-tighter uppercase italic mb-8">{post.title}</h1>
|
||||||
|
<p className="text-xl text-white/70 font-light mb-12 border-l-2 border-[#FF3E00] pl-6">{post.desc}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="max-w-5xl mx-auto px-6 mb-16">
|
||||||
|
<img src={post.img} alt={post.title} className="w-full h-[60vh] object-cover grayscale opacity-90 border border-white/10" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="max-w-3xl mx-auto px-6">
|
||||||
|
<div className="text-white/70 font-light text-lg space-y-8 leading-relaxed">
|
||||||
|
<p>
|
||||||
|
Quando o assunto é a busca pela excelência na composição corporal, o que mais vemos por aí sāo informações diluídas, repletas de meias verdades ou conselhos criados para agradar o público geral. Porém, a realidade é muito mais agressiva e direta. Nós não estamos aqui para adotar métodos recreativos nem para fingir que a evolução acontece sem um nível extraordinário de sofrimento intencional.
|
||||||
|
</p>
|
||||||
|
<h2 className="text-3xl font-black italic uppercase tracking-tighter text-white mt-12 mb-6">A BASE DO PROBLEMA</h2>
|
||||||
|
<p>
|
||||||
|
A maioria dos indivíduos peca não por falta de vontade, mas por seguir prescrições erradas. A indústria criou uma cultura de conveniência em que "treinar fofo" e dietas hiper permissivas tornaram-se o padrão. Mas é preciso entender um princípio básico de engenharia biológica: o corpo não muda se não for forçado através do princípio da sobrecarga progressiva e restrição estratégica. Por isso nossa <Link to="/metodologia" className="text-[#FF3E00] hover:underline font-bold">Metodologia Exclusiva</Link> é focada em resultados reais e inegociáveis.
|
||||||
|
</p>
|
||||||
|
<blockquote className="border-l-4 border-[#FF3E00] pl-6 my-10 italic text-2xl font-bold text-white max-w-2xl">
|
||||||
|
"Se o seu treino não te assusta um pouco, ele provavelmente não está fazendo você crescer."
|
||||||
|
</blockquote>
|
||||||
|
<h2 className="text-3xl font-black italic uppercase tracking-tighter text-white mt-12 mb-6">ESTRUTURAÇÃO TÁTICA</h2>
|
||||||
|
<p>
|
||||||
|
Para garantir resultados severos, precisamos de três pilares inegociáveis:
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc pl-6 space-y-4">
|
||||||
|
<li><strong className="font-bold text-white">Intensidade Real:</strong> Você deve estar próximo à falha mecânica. Parar com 5 repetições em reserva não é estímulo, é aquecimento.</li>
|
||||||
|
<li><strong className="font-bold text-white">Nutrição de Precisão:</strong> O cálculo de macronutrientes não serve apenas para contar calorias, mas para gerenciar a sinalização hormonal. Insulina, cortisol e testosterona ditam as regras.</li>
|
||||||
|
<li><strong className="font-bold text-white">Recuperação Fria:</strong> O sono não é luxo, é onde o tecido que foi destruído no salão de pesos é efetivamente construído. Todo o seu esforço é validado enquanto você dorme.</li>
|
||||||
|
</ul>
|
||||||
|
<h2 className="text-3xl font-black italic uppercase tracking-tighter text-white mt-12 mb-6">A APLICAÇÃO METÓDICA</h2>
|
||||||
|
<p>
|
||||||
|
Voltando ao tema central: {post.desc.toLowerCase()} Como colocar isso na prática? Pare de procurar atalhos. A melhor hora para consertar seus métodos foi há 6 meses. A segunda melhor é hoje. Mapeie suas deficiências e trace um plano de ataque contínuo para as próximas 12 semanas. Sem interrupções, sem falhas operacionais, sem desculpas.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Aplique as variáveis descritas neste artigo no seu próximo microciclo de treinos ou na sua próxima organização de macros e veja a diferença clara entre atuar como um iniciante e operar como um arquiteto do próprio físico. Se você não quer mais perder tempo e deseja um plano agressivo feito sob medida, preencha agora a <Link to="/contato" className="text-[#FF3E00] hover:underline font-bold">Aplicação de Consultoria</Link> e veja se você está pronto para trabalhar conosco.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-20 pt-10 border-t border-white/10 flex flex-col md:flex-row justify-between items-center gap-6">
|
||||||
|
<div>
|
||||||
|
<span className="text-[10px] uppercase tracking-widest text-[#FF3E00] font-bold block mb-2">Compartilhe este conhecimento</span>
|
||||||
|
<div className="flex flex-wrap gap-4">
|
||||||
|
<button onClick={() => window.open(`https://twitter.com/intent/tweet?url=${encodeURIComponent(window.location.href)}&text=${encodeURIComponent(post.title)}`, '_blank')} className="text-white/50 hover:text-white transition-colors text-xs uppercase font-bold tracking-widest border border-white/20 px-4 py-2 hover:border-white">Twitter</button>
|
||||||
|
<button onClick={() => window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(window.location.href)}`, '_blank')} className="text-white/50 hover:text-white transition-colors text-xs uppercase font-bold tracking-widest border border-white/20 px-4 py-2 hover:border-white">Facebook</button>
|
||||||
|
<button onClick={() => window.open(`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(window.location.href)}`, '_blank')} className="text-white/50 hover:text-white transition-colors text-xs uppercase font-bold tracking-widest border border-white/20 px-4 py-2 hover:border-white">LinkedIn</button>
|
||||||
|
<button onClick={handleCopyLink} className={`transition-colors text-xs uppercase font-bold tracking-widest border px-4 py-2 ${copied ? "text-[#FF3E00] border-[#FF3E00] shadow-[0_0_10px_rgba(255,62,0,0.3)]" : "text-white/50 hover:text-white border-white/20 hover:border-white"}`}>
|
||||||
|
{copied ? "Link Copiado!" : "Copiar Link"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
233
Template-01/src/pages/Contato.tsx
Normal file
233
Template-01/src/pages/Contato.tsx
Normal file
|
|
@ -0,0 +1,233 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import { Mail, MessageSquare, MapPin, Send } from "lucide-react";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
export default function Contato() {
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [nameError, setNameError] = useState("");
|
||||||
|
const [whatsapp, setWhatsapp] = useState("");
|
||||||
|
const [whatsappError, setWhatsappError] = useState("");
|
||||||
|
const [objective, setObjective] = useState("Emagrecimento Agressivo");
|
||||||
|
const [motivation, setMotivation] = useState("");
|
||||||
|
const [motivationError, setMotivationError] = useState("");
|
||||||
|
const [isSubmitted, setIsSubmitted] = useState(false);
|
||||||
|
|
||||||
|
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const val = e.target.value;
|
||||||
|
setName(val);
|
||||||
|
if (val.length > 0 && val.length < 3) {
|
||||||
|
setNameError("O nome deve ter pelo menos 3 caracteres.");
|
||||||
|
} else {
|
||||||
|
setNameError("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleWhatsappChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const val = e.target.value;
|
||||||
|
setWhatsapp(val);
|
||||||
|
if (val.length > 0 && !/^[0-9\s()+\-]+$/.test(val)) {
|
||||||
|
setWhatsappError("Apenas números, parênteses, espaços, traços e + são permitidos.");
|
||||||
|
} else {
|
||||||
|
setWhatsappError("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMotivationChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
const val = e.target.value;
|
||||||
|
setMotivation(val);
|
||||||
|
if (val.length > 0 && val.length < 10) {
|
||||||
|
setMotivationError("Descreva sua determinação com mais detalhes (mín. 10 caracteres).");
|
||||||
|
} else {
|
||||||
|
setMotivationError("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let isValid = true;
|
||||||
|
|
||||||
|
if (name.length < 3) {
|
||||||
|
setNameError("O nome deve ter pelo menos 3 caracteres.");
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
if (!whatsapp || (whatsapp.length > 0 && !/^[0-9\s()+\-]+$/.test(whatsapp))) {
|
||||||
|
setWhatsappError("Apenas números, parênteses, espaços, traços e + são permitidos.");
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
if (motivation.length < 10) {
|
||||||
|
setMotivationError("Descreva sua determinação com mais detalhes (mín. 10 caracteres).");
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid) {
|
||||||
|
// Logic for successful submission can go here
|
||||||
|
console.log("Formulário validado com sucesso!");
|
||||||
|
setIsSubmitted(true);
|
||||||
|
setName("");
|
||||||
|
setWhatsapp("");
|
||||||
|
setObjective("Emagrecimento Agressivo");
|
||||||
|
setMotivation("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col pt-10">
|
||||||
|
<SEO
|
||||||
|
title="Contato & Aplicação | MacroLojaUK"
|
||||||
|
description="Pronto para mudar de nível? Preencha o formulário e faça sua aplicação para a consultoria de elite com Alexandre Vaz."
|
||||||
|
/>
|
||||||
|
<section className="py-32 lg:py-48 bg-[#050505] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-20">
|
||||||
|
|
||||||
|
{/* Info Column */}
|
||||||
|
<motion.div initial={{ opacity: 0, x: -40 }} animate={{ opacity: 1, x: 0 }} transition={{ duration: 0.6 }}>
|
||||||
|
<span className="text-[#FF3E00] font-bold tracking-[0.2em] text-xs uppercase block mb-4 border-l-2 border-[#FF3E00] pl-4">Elite Support</span>
|
||||||
|
<h1 className="text-6xl sm:text-[70px] md:text-[110px] leading-[0.85] font-black tracking-tighter uppercase italic mb-8">
|
||||||
|
VAMOS AO <br/><span className="text-white/40">TRABALHO.</span>
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-white/60 mb-12 font-light leading-relaxed max-w-md">
|
||||||
|
Pronto para mudar de nível? Preencha o formulário ou chame no WhatsApp para analisarmos o seu caso. Não aceitamos todos.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="space-y-8 mb-12">
|
||||||
|
<div className="flex items-start gap-4">
|
||||||
|
<div className="w-12 h-12 bg-white/5 border border-white/10 flex items-center justify-center shrink-0" title="WhatsApp Premium">
|
||||||
|
<MessageSquare className="w-5 h-5 text-[#FF3E00]" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="font-bold text-white uppercase tracking-widest mb-1 text-sm">WhatsApp Premium</h4>
|
||||||
|
<p className="text-white/40 text-xs">Atendimento para fechamento de planos.</p>
|
||||||
|
<a href="https://wa.me/5511999999999" target="_blank" rel="noopener noreferrer" className="text-[#FF3E00] font-mono mt-1 hover:underline block">+55 (11) 99999-9999</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-start gap-4">
|
||||||
|
<div className="w-12 h-12 bg-white/5 border border-white/10 flex items-center justify-center shrink-0" title="E-mail Comercial">
|
||||||
|
<Mail className="w-5 h-5 text-[#FF3E00]" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="font-bold text-white uppercase tracking-widest mb-1 text-sm">E-mail Comercial</h4>
|
||||||
|
<p className="text-white/40 text-xs">Parcerias e patrocínios.</p>
|
||||||
|
<p className="text-[#FF3E00] font-mono mt-1">contato@alexandrevaz.com</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-start gap-4">
|
||||||
|
<div className="w-12 h-12 bg-white/5 border border-white/10 flex items-center justify-center shrink-0" title="Studio Presencial">
|
||||||
|
<MapPin className="w-5 h-5 text-[#FF3E00]" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="font-bold text-white uppercase tracking-widest mb-1 text-sm">Studio Presencial</h4>
|
||||||
|
<p className="text-white/40 text-xs">Apenas para alunos VIP.</p>
|
||||||
|
<p className="text-white/60 text-xs mt-1">Av. Faria Lima, 1000 - São Paulo, SP</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Form Column */}
|
||||||
|
<motion.div initial={{ opacity: 0, y: 40 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.6, delay: 0.2 }}>
|
||||||
|
<div className="bg-white/5 border border-white/10 p-8 md:p-12 relative overflow-hidden h-full flex flex-col justify-center">
|
||||||
|
<h3 className="text-2xl font-black italic tracking-tighter uppercase mb-8 relative z-10">APLICAÇÃO DE CONSULTORIA</h3>
|
||||||
|
{isSubmitted ? (
|
||||||
|
<div className="relative z-10 flex flex-col items-center justify-center text-center py-10 bg-[#FF3E00]/10 border border-[#FF3E00]/20 rounded-sm">
|
||||||
|
<div className="w-16 h-16 bg-[#FF3E00]/20 text-[#FF3E00] flex items-center justify-center rounded-full mb-6">
|
||||||
|
<Send className="w-8 h-8" />
|
||||||
|
</div>
|
||||||
|
<h4 className="text-xl font-bold uppercase tracking-widest text-white mb-2">Sua aplicação foi enviada com sucesso!</h4>
|
||||||
|
<p className="text-white/60 text-sm max-w-sm">Entraremos em contato em breve para os próximos passos. Fique atento ao seu WhatsApp.</p>
|
||||||
|
<button
|
||||||
|
onClick={() => setIsSubmitted(false)}
|
||||||
|
className="mt-8 px-8 py-3 border border-white/20 text-white text-[10px] font-black uppercase tracking-widest hover:border-[#FF3E00] hover:text-[#FF3E00] transition-colors"
|
||||||
|
>
|
||||||
|
Nova Aplicação
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<form className="relative z-10 flex flex-col gap-6" onSubmit={handleSubmit}>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<label className="text-[10px] font-bold uppercase tracking-widest text-[#FF3E00]">Nome Completo</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={name}
|
||||||
|
onChange={handleNameChange}
|
||||||
|
className={`bg-[#050505] border ${nameError ? "border-red-500/80 shadow-[0_0_10px_rgba(239,68,68,0.3)]" : "border-white/10"} px-4 py-3 text-white focus:outline-none focus:border-[#FF3E00] transition-colors`}
|
||||||
|
/>
|
||||||
|
{nameError && <span className="text-red-500 drop-shadow-[0_0_8px_rgba(239,68,68,0.8)] text-[10px] font-bold uppercase tracking-widest">{nameError}</span>}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<label className="text-[10px] font-bold uppercase tracking-widest text-[#FF3E00]">WhatsApp</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={whatsapp}
|
||||||
|
onChange={handleWhatsappChange}
|
||||||
|
className={`bg-[#050505] border ${whatsappError ? "border-red-500/80 shadow-[0_0_10px_rgba(239,68,68,0.3)]" : "border-white/10"} px-4 py-3 text-white focus:outline-none focus:border-[#FF3E00] transition-colors`}
|
||||||
|
/>
|
||||||
|
{whatsappError && <span className="text-red-500 drop-shadow-[0_0_8px_rgba(239,68,68,0.8)] text-[10px] font-bold uppercase tracking-widest">{whatsappError}</span>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<label className="text-[10px] font-bold uppercase tracking-widest text-[#FF3E00]">Objetivo Principal</label>
|
||||||
|
<select
|
||||||
|
value={objective}
|
||||||
|
onChange={(e) => setObjective(e.target.value)}
|
||||||
|
className="bg-[#050505] border border-white/10 px-4 py-3 text-white focus:outline-none focus:border-[#FF3E00] transition-colors appearance-none text-sm"
|
||||||
|
>
|
||||||
|
<option value="Emagrecimento Agressivo">Emagrecimento Agressivo</option>
|
||||||
|
<option value="Hipertrofia Extrema">Hipertrofia Extrema</option>
|
||||||
|
<option value="Preparação de Atleta">Preparação de Atleta</option>
|
||||||
|
<option value="Personal Presencial (SP)">Personal Presencial (SP)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<label className="text-[10px] font-bold uppercase tracking-widest text-[#FF3E00]">Por que devemos te aceitar?</label>
|
||||||
|
<textarea
|
||||||
|
rows={6}
|
||||||
|
value={motivation}
|
||||||
|
onChange={handleMotivationChange}
|
||||||
|
className={`bg-[#050505] border ${motivationError ? "border-red-500/80 shadow-[0_0_10px_rgba(239,68,68,0.3)]" : "border-white/10"} px-4 py-3 text-white focus:outline-none focus:border-[#FF3E00] transition-colors resize-none placeholder-white/20 text-sm`}
|
||||||
|
placeholder="Não aceitamos clientes sem disciplina. Descreva sua determinação e por que você está pronto para subir de nível..."
|
||||||
|
></textarea>
|
||||||
|
{motivationError && <span className="text-red-500 drop-shadow-[0_0_8px_rgba(239,68,68,0.8)] text-[10px] font-bold uppercase tracking-widest">{motivationError}</span>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button className="flex items-center justify-center gap-2 mt-4 px-10 py-5 bg-white text-black font-black uppercase tracking-widest hover:bg-[#FF3E00] hover:text-white transition-colors w-full text-[11px]">
|
||||||
|
Enviar Aplicação <Send className="w-4 h-4 ml-2" />
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* FAQ Section */}
|
||||||
|
<section className="py-24 bg-[#050505] relative z-10 border-t border-white/5">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-4xl">
|
||||||
|
<h2 className="text-[40px] md:text-[60px] font-black tracking-tighter uppercase italic text-center mb-16">DÚVIDAS <span className="text-[#FF3E00]">FREQUENTES</span></h2>
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
{[
|
||||||
|
{ q: "Qual a diferença entre a Consultoria Online e o App Premium?", a: "A consultoria online é 100% personalizada. Nenhuma planilha é igual à outra. Eu analiso fotos, histórico e rotina para montar o plano. O app é geralmente para quem busca planilhas padronizadas e mais em conta." },
|
||||||
|
{ q: "Como funciona o suporte via WhatsApp?", a: "Dependendo do seu plano, você tem acesso direto a mim ou à minha equipe de suporte de segunda a sexta. Dúvidas sobre execuções ou dieta são respondidas em até 24 ou 48 horas." },
|
||||||
|
{ q: "Preciso ir à academia ou posso treinar em casa?", a: "Montamos o plano de acordo com o arsenal que você tem disponível. Entretanto, para hipertrofia máxima, o ambiente de academia é altamente recomendado." },
|
||||||
|
{ q: "Vocês passam dieta / anabolizantes?", a: "Nós trabalhamos com nutricionistas parceiros que cuidam do planejamento dietético (em planos específicos). Fomentamos uma abordagem natural, não prescrevemos estróides." }
|
||||||
|
].map((faq, i) => (
|
||||||
|
<div key={i} className="bg-white/5 border border-white/10 p-6 hover:border-white/30 transition-colors">
|
||||||
|
<h4 className="text-lg font-bold text-white mb-3 italic tracking-tighter uppercase">{faq.q}</h4>
|
||||||
|
<p className="text-white/60 font-light text-sm">{faq.a}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
375
Template-01/src/pages/Home.tsx
Normal file
375
Template-01/src/pages/Home.tsx
Normal file
|
|
@ -0,0 +1,375 @@
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import { ArrowRight, CheckCircle2, Dumbbell, Flame, Trophy, Activity, Target, ChevronDown } from "lucide-react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
const FADE_UP = {
|
||||||
|
hidden: { opacity: 0, y: 40 },
|
||||||
|
visible: { opacity: 1, y: 0, transition: { duration: 0.6, ease: "easeOut" } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAGGER = {
|
||||||
|
visible: { transition: { staggerChildren: 0.1 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
const schema = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "SportsActivityLocation",
|
||||||
|
"name": "MacroLojaUK | Treinamento de Elite",
|
||||||
|
"image": "https://images.unsplash.com/photo-1534438327276-14e5300c3a48?q=80&w=2940&auto=format&fit=crop",
|
||||||
|
"description": "Transformação corporal de alto impacto para quem exige o topo. Consultoria personalizada, nutrição de precisão e performance atlética incomparável.",
|
||||||
|
"url": "https://macrolojauk.com/",
|
||||||
|
"priceRange": "$$$"
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col">
|
||||||
|
<SEO
|
||||||
|
title="O Fim das Desculpas | MacroLojaUK Treinamento de Elite"
|
||||||
|
description="Transformação corporal de alto impacto para quem exige o topo. Consultoria personalizada, nutrição de precisão e performance atlética incomparável."
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
{/* 1. HERO SECTION */}
|
||||||
|
<section className="relative min-h-[90vh] flex items-center pt-20 overflow-hidden">
|
||||||
|
{/* Background Image with Overlay */}
|
||||||
|
<div className="absolute inset-x-0 bottom-0 top-[20%] z-0">
|
||||||
|
<img
|
||||||
|
src="https://images.unsplash.com/photo-1534438327276-14e5300c3a48?q=80&w=2940&auto=format&fit=crop"
|
||||||
|
alt="Treinamento Intenso"
|
||||||
|
className="w-full h-full object-cover object-center opacity-30 grayscale mix-blend-screen"
|
||||||
|
style={{ maskImage: "linear-gradient(to top, black, transparent)", WebkitMaskImage: "linear-gradient(to top, black, transparent)" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className="container mx-auto px-6 lg:px-12 flex-1 flex flex-col justify-center relative z-10 space-y-2 mt-12"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
variants={STAGGER}
|
||||||
|
>
|
||||||
|
<motion.div variants={FADE_UP} className="max-w-5xl relative">
|
||||||
|
<div className="absolute left-[-48px] top-1/2 -translate-y-1/2 -rotate-90 origin-left hidden xl:block">
|
||||||
|
<p className="text-[8px] md:text-[10px] uppercase tracking-[0.5em] md:tracking-[1em] text-white/20 whitespace-nowrap font-bold">DISCIPLINA • PERFORMANCE • EXCLUSIVIDADE</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className="text-[#FF3E00] font-bold tracking-[0.2em] text-xs uppercase block mb-4 border-l-2 border-[#FF3E00] pl-4">The Gold Standard Training</span>
|
||||||
|
<h1 className="text-5xl sm:text-6xl md:text-[100px] lg:text-[140px] leading-[0.85] font-black tracking-tighter uppercase italic drop-shadow-2xl">
|
||||||
|
O FIM DAS<br/><span className="text-white/40">DESCULPAS.</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="max-w-lg text-xl text-white/60 font-light mt-8 leading-relaxed">
|
||||||
|
Transformação corporal de alto impacto para quem exige o topo. Consultoria personalizada, nutrição de precisão e performance atlética incomparável.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="flex flex-col sm:flex-row items-start sm:items-center space-y-6 sm:space-y-0 sm:space-x-10 mt-12">
|
||||||
|
<Link
|
||||||
|
to="/contato"
|
||||||
|
className="w-full sm:w-auto bg-white text-black px-8 sm:px-12 py-5 text-sm font-black uppercase tracking-widest hover:bg-[#FF3E00] hover:text-white transition-all transform hover:scale-105 active:scale-95 inline-block text-center shadow-[0_0_20px_rgba(255,255,255,0.1)] hover:shadow-[0_0_30px_rgba(255,62,0,0.4)]"
|
||||||
|
>
|
||||||
|
Iniciar Evolução
|
||||||
|
</Link>
|
||||||
|
<div className="flex items-center space-x-6 sm:border-l sm:border-white/10 sm:pl-10">
|
||||||
|
<div className="flex items-center -space-x-4">
|
||||||
|
<img src="https://images.unsplash.com/photo-1570295999919-56ceb5ecca61?w=100&h=100&fit=crop" alt="Client" className="w-12 h-12 rounded-full border-2 border-[#050505] grayscale z-30" />
|
||||||
|
<img src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop" alt="Client" className="w-12 h-12 rounded-full border-2 border-[#050505] grayscale z-20" />
|
||||||
|
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop" alt="Client" className="w-12 h-12 rounded-full border-2 border-[#050505] grayscale z-10" />
|
||||||
|
</div>
|
||||||
|
<div className="text-[11px] font-bold uppercase tracking-tighter text-white/50 leading-tight">
|
||||||
|
<span className="text-white text-lg font-black block">+450</span>
|
||||||
|
Vidas Transformadas
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ delay: 1, duration: 1 }}
|
||||||
|
className="absolute bottom-10 left-1/2 -translate-x-1/2 flex flex-col items-center justify-center z-20 hidden md:flex"
|
||||||
|
>
|
||||||
|
<span className="text-[9px] uppercase tracking-[0.2em] font-bold text-white/30 mb-2">Descubra</span>
|
||||||
|
<motion.div
|
||||||
|
animate={{ y: [0, 10, 0] }}
|
||||||
|
transition={{ repeat: Infinity, duration: 2, ease: "easeInOut" }}
|
||||||
|
>
|
||||||
|
<ChevronDown className="w-5 h-5 text-[#FF3E00]/60" />
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. SERVICES SECTION - Bento Grid Style */}
|
||||||
|
<section className="py-32 bg-[#050505] relative z-10 border-t border-white/10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
<motion.div
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={{ once: true, margin: "-100px" }}
|
||||||
|
variants={STAGGER}
|
||||||
|
className="mb-20"
|
||||||
|
>
|
||||||
|
<h2 className="text-4xl sm:text-[60px] md:text-[80px] leading-[0.9] font-black tracking-tighter uppercase italic mb-6">
|
||||||
|
METODOLOGIA DE <span className="text-[#FF3E00]">ELITE</span>
|
||||||
|
</h2>
|
||||||
|
<p className="text-white/60 text-lg max-w-2xl font-light">
|
||||||
|
Acompanhamento premium e personalizado para cada objetivo. Seja qual for o seu nível atual, temos o método exato para destruir seus platôs.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||||
|
{/* Card 1: Consultoria */}
|
||||||
|
<motion.div variants={FADE_UP} className="col-span-1 md:col-span-2 row-span-2 group relative overflow-hidden bg-gradient-to-br from-white/5 to-transparent border border-white/10 p-10 min-h-[400px] flex flex-col justify-between hover:border-[#FF3E00]/50 transition-all">
|
||||||
|
<div className="absolute inset-0 opacity-20 grayscale group-hover:grayscale-0 transition-opacity">
|
||||||
|
<img src="https://images.unsplash.com/photo-1581009146145-b5ef050c2e1e?q=80&w=2940&auto=format&fit=crop" className="w-full h-full object-cover mix-blend-overlay opacity-30" alt="Consultoria" />
|
||||||
|
</div>
|
||||||
|
<div className="relative z-10 space-y-4">
|
||||||
|
<span className="text-xs font-bold uppercase tracking-widest text-white/50">Programa Flagship</span>
|
||||||
|
<h3 className="text-4xl font-black italic uppercase tracking-tighter">Consultoria Online</h3>
|
||||||
|
<p className="text-white/60 font-light text-sm max-w-sm italic">
|
||||||
|
"O acompanhamento diário e ajustes finos que separam amadores de atletas de elite."
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="relative z-10 mt-12 flex justify-between items-end">
|
||||||
|
<div className="space-y-1 w-1/2">
|
||||||
|
<div className="w-full h-1 bg-white/20 rounded-full">
|
||||||
|
<div className="w-[95%] h-full bg-[#FF3E00]"></div>
|
||||||
|
</div>
|
||||||
|
<p className="text-[9px] uppercase font-bold opacity-40">Taxa de Sucesso</p>
|
||||||
|
</div>
|
||||||
|
<div className="text-xl font-bold">95%</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Card 2: Emagrecimento Stats */}
|
||||||
|
<motion.div variants={FADE_UP} className="bg-white/5 p-8 border border-white/10 flex flex-col justify-between h-full min-h-[200px]">
|
||||||
|
<span className="text-[#FF3E00] text-5xl font-black italic tracking-tighter">-12KG</span>
|
||||||
|
<p className="text-[10px] uppercase tracking-wider font-bold opacity-50">Média em 90 dias</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Card 3: Hipertrofia Label */}
|
||||||
|
<motion.div variants={FADE_UP} className="bg-[#FF3E00] p-8 flex flex-col justify-between h-full min-h-[200px]">
|
||||||
|
<span className="text-white text-4xl font-black italic tracking-tighter">VIP</span>
|
||||||
|
<p className="text-[10px] uppercase tracking-wider font-bold text-black mt-4 border-t border-black/20 pt-2">Presencial (Vagas Esgotadas)</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Card 4: Personal Mini */}
|
||||||
|
<motion.div variants={FADE_UP} className="col-span-1 md:col-span-2 grid grid-cols-2 gap-4 h-full">
|
||||||
|
<div className="bg-neutral-900 border border-white/10 flex items-center justify-center flex-col opacity-60 p-6 group hover:opacity-100 transition-opacity">
|
||||||
|
<span className="text-xs font-bold uppercase tracking-widest text-[#F5F5F5]">Hipertrofia</span>
|
||||||
|
<Dumbbell className="w-5 h-5 text-white/40 mt-3 group-hover:text-white transition-colors" />
|
||||||
|
</div>
|
||||||
|
<div className="bg-white/5 border border-white/10 flex items-center justify-center flex-col p-6 group hover:bg-[#FF3E00]/10 transition-colors cursor-pointer">
|
||||||
|
<span className="text-xs font-bold text-[#FF3E00] uppercase tracking-widest">Protocolos</span>
|
||||||
|
<Activity className="w-5 h-5 text-[#FF3E00] mt-3" />
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. TRANSFORMATIONS SECTION */}
|
||||||
|
<section className="py-32 bg-[#050505] relative z-10 border-t border-white/5">
|
||||||
|
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
<motion.div
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={{ once: true, margin: "-100px" }}
|
||||||
|
variants={STAGGER}
|
||||||
|
className="text-left mb-20"
|
||||||
|
>
|
||||||
|
<span className="text-[#FF3E00] font-bold tracking-[0.2em] text-xs uppercase block mb-4">Caso de Sucessos Reais</span>
|
||||||
|
<h2 className="text-4xl sm:text-[60px] md:text-[80px] leading-[0.9] font-black tracking-tighter uppercase italic mb-6">
|
||||||
|
NÃO VENDEMOS TREINO.<br/><span className="text-white/50">VENDEMOS RENOVAÇÃO.</span>
|
||||||
|
</h2>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
name: "Código Apex / T. Marques",
|
||||||
|
stats: "Recomposição Intensa: -12kg Fat / +5kg Muscle",
|
||||||
|
before: "https://images.unsplash.com/photo-1583454155184-870a1f63aebc?q=80&w=600&auto=format&fit=crop&sepia=100",
|
||||||
|
after: "https://images.unsplash.com/photo-1583454110551-21f2fa2afe61?q=80&w=600&auto=format&fit=crop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Doutrina Sigma / L. Almeida",
|
||||||
|
stats: "Secagem Extrema: -16kg Fat / Preservação Tonal",
|
||||||
|
before: "https://images.unsplash.com/photo-1522851412702-8a9d18e11a3d?q=80&w=600&auto=format&fit=crop&sepia=100",
|
||||||
|
after: "https://images.unsplash.com/photo-1571019614242-c5c5dee9f50b?q=80&w=600&auto=format&fit=crop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Projeto Leviatã / M. Castro",
|
||||||
|
stats: "Bulking Limpo: +10kg Massa Magra / Densidade Densa",
|
||||||
|
before: "https://images.unsplash.com/photo-1534438097544-e29ed870e8ed?q=80&w=600&auto=format&fit=crop&sepia=100",
|
||||||
|
after: "https://images.unsplash.com/photo-1534438327276-14e5300c3a48?q=80&w=600&auto=format&fit=crop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Operação Centurião / F. Moraes",
|
||||||
|
stats: "Transformação Total: -20kg Fat / Novo Estilo de Vida",
|
||||||
|
before: "https://images.unsplash.com/photo-1541534741688-6078c6bfb5c5?q=80&w=600&auto=format&fit=crop&sepia=100",
|
||||||
|
after: "https://images.unsplash.com/photo-1581009146145-b5ef050c2e1e?q=80&w=600&auto=format&fit=crop"
|
||||||
|
}
|
||||||
|
].map((item, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={index}
|
||||||
|
variants={FADE_UP}
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={{ once: true }}
|
||||||
|
className="group"
|
||||||
|
>
|
||||||
|
<div className="relative aspect-[4/3] bg-neutral-900 border border-white/10 overflow-hidden flex grayscale hover:grayscale-0 transition-all duration-500">
|
||||||
|
<div className="w-1/2 h-full bg-[#151515] relative border-r border-white/20 flex items-center justify-center opacity-80 transition-all duration-500">
|
||||||
|
<span className="absolute bottom-4 left-4 text-[10px] uppercase font-bold tracking-widest text-[#F5F5F5] bg-black/80 px-3 py-1">Antes</span>
|
||||||
|
<img src={item.before} className="w-full h-full object-cover opacity-60 mix-blend-luminosity" alt="Antes" />
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 h-full bg-[#111] relative flex items-center justify-center transition-all duration-500">
|
||||||
|
<span className="absolute bottom-4 right-4 text-[10px] uppercase font-bold tracking-widest text-black bg-[#CCFF00] px-3 py-1 z-10">Depois</span>
|
||||||
|
<img src={item.after} className="w-full h-full object-cover" alt="Depois" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 flex flex-col justify-start items-start pb-6">
|
||||||
|
<h4 className="text-xl font-bold italic uppercase tracking-tighter mb-1">{item.name}</h4>
|
||||||
|
<p className="text-white/40 text-[11px] uppercase tracking-wider font-semibold">{item.stats}</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 4. PLANS SECTION */}
|
||||||
|
<section className="py-40 bg-[#050505] relative border-t border-white/5 z-10">
|
||||||
|
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl relative z-10">
|
||||||
|
<div className="flex flex-col md:flex-row justify-between items-start md:items-end mb-24 border-b border-white/10 pb-12 gap-8">
|
||||||
|
<motion.div
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={{ once: true, margin: "-100px" }}
|
||||||
|
variants={STAGGER}
|
||||||
|
>
|
||||||
|
<h2 className="text-5xl sm:text-[70px] md:text-[110px] leading-[0.85] font-black tracking-tighter uppercase italic">
|
||||||
|
O CUSTO DA <br/><span className="text-white/40">GRANDEZA.</span>
|
||||||
|
</h2>
|
||||||
|
</motion.div>
|
||||||
|
<div className="text-left md:text-right border-l-2 border-[#FF3E00] pl-6 md:border-l-0 md:pl-0 md:border-r-2 md:pr-6">
|
||||||
|
<span className="text-[10px] uppercase font-bold tracking-widest text-[#FF3E00] block mb-2">Vagas Restantes</span>
|
||||||
|
<span className="text-3xl md:text-4xl font-black italic text-white line-through opacity-50 block leading-none mb-1">05 SLOTS</span>
|
||||||
|
<span className="text-3xl md:text-4xl font-black italic text-[#FF3E00] leading-none">03 SLOTS</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-0 border border-white/10 mx-auto bg-white/5">
|
||||||
|
{/* Trimestral Card */}
|
||||||
|
<motion.div variants={FADE_UP} className="border-b md:border-b-0 md:border-r border-white/10 p-8 md:p-12 flex flex-col hover:bg-white/5 transition-colors relative group">
|
||||||
|
<h3 className="text-2xl font-black uppercase mb-4 tracking-tighter italic">Base Mensal</h3>
|
||||||
|
<p className="text-white/50 text-[11px] mb-12 uppercase tracking-widest leading-relaxed">O plano fundamental para iniciar a transformação corporal profunda e sistêmica.</p>
|
||||||
|
<div className="mb-12 border-b border-white/10 pb-8">
|
||||||
|
<span className="text-6xl font-black tracking-tighter italic">R$ 297</span>
|
||||||
|
<span className="text-white/40 text-[10px] uppercase font-bold tracking-widest ml-2">/mês</span>
|
||||||
|
</div>
|
||||||
|
<ul className="flex flex-col gap-6 mb-16 flex-grow">
|
||||||
|
{[
|
||||||
|
"Treino periodizado mensal",
|
||||||
|
"Guia macro flexível",
|
||||||
|
"Análise de video básica",
|
||||||
|
"Suporte assíncrono (48h)",
|
||||||
|
].map((feature, i) => (
|
||||||
|
<li key={i} className="flex items-start gap-4 opacity-70 group-hover:opacity-100 transition-opacity">
|
||||||
|
<div className="w-1.5 h-1.5 bg-[#FF3E00] mt-1.5 shrink-0 rounded-full" />
|
||||||
|
<span className="text-xs font-semibold text-white uppercase tracking-wider">{feature}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Link to="/contato" className="w-full text-center px-6 py-5 border border-white/20 text-[11px] font-black uppercase tracking-widest hover:border-[#FF3E00] hover:text-[#FF3E00] transition-colors block">
|
||||||
|
Selecionar Plano
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* VIP Card */}
|
||||||
|
<motion.div variants={FADE_UP} className="bg-[#FF3E00] border-0 p-8 md:p-12 flex flex-col relative transform md:-translate-y-8 md:scale-[1.02] shadow-2xl z-20">
|
||||||
|
<div className="absolute top-0 right-12 bg-black text-[#FF3E00] text-[10px] font-black uppercase tracking-widest px-4 py-2 transform -translate-y-1/2">
|
||||||
|
Elite Choice
|
||||||
|
</div>
|
||||||
|
<h3 className="text-3xl font-black uppercase mb-4 tracking-tighter italic text-white">Mutação 90D</h3>
|
||||||
|
<p className="text-black/70 text-[11px] font-bold uppercase tracking-widest mb-12 leading-relaxed">Arquitetura intensiva de 3 meses. Para resultados severos e estética final.</p>
|
||||||
|
<div className="mb-12 border-b border-black/20 pb-8">
|
||||||
|
<span className="text-4xl font-black tracking-tighter italic text-black/40 line-through block mb-2">R$ 891</span>
|
||||||
|
<div>
|
||||||
|
<span className="text-7xl font-black tracking-tighter italic text-white drop-shadow-lg">R$ 797</span>
|
||||||
|
<span className="text-black/80 text-[10px] uppercase font-bold tracking-widest block mt-2">/ciclo completo</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul className="flex flex-col gap-6 mb-16 flex-grow">
|
||||||
|
{[
|
||||||
|
"Tudo do plano mensal base",
|
||||||
|
"Periodização ondulatória reversa",
|
||||||
|
"Macros adaptativos complexos",
|
||||||
|
"Call quinzenal de alinhamento",
|
||||||
|
"Hotline VIP 24h",
|
||||||
|
].map((feature, i) => (
|
||||||
|
<li key={i} className="flex items-start gap-4">
|
||||||
|
<div className="w-1.5 h-1.5 bg-black mt-1.5 shrink-0 rounded-full" />
|
||||||
|
<span className="text-xs font-bold text-white uppercase tracking-wider">{feature}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Link to="/contato" className="w-full text-center px-6 py-6 bg-black text-white text-[11px] font-black uppercase tracking-widest hover:bg-transparent hover:text-black hover:border-black border border-black transition-colors block">
|
||||||
|
Aplicar Mutaçao
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Anual Card */}
|
||||||
|
<motion.div variants={FADE_UP} className="p-8 md:p-12 flex flex-col hover:bg-white/5 transition-colors group">
|
||||||
|
<h3 className="text-2xl font-black uppercase mb-4 tracking-tighter italic">Master Anual</h3>
|
||||||
|
<p className="text-white/50 text-[11px] mb-12 uppercase tracking-widest leading-relaxed">Para quem adota o fitness como estilo vitalício. Economia e constância.</p>
|
||||||
|
<div className="mb-12 border-b border-white/10 pb-8">
|
||||||
|
<span className="text-6xl font-black tracking-tighter italic">R$ 227</span>
|
||||||
|
<span className="text-white/40 text-[10px] uppercase font-bold tracking-widest ml-2">/mês (12x)</span>
|
||||||
|
<div className="text-[#FF3E00] text-[10px] mt-3 uppercase tracking-widest font-bold">R$ 2.724 aporte único</div>
|
||||||
|
</div>
|
||||||
|
<ul className="flex flex-col gap-6 mb-16 flex-grow">
|
||||||
|
{[
|
||||||
|
"Tudo do plano Mutação 90D",
|
||||||
|
"Ciclos de bulk/cut macro",
|
||||||
|
"Revisão biomecânica",
|
||||||
|
"Plataforma privada premium",
|
||||||
|
"Prioridade em presencial",
|
||||||
|
].map((feature, i) => (
|
||||||
|
<li key={i} className="flex items-start gap-4 opacity-70 group-hover:opacity-100 transition-opacity">
|
||||||
|
<div className="w-1.5 h-1.5 bg-[#FF3E00] mt-1.5 shrink-0 rounded-full" />
|
||||||
|
<span className="text-xs font-semibold text-white uppercase tracking-wider">{feature}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Link to="/contato" className="w-full text-center px-6 py-5 border border-white/20 text-[11px] font-black uppercase tracking-widest hover:border-[#FF3E00] hover:text-[#FF3E00] transition-colors block">
|
||||||
|
Tornar-se Mestre
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 5. FINAL CTA SECTION */}
|
||||||
|
<section className="py-24 relative overflow-hidden bg-white text-black z-10 border-t-8 border-[#FF3E00]">
|
||||||
|
<div className="absolute inset-0 opacity-10">
|
||||||
|
<img src="https://images.unsplash.com/photo-1541534741688-6078c6bfb5c5?q=80&w=2938&auto=format&fit=crop" className="w-full h-full object-cover mix-blend-multiply" alt="Background CTA" />
|
||||||
|
</div>
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl flex flex-col items-center justify-center text-center relative z-10">
|
||||||
|
<h2 className="text-4xl sm:text-[50px] md:text-[90px] font-black tracking-tighter uppercase italic leading-[0.85] mb-8">
|
||||||
|
A DECISÃO É SUA.<br/>
|
||||||
|
<span className="text-black/30">A MEDIOCRIDADE TAMBÉM.</span>
|
||||||
|
</h2>
|
||||||
|
<Link to="/contato" className="w-full sm:w-auto text-center bg-black text-white px-8 sm:px-12 py-6 text-sm font-black uppercase tracking-widest hover:bg-[#FF3E00] transition-colors transform hover:scale-105 active:scale-95 inline-block">
|
||||||
|
Agendar Reunião Estratégica
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
24
Template-01/src/pages/NotFound.tsx
Normal file
24
Template-01/src/pages/NotFound.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { ArrowLeft } from "lucide-react";
|
||||||
|
|
||||||
|
export default function NotFound() {
|
||||||
|
return (
|
||||||
|
<div className="w-full min-h-[70vh] flex flex-col items-center justify-center bg-[#050505] text-center px-6">
|
||||||
|
<h1 className="text-[120px] md:text-[200px] font-black italic tracking-tighter text-[#FF3E00] leading-none drop-shadow-[0_0_20px_rgba(255,62,0,0.4)]">
|
||||||
|
404
|
||||||
|
</h1>
|
||||||
|
<h2 className="text-3xl md:text-5xl font-black italic uppercase tracking-tighter text-white mb-6">
|
||||||
|
Território Desconhecido
|
||||||
|
</h2>
|
||||||
|
<p className="text-white/60 font-light mb-10 max-w-md">
|
||||||
|
A página que você está procurando não existe ou foi removida. O foco inabalável não permite distrações, volte para o caminho certo.
|
||||||
|
</p>
|
||||||
|
<Link
|
||||||
|
to="/"
|
||||||
|
className="flex items-center gap-2 border border-white/20 px-8 py-4 text-white uppercase text-[11px] tracking-widest font-bold hover:bg-[#FF3E00] hover:border-[#FF3E00] transition-colors"
|
||||||
|
>
|
||||||
|
<ArrowLeft className="w-4 h-4" /> Voltar ao Início
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
147
Template-01/src/pages/Sobre.tsx
Normal file
147
Template-01/src/pages/Sobre.tsx
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import { CheckCircle2, Shield, Calendar, Award } from "lucide-react";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
export default function Sobre() {
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col pt-10">
|
||||||
|
<SEO
|
||||||
|
title="Sobre o Treinador | MacroLojaUK"
|
||||||
|
description="Conheça Alexandre Vaz e a filosofia de treinamento intenso por trás da MacroLojaUK. Mais de uma década forjando corpos e mentes."
|
||||||
|
/>
|
||||||
|
{/* Hero Sobre */}
|
||||||
|
<section className="relative py-32 lg:py-48 overflow-hidden border-b border-white/5 bg-[#050505]">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, x: -40 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.6 }}
|
||||||
|
>
|
||||||
|
<h1 className="text-5xl sm:text-[70px] md:text-[110px] leading-[0.85] font-black tracking-tighter uppercase italic mb-8">
|
||||||
|
NÃO É SOBRE GENÉTICA.<br />
|
||||||
|
<span className="text-[#FF3E00]">É SOBRE TRABALHO.</span>
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-white/60 mb-10 font-light leading-relaxed max-w-lg border-l-2 border-[#FF3E00] pl-6">
|
||||||
|
Sou Alexandre Vaz. Há mais de uma década, venho destruindo o mito de que você precisa ter nascido com o metabolismo perfeito para conquistar um físico de elite. Minha missão é forjar corpos e mentes inquebráveis através de disciplina militar e ciência aplicada.
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<div className="flex items-center gap-3 text-[10px] font-bold uppercase tracking-widest text-[#FF3E00] border border-[#FF3E00]/30 px-4 py-2">
|
||||||
|
<Shield className="w-4 h-4" />
|
||||||
|
+12 Anos na Trincheira
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
transition={{ duration: 0.6, delay: 0.2 }}
|
||||||
|
className="relative"
|
||||||
|
>
|
||||||
|
<div className="aspect-[4/5] bg-neutral-900 border border-white/10 relative z-10 overflow-hidden grayscale hover:grayscale-0 transition-all duration-700">
|
||||||
|
<img src="https://images.unsplash.com/photo-1583454110551-21f2fa2afe61?q=80&w=2070&auto=format&fit=crop" alt="Alexandre Vaz" className="w-full h-full object-cover" />
|
||||||
|
</div>
|
||||||
|
{/* Decorative background element */}
|
||||||
|
<div className="absolute -inset-4 border border-primary-500/30 z-0 translate-x-8 translate-y-8" />
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Filosofia / Timeline */}
|
||||||
|
<section className="py-32 bg-[#050505] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-20">
|
||||||
|
{/* Timeline */}
|
||||||
|
<div>
|
||||||
|
<h2 className="text-4xl md:text-[60px] font-black tracking-tighter uppercase italic mb-12">O CAMINHO DA <span className="text-white/40">FORJA</span></h2>
|
||||||
|
<div className="space-y-12 relative before:absolute before:inset-0 before:ml-5 before:-translate-x-px md:before:ml-[23px] before:md:-translate-x-px before:h-full before:w-px before:bg-white/10">
|
||||||
|
{[
|
||||||
|
{ year: "2012", title: "O Início Corporal", desc: "Graduação em Educação Física e início do trabalho de base focado em fisiologia do exercício e hipertrofia." },
|
||||||
|
{ year: "2016", title: "Certificação Internacional", desc: "Especialização em nutrição esportiva e métodos de força no exterior (ISSA, NSCA fictícios)." },
|
||||||
|
{ year: "2019", title: "O Método Mutação", desc: "Lançamento do método que unificou biomecânica, nutrição estratégica e psicologia de alta performance." },
|
||||||
|
{ year: "2024", title: "Treinador de Elite", desc: "Mais de 500 transformações radicais documentadas. Torna-se referência no mercado premium de fitness." }
|
||||||
|
].map((item, i) => (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
key={i}
|
||||||
|
className="relative flex items-center justify-between md:justify-normal md:odd:flex-row-reverse group is-active"
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-center w-10 h-10 rounded-full border border-white/20 bg-neutral-950 text-neutral-500 group-hover:text-primary-500 group-hover:border-primary-500 shrink-0 md:order-1 md:group-odd:-translate-x-1/2 md:group-even:translate-x-1/2 shadow-sm transition-colors">
|
||||||
|
<Calendar className="w-4 h-4" />
|
||||||
|
</div>
|
||||||
|
<div className="w-[calc(100%-4rem)] md:w-[calc(50%-2.5rem)] bg-[#121212] p-6 border border-white/5 group-hover:border-white/10 transition-colors">
|
||||||
|
<div className="flex items-center justify-between mb-2">
|
||||||
|
<h3 className="font-bold text-white uppercase tracking-wider">{item.title}</h3>
|
||||||
|
<span className="text-primary-500 font-black heading-impact">{item.year}</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-neutral-400 font-light">{item.desc}</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Certificações & Rotina */}
|
||||||
|
<div>
|
||||||
|
<div className="mb-16">
|
||||||
|
<h2 className="text-4xl md:text-[60px] font-black tracking-tighter uppercase italic mb-8">PEDIGREE TÉCNICO</h2>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
|
{[
|
||||||
|
"Master Trainer NSCA",
|
||||||
|
"Especialista em Biomecânica",
|
||||||
|
"Pós-graduado em Fisiologia",
|
||||||
|
"Nutrição Esportiva (ISSN)",
|
||||||
|
"Certified Strength Coach",
|
||||||
|
"Reabilitação Lesões Atletas"
|
||||||
|
].map((cert, i) => (
|
||||||
|
<div key={i} className="flex items-center gap-3 bg-[#121212] p-4 border border-white/5">
|
||||||
|
<Award className="w-5 h-5 text-primary-500 shrink-0" />
|
||||||
|
<span className="text-sm text-neutral-300 font-semibold">{cert}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2 className="text-4xl md:text-[60px] font-black tracking-tighter uppercase italic mb-8 border-t border-white/5 pt-16">UM DIA NA <span className="text-white/40">VIDA</span></h2>
|
||||||
|
<p className="text-white/60 mb-6 font-light max-w-md">Eu não passo um treino que não faria. Não exijo uma disciplina que eu mesmo não aplico diariamente.</p>
|
||||||
|
<div className="space-y-4">
|
||||||
|
{[
|
||||||
|
{ time: "04:30", act: "Alvorada & Cardio em Jejum" },
|
||||||
|
{ time: "06:00", act: "Primeira Refeição & Estudo" },
|
||||||
|
{ time: "08:00", act: "Check-in Consultoria (+50 alunos)" },
|
||||||
|
{ time: "11:00", act: "Treino de Força (Iron Time)" },
|
||||||
|
{ time: "14:00", act: "Aulas de Personal Presencial" },
|
||||||
|
{ time: "22:00", act: "Última refeição & Foco no Off" }
|
||||||
|
].map((routine, i) => (
|
||||||
|
<div key={i} className="flex items-center justify-between py-3 border-b border-white/5 last:border-0">
|
||||||
|
<span className="font-mono text-primary-500">{routine.time}</span>
|
||||||
|
<span className="text-sm text-neutral-300 uppercase tracking-widest">{routine.act}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Banner Motivacional */}
|
||||||
|
<section className="py-32 relative overflow-hidden bg-white text-black z-10 border-t-8 border-[#FF3E00]">
|
||||||
|
<div className="absolute inset-0 opacity-10">
|
||||||
|
<img src="https://images.unsplash.com/photo-1526506159807-1c00ba4ce19b?q=80&w=2940&auto=format&fit=crop" className="w-full h-full object-cover mix-blend-multiply" alt="Background CTA" />
|
||||||
|
</div>
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl flex flex-col items-center justify-center text-center relative z-10">
|
||||||
|
<h2 className="text-[40px] md:text-[80px] font-black tracking-tighter uppercase italic leading-[0.85] mb-8">
|
||||||
|
A ÚNICA VARIÁVEL QUE VOCÊ CONTROLA É O SEU <br/>
|
||||||
|
<span className="text-black/30">ESFORÇO.</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
26
Template-01/tsconfig.json
Normal file
26
Template-01/tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": [
|
||||||
|
"ES2022",
|
||||||
|
"DOM",
|
||||||
|
"DOM.Iterable"
|
||||||
|
],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"allowJs": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"noEmit": true
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Template-01/vite.config.ts
Normal file
24
Template-01/vite.config.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import path from 'path';
|
||||||
|
import {defineConfig, loadEnv} from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig(({mode}) => {
|
||||||
|
const env = loadEnv(mode, '.', '');
|
||||||
|
return {
|
||||||
|
plugins: [react(), tailwindcss()],
|
||||||
|
define: {
|
||||||
|
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(__dirname, '.'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
||||||
|
// Do not modifyâfile watching is disabled to prevent flickering during agent edits.
|
||||||
|
hmr: process.env.DISABLE_HMR !== 'true',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
20
Template-02/README.md
Normal file
20
Template-02/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<div align="center">
|
||||||
|
<img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
# Run and deploy your AI Studio app
|
||||||
|
|
||||||
|
This contains everything you need to run your app locally.
|
||||||
|
|
||||||
|
View your app in AI Studio: https://ai.studio/apps/ab70d450-2df0-4f23-86be-996339f68015
|
||||||
|
|
||||||
|
## Run Locally
|
||||||
|
|
||||||
|
**Prerequisites:** Node.js
|
||||||
|
|
||||||
|
|
||||||
|
1. Install dependencies:
|
||||||
|
`npm install`
|
||||||
|
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
|
||||||
|
3. Run the app:
|
||||||
|
`npm run dev`
|
||||||
36
Template-02/index.html
Normal file
36
Template-02/index.html
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="pt-BR">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
|
||||||
|
<!-- SEO and Meta Tags -->
|
||||||
|
<title>Alexandre Vaz | The Gold Standard Training</title>
|
||||||
|
<meta name="description" content="O fim das desculpas. Transformação corporal de alto impacto, consultoria personalizada, nutrição de precisão e performance atlética. Elite Training por Alexandre Vaz." />
|
||||||
|
<meta name="keywords" content="treino, hipertrofia, emagrecimento, consultoria fitness, alexandre vaz, bodybuilding, personal trainer online, estética, alta performance" />
|
||||||
|
<meta name="author" content="Alexandre Vaz" />
|
||||||
|
<meta name="robots" content="index, follow" />
|
||||||
|
|
||||||
|
<!-- Open Graph (Facebook / LinkedIn) -->
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="https://alexandrevaz.com/" />
|
||||||
|
<meta property="og:title" content="Alexandre Vaz | The Gold Standard Training" />
|
||||||
|
<meta property="og:description" content="O fim das desculpas. Transformação corporal de alto impacto, consultoria personalizada, nutrição de precisão e performance atlética." />
|
||||||
|
<meta property="og:image" content="https://images.unsplash.com/photo-1571019614242-c5c5dee9f50b?q=80&w=1200&auto=format&fit=crop" />
|
||||||
|
|
||||||
|
<!-- Twitter Cards -->
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:url" content="https://alexandrevaz.com/" />
|
||||||
|
<meta name="twitter:title" content="Alexandre Vaz | The Gold Standard Training" />
|
||||||
|
<meta name="twitter:description" content="O fim das desculpas. Transformação corporal de alto impacto, consultoria personalizada e performance atlética." />
|
||||||
|
<meta name="twitter:image" content="https://images.unsplash.com/photo-1571019614242-c5c5dee9f50b?q=80&w=1200&auto=format&fit=crop" />
|
||||||
|
|
||||||
|
<!-- Favicon -->
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🛡️</text></svg>">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
6
Template-02/metadata.json
Normal file
6
Template-02/metadata.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "Alexandre Vaz Elite",
|
||||||
|
"description": "High-end personal trainer premium website, single page application.",
|
||||||
|
"requestFramePermissions": [],
|
||||||
|
"majorCapabilities": []
|
||||||
|
}
|
||||||
4447
Template-02/package-lock.json
generated
Normal file
4447
Template-02/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
38
Template-02/package.json
Normal file
38
Template-02/package.json
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"name": "react-example",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --port=3000 --host=0.0.0.0",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"clean": "rm -rf dist",
|
||||||
|
"lint": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@google/genai": "^1.29.0",
|
||||||
|
"@tailwindcss/vite": "^4.1.14",
|
||||||
|
"@vitejs/plugin-react": "^5.0.4",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"dotenv": "^17.2.3",
|
||||||
|
"express": "^4.21.2",
|
||||||
|
"lucide-react": "^0.546.0",
|
||||||
|
"motion": "^12.23.24",
|
||||||
|
"react": "^19.0.1",
|
||||||
|
"react-dom": "^19.0.1",
|
||||||
|
"react-helmet-async": "^3.0.0",
|
||||||
|
"react-router-dom": "^7.15.0",
|
||||||
|
"tailwind-merge": "^3.5.0",
|
||||||
|
"vite": "^6.2.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/express": "^4.17.21",
|
||||||
|
"@types/node": "^22.14.0",
|
||||||
|
"autoprefixer": "^10.4.21",
|
||||||
|
"tailwindcss": "^4.1.14",
|
||||||
|
"tsx": "^4.21.0",
|
||||||
|
"typescript": "~5.8.2",
|
||||||
|
"vite": "^6.2.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
4
Template-02/public/robots.txt
Normal file
4
Template-02/public/robots.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
Sitemap: https://alexandrevaz.com/sitemap.xml
|
||||||
33
Template-02/public/sitemap.xml
Normal file
33
Template-02/public/sitemap.xml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>1.0</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/sobre</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/metodologia</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/blog</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>daily</changefreq>
|
||||||
|
<priority>0.9</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://alexandrevaz.com/contato</loc>
|
||||||
|
<lastmod>2024-05-01</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
||||||
69
Template-02/src/App.tsx
Normal file
69
Template-02/src/App.tsx
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { BrowserRouter, Routes, Route, useLocation } from "react-router-dom";
|
||||||
|
import { AnimatePresence, motion } from "motion/react";
|
||||||
|
import Layout from "./components/Layout";
|
||||||
|
import Home from "./pages/Home";
|
||||||
|
import Sobre from "./pages/Sobre";
|
||||||
|
import Blog from "./pages/Blog";
|
||||||
|
import Contato from "./pages/Contato";
|
||||||
|
import BlogPost from "./pages/BlogPost";
|
||||||
|
import NotFound from "./pages/NotFound";
|
||||||
|
|
||||||
|
const PageTransition: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 20, filter: "blur(4px)" }}
|
||||||
|
animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
|
||||||
|
exit={{ opacity: 0, y: -20, filter: "blur(4px)" }}
|
||||||
|
transition={{ duration: 0.6, ease: [0.22, 1, 0.36, 1] }}
|
||||||
|
className="flex flex-col flex-grow w-full"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AnimatedRoutes() {
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (location.hash) {
|
||||||
|
const element = document.getElementById(location.hash.replace('#', ''));
|
||||||
|
if (element) {
|
||||||
|
setTimeout(() => {
|
||||||
|
element.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
}, [location]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnimatePresence mode="wait">
|
||||||
|
<Routes location={location}>
|
||||||
|
<Route path="/" element={<PageTransition key="home"><Home /></PageTransition>} />
|
||||||
|
<Route path="/sobre" element={<PageTransition key="sobre"><Sobre /></PageTransition>} />
|
||||||
|
<Route path="/blog" element={<PageTransition key="blog"><Blog /></PageTransition>} />
|
||||||
|
<Route path="/blog/:slug" element={<PageTransition key="post"><BlogPost /></PageTransition>} />
|
||||||
|
<Route path="/contato" element={<PageTransition key="contato"><Contato /></PageTransition>} />
|
||||||
|
<Route path="*" element={<PageTransition key="notfound"><NotFound /></PageTransition>} />
|
||||||
|
</Routes>
|
||||||
|
</AnimatePresence>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
return (
|
||||||
|
<BrowserRouter>
|
||||||
|
<Layout>
|
||||||
|
<AnimatedRoutes />
|
||||||
|
</Layout>
|
||||||
|
</BrowserRouter>
|
||||||
|
);
|
||||||
|
}
|
||||||
20
Template-02/src/components/Footer.tsx
Normal file
20
Template-02/src/components/Footer.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className="w-full bg-[#FDFBF7] border-t border-[#E8DCC4] py-8 px-6 lg:px-12 z-20 relative">
|
||||||
|
<div className="flex flex-col md:flex-row items-center justify-between text-[10px] uppercase tracking-[0.2em] font-medium text-[#888888] gap-6">
|
||||||
|
<div>© {new Date().getFullYear()} Aurora — Wellness & Mentoring</div>
|
||||||
|
<div className="flex space-x-8">
|
||||||
|
<a href="#" className="hover:text-[#D4BAB6] transition-colors">Instagram</a>
|
||||||
|
<a href="#" className="hover:text-[#D4BAB6] transition-colors">Pinterest</a>
|
||||||
|
<a href="#" className="hover:text-[#D4BAB6] transition-colors">LinkedIn</a>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<div className="w-1.5 h-1.5 bg-[#D4BAB6] rounded-full animate-pulse"></div>
|
||||||
|
<span>Mentoria Ativa</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
28
Template-02/src/components/Layout.tsx
Normal file
28
Template-02/src/components/Layout.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Link, useLocation } from "react-router-dom";
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import Navbar from "./Navbar";
|
||||||
|
import Footer from "./Footer";
|
||||||
|
|
||||||
|
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||||
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}, [pathname]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen flex flex-col bg-[#FDFBF7] text-[#333333] selection:bg-[#D4B5B0] selection:text-white relative overflow-hidden font-sans">
|
||||||
|
{/* Ambient backgrounds */}
|
||||||
|
<div className="fixed inset-0 opacity-40 pointer-events-none z-0">
|
||||||
|
<div className="absolute top-[-10%] left-[-10%] w-[50%] h-[50%] bg-[#D4B5B0] rounded-full blur-[150px] opacity-30"></div>
|
||||||
|
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-[#E8DCC4] rounded-full blur-[120px] opacity-40"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col flex-grow z-10 relative">
|
||||||
|
<Navbar />
|
||||||
|
<main className="flex-grow pt-20 lg:pt-20">{children}</main>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
305
Template-02/src/components/Navbar.tsx
Normal file
305
Template-02/src/components/Navbar.tsx
Normal file
|
|
@ -0,0 +1,305 @@
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Link, useLocation } from "react-router-dom";
|
||||||
|
import { motion, AnimatePresence } from "motion/react";
|
||||||
|
import { Menu, X, Search, ChevronDown } from "lucide-react";
|
||||||
|
import { cn } from "../lib/utils";
|
||||||
|
import { posts } from "../pages/Blog";
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
{ name: "Início", path: "/" },
|
||||||
|
{ name: "Sobre a Mentora", path: "/sobre" },
|
||||||
|
{ name: "Journal", path: "/blog" },
|
||||||
|
{ name: "Contato", path: "/contato" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function Navbar() {
|
||||||
|
const [isScrolled, setIsScrolled] = useState(false);
|
||||||
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||||
|
const [searchOpen, setSearchOpen] = useState(false);
|
||||||
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
const [langMenuOpen, setLangMenuOpen] = useState(false);
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
const searchResults = searchQuery.trim() !== ""
|
||||||
|
? posts.filter(post =>
|
||||||
|
post.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
|
post.category.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
|
post.desc.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
|
).slice(0, 5) // Limits to 5 results
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const getLang = () => {
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
if (document.cookie.includes('googtrans=/pt/en')) return 'en';
|
||||||
|
if (document.cookie.includes('googtrans=/pt/es')) return 'es';
|
||||||
|
}
|
||||||
|
return 'pt';
|
||||||
|
};
|
||||||
|
const [currentLang, setCurrentLang] = useState(getLang());
|
||||||
|
|
||||||
|
const switchLang = (lang: string) => {
|
||||||
|
const host = window.location.hostname;
|
||||||
|
if (lang === 'pt') {
|
||||||
|
document.cookie = `googtrans=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
|
||||||
|
document.cookie = `googtrans=; expires=Thu, 01 Jan 1970 00:00:00 UTC; domain=.${host}; path=/;`;
|
||||||
|
} else {
|
||||||
|
document.cookie = `googtrans=/pt/${lang}; path=/`;
|
||||||
|
document.cookie = `googtrans=/pt/${lang}; domain=.${host}; path=/`;
|
||||||
|
}
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleScroll = () => {
|
||||||
|
setIsScrolled(window.scrollY > 20);
|
||||||
|
};
|
||||||
|
window.addEventListener("scroll", handleScroll);
|
||||||
|
return () => window.removeEventListener("scroll", handleScroll);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMobileMenuOpen(false);
|
||||||
|
}, [location.pathname]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!document.getElementById("google-translate-script")) {
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.id = "google-translate-script";
|
||||||
|
script.src = "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit";
|
||||||
|
|
||||||
|
const setupScript = document.createElement("script");
|
||||||
|
setupScript.innerHTML = `
|
||||||
|
function googleTranslateElementInit() {
|
||||||
|
new window.google.translate.TranslateElement({
|
||||||
|
pageLanguage: 'pt',
|
||||||
|
includedLanguages: 'pt,en,es',
|
||||||
|
autoDisplay: false
|
||||||
|
}, 'google_translate_element');
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(setupScript);
|
||||||
|
document.body.appendChild(script);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<AnimatePresence>
|
||||||
|
{searchOpen && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
exit={{ opacity: 0, scale: 0.95 }}
|
||||||
|
transition={{ duration: 0.2 }}
|
||||||
|
className="fixed inset-0 z-[100] bg-[#FDFBF7]/95 backdrop-blur-xl flex flex-col pt-32 px-6 lg:px-12"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={() => setSearchOpen(false)}
|
||||||
|
className="absolute top-8 right-6 lg:right-12 text-[#888888] hover:text-[#D4BAB6] transition-colors"
|
||||||
|
aria-label="Fechar busca"
|
||||||
|
>
|
||||||
|
<X size={40} strokeWidth={1} />
|
||||||
|
</button>
|
||||||
|
<div className="container mx-auto max-w-4xl w-full">
|
||||||
|
<span className="text-[#D4BAB6] font-medium tracking-[0.2em] text-xs uppercase block mb-4 border-l pl-4 border-[#D4BAB6]">Pesquisar Journal</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="PROCURAR..."
|
||||||
|
className="w-full bg-transparent border-b border-[#E8DCC4] text-4xl md:text-5xl text-[#333333] font-serif italic outline-none py-4 placeholder:text-[#333333]/30 focus:border-[#D4BAB6] transition-colors"
|
||||||
|
autoFocus
|
||||||
|
value={searchQuery}
|
||||||
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{searchQuery.trim() === "" ? (
|
||||||
|
<div className="mt-12 flex flex-wrap gap-6 items-center text-xs font-medium text-[#888888] tracking-widest uppercase">
|
||||||
|
<span>Sugestões:</span>
|
||||||
|
<Link to="/blog" onClick={() => setSearchOpen(false)} className="hover:text-[#D4BAB6] transition-colors">Bem-estar</Link>
|
||||||
|
<Link to="/sobre" onClick={() => setSearchOpen(false)} className="hover:text-[#D4BAB6] transition-colors">Mentoria</Link>
|
||||||
|
<Link to="/contato" onClick={() => setSearchOpen(false)} className="hover:text-[#D4BAB6] transition-colors">Consultoria</Link>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="mt-12 space-y-4 max-h-[50vh] overflow-y-auto pb-8 pr-4 custom-scrollbar">
|
||||||
|
{searchResults.length > 0 ? (
|
||||||
|
searchResults.map((post, index) => (
|
||||||
|
<Link
|
||||||
|
key={index}
|
||||||
|
to={`/blog/${posts.indexOf(post)}`}
|
||||||
|
state={{ post }}
|
||||||
|
onClick={() => {
|
||||||
|
setSearchOpen(false);
|
||||||
|
setSearchQuery("");
|
||||||
|
}}
|
||||||
|
className="block bg-white/40 border border-[#E8DCC4]/30 hover:border-[#D4BAB6] p-6 transition-all group rounded-lg"
|
||||||
|
>
|
||||||
|
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
||||||
|
<div>
|
||||||
|
<span className="text-[#D4BAB6] text-[10px] font-medium uppercase tracking-widest mb-2 block">{post.category}</span>
|
||||||
|
<h3 className="text-xl md:text-2xl font-serif text-[#333333] group-hover:text-[#D4BAB6] transition-colors">{post.title}</h3>
|
||||||
|
<p className="text-[#666666] text-sm mt-2 line-clamp-1">{post.desc}</p>
|
||||||
|
</div>
|
||||||
|
<span className="text-[#888888] font-medium uppercase tracking-widest text-[11px] whitespace-nowrap self-start md:self-auto border-b border-transparent group-hover:border-[#D4BAB6] group-hover:text-[#D4BAB6] transition-colors pb-1">
|
||||||
|
Ler Artigo
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="text-[#888888] font-serif text-xl italic mt-8 text-center tracking-wide">
|
||||||
|
Nenhum resultado encontrado para "{searchQuery}"
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
|
||||||
|
<header
|
||||||
|
className={cn(
|
||||||
|
"fixed top-0 left-0 right-0 z-50 transition-all duration-300",
|
||||||
|
isScrolled ? "bg-[#FDFBF7]/90 backdrop-blur-md border-b border-[#E8DCC4] py-4 shadow-sm" : "bg-transparent py-6"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl flex items-center justify-between">
|
||||||
|
<Link to="/" className="flex items-center gap-2 group">
|
||||||
|
<span className="text-2xl font-serif tracking-wide text-[#333333] mr-1">AURORA</span>
|
||||||
|
<span className="text-[10px] uppercase tracking-[0.2em] font-medium text-[#D4BAB6] hidden sm:block">Wellness Elite</span>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{/* Desktop Nav */}
|
||||||
|
<nav className="hidden lg:flex items-center gap-10">
|
||||||
|
{links.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.path}
|
||||||
|
to={link.path}
|
||||||
|
className={cn(
|
||||||
|
"text-[11px] font-medium tracking-[0.15em] uppercase transition-colors relative group",
|
||||||
|
location.pathname === link.path
|
||||||
|
? "text-[#D4BAB6]"
|
||||||
|
: "text-[#666666] hover:text-[#D4BAB6]"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{link.name}
|
||||||
|
{location.pathname === link.path && (
|
||||||
|
<motion.div
|
||||||
|
layoutId="navbar-indicator"
|
||||||
|
className="absolute -bottom-2 left-0 right-0 h-[1px] bg-[#D4BAB6]"
|
||||||
|
initial={false}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div className="hidden lg:flex items-center gap-6">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] font-medium tracking-[0.1em] text-[#888888] uppercase">
|
||||||
|
<button onClick={() => switchLang('pt')} className={`hover:text-[#D4BAB6] transition-colors ${currentLang === 'pt' ? 'text-[#333333]' : ''}`}>PT</button>
|
||||||
|
<span className="font-light">|</span>
|
||||||
|
<button onClick={() => switchLang('en')} className={`hover:text-[#D4BAB6] transition-colors ${currentLang === 'en' ? 'text-[#333333]' : ''}`}>EN</button>
|
||||||
|
<span className="font-light">|</span>
|
||||||
|
<button onClick={() => switchLang('es')} className={`hover:text-[#D4BAB6] transition-colors ${currentLang === 'es' ? 'text-[#333333]' : ''}`}>ES</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onClick={() => setSearchOpen(true)} className="text-[#333333] hover:text-[#D4BAB6] transition-colors" aria-label="Buscar">
|
||||||
|
<Search size={18} strokeWidth={1.5} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
to="/contato"
|
||||||
|
className="border border-[#E8DCC4] px-6 py-2 rounded-full hover:bg-[#D4BAB6] hover:text-white hover:border-[#D4BAB6] transition-all text-[11px] uppercase tracking-widest font-medium text-[#333333]"
|
||||||
|
>
|
||||||
|
Consultoria
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right side controls */}
|
||||||
|
<div className="flex items-center gap-3 lg:gap-0 lg:ml-4">
|
||||||
|
<div id="google_translate_element" className="hidden"></div>
|
||||||
|
|
||||||
|
<div className="lg:hidden flex items-center gap-3">
|
||||||
|
<div className="relative text-[10px] font-medium tracking-widest text-[#333333] uppercase">
|
||||||
|
<button
|
||||||
|
onClick={() => setLangMenuOpen(!langMenuOpen)}
|
||||||
|
className="flex items-center gap-1 hover:text-[#D4BAB6] transition-colors p-2"
|
||||||
|
>
|
||||||
|
{currentLang.toUpperCase()} <ChevronDown size={14} strokeWidth={1.5} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{langMenuOpen && (
|
||||||
|
<div className="absolute top-10 left-1/2 -translate-x-1/2 bg-[#FDFBF7] border border-[#E8DCC4] rounded-lg shadow-xl flex flex-col min-w-[60px] overflow-hidden z-50">
|
||||||
|
{['pt', 'en', 'es'].map(lang => (
|
||||||
|
<button
|
||||||
|
key={lang}
|
||||||
|
onClick={() => {
|
||||||
|
switchLang(lang);
|
||||||
|
setLangMenuOpen(false);
|
||||||
|
}}
|
||||||
|
className={`px-4 py-3 text-center transition-colors hover:bg-[#E8DCC4]/20 ${currentLang === lang ? 'text-[#D4BAB6]' : 'text-[#666666] hover:text-[#333333]'}`}
|
||||||
|
>
|
||||||
|
{lang.toUpperCase()}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onClick={() => setSearchOpen(true)} className="text-[#333333] hover:text-[#D4BAB6] transition-colors p-2" aria-label="Buscar">
|
||||||
|
<Search size={18} strokeWidth={1.5} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu Toggle */}
|
||||||
|
<button
|
||||||
|
className="lg:hidden text-[#333333] p-2 focus:outline-none"
|
||||||
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||||
|
aria-label="Toggle Menu"
|
||||||
|
>
|
||||||
|
{mobileMenuOpen ? <X size={24} strokeWidth={1.5} /> : <Menu size={24} strokeWidth={1.5} />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{/* Mobile Menu Content */}
|
||||||
|
<AnimatePresence>
|
||||||
|
{mobileMenuOpen && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: -20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, y: -20 }}
|
||||||
|
transition={{ duration: 0.2 }}
|
||||||
|
className="fixed inset-0 z-40 bg-[#FDFBF7] pt-24 px-6 pb-6 flex flex-col"
|
||||||
|
>
|
||||||
|
<nav className="flex flex-col gap-8 items-center justify-center flex-grow">
|
||||||
|
{links.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.path}
|
||||||
|
to={link.path}
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
className={cn(
|
||||||
|
"font-serif text-3xl md:text-5xl transition-colors tracking-wide",
|
||||||
|
location.pathname === link.path
|
||||||
|
? "text-[#D4BAB6]"
|
||||||
|
: "text-[#333333] hover:text-[#D4BAB6]"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{link.name}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
<Link
|
||||||
|
to="/contato"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
className="mt-8 px-8 py-4 border border-[#E8DCC4] text-[#333333] font-medium uppercase tracking-widest text-[11px] text-center w-full max-w-[280px] hover:bg-[#D4BAB6] hover:text-white hover:border-[#D4BAB6] transition-all rounded-full"
|
||||||
|
>
|
||||||
|
Agendar Reunião
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
44
Template-02/src/components/SEO.tsx
Normal file
44
Template-02/src/components/SEO.tsx
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Helmet } from 'react-helmet-async';
|
||||||
|
|
||||||
|
interface SEOProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
url?: string;
|
||||||
|
image?: string;
|
||||||
|
type?: string;
|
||||||
|
schema?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SEO({ title, description, url, image, type = "website", schema }: SEOProps) {
|
||||||
|
const siteName = "Aurora | Wellness & Mentoring";
|
||||||
|
const defaultImage = "https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=1200&auto=format&fit=crop";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Helmet>
|
||||||
|
<title>{title}</title>
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
|
||||||
|
{/* Open Graph / Facebook */}
|
||||||
|
<meta property="og:type" content={type} />
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
{url && <meta property="og:url" content={url} />}
|
||||||
|
<meta property="og:image" content={image || defaultImage} />
|
||||||
|
<meta property="og:site_name" content={siteName} />
|
||||||
|
|
||||||
|
{/* Twitter */}
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:title" content={title} />
|
||||||
|
<meta name="twitter:description" content={description} />
|
||||||
|
<meta name="twitter:image" content={image || defaultImage} />
|
||||||
|
|
||||||
|
{/* Structured Data / JSON-LD */}
|
||||||
|
{schema && (
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{JSON.stringify(schema)}
|
||||||
|
</script>
|
||||||
|
)}
|
||||||
|
</Helmet>
|
||||||
|
);
|
||||||
|
}
|
||||||
85
Template-02/src/index.css
Normal file
85
Template-02/src/index.css
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500&display=swap');
|
||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||||
|
--font-serif: "Cormorant Garamond", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
||||||
|
|
||||||
|
--animate-accordion-down: accordion-down 0.2s ease-out;
|
||||||
|
--animate-accordion-up: accordion-up 0.2s ease-out;
|
||||||
|
|
||||||
|
@keyframes accordion-down {
|
||||||
|
from { height: 0 }
|
||||||
|
to { height: var(--radix-accordion-content-height) }
|
||||||
|
}
|
||||||
|
@keyframes accordion-up {
|
||||||
|
from { height: var(--radix-accordion-content-height) }
|
||||||
|
to { height: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
background-color: #FDFBF7;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background-color: #D4BAB6;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
/* Prevent horizontal scroll on mobile */
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-color: #FDFBF7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide scrollbar for clean look */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #FDFBF7;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #E8DCC4;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #D4BAB6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-scrollbar::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
}
|
||||||
|
.custom-scrollbar::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.custom-scrollbar::-webkit-scrollbar-thumb {
|
||||||
|
background: #E8DCC4;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #D4BAB6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Google Translate overrides */
|
||||||
|
#google_translate_element {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.goog-te-banner-frame.skiptranslate,
|
||||||
|
.skiptranslate > iframe.goog-te-banner-frame {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
top: 0px !important;
|
||||||
|
position: static !important;
|
||||||
|
}
|
||||||
|
#goog-gt-tt, .goog-te-balloon-frame {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.goog-text-highlight {
|
||||||
|
background-color: transparent !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
6
Template-02/src/lib/utils.ts
Normal file
6
Template-02/src/lib/utils.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { clsx, type ClassValue } from "clsx";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs));
|
||||||
|
}
|
||||||
13
Template-02/src/main.tsx
Normal file
13
Template-02/src/main.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import {StrictMode} from 'react';
|
||||||
|
import {createRoot} from 'react-dom/client';
|
||||||
|
import { HelmetProvider } from 'react-helmet-async';
|
||||||
|
import App from './App.tsx';
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
createRoot(document.getElementById('root')!).render(
|
||||||
|
<StrictMode>
|
||||||
|
<HelmetProvider>
|
||||||
|
<App />
|
||||||
|
</HelmetProvider>
|
||||||
|
</StrictMode>,
|
||||||
|
);
|
||||||
180
Template-02/src/pages/Blog.tsx
Normal file
180
Template-02/src/pages/Blog.tsx
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
import React, { useRef } from "react";
|
||||||
|
import { motion, useScroll, useTransform } from "motion/react";
|
||||||
|
import { ArrowRight, Clock } from "lucide-react";
|
||||||
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
export const posts = [
|
||||||
|
{
|
||||||
|
category: "Movimento & Rotina",
|
||||||
|
title: "O Fim do Platô: Técnicas Suaves de Progressão",
|
||||||
|
desc: "Descubra como utilizar métodos gentis para forçar seu corpo a construir novos tecidos e quebrar estagnação, respeitando seus limites.",
|
||||||
|
img: "https://images.unsplash.com/photo-1518611012118-696072aa579a?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "8 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Nutrição Intuitiva",
|
||||||
|
title: "Ciclo de Nutrientes para Renovação Diária",
|
||||||
|
desc: "A estratégia nutricional adaptada para quem quer mais saúde e controle corporal sem perder o prazer de viver.",
|
||||||
|
img: "https://images.unsplash.com/photo-1490645935967-10de6ba17061?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "12 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Mindset Saudável",
|
||||||
|
title: "A Psicologia da Constância Gentil",
|
||||||
|
desc: "Por que você desiste após 3 semanas? O modelo mental necessário para encarar a saúde como um ato de amor próprio e não punição.",
|
||||||
|
img: "https://images.unsplash.com/photo-1517436073-3b1b1b1b1b1b?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "5 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Suplementação Inteligente",
|
||||||
|
title: "Guia Definitivo da Vitalidade",
|
||||||
|
desc: "Os suplementos essenciais para a saúde da mulher. Mitos, verdades e como usar a favor do seu bem-estar diário.",
|
||||||
|
img: "https://images.unsplash.com/photo-1593095948071-474c5cc2989d?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "6 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Movimento",
|
||||||
|
title: "Fluidez vs. Musculação: A Ordem Importa?",
|
||||||
|
desc: "Entenda a sinalização molecular e por que integrar modalidades pode ser o segredo para um corpo esguio e tonificado.",
|
||||||
|
img: "https://images.unsplash.com/photo-1544367567-0f2fcb009e0b?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "7 min"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Recuperação",
|
||||||
|
title: "Dormir é Viver: A Importância do Sono Profundo",
|
||||||
|
desc: "Você floresce no descanso. Estratégias de higiene do sono para maximizar a sua imunidade e renovação hormonal.",
|
||||||
|
img: "https://images.unsplash.com/photo-1515444744559-7be63e160e1d?q=80&w=800&auto=format&fit=crop",
|
||||||
|
readTime: "9 min"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function FeaturedPost() {
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const { scrollYProgress } = useScroll({
|
||||||
|
target: ref,
|
||||||
|
offset: ["start end", "end start"]
|
||||||
|
});
|
||||||
|
const y = useTransform(scrollYProgress, [0, 1], ["-10%", "10%"]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ref} className="relative group overflow-hidden border border-[#E8DCC4] bg-white rounded-2xl shadow-sm flex flex-col md:flex-row h-auto md:h-[500px]">
|
||||||
|
<div className="w-full md:w-1/2 h-64 md:h-full relative overflow-hidden">
|
||||||
|
<motion.div style={{ y }} className="absolute top-[-10%] left-0 w-full h-[120%]">
|
||||||
|
<img src="https://images.unsplash.com/photo-1518611012118-696072aa579a?q=80&w=1200&auto=format&fit=crop" className="w-full h-full object-cover group-hover:scale-105 transition-all duration-700 origin-center opacity-90" alt="Featured" />
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full md:w-1/2 p-8 md:p-16 flex flex-col justify-center">
|
||||||
|
<div className="flex items-center gap-4 mb-6">
|
||||||
|
<span className="bg-[#FAF5F0] text-[#D4BAB6] text-[10px] font-medium uppercase tracking-widest px-4 py-1.5 rounded-full relative z-10">Autocuidado</span>
|
||||||
|
<div className="flex items-center gap-1 text-[10px] text-[#888888] uppercase tracking-widest font-medium relative z-10">
|
||||||
|
<Clock className="w-3 h-3" /> 10 Min Leitura
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Link to="/blog/1" state={{ post: posts[0] }} className="text-3xl md:text-[40px] font-serif text-[#333333] tracking-normal mb-6 hover:text-[#D4BAB6] transition-colors cursor-pointer leading-[1.1] block relative z-10">O Fim do Platô: Técnicas Suaves de Progressão</Link>
|
||||||
|
<p className="text-[#666666] font-light mb-8 line-clamp-3 text-sm relative z-10">
|
||||||
|
Descubra como utilizar métodos gentis para forçar seu corpo a construir novos tecidos e quebrar estagnação, respeitando seus limites diários.
|
||||||
|
</p>
|
||||||
|
<div className="mt-auto relative z-10">
|
||||||
|
<Link to="/blog/1" state={{ post: posts[0] }} className="inline-flex items-center gap-2 text-[#D4BAB6] font-medium uppercase tracking-widest text-[11px] hover:text-[#C2A19D] transition-colors pb-1 cursor-pointer">
|
||||||
|
Ler Artigo Completo <ArrowRight className="w-4 h-4 ml-1" />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PostCard: React.FC<{ post: any, index: number }> = ({ post, index }) => {
|
||||||
|
const ref = useRef<HTMLAnchorElement>(null);
|
||||||
|
const { scrollYProgress } = useScroll({
|
||||||
|
target: ref,
|
||||||
|
offset: ["start end", "end start"]
|
||||||
|
});
|
||||||
|
const y = useTransform(scrollYProgress, [0, 1], ["-10%", "10%"]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link to={`/blog/${index+2}`} state={{ post }} ref={ref} className="h-full block">
|
||||||
|
<motion.article
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: (index % 3) * 0.1 }}
|
||||||
|
className="bg-white border border-[#E8DCC4] rounded-2xl hover:border-[#D4BAB6]/50 transition-all flex flex-col group cursor-pointer overflow-hidden p-6 hover:shadow-lg h-full"
|
||||||
|
>
|
||||||
|
<div className="relative h-56 overflow-hidden w-[calc(100%+3rem)] -mx-6 -mt-6 mb-6">
|
||||||
|
<motion.div style={{ y }} className="absolute top-[-15%] left-0 w-full h-[130%]">
|
||||||
|
<img src={post.img} className="w-full h-full object-cover opacity-90 group-hover:scale-105 transition-all duration-700 origin-center" alt={post.title} />
|
||||||
|
</motion.div>
|
||||||
|
<div className="absolute bottom-4 right-4 bg-white/90 backdrop-blur-sm text-[#D4BAB6] px-3 py-1 text-[9px] font-medium uppercase tracking-widest z-10 rounded-full shadow-sm">
|
||||||
|
{post.category}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col flex-grow">
|
||||||
|
<h3 className="text-xl font-serif tracking-normal mb-3 text-[#333333] group-hover:text-[#D4BAB6] transition-colors line-clamp-2">{post.title}</h3>
|
||||||
|
<p className="text-xs text-[#666666] font-light mb-6 flex-grow line-clamp-3">{post.desc}</p>
|
||||||
|
<div className="flex items-center justify-between mt-auto pt-4 border-t border-[#E8DCC4]/50">
|
||||||
|
<div className="flex items-center gap-2 text-[10px] uppercase tracking-widest font-medium text-[#888888]">
|
||||||
|
<Clock className="w-3 h-3" /> {post.readTime}
|
||||||
|
</div>
|
||||||
|
<ArrowRight className="w-4 h-4 text-[#D4BAB6] group-hover:translate-x-1 transition-all" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.article>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Blog() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col pt-10 bg-[#FDFBF7]">
|
||||||
|
<SEO
|
||||||
|
title="Journal | Aurora Wellness"
|
||||||
|
description="Conteúdo inspirador sobre saúde feminina, nutrição intuitiva e expansão da mente."
|
||||||
|
/>
|
||||||
|
<section className="py-24 lg:py-32 bg-[#FAF5F0] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl text-center">
|
||||||
|
<span className="text-[#D4BAB6] font-medium tracking-[0.2em] text-xs uppercase block mb-6">Journal</span>
|
||||||
|
<h1 className="text-5xl sm:text-6xl md:text-[90px] leading-[0.9] font-serif tracking-normal text-[#333333] mb-8">
|
||||||
|
Inspiração para<br/>
|
||||||
|
<span className="text-[#A3918D] italic">a Alma.</span>
|
||||||
|
</h1>
|
||||||
|
<p className="text-[#666666] text-lg max-w-2xl mx-auto font-light leading-relaxed">
|
||||||
|
Artigos leves e baseados em ciência gentil. O entendimento profundo por trás do seu bem-estar diário.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="py-20 bg-[#FDFBF7] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
{/* Featured Post (First one) */}
|
||||||
|
<div className="mb-20">
|
||||||
|
<FeaturedPost />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Grid Posts */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
|
{posts.map((post, i) => (
|
||||||
|
<PostCard post={post} index={i} key={`post-${i}`} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Newsletter */}
|
||||||
|
<section className="py-24 bg-[#E8DCC4]/20 border-t border-[#E8DCC4] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-3xl text-center">
|
||||||
|
<h2 className="text-4xl md:text-[50px] font-serif tracking-normal text-[#333333] mb-4">Cartas de <span className="text-[#D4BAB6] italic">Inspiração</span></h2>
|
||||||
|
<p className="text-[#666666] mb-10 font-light text-sm max-w-lg mx-auto">Junte-se à nossa comunidade e receba, quinzenalmente, pílulas de sabedoria sobre corpo e mente diretamente na sua caixa de entrada.</p>
|
||||||
|
<form className="flex flex-col sm:flex-row gap-3 max-w-lg mx-auto">
|
||||||
|
<input type="email" placeholder="Seu melhor e-mail" className="flex-grow bg-white border border-[#E8DCC4] rounded-full px-6 py-3 text-[#333333] placeholder-[#888888] focus:outline-none focus:border-[#D4BAB6] transition-colors font-light" />
|
||||||
|
<button type="button" className="bg-[#D4BAB6] text-white rounded-full font-medium uppercase tracking-[0.1em] text-[10px] hover:bg-[#C2A19D] transition-colors px-8 py-4 shadow-sm">
|
||||||
|
Inscrever-se
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
154
Template-02/src/pages/BlogPost.tsx
Normal file
154
Template-02/src/pages/BlogPost.tsx
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
import { useLocation, Link, Navigate } from "react-router-dom";
|
||||||
|
import { ArrowLeft, Clock, Tag, Share2, Facebook, Twitter, Linkedin } from "lucide-react";
|
||||||
|
import { motion, useScroll, useSpring } from "motion/react";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
export default function BlogPost() {
|
||||||
|
const location = useLocation();
|
||||||
|
const post = location.state?.post;
|
||||||
|
|
||||||
|
const { scrollYProgress } = useScroll();
|
||||||
|
const scaleX = useSpring(scrollYProgress, {
|
||||||
|
stiffness: 100,
|
||||||
|
damping: 30,
|
||||||
|
restDelta: 0.001
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!post) return <Navigate to="/blog" />;
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "BlogPosting",
|
||||||
|
"headline": post.title,
|
||||||
|
"image": post.img,
|
||||||
|
"description": post.desc,
|
||||||
|
"publisher": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "Aurora Wellness",
|
||||||
|
"logo": {
|
||||||
|
"@type": "ImageObject",
|
||||||
|
"url": "https://aurorawellness.com/logo.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"datePublished": "2024-01-01"
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col bg-[#FDFBF7] relative min-h-screen">
|
||||||
|
<SEO
|
||||||
|
title={`${post.title} | Journal Aurora`}
|
||||||
|
description={post.desc}
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
{/* Scroll Progress Bar */}
|
||||||
|
<motion.div
|
||||||
|
className="fixed top-0 left-0 right-0 h-1 bg-[#D4BAB6] origin-left z-50 pointer-events-none"
|
||||||
|
style={{ scaleX }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Hero Section */}
|
||||||
|
<section className="relative pt-32 pb-20 px-6 lg:px-12 z-10">
|
||||||
|
<div className="max-w-4xl mx-auto">
|
||||||
|
<Link to="/blog" className="inline-flex items-center gap-2 text-[#888888] hover:text-[#D4BAB6] transition-colors text-[10px] uppercase tracking-widest font-medium mb-12">
|
||||||
|
<ArrowLeft className="w-4 h-4" /> Voltar ao Journal
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="flex flex-wrap items-center gap-4 mb-8">
|
||||||
|
<span className="bg-[#FAF5F0] text-[#D4BAB6] px-4 py-1.5 rounded-full text-[10px] font-medium uppercase tracking-widest">
|
||||||
|
{post.category}
|
||||||
|
</span>
|
||||||
|
<div className="flex items-center gap-2 text-[10px] text-[#888888] uppercase tracking-widest font-medium">
|
||||||
|
<Clock className="w-3 h-3" /> {post.readTime}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2 text-[10px] text-[#888888] uppercase tracking-widest font-medium">
|
||||||
|
<Tag className="w-3 h-3" /> Autocuidado
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className="text-4xl sm:text-5xl md:text-[60px] font-serif leading-[1.1] tracking-normal text-[#333333] mb-8">
|
||||||
|
{post.title}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div className="flex items-center justify-between border-t border-b border-[#E8DCC4]/50 py-6 mb-12">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<img src="https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=100&h=100&fit=crop" alt="Aurora" className="w-12 h-12 rounded-full border border-[#D4BAB6]" />
|
||||||
|
<div>
|
||||||
|
<div className="text-sm font-serif text-[#333333]">Aurora Elena</div>
|
||||||
|
<div className="text-[10px] text-[#888888] uppercase tracking-widest mt-1">Mentora Fundadora</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="hidden sm:flex items-center gap-4">
|
||||||
|
<span className="text-[10px] text-[#888888] uppercase tracking-widest font-medium flex items-center gap-2">
|
||||||
|
<Share2 className="w-3 h-3" /> Compartilhar
|
||||||
|
</span>
|
||||||
|
<button aria-label="Share on Facebook" className="w-8 h-8 rounded-full border border-[#E8DCC4] flex items-center justify-center text-[#888888] hover:text-[#D4BAB6] hover:border-[#D4BAB6] transition-colors">
|
||||||
|
<Facebook className="w-3 h-3" />
|
||||||
|
</button>
|
||||||
|
<button aria-label="Share on Twitter" className="w-8 h-8 rounded-full border border-[#E8DCC4] flex items-center justify-center text-[#888888] hover:text-[#D4BAB6] hover:border-[#D4BAB6] transition-colors">
|
||||||
|
<Twitter className="w-3 h-3" />
|
||||||
|
</button>
|
||||||
|
<button aria-label="Share on LinkedIn" className="w-8 h-8 rounded-full border border-[#E8DCC4] flex items-center justify-center text-[#888888] hover:text-[#D4BAB6] hover:border-[#D4BAB6] transition-colors">
|
||||||
|
<Linkedin className="w-3 h-3" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="max-w-5xl mx-auto w-full aspect-video rounded-3xl overflow-hidden mb-20 shadow-md">
|
||||||
|
<img src={post.img} alt={post.title} className="w-full h-full object-cover" />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Content Section */}
|
||||||
|
<section className="px-6 lg:px-12 pb-32">
|
||||||
|
<div className="max-w-3xl mx-auto relative">
|
||||||
|
|
||||||
|
<div className="prose prose-lg prose-neutral max-w-none">
|
||||||
|
<p className="text-xl text-[#666666] font-light leading-relaxed mb-10 italic">
|
||||||
|
{post.desc}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl md:text-3xl font-serif text-[#333333] mb-6 mt-12">O Ponto de Partida</h2>
|
||||||
|
<p className="text-[#666666] font-light leading-relaxed mb-6">
|
||||||
|
Muitas de nós acreditamos que o caminho para o corpo dos sonhos exige sofrimento, privações extremas e punição na academia. O que a ciência gentil nos mostra, porém, é que o estresse prolongado — seja ele emocional ou físico — bloqueia os nossos resultados. A biologia do nosso corpo responde melhor ao estímulo quando há segurança, e não terror.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="text-[#666666] font-light leading-relaxed mb-6">
|
||||||
|
Na metodologia Aurora, tratamos a sinalização hormonal como uma conversa. Se você grita com seu corpo (cortisol nas alturas), ele se fecha. Se você sussurra com firmeza (treino inteligente), ele floresce e reconstrói tecidos.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<blockquote className="border-l-2 border-[#D4BAB6] pl-6 my-10 italic text-xl text-[#333333] font-serif">
|
||||||
|
"O verdadeiro empoderamento vem quando aprendemos a cuidar do nosso corpo com amor e disciplina contínua."
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<h2 className="text-2xl md:text-3xl font-serif text-[#333333] mb-6 mt-12">Como Aplicar Hoje</h2>
|
||||||
|
<p className="text-[#666666] font-light leading-relaxed mb-6">
|
||||||
|
Comece pelas pequenas pausas. Ao final de um dia exaustivo, o que o seu corpo realmente pede? É uma corrida extenuante, ou uma caminhada revigorante seguida de um treino restaurador? Aprender a ouvir é a chave.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul className="list-disc pl-6 space-y-4 text-[#666666] font-light mb-8 marker:text-[#D4BAB6]">
|
||||||
|
<li>Priorize o sono profundo antes de intensificar os treinos.</li>
|
||||||
|
<li>Inclua elementos que reduzam o estado de alerta do seu corpo.</li>
|
||||||
|
<li>Observe os alimentos que trazem energia sustentável.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-20 p-8 md:p-12 bg-[#FAF5F0] border border-[#E8DCC4] rounded-2xl flex flex-col items-center text-center">
|
||||||
|
<h3 className="text-2xl font-serif text-[#333333] mb-4">Gostou deste conteúdo?</h3>
|
||||||
|
<p className="text-[#666666] text-sm font-light mb-8 max-w-md">Para mergulhar mais fundo na transformação que propomos, convidamos você a conhecer a nossa Mentoria Premium.</p>
|
||||||
|
<Link to="/contato" className="bg-[#D4BAB6] text-white px-8 py-4 rounded-full font-medium uppercase tracking-[0.1em] text-[10px] hover:bg-[#C2A19D] transition-all inline-block shadow-sm">
|
||||||
|
Ver Detalhes da Mentoria
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
231
Template-02/src/pages/Contato.tsx
Normal file
231
Template-02/src/pages/Contato.tsx
Normal file
|
|
@ -0,0 +1,231 @@
|
||||||
|
import { useState } from "react";
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import { MapPin, Mail, MessageSquare, ArrowRight, Instagram, Sparkles } from "lucide-react";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
const FADE_UP = {
|
||||||
|
hidden: { opacity: 0, y: 30 },
|
||||||
|
visible: { opacity: 1, y: 0, transition: { duration: 0.6, ease: "easeOut" } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAGGER = {
|
||||||
|
visible: { transition: { staggerChildren: 0.1 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Contato() {
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
nome: "",
|
||||||
|
whatsapp: "",
|
||||||
|
objetivo: "emagrecimento",
|
||||||
|
motivacao: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
const [nameError, setNameError] = useState("");
|
||||||
|
const [whatsappError, setWhatsappError] = useState("");
|
||||||
|
const [motivationError, setMotivationError] = useState("");
|
||||||
|
|
||||||
|
const handleSubmit = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setNameError("");
|
||||||
|
setWhatsappError("");
|
||||||
|
setMotivationError("");
|
||||||
|
|
||||||
|
let isValid = true;
|
||||||
|
if (formData.nome.split(" ").length < 2) {
|
||||||
|
setNameError("Por favor, insira nome e sobrenome.");
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
const whatsappClean = formData.whatsapp.replace(/\D/g, "");
|
||||||
|
if (whatsappClean.length < 10) {
|
||||||
|
setWhatsappError("WhatsApp inválido. Inclua o DDD.");
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
if (formData.motivacao.length < 20) {
|
||||||
|
setMotivationError("Por favor, conte um pouco mais sobre você (mín. 20 caracteres).");
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid) {
|
||||||
|
const message = `*Nova Aplicação de Mentoria*%0A%0A*Nome:* ${formData.nome}%0A*Objetivo:* ${formData.objetivo}%0A*Motivação:* ${formData.motivacao}`;
|
||||||
|
window.open(`https://wa.me/5511999999999?text=${message}`, "_blank");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "ContactPage",
|
||||||
|
"name": "Contato - Aurora Wellness",
|
||||||
|
"description": "Formulário de aplicação para a mentoria de bem-estar e performance de Aurora Elena.",
|
||||||
|
"url": "https://aurorawellness.com/contato"
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col bg-[#FDFBF7]">
|
||||||
|
<SEO
|
||||||
|
title="Contato | Aurora Wellness"
|
||||||
|
description="Aplique agora para a nossa mentoria. Transforme corpo e mente com acompanhamento especializado e gentil."
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
{/* Header */}
|
||||||
|
<section className="py-32 lg:py-48 bg-[#FAF5F0] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl relative z-10">
|
||||||
|
<motion.div
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
variants={STAGGER}
|
||||||
|
className="max-w-3xl"
|
||||||
|
>
|
||||||
|
<span className="text-[#D4BAB6] font-medium tracking-[0.2em] text-xs uppercase block mb-6 border-l pl-4 border-[#D4BAB6]">Vamos Conversar</span>
|
||||||
|
<h1 className="text-5xl sm:text-6xl md:text-[90px] leading-[0.9] font-serif tracking-normal text-[#333333] mb-8">
|
||||||
|
Sua Jornada<br/>
|
||||||
|
<span className="text-[#A3918D] italic">Começa Aqui.</span>
|
||||||
|
</h1>
|
||||||
|
<p className="text-lg text-[#666666] font-light max-w-xl leading-relaxed">
|
||||||
|
Dê o primeiro passo em direção ao cuidado que você merece. Preencha o formulário e deixe nossa equipe cuidar do resto.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Main Content */}
|
||||||
|
<section className="py-24 bg-[#FDFBF7] relative z-10 -mt-10 lg:-mt-20">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl relative z-20">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-20">
|
||||||
|
|
||||||
|
{/* Informações de Contato */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, x: -30 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
className="lg:col-span-4 flex flex-col justify-between"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div className="mb-12">
|
||||||
|
<div className="flex items-center gap-4 mb-4">
|
||||||
|
<div className="w-10 h-10 rounded-full bg-[#FAF5F0] flex items-center justify-center border border-[#E8DCC4]">
|
||||||
|
<MessageSquare className="w-4 h-4 text-[#D4BAB6]" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="text-sm font-medium uppercase tracking-widest text-[#333333]">WhatsApp Direto</h4>
|
||||||
|
<a href="https://wa.me/5511999999999" target="_blank" rel="noopener noreferrer" className="text-[#666666] font-light mt-1 hover:text-[#D4BAB6] transition-colors block">+55 (11) 99999-9999</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-12">
|
||||||
|
<div className="flex items-center gap-4 mb-4">
|
||||||
|
<div className="w-10 h-10 rounded-full bg-[#FAF5F0] flex items-center justify-center border border-[#E8DCC4]">
|
||||||
|
<Mail className="w-4 h-4 text-[#D4BAB6]" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="text-sm font-medium uppercase tracking-widest text-[#333333]">E-mail Corporativo</h4>
|
||||||
|
<p className="text-[#666666] font-light mt-1">contato@aurorawellness.com</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-12">
|
||||||
|
<div className="flex items-center gap-4 mb-4">
|
||||||
|
<div className="w-10 h-10 rounded-full bg-[#FAF5F0] flex items-center justify-center border border-[#E8DCC4]">
|
||||||
|
<MapPin className="w-4 h-4 text-[#D4BAB6]" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="text-sm font-medium uppercase tracking-widest text-[#333333]">Localização</h4>
|
||||||
|
<p className="text-[#666666] font-light mt-1">Atendimento Global (Online)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative mt-8 lg:mt-0 p-8 bg-[#FAF5F0] rounded-2xl border border-[#E8DCC4] overflow-hidden">
|
||||||
|
<Sparkles className="absolute top-4 right-4 w-6 h-6 text-[#D4BAB6]/30" strokeWidth={1.5} />
|
||||||
|
<div className="relative z-10 flex flex-col items-start">
|
||||||
|
<h3 className="text-xl font-serif text-[#333333] mb-4">Siga-nos Inspirando</h3>
|
||||||
|
<p className="text-sm text-[#666666] font-light mb-6">Acompanhe dicas diárias de bem-estar e performance em nosso Instagram.</p>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="flex items-center gap-2 text-[#D4BAB6] hover:text-[#C2A19D] transition-colors text-[11px] font-medium uppercase tracking-widest"
|
||||||
|
>
|
||||||
|
<Instagram className="w-4 h-4" />
|
||||||
|
@aurorawellness
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Formulário */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 40 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.8, delay: 0.2 }}
|
||||||
|
className="lg:col-span-8 bg-white border border-[#E8DCC4] rounded-2xl p-8 md:p-12 shadow-sm"
|
||||||
|
>
|
||||||
|
<form onSubmit={handleSubmit} className="flex flex-col gap-8">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<label className="text-[10px] font-medium uppercase tracking-widest text-[#888888]">Nome Completo</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={formData.nome}
|
||||||
|
onChange={(e) => setFormData({...formData, nome: e.target.value})}
|
||||||
|
placeholder="Seu nome completo"
|
||||||
|
className={`bg-[#FDFBF7] border ${nameError ? "border-red-400" : "border-[#E8DCC4]"} rounded-lg px-4 py-3 text-[#333333] placeholder-[#888888]/40 focus:outline-none focus:border-[#D4BAB6] transition-colors font-light`}
|
||||||
|
/>
|
||||||
|
{nameError && <span className="text-red-400 text-[10px] font-medium">{nameError}</span>}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<label className="text-[10px] font-medium uppercase tracking-widest text-[#888888]">WhatsApp</label>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
value={formData.whatsapp}
|
||||||
|
onChange={(e) => setFormData({...formData, whatsapp: e.target.value})}
|
||||||
|
placeholder="(11) 99999-9999"
|
||||||
|
className={`bg-[#FDFBF7] border ${whatsappError ? "border-red-400" : "border-[#E8DCC4]"} rounded-lg px-4 py-3 text-[#333333] placeholder-[#888888]/40 focus:outline-none focus:border-[#D4BAB6] transition-colors font-light`}
|
||||||
|
/>
|
||||||
|
{whatsappError && <span className="text-red-400 text-[10px] font-medium">{whatsappError}</span>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<label className="text-[10px] font-medium uppercase tracking-widest text-[#888888]">Objetivo Principal</label>
|
||||||
|
<div className="relative">
|
||||||
|
<select
|
||||||
|
value={formData.objetivo}
|
||||||
|
onChange={(e) => setFormData({...formData, objetivo: e.target.value})}
|
||||||
|
className="w-full bg-[#FDFBF7] border border-[#E8DCC4] rounded-lg px-4 py-3 text-[#333333] focus:outline-none focus:border-[#D4BAB6] transition-colors appearance-none font-light"
|
||||||
|
>
|
||||||
|
<option value="emagrecimento">Tonificação & Estética</option>
|
||||||
|
<option value="saude">Saúde Pélvica & Bem-estar</option>
|
||||||
|
<option value="hipertrofia">Ganho de Massa</option>
|
||||||
|
<option value="habitos">Rotina & Hábitos</option>
|
||||||
|
</select>
|
||||||
|
<div className="absolute right-4 top-1/2 -translate-y-1/2 pointer-events-none text-[#888888]">
|
||||||
|
<svg width="12" height="8" viewBox="0 0 12 8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<label className="text-[10px] font-medium uppercase tracking-widest text-[#888888]">Sua História</label>
|
||||||
|
<textarea
|
||||||
|
rows={5}
|
||||||
|
value={formData.motivacao}
|
||||||
|
onChange={(e) => setFormData({...formData, motivacao: e.target.value})}
|
||||||
|
placeholder="Conte-nos brevemente por que você busca essa transformação hoje..."
|
||||||
|
className={`bg-[#FDFBF7] border ${motivationError ? "border-red-400" : "border-[#E8DCC4]"} rounded-lg px-4 py-3 text-[#333333] focus:outline-none focus:border-[#D4BAB6] transition-colors resize-none placeholder-[#888888]/40 font-light`}
|
||||||
|
/>
|
||||||
|
{motivationError && <span className="text-red-400 text-[10px] font-medium">{motivationError}</span>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button className="self-end flex items-center justify-center gap-2 mt-2 px-10 py-4 bg-[#D4BAB6] text-white rounded-full font-medium uppercase tracking-[0.1em] text-[11px] hover:bg-[#C2A19D] transition-all transform hover:-translate-y-1 shadow-[0_10px_30px_rgba(212,186,182,0.3)]">
|
||||||
|
Enviar Aplicação <ArrowRight className="w-4 h-4 ml-2" />
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
340
Template-02/src/pages/Home.tsx
Normal file
340
Template-02/src/pages/Home.tsx
Normal file
|
|
@ -0,0 +1,340 @@
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import { ArrowRight, CheckCircle2, Sparkles, Feather, Activity, Target } from "lucide-react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
const FADE_UP = {
|
||||||
|
hidden: { opacity: 0, y: 40 },
|
||||||
|
visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAGGER = {
|
||||||
|
visible: { transition: { staggerChildren: 0.2 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
const schema = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "HealthAndBeautyBusiness",
|
||||||
|
"name": "Aurora Elite Wellness",
|
||||||
|
"image": "https://images.unsplash.com/photo-1518611012118-696072aa579a?q=80&w=2940&auto=format&fit=crop",
|
||||||
|
"description": "Mentoria e bem-estar para mulheres que buscam uma vida leve, saudável e sofisticada.",
|
||||||
|
"url": "https://aurorawellness.com",
|
||||||
|
"priceRange": "$$$"
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col bg-[#FDFBF7]">
|
||||||
|
<SEO
|
||||||
|
title="Aurora Wellness | Elegância e Performance Feminina"
|
||||||
|
description="Mentoria e bem-estar para mulheres que buscam uma vida leve, saudável e sofisticada."
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
{/* 1. HERO SECTION */}
|
||||||
|
<section className="relative min-h-screen flex items-center pt-20 overflow-hidden">
|
||||||
|
{/* Background Image with Overlay */}
|
||||||
|
<div className="absolute inset-0 w-full z-0 h-full">
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-r from-[#FDFBF7] from-30% via-[#FDFBF7]/90 via-60% to-transparent z-10 hidden lg:block"></div>
|
||||||
|
<div className="absolute inset-0 bg-[#FDFBF7]/40 z-10"></div>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-t from-[#FDFBF7] from-20% via-[#FDFBF7]/90 via-60% to-transparent z-10 lg:hidden"></div>
|
||||||
|
<img
|
||||||
|
src="https://images.unsplash.com/photo-1518611012118-696072aa579a?q=80&w=2940&auto=format&fit=crop"
|
||||||
|
alt="Elegância e Bem-estar"
|
||||||
|
className="w-full h-full object-cover object-[70%_top] opacity-70"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className="container mx-auto px-6 lg:px-12 flex-1 flex flex-col justify-center relative z-20 mt-12"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
variants={STAGGER}
|
||||||
|
>
|
||||||
|
<motion.div variants={FADE_UP} className="max-w-2xl relative">
|
||||||
|
<span className="text-[#D4BAB6] font-medium tracking-[0.2em] text-xs uppercase block mb-6 border-l pl-4 border-[#D4BAB6]">The Aurora Protocol</span>
|
||||||
|
<h1 className="text-5xl sm:text-6xl md:text-[90px] lg:text-[110px] leading-[0.9] font-serif tracking-normal text-[#333333] drop-shadow-sm">
|
||||||
|
Reencontre<br/><span className="text-[#A3918D] italic">Sua Essência.</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="max-w-md text-lg text-[#666666] font-light mt-8 leading-relaxed">
|
||||||
|
Transformação profunda e leveza para mulheres que desejam saúde, estética e performance, sem perder a elegância da vida.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="flex flex-col sm:flex-row items-start sm:items-center space-y-6 sm:space-y-0 sm:space-x-8 mt-12">
|
||||||
|
<Link
|
||||||
|
to="/contato"
|
||||||
|
className="w-full sm:w-auto bg-[#D4BAB6] text-white px-8 sm:px-10 py-4 text-[11px] font-medium uppercase tracking-[0.15em] hover:bg-[#C2A19D] transition-all transform hover:scale-[1.02] shadow-[0_10px_30px_rgba(212,186,182,0.3)] rounded-full text-center"
|
||||||
|
>
|
||||||
|
Inicie Sua Jornada
|
||||||
|
</Link>
|
||||||
|
<div className="flex items-center space-x-6">
|
||||||
|
<div className="flex items-center -space-x-3">
|
||||||
|
<img src="https://images.unsplash.com/photo-1524504388940-b1c1722653e1?w=100&h=100&fit=crop" alt="Client" className="w-10 h-10 rounded-full border-2 border-[#FDFBF7] z-30" />
|
||||||
|
<img src="https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=100&h=100&fit=crop" alt="Client" className="w-10 h-10 rounded-full border-2 border-[#FDFBF7] z-20" />
|
||||||
|
<img src="https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=100&h=100&fit=crop" alt="Client" className="w-10 h-10 rounded-full border-2 border-[#FDFBF7] z-10" />
|
||||||
|
</div>
|
||||||
|
<div className="text-[10px] font-medium uppercase tracking-widest text-[#888888] leading-tight">
|
||||||
|
<span className="text-[#333333] text-base font-serif italic block">+200</span>
|
||||||
|
Mulheres Inspiradas
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. SERVICES SECTION */}
|
||||||
|
<section className="py-32 bg-[#FAF5F0] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
<motion.div
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={{ once: true, margin: "-100px" }}
|
||||||
|
variants={STAGGER}
|
||||||
|
className="mb-20 text-center max-w-3xl mx-auto"
|
||||||
|
>
|
||||||
|
<h2 className="text-4xl sm:text-5xl md:text-[70px] leading-[1] font-serif tracking-normal text-[#333333] mb-6">
|
||||||
|
Método <span className="text-[#D4BAB6] italic">Aurora</span>
|
||||||
|
</h2>
|
||||||
|
<p className="text-[#666666] text-lg font-light leading-relaxed">
|
||||||
|
Um ecossistema criado para o bem-estar feminino. Cuidamos do seu corpo com a delicadeza e a precisão que ele merece.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||||
|
{/* Card 1 */}
|
||||||
|
<motion.div variants={FADE_UP} className="bg-white rounded-2xl p-10 flex flex-col items-center text-center shadow-sm border border-[#E8DCC4]/40 hover:shadow-xl transition-all duration-500 group">
|
||||||
|
<div className="w-16 h-16 bg-[#FDFBF7] rounded-full flex items-center justify-center mb-8 group-hover:scale-110 transition-transform duration-500">
|
||||||
|
<Sparkles className="w-6 h-6 text-[#D4BAB6]" strokeWidth={1.5} />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-2xl font-serif text-[#333333] mb-4">Estética Suave</h3>
|
||||||
|
<p className="text-[#666666] font-light text-sm leading-relaxed mb-8 flex-grow">
|
||||||
|
Programas de treino voltados para tonificação, saúde pélvica e fluidez de movimento.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Card 2 */}
|
||||||
|
<motion.div variants={FADE_UP} className="bg-white rounded-2xl p-10 flex flex-col items-center text-center shadow-sm border border-[#E8DCC4]/40 hover:shadow-xl transition-all duration-500 group">
|
||||||
|
<div className="w-16 h-16 bg-[#FDFBF7] rounded-full flex items-center justify-center mb-8 group-hover:scale-110 transition-transform duration-500">
|
||||||
|
<Feather className="w-6 h-6 text-[#D4BAB6]" strokeWidth={1.5} />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-2xl font-serif text-[#333333] mb-4">Nutrição Leve</h3>
|
||||||
|
<p className="text-[#666666] font-light text-sm leading-relaxed mb-8 flex-grow">
|
||||||
|
Sem restrições extremas. Alimentação baseada em intuição, nutrientes e prazer diário.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Card 3 */}
|
||||||
|
<motion.div variants={FADE_UP} className="bg-[#D4BAB6] rounded-2xl p-10 flex flex-col items-center text-center shadow-md transform md:-translate-y-4 hover:shadow-xl transition-all duration-500">
|
||||||
|
<div className="w-16 h-16 bg-white/20 rounded-full flex items-center justify-center mb-8">
|
||||||
|
<Target className="w-6 h-6 text-white" strokeWidth={1.5} />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-2xl font-serif text-white mb-4">Mentoria Premium</h3>
|
||||||
|
<p className="text-white/90 font-light text-sm leading-relaxed mb-8 flex-grow">
|
||||||
|
Acompanhamento diário (1:1) com nossa equipe para garantir que sua jornada seja perfeita.
|
||||||
|
</p>
|
||||||
|
<Link to="/contato" className="bg-white text-[#D4BAB6] rounded-full px-8 py-3 text-[10px] font-medium uppercase tracking-widest hover:bg-[#FDFBF7] transition-colors w-full">
|
||||||
|
Saber Mais
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. TRANSFORMATIONS SECTION */}
|
||||||
|
<section id="historias-reais" className="py-32 bg-[#FDFBF7] relative z-10">
|
||||||
|
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
<motion.div
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={{ once: true, margin: "-100px" }}
|
||||||
|
variants={STAGGER}
|
||||||
|
className="text-center mb-24 max-w-3xl mx-auto"
|
||||||
|
>
|
||||||
|
<span className="text-[#D4BAB6] font-medium tracking-[0.2em] text-xs uppercase block mb-4">Histórias Reais</span>
|
||||||
|
<h2 className="text-4xl sm:text-5xl md:text-[70px] leading-[1] font-serif tracking-normal text-[#333333] mb-6">
|
||||||
|
Elegância é se sentir<br/><span className="text-[#A3918D] italic">bem na própria pele.</span>
|
||||||
|
</h2>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 lg:gap-16">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
name: "Carolina Soares",
|
||||||
|
stats: "Descobrindo a confiança após a maternidade.",
|
||||||
|
before: "https://images.unsplash.com/photo-1571019614242-c5c5dee9f50b?q=80&w=800&auto=format&fit=crop",
|
||||||
|
after: "https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=800&auto=format&fit=crop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Mariana Lemos",
|
||||||
|
stats: "Bem-estar, leveza e mais energia para o dia a dia.",
|
||||||
|
before: "https://images.unsplash.com/photo-1542596594-649edbc13630?q=80&w=800&auto=format&fit=crop",
|
||||||
|
after: "https://images.unsplash.com/photo-1534528741775-53994a69daeb?q=80&w=800&auto=format&fit=crop"
|
||||||
|
}
|
||||||
|
].map((item, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={index}
|
||||||
|
variants={FADE_UP}
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={{ once: true }}
|
||||||
|
className="group flex flex-col"
|
||||||
|
>
|
||||||
|
<div className="relative aspect-[3/4] sm:aspect-square bg-[#FAF5F0] overflow-hidden rounded-2xl mb-8 flex group-hover:shadow-2xl transition-all duration-700">
|
||||||
|
<div className="w-1/2 h-full relative border-r border-white/50 opacity-90 transition-all duration-700">
|
||||||
|
<span className="absolute top-4 left-4 text-[9px] uppercase font-medium tracking-widest text-[#666666] bg-white/80 backdrop-blur-sm rounded-full px-3 py-1 shadow-sm">Antes</span>
|
||||||
|
<img src={item.before} className="w-full h-full object-cover" alt="Antes" />
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2 h-full relative transition-all duration-700">
|
||||||
|
<span className="absolute top-4 right-4 text-[9px] uppercase font-medium tracking-widest text-white bg-[#D4BAB6]/90 backdrop-blur-sm rounded-full px-3 py-1 shadow-sm z-10">Depois</span>
|
||||||
|
<img src={item.after} className="w-full h-full object-cover" alt="Depois" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-center">
|
||||||
|
<h4 className="text-2xl font-serif text-[#333333] mb-2">{item.name}</h4>
|
||||||
|
<p className="text-[#888888] text-sm font-light italic">{item.stats}</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3.B TESTIMONIALS SECTION */}
|
||||||
|
<section className="py-24 bg-[#E8DCC4]/20 relative z-10 border-t border-[#E8DCC4]/30">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-5xl">
|
||||||
|
<motion.div
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={{ once: true, margin: "-100px" }}
|
||||||
|
variants={STAGGER}
|
||||||
|
className="grid grid-cols-1 md:grid-cols-2 gap-12"
|
||||||
|
>
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
quote: "O método não mudou apenas meu corpo, mas a forma como me vejo. Encontrei uma leveza que não sentia há anos.",
|
||||||
|
author: "Juliana T.",
|
||||||
|
role: "Aluna Mentoria Premium"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
quote: "Finalmente um acompanhamento que entende a rotina da mulher real. Resultados incríveis sem perder o prazer de viver.",
|
||||||
|
author: "Fernanda M.",
|
||||||
|
role: "Aluna Essência"
|
||||||
|
}
|
||||||
|
].map((testimonial, index) => (
|
||||||
|
<motion.div key={index} variants={FADE_UP} className="bg-white p-10 rounded-2xl shadow-sm border border-[#E8DCC4]/30 relative">
|
||||||
|
<div className="text-6xl text-[#D4BAB6]/30 absolute top-6 left-6 font-serif leading-none">"</div>
|
||||||
|
<p className="text-[#666666] font-light text-lg italic leading-relaxed relative z-10 pt-6 mb-8">
|
||||||
|
{testimonial.quote}
|
||||||
|
</p>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="w-10 h-10 rounded-full bg-[#FAF5F0] flex items-center justify-center text-[#D4BAB6] font-serif">
|
||||||
|
{testimonial.author.charAt(0)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h5 className="text-[#333333] font-medium text-sm">{testimonial.author}</h5>
|
||||||
|
<span className="text-[#888888] text-[10px] uppercase tracking-wider">{testimonial.role}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 4. PLANS SECTION */}
|
||||||
|
<section className="py-32 bg-white relative z-10 border-y border-[#E8DCC4]/30">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-6xl relative z-10">
|
||||||
|
<div className="text-center mb-20">
|
||||||
|
<h2 className="text-4xl sm:text-5xl md:text-[70px] leading-[1] font-serif tracking-normal text-[#333333] mb-4">
|
||||||
|
Jornadas <span className="text-[#D4BAB6] italic">Exclusivas</span>
|
||||||
|
</h2>
|
||||||
|
<p className="text-[#666666] max-w-xl mx-auto font-light">Selecione o plano ideal para a sua transformação.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-4xl mx-auto">
|
||||||
|
{/* Mensal Card */}
|
||||||
|
<motion.div variants={FADE_UP} initial="hidden" whileInView="visible" viewport={{ once: true }} className="bg-[#FDFBF7] border border-[#E8DCC4] rounded-2xl p-10 flex flex-col hover:shadow-xl transition-all duration-500">
|
||||||
|
<span className="text-[#D4BAB6] text-[10px] font-medium uppercase tracking-widest mb-4 block">Essência</span>
|
||||||
|
<h3 className="text-3xl font-serif text-[#333333] mb-4">Acompanhamento</h3>
|
||||||
|
<p className="text-[#666666] text-sm mb-10 font-light leading-relaxed">O início perfeito para construir hábitos contínuos de forma suave.</p>
|
||||||
|
|
||||||
|
<div className="mb-10 pb-8 border-b border-[#E8DCC4]/50">
|
||||||
|
<span className="text-5xl font-serif text-[#333333]">R$ 497</span>
|
||||||
|
<span className="text-[#888888] text-[10px] uppercase font-medium tracking-widest ml-2">/mês</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul className="flex flex-col gap-5 mb-12 flex-grow">
|
||||||
|
{[
|
||||||
|
"Treino focado em estética feminina",
|
||||||
|
"Guia nutricional flexível",
|
||||||
|
"Alinhamento mental",
|
||||||
|
"Suporte semanal",
|
||||||
|
].map((feature, i) => (
|
||||||
|
<li key={i} className="flex items-center gap-4 text-[#666666]">
|
||||||
|
<CheckCircle2 className="w-4 h-4 text-[#D4BAB6]" strokeWidth={2} />
|
||||||
|
<span className="text-sm font-light">{feature}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Link to="/contato" className="w-full text-center px-8 py-4 border border-[#D4BAB6] text-[#D4BAB6] rounded-full text-[11px] font-medium uppercase tracking-widest hover:bg-[#D4BAB6] hover:text-white transition-colors">
|
||||||
|
Escolher Essência
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Premium Card */}
|
||||||
|
<motion.div variants={FADE_UP} initial="hidden" whileInView="visible" viewport={{ once: true }} className="bg-[#D4BAB6] rounded-2xl p-10 flex flex-col relative transform md:-translate-y-4 shadow-2xl z-20">
|
||||||
|
<div className="absolute top-0 right-10 bg-white text-[#D4BAB6] text-[9px] font-medium uppercase tracking-widest px-4 py-1.5 rounded-b-lg shadow-sm">
|
||||||
|
Mais Desejado
|
||||||
|
</div>
|
||||||
|
<span className="text-white/80 text-[10px] font-medium uppercase tracking-widest mb-4 block">Plenitude</span>
|
||||||
|
<h3 className="text-3xl font-serif text-white mb-4">Mentoria Premium</h3>
|
||||||
|
<p className="text-white/90 text-sm mb-10 font-light leading-relaxed">Transformação completa de 3 meses, unindo corpo, mente e rotina.</p>
|
||||||
|
|
||||||
|
<div className="mb-10 pb-8 border-b border-white/20">
|
||||||
|
<span className="text-5xl font-serif text-white">R$ 1.297</span>
|
||||||
|
<span className="text-white/80 text-[10px] uppercase font-medium tracking-widest ml-2">/ciclo</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul className="flex flex-col gap-5 mb-12 flex-grow">
|
||||||
|
{[
|
||||||
|
"Tudo do plano Essência",
|
||||||
|
"Dieta personalizada (Nutricionista)",
|
||||||
|
"Acompanhamento diário VIP",
|
||||||
|
"Encontros de mentoria ao vivo",
|
||||||
|
"Material exclusivo mensal",
|
||||||
|
].map((feature, i) => (
|
||||||
|
<li key={i} className="flex items-center gap-4 text-white">
|
||||||
|
<CheckCircle2 className="w-4 h-4 text-white" strokeWidth={2} />
|
||||||
|
<span className="text-sm font-light">{feature}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Link to="/contato" className="w-full text-center px-8 py-4 bg-white text-[#D4BAB6] rounded-full text-[11px] font-medium uppercase tracking-widest hover:bg-[#FDFBF7] transition-colors shadow-sm">
|
||||||
|
Aplicar para Mentoria
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 5. FINAL CTA SECTION */}
|
||||||
|
<section className="py-32 relative overflow-hidden bg-[#FAF5F0] z-10 text-center">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-4xl relative z-10 flex flex-col items-center">
|
||||||
|
<h2 className="text-4xl sm:text-5xl md:text-[80px] font-serif tracking-normal text-[#333333] leading-[1] mb-8">
|
||||||
|
Pronta para florescer <br/>
|
||||||
|
<span className="text-[#A3918D] italic">sua melhor versão?</span>
|
||||||
|
</h2>
|
||||||
|
<p className="text-[#666666] font-light text-lg mb-12 max-w-xl">
|
||||||
|
Não espere o momento perfeito. Comece hoje a jornada de autocuidado e sofisticação que você merece.
|
||||||
|
</p>
|
||||||
|
<Link to="/contato" className="bg-[#D4BAB6] text-white px-10 py-5 rounded-full text-[11px] font-medium uppercase tracking-[0.15em] hover:bg-[#C2A19D] transition-transform transform hover:-translate-y-1 shadow-[0_10px_30px_rgba(212,186,182,0.3)] inline-block">
|
||||||
|
Agendar Reunião Estratégica
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
24
Template-02/src/pages/NotFound.tsx
Normal file
24
Template-02/src/pages/NotFound.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { ArrowLeft } from "lucide-react";
|
||||||
|
|
||||||
|
export default function NotFound() {
|
||||||
|
return (
|
||||||
|
<div className="w-full min-h-[70vh] flex flex-col items-center justify-center bg-[#050505] text-center px-6">
|
||||||
|
<h1 className="text-[120px] md:text-[200px] font-black italic tracking-tighter text-[#FF3E00] leading-none drop-shadow-[0_0_20px_rgba(255,62,0,0.4)]">
|
||||||
|
404
|
||||||
|
</h1>
|
||||||
|
<h2 className="text-3xl md:text-5xl font-black italic uppercase tracking-tighter text-white mb-6">
|
||||||
|
Território Desconhecido
|
||||||
|
</h2>
|
||||||
|
<p className="text-white/60 font-light mb-10 max-w-md">
|
||||||
|
A página que você está procurando não existe ou foi removida. O foco inabalável não permite distrações, volte para o caminho certo.
|
||||||
|
</p>
|
||||||
|
<Link
|
||||||
|
to="/"
|
||||||
|
className="flex items-center gap-2 border border-white/20 px-8 py-4 text-white uppercase text-[11px] tracking-widest font-bold hover:bg-[#FF3E00] hover:border-[#FF3E00] transition-colors"
|
||||||
|
>
|
||||||
|
<ArrowLeft className="w-4 h-4" /> Voltar ao Início
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
162
Template-02/src/pages/Sobre.tsx
Normal file
162
Template-02/src/pages/Sobre.tsx
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import SEO from "../components/SEO";
|
||||||
|
|
||||||
|
const FADE_UP = {
|
||||||
|
hidden: { opacity: 0, y: 40 },
|
||||||
|
visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAGGER = {
|
||||||
|
visible: { transition: { staggerChildren: 0.2 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Sobre() {
|
||||||
|
const schema = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "Person",
|
||||||
|
"name": "Aurora Elena",
|
||||||
|
"jobTitle": "Mentora de Bem-Estar e Especialista em Performance Feminina",
|
||||||
|
"url": "https://aurorawellness.com/sobre",
|
||||||
|
"image": "https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=2940&auto=format&fit=crop"
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full flex flex-col bg-[#FDFBF7]">
|
||||||
|
<SEO
|
||||||
|
title="Sobre a Mentora | Aurora Wellness"
|
||||||
|
description="A jornada de Aurora Elena na construção de um método único focado no bem-estar e na performance feminina."
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Hero Section */}
|
||||||
|
<section className="relative py-32 lg:py-48 overflow-hidden bg-[#FAF5F0]">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl relative z-10">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center">
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
variants={STAGGER}
|
||||||
|
className="order-2 lg:order-1"
|
||||||
|
>
|
||||||
|
<motion.div variants={FADE_UP}>
|
||||||
|
<span className="text-[#D4BAB6] font-medium tracking-[0.2em] text-xs uppercase block mb-6 border-l pl-4 border-[#D4BAB6]">A Mentora</span>
|
||||||
|
<h1 className="text-5xl sm:text-6xl md:text-[90px] leading-[0.9] font-serif tracking-normal text-[#333333] mb-8">
|
||||||
|
A Arte de<br/>
|
||||||
|
<span className="text-[#A3918D] italic">Transformar.</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="text-lg text-[#666666] mb-10 font-light leading-relaxed max-w-lg border-l-2 border-[#D4BAB6] pl-6 italic">
|
||||||
|
"Eu não acredito em força sem leveza. O verdadeiro empoderamento vem quando aprendemos a cuidar do nosso corpo com amor e disciplina."
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="flex flex-col sm:flex-row gap-6 items-start sm:items-center">
|
||||||
|
<div className="flex items-center gap-3 text-[10px] font-medium uppercase tracking-widest text-[#D4BAB6] border border-[#E8DCC4] rounded-full px-6 py-3 bg-white/50">
|
||||||
|
<span className="w-2 h-2 rounded-full bg-[#D4BAB6]"></span>
|
||||||
|
Especialista em Saúde Feminina
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
transition={{ duration: 1, ease: "easeOut" }}
|
||||||
|
className="order-1 lg:order-2 w-full aspect-[3/4] relative rounded-2xl overflow-hidden shadow-lg"
|
||||||
|
>
|
||||||
|
<div className="absolute inset-0 bg-[#D4BAB6]/10 mix-blend-multiply z-10 pointer-events-none"></div>
|
||||||
|
<img
|
||||||
|
src="https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=1200&auto=format&fit=crop"
|
||||||
|
alt="Aurora Elena - Mentora"
|
||||||
|
className="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Content Section */}
|
||||||
|
<section className="py-32 bg-[#FDFBF7] relative z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-7xl">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-20">
|
||||||
|
{/* Timeline */}
|
||||||
|
<div>
|
||||||
|
<h2 className="text-4xl md:text-[50px] font-serif tracking-normal text-[#333333] mb-12">O Desabrochar da <span className="text-[#D4BAB6] italic">Jornada</span></h2>
|
||||||
|
<div className="space-y-12 relative before:absolute before:inset-0 before:ml-5 before:-translate-x-px md:before:ml-[23px] before:md:-translate-x-px before:h-full before:w-[1px] before:bg-[#E8DCC4]">
|
||||||
|
{[
|
||||||
|
{ year: "2015", title: "O Despertar", desc: "Graduação em Nutrição e primeiras descobertas sobre a relação íntima entre saúde mental e forma física feminina." },
|
||||||
|
{ year: "2018", title: "Especialização Internacional", desc: "Estudos em Nova York focados em saúde pélvica, biomecânica e abordagens gentis de condicionamento." },
|
||||||
|
{ year: "2021", title: "A Criação do Método", desc: "Lançamento oficial do método Aurora, após anos testando e refinando práticas com mais de 100 mulheres." },
|
||||||
|
{ year: "Hoje", title: "Expansão e Impacto", desc: "Comunidade com milhares de alunas, transformando o conceito de fitness feminino no país." }
|
||||||
|
].map((item, index) => (
|
||||||
|
<div key={index} className="relative flex items-start gap-8 md:gap-12">
|
||||||
|
<div className="relative z-10 w-10 h-10 md:w-12 md:h-12 rounded-full bg-white border border-[#E8DCC4] flex items-center justify-center shrink-0 mt-1 shadow-sm">
|
||||||
|
<div className="w-3 h-3 md:w-4 md:h-4 bg-[#D4BAB6] rounded-full"></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="text-[#D4BAB6] font-medium tracking-[0.2em] text-xs uppercase mb-2 block">{item.year}</span>
|
||||||
|
<h3 className="text-2xl font-serif text-[#333333] mb-3">{item.title}</h3>
|
||||||
|
<p className="text-[#666666] font-light leading-relaxed text-sm md:text-base max-w-md">{item.desc}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Certificações & Rotina */}
|
||||||
|
<div>
|
||||||
|
<div className="mb-16">
|
||||||
|
<h2 className="text-4xl md:text-[50px] font-serif tracking-normal text-[#333333] mb-8">Base <span className="text-[#D4BAB6] italic">Teórica</span></h2>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
|
{[
|
||||||
|
"Especialista em Nutrição Feminina",
|
||||||
|
"Certificação em Pilates",
|
||||||
|
"Especialização em Biomecânica",
|
||||||
|
"Saúde Pélvica Avançada"
|
||||||
|
].map((cert, index) => (
|
||||||
|
<div key={index} className="bg-white border border-[#E8DCC4] p-5 rounded-lg flex items-center gap-3">
|
||||||
|
<div className="w-1.5 h-1.5 bg-[#D4BAB6] rounded-full"></div>
|
||||||
|
<span className="text-[#666666] font-light text-sm uppercase tracking-wider">{cert}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2 className="text-4xl md:text-[50px] font-serif tracking-normal text-[#333333] mb-8 border-t border-[#E8DCC4]/50 pt-16">O Estilo de <span className="text-[#D4BAB6] italic">Vida</span></h2>
|
||||||
|
<p className="text-[#666666] mb-8 font-light max-w-md italic">“Eu prego o equilíbrio porque é assim que eu vivo. Minha rotina é minha maior vitrine.”</p>
|
||||||
|
<div className="space-y-4">
|
||||||
|
{[
|
||||||
|
{ time: "06:00", act: "Meditação e Movimento Suave" },
|
||||||
|
{ time: "08:00", act: "Acompanhamento das Alunas" },
|
||||||
|
{ time: "14:00", act: "Estudos e Pesquisa" },
|
||||||
|
{ time: "19:00", act: "Desconexão e Autocuidado" }
|
||||||
|
].map((item, index) => (
|
||||||
|
<div key={index} className="flex flex-col sm:flex-row sm:items-center justify-between border-b border-[#E8DCC4]/50 pb-4">
|
||||||
|
<span className="text-[#D4BAB6] font-medium tracking-widest text-xs uppercase mb-1 sm:mb-0">{item.time}</span>
|
||||||
|
<span className="text-[#333333] font-serif text-lg">{item.act}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* CTA Final */}
|
||||||
|
<section className="py-32 relative overflow-hidden bg-[#FAF5F0] z-10">
|
||||||
|
<div className="container mx-auto px-6 lg:px-12 max-w-4xl flex flex-col items-center justify-center text-center relative z-10">
|
||||||
|
<h2 className="text-4xl md:text-[60px] font-serif tracking-normal text-[#333333] leading-[1.1] mb-8">
|
||||||
|
Pronta para trilhar o<br/><span className="text-[#D4BAB6] italic">seu próprio caminho?</span>
|
||||||
|
</h2>
|
||||||
|
<Link to="/contato" className="bg-[#D4BAB6] text-white px-10 py-5 rounded-full text-[11px] font-medium uppercase tracking-[0.15em] hover:bg-[#C2A19D] transition-transform transform hover:-translate-y-1 shadow-[0_10px_30px_rgba(212,186,182,0.3)] mt-8 inline-block">
|
||||||
|
Iniciar Mentoria
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
26
Template-02/tsconfig.json
Normal file
26
Template-02/tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": [
|
||||||
|
"ES2022",
|
||||||
|
"DOM",
|
||||||
|
"DOM.Iterable"
|
||||||
|
],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"allowJs": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"noEmit": true
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Template-02/vite.config.ts
Normal file
24
Template-02/vite.config.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import path from 'path';
|
||||||
|
import {defineConfig, loadEnv} from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig(({mode}) => {
|
||||||
|
const env = loadEnv(mode, '.', '');
|
||||||
|
return {
|
||||||
|
plugins: [react(), tailwindcss()],
|
||||||
|
define: {
|
||||||
|
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(__dirname, '.'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
||||||
|
// Do not modifyâfile watching is disabled to prevent flickering during agent edits.
|
||||||
|
hmr: process.env.DISABLE_HMR !== 'true',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue