/* As peças: cartão, campo, botão, tabela, selo.
 *
 * O que se repete em toda tela. Os papéis de botão moram aqui — o que
 * avança, o secundário e o que destrói.
 *
 * Parte de estilo/. A folha foi dividida por assunto em 03/08/2026: 915 linhas
 * num arquivo só obrigavam a rolar por tudo para achar qualquer coisa.
 *
 * Ligadas por <link> múltiplo, e NÃO por @import: @import encadeia downloads —
 * o navegador só descobre o segundo arquivo depois de baixar o primeiro. */

.cartao {
  background: var(--cartao);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  padding: var(--e5);
  margin-bottom: var(--e4);
  box-shadow: var(--sombra);
}

/* O respiro do cartão encolhe quando não sobra espaço para ele.

   `--e5` acompanha o tamanho do texto: a 200% vira 48px de cada lado. E os
   cartões se ANINHAM — o de cargo mora dentro do da cédula —, então numa janela
   de 320px eram 96px de recuo somados aos 80px do `main`: sobravam 76px de
   conteúdo, e o título de um cargo passava a rolar dentro da própria caixa.

   O gatilho é o mesmo da gaveta, e em `rem` de propósito: a 200% uma janela de
   320px mede 10rem e entra aqui — que é exatamente quando precisa entrar. */
@media (max-width: 47.999rem) {
  .cartao {
    padding: var(--e3);
  }

  main {
    padding-left: var(--e3);
    padding-right: var(--e3);
  }
}

/* Nenhum título empurra a página para o lado.

   Com o texto a 200%, "Presidência" pede 232px de uma linha só. Não existe
   recuo pequeno o bastante para caber isso numa janela de 320px — a saída é a
   palavra quebrar. `hyphens` faz a quebra na sílaba, e o documento declara
   `lang="pt-BR"`, que é o que ensina o navegador onde separar; `overflow-wrap`
   fica de rede, para quando não houver regra de sílaba (um código, um
   protocolo). Rolagem lateral não é alternativa: é o que a WCAG 1.4.10 proíbe. */
h1,
h2,
h3 {
  hyphens: auto;
  overflow-wrap: break-word;
}

label {
  display: block;
  font-size: var(--texto-miudo);
  line-height: 1.4;
  color: var(--apagado);
  margin-bottom: 0.3rem;
}

/* `input` sem filtro pegava CAIXA DE MARCAR e BOTÃO DE RÁDIO junto.
   
   Eles não são campos de texto: largura total e altura mínima de 2,75rem
   transformam um rádio num retângulo do tamanho da tela. Na cédula o estrago
   ficou escondido porque o rádio vive num contêiner flex, que o encolhe — mas a
   altura de 44px já estava lá. No primeiro rádio posto dentro de um `label` em
   bloco, ele apareceu com 1232px de largura.
   
   Notado em 05/08/2026, ao olhar a tela — nenhuma auditoria automática acusa
   isso, porque um rádio gigante continua sendo um rádio com rótulo. */
input:not([type="radio"]):not([type="checkbox"]),
select,
textarea {
  width: 100%;
  padding: 0.6rem 0.7rem;
  font: inherit;
  color: var(--tinta);
  background: var(--papel);
  border: 1px solid var(--borda);
  border-radius: 8px;
  /* Recuo e borda entram na altura. Sem isto, campo e botão calculam altura de
     formas diferentes e nunca coincidem. */
  box-sizing: border-box;
}

/* Campo, seletor e botão têm a MESMA altura.
   Numa linha alinhada pelo topo, altura diferente vira base diferente — dois
   pixels que o olho não nomeia mas percebe. E 2.75rem é o alvo de toque de
   44px: a mesa de uma eleição pode ser um tablet. */
input:not([type="radio"]):not([type="checkbox"]),
select {
  min-height: 2.75rem;
}

/* Marcar e desmarcar: tamanho natural do controle, e o alvo de toque vem do
   rótulo em volta — que é onde ele deve estar, porque clicar no texto também
   marca. */
input[type="radio"],
input[type="checkbox"] {
  width: auto;
  min-height: 0;
  margin-right: 0.5rem;
  accent-color: var(--acao);
}

