/* forms.css — estilos app-level de validação e UX de senha.
   Carregado por padrão em todos os temas e pelo admin, para que validação,
   olho de senha e força de senha funcionem em qualquer tema.

   TODA cor/medida sai de um token do tema com fallback: um tema define
   --accent, --muted, --border, --radius etc. e este arquivo se adapta, sem
   precisar sobrescrever nada. Se ainda assim o tema quiser marcação/estilo
   próprios, pode recusar este CSS com app_head($seo, ['core_css' => false])
   e cuidar de .field-error/.password-* por conta própria. */

.field-error { display: block; color: var(--danger, #b91c1c); font-size: 0.85rem; margin-top: 0.25rem; }
input.is-invalid, textarea.is-invalid, select.is-invalid { border-color: var(--danger, #b91c1c) !important; }

/* Olho de mostrar/ocultar senha */
.password-wrap { position: relative; display: block; }
.password-wrap > input { width: 100%; padding-right: 2.4rem; }
.password-toggle {
  position: absolute; right: 0.3rem; top: 50%; transform: translateY(-50%);
  background: none; border: 0; cursor: pointer; line-height: 0; color: inherit;
  /* 28px: o alvo tinha 23px, um a menos que o mínimo de 24px da WCAG 2.2 — e este
     botão está em todo campo de senha do produto. */
  width: 28px; height: 28px; display: grid; place-items: center; padding: 0;
  border-radius: 6px; opacity: 0.55;
}
.password-toggle:hover, .password-toggle.is-on { opacity: 1; }
/* O traço de "oculto" só aparece quando a senha está VISÍVEL: o ícone mostra o
   estado em que o campo vai ficar se você clicar de novo, que é o que se espera
   de um interruptor. */
.password-toggle .pw-eye-off { opacity: 0; }
.password-toggle.is-on .pw-eye-off { opacity: 1; }
.password-toggle:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; opacity: 1; }
/* Todo tema/admin define `button:active { transform: translateY(1px) }` como
   micro-interação de clique — especificidade (0,1,1) vence a centralização
   vertical acima (0,1,0) e desloca o botão durante o mousedown, fazendo o
   mouseup/click cair no input por baixo em vez do próprio botão (o "olhinho"
   parecia não responder). `:active` aqui sobe a especificidade pra (0,2,0) e
   preserva a centralização. */
.password-toggle:active { transform: translateY(-50%); }

/* Barra de força + regras (campos de definição de senha) */
.password-strength { margin-top: 0.45rem; }
.password-bar { height: 6px; border-radius: var(--radius-sm, 4px); background: var(--border, #e5e7eb); overflow: hidden; }
.password-bar > span {
  display: block; height: 100%; width: 100%; background: var(--danger, #ef4444);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.2s, background 0.2s;
}
.password-bar.strength-2 > span { background: var(--warning, #f59e0b); }
.password-bar.strength-3 > span { background: var(--warning-strong, #eab308); }
.password-bar.strength-4 > span { background: var(--success, #22c55e); }
.password-level { font-size: 0.8rem; color: var(--muted, #6b7280); margin-top: 0.2rem; }
.password-rules { list-style: none; padding: 0; margin: 0.35rem 0 0; font-size: 0.82rem; }
.password-rules li { color: var(--muted, #6b7280); padding-left: 1.3rem; position: relative; line-height: 1.5; }
.password-rules li::before { content: '○'; position: absolute; left: 0; }
.password-rules li.is-met { color: var(--success, #16a34a); }
.password-rules li.is-met::before { content: '✓'; font-weight: 700; }

/* Endereço estruturado (padrão BR) */
.address-fields { border: 1px solid var(--border, #e5e7eb); border-radius: var(--radius, 8px); padding: 0.75rem 1rem 1rem; margin: 0.75rem 0; }
.address-fields > legend { font-weight: 600; font-size: 0.95rem; padding: 0 0.4rem; }
.address-row { display: flex; gap: 0.75rem; flex-wrap: wrap; }
.address-row > label { flex: 1 1 45%; min-width: 8rem; }
.cep-status { display: block; color: var(--muted, #6b7280); font-size: 0.8rem; margin-top: 0.2rem; min-height: 1rem; }

/* Formas de entrega no checkout */
.shipping-methods { border: 1px solid var(--border, #e5e7eb); border-radius: var(--radius, 8px); padding: 0.75rem 1rem 1rem; margin: 0.75rem 0; }
.shipping-methods > legend { font-weight: 600; font-size: 0.95rem; padding: 0 0.4rem; }
.shipping-option {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 0.15rem 0.6rem;
  padding: 0.55rem 0.4rem; border-bottom: 1px solid var(--border, #f1f1f4); cursor: pointer;
}
.shipping-option:last-child { border-bottom: 0; }
.shipping-option .shipping-name { font-weight: 500; }
.shipping-option .shipping-desc { grid-column: 2; color: var(--muted, #6b7280); font-size: 0.82rem; }
.shipping-option .shipping-price { grid-column: 3; grid-row: 1; font-weight: 600; white-space: nowrap; }

/* Resumo de valores do checkout (bloco de CTA — acento tênue; tokens do tema com fallback) */
.checkout-summary {
    margin: 1.25rem 0; padding: 1rem 1.15rem;
    background: var(--accent-soft, #eef4ff);
    border: 1px solid var(--border-strong, #d0d5dd); border-radius: var(--radius, 8px);
}
.checkout-summary p { margin: 0.2rem 0; display: flex; justify-content: space-between; }
.checkout-summary p:last-child { border-top: 1px solid var(--border-strong, #d0d5dd); margin-top: 0.5rem; padding-top: 0.5rem; font-size: 1.1rem; }
.checkout-summary p:last-child strong { color: var(--accent, #2563eb); }

/* ── Acessibilidade (app-level, todos os temas) ──────────────────────────────
   Skip link: oculto até receber foco por teclado, aí aparece no topo. */
/* `a.skip-link` e não `.skip-link`: o admin tem `.admin a { color: var(--a-accent) }`
   com especificidade (0,2,0), que vencia o `color: #fff` daqui (0,1,0) — o link
   aparecia em AZUL sobre o verde do fallback, 1.45:1, ilegível. E o fundo lia
   `--accent`, que só existe nos temas: no admin caía no verde do fallback, que não
   é cor de lugar nenhum do painel. A cadeia agora tenta o token do admin primeiro. */
a.skip-link {
  position: absolute; left: 0.5rem; top: -3rem; z-index: 1000;
  background: var(--a-accent, var(--accent, #2563eb));
  padding: 0.6rem 1rem; border-radius: 0 0 var(--radius, 6px) var(--radius, 6px);
  text-decoration: none; transition: top 0.15s ease;
}
/* `:link`/`:visited` sobe para (0,2,1) e ganha do `.admin a { color: var(--a-accent) }`,
   que é (0,2,0)... empatava em (0,1,1) com o seletor curto e vencia por vir depois,
   pintando o texto de AZUL sobre o fundo AZUL — 1.00:1. Cor de link genérica é
   exatamente o que um chip sobre fundo colorido não pode herdar. */
a.skip-link:link, a.skip-link:visited, a.skip-link:hover, a.skip-link:focus { color: #fff; }
a.skip-link:focus { top: 0; outline: 2px solid #fff; outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { a.skip-link { transition: none; } }

/* Resumo de erros focável no envio com erro. */
.error-summary {
  margin: 0 0 1.25rem; padding: 0.9rem 1.1rem;
  border: 1px solid var(--danger, #b91c1c); border-radius: var(--radius, 6px);
  background: color-mix(in srgb, var(--danger, #b91c1c) 8%, transparent);
}
.error-summary:focus { outline: 2px solid var(--danger, #b91c1c); outline-offset: 2px; }
.error-summary__title { margin: 0 0 0.4rem; font-weight: 600; color: var(--danger, #b91c1c); }
.error-summary__list { margin: 0; padding-left: 1.2rem; }
.error-summary__list a { color: var(--danger, #b91c1c); }

/* Mensagem de erro por campo (a que o aria-describedby aponta). */
.field-error { display: block; color: var(--danger, #b91c1c); font-size: 0.85rem; margin-top: 0.25rem; }

/* ── Selo de status (app-level) ───────────────────────────────────────────────
   `status_badge()` é helper do NÚCLEO, então o estilo mínimo dele mora aqui —
   senão cada tema que mostrasse o status de um pedido teria de reinventar (ou,
   como acontecia, cuspir "paid" cru em inglês por não ter onde estilizar).

   Precisa funcionar em temas de fundo claro E escuro sem saber qual é. Por isso
   o texto usa os PRÓPRIOS tokens do tema (--fg sobre --soft é um par que o tema
   já garante legível) e a cor do estado vive só no ponto: um valor fixo aqui
   nunca teria contraste nos dois extremos. O rótulo ("Pago", "Falhou") é que
   carrega o significado — o ponto é reforço, não a informação.

   Duas armadilhas de cascata, e o seletor resolve as duas de uma vez:

   1. o ADMIN também carrega este arquivo, e já tem o selo dele em admin.css
      (com outros tons). Sem excluí-lo, propriedades daqui que o admin não
      redefine (borda, line-height) vazariam para lá. Daí o `:not(.admin)`.
   2. o `:where()` zera a especificidade do escopo — sem ele, `body:not(.admin)
      .badge` passaria a valer MAIS que o `.badge` de um tema, e o tema perderia
      o direito de substituir (o mfc, que tem selo próprio, seria o primeiro a
      quebrar). Com `:where()`, isto vale exatamente `.badge`: forms.css carrega
      antes do theme.css, então quem define ganha. */
:where(body:not(.admin)) .badge {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.15rem 0.6rem; border-radius: 999px;
  font-size: 0.78rem; font-weight: 600; line-height: 1.7; white-space: nowrap;
  background: var(--soft, #f3f4f6); color: var(--fg, #111827);
  border: 1px solid var(--border, #e5e7eb);
}
/* O ponto é sempre `currentColor`, nunca uma cor fixa: um tema que já estiliza o
   selo (mfc) define a cor do TEXTO, e um ponto de cor própria brigaria com ela.
   Assim o ponto acompanha qualquer tema de graça — inclusive os que ainda nem
   existem. */
:where(body:not(.admin)) .badge-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: currentColor; }

/* O estado entra como TINTA sobre o fundo do próprio tema, não como cor de
   texto: 16% mal move a luminância, então o par --fg/--bg que o tema já garante
   legível continua valendo em fundo claro e escuro. Fixar a cor no texto exigiria
   um valor que tivesse contraste nos dois extremos — não existe. */
:where(body:not(.admin)) .badge-ok     { background: color-mix(in srgb, #16a34a 16%, var(--bg, #fff)); border-color: color-mix(in srgb, #16a34a 38%, var(--bg, #fff)); }
:where(body:not(.admin)) .badge-warn   { background: color-mix(in srgb, #d97706 16%, var(--bg, #fff)); border-color: color-mix(in srgb, #d97706 38%, var(--bg, #fff)); }
:where(body:not(.admin)) .badge-danger { background: color-mix(in srgb, #dc2626 16%, var(--bg, #fff)); border-color: color-mix(in srgb, #dc2626 38%, var(--bg, #fff)); }
:where(body:not(.admin)) .badge-info   { background: color-mix(in srgb, #2563eb 16%, var(--bg, #fff)); border-color: color-mix(in srgb, #2563eb 38%, var(--bg, #fff)); }

/* ── Porteiro do WhatsApp (modal criado por whatsapp-lead.js) ───────────────
   Mora aqui, e não num tema, pela mesma razão do JS: o recurso vale para todos
   os temas de uma vez, sem editar nenhum. Todas as cores saem dos tokens que os
   temas já definem (--bg, --fg, --accent...) com fallback neutro — um tema que
   os declara ganha a própria identidade de graça; um que não, continua legível.
   `:where()` mantém a especificidade em zero, então qualquer tema pode
   sobrescrever o visual sem `!important`. */
:where(body:not(.admin)) .wa-lead {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
  background: rgba(0, 0, 0, 0.55);
}
body.wa-lead-aberto { overflow: hidden; }

:where(body:not(.admin)) .wa-lead__box {
  position: relative;
  width: 100%; max-width: 25rem;
  max-height: 92vh; overflow-y: auto;
  padding: 1.6rem 1.5rem 1.5rem;
  background: var(--bg, #fff); color: var(--fg, #111827);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: var(--radius, 12px);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28);
}
:where(body:not(.admin)) .wa-lead__x {
  position: absolute; top: 0.5rem; right: 0.6rem;
  width: 2rem; height: 2rem; line-height: 1;
  font-size: 1.4rem; cursor: pointer;
  background: none; border: 0; color: var(--muted, #6b7280);
  border-radius: var(--radius-sm, 8px);
}
:where(body:not(.admin)) .wa-lead__x:hover { color: var(--fg, #111827); }
:where(body:not(.admin)) .wa-lead__titulo { margin: 0 0 0.35rem; font-size: 1.2rem; }
:where(body:not(.admin)) .wa-lead__texto  { margin: 0 0 1rem; color: var(--muted, #6b7280); font-size: 0.92rem; }
:where(body:not(.admin)) .wa-lead__label  { display: block; margin: 0 0 0.25rem; font-size: 0.85rem; font-weight: 600; }
:where(body:not(.admin)) .wa-lead__op     { font-weight: 400; color: var(--muted, #6b7280); }
:where(body:not(.admin)) .wa-lead__input {
  width: 100%; margin: 0 0 0.85rem; padding: 0.6rem 0.7rem;
  font: inherit; color: var(--fg, #111827);
  background: var(--bg, #fff);
  border: 1px solid var(--border-strong, var(--border, #d1d5db));
  border-radius: var(--radius-sm, 8px);
}
:where(body:not(.admin)) .wa-lead__input:focus-visible {
  outline: 2px solid var(--accent, #2563eb); outline-offset: 1px;
}
:where(body:not(.admin)) .wa-lead__enviar {
  width: 100%; padding: 0.7rem 1rem; cursor: pointer;
  font: inherit; font-weight: 600;
  color: #fff; background: var(--accent, #16a34a);
  border: 0; border-radius: var(--radius-sm, 8px);
}
:where(body:not(.admin)) .wa-lead__enviar:hover { filter: brightness(0.94); }
/* A saída de emergência é um <a> com a mesma cara do botão — precisa das regras
   que um link não herda de <button>. */
:where(body:not(.admin)) a.wa-lead__enviar {
  display: block; box-sizing: border-box;
  text-align: center; text-decoration: none;
}
:where(body:not(.admin)) .wa-lead__secundario {
  width: 100%; margin-top: 0.6rem; padding: 0.6rem 1rem; cursor: pointer;
  font: inherit;
  color: var(--muted, #6b7280); background: none;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: var(--radius-sm, 8px);
}
/* Botão travado pela verificação de segurança (ver turnstile-gate.js).

   Vale em QUALQUER tema e também no admin — por isso sem o `:where(body:not(.admin))`
   dos seletores acima: o login do painel também tem captcha. Só opacidade e
   cursor, sem trocar cor: cada tema tem a sua, e sobrescrevê-la aqui faria o
   botão mudar de identidade por um segundo. */
[data-turnstile-aguardando] {
  opacity: 0.55;
  cursor: not-allowed;
  filter: grayscale(0.35);
}

/* Captcha do porteiro. O widget da Cloudflare mede 300x65 e o modal é estreito:
   sem o max-width ele estoura a caixa nos aparelhos pequenos. */
:where(body:not(.admin)) .wa-lead__captcha { margin: 0 0 0.85rem; }
:where(body:not(.admin)) .wa-lead__captcha iframe { max-width: 100%; }
/* Recado de "espere o captcha" / "não carregou". Vermelho discreto: é bloqueio
   de envio, não decoração — quem clicou em enviar precisa entender por que não
   foi. */
:where(body:not(.admin)) .wa-lead__aviso {
  margin: 0 0 0.85rem; font-size: 0.85rem;
  color: var(--danger-fg, #8c1d18);
}
/* Honeypot: fora da tela, nunca display:none — campo escondido assim é ignorado
   por parte dos preenchedores automáticos, que é justamente quem se quer pegar. */
:where(body:not(.admin)) .wa-lead__hp {
  position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0;
}

/* ── Aviso de cookies (app-level, todos os temas) ────────────────────────────
   Faixa presa embaixo, não modal com véu: consentir não é pré-requisito para ler
   o site, e cobrir o conteúdo empurra a pessoa a aceitar só para enxergar — o
   oposto da escolha livre que a LGPD pede.

   DOIS NÍVEIS, como o guia de cookies da ANPD cobra: o 1º traz informação curta,
   aceitar, recusar e o gatilho do 2º; o 2º traz uma caixa por finalidade, com
   aceitar/recusar ainda visíveis. `[data-wm-consent-modo]` é quem alterna.

   Tokens do tema com cadeia de fallback (`--accent` → `--btn-bg` → hex): assim o
   aviso nasce na cor da marca tanto em tema que usa os nomes do núcleo quanto em
   tema que nomeia os próprios, como o gototem. Especificidade baixa via :where(),
   como as classes .wa-lead — qualquer tema veste sem !important. */
:where(body:not(.admin)) .wm-consent {
  position: fixed; inset: auto 0 0 0; z-index: 9998;
  display: flex; justify-content: center;
  padding: 0.75rem;
}
:where(body:not(.admin)) .wm-consent[hidden] { display: none; }
:where(body:not(.admin)) .wm-consent__box {
  /* border-box explícito: este arquivo não tem reset global (ver
     a.wa-lead__enviar, mesma razão), e com content-box o padding somaria à
     largura de 100% — a faixa estouraria a tela no celular. */
  box-sizing: border-box;
  width: 100%; max-width: 62rem;
  max-height: 88vh; overflow-y: auto;
  padding: 0.8rem 0.95rem;
  background: var(--bg, var(--bg-card, #fff)); color: var(--fg, var(--text-body, #111827));
  border: 1px solid var(--border, var(--border-soft, #e5e7eb));
  border-radius: var(--radius, 12px);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.22);
}
:where(body:not(.admin)) .wm-consent__titulo {
  margin: 0 0 0.2rem; font-size: 0.95rem;
}
:where(body:not(.admin)) .wm-consent__p {
  margin: 0; font-size: 0.85rem; color: var(--muted, var(--text-placeholder, #6b7280));
}
/* Linha do link da política, no 1º nível. É LINK, não um terceiro botão: as duas
   decisões principais precisam continuar sendo as óbvias da faixa. */
:where(body:not(.admin)) .wm-consent__meta {
  margin: 0.35rem 0 0; font-size: 0.85rem;
}
:where(body:not(.admin)) .wm-consent__link { color: inherit; text-decoration: underline; }
/* Um tema (ou o próprio núcleo, se a decisão mudar) pode recolocar o gatilho do
   2º nível como link de texto: `<button class="wm-consent__mais"
   data-wm-consent="prefs">`. O estilo fica pronto para isso. */
:where(body:not(.admin)) .wm-consent__mais {
  padding: 0; font: inherit; cursor: pointer;
  color: inherit; text-decoration: underline;
  background: none; border: 0;
}
:where(body:not(.admin)) .wm-consent__acoes {
  display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.8rem;
}
:where(body:not(.admin)) .wm-consent__btn {
  box-sizing: border-box;
  /* Discreto de propósito: o aviso é obrigação, não chamada para ação. Botão
     grande numa faixa que aparece sozinha compete com o conteúdo pelo qual a
     pessoa entrou. Os DOIS têm a mesma medida — a simetria entre aceitar e
     recusar é o ponto que o guia da ANPD cobra com mais força. */
  /* 8,5rem de base para os dois caberem lado a lado num celular de 360px; não
     cabendo, o flex-wrap os empilha em vez de cortá-los. */
  flex: 1 1 8.5rem; padding: 0.4rem 0.85rem; cursor: pointer;
  font: inherit; font-size: 0.85rem; font-weight: 600;
  color: var(--btn-text, #fff); background: var(--accent, var(--btn-bg, #2563eb));
  border: 0; border-radius: var(--radius-sm, 8px);
}
:where(body:not(.admin)) .wm-consent__btn:hover { filter: brightness(0.94); }
/* Recusar tem de ser tão fácil de achar quanto aceitar (LGPD art. 8º, e o guia
   da ANPD trata o contrário como padrão abusivo): mesmo tamanho, mesmo peso de
   fonte, mesma linha, borda visível — nada de cinza-apagado que faça o olho
   pular. Só o preenchimento distingue. */
:where(body:not(.admin)) .wm-consent__btn--sec {
  color: var(--fg, var(--text-body, #111827)); background: none;
  border: 1px solid var(--border-strong, var(--border, var(--border-soft, #d1d5db)));
}
/* Com o 2º nível aberto, o gatilho dele não tem mais o que oferecer. */
:where(body:not(.admin)) [data-wm-consent-modo="preferencias"] .wm-consent__mais { display: none; }
/* 2º nível. Escondido no modo "aviso" — existe no HTML desde o começo porque é o
   mesmo painel que o "gerenciar cookies" reabre depois da escolha. */
:where(body:not(.admin)) [data-wm-consent-modo="aviso"] .wm-consent__prefs { display: none; }
:where(body:not(.admin)) .wm-consent__grade {
  display: grid; gap: 0.55rem; margin-top: 0.8rem;
  padding-top: 0.8rem; border-top: 1px solid var(--border, var(--border-soft, #e5e7eb));
}
:where(body:not(.admin)) .wm-consent__op {
  display: flex; gap: 0.5rem; align-items: flex-start;
  font-size: 0.88rem; cursor: pointer;
}
:where(body:not(.admin)) .wm-consent__op input { margin-top: 0.2rem; }
:where(body:not(.admin)) .wm-consent__op em {
  display: block; font-style: normal; font-size: 0.82rem;
  color: var(--muted, var(--text-placeholder, #6b7280));
}
:where(body:not(.admin)) .wm-consent__nota {
  margin: 0; font-size: 0.8rem; color: var(--muted, var(--text-placeholder, #6b7280));
}
:where(body:not(.admin)) .wm-consent__prefs-acoes {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
}
@media (min-width: 46rem) {
  /* Na largura de desktop o texto e os botões dividem a faixa — três linhas
     empilhadas ocupariam meia tela para dizer uma frase. */
  :where(body:not(.admin)) .wm-consent__box {
    display: grid; grid-template-columns: 1fr auto;
    align-items: center; column-gap: 1.5rem;
  }
  :where(body:not(.admin)) .wm-consent__acoes { margin-top: 0; }
  :where(body:not(.admin)) .wm-consent__btn { flex: 0 0 auto; }
  :where(body:not(.admin)) .wm-consent__prefs { grid-column: 1 / -1; }
}
