/* ==========================================================================
   Garagem — folha de estilo base
   Identidade visual da seção 3 do spec.

   Direção: instrumento, não brochura. Tons frios, superfícies quietas,
   estrutura por espaço e tonalidade — bordas discretas, sem sombras
   dramáticas. O único elemento escuro do app é o mostrador de hodômetro,
   que é a assinatura visual do produto.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* --- Paleta oficial (seção 3 do spec) --------------------------------- */
  --azul-aco: #2B6CA8;
  --grafite: #2D3748;
  --cinza-claro: #F1F4F7;
  --laranja-sinal: #E8752C;

  /* Derivadas da paleta — mesma matiz, só a luminosidade muda.
     Nunca introduzir uma quinta matiz. */
  --azul-aco-escuro: #235887;
  --azul-aco-claro: #E7EFF7;
  --grafite-claro: #3C4859;
  --laranja-sinal-fraco: #FCEFE5;

  /* --- Superfícies ------------------------------------------------------- */
  --canvas: var(--cinza-claro);      /* fundo da aplicação */
  --painel: #FFFFFF;                 /* cartões, listas, barras */
  --painel-elevado: #FFFFFF;         /* popovers e sheets (sobem por sombra) */
  --instrumento: var(--grafite);     /* mostrador escuro — assinatura */
  --campo: #FBFCFD;                  /* inputs: levemente recuados */

  /* --- Texto: quatro níveis ---------------------------------------------- */
  --texto: var(--grafite);
  --texto-secundario: #55617A;
  --texto-terciario: #7B8698;
  --texto-mudo: #A3ABBA;
  --texto-invertido: #F4F7FA;
  --texto-invertido-fraco: #9FAEC2;

  /* --- Bordas: baixa opacidade, some quando não se procura por ela ------- */
  --borda: rgba(45, 55, 72, 0.10);
  --borda-suave: rgba(45, 55, 72, 0.06);
  --borda-forte: rgba(45, 55, 72, 0.18);
  --anel-foco: rgba(43, 108, 168, 0.35);

  /* --- Semânticas — cor só quando comunica estado ------------------------ */
  --alerta: var(--laranja-sinal);      /* vencido / vencendo */
  --alerta-fundo: var(--laranja-sinal-fraco);
  --ok: #2E7D5B;
  --ok-fundo: #E6F2EC;
  --erro: #C0392B;
  --erro-fundo: #FBEAE7;

  /* --- Tipografia (seção 3 do spec) -------------------------------------- */
  --fonte-titulo: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
  --fonte-corpo: 'Inter', 'Segoe UI', system-ui, sans-serif;

  /* Escala 1.25 sobre base 15px, arredondada ao pixel */
  --t-legenda: 0.6875rem; /* 11px — labels de instrumento, em caixa alta */
  --t-mini: 0.8125rem;    /* 13px — metadados */
  --t-corpo: 0.9375rem;   /* 15px */
  --t-h4: 1.0625rem;      /* 17px */
  --t-h3: 1.25rem;        /* 20px */
  --t-h2: 1.5rem;         /* 24px */
  --t-h1: 1.875rem;       /* 30px */

  /* --- Espaçamento: base 4px --------------------------------------------- */
  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-5: 20px;
  --e-6: 24px;
  --e-8: 32px;
  --e-10: 40px;
  --e-12: 48px;

  /* Densidade: oficina, não brochura. Cartão respira em 16px, não 24. */
  --pad-cartao: var(--e-4);
  --pad-secao: var(--e-6);

  /* --- Raio: escala, não valor único ------------------------------------- */
  --r-pequeno: 6px;   /* inputs, botões, chips */
  --r-medio: 10px;    /* cartões, mostradores */
  --r-grande: 16px;   /* sheets, modais */
  --r-total: 999px;   /* pílulas */

  /* --- Elevação: 1px ring + duas camadas suaves -------------------------- */
  --elev-0: 0 0 0 1px var(--borda);
  --elev-1: 0 0 0 1px rgba(45, 55, 72, 0.06),
            0 1px 2px -1px rgba(45, 55, 72, 0.08),
            0 2px 4px rgba(45, 55, 72, 0.04);
  --elev-2: 0 0 0 1px rgba(45, 55, 72, 0.06),
            0 4px 12px -4px rgba(45, 55, 72, 0.14),
            0 8px 24px -8px rgba(45, 55, 72, 0.10);

  /* --- Movimento: sentido, não assistido --------------------------------- */
  --saida: cubic-bezier(0.23, 1, 0.32, 1);
  --entre-tela: cubic-bezier(0.77, 0, 0.175, 1);
  --dur-toque: 120ms;
  --dur-popover: 180ms;
  --dur-sheet: 260ms;

  /* --- Layout ------------------------------------------------------------ */
  --largura-max: 640px;   /* PWA mobile-first: conteúdo não vira planilha */
  --altura-header: 68px;
  --altura-nav: 60px;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-top: env(safe-area-inset-top, 0px);
}

/* --------------------------------------------------------------------------
   2. Reset e base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100dvh;
  background: var(--canvas);
  color: var(--texto);
  font-family: var(--fonte-corpo);
  font-size: var(--t-corpo);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--fonte-titulo);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em; /* títulos apertam opticamente */
  text-wrap: balance;
}

h1 { font-size: var(--t-h1); letter-spacing: -0.02em; }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); letter-spacing: -0.01em; }

p, li {
  text-wrap: pretty;
}

a {
  color: var(--azul-aco);
  text-decoration-color: rgba(43, 108, 168, 0.3);
  text-underline-offset: 2px;
}

a:hover {
  text-decoration-color: currentColor;
}

img, svg {
  display: block;
  max-width: 100%;
}

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

fieldset {
  min-width: 0;
  padding: 0;
  border: 0;
}

legend {
  padding: 0;
}

/* `hidden` tem de vencer qualquer `display` declarado depois dele — vários
   componentes deste projeto alternam visibilidade pelo atributo. */
[hidden] {
  display: none !important;
}

/* Foco visível e consistente em tudo que recebe teclado. */
:focus-visible {
  outline: 2px solid var(--anel-foco);
  outline-offset: 2px;
  border-radius: var(--r-pequeno);
}

