/* ===== 03-formulario.css — texto auxiliar, campos, ajuda, inputs, senha, botões, picker, empty state =====
   Fatia do antigo app.css (09/08/2026). O NÚMERO NO NOME É A POSIÇÃO NA CASCATA: é a ordem
   dos <link> no index.html, e trocá-la muda quem vence. Regra e política em 01-base.css. */

/* Text helpers */
.muted { color: var(--muted); }
.hint { color: var(--muted); font-size: .85rem; }
.error { color: var(--danger); font-weight: 600; }

/* Aviso preso a um campo — hoje só o telefone repetido do cadastro de cliente. Amarelo de espera
   (--wait) e não vermelho de erro, pelo mesmo motivo da faixa de demonstração: nada está errado, o
   Salvar continua liberado e dois clientes podem dividir um telefone de propósito. Vermelho aqui
   leria como "corrija isto para continuar", e o prestador que está cadastrando a esposa do cliente
   pararia num muro que não existe. */
.campo-aviso {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    margin-top: .45rem;
    padding: .55rem .7rem;
    background: var(--wait-tint);
    border-radius: .5rem;
    font-size: .85rem;
    line-height: 1.35;
    color: var(--ink);
}

.campo-aviso > .icon { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; color: var(--wait); margin-top: .1rem; }
.campo-aviso-corpo { flex: 1 1 auto; min-width: 0; }
.campo-aviso-corpo p { margin: 0; }
/* O botão só existe quando o aviso aparece, e ele é a ação inteira do aviso: ocupa a largura para o
   polegar acertá-lo sem mira, como todo botão de bloco do app. */
.campo-aviso-corpo > .btn-secondary { margin-top: .5rem; }

/* A crítica do formulário (<FeedbackErro>) recebe o foco quando aparece, para ser lida pelo leitor
   de tela e para dizer a quem enxerga onde a tela parou. Sem contorno o salto ficaria mudo: a página
   rolaria sozinha e nada indicaria por quê. Em :focus e não :focus-visible pelo mesmo motivo do
   .resultado-alert — foco movido por código, não pelo teclado. */
.error:focus { outline: 2px solid var(--danger); outline-offset: 3px; border-radius: .3rem; }

/* .login-card foi removido na S15: login e cadastro eram as duas únicas telas com cartão de largura
   fixa (360px) centralizado, e no navegador isso deixava o formulário espremido no meio da tela,
   já nascendo com barra de rolagem. As duas passaram ao padrão de página (<h1> + .dev-panel),
   herdando a largura de .app-main (720px, fluida abaixo disso) como todas as demais. */

.field { margin-bottom: 1rem; display: flex; flex-direction: column; }
.field label { font-size: .85rem; font-weight: 600; margin-bottom: .35rem; }

/* Rótulo com uma marca à direita — o "olho cortado" do <CampoPrivado> ou um <Ajuda>. A marca vai na
   ponta direita (justify entre rótulo e ícone) e não colada ao texto porque é de lá que o balão do
   Ajuda abre: alinhado pela direita do campo, para dentro da tela. Colado ao rótulo, à esquerda, o
   balão sairia pela borda esquerda. A margem do label migra para a linha (o label empilhado a zera). */
.field-label-row { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .35rem; }
.field-label-row > label { margin-bottom: 0; }

/* Campo de cabeçalho com ícone mnemônico à esquerda em vez de label acima (Orçamento: Cliente,
   Endereço, Equipamento, Válido até) — app de uso repetido em campo, o ícone é decorado uma vez só.
   O rótulo textual não some: vira aria-label no controle e title no ícone/wrapper pra leitor de
   tela e tooltip. */
.field-icon {
    display: flex;
    align-items: center;
    gap: .65rem;
    margin-bottom: .75rem;
}

.field-icon > .icon {
    flex-shrink: 0;
    width: 1.35rem;
    height: 1.35rem;
    color: var(--muted);
}

.field-icon > .input,
.field-icon > .picker-summary,
.field-icon > .btn-secondary {
    flex: 1;
    min-width: 0;
}

