# PluraAssistent

Biblioteca de acessibilidade da Plura para React e Next.js.

## O que a biblioteca faz

- Renderiza o `PluraAssistent` com alto contraste, controle de fonte, filtros de daltonismo, redução de movimento e modo noturno.
- Organiza esses recursos em um menu redesenhado com visão geral, hierarquia mais clara e áreas dedicadas para configuração.
- Aceita `simplifyText` para habilitar a simplificação de texto por IA.
- Funciona sem IA. Se `simplifyText` não for informado, o assistente continua funcionando e o card de IA aparece como indisponível.
- Inclui um leitor em áudio com seleção manual para textos, imagens e componentes, usando `alt`, `aria-label`, `aria-labelledby`, `title` e fallbacks acessíveis.
- Inclui contraste seletivo com auditoria e correção automática baseada em WCAG AA para textos e componentes visíveis.
- Permite mover manualmente o assistente pela tela e manter a última posição salva no navegador.
- Permite redimensionar a janela do assistente no desktop, com limites seguros e restauração do último tamanho salvo.
- Mantém gráficos SVG legíveis no alto contraste quando você marca os elementos do gráfico com atributos `data-plura-contrast-chart`.
- Exporta utilitários para marcar elementos que devem receber borda no modo contraste.

## Instalação

```bash
npm install plura-assistent
```

## Uso básico em React

```tsx
import { PluraAssistent } from "plura-assistent";

export default function App() {
  return <PluraAssistent />;
}
```

## Uso com IA

```tsx
import { PluraAssistent } from "plura-assistent";

const simplifyText = async (texto: string) => {
  const resposta = await fetch("/api/simplificar", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ texto }),
  });

  const { resultado } = await resposta.json();
  return resultado;
};

export default function App() {
  return <PluraAssistent simplifyText={simplifyText} />;
}
```

## Next.js App Router

O pacote pode ser importado direto no `app/layout.tsx`, sem provider local.

```tsx
import type { Metadata } from "next";
import { PluraAssistent } from "plura-assistent";
import "./globals.css";

export const metadata: Metadata = {
  title: "Minha aplicação",
  description: "Exemplo com PluraAssistent",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="pt-BR">
      <body>
        <PluraAssistent />
        {children}
      </body>
    </html>
  );
}
```

## Props

- `simplifyText?: (texto: string) => Promise<string>`
- `placement?: { top?: string; bottom?: string; left?: string; right?: string }`
  Se `left` for informado, o label "Seu assistente virtual" abre para a direita do ícone.
  O `placement` continua controlando apenas a posição do ícone flutuante.
  Quando o usuário move o menu manualmente, a última posição da janela do assistente fica salva no navegador.
  No desktop, quando o usuário redimensiona a janela, o último tamanho também fica salvo no navegador.
- `triggerColor?: string | { from: string; to?: string; direction?: string }`
  Personaliza o fundo do botão flutuante e do label lateral sem alterar a logo. Aceita hexadecimal, `rgb()`, `hsl()`, `var(--token)` e gradiente.

Exemplo com cor estática:

```tsx
<PluraAssistent triggerColor="#3c446a" />
```

Exemplo com degradê:

```tsx
<PluraAssistent
  triggerColor={{
    from: "#3c446a",
    to: "#9c416f",
    direction: "135deg",
  }}
/>
```

Exemplo com string de background:

```tsx
<PluraAssistent
  triggerColor="linear-gradient(135deg, #3c446a 0%, #9c416f 100%)"
/>
```

Se você usa tokens em CSS ou Tailwind v4, também pode passar a variável diretamente:

```tsx
<PluraAssistent triggerColor="var(--color-fuchsia-600)" />
```

## Janela do assistente

- O arraste continua disponível pelo botão de mover no header.
- O redimensionamento manual fica disponível no desktop pelo canto inferior direito da janela.
- Em telas pequenas, o menu continua usando o layout responsivo padrão e o resize manual fica desabilitado.
- Ao diminuir bastante a largura da janela, o conteúdo interno entra em um layout compacto automaticamente.

