/* ==========================================================================
   PAINEL OBD-II — estilo
   --------------------------------------------------------------------------
   Escrito para um celular preso ao painel de um carro. Daí vêm as decisões que
   explicam quase tudo abaixo:

   · **Números grandes, rótulos pequenos.** O que se lê de relance é o valor;
     o rótulo só existe para a primeira vez. A rotação sai em 30 px, e os
     dígitos são tabulares — sem isso o número muda de largura a cada leitura
     e o olho perde o lugar.
   · **Nada muda de lugar.** Os mostradores têm altura mínima, a unidade fica
     fora do número e o ponteiro mora numa grade de duas linhas: passar de 999
     para 1.000 não empurra nada. Layout que pula com o carro andando é layout
     que obriga a olhar de novo.
   · **Alvo mínimo de 52 px**, porque o dedo mira num suporte que balança.
   · **O escuro é o modo de verdade.** Este aplicativo é usado dirigindo, e
     boa parte disso é à noite: tela clara a meio palmo do rosto ofusca. O
     claro existe, mas o desenho nasceu escuro.
   ========================================================================== */

:root {
  color-scheme: light;
  --fundo: #eef1f5;
  --superficie: #ffffff;
  --superficie-2: #f4f7fa;
  --texto: #101720;
  --suave: #55616f;
  --borda: #d8dfe7;
  --principal: #123a5e;
  --principal-texto: #ffffff;
  --principal-fraco: #e3ecf5;
  --ok: #0f7a52;
  --ok-fraco: #e1f4ec;
  --atencao: #a15c00;
  --atencao-fraco: #fdf0da;
  --perigo: #b8302a;
  --perigo-fraco: #fbe8e7;
  --frio: #2b6ea8;
  --sombra: 0 1px 2px rgba(16, 23, 32, .08), 0 4px 12px rgba(16, 23, 32, .06);
  --raio: 14px;
  --barra-altura: 64px;
  --topo-altura: 48px;
}

/*
 * O escuro vale em dois casos: escolha explícita nos ajustes, e modo automático
 * com o aparelho no escuro. A lista aparece duas vezes porque o CSS não deixa
 * agrupar um seletor com uma consulta de mídia — e repetir quinze linhas é
 * melhor que uma camada de indireção que ninguém consegue ler depois.
 */
:root[data-tema="escuro"] {
  color-scheme: dark;
  --fundo: #0d1720;
  --superficie: #16232f;
  --superficie-2: #1e2d3b;
  --texto: #eef3f9;
  --suave: #9fb0c0;
  --borda: #2a3a49;
  --principal: #4ea0f5;
  --principal-texto: #08121d;
  --principal-fraco: #17293c;
  --ok: #3fd39a;
  --ok-fraco: #10281f;
  --atencao: #f0b24a;
  --atencao-fraco: #2d2313;
  --perigo: #f47a72;
  --perigo-fraco: #301917;
  --frio: #6fb4f0;
  --sombra: 0 1px 2px rgba(0, 0, 0, .45);
}

@media (prefers-color-scheme: dark) {
  :root[data-tema="auto"] {
    color-scheme: dark;
    --fundo: #0d1720;
    --superficie: #16232f;
    --superficie-2: #1e2d3b;
    --texto: #eef3f9;
    --suave: #9fb0c0;
    --borda: #2a3a49;
    --principal: #4ea0f5;
    --principal-texto: #08121d;
    --principal-fraco: #17293c;
    --ok: #3fd39a;
    --ok-fraco: #10281f;
    --atencao: #f0b24a;
    --atencao-fraco: #2d2313;
    --perigo: #f47a72;
    --perigo-fraco: #301917;
    --frio: #6fb4f0;
    --sombra: 0 1px 2px rgba(0, 0, 0, .45);
  }
}

* { box-sizing: border-box; }

/*
 * O `hidden` do HTML precisa ganhar de qualquer `display` daqui — senão o aviso
 * de versão nova fica permanentemente na tela, inclusive na primeira abertura.
 */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--fundo);
  color: var(--texto);
  font: 17px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
  padding-bottom: calc(var(--barra-altura) + env(safe-area-inset-bottom));
  overflow-x: hidden;
}

body.carregando .conteudo { opacity: 0; }

/* ------------------------------------------------------------------- topo */

/*
 * A altura do topo é um número, e não a soma de paddings.
 *
 * As telas que se prendem à janela — painel e editor — precisam subtrair essa
 * altura para saber quanto espaço sobra. Com a altura saindo de padding mais
 * entrelinha, a conta do CSS e a realidade discordavam em alguns pixels, e uns
 * poucos pixels são exatamente a diferença entre caber e aparecer uma barra de
 * rolagem.
 */
.topo {
  position: sticky;
  top: 0;
  z-index: 5;
  box-sizing: content-box;
  height: var(--topo-altura);
  display: flex;
  align-items: center;
  background: var(--principal);
  color: var(--principal-texto);
  padding: env(safe-area-inset-top) 16px 0;
}

.topo-titulo {
  margin: 0;
  font-size: 19px;
  font-weight: 650;
  letter-spacing: .2px;
}

.conteudo { padding: 12px 12px 8px; }

.tela { display: flex; flex-direction: column; gap: 12px; }

/* ---------------------------------------------------------------- cartões */

.cartao {
  background: var(--superficie);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.secao-titulo {
  margin: 0;
  font-size: 16px;
  font-weight: 650;
  color: var(--texto);
}

.campo-dica {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--suave);
}

.erro {
  margin: 12px;
  padding: 12px;
  border-radius: var(--raio);
  background: var(--perigo-fraco);
  color: var(--perigo);
}

/* ------------------------------------------- o painel preso na janela */

/*
 * O painel ocupa a janela inteira e não rola. Nem um pixel.
 *
 * É a diferença entre um aplicativo e um quadro de instrumentos: num carro, o
 * número que exige rolar para aparecer é um número que não se lê. A altura
 * disponível é o que sobra da barra de abas — o título some, porque a aba acesa
 * já diz onde se está e quarenta e oito pixels de barra azul valem mais como
 * velocímetro.
 */
