0010 — UI unificada para apps server-render¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-15 · Decidido em: 2026-07-15
Contexto¶
A constituição regia documentação e engenharia, mas não tinha convenção de UI.
Resultado (loop §6, feedback de app): cada app que renderiza HTML no servidor —
telas de admin/auditoria/dev, mesmo internas e protegidas pelo gate de auth do
Coolify — reinventava o visual. O integrador já tinha layout.html +
custom-theme.css + logo + Bootstrap padronizados; o tradutor ecom nasceu com
<table border="1"> cru até ser retrofitado à mão. Divergência que só se pega no
olho, nunca no gate.
Pior: o custom-theme.css do integrador usava #0066CC/#6B7280 (chute "azul
vibrante ou similar"), não a paleta canônica do logo (royal #064490, prata
#939495) — o mesmo drift de cor que a reconciliação do xadm.css (2026-07-01) já
tinha corrigido no lado docs. Templatizar copiando teria propagado a cor errada.
Decisão¶
Todo app com views renderizadas no servidor segue o layout padrão X-Adm — piso na constituição §5 (UI dos apps), detalhe operável em Java/Micronaut §UI.
- Fragment base único (
head/navbar/scripts), Bootstrap 5, header escuro com logo + nome do cliente, e os idiomas visuais da casa (table-striped,badge bg-*,alert-*). O app só escreve o conteúdo de cada tela; o esqueleto vem do template. - Paleta única: o
custom-theme.cssdos apps deriva dos mesmos tokens doxadm.cssdo portal — uma fonte, dois consumidores (MkDocs Material no portal, Bootstrap nos apps). Sem CSS próprio por app além do necessário. - Kit rastreado, opcional no manifesto:
layout.html,custom-theme.css,logo.pngefavicon.icosão templates rastreados (sha256, sincronizados pela/xadm-docs) mas opcionais — app headless/Flutter não tem view, então não é defasagem; app com views mantém em sincronia. Adoção fora-do-padrão vira item de conformidade do/xadm-docs§3b (app tem views server-render e não usa o layout → não-conformidade). - Escopo = server-render. A casa só server-renderiza em Micronaut/Thymeleaf; Flutter é nativo e tem identidade própria (Flutter), fora deste raio.
Alternativas consideradas¶
- Só documentar a convenção (sem template rastreado): o drift continua só no olho — o problema exato reportado. Preterido: o valor está no gate, não na prosa.
- Xerocar o kit do integrador: propagaria a cor errada (
#0066CC) e o navbar inconsistente (dois estilos,<style>inline + CSS). Preterido em favor de re-derivar limpo na paleta canônica. - Binários fora do manifesto (referenciar o logo publicado): app server-render precisa
servir asset local (offline/gate), e o sync por
/xadm-docsjá cobre binário por sha256. Preterido: kit completo (imagens inclusas) rastreado é consistente com o resto.
Consequências¶
- Tela nova nasce no padrão sem esforço: puxa os três fragments, escreve o miolo.
- Zero drift de CSS por app; operador que abre integrador e tradutor vê a mesma casa.
- Favicon é default substituível (gerado do wordmark); a variação quadrada do logo segue design pendente (backlog item 27) — quando existir, gera-se um favicon melhor.
- Sem guarda offline: conformidade de UI é auditoria de código (
/xadm-docs§3b) + revisão de PR, não ovalida-frontmatter— o layout não tem shape validável por script.