# Fase 3 — o desenho da interface

Registro das decisões de aparência e comportamento da interface nova. O que a
Fase 3 constrói está no roadmap; o que está aqui é **por que a tela se parece
com o que se parece**, para que a próxima tela não reabra a discussão.

---

## 1. A agenda mantém a grade por barbeiro

Decisão do dono, 13/09/2026: *"mantenha a grade por barbeiro e comece pela
comanda"*.

Era a única pergunta que a proposta de redesenho deixou em aberto. A agenda do
ERP hoje é uma grade de colunas — uma coluna por colaborador, as horas descendo
— e a alternativa considerada era uma lista única ordenada por horário, que
ocupa menos largura e funciona melhor no telefone.

A grade fica. E a razão é operacional, não estética: quem olha a agenda no
balcão não pergunta *"o que vem agora"*, pergunta *"quem está livre agora"* — e
essa segunda pergunta se responde varrendo uma linha da grade com o olho. Numa
lista por horário a mesma pergunta exige ler todos os itens daquela faixa e
montar a resposta de cabeça.

Consequência para o desenho: **a largura é um recurso escasso da agenda**, e
nenhuma decisão global pode gastá-la. É por isso que o sistema abaixo não tem
barra lateral fixa nem cartões com margem larga.

---

## 2. O ouro veio do logo, e não do gosto

`#D9B437`, amostrado de `public/global/img/logo-1.png` — **5.197 pixels**, a cor
dominante do arquivo. Não é um dourado escolhido numa paleta: é o dourado que já
está na fachada, na capa e no avental.

Isso importa porque a alternativa era herdar o acento do template do Vite. Até
13/09/2026 o `frontend/src/index.css` era o arquivo do template **inteiro**:
acento roxo `#aa3bff`, um `--social-bg` para um bloco de redes sociais que não
existe, `#root` travado em 1126px e centrado, e uma escala tipográfica ancorada
num 18px que ninguém escolheu.

Nada disso tinha sido decidido para o PDV — mas **vazou para decisões**: a borda
de todo `.aviso`, o hover de todo botão e o realce de toda linha de tabela eram
roxos por herança. Um valor que ninguém escolheu ainda é um valor que a tela usa.

---

## 3. Acento e semântica não se misturam

A regra em uma frase: **o ouro é do que a pessoa veio fazer; o vermelho é do que
não volta atrás. Nunca o mesmo botão.**

Ela existe porque o contrário existe, e custa. No ERP de hoje, **quatro
confirmações destrutivas** — limpar comanda, remover item, desmarcar
agendamento, cancelar venda — usam `btn green-jungle`, o mesmo verde do Salvar.
Desmarcar apaga a linha. Nada na cor separa o que volta atrás do que não volta.

O protótipo React tinha herdado a mesma falha, e pior: **os nove botões da tela
eram a mesma regra de CSS**. `confirmar`, que estorna um pagamento, saía
visualmente idêntico a `lançar`.

Agora são três formas, e a diferença é de **peso e preenchimento além de cor** —
porque parte dos homens não separa vermelho de verde, e o PDV é operado por
barbeiro, não por quem escolheu a paleta:

| classe | aparência | para quê |
|---|---|---|
| `.primaria` | preenchida de ouro, negrito | o que a pessoa veio fazer: `lançar`, `receber`, `autorizar`, `finalizar comanda` |
| `.destrutiva` | contorno e texto vermelhos, negrito; preenche no hover | o que não volta atrás: os dois `confirmar` |
| (padrão) | contorno neutro, peso normal | recuar, navegar, abrir |

**Os botões que ABREM a confirmação ficam neutros** — `remover`, `estornar`.
Eles não fazem nada: revelam o aviso. Pintá-los de vermelho encheria a tabela de
vermelho e gastaria o sinal antes da hora em que ele é preciso.

E os avisos ganharam três degraus, em que o **preenchimento é o degrau**:

| classe | aparência | diz |
|---|---|---|
| `.aviso` | contorno, trilho âmbar, sem fundo | leia antes de seguir |
| `.aviso-forte` | trilho e fundo vermelhos | isto apaga pagamento |
| `.erro` | texto vermelho | o servidor recusou |

O trilho do `.aviso` era do acento. Virou âmbar porque acento agora é só de
ação: trilho dourado ao lado de botão dourado faz a página ter dois lugares
dizendo *"aqui"* — e nenhum dos dois é o botão.

---

## 4. Dois temas, e o que eles pegaram

O tema claro e o escuro continuam existindo. É escolha do autor do `App.css`,
que já estava escrita no cabeçalho dele — *"as cores vêm das variáveis de
`index.css`, então o tema claro e o escuro seguem sozinhos"* — e continua certa:
a barbearia com vitrine ao meio-dia não é a mesma tela do balcão às dez da
noite.

**A frase era verdade pela metade, e a metade que faltava era o tema escuro.**
Cinco cores não a cumpriam, porque eram literais cravados no `App.css` —
`#1a7f4b` em `.estado.aberta`, e `#b4232a` em `.estado.cancelada`, `.fiado`,
`.aviso-forte` e `.erro`. Literal não segue tema nenhum: ele fica onde foi
escrito.

Medido sobre os dois fundos:

| literal | onde | tema claro | tema escuro |
|---|---|---|---|
| `#1a7f4b` | `.estado.aberta` | 4,74:1 — passa | **3,78:1 — reprova** |
| `#b4232a` | `.erro`, `.cancelada`, `.fiado`, `.aviso-forte` | 6,16:1 — passa | **2,91:1 — reprova** |

