# Link

> Componentes / Navegação e estrutura · Estado: **Em andamento** — Implementado e utilizável, mas ainda sem a validação completa de acessibilidade.

O link de texto — num parágrafo, numa lista de referências, no pé de um cartão —, sempre sublinhado. Interno vai pelo roteador do Next; externo, `mailto:` e `tel:`, por `<a>`. Com `novaAba`, avisa que abre em outra aba. Com `previa` (E155), mostra um cartão com o destino no ponteiro e no foco.

- Função: Navegação e estrutura
- Também chamado de: link, hiperlink, âncora, link de texto, hover preview, prévia de link, cartão de prévia
- Mora em: `app/components/atoms/Link.tsx`
- Página: [https://phorte-design-system.vercel.app/styleguide/peca/Link](https://phorte-design-system.vercel.app/styleguide/peca/Link)
- Ficha no Storybook: [components-base-link](https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-base-link--docs)
- Prévia ao vivo, sozinha: [https://phorte-design-system.vercel.app/previa/Link/0](https://phorte-design-system.vercel.app/previa/Link/0)
- Todas as peças: [https://phorte-design-system.vercel.app/llms.txt](https://phorte-design-system.vercel.app/llms.txt)

## Como usar no código

```tsx
import { Link } from '@/app/components/atoms/Link';

<Link href={…}>…</Link>
```

O `…` marca as props obrigatórias — ver *Propriedades*.

## Uso

### Variantes na ficha

1. [Padrão](https://phorte-design-system.vercel.app/previa/Link/0)
2. [No texto](https://phorte-design-system.vercel.app/previa/Link/1)
3. [Nova aba](https://phorte-design-system.vercel.app/previa/Link/2)
4. [Inverso](https://phorte-design-system.vercel.app/previa/Link/3)
5. [Com prévia](https://phorte-design-system.vercel.app/previa/Link/4)

Para **navegar** a partir de um texto: o edital no meio de um parágrafo, o e-mail da secretaria, "Ver todos os cursos" no fim de uma lista.

### Quando não usar

Para agir no lugar (enviar, abrir, fechar), use o Button. Para um link com cara de botão ("Inscrever-se"), o Button com `href`. Para o caminho de páginas, o Breadcrumb.

### Faça

- Escreva o destino no texto do link: "o edital completo", nunca "clique aqui".
- Use `novaAba` só para fora do site, e com parcimônia: sair da aba é decisão de quem lê.
- Use `variant="inverso"` sobre fundo escuro, e `sutil` em texto corrido cinza.
- Use `previa={{ titulo, descricao, imagem }}` (E155) quando o destino não é óbvio pelo texto — um curso citado num parágrafo, um documento externo. O título e a descrição dizem o que há do outro lado; a imagem é decorativa.
- Escreva a prévia como o destino se apresenta (E155b): o título é o nome da página de destino, como ela o mostra; a descrição é uma frase, de até ~160 caracteres, dizendo o que a pessoa encontra lá. O cartão tem formato fixo — a descrição para em 3 linhas —, e o texto passa inteiro para o leitor de tela.

### Evite

- Tirar o sublinhado: no meio do texto, a cor sozinha não separa o link para quem não distingue o vermelho (WCAG 1.4.1).
- Link sem destino (`href="#"`) para disparar ação: aí é Button.
- Dois links seguidos para o mesmo lugar.
- Pôr na prévia o que a pessoa precisa saber para decidir: no celular não há ponteiro, e ela só aparece no foco. O essencial vai no texto do link.
- Prévia em todo link de um texto: vira ruído. Uma ou duas por bloco, nos destinos que pedem.
- Esperar que a prévia se preencha sozinha a partir do destino: ela não lê a página do outro lado (decisão do Marcelo, 2026-10-01, E155b) — buscar o Open Graph pelo servidor abria risco de segurança (SSRF), de página ou build travados por destino lento ou fora do ar, e de texto e imagem que ninguém revisou.

### Anatomia

1. **Texto** — Peso médio, sublinhado de 1px afastado 4px, na cor da variante.
2. **Ícone de nova aba** — Com `novaAba`: `ExternalLink` de 12px, decorativo, e "(abre em nova aba)" só para o leitor.
3. **Prévia** — Com `previa` (E155): cartão `--card` de 288px (até a largura da tela menos 32px), borda e sombra, embaixo do link: a imagem 16:9 (decorativa, `alt=""`), o título, a descrição e, para link de fora, o endereço.

### Estados

| Estado | O que muda |
| --- | --- |
| Padrão | `padrao`: `--primary`; `sutil`: `--ink`; `inverso`: `--ink-inverse`. |
| Hover | O sublinhado engrossa para 2px, e a cor escurece (ou, no `sutil`, fica vermelha). |
| Foco | O anel de foco (`anel-de-foco`; no `inverso`, o inverso), só no teclado. |
| Prévia aberta | O cartão embaixo do link (em cima, se embaixo não couber; empurrado para dentro da tela, se passaria da borda). Abre no ponteiro depois de 400ms e no foco na hora. Formato fixo (E155b): imagem 16:9, título que quebra linha sem corte, descrição em até 3 linhas — testado na ficha com texto longo. |

### Comportamento

| Situação | O que acontece |
| --- | --- |
| Endereço interno (`/cursos`) | Vai pelo `next/link`: pré-carrega e não recarrega a página. |
| Externo, `mailto:` ou `tel:` | Um `<a>` comum. |
| Com `novaAba` | `target="_blank"` e `rel="noopener noreferrer"`, e o aviso para quem ouve — conferido no teste da ficha. |
| Ponteiro do link para a prévia | A prévia continua aberta enquanto o ponteiro vai do link ao cartão, e fecha quando ele deixa a região do link e do cartão — medido com o mouse no navegador, a 1280 e a 320px (E155, SC 1.4.13). |
| Prévia com imagem | A imagem só carrega quando a prévia abre: nada vem de outro site antes de a pessoa pedir. |
| Aviso fora do Link | O pedaço `AvisoDeNovaAba` (ícone e "(abre em nova aba)") é exportado para links que não usam o Link — o Footer e os menus da Navbar (E71). |

### Relacionados

- [Button](https://phorte-design-system.vercel.app/styleguide/md/Button.md) — Para agir, ou link com cara de botão (`href`).
- [Breadcrumb](https://phorte-design-system.vercel.app/styleguide/md/Breadcrumb.md) — O caminho de páginas.
- [Tooltip](https://phorte-design-system.vercel.app/styleguide/md/Tooltip.md) — A dica curta de um controle; a prévia do Link segue a mesma mecânica.

## Especificação

### Propriedades

| Prop | Tipo | Padrão | Obrigatória | Descrição |
| --- | --- | --- | --- | --- |
| `variant` | `'padrao' \| 'sutil' \| 'inverso'` | `'padrao'` | não | Variante do `cva`. |
| `href` | `string` | — | sim |  |
| `novaAba` | `boolean` | `false` | não | Abre em outra aba (E67). Ganha o ícone e o aviso "(abre em nova aba)" para quem ouve, e o `rel="noopener noreferrer"`. Use pouco: tirar a pessoa da aba em que ela está é decisão dela. |
| `previa` | `PreviaDoLink` | — | não | Prévia do destino (E155, o "hover preview" da revisão 4): um cartão com a imagem, o título e a descrição do que está do outro lado, no ponteiro **e no foco**. Complementa o link — o nome continua sendo o texto dele —, e não tem nada clicável dentro. No celular, sem ponteiro, aparece no foco. |

Aceita também: `Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>`.

### Medidas

| Parte | Valor | Classe |
| --- | --- | --- |
| Sublinhado | 1px (2px no hover), afastado 4px | `decoration-1 underline-offset-4` |
| Ícone de nova aba | 12px | `Icone tamanho="xs"` |

### Tokens de cor

| Token | Valor | Usado como |
| --- | --- | --- |
| `--border` | #E5E5E5 | `border-border` |
| `--card` | #FFFFFF | `bg-card` |
| `--foreground` | #1A1A1A | `text-ink` |
| `--ink-inverse` | #FAFAFA | `text-ink-inverse` |
| `--ink-inverse-muted` | #C7C7C7 | `text-ink-inverse-muted` |
| `--muted` | #F4F6F9 | `bg-muted` |
| `--muted-foreground` | #595959 | `text-muted-foreground` |
| `--primary` | #D42B2B | `text-primary` |
| `--primary-dark` | #A81E1E | `text-primary-dark` |

## Acessibilidade

### Teclado

| Tecla | Faz |
| --- | --- |
| Tab | Leva o foco ao link — conferido no teste da ficha. |
| Enter | Segue o link (Espaço não: é link, não botão). |
| Esc | Com a prévia aberta, fecha a prévia e o foco fica no link — conferido no teste da ficha. |

### Leitor de tela

- O nome é o texto do link; com `novaAba`, "Portal do MEC (abre em nova aba)" — conferido no teste da ficha.
- Não tem o alvo de 44px: é texto corrido, a mesma exceção do `Button variant="link"`.
- A prévia descreve o link (`aria-describedby`, como o Tooltip): o leitor diz o nome do link e depois o título e a descrição — conferido no teste da ficha. Não tem nada clicável dentro.

### O que sustenta o estado

Usa os padrões: estatico. Falta ouvir com leitor de tela: estatico.

## Status e recursos

| Tipo | Recurso | Status |
| --- | --- | --- |
| Código | `app/components/atoms/Link.tsx` | Disponível |
| Ficha | https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-base-link--docs | Disponível |
| Teste de acessibilidade | axe em `npm run test` | No gate de todo commit |
| Leitor de tela | Passada da E33 | Falta ouvir |
| Design | Figma | Desativado até a Fase 2 |

### Histórico

- `7b99f03` 2026-10-01 — E155b: Link com prévia — formato fixo, e a prévia não lê o destino
- `251416b` 2026-10-01 — E159: Testimonials — o vídeo toca dentro do cartão, YouTube e Vimeo
- Histórico completo no GitHub: https://github.com/srbunnie/Pos-Phorte-Design-System/commits/main/app/components/atoms/Link.tsx
