/* ═══════════════════════════════════════════════════════════════
   MOVE! ENERGIA — Componentes
   ═══════════════════════════════════════════════════════════════

   Consome os tokens de `tokens.css`, que precisa vir ANTES deste
   arquivo no HTML. Nenhuma cor, medida ou duração literal aqui: se um
   valor não existe como token, o lugar de criá-lo é `tokens.css`.

   Sete componentes, cada um com todos os seus estados:
     1. Tabela com paginação   .tbl-card / .tbl / .tbl-pag
     2. Estado vazio           .empty-state
     3. Estado de erro         .error-state
     4. Área de upload         .drop-zone
     5. Diálogo de confirmação .modal / .confirm-dialog
     6. Campo                  .field
     7. Barra de filtros       .filter-bar

   Os componentes 1, 2, 4 e 5 existiam em versão mínima no
   `move-style.css` e foram removidos de lá — a definição é esta, e só
   esta. Os nomes de classe foram preservados de propósito: os HTML que
   já usavam `.tbl`, `.empty-state`, `.drop-zone` e `.modal` continuam
   funcionando sem tocar no markup, e ganham os estados novos de graça.

   Galeria de referência: `docs/componentes.html` (fora de shared/docs/,
   porque é documento interno e não pode ser publicado nos 4 domínios).
   ═══════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════
   1 · TABELA COM PAGINAÇÃO
   ═══════════════════════════════════════════════════════════════ */

.tbl-card{
  background:var(--table-bg);
  border:1px solid var(--table-border);
  border-radius:var(--table-radius);
  overflow:hidden;
}
.tbl-head{
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--spacing-3);flex-wrap:wrap;
  padding:var(--spacing-4) var(--spacing-5) var(--spacing-3);
  border-bottom:1px solid var(--color-border-subtle);
}
.tbl-head h3{
  font-size:var(--font-size-15);
  font-weight:var(--font-weight-bold);
  margin:0;
}
.tbl-count{
  font-size:var(--font-size-12);
  color:var(--color-text-tertiary);
}

/* rolagem horizontal presa ao card — a página nunca rola de lado */
.tbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;}

.tbl{
  width:100%;border-collapse:collapse;
  font-size:var(--table-font-size);
  min-width:var(--table-min-width);
}
.tbl th{
  padding:var(--spacing-3) var(--table-cell-padding-x);
  text-align:left;white-space:nowrap;
  font-size:var(--table-head-font-size);
  font-weight:var(--font-weight-bold);
  letter-spacing:var(--letter-spacing-wide);
  text-transform:uppercase;
  color:var(--color-text-secondary);
  border-bottom:1px solid var(--color-border-subtle);
  background:var(--table-bg);
}
.tbl td{
  padding:var(--table-cell-padding-y) var(--table-cell-padding-x);
  border-bottom:1px solid var(--color-border-subtle);
  color:var(--color-text-secondary);
  vertical-align:middle;
}
.tbl tbody tr:last-child td{border-bottom:none;}
.tbl td strong{color:var(--color-text-primary);font-weight:var(--font-weight-semibold);}

/* cabeçalho fixo — só quando a tabela tem altura própria */
.tbl-wrap.tbl-sticky{max-height:60vh;overflow-y:auto;}
.tbl-wrap.tbl-sticky .tbl th{position:sticky;top:0;z-index:var(--z-sticky);}

/* ── estado: linha em hover ── */
.tbl tbody tr:hover td{background:var(--table-row-hover-bg);}

/* ── estado: linha selecionada ──
   a borda esquerda marca sem depender só de cor de fundo, que some
   quando o hover passa por cima */
.tbl tbody tr.selected td{background:var(--table-row-selected-bg);}
.tbl tbody tr.selected td:first-child{box-shadow:inset 3px 0 0 var(--table-row-selected-border);}

