/* Utilidades mínimas.
 *
 * O daisyui.css standalone entrega os componentes e as variáveis de tema, mas
 * NENHUMA utilidade do Tailwind — `w-full`, `shadow-sm` e `text-xl` não existem
 * nele. Como a decisão foi não rodar o compilador do Tailwind no navegador, as
 * poucas que os templates usam são definidas aqui. */

.w-full {
  width: 100%;
}

.bg-base-100 {
  background: var(--color-base-100, #fff);
}

.bg-base-200 {
  background: var(--color-base-200, #f2f2f2);
}

.shadow-sm {
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.06);
}

.text-xl {
  font-size: 1.25rem;
}

.text-base {
  font-size: 1rem;
}

/* O atributo hidden empata em especificidade com as classes abaixo e perderia
 * por ordem de cascata; sem isto, blocos marcados como ocultos aparecem. */
[hidden] {
  display: none !important;
}

/* Camada de layout da área de moderação.
 *
 * O daisyUI standalone entrega os componentes (btn, navbar, table, badge…) e as
 * variáveis de tema, mas não as utilidades do Tailwind. Como a decisão foi não
 * rodar o compilador do Tailwind no navegador, as poucas utilidades de layout
 * necessárias moram aqui, com prefixo `mod-`. */

body {
  background: var(--mod-fundo);
  min-height: 100vh;
  margin: 0;
}

.mod-conteudo {
  padding: 1.5rem;
}

.mod-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.mod-titulo {
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
}

.mod-subtitulo {
  font-size: 0.8rem;
  font-weight: 400;
  opacity: 0.6;
}

.mod-filtros {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  align-items: end;
}

.mod-campo {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.mod-campo > label {
  font-size: 0.75rem;
  opacity: 0.7;
}

/* Busca ocupa duas colunas: em 11rem o placeholder parava em "…ou id de pa".
 * A campanha não fica mais aqui (tem tela dedicada), só a busca usa `span 2`.
 * O span fica no media query porque `auto-fit` criaria a segunda coluna mesmo
 * numa tela onde só cabe uma, e aí quem estouraria seria a grade. */
@media (min-width: 40rem) {
  .mod-campo--q {
    grid-column: span 2;
  }
}

/* O daisyUI liga `appearance: base-select` dentro de um `@supports`, e no
 * Chrome que já o implementa o texto do <select> passa a ser desenhado por um
 * botão interno do agente — onde o `overflow: hidden` e o `text-overflow:
 * ellipsis` do próprio `.select` não chegam. Medido no navegador: o rótulo da
 * campanha ocupava 270px numa caixa de 180px, saindo por cima do filtro
 * seguinte e apagando a seta. Com o appearance clássico — que é o caminho que
 * o daisyUI já estiliza — o <select> volta a truncar com reticências. */
.mod-conteudo select.select {
  appearance: none;
  -webkit-appearance: none;
}

.mod-navbar-fim {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-left: auto;
}

.mod-acoes-filtro {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

/* Destaque da campanha selecionada no topo da listagem: o filete e o fundo
 * tingido a diferenciam dos demais blocos neutros da tela, sem competir com
 * a cor de decisão (só o bloco de Decisão do moderar.html tinge o fundo). */
.mod-campanha-atual {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--color-primary, #1d4ed8);
  background: var(--color-base-200, #f2f2f2);
  border-radius: 0.25rem;
}

.mod-campanha-nome {
  font-weight: 600;
}

/* --- Tela de escolha de campanhas --- */
.mod-campanhas-stat {
  display: inline-block;
  margin-bottom: 1rem;
}

.mod-campanhas-stat .card-body {
  flex-direction: row;
  align-items: baseline;
  gap: 0.5rem;
  padding: 1rem 1.5rem;
}

.mod-campanhas-numero {
  font-size: 1.5rem;
  font-weight: 700;
}

.mod-periodo {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 12rem;
}

.mod-progresso {
  width: 100%;
  height: 0.35rem;
}

.mod-tabela-wrap {
  overflow-x: auto;
}

.mod-thumb {
  width: 3rem;
  height: 3rem;
  object-fit: cover;
  border-radius: 0.25rem;
  background: var(--color-base-300, #e5e5e5);
}

.mod-thumb-vazio {
  display: inline-block;
  width: 3rem;
  height: 3rem;
  border-radius: 0.25rem;
  background: var(--color-base-300, #e5e5e5);
}

.mod-rodape {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1rem;
  flex-wrap: wrap;
}

.mod-contagem {
  font-size: 0.8rem;
  opacity: 0.7;
}

.mod-vazio {
  text-align: center;
  padding: 3rem 1rem;
  opacity: 0.7;
}

.mod-nowrap {
  white-space: nowrap;
}

.mod-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8rem;
}

/* Identificador truncado (utils/display.py:id_compacto), o mesmo do admin. O
 * tracejado indica que há mais texto — o valor inteiro está no `title`. A
 * regra é repetida aqui porque `change_list.css` é do admin e não chega nesta
 * área. */
.id-compacto {
  border-bottom: 1px dotted var(--color-base-300, #d4d4d8);
  cursor: help;
}

/* A coluna da ação abraça o botão em vez de disputar largura com os dados:
 * `width: 1%` num table-layout automático encolhe a coluna até o conteúdo. */
.mod-col-moderar {
  width: 1%;
  white-space: nowrap;
}

/* Cabeçalho ordenável: só o "Criado em" por enquanto. Herda a cor do <th> —
 * um link azul no cabeçalho competiria com os dados da tabela. */
.mod-ordenar {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

.mod-ordenar:hover {
  text-decoration: underline;
}

.mod-seta {
  opacity: 0.7;
}

/* Indicador de carregamento do htmx. */
.mod-indicador {
  visibility: hidden;
}

.htmx-request .mod-indicador,
.htmx-request.mod-indicador {
  visibility: visible;
}

/* --- Tela de moderação --- */
.mod-colunas {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 1024px) {
  .mod-colunas {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
  }

  /* Modo foco: a coluna de dados sai (o JS marca `hidden`) e sobra uma coluna
   * só, com o cupom na largura inteira. Abaixo de 1024px o grid já é de uma
   * coluna e esconder a esquerda basta. */
  .mod-colunas--foco {
    grid-template-columns: minmax(0, 1fr);
  }

  .mod-sticky {
    position: sticky;
    top: 1rem;
  }
}

/* O teto de 75vh serve para o cupom acompanhar a coluna ao lado; sem ela, o
 * que se quer é justamente altura. */
.mod-colunas--foco .mod-cupom {
  max-height: none;
}

.mod-bloco {
  margin-bottom: 1rem;
}

.mod-dados-grade {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  margin-bottom: 1rem;
}

.mod-dados-grade > div {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.mod-rotulo {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  opacity: 0.65;
}

.mod-campos {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}

.mod-erro {
  color: var(--color-error, #b91c1c);
  font-size: 0.75rem;
}

/* Nota sob o campo — o período aceito, não um alerta: fica na cor do texto,
 * só mais discreta, para não competir com .mod-erro. */
.mod-ajuda {
  color: var(--color-base-content, #1f2937);
  font-size: 0.75rem;
  opacity: 0.7;
}

.mod-criticas {
  margin: 0.35rem 0 0;
  padding-left: 1.1rem;
}

.mod-criticas li {
  margin-bottom: 0.2rem;
}

.mod-alerta {
  margin-top: 0.75rem;
  margin-bottom: 0.75rem;
  /* O participationId pode ser um hash de 64 caracteres sem espaço nenhum:
   * sem isto o alerta estica a página em vez de quebrar a linha. */
  overflow-wrap: anywhere;
}

.mod-nota {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 0.75rem;
}

.mod-acoes-decisao {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.75rem;
}

.mod-cupom {
  overflow: auto;
  max-height: 75vh;
  text-align: center;
}

.mod-cupom img {
  max-width: 100%;
  height: auto;
}

/* O `max-width: 100%` acima travava o zoom na largura da coluna: o slider
 * escrevia até 1600px e nada acontecia. A classe é posta pelo JS só quando ele
 * assume a largura da imagem — sem JS a regra de cima continua valendo, e o
 * comprovante (que ninguém redimensiona) não estoura o card. O `overflow:
 * auto` do `.mod-cupom` rola o que passar. */
.mod-cupom--zoomavel img {
  max-width: none;
}

/* Palco da rotação visual: `transform` não altera a caixa de layout, então o
 * JS troca as dimensões daqui quando a imagem gira. Em repouso não há estilo
 * inline nenhum e o palco se dimensiona sozinho — a imagem só sai do fluxo
 * enquanto está girada, e é por isso que o estado inicial não depende do JS. */
.mod-cupom-palco {
  display: inline-block;
  position: relative;
}

.mod-cupom-palco img {
  transform-origin: center;
  cursor: zoom-in;
}

.mod-cupom-palco--girado img {
  position: absolute;
  top: 50%;
  left: 50%;
}

.mod-colunas--foco .mod-cupom-palco img {
  cursor: zoom-out;
}

.mod-pdf {
  width: 100%;
  height: 70vh;
  border: 0;
}

.mod-sem-score {
  color: var(--color-error, #b91c1c);
  font-weight: 600;
}

/* --- Tabela de produtos --- */
/* table-layout fixo: sem isto a coluna do produto cresce com o texto mais
 * longo e estoura o card. */
.mod-tabela-produtos {
  width: 100%;
  table-layout: fixed;
}

.mod-tabela-produtos td,
.mod-tabela-produtos th {
  vertical-align: top;
}

/* As larguras vivem no <colgroup>: com table-layout fixed, largura posta em
 * <td> do corpo é ignorada. */
.mod-col-produto {
  width: auto;
}

.mod-col-qtd {
  width: 6rem;
}

.mod-col-valor {
  width: 8.5rem;
}

.mod-col-remover {
  width: 5.5rem;
}

.mod-col-num {
  text-align: left;
}

.mod-col-acao {
  text-align: center;
}

/* O checkbox DELETE precisa continuar no POST — some da tela, não do form.
   `display: none` não impede o envio; `disabled` impediria. */
.mod-oculto {
  display: none;
}

.mod-btn-remover {
  white-space: nowrap;
}

/* Linha já gravada marcada para remoção: some no save, mas segue visível
   (e editável) até lá, para o moderador poder desfazer. */
.mod-linha-removida {
  opacity: 0.45;
}

.mod-linha-removida input {
  text-decoration: line-through;
}

.mod-tabela-produtos input[type="text"],
.mod-tabela-produtos input[type="number"],
.mod-col-num input {
  width: 100%;
  min-width: 0;
}

.mod-combo-entrada {
  text-overflow: ellipsis;
}

/* --- Combobox de produto --- */
.mod-combo {
  position: relative;
}

.mod-combo-lista {
  position: absolute;
  z-index: 30;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  max-height: 16rem;
  overflow-y: auto;
  background: var(--color-base-100, #fff);
  border: 1px solid var(--color-base-300, #d4d4d4);
  border-radius: 0.5rem;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.12);
}

.mod-combo-item {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.4rem 0.55rem;
  border-radius: 0.35rem;
  cursor: pointer;
}

.mod-combo-item:hover,
.mod-combo-ativo {
  background: var(--color-base-200, #f2f2f2);
}

.mod-combo-ean {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  opacity: 0.7;
}

.mod-combo-desc {
  font-size: 0.85rem;
  line-height: 1.2;
}

.mod-combo-vazio {
  padding: 0.6rem;
  font-size: 0.85rem;
  opacity: 0.6;
}

/* A célula precisa deixar a lista escapar para fora da linha. */
.mod-tabela-produtos td,
.mod-tabela-produtos tr {
  overflow: visible;
}

/* --- Confirmação da decisão --- */
.mod-confirmacao-resumo {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 1rem;
  margin: 1rem 0 0;
}

.mod-confirmacao-resumo dt {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  opacity: 0.55;
  align-self: center;
}

.mod-confirmacao-resumo dd {
  margin: 0;
  font-size: 0.9rem;
}

/* --- Cor ---------------------------------------------------------------
 *
 * Cada cor responde "o que isso me diz?". As utilidades do Tailwind não
 * existem no daisyUI standalone (`bg-primary`, `text-primary` e afins), então
 * tudo aqui é classe `mod-` lendo as variáveis do tema, com fallback para o
 * caso de o CDN não responder. */

:root {
  --mod-fundo: #eef2f8;
  --mod-cor-cupom: var(--color-primary, #4b6bfb);
  --mod-cor-produtos: var(--color-accent, #67cba0);
  --mod-cor-score: var(--color-info, #3abff8);
  --mod-cor-decisao: var(--color-warning, #eab308);
}

/* A navbar branca encostava nos cards brancos: nada ancorava o topo. */
.mod-navbar {
  background: var(--color-primary, #4b6bfb);
  color: var(--color-primary-content, #fff);
}

.mod-navbar .btn,
.mod-navbar .mod-contagem,
.mod-navbar .mod-subtitulo {
  color: inherit;
}

.mod-navbar .btn-ghost:hover {
  background: rgb(255 255 255 / 0.15);
}

.mod-navbar .mod-subtitulo,
.mod-navbar .mod-contagem {
  opacity: 0.8;
}

/* Filete + ponto no título dão identidade a cada bloco sem pintar a área
 * toda, que cansaria a leitura numa tela usada o dia inteiro. */
.mod-bloco {
  border-left: 3px solid transparent;
}

.mod-bloco .card-title::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 9999px;
  background: currentColor;
  margin-right: 0.15rem;
  flex: none;
}

.mod-bloco--cupom {
  border-left-color: var(--mod-cor-cupom);
}

.mod-bloco--cupom .card-title::before {
  background: var(--mod-cor-cupom);
}

.mod-bloco--produtos {
  border-left-color: var(--mod-cor-produtos);
}

.mod-bloco--produtos .card-title::before {
  background: var(--mod-cor-produtos);
}

.mod-bloco--score {
  border-left-color: var(--mod-cor-score);
}

.mod-bloco--score .card-title::before {
  background: var(--mod-cor-score);
}

/* A decisão é o que falta fazer: é o único bloco com fundo tingido, para o
 * olho cair nele. Dupla classe para vencer `.bg-base-100` com folga. */
.mod-bloco.mod-bloco--decisao {
  border-left-color: var(--mod-cor-decisao);
  background: color-mix(in srgb, var(--color-warning, #eab308) 7%, #fff);
}

.mod-bloco--decisao .card-title::before {
  background: var(--mod-cor-decisao);
}

/* Cabeçalho e zebra: a tabela de produtos é conferida linha a linha contra a
 * imagem do cupom, e alternar o fundo evita pular de linha. */
.mod-tabela-produtos thead th {
  background: var(--color-base-200, #f2f2f2);
}

.mod-tabela-produtos tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--mod-cor-produtos) 6%, transparent);
}

.mod-tabela-produtos tfoot th {
  background: var(--color-base-200, #f2f2f2);
}

/* Número que o moderador confere contra a imagem. */
.mod-total {
  /* O primary puro dá 3.37:1 sobre o rodapé da tabela — abaixo dos 4.5 que
     texto de 16px pede. Escurecido, mantém a cor e passa. */
  color: color-mix(in srgb, var(--color-primary, #4b6bfb) 72%, #000);
  font-weight: 700;
  font-size: 1rem;
}


/* Rótulos longos ("PAGAMENTO EFETUADO") estouravam o badge, que é de altura
 * fixa e não quebra linha. */
.mod-dados-grade .badge {
  height: auto;
  white-space: normal;
  padding-block: 0.15rem;
  text-align: center;
}

/* O `alert-soft` pinta o texto com a própria cor de aviso: âmbar sobre creme
 * não tem contraste para texto corrido. A cor fica na borda e no título; as
 * críticas em si usam a cor de texto normal. */
.mod-alerta.alert-soft {
  color: var(--color-base-content, #1f2937);
  border-left: 3px solid var(--color-warning, #eab308);
}

/* O verde do tema com texto branco dá 3.29:1 — abaixo dos 4.5 exigidos, no
 * botão mais usado da tela e em todo badge de aprovação. Escurecido, passa,
 * e a cor percebida é a mesma. Vale só aqui; o tema segue intacto no resto. */
.mod-bloco--decisao .btn-success,
.mod-conteudo .badge-success {
  background-color: color-mix(in srgb, var(--color-success, #16a34a) 82%, #000);
  border-color: color-mix(in srgb, var(--color-success, #16a34a) 82%, #000);
}

/* O badge-ghost tem o fundo da própria faixa zebrada: na listagem ele sumia
 * em linha sim, linha não. Uma borda o mantém legível sobre qualquer fundo. */
.mod-conteudo .badge-ghost {
  border-color: color-mix(in srgb, var(--color-base-content, #1f2937) 22%, transparent);
}

/* --- Login ------------------------------------------------------------- */

.mod-login {
  display: flex;
  justify-content: center;
  padding-top: 3rem;
}

.mod-login .mod-bloco {
  width: 100%;
  max-width: 22rem;
}

.mod-login-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.mod-sair {
  display: inline;
  margin: 0;
}

/* --- Atribuição em lote ------------------------------------------------ */

/* A barra fica colada no topo da tabela e é a única faixa tingida da lista:
 * é a ação que opera sobre o que está selecionado logo abaixo. */
.mod-barra-atribuicao {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  background: var(--color-base-200, #f2f2f2);
  border-bottom: 1px solid var(--color-base-300, #e5e7eb);
}

.mod-barra-atribuicao label {
  font-size: 0.75rem;
  opacity: 0.7;
}

/* A contagem é o que o coordenador confere antes de confirmar. */
.mod-selecao {
  font-size: 0.85rem;
  font-weight: 600;
  margin-right: auto;
}

.mod-quantidade {
  width: 7rem;
}

.mod-col-check {
  width: 2.5rem;
  text-align: center;
}
