Primeira versão templates corretor de imoveis
This commit is contained in:
commit
b9ff7f165c
44 changed files with 13445 additions and 0 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
20
Template-01/README.md
Normal file
20
Template-01/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<div align="center">
|
||||
<img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
|
||||
</div>
|
||||
|
||||
# Run and deploy your AI Studio app
|
||||
|
||||
This contains everything you need to run your app locally.
|
||||
|
||||
View your app in AI Studio: https://ai.studio/apps/3834725f-5856-4096-8bdd-9346114a9c47
|
||||
|
||||
## 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`
|
||||
22
Template-01/fix_links.js
Normal file
22
Template-01/fix_links.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
const fs = require('fs');
|
||||
const file = 'src/data/articles.tsx';
|
||||
let content = fs.readFileSync(file, 'utf8');
|
||||
|
||||
const replacements = [
|
||||
['<Link to="/">\n análise de valorização do Jardim Europa', '<Link to="/artigo/valorizacao-jardim-europa">\n análise de valorização do Jardim Europa'],
|
||||
['<Link to="/">novo conceito de luxo vertical', '<Link to="/artigo/novo-luxo-sp">novo conceito de luxo vertical'],
|
||||
['<Link to="/">\n residência no Jardim Europa', '<Link to="/artigo/residencial-jardim-europa-01">\n residência no Jardim Europa'],
|
||||
['<Link to="/">leia o guia de aquisição', '<Link to="/artigo/guia-aquisicao-jardim-europa">leia o guia de aquisição'],
|
||||
['<Link to="/">\n como o retrofit pode impactar esse risco legal', '<Link to="/artigo/importancia-retrofit">\n como o retrofit pode impactar esse risco legal'],
|
||||
['<Link to="/">casa na Fazenda Boa Vista', '<Link to="/artigo/fazenda-boa-vista">casa na Fazenda Boa Vista'],
|
||||
['<Link to="/">arquitetura', '<Link to="/artigo/tendencias-arquitetura-2026">arquitetura'],
|
||||
['<Link to="/">off-market insights', '<Link to="/artigo/mercado-off-market">off-market insights'],
|
||||
['<Link to="/">importância do retrofit', '<Link to="/artigo/importancia-retrofit">importância do retrofit']
|
||||
];
|
||||
|
||||
for (const [search, replace] of replacements) {
|
||||
content = content.replace(search, replace);
|
||||
}
|
||||
|
||||
fs.writeFileSync(file, content);
|
||||
console.log("Done");
|
||||
13
Template-01/index.html
Normal file
13
Template-01/index.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>My Google AI Studio App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
6
Template-01/metadata.json
Normal file
6
Template-01/metadata.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "Rafael Fontes - Corretor de Imobiliária Premium",
|
||||
"description": "Website premium para corretor de imóveis focado em propriedades de alto padrão e luxo.",
|
||||
"requestFramePermissions": [],
|
||||
"majorCapabilities": []
|
||||
}
|
||||
4480
Template-01/package-lock.json
generated
Normal file
4480
Template-01/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
38
Template-01/package.json
Normal file
38
Template-01/package.json
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "react-example",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --port=3000 --host=0.0.0.0",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.29.0",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"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-icons": "^5.6.0",
|
||||
"react-router-dom": "^7.15.0",
|
||||
"vite": "^6.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^22.14.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "~5.8.2",
|
||||
"vite": "^6.2.3"
|
||||
}
|
||||
}
|
||||
4
Template-01/public/robots.txt
Normal file
4
Template-01/public/robots.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://rafaelfontes.com.br/sitemap.xml
|
||||
28
Template-01/public/sitemap.xml
Normal file
28
Template-01/public/sitemap.xml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://rafaelfontes.com.br/</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://rafaelfontes.com.br/portfolio</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://rafaelfontes.com.br/assessoria</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://rafaelfontes.com.br/insights</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://rafaelfontes.com.br/contato</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
768
Template-01/src/App.tsx
Normal file
768
Template-01/src/App.tsx
Normal file
|
|
@ -0,0 +1,768 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "motion/react";
|
||||
import {
|
||||
Menu,
|
||||
X,
|
||||
ArrowRight,
|
||||
Instagram,
|
||||
Linkedin,
|
||||
MapPin,
|
||||
ArrowLeft,
|
||||
MessageCircle,
|
||||
UserCheck,
|
||||
Briefcase,
|
||||
ShieldCheck,
|
||||
Search,
|
||||
} from "lucide-react";
|
||||
import { Routes, Route, Link, useParams, useLocation } from "react-router-dom";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { articles, ArticleType, Article } from "./data/articles";
|
||||
import { PortfolioPage } from "./pages/PortfolioPage";
|
||||
import { AssessoriaPage } from "./pages/AssessoriaPage";
|
||||
import { InsightsPage } from "./pages/InsightsPage";
|
||||
import { ContatoPage } from "./pages/ContatoPage";
|
||||
import { Analytics } from "./components/Analytics";
|
||||
|
||||
export default function App() {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 50);
|
||||
};
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
setIsMobileMenuOpen(false);
|
||||
setIsSearchOpen(false);
|
||||
setSearchQuery("");
|
||||
}, [location.pathname]);
|
||||
|
||||
// Filter articles for the homepage feeds
|
||||
const propertiesAsArticles = articles.filter((a) => a.type === "property");
|
||||
const marketInsights = articles.filter((a) => a.type === "insight");
|
||||
|
||||
const searchResults = articles.filter(a =>
|
||||
a.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
a.excerpt.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
(a.details?.location && a.details.location.toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
);
|
||||
|
||||
const isArticleRoute = location.pathname.startsWith('/artigo/');
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-zinc-50 text-zinc-900 selection:bg-brand-gold selection:text-white font-sans overflow-x-hidden">
|
||||
<Analytics />
|
||||
<Helmet>
|
||||
<title>Rafael Fontes | Corretor de Imóveis Premium</title>
|
||||
<meta name="description" content="Rafael Fontes é um corretor de imóveis especializado no mercado premium e de luxo. Acesso exclusivo a propriedades off-market em São Paulo." />
|
||||
<meta name="keywords" content="corretor de luxo, imóveis premium, são paulo, off-market, mansões, apartamentos alto padrão" />
|
||||
<meta property="og:title" content="Rafael Fontes | Corretor de Imóveis Premium" />
|
||||
<meta property="og:description" content="Rafael Fontes é um corretor de imóveis especializado no mercado premium e de luxo. Acesso exclusivo a propriedades off-market em São Paulo." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="Rafael Fontes | Corretor de Imóveis Premium" />
|
||||
<meta name="twitter:description" content="Rafael Fontes é um corretor de imóveis especializado no mercado premium e de luxo em São Paulo." />
|
||||
<link rel="canonical" href="https://rafaelfontes.com.br" />
|
||||
</Helmet>
|
||||
{/* HEADER */}
|
||||
<nav
|
||||
className={`fixed w-full z-50 transition-all duration-500 border-b ${
|
||||
isScrolled || isArticleRoute
|
||||
? "bg-zinc-50/95 backdrop-blur-md border-zinc-200 py-4"
|
||||
: "bg-transparent border-transparent py-8"
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 flex justify-between items-center">
|
||||
<div className="flex items-center gap-6">
|
||||
<Link to="/" className="flex flex-col">
|
||||
<span className="text-2xl font-serif font-bold tracking-tight text-zinc-900 leading-none">
|
||||
RAFAEL FONTES
|
||||
</span>
|
||||
<span className="text-[10px] uppercase tracking-[0.3em] text-brand-gold font-bold mt-1.5">
|
||||
Corretor de Imóveis Premium
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Desktop Nav */}
|
||||
<div className="hidden md:flex items-center gap-8 text-xs uppercase tracking-[0.15em] font-semibold text-zinc-600">
|
||||
<Link
|
||||
to="/portfolio"
|
||||
className="hover:text-brand-gold transition-colors"
|
||||
>
|
||||
Portfólio
|
||||
</Link>
|
||||
<Link
|
||||
to="/assessoria"
|
||||
className="hover:text-brand-gold transition-colors"
|
||||
>
|
||||
A Assessoria
|
||||
</Link>
|
||||
<Link
|
||||
to="/insights"
|
||||
className="hover:text-brand-gold transition-colors"
|
||||
>
|
||||
Insights
|
||||
</Link>
|
||||
<Link
|
||||
to="/contato"
|
||||
className="hover:text-brand-gold transition-colors"
|
||||
>
|
||||
Contato
|
||||
</Link>
|
||||
<button
|
||||
onClick={() => setIsSearchOpen(true)}
|
||||
className="hover:text-brand-gold transition-colors flex items-center justify-center p-2 -mr-2"
|
||||
aria-label="Buscar"
|
||||
>
|
||||
<Search size={18} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="md:hidden flex items-center gap-4">
|
||||
<button
|
||||
onClick={() => setIsSearchOpen(true)}
|
||||
className="text-zinc-900 flex items-center justify-center"
|
||||
aria-label="Buscar"
|
||||
>
|
||||
<Search size={22} />
|
||||
</button>
|
||||
<button
|
||||
className="text-zinc-900"
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
>
|
||||
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile Dropdown */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: "auto" }}
|
||||
exit={{ opacity: 0, height: 0 }}
|
||||
className="absolute top-full left-0 w-full bg-zinc-50 border-b border-zinc-200 overflow-hidden md:hidden shadow-xl shadow-black/5"
|
||||
>
|
||||
<div className="flex flex-col px-6 py-8 gap-6 text-sm uppercase tracking-widest font-semibold text-zinc-600">
|
||||
<Link
|
||||
to="/portfolio"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
Portfólio
|
||||
</Link>
|
||||
<Link
|
||||
to="/assessoria"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
>
|
||||
A Assessoria
|
||||
</Link>
|
||||
<Link to="/insights" onClick={() => setIsMobileMenuOpen(false)}>
|
||||
Insights
|
||||
</Link>
|
||||
<Link to="/contato" onClick={() => setIsMobileMenuOpen(false)}>
|
||||
Contato
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</nav>
|
||||
|
||||
{/* SEARCH MODAL */}
|
||||
<AnimatePresence>
|
||||
{isSearchOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-0 z-[100] bg-zinc-50/95 backdrop-blur-xl flex flex-col pt-32 px-6 lg:px-8"
|
||||
>
|
||||
<button
|
||||
onClick={() => setIsSearchOpen(false)}
|
||||
className="absolute top-8 right-6 lg:right-8 text-zinc-500 hover:text-zinc-900 transition-colors p-2"
|
||||
aria-label="Agendar"
|
||||
>
|
||||
<X size={32} strokeWidth={1} />
|
||||
</button>
|
||||
|
||||
<div className="max-w-4xl w-full mx-auto flex flex-col h-full">
|
||||
<div className="relative mb-12">
|
||||
<input
|
||||
autoFocus
|
||||
type="text"
|
||||
placeholder="Busque por bairro, exclusividade ou insights..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full bg-transparent border-b-2 border-zinc-300 text-3xl md:text-5xl font-serif text-zinc-900 pb-4 focus:outline-none focus:border-brand-gold transition-colors placeholder:text-zinc-300"
|
||||
/>
|
||||
<Search className="absolute right-0 bottom-6 text-zinc-300" size={32} />
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto pb-32">
|
||||
{searchQuery.length > 2 ? (
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-xs uppercase tracking-widest text-zinc-400 font-bold mb-8">Resultados ({searchResults.length})</h3>
|
||||
{searchResults.length > 0 ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{searchResults.map((result) => (
|
||||
<Link
|
||||
key={result.id}
|
||||
to={`/artigo/${result.id}`}
|
||||
onClick={() => setIsSearchOpen(false)}
|
||||
className="group block border border-zinc-200 bg-white p-6 hover:border-brand-gold transition-colors"
|
||||
>
|
||||
<div className="text-xs font-bold text-brand-gold uppercase tracking-widest mb-3">
|
||||
{result.type === 'property' ? 'Portfólio' : 'Insight'}
|
||||
</div>
|
||||
<h4 className="font-serif text-xl text-zinc-900 mb-2 group-hover:text-brand-gold transition-colors">{result.title}</h4>
|
||||
<p className="text-sm font-light text-zinc-600 line-clamp-2">{result.excerpt}</p>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-zinc-500 font-light text-lg">Nenhum resultado encontrado para "{searchQuery}". Tente outros termos.</p>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-zinc-400 font-light text-lg">
|
||||
Digite pelo menos 3 caracteres para iniciar a busca.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/portfolio" element={<PortfolioPage propertiesAsArticles={propertiesAsArticles} />} />
|
||||
<Route path="/assessoria" element={<AssessoriaPage />} />
|
||||
<Route path="/insights" element={<InsightsPage marketInsights={marketInsights} />} />
|
||||
<Route path="/contato" element={<ContatoPage />} />
|
||||
<Route path="/artigo/:id" element={<ArticleRoute />} />
|
||||
</Routes>
|
||||
|
||||
{/* FOOTER */}
|
||||
<footer className="bg-white py-8 text-zinc-900 border-t border-zinc-200 text-center text-xs uppercase tracking-widest text-zinc-500 font-bold">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 flex flex-col md:flex-row justify-between items-center gap-4">
|
||||
<p>© {new Date().getFullYear()} RAFAEL FONTES • CRECI 123456-F.</p>
|
||||
<div className="flex gap-8">
|
||||
<a href="#" className="hover:text-brand-gold transition-colors">
|
||||
Políticas de Privacidade
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
{/* Floating WhatsApp Button */}
|
||||
<AnimatePresence>
|
||||
{(isScrolled || isArticleRoute) && (
|
||||
<motion.a
|
||||
initial={{ opacity: 0, scale: 0.8, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.8, y: 20 }}
|
||||
href="https://wa.me/5511999999999"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="fixed bottom-6 right-6 z-50 bg-[#25D366] text-white p-4 rounded-full shadow-[0_4px_14px_rgba(37,211,102,0.4)] hover:bg-[#22bf5b] transition-colors hover:scale-110 active:scale-95 flex items-center justify-center"
|
||||
aria-label="Falar no WhatsApp"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
width="28"
|
||||
height="28"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a12.8 12.8 0 0 0-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413Z" />
|
||||
</svg>
|
||||
</motion.a>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function HomePage() {
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (location.hash) {
|
||||
const element = document.getElementById(location.hash.substring(1));
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Rafael Fontes | Início</title>
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "RealEstateAgent",
|
||||
"name": "Rafael Fontes",
|
||||
"image": "https://images.unsplash.com/photo-1560250097-0b93528c311a?q=80&w=1974&auto=format&fit=crop",
|
||||
"@id": "https://rafaelfontes.com.br",
|
||||
"url": "https://rafaelfontes.com.br",
|
||||
"telephone": "+5511999999999",
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"streetAddress": "Av. Brigadeiro Faria Lima, 3477",
|
||||
"addressLocality": "São Paulo",
|
||||
"addressRegion": "SP",
|
||||
"postalCode": "04538-133",
|
||||
"addressCountry": "BR"
|
||||
},
|
||||
"priceRange": "$$$$"
|
||||
})}
|
||||
</script>
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Como funciona a assessoria para compra de imóveis?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Busca ativa por todo o mercado. Filtro o ruído, faço as inspeções prévias e entrego relatórios analíticos antes da sua visita."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "O que são imóveis off-market?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "São propriedades exclusivas que não são anunciadas publicamente, oferecendo maior privacidade e oportunidades únicas para compradores qualificados."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Qual é a vantagem de contratar um corretor exclusivo para a venda do meu imóvel?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "A exclusividade garante um plano de marketing focado, filtro rigoroso de potenciais compradores e proteção contra a desvalorização do ativo por sobreposição de anúncios no mercado."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Você atua apenas na venda de imóveis prontos ou também em lançamentos?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Atuo em ambos. Para lançamentos, ofereço antecipação de informações e acesso privilegiado a unidades específicas antes da abertura para o mercado em geral."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Como é garantido o sigilo durante a negociação?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Trabalho com Acordos de Confidencialidade (NDA) quando necessário e filtro estritamente as informações compartilhadas, protegendo a identidade e o patrimônio de ambas as partes."
|
||||
}
|
||||
}
|
||||
]
|
||||
})}
|
||||
</script>
|
||||
</Helmet>
|
||||
<section className="pt-40 pb-20 md:pt-52 md:pb-32 px-6 min-h-[90vh] flex items-center">
|
||||
<div className="max-w-7xl mx-auto flex flex-col md:flex-row gap-12 items-center">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1, ease: "easeOut" }}
|
||||
className="w-full md:w-1/2 pr-0 md:pr-12"
|
||||
>
|
||||
<div className="flex items-center gap-4 mb-8">
|
||||
<div className="w-12 h-px bg-brand-gold"></div>
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-brand-gold font-bold">
|
||||
Apresentação Profissional
|
||||
</span>
|
||||
</div>
|
||||
<h1 className="text-5xl md:text-6xl lg:text-7xl font-serif text-zinc-900 leading-[1.1] mb-8">
|
||||
Conectando você aos endereços mais cobiçados.
|
||||
</h1>
|
||||
<p className="text-lg md:text-xl text-zinc-600 font-light mb-10 leading-relaxed border-l-2 border-zinc-200 pl-6">
|
||||
Como corretor especialista no segmento premium, faço mais do que
|
||||
listar imóveis. Eu documento, analiso e apresento as propriedades
|
||||
mais requintadas do mercado de forma aprofundada e sigilosa.
|
||||
</p>
|
||||
<div className="flex flex-wrap items-center gap-4">
|
||||
<Link
|
||||
to="/portfolio"
|
||||
className="bg-zinc-900 hover:bg-brand-gold text-white px-6 py-4 text-xs font-bold uppercase tracking-[0.1em] transition-colors inline-block text-center"
|
||||
>
|
||||
Portfólio
|
||||
</Link>
|
||||
<Link
|
||||
to="/assessoria"
|
||||
className="border border-zinc-300 text-zinc-900 hover:border-zinc-900 hover:bg-zinc-900 hover:text-white px-6 py-4 text-xs font-bold uppercase tracking-[0.1em] transition-colors inline-block text-center"
|
||||
>
|
||||
A Assessoria
|
||||
</Link>
|
||||
<Link
|
||||
to="/insights"
|
||||
className="border border-zinc-300 text-zinc-900 hover:border-zinc-900 hover:bg-zinc-900 hover:text-white px-6 py-4 text-xs font-bold uppercase tracking-[0.1em] transition-colors inline-block text-center"
|
||||
>
|
||||
Insights
|
||||
</Link>
|
||||
<Link
|
||||
to="/contato"
|
||||
className="border border-zinc-300 text-zinc-900 hover:border-zinc-900 hover:bg-zinc-900 hover:text-white px-6 py-4 text-xs font-bold uppercase tracking-[0.1em] transition-colors inline-block text-center"
|
||||
>
|
||||
Contato
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 1, delay: 0.2, ease: "easeOut" }}
|
||||
className="w-full md:w-1/2 relative"
|
||||
>
|
||||
<div className="aspect-[4/5] md:aspect-square overflow-hidden bg-zinc-200 relative">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1560250097-0b93528c311a?q=80&w=1974&auto=format&fit=crop"
|
||||
alt="Rafael Fontes - Retrato"
|
||||
className="w-full h-full object-cover grayscale origin-top"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-zinc-900/60 to-transparent flex items-end p-8">
|
||||
<div>
|
||||
<p className="text-white font-serif text-2xl">
|
||||
Rafael Fontes
|
||||
</p>
|
||||
<p className="text-zinc-300 text-sm tracking-widest font-light uppercase mt-1">
|
||||
CRECI 123456-F
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Stamp / Detail */}
|
||||
<div className="absolute -bottom-6 -left-6 bg-brand-gold text-white p-6 shadow-xl hidden md:block">
|
||||
<p className="font-serif text-4xl mb-1">15+</p>
|
||||
<p className="text-xs uppercase tracking-widest font-bold">
|
||||
Anos de Mercado
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* DIFERENCIAIS SECTION */}
|
||||
<section className="py-24 bg-zinc-50 border-t border-zinc-200">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="text-center mb-16">
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-zinc-400 font-bold block mb-4">
|
||||
Nossos Pilares
|
||||
</span>
|
||||
<h2 className="text-4xl md:text-5xl font-serif text-zinc-900 leading-tight">
|
||||
Diferenciais
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="bg-white p-10 border border-zinc-200 hover:border-brand-gold transition-colors duration-300"
|
||||
>
|
||||
<div className="w-12 h-12 bg-zinc-50 flex items-center justify-center rounded-full mb-8 text-brand-gold">
|
||||
<UserCheck size={20} />
|
||||
</div>
|
||||
<h3 className="text-xl font-serif text-zinc-900 mb-4">
|
||||
Atendimento Personalizado
|
||||
</h3>
|
||||
<p className="text-zinc-600 font-light leading-relaxed">
|
||||
Cada cliente recebe atenção exclusiva. Compreender profundamente suas necessidades, estilo de vida e expectativas é o ponto de partida para qualquer busca ou negociação.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
className="bg-white p-10 border border-zinc-200 hover:border-brand-gold transition-colors duration-300"
|
||||
>
|
||||
<div className="w-12 h-12 bg-zinc-50 flex items-center justify-center rounded-full mb-8 text-brand-gold">
|
||||
<Briefcase size={20} />
|
||||
</div>
|
||||
<h3 className="text-xl font-serif text-zinc-900 mb-4">
|
||||
Estratégia de Negociação
|
||||
</h3>
|
||||
<p className="text-zinc-600 font-light leading-relaxed">
|
||||
Abordagem analítica e sigilosa para garantir a melhor composição de valores. Protejo seus interesses com dados de mercado concretos e vasta experiência em transações complexas.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
className="bg-white p-10 border border-zinc-200 hover:border-brand-gold transition-colors duration-300"
|
||||
>
|
||||
<div className="w-12 h-12 bg-zinc-50 flex items-center justify-center rounded-full mb-8 text-brand-gold">
|
||||
<ShieldCheck size={20} />
|
||||
</div>
|
||||
<h3 className="text-xl font-serif text-zinc-900 mb-4">
|
||||
Rede Off-Market
|
||||
</h3>
|
||||
<p className="text-zinc-600 font-light leading-relaxed">
|
||||
Acesso privilegiado a propriedades exclusivas que não são anunciadas publicamente, oferecendo um portfólio reservado para compradores qualificados.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* TESTIMONIALS SECTION (SOCIAL PROOF) */}
|
||||
<section className="py-24 bg-white border-t border-zinc-200">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="text-center mb-16">
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-zinc-400 font-bold block mb-4">
|
||||
Reconhecimento
|
||||
</span>
|
||||
<h2 className="text-4xl md:text-5xl font-serif text-zinc-900 leading-tight">
|
||||
O que dizem nossos clientes
|
||||
</h2>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<div className="bg-zinc-50 p-10 border border-zinc-200 relative">
|
||||
<div className="text-brand-gold text-4xl font-serif absolute top-6 left-6 opacity-30">"</div>
|
||||
<p className="text-zinc-700 font-light leading-relaxed mb-6 relative z-10">
|
||||
"A abordagem do Rafael foi fundamental para encontrarmos nosso novo lar de forma totalmente sigilosa e assertiva. Ele não apenas nos mostrou imóveis, mas apresentou uma análise completa sobre a valorização da região."
|
||||
</p>
|
||||
<div className="font-serif font-medium text-zinc-900">
|
||||
S.M. — Cliente de Compra (Itaim Bibi)
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-zinc-50 p-10 border border-zinc-200 relative">
|
||||
<div className="text-brand-gold text-4xl font-serif absolute top-6 left-6 opacity-30">"</div>
|
||||
<p className="text-zinc-700 font-light leading-relaxed mb-6 relative z-10">
|
||||
"Confiei a venda do meu apartamento exclusivamente à assessoria dele. O nível de qualificação dos interessados me impressionou, resultando em um fechamento focado apenas no alvo desejado."
|
||||
</p>
|
||||
<div className="font-serif font-medium text-zinc-900">
|
||||
A.C.M — Cliente de Venda (Jardins)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ SECTION */}
|
||||
<section className="py-24 bg-zinc-50 border-t border-zinc-200">
|
||||
<div className="max-w-4xl mx-auto px-6 lg:px-8">
|
||||
<div className="text-center mb-16">
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-zinc-400 font-bold block mb-4">
|
||||
Esclarecimentos
|
||||
</span>
|
||||
<h2 className="text-4xl md:text-5xl font-serif text-zinc-900 leading-tight">
|
||||
Perguntas Frequentes
|
||||
</h2>
|
||||
</div>
|
||||
<div className="space-y-6">
|
||||
<div className="border border-zinc-200 p-6 bg-white">
|
||||
<h3 className="font-serif text-xl text-zinc-900 mb-3">Como funciona a assessoria para compra de imóveis?</h3>
|
||||
<p className="text-zinc-600 font-light">Busca ativa por todo o mercado. Filtro o ruído, faço as inspeções prévias e entrego relatórios analíticos antes da sua visita.</p>
|
||||
</div>
|
||||
<div className="border border-zinc-200 p-6 bg-white">
|
||||
<h3 className="font-serif text-xl text-zinc-900 mb-3">O que são imóveis off-market?</h3>
|
||||
<p className="text-zinc-600 font-light">São propriedades exclusivas que não são anunciadas publicamente, oferecendo maior privacidade e oportunidades únicas para compradores qualificados.</p>
|
||||
</div>
|
||||
<div className="border border-zinc-200 p-6 bg-white">
|
||||
<h3 className="font-serif text-xl text-zinc-900 mb-3">Qual é a vantagem de contratar um corretor exclusivo para a venda do meu imóvel?</h3>
|
||||
<p className="text-zinc-600 font-light">A exclusividade garante um plano de marketing focado, filtro rigoroso de potenciais compradores e proteção contra a desvalorização do ativo por sobreposição de anúncios no mercado.</p>
|
||||
</div>
|
||||
<div className="border border-zinc-200 p-6 bg-white">
|
||||
<h3 className="font-serif text-xl text-zinc-900 mb-3">Você atua apenas na venda de imóveis prontos ou também em lançamentos?</h3>
|
||||
<p className="text-zinc-600 font-light">Atuo em ambos. Para lançamentos, ofereço antecipação de informações e acesso privilegiado a unidades específicas antes da abertura para o mercado em geral.</p>
|
||||
</div>
|
||||
<div className="border border-zinc-200 p-6 bg-white">
|
||||
<h3 className="font-serif text-xl text-zinc-900 mb-3">Como é garantido o sigilo durante a negociação?</h3>
|
||||
<p className="text-zinc-600 font-light">Trabalho com Acordos de Confidencialidade (NDA) quando necessário e filtro estritamente as informações compartilhadas, protegendo a identidade e o patrimônio de ambas as partes.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function ArticleRoute() {
|
||||
const { id } = useParams();
|
||||
const article = articles.find((a) => a.id === id);
|
||||
|
||||
if (!article) {
|
||||
return (
|
||||
<div className="min-h-screen pt-40 pb-24 text-center">
|
||||
<h1 className="text-4xl font-serif mb-4">Artigo não encontrado</h1>
|
||||
<Link to="/" className="text-brand-gold hover:underline">Voltar para o início</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <ArticleView article={article} />;
|
||||
}
|
||||
|
||||
function ArticleView({ article }: { article: Article }) {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{article.title} | Rafael Fontes</title>
|
||||
<meta name="description" content={article.excerpt} />
|
||||
{article.type === "property" ? (
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "RealEstateListing",
|
||||
"name": article.title,
|
||||
"description": article.excerpt,
|
||||
"image": article.coverImage,
|
||||
"offers": {
|
||||
"@type": "Offer",
|
||||
"priceCurrency": "BRL",
|
||||
"price": article.details?.price?.replace(/[^0-9]/g, "") || "0"
|
||||
}
|
||||
})}
|
||||
</script>
|
||||
) : (
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": article.title,
|
||||
"description": article.excerpt,
|
||||
"image": article.coverImage,
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Rafael Fontes"
|
||||
},
|
||||
"datePublished": "2024-01-01" // Idealmente seria a data do artigo
|
||||
})}
|
||||
</script>
|
||||
)}
|
||||
</Helmet>
|
||||
<motion.article
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="pt-32 pb-24"
|
||||
>
|
||||
<div className="max-w-4xl mx-auto px-6 lg:px-8">
|
||||
<Link
|
||||
to="/"
|
||||
className="inline-flex items-center gap-2 text-xs uppercase tracking-widest font-bold text-zinc-500 hover:text-zinc-900 transition-colors mb-12"
|
||||
>
|
||||
<ArrowLeft size={16} />
|
||||
Voltar
|
||||
</Link>
|
||||
|
||||
<div className="flex items-center gap-4 text-brand-gold text-xs font-bold uppercase tracking-widest mb-6">
|
||||
<span>{article.category}</span>
|
||||
<span className="w-4 h-px bg-brand-gold"></span>
|
||||
<span className="text-zinc-400">{article.date}</span>
|
||||
</div>
|
||||
|
||||
<h1 className="text-4xl md:text-6xl font-serif text-zinc-900 leading-[1.1] mb-8">
|
||||
{article.title}
|
||||
</h1>
|
||||
|
||||
<p className="text-xl text-zinc-600 font-light leading-relaxed mb-12 border-l-2 border-zinc-200 pl-6">
|
||||
{article.excerpt}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="w-full max-w-6xl mx-auto px-6 lg:px-8 mb-16">
|
||||
<div className="aspect-[21/9] md:aspect-[21/9] bg-zinc-200 overflow-hidden relative">
|
||||
<img
|
||||
src={article.coverImage}
|
||||
alt={article.title}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
{article.type === "property" && article.details && (
|
||||
<div className="absolute bottom-6 right-6 bg-white/90 backdrop-blur px-6 py-4 shadow-xl">
|
||||
<div className="text-xs uppercase tracking-widest text-zinc-500 font-bold mb-1">
|
||||
Preço Relacionado
|
||||
</div>
|
||||
<div className="font-serif text-2xl text-zinc-900">
|
||||
{article.details.price}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="max-w-3xl mx-auto px-6 lg:px-8">
|
||||
<div className="prose prose-zinc prose-lg font-light leading-loose text-zinc-700">
|
||||
{article.content}
|
||||
</div>
|
||||
|
||||
<div className="my-16 p-10 bg-zinc-50 border-l-4 border-brand-gold">
|
||||
<blockquote className="text-2xl font-serif italic text-zinc-900 mb-6 m-0 border-none p-0">
|
||||
"{article.quote.text}"
|
||||
</blockquote>
|
||||
<cite className="text-sm uppercase tracking-widest font-bold text-zinc-500 not-italic">
|
||||
— {article.quote.author}
|
||||
</cite>
|
||||
</div>
|
||||
|
||||
<div className="text-center pt-16 border-t border-zinc-200 mt-16">
|
||||
<h3 className="font-serif text-2xl mb-6">
|
||||
Possui interesse nesta propriedade ou assunto?
|
||||
</h3>
|
||||
<a
|
||||
href="https://wa.me/5511999999999"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="inline-flex items-center gap-3 bg-zinc-900 hover:bg-brand-gold text-white px-8 py-4 text-xs font-bold uppercase tracking-[0.1em] transition-colors"
|
||||
>
|
||||
Falar Diretamente no WhatsApp
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{article.type === "property" && article.details?.location && (
|
||||
<div className="mt-20 border-t border-zinc-200 pt-16">
|
||||
<h3 className="font-serif text-2xl mb-2 text-zinc-900">
|
||||
Localização Regional
|
||||
</h3>
|
||||
<p className="text-zinc-500 font-light text-sm mb-8">
|
||||
Para preservar a segurança e privacidade do proprietário, exibimos apenas a região aproximada da propriedade. A localização exata será divulgada apenas mediante reunião de qualificação.
|
||||
</p>
|
||||
<div className="w-full h-80 bg-zinc-200 border border-zinc-200 overflow-hidden relative">
|
||||
<iframe
|
||||
src={`https://maps.google.com/maps?q=${encodeURIComponent(article.details.location)}&t=m&z=14&output=embed`}
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen={false}
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
title={`Mapa regional para ${article.details.location}`}
|
||||
className="w-full h-full object-cover mix-blend-luminosity hover:mix-blend-normal opacity-80 hover:opacity-100 transition-all duration-700"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</motion.article>
|
||||
</>
|
||||
);
|
||||
}
|
||||
86
Template-01/src/components/Analytics.tsx
Normal file
86
Template-01/src/components/Analytics.tsx
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import { useEffect } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
export function Analytics() {
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
// Inject Google Tag Manager
|
||||
const gtmId = import.meta.env.VITE_GTM_ID;
|
||||
if (gtmId) {
|
||||
const script = document.createElement("script");
|
||||
script.innerHTML = `
|
||||
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','${gtmId}');
|
||||
`;
|
||||
document.head.appendChild(script);
|
||||
|
||||
const noscript = document.createElement("noscript");
|
||||
noscript.innerHTML = `<iframe src="https://www.googletagmanager.com/ns.html?id=${gtmId}" height="0" width="0" style="display:none;visibility:hidden"></iframe>`;
|
||||
document.body.insertBefore(noscript, document.body.firstChild);
|
||||
}
|
||||
|
||||
// Inject Google Analytics (if separate from GTM)
|
||||
const gaId = import.meta.env.VITE_GA_MEASUREMENT_ID;
|
||||
if (gaId) {
|
||||
const scriptGa = document.createElement("script");
|
||||
scriptGa.async = true;
|
||||
scriptGa.src = `https://www.googletagmanager.com/gtag/js?id=${gaId}`;
|
||||
document.head.appendChild(scriptGa);
|
||||
|
||||
const scriptInline = document.createElement("script");
|
||||
scriptInline.innerHTML = `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', '${gaId}');
|
||||
`;
|
||||
document.head.appendChild(scriptInline);
|
||||
}
|
||||
|
||||
// Inject Meta/Facebook Pixel
|
||||
const pixelId = import.meta.env.VITE_FB_PIXEL_ID;
|
||||
if (pixelId) {
|
||||
const script = document.createElement("script");
|
||||
script.innerHTML = `
|
||||
!function(f,b,e,v,n,t,s)
|
||||
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
||||
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
|
||||
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
|
||||
n.queue=[];t=b.createElement(e);t.async=!0;
|
||||
t.src=v;s=b.getElementsByTagName(e)[0];
|
||||
s.parentNode.insertBefore(t,s)}(window, document,'script',
|
||||
'https://connect.facebook.net/en_US/fbevents.js');
|
||||
fbq('init', '${pixelId}');
|
||||
fbq('track', 'PageView');
|
||||
`;
|
||||
document.head.appendChild(script);
|
||||
|
||||
const noscript = document.createElement("noscript");
|
||||
noscript.innerHTML = `<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=${pixelId}&ev=PageView&noscript=1" />`;
|
||||
document.body.appendChild(noscript);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Track page views on route change
|
||||
useEffect(() => {
|
||||
// GA PageView
|
||||
const gaId = import.meta.env.VITE_GA_MEASUREMENT_ID;
|
||||
if (gaId && typeof window !== "undefined" && (window as any).gtag) {
|
||||
(window as any).gtag("config", gaId, {
|
||||
page_path: location.pathname + location.search,
|
||||
});
|
||||
}
|
||||
|
||||
// FB Pixel PageView
|
||||
const pixelId = import.meta.env.VITE_FB_PIXEL_ID;
|
||||
if (pixelId && typeof window !== "undefined" && (window as any).fbq) {
|
||||
(window as any).fbq('track', 'PageView');
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
return null;
|
||||
}
|
||||
652
Template-01/src/data/articles.tsx
Normal file
652
Template-01/src/data/articles.tsx
Normal file
|
|
@ -0,0 +1,652 @@
|
|||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export type ArticleType = "property" | "insight";
|
||||
|
||||
export interface Article {
|
||||
id: string;
|
||||
type: ArticleType;
|
||||
category: string;
|
||||
title: string;
|
||||
excerpt: string;
|
||||
coverImage: string;
|
||||
date: string;
|
||||
content: React.ReactNode;
|
||||
quote: {
|
||||
text: string;
|
||||
author: string;
|
||||
};
|
||||
details?: {
|
||||
price?: string;
|
||||
specs?: string;
|
||||
status?: string;
|
||||
location?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const articles: Article[] = [
|
||||
{
|
||||
id: "residencial-jardim-europa-01",
|
||||
type: "property",
|
||||
category: "Jardim Europa, São Paulo",
|
||||
title: "Residência de Autor: Modernismo e Privacidade Absoluta",
|
||||
excerpt:
|
||||
"Uma análise detalhada desta propriedade singular com 850m² de área construída, integrando living e um jardim projetado por Burle Marx.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?q=80&w=2075&auto=format&fit=crop",
|
||||
date: "Maio 2026",
|
||||
quote: {
|
||||
text: "A arquitetura não é sobre a construção de paredes, mas sobre a criação de atmosferas.",
|
||||
author: "Peter Zumthor",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 18.500.000",
|
||||
specs: "850m² • 4 Suítes • 6 Vagas",
|
||||
status: "Disponível para Visitação",
|
||||
location: "Jardim Europa, São Paulo",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Apresento esta excepcional residência localizada no coração do Jardim
|
||||
Europa, um dos bairros mais tradicionais e valorizados de São Paulo.
|
||||
Tive o privilégio de acompanhar a evolução desta propriedade ao longo
|
||||
dos anos, e seu estado de conservação e design permanecem
|
||||
irretocáveis.
|
||||
</p>
|
||||
<h3>O Espaço e a Luz</h3>
|
||||
<p>
|
||||
A planta foi concebida para que a luz natural permeie todos os
|
||||
ambientes durante o dia. Painéis de vidro piso-teto criam uma
|
||||
transição fluida entre o interior e o monumental jardim, que abriga
|
||||
espécies nativas e espelhos d'água.
|
||||
</p>
|
||||
<p>
|
||||
No piso superior, a suíte master atua como um refúgio particular,
|
||||
contando com dois banheiros independentes, um amplo closet e uma
|
||||
varanda voltada para o verde. Caso esteja em busca de outras
|
||||
propriedades na região, você pode conferir nossa{" "}
|
||||
<Link to="/artigo/valorizacao-jardim-europa">
|
||||
análise de valorização do Jardim Europa
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "cobertura-itaim-bibi",
|
||||
type: "property",
|
||||
category: "Itaim Bibi, São Paulo",
|
||||
title: "A Perspectiva 360º: Cobertura Duplex no Centro Financeiro",
|
||||
excerpt:
|
||||
"Oportunidade raríssima no coração do Itaim. Uma cobertura reformada em 2024, com espaço gourmet completo voltado para o skyline da cidade.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1600607688969-a5bfcd64bd40?q=80&w=2053&auto=format&fit=crop",
|
||||
date: "Abril 2026",
|
||||
quote: {
|
||||
text: "Viver no topo é ter a cidade como seu quadro em constante mudança.",
|
||||
author: "Rafael Fontes",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 12.800.000",
|
||||
specs: "420m² • 3 Suítes • 4 Vagas",
|
||||
status: "Exclusividade",
|
||||
location: "Itaim Bibi",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
O Itaim Bibi se consolidou como o epicentro financeiro e de lifestyle
|
||||
da América Latina. Ter uma cobertura duplex nesta região é um
|
||||
privilégio destinado a poucos. Este imóvel, em particular, passou por
|
||||
um retrofit completo estrutural em 2024, assinado por um renomado
|
||||
escritório de arquitetura brasileiro.
|
||||
</p>
|
||||
<h3>Design e Funcionalidade</h3>
|
||||
<p>
|
||||
Os acabamentos incluem mármore Travertino Navona e marcenaria Ornare
|
||||
em todos os ambientes. O destaque definitivo é a área social no
|
||||
segundo pavimento, equipada com piscina de borda infinita aquecida e
|
||||
espaço gourmet, perfeito para recepções íntimas com vista para o
|
||||
parque Ibirapuera.
|
||||
</p>
|
||||
<p>
|
||||
Leia mais sobre o{" "}
|
||||
<Link to="/artigo/novo-luxo-sp">novo conceito de luxo vertical</Link>.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "fazenda-boa-vista",
|
||||
type: "property",
|
||||
category: "Porto Feliz, São Paulo",
|
||||
title: "Refúgio de Fim de Semana com Arquitetura Vernacular",
|
||||
excerpt:
|
||||
"Nesta casa de campo a uma hora de São Paulo, os limites entre o interior e o exterior deixam de existir, cercados por mata nativa e lagos exuberantes.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1613977257363-707ba9348227?q=80&w=2070&auto=format&fit=crop",
|
||||
date: "Março 2026",
|
||||
quote: {
|
||||
text: "O luxo contemporâneo é o espaço, o silêncio e o tempo.",
|
||||
author: "Axel Vervoordt",
|
||||
},
|
||||
details: {
|
||||
price: "Consulte o Valor",
|
||||
specs: "1.200m² • 6 Suítes • 8 Vagas",
|
||||
status: "Off-Market",
|
||||
location: "Fazenda Boa Vista",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Uma imersão completa na natureza sem abrir mão de nenhuma conveniência
|
||||
urbana. Esta propriedade em um dos condomínios mais exclusivos do país
|
||||
foi idealizada para ser um santuário familiar.
|
||||
</p>
|
||||
<h3>Sustentabilidade e Conforto</h3>
|
||||
<p>
|
||||
Com painéis solares, captação de água da chuva e automação residencial
|
||||
nível 4, a casa opera com altíssima eficiência. O layout privilegia
|
||||
áreas de convivência generosas, com um deck expansivo que se projeta
|
||||
em direção à paisagem. Uma verdadeira obra de arte habitável.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "tendencias-arquitetura-2026",
|
||||
type: "insight",
|
||||
category: "Tendências",
|
||||
title: "Tendências de Arquitetura e Interior para 2026",
|
||||
excerpt:
|
||||
"A fusão entre tecnologia invisível, materiais orgânicos e a fluidez dos layouts dita as regras das novas residências de luxo.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1618221195710-dd6b41faaea6?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "18 Maio, 2026",
|
||||
quote: {
|
||||
text: "Onde o design encontra a tecnologia, nasce o conforto invisível.",
|
||||
author: "Design Studio",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Este ano consolidou uma mudança silenciosa nas exigências do mercado
|
||||
premium: a tecnologia não deve mais ser vista no ambiente, mas deve
|
||||
operar tudo nos bastidores.
|
||||
</p>
|
||||
<h3>Acabamentos Orgânicos Naturais</h3>
|
||||
<p>
|
||||
Observamos a valorização de imperfeições naturais nas pedras e
|
||||
madeiras de demolição, trazendo calor e exclusividade a ambientes que
|
||||
há pouco tempo eram pautados pela frieza modernista do vidro e
|
||||
cimento.
|
||||
</p>
|
||||
<p>
|
||||
Visite nossa{" "}
|
||||
<Link to="/artigo/residencial-jardim-europa-01">
|
||||
residência no Jardim Europa
|
||||
</Link>{" "}
|
||||
para ver a aplicação prática deste conceito de design.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "mercado-luxo-sp",
|
||||
type: "insight",
|
||||
category: "Mercado Financeiro",
|
||||
title: "Por que São Paulo atrai investidores globais?",
|
||||
excerpt:
|
||||
"Dados exclusivos de valorização indicam que a capital paulista se mantém resistente às oscilações internacionais.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1430285561322-780c604615ce?q=80&w=2070&auto=format&fit=crop",
|
||||
date: "12 Maio, 2026",
|
||||
quote: {
|
||||
text: "O mercado imobiliário paulistano premium é blindado pelas dinâmicas de escassez e exclusividade.",
|
||||
author: "Financial Times",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
De forma constante, o metro quadrado das coberturas de São Paulo em
|
||||
regiões prime (Itaim, Vila Nova Conceição) superou a inflação nos
|
||||
últimos dez anos.
|
||||
</p>
|
||||
<h3>Safe Haven</h3>
|
||||
<p>
|
||||
Para fundos e family offices, estacionar capital em imóveis icônicos
|
||||
da cidade provou ser tanto um mecanismo de proteção quanto um
|
||||
propulsor de ganhos através da hiper-valorização e retrofit.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "guia-aquisicao-jardim-europa",
|
||||
type: "insight",
|
||||
category: "Investimentos",
|
||||
title: "A valorização contínua e as oportunidades no Jardim Europa",
|
||||
excerpt:
|
||||
"Como as restrições construtivas garantem o valor do bairro, e por que a paciência é a melhor estratégia de compra.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1518507727145-cb3e7f01de55?q=80&w=2070&auto=format&fit=crop",
|
||||
date: "05 Maio, 2026",
|
||||
quote: {
|
||||
text: "A ausência de verticalização é o maior luxo contemporâneo de São Paulo.",
|
||||
author: "Instituto Urbano",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Diferente de NY ou Londres, as áreas exclusivas de casas em São Paulo
|
||||
não podem se adensar. O Jardim Europa é tombado, protegendo seus
|
||||
moradores dos prédios altos. Mas o que isso significa para o
|
||||
patrimônio?
|
||||
</p>
|
||||
<h3>Escassez de Solo e Curva de Apreciação</h3>
|
||||
<p>
|
||||
Na prática, quem possui um terreno na região não tem novos
|
||||
competidores. Recomendamos sempre uma análise minuciosa de diligência
|
||||
(<Link to="/artigo/guia-aquisicao-jardim-europa">leia o guia de aquisição</Link>) antes
|
||||
de assinar qualquer compromisso, devido à complexidade da
|
||||
regularização imobiliária das casas antigas.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "penthouse-cidade-jardim",
|
||||
type: "property",
|
||||
category: "Cidade Jardim, São Paulo",
|
||||
title: "Triplex Suspenso com Vista para a Skyline Paulista",
|
||||
excerpt:
|
||||
"Com mais de 1000m², este apartamento evoca a essência de uma mansão suspensa.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "01 Maio, 2026",
|
||||
quote: {
|
||||
text: "A grandiosidade se mede pelo espaço e pela privacidade, a centenas de metros do chão.",
|
||||
author: "Rafael Fontes",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 35.000.000",
|
||||
specs: "1050m² • 5 Suítes • 10 Vagas",
|
||||
status: "Exclusividade",
|
||||
location: "Cidade Jardim",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Espaços palacianos. O pé direito duplo do living cria uma sensação de
|
||||
imponência. A suíte master ocupa um andar inteiro. Esta é, de fato,
|
||||
uma joia cobiçada no portfólio.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "guia-aquisicao",
|
||||
type: "insight",
|
||||
category: "Guia Jurídico",
|
||||
title: "Guia de Aquisição: Estruturação jurídica para grandes propriedades",
|
||||
excerpt:
|
||||
"Os passos essenciais e diligências que aplico antes de apresentar qualquer imóvel aos meus clientes.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1450101499163-c8848c66cb85?q=80&w=2070&auto=format&fit=crop",
|
||||
date: "28 Abril, 2026",
|
||||
quote: {
|
||||
text: "A verdadeira segurança em uma negociação imobiliária reside no que não está visível.",
|
||||
author: "L. Barros, Jurista",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Em transações de alto valor agregado, as certidões cíveis e criminais
|
||||
formam apenas 30% da verdadeira análise de risco.
|
||||
</p>
|
||||
<p>
|
||||
Para ler mais, verifique{" "}
|
||||
<Link to="/artigo/importancia-retrofit">
|
||||
como o retrofit pode impactar esse risco legal
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "novo-luxo-sp",
|
||||
type: "insight",
|
||||
category: "Comportamento",
|
||||
title: "O Novo Luxo: Espaço vs Localização",
|
||||
excerpt:
|
||||
"A mudança de paradigma daqueles que valorizavam endereços cobiçados acima de tudo, em prol do espaço e bem-estar.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1512917774080-9991f1c4c750?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "22 Abril, 2026",
|
||||
quote: {
|
||||
text: "Não compramos mais endereço, compramos qualidade de vida.",
|
||||
author: "Exame",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
A pandemia alterou permanentemente o morar premium. O verde deixou de
|
||||
ser adorno para ser infraestrutura.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "investimento-arte-imoveis",
|
||||
type: "insight",
|
||||
category: "Lifestyle",
|
||||
title: "Investimento em Arte e Alta Decoração de Interiores",
|
||||
excerpt:
|
||||
"Como colecionar arte tem sinergia com o mercado de real estate de altíssimo nível.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1513694203232-719a280e022f?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "15 Abril, 2026",
|
||||
quote: {
|
||||
text: "As paredes são curadoras de nossas almas.",
|
||||
author: "D. Soares",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Casas de proporções generosas demandam peças à altura. Há um
|
||||
intercâmbio constante entre galerias de arte e imobiliárias premium.
|
||||
Em minha{" "}
|
||||
<Link to="/artigo/fazenda-boa-vista">casa na Fazenda Boa Vista</Link>, o
|
||||
projeto incluiu recuos para esculturas grandes.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "condominio-vila-nova",
|
||||
type: "property",
|
||||
category: "Vila Nova Conceição",
|
||||
title: "Apartamento Neoclássico na Praça Pereira Coutinho",
|
||||
excerpt:
|
||||
"Uma joia intocada em um dos logradouros mais valorizados do país.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1497366216548-37526070297c?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "10 Abril, 2026",
|
||||
quote: {
|
||||
text: "Viver de frente para a praça é prolongar a sala de estar.",
|
||||
author: "R. Fontes",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 16.000.000",
|
||||
specs: "300m² • 3 Suítes • 4 Vagas",
|
||||
status: "Disponível",
|
||||
location: "Vila Nova Conceição",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
A exclusividade de atravessar a rua e estar no Ibirapuera. Edifício de
|
||||
assinatura clássica, segurança impecável. Veja as tendências em{" "}
|
||||
<Link to="/artigo/tendencias-arquitetura-2026">arquitetura</Link> para
|
||||
atualizar o apartamento se desejar um retrofit.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "casa-alphaville",
|
||||
type: "property",
|
||||
category: "Alphaville, São Paulo",
|
||||
title: "Mansão Monumental no Tamboré",
|
||||
excerpt:
|
||||
"Segurança e qualidade de vida com proporções que a capital já não oferece.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1628611225249-6c4c3af4a80b?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "03 Abril, 2026",
|
||||
quote: {
|
||||
text: "O refúgio perfeito a 30 minutos da Faria Lima.",
|
||||
author: "Revista Habitar",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 22.000.000",
|
||||
specs: "1500m² • 6 Suítes • 12 Vagas",
|
||||
status: "Consulte",
|
||||
location: "Tamboré Destaque",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Condomínios de alto luxo em Barueri continuam sua ascensão
|
||||
impulsionada pelo recuo da modalidade de trabalho híbrido.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "arquitetura-biofilica",
|
||||
type: "insight",
|
||||
category: "Design",
|
||||
title: "Design Biofílico: O que os compradores premium procuram hoje",
|
||||
excerpt:
|
||||
"Como a integração com o verde deixou de ser um diferencial e passou a ser exigência.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "30 Março, 2026",
|
||||
quote: {
|
||||
text: "A natureza não é um lugar para visitar. É a nossa casa.",
|
||||
author: "Gary Snyder",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Temos notado o aumento drástico pela procura de incorporações que
|
||||
possuam mata nativa integrada. O verde é a nova corrente estética.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "sustentabilidade-luxo",
|
||||
type: "insight",
|
||||
category: "Visão de Futuro",
|
||||
title: "Sustentabilidade e Alto Padrão não são mais mutuamente exclusivos",
|
||||
excerpt: "Certificações EDGE e LEED em residências horizontais.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1501183638710-841dd1904471?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "25 Março, 2026",
|
||||
quote: {
|
||||
text: "Luxo de verdade é não causar impacto sistêmico.",
|
||||
author: "ESG Real Estate",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
A preocupação climática levou a uma modernização drástica dos métodos
|
||||
construtivos e de suprimentos de energia off-grid.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "retorno-casas-vila",
|
||||
type: "insight",
|
||||
category: "Urbanismo",
|
||||
title: "O Retorno e Valorização das Casas de Vila em São Paulo",
|
||||
excerpt:
|
||||
"A procura desenfreada por vilas charmosas nos Jardins e Pinheiros.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1579487785973-74d2ca78ddfc?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "20 Março, 2026",
|
||||
quote: {
|
||||
text: "Há uma poesia irreplicável em pisar na rua de paralelepípedos e abrir um modesto portão para um oasis interno.",
|
||||
author: "R. Fontes",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Com as poucas unidades disponíveis no mercado, a precificação bate
|
||||
recordes históricos. Veja mais em{" "}
|
||||
<Link to="/artigo/mercado-off-market">off-market insights</Link>.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "mercado-off-market",
|
||||
type: "insight",
|
||||
category: "Fundamentos",
|
||||
title: "Mercado Off-Market: A negociação nas sombras",
|
||||
excerpt:
|
||||
"Como operam as chamadas 'Secret Listings' nas camadas mais altas da riqueza paulistana.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1590856029826-c7a73142bbf1?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "14 Março, 2026",
|
||||
quote: {
|
||||
text: "A discrição é a forma mais elevada de confiança.",
|
||||
author: "Private Broker",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Cerca de 40% das transações ultraluxo acontecem sem que a propriedade
|
||||
seja sequer fotografada profissionalmente e inserida na rede.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "importancia-retrofit",
|
||||
type: "insight",
|
||||
category: "Investimentos",
|
||||
title: "A Importância do Retrofit nos Endereços Icônicos",
|
||||
excerpt: "Atualizando prédios da década de 70 para compradores atuais.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1503387762-592deb58ef4e?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "10 Março, 2026",
|
||||
quote: {
|
||||
text: "Preservamos a fachada para atualizar a alma.",
|
||||
author: "Arquitetura & Urbanismo",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
O retrofit é, hoje, a modalidade de investimento que mais agrega valor
|
||||
ao metro quadrado defasado de Higienópolis e Jardins.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "casa-pinheiros",
|
||||
type: "property",
|
||||
category: "Alto de Pinheiros",
|
||||
title: "Residência Contemporânea Próxima à Praça Panamericana",
|
||||
excerpt: "Casa de esquina, com total segurança e vocação receber.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1512915922686-57c11dde9b6b?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "05 Março, 2026",
|
||||
quote: {
|
||||
text: "Silêncio profundo na metrópole barulhenta.",
|
||||
author: "Proprietário",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 14.500.000",
|
||||
specs: "650m² • 4 Suítes • 5 Vagas",
|
||||
status: "Disponível",
|
||||
location: "Alto de Pinheiros",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>Luz, brisa e segurança. Uma rara oportunidade em Pinheiros.</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "apartamento-jardins",
|
||||
type: "property",
|
||||
category: "Jardins",
|
||||
title: "Apartamento de Época Totalmente Restaurado",
|
||||
excerpt: "O charme do piso em taco de peroba e do pé direito de 3.20m.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1533779283484-8ad4940aa3a8?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "28 Fevereiro, 2026",
|
||||
quote: {
|
||||
text: "O antigo redescoberto.",
|
||||
author: "Design Team",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 6.800.000",
|
||||
specs: "280m² • 3 Suítes • 2 Vagas",
|
||||
status: "Em Negociação",
|
||||
location: "Jardins",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Um espetáculo visual de retrofit de ponta, ver mais em{" "}
|
||||
<Link to="/artigo/importancia-retrofit">importância do retrofit</Link>.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "cobertura-brooklin",
|
||||
type: "property",
|
||||
category: "Brooklin",
|
||||
title: "Penthouse Exclusiva no Novo Polo",
|
||||
excerpt:
|
||||
"Condomínio clube moderno com todas as facilidades e uma planta fenomenal.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1502672260266-1c1e52509def?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "20 Fevereiro, 2026",
|
||||
quote: {
|
||||
text: "O novo centro convergiu para cá.",
|
||||
author: "Valor Econômico",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 10.500.000",
|
||||
specs: "380m² • 3 Suítes • 4 Vagas",
|
||||
status: "Disponível",
|
||||
location: "Brooklin Novo",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Uma chance excelente na região com as sedes das maiores empresas do
|
||||
Brasil.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "fazenda-boa-vista-grama",
|
||||
type: "property",
|
||||
category: "Fazenda da Grama",
|
||||
title: "Casa de Campo Moderna com Vista para o Lago",
|
||||
excerpt: "Para fugir de São Paulo, no condomínio com praia particular.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1521579294248-c2bfa12a52ce?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "15 Fevereiro, 2026",
|
||||
quote: {
|
||||
text: "O pé na areia agora é verde e montanhoso.",
|
||||
author: "Lifestyle Magazine",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 15.000.000",
|
||||
specs: "800m² • 5 Suítes • 6 Vagas",
|
||||
status: "Off-Market",
|
||||
location: "Itupeva",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Arquitetura em U ao redor de um pátio magnífico e uma piscina espelho
|
||||
que repousa sobre a visão do lago central.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
20
Template-01/src/index.css
Normal file
20
Template-01/src/index.css
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap');
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@theme {
|
||||
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-serif: "Playfair Display", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
||||
|
||||
--color-brand-gold: #cba258;
|
||||
--color-brand-gold-hover: #b8914b;
|
||||
--color-brand-dark: #121212;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply font-sans text-zinc-800 bg-zinc-50;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
@apply font-serif;
|
||||
}
|
||||
16
Template-01/src/main.tsx
Normal file
16
Template-01/src/main.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import {StrictMode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { HelmetProvider } from 'react-helmet-async';
|
||||
import App from './App.tsx';
|
||||
import './index.css';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<HelmetProvider>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</HelmetProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
99
Template-01/src/pages/AssessoriaPage.tsx
Normal file
99
Template-01/src/pages/AssessoriaPage.tsx
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import { motion } from "motion/react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
|
||||
export function AssessoriaPage() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>A Assessoria | Rafael Fontes | Consultoria Imobiliária Especializada</title>
|
||||
<meta name="description" content="Proteja seus interesses nas transações imobiliárias mais complexas. Assessoria completa focada em precisão: do representation do vendedor ao buyer's agent." />
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Service",
|
||||
"serviceType": "Consultoria Imobiliária",
|
||||
"provider": {
|
||||
"@type": "RealEstateAgent",
|
||||
"name": "Rafael Fontes"
|
||||
},
|
||||
"description": "Consultoria imobiliária especializada em transações complexas e mercado de luxo. Representação de proprietários e assessoria na compra (Buyer's Agent)."
|
||||
})}
|
||||
</script>
|
||||
</Helmet>
|
||||
<div className="pt-32 pb-24 bg-zinc-50 text-zinc-900 min-h-screen flex items-center">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-20 items-center">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
>
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-brand-gold font-bold block mb-4">
|
||||
A Prática
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl font-serif leading-tight mb-8">
|
||||
Consultoria Imobiliária Especializada.
|
||||
</h1>
|
||||
<div className="w-16 h-px bg-brand-gold mb-8"></div>
|
||||
<p className="text-zinc-600 font-light text-lg leading-relaxed mb-8">
|
||||
Sou contratado para proteger os interesses dos meus clientes nas
|
||||
transações mais complexas do mercado. Não trabalho com volume,
|
||||
mas com precisão.
|
||||
</p>
|
||||
|
||||
<ul className="space-y-8 mt-12">
|
||||
<li className="flex gap-4">
|
||||
<div className="w-8 h-8 rounded-full border border-brand-gold flex items-center justify-center shrink-0 mt-1">
|
||||
<span className="text-brand-gold text-xs">01</span>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-xl font-serif mb-2">
|
||||
Representação de Proprietários
|
||||
</h4>
|
||||
<p className="text-zinc-600 font-light">
|
||||
Estratégias de marketing personalizadas, fotos editoriais
|
||||
e apresentação focada para compradores qualificados.
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex gap-4">
|
||||
<div className="w-8 h-8 rounded-full border border-brand-gold flex items-center justify-center shrink-0 mt-1">
|
||||
<span className="text-brand-gold text-xs">02</span>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-xl font-serif mb-2">
|
||||
Assessoria na Compra (Buyer's Agent)
|
||||
</h4>
|
||||
<p className="text-zinc-600 font-light">
|
||||
Busca ativa por todo o mercado. Filtro o ruído, faço as
|
||||
inspeções prévias e entrego relatórios analíticos antes da
|
||||
sua visita.
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
className="grid grid-cols-2 gap-4"
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
>
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1449844908441-8829872d2607?q=80&w=2070&auto=format&fit=crop"
|
||||
alt="Jardins"
|
||||
className="w-full aspect-[3/4] object-cover rounded-sm grayscale-[30%]"
|
||||
/>
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=2070&auto=format&fit=crop"
|
||||
alt="Itaim"
|
||||
className="w-full aspect-[3/4] object-cover rounded-sm grayscale-[30%] translate-y-8"
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
137
Template-01/src/pages/ContatoPage.tsx
Normal file
137
Template-01/src/pages/ContatoPage.tsx
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
import React, { useState } from "react";
|
||||
import { motion } from "motion/react";
|
||||
import { Instagram as InstaIcon, Linkedin as LinkedInIcon } from "lucide-react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
|
||||
export function ContatoPage() {
|
||||
const [isSubmitted, setIsSubmitted] = useState(false);
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setIsSubmitted(true);
|
||||
// Here you would typically send data to a backend
|
||||
setTimeout(() => {
|
||||
setIsSubmitted(false);
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Contato | Rafael Fontes | Corretor de Luxo</title>
|
||||
<meta name="description" content="Entre em contato para agendar uma reunião sigilosa. Discutiremos seus objetivos imobiliários no momento atual do mercado." />
|
||||
</Helmet>
|
||||
<div className="bg-zinc-50 pt-32 pb-24 text-zinc-900 min-h-screen flex items-center">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8 w-full">
|
||||
<motion.div
|
||||
className="grid grid-cols-1 md:grid-cols-12 gap-16"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
>
|
||||
<div className="md:col-span-5">
|
||||
<h1 className="text-4xl lg:text-5xl font-serif leading-tight mb-8">
|
||||
Pronto para o<br />
|
||||
próximo passo?
|
||||
</h1>
|
||||
<p className="text-zinc-600 font-light text-lg mb-10 max-w-md">
|
||||
Entre em contato para agendar uma reunião sigilosa. Discutiremos
|
||||
seus objetivos imobiliários no momento atual do mercado.
|
||||
</p>
|
||||
|
||||
{isSubmitted ? (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="p-6 bg-brand-gold/10 border border-brand-gold/20 text-zinc-900 mb-8"
|
||||
>
|
||||
<h3 className="font-serif text-xl mb-2">Mensagem Enviada</h3>
|
||||
<p className="text-zinc-600 font-light">Obrigado pelo seu contato. Retornarei o mais breve possível com máxima discrição.</p>
|
||||
</motion.div>
|
||||
) : (
|
||||
<form className="space-y-4 max-w-md" onSubmit={handleSubmit}>
|
||||
<div>
|
||||
<label htmlFor="name" className="sr-only">Nome Completo</label>
|
||||
<input required type="text" id="name" placeholder="Nome Completo" className="w-full bg-white border border-zinc-200 text-zinc-900 px-4 py-3 text-sm focus:outline-none focus:border-brand-gold transition-colors placeholder:text-zinc-400" />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="email" className="sr-only">Email</label>
|
||||
<input required type="email" id="email" placeholder="Endereço de E-mail" className="w-full bg-white border border-zinc-200 text-zinc-900 px-4 py-3 text-sm focus:outline-none focus:border-brand-gold transition-colors placeholder:text-zinc-400" />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="phone" className="sr-only">Telefone / WhatsApp</label>
|
||||
<input required type="tel" id="phone" placeholder="Telefone / WhatsApp" className="w-full bg-white border border-zinc-200 text-zinc-900 px-4 py-3 text-sm focus:outline-none focus:border-brand-gold transition-colors placeholder:text-zinc-400" />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="message" className="sr-only">Mensagem (opcional)</label>
|
||||
<textarea id="message" rows={4} placeholder="Sua Mensagem (opcional)" className="w-full bg-white border border-zinc-200 text-zinc-900 px-4 py-3 text-sm focus:outline-none focus:border-brand-gold transition-colors placeholder:text-zinc-400 resize-none"></textarea>
|
||||
</div>
|
||||
<button type="submit" className="w-full bg-brand-gold hover:bg-brand-gold-hover text-white px-8 py-4 text-xs font-bold uppercase tracking-[0.1em] transition-colors mt-2">
|
||||
Solicitar Contato
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-3 md:col-start-7 text-sm font-light">
|
||||
<h4 className="text-zinc-900 font-bold mb-6 font-serif tracking-wide text-lg">
|
||||
Contato Rápido
|
||||
</h4>
|
||||
<ul className="space-y-4 text-zinc-600">
|
||||
<li>
|
||||
<a
|
||||
href="mailto:rafael@rafaelfontes.com"
|
||||
className="hover:text-brand-gold transition-colors"
|
||||
>
|
||||
rafael@rafaelfontes.com
|
||||
</a>
|
||||
</li>
|
||||
<li>+55 11 99999.9999</li>
|
||||
<li className="pt-4 flex gap-6">
|
||||
<a href="#" className="hover:text-brand-gold transition-colors">
|
||||
<InstaIcon size={20} />
|
||||
</a>
|
||||
<a href="#" className="hover:text-brand-gold transition-colors">
|
||||
<LinkedInIcon size={20} />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-3 text-sm font-light">
|
||||
<h4 className="text-zinc-900 font-bold mb-6 font-serif tracking-wide text-lg">
|
||||
Localização
|
||||
</h4>
|
||||
<ul className="space-y-4 text-zinc-600">
|
||||
<li>Av. Brigadeiro Faria Lima, 3477</li>
|
||||
<li>Itaim Bibi</li>
|
||||
<li>São Paulo - SP</li>
|
||||
<li>14º Andar (Atendimento com hora marcada)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* MAP SECTION */}
|
||||
<motion.div
|
||||
className="mt-20 w-full h-96 bg-zinc-200 border border-zinc-200"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
>
|
||||
<iframe
|
||||
src="https://maps.google.com/maps?q=Av.%20Brigadeiro%20Faria%20Lima,%203477,%20São%20Paulo&t=m&z=16&output=embed"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen={false}
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
title="Localização do Escritório"
|
||||
className="w-full h-full object-cover grayscale opacity-80 hover:grayscale-0 hover:opacity-100 transition-all duration-700"
|
||||
></iframe>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
65
Template-01/src/pages/InsightsPage.tsx
Normal file
65
Template-01/src/pages/InsightsPage.tsx
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { Link } from "react-router-dom";
|
||||
import { ArrowRight } from "lucide-react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { Article } from "../data/articles";
|
||||
import { motion } from "motion/react";
|
||||
|
||||
export function InsightsPage({ marketInsights }: { marketInsights: Article[] }) {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Insights & Blog | Rafael Fontes</title>
|
||||
<meta name="description" content="Artigos e análises de mercado sobre o mercado imobiliário premium de São Paulo. Dicas de negócios e inteligência analítica." />
|
||||
</Helmet>
|
||||
<div className="pt-32 pb-24 bg-zinc-50 min-h-screen">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="flex flex-col md:flex-row justify-between items-end mb-16 gap-6">
|
||||
<div>
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-zinc-400 font-bold block mb-4">
|
||||
Blog Pessoal
|
||||
</span>
|
||||
<h1 className="text-4xl font-serif text-zinc-900 leading-tight">
|
||||
Artigos & Análises de Mercado
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-12">
|
||||
{marketInsights.map((post, index) => (
|
||||
<motion.div
|
||||
key={post.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.1 * index }}
|
||||
>
|
||||
<Link
|
||||
to={`/artigo/${post.id}`}
|
||||
className="group block"
|
||||
>
|
||||
<div className="mb-4">
|
||||
<span className="text-xs text-zinc-400 uppercase tracking-widest">
|
||||
{post.date}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-serif text-zinc-900 mb-4 group-hover:text-brand-gold transition-colors">
|
||||
{post.title}
|
||||
</h3>
|
||||
<p className="text-zinc-600 font-light text-sm leading-relaxed mb-6">
|
||||
{post.excerpt}
|
||||
</p>
|
||||
<span className="flex items-center gap-2 text-xs font-bold uppercase tracking-wider text-brand-gold">
|
||||
Ler artigo completo{" "}
|
||||
<ArrowRight
|
||||
size={14}
|
||||
className="group-hover:translate-x-1 transition-transform"
|
||||
/>
|
||||
</span>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
146
Template-01/src/pages/PortfolioPage.tsx
Normal file
146
Template-01/src/pages/PortfolioPage.tsx
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
import { motion } from "motion/react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { MapPin, ArrowRight } from "lucide-react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { Article } from "../data/articles";
|
||||
|
||||
export function PortfolioPage({ propertiesAsArticles }: { propertiesAsArticles: Article[] }) {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Portfólio de Luxo | Rafael Fontes</title>
|
||||
<meta name="description" content="Explore propriedades de alto padrão e luxo em São Paulo. Casas e apartamentos em bairros como Itaim Bibi e Jardins, além de opções off-market exclusivas." />
|
||||
<meta property="og:title" content="Portfólio de Luxo | Rafael Fontes" />
|
||||
<meta property="og:description" content="Explore propriedades de alto padrão e luxo em São Paulo. Casas e apartamentos em bairros como Itaim Bibi e Jardins." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="Portfólio de Luxo | Rafael Fontes" />
|
||||
<meta name="twitter:description" content="Explore propriedades de alto padrão e luxo em São Paulo." />
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [{
|
||||
"@type": "ListItem",
|
||||
"position": 1,
|
||||
"name": "Home",
|
||||
"item": "https://rafaelfontes.com.br/"
|
||||
},{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"name": "Portfólio",
|
||||
"item": "https://rafaelfontes.com.br/portfolio"
|
||||
}]
|
||||
})}
|
||||
</script>
|
||||
</Helmet>
|
||||
<div className="pt-32 pb-24 bg-zinc-50 min-h-screen">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6 mb-24">
|
||||
<div className="max-w-2xl">
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-zinc-400 font-bold block mb-4">
|
||||
Destaques do Portfólio
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl font-serif text-zinc-900 leading-tight">
|
||||
Apresentação de Imóveis
|
||||
</h1>
|
||||
</div>
|
||||
<p className="text-zinc-500 font-light max-w-sm">
|
||||
Cada propriedade é tratada como um estudo de caso. Analiso a
|
||||
arquitetura, a viabilidade e o potencial do ativo antes de
|
||||
apresentá-lo.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-32">
|
||||
{propertiesAsArticles.map((property, index) => (
|
||||
<motion.article
|
||||
key={property.id}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className={`flex flex-col ${index % 2 !== 0 ? "md:flex-row-reverse" : "md:flex-row"} gap-12 lg:gap-20 items-center group`}
|
||||
>
|
||||
{/* Image Side */}
|
||||
<div className="w-full md:w-3/5">
|
||||
<Link
|
||||
to={`/artigo/${property.id}`}
|
||||
className="block relative aspect-[16/11] overflow-hidden bg-zinc-100"
|
||||
>
|
||||
<img
|
||||
src={property.coverImage}
|
||||
alt={property.title}
|
||||
loading={index === 0 ? "eager" : "lazy"}
|
||||
className="w-full h-full object-cover transform group-hover:scale-105 transition-transform duration-[1.5s] ease-out"
|
||||
/>
|
||||
<div className="absolute top-6 left-6 bg-white/90 backdrop-blur px-4 py-2 text-xs font-bold uppercase tracking-wider text-zinc-900">
|
||||
{property.details?.status || "Exclusividade"}
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Content Side */}
|
||||
<div className="w-full md:w-2/5 flex flex-col justify-center">
|
||||
<div className="flex items-center gap-3 text-brand-gold text-sm font-semibold uppercase tracking-wider mb-4">
|
||||
<MapPin size={16} />
|
||||
<span>{property.category}</span>
|
||||
</div>
|
||||
|
||||
<Link to={`/artigo/${property.id}`}>
|
||||
<h3 className="text-3xl lg:text-4xl font-serif text-zinc-900 leading-tight mb-6 hover:text-brand-gold transition-colors">
|
||||
{property.title}
|
||||
</h3>
|
||||
</Link>
|
||||
|
||||
<p className="text-zinc-600 font-light leading-relaxed mb-8">
|
||||
{property.excerpt}
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-8 py-6 border-y border-zinc-100">
|
||||
<div>
|
||||
<span className="block text-xs uppercase tracking-widest text-zinc-400 font-semibold mb-1">
|
||||
Características
|
||||
</span>
|
||||
<span className="text-zinc-900 font-medium">
|
||||
{property.details?.specs}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="block text-xs uppercase tracking-widest text-zinc-400 font-semibold mb-1">
|
||||
Preço Solicitado
|
||||
</span>
|
||||
<span className="text-zinc-900 font-serif text-xl">
|
||||
{property.details?.price}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
to={`/artigo/${property.id}`}
|
||||
className="inline-flex items-center gap-3 text-xs font-bold uppercase tracking-[0.1em] text-zinc-900 group-hover:text-brand-gold transition-colors w-fit"
|
||||
>
|
||||
Acessar Dossier Completo{" "}
|
||||
<ArrowRight
|
||||
size={16}
|
||||
className="group-hover:translate-x-1 transition-transform"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</motion.article>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-24 text-center">
|
||||
<Link
|
||||
to="/contato"
|
||||
className="inline-flex items-center gap-3 border border-zinc-300 px-8 py-4 text-xs font-bold uppercase tracking-[0.1em] text-zinc-900 hover:bg-zinc-900 hover:text-white hover:border-zinc-900 transition-all duration-300"
|
||||
>
|
||||
Solicitar Lista Completa (Opções Off-Market)
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
1
Template-01/src/vite-env.d.ts
vendored
Normal file
1
Template-01/src/vite-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
||||
26
Template-01/tsconfig.json
Normal file
26
Template-01/tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"module": "ESNext",
|
||||
"lib": [
|
||||
"ES2022",
|
||||
"DOM",
|
||||
"DOM.Iterable"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"allowJs": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
24
Template-01/vite.config.ts
Normal file
24
Template-01/vite.config.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import tailwindcss from '@tailwindcss/vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import path from 'path';
|
||||
import {defineConfig, loadEnv} from 'vite';
|
||||
|
||||
export default defineConfig(({mode}) => {
|
||||
const env = loadEnv(mode, '.', '');
|
||||
return {
|
||||
plugins: [react(), tailwindcss()],
|
||||
define: {
|
||||
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, '.'),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
||||
// Do not modifyâfile watching is disabled to prevent flickering during agent edits.
|
||||
hmr: process.env.DISABLE_HMR !== 'true',
|
||||
},
|
||||
};
|
||||
});
|
||||
49
Template-02/README.md
Normal file
49
Template-02/README.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Helena Fontes - Template Premium para Corretores de Alto Padrão
|
||||
|
||||
Este é um template React VIP, projetado para corretores de imóveis, butiques imobiliárias e assessorias que focam no mercado de alto padrão e luxo.
|
||||
|
||||
## 🚀 Como Iniciar
|
||||
|
||||
1. **Instale as dependências:**
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
2. **Rode o servidor de desenvolvimento:**
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
Acesse em `http://localhost:5173/` (ou a porta informada pelo Vite).
|
||||
|
||||
3. **Crie a build para produção:**
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## 🎨 Customização
|
||||
|
||||
### 1. Identidade Visual (Cores e Fontes)
|
||||
Para alterar a paleta de cores (ex: o tom dourado ou o tom escuro), edite o arquivo `src/index.css`.
|
||||
As fontes são o **Montserrat** (sem serifa) e **Cormorant Garamond** (serifada) aplicadas via Tailwind. Se desejar alterar as fontes globais, modifique os imports no início do `src/index.css` e as definições variáveis.
|
||||
|
||||
### 2. Edição de Dados (Portfólio e Blog)
|
||||
O template é preenchido através do arquivo **`src/data/articles.ts`**.
|
||||
Para adicionar ou remover propriedades e artigos de mercado, basta alterar este arquivo. As imagens devem preferencialmente seguir o aspect ratio das fotos atuais (ou utilizar o Unsplash para placeholder).
|
||||
|
||||
### 3. Integração de Analytics (Tráfego Pago)
|
||||
Configure suas tags no arquivo `.env` baseado no `.env.example`:
|
||||
- `VITE_GTM_ID`: Google Tag Manager
|
||||
- `VITE_GA_MEASUREMENT_ID`: Google Analytics (G-XXXXXX)
|
||||
- `VITE_FB_PIXEL_ID`: Pixel do Facebook/Meta
|
||||
- `VITE_GOOGLE_ADS_ID`: Tag de Conversão Google Ads (AW-XXXXXX)
|
||||
|
||||
### 4. Formulário de Contato
|
||||
A página de contato (`src/pages/ContatoPage.tsx`) possui um design funcional. Para receber os leads diretamente e de forma gratuita em templates estáticos (sem backend), recomendamos trocar o evento onSubmit padrão e integrar plataformas simples como o [Formspree](https://formspree.io/) ou [Netlify Forms](https://docs.netlify.com/forms/setup/).
|
||||
|
||||
### 5. Links e Redes Sociais
|
||||
Lembre-se de atualizar os `href` dos ícones no arquivo `src/App.tsx` (Footer) com os links reais de seu Instagram e LinkedIn.
|
||||
|
||||
## 🌐 Deploy
|
||||
Sendo um aplicativo Vite React App Single Page Application (SPA), o projeto é totalmente otimizado para deploy em plataformas de hospedagem estática gratuitas ou profissionais como **Vercel**, **Netlify**, ou **Cloudflare Pages**.
|
||||
|
||||
*Desenvolvido com sofisticação em React, Vite, Framer Motion e Tailwind CSS.*
|
||||
22
Template-02/fix_links.js
Normal file
22
Template-02/fix_links.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
const fs = require('fs');
|
||||
const file = 'src/data/articles.tsx';
|
||||
let content = fs.readFileSync(file, 'utf8');
|
||||
|
||||
const replacements = [
|
||||
['<Link to="/">\n análise de valorização do Jardim Europa', '<Link to="/artigo/valorizacao-jardim-europa">\n análise de valorização do Jardim Europa'],
|
||||
['<Link to="/">novo conceito de luxo vertical', '<Link to="/artigo/novo-luxo-sp">novo conceito de luxo vertical'],
|
||||
['<Link to="/">\n residência no Jardim Europa', '<Link to="/artigo/residencial-jardim-europa-01">\n residência no Jardim Europa'],
|
||||
['<Link to="/">leia o guia de aquisição', '<Link to="/artigo/guia-aquisicao-jardim-europa">leia o guia de aquisição'],
|
||||
['<Link to="/">\n como o retrofit pode impactar esse risco legal', '<Link to="/artigo/importancia-retrofit">\n como o retrofit pode impactar esse risco legal'],
|
||||
['<Link to="/">casa na Fazenda Boa Vista', '<Link to="/artigo/fazenda-boa-vista">casa na Fazenda Boa Vista'],
|
||||
['<Link to="/">arquitetura', '<Link to="/artigo/tendencias-arquitetura-2026">arquitetura'],
|
||||
['<Link to="/">off-market insights', '<Link to="/artigo/mercado-off-market">off-market insights'],
|
||||
['<Link to="/">importância do retrofit', '<Link to="/artigo/importancia-retrofit">importância do retrofit']
|
||||
];
|
||||
|
||||
for (const [search, replace] of replacements) {
|
||||
content = content.replace(search, replace);
|
||||
}
|
||||
|
||||
fs.writeFileSync(file, content);
|
||||
console.log("Done");
|
||||
13
Template-02/index.html
Normal file
13
Template-02/index.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Helena Fontes | Corretora de Imóveis Premium</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
6
Template-02/metadata.json
Normal file
6
Template-02/metadata.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "Rafael Fontes - Corretor de Imobiliária Premium",
|
||||
"description": "Website premium para corretor de imóveis focado em propriedades de alto padrão e luxo.",
|
||||
"requestFramePermissions": [],
|
||||
"majorCapabilities": []
|
||||
}
|
||||
4480
Template-02/package-lock.json
generated
Normal file
4480
Template-02/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
38
Template-02/package.json
Normal file
38
Template-02/package.json
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "react-example",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --port=3000 --host=0.0.0.0",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.29.0",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"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-icons": "^5.6.0",
|
||||
"react-router-dom": "^7.15.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"
|
||||
}
|
||||
}
|
||||
1
Template-02/public/_redirects
Normal file
1
Template-02/public/_redirects
Normal file
|
|
@ -0,0 +1 @@
|
|||
/* /index.html 200
|
||||
4
Template-02/public/robots.txt
Normal file
4
Template-02/public/robots.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://helenafontes.com.br/sitemap.xml
|
||||
28
Template-02/public/sitemap.xml
Normal file
28
Template-02/public/sitemap.xml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://helenafontes.com.br/</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://helenafontes.com.br/portfolio</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://helenafontes.com.br/assessoria</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://helenafontes.com.br/insights</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://helenafontes.com.br/contato</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
29
Template-02/replace.ts
Normal file
29
Template-02/replace.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
function replaceStone(filePath: string) {
|
||||
let content = fs.readFileSync(filePath, 'utf8');
|
||||
let original = content;
|
||||
|
||||
content = content.replace(/zinc-/g, "stone-");
|
||||
|
||||
if (content !== original) {
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
console.log('Updated stone in ' + filePath);
|
||||
}
|
||||
}
|
||||
|
||||
function processDirectory(dir: string) {
|
||||
const files = fs.readdirSync(dir);
|
||||
for (const file of files) {
|
||||
const fullPath = path.join(dir, file);
|
||||
const stat = fs.statSync(fullPath);
|
||||
if (stat.isDirectory()) {
|
||||
processDirectory(fullPath);
|
||||
} else if (fullPath.endsWith('.tsx') || fullPath.endsWith('.ts')) {
|
||||
replaceStone(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processDirectory('./src');
|
||||
783
Template-02/src/App.tsx
Normal file
783
Template-02/src/App.tsx
Normal file
|
|
@ -0,0 +1,783 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "motion/react";
|
||||
import {
|
||||
Menu,
|
||||
X,
|
||||
ArrowRight,
|
||||
Instagram,
|
||||
Linkedin,
|
||||
MapPin,
|
||||
ArrowLeft,
|
||||
MessageCircle,
|
||||
UserCheck,
|
||||
Briefcase,
|
||||
ShieldCheck,
|
||||
Search,
|
||||
} from "lucide-react";
|
||||
import { Routes, Route, Link, useParams, useLocation } from "react-router-dom";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { articles, ArticleType, Article } from "./data/articles";
|
||||
import { PortfolioPage } from "./pages/PortfolioPage";
|
||||
import { AssessoriaPage } from "./pages/AssessoriaPage";
|
||||
import { InsightsPage } from "./pages/InsightsPage";
|
||||
import { ContatoPage } from "./pages/ContatoPage";
|
||||
import { NotFoundPage } from "./pages/NotFoundPage";
|
||||
import { Analytics } from "./components/Analytics";
|
||||
|
||||
export default function App() {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 50);
|
||||
};
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
setIsMobileMenuOpen(false);
|
||||
setIsSearchOpen(false);
|
||||
setSearchQuery("");
|
||||
}, [location.pathname]);
|
||||
|
||||
// Filter articles for the homepage feeds
|
||||
const propertiesAsArticles = articles.filter((a) => a.type === "property");
|
||||
const marketInsights = articles.filter((a) => a.type === "insight");
|
||||
|
||||
const searchResults = articles.filter(a =>
|
||||
a.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
a.excerpt.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
(a.details?.location && a.details.location.toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
);
|
||||
|
||||
const isArticleRoute = location.pathname.startsWith('/artigo/');
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#FCFAFA] text-brand-dark selection:bg-brand-gold selection:text-white font-sans overflow-x-hidden">
|
||||
<Analytics />
|
||||
<Helmet>
|
||||
<title>Helena Fontes | Corretora de Imóveis Premium</title>
|
||||
<meta name="description" content="Helena Fontes é uma corretora de imóveis especializada no mercado premium e de luxo. Acesso exclusivo a propriedades off-market em São Paulo." />
|
||||
<meta name="keywords" content="corretora de luxo, imóveis premium, são paulo, off-market, mansões, apartamentos alto padrão" />
|
||||
<meta property="og:title" content="Helena Fontes | Corretora de Imóveis Premium" />
|
||||
<meta property="og:description" content="Helena Fontes é uma corretora de imóveis especializada no mercado premium e de luxo. Acesso exclusivo a propriedades off-market em São Paulo." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="Helena Fontes | Corretora de Imóveis Premium" />
|
||||
<meta name="twitter:description" content="Helena Fontes é uma corretora de imóveis especializada no mercado premium e de luxo em São Paulo." />
|
||||
<link rel="canonical" href="https://helenafontes.com.br" />
|
||||
</Helmet>
|
||||
{/* HEADER */}
|
||||
<nav
|
||||
className={`fixed w-full z-50 transition-all duration-700 ${
|
||||
isScrolled || isArticleRoute
|
||||
? "bg-[#FCFAFA]/95 backdrop-blur-md py-4 shadow-sm"
|
||||
: "bg-transparent py-8"
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between">
|
||||
{/* Left side: Menu (Mobile) or some links (Desktop) */}
|
||||
<div className="flex-1 flex items-center justify-start">
|
||||
<button
|
||||
className={`md:hidden ${isScrolled || isArticleRoute ? 'text-brand-dark' : 'text-brand-dark'}`}
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
>
|
||||
{isMobileMenuOpen ? <X size={24} strokeWidth={1} /> : <Menu size={24} strokeWidth={1} />}
|
||||
</button>
|
||||
<div className="hidden md:flex items-center gap-8 text-[10px] uppercase tracking-[0.2em] font-semibold text-stone-500">
|
||||
<Link to="/portfolio" className="hover:text-brand-gold transition-colors">Portfólio</Link>
|
||||
<Link to="/assessoria" className="hover:text-brand-gold transition-colors">Assessoria</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Center: Logo */}
|
||||
<div className="flex-shrink-0 text-center flex flex-col items-center">
|
||||
<Link to="/">
|
||||
<span className={`text-2xl md:text-3xl font-serif tracking-widest leading-none ${isScrolled || isArticleRoute ? 'text-brand-dark' : 'text-brand-dark'}`}>
|
||||
HELENA FONTES
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Right side: Search & other links */}
|
||||
<div className="flex-1 flex items-center justify-end gap-6 md:gap-8">
|
||||
<div className="hidden md:flex items-center gap-8 text-[10px] uppercase tracking-[0.2em] font-semibold text-stone-500">
|
||||
<Link to="/insights" className="hover:text-brand-gold transition-colors">Insights</Link>
|
||||
<Link to="/contato" className="hover:text-brand-gold transition-colors">Contato</Link>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setIsSearchOpen(true)}
|
||||
className={`hover:text-brand-gold transition-colors flex items-center ${isScrolled || isArticleRoute ? 'text-brand-dark' : 'text-brand-dark'}`}
|
||||
aria-label="Buscar"
|
||||
>
|
||||
<Search size={20} strokeWidth={1.5} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile Dropdown */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="absolute top-full left-0 w-full bg-[#FCFAFA] overflow-hidden md:hidden shadow-2xl shadow-black/5 border-t border-stone-100"
|
||||
>
|
||||
<div className="flex flex-col px-8 py-10 gap-8 text-xs uppercase tracking-[0.2em] font-medium text-stone-600 text-center">
|
||||
<Link to="/portfolio" onClick={() => setIsMobileMenuOpen(false)} className="hover:text-brand-gold">Portfólio</Link>
|
||||
<div className="w-12 h-px bg-stone-200 mx-auto"></div>
|
||||
<Link to="/assessoria" onClick={() => setIsMobileMenuOpen(false)} className="hover:text-brand-gold">A Assessoria</Link>
|
||||
<div className="w-12 h-px bg-stone-200 mx-auto"></div>
|
||||
<Link to="/insights" onClick={() => setIsMobileMenuOpen(false)} className="hover:text-brand-gold">Insights</Link>
|
||||
<div className="w-12 h-px bg-stone-200 mx-auto"></div>
|
||||
<Link to="/contato" onClick={() => setIsMobileMenuOpen(false)} className="hover:text-brand-gold">Contato</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</nav>
|
||||
|
||||
{/* SEARCH MODAL */}
|
||||
<AnimatePresence>
|
||||
{isSearchOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-0 z-[100] bg-[#FCFAFA]/95 backdrop-blur-xl flex flex-col pt-32 px-6 lg:px-8"
|
||||
>
|
||||
<button
|
||||
onClick={() => setIsSearchOpen(false)}
|
||||
className="absolute top-8 right-6 lg:right-8 text-stone-500 hover:text-brand-dark transition-colors p-2"
|
||||
aria-label="Agendar"
|
||||
>
|
||||
<X size={32} strokeWidth={1} />
|
||||
</button>
|
||||
|
||||
<div className="max-w-4xl w-full mx-auto flex flex-col h-full">
|
||||
<div className="relative mb-12">
|
||||
<input
|
||||
autoFocus
|
||||
type="text"
|
||||
placeholder="Busque por bairro, exclusividade ou insights..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full bg-transparent border-b-2 border-stone-300 text-3xl md:text-5xl font-serif text-brand-dark pb-4 focus:outline-none focus:border-brand-gold transition-colors placeholder:text-stone-300"
|
||||
/>
|
||||
<Search className="absolute right-0 bottom-6 text-stone-300" size={32} />
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto pb-32">
|
||||
{searchQuery.length > 2 ? (
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-xs uppercase tracking-widest text-stone-400 font-bold mb-8">Resultados ({searchResults.length})</h3>
|
||||
{searchResults.length > 0 ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{searchResults.map((result) => (
|
||||
<Link
|
||||
key={result.id}
|
||||
to={`/artigo/${result.id}`}
|
||||
onClick={() => setIsSearchOpen(false)}
|
||||
className="group block border border-stone-200 bg-white p-6 hover:border-brand-gold transition-colors"
|
||||
>
|
||||
<div className="text-xs font-bold text-brand-gold uppercase tracking-widest mb-3">
|
||||
{result.type === 'property' ? 'Portfólio' : 'Insight'}
|
||||
</div>
|
||||
<h4 className="font-serif text-xl text-brand-dark mb-2 group-hover:text-brand-gold transition-colors">{result.title}</h4>
|
||||
<p className="text-sm font-light text-stone-600 line-clamp-2">{result.excerpt}</p>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-stone-500 font-light text-lg">Nenhum resultado encontrado para "{searchQuery}". Tente outros termos.</p>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-stone-400 font-light text-lg">
|
||||
Digite pelo menos 3 caracteres para iniciar a busca.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/portfolio" element={<PortfolioPage propertiesAsArticles={propertiesAsArticles} />} />
|
||||
<Route path="/assessoria" element={<AssessoriaPage />} />
|
||||
<Route path="/insights" element={<InsightsPage marketInsights={marketInsights} />} />
|
||||
<Route path="/contato" element={<ContatoPage />} />
|
||||
<Route path="/artigo/:id" element={<ArticleRoute />} />
|
||||
<Route path="*" element={<NotFoundPage />} />
|
||||
</Routes>
|
||||
|
||||
{/* FOOTER */}
|
||||
<footer className="bg-white py-20 text-brand-dark border-t border-stone-100">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="flex flex-col items-center mb-12">
|
||||
<span className="font-serif text-2xl text-brand-dark italic mb-8">Helena Fontes</span>
|
||||
<div className="flex gap-8 mb-8 text-stone-400">
|
||||
<a href="https://instagram.com" target="_blank" rel="noopener noreferrer" className="hover:text-brand-gold transition-colors" aria-label="Instagram">
|
||||
<Instagram size={18} strokeWidth={1.5} />
|
||||
</a>
|
||||
<a href="https://linkedin.com" target="_blank" rel="noopener noreferrer" className="hover:text-brand-gold transition-colors" aria-label="LinkedIn">
|
||||
<Linkedin size={18} strokeWidth={1.5} />
|
||||
</a>
|
||||
</div>
|
||||
<div className="w-px h-12 bg-brand-gold/30"></div>
|
||||
</div>
|
||||
<div className="flex flex-wrap justify-center gap-6 md:gap-12 text-[10px] uppercase tracking-[0.3em] font-bold text-stone-400 mb-12">
|
||||
<Link to="/portfolio" className="hover:text-brand-gold transition-colors">Portfólio</Link>
|
||||
<Link to="/assessoria" className="hover:text-brand-gold transition-colors">A Assessoria</Link>
|
||||
<Link to="/insights" className="hover:text-brand-gold transition-colors">Insights</Link>
|
||||
<Link to="/contato" className="hover:text-brand-gold transition-colors">Contato</Link>
|
||||
</div>
|
||||
<p className="text-center text-[10px] uppercase tracking-[0.2em] text-stone-400 leading-relaxed font-semibold">
|
||||
© {new Date().getFullYear()} HELENA FONTES • CRECI 123456-F. <br className="md:hidden" />
|
||||
<span className="hidden md:inline"> | </span>CURADORIA IMOBILIÁRIA EXCLUSIVA
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
{/* Floating WhatsApp Button */}
|
||||
<AnimatePresence>
|
||||
{(isScrolled || isArticleRoute) && (
|
||||
<motion.a
|
||||
initial={{ opacity: 0, scale: 0.8, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.8, y: 20 }}
|
||||
href="https://wa.me/5511999999999"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="fixed bottom-6 right-6 z-50 bg-[#25D366] text-white p-4 rounded-full shadow-[0_4px_14px_rgba(37,211,102,0.4)] hover:bg-[#22bf5b] transition-colors hover:scale-110 active:scale-95 flex items-center justify-center"
|
||||
aria-label="Falar no WhatsApp"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
width="28"
|
||||
height="28"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a12.8 12.8 0 0 0-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413Z" />
|
||||
</svg>
|
||||
</motion.a>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function HomePage() {
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (location.hash) {
|
||||
const element = document.getElementById(location.hash.substring(1));
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Helena Fontes | Início</title>
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "RealEstateAgent",
|
||||
"name": "Helena Fontes",
|
||||
"image": "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?q=80&w=1976&auto=format&fit=crop",
|
||||
"@id": "https://helenafontes.com.br",
|
||||
"url": "https://helenafontes.com.br",
|
||||
"telephone": "+5511999999999",
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"streetAddress": "Av. Brigadeiro Faria Lima, 3477",
|
||||
"addressLocality": "São Paulo",
|
||||
"addressRegion": "SP",
|
||||
"postalCode": "04538-133",
|
||||
"addressCountry": "BR"
|
||||
},
|
||||
"priceRange": "$$$$"
|
||||
})}
|
||||
</script>
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Como funciona a assessoria para compra de imóveis?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Busca ativa por todo o mercado. Filtro o ruído, faço as inspeções prévias e entrego relatórios analíticos antes da sua visita."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "O que são imóveis off-market?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "São propriedades exclusivas que não são anunciadas publicamente, oferecendo maior privacidade e oportunidades únicas para compradores qualificados."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Qual é a vantagem de contratar uma corretora exclusiva para a venda do meu imóvel?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "A exclusividade garante um plano de marketing focado, filtro rigoroso de potenciais compradores e proteção contra a desvalorização do ativo por sobreposição de anúncios no mercado."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Você atua apenas na venda de imóveis prontos ou também em lançamentos?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Atuo em ambos. Para lançamentos, ofereço antecipação de informações e acesso privilegiado a unidades específicas antes da abertura para o mercado em geral."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Como é garantido o sigilo durante a negociação?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Trabalho com Acordos de Confidencialidade (NDA) quando necessário e filtro estritamente as informações compartilhadas, protegendo a identidade e o patrimônio de ambas as partes."
|
||||
}
|
||||
}
|
||||
]
|
||||
})}
|
||||
</script>
|
||||
</Helmet>
|
||||
<section className="relative pt-40 pb-20 md:pt-48 md:pb-32 px-6 overflow-hidden bg-[#FCFAFA]">
|
||||
<div className="max-w-7xl mx-auto w-full flex flex-col-reverse md:flex-row gap-16 md:gap-20 items-center">
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 1, delay: 0.2 }}
|
||||
className="w-full md:w-1/2 flex flex-col text-center md:text-left z-10"
|
||||
>
|
||||
<span className="text-brand-gold text-[10px] md:text-xs uppercase tracking-[0.3em] font-bold block mb-4 md:mb-6">
|
||||
Portfólio Pessoal
|
||||
</span>
|
||||
<h1 className="text-5xl md:text-6xl lg:text-7xl font-serif text-brand-dark leading-[1.1] tracking-tight mb-8">
|
||||
Sua morada, <br className="hidden lg:block"/>
|
||||
<span className="italic font-light">cuidada em detalhes.</span>
|
||||
</h1>
|
||||
<p className="text-stone-500 font-light text-lg max-w-md mx-auto md:mx-0 mb-10 leading-relaxed">
|
||||
Bem-vinda ao meu espaço. Aqui compartilho minha curadoria pessoal das propriedades mais acolhedoras e exclusivas de São Paulo.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row items-center gap-6 justify-center md:justify-start">
|
||||
<Link
|
||||
to="/portfolio"
|
||||
className="inline-flex items-center justify-center min-w-[200px] gap-4 bg-brand-dark hover:bg-brand-gold text-white px-8 py-4 text-[10px] font-bold uppercase tracking-[0.2em] transition-colors w-fit"
|
||||
>
|
||||
Conhecer Portfólio
|
||||
</Link>
|
||||
<Link
|
||||
to="/assessoria"
|
||||
className="inline-flex items-center justify-center min-w-[200px] gap-2 text-brand-dark hover:text-brand-gold text-[10px] font-bold uppercase tracking-[0.2em] transition-colors w-fit border border-brand-dark hover:border-brand-gold px-8 py-4"
|
||||
>
|
||||
A Assessoria
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 1.2, delay: 0.3 }}
|
||||
className="w-full md:w-1/2 relative flex justify-center md:justify-end"
|
||||
>
|
||||
<div className="relative w-full max-w-sm lg:max-w-md">
|
||||
<div className="aspect-[4/5] md:aspect-[3/4] object-cover overflow-hidden rounded-t-full rounded-b-sm bg-stone-100 shadow-xl shadow-stone-200/50">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?q=80&w=2070&auto=format&fit=crop"
|
||||
alt="Interior delicado"
|
||||
className="w-full h-full object-cover object-center"
|
||||
/>
|
||||
</div>
|
||||
{/* Delicate accents */}
|
||||
<div className="absolute -top-6 -right-6 w-32 h-32 border border-brand-gold/30 rounded-full -z-10"></div>
|
||||
<div className="absolute -bottom-8 -left-8 w-40 h-40 bg-[#f4ece8] rounded-full blur-2xl -z-10"></div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* APRESENTAÇÃO / SOBRE SECTION */}
|
||||
<section className="py-24 md:py-32 bg-white relative overflow-hidden">
|
||||
<div className="absolute top-0 right-0 w-1/3 h-full bg-[#FCFAFA] -z-10 mix-blend-multiply"></div>
|
||||
<div className="max-w-6xl mx-auto px-6 lg:px-8">
|
||||
<div className="flex flex-col md:flex-row gap-16 lg:gap-24 items-center">
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 1 }}
|
||||
className="w-full md:w-5/12 relative order-2 md:order-1"
|
||||
>
|
||||
<div className="aspect-square rounded-full overflow-hidden border-8 border-white shadow-2xl shadow-stone-200 max-w-sm mx-auto">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?q=80&w=1976&auto=format&fit=crop"
|
||||
alt="Helena Fontes - Retrato"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 1, delay: 0.2 }}
|
||||
className="w-full md:w-7/12 order-1 md:order-2 text-center md:text-left"
|
||||
>
|
||||
<h2 className="text-3xl md:text-4xl lg:text-5xl font-serif text-brand-dark leading-tight mb-8">
|
||||
Um olhar refinado para <br className="hidden md:block"/><span className="italic text-brand-gold/80">o seu próximo lar.</span>
|
||||
</h2>
|
||||
<div className="space-y-6 text-stone-500 font-light text-lg">
|
||||
<p>
|
||||
Olá, sou Helena. Ao longo dos últimos anos, venho me dedicando a entender o que realmente transforma uma propriedade em um refúgio. Mais do que metragens e valores, busco a essência de cada endereço.
|
||||
</p>
|
||||
<p>
|
||||
Trabalho de forma intimista, com um portfólio reduzido e acesso a propriedades exclusivas. Meu papel é guiar você em uma jornada tranquila, transparente e absolutamente inspiradora até a sua nova casa.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-10 font-serif italic text-2xl text-brand-dark opacity-80">
|
||||
Helena Fontes
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* DIFERENCIAIS SECTION (Redesigned) */}
|
||||
<section className="py-24 md:py-32 bg-[#FCFAFA] relative overflow-hidden">
|
||||
<div className="absolute top-1/2 left-0 -translate-y-1/2 w-64 h-64 bg-stone-100 rounded-full blur-3xl -z-10"></div>
|
||||
<div className="max-w-5xl mx-auto px-6 lg:px-8">
|
||||
<div className="text-center mb-16 md:mb-24">
|
||||
<h2 className="text-3xl md:text-5xl font-serif text-brand-dark leading-tight">
|
||||
Elevando o <span className="italic font-light">cuidado,</span> <br/>
|
||||
<span className="text-stone-400">em cada detalhe.</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="space-y-16 lg:space-y-24">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="flex flex-col md:flex-row gap-8 md:gap-16 items-center"
|
||||
>
|
||||
<div className="text-brand-gold font-serif italic text-6xl md:text-8xl opacity-30 select-none">I.</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-serif text-brand-dark mb-4">
|
||||
Discrição e Sutileza
|
||||
</h3>
|
||||
<p className="text-stone-500 font-light leading-relaxed max-w-xl">
|
||||
Cada cliente recebe atenção exclusiva. Compreender profundamente suas necessidades, seus desejos e seu estilo de vida, conduzindo cada visita com absoluta discrição e leveza.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
className="flex flex-col md:flex-row gap-8 md:gap-16 items-center md:pl-20"
|
||||
>
|
||||
<div className="text-brand-gold font-serif italic text-6xl md:text-8xl opacity-30 select-none">II.</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-serif text-brand-dark mb-4">
|
||||
Curadoria Afetiva
|
||||
</h3>
|
||||
<p className="text-stone-500 font-light leading-relaxed max-w-xl">
|
||||
Não mostro dezenas de casas; apresento lares que ressoam com a sua personalidade. Uma seleção criteriosa focada na qualidade de vida e no bom gosto, não no volume.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
className="flex flex-col md:flex-row gap-8 md:gap-16 items-center md:pl-40"
|
||||
>
|
||||
<div className="text-brand-gold font-serif italic text-6xl md:text-8xl opacity-30 select-none">III.</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-serif text-brand-dark mb-4">
|
||||
Rede Off-Market
|
||||
</h3>
|
||||
<p className="text-stone-500 font-light leading-relaxed max-w-xl">
|
||||
Acesso privilegiado a propriedades exclusivas não anunciadas publicamente. Casas e coberturas preservadas para quem valoriza a verdadeira raridade antes que cheguem ao mercado.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* TESTIMONIALS SECTION (SOCIAL PROOF) */}
|
||||
<section className="py-24 lg:py-32 bg-white flex flex-col items-center text-center px-6">
|
||||
<div className="max-w-4xl mx-auto w-full">
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-stone-400 font-bold block mb-12">
|
||||
Reconhecimento
|
||||
</span>
|
||||
<div className="relative">
|
||||
<div className="text-brand-gold/10 text-[120px] font-serif absolute -top-16 left-1/2 -translate-x-1/2 italic leading-none pointer-events-none select-none">"</div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="relative z-10"
|
||||
>
|
||||
<h2 className="text-2xl md:text-4xl lg:text-5xl font-serif text-brand-dark leading-snug mb-10 text-stone-600 font-light relative z-10 p-8 md:p-12 border border-stone-100 bg-white shadow-2xl shadow-stone-100 rounded-sm">
|
||||
"A sensibilidade da Helena foi fundamental para encontrarmos nosso novo lar. Ela não apenas nos mostrou imóveis, mas ajudou a vislumbrar o estilo de vida que sonhávamos, com uma paciência e discrição raras no mercado."
|
||||
<div className="mt-8 font-serif font-medium text-brand-dark tracking-wide text-lg">
|
||||
<span className="block text-brand-gold text-xs uppercase tracking-widest font-bold mb-2">Cliente Compradora</span>
|
||||
S.M. — Itaim Bibi
|
||||
</div>
|
||||
</h2>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
<div className="mt-12">
|
||||
<Link to="/assessoria" className="text-[10px] uppercase font-bold tracking-[0.2em] text-brand-dark border-b border-brand-dark hover:border-brand-gold hover:text-brand-gold transition-colors pb-1">
|
||||
Conhecer a Metodologia
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ SECTION */}
|
||||
<section className="py-24 lg:py-32 bg-[#FCFAFA]">
|
||||
<div className="max-w-5xl mx-auto px-6 lg:px-8">
|
||||
<div className="text-center mb-16 md:mb-24">
|
||||
<h2 className="text-3xl md:text-5xl font-serif text-brand-dark leading-tight">
|
||||
Esclarecimentos <span className="italic text-stone-400">Freqüentes</span>
|
||||
</h2>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{[
|
||||
{
|
||||
q: "Como funciona a assessoria para compra de imóveis?",
|
||||
a: "Busca ativa por todo o mercado. Filtro o ruído, faço as inspeções prévias e entrego relatórios analíticos antes da sua visita."
|
||||
},
|
||||
{
|
||||
q: "O que são imóveis off-market?",
|
||||
a: "São propriedades exclusivas que não são anunciadas publicamente, oferecendo maior privacidade e oportunidades únicas para compradores qualificados."
|
||||
},
|
||||
{
|
||||
q: "Qual a vantagem da exclusividade de venda?",
|
||||
a: "A exclusividade garante um plano de marketing focado, filtro rigoroso e proteção contra a desvalorização do ativo por sobreposição de anúncios no mercado."
|
||||
},
|
||||
{
|
||||
q: "Como é garantido o sigilo da negociação?",
|
||||
a: "Trabalho com Acordos de Confidencialidade (NDA) quando necessário e filtro estritamente as informações compartilhadas."
|
||||
}
|
||||
].map((faq, idx) => (
|
||||
<div key={idx} className="group border-b border-stone-200 py-8 px-4 hover:bg-white transition-colors cursor-default">
|
||||
<div className="flex flex-col md:flex-row md:items-baseline gap-4 md:gap-12">
|
||||
<h3 className="font-serif text-xl tracking-wide text-brand-dark md:w-5/12 shrink-0 group-hover:text-brand-gold transition-colors">
|
||||
{faq.q}
|
||||
</h3>
|
||||
<p className="text-stone-500 font-light md:w-7/12 leading-relaxed">
|
||||
{faq.a}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function ArticleRoute() {
|
||||
const { id } = useParams();
|
||||
const article = articles.find((a) => a.id === id);
|
||||
|
||||
if (!article) {
|
||||
return (
|
||||
<div className="min-h-screen pt-40 pb-24 text-center">
|
||||
<h1 className="text-4xl font-serif mb-4">Artigo não encontrado</h1>
|
||||
<Link to="/" className="text-brand-gold hover:underline">Voltar para o início</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <ArticleView article={article} />;
|
||||
}
|
||||
|
||||
function ArticleView({ article }: { article: Article }) {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{article.title} | Helena Fontes</title>
|
||||
<meta name="description" content={article.excerpt} />
|
||||
{article.type === "property" ? (
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "RealEstateListing",
|
||||
"name": article.title,
|
||||
"description": article.excerpt,
|
||||
"image": article.coverImage,
|
||||
"offers": {
|
||||
"@type": "Offer",
|
||||
"priceCurrency": "BRL",
|
||||
"price": article.details?.price?.replace(/[^0-9]/g, "") || "0"
|
||||
}
|
||||
})}
|
||||
</script>
|
||||
) : (
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": article.title,
|
||||
"description": article.excerpt,
|
||||
"image": article.coverImage,
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Helena Fontes"
|
||||
},
|
||||
"datePublished": "2024-01-01" // Idealmente seria a data do artigo
|
||||
})}
|
||||
</script>
|
||||
)}
|
||||
</Helmet>
|
||||
<motion.article
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="pt-32 pb-24"
|
||||
>
|
||||
<div className="max-w-4xl mx-auto px-6 lg:px-8">
|
||||
<Link
|
||||
to="/"
|
||||
className="inline-flex items-center gap-2 text-xs uppercase tracking-widest font-bold text-stone-500 hover:text-brand-dark transition-colors mb-12"
|
||||
>
|
||||
<ArrowLeft size={16} />
|
||||
Voltar
|
||||
</Link>
|
||||
|
||||
<div className="flex items-center gap-4 text-brand-gold text-[10px] font-bold uppercase tracking-[0.3em] mb-8 justify-center md:justify-start">
|
||||
<span>{article.category}</span>
|
||||
<span className="w-4 h-px bg-brand-gold"></span>
|
||||
<span className="text-stone-400">{article.date}</span>
|
||||
</div>
|
||||
|
||||
<h1 className="text-4xl md:text-5xl lg:text-7xl font-serif text-brand-dark leading-[1.1] mb-12 text-center md:text-left">
|
||||
{article.title}
|
||||
</h1>
|
||||
|
||||
<p className="text-xl text-stone-500 font-light leading-relaxed mb-16 max-w-2xl px-6 border-l border-brand-gold/50 mx-auto md:mx-0">
|
||||
{article.excerpt}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="w-full max-w-6xl mx-auto px-4 lg:px-8 mb-24">
|
||||
<div className="aspect-[4/3] md:aspect-[21/9] bg-stone-100 overflow-hidden relative rounded-t-full md:rounded-bl-[200px] md:rounded-tr-[200px]">
|
||||
<img
|
||||
src={article.coverImage}
|
||||
alt={article.title}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
{article.type === "property" && article.details && (
|
||||
<div className="absolute bottom-6 right-1/2 translate-x-1/2 md:translate-x-0 md:right-12 bg-white/95 backdrop-blur rounded-sm px-8 py-4 shadow-xl text-center md:text-left">
|
||||
<div className="text-[10px] uppercase tracking-[0.3em] text-stone-400 font-bold mb-1">
|
||||
Valor
|
||||
</div>
|
||||
<div className="font-serif text-2xl text-brand-dark">
|
||||
{article.details.price}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="max-w-3xl mx-auto px-6 lg:px-8">
|
||||
<div className="prose prose-zinc prose-lg font-light leading-loose text-stone-700">
|
||||
{article.content}
|
||||
</div>
|
||||
|
||||
<div className="my-24 py-16 px-6 text-center relative max-w-4xl mx-auto">
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-px h-16 bg-brand-gold/30"></div>
|
||||
<blockquote className="text-3xl md:text-4xl font-serif italic text-stone-500 mb-8 mt-8 leading-relaxed font-light">
|
||||
"{article.quote.text}"
|
||||
</blockquote>
|
||||
<cite className="text-[10px] uppercase tracking-[0.3em] font-bold text-brand-gold not-italic">
|
||||
— {article.quote.author}
|
||||
</cite>
|
||||
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-px h-16 bg-brand-gold/30"></div>
|
||||
</div>
|
||||
|
||||
<div className="text-center pt-16 border-t border-stone-200 mt-16">
|
||||
<h3 className="font-serif text-2xl mb-6">
|
||||
Possui interesse nesta propriedade ou assunto?
|
||||
</h3>
|
||||
<a
|
||||
href="https://wa.me/5511999999999"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="inline-flex items-center gap-3 bg-brand-dark hover:bg-brand-gold text-white px-8 py-4 text-xs font-bold uppercase tracking-[0.1em] transition-colors"
|
||||
>
|
||||
Falar Diretamente no WhatsApp
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{article.type === "property" && article.details?.location && (
|
||||
<div className="mt-32 pt-24 border-t border-stone-200">
|
||||
<span className="text-[10px] uppercase tracking-[0.3em] font-bold text-brand-gold block mb-4 text-center">Localização</span>
|
||||
<h3 className="font-serif text-3xl md:text-5xl mb-6 text-brand-dark text-center">
|
||||
Território & Contexto
|
||||
</h3>
|
||||
<p className="text-stone-500 font-light text-center max-w-xl mx-auto mb-16 leading-relaxed">
|
||||
Para assegurar a serenidade e máxima privacidade, indicamos apenas a região aproximada. A localização exata deste imóvel será compartilhada de forma estritamente pessoal, mediante uma qualificação delicada.
|
||||
</p>
|
||||
<div className="w-full h-96 bg-stone-100 overflow-hidden relative rounded-sm shadow-xl shadow-stone-200/50 border border-white">
|
||||
<iframe
|
||||
src={`https://maps.google.com/maps?q=${encodeURIComponent(article.details.location)}&t=m&z=14&output=embed`}
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen={false}
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
title={`Mapa regional para ${article.details.location}`}
|
||||
className="w-full h-full object-cover grayscale opacity-80 hover:grayscale-0 hover:opacity-100 transition-all duration-700"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</motion.article>
|
||||
</>
|
||||
);
|
||||
}
|
||||
104
Template-02/src/components/Analytics.tsx
Normal file
104
Template-02/src/components/Analytics.tsx
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import { useEffect } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
export function Analytics() {
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
// Inject Google Tag Manager
|
||||
const gtmId = import.meta.env.VITE_GTM_ID;
|
||||
if (gtmId) {
|
||||
const script = document.createElement("script");
|
||||
script.innerHTML = `
|
||||
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','${gtmId}');
|
||||
`;
|
||||
document.head.appendChild(script);
|
||||
|
||||
const noscript = document.createElement("noscript");
|
||||
noscript.innerHTML = `<iframe src="https://www.googletagmanager.com/ns.html?id=${gtmId}" height="0" width="0" style="display:none;visibility:hidden"></iframe>`;
|
||||
document.body.insertBefore(noscript, document.body.firstChild);
|
||||
}
|
||||
|
||||
// Inject Google Analytics (if separate from GTM)
|
||||
const gaId = import.meta.env.VITE_GA_MEASUREMENT_ID;
|
||||
if (gaId) {
|
||||
const scriptGa = document.createElement("script");
|
||||
scriptGa.async = true;
|
||||
scriptGa.src = `https://www.googletagmanager.com/gtag/js?id=${gaId}`;
|
||||
document.head.appendChild(scriptGa);
|
||||
|
||||
const scriptInline = document.createElement("script");
|
||||
scriptInline.innerHTML = `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', '${gaId}');
|
||||
`;
|
||||
document.head.appendChild(scriptInline);
|
||||
}
|
||||
|
||||
// Inject Google Ads (if separate from above GA tag)
|
||||
const adsId = import.meta.env.VITE_GOOGLE_ADS_ID;
|
||||
if (adsId && adsId !== gaId) {
|
||||
const scriptAds = document.createElement("script");
|
||||
scriptAds.async = true;
|
||||
scriptAds.src = `https://www.googletagmanager.com/gtag/js?id=${adsId}`;
|
||||
document.head.appendChild(scriptAds);
|
||||
|
||||
const scriptInline = document.createElement("script");
|
||||
scriptInline.innerHTML = `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', '${adsId}');
|
||||
`;
|
||||
document.head.appendChild(scriptInline);
|
||||
}
|
||||
|
||||
// Inject Meta/Facebook Pixel
|
||||
const pixelId = import.meta.env.VITE_FB_PIXEL_ID;
|
||||
if (pixelId) {
|
||||
const script = document.createElement("script");
|
||||
script.innerHTML = `
|
||||
!function(f,b,e,v,n,t,s)
|
||||
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
||||
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
|
||||
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
|
||||
n.queue=[];t=b.createElement(e);t.async=!0;
|
||||
t.src=v;s=b.getElementsByTagName(e)[0];
|
||||
s.parentNode.insertBefore(t,s)}(window, document,'script',
|
||||
'https://connect.facebook.net/en_US/fbevents.js');
|
||||
fbq('init', '${pixelId}');
|
||||
fbq('track', 'PageView');
|
||||
`;
|
||||
document.head.appendChild(script);
|
||||
|
||||
const noscript = document.createElement("noscript");
|
||||
noscript.innerHTML = `<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=${pixelId}&ev=PageView&noscript=1" />`;
|
||||
document.body.appendChild(noscript);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Track page views on route change
|
||||
useEffect(() => {
|
||||
// GA PageView
|
||||
const gaId = import.meta.env.VITE_GA_MEASUREMENT_ID;
|
||||
if (gaId && typeof window !== "undefined" && (window as any).gtag) {
|
||||
(window as any).gtag("config", gaId, {
|
||||
page_path: location.pathname + location.search,
|
||||
});
|
||||
}
|
||||
|
||||
// FB Pixel PageView
|
||||
const pixelId = import.meta.env.VITE_FB_PIXEL_ID;
|
||||
if (pixelId && typeof window !== "undefined" && (window as any).fbq) {
|
||||
(window as any).fbq('track', 'PageView');
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
return null;
|
||||
}
|
||||
652
Template-02/src/data/articles.tsx
Normal file
652
Template-02/src/data/articles.tsx
Normal file
|
|
@ -0,0 +1,652 @@
|
|||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export type ArticleType = "property" | "insight";
|
||||
|
||||
export interface Article {
|
||||
id: string;
|
||||
type: ArticleType;
|
||||
category: string;
|
||||
title: string;
|
||||
excerpt: string;
|
||||
coverImage: string;
|
||||
date: string;
|
||||
content: React.ReactNode;
|
||||
quote: {
|
||||
text: string;
|
||||
author: string;
|
||||
};
|
||||
details?: {
|
||||
price?: string;
|
||||
specs?: string;
|
||||
status?: string;
|
||||
location?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const articles: Article[] = [
|
||||
{
|
||||
id: "residencial-jardim-europa-01",
|
||||
type: "property",
|
||||
category: "Jardim Europa, São Paulo",
|
||||
title: "Residência de Autor: Modernismo e Privacidade Absoluta",
|
||||
excerpt:
|
||||
"Uma análise detalhada desta propriedade singular com 850m² de área construída, integrando living e um jardim projetado por Burle Marx.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?q=80&w=2075&auto=format&fit=crop",
|
||||
date: "Maio 2026",
|
||||
quote: {
|
||||
text: "A arquitetura não é sobre a construção de paredes, mas sobre a criação de atmosferas.",
|
||||
author: "Peter Zumthor",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 18.500.000",
|
||||
specs: "850m² • 4 Suítes • 6 Vagas",
|
||||
status: "Disponível para Visitação",
|
||||
location: "Jardim Europa, São Paulo",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Apresento esta excepcional residência localizada no coração do Jardim
|
||||
Europa, um dos bairros mais tradicionais e valorizados de São Paulo.
|
||||
Tive o privilégio de acompanhar a evolução desta propriedade ao longo
|
||||
dos anos, e seu estado de conservação e design permanecem
|
||||
irretocáveis.
|
||||
</p>
|
||||
<h3>O Espaço e a Luz</h3>
|
||||
<p>
|
||||
A planta foi concebida para que a luz natural permeie todos os
|
||||
ambientes durante o dia. Painéis de vidro piso-teto criam uma
|
||||
transição fluida entre o interior e o monumental jardim, que abriga
|
||||
espécies nativas e espelhos d'água.
|
||||
</p>
|
||||
<p>
|
||||
No piso superior, a suíte master atua como um refúgio particular,
|
||||
contando com dois banheiros independentes, um amplo closet e uma
|
||||
varanda voltada para o verde. Caso esteja em busca de outras
|
||||
propriedades na região, você pode conferir nossa{" "}
|
||||
<Link to="/artigo/valorizacao-jardim-europa">
|
||||
análise de valorização do Jardim Europa
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "cobertura-itaim-bibi",
|
||||
type: "property",
|
||||
category: "Itaim Bibi, São Paulo",
|
||||
title: "A Perspectiva 360º: Cobertura Duplex no Centro Financeiro",
|
||||
excerpt:
|
||||
"Oportunidade raríssima no coração do Itaim. Uma cobertura reformada em 2024, com espaço gourmet completo voltado para o skyline da cidade.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1600607688969-a5bfcd64bd40?q=80&w=2053&auto=format&fit=crop",
|
||||
date: "Abril 2026",
|
||||
quote: {
|
||||
text: "Viver no topo é ter a cidade como seu quadro em constante mudança.",
|
||||
author: "Helena Fontes",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 12.800.000",
|
||||
specs: "420m² • 3 Suítes • 4 Vagas",
|
||||
status: "Exclusividade",
|
||||
location: "Itaim Bibi",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
O Itaim Bibi se consolidou como o epicentro financeiro e de lifestyle
|
||||
da América Latina. Ter uma cobertura duplex nesta região é um
|
||||
privilégio destinado a poucos. Este imóvel, em particular, passou por
|
||||
um retrofit completo estrutural em 2024, assinado por um renomado
|
||||
escritório de arquitetura brasileiro.
|
||||
</p>
|
||||
<h3>Design e Funcionalidade</h3>
|
||||
<p>
|
||||
Os acabamentos incluem mármore Travertino Navona e marcenaria Ornare
|
||||
em todos os ambientes. O destaque definitivo é a área social no
|
||||
segundo pavimento, equipada com piscina de borda infinita aquecida e
|
||||
espaço gourmet, perfeito para recepções íntimas com vista para o
|
||||
parque Ibirapuera.
|
||||
</p>
|
||||
<p>
|
||||
Leia mais sobre o{" "}
|
||||
<Link to="/artigo/novo-luxo-sp">novo conceito de luxo vertical</Link>.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "fazenda-boa-vista",
|
||||
type: "property",
|
||||
category: "Porto Feliz, São Paulo",
|
||||
title: "Refúgio de Fim de Semana com Arquitetura Vernacular",
|
||||
excerpt:
|
||||
"Nesta casa de campo a uma hora de São Paulo, os limites entre o interior e o exterior deixam de existir, cercados por mata nativa e lagos exuberantes.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1613977257363-707ba9348227?q=80&w=2070&auto=format&fit=crop",
|
||||
date: "Março 2026",
|
||||
quote: {
|
||||
text: "O luxo contemporâneo é o espaço, o silêncio e o tempo.",
|
||||
author: "Axel Vervoordt",
|
||||
},
|
||||
details: {
|
||||
price: "Consulte o Valor",
|
||||
specs: "1.200m² • 6 Suítes • 8 Vagas",
|
||||
status: "Off-Market",
|
||||
location: "Fazenda Boa Vista",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Uma imersão completa na natureza sem abrir mão de nenhuma conveniência
|
||||
urbana. Esta propriedade em um dos condomínios mais exclusivos do país
|
||||
foi idealizada para ser um santuário familiar.
|
||||
</p>
|
||||
<h3>Sustentabilidade e Conforto</h3>
|
||||
<p>
|
||||
Com painéis solares, captação de água da chuva e automação residencial
|
||||
nível 4, a casa opera com altíssima eficiência. O layout privilegia
|
||||
áreas de convivência generosas, com um deck expansivo que se projeta
|
||||
em direção à paisagem. Uma verdadeira obra de arte habitável.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "tendencias-arquitetura-2026",
|
||||
type: "insight",
|
||||
category: "Tendências",
|
||||
title: "Tendências de Arquitetura e Interior para 2026",
|
||||
excerpt:
|
||||
"A fusão entre tecnologia invisível, materiais orgânicos e a fluidez dos layouts dita as regras das novas residências de luxo.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1618221195710-dd6b41faaea6?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "18 Maio, 2026",
|
||||
quote: {
|
||||
text: "Onde o design encontra a tecnologia, nasce o conforto invisível.",
|
||||
author: "Design Studio",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Este ano consolidou uma mudança silenciosa nas exigências do mercado
|
||||
premium: a tecnologia não deve mais ser vista no ambiente, mas deve
|
||||
operar tudo nos bastidores.
|
||||
</p>
|
||||
<h3>Acabamentos Orgânicos Naturais</h3>
|
||||
<p>
|
||||
Observamos a valorização de imperfeições naturais nas pedras e
|
||||
madeiras de demolição, trazendo calor e exclusividade a ambientes que
|
||||
há pouco tempo eram pautados pela frieza modernista do vidro e
|
||||
cimento.
|
||||
</p>
|
||||
<p>
|
||||
Visite nossa{" "}
|
||||
<Link to="/artigo/residencial-jardim-europa-01">
|
||||
residência no Jardim Europa
|
||||
</Link>{" "}
|
||||
para ver a aplicação prática deste conceito de design.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "mercado-luxo-sp",
|
||||
type: "insight",
|
||||
category: "Mercado Financeiro",
|
||||
title: "Por que São Paulo atrai investidores globais?",
|
||||
excerpt:
|
||||
"Dados exclusivos de valorização indicam que a capital paulista se mantém resistente às oscilações internacionais.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1430285561322-780c604615ce?q=80&w=2070&auto=format&fit=crop",
|
||||
date: "12 Maio, 2026",
|
||||
quote: {
|
||||
text: "O mercado imobiliário paulistano premium é blindado pelas dinâmicas de escassez e exclusividade.",
|
||||
author: "Financial Times",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
De forma constante, o metro quadrado das coberturas de São Paulo em
|
||||
regiões prime (Itaim, Vila Nova Conceição) superou a inflação nos
|
||||
últimos dez anos.
|
||||
</p>
|
||||
<h3>Safe Haven</h3>
|
||||
<p>
|
||||
Para fundos e family offices, estacionar capital em imóveis icônicos
|
||||
da cidade provou ser tanto um mecanismo de proteção quanto um
|
||||
propulsor de ganhos através da hiper-valorização e retrofit.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "guia-aquisicao-jardim-europa",
|
||||
type: "insight",
|
||||
category: "Investimentos",
|
||||
title: "A valorização contínua e as oportunidades no Jardim Europa",
|
||||
excerpt:
|
||||
"Como as restrições construtivas garantem o valor do bairro, e por que a paciência é a melhor estratégia de compra.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1518507727145-cb3e7f01de55?q=80&w=2070&auto=format&fit=crop",
|
||||
date: "05 Maio, 2026",
|
||||
quote: {
|
||||
text: "A ausência de verticalização é o maior luxo contemporâneo de São Paulo.",
|
||||
author: "Instituto Urbano",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Diferente de NY ou Londres, as áreas exclusivas de casas em São Paulo
|
||||
não podem se adensar. O Jardim Europa é tombado, protegendo seus
|
||||
moradores dos prédios altos. Mas o que isso significa para o
|
||||
patrimônio?
|
||||
</p>
|
||||
<h3>Escassez de Solo e Curva de Apreciação</h3>
|
||||
<p>
|
||||
Na prática, quem possui um terreno na região não tem novos
|
||||
competidores. Recomendamos sempre uma análise minuciosa de diligência
|
||||
(<Link to="/artigo/guia-aquisicao-jardim-europa">leia o guia de aquisição</Link>) antes
|
||||
de assinar qualquer compromisso, devido à complexidade da
|
||||
regularização imobiliária das casas antigas.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "penthouse-cidade-jardim",
|
||||
type: "property",
|
||||
category: "Cidade Jardim, São Paulo",
|
||||
title: "Triplex Suspenso com Vista para a Skyline Paulista",
|
||||
excerpt:
|
||||
"Com mais de 1000m², este apartamento evoca a essência de uma mansão suspensa.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "01 Maio, 2026",
|
||||
quote: {
|
||||
text: "A grandiosidade se mede pelo espaço e pela privacidade, a centenas de metros do chão.",
|
||||
author: "Helena Fontes",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 35.000.000",
|
||||
specs: "1050m² • 5 Suítes • 10 Vagas",
|
||||
status: "Exclusividade",
|
||||
location: "Cidade Jardim",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Espaços palacianos. O pé direito duplo do living cria uma sensação de
|
||||
imponência. A suíte master ocupa um andar inteiro. Esta é, de fato,
|
||||
uma joia cobiçada no portfólio.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "guia-aquisicao",
|
||||
type: "insight",
|
||||
category: "Guia Jurídico",
|
||||
title: "Guia de Aquisição: Estruturação jurídica para grandes propriedades",
|
||||
excerpt:
|
||||
"Os passos essenciais e diligências que aplico antes de apresentar qualquer imóvel aos meus clientes.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1450101499163-c8848c66cb85?q=80&w=2070&auto=format&fit=crop",
|
||||
date: "28 Abril, 2026",
|
||||
quote: {
|
||||
text: "A verdadeira segurança em uma negociação imobiliária reside no que não está visível.",
|
||||
author: "L. Barros, Jurista",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Em transações de alto valor agregado, as certidões cíveis e criminais
|
||||
formam apenas 30% da verdadeira análise de risco.
|
||||
</p>
|
||||
<p>
|
||||
Para ler mais, verifique{" "}
|
||||
<Link to="/artigo/importancia-retrofit">
|
||||
como o retrofit pode impactar esse risco legal
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "novo-luxo-sp",
|
||||
type: "insight",
|
||||
category: "Comportamento",
|
||||
title: "O Novo Luxo: Espaço vs Localização",
|
||||
excerpt:
|
||||
"A mudança de paradigma daqueles que valorizavam endereços cobiçados acima de tudo, em prol do espaço e bem-estar.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1512917774080-9991f1c4c750?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "22 Abril, 2026",
|
||||
quote: {
|
||||
text: "Não compramos mais endereço, compramos qualidade de vida.",
|
||||
author: "Exame",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
A pandemia alterou permanentemente o morar premium. O verde deixou de
|
||||
ser adorno para ser infraestrutura.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "investimento-arte-imoveis",
|
||||
type: "insight",
|
||||
category: "Lifestyle",
|
||||
title: "Investimento em Arte e Alta Decoração de Interiores",
|
||||
excerpt:
|
||||
"Como colecionar arte tem sinergia com o mercado de real estate de altíssimo nível.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1513694203232-719a280e022f?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "15 Abril, 2026",
|
||||
quote: {
|
||||
text: "As paredes são curadoras de nossas almas.",
|
||||
author: "D. Soares",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Casas de proporções generosas demandam peças à altura. Há um
|
||||
intercâmbio constante entre galerias de arte e imobiliárias premium.
|
||||
Em minha{" "}
|
||||
<Link to="/artigo/fazenda-boa-vista">casa na Fazenda Boa Vista</Link>, o
|
||||
projeto incluiu recuos para esculturas grandes.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "condominio-vila-nova",
|
||||
type: "property",
|
||||
category: "Vila Nova Conceição",
|
||||
title: "Apartamento Neoclássico na Praça Pereira Coutinho",
|
||||
excerpt:
|
||||
"Uma joia intocada em um dos logradouros mais valorizados do país.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1497366216548-37526070297c?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "10 Abril, 2026",
|
||||
quote: {
|
||||
text: "Viver de frente para a praça é prolongar a sala de estar.",
|
||||
author: "R. Fontes",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 16.000.000",
|
||||
specs: "300m² • 3 Suítes • 4 Vagas",
|
||||
status: "Disponível",
|
||||
location: "Vila Nova Conceição",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
A exclusividade de atravessar a rua e estar no Ibirapuera. Edifício de
|
||||
assinatura clássica, segurança impecável. Veja as tendências em{" "}
|
||||
<Link to="/artigo/tendencias-arquitetura-2026">arquitetura</Link> para
|
||||
atualizar o apartamento se desejar um retrofit.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "casa-alphaville",
|
||||
type: "property",
|
||||
category: "Alphaville, São Paulo",
|
||||
title: "Mansão Monumental no Tamboré",
|
||||
excerpt:
|
||||
"Segurança e qualidade de vida com proporções que a capital já não oferece.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1628611225249-6c4c3af4a80b?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "03 Abril, 2026",
|
||||
quote: {
|
||||
text: "O refúgio perfeito a 30 minutos da Faria Lima.",
|
||||
author: "Revista Habitar",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 22.000.000",
|
||||
specs: "1500m² • 6 Suítes • 12 Vagas",
|
||||
status: "Consulte",
|
||||
location: "Tamboré Destaque",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Condomínios de alto luxo em Barueri continuam sua ascensão
|
||||
impulsionada pelo recuo da modalidade de trabalho híbrido.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "arquitetura-biofilica",
|
||||
type: "insight",
|
||||
category: "Design",
|
||||
title: "Design Biofílico: O que os compradores premium procuram hoje",
|
||||
excerpt:
|
||||
"Como a integração com o verde deixou de ser um diferencial e passou a ser exigência.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "30 Março, 2026",
|
||||
quote: {
|
||||
text: "A natureza não é um lugar para visitar. É a nossa casa.",
|
||||
author: "Gary Snyder",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Temos notado o aumento drástico pela procura de incorporações que
|
||||
possuam mata nativa integrada. O verde é a nova corrente estética.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "sustentabilidade-luxo",
|
||||
type: "insight",
|
||||
category: "Visão de Futuro",
|
||||
title: "Sustentabilidade e Alto Padrão não são mais mutuamente exclusivos",
|
||||
excerpt: "Certificações EDGE e LEED em residências horizontais.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1501183638710-841dd1904471?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "25 Março, 2026",
|
||||
quote: {
|
||||
text: "Luxo de verdade é não causar impacto sistêmico.",
|
||||
author: "ESG Real Estate",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
A preocupação climática levou a uma modernização drástica dos métodos
|
||||
construtivos e de suprimentos de energia off-grid.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "retorno-casas-vila",
|
||||
type: "insight",
|
||||
category: "Urbanismo",
|
||||
title: "O Retorno e Valorização das Casas de Vila em São Paulo",
|
||||
excerpt:
|
||||
"A procura desenfreada por vilas charmosas nos Jardins e Pinheiros.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1579487785973-74d2ca78ddfc?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "20 Março, 2026",
|
||||
quote: {
|
||||
text: "Há uma poesia irreplicável em pisar na rua de paralelepípedos e abrir um modesto portão para um oasis interno.",
|
||||
author: "R. Fontes",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Com as poucas unidades disponíveis no mercado, a precificação bate
|
||||
recordes históricos. Veja mais em{" "}
|
||||
<Link to="/artigo/mercado-off-market">off-market insights</Link>.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "mercado-off-market",
|
||||
type: "insight",
|
||||
category: "Fundamentos",
|
||||
title: "Mercado Off-Market: A negociação nas sombras",
|
||||
excerpt:
|
||||
"Como operam as chamadas 'Secret Listings' nas camadas mais altas da riqueza paulistana.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1590856029826-c7a73142bbf1?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "14 Março, 2026",
|
||||
quote: {
|
||||
text: "A discrição é a forma mais elevada de confiança.",
|
||||
author: "Private Broker",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Cerca de 40% das transações ultraluxo acontecem sem que a propriedade
|
||||
seja sequer fotografada profissionalmente e inserida na rede.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "importancia-retrofit",
|
||||
type: "insight",
|
||||
category: "Investimentos",
|
||||
title: "A Importância do Retrofit nos Endereços Icônicos",
|
||||
excerpt: "Atualizando prédios da década de 70 para compradores atuais.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1503387762-592deb58ef4e?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "10 Março, 2026",
|
||||
quote: {
|
||||
text: "Preservamos a fachada para atualizar a alma.",
|
||||
author: "Arquitetura & Urbanismo",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
O retrofit é, hoje, a modalidade de investimento que mais agrega valor
|
||||
ao metro quadrado defasado de Higienópolis e Jardins.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "casa-pinheiros",
|
||||
type: "property",
|
||||
category: "Alto de Pinheiros",
|
||||
title: "Residência Contemporânea Próxima à Praça Panamericana",
|
||||
excerpt: "Casa de esquina, com total segurança e vocação receber.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1512915922686-57c11dde9b6b?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "05 Março, 2026",
|
||||
quote: {
|
||||
text: "Silêncio profundo na metrópole barulhenta.",
|
||||
author: "Proprietário",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 14.500.000",
|
||||
specs: "650m² • 4 Suítes • 5 Vagas",
|
||||
status: "Disponível",
|
||||
location: "Alto de Pinheiros",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>Luz, brisa e segurança. Uma rara oportunidade em Pinheiros.</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "apartamento-jardins",
|
||||
type: "property",
|
||||
category: "Jardins",
|
||||
title: "Apartamento de Época Totalmente Restaurado",
|
||||
excerpt: "O charme do piso em taco de peroba e do pé direito de 3.20m.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1533779283484-8ad4940aa3a8?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "28 Fevereiro, 2026",
|
||||
quote: {
|
||||
text: "O antigo redescoberto.",
|
||||
author: "Design Team",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 6.800.000",
|
||||
specs: "280m² • 3 Suítes • 2 Vagas",
|
||||
status: "Em Negociação",
|
||||
location: "Jardins",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Um espetáculo visual de retrofit de ponta, ver mais em{" "}
|
||||
<Link to="/artigo/importancia-retrofit">importância do retrofit</Link>.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "cobertura-brooklin",
|
||||
type: "property",
|
||||
category: "Brooklin",
|
||||
title: "Penthouse Exclusiva no Novo Polo",
|
||||
excerpt:
|
||||
"Condomínio clube moderno com todas as facilidades e uma planta fenomenal.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1502672260266-1c1e52509def?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "20 Fevereiro, 2026",
|
||||
quote: {
|
||||
text: "O novo centro convergiu para cá.",
|
||||
author: "Valor Econômico",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 10.500.000",
|
||||
specs: "380m² • 3 Suítes • 4 Vagas",
|
||||
status: "Disponível",
|
||||
location: "Brooklin Novo",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Uma chance excelente na região com as sedes das maiores empresas do
|
||||
Brasil.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "fazenda-boa-vista-grama",
|
||||
type: "property",
|
||||
category: "Fazenda da Grama",
|
||||
title: "Casa de Campo Moderna com Vista para o Lago",
|
||||
excerpt: "Para fugir de São Paulo, no condomínio com praia particular.",
|
||||
coverImage:
|
||||
"https://images.unsplash.com/photo-1521579294248-c2bfa12a52ce?q=80&w=2000&auto=format&fit=crop",
|
||||
date: "15 Fevereiro, 2026",
|
||||
quote: {
|
||||
text: "O pé na areia agora é verde e montanhoso.",
|
||||
author: "Lifestyle Magazine",
|
||||
},
|
||||
details: {
|
||||
price: "R$ 15.000.000",
|
||||
specs: "800m² • 5 Suítes • 6 Vagas",
|
||||
status: "Off-Market",
|
||||
location: "Itupeva",
|
||||
},
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Arquitetura em U ao redor de um pátio magnífico e uma piscina espelho
|
||||
que repousa sobre a visão do lago central.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
20
Template-02/src/index.css
Normal file
20
Template-02/src/index.css
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600&family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap');
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@theme {
|
||||
--font-sans: "Montserrat", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-serif: "Cormorant Garamond", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
||||
|
||||
--color-brand-gold: #C89B85; /* Soft rose gold / blush */
|
||||
--color-brand-gold-hover: #b58571;
|
||||
--color-brand-dark: #2a2422; /* Warm espresso / charcoal */
|
||||
}
|
||||
|
||||
body {
|
||||
@apply font-sans text-brand-dark bg-[#FCFAFA];
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
@apply font-serif;
|
||||
}
|
||||
16
Template-02/src/main.tsx
Normal file
16
Template-02/src/main.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import {StrictMode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { HelmetProvider } from 'react-helmet-async';
|
||||
import App from './App.tsx';
|
||||
import './index.css';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<HelmetProvider>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</HelmetProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
108
Template-02/src/pages/AssessoriaPage.tsx
Normal file
108
Template-02/src/pages/AssessoriaPage.tsx
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
import { motion } from "motion/react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
|
||||
export function AssessoriaPage() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>A Assessoria | Helena Fontes | Consultoria Imobiliária Especializada</title>
|
||||
<meta name="description" content="Proteja seus interesses nas transações imobiliárias mais complexas. Assessoria completa focada em precisão: do representation do vendedor ao buyer's agent." />
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Service",
|
||||
"serviceType": "Consultoria Imobiliária",
|
||||
"provider": {
|
||||
"@type": "RealEstateAgent",
|
||||
"name": "Helena Fontes"
|
||||
},
|
||||
"description": "Consultoria imobiliária especializada em transações complexas e mercado de luxo. Representação de proprietários e assessoria na compra (Buyer's Agent)."
|
||||
})}
|
||||
</script>
|
||||
</Helmet>
|
||||
<div className="pt-40 pb-32 bg-[#FCFAFA] text-brand-dark min-h-screen">
|
||||
<div className="max-w-4xl mx-auto px-6 lg:px-8">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="text-center mb-20"
|
||||
>
|
||||
<span className="text-[10px] uppercase tracking-[0.3em] text-brand-gold font-bold block mb-6">
|
||||
A Prática
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl lg:text-7xl font-serif leading-tight mb-8">
|
||||
A arte do <span className="italic text-stone-400">encontro</span>.
|
||||
</h1>
|
||||
<div className="w-px h-16 bg-brand-gold/50 mx-auto my-12"></div>
|
||||
<p className="text-stone-500 font-light text-lg md:text-xl leading-relaxed max-w-2xl mx-auto">
|
||||
Meu trabalho transcende a transação. Atuo como uma curadora do seu tempo e
|
||||
patrimônio, garantindo que o processo de comprar ou vender uma propriedade
|
||||
seja tão refinado quanto o imóvel em si.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="space-y-24 md:space-y-32">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="flex flex-col md:flex-row items-center gap-12 md:gap-20"
|
||||
>
|
||||
<div className="w-full md:w-1/2">
|
||||
<div className="aspect-[4/5] object-cover rounded-t-full bg-stone-100 overflow-hidden shadow-xl shadow-stone-200/50 p-2 border border-white">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1449844908441-8829872d2607?q=80&w=2070&auto=format&fit=crop"
|
||||
alt="Detalhe arquitetônico"
|
||||
className="w-full h-full object-cover rounded-t-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full md:w-1/2">
|
||||
<div className="text-brand-gold font-serif italic text-6xl mb-6 opacity-40">I.</div>
|
||||
<h4 className="text-2xl md:text-3xl font-serif mb-6 text-brand-dark">
|
||||
Para quem vende
|
||||
</h4>
|
||||
<p className="text-stone-500 font-light leading-relaxed text-lg">
|
||||
Sua propriedade possui uma narrativa única. Desenvolvo estratégias de apresentação
|
||||
que valorizam não apenas os espaços, mas o estilo de vida que o imóvel proporciona.
|
||||
O foco é em alcançar as pessoas certas, de forma reservada e altamente direcionada.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="flex flex-col md:flex-row-reverse items-center gap-12 md:gap-20"
|
||||
>
|
||||
<div className="w-full md:w-1/2">
|
||||
<div className="aspect-[4/5] object-cover rounded-t-full bg-stone-100 overflow-hidden shadow-xl shadow-stone-200/50 p-2 border border-white">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?q=80&w=2070&auto=format&fit=crop"
|
||||
alt="Ambiente sofisticado"
|
||||
className="w-full h-full object-cover rounded-t-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full md:w-1/2 md:text-right">
|
||||
<div className="text-brand-gold font-serif italic text-6xl mb-6 opacity-40">II.</div>
|
||||
<h4 className="text-2xl md:text-3xl font-serif mb-6 text-brand-dark">
|
||||
Para quem busca
|
||||
</h4>
|
||||
<p className="text-stone-500 font-light leading-relaxed text-lg">
|
||||
Como <i>Buyer's Agent</i>, mapeio o mercado (incluindo oportunidades <i>off-market</i>)
|
||||
para filtrar rigorosamente o que realmente importa. Faço as visitas prévias, economizando
|
||||
seu tempo e apresentando apenas os imóveis que ressoam com a sua busca.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
150
Template-02/src/pages/ContatoPage.tsx
Normal file
150
Template-02/src/pages/ContatoPage.tsx
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
import React, { useState } from "react";
|
||||
import { motion } from "motion/react";
|
||||
import { Instagram as InstaIcon, Linkedin as LinkedInIcon } from "lucide-react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
|
||||
export function ContatoPage() {
|
||||
const [isSubmitted, setIsSubmitted] = useState(false);
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setIsSubmitted(true);
|
||||
// Here you would typically send data to a backend
|
||||
setTimeout(() => {
|
||||
setIsSubmitted(false);
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Contato | Helena Fontes | Corretora de Luxo</title>
|
||||
<meta name="description" content="Entre em contato para agendar uma reunião sigilosa. Discutiremos seus objetivos imobiliários no momento atual do mercado." />
|
||||
</Helmet>
|
||||
<div className="bg-[#FCFAFA] pt-40 pb-32 text-brand-dark min-h-screen">
|
||||
<div className="max-w-4xl mx-auto px-6 lg:px-8 w-full">
|
||||
<motion.div
|
||||
className="text-center mb-20"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
>
|
||||
<span className="text-[10px] uppercase tracking-[0.3em] text-brand-gold font-bold block mb-4">
|
||||
Atendimento Exclusivo
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl lg:text-7xl font-serif leading-tight mb-8">
|
||||
Um convite para <br className="hidden md:block"/>
|
||||
<span className="italic text-stone-400">conversarmos.</span>
|
||||
</h1>
|
||||
<p className="text-stone-500 font-light text-lg mb-12 max-w-xl mx-auto">
|
||||
Entre em contato para agendar uma reunião sigilosa. Discutiremos
|
||||
suas perspectivas no mercado imobiliário com a devida delicadeza
|
||||
e confidencialidade.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
className="flex flex-col md:flex-row gap-16 md:gap-24"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
>
|
||||
<div className="w-full md:w-3/5">
|
||||
{isSubmitted ? (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="p-8 bg-[#f4ece8] text-brand-dark mb-8 rounded-sm"
|
||||
>
|
||||
<h3 className="font-serif text-2xl mb-3">Mensagem Recebida</h3>
|
||||
<p className="text-stone-500 font-light">Obrigada pelo seu contato. Retornarei o mais breve possível com máxima discrição.</p>
|
||||
</motion.div>
|
||||
) : (
|
||||
<form className="space-y-8" onSubmit={handleSubmit}>
|
||||
<div>
|
||||
<label htmlFor="name" className="sr-only">Nome Completo</label>
|
||||
<input required type="text" id="name" placeholder="SEU NOME" className="w-full bg-transparent border-b border-stone-300 text-brand-dark px-2 py-4 text-[10px] tracking-widest uppercase focus:outline-none focus:border-brand-gold transition-colors placeholder:text-stone-400" />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="email" className="sr-only">Email</label>
|
||||
<input required type="email" id="email" placeholder="ENDEREÇO DE E-MAIL" className="w-full bg-transparent border-b border-stone-300 text-brand-dark px-2 py-4 text-[10px] tracking-widest uppercase focus:outline-none focus:border-brand-gold transition-colors placeholder:text-stone-400" />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="phone" className="sr-only">Telefone / WhatsApp</label>
|
||||
<input required type="tel" id="phone" placeholder="TELEFONE / WHATSAPP" className="w-full bg-transparent border-b border-stone-300 text-brand-dark px-2 py-4 text-[10px] tracking-widest uppercase focus:outline-none focus:border-brand-gold transition-colors placeholder:text-stone-400" />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="message" className="sr-only">Mensagem (opcional)</label>
|
||||
<textarea id="message" rows={4} placeholder="COMO POSSO AJUDAR?" className="w-full bg-transparent border-b border-stone-300 text-brand-dark px-2 py-4 text-[10px] tracking-widest uppercase focus:outline-none focus:border-brand-gold transition-colors placeholder:text-stone-400 resize-none"></textarea>
|
||||
</div>
|
||||
<button type="submit" className="w-full bg-brand-dark hover:bg-brand-gold text-white px-8 py-5 text-[10px] font-bold uppercase tracking-[0.3em] transition-colors mt-8">
|
||||
Enviar Mensagem
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="w-full md:w-2/5 space-y-16">
|
||||
<div>
|
||||
<h4 className="text-[10px] uppercase tracking-[0.3em] text-stone-400 font-bold block mb-6">
|
||||
Contato Direto
|
||||
</h4>
|
||||
<ul className="space-y-4 text-stone-500 font-light text-lg">
|
||||
<li>
|
||||
<a
|
||||
href="mailto:helena@helenafontes.com"
|
||||
className="hover:text-brand-gold border-b border-stone-300 hover:border-brand-gold pb-1 transition-colors block w-fit"
|
||||
>
|
||||
helena@helenafontes.com
|
||||
</a>
|
||||
</li>
|
||||
<li>+55 11 99999.9999</li>
|
||||
<li className="pt-4 flex gap-6">
|
||||
<a href="#" className="text-stone-400 hover:text-brand-gold transition-colors">
|
||||
<InstaIcon size={20} strokeWidth={1.5} />
|
||||
</a>
|
||||
<a href="#" className="text-stone-400 hover:text-brand-gold transition-colors">
|
||||
<LinkedInIcon size={20} strokeWidth={1.5} />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="text-[10px] uppercase tracking-[0.3em] text-stone-400 font-bold block mb-6">
|
||||
O Escritório
|
||||
</h4>
|
||||
<ul className="space-y-4 text-stone-500 font-light text-lg">
|
||||
<li>Av. Brigadeiro Faria Lima, 3477</li>
|
||||
<li>Itaim Bibi — São Paulo, SP</li>
|
||||
<li className="pt-4 text-stone-400 italic text-sm">Apenas com hora marcada</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* MAP SECTION */}
|
||||
<motion.div
|
||||
className="w-full h-80 md:h-96 mt-24 bg-stone-100 border border-white shadow-xl shadow-stone-200/50 rounded-sm overflow-hidden"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
>
|
||||
<iframe
|
||||
src="https://maps.google.com/maps?q=Av.%20Brigadeiro%20Faria%20Lima,%203477,%20São%20Paulo&t=m&z=16&output=embed&layer=c"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen={false}
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
title="Localização do Escritório"
|
||||
className="w-full h-full object-cover grayscale opacity-80 hover:grayscale-0 hover:opacity-100 transition-all duration-700"
|
||||
></iframe>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
66
Template-02/src/pages/InsightsPage.tsx
Normal file
66
Template-02/src/pages/InsightsPage.tsx
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import { Link } from "react-router-dom";
|
||||
import { ArrowRight } from "lucide-react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { Article } from "../data/articles";
|
||||
import { motion } from "motion/react";
|
||||
|
||||
export function InsightsPage({ marketInsights }: { marketInsights: Article[] }) {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Insights & Blog | Helena Fontes</title>
|
||||
<meta name="description" content="Artigos e análises de mercado sobre o mercado imobiliário premium de São Paulo. Dicas de negócios e inteligência analítica." />
|
||||
</Helmet>
|
||||
<div className="pt-40 pb-32 bg-[#FCFAFA] min-h-screen">
|
||||
<div className="max-w-4xl mx-auto px-6 lg:px-8">
|
||||
<div className="mb-24 text-center md:text-left">
|
||||
<span className="text-[10px] uppercase tracking-[0.3em] text-stone-400 font-bold block mb-4">
|
||||
Diário Pessoal
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl lg:text-7xl font-serif text-brand-dark leading-tight">
|
||||
Reflexões e <br className="hidden md:block"/><span className="italic text-stone-400">Inspirações.</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col space-y-16 lg:space-y-24">
|
||||
{marketInsights.map((post, index) => (
|
||||
<motion.div
|
||||
key={post.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6, delay: 0.1 }}
|
||||
className="border-t border-stone-200 pt-12 md:pt-16"
|
||||
>
|
||||
<Link
|
||||
to={`/artigo/${post.id}`}
|
||||
className="group block"
|
||||
>
|
||||
<div className="flex flex-col md:flex-row md:items-baseline gap-4 md:gap-16 mb-6">
|
||||
<span className="text-[10px] text-brand-gold uppercase tracking-[0.3em] font-bold w-32 shrink-0">
|
||||
{post.date}
|
||||
</span>
|
||||
<h3 className="text-2xl md:text-4xl font-serif text-brand-dark group-hover:text-stone-500 transition-colors leading-snug">
|
||||
{post.title}
|
||||
</h3>
|
||||
</div>
|
||||
<div className="flex flex-col md:flex-row gap-4 md:gap-16">
|
||||
<div className="w-32 shrink-0 hidden md:block"></div>
|
||||
<div>
|
||||
<p className="text-stone-500 font-light text-lg leading-relaxed mb-10 max-w-2xl">
|
||||
{post.excerpt}
|
||||
</p>
|
||||
<span className="flex items-center gap-4 text-[10px] font-bold uppercase tracking-[0.3em] text-brand-dark group-hover:text-brand-gold transition-colors w-fit">
|
||||
<span className="pb-1 border-b border-brand-dark group-hover:border-brand-gold transition-colors">Ler artigo</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
34
Template-02/src/pages/NotFoundPage.tsx
Normal file
34
Template-02/src/pages/NotFoundPage.tsx
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { Link } from "react-router-dom";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
|
||||
export function NotFoundPage() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Página Não Encontrada | Helena Fontes</title>
|
||||
<meta name="description" content="A página que você está procurando não existe ou foi movida." />
|
||||
</Helmet>
|
||||
|
||||
<div className="min-h-[80vh] flex flex-col items-center justify-center px-6 lg:px-8 text-center pt-32 pb-24">
|
||||
<span className="text-[10px] uppercase tracking-[0.3em] font-bold text-brand-gold mb-4 block">
|
||||
Erro 404
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-6xl lg:text-8xl font-serif text-brand-dark leading-[1.1] mb-8">
|
||||
Destino <br className="hidden md:block" />
|
||||
<span className="italic text-stone-400">indisponível</span>
|
||||
</h1>
|
||||
<p className="text-stone-500 font-light max-w-lg mx-auto mb-12">
|
||||
A página que você procura pode ter sido alterada, retirada do ar para garantir a exclusividade, ou o endereço foi digitado incorretamente.
|
||||
</p>
|
||||
<Link
|
||||
to="/"
|
||||
className="inline-flex items-center gap-4 bg-brand-dark hover:bg-brand-gold text-white px-8 py-5 text-[10px] font-bold uppercase tracking-[0.3em] transition-colors"
|
||||
>
|
||||
<ArrowLeft size={16} />
|
||||
Retornar à Homepage
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
140
Template-02/src/pages/PortfolioPage.tsx
Normal file
140
Template-02/src/pages/PortfolioPage.tsx
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
import { motion } from "motion/react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { MapPin, ArrowRight } from "lucide-react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { Article } from "../data/articles";
|
||||
|
||||
export function PortfolioPage({ propertiesAsArticles }: { propertiesAsArticles: Article[] }) {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Portfólio de Luxo | Helena Fontes</title>
|
||||
<meta name="description" content="Explore propriedades de alto padrão e luxo em São Paulo. Casas e apartamentos em bairros como Itaim Bibi e Jardins, além de opções off-market exclusivas." />
|
||||
<meta property="og:title" content="Portfólio de Luxo | Helena Fontes" />
|
||||
<meta property="og:description" content="Explore propriedades de alto padrão e luxo em São Paulo. Casas e apartamentos em bairros como Itaim Bibi e Jardins." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="Portfólio de Luxo | Helena Fontes" />
|
||||
<meta name="twitter:description" content="Explore propriedades de alto padrão e luxo em São Paulo." />
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [{
|
||||
"@type": "ListItem",
|
||||
"position": 1,
|
||||
"name": "Home",
|
||||
"item": "https://helenafontes.com.br/"
|
||||
},{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"name": "Portfólio",
|
||||
"item": "https://helenafontes.com.br/portfolio"
|
||||
}]
|
||||
})}
|
||||
</script>
|
||||
</Helmet>
|
||||
<div className="pt-40 pb-32 bg-[#FCFAFA] min-h-screen">
|
||||
<div className="max-w-7xl mx-auto px-6 lg:px-8">
|
||||
<div className="flex flex-col md:flex-row md:items-end justify-between gap-12 mb-32">
|
||||
<div className="max-w-2xl text-center md:text-left">
|
||||
<span className="text-[10px] uppercase tracking-[0.3em] text-brand-gold font-bold block mb-4">
|
||||
Destaques do Portfólio
|
||||
</span>
|
||||
<h1 className="text-4xl md:text-5xl lg:text-7xl font-serif text-brand-dark leading-tight">
|
||||
A curadoria <span className="italic text-stone-400">em foco.</span>
|
||||
</h1>
|
||||
</div>
|
||||
<p className="text-stone-500 font-light text-lg max-w-md text-center md:text-right mt-8 md:mt-0">
|
||||
Cada propriedade é tratada como uma obra de arte viva. Analiso a
|
||||
arquitetura e a atmosfera, apresentando apenas espaços que inspiram.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-40">
|
||||
{propertiesAsArticles.map((property, index) => (
|
||||
<motion.article
|
||||
key={property.id}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className={`flex flex-col ${index % 2 !== 0 ? "md:flex-row-reverse" : "md:flex-row"} gap-12 lg:gap-24 items-center group`}
|
||||
>
|
||||
{/* Image Side */}
|
||||
<div className="w-full md:w-3/5">
|
||||
<Link
|
||||
to={`/artigo/${property.id}`}
|
||||
className={`block relative overflow-hidden bg-stone-100 ${index % 2 !== 0 ? "aspect-square rounded-full md:rounded-bl-[200px] md:rounded-tr-[200px] md:rounded-tl-sm md:rounded-br-sm" : "aspect-[4/5] rounded-t-full"}`}
|
||||
>
|
||||
<img
|
||||
src={property.coverImage}
|
||||
alt={property.title}
|
||||
loading={index === 0 ? "eager" : "lazy"}
|
||||
className="w-full h-full object-cover transform group-hover:scale-[1.03] transition-transform duration-[2s] ease-out"
|
||||
/>
|
||||
<div className="absolute top-8 left-1/2 -translate-x-1/2 md:translate-x-0 md:left-8 bg-white px-6 py-2 text-[10px] font-bold uppercase tracking-widest text-brand-dark rounded-full shadow-lg">
|
||||
{property.details?.status || "Exclusividade"}
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Content Side */}
|
||||
<div className="w-full md:w-2/5 flex flex-col items-center text-center md:text-left md:items-start justify-center">
|
||||
<div className="flex items-center gap-3 text-brand-gold text-[10px] uppercase tracking-[0.2em] mb-4">
|
||||
<span>{property.category}</span>
|
||||
</div>
|
||||
|
||||
<Link to={`/artigo/${property.id}`}>
|
||||
<h3 className="text-3xl lg:text-5xl font-serif text-brand-dark leading-[1.1] mb-6 hover:text-stone-500 transition-colors">
|
||||
{property.title}
|
||||
</h3>
|
||||
</Link>
|
||||
|
||||
<p className="text-stone-500 font-light text-lg leading-relaxed mb-10 max-w-md">
|
||||
{property.excerpt}
|
||||
</p>
|
||||
|
||||
<div className="w-full grid grid-cols-2 gap-8 mb-10 pt-8 border-t border-stone-200">
|
||||
<div className="text-center md:text-left">
|
||||
<span className="block text-[10px] uppercase tracking-[0.2em] text-stone-400 mb-2">
|
||||
Acomodações
|
||||
</span>
|
||||
<span className="text-brand-dark font-serif text-xl">
|
||||
{property.details?.specs}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-center md:text-right">
|
||||
<span className="block text-[10px] uppercase tracking-[0.2em] text-stone-400 mb-2">
|
||||
Valor
|
||||
</span>
|
||||
<span className="text-brand-dark font-serif text-xl">
|
||||
{property.details?.price}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
to={`/artigo/${property.id}`}
|
||||
className="inline-flex items-center gap-4 text-[10px] font-bold uppercase tracking-[0.3em] text-brand-dark group-hover:text-brand-gold transition-colors"
|
||||
>
|
||||
<span className="pb-1 border-b border-brand-dark group-hover:border-brand-gold transition-colors">Examinar</span>
|
||||
</Link>
|
||||
</div>
|
||||
</motion.article>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-32 text-center border-t border-stone-200 pt-16">
|
||||
<Link
|
||||
to="/contato"
|
||||
className="inline-flex items-center gap-3 bg-brand-dark px-10 py-5 text-[10px] font-bold uppercase tracking-[0.2em] text-white hover:bg-brand-gold transition-colors duration-300"
|
||||
>
|
||||
Solicitar Lista Completa (Opções Off-Market)
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
1
Template-02/src/vite-env.d.ts
vendored
Normal file
1
Template-02/src/vite-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
||||
26
Template-02/tsconfig.json
Normal file
26
Template-02/tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"module": "ESNext",
|
||||
"lib": [
|
||||
"ES2022",
|
||||
"DOM",
|
||||
"DOM.Iterable"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"allowJs": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
24
Template-02/vite.config.ts
Normal file
24
Template-02/vite.config.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import tailwindcss from '@tailwindcss/vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import path from 'path';
|
||||
import {defineConfig, loadEnv} from 'vite';
|
||||
|
||||
export default defineConfig(({mode}) => {
|
||||
const env = loadEnv(mode, '.', '');
|
||||
return {
|
||||
plugins: [react(), tailwindcss()],
|
||||
define: {
|
||||
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, '.'),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
||||
// Do not modifyâfile watching is disabled to prevent flickering during agent edits.
|
||||
hmr: process.env.DISABLE_HMR !== 'true',
|
||||
},
|
||||
};
|
||||
});
|
||||
Loading…
Reference in a new issue