/* ── estado: coluna ordenável ── */
.tbl th.sortable{cursor:pointer;user-select:none;transition:color var(--duration-base) var(--ease-out);}
.tbl th.sortable:hover{color:var(--color-text-primary);}
.tbl th.sortable::after{
  content:'↕';
  margin-left:var(--spacing-1);
  opacity:.35;font-size:var(--font-size-11);
}
.tbl th.sortable[aria-sort="ascending"]{color:var(--color-brand);}
.tbl th.sortable[aria-sort="ascending"]::after{content:'↑';opacity:1;}
.tbl th.sortable[aria-sort="descending"]{color:var(--color-brand);}
.tbl th.sortable[aria-sort="descending"]::after{content:'↓';opacity:1;}

/* ── estado: carregando (linhas skeleton) ── */
.tbl td .sk{
  display:block;height:12px;
  border-radius:var(--skeleton-radius);
  background:linear-gradient(90deg,
    var(--color-skeleton-base) 0%,
    var(--color-skeleton-shimmer) 50%,
    var(--color-skeleton-base) 100%);
  background-size:200% 100%;
  animation:tbl-sk var(--skeleton-duration) ease-in-out infinite;
}
.tbl td .sk.w-60{width:60%;}
.tbl td .sk.w-40{width:40%;}
@keyframes tbl-sk{to{background-position:-200% 0;}}

/* ── estado: vazia / erro dentro da tabela ──
   a célula ocupa a largura toda para o estado ficar centrado no card */
.tbl td.tbl-state{padding:0;border-bottom:none;}

/* ── PAGINAÇÃO ── */
.tbl-pag{
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--spacing-3);flex-wrap:wrap;
  padding:var(--spacing-3) var(--spacing-5);
  border-top:1px solid var(--color-border-subtle);
  font-size:var(--pag-font-size);
}
.tbl-pag-info{color:var(--color-text-tertiary);}
.tbl-pag-nav{display:flex;align-items:center;gap:var(--spacing-1);}
.tbl-pag button{
  min-width:var(--pag-btn-size);height:var(--pag-btn-size);
  padding:0 var(--spacing-2);
  display:inline-flex;align-items:center;justify-content:center;
  background:transparent;
  border:1px solid transparent;
  border-radius:var(--pag-radius);
  color:var(--color-text-secondary);
  font-family:var(--font-brand);
  font-size:var(--pag-font-size);
  font-weight:var(--font-weight-semibold);
  cursor:pointer;
  transition:background var(--duration-fast) var(--ease-out),
             color var(--duration-fast) var(--ease-out),
             border-color var(--duration-fast) var(--ease-out);
  -webkit-tap-highlight-color:transparent;
}
.tbl-pag button:hover:not(:disabled):not([aria-current="page"]){
  background:var(--color-hover-overlay);
  color:var(--color-text-primary);
}
.tbl-pag button:focus-visible{
  outline:none;
  box-shadow:0 0 0 3px var(--color-interactive-focus-ring);
}
/* página atual */
.tbl-pag button[aria-current="page"]{
  background:var(--pag-active-bg);
  border-color:var(--pag-active-border);
  color:var(--pag-active-text);
  cursor:default;
}
/* primeira/última página — anterior/próxima desabilitados.
   pointer-events:none impede o clique fantasma que o :disabled sozinho
   ainda deixa passar em alguns navegadores móveis */
.tbl-pag button:disabled{
  opacity:var(--color-interactive-disabled-opacity);
  cursor:not-allowed;pointer-events:none;
}
/* elipse entre blocos de páginas — não é botão, não recebe foco */
.tbl-pag .pag-gap{
  min-width:var(--pag-btn-size);
  text-align:center;
  color:var(--color-text-tertiary);
  user-select:none;
}


/* ═══════════════════════════════════════════════════════════════
   2 · ESTADO VAZIO
   ═══════════════════════════════════════════════════════════════ */