## Leitor em áudio

O leitor em áudio já faz parte do menu do assistente e não precisa de configuração extra.
Ele usa a API nativa de fala do navegador para ler textos, imagens e componentes selecionados manualmente na tela.

Observações:

- depende de suporte do navegador a `speechSynthesis`
- tenta usar uma voz `pt-BR` quando o navegador disponibiliza essa opção e fala em velocidade `0.8`
- para imagens e componentes, prioriza `alt`, `aria-label`, `aria-labelledby`, `title` e texto visível
- quando não houver descrição disponível, usa um fallback acessível

## Contraste seletivo

O contraste seletivo também já faz parte do menu do assistente.
Ele audita a página hospedeira e pode corrigir contraste insuficiente com ajuste mínimo seguindo WCAG AA.

Observações:

- foca em textos visíveis e componentes interativos, como botões, links, inputs, textareas, placeholders visíveis, selects, badges e cards clicáveis
- pode auditar, aplicar correções, reanalisar e observar mudanças dinâmicas na página
- a correção é heurística e baseada no DOM e no CSS computado do navegador
- não tenta corrigir imagens, `background-image`, gradientes complexos, canvas ou pseudo-elementos
- não altera a interface interna do próprio PluraAssistent

## Escala de fonte

O ajuste de fonte continua global e persistido no navegador.
Agora ele combina uma variável CSS na raiz com fallback compatível para elementos que ainda dependem de tamanhos fixos.

Se você tiver uma subtree que não deve participar da escala, marque o container com:

```html
<div data-plura-font-scale-opt-out="true">
  ...
</div>
```

## Marcação para borda no modo contraste

`plura-card` e `data-plura-card` não criam um card visual pronto por conta própria.
Eles apenas marcam elementos que devem receber borda quando o modo contraste estiver ativo.

Se você já estiver usando `PluraAssistent`, o registro necessário acontece automaticamente.

Exemplo com o helper React:

```tsx
import { ContrastBorder } from "plura-assistent";

export function Example() {
  return (
    <ContrastBorder className="rounded-lg border p-4">
      <h3>Meu card</h3>
      <p>Conteúdo do card</p>
    </ContrastBorder>
  );
}
```

Exemplo com marcador direto:

```tsx
export function Example() {
  return (
    <div data-plura-card className="rounded-lg border p-4">
      <h3>Meu card</h3>
      <p>Conteúdo do card</p>
    </div>
  );
}
```

Se você for usar esses marcadores sem montar `PluraAssistent`, registre manualmente no browser:

```tsx
"use client";

import { useEffect } from "react";
import { registerContrastBorder } from "plura-assistent";

export function ContrastBorderSetup() {
  useEffect(() => {
    registerContrastBorder();
  }, []);

  return null;
}
```

## SVGs no alto contraste

Se você tiver gráficos SVG que perdem legibilidade no modo de alto contraste, marque os elementos principais do gráfico:

- `data-plura-contrast-chart` no `<svg>`
- `data-plura-contrast-chart-canvas` no fundo do gráfico
- `data-plura-contrast-chart-segment` em cada setor ou barra, com `--plura-contrast-fill`
- `data-plura-contrast-chart-hole` em miolos internos, como donut charts
- `data-plura-contrast-chart-label` em textos do SVG
- `data-plura-contrast-chart-dot` em marcadores de legenda fora do SVG

Exemplo:

```tsx
<svg data-plura-contrast-chart>
  <circle data-plura-contrast-chart-canvas />
  <path
    data-plura-contrast-chart-segment
    style={{ "--plura-contrast-fill": "#9ca3af" } as React.CSSProperties}
  />
  <text data-plura-contrast-chart-label>Total</text>
</svg>
```

## Exports

```ts
export { PluraAssistent, ToggleContrast, ContrastBorder, registerContrastBorder };
export type {
  PluraAssistentProps,
  PluraAssistentPlacement,
  PluraAssistentTriggerColor,
  PluraAssistentTriggerGradient,
};
```
