/* video-esteira — área administrativa
   Painel técnico escuro, densidade de informação alta, hierarquia clara.
   Referência declarada: openart.ai (grid visual limpo) — ponto fraco dela
   (esconder informação) é exatamente o que este painel evita: recusa de
   conversão precisa saltar aos olhos, nada fica escondido atrás de tabs. */

:root {
  /* --- superfícies --- */
  --cor-fundo: #0b0d12;
  --cor-fundo-painel: #12151c;
  --cor-fundo-elevado: #191d27;
  --cor-borda: #262b38;
  --cor-borda-forte: #3a4152;

  /* --- texto --- */
  --cor-texto: #e6e9f0;
  --cor-texto-secundario: #9aa3b8;
  /* 4,56:1 sobre --cor-fundo-elevado e 4,94:1 sobre --cor-fundo-painel
     (medido). O valor anterior (#6b7386) dava 3,55:1 e reprovava em texto
     de conteudo -- "custo: nao medido" e "vem de outro no" vivem aqui. */
  --cor-texto-fraco: #7d8598;

  /* --- DINHEIRO EM RISCO — a família âmbar, e só ela ---
     `CANVAS-DIRECAO-DE-DESIGN.md` §4.3: âmbar significa dinheiro, no app
     inteiro. Selo de custo, `indeterminado`, reserva pendurada,
     confirmação de gasto. Um aviso que NÃO é sobre dinheiro nunca usa
     âmbar — o valor deste canal vem da raridade dele. Se toda geração em
     andamento fosse âmbar, âmbar viraria papel de parede, e o caso que
     precisa ser visto (a chamada que pode ter cobrado e ninguém sabe)
     deixaria de ser visto. */
  --gasto: #fbbf24;
  --gasto-fundo: rgba(251, 191, 36, 0.16);
  --gasto-borda: #b45309;

  /* --- papéis semânticos de categoria de nó --- */
  --cor-nativo: #38bdf8;
  --cor-nativo-fundo: rgba(56, 189, 248, 0.12);
  /* A categoria "fornecedor" É dinheiro: na tela do grafo importado não
     existe selo de custo, e este ponto é o único sinal de que o nó gasta.
     Aponta para `--gasto` em vez de repetir o hex, para que a família
     âmbar tenha uma fonte só. */
  --cor-fornecedor: var(--gasto);
  --cor-fornecedor-fundo: var(--gasto-fundo);
  /* Era #6b7280 — 3,78:1 contra o painel, ABAIXO do piso de 4,5:1, e é
     usado como cor de TEXTO em chip. Defeito de contraste medido, não
     ajuste de gosto. Fica no piso de propósito: "ignorável" quer dizer
     "pule", e apagado é o que ele deve parecer. */
  --cor-ignoravel: #7d8598;
  --cor-ignoravel-fundo: rgba(125, 133, 152, 0.14);
  /* Era #f43f5e — o MESMO hex de `--cor-critico`. Um nó cujo tipo o
     importador não reconhece aparecia com a cor de coisa quebrada, e não
     é: é um nó que ninguém classificou ainda. Colisão irmã da do âmbar,
     achada na varredura da frente C. Lavanda clara, 9,89:1 contra o
     painel e 2,00:1 de separação em LUMINÂNCIA contra `--cor-ignoravel`
     — os dois pontos da legenda se distinguem também em preto e branco. */
  --cor-desconhecido: #c4b5fd;
  --cor-desconhecido-fundo: rgba(196, 181, 253, 0.16);

  /* --- papéis semânticos de severidade --- */
  --cor-critico: #f43f5e;
  --cor-critico-fundo: rgba(244, 63, 94, 0.14);
  --cor-critico-borda: #9f1239;
  /* `--cor-aviso` continua âmbar porque aviso de verdade é sobre risco;
     o que saiu daqui foi tudo que era INFORMAÇÃO e estava pegando âmbar
     emprestado por falta de papel próprio. */
  --cor-aviso: #f59e0b;
  --cor-aviso-fundo: rgba(245, 158, 11, 0.12);
  /* O papel que FALTAVA no vocabulário, e cuja ausência causou a colisão:
     sem `info`, toda informação neutra pegou `--cor-aviso`. `LEI #15a` —
     onde falta papel, a tela pega o token de significado oposto. */
  --cor-info: #38bdf8;
  --cor-info-fundo: rgba(56, 189, 248, 0.12);
  --cor-sucesso: #34d399;
  --cor-sucesso-fundo: rgba(52, 211, 153, 0.12);

  /* --- categoria de nó do CANVAS (`CANVAS-DIRECAO-DE-DESIGN.md` §4.1) ---
     Trilho de 3 px no topo do cartão. Carrega categoria e NADA MAIS:
     nunca estado, nunca custo. */
  --cat-entrada: #64748b;
  --cat-texto: #38bdf8;
  --cat-imagem: #a78bfa;
  --cat-video: #f472b6;
  --cat-audio: #2dd4bf;
  --cat-composicao: #818cf8;
  --cat-controle: #94a3b8;
  --cat-medicao: #22d3ee;
  --cat-saida: #34d399;

  /* --- TIPO DE DADO da porta (`CANVAS-DIRECAO-DE-DESIGN.md` §5) ---
     Canal diferente do trilho: o trilho diz a CATEGORIA do nó, a porta diz
     o TIPO que trafega na aresta. Os quatro de mídia reusam o hex da
     categoria homônima de propósito — "vídeo" é vídeo nos dois lugares, e
     duas cores para a mesma ideia seria a segunda gramática que o §10
     proíbe. `numero` e `booleano` não têm categoria, e ganham as suas.
     A cor é REFORÇO: o nome da porta é a verdade (§5). */
  --porta-texto: #38bdf8;
  --porta-imagem: #a78bfa;
  --porta-video: #f472b6;
  --porta-audio: #2dd4bf;
  --porta-numero: #fbbf24;
  --porta-booleano: #94a3b8;

  --raio: 8px;
  --raio-pequeno: 4px;
  --fonte-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  --fonte-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

* {
  box-sizing: border-box;
}

/* As superfícies que o navegador desenha por conta própria — seleção,
 * cursor de texto, barra de rolagem — vêm com a cor de NENHUM sistema de
 * design. Deixá-las no padrão é o detalhe que denuncia página montada em
 * vez de construída, e não custa nada trazê-las para a paleta. */
::selection {
  background: var(--cor-nativo);
  color: var(--cor-fundo);
}

html {
  scrollbar-color: var(--cor-borda-forte) var(--cor-fundo);
  scrollbar-width: thin;
  accent-color: var(--cor-nativo);
  caret-color: var(--cor-nativo);
}

::-webkit-scrollbar {
  width: 11px;
  height: 11px;
}

::-webkit-scrollbar-track {
  background: var(--cor-fundo);
}

::-webkit-scrollbar-thumb {
  background: var(--cor-borda-forte);
  border: 3px solid var(--cor-fundo);
  border-radius: 999px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--cor-texto-fraco);
}