.empty-state{
  display:flex;flex-direction:column;align-items:center;
  gap:var(--spacing-2);
  padding:var(--state-padding);
  text-align:center;
  color:var(--color-text-tertiary);
}
.empty-state .emi{
  font-size:var(--state-icon-size);
  line-height:1;
  opacity:.9;
}
.empty-state h4{
  font-size:var(--state-title-size);
  font-weight:var(--font-weight-semibold);
  color:var(--color-text-primary);
  margin:0;
}
.empty-state p{
  font-size:var(--state-text-size);
  line-height:var(--line-height-normal);
  max-width:var(--state-max-width);
  margin:0;
}
.empty-state .empty-actions{
  display:flex;gap:var(--spacing-2);flex-wrap:wrap;
  justify-content:center;
  margin-top:var(--spacing-2);
}

/* ── estado: busca sem resultado ──
   tom neutro em vez do laranja do primeiro uso: aqui não há nada a
   celebrar nem a criar, só um filtro a afrouxar */
.empty-state.no-results .emi{opacity:.55;}

/* ── estado: sem permissão ── */
.empty-state.forbidden .emi{opacity:.55;}
.empty-state.forbidden h4{color:var(--color-text-secondary);}

/* ── estado: compacto (dentro de card pequeno) ── */
.empty-state.compact{padding:var(--state-padding-compact);}
.empty-state.compact .emi{font-size:24px;}
.empty-state.compact h4{font-size:var(--font-size-13);}
.empty-state.compact p{font-size:var(--font-size-12);}


/* ═══════════════════════════════════════════════════════════════
   3 · ESTADO DE ERRO
   ═══════════════════════════════════════════════════════════════ */

.error-state{
  display:flex;flex-direction:column;align-items:center;
  gap:var(--spacing-2);
  padding:var(--state-padding);
  text-align:center;
}
.error-state .eri{
  font-size:var(--state-icon-size);
  line-height:1;
  color:var(--color-error-icon);
}
.error-state h4{
  font-size:var(--state-title-size);
  font-weight:var(--font-weight-semibold);
  color:var(--color-error-text);
  margin:0;
}
.error-state p{
  font-size:var(--state-text-size);
  line-height:var(--line-height-normal);
  color:var(--color-text-secondary);
  max-width:var(--state-max-width);
  margin:0;
}
.error-state .error-actions{
  display:flex;gap:var(--spacing-2);flex-wrap:wrap;
  justify-content:center;
  margin-top:var(--spacing-2);
}

/* ── estado: offline ──
   âmbar, não vermelho: não é falha da aplicação e costuma se resolver
   sozinho, então não deve alarmar como um erro real */
.error-state.offline .eri{color:var(--color-warning-icon);}
.error-state.offline h4{color:var(--color-warning-text);}

/* ── estado: inline (dentro de card ou linha de tabela) ── */
.error-state.inline{
  flex-direction:row;align-items:flex-start;
  text-align:left;
  gap:var(--spacing-3);
  padding:var(--spacing-3) var(--spacing-4);
  background:var(--color-error-bg);
  border:1px solid var(--color-error-border);
  border-radius:var(--radius-md);
}
.error-state.inline .eri{font-size:var(--font-size-18);flex-shrink:0;}
.error-state.inline h4{font-size:var(--font-size-13);}
.error-state.inline p{font-size:var(--font-size-12);max-width:none;}

/* ── estado: com detalhe técnico colapsável ──
   o <details> fica fechado por padrão: o texto de cima é para quem vai
   agir, o de dentro é para quem vai depurar */
.error-state details{
  margin-top:var(--spacing-3);
  width:100%;max-width:var(--state-max-width);
  text-align:left;
}
.error-state.inline details{max-width:none;}
.error-state summary{
  cursor:pointer;list-style:none;
  font-size:var(--font-size-12);
  color:var(--color-text-tertiary);
  padding:var(--spacing-1) 0;
  -webkit-tap-highlight-color:transparent;
}
.error-state summary::-webkit-details-marker{display:none;}
.error-state summary::before{content:'▸ ';display:inline-block;transition:transform var(--duration-fast);}
.error-state details[open] summary::before{content:'▾ ';}
.error-state summary:hover{color:var(--color-text-secondary);}
.error-state details pre{
  margin-top:var(--spacing-2);
  padding:var(--spacing-3);
  background:var(--color-fill-subtle);
  border:1px solid var(--color-border-subtle);
  border-radius:var(--radius-sm);
  font-family:var(--font-mono);
  font-size:var(--font-size-11);
  line-height:var(--line-height-relaxed);
  color:var(--color-text-tertiary);
  white-space:pre-wrap;word-break:break-word;
  max-height:160px;overflow-y:auto;
}