input:focus-visible,
select:focus-visible,
button:focus-visible,
textarea:focus-visible {
  outline: 3px solid var(--acao);
  outline-offset: 2px;
}

/* `<fieldset>` usado só para AGRUPAR, sem moldura.

   Ele existe aqui pelo que anuncia, não pelo que desenha: a legenda dá o contexto
   — de qual cargo é este formulário — a quem usa leitor de tela, e o nome do
   cargo já está visível no título logo acima.

   Sem isto o navegador desenha a moldura e o recuo padrão, e a linha de candidato
   ganharia uma caixa em volta que não significa nada. */
.sem-moldura {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.linha {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  /* Alinha pelo TOPO, e não pelo rodapé.
     Pelo rodapé, qualquer texto abaixo de um campo — ajuda, erro — deixava
     aquele item mais alto e empurrava o campo dele para cima, desalinhando a
     linha inteira. Pelo topo, a altura do item deixa de importar, e a mensagem
     pode ficar onde precisa ficar: colada ao campo de que fala. */
  align-items: start;
  margin-bottom: 0.75rem;
}

/* EXCEÇÃO: linha com caixa de texto alinha pelo rodapé.
   Uma `textarea` de quatro linhas nunca terá o mesmo topo útil de um campo de
   uma linha — alinhá-las pelo topo deixaria o botão lá em cima, a oitenta
   pixels da base da caixa. Aqui o rodapé é que é a referência visual, e a
   exceção é segura porque estas linhas não carregam mensagem por campo. */
.linha:has(textarea) {
  align-items: end;
}

/* O botão não tem rótulo, e sem isto ele encostaria no topo enquanto os campos
   começam uma linha abaixo. O espaçador vale exatamente um rótulo.

   `:has(label)` é a parte que faltava: numa linha cujos campos NÃO têm rótulo —
   a de candidato, que usa só texto de exemplo — o espaçador empurrava o botão
   sozinho, 23px abaixo dos campos. Compensar altura de rótulo onde não há
   rótulo é criar o desalinhamento que se queria evitar.

   Não vale na linha com caixa de texto, que alinha pelo rodapé. */
.linha:has(label):not(:has(textarea)) > .acao::before {
  content: "";
  display: block;
  height: calc(var(--texto-miudo) * 1.4 + 0.3rem);
}
.linha > div {
  /* A base de 12rem vira 384px quando alguém amplia o texto para 200% — maior
     que uma tela de 320px. `min-width: 0` deixa o item encolher abaixo dela;
     sem isso, `flex-shrink` não tem efeito, porque o padrão `min-width: auto`
     trava no tamanho do conteúdo. */
  flex: 1 1 12rem;
  min-width: 0;
}

/* Campo dentro de linha acompanha o contêiner em vez de impor a largura
   própria — a largura padrão de um <input> é maior que 320px a 200%. */
.linha input,
.linha select,
.linha textarea {
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  /* `block`, e não o `inline-block` padrão.

     Elemento inline participa da caixa de linha, e ela reserva espaço abaixo
     para as descidas das letras — g, p, q. Num textarea de quatro linhas isso
     dava 9px de sobra invisível por baixo, e ele terminava acima dos campos
     vizinhos numa linha alinhada pelo rodapé. */
  display: block;
}

/* PAPÉIS DE BOTÃO.

   Antes, todo botão nascia azul-cheio: numa mesma linha, "liberar a cerimônia
   de chaves" e "cancelar a eleição" tinham exatamente o mesmo peso. Um avança a
   eleição; o outro a mata.

   O preenchido continua sendo o padrão porque cada área tem uma ação principal
   — cadastrar, autorizar, apurar. O que muda é que agora existem os outros dois
   papéis, e a barra de estado os usa. */
/* UM LINK QUE É AÇÃO se parece com um botão.
   
   O editor de templates abre em página PRÓPRIA — ela tem política de conteúdo
   diferente —, e navegar é trabalho de `<a>`: um `<button>` com `window.open`
   perderia abrir em nova aba, copiar o endereço e o meio do teclado. Mas ele
   fica ao lado dos botões da tela, e um link sublinhado solto ali é o que não
   se lê como ação.
   
   `a.botao` entra em toda regra de `button` abaixo. `display: inline-flex` e
   `text-decoration: none` são o que um `<a>` precisa a mais para ter a mesma
   caixa. */
a.botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

button,
a.botao {
  /* Mesma conta de altura dos campos — ver o comentário deles. */
  box-sizing: border-box;
  /* Rótulo longo quebra em duas linhas em vez de esticar o botão para fora da
     tela. É o que permite a barra de estado caber em 320px. */
  max-width: 100%;
  white-space: normal;
  overflow-wrap: break-word;
  font-family: inherit;
  font-size: var(--texto-apoio);
  font-weight: var(--peso-medio);
  line-height: 1.2;
  padding: var(--e3) var(--e5);
  border-radius: 8px;
  border: 1px solid var(--acao);
  background: var(--acao);
  color: var(--sobre-acao);
  cursor: pointer;
  /* Alvo de toque: 44px é o mínimo para quem opera por toque, e a mesa de uma
     eleição pode ser um tablet. */
  min-height: 2.75rem;
}

/* O que destrói não pode parecer o que avança. */
button.perigo {
  background: transparent;
  border-color: var(--alerta);
  color: var(--alerta);
}
button.perigo:hover {
  background: var(--alerta);
  color: var(--papel);
}

button.secundario,
a.botao.secundario {
  background: transparent;
  color: var(--acao);
  font-weight: var(--peso-normal);
}

/* O que destrói DENTRO de uma lista.

   `perigo` cheio de borda repetido em vinte linhas vira uma parede vermelha, e
   parede que se repete é parede que se aprende a não ver — junto com o aviso.
   Aqui a cor fica só no texto, e a moldura só aparece ao passar o ponteiro ou ao
   receber o foco.

   Continua distinto do `secundario` ao lado, que é o que importa: os dois botões
   da linha fazem coisas de gravidade muito diferente. E a distinção não é SÓ a
   cor — o rótulo diz "Excluir", e o nome acessível diz de quem. */
button.perigo-discreto {
  background: transparent;
  border-color: transparent;
  color: var(--alerta);
  font-weight: var(--peso-normal);
}
button.perigo-discreto:hover {
  border-color: var(--alerta);
}
button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.principal {
  width: 100%;
  font-size: var(--texto-destaque);
  padding: 0.85rem;
  margin-top: 1rem;
}
.botoes {
  display: flex;
  gap: 0.75rem;
  margin-top: 1rem;
}
.botoes button {
  flex: 1;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--texto-apoio);
}
th,
td {
  text-align: left;
  padding: 0.5rem 0.4rem;
  border-bottom: 1px solid var(--borda);
}
th {
  font-size: var(--texto-miudo);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--apagado);
}

