# Design System — Site Institucional Omni

> **Documento oficial de regras, decisões e convenções do projeto.**
> Consolidado em 2026-08-04. Base congelada — só alterar mediante solicitação explícita do time.

---

## 0. Fontes oficiais e protocolo de divergência

Duas fontes **oficiais e complementares** — **sempre consultar AMBAS antes de criar ou modificar qualquer componente da interface**:

| Fonte | Para quê |
|---|---|
| **Figma** | Layouts, medidas, componentes, especificações visuais (cores/tamanhos/posições exatas). |
| **`design system.md`** (este arquivo) | Regras, decisões, padrões e convenções do projeto. |

- **Figma:** `fileKey = lCboMncjYTlvrgqifU4Y76`. Consultar via MCP (skill `figma-design-to-code` antes de `get_design_context`).
- **Em caso de divergência entre Figma e este documento:** **NÃO** supor nem alterar a implementação por conta própria. Identificar a inconsistência e **solicitar orientação** antes de prosseguir.
- Toda página/componente novo segue exatamente este DS. Ao reeditar Home ou páginas existentes, aplicar as mesmas regras (consistência visual, estrutural e de experiência).

### Nós de referência no Figma
- **Desktop:** canvas `0:1` → frame "Linha criativa" `1:688` (1440px).
- **Mobile:** canvas `1:6232` → frame "Linha criativa" `1:6682` (393px). *(Obs.: `get_metadata` sem nodeId só lista "Desktop"; acessar Mobile direto por `1:6232`.)*
- **Frames responsivos de exemplo (hero):** 1280 = `1:2860`, 1440 = `1:2832` (frame antigo, altura 680), 1680 = `1:2809`, 1920 = `1:2781`.
- **Banners do hero:** Foto 01 = `1:1645`, Foto 02 = `1:1672`, Foto 03 = `1:1699`.

---

## 1. Stack

Laravel 11 · Inertia 2 (sem API REST) · React 19 + TypeScript 5 · Tailwind CSS 4 (CSS-first, `@theme`) · shadcn/ui · Vite 6 · Filament 3 (CMS) · MySQL. **Não trocar tecnologia sem decisão explícita.**

---

## 2. Tipografia

**Fonte: Averta CY** (Regular 400 / Semibold 600 / Bold 700). Arquivos `.woff2` em `public/fonts/`, `@font-face` em `resources/css/app.css`. Fallback: Inter / system-ui.

Escala (token → tamanho / line-height), definida em `@theme`:

| Token Tailwind | Tamanho | line-height | Uso |
|---|---|---|---|
| `text-heading-lg` | 33px | 1.2 | Heading Large — título do hero (desktop) |
| `text-heading-md` | 27px | 1.2 | Heading Medium — título de seção (desktop) / título hero mobile |
| `text-heading-sm` | 23px | 1.2 | Heading Small — título de seção (mobile) |
| `text-subtitle` | 19px | 1.4 | Subtítulos |
| `text-body` | 16px | 1.4 | Texto padrão |
| `text-body-sm` | 14px | 1.4 | Texto secundário / datas / labels |

- **Tracking:** `letter-spacing: -0.02em` no `body` (equivale ao "letter-spacing -2" do Figma; ex.: 33px → -0.66px).
- **Título de seção** (`SectionTitle`): `text-heading-sm` no mobile → `text-heading-md` no desktop (variante `web:`); cor `gray-700` (algumas seções específicas usam `gray-800` — seguir o Figma da seção).
- **Nunca** definir `fontFamily` inline no JSX. Sempre via classe Tailwind do tema.

---

## 3. Cores (tokens `@theme`)

**Nunca usar hex inline no JSX.** Sempre tokens semânticos.

**Primária (laranja Omni)** — `primary` = primary-main. As numeradas são TINTS (mais claras):
`--color-primary #E95814` · `-100 #FEF6F3` · `-200 #FDEBE3` · `-300 #F8CDB9` · `-400 #F6BCA1` · `-600 #F29B72` · `-700 #F08A5B`