/* ═══════════════════════════════════════════════════════════════
   4 · ÁREA DE UPLOAD
   ═══════════════════════════════════════════════════════════════ */

.drop-zone{
  position:relative;
  border:2px dashed var(--dz-border-idle);
  border-radius:var(--dz-radius);
  background:var(--dz-bg-idle);
  padding:var(--dz-padding);
  text-align:center;cursor:pointer;
  transition:border-color var(--duration-base) var(--ease-out),
             background var(--duration-base) var(--ease-out);
}
.drop-zone input[type=file]{
  position:absolute;inset:0;
  width:100%;height:100%;
  opacity:0;cursor:pointer;
}
.drop-zone .dz-ico{font-size:var(--dz-icon-size);margin-bottom:var(--spacing-1);line-height:1;}
.drop-zone .dz-txt{font-size:var(--font-size-13);color:var(--color-text-secondary);}
.drop-zone .dz-txt strong{color:var(--color-brand);font-weight:var(--font-weight-semibold);}
.drop-zone .dz-hint{
  display:block;margin-top:var(--spacing-1);
  font-size:var(--font-size-11);
  color:var(--color-text-tertiary);
}

/* ── estado: hover, toque e arrastando por cima ──
   o mesmo destaque para os três: para quem arrasta um arquivo, "posso
   soltar aqui" e "isto é clicável" são a mesma informação. O :active
   existe porque no celular não há hover — sem ele, tocar na área não dá
   retorno nenhum até o seletor de arquivos abrir. */
.drop-zone:hover,
.drop-zone:active,
.drop-zone.drag{
  border-color:var(--dz-border-active);
  background:var(--dz-bg-active);
}
.drop-zone.drag{border-style:solid;}

/* ── estado: enviando ── */
.drop-zone.uploading{cursor:progress;border-style:solid;}
.drop-zone.uploading input[type=file]{pointer-events:none;}
.dz-progress{
  height:4px;margin-top:var(--spacing-3);
  background:var(--color-fill-subtle);
  border-radius:var(--radius-pill);
  overflow:hidden;
}
.dz-progress>span{
  display:block;height:100%;width:0;
  background:var(--color-brand);
  border-radius:inherit;
  transition:width var(--duration-moderate) var(--ease-out);
}

/* ── estado: sucesso ── */
.drop-zone.done{
  border-color:var(--color-success-border);
  border-style:solid;
  background:var(--color-success-bg);
}
.drop-zone.done .dz-txt strong{color:var(--color-success-text);}
/* Ícone entra com leve overshoot — raro (um upload por documento), aqui vale o toque de delight */
.drop-zone.done .dz-ico{animation:dz-done-pop var(--duration-slow) var(--ease-spring);}
@keyframes dz-done-pop{from{transform:scale(0.8);opacity:0;}to{transform:scale(1);opacity:1;}}

/* ── estado: erro (tipo ou tamanho rejeitado) ── */
.drop-zone.error{
  border-color:var(--color-error-border);
  border-style:solid;
  background:var(--color-error-bg);
}
.drop-zone.error .dz-txt{color:var(--color-error-text);}
.drop-zone.error .dz-txt strong{color:var(--color-error-text);}

/* ── estado: desabilitado e limite atingido ──
   limite atingido não é erro: o que já foi enviado está certo, só não
   cabe mais. Por isso cinza, não vermelho */
.drop-zone.disabled,
.drop-zone.full{
  opacity:var(--color-interactive-disabled-opacity);
  cursor:not-allowed;
  border-color:var(--color-border);
  background:var(--color-fill-subtle);
}
.drop-zone.disabled input[type=file],
.drop-zone.full input[type=file]{pointer-events:none;}