.selo {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: var(--texto-miudo);
  font-weight: 600;
  letter-spacing: 0.04em;
  background: var(--acao-clara);
  color: var(--acao);
}

.erro {
  color: var(--alerta);
  min-height: 1.4rem;
  margin: 0.5rem 0 0;
}
.certo {
  color: var(--certo);
}
/* Espaço reservado para o veredito da auditoria.

   Sem isto a caixa está vazia antes de conferir e cresce ao receber o resultado,
   empurrando a tabela inteira para baixo — 97px, medidos. Apontado por Gabriel
   em 05/08/2026, e é o mesmo defeito que o `min-height` de `.erro-do-campo` já
   tinha corrigido noutro lugar: quando o conteúdo é previsível em ALTURA, o
   espaço se reserva desde o início.

   A conta é uma linha de conclusão mais TRÊS de apoio: com achados, a frase de
   alcance ganha a menção ao detalhamento e passa de duas linhas. Reservar duas
   deixava 32px de salto — medido, não estimado. Trilha COM achados ainda cresce, porque a lista de grupos é de
   tamanho imprevisível — e nessa hora a atenção de quem lê está no problema, não
   na tabela. */
#veredito {
  min-height: calc(
    var(--texto-corpo) * var(--altura-corpo) + 3 * var(--texto-apoio) *
      var(--altura-apoio)
  );
}

/* A lista de vereditos da auditoria.
   O termo carrega o peso — só ele fica em cor de alerta, e SÓ quando é
   adulteração. "Assinado por outro servidor" em vermelho leria como acusação,
   que é exatamente o erro que esta mudança existe para corrigir. */
