Conn2Flow
Navegação das docs

SDD

req-148: Modais de sistema sem CSS em páginas Tailwind que não os declararam

Na tela de login do Photon, um erro de senha abre o modal de alerta. Ele aparecia sem estilo: o botão "Ok" tinha texto branco sobre fundo transparente — ilegível — e o cartão não…

  • Status do intake: implemented-pending-homologation

  • Data: 2026-08-30

  • Origem: relato do Engenheiro Chefe — "a caixa de alerta tah com problemas visuais" em http://localhost/photon/signin/, com o HTML do modal colado

  • Classificação: defeito visual, arquitetura de compilação CSS

  • Batch: BATCH-150


1. O sintoma

Na tela de login do Photon, um erro de senha abre o modal de alerta. Ele aparecia sem estilo: o botão "Ok" tinha texto branco sobre fundo transparente — ilegível — e o cartão não tinha sombra nem largura máxima.

Medido no navegador, com o alerta aberto:

Classe Esperado Entregue
bg-sky-600 azul rgba(0, 0, 0, 0)
shadow-xl sombra none
max-w-md 448px 361px (sem limite)

7 das 12 classes do modal não tinham regra nenhuma na página.

2. A causa

O componente interface-alerta-modal-tailwind tem seu CSS compilado — 4.694 bytes, no disco e no banco. O problema não era ausência de CSS, e sim de qual página ele fazia parte.

A compilação Tailwind é por recurso: cada página compila as utilities que o HTML dela usa, mais as dos recursos declarados em tailwind_dependencies. O modal é injetado em runtime por interface_alerta(), então nenhuma varredura de HTML o encontra — ele precisa ser declarado.

E estava, em algumas páginas:

perfil-usuario     -> declara os 3 modais
Area-restrita      -> declara os 3 modais
acessar-sistema    -> declara apenas 2FA e login-metodos     ← a tela de login

interface_alerta() pode disparar em qualquer tela. Enquanto a declaração fosse manual, a lista seria uma lista de exceções — e bastava estar incompleta uma vez para a tela quebrar. Foi exatamente o que aconteceu.

Nas variantes Fomantic o problema nunca existiu: as classes delas (ui modal, ui button) vivem na folha global do Fomantic, que toda tela carrega. É uma armadilha exclusiva do Tailwind, onde cada utility precisa ser compilada por quem a usa.

3. A correção

Os três modais que a biblioteca de interface injeta em runtime passaram a ser dependência automática de toda página Tailwind, resolvida no compilador (tailwind_recursos_dependencies()), e não declaração por página.

if ($type === 'pages') {
    foreach (tailwind_recursos_modais_de_sistema() as $modalId) {
        $dependencies[] = ['type' => 'components', 'id' => $modalId,
                           'scope' => 'global', 'opcional' => true];
    }
}

Cobertura estrutural: nenhuma página nova precisa lembrar de nada.

Por que opcional

A primeira versão era estrita e abortou a compilação do Photon inteiro:

❌ Erro fatal: Dependência Tailwind do Gestor não encontrada: interface-alerta-modal-tailwind

O projeto traz os modais em pt-br e não em en. Ausência aqui não é erro — é uma instalação que não tem aquele componente naquele idioma.

A distinção que ficou: dependência declarada continua falhando alto (ali a ausência significa erro de digitação); dependência automática degrada em silêncio, porque quem a acrescentou foi o sistema, não o autor do recurso.

Uma tentativa descartada no caminho

Antes disso tentei emitir o CSS do componente junto com o HTML dele, dentro de interface_componentes_incluir(). Não funcionou, e a razão é instrutiva: aquela rotina faz $_GESTOR['pagina'] .= $html, ou seja, roda depois de a <head> estar montada. Chamar gestor_pagina_recursos_incluir() ali é inócuo — ninguém mais vai ler $_GESTOR['css-precompiled'].

Descartada em favor da solução de build, que é onde o problema realmente vive.

4. Validação

Medida (modal aberto, senha inválida) Antes Depois
Classes sem regra 7 0
shadow-xl none sombra completa
bg-sky-600 (botão) rgba(0,0,0,0) oklch(0.588 0.158 241.966)
max-w-md 361px 448px
  • 34 recursos recompilados no core; pipelines de [REDACTED]-local e [REDACTED]-local passam.

  • PHPUnit 955/955 (4 novos); Vitest 378/378.

  • Confirmação visual: cartão branco, título, mensagem e botão azul legível.

5. Observações registradas, não corrigidas

  1. O Photon não tem os componentes do core em en — só pt-br. Se o projeto for usar inglês, a sincronização de core precisa trazê-los. Hoje a compilação apenas os ignora.

  2. Bloqueio de IP disparado pelos testes: as repetições de login inválido acionaram a proteção contra força bruta (acessos.status = 'bloqueado', tipo login, IP [REDACTED] do Docker). O registro foi removido do ambiente local. É o sistema funcionando como projetado.

O Futuro é Híbrido: Humano + IA.

O Conn2Flow é a ferramenta. Se você precisa do Arquiteto para desenhar a estratégia da sua empresa usando essa tecnologia...

Contrate Consultoria Especializada