/* ── lista de arquivos ── */
.file-list{display:flex;flex-direction:column;gap:var(--spacing-2);margin-top:var(--spacing-3);}
.file-item{
  display:flex;align-items:center;gap:var(--spacing-2);
  padding:var(--spacing-2) var(--spacing-3);
  background:var(--color-fill-subtle);
  border:1px solid var(--color-border-subtle);
  border-radius:var(--radius-sm);
  font-size:var(--font-size-13);
  color:var(--color-text-secondary);
}
.file-item .fi-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.file-item .fi-size{font-size:var(--font-size-11);color:var(--color-text-tertiary);flex-shrink:0;}
.file-item.error{
  background:var(--color-error-bg);
  border-color:var(--color-error-border);
  color:var(--color-error-text);
}
.file-rm{
  flex-shrink:0;
  background:none;border:none;padding:0 var(--spacing-1);
  color:var(--color-text-tertiary);
  font-size:var(--font-size-16);cursor:pointer;line-height:1;
  -webkit-tap-highlight-color:transparent;
}
.file-rm:hover{color:var(--color-error-text);}


/* ═══════════════════════════════════════════════════════════════
   5 · MODAL E DIÁLOGO DE CONFIRMAÇÃO
   ═══════════════════════════════════════════════════════════════ */

.modal-bg{
  position:fixed;inset:0;z-index:var(--z-modal);
  display:none;align-items:center;justify-content:center;
  padding:var(--spacing-4);
  background:var(--color-overlay);
  backdrop-filter:blur(var(--blur-sm));
  -webkit-backdrop-filter:blur(var(--blur-sm));
}
.modal-bg.open{display:flex;}
.modal{
  width:100%;max-width:var(--modal-max-width-md);
  max-height:92vh;overflow-y:auto;
  padding:var(--spacing-6) var(--spacing-5);
  background:var(--modal-bg);
  border:1px solid var(--modal-border);
  border-radius:var(--modal-radius);
  box-shadow:var(--elevation-4);
  animation:modal-in var(--duration-moderate) var(--ease-out);
}
@keyframes modal-in{from{opacity:0;transform:translateY(18px);}to{opacity:1;transform:none;}}
@media(prefers-reduced-motion:reduce){
  .modal{animation:none;}
}
.modal::-webkit-scrollbar{width:4px;}
.modal::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:2px;}
.modal-sm{max-width:var(--modal-max-width-sm);}
.modal-lg{max-width:var(--modal-max-width-lg);}
.modal-head{
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--spacing-3);
  margin-bottom:var(--spacing-5);
}
.modal-head h3{
  font-size:var(--font-size-18);
  font-weight:var(--font-weight-extrabold);
  margin:0;
}
.modal-close{
  flex-shrink:0;
  width:32px;height:32px;
  display:flex;align-items:center;justify-content:center;
  background:var(--color-fill-ghost);
  border:none;border-radius:50%;
  color:var(--color-text-secondary);
  font-size:var(--font-size-20);cursor:pointer;line-height:1;
  transition:background var(--duration-fast) var(--ease-out),
             color var(--duration-fast) var(--ease-out);
  -webkit-tap-highlight-color:transparent;
}
.modal-close:hover{background:var(--color-fill-moderate);color:var(--color-text-primary);}
.modal-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--spacing-3);}
.mfull{grid-column:1/-1;}

/* ── DIÁLOGO DE CONFIRMAÇÃO ── */
.confirm-dialog{
  max-width:var(--confirm-max-width);
  text-align:center;
}
.confirm-dialog .cf-ico{
  width:var(--confirm-icon-size);height:var(--confirm-icon-size);
  margin:0 auto var(--confirm-gap);
  display:flex;align-items:center;justify-content:center;
  border-radius:50%;
  font-size:var(--font-size-20);line-height:1;
  background:var(--color-fill-brand-ghost);
  color:var(--color-brand);
}
.confirm-dialog h3{
  font-size:var(--font-size-18);
  font-weight:var(--font-weight-bold);
  margin:0 0 var(--spacing-2);
}
.confirm-dialog p{
  font-size:var(--font-size-13);
  line-height:var(--line-height-normal);
  color:var(--color-text-secondary);
  margin:0;
}
.confirm-dialog .cf-actions{
  display:flex;gap:var(--spacing-2);
  margin-top:var(--spacing-5);
}
/* o confirmar vem por último — a ação irreversível não deve cair onde o
   polegar já está indo */