html, body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--cor-fundo);
  color: var(--cor-texto);
  font-family: var(--fonte-ui);
  font-size: 14px;
  line-height: 1.45;
}

h2 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cor-texto-secundario);
  margin: 0 0 12px;
  font-weight: 600;
}

h3 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--cor-texto-fraco);
  margin: 16px 0 6px;
  font-weight: 600;
}

.mono {
  font-family: var(--fonte-mono);
}

/* --- topbar --- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 20px;
  border-bottom: 1px solid var(--cor-borda);
  background: var(--cor-fundo-painel);
}

.topbar-titulo {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-family: var(--fonte-mono);
}

.marca {
  font-weight: 700;
  color: var(--cor-texto);
}

.separador {
  color: var(--cor-texto-fraco);
}

.topbar-direita {
  display: flex;
  gap: 10px;
  align-items: center;
}

/* O chip do estúdio é uma CONDIÇÃO PERMANENTE do ambiente, não um
   evento e não dinheiro. Ele já disse "SEM AUTH · SÓ LOCAL"; deixou de
   ser verdade em v0.41.0, quando `_gate_estudio` passou a exigir token
   de todo mundo assim que um token existe. Rótulo de segurança que
   envelhece é pior que nenhum, porque o operador confia nele. Alerta que nunca sai da tela vira decoração no
   segundo dia — e, em âmbar, competia com o único canal que precisa
   assustar. Fica legível e quieto: chip neutro de borda forte. Quem
   carrega o significado é o texto, que diz exatamente o que é; a cor não
   é indicador de nada aqui, e por isso não pode mentir. */
.badge-aviso {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--cor-texto-secundario);
  background: var(--cor-fundo-elevado);
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio-pequeno);
  padding: 3px 8px;
}

/* Link entre as telas do produto (estúdio · canvas · acervo · vitrine). Vive
   aqui e não no CSS de uma delas: as três usam, e uma cópia por tela era
   exatamente a duplicação que a LEI #12 proíbe. */
.link-navegacao {
  font-size: 11px;
  color: var(--cor-texto-secundario);
}