/* Qualquer número dinâmico usa largura fixa — nada de layout dançando. */
.num,
.mostrador__valor,
.instrumento__valor {
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   3. Utilitários de texto
   -------------------------------------------------------------------------- */

.legenda {
  font-size: var(--t-legenda);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--texto-terciario);
}

.mini { font-size: var(--t-mini); color: var(--texto-secundario); }
.mudo { color: var(--texto-mudo); }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   4. Casca do app
   -------------------------------------------------------------------------- */

.app {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100dvh;
}

.app__conteudo {
  width: 100%;
  max-width: var(--largura-max);
  margin-inline: auto;
  padding: var(--e-5) var(--e-4) var(--e-10);
}

/* --- Header: mesma cor do canvas. Não fragmentar a tela em dois mundos. -- */
.header {
  position: sticky;
  top: 0;
  z-index: 20;
  padding-top: var(--safe-top);
  background: var(--canvas);
  border-bottom: 1px solid var(--borda-suave);
}

.header__interno {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  width: 100%;
  max-width: var(--largura-max);
  min-height: var(--altura-header);
  margin-inline: auto;
  padding: var(--e-2) var(--e-4);
}

.header__marca {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h4);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--grafite);
}

/* --------------------------------------------------------------------------
   5. Seletor de veículo ativo — o mostrador (assinatura)

   Placa grafite com o km corrente em dígitos tabulares. É o único bloco
   escuro do app; ele fixa o veículo ativo e a leitura de hodômetro num só
   objeto, do jeito que um painel faz.
   -------------------------------------------------------------------------- */

.mostrador {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  flex: 1;
  min-width: 0;
  padding: var(--e-2) var(--e-3);
  background: var(--instrumento);
  color: var(--texto-invertido);
  border: 0;
  border-radius: var(--r-medio);
  text-align: left;
  cursor: pointer;
  transition: transform var(--dur-toque) var(--saida),
              background-color var(--dur-toque) var(--saida);
}

.mostrador:hover { background: var(--grafite-claro); }
.mostrador:active { transform: scale(0.985); }

.mostrador__identificacao {
  flex: 1;
  min-width: 0;
}

.mostrador__apelido {
  display: block;
  font-family: var(--fonte-titulo);
  font-size: var(--t-corpo);
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mostrador__placa {
  display: block;
  font-size: var(--t-legenda);
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--texto-invertido-fraco);
  font-variant-numeric: tabular-nums;
}

.mostrador__leitura {
  text-align: right;
  flex-shrink: 0;
}

.mostrador__valor {
  display: block;
  font-family: var(--fonte-titulo);
  font-size: var(--t-h3);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.mostrador__unidade {
  display: block;
  font-size: var(--t-legenda);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texto-invertido-fraco);
}

.mostrador__seta {
  flex-shrink: 0;
  color: var(--texto-invertido-fraco);
  transition: transform var(--dur-popover) var(--saida);
}

.mostrador[aria-expanded='true'] .mostrador__seta {
  transform: rotate(180deg);
}

/* --- Menu de troca de veículo ----------------------------------------------

   Popover ancorado no mostrador, não sheet: trocar de veículo é escolha rápida
   de um entre poucos, e cobrir a tela para isso seria desproporcional. Sobe por
   --elev-2 sobre --painel-elevado, os tokens reservados para esta camada.
   -------------------------------------------------------------------------- */

.seletor {
  position: relative;
  flex: 1;
  min-width: 0;
}

.seletor__menu {
  position: absolute;
  top: calc(100% + var(--e-2));
  right: 0;
  left: 0;
  z-index: 30;
  overflow: hidden;
  background: var(--painel-elevado);
  border-radius: var(--r-medio);
  box-shadow: var(--elev-2);
  animation: menu-abre var(--dur-popover) var(--saida) both;
}

@keyframes menu-abre {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

.seletor__lista {
  list-style: none;
  padding: var(--e-1);
  margin: 0;
  max-height: 50dvh;
  overflow-y: auto;
}

.seletor__item {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  width: 100%;
  min-height: 48px;
  padding: var(--e-2);
  background: transparent;
  border: 0;
  border-radius: var(--r-pequeno);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-toque) var(--saida);
}

.seletor__item:hover { background: var(--cinza-claro); }

.seletor__item[aria-checked='true'] .seletor__nome { color: var(--azul-aco); }

.seletor__marca {
  display: grid;
  place-items: center;
  width: 18px;
  flex-shrink: 0;
  color: var(--azul-aco);
}

.seletor__marca svg { stroke: currentColor; fill: none; }

.seletor__texto {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.seletor__nome {
  font-family: var(--fonte-titulo);
  font-size: var(--t-corpo);
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.seletor__detalhe {
  font-size: var(--t-legenda);
  color: var(--texto-terciario);
}

.seletor__km {
  flex-shrink: 0;
  font-family: var(--fonte-titulo);
  font-size: var(--t-mini);
  font-weight: 500;
  color: var(--texto-secundario);
}

.seletor__rodape {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  min-height: 48px;
  padding: var(--e-2) var(--e-3);
  border-top: 1px solid var(--borda-suave);
  color: var(--azul-aco);
  font-size: var(--t-mini);
  font-weight: 500;
  text-decoration: none;
}

.seletor__rodape:hover { background: var(--azul-aco-claro); }

.seletor__rodape-icone {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  stroke-width: 1.75;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------------------
   6. Navegação inferior

   Tab bar, não sidebar: o uso real é em pé, no posto ou na oficina, com uma
   mão. Quatro destinos primários + "Mais" para os módulos restantes.
   -------------------------------------------------------------------------- */

.nav {
  position: sticky;
  bottom: 0;
  z-index: 20;
  padding-bottom: var(--safe-bottom);
  background: var(--painel);
  border-top: 1px solid var(--borda);
}

.nav__lista {
  display: flex;
  width: 100%;
  max-width: var(--largura-max);
  margin-inline: auto;
  list-style: none;
  padding: 0;
}

.nav__item { flex: 1; }

.nav__link {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: var(--altura-nav); /* alvo de toque acima de 44px */
  padding: var(--e-2) var(--e-1);
  color: var(--texto-terciario);
  font-size: var(--t-legenda);
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: color var(--dur-toque) var(--saida);
}

.nav__link:hover { color: var(--texto-secundario); }
.nav__link:active { transform: scale(0.96); }

.nav__link[aria-current='page'] {
  color: var(--azul-aco);
}

.nav__icone {
  width: 22px;
  height: 22px;
  stroke: currentColor;
  stroke-width: 1.75;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------------------
   7. Cartões e placas de instrumento
   -------------------------------------------------------------------------- */

.cartao {
  background: var(--painel);
  border-radius: var(--r-medio);
  box-shadow: var(--elev-1);
  padding: var(--pad-cartao);
}

/* Raio concêntrico: filho = pai − padding. */
.cartao > .cartao__interno {
  border-radius: calc(var(--r-medio) - var(--pad-cartao) / 2);
}

.cartao__cabecalho {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
  margin-bottom: var(--e-3);
}

/* Placa de instrumento: label demovido em caixa alta, valor lidera. */
.instrumento {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
}

.instrumento__rotulo {
  font-size: var(--t-legenda);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--texto-terciario);
}

.instrumento__valor {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h2);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--texto);
}

.instrumento__nota {
  font-size: var(--t-mini);
  color: var(--texto-secundario);
}

/* Unidade acompanha o valor, meia altura e demovida: "45.000 km" tem de ler
   como uma leitura só, não como duas informações. */
.instrumento__unidade {
  margin-left: 0.28em;
  font-size: var(--t-mini);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--texto-terciario);
}

