/* Painel de frota. CSS puro, sem build (ADR 5).
   Unidades relativas em texto e espaco para o painel aguentar zoom e, depois, telas
   pequenas — mobile nao e requisito da v1, mas nada aqui impede. */

:root {
  --fundo: #f4f5f7;
  --cartao: #fff;
  --texto: #15181d;
  --texto-fraco: #555b66;
  --borda: #c8ccd4;
  --acento: #1a4fd6;
  /* Texto que fica *em cima* do acento. No tema escuro o acento e claro, e branco sobre
     ele da 2.5:1 — abaixo do piso de 4.5:1. Por isso a cor e uma variavel, nao #fff. */
  --sobre-acento: #fff;

  /* Os 4 estados de idade_s do contrato (API.md, ponto 2). Cores escolhidas com
     contraste >= 4.5:1 contra branco, porque elas tambem viram texto na tabela. */
  --fresco: #0a7d3c;
  --recente: #8a6100;
  --parado: #a23b00;
  --sem-sinal: #6b7280;
}

@media (prefers-color-scheme: dark) {
  :root {
    --fundo: #15181d;
    --cartao: #1e232b;
    --texto: #eef1f5;
    --texto-fraco: #aab2bf;
    --borda: #3a4150;
    --acento: #7aa2ff;
    --sobre-acento: #10131a;
    --fresco: #46d07f;
    --recente: #e3b53f;
    --parado: #ff8b50;
    --sem-sinal: #9aa3b0;
  }
}

* { box-sizing: border-box; }

/* O atributo `hidden` vale menos que qualquer regra de display com seletor proprio
   (`#app { display: flex }` ganharia dele). Como a troca de tela e toda por `hidden`,
   esta linha e o que faz a guarda de rota funcionar de verdade. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font: 1rem/1.4 system-ui, sans-serif;
  color: var(--texto);
  background: var(--fundo);
  /* nada de scroll horizontal no body */
  overflow-x: hidden;
}

/* Foco sempre visivel, em tudo. Nunca `outline: none`. */
:focus-visible {
  outline: 3px solid var(--acento);
  outline-offset: 2px;
}

/* Alvo de toque minimo de 44px em todo controle. */
button, input, select {
  font: inherit;
  min-height: 2.75rem;
  border-radius: .375rem;
  border: 1px solid var(--borda);
}

button {
  min-width: 2.75rem;
  padding: 0 .9rem;
  background: var(--cartao);
  color: var(--texto);
  cursor: pointer;
}
button:hover:not(:disabled) { border-color: var(--acento); }
button:disabled { opacity: .5; cursor: default; }

input {
  width: 100%;
  padding: 0 .6rem;
  background: var(--cartao);
  color: var(--texto);
}

.sr {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ===== Login ===== */

#login {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 1rem;
}

.cartao {
  width: min(22rem, 100%);
  padding: 1.5rem;
  background: var(--cartao);
  border: 1px solid var(--borda);
  border-radius: .75rem;
}
.cartao h1 { margin: 0 0 1rem; font-size: 1.5rem; }
.cartao button[type="submit"] { width: 100%; background: var(--acento); color: var(--sobre-acento); border-color: transparent; }

.campo { margin: 0 0 1rem; }
.campo label { display: block; margin-bottom: .25rem; color: var(--texto-fraco); }

.erro { margin: 1rem 0 0; color: var(--parado); min-height: 1.4em; }
.erro:empty { margin: 0; }

/* ===== Layout do app ===== */

#app { display: flex; flex-direction: column; height: 100vh; }

header {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .5rem .75rem;
  background: var(--cartao);
  border-bottom: 1px solid var(--borda);
}
header nav { display: flex; gap: .25rem; }
header #btn-senha { margin-left: auto; }
/* aria-current marca a secao ativa: um atributo em vez de uma classe so para isso */
header [aria-current="page"] { background: var(--acento); color: var(--sobre-acento); border-color: transparent; }

.status { color: var(--texto-fraco); font-size: .875rem; }
.status.falha { color: var(--parado); }
.recado { color: var(--fresco); font-size: .875rem; }
.recado:empty { display: none; }

