  /* ---------------------------------------------------------- utilidades */
  .vazio { color: var(--ink-3); font-size: 13px; }
  a { color: var(--orange-dk); font-weight: 600; text-decoration: none; }
  a:hover { text-decoration: underline; }

  /* ---------------------------------------------------------- estado vazio */
  .vazio-estado { text-align: center; padding: 90px var(--s4) 0; color: var(--ink-3); }
  .vazio-estado svg { width: 56px; height: 56px; color: #b7c0cf; margin-bottom: var(--s4); }
  .vazio-estado h3 { font-family: var(--brand); font-weight: 700; font-size: 18px;
                     color: var(--navy); margin: 0 0 6px; }
  .vazio-estado p { max-width: 340px; margin: 0 auto; font-size: 14px; }
  /* Variante em moldura própria, para quando o vazio divide a tela com outro
     conteúdo (a grade de pastas, por exemplo) em vez de ocupá-la sozinho. */
  .vazio-estado.compacto { padding: 40px var(--s5); background: var(--surface);
                           border: 1px solid var(--border); border-radius: 12px; }
  .vazio-estado.compacto svg { width: 42px; height: 42px; margin-bottom: var(--s3); }
  .vazio-estado.compacto h3 { font-size: 16px; }
  .vazio-estado.compacto p { font-size: 13px; }

  /* PRIMEIROS PASSOS — o que um assinante novo vê no lugar de uma tela vazia.
     Item 62. Herda a moldura do `.compacto` (mesma superfície, mesma borda, mesmo
     raio) porque não é um cartaz novo: é o mesmo estado vazio, com o caminho
     escrito dentro. Inventar uma moldura própria aqui faria a primeira tela do
     produto não se parecer com o resto dele. */
  .vazio-estado.primeiros-passos { padding: 40px var(--s5); background: var(--surface);
                                   border: 1px solid var(--border); border-radius: 12px;
                                   max-width: 560px; margin: 0 auto; }
  .vazio-estado.primeiros-passos svg { width: 46px; height: 46px; margin-bottom: var(--s3); }
  .vazio-estado.primeiros-passos h3 { font-size: 19px; }
  /* O parágrafo herda `max-width: 340px` do `.vazio-estado`, e nesta variante isso
     deixava a palavra "passos." sozinha na segunda linha. 420px cabe a frase inteira
     numa linha, e continua estreito o bastante para não virar um bloco de texto. */
  .vazio-estado.primeiros-passos p { max-width: 420px; }
  /* Os passos: numerados, alinhados à ESQUERDA dentro de um bloco centrado. Texto
     de instrução centralizado obriga o olho a procurar o começo de cada linha. */
  .pp-passos { list-style: none; counter-reset: passo; margin: var(--s5) 0 0;
               padding: 0; text-align: left; display: flex; flex-direction: column;
               gap: var(--s4); }
  .pp-passos li { counter-increment: passo; display: grid;
                  grid-template-columns: 26px 1fr; gap: var(--s3); align-items: start; }
  /* O número no navy da marca, e não no laranja: laranja é da ação principal, e o
     botão logo abaixo é quem tem direito a ele. */
  .pp-passos li::before { content: counter(passo); grid-row: 1 / span 2;
                          width: 26px; height: 26px; border-radius: 50%;
                          background: var(--navy); color: #fff;
                          font-family: var(--brand); font-weight: 700; font-size: 13px;
                          display: flex; align-items: center; justify-content: center; }
  .pp-passos li b { font-size: 14px; color: var(--ink); font-weight: 700; }
  .pp-passos li span { display: block; font-size: 13px; line-height: 1.5;
                       color: var(--ink-3); margin-top: 2px; }/* ------------------------------------------------------------- Entregar
     Arquivos, link do cliente e os comentários dele. Três coisas da mesma
     família — o que sai daqui para fora. */

  /* Marco de entrega: a faixa que responde "isto já saiu?" antes de qualquer
     outra coisa da tela. Quem aponta é o profissional — a existência de um link
     não prova entrega. */
  /* Duas linhas: o anúncio em cima, o caminho inteiro embaixo. */
  .ent-marco { display: flex; flex-direction: column; gap: var(--s3);
               background: var(--surface); border: 1px solid var(--border);
               border-radius: 12px; padding: 14px 18px; margin-top: var(--s4); }
  .ent-marco-topo { display: flex; align-items: center; gap: var(--s3); }
  .ent-etapas { border-top: 1px solid var(--hair); padding-top: var(--s3); }
  /* Entregue = o mesmo navy do console do Processar, e não o verde claro. São
     os dois momentos em que a tela anuncia "esta etapa terminou", e anunciavam
     de jeitos diferentes. O verde continua no que é ESTADO — o disco do ícone,
     o arco do medidor —, sobre o escuro, que é onde ele acende. */
  .ent-marco.feito { background: linear-gradient(135deg, var(--navy-3) 0%, var(--navy-4) 100%);
                     border-color: var(--navy-2); }
  /* Sobre o navy valem as cores da família clara: as do tema foram calibradas
     para texto escuro sobre branco e apagam aqui. */
  .ent-marco.feito .ent-marco-txt b { color: #fff; }
  /* "desfazer" com a mesma roupa dos botões secundários do console do Processar.
     Branco cheio sobre o navy virava a coisa mais clara do bloco — mais visível
     que o próprio "Trabalho entregue", que é o que ele veio anunciar. */
  .ent-marco.feito button:not(.principal) { background: rgba(255,255,255,.07);
                                            color: var(--tinta-esc-1);
                                            border-color: rgba(255,255,255,.14); }
  .ent-marco.feito button:not(.principal):hover:not(:disabled) { background: rgba(255,255,255,.13);
                                                                 color: #fff; }
  /* A trilha sobre o navy: mesma família clara do resto do escuro. O verde e o
     laranja dos discos ficam — são estado, e é sobre o escuro que acendem. */
  .ent-marco.feito .ent-etapas { border-top-color: rgba(255,255,255,.10); }
  .ent-marco.feito .et-txt b { color: #fff; }
  .ent-marco.feito .et-txt small { color: var(--tinta-esc-2); }
  .ent-marco.feito .etapa.agora .et-txt small { color: var(--warn-claro); }
  .ent-marco.feito .et-linha { background: rgba(255,255,255,.14); }
  .ent-marco.feito .et-linha.ok { background: var(--good-claro); }
  /* Disco no verde NEON, com halo. O tique dentro passa a ser navy, e não
     branco: branco sobre #2ee08a dá 1,73:1, que não se lê; navy dá 9,55:1. */
  .ent-marco.feito .etapa.ok .et-num { background: var(--good-claro); color: var(--navy);
                                       box-shadow: 0 0 9px rgba(46,224,138,.55); }
  .ent-marco.feito .etapa.espera .et-num { background: rgba(255,255,255,.08);
                                           color: var(--tinta-esc-2); }
  /* `!important` porque a regra base `.etapa:hover` já traz um — ela existe para
     vencer o hover genérico de botão. Sem empatar a arma, o realce claro voltava
     e branqueava a etapa sobre o navy. */
  .ent-marco.feito .etapa:hover { background: rgba(255,255,255,.07) !important; }
  .ent-marco-ic { width: 38px; height: 38px; border-radius: 50%; flex: none;
                  display: grid; place-items: center; background: var(--surface-2);
                  border: 1px solid var(--border); color: var(--ink-3); }
  .ent-marco-ic svg { width: 20px; height: 20px; }
  /* O mesmo neon do disco das etapas: é o "✓ pronto" que o olho procura, e é o
     único verde que sobra no bloco. Tique em navy pelo mesmo motivo de contraste. */
  .ent-marco.feito .ent-marco-ic { background: var(--good-claro); border-color: var(--good-claro);
                                   color: var(--navy);
                                   box-shadow: 0 0 12px rgba(46,224,138,.45); }
  .ent-marco-txt { flex: 1; min-width: 0; }
  .ent-marco-txt b { display: block; font-size: 13.5px; }
  .ent-marco-txt small { color: var(--ink-2); font-size: 12px; }
  .ent-marco.feito .ent-marco-txt small { color: var(--tinta-esc-2); }
  .ent-marco input { width: 240px; flex: none; }
  /* Data combinada + contagem regressiva, no marco: é a resposta de "ainda dá
     tempo?" e precisa estar onde se decide dar por entregue. */
  .ent-prazo { flex: none; display: flex; flex-direction: column; align-items: flex-end;
    gap: 2px; padding-right: var(--s3); border-right: 1px solid var(--border); margin-right: 2px; }
  .ent-prazo .ep-rot { font: 700 9.5px/1 var(--ui); text-transform: uppercase;
    letter-spacing: .4px; color: var(--ink-3); }
  .ent-prazo .ep-data { font: 700 14px/1 var(--ui); color: var(--ink);
    font-variant-numeric: tabular-nums; }
  .ent-prazo .ep-conta { font: 700 11px/1 var(--ui); border-radius: 20px; padding: 3px 8px; }
  .ent-prazo .ep-conta.ok { background: var(--good-bg); color: var(--good); }
  .ent-prazo .ep-conta.perto { background: var(--warn-bg); color: var(--warn); }
  .ent-prazo .ep-conta.tarde { background: var(--bad-bg); color: var(--bad); }
  /* A data combinada mora no formulário do LINK, não no marco de entrega: quem
     revisa é deste link, e dois revisores podem ter prazos diferentes. */
  /* `margin: 0` explícito: a regra genérica de <label> traz 0 0 6px, e num
     formulário em linha esses 6px levantavam o campo 6,0px acima da base do
     "Nome do revisor" ao lado. Medido antes de acreditar. */
  .ent-campo { display: flex; flex-direction: column; gap: 3px; flex: none; margin: 0; }
  /* O <input type="date"> media 43,7px onde os outros campos têm 38.
     `height: 38px` não resolve, nem inline: o widget de data do Chrome tem
     altura intrínseca própria (23,7px de conteúdo com fonte 14) e não comprime
     — a altura declarada vira piso, não teto. O que resolve é dar espaço a
     menos: fonte 13 (conteúdo ~22) e recheio 7px fecham 22+2+14 = 38. */
  .ent-campo input[type="date"] { font-size: 13px; padding: 7px 12px; }
  .ent-campo span { font: 700 10px/1 var(--ui); text-transform: uppercase; letter-spacing: .4px;
    color: var(--ink-3); }
  .ent-campo input[type="date"] { width: 148px; }
  .ent-campo select { width: auto; }
  /* Entrega travada por comentário aberto: âmbar, que é a cor de "falta algo",
     e não vermelho — nada quebrou, só não terminou. A tarja fica GRUDADA no
     marco (margem negativa contra o gap de 16px) porque é a explicação do botão
     desabilitado logo acima; solta no meio da página viraria outro aviso. */
  .ent-marco.travado { background: var(--warn-bg); border-color: var(--warn-bd2);
    border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
  .ent-marco.travado .ent-marco-ic { background: #fff; border-color: var(--warn-bd2); color: var(--warn); }
  .ent-trava { display: flex; align-items: center; gap: var(--s3);
    margin: -16px 0 var(--s4); padding: 11px 22px 13px;
    background: var(--warn-bg); border: 1px solid var(--warn-bd2); border-top: 1px solid #edddc0;
    border-radius: 0 0 12px 12px; color: var(--warn); }
  .ent-trava svg { width: 20px; height: 20px; flex: none; }
  .ent-trava div { flex: 1; min-width: 0; }
  .ent-trava b { font-size: 13px; }
  .ent-trava small { display: block; color: #7a5410; font-size: 12px; margin-top: 1px; }
  /* O botão do aviso é o botão NORMAL do padrão (38px, borda, fundo branco).
     Ele herdava o âmbar do texto da tarja e virava um quarto tipo de botão na
     mesma tela; e como fica numa faixa de largura cheia, não é caso de .btn-p,
     que existe para barra densa e lista. */
  .ent-trava button { flex: none; background: var(--surface); border-color: #e0cba2; color: var(--ink); }
  .ent-trava button:hover:not(:disabled) { background: #fffdf8; border-color: var(--warn); }
  .ent-coment.piscar { animation: piscaComent 1.4s ease 2; }
  @keyframes piscaComent { 0%,100% { background: transparent; } 40% { background: var(--warn-bg); } }
  /* Cabeçalho do bloco de arquivos: título à esquerda, "baixar tudo" à direita. */
  .ent-cab { display: flex; align-items: flex-start; justify-content: space-between;
             gap: var(--s3); margin-bottom: var(--s3); }
  .ent-cab .cfg-titulo, .ent-cab .cfg-ajuda { margin: 0; }

  /* Campo e select na MESMA altura. Medido antes: input com 42px e select com
     38 — dois controles lado a lado que não se alinhavam. */
  .ent-novo input, .ent-novo select { height: 38px; }
  @media (max-width: 1100px) {
  }

  /* AS COLUNAS DA TABELA DE ARQUIVOS — item 109, ele viu: "ainda dá pra melhorar as
   * colunas da tabela".
   *
   * O defeito só apareceu quando as abas (item 105) deram 1.470px ao painel — antes eram 727
   * e a proporção passava. Medido nos 10 arquivos do voo de 889 fotos:
   *
   *     Arquivo   843px (59%)   e precisa de 843
   *     Formato   179px (13%)   e precisa de ~50  (é um selo de 3 letras)
   *     Tamanho   196px (14%)   e precisa de ~70  ("662 MB")
   *     Ação      202px (14%)   e precisa de ~90  (um botão)
   *
   * O pior efeito não era o desperdício: era a DISTÂNCIA. O botão "baixar" ficava em x=1349,
   * e o olho tinha de atravessar 843px para ligar o arquivo ao botão dele — numa lista em que
   * baixar o arquivo errado custa 662MB de download.
   *
   * Agora as três colunas da direita são fixas no que o conteúdo pede, e a tabela tem teto de
   * largura. A sobra não fica vazia: a nota explicativa (ortomosaico, elevação, curvas) subiu
   * para o lado da tabela, onde ela é lida junto com a lista que ela explica, em vez de
   * embaixo, depois de dez linhas. */
  .ent-arquivos { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
                  gap: var(--s4); align-items: start; }
  .ent-tab { width: 100%; border-collapse: collapse; font-size: 12.5px; }
  /* `table-layout: fixed` é o que faz as larguras abaixo valerem: sem ele o navegador
   * redistribui as colunas pelo conteúdo e o `width` do `th` vira sugestão. */
  .ent-tab { table-layout: fixed; }
  .ent-tab th:nth-child(2), .ent-tab td:nth-child(2) { width: 92px; }
  .ent-tab th:nth-child(3), .ent-tab td:nth-child(3) { width: 104px; }
  .ent-tab th:nth-child(4), .ent-tab td:nth-child(4) { width: 116px; }
  /* O BOTAO "baixar" CENTRADO NA COLUNA DELE. Item 150, pedido dele em 08/08/2026.
     A coluna tem largura fixa de 116px e o botao mede menos que isso, entao encostado a esquerda
     ele deixava um vao morto a direita em toda linha -- e numa tabela de tamanho fixo esse vao se
     repete e vira coluna torta.
     `text-align` NAO resolveria: o filho e um `button`, que e inline-block e obedece ao
     text-align do pai -- mas o `th` da coluna esta com `text-align: left` herdado da regra dos
     cabecalhos, e centrar so a celula deixaria o cabecalho fora de registro com o conteudo.
     Centro os DOIS, e assim a coluna fecha alinhada de cima a baixo. */
  .ent-tab th:nth-child(4), .ent-tab td:nth-child(4) { text-align: center; }
  /* Nome longo não empurra a coluna: corta com reticências. O nome inteiro fica na dica. */
  .ent-tab td:first-child > b,
  .ent-tab td:first-child > span:first-child { display: block; overflow: hidden;
                                              text-overflow: ellipsis; white-space: nowrap; }
  .ent-tab th { text-align: left; color: var(--ink-3); font-weight: 600; font-size: 10.5px;
                text-transform: uppercase; letter-spacing: .04em; padding: 0 8px 6px; }
  .ent-tab td { padding: 8px; border-top: 1px solid var(--hair); vertical-align: middle; }
  /* Zebra: uma linha clara, a de baixo branca — o mesmo padrão do visualizador.
     Na tabela de arquivos são quatro colunas com o tamanho lá na direita, e é
     essa faixa que impede ler o tamanho da linha de cima. */
  .ent-tab tr:nth-of-type(even) { background: var(--zebra); }
  .ent-coment:nth-of-type(odd) { background: var(--zebra); }
  .ent-coment { padding-left: 8px; padding-right: 8px; border-radius: 8px; }
  .ent-tab td.num, .ent-tab th.num { text-align: right; font-variant-numeric: tabular-nums;
                                     color: var(--ink-2); }
  .ent-desc { display: block; color: var(--ink-3); font-size: 11px; margin-top: 2px; }
  .ent-fmt { display: inline-block; font: 700 10px/1 var(--ui); padding: 3px 7px; border-radius: 5px;
             background: var(--surface-2); border: 1px solid var(--border); color: var(--ink-2); }
  /* O formato que entrou no item 427 (GeoTIFF, KML, SHP): marca ao lado do chip, não no lugar dele. */
  .ent-novo { display: inline-block; margin-left: 6px; font: 700 9px/1 var(--ui); padding: 3px 6px;
              border-radius: 5px; background: var(--orange); color: #fff; text-transform: uppercase; }

  .ent-nota { background: var(--surface-2); border: 1px solid var(--border); border-radius: 9px;
              padding: 11px 14px; font-size: 12.5px; color: var(--ink-2); margin-top: var(--s3); }
  .ent-nota b { color: var(--ink); }

  .ent-novo { display: flex; gap: var(--s2); margin-bottom: var(--s3); align-items: flex-end; }
  .ent-novo input { flex: 1; min-width: 0; }
  .ent-novo select { width: auto; }
  .ent-pill { flex: none; font-size: 10.5px; font-weight: 700; border-radius: 20px; padding: 2px 8px; }
  .ent-pill.viva { background: var(--good-bg); color: var(--good); }
  .ent-pill.expira { background: var(--warn-bg); color: var(--warn); }
  .ent-pill.morta { background: var(--bad-bg); color: var(--bad); }
  /* padding vertical SEM atalho: o `padding: 10px 0` zerava as laterais e apagava o
     remendo de 8px que a zebra ganhou acima — atalho depois de remendo desfaz o remendo. */
  .ent-coment { display: flex; gap: var(--s2); align-items: flex-start;
                padding-top: 10px; padding-bottom: 10px;
                border-top: 1px solid var(--hair); }
  /* --navy-2, o mesmo azul do comentário no visualizador. Estava em --navy
     (var(--navy), o tom do topo) e o mesmo comentário aparecia com um azul no
     Anotações e outro aqui. */
  .ent-n { width: 22px; height: 22px; border-radius: 6px; background: var(--navy-2); color: #fff;
           flex: none; display: grid; place-items: center; font: 800 11px/1 var(--ui); }
  /* Selo do tipo, igual ao das listas do visualizador: mesmo formato, mesmas
     quatro cores, mesmos rótulos. */
  .ent-tipo { display: inline-block; font: 700 9.5px/1 var(--ui); text-transform: uppercase;
    letter-spacing: .4px; margin-left: 6px; padding: 3px 7px; border-radius: 20px; color: #fff; }
  .ent-tipo.t-duvida { background: var(--navy-2); }
  .ent-tipo.t-problema { background: var(--bad); }
  .ent-tipo.t-pedido { background: var(--warn); }
  .ent-tipo.t-informacao { background: var(--good); }
  .ent-parecer { font: 700 10.5px/1 var(--ui); margin-left: 5px; }
  .ent-parecer.aprovado { color: var(--good); }
  .ent-parecer.reprovado { color: var(--bad); }
  /* Atendido recua o TEXTO, não as marcas — mesma regra do visualizador.
     O registro de que foi lido e resolvido é parte da conversa com o revisor,
     então ele não some da tela; só deixa de disputar a leitura. */
  .ent-coment.feito .ent-corpo b, .ent-coment.feito .ent-corpo p { opacity: .5; }
  .ent-corpo { flex: 1; min-width: 0; }
  .ent-corpo p { margin: 2px 0 0; font-size: 12.5px; color: var(--ink-2); }
  .ent-quando { font-size: 11px; color: var(--ink-3); }
  /* Cabecalho da aba: titulo a esquerda, acao a direita, na mesma linha -- item 203. */
  .ent-cab { display: flex; align-items: center; justify-content: space-between;
             gap: 12px; margin-bottom: 2px; }
  .ent-cab .cfg-titulo { margin: 0; }
  /* AZUL, e nao laranja: laranja e o que sai da mao do assinante, azul e o que veio do
     revisor. E a mesma gramatica do item 222, do outro lado do produto. */
  .bt-comentario { border: 1px solid var(--comentario); background: var(--comentario);
                   color: #fff; border-radius: 9px; padding: 8px 14px;
                   font: 700 12.5px/1 var(--ui); cursor: pointer; white-space: nowrap;
                   transition: var(--t, .15s); }
  .bt-comentario:hover:not(:disabled) { background: var(--comentario-dk);
                                        border-color: var(--comentario-dk); }
  /* Desligado sem comentario: cinza e sem cursor, para nao prometer clique. O porque fica
     no `title`, que e onde a pessoa procura quando um botao nao responde. */
  .bt-comentario:disabled { background: var(--inerte-bg); border-color: #dfe4ec;
                            color: #7a8699; cursor: default; }
  /* O DOCUMENTO GERADO, na propria aba -- pedido dele: "a tela dos relatorios de
     comentarios do revisor tem que ficar junto na aba entregar".
     Borda azul a esquerda, como cada comentario da lista logo abaixo: e a mesma familia
     visual, e diz sem palavra nenhuma que aquele PDF e feito destes comentarios. */
  .rel-coments { display: flex; align-items: center; gap: 12px; margin: 10px 0 4px;
                 padding: 10px 14px; background: #f6f8fb; border: 1px solid #dfe4ec;
                 border-left: 3px solid var(--comentario); border-radius: 8px; }
  .rel-coments .rc-quem { flex: 1; min-width: 0; }
  .rel-coments .rc-quem b { display: block; font-size: 13.5px; color: var(--ink, #12203a); }
  .rel-coments .rc-quem span { font-size: 12px; color: #7a8699; }
  /* Arquivo que sumiu do disco: MOSTRA, nao esconde -- mesma decisao da tela Relatorios.
     A borda fica ambar porque ha o que fazer (gerar de novo), e nao vermelha: nada se
     perdeu que nao possa ser refeito com um clique. */
  .rel-coments.sumiu { border-left-color: var(--orange, #ff6501); }
  /* O SEGUNDO numero da aba: quantos comentarios ainda esperam resposta. Item 203.
     Laranja porque pede acao, e o total ao lado fica neutro -- os dois numeros dizem coisas
     diferentes, e a cor e o que impede de le-los como um so. */
  .ent-falta { background: var(--orange, #ff6501); color: #fff;
    border-radius: 20px; padding: 0 6px; margin-left: 3px; font-size: 11px; }
  .ent-conta { display: inline-block; font: 700 10.5px/1 var(--ui); color: #fff;
               background: var(--orange); border-radius: 20px; padding: 2px 8px; margin-left: 6px; }