.instrumento--alerta .instrumento__valor { color: var(--alerta); }

/* Duas leituras lado a lado num cartão estreito (km previsto + data prevista).
   24px em duas colunas quebraria a data em telas de 360px; 20px continua sendo
   leitura de instrumento e cabe. Só o tamanho muda — fonte, peso e tabular
   permanecem, senão deixa de ser a mesma peça. */
.instrumento--compacto .instrumento__valor {
  font-size: var(--t-h3);
  letter-spacing: -0.015em;
}

/* --------------------------------------------------------------------------
   8. Botões
   -------------------------------------------------------------------------- */

.botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  min-height: 44px;
  padding: 0 var(--e-4);
  border: 1px solid transparent;
  border-radius: var(--r-pequeno);
  font-family: var(--fonte-corpo);
  font-size: var(--t-corpo);
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--dur-toque) var(--saida),
              border-color var(--dur-toque) var(--saida),
              transform var(--dur-toque) var(--saida);
}

.botao:active { transform: scale(0.97); }

.botao:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

.botao--primario {
  background: var(--azul-aco);
  color: #FFFFFF;
}
.botao--primario:hover:not(:disabled) { background: var(--azul-aco-escuro); }

.botao--secundario {
  background: var(--painel);
  color: var(--texto);
  border-color: var(--borda-forte);
}
.botao--secundario:hover:not(:disabled) { background: var(--cinza-claro); }

.botao--fantasma {
  background: transparent;
  color: var(--azul-aco);
}
.botao--fantasma:hover:not(:disabled) { background: var(--azul-aco-claro); }

/* Ação destrutiva: vermelho de `--erro`, nunca o laranja. Laranja neste
   projeto é vencimento de manutenção e só — usá-lo aqui apagaria a única
   coisa que ele significa. */
.botao--destrutivo {
  background: var(--erro);
  color: #FFFFFF;
}
.botao--destrutivo:hover:not(:disabled) { background: #A5322A; }

/* Variante fantasma da mesma ideia, para a linha de ações de um cartão. */
.botao--perigo { color: var(--erro); }
.botao--perigo:hover:not(:disabled) { background: var(--erro-fundo); }

/* Ação secundária dentro de cartão: rótulo e recuo menores, mas os 44px de
   altura ficam — a regra de alvo de toque não abre exceção por hierarquia. */
.botao--pequeno {
  padding: 0 var(--e-3);
  font-size: var(--t-mini);
  gap: var(--e-1);
}

.botao--bloco { width: 100%; }

.botao__icone {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  stroke: currentColor;
  stroke-width: 1.9;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Botão só de ícone — fechar sheet. Quadrado, alvo de 44px mantido. */
.botao-icone {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-right: calc(var(--e-2) * -1);
  background: transparent;
  border: 0;
  border-radius: var(--r-pequeno);
  color: var(--texto-terciario);
  cursor: pointer;
  transition: background-color var(--dur-toque) var(--saida),
              color var(--dur-toque) var(--saida);
}

.botao-icone:hover {
  background: var(--cinza-claro);
  color: var(--texto);
}

.botao-icone svg { stroke: currentColor; fill: none; }

/* --------------------------------------------------------------------------
   9. Campos de formulário

   Inputs são recuados: fundo levemente mais escuro que a superfície,
   sinalizando "escreva aqui" sem borda pesada.
   -------------------------------------------------------------------------- */

.campo {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
}

.campo__rotulo {
  font-size: var(--t-mini);
  font-weight: 500;
  color: var(--texto-secundario);
}

.campo__controle {
  width: 100%;
  min-height: 44px;
  padding: var(--e-2) var(--e-3);
  background: var(--campo);
  border: 1px solid var(--borda-forte);
  border-radius: var(--r-pequeno);
  transition: border-color var(--dur-toque) var(--saida),
              box-shadow var(--dur-toque) var(--saida);
}

.campo__controle::placeholder { color: var(--texto-mudo); }

.campo__controle:focus {
  outline: none;
  border-color: var(--azul-aco);
  box-shadow: 0 0 0 3px var(--anel-foco);
}

.campo__controle:disabled {
  background: var(--cinza-claro);
  color: var(--texto-mudo);
  cursor: not-allowed;
}

.campo__ajuda { font-size: var(--t-mini); color: var(--texto-terciario); }
.campo__erro { font-size: var(--t-mini); color: var(--erro); }

/* Aviso que NÃO bloqueia o envio — hoje, km de manutenção lançado fora de
   ordem cronológica.

   Fica um degrau acima de `.campo__ajuda` e um abaixo de `.campo__erro`: ganha
   peso e o texto principal, mas nenhuma cor semântica. Vermelho seria mentira
   (não impede nada) e laranja gastaria a única coisa que o laranja significa
   neste app, que é vencimento de manutenção. Hierarquia por peso, não por
   matiz. */
.campo__nota {
  font-size: var(--t-mini);
  font-weight: 500;
  color: var(--texto-secundario);
}

.campo--invalido .campo__controle {
  border-color: var(--erro);
}

.campo__obrigatorio {
  color: var(--erro);
  font-weight: 600;
}

/* Dois campos curtos na mesma linha (marca/modelo, ano/km). Em telas muito
   estreitas volta a empilhar: 44px de alvo importa mais que a linha. */
.campo-par {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--e-3);
}

@media (max-width: 360px) {
  .campo-par { grid-template-columns: 1fr; }
}

/* Placa lê como placa: caixa alta, espaçada, na fonte de instrumento. */
.campo__controle--placa {
  font-family: var(--fonte-titulo);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* --- Segmentado: escolha de tipo de veículo --------------------------------

   Quatro opções fixas e mutuamente exclusivas, todas visíveis: um <select>
   esconderia a lista atrás de um toque e perderia o ícone, que é o que faz a
   escolha ser reconhecida sem ler.
   -------------------------------------------------------------------------- */

.segmentado__opcoes {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--e-1);
  margin-top: var(--e-1);
}

.segmentado__opcao {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e-1);
  min-height: 68px;
  padding: var(--e-2) var(--e-1);
  background: var(--campo);
  border: 1px solid var(--borda-forte);
  border-radius: var(--r-pequeno);
  font-size: var(--t-legenda);
  font-weight: 500;
  color: var(--texto-secundario);
  text-align: center;
  cursor: pointer;
  transition: background-color var(--dur-toque) var(--saida),
              border-color var(--dur-toque) var(--saida),
              color var(--dur-toque) var(--saida);
}

