/* ============================================================
   Desbravia — Design System

   "Onde não há caminhos, há jornada." A marca não vende turismo,
   vende o impacto do mundo real: terra crua, silêncio da rocha,
   força da natureza. O design tem de parecer RESISTÊNCIA e
   TÉCNICA, não conforto plastificado.

   Daí as três regras que mandam em tudo aqui:
   · Verde musgo estrutura, terracota age. Nunca o contrário.
   · Nenhuma serifa. Inter, 400 no corpo e 800 nos títulos.
   · Canto de 4px. Pílula é cosmético; equipamento tem quina.

   Renderização continua leve (alvo: aparelho sem GPU dedicada).
   ============================================================ */

:root {
  /* O mesmo triângulo do sprite, em máscara, para os pseudo-elementos
     que não podem carregar um `<use>`. */
  --ico-atencao: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.8L1.9 20.4h20.2z'/%3E%3Cpath d='M12 9.6v4.9M12 17.3v.2'/%3E%3C/svg%3E");

  --bg: #f9f9f9;              /* Branco Gelo */
  --bg-alt: #eeefee;
  --surface: #ffffff;
  --surface-2: #f2f4f2;
  --text: #1c2a23;
  --text-soft: #4d5a54;
  /* Medido a 375px, com sessão, tela por tela: #7c8781 dava 3,4:1 sobre
     `--surface-2` e 3,7:1 sobre `--surface` — abaixo dos 4,5:1 que a
     norma pede para texto pequeno, e é justamente ele que carrega TODA
     dica de campo do app ("De onde você sai", "Sem isso, a vitrine
     mostra…"). 26 textos reprovados em 10 telas. Agora: 4,5 a 5,0. */
  --text-faint: #656e69;
  --border: #dfe3e0;
  --border-strong: #c3cac6;

  /* Verde Musgo é a cor da estrutura: barra, estado ativo, o que
     organiza. Terracota é a cor do gesto: só o que a pessoa aperta.
     Trocar os papéis é o erro que faz a tela virar enfeite. */
  --brand: #2c4c3b;
  --brand-hover: #21382c;
  --brand-soft: #e6ece8;
  --brand-text: #f9f9f9;

  --accent: #c36b42;          /* Terracota — ação */
  --accent-hover: #a95733;
  --slate: #36454f;           /* Cinza Ardósia — texto/secundária */
  /* Os três primeiros foram escurecidos em 16/09/2026, medidos como TEXTO
     sobre as três superfícies do tema claro. O tema escuro clareia estes
     mesmos tokens e por isso passava; o lado claro nunca tinha sido medido
     e reprovava inteiro: warn 3,07 / danger 4,23 / ok 4,18 sobre
     `--surface-2`. Como fundo com branco por cima eles só melhoram. */
  --danger: #c0302f;          /* era #d43b3b */
  --warn: #9a6108;            /* era #c07d10 */
  --ok: #147a43;              /* era #17864a */
  --info: #2563eb;

  /* Terracota LIDA. `--accent` é a cor da marca e o fundo do gesto; com
     11 a 14px de texto ela dá 3,45. Este é o mesmo tom escurecido que a
     folha já usava em `--accent-hover`, agora com nome de quem o usa. */
  --accent-txt: #a95733;

  /* Quina, não pílula. O brandbook pede 4px para o visual técnico —
     o mesmo canto do equipamento de montanha, que é onde a marca vive.
     `--r-pill` continua existindo só para o que é etiqueta (chip de
     contagem), onde arredondar comunica "isto não é botão". */
  --r-lg: 6px;
  --r: 4px;
  --r-sm: 4px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(28, 42, 35, .06);
  --shadow: 0 4px 16px rgba(28, 42, 35, .10);
  --shadow-lift: 0 10px 32px rgba(28, 42, 35, .16);

  --topbar-h: 64px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Uma escala só, usada em tudo — espaçamento improvisado é o que
     faz um app parecer montado por partes. */
  --sp-1: 6px;  --sp-2: 10px; --sp-3: 16px;
  --sp-4: 24px; --sp-5: 36px; --sp-6: 56px;

  --ease: cubic-bezier(.2, .7, .3, 1);
  /* O VITRAL: o que o vidro faz com a foto que está atrás DELE — só ali.
     Fora do vidro a foto fica inteira, com cor cheia. A conta que amarra
     os três tokens está junto de `.parede.tem-parede ~ .container`. */
  --vitral-filtro: contrast(.4) brightness(1.5);
  --vitral: 32%;
  /* O texto que fica SOBRE o vidro: 80% da cor principal, 20% do cinza.
     Declarado aqui, na raiz, porque dentro do vidro ele substitui o
     próprio `--text-soft` — e um token não pode se misturar consigo. */
  --vitral-texto: color-mix(in srgb, var(--text) 80%, var(--text-soft));
}

@media (prefers-color-scheme: dark) {
  :root {
    /* No escuro ele só escurece, sem achatar: vai de 0 a 128/255. */
    --vitral-filtro: brightness(.5);
    --vitral: 30%;
    /* O escuro não é invenção: é o Cinza Ardósia da marca levado ao
       fundo. Preto puro apagaria a família — ardósia mantém o app
       reconhecível como o mesmo produto às 6h e às 22h. */
    --bg: #131a1e;
    --bg-alt: #0e1417;
    --surface: #1a242a;
    --surface-2: #223038;
    --text: #f9f9f9;
    --text-soft: #a9b6b0;
    /* No escuro o mesmo papel, o mesmo defeito: 3,8:1 sobre
       `--surface-2`. Sobe até 4,9 e continua sendo o tom mais apagado
       da folha — `--text-soft` está em 6,5. */
    --text-faint: #8f9f99;
    --border: #2b3a42;
    --border-strong: #3b4d56;

    /* No escuro o musgo fechado some no fundo: sobe para a folha nova,
       mantendo o mesmo papel de estrutura. */
    /* Clareado de #6f9d80 em 16/09/2026. O valor antigo dava 4,40 sobre
       `--surface-2` — a superfície mais clara do tema escuro — e derrubava
       toda etiqueta pequena em musgo: o "pronto" de O que existe (104
       delas), o link de referência da Bancada e o nome da patente musgo.
       A folha já tinha contornado isso UMA vez trocando o fundo de um
       card; a segunda vez é sinal de que o errado era o token. */
    --brand: #78a689;
    --brand-hover: #86b596;
    --brand-soft: #1c2b23;
    --brand-text: #101a14;

    --accent: #d98255;          /* Terracota clareada para o escuro */
    --accent-hover: #e69a72;
    --slate: #9fb0b9;
    --danger: #ef6b6b;
    --warn: #e0b23a;
    --ok: #5cc08c;
    --info: #6ea8ff;
    /* No escuro a terracota já é clara o bastante para ler: 4,70. */
    --accent-txt: var(--accent);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
    --shadow: 0 4px 18px rgba(0, 0, 0, .5);
    --shadow-lift: 0 12px 36px rgba(0, 0, 0, .6);
  }
}

* { box-sizing: border-box; }

/* `hidden` esconde de verdade — inclusive quem tem `display` próprio.
   
   O atributo vem do navegador com `display: none`, e essa regra da folha do
   USUÁRIO perde para qualquer classe da nossa que declare `display`. O
   resultado não parece um defeito: o elemento fica "escondido" e continua
   ocupando o espaço dele. `.acv-ponte` (que já saiu) era `display: flex` com 8px de
   preenchimento e uma borda verde à esquerda — escondida, ela virava uma
   BARRINHA de 16px entre a contagem de destinos e a grade, sem texto e sem
   explicação.
   
   Alguém já tinha topado com isso e consertado em dois lugares
   (`.rot-seta-btn[hidden]`, `.rot-faixa[hidden]`), um de cada vez, à mão. O
   `!important` aqui é a exceção que dispensa a próxima: `hidden` é uma
   afirmação sobre a EXISTÊNCIA do elemento na tela, e nenhuma regra de
   aparência tem o direito de discordar dela. `test_hidden_esconde.py`
   prende isto. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5 { margin: 0; line-height: 1.25; font-weight: 650; letter-spacing: -.01em; }
h2 { font-size: 22px; }
h3 { font-size: 17px; }
h4 { font-size: 15px; }
p { margin: 0 0 10px; }
small { font-size: 12.5px; color: var(--text-soft); }
code { font-family: var(--mono); font-size: .9em; }
a { color: var(--brand); }

/* Campo que esconde o que se digita SEM ser `type="password"`.
   Um `input[type=password]` no documento faz o Chrome tratar a página
   inteira como formulário de login — e numa SPA sem `<form>` ele elege
   como "usuário" a primeira caixa de texto que encontrar, que era a busca
   de origem do montador. `-webkit-text-security` dá o mesmo disfarce sem
   convidar o gerenciador de senhas. */
.aik-oculto { -webkit-text-security: disc; }

/* ------------------------------------- a viagem em uma frase -- */
/* A caixa da frase, o rótulo e a linha da busca são definidos uma vez só,
   lá embaixo, no bloco "a busca abre a tela". Aqui havia uma segunda
   definição de cada um — tracejada, com o botão ao lado do campo — que
   perdia por ORDEM e não fazia nada, menos a regra de telefone logo
   abaixo, que desmontava a busca em duas peças justamente onde a tela é
   mais estreita. */
.frase-caixa { display: flex; flex-direction: column; gap: var(--s2); }
.frase-lida {
  display: flex; flex-wrap: wrap; gap: 7px; align-items: center;
  font-size: 12.5px; color: var(--text-soft);
}
.frase-selo {
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--brand); font-weight: 700;
}
.frase-chip {
  /* Mais folga e uma borda que se vê. Dito por quem usou: estas etiquetas
     precisam funcionar como "um resumo visual confiável", e apertadas
     contra uma borda de 1px em `--border` elas liam como ruído entre a
     frase e os cartões. */
  padding: 4px 11px; border-radius: 999px; font-size: 12.5px;
  border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--text);
}
/* O nome do campo dentro da etiqueta: quieto, porque o que se confere é o
   VALOR. Versalete e não maiúscula cheia — a etiqueta tem 12,5px e uma
   palavra inteira em caixa alta aqui vira grito. */
.frase-chip-campo {
  color: var(--text-faint); font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: .04em;
}
/* O que a IA deduziu, marcado como dedução. Mesma forma do chip do leitor,
   traço diferente: são dois graus de certeza, e quem confere precisa saber
   qual pedaço olhar com mais atenção. */
.frase-selo-ia { color: var(--text-soft); }
.frase-chip-ia { border-style: dashed; color: var(--text-soft); }

/* As propostas: os mesmos cartões da vitrine, num trilho mais curto.
   Reusa `.rot-card` inteiro — duas folhas para o mesmo cartão divergiriam
   na primeira mudança, e o cartão da frase ficaria com a cara de ontem. */
.frase-propostas { display: flex; flex-direction: column; gap: 2px; }
.frase-propostas-titulo {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin: 4px 0 0; font-size: 12.5px; color: var(--text-soft);
}
.frase-trilho {
  display: flex; gap: 12px;
  /* Sangra até a borda como o trilho da vitrine, mas descontando o padding
     da própria caixa — sem isto o primeiro cartão nasce recuado e o último
     não encosta em lugar nenhum. */
  margin: 10px calc(var(--s3) * -1) 0;
  padding: 4px var(--s3) 10px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--s3);
  scrollbar-width: none;
}
.frase-trilho::-webkit-scrollbar { display: none; }
/* O mesmo desbotado das outras faixas: a ponta cortada reta parece tela
   quebrada, e esta faixa nem setas tinha até agora. */
.frase-trilho.tem-mais-antes { --fade-antes: 40px; }
.frase-trilho.tem-mais-depois { --fade-depois: 40px; }
.frase-buscando { margin: 6px 0 0; font-size: 12.5px; color: var(--text-soft); }

/* No telefone a busca continua sendo uma peça só: quebrar o botão para
   baixo do campo, dentro da mesma moldura, desenha um retângulo com uma
   barra colada embaixo. O que encolhe é o rótulo do botão, não o
   arranjo. */
@media (max-width: 520px) {
  #frase-viagem { font-size: 16px; padding: 14px; min-height: calc(1.4em + 28px); }
  #frase-aplicar { padding: 0 16px; font-size: 14px; }
}

/* ---------------------------------------------- Layout ---- */
#app-shell { min-height: 100%; display: flex; flex-direction: column; }

/* A faixa que o telefone reserva para si.
   Instalado na tela de início, o app ocupa a tela INTEIRA — a página começa
   debaixo do relógio e do alto-falante do iPhone. `viewport-fit=cover` está
   no `index.html` desde sempre e nada aqui respeitava a sobra: a caixa de
   busca subia até encostar no entalhe.
   Fora do modo instalado, e em telefone sem entalhe, `env()` devolve zero e
   nada muda — por isso não há `@media` nenhum em volta. */
:root { --safe-topo: env(safe-area-inset-top, 0px); }

.topbar {
  /* Altura + a sobra: a barra cresce para caber embaixo do relógio, em vez
     de o conteúdo dela ser empurrado para fora. */
  height: calc(var(--topbar-h) + var(--safe-topo));
  padding-top: var(--safe-topo);
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* De lado é a mesma história, deitado: o entalhe come a margem esquerda.
     `max()` mantém os 18px de sempre quando não há sobra. */
  padding-left: max(18px, env(safe-area-inset-left));
  padding-right: max(18px, env(safe-area-inset-right));
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 900;
}

.brand { display: flex; align-items: center; gap: 10px; min-width: 0;
  /* Virou <button> para levar à tela inicial: tira o visual de
     botão e mantém o de marca. */
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: inherit; }
.brand .logo { font-size: 22px; line-height: 1; }
.brand-name { font-weight: 700; font-size: 17px; letter-spacing: -.02em; }

.badge {
  font-size: 11px;
  font-weight: 650;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  letter-spacing: .03em;
  text-transform: uppercase;
  white-space: nowrap;
}
.badge.offline { background: var(--danger); color: #fff; }
.badge.sync { background: var(--warn); color: #fff; }

.topnav {
  display: flex;
  gap: 4px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.topnav::-webkit-scrollbar { display: none; }
.nav-btn { flex: none; }
.nav-btn {
  border: 0;
  background: transparent;
  color: var(--text-soft);
  font: inherit;
  font-size: 14px;
  font-weight: 550;
  padding: 8px 14px;
  border-radius: var(--r-pill);
  cursor: pointer;
}
.nav-btn:hover { background: var(--surface-2); color: var(--text); }
.nav-btn.active { background: var(--brand); color: var(--brand-text); }

main#view { flex: 1; min-height: 0; position: relative; }
.view { display: none; }
.view.active { display: block; }

.container { max-width: 940px; margin: 0 auto; padding: 26px 18px 60px; }
.page-head { margin-bottom: 22px; }
.page-head h2 { margin-bottom: 4px; }
.page-head p { color: var(--text-soft); margin: 0; }

/* ---------------------------------------------- Panels ---- */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 20px;
}
.panel + .panel { margin-top: 16px; }

/* ---------------------------------------------- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: var(--r-sm);
  cursor: pointer;
  white-space: nowrap;
}
/* Botão pequeno: o que aparece DENTRO de uma linha de lista, ao lado de
   um texto, e não como ação da tela. Em tamanho normal ele rouba a linha
   inteira e passa a parecer a ação principal, que é o oposto do que é. */
.btn.sm {
  /* `min-height` também: a folha traz um piso de 38px para o botão normal,
     e sem desfazê-lo aqui o botão pequeno ficava baixo e alto ao mesmo
     tempo — texto de 12px num bloco de 38. */
  min-height: 0;
  font-size: 12.5px;
  font-weight: 600;
  padding: 4px 11px;
  gap: 5px;
}
.btn.sm .ico { width: 13px; height: 13px; }
.btn:hover:not(:disabled) { background: var(--surface-2); border-color: var(--text-faint); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn.primary { background: var(--brand); border-color: var(--brand); color: var(--brand-text); }
.btn.primary:hover:not(:disabled) { background: var(--brand-hover); border-color: var(--brand-hover); }
.btn.danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.btn.danger:hover:not(:disabled) { background: var(--danger); color: #fff; }
/* A aparência final do fantasma mora no bloco de refinamento, mais abaixo:
   aqui ficam só o preenchimento e a cor do texto. */
.btn.ghost { background: transparent; color: var(--text-soft); }
.btn.ghost:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.btn.block { width: 100%; }
.btn.lg { padding: 13px 22px; font-size: 15px; }

/* ---------------------------------------------- Forms ----- */
.field { margin-bottom: 16px; }
.field > label, .field-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-soft);
  margin-bottom: 6px;
}
.field-hint { font-size: 12.5px; color: var(--text-faint); margin-top: 6px; }

input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="date"], input[type="time"],
input[type="search"], select, textarea {
  width: 100%;
  padding: 11px 13px;
  font: inherit;
  font-size: 15px;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  outline: none;
}
input:focus, select:focus, textarea:focus { border-color: var(--brand); background: var(--surface); }
input::placeholder { color: var(--text-faint); }

.row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { .grid-2 { grid-template-columns: 1fr; } }

/* ------------------------------------------ Chips (tags) -- */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-soft);
  font: inherit;
  font-size: 13.5px;
  font-weight: 550;
  cursor: pointer;
  user-select: none;
}
/* `aria-pressed` E `.active`: a marcação de estado do chip é feita pelos
   dois nomes em telas diferentes, e quem usasse só a classe ficava com um
   chip escolhido que não muda de aparência — a pessoa toca, nada acontece
   na tela, e ela toca de novo. */
.chip:hover { border-color: var(--brand); color: var(--text); }
.chip.active,
.chip[aria-pressed="true"] {
  background: var(--brand-soft);
  border-color: var(--brand);
  color: var(--brand);
  font-weight: 650;
}

/* ------------------------------------------ Wizard -------- */
.steps { display: flex; gap: 6px; margin-bottom: 24px; }
.step-dot {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-faint);
}
.step-dot::before { content: ""; height: 4px; border-radius: 2px; background: var(--border); }
.step-dot.done { color: var(--text-soft); }
.step-dot.done::before { background: var(--brand); opacity: .45; }
.step-dot.current { color: var(--brand); }
.step-dot.current::before { background: var(--brand); }

/* Roteiro que veio da vitrine e ainda não pôde entrar.

   Ele só carrega no passo 4, que exige o ponto de saída — e quem escolhia
   um roteiro lá em cima caía no formulário sem sinal nenhum de que já
   trazia dez paradas no bolso. Era indistinguível de começar do zero.

   Faixa, e não toast: o percurso até a carga tem três passos, e um aviso
   que some em três segundos não acompanha três passos. A borda esquerda
   grossa em terracota é a mesma marca da ação principal — o que está aqui
   é a decisão que a pessoa já tomou, esperando a vez. */
.rot-espera {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--r);
  background: var(--brand-soft);
}
.rot-espera.hidden { display: none; }
.rot-espera-ico { display: flex; color: var(--accent-txt); }
.rot-espera-ico .ico { width: 20px; height: 20px; }
.rot-espera-texto {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.rot-espera-texto strong { font-size: 14px; color: var(--text); }
.rot-espera-texto small { font-size: 12px; color: var(--text-soft); }
.rot-espera-sair { flex: 0 0 auto; font-size: 12px; padding: 6px 10px; }

/* A faixa diz o que está em espera; isto diz ONDE vai entrar. Sem o
   segundo, a pessoa sabe que tem um roteiro guardado e continua sem saber
   que o passo 4 já vem preenchido. */
.step-dot[data-carga]::after {
  content: attr(data-carga) " paradas";
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--accent-txt);
  font-variant-numeric: tabular-nums;
}

.wizard-step { display: none; }
.wizard-step.active { display: block; }
.wizard-actions {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

/* ------------------------------------ Origin / autocomplete */

.autocomplete { position: relative; }
.autocomplete-list {
  position: absolute;
  z-index: 700;
  top: calc(100% + 4px);
  left: 0; right: 0;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow);
  max-height: 260px;
  overflow-y: auto;
}
.autocomplete-list:empty { display: none; }
.ac-item {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  font: inherit;
  color: var(--text);
  padding: 10px 13px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.ac-item:last-child { border-bottom: 0; }
.ac-item:hover { background: var(--brand-soft); }
.ac-item strong { display: block; font-size: 14px; font-weight: 600; }
.ac-item span { display: block; font-size: 12px; color: var(--text-faint); margin-top: 1px; }


/* --------------------------------------- Data + hora ------ */
.datetime-row { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.dt-part { flex: 1 1 200px; min-width: 0; }
.dt-part.dt-time { flex: 0 0 170px; }
.dt-part > label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-faint);
  margin-bottom: 5px;
}
/* Sem largura explícita, o input de hora encolhe e fica torto no Chrome. */
input[type="time"], input[type="date"] {
  width: 100%;
  min-height: 44px;
  font-variant-numeric: tabular-nums;
}
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(.5);
  cursor: pointer;
}
@media (prefers-color-scheme: dark) {
  input[type="time"]::-webkit-calendar-picker-indicator,
  input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(.75); }
}
@media (max-width: 560px) { .dt-part.dt-time { flex: 1 1 100%; } }

/* Ida e volta lado a lado, as dicas embaixo das duas (16/10/2026).
   Empilhadas, a dica da ida caía colada no título da volta. O campo de
   data tem a largura de uma data: na linha inteira, o ícone do calendário
   ficava a um palmo do número e passava despercebido. */
.quando-grade {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: var(--sp-3) var(--sp-5); margin-top: var(--sp-3);
}
.quando-col { flex: 0 1 auto; min-width: 0; max-width: 100%; }
.quando-rotulo {
  display: block; font-size: 13px; font-weight: 600;
  color: var(--text); margin-bottom: var(--sp-1);
}
.quando-grade .dt-part { flex: 0 1 220px; }
.quando-grade input[type="date"], .quando-grade input[type="number"] { width: 220px; max-width: 100%; }
.quando-dicas {
  display: grid; gap: 2px; margin-top: var(--sp-3);
  font-size: 13px; color: var(--text-soft);
}
.quando-dicas .field-hint { margin-top: 0; }
@media (max-width: 560px) {
  .quando-col, .quando-grade .dt-part { flex: 1 1 100%; }
  .quando-grade input[type="date"], .quando-grade input[type="number"] { width: 100%; }
}

/* A FAIXA DO RAIO saiu em 1.217.17, e com ela 98 linhas de folha.

   Era o controle de dois polegares ("de 60 a 200 km"), com o trilho, o
   preenchimento e a dica em horas de estrada. O controle já tinha saído da
   página — nenhum elemento com esses ids ou classes em 30/09/2026 — e
   ficaram a folha e o código que o ligava, que desistia calado por não
   achar o elemento. Mesma regra da bússola, logo abaixo. */

/* A BÚSSOLA saiu em 1.188.0, e com ela 44 linhas de folha.

   Ela era um quadrado de oito direções com a contagem de pontos do
   OpenStreetMap em cada uma, e saiu da tela junto com o OSM no montador.
   O desenho ficou aqui e o código ficou no `wizard.js` — regra de folha
   sem elemento que a use é peso que todo navegador baixa e ninguém
   pinta, e método sem tela é leitura cobrada de quem abre o arquivo. */

/* --------------------------------------- Minha lista ------- */

.alert {
  border-radius: 10px; padding: 10px 13px; font-size: 13px;
  border: 1px solid var(--border); background: var(--surface-2);
}
.alert.ok { border-color: var(--brand); }
.alert.warn { border-color: var(--warn); }

/* --------------------------------- Destinos-chave ---------- */

.taste-legend {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--text-soft);
  margin: 4px 0 12px;
}
/* A legenda é a chave dos três botões de gosto: mesma cor lá e aqui, ou
   ninguém liga um ao outro. */
.taste-legend > span { display: inline-flex; align-items: center; gap: 5px; }
.taste-legend .ico { width: 15px; height: 15px; }
.taste-legend .tl-love .ico { color: var(--accent-txt); }
.taste-legend .tl-like .ico { color: var(--brand); }
.taste-legend .tl-nope .ico { color: var(--danger); }

/* ------------------------------------------ POI discovery -- */

/* Pendências do garimpo: lista curta, cada linha com exemplos ao lado. */

/* ------------------------------------------ Map view ------ */
#view-map.active { display: grid; grid-template-columns: 1fr; height: calc(100vh - var(--topbar-h)); }
@media (min-width: 900px) { #view-map.active { grid-template-columns: 1fr 400px; } }
#leaflet-map { width: 100%; height: 100%; min-height: 320px; background: var(--bg-alt); }

#map-side-panel {
  background: var(--surface);
  border-left: 1px solid var(--border);
  overflow-y: auto;
  padding: 20px;
}
@media (max-width: 899px) {
  #view-map.active { grid-template-rows: 55vh 1fr; height: auto; }
  #map-side-panel { border-left: 0; border-top: 1px solid var(--border); }
}

/* A trilha do Diário: o caminho de níveis, e o botão de subir. Ela é um
   caminho, não um menu — por isso o passo atual não é clicável. */
.diario-trilha {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin: 0 0 8px;
  font-size: 0.95rem;
}
.trilha-passo {
  background: none;
  border: 0;
  padding: 2px 4px;
  /* Musgo, e não terracota, por duas razões que apontam para o mesmo
     lado: a terracota dava 3,63 no tema claro, e migalha de caminho é
     estrutura — o gesto da tela é outro. */
  color: var(--brand);
  cursor: pointer;
  font: inherit;
  border-radius: 6px;
}
.trilha-passo:hover { background: var(--bg-alt); }
.trilha-aqui { font-weight: 700; }
.trilha-sep { opacity: 0.45; }

/* Modo cru do mapa: o OSM vem colorido, e onde o dado desenhado por cima é
   a informação (as cores de cobertura do Diário, a janela de busca do
   planejador) o relevo verde disputa a leitura. O filtro pega SÓ o painel
   dos blocos — contorno e ponto moram noutro painel e passam intactos.

   No claro basta tirar a saturação. No escuro, inverter e girar o matiz é o
   que transforma o mapa claro do OSM num mapa escuro sem precisar de outro
   provedor: o azul da água volta a ser azul depois do giro de 180°. */
.mapa-cru .leaflet-tile-pane {
  filter: saturate(0.35) contrast(0.92) brightness(1.02);
}
@media (prefers-color-scheme: dark) {
  .mapa-cru .leaflet-tile-pane {
    filter: invert(1) hue-rotate(180deg) saturate(0.5) brightness(0.92)
            contrast(0.92);
  }
}

/* A legenda do catálogo fica ACIMA do painel do roteiro, separada por uma
   linha: são duas respostas diferentes (o que existe / o que você montou)
   e coladas elas leriam como uma coisa só. */
.mapa-legenda {
  margin-bottom: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.mapa-legenda-liga {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  margin-bottom: 4px;
}
.mapa-legenda-liga strong { font-size: 1.05rem; }
/* Com dois controles (catálogo e "esconder os que já visitei"), a dica
   corria para o lado do segundo no telefone: ela é linha própria. */
.mapa-legenda > .field-hint { display: block; }
/* Os tipos no mapa (`mapa-do-catalogo.js`): o chip aceso é o tipo que
   aparece; apagado, o tipo some do mapa e segue aqui para voltar. */
.mc-tipos { margin: 4px 0 6px; }
.mc-tipos > summary { cursor: pointer; font-size: 13px; color: var(--text-soft); padding: 6px 0; }
.mc-tipos-lista { display: flex; flex-wrap: wrap; gap: var(--s2); padding-top: var(--s2); }
.mc-tipos-todos { display: flex; gap: var(--s3); padding-top: var(--s1); font-size: 13px; }
.mc-tipos-todos .md-link:disabled { color: var(--text-faint); text-decoration: none; cursor: default; }
.mc-tipo { display: inline-flex; align-items: center; gap: 6px; }
.mc-tipo .ico { width: 15px; height: 15px; }
.mc-tipo small { opacity: .75; font-variant-numeric: tabular-nums; }

.map-hud {
  position: absolute;
  left: 14px;
  bottom: 22px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 500;
}
.hud-btn {
  /* 42px passava perto: o alvo do dedo é 44 e não 42. */
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  border-radius: var(--r-sm);
  font-size: 18px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.hud-btn:hover { background: var(--surface-2); }

.empty-state { text-align: center; padding: 40px 20px; color: var(--text-soft); }
.empty-state .ico { font-size: 40px; display: block; margin-bottom: 12px; opacity: .6; }
.empty-state h4 { margin-bottom: 6px; color: var(--text); }

/* ------------------------------------------ Summary KPIs -- */
.summary-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 22px; }
.kpi {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 14px;
  text-align: center;
}
.kpi strong { display: block; font-size: 21px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.kpi span { display: block; font-size: 11.5px; color: var(--text-soft); margin-top: 2px; text-transform: uppercase; letter-spacing: .04em; }

/* ---- De que é feito o custo estimado ----
   O azulejo do custo é o único que abre. Ele continua parecendo azulejo
   (a grade se lê de relance e um botão com outra cara quebraria isso) e
   só a seta e o cursor dizem que ele responde. */
.kpi-conta {
  font: inherit; color: inherit; cursor: pointer; width: 100%;
  -webkit-appearance: none; appearance: none;
}
.kpi-conta:hover { border-color: var(--border-strong); }
.kpi-conta .ico {
  width: 12px; height: 12px; vertical-align: -1px;
  transition: transform .15s ease;
}
.kpi-conta[aria-expanded="true"] .ico { transform: rotate(180deg); }
.conta {
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2);
  padding: 4px 14px 12px; margin: -12px 0 22px;
}
.conta-linha {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; padding: 9px 0; border-bottom: 1px solid var(--border);
}
.conta-linha:last-of-type { border-bottom: 0; }
/* Regra DIRETA no filho: a folha tem cor própria para `small`, e pintar
   só `.conta` deixaria a explicação com a cor de antes. */
.conta-nome { font-size: 13px; color: var(--text); }
.conta-nome small {
  display: block; font-size: 11px; color: var(--text-faint);
  margin-top: 2px; line-height: 1.35;
}
.conta-valor {
  font-size: 14px; font-weight: 650; white-space: nowrap;
  font-variant-numeric: tabular-nums; color: var(--text);
}
/* A parcela que o app não sabe — ele assumiu. Marcada com traço, não com
   cor de alerta: não é erro, é suposição. */
.conta-suposta { border-left: 2px solid var(--border-strong); padding-left: 10px; }
.conta-total { border-top: 1px solid var(--border-strong); margin-top: 2px; }
.conta-total .conta-nome, .conta-total .conta-valor { font-weight: 700; }
.conta-nota {
  display: block; margin-top: 10px; font-size: 11px;
  color: var(--text-faint); line-height: 1.45;
}

/* ---- Quem vai na viagem, dentro do roteiro ----
   A lista de pessoas mora em `quem-esta-na-viagem.js` e é a mesma da tela
   de Viagens; aqui ela só ganha um lugar para nascer. */
.te-quem { margin: 0 0 18px; }
.te-quem small {
  display: block; margin-top: 5px; font-size: 11.5px;
  color: var(--text-faint);
}
.te-quem .quem-painel { margin-top: 12px; }

/* ---- A rota do dia no Google Maps ----
   Botão FANTASMA, e não terracota: o gesto principal do painel é salvar a
   viagem, e um segundo terracota na mesma tela seria nenhum. Era um link
   sublinhado, e passava despercebido (17/10/2026). */
.dgm { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 10px;
  text-decoration: none; }
.dgm .ico { width: 15px; height: 15px; }
.dgm-de { font-size: 11.5px; font-weight: 500; color: var(--text-soft); }

/* ------------------------------------------ Modal --------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 1500;
  background: rgba(8, 12, 20, .72);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  overflow-y: auto;
}
.modal-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  width: 100%;
  max-width: 720px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 20px 22px 12px;
}
.modal-body { padding: 0 22px; overflow-y: auto; flex: 1; }
.modal-foot { padding: 16px 22px 20px; border-top: 1px solid var(--border); }
.onb-lead { color: var(--text-soft); font-size: 14px; }
.onb-progress { margin: 14px 0 4px; text-align: center; }

/* ----------------------------------------- Quiz gostos ---- */
.taste-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 620px) { .taste-grid { grid-template-columns: 1fr; } }

.taste-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface-2);
}
.taste-label { font-size: 13.5px; font-weight: 550; display: flex; align-items: center; gap: 7px; }
.taste-options { display: flex; gap: 4px; flex: none; }
.taste-opt {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  border-radius: var(--r-sm);
  color: var(--text-soft);
  cursor: pointer;
  opacity: .45;
  padding: 0;
}
/* O desenho carrega o sentido; a cor só confirma. Quem não distingue
   vermelho de verde ainda lê coração, traço e barra. */
.taste-opt .ico { width: 19px; height: 19px; vertical-align: 0; }
.taste-opt:hover { opacity: .85; }
.taste-opt[aria-pressed="true"] { opacity: 1; border-width: 2px; }
.taste-opt.taste-love[aria-pressed="true"] {
  border-color: var(--accent); background: var(--brand-soft); color: var(--accent-txt);
}
.taste-opt.taste-like[aria-pressed="true"] {
  border-color: var(--brand); background: var(--brand-soft); color: var(--brand);
}
.taste-opt.taste-nope[aria-pressed="true"] {
  border-color: var(--danger); color: var(--danger);
}

.chip.chip-avoid { opacity: .45; text-decoration: line-through; }

/* --------------------------------------- Já fui / badges -- */
.badges { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }

.year-bars {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  height: 130px;
  margin-top: 12px;
  padding-bottom: 4px;
  overflow-x: auto;
}
.year-bar {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  min-width: 48px;
  height: 100%;
}
.year-fill {
  width: 100%;
  background: var(--brand);
  border-radius: 4px 4px 0 0;
  min-height: 4px;
}
.year-bar small { font-size: 11px; color: var(--text-soft); }
.year-bar strong { font-size: 13px; }

/* ------------------------------------------ Recibo -------- */
.receipt-card {
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 16px;
  background: var(--surface-2);
}
.receipt-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.receipt-total {
  font-size: 24px;
  font-weight: 700;
  color: var(--brand);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.receipt-items {
  margin-top: 12px;
  border-top: 1px solid var(--border);
  padding-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.receipt-items > div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13.5px;
}
.receipt-items span:last-child {
  font-variant-numeric: tabular-nums;
  color: var(--text-soft);
  white-space: nowrap;
}
.split-box {
  margin-top: 14px;
  padding: 12px 14px;
  background: var(--brand-soft);
  border: 1px solid var(--brand);
  border-radius: var(--r-sm);
}

/* ------------------------------------------ Clima --------- */
.wx-strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  margin-bottom: 14px;
  padding-bottom: 4px;
  scrollbar-width: thin;
}
.wx-day {
  flex: none;
  min-width: 92px;
  max-width: 124px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  text-align: center;
}
.wx-day.rainy { border-color: var(--info); background: var(--brand-soft); }
.wx-dow { font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--text-soft); }
/* O lugar daquele dia. Duas linhas no máximo: "Santo Antônio da Patrulha"
   esticaria o cartão e a faixa inteira junto. A UF sai do cartão e fica no
   `title` — dentro da faixa ela é ruído, e a viagem quase sempre é num
   estado só. */
.wx-onde {
  font-size: 10.5px; line-height: 1.25; color: var(--text-soft);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* De onde veio o número — a faixa antiga era a semana da origem inteira,
   e não dizia isso em lugar nenhum. */
.wx-fonte {
  display: block; margin: -8px 0 14px; font-size: 11px;
  color: var(--text-faint);
}
.wx-temp { font-size: 14px; font-weight: 650; font-variant-numeric: tabular-nums; }
.wx-rain { font-size: 12px; color: var(--info); font-weight: 600; }
.wx-cond { font-size: 10.5px; color: var(--text-faint); line-height: 1.2; }
.wx-box {
  padding: 10px 14px;
  background: var(--surface-2);
  border-radius: var(--r-sm);
  margin-bottom: 14px;
}

.warn-box {
  border-left: 3px solid var(--warn);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 11px 14px;
  margin-bottom: 18px;
  font-size: 13px;
  color: var(--text-soft);
}
.warn-box ul { margin: 0; padding-left: 18px; }
.warn-box li + li { margin-top: 4px; }

/* ------------------------------------- Onde dormir ------ */
/* Fecha o dia, e por isso vem depois da timeline e não dentro dela: não é
   uma parada do roteiro, é a decisão que sobra para a pessoa tomar. */
.od {
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  padding: 12px 14px;
  margin: 0 0 18px 20px;
  font-size: 13px;
}
.od-linha { display: flex; align-items: center; gap: 7px; }
.od-quando { color: var(--text-soft); margin-top: 3px; }
/* Regra DIRETA no `small`: a folha já tem cor para `small`, e pintar
   só o `.od` deixaria esta linha com a cor de antes. */
.od-nota { display: block; margin-top: 6px; color: var(--text-faint); }
.od-links { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.od-link {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--brand);
  font-weight: 600;
  text-decoration: none;
}
.od-link:hover { border-color: var(--brand); }
.od-link .ico { width: 14px; height: 14px; }

/* ------------------------------------------ Timeline ------ */
.day-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 22px 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.day-head:first-child { margin-top: 0; }
.day-head h4 { font-size: 15px; }
.day-head .day-meta { font-size: 12px; color: var(--text-faint); white-space: nowrap; }

.timeline { position: relative; padding-left: 20px; }
.timeline::before {
  content: "";
  position: absolute;
  left: 5px; top: 6px; bottom: 6px;
  width: 2px;
  background: var(--border);
}
.stop { position: relative; padding: 0 0 18px; }
.stop::before {
  content: "";
  position: absolute;
  left: -19px; top: 5px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--brand);
  border: 2px solid var(--surface);
}
.stop.rest_break::before { background: var(--info); }
.stop.lunch::before, .stop.dinner::before,
.stop.breakfast::before, .stop.snack::before { background: var(--accent); }
.stop.accommodation::before { background: #9333ea; width: 12px; height: 12px; left: -20px; }
.stop h5 { margin: 0; font-size: 14.5px; font-weight: 600; }
.stop .times { font-size: 12.5px; color: var(--text-soft); font-variant-numeric: tabular-nums; margin-top: 1px; }
.stop .travel { font-size: 12px; color: var(--text-faint); margin-top: 3px; }

/* ------------------------------------------ Cards --------- */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 14px; }
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 16px;
  cursor: pointer;
}
.card:hover { border-color: var(--border-strong); }
.card.active { border-color: var(--brand); background: var(--brand-soft); }
.card h4 { margin-bottom: 3px; }

/* ------------------------------------------ Toast/banner -- */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  background: var(--text);
  color: var(--bg);
  padding: 11px 20px;
  border-radius: var(--r-lg);
  font-size: 14px;
  font-weight: 550;
  z-index: 1200;
  box-shadow: var(--shadow);
  /* `max-content`: ver `.update-banner`, logo abaixo. */
  width: max-content;
  max-width: calc(100vw - 40px);
  text-align: center;
}

.update-banner {
  position: fixed;
  left: 50%; bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  /* Sem `max-content`, `left: 50%` deixa só METADE da tela para a caixa:
     no iPhone o texto quebrava em três linhas ("Nova / versão /
     disponível."). Quina, não pílula: é aviso com botão, não etiqueta. */
  width: max-content; max-width: calc(100vw - 32px);
  display: flex; align-items: center; gap: 14px;
  background: var(--brand);
  color: var(--brand-text);
  padding: 8px 8px 8px 16px;
  border-radius: var(--r-lg);
  z-index: 1200;
  font-size: 14px;
  font-weight: 550;
}
.update-banner button {
  border: 0;
  background: var(--brand-text);
  color: var(--brand);
  font: inherit;
  font-weight: 700;
  padding: 6px 14px;
  border-radius: var(--r);
  cursor: pointer;
}

.pre {
  font-family: var(--mono);
  font-size: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 14px;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

.spinner {
  display: inline-block;
  width: 15px; height: 15px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.hidden { display: none !important; }
.divider { height: 1px; background: var(--border); margin: 20px 0; }

/* ------------------------------------------------ Login / cadastro --- */
/* Portão de tela cheia: cobre topbar e conteúdo até haver sessão. */
.auth-gate {
  position: fixed; inset: 0; z-index: 300;
  background: var(--bg);
  overflow-y: auto;
  display: grid; place-items: center;
  padding: 28px 20px;
}
.auth-gate-inner { width: 100%; max-width: 400px; }
/* Enquanto o portão está de pé, a ferramenta some por completo — nem a
   topbar nem as abas ficam acessíveis. */
body.gated .topbar,
body.gated #view { display: none; }
.auth-foot {
  text-align: center; margin-top: 18px;
  font-size: 12.5px; color: var(--text-faint);
}

/* O card do login em si. */
#auth-box {
  width: 100%; margin: 0 auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  padding: 30px 28px;
}
.auth-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 22px; }
.auth-logo {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center; font-size: 24px;
  border-radius: 13px; background: var(--brand-soft);
}
.auth-brand-txt strong { display: block; font-size: 16px; line-height: 1.2; }
/* 4,4:1 de contraste — medido na entrada, a 375px, abaixo dos 4,5:1 que a
   norma pede para texto pequeno. É a linha que diz o que o app é para quem
   chegou agora. Só a cor: o `font-size` que estava aqui era regra MORTA —
   `.auth-brand-txt .marca-lema`, logo abaixo, tem uma classe a mais e
   vence. O tamanho do lema é decisão do desenho da marca, e mora lá. */
.auth-brand-txt small { color: var(--text-soft); }
#auth-title { font-size: 21px; margin-bottom: 4px; }
.auth-sub { color: var(--text-soft); font-size: 13.5px; margin-bottom: 22px; }

/* Campo de senha com botão mostrar/ocultar embutido. */
.auth-pass { position: relative; }
.auth-pass input { padding-right: 78px; }
.auth-eye {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  border: none; background: transparent; color: var(--brand);
  font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer; padding: 6px 8px; border-radius: var(--r-sm);
}
.auth-eye:hover { background: var(--brand-soft); }

/* Erro inline, mais claro que só um toast que some.
   O vermelho era escrito à mão aqui — `#e5484d` — e a frase que
   justificava dizia que "funciona nos dois temas". Medido: 4,04 sobre
   `--surface` no escuro. `--danger` é clareado justamente para o tema
   escuro; o hexadecimal fixo não sabe em que tema está. */
.auth-error {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 38%, transparent);
  color: var(--danger);
  border-radius: var(--r-sm);
  padding: 10px 12px; font-size: 13px; margin-bottom: 16px;
}

.auth-switch {
  text-align: center; margin-top: 18px;
  font-size: 13.5px; color: var(--text-soft);
}
.auth-link {
  border: none; background: none; color: var(--brand);
  font: inherit; font-weight: 600; cursor: pointer; padding: 0 2px;
}
.auth-link:hover { text-decoration: underline; }

code { overflow-wrap: anywhere; }

/* O dedo na entrada.
   Medido na produção a 375px: "Esqueci minha senha" era um alvo de 20px de
   altura, "Criar conta" idem, e os dois links legais do rodapé, de 15px. O
   dedo pede 44. Quem erra o toque aqui é justamente quem já não está
   conseguindo entrar — e o erro não avisa: leva para outra tela.

   `hover: none` e não largura: quem decide é o ponteiro, não o tamanho do
   monitor. */
@media (hover: none) {
  .auth-link,
  .auth-foot a {
    display: inline-block;
    box-sizing: border-box;
    min-height: 44px;
    padding: 12px 10px;
  }
  /* As duas linhas de `.auth-switch` ficam a 38px de centro a centro. Com
     alvos de 44px elas se sobreporiam por 6px, e a faixa do meio abriria a
     tela errada sem que nada na tela explicasse por quê. */
  .auth-switch { margin-top: 4px; }
  /* Cabe dentro do campo, que tem 47px. */
  .auth-eye { min-height: 44px; padding: 6px 10px; }
}

@media (max-width: 700px) {
  /* Lados só. O atalho `padding: 0 10px` ZERA o topo, e com ele some a
     faixa reservada ao entalhe — foi assim que a barra cresceu de altura e
     a busca continuou encostada no alto-falante. */
  .topbar { padding-left: 10px; padding-right: 10px; gap: 10px; }
  .brand-name { display: none; }
  .brand { flex: none; }
  .nav-btn { padding: 7px 12px; font-size: 13px; }
  .container { padding: 20px 14px 50px; }
  .panel { padding: 16px; border-radius: var(--r); }
  .steps { gap: 4px; }
  .step-dot { font-size: 10.5px; }
  .wizard-actions { flex-direction: column-reverse; }
  .wizard-actions .btn { width: 100%; }

}

/* ------------------------------------ Qualidade de dados ---- */
.dq-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.dq-card {
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface-2);
  padding: 13px 15px;
}
.dq-card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-bottom: 4px;
}
.dq-health {
  font-size: 15px; font-weight: 700;
  border-radius: var(--r-pill); padding: 2px 10px;
}
.dq-hok { color: var(--ok); background: color-mix(in srgb, var(--ok) 15%, transparent); }
.dq-hmed { color: var(--warn); background: color-mix(in srgb, var(--warn) 15%, transparent); }
.dq-hbad { color: var(--danger); background: color-mix(in srgb, var(--danger) 15%, transparent); }

.dq-bars { display: flex; height: 7px; border-radius: 999px; overflow: hidden;
  background: var(--border); margin: 9px 0 5px; }
.dq-bar.ok { background: var(--ok); }
.dq-bar.bad { background: var(--danger); }
.dq-legend { color: var(--text-faint); font-size: 11.5px; }
.dq-crit { color: var(--danger); }

/* Faixas de impacto no roteiro */
.dq-impacto {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 10px; margin-bottom: 14px;
}
@media (max-width: 620px) { .dq-impacto { grid-template-columns: 1fr; } }
.dq-imp {
  display: flex; flex-direction: column; gap: 3px; text-align: left;
  padding: 12px 13px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface-2);
  color: var(--text); font: inherit; cursor: pointer;
  border-left: 4px solid var(--border-strong);
}
.dq-imp:hover:not(:disabled) { border-color: var(--brand); }
.dq-imp:disabled { opacity: .45; cursor: default; }
.dq-imp[aria-pressed="true"] { background: var(--brand-soft); border-color: var(--brand); }
.dq-imp-n { font-size: 18px; font-weight: 700; }
.dq-imp strong { font-size: 13.5px; }
.dq-imp small { font-size: 11.5px; color: var(--text-faint); line-height: 1.3; }
.dq-imp-bloqueia { border-left-color: var(--danger); }
.dq-imp-atrapalha { border-left-color: var(--warn); }
.dq-imp-enfraquece { border-left-color: var(--info); }

/* Barra de filtros (busca + cidade) */
.dq-filtros {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
  margin: 14px 0 4px;
}
.dq-filtros .dq-busca { flex: 1 1 220px; min-width: 180px; }
.dq-filtros .dq-cidade { flex: 0 1 200px; }
.dq-filtros .dq-ordem { flex: 0 1 170px; }
.dq-filtros .btn { flex: none; }
.dq-lista { display: flex; flex-direction: column; gap: 5px; }

.dq-issues { display: flex; flex-direction: column; gap: 5px; }
.dq-issue {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface-2);
  color: var(--text); font: inherit; font-size: 13.5px;
  cursor: pointer; text-align: left; width: 100%;
}
.dq-issue:hover { border-color: var(--brand); }
.dq-issue[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-soft); }
.dq-issue.erro { border-left: 3px solid var(--danger); }
.dq-issue.aviso { border-left: 3px solid var(--warn); }
/* Gravidade em duas pistas: a forma (octógono, triângulo, círculo) e a
   cor. Sozinha, a cor exclui quem não a distingue. */
.dq-sev .ico { width: 17px; height: 17px; }
.dq-imp-n .ico { width: 19px; height: 19px; vertical-align: -.15em; }
.sev-erro, .sev-bloqueia { color: var(--danger); }
.sev-aviso, .sev-atrapalha { color: var(--warn); }
.sev-info, .sev-enfraquece { color: var(--brand); }
.dq-issue.info { border-left: 3px solid var(--info); }
.dq-n { font-weight: 700; min-width: 52px; font-variant-numeric: tabular-nums; }
.dq-lbl { flex: 1 1 auto; }
.dq-campo { font-size: 11px; color: var(--text-faint); flex: none; }

/* Sem `overflow: hidden`: ele anulava `position: sticky` do Salvar lá
   dentro, em silêncio — medido, a barra passava batido enquanto na bancada
   grudava. O recorte existia por causa de UMA coisa, o fundo que a linha do
   título ganha ao passar o mouse, e é ela que passa a se recortar. */
.dq-rec { border: 1px solid var(--border); border-radius: var(--r-sm);
  margin-bottom: 6px; background: var(--surface-2); }
.dq-rec-head {
  display: flex; align-items: center; gap: 8px 10px; width: 100%;
  flex-wrap: wrap;
  padding: 10px 12px; border: 0; background: none; color: var(--text);
  font: inherit; font-size: 13.5px; cursor: pointer; text-align: left;
}
.dq-rec-head:hover { background: var(--surface); }
/* Nome ocupa a primeira linha inteira; meta e tags descem para a segunda,
   assim o nome nunca é espremido a zero pelas tags de problema. */
.dq-rec-nome { font-weight: 600; flex: 1 1 100%; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dq-rec-meta { font-size: 11.5px; color: var(--text-faint); flex: none; }
.dq-rec-tags { display: flex; gap: 4px; flex: 1 1 auto; flex-wrap: wrap; }
.dq-minitag {
  font-size: 10px; color: var(--text-soft); white-space: nowrap;
  border: 1px solid var(--border-strong); border-radius: 999px; padding: 1px 7px;
}
/* Ausência declarada é trabalho concluído, não pendência: entra na cor da
   marca, não na de alerta, senão a linha continua parecendo um problema
   depois de alguém ter resolvido. */

/* A caixa fica logo abaixo do campo que ela encerra, dentro da mesma
   célula: como célula própria da grade ela caía numa coluna qualquer da
   linha seguinte, longe do campo e sem dizer a que se referia. */
.dq-ausencia {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; color: var(--text-faint);
  cursor: pointer; user-select: none; margin-top: 2px;
}
.dq-ausencia input { width: 15px; height: 15px; flex: none; margin: 0; }
.dq-ausencia:hover { color: var(--text-soft); }
.dq-ausencia:has(input:checked) { color: var(--brand); font-weight: 600; }

/* ------------------------------------------ repetidos, em grupo -- */
/* A borda esquerda amarra os membros: sem ela, quinze linhas seguidas não
   mostram onde um conjunto termina e o outro começa. */
.dq-grupos { display: flex; flex-direction: column; gap: 12px; }
.dq-grupo {
  border: 1px solid var(--border); border-left: 3px solid var(--brand);
  border-radius: var(--r-sm); background: var(--surface-2); overflow: hidden;
}
.dq-grupo-cab {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; background: var(--brand-soft);
  font-size: 13px; font-family: ui-monospace, monospace;
}
.dq-grupo-cab strong { font-weight: 700; }
.dq-grupo-item {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 12px;
  width: 100%; padding: 9px 12px; text-align: left;
  background: none; border: 0; border-top: 1px solid var(--border);
  color: var(--text); cursor: pointer; font: inherit;
}
.dq-grupo-item:hover { background: var(--surface); }
.dq-grupo-nome { font-size: 13.5px; font-weight: 600; }
.dq-grupo-meta { font-size: 11.5px; color: var(--text-faint); grid-column: 1; }
/* A origem da posição é a resposta para "qual delas está certa": some no
   meio do texto se não tiver cor própria. */
.dq-grupo-fonte {
  /* Coluna e linha explícitas: sem elas o posicionamento automático dava a
     primeira coluna ao selo e jogava o nome do lugar para a direita. */
  grid-column: 2; grid-row: 1 / span 2;
  align-self: center; justify-self: end;
  font-size: 11px; padding: 2px 8px; border-radius: var(--r-pill);
  border: 1px solid var(--border-strong); white-space: nowrap;
}
.dq-grupo-fonte.boa { color: var(--brand); border-color: var(--brand); }
.dq-grupo-fonte.fraca { color: var(--warn); border-color: var(--warn); }
.dq-grupo-corpo { padding: 0 12px 12px; border-top: 1px solid var(--border); }

.dq-amostra { display: flex; flex-direction: column; gap: 4px; margin-top: 8px;
  max-height: 260px; overflow-y: auto; }

.dq-rec-body { padding: 4px 12px 14px; border-top: 1px solid var(--border); }
/* A caixa de marcar da linha não tinha rótulo: o texto ao lado é um botão
   que abre a ficha, então não dava para embrulhar os dois. Ela media 20x20
   — metade do dedo. Agora tem um rótulo só dela, invisível no texto e com
   altura de dedo, e a regra geral de `label:has(> input)` faz o resto. */
.dq-pick-alvo { display: inline-flex; align-items: center; flex: none; }
.dq-rec-top { display: flex; align-items: center; gap: 8px; padding-left: 10px;
  border-radius: var(--r-sm) var(--r-sm) 0 0; overflow: hidden; }
.dq-rec-top .dq-rec-head { flex: 1 1 auto; }

/* Automações e exclusão em lote */
.dq-auto {
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2); padding: 12px 14px; margin-bottom: 14px;
}
.dq-lote {
  display: flex; align-items: center; gap: 12px;
  margin: 4px 0 10px; flex-wrap: wrap;
}
.dq-sugestoes { display: flex; flex-direction: column; gap: 4px;
  max-height: 320px; overflow-y: auto; }
.dq-sug {
  display: flex; flex-direction: column; gap: 2px;
  padding: 7px 10px; border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface);
}
.dq-sug-nome { font-size: 13px; }
.dq-sug-campos { font-size: 11.5px; color: var(--text-faint); }

.dq-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px; margin: 12px 0; }
.dq-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px;
  color: var(--text-soft); }
.dq-field input, .dq-field textarea { font-size: 13px; padding: 7px 9px; }
.dq-field.faltando input, .dq-field.faltando textarea { border-color: var(--warn); }
/* Pseudo-elemento não aceita `<use>`, então o triângulo entra como
   máscara: a forma vem do mesmo desenho do sprite e a cor de `background`,
   que é o único jeito de um `::after` herdar a paleta. */
.dq-field.faltando > span::after {
  content: "";
  display: inline-block;
  width: .95em; height: .95em;
  margin-left: .3em;
  vertical-align: -.15em;
  background: var(--warn);
  -webkit-mask: var(--ico-atencao) center / contain no-repeat;
  mask: var(--ico-atencao) center / contain no-repeat;
}
/* ---- Cadastros: criar, filtrar, listar (nesta ordem) ---- */
.dq-novo {
  border: 1px solid var(--brand); border-radius: var(--r);
  background: var(--brand-soft); margin-bottom: var(--s4);
}
.dq-novo > summary {
  display: flex; align-items: center; gap: var(--s3); cursor: pointer;
  padding: var(--s3) var(--s4); list-style: none; font-size: 13px;
}
.dq-novo > summary::-webkit-details-marker { display: none; }
.dq-novo-ico {
  flex: none; width: 30px; height: 30px; display: grid; place-items: center;
  /* Era um disco cheio de musgo com um "＋" branco por cima: 3,08 medido,
     e o "＋" era o caractere U+FF0B, não um desenho do conjunto. Agora é
     contorno, como o resto da folha desenha ícone, e o traço carrega a
     cor do musgo com o contraste do próprio token. */
  border-radius: 50%; color: var(--brand);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand) 38%, transparent);
}
.dq-novo-ico .ico { width: 18px; height: 18px; }
.dq-novo summary strong { display: block; font-size: 14px; color: var(--text); }
.dq-novo summary small { color: var(--text-soft); font-size: 11.5px; }
.dq-novo-corpo {
  padding: 0 var(--s4) var(--s4); border-top: 1px solid var(--border);
  padding-top: var(--s4); margin-top: var(--s2);
}
/* O cadastro novo é curto e vive dentro de um painel de outra cor: a barra
   não tem rolagem para acompanhar, e o fundo opaco dela só apareceria como
   um retângulo de cor errada no meio do verde. */
.dq-novo-corpo .dq-form-actions {
  position: static; background: none; border-top: 0; padding: 0;
  margin-top: var(--s3);
}
/* Pelo link do Maps: o campo ocupa a linha, o botão fica ao lado; no
   telefone o botão desce sozinho (wrap), sem apertar o campo. A linha fina
   de baixo separa "colar o link" de "conferir o que veio". */
.dq-link {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s2) var(--s3);
}
.dq-link-campo { flex: 1 1 320px; margin: 0; }
.dq-link-msg {
  margin: var(--s2) 0 var(--s4); padding-bottom: var(--s3);
  border-bottom: 1px solid var(--border);
}

.dq-filtro-bloco {
  border: 1px solid var(--border); border-radius: var(--r);
  padding: var(--s3); background: var(--surface);
}
.dq-atalhos {
  display: flex; gap: var(--s2); flex-wrap: wrap; margin-bottom: var(--s3);
}
.dq-geo {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--s3); margin-top: var(--s3);
}
.dq-avancado {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--s3); margin-top: var(--s3); padding-top: var(--s3);
  border-top: 1px dashed var(--border);
}

/* Fontes: o que ainda não está na base única */

/* O item que não pode entrar. A classe nasceu junto com a tranca e ficou
   SEM REGRA NENHUMA: na tela, o barrado era idêntico ao que se podia
   trazer — só a caixa não marcava. "Por que não consigo trazer alguns"
   começa aí: nada dizia quais eram "alguns".

   O motivo é TEXTO em `--danger`, que é cor de texto (clareada no escuro);
   usá-la de fundo atrás de branco dá 3,0:1. */

/* A linha que conta o outro lado e leva até ele. */

/* O status no cartão. Não é etiqueta de contagem, então não é pílula:
   quina, como todo controle deste app. E é estrutura, não gesto — musgo e
   neutro, nunca terracota, que fica reservado para a coisa que a pessoa
   veio fazer. */
.dq-status {
  display: inline-flex; align-items: center; gap: 5px;
  align-self: flex-start; flex: 0 0 auto;
  padding: 3px 8px; border: 1px solid var(--border-strong);
  border-radius: var(--r-sm); background: var(--surface);
  color: var(--text-soft); font-size: 11px; font-weight: 600;
  letter-spacing: .02em; cursor: pointer;
}
.dq-status svg { width: 13px; height: 13px; }
.dq-status[aria-pressed="true"] {
  border-color: var(--brand); color: var(--brand); background: var(--brand-soft);
}
.dq-status:hover { border-color: var(--text-soft); }
.dq-status:disabled { opacity: .55; cursor: progress; }

/* ---- Destino principal e entorno (wizard, catálogo curado) ---- */
.md-block { margin-bottom: var(--s5); }
.md-alcance { font-size: 13px; color: var(--text-soft); }
.md-alcance input { width: 90px; margin: 0 4px; }
.md-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--s3);
}
.md-card {
  display: flex; flex-direction: column; gap: var(--s2);
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); overflow: hidden;
}
.md-card.escolhido { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
.md-foto {
  display: grid; place-items: center; aspect-ratio: 4 / 3; position: relative;
  background: var(--surface-2); overflow: hidden;
}
/* A foto ocupa a caixa, e não o contrário.
   Medido em produção: com `aspect-ratio` no pai e `height: 100%` no filho, o
   navegador não resolve a porcentagem — a altura do pai vem da proporção, e
   isso não conta como altura definida. A `<img>` ficava com a altura
   INTEIRA (924px dentro de um quadro de 390), o recorte passava a ser o
   `overflow` do pai, sempre pelo meio, e `object-position` não tinha efeito
   nenhum. O mesmo padrão que `.acv-foto` já usava é o que funciona. */
/* `center` continua sendo o padrão: quem tem ponto de interesse recebe um
   `object-position` inline, e quem não tem fica como sempre esteve. */
.md-foto img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: center;
}
.md-sem-foto { color: var(--text-faint); font-size: 12px; }
.md-corpo { display: flex; flex-direction: column; gap: 2px; padding: 0 var(--s3); }
.md-corpo strong { font-size: 14px; line-height: 1.25; }
.md-corpo small { color: var(--text-soft); font-size: 11.5px; }
.md-desc {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; margin-top: 2px;
}
.md-card .md-acao { margin: 0 var(--s3) var(--s3); }
.md-escolhido {
  display: flex; flex-direction: column; gap: 2px; padding: var(--s3);
  border: 1px solid var(--brand); border-radius: var(--r-sm);
  background: var(--brand-soft); margin-bottom: var(--s3);
}
.md-cabe { margin-bottom: var(--s3); font-size: 13px; }
.md-ok { color: var(--ok); }
.md-estoura {
  padding: var(--s3); border-radius: var(--r-sm);
  background: rgba(192,125,16,.12); color: var(--warn);
}
.md-sugerido { border-color: var(--brand); }
.md-filtros {
  display: flex; gap: var(--s2); flex-wrap: wrap; margin-bottom: var(--s3);
}
.md-filtros input[type="search"] { flex: 1 1 200px; }
.md-filtros .dq-select { flex: 0 1 220px; }
.md-visitados { align-self: center; }
#ar-visitados-aviso:empty { display: none; }
/*
  Selo de "já visitei". Discreto de propósito: ele informa, não recomenda —
  o cartão continua sendo do lugar, não do selo. Fica em linha própria
  porque nome de destino é longo e empurrá-lo para uma segunda linha
  cobraria do que importa para pagar o aviso.
*/
.md-visitado {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-start;
  margin-top: 2px; padding: 1px 6px; border-radius: 999px;
  font-size: 10.5px; line-height: 1.6; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ok); background: var(--brand-soft);
  border: 1px solid var(--border);
}
.md-visitado svg { width: 12px; height: 12px; }
.md-visao {
  display: grid; grid-template-columns: minmax(280px, 1.4fr) minmax(240px, 1fr);
  gap: var(--s4); margin-bottom: var(--s4); align-items: start;
}
@media (max-width: 720px) { .md-visao { grid-template-columns: 1fr; } }
.md-mapa {
  height: 320px; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--border); background: var(--surface-2);
}
.md-rosca-svg { width: 100%; max-width: 260px; height: auto; display: block; }
.rosca-fatia { cursor: pointer; transition: fill-opacity .12s ease; }
.rosca-fatia:hover { fill-opacity: .95 !important; }
.rosca-fatia.ativa { stroke: var(--text); stroke-width: 1.6; }
.rosca-n { font-size: 22px; font-weight: 700; fill: var(--text); }
.rosca-rot { font-size: 9px; fill: var(--text-faint); text-transform: uppercase; }
.md-legenda { display: flex; flex-direction: column; gap: 3px; margin-top: var(--s2);
  max-height: 220px; overflow-y: auto; }
.md-leg {
  display: flex; align-items: center; gap: 6px; padding: 3px 6px;
  border: 0; border-radius: var(--r-sm); background: none; cursor: pointer;
  font: inherit; font-size: 11.5px; color: var(--text-soft); text-align: left;
}
.md-leg:hover { background: var(--surface-2); }
.md-leg[aria-pressed="true"] { background: var(--brand-soft); color: var(--brand); }
.md-leg-cor { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.md-leg-faixas { font-size: 10px; color: var(--text-faint); margin-top: 4px; }
.md-mais { margin-top: var(--s3); }
.te-salvar {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  margin-top: var(--s3); padding: var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.te-salvar small { color: var(--text-soft); font-size: 11.5px; }
.te-salvo { color: var(--ok); font-size: 13px; font-weight: 650; }
.te-salvar #btn-replanejar { margin-left: auto; }
.te-replan-dica {
  display: block; margin-top: 6px; color: var(--text-soft); font-size: 11.5px;
}

/* Replanejar mora no cartão da viagem: o roteiro salvo é o começo da
   próxima versão dele, não um registro só de leitura. */
.card-rodape {
  display: flex; align-items: center; gap: var(--s2);
  margin-top: var(--s2); flex-wrap: wrap;
}

.ar-topo {
  display: grid; grid-template-columns: minmax(280px, 2fr) minmax(200px, 1fr);
  gap: var(--s4); margin-bottom: var(--s4); align-items: start;
}
@media (max-width: 720px) { .ar-topo { grid-template-columns: 1fr; } }
.ar-mapa {
  height: 340px; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--border); background: var(--surface-2);
}
.ar-lado { display: flex; flex-direction: column; gap: var(--s2); }
.ar-resumo {
  padding: var(--s3); border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2);
  display: flex; flex-direction: column; gap: 2px; font-size: 13px;
}
.ar-resumo strong { font-size: 20px; color: var(--brand); }
.ar-resumo small { color: var(--text-soft); font-size: 11.5px; }
.ar-agrupar { font-size: 12px; color: var(--text-soft); }
.ar-agrupar .dq-select { width: 100%; margin-top: 4px; }

/* A ordem do entorno (`a-ordem-do-entorno.js`): o número no mapa e a lista.
   As cores são as do mapa — o verde do que entrou e o ouro do principal —,
   iguais nos dois temas porque o fundo é a base do mapa, não a página. */
:root { --ar-rota: #2aa79b; --ar-principal: #e0a800; --ar-num-texto: #0b1210; }
.leaflet-marker-icon.ar-num {
  display: grid; place-items: center; border-radius: 50%;
  background: var(--ar-rota); color: var(--ar-num-texto);
  border: 2px solid var(--ar-num-texto); box-sizing: border-box;
  font: 800 12px/1 var(--sans); cursor: pointer;
}
.leaflet-marker-icon.ar-num-principal { background: var(--ar-principal); cursor: default; }
/* Os dias do roteiro no mapa (`os-dias-no-mapa.js`): o número na cor do
   dia — a cor vem no `style`, por dia — e o seletor abaixo do zoom. */
.leaflet-marker-icon.dm-num { background: none; border: 0; }
/* O pin da visita (19/10/2026): a gota com sombra curta, que lê como
   objeto sobre o mapa e não como mancha. */
.leaflet-marker-icon.dm-pin svg { display: block; overflow: visible; cursor: pointer;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, .45)); transition: transform .12s ease; transform-origin: 50% 100%; }
.leaflet-marker-icon.dm-pin:hover svg { transform: scale(1.12); }
.leaflet-marker-icon.dm-seta { background: none; border: 0; pointer-events: none; }
.leaflet-marker-icon.dm-seta svg { display: block; filter: drop-shadow(0 0 1.5px rgba(0, 0, 0, .7)); }
.leaflet-control.dm-dias {
  background: var(--surface); color: var(--text); padding: var(--s2);
  display: grid; gap: var(--s1); max-width: 220px;
}
.dm-select { font: 600 13px/1.2 var(--sans); min-height: 36px; }
.dm-legenda { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s2); font-size: 11.5px; color: var(--text-soft); }
.dm-leg { display: inline-flex; align-items: center; gap: 4px; }
.dm-leg i { width: 14px; height: 4px; border-radius: 2px; display: inline-block; }
/* O balão da visita (`o-balao-da-parada.js`): na folha do app, e não no
   branco do Leaflet — os botões são os do app e precisam do fundo dele. */
.dm-pop .bp-casca, .dm-pop .bp-ponta {
  background: var(--surface); color: var(--text); border-radius: var(--r-lg);
}
.dm-pop .bp-miolo { margin: var(--s3); }
.bp { display: grid; grid-template-columns: 96px 1fr; gap: var(--s3); align-items: start; }
.bp-foto {
  width: 96px; height: 96px; border-radius: var(--r); overflow: hidden;
  display: grid; place-items: center; background: var(--surface-2); color: var(--text-faint);
}
.bp-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bp-txt { display: grid; gap: 2px; font-size: 13px; color: var(--text-soft); min-width: 0; }
.bp-cab { display: flex; align-items: baseline; gap: var(--s2); justify-content: space-between; }
.bp-cab strong { color: var(--text); font-size: 15px; line-height: 1.25; }
.bp-cidade { color: var(--text); font-weight: 600; }
/* A cidade ao lado do nome da parada, no painel do roteiro. */
.stop-cidade { font-weight: 400; color: var(--text-soft); }
.bp-tempo { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; color: var(--text-soft); }
.bp-tags:empty { display: none; }
.bp-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.bp-tag { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600;
  padding: 2px 6px; border-radius: var(--r); color: var(--warn);
  background: color-mix(in srgb, var(--warn) 14%, transparent); }
.bp-tag.bp-evite { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); }
.bp-acoes { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s2); }
.bp-acoes .btn { text-decoration: none; }
/* "Ficaram de fora" no painel do roteiro (`o-que-ficou-de-fora.js`). */
.fdf { margin: var(--s3) 0; padding: var(--s3); border: 1px dashed var(--border-strong); border-radius: var(--r); }
.fdf-cab { display: grid; gap: 2px; }
.fdf-cab small { color: var(--text-soft); font-size: 12.5px; }
.fdf-lista { list-style: none; margin: var(--s2) 0 0; padding: 0; display: grid; gap: var(--s1); }
.fdf-item { display: flex; align-items: center; gap: var(--s2); padding: var(--s2) 0; border-top: 1px solid var(--border); }
.fdf-ico { color: var(--text-faint); flex: 0 0 auto; }
.fdf-txt { display: grid; flex: 1; min-width: 0; color: var(--text-soft); }
.fdf-txt b { color: var(--text); font-weight: 600; }
.fdf-txt small { font-size: 12px; }
.fdf-todas { margin-top: var(--s2); }
/* "Achei outra hospedagem", na noite do roteiro (`a-hospedagem-que-achei.js`). */
.hq { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s3); margin-top: var(--s2); font-size: 13px; }
.hq-caixa { flex-basis: 100%; display: grid; gap: var(--s1); }
.hq-busca { width: 100%; }
.hq-lista { display: grid; gap: 2px; }
.hq-op {
  display: flex; align-items: center; gap: var(--s2); text-align: left; width: 100%;
  padding: var(--s2); border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2); color: var(--text); font: inherit; cursor: pointer;
}
.hq-op:hover { border-color: var(--brand); }
@media (max-width: 420px) {
  .bp { grid-template-columns: 72px 1fr; }
  .bp-foto { width: 72px; height: 72px; }
}
.ar-ordem-caixa:empty { display: none; }
.ar-ordem-caixa {
  padding: var(--s3); border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2);
}
.ar-ordem-tit { margin: 0 0 var(--s2); font-size: 13px; }
.ar-ordem {
  list-style: none; margin: 0 0 var(--s2); padding: 0;
  display: flex; flex-direction: column; gap: var(--s2);
  max-height: 260px; overflow-y: auto;
}
.ar-ordem li { display: flex; gap: var(--s2); align-items: flex-start; font-size: 13px; }
.ar-ordem-n {
  flex: 0 0 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
  background: var(--ar-rota); color: var(--ar-num-texto); font-weight: 800; font-size: 11px;
}
.ar-ordem-principal .ar-ordem-n { background: var(--ar-principal); }
.ar-ordem-txt { display: flex; flex-direction: column; min-width: 0; }
.ar-ordem-txt b { overflow-wrap: anywhere; }
.ar-ordem-txt small { color: var(--text-soft); font-size: 11.5px; }

.md-grupos { display: flex; flex-direction: column; gap: var(--s3); }
.md-grupo { border: 1px solid var(--border); border-radius: var(--r); }
.md-grupo-cab {
  display: flex; align-items: baseline; gap: var(--s2); width: 100%;
  padding: var(--s3); border: 0; background: var(--surface-2);
  border-radius: var(--r) var(--r) 0 0; cursor: pointer;
  font: inherit; color: var(--text); text-align: left;
}
.md-grupo-cab strong { font-size: 14px; }
.md-grupo-cab small { color: var(--text-soft); font-size: 11.5px; margin-left: auto; }
.md-grupo-seta { color: var(--text-faint); }
.md-grupo-corpo { padding: var(--s3); }
/* "Fechar todos os grupos", acima do primeiro (`o-vale-conferir.js`). */
.md-grupos-ferr { display: flex; justify-content: flex-end; }
.md-grupos-todos { font-size: 13px; color: var(--text-soft); }
/* O último grupo do entorno: fora do que foi pedido, por isso o fundo de
   cabeçalho é o mesmo e só a dica diz o porquê. */
#ar-vale-conferir:not(:empty) { margin-top: var(--s3); }
.md-vale-dica { margin: 0; padding: var(--s2) var(--s3) 0; font-size: 12.5px; color: var(--text-soft); }

/* Gerar roteiro FIXO no pé da tela no passo do destino: a lista de grupos
   é longa, e o botão ficava a muitas rolagens de distância (16/10/2026). */
.wizard-step[data-step="3"]:has(#around-block:not(.hidden)) .wizard-actions {
  position: sticky; bottom: 0; z-index: 5;
  background: var(--surface);
  padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px));
}
.md-grupo-mais { padding: 0 var(--s3) var(--s3); }
.md-mais-bloco { width: 100%; }
.md-nivel {
  display: flex; align-items: baseline; gap: var(--s2);
  margin: var(--s4) 0 var(--s2);
}
.md-nivel small { color: var(--text-faint); font-size: 11px; }
.md-nivel-pais strong {
  font-size: 16px; letter-spacing: -.01em;
}
.md-nivel-pais { border-bottom: 1px solid var(--border-strong); padding-bottom: 4px; }
.md-nivel-uf strong { font-size: 13px; color: var(--text-soft); }
.md-nivel-uf { margin-left: var(--s3); }

.cs-fonte {
  display: block; font-weight: 400; font-size: 11px;
  color: var(--text-faint); text-transform: none; letter-spacing: 0;
}
.md-ou {
  margin: var(--s4) 0 var(--s3); font-size: 12px; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .06em;
}
.exp-sugestao {
  display: flex; gap: var(--s2); align-items: flex-start;
  padding: var(--s3); border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2); margin: var(--s3) 0;
}
.exp-sugestao small { display: block; color: var(--text-soft); font-size: 11.5px; }

/* ---- Referências turísticas ---- */
.rf-lista { display: flex; flex-direction: column; gap: var(--s3); }
.rf-item {
  padding: var(--s3); border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--r-sm); background: var(--surface);
}
.rf-item.rf-fila { border-left-color: var(--warn); }
.rf-item.rf-ok { border-left-color: var(--ok); }
.rf-item.rf-off { opacity: .6; }
.rf-topo { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.rf-escopo-selo {
  flex: none; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; padding: 2px 8px; border-radius: var(--r-pill);
  background: var(--brand-soft); color: var(--brand);
}
.rf-titulo-link { font-size: 14px; font-weight: 650; color: var(--text); }
.rf-titulo-link:hover { color: var(--brand); }
.rf-sit { margin-left: auto; font-size: 11px; color: var(--text-faint); }
.rf-onde, .rf-fonte { display: block; color: var(--text-soft); font-size: 11.5px; }
.rf-fonte { font-family: var(--mono); font-size: 10.5px; color: var(--text-faint); }
.rf-obs-txt { margin-top: 6px; font-size: 12.5px; color: var(--text); }
.rf-acoes {
  display: flex; gap: var(--s2); align-items: center;
  margin-top: var(--s2); flex-wrap: wrap;
}
.rf-acoes .dq-select { flex: 0 1 220px; }

/* Apêndice de referências dentro da ficha do destino */
.dq-refs {
  margin-top: var(--s3); padding: var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.dq-refs-topo { display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap; }
.dq-refs-topo .field-hint { margin: 0; }
.dq-refs-lista { display: flex; flex-direction: column; gap: 4px; margin-top: var(--s2); }
.dq-ref-item { display: flex; gap: var(--s2); align-items: baseline; flex-wrap: wrap; }
.dq-ref-link { font-size: 12.5px; color: var(--brand); text-decoration: underline; }
.dq-ref-item small { color: var(--text-faint); font-size: 11px; }

/* Campo derivado: parece dado, não formulário — não convida a digitar. */
.dq-field input.dq-travado {
  background: var(--surface-2); color: var(--text-soft);
  border-style: dashed; cursor: default;
}
.dq-field input.dq-travado::placeholder { font-style: italic; }
.dq-travado-nota { font-size: 10.5px; color: var(--text-faint); }
.dq-trilha-acoes { display: flex; gap: var(--s3); font-size: 10.5px; }
.dq-trilha-acoes a { color: var(--brand); text-decoration: underline; }
.linkish {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--brand); text-decoration: underline;
}
/* O Salvar acompanha a rolagem, em TODA tela que abre o cadastro.
   A ficha tem dezesseis campos, mais foto, referências, agrupador,
   restrições e o "como visitar": trocar só o bairro obrigava a rolar tudo
   até o fim para achar o botão — e rolar de volta.
   O fundo é opaco porque a barra passa por cima do que rola sob ela, e vem
   de uma variável porque cada tela tem um chão diferente: a bancada desenha
   sobre o fundo da página, a Oficina dentro de um cartão. */
.dq-form-actions {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  position: sticky; bottom: 0; z-index: 4;
  margin-top: var(--s3); padding: 10px 0;
  background: var(--fundo-da-barra, var(--bg));
  border-top: 1px solid var(--border);
}
.dq-rec-body { --fundo-da-barra: var(--surface-2); }
.dq-proc { margin-bottom: 10px; }
.dq-signals { margin-top: 8px; }

.dq-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.dq-table th { text-align: left; font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-faint); padding: 6px 8px;
  border-bottom: 1px solid var(--border); }
.dq-table td { padding: 7px 8px; border-bottom: 1px solid var(--border);
  vertical-align: top; }
.dq-col { display: block; color: var(--text-faint); font-size: 10.5px;
  font-family: var(--mono); }
.dq-pct { font-weight: 700; border-radius: var(--r-pill); padding: 1px 8px; }
.dq-ex { color: var(--text-faint); font-size: 11.5px; }
.dq-peso { font-weight: 700; font-size: 15px; color: var(--brand);
  font-variant-numeric: tabular-nums; }
.dq-cid { display: block; color: var(--text-faint); font-size: 11px; }

.dq-tiers { display: flex; gap: 8px; flex-wrap: wrap; }
.dq-tier { border: 1px solid var(--border); border-radius: var(--r-sm);
  padding: 8px 12px; background: var(--surface-2); min-width: 110px; }
.dq-tier b { display: block; font-size: 19px; color: var(--brand); }
.dq-tier span { font-size: 11px; color: var(--text-faint); }

/* --------------------------- Mapa de cidades visitadas ------ */
.vs-legend {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin: 10px 0 14px; font-size: 12px; color: var(--text-soft);
  align-items: center;
}
.vs-legend .vs-item { display: flex; align-items: center; gap: 6px; }
/* Os três números da legenda. Cor de TEXTO, não a cor da mancha do mapa:
   lá o tom é fundo de uma área grande, aqui é texto de 12px, e o mesmo
   hexadecimal reprovou nos dois temas. Regra direta no `b` porque a
   folha já tem cor para `b` — pintar só `.vs-legend` não chegaria nele. */
.vs-conta { font-weight: 700; }
.vs-sim { color: #0f6e52; }
.vs-nao { color: #3a4a63; }
.vs-nada { color: #5b6472; }
@media (prefers-color-scheme: dark) {
  /* Clareados para o fundo ardósia — a mesma razão pela qual `--danger`
     é clareada aqui: no escuro, cor de texto sobe de claridade. */
  .vs-sim { color: #58c39c; }
  .vs-nao { color: #a9b6cc; }
  .vs-nada { color: #97a2b4; }
}
.vs-swatch { width: 15px; height: 15px; border-radius: 4px; border: 1px solid rgba(0,0,0,.25); }

/* Status de download das fronteiras + aviso de cadastro sem contorno */

.vs-fix {
  margin: 0 0 14px; padding: 12px 14px; border-radius: 10px;
  background: rgba(212, 59, 59, .07);
  border: 1px solid rgba(212, 59, 59, .28);
}
.vs-fix-head { font-weight: 600; font-size: 13px; margin-bottom: 4px; color: var(--text); }
.vs-fix-item {
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline;
  padding: 7px 0; border-top: 1px solid rgba(212, 59, 59, .16); font-size: 13px;
}
.vs-fix-item strong { color: var(--text); }
.vs-fix-motivo { color: var(--text-soft); font-size: 12px; }
.vs-fix-dica { color: #b02a2a; font-size: 12px; font-weight: 500; }

/* Religar as visitas antigas ao catálogo. Vizinho do aviso de cima e
   deliberadamente MAIS QUIETO que ele: aquele diz que uma cidade está
   fora do mapa, este é manutenção que pode esperar. Por isso fundo de
   superfície e borda neutra, em vez do vermelho do defeito. */
.vd-religar {
  display: flex; flex-wrap: wrap; gap: var(--sp-2);
  align-items: center; justify-content: space-between;
  margin: 0 0 14px; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2);
}
.vd-religar-txt { display: flex; flex-direction: column; gap: 3px;
  font-size: 13px; min-width: 0; flex: 1 1 240px; }
.vd-religar-txt strong { color: var(--text); }
.vd-religar-txt span { color: var(--text-soft); font-size: 12.5px; }
#vd-religar-btn { flex: none; }

/* "Mesmo nome, outra cidade": a lista inteira, porque é ela a decisão.
   A linha toda é o alvo — o quadradinho sozinho tem 13px. */
.vd-conferir { align-items: stretch; }
.vd-pares { display: flex; flex-direction: column; gap: 1px; flex: 1 1 100%;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--border); overflow: hidden; }
.vd-par { display: flex; gap: var(--sp-2); align-items: flex-start;
  padding: 10px 12px; background: var(--surface); cursor: pointer; }
.vd-par input { flex: none; margin: 3px 0 0; accent-color: var(--brand); }
.vd-par-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0;
  font-size: 13px; }
.vd-par-txt strong { color: var(--text); overflow-wrap: anywhere; }
.vd-par-onde { color: var(--text-soft); display: inline-flex; flex-wrap: wrap;
  align-items: center; gap: 4px; }
.vd-par-onde .ico { width: 13px; height: 13px; }
.vd-par-txt small { color: var(--text-faint); font-size: 12px; }
#vd-conferir-btn { flex: none; margin-left: auto; }

/* "O banco está atrás do código", no Painel. Este é vermelho, ao
   contrário do religar: enquanto ele estiver na tela, alguma tela do app
   está devolvendo "sem rede" para quem usa. */
.bda-caixa {
  display: flex; flex-wrap: wrap; gap: var(--sp-2);
  align-items: center; justify-content: space-between;
  margin: 0 0 var(--sp-3); padding: 12px 14px;
  border: 1px solid var(--danger); border-radius: var(--r);
  background: var(--surface-2);
}
.bda-txt { display: flex; flex-direction: column; gap: 3px;
  font-size: 13px; min-width: 0; flex: 1 1 260px; }
.bda-txt strong { color: var(--text); }
.bda-txt span { color: var(--text-soft); font-size: 12.5px; }
.bda-lista {
  font-family: var(--mono); font-size: 12px; color: var(--danger);
  overflow-x: auto; white-space: nowrap; padding-top: 2px;
}
#bda-btn { flex: none; }
@media (prefers-color-scheme: dark) { .vs-fix-dica { color: #ff9b9b; } }

.vs-hit {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 6px 8px 6px 11px; border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2); color: var(--text);
  font: inherit; font-size: 13.5px; text-align: left;
}
.vs-hit .vs-ico { flex: none; }
.vs-hit .vs-nome { flex: 1 1 auto; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.vs-hit .vs-cid { font-size: 11px; color: var(--text-faint); flex: none; }
.vs-acoes { display: flex; align-items: center; gap: 6px; flex: none; }
.vs-btn {
  border: 1px solid var(--border); border-radius: var(--r);
  padding: 4px 12px; font: inherit; font-size: 12.5px; cursor: pointer;
  background: var(--surface); color: var(--text-soft);
}
.vs-btn:disabled { opacity: .5; cursor: default; }
.vs-fui { border-color: var(--border-strong); color: var(--text-soft); font-weight: 600;
  display: inline-flex; align-items: center; gap: 5px; }
.vs-fui .ico { width: 15px; height: 15px; }
/* Marcado: o mesmo botão, cheio — e tocar de novo desfaz. */
.vs-fui.feito { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
.vs-fui:not(.feito):hover:not(:disabled) { background: var(--brand-soft); }
.vs-grp-acoes { display: flex; align-items: center; gap: 12px; flex: none; }

.vs-pulados {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12px; color: var(--text-faint); margin: 6px 0 2px;
}
.vs-link {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--brand); font: inherit; font-size: 12px; text-decoration: underline;
}

/* Árvore região → cidade → lugares */
.vs-grp { border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2); margin-bottom: 5px; }
.vs-grp-head { display: flex; align-items: center; gap: 8px; padding: 8px 10px; }
.vs-grp-toggle {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px;
  background: none; border: 0; color: var(--text); font: inherit;
  font-size: 14px; font-weight: 600; cursor: pointer; text-align: left;
}
.vs-chevron { flex: none; color: var(--text-faint); font-size: 12px; width: 12px; }
.vs-grp-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vs-grp-uf { color: var(--text-faint); font-weight: 400; flex: none; }
.vs-grp-prog {
  flex: none; font-size: 11.5px; font-weight: 700; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-pill); padding: 1px 9px;
}
.vs-grp-body { padding: 4px 8px 8px; display: flex; flex-direction: column; gap: 4px; }
/* Cidade: recuada e mais leve que a região. */
.vs-grp-cid { border: 0; background: none; margin: 0; }
.vs-grp-cid > .vs-grp-head { padding: 5px 6px; }
.vs-grp-cid .vs-grp-toggle { font-size: 13px; font-weight: 550; }
.vs-grp-cid > .vs-grp-body { padding-left: 18px; }

/* Lista de registros, com remoção */
.vs-registros { display: flex; flex-direction: column; gap: 4px; }
.vs-reg {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2);
}
.vs-reg-ico { flex: none; }
.vs-reg-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.vs-reg-nome { font-size: 13.5px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.vs-reg-sub { font-size: 11px; color: var(--text-faint); }
.vs-reg-del { flex: none; padding: 4px 9px; font-size: 14px; line-height: 1; }
.vs-reg-del:hover:not(:disabled) { color: var(--danger, #e5484d); }

/* ===================== Expedições ===================== */
.exp-card {
  background: var(--surface, #fff); border: 1px solid var(--border, #e3e3e3);
  border-radius: 12px; padding: 14px 16px; margin-bottom: 12px;
}
.exp-head { display: flex; align-items: center; gap: 10px; }
.exp-ico { line-height: 1; color: var(--brand); }
.exp-ico .ico { width: 22px; height: 22px; }
.exp-titulo { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.exp-titulo strong { color: var(--text); }
.exp-titulo small { color: var(--text-soft); font-size: 12px; }
.exp-cor { width: 16px; height: 16px; border-radius: 50%; border: 1px solid rgba(0,0,0,.2); flex: 0 0 auto; }
.exp-desc { margin: 8px 0 0; font-size: 13px; color: var(--text-soft); }
.exp-acoes { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.exp-form-grid { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
.exp-form-grid label, .exp-form label {
  display: flex; flex-direction: column; gap: 4px; font-size: 12px;
  color: var(--text-soft); flex: 1 1 140px;
}
.exp-form label { flex-basis: 100%; }
.exp-form input, .exp-form textarea {
  padding: 8px 10px; border: 1px solid var(--border, #ccc); border-radius: 8px;
  font: inherit; background: var(--bg, #fff); color: var(--text);
}
.exp-form input[type="color"] { padding: 2px; height: 38px; min-width: 54px; }
.exp-locais { margin-top: 14px; border-top: 1px solid var(--border, #eee); padding-top: 12px; }
.exp-membros { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.exp-loc, .exp-hit {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--border, #e6e6e6); border-radius: 8px;
  background: var(--bg, #fafafa); width: 100%; text-align: left; font: inherit; color: var(--text);
}
.exp-loc small, .exp-hit small { display: block; color: var(--text-soft); font-size: 11px; }
.exp-hit { cursor: pointer; }
.exp-add { color: var(--ok); font-size: 12px; font-weight: 600; flex: 0 0 auto; }
.exp-buscar input {
  width: 100%; padding: 9px 11px; border: 1px solid var(--border, #ccc);
  border-radius: 8px; font: inherit; background: var(--bg, #fff); color: var(--text);
}
.exp-resultados { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
/* ===================== Regiões turísticas ===================== */
.reg-resumo { font-size: 13px; margin: 10px 0; color: var(--text); }
.reg-chg-lista { display: flex; flex-direction: column; gap: 4px; max-height: 260px; overflow-y: auto; }
.reg-chg {
  display: flex; flex-wrap: wrap; gap: 4px 10px; justify-content: space-between;
  padding: 6px 8px; border: 1px solid var(--border, #eee); border-radius: 7px; font-size: 12px;
}
.reg-chg small { color: var(--text-soft); }
.reg-arrow { color: var(--text-soft); }
.reg-arrow strong { color: var(--ok); }
.reg-unmatched { margin-top: 10px; font-size: 12px; }
.reg-unmatched summary { cursor: pointer; color: var(--text-soft); }
.reg-unmatched-lista { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.reg-tag {
  font-size: 11px; padding: 3px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 28%, transparent);
  color: var(--danger);
}

.reg-uf { margin-top: 16px; }
.reg-uf-head { font-weight: 700; color: var(--text); margin-bottom: 8px; }
.reg-uf-head small, .reg-grupo-nome small { color: var(--text-soft); font-weight: 400; font-size: 12px; }
.reg-grupo { margin: 10px 0 12px; }
.reg-grupo-nome { font-weight: 600; font-size: 13px; color: var(--text); margin-bottom: 6px; }
.reg-cidades { display: flex; flex-wrap: wrap; gap: 6px; }
.reg-cidade {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  padding: 4px 8px; border: 1px solid var(--border, #e3e3e3); border-radius: 999px;
  background: var(--bg, #fafafa); color: var(--text);
}

/* Hierarquia do cadastro de regiões: país → macrorregião → estado */
.reg-pais { margin-top: 18px; }
.reg-pais-head {
  font-weight: 700; font-size: 15px; color: var(--text);
  padding-bottom: 6px; border-bottom: 2px solid var(--border, #e3e3e3);
}
.reg-pais-head small, .reg-macro-head small { color: var(--text-soft); font-weight: 400; font-size: 12px; margin-left: 6px; }
.reg-macro { margin: 12px 0 12px 10px; padding-left: 12px; border-left: 3px solid rgba(13,122,112,.35); }
.reg-macro-head { font-weight: 700; font-size: 13px; color: #0d7a70; margin-bottom: 6px; }
@media (prefers-color-scheme: dark) { .reg-macro-head { color: #4fd1c5; } }
.reg-macro .reg-uf { margin-top: 10px; margin-left: 8px; }

/* Seletor de campo na exportação da aba Qualidade */
.dq-select {
  padding: 8px 10px; border: 1px solid var(--border, #ccc); border-radius: 8px;
  font: inherit; background: var(--bg, #fff); color: var(--text);
}

/* Painel de provedores de IA na aba Qualidade */
.dq-ia { display: flex; align-items: center; gap: 8px; padding: 5px 0; font-size: 12px; flex-wrap: wrap; }
.dq-ia code { font-size: 11px; color: var(--text-soft); }
.dq-ia small { color: var(--text-soft); }
.dq-ia-luz { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; background: #b9b9b9; }
.dq-ia-luz.ok { background: #1a8f6f; }
.dq-ia-luz.erro { background: #d43b3b; }
.dq-ia-luz.off { background: #b9b9b9; }

/* ===================== Chaves de IA (Perfil) ===================== */
.aik { border: 1px solid var(--border, #e3e3e3); border-radius: 10px; padding: 12px 14px; margin-bottom: 10px; }
.aik-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.aik-luz { width: 9px; height: 9px; border-radius: 50%; background: #b9b9b9; flex: 0 0 auto; }
.aik-luz.on { background: #1a8f6f; }
.aik-luz.erro { background: #d43b3b; }
.aik-tag { font-size: 11px; color: var(--text-soft); background: rgba(128,128,128,.12); padding: 2px 8px; border-radius: 999px; }
/* `--danger`, e não um hexadecimal escrito à mão: o token é CLAREADO no
   tema escuro justamente para servir de texto, e o #b02a2a fixo aqui
   dava 2,25 sobre o painel escuro — a etiqueta "não configurada"
   simplesmente não se lia. */
.aik-tag.off { color: var(--danger);
  /* 8%, e não 12%: o próprio véu clareia o fundo e derrubava a conta
     de 4,51 para 4,49 — a etiqueta reprovava por um centésimo. */
  background: color-mix(in srgb, var(--danger) 8%, transparent); }
.aik-link { font-size: 11px; margin-left: auto; color: #0d7a70; }
@media (prefers-color-scheme: dark) { .aik-link { color: #4fd1c5; } }
.aik-nota { font-size: 12px; color: var(--text-soft); margin: 4px 0 8px; }
.aik-form { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; align-items: center; }
.aik-input { flex: 1 1 220px; padding: 8px 10px; border: 1px solid var(--border, #ccc); border-radius: 8px; font: inherit; background: var(--bg, #fff); color: var(--text); }
.aik-saida { font-size: 12px; }
.aik-res { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 12px; }
.aik-res small { color: var(--text-soft); }

/* Auditoria de endereço na aba Qualidade */
.dq-end-barras { display: flex; flex-direction: column; gap: 4px; }
.dq-end-linha { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.dq-end-n {
  min-width: 44px; text-align: right; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.dq-end-n.bom { color: var(--ok); }
.dq-end-n.ruim { color: var(--danger); }

/* ============================================================
   REFINAMENTO DE INTERFACE
   Hierarquia de navegação, ritmo vertical e estados de foco.
   Vem depois de propósito: sobrepõe o que envelheceu sem
   reescrever o arquivo inteiro.
   ============================================================ */

:root {
  /* Escala de espaçamento: múltiplos de 4 evitam o "quase alinhado". */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px;
  --ring: 0 0 0 3px color-mix(in srgb, var(--brand) 35%, transparent);
}

/* A assinatura do Leaflet é desenho de terceiro dentro da NOSSA página.
   A caixa vem branca a 80% e o link vem `#0078A8`; sobre o mapa escuro a
   caixa compõe para cinza-claro e o azul cai para 3,20 — medido nas duas
   telas de mapa. Fundo opaco e os tokens da folha resolvem, e a assinatura
   continua dizendo o que precisa dizer. */
/* `.leaflet-container` no seletor porque a regra do fundo em `leaflet.css`
   é `.leaflet-container .leaflet-control-attribution` — dois níveis. Sem
   igualar, esta regra passaria em qualquer grep e perderia no navegador. */
.leaflet-container .leaflet-control-attribution {
  background: var(--surface);
  color: var(--text-soft);
}
.leaflet-container .leaflet-control-attribution a { color: var(--brand); }

/* ---------------------------------------------------- topo -- */
.topbar { padding-left: var(--s5); padding-right: var(--s5); gap: var(--s5); }
.brand .logo { font-size: 20px; }

.topnav {
  display: flex;
  align-items: center;
  gap: var(--s1);
  flex: 1 1 auto;
  justify-content: center;
  /* A barra antiga rolava na horizontal, e esse overflow recortava o menu
     suspenso — que é filho dela. Com os itens agrupados não há mais o que
     rolar, então o recorte só atrapalhava. */
  overflow: visible;
}

.nav-btn {
  padding: 8px 13px;
  border-radius: var(--r-sm);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.2;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-soft);
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.nav-btn:hover { background: var(--surface-2); color: var(--text); }
.nav-btn.active {
  background: var(--brand-soft);
  color: var(--brand);
  font-weight: 600;
}

/* "Base": curadoria do catálogo, fora do caminho de quem só quer viajar. */
.nav-group { position: relative; }
.nav-group.aberto .nav-more { background: var(--surface-2); color: var(--text); }

/* A tela atual dentro de uma gaveta fechada.
   Com `Planejar` e `Explorar` agrupando as telas de quem viaja, o
   `.nav-item.active` fica escondido enquanto o menu não abre — e a barra
   passa a não dizer em que tela a pessoa está. Quem carrega a marca é o
   rótulo do grupo, com a mesma pastilha do botão direto. */
.topnav .nav-group.tem-ativo > .nav-more {
  background: var(--brand-soft);
  color: var(--brand);
  font-weight: 600;
}

.nav-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 290px;
  padding: var(--s2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  display: none;
  z-index: 950;
}
.nav-group.aberto .nav-menu { display: block; }

.nav-item {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  width: 100%;
  padding: 10px var(--s3);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  text-align: left;
  cursor: pointer;
  color: var(--text);
  font: inherit;
}
.nav-item:hover { background: var(--surface-2); }
.nav-item.active { background: var(--brand-soft); }
.nav-item.active strong { color: var(--brand); }
.nav-ico { font-size: 17px; line-height: 1.35; flex: none; }
.nav-item strong { display: block; font-size: 13.5px; font-weight: 600; }
.nav-item small {
  display: block; color: var(--text-soft); font-size: 11.5px;
  margin-top: 1px; line-height: 1.35;
}
/* Na barra do desktop, `Meus Lugares` é só o nome: ícone e descrição são da
   gaveta do telefone (bloco "móvel", abaixo). */
.nav-meu-mapa .nav-ico, .nav-meu-mapa small { display: none; }
.nav-meu-mapa strong { font-weight: inherit; }

/* Perfil sai da fila: é conta, não navegação de conteúdo. */
.nav-avatar {
  flex: none;
  width: 36px; height: 36px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-soft);
  font-size: 15px;
  cursor: pointer;
  display: grid; place-items: center;
  transition: border-color .12s ease, color .12s ease;
}
.nav-avatar:hover { border-color: var(--border-strong); color: var(--text); }
.nav-avatar.active { border-color: var(--brand); color: var(--brand); }

.nav-toggle {
  display: none;
  width: 38px; height: 38px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  font-size: 16px;
  cursor: pointer;
}

/* --------------------------------------------- ritmo da página -- */
.container { max-width: 1060px; padding: var(--s6) var(--s5) var(--s7); }
.page-head { margin-bottom: var(--s5); max-width: 68ch; }
.page-head h2 {
  font-size: 25px; font-weight: 700; letter-spacing: -.02em;
  margin-bottom: var(--s1);
}
.page-head p { font-size: 14px; line-height: 1.55; }

.panel { padding: var(--s5); border-radius: var(--r-lg); }
.panel + .panel { margin-top: var(--s4); }
.panel h3 {
  font-size: 15px; font-weight: 650; letter-spacing: -.01em;
  margin-bottom: var(--s3);
}

/* ------------------------------------------------- controles -- */
.btn {
  min-height: 38px;
  padding: 9px 15px;
  border-radius: var(--r-sm);
  font-size: 13.5px;
  font-weight: 550;
  transition: background .12s ease, border-color .12s ease;
}
.btn.primary { font-weight: 600; }
/* Fantasma, mas ainda um botão.
   Sem preenchimento E sem contorno ele é só um texto — e no telefone não
   existe hover para revelar que ali havia um controle. São 95 deles no app
   ("Cancelar", "Fechar", "Descartar", "Devolver à circulação"), e foi
   exatamente isto que o usuário descreveu como "botões que ficam
   invisíveis". O contorno o devolve à condição de controle; ele continua
   abaixo do `.btn` porque não tem preenchimento. */
.btn.ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text-soft);
}
.btn.ghost:hover:not(:disabled) {
  border-color: var(--border-strong);
  color: var(--text);
}
/* Onde não há hover, o contorno tem de se sustentar sozinho. */
@media (hover: none) {
  .btn.ghost { border-color: var(--border-strong); color: var(--text); }
  /* Os três julgamentos de cada tipo de lugar, no primeiro passo: 34x34.
     É a PRIMEIRA tela de quem acaba de criar conta, e são trinta toques
     seguidos em alvos menores que o dedo. */
  .taste-opt { width: 44px; height: 44px; }
  /* A barra tem classe própria e por isso ficava de fora das regras de
     `.btn` do bloco do dedo: no telefone, `Meus Lugares` e `O que existe`
     mediam 41px numa gaveta onde os vizinhos com ícone medem 57. */
  .topnav .nav-btn { min-height: 44px; display: flex; align-items: center; }
}

input, select, textarea { border-radius: var(--r-sm); }
input:not([type="checkbox"]):not([type="radio"]), select { min-height: 38px; }

/* Foco visível só para teclado: mouse não ganha anel, teclado nunca fica sem. */
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--r-sm);
}

.chip { font-size: 13px; padding: 7px 13px; }

/* ------------------------------------------------------ móvel -- */
@media (max-width: 900px) {
  .topbar {
    padding-left: max(var(--s4), env(safe-area-inset-left));
    padding-right: max(var(--s4), env(safe-area-inset-right));
    gap: var(--s3);
  }
  .nav-toggle { display: grid; place-items: center; order: -1; }

  /* Gaveta: 11 destinos não cabem numa barra de telefone. */
  .topnav {
    position: fixed;
    /* Ancorada na barra REAL, com a sobra do entalhe incluída: presa só ao
       `--topbar-h` ela abria por baixo da barra e cobria os botões dela. */
    inset: calc(var(--topbar-h) + var(--safe-topo)) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: var(--s3);
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow);
    max-height: calc(100vh - var(--topbar-h) - var(--safe-topo));
    overflow-y: auto;
    display: none;
  }
  .topnav.aberto { display: flex; }
  /* Acima do véu, que fica em 900 junto com a barra do topo. */
  .topnav { z-index: 940; }
  .nav-btn {
    text-align: left; padding: 11px var(--s3); font-size: 14.5px;
    /* Na gaveta estes itens são IRMÃOS dos que têm ícone e descrição.
       Em `--text-soft` eles pareciam desligados ao lado deles — "Destinos",
       "Mapa" e "O que existe" liam como opções indisponíveis. */
    color: var(--text);
  }
  /* O item da tela atual era um bloco verde maciço de ponta a ponta: no
     desktop é uma pastilha discreta, mas com a largura toda ele vira a
     coisa mais forte da gaveta e afoga o resto do menu. Aqui ele se marca
     por uma barra na lateral e um fundo de leve. */
  /* `.topnav.aberto` no seletor não é enfeite: há uma redeclaração de
     `.nav-btn.active` mais abaixo, no bloco de refinamento da marca, e com
     a mesma especificidade ela venceria por vir depois. */
  .topnav.aberto .nav-btn.active {
    background: color-mix(in srgb, var(--brand) 14%, transparent);
    color: var(--brand);
    box-shadow: inset 3px 0 0 var(--brand);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
  }
  /* `.topnav` no seletor, de novo pelo mesmo motivo: o menu da CONTA é um
     `.nav-group` com um `.nav-menu` dentro, e mora fora da barra. Sem o
     prefixo, ele herdava o desenho da gaveta — `position: static` e
     `display: block` — e ficava permanentemente aberto dentro da barra do
     telefone, 280x362px, metade acima da borda de cima da tela. Medido no
     banco de prova a 375px. */
  .topnav .nav-group { position: static; }
  .topnav .nav-menu {
    position: static; display: block; min-width: 0;
    border: 0; box-shadow: none; padding: 0 0 0 var(--s3);
    background: transparent;
  }
  /* O rótulo do grupo vira TÍTULO DE SEÇÃO, e não some.
     Escondido, os cinco itens de "Jornadas" e "Acervo" viravam uma lista
     achatada sem dono: não dava para saber o que era jornada e o que era
     acervo — que é a pergunta que a gaveta existe para responder. */
  /* `.topnav` no seletor não é enfeite: o retrato da conta mora FORA da
     barra e também é `.nav-more` — sem o prefixo, `pointer-events: none`
     apagava o menu da conta no telefone inteiro. */
  .topnav .nav-more {
    display: block;
    /* Aqui é título de seção, e título não é alvo: sem desfazer os 44px do
       bloco do dedo, a gaveta ganharia três faixas vazias. */
    min-height: 0;
    pointer-events: none;         /* é rótulo aqui, não botão */
    margin: var(--s3) 0 2px;
    padding: 0 var(--s3);
    font-size: 11px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-faint);
  }
  .topnav .nav-more .nav-seta { display: none; }
  /* `Meus Lugares` fica fora de gaveta, mas na gaveta do telefone tem o
     desenho dos itens: ícone, nome e o que se acha lá. */
  .topnav .nav-meu-mapa {
    align-items: flex-start; gap: var(--s3);
    /* Recuo dobrado: os itens de cima ganham um `--s3` do `.nav-menu`, e
       sem ele o ícone saía da coluna dos outros. */
    margin-top: var(--s3); padding: 10px var(--s3) 10px calc(var(--s3) * 2);
  }
  .topnav .nav-meu-mapa .nav-ico { display: block; }
  .topnav .nav-meu-mapa strong { display: block; font-size: 13.5px; font-weight: 600; }
  .topnav .nav-meu-mapa small {
    display: block; color: var(--text-soft); font-size: 11.5px;
    font-weight: 400; margin-top: 1px; line-height: 1.35;
  }
  /* Aqui a gaveta está aberta e o item marcado aparece: o rótulo volta a
     ser só título de seção. Pintado, seriam duas marcas para uma tela. */
  .topnav .nav-group.tem-ativo > .nav-more {
    background: transparent;
    color: var(--text-faint);
    font-weight: 700;
  }
  .container { padding: var(--s5) var(--s4) var(--s7); }
  .page-head h2 { font-size: 21px; }
}

/* O véu atrás da gaveta.
   Sem ele, a gaveta terminava no meio da tela com o conteúdo aparecendo
   logo abaixo: lia como página quebrada, e não como menu aberto por cima.
   Ele também dá o alvo grande para fechar — tocar em qualquer lugar fora,
   que é o gesto que a pessoa já tem na mão. */
@media (max-width: 900px) {
  body:has(.topnav.aberto)::before {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .55);
    z-index: 900;
  }
}

/* ===================== Fotos dos destinos ===================== */
.ft-grade {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--s4);
}
.ft-card {
  display: flex; flex-direction: column; gap: var(--s2);
  padding: 0; border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); cursor: pointer; overflow: hidden;
  text-align: left; font: inherit; color: var(--text);
  transition: border-color .12s ease, transform .12s ease;
}
.ft-card:hover { border-color: var(--brand); transform: translateY(-2px); }
/* Caixa de proporção fixa: a foto se encaixa nela, nunca o contrário —
   esticar a imagem para caber deformava retrato e panorâmica. */
.ft-thumb {
  display: grid; place-items: center; aspect-ratio: 4 / 3; position: relative;
  background: var(--surface-2); overflow: hidden;
}
.ft-thumb img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: center;
}
/* "Foto inteira": mostra tudo, com faixa nas sobras. */
.ft-inteira .ft-thumb img,
.ft-inteira .ft-item img { object-fit: contain; background: var(--surface-2); }
.ft-vazio { color: var(--text-faint); font-size: 12px; }
.ft-legenda { padding: 0 var(--s3) var(--s3); }
.ft-legenda strong { display: block; font-size: 13px; line-height: 1.3; }
.ft-legenda small { color: var(--text-soft); font-size: 11.5px; }

/* Modal de fotos de um destino */
.ft-modal {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0,0,0,.6); display: grid; place-items: center;
  padding: var(--s4);
}
.ft-modal-caixa {
  width: min(920px, 100%); max-height: 88vh; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow);
}
.ft-modal-topo {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); padding: var(--s4) var(--s5);
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.ft-modal-corpo { padding: var(--s5); }
.ft-secao + .ft-secao { margin-top: var(--s5); padding-top: var(--s5); border-top: 1px solid var(--border); }
.ft-secao h4 { font-size: 14px; font-weight: 650; margin-bottom: var(--s2); }
.ft-lista {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--s3); margin-top: var(--s3);
}
.ft-item {
  margin: 0; border: 1px solid var(--border); border-radius: var(--r-sm);
  overflow: hidden; background: var(--surface-2);
}
.ft-item.capa { border-color: var(--brand); }
.ft-item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.ft-item figcaption { padding: var(--s2); display: flex; flex-direction: column; gap: 5px; }
.ft-item small { color: var(--text-soft); font-size: 11px; line-height: 1.35; }
.ft-tag {
  align-self: flex-start; font-size: 10px; font-weight: 700;
  padding: 2px 7px; border-radius: var(--r-pill);
  background: var(--brand-soft); color: var(--brand);
}
.ft-acoes { display: flex; gap: var(--s1); flex-wrap: wrap; }

/* Fotos dentro do cadastro do destino */
.dq-fotos {
  margin-top: var(--s4); padding: var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.dq-fotos-topo {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
}
.dq-fotos-tira {
  display: flex; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s2);
}
.dq-foto {
  margin: 0; width: 116px; border: 1px solid var(--border);
  border-radius: var(--r-sm); overflow: hidden; background: var(--surface);
}
.dq-foto.capa { border-color: var(--brand); }
.dq-foto img {
  display: block; width: 100%; aspect-ratio: 4 / 3;
  object-fit: cover; object-position: center;
}
.dq-foto figcaption {
  font-size: 10px; font-weight: 700; text-align: center;
  padding: 2px; color: var(--brand); text-transform: uppercase;
}
.ft-acoes .btn { min-height: 28px; padding: 4px 9px; font-size: 11.5px; }

/* ===================== Validação dos cadastros ===================== */
.vl-topo {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s3);
}
.vl-cartao {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--s3) var(--s4);
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2);
}
.vl-n { font-size: 22px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.vl-n.vl-ok { color: var(--ok); }
.vl-n.vl-susp { color: var(--warn); }
.vl-n.vl-erro { color: var(--danger); }
.vl-rot { font-size: 12px; color: var(--text-soft); line-height: 1.35; }
.vl-rot small { display: block; font-size: 11px; color: var(--text-faint); }

.vl-fila { display: flex; flex-direction: column; gap: var(--s2); }
.vl-item {
  padding: var(--s3); border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface);
}
.vl-linha { display: flex; align-items: flex-start; gap: var(--s3); }
.vl-acoes { flex: none; display: flex; gap: var(--s2); flex-wrap: wrap; }
.vl-corpo { margin-top: var(--s3); border-top: 1px solid var(--border); padding-top: var(--s3); }
.vl-item.vl-feito { opacity: .72; background: var(--surface-2); }
.vl-sel.vl-assinado { background: rgba(30,140,90,.14); color: var(--ok); }
@media (max-width: 620px) {
  .vl-linha { flex-wrap: wrap; }
  .vl-acoes { width: 100%; }
  .vl-acoes .btn { flex: 1 1 auto; }
}
.vl-sel {
  flex: none; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; padding: 3px 8px; border-radius: var(--r-pill);
}
.vl-sel.vl-erro { background: rgba(212,59,59,.12); color: var(--danger); }
.vl-sel.vl-suspeito { background: rgba(192,125,16,.14); color: var(--warn); }
.vl-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.vl-txt strong { font-size: 13.5px; }
.vl-txt small { color: var(--text-soft); font-size: 11.5px; }
.vl-achado {
  font-style: normal; font-size: 12px; color: var(--text);
  background: var(--surface-2); border-left: 2px solid var(--border-strong);
  padding: 5px 9px; border-radius: 0 var(--r-sm) var(--r-sm) 0; margin-top: 3px;
}
.vl-ok-btn { flex: none; }

/* Colar link de foto no painel do destino */
.ft-url { display: flex; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s2); }
.ft-url input { flex: 1 1 180px; }

/* Fila de enriquecimento: um destino de cada vez, sem sair da tela. */
.ft-fila-painel {
  border: 1px solid var(--brand); border-radius: var(--r);
  background: var(--surface-2); margin-bottom: var(--s4); overflow: hidden;
}
.ft-fila-topo {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  padding: var(--s3) var(--s4); background: var(--brand-soft);
  border-bottom: 1px solid var(--border);
}
.ft-fila-topo strong { font-size: 15px; }
.ft-fila-conta { margin-left: auto; font-size: 13px; color: var(--text-soft); }
.ft-fila-corpo { padding: var(--s4); }
.ft-fila-alvo {
  display: flex; gap: var(--s4); align-items: flex-start; flex-wrap: wrap;
}
.ft-fila-info { flex: 1 1 260px; display: flex; flex-direction: column; gap: 6px; }
.ft-fila-info h4 { margin: 0; font-size: 18px; }
.ft-fila-info > small { color: var(--text-soft); font-size: 12.5px; }
.ft-fila-buscar { text-decoration: none; }
.ft-fila-buscas { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-self: flex-start; }
.ft-fila-atual { width: 150px; margin: 0; }
.ft-fila-atual img {
  width: 100%; height: 100px; object-fit: cover;
  border-radius: var(--r-sm); border: 1px solid var(--border);
}
.ft-fila-atual figcaption {
  font-size: 11px; color: var(--text-faint); margin-top: 4px; text-align: center;
}
.ft-fila-cola {
  display: flex; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s4);
}
.ft-fila-cola input { flex: 1 1 260px; }
/* Foto sem link e o destino sem atrativo, longe do "Salvar e próximo":
   excluir não tem volta, e não pode estar onde o dedo vai por hábito. */
.ft-fila-acoes {
  display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; margin-top: var(--s3);
}
.ft-fila-enviar { cursor: pointer; }
.ft-fila-acoes .btn.danger { margin-left: auto; }
.ft-fila-previa:not(:empty) { margin-top: var(--s3); }
.ft-fila-previa img {
  max-height: 220px; max-width: 100%; border-radius: var(--r-sm);
  border: 1px solid var(--border);
}
.ft-fila-saida:not(:empty) { margin-top: var(--s2); font-size: 12px; }
.ft-fila-fim { text-align: center; padding: var(--s5) var(--s3); }

/* Flag de validação dentro do cadastro */
.dq-val {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3);
  padding: var(--s3); margin-bottom: var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.dq-val-flag { display: flex; align-items: center; gap: var(--s2); cursor: pointer; }
.dq-val-flag input { width: 18px; height: 18px; accent-color: var(--brand); }
.dq-val-flag strong { display: block; font-size: 13px; }
.dq-val-quem { display: block; color: var(--text-soft); font-size: 11.5px; }
.dq-val-ia { display: flex; flex-direction: column; gap: 3px; flex: 1 1 220px; }
.dq-val-selo {
  align-self: flex-start; font-size: 11px; font-weight: 650;
  padding: 3px 9px; border-radius: var(--r-pill);
  background: rgba(128,128,128,.14); color: var(--text-soft);
}
.dq-val-erro .dq-val-selo { background: rgba(212,59,59,.13); color: var(--danger); }
.dq-val-suspeito .dq-val-selo { background: rgba(192,125,16,.15); color: var(--warn); }
.dq-val-ok .dq-val-selo { background: rgba(23,134,74,.13); color: var(--ok); }
.dq-val-ia small { color: var(--text-soft); font-size: 11.5px; line-height: 1.4; }
.dq-val-msg { font-size: 11.5px; }

/* Selos na linha da lista */
.dq-selo-val, .dq-selo-ia {
  display: inline-block; font-size: 10.5px; font-weight: 700;
  padding: 1px 7px; border-radius: var(--r-pill); margin-left: 4px;
}
.dq-selo-val { background: rgba(23,134,74,.14); color: var(--ok); }
.dq-selo-erro { background: rgba(212,59,59,.13); color: var(--danger); }
.dq-selo-suspeito { background: rgba(192,125,16,.15); color: var(--warn); }

/* Quem ficou de fora da busca de destinos, e o conserto de cada motivo. */
.md-ocultos {
  margin: var(--s3) 0; padding: var(--s3);
  border: 1px dashed var(--border-strong); border-radius: var(--r-sm);
  background: var(--surface-2); color: var(--text-soft);
  font-size: 12.5px; line-height: 1.7;
}
.md-ocultos b { color: var(--text); }
.md-link {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--brand); font-size: inherit; font-weight: 600;
  text-decoration: underline;
}

/* ==========================================================================
   CAMADA DESBRAVIA
   Reveste os componentes existentes sem mexer no layout que já funciona.

   A divisão de papéis entre as duas cores é o coração disto e não é
   estética: VERDE MUSGO estrutura (barra, item ativo, o que organiza),
   TERRACOTA age (só o que a pessoa aperta). Numa tela em que tudo é
   terracota, nada é ação — e o brandbook chama a terracota de "Ação".

   Títulos em 800: o peso é o que faz hierarquia quando não há serifa.
   ========================================================================== */

h1, h2, h3, h4, h5 {
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.15;
}
h1 { font-size: clamp(26px, 3.6vw, 36px); font-weight: 900; }
h2 { font-size: clamp(21px, 2.6vw, 26px); }

/* Respiro amplo isola a fotografia da natureza — é o que o brandbook
   pede e o que impede a tela de virar planilha. */
.panel { padding: 26px; border-radius: var(--r-lg); }
.panel + .panel { margin-top: 18px; }

/* --------------------------------------------------- barra fixa -- */
.topbar { border-bottom: 1px solid var(--border); }
.nav-btn { border-radius: var(--r); letter-spacing: .01em; }
.nav-btn.active { background: var(--brand); color: var(--brand-text); }

/* ------------------------------------------------------- botões -- */
/* Terracota sobre Branco Gelo, canto de 4px: a regra literal do
   brandbook para CTA. Sem halo, sem elevação — equipamento não brilha. */
.btn { border-radius: var(--r); font-weight: 600; letter-spacing: .01em; }
/* Link com cara de botão não leva o sublinhado do navegador: "Chegar"
   (um `<a>`) saía sublinhado ao lado de "Cheguei" (um `<button>`), o mesmo
   par com dois desenhos — medido no Simulador do iOS em 01/10/2026. */
a.btn { text-decoration: none; }
.btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #f9f9f9;
}
.btn.primary:hover:not(:disabled) {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}
/* A ação secundária fica na cor da estrutura, para não disputar com o
   gesto principal. */
.btn.secondary {
  background: var(--brand); border-color: var(--brand); color: var(--brand-text);
}
.btn:focus-visible, .chip:focus-visible, .nav-btn:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ------------------------------------------------------- campos -- */
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="date"], input[type="time"],
input[type="search"], select, textarea { border-radius: var(--r); }
input:focus, select:focus, textarea:focus { border-color: var(--brand); }

/* -------------------------------------------------------- chips -- */
/* Filtro é etiqueta, não botão: continua arredondado de propósito, para
   a mão saber que ali não é a ação principal. */
.chip { border-radius: var(--r-pill); }
.chip.active,
.chip[aria-pressed="true"] {
  background: var(--brand); border-color: var(--brand); color: var(--brand-text);
}
/* Regra DIRETA no filho, e não herança. A folha tem cor própria para
   `small`, `b` e `strong`; pintar só o chip deixava o `small` com
   `--text-soft` sobre o verde cheio — 1,31 medido no primeiro passo do
   montador, em "Equilibrado · cerca de 6h por dia". É a mesma armadilha
   do azulejo de DESTINOS, com outro componente. */
.chip.active small, .chip[aria-pressed="true"] small,
.chip.active b, .chip[aria-pressed="true"] b,
.chip.active strong, .chip[aria-pressed="true"] strong {
  color: var(--brand-text);
}

/* ---------------------------------------------- cartão de destino -- */
.md-card { border-radius: var(--r-lg); overflow: hidden; transition: box-shadow .2s ease; }
.md-card:hover { box-shadow: var(--shadow); }

/* A legenda fica SEMPRE visível: em telefone não existe hover, e ninguém
   escolhe um destino cujo nome só aparece se passar o dedo por cima. */

/* ---------------------------------------------------- passo a passo -- */
.step-dot { text-transform: uppercase; letter-spacing: .06em; font-size: 11px; font-weight: 600; }
.step-dot::before { height: 3px; border-radius: 0; }
.step-dot.current { color: var(--accent-txt); }
.step-dot.current::before { background: var(--accent); }

/* ------------------------------------------------- estado vazio -- */
.empty-state { border-radius: var(--r-lg); border: 1px dashed var(--border-strong); padding: 40px 20px; }
.empty-state h4 { font-weight: 800; font-size: 19px; }

/* --------------------------------------------------------- marca -- */
.marca-logo { width: 30px; height: 30px; display: block; flex: none; }
#auth-title { font-size: clamp(24px, 3vw, 32px); font-weight: 900; }
.marca-lema {
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-faint); font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* A marca era um emoji; agora é o mosquetão. As duas regras antigas
   dimensionavam glifo de texto, o que deixaria o SVG sem tamanho. */
.logo, .auth-logo {
  width: 34px; height: 34px; display: block; flex: none;
  font-size: 0; background: none;
}
.auth-logo { width: 44px; height: 44px; }

/* O lema tem três palavras longas e o cabeçalho da marca é estreito: sem
   isto ele quebra em três linhas e empurra o mosquetão para o canto. */
.auth-brand { align-items: center; }
.auth-brand-txt .marca-lema {
  display: block; letter-spacing: .1em; font-size: 10px; line-height: 1.5;
  max-width: 26ch;
}

/* O brandbook manda Branco Gelo sobre Terracota no botão. Medi: dá
   3,63:1, abaixo dos 4,5:1 que a WCAG exige para texto de tamanho
   normal — o rótulo fica difícil de ler no sol, que é justamente onde
   este app é usado. Mantive a terracota como identidade em tudo que é
   cor (etiqueta, foco, destaque) e escureci só o PREENCHIMENTO do
   botão para #a95733: mesma matiz, 4,87:1.
   Se preferir a fidelidade absoluta ao hex, é trocar aqui — mas fica
   registrado que a conta não fecha. */
.btn.primary { background: #a95733; border-color: #a95733; }
.btn.primary:hover:not(:disabled) { background: #8f4726; border-color: #8f4726; }

/* A saída escrita no campo (`a-saida-e-o-alcance.js`): lê como escolha
   feita, não como texto a meio de digitar. */
#origin-search.tem-saida { font-weight: 600; border-color: var(--brand); }

/* A troca de marca por tema saiu daqui, e a razão vale o registro: a marca
   é um EMBLEMA — gelo sobre verde, com o fundo dentro do próprio desenho.
   Repintar as mesmas formas em verde escuro para "servir o fundo claro"
   produzia um borrão escuro de 28px na barra, que também é escura. Um
   emblema serve os dois fundos, e um arquivo só não tem como divergir. */

/* ==========================================================================
   VITRINE — o fundo fotográfico de "Criar roteiro"
   A regra que manda aqui: a foto fica ATRÁS de um véu pesado e o painel
   continua opaco. Fundo bonito que atrapalha ler o campo de data é fundo
   ruim, e esta tela é onde a pessoa digita data, hora e coordenada.
   ========================================================================== */
#view-new { position: relative; }
#view-new > .container { position: relative; z-index: 1; }

/* A vitrine — a foto do acervo como fundo da tela de montar — saiu.
   Ver o comentário no `index.html`: o preço dela era um degradê atrás de
   cada título e um `text-shadow` de 12px, que na tela viram uma mancha
   desfocada em volta das letras. A tela em que se digita pede calma. */

/* ---------------------------------------------------------- ícones -- */
/* Herdam a cor de onde estão: musgo na estrutura, terracota na ação.
   Um arquivo, dois papéis, zero duplicação. */
.ico {
  width: 1.15em; height: 1.15em;
  vertical-align: -.2em;
  flex: none;
  color: inherit;
}
.nav-ico .ico { width: 20px; height: 20px; color: var(--brand); }
.nav-avatar .ico { width: 20px; height: 20px; }
.btn .ico { width: 17px; height: 17px; margin-right: 2px; }

.chip .ico { width: 16px; height: 16px; }
/* Seta de abrir/fechar: um desenho só, girado. Trocar o caractere de
   baixo pelo da direita fazia o bloco pular a cada clique — os dois
   glifos têm largura diferente. */
.vs-chevron .ico, .md-grupo-seta .ico, .nav-seta .ico {
  width: 15px; height: 15px;
  transition: transform .16s ease;
}
.nav-seta { display: inline-flex; margin-left: 4px; }
.vs-chevron.fechado .ico, .md-grupo-seta.fechado .ico { transform: rotate(-90deg); }
.nav-more[aria-expanded="true"] .nav-seta .ico { transform: rotate(180deg); }
.ico.fechado-cima { transform: rotate(180deg); }
.taste-label .ico { width: 18px; height: 18px; color: var(--brand); }

/* Abre e fecha o quadro de tipos. Não é botão de caixa: é a continuação da
   frase que resume o que está marcado, logo acima dele. */
#interest-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 8px; text-decoration: none;
}
#interest-toggle:hover { text-decoration: underline; }
#interest-toggle .ico { width: 16px; height: 16px; }
.empty-state .ico { width: 40px; height: 40px; }

 .wx-box .ico, .travel .ico { width: 15px; height: 15px; }
/* No cartão de destino o ícone é sinal secundário: não pode competir
   com a foto nem com o nome. */
.md-card .ico { opacity: .7; }

/* ==================== o cabeçalho de Jornadas ======================== */
/* O campo do código morava numa faixa entre a viagem de agora e a lista —
   um formulário atravessado no caminho de quem só veio ver as próprias
   viagens. Entrar com código acontece UMA vez por viagem, e por convite.
   Virou um botão do cabeçalho que abre o campo ali mesmo. */
.jor-cabeca {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
}
.jor-cabeca-txt { min-width: 0; }
.jor-acoes { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--sp-1) var(--sp-3); flex: none; }
.jor-codigo { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.jor-codigo .ico { width: 16px; height: 16px; }
.entrar-codigo-box { margin-bottom: var(--sp-4); }

/* ============================ a viagem de agora, no alto de Jornadas = */
/* Ela vem antes da lista porque é a única que tem hora marcada. O bloco
   inteiro some quando não há viagem de agora — estado vazio acima de uma
   lista que já mostra o que existe é ruído, e não informação. */
.jornada-agora {
  display: grid;
  /* A foto ocupa uma coluna de largura FIXA e o texto toma o resto. Sem
     a foto, a primeira coluna não existe e o bloco fica como era. */
  grid-template-columns: auto 1fr;
  margin-bottom: var(--sp-4);
  /* Musgo é a cor da ESTRUTURA, e este bloco é estrutura: ele diz onde
     você está no tempo. O terracota fica só no botão, que é o gesto. */
  border: 1px solid var(--brand);
  border-left: 4px solid var(--brand);
  border-radius: var(--r-lg);
  background: var(--surface);
  /* O `overflow` é o que faz a foto respeitar a quina do bloco. */
  overflow: hidden;
}
/* A FOTO É UMA FAIXA, E O TEXTO MORA FORA DELA.
   Esta folha não admite véu nem degradê atrás de texto de leitura: quando
   um título precisa de sombra para se ler sobre uma imagem, a imagem está
   no lugar errado. Aqui ela argumenta ao lado, com quina, e nenhuma
   palavra passa por cima dela. */
.jag-capa { width: 232px; align-self: stretch; background: var(--surface-2); }
.jag-capa img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
.jag-corpo {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--sp-2);
  padding: var(--sp-4);
  min-width: 0;
}
.jag-selo {
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--brand);
}
.jag-titulo { font-size: 18px; line-height: 1.25; }
/* "Faltam 3 dias" é o que a pessoa abre o app para ver na semana da
   viagem, e estava escrito como duas datas — uma conta para o leitor
   fazer. Peso de número, não de rótulo. */
.jag-conta {
  margin: 0;
  font-size: 27px; font-weight: 800; letter-spacing: -.02em;
  line-height: 1.05; color: var(--text);
}
.jag-quando { color: var(--text-faint); font-variant-numeric: tabular-nums; }
.jag-medidas, .jcard-numeros {
  display: flex; flex-wrap: wrap; gap: 6px;
  list-style: none; margin: 0; padding: 0;
}
.jag-medidas li, .jcard-medida {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--border-strong); border-radius: var(--r-pill);
  font-size: 12.5px; color: var(--text-soft);
  background: var(--surface-2);
}
.jag-medidas b, .jcard-medida b {
  color: var(--text); font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.jag-medidas .ico, .jcard-medida .ico {
  width: 15px; height: 15px; color: var(--brand);
}
/* A pílula da previsão. Quando a chance de chuva passa de 60% ela troca
   de tom: é a única das medidas que muda o que a pessoa põe na mala, e
   `--warn` é o token de "olhe para isto" — não `--danger`, que é erro. */
.jag-molhado { border-color: var(--warn); }
.jag-molhado .ico { color: var(--warn); }
.jag-ir { margin-top: var(--sp-1); }
@media (max-width: 700px) {
  /* No telefone a faixa vai para CIMA e vira o topo do cartão: uma
     coluna de 232px ao lado de um texto deixaria os dois estreitos. */
  .jornada-agora { grid-template-columns: 1fr; }
  .jag-capa { width: auto; aspect-ratio: 4 / 3; }
}
/* Sem viagem de agora o bloco continua existindo — é a única porta para o
   painel da estrada —, mas perde o peso: nada de borda de marca nem de
   terracota para o que é só um caminho. */
.jag-vazia {
  display: flex;
  flex-direction: row; align-items: center; flex-wrap: wrap;
  gap: var(--sp-2);
  border-color: var(--border); border-left-color: var(--border);
  padding: var(--sp-3);
  background: var(--surface-2);
}
.jag-vazia .jag-ir { margin-top: 0; }

/* ==================== o cartão de uma jornada ======================== */
/* `657 km · R$ 1672` era uma frase: dois números de naturezas diferentes
   separados por um ponto, no peso do resto do texto. Viraram medidas com
   ícone, e a terceira é a que faltava — quantos LUGARES. "657 km" não diz
   se a viagem é longa ou cheia; "10 paradas" ao lado diz. */
/* Sem `overflow: hidden` no cartão: ele cortava o menu das reticências,
   que abre para baixo e passa da borda — medido no Simulador do iOS em
   01/10/2026, só a linha de cima do menu aparecia. Quem respeita a quina
   agora é a capa, recortando a si mesma. */
.jcard { display: flex; flex-direction: column; padding: 0; }
.jcard-capa {
  aspect-ratio: 4 / 3; background: var(--surface-2);
  overflow: hidden; border-radius: calc(var(--r) - 1px) calc(var(--r) - 1px) 0 0;
}
.jcard-capa img {
  display: block; width: 100%; height: 100%; object-fit: cover;
}
.jcard-corpo {
  display: flex; flex-direction: column; gap: 7px;
  padding: 14px;
}
.jcard-cabeca {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px;
}
.jcard-titulo { margin: 0; font-size: 15px; line-height: 1.3; min-width: 0; }
.jcard-quando {
  color: var(--text-faint); font-variant-numeric: tabular-nums;
  font-size: 12.5px;
}
/* O selo do estado, com um tom por estado. Cor SEMÂNTICA, e não a da
   marca: "cancelada" em musgo diria que está tudo bem. */
.jcard-estado {
  flex: none;
  font-size: 10px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--r-pill);
  border: 1px solid currentColor;
}
.est-planejando, .est-rascunho { color: var(--text-soft); }
.est-confirmada { color: var(--brand); }
.est-andando { color: var(--accent-txt); }
.est-concluida { color: var(--ok); }
.est-cancelada { color: var(--danger); }
.est-neutro { color: var(--text-faint); }
.jcard-acoes {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin-top: 3px;
}
.jcard-acoes .btn { font-size: 12.5px; padding: 6px 10px; }
/* O cartão inteiro é alvo de toque, e por isso ele não pode ganhar o
   fundo de marca quando está escolhido: o `--brand-soft` atrás das
   etiquetas em `--surface-2` deixava as duas superfícies iguais. A marca
   do escolhido é a borda. */
.jcard.active { background: var(--surface); }
.jcard.active { border-color: var(--brand); box-shadow: inset 3px 0 0 var(--brand); }

/* ============================ concluir a viagem ===================== */
.conc-card { max-width: 560px; }
.conc-topo {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: var(--sp-4) var(--sp-4) 0;
}
.conc-fecha {
  background: none; border: 0; color: var(--text-soft);
  cursor: pointer; padding: 6px; line-height: 0; border-radius: var(--r);
}
.conc-fecha:hover { color: var(--text); background: var(--surface-2); }
.conc-corpo { display: flex; flex-direction: column; gap: var(--sp-3); }
.conc-explica { color: var(--text-soft); margin: 0; }
/* A lista é de conferência, não de leitura: o alvo é a linha inteira, e a
   caixa de marcar vai antes do nome porque é ela que se aperta. */
.conc-lista { list-style: none; margin: 0; padding: 0; }
.conc-item + .conc-item { border-top: 1px solid var(--border); }
.conc-item label {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: 10px 2px; cursor: pointer; min-height: 44px;
}
.conc-item span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.conc-item small { color: var(--text-faint); }
/* A caixa de marcar vem com a cor do SISTEMA por padrão — azul, no Mac —,
   e são nove delas lado a lado nesta tela. `accent-color` é como o resto do
   app já pinta as suas (ver `.dq-val-flag`). */
.conc-item input {
  margin-top: 3px; flex: 0 0 auto;
  width: 18px; height: 18px; accent-color: var(--brand); cursor: pointer;
}
.conc-ja { display: flex; align-items: center; gap: 6px; }
.conc-pe { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* ============================ o recado de quem usa ================== */
.rc-card { max-width: 560px; }
.rc-topo {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: var(--sp-4) var(--sp-4) 0;
}
.rc-fecha {
  background: none; border: 0; color: var(--text-soft);
  cursor: pointer; padding: 6px; line-height: 0; border-radius: var(--r);
}
.rc-fecha:hover { color: var(--text); background: var(--surface-2); }
.rc-corpo { display: flex; flex-direction: column; gap: var(--sp-3); }
.rc-pe { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* ============================ o link público do roteiro ============= */
/* A caixa nasceu sem uma linha de CSS: título colado na quina, o "×" um
   botão cinza do sistema de 31x22 embaixo do título, "Copiar" caindo para
   baixo do endereço (banco de prova, 375px, 01/10/2026). Mesmo molde das
   duas caixas de cima. */
.pub-card { max-width: 560px; }
.pub-topo {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: var(--sp-4) var(--sp-4) 0;
}
.pub-fecha {
  background: none; border: 0; color: var(--text-soft);
  cursor: pointer; padding: 6px; line-height: 0; border-radius: var(--r);
}
.pub-fecha:hover { color: var(--text); background: var(--surface-2); }
.pub-corpo {
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding-bottom: var(--sp-4);
}
.pub-corpo .field { margin: 0; }
.pub-explica { color: var(--text-soft); margin: 0; }
.pub-link { display: flex; gap: var(--sp-2); }
.pub-link input { flex: 1; min-width: 0; }
.pub-atalhos { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pub-fora {
  padding: var(--sp-3); font-size: 13.5px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2);
}
.pub-fora strong { color: var(--text); }
.pub-fora ul { margin: 6px 0 8px; padding-left: 18px; color: var(--text-soft); }
.pub-fora small { display: block; color: var(--text-soft); font-size: 12px; }
.pub-acoes { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); }
.pub-aviso { color: var(--text-soft); font-size: 12px; }

/* A caixa de entrada, no Painel. Lista de leitura: linhas separadas por
   fio, sem cartão em cada uma — são itens de uma mesma fila, e borda em
   volta de cada um separa o que se lê em conjunto. */
.rc-pendentes {
  margin-left: var(--sp-2);
  font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase;
  padding: 2px 8px; border-radius: var(--r-pill);
  background: var(--brand-soft); color: var(--brand);
}
.rc-lista { list-style: none; margin: 0; padding: 0; }
.rc-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  padding: var(--sp-3) 0;
}
.rc-item + .rc-item { border-top: 1px solid var(--border); }
/* Lido não some: continua na caixa, mais quieto. Sumir com o que foi lido
   é como se perde a segunda leitura, que costuma ser a que entende. */
.rc-lido { opacity: .62; }
.rc-cabeca { display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap; }
.rc-cabeca small { color: var(--text-faint); font-variant-numeric: tabular-nums; }
.rc-tipo {
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-soft);
}
.rc-texto { margin: 0; white-space: pre-wrap; }
.rc-marca { display: flex; align-items: center; gap: 5px; color: var(--text-faint); }

/* ============================ cidades conferidas =================== */
/* Uma grade, e não uma linha: com `.row` os três campos empilhavam em
   largura cheia, porque a folha dá `width: 100%` a todo `input`. A cidade
   e a data cabem lado a lado no monitor; no telefone a grade colapsa
   sozinha em uma coluna, sem media query. */
.cc-form {
  display: grid; gap: var(--sp-2);
  grid-template-columns: minmax(200px, 1fr) minmax(150px, 190px);
  align-items: center;
}
.cc-form #cc-nota { grid-column: 1 / -1; }
.cc-form #cc-marcar { grid-column: 1 / -1; justify-self: start; }
@media (max-width: 560px) {
  .cc-form { grid-template-columns: 1fr; }
}
.cc-resumo { margin: var(--sp-3) 0 var(--sp-2); }
.cc-lista { list-style: none; margin: 0; padding: 0; }
.cc-item {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 10px 0;
}
.cc-item + .cc-item { border-top: 1px solid var(--border); }
.cc-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.cc-txt small { color: var(--text-faint); font-variant-numeric: tabular-nums; }
.cc-nota { font-style: italic; }
/* A cidade que cresceu desde a conferência é a que pede uma segunda
   passada — e é a única linha da lista que precisa chamar atenção. */
.cc-cresceu {
  display: flex; align-items: center; gap: 5px; flex: 0 0 auto;
  font-size: 12.5px; font-weight: 600; color: var(--accent-txt);
}
.cc-cresceu .ico { width: 15px; height: 15px; }

/* ======================== ativo, inativo ou todos ================== */
/* O seletor das filas de enriquecimento: rótulo curto ao lado, e não em
   cima — é um filtro, não um campo de formulário. */
.se-rotulo { display: inline-flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-3); }
.se-rotulo > span { font-size: 13px; font-weight: 600; color: var(--text-soft); }
.se-rotulo select { width: auto; }
.ft-fila-topo .se-rotulo { margin: 0; }

/* ============================ varredura por cidade ================= */
/* Mesma grade das cidades conferidas: cidade larga, UF estreita, botão. */
.vr-form {
  display: grid; gap: var(--sp-2);
  grid-template-columns: minmax(180px, 1fr) 64px auto;
  align-items: center;
}
@media (max-width: 560px) {
  .vr-form { grid-template-columns: 1fr 64px; }
  .vr-form .vr-abrir { grid-column: 1 / -1; justify-self: start; }
}
.vr-lista-passos { margin: var(--sp-3) 0 0; padding-left: 1.3em; display: grid; gap: var(--sp-2); }
.vr-lista-passos li { line-height: 1.5; }
.vr-msg { margin-top: var(--sp-2); }
.vr-cabeca { margin: var(--sp-3) 0 var(--sp-2); }
.vr-abas { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.vr-lista { list-style: none; margin: 0; padding: 0; }
.vr-item {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding: 10px 0;
}
.vr-item + .vr-item { border-top: 1px solid var(--border); }
.vr-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 240px; }
.vr-txt a { font-weight: 600; overflow-wrap: anywhere; }
.vr-txt small { color: var(--text-faint); font-variant-numeric: tabular-nums; }
.vr-txt small .ico { width: 13px; height: 13px; vertical-align: -2px; }
.vr-motivo { font-style: italic; }
.vr-acoes { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.vr-mais { margin-top: var(--sp-3); }
.rc-lista { margin-top: var(--sp-4); border-top: 1px solid var(--border); padding-top: var(--sp-3); }
.rc-lista > summary { cursor: pointer; font-weight: 600; min-height: 44px; display: flex; align-items: center; gap: var(--sp-2); }
.vr-importar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin: 0 0 var(--sp-2); }

/* Panorama: país → estado → região → cidade (`o-panorama-da-varredura.js`).
   Cada nível recua um pouco e tem duas réguas: cidades varridas e locais
   completos. A barra cheia fica verde; a vazia é só o trilho. */
.pv { margin: var(--sp-3) 0 var(--sp-4); border: 1px solid var(--border); border-radius: var(--r); padding: var(--sp-3); background: var(--surface); }
.pv-cabeca { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.pv-arvore { margin-top: var(--sp-2); }
.pv-no > summary {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-3);
  min-height: 44px; padding: 6px 0; cursor: pointer; list-style: none;
}
.pv-no > summary::-webkit-details-marker { display: none; }
.pv-no > summary::before {
  content: ""; width: 7px; height: 7px; flex: none; margin-right: -2px;
  border-right: 2px solid var(--text-faint); border-bottom: 2px solid var(--text-faint);
  transform: rotate(-45deg); transition: transform .15s;
}
.pv-no[open] > summary::before { transform: rotate(45deg); }
.pv-no > summary .ico { width: 18px; height: 18px; flex: none; color: var(--text-soft); }
.pv-no + .pv-no { border-top: 1px solid var(--border); }
.pv-filhos { padding: 0 0 var(--sp-2) var(--sp-4); }
.pv-nome { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.pv-pais > summary .pv-nome { font-size: 1.05em; }
.pv-regiao.fechada > summary .ico { color: var(--ok); }
.pv-reguas { display: inline-flex; flex-wrap: wrap; gap: 4px var(--sp-3); margin-left: auto; }
.pv-regua { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.pv-regua b { color: var(--text); font-weight: 600; }
.pv-vazio { color: var(--text-faint); }
.pv-barra { width: 64px; height: 6px; border-radius: var(--r-pill); background: var(--surface-2); overflow: hidden; }
.pv-barra i { display: block; height: 100%; background: var(--brand); border-radius: inherit; }
.pv-barra.cheia i { background: var(--ok); }
.pv-faltas { display: inline-flex; flex-wrap: wrap; gap: 4px; flex-basis: 100%; padding-left: 28px; }
.pv-falta { font-size: 11px; padding: 1px 7px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--text-soft); }
.pv-cidades { list-style: none; margin: 0; padding: 0; }
.pv-cidade {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2);
  width: 100%; min-height: 44px; padding: 6px var(--sp-2); text-align: left;
  font: inherit; color: inherit; background: none; border: 0; border-radius: var(--r-sm);
}
button.pv-cidade { cursor: pointer; }
button.pv-cidade:hover { background: var(--surface-2); }
.pv-cidades li + li { border-top: 1px solid var(--border); }
.pv-cidade .pv-nome { font-weight: 500; }
.pv-cidade .pv-faltas { padding-left: 0; }
.pv-selo { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; padding: 1px 7px; border-radius: var(--r-pill); border: 1px solid var(--border); color: var(--text-soft); }
.pv-selo .ico { width: 12px; height: 12px; }
.pv-selo.ok { color: var(--ok); border-color: currentColor; }
.pv-selo.falta { color: var(--warn); border-color: currentColor; }
.pv-regua-txt { white-space: nowrap; }
/* Três níveis de recuo comem metade de uma tela de 375px. */
@media (max-width: 560px) {
  .pv { padding: var(--sp-2); }
  .pv-filhos { padding-left: var(--sp-2); }
  .pv-cidade { padding-inline: 4px; }
  .pv-faltas { padding-left: 0; }
}

/* ==================================== hub "Em andamento" ============ */
/* Alvos grandes e poucos. É a tela usada com o carro andando: cada ação
   precisa ser acertada sem olhar, então área generosa vale mais que
   densidade de informação. */
.andamento-grade {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
  margin-top: 18px;
}
.andamento-acao {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  min-height: 118px; padding: 18px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  cursor: pointer; text-align: left;
  transition: border-color .16s ease, transform .16s ease;
}
.andamento-acao:hover { border-color: var(--accent); transform: translateY(-2px); }
.andamento-acao .ico { width: 26px; height: 26px; color: var(--accent-txt); }
.andamento-acao strong { font-size: 17px; font-weight: 800; }
.andamento-acao small { color: var(--text-soft); line-height: 1.4; }

.andamento-viagem {
  display: flex; flex-direction: column; gap: 4px;
  padding: 16px 18px; border-radius: var(--r-lg);
  background: var(--brand); color: var(--brand-text);
}
.andamento-viagem strong { font-size: 20px; font-weight: 800; }
.andamento-viagem .field-hint { color: inherit; opacity: .85; }
.andamento-selo {
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 700; opacity: .8;
}

.acervo-atalhos { display: flex; gap: 10px; flex-wrap: wrap; margin: 4px 0 16px; }

@media (prefers-reduced-motion: reduce) {
  .andamento-acao:hover { transform: none; }
}

/* ==================================== mapa da ferramenta ============ */
/* Tela de leitura, não de operação: linha curta, respiro entre blocos e
   nenhum botão disputando atenção. Quem chega aqui está decidindo o que
   pedir, não executando tarefa. */
.fn-topo {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  margin-bottom: 18px; padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.fn-resumo { font-size: 14px; color: var(--text-soft); }
.fn-resumo strong { color: var(--text); font-weight: 800; }
.fn-controles { display: flex; gap: 8px; margin-left: auto; flex-wrap: wrap; }
.fn-busca {
  min-width: 260px; padding: 8px 12px; font: inherit; font-size: 13px;
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--text);
}

.fn-area { margin-bottom: 30px; }
.fn-area-cab { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.fn-area-cab h3 { font-size: 19px; font-weight: 800; }
.fn-papel {
  font-size: 11px; color: var(--text-faint);
  border: 1px solid var(--border); border-radius: var(--r-pill);
  padding: 1px 9px;
}
.fn-ir { margin-left: auto; font-size: 12px; padding: 4px 12px; }
.fn-area-resumo {
  color: var(--text-soft); font-size: 13.5px; max-width: 62ch;
  margin: 4px 0 12px;
}

.fn-lista {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 12px;
}
.fn-item {
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2); padding: 12px 14px;
}
.fn-item-cab {
  display: flex; align-items: center; gap: 8px; margin-bottom: 5px;
}
.fn-item-cab strong { font-size: 14px; font-weight: 700; }
.fn-item p { font-size: 12.5px; color: var(--text-soft); line-height: 1.5; }
.fn-nota {
  display: flex; gap: 5px; align-items: flex-start;
  margin-top: 6px; color: var(--text-faint) !important;
}
.fn-nota .ico { width: 13px; height: 13px; flex: none; margin-top: 2px; }

/* O caminho do arquivo é o que transforma o inventário em índice de
   código: dá para ir direto ao lugar sem abrir o que não interessa. */
.fn-arquivos { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 9px; }
.fn-arquivos code {
  font-size: 10.5px; color: var(--text-faint);
  background: var(--bg-alt); border-radius: 3px; padding: 1px 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.fn-estado {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; padding: 2px 8px; border-radius: var(--r-pill);
  border: 1px solid currentColor; margin-left: auto; white-space: nowrap;
}
.fn-pronto { color: var(--brand); }
.fn-parcial { color: var(--warn); }
.fn-andamento { color: var(--accent-txt); }
.fn-ideia { color: var(--text-faint); }

/* ==========================================================================
   Roteiros prontos — a faixa que abre o app

   A tela começava num formulário. A faixa põe a proposta antes da pergunta,
   e por isso ela mora acima do assistente, não numa aba escondida.

   O cartão é foto grande com o texto POR CIMA, não foto ao lado de texto: em
   telefone, o segundo formato dá uma miniatura de 80px que não convence
   ninguém a viajar. O véu em degradê é o que mantém o título legível sobre
   qualquer imagem — inclusive uma cachoeira estourada de sol.
   ========================================================================== */
.rot-faixa { margin-bottom: var(--sp-5); }

/* A engrenagem dos roteiros prontos: ícone sem texto, cor de estrutura. O
   ponto terracota diz que há ajuste valendo (`as-preferencias-da-vitrine.js`). */
.rot-engrenagem { position: relative; display: inline-flex; align-items: center;
  justify-content: center; width: 32px; height: 32px; margin-left: var(--sp-1);
  vertical-align: middle; border: 0; border-radius: var(--r); background: none;
  color: var(--text-soft); cursor: pointer; }
.rot-engrenagem:hover, .rot-engrenagem[aria-expanded="true"] { color: var(--text); background: var(--surface-2); }
.rot-engrenagem .ico { width: 18px; height: 18px; }
.rot-engrenagem.com-ajuste::after { content: ""; position: absolute; top: 6px; right: 6px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.rot-jeito { margin-top: var(--sp-3); padding: var(--sp-3); border: 1px solid var(--border);
  border-radius: var(--r-lg); background: var(--surface); max-width: 560px; }
.rot-jeito-corpo { display: grid; gap: var(--sp-3); }
.rot-jeito-linha { display: flex; align-items: center; gap: var(--sp-2); font-size: 14px; }
.rot-jeito-gostos { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-1); }
.rot-jeito-botoes { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.rot-faixa-cabeca {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px 20px;
  flex-wrap: wrap;
}
/* "Tenho [um dia]" — o tamanho da viagem, ao lado do título e não acima
   dele: é filtro do que está logo abaixo, não uma segunda seção. */

/* Subir e descer uma parada. À DIREITA e dentro do bloco: à esquerda elas
   caíam sobre a linha da timeline e, no painel estreito do mapa, metade
   ficava fora. Só aparecem quando o ponteiro passa — trinta setas sempre
   acesas competiriam com o roteiro em si. */
.stop { position: relative; }
.stop-ordem {
  position: absolute; right: 4px; top: 6px;
  display: flex; gap: 3px;
  opacity: 0; transition: opacity .12s;
}
.stop:hover .stop-ordem, .stop-ordem:focus-within { opacity: 1; }
.stop-ordem button {
  display: flex; padding: 4px; border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface); color: var(--text-soft); cursor: pointer;
}
.stop-ordem button:hover { color: var(--brand); }
.stop-ordem .ico { width: 14px; height: 14px; }
/* Os três pontos da parada no montador (`ajustar-a-parada.js`): sempre
   acesos, porque são o gesto; as setas é que esperam o ponteiro. */
.stop > .aap-btn { position: absolute; right: 0; top: 2px; margin: 0; }
.stop.poi > .stop-ordem { right: 36px; }
.stop.poi h5 { padding-right: 40px; }
.aap-menu { top: 34px; right: 0; }
/* "Ver no Google Maps" de cada destino do roteiro. */
.stop-maps { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; margin-top: 2px; }
.stop-maps .ico { width: 14px; height: 14px; }
.aap-folha { display: flex; flex-direction: column; }
.aap-dica { font-size: 12.5px; color: var(--text-soft); margin: 0; }
.aap-perto { min-height: 60px; }
.aap-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.aap-lista li { display: flex; align-items: center; gap: var(--s2); padding: var(--s2) 0;
  border-bottom: 1px solid var(--border); }
.aap-lista li:last-child { border-bottom: 0; }
.aap-cat { flex: 0 0 auto; display: flex; color: var(--brand); }
.aap-cat .ico { width: 20px; height: 20px; }
.aap-nome { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.aap-nome strong { font-size: 14px; overflow-wrap: anywhere; }
.aap-nome small { font-size: 12px; color: var(--text-soft); }

.rot-vazio { color: var(--text-soft); padding: 18px 4px; }

/* O mapa vazio, no alto de Meus Lugares: entre ele e o "+ Registrar lugar". */
#vs-vazio:not(:empty) { margin-bottom: var(--sp-3); }

.rot-faixa-cabeca h2 { font-size: 25px; letter-spacing: -.02em; margin: 0; }
.rot-faixa-cabeca p {
  margin: 4px 0 0; font-size: 13.5px; color: var(--text-soft);
}
/* Trilho horizontal com encaixe: rolar de lado é o gesto que a pessoa já usa
   para vitrine, e o encaixe impede o cartão cortado pela metade. Sangra até a
   borda para o cartão seguinte aparecer espiando — é ele que avisa que há
   mais, sem precisar de seta. */
.rot-trilho {
  display: flex;
  gap: 14px;
  margin: 16px -16px 0;
  padding: 4px 16px 14px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* Sem isto o encaixe ignora o `padding` e para o primeiro cartão colado
     na borda da tela — o navegador rolava 16px sozinho no carregamento. */
  scroll-padding-inline: 16px;
  scrollbar-width: none;

}
.rot-trilho::-webkit-scrollbar { display: none; }

/* O cartão que espia na borda avisa que há mais; cortado pela régua, avisa
   que a tela quebrou. O desbotado resolve os dois: continua dizendo "tem
   mais para lá" e tira o corte reto. Quem liga é `faixa-rolante.js`, com a
   mesma medida que decide as setas: uma conta, dois efeitos.

   A regra é de QUALQUER faixa que role de lado — a vitrine de roteiros e a
   fila de conquistas usam a mesma. As duas pontas nascem em zero porque o
   desbotado tem de sumir na ponta onde a faixa ACABOU: ali não há mais
   cartão, e desbotar comeria a borda do último — some justamente o que diz
   "acabou". */
.rot-trilho, .frase-trilho, .evp-trilho {
  --fade-antes: 0px;
  --fade-depois: 0px;
  -webkit-mask-image: linear-gradient(to right,
    transparent 0, #000 var(--fade-antes),
    #000 calc(100% - var(--fade-depois)), transparent 100%);
  mask-image: linear-gradient(to right,
    transparent 0, #000 var(--fade-antes),
    #000 calc(100% - var(--fade-depois)), transparent 100%);
}
.rot-trilho.tem-mais-antes, .evp-trilho.tem-mais-antes {
  --fade-antes: 40px;
}
.rot-trilho.tem-mais-depois, .evp-trilho.tem-mais-depois {
  --fade-depois: 40px;
}

.rot-card {
  position: relative;
  flex: 0 0 auto;
  width: 264px;
  height: 316px;
  scroll-snap-align: start;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  padding: 0;
  cursor: pointer;
  text-align: left;
  /* Sem foto, o fundo é a cor da família — nunca um retângulo vazio. */
  background: linear-gradient(155deg,
              color-mix(in srgb, var(--cor) 85%, #000),
              color-mix(in srgb, var(--cor) 45%, #000));
  box-shadow: var(--shadow-sm);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.rot-card:hover, .rot-card:focus-visible {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
}

.rot-foto {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  transition: transform .6s var(--ease);
}
.rot-card:hover .rot-foto { transform: scale(1.06); }

/* Metade de baixo escura o bastante para texto branco em cima de qualquer
   foto; metade de cima quase limpa, para a imagem continuar sendo o motivo. */
.rot-veu {
  position: absolute; inset: 0;
  background: linear-gradient(to top,
              rgba(10,16,14,.92) 0%, rgba(10,16,14,.72) 38%,
              rgba(10,16,14,.18) 68%, rgba(10,16,14,.05) 100%);
}

.rot-txt {
  position: absolute; inset: auto 0 0 0;
  display: flex; flex-direction: column; gap: 5px;
  padding: 16px 16px 15px;
  color: #f4f7f5;
}
.rot-selo {
  align-self: flex-start;
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 9px; border-radius: var(--r-pill);
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(255,255,255,.28);
  backdrop-filter: blur(4px);
}
/* Sobre foto, a sombra é CONTORNO: curta e escura. Um borrão de 10px lê
   como névoa em volta das letras — foi o que a tela de montar ganhou
   quando tinha foto atrás, e é o que se está desfazendo aqui. */
.rot-titulo {
  font-size: 19px; font-weight: 700; line-height: 1.2;
  letter-spacing: -.015em;
  text-shadow: 0 1px 2px rgba(0,0,0,.9);
}
.rot-cidades {
  font-size: 12px; color: rgba(244,247,245,.78);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* O que o roteiro é para QUEM LÊ: a que distância fica, quantas paradas a
   pessoa já conhece. Fica abaixo das cidades e acima da chamada, em tom
   mais claro que o título e mais forte que as cidades — é informação de
   decisão, e não legenda. Na pílula do topo ela quebrava a linha e
   desalinhava o cartão dos vizinhos. */

.rot-pv-ico { width: 13px; height: 13px; opacity: .85; }

.rot-cta {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 6px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .02em;
  color: #ffd9c4;                     /* terracota clareado: legível no escuro */
}
.rot-seta { width: 15px; height: 15px; transform: rotate(-90deg); }

@media (prefers-reduced-motion: reduce) {
  .rot-card, .rot-foto { transition: none; }
  .rot-card:hover { transform: none; }
  .rot-card:hover .rot-foto { transform: none; }
}

/* ------------------------------------------------- ficha do roteiro ---- */
.rot-ficha-card { max-width: 640px; overflow: hidden; }

.rot-ficha-capa {
  position: relative;
  min-height: 190px;
  display: flex; align-items: flex-end;
  background-size: cover; background-position: center;
  background-color: var(--cor);
  padding: 0;
}
/* O degradê é pseudo-elemento para a capa poder receber a foto por
   `style=` sem que o JS precise montar duas camadas. */
.rot-ficha-capa::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top,
              rgba(10,16,14,.94) 0%, rgba(10,16,14,.6) 55%,
              rgba(10,16,14,.25) 100%);
}
.rot-ficha-titulo { position: relative; z-index: 1; padding: 18px 22px 16px; color: #f4f7f5; }
.rot-ficha-titulo h3 {
  margin: 7px 0 4px; font-size: 23px; line-height: 1.18;
  letter-spacing: -.02em; text-shadow: 0 1px 2px rgba(0,0,0,.9);
}
.rot-ficha-titulo p { margin: 0; font-size: 12.5px; color: rgba(244,247,245,.8); }

.rot-fecha {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255,255,255,.25);
  background: rgba(10,16,14,.5);
  color: #f4f7f5; cursor: pointer;
  backdrop-filter: blur(4px);
}
.rot-fecha:hover { background: rgba(10,16,14,.75); }

.rot-ficha-corpo { padding: 6px 22px 4px; }
/* O selo dos roteiros produzidos pelo Desbravia (`o-roteiro-do-desbravia.js`).
   Faixa sólida com quina, e não véu: fica sobre a foto do cartão. A cor do
   texto é `--brand-text`, que vira escura no tema escuro junto com o
   `--brand` clareado: com branco fixo, dava 2,8:1 (1.275.1). */
.rot-autoria {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--r); background: var(--brand); color: var(--brand-text);
}
.rot-autoria .ico { width: 12px; height: 12px; }
.rot-ficha-resumo { margin: var(--sp-2) 0 var(--sp-3); font-size: 14px; line-height: 1.55; color: var(--text-soft); }
.rot-validar { display: flex; flex-wrap: wrap; gap: var(--sp-2); padding: var(--sp-2) 22px; border-top: 1px solid var(--border); }
.rot-paradas { list-style: none; margin: 0; padding: 0; }

.rot-parada {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.rot-parada:last-child { border-bottom: 0; }
/* As reticências de cada parada. `relative` aqui e não no `<ol>`: o menu
   se ancora na LINHA, e ancorado na lista ele apareceria sempre no topo
   dela, longe da parada que abriu.
   O botão do cartão (`.md-menu-btn`) não serve: ele é claro sobre foto
   escura, e aqui o chão é a superfície da ficha. */
.rot-op-btn {
  position: relative; z-index: 1;
  flex: 0 0 auto; margin-left: auto;
  width: 30px; height: 30px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: var(--r);
  background: none; color: var(--text-soft); cursor: pointer;
}
.rot-op-btn:hover, .rot-op-btn:focus-visible,
.rot-op-btn[aria-expanded="true"] {
  background: var(--surface-2); border-color: var(--border);
  color: var(--text);
}
.rot-op-btn .ico { width: 16px; height: 16px; }
.rot-parada { position: relative; }
.rot-op-menu { top: 40px; right: 4px; }

.rot-ordem {
  flex: 0 0 auto;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--brand-soft); color: var(--brand);
  font-size: 11px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.rot-parada-foto {
  flex: 0 0 auto;
  width: 54px; height: 54px;
  border-radius: var(--r);
  background-size: cover; background-position: center;
  background-color: var(--surface-2);
}
.rot-parada-foto.sem-foto {
  display: grid; place-items: center; color: var(--text-faint);
}
.rot-parada-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Duas linhas em vez de reticências: nome de destino no Brasil é comprido
   ("Parque Estadual do Espigão Alto"), e cortar no meio faz a pessoa não
   reconhecer o lugar que ela talvez já conheça. */
.rot-parada-txt strong {
  font-size: 14px; font-weight: 600; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.rot-parada-txt small { font-size: 11.5px; color: var(--text-soft); }

.rot-ficha-pe { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
/* O link da rota é botão, e botão não vem sublinhado. */
.rot-ficha-pe a.btn { text-decoration: none; }
.rot-ficha-pe .btn { flex: 1; justify-content: center; }
.rot-ficha-pe .btn.ghost { flex: 0 0 auto; }
/* O Maps virou segunda opção: quem quer a rota pronta ainda a tem, mas a
   ação que abre o roteiro para edição é a que ganha o peso visual. Link em
   vez de botão porque duas caixas lado a lado leem como escolha entre
   iguais — e elas não são. */
.rot-maps {
  /* Linha própria, embaixo. Sem `flex-wrap` no pai ele não descia: ficava
     espremido ao lado dos botões e o texto era CORTADO no meio — "Abrir no
     Google M". Defeito que só a tela mostra: o CSS lê como se estivesse
     certo. */
  flex: 1 0 100%; order: 3; text-align: center;
  font-size: 13px; color: var(--text-faint); text-decoration: underline;
  text-underline-offset: 3px; padding-top: 2px;
}
.rot-maps:hover { color: var(--text-soft); }

@media (max-width: 560px) {
  .rot-card { width: 82vw; max-width: 300px; height: 300px; }
  /* Um por linha, na ordem em que se decide: a AÇÃO primeiro, a saída
     depois, o link do Maps por último.
     Era `column-reverse` com `order: -1` no link. Aquilo resolvia "o Maps
     não sobe para cima da ação" e criava outro problema no caminho: com a
     inversão, "Fechar" ficava ACIMA de "Montar este roteiro" — o polegar
     chegava primeiro no botão que desiste. Ordem explícita não inverte
     nada e diz o que se quer. */
  .rot-ficha-pe { flex-direction: column; }
  .rot-ficha-pe .btn { width: 100%; }
  .rot-ficha-pe .btn.primary { order: 1; }
  .rot-ficha-pe .btn.ghost { order: 2; }
  .rot-maps { order: 3; }
}

/* A nota fica na mesma linha do tipo e da cidade, com a estrela do sprite —
   o caractere de estrela da fonte muda de desenho a cada sistema. */
.rot-nota-caixa {
  display: inline-flex; align-items: center; gap: 3px;
  margin-left: 4px; color: var(--warn); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.rot-nota { width: 12px; height: 12px; }

/* --------------------------------------------------- setas do trilho ---
   No telefone o dedo arrasta e o cartão espiando na borda já diz que há
   mais. No computador não existe esse gesto — a roda do mouse rola a
   página, não a faixa —, e o cartão cortado passava a impressão de tela
   quebrada em vez de vitrine. */
.rot-palco { position: relative; }

.rot-seta-btn {
  position: absolute;
  top: calc(50% - 12px);            /* desconta a sombra de baixo do trilho */
  transform: translateY(-50%);
  z-index: 2;
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--text);
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: background .2s var(--ease), transform .2s var(--ease);
}
.rot-seta-btn:hover { background: var(--surface); transform: translateY(-50%) scale(1.06); }
.rot-seta-btn[hidden] { display: none; }
.rot-seta-btn.antes { left: -6px; }
.rot-seta-btn.depois { right: -6px; }
/* Um desenho só, espelhado: duas setas desenhadas à mão nunca ficam
   exatamente simétricas, e a assimetria aparece justamente lado a lado. */
.rot-seta-btn.depois .ico { transform: scaleX(-1); }
.rot-seta-btn .ico { width: 19px; height: 19px; }

@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .rot-seta-btn { background: var(--surface); }
}

/* Tela de toque não precisa de botão, e ele só taparia cartão. */
@media (pointer: coarse) {
  .rot-seta-btn { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .rot-seta-btn { transition: none; }
  .rot-seta-btn:hover { transform: translateY(-50%); }
}

/* A contagem que sustenta a nota. Discreta de propósito: ela qualifica a
   estrela, não disputa com ela. */
 .nota-quantos { color: var(--text-faint); font-weight: 400;
  margin-left: 2px; }
/* A nota digitada à mão se identifica. Em itálico e apagada: ela é um
   aparte sobre a nota, não um segundo número disputando a leitura. */
.nota-fonte { color: var(--text-faint); font-weight: 400; font-style: italic;
  margin-left: 5px; }
/* Só a estrutura da nota — a linha e o respiro entre a estrela e o número.
   A aparência é de cada tela: a mesma regra aqui faria o selo da Oficina
   herdar o tamanho do cartão da vitrine. */
.nota { display: inline-flex; align-items: center; gap: 3px; }
/* Onde a nota é um dado entre outros na mesma linha, ela ganha só o
   afastamento — a cor e o tamanho vêm do texto que a cerca. */
.bg-nota, .dq-nota { margin-left: 6px; }
.bg-nota .ico, .dq-nota .ico { width: 12px; height: 12px; }

/* ================================================== Duplicidades =========
   A pergunta é "estes dois são a mesma coisa?", e ela se responde
   comparando linha por linha. Por isso lado a lado com os campos
   alinhados: uma lista corrida obrigaria a guardar o primeiro cadastro na
   memória enquanto lê o segundo. */
.dup-vazio { color: var(--text-soft); padding: 18px 2px; }

.dup-par {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 14px 16px 12px;
  margin-bottom: 12px;
  background: var(--surface);
  transition: opacity .2s var(--ease);
}
.dup-par.julgando { opacity: .45; pointer-events: none; }

.dup-par-topo {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; margin-bottom: 12px;
}
.dup-selo {
  font-size: 10.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; padding: 3px 9px;
  border-radius: var(--r-pill); border: 1px solid currentColor;
}
.dup-selo.forte { color: var(--danger); }
.dup-selo.alerta { color: var(--warn); }
.dup-selo.duvida { color: var(--text-faint); }
.dup-medida { font-size: 12px; color: var(--text-soft); }

.dup-lados {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 12px; align-items: start;
}
.dup-lado {
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 10px 12px;
  background: var(--surface-2);
  min-width: 0;
}
.dup-nome { display: block; font-size: 14.5px; line-height: 1.25; margin-bottom: 8px; }
.dup-versus {
  align-self: center; font-size: 11px; font-weight: 700;
  color: var(--text-faint); text-transform: uppercase; letter-spacing: .08em;
}

.dup-campos { margin: 0; display: grid; gap: 3px; }
.dup-campos > div { display: flex; gap: 8px; font-size: 12.5px; }
.dup-campos dt {
  color: var(--text-faint); min-width: 46px;
  text-transform: uppercase; font-size: 10.5px; letter-spacing: .04em;
  align-self: center;
}
.dup-campos dd { margin: 0; color: var(--text); font-variant-numeric: tabular-nums; }

/* O aviso de coordenada errada é o que impede o pior erro possível aqui:
   unir dois lugares legítimos e apagar um destino. */
.dup-alerta {
  display: flex; gap: 8px; align-items: flex-start;
  margin: 12px 0 0; padding: 10px 12px;
  border-radius: var(--r); font-size: 12.5px; line-height: 1.45;
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  color: var(--text);
}
.dup-alerta .ico { flex: 0 0 auto; width: 16px; height: 16px; color: var(--warn); }
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .dup-alerta { background: var(--surface-2); border-color: var(--warn); }
}

.dup-desc { margin: 8px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--text-soft); }
.dup-lado-acoes { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: 10px; }
.dup-acoes { display: flex; gap: 10px; margin-top: 12px; }
.dup-acoes .btn { flex: 0 1 auto; }

@media (max-width: 620px) {
  .dup-lados { grid-template-columns: 1fr; }
  .dup-versus { justify-self: center; }
  .dup-acoes { flex-direction: column; }
  .dup-acoes .btn { width: 100%; justify-content: center; }
}

/* A gaveta dos já conferidos. Recolhida: é saída de emergência, não o
   trabalho do dia — mas visível o bastante para o engano não parecer
   definitivo, que é o que faria a pessoa hesitar em toda decisão. */
.dup-julgados { margin-top: 14px; }
.dup-julgados > summary {
  cursor: pointer; display: flex; align-items: baseline; gap: 10px;
  flex-wrap: wrap; list-style: none;
}
.dup-julgados > summary::-webkit-details-marker { display: none; }
/* A seta é o chevron do sprite, girado — caractere de triângulo da fonte
   muda de desenho a cada sistema e não é a identidade do projeto. */
.dup-seta {
  width: 14px; height: 14px; color: var(--text-faint);
  transform: rotate(-90deg);
  transition: transform .2s var(--ease);
}
.dup-julgados[open] .dup-seta { transform: rotate(0deg); }
.dup-julgados > summary small { color: var(--text-soft); font-size: 12.5px; }
.dup-julgados > div { margin-top: 12px; }

.dup-julgado {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.dup-julgado:last-child { border-bottom: 0; }
.dup-julgado-txt { flex: 1 1 auto; font-size: 13px; min-width: 0; }
.dup-julgado-txt small { color: var(--text-soft); margin-left: 5px; }
.dup-julgado-txt em {
  font-style: normal; color: var(--text-faint);
  margin: 0 7px; font-size: 11.5px; text-transform: uppercase;
}
.dup-julgado .btn { flex: 0 0 auto; }

@media (max-width: 620px) {
  .dup-julgado { flex-direction: column; align-items: stretch; gap: 8px; }
  .dup-julgado .btn { width: 100%; justify-content: center; }
}

/* --------------------------------------------- desativados ---------- */
.dsv-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.dsv-item:last-child { border-bottom: 0; }
.dsv-item.julgando { opacity: .45; pointer-events: none; }
.dsv-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dsv-txt strong { font-size: 14px; font-weight: 600; }
.dsv-txt small { font-size: 11.5px; color: var(--text-soft); }
.dsv-item .btn { flex: 0 0 auto; }

@media (max-width: 620px) {
  .dsv-item { flex-direction: column; align-items: stretch; gap: 8px; }
  .dsv-item .btn { width: 100%; justify-content: center; }
}

/* ----------------------------------------------------- comboio ------- */
.cmb-acoes {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.cmb-continuo {
  display: flex; align-items: center; gap: 7px;
  font-size: 12.5px; color: var(--text-soft);
}
/* O pedido de socorro não divide espaço com o resto: ou ele é a coisa
   mais visível da tela, ou não devia estar aqui. */
.cmb-sos-area {
  display: flex; flex-direction: column; gap: 6px;
  margin: 4px 0 16px; padding: 12px 14px;
  border: 1px dashed var(--border); border-radius: 10px;
}
.cmb-sos-area small { color: var(--text-soft); font-size: 11.5px; }
.cmb-sos-area input {
  width: 100%; padding: 9px 11px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text); font: inherit; font-size: 13px;
}
.cmb-sos-confirma {
  border-style: solid; border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
}
.cmb-sos-botoes { display: flex; gap: 10px; flex-wrap: wrap; }
.cmb-sos-botoes .btn { flex: 1 1 auto; justify-content: center; }
.cmb-sos-ativo {
  display: flex; flex-direction: column; gap: 6px;
  margin: 4px 0 16px; padding: 12px 14px; border-radius: 10px;
  border: 1px solid var(--danger);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
}
.cmb-sos-ativo small { color: var(--text-soft); font-size: 12px; }
.cmb-sos-ativo .btn { align-self: flex-start; }

.cmb-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--border);
}
.cmb-item:last-child { border-bottom: 0; }
/* SOS não é um selo a mais na linha: é a única coisa que importa nela. */
.cmb-item.cmb-alerta {
  border-left: 3px solid var(--danger); padding-left: 10px;
  background: color-mix(in srgb, var(--danger) 8%, transparent);
}
.cmb-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cmb-txt strong { font-size: 14.5px; }
.cmb-txt small { font-size: 12px; color: var(--text-soft); }
.cmb-selos { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 3px; }
.cmb-selo {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text-soft);
}
.cmb-selo.cmb-sos { border-color: var(--danger); color: var(--danger); }
/* O recado é texto de gente, não rótulo: em caixa alta ele vira grito e
   fica mais difícil de ler justamente na linha em que ler importa. */
.cmb-recado {
  font-size: 13px; font-style: normal; color: var(--danger);
  margin-top: 2px;
}
.cmb-item .btn { flex: 0 0 auto; }

@media (max-width: 620px) {
  .cmb-item { flex-wrap: wrap; }
  .cmb-item .btn { flex: 1 1 0; justify-content: center; }
}

/* ------------------------------------------------ em andamento ------- */
/* Alvos grandes e linha por parada: isto é lido com o carro andando e
   tocado com uma mão só. */
.andamento-dia { margin: 4px 0 16px; }
.andamento-dia-cab {
  display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 6px; padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.andamento-dia-cab strong { font-size: 15px; }
.andamento-dia-cab small { color: var(--text-soft); font-size: 12px; }
.andamento-parada {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.andamento-parada:last-child { border-bottom: 0; }
.andamento-parada.andamento-feito { opacity: .55; }
.andamento-hora {
  flex: 0 0 auto; font-variant-numeric: tabular-nums;
  font-size: 15px; font-weight: 600; min-width: 46px;
}
.andamento-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.andamento-txt strong { font-size: 14px; font-weight: 600; }
.andamento-txt small { font-size: 11.5px; color: var(--text-soft); }
.andamento-parada .btn { flex: 0 0 auto; padding: 8px 14px; }

@media (max-width: 620px) {
  .andamento-parada { flex-wrap: wrap; }
  .andamento-txt { flex-basis: calc(100% - 58px); }
  .andamento-parada .btn { flex: 1 1 0; justify-content: center; }
}

/* O texto ocupa o que sobrar e o botão fica na mesma linha: a explicação
   sem o caminho vira aviso, e aviso a mais é o que as pessoas aprendem a
   não ler. */

/* ------------------------------------------------- fechados --------- */
.fch-acoes { margin-bottom: 10px; }
.fch-saidos { margin: 16px 0 4px; }
.dsv-porque { color: var(--warn); font-size: 11.5px; }
/* A anotação lida é a prova da acusação: ela fica grifada dentro do nome,
   e não num rótulo à parte, senão quem confere teria de procurar no texto
   qual palavra motivou a linha. */
.fch-marca {
  background: color-mix(in srgb, var(--warn) 22%, transparent);
  color: inherit; padding: 0 3px; border-radius: 3px;
}

/* ------------------------------------------------------ névoa -------- */
/* O resumo da névoa fala do que FALTA, e por isso o número que salta é o
   das cidades no escuro — é ele que faz alguém desviar 40 km. */

/* O painel de cadastros a corrigir vem recolhido: aberto, ele empurrava o
   mapa para baixo da dobra com 104 linhas de "informe a UF" — a lista de
   tarefas passando na frente da coisa que a pessoa veio ver. */
details.vs-fix > summary { cursor: pointer; list-style: none; }
details.vs-fix > summary::-webkit-details-marker { display: none; }
details.vs-fix > summary::after {
  content: "ver"; margin-left: 8px; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--accent-txt);
}
details.vs-fix[open] > summary::after { content: "esconder"; }

/* O título da cidade, dentro da ficha do mapa.

   A segunda linha, miúda, não é enfeite: ela é o que separa "esta é a terra
   dos mirantes" — afirmação sobre o estado, que um acervo pessoal não pode
   fazer — de "4 dos 6 lugares mapeados aqui são mirantes", que é verdade. O
   denominador é a honestidade, então ele nunca aparece sem o número. */
.fc-titulo {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 2px;
  font-size: 13px;
  font-weight: 700;
  color: var(--accent-txt);
}
.fc-titulo .fc-ico { width: 15px; height: 15px; flex: 0 0 auto; }
.fc-titulo-conta {
  display: block;
  margin-bottom: 6px;
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

/* "Já sabe para onde vai?" — o atalho acima da lista de destinos.

   A lista abaixo dele parte de um raio a partir de casa: ótima para
   descobrir, inútil para achar um destino que a pessoa já escolheu e que
   está fora do alcance atual. Os dois caminhos convivem, e a ordem é essa —
   quem sabe resolve na primeira linha, quem não sabe rola e explora. */
.md-atalho { margin-bottom: var(--sp-3); }
.md-atalho .field { margin-bottom: 0; }
.md-atalho .md-ou { margin: 10px 0 0; }

/* O destino principal em destaque.

   No passo da montagem, toda parada sugerida aparece num cartão com foto —
   menos a que a pessoa escolheu. O destino principal ficava numa caixinha de
   texto no topo enquanto as secundárias, logo abaixo, mostravam a paisagem:
   a hierarquia ao contrário, no lugar onde ela mais importa.

   A foto ocupa espaço de verdade porque é ela o motivo da viagem. Ver a
   cachoeira que puxou o roteiro é o que faz a montagem parecer uma viagem em
   vez de um formulário. */
/* Bloco próprio, e não uma classe na caixa: a mesma caixa é escrita pelo
   roteiro pronto e pelo replanejar, que trocam o conteúdo por texto simples.
   Se o formato morasse na caixa, cada uma delas teria de lembrar de tirá-lo,
   e a que esquecesse quebraria o layout em silêncio. A margem negativa
   anula o respiro da caixa para a foto encostar na borda. */
.dd {
  display: grid;
  /* A foto ocupa mais de um terço da ficha. Medido na tela: com 260px, um
     destino sem nota e sem descrição — que é a maioria — deixava metade do
     cartão vazia, e o vazio come justamente o efeito que ele veio dar. */
  grid-template-columns: minmax(0, 340px) 1fr;
  margin: calc(var(--s3) * -1);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.dd-foto {
  position: relative;
  margin: 0;
  min-height: 210px;
  background: var(--brand-soft);
}
.dd-foto img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
/* Sem foto, o ícone do tipo em tamanho grande — e não o retângulo cinza de
   "sem foto" dos cartões. Anunciar uma falta no lugar mais importante da
   tela é o oposto do que ele existe para fazer. */
.dd-marca {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--brand);
  opacity: .5;
}
.dd-foto img + .dd-marca { display: none; }
.dd-foto.dd-sem img { display: none; }
.dd-foto.dd-sem .dd-marca { display: flex; }
.dd-marca .dd-ico { width: 56px; height: 56px; }

.dd-corpo {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--s3);
  min-width: 0;
}
.dd-nome { font-size: 21px; line-height: 1.2; color: var(--text); }
.dd-marcas { font-size: 13px; color: var(--text-soft); }
.dd-numeros {
  display: flex; align-items: center; gap: 8px;
  margin-top: 2px;
  font-size: 12.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.dd-numeros .dd-mini { width: 13px; height: 13px; margin-right: 3px; }
.dd-desc {
  margin: 6px 0 0;
  font-size: 13px; line-height: 1.5; color: var(--text-soft);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}

@media (max-width: 700px) {
  /* No telefone a foto vira faixa: lado a lado, sobrariam 40% de largura
     para o nome e nem foto nem texto funcionariam. */
  .dd { grid-template-columns: 1fr; }
  .dd-foto { min-height: 160px; }
  .dd-nome { font-size: 19px; }
}

/*
  A lista de viagens dentro do painel do mapa. O painel é estreito e a
  pessoa chega nele procurando UMA coisa — o roteiro dela —, então cada
  item é um alvo largo com o nome em primeiro plano e a data em segundo.
*/
.viagens-atalho { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s3); }
.viagem-atalho {
  display: flex; flex-direction: column; gap: 2px; width: 100%;
  padding: var(--s3); text-align: left; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); color: var(--text);
}
.viagem-atalho:hover { border-color: var(--brand); }
.viagem-atalho strong { font-size: 14px; line-height: 1.25; }
.viagem-atalho small { color: var(--text-soft); font-size: 11.5px; }

/* ============================================================
   Busca fixa do topo + ficha do destino.

   A barra vive dentro da `topbar`, que tem altura fixa: por isso ela
   encolhe (`min-width: 0`) em vez de empurrar a marca para fora. No
   telefone, o menu já virou gaveta e sobra a largura de que ela precisa.
   ============================================================ */
.busca-global {
  position: relative;
  display: flex; align-items: center; gap: var(--s2);
  flex: 1 1 220px; min-width: 0; max-width: 460px;
  padding: 0 var(--s3);
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface-2); height: 36px;
}
.busca-global:focus-within { border-color: var(--brand); }
.bg-lupa { display: grid; place-items: center; color: var(--text-faint); }
.bg-lupa .ico { width: 16px; height: 16px; }
/*
  O seletor é comprido de propósito. `input[type="search"]` lá em cima vale
  (0,1,1) e `input:not([type="checkbox"])...` vale (0,2,1): os dois ganham
  de `.bg-campo` sozinho, e o input continuava desenhando a caixa dele —
  fundo, borda e cantos próprios — DENTRO da pílula arredondada. Um
  retângulo por cima do contorno redondo, que é exatamente o que aparecia.
*/
.busca-global input[type="search"].bg-campo {
  flex: 1 1 auto; min-width: 0; width: auto;
  height: 100%; min-height: 0; padding: 0;
  border: 0; border-radius: 0; background: transparent; color: var(--text);
  font-size: 13px; outline: none; box-shadow: none;
}
.busca-global input[type="search"].bg-campo:focus { background: transparent; }
.bg-campo::-webkit-search-cancel-button { display: none; }

.bg-lista {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  max-height: 60vh; overflow-y: auto; z-index: 950;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface); box-shadow: 0 18px 40px rgba(0,0,0,.18);
}
.bg-grupo {
  padding: 8px var(--s3) 4px; font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-faint);
}
.bg-grupo small { color: var(--text-faint); text-transform: none; letter-spacing: 0; }
.bg-item {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: 8px var(--s3); text-align: left; cursor: pointer;
  border: 0; background: transparent; color: var(--text);
}
.bg-item:hover, .bg-item:focus-visible { background: var(--surface-2); }
.bg-mini {
  display: grid; place-items: center; flex: none;
  width: 38px; height: 38px; overflow: hidden;
  border-radius: var(--r-sm); background: var(--surface-2);
  color: var(--text-soft);
}
.bg-mini img { width: 100%; height: 100%; object-fit: cover; }
.bg-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.bg-txt strong { font-size: 13px; line-height: 1.25; }
.bg-txt small { color: var(--text-soft); font-size: 11px; }
.bg-selo { margin-left: auto; color: var(--ok); }
.bg-selo .ico { width: 15px; height: 15px; }
.bg-vazio { padding: var(--s4); color: var(--text-soft); font-size: 12.5px; }

/* ---------------------------------------------- a ficha do destino */
.fd-corpo { display: flex; flex-direction: column; gap: var(--s4); }
.fd-capa {
  display: grid; place-items: center; overflow: hidden;
  /* 4:3 vale em toda largura. Limitar a ALTURA voltaria a alargar o quadro
     numa tela grande — que é exatamente o corte de 21:9 de antes, com outro
     nome. Limita-se a largura, e a proporção se mantém. */
  aspect-ratio: 4 / 3; width: 100%; max-width: 520px; position: relative;
  border-radius: var(--r-lg); background: var(--surface-2);
}
.fd-capa img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}
.fd-sem-capa { background: linear-gradient(140deg, var(--brand-soft), var(--surface-2)); }
.fd-marca .fd-ico { width: 64px; height: 64px; color: var(--brand); opacity: .5; }
/* A marca do tipo também espera atrás da foto, e só aparece se ela quebrar. */
.fd-capa img ~ .fd-marca { display: none; }
.fd-sem-capa img { display: none; }
.fd-sem-capa .fd-marca { display: block; }
.fd-cabeca { display: flex; flex-direction: column; gap: 4px; }
.fd-tipo {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-soft);
}
.fd-tipo .ico { width: 15px; height: 15px; }
.fd-nome { font-size: 26px; line-height: 1.15; margin: 0; }
.fd-onde { color: var(--text-soft); margin: 0; font-size: 14px; }
.fd-selos { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: 4px; }
.fd-selo {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 999px; font-size: 11.5px;
  border: 1px solid var(--border); color: var(--text-soft);
}
.fd-selo .ico { width: 13px; height: 13px; }
.fd-alerta { color: var(--warn); }
.fd-desc { margin: 0; line-height: 1.55; max-width: 70ch; }
.fd-acoes { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }
.fd-mapa {
  height: 300px; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--border); background: var(--surface-2);
}
.fd-fotos {
  display: grid; gap: var(--s2);
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}
.fd-fotos:empty { display: none; }

/* A chuva na escolha (`a-chuva-na-escolha.js`): o selo no cartão do
   montador e o aviso do destino escolhido, antes de montar. */
:root { --tp-chuva: #c0302f; --tp-talvez: #9a6b00; --tp-seco: #2c7a4b; }
:root[data-theme="dark"] { --tp-chuva: #ef6b6b; --tp-talvez: #e3b341; --tp-seco: #6fcf97; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --tp-chuva: #ef6b6b; --tp-talvez: #e3b341; --tp-seco: #6fcf97; }
}
.tp-selo { display: inline-flex; align-items: center; gap: 4px; margin-left: 6px; font-size: 11.5px; font-weight: 700; }
.tp-selo .ico, .tp-resumo .ico { width: 13px; height: 13px; }
.tp-chuva { color: var(--tp-chuva); }
.tp-talvez { color: var(--tp-talvez); }
.tp-seco { color: var(--tp-seco); }
.tp-resumo { display: inline-flex; align-items: center; gap: 4px; }
.md-chuva:empty { display: none; }
.tp-aviso {
  display: flex; gap: var(--s2); align-items: flex-start; padding: var(--s3); margin: var(--s2) 0;
  border: 1px solid currentColor; border-radius: var(--r-sm); background: var(--surface-2);
  font-size: 13.5px; line-height: 1.5;
}
.tp-aviso span { color: var(--text); }
.tp-aviso b { color: inherit; }
.tp-aviso.tp-chuva b { color: var(--tp-chuva); }
.tp-aviso.tp-talvez b { color: var(--tp-talvez); }
.tp-aviso.tp-seco b { color: var(--tp-seco); }
.tp-aviso .ico { width: 18px; height: 18px; flex: 0 0 auto; margin-top: 2px; }

/* O rodapé da ficha (`o-sinal-do-destino.js`): "não recomendar" e o aviso
   discreto. Discreto de propósito — é para quem achou o erro, não um
   convite a duvidar de cada cadastro. */
.fd-sinal {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3);
  padding-top: var(--s3); border-top: 1px solid var(--border);
}
.fd-sinal:empty { display: none; }
.sd-avisar { color: var(--text-soft); font-size: 13px; display: inline-flex; align-items: center; gap: 6px; }
.sd-avisar .ico { width: 14px; height: 14px; }
.sd-dialogo {
  width: min(480px, calc(100vw - 32px)); padding: 0; color: var(--text);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-lg);
}
.sd-dialogo::backdrop { background: rgba(0, 0, 0, .55); }
/* A vitrine de compartilhar (`a-vitrine-de-compartilhar.js`): a prévia do
   cartão no tamanho da tela, o formato e a legenda pronta. */
.vc-dialogo { width: min(560px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); }
.vc { display: flex; flex-direction: column; gap: var(--s3); padding: var(--s4); }
.vc-cab { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); }
.vc-cab h3 { margin: 0; font-size: 17px; }
.vc-fecha { background: none; border: 0; color: var(--text-soft); cursor: pointer; padding: var(--s1); }
.vc-formatos { display: flex; gap: var(--s2); }
.vc-previa { display: grid; place-items: center; min-height: 200px; background: var(--surface-2);
  border-radius: var(--r); padding: var(--s2); }
.vc-previa img { display: block; max-width: 100%; max-height: 52dvh; border-radius: var(--r); }
.vc textarea { width: 100%; box-sizing: border-box; font-size: 13px; resize: vertical; }
/* Os ajustes do cartão do roteiro (`os-ajustes-do-cartao.js`): layout,
   título, a foto principal e as de baixo. A foto escolhida ganha a borda
   do gesto; as outras ficam apagadas, mas à vista. */
.vc-ajustes { display: flex; flex-direction: column; gap: var(--s3); }
.vc-ajuste { display: flex; flex-direction: column; gap: var(--s1); }
.vc-ajuste input[type="text"] { width: 100%; box-sizing: border-box; }
.vc-fotos { display: flex; gap: var(--s2); overflow-x: auto; padding-bottom: 2px; }
.vc-foto { flex: 0 0 auto; width: 64px; height: 64px; padding: 0; border: 2px solid transparent;
  border-radius: var(--r); overflow: hidden; background: var(--surface-2); color: var(--text); cursor: pointer; opacity: .55; }
.vc-foto img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vc-foto[aria-pressed="true"] { border-color: var(--accent); opacity: 1; }
.sd-form { display: flex; flex-direction: column; gap: var(--s3); padding: var(--s4); margin: 0; }
.sd-form h3 { margin: 0; font-size: 17px; overflow-wrap: anywhere; }
.sd-tipos { border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s1); }
.sd-tipos legend { font-size: 12px; color: var(--text-soft); margin-bottom: var(--s1); }
.sd-tipo { display: flex; align-items: center; gap: var(--s2); font-size: 14px; cursor: pointer; }
.sd-rotulo { font-size: 12px; color: var(--text-soft); }
.sd-form textarea { width: 100%; box-sizing: border-box; }
.sd-botoes { display: flex; justify-content: flex-end; gap: var(--s2); flex-wrap: wrap; }
/* A pergunta do app no lugar do `confirm()` (`a-pergunta.js`). */
.pg-dialogo { width: min(420px, calc(100vw - 32px)); }
.pg-texto { margin: 0; font-size: 15px; line-height: 1.45; white-space: pre-line; overflow-wrap: anywhere; }

/* A aba Sinais do Catálogo (`os-sinais-da-curadoria.js`). */
.sn-cabeca { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3); }
.sn-cabeca h3 { margin: 0; }
.sn-filtro { font-size: 12px; color: var(--text-soft); display: flex; align-items: center; gap: var(--s2); }
.sn-lista, .sn-ranking { list-style: none; margin: var(--s3) 0; padding: 0; display: flex; flex-direction: column; gap: var(--s2); }
.sn-item {
  padding: var(--s3); border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2); display: flex; flex-direction: column; gap: var(--s2);
}
.sn-resolvido { opacity: .75; }
.sn-topo { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) var(--s2); }
.sn-topo b { overflow-wrap: anywhere; }
.sn-topo small, .sn-txt small { color: var(--text-soft); font-size: 12px; }
.sn-tipo {
  font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  padding: 2px 8px; border-radius: var(--r-pill); border: 1px solid var(--border-strong); color: var(--text-soft);
}
.sn-nao_existe { color: var(--danger); border-color: var(--danger); }
.sn-texto, .sn-resposta { margin: 0; font-size: 14px; line-height: 1.5; overflow-wrap: anywhere; }
.sn-resposta { color: var(--text-soft); font-size: 13px; }
.sn-acoes { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.sn-resp { flex: 1 1 200px; }
.sn-dispensados summary { cursor: pointer; font-weight: 600; display: flex; align-items: center; gap: var(--s2); }
.sn-ranking li { display: flex; align-items: center; gap: var(--s3); }
.sn-pessoas {
  flex: 0 0 auto; min-width: 32px; text-align: center; font-weight: 800; font-variant-numeric: tabular-nums;
  padding: 2px 8px; border-radius: var(--r-pill); background: var(--brand); color: var(--brand-text);
}
.sn-txt { display: flex; flex-direction: column; min-width: 0; }
.sn-txt b { overflow-wrap: anywhere; }
.fd-foto {
  display: block; overflow: hidden; aspect-ratio: 4 / 3; position: relative;
  border-radius: var(--r-sm); background: var(--surface-2);
}
.fd-foto img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}

@media (max-width: 720px) {
  .busca-global { flex: 1 1 120px; }
  .fd-nome { font-size: 21px; }
  .fd-capa { aspect-ratio: 4 / 3; }
}

.fd-voltar { align-self: flex-start; }

.vs-voltar { margin-bottom: var(--s3); }

/* ============================================ Destinos (acervo) ======
   A base na tela de quem viaja. Cartão largo e baixo, e não quadrado: o
   nome do lugar é o que se lê, e nome de cachoeira é comprido. */
.acv-filtros {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  margin-bottom: 14px;
}
.acv-filtros input[type="search"] { flex: 1 1 240px; min-width: 200px; }
.acv-filtros select {
  padding: 9px 12px; border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2);
  color: var(--text); font-size: 13px; max-width: 220px;
}
/* O FILTRO QUE LIGA E DESLIGA — em chip, e não em caixinha solta.

     "esses botoes estao muito feios, encontre uma forma mais elegante"

   A caixa nativa ao lado do texto era o único controle da tela sem o
   desenho do app: cinza do navegador, 13 px de quadrado, desalinhada do
   texto. O filtro vira o mesmo chip dos outros filtros, e ligado ele se
   enche de musgo com o traço de "conferido" — o estado se lê de longe,
   sem precisar achar o quadradinho.

   A caixa continua ALI, invisível e por baixo: é ela que o teclado, o
   leitor de tela e o `change` do JS enxergam. Esconder com `display:
   none` tiraria o controle do teclado. */
.alterna {
  position: relative;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-soft);
  font-size: 13px; font-weight: 550; line-height: 1.2;
  cursor: pointer; user-select: none;
  transition: background .15s, border-color .15s, color .15s;
}
.alterna > input[type="checkbox"] {
  position: absolute; inset: 0;
  width: 100%; height: 100%; margin: 0;
  opacity: 0; cursor: pointer;
}
.alterna-ico {
  display: inline-flex; width: 0; overflow: hidden;
  transition: width .15s var(--ease);
}
.alterna-ico .ico { width: 14px; height: 14px; flex: none; }
.alterna:hover { border-color: var(--brand); color: var(--text); }
.alterna:has(> input:checked) {
  background: var(--brand); border-color: var(--brand); color: var(--brand-text);
}
.alterna:has(> input:checked) .alterna-ico { width: 14px; }
.alterna:has(> input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .alterna, .alterna-ico { transition: none; }
}
/* Quem se toca é o RÓTULO, não a caixinha. A regra existia, escrita por
   LARGURA (`max-width: 620px`) e com 40px; aqui ela vale por PONTEIRO, que
   é quem manda — um tablet largo com toque tem o mesmo dedo. */
@media (hover: none) {
  label:has(> input[type="checkbox"]),
  label:has(> input[type="radio"]) {
    display: inline-flex; align-items: center; gap: 8px; min-height: 44px;
  }
}

.acv-grade {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.acv-card {
  display: flex; gap: 12px; align-items: stretch; text-align: left;
  padding: 0; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface); color: inherit; cursor: pointer;
}
.acv-card:hover { border-color: var(--brand); }

/* Os melhores (`os-melhores.js`): o cartão de Destinos com a posição na
   frente. Ouro, prata e bronze só no pódio; do quarto em diante, neutro. */
:root { --om-ouro: #c9a227; --om-prata: #a7b1ba; --om-bronze: #b07a4f; --om-num: #101a14; }
.om-filtros { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); margin-bottom: var(--s2); }
.om-filtros .dq-select { width: auto; min-width: 0; flex: 1 1 160px; max-width: 240px; }
.om-filtros .chips { margin: 0; }
.om-filtros .chip { white-space: nowrap; }
@media (max-width: 520px) { .om-filtros .dq-select { max-width: none; } }
.om-podio { margin-top: var(--s4); }
.om-cab { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); margin-bottom: var(--s3); }
.om-cab h3 { margin: 0; }
.om-cab .btn { margin-left: auto; }
.om-cab-lista .btn { margin-left: 0; }
.om-progresso { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-soft); }
.om-progresso .ico { width: 14px; height: 14px; }
.om-completo { color: var(--brand); font-weight: 700; }
.om-grade {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.om-grade > li { display: flex; }
.om-card { position: relative; width: 100%; }
.om-pos {
  position: absolute; top: 8px; left: 8px; z-index: 1; min-width: 28px; height: 28px; padding: 0 6px;
  display: grid; place-items: center; border-radius: 50%; box-sizing: border-box;
  font: 800 13px/1 var(--sans); font-variant-numeric: tabular-nums;
  background: var(--surface); color: var(--text); border: 1px solid var(--border-strong);
}
.om-ouro, .om-prata, .om-bronze { color: var(--om-num); border-color: transparent; }
.om-ouro { background: var(--om-ouro); }
.om-prata { background: var(--om-prata); }
.om-bronze { background: var(--om-bronze); }
.om-casa { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-soft); }
.om-casa .ico { width: 13px; height: 13px; }
.acv-foto {
  flex: none; width: 96px; margin: 0; position: relative;
  background: var(--surface-2); overflow: hidden;
}
.acv-foto img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.acv-foto.sem img { display: none; }
/* O desenho do tipo só onde NÃO há foto: sem `cover_url`, ou com o link
   quebrado (`onerror` põe `.sem`). O comentário antigo dizia "fica atrás e
   a foto cobre", mas a marca vem DEPOIS da imagem, com `position: absolute`
   — pintava por cima de toda foto:
       "mantenha essa marca dagua somente para locais sem fotos ou que o
        link para a foto quebrou" (10/10/2026)
   O tipo continua escrito na linha de baixo do nome. */
.acv-foto img ~ .acv-marca { display: none; }
.acv-foto.sem .acv-marca { display: flex; }
.acv-marca {
  position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center; color: var(--text-soft);
}
.acv-marca .ico { width: 26px; height: 26px; }

.acv-corpo {
  display: flex; flex-direction: column; gap: 3px;
  padding: 11px 12px 11px 0; min-width: 0;
}
.acv-nome { font-size: 15px; line-height: 1.25; }
.acv-onde, .acv-nota { font-size: 12.5px; color: var(--text-soft); }
.acv-nota { display: inline-flex; align-items: center; gap: 4px; }
.acv-selos { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 3px; }
.acv-selo {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; padding: 2px 8px; border-radius: 999px;
  background: var(--surface-2); color: var(--text-soft);
}
.acv-selo .ico { width: 13px; height: 13px; }
.acv-selo.joia { color: var(--brand); }
.acv-selo.alerta { color: var(--warn); }
.acv-rodape { display: flex; justify-content: center; margin-top: 18px; }

/* ---------------------------------------------------- nome da conta --
   O nome fica ao lado do botão que o troca: separados, viravam "um texto
   qualquer" e "um botão qualquer" — juntos, é uma linha só que se lê como
   uma frase. Em tela estreita quebram, porque o botão não pode espremer
   o nome de quem tem nome comprido. */
/* A linha só se separa do resumo de gostos que vem logo abaixo quando há
   bloco: sem isto, "Jonathan Willys" e "Você ama: praia…" leem-se como uma
   coisa só. A borda mora no bloco (que só existe logado), não na caixa —
   caixa vazia com borda deixa um risco solto na tela. */
.nome-bloco,
.veiculo-bloco,
.casa-bloco {
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
/* A cidade escolhida, confirmada abaixo do campo. Um campo de busca com
   texto dentro não diz se aquilo virou um PONTO no mapa ou se ficou só
   digitado — e é a coordenada que a vitrine usa. */
.casa-escolhida {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px; padding: 9px 12px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
  font-size: 14px; font-weight: 600;
}
.casa-escolhida .ico { width: 16px; height: 16px; color: var(--brand); }
.nome-linha {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 4px 0 2px;
}
.nome-atual {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
}

/* -------------------------------------------- quem está na viagem --
   O painel abre embaixo do cartão da viagem: a pergunta dura dez
   segundos e não merece uma tela nova. Nome de um lado, ação do outro,
   porque a linha é lida de relance à procura de um nome estranho. */
.quem-painel { margin: 10px 0 16px; }
/* Quem está, numa janela da viagem (16/10/2026): o avatar (ou as iniciais),
   a patente na cor dela, os números de Meus Lugares e os selos. */
.quem-dialogo { width: min(560px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); }
.quem-dialogo .quem-painel { margin: 0; padding: var(--s4); }
.quem-dialogo .quem-linha { align-items: flex-start; gap: var(--s2) var(--s3); flex-wrap: wrap; }
/* As ações (dar poderes, tirar) numa linha abaixo: ao lado, apertavam a
   coluna até o nome e a patente se sobreporem (medido a 375px). */
.quem-dialogo .quem-acoes { flex-basis: 100%; padding-left: 56px; }
.quem-dialogo .quem-papel { align-self: flex-start; }
.quem-avatar { position: relative; flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; overflow: hidden;
  display: grid; place-items: center; background: var(--brand-soft); color: var(--brand); font-weight: 800; font-size: 15px; }
.quem-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.quem-quem { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.quem-patente { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 700;
  color: var(--pat-txt, var(--brand)); }
.quem-patente .ico { width: 16px; height: 16px; }
.quem-patente small { font-weight: 500; color: var(--text-soft); }
.quem-numeros { font-size: 12px; color: var(--text-soft); }
.quem-selos { display: flex; flex-wrap: wrap; gap: 4px; }
.quem-selo { display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px; border-radius: var(--r);
  font-size: 11.5px; font-weight: 600; color: var(--text-soft); background: var(--surface-2); border: 1px solid var(--border); }
.quem-selo .ico { width: 12px; height: 12px; color: var(--pat-ouro); }
.quem-lista { display: flex; flex-direction: column; gap: 2px; }
.quem-linha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}
.quem-linha:last-child { border-bottom: 0; }

/* --------------------------------------------- o que cada um quer --
   O roteiro justo (`o-roteiro-justo.js`): abre embaixo do cartão, como o
   "quem está". A turma em cima — quem já marcou e se a escolha forte dela
   está no roteiro —, as opções embaixo. O marcador é um quadrado de 44px
   com o número da ordem: a ordem É a informação (1 = escolha forte). */
.rj-painel { margin: 10px 0 16px; display: flex; flex-direction: column; gap: var(--sp-2); }
.rj-painel h4 { display: inline-flex; align-items: center; gap: 8px; margin: 0; }
.rj-painel h4 .ico { width: 18px; height: 18px; color: var(--brand); }
.rj-turma, .rj-opcoes { list-style: none; margin: 0; padding: 0; }
.rj-pessoa {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px;
  padding: 8px 0; border-bottom: 1px solid var(--border);
  font-size: 14px; color: var(--text-soft); overflow-wrap: anywhere;
}
.rj-pessoa strong { color: var(--text); font-weight: 650; }
/* O estado no MESMO tamanho da escolha: menor, no meio da frase, a linha
   alternava grande-pequeno-grande quando quebrava (Simulador, 01/10/2026).
   As outras escolhas descem para uma linha própria, essa sim menor. */
.rj-estado { font-style: normal; color: var(--text-soft); }
.rj-depois { flex-basis: 100%; font-size: 12.5px; color: var(--text-soft); }
.rj-estado.rj-dentro { color: var(--ok); font-weight: 600; }
.rj-estado .ico { width: 14px; height: 14px; vertical-align: -2px; }
.rj-placar { margin: 0; font-size: 13.5px; color: var(--text); }
.rj-sub {
  margin: var(--sp-2) 0 0; font-size: 12px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft);
}
.rj-op {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 6px 0; border-bottom: 1px solid var(--border);
}
.rj-op:last-child { border-bottom: 0; }
.rj-marca {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0; cursor: pointer;
  border: 1px solid var(--border-strong); border-radius: var(--r);
  background: var(--surface); color: var(--text-soft);
  font: inherit; font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums;
}
.rj-marca .ico { width: 18px; height: 18px; }
.rj-marca[aria-pressed="true"] {
  background: var(--brand); border-color: var(--brand); color: var(--brand-text);
}
.rj-marca:focus-visible { outline: none; box-shadow: var(--ring); }
.rj-txt { display: flex; flex-direction: column; min-width: 0; }
.rj-txt strong { font-size: 14.5px; font-weight: 650; color: var(--text); overflow-wrap: anywhere; }
.rj-txt small { font-size: 12.5px; color: var(--text-soft); }
.rj-acoes { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-1); }

/* -------------------------------------- convite e poderes da viagem --
   O código fica em fonte de máquina e espaçado: ele é DITADO por telefone
   e digitado por outra pessoa — "0" e "O" juntos custam a viagem. */
.entrar-codigo-box { margin-bottom: 16px; max-width: 420px; }
.entrar-codigo-box input { flex: 1; text-transform: uppercase; }
.quem-cabeca {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.quem-codigo {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding: 10px 0 14px; margin-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.quem-code {
  display: block; font-family: var(--mono); font-size: 20px;
  letter-spacing: 2px; color: var(--text);
}
.quem-acoes { display: flex; gap: 6px; flex-wrap: wrap; }
.quem-papel {
  margin-left: 6px; padding: 1px 7px; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--text-soft); font-size: 12px;
}

/* Os quatro campos do carro cabem lado a lado em tela larga e empilham no
   telefone — é onde este cadastro costuma ser feito, na véspera. */
.veiculo-campos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px;
}

/* ------------------------------------------------ estado da base --
   Quatro números em cima, a fila embaixo. O primeiro passo é o único
   destacado: a tela está recomendando UM, e destacar todos seria não
   recomendar nenhum. */
.eb-numeros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-bottom: 22px;
}
.eb-quadro {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 14px 16px;
}
.eb-quadro strong { display: block; font-size: 26px; line-height: 1.1; }
.eb-quadro span { display: block; color: var(--text-soft); font-size: 13px; }
.eb-quadro small { display: block; color: var(--text-faint); font-size: 12px; }
.eb-titulo { margin-bottom: 2px; }
.eb-ordem { margin-bottom: 12px; }
.eb-fila { display: flex; flex-direction: column; gap: 10px; }
.eb-passo {
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 12px 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.eb-primeiro { border-color: var(--accent); background: var(--surface-2); }
.eb-passo-cabeca { display: flex; align-items: center; gap: 12px; }
.eb-quantos {
  font-size: 22px; font-weight: 700; min-width: 44px; text-align: right;
}
.eb-passo-txt strong { display: block; }
.eb-passo-txt small { color: var(--text-soft); }
.eb-passo-acoes { display: flex; gap: 8px; flex-wrap: wrap; }
.eb-amostra {
  flex-basis: 100%;
  border-top: 1px solid var(--border);
  margin-top: 10px; padding-top: 10px;
  display: flex; flex-direction: column; gap: 4px;
}
.eb-amostra small { color: var(--text-soft); }

/* ------------------------------------------- mala, carro e compras --
   Item de checklist é tocado com o carro carregando ao lado: alvo alto,
   texto grande, e o feito sai de cena sem sumir — quem confere quer ver
   o que já passou para não pegar duas vezes. */
.mala-viagem { margin-bottom: 14px; }
.mala-listas { display: flex; flex-direction: column; gap: 22px; }
.mala-bloco {
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 14px 16px;
}
.mala-cabeca {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
}
.mala-cabeca h3 { margin: 0; }
.mala-progresso { color: var(--text-soft); font-size: 13px; }
.mala-itens { margin-top: 10px; display: flex; flex-direction: column; }
.mala-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 2px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.mala-item:last-child { border-bottom: 0; }
.mala-item input { margin-top: 3px; width: 20px; height: 20px; flex: none; }
.mala-item small { display: block; color: var(--text-soft); font-size: 12px; }
.mala-porque { color: var(--text-faint); font-style: italic; }
.mala-feito strong { text-decoration: line-through; color: var(--text-faint); }

/* ------------------------------------------- cartão de fila de um ---
   Mesmo desenho da fila de fotos: um alvo por vez, o caminho para achar
   o dado e o campo para colar. A prévia tem peso visual de propósito —
   é ela que impede gravar o ponto errado, que é o defeito que esta tela
   existe para desfazer. */

/* Os controles herdavam a largura total do formulário e cada um caía numa
   linha, com a contagem sozinha numa terceira. Aqui eles têm a largura do
   que guardam: duas letras e um seletor curto. */

/* Largura do que ele guarda: um par de coordenadas, não a mesa inteira. */

/* O botão é uma ação, não uma faixa: cresce com o texto e para ali. E
   sublinhado é coisa de link no meio de um texto, não de botão. */

/* --------------------------------------------- a espera do mapa ---
   A marca respirando por cima do quadro, enquanto os pontos não chegam.
   O véu é translúcido de propósito: o mapa que já está desenhado continua
   à vista por trás, e o que a tela diz é "estou completando", não
   "recomeçamos do zero". */
.espera {
  position: absolute; inset: 0; z-index: 600;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 12px;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(1.5px);
  pointer-events: none;
}
.espera img { width: 58px; height: 58px; animation: respira 1.5s ease-in-out infinite; }
.espera-txt { font-size: 13px; color: var(--text-soft); }
@keyframes respira { 0%, 100% { opacity: 1; } 50% { opacity: .42; } }
@media (prefers-reduced-motion: reduce) {
  .espera img { animation-duration: 4s; }
}

/* A escolha de base na aba Locais do Catálogo. Fica discreta: é uma
   passagem, não um filtro que se usa toda hora — e some quando só há uma
   base para escolher. */
.dq-bases { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }

/* ------------------------------------------------ como visitar ---
   O painel só abre a pedido, e o que ele diz tem pesos diferentes: o que o
   lugar EXIGE decide se dá para ir hoje; o resto é leitura. Por isso a
   exigência tem moldura e o histórico não. */
.fd-visitar { margin-top: 16px; }
.cv { border: 1px solid var(--border); border-radius: 12px; padding: 16px 18px;
  display: flex; flex-direction: column; gap: 14px; }
.cv-carregando { color: var(--text-soft); font-size: 14px; padding: 14px 0;
  display: flex; align-items: center; gap: 8px; }
.cv-selo { display: flex; gap: 8px; align-items: flex-start; font-size: 13px;
  line-height: 1.45; border-radius: 9px; padding: 10px 12px; }
.cv-selo .ico { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.cv-selo.aviso { background: color-mix(in srgb, #e2662a 12%, transparent);
  color: var(--text); }
.cv-selo.ok { background: color-mix(in srgb, var(--brand) 14%, transparent);
  color: var(--text-soft); }
.cv-bloco h4 { font: 600 12px/1 system-ui; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-faint); margin: 0 0 5px; }
.cv-bloco p { margin: 0; line-height: 1.55; }
.cv-bloco ul { margin: 0; padding-left: 18px; line-height: 1.55; }
.cv-exige { border-left: 3px solid #e2662a; padding-left: 12px; }
.cv-incerto { color: var(--text-soft); font-size: 13.5px; }
.cv-acoes { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* O caminho do garimpo para a base, dentro do cadastro.
   Mesma moldura do bloco de fotos: são os dois "o que mais existe sobre
   este lugar", e molduras diferentes fariam parecer telas diferentes. */

/* O aviso de "já está lá" é o produto deste bloco: é ele que evita a meia
   hora arrumando o que não vai a lugar nenhum. Cor de atenção, não de erro
   — nada quebrou, só não vale a pena continuar. */

/* ============================================================
   Agrupamento: o parque e os lugares dentro dele
   ============================================================ */

/* Na ficha do destino. Fica logo abaixo do nome e acima da descrição
   porque é contexto de LUGAR, não ação: quem lê "Praia das Pombas"
   precisa saber que ela fica dentro de Itapuã antes de decidir qualquer
   coisa sobre ela. */
.fd-grupo {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2);
}
.fd-grupo:empty { display: none; }
.fd-grupo-rot {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--text-soft); font-size: 13px;
}
.fd-grupo-rot .ico { width: 14px; height: 14px; }
.fd-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px; font-size: 12.5px;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text); cursor: pointer;
}
.fd-chip:hover { border-color: var(--accent); color: var(--accent-txt); }
.fd-chip .ico { width: 13px; height: 13px; }

/* No cadastro. Mesma moldura dos outros blocos do formulário: são todos
   "o que mais existe sobre este lugar". */
.dq-dentro {
  margin-top: var(--s4); padding: var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.dq-dentro-topo {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
}
.dq-dentro-topo .ico { width: 15px; height: 15px; vertical-align: -2px; }
.dq-dentro-corpo { margin-top: var(--s3); }
.dq-dentro-linha {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
}
.dq-dentro-nota { margin: var(--s2) 0 0; }
.dq-dentro-chip {
  display: inline-block; padding: 2px 8px; margin: 2px 2px 0 0;
  border-radius: 999px; font-size: 12px;
  border: 1px solid var(--border); color: var(--text-soft);
}
.dq-dentro-q { width: 100%; max-width: 460px; }
.dq-dentro-achados {
  display: flex; flex-direction: column; gap: 2px; margin-top: var(--s2);
}
.dq-dentro-achados:empty { display: none; }
/* Opção de lista, não botão de ação: o traço fica no hover, senão dez
   resultados viram dez botões competindo com o Salvar. */
.dq-dentro-op {
  text-align: left; padding: 6px 9px; border-radius: var(--r-sm);
  border: 1px solid transparent; background: none; color: var(--text);
  cursor: pointer; font-size: 14px;
}
.dq-dentro-op:hover { border-color: var(--accent); background: var(--surface); }
.dq-dentro-op small { color: var(--text-soft); }

/* Na parada do roteiro: o que se faz dentro dela. Recuado sob o nome, com
   o mesmo tom das outras linhas de apoio da timeline — é explicação do
   tempo que a parada ocupa, não uma parada a mais. */
.stop-dentro {
  display: flex; align-items: baseline; gap: 5px;
  color: var(--text-soft); font-size: 12.5px; margin-top: 2px;
}
.stop-dentro .ico { width: 13px; height: 13px; flex: 0 0 auto; align-self: center; }

/* Na parada: a estrada de chão e a cachoeira no dia da visita. A palavra
   que decide leva a cor do nível; o porquê fica no tom das linhas de apoio.
   As cores são as de TEXTO (--danger é clareada no escuro para ser lida). */
.stop-condicao {
  display: flex; align-items: baseline; gap: 5px;
  color: var(--text-soft); font-size: 12.5px; margin-top: 3px;
}
.stop-condicao .ico { width: 13px; height: 13px; flex: 0 0 auto; align-self: center; }
.stop-condicao.cond-passa .ico, .stop-condicao.cond-passa b { color: var(--ok); }
.stop-condicao.cond-cuidado .ico, .stop-condicao.cond-cuidado b { color: var(--warn); }
.stop-condicao.cond-evite .ico, .stop-condicao.cond-evite b { color: var(--danger); }

/* Durante a viagem: o evento que cai nos dias, logo abaixo dos avisos.
   Mesma moldura do aviso, com a linha da marca no lugar da de atenção —
   é uma oportunidade, não um problema. */
.ev-viagem {
  border-left: 3px solid var(--brand);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 11px 14px; margin-bottom: 18px; font-size: 13px;
}
.ev-viagem > strong { display: flex; align-items: center; gap: 6px; }
.ev-viagem > strong .ico { width: 15px; height: 15px; }
.ev-viagem ul { margin: 6px 0 0; padding-left: 18px; }
.ev-viagem li + li { margin-top: 6px; }
.ev-linha { display: flex; flex-direction: column; }
/* O evento no dia, SEM horário: tracejado e apagado, porque ainda não ocupa
   tempo — só existe. O ponto da linha do tempo é oco pelo mesmo motivo. */
.stop.ev-no-dia { border: 1px dashed var(--border-strong); border-radius: var(--r);
  padding: var(--sp-2) var(--sp-3); margin-bottom: 18px; }
.stop.ev-no-dia::before { background: var(--surface); border-color: var(--brand); }
.stop.ev-no-dia h5 { display: flex; align-items: center; gap: 6px; }
.stop.ev-no-dia .btn { margin-top: var(--sp-2); }
/* A ficha do evento (`a-ficha-do-evento.js`). */
.evf-card { max-width: 560px; overflow: hidden; }
.evf-foto { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.evf-corpo p { margin: 0 0 var(--sp-2); }
.evf-quando, .evf-onde { display: flex; align-items: flex-start; gap: 6px; color: var(--text-soft); font-size: 14px; }
.evf-corpo h4 { margin: var(--sp-3) 0 var(--sp-1); font-size: 14px; }
.evf-prog { white-space: pre-line; font-size: 14px; }
.evd { margin-top: var(--sp-2); }
.evd summary { cursor: pointer; color: var(--text-soft); font-size: 13px; min-height: 32px; }
.evd .field { margin-top: var(--sp-2); }
.ev-linha small, .ev-viagem .ev-dica { color: var(--text-soft); font-size: 12px; }
.ev-viagem .ev-dica { display: block; margin-top: 8px; }
.ev-estimado span { color: var(--text-soft); }

/* Combustível: mesma moldura de "Durante a viagem", com a linha neutra —
   é conta, não alerta nem oportunidade de passeio. */
.cb-viagem {
  border-left: 3px solid var(--border-strong);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 11px 14px; margin-bottom: 18px; font-size: 13px;
  display: flex; flex-direction: column; gap: 4px;
}
.cb-viagem > strong { display: flex; align-items: center; gap: 6px; }
.cb-viagem > strong .ico { width: 15px; height: 15px; }
.cb-viagem p { margin: 0; }
.cb-viagem small { color: var(--text-soft); font-size: 12px; }

/* O buraco sem sinal, sob as paradas de hoje. */
.sn { margin-top: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-2); }
.sn-lista { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; font-size: 13.5px; }
.sn-lista li { display: flex; flex-direction: column; }
.sn-lista small, .sn-fonte { color: var(--text-soft); font-size: 12.5px; }

/* ----------------------------------------------- a estrada contada --
   Ao pé do sinal da estrada (`a-estrada-contada.js`): a lista do que vai
   ser falado, com o quilômetro em fonte de máquina — é a coluna que se lê
   de relance para saber quanto falta. */
.ec { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-3); }
/* Lista, botão e explicação um embaixo do outro: o `small` inline colava
   no lado do botão e quebrava em três linhas tortas (375px). */
#ec-saida { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); }
#ec-saida .ec-lista { align-self: stretch; }
.ec-resumo { margin: 0; font-size: 14px; color: var(--text); font-weight: 600; }
.ec-lista {
  list-style: none; margin: 0; padding: 0;
  max-height: 280px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--r);
}
.ec-lista li {
  display: grid; grid-template-columns: 58px 1fr; gap: var(--sp-2);
  padding: 7px 10px; border-bottom: 1px solid var(--border);
  font-size: 13.5px; line-height: 1.4; color: var(--text);
}
.ec-lista li:last-child { border-bottom: 0; }
.ec-km {
  font-family: var(--mono); font-size: 12.5px; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}
.ec-agora { margin: 0; }
.sn-ok { margin: 0; font-size: 13.5px; }

/* A melhor época, na ficha do cadastro. */
.mf { border: 1px solid var(--border); border-radius: var(--r); padding: var(--sp-3);
      margin: var(--sp-3) 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.mf legend { font-weight: 600; padding: 0 4px; }
.mf-meses { display: flex; flex-wrap: wrap; gap: 6px; }
.mf-mes { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
.mf-acoes { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }

/* A aba Eventos do Catálogo. */
.ev-acoes { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-3) 0; }
.ev-lista { display: flex; flex-direction: column; gap: var(--sp-3); }
.ev-cartao {
  border: 1px solid var(--border); border-radius: var(--r);
  padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-2);
}
.ev-cab { display: flex; flex-direction: column; }
.ev-cab small, .ev-sem { color: var(--text-soft); font-size: 12.5px; }
.ev-proposta {
  border-left: 3px solid var(--warn); padding-left: var(--sp-2);
  display: flex; flex-direction: column; gap: 4px; font-size: 13px;
}
.ev-proposta a { overflow-wrap: anywhere; }
.ev-botoes, .ev-datas { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: flex-end; }
.ev-datas .field { flex: 1 1 140px; margin: 0; }
.ev-previa { margin: 0 0 var(--sp-3); padding-left: 18px; font-size: 13px; }
.ev-busca { margin: 0 0 var(--sp-3); }
.ev-novo { margin-bottom: var(--sp-3); border-color: var(--border-strong); }
.ev-novo .field { margin: 0; }
.ev-uf { flex: 0 0 72px; }
.ev-meses { border: 0; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.ev-meses legend { font-size: 13px; margin-bottom: var(--sp-1); }
.ev-meses legend small, .ev-fonte { color: var(--text-soft); font-size: 12.5px; }
.ev-meses .chip { display: inline-flex; align-items: center; gap: 4px; }
.ev-inativo { border-style: dashed; }

/* Onde a gente se encontra, sob a lista do comboio. */
.pe { margin-top: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-2); }
.pe-lista { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: var(--sp-3); }
.pe-opcao { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; }
.pe-opcao small { color: var(--text-soft); font-size: 12.5px; }
.pe-opcao .btn { align-self: flex-start; margin-top: 4px; }

/* ============================================================
   Lugares restritos — guia, autorização, agendamento
   ============================================================ */

/* O selo. Cor de atenção, não de erro: nada está quebrado, mas há uma
   providência a tomar antes de sair de casa. */
.lr-selo {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 999px; font-size: 11.5px;
  border: 1px solid var(--warn); color: var(--warn);
}
.lr-selo .ico { width: 13px; height: 13px; flex: 0 0 auto; }

/* A caixa que interrompe. É o único aviso deste app que bloqueia, e por
   isso ela pede uma marca explícita: um "ok" sozinho vira reflexo. */
.lr-fundo {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(8, 14, 12, .72);
  display: flex; align-items: center; justify-content: center;
  padding: var(--s4);
}
.lr-modal {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--r);
  padding: var(--s4); max-width: 620px; width: 100%;
  max-height: 82vh; overflow-y: auto;
  box-shadow: 0 18px 48px rgba(0, 0, 0, .4);
}
.lr-modal h3 {
  display: flex; align-items: center; gap: var(--s2);
  margin: 0 0 var(--s2); font-size: 19px; line-height: 1.25;
}
.lr-modal h3 .ico { width: 20px; height: 20px; flex: 0 0 auto; color: var(--warn); }
.lr-intro { margin: 0 0 var(--s3); color: var(--text-soft); }
.lr-lista { margin: 0 0 var(--s3); padding-left: 18px; }
.lr-lista > li { margin-bottom: var(--s3); }
.lr-lista > li > small { color: var(--text-soft); margin-left: 6px; }
.lr-lista ul { margin: 4px 0 0; padding-left: 16px; }
.lr-lista ul li { font-size: 13.5px; color: var(--text-soft); margin-top: 3px; }
.lr-lista ul li b { color: var(--text); }
.lr-nota {
  margin: 6px 0 0; padding: 6px 10px; font-size: 13.5px;
  border-left: 3px solid var(--warn); background: var(--surface-2);
}
.lr-ciente {
  display: flex; align-items: flex-start; gap: var(--s2);
  padding: var(--s3); border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2);
  cursor: pointer;
}
.lr-acoes {
  display: flex; gap: var(--s3); justify-content: flex-end;
  flex-wrap: wrap; margin-top: var(--s3);
}

/* O editor, no cadastro. Mesma moldura dos outros blocos do formulário. */
.dq-restr {
  margin-top: var(--s4); padding: var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.dq-restr-topo {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
}
.dq-restr-topo .ico { width: 15px; height: 15px; vertical-align: -2px; }
.dq-restr-ops {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4);
  margin: var(--s3) 0;
}
.dq-restr-op { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.dq-restr-nota textarea { width: 100%; }

/* ============================================================
   O texto do destino, no cadastro
   ============================================================ */
.dq-texto {
  margin-top: var(--s4); padding: var(--s3);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2);
}
.dq-texto-topo {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
}
.dq-texto-topo .ico { width: 15px; height: 15px; vertical-align: -2px; }
.dq-texto-corpo { display: grid; gap: var(--s3); margin-top: var(--s3); }
.dq-texto-corpo textarea { width: 100%; }
.dq-texto-acoes {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
}
/* O botão de IA ao lado da descrição: fica ABAIXO do campo, e não dentro
   do rótulo, para não competir com o nome do campo na leitura. */
.dq-desc-ia {
  display: flex; align-items: center; gap: var(--s2);
  flex-wrap: wrap; margin-top: 4px;
}
.dq-desc-ia .btn { padding: 4px 10px; font-size: 13px; }

/* ============================================================
   As reticências do cartão de destino
   ============================================================ */
.md-card { position: relative; }
/* Canto superior direito, fora do caminho do nome e do botão de ação:
   é atalho, não a decisão principal da tela. */
/* Ele fica POR CIMA da foto do cartão, sempre. Sem fundo próprio, o traço
   cinza sumia na foto clara e desaparecia de vez na escura — botão que só
   se acha por tentativa é botão que ninguém usa. Medido: o desenho caía
   dentro do retângulo da imagem em todo cartão com capa. */
.md-menu-btn {
  position: absolute; top: 6px; right: 6px; z-index: 2;
  width: 28px; height: 28px; padding: 0; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(10, 18, 15, .55); backdrop-filter: blur(2px);
  color: #f2f5f3; cursor: pointer;
}
.md-menu-btn:hover, .md-menu-btn:focus-visible {
  background: rgba(10, 18, 15, .82); border-color: rgba(255, 255, 255, .45);
}
.md-menu-btn .ico { width: 16px; height: 16px; }
.md-menu {
  position: absolute; top: 36px; right: 6px; z-index: 5;
  min-width: 210px; padding: 4px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface); box-shadow: 0 10px 26px rgba(0, 0, 0, .28);
  display: flex; flex-direction: column;
}
.md-menu-op {
  display: flex; align-items: center; gap: var(--s2);
  padding: 8px 10px; border: 0; border-radius: var(--r-sm);
  background: none; color: var(--text); font: inherit; font-size: 13.5px;
  text-align: left; cursor: pointer;
}
.md-menu-op:hover:not(:disabled) { background: var(--surface-2); }
.md-menu-op:disabled { color: var(--text-soft); cursor: default; }
.md-menu-op .ico { width: 15px; height: 15px; flex: 0 0 auto; }

/* A busca da árvore do catálogo, no Diário. Fica ACIMA da árvore e não
   dentro dela: com quatro níveis, quem já sabe o nome não deve precisar
   descer nenhum. */
.vs-busca {
  display: flex; align-items: center; gap: var(--s3);
  flex-wrap: wrap; margin-bottom: var(--s3);
}
.vs-busca #vs-q { flex: 1 1 260px; }
/* Recuo por nível: sem ele, país e cidade parecem irmãos. */
.vs-grp-state > .vs-grp-body { padding-left: 10px; }
.vs-grp-region > .vs-grp-body { padding-left: 10px; }

/* NO TELEFONE (16/10/2026): "a parte de registrar locais [...] esta muito
   ruim no celular". Quatro níveis de caixa dentro de caixa comiam a largura
   e o nome do lugar virava UMA letra ("C", "P"); "fui em todos" quebrava em
   três linhas. Aqui os níveis viram um filete à esquerda, o nome vem
   inteiro (até duas linhas) e as ações descem para a linha de baixo. */
@media (max-width: 640px) {
  .vs-grp .vs-grp { border: 0; background: none; margin-bottom: 0; }
  .vs-grp .vs-grp-body, .vs-grp-cid > .vs-grp-body {
    padding: 2px 0 6px 8px; margin-left: 7px; border-left: 1px solid var(--border-strong); }
  .vs-grp-state > .vs-grp-body, .vs-grp-region > .vs-grp-body { padding-left: 8px; }
  .vs-grp-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; row-gap: 0;
    padding: 4px 2px; }
  .vs-grp-cid > .vs-grp-head { padding: 2px; }
  .vs-grp-nome { white-space: normal; overflow-wrap: anywhere; }
  .vs-grp-acoes { grid-column: 1 / -1; padding-left: 20px; gap: 18px; }
  .vs-hit { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; padding: 4px 4px 4px 8px; }
  .vs-hit .vs-nome { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical;
    -webkit-line-clamp: 2; line-height: 1.25; }
  .vs-acoes { gap: 4px; }
  .vs-busca #vs-q { flex-basis: 100%; }
  /* País e estado quase sempre são um só: não recuam, e o Brasil perde a
     caixa — a largura vai para o nome do lugar. */
  #vs-tree > .vs-grp { border: 0; background: none; }
  .vs-grp-country > .vs-grp-body, .vs-grp-state > .vs-grp-body { margin-left: 0; padding-left: 0; border-left: 0; }
  #visited-catalog.panel { padding: 14px 12px; }
  /* "Não conheço" o Brasil inteiro gastava uma linha por nível e quase
     nunca é o que se quer; segue na região e na cidade. */
  .vs-grp-country > .vs-grp-head > .vs-grp-acoes, .vs-grp-state > .vs-grp-head > .vs-grp-acoes { display: none; }
  .vs-fui { padding: 4px 10px; }
}

/* A porta para o que o catálogo não tem — na árvore e no pé de Destinos.
   Discreta: é um `.btn.ghost` sozinho numa linha, depois do que se procura,
   para que sugerir nunca venha antes de procurar. */
.vs-sugerir, .acv-sugerir {
  display: flex; justify-content: center; margin-top: var(--sp-3);
}
#vs-sugestao, #acv-sugestao { margin-top: var(--sp-3); }
.sd h4 { margin: 0 0 var(--sp-1); }
.sd-dica { margin: 0 0 var(--sp-3); }
.sd label small { color: var(--text-faint); font-weight: 400; }
.sd textarea { width: 100%; resize: vertical; }
.sd-fui { color: var(--text-soft); margin-bottom: var(--sp-3); }
.sd-acoes { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.sd-msg:empty { display: none; }
.sd-msg .btn { margin-top: var(--sp-2); }
@media (max-width: 520px) {
  .sd .grid-2 { grid-template-columns: 1fr; gap: 0; }
}

/* A fila das sugestões, no topo da Bancada. */
.sb { margin-bottom: var(--sp-4); }
.sb-cabeca { display: flex; align-items: center; gap: var(--sp-2); }
.sb-cabeca h3 { margin: 0; }
.sb-conta {
  font-size: 12px; font-weight: 700; padding: 1px 8px;
  border-radius: var(--r-pill); background: var(--brand); color: var(--brand-text);
}
.sb-lista { list-style: none; margin: var(--sp-2) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--sp-2); }
.sb-item {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3);
  justify-content: space-between; align-items: flex-start;
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--border);
  border-radius: var(--r-lg); background: var(--surface);
}
.sb-texto { display: flex; flex-direction: column; gap: 2px;
  flex: 1 1 260px; min-width: 0; }
.sb-nome { color: var(--text); overflow-wrap: anywhere; }
.sb-onde { color: var(--text-soft); font-size: 13px; }
.sb-quem { color: var(--text-faint); font-size: 12.5px; }
.sb-nota { margin: var(--sp-1) 0 0; font-size: 13px; color: var(--text-soft);
  white-space: pre-wrap; overflow-wrap: anywhere; }
.sb-link { display: inline-flex; align-items: center; gap: 4px;
  font-size: 13px; color: var(--brand); width: fit-content; }
.sb-link .ico { width: 14px; height: 14px; }
.sb-acoes { display: flex; flex-wrap: wrap; gap: var(--sp-1); }

/* ============================================================
   Bancada — uma fila só, com os enriquecimentos escolhidos
   ============================================================ */
.bc-seletor {
  display: flex; flex-wrap: wrap; gap: var(--s2);
  align-items: center; margin-bottom: var(--s3);
}
.bc-op {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface);
  font-size: 14px;
}
.bc-op:has(input:checked) { border-color: var(--accent); color: var(--accent-txt); }
/* Zerado continua clicável, mas não compete por atenção: é trabalho que
   não existe, e escondê-lo faria a contagem parecer errada. */
.bc-op.vazio { opacity: .45; }
.bc-op-n {
  font-variant-numeric: tabular-nums; font-size: 12.5px;
  color: var(--text-soft); background: var(--surface-2);
  border-radius: 999px; padding: 1px 7px;
}
.bc-resumo { margin-bottom: var(--s3); max-width: 80ch; }

/* O relatório do lote. Ele mostra NOMES, não um placar: os que a máquina
   não resolveu são a lista de trabalho que sobrou, e agrupá-los pelo motivo
   é o que revela quando dez cadastros falham pela MESMA causa — que quase
   sempre se conserta em outra tela, de uma vez. */
/* A marca de rascunho da descrição. Amarela como os outros avisos da
   Oficina: ela não diz que há erro — diz que ninguém leu ainda. */
.dq-desc-rascunho {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 8px 0 4px; padding: 8px 12px;
  border: 1px solid var(--warn); border-radius: var(--r-sm);
  font-size: 13px; color: var(--text-soft);
}
.dq-desc-rascunho span { flex: 1 1 auto; }

.bc-lote-saida:not(:empty) { margin-bottom: var(--s4); max-width: 80ch; }
.bc-lote-placar {
  font-size: 15px; padding: 10px 14px; margin-bottom: 8px;
  border-radius: var(--r-sm); background: var(--surface-2);
  border: 1px solid var(--border);
}
.bc-lote-placar b { color: var(--brand); font-variant-numeric: tabular-nums; }
.bc-lote-grupo { margin-bottom: 10px; }
.bc-lote-motivo {
  font-size: 12.5px; color: var(--warn); margin-bottom: 3px;
  padding-left: 10px; border-left: 2px solid var(--warn);
}
.bc-lote-item { font-size: 13px; padding: 1px 0 1px 12px; }
.bc-lote-item small { color: var(--text-faint); }

/* As rotinas de varredura, recolhidas.
   Elas são de usar de vez em quando; abertas, empurrariam a fila — que é o
   trabalho de todo dia — para baixo da dobra. */
.bc-rotinas {
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface-2); margin-bottom: var(--s4);
}
.bc-rotinas > summary {
  cursor: pointer; padding: 10px 14px; font-weight: 600; font-size: 14px;
  list-style: none;
}
.bc-rotinas > summary::-webkit-details-marker { display: none; }
/* A seta é desenhada, não escrita: caractere de forma é o primo do emoji —
   muda de desenho a cada fonte e some quando ela não o tem. */
.bc-rotinas > summary::before {
  content: ""; display: inline-block; margin-right: 8px;
  border: 5px solid transparent; border-left-color: var(--text-faint);
  transform: translateY(1px);
}
.bc-rotinas[open] > summary::before {
  border-left-color: transparent; border-top-color: var(--text-faint);
  transform: translateY(4px);
}
.bc-rotinas #bc-rotinas-corpo:not(:empty) { padding: 0 14px 14px; }

/* Os painéis de cima da Bancada, recolhidos (`index.html`, 1.237.1). O
   título do painel vai para a linha do grupo; o de dentro some, para não
   ler duas vezes a mesma coisa. */
.bc-grupo { border: 1px solid var(--border); border-radius: var(--r); background: var(--surface);
  margin-bottom: var(--sp-2); }
.bc-grupo > summary { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px var(--sp-2);
  min-height: 44px; padding: 10px 14px; cursor: pointer; list-style: none; }
.bc-grupo > summary::-webkit-details-marker { display: none; }
.bc-grupo > summary::before {
  content: ""; display: inline-block; align-self: center;
  border: 5px solid transparent; border-left-color: var(--text-faint);
  transform: translateX(2px);
}
.bc-grupo[open] > summary::before {
  border-left-color: transparent; border-top-color: var(--text-faint);
  transform: translateY(3px);
}
.bc-grupo > summary:hover .bc-grupo-titulo { text-decoration: underline; }
.bc-grupo > summary:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r); }
.bc-grupo-titulo { font-size: 15px; font-weight: 700; color: var(--text); }
.bc-grupo-dica { font-size: 13px; color: var(--text-soft); }
.bc-grupo[open] > summary { border-bottom: 1px solid var(--border); }
.bc-grupo > :not(summary) { margin: var(--sp-2); }
.bc-grupo .vr-painel > h3:first-child, .bc-grupo .cc-painel > h3:first-child,
.bc-grupo .fc-cabeca > h3 { display: none; }

.bc-corpo { display: grid; gap: var(--s4); align-items: start; }
@media (min-width: 900px) { .bc-corpo { grid-template-columns: 300px 1fr; } }

.bc-fila {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 74vh; overflow-y: auto; padding-right: 4px;
}
.bc-item {
  display: flex; flex-direction: column; gap: 3px; text-align: left;
  padding: 9px 11px; border-radius: var(--r-sm); cursor: pointer;
  border: 1px solid transparent; background: var(--surface-2);
  color: var(--text); font: inherit;
}
.bc-item:hover { border-color: var(--border); }
.bc-item.ativo { border-color: var(--accent); background: var(--surface); }
.bc-item-nome { font-weight: 600; font-size: 14.5px; }
.bc-item-onde { font-size: 12.5px; color: var(--text-soft); }
.bc-item-faltas { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.bc-falta {
  font-size: 11px; padding: 1px 7px; border-radius: 999px;
  border: 1px solid var(--warn); color: var(--warn);
}
.bc-falta.grande { font-size: 12.5px; padding: 2px 9px; }

.bc-ficha { min-width: 0; }
.bc-cabeca {
  display: flex; align-items: center; gap: var(--s3);
  flex-wrap: wrap; margin-bottom: var(--s3);
}
.bc-cabeca h3 { margin: 0; }
.bc-pede { display: flex; flex-wrap: wrap; gap: 5px; }
.bc-cabeca .bc-proximo { margin-left: auto; }
.bc-cabeca .ico.deitado { transform: rotate(-90deg); }

/* ============================================================
   Painel do dono
   ============================================================ */
.pn-grade {
  display: grid; gap: var(--s3); margin-bottom: var(--s4);
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.pn-cartao {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--s3); border: 1px solid var(--border);
  border-radius: var(--r-sm); background: var(--surface-2);
}
.pn-valor {
  font-size: 27px; font-weight: 700; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.pn-rotulo { font-size: 13px; color: var(--text-soft); }

.pn-barras { display: grid; gap: var(--s3); margin-bottom: var(--s4); }
@media (min-width: 700px) { .pn-barras { grid-template-columns: 1fr 1fr; } }
.pn-barra-topo {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 14px; margin-bottom: 5px;
}
.pn-barra-topo b { font-variant-numeric: tabular-nums; }
.pn-trilho {
  display: block; height: 8px; border-radius: 999px;
  background: var(--surface-2); overflow: hidden;
}
.pn-preenchido {
  display: block; height: 100%; border-radius: 999px;
  background: var(--accent);
}

.pn-tabela { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.pn-tabela td {
  padding: 8px 10px; border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.pn-brl { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pn-nota { color: var(--text-soft); font-size: 13px; }
.rolagem-x { overflow-x: auto; margin-bottom: var(--s4); }

/* As ressalvas não são rodapé: elas dizem quais números são estimativa, e
   um painel que esconde isso vira decisão tomada em cima de chute. */
.pn-ressalvas {
  border: 1px solid var(--border); border-left: 3px solid var(--warn);
  border-radius: var(--r-sm); background: var(--surface-2);
  padding: var(--s3); font-size: 13.5px; color: var(--text-soft);
}
.pn-ressalvas ul { margin: 6px 0 0; padding-left: 20px; }
.pn-ressalvas .ico { width: 15px; height: 15px; vertical-align: -2px; }

/* ------------------------------------------- fora do seu perfil ------
   O quiz de gosto é uma boa regra e um péssimo veto: quem disse "não
   gosto de balada" pode querer UMA balada temática numa cidade nova. O
   bloco nasce fechado e discreto de propósito — aberto, competiria com a
   lista que a pessoa veio ver; ausente, o filtro decidiria por ela. */
.md-fora {
  margin-top: 16px;
  border: 1px dashed var(--border);
  border-radius: var(--r-lg);
  background: var(--surface-2);
}
/* O marcador nativo do <details> fica no fio de cima da linha, e a linha
   aqui tem duas alturas (título e explicação). Ele vira um elemento de
   grade, alinhado ao título, para não flutuar no meio do parágrafo. */
.md-fora > summary {
  cursor: pointer;
  padding: 12px 14px;
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: 2px 8px;
  align-items: baseline;
}
.md-fora > summary::marker,
.md-fora > summary::-webkit-details-marker { content: ""; display: none; }
/* O símbolo do sprite aponta para BAIXO. Fechado ele tem de apontar para a
   direita (há algo ali dentro), aberto para baixo (está aberto) — medido na
   tela: sem a rotação de base ele apontava para a ESQUERDA, que não quer
   dizer nada em lista nenhuma. */
.md-fora > summary .md-fora-seta {
  grid-row: 1; grid-column: 1;
  color: var(--text-soft);
  transform: rotate(-90deg);
  transition: transform .15s var(--ease);
  display: inline-flex;
}
.md-fora[open] > summary .md-fora-seta { transform: rotate(0deg); }
.md-fora > summary strong { grid-column: 2; font-size: 14.5px; }
.md-fora > summary small {
  grid-column: 2; color: var(--text-soft); font-size: 12.5px;
}
.md-fora > summary:hover strong { color: var(--brand); }
.md-fora-corpo { padding: 0 14px 14px; }
@media (prefers-reduced-motion: reduce) {
  .md-fora > summary .md-fora-seta { transition: none; }
}

/* ---------------------------------------- o carro perguntado à IA ----
   Ninguém sabe o km/l do próprio carro de cabeça; sabe o modelo e o ano.
   O bloco fica ACIMA dos campos e separado por um fio: ele é o atalho
   para preenchê-los, não mais um campo a preencher. */
.veiculo-busca {
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.veiculo-busca .field { margin-bottom: 0; }
#veiculo-sugestao { margin-top: 8px; }
#veiculo-sugestao .alert { margin: 0; }

/* ------------------------------- a parada que a pessoa já conhece ----
   O roteiro pronto não sabia nada sobre quem o lê. Para quem mora na
   região, metade das paradas são lugares de domingo à tarde da infância.
   A parada visitada não some nem fica riscada — voltar a um lugar é
   motivo legítimo de viagem —, ela só fica MAIS CLARA que as outras, e
   ganha ao lado o botão que a troca por uma inédita ali perto. */
.rot-parada-vista { opacity: .72; }
/* Uma linha só: o selo diz o que é, o botão faz o que fazer com isso. */
.rot-parada-visto {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 8px; margin-top: 6px;
}
/* Com contorno, e não fantasma. Fantasma ao lado de um selo em pílula
   verde lê como legenda, não como ação — e esta é A ação da funcionalidade:
   sem ela, o selo só informa que a parada está gasta e não oferece saída. */
.rot-trocar { flex: 0 0 auto; font-size: 12px; padding: 3px 10px; }
.rot-trocar:hover { border-color: var(--brand); color: var(--brand); }
.rot-trocar .spinner { width: 11px; height: 11px; }

/* ==========================================================================
   O TELEFONE — regras que valem para a interface inteira em tela estreita

   Elas não existiam. O app foi desenhado no monitor e depois estreitado, e
   o que sobrou da redução foram três coisas que só aparecem com o dedo na
   tela:

   1. CAIXA DE MARCAR DE 13px. É o tamanho padrão do navegador, menor que a
      ponta de um dedo. "só joias escondidas", "esconder o que já visitei",
      "ocultar o que já visitei" — todas erravam o toque, e errar um filtro
      não dá erro: dá uma lista diferente sem explicação.
   2. CAMPO QUE PARA NO MEIO DA LINHA. Os seletores de filtro têm teto de
      220px para caber lado a lado no monitor. No telefone eles ficam com
      um vão morto à direita, e a tela lê como quebrada.
   3. ALVO PEQUENO DEMAIS. Rótulo de caixa de marcar é o alvo natural, e
      não o quadradinho — mas só se ele tiver altura de dedo.
   ========================================================================== */
/* O bloco abaixo é de LARGURA por herança, e o alvo do dedo é de
   PONTEIRO. Enquanto o resto daqui é mesmo sobre caber em tela estreita,
   a altura da caixa de marcar vale para qualquer tela tocável — por isso
   ela é repetida no bloco de `hover: none`, logo adiante. */
@media (max-width: 620px) {
  input[type="checkbox"], input[type="radio"] {
    width: 20px; height: 20px;
    flex: none;
    accent-color: var(--brand);
  }
  /* O alvo é a linha inteira. `:has` porque o rótulo é quem embrulha a
     caixa em todas as telas do app — não há uma classe comum. */
  label:has(> input[type="checkbox"]),
  label:has(> input[type="radio"]) {
    /* `inline-flex` junto: `min-height` não faz nada num rótulo `inline`,
       e a classe `.check` — a mais usada do app para isto — não tem
       display nenhum declarado. Sem esta linha o alvo continuava do
       tamanho do texto, e a regra abaixo era só enfeite. */
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /* 44, e não 40. O número estava a quatro pixels do alvo do dedo em
       TODA caixa de marcar do app — e esta regra vence por `:has` qualquer
       `min-height` que uma tela tente pôr no rótulo dela, então o erro
       viajava junto com o conserto. Medido a 375px: Destinos, Catálogo e
       a legenda do mapa, todas em 40. */
    min-height: 44px;
  }

  /* Teto de largura é regra de barra horizontal; aqui não há barra. */
  select, input[type="search"], input[type="text"], input[type="number"] {
    max-width: none;
  }
  /* O quadro cinza do "sem foto" ocupa 16:9 da largura do cartão. No
     monitor o cartão tem 264px e o quadro 148; no telefone o cartão tem a
     tela inteira e o quadro passa de 200px de cinza. Com 344 destinos sem
     foto, isso é meia tela de vazio por cartão — e o nome do lugar, que é
     o que se lê, some abaixo da dobra. Com foto, nada muda: a foto é o
     argumento e merece o espaço. */
  .md-card:has(.md-sem-foto) .md-foto {
    aspect-ratio: auto;
    min-height: 0;
    padding: 10px 0;
  }

  .acv-filtros select,
  .md-filtros .dq-select,
  .md-filtros input[type="search"] {
    flex: 1 1 100%;
    width: 100%;
    /* Aqui de novo, e não só na regra genérica acima: o teto mora numa
       regra de especificidade maior (`.acv-filtros select`), e sem
       repeti-lo o campo continuava parando nos 220px. */
    max-width: none;
  }
}

/* A barra do socorro.
   Fica no rodapé e FICA: um toast some em três segundos, e este é o único
   aviso do app que alguém pode estar esperando com o carro parado no
   acostamento. Acima de tudo, inclusive do portão de login (300), porque
   uma sessão que expirou no meio da estrada não pode engolir o pedido de
   ajuda de quem já está na tela. */
.socorro-barra {
  position: fixed; z-index: 400;
  left: 12px; right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 14px 16px;
  border-radius: var(--r-lg);
  /* O vermelho é escrito aqui, e não `var(--danger)`.
     `--danger` é cor de TEXTO, e no tema escuro ela é clareada para se ler
     sobre fundo escuro (#ef6b6b). Usada como FUNDO, essa mesma clareada dá
     3,0:1 com o branco por cima — medido na produção, no aviso mais
     importante do app. Um valor só nos dois temas: 4,68:1. */
  background: #d43b3b; color: #fff;
  box-shadow: var(--shadow);
}
.socorro-txt { flex: 1 1 200px; min-width: 0; line-height: 1.4; }
.socorro-txt strong { display: block; font-size: 15px; font-weight: 700; }
/* O recado é o que transforma "socorro" em ação — e ele pode ser longo. */
.socorro-txt span { display: block; font-size: 13.5px; opacity: .95;
                    overflow-wrap: anywhere; }
.socorro-ir {
  flex: none; border: 1px solid rgba(255, 255, 255, .55);
  background: rgba(255, 255, 255, .14); color: #fff;
  font: inherit; font-weight: 600; font-size: 13.5px;
  padding: 10px 14px; border-radius: var(--r-sm); cursor: pointer;
}
.socorro-ir:hover { background: rgba(255, 255, 255, .24); }
.cmb-aviso-nao { display: block; color: var(--text-faint); line-height: 1.4; }

/* Item de menu que é LINK, e não rota interna: Blog e Criadores são
   páginas próprias, servidas fora do `index.html`. Sem isto o item nasce
   sublinhado e azul no meio de seis irmãos que não são. */
a.nav-item { text-decoration: none; color: inherit; }

/* ============================================================
   A TELA QUE RECEBE QUEM CHEGA

   Três coisas disputavam a primeira olhada — a vitrine de roteiros, o
   campo de frase e um formulário de nove decisões — e nenhuma ganhava.
   Aqui a ordem fica escrita no tamanho: a vitrine propõe, a frase
   pergunta em uma linha, o formulário espera embaixo para quem quiser
   ele.
   ============================================================ */

/* ---------------------------------------------- a busca abre a tela */
/* Uma pergunta, um campo, e exemplos de como falar com ele. Nada de
   cartão, nada de moldura: a moldura seria mais uma coisa competindo com
   o campo, que é a única coisa desta parte da tela. */
.busca-primeira {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: clamp(28px, 6vw, 64px) 0 clamp(24px, 4vw, 40px);
}
.busca-titulo {
  margin: 0;
  font-size: clamp(27px, 4.4vw, 40px);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.08;
}
.busca-linha-fina {
  margin: 10px 0 0;
  max-width: 46ch;
  font-size: 15.5px;
  color: var(--text-faint);
  line-height: 1.5;
}
.frase-caixa {
  width: 100%;
  max-width: 720px;
  margin-top: clamp(20px, 3vw, 30px);
  text-align: left;
}
/* O convite do quiz: uma linha de estrutura, na largura da frase, sem
   terracota — a ação desta tela é a frase. Texto e ações quebram juntos
   no telefone, sem apertar o botão numa coluna. */
.convite-quiz {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3);
  max-width: 720px; margin: 0 auto var(--sp-4);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border); border-radius: var(--r);
}
.convite-quiz-ico { display: inline-flex; color: var(--brand); }
.convite-quiz-ico .ico { width: 20px; height: 20px; }
.convite-quiz-texto { flex: 1 1 260px; margin: 0; font-size: 14px; color: var(--text-soft); }
.convite-quiz-acoes { display: inline-flex; align-items: center; gap: var(--sp-3); }
/* O rótulo do campo some da vista e fica para quem lê com leitor de tela:
   o título da seção logo acima já diz o que se pede, e repetir a pergunta
   duas vezes em dois tamanhos é ruído. */
.frase-rotulo {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap;
}
/* A linha da busca é UMA peça: campo e botão dentro da mesma moldura, sem
   um vão entre eles. Dois controles soltos lado a lado leem como dois
   controles; juntos, leem como uma busca. */
.frase-linha {
  display: flex;
  /* `stretch` cria um laço com o campo que cresce sozinho: a linha estica
     o `textarea` até a altura dela, e `scrollHeight` — que é como se mede
     de quanto o texto precisa — passa a devolver a altura ESTICADA. O
     campo crescia uma linha e não voltava mais, vazio ou cheio.
     Com `flex-start` quem define a altura é o texto, e a linha segue. */
  align-items: flex-start;
  gap: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: border-color .14s var(--ease), box-shadow .14s var(--ease);
}
.frase-linha:focus-within {
  border-color: var(--brand);
  box-shadow: var(--shadow);
}
/* O campo cresce porque a frase é longa por natureza — "sair de Bagé
   sábado, bate e volta, com as crianças, cachoeira até 150 km" tem 62
   caracteres, e num campo de 15px eles não cabem sem cortar. */
#frase-viagem {
  flex: 1 1 auto; min-width: 0;
  border: 0; border-radius: 0; background: none;
  font-size: 16.5px; padding: 15px 16px;
  /* Cresce com a frase, em vez de rolar por dentro. O `resize` sai porque
     a alça de arrastar do canto é um controle a mais numa tela que já tem
     uma pergunta; quem manda na altura é o texto. O teto de 7 linhas
     existe para o botão "Montar" não sair da vista. */
  font-family: inherit; line-height: 1.4;
  resize: none; overflow-y: auto; max-height: 11.2em;
  /* Nunca menos que uma linha inteira: a medida feita fora da vista dava 0. */
  min-height: calc(1.4em + 30px);
}
#frase-viagem:focus { outline: none; box-shadow: none; }
#frase-aplicar {
  flex: none;
  border-radius: 0;
  padding: 0 22px;
  font-size: 15px;
  /* A altura de UMA linha do campo (15px de recuo em cima e embaixo mais
     uma linha de 23,1px). É o piso: com a frase em uma linha, campo e
     botão começam iguais. */
  min-height: 53px;
  /* E o botão ACOMPANHA o campo quando a frase cresce.
     Relatado assim: *"fica esquisito quando o texto quebra pra duas
     linhas"*. Medido em 375px, com a frase em três linhas: campo de 99px
     ao lado de um botão de 53px, e 46px de superfície morta embaixo dele,
     dentro da mesma moldura — um retângulo vazio que não é campo nem
     botão. Com sete linhas (o teto) eram 132px de vazio.
     `align-self` no BOTÃO, e nunca `align-items: stretch` na linha: o
     `stretch` na linha pega o `textarea` junto, e aí `scrollHeight` passa
     a medir a altura esticada — o campo cresce uma linha e não volta
     mais, que é o laço descrito ali em cima. */
  align-self: stretch;
}

/* --------------------------------------------- falar em vez de digitar */
/* O microfone mora DENTRO da moldura, entre o campo e o "Montar".
   Sem contorno e sem preenchimento: quem tem contorno aqui é a moldura, e
   um segundo botão desenhado ao lado do terracota disputaria a decisão
   que só o "Montar" toma. É ícone de busca, não botão de ação.

   `align-self: stretch` pelo mesmo motivo do "Montar": sem ele sobra
   superfície morta embaixo quando a frase passa de uma linha. */
.frase-voz {
  flex: none;
  align-self: stretch;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--text-faint);
  cursor: pointer;
  transition: color .12s var(--ease);
}
/* 18px: o mesmo corpo da lupa da barra de busca. Menor que isso o berço
   do microfone vira um traço só. */
.frase-voz svg { width: 18px; height: 18px; flex: none; }
.frase-voz:hover:not(:disabled),
.frase-voz:focus-visible { color: var(--brand); }
.frase-voz:disabled { opacity: .5; cursor: default; }
/* Gravando: a única hora em que ele puxa a cor da ação — sem rótulo, é a
   cor e o pulso que dizem que o microfone está aberto. */
.frase-voz.gravando { color: var(--accent-txt); }
.frase-voz.gravando svg { animation: voz-pulso 1.1s var(--ease) infinite; }
@keyframes voz-pulso { 50% { opacity: .3; } }
/* O que está acontecendo com o áudio. Fora da moldura, porque cresce com
   o texto e lá dentro empurraria o campo. */
.frase-voz-estado:empty { display: none; }
.frase-voz-estado {
  margin-top: var(--sp-2); font-size: 12.5px; color: var(--text-soft);
}
/* `--danger` é cor de TEXTO nesta folha (clareada no escuro). Aqui ela
   está no lugar dela; de fundo, atrás de branco, daria 3,0:1. */
.frase-voz-estado.ruim { color: var(--danger); }

/* Os exemplos. Quietos de propósito: são gramática, não convite —
   terracota aqui competiria com o botão que de fato monta a viagem. */
.frase-atalhos {
  display: flex; flex-wrap: wrap; gap: 7px;
  justify-content: center;
  margin-top: var(--sp-3);
}
.frase-atalho {
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-soft);
  font: inherit; font-size: 12.5px; font-weight: 550;
  padding: 7px 13px;
  cursor: pointer;
  transition: border-color .12s var(--ease), color .12s var(--ease);
}
.frase-atalho:hover,
.frase-atalho:focus-visible {
  border-color: var(--brand);
  background: var(--brand-soft);
  color: var(--text);
}

/* --------------------------------------- o formulário, recolhido */
/* Ele deixou de ser a entrada e virou a alternativa. Fica quieto: uma
   linha com uma pergunta, sem moldura de cartão e sem cor de gesto — quem
   vem por aqui é quem já sabe o que quer, e essa pessoa acha. */
/* A SEGUNDA PORTA, e ela precisa parecer uma.
   Era uma faixa sem moldura no fim da página, com a explicação dentro do
   próprio botão e cortada por reticências. Duas coisas erradas ao mesmo
   tempo: a explicação dentro do controle — o que esta folha chama de
   cartão apertado — e um traço de rodapé no lugar de uma porta.
   Agora tem a mesma forma das DUAS PORTAS logo acima: pergunta em
   versalete, controle emoldurado, explicação FORA dele. Nada de terracota:
   o gesto principal desta tela é o "Montar" da busca, e dois terracotas
   na mesma tela é nenhum. */
.a-mao { margin: var(--sp-4) 0 var(--sp-5); }
.a-mao-pergunta {
  margin: 0 0 var(--sp-2);
  font-size: 12px; font-weight: 650;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-faint);
}
.a-mao-botao {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 13px var(--sp-3);
  border: 1px solid var(--border);
  /* A moldura de 1px em `--border-strong` dava 1,99 contra o fundo da
     página — abaixo dos 3:1 que um contorno de controle pede, e o
     `--surface` por dentro quase não se separa do `--bg`. Quem marca a
     porta é o filete de musgo, que é como esta folha já marca bloco com
     dono (`.pat`). Musgo e não terracota: o gesto desta
     tela é o "Montar" da busca. */
  border-left: 3px solid var(--brand);
  border-radius: var(--r);
  background: var(--surface); font: inherit; text-align: left;
  color: var(--text);
  cursor: pointer;
  transition: border-color .12s var(--ease), background .12s var(--ease);
}
.a-mao-botao:hover { border-color: var(--brand); background: var(--surface-2); }
.a-mao-botao:hover { border-left-color: var(--brand-hover); }
.a-mao-ico { flex: none; display: inline-flex; color: var(--brand); }
.a-mao-ico .ico { width: 19px; height: 19px; }
.a-mao-titulo { font-weight: 650; font-size: 15.5px; flex: 1 1 auto; }
.a-mao-dica {
  margin: 6px 0 0;
  font-size: 13px; color: var(--text-soft);
}
.a-mao-chevron { flex: none; color: var(--text-faint); display: inline-flex; }
.a-mao-chevron .ico {
  width: 17px; height: 17px; transition: transform .16s var(--ease);
}
.a-mao.aberto .a-mao-chevron .ico { transform: rotate(180deg); }
.a-mao-corpo { padding-top: var(--sp-2); }

/* ---------------------------------------- o caminho curto da frase */
/* Depois da frase entendida: montar com o que foi dito. Fica aqui, colado
   na resposta, porque antes a tela rolava sozinha 900px até o formulário
   e deixava a resposta para trás.

   Eram DUAS portas — esta e "escolher os destinos um a um". A segunda
   virou porta fixa da tela, logo acima das propostas, e repetida aqui
   punha a mesma porta duas vezes na mesma rolagem. Ficou uma ação, e ela
   é a terracota da tela. */
.duas-portas {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
}

.dp-expressa { width: 100%; justify-content: center; }
/* A dica fica FORA do botão: rótulo e explicação dentro do mesmo controle
   viram cartão apertado, e o alvo do dedo deixa de ser óbvio. */
.dp-expressa-dica {
  margin: 6px 0 0;
  font-size: 13px; color: var(--text-soft);
  overflow-wrap: anywhere;
}
.dp-expressa-dica strong { color: var(--text); font-weight: 650; }
.dp-sem-pronto {
  margin: 0 0 var(--sp-2);
  max-width: 56ch;
  font-size: 13.5px; line-height: 1.5; color: var(--text-soft);
}

/* ----------------------------------- perto de você nas próximas semanas */
/* A faixa de eventos (`os-eventos-perto.js`), logo depois dos roteiros
   prontos. Fundo próprio: o miolo da tela de entrada é vidro sobre a parede
   de fotos. Discreta desde 1.236.0 — era uma lista de oito linhas de 52px
   que empurrava a tela; virou uma fila de cartões pequenos que rola de
   lado, com as setas e o desbotado da vitrine (`faixa-rolante.js`). */
.evp {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3) var(--sp-4) var(--sp-2);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.evp-cabeca { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3); }
.evp-cabeca h2 { margin: 0; font-size: 15px; font-weight: 700; color: var(--text); text-wrap: balance; }
.evp-cabeca p { margin: 2px 0 0; font-size: 12.5px; color: var(--text-soft); }
.evp-cal { flex: none; display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; }
.evp-cal .ico { width: 16px; height: 16px; }
/* No telefone a contagem empurrava a faixa para três linhas de cabeçalho;
   o número de cartões já se vê rolando. */
@media (max-width: 620px) { .evp-cabeca p { display: none; } }
.evp-trilho {
  list-style: none; margin: 0 calc(-1 * var(--sp-4)); padding: 2px var(--sp-4) var(--sp-2);
  display: flex; gap: var(--sp-2); overflow-x: auto;
  scroll-snap-type: x proximity; scroll-padding-inline: var(--sp-4);
  scrollbar-width: none;
}
.evp-trilho::-webkit-scrollbar { display: none; }
.evp-trilho li { flex: 0 0 auto; width: 236px; scroll-snap-align: start; }
.evp-palco .rot-seta-btn { top: 50%; width: 36px; height: 36px; }
.evp-item {
  display: flex; align-items: flex-start; gap: var(--sp-2); width: 100%; height: 100%;
  min-height: 56px; padding: 8px; text-align: left;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r);
  font: inherit; color: var(--text);
}
button.evp-item { cursor: pointer; }
button.evp-item:hover { border-color: var(--border-strong); }
button.evp-item:hover strong { text-decoration: underline; }
button.evp-item:focus-visible { outline: none; box-shadow: var(--ring); }
.evp-data {
  /* 46 cabe "COSTUMA" no corpo de 9px; a 11px vazava do bloco no WebKit. */
  flex: none; width: 46px; display: flex; flex-direction: column; align-items: center;
  padding: 3px 0; border-radius: var(--r);
  background: var(--brand); color: var(--brand-text); line-height: 1.1;
}
.evp-data b { font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; }
.evp-data small { font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
  /* Nomeada, e não herdada: a regra geral de `small` deixava o mês em
     --text-soft sobre o musgo, 1,3:1. */
  color: var(--brand-text); }
.evp-costume { background: var(--bg-alt); color: var(--text-soft); }
.evp-costume small { font-size: 9px; letter-spacing: .02em; color: var(--text-soft); }
.evp-costume b { font-size: 13px; text-transform: uppercase; }
.evp-txt { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.evp-txt strong, .evp-txt small {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.evp-txt strong { font-size: 13.5px; font-weight: 650; line-height: 1.25; }
.evp-txt small { font-size: 11.5px; color: var(--text-soft); line-height: 1.3; }

/* ------------------------------------------------------- o calendário */
/* `o-calendario.js`. Forma separa as duas coisas, e não só cor: a viagem é
   uma FAIXA cheia debaixo dos dias, o evento é um PONTO — oco quando passa
   do alcance da casa. Os nomes só cabem no computador; no telefone ficam
   os pontos, e a lista do dia diz o resto. */
.cal-card { max-width: 760px; }
.cal-mes { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  padding: 0 22px; }
.cal-titulo { font-size: 17px; font-weight: 800; color: var(--text); }
.cal-passo { display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r);
  border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; }
.cal-passo:hover { background: var(--surface-2); }
.cal-passo .ico { width: 18px; height: 18px; }
.cal-passo.depois .ico { transform: scaleX(-1); }
.cal-legenda { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); margin: var(--sp-2) 0 var(--sp-2);
  padding: 0 22px; font-size: 12px; color: var(--text-soft); }
.cal-legenda span { display: inline-flex; align-items: center; gap: 6px; }
.cal-corpo { padding-bottom: var(--sp-4); }
.cal-semana, .cal-grade { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-semana span { padding: 4px 0; text-align: center; font-size: 11px; font-weight: 700;
  letter-spacing: .06em; color: var(--text-faint); }
.cal-grade { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.cal-grade li { min-width: 0; border-bottom: 1px solid var(--border); }
.cal-dia {
  position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 2px;
  width: 100%; min-height: 84px; padding: 4px 4px 10px; text-align: left;
  background: none; border: 0; border-radius: 0; font: inherit; color: var(--text); cursor: pointer;
}
.cal-dia:hover { background: var(--surface-2); }
.cal-dia:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--brand); }
.cal-n { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 22px;
  width: 22px; text-align: center; border-radius: var(--r); }
.cal-dia.hoje .cal-n { background: var(--brand); color: var(--brand-text); }
.cal-dia.escolhido { background: var(--brand-soft); }
.cal-dia.escolhido .cal-n { box-shadow: 0 0 0 1.5px var(--brand); }
.cal-nome { display: block; font-size: 11px; line-height: 1.25; color: var(--text-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-pontos { display: flex; align-items: center; gap: 3px; min-height: 8px; }
.cal-pontos b { font-size: 10px; line-height: 1; color: var(--text-soft); }
.cal-ponto { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: var(--r-pill);
  background: var(--brand); border: 1.5px solid var(--brand); box-sizing: border-box; }
.cal-ponto.longe { background: transparent; }
.cal-tira { display: inline-block; flex: none; width: 16px; height: 8px; border-radius: 2px; background: var(--brand); }
.cal-faixa { position: absolute; left: 0; right: 0; bottom: 3px; height: 16px; overflow: hidden;
  background: var(--brand); }
.cal-dia.vi-ini .cal-faixa { left: 4px; border-top-left-radius: var(--r); border-bottom-left-radius: var(--r); }
.cal-dia.vi-fim .cal-faixa { right: 4px; border-top-right-radius: var(--r); border-bottom-right-radius: var(--r); }
.cal-faixa-nome { display: block; padding: 0 5px; font-size: 10.5px; line-height: 16px; font-weight: 700;
  color: var(--brand-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-dia.com-viagem .cal-pontos { margin-bottom: 18px; }
.cal-listas { display: flex; flex-direction: column; gap: var(--sp-1); margin-top: var(--sp-3); }
.cal-h { margin: var(--sp-2) 0 0; font-size: 14px; font-weight: 700; color: var(--text); }
.cal-nada { margin: var(--sp-2) 0 0; font-size: 13.5px; color: var(--text-soft); }
.cal-lista { list-style: none; margin: 0; padding: 0; }
.cal-lista li + li { border-top: 1px solid var(--border); }
.cal-item { display: flex; align-items: center; gap: var(--sp-2); width: 100%; min-height: 48px;
  padding: 6px 2px; text-align: left; background: none; border: 0; font: inherit; color: var(--text); cursor: pointer; }
.cal-item:hover strong { text-decoration: underline; }
.cal-item:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r); }
.cal-item > span { display: flex; flex-direction: column; min-width: 0; }
.cal-item strong { font-size: 14px; font-weight: 650; overflow-wrap: anywhere; }
.cal-item small { font-size: 12px; color: var(--text-soft); overflow-wrap: anywhere; }
@media (max-width: 620px) {
  .modal.cal { padding: 8px; }
  .cal-mes, .cal-legenda { padding: 0 12px; }
  .cal .modal-head { padding: 14px 12px 8px; }
  .cal-corpo.modal-body { padding: 0 8px var(--sp-4); }
  .cal-dia { min-height: 52px; align-items: center; padding: 4px 0 10px; }
  .cal-nome, .cal-faixa-nome { display: none; }
  .cal-faixa { height: 6px; }
  .cal-dia.com-viagem .cal-pontos { margin-bottom: 0; }
  .cal-listas { padding: 0 4px; }
}

/* ------------------------------------------------ o álbum de figurinhas */
/* `o-album-de-figurinhas.js`, em Meus Lugares. Recolhido numa linha, como o
   acervo logo acima. A figurinha que falta é um espaço tracejado com o
   número e o nome — o convite; a colada ganha a foto. A brilhante (peso
   90+) leva o ouro da patente mais alta: é desenho, 3:1 basta. */
/* O LIVRO DO ÁLBUM (`o-livro-do-album.js`): capa de couro musgo com o
   título em dourado, que gira sobre a lombada ao abrir; papel com a sombra
   da lombada; a folha solta que vira. O papel é token por tema — a tinta é
   `--text`, então ele claro no claro e escuro no escuro. */
:root { --lv-papel: #f4eee0; --lv-papel-luz: #fdfaf2; --lv-lombada: rgba(70, 52, 22, .26); --lv-capa: #23402f;
  --lv-capa-2: #15271d; --lv-dourado: #e3c25a; --lv-capa-texto: #f4efe2; }
:root[data-theme="dark"] { --lv-papel: #141c17; --lv-papel-luz: #1f2b23; --lv-lombada: rgba(0, 0, 0, .6); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --lv-papel: #141c17; --lv-papel-luz: #1f2b23; --lv-lombada: rgba(0, 0, 0, .6); }
}
.lv { display: grid; gap: var(--sp-2); padding-top: var(--sp-2); overflow: hidden; }
.lv-palco { perspective: 2400px; outline: none; padding: 4px 0 8px; }
.lv-palco:focus-visible { box-shadow: var(--ring); border-radius: var(--r); }
.lv-livro { position: relative; display: grid; grid-template-columns: 1fr 1fr; width: min(100%, 980px);
  margin: 0 auto; aspect-ratio: 3 / 2; transform-style: preserve-3d; transition: transform .9s var(--ease); }
.lv:not(.lv-uma):not(.aberto) .lv-livro { transform: translateX(-25%); }
.lv-uma .lv-livro { grid-template-columns: 1fr; aspect-ratio: auto; min-height: 540px; }
.lv-pagina, .lv-face { position: relative; overflow: hidden; color: var(--text); padding: 18px 20px 30px;
  box-sizing: border-box; background-color: var(--lv-papel); }
/* O papel: a sombra da lombada por cima de uma luz no meio da página — o
   cinza chapado de antes era "meio sem graça" (16/10/2026). */
.lv-esq, .lv-verso, .volta .lv-frente { border-radius: var(--r-lg) 0 0 var(--r-lg);
  background-image: linear-gradient(to left, var(--lv-lombada), transparent 9%),
    radial-gradient(ellipse at 55% 40%, var(--lv-papel-luz), transparent 72%); box-shadow: var(--shadow); }
.lv-dir, .vai .lv-frente, .volta .lv-verso { border-radius: 0 var(--r-lg) var(--r-lg) 0;
  background-image: linear-gradient(to right, var(--lv-lombada), transparent 9%),
    radial-gradient(ellipse at 45% 40%, var(--lv-papel-luz), transparent 72%); box-shadow: var(--shadow); }
.lv-uma .lv-esq, .uma .lv-face { border-radius: var(--r-lg);
  background-image: linear-gradient(to right, var(--lv-lombada), transparent 6%),
    radial-gradient(ellipse at 50% 40%, var(--lv-papel-luz), transparent 72%); }
/* O filete dourado em volta de cada página, como nos álbuns de capa dura. */
.lv-pagina::before, .lv-face::before { content: ""; position: absolute; inset: 9px; pointer-events: none;
  border: 1px solid color-mix(in srgb, var(--lv-dourado) 30%, transparent); border-radius: 3px; }
.lv-uma .lv-dir { display: none; }
.lv:not(.lv-uma):not(.aberto) .lv-esq { visibility: hidden; }
/* A capa. */
.lv-capa { position: absolute; top: 0; bottom: 0; left: 50%; width: 50%; z-index: 3; padding: 0; border: 0;
  cursor: pointer; font: inherit; transform-origin: left center; transform-style: preserve-3d;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  transition: transform .9s var(--ease), opacity .9s var(--ease);
  border-radius: 0 var(--r-lg) var(--r-lg) 0; color: var(--lv-dourado);
  background: repeating-linear-gradient(45deg, rgba(255, 255, 255, .025) 0 2px, transparent 2px 7px),
    radial-gradient(circle at 30% 18%, #31593f, var(--lv-capa) 58%, var(--lv-capa-2));
  box-shadow: inset 10px 0 16px rgba(0, 0, 0, .38), var(--shadow-lift); }
.lv-capa:focus-visible { outline: none; box-shadow: inset 10px 0 16px rgba(0, 0, 0, .38), var(--ring); }
.lv.aberto .lv-capa { transform: rotateY(-180deg); pointer-events: none; }
.lv-uma .lv-capa { left: 0; width: 100%; border-radius: var(--r-lg); }
.lv-uma.aberto .lv-capa { transform: rotateY(-100deg); opacity: 0; }
.lv-capa-frente { position: absolute; inset: 0; display: grid; place-items: stretch; padding: 22px; }
.lv-capa-moldura { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; text-align: center; border: 2px solid var(--lv-dourado); border-radius: var(--r);
  box-shadow: inset 0 0 0 6px var(--lv-capa), inset 0 0 0 7px var(--lv-dourado); padding: 20px; }
.lv-capa-moldura small { font-size: 11px; font-weight: 800; letter-spacing: .22em; text-transform: uppercase; }
.lv-capa-moldura strong { font-size: clamp(24px, 3.6vw, 38px); font-weight: 900; line-height: 1.08; }
.lv-capa-moldura em { font-style: normal; font-weight: 700; color: var(--lv-capa-texto); font-size: 15px; }
.lv-capa-selo .ico { width: 56px; height: 56px; }
/* A folha solta que vira (duas faces; no telefone, só a que sai). */
.lv-folha-solta { position: absolute; top: 0; bottom: 0; width: 50%; z-index: 4; transform-style: preserve-3d;
  transition: transform .65s var(--ease), opacity .65s var(--ease); }
.lv-folha-solta.vai { left: 50%; transform-origin: left center; }
.lv-folha-solta.volta { left: 0; transform-origin: right center; }
.lv-folha-solta.vai.virou { transform: rotateY(-180deg); }
.lv-folha-solta.volta.virou { transform: rotateY(180deg); }
.lv-folha-solta.uma { left: 0; width: 100%; }
.lv-folha-solta.uma.vai { transform-origin: left center; }
.lv-folha-solta.uma.volta { transform-origin: right center; }
.lv-folha-solta.uma.vai.virou { transform: rotateY(-100deg); opacity: 0; }
.lv-folha-solta.uma.volta.virou { transform: rotateY(100deg); opacity: 0; }
.lv-face { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.lv-verso { transform: rotateY(180deg); }
.uma .lv-verso { display: none; }
@media (prefers-reduced-motion: reduce) {
  .lv-livro, .lv-capa, .lv-folha-solta { transition: none; }
}
/* O que vai nas páginas. */
.lv-num { position: absolute; left: 0; right: 0; bottom: 8px; text-align: center; font-size: 11px;
  color: var(--text-soft); font-variant-numeric: tabular-nums; }
.lv-cabeca { display: block; margin-bottom: 8px; font-size: 11px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-soft); }
/* `.lv .lv-grade`, e não só `.lv-grade`: a `.alb-grade` vem depois na folha e
   venceria pela ordem (auto-fill de 132px). Três colunas aberto, duas no telefone. */
.lv .lv-grade { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; padding: 0; }
.lv-uma .lv-grade { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.lv-grade .alb-nome { font-size: 12px; }
@media (max-width: 1100px) { .lv-grade .alb-onde { display: none; } }
.lv-guarda { height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; text-align: center; color: var(--text-soft); font-size: 14px; }
.lv-guarda .ico { width: 64px; height: 64px; color: var(--brand); opacity: .7; }
.lv-guarda p { margin: 0; max-width: 26ch; }
.lv-respiro .ico { width: 40px; height: 40px; opacity: .35; }
.lv-sumario { display: flex; flex-direction: column; height: 100%; }
.lv-sumario h4 { margin: 0 0 8px; font-size: 20px; font-weight: 900; }
.lv-sumario ol { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1; min-height: 0; }
.lv-cap { display: grid; grid-template-columns: 24px auto minmax(12px, 1fr) auto; align-items: baseline;
  gap: 6px; width: 100%; padding: 5px 0; border: 0; background: none; font: inherit; font-size: 13.5px;
  color: var(--text); text-align: left; cursor: pointer; }
.lv-cap:hover .lv-cap-nome { text-decoration: underline; }
.lv-cap:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-sm); }
.lv-cap-n { color: var(--text-soft); font-variant-numeric: tabular-nums; }
.lv-cap-nome small { color: var(--text-soft); font-size: 11px; }
.lv-cap-pontos { border-bottom: 1px dotted var(--border-strong); transform: translateY(-4px); }
.lv-cap-conta { display: inline-flex; align-items: center; gap: 4px; color: var(--text-soft);
  font-variant-numeric: tabular-nums; }
.lv-cap-conta .ico { width: 14px; height: 14px; color: var(--pat-ouro); }
.lv-abertura { position: relative; height: 100%; display: flex; flex-direction: column; justify-content: center; gap: 10px; }
.lv-dagua { position: absolute; right: 18px; bottom: 6px; font-size: clamp(140px, 22vw, 260px); font-weight: 900;
  line-height: 1; color: color-mix(in srgb, var(--lv-dourado) 11%, transparent); pointer-events: none;
  font-variant-numeric: tabular-nums; }
.lv-ornamento { display: flex; align-items: center; gap: 14px; width: 160px; height: 8px; color: var(--lv-dourado);
  background: radial-gradient(circle, currentColor 3px, transparent 3.5px) center / 10px 10px no-repeat; }
.lv-ornamento::before, .lv-ornamento::after { content: ""; flex: 1; height: 1px; background: currentColor; opacity: .6; }
.lv-polaroides { display: flex; margin-top: 14px; padding-left: 10px; }
.lv-polaroides img { width: clamp(64px, 9vw, 104px); aspect-ratio: 1; object-fit: cover; padding: 5px 5px 16px;
  background: #fbf8f0; border-radius: 2px; box-shadow: 0 6px 16px rgba(0, 0, 0, .35); margin-left: -10px; }
.lv-polaroides img:nth-child(1) { transform: rotate(-5deg); }
.lv-polaroides img:nth-child(2) { transform: rotate(3deg) translateY(6px); }
.lv-polaroides img:nth-child(3) { transform: rotate(-2deg) translateY(-2px); }
.lv-polaroides img:nth-child(4) { transform: rotate(6deg) translateY(4px); }
.lv-abertura .alb-fio { width: 100%; }
.lv-abertura p { margin: 0; color: var(--text-soft); }
.lv-cap-de { font-size: 12px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--text-soft); }
.lv-abertura h4 { margin: 0; font-size: clamp(26px, 3.6vw, 42px); font-weight: 900; line-height: 1.05; }
.lv-uf { font-size: 13px; color: var(--text-soft); }
/* A abertura do estado (1.273.0): a capa do capítulo, no verde da capa do
   álbum, com a arte do estado em traço dourado (`as-artes-dos-estados.js`). */
.lv-estado { position: absolute; inset: 0; overflow: hidden; color: var(--lv-capa-texto);
  background: radial-gradient(circle at 30% 18%, #31593f, var(--lv-capa) 58%, var(--lv-capa-2)); }
.lv-estado::before { content: ""; position: absolute; inset: 12px; border: 1px solid
  color-mix(in srgb, var(--lv-dourado) 35%, transparent); border-radius: 3px; pointer-events: none; }
.lv-arte { position: absolute; inset: 4% 0 0 0; color: var(--lv-dourado); opacity: .8; }
.lv-arte svg { display: block; width: 100%; height: 100%; }
.lv-estado-txt { position: absolute; left: 8%; top: 18%; display: flex; flex-direction: column; gap: 10px; max-width: 56%; }
.lv-estado-txt h4 { margin: 0; font-size: clamp(26px, 4.4vw, 52px); font-weight: 900; line-height: 1.02; color: var(--lv-capa-texto); }
.lv-estado .lv-cap-de, .lv-estado .lv-uf, .lv-estado p { color: color-mix(in srgb, var(--lv-capa-texto) 78%, transparent); }
.lv-estado p { margin: 0; font-size: 14px; }
.lv-estado .lv-dagua-estado { color: color-mix(in srgb, var(--lv-dourado) 16%, transparent); }
.lv-sum-parte { margin: 10px 0 2px; font-size: 11px; font-weight: 800; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-soft); }
.lv-sum-parte:first-child { margin-top: 0; }
.lv-estado ~ .lv-num { color: color-mix(in srgb, var(--lv-capa-texto) 70%, transparent); }
/* As setas nas pontas, sempre no mesmo lugar: o nome do capítulo no meio
   varia de tamanho e é cortado, em vez de empurrar as setas. */
.lv-nav { display: grid; grid-template-columns: 48px minmax(0, 1fr) 48px; align-items: center;
  gap: var(--sp-2); width: min(100%, 980px); margin: 0 auto; }
.lv-nav .btn { width: 48px; padding-left: 0; padding-right: 0; justify-content: center; }
.lv-onde { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 0;
  font-size: 13px; color: var(--text-soft); text-decoration: none; }
.lv-onde span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lv-onde .ico { width: 15px; height: 15px; flex: 0 0 auto; }
.alb { border: 1px solid var(--border); border-radius: var(--r); background: var(--surface);
  margin: 0 0 var(--sp-3); }
.alb > summary { list-style: none; cursor: pointer; }
.alb > summary::-webkit-details-marker, .alb-pagina > summary::-webkit-details-marker { display: none; }
.alb-faixa { display: grid; grid-template-columns: auto minmax(0, 1fr) 120px; align-items: center;
  gap: var(--sp-3); min-height: 56px; padding: 10px 14px; }
.alb-faixa:focus-visible, .alb-pagina > summary:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r); }
.alb-ico { display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--r);
  background: var(--brand-soft); color: var(--brand); }
.alb-ico .ico { width: 20px; height: 20px; }
.alb-txt { display: flex; flex-direction: column; min-width: 0; }
.alb-txt strong { font-size: 15px; font-weight: 700; color: var(--text); }
.alb-txt small { font-size: 12.5px; color: var(--text-soft); }
.alb-fio { display: block; height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.alb-fio i { display: block; height: 100%; background: var(--brand); }
.alb-corpo { padding: 0 14px 14px; border-top: 1px solid var(--border); }
.alb-corpo > .field-hint { margin: var(--sp-2) 0; }
.alb-pagina { border-top: 1px solid var(--border); }
.alb-pagina:first-child { border-top: 0; }
.alb-pagina > summary { display: grid; grid-template-columns: minmax(0, 1fr) auto 80px; align-items: center;
  gap: var(--sp-2); min-height: 44px; padding: 6px 2px; list-style: none; cursor: pointer; }
.alb-pagina > summary:hover strong { text-decoration: underline; }
.alb-pag-nome { min-width: 0; font-size: 14px; color: var(--text); }
.alb-pag-nome small { color: var(--text-faint); font-size: 11.5px; letter-spacing: .04em; }
.alb-conta { display: inline-flex; align-items: center; gap: 4px; font-size: 13px;
  font-variant-numeric: tabular-nums; color: var(--text-soft); }
.alb-conta .ico { width: 15px; height: 15px; color: var(--brand); }
.alb-pagina.completa .alb-conta { color: var(--brand); font-weight: 700; }
.alb-grade { list-style: none; margin: 0; padding: var(--sp-1) 0 var(--sp-3);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: var(--sp-2); }
.alb-fig { display: flex; flex-direction: column; gap: 3px; width: 100%; height: 100%; min-height: 44px;
  padding: 6px; text-align: left; font: inherit; color: var(--text); cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); }
.alb-fig:hover { border-color: var(--border-strong); }
.alb-fig:focus-visible { outline: none; box-shadow: var(--ring); }
.alb-quadro { position: relative; display: block; aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: var(--r-sm); background: var(--surface-2); }
.alb-quadro img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.alb-marca { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--text-faint); }
.alb-marca .ico { width: 28px; height: 28px; }
/* A marca do tipo só sem foto, ou com o link quebrado — a mesma regra do Acervo. */
.alb-quadro img ~ .alb-marca { display: none; }
.alb-fig.sem-foto img { display: none; }
.alb-fig.sem-foto .alb-marca { display: flex; }
.alb-num { position: absolute; left: 4px; top: 4px; min-width: 22px; padding: 1px 5px; border-radius: var(--r-sm);
  background: var(--surface); color: var(--text); font-size: 11px; font-weight: 800;
  font-variant-numeric: tabular-nums; text-align: center; }
.alb-nome { font-size: 13px; font-weight: 650; line-height: 1.25;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.alb-onde { font-size: 11.5px; color: var(--text-soft); }
/* A que falta: tracejada, com o número no meio. */
.alb-fig.vazia { background: transparent; border-style: dashed; border-color: var(--border-strong); }
.alb-fig.vazia .alb-quadro { background: transparent; }
/* O número É o desenho da vazia: o tipo por baixo dele virava borrão. */
.alb-fig.vazia .alb-marca { display: none; }
.alb-fig.vazia .alb-num { left: 50%; top: 50%; transform: translate(-50%, -50%); background: none;
  font-size: 22px; color: var(--text-soft); }
/* O mistério: a foto do lugar que falta, em cinza e desfocada — dá para
   ver que é uma cachoeira, não qual. Escala para o desfoque não deixar
   borda clara; o número ganha a chapa para ser lido por cima. */
.alb-fig.vazia .alb-quadro img { filter: grayscale(1) blur(3px) brightness(.9); transform: scale(1.1); opacity: .85; }
.alb-fig.vazia .alb-quadro img ~ .alb-num { background: var(--surface); padding: 1px 9px; color: var(--text); font-size: 18px; }
.alb-fig.vazia.sem-foto .alb-quadro img ~ .alb-num { background: none; color: var(--text-soft); font-size: 22px; }
.alb-fig.vazia .alb-nome { color: var(--text-soft); font-weight: 600; }
/* A brilhante. */
.alb-fig.brilha { border-color: var(--pat-ouro); }
.alb-fig.colada.brilha { box-shadow: inset 0 0 0 1px var(--pat-ouro); }
.alb-brilho { position: absolute; right: 4px; top: 4px; display: grid; place-items: center;
  width: 22px; height: 22px; border-radius: var(--r-sm); background: var(--surface); color: var(--pat-ouro); }
.alb-brilho .ico { width: 14px; height: 14px; }
/* O reflexo da brilhante colada: uma faixa de ouro e luz que atravessa a
   foto UMA vez, quando a página abre, e de novo sob o dedo ou o ponteiro.
   Ouro da patente, não arco-íris — a mesma regra do brasão (`.pat::after`). */
.alb-fig.colada.brilha .alb-quadro::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 32%,
    color-mix(in srgb, var(--pat-ouro) 45%, transparent) 44%, rgba(255, 255, 255, .7) 50%,
    color-mix(in srgb, var(--pat-ouro) 45%, transparent) 56%, transparent 68%);
  background-size: 260% 100%; background-position: 130% 0;
  mix-blend-mode: screen;
  animation: alb-reflexo 1.5s var(--ease) .25s 1 both;
}
.alb-fig.colada.brilha:hover .alb-quadro::after,
.alb-fig.colada.brilha:focus-visible .alb-quadro::after { animation: alb-reflexo-de-novo 1.1s var(--ease) 1 both; }
@keyframes alb-reflexo { from { background-position: 130% 0; } to { background-position: -30% 0; } }
@keyframes alb-reflexo-de-novo { from { background-position: 130% 0; } to { background-position: -30% 0; } }
/* A patente de ouro, a mais alta: o selo vira metal e o reflexo o atravessa. */
.pat.pat-ouro .pat-selo {
  position: relative; overflow: hidden;
  background: linear-gradient(145deg, color-mix(in srgb, var(--pat-ouro) 30%, transparent),
    color-mix(in srgb, var(--pat-ouro) 8%, transparent) 55%, color-mix(in srgb, var(--pat-ouro) 26%, transparent));
  box-shadow: 0 0 0 1px var(--pat-ouro), 0 0 14px color-mix(in srgb, var(--pat-ouro) 35%, transparent);
}
.pat.pat-ouro .pat-selo::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .55) 50%, transparent 70%);
  background-size: 260% 100%; background-position: 130% 0;
  animation: alb-reflexo 1.6s var(--ease) .6s 1 both;
}
@media (prefers-reduced-motion: reduce) {
  .alb-fig.colada.brilha .alb-quadro::after, .pat.pat-ouro .pat-selo::after { animation: none; opacity: 0; }
}
/* As figurinhas no popup do mapa. O popup do Leaflet é branco nos dois
   temas, então as cores daqui são as do popup, não as do app. */
.alb-mapa { margin-top: 8px; padding-top: 8px; border-top: 1px solid rgba(0, 0, 0, .12); }
.alb-mapa-tit { display: flex; align-items: center; gap: 5px; color: var(--popup-txt-soft); }
.alb-mapa-tit .ico { width: 14px; height: 14px; color: var(--pat-txt-ouro-fixo); }
.alb-mapa-grade { display: flex; gap: 6px; margin-top: 6px; }
.alb-mini {
  position: relative; width: 56px; height: 44px; padding: 0; overflow: hidden; cursor: pointer;
  border: 1px solid rgba(0, 0, 0, .18); border-radius: var(--r-sm); background: #eef0f2;
}
.alb-mini.brilha { border-color: var(--pat-ouro); box-shadow: inset 0 0 0 1px var(--pat-ouro); }
.alb-mini img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.alb-mini b { position: absolute; left: 2px; top: 2px; padding: 0 4px; border-radius: 3px;
  background: #fff; color: #1c2a23; font-size: 10px; font-weight: 800; font-variant-numeric: tabular-nums; }
@media (max-width: 620px) {
  .alb-faixa { grid-template-columns: auto minmax(0, 1fr); }
  .alb-faixa > .alb-fio { grid-column: 1 / -1; }
  .alb-grade { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
  .alb-pagina > summary { grid-template-columns: minmax(0, 1fr) auto 56px; }
}

/* ------------------------------------------------- adaptar para mim */
/* O roteiro de outra pessoa, no alto do montador (`refazer-a-viagem.js`).
   Fundo próprio e opaco: o miolo desta tela é vidro sobre a parede de
   fotos, e o bloco não pode depender do que estiver atrás dele. */
.rv {
  display: flex; flex-direction: column; gap: var(--sp-2);
  max-width: 720px; margin: 0 auto var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--r);
  /* O bloco rola até o alto ao chegar; sem isto a etiqueta parava sob a
     barra fixa do topo (medido a 375px). */
  scroll-margin-top: calc(var(--topbar-h) + var(--safe-topo) + var(--sp-3));
}
.rv-etiqueta {
  display: inline-flex; align-items: center; gap: 6px; margin: 0;
  font-size: 12px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-soft);
}
.rv-etiqueta .ico { width: 16px; height: 16px; color: var(--brand); }
.rv-titulo {
  margin: 0; font-size: 20px; font-weight: 800; letter-spacing: -.01em;
  line-height: 1.2; text-wrap: balance; color: var(--text);
}
.rv-resumo, .rv-fora {
  margin: 0; max-width: 62ch; line-height: 1.5;
  color: var(--text-soft); overflow-wrap: anywhere;
}
.rv-resumo { font-size: 14px; }
.rv-fora { font-size: 13px; }
.rv-fora strong { color: var(--text); font-weight: 650; }
.rv-acoes {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sp-2) var(--sp-3); margin-top: var(--sp-1);
}

@media (prefers-reduced-motion: reduce) {
  .a-mao-chevron .ico { transition: none; }
  .frase-linha { transition: none; }
  /* O microfone pulsando é o aviso de que ESTÁ GRAVANDO, então ele não
     some aqui — fica parado na cor da ação, que diz a mesma coisa sem
     movimento. */
  .frase-voz.gravando svg { animation: none; }
}

/* ---------------------------------------------------- o ajuste fino */
/* O que tinha resposta padrão boa desce para cá. O RESUMO na própria
   linha do botão é a parte que não pode faltar: recolher um padrão sem
   dizer qual ele é troca "denso" por "traiçoeiro". */
.ajuste-fino {
  margin: var(--sp-3) 0 var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface-2);
  overflow: hidden;
}
/* A cabeça tem duas partes agora: o botão que abre, e as MARCAS do que
   já está decidido. Elas saíram de dentro do botão porque passaram a ser
   controles — botão dentro de botão é HTML inválido e quebra o teclado, e
   era por isso que o resumo antigo só podia ser cinza. */
.ajuste-cabeca {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 6px var(--sp-2);
  padding: 10px 14px;
}
.ajuste-botao {
  display: flex; align-items: center; gap: 6px;
  flex: none;
  padding: 2px 0;
  border: 0; background: none;
  font: inherit; text-align: left;
  color: var(--text);
  cursor: pointer;
}
.ajuste-titulo { font-weight: 600; font-size: 14px; flex: none; }
.ajuste-marcas {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  flex: 1 1 auto; min-width: 0;
}
/* Quina e não pílula: é controle. O tom é o do texto, não o da marca —
   são quatro marcas lado a lado, e quatro terracota seriam nenhum. */
.ajuste-marca {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface);
  font: inherit; font-size: 12px; color: var(--text-soft);
  cursor: pointer;
  white-space: nowrap;
}
.ajuste-marca:hover { border-color: var(--border-strong); color: var(--text); }
.ajuste-marca .ico {
  width: 13px; height: 13px; flex: none; color: var(--text-faint);
}
.ajuste-marca:hover .ico { color: var(--brand); }
.ajuste-chevron { flex: none; display: inline-flex; color: var(--text-faint); }
.ajuste-chevron .ico { width: 16px; height: 16px; transition: transform .16s var(--ease); }
.ajuste-fino.aberto .ajuste-chevron .ico { transform: rotate(180deg); }
.ajuste-corpo {
  padding: 2px 14px 16px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.ajuste-corpo > .datetime-row,
.ajuste-corpo > .dt-part { margin-top: 14px; }

/* ------------------------------------------------ o alcance do volante */
/* Horas de volante é o que o motor precisa; quilômetro de alcance é o que
   a decisão precisa. O número já existia escondido no `data-km`. */
.volante-alcance {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-top: var(--sp-2);
}
.volante-svg { width: 62px; height: 62px; flex: none; overflow: visible; }
.ra-outro {
  fill: none;
  stroke: var(--border-strong);
  stroke-width: 1;
  stroke-dasharray: 2 3;
}
.ra-ativo {
  fill: color-mix(in srgb, var(--brand) 14%, transparent);
  stroke: var(--brand);
  stroke-width: 1.5;
  transition: r .25s var(--ease);
}
.ra-casa { fill: var(--accent); }
.volante-texto { display: flex; flex-direction: column; gap: 1px; font-size: 14px; }
.volante-texto strong { font-size: 17px; font-weight: 650; letter-spacing: -.01em; }
.volante-texto small { font-size: 12.5px; color: var(--text-faint); }
.volante-porque { margin-top: var(--sp-2); }

@media (prefers-reduced-motion: reduce) {
  .ra-ativo { transition: none; }
  .ajuste-chevron .ico { transition: none; }
}

/* ------------------------------------------- as abas de duração */
/* Eram pílulas com DUAS linhas de texto dentro — rótulo e detalhe —, o que
   transforma um controle num cartãozinho apertado, e quatro deles numa
   fileira de cartõezinhos. Agora são um controle segmentado: uma peça só,
   de quina, com divisórias entre as partes e UMA linha em cada. O detalhe
   ("2 a 3 dias") saiu de dentro do botão e virou a legenda da faixa, que é
   onde explicação mora. */
.rot-abas {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.rot-abas::-webkit-scrollbar { display: none; }
.rot-abas.ocupado { opacity: .55; }
.rot-aba {
  flex: 0 0 auto;
  padding: 9px 16px;
  border: 0;
  border-left: 1px solid var(--border);
  background: none;
  color: var(--text-soft);
  font: inherit; font-size: 13.5px; font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background .12s var(--ease), color .12s var(--ease);
}
.rot-aba:first-child { border-left: 0; }
.rot-aba:hover:not([aria-selected="true"]) {
  background: var(--surface-2); color: var(--text);
}
/* Verde musgo: a aba organiza a vitrine, não é o gesto que monta a viagem.
   Terracota aqui roubaria o papel do botão que importa. */
.rot-aba[aria-selected="true"] {
  background: var(--brand);
  color: var(--brand-text);
}
/* O detalhe do tamanho escolhido, fora do controle. */

.rot-faixa-cabeca p .rot-faixa-detalhe {
  color: var(--text);
  font-weight: 600;
}

/* ------------------------------- o selo do estado, na quina do cartão */
/* Ele substituiu um traço solto com "41 km de ponta a ponta" ao lado.
   Relatado assim: *"isso não agrega em nada da forma que está"*. O número
   respondia "cabe num vale?", que é pergunta de segunda ordem, e o traço
   respondia a mesma coisa de novo. A primeira — ONDE, no estado, isso
   fica — é que decide se a pessoa vai, e nenhum dos dois respondia.

   Por que quina, e não uma linha na coluna de texto: o cartão tem 264 px e
   a coluna já carrega selo, título, cidades e os selos de "para você". Um
   desenho ali empurra a chamada para fora no telefone. E a metade de cima
   é justamente a parte que o véu deixa quase limpa.

   As cores são fixas, e não tokens. O cartão é escuro nos DOIS temas — o
   véu é um degradê fixo e o texto é `#f4f7f5` —, então `--border` como
   massa do estado sumiria no tema escuro. Aqui a régua não é o tema da
   página: é a foto embaixo. */
.rot-uf {
  position: absolute; top: 12px; right: 12px;
  width: 62px; padding: 5px;
  /* Quina, como todo o resto: `--r` é 4px. Pílula é para etiqueta de
     contagem, e isto não é contagem. */
  border-radius: var(--r);
  /* Véu de borda DEFINIDA, e não borrão: é a regra da folha para desenho
     sobre foto. A faixa sólida é o chão do selo. */
  /* Sólida, e não meio transparente: a 58% a foto atravessava a massa do
     estado e a silhueta deixava de ler como forma. Medido na produção
     sobre uma cachoeira escura e sobre uma fachada branca ao sol. */
  background: rgba(9, 14, 12, .86);
  border: 1px solid rgba(255, 255, 255, .3);
  line-height: 0;
  /* Enquanto o contorno não chegou, o selo não ocupa lugar nenhum: sem
     silhueta não há o que localizar, e um quadro vazio na quina diria que
     faltou alguma coisa num cartão que está inteiro. */
  display: none;
}
.rot-uf.tem-mapa { display: block; }
.rot-uf .ore { display: block; width: 100%; height: auto; }
/* O estado, em claro sobre o véu escuro. */
.rot-uf .ore-chao {
  fill: rgba(255, 255, 255, .34);
  stroke: rgba(255, 255, 255, .62);
  stroke-width: 3;
}
/* A grossura do traço é em unidade do SVG, e o quadro tem 620 delas em
   62 px: o `stroke-width: 3` do painel daria 0,3 px aqui. Escala de traço
   não acompanha escala de desenho. */
.rot-uf .ore-brilho {
  stroke: rgba(8, 13, 11, .8); stroke-width: 26; opacity: 1;
}
.rot-uf .ore-rota { stroke: rgba(255, 224, 205, .95); stroke-width: 11; }
.rot-uf .ore-outra {
  fill: rgba(255, 255, 255, .78); stroke: rgba(8, 13, 11, .55);
  stroke-width: 4; opacity: 1;
}
.rot-uf .ore-disco {
  fill: var(--accent); stroke: rgba(8, 13, 11, .75); stroke-width: 6;
}
.rot-uf .ore-anel { fill: var(--accent); opacity: .3; }

/* O mesmo mapa, grande, na ficha — é aqui que a pessoa decide. */
.rot-ficha-mapa {
  display: flex; align-items: center; gap: var(--sp-3);
  margin: 0 0 var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  /* `--surface`, e não `--surface-2`. A massa do estado é `--border`, e
     esse tom foi escolhido medindo contra `--surface`: sobre `--surface-2`
     o degrau cai de 1,30 para 1,15 e a silhueta vira um fantasma dentro do
     cartão. Medido na produção em 14/09/2026, no tema escuro. Quem
     delimita o bloco é a borda, como no painel "Onde fica" da tela de
     planejar — que usa esta mesma receita e já foi aceita na tela. */
  background: var(--surface);
}
.rot-ficha-mapa .ore-quadro { flex: 0 0 auto; display: block; width: 120px; }
.rot-ficha-mapa .ore { display: block; width: 100%; height: auto; }
.rot-ficha-onde { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rot-ficha-onde small { font-size: 12px; color: var(--text-faint); }
.rot-ficha-onde .ore-onde { color: var(--text-soft); }

/* ------------------------------- o balão do ponto no mapa do catálogo */
/* Era uma DICA ao passar o mouse (foto, nome e onde fica), e no iPhone ela
   engolia o toque. Virou o balão (`o-catalogo-no-roteiro.js`) com a mesma
   cabeça — a foto grande em cima — e os botões embaixo. A largura vem do
   `minWidth`/`maxWidth` do Leaflet; aqui a foto vai de ponta a ponta. */
.cr-pop .bp-miolo { margin: 0; }
.cr-pop .bp-casca { padding: 0; overflow: hidden; }
.cr-cartao { display: block; }
.cr-corpo { display: flex; flex-direction: column; gap: 6px; padding: 0 var(--s3) var(--s3); font-size: 12.5px; color: var(--text-soft); }
.cr-corpo .bp-acoes { margin-top: 2px; }
.mc-dica { display: block; }
.mc-dica-foto {
  display: block; width: 100%; height: 120px;
  object-fit: cover;
  background: var(--bg-alt);
}
.mc-dica-nome {
  display: block; padding: 7px 9px 0;
  font-weight: 700; font-size: 12.5px; line-height: 1.25;
  color: var(--text);
}
.mc-dica-onde {
  display: block; padding: 1px 9px 7px;
  font-size: 11px; color: var(--text-faint);
}
/* Sem foto, a dica é só o texto: a folga de cima volta. */
.mc-dica-nome:first-child { padding-top: 7px; }

/* ------------------------------------- os selos "para você" no cartão */
/* Eram texto solto sobre a foto. Por cima de uma cachoeira clara o branco
   a 92% não tem contraste calculável — e é justamente a informação que
   decide sem abrir o cartão. Agora cada um carrega o próprio fundo. */
.rot-selos { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 1px; }
.rot-pv {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  font-size: 11.5px; font-weight: 650; letter-spacing: .01em;
  white-space: nowrap;
}
.rot-pv-ico { width: 12px; height: 12px; }
/* Fundo quase opaco, e não um véu: o cálculo de contraste tem de fechar
   contra o PRÓPRIO fundo do selo, seja qual for a foto atrás dele. */
.rot-pv-perto { background: rgba(12, 20, 16, .82); color: #eef3ef; }
.rot-pv-visto { background: rgba(240, 244, 240, .92); color: #1c2a23; }
/* "Na época": musgo da marca, também quase opaco sobre a foto. */
.rot-pv-epoca { background: rgba(44, 76, 59, .94); color: #eef3ef; }
/* O tempo dos dias da viagem (`a-chuva-na-escolha.js`), com fundo próprio
   como os outros selos sobre a foto. */
.rot-pv-chuva { background: rgba(122, 32, 32, .94); color: #eef3ef; }
.rot-pv-talvez { background: rgba(110, 82, 16, .94); color: #eef3ef; }
.rot-pv-seco { background: rgba(44, 76, 59, .94); color: #eef3ef; }
/* "Estrada de terra", para quem evita: o claro do "já visitado", opaco. */
.rot-pv-terra { background: rgba(240, 244, 240, .92); color: #1c2a23; }

/* ------------------------------------------ levar a viagem */
.card-levar .levar-rotulo { margin-left: 2px; }
.card-levar[disabled] { opacity: .6; cursor: progress; }
.card-levar.levada { color: var(--brand); }
.card-levar.levada .ico { color: var(--brand); }

/* O selo fica no CARTÃO, e não dentro do menu: "na bagagem" é informação,
   e informação atrás de um menu fechado não informa ninguém. Etiqueta, não
   botão — daí a pílula, que é a única coisa arredondada desta folha. */
.selo-bagagem {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  background: var(--brand-soft);
  color: var(--brand);
  font-size: 11.5px; font-weight: 650; letter-spacing: .02em;
  white-space: nowrap;
}
.selo-bagagem .ico { width: 13px; height: 13px; }
.card-selos:empty { display: none; }

/* ------------------------------------------ o menu do cartão */
/* Seis botões do mesmo peso não hierarquizam nada: a pessoa lê todos para
   achar o que quer, toda vez. Fica à vista o que se aperta quase sempre;
   o resto entra aqui. */
.card-rodape { position: relative; }
.card-mais { padding: 8px 10px; margin-left: auto; }
.card-mais .ico { width: 18px; height: 18px; }
.card-menu {
  position: absolute;
  top: calc(100% + 6px); right: 0;
  z-index: 30;
  min-width: 216px;
  display: flex; flex-direction: column;
  padding: 5px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-lift);
}
.card-menu-item {
  display: flex; align-items: center; gap: 9px;
  width: 100%;
  padding: 9px 10px;
  border: 0; border-radius: var(--r-sm);
  background: none;
  color: var(--text);
  font: inherit; font-size: 13.5px; font-weight: 550;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.card-menu-item:hover { background: var(--surface-2); }
.card-menu-item .ico { width: 16px; height: 16px; flex: none; color: var(--text-faint); }
.card-menu-item.levada .ico { color: var(--brand); }
/* O destrutivo por último e separado: mão que desce a lista não pode
   esbarrar em "apagar" na velocidade de "replanejar". */
.card-menu-item.perigo {
  margin-top: 4px; padding-top: 11px;
  border-top: 1px solid var(--border);
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  color: var(--danger);
}
.card-menu-item.perigo .ico { color: var(--danger); }
.card-menu-item.perigo:hover {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}

/* ------------------------------------------- o alternador de camada */
/* Mapa e Meus Lugares são a mesma superfície com perguntas diferentes. O
   controle vive no MESMO canto das duas telas, por cima do mapa: é a
   relação com o mapa que o faz ler como um botão de camada. Em lugares
   diferentes, leria como dois controles sem relação. */
.dm-hospeda { position: relative; }
.dm {
  position: absolute;
  /* À DIREITA, e não à esquerda: o zoom do Leaflet nasce na quina de cima
     à esquerda, e o alternador o cobria — medido na tela, o "+" ficava
     atrás dele. A quina de cima à direita está livre nos dois mapas (o HUD
     do catálogo fica embaixo à esquerda). */
  top: 12px; right: 12px;
  /* Acima dos controles do Leaflet, que ficam em 400 e 1000. */
  z-index: 1001;
  display: inline-flex;
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.dm-btn {
  border: 0;
  border-left: 1px solid var(--border);
  background: none;
  color: var(--text-soft);
  font: inherit; font-size: 13px; font-weight: 600;
  padding: 9px 14px;
  white-space: nowrap;
  cursor: pointer;
}
.dm-btn:first-child { border-left: 0; }
.dm-btn:hover:not([aria-current]) { background: var(--surface-2); color: var(--text); }
/* Musgo: o alternador organiza, não é o gesto que monta a viagem. */
.dm-btn[aria-current="page"] {
  background: var(--brand);
  color: var(--brand-text);
  cursor: default;
}
/* No telefone o mapa é estreito: o que encolhe é o rótulo, não o lugar. */
@media (max-width: 620px) {
  .dm { font-size: 12.5px; }
  .dm-btn { padding: 9px 11px; }
}

/* ============================================================
   MEU MAPA — o acervo primeiro, a lacuna depois

   A tela mostrava o que já foi visitado e, no último bloco, o quanto isso
   dava. Aqui a ordem inverte: o acumulado abre a tela, porque é ele que
   faz alguém abrir o app numa quinta-feira sem viagem marcada.
   ============================================================ */

/* ------------------------------------------------------- os troféus */
/* ERAM DEZ AZULEJOS IGUAIS, e a queixa foi exata: "essas medalhas não me
   explicam nada […] cara de site genérico".

   A causa não era o ícone nem a cor: era a FORMA. Os dez marcos não são
   dez coisas soltas — 1, 10, 50 e 100 lugares são a mesma escada, e 5 e
   25 cidades são outra. Desenhar escada como fileira de medalhas joga
   fora a única estrutura que o dado tem, e o que sobra é papel de parede.

   Cada medida virou uma escada: o número de hoje, a trilha com um entalhe
   por degrau, e a frase do que falta para o próximo. Os degraus ficam
   IGUALMENTE espaçados de propósito — a trilha é ordinal, não é régua —,
   e por isso cada entalhe carrega o número embaixo: é ele que impede
   alguém de ler a distância como escala.

   O bloco separado de números saiu junto: "183 lugares" estava desenhado
   duas vezes na mesma tela, e a segunda cópia é a que envelhece sozinha. */
.trofeus {
  display: flex; flex-direction: column; gap: var(--sp-3);
  margin-bottom: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.trofeus-cabeca {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-2); flex-wrap: wrap;
}
.trofeus-cabeca h3 { margin: 0; font-size: 15px; }
.trofeus-conta {
  font-size: 12.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.trofeus-conta strong { color: var(--text); font-weight: 700; }

/* =============== A PATENTE ===============
   O brasão, o que falta para o próximo, e as missões do mês.

   O tom da patente é um TOKEN por nível, não uma cor solta: a folha já
   tem musgo, terracota e os neutros, e a hierarquia pede que a cor suba
   junto. Ouro e cobre entram como os dois únicos tons novos do conjunto,
   e entram porque uma patente que não muda de cor não é uma patente. */
:root {
  --pat-chao: var(--text-faint);
  --pat-barro: #8a7a5f;
  --pat-musgo: var(--brand);
  --pat-cobre: var(--accent);
  --pat-ouro: #c9a227;
  /* A cor que DESENHA não é a cor que se LÊ.
     O brasão, o fio do topo e a borda usam `--pat` e vivem bem com 3:1 —
     são desenho. O "PATENTE 4 DE 5" tem 11px e precisa de 4,5, e medido no
     tema claro a escada inteira reprovava: barro 3,78, cobre 3,45 e ouro
     2,19 — o ouro nem os 3:1 do desenho alcançava, então o NOME da patente
     de nível cinco também estava ilegível. Aqui cada nível ganha o mesmo
     tom puxado até passar, mantendo a identidade. */
  --pat-txt-chao: var(--text-faint);
  --pat-txt-barro: #6f6247;
  --pat-txt-musgo: var(--brand);
  --pat-txt-cobre: #a95733;
  --pat-txt-ouro: #7d640f;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* No escuro o caminho é o contrário: clarear até passar. Cobre e ouro
       já passavam (4,70 e 5,61); barro estava em 3,25. */
    --pat-txt-barro: #a8977a;
    --pat-txt-cobre: var(--accent);
    --pat-txt-ouro: var(--pat-ouro);
  }
}
.pat {
  position: relative; overflow: hidden;
  display: grid; align-items: center;
  grid-template-columns: auto 1fr auto;
  grid-template-areas: "selo texto conta" "prox prox prox";
  gap: 14px var(--sp-3);
  padding: var(--sp-3);
  margin-bottom: var(--sp-3);
  border: 1px solid var(--border);
  border-left: 3px solid var(--pat);
  border-radius: var(--r-lg);
  background: var(--surface-2);
}
.pat-chao { --pat: var(--pat-chao); --pat-txt: var(--pat-txt-chao); }
.pat-barro { --pat: var(--pat-barro); --pat-txt: var(--pat-txt-barro); }
.pat-musgo { --pat: var(--pat-musgo); --pat-txt: var(--pat-txt-musgo); }
.pat-cobre { --pat: var(--pat-cobre); --pat-txt: var(--pat-txt-cobre); }
.pat-ouro { --pat: var(--pat-ouro); --pat-txt: var(--pat-txt-ouro); }
/* O reflexo que atravessa o brasão — o "foil" do pedido, traduzido para
   a identidade: um brilho da PRÓPRIA cor da patente, não arco-íris. Ele
   passa uma vez e para; brilho em laço é enfeite que compete com o
   conteúdo da tela. */
.pat::after {
  content: ""; position: absolute; inset: 0 0 auto; height: 2px;
  background: linear-gradient(90deg, transparent,
    color-mix(in srgb, var(--pat) 85%, transparent) 50%, transparent);
  transform: translateX(-100%);
  animation: pat-brilho 1.4s var(--ease) .4s 1 both;
  pointer-events: none;
}
@keyframes pat-brilho { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .pat::after { animation: none; transform: none; }
}
.pat-selo {
  grid-area: selo;
  display: grid; place-items: center;
  width: 64px; height: 64px;
  border-radius: var(--r-lg);
  color: var(--pat);
  background: color-mix(in srgb, var(--pat) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--pat) 34%, transparent);
}
.pat-selo .ico { width: 40px; height: 40px; }
.pat-texto { grid-area: texto; display: block; min-width: 0; }
/* Regra DIRETA em cada filho: a folha tem cor própria para `small` e
   `strong`, e pintar só `.pat` deixaria estes três com a cor de antes. */
.pat-nivel {
  display: block; font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--pat-txt, var(--pat));
  font-weight: 700;
}
.pat-nome {
  display: block; font-size: 19px; font-weight: 800;
  letter-spacing: -.02em; color: var(--text); text-wrap: balance;
}
.pat-lore {
  display: block; margin-top: 3px; font-size: 12px;
  color: var(--text-faint); line-height: 1.4;
}
.pat-conta { grid-area: conta; text-align: right; }
.pat-conta b {
  display: block; font-size: 22px; font-weight: 800; line-height: 1;
  color: var(--text); font-variant-numeric: tabular-nums;
}
.pat-conta small {
  display: block; margin-top: 3px; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint);
}
.pat-prox { grid-area: prox; display: block; }
.pat-barra {
  display: block; height: 4px; border-radius: 999px;
  background: var(--border-strong); overflow: hidden;
}
.pat-barra i {
  display: block; height: 100%; width: var(--ate, 0%);
  border-radius: 999px; background: var(--pat);
  transition: width .6s var(--ease);
}
.pat-falta {
  display: block; margin-top: 7px; font-size: 12px;
  color: var(--text-soft); line-height: 1.45;
}
.pat-falta b { color: var(--text); font-weight: 700; }

/* ---- As missões do mês ---- */
/* =============== A ESCALA DAS PATENTES ===============
   "não consigo ver o que foi conquistado nem o que está por vir, seria
    legal ter uma opção de clicar e ver todas escalas"

   São cinco brasões desenhados, um por nível — e a tela mostrava um de
   cada vez, então quatro deles existiam no sprite e ninguém via. Um
   brasão que não se compara com os outros é um ícone, não é patente.

   O FIO VERTICAL é a mesma gramática da trilha das escadas: sólido no
   que já foi andado, pontilhado no que falta. Ele atravessa a lista
   inteira e é INTERROMPIDO pelo brasão, que tem fundo opaco — desenhar
   segmento por segmento entre centros de brasão dependeria de todas as
   linhas terem a mesma altura, e elas não têm: o lore de cada patente
   tem um tamanho. */
.pat-escala-bloco { margin-bottom: var(--sp-3); }
.pat-todas {
  width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 10px var(--sp-3);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text-soft);
  font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
}
.pat-todas:hover { border-color: var(--border-strong); color: var(--text); }
.pat-todas-seta { width: 15px; height: 15px; transition: transform .15s ease; }
.pat-todas-aberta .pat-todas-seta { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .pat-todas-seta { transition: none; }
}
.pat-escala {
  list-style: none; margin: var(--sp-2) 0 0; padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface);
}
.pat-deg {
  position: relative;
  display: grid; grid-template-columns: 38px 1fr auto;
  align-items: center; column-gap: 12px;
  padding: 10px 0;
}
.pat-deg::before {
  content: ""; position: absolute; left: 18px; top: 0; bottom: 0;
  border-left: 2px dashed var(--border-strong);
}
.pat-deg-ganha::before {
  border-left-style: solid; border-left-color: var(--brand);
}
/* As pontas param no centro do brasão: fio que sai da lista parece
   caminho cortado. O brasão fica centrado na linha, então 50% da altura
   é exatamente o centro dele. */
.pat-deg:first-child::before { top: 50%; }
.pat-deg:last-child::before { bottom: 50%; }
.pat-deg-selo {
  position: relative; z-index: 1;
  display: grid; place-items: center;
  width: 38px; height: 38px;
  border-radius: var(--r);
  /* Opaco de propósito: é ele que interrompe o fio. Misturar com
     `--surface` (opaca) mantém a opacidade e ainda dá o tom da patente. */
  color: var(--text-faint);
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.pat-deg-ganha .pat-deg-selo {
  color: var(--pat);
  background: color-mix(in srgb, var(--pat) 14%, var(--surface));
  border-color: color-mix(in srgb, var(--pat) 35%, var(--border));
}
.pat-deg-ico { width: 24px; height: 24px; }
.pat-deg-txt { display: block; min-width: 0; }
/* Regra direta ganha de herança: a folha pinta `small` e `strong` por
   conta própria, e sem nomear os três aqui eles ficariam com a cor de
   antes. */
.pat-deg-nivel {
  display: block; font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-faint);
}
.pat-deg-nome {
  display: block; font-size: 14px; font-weight: 700; color: var(--text);
}
.pat-deg-ganha .pat-deg-nome { color: var(--pat-txt); }
.pat-deg-lore { display: block; font-size: 11.5px; color: var(--text-faint);
                line-height: 1.35; }
.pat-deg-estado {
  display: flex; align-items: center; gap: 4px;
  font-size: 11.5px; color: var(--text-faint); text-align: right;
  font-variant-numeric: tabular-nums;
}
.pat-deg-estado b { color: var(--text); font-weight: 700; }
.pat-deg-ok { width: 14px; height: 14px; color: var(--brand); }
/* `.pat-deg-estado b` é (0,1,1) e esta era (0,1,0): a regra de cima
   ganhava por especificidade e o chip saía em `--text`, sem o tom da
   patente. Medido no tema claro: 13,02 — legível, e sem a cor que era o
   ponto. O seletor sobe para empatar e vencer por ordem. */
.pat-deg-estado .pat-deg-aqui {
  padding: 3px 8px; border-radius: var(--r);
  /* O tom PUXADO para o texto, e não puro: os tons da patente foram
     medidos sobre `--surface` e `--surface-2`, não sobre um fundo já
     tingido com eles próprios. Medido no claro, cobre puro sobre a
     tinta de 12%: 4,46 — passa raspando por baixo. */
  color: color-mix(in srgb, var(--pat-txt) 80%, var(--text));
  font-weight: 700;
  border: 1px solid color-mix(in srgb, var(--pat) 45%, transparent);
  background: color-mix(in srgb, var(--pat) 12%, transparent);
}
/* A patente de agora é a única com peso na lista: sem isso as cinco
   linhas leem igual, e "onde eu estou" volta a ser invisível. */
.pat-deg-atual .pat-deg-nome { font-size: 15px; }
@media (max-width: 479px) {
  /* O estado desce para baixo do nome: "faltam 201" ao lado de um lore
     de duas linhas espremia as duas colunas. */
  .pat-deg { grid-template-columns: 38px 1fr; row-gap: 6px; }
  .pat-deg-estado { grid-column: 2; justify-content: flex-start;
                    text-align: left; }
}

.mis { margin-bottom: var(--sp-3); }
.mis-cabeca {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 4px 10px; margin-bottom: 8px; flex-wrap: wrap;
}
.mis-cabeca h4 { margin: 0; font-size: 13px; }
.mis-cabeca small { font-size: 11px; color: var(--text-faint); }
.mis-lista { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 8px; }
.mis-item {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: 11px;
  padding: 10px 12px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2);
}
.mis-ico { display: grid; place-items: center; color: var(--text-soft); }
.mis-ico .ico { width: 18px; height: 18px; }
.mis-texto { display: block; min-width: 0; }
.mis-texto strong {
  display: block; font-size: 12.5px; font-weight: 600; color: var(--text);
  line-height: 1.35;
}
.mis-barra {
  display: block; height: 3px; margin-top: 7px;
  border-radius: 999px; background: var(--border-strong);
}
.mis-barra i {
  display: block; height: 100%; width: var(--ate, 0%);
  border-radius: 999px; background: var(--brand);
}
.mis-conta {
  font-size: 15px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.mis-conta small { font-size: 11px; color: var(--text-faint); font-weight: 400; }
.mis-feita { border-color: var(--brand); }
.mis-feita .mis-ico { color: var(--brand); }

@media (max-width: 559px) {
  .pat {
    grid-template-columns: auto 1fr;
    grid-template-areas: "selo texto" "conta conta" "prox prox";
  }
  .pat-conta { text-align: left; }
}

/* =============== A FAIXA DO ACERVO ===============
   "essa parte gamificada podia ficar colapsada, o mapa acaba ficando em
    segundo plano, quando deveria ser o destaque da página."

   Medido no tema escuro a 402 px: brasão (150) + missões (210) + seis
   escadas (596) = 956 px acima do mapa. A tela chamada "Meus Lugares" não
   mostrava mapa nenhum sem rolar.

   A faixa é o resumo que cabe numa linha, e é um BOTÃO inteiro: o alvo é
   a faixa toda, não uma setinha no canto. Ela usa os mesmos tokens da
   patente (`--pat`), então o nível continua se lendo pela cor — de
   relance, e sem legenda. */
.acv-faixa {
  position: relative; overflow: hidden;
  width: 100%;
  display: flex; align-items: center; gap: var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-3);
  padding: 10px var(--sp-3) 13px;
  text-align: left;
  border: 1px solid var(--border);
  border-left: 3px solid var(--pat, var(--brand));
  border-radius: var(--r-lg);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.acv-faixa:hover { border-color: var(--border-strong); }
/* O compartilhar do explorador, ao lado da faixa (`o-acervo-recolhido.js`). */
.acv-linha { display: flex; gap: var(--s2); align-items: stretch; margin-bottom: var(--sp-3); }
.acv-linha > .acv-faixa { flex: 1; min-width: 0; margin-bottom: 0; }
.acv-partilha { flex: 0 0 auto; min-width: 48px; display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--r); background: var(--surface); color: var(--brand); }
.acv-partilha:hover { border-color: var(--border-strong); }
.acv-partilha:focus-visible { outline: none; box-shadow: var(--ring); }
.acv-partilha .ico { width: 20px; height: 20px; }
.acv-faixa.acv-aberta { padding-bottom: 10px; }
/* `acv-brasao`, e não `acv-selo`: esse nome já era o selo do cartão de
   Destinos ("já visitei"), duas mil linhas acima. Esta regra vinha depois e
   vencia — o selo do cartão virava um quadrado de 34px com o texto
   espremido embaixo do ícone. */
.acv-brasao {
  flex: none; display: grid; place-items: center;
  width: 34px; height: 34px;
  border-radius: var(--r);
  color: var(--pat, var(--brand));
  background: color-mix(in srgb, var(--pat, var(--brand)) 14%, transparent);
}
.acv-brasao .ico { width: 22px; height: 22px; }
.acv-quem { min-width: 0; flex: 1 1 auto; display: block; }
/* Regra direta ganha de herança: a folha pinta `small` e `strong` por
   conta própria, e sem nomear os dois aqui eles ficariam com a cor de
   antes sobre este fundo. */
.acv-nivel {
  display: block;
  font-size: 10px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--pat-txt, var(--text-faint));
}
.acv-nome {
  display: block; font-size: 15px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.acv-conta { flex: none; text-align: right; }
.acv-conta b {
  display: block; font-size: 17px; font-weight: 800; color: var(--text);
  line-height: 1.1; font-variant-numeric: tabular-nums;
}
.acv-conta small { font-size: 10.5px; color: var(--text-faint); }
.acv-mais {
  flex: none; display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600; color: var(--text-soft);
}
.acv-mais .ico { width: 15px; height: 15px; }
/* A seta aponta para onde o clique leva: `i-chevron` já nasce apontando
   para BAIXO (é ele que abre), e recolher é o mesmo desenho de cabeça
   para baixo. Sem o giro, o mesmo desenho diria as duas coisas. */
.acv-seta { transition: transform .15s ease; }
.acv-aberta .acv-seta { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .acv-seta { transition: none; }
}
/* O fio de progresso mora na borda de baixo da faixa — não é barra de
   leitura, é a mesma informação do `.pat-barra` reduzida a um fio. */
.acv-fio {
  position: absolute; inset: auto 0 0 0; height: 3px;
  background: var(--border);
}
.acv-fio i {
  display: block; height: 100%; width: var(--ate, 0%);
  background: var(--pat, var(--brand));
}
@media (max-width: 479px) {
  /* Na tela estreita a conta desce para baixo do nome: três blocos numa
     linha de 340 px espremem o nome da patente até a reticência. */
  .acv-faixa { flex-wrap: wrap; }
  .acv-quem { flex-basis: calc(100% - 34px - var(--sp-3)); }
  /* Aberta não há selo nem contagem: a reserva acima jogaria o "Recolher"
     para uma segunda linha sozinha, que foi o que a bancada mostrou. */
  .acv-aberta { flex-wrap: nowrap; }
  .acv-aberta .acv-quem { flex-basis: auto; }
  .acv-conta { text-align: left; }
  .acv-conta b { display: inline; font-size: 15px; }
  .acv-mais { margin-left: auto; }
}

/* O mapa do Diário. Era `height:420px` escrito no atributo `style` da
   página; com o acervo recolhido ele virou a primeira coisa da tela, e
   aí faz diferença ele usar a altura que a janela tem. O piso de 380 px
   é o que ainda mostra um estado inteiro no telefone. */
.mapa-do-diario {
  height: clamp(380px, 56vh, 560px);
  background: var(--bg-alt);
}

.escadas {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--sp-3);
}
/* Duas linhas: em cima o número, a medida e o estado; embaixo a trilha
   inteira, que precisa da largura toda para os entalhes não se tocarem.

   Cada escada é um CARD com raridade — e a raridade é o degrau mais alto
   já vencido, não uma etiqueta de estilo. Quem ainda não venceu nenhum
   fica sem cor e sem etiqueta: dar "Comum" a quem não começou é premiar
   o zero. */
.escada {
  position: relative; overflow: hidden;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "quanto estado" "trilha trilha";
  align-items: baseline;
  column-gap: 10px; row-gap: 12px;
  padding: 12px 14px 4px;
  border: 1px solid var(--border); border-radius: var(--r-lg);
  /* `--surface`, e não `--surface-2`: o painel em volta já é `--surface`,
     e o card ganha corpo pela BORDA. Medido na bancada a 375 px no tema
     escuro, o card em `--surface-2` derrubou "Desbravador · escada
     completa" (`--brand`) de 4,5 para 4,40 — é a mesma armadilha do
     chão do estado, com outro token. */
  background: var(--surface);
}
/* DOIS tokens por raridade, e é a mesma lição de `--pat` e `--pat-txt`:
   `--rar` DESENHA (a borda e o fio do topo, que vivem bem com 3:1) e
   `--rar-txt` se LÊ. Medido na produção em 16/09/2026, tema claro, 402px:
   a etiqueta "LENDÁRIO" saía do ouro de desenho e dava 3,66 sobre
   `--surface` — reprovada, e é o menor texto da tela (9,5px). Os tons de
   texto da patente já existiam, medidos, para exatamente isto. */
.esc-comum { --rar: var(--text-faint); --rar-txt: var(--pat-txt-chao); }
.esc-rara { --rar: var(--info); --rar-txt: var(--info); }
.esc-epica { --rar: var(--pat-cobre); --rar-txt: var(--pat-txt-cobre); }
.esc-lendaria { --rar: var(--pat-ouro); --rar-txt: var(--pat-txt-ouro); }
.escada[class*="esc-"]:not(.esc-nenhuma) { border-color:
  color-mix(in srgb, var(--rar) 40%, var(--border)); }
/* O "foil" do card raro, e por que ele NÃO é um brilho atravessando.
   A primeira versão era uma faixa diagonal suave sobre o card inteiro:
   na bancada ela passou por baixo de "Desbravador · escada completa" e
   virou exatamente a névoa que esta folha não admite atrás de texto de
   leitura. O metal virou então um FIO no topo do card — um degradê de
   três paradas em dois pixels, que lê como brilho de borda e não
   encosta em nenhuma palavra. */
.esc-lendaria::before, .esc-epica::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 2px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--rar) 25%, transparent),
    var(--rar) 45%,
    color-mix(in srgb, var(--rar) 25%, transparent));
  pointer-events: none;
}
.escada-raridade {
  position: absolute; top: 10px; right: 12px;
  font-size: 9.5px; font-weight: 700; letter-spacing: .09em;
  /* A etiqueta é o menor texto da tela (9,5 px). A cor pura da raridade
     dava 4,09 na terracota e 4,18 no cinza — reprovadas as duas. Puxada
     30% para o tom do texto ela passa dos 4,5 e continua sendo
     reconhecivelmente a cor da raridade. */
  text-transform: uppercase;
  /* Sem fallback para `--rar`: toda classe de raridade declara
     `--rar-txt`, e o fallback só serviria para o dia em que
     alguém esquecesse — devolvendo o defeito em silêncio. */
  color: color-mix(in srgb, var(--rar-txt) 70%, var(--text));
  padding: 3px 7px; border-radius: var(--r-pill);
  border: 1px solid color-mix(in srgb, var(--rar) 45%, transparent);
  background: color-mix(in srgb, var(--rar) 10%, transparent);
}
.escada-quanto {
  grid-area: quanto;
  display: flex; align-items: baseline; gap: 5px;
}
.escada-num {
  font-size: 24px; font-weight: 800; letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.escada-medida { font-size: 12px; color: var(--text-faint); }
.escada-estado {
  grid-area: estado; justify-self: end; text-align: right;
  font-size: 12px; color: var(--text-soft); line-height: 1.4;
}
/* A etiqueta de raridade mora no canto de cima à direita; sem esta
   reserva o estado passa por baixo dela na tela estreita. */
.escada[class*="esc-"]:not(.esc-nenhuma) .escada-estado { padding-top: 20px; }
.escada-estado b { color: var(--text); font-weight: 700; }
.escada.completa .escada-fim { color: var(--brand); }

/* A trilha. `--degraus` não é usada pelo desenho — fica no elemento para
   quem inspeciona saber quantos entalhes deveriam estar ali. */
/* Duas alturas DECLARADAS, e não porcentagens: a da subida e a da linha
   dos números. O entalhe é posicionado com a mesma `--trilha-alt` que o
   desenho usa, então os dois não têm como discordar — que foi
   exatamente o que aconteceu enquanto a conta era em porcentagem da
   caixa inteira. */
.escada-trilha {
  grid-area: trilha; position: relative;
  --trilha-alt: 34px; --num-alt: 18px;
  display: block; height: calc(var(--trilha-alt) + var(--num-alt));
  margin: 2px 9px 12px;
}
/* A trilha SOBE — ela era uma onda de dois períodos, e subir e descer
   quatro vezes não queria dizer nada. O quadro é esticado
   (`preserveAspectRatio: none`), então o traço seria esticado junto:
   `vector-effect` o mantém em pixels, que é o que faz a linha ter a
   mesma espessura em qualquer largura de tela. */
/* A subida fica na parte de CIMA; embaixo dela, a linha dos números. */
.tr-svg {
  position: absolute; top: 0; left: 0;
  width: 100%; height: var(--trilha-alt);
}
.tr-svg path {
  fill: none; stroke-linecap: round; stroke-linejoin: round;
  stroke-width: 3; vector-effect: non-scaling-stroke;
}
/* O que falta andar é PONTILHADO, como num mapa de trilha impresso. O
   traço não é esticado (`vector-effect`), então o tracejado também sai
   em pixels e fica igual em qualquer largura. */
.tr-chao { stroke: var(--border-strong); stroke-dasharray: 2 6; }
/* O andado é a MESMA curva, recortada por X no próprio desenho — ver o
   comentário de `_trilha` em `trofeus-do-mapa.js`. */
.tr-feito { stroke: var(--brand); }
/* Cada entalhe é um marco. O ganho é sólido na cor da marca; o que falta
   é um anel vazado — a mesma gramática da lacuna no mapa, onde vazado
   quer dizer "existe e não está preenchido". */
/* `--y` chega como fração (0 a 1) e é multiplicada pela altura ÚTIL — o
   quadro menos os dezoito pixels reservados aos números. Em porcentagem
   ela se resolveria contra a caixa inteira e o entalhe cairia abaixo da
   curva. */
.degrau {
  position: absolute; left: var(--x, 0%);
  top: calc(var(--y, .5) * var(--trilha-alt));
  transform: translate(-50%, -50%);
  display: block;
}
.degrau i {
  display: block; width: 11px; height: 11px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--surface);
}
.degrau.ganho i { border-color: var(--brand); background: var(--brand); }
/* O cume. O último entalhe não é mais um degrau: é onde a trilha termina,
   e um losango é a marca de cume do mapa topográfico — quina, que é o
   canto deste app, e não mais um círculo igual aos outros. */
.degrau.cume i {
  width: 13px; height: 13px; border-radius: 2px; transform: rotate(45deg);
}
/* O número é o que impede a trilha de ser lida como régua — sem ele,
   "10" e "50" à mesma distância virariam mentira. Fica numa camada à
   parte, na mesma linha de base: dentro do entalhe, a curva o levava
   para cima do traço. */
.tr-num {
  position: absolute; bottom: 0; left: var(--x, 0%);
  transform: translateX(-50%);
  font-size: 10.5px; line-height: 1;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.tr-num.ganho { color: var(--text-soft); }
/* O primeiro e o último encostam na borda: o rótulo deles alinha por
   dentro para não sair do quadro. */
.tr-num[style*="--x:0%"] { left: 0; transform: none; }
.tr-num[style*="--x:100%"] { left: auto; right: 0; transform: none; }

@media (min-width: 560px) {
  /* Com espaço, o estado volta para a mesma linha do número e a trilha
     ganha a largura inteira sem empurrar nada para baixo. */
  .escada { grid-template-columns: 132px 1fr; align-items: center;
            grid-template-areas: "quanto trilha" "quanto estado";
            row-gap: 4px; }
  .escada-quanto { align-self: center; flex-wrap: wrap; }
  .escada-estado { justify-self: start; text-align: left; }
  .escada-trilha { margin-bottom: 22px; }
  /* A ETIQUETA DESCE PARA A QUINA DE BAIXO, e o motivo é a trilha nova.
     Na tela larga a trilha sobe para a primeira linha, e agora ela TERMINA
     NO ALTO: o cume, que é o ponto mais alto do desenho, cai no canto
     direito de cima — exatamente onde a etiqueta mora. Medido a 1000px:
     colisão nos quatro cards, o losango por cima da palavra.

     Embaixo ela não disputa com nada — o estado alinha à esquerda —, e a
     reserva à direita garante isso mesmo quando ele cresce ("faltam 17
     lugares para Explorador" é o mais longo). A reserva de CIMA é a da
     tela estreita, onde a etiqueta continua no alto; aqui ela sai. */
  .escada-raridade { top: auto; bottom: 10px; }
  .escada[class*="esc-"]:not(.esc-nenhuma) .escada-estado {
    padding-top: 0; padding-right: 84px;
  }
}

/* -------------------------------------------- descobrir o que falta */
.pn-convite {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.pn-txt { flex: 1 1 260px; display: flex; flex-direction: column; gap: 2px; }
.pn-txt strong { font-size: 15px; font-weight: 700; }
.pn-txt small { font-size: 13px; color: var(--text-faint); line-height: 1.45; }
.pn-lista:empty { display: none; }
.pn-espera { margin: var(--sp-2) 0 0; font-size: 14px; color: var(--text-faint); }
.pn-grade {
  display: grid; gap: 10px; margin-top: var(--sp-2);
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
}
.pn-card {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 12px 13px;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface);
  /* Cor própria: `button` não herda a do texto, e cada motor pinta a sua
     (preto no Chromium sem `color-scheme`, azul do sistema no WebKit). */
  color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color .12s var(--ease);
}
.pn-card:hover { border-color: var(--brand); }
.pn-ico { flex: none; color: var(--brand); }
.pn-ico .ico { width: 20px; height: 20px; }
.pn-card-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pn-card-txt strong { font-size: 14px; font-weight: 700; line-height: 1.25; }
.pn-card-txt small { font-size: 12px; color: var(--text-faint); }
/* O MOTIVO da sugestão. Sem ele a lista é um punhado de nomes que a pessoa
   não sabe por que está vendo — e sugestão sem motivo é indistinguível de
   sorteio. */
.pn-perto {
  margin-top: 3px;
  font-size: 12px; font-weight: 600; color: var(--accent-txt);
}
.pn-rodape {
  margin: var(--sp-2) 0 0;
  font-size: 12px; color: var(--text-faint); line-height: 1.45;
}

/* O aviso de que "bate e volta" não pode ser prometido sem saber de onde.
   A conta de dias mede o que acontece DENTRO do roteiro — quatro paradas
   em Ametista do Sul cabem num dia. O que não cabe é chegar lá: são sete
   horas só de ida a partir de Porto Alegre. Sem a cidade de casa, o app
   para de afirmar em vez de esconder a lista. */
.rot-promessa {
  margin: 0 0 10px;
  padding: 9px 12px;
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--r);
  background: var(--surface-2);
  font-size: 12.5px; color: var(--text-soft); line-height: 1.5;
}
.rot-promessa strong { color: var(--text); }

/* --------------------------------- o roteiro sobre a silhueta do estado */
/* Terceira tentativa de dar chão ao traço, e a primeira que responde uma
   pergunta nova: ONDE, no estado, isso fica. "Maratá · Barão" não diz
   nada a quem mora em Pelotas; a mancha na metade nordeste diz tudo.

   O contorno vem do IBGE simplificado a 172 vértices (3,7 KB), guardado
   no aparelho — não muda, e é o mesmo para todo mundo. */
.ore-painel {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.ore-quadro { flex: 0 0 auto; display: block; width: 150px; }
.ore { display: block; width: 100%; height: auto; }
.ore-texto { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ore-texto strong { font-size: 15px; line-height: 1.3; }
.ore-texto small { font-size: 12px; color: var(--text-faint); }
/* O rótulo diz o que o quadro responde. Sem ele, o mapa ao lado de um
   título parece ilustração — e ilustração ninguém olha duas vezes. */
.ore-onde {
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-soft);
}
.ore-regiao { font-size: 12.5px; color: var(--text-soft); font-weight: 600; }

/* O estado: massa quieta, com a borda marcada. Ele é o CHÃO — se competir
   com o traço, some a informação que o desenho existe para dar. */
.ore-chao {
  /* A cor da LINHA usada como massa, de propósito. `--surface-2` sobre
     `--surface` dá um degrau de 2% no tema claro: a silhueta ficava um
     fantasma dentro do cartão. `--border` é o primeiro tom que se lê como
     forma nos dois temas sem virar bloco escuro. */
  fill: var(--border);
  stroke: var(--border-strong);
  stroke-width: 1.6;
  stroke-linejoin: round;
}
/* O brilho é o halo de sempre, com a cor da marca: o mesmo caminho, mais
   grosso e translúcido por baixo. Sobre o cinza do estado, o traço fino
   sozinho desaparece a 132 px de largura. */
.ore-brilho {
  fill: none; stroke: var(--brand);
  stroke-width: 9; opacity: .22;
  stroke-linecap: round; stroke-linejoin: round;
}
.ore-rota {
  fill: none; stroke: var(--brand);
  stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
}
/* A parada é terracota porque é o assunto: no desenho inteiro, é o único
   lugar para onde o olho deve ir. */
.ore-disco { fill: var(--accent); stroke: var(--surface); stroke-width: 3; }
/* As OUTRAS paradas: presentes e quietas. Elas existem para a mancha —
   "ali tem muita coisa" é informação que um marco solto não dá —, e por
   isso não competem com o laranja, que é onde o olho deve ir. */
.ore-outra {
  fill: var(--text-faint);
  stroke: var(--surface); stroke-width: 1.5;
  opacity: .85;
}
/* O anel do marco único: quando o roteiro inteiro cabe num ponto, é ele
   que dá presença ao ponto sem inventar distância entre as paradas. */
.ore-anel { fill: var(--accent); opacity: .2; }

@media (min-width: 700px) {
  /* Com espaço, o mapa cresce: a essa largura a silhueta do estado passa
     a ser reconhecível de relance, que é o trabalho dela. */
  .ore-quadro { width: 220px; }
}
@media (min-width: 1000px) {
  /* Medido na produção a 1568 px: com o mapa em 220 o painel tinha 720 de
     largura e o conteúdo parava na metade — metade de um cartão vazia lê
     como cartão mal montado. Quem cresce é o mapa, que é o assunto. */
  .ore-quadro { width: 280px; }
  .ore-texto strong { font-size: 16px; }
}

/* O chip que diz "a IA ainda está vindo".
   As propostas saem em meio segundo e a dedução leva de 2 a 25 — sem este
   carimbo, o chip "Deduzi" aparece do nada e a tela parece mudar sozinha.
   Pedido assim: "se for um loading de IA, use o ícone de carregamento, o
   usuário precisa entender isso". */
.frase-deduzindo {
  display: inline-flex; align-items: center; gap: 6px;
  opacity: .75;
}
.frase-deduzindo .spinner { width: 11px; height: 11px; border-width: 1.5px; }

/* -------------------- roteiros prontos dentro da ficha do destino */
/* Quem abriu esta ficha já escolheu o assunto; montar do zero custaria
   três decisões para chegar a uma lista que o catálogo já monta. O bloco
   some quando não há roteiro que passe por aqui — anunciar falta onde não
   havia pergunta é pior que não anunciar nada. */
.fd-roteiros { margin-top: var(--sp-4); }
.fd-roteiros-titulo { margin: 0 0 2px; font-size: 15px; }
.fd-roteiros-dica {
  margin: 0 0 4px; font-size: 12.5px; color: var(--text-faint);
}

/* ---------------------------- "montar a partir DESTE destino" */
/* A mesma cara da faixa do roteiro em espera, e de propósito: são o mesmo
   tipo de recado — "algo já foi escolhido, e falta isto". Um toast não
   serve, some em três segundos e o caminho até o roteiro tem três passos.

   Relatado por quem passou: "voltei pra tela inicial e não entendi nada:
   o wizard estava colapsado e o destino lá, mas nenhum indicativo que
   esse local estava selecionado e o que eu deveria fazer". */
.so-este {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--r);
  background: var(--brand-soft);
}
.so-este-ico { display: flex; color: var(--accent-txt); }
.so-este-ico .ico { width: 20px; height: 20px; }
.so-este-txt {
  flex: 1 1 180px; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.so-este-rotulo {
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-soft);
}
.so-este-txt strong { font-size: 14.5px; line-height: 1.25; }
.so-este-txt small { font-size: 12px; color: var(--text-faint); }
/* O que FALTA é a única linha acionável da faixa; ela não pode ler como
   legenda. Dois nomes no seletor em vez de `!important`: a folha reserva
   o `!important` para o `[hidden]`, e aqui basta ganhar de
   `.so-este-txt small`, que é 0-2-0 — este é 0-2-0 e vem depois. */
.so-este-txt .so-este-falta { color: var(--text-soft); font-weight: 600; }

/* ------------------------------------------- a parede do acervo */
/* Uma foto do acervo atrás da tela de planejar, e o miolo em VITRAL.

     "quero voltar a ideia original, de ter uma imagem de fundo transitoria
      e essa parte central de onde tem os roteiros, deixar o fundo em estilo
      vitral transparente" — e depois: "quero trazer mais destaque pra
      imagem de fundo".

   A foto de fundo já saiu daqui uma vez porque o texto ficava sobre ela e
   cada título precisou de degradê e sombra de 12 px. O vitral não repete
   aquilo: o texto fica sobre o VIDRO, uma superfície inteira de borda
   definida que desfoca o que está atrás dela. O JS só acende a foto acima
   de 1180 px.

   O DESTAQUE (1.203.0) veio de tirar o escurecimento da FOTO e pô-lo no
   VIDRO — o "spotlight reverso": só o que está atrás do texto é
   escurecido (`backdrop-filter`), e as laterais ficam com a foto inteira.
   Antes a foto toda levava `brightness(.62)` para proteger um texto que
   só existe no miolo. */
.parede {
  position: fixed; inset: 0;
  overflow: hidden; pointer-events: none;
  z-index: 0;
}
.parede:not(.tem-parede) { display: none; }
#view-new { position: relative; }
#view-new > .container { position: relative; z-index: 1; }
/* DOIS DESTINOS, UM DE CADA LADO (1.205.0).
     "volte a ideia de ter dois destinos, um de cada lado do montador [...]
      veja uma forma de nao ficar estranho a divisao dos dois destinos ao
      fundo, e garanta que o centro da imagem fique em destaque."

   Cada lado vai da sua borda até PASSAR do meio (0–58% e 42–100%), e os
   dois se sobrepõem numa faixa central de 16% da tela, onde a foto da
   direita esmaece sobre a da esquerda. Essa faixa fica sempre sob o
   vitral — ele tem 1060 px e a faixa só chega a isso numa tela de 6.600
   px —, então o desfoque transforma a emenda numa passagem de cor, e não
   numa linha no meio da tela. A da esquerda não tem máscara: é a de
   baixo, e é o que impede o fundo da página de aparecer na emenda. */
.parede-lado {
  position: absolute; top: 0; bottom: 0;
  overflow: hidden;
}
.parede-esq { left: 0; width: 58%; }
.parede-dir {
  left: 42%; right: 0;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 27.6%);
  mask-image: linear-gradient(to right, transparent 0%, #000 27.6%);
}
.parede-foto {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(1.15);
  opacity: 0;
  transition: opacity 1.4s var(--ease);
  /* O enquadramento é do JS (`posicao()`): o ponto de foco da foto cai no
     centro da margem VISÍVEL do seu lado, e não no meio da caixa, que é
     onde o vidro cobre. O zoom lento cresce a partir desse ponto
     (`transform-origin` também vem do JS), então o assunto fica parado no
     centro da margem enquanto o resto da foto se move em volta. */
  animation: parede-zoom 24s linear forwards;
  will-change: transform, opacity;
}
@keyframes parede-zoom {
  from { transform: scale(1.1); }
  to   { transform: scale(1); }
}
/* Enquadrada pelo JS, a foto tem tamanho e lugar exatos (a proporção é a
   dela): o `cover` e o `inset` eram só o primeiro quadro, antes da conta. */
.parede-foto.enquadrada { right: auto; bottom: auto; object-fit: fill; }
/* A primeira de cada lado entra sozinha; as seguintes, quando `_trocar`
   as acende. */
.parede-foto:first-child, .parede-foto.entrou { opacity: 1; }

/* O VITRAL. A opacidade não é gosto: é o pior caso, calculado.

     "as imagens estão aparecendo pouco ainda, dá mais destaque"

   Três tokens se amarram: o filtro que o vidro aplica à foto de trás, a
   opacidade do vidro e a cor do texto sobre ele. O texto era `--text-soft`
   puro, e cinza médio só se lê sobre fundo quase liso — o vidro precisava
   de 55–70% e a foto aparecia como uma sombra. Com o texto a 80% da cor
   principal (`--vitral-texto`), o vidro desce a 30% (escuro) e 32%
   (claro), e o que se vê da foto através dele DOBRA: de 48 para 97 níveis
   de brilho. A hierarquia fica com tamanho e peso, que já carregavam.

   A conta é a mesma de antes: o pior pixel que o filtro deixa passar
   (0–128 no escuro, 115–255 no claro), composto sob o vidro, contra o
   texto — pelo menos 4,5:1. O teste refaz a conta a partir destes tokens.
   Ela vale por PIXEL, e é por isso que o desfoque pôde cair para 10 px: a
   foto volta a ter forma atrás do vidro sem mexer no contraste.
   Os painéis de dentro continuam sólidos: o vidro é o chão da coluna. */
.parede.tem-parede ~ .container {
  --text-soft: var(--vitral-texto);
  --text-faint: var(--vitral-texto);
  background: color-mix(in srgb, var(--bg) var(--vitral), transparent);
  -webkit-backdrop-filter: blur(10px) var(--vitral-filtro) saturate(1.3);
  backdrop-filter: blur(10px) var(--vitral-filtro) saturate(1.3);
  border-left: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
  min-height: calc(100vh - 60px);
  padding-bottom: var(--sp-5);
}

/* O NOME DO LUGAR — em etiqueta sólida, no rodapé da margem do seu lado.
   Só onde a margem cabe a etiqueta inteira: (largura − 1060) / 2 tem de
   dar 220 px, e isso é 1500 px de tela. Mais estreito, ela cobriria o
   miolo — e aí some, em vez de encolher até virar reticências. */
.parede-nome {
  position: absolute; bottom: 16px;
  width: min(260px, calc((100vw - 1060px) / 2 - 32px));
  z-index: 1;
  display: none; flex-direction: column; gap: 1px;
  padding: 8px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
  background: var(--surface);
  text-align: left; cursor: pointer;
  pointer-events: auto;
  font: inherit;
}
.parede-esq .parede-nome { left: 16px; }
.parede-dir .parede-nome { right: 16px; }
@media (min-width: 1500px) { .parede-nome { display: flex; } }
/* Durante a troca, duas etiquetas convivem por um instante no mesmo lado:
   só a última (a da foto que está entrando) aparece. */
.parede-lado .parede-nome:not(:last-child) { visibility: hidden; }
.parede-nome:hover { border-color: var(--brand); }
.parede-nome strong {
  font-size: 12.5px; font-weight: 700; line-height: 1.25;
  color: var(--text);
}
.parede-nome small { font-size: 11px; color: var(--text-faint); }

@media (prefers-reduced-motion: reduce) {
  .parede-foto { transition: none; animation: none; transform: none; }
}

/* ------------------------------------- a parada de refeição no roteiro */
/* Ela existia e era linha morta: dizia "Refeição (Lunch)" e não dava para
   fazer nada com ela. Ganhou as duas alavancas que faltavam — o tempo,
   que REFAZ o roteiro, e a busca de onde comer ali perto. */
.ha-caixa {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px 10px;
  margin: 8px 0 2px;
}
.ha-tempo {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--text-faint);
}
.ha-select, .ha-hora { font-size: 12.5px; padding: 5px 8px; min-height: 34px; }
.ha-onde { font-size: 12.5px; padding: 6px 11px; }
/* A lista ocupa a linha inteira: nomes de restaurante são longos, e ao
   lado do botão eles quebrariam em duas palavras por linha. */
.ha-lista { flex: 1 0 100%; }
.ha-titulo, .ha-vazio, .ha-fonte {
  display: block; font-size: 11.5px; color: var(--text-faint);
}
.ha-titulo { margin-bottom: 6px; }
/* A procedência fica escrita: o catálogo foi curado, o OpenStreetMap é
   cru. Misturar sem dizer qual é qual daria ao segundo a autoridade do
   primeiro. */
.ha-fonte { margin-top: 7px; line-height: 1.45; }
/* A saída quando não há lista: link, não botão — não é o gesto principal
   desta tela, e um segundo terracota ao lado de "Onde comer por perto"
   seria nenhum. Cresce para o dedo no bloco de `hover: none`. */
.ha-saida {
  display: inline-block; margin-top: 8px;
  font-size: 12px; color: var(--text-soft);
  text-decoration: underline; text-underline-offset: 3px;
}
.ha-saida:hover { color: var(--brand); }
.ha-saida .ico { width: 13px; height: 13px; vertical-align: -2px; }
.ha-vazio + .ha-saida { margin-top: 6px; }
.ha-itens { display: flex; flex-direction: column; gap: 1px; }
.ha-item {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  padding: 9px 10px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface);
  text-decoration: none; color: inherit;
}
.ha-item + .ha-item { border-top-color: var(--border); }
.ha-item:hover { border-color: var(--border-strong); }
.ha-item strong { font-size: 12.5px; font-weight: 600; }
.ha-item small {
  font-size: 11px; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------- "Meus registros" */
/* RECOLHIDO por padrão. Dito na tela, com 183 registros dentro: "fica uma
   lista imensa e aparentemente bagunçada". Ela é a última coisa da página
   e a mais alta — aberta, empurra para fora o acervo, o mapa e o "perto e
   novo", e quem rola até o fim rola 183 linhas para chegar ao rodapé. */
.vs-cabeca { margin: 0; }
.vs-abrir {
  display: flex; align-items: center; gap: 8px;
  width: 100%; min-height: 44px;
  padding: 4px 0; border: 0; background: none;
  font: inherit; color: inherit; text-align: left;
  cursor: pointer;
}
.vs-abrir-seta {
  flex: none; transition: transform .18s var(--ease);
  color: var(--text-faint);
}
.vs-abrir[aria-expanded="true"] .vs-abrir-seta { transform: rotate(180deg); }
/* O número fica no botão: a pessoa sabe o tamanho da lista sem abri-la. */
.vs-abrir-n {
  margin-left: auto;
  font-size: 12px; font-weight: 700;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.vs-corpo { padding-top: 4px; }

/* A busca: com 183 linhas, achar pelo nome é rolar — e achar é o primeiro
   passo para corrigir. Registro errado que ninguém acha continua mentindo
   no mapa. Campo e lupa na mesma moldura: dois controles soltos lado a
   lado leem como dois controles.

   `reg-` E NÃO `vs-`: `.vs-busca` já existe cinco mil linhas acima, e é a
   busca da árvore do catálogo. Reaproveitar o nome trouxe o
   `flex-wrap: wrap` de lá para cá, e a lupa foi parar numa linha própria
   em cima do campo — medido na tela, não no grep. */
.reg-busca {
  display: flex; align-items: center; gap: 7px;
  margin-top: 8px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface);
}
/* O anel de foco é do CONJUNTO, não do campo: a folha põe `--ring` em
   todo `input:focus-visible`, e dentro desta moldura ele desenhava uma
   segunda borda por dentro da primeira. Quem recebe o foco continua
   sendo anunciado — só que a marca aparece no controle inteiro. */
.reg-busca:focus-within {
  border-color: var(--brand); box-shadow: var(--ring);
}
.reg-busca-ico { flex: none; color: var(--text-faint); }
/* DOIS nomes no seletor, de propósito: a folha tem uma regra
   `input[type="search"], select, textarea` com largura, borda e recheio
   próprios, e ela tem especificidade 0-1-1. Uma classe sozinha (0-1-0)
   perde — o campo continuava com moldura e recheio dentro da moldura. */
.reg-busca .reg-busca-campo {
  flex: 1 1 auto; width: auto; min-width: 0;
  border: 0; background: none; padding: 10px 0;
  font: inherit; color: var(--text);
}
.reg-busca .reg-busca-campo:focus,
.reg-busca .reg-busca-campo:focus-visible {
  outline: none; border: 0; box-shadow: none;
}
/* Vazio sem explicação parece quebrado — e aqui ele SEMPRE tem
   explicação, porque só fica vazio por causa de um controle. */
.vs-nada {
  margin: 10px 0 2px;
  font-size: 12.5px; color: var(--text-faint);
}

/* ------------------------------------------- filtro dos registros */
.vs-filtros {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 10px 0 4px;
}
.vs-filtro { font-size: 12.5px; padding: 6px 12px; }
.vs-filtro-n {
  font-size: 11px; font-weight: 700; opacity: .7;
  font-variant-numeric: tabular-nums;
}
/* Mais respiro entre registros: a linha tinha a altura do botão de remover
   e nada em volta, e 181 delas viravam uma parede. */
.vs-reg { padding-block: 11px; }

/* A LINHA ACESA, quando a busca traz alguém até ela.
   "não aconteceu nada" era isto: o clique trocava de tela e parava, com o
   registro a três blocos de rolagem dentro de uma lista recolhida.
   Acender é o que diz "é esta aqui". Borda, e não fundo forte: a linha
   continua legível, e o texto não muda de cor no meio da leitura. */
.vs-reg-achado {
  outline: 2px solid var(--brand);
  outline-offset: -2px;
  border-radius: var(--r);
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}
/* O lápis recebe o foco na chegada: é onde a próxima ação está, e foi a
   segunda metade da queixa ("nem sei onde é"). */
.vs-reg-achado .vs-reg-fix {
  border-color: var(--brand);
  color: var(--brand);
}

/* ============================================================
   O mapa repaginado (1.266.0).

     "tá tudo muito quadradão, parece simples demais, cara de layout
      padrão [...] sem nenhum capricho" (19/10/2026)

   Nesta tela o dono pediu, com essas palavras, para sair da quina de 4px:
   cartão com 14px, controle com 10px. O painel fica em `--bg` e os
   cartões em `--surface` — superfícies em camadas, sombra curta — e a cor
   de cada dia (`OsDiasNoMapa.cor`, via `--dia`) costura a lista ao mapa.
   Só desenho: a altura dos alvos continua sendo do bloco do dedo.
   ============================================================ */
#view-map, .dm { --mr-cartao: 14px; --mr-ctl: 10px; }
#map-side-panel { background: var(--bg); }

/* O catálogo no mapa: um cartão, com interruptores no lugar das caixinhas. */
#map-side-panel .mapa-legenda {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--mr-cartao); box-shadow: var(--shadow-sm);
  padding: 12px 16px; margin-bottom: 18px;
}
#map-side-panel .mapa-legenda-liga { flex-direction: row-reverse; justify-content: space-between; gap: 12px; padding: 6px 0; margin: 0; }
#map-side-panel .mapa-legenda-liga input {
  -webkit-appearance: none; appearance: none; flex: none; margin: 0; position: relative;
  width: 38px; height: 22px; border-radius: 11px; background: var(--border-strong);
  cursor: pointer; transition: background .15s ease;
}
#map-side-panel .mapa-legenda-liga input::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--surface); box-shadow: 0 1px 2px rgba(0, 0, 0, .35); transition: transform .15s ease;
}
#map-side-panel .mapa-legenda-liga input:checked { background: var(--brand); }
#map-side-panel .mapa-legenda-liga input:checked::after { transform: translateX(16px); }
#map-side-panel .mapa-legenda-liga input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
#map-side-panel .mc-tipos { border-top: 1px solid var(--border); margin: 6px 0 0; padding-top: 4px; }

/* O cabeçalho da viagem e as ações dela. */
#itinerary-panel > h3 { font-size: 22px; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; margin: 4px 0 12px; text-wrap: balance; }
#map-side-panel .btn { border-radius: var(--mr-ctl); }
#map-side-panel .btn.ghost { background: var(--surface-2); border-color: transparent; color: var(--text); }
#map-side-panel .btn.ghost:hover:not(:disabled) { border-color: var(--border-strong); }
#map-side-panel .te-salvar {
  background: var(--surface); border-color: var(--border); border-radius: var(--mr-cartao);
  box-shadow: var(--shadow-sm); gap: 8px;
}
#map-side-panel .warn-box, #map-side-panel .conta { border-radius: var(--mr-cartao); }

/* Os números da viagem: uma faixa só, e não quatro azulejos. */
#map-side-panel .summary-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; overflow: hidden;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--mr-cartao); box-shadow: var(--shadow-sm);
}
#map-side-panel .summary-grid .kpi { background: none; border: 0; border-radius: 0; padding: 12px 4px; }
#map-side-panel .summary-grid .kpi + .kpi { border-left: 1px solid var(--border); }
#map-side-panel .summary-grid .kpi strong { font-size: 17px; white-space: nowrap; }
#map-side-panel .summary-grid .kpi span { font-size: 10px; letter-spacing: .07em; }

/* O dia: gruda no alto enquanto a lista dele passa, com a cor do mapa. */
#map-side-panel .day-head {
  position: sticky; top: 0; z-index: 6; align-items: center;
  background: var(--bg); margin: 26px -20px 10px; padding: 12px 20px 10px;
}
#map-side-panel .day-head h4 { display: flex; align-items: center; gap: 10px; font-size: 16px; font-weight: 800; letter-spacing: -.01em; }
#map-side-panel .day-head h4::before {
  content: ""; flex: none; width: 10px; height: 10px; border-radius: 50%;
  background: var(--dia, var(--brand));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--dia, var(--brand)) 28%, transparent);
}
/* No telefone quem rola é a página, sob a barra de cima: grudado, o dia sumiria atrás dela. */
@media (max-width: 899px) { #map-side-panel .day-head { position: static; } }
#map-side-panel .dgm { border-radius: var(--mr-ctl); background: var(--surface); border: 1px solid var(--border); }

/* As paradas: cada uma um cartão, presas à linha do dia. */
#map-side-panel .timeline::before { background: color-mix(in srgb, var(--dia, var(--brand)) 40%, var(--border)); }
#map-side-panel .timeline > .stop:not(.ev-no-dia) {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 10px 12px 11px; margin-bottom: 10px; box-shadow: var(--shadow-sm);
}
#map-side-panel .timeline > .stop::before { top: 15px; left: -20px; }
#map-side-panel .timeline > .stop.poi::before { background: var(--dia, var(--brand)); }
#map-side-panel .timeline > .stop > .aap-btn { right: 6px; top: 6px; }
#map-side-panel .timeline > .stop.poi > .stop-ordem { right: 44px; top: 8px; }
#map-side-panel .stop-ordem button { border-radius: 8px; }
#map-side-panel .od { border-radius: 12px; background: var(--surface); }

/* Os controles sobre o mapa: objetos que flutuam, não caixas coladas. */
.leaflet-container .leaflet-bar {
  border-radius: var(--mr-ctl, 10px); overflow: hidden;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .22); border: 1px solid var(--border);
}
.leaflet-container .leaflet-control.dm-dias,
.leaflet-container .sn-legenda:not(.sn-desligada) {
  border-radius: var(--mr-cartao, 14px); border: 1px solid var(--border);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .24);
}
.leaflet-container .leaflet-control.dm-dias .dm-select { border-radius: var(--mr-ctl, 10px); }
.leaflet-container .sn-ligar { border-radius: var(--mr-ctl, 10px); box-shadow: 0 4px 14px rgba(0, 0, 0, .22); }
.dm { border-radius: var(--mr-ctl); padding: 3px; gap: 2px; border-color: var(--border); box-shadow: 0 4px 14px rgba(0, 0, 0, .22); }
.dm .dm-btn { border-left: 0; border-radius: 8px; }
.dm-pop .bp-casca { border-radius: var(--mr-cartao, 14px); box-shadow: var(--shadow-lift); }
.dm-pop .bp-foto { border-radius: 10px; }

/* Os pontos do catálogo como pinos (`os-pinos-do-catalogo.js`). A gota é
   um quadrado girado com uma quina viva: a ponta cai no lugar exato. */
.leaflet-marker-icon.cg-pino { background: none; border: 0; }
.cg-disco {
  position: absolute; left: 0; top: 0; box-sizing: border-box;
  display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  background: var(--surface); color: var(--text-soft);
  border: 1.5px solid var(--border-strong);
  box-shadow: 0 2px 5px rgba(0, 0, 0, .35); cursor: pointer;
  transition: transform .12s ease;
}
.cg-disco > svg, .cg-disco > .ico { width: 14px; height: 14px; transform: rotate(45deg); }
.leaflet-marker-icon.cg-pino:hover .cg-disco { transform: rotate(-45deg) scale(1.15); }
.cg-topo .cg-disco {
  width: 34px; height: 34px; background: var(--warn); color: var(--surface);
  border: 2px solid var(--surface); box-shadow: 0 3px 8px rgba(0, 0, 0, .4);
}
.cg-topo .cg-disco > svg, .cg-topo .cg-disco > .ico { width: 17px; height: 17px; }
.cg-disco .cg-estrela {
  position: absolute; top: -7px; right: -7px; display: grid; place-items: center;
  width: 16px; height: 16px; border-radius: 50%; transform: rotate(45deg);
  background: var(--surface); color: var(--warn); box-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}
.cg-estrela svg, .cg-estrela .ico { width: 11px; height: 11px; }

/* "Imperdíveis a até 25 km": o top 20 perto das paradas, para pôr no roteiro. */
.cg-imperdiveis { border-top: 1px solid var(--border); margin-top: 8px; padding-top: 12px; }
.cg-imperdiveis h4 { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 800; margin: 0; }
.cg-imperdiveis h4 .cg-estrela { color: var(--warn); display: inline-flex; }
.cg-imperdiveis h4 .cg-estrela svg, .cg-imperdiveis h4 .cg-estrela .ico { width: 15px; height: 15px; }
.cg-imperdiveis > small { display: block; color: var(--text-soft); font-size: 12px; margin: 2px 0 8px; }
.cg-imperdiveis ul { list-style: none; margin: 0 -6px; padding: 0; display: grid; gap: 2px; }
.cg-item {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: 10px;
  width: 100%; padding: 6px; border: 0; border-radius: var(--mr-ctl, 10px);
  background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.cg-item:hover { background: var(--surface-2); }
.cg-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cg-item img, .cg-sem-foto { width: 44px; height: 44px; border-radius: 8px; object-fit: cover; display: block; }
.cg-sem-foto { display: grid; place-items: center; background: var(--surface-2); color: var(--text-faint); }
.cg-sem-foto svg, .cg-sem-foto .ico { width: 18px; height: 18px; }
.cg-txt { display: grid; min-width: 0; }
.cg-txt strong { font-size: 13.5px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cg-txt small { font-size: 12px; color: var(--text-soft); }
.cg-ir {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px;
  background: var(--brand-soft); color: var(--brand);
}
.cg-ir svg, .cg-ir .ico { width: 15px; height: 15px; }

/* ============================================================
   Meus Lugares repaginado (1.267.0).

   A mesma régua do mapa do roteiro (1.266.0): cartão com 14px, controle
   com 10px, superfícies em camadas. A tela vira três faixas — o gesto no
   cabeçalho, o placar (patente, álbum e recompensas, cada um com o fio de
   quanto falta) e o mapa no centro com o sumário do nível ao lado, que
   desce para baixo dele quando falta largura.
   ============================================================ */
#view-visited { --mr-cartao: 14px; --mr-ctl: 10px; }
#view-visited .container.ml { max-width: 1240px; }
#view-visited .panel { border-radius: var(--mr-cartao); }
/* O quadro sem número nenhum era uma caixa vazia no fim da tela. */
#view-visited .panel:has(> #visited-stats:empty) { display: none; }

#view-visited .ml-cabeca { max-width: none; }
.ml-cabeca { display: flex; align-items: flex-end; justify-content: space-between; flex-wrap: wrap; gap: 12px 24px; }
.ml-cabeca > div { flex: 1 1 280px; min-width: 0; }
.ml-cabeca #vs-vazio:not(:empty) { margin: 14px 0 0; }
#view-visited .ml-registrar { flex: none; border-radius: var(--mr-ctl); font-size: 15px; padding: 12px 22px;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 30%, transparent); }
@media (max-width: 599px) { #view-visited .ml-registrar { width: 100%; } }

/* O placar. */
.ml-placar { display: grid; gap: 12px; margin-bottom: 18px; }
.ml-placar > div { min-width: 0; }
.ml-placar #acervo-corpo { order: 4; }
.ml-placar .acv-linha, .ml-placar .alb, .ml-placar .loja { margin: 0; }
.ml-placar .acv-faixa, .ml-placar .alb, .ml-placar .loja, .ml-placar .acv-partilha {
  border: 1px solid var(--border); border-radius: var(--mr-cartao);
  background: var(--surface); box-shadow: var(--shadow-sm);
}
/* Patente: brasão e nome em cima, o fio com a conta embaixo. O
   compartilhar entra na quina do cartão — ao lado, ele espremia o nome
   até "Pé ...". */
.ml-placar .acv-linha { position: relative; }
.ml-placar .acv-faixa {
  display: grid; grid-template-columns: 36px minmax(0, 1fr) auto;
  grid-template-areas: "b q m" "f f c"; align-items: center; gap: 10px 12px; padding: 12px 62px 12px 14px;
}
.ml-placar .acv-partilha { position: absolute; top: 8px; right: 8px; width: 44px; height: 44px; min-width: 0;
  border-radius: var(--mr-ctl); box-shadow: none; }
.ml-placar .acv-conta { display: flex; align-items: baseline; gap: 6px; text-align: left; }
.ml-placar .acv-conta b { display: inline; font-size: 15px; }
.ml-placar .acv-faixa:hover, .ml-placar .alb:hover, .ml-placar .loja:hover { border-color: var(--border-strong); }
.ml-placar .acv-brasao { grid-area: b; width: 36px; height: 36px; border-radius: var(--mr-ctl); }
.ml-placar .acv-quem { grid-area: q; }
.ml-placar .acv-conta { grid-area: c; }
.ml-placar .acv-mais { grid-area: m; }
/* O "Ver acervo" espremia o nome até "Pé na ...": o cartão inteiro é o
   botão, como os do álbum e das recompensas. Aberto, o "Recolher" fica. */
.ml-placar .acv-faixa:not(.acv-aberta) .acv-mais { display: none; }
.ml-placar .acv-fio { grid-area: f; position: static; height: 6px; border-radius: 3px; overflow: hidden; }
.ml-placar .acv-fio i { border-radius: 3px; }
.ml-placar .alb-faixa { grid-template-columns: 36px minmax(0, 1fr); gap: 10px 12px; padding: 12px 14px; min-height: 0; }
.ml-placar .alb-fio { grid-column: 1 / -1; }
.ml-placar .alb-ico, .ml-placar .loja-ico { border-radius: var(--mr-ctl); }
.ml-placar .loja-faixa { display: grid; grid-template-columns: 36px minmax(0, 1fr); align-items: center; gap: 10px 12px; padding: 12px 14px; }
.loja-fio { grid-column: 1 / -1; display: block; height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.loja-fio i { display: block; height: 100%; border-radius: 3px; background: var(--warn); }
/* No tablet a patente ocupa a linha (três colunas de 237px a quebravam
   em "PATENTE / 2 / DE / 5"), e álbum e recompensas dividem a de baixo. */
@media (min-width: 760px) {
  .ml-placar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ml-placar #acervo-faixa { grid-column: 1 / -1; }
}
@media (min-width: 1100px) {
  .ml-placar { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ml-placar #acervo-faixa { grid-column: auto; }
}
@media (min-width: 760px) {
  /* O que abre ocupa a linha inteira, embaixo dos três. */
  .ml-placar #acervo-corpo, .ml-placar > div:has(> details[open]) { grid-column: 1 / -1; order: 4; }
  .ml-placar .acv-linha, .ml-placar .alb, .ml-placar .loja { height: 100%; }
}

/* O mapa no centro e o sumário ao lado. */
.ml-grade { display: grid; gap: 16px; }
.ml-centro { min-width: 0; display: grid; gap: 12px; align-content: start; }
.ml-centro .diario-trilha { margin: 0; }
/* As caixas de aviso vazias não pagam o vão da grade. */
.ml-centro > :empty { display: none; }
.ml-centro .pn-convite { margin: 0; border-radius: var(--mr-cartao); }
.ml-mapa { position: relative; margin: 0; box-shadow: var(--shadow-sm); }
/* O zoom (1000) e o alternador (1001) passavam por cima da barra do alto
   ao rolar a página: o quadro do mapa agora é um andar só. */
.dm-hospeda, .leaflet-container { isolation: isolate; }
@media (min-width: 1100px) {
  .ml-grade { grid-template-columns: minmax(0, 1fr) 340px; gap: 20px; align-items: start; }
  .ml-lado { position: sticky; top: calc(var(--topbar-h) + 16px); }
  .ml-mapa .mapa-do-diario { height: clamp(460px, 64vh, 640px); }
}

/* Os filtros flutuantes (`os-filtros-do-diario.js`) e a legenda que um deles abre. */
.ml-filtros {
  position: absolute; left: 10px; bottom: 10px; z-index: 3; display: flex; gap: 4px; padding: 4px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--mr-ctl);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .22);
}
.ml-filtro {
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border: 0; border-radius: 8px;
  background: none; color: var(--text-soft); font: 600 13px/1 var(--sans); cursor: pointer; white-space: nowrap;
}
.ml-filtro .ico { width: 16px; height: 16px; }
.ml-filtro:hover { color: var(--text); }
.ml-filtro[aria-pressed="true"] { background: var(--brand); color: var(--brand-text); }
.ml-filtro:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ml-sem-missoes .mv-fronteira { display: none; }
.ml-legenda {
  position: absolute; left: 10px; bottom: 62px; z-index: 2;
  max-width: min(380px, calc(100% - 20px)); max-height: calc(100% - 130px); overflow-y: auto;
  padding: 10px 12px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--mr-cartao); box-shadow: 0 6px 20px rgba(0, 0, 0, .24);
}
.ml-legenda:empty, .ml-sem-legenda .ml-legenda { display: none; }
.ml-legenda .vs-legend { margin: 0; gap: 6px 10px; }

/* O sumário do nível (`o-sumario-do-mapa.js`). */
.sm { background: var(--surface); border: 1px solid var(--border); border-radius: var(--mr-cartao);
  box-shadow: var(--shadow-sm); padding: 16px; }
.sm-cabeca h3 { margin: 0; font-size: 17px; font-weight: 800; letter-spacing: -.01em; text-wrap: balance; }
.sm-cabeca small { display: block; margin: 2px 0 10px; font-size: 12.5px; color: var(--text-soft); }
.sm-fio { display: block; height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.sm-fio i { display: block; height: 100%; border-radius: 3px; background: var(--brand); }
.sm-busca { display: flex; align-items: center; gap: 8px; margin: 14px 0 10px; padding: 0 12px;
  border: 1px solid var(--border-strong); border-radius: var(--mr-ctl); background: var(--bg); }
.sm-busca:focus-within { border-color: var(--brand); box-shadow: var(--ring); }
.sm-busca .ico { flex: none; width: 16px; height: 16px; color: var(--text-faint); }
.sm-busca input[type="search"], .sm-busca input[type="search"]:focus {
  flex: 1; min-width: 0; margin: 0; padding: 10px 0; border: 0; background: none; box-shadow: none; outline: none;
  color: var(--text); font: inherit; font-size: 14px;
}
.sm-filtros { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.sm-lista { list-style: none; margin: 0 -8px; padding: 0; display: grid; gap: 2px; max-height: 26rem; overflow-y: auto; }
.sm-item {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "n p" "f f";
  align-items: center; gap: 6px 10px; width: 100%; padding: 9px 8px; border: 0; border-radius: var(--mr-ctl);
  background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.sm-item:hover { background: var(--surface-2); }
.sm-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.sm-nome { grid-area: n; display: grid; min-width: 0; }
.sm-nome strong { font-size: 14px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sm-nome small { font-size: 12px; color: var(--text-soft); }
.sm-pct { grid-area: p; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text-soft); }
.sm-sim .sm-pct { color: var(--brand); }
.sm-item .sm-fio { grid-area: f; height: 4px; }
.sm-item:not(.sm-sim) .sm-fio i { background: var(--text-faint); }
.sm-nada { padding: 12px 8px; font-size: 13px; color: var(--text-soft); }

/* ============================================================
   O Mutirão do Maps (1.268.0) — os inativos lidos no Maps, revisados em lote.
   Cartão: a capa escolhida à esquerda, o que o Maps disse à direita, as
   outras fotos embaixo para trocar com um toque.
   ============================================================ */
.mt-placar { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: center;
  margin: var(--sp-3) 0 0; font-size: 14px; color: var(--text-soft); }
.mt-placar strong { color: var(--text); font-variant-numeric: tabular-nums; }
.mt-aguarda { margin: var(--sp-3) 0 0; }
.mt-abrir[aria-disabled="true"] { opacity: .55; cursor: progress; }
.mt-lote { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-bottom: var(--sp-2); }
/* A folha põe `select` em bloco e na largura toda; aqui ele cabe no "80 lugares". */
#mutirao-do-maps .mt-tamanho { display: inline-block; width: auto; min-width: 0; flex: 0 0 auto; }
.mt-abas { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-4) 0 var(--sp-3); }
.mt-aba[aria-selected="true"] { background: var(--brand); border-color: var(--brand); color: var(--brand-text); }
.mt-aba[aria-selected="true"] small { color: var(--brand-text); }
.mt-aba small { margin-left: 4px; font-variant-numeric: tabular-nums; color: var(--text-soft); }
.mt-lote-acao:not(:empty) { margin-bottom: var(--sp-3); display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
/* Ativar e Excluir rolam junto, presos embaixo da barra do topo: marcava-se
   um cartão lá embaixo e era preciso subir a tela inteira para agir. */
.mt-lote-acao:not(:empty) {
  position: sticky; top: calc(var(--topbar-h) + var(--safe-topo)); z-index: 4;
  background: var(--surface); padding: var(--sp-2) 0; border-bottom: 1px solid var(--border);
}
.mt-marcar { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; font-size: 14px;
  color: var(--text-soft); cursor: pointer; justify-self: start; }
.mt-marcar input { width: 20px; height: 20px; min-height: 0; margin: 0; accent-color: var(--brand); }
.mt-cartoes { display: grid; gap: var(--sp-3); }
.mt-cartao { display: grid; grid-template-columns: minmax(0, 240px) minmax(0, 1fr); gap: var(--sp-3);
  padding: var(--sp-3); border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface); }
/* `aspect-ratio` no pai não segura filho com height:100% — a imagem vai absoluta. */
.mt-capa { position: relative; aspect-ratio: 4 / 3; border-radius: var(--r); overflow: hidden;
  background: var(--surface-2); display: grid; place-items: center; }
.mt-capa img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.mt-sem-capa { font-size: 13px; color: var(--text-soft); padding: var(--sp-2); text-align: center; }
.mt-corpo { min-width: 0; display: grid; gap: 6px; align-content: start; }
.mt-corpo h4 { margin: 0; font-size: 16px; font-weight: 700; }
.mt-onde, .mt-endereco { margin: 0; font-size: 13px; color: var(--text-soft); overflow-wrap: anywhere; }
.mt-endereco svg { width: 14px; height: 14px; vertical-align: -2px; }
.mt-motivos { margin: 0; padding-left: 1.2em; font-size: 13px; color: var(--text); }
.mt-ia { margin: 0; }
.mt-desc { display: flex; flex-direction: column; gap: var(--sp-1); font-size: 13px; font-weight: 600; color: var(--text); }
.mt-desc textarea { width: 100%; font-family: inherit; font-size: 14px; font-weight: 400; line-height: 1.45; resize: vertical; }
.mt-desc + .field-hint, .mt-desc-ficha { margin: 0; }
.mt-busca { display: flex; gap: var(--sp-2); margin: var(--sp-3) 0 var(--sp-1); }
#mutirao-do-maps .mt-busca select { flex: 0 0 auto; width: auto; }
#mutirao-do-maps .mt-busca input { flex: 1 1 0; min-width: 0; }
.mt-achados { margin: 0 0 var(--sp-2); }
.mt-achados:empty { display: none; }
/* ============================================================
   Vídeos do YouTube na ficha do destino (1.272.0) — a miniatura primeiro,
   o player só no toque (`video-do-youtube.js`). A mesma regra existe em
   `noticias.html`, que não carrega esta folha.
   ============================================================ */
.fd-videos { margin-top: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-2); }
.fd-videos-titulo { display: flex; align-items: center; gap: var(--sp-2); margin: 0; }
.yt-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--sp-3); }
.yt-video { margin: 0; display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.yt-fachada, .yt-player { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; padding: 0;
  border-radius: var(--r); overflow: hidden; background: var(--surface-2); color: var(--text); cursor: pointer; }
.yt-vertical .yt-fachada, .yt-vertical .yt-player { aspect-ratio: 9 / 16; max-height: 70vh; }
.yt-fachada img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.yt-play { position: absolute; left: 50%; top: 50%; width: 56px; height: 40px; transform: translate(-50%, -50%);
  border-radius: var(--r-lg); background: rgba(0, 0, 0, .72); }
.yt-play::after { content: ""; position: absolute; left: 23px; top: 12px; border-style: solid;
  border-width: 8px 0 8px 14px; border-color: transparent transparent transparent #fff; }
.yt-fachada:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.yt-video figcaption { display: flex; flex-direction: column; gap: 2px; font-size: 13px; color: var(--text-soft); }
.yt-video figcaption strong { color: var(--text); font-size: 14px; line-height: 1.3; }
.yt-video figcaption a { color: var(--text-soft); }
.yt-tirar { align-self: flex-start; margin-top: var(--sp-1); }
.yt-colar { display: flex; gap: var(--sp-2); }
.yt-colar input { flex: 1 1 0; min-width: 0; }

.mt-sugestao { font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-soft); }
.mt-sugestao.mt-pronto { color: var(--ok); }
.mt-sugestao.mt-olho { color: var(--warn); }
.mt-sugestao.mt-excluir { color: var(--danger); }

/* ============================================================
   Importar um estado (1.270.0) — seis passos, o próximo aceso.
   ============================================================ */
.ie-escolha { display: flex; align-items: center; gap: var(--sp-2); font-weight: 600; margin: var(--sp-3) 0; }
#importacao-do-estado .ie-estado { flex: 1 1 0; min-width: 0; width: auto; }
.ie-passos { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); counter-reset: ie; }
.ie-passo { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3); border: 1px solid var(--border); border-radius: var(--r); counter-increment: ie; }
.ie-passo.ie-atual { border-color: var(--brand); }
.ie-texto { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; flex: 1 1 240px; }
.ie-texto strong::before { content: counter(ie) ". "; color: var(--text-soft); }
.ie-texto .field-hint { margin: 0; }
.ie-agora { font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--brand); }
.mt-miudas { display: flex; flex-wrap: wrap; gap: 6px; }
.mt-miuda { width: 72px; height: 54px; padding: 0; border: 2px solid transparent; border-radius: var(--r);
  overflow: hidden; background: var(--border); cursor: pointer; }
.mt-miuda img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mt-miuda[aria-pressed="true"] { border-color: var(--accent); }
.mt-miuda.mt-fora img { opacity: .4; }
.mt-botoes { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: 4px; }
@media (max-width: 599px) {
  .mt-cartao { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   O DEDO — por último, de propósito.

   Este bloco já esteve no meio da folha, e não valia nada: `.btn` e
   `input, select` redeclaram `min-height: 38px` mais abaixo, com a MESMA
   especificidade, e regra empatada que vem depois ganha. O arquivo dizia
   44px, o navegador media 38, e o teste que lia o fonte dizia que estava
   feito.

   Fica no fim da folha porque é a última palavra sobre tamanho de alvo. O
   que vier depois disto tem de ser deliberado.
   ============================================================ */
/* O dedo, no app inteiro.
   A tela de entrada foi a primeira a ser medida; depois entrei com sessão e
   medi as dez telas de dentro, a 375px. O resultado não era um botão
   pequeno: era quase todo botão. Catálogo, 36 de 39 alvos abaixo de 44px;
   registro de lugares, 24 de 24; referências, 25 de 27. Chip de filtro em
   36, seletor em 38, campo em 34, o hambúrguer em 38 e o perfil em 36 —
   os dois controles que a mão usa o tempo todo.

   Erro de toque não dá erro: dá outra tela, outro filtro, outra lista. A
   pessoa não sabe que errou, sabe que o app "fez outra coisa".

   Cresce só onde o ponteiro é grosso, e por altura mínima — a largura
   continua sendo do conteúdo, então nada esticou: medido depois em todas as
   telas, zero transbordo lateral e a barra de topo continua nos 64px. */
@media (hover: none) {
  .btn, .chip, select, textarea,
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]) {
    min-height: 44px;
  }
  /* `height`, e não só `min-height`, e SÓ para `select`.
     Medido no Simulador do iOS 26, iPhone 17, em 16/09/2026: os três
     filtros de Destinos mediam 37px com esta regra valendo. O WebKit não
     aplica `min-height` a controle de formulário NATIVO — o `<select>`
     tem tamanho intrínseco e ignora o mínimo. O Chromium aplica, então a
     varredura a 375px aprovava: é a diferença que só o motor do telefone
     dele mostra.
     `height` ele respeita, e a altura é a mesma nos dois motores. */
  select { height: 44px; }
  /* Quadrados: aqui o alvo é a área toda, não a linha de texto. */
  #nav-toggle, #nav-me, .brand { width: 44px; height: 44px; }
  /* A porta do formulário. Não é `.btn` — é linha com seta, do mesmo
     feitio de `.a-mao-botao`, e por isso ficaria de fora da regra acima. */

  /* O menu do cartão e as abas da vitrine não são `.btn` — nasceram
     depois, com classe própria, e por isso ficaram de fora da regra de
     cima. Medido: 38px nos cinco itens do menu. Numa lista em que o
     último item apaga a viagem, errar de alvo por seis pixels é caro. */
  .card-menu-item, .rot-aba, .dm-btn, .frase-atalho,
  .vs-filtro, .vd-par, .sb-link, .alterna { min-height: 44px; }
  .sd-avisar, .sd-tipo { min-height: 44px; }
  .om-cab .btn.sm { min-height: 44px; }
  .bp-acoes .btn.sm { min-height: 44px; }
  .hq .md-link, .hq-op { min-height: 44px; }
  .fdf-incluir.btn.sm, .fdf-todas { min-height: 44px; }
  .vc-fecha { min-width: 44px; min-height: 44px; }
  .lv-cap, .lv-onde { min-height: 44px; }
  /* A árvore de registrar lugares (`arvore-do-catalogo.js`). */
  .vs-btn, .vs-grp-toggle { min-height: 44px; }
  .vs-link { min-height: 44px; display: inline-flex; align-items: center; }
  /* Ícone sozinho: sem rótulo, a LARGURA não vem do conteúdo — e um
     alvo de 44px de alto por 18 de largo é meio alvo. */
  .frase-voz { min-width: 44px; min-height: 44px; }
  /* A faixa do acervo é um botão de largura inteira, sem `.btn`: fechada
     ela já passa de 44px pelo conteúdo, aberta é uma linha só. */
  .acv-faixa { min-height: 44px; }
  /* "Ver as 5 patentes" — botão de largura inteira, também sem `.btn`. */
  .pat-todas { min-height: 44px; }
  .dq-status { min-height: 44px; }
  /* Os dois da parada de refeição. Nascem com classe própria e por isso
     ficam FORA das regras de `.btn`/`select` acima — já foram seis assim. */
  .ha-select, .ha-hora, .ha-onde { min-height: 44px; }
  /* A saída para o mapa é `a` com classe própria — mesma história. */
  .ha-saida { min-height: 44px; line-height: 44px; }
  /* O azulejo que abre a conta e a rota do dia no Google Maps: os dois
     nascem com classe própria e ficariam fora das regras de cima. */
  .kpi-conta { min-height: 44px; }
  .dgm { min-height: 44px; line-height: 44px; }
  /* As reticências de cada parada do roteiro pronto: 30px de desenho, e
     elas ficam entre uma foto e o nome — errar aqui abre a ficha de
     outro destino. Largura junto, porque é alvo quadrado. */
  .rot-op-btn { min-height: 44px; min-width: 44px; }
  /* `min-width` junto: medido a 375px, o passo "BR" tinha 27px de
     largura — alto o bastante e estreito demais. */
  .trilha-passo { min-height: 44px; min-width: 44px; }
  .socorro-ir { min-height: 44px; }
  /* O Leaflet declara 30px em `.leaflet-touch .leaflet-bar a` — duas
     classes. Uma só perde, e o zoom continuava do tamanho de antes. */
  /* "Entrar com código" é um `md-link`, e `md-link` já custou este
     mesmo conserto uma vez: 38px medidos a 375px. */
  .jor-codigo { min-height: 44px; }
  .convite-quiz-nao { min-height: 44px; }
  .rv-fechar { min-height: 44px; min-width: 44px; }
  .rj-marca { min-height: 44px; min-width: 44px; }
  /* "Atualizar", na faixa de versão nova: 30px de altura medidos no iPhone. */
  .update-banner button { min-height: 44px; }
  /* O "×" das três caixas de diálogo (27px de quadrado) e o "⋮" do cartão
     (42 de largura), medidos a 375px no banco de prova em 01/10/2026. */
  .conc-fecha, .rc-fecha, .pub-fecha { min-width: 44px; min-height: 44px; }
  .fc-cid-btn { display: inline-block; min-height: 44px; }
  /* A engrenagem da vitrine é discreta no desenho, não no alvo. */
  .rot-engrenagem { min-width: 44px; min-height: 44px; }
  /* O calendário e o atalho dele na faixa de eventos (`o-calendario.js`). */
  .cal-passo { width: 44px; height: 44px; }
  .cal-dia, .cal-item, .evp-cal { min-height: 44px; }
  .alb-fig { min-height: 44px; }
  .alb-mini { min-width: 44px; min-height: 44px; }
  .loja-item { min-height: 44px; }
  .card-mais { min-width: 44px; }
  /* "Desmarcar todas", na caixa de concluir: um `md-link` de 17px de alto.
     Lá ele é item de coluna flex, então a altura vale sem mexer no texto. */
  .conc-corpo > .md-link { min-height: 44px; align-self: flex-start; }
  .md-grupos-todos { min-height: 44px; }
  .leaflet-touch .leaflet-bar a { width: 44px; height: 44px; line-height: 44px; }
  /* O roteiro no telefone. Medido pelo testador de usuário a 375px:
     "inverter" com 14px de alto e as setas de ordem com 24×24 — e as setas
     ainda nasciam com opacidade zero, à espera de um hover que o dedo não
     tem. Aqui elas ficam acesas, vão para a direita do nome (float, não
     `absolute`: com 44px por cima do título elas o cobririam) e a parada
     contém o próprio float. */
  .rot-inverter { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; }
  .stop { display: flow-root; }
  .stop-ordem { position: static; float: right; opacity: 1; margin: 0 0 4px 8px; }
  .stop > .aap-btn { position: static; float: right; margin: 0 0 4px 4px; }
  /* O horário passa por baixo das setas: ao lado delas, "120 min" quebrava em duas linhas. */
  .stop .times { clear: right; }
  .stop.poi h5 { padding-right: 0; }
  .md-menu-op { min-height: 44px; }
  .cr-outros .md-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; }
  .stop-maps { min-height: 44px; }
  .mc-tipos > summary { display: flex; align-items: center; min-height: 44px; padding: 0; }
  .mc-tipos-todos .md-link { display: inline-flex; align-items: center; min-height: 44px; }
  .sn-mapa, .sn-legenda .sn-fechar, .sn-ligar { min-height: 44px; min-width: 44px; }
  .mala-tirar { min-height: 44px; min-width: 44px; justify-content: center; align-items: center; }
  .cg-item, .od-link, .ml-filtro, .sm-item { min-height: 44px; }
  .mt-painel .btn.sm, .mt-marcar, .ie-painel .btn.sm, .dup-lado-acoes .btn.sm, .fd-videos .btn.sm { min-height: 44px; }
  .stop-ordem button { min-width: 44px; min-height: 44px; align-items: center;
                       justify-content: center; }
  /* A varredura por cidade: os `.btn.sm` da fila (Cadastrar, Não entra,
     É o mesmo) ganham de `.btn` pela especificidade e ficavam em 29px; o
     nome do lugar e "Buscar no Google Maps" são `a` soltos no texto.
     Medido a 375px na bancada, 25/09/2026. */
  .vr-painel .btn.sm { min-height: 44px; }
  .vr-txt > a, .vr-busca { display: inline-flex; align-items: center; min-height: 44px; }
}

/* Caminho de arquivo não quebra sozinho: `backend/app/routers/data_qualidade.py`
   empurrava a página 11px para o lado na tela de funcionalidades, e página
   que rola de lado no telefone parece quebrada, não larga. */

/* ============================================================
   A fila de curadoria por região
   ------------------------------------------------------------
   Uma lista de linhas, não de cartões: são itens de uma mesma
   fila e comparar "quantos faltam" entre eles é o trabalho da
   tela. Borda e sombra em cada uma separariam o que precisa ser
   lido em conjunto.

   O número vem primeiro porque é a pergunta ("quanto falta"), e
   o nome da região é a resposta de qual. A região que está a UM
   destino ganha a terracota — a cor de ação —, porque é a única
   linha da tela que cabe numa tarde.
   ============================================================ */
.fc {
  margin-bottom: var(--sp-4);
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.fc-cabeca [data-refazer] { margin-bottom: var(--sp-2); }
.fc-cabeca h3 {
  margin: 0 0 4px;
  font-size: 1.05rem;
  letter-spacing: -.01em;
}
.fc-cabeca p {
  margin: 0 0 var(--sp-3);
  max-width: 62ch;
  color: var(--text-soft);
  font-size: .86rem;
  line-height: 1.5;
}
.fc-espera { margin: 0; color: var(--text-soft); font-size: .88rem; }

.fc-lista { display: flex; flex-direction: column; }
/* O número alinha com o NOME da região, não com o meio da linha: a linha
   cresce quando há garimpo a mostrar, e o azulejo centralizado descolava
   do que ele conta — ficava boiando ao lado das cidades. */
.fc-item {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
  padding: var(--sp-2) 0;
  border-top: 1px solid var(--border);
}
.fc-item:first-child { border-top: 0; }

/* Largura fixa para os números alinharem em coluna mesmo com um
   dígito de diferença — é o que deixa a fila legível de relance. */
.fc-quanto {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* 62 e não 52: em 375px "destinos" mede exatos 52 e encostava nas duas
     bordas do azulejo, com cara de texto vazando. */
  flex: 0 0 62px;
  padding: 6px 4px;
  border-radius: var(--r);
  background: var(--surface-2);
  color: var(--text-soft);
  line-height: 1;
}
.fc-quanto b {
  font-size: 1.25rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.fc-quanto small { margin-top: 3px; font-size: .64rem; letter-spacing: .04em;
  text-transform: uppercase; }

/* Preenchimento com `--brand`/`--brand-text`, nunca com `--accent`: no
   escuro a terracota é clareada para servir de TEXTO, e usá-la de fundo
   sob branco derruba o contraste para 2,3:1. O par da marca é o único
   desta folha desenhado para ser fundo nos dois temas. */
.fc-perto .fc-quanto { background: var(--brand); color: var(--brand-text); }
/* `b` E `small` nomeados um a um: a folha tem regra própria de cor para
   ambos, e regra direta ganha de herança sempre. Medido em 375px no tema
   claro, o "DESTINOS" do azulejo destacado estava em `--text-soft` sobre
   o verde da marca — 1,32:1, ilegível, enquanto o número ao lado marcava
   9,05. O container estava certo; quem não herdava era o filho. */
.fc-perto .fc-quanto b,
.fc-perto .fc-quanto small { color: var(--brand-text); }

.fc-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.fc-txt strong { font-size: .95rem; }
.fc-txt small { color: var(--text-soft); font-size: .8rem; }
.fc-onde {
  color: var(--brand);
  font-size: .78rem;
  overflow-wrap: anywhere;
}

/* O atalho: o que já está salvo e encaixa neste grupo. Fica ABAIXO das
   cidades porque só faz sentido depois de se saber onde é — e é a única
   linha da fila que aponta para trabalho já feito, por isso ganha a
   régua de cor à esquerda em vez de mais uma cor de texto. */
.fc-garimpo {
  margin-top: 4px;
  padding-left: 8px;
  border-left: 2px solid var(--border-strong);
  color: var(--text-soft);
  font-size: .78rem;
  overflow-wrap: anywhere;
}
.fc-destrava .fc-garimpo { border-left-color: var(--brand); }
.fc-destrava .fc-garimpo b { color: var(--brand); }
.fc-destrava .fc-quanto { background: var(--brand); color: var(--brand-text); }
.fc-destrava .fc-quanto b,
.fc-destrava .fc-quanto small { color: var(--brand-text); }
/* Fechada por padrão: são 16 linhas de 1.300px empurrando a fila de
   cadastros — o trabalho real desta tela — para baixo da dobra. O que
   ainda NÃO produz roteiro fica aberto; o que já produz e pode ganhar um
   temático é segunda prioridade, e segunda prioridade não custa uma tela. */
.fc-gaveta { margin-top: var(--sp-3); }
.fc-gaveta > summary {
  cursor: pointer;
  padding: var(--sp-1) 0;
  color: var(--text-soft);
  font-size: .84rem;
}
.fc-gaveta > summary:hover { color: var(--text); }
/* A seta é desenhada, não escrita — o mesmo desenho de `.bc-rotinas`, que
   é a outra gaveta desta tela. O marcador padrão do navegador é primo do
   emoji: muda de forma a cada plataforma. */
.fc-gaveta > summary { list-style: none; }
.fc-gaveta > summary::-webkit-details-marker { display: none; }
.fc-gaveta > summary::before {
  content: ""; display: inline-block; margin-right: 8px;
  border: 5px solid transparent; border-left-color: var(--text-faint);
  transform: translateY(1px);
}
.fc-gaveta[open] > summary::before {
  border-left-color: transparent; border-top-color: var(--text-faint);
  transform: translateY(4px);
}
.fc-tema .fc-quanto { background: var(--brand-soft); }
/* As cidades da região: onde procurar o destino que falta. */
.fc-cidades { margin-top: var(--sp-2); }
.fc-cid-lista {
  list-style: none; margin: var(--sp-1) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.fc-cid {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px var(--sp-2);
  padding: 4px 0; border-top: 1px solid var(--border);
}
.fc-cid:first-child { border-top: 0; }
.fc-cid-btn {
  border: 0; background: none; padding: 0; cursor: pointer; text-align: left;
  color: var(--text); font: inherit; font-size: .86rem; font-weight: 600;
  text-decoration: underline; text-decoration-color: var(--border-strong);
  text-underline-offset: 3px;
}
.fc-cid-btn:hover, .fc-cid-btn:focus-visible { color: var(--brand); }
.fc-cid-vazia .fc-cid-btn { color: var(--text-soft); }
.fc-cid small { color: var(--text-soft); font-size: .78rem; }
.fc-cid-decidir { color: var(--brand); font-size: .78rem; }

/* =================================================== PERFIL ============
   Como estava: 2.419 px numa coluna só, com o bloco de Chaves de IA
   ocupando 1.160 deles — quase metade da tela para algo que só admin usa.
   Tudo aberto ao mesmo tempo, sem hierarquia, e "Sair da conta" no meio
   do caminho.

   Agora: um cartão que não recolhe (quem você é) e gavetas que recolhem,
   cada uma dizendo na própria linha o que guarda. */
.pf .panel { margin-bottom: var(--sp-2); }

/* ---- o cartão de quem você é ---- */
.pf-eu {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
}
.pf-eu-txt { flex: 1 1 200px; min-width: 0; }
/* Regra DIRETA em cada filho: a folha tem cor própria para `strong` e
   `small`, e pintar só `.pf-eu-txt` deixaria os dois com a cor de antes. */
.pf-eu-txt strong {
  display: block; font-size: 18px; font-weight: 700; color: var(--text);
  letter-spacing: -.01em;
}
.pf-eu-txt > small {
  display: block; margin-top: 2px; font-size: 13px; color: var(--text-soft);
  overflow-wrap: anywhere;
}
.pf-selos { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* O selo é o menor texto da tela (10,5 px). A cor pura da marca deu 4,42
   medido na produção — reprovada por pouco, que é como esta armadilha
   costuma aparecer. Puxada 30% para o tom do texto ela passa e continua
   sendo reconhecivelmente musgo. Mesma correção da etiqueta de raridade
   em Meus Lugares. */
.pf-selo {
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--r-pill);
  color: color-mix(in srgb, var(--brand) 70%, var(--text));
  border: 1px solid color-mix(in srgb, var(--brand) 40%, transparent);
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}
/* Administrador é PAPEL, não plano — e por isso outro tom. A tela antiga
   escrevia "plano admin" e confundia as duas coisas. */
.pf-selo-admin {
  color: color-mix(in srgb, var(--accent) 70%, var(--text));
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.pf-eu-acoes { display: flex; gap: 8px; flex-wrap: wrap; }
/* O seletor de arquivo é um `label` com cara de botão: o `input[type=file]`
   do navegador não aceita desenho, e escondê-lo atrás do rótulo é a única
   forma de ele ter a mesma quina dos outros controles. */
.pf-trocar-foto { cursor: pointer; }
.pf-trocar-foto .ico { width: 16px; height: 16px; }
.pf-foto-dica {
  display: block; margin-top: 10px; font-size: 11.5px;
  color: var(--text-faint); line-height: 1.45;
}

/* ---- o retrato ---- */
.pf-retrato, .nmc-retrato, .nav-selo {
  display: grid; place-items: center; flex: none;
  border-radius: var(--r-pill);
  background: var(--brand-soft); color: var(--brand);
  font-weight: 800; letter-spacing: .02em;
  overflow: hidden;
}
.pf-retrato { width: 64px; height: 64px; font-size: 22px; }
.nmc-retrato { width: 40px; height: 40px; font-size: 14px; }
.nav-selo { width: 100%; height: 100%; font-size: 13px; }
.pf-retrato img, .nmc-retrato img, .nav-selo img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
/* Com foto, o fundo da marca não aparece — e a borda some junto, senão
   fica um anel claro em volta do retrato de todo mundo. */
.nav-avatar.tem-foto { padding: 0; border-color: transparent; }

/* ---- as gavetas ---- */
.pf-gaveta > summary {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-2); cursor: pointer; list-style: none;
}
.pf-gaveta > summary::-webkit-details-marker { display: none; }
.pf-tit { font-size: 15px; font-weight: 700; color: var(--text); }
/* O resumo na linha fechada. Gaveta que não diz o que guarda só esconde —
   e é ele que faz esta tela ser melhor que a de antes, não o recolher. */
.pf-resumo {
  flex: 1 1 auto; text-align: right;
  font-size: 12px; color: var(--text-faint); line-height: 1.4;
  overflow-wrap: anywhere;
}
/* A seta é desenhada, como a das outras gavetas do app: o marcador padrão
   do navegador muda de forma a cada plataforma. */
.pf-gaveta > summary::after {
  content: ""; flex: none; align-self: center;
  border: 5px solid transparent; border-left-color: var(--text-faint);
  transition: transform .15s var(--ease);
}
.pf-gaveta[open] > summary::after {
  border-left-color: transparent; border-top-color: var(--text-faint);
  transform: translateY(3px);
}
.pf-corpo { margin-top: var(--sp-3); }
.pf-corpo > :first-child { margin-top: 0; }

/* ---- uma linha de dado com o botão de trocar ---- */
.pf-linha {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: 12px 0;
  border-bottom: 1px solid var(--border);
}
.pf-linha:last-of-type { border-bottom: 0; }
.pf-linha-txt { min-width: 0; }
.pf-linha-txt small {
  display: block; font-size: 11px; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .05em;
}
.pf-linha-txt strong {
  display: block; margin-top: 2px; font-size: 14px; color: var(--text);
  font-weight: 600;
}
/* A segunda `small` explica o que a ação faz, e não é etiqueta: volta ao
   corpo do texto. */
.pf-linha-txt strong + small {
  text-transform: none; letter-spacing: 0; margin-top: 4px;
  font-size: 11.5px; line-height: 1.45;
}
.pf-forma { margin: 6px 0 14px; }
.pf-forma .field { margin-bottom: 10px; }
.pf-forma p { margin: 0 0 10px; font-size: 13px; color: var(--text-soft); }
.pf-erro {
  margin-bottom: 10px; font-size: 12.5px; color: var(--danger);
  line-height: 1.45;
}
/* O quadro do que não tem volta. Traço na borda e não fundo vermelho:
   `--danger` é cor de TEXTO, clareada para o escuro — atrás de branco ela
   dá 3,0:1. */
.pf-forma-risco {
  padding: 14px; border-radius: var(--r);
  border: 1px solid color-mix(in srgb, var(--danger) 45%, var(--border));
  border-left-width: 3px;
}
.pf-risco[open] > summary .pf-tit { color: var(--danger); }
.pf-versao {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
  font-size: 13px; color: var(--text-soft);
}
.pf-rodape { margin-top: var(--sp-3); }

/* ---- os planos ---- */
.pl-grade {
  display: grid; gap: var(--sp-2);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.pl-cartao {
  padding: var(--sp-3);
  border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface-2);
}
.pl-meu { border-color: var(--brand); }
.pl-cabeca {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px;
}
.pl-cabeca strong { font-size: 16px; font-weight: 700; color: var(--text); }
.pl-atual {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--brand) 70%, var(--text));
}
.pl-atual .ico { width: 13px; height: 13px; }
.pl-preco {
  display: block; margin: 8px 0 2px;
  font-size: 15px; font-weight: 700; color: var(--text);
}
.pl-resumo {
  display: block; font-size: 12px; color: var(--text-faint); line-height: 1.45;
}
.pl-itens {
  list-style: none; margin: 12px 0 0; padding: 12px 0 0;
  border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 7px;
}
.pl-itens li {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; font-size: 12.5px; color: var(--text-soft);
}
.pl-itens b { color: var(--text); font-weight: 600; white-space: nowrap; }
.pl-nota { display: block; margin-top: var(--sp-3); line-height: 1.5; }

/* ---- o menu da conta, no canto de cima ---- */
.nav-menu-conta { min-width: 280px; }
.nmc-cabeca {
  display: flex; align-items: center; gap: 10px;
  padding: 4px var(--sp-3) 12px;
  border-bottom: 1px solid var(--border); margin-bottom: 6px;
}
.nmc-quem { min-width: 0; }
.nmc-quem strong {
  display: block; font-size: 13.5px; font-weight: 700; color: var(--text);
}
.nmc-quem small {
  display: block; font-size: 11.5px; color: var(--text-faint);
  overflow-wrap: anywhere;
}
.nmc-plano { color: var(--brand); font-weight: 600; margin-top: 2px; }
.nmc-risco { border-top: 1px solid var(--border); margin-top: 6px; padding-top: 6px; }

@media (hover: none) {
  /* Controles do Perfil que nascem com classe própria e por isso ficariam
     de fora das regras de `.btn` do bloco do dedo. */
  .pf-gaveta > summary, .pf-trocar-foto { min-height: 44px; }
  /* As marcas do "Ajustar detalhes", a ação de GPS dentro do campo de
     origem e a linha das coordenadas: nascem com classe própria, mesma
     história — já ficaram seis controles de fora assim neste app. */
  .ajuste-marca, .ajuste-botao { min-height: 44px; }
  .acao-do-campo { min-width: 44px; }
  .campo-origem #btn-manual-coords { min-height: 44px; line-height: 44px; }
}

/* Na tela estreita o resumo desce para a própria linha.
   Medido na bancada a 375 px com o caso difícil (e-mail de 40 caracteres):
   lado a lado, o resumo espremia o título e "Seus dados" quebrava em duas
   linhas, com a segunda metade sozinha embaixo — o contrário do que um
   título de seção faz. */
@media (max-width: 559px) {
  .pf-gaveta > summary {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas: "tit seta" "res res";
    row-gap: 3px; align-items: center;
  }
  .pf-tit { grid-area: tit; }
  .pf-resumo { grid-area: res; text-align: left; }
  .pf-gaveta > summary::after { grid-area: seta; }

  /* O cartão: o retrato e o nome na primeira linha, o resto embaixo com a
     largura toda. Assim o e-mail longo quebra numa linha inteira em vez de
     numa coluna de 180 px. */
  .pf-eu { display: grid; grid-template-columns: auto 1fr; gap: 12px; }
  .pf-retrato { grid-row: span 2; align-self: start; }
  .pf-eu-acoes { grid-column: 1 / -1; }
}

/* ---- Levar o mapa da ferramenta embora ----
   O bloco de baixar fica ACIMA da lista, e não no fim: a lista tem 96
   itens, e um botão depois dela só existe para quem já rolou tudo — que é
   exatamente quem não precisa do arquivo. */
.fn-baixar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
}
.fn-baixar-txt { flex: 1 1 260px; min-width: 0; }
/* Regra direta em cada filho: a folha tem cor própria para `strong` e
   `small`, e pintar só o bloco deixaria os dois com a cor de antes. */
.fn-baixar-txt strong {
  display: block; font-size: 14px; font-weight: 700; color: var(--text);
}
.fn-baixar-txt small {
  display: block; margin-top: 3px; font-size: 12px;
  color: var(--text-faint); line-height: 1.45;
}

/* ---- Um campo para dizer de onde se sai ----
   Eram dois botões soltos acima, o campo embaixo com rótulo começando em
   "Ou…", e o "Trocar" no cartão do resultado: quatro caminhos para a
   mesma resposta, nenhum dizendo qual valia. O gesto de GPS virou ação
   DO CAMPO, que é onde ele pertence. */
.campo-com-acao { position: relative; display: block; }
.campo-com-acao input { padding-right: 46px; }
.acao-do-campo {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: 42px;
  display: grid; place-items: center;
  border: 0; background: none;
  color: var(--text-faint);
  cursor: pointer;
}
.acao-do-campo:hover { color: var(--brand); }
.acao-do-campo .ico { width: 18px; height: 18px; }
/* A linha das coordenadas: o caso raro, e por isso discreto — mas
   discreto não pode virar pequeno demais para o dedo. Medido a 375 px
   com toque: 14 px de altura, contra os 44 que a régua da casa pede. */
.campo-origem #btn-manual-coords {
  display: inline-block; margin-top: 8px; font-size: 12px;
}

/* ------------------------------------------------------ o mapa vivo
   Neblina, coroa, fronteira e pulso, por cima do mapa do Diário. Ver
   `o-mapa-vivo.js`. O ouro é o da patente: completar uma região é a mesma
   conquista que subir de nível. */
:root {
  --mv-neblina: #3a4a63;
  --mv-ouro-claro: #f3d77a;
  --mv-ouro-escuro: #3a2e08;
  --pat-txt-ouro-fixo: #7d640f;
  /* O popup do Leaflet é branco nos DOIS temas: a cor de texto dele não
     muda com o tema, e por isso não tem par escuro. */
  --popup-txt-soft: #4a4f57;
  --mv-pulso: #4bbf8a;
}
.mapa-do-diario path.mv-completa {
  stroke: var(--pat-ouro); stroke-width: 3px; stroke-opacity: 1;
}
.leaflet-marker-icon.mv-coroa,
.leaflet-marker-icon.mv-fronteira,
.leaflet-marker-icon.mv-pulso { background: none; border: 0; }
.mv-coroa, .mv-fronteira { display: grid; place-items: center; }
/* A nuvem: o canvas de `a-neblina-do-mapa.js`, entre as áreas e os
   marcadores. Some durante o zoom e volta redesenhada. */
.mv-neblina-tela { position: absolute; left: 0; top: 0; pointer-events: none;
  transition: opacity .25s var(--ease); }
/* O ouro que BRILHA: a coroa e as fronteiras saem da nuvem como na imagem
   de referência — sem caixa, desenho dourado com halo. O halo é
   `drop-shadow` no desenho, não sombra atrás de texto. */
.mv-coroa .ico, .mv-fronteira .ico {
  color: var(--mv-ouro-claro);
  filter: drop-shadow(0 0 2px var(--pat-ouro)) drop-shadow(0 0 7px color-mix(in srgb, var(--pat-ouro) 80%, transparent))
    drop-shadow(0 1px 1px rgba(0, 0, 0, .6));
}
.mv-coroa .ico { width: 34px; height: 34px; }
.mv-fronteira > span { display: grid; place-items: center; cursor: help;
  animation: mv-flutua 2.8s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -.55s); }
.mv-fronteira .ico { width: 32px; height: 32px; }
.mv-bau .ico { width: 34px; height: 34px; }
.mv-q {
  font: 900 34px/1 Inter, system-ui, sans-serif; color: var(--mv-ouro-claro);
  -webkit-text-stroke: 1px var(--pat-ouro);
  filter: drop-shadow(0 0 2px var(--pat-ouro)) drop-shadow(0 0 8px color-mix(in srgb, var(--pat-ouro) 80%, transparent))
    drop-shadow(0 1px 1px rgba(0, 0, 0, .7));
}
@keyframes mv-flutua { 50% { transform: translateY(-5px); } }
@media (prefers-reduced-motion: reduce) {
  .mv-fronteira > span { animation: none; }
}
/* Largura FIXA, como a `.mc-dica-caixa`: sem ela o Leaflet encolhe a dica
   até a maior palavra. E fundo do tema: a branca do Leaflet some o texto
   claro do escuro. */
.leaflet-tooltip.mv-dica {
  width: 220px; white-space: normal; padding: var(--sp-2);
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--r);
  font-size: 13px; line-height: 1.4;
}
.leaflet-tooltip.mv-dica.leaflet-tooltip-top::before { border-top-color: var(--border-strong); }
.mv-dica small { color: var(--text-soft); font-size: 12px; }
.mv-pulso {
  border: 3px solid var(--mv-pulso); border-radius: 50%;
  animation: mv-pulsa .9s ease-out 3 both;
}
@keyframes mv-pulsa {
  from { transform: scale(.5); opacity: 1; }
  to { transform: scale(2.4); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .mv-pulso { animation: none; opacity: .9; }
}
.vs-swatch.vs-nuvem {
  background: radial-gradient(circle at 30% 35%, #dfe3e8 0 22%, transparent 48%),
    radial-gradient(circle at 70% 65%, #b9c0c8 0 18%, transparent 46%), #4a525c;
}
.vs-marca { display: inline-grid; place-items: center; color: var(--mv-neblina); }
.vs-marca .ico { width: 16px; height: 16px; }
.vs-marca.mv-ouro { color: var(--pat-txt-ouro); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .vs-marca { color: #a9b6cc; }
}

/* A missão ativa: a barra do "Descobrir por perto" vestida de conquista,
   como na imagem de referência — borda e halo de ouro, o musgo entrando
   pelo fundo, e a bússola numa medalha. A medalha é redonda porque a
   bússola é; os botões continuam de quina. */
.pn-convite.pn-missao {
  border-color: var(--pat-ouro);
  background: linear-gradient(100deg, var(--surface) 35%,
    color-mix(in srgb, var(--brand) 26%, var(--surface)) 100%);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pat-ouro) 35%, transparent),
    0 0 22px color-mix(in srgb, var(--pat-ouro) 22%, transparent);
}
.pn-medalha {
  flex: none; display: grid; place-items: center;
  width: 52px; height: 52px; border-radius: 50%;
  color: var(--mv-ouro-escuro);
  background: radial-gradient(circle at 34% 30%, var(--mv-ouro-claro), var(--pat-ouro) 58%, var(--pat-txt-ouro-fixo) 100%);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pat-ouro) 55%, transparent),
    0 0 16px color-mix(in srgb, var(--pat-ouro) 45%, transparent);
}
.pn-medalha .ico { width: 30px; height: 30px; }
.pn-ouro { color: var(--pat-txt-ouro); }
.pn-txt small .pn-ouro { font-weight: 700; }
.pn-acoes { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pn-missao .pn-txt { flex: 1 1 180px; }
@media (max-width: 560px) {
  .pn-medalha { width: 40px; height: 40px; }
  .pn-medalha .ico { width: 24px; height: 24px; }
}

/* ------------------------------------------------ a loja de recompensas
   `a-loja-de-recompensas.js`. Recolhida como o álbum; o item fechado diz
   em que patente abre. Musgo é a estrutura; o item em uso ganha o ouro da
   patente — não há terracota aqui, porque nada se compra. */
.loja { margin: var(--sp-3) 0; border: 1px solid var(--border); border-radius: var(--r); background: var(--surface); }
.loja > summary { list-style: none; cursor: pointer; }
.loja > summary::-webkit-details-marker { display: none; }
.loja-faixa { display: flex; align-items: center; gap: var(--sp-3); padding: 12px 14px; }
.loja-faixa:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r); }
.loja-ico { display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--r);
  color: var(--pat-txt-ouro); background: color-mix(in srgb, var(--pat-ouro) 14%, transparent); }
.loja-ico .ico { width: 20px; height: 20px; }
.loja-tit { display: flex; flex-direction: column; min-width: 0; }
.loja-tit strong { font-size: 15px; font-weight: 700; color: var(--text); }
.loja-tit small { font-size: 12.5px; color: var(--text-soft); }
.loja-corpo { padding: 0 14px 14px; border-top: 1px solid var(--border); }
.loja-grupo h4 { margin: var(--sp-3) 0 var(--sp-2); font-size: 13px; font-weight: 700; color: var(--text-soft);
  letter-spacing: .04em; text-transform: uppercase; }
.loja-grade { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2);
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.loja-item { display: flex; align-items: center; gap: 12px; width: 100%; height: 100%; padding: 10px;
  text-align: left; font: inherit; color: var(--text); cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); }
.loja-item:hover:not(.fechado) { border-color: var(--border-strong); }
.loja-item:focus-visible { outline: none; box-shadow: var(--ring); }
.loja-item.em-uso { border-color: var(--pat-ouro); box-shadow: inset 0 0 0 1px var(--pat-ouro); }
.loja-item.fechado { cursor: default; border-style: dashed; }
.loja-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.loja-txt strong { font-size: 14px; font-weight: 700; }
.loja-txt small { font-size: 12px; color: var(--text-soft); line-height: 1.35; }
.loja-estado { display: inline-flex; align-items: center; gap: 4px; margin-top: 2px;
  font-size: 12px; font-weight: 600; color: var(--text-faint); }
.loja-item.em-uso .loja-estado { color: var(--pat-txt-ouro); }
.loja-estado .ico { width: 13px; height: 13px; }
.loja-som { display: flex; align-items: center; gap: 8px; margin-top: var(--sp-3); font-size: 14px; color: var(--text); }
/* A amostra: o próprio item, em miniatura. */
.loja-amostra { flex: none; display: grid; place-items: center; width: 44px; height: 44px;
  border-radius: var(--r); border: 1px solid var(--border); color: var(--text-faint); }
.loja-amostra .ico { width: 18px; height: 18px; }
.loja-territorio-musgo { background: linear-gradient(135deg, #0d5f4f, #4bbf8a 60%, #a8ddb5); box-shadow: 0 0 0 2px #c9a227 inset; }
.loja-territorio-cobre { background: linear-gradient(135deg, #7a3b1d, #c98a5a 60%, #e8c3a0); box-shadow: 0 0 0 2px #c36b42 inset; }
.loja-territorio-lago { background: linear-gradient(135deg, #1d4e6b, #5aa7c9 60%, #a9d6ea); box-shadow: 0 0 0 2px #9fb3c8 inset; }
.loja-territorio-ouro { background: linear-gradient(135deg, #7d640f, #c9a227 60%, #e9d27a); box-shadow: 0 0 0 2px #fff1b8 inset; }
.loja-moldura-nenhuma, .loja-moldura-barro, .loja-moldura-cobre, .loja-moldura-ouro { border-radius: 50%; background: var(--surface-2); }
.loja-moldura-barro { box-shadow: 0 0 0 3px var(--pat-barro); }
.loja-moldura-cobre { box-shadow: 0 0 0 3px var(--pat-cobre), 0 0 8px color-mix(in srgb, var(--pat-cobre) 50%, transparent); }
.loja-moldura-ouro { box-shadow: 0 0 0 3px var(--pat-ouro), 0 0 10px color-mix(in srgb, var(--pat-ouro) 60%, transparent); }
.loja-tema_album-papel { background: var(--surface-2); border-style: dashed; }
.loja-tema_album-caderno { background: var(--alb-caderno); border: 1px dashed var(--alb-caderno-linha); }
.loja-tema_album-ouro { background: var(--surface-2); box-shadow: inset 0 0 0 2px var(--pat-ouro); }

/* A moldura do retrato, nos três lugares onde ele aparece. */
:root[data-moldura="barro"] :is(.pf-retrato, .nmc-retrato, .nav-selo) { box-shadow: 0 0 0 2px var(--pat-barro); }
:root[data-moldura="cobre"] :is(.pf-retrato, .nmc-retrato, .nav-selo) {
  box-shadow: 0 0 0 2px var(--pat-cobre), 0 0 8px color-mix(in srgb, var(--pat-cobre) 50%, transparent); }
:root[data-moldura="ouro"] :is(.pf-retrato, .nmc-retrato, .nav-selo) {
  box-shadow: 0 0 0 3px var(--pat-ouro), 0 0 12px color-mix(in srgb, var(--pat-ouro) 60%, transparent); }

/* O tema do álbum. O caderno de campo: papel pardo e a figurinha colada
   "costurada" por uma linha tracejada por dentro da borda. */
:root {
  --alb-caderno: color-mix(in srgb, #a07c4a 16%, var(--surface));
  --alb-caderno-linha: color-mix(in srgb, #a07c4a 60%, transparent);
}
:root[data-tema-album="caderno"] .alb { background: var(--alb-caderno); }
:root[data-tema-album="caderno"] .alb-fig.colada { outline: 1px dashed var(--alb-caderno-linha); outline-offset: -4px; }
:root[data-tema-album="ouro"] .alb-fig.colada { border-color: var(--pat-ouro); box-shadow: inset 0 0 0 1px var(--pat-ouro); }

/* O confete (`a-celebracao.js`): por cima de tudo, sem toque. */
.celebra-confete { position: fixed; inset: 0; z-index: 3000; pointer-events: none; }

/* A página completa do álbum, com o cartão de Stories (`o-cartao-de-stories.js`). */
.alb-conquista { display: flex; flex-wrap: wrap; align-items: center; gap: 8px var(--sp-2);
  margin: var(--sp-2) 0; font-size: 14px; font-weight: 700; color: var(--pat-txt-ouro); }
.alb-conquista .ico { width: 18px; height: 18px; }
.alb-mapa .alb-conquista { color: var(--pat-txt-ouro-fixo); margin: 0 0 6px; }

/* O roteiro secreto na loja: a bússola da missão, em ouro. */
.loja-secreto { color: var(--pat-txt-ouro); background: color-mix(in srgb, var(--pat-ouro) 12%, transparent); }

/* "Tipo é / não é", no filtro avançado do Catálogo (`os-recortes-do-catalogo.js`). */
.dq-tipo-op { display: flex; gap: var(--s2); align-items: center; }
.dq-tipo-op > .dq-select:first-child { flex: 0 0 auto; width: auto; }
.dq-tipo-op > select:last-child { flex: 1 1 auto; min-width: 0; }

/* O ponto cinza no roteiro (`o-catalogo-no-roteiro.js`): os outros dias,
   a um toque, embaixo do "Adicionar". */
.cr-outros { font-size: 12.5px; color: var(--text-soft); }

/* O sinal de celular no mapa do roteiro (`o-sinal-no-mapa.js`). */
.sn-dia { display: flex; flex-wrap: wrap; align-items: center; gap: 2px var(--s3); margin: 2px 0 var(--s2); }
.sn-dia .sn-mapa { margin: 0; }
.sn-estado { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; }
.sn-estado .ico { width: 15px; height: 15px; }
.sn-ok { color: var(--ok); }
.sn-sem { color: var(--danger); }
.sn-nada { color: var(--warn); }
/* O controle do canto do mapa: desligado é um botão; ligado, a legenda. */
.sn-legenda.sn-desligada { padding: 0; background: none; box-shadow: none; border: 0; }
.sn-ligar { display: inline-flex; align-items: center; gap: 6px; padding: 10px 12px;
  border: 1px solid var(--border-strong); border-radius: var(--r); background: var(--surface); color: var(--text);
  font: 600 13px/1 Inter, system-ui, sans-serif; cursor: pointer; box-shadow: 0 2px 8px rgba(0, 0, 0, .25); }
.sn-ligar .ico { width: 16px; height: 16px; }
.sn-andamento { display: flex; align-items: center; gap: 6px; flex-basis: 100%; color: var(--text-soft); }
.sn-andamento .spinner { width: 12px; height: 12px; }
.sn-mapa { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; margin: 2px 0 var(--s2); }
.sn-mapa .ico { width: 15px; height: 15px; }
.sn-ver { margin-top: var(--s2); }
.sn-rotulo span {
  display: inline-block; transform: translate(-50%, -50%); white-space: nowrap;
  padding: 3px 8px; border-radius: var(--r); font: 700 12px/1.2 Inter, system-ui, sans-serif;
  background: #e5484d; color: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .5);
}
.sn-legenda {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; max-width: 260px;
  padding: 8px 10px; background: var(--surface); color: var(--text); font-size: 12px;
}
.sn-legenda strong { flex-basis: 100%; font-size: 12.5px; }
.sn-legenda span { display: inline-flex; align-items: center; gap: 4px; }
.sn-legenda i { display: inline-block; width: 14px; height: 6px; border-radius: 3px; }
.sn-legenda small { color: var(--text-soft); flex-basis: 100%; }
.sn-legenda .sn-fechar { position: absolute; top: 2px; right: 4px; border: 0; background: none;
  color: var(--text-soft); font-size: 16px; cursor: pointer; }
.sn-legenda { position: relative; }

/* "Antes de sair" (`mala-e-checklist.js`): quem marcou, o item seu e o
   campo de acrescentar. */
.mala-quem { display: inline-flex; align-items: center; gap: 4px; color: var(--brand); font-size: 12px; }
.mala-quem .ico { width: 12px; height: 12px; }
.mala-tirar { margin-left: auto; align-self: center; border: 0; background: none; color: var(--text-soft);
  cursor: pointer; padding: 4px; display: inline-flex; }
.mala-tirar .ico { width: 14px; height: 14px; }
.mala-novo { display: flex; gap: var(--s2); margin-top: var(--s2); }
.mala-novo input { flex: 1 1 auto; min-width: 0; }