/* Duas .field-icon lado a lado (Orçamento: Data do orçamento + Válido até). Mesmo gotcha do
   .filtro-datas: input[type=date] nativo + ícone mnemônico apertam em telas de 360px — reduz
   padding/fonte do input e o tamanho do ícone pra caber os dois campos no painel.

   E **empilha quando não couberem**, em vez de espremer. O input[type=date] nativo tem largura
   mínima intrínseca, e quando ela não cabe o widget **não corta o próprio ícone: corta o texto** —
   no Android o campo virou "23/08/202", uma data que o prestador lê como certa e está errada. Com
   um <Ajuda> na ponta direita do "Válido até" é o que acontecia num celular comum.

   Os 13rem são o limiar, e o número não é palpite arredondado: a coluna útil é a largura da tela
   menos ~67px (folga da .app-main mais a do painel), então dois campos + gap só cabem lado a lado
   acima de ~491px — ou seja, **todo celular empilha e todo navegador não**. Foi calibrado depois de
   11rem falhar num aparelho real: o widget de data do Android é mais largo que o do Chrome de mesa,
   e limiar ajustado no navegador mente sobre o celular, que é onde o app é usado. */
.field-icon-row { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: .75rem; }
.field-icon-row > .field-icon { flex: 1 1 13rem; min-width: 0; margin-bottom: 0; }
.field-icon-row > .field-icon > .icon { width: 1.1rem; height: 1.1rem; }
.field-icon-row .input { padding: .55rem .4rem; font-size: .85rem; }
.field-icon-row .input::-webkit-calendar-picker-indicator { padding: 0; margin-left: .2rem; }

/* ---- Ajuda pontual (<Ajuda>) ----
   O "i" na ponta direita de um campo cujo comportamento não se lê no controle. É um
   <details>/<summary> — o porquê está no comentário do componente; daqui interessa que o gatilho
   precisa perder a setinha nativa (list-style + o pseudo-elemento do WebKit) para virar só o ícone.

   1,5rem de alvo de toque, e não os 2,75rem do .icon-btn: este divide a linha com um campo, e cada
   pixel que ele toma sai da largura de um input[type=date], que **não tem para onde encolher** — o
   widget nativo do Android é mais largo que o do navegador e, sem espaço, ele trunca o ano
   ("23/08/202") em vez de cortar o próprio ícone. 24px é o mínimo do WCAG 2.5.8 (AA); a régua de
   44px do 2.5.5 é AAA e vale para as ações que o app trata como principais, não para uma revelação
   de texto que não muda nada. */
.ajuda { position: relative; flex: 0 0 auto; align-self: center; }

.ajuda-gatilho {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: .5rem;
    color: var(--muted);
    cursor: pointer;
    list-style: none;
}

.ajuda-gatilho::-webkit-details-marker { display: none; }
.ajuda-gatilho .icon { width: 1.05rem; height: 1.05rem; }
.ajuda-gatilho:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.ajuda[open] > .ajuda-gatilho { color: var(--brand-dark); background: var(--brand-tint); }

/* Dentro do par de datas o gatilho ainda encosta no campo: o gap de .65rem do .field-icon separa o
   ícone mnemônico do controle, e entre controle e ajuda ele não separa nada — só tira largura de
   quem não tem de sobra. Sobram os 2px do :active para o toque não parecer colado. */
.field-icon-row .ajuda { margin-left: calc(-.65rem + 2px); }

/* Fundo que fecha o balão ao toque em qualquer outro ponto da tela. Invisível e sem cor: ele não
   escurece nada — o balão não é modal, não interrompe tarefa nenhuma e some sem pedir licença.
   Abaixo do balão (26) e na mesma faixa do .aviso-acao (25); dentro de um BottomSheet (30) o toque
   no próprio sheet não chega até aqui, e nesse caso fechar continua sendo tocar no ícone de novo. */
.ajuda-fundo { position: fixed; inset: 0; z-index: 25; background: transparent; }

/* Escuro sobre claro pelo mesmo motivo do .aviso-acao: é um elemento que aparece por cima de
   conteúdo qualquer, e precisa se ler como camada, não como mais um parágrafo do formulário.
   Alinhado pela direita porque o lugar do ícone é a ponta direita do campo — o balão abre para
   dentro da tela, sobre o campo que ele explica. */