**Neutras (gray — substitui o gray do Tailwind):**
`-100 #F7F7F8` · `-200 #F0F0F2` · `-300 #E1E2E4` · `-400 #C2C5C9` · `-500 #8C9099` · `-600 #676D79` · `-700 #3E4149` · `-800 #151618`

**Apoio:**
`--color-secondary-blue #E5EBF5` (cards "Nossas Soluções") · `--color-footer-muted #A4A7AF` (texto secundário do footer) · `--color-divider #D9D9D9` (divisória da navbar) · `--color-hero-blue #002FA7` · `--color-hero-orange #331E0E` (bases dos gradientes do hero)

---

## 4. Raios e sombras

**Raios:** `sm 4px` (tags) · `md 12px` (botões, setas, tabs, inputs) · `lg 16px` (botão de menu mobile) · `xl 20px` (cards, navbar) · `2xl 24px` (mega menu). *(Card de vídeo do hero: 32px.)*

**Sombras (validadas no Figma):**
- `shadow-subtle`: `0px 6px 200px -1px rgba(0,0,0,0.1)` — cards.
- `shadow-navbar`: `0px 6px 16px rgba(194,197,201,0.42)` — navbar/mega menu.
- `shadow-menu-button`: `0px 6px 8px rgba(194,197,201,0.42)` — botão hambúrguer mobile, card de notícias.

---

## 5. Grid & Responsividade ("Telas Maiores")

Regra oficial (validada nos frames 1280/1440/1680/1920): responsivo e consistente **até 1920px**, sem esticar/deformar, sem excesso de espaço vazio, preservando enquadramento das imagens e hierarquia visual (fontes ficam fixas — só o container escala).

- **Breakpoint Web/Mobile = 720px.** Token de variante: **`web:`** (`--breakpoint-web: 720px`). Abaixo de 720 = composição Mobile (estrutura própria, não é media query simples).
- **Grid de conteúdo (regra única):** `max-w-[1440px]` + `px-[140px]` no desktop →
  - ≤ 1440: conteúdo = viewport − 280 (margem lateral **140px**; ex.: 1280 → conteúdo 1000).
  - > 1440: conteúdo trava em **1160px** centralizado; margem cresce (260 em 1680, **380 em 1920**).
  - **Mobile:** `px-7` (margem **28px**; conteúdo 337 em 393).
  - Encapsulado no componente **`Section`** (`components/ui/Section.tsx`). `AppSection` e `SiteFooter` seguem a mesma regra.
- **Navbar é exceção ao grid:** **1180px centralizado (fixo)** — margem = (viewport − 1180)/2 (130 em 1440, 370 em 1920). *Escolha do time: fixo/centralizado, fiel ao Figma.*
- Passar exato pelos valores do Figma nos tamanhos definidos **e** fluir suave em qualquer largura intermediária (não usar breakpoints "duros" que criem saltos).

---

## 6. Tokens no código & `cn()` (armadilha crítica)

- Tokens de cor/tipografia/espaçamento em `resources/css/app.css` dentro de `@theme`. `tailwind.config.ts` cobre só `content` + `darkMode` (via `@config`).
- **`cn()` (`lib/utils.ts`) usa `extendTailwindMerge`** registrando os tamanhos custom (`heading-lg/md/sm`, `subtitle`, `body`, `body-sm`) no grupo `font-size`. **Sem isso, o `tailwind-merge` descarta `text-heading-*` ao ver `text-white`/`text-gray-*` (acha que é cor) e zera o tamanho do título.** Ao criar novo token de fonte, **registrar aqui também**.

---

## 7. Navbar (desktop)