.link-navegacao:hover {
  color: var(--cor-texto);
}

.badge-versao {
  font-family: var(--fonte-mono);
  font-size: 12px;
  color: var(--cor-texto-secundario);
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio-pequeno);
  padding: 3px 8px;
}

/* --- layout de 3 colunas --- */

.layout {
  display: grid;
  /* A largura da lateral é do usuário, não nossa: o grafo pede espaço, o
   * painel de trabalho também, e quem sabe qual dos dois está em uso
   * naquele minuto é quem está usando. */
  grid-template-columns: 300px minmax(0, 1fr) 5px var(--largura-lateral, 380px);
  gap: 1px;
  background: var(--cor-borda);
  height: calc(100vh - 49px);
}

@media (max-width: 1100px) {
  .layout {
    grid-template-columns: 1fr;
    height: auto;
  }

  .divisor {
    display: none;
  }
}

.painel {
  background: var(--cor-fundo-painel);
  padding: 16px;
  overflow-y: auto;
}

.painel-lateral-direita {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
}

.painel-secao {
  padding: 16px;
  border-bottom: 1px solid var(--cor-borda);
  overflow-y: auto;
  /* Cada seção tem a sua fatia e rola por dentro. Antes só a última
   * crescia, então um relatório com 8 recusas empurrava o painel
   * "Template" para FORA da tela — a seção onde se trabalha ficava
   * inalcançável justamente no grafo que mais precisa de conserto.
   * `min-height: 0` é o que permite um filho de flex encolher abaixo do
   * conteúdo; sem ele, `overflow-y` não tem efeito nenhum. */
  flex: 1 1 0;
  min-height: 0;
}

/* O painel de trabalho ganha mais espaço que os dois de leitura. */
.painel-secao:last-child {
  flex-grow: 1.6;
}

/* --- dropzone --- */

.dropzone {
  border: 2px dashed var(--cor-borda-forte);
  border-radius: var(--raio);
  padding: 22px 14px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.dropzone:hover,
.dropzone:focus-visible,
.dropzone.dropzone-ativo {
  border-color: var(--cor-nativo);
  background: rgba(56, 189, 248, 0.06);
  outline: none;
}

.dropzone-texto-principal {
  margin: 0 0 4px;
  font-weight: 600;
  color: var(--cor-texto);
}

.dropzone-texto-secundario {
  margin: 0;
  font-size: 12px;
  color: var(--cor-texto-fraco);
}

/* --- campos de versão --- */

.campo-versoes {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 14px;
}

.campo {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--cor-texto-secundario);
}

.campo input {
  font-family: var(--fonte-mono);
  font-size: 12px;
  background: var(--cor-fundo-elevado);
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio-pequeno);
  color: var(--cor-texto);
  padding: 6px 8px;
}

.campo input:focus {
  outline: 1px solid var(--cor-nativo);
  border-color: var(--cor-nativo);
}

/* --- estado da importação --- */

.estado-importacao {
  margin-top: 12px;
  font-size: 12.5px;
}

.estado-importacao:empty {
  display: none;
}

.estado-erro {
  border: 1px solid var(--cor-critico-borda);
  background: var(--cor-critico-fundo);
  color: #ffd4dc;
  border-radius: var(--raio-pequeno);
  padding: 10px 12px;
  white-space: pre-wrap;
  font-family: var(--fonte-mono);
}

.estado-carregando {
  color: var(--cor-texto-secundario);
}

/* --- resumo da receita --- */

.resumo-receita dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 10px;
  margin: 0;
  font-size: 12.5px;
}

.resumo-receita dt {
  color: var(--cor-texto-fraco);
}

.resumo-receita dd {
  margin: 0;
  color: var(--cor-texto);
  overflow-wrap: anywhere;
}

.chips-categorias {
  list-style: none;
  padding: 0;
  margin: 10px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chip {
  font-size: 11px;
  font-family: var(--fonte-mono);
  border-radius: var(--raio-pequeno);
  padding: 3px 7px;
  border: 1px solid;
}

/* --- legenda + cor por categoria (papel semântico) --- */

.legenda ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  color: var(--cor-texto-secundario);
}

.ponto {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 6px;
}

.categoria-nativo, .chip-nativo { color: var(--cor-nativo); border-color: var(--cor-nativo); background: var(--cor-nativo-fundo); }
.categoria-fornecedor, .chip-fornecedor { color: var(--cor-fornecedor); border-color: var(--cor-fornecedor); background: var(--cor-fornecedor-fundo); }
.categoria-ignoravel, .chip-ignoravel { color: var(--cor-ignoravel); border-color: var(--cor-ignoravel); background: var(--cor-ignoravel-fundo); }
.categoria-desconhecido, .chip-desconhecido { color: var(--cor-desconhecido); border-color: var(--cor-desconhecido); background: var(--cor-desconhecido-fundo); }