/* O respiro é PREENCHIMENTO do contêiner, e não margem da lista.

   Margem do primeiro filho escapa da caixa do pai e não entra na medição — o
   deslocamento aparecia na tela e não no medidor. Preenchimento fica dentro,
   então o que se mede é o que se vê. */
#veredito-detalhe:not(:empty) {
  padding-top: 0.75rem;
}
.vereditos {
  margin: 0;
}
.vereditos dt {
  font-weight: 600;
  margin-top: 0.75rem;
}
.vereditos dd {
  margin: 0.15rem 0 0;
  color: var(--apagado);
  font-size: var(--texto-apoio);
  line-height: var(--altura-apoio);
}

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

/* Números que se comparam ficam alinhados.
   Conferir resultado de eleição com dígitos que dançam de linha para linha
   transforma leitura em trabalho de olho, exatamente onde o erro é mais caro. */
#resultado td:last-child,
#resultado th:last-child,
.protocolo {
  font-variant-numeric: tabular-nums;
}

/* ================================================= tabela em tela estreita

   Tabela não reflui: as colunas têm largura mínima e, somadas, passam de 320px.
   A saída é a própria tabela rolar na horizontal, dentro de uma região que o
   teclado alcança — e não a página inteira rolar de lado, que é o que a WCAG
   1.4.10 proíbe.

   `.rola` já fazia isso na lista de eleitores, com `tabindex` e `role` para
   quem navega por teclado conseguir rolar. As outras tabelas ficaram de fora. */
.area .rola {
  overflow-x: auto;
  /* Sem isto, um filho flex ou grid impede o contêiner de encolher e a rolagem
     nunca acontece — o estouro só muda de lugar. */
  min-width: 0;
}

.area table {
  /* Impede que uma célula de conteúdo longo — nome de eleitor, hash da trilha —
     estique a tabela indefinidamente. */
  table-layout: auto;
  word-break: normal;
  overflow-wrap: anywhere;
}

/* O identificador de quem está autenticado quebra em vez de empurrar a faixa. */
.quem {
  min-width: 0;
  flex-wrap: wrap;
}

/* ============================================== campo obrigatório e seu erro

   A obrigatoriedade é TEXTO, e não um asterisco colorido: informar por cor
   sozinha esconde de quem não distingue a diferença e de quem não vê a tela.
   Fica mais discreta que o rótulo, mas continua legível — o contraste é o do
   texto de apoio, que a auditoria já mede. */
.exigido {
  font-weight: var(--peso-normal);
  color: var(--apagado);
}

/* O erro mora COLADO ao campo a que se refere.

   Erro que só existe num aviso no rodapé não é encontrado por quem navega por
   teclado: o foco está no campo, e a explicação está a vinte tabulações dali.
   Vazio, o parágrafo não ocupa espaço — sem isto, cada campo reservaria uma
   linha em branco permanente. */
.erro-do-campo {
  margin: var(--e1) 0 0;
  font-size: var(--texto-miudo);
  line-height: 1.35;
  color: var(--alerta);
  /* O espaço é RESERVADO, mesmo vazio.

     Sem isto, a mensagem aparecendo empurrava 22px de conteúdo para baixo: a
     busca, a tabela, tudo. Quem estava lendo perde o lugar, e quem ia clicar
     clica no que se moveu para debaixo do ponteiro.

     Uma linha basta — a maior mensagem que este formulário produz, a recusa por
     documento repetido com o nome de quem o ocupa, cabe em uma. É o mesmo que
     `.erro` já fazia no aviso geral; eu é que não tinha seguido. */
  min-height: calc(var(--texto-miudo) * 1.35);
}

/* O campo recusado se marca também na borda — cor SOMADA ao texto do erro,
   nunca no lugar dele. */
input[aria-invalid="true"],
select[aria-invalid="true"] {
  border-color: var(--alerta);
}

/* ==================================================== navegação entre páginas

   Existe porque a lista cortava em cinquenta sem dizer, e quem operava concluiu
   que eleitores cadastrados não existiam. */