.confirm-dialog .cf-actions>*{flex:1;}

/* ── estado: destrutivo ── */
.confirm-dialog.danger .cf-ico{
  background:var(--color-error-bg);
  color:var(--color-error-icon);
}

/* ── estado: com aviso ── */
.confirm-dialog .cf-warn{
  display:block;
  margin-top:var(--confirm-gap);
  padding:var(--spacing-3);
  background:var(--color-warning-bg);
  border:1px solid var(--color-warning-border);
  border-radius:var(--radius-md);
  font-size:var(--font-size-12);
  line-height:var(--line-height-normal);
  color:var(--color-warning-text);
  text-align:left;
}

/* ── estado: confirmação digitada (ação irreversível) ──
   digitar o nome do alvo é o que separa "cliquei sem ler" de "eu quis" */
.confirm-dialog .cf-type{margin-top:var(--confirm-gap);text-align:left;}
.confirm-dialog .cf-type label{
  display:block;margin-bottom:var(--spacing-2);
  font-size:var(--font-size-12);
  color:var(--color-text-secondary);
}
.confirm-dialog .cf-type code{
  font-family:var(--font-mono);
  font-size:var(--font-size-12);
  color:var(--color-error-text);
}

/* ── estado: confirmando ── */
.confirm-dialog.busy .cf-actions{pointer-events:none;}


/* ═══════════════════════════════════════════════════════════════
   6 · CAMPO
   ═══════════════════════════════════════════════════════════════
   Sistema novo, não substitui `.fg`/`.iw` do `move-style.css` de
   imediato: aquele está em 6 formulários em produção e migrar todos é
   tarefa própria. Formulário novo nasce com `.field`; o antigo migra
   quando for mexido por outro motivo.
   ═══════════════════════════════════════════════════════════════ */

.field{display:flex;flex-direction:column;gap:var(--spacing-2);}
.field>label{
  font-size:var(--type-label-size);
  font-weight:var(--font-weight-bold);
  letter-spacing:var(--letter-spacing-wide);
  text-transform:uppercase;
  color:var(--color-text-secondary);
}
.field-wrap{
  display:flex;align-items:center;
  height:var(--input-height);
  background:var(--input-bg);
  border:1px solid var(--input-border);
  border-radius:var(--input-radius);
  transition:border-color var(--duration-base) var(--ease-out),
             background var(--duration-base) var(--ease-out),
             box-shadow var(--duration-base) var(--ease-out);
}
.field-wrap input,
.field-wrap select,
.field-wrap textarea{
  flex:1;min-width:0;width:100%;
  height:100%;
  padding:0 var(--spacing-4);
  background:none;border:none;outline:none;
  color:var(--color-text-primary);
  font-family:var(--font-brand);
  font-size:var(--input-font-size);
  -webkit-appearance:none;appearance:none;
}
.field-wrap textarea{
  padding:var(--spacing-3) var(--spacing-4);
  resize:vertical;min-height:80px;
  line-height:var(--line-height-normal);
}
.field-wrap:has(textarea){height:auto;}
.field-wrap input::placeholder,
.field-wrap textarea::placeholder{color:var(--color-text-tertiary);}
.field-wrap select{cursor:pointer;padding-right:var(--spacing-8);}
.field-wrap select option{background:var(--color-surface-1);color:var(--color-text-primary);}