Os dois passam no claro e falham no escuro, o que diz como foram escolhidos:
olhando uma tela só. `.estado` tem 0,72rem e `.erro` 0,8rem — texto pequeno, em
que o mínimo é 4,5:1. E o pior dos dois, **2,91:1, era a cor do texto que avisa
que a ação apaga pagamento**.

Agora são `--ok` e `--perigo`, que existem nos dois temas: 5,04:1 e 6,23:1 no
claro, 8,52:1 e acima no escuro.

O ouro tem duas versões pelo mesmo motivo. `#D9B437` cheio funciona como
**preenchimento** nos dois temas, mas como **texto** sobre branco ele não tem
contraste — por isso `--ouro-texto` escurece no claro (`#8A6D12`) e clareia no
escuro (`#E3C255`). E o que se escreve em cima do ouro cheio é quase-preto
quente, não branco: branco sobre `#D9B437` dá **1,9:1** e é ilegível; o
quase-preto dá 9,8:1.

---

## 5. Sem fonte da web, e é decisão de operação

A proposta em documento usava Archivo e IBM Plex. A tela não usa.

Ela abre entre um cliente e o próximo, muitas vezes por dia, e um
`font-display: swap` significa **um piscar a cada abertura**. A pilha do sistema
não pisca, e o que a coluna de dinheiro precisa — `tabular-nums` — ela já
entrega. A marca entra pela cor e pela estrutura, que é onde ela importa numa
tela de balcão.

---

## 6. O que mudou na comanda

Primeira tela a receber o sistema, por decisão do dono (*"comece pela comanda"*).

- **`index.css`** deixou de ser o arquivo do template e passou a ser o sistema:
  24 variáveis, nos dois temas, com semântica separada do acento.
- **`App.css`** passou a consumi-las. Os cinco literais saíram. Zero variável
  consumida sem definição, conferido nos dois sentidos — e a conferência valeu:
  no primeiro corte, **os seis tokens que o `App.css` usava tinham sumido**, e a
  tela teria ficado sem cor nenhuma.
- **Sete botões** receberam variante: quatro `.primaria`, dois `.destrutiva`, e
  os de recuar ficaram neutros.
- **`index.html`** trocou `lang="en"` por `lang="pt-BR"`. Não é etiqueta: com
  `en`, o corretor do navegador sublinha **todo nome de cliente digitado no
  PDV**, a hifenização quebra palavra no lugar errado e o leitor de tela
  pronuncia português com fonética inglesa. O título deixou de ser `frontend`.
- **O favicon** era o losango roxo do Vite. O ícone da aba tem trabalho real:
  separar esta aba da aba do ERP, que fica aberta do lado.
- **Quatro arquivos mortos do template** saíram: `frontend/public/icons.svg` e os três de
  `src/assets/`, que nenhum import referenciava.

### A paginação que faltava

A lista dizia *"1 de 11"* e **não tinha como ver as outras dez**.

O vão passava batido justamente porque a tela não mentia: `.contagem` sempre
disse quantas de quantas. Ela não enganava, ela parava.
`listarComandasAbertas` já aceitava `pagina` e `porPagina`, e o envelope já
devolvia os dois — faltava o controle.

Duas coisas que ele precisou resolver:

1. **`porPagina` vem do envelope, não de uma constante da tela.** Quem decide o
   tamanho da página é `ComandasController::indexAction`. Cravar 20 aqui seria
   repetir a regra do servidor — e regra repetida é regra que diverge.
2. **A página pode deixar de existir embaixo da tela.** Finalizar a última
   comanda da página 3 tira a página 3 da coleção, e o servidor devolve `dados`
   vazio. Escrever *"nenhuma comanda aberta nesta unidade"* aí seria mentira: as
   das páginas 1 e 2 continuam abertas. A tela recua uma página e busca de novo.

E trocar de página **fecha o detalhe**: ele é de uma comanda que pode não estar
na página nova, e detalhe aberto sobre uma linha que saiu da lista é pior que
detalhe nenhum.

---

## 7. O que ainda NÃO foi visto renderizado

Escrito aqui porque *build verde não prova a tela* — foi abrindo a página no
navegador que apareceram três defeitos que teste, portão e revisão adversarial
não acharam (roadmap, Fase 3, linha 6 da tabela).

**Visto:** os dois temas no estado de erro — fundo, tinta, pilha de fontes,
`.aviso` com o trilho âmbar, título e favicon da aba. Foi assim que apareceu o
link **`rgb(158,158,255)`**, o azul-roxo padrão do navegador no único elemento
clicável do estado de erro. Nenhuma regra de `a` existia, nem no template nem no
sistema novo. Corrigido para `--ouro-texto`, com sublinhado mantido — link que
só se distingue por cor não se distingue para quem não separa as duas cores.

**Não visto:** a tabela, os selos de estado, os três degraus de aviso, os sete
botões com variante e o controle de paginação. Falta sessão para a API
responder: o banco carregado é a cópia anonimizada de produção, e
`definir-senha-contrato.php` **recusa** rodar nele — guarda correta, ele não
troca senha num banco de 2.432 usuários. O banco de contrato teria sessão, mas
tem **uma** comanda, então nem a paginação apareceria; e repontar o
`config/autoload/local.php` para ele depende de restauração por `trap`, que já
deixou este repositório com guarda arrancada uma vez.

**Fica devendo, e o lugar de pagar é o primeiro uso real da tela** — que é
exatamente o mecanismo que a Fase 3 já provou valer oito vezes.