/* Botao do veiculo fora do grupo. Cor de aviso com contraste >= 4.5:1 nos dois temas. */
.aviso { color: var(--parado); border-color: currentColor; font-size: .875rem; }

#secao-mapa { position: relative; flex: 1; min-height: 20rem; }
#mapa { position: absolute; inset: 0; }

#legenda {
  position: absolute;
  right: .75rem; bottom: 1.5rem;
  z-index: 500; /* acima dos panes do Leaflet (400) e abaixo dos popups (700) */
  margin: 0;
  padding: .5rem .75rem;
  list-style: none;
  font-size: .8125rem;
  background: var(--cartao);
  border: 1px solid var(--borda);
  border-radius: .5rem;
}
#legenda li { display: flex; align-items: center; gap: .4rem; }
.bolinha { width: .7rem; height: .7rem; border-radius: 50%; display: inline-block; }
.bolinha.fresco { background: var(--fresco); }
.bolinha.recente { background: var(--recente); }
.bolinha.parado { background: var(--parado); }
.bolinha.sem-sinal { background: var(--sem-sinal); }

/* ===== Icone do veiculo =====
   O marcador e um divIcon: SVG do carrinho + rotulo. O rotulo e filho do icone, nao
   tooltip do Leaflet, porque assim quem decide se ele aparece e o CSS (:hover, :focus e
   a classe .movendo) — sem JS ligando e desligando tooltip a cada poll. */

.carro {
  width: 2.75rem;   /* 44px: alvo de toque, mesmo com o desenho menor no meio */
  height: 2.75rem;
  display: grid;
  place-items: center;
  /* Leaflet posiciona o marcador por `transform: translate3d(...)` neste mesmo elemento.
     Transicionar o transform e o que faz o carro deslizar da posicao antiga para a nova
     em vez de saltar. 60s entre polls, 900ms de deslize. */
  transition: transform 900ms linear;
}
/* No zoom o Leaflet reposiciona tudo de uma vez; animar isso arrastaria os carros atras
   do mapa. Durante a animacao de zoom ele poe .leaflet-zoom-anim no container. */
.leaflet-zoom-anim .carro,
.leaflet-container.sem-desliza .carro { transition: none; }