/* O radio continua no DOM e recebe teclado; só não é desenhado. */
.segmentado__opcao input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.segmentado__icone {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  stroke-width: 1.6;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.segmentado__opcao:hover { background: var(--painel); }

.segmentado__opcao:has(input:checked) {
  background: var(--azul-aco-claro);
  border-color: var(--azul-aco);
  color: var(--azul-aco-escuro);
}

.segmentado__opcao:has(input:focus-visible) {
  outline: 2px solid var(--anel-foco);
  outline-offset: 2px;
}

/* --- Escolha de foto ------------------------------------------------------- */

.foto-escolha {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-top: var(--e-1);
}

.foto-escolha__previa {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 72px;
  height: 72px;
  overflow: hidden;
  background: var(--campo);
  border-radius: var(--r-medio);
  box-shadow: var(--elev-0);
  color: var(--texto-mudo);
}

.foto-escolha__previa--cheia { background: var(--grafite); }

.foto-escolha__previa img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.foto-escolha__icone {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  stroke-width: 1.6;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.foto-escolha__acoes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-2);
}

.foto-escolha__acoes .campo__ajuda { flex-basis: 100%; }

/* --------------------------------------------------------------------------
   10. Selos de estado — laranja é vencimento, nunca decoração
   -------------------------------------------------------------------------- */

.selo {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  padding: 3px var(--e-2);
  border-radius: var(--r-total);
  font-size: var(--t-legenda);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.selo--alerta { background: var(--alerta-fundo); color: #A5501A; }
.selo--ok     { background: var(--ok-fundo);     color: var(--ok); }
.selo--erro   { background: var(--erro-fundo);   color: var(--erro); }
.selo--neutro { background: var(--cinza-claro);  color: var(--texto-secundario); }

/* --------------------------------------------------------------------------
   11. Estados de dados — vazio, carregando, erro
   -------------------------------------------------------------------------- */

.estado {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-12) var(--e-5);
  text-align: center;
}

.estado__titulo {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h4);
  font-weight: 600;
  color: var(--texto);
}

.estado__texto {
  font-size: var(--t-mini);
  color: var(--texto-terciario);
  max-width: 34ch;
}

.estado__acao { margin-top: var(--e-3); }

/* Ícone de estado vazio: grande, mas em tom baixo — sinaliza a categoria sem
   virar ilustração. */