- **1180×80**, centralizado, fixo (flutua sobre o hero). **Distância do topo: 40px** (`pt-10`).
- **Branco #FFFFFF a 90%** (`bg-white/90`) + `backdrop-blur 2.5px` + `shadow-navbar` + radius **20px**.
- **Padding interno 24px** horizontal. Linha do menu = **32px** de altura (→ 24px acima/abaixo dentro dos 80px).
- **Espaçamentos:** logo 45px (px-3) · logo→menu **40px** · entre itens **16px** · padding de cada item **8px** · label→chevron **4px**.
- **Busca:** divisória `#D9D9D9` de 28px + pl-8 + ícone 24px.
- **Botão "Área do cliente":** outline (borda `primary-600`, texto `primary`), radius 12, à direita.
- **Itens:** Para você ▾ · Para empresas ▾ · A Omni · Atendimento · Agentes Omni. Só *Para você* e *Para empresas* abrem **mega menu no hover** (radius inferior 24, border-top `gray-200`, colunas de 340).
- **Chevron:** SVG 8×5 (viewBox) — renderizar com largura fixa (`w-3`), **nunca** em box quadrado com `preserveAspectRatio="none"` (distorce).

## 7.1. TopBar mobile
Branco 90% + `blur 6px`, radius 20, padding 20/12, `shadow-navbar`. Hambúrguer: bg branco, radius 16, padding 12, `shadow-menu-button`. Menu **accordion** (itens 64px, submenu 48px, divisórias `gray-100`, botão "Área do cliente" em `primary-200`).

---

## 8. Hero / Banner

**Estrutura & responsividade**
- **Altura = 100vh** (`h-screen`) — o hero preenche o viewport (frames DS: 832/900/1050/1080 = as próprias resoluções).
- **Imagem full-bleed:** `object-cover object-[50%_12%]` — corta por baixo preservando o rosto; enquadramento constante em qualquer tela (não re-zooma por resolução).
- **Conteúdo no grid** (Seção 5): texto/bullets ancorados à esquerda (margem do grid), setas à direita.

**Texto**
- Bloco de **326px** de largura (o título fecha em **3 linhas**; 320px quebra pra 4 por ~0,7px).
- Título: `text-heading-lg` (33px) branco · **centralizado na vertical** (`top-1/2`).
- Espaçamentos: título → subtítulo **12px**; (título+subtítulo) → CTA **28px**.
- Subtítulo: `text-subtitle` (19px) branco. CTA: botão primário "Saiba mais" (px-28/py-16, radius 12).
- **`titleShadow`** (opcional, por slide): `text-shadow: 0px 18px 24px rgba(41,41,41,0.6)` — só quando a foto é clara/movimentada (ex.: Foto 03). Classe `.hero-title-shadow`.

**Bullets & setas**
- **Centro-alinhados a `top-[75%]`** da altura (mesma linha de centro).
- **Bullets brancos** (sobre imagem escura): slot 16px, círculo 12px, gap 12px. Ativo: `bg-white` + `ring-1 ring-primary-200/20`. Inativo: `bg-white/20` + `border border-white/80`. (Quantidade = nº de slides.)
- **Setas:** 60×60, `bg-gray-100/10` (= rgba 247,247,248,0.1), `border-white/20`, radius 12, gap 12. Chevron branco **14px** (prev = sem rotação "‹", next = `rotate-180` "›").

**Shape do banner (CMS — exclusivo, 3 opções)**
- Campo `shape: 'blue' | 'orange' | 'black'`. **Um shape por banner, exclusivo (sem preto fixo por baixo).**
  - `blue` / `orange` → Color Degrade cobrindo ~**57%** à esquerda (`hero-overlay-blue` / `hero-overlay-orange`).
  - `black` → Shape Black cobrindo a imagem inteira, preto **30%** (`hero-overlay-black`).

**Carrossel (CMS-ready)**
- **Autoplay: troca a cada 8 segundos** (`HERO_AUTOPLAY_MS = 8000`). Setas manuais (desktop) + swipe (mobile) + bullets clicáveis.
- Slide = `{ image, title, subtitle, ctaLabel, ctaHref, shape, titleShadow? }`. CMS pode cadastrar materiais distintos para desktop e mobile.

**Hero mobile:** composição própria (393×680) — título `text-heading-md` (27px), bloco de 280px, sem setas (swipe), bullets; shape em camada única cobrindo a imagem.

---

## 9. Componentes

- **`Section`** — container do grid (Seção 5).
- **`Button`** — variantes `primary` (bg primary, branco), `outline` (borda primary), `secondary` (bg primary-200), `ghost`; tamanhos `sm/md/lg`; radius 12, `font-bold`.

