/* ============================================================================
   form-validacao.css — o ÚNICO visual de erro de formulário do sistema.

   POR QUE ESTE ARQUIVO EXISTE, e por que o bloco NÃO ficou em cadastros.css:
   o estado de erro morava lá sob `.cad-premium .cad-surface .cad-field`, ou seja,
   exigindo TRÊS classes aninhadas. Medido em 2026-08-20:

       13 telas de cadastro   cad-premium ✓  cad-surface ✓  cad-field ✓  -> borda + fundo + texto
       reservas.html          cad-premium ✓  cad-surface ✗  cad-field ✗  -> so texto
       login / e-mail         cad-premium ✗  cad-surface ✗  cad-field ✗  -> so texto, e de outra cor

   A saida NAO e pendurar `cad-premium cad-surface cad-field` no login: isso arrastaria a
   superficie, a metrica de campo (--occ-field-h), o raio, o override de select2 e o
   [data-valido] inteiros do design de cadastro para dentro do card de login — regressao
   visual grande para resolver uma questao de seletor.

   A saida e inverter: um componente de ERRO nunca deveria ter sido escopado por tela. O
   seletor interno abaixo e byte a byte o que estava em cadastros.css:516-529 e :563-568,
   so que sem o prefixo. Login, e-mail e reservas passam a funcionar sem UMA classe nova.

   ORDEM DE CARGA (head.html): este arquivo entra por ULTIMO entre os custom, depois de
   overrides.css. Nao e detalhe — overrides.css:67-70 declara
   `.form-control:focus { border-color/box-shadow ... !important }` GLOBAL; sem vir depois,
   o campo com erro voltaria a ficar teal exatamente quando recebe foco, que e o inverso
   do necessario. Os !important daqui existem por essa mesma razao.
   ============================================================================ */

/* ---------------------------------------------------------------- estado invalido

   A classe entra no CONTAINER do campo, NUNCA no <input>. E o inverso da convencao do
   Bootstrap, e e intencional: e por isso que a regra vendor `.form-control.is-invalid`
   (bootstrap.css:3122) nunca casa neste projeto. Manter assim — se o JS passar a marcar
   o proprio input, aquela regra acorda e traz um icone SVG de fundo que ninguem pediu. */
.is-invalid .form-control,
.is-invalid .form-select,
.is-invalid select,
.is-invalid input:not([type=checkbox]):not([type=radio]):not(.form-check-input):not(.btn-close),
/* select2 esconde o <select> real e desenha um <span> proprio. Sem esta linha, campo com
   select2 e o unico que fica sem borda vermelha — gap que ja existia em uh/pdv/produto-servico. */
.is-invalid .select2-container--default .select2-selection--single {
	border-color: var(--occ-danger) !important;
	background-color: var(--occ-danger-soft) !important;
}

/* O seletor de cor guarda o valor num <input type="hidden"> e mostra a cor num <button>.
   Sem esta linha o campo reprovado nao teria NENHUM sinal visivel — o hidden nao aparece
   e o botao nao casa com os seletores de .form-control acima. */
.is-invalid .cad-cor-btn {
	border-color: var(--occ-danger) !important;
	box-shadow: 0 0 0 3px var(--occ-danger-soft) !important;
}

.is-invalid .form-control:focus,
.is-invalid .form-select:focus,
.is-invalid input:focus,
.is-invalid select:focus {
	border-color: var(--occ-danger) !important;
	box-shadow: 0 0 0 3px var(--occ-danger-soft) !important;
}

/* ---------------------------------------------------------------- a mensagem

   UMA classe para os dois casos: a mensagem que o servidor renderiza (fragmento
   views/fragments/campo-erro.html) e a que o form-validacao.js cria ao vivo. E isso que
   garante um so visual POR CONSTRUCAO — antes eram duas regras (.text-danger e
   .cad-msg-cliente) que alguem precisava lembrar de manter iguais, e que ja tinham
   divergido na cor do icone.

   display:flex e nao inline: a mensagem ocupa a linha inteira abaixo do campo, e o
   align-items:flex-start mantem o icone alinhado com a PRIMEIRA linha de um texto que
   quebra em duas. */
.xn-erro {
	display: flex;
	align-items: flex-start;
	gap: 5px;
	margin-top: 5px;
	font-size: var(--occ-fs-xs);
	line-height: var(--occ-lh-tight);
	color: var(--occ-danger);
}

/* margin-top de 1px alinha a optica do glifo com a altura-x do texto; flex:none impede
   que o icone encolha quando a mensagem e longa. */
.xn-erro i {
	font-size: .8125rem;
	margin-top: 1px;
	flex: none;
}

/* ---------------------------------------------------------------- o aviso

   Irmão do erro, para o que NÃO recusa o valor ("Hóspede já cadastrado.", "Dígito verificador
   não confere."): mesma posição e tamanho da .xn-erro, em âmbar e com ⓘ. Uma frase curta; o
   detalhe vai no title. Montado só por FormValidacao.avisar — nenhuma tela escreve o seu. */
.xn-aviso {
	display: flex;
	align-items: flex-start;
	gap: 5px;
	margin-top: 5px;
	font-size: var(--occ-fs-xs);
	line-height: var(--occ-lh-tight);
	color: var(--occ-warn);
}
.xn-aviso[title] {
	cursor: help;
}
.xn-aviso i {
	font-size: .8125rem;
	margin-top: 1px;
	flex: none;
}
/* Erro e aviso no mesmo campo: o erro fala primeiro, o aviso sai (o JS também o tira). */
.is-invalid .xn-aviso {
	display: none;
}

/* Duas mensagens no mesmo campo (raro, mas acontece quando o DTO tem @AssertTrue numa
   propriedade derivada alem da validacao do campo) empilham sem dobrar o espacamento. */
.xn-erro + .xn-erro {
	margin-top: 2px;
}