.estado__icone {
  width: 40px;
  height: 40px;
  margin-bottom: var(--e-2);
  stroke: var(--texto-mudo);
  stroke-width: 1.4;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Esqueleto de leitura: usado enquanto a primeira carga da garagem não voltou.
   "Ainda não sei" não pode aparecer como "não tem nada". */
.carga {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  padding: var(--e-2) 0;
}

.carga__linha { height: 14px; }
.carga__linha--curta { width: 40%; }
.carga__linha--media { width: 68%; }

/* Esqueleto de carregamento */
.esqueleto {
  background: linear-gradient(
    90deg,
    rgba(45, 55, 72, 0.05) 25%,
    rgba(45, 55, 72, 0.09) 37%,
    rgba(45, 55, 72, 0.05) 63%
  );
  background-size: 400% 100%;
  border-radius: var(--r-pequeno);
  animation: esqueleto 1.4s ease-in-out infinite;
}

@keyframes esqueleto {
  0%   { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

/* --------------------------------------------------------------------------
   11b. Lista do menu "Mais"

   Cartão único com linhas divididas, não cartões soltos: são destinos de
   navegação, não conteúdo — devem ler como um índice.
   -------------------------------------------------------------------------- */

.lista-mais {
  list-style: none;
  padding: 0;
  background: var(--painel);
  border-radius: var(--r-medio);
  box-shadow: var(--elev-1);
  overflow: hidden;
}

.lista-mais li + li .item-mais {
  border-top: 1px solid var(--borda-suave);
}

.item-mais {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  min-height: 60px;
  padding: var(--e-3) var(--e-4);
  color: inherit;
  text-decoration: none;
  transition: background-color var(--dur-toque) var(--saida);
}

.item-mais:hover { background: var(--cinza-claro); }
.item-mais:active { background: var(--azul-aco-claro); }

.item-mais__icone {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  stroke: var(--azul-aco);
  stroke-width: 1.75;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.item-mais__texto {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.item-mais__titulo {
  font-family: var(--fonte-titulo);
  font-size: var(--t-corpo);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.item-mais__descricao {
  font-size: var(--t-mini);
  color: var(--texto-terciario);
}

.item-mais__seta {
  flex-shrink: 0;
  color: var(--texto-mudo);
  stroke: currentColor;
}

code {
  font-family: ui-monospace, 'Cascadia Code', 'Consolas', monospace;
  font-size: 0.9em;
  padding: 1px 5px;
  background: var(--cinza-claro);
  border-radius: 4px;
  color: var(--texto-secundario);
}

/* --------------------------------------------------------------------------
   12. Entrada de vista

   Nunca de scale(0) — nada aparece do nada.
   -------------------------------------------------------------------------- */

.vista {
  display: flex;
  flex-direction: column;
  gap: var(--e-5);
  animation: entrada var(--dur-popover) var(--saida) both;
}

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

.vista__cabecalho {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--e-3);
}

/* --------------------------------------------------------------------------
   12b. Aviso de resultado

   Confirmação curta acima da lista, não toast flutuante: o retorno pertence ao
   contexto da ação e não deve tapar conteúdo nem exigir pressa para ler.
   -------------------------------------------------------------------------- */

.aviso {
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-pequeno);
  font-size: var(--t-mini);
  font-weight: 500;
  background: var(--cinza-claro);
  color: var(--texto-secundario);
  box-shadow: var(--elev-0);
}

.aviso--ok     { background: var(--ok-fundo);     color: var(--ok); }
.aviso--alerta { background: var(--alerta-fundo);  color: #A5501A; }
.aviso--erro   { background: var(--erro-fundo);   color: var(--erro); }

/* --------------------------------------------------------------------------
   12c. Cartão de veículo

   Um cartão por veículo, não linha de lista: cada um carrega identificação,
   uma leitura de instrumento (km) e três ações. Linha de tabela não sustenta
   isso em tela de celular.

   O veículo ativo se distingue por anel azul, não por fundo escuro — o fundo
   grafite é exclusividade do mostrador do topo (ver "Assinatura" no
   system.md); replicá-lo aqui esvaziaria o sentido dele.
   -------------------------------------------------------------------------- */

.lista-veiculos {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  list-style: none;
  padding: 0;
}

.cartao-veiculo {
  display: grid;
  gap: var(--e-3);
}

.cartao-veiculo--ativo {
  box-shadow: 0 0 0 1.5px var(--azul-aco),
              0 2px 8px -2px rgba(43, 108, 168, 0.18);
}

.cartao-veiculo__topo {
  display: flex;
  align-items: flex-start;
  gap: var(--e-3);
}

.avatar-veiculo {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  overflow: hidden;
  background: var(--azul-aco-claro);
  border-radius: var(--r-medio);
  box-shadow: var(--elev-0);
  color: var(--azul-aco);
}

/* Com foto, o fundo azul-claro sai: a imagem cobre o quadrado inteiro. */
.avatar-veiculo--foto { background: var(--grafite); }

.avatar-veiculo__icone {
  width: 26px;
  height: 26px;
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.avatar-veiculo__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cartao-veiculo__identificacao {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.cartao-veiculo__nome {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h4);
  font-weight: 600;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

.cartao-veiculo__meta {
  font-size: var(--t-legenda);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--texto-terciario);
}

.cartao-veiculo__ficha {
  font-size: var(--t-mini);
  color: var(--texto-secundario);
}

.cartao-veiculo__leitura { gap: 0; }

/* Ações separadas do conteúdo por um divisor, não por espaço solto: fica claro
   que a linha inteira pertence àquele veículo. */
.cartao-veiculo__acoes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
  padding-top: var(--e-3);
  border-top: 1px solid var(--borda-suave);
}

.cartao-veiculo__acoes .botao:first-child { margin-right: auto; }

/* --------------------------------------------------------------------------
   12d. Sheet — cadastro e edição de veículo

   <dialog> nativo: foco preso, Esc e backdrop sem JS de acessibilidade
   reinventado. Sobe pela base porque o formulário é longo e o polegar fica
   embaixo — os tokens --r-grande, --dur-sheet e --entre-tela foram reservados
   na Sessão 1 exatamente para esta camada.
   -------------------------------------------------------------------------- */

.sheet {
  position: fixed;
  /* `width: auto` de propósito: com left/right em 0, é o par que resolve a
     largura, e só então `max-width` a limita e `margin-inline: auto` centra.
     Com `width: 100%` as margens automáticas ficam sem folga para distribuir e
     o sheet gruda na esquerda em tela larga. */
  inset: auto 0 0 0;
  width: auto;
  max-width: var(--largura-max);
  max-height: min(90dvh, 760px);
  margin-inline: auto;
  margin-block: 0;
  padding: 0;
  overflow: hidden;
  background: var(--painel-elevado);
  border: 0;
  border-radius: var(--r-grande) var(--r-grande) 0 0;
  box-shadow: var(--elev-2);
  color: var(--texto);
}

.sheet[open] {
  animation: sheet-sobe var(--dur-sheet) var(--entre-tela);
}

.sheet::backdrop {
  background: rgba(45, 55, 72, 0.45);
  animation: veu var(--dur-sheet) var(--saida);
}

@keyframes sheet-sobe {
  from { transform: translateY(100%); }
  to   { transform: none; }
}

@keyframes veu {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.sheet__forma {
  display: flex;
  flex-direction: column;
  max-height: inherit;
}

.sheet__cabecalho {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e-3);
  padding: var(--e-4) var(--pad-secao);
  border-bottom: 1px solid var(--borda-suave);
}

.sheet__titulo {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.015em;
  overflow-wrap: anywhere;
}

.sheet__corpo {
  display: flex;
  flex-direction: column;
  gap: var(--e-4);
  padding: var(--pad-secao);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.sheet__rodape {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  padding: var(--e-3) var(--pad-secao);
  padding-bottom: calc(var(--e-3) + var(--safe-bottom));
  background: var(--painel-elevado);
  border-top: 1px solid var(--borda-suave);
}

.sheet__botoes {
  display: flex;
  gap: var(--e-2);
}

/* Salvar é a ação esperada: ocupa o dobro do Cancelar. */
.sheet__botoes .botao { flex: 1; }
.sheet__botoes .botao--primario { flex: 2; }

.sheet__erro {
  font-size: var(--t-mini);
  color: var(--erro);
}

/* --------------------------------------------------------------------------
   12e. Modal de confirmação destrutiva

   Centralizado e estreito, ao contrário do sheet: não é formulário, é uma
   pergunta que precisa parar o fluxo. Vermelho de --erro, nunca laranja.
   -------------------------------------------------------------------------- */

.modal {
  width: calc(100% - var(--e-8));
  max-width: 420px;
  padding: var(--pad-secao);
  margin: auto;
  background: var(--painel-elevado);
  border: 0;
  border-radius: var(--r-grande);
  box-shadow: var(--elev-2);
  color: var(--texto);
}

.modal[open] {
  animation: modal-entra var(--dur-popover) var(--saida);
}

.modal::backdrop {
  background: rgba(45, 55, 72, 0.45);
  animation: veu var(--dur-popover) var(--saida);
}

/* De 0.96, não de 0: nada aparece do nada. */
@keyframes modal-entra {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: none; }
}

.modal__interno {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
}

.modal__marca {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  background: var(--erro-fundo);
  border-radius: var(--r-total);
  color: var(--erro);
}

.modal__marca svg {
  stroke: currentColor;
  stroke-width: 1.8;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.modal__titulo {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.015em;
}

.modal__texto {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  font-size: var(--t-mini);
  color: var(--texto-secundario);
}

/* O aviso de cascata é o motivo da caixa existir: destacado, não escondido no
   meio do parágrafo. */
.modal__cascata {
  padding: var(--e-2) var(--e-3);
  background: var(--erro-fundo);
  border-radius: var(--r-pequeno);
  color: #8E2C21;
}

.modal__promocao {
  color: var(--texto-terciario);
}

.modal__erro {
  margin-top: var(--e-2);
  font-size: var(--t-mini);
  color: var(--erro);
}

.modal__acoes {
  display: flex;
  gap: var(--e-2);
  margin-top: var(--e-4);
}

.modal__acoes .botao { flex: 1; }

/* --------------------------------------------------------------------------
   12f. Bloco de seção dentro de uma vista

   Chega na Sessão 5, quando a primeira vista passou a ter dois blocos
   (previsões e histórico). O título de bloco é h4, não h2 visual: a <h1> da
   vista continua sendo a única voz forte da tela — dois títulos grandes
   competindo transformariam a vista em duas páginas coladas.
   -------------------------------------------------------------------------- */

.secao {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
}

.secao__cabecalho {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-2);
}

.secao__titulo {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h4);
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* Contagem de itens: informação de apoio, no nível mais baixo de texto. */
.secao__contagem {
  font-size: var(--t-mini);
  font-weight: 500;
  color: var(--texto-terciario);
}

/* Legenda de uma linha logo abaixo do título — sobe contra o gap da seção
   para ficar colada no título a que pertence, não no conteúdo. */
.secao__nota {
  margin-top: calc(var(--e-2) * -1);
  font-size: var(--t-mini);
  color: var(--texto-terciario);
}

/* --------------------------------------------------------------------------
   12g. Filtro por tipo — chips de escolha exclusiva

   `role="radiogroup"` de verdade: a escolha é única e sempre há uma marcada.
   Altura de 40px, igual à do `.alternador__opcao` — os dois são a mesma
   categoria de controle (escolha exclusiva, rótulo de uma palavra, sem ícone),
   e um terceiro tamanho para a mesma função só criaria ruído.

   Rola na horizontal em vez de quebrar linha: com sete tipos, duas ou três
   linhas de chip empurrariam o histórico para fora da primeira tela.
   -------------------------------------------------------------------------- */

.filtro {
  display: flex;
  gap: var(--e-2);
  overflow-x: auto;
  /* O par padding/margin devolve o espaço que o `overflow` recortaria do anel
     de foco. Sem ele, o foco no chip aparece cortado nos quatro lados. */
  padding: var(--e-1);
  margin: calc(var(--e-1) * -1);
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}

.filtro::-webkit-scrollbar { display: none; }

.filtro__opcao {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  flex: 0 0 auto;
  min-height: 40px;
  padding: 0 var(--e-3);
  background: var(--painel);
  border: 1px solid var(--borda-forte);
  border-radius: var(--r-total);
  font-family: var(--fonte-corpo);
  font-size: var(--t-mini);
  font-weight: 500;
  color: var(--texto-secundario);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-toque) var(--saida),
              border-color var(--dur-toque) var(--saida),
              color var(--dur-toque) var(--saida);
}

.filtro__opcao:hover[aria-checked='false'] { color: var(--texto); }

.filtro__opcao[aria-checked='true'] {
  background: var(--azul-aco-claro);
  border-color: var(--azul-aco);
  color: var(--azul-aco-escuro);
  font-weight: 600;
}

/* Contagem demovida dentro do chip: é apoio, não o rótulo. */
.filtro__contagem {
  font-size: var(--t-legenda);
  font-weight: 500;
  color: var(--texto-terciario);
}

.filtro__opcao[aria-checked='true'] .filtro__contagem { color: var(--azul-aco); }

/* --------------------------------------------------------------------------
   12h. Previsão de próxima manutenção

   Um cartão por tipo, com a previsão do último registro daquele tipo.

   SEM cor de alerta, sem selo de urgência e sem ordenação por vencimento: a
   Sessão 5 entrega exibição neutra, e o laranja de `--alerta` só entra quando
   a Edge Function agendada de Web Push existir. Um cartão que já pintasse de
   laranja aqui criaria um segundo lugar onde a regra de vencimento vive.
   -------------------------------------------------------------------------- */

.previsoes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--e-3);
  list-style: none;
  padding: 0;
}

.previsao {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
}

.previsao__tipo {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h4);
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* Km previsto e data prevista dividem a linha: são a mesma previsão lida por
   duas unidades, e "o que vier primeiro" só se entende se as duas estiverem
   visíveis ao mesmo tempo. */
.previsao__leituras {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-4);
}

.previsao__leituras .instrumento { flex: 1 1 auto; min-width: 0; }

/* Tipo sem intervalo cadastrado ('outro' inteiro, 'bateria' sem km): a trigger
   deixa a previsão nula de propósito, e a tela diz isso em palavras em vez de
   mostrar um travessão órfão. */
.previsao__sem {
  font-size: var(--t-mini);
  color: var(--texto-terciario);
}

/* De onde a previsão veio — é o que torna a regra de desempate conferível a
   olho: "a previsão vem do último registro que você lançou". */
.previsao__origem {
  padding-top: var(--e-3);
  border-top: 1px solid var(--borda-suave);
  font-size: var(--t-legenda);
  color: var(--texto-terciario);
}

/* --------------------------------------------------------------------------
   12i. Lançamento — linha de histórico

   Linha, não cartão, ao contrário do veículo: um registro de manutenção é um
   fato de cinco campos numa lista que cresce sem limite, e cartão por registro
   viraria uma pilha de caixas em duas semanas de uso.

   A linha inteira é o botão de edição — e a exclusão mora dentro do sheet de
   edição. Assim a lista não carrega dois botões por registro competindo com a
   leitura, que é o que ela existe para dar.
   -------------------------------------------------------------------------- */

.lista-lancamentos {
  list-style: none;
  padding: 0;
  background: var(--painel);
  border-radius: var(--r-medio);
  box-shadow: var(--elev-1);
  overflow: hidden;
}

.lista-lancamentos li + li .lancamento {
  border-top: 1px solid var(--borda-suave);
}

.lancamento {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  width: 100%;
  min-height: 60px;
  padding: var(--e-3) var(--e-4);
  background: transparent;
  border: 0;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-toque) var(--saida);
}