.carro-svg {
  width: 1.75rem; height: 1.75rem;
  /* `direcao` (0..359) vem no payload; rotacao fica no filho porque o transform do pai e
     do Leaflet. */
  transform: rotate(var(--direcao, 0deg));
  transition: transform 900ms linear;
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / .5));
}
.carro-svg .corpo { fill: var(--cor); stroke: #fff; stroke-width: 1.1; }
.carro-svg .vidro { fill: #fff; opacity: .85; }

.carro.fresco { --cor: var(--fresco); }
.carro.recente { --cor: var(--recente); }
.carro.parado { --cor: var(--parado); }
/* Sem sinal: esmaecido de proposito. Um GPS de 101 dias nao pode parecer carro ativo. */
.carro.sem-sinal { --cor: var(--sem-sinal); }
.carro.sem-sinal .carro-svg { opacity: .45; }

.rotulo {
  position: absolute;
  top: 2.4rem;
  left: 50%;
  transform: translateX(-50%);
  padding: .1rem .35rem;
  font-size: .75rem;
  line-height: 1.3;
  white-space: nowrap;
  text-align: center;
  color: #fff;
  background: rgb(0 0 0 / .78);  /* branco sobre isto passa de 4.5:1 */
  border-radius: .25rem;
  pointer-events: none;          /* o rotulo nao rouba o clique do marcador */
  opacity: 0;
  transition: opacity 150ms linear;
}
.rotulo .placa { font-weight: 700; }
.rotulo .modelo { display: block; font-weight: 400; opacity: .9; }

/* Requisito do Alvaro: rotulo no hover E enquanto o veiculo se movimenta.
   `.movendo` entra quando velocidade > 0. */
.carro.movendo .rotulo { opacity: 1; }

/* `.colide` vem da passada de colisao em app.js: o rotulo fixo deste carro cairia em cima
   de outro ja colocado. Esconde o fixo, nunca o do hover/foco — por isso as duas regras
   abaixo vem depois e precisam de especificidade maior que `.carro.movendo.colide`. */
.carro.movendo.colide .rotulo { opacity: 0; }
.carro.movendo.colide:hover .rotulo,
.carro.movendo.colide:focus-visible .rotulo,
.carro:hover .rotulo,
.carro:focus-visible .rotulo { opacity: 1; }

/* O marcador com rotulo visivel sobe acima dos vizinhos para o texto nao ficar atras
   de outro carrinho. */
.carro:hover, .carro:focus-visible { z-index: 1000 !important; }

/* ===== Popup ===== */

.popup dl { display: grid; grid-template-columns: auto 1fr; gap: .15rem .5rem; margin: .4rem 0 0; }
.popup dt { color: var(--texto-fraco); }
.popup dd { margin: 0; }
.popup h2 { margin: 0; font-size: 1rem; }

/* ===== Logs ===== */

#secao-logs { flex: 1; overflow: auto; padding: .75rem; }

.barra-paginacao { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin-bottom: .75rem; }

#tabela-logs { width: 100%; border-collapse: collapse; font-size: .875rem; }
#tabela-logs th, #tabela-logs td { padding: .4rem .5rem; text-align: left; border-bottom: 1px solid var(--borda); vertical-align: top; }
#tabela-logs thead th { position: sticky; top: 0; background: var(--cartao); }
#tabela-logs tbody tr.com-erro { background: rgb(162 59 0 / .09); }
#tabela-logs .num { text-align: right; font-variant-numeric: tabular-nums; }
/* Os contadores vem um por linha (\n no textContent) e nao devem quebrar no meio do
   rotulo; a secao tem overflow proprio, entao a largura extra nao vaza para o body. */
#tabela-logs .cont { white-space: pre; }
#tabela-logs .quando { white-space: nowrap; }
/* A coluna de erros e a razao desta tela existir: largura para a mensagem caber. */
#tabela-logs td:last-child { min-width: 22rem; }
.mensagens { margin: .25rem 0 0; padding-left: 1.1rem; color: var(--parado); }
.divergencias { margin: .25rem 0 0; padding-left: 1.1rem; color: var(--texto-fraco); }
.tag-simulacao { font-size: .75rem; border: 1px solid var(--borda); border-radius: .25rem; padding: 0 .25rem; }

/* ===== Usuarios ===== */

#secao-usuarios { flex: 1; overflow: auto; padding: .75rem; }

#tabela-usuarios { width: 100%; border-collapse: collapse; }
#tabela-usuarios th, #tabela-usuarios td {
  padding: .4rem .5rem; text-align: left; border-bottom: 1px solid var(--borda);
}
#tabela-usuarios thead th { position: sticky; top: 0; background: var(--cartao); }
/* Os botoes de linha mantem os 44px do resto; em tela estreita eles empilham em vez de
   empurrar a tabela para fora (nada de scroll horizontal no body). */
#tabela-usuarios .acoes { display: flex; flex-wrap: wrap; gap: .4rem; }
.perigo { color: var(--parado); border-color: currentColor; }

/* ===== Dialogos ===== */

dialog {
  width: min(24rem, calc(100vw - 2rem));
  padding: 1.25rem;
  color: var(--texto);
  background: var(--cartao);
  border: 1px solid var(--borda);
  border-radius: .75rem;
}
dialog::backdrop { background: rgb(0 0 0 / .5); }
dialog h2 { margin: 0 0 1rem; font-size: 1.25rem; }
dialog select { width: 100%; padding: 0 .5rem; background: var(--cartao); color: var(--texto); }
dialog small { display: block; margin-top: .25rem; color: var(--texto-fraco); font-size: .8125rem; }
.acoes-dialogo { display: flex; justify-content: flex-end; gap: .5rem; flex-wrap: wrap; }
.acoes-dialogo .principal { background: var(--acento); color: var(--sobre-acento); border-color: transparent; }

/* ===== Movimento ===== */

@media (prefers-reduced-motion: reduce) {
  /* Quem pediu menos movimento recebe o salto: a posicao continua correta, so nao desliza. */
  .carro, .carro-svg, .rotulo, .leaflet-fade-anim .leaflet-tile,
  .leaflet-zoom-anim .leaflet-zoom-animated { transition: none !important; }
}