.ajuda-balao {
    position: absolute;
    top: calc(100% + .3rem);
    right: 0;
    z-index: 26;
    width: max-content;
    max-width: min(20rem, 76vw);
    padding: .65rem .8rem;
    border-radius: .6rem;
    background: var(--brand-dark);
    color: #fff;
    font-size: .85rem;
    font-weight: 400;
    line-height: 1.35;
    text-align: left;
    /* pre-line, não normal: é o que faz um "\n" no Texto virar parágrafo, sem obrigar o componente a
       receber RenderFragment por causa de uma quebra de linha. Espaço continua colapsando. */
    white-space: pre-line;
    box-shadow: 0 4px 16px rgba(28, 27, 25, .28);
}

.ajuda-balao-titulo { display: block; margin-bottom: .1rem; }

.input {
    width: 100%;
    box-sizing: border-box;
    padding: .8rem .85rem;
    font-size: 1rem;
    border: 1px solid var(--line);
    border-radius: .6rem;
    background: #fff;
}

.input:focus { outline: 2px solid var(--brand); border-color: var(--brand); }

/* Campo de senha com o olho de revelar (CampoSenha). O botão fica DENTRO da moldura do campo, e não
   ao lado: ao lado ele comeria ~3rem de largura do input justo na tela mais estreita, e o par
   "campo + botão" leria como dois controles irmãos em vez de um controle e o interruptor dele. O
   padding à direita é o que abre o buraco — sem ele a senha passa por baixo do ícone. */
.campo-senha { position: relative; display: flex; align-items: center; }

.campo-senha .input { padding-right: 3rem; }

/* Alvo de toque de 2.75rem como o .icon-btn, mas em tom neutro: o olho é auxiliar do campo e na cor
   da marca competiria com o "Entrar" logo abaixo, que é a ação da tela. Vira cor de marca com a
   senha à mostra — segundo sinal do estado, além do ícone trocado, para quem não distingue os dois
   desenhos de olho de relance (tela ao sol, que é a premissa do app). */
.campo-senha-olho {
    position: absolute;
    right: .15rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    color: var(--muted);
    background: transparent;
    border: none;
    border-radius: .5rem;
    cursor: pointer;
}

.campo-senha-olho .icon { width: 1.25rem; height: 1.25rem; }
.campo-senha-olho:active { background: var(--brand-tint); }
.campo-senha-olho.is-visivel { color: var(--brand); }

/* outline-offset negativo: o .input:focus desenha o dele PARA FORA da borda, e o do botão para
   dentro — sem isso os dois se encostam e viram um borrão de 4px no canto direito do campo. */
.campo-senha-olho:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* Textarea nativa não herda a fonte do documento (vira monoespaçada) e cresce nos dois eixos —
   estoura a largura do card. Só vertical, e na mesma fonte dos demais campos. */
textarea.input { font-family: inherit; resize: vertical; }

/* O seletor de arquivo tem largura intrínseca própria (botão + nome do arquivo, no shadow DOM) e
   ignora o container: o <InputFile> das fotos da OS estourava a viewport em ~11px, o bastante para
   ligar rolagem horizontal na tela inteira. Regra no seletor de tipo, não numa classe, porque vale
   para qualquer campo de arquivo que apareça depois. */
input[type="file"] { max-width: 100%; box-sizing: border-box; }

/* Select nativo do navegador é quadrado e destoa do resto dos campos — some com o widget padrão
   do SO e desenha uma seta consistente com os demais ícones do app. */
select.input {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 2.6rem;
    background-color: #fff;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2378746c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .75rem center;
    background-size: 1.15rem;
}

select.input::-ms-expand { display: none; }

select.input:disabled { opacity: .6; background-color: var(--bg); }

.btn-primary-lg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: .85rem;
    font-size: 1.05rem;
    font-weight: 600;
    color: #fff;
    background: var(--brand);
    border: none;
    border-radius: .6rem;
    text-decoration: none;
    cursor: pointer;
}