.lancamento:hover { background: var(--cinza-claro); }
.lancamento:active { background: var(--azul-aco-claro); }

.lancamento__texto {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.lancamento__topo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
}

.lancamento__tipo {
  font-family: var(--fonte-titulo);
  font-size: var(--t-corpo);
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* O custo alinha à direita e fica na fonte de instrumento: é o número que o
   módulo Financeiro vai somar, não um detalhe do texto. */
.lancamento__custo {
  flex-shrink: 0;
  font-family: var(--fonte-titulo);
  font-size: var(--t-corpo);
  font-weight: 600;
}

.lancamento__meta {
  font-size: var(--t-mini);
  color: var(--texto-secundario);
  overflow-wrap: anywhere;
}

.lancamento__previsao {
  font-size: var(--t-legenda);
  color: var(--texto-terciario);
}

.lancamento__seta {
  flex-shrink: 0;
  color: var(--texto-mudo);
  stroke: currentColor;
}

/* Ação destrutiva no pé do corpo do sheet, atrás de um divisor — nunca ao lado
   de "Salvar". A linha de botões do rodapé é da ação esperada; misturar
   exclusão ali poria a ação irreversível a um deslize de distância. */
.sheet__destrutivo {
  padding-top: var(--e-4);
  border-top: 1px solid var(--borda-suave);
}

/* --------------------------------------------------------------------------
   12b. Portão de sessão

   O que aparece enquanto a sessão persistida está sendo lida, em app.html e
   em entrar.html. Existe para não piscar tela de login na cara de quem já
   está logado — nem pintar o shell antes de saber de quem é a garagem.

   Deliberadamente quase vazio: é um intervalo de milissegundos no caso normal.
   Marca + um pulso. Spinner girando aqui daria ao instante mais peso do que
   ele tem.
   -------------------------------------------------------------------------- */

.portao {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e-4);
  min-height: 100dvh;
  padding: var(--e-6);
  text-align: center;
}