.ponto.categoria-nativo { background: var(--cor-nativo); }
.ponto.categoria-fornecedor { background: var(--cor-fornecedor); }
.ponto.categoria-ignoravel { background: var(--cor-ignoravel); }
.ponto.categoria-desconhecido { background: var(--cor-desconhecido); }

/* --- painel do grafo --- */

.painel-grafo {
  padding: 16px 0 16px 16px;
  display: flex;
  flex-direction: column;
}

.grafo-vazio, .relatorio-vazio, .detalhe-vazio {
  color: var(--cor-texto-fraco);
  font-size: 13px;
  padding: 12px 0;
}

.grafo-scroll {
  /* Era `auto`: o SVG esticava por CSS até caber e o resto virava barra de
     rolagem. Agora quem move é a CÂMERA (ver `app.js`) — arrastar e rolar
     são zoom e deslocamento, como no canvas do próprio ComfyUI, e a barra
     de rolagem só atrapalharia. */
  overflow: hidden;
  position: relative;
  cursor: grab;
  flex: 1;
  /* grafo largo e raso (poucas camadas, muitos nós por camada) sobra
     espaço vertical — centralizar evita que ele fique grudado no topo */
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  background:
    linear-gradient(var(--cor-fundo) 0, var(--cor-fundo) 100%),
    repeating-linear-gradient(0deg, transparent, transparent 23px, var(--cor-borda) 24px),
    repeating-linear-gradient(90deg, transparent, transparent 23px, var(--cor-borda) 24px);
  background-blend-mode: normal;
  position: relative;
}

.grafo-scroll.arrastando {
  cursor: grabbing;
}

.grafo-scroll:focus-visible {
  outline: 2px solid var(--cor-nativo);
  outline-offset: -2px;
}

#grafo-svg {
  display: block;
  /* O SVG ocupa o painel inteiro e o `viewBox` acompanha o TAMANHO DELE,
     em pixels (ver `ajustarMolduraDoSvg`): quem enquadra é a câmera, não
     o CSS. Esticar o SVG até caber — o que se fazia antes — transformava
     um grafo de 25 nós em letra de 4 px sem nenhum jeito de chegar perto. */
  width: 100%;
  height: 100%;
}

/* --- ferramentas de zoom --- */

.ferramentas-grafo {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 12px;
  vertical-align: middle;
}

.botao-zoom {
  width: 24px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio-pequeno);
  background: var(--cor-fundo-elevado);
  color: var(--cor-texto-secundario);
  font-family: var(--fonte-ui);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}

.botao-zoom-largo {
  width: auto;
  padding: 0 8px;
  font-size: 11px;
  text-transform: none;
  letter-spacing: 0;
}

.botao-zoom:hover {
  color: var(--cor-texto);
  border-color: var(--cor-texto-fraco);
}

.zoom-nivel {
  min-width: 42px;
  text-align: center;
  font-family: var(--fonte-mono);
  font-size: 11px;
  color: var(--cor-texto-fraco);
  font-variant-numeric: tabular-nums;
}

/* nós do grafo (desenhados via SVG, ver app.js) */

.no-grafo rect {
  fill: var(--cor-fundo-elevado);
  stroke-width: 1.5;
  rx: 6;
}

.no-grafo.categoria-nativo rect { stroke: var(--cor-nativo); }
.no-grafo.categoria-fornecedor rect { stroke: var(--cor-fornecedor); }
.no-grafo.categoria-ignoravel rect { stroke: var(--cor-ignoravel); }
.no-grafo.categoria-desconhecido rect { stroke: var(--cor-desconhecido); }

.no-grafo.no-selecionado rect {
  stroke-width: 3;
  filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.25));
}

.no-grafo:hover rect {
  filter: brightness(1.25);
}

.no-grafo {
  cursor: pointer;
}

.no-grafo text {
  fill: var(--cor-texto);
  font-family: var(--fonte-mono);
  pointer-events: none;
}

.no-grafo .no-id {
  fill: var(--cor-texto-fraco);
  font-size: 10px;
}

.no-grafo .no-class-type {
  font-size: 11px;
  font-weight: 600;
}

.no-grafo .no-titulo {
  fill: var(--cor-texto-secundario);
  font-size: 10px;
}