body.painel-fixo { overflow: hidden; }
body.painel-fixo .topo { display: none; }

body.painel-fixo .conteudo {
  padding: 0;
  max-width: none;
  /*
   * `--altura-janela` é medida em JavaScript; `100dvh` fica de reserva para o
   * primeiro quadro, antes de a medição acontecer. Ver `medirJanela` em
   * `app.js`: num celular o `dvh` conta o espaço da barra de endereço como
   * livre, e a última fileira de mostradores some embaixo da barra de abas.
   */
  height: calc(var(--altura-janela, 100dvh) - var(--barra-altura) - env(safe-area-inset-bottom));
}

.tela-painel {
  position: relative;
  height: 100%;
  gap: 0;
}

/*
 * Câmera à esquerda, instrumentos à direita, controles na borda.
 *
 * Três colunas, e só a do meio é obrigatória. A da câmera aparece quando há
 * imagem — reservar quarenta por cento da tela para um retângulo preto quando
 * não se está gravando seria tirar espaço dos ponteiros em troca de nada.
 */
.palco {
  height: 100%;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  /*
   * A linha é `minmax(0, 1fr)`, e não `auto`.
   *
   * Sem isto a linha implícita cresce até caber o conteúdo, e o `height: 100%`
   * daqui vira só uma sugestão: o palco media 323 pixels e a coluna dos
   * mostradores, 428. A tela não rolava — `overflow: hidden` no `body` —, e o
   * resultado era pior que rolar: o mostrador de baixo ficava cortado ao meio,
   * sem nenhum jeito de alcançá-lo.
   */
  grid-template-rows: minmax(0, 1fr);
  gap: 6px;
  padding: 6px;
}

.palco.com-camera { grid-template-columns: minmax(0, 38%) minmax(0, 1fr) auto; }

.palco-camera {
  position: relative;
  min-width: 0;
  border-radius: 10px;
  overflow: hidden;
  background: #000;
}

/* A imagem preenche a coluna: é para conferir o enquadramento, e enquadramento
   com tarja preta em volta não se confere. */
.palco-camera .previa-de-video {
  width: 100%;
  height: 100%;
  max-height: none;
  border-radius: 0;
  object-fit: cover;
}

.camera-estado {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  padding: 5px 8px;
  font-size: 11.5px;
  color: #f2f6fa;
  background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, .72));
}