/* ícones — o lead encosta na borda, o input recua para não colar nele */
.field-ico{
  flex-shrink:0;
  display:flex;align-items:center;
  color:var(--color-text-tertiary);
  font-size:var(--font-size-15);
  pointer-events:none;
}
.field-ico.lead{padding-left:var(--spacing-4);}
.field-ico.lead+input,
.field-ico.lead+select,
.field-ico.lead~input{padding-left:var(--spacing-2);}
.field-ico.trail{padding-right:var(--spacing-4);}

/* botão dentro do campo (olho da senha) — é o único filho clicável */
.field-btn{
  flex-shrink:0;
  background:none;border:none;
  padding:0 var(--spacing-3);
  color:var(--color-text-tertiary);
  font-size:var(--font-size-16);cursor:pointer;line-height:1;
  -webkit-tap-highlight-color:transparent;
}
.field-btn:hover{color:var(--color-text-primary);}

.field-hint{
  font-size:var(--font-size-12);
  line-height:var(--line-height-normal);
  color:var(--color-text-tertiary);
  padding-left:var(--spacing-1);
}

/* ── estado: hover ── */
.field-wrap:hover{
  background:var(--input-hover-bg);
  border-color:var(--input-hover-border);
}

/* ── estado: foco ── */
.field-wrap:focus-within{
  background:var(--input-focus-bg);
  border-color:var(--input-focus-border);
  box-shadow:var(--input-focus-shadow);
}

/* ── estado: preenchido ──
   sinal discreto de que há conteúdo, sem competir com o foco */
.field-wrap input:not(:placeholder-shown){font-weight:var(--font-weight-medium);}

/* ── estado: erro ──
   a cor sozinha não comunica (daltonismo, tela ruim, sol na tela): o
   texto do .field-hint é que carrega o motivo, e o aria-invalid é que
   avisa o leitor de tela. A borda é reforço, não o canal */
.field.error .field-wrap{
  border-color:var(--input-error-border);
  box-shadow:0 0 0 3px var(--color-error-bg);
}
.field.error>label{color:var(--color-error-text);}
.field.error .field-hint{color:var(--color-error-text);}
.field.error .field-ico{color:var(--color-error-icon);}

/* ── estado: sucesso ── */
.field.success .field-wrap{border-color:var(--input-success-border);}
.field.success .field-hint{color:var(--color-success-text);}
.field.success .field-ico{color:var(--color-success-icon);}

/* ── estado: desabilitado ── */
.field.disabled,
.field:has(input:disabled),
.field:has(select:disabled),
.field:has(textarea:disabled){
  opacity:var(--input-disabled-opacity);
}
.field.disabled .field-wrap,
.field:has(input:disabled) .field-wrap{cursor:not-allowed;}
.field.disabled .field-wrap:hover,
.field:has(input:disabled) .field-wrap:hover{
  background:var(--input-bg);
  border-color:var(--input-border);
}
.field input:disabled,
.field select:disabled,
.field textarea:disabled{cursor:not-allowed;}

/* ── estado: somente-leitura ──
   sem borda de foco e sem hover: nada aqui é editável, e fingir que é
   só gera tentativa frustrada */
.field.readonly .field-wrap{
  background:var(--color-fill-subtle);
  border-style:dashed;
}
.field.readonly .field-wrap:hover,
.field.readonly .field-wrap:focus-within{
  background:var(--color-fill-subtle);
  border-color:var(--input-border);
  box-shadow:none;
}

/* ── estado: com contador de caracteres ── */
.field-foot{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--spacing-3);
}
.field-foot .field-hint{flex:1;}
.field-count{
  flex-shrink:0;
  font-family:var(--font-mono);
  font-size:var(--font-size-11);
  color:var(--color-text-tertiary);
}
.field-count.over{color:var(--color-error-text);}


/* ═══════════════════════════════════════════════════════════════
   7 · BARRA DE FILTROS
   ═══════════════════════════════════════════════════════════════ */