.aresta {
  fill: none;
  stroke: var(--cor-borda-forte);
  stroke-width: 1.5;
}

/* --- relatório de conversão --- */

.banner-ok, .banner-recusado {
  border-radius: var(--raio-pequeno);
  padding: 10px 12px;
  font-weight: 600;
  font-size: 13px;
  margin-bottom: 12px;
}

.banner-ok {
  background: var(--cor-sucesso-fundo);
  color: var(--cor-sucesso);
  border: 1px solid var(--cor-sucesso);
}

.banner-recusado {
  background: var(--cor-critico-fundo);
  color: #ffd4dc;
  border: 2px solid var(--cor-critico);
}

.lista-relatorio {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.item-relatorio {
  font-size: 12px;
  border-radius: var(--raio-pequeno);
  padding: 6px 8px;
  border-left: 1px solid;
}

.item-recusa {
  border-color: var(--cor-critico);
  background: var(--cor-critico-fundo);
  color: #ffd4dc;
}

.item-perda {
  border-color: var(--cor-critico);
  background: var(--cor-critico-fundo);
  color: var(--cor-texto);
}

.item-aviso {
  border-color: var(--cor-info);
  background: var(--cor-info-fundo);
  color: var(--cor-texto);
}

.item-traduzido {
  border-color: var(--cor-sucesso);
  background: var(--cor-sucesso-fundo);
  color: var(--cor-texto);
}

.item-cabecalho {
  font-family: var(--fonte-mono);
  font-weight: 600;
  margin-bottom: 2px;
}

/* --- detalhe do nó --- */

.detalhe-titulo {
  font-family: var(--fonte-mono);
  font-weight: 700;
  font-size: 13px;
  margin-bottom: 2px;
}

.detalhe-subtitulo {
  color: var(--cor-texto-fraco);
  font-size: 12px;
  margin-bottom: 10px;
}

.tabela-inputs {
  width: 100%;
  border-collapse: collapse;
  font-size: 11.5px;
  font-family: var(--fonte-mono);
}

.tabela-inputs th {
  text-align: left;
  color: var(--cor-texto-fraco);
  font-weight: 500;
  padding: 3px 6px 3px 0;
  border-bottom: 1px solid var(--cor-borda);
}

.tabela-inputs td {
  padding: 3px 6px 3px 0;
  border-bottom: 1px solid var(--cor-borda);
  vertical-align: top;
  word-break: break-word;
}

.tabela-inputs td.chave {
  color: var(--cor-texto-secundario);
  white-space: nowrap;
}

/* --- parametrização de template ------------------------------------- */
/* Reusa os papéis semânticos já declarados no :root (sucesso, aviso,
 * borda-forte). Nenhuma cor literal nova: papel que falta é papel que a
 * tela acaba pegando emprestado do significado oposto (LEI #15a). */

.ajuda-secao {
  margin: 0 0 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--cor-texto-secundario);
}

.campo select {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-pequeno);
  background: var(--cor-fundo-elevado);
  color: var(--cor-texto);
  font-family: var(--fonte-ui);
  font-size: 13px;
}

.campo input[type="checkbox"] {
  width: auto;
  margin-right: auto;
}

.estado-ok {
  color: var(--cor-sucesso);
  background: var(--cor-sucesso-fundo);
}

.tabela-extrato {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  margin-top: 8px;
}

.tabela-extrato th,
.tabela-extrato td {
  border-bottom: 1px solid var(--cor-borda);
  padding: 4px 6px;
  text-align: left;
  vertical-align: top;
}

.botao-primario,
.botao-secundario,
.botao-marca {
  border-radius: var(--raio-pequeno);
  border: 1px solid var(--cor-borda-forte);
  padding: 6px 10px;
  font-family: var(--fonte-ui);
  font-size: 12px;
  cursor: pointer;
}

.botao-primario {
  width: 100%;
  margin-top: 8px;
  background: var(--cor-nativo-fundo);
  border-color: var(--cor-nativo);
  color: var(--cor-texto);
}

.botao-primario:disabled {
  background: var(--cor-fundo-elevado);
  border-color: var(--cor-borda);
  color: var(--cor-texto-fraco);
  cursor: not-allowed;
}

.botao-secundario {
  margin-left: 8px;
  background: transparent;
  color: var(--cor-texto-secundario);
}

.botao-marca {
  background: var(--cor-fundo-elevado);
  color: var(--cor-texto-secundario);
  white-space: nowrap;
}

.botao-marca-cliente {
  background: var(--cor-sucesso-fundo);
  border-color: var(--cor-sucesso);
  color: var(--cor-texto);
}