.camera-estado-erro { color: #ffd9d6; }

.palco-grade {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.palco-grade .alertas:empty { display: none; }

/*
 * O alerta no painel é uma faixa, não um cartão.
 *
 * Ele precisa ser visto — a luz de anomalia é a única coisa desta tela que pede
 * uma decisão —, mas cada pixel que ele toma sai da altura do velocímetro. Numa
 * linha só, com o texto cortado se passar, ele avisa sem ocupar um sexto da
 * tela como ocupava.
 */
.palco-grade .alerta {
  margin: 0;
  padding: 3px 8px;
  font-size: 12px;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.palco-vazio {
  grid-column: 1 / -1;
  align-self: center;
  margin: 0;
  text-align: center;
  color: var(--suave);
  font-size: 13.5px;
}

/*
 * O trilho de controles.
 *
 * Sessenta pixels da largura — que numa tela deitada é o que sobra de graça — em
 * troca de nenhuma altura, que é o que falta. Antes estes cinco comandos eram
 * botões largos empilhados sob o painel, e empurravam os mostradores para fora
 * da janela.
 */
.trilho {
  display: flex;
  flex-direction: column;
  gap: 5px;
  width: 62px;
}

.trilho-botao {
  flex: 1;
  min-height: 0;
  padding: 2px;
  border: 1px solid var(--borda);
  border-radius: 10px;
  background: var(--superficie);
  color: var(--texto);
  font: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  cursor: pointer;
}

.trilho-icone { font-size: 19px; line-height: 1; }

.trilho-nome {
  font-size: 9.5px;
  line-height: 1.1;
  text-align: center;
  color: var(--suave);
  font-variant-numeric: tabular-nums;
}

.trilho-botao[aria-pressed="true"] {
  background: var(--principal-fraco);
  border-color: var(--principal);
}

.trilho-botao[aria-pressed="true"] .trilho-nome { color: var(--principal); }

.trilho-botao.gravando {
  background: var(--perigo);
  border-color: var(--perigo);
  color: #fff;
}

.trilho-botao.gravando .trilho-nome { color: #fff; }

.trilho-botao:disabled { opacity: .45; cursor: default; }

/*
 * A gaveta: o que se lê parado.
 *
 * Situação da conexão, máximos e explicações. Estavam na tela e custavam três
 * vezes a altura dela; aqui continuam a um toque e não custam nada. Ela desliza
 * por cima do painel em vez de empurrá-lo, porque empurrar redesenharia todos
 * os ponteiros a cada abertura.
 */
.gaveta {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 4;
  width: min(400px, 78%);
  box-sizing: border-box;
  padding: 10px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--fundo);
  border-left: 1px solid var(--borda);
  box-shadow: -10px 0 28px rgba(0, 0, 0, .28);
}

.gaveta-fundo {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: rgba(0, 0, 0, .35);
}

.gaveta-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.gaveta-fechar { padding: 4px 12px; }

/* ------------------------------------------ o editor preso na janela */

/*
 * Pelo mesmo motivo do painel, e com um a mais: aqui a forma da grade é a
 * informação. Se a grade do editor tem células quadradas e a do painel tem
 * linhas que dividem a altura, o mesmo painel tem duas formas — e a que se
 * arrasta não é a que se vê dirigindo.
 */
body.editor-fixo { overflow: hidden; }

body.editor-fixo .conteudo {
  padding: 0;
  max-width: none;
  height: calc(var(--altura-janela, 100dvh) - var(--topo-altura) - env(safe-area-inset-top)
    - var(--barra-altura) - env(safe-area-inset-bottom));
}

.tela-editor {
  height: 100%;
  gap: 0;
}

.tela-editor .grade-do-painel.editando {
  flex: 1;
  min-height: 0;
  /*
   * Folga à direita e embaixo para as alças de canto.
   *
   * Elas moram em `right: -11px; bottom: -11px`, fora do próprio mostrador. Sem
   * esta folga, a alça da última coluna e a da última linha caíam fora do palco
   * — e como o corpo tem `overflow: hidden` no editor preso, ficavam
   * inalcançáveis: invisíveis, embaixo da barra de abas. Redimensionar pela
   * ponta simplesmente não funcionava ali.
   */
  padding: 0 12px 12px 0;
  gap: 6px;
  grid-auto-rows: minmax(0, 1fr);
  grid-template-rows: repeat(var(--linhas, 4), minmax(0, 1fr));
}

/* A coluna de comandos: estreita, porque a largura é o que sobra na tela
   deitada, e rolável por dentro, porque a página inteira não rola mais. */
.editor-lateral {
  width: 168px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/*
 * Tudo aqui é miúdo de propósito.
 *
 * São sete controles numa coluna de trezentos pixels de altura, e a coluna não
 * pode rolar por dentro: a primeira versão tinha botão de tamanho normal, e as
 * abas dos painéis saíam por cima enquanto «Apagar» ficava cortado embaixo —
 * dois comandos invisíveis numa tela que existe para dar comandos. No editor
 * isso se pode: é uma tela em que se opera parado, olhando.
 */
.editor-lateral .botao {
  min-height: 38px;
  padding: 6px 8px;
  font-size: 12px;
  border-radius: 10px;
}

.editor-lateral .campo-dica {
  margin: 0;
  font-size: 10.5px;
  line-height: 1.25;
}

.tela-editor .abas-de-painel {
  margin: 0;
  gap: 5px;
  flex-wrap: nowrap;
  overflow-x: auto;
}

.tela-editor .aba-painel {
  min-height: 30px;
  padding: 4px 12px;
  font-size: 12.5px;
  flex: 0 0 auto;
}

/* --------------------------------------------------- a grade do painel */

/*
 * A grade do painel personalizado.
 *
 * **Oito colunas**, o mesmo número que `dominio/painel.js` usa para colocar,
 * mover e redimensionar. Estiveram quatro aqui por um tempo, e o estrago era
 * silencioso: um mostrador em «x = 6» caía numa coluna implícita, de largura
 * automática, e o painel inteiro saía torto — colunas de tamanhos diferentes,
 * itens grudados e a impressão de que a disposição salva não era a desenhada.
 * O número de colunas é do modelo; o CSS não pode ter opinião própria sobre
 * ele.
 *
 * A altura da linha vem de `--celula`, que o JavaScript mede e mantém igual à
 * largura da coluna. O CSS sozinho não faz essa conta: a largura da coluna só
 * existe depois do desenho. Com uma altura fixa em pixels, o mesmo painel
 * sairia achatado num celular estreito e esticado num tablet, e um item de 2×2
 * deixaria de ser quadrado.
 */
.grade-do-painel {
  display: grid;
  grid-template-columns: repeat(var(--colunas, 8), 1fr);
  grid-auto-rows: var(--celula, 84px);
  gap: 8px;
}

.item-do-painel {
  position: relative;
  min-width: 0;
  min-height: 0;
}

/*
 * No painel vivo as linhas dividem a altura, em vez de seguirem a largura.
 *
 * Fora daqui a célula é quadrada — o editor precisa disso para que o que se
 * arrasta tenha a forma do que vai aparecer. Aqui a altura é a da janela e não
 * sobra nada: com célula quadrada, o painel ou deixava faixa vazia embaixo ou
 * vazava para fora da tela, que é como um mostrador acaba cortado ao meio.
 */
.tela-painel .grade-do-painel {
  flex: 1;
  min-height: 0;
  gap: 6px;
  grid-auto-rows: minmax(0, 1fr);
  grid-template-rows: repeat(var(--linhas, 3), minmax(0, 1fr));
}

/* O visor preenche a célula que lhe deram, seja ela qual for. */
.item-do-painel > .medidor,
.item-do-painel > .mostrador,
.item-do-painel > .visor-barra {
  width: 100%;
  height: 100%;
}

/*
 * Um mostrador maior mostra um número maior.
 *
 * Sem isto, aumentar um mostrador só aumentava a caixa em volta — o número
 * continuava do mesmo tamanho, boiando no meio do espaço novo, e o
 * redimensionamento parecia não fazer nada. Quem arrasta a alça para agrandar a
 * temperatura quer **ler** a temperatura de mais longe, não ganhar margem.
 *
 * Os degraus são explícitos, e não uma conta em unidades de contêiner, porque
 * são quatro casos e porque a leitura no carro merece um tamanho escolhido em
 * cada um, e não interpolado.
 */
/*
 * O tamanho da letra vem da célula, e não do número de células que o item ocupa.
 *
 * Eram degraus fixos por largura — 2 colunas, 34 pixels; 3 colunas, 52 — e a
 * conta só fechava enquanto a coluna tivesse sempre a mesma largura. Deixou de
 * ter: com a câmera ocupando a lateral, os mostradores dividem pouco mais da
 * metade da tela, e «14,2 V» num item de uma coluna virava «14,» — um número
 * cortado, que num painel de carro se lê como outro número.
 *
 * `cqw` e `cqh` são a largura e a altura da própria célula. O `min()` entre as
 * duas é o que impede a letra de crescer pela altura numa célula estreita e
 * vazar pelos lados. Os limites do `clamp()` existem para os extremos: nem
 * ilegível numa célula minúscula, nem gigante numa tela de tablet.
 */
.item-do-painel { container-type: size; }

.item-do-painel .mostrador { padding: 5px 6px; }

.item-do-painel .mostrador-numero { font-size: clamp(13px, min(32cqw, 38cqh), 56px); }
.item-do-painel .mostrador-titulo { font-size: clamp(9px, min(10cqw, 15cqh), 15px); }
.item-do-painel .mostrador-unidade { font-size: clamp(8px, min(9cqw, 13cqh), 14px); }

.item-do-painel .barra-numero { font-size: clamp(13px, min(15cqw, 26cqh), 30px); }
.item-do-painel .barra-titulo { font-size: clamp(9px, min(9cqw, 14cqh), 14px); }

.item-do-painel[data-altura="2"] .barra-trilho,
.item-do-painel[data-altura="3"] .barra-trilho { height: 18px; }

/*
 * O modo quadro de instrumentos.
 *
 * Some tudo que não é o painel, e o fundo vai a preto — que num carro à noite é
 * o que não ofusca, e de dia é o que dá contraste ao número. A grade se estica
 * para a tela inteira e as células deixam de ser quadradas: aqui manda a altura
 * disponível, porque o que se quer é o maior ponteiro que couber.
 */
body.quadro-de-instrumentos {
  /*
   * O modo cheio troca a paleta inteira, e não só o fundo.
   *
   * Forçar `background: #000` sem trocar os tokens deixava o texto escuro do
   * tema claro em cima do preto: «14,2 V» sumia, legível só contra a luz. Um
   * quadro de instrumentos é escuro por natureza — à noite, tela clara a meio
   * palmo do rosto ofusca —, então aqui o escuro não é uma opção do tema: é o
   * modo.
   */
  color-scheme: dark;
  --fundo: #000;
  --superficie: #0a0d11;
  --superficie-2: #141a21;
  --texto: #f2f6fa;
  --suave: #8fa1b3;
  --borda: #1b222b;
  --principal: #4ea0f5;
  --principal-texto: #06101a;
  --principal-fraco: #17293c;
  --ok: #3fd39a;
  --ok-fraco: #10281f;
  --atencao: #f0b24a;
  --atencao-fraco: #2d2313;
  --perigo: #f47a72;
  /*
   * Os tons fracos entram junto, e não por capricho: o alerta da luz de
   * anomalia pinta o fundo com `--perigo-fraco`, e sem redefini-lo aqui ele
   * ficava rosa-claro atravessado no meio de um quadro preto — a única coisa
   * berrante da tela, à noite, a meio palmo do rosto.
   */
  --perigo-fraco: #301917;
  --frio: #6fb4f0;

  padding-bottom: 0;
  background: var(--fundo);
  color: var(--texto);
  overflow: hidden;
}

body.quadro-de-instrumentos .topo,
body.quadro-de-instrumentos .barra,
body.quadro-de-instrumentos .atualizacao,
body.quadro-de-instrumentos .cartao,
body.quadro-de-instrumentos .trilho,
body.quadro-de-instrumentos .gaveta,
body.quadro-de-instrumentos .gaveta-fundo,
body.quadro-de-instrumentos .alertas:empty { display: none !important; }

/*
 * O modo cheio não remonta nada: o palco já é do tamanho da janela, e aqui ele
 * só ganha de volta a altura da barra de abas e perde o trilho. Antes este
 * bloco refazia a geometria da grade por conta própria, e as duas contas
 * discordavam — o painel mudava de proporção ao entrar no modo cheio.
 */
body.quadro-de-instrumentos .conteudo {
  padding: 0;
  max-width: none;
  height: var(--altura-janela, 100dvh);
}

body.quadro-de-instrumentos .tela { gap: 0; }
body.quadro-de-instrumentos .palco { padding: 8px; }
body.quadro-de-instrumentos .palco.com-camera { grid-template-columns: minmax(0, 40%) minmax(0, 1fr); }
body.quadro-de-instrumentos .palco:not(.com-camera) { grid-template-columns: minmax(0, 1fr); }

body.quadro-de-instrumentos .medidor,
body.quadro-de-instrumentos .mostrador,
body.quadro-de-instrumentos .visor-barra {
  background: var(--superficie);
  box-shadow: none;
  border: 1px solid var(--borda);
}

/*
 * O aviso não pode atravessar o quadro.
 *
 * Fora daqui ele mora acima da barra de abas; sem a barra, ele caía bem no meio
 * da tela, por cima do velocímetro. Encolhido e encostado no canto, ele informa
 * sem tapar o que se está olhando.
 */
body.quadro-de-instrumentos .avisos {
  left: auto;
  right: 10px;
  bottom: 10px;
  width: min(48%, 320px);
}

body.quadro-de-instrumentos .aviso {
  background: var(--superficie-2);
  color: var(--texto);
  font-size: 13px;
  padding: 8px 12px;
}

/* ------------------------------------------------------------- o editor */

/*
 * No editor a grade reserva linhas vazias.
 *
 * Fora dele, a grade só cria as linhas que os itens ocupam — o que é certo para
 * o painel e errado para o editor: sem espaço vazio visível, não há para onde
 * arrastar um mostrador que se quer mais para baixo.
 */
.grade-do-painel.editando {
  grid-template-rows: repeat(var(--linhas, 4), var(--celula, 84px));
  padding-bottom: 8px;
}

/*
 * `touch-action: none` é o que faz o arrasto funcionar em celular.
 *
 * Sem ele o navegador entende o deslizar do dedo como rolagem da página, rola a
 * tela e o item foge do dedo enquanto o fundo anda atrás. É a causa número um
 * de arrasto que «não funciona no telefone» — e é invisível no computador, onde
 * o mouse não rola nada.
 */
.grade-do-painel.editando .item-do-painel {
  touch-action: none;
  cursor: grab;
  border-radius: var(--raio);
  outline: 2px dashed var(--borda);
  outline-offset: 2px;
}

.grade-do-painel.editando .item-do-painel.arrastando {
  cursor: grabbing;
  z-index: 3;
  opacity: .9;
  outline-color: var(--principal);
  /* Sem transição durante o arrasto: o item tem de colar no dedo. */
  transition: none;
}

/*
 * A alça de tamanho fica quase toda para fora do mostrador.
 *
 * Ela precisa de um alvo de dedo — trinta pixels, não dez —, e num mostrador de
 * uma célula esses trinta pixels cobriam a unidade: «11,4 km/L» virava «11,4»
 * com um botão por cima do resto. Empurrada para o vão entre as células, o alvo
 * continua inteiro e só o canto encosta no conteúdo.
 */
.alca-de-tamanho {
  position: absolute;
  right: -11px;
  bottom: -11px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--principal);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
  cursor: nwse-resize;
  touch-action: none;
  z-index: 4;
}

.alca-de-tamanho::after {
  content: "⇲";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--principal-texto);
  font-size: 14px;
}

/* Espaço para as alças não saírem cortadas na borda da tela. */
.grade-do-painel.editando { padding: 0 12px 14px; }

/*
 * No editor o conteúdo sobe um pouco, para sair de baixo da alça.
 *
 * O mostrador centraliza o conteúdo na vertical, e o canto de baixo à direita é
 * justamente onde a unidade termina: a alça cobria o «/L» de «11,4 km/L». Um
 * respiro embaixo empurra o texto para cima e devolve o canto à alça — e só
 * enquanto se edita, porque no painel de verdade não há alça nenhuma.
 */
.grade-do-painel.editando .mostrador { padding-bottom: 22px; }
.grade-do-painel.editando .visor-barra { padding-bottom: 18px; }

/* «Não cabe», dito sem texto. */
@keyframes sacudir {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}

.item-do-painel.sacudindo { animation: sacudir .3s; }

.abas-de-painel {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 4px;
}

.aba-painel {
  flex: none;
  border: 1px solid var(--borda);
  border-radius: 999px;
  background: var(--superficie-2);
  color: var(--texto);
  font: inherit;
  font-size: 14px;
  padding: 10px 16px;
  min-height: 44px;
  cursor: pointer;
}

.aba-painel.ativa {
  background: var(--principal);
  border-color: var(--principal);
  color: var(--principal-texto);
  font-weight: 650;
}

.aba-painel.nova { font-size: 20px; padding: 8px 18px; }

.dois-campos { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/*
 * Os botões de tamanho do mostrador.
 *
 * Alvo grande de propósito: são tocados com o polegar, dentro de um carro, por
 * quem está montando o painel — e o «−» e o «+» de meia dúzia de pixels é o
 * tipo de controle que funciona no computador e não funciona onde importa.
 */
/*
 * Largura e altura lado a lado, não empilhadas.
 *
 * Empilhados, os dois pares de botões custam uns cento e dez pixels de altura —
 * e numa folha de ajustes aberta sobre um celular deitado isso é um terço da
 * tela, que empurra o «Aplicar» para fora. Lado a lado custam setenta, e a tela
 * baixa é justamente onde sobra largura.
 */
.passos-de-tamanho {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
}

.passo {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

.passo-nome { font-size: 12.5px; color: var(--suave); }

.passo-controles {
  display: flex;
  align-items: center;
  gap: 4px;
}

.passo-botao {
  min-width: 48px;
  min-height: 44px;
  padding: 0;
  font-size: 22px;
  line-height: 1;
}

.passo-valor {
  min-width: 34px;
  text-align: center;
  font-size: 19px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- barra */

.visor-barra {
  background: var(--superficie);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
}

.barra-topo { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.barra-titulo { font-size: 12.5px; color: var(--suave); }
.barra-valor { display: flex; align-items: baseline; gap: 3px; }
.barra-numero { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.barra-unidade { font-size: 11.5px; color: var(--suave); }

.barra-trilho {
  height: 12px;
  border-radius: 999px;
  background: var(--superficie-2);
  overflow: hidden;
}

.barra-cheia {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--principal);
  transition: width .12s linear, background .3s;
}

.visor-barra[data-faixa="atencao"] .barra-cheia { background: var(--atencao); }
.visor-barra[data-faixa="perigo"] .barra-cheia { background: var(--perigo); }
.visor-barra[data-faixa="frio"] .barra-cheia { background: var(--frio); }
.visor-barra[data-faixa="atencao"] .barra-numero { color: var(--atencao); }
.visor-barra[data-faixa="perigo"] .barra-numero { color: var(--perigo); }

/* -------------------------------------------------------------- ponteiros */

.medidores {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

/*
 * O ponteiro e o número ocupam a mesma célula da grade, e o rótulo vem numa
 * linha só dele.
 *
 * Com posicionamento absoluto o número descia sobre o rótulo quando passava de
 * três dígitos — «1.726 rpm» escrito por cima da palavra «Giro». Numa grade os
 * dois nunca se encontram, porque a linha de baixo é reservada mesmo que o
 * número cresça.
 */
/*
 * O desenho ocupa o espaço que houver, e o rótulo fica embaixo.
 *
 * `minmax(0, 1fr)` na primeira linha é o que permite ao SVG encolher numa
 * célula baixa: sem o mínimo zero, o conteúdo impõe a altura e o mostrador
 * estoura para fora da célula, cortando o rótulo.
 */
.medidor {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  background: var(--superficie);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: 12px 8px 10px;
  text-align: center;
}

/*
 * O desenho cabe na célula, seja ela qual for.
 *
 * Com largura e altura em cem por cento, o SVG se ajusta à caixa e o
 * `preserveAspectRatio` padrão mantém a proporção, centrando o que sobrar. É o
 * que faz o mesmo mostrador funcionar numa célula quadrada de oitenta pixels e
 * no velocímetro que ocupa a altura de uma tela deitada.
 */
.medidor-desenho {
  grid-row: 1;
  width: 100%;
  height: 100%;
  min-height: 0;
  display: block;
}

.medidor-trilho {
  fill: none;
  stroke: var(--superficie-2);
  stroke-width: 6;
  stroke-linecap: round;
}

/* A faixa vermelha do conta-giros: desenhada por baixo dos traços. */
.medidor-zona-vermelha {
  fill: none;
  stroke: var(--perigo);
  stroke-width: 6;
  opacity: .75;
  stroke-linecap: butt;
}

.medidor-traco {
  stroke: var(--suave);
  stroke-width: 1.4;
  opacity: .65;
}

.medidor-traco.maior {
  stroke: var(--texto);
  stroke-width: 2.6;
  opacity: .9;
}

/*
 * Os números da escala.
 *
 * Dígitos tabulares e tamanho fixo: é o que faz «120» ocupar a mesma largura
 * que «100» e os números ficarem alinhados ao redor do mostrador em vez de
 * dançarem conforme o dígito.
 */
.medidor-valor-da-escala {
  fill: var(--suave);
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/*
 * O ponteiro.
 *
 * A transição é curta de propósito: 120 ms tira o degrau entre duas leituras
 * sem atrasar a informação. Acima de uns 200 ms o ponteiro passa a mostrar o
 * passado, que num velocímetro é pior que não mostrar nada.
 */
.medidor-ponteiro {
  fill: var(--principal);
  transition: transform .12s linear;
}

.medidor[data-faixa="atencao"] .medidor-ponteiro { fill: var(--atencao); }
.medidor[data-faixa="perigo"] .medidor-ponteiro { fill: var(--perigo); }
.medidor[data-faixa="frio"] .medidor-ponteiro { fill: var(--frio); }
.medidor[data-faixa="sem"] .medidor-ponteiro { fill: var(--borda); }

.medidor-eixo {
  fill: var(--superficie);
  stroke: var(--principal);
  stroke-width: 3;
}

.medidor[data-faixa="atencao"] .medidor-eixo { stroke: var(--atencao); }
.medidor[data-faixa="perigo"] .medidor-eixo { stroke: var(--perigo); }

/*
 * O número digital, desenhado dentro do SVG.
 *
 * São elementos de texto do próprio desenho, e por isso a cor vai em `fill` e
 * não em `color`, e o tamanho em unidades do `viewBox` — que escalam junto com
 * o mostrador. É o que faz o número ficar sempre no mesmo lugar do desenho, do
 * ponteiro pequeno de uma célula ao velocímetro que ocupa a tela inteira.
 */
.medidor-numero {
  fill: var(--texto);
  font-size: 32px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

.medidor-unidade {
  fill: var(--suave);
  font-size: 13px;
}

/* A segunda fonte de velocidade: menor, e sempre com a origem ao lado. */
.medidor-secundario {
  fill: var(--suave);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.medidor-titulo {
  grid-row: 2;
  margin-top: 2px;
  font-size: 13px;
  color: var(--suave);
}

/* ------------------------------------------------------------ mostradores */

.mostradores {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px;
}

.mostrador {
  background: var(--superficie-2);
  border-radius: 10px;
  padding: 10px;
  min-height: 76px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
}

/*
 * O rótulo do mostrador quebra em duas linhas em vez de virar reticências.
 *
 * «Consumo m…» não informa nada, e o mostrador tem altura mínima, não fixa:
 * uma linha a mais cabe. Reticências num painel de carro são pior que texto
 * miúdo — obrigam a parar para decifrar.
 */
.mostrador-titulo {
  font-size: 12px;
  line-height: 1.25;
  color: var(--suave);
}

/*
 * A unidade quebra para a linha de baixo quando não cabe.
 *
 * Numa célula de oitenta e cinco pixels, «10,8 km/L» não cabe em uma linha — e
 * sem quebrar, o navegador corta: aparecia «10,8 km», que se lê como
 * quilômetros. Um número com a unidade errada é pior que um número truncado,
 * porque parece certo.
 */
.mostrador-linha {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 4px;
}

.mostrador-numero {
  font-size: 22px;
  font-weight: 650;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.mostrador-unidade { font-size: 12px; color: var(--suave); }
.mostrador-dica { font-size: 11.5px; color: var(--suave); }

.mostrador[data-faixa="atencao"] .mostrador-numero { color: var(--atencao); }
.mostrador[data-faixa="perigo"] .mostrador-numero { color: var(--perigo); }
.mostrador[data-faixa="frio"] .mostrador-numero { color: var(--frio); }

/* ----------------------------------------------------- situação e alertas */

.situacao {
  margin: 0;
  font-size: 13.5px;
  color: var(--suave);
  display: flex;
  align-items: center;
  gap: 8px;
}

.situacao::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--borda);
  flex: none;
}

.situacao[data-situacao="conectado"]::before { background: var(--ok); }
.situacao[data-situacao="conectando"]::before { background: var(--atencao); }
.situacao[data-situacao="erro"]::before { background: var(--perigo); }

.alertas { display: flex; flex-direction: column; gap: 6px; }
.alertas:empty { display: none; }

.alerta {
  margin: 0;
  padding: 10px 12px;
  border-radius: 10px;
  font-size: 14px;
  line-height: 1.35;
}

.alerta-ok { background: var(--ok-fraco); color: var(--ok); }
.alerta-atencao { background: var(--atencao-fraco); color: var(--atencao); }
.alerta-perigo { background: var(--perigo-fraco); color: var(--perigo); }

/* ---------------------------------------------------------------- botões */

.botao {
  border: 0;
  border-radius: 12px;
  min-height: 52px;
  padding: 12px 18px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  background: var(--superficie-2);
  color: var(--texto);
  touch-action: manipulation;
}

.botao:active { transform: translateY(1px); }
.botao.largo { width: 100%; }

.botao-principal { background: var(--principal); color: var(--principal-texto); min-height: 60px; font-size: 18px; }
.botao-secundario { background: var(--principal-fraco); color: var(--principal); }
.botao-perigo { background: var(--perigo); color: #fff; }
.botao-fantasma { background: transparent; color: var(--principal); border: 1px solid var(--borda); }

.coluna-botoes { display: flex; flex-direction: column; gap: 8px; }

/* ---------------------------------------------------------------- campos */

.campo { display: flex; flex-direction: column; gap: 6px; }

.campo-rotulo { font-size: 13.5px; color: var(--suave); font-weight: 600; }

.entrada {
  width: 100%;
  min-height: 52px;
  padding: 12px 14px;
  border: 1px solid var(--borda);
  border-radius: 12px;
  background: var(--superficie-2);
  color: var(--texto);
  font: inherit;
}

select.entrada { appearance: none; background-image: none; }

/* ------------------------------------------------------ escolhas do painel */

.escolhas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 8px;
}

.escolha {
  border: 1px solid var(--borda);
  border-radius: 10px;
  background: var(--superficie-2);
  color: var(--texto);
  padding: 10px 8px;
  min-height: 56px;
  font: inherit;
  font-size: 13.5px;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 2px;
  cursor: pointer;
}

.escolha.marcada {
  background: var(--principal-fraco);
  border-color: var(--principal);
  color: var(--principal);
  font-weight: 600;
}

.escolha-unidade { font-size: 11.5px; color: var(--suave); }
.escolha.marcada .escolha-unidade { color: inherit; opacity: .8; }

/* ----------------------------------------------------------------- vídeo */

/*
 * O interruptor da câmera.
 *
 * Um `label` envolvendo a caixa de seleção, e não um botão estilizado: assim o
 * toque em qualquer lugar da linha alterna — e num carro o alvo precisa ser a
 * linha inteira, não um quadradinho de vinte pixels.
 */
.interruptor {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  padding: 8px 4px;
  cursor: pointer;
}

.interruptor-caixa {
  width: 26px;
  height: 26px;
  flex: none;
  accent-color: var(--principal);
}

.interruptor-nome { font-size: 15px; }

.interruptor:has(.interruptor-caixa:disabled) { opacity: .5; cursor: default; }

/*
 * A prévia da câmera fica pequena, e é proposital.
 *
 * Ela existe para confirmar que a lente está apontada para a estrada e
 * desimpedida — não para se assistir dirigindo. Grande, viraria uma televisão
 * no painel, que é exatamente o que não se quer num carro em movimento.
 */
.previa-de-video {
  width: 100%;
  max-height: 150px;
  object-fit: cover;
  border-radius: 10px;
  background: #000;
  transform: scaleX(1);
}

.tocador {
  width: 100%;
  max-height: 60vh;
  border-radius: 10px;
  background: #000;
  display: block;
}

/* A leitura do instante que está tocando: números grandes, rótulo pequeno. */
.leitura-do-video {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  padding: 10px 12px;
  background: var(--superficie-2);
  border-radius: 10px;
  min-height: 54px;
  align-items: center;
}

.leitura-item { display: flex; flex-direction: column; line-height: 1.15; }
.leitura-item strong { font-size: 18px; font-variant-numeric: tabular-nums; }
.leitura-item small { font-size: 11.5px; color: var(--suave); }
.leitura-vazia { font-size: 13.5px; color: var(--suave); }

.trechos {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  -webkit-overflow-scrolling: touch;
}

.trecho {
  flex: none;
  border: 1px solid var(--borda);
  border-radius: 10px;
  background: var(--superficie-2);
  color: var(--texto);
  font: inherit;
  font-size: 13px;
  padding: 8px 12px;
  min-height: 52px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  cursor: pointer;
}

.trecho.tocando {
  background: var(--principal-fraco);
  border-color: var(--principal);
  color: var(--principal);
  font-weight: 600;
}

.trecho-hora { font-variant-numeric: tabular-nums; }
.trecho-tamanho { font-size: 11px; color: var(--suave); }
.trecho.tocando .trecho-tamanho { color: inherit; opacity: .8; }

/* ---------------------------------------------------------------- listas */

.lista { display: flex; flex-direction: column; gap: 8px; }

.item {
  background: var(--superficie);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 64px;
}

.item-corpo { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.item-nome { font-weight: 600; }
.item-detalhe { font-size: 13.5px; color: var(--suave); }
.item-detalhe.suave { font-size: 12.5px; opacity: .8; }
.item-seta { font-size: 26px; color: var(--suave); line-height: 1; }

.viagem { cursor: pointer; }

.etiqueta {
  font-size: 12px;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: 999px;
  white-space: nowrap;
}

.etiqueta-pago { background: var(--ok-fraco); color: var(--ok); }
.etiqueta-pendente { background: var(--atencao-fraco); color: var(--atencao); }
.etiqueta-cancelado { background: var(--perigo-fraco); color: var(--perigo); }

.etiqueta-aberto { background: var(--principal-fraco); color: var(--principal); }

.tipo-adaptador.nao-funciona .item-nome { text-decoration: line-through; text-decoration-thickness: 1px; }

/*
 * «Com a ponte» não leva risco no nome, e é isso que a distingue de «não».
 *
 * Riscar diria «esqueça este, compre outro» — e para quem já tem o adaptador
 * Wi-Fi na mão isso seria falso e caro. Ele funciona; o que falta é um programa
 * rodando no aparelho, e a seção abaixo da tabela diz qual.
 */
.tipo-adaptador.com-ponte .item-nome { color: var(--principal); }

/*
 * Os passos de instalação da ponte.
 *
 * Números à esquerda, comando embutido no texto: são cinco linhas que alguém vai
 * ler com o celular numa mão e o Termux na outra, e uma lista numerada é a forma
 * que não deixa perder o lugar.
 */
.passos {
  margin: 4px 0 0;
  padding-left: 20px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--texto);
}

.passos li { margin-bottom: 5px; }

.passos li::marker { color: var(--suave); }

/*
 * A dica que não pode ser lida por cima.
 *
 * «Os dois primeiros passos precisam de internet» é a frase que decide se a
 * pessoa termina a instalação no sofá ou descobre no estacionamento, com o
 * carro ligado, que não dá para baixar nada dali.
 */
.campo-dica-forte {
  color: var(--texto);
  font-weight: 600;
}

/* ----------------------------------------------------------------- falhas */

.falha-codigo {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: .5px;
}

/* ------------------------------------------------------------ valor/linha */

.detalhe-linhas { display: flex; flex-direction: column; }

.linha-valor {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--borda);
}

.linha-valor:last-child { border-bottom: 0; }
.linha-rotulo { color: var(--suave); font-size: 14px; }
.linha-numero { font-weight: 650; font-variant-numeric: tabular-nums; text-align: right; }

/* --------------------------------------------------------------- gráfico */

.grafico-caixa { display: flex; flex-direction: column; gap: 6px; }
.grafico { width: 100%; height: auto; display: block; }
.grafico-grade { stroke: var(--borda); stroke-width: 1; }
.grafico-linha { fill: none; stroke: var(--principal); stroke-width: 1.8; stroke-linejoin: round; }

.grafico-eixo {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  color: var(--suave);
}

/* --------------------------------------------------------------- registro */

.registro {
  background: var(--superficie-2);
  border-radius: 10px;
  padding: 10px;
  max-height: 55vh;
  overflow-y: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  line-height: 1.5;
}

.registro-linha { margin: 0; white-space: pre-wrap; word-break: break-all; }
.registro-saida { color: var(--principal); }
.registro-entrada { color: var(--texto); }

/* ------------------------------------------------------------------ vazio */

.vazio {
  text-align: center;
  padding: 18px 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.vazio-mensagem { margin: 0; font-weight: 600; }
.vazio-detalhe { margin: 0; font-size: 13.5px; color: var(--suave); }

/* ------------------------------------------------------------------ barra */

.barra {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 6;
  display: flex;
  background: var(--superficie);
  border-top: 1px solid var(--borda);
  padding-bottom: env(safe-area-inset-bottom);
}

.barra-item {
  position: relative;
  flex: 1;
  border: 0;
  background: none;
  color: var(--suave);
  font: inherit;
  font-size: 11.5px;
  height: var(--barra-altura);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  cursor: pointer;
}

.barra-icone { font-size: 21px; line-height: 1; }
.barra-item.ativa { color: var(--principal); font-weight: 650; }

.barra-pastilha {
  position: absolute;
  top: 8px;
  left: 50%;
  margin-left: 6px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--perigo);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

/* ------------------------------------------------------ avisos e diálogos */

.avisos {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(var(--barra-altura) + 12px + env(safe-area-inset-bottom));
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}

.aviso {
  padding: 12px 14px;
  border-radius: 12px;
  box-shadow: var(--sombra);
  font-size: 14.5px;
  background: var(--superficie);
  color: var(--texto);
  border-left: 4px solid var(--principal);
  animation: entrar .18s ease-out;
}

.aviso-ok { border-left-color: var(--ok); }
.aviso-erro { border-left-color: var(--perigo); }
.aviso-atencao { border-left-color: var(--atencao); }
.aviso.saindo { opacity: 0; transition: opacity .2s; }

@keyframes entrar {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

.dialogo {
  border: 0;
  border-radius: 16px;
  padding: 0;
  width: min(94vw, 420px);
  background: var(--superficie);
  color: var(--texto);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .35);
}

.dialogo::backdrop { background: rgba(0, 0, 0, .55); }

.dialogo-corpo { padding: 18px; display: flex; flex-direction: column; gap: 12px; }
.dialogo-titulo { margin: 0; font-size: 18px; }
.dialogo-texto { margin: 0; color: var(--suave); font-size: 14.5px; line-height: 1.45; }
.dialogo-botoes { display: flex; flex-direction: column; gap: 8px; }

.folha-topo { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.fechar { min-height: 44px; padding: 8px 14px; }

/* ------------------------------------------------------------ atualização */

.atualizacao {
  margin: 0;
  padding: 10px 12px;
  background: var(--atencao-fraco);
  color: var(--atencao);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 14px;
}

/* ------------------------------------------------------------- telas largas */

/*
 * O aplicativo nasceu para celular em pé. Num tablet ou no computador — que é
 * onde o adaptador USB funciona — esticar os cartões para 1200 px deixaria
 * linhas de texto impossíveis de acompanhar, então a coluna só cresce até onde
 * ainda se lê, e os ponteiros ganham o espaço que sobra.
 */
/*
 * Tela baixa: celular deitado, que é como este aplicativo é usado.
 *
 * Sessenta e quatro pixels de barra de abas são um sexto da altura útil de um
 * celular em paisagem — espaço que sai inteiro do velocímetro. Cinquenta ainda
 * dão alvo de sobra para o dedo e devolvem quatorze pixels a quem precisa.
 */
@media (max-height: 540px) {
  :root {
    --barra-altura: 50px;
    --topo-altura: 34px;
  }

  .topo-titulo { font-size: 16px; }
  .barra-icone { font-size: 18px; }
  .barra-item { font-size: 10px; }

  /*
   * A folha de ajustes em duas colunas.
   *
   * Empilhada, ela tem quase o dobro da altura de um celular deitado — e o que
   * fica abaixo da dobra é justamente o que se veio fazer: os botões de
   * tamanho apareciam cortados no rodapé. Numa tela baixa e larga, largura é o
   * que sobra, então os campos vão lado a lado e a folha inteira cabe sem
   * rolar. As dicas e a coluna de botões atravessam as duas, porque quebradas
   * ao meio não se leem.
   */
  .folha > .tela {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: 10px 16px;
  }

  .folha > .tela > .coluna-botoes { grid-column: 1 / -1; }

  /*
   * Numa tela baixa, o parágrafo solto de explicação sai.
   *
   * Não por desprezo pela explicação — este aplicativo vive dela —, mas porque
   * ali ela custa oitenta pixels de uma folha que não cabe, e o que sai em
   * troca é um botão inalcançável. As dicas curtas, coladas a cada campo,
   * ficam: são as que respondem no momento da dúvida.
   */
  .folha > .tela > .campo-dica { display: none; }

  .folha .campo-dica { font-size: 11.5px; line-height: 1.35; }
  .folha.dialogo-corpo { padding: 14px; gap: 10px; }

  .folha > .tela > .coluna-botoes { flex-direction: row; flex-wrap: wrap; }
  .folha > .tela > .coluna-botoes > .botao { flex: 1 1 30%; }
}

@media (min-width: 720px) {
  .conteudo { max-width: 720px; margin: 0 auto; }
  .medidores { grid-template-columns: repeat(2, 1fr); }
  .dialogo-botoes { flex-direction: row-reverse; }
  .dialogo-botoes .botao { flex: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .medidor-arco { transition: none; }
  .aviso { animation: none; }
}