.filter-bar{
  display:flex;align-items:center;
  gap:var(--filter-gap);flex-wrap:wrap;
  margin-bottom:var(--spacing-4);
}
.filter-bar .fsrch,
.filter-bar .fsel{
  height:var(--filter-height);
  padding:0 var(--spacing-4);
  background:var(--filter-bg);
  border:1px solid var(--filter-border);
  border-radius:var(--filter-radius);
  color:var(--color-text-primary);
  font-family:var(--font-brand);
  font-size:var(--filter-font-size);
  outline:none;
  transition:border-color var(--duration-base) var(--ease-out),
             background var(--duration-base) var(--ease-out),
             box-shadow var(--duration-base) var(--ease-out);
  -webkit-appearance:none;appearance:none;
}
.filter-bar .fsrch{flex:1;min-width:180px;}
.filter-bar .fsrch::placeholder{color:var(--color-text-tertiary);}
.filter-bar .fsel{
  cursor:pointer;
  color:var(--color-text-secondary);
  padding-right:var(--spacing-7);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23ffffff88' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right var(--spacing-3) center;
}
.filter-bar .fsel option{background:var(--color-surface-1);color:var(--color-text-primary);}

/* ── estado: hover ── */
.filter-bar .fsrch:hover,
.filter-bar .fsel:hover{border-color:var(--color-border-strong);}

/* ── estado: busca em foco ── */
.filter-bar .fsrch:focus,
.filter-bar .fsel:focus{
  border-color:var(--color-interactive-focus-border);
  box-shadow:0 0 0 3px var(--color-interactive-focus-ring);
}

/* ── estado: filtro com valor aplicado ──
   o <select> não mostra sozinho que está filtrando; sem isto o usuário
   olha uma lista curta e acha que não há dados */
.filter-bar .fsel.active{
  background-color:var(--chip-bg);
  border-color:var(--chip-border);
  color:var(--chip-text);
}

/* ── estado: chips de filtro ativo ──
   `.filter-active`, e não `.filter-chips`: esse nome já existe em
   `app.html` para outra coisa — uma fila de abas com rolagem horizontal.
   Dois componentes diferentes com o mesmo nome é o tipo de armadilha que
   só aparece meses depois, quando alguém reusa o errado. */
.filter-active{
  display:flex;align-items:center;
  gap:var(--spacing-2);flex-wrap:wrap;
  margin-bottom:var(--spacing-4);
}
.filter-chip{
  display:inline-flex;align-items:center;gap:var(--spacing-1);
  height:26px;padding:0 var(--spacing-1) 0 var(--spacing-3);
  background:var(--chip-bg);
  border:1px solid var(--chip-border);
  border-radius:var(--radius-badge);
  font-size:var(--font-size-12);
  font-weight:var(--font-weight-semibold);
  color:var(--chip-text);
  white-space:nowrap;
}
.filter-chip button{
  width:18px;height:18px;
  display:flex;align-items:center;justify-content:center;
  background:none;border:none;border-radius:50%;
  color:inherit;opacity:.7;
  font-size:var(--font-size-13);cursor:pointer;line-height:1;
  -webkit-tap-highlight-color:transparent;
}
.filter-chip button:hover{opacity:1;background:var(--color-fill-brand-moderate);}

/* ── estado: limpar tudo ── */
.filter-clear{
  background:none;border:none;padding:0 var(--spacing-2);
  color:var(--color-text-tertiary);
  font-family:var(--font-brand);
  font-size:var(--font-size-12);
  text-decoration:underline;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.filter-clear:hover{color:var(--color-text-primary);}

/* ── estado: contagem de resultados ── */
.filter-count{
  font-size:var(--font-size-12);
  color:var(--color-text-tertiary);
  white-space:nowrap;
}

/* ── estado: empilhada no mobile ──
   os selects viram grade de 2 para não gastar uma linha cada */
@media(max-width:640px){
  .filter-bar{flex-direction:column;align-items:stretch;}
  .filter-bar .fsrch{min-width:0;width:100%;}
  .filter-bar .fsel{width:100%;}
  .tbl-pag{justify-content:center;}
  .tbl-pag-info{width:100%;text-align:center;}
  .confirm-dialog .cf-actions{flex-direction:column-reverse;}
  .modal-grid{grid-template-columns:1fr;}
  .mfull{grid-column:1;}
}
