pswex-design-system 7.0.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/LICENSE.md +16 -0
- package/README.md +67 -0
- package/bin/instalar.mjs +62 -0
- package/package.json +31 -0
- package/skill/README.md +57 -0
- package/skill/SKILL.md +117 -0
- package/skill/assets/PROMPT-FIGMA.md +138 -0
- package/skill/assets/catalogo-icones.json +324 -0
- package/skill/assets/figma-variables.json +764 -0
- package/skill/assets/manifesto.json +1287 -0
- package/skill/assets/pswex.tokens.json +694 -0
- package/skill/assets/styles.css +381 -0
- package/skill/assets/tokens.css +81 -0
- package/skill/references/classes.md +27 -0
- package/skill/references/componentes.md +628 -0
- package/skill/references/cor.md +166 -0
- package/skill/references/fundos.md +43 -0
- package/skill/references/icones.md +71 -0
- package/skill/references/voz.md +76 -0
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
# Componentes
|
|
2
|
+
|
|
3
|
+
36 no total, todos em `window.PSWEX`.
|
|
4
|
+
O tipo completo de cada um está em `componentes/tipos/<Nome>.d.ts`.
|
|
5
|
+
|
|
6
|
+
### Fundamentos
|
|
7
|
+
|
|
8
|
+
#### EscalaTipografica
|
|
9
|
+
|
|
10
|
+
Gilroy em cinco pesos, escala em clamp, sem breakpoint.
|
|
11
|
+
|
|
12
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
13
|
+
|---|---|---|---|
|
|
14
|
+
| `className` | `string` | não | |
|
|
15
|
+
|
|
16
|
+
```jsx
|
|
17
|
+
<EscalaTipografica />
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
#### Icone
|
|
21
|
+
|
|
22
|
+
Catálogo de 72 ícones de traço: um para cada um dos 14 serviços, um para cada uma das 12 campanhas, e 20 de interface. Os que terminam em `-compact` são a versão simplificada, para 20px ou menos.
|
|
23
|
+
|
|
24
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| `nome` | um dos 72 nomes do catálogo, lista na seção Ícones | sim | Nome do ícone no catálogo. O sufixo `-compact` é a versão simplificada, para 20px ou menos. |
|
|
27
|
+
| `tamanho` | `number` | não | Lado do quadrado, em px. O traço não engrossa junto, por isso 24 é o tamanho de desenho. |
|
|
28
|
+
| `titulo` | `string` | não | Rótulo para leitor de tela. Sem ele o ícone é tratado como decoração. |
|
|
29
|
+
| `className` | `string` | não | |
|
|
30
|
+
| `id` | `string` | não | |
|
|
31
|
+
| `style` | `React.CSSProperties` | não | |
|
|
32
|
+
|
|
33
|
+
```jsx
|
|
34
|
+
<Icone nome="agentes-ia" tamanho={26} />
|
|
35
|
+
<Icone nome="whatsapp-chat" tamanho={18} titulo="Falar no WhatsApp" />
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### PaletaMarca
|
|
39
|
+
|
|
40
|
+
As dez cores da identidade, iguais nos dois temas.
|
|
41
|
+
|
|
42
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| `className` | `string` | não | |
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
<PaletaMarca />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### PaletaSemantica
|
|
51
|
+
|
|
52
|
+
Os tokens de papel na tela, que invertem no tema escuro.
|
|
53
|
+
|
|
54
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| `className` | `string` | não | |
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
<PaletaSemantica />
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Componentes
|
|
63
|
+
|
|
64
|
+
#### Btn
|
|
65
|
+
|
|
66
|
+
Botão pílula em três variantes.
|
|
67
|
+
|
|
68
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| `variante` | `"cta" \| "red" \| "ghost"` | não | `cta` é o lime, usado para conversão e só uma vez por tela. `red` é o vermelho da marca. `ghost` é contorno, para ação secundária. |
|
|
71
|
+
| `href` | `string` | não | Destino do link. O componente renderiza um `<a>`, então href é o que torna o botão clicável. |
|
|
72
|
+
| `target` | `string` | não | |
|
|
73
|
+
| `rel` | `string` | não | |
|
|
74
|
+
| `children` | `React.ReactNode` | não | |
|
|
75
|
+
| `className` | `string` | não | |
|
|
76
|
+
| `id` | `string` | não | |
|
|
77
|
+
| `style` | `React.CSSProperties` | não | |
|
|
78
|
+
|
|
79
|
+
```jsx
|
|
80
|
+
<Btn variante="cta" href="#contato">Falar no WhatsApp</Btn>
|
|
81
|
+
<Btn variante="ghost" href="/projetos">Ver projetos</Btn>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Card
|
|
85
|
+
|
|
86
|
+
Card de conteúdo com eyebrow, título, apoio e link.
|
|
87
|
+
|
|
88
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
89
|
+
|---|---|---|---|
|
|
90
|
+
| `icone` | um dos 72 nomes do catálogo, lista na seção Ícones | não | Ícone do catálogo, acima do eyebrow. É o que tira o card de ser só texto. Ver Icone para a lista. |
|
|
91
|
+
| `eyebrow` | `React.ReactNode` | não | |
|
|
92
|
+
| `titulo` | `React.ReactNode` | sim | |
|
|
93
|
+
| `texto` | `React.ReactNode` | não | Texto de apoio do card. |
|
|
94
|
+
| `href` | `string` | não | Quando existe, o card inteiro vira link e ganha o hover de elevação. |
|
|
95
|
+
| `linkTexto` | `React.ReactNode` | não | Rótulo do link de texto no pé do card. |
|
|
96
|
+
| `className` | `string` | não | |
|
|
97
|
+
|
|
98
|
+
```jsx
|
|
99
|
+
<Card
|
|
100
|
+
eyebrow="Serviço"
|
|
101
|
+
titulo="Agentes de IA"
|
|
102
|
+
texto="Atendimento que responde na hora e não deixa lead esfriar."
|
|
103
|
+
href="/agentes-de-ia"
|
|
104
|
+
linkTexto="Ver como funciona"
|
|
105
|
+
/>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### Cards
|
|
109
|
+
|
|
110
|
+
Grade fluida de cards, 2, 3 ou 4 colunas.
|
|
111
|
+
|
|
112
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| `colunas` | `2 \| 3 \| 4` | não | Número de colunas alvo. A grade é fluida e quebra sozinha no mobile. |
|
|
115
|
+
| `children` | `React.ReactNode` | não | |
|
|
116
|
+
| `className` | `string` | não | |
|
|
117
|
+
| `id` | `string` | não | |
|
|
118
|
+
| `style` | `React.CSSProperties` | não | |
|
|
119
|
+
|
|
120
|
+
```jsx
|
|
121
|
+
<Cards colunas={3}>
|
|
122
|
+
<Card titulo="Sites" texto="Página que carrega rápido e converte." />
|
|
123
|
+
</Cards>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### Caso
|
|
127
|
+
|
|
128
|
+
Card de caso com tag de categoria.
|
|
129
|
+
|
|
130
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
131
|
+
|---|---|---|---|
|
|
132
|
+
| `icone` | um dos 72 nomes do catálogo, lista na seção Ícones | não | Ícone do catálogo, acima da tag. Ver Icone para a lista. |
|
|
133
|
+
| `tag` | `React.ReactNode` | não | Rótulo do setor ou do tipo de trabalho. |
|
|
134
|
+
| `titulo` | `React.ReactNode` | sim | |
|
|
135
|
+
| `texto` | `React.ReactNode` | não | |
|
|
136
|
+
| `className` | `string` | não | |
|
|
137
|
+
|
|
138
|
+
```jsx
|
|
139
|
+
<Caso tag="Autoescola" titulo="Clube Líder" texto="O que era feito à mão virou fila automática." />
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Eyebrow
|
|
143
|
+
|
|
144
|
+
Rótulo curto em caixa alta acima do título.
|
|
145
|
+
|
|
146
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
147
|
+
|---|---|---|---|
|
|
148
|
+
| `children` | `React.ReactNode` | não | |
|
|
149
|
+
| `className` | `string` | não | |
|
|
150
|
+
| `id` | `string` | não | |
|
|
151
|
+
| `style` | `React.CSSProperties` | não | |
|
|
152
|
+
|
|
153
|
+
```jsx
|
|
154
|
+
<Eyebrow>Belo Horizonte</Eyebrow>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Faq
|
|
158
|
+
|
|
159
|
+
Item de FAQ em details.
|
|
160
|
+
|
|
161
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
162
|
+
|---|---|---|---|
|
|
163
|
+
| `pergunta` | `React.ReactNode` | sim | |
|
|
164
|
+
| `children` | `React.ReactNode` | não | |
|
|
165
|
+
| `aberto` | `boolean` | não | Deixa o item aberto no primeiro render. |
|
|
166
|
+
| `className` | `string` | não | |
|
|
167
|
+
|
|
168
|
+
```jsx
|
|
169
|
+
<Faq pergunta="Em quanto tempo fica pronto?">Depende do escopo. A proposta traz o prazo fechado.</Faq>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Field
|
|
173
|
+
|
|
174
|
+
Campo de formulário com label, controle e linha de erro.
|
|
175
|
+
|
|
176
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
177
|
+
|---|---|---|---|
|
|
178
|
+
| `label` | `React.ReactNode` | sim | Texto da label. |
|
|
179
|
+
| `nota` | `React.ReactNode` | não | Complemento da label, em peso leve. Serve para "opcional". |
|
|
180
|
+
| `nome` | `string` | sim | `id` e `name` do controle. |
|
|
181
|
+
| `tipo` | `unknown` | não | |
|
|
182
|
+
| `placeholder` | `string` | não | |
|
|
183
|
+
| `erro` | `React.ReactNode` | não | Mensagem de erro abaixo do campo. |
|
|
184
|
+
| `className` | `string` | não | |
|
|
185
|
+
|
|
186
|
+
```jsx
|
|
187
|
+
<Field nome="whatsapp" label="WhatsApp" tipo="tel" placeholder="(31) 99999-9999" />
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### Lead
|
|
191
|
+
|
|
192
|
+
Parágrafo de abertura, maior que o corpo.
|
|
193
|
+
|
|
194
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
195
|
+
|---|---|---|---|
|
|
196
|
+
| `children` | `React.ReactNode` | não | |
|
|
197
|
+
| `className` | `string` | não | |
|
|
198
|
+
| `id` | `string` | não | |
|
|
199
|
+
| `style` | `React.CSSProperties` | não | |
|
|
200
|
+
|
|
201
|
+
```jsx
|
|
202
|
+
<Lead>Seu time faz o trabalho. O processo faz o trabalho voltar.</Lead>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
#### PillList
|
|
206
|
+
|
|
207
|
+
Pílulas de navegação secundária.
|
|
208
|
+
|
|
209
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
210
|
+
|---|---|---|---|
|
|
211
|
+
| `itens` | `{ rotulo: React.ReactNode; href: string; }[]` | sim | Cada item vira uma pílula clicável. |
|
|
212
|
+
| `className` | `string` | não | |
|
|
213
|
+
|
|
214
|
+
```jsx
|
|
215
|
+
<PillList itens={[{rotulo:'Sites', href:'/sites'}, {rotulo:'Lojas virtuais', href:'/lojas'}]} />
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
#### Quote
|
|
219
|
+
|
|
220
|
+
Depoimento com régua vermelha e atribuição.
|
|
221
|
+
|
|
222
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
223
|
+
|---|---|---|---|
|
|
224
|
+
| `children` | `React.ReactNode` | não | A citação. |
|
|
225
|
+
| `autor` | `React.ReactNode` | não | Quem falou, e de onde. |
|
|
226
|
+
| `className` | `string` | não | |
|
|
227
|
+
|
|
228
|
+
```jsx
|
|
229
|
+
<Quote autor="Michele, clínica">
|
|
230
|
+
Resolveu a agenda que vivia dando choque de horário.
|
|
231
|
+
</Quote>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### Quotes
|
|
235
|
+
|
|
236
|
+
Grade fluida de depoimentos.
|
|
237
|
+
|
|
238
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
239
|
+
|---|---|---|---|
|
|
240
|
+
| `children` | `React.ReactNode` | não | |
|
|
241
|
+
| `className` | `string` | não | |
|
|
242
|
+
| `id` | `string` | não | |
|
|
243
|
+
| `style` | `React.CSSProperties` | não | |
|
|
244
|
+
|
|
245
|
+
```jsx
|
|
246
|
+
<Quotes><Quote autor="Bruno, climatização">Chegou lead no mesmo dia.</Quote></Quotes>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
#### Ratingbar
|
|
250
|
+
|
|
251
|
+
Faixa fina logo abaixo do hero, no navy mais escuro, com frases curtas de contexto.
|
|
252
|
+
|
|
253
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
254
|
+
|---|---|---|---|
|
|
255
|
+
| `estrelas` | `React.ReactNode` | não | Estrelas em texto. Vazio por padrão: nota de avaliação só entra com fonte conferida. |
|
|
256
|
+
| `destaque` | `React.ReactNode` | não | Trecho em negrito logo depois das estrelas. |
|
|
257
|
+
| `itens` | `React.ReactNode[]` | não | Frases curtas ao lado, separadas pelo próprio flex. |
|
|
258
|
+
| `className` | `string` | não | |
|
|
259
|
+
|
|
260
|
+
```jsx
|
|
261
|
+
<Ratingbar itens={["Mais de 10 anos fazendo tecnologia que vende", "Belo Horizonte, atendendo o Brasil inteiro"]} />
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### Reveal
|
|
265
|
+
|
|
266
|
+
Envelope de entrada: o conteúdo sobe 14px e aparece quando ganha a classe `in`.
|
|
267
|
+
|
|
268
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
269
|
+
|---|---|---|---|
|
|
270
|
+
| `visivel` | `boolean` | não | `true` já entra visível, que é o que o script do site faz ao cruzar a viewport. |
|
|
271
|
+
| `children` | `React.ReactNode` | não | |
|
|
272
|
+
| `className` | `string` | não | |
|
|
273
|
+
| `id` | `string` | não | |
|
|
274
|
+
| `style` | `React.CSSProperties` | não | |
|
|
275
|
+
|
|
276
|
+
```jsx
|
|
277
|
+
<Reveal visivel>
|
|
278
|
+
<SecHead titulo="Onde a gente já entregou" />
|
|
279
|
+
</Reveal>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### Row2
|
|
283
|
+
|
|
284
|
+
Duas colunas dentro do formulário.
|
|
285
|
+
|
|
286
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
287
|
+
|---|---|---|---|
|
|
288
|
+
| `children` | `React.ReactNode` | não | |
|
|
289
|
+
| `className` | `string` | não | |
|
|
290
|
+
| `id` | `string` | não | |
|
|
291
|
+
| `style` | `React.CSSProperties` | não | |
|
|
292
|
+
|
|
293
|
+
```jsx
|
|
294
|
+
<Row2><Field nome="nome" label="Nome" /><Field nome="email" label="E-mail" tipo="email" /></Row2>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### SecHead
|
|
298
|
+
|
|
299
|
+
Eyebrow, h2 e apoio, o cabeçalho de toda seção.
|
|
300
|
+
|
|
301
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
302
|
+
|---|---|---|---|
|
|
303
|
+
| `eyebrow` | `React.ReactNode` | não | Rótulo em caixa alta acima do título. |
|
|
304
|
+
| `titulo` | `React.ReactNode` | sim | Título da seção, sai como h2. |
|
|
305
|
+
| `apoio` | `React.ReactNode` | não | Linha de apoio abaixo do título. |
|
|
306
|
+
| `className` | `string` | não | |
|
|
307
|
+
|
|
308
|
+
```jsx
|
|
309
|
+
<SecHead
|
|
310
|
+
eyebrow="Projetos"
|
|
311
|
+
titulo="Onde a gente já entregou"
|
|
312
|
+
apoio="Cliente com nome, setor e o que foi feito."
|
|
313
|
+
/>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
#### Selos
|
|
317
|
+
|
|
318
|
+
Pílulas de contorno para credencial e localização.
|
|
319
|
+
|
|
320
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
321
|
+
|---|---|---|---|
|
|
322
|
+
| `itens` | `React.ReactNode[]` | sim | Credencial, localização, CNPJ, o que for verificável. |
|
|
323
|
+
| `className` | `string` | não | |
|
|
324
|
+
|
|
325
|
+
```jsx
|
|
326
|
+
<Selos itens={['Belo Horizonte', 'CNPJ 28.477.119/0001-79', 'Google Ads AI']} />
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
#### SkipLink
|
|
330
|
+
|
|
331
|
+
Atalho de teclado para pular a navegação e cair no conteúdo.
|
|
332
|
+
|
|
333
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
334
|
+
|---|---|---|---|
|
|
335
|
+
| `children` | `React.ReactNode` | não | |
|
|
336
|
+
| `className` | `string` | não | |
|
|
337
|
+
| `id` | `string` | não | |
|
|
338
|
+
| `style` | `React.CSSProperties` | não | |
|
|
339
|
+
|
|
340
|
+
```jsx
|
|
341
|
+
<SkipLink href="#conteudo">Ir para o conteúdo</SkipLink>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### StepsList
|
|
345
|
+
|
|
346
|
+
Método numerado, com a numeração vinda do CSS.
|
|
347
|
+
|
|
348
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
349
|
+
|---|---|---|---|
|
|
350
|
+
| `passos` | `PassoProps[]` | sim | |
|
|
351
|
+
| `className` | `string` | não | |
|
|
352
|
+
|
|
353
|
+
```jsx
|
|
354
|
+
<StepsList passos={[
|
|
355
|
+
{titulo:'Elimina', texto:'O que não precisa existir sai.'},
|
|
356
|
+
{titulo:'Simplifica', texto:'O que sobra fica com menos passo.'},
|
|
357
|
+
]} />
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### Ticks
|
|
361
|
+
|
|
362
|
+
Lista de checagem com marcador redondo.
|
|
363
|
+
|
|
364
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
365
|
+
|---|---|---|---|
|
|
366
|
+
| `itens` | `React.ReactNode[]` | sim | Itens da lista. |
|
|
367
|
+
| `positivo` | `boolean` | não | `false` troca o marcador para o X em fundo rosa claro. |
|
|
368
|
+
| `className` | `string` | não | |
|
|
369
|
+
|
|
370
|
+
```jsx
|
|
371
|
+
<Ticks itens={['Hospedagem inclusa', 'Open Graph em todas as páginas']} />
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
#### TxtLink
|
|
375
|
+
|
|
376
|
+
Link de texto com sublinhado no hover.
|
|
377
|
+
|
|
378
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
379
|
+
|---|---|---|---|
|
|
380
|
+
| `href` | `string` | não | Destino do link. O componente renderiza um `<a>`. |
|
|
381
|
+
| `target` | `string` | não | |
|
|
382
|
+
| `rel` | `string` | não | |
|
|
383
|
+
| `children` | `React.ReactNode` | não | |
|
|
384
|
+
| `className` | `string` | não | |
|
|
385
|
+
| `id` | `string` | não | |
|
|
386
|
+
| `style` | `React.CSSProperties` | não | |
|
|
387
|
+
|
|
388
|
+
```jsx
|
|
389
|
+
<TxtLink href="/servicos">Ver todos os serviços</TxtLink>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
#### Vid
|
|
393
|
+
|
|
394
|
+
Depoimento em vídeo em proporção 16 por 10, com o nome de quem fala sobreposto embaixo.
|
|
395
|
+
|
|
396
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
397
|
+
|---|---|---|---|
|
|
398
|
+
| `src` | `string` | não | |
|
|
399
|
+
| `placeholder` | `React.ReactNode` | não | Texto mostrado no lugar do player enquanto não existe arquivo de vídeo. |
|
|
400
|
+
| `poster` | `string` | não | Imagem que aparece antes do play. |
|
|
401
|
+
| `legenda` | `React.ReactNode` | não | Nome e contexto de quem fala, sobre um véu escuro no rodapé. |
|
|
402
|
+
| `className` | `string` | não | |
|
|
403
|
+
|
|
404
|
+
```jsx
|
|
405
|
+
<Vid src="/depoimentos/bruno.mp4" poster="/depoimentos/bruno.jpg" legenda="Bruno, Climatização" />
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Blocos
|
|
409
|
+
|
|
410
|
+
#### Footer
|
|
411
|
+
|
|
412
|
+
Rodapé no navy mais escuro. Coluna da marca com descrição e selos, mais até três colunas de navegação, e a linha legal no pé.
|
|
413
|
+
|
|
414
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
415
|
+
|---|---|---|---|
|
|
416
|
+
| `logo` | `React.ReactNode` | não | |
|
|
417
|
+
| `descricao` | `React.ReactNode` | não | Parágrafo de posicionamento embaixo do logo. |
|
|
418
|
+
| `selos` | `React.ReactNode` | não | Selos da primeira coluna. Um `Selos` cabe aqui. |
|
|
419
|
+
| `colunas` | `FooterColuna[]` | não | |
|
|
420
|
+
| `legal` | `React.ReactNode[]` | não | Linha final: razão social, CNPJ, endereço, telefone. |
|
|
421
|
+
| `className` | `string` | não | |
|
|
422
|
+
|
|
423
|
+
```jsx
|
|
424
|
+
<Footer
|
|
425
|
+
logo={<img src="/logo-branco.png" alt="PSWEX" height={28} />}
|
|
426
|
+
descricao="Nós fazemos seu negócio dar certo."
|
|
427
|
+
selos={<Selos itens={["Meta Tech Provider", "Google Ads AI"]} />}
|
|
428
|
+
colunas={[{ titulo: "Serviços", links: [{ href: "/sites", label: "Criação de sites" }] }]}
|
|
429
|
+
legal={["PSWEX Tecnologia", "CNPJ 28.477.119/0001-79", "(31) 99922-9792"]}
|
|
430
|
+
/>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
#### Hero
|
|
434
|
+
|
|
435
|
+
Dobra de abertura em navy com foto de fundo.
|
|
436
|
+
|
|
437
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
438
|
+
|---|---|---|---|
|
|
439
|
+
| `eyebrow` | `React.ReactNode` | não | |
|
|
440
|
+
| `titulo` | `React.ReactNode` | sim | |
|
|
441
|
+
| `apoio` | `React.ReactNode` | não | |
|
|
442
|
+
| `acoes` | `React.ReactNode` | não | Botões da dobra. Um cta e um ghost é o padrão da casa. |
|
|
443
|
+
| `nota` | `React.ReactNode` | não | Linha pequena abaixo dos botões. |
|
|
444
|
+
| `lado` | `React.ReactNode` | não | Coluna da direita: imagem, vídeo, o que a página pedir. |
|
|
445
|
+
| `fundo` | `"foto" \| "grad" \| "grad-azul" \| "grad-vermelho"` | não | `foto` é o webp de fundo. `grad` é a arte vetorial, que troca sozinha de arquivo em 1400px e em 980px. `grad-azul` e `gr |
|
|
446
|
+
| `className` | `string` | não | |
|
|
447
|
+
|
|
448
|
+
```jsx
|
|
449
|
+
<Hero
|
|
450
|
+
eyebrow="Belo Horizonte, 10 anos"
|
|
451
|
+
titulo="Nós fazemos seu negócio dar certo"
|
|
452
|
+
apoio="Seu time faz o trabalho. O processo faz o trabalho voltar. E você paga pelas duas vezes."
|
|
453
|
+
acoes={<><Btn variante="cta" href="#contato">Falar no WhatsApp</Btn><Btn variante="ghost" href="/projetos">Ver projetos</Btn></>}
|
|
454
|
+
nota="Resposta no mesmo dia útil."
|
|
455
|
+
/>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
#### LeadForm
|
|
459
|
+
|
|
460
|
+
Formulário de captura em card branco.
|
|
461
|
+
|
|
462
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
463
|
+
|---|---|---|---|
|
|
464
|
+
| `children` | `React.ReactNode` | não | |
|
|
465
|
+
| `botao` | `React.ReactNode` | não | Texto do botão de envio. |
|
|
466
|
+
| `nota` | `React.ReactNode` | não | Linha de privacidade abaixo do botão. |
|
|
467
|
+
| `className` | `string` | não | |
|
|
468
|
+
|
|
469
|
+
```jsx
|
|
470
|
+
<LeadForm botao="Quero falar com a PSWEX" nota="Seus dados ficam com a PSWEX.">
|
|
471
|
+
<Row2><Field nome="nome" label="Nome" /><Field nome="tel" label="WhatsApp" tipo="tel" /></Row2>
|
|
472
|
+
<Field nome="empresa" label="Empresa" nota="opcional" />
|
|
473
|
+
</LeadForm>
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
#### PhoneMock
|
|
477
|
+
|
|
478
|
+
Aparelho desenhado em CSS com uma conversa dentro. É a coluna direita do hero da home.
|
|
479
|
+
|
|
480
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
481
|
+
|---|---|---|---|
|
|
482
|
+
| `mensagens` | `PhoneMensagem[]` | sim | |
|
|
483
|
+
| `passos` | `React.ReactNode[]` | não | Pílulas que entram animadas ao lado do aparelho. Abaixo de 1100px empilham. |
|
|
484
|
+
| `className` | `string` | não | |
|
|
485
|
+
|
|
486
|
+
```jsx
|
|
487
|
+
<PhoneMock
|
|
488
|
+
mensagens={[
|
|
489
|
+
{ texto: "Vocês fazem orçamento de quanto?" },
|
|
490
|
+
{ texto: "Depende do que você precisa.", de: "voce" },
|
|
491
|
+
]}
|
|
492
|
+
passos={["Entender o que trava", "Escolher por onde começar"]}
|
|
493
|
+
/>
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
#### Secao
|
|
497
|
+
|
|
498
|
+
Seção com padding vertical da escala e Shell embutido.
|
|
499
|
+
|
|
500
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
501
|
+
|---|---|---|---|
|
|
502
|
+
| `fundo` | um dos 10 nomes do catálogo, lista na seção Ícones | não | Fundo da seção. `dark` é o navy da marca. `grad` é a arte vetorial da casa, azul de um lado e vermelho do outro, com a p |
|
|
503
|
+
| `children` | `React.ReactNode` | não | |
|
|
504
|
+
| `className` | `string` | não | |
|
|
505
|
+
| `id` | `string` | não | |
|
|
506
|
+
| `style` | `React.CSSProperties` | não | |
|
|
507
|
+
|
|
508
|
+
```jsx
|
|
509
|
+
<Secao fundo="dark">
|
|
510
|
+
<SecHead eyebrow="Método" titulo="Elimina, simplifica, automatiza" />
|
|
511
|
+
<StepsList passos={[{titulo:'Elimina', texto:'O que não precisa existir sai.'}]} />
|
|
512
|
+
</Secao>
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
#### Servicos
|
|
516
|
+
|
|
517
|
+
Grade de serviço com ícone. É o atalho para não montar `Cards` cheio de `Card` na mão em toda página.
|
|
518
|
+
|
|
519
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
520
|
+
|---|---|---|---|
|
|
521
|
+
| `itens` | um dos 72 nomes do catálogo, lista na seção Ícones | sim | Um item por card. O ícone é obrigatório, que é o ponto do bloco. |
|
|
522
|
+
| `titulo` | `React.ReactNode` | sim | |
|
|
523
|
+
| `texto` | `React.ReactNode` | não | |
|
|
524
|
+
| `href` | `string` | não | Quando existe, o card vira link e ganha o rótulo "Ver" no pé. |
|
|
525
|
+
| `colunas` | `2 \| 3 \| 4` | não | |
|
|
526
|
+
| `className` | `string` | não | |
|
|
527
|
+
|
|
528
|
+
```jsx
|
|
529
|
+
<Servicos
|
|
530
|
+
colunas={3}
|
|
531
|
+
itens={[
|
|
532
|
+
{ icone: 'criacao-de-sites', titulo: 'Sites', texto: 'Carrega rápido e tem para onde ir.', href: '/sites' },
|
|
533
|
+
{ icone: 'agentes-ia', titulo: 'Agentes de IA', texto: 'Responde na hora e qualifica.', href: '/ia' },
|
|
534
|
+
]}
|
|
535
|
+
/>
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
#### Shell
|
|
539
|
+
|
|
540
|
+
Container de 1200px com respiro lateral.
|
|
541
|
+
|
|
542
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
543
|
+
|---|---|---|---|
|
|
544
|
+
| `children` | `React.ReactNode` | não | |
|
|
545
|
+
| `className` | `string` | não | |
|
|
546
|
+
| `id` | `string` | não | |
|
|
547
|
+
| `style` | `React.CSSProperties` | não | |
|
|
548
|
+
|
|
549
|
+
```jsx
|
|
550
|
+
<Shell>
|
|
551
|
+
<SecHead titulo="Serviços" />
|
|
552
|
+
</Shell>
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
#### Split
|
|
556
|
+
|
|
557
|
+
Duas colunas dentro de uma `section`, que viram uma só abaixo de 900px.
|
|
558
|
+
|
|
559
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
560
|
+
|---|---|---|---|
|
|
561
|
+
| `proporcao` | `"a" \| "b" \| "c"` | não | `a` dá mais espaço à esquerda, `b` divide igual, `c` divide igual e centraliza na vertical. |
|
|
562
|
+
| `children` | `React.ReactNode` | não | |
|
|
563
|
+
| `className` | `string` | não | |
|
|
564
|
+
| `id` | `string` | não | |
|
|
565
|
+
| `style` | `React.CSSProperties` | não | |
|
|
566
|
+
|
|
567
|
+
```jsx
|
|
568
|
+
<section>
|
|
569
|
+
<Split proporcao="a">
|
|
570
|
+
<div><SecHead titulo="O que você recebe." /></div>
|
|
571
|
+
<div><StepsList passos={[{ titulo: "Entender" }]} /></div>
|
|
572
|
+
</Split>
|
|
573
|
+
</section>
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
#### Topbar
|
|
577
|
+
|
|
578
|
+
Cabeçalho fixo em navy translúcido. Logo à esquerda, navegação no meio, botão de conversão à direita.
|
|
579
|
+
|
|
580
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
581
|
+
|---|---|---|---|
|
|
582
|
+
| `logo` | `React.ReactNode` | não | Logo da marca. Imagem de 30px de altura sobre o navy. |
|
|
583
|
+
| `href` | `string` | não | |
|
|
584
|
+
| `links` | `TopbarLink[]` | não | |
|
|
585
|
+
| `acao` | `React.ReactNode` | não | Botão da direita. Um `Btn` com variante `cta` é o padrão. |
|
|
586
|
+
| `className` | `string` | não | |
|
|
587
|
+
|
|
588
|
+
```jsx
|
|
589
|
+
<Topbar
|
|
590
|
+
logo={<img src="/logo-branco.png" alt="PSWEX" height={30} />}
|
|
591
|
+
href="/"
|
|
592
|
+
links={[{ href: "/servicos", label: "Serviços" }, { href: "/cases", label: "Projetos", atual: true }]}
|
|
593
|
+
acao={<Btn variante="cta" href="/avaliacao">Falar com a gente</Btn>}
|
|
594
|
+
/>
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
#### Wall
|
|
598
|
+
|
|
599
|
+
Parede de logos de cliente em grade automática.
|
|
600
|
+
|
|
601
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
602
|
+
|---|---|---|---|
|
|
603
|
+
| `titulo` | `React.ReactNode` | não | Rótulo centralizado acima da grade. |
|
|
604
|
+
| `logos` | `WallLogo[]` | sim | |
|
|
605
|
+
| `className` | `string` | não | |
|
|
606
|
+
|
|
607
|
+
```jsx
|
|
608
|
+
<Wall titulo="Quem já confiou" logos={[{ src: "/logos/unimed.png", alt: "Unimed, cliente PSWEX" }]} />
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
#### WhatsAppModal
|
|
612
|
+
|
|
613
|
+
Pede nome e número antes de abrir a conversa no WhatsApp. É o que separa um clique anônimo de um lead com nome.
|
|
614
|
+
|
|
615
|
+
| Prop | Tipo | Obrigatória | O que faz |
|
|
616
|
+
|---|---|---|---|
|
|
617
|
+
| `aberto` | `boolean` | não | `false` mantém o `hidden`, que é como o modal nasce antes do clique. |
|
|
618
|
+
| `eyebrow` | `React.ReactNode` | não | |
|
|
619
|
+
| `titulo` | `React.ReactNode` | não | |
|
|
620
|
+
| `apoio` | `React.ReactNode` | não | |
|
|
621
|
+
| `botao` | `React.ReactNode` | não | |
|
|
622
|
+
| `nota` | `React.ReactNode` | não | Linha de privacidade centralizada abaixo do botão. |
|
|
623
|
+
| `className` | `string` | não | |
|
|
624
|
+
| `style` | `React.CSSProperties` | não | Escape para ancorar o modal dentro de um container, em vez de cobrir a tela. |
|
|
625
|
+
|
|
626
|
+
```jsx
|
|
627
|
+
<WhatsAppModal aberto />
|
|
628
|
+
```
|