/* App do lojista. Carrega DEPOIS de /style.css e reusa os tokens de cor dele — é o
   mesmo produto, e paleta duplicada divergiria no primeiro ajuste de marca.

   O QUE GUIA ESTE LAYOUT: o garagista não usa isto sentado numa mesa. Ele usa no
   pátio, no celular, com uma mão, olhando o carro. Então: alvos grandes, foto antes
   de texto, e a informação que ele procura ("está no ar?", "falta conferir algo?")
   visível sem abrir nada. */

:root {
  --raio: 12px;
  --raio-g: 16px;
  --atencao: #f0b354;
  --atencao-bg: #2a2115;
  --atencao-linha: #5c4626;
}

.app-body { display: flex; flex-direction: column; min-height: 100vh; }
.app-main { flex: 1; width: min(1120px, 92vw); margin: 0 auto; padding: 32px 0 80px; }
.hidden { display: none !important; }

/* ====================================================== cabeçalho de página */
.topo-pagina { display: flex; gap: 20px; align-items: end; justify-content: space-between;
               flex-wrap: wrap; margin: 0 0 24px; }
.topo-pagina h1 { margin: 0 0 4px; font-size: clamp(24px, 3.4vw, 32px);
                  letter-spacing: -.025em; }
.topo-pagina .muted { margin: 0; font-size: 14px; }
.topo-acoes-pagina { display: flex; gap: 10px; flex-wrap: wrap; }
.topo-acoes-pagina .btn, .topo-acoes-pagina .btn-ghost { border: 0; cursor: pointer; font: inherit; }
.topo-acoes-pagina .btn-ghost { border: 1px solid var(--linha); }

/* ================================================================== resumo */
/* Três números, não um dashboard. O que o lojista precisa saber ao abrir é quantos
   tem, quantos estão rendendo, e se algo o espera.

   ⚠️ E AGORA ELES FILTRAM. Eram `<div>` inertes, e a barra lateral repetia a MESMA
   contagem em botões miúdos — dois lugares para o mesmo número, e o bonito era o que
   não fazia nada. Quem batia o olho em "2 a conferir" e queria ver aqueles dois carros
   não tinha onde tocar. São `<button>` com `aria-pressed`, e o estado marcado é a única
   fonte de verdade sobre qual recorte está na tela. */
.resumo { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 20px; }
.pil { display: flex; align-items: baseline; gap: 7px; padding: 10px 16px; cursor: pointer;
       border-radius: 999px; font: inherit; text-align: left;
       border: 1px solid var(--linha); background: var(--bg-2); color: var(--txt);
       transition: border-color .12s, background .12s; }
.pil:hover { border-color: var(--acento); }
.pil b { font-size: 18px; letter-spacing: -.02em; }
.pil span { font-size: 13px; color: var(--txt-2); }
/* Marcada = fundo de acento e borda cheia. É o mesmo par de sinais do `.filtro-op.ativo`
   da barra lateral, para as duas famílias de controle se reconhecerem como controle. */