.editor-marca {
  margin-left: auto;
}

.marca-editado {
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: var(--raio-pequeno);
  font-size: 10px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  background: var(--cor-nativo-fundo);
  border: 1px solid var(--cor-nativo);
  color: var(--cor-texto);
  white-space: nowrap;
}

.marca-fixo {
  font-size: 11px;
  color: var(--cor-texto-fraco);
  white-space: nowrap;
}

.editor-campo {
  margin-top: 12px;
  padding: 12px;
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio);
  background: var(--cor-fundo-elevado);
}

/* O editor mede ~480px e a seção que o hospeda, ~390px: sem grudar, a
 * ação principal nasce abaixo da dobra e quem digita não vê onde
 * confirmar. Fica colada no fim da área visível enquanto o editor estiver
 * na tela. */
.editor-acoes {
  display: flex;
  align-items: center;
  margin: 8px -12px -12px;
  padding: 8px 12px;
  position: sticky;
  bottom: -12px;
  background: var(--cor-fundo-elevado);
  border-top: 1px solid var(--cor-borda);
  border-radius: 0 0 var(--raio) var(--raio);
}

.editor-acoes .botao-primario {
  width: auto;
}

.lista-campos {
  margin: 0 0 8px;
  padding: 0;
  list-style: none;
}

.item-campo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  padding: 6px 0;
  border-bottom: 1px solid var(--cor-borda);
  font-size: 12px;
}

/* Campo que o servidor recusaria: o motivo fica NA LINHA do campo, junto
 * do botão que leva ao conserto — não só no título do botão de salvar. */
.item-campo-incompleto {
  border-left: 2px solid var(--cor-critico);
  padding-left: 6px;
}

.selo-sem-custo,
.selo-custo-incerto {
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: var(--raio-pequeno);
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.selo-sem-custo {
  background: var(--cor-sucesso-fundo);
  border: 1px solid var(--cor-sucesso);
  color: var(--cor-texto);
}

.selo-custo-incerto {
  background: var(--gasto-fundo);
  border: 1px solid var(--gasto);
  color: var(--cor-texto);
}

.orientacao-falha {
  flex-basis: 100%;
  margin-top: 4px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--cor-texto-secundario);
}

.item-campo-motivo {
  color: var(--cor-critico);
  font-size: 11px;
}

.previa-campo {
  margin-bottom: 10px;
  padding: 8px 10px;
  border-left: 1px solid var(--cor-nativo);
  background: var(--cor-fundo-elevado);
  border-radius: var(--raio-pequeno);
}

.previa-rotulo {
  font-size: 13px;
  font-weight: 600;
}

/* `.campo` usa display:flex, que VENCE o atributo `hidden` — sem esta
 * regra, esconder o slot/opções pelo `hidden` não tem efeito nenhum
 * (bug real visto no smoke test do editor de campo). */
[hidden] {
  display: none !important;
}

/* --- superfícies que o navegador desenha ---------------------------- */
/* Seleção, cursor de texto, barra de rolagem e o checkbox nativo saem com
 * o padrão do sistema e não pertencem a design nenhum. Numeral tabular na
 * linha de custo porque é dado: colunas de dígitos precisam alinhar. */

::selection {
  background: var(--cor-nativo-fundo);
  color: var(--cor-texto);
}

input,
select,
textarea {
  caret-color: var(--cor-nativo);
}

.campo input[type="checkbox"] {
  accent-color: var(--cor-nativo);
}

* {
  scrollbar-width: thin;
  scrollbar-color: var(--cor-borda-forte) transparent;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: var(--cor-borda-forte);
  border: 2px solid var(--cor-fundo-painel);
  border-radius: 6px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--cor-texto-fraco);
}

/* --- estados dos controles ------------------------------------------ */
/* Todo controle interativo tem default, hover, focus e disabled. Sem isso
 * o botão parece decoração, não controle. */

.botao-primario,
.botao-secundario,
.botao-marca {
  transition: border-color 0.15s ease-out, background 0.15s ease-out,
    color 0.15s ease-out;
}

.botao-primario:hover:not(:disabled) {
  background: var(--cor-nativo);
  color: var(--cor-fundo);
}

.botao-primario:active:not(:disabled) {
  transform: translateY(1px);
}

.botao-secundario:hover {
  color: var(--cor-texto);
  border-color: var(--cor-texto-fraco);
}

.botao-marca:hover {
  border-color: var(--cor-nativo);
  color: var(--cor-texto);
}

