first commit
This commit is contained in:
@@ -1,96 +1,112 @@
|
||||
# RivusLab — Landing Page
|
||||
|
||||
Landing page institucional da RivusLab.
|
||||
Stack: **Vite + React + TypeScript + Tailwind CSS** com i18n (PT/EN/ES) e tokens de design centralizados em um único arquivo CSS.
|
||||
Landing page institucional da **RivusLab**: engenharia de software sob medida e especialização em Planview AdaptiveWork.
|
||||
|
||||
**Stack:** Vite · React 18 · TypeScript · Tailwind CSS · i18next (PT / EN / ES) · Framer Motion
|
||||
|
||||
---
|
||||
|
||||
## Rodando o projeto
|
||||
## Início rápido
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev # ambiente de desenvolvimento (http://localhost:5173)
|
||||
npm run build # build de produção em ./dist
|
||||
npm run preview # serve o build de produção localmente
|
||||
npm run lint # type-check com TypeScript
|
||||
npm run dev # http://localhost:5173
|
||||
npm run build # saída em ./dist
|
||||
npm run preview # preview do build de produção
|
||||
npm run lint # type-check (tsc --noEmit)
|
||||
```
|
||||
|
||||
Requer **Node 18+** (testado em Node 24).
|
||||
Requer **Node 18+**.
|
||||
|
||||
---
|
||||
|
||||
## Personalizando a identidade visual
|
||||
## Funcionalidades
|
||||
|
||||
> Tudo o que define a marca (cores, tipografia, raios, espaçamentos, sombras) está em **um único arquivo**:
|
||||
> [`src/styles/theme.css`](src/styles/theme.css)
|
||||
| Recurso | Comportamento |
|
||||
| -------- | ------------- |
|
||||
| **Idiomas** | PT, EN e ES; detecção pelo navegador; persistência em `localStorage` (`rivuslab-lang`) |
|
||||
| **Tema claro/escuro** | Segue o sistema por padrão; botão na navbar alterna e grava `light` ou `dark` em `rivus-theme` |
|
||||
| **Logos** | `logo-light.png` no tema claro, `logo-dark.png` no escuro (navbar e footer) |
|
||||
| **Design tokens** | Cores, tipografia, raios e sombras centralizados em `src/styles/theme.css` |
|
||||
| **Acessibilidade** | Skip link, `aria-label`, foco visível, contraste pensado para AA |
|
||||
|
||||
Basta editar os valores das CSS variables e a mudança propaga para o site inteiro.
|
||||
---
|
||||
|
||||
## Personalizar a marca
|
||||
|
||||
Edite **[`src/styles/theme.css`](src/styles/theme.css)** — é o único arquivo de tokens. As variáveis são consumidas pelo Tailwind em [`tailwind.config.ts`](tailwind.config.ts).
|
||||
|
||||
```css
|
||||
:root {
|
||||
--color-primary: 35 196 192; /* #23C4C0 — teal */
|
||||
--color-secondary: 15 58 108; /* #0F3A6C — navy */
|
||||
--radius-md: 10px;
|
||||
--space-section-y: 6rem;
|
||||
/* ...etc */
|
||||
--color-primary: 35 196 192; /* #23C4C0 */
|
||||
--color-secondary: 15 58 108; /* #0F3A6C */
|
||||
--color-badge-fg: 15 58 108; /* texto dos badges (tema claro) */
|
||||
/* ... */
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
--color-bg: 11 22 38;
|
||||
--color-badge-fg: 147 220 218; /* texto dos badges (tema escuro) */
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
> ⚠️ Cores são armazenadas como triplets **R G B** (sem vírgulas, sem `rgb()`).
|
||||
> Esse formato permite que o Tailwind aplique opacidade automaticamente, ex.: `bg-primary/40`.
|
||||
> Cores usam triplets **R G B** (sem `rgb()`), para o Tailwind aplicar opacidade (`bg-primary/40`, etc.).
|
||||
> Ex.: `#23C4C0` → `35 196 192`.
|
||||
|
||||
Para encontrar o triplet de um hex, basta converter (ex.: `#23C4C0` → `35 196 192`).
|
||||
### Tema claro / escuro
|
||||
|
||||
### Tema escuro (opcional)
|
||||
- Ativação: `data-theme="light"` ou `data-theme="dark"` no `<html>`.
|
||||
- Script inline em [`index.html`](index.html) evita flash na primeira carga.
|
||||
- Lógica React: [`src/lib/theme.ts`](src/lib/theme.ts), [`src/hooks/useTheme.ts`](src/hooks/useTheme.ts), botão [`src/components/ThemeToggle.tsx`](src/components/ThemeToggle.tsx).
|
||||
|
||||
Já vem incluído como `[data-theme="dark"]`.
|
||||
Para ativar, defina o atributo no `<html>`:
|
||||
|
||||
```html
|
||||
<html lang="pt-BR" data-theme="dark">
|
||||
```
|
||||
| Situação | Resultado |
|
||||
| -------- | --------- |
|
||||
| Sem valor em `rivus-theme` | Segue `prefers-color-scheme` do SO |
|
||||
| Usuário clicou no toggle | Grava `light` ou `dark` e mantém a escolha |
|
||||
| SO muda o tema | Só atualiza o site se não houver preferência salva |
|
||||
|
||||
---
|
||||
|
||||
## Editando os textos
|
||||
## Textos (i18n)
|
||||
|
||||
Os textos vivem em arquivos JSON simples, um por idioma:
|
||||
Um JSON por idioma:
|
||||
|
||||
- [`src/i18n/locales/pt.json`](src/i18n/locales/pt.json) — Português (padrão)
|
||||
- [`src/i18n/locales/en.json`](src/i18n/locales/en.json) — Inglês
|
||||
- [`src/i18n/locales/es.json`](src/i18n/locales/es.json) — Espanhol
|
||||
- [`src/i18n/locales/pt.json`](src/i18n/locales/pt.json) — padrão / fallback
|
||||
- [`src/i18n/locales/en.json`](src/i18n/locales/en.json)
|
||||
- [`src/i18n/locales/es.json`](src/i18n/locales/es.json)
|
||||
|
||||
Para adicionar uma nova chave de texto, edite os três arquivos com a mesma estrutura e referencie via `t('caminho.da.chave')` no componente.
|
||||
Use a mesma chave nos três arquivos e no componente: `t('secao.chave')`.
|
||||
|
||||
O idioma padrão é detectado a partir do navegador e é persistido em `localStorage` (chave `rivuslab-lang`).
|
||||
Chaves de tema (exemplo): `theme.switchToLight`, `theme.switchToDark`.
|
||||
|
||||
---
|
||||
|
||||
## Trocando os logos
|
||||
## Logos e favicon
|
||||
|
||||
Os logos estão em `public/`:
|
||||
Coloque os arquivos em **`public/`**:
|
||||
|
||||
| Arquivo | Onde aparece |
|
||||
| ----------------------- | ---------------------------------- |
|
||||
| `public/logo-light.png` | Navbar e footer (fundo claro) |
|
||||
| `public/logo-dark.png` | Reservado para variações em escuro |
|
||||
| `public/favicon.svg` | Aba do navegador |
|
||||
| Arquivo | Uso |
|
||||
| ------- | --- |
|
||||
| `logo-light.png` | Navbar e footer no **tema claro** |
|
||||
| `logo-dark.png` | Navbar e footer no **tema escuro** |
|
||||
| `favicon.svg` | Ícone da aba |
|
||||
|
||||
Para trocar, basta substituir os arquivos mantendo os nomes (ou ajustar os `src` nos componentes `Navbar.tsx` e `Footer.tsx`).
|
||||
Os caminhos estão centralizados em [`src/lib/logos.ts`](src/lib/logos.ts). Para outros nomes de arquivo, altere só esse módulo.
|
||||
|
||||
---
|
||||
|
||||
## Estrutura
|
||||
## Estrutura do projeto
|
||||
|
||||
```
|
||||
HomePage/
|
||||
├── public/
|
||||
│ ├── logo-light.png ← logo principal (fundo claro)
|
||||
│ ├── logo-dark.png ← logo para fundos escuros
|
||||
│ ├── logo-light.png
|
||||
│ ├── logo-dark.png
|
||||
│ └── favicon.svg
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ ├── Navbar.tsx
|
||||
│ │ ├── Navbar.tsx # menu + idioma + tema
|
||||
│ │ ├── Hero.tsx
|
||||
│ │ ├── Services.tsx
|
||||
│ │ ├── Adaptivework.tsx
|
||||
@@ -98,50 +114,79 @@ HomePage/
|
||||
│ │ ├── Process.tsx
|
||||
│ │ ├── CTA.tsx
|
||||
│ │ ├── Footer.tsx
|
||||
│ │ └── LanguageSwitcher.tsx
|
||||
│ │ ├── LanguageSwitcher.tsx
|
||||
│ │ └── ThemeToggle.tsx
|
||||
│ ├── hooks/
|
||||
│ │ └── useTheme.ts
|
||||
│ ├── i18n/
|
||||
│ │ ├── index.ts ← setup do i18next
|
||||
│ │ ├── index.ts
|
||||
│ │ └── locales/{pt,en,es}.json
|
||||
│ ├── lib/
|
||||
│ │ └── sections.ts ← ids/labels das seções de navegação
|
||||
│ │ ├── logos.ts
|
||||
│ │ ├── sections.ts # ids e labels da navegação
|
||||
│ │ └── theme.ts
|
||||
│ ├── styles/
|
||||
│ │ └── theme.css ← ⭐ arquivo único de customização
|
||||
│ │ └── theme.css # tokens de design
|
||||
│ ├── App.tsx
|
||||
│ ├── index.css
|
||||
│ ├── index.css # componentes (.badge, .btn, …)
|
||||
│ └── main.tsx
|
||||
├── index.html
|
||||
├── tailwind.config.ts ← consome variáveis de theme.css
|
||||
├── postcss.config.js
|
||||
├── tailwind.config.ts
|
||||
├── vite.config.ts
|
||||
└── tsconfig.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Seções da página
|
||||
|
||||
1. **Hero** — proposta de valor + CTAs + visual com mini "editor"
|
||||
2. **Services** — Outsourcing, Squads, Consultoria
|
||||
3. **AdaptiveWork** — destaque para a especialização em Planview AdaptiveWork
|
||||
4. **Why Us** — 4 pilares de diferenciação
|
||||
5. **Process** — 4 etapas (Diagnóstico → Proposta → Execução → Evolução)
|
||||
6. **CTA** — bloco escuro com email/WhatsApp
|
||||
7. **Footer** — navegação, contato, redes sociais
|
||||
1. **Hero** — proposta de valor e CTAs
|
||||
2. **Services** — outsourcing, consultoria
|
||||
3. **AdaptiveWork** — especialização Planview
|
||||
4. **Why Us** — diferenciais
|
||||
5. **Process** — etapas do trabalho
|
||||
6. **CTA** — contato (e-mail / WhatsApp)
|
||||
7. **Footer** — links, redes e copyright
|
||||
|
||||
Navegação por âncoras (`#services`, `#contact`, etc.) definidas em [`src/lib/sections.ts`](src/lib/sections.ts).
|
||||
|
||||
---
|
||||
|
||||
## Dicas
|
||||
## Classes utilitárias (CSS)
|
||||
|
||||
- O menu mobile abre como drawer abaixo da navbar e bloqueia o scroll do body.
|
||||
- Todos os ícones vêm de [`lucide-react`](https://lucide.dev) — basta importar e usar.
|
||||
- Animações de entrada usam `framer-motion` com `whileInView` (`once: true`) para não repetir.
|
||||
- Acessibilidade: skip-link, `aria-label`, contrastes AA e foco visível.
|
||||
Definidas em [`src/index.css`](src/index.css):
|
||||
|
||||
- `.container-rl` — largura máxima e padding horizontal
|
||||
- `.btn-primary` / `.btn-secondary` / `.btn-ghost`
|
||||
- `.badge` — pills (cor do texto via `--color-badge-fg`)
|
||||
- `.card` / `.card-hover`
|
||||
- `.heading` — títulos de seção
|
||||
|
||||
Ícones: [Lucide React](https://lucide.dev). Animações: `framer-motion` com `whileInView` (`once: true`).
|
||||
|
||||
---
|
||||
|
||||
## Próximos passos sugeridos
|
||||
## Deploy
|
||||
|
||||
- Integrar formulário de contato a um backend (ex.: Resend, Formspree).
|
||||
- Adicionar página de cases / portfolio.
|
||||
- Configurar SEO com meta tags por idioma.
|
||||
- Adicionar analytics (Plausible / Umami).
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
Publique o conteúdo de **`dist/`** (Netlify, Vercel, S3 + CloudFront, nginx estático, etc.).
|
||||
Configure fallback para `index.html` se o host usar SPA routing (esta landing é single-page com âncoras).
|
||||
|
||||
---
|
||||
|
||||
## Próximos passos (sugestões)
|
||||
|
||||
- Formulário de contato (Resend, Formspree, API própria)
|
||||
- Página de cases / portfólio
|
||||
- Meta tags e Open Graph por idioma
|
||||
- Analytics (Plausible, Umami, etc.)
|
||||
- Atualizar `theme-color` no `<meta>` conforme o tema ativo
|
||||
|
||||
---
|
||||
|
||||
## Licença
|
||||
|
||||
Projeto privado — uso interno RivusLab.
|
||||
|
||||
Reference in New Issue
Block a user