# ADR-009 — UI: nativo primeiro + Tailwind 4 + daisyUI + Lucide; CMS próprio e independente

| Campo | Valor |
|---|---|
| **Status** | Aceito (2026-10-20) |
| **Data** | 2026-10-14 |
| **Plano de origem** | `wiki/plan/01-analise-e-decisoes.md` |
| **Relacionadas** | ADR-016, ADR-010, ADR-020, ADR-028 |

## Contexto

O `cms/` adotou **Filament v4** — pesado e com acessibilidade difícil de garantir — que internamente
usa **TipTap** no editor de texto rico. O `sucesu-cms` implementou um CMS próprio inspirado no
**AdminLTE4** (`V2/layouts/cms/`), com Bootstrap 5 + jQuery e muitos recursos "vendorizados", mas
com dependências legadas. O projeto exige **controle de acessibilidade (eMAG)**, **mínimo de
dependências** e **zero CDN**.

## Decisão

- Base nativa: **Blade** + roteamento/validação nativos.
- **CMS é um shell próprio e independente** em `src/layout/Cms` (namespace `Layout\Cms`; views registradas
  como `cms::`), inspirado no AdminLTE4/`sucesu-cms`, com a filosofia de **"espaços, não controle"**:
  o módulo **nunca monta o shell** — usa o componente **`<x-layout::cms>`** (mesma simetria do portal,
  `<x-layout::portal>` — ADR-016), informa os campos padrão (`title`, `breadcrumbs`) e preenche
  **apenas o conteúdo central (`<main>`)**; espaços adicionais são slots/stacks nomeados
  (`actions`, `styles`, `scripts`, `modals`). O shell fornece header, sidebar, rodapé,
  acessibilidade e o grid.
- **Sem Livewire e sem qualquer framework de UI reativo**: Blade + formulários HTML nativos +
  validação nativa + **JS pequeno vendorizado** (progressive enhancement). **Filament: não.**
  Adotar UI reativa exigiria **nova ADR** justificando o ganho frente a simplicidade/determinismo
  (ADR-001/ADR-002).
- **Editor de texto rico:** **TipTap** é o **único** editor do projeto (ADR-028) — vendorizado e
  desacoplado do Filament, com AST JSON e parser PHP. O que se descarta é o **Filament**, não o
  TipTap.
- **Tailwind 4** (CSS-first) + **daisyUI** (primitivas acessíveis/tematizáveis) + **Lucide**
  (SVG vendorizado, sem wrapper composer).
- **Zero CDN: tudo vendorizado/build local.**

## Justificativa (alternativas descartadas)

- **Filament** — descartada: peso, acessibilidade difícil e acoplamento do domínio à UI.
- **Livewire (ou qualquer UI reativa)** — descartada: dependência pesada + máquina de estado
  cliente-servidor + harness de teste próprio; fere **simplicidade, determinismo e mínimo de
  dependências** (ADR-001/ADR-002) para telas que HTML+HTTP resolvem.
- **Bootstrap 5 + jQuery** (como no `sucesu-cms`) — descartada: legado, peso e a11y.
- **Wrapper composer de ícones** — descartada: dependência evitável; SVG vendorizado basta.

## Consequências

**Positivas**
- Controle total de acessibilidade e tema; bundle enxuto; poucas dependências.
- Módulos só preenchem "espaços" — não reimplementam o shell.

**Custos / negativas**
- O shell é código nosso (manutenção), mas pequeno e reutilizável.
- Interatividade complexa pode exigir JS próprio (vendorizado).

## Licenças de terceiros (verificado)

Stack de UI **100% permissiva**, seguro para uso comercial e redistribuição multi-cliente:

| Pacote | Licença |
|---|---|
| daisyUI 5 (npm) | **MIT** |
| Tailwind CSS 4 | **MIT** |
| Lucide (ícones) | **ISC** |
| Atkinson Hyperlegible Next (fonte) | **SIL OFL 1.1** |

- **Política:** aceitar apenas licenças **permissivas** (MIT, ISC, Apache-2.0, BSD, OFL);
  **copyleft (GPL/AGPL) ou não-permissiva falha o gate**. Manter `THIRD_PARTY_LICENSES`.
- MIT permite uso comercial, modificação e **redistribuição** sem royalties nem copyleft;
  a única obrigação é preservar o aviso de copyright/licença. Diferente de bibliotecas pagas
  que proíbem redistribuir componentes — inviável para um fornecedor multi-prefeitura.
- A marca "daisyUI" não é licenciada: não usar para sugerir endosso.

## Exemplo mínimo (comparativo)

```blade
{{-- ❌ Módulo reimplementando o painel --}}
<html><body><aside>…menu…</aside><div>…</div></body></html>

{{-- ✅ Módulo define apenas o conteúdo central + campos padrão do shell --}}
<x-layout::cms
    :title="__('noticias::index.title')"
    :breadcrumbs="[['label' => __('noticias::index.title')]]"
>
    <x-slot:actions><x-cms::button.save>{{ __('core::actions.save') }}</x-cms::button.save></x-slot:actions>

    … conteúdo (main) …
</x-layout::cms>

@push('scripts') … @endpush
```

## Verificação

- `tools/vendor-check` falha em referência a CDN.
- Gate de a11y (ADR-025) verde no shell e nas views de módulo.

## Referências

- `sucesu-cms/V2/layouts/cms/`; `wiki/plan/12-admin-cms-editor.md`.