.botao-marca-cliente:hover {
  border-color: var(--cor-sucesso);
}

.botao-primario:focus-visible,
.botao-secundario:focus-visible,
.botao-marca:focus-visible,
.campo select:focus-visible,
.campo input:focus-visible {
  outline: 2px solid var(--cor-nativo);
  outline-offset: 2px;
}

.campo select:focus {
  border-color: var(--cor-borda-forte);
  outline: none;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* --- item do acervo -------------------------------------------------- */
/* Nome primeiro, meta abaixo, custo como dado. O hash sai da linha e vira
 * `title`: identifica o artefato, mas não é o que o admin lê. */

.item-template {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 8px;
  padding: 10px 0;
  border-bottom: 1px solid var(--cor-borda);
}

.item-template:last-child {
  border-bottom: none;
}

.item-template-nome {
  font-size: 13px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.item-template-meta {
  grid-column: 1 / -1;
  font-size: 11px;
  color: var(--cor-texto-secundario);
}

.linha-custo {
  grid-column: 1 / -1;
  margin-top: 4px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--cor-texto-secundario);
}

.custo-nao-medido {
  color: var(--cor-texto-fraco);
}

/* Quatro ações (abrir · ver formulário · testar · excluir) não cabem na
 * coluna estreita ao lado do nome: ganham a linha inteira e quebram. */
.item-template-acoes {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
  align-self: start;
}

.item-template-hash {
  margin-left: 6px;
  font-size: 11px;
  font-weight: 400;
  color: var(--cor-texto-fraco);
}

/* Nome NÃO é identidade (D-18): o mesmo grafo salvo com um campo a mais
 * vira outro template com o mesmo nome. O selo é o que impede editar um
 * e publicar o outro. */
/* "nome repetido" e INFORMACAO, nao dinheiro: o hash e a identidade e o
   selo so avisa que dois templates compartilham o nome. */
.selo-homonimo {
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: var(--raio-pequeno);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--cor-info-fundo);
  border: 1px solid var(--cor-info);
  color: var(--cor-texto);
}

/* Revisão é a MESMA coisa noutra versão; homônimo de outro grafo é coisa
 * diferente com o mesmo nome. Papéis distintos, selos distintos. */
.selo-revisao {
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: var(--raio-pequeno);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--cor-nativo-fundo);
  border: 1px solid var(--cor-nativo);
  color: var(--cor-texto);
}

.revisoes-anteriores {
  grid-column: 1 / -1;
  margin-top: 6px;
  font-size: 11px;
  color: var(--cor-texto-secundario);
}

.revisoes-anteriores summary {
  cursor: pointer;
  padding: 2px 0;
}

.item-revisao {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 6px 0 6px 10px;
  border-left: 1px solid var(--cor-borda);
}

.confirmacao-exclusao {
  grid-column: 1 / -1;
  margin-top: 6px;
  padding: 8px 10px;
  border: 1px solid var(--cor-critico-borda);
  background: var(--cor-critico-fundo);
  border-radius: var(--raio-pequeno);
  font-size: 11px;
  line-height: 1.5;
}

.botao-destrutivo {
  border-color: var(--cor-critico);
  color: var(--cor-critico);
}

.previa-imagem {
  margin-top: 6px;
  max-width: 100%;
  /* `width: auto` + `object-fit` para que uma imagem pequena não seja
   * esticada até o limite da caixa: a prévia serve para reconhecer a
   * foto, e uma foto deformada não cumpre isso. */
  width: auto;
  height: auto;
  max-height: 160px;
  object-fit: contain;
  /* `.campo` é flex-column e estica os filhos na largura — sem isto uma
   * foto quadrada saía retangular. */
  align-self: flex-start;
  border-radius: var(--raio-pequeno);
  border: 1px solid var(--cor-borda);
}

.campo input[type="file"] {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--cor-borda-forte);
  border-radius: var(--raio-pequeno);
  background: var(--cor-fundo-elevado);
  color: var(--cor-texto);
  font-family: var(--fonte-ui);
  font-size: 12px;
}

.json-resolvido {
  max-height: 240px;
  overflow: auto;
  margin: 6px 0 0;
  padding: 8px;
  border-radius: var(--raio-pequeno);
  background: var(--cor-fundo-elevado);
  font-family: var(--fonte-mono);
  font-size: 11px;
  line-height: 1.45;
}

.item-template-acoes .botao-secundario {
  margin-left: 0;
}

/* --- oferta no acervo (D-A37) ---------------------------------------- */

.linha-oferta {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 11px;
}

.linha-oferta .botao-secundario {
  margin-left: 0;
}

