Primeira versão templates personal trainer

This commit is contained in:
Marcio Bevervanso 2026-05-13 19:21:04 -03:00
commit 803f5b8a0b
47 changed files with 12708 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

20
Template-01/README.md Normal file
View 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
View 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>

View 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

File diff suppressed because it is too large Load diff

38
Template-01/package.json Normal file
View 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"
}
}

View file

@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://alexandrevaz.com/sitemap.xml

View 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
View 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>
);
}

View 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>
);
}

View 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>
);
}

View 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>
</>
);
}

View 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
View 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;
}

View 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
View 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>,
);

View 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>
);
}

View 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 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 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>
);
}

View 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>
);
}

View 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>
);
}

View 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>
);
}

View 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. 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
View 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
}
}

View 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
View 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
View 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>

View 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

File diff suppressed because it is too large Load diff

38
Template-02/package.json Normal file
View 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"
}
}

View file

@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://alexandrevaz.com/sitemap.xml

View 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
View 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>
);
}

View 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>
);
}

View 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>
);
}

View 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>
</>
);
}

View 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
View 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;
}

View 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
View 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>,
);

View 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>
);
}

View 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 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>
);
}

View 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">
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>
);
}

View 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>
);
}

View 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>
);
}

View 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
View 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
}
}

View 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',
},
};
});