Initial commit

This commit is contained in:
Rafael Dias Martins
2026-08-31 14:10:20 -03:00
commit 8fcb5aac66
454 changed files with 60207 additions and 0 deletions
+893
View File
@@ -0,0 +1,893 @@
# Padrões de Estilo - Course Platform
Este documento define os padrões de estilo unificados para todo o sistema, garantindo consistência visual e facilidade de manutenção.
## Índice
- [Princípios Fundamentais](#princípios-fundamentais)
- [Cores e Tema](#cores-e-tema)
- [Tipografia](#tipografia)
- [Espaçamento](#espaçamento)
- [Badges e Labels](#badges-e-labels)
- [Componentes](#componentes)
- [Transições e Animações](#transições-e-animações)
- [Regras CSS Globais](#regras-css-globais)
---
## Princípios Fundamentais
1. **Usar CSS Variables** para cores, backgrounds e bordas (definidas em `:root` e `.dark`)
2. **Padronizar em `neutral-*`** em vez de `gray-*` para consistência
3. **Usar `blue-600`** como cor primária para botões de ação principal
4. **Manter border-radius de 8px** (`rounded-lg` ou `rounded-xl`)
5. **Usar sombras sutis**: `shadow-sm` padrão, `shadow-md` no hover
6. **Evitar regras CSS globais com `!important`** que sobrescrevem classes Tailwind
---
## Cores e Tema
### CSS Variables (Definidas em `globals.css`)
```css
/* Tema Claro (:root) */
--background: #ffffff;
--foreground: #09090b;
--card: #ffffff;
--card-foreground: #09090b;
--primary: #18181b;
--primary-foreground: #fafafa;
--secondary: #f4f4f5;
--secondary-foreground: #18181b;
--muted: #f4f4f5;
--muted-foreground: #71717a;
--accent: #f4f4f5;
--accent-foreground: #18181b;
--destructive: #ef4444;
--destructive-foreground: #fafafa;
--border: #e4e4e7;
--input: #e4e4e7;
--ring: #18181b;
--radius: 0.5rem;
/* Tema Escuro (.dark) */
--background: #09090b;
--foreground: #fafafa;
--card: #09090b;
--card-foreground: #fafafa;
--primary: #fafafa;
--primary-foreground: #18181b;
--secondary: #27272a;
--secondary-foreground: #fafafa;
--muted: #27272a;
--muted-foreground: #a1a1aa;
--accent: #27272a;
--accent-foreground: #fafafa;
--destructive: #7f1d1d;
--destructive-foreground: #fafafa;
--border: #27272a;
--input: #27272a;
--ring: #d4d4d8;
```
### Cores Semânticas (Tailwind)
| Propósito | Light Mode | Dark Mode |
|-----------|------------|-----------|
| Primary (Ação principal) | `blue-600` | `blue-500` |
| Primary Hover | `blue-700` | `blue-600` |
| Success | `green-600` | `green-500` |
| Success Hover | `green-700` | `green-600` |
| Warning | `yellow-500` | `yellow-400` |
| Warning Hover | `yellow-600` | `yellow-500` |
| Error/Destructive | `red-600` | `red-500` |
| Error Hover | `red-700` | `red-600` |
| Info | `blue-600` | `blue-500` |
### Cores Neutras (Padrão)
**Use sempre `neutral-*` em vez de `gray-*` para consistência:**
| Escala | Light Mode | Dark Mode |
|--------|------------|-----------|
| 50 | `#fafafa` | `#18181b` |
| 100 | `#f5f5f5` | `#27272a` |
| 200 | `#e5e5e5` | `#3f3f46` |
| 300 | `#d4d4d4` | `#52525b` |
| 400 | `#a3a3a3` | `#71717a` |
| 500 | `#737373` | `#a1a1aa` |
| 600 | `#525252` | `#d4d4d8` |
| 700 | `#404040` | `#e4e4e7` |
| 800 | `#262626` | `#f4f4f5` |
| 900 | `#171717` | `#fafafa` |
| 950 | `#0a0a0a` | `#fafafa` |
---
## Tipografia
### Fonte
- **Fonte Principal**: Geist Sans (Google Fonts)
- **Fonte Monospace**: Geist Mono (Google Fonts)
### Tamanhos e Pesos
| Elemento | Classe Tailwind | Uso |
|----------|-----------------|-----|
| Título Principal | `text-2xl md:text-3xl font-semibold` | Títulos de página |
| Título de Seção | `text-lg font-semibold` | Títulos de seção |
| Subtítulo | `text-base font-medium` | Subtítulos |
| Texto Normal | `text-sm` | Texto de conteúdo |
| Texto Secundário | `text-sm text-muted-foreground` | Texto de apoio |
| Label | `text-sm font-medium` | Labels de formulário |
| Caption/Small | `text-xs` | Textos pequenos |
### Exemplos
```jsx
// Título de Página
<h1 className="text-2xl md:text-3xl font-semibold text-foreground">
Título da Página
</h1>
// Título de Seção
<h2 className="text-lg font-semibold text-foreground">
Título da Seção
</h2>
// Subtítulo
<p className="text-sm text-muted-foreground">
Descrição ou subtítulo
</p>
// Label
<label className="text-sm font-medium leading-none">
Nome do Campo
</label>
```
---
## Espaçamento
### Padrões de Padding
| Elemento | Padding/Margin |
|----------|----------------|
| Card padding | `p-5` |
| Card padding (compacto) | `p-4` |
| Button padding | `px-4 py-2` |
| Input padding | `px-3 py-2` |
| Table cell padding | `px-6 py-4` |
| Section gap | `gap-3` ou `gap-4` |
| Vertical spacing entre elementos | `space-y-4` |
| Horizontal spacing entre elementos | `space-x-3` |
### Exemplos
```jsx
// Card
<div className="border rounded-xl p-5 shadow-sm bg-card">
{/* conteúdo */}
</div>
// Formulário com espaçamento vertical
<form className="space-y-4">
{/* campos */}
</form>
// Botões com espaçamento horizontal
<div className="flex gap-3">
<button>Cancelar</button>
<button>Salvar</button>
</div>
```
---
## Badges e Labels
Badges são pequenos labels coloridos usados para indicar status, categorias ou outros metadados. Devem ser usados consistentemente em toda a aplicação.
### Estrutura Base
```jsx
<span className="text-xs px-2 py-1 rounded-full border [badge-classes]">
Label Text
</span>
```
### Padrões de Cores
#### Success/Green (Disponível, Pago, Ativo, Presente)
**Tema Claro:** `bg-emerald-100 text-emerald-700 border-emerald-200`
**Tema Escuro:** `dark:bg-emerald-900/20 dark:text-emerald-300 dark:border-emerald-800`
```jsx
<span className="text-xs px-2 py-1 rounded-full border bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/20 dark:text-emerald-300 dark:border-emerald-800">
Disponível
</span>
```
**Casos de Uso:**
- "Disponível" (Available)
- "Pago" (Paid)
- "Ativa" (Active)
- "Presente" (Present)
- Status "Verified"
---
#### Info/Blue (Em breve, Aguardando Verificação, Justificado)
**Tema Claro:** `bg-blue-100 text-blue-700 border-blue-200`
**Tema Escuro:** `dark:bg-blue-900/20 dark:text-blue-300 dark:border-blue-800`
```jsx
<span className="text-xs px-2 py-1 rounded-full border bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-900/20 dark:text-blue-300 dark:border-blue-800">
Em breve
</span>
```
**Casos de Uso:**
- "Em breve" (Upcoming)
- "Aguardando Verificação" (Pending Verification)
- "Justificado" (Excused)
- Templates "Public"
---
#### Danger/Red (Encerrada, Rejeitado, Ausente)
**Tema Claro:** `bg-red-100 text-red-700 border-red-200`
**Tema Escuro:** `dark:bg-red-900/20 dark:text-red-300 dark:border-red-800`
```jsx
<span className="text-xs px-2 py-1 rounded-full border bg-red-100 text-red-700 border-red-200 dark:bg-red-900/20 dark:text-red-300 dark:border-red-800">
Encerrada
</span>
```
**Casos de Uso:**
- "Encerrada" (Expired)
- "Rejeitado" (Rejected)
- "Ausente" (Absent)
- Status "Rejected"
---
#### Warning/Amber (Aguardando Pagamento, Atrasado, Arquivada)
**Tema Claro:** `bg-amber-100 text-amber-700 border-amber-200`
**Tema Escuro:** `dark:bg-amber-900/20 dark:text-amber-300 dark:border-amber-800`
```jsx
<span className="text-xs px-2 py-1 rounded-full border bg-amber-100 text-amber-700 border-amber-200 dark:bg-amber-900/20 dark:text-amber-300 dark:border-amber-800">
Aguardando Pagamento
</span>
```
**Casos de Uso:**
- "Aguardando Pagamento" (Pending Payment)
- "Atrasado" (Late)
- "Arquivada" (Archived)
- Status "Pending"
---
#### Warning/Yellow (Obrigações)
**Tema Claro:** `bg-yellow-100 text-yellow-800 border-yellow-300`
**Tema Escuro:** `dark:bg-yellow-900/50 dark:text-yellow-200 dark:border-yellow-700`
```jsx
<span className="text-xs px-2 py-1 rounded-full border bg-yellow-100 text-yellow-800 border-yellow-300 dark:bg-yellow-900/50 dark:text-yellow-200 dark:border-yellow-700">
Obrigação
</span>
```
**Casos de Uso:**
- Obrigações de pagamento
- "Obrigação" (Obligation)
---
#### Purple (Leitura)
**Tema Claro:** `bg-purple-100 text-purple-700 border-purple-200`
**Tema Escuro:** `dark:bg-purple-900/20 dark:text-purple-300 dark:border-purple-800`
```jsx
<span className="text-xs px-2 py-1 rounded-full border bg-purple-100 text-purple-700 border-purple-200 dark:bg-purple-900/20 dark:text-purple-300 dark:border-purple-800">
Leitura
</span>
```
**Casos de Uso:**
- "Leitura" (Reading)
- Categoria "Indigo"
---
#### Indigo (Trabalhos)
**Tema Claro:** `bg-indigo-100 text-indigo-700 border-indigo-200`
**Tema Escuro:** `dark:bg-indigo-900/20 dark:text-indigo-300 dark:border-indigo-800`
```jsx
<span className="text-xs px-2 py-1 rounded-full border bg-indigo-100 text-indigo-700 border-indigo-200 dark:bg-indigo-900/20 dark:text-indigo-300 dark:border-indigo-800">
Trabalhos
</span>
```
**Casos de Uso:**
- "Trabalhos" (Homework)
- Itens relacionados a assignments
---
#### Neutral/Gray (Outros, Padrão)
**Tema Claro:** `bg-gray-100 text-gray-700 border-gray-200`
**Tema Escuro:** `dark:bg-gray-800 dark:text-gray-300 dark:border-gray-700`
```jsx
<span className="text-xs px-2 py-1 rounded-full border bg-gray-100 text-gray-700 border-gray-200 dark:bg-gray-800 dark:text-gray-300 dark:border-gray-700">
Outros
</span>
```
**Casos de Uso:**
- "Outros" (Other)
- Categorias padrão/desconhecidas
- Status neutro
### Badges por Categoria
#### Categorias de Arquivos
| Categoria | Cor |
|-----------|-----|
| Slides | Blue |
| Exercícios | Green |
| Leitura | Purple |
| Vídeos | Red |
| Áudio | Yellow |
| Trabalhos | Indigo |
| Outros | Gray |
#### Status de Presença
| Status | Cor |
|--------|-----|
| Presente | Green |
| Ausente | Red |
| Atrasado | Amber |
| Justificado | Blue |
#### Status de Pagamento
| Status | Cor |
|--------|-----|
| Pago | Green |
| Aguardando Verificação | Blue |
| Rejeitado | Red |
| Aguardando Pagamento | Amber |
| Obrigação | Yellow |
#### Status de Provas
| Status | Cor |
|--------|-----|
| Disponível | Green |
| Em breve | Blue |
| Encerrada | Red |
#### Status de Turma
| Status | Cor |
|--------|-----|
| Ativa | Green |
| Arquivada | Amber |
### Exemplo de Implementação
```jsx
const categoryColors = {
'Slides': 'text-xs px-2 py-1 rounded-full border bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-900/20 dark:text-blue-300 dark:border-blue-800',
'Exercícios': 'text-xs px-2 py-1 rounded-full border bg-green-100 text-green-700 border-green-200 dark:bg-green-900/20 dark:text-green-300 dark:border-green-800',
'Leitura': 'text-xs px-2 py-1 rounded-full border bg-purple-100 text-purple-700 border-purple-200 dark:bg-purple-900/20 dark:text-purple-300 dark:border-purple-800',
'Vídeos': 'text-xs px-2 py-1 rounded-full border bg-red-100 text-red-700 border-red-200 dark:bg-red-900/20 dark:text-red-300 dark:border-red-800',
'Áudio': 'text-xs px-2 py-1 rounded-full border bg-yellow-100 text-yellow-700 border-yellow-200 dark:bg-yellow-900/20 dark:text-yellow-300 dark:border-yellow-800',
'Trabalhos': 'text-xs px-2 py-1 rounded-full border bg-indigo-100 text-indigo-700 border-indigo-200 dark:bg-indigo-900/20 dark:text-indigo-300 dark:border-indigo-800',
'Outros': 'text-xs px-2 py-1 rounded-full border bg-gray-100 text-gray-700 border-gray-200 dark:bg-gray-800 dark:text-gray-300 dark:border-gray-700'
};
<span className={categoryColors[category] || categoryColors['Outros']}>
{category}
</span>
```
### Notas Importantes
1. **Consistência**: Sempre use a string de classes completa incluindo variantes de tema claro e escuro
2. **Acessibilidade**: As combinações de cores fornecem contraste suficiente para ambos os temas
3. **Opacidade**: O tema escuro usa `/20` de opacidade para a maioria das cores (exceto yellow que usa `/50`)
4. **Borda**: Sempre inclua borda para melhor separação visual
5. **Arredondamento**: Use `rounded-full` para badges em formato de pílula
6. **Tamanho**: Use `text-xs` para badges pequenos, `text-sm` para badges maiores se necessário
---
## Componentes
### Cards
**Padrão Unificado:**
```jsx
<div className="border rounded-xl p-5 shadow-sm bg-card dark:bg-card dark:border-border hover:shadow-md hover:border-neutral-300 dark:hover:border-neutral-700 transition-all">
{/* conteúdo */}
</div>
```
**Card com Link:**
```jsx
<Link href="/path" className="block no-underline">
<div className="border rounded-xl p-5 shadow-sm bg-card hover:shadow-md transition-all">
{/* conteúdo */}
</div>
</Link>
```
### Botões
**Primary (Ação Principal):**
```jsx
<button
type="submit"
className="inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium bg-blue-600 hover:bg-blue-700 text-white h-10 px-4 py-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
>
Salvar
</button>
```
**Secondary (Ação Secundária):**
```jsx
<button
type="button"
className="inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium border border-input bg-background hover:bg-accent hover:text-accent-foreground h-10 px-4 py-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
>
Cancelar
</button>
```
**Destructive (Ação de Exclusão):**
```jsx
<button
type="button"
className="inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium bg-red-600 hover:bg-red-700 text-white h-10 px-4 py-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
>
Excluir
</button>
```
**Botão com Ícone:**
```jsx
<button className="inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium shadow-sm hover:shadow transition-shadow">
<Icon className="w-4 h-4" />
<span>Texto do Botão</span>
</button>
```
### Inputs
**Input de Texto:**
```jsx
<input
type="text"
className="flex h-10 w-full rounded-lg border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
placeholder="Digite aqui..."
/>
```
**Select:**
```jsx
<div className="relative">
<select
className="flex h-10 w-full rounded-lg border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 appearance-none"
>
<option value="">Selecione...</option>
{/* opções */}
</select>
<svg className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground">
{/* ícone de seta */}
</svg>
</div>
```
**Textarea:**
```jsx
<textarea
className="flex min-h-[80px] w-full rounded-lg border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
placeholder="Digite sua mensagem..."
rows={4}
/>
```
### Tabelas
**Tabela Padrão:**
```jsx
<div className="w-full overflow-x-auto rounded-xl border border-border bg-card shadow-sm">
<table className="w-full text-sm text-left">
<thead className="bg-muted text-muted-foreground font-semibold uppercase text-xs">
<tr>
<th className="px-6 py-4 border-b border-border">Coluna 1</th>
<th className="px-6 py-4 border-b border-border">Coluna 2</th>
<th className="px-6 py-4 border-b border-border text-right">Ações</th>
</tr>
</thead>
<tbody className="divide-y divide-border">
<tr className="hover:bg-accent transition-colors">
<td className="px-6 py-4 text-foreground">Valor 1</td>
<td className="px-6 py-4 text-foreground">Valor 2</td>
<td className="px-6 py-4 text-right">
{/* ações */}
</td>
</tr>
</tbody>
</table>
</div>
```
### Badges
**Status Badges:**
```jsx
// Success (Pago)
<span className="px-2 py-1 rounded-full text-xs font-medium border bg-green-100 dark:bg-green-900/50 text-green-800 dark:text-green-200 border-green-300 dark:border-green-700">
Pago
</span>
// Warning (Pendente)
<span className="px-2 py-1 rounded-full text-xs font-medium border bg-yellow-100 dark:bg-yellow-900/50 text-yellow-800 dark:text-yellow-200 border-yellow-300 dark:border-yellow-700">
Pendente
</span>
// Error (Rejeitado)
<span className="px-2 py-1 rounded-full text-xs font-medium border bg-red-100 dark:bg-red-900/50 text-red-800 dark:text-red-200 border-red-300 dark:border-red-700">
Rejeitado
</span>
// Info (Aguardando Verificação)
<span className="px-2 py-1 rounded-full text-xs font-medium border bg-blue-100 dark:bg-blue-900/50 text-blue-800 dark:text-blue-200 border-blue-300 dark:border-blue-700">
Aguardando Verificação
</span>
// Neutral (Não Pago)
<span className="px-2 py-1 rounded-full text-xs font-medium border bg-neutral-100 dark:bg-neutral-700 text-neutral-800 dark:text-neutral-200 border-neutral-300 dark:border-neutral-600">
Não Pago
</span>
```
### Flash Messages
```jsx
// Success
<div className="px-4 py-3 rounded relative mb-4 text-green-700 dark:text-green-300 bg-green-100 dark:bg-green-900/50 border border-green-400 dark:border-green-700">
<div className="flex items-center">
<strong className="font-bold mr-1">Sucesso:</strong>
<span className="block sm:inline">Mensagem de sucesso</span>
</div>
</div>
// Error
<div className="px-4 py-3 rounded relative mb-4 text-red-700 dark:text-red-300 bg-red-100 dark:bg-red-900/50 border border-red-400 dark:border-red-700">
<div className="flex items-center">
<strong className="font-bold mr-1">Erro:</strong>
<span className="block sm:inline">Mensagem de erro</span>
</div>
</div>
// Warning
<div className="px-4 py-3 rounded relative mb-4 text-yellow-700 dark:text-yellow-300 bg-yellow-100 dark:bg-yellow-900/50 border border-yellow-400 dark:border-yellow-700">
<div className="flex items-center">
<strong className="font-bold mr-1">Aviso:</strong>
<span className="block sm:inline">Mensagem de aviso</span>
</div>
</div>
// Info
<div className="px-4 py-3 rounded relative mb-4 text-blue-700 dark:text-blue-300 bg-blue-100 dark:bg-blue-900/50 border border-blue-400 dark:border-blue-700">
<div className="flex items-center">
<strong className="font-bold mr-1">Info:</strong>
<span className="block sm:inline">Mensagem informativa</span>
</div>
</div>
```
### Sidebar Navigation
```jsx
<aside className="w-64 flex-shrink-0 border-r border-neutral-200 dark:border-neutral-800 p-4 bg-white dark:bg-neutral-950">
<nav className="mt-2">
<ul className="space-y-1">
{/* itens de navegação */}
</ul>
</nav>
</aside>
```
### Stats Cards
```jsx
<div className="rounded-lg border border-neutral-200 dark:border-neutral-800 p-3 bg-neutral-50 dark:bg-neutral-800/40">
<p className="text-xs text-neutral-700 dark:text-neutral-300 font-medium">Label</p>
<p className="mt-1 text-lg font-semibold text-neutral-900 dark:text-neutral-100">Valor</p>
</div>
```
---
## Transições e Animações
### Padrões de Transição
```jsx
// Transição suave para todas as propriedades
className="transition-all duration-200"
// Transição apenas para cores
className="transition-colors"
// Transição para sombra
className="transition-shadow"
// Transição para transformações
className="transition-transform"
```
### Hover Effects
```jsx
// Card hover
<div className="hover:shadow-md hover:border-neutral-300 dark:hover:border-neutral-700 transition-all">
// Button hover
<button className="hover:bg-blue-700 transition-colors">
// Link hover
<a className="hover:text-blue-600 transition-colors">
```
---
## Regras CSS Globais
### Importante: Evitar `!important` em regras globais
**NÃO FAÇA:**
```css
button[type="submit"] {
background-color: var(--primary) !important;
color: var(--primary-foreground) !important;
}
```
Isso sobrescreve todas as classes Tailwind e causa problemas de manutenção.
**FAÇA:**
Deixe cada componente definir seu próprio estilo usando classes Tailwind ou CSS variables sem `!important`.
### Estilos Base (Definidos em `globals.css`)
```css
/* Form elements */
input, select, textarea {
border: 1px solid var(--input);
background-color: var(--background);
border-radius: var(--radius);
padding: 0.5rem 0.75rem;
font-size: 0.875rem;
color: var(--foreground);
transition: all 0.2s;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: var(--ring);
box-shadow: 0 0 0 2px var(--background), 0 0 0 4px var(--ring);
}
/* Tables */
table {
border-collapse: collapse;
width: 100%;
font-size: 0.875rem;
}
thead {
background-color: var(--muted);
}
tbody tr {
border-bottom: 1px solid var(--border);
}
tbody tr:hover {
background-color: var(--accent);
}
th {
text-align: left;
font-weight: 500;
color: var(--muted-foreground);
padding: 0.75rem 1rem;
font-size: 0.75rem;
text-transform: uppercase;
}
td {
padding: 1rem;
vertical-align: middle;
}
/* Cards */
.card {
background-color: var(--card);
color: var(--card-foreground);
border-radius: var(--radius);
border: 1px solid var(--border);
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
}
/* Badges */
.badge {
display: inline-flex;
align-items: center;
border-radius: 9999px;
padding: 0.125rem 0.625rem;
font-size: 0.75rem;
font-weight: 500;
}
/* Links */
a {
color: var(--primary);
text-decoration: none;
}
a:hover,
a:focus,
a:active {
text-decoration: none !important;
}
```
---
## Checklist de Implementação
Ao criar ou modificar componentes, verifique:
- [ ] Usar CSS variables (`bg-card`, `text-foreground`, `border-border`)
- [ ] Usar `neutral-*` em vez de `gray-*`
- [ ] Usar `blue-600` para botões primary
- [ ] Usar `rounded-lg` ou `rounded-xl` para border-radius
- [ ] Adicionar `transition-colors` ou `transition-all` para elementos interativos
- [ ] Testar em tema claro e escuro
- [ ] Verificar contraste de cores
- [ ] Usar classes Tailwind em vez de CSS customizado quando possível
- [ ] Evitar `!important` em regras CSS
---
## Exemplos de Componentes Completos
### Formulário Padrão
```jsx
function StandardForm({ onSubmit, onCancel }) {
return (
<form onSubmit={onSubmit} className="bg-card text-card-foreground rounded-xl border shadow-sm p-6 max-w-lg mx-auto space-y-4">
<div className="space-y-2">
<label htmlFor="name" className="text-sm font-medium leading-none">
Nome
</label>
<input
id="name"
name="name"
className="flex h-10 w-full rounded-lg border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
placeholder="Digite o nome"
/>
</div>
<div className="space-y-2">
<label htmlFor="email" className="text-sm font-medium leading-none">
Email
</label>
<input
id="email"
name="email"
type="email"
className="flex h-10 w-full rounded-lg border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
placeholder="Digite o email"
/>
</div>
<div className="flex gap-3 mt-6">
<button
type="submit"
className="inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium bg-blue-600 hover:bg-blue-700 text-white h-10 px-4 py-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 flex-1"
>
Salvar
</button>
<button
type="button"
onClick={onCancel}
className="inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium border border-input bg-background hover:bg-accent hover:text-accent-foreground h-10 px-4 py-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 flex-1"
>
Cancelar
</button>
</div>
</form>
);
}
```
### Card de Dashboard
```jsx
function DashboardCard({ title, description, buttonText, link, icon: Icon }) {
return (
<Link href={link} className="block no-underline">
<div className="h-full border rounded-xl p-5 shadow-sm bg-card dark:bg-card dark:border-border hover:shadow-md hover:border-neutral-300 dark:hover:border-neutral-700 transition-all">
<div className="flex items-start gap-4">
{Icon && (
<div className="p-2.5 rounded-lg bg-blue-50 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300">
<Icon className="w-5 h-5" />
</div>
)}
<div className="flex-1">
<h3 className="text-lg font-semibold text-foreground mb-2">{title}</h3>
<p className="text-sm text-muted-foreground mb-4">{description}</p>
<span className="inline-flex justify-center text-white text-sm font-medium py-2 px-6 rounded-lg transition-colors bg-blue-600 hover:bg-blue-700">
{buttonText}
</span>
</div>
</div>
</div>
</Link>
);
}
```
---
## Conclusão
Seguir estes padrões garantirá:
**Consistência visual** em todo o sistema
**Manutenção mais fácil** com código previsível
**Melhor suporte** a tema claro/escuro
**Código mais limpo** e organizado
**Experiência do usuário** mais coesa
Para dúvidas ou sugestões de melhoria, consulte a equipe de desenvolvimento.