.selo-publico,
.selo-interno-inline {
  padding: 2px 7px;
  border-radius: var(--raio-pequeno);
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.selo-publico {
  background: var(--cor-sucesso-fundo);
  border: 1px solid var(--cor-sucesso);
  color: var(--cor-texto);
}

.selo-interno-inline {
  background: var(--cor-info-fundo);
  border: 1px solid var(--cor-info);
  color: var(--cor-texto);
}

.detalhe-oferta {
  color: var(--cor-texto-secundario);
}

.campo textarea {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-pequeno);
  background: var(--cor-fundo-elevado);
  color: var(--cor-texto);
  font-family: var(--fonte-mono);
  font-size: 12px;
  line-height: 1.45;
  resize: vertical;
}

.campo textarea:focus-visible {
  outline: 2px solid var(--cor-nativo);
  outline-offset: 2px;
}

/* --- painéis recolhíveis e redimensionáveis --------------------------- */
/* Divisor é `role="separator"` com `tabindex` e setas do teclado: arrastar
 * com o mouse não pode ser o ÚNICO jeito de mudar o tamanho — quem navega
 * por teclado ficaria travado no tamanho que a gente escolheu. */

.divisor {
  background: var(--cor-borda);
  position: relative;
  transition: background 0.15s ease-out;
}

.divisor-vertical {
  cursor: col-resize;
}

.divisor-horizontal {
  height: 5px;
  flex: 0 0 5px;
  cursor: row-resize;
}

.divisor:hover,
.divisor:focus-visible {
  background: var(--cor-nativo);
  outline: none;
}

/* Alvo de arraste maior que a linha, sem engordar a linha. */
.divisor::after {
  content: "";
  position: absolute;
  inset: -3px;
}

.painel-secao h2 {
  margin: 0;
}

.cabecalho-secao {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 0 0 12px;
  border: none;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
  cursor: pointer;
}

.cabecalho-secao:hover {
  color: var(--cor-texto);
}

.cabecalho-secao:focus-visible {
  outline: 2px solid var(--cor-nativo);
  outline-offset: 2px;
}

.chevron {
  width: 0;
  height: 0;
  border-left: 4px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transform: rotate(90deg);
  transition: transform 0.15s ease-out;
}

.painel-secao[data-recolhido] .chevron {
  transform: rotate(0deg);
}

.painel-secao[data-recolhido] {
  flex: 0 0 auto !important;
  overflow: hidden;
}

.painel-secao[data-recolhido] .conteudo-secao {
  display: none;
}

.painel-secao[data-recolhido] .cabecalho-secao {
  padding-bottom: 0;
}

.conteudo-secao {
  min-height: 0;
}

.marca-recolhido {
  margin-left: auto;
  font-size: 10px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--cor-texto-fraco);
}

.marca-recolhido:empty {
  display: none;
}

.topbar-direita .botao-secundario {
  margin-left: 0;
}

/* --- card expandido sobre o grafo ------------------------------------ */

.camada-cards {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.card-expandido {
  position: absolute;
  z-index: 3;
  width: 320px;
  max-height: 340px;
  overflow-y: auto;
  padding: 10px 12px 12px;
  border: 1px solid var(--cor-nativo);
  border-radius: var(--raio);
  background: var(--cor-fundo-painel);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  pointer-events: auto;
}

.card-expandido-titulo {
  margin-bottom: 8px;
  font-family: var(--fonte-mono);
  font-size: 12px;
  font-weight: 600;
}

.linha-campo {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr) auto;
  gap: 6px;
  align-items: start;
  padding: 4px 0;
  border-top: 1px solid var(--cor-borda);
  font-size: 11px;
}

.linha-campo-nome {
  font-family: var(--fonte-mono);
  color: var(--cor-texto-secundario);
  overflow-wrap: anywhere;
}

.linha-campo-valor {
  overflow-wrap: anywhere;
  color: var(--cor-texto);
}

.card-expandido .botao-secundario {
  margin: 8px 0 0;
}

.trabalho-atual {
  margin-left: 10px;
  padding: 2px 8px;
  border-radius: var(--raio-pequeno);
  border: 1px solid var(--cor-borda-forte);
  background: var(--cor-fundo-elevado);
  font-family: var(--fonte-mono);
  font-size: 10px;
  color: var(--cor-texto-secundario);
}

.trabalho-novo {
  border-color: var(--cor-nativo);
  color: var(--cor-texto);
}

.trabalho-vazio {
  border-style: dashed;
  color: var(--cor-texto-fraco);
}
