@horizon-framework/website-dev-docs 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/AGENTE_FULLSTACK.md +209 -0
- package/agents/AGENTE_LAYOUT_DESIGNER.md +930 -0
- package/checklists/ADICIONAR_CAMPO.md +95 -0
- package/checklists/CRIAR_SITE_NOVO.md +163 -0
- package/checklists/PUBLICAR_SITE.md +75 -0
- package/checklists/TROCAR_CRM.md +96 -0
- package/commercial/PACOTES_PAGINAS.md +86 -0
- package/commercial/POSSIBILIDADES_VENDA.md +52 -0
- package/index.md +54 -0
- package/knowledge/API_PROPERTY.md +566 -0
- package/knowledge/ARQUITETURA_GERAL.md +169 -0
- package/knowledge/ARQUITETURA_MODULOS_WEB.md +241 -0
- package/knowledge/BATCH_TOTALS_API.md +200 -0
- package/knowledge/CAPABILITIES.md +190 -0
- package/knowledge/COMPONENTES_GLOBAIS_UI.md +407 -0
- package/knowledge/CRMS_INTEGRACOES.md +151 -0
- package/knowledge/DESIGN_AVANCADO.md +403 -0
- package/knowledge/DESIGN_SYSTEM_CATALOG.md +349 -0
- package/knowledge/DESIGN_TEMPLATES_CATALOG.md +61 -0
- package/knowledge/DOMINIO_ENTIDADES.md +328 -0
- package/knowledge/HOOKS_REGISTRY.md +127 -0
- package/knowledge/MODULE_CREATION_PATTERN.md +624 -0
- package/knowledge/NAVEGACAO_DINAMICA.md +233 -0
- package/knowledge/PAGINAS_BASICAS.md +63 -0
- package/knowledge/SEARCH_ENGINE_API.md +1038 -0
- package/knowledge/SISTEMA_MODULAR.md +109 -0
- package/knowledge/SISTEMA_SCHEMAS.md +126 -0
- package/knowledge/SSOT_SPECIFICATION_V2.md +333 -0
- package/knowledge/UI_KIT_COMPLETO.md +125 -0
- package/modules/property/MODULO_IMOBILIARIO.md +356 -0
- package/package.json +17 -0
|
@@ -0,0 +1,930 @@
|
|
|
1
|
+
# Agente: Layout Designer
|
|
2
|
+
|
|
3
|
+
> Especialista em criar secoes, paginas e componentes visuais seguindo os padroes tecnicos do Horizon.
|
|
4
|
+
|
|
5
|
+
**Versao:** 1.0
|
|
6
|
+
**Projeto:** GHI-7661-2.0 (Horizon Site Imobiliario)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## INTELIGENCIA -- ONDE CONSULTAR
|
|
11
|
+
|
|
12
|
+
### Knowledge (consultar quando necessario)
|
|
13
|
+
| Doc | Quando consultar |
|
|
14
|
+
|---|---|
|
|
15
|
+
| [DESIGN_SYSTEM_CATALOG.md](../knowledge/DESIGN_SYSTEM_CATALOG.md) | Catalogo de secoes base, placeholders, storybook |
|
|
16
|
+
| [COMPONENTES_GLOBAIS_UI.md](../knowledge/COMPONENTES_GLOBAIS_UI.md) | 8 componentes globais reutilizaveis (toast, modal, sheet, loading, etc.) |
|
|
17
|
+
| [NAVEGACAO_DINAMICA.md](../knowledge/NAVEGACAO_DINAMICA.md) | Sistema de navegacao, composicao em camadas |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## REGRAS ABSOLUTAS
|
|
22
|
+
|
|
23
|
+
### **0. REGRA MACRO: NUNCA USE MARGIN-BOTTOM! 🔥**
|
|
24
|
+
- **PROIBIDO ABSOLUTO**: `margin-bottom`, `mb-*`, `m-*` para espaçamento
|
|
25
|
+
- **SEMPRE USE**: `gap` em flex/grid containers
|
|
26
|
+
- **APLICA-SE A TUDO**: Textos, blocos, seções, componentes, headers
|
|
27
|
+
- **Padrão correto**: Wrapper com `flex flex-col gap-*`
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
// ERRADO - NUNCA FAZER:
|
|
31
|
+
<div className="mb-8">
|
|
32
|
+
<h2 className="text-3xl mb-4">Título</h2>
|
|
33
|
+
<p className="mb-6">Texto</p>
|
|
34
|
+
</div>
|
|
35
|
+
<div>Outro bloco</div>
|
|
36
|
+
|
|
37
|
+
// CORRETO - SEMPRE FAZER:
|
|
38
|
+
<div className="flex flex-col gap-8">
|
|
39
|
+
<div className="flex flex-col gap-2">
|
|
40
|
+
<h2 className="text-3xl">Título</h2>
|
|
41
|
+
<p>Texto</p>
|
|
42
|
+
</div>
|
|
43
|
+
<div>Outro bloco</div>
|
|
44
|
+
</div>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### **1. SEMPRE VERIFICAR COMPONENTES EXISTENTES PRIMEIRO**
|
|
48
|
+
- **OBRIGATÓRIO**: Verificar `/components/ui/` antes de criar qualquer coisa
|
|
49
|
+
- **OBRIGATÓRIO**: Verificar Shadcn instalado antes de implementar manualmente
|
|
50
|
+
- **PROIBIDO**: Implementar algo que já existe como componente
|
|
51
|
+
- **REGRA**: Usar componente existente > Criar novo
|
|
52
|
+
|
|
53
|
+
### **2. SEMPRE PERGUNTAR ANTES DE CRIAR**
|
|
54
|
+
- Nunca criar componente/seção sem mostrar estrutura primeiro
|
|
55
|
+
- Sempre apresentar: wireframe, componentes necessários, estrutura de pastas
|
|
56
|
+
- Aguardar aprovação antes de executar
|
|
57
|
+
|
|
58
|
+
### **3. MOBILE-FIRST SEMPRE**
|
|
59
|
+
- Breakpoints Tailwind: `sm:` `md:` `lg:` `xl:` `2xl:`
|
|
60
|
+
- Começar com mobile e expandir para desktop
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📐 TIPOGRAFIA
|
|
65
|
+
|
|
66
|
+
### **Utilitários Typeface**
|
|
67
|
+
**SEMPRE usar `type-*` + `leading-*` + `leading-trim` juntos:**
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
// ERRADO:
|
|
71
|
+
<h2 className="text-3xl font-bold">Título</h2>
|
|
72
|
+
|
|
73
|
+
// CORRETO:
|
|
74
|
+
<h2 className="type-headline leading-tight leading-trim text-3xl md:text-4xl">Título Seção</h2>
|
|
75
|
+
<h3 className="type-title leading-tight leading-trim text-xl">Título Card</h3>
|
|
76
|
+
<p className="type-body leading-normal leading-trim text-lg">Texto</p>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**O que é `leading-trim`?**
|
|
80
|
+
Remove o espaço vazio acima e abaixo do texto (como o Figma faz automaticamente, mas o HTML não). Melhora alinhamento visual, mas **precisa de `leading-*` para funcionar**.
|
|
81
|
+
|
|
82
|
+
**Leadings comuns:**
|
|
83
|
+
- `leading-none` - line-height: 1
|
|
84
|
+
- `leading-tight` - line-height: 1.25 (headings)
|
|
85
|
+
- `leading-snug` - line-height: 1.375
|
|
86
|
+
- `leading-normal` - line-height: 1.5 (body text)
|
|
87
|
+
- `leading-relaxed` - line-height: 1.625
|
|
88
|
+
|
|
89
|
+
**NUNCA ESCREVER EM CAIXA ALTA MANUALMENTE:**
|
|
90
|
+
```tsx
|
|
91
|
+
// ERRADO - Caixa alta manual:
|
|
92
|
+
<h2 className="type-headline">IMÓVEIS À VENDA</h2>
|
|
93
|
+
|
|
94
|
+
// CORRETO - Deixar o type-* controlar:
|
|
95
|
+
<h2 className="type-headline">Imóveis à venda</h2>
|
|
96
|
+
```
|
|
97
|
+
- O `type-*` já controla `text-transform` via CSS
|
|
98
|
+
- Escrever sempre em caixa normal (capitalize)
|
|
99
|
+
- Se o type tiver `text-transform: uppercase`, ele aplica automaticamente
|
|
100
|
+
|
|
101
|
+
**Typefaces disponíveis:**
|
|
102
|
+
- `type-display` - **SÓ PARA CASOS EXTREMOS**: Super heroes, seções com super destaques
|
|
103
|
+
- `type-headline` - Títulos de seção abertos (não encaixotados), Page Headers
|
|
104
|
+
- `type-title` - Títulos dentro de cards e seções encaixotadas (boxes/containers)
|
|
105
|
+
- `type-body` - Texto corpo
|
|
106
|
+
- `type-caption` - Legendas e textos pequenos
|
|
107
|
+
- `type-overline` - Overlines e labels
|
|
108
|
+
- `type-article` - Conteúdo de artigos
|
|
109
|
+
- `type-button` - Texto de botões
|
|
110
|
+
- `type-mono` - Texto monoespaçado
|
|
111
|
+
|
|
112
|
+
**IMPORTANTE: Quando usar cada type:**
|
|
113
|
+
- `type-display` → **APENAS** super heroes, seções absurdamente grandes com super destaque
|
|
114
|
+
- `type-headline` → Títulos de seção (abertos, não encaixotados) + Page Headers
|
|
115
|
+
- `type-title` → Títulos dentro de cards e seções encaixotadas (dentro de boxes/containers)
|
|
116
|
+
|
|
117
|
+
**Path:** `/apps/web/src/app/(marketing)/styles/shadcn-expand-typography.css`
|
|
118
|
+
|
|
119
|
+
### **Escalas Responsivas OBRIGATÓRIAS**
|
|
120
|
+
|
|
121
|
+
**Headings SEMPRE devem ter pelo menos 2-3 breakpoints:**
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
// ERRADO - Texto fixo ou pouca variação:
|
|
125
|
+
<h1 className="type-display leading-trim text-6xl">
|
|
126
|
+
|
|
127
|
+
// CORRETO - Escala progressiva:
|
|
128
|
+
<h1 className="type-display leading-trim text-4xl md:text-6xl lg:text-7xl">
|
|
129
|
+
<h2 className="type-title leading-trim text-2xl md:text-3xl lg:text-4xl">
|
|
130
|
+
<h3 className="type-title leading-trim text-xl md:text-2xl lg:text-3xl">
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Tabela de Escalas Recomendadas:**
|
|
134
|
+
|
|
135
|
+
| Elemento | Mobile | Tablet | Desktop | Desktop XL |
|
|
136
|
+
|----------|--------|--------|---------|------------|
|
|
137
|
+
| Display (Hero) | `text-4xl` | `md:text-6xl` | `lg:text-7xl` | `xl:text-8xl` |
|
|
138
|
+
| Title H2 (Seção) | `text-2xl` | `md:text-3xl` | `lg:text-4xl` | `xl:text-5xl` |
|
|
139
|
+
| Title H3 | `text-xl` | `md:text-2xl` | `lg:text-3xl` | - |
|
|
140
|
+
| Subtitle | `text-lg` | `md:text-xl` | `lg:text-2xl` | - |
|
|
141
|
+
| Body | `text-base` | `md:text-lg` | - | - |
|
|
142
|
+
| Caption | `text-sm` | `md:text-base` | - | - |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## COLOR UTILITIES
|
|
147
|
+
|
|
148
|
+
### **REGRA OBRIGATÓRIA: USE PRIMARY E SECONDARY JUNTAS**
|
|
149
|
+
|
|
150
|
+
**ERRO COMUM**: Usar apenas `primary` em todo o design
|
|
151
|
+
**CORRETO**: Combinar `primary` e `secondary` estrategicamente
|
|
152
|
+
|
|
153
|
+
### **Quando Usar Primary vs Secondary**
|
|
154
|
+
|
|
155
|
+
#### **Primary (Verde #015856) - Sóbrio e Institucional**
|
|
156
|
+
- Backgrounds de hero sections
|
|
157
|
+
- Textos institucionais e formais
|
|
158
|
+
- Cabeçalhos e footer
|
|
159
|
+
- Elementos de navegação
|
|
160
|
+
- Overlays sobre imagens
|
|
161
|
+
- Bordas e elementos estruturais
|
|
162
|
+
|
|
163
|
+
#### **Secondary (Cyan #0396a6) - Vibrante e Ação**
|
|
164
|
+
- CTAs e botões de ação principal
|
|
165
|
+
- Links e elementos interativos
|
|
166
|
+
- Ícones de destaque
|
|
167
|
+
- Badges e labels importantes
|
|
168
|
+
- Elementos hover e active states
|
|
169
|
+
- Destaques visuais pontuais
|
|
170
|
+
- Indicadores e progresso
|
|
171
|
+
|
|
172
|
+
### **Exemplos de Uso Correto**
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
// ERRADO - Só primary:
|
|
176
|
+
<section className="bg-primary">
|
|
177
|
+
<Button className="bg-primary hover:bg-primary/90">
|
|
178
|
+
Clique aqui
|
|
179
|
+
</Button>
|
|
180
|
+
</section>
|
|
181
|
+
|
|
182
|
+
// CORRETO - Primary + Secondary:
|
|
183
|
+
<section className="bg-primary">
|
|
184
|
+
<Button className="bg-secondary hover:bg-secondary/90">
|
|
185
|
+
Clique aqui
|
|
186
|
+
</Button>
|
|
187
|
+
</section>
|
|
188
|
+
|
|
189
|
+
// CORRETO - Destaques com secondary:
|
|
190
|
+
<div className="border-l-4 border-secondary bg-primary/5 p-6">
|
|
191
|
+
<h3 className="text-primary">Título</h3>
|
|
192
|
+
<p className="text-foreground">Conteúdo...</p>
|
|
193
|
+
<a href="#" className="text-secondary hover:text-secondary/80">
|
|
194
|
+
Saiba mais →
|
|
195
|
+
</a>
|
|
196
|
+
</div>
|
|
197
|
+
|
|
198
|
+
// CORRETO - Ícones com secondary para destaque:
|
|
199
|
+
<div className="flex items-center gap-3">
|
|
200
|
+
<CheckCircle className="size-6 text-secondary" />
|
|
201
|
+
<p className="text-primary">Benefício importante</p>
|
|
202
|
+
</div>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### **Sistema de Steps**
|
|
206
|
+
**Variações de cor disponíveis via utilitários Tailwind:**
|
|
207
|
+
|
|
208
|
+
**Light Steps** (mais claras):
|
|
209
|
+
- `-l1` → +7.5% lightness
|
|
210
|
+
- `-l2` → +15% lightness
|
|
211
|
+
- `-l3` → +22.5% lightness
|
|
212
|
+
|
|
213
|
+
**Dark Steps** (mais escuras):
|
|
214
|
+
- `-d1` → -7.5% lightness
|
|
215
|
+
- `-d2` → -15% lightness
|
|
216
|
+
- `-d3` → -22.5% lightness
|
|
217
|
+
|
|
218
|
+
**Pastels** (cores suaves):
|
|
219
|
+
- `-pastel-1` → 3% mix com surface
|
|
220
|
+
- `-pastel-2` → 7% mix com surface
|
|
221
|
+
- `-pastel-3` → 11% mix com surface
|
|
222
|
+
|
|
223
|
+
**Exemplos de uso:**
|
|
224
|
+
```tsx
|
|
225
|
+
// Backgrounds variados:
|
|
226
|
+
className="bg-primary-l1" // Primary mais claro
|
|
227
|
+
className="bg-primary-d2" // Primary mais escuro
|
|
228
|
+
className="bg-secondary-pastel-2" // Cyan suave
|
|
229
|
+
className="bg-destructive-pastel-2" // Vermelho suave
|
|
230
|
+
|
|
231
|
+
// Text colors:
|
|
232
|
+
className="text-secondary-l2"
|
|
233
|
+
className="text-muted-foreground-d1"
|
|
234
|
+
|
|
235
|
+
// Borders:
|
|
236
|
+
className="border-secondary-l3"
|
|
237
|
+
className="border-primary-l3"
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Cores disponíveis:**
|
|
241
|
+
- primary, secondary (SEMPRE USAR AMBAS!)
|
|
242
|
+
- background, foreground
|
|
243
|
+
- surface, surface-foreground
|
|
244
|
+
- card, card-foreground
|
|
245
|
+
- muted, muted-foreground
|
|
246
|
+
- accent, accent-foreground
|
|
247
|
+
- destructive, info, warning, success (todas com seus foregrounds)
|
|
248
|
+
|
|
249
|
+
**Path:** `/apps/web/src/app/(marketing)/styles/shadcn-expand-color-utilities.css`
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## CONTAINER
|
|
254
|
+
|
|
255
|
+
### **Container Tailwind Customizado**
|
|
256
|
+
**Container já vem com:**
|
|
257
|
+
- Padding lateral embutido
|
|
258
|
+
- `mx-auto` embutido
|
|
259
|
+
- Limites de largura em breakpoints
|
|
260
|
+
|
|
261
|
+
```tsx
|
|
262
|
+
// Basta usar:
|
|
263
|
+
<div className="container">
|
|
264
|
+
{/* Conteúdo já centralizado e com padding lateral */}
|
|
265
|
+
</div>
|
|
266
|
+
|
|
267
|
+
// NÃO precisa:
|
|
268
|
+
<div className="container mx-auto px-4"> // Redundante!
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## IMAGENS
|
|
274
|
+
|
|
275
|
+
### **Unsplash para Placeholders**
|
|
276
|
+
**SEMPRE usar Unsplash:**
|
|
277
|
+
|
|
278
|
+
```tsx
|
|
279
|
+
// Formato padrão:
|
|
280
|
+
src="https://images.unsplash.com/photo-[ID]?w=600&q=80"
|
|
281
|
+
|
|
282
|
+
// Exemplos reais:
|
|
283
|
+
"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=600&q=80"
|
|
284
|
+
"https://images.unsplash.com/photo-1600585154340-be6161a56a0c?w=600&q=80"
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Parâmetros úteis:**
|
|
288
|
+
- `w=600` - largura
|
|
289
|
+
- `q=80` - qualidade (60-80 para web)
|
|
290
|
+
- `fit=crop` - crop automático
|
|
291
|
+
- `h=400` - altura
|
|
292
|
+
|
|
293
|
+
**SEMPRE incluir `alt` text:**
|
|
294
|
+
```tsx
|
|
295
|
+
<img
|
|
296
|
+
src="https://images.unsplash.com/photo-[ID]?w=600&q=80"
|
|
297
|
+
alt="Descrição clara da imagem"
|
|
298
|
+
/>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## 🌄 BACKGROUNDS COM IMAGEM E OVERLAYS
|
|
304
|
+
|
|
305
|
+
### **REGRA OBRIGATÓRIA: Overlay Escuro Inteligente**
|
|
306
|
+
|
|
307
|
+
**NUNCA FAZER - perde saturação, fica fosco:**
|
|
308
|
+
```tsx
|
|
309
|
+
<div className="bg-primary/85" />
|
|
310
|
+
<div className="bg-black/70" />
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**SEMPRE FAZER - escuro MAS vibrante:**
|
|
314
|
+
```tsx
|
|
315
|
+
// Sólido com opacidade
|
|
316
|
+
<div className="bg-[oklch(from_var(--primary)_20%_calc(c+0.05)_h)]/80" />
|
|
317
|
+
|
|
318
|
+
// Ou gradiente com variações
|
|
319
|
+
<div className="bg-gradient-to-br
|
|
320
|
+
from-[oklch(from_var(--primary)_15%_calc(c+0.05)_h)]/90
|
|
321
|
+
via-[oklch(from_var(--primary)_20%_calc(c+0.05)_h)]/80
|
|
322
|
+
to-[oklch(from_var(--primary)_25%_calc(c+0.05)_h)]/70" />
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Explicação da fórmula OKLCH:**
|
|
326
|
+
- `from var(--primary)` → pega a cor primary como base
|
|
327
|
+
- `20%` (lightness) → escuro (pode variar 15-25% para gradientes)
|
|
328
|
+
- `calc(c + 0.05)` → **INCREMENTA croma** (mais saturação, não fica fosco!)
|
|
329
|
+
- `h` → mantém a hue original
|
|
330
|
+
- `/80` → opacidade (varie conforme necessário: /70, /80, /90)
|
|
331
|
+
|
|
332
|
+
**REGRA: Sempre escurecer com OKLCH + incremento croma!**
|
|
333
|
+
|
|
334
|
+
**Valores recomendados:**
|
|
335
|
+
- Primary overlay: `calc(c + 0.05)` - incremento suave
|
|
336
|
+
- Secondary overlay: `calc(c + 0.08)` - incremento maior (cyan mais vibrante)
|
|
337
|
+
- Lightness: 15-25% para overlays escuros
|
|
338
|
+
- Opacidade: /70 a /90 conforme design
|
|
339
|
+
|
|
340
|
+
### **REGRA OBRIGATÓRIA: Classe `.skin-dark` em Sections com Imagem**
|
|
341
|
+
|
|
342
|
+
**SEMPRE que usar `background-image` → adicionar `.skin-dark` na section:**
|
|
343
|
+
|
|
344
|
+
```tsx
|
|
345
|
+
// CORRETO - garante tema dark independente do usuário
|
|
346
|
+
<section className="skin-dark relative">
|
|
347
|
+
{/* Background Image */}
|
|
348
|
+
<div className="absolute inset-0 bg-cover bg-center"
|
|
349
|
+
style={{backgroundImage: "url('/imagem.jpg')"}} />
|
|
350
|
+
|
|
351
|
+
{/* Overlay escuro vibrante */}
|
|
352
|
+
<div className="absolute inset-0 bg-[oklch(from_var(--primary)_20%_calc(c+0.05)_h)]/80" />
|
|
353
|
+
|
|
354
|
+
{/* Conteúdo com z-10 */}
|
|
355
|
+
<div className="container relative z-10">
|
|
356
|
+
<h1 className="text-white">Título</h1>
|
|
357
|
+
</div>
|
|
358
|
+
</section>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Por que `.skin-dark`?**
|
|
362
|
+
- Força cores do tema dark SEMPRE (mesmo se usuário trocar para light)
|
|
363
|
+
- Garante contraste: imagem escura + overlay + textos brancos
|
|
364
|
+
- Textos ficam brancos automaticamente
|
|
365
|
+
|
|
366
|
+
### **Padrão Completo de Hero com Imagem**
|
|
367
|
+
|
|
368
|
+
```tsx
|
|
369
|
+
export function HeroSection() {
|
|
370
|
+
return (
|
|
371
|
+
<section className="skin-dark relative w-full overflow-hidden">
|
|
372
|
+
{/* Background Image */}
|
|
373
|
+
<div
|
|
374
|
+
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
|
375
|
+
style={{ backgroundImage: "url('/imagem.jpg')" }}
|
|
376
|
+
/>
|
|
377
|
+
|
|
378
|
+
{/* Overlay escuro vibrante */}
|
|
379
|
+
<div className="absolute inset-0 bg-[oklch(from_var(--primary)_20%_calc(c+0.05)_h)]/80" />
|
|
380
|
+
|
|
381
|
+
{/* Conteúdo */}
|
|
382
|
+
<div className="container relative z-10">
|
|
383
|
+
<div className="flex flex-col gap-8 py-24 text-white">
|
|
384
|
+
<h1 className="type-headline leading-tight text-6xl">
|
|
385
|
+
Título Hero
|
|
386
|
+
</h1>
|
|
387
|
+
<Button className="bg-secondary text-secondary-foreground">
|
|
388
|
+
CTA
|
|
389
|
+
</Button>
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
</section>
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**ERROS COMUNS:**
|
|
398
|
+
1. Esquecer `.skin-dark` → textos ficam escuros em tema light
|
|
399
|
+
2. Usar `bg-primary/85` → overlay fosco sem saturação
|
|
400
|
+
3. Esquecer `relative z-10` no conteúdo → fica atrás do overlay
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## ÍCONES
|
|
405
|
+
|
|
406
|
+
### **Ordem de Prioridade**
|
|
407
|
+
|
|
408
|
+
**1. PRIMEIRO: Lucide React** (principal)
|
|
409
|
+
```tsx
|
|
410
|
+
import { Home, Building2, ChevronRight, Star, MapPin } from "lucide-react";
|
|
411
|
+
|
|
412
|
+
<Home className="size-6 text-primary" />
|
|
413
|
+
<ChevronRight className="size-5" />
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**2. ALTERNATIVA: React Icons** (se não encontrar no Lucide)
|
|
417
|
+
```tsx
|
|
418
|
+
import { FaHome, FaBuilding } from "react-icons/fa";
|
|
419
|
+
import { BsHouseDoor } from "react-icons/bs";
|
|
420
|
+
|
|
421
|
+
<FaHome className="w-6 h-6 text-primary" />
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Tamanhos comuns:**
|
|
425
|
+
- `size-4` (16px) - Ícones inline em texto
|
|
426
|
+
- `size-5` (20px) - Botões pequenos
|
|
427
|
+
- `size-6` (24px) - Padrão para a maioria
|
|
428
|
+
- `size-8` (32px) - Ícones grandes em cards
|
|
429
|
+
- `size-12` (48px) - Ícones em heroes
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## SHADCN UI
|
|
434
|
+
|
|
435
|
+
### **Componentes Instalados**
|
|
436
|
+
Ver lista completa em: `/src/components/ui/`
|
|
437
|
+
|
|
438
|
+
Principais:
|
|
439
|
+
- `accordion`, `alert`, `avatar`, `badge`, `button`, `card`
|
|
440
|
+
- `checkbox`, `dialog`, `dropdown-menu`, `form`, `input`
|
|
441
|
+
- `carousel`, `popover`, `scroll-area`, `select`, `tabs`
|
|
442
|
+
- E muitos outros...
|
|
443
|
+
|
|
444
|
+
### **MCP para Shadcn**
|
|
445
|
+
**Usar funções MCP para consultar/instalar:**
|
|
446
|
+
```
|
|
447
|
+
mcp__shadcn-ui__list-components → Listar todos
|
|
448
|
+
mcp__shadcn-ui__get-component-docs → Ver docs
|
|
449
|
+
mcp__shadcn-ui__install-component → Instalar novo
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### **Componentes Customizados (Horizon UI)**
|
|
453
|
+
|
|
454
|
+
**Path:** `/src/components/ui/horizon-ui/`
|
|
455
|
+
|
|
456
|
+
**Componentes disponíveis:**
|
|
457
|
+
- `Dots` - Pontinhos de navegação para carousels
|
|
458
|
+
- Outros componentes customizados do projeto
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## ESTRUTURA DE ARQUIVOS
|
|
463
|
+
|
|
464
|
+
### **Páginas Simples**
|
|
465
|
+
```
|
|
466
|
+
/app/(marketing)/(pages)/[pagina]/
|
|
467
|
+
├── page.tsx # Só importa componentes
|
|
468
|
+
└── components/
|
|
469
|
+
├── SecaoA.tsx
|
|
470
|
+
├── SecaoB.tsx
|
|
471
|
+
└── ...
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### **Páginas Complexas (Home, etc)**
|
|
475
|
+
```
|
|
476
|
+
/app/(marketing)/(pages)/home/
|
|
477
|
+
├── page.tsx # Só importa seções
|
|
478
|
+
└── sections/
|
|
479
|
+
├── hero/
|
|
480
|
+
│ ├── HeroSection.tsx
|
|
481
|
+
│ ├── hero-data.ts
|
|
482
|
+
│ ├── HeroCard.tsx # Se tiver cards
|
|
483
|
+
│ └── index.ts
|
|
484
|
+
├── categories/
|
|
485
|
+
│ ├── CategoriesSection.tsx
|
|
486
|
+
│ ├── categories-data.ts
|
|
487
|
+
│ ├── CategoryCard.tsx
|
|
488
|
+
│ └── index.ts
|
|
489
|
+
└── ...
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
**Regras:**
|
|
493
|
+
- Sempre separar dados em `*-data.ts`
|
|
494
|
+
- Sempre separar cards em arquivo próprio
|
|
495
|
+
- Sempre exportar via `index.ts`
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## PADRÕES DE SEÇÕES
|
|
500
|
+
|
|
501
|
+
### **Padding de Seções**
|
|
502
|
+
|
|
503
|
+
**Padding padrão:**
|
|
504
|
+
```tsx
|
|
505
|
+
className="py-24" // 24px top + 24px bottom = padrão
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
**Seções coladas (mesmo fundo, sem divisão):**
|
|
509
|
+
|
|
510
|
+
Quando duas seções estão coladas sem divisão visual (mesmo background, sem traço/separator):
|
|
511
|
+
- Juntas teriam: `24px + 24px = 48px` de gap (MUITO!)
|
|
512
|
+
- **Solução**: Compensar o padding entre elas
|
|
513
|
+
|
|
514
|
+
```tsx
|
|
515
|
+
// ERRADO - Gap de 48px entre seções coladas:
|
|
516
|
+
<section className="py-24 bg-surface">...</section>
|
|
517
|
+
<section className="py-24 bg-surface">...</section>
|
|
518
|
+
|
|
519
|
+
// CORRETO - Gap de 24px compensado:
|
|
520
|
+
<section className="py-24 pb-12 bg-surface">...</section>
|
|
521
|
+
<section className="pt-12 py-24 bg-surface">...</section>
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
**Lógica:**
|
|
525
|
+
- Primeira seção: `pb-12` (reduz padding-bottom)
|
|
526
|
+
- Segunda seção: `pt-12` (reduz padding-top)
|
|
527
|
+
- Total entre elas: `12px + 12px = 24px`
|
|
528
|
+
|
|
529
|
+
### **Estrutura Padrão de Seção**
|
|
530
|
+
|
|
531
|
+
```tsx
|
|
532
|
+
export function MinhaSecao() {
|
|
533
|
+
return (
|
|
534
|
+
<section className="py-24 bg-surface/30">
|
|
535
|
+
<div className="container">
|
|
536
|
+
<div className="flex flex-col gap-8">
|
|
537
|
+
|
|
538
|
+
{/* Header */}
|
|
539
|
+
<div className="flex flex-col gap-2">
|
|
540
|
+
<h2 className="type-headline leading-tight leading-trim text-2xl md:text-3xl lg:text-4xl">
|
|
541
|
+
Título da Seção
|
|
542
|
+
</h2>
|
|
543
|
+
<p className="type-body leading-normal leading-trim text-muted-foreground text-lg">
|
|
544
|
+
Descrição da seção
|
|
545
|
+
</p>
|
|
546
|
+
</div>
|
|
547
|
+
|
|
548
|
+
{/* Content */}
|
|
549
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
550
|
+
{/* Cards ou conteúdo aqui */}
|
|
551
|
+
</div>
|
|
552
|
+
|
|
553
|
+
</div>
|
|
554
|
+
</div>
|
|
555
|
+
</section>
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### **ERRADO vs CORRETO**
|
|
561
|
+
|
|
562
|
+
#### **1. Header de Seção**
|
|
563
|
+
|
|
564
|
+
```tsx
|
|
565
|
+
// ERRADO - margin-bottom entre elementos:
|
|
566
|
+
<div className="mb-8">
|
|
567
|
+
<h2 className="text-3xl font-bold mb-3">Título</h2>
|
|
568
|
+
<p className="text-muted-foreground">Descrição</p>
|
|
569
|
+
</div>
|
|
570
|
+
<div>Conteúdo...</div>
|
|
571
|
+
|
|
572
|
+
// CORRETO - gap entre elementos:
|
|
573
|
+
<div className="flex flex-col gap-8">
|
|
574
|
+
<div className="flex flex-col gap-2">
|
|
575
|
+
<h2 className="type-headline leading-tight leading-trim text-2xl md:text-3xl lg:text-4xl">
|
|
576
|
+
Título
|
|
577
|
+
</h2>
|
|
578
|
+
<p className="type-body leading-normal leading-trim text-muted-foreground text-lg">
|
|
579
|
+
Descrição
|
|
580
|
+
</p>
|
|
581
|
+
</div>
|
|
582
|
+
<div>Conteúdo...</div>
|
|
583
|
+
</div>
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
**Regras do Header:**
|
|
587
|
+
- Header e content separados com `gap-8`
|
|
588
|
+
- Título de seção ABERTA usa `type-headline` (não `type-title`!)
|
|
589
|
+
- Título de seção ENCAIXOTADA (dentro de box) usa `type-title`
|
|
590
|
+
- Título e descrição separados com `gap-2` (não muito afastados!)
|
|
591
|
+
- NUNCA usar `margin-bottom`, SEMPRE `gap`
|
|
592
|
+
|
|
593
|
+
**Overlines em Headers:**
|
|
594
|
+
- **Sempre usar `gap-2`** entre overline, título e descrição
|
|
595
|
+
- **Seções comuns**: Usar componente `<Overline>` padrão
|
|
596
|
+
```tsx
|
|
597
|
+
<div className="flex flex-col gap-2">
|
|
598
|
+
<Overline variant="accent">Destaques</Overline>
|
|
599
|
+
<h2 className="type-headline...">Título</h2>
|
|
600
|
+
<p className="type-body...">Descrição</p>
|
|
601
|
+
</div>
|
|
602
|
+
```
|
|
603
|
+
- **Seções criativas** (quando solicitado algo mais criativo):
|
|
604
|
+
- Variar: só ícone, ícone + texto, só texto
|
|
605
|
+
- Usar `type-overline` sem componente (sem "caixa")
|
|
606
|
+
- Adicionar detalhes decorativos ao redor
|
|
607
|
+
```tsx
|
|
608
|
+
<div className="flex flex-col gap-2">
|
|
609
|
+
<div className="flex items-center gap-2">
|
|
610
|
+
<Icon className="size-4 text-primary" />
|
|
611
|
+
<span className="type-overline">Destaques</span>
|
|
612
|
+
</div>
|
|
613
|
+
<h2 className="type-headline...">Título</h2>
|
|
614
|
+
</div>
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
#### **2. Tipografia**
|
|
618
|
+
|
|
619
|
+
```tsx
|
|
620
|
+
// ERRADO - sem type, leading, e leading-trim:
|
|
621
|
+
<h2 className="text-3xl md:text-4xl font-bold">
|
|
622
|
+
|
|
623
|
+
// CORRETO - seção ABERTA usa headline + leading + leading-trim + escala:
|
|
624
|
+
<h2 className="type-headline leading-tight leading-trim text-2xl md:text-3xl lg:text-4xl">
|
|
625
|
+
|
|
626
|
+
// CORRETO - card e seções ENCAIXOTADAS usam title:
|
|
627
|
+
<h3 className="type-title leading-tight leading-trim text-xl md:text-2xl">
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
#### **3. Grid de Cards**
|
|
631
|
+
|
|
632
|
+
```tsx
|
|
633
|
+
// Grid responsivo padrão:
|
|
634
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
635
|
+
{items.map(item => <Card key={item.id} {...item} />)}
|
|
636
|
+
</div>
|
|
637
|
+
|
|
638
|
+
// Grid com 4 colunas desktop:
|
|
639
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
---
|
|
643
|
+
|
|
644
|
+
## CAROUSELS
|
|
645
|
+
|
|
646
|
+
### **SEMPRE USAR COMPONENTE CAROUSEL DO SHADCN**
|
|
647
|
+
- **OBRIGATÓRIO**: Usar `<Carousel>` de `/components/ui/carousel`
|
|
648
|
+
- **PROIBIDO**: Implementar Embla diretamente (usar componente existente!)
|
|
649
|
+
- Sempre usar Dots de `/components/ui/horizon-ui/dots`
|
|
650
|
+
|
|
651
|
+
### **Padrão Correto:**
|
|
652
|
+
```tsx
|
|
653
|
+
import { Carousel, CarouselContent, CarouselItem, type CarouselApi } from "@/components/ui/carousel";
|
|
654
|
+
import Autoplay from "embla-carousel-autoplay";
|
|
655
|
+
import { Dots } from "@/components/ui/horizon-ui/dots";
|
|
656
|
+
import { useCarouselController } from "@/hooks/use-carousel-controller";
|
|
657
|
+
|
|
658
|
+
const [api, setApi] = useState<CarouselApi>();
|
|
659
|
+
const controller = useCarouselController(api);
|
|
660
|
+
|
|
661
|
+
<Carousel
|
|
662
|
+
setApi={setApi}
|
|
663
|
+
opts={{ align: "start", loop: true }}
|
|
664
|
+
plugins={[Autoplay({ delay: 4000, stopOnInteraction: false })]}
|
|
665
|
+
>
|
|
666
|
+
<CarouselContent className="-ml-4 md:-ml-6">
|
|
667
|
+
{items.map((item) => (
|
|
668
|
+
<CarouselItem key={item.id} className="pl-4 md:pl-6 basis-1/2 md:basis-1/3 lg:basis-1/4">
|
|
669
|
+
<Card {...item} />
|
|
670
|
+
</CarouselItem>
|
|
671
|
+
))}
|
|
672
|
+
</CarouselContent>
|
|
673
|
+
</Carousel>
|
|
674
|
+
|
|
675
|
+
<Dots api={api} variant="line" size="md" />
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
**Regras do Padrão Shadcn:**
|
|
679
|
+
- `CarouselContent` → `-ml-4 md:-ml-6` (margin negativo)
|
|
680
|
+
- `CarouselItem` → `pl-4 md:pl-6` (padding)
|
|
681
|
+
- `basis-*` → Controla quantos por vez (1/2, 1/3, 1/4)
|
|
682
|
+
- `useCarouselController` → Para botões customizados
|
|
683
|
+
|
|
684
|
+
---
|
|
685
|
+
|
|
686
|
+
## CHECKLIST ANTES DE ENTREGAR
|
|
687
|
+
|
|
688
|
+
### **Tipografia**
|
|
689
|
+
- [ ] Títulos de seção ABERTA usam `type-headline` (não `type-title`)?
|
|
690
|
+
- [ ] Títulos de card e seções ENCAIXOTADAS usam `type-title`?
|
|
691
|
+
- [ ] Page Headers usam `type-headline`?
|
|
692
|
+
- [ ] Todos os textos têm `leading-*` + `leading-trim`?
|
|
693
|
+
- [ ] Headings têm pelo menos 2 breakpoints de tamanho?
|
|
694
|
+
- [ ] Mobile começa legível (não muito grande)?
|
|
695
|
+
- [ ] Proporções mantidas em todos os breakpoints?
|
|
696
|
+
|
|
697
|
+
### **Layout**
|
|
698
|
+
- [ ] ZERO `margin-bottom` ou `mb-*` NO CÓDIGO INTEIRO?
|
|
699
|
+
- [ ] Header separado de content com `gap-8`?
|
|
700
|
+
- [ ] Título e descrição dentro do header com `gap-2`?
|
|
701
|
+
- [ ] Todos os espaçamentos usando `gap` (não `margin`)?
|
|
702
|
+
- [ ] Container usado corretamente?
|
|
703
|
+
- [ ] Padding de seções: `py-24` padrão?
|
|
704
|
+
- [ ] Seções coladas compensadas: `pb-12` e `pt-12`?
|
|
705
|
+
|
|
706
|
+
### **Componentização**
|
|
707
|
+
- [ ] Cards em arquivo separado?
|
|
708
|
+
- [ ] Dados em arquivo separado (`*-data.ts`)?
|
|
709
|
+
- [ ] Exportado via `index.ts`?
|
|
710
|
+
|
|
711
|
+
### **Responsividade**
|
|
712
|
+
- [ ] Testei mobile, tablet e desktop?
|
|
713
|
+
- [ ] Grid responsivo configurado?
|
|
714
|
+
- [ ] Imagens com aspect-ratio correto?
|
|
715
|
+
|
|
716
|
+
### **Interatividade**
|
|
717
|
+
- [ ] Todos os hovers funcionam?
|
|
718
|
+
- [ ] Animações suaves (`transition-all duration-300`)?
|
|
719
|
+
- [ ] Estados disabled/loading tratados?
|
|
720
|
+
|
|
721
|
+
### **Acessibilidade**
|
|
722
|
+
- [ ] Imagens com `alt` text?
|
|
723
|
+
- [ ] Botões com labels claros?
|
|
724
|
+
- [ ] Cores com contraste suficiente?
|
|
725
|
+
|
|
726
|
+
### **Carousel (se aplicável)**
|
|
727
|
+
- [ ] Embla configurado corretamente?
|
|
728
|
+
- [ ] Dots component adicionado?
|
|
729
|
+
- [ ] Responsividade configurada?
|
|
730
|
+
- [ ] Autoplay configurado se necessário?
|
|
731
|
+
|
|
732
|
+
---
|
|
733
|
+
|
|
734
|
+
## EXEMPLO COMPLETO
|
|
735
|
+
|
|
736
|
+
<details>
|
|
737
|
+
<summary><strong>Ver exemplo completo de seção</strong></summary>
|
|
738
|
+
|
|
739
|
+
```tsx
|
|
740
|
+
// sections/destaque/DestaqueSection.tsx
|
|
741
|
+
"use client";
|
|
742
|
+
|
|
743
|
+
import useEmblaCarousel from "embla-carousel-react";
|
|
744
|
+
import Autoplay from "embla-carousel-autoplay";
|
|
745
|
+
import { useState, useEffect } from "react";
|
|
746
|
+
import type { CarouselApi } from "@/components/ui/carousel";
|
|
747
|
+
import { Dots } from "@/components/ui/horizon-ui/dots";
|
|
748
|
+
import { ChevronRight } from "lucide-react";
|
|
749
|
+
import { destaques } from "./destaque-data";
|
|
750
|
+
import { DestaqueCard } from "./DestaqueCard";
|
|
751
|
+
|
|
752
|
+
export function DestaqueSection() {
|
|
753
|
+
const [emblaApi, setEmblaApi] = useState<CarouselApi>();
|
|
754
|
+
|
|
755
|
+
const [emblaRef, emblaApiInstance] = useEmblaCarousel(
|
|
756
|
+
{ loop: true, align: "start" },
|
|
757
|
+
[Autoplay({ delay: 4000, stopOnInteraction: false })]
|
|
758
|
+
);
|
|
759
|
+
|
|
760
|
+
useEffect(() => {
|
|
761
|
+
if (emblaApiInstance) setEmblaApi(emblaApiInstance);
|
|
762
|
+
}, [emblaApiInstance]);
|
|
763
|
+
|
|
764
|
+
return (
|
|
765
|
+
<section className="py-24 bg-surface/30">
|
|
766
|
+
<div className="container">
|
|
767
|
+
<div className="flex flex-col gap-8">
|
|
768
|
+
|
|
769
|
+
{/* Header */}
|
|
770
|
+
<div className="flex flex-col gap-2">
|
|
771
|
+
<h2 className="type-headline leading-tight leading-trim text-2xl md:text-3xl lg:text-4xl">
|
|
772
|
+
Imóveis em Destaque
|
|
773
|
+
</h2>
|
|
774
|
+
<p className="type-body leading-normal leading-trim text-muted-foreground text-lg">
|
|
775
|
+
Confira nossa seleção especial
|
|
776
|
+
</p>
|
|
777
|
+
</div>
|
|
778
|
+
|
|
779
|
+
{/* Carousel + Dots */}
|
|
780
|
+
<div className="flex flex-col gap-6">
|
|
781
|
+
<div className="overflow-hidden" ref={emblaRef}>
|
|
782
|
+
<div className="flex">
|
|
783
|
+
{destaques.map((item) => (
|
|
784
|
+
<div
|
|
785
|
+
key={item.id}
|
|
786
|
+
className="flex-[0_0_100%] md:flex-[0_0_50%] lg:flex-[0_0_33.333%] min-w-0 pr-6"
|
|
787
|
+
>
|
|
788
|
+
<DestaqueCard {...item} />
|
|
789
|
+
</div>
|
|
790
|
+
))}
|
|
791
|
+
</div>
|
|
792
|
+
</div>
|
|
793
|
+
|
|
794
|
+
<Dots api={emblaApi} variant="line" size="md" />
|
|
795
|
+
</div>
|
|
796
|
+
|
|
797
|
+
{/* CTA */}
|
|
798
|
+
<div className="text-center">
|
|
799
|
+
<a
|
|
800
|
+
href="/imoveis"
|
|
801
|
+
className="inline-flex items-center gap-2 text-primary type-button leading-trim font-semibold hover:gap-3 transition-all duration-300"
|
|
802
|
+
>
|
|
803
|
+
Ver Todos os Imóveis
|
|
804
|
+
<ChevronRight className="size-5" />
|
|
805
|
+
</a>
|
|
806
|
+
</div>
|
|
807
|
+
|
|
808
|
+
</div>
|
|
809
|
+
</div>
|
|
810
|
+
</section>
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// sections/destaque/DestaqueCard.tsx
|
|
815
|
+
export function DestaqueCard({ image, title, price }: DestaqueCardProps) {
|
|
816
|
+
return (
|
|
817
|
+
<div className="group rounded-2xl overflow-hidden shadow-lg hover:shadow-2xl transition-all duration-300">
|
|
818
|
+
<div className="aspect-[4/3] relative overflow-hidden">
|
|
819
|
+
<img
|
|
820
|
+
src={image}
|
|
821
|
+
alt={title}
|
|
822
|
+
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
|
|
823
|
+
/>
|
|
824
|
+
</div>
|
|
825
|
+
<div className="p-6 flex flex-col gap-3">
|
|
826
|
+
<h3 className="type-title leading-tight leading-trim text-xl group-hover:text-primary transition-colors">
|
|
827
|
+
{title}
|
|
828
|
+
</h3>
|
|
829
|
+
<p className="type-headline leading-tight leading-trim text-2xl text-primary font-bold">
|
|
830
|
+
{price}
|
|
831
|
+
</p>
|
|
832
|
+
</div>
|
|
833
|
+
</div>
|
|
834
|
+
);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// sections/destaque/destaque-data.ts
|
|
838
|
+
export interface Destaque {
|
|
839
|
+
id: number;
|
|
840
|
+
image: string;
|
|
841
|
+
title: string;
|
|
842
|
+
price: string;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
export const destaques: Destaque[] = [
|
|
846
|
+
{
|
|
847
|
+
id: 1,
|
|
848
|
+
image: "https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=600&q=80",
|
|
849
|
+
title: "Apartamento Moderno",
|
|
850
|
+
price: "R$ 850.000",
|
|
851
|
+
},
|
|
852
|
+
// ...
|
|
853
|
+
];
|
|
854
|
+
|
|
855
|
+
// sections/destaque/index.ts
|
|
856
|
+
export { DestaqueSection } from "./DestaqueSection";
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
</details>
|
|
860
|
+
|
|
861
|
+
---
|
|
862
|
+
|
|
863
|
+
## DESIGN SYSTEM
|
|
864
|
+
|
|
865
|
+
### **Biblioteca de Seções Base**
|
|
866
|
+
|
|
867
|
+
Este projeto inclui um Design System completo com 15 seções base prontas para uso.
|
|
868
|
+
|
|
869
|
+
**Localização:** `/src/design/sections-base/`
|
|
870
|
+
|
|
871
|
+
**Categorias disponíveis:**
|
|
872
|
+
- **Heroes** (4 variantes): hero-centered, hero-split, hero-fullscreen, hero-minimal
|
|
873
|
+
- **Features** (4 variantes): features-grid-3, features-list, features-carousel, features-comparison
|
|
874
|
+
- **CTAs** (3 variantes): cta-centered, cta-split, cta-banner
|
|
875
|
+
- **Galleries** (2 variantes): gallery-grid, gallery-masonry
|
|
876
|
+
- **Testimonials** (1): testimonials-carousel
|
|
877
|
+
- **Stats** (1): stats-simple
|
|
878
|
+
|
|
879
|
+
### **Como Usar Seções Base**
|
|
880
|
+
|
|
881
|
+
```tsx
|
|
882
|
+
// Importar seção base
|
|
883
|
+
import { HeroCentered } from "@/design/sections-base/heroes/hero-centered";
|
|
884
|
+
|
|
885
|
+
// Usar diretamente
|
|
886
|
+
<HeroCentered />
|
|
887
|
+
|
|
888
|
+
// Ou customizar os dados
|
|
889
|
+
import { heroCenteredData } from "@/design/sections-base/heroes/hero-centered";
|
|
890
|
+
|
|
891
|
+
// Modificar dados conforme necessário
|
|
892
|
+
const customData = {
|
|
893
|
+
...heroCenteredData,
|
|
894
|
+
title: "Meu título customizado",
|
|
895
|
+
};
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
### **Placeholders Criativos**
|
|
899
|
+
|
|
900
|
+
Use enquanto não tem assets reais:
|
|
901
|
+
|
|
902
|
+
```tsx
|
|
903
|
+
import { ImagePlaceholder, VideoPlaceholder } from "@/design/creative/placeholders";
|
|
904
|
+
|
|
905
|
+
<ImagePlaceholder aspectRatio="4/3" showLabel />
|
|
906
|
+
<VideoPlaceholder aspectRatio="16/9" />
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
### **Storybook**
|
|
910
|
+
|
|
911
|
+
Visualize todas as seções no Storybook:
|
|
912
|
+
```bash
|
|
913
|
+
pnpm storybook
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
Navegue até: **"Design System / Catalog Overview"**
|
|
917
|
+
|
|
918
|
+
### **Páginas Demonstrativas**
|
|
919
|
+
|
|
920
|
+
Acesse: `http://localhost:3000/design`
|
|
921
|
+
|
|
922
|
+
15 páginas demonstrativas completas organizadas por categoria.
|
|
923
|
+
|
|
924
|
+
### **Documentação Completa**
|
|
925
|
+
|
|
926
|
+
Ver: `/docs/design-system-guide.md`
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
**Última atualização:** 2025-10-25
|