/* A classe nasceu em <a> e hoje veste os dois; <button> nativo não herda a fonte do documento, então
   sem isto o mesmo botão sai com a fonte do sistema quando é <button> e com a do app quando é <a> —
   diferença que aparece lado a lado na vitrine, onde os dois convivem. */
button.btn-primary-lg { font-family: inherit; }

.btn-primary-lg:disabled { opacity: .6; cursor: default; }
.btn-primary-lg:active:not(:disabled) { background: var(--brand-dark); }

/* Botão grande de ação negativa (recusar orçamento — link público, S5) — mesmo tamanho/alvo de
   toque do .btn-primary-lg, cor de perigo em vez da marca. */
.btn-danger-lg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: .85rem;
    font-size: 1.05rem;
    font-weight: 600;
    color: #fff;
    background: var(--danger);
    border: none;
    border-radius: .6rem;
    text-decoration: none;
    cursor: pointer;
    min-height: 44px;
    box-sizing: border-box;
}

.btn-danger-lg:disabled { opacity: .6; cursor: default; }
.btn-danger-lg:active:not(:disabled) { background: #b91c1c; }

.dev-hint {
    margin-top: 1rem;
    font-size: .8rem;
    color: var(--muted);
    text-align: center;
}

/* Dev panel on Home */
.dev-panel {
    margin-top: 1.5rem;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: .8rem;
    padding: 1rem 1.1rem;
}

.dev-panel h2 { margin: 0 0 .5rem; font-size: 1.05rem; }

.fieldset-reset { border: 0; margin: 0; padding: 0; min-width: 0; }
.fieldset-reset:disabled { opacity: .65; }

.row-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin: .5rem 0; }

.btn-secondary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: .6rem .9rem;
    font-size: .95rem;
    color: var(--brand);
    background: #fff;
    border: 1px solid var(--brand);
    border-radius: .55rem;
    text-decoration: none;
    cursor: pointer;
}

/* Mesma correção do button.btn-primary-lg logo acima, e aqui ela é mais visível: o sheet de ações
   empilha <a class="btn-secondary"> (mapa, Editar) e <button class="btn-secondary"> (Copiar endereço)
   um sobre o outro, e sem isto os vizinhos saem em fontes diferentes. No formulário de Endereço o
   mesmo botão troca de elemento conforme os campos são preenchidos — ali a fonte mudaria no meio da
   digitação. */
button.btn-secondary { font-family: inherit; }

.btn-secondary:active:not(:disabled) { background: var(--brand-tint); }

/* Mesmo par de regras do .btn-primary-lg e do .btn-danger-lg, que já tinham o estado desenhado. O
   .btn-secondary não tinha: como ele traz cor e fundo próprios, o navegador não aplica o cinza
   padrão de botão desabilitado, e um `disabled` ficava só no DOM — o botão continuava com cara de
   clicável, apertava (o :active acima) e não fazia nada. Vale para os dois usos: o botão que espera
   o preenchimento (conferir endereço no mapa) e os que travam durante um busy (sheets, <PontoGps>). */
.btn-secondary:disabled { opacity: .6; cursor: default; }

.btn-secondary,
.btn-primary-lg { min-height: 44px; box-sizing: border-box; }

/* Destaque intermediário: entre o .btn-secondary (contorno, sem preenchimento) e o .btn-primary-lg
   (preenchido, cor máxima) — usado pela ação "Execução" do sheet de Orçamento, que quase sempre tem
   algo (OS/visita/recebimento) esperando dentro assim que o orçamento é aprovado, e por isso pesa
   mais que os outros botões do sheet sem competir com a ação primária do status. Mesma receita do
   .resumo-tile-destaque: contorno + fundo tingido, sem virar preenchido. Modificador de
   .btn-secondary (não classe própria), como .btn-block. */
.btn-secondary.btn-destaque {
    color: var(--brand-dark);
    background: var(--brand-tint);
    font-weight: 600;
}

/* .btn-secondary:active já pinta de --brand-tint — sem isto o :active do destaque ficaria idêntico
   ao repouso (nenhum feedback de toque). */
.btn-secondary.btn-destaque:active:not(:disabled) { filter: brightness(.96); }