.paginacao {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--e3);
  margin-top: var(--e4);
}

/* Indisponível usa `aria-disabled`, e não `disabled` — o botão CONTINUA na
   ordem de foco, para quem navega por teclado ouvir que chegou ao fim em vez de
   passar direto sem entender. A recusa fica no manipulador. */
.paginacao button[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* A ajuda do campo, colada nele. */
.ajuda-do-campo {
  margin: var(--e1) 0 0;
  font-size: var(--texto-miudo);
  line-height: 1.35;
}

/* `[hidden]` é regra do NAVEGADOR, e qualquer `display` de autor a vence: sem
   esta linha, `.paginacao { display: flex }` fazia "Página 1 de 1" aparecer com
   zero eleitores. */
.paginacao[hidden] {
  display: none;
}

/* O tipo do documento, junto do número.

   Discreto de propósito: o número é o que se compara com o papel na mão; o tipo
   diz de que documento ele é. Não vira coluna própria — coluna é ordenável, e
   ordenar por tipo separaria a assembleia entre quem tem CPF e quem não tem. */
.tipo-do-documento {
  font-size: var(--texto-miudo);
  color: var(--apagado);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ---------------------------------------------------------------- diálogos

   MORAM AQUI, e não em `urna.css`, porque as DUAS páginas usam: a urna, para
   configurar o terminal; o painel, para cadastrar o rosto na mesa.

   A primeira versão do diálogo de rosto herdou a classe da urna e o painel não
   carrega aquela folha — resultado: fundo transparente, `position: static`, e a
   tela de trás aparecendo através do texto. É o MESMO defeito que já tinha
   acontecido em 05/08/2026, pela mesma causa: estilo numa folha que a página não
   lê. Medido em 06/08/2026 antes de corrigir: `rgba(0, 0, 0, 0)`.

   `--papel` é o nome que existe. `--fundo` não existe em folha nenhuma, e
   declaração inválida vira nada. */
.dialogo {
  /* `<dialog>` nasce com borda, largura automática e centralizado pelo
     navegador. Aqui ele cobre a tela: numa urna e num guichê, meia tela com o
     resto visível atrás convida a tocar no que não deve. */
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  border: 0;
  padding: var(--e5);
  background: var(--papel);
  color: var(--tinta);

  /* SOBRA NO FIM, PARA A BARRA DO SISTEMA NÃO COMER O ÚLTIMO BOTÃO.

     Em tablet e celular, a barra de navegação — voltar, início, abas — fica por
     cima da parte de baixo da tela. O diálogo de configuração é mais alto que a
     tela e rola por dentro; rolado até o fim, o último botão ficava METADE
     escondido atrás dela. Visto em 14/08/2026, num moto g55, com a urna já
     rodando como aplicativo.

     Medir não pegava: numa janela de navegador não existe barra de sistema, e o
     botão aparecia inteiro. Foi preciso alguém olhar o aparelho.

     `env(safe-area-inset-bottom)` é o valor exato quando o navegador o informa,
     e a sobra fixa é o que garante o resultado quando ele informa zero — que é o
     caso do WebView sem `viewport-fit=cover`. Em tela grande isso é um espaço a
     mais no fim de um diálogo que já rola: não custa nada. */
  padding-bottom: calc(var(--e7) + env(safe-area-inset-bottom, 0px));
}

/* O fundo do modal nativo. Sem isto ele é translúcido por padrão, e a tela de
   trás continua legível — que é o que o modal existe para impedir. */
.dialogo::backdrop {
  background: rgba(0, 0, 0, 0.6);
}

.dialogo > * {
  max-width: 34rem;
}

.dialogo h2,
.dialogo h3 {
  margin-top: 0;
}

.dialogo fieldset label {
  display: block;
  margin-bottom: var(--e2);
}

/* A confirmação de exclusão não cobre a tela toda.

   Os outros diálogos do sistema capturam rosto: lá, cobrir tudo é o ponto —
   meia tela com o resto visível atrás convida a tocar no que não deve. Aqui é o
   contrário. A pergunta diz "o cargo sai da cédula, e os 3 candidatos dele saem
   junto", e essa frase se confere olhando a cédula ATRÁS do diálogo. Cobrir a
   tela apagaria justamente o que dá sentido à pergunta.

   `margin: auto` centra nos dois eixos; sem ele o `<dialog>` de altura
   automática encosta no topo. */
.dialogo.confirmacao {
  width: min(32rem, calc(100% - 2rem));
  /* `fit-content`, e NÃO `auto`.

     Com `auto` a caixa esticava até o máximo, deixando meia tela de vazio
     debaixo dos botões. O motivo não é óbvio e vale escrito: um `<dialog>`
     modal nasce posicionado com `inset: 0`, e um elemento posicionado que tem
     topo E base fixados, altura `auto` e margem `auto` tem a altura RESOLVIDA
     para preencher o espaço — a margem é que fica sobrando, não a altura.
     `fit-content` tira a altura da equação, e aí sobra para a margem centrar.

     Visto numa captura do manual, não na tela: a caixa vazia só chama atenção
     quando está impressa ao lado das outras. */
  height: fit-content;
  max-height: calc(100% - 2rem);
  margin: auto;
  border-radius: var(--raio);
}

/* Os dois botões da confirmação.

   `flex-wrap` porque a 320px com texto ampliado eles não cabem lado a lado, e
   `gap` porque um deles apaga: alvos de toque colados são onde se mira no
   "Cancelar" e se acerta o "Excluir".

   A ORDEM no documento é cancelar, depois excluir — e é ela que decide o que
   recebe o foco primeiro. Nenhuma regra visual pode inverter isso: `row-reverse`
   deixaria "Excluir" à esquerda na tela e ainda assim primeiro no Tab, que é o
   pior dos dois mundos. */
.acoes-do-dialogo {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e3);
  margin-top: var(--e5);
}

/* O vídeo de câmera, nas três telas que capturam.

   Nunca maior que a tela, e com a proporção mantida: esticado, o rosto deforma —
   e rosto deformado é o que faz a comparação errar. */
video {
  display: block;
  width: 100%;
  max-width: 24rem;
  margin: var(--e3) 0;
  border-radius: var(--raio);
  background: #000;
}

/* O PALCO DA CAPTURA GUIADA, nas duas telas que CADASTRAM rosto: o auto-cadastro
   e a mesa.

   Mora aqui, e não no CSS de uma delas, pelo mesmo motivo do módulo que as duas
   importam: enquadramento é a mesma decisão nos dois lugares, e um oval em
   posição diferente é um critério diferente sem ninguém ter decidido isso. */
.palco-captura {
  position: relative;
  background: #000;
  border-radius: var(--raio);
  overflow: hidden;
}

.palco-captura video {
  /* As duas linhas abaixo DESFAZEM a regra genérica `video {}` acima. Deixá-las
     valer deixava faixa preta, e foi achado numa foto de celular durante um
     teste de verdade:

       `margin: 12px 0`   -> 24px do fundo preto do palco acima e abaixo da
                             imagem. Medido: palco 456px, vídeo 432px.
       `max-width: 24rem` -> acima de 384px o vídeo para de crescer e o palco
                             continua, deixando preto na LATERAL. É o pior dos
                             dois: a oval fica sobre a faixa e o rosto sai do
                             enquadramento. */
  max-width: none;
  margin: 0;
  /* Espelhado: a pessoa se vê como no espelho, e não invertida. Sem isto,
     "centralize o rosto" faz mover para o lado errado. */
  transform: scaleX(-1);
  aspect-ratio: 3 / 4;
  object-fit: cover;
}

/* O oval é decorativo e não recebe evento de ponteiro: um toque na tela precisa
   chegar no que está embaixo. */
.palco-captura .guia {
  position: absolute;
  inset: 10% 18%;
  border: 3px dashed rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  pointer-events: none;
}

/* A orientação é a voz da câmera: muda a cada quadro analisado, e é o que a
   pessoa lê enquanto se enquadra. Por isso não é texto de apoio apagado.

   `min-height` reserva a linha ANTES de haver texto: sem ela, a primeira
   mensagem empurra os botões para baixo no instante em que alguém vai clicar. */
.orientacao {
  margin: 0;
  min-height: 1.5rem;
  font-size: var(--texto-destaque);
  line-height: var(--altura-corpo);
}