.portao__marca {
  font-family: var(--fonte-titulo);
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--texto);
}

/* Barra de progresso indeterminada, mesma linguagem do .esqueleto: tonalidade
   em movimento, não spinner. */
.portao__pulso {
  width: 96px;
  height: 3px;
  overflow: hidden;
  background: var(--borda);
  border-radius: var(--r-total);
}

.portao__pulso::after {
  content: '';
  display: block;
  width: 40%;
  height: 100%;
  background: var(--azul-aco);
  border-radius: var(--r-total);
  animation: portao-pulso 1.1s var(--saida) infinite;
}

@keyframes portao-pulso {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

/* Falha antes de haver sessão: o import do supabase-js pela CDN não voltou.
   Precisa de saída, senão o pulso vira spinner eterno. */
.portao__erro {
  max-width: 32ch;
  font-size: var(--t-mini);
  color: var(--erro);
}

/* --------------------------------------------------------------------------
   12c. Autenticação — entrar.html

   Não é uma vista do shell: não tem mostrador, nem tab bar, nem veículo ativo.
   Centrada na altura da tela, coluna estreita, cartão único.

   Os tokens são os mesmos do resto do app. Nenhum valor novo entra aqui — o
   formulário reusa .campo, .botao e .aviso da Sessão 1/2.
   -------------------------------------------------------------------------- */

.autenticacao {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--e-6);
  width: 100%;
  max-width: 420px;   /* mais estreito que --largura-max: são dois campos */
  min-height: 100dvh;
  margin-inline: auto;
  padding: var(--e-8) var(--e-4);
}

.autenticacao__topo {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
  text-align: center;
}

.autenticacao__marca {
  font-size: var(--t-h1);
  letter-spacing: -0.02em;
}

.autenticacao__linha {
  font-size: var(--t-mini);
  color: var(--texto-secundario);
}

.autenticacao__cartao {
  display: flex;
  flex-direction: column;
  gap: var(--e-5);
  padding: var(--pad-secao);
}

.autenticacao__rodape {
  font-size: var(--t-legenda);
  color: var(--texto-terciario);
  text-align: center;
}

/* --- Alternador entrar / criar conta -------------------------------------
   Duas opções mutuamente exclusivas que trocam o MESMO formulário, então é
   tablist, não navegação. Vive sobre o fundo recuado de --campo pelo mesmo
   motivo dos inputs: o que está por baixo é trilho, o que sobe é a escolha.

   Não é .segmentado: aquele é escolha de conteúdo do formulário (tipo de
   veículo), com ícone e alvo de 68px. Aqui a escolha é de modalidade da tela.
   ------------------------------------------------------------------------ */

.alternador {
  display: flex;
  gap: var(--e-1);
  padding: var(--e-1);
  background: var(--campo);
  border: 1px solid var(--borda);
  border-radius: var(--r-pequeno);
}

.alternador__opcao {
  flex: 1;
  min-height: 40px;
  padding: 0 var(--e-3);
  font-family: var(--fonte-corpo);
  font-size: var(--t-mini);
  font-weight: 500;
  color: var(--texto-secundario);
  background: transparent;
  border: 0;
  border-radius: calc(var(--r-pequeno) - 2px);
  cursor: pointer;
  transition: background var(--dur-toque) var(--saida),
              color var(--dur-toque) var(--saida);
}

.alternador__opcao:hover:not([aria-selected='true']) { color: var(--texto); }

.alternador__opcao[aria-selected='true'] {
  color: var(--azul-aco);
  font-weight: 600;
  background: var(--painel);
  box-shadow: var(--elev-0);
}

.alternador__opcao:disabled { cursor: default; opacity: 0.6; }