### 9.1. Estados de hover dos botões (padrão oficial)
- **Botão Primário (laranja):** default `bg-primary` (#E95814) → **hover `bg-primary-700` (#F08A5B)** — o laranja clareia (Figma node 35:3336). **Não** usar `opacity` no hover. Vale para TODO botão laranja (CTA do hero, "Baixar aplicativo", "Pesquisar", "Saiba mais", etc.).
- **Botão Outline (fundo transparente):** default `border-primary-600` (#F29B72) + texto `primary` (#E95814), bg transparente → **hover `bg-primary-100` (#FEF6F3) + `border-primary-400` (#F6BCA1) + texto `primary-700` (#F08A5B)**; disable `border-primary-100` + texto `primary-300` (#F8CDB9) (Figma node 35:3400). Vale para TODO botão outline (Área do cliente, "Continuar lendo", "Ver mais notícias", etc.).
- **Botão Outline - Secondary (cinza):** default `border-gray-300` (#E1E2E4) + texto `gray-600` (#676D79), bg transparente → **hover `bg-gray-100` (#F7F7F8)** mantendo borda e texto (sem sombra); disable `border-gray-100` (#F7F7F8) + texto `gray-200` (#F0F0F2) (Figma node 39:3422). Usado nas **tabs "Para você / Para empresas"** da seção Soluções.
- Demais tipos (implementação atual, a confirmar no Figma): `secondary` → hover `bg-primary-300`; `ghost` → hover `bg-primary-100`.
- Ao criar/estilizar qualquer botão novo, seguir este padrão de hover.
- **`SectionTitle`** (Seção 2) · **`Eyebrow`** (primary, Body Bold, sem uppercase).
- **Cards:** *Acesso Rápido* (branco, 216px, radius 20, `shadow-subtle`, hover borda `primary-400`/título → primary) · *Nossas Soluções* (`secondary-blue`, 216×333, título Subtitle Bold, imagem no rodapé; **hover** = `shadow-subtle` + overlay `rgba(34,54,88,0.1)` — token `overlay-navy/10` — Figma node 1:1941) · *Notícias* (308px, imagem 208px radius 20, data `gray-600`, título Subtitle Bold, "Continuar lendo" outline) · *Glass* (blur 4, `bg-white/10`, `border-white/60`, radius 20 — seção "Baixe o app").
- **Setas de carrossel (variante clara, sobre fundo branco):** 60×60, bg branco, borda `gray-300`, radius 12, chevron laranja/cinza (usar o asset do Figma).
- **Indicadores mobile:** carrosséis usam "Progress Bar" (não dots) no mobile.

---

## 10. Arquitetura frontend

```
resources/js/
  components/
    ui/          # globais reutilizados em 2+ features (Button, Section, SectionTitle, Eyebrow, Card…)
    layout/      # SiteHeader, Navbar, MobileTopBar, SiteFooter, SiteLayout, navigation.ts
  features/<feature>/
    <Feature>Page.tsx   # orquestra a página
    sections/ components/ data/ hooks/ types.ts enums.ts constants.ts index.ts
  lib/ (utils.ts cn, motion/variants.ts)
  Pages/*.tsx    # FINO: só wrapper Inertia + props
```
- `Pages/*.tsx` são apenas wrappers. Lógica/tipos/dados ficam na feature.
- **Dados serializáveis** em `data/*.ts` (sem JSX embutido). Assets centralizados em `data/assets.ts`.
- Tokens semânticos, sem hex/fontFamily inline. Animações em `lib/motion/variants.ts` (framer-motion).
- Antes de criar componente/página: consultar **Figma (MCP)** + **este documento**; reutilizar `components/ui` antes de criar.

---

## 11. Assets

`public/images/{hero,solucoes,app,agentes,noticias,social,stores,logo,icons}` + `public/fonts` (Averta CY `.woff2`). Assets exportados do Figma. Mapa do Brasil (Agentes) = 1 PNG (export via screenshot). **Imagens estão pesadas (~26MB) — otimizar (webp) numa etapa futura.**