.btn-block { width: 100%; }

/* Botão desabilitado que não é um <button>/<input> (ex.: <label> disfarçado de botão apontando pra
   um <input type=file> — esses não têm :disabled próprio), então o visual vem de uma classe. */
.is-disabled { opacity: .6; cursor: default; pointer-events: none; }

/* Input de arquivo nativo é feio e não dá pra restilizar direto (cada navegador desenha o próprio
   "Escolher arquivo"). Escondido do olho mas presente no layout — clip em vez de display:none — pra
   continuar focável/anunciado por teclado e leitor de tela; quem dispara o seletor é o <label for=...>
   estilizado como .btn-secondary ao lado, gesto padrão de HTML que não precisa de JS. */
.input-file-oculto {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* EntityPicker — preenche a altura do sheet-body; a lista rola no seu próprio contêiner pra o
   CTA "Cadastrar novo X" ficar sempre visível, sem depender de scroll até o fim. */
.entity-picker { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.entity-picker .search-row { flex-shrink: 0; }
.entity-picker-list { flex: 1; overflow-y: auto; min-height: 0; }
.picker-create { flex-shrink: 0; margin-top: .75rem; }
.picker-create .icon { width: 1.1rem; height: 1.1rem; margin-right: .4rem; }

/* Empty-state de primeiro uso das listas — o texto ganha um CTA pro mesmo destino do botão
   primário da BottomBar (que fica longe do olho, fixo na base). Só no recorte "ativos":
   arquivados e busca sem resultado continuam texto puro. */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .75rem;
    padding: 1rem 0;
    text-align: center;
}

/* Section header (title + inline toggle) */
.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-bottom: .75rem;
}

.section-header h1 { margin: 0; font-size: 1.05rem; }

.section-header h1.title-strong {
    font-size: 1.25rem;
    font-weight: 800;
    color: var(--brand-dark);
    letter-spacing: -.01em;
}

.page-title-strong {
    margin: 0 0 .5rem;
    font-weight: 800;
    font-size: 1.2rem;
    line-height: 1;
    color: var(--brand-dark);
    letter-spacing: -.01em;
    text-align: center;
    text-transform: uppercase;
}

.dev-panel-tight { margin-top: 0; }

/* Cabeçalho de grupo de Parâmetros (Deixe com a sua cara / Como você trabalha / Suporte e seus
   dados) — não colapsável de propósito (aninhar acordeão em acordeão poria dois toques entre o
   prestador e a troca de senha). Só rótulo, sem moldura: os PainelExpansivel abaixo já são a caixa. */
.param-grupo {
    margin: 1.4rem 0 .5rem;
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--muted);
}

/* O primeiro grupo (logo depois de Aparência) não precisa da folga extra de separação — o
   PainelExpansivel anterior já termina com a própria margem. */
.param-grupo:first-of-type { margin-top: .5rem; }

/* Carimbo de build sob o número da versão (Ajuda e suporte). Só o tamanho separa esta linha da de
   cima — a hierarquia já está no par (número em negrito, carimbo miúdo), e o .hint que envolve as
   duas já é --muted.

   SEM `opacity` aqui, e a tentação é real: --muted sobre branco dá 4.65:1, que passa o AA de 4.5
   com quase nada de folga, e um .75 de opacidade derruba para ~2.9:1 — reprovado. Justamente nesta
   linha, que é a que alguém vai ler em voz alta no WhatsApp, de um celular sob sol forte. Apagar
   texto com opacity é apagar o contraste junto.

   tabular-nums porque é hexadecimal e data, onde largura irregular de dígito atrapalha quem soletra. */
.versao-build { font-size: .78rem; font-variant-numeric: tabular-nums; }

/* Painel com bastante informação por linha (ex.: Agenda) — menos respiro nas laterais que o padrão,
   pra sobrar espaço pro conteúdo do card. */
.dev-panel-compact-x { padding-left: .65rem; padding-right: .65rem; }

/* Checkbox field (form) */
.field-checkbox {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: 1rem;
}

.field-checkbox input[type="checkbox"] { width: 1.2rem; height: 1.2rem; }