/* --- Formulário ---------------------------------------------------------- */

.forma-auth {
  display: flex;
  flex-direction: column;
  gap: var(--e-4);
}

.forma-auth__erro { margin-bottom: calc(var(--e-1) * -1); }

/* Boa notícia vinda da tela anterior (e-mail confirmado, senha alterada).
   Mesmo recuo negativo do erro: os dois ocupam o mesmo lugar na coluna, nunca
   ao mesmo tempo. */
.forma-auth__sucesso { margin-bottom: calc(var(--e-1) * -1); }

.forma-auth__nota {
  font-size: var(--t-legenda);
  color: var(--texto-terciario);
  text-align: center;
}

/* --- Saídas em texto (Sessão 4) -------------------------------------------
   "Esqueci minha senha" e "Voltar para o login" são links, não botões: levam
   a outra página e nada acontece ao tocá-los além disso. Botão aqui
   competiria com a ação primária do cartão, que é entrar.

   Os 44px de alvo de toque continuam valendo — a regra não abre exceção por
   o elemento ser <a>. `min-height` + `inline-flex` em vez de padding chutado:
   padding depende da altura de linha da fonte e erra por alguns pixels quando
   a escala tipográfica muda.
   -------------------------------------------------------------------------- */

.forma-auth__esqueci,
.forma-auth__voltar {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--t-mini);
  font-weight: 500;
  text-decoration: none;
}

.forma-auth__esqueci {
  align-self: flex-start;
  color: var(--azul-aco);
}

.forma-auth__esqueci:hover { text-decoration: underline; }

.forma-auth__voltar {
  align-self: center;
  padding-inline: var(--e-3);
  color: var(--texto-secundario);
}

.forma-auth__voltar:hover { color: var(--texto); text-decoration: underline; }

/* Campo com botão embutido — hoje só o "mostrar senha". O botão flutua sobre
   o input em vez de dividir a linha: dividir encurtaria o campo de senha, que
   é onde o texto precisa de espaço. */
.campo__com-acao {
  position: relative;
  display: flex;
}

.campo__com-acao .campo__controle {
  flex: 1;
  padding-right: 48px;
}

.campo__acao {
  position: absolute;
  top: 50%;
  right: 0;
  /* `.botao-icone` traz margin-right negativa para encostar na borda do sheet;
     aqui ele mora dentro do campo e essa margem o jogaria para fora. */
  margin-right: 0;
  transform: translateY(-50%);
  color: var(--texto-terciario);
  background: transparent;
}

.campo__acao:hover { background: transparent; color: var(--texto-secundario); }
.campo__acao[aria-pressed='true'] { color: var(--azul-aco); }

/* --- Telas de instrução ---------------------------------------------------
   Um recado que ocupa o cartão inteiro, em vez de um `.aviso` de uma linha:
   confirme seu e-mail, verifique sua caixa de entrada, link inválido. Nos
   três a próxima ação da pessoa está FORA do navegador, e isso precisa de
   espaço para ser lido.
   -------------------------------------------------------------------------- */

.autenticacao__confirme {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-3);
  text-align: center;
}

.autenticacao__selo {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  color: var(--azul-aco);
  background: var(--azul-aco-claro);
  border-radius: var(--r-total);
}

.autenticacao__selo svg { stroke: currentColor; fill: none; }

/* Link morto não é vencimento de manutenção: `--erro`, nunca o laranja. */
.autenticacao__selo--erro {
  color: var(--erro);
  background: var(--erro-fundo);
}

.autenticacao__titulo {
  font-size: var(--t-h4);
  letter-spacing: -0.01em;
}

/* Recebe foco por script ao trocar de estado — sem contorno de foco visível,
   porque o alvo é o leitor de tela, não o ponteiro. */
.autenticacao__titulo:focus { outline: none; }

.autenticacao__texto {
  font-size: var(--t-mini);
  color: var(--texto-secundario);
}

/* Cabeçalho do formulário quando ele tem um assunto próprio (recuperar
   senha, definir nova senha) e não o alternador entrar/criar conta. */
.autenticacao__intro {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
}

/* `>` de propósito: quando as ações estão agrupadas em `.autenticacao__acoes`,
   quem controla o espaçamento entre elas é o grupo. */
.autenticacao__confirme > .botao { margin-top: var(--e-2); }

.autenticacao__acoes {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  width: 100%;
  margin-top: var(--e-2);
}

/* Resposta ao "Reenviar e-mail": sucesso ou falha, no mesmo lugar. */
.autenticacao__retorno {
  width: 100%;
  text-align: left;
}

/* --------------------------------------------------------------------------
   12d. Bloco de conta — pé do menu "Mais"

   Identificação de quem está logado e a saída. Fora da tab bar de propósito:
   sair é raro e não deveria ficar sob o polegar.
   -------------------------------------------------------------------------- */

.conta {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-top: var(--e-6);
  padding: var(--e-3) var(--pad-cartao);
  background: var(--painel);
  border-radius: var(--r-medio);
  box-shadow: var(--elev-1);
}

.conta__avatar {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  color: var(--texto-terciario);
  background: var(--cinza-claro);
  border-radius: var(--r-total);
}

.conta__avatar svg { stroke: currentColor; fill: none; stroke-width: 1.9; }

.conta__texto {
  display: flex;
  flex-direction: column;
  min-width: 0;   /* deixa o e-mail longo truncar em vez de esticar a linha */
  margin-right: auto;
}

.conta__rotulo {
  font-size: var(--t-legenda);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--texto-terciario);
}

.conta__valor {
  overflow: hidden;
  font-size: var(--t-mini);
  color: var(--texto);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   13. Acessibilidade e telas maiores
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* A regra acima congelaria o pulso do portão fora da tela
     (translateX(-100%)), deixando quem pediu menos movimento sem nenhum sinal
     de que algo está acontecendo. Vira barra estática. */
  .portao__pulso::after {
    width: 100%;
    transform: none;
    opacity: 0.45;
  }
}

/* Acima do tablet o conteúdo permanece em coluna única e centrado: este é um
   app de campo, alargar transformaria a leitura de lançamentos em planilha. */
@media (min-width: 768px) {
  :root {
    --pad-cartao: var(--e-5);
  }

  .app__conteudo {
    padding-inline: var(--e-6);
  }
}