.pil.ativa { border-color: var(--acento); background: rgba(55, 211, 155, .12); }
.pil.ativa span { color: var(--txt); }
.pil.alerta { border-color: var(--atencao-linha); background: var(--atencao-bg); }
.pil.alerta b, .pil.alerta span { color: var(--atencao); }
.pil.alerta:hover { border-color: var(--atencao); }
.pil.alerta.ativa { background: #3a2d1c; border-color: var(--atencao); }

/* ========================================================= card do veículo */
.grade-veiculos { display: grid; gap: 18px;
                  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }

.cv { display: flex; flex-direction: column; border-radius: var(--raio-g); overflow: hidden;
      border: 1px solid var(--linha); background: var(--bg-2);
      transition: border-color .15s, transform .15s; }
.cv:hover { border-color: #2e3c55; transform: translateY(-2px); }
.cv.vendido { opacity: .72; }

.cv-capa { position: relative; aspect-ratio: 4/3; background: var(--bg); }
.cv-capa img, .cv-capa video { width: 100%; height: 100%; object-fit: cover; display: block; }
.cv-sem-foto { display: grid; place-items: center; height: 100%;
               color: var(--txt-2); font-size: 13px; }
/* Capa que é um QUADRO DO VÍDEO, e não a foto escolhida: escurece um tom. O lojista
   precisa saber, sem clicar, que aquele carro ainda não tem foto no anúncio — a capa é
   o que vai para o WhatsApp, e um frame de vídeo passando por foto escolhida esconde
   trabalho que falta. Ver `previaDoItem` no app.js. */
.cv-capa.so-video video { opacity: .72; }
.cv-capa.so-video::after { content: "quadro do vídeo"; position: absolute; left: 10px;
                           top: 50%; right: 10px; transform: translateY(-50%);
                           text-align: center; font-size: 11px; letter-spacing: .04em;
                           text-transform: uppercase; color: #c3cddd;
                           text-shadow: 0 1px 6px rgba(0,0,0,.9); pointer-events: none; }

.cv-status { position: absolute; top: 10px; left: 10px; padding: 4px 10px;
             border-radius: 999px; font-size: 11px; font-weight: 700;
             letter-spacing: .03em; text-transform: uppercase;
             background: rgba(5,8,14,.78); color: #c3cddd; backdrop-filter: blur(6px); }
.cv-status.ativo { background: var(--acento); color: #05130d; }
.cv-status.vendido { background: #3a4152; color: #dfe6f2; }

.cv-selos { position: absolute; bottom: 10px; left: 10px; display: flex; gap: 5px;
            flex-wrap: wrap; }
.cv-selo { padding: 3px 8px; border-radius: 6px; font-size: 11px;
           background: rgba(5,8,14,.78); color: #c3cddd; backdrop-filter: blur(6px); }
/* O único selo que é PRODUTO e não insumo: o vídeo pronto para mandar no WhatsApp. Os
   outros contam o que existe guardado; este conta o que dá para usar hoje. */
.cv-selo.pronto { background: rgba(55, 211, 155, .92); color: #04140e; font-weight: 600; }

.cv-corpo { padding: 15px 16px 12px; flex: 1; }
.cv-corpo h3 { margin: 0 0 7px; font-size: 16px; line-height: 1.3; letter-spacing: -.01em; }
.cv-linha { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
            margin: 0; font-size: 13px; }
.cv-preco { font-size: 17px; color: var(--acento); letter-spacing: -.01em; }
.cv-nota { margin: 8px 0 0; font-size: 12px; }
/* A única cor de atenção do card: é a única coisa que EXIGE ação antes de o anúncio
   poder ir ao ar. */
.cv-aviso { margin: 9px 0 0; padding: 6px 10px; border-radius: 8px; font-size: 12px;
            background: var(--atencao-bg); border: 1px solid var(--atencao-linha);
            color: var(--atencao); }

.cv-acoes { display: flex; gap: 8px; padding: 0 16px 15px; align-items: center;
            flex-wrap: wrap; }
.cv-acoes .btn, .cv-acoes .btn-ghost { border: 0; cursor: pointer; font: inherit;
                                       text-decoration: none; }
.cv-acoes .btn-ghost { border: 1px solid var(--linha); }

/* Ações de ÍCONE, na ponta direita: QR e lixeira. Com "QR" em botão de rótulo, as
   quatro ações não cabiam nos 268px do card e quebravam em duas linhas — e a segunda
   linha juntava "QR" (inofensivo) com a lixeira (definitiva) na mesma altura, que é
   como o polegar erra. Mesma silhueta quadrada, cores diferentes: a lixeira é a única
   que fica vermelha ao encostar. */
.cv-icone { display: grid; place-items: center; height: 36px; min-width: 36px; padding: 0 9px;
            flex: none; border-radius: 9px; cursor: pointer; font: inherit; font-size: 12px;
            font-weight: 600; letter-spacing: .04em; border: 1px solid var(--linha);
            background: none; color: var(--txt-2); }
.cv-icone:hover { border-color: var(--acento); color: var(--txt); }

/* ------------------------------------------- convite no fim da grade */
/* Com um veículo só, a grade deixava um card de 268px sozinho ao lado de mais de mil
   pixels de nada — e vazio de layout parece defeito, não espaço livre. Aqui o vazio
   passa a dizer o que fazer com ele. Tracejado e sem fundo porque NÃO é mercadoria:
   os cards de verdade são caixas cheias e elevadas; este é um contorno. */
.cv-novo { display: flex; flex-direction: column; align-items: center; justify-content: center;
           gap: 6px; min-height: 220px; padding: 24px 20px; cursor: pointer; font: inherit;
           text-align: center; border-radius: var(--raio-g); color: var(--txt-2);
           border: 1px dashed var(--linha); background: none;
           transition: border-color .15s, color .15s, background .15s; }
.cv-novo:hover { border-color: var(--acento); color: var(--txt);
                 background: rgba(55, 211, 155, .05); }
.cv-novo b { font-size: 15px; color: var(--txt); }
.cv-novo .muted { font-size: 12.5px; line-height: 1.45; max-width: 24ch; }
.cv-novo-mais { display: grid; place-items: center; width: 40px; height: 40px;
                border-radius: 50%; font-size: 22px; line-height: 1;
                background: var(--linha); color: var(--txt-2); }
.cv-novo:hover .cv-novo-mais { background: var(--acento); color: #04140e; }

.vazio { text-align: center; padding: 54px 28px; }
.vazio h2 { margin: 0 0 8px; font-size: 21px; }
.vazio p { max-width: 46ch; margin: 0 auto 22px; }
.vazio .btn { border: 0; cursor: pointer; font: inherit; }

/* ============================================= confirmação da ficha pela IA */
/* O bloco mais importante do app. Fica no TOPO da ficha, antes de vídeo e fotos,
   porque é o que bloqueia a publicação — e porque a promessa dos Termos ("nenhum
   anúncio é publicado sem que você revise cada campo") só é verdade se estiver
   difícil de ignorar. */
.conf { border-radius: var(--raio-g); padding: 20px; margin: 0 0 26px;
        border: 1px solid var(--linha); background: var(--bg-2); }
.conf.pendente { border-color: var(--atencao-linha); background: var(--atencao-bg); }
.conf.ok { border-color: #1f5340; }
.conf-topo { display: flex; gap: 16px; align-items: start; justify-content: space-between;
             flex-wrap: wrap; }
.conf-topo h2 { margin: 0 0 5px; font-size: 18px; letter-spacing: -.01em; }
.conf.pendente .conf-topo h2 { color: var(--atencao); }
.conf.ok .conf-topo h2 { color: #8ce3c0; }
.conf-topo .muted { margin: 0; font-size: 14px; max-width: 62ch; }
.conf-topo .btn { border: 0; cursor: pointer; font: inherit; white-space: nowrap; }

.conf-lista { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 8px; }
.conf-lista li { display: flex; gap: 14px; align-items: center; justify-content: space-between;
                 flex-wrap: wrap; padding: 12px 14px; border-radius: var(--raio);
                 background: var(--bg); border: 1px solid var(--linha); }
.conf-campo { display: grid; gap: 2px; min-width: 0; }
.conf-campo .muted { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
.conf-campo b { font-size: 15px; word-break: break-word; }
.conf-acoes { display: flex; gap: 7px; flex: none; }
.conf-acoes .btn, .conf-acoes .btn-ghost { border: 0; cursor: pointer; font: inherit; }
.conf-acoes .btn-ghost { border: 1px solid var(--linha); }
.conf-acoes button:disabled { opacity: .5; cursor: default; }

.conf-aprovados { margin: 16px 0 0; font-size: 14px; }
.conf-aprovados summary { cursor: pointer; color: var(--txt-2); }
.conf-aprovados ul { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 6px; }
.conf-aprovados li { display: flex; gap: 10px; justify-content: space-between;
                     padding: 9px 12px; border-radius: 9px; background: var(--bg); }
.conf-aprovados .muted { font-size: 13px; }

/* ================================================================ cartões */
.card { background: var(--bg-2); border: 1px solid var(--linha);
        border-radius: var(--raio-g); padding: 24px; }
.app-main > .card { width: 100%; }
.estreito { width: min(480px, 100%); margin: 24px auto 0; }
.estreito h1 { margin: 0 0 8px; font-size: clamp(22px, 3.2vw, 27px); letter-spacing: -.02em; }
.estreito > .muted { margin: 0 0 22px; }

/* ============================================================= formulários */
.lbl { display: block; margin: 0 0 6px; font-size: 13px; color: var(--txt-2); }
.estreito .lbl { margin-top: 16px; }

input[type="email"], input[type="password"], input[type="text"],
input[type="tel"], input[type="number"], select, textarea {
  width: 100%; padding: 12px 14px; border-radius: var(--raio);
  border: 1px solid var(--linha); background: var(--bg);
  color: var(--txt); font: inherit; font-size: 15px;
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--acento); outline-offset: 1px; border-color: var(--acento);
}
input:disabled { opacity: .55; }
textarea { resize: vertical; }

/* Alvo do "Corrigir" da confirmação: pisca uma vez para o olho achar o campo depois
   da rolagem. Sem isso, o foco muda e nada indica onde ele foi. */
.piscar { animation: piscar 1.6s ease-out; }
@keyframes piscar {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  15%, 55% { box-shadow: 0 0 0 3px rgba(240,179,84,.45); }
}

/* Prefixo/sufixo grudado no campo (R$ … km). O símbolo dentro do input tira a dúvida
   de "escrevo o R$?", e o "km" evita ler 48.000 como preço. */
.campo-com-prefixo { display: flex; align-items: stretch; border-radius: var(--raio);
                     border: 1px solid var(--linha); background: var(--bg); overflow: hidden; }
.campo-com-prefixo:focus-within { outline: 2px solid var(--acento); outline-offset: 1px;
                                  border-color: var(--acento); }
.campo-com-prefixo span { display: grid; place-items: center; padding: 0 13px;
                          font-size: 14px; color: var(--txt-2); background: var(--bg-2); }
.campo-com-prefixo span:first-child { border-right: 1px solid var(--linha); }
.campo-com-prefixo .sufixo { border-left: 1px solid var(--linha); border-right: 0; }
.campo-com-prefixo input { border: 0; border-radius: 0; background: transparent; min-width: 0; }
.campo-com-prefixo input:focus-visible { outline: none; }

.campo-link { display: flex; align-items: stretch; border-radius: var(--raio);
              border: 1px solid var(--linha); background: var(--bg); overflow: hidden; }
.campo-link:focus-within { outline: 2px solid var(--acento); outline-offset: 1px; }
.campo-link span { display: grid; place-items: center; padding: 0 6px 0 13px;
                   color: var(--txt-2); font-size: 14px; white-space: nowrap;
                   border-right: 1px solid var(--linha); background: var(--bg-2); }
.campo-link input { border: 0; border-radius: 0; background: transparent; flex: 1; min-width: 0; }
.campo-link input:focus-visible { outline: none; }

form .btn { width: 100%; margin-top: 22px; border: 0; cursor: pointer; font: inherit; }
form .btn:disabled { opacity: .6; cursor: default; }
.cf-turnstile { margin-top: 18px; }
.alternar { margin: 18px 0 0; font-size: 14px; }

.aceite { display: flex; gap: 10px; align-items: start; margin: 18px 0 0;
          font-size: 14px; color: var(--txt-2); cursor: pointer; }
.aceite input { width: 18px; height: 18px; margin: 2px 0 0; flex: none;
                accent-color: var(--acento); cursor: pointer; }
.aceite a { text-decoration: underline; }

/* Duas colunas a partir de 620px. `.largo` atravessa — opcionais e observações são
   texto corrido e ficariam apertados em metade da largura. */
/* `min-width: 0` não é detalhe: item de grid tem largura mínima automática igual ao
   conteúdo, e um valor longo (lista de opcionais) estouraria a coluna em vez de
   quebrar. É a causa clássica de layout de grid "vazando" para fora da tela. */
.field { min-width: 0; }

.ficha-grid { display: grid; gap: 16px 20px; grid-template-columns: 1fr; margin-top: 20px; }
@media (min-width: 620px) {
  .ficha-grid { grid-template-columns: 1fr 1fr; }
  .ficha-grid .largo { grid-column: 1 / -1; }
}

.selo-ia { display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
           font-size: 10px; font-weight: 700; letter-spacing: .04em;
           background: #2b3a52; color: #9fc4ff; cursor: help; vertical-align: middle; }

/* ================================================================== seções */
.tpl-sec { margin: 30px 0 8px; font-size: 12px; letter-spacing: .08em;
           text-transform: uppercase; color: var(--txt-2);
           padding-top: 22px; border-top: 1px solid var(--linha); }
.acoes { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 20px; }
.acoes .btn, .acoes .btn-ghost { border: 0; cursor: pointer; font: inherit; }
.acoes .btn-ghost { border: 1px solid var(--linha); }
.acoes button:disabled { opacity: .55; cursor: default; }
label.btn-ghost { cursor: pointer; }

/* ================================================================== opções */
.opcoes { display: grid; gap: 12px; }
.opcao { display: grid; gap: 4px; justify-items: start; text-align: left; padding: 18px;
         border-radius: var(--raio); cursor: pointer; font: inherit;
         border: 1px solid var(--linha); background: var(--bg); color: var(--txt);
         transition: border-color .15s, background .15s; }
.opcao:hover:not(:disabled) { border-color: var(--acento); background: #172031; }
.opcao:disabled { opacity: .5; cursor: default; }
.opcao b { font-size: 16px; }
.opcao .muted { font-size: 14px; }

/* =================================================================== fotos */
.fotos { display: grid; gap: 10px; margin: 4px 0 16px;
         grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); }
.foto { position: relative; margin: 0; border-radius: var(--raio); overflow: hidden;
        border: 1px solid var(--linha); background: var(--bg); aspect-ratio: 4/3; }
.foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.foto.capa { border-color: var(--acento); }
.foto figcaption { position: absolute; left: 6px; bottom: 6px; padding: 2px 8px;
                   border-radius: 999px; font-size: 11px; font-weight: 600;
                   background: var(--acento); color: #05130d; }
.foto-acoes { position: absolute; top: 6px; right: 6px; display: flex; gap: 4px; }
.foto-acoes button { width: 27px; height: 27px; border-radius: 8px; cursor: pointer;
                     border: 0; font-size: 13px; line-height: 1;
                     background: rgba(5,8,14,.75); color: #fff; }
.foto-acoes button:hover { background: rgba(5,8,14,.95); }

/* ======================================================= textos do anúncio */
.tabs-canal { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 12px; }
.tab-canal { padding: 7px 13px; border-radius: 999px; cursor: pointer; font: inherit;
             font-size: 13px; border: 1px solid var(--linha);
             background: var(--bg); color: var(--txt-2); }
.tab-canal:hover { border-color: var(--acento); }
.tab-canal.ativa { background: var(--acento); border-color: var(--acento);
                   color: #05130d; font-weight: 600; }
.texto-canal { display: grid; gap: 10px; justify-items: start; }
/* `readonly` e não `disabled`: o texto continua selecionável, e é isso que salva o
   caso em que a área de transferência é negada pelo navegador. */
.texto-canal textarea { line-height: 1.55; font-size: 14px; }
.texto-canal .btn-ghost { border: 1px solid var(--linha); cursor: pointer; font: inherit; }

/* ================================================================== avisos */
.msg { margin: 16px 0 0; padding: 11px 14px; border-radius: var(--raio); font-size: 14px; }
.msg.err { background: #2a1417; border: 1px solid #5c2731; color: #ffb3bd; }
.msg.ok  { background: #10241c; border: 1px solid #1f5340; color: #8ce3c0; }
.msg-foto { margin: 10px 0 0; font-size: 13px; min-height: 1em; }

.analise { margin: 0 0 12px; padding: 12px 15px; border-radius: var(--raio); font-size: 14px;
           border: 1px solid var(--linha); background: var(--bg); }
.analise .muted { display: block; font-size: 13px; margin-top: 4px; }
.analise.processando { border-color: #3a4a6b; color: #9fc4ff; }
.analise.pronta { border-color: #1f5340; color: #8ce3c0; }
.analise.erro { border-color: #5c2731; color: #ffb3bd; }

.endereco-publico { margin: 0 0 6px; padding: 12px 14px; border-radius: var(--raio);
                    background: var(--bg); border: 1px solid var(--linha); font-size: 14px; }
.endereco-publico a { font-weight: 600; }

.lista-topo { display: flex; gap: 16px; align-items: start; justify-content: space-between;
              flex-wrap: wrap; margin-bottom: 20px; }
.lista-topo h1 { margin: 0 0 4px; }
.lista-topo .btn, .lista-topo .btn-ghost { border: 0; cursor: pointer; font: inherit;
                                           white-space: nowrap; }
.lista-topo .btn-ghost { border: 1px solid var(--linha); }

.rodape-nota { margin: 34px 0 0; font-size: 13px; text-align: center; }
.diag-saida { margin: 12px 0 0; padding: 14px; border-radius: var(--raio); max-height: 46vh;
              overflow: auto; background: var(--bg-2); border: 1px solid var(--linha);
              color: var(--txt-2); font-size: 12px; line-height: 1.5;
              font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
              white-space: pre-wrap; word-break: break-word; }

/* ==================================================== IA em destaque (passo 1) */
/* O vídeo é o PRIMEIRO passo porque é o caminho que o produto quer que o lojista
   tome. Antes de o assistente existir, este bloco vivia no meio de uma página com
   sete seções empilhadas, e o lojista digitava 13 campos à mão sem saber que não
   precisava — o valor inteiro do produto ficava invisível. Hoje a ordem já resolve
   isso; o tratamento visual continua porque o passo 1 é também a promessa da marca.
   (Era `.ia-hero`, que embrulhava a seção toda; agora o painel é quem embrulha.) */
.passo-painel[data-passo="video"] .ia-cab {
  padding: 18px; border-radius: var(--raio-g); border: 1px solid #1d4b3a;
  background: linear-gradient(180deg, rgba(55,211,155,.07), rgba(55,211,155,.02));
}

.ia-cab { display: flex; gap: 14px; align-items: start; }
.ia-cab h2 { margin: 0 0 5px; font-size: clamp(18px, 2.3vw, 22px); letter-spacing: -.02em; }
.ia-cab .muted { margin: 0; font-size: 14px; line-height: 1.55; }
.ia-eti { flex: none; display: grid; place-items: center; width: 38px; height: 38px;
          border-radius: 11px; font-size: 12px; font-weight: 800; letter-spacing: .04em;
          color: #04140e; background: var(--acento); }

/* linha do vídeo */
.ia-video { display: flex; gap: 14px; align-items: center; justify-content: space-between;
            flex-wrap: wrap; margin: 18px 0 0; padding: 14px 16px; border-radius: var(--raio);
            border: 1px dashed #2e4a5f; background: rgba(5,8,14,.35); }
.ia-video.tem-video { border-style: solid; border-color: #1f5340; }
.ia-video-txt { display: grid; gap: 2px; }
.ia-video-txt b { font-size: 15px; }
.ia-video-txt .muted { font-size: 13px; }
.ia-video label { cursor: pointer; }
.ia-video label.btn-ghost { border: 1px solid var(--linha); }

/* opção das fotos */
.ia-opt { display: flex; gap: 16px; align-items: start; justify-content: space-between;
          flex-wrap: wrap; margin: 12px 0 0; padding: 14px 16px; border-radius: var(--raio);
          border: 1px solid var(--linha); background: rgba(5,8,14,.35); }
.ia-chk { display: flex; gap: 11px; align-items: start; cursor: pointer; flex: 1 1 300px; }
.ia-chk input { width: 19px; height: 19px; margin: 1px 0 0; flex: none;
                accent-color: var(--acento); cursor: pointer; }
.ia-chk span { display: grid; gap: 3px; }
.ia-chk b { font-size: 15px; }
.ia-chk em { font-style: normal; font-size: 13px; line-height: 1.5; }

/* Botões e não <select>: são quatro opções, e o dedo acerta um alvo de 44px. Um
   select no celular abre roleta nativa para escolher entre quatro números. */
.ia-qtd { display: flex; gap: 6px; flex: none; }
.ia-qtd button { width: 44px; height: 44px; border-radius: var(--raio); cursor: pointer;
                 font: inherit; font-weight: 700; color: var(--txt-2);
                 border: 1px solid var(--linha); background: var(--bg-2); }
.ia-qtd button:hover { border-color: var(--acento); color: var(--txt); }
.ia-qtd button.escolhida { background: var(--acento); border-color: var(--acento);
                           color: #04140e; }
.ia-qtd.desligada { opacity: .4; pointer-events: none; }

.btn-ia { font-size: 16px; padding: 13px 26px; }

/* etapas */
.ia-etapas { list-style: none; display: grid; gap: 8px; margin: 16px 0 0; padding: 0;
             grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.ia-etapa { display: flex; gap: 10px; align-items: start; padding: 11px 13px;
            border-radius: var(--raio); border: 1px solid var(--linha);
            background: rgba(5,8,14,.4); }
.ia-etapa span:last-child { display: grid; gap: 2px; min-width: 0; }
.ia-etapa b { font-size: 14px; }
.ia-etapa em { font-style: normal; font-size: 12.5px; color: var(--txt-2); line-height: 1.45; }
.ia-ic { flex: none; display: grid; place-items: center; width: 22px; height: 22px;
         border-radius: 50%; font-size: 12px; font-weight: 700;
         border: 1px solid var(--linha); color: var(--txt-2); }
.ia-etapa.rodando { border-color: #3a4a6b; }
.ia-etapa.rodando .ia-ic { border-color: #3a4a6b; color: #9fc4ff;
                           animation: gira 1.4s linear infinite; }
.ia-etapa.pronta { border-color: #1f5340; }
.ia-etapa.pronta .ia-ic { border-color: #1f5340; color: #8ce3c0; }
.ia-etapa.falhou { border-color: #5c2731; }
.ia-etapa.falhou .ia-ic { border-color: #5c2731; color: #ffb3bd; }
@keyframes gira { to { transform: rotate(360deg); } }

/* ============================================ lote de fotos vindo da IA */
/* Amarelo de atenção, e não verde: são CANDIDATAS. O verde diria "pronto", e o
   lojista fecharia a tela achando que as fotos já estão no anúncio — quando o que
   falta é justamente ele escolher. */
.ia-lote { margin: 0 0 18px; padding: 16px; border-radius: var(--raio-g);
           border: 1px solid var(--atencao-linha); background: var(--atencao-bg); }
.ia-lote-cab { display: flex; gap: 14px; align-items: start; justify-content: space-between;
               flex-wrap: wrap; margin: 0 0 14px; }
.ia-lote-cab b { font-size: 15px; color: var(--atencao); }
.ia-lote-cab .muted { margin: 3px 0 0; font-size: 13px; max-width: 46ch; }
.ia-lote-acoes { display: flex; gap: 8px; flex-wrap: wrap; }
.ia-lote-acoes .btn, .ia-lote-acoes .btn-ghost { border: 0; cursor: pointer; font: inherit; }
.ia-lote-acoes .btn-ghost { border: 1px solid var(--atencao-linha); }
.ia-lote-acoes button:disabled { opacity: .5; cursor: default; }

.grade-ia { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
/* A figura inteira é o alvo: isto é usado no pátio, com o polegar, e um quadradinho
   de 27px numa grade de 10 fotos erra mais do que acerta. */
.foto.cand { cursor: pointer; opacity: .62; border-color: transparent;
             transition: opacity .12s, border-color .12s; }
.foto.cand:hover { opacity: .85; }
.foto.cand.marcada { opacity: 1; border-color: var(--acento); }
.cand-marca { position: absolute; top: 6px; right: 6px; display: grid; place-items: center;
              width: 25px; height: 25px; border-radius: 50%; font-size: 13px; font-weight: 700;
              color: #04140e; background: var(--acento); opacity: 0; transform: scale(.6);
              transition: opacity .12s, transform .12s; }
.foto.cand.marcada .cand-marca { opacity: 1; transform: scale(1); }

/* Selo de "a IA está trabalhando" no card do estoque. O lojista fecha a tela do
   veículo e vai cadastrar o próximo — sem isto, ele não tem como saber de qual carro
   a análise ainda está rodando. */
.cv-selo.gerando { border-color: #3a4a6b; color: #9fc4ff; }

/* ===================================================== imagem que não carregou */
/* Ícone de imagem quebrada não diz nada, e o lojista conclui que o sistema perdeu as
   fotos dele. A causa quase sempre é a URL pública do R2 (domínio no bucket errado,
   acesso público desligado), e é isso que a mensagem precisa insinuar. */
.img-quebrada { display: grid; place-items: center; text-align: center; padding: 10px;
                background: repeating-linear-gradient(45deg, #141c2a, #141c2a 8px,
                            #101725 8px, #101725 16px); }
.img-quebrada::after { content: "imagem não carregou — confira o Diagnóstico técnico";
                       font-size: 11px; line-height: 1.4; color: var(--txt-2); }
.foto.img-quebrada { aspect-ratio: 4/3; }

/* ============================================================ peças de vídeo */
.pecas-grade { display: grid; gap: 16px; margin: 4px 0 0;
               grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }

.peca { display: flex; flex-direction: column; border-radius: var(--raio-g);
        overflow: hidden; border: 1px solid var(--linha); background: var(--bg-2); }
.peca.pronta { border-color: #1f5340; }

/* A proporção do quadro é a do formato, e isso é o ponto: o lojista escolhe pelo
   FORMATO, e três molduras idênticas não deixariam ele ver qual é qual sem ler. */
.peca-tela { background: var(--bg); display: grid; place-items: center; }
.peca-tela.r9x16 { aspect-ratio: 9/16; }
.peca-tela.r1x1  { aspect-ratio: 1/1; }
.peca-tela.r16x9 { aspect-ratio: 16/9; }
.peca-tela video { width: 100%; height: 100%; object-fit: contain; display: block;
                   background: #000; }
.peca-nada { font-size: 12px; color: var(--txt-2); }

/* ⚠️ O QUADRO NÃO PODE FICAR VAZIO ENQUANTO NÃO HÁ VÍDEO PRONTO, que é o estado em
   que esta tela passa a maior parte do tempo (o render leva minutos). A prévia é a
   capa do veículo ou o próprio vídeo enviado, esmaecido, com o rótulo por cima — o
   lojista vê o carro dele e entende que aquilo é o lugar onde o vídeo vai aparecer.
   Ver `montarPecas` no `app.js`. */
.peca-previa { position: relative; width: 100%; height: 100%;
               display: grid; place-items: center; overflow: hidden; }
.peca-previa img, .peca-previa video { position: absolute; inset: 0; width: 100%;
                                       height: 100%; object-fit: cover; display: block;
                                       opacity: .32; pointer-events: none; }
.peca-previa span { position: relative; z-index: 1; padding: 5px 12px; border-radius: 999px;
                    font-size: 12px; color: var(--txt); background: rgba(5,8,14,.72); }

.peca-pe { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
           padding: 11px 13px 0; }
.peca-pe b { font-size: 14px; }
.peca-pe .muted { font-size: 12px; }
.peca-acoes { display: flex; gap: 8px; flex-wrap: wrap; padding: 10px 13px 13px; }
.peca-acoes .btn-ghost { border: 1px solid var(--linha); cursor: pointer; font: inherit;
                         text-decoration: none; }

/* Botão de escolha com rótulo por extenso (áudio da peça). Os de quantidade são
   quadrados porque cabem um número; estes precisam da frase inteira — "Com áudio e
   legenda" e "Sem áudio" são a diferença entre duas peças diferentes, e abreviar
   obrigaria o lojista a descobrir na peça pronta. */
.ia-qtd button.largo { width: auto; padding: 0 16px; font-weight: 600; font-size: 14px; }

/* Chamada para a peça, dentro do painel de conferência. Só aparece no instante em que
   o portão abre — antes disso o servidor recusaria, e descobrir isso descendo a
   página e levando um 409 gastaria a paciência do lojista com uma regra que o produto
   já conhecia. */
.conf-emenda { display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
               margin: 12px 0 0; padding: 12px 14px; border-radius: var(--raio);
               border: 1px solid #1f5340; background: rgba(55,211,155,.06);
               font-size: 14px; line-height: 1.5; }
.conf-emenda .btn { border: 0; cursor: pointer; font: inherit; white-space: nowrap; }

/* ================================================================= combobox */
/* Substitui o <datalist>. 33 marcas num datalist abrem uma lista maior que a tela do
   celular, sem busca por digitação em boa parte dos navegadores e sem rolagem decente
   em nenhum. Aqui filtra sem acento enquanto se digita — e o campo continua aceitando
   valor livre, que é o contrato dele. */
.combo { position: relative; display: flex; align-items: stretch;
         border: 1px solid var(--linha); border-radius: var(--raio);
         background: var(--bg-2); min-width: 0; }
.combo:focus-within { outline: 2px solid var(--acento); outline-offset: 1px; }
.combo input { flex: 1; min-width: 0; border: 0; border-radius: 0; background: transparent; }
.combo input:focus-visible { outline: none; }
.combo-seta { flex: none; width: 38px; border: 0; border-left: 1px solid var(--linha);
              background: transparent; color: var(--txt-2); cursor: pointer;
              font-size: 13px; border-radius: 0 var(--raio) var(--raio) 0; }
.combo-seta:hover { color: var(--txt); }

.combo-lista { position: absolute; z-index: 40; top: calc(100% + 5px); left: 0; right: 0;
               max-height: 260px; overflow-y: auto; padding: 5px;
               border: 1px solid var(--linha); border-radius: var(--raio);
               background: #101725; box-shadow: 0 18px 44px rgba(0,0,0,.55); }
.combo-item { display: block; width: 100%; text-align: left; padding: 9px 11px;
              border: 0; border-radius: 8px; background: transparent; color: var(--txt);
              font: inherit; font-size: 14px; cursor: pointer; }
.combo-item:hover, .combo-item.ativo { background: #1b2739; }
.combo-vazio { margin: 0; padding: 10px 11px; font-size: 13px; color: var(--txt-2);
               line-height: 1.5; }

/* =============================================================== chips */
/* Grade de seleção. O texto separado por vírgula exigia que o lojista soubesse
   escrever "Freios ABS com EBD" — ele digitava "abs", e o anúncio saía com um item
   que nenhum comprador procura. Cor cheia = selecionado, sem depender de checkbox
   miúdo que o polegar erra. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
         padding: 12px; border: 1px solid var(--linha); border-radius: var(--raio);
         background: rgba(5,8,14,.3); }
.chip { padding: 8px 14px; border-radius: 999px; cursor: pointer; font: inherit;
        font-size: 13.5px; color: var(--txt-2); background: var(--bg-2);
        border: 1px solid var(--linha); transition: background .12s, color .12s,
        border-color .12s; }
.chip:hover { border-color: var(--acento); color: var(--txt); }
.chip.ativa { background: var(--acento); border-color: var(--acento); color: #04140e;
              font-weight: 600; }
/* Os diferenciais são argumento de venda, não item de série: laranja para não
   competirem visualmente com a lista de itens, que é longa e verde. */
.chips.destaque .chip.ativa { background: var(--atencao); border-color: var(--atencao);
                              color: #1a1206; }
.chip-novo { display: flex; gap: 6px; align-items: center; flex: 1 1 210px; min-width: 170px; }
.chip-novo input { flex: 1; min-width: 0; padding: 7px 11px; font-size: 13.5px; }
.chip-novo button { padding: 7px 13px; border-radius: 999px; cursor: pointer; font: inherit;
                    font-size: 13px; color: var(--txt-2); background: transparent;
                    border: 1px dashed var(--linha); }
.chip-novo button:hover { border-style: solid; border-color: var(--acento); color: var(--txt); }

/* ========================================================= identidade da loja */
.temas { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 20px; }
.tema-op { display: flex; align-items: center; gap: 9px; padding: 9px 14px 9px 9px;
           border-radius: 999px; cursor: pointer; font: inherit; font-size: 13.5px;
           color: var(--txt-2); background: var(--bg-2);
           border: 1px solid var(--linha); transition: border-color .12s, color .12s; }
.tema-op:hover { border-color: var(--acento); color: var(--txt); }
.tema-op.escolhido { border-color: var(--acento); color: var(--txt); font-weight: 600; }
/* As bolinhas leem as variáveis do PRÓPRIO tema (o `data-tema` está nelas), então
   nenhuma cor é repetida aqui — vêm todas de /temas.css. */
.tema-bolas { display: flex; }
.tema-bolas i { width: 18px; height: 18px; border-radius: 50%; display: block;
                box-shadow: 0 0 0 1.5px #111826; }
.tema-bolas i + i { margin-left: -6px; }

/* ⚠️ ALTURA IGUAL NOS DOIS SLOTS, e é isso que alinha os botões.
   A versão anterior tinha logo de 96px e capa em `aspect-ratio: 4/1` — numa coluna
   larga a capa passava dos 200px de altura, e como cada fileira de botões segue a sua
   própria caixa, os quatro botões terminavam em quatro linhas diferentes. Fixar a
   MESMA altura resolve na origem, sem precisar empurrar nada com margem. */
.imgs-loja { display: grid; gap: 18px; margin: 0 0 6px;
             grid-template-columns: 132px minmax(240px, 1fr); align-items: start; }
@media (max-width: 620px) { .imgs-loja { grid-template-columns: 1fr; } }
.img-slot { display: grid; gap: 8px; min-width: 0; }
.img-alvo { display: grid; place-items: center; overflow: hidden; background: var(--bg);
            border: 1px dashed var(--linha); color: var(--txt-2); font-size: 12px;
            height: 132px; }
.img-alvo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.img-alvo.redonda { width: 132px; border-radius: 22px; }
.img-alvo.larga { width: 100%; border-radius: var(--raio); }

/* ------------------------------------------------------- ações da imagem */
/* ⚠️ CORES DIFERENTES PORQUE AS AÇÕES SÃO DIFERENTES. Os dois botões eram
   `.btn-ghost` idênticos, lado a lado, e um deles apaga a marca da loja — mesma
   silhueta para "enviar" e "destruir" é como o clique errado acontece. */
.img-acoes { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.bt-enviar, .bt-remover { padding: 9px 16px; border-radius: var(--raio); cursor: pointer;
                          font: inherit; font-size: 13.5px; font-weight: 600;
                          white-space: nowrap; transition: background .12s, border-color .12s; }
.bt-enviar { color: var(--acento); background: rgba(55,211,155,.10);
             border: 1px solid #1f5340; }
.bt-enviar:hover { background: rgba(55,211,155,.18); }
.bt-remover { color: #ffb3bd; background: transparent; border: 1px solid #5c2731; }
.bt-remover:hover { background: #2a1417; }

/* ------------------------------------------------------------------ prévia */
/* Duas molduras porque o catálogo é aberto nos dois, e o que quebra é diferente em
   cada um: no computador a capa fica larga e baixa; no celular ela vira quase quadrada
   e a logo cobre metade dela. Mostrar só um dos dois esconde metade dos problemas. */
.previas { display: flex; gap: 20px; flex-wrap: wrap; margin: 18px 0 0; }
.previa-caixa { display: grid; gap: 7px; }
.previa-rot { font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
              color: var(--txt-2); }
.previa { overflow: hidden; border-radius: 12px; border: 1px solid var(--linha);
          background: var(--bg); color: var(--txt); }
.previa.desktop { width: min(480px, 100%); }
.previa.celular { width: 232px; }

.pv-capa { height: 64px; background: var(--bg-2); }
.pv-capa.vazia { background: repeating-linear-gradient(45deg, var(--bg-2), var(--bg-2) 7px,
                 var(--bg) 7px, var(--bg) 14px); }
.pv-capa img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pv-linha { display: flex; align-items: center; gap: 9px; padding: 0 12px 10px; }
.pv-logo { width: 34px; height: 34px; border-radius: 9px; object-fit: cover;
           margin-top: -14px; border: 2px solid var(--bg); background: var(--bg-2);
           display: block; flex: none; }
.pv-logo.vazia { background: var(--linha); }
.pv-linha b { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis;
              white-space: nowrap; }
.pv-grade { display: grid; gap: 9px; padding: 0 13px 14px;
            grid-template-columns: repeat(3, 1fr); }
.previa.celular .pv-grade { grid-template-columns: repeat(2, 1fr); }
.pv-card { border-radius: 9px; border: 1px solid var(--linha); background: var(--bg-2);
           padding: 6px; display: grid; gap: 5px; }
/* ⚠️ A prévia mostra TEXTO, não barras cinzas. Esqueleto responde "o layout é assim",
   que não é a pergunta — a pergunta do lojista é "a cor do preço vai dar para ler no
   meu catálogo?". Com nome e valor escritos, ele compara os temas olhando exatamente
   o que o comprador vai olhar. */
.pv-foto { position: relative; aspect-ratio: 4/3; border-radius: 6px;
           display: grid; place-items: center; color: var(--txt-2); font-size: 11px;
           background: linear-gradient(145deg, var(--linha), var(--bg)); }
.pv-card b { font-size: 10.5px; line-height: 1.25; color: var(--txt);
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-preco { font-size: 12px; font-weight: 700; color: var(--acento); }

/* ============================================== assistente de passos do anúncio */
/* A tela do veículo era uma página só com sete blocos empilhados, e o relato de quem
   usou foi literal: "não sei nem onde clicar". Não faltava instrução — faltava ordem.
   Sete coisas visíveis ao mesmo tempo não têm primeira.

   O desenho aqui tem uma regra que vale por todas: EM CADA PASSO existe UM botão
   cheio (`.btn`), e ele é o que leva adiante. Tudo o mais é `.btn-ghost`. É o que
   permite atravessar o fluxo inteiro sem ler, só seguindo o botão verde. */
.passos { margin: 4px 0 0; }
.passos ol { display: flex; align-items: center; gap: 4px; list-style: none;
             margin: 0; padding: 0; }
/* ⚠️ Os quatro zeros são cinto de segurança, não redundância. `/style.css` também é
   carregado aqui e tinha um `.passos li` com `padding:24px` e borda, da seção
   "1. Grave → 2. Confira" da landing: cada chip virava um cartão de 90px e a tela do
   app rolava de lado no celular, sem erro em lugar nenhum. Lá a regra foi escopada
   para `ol.passos`; isto aqui garante que um nome repetido no futuro não volte a
   sequestrar a barra. */
.passos li { flex: 1 1 0; min-width: 0;
             background: none; border: 0; border-radius: 0; padding: 0; }

/* `min-width: 44px` porque no celular o chip não-ativo é só o número, e 40px fica
   abaixo do alvo de toque de quem usa isto em pé, com uma mão. */
.passo-chip { width: 100%; min-width: 44px; min-height: 44px;
              display: flex; align-items: center; justify-content: center;
              gap: 9px; padding: 10px 8px; border-radius: var(--raio); cursor: pointer;
              font: inherit; font-size: 14px; font-weight: 600; color: var(--txt-2);
              border: 1px solid var(--linha); background: var(--bg);
              transition: border-color .15s, color .15s, background .15s; }
.passo-chip:hover:not(:disabled) { border-color: var(--acento); color: var(--txt); }
.passo-chip .passo-n { flex: none; display: grid; place-items: center;
                       width: 24px; height: 24px; border-radius: 999px; font-size: 13px;
                       font-weight: 700; background: var(--linha); color: var(--txt-2); }
.passo-chip .passo-rot { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.passo-chip.feito { color: var(--txt); border-color: #1f5340; }
.passo-chip.feito .passo-n { background: #1f5340; color: var(--acento); }
.passo-chip.ativo { color: var(--txt); border-color: var(--acento);
                    background: rgba(55, 211, 155, .10); }
.passo-chip.ativo .passo-n { background: var(--acento); color: #04140e; }
/* Travado NÃO é o mesmo que desabilitado por engano: são os passos que precisam de um
   veículo criado para anexar arquivo. O cursor e a opacidade dizem "ainda não", e o
   texto do próprio painel diz por quê — o lojista que clica merece a razão. */
.passo-chip.travado, .passo-chip:disabled { opacity: .45; cursor: not-allowed; }

.passo-conta { margin: 10px 0 0; font-size: 13px; }

/* ⚠️ `!important` porque `.acoes` e outros filhos declaram `display:flex`, e um
   `display` explícito vence o `[hidden]` do agente de usuário. Sem isto, trocar de
   passo não esconderia nada — o sintoma seria a página antiga de volta, inteira. */
.passo-painel[hidden] { display: none !important; }
.passo-painel { margin-top: 22px; }

.passo-h { margin: 0 0 6px; font-size: clamp(19px, 2.6vw, 23px); letter-spacing: -.02em; }
.passo-sub { margin: 0 0 14px; font-size: 14px; line-height: 1.55; }
.passo-nota { margin: 8px 0 0; font-size: 13px; }

/* O que falta para publicar. Cor de atenção e não de erro: não é falha do lojista,
   é trabalho que ainda existe. */
.passo-falta { margin: 0 0 14px; padding: 11px 14px; border-radius: var(--raio);
               font-size: 14px; line-height: 1.5;
               border: 1px solid var(--atencao-linha); background: var(--atencao-bg);
               color: var(--txt); }
.passo-travado { margin: 0; padding: 16px; border-radius: var(--raio); font-size: 14px;
                 border: 1px dashed var(--linha); background: var(--bg);
                 color: var(--txt-2); }
.passo-alt { margin: 14px 0 0; font-size: 14px; }

/* Botão que parece link: usado dentro de frase ("Ir para a ficha"), onde um botão
   cheio quebraria a leitura e um <a href="#"> mexeria na URL. */
.link-btn { border: 0; background: none; padding: 0; font: inherit; font-weight: 600;
            color: var(--acento); cursor: pointer; text-decoration: underline; }

.passo-nav { display: flex; align-items: center; justify-content: space-between;
             gap: 12px; margin: 28px 0 0; padding-top: 20px;
             border-top: 1px solid var(--linha); }
.passo-nav .btn, .passo-nav .btn-ghost { border: 0; cursor: pointer; font: inherit; }
.passo-nav .btn-ghost { border: 1px solid var(--linha); }
.passo-nav button:disabled { opacity: .5; cursor: default; }

/* Enquanto o vídeo sobe, o rótulo do seletor não pode continuar convidando ao
   clique: o upload já está em curso e um segundo arquivo criaria um segundo veículo. */
.ia-video label.ocupado { opacity: .55; pointer-events: none; }

@media (max-width: 640px) {
  /* ⚠️ DUAS FILEIRAS DE TRÊS, TODAS COM NOME. A versão anterior escondia o rótulo de
     todos os passos menos o aberto, para caber seis chips numa linha de 360px — e o
     resultado em tela foi o relato: "um botão com número e a descrição cortada".
     Cinco números sem palavra nenhuma não dizem o que é o passo 4, e o único que
     tinha nome ainda vinha com reticências.

     Empilhar em grade resolve na origem: número em cima, nome embaixo, nome inteiro,
     alvo de 58px. Custa uma fileira de altura, e devolve a única coisa que a barra
     existia para dar — saber o que vem pela frente sem ter que clicar. */
  .passos ol { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
  .passos li { flex: none; }
  .passo-chip { flex-direction: column; gap: 5px; padding: 9px 4px; min-height: 58px;
                font-size: 11.5px; line-height: 1.2; }
  .passo-chip .passo-n { width: 22px; height: 22px; font-size: 12px; }
  .passo-chip .passo-rot { display: block; white-space: normal; text-align: center;
                           overflow: visible; text-overflow: clip; }
  /* ⚠️ O `.passo-nav` DESTE BLOCO SAIU, e não é limpeza: ele tinha `order: -1` no botão
     cheio, uma sobra da época em que os dois botões dividiam a mesma linha e o avanço
     precisava ser puxado para cima. Com a régua empilhada (bloco do fim do arquivo),
     esse `order` invertia a ordem — "avançar" acima de "voltar", exatamente o contrário
     do que aquele bloco documenta. Duas regras para a mesma barra, e a que perdia era
     a que alguém tinha acabado de escrever. */
}

/* ================================================== filtros do estoque (lojista) */
/* Uma loja com 60 carros não acha nada rolando a grade. E o que o LOJISTA procura não
   é o que o comprador procura — ele filtra por "o que ainda me deve trabalho" e "o que
   está no ar", não por marca e preço. Daí dois conjuntos de filtros diferentes, e não
   uma abstração compartilhada que serviria mal aos dois. */
.com-filtros { display: grid; gap: 20px; align-items: start; }
@media (min-width: 900px) {
  .com-filtros { grid-template-columns: 244px minmax(0, 1fr); gap: 26px; }
  /* Gruda ao rolar: com 60 cards, o filtro sumia da tela no primeiro scroll e voltar
     até ele para trocar de marca era rolar a página inteira de volta. */
  .filtros { position: sticky; top: 84px; max-height: calc(100vh - 104px); overflow-y: auto; }
}
.filtros-conteudo { min-width: 0; }

.filtros-cab { display: flex; align-items: center; justify-content: space-between;
               gap: 12px; margin: 0 0 12px; }
.filtros-cab b { font-size: 15px; display: flex; align-items: center; gap: 8px; }
.filtros-n { display: grid; place-items: center; min-width: 20px; height: 20px;
             padding: 0 6px; border-radius: 999px; font-style: normal; font-size: 11px;
             font-weight: 700; background: var(--acento); color: #04140e; }

.filtros-chips { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 16px; }
.filtro-chip { display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
               font: inherit; font-size: 13px; padding: 7px 12px; border-radius: 999px;
               border: 1px solid var(--acento); background: rgba(55, 211, 155, .12);
               color: var(--txt); }
.filtro-chip span[aria-hidden] { color: var(--txt-2); font-size: 15px; line-height: 1; }
.filtro-chip:hover span[aria-hidden] { color: var(--txt); }

.filtro-grupo { padding: 14px 0 0; margin: 0 0 14px; border-top: 1px solid var(--linha); }
.filtro-rot { display: block; margin: 0 0 8px; font-size: 12px; letter-spacing: .07em;
              text-transform: uppercase; color: var(--txt-2); }
.filtro-busca { width: 100%; padding: 11px 13px; border-radius: var(--raio); font: inherit;
                font-size: 15px; border: 1px solid var(--linha); background: var(--bg);
                color: var(--txt); }
.filtro-busca::placeholder { color: var(--txt-2); }

/* Linha inteira clicável, rótulo à esquerda e contagem à direita: é a forma que o
   lojista já conhece de qualquer portal, e o alvo de toque vira a largura da barra. */
.filtro-op { display: flex; align-items: center; justify-content: space-between; gap: 10px;
             width: 100%; min-height: 40px; padding: 9px 11px; margin: 0 0 3px;
             border: 1px solid transparent; border-radius: 9px; cursor: pointer;
             font: inherit; font-size: 14.5px; text-align: left;
             background: none; color: var(--txt-2); }
.filtro-op:hover { background: var(--bg); color: var(--txt); }
.filtro-op.ativo { background: rgba(55, 211, 155, .12); border-color: var(--acento);
                   color: var(--txt); font-weight: 600; }
.filtro-op em { font-style: normal; font-size: 12px; color: var(--txt-2); flex: none; }

.filtros-conta { margin: 0 0 14px; font-size: 14px; }

/* Só para leitor de tela: o "×" do chip é `aria-hidden`, então sem isto o botão de
   remover filtro seria anunciado apenas como o nome do filtro — e quem não vê a tela
   não teria como saber que clicar ali tira, e não aplica. */
.so-leitor { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
             overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* A zona de risco (`.perigo` / `.btn-perigo`) VIVIA AQUI e saiu junto com o botão de
   excluir do último passo — a exclusão hoje é a lixeira do card, em "Meus veículos".
   Ver o comentário no painel `publicar` do `app.js`. Se um dia voltar a existir uma
   ação sem volta numa tela, ela merece cor e caixa próprias de novo. */

/* O `<summary>` é o botão de abrir no celular. Some no desktop, onde a barra fica
   sempre aberta — um botão "Filtros" ao lado de uma lista já visível confunde. */
.filtros-abrir { display: flex; align-items: center; justify-content: space-between;
                 padding: 13px 15px; cursor: pointer; font-weight: 600; font-size: 15px;
                 list-style: none; border: 1px solid var(--linha); border-radius: var(--raio);
                 background: var(--bg-2); color: var(--txt); }
.filtros-abrir::-webkit-details-marker { display: none; }
.filtros-abrir::after { content: "▾"; color: var(--txt-2); }
.filtros-caixa[open] .filtros-abrir { border-radius: var(--raio) var(--raio) 0 0; }
.filtros-corpo { padding: 14px 15px 16px; border: 1px solid var(--linha); border-top: 0;
                 border-radius: 0 0 var(--raio) var(--raio); background: var(--bg-2); }
.filtros-corpo .filtro-grupo:first-of-type { border-top: 0; padding-top: 0; }

@media (min-width: 900px) {
  .filtros-abrir { display: none; }
  /* ⚠️ AQUI ESTAVA A CAUSA DE "NÃO DÁ PRA DIFERENCIAR O QUE É O QUE". Esta regra zerava
     fundo, borda e raio no desktop: a coluna de filtros ficava flutuando no mesmo preto
     da página, e a ÚNICA caixa desenhada da região inteira era a opção ativa, verde e
     com borda — que então lia como se fosse o card do veículo.

     O painel volta a ter corpo, e com o fundo `--bg` de propósito: o card do veículo é
     `--bg-2`, mais claro que a página, elevado. Dar `--bg-2` ao painel repetiria a
     confusão com outra borda. Igual ao fundo e com borda, ele lê como recorte da
     página — a regra que a tela passa a ensinar é CONTEÚDO É ELEVADO, CONTROLE É
     RECUADO. Cor nenhuma nova: só a troca de papel entre dois tokens que já existiam. */
  .filtros-corpo { padding: 16px; border: 1px solid var(--linha); border-top: 1px solid var(--linha);
                   border-radius: var(--raio-g); background: var(--bg); }
  /* No desktop o cabeçalho é o que nomeia a caixa — sem o `<summary>`, que some. */
  .filtros-cab b { font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
                   color: var(--txt-2); }
}

/* Explica um painel curto em vez de escondê-lo: loja com uma marca só não tem o que
   filtrar além da busca, e caixa quase vazia sem motivo é a mesma pergunta de novo
   ("o que é isto?"). Some sozinha quando a segunda marca entrar no estoque. */
.filtro-nota { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--linha);
               font-size: 12.5px; line-height: 1.5; }

/* ============================================== situação do teste / assinatura */
/* Antes disto, os tetos eram cobrados em três endpoints e não apareciam em tela
   nenhuma: o lojista descobria o limite ao tomar um erro no meio de uma publicação.
   Com o teste de 7 dias seria pior — ele acordaria com o catálogo fora do ar sem
   nunca ter lido que havia prazo. */
.situacao { display: flex; align-items: center; justify-content: space-between; gap: 18px;
            flex-wrap: wrap; margin: 0 0 22px; padding: 16px 18px;
            border: 1px solid var(--linha); border-radius: var(--raio-g);
            background: var(--bg-2); }
.situacao > div { display: grid; gap: 6px; min-width: 0; }
.situacao b { font-size: 15.5px; }
.situacao span { font-size: 13.5px; line-height: 1.55; color: var(--txt-2); max-width: 74ch; }
.situacao .btn, .situacao .btn-ghost { flex: none; text-decoration: none; white-space: nowrap; }

/* Tom de atenção só nos dois últimos dias. Banner alarmante desde o primeiro dia vira
   paisagem, e aí não avisa nada quando importa. */
.situacao.atencao { border-color: var(--atencao-linha); background: var(--atencao-bg); }
.situacao.atencao b { color: var(--atencao); }
/* Fora do ar é o único estado em que o produto parou de entregar — merece a cor da
   zona de risco, a mesma do botão de excluir. */
.situacao.fora { border-color: #7d3348; background: #1c1218; }
.situacao.fora b { color: #ff9db4; }

.sit-usos { display: flex; flex-wrap: wrap; gap: 8px; }
.sit-uso { padding: 5px 11px; border-radius: 999px; font-size: 13px;
           border: 1px solid var(--linha); background: var(--bg); color: var(--txt-2); }
.sit-uso b { font-size: 13px; color: var(--txt); }
/* Teto batido: o número que trava a próxima ação não pode ter a mesma cor dos outros. */
.sit-uso.cheio { border-color: var(--atencao-linha); background: var(--atencao-bg); }
.sit-uso.cheio b { color: var(--atencao); }

@media (max-width: 640px) {
  .situacao { flex-direction: column; align-items: stretch; }
  .situacao .btn, .situacao .btn-ghost { text-align: center; }
}

/* Dica sob o campo da ficha. Vem do SCHEMA (`campos[].dica`, migration_040), não de um
   caso especial no front — o formulário inteiro é desenhado pelo schema, e um `if` por
   campo devolveria a ficha para dentro do código, um `if` por vez. */
.campo-dica { display: block; margin: 6px 0 0; font-size: 12.5px; line-height: 1.45;
              color: var(--txt-2); }

/* ==================================================== tela de entrar, enxuta */
/* Era um cartão alto e solto no meio do escuro: título grande, muito respiro entre
   os campos e nada em volta. Numa tela de duas entradas e um botão, o espaço vazio
   não organiza nada — só empurra o botão para baixo da dobra no celular.
   O casco (cabeçalho com Início/Blog e rodapé) vive no `app/index.html`. */
/* ⚠️ `.app-main > .card.estreito` E NÃO `.estreito`. Havia um `.app-main > .card
   { width: 100% }` logo acima que vence `.estreito { width: min(480px,100%) }` por
   especificidade (0,2,0 contra 0,1,0) — então o cartão de login NUNCA respeitou os
   480px e ocupava os 1120px da coluna inteira, esticado de ponta a ponta numa tela
   de dois campos. Precisa ser tão específico quanto a regra que o atropelava. */
.app-main > .card.estreito { width: min(400px, 100%); padding: 26px 24px; margin: 0 auto; }
.estreito h1 { font-size: clamp(20px, 3vw, 24px); margin-bottom: 6px; }
.estreito > .muted { margin: 0 0 16px; font-size: 14px; }
.estreito .lbl { margin-top: 12px; }
.estreito input[type="email"], .estreito input[type="password"] { padding: 11px 13px; }
.estreito .btn { width: 100%; margin-top: 16px; text-align: center; }

/* Centraliza na vertical quando a tela é SÓ o cartão (entrar, onboarding, erro). O
   `:has()` é o que permite fazer isso sem uma classe posta por JS em quatro telas; se
   um navegador não o suportar, o cartão volta a ficar no topo — que é o que ele já
   fazia, não uma tela quebrada. */
.app-main:has(> .estreito) { display: grid; place-items: center; align-content: center;
                             padding: 24px 0 48px; }
.cf-turnstile:not(:empty) { margin-top: 14px; }
.cf-turnstile:empty { margin: 0; }
.alternar { margin: 14px 0 0; }
.aceite { margin: 14px 0 0; }

/* O rodapé do app repete o da landing, mas aqui ele não pode grudar no conteúdo
   quando a tela é curta — `margin-top:auto` empurra para o fim da viewport, que é
   o que o `.app-body` em coluna permite. */
.app-body > .rodape { margin-top: auto; }

/* ------------------------------------------------- lixeira no card do estoque */
/* Separada das demais ações pelo espaçador: é a única do card que não tem volta, e
   encostá-la em "Editar" faria o polegar errar num card de 268px. */
.cv-espaco { flex: 1; }
.cv-lixo { display: grid; place-items: center; width: 36px; height: 36px; flex: none;
           border-radius: 9px; cursor: pointer; border: 1px solid var(--linha);
           background: none; color: var(--txt-2); }
.cv-lixo svg { width: 17px; height: 17px; fill: currentColor; }
.cv-lixo:hover { border-color: #7d3348; background: #2a1620; color: #ff9db4; }
.cv-lixo:disabled, .cv-lixo.ocupado { opacity: .5; cursor: default; }

/* Recusa por PLANO. É a única mensagem do app que pede uma decisão comercial — no
   texto cinza de 13px dos avisos de upload, o lojista conclui que o produto quebrou
   em vez de entender que o teste acabou. */
.plano-bloqueio { display: flex; align-items: center; justify-content: space-between;
                  gap: 16px; flex-wrap: wrap; margin: 14px 0 0; padding: 16px 18px;
                  border-radius: var(--raio); border: 1px solid var(--atencao-linha);
                  background: var(--atencao-bg); }
.plano-bloqueio > div { display: grid; gap: 4px; min-width: 0; }
.plano-bloqueio b { font-size: 15.5px; color: var(--atencao); }
.plano-bloqueio span { font-size: 13.5px; line-height: 1.55; color: var(--txt); max-width: 70ch; }
.plano-bloqueio .btn { flex: none; text-decoration: none; white-space: nowrap; }
@media (max-width: 640px) {
  .plano-bloqueio { flex-direction: column; align-items: stretch; }
  .plano-bloqueio .btn { text-align: center; }
}

/* ------------------------------------------- legenda das ações da confirmação */
/* Cada linha carrega a COR do próprio botão. É o que transforma a leitura em
   reconhecimento: o lojista bate o olho no verde da legenda e acha o verde na linha
   do campo, sem decodificar quarenta palavras de texto corrido. */
.conf-legenda { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 7px; }
.conf-legenda li { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
                   font-size: 13.5px; color: var(--txt-2); }
.conf-legenda span { flex: none; padding: 3px 10px; border-radius: 999px;
                     font-size: 12.5px; font-weight: 600; }
.leg-ok { background: var(--acento); color: #04140e; }
.leg-corrigir { border: 1px solid var(--linha); background: var(--bg); color: var(--txt); }
.leg-ignorar { border: 1px solid #5c4626; background: var(--atencao-bg); color: var(--atencao); }

/* Ignorar tem cor própria — sem ela, "Corrigir" e "Ignorar" eram dois botões
   cinzentos idênticos, e a legenda perderia a única coisa que a faz funcionar. É o
   tom de ATENÇÃO e não o de perigo: apagar um campo se desfaz digitando de novo. */
.btn-ignorar { border: 1px solid #5c4626; background: var(--atencao-bg);
               color: var(--atencao); border-radius: var(--raio); cursor: pointer;
               font: inherit; font-weight: 600; }
.btn-ignorar:hover { background: #3a2d1c; }
.btn-ignorar:disabled { opacity: .5; cursor: default; }

/* ==================================================== o app no celular, apertado */
/* ⚠️ ESTA É A TELA REAL DO PRODUTO. O lojista usa isto em pé, no pátio, no celular,
   com uma mão — e o que o desenho de mesa produz ali é sempre o mesmo defeito: cada
   bloco ocupa uma tela inteira, e ler o passo custa quatro rolagens. As três causas
   estavam medidas em px de desktop: o respiro do cartão (24px de todos os lados), a
   grade dos vídeos (uma coluna, e o 9:16 virava um retângulo de 640px de altura) e o
   corpo dos textos de apoio, que são explicação e não conteúdo. */
@media (max-width: 640px) {
  .app-main { width: min(1120px, 94vw); padding: 20px 0 64px; }
  .card { padding: 16px 14px; }

  .topo-pagina { gap: 12px; margin: 0 0 18px; }
  .passo-h { font-size: 19px; }
  .passo-sub, .passo-nota, .passo-alt { font-size: 13px; line-height: 1.5; }
  .passo-falta, .passo-travado { padding: 11px 12px; font-size: 13px; }
  .tpl-sec { margin: 22px 0 6px; padding-top: 16px; }

  /* O cabeçalho do passo 1 é a promessa da marca, mas não precisa de três linhas de
     texto para isso no celular — o selo "IA" e o título já dizem. */
  .ia-cab { gap: 10px; }
  .passo-painel[data-passo="video"] .ia-cab { padding: 14px; }
  .ia-cab .muted { font-size: 13px; }
  .ia-video, .ia-opt { padding: 12px 13px; }
  .ia-chk em { font-size: 12.5px; }
  .ia-qtd { flex-wrap: wrap; }
  .ia-etapas { gap: 6px; }
  .ia-etapa { padding: 9px 11px; }
  .ia-etapa em { font-size: 12px; }

  /* ⚠️ DUAS COLUNAS, e é por isto que o card do 9:16 deixou de tomar a tela toda: numa
     coluna só, a moldura vertical ficava com 640px de altura num aparelho de 360px de
     largura — o lojista rolava uma tela inteira de retângulo preto por formato. Em
     duas colunas os três formatos cabem de um olhar, que é como se escolhe entre
     eles. O teto em `vh` é o cinto de segurança para telas estreitas e altas. */
  .pecas-grade { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .peca-tela { max-height: 44vh; }
  .peca-pe { padding: 9px 10px 0; gap: 6px; }
  .peca-pe b { font-size: 13px; }
  .peca-pe .muted { font-size: 11.5px; }
  .peca-acoes { padding: 8px 10px 10px; gap: 6px; }

  .fotos { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
  .grade-ia { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }

  /* As pílulas quebram em duas fileiras num aparelho de 360px, e é o comportamento
     certo: são o filtro principal da tela e precisam continuar legíveis. Encolhem o
     bastante para caberem duas por linha sem virar alvo pequeno demais. */
  .resumo { gap: 6px; margin: 0 0 16px; }
  .pil { padding: 9px 13px; gap: 6px; }
  .pil b { font-size: 16px; }
  .pil span { font-size: 12.5px; }

  .grade-veiculos { gap: 12px; }
  .cv-novo { min-height: 150px; padding: 20px 16px; }
  .conf { padding: 15px 14px; }
  .conf-topo h2 { font-size: 17px; }
  .conf-topo .muted { font-size: 13px; }

  /* "instagram.com/" e o prefixo mais longo do app, e ele divide a mesma regra que
     "R$", "KM" e "+55". Em 360px, aos 14px com 13px de respiro dos dois lados, ele
     comeria ~126px de um campo de ~280px — quase metade da largura para escrever um
     nome de perfil de uma palavra. Encolher o prefixo (nunca o campo) devolve o
     espaco a quem digita, e os prefixos curtos nao perdem nada com isso. */
  .campo-com-prefixo span { padding: 0 9px; font-size: 13px; }

  /* ⚠️ TRÊS BOTÕES NUMA RÉGUA QUE NÃO QUEBRA NEM ENCOLHE. `.conf-acoes` nasceu com
     dois ("Está certo" e "Corrigir") e cabia; o "Ignorar" chegou depois e passou da
     borda. A causa é a soma de duas declarações que sozinhas são inofensivas:
     `flex: none` impede encolher, e a ausência de `flex-wrap` impede quebrar — a
     régua vira largura FIXA de ~280px dentro de um cartão de ~254px, e o excesso sai
     pela direita da janela levando rolagem horizontal junto.

     Em grade de três colunas iguais eles dividem o que há, e o alvo de toque continua
     inteiro porque a altura não muda. */
  .conf-acoes { display: grid; grid-template-columns: repeat(3, 1fr);
                gap: 6px; width: 100%; }
  .conf-acoes .btn, .conf-acoes .btn-ghost, .conf-acoes .btn-ignorar {
    padding: 10px 6px; text-align: center; }

  /* Mesma causa no rodapé de navegação do passo, com um agravante: os rótulos são
     escritos pelo `nav()` e um deles tem 20 caracteres ("Salvar e continuar →").
     Somado ao "← Vídeo" passa da largura do cartão, e `justify-content: space-between`
     não quebra linha — só afasta os dois até estourarem.

     Empilhados, cada um ocupa a linha inteira. A ordem do DOM não muda: voltar em
     cima, avançar embaixo, que é onde o polegar está. */
  .passo-nav { flex-direction: column; align-items: stretch; gap: 8px; }
  .passo-nav .btn, .passo-nav .btn-ghost { text-align: center; }
  /* O `<span></span>` que o `nav()` põe no lugar do botão ausente viraria uma sobra de
     8px no topo do primeiro passo e no fim do último. */
  .passo-nav > span:empty { display: none; }
}
