/* Componentes da rodada 2: carrossel, mapa com ficha sobreposta, calendário e loja. */

/* =========================================================== Carrossel ==== */
.railbox { position: relative; }
.rail {
  display: flex;
  gap: var(--sp-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  padding: var(--sp-2) 0 var(--sp-4);
  -webkit-overflow-scrolling: touch;
  /* Sem barra de rolagem visível, em nenhum navegador. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.rail::-webkit-scrollbar { display: none; width: 0; height: 0; }
.rail:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: var(--r-md); }
.rail > * { scroll-snap-align: start; flex: 0 0 var(--rail-item, 320px); min-width: 0; }

/* A seta flutua sobre a trilha, não encosta nela: redonda de verdade (o
   `aspect-ratio` impede que uma caixa flex a estique em oval) e grande o bastante
   para o dedo.
   Fundo transparente, a pedido: o que separa a seta do cartão deixa de ser tinta
   e passa a ser o anel mais o véu de `--arrow-veu`, que desfoca e empurra o que
   está atrás para longe da luminância do glifo — para o escuro nas fases escuras,
   para o claro nas claras, já que `--fg` troca de lado junto com a fase. Sem o
   véu o glifo cairia sobre a foto do cartão e o contraste seria o da foto. */
.rail__arrow {
  position: absolute;
  top: calc(50% - 28px);
  z-index: 4;
  flex: none;
  width: 56px;
  height: 56px;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: transparent;
  -webkit-backdrop-filter: var(--arrow-veu);
  backdrop-filter: var(--arrow-veu);
  color: var(--fg);
  font-size: 1.75rem;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--line);
  transition: transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
/* Sem véu não há contraste garantido: aí a tinta sólida volta. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .rail__arrow { background: var(--ink-800); }
}
.rail__arrow--prev { left: -18px; }
.rail__arrow--next { right: -18px; }
.rail__arrow:hover:not(:disabled) { transform: scale(1.1); border-color: var(--accent); }
.rail__arrow:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.rail__arrow:disabled { opacity: 0.25; cursor: default; }
.railbox--static .rail__arrow, .railbox--static .rail__dots { display: none; }

.rail__dots { display: flex; justify-content: center; gap: 0.4rem; margin-top: var(--sp-2); }
.rail__dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--line-strong);
  transition: width var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.rail__dot.is-on { width: 22px; border-radius: var(--r-pill); background: var(--accent); }

@media (max-width: 1100px) {
  .rail__arrow--prev { left: 2px; }
  .rail__arrow--next { right: 2px; }
}
/* No celular cabe um cartão por vez, então o cartão em foco vai para o meio da
   tela — igual ao carrossel do mapa. O respiro lateral é o que sobra da largura
   do cartão, e é ele que deixa o primeiro e o último também alcançarem o centro.
   Simétrico de propósito: o passo que o carousel.js mede é a distância entre dois
   cartões, e um respiro igual dos dois lados não entra nessa conta.
   A largura vem da tela (vw), não em porcentagem: `86%` contaria a caixa já
   descontada do respiro e o cartão voltava a parar fora do centro. */
@media (max-width: 700px) {
  .rail {
    gap: var(--sp-3);
    --rail-card: min(84vw, 420px);
    padding-inline: calc(50% - var(--rail-card) / 2);
  }
  .rail > * { flex-basis: var(--rail-card); scroll-snap-align: center; }
  .rail__arrow { width: 46px; height: 46px; top: calc(50% - 23px); font-size: 1.5rem; }
}

/* ======================================================= Explorar/Mapa ==== */
/* O painel absoluto do catálogo se ancora aqui. Sem isto ele sobe até o `main`,
   que é o primeiro ancestral posicionado, e cobre o herói da home. */
.explore__layout { position: relative; --lista-w: clamp(296px, 25vw, 400px); }
.mapwrap { position: relative; }
/* O mapa sangra até as bordas da tela — `#view-mapa` fica fora do `.wrap` de
   propósito. Borda e raio do `.panel` só fazem sentido quando sobra margem para
   desenhá-los, e aqui não sobra: eles comiam 2 px de cada lado do desenho. */
.panel--mapa { border: 0; border-radius: 0; }

/* Tela cheia sem a API de fullscreen: ela exige gesto do usuário em cada
   aparelho e falha em silêncio dentro de iframe. Posição fixa entrega o mesmo
   resultado e continua obedecendo ao Esc. */
.explore__layout[data-cheio='true'] { position: fixed; inset: 0; z-index: 70; background: var(--bg); }
/* A barra sai de cena, em vez de disputar camada com ela: `main` abre contexto de
   empilhamento próprio, então o z-index daqui dentro nunca passaria por cima.
   É também o que a regra do topo, mais abaixo, já assumia ao dispensar o
   desconto da navegação. */
html[data-mapa-cheio='true'] .nav { display: none; }
.explore__layout[data-cheio='true'] .map { height: 100svh; }

/* O catálogo flutua colado na borda esquerda do mapa vazado, sem tirar largura
   do desenho — por isso o painel é absoluto e translúcido, não uma coluna.
   `overflow` visível de propósito: a caixa de chips nasce abaixo do botão e
   seria decepada pelo recorte que o `.panel` usa para arredondar os cantos. */
.panel--side {
  position: absolute; left: 0; top: 0; bottom: 0; z-index: 4;
  width: var(--lista-w);
  display: grid; grid-template-rows: auto minmax(0, 1fr);
  background: color-mix(in srgb, var(--ink-900) 88%, transparent);
  backdrop-filter: blur(16px);
  border: 1px solid var(--line-strong); border-left: 0;
  border-radius: 0 var(--r-lg) var(--r-lg) 0;
  overflow: visible;
}

@keyframes popin { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.mapop__top { display: flex; align-items: flex-start; gap: var(--sp-3); }
.mapop__title { font-family: var(--font-display); font-size: var(--t-d3); margin: 0; flex: 1; }
.mapop__close {
  flex: none; width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--line-strong); background: var(--surface-2);
  color: var(--fg); cursor: pointer; font-size: 1.1rem; line-height: 1;
}

/* Estrela de favoritos */
.fav {
  display: inline-flex; align-items: center; gap: 0.4rem;
  min-height: 40px; padding: 0.4rem 0.8rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-strong);
  background: var(--surface-2); color: var(--fg);
  font: inherit; font-size: var(--t-xs); cursor: pointer;
}
.fav__star { font-size: 1.05rem; line-height: 1; color: var(--fg-dim); }
.fav[aria-pressed='true'] { border-color: var(--fav-ring); background: var(--fav-fill); color: var(--fav-glyph); }
.fav[aria-pressed='true'] .fav__star { color: var(--fav-glyph); }
.fav:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.place__fav { position: absolute; top: 8px; right: 8px; padding: 0.3rem 0.5rem; min-height: 34px; }

/* Carrossel flutuante de lugares, ancorado no rodapé do mapa (celular) */
.mapdock {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 5;
  padding: var(--sp-3) var(--sp-3) var(--sp-2);
  background: linear-gradient(0deg, color-mix(in srgb, var(--ink-900) 88%, transparent) 55%, transparent);
}
/* O cartão em foco fica no meio da tela, não encostado na borda esquerda: é ele
   que acende o ponto no mapa, e o olho procura o destaque no centro. O respiro
   lateral é o que sobra da largura do cartão, então o primeiro e o último também
   alcançam o centro — sem ele, as pontas da trilha nunca chegariam lá.
   Simétrico de propósito: o carrossel mede o passo pela distância entre cartões,
   e um respiro igual dos dois lados não entra nessa conta.
   A largura do cartão é medida na tela, não em porcentagem: `flex-basis: 78%`
   contaria a caixa já descontada do respiro, e o cartão parava 31 px do centro. */
.mapdock { --dock-card: min(78vw, 420px); }
.mapdock .rail {
  padding-block: 0 var(--sp-2);
  padding-inline: calc(50% - var(--dock-card) / 2);
}
.mapdock .rail > * { flex-basis: var(--dock-card); scroll-snap-align: center; }
.mapdock .place { background: color-mix(in srgb, var(--ink-800) 94%, transparent); backdrop-filter: blur(10px); }
/* Menores que as do carrossel da home — o cartão flutuante é baixo e uma seta de
   56px o atravessaria —, mas não abaixo de 44px: é o piso do alvo de toque, e
   estas setas vivem num lugar onde só se chega com o dedo. */
.mapdock .rail__arrow { width: 44px; height: 44px; top: calc(50% - 22px); font-size: 1.4rem; }

/* Moeda da categoria: a mesma peça no ponto do mapa e no cartão da lista. É ela
   que liga um ao outro, então cor, anel e glifo não podem divergir entre os dois.
   `--cat-fg` vem do JS que pinta a peça: as sete cores do guia vão do verde-claro
   ao violeta, e um glifo branco fixo sumiria em metade delas. */
.coin {
  display: grid; place-items: center; flex: none;
  border-radius: 50%;
  background: var(--cat, var(--purple));
  color: var(--cat-fg, #fff);
  box-shadow: 0 3px 10px -3px rgba(16, 13, 21, 0.8), inset 0 0 0 2px rgba(255, 255, 255, 0.92);
}
.coin svg { width: 56%; height: 56%; }

/* O cartão só carrega o essencial: moeda, nome, praia/categoria e nota. O resto
   mora na página do lugar, que o "mais detalhes" abre. */
.place {
  position: relative; display: block; padding: 0;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--ink-800) 76%, transparent);
  border: 1px solid var(--line);
  transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.place:hover { border-color: color-mix(in srgb, var(--cat) 55%, var(--line-strong)); transform: translateY(-1px); }
.place[aria-current='true'] {
  border-color: var(--cat);
  box-shadow: 0 0 0 1px var(--cat), 0 14px 30px -22px var(--cat);
}
.place__hit {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center;
  gap: var(--sp-3);
  width: 100%; text-align: left; cursor: pointer; font: inherit; color: inherit;
  background: transparent; border: 0;
  padding: var(--sp-3) 2.9rem var(--sp-3) var(--sp-3);
  border-radius: inherit;
}
.place__hit:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; }
.place__coin { width: 42px; height: 42px; }
.place__info { display: grid; gap: 0.1rem; min-width: 0; }
.place__nota { display: flex; align-items: center; gap: 0.25rem; font-size: var(--t-xs); color: var(--gold); font-weight: 600; }
/* Discreto de propósito: é a saída para a página inteira, não a ação principal
   do cartão — clicar no cartão já acende o ponto no mapa. */
.place__mais {
  display: block; width: 100%; text-align: left;
  padding: 0 var(--sp-3) var(--sp-3); margin-top: -0.2rem;
  background: none; border: 0; cursor: pointer; font: inherit;
  font-family: var(--font-display); font-size: 0.6875rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-dim);
}
.place__mais:hover { color: var(--fg); }
.place__mais:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }

.panel--side .placelist { display: grid; gap: var(--sp-3); padding: var(--sp-3); min-height: 0; overflow-y: auto; }

/* ---- Controles sobre o desenho ---- */
.mapctl {
  display: grid; place-items: center; cursor: pointer; padding: 0;
  background: color-mix(in srgb, var(--ink-900) 86%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line-strong); color: var(--fg);
  box-shadow: var(--shadow-card);
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.mapctl:hover { border-color: var(--accent); }
.mapctl:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.mapctls { position: absolute; top: var(--sp-3); right: var(--sp-3); z-index: 6; display: grid; gap: var(--sp-2); }
.mapctls .mapctl { width: 40px; height: 40px; border-radius: var(--r-md); }
.mapctls .mapctl svg { width: 18px; height: 18px; }
/* A lingueta nasce na borda direita da coluna e acompanha o recolhimento. */
.mapctl--lista {
  position: absolute; z-index: 8;
  top: 50%; translate: 0 -50%;
  left: var(--lista-w);
  width: 24px; height: 56px;
  border-left: 0; border-radius: 0 var(--r-md) var(--r-md) 0;
  transition: left var(--dur) var(--ease-out);
}
.mapctl__seta {
  width: 7px; height: 7px;
  border-left: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translate(1px, -1px);
}
.explore__layout[data-lista='false'] .mapctl__seta { transform: rotate(-135deg) translate(1px, -1px); }

/* ---- Lista recolhida: a faixa de comando flutua no topo do mapa -----------
   O mesmo desenho serve ao celular, onde a coluna nunca cabe — abaixo de
   1041 px é o JS que força este estado, em vez de duplicar as regras numa
   media query. */
.explore__layout[data-lista='false'] .panel--side {
  /* O painel cobre o mapa inteiro só para dar à faixa um trilho onde grudar; quem
     aparece é a faixa. Por isso ele não recebe cliques — senão engoliria o arrasto
     do mapa na área vazia. */
  top: 0; bottom: 0;
  left: clamp(1rem, 4vw, 3rem); right: clamp(1rem, 4vw, 3rem);
  width: auto; z-index: 7; pointer-events: none;
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2);
  background: none; backdrop-filter: none; border: 0; border-radius: 0;
}
.explore__layout[data-lista='false'] .placelist { display: none; }
/* Grudada, não ancorada no topo do mapa: um `top` fixo serve a um caso e quebra o
   outro. Enquanto o mapa começa abaixo da navegação, a faixa fica no alto dele —
   sem a faixa de mapa morto que o desconto da barra abria. Quando a rolagem leva o
   topo do mapa para baixo da barra, ela para logo abaixo dela em vez de sumir. */
.explore__layout[data-lista='false'] .mapbar {
  position: sticky; top: calc(var(--nav-h) + var(--sp-3));
  align-self: stretch; padding: 0; border-bottom: 0;
  margin-top: var(--sp-3); pointer-events: auto;
}
/* Em tela cheia a navegação sai de cena, então não há o que desviar. */
.explore__layout[data-cheio='true'][data-lista='false'] .mapbar { top: var(--sp-3); }
/* Vidro sobre o mapa: aqui o campo e a pastilha têm um desenho atrás, não a página. */
.explore__layout[data-lista='false'] .mapbar .search input,
.explore__layout[data-lista='false'] .mapbar__conta {
  background: color-mix(in srgb, var(--ink-900) 82%, transparent);
  backdrop-filter: blur(10px);
}
.explore__layout[data-lista='false'] .mapctl--lista { left: 0; }

@media (max-width: 1040px) {
  /* No celular o mapa é o fundo da seção e tudo que fala dele flutua por cima.
     A margem morta embaixo era espaço que o desenho podia estar usando. */
  #view-mapa { padding-bottom: 0; }
  .mapctl--lista { display: none; }
  /* A faixa de busca ocupa o topo: os controles descem para não brigar com ela.
     A conta é o ponto mais baixo em que a faixa grudada pode parar — altura da
     barra fixa mais a própria faixa —, não a barra de navegação em si: é da faixa
     que estes botões precisam escapar, e ela desce até ali quando a rolagem leva
     o topo do mapa para debaixo da navegação. */
  .mapctls { top: calc(var(--nav-h) + 3.6rem); }
}
@media (min-width: 1041px) { .mapdock { display: none; } }

/* ==================================================== Página do lugar ===== */
/* Acima da barra fixa de navegação (z-index 100): a página do lugar cobre tudo,
   e com 90 a barra passava por cima dela — inclusive do × de fechar. */
.negocio {
  position: fixed; inset: 0; z-index: 150;
  overflow-y: auto; overscroll-behavior: contain;
  background: color-mix(in srgb, var(--ink-900) 96%, transparent);
  backdrop-filter: blur(22px);
  animation: negocio-in var(--dur) var(--ease-out);
}
.negocio[hidden] { display: none; }
@keyframes negocio-in { from { opacity: 0; transform: scale(0.985) translateY(12px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .negocio { animation: none; } }
.negocio__in { max-width: 980px; margin-inline: auto; padding: clamp(1.25rem, 4vw, 3rem); display: grid; gap: var(--sp-5); }
/* Fixo, não absoluto: a ficha rola, e o fechar tem de continuar à vista. */
.negocio__x {
  position: fixed; top: var(--sp-4); right: var(--sp-4); z-index: 2;
  width: 46px; height: 46px; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center; font-size: 1.4rem; line-height: 1;
  background: var(--ink-700); border: 1px solid var(--line-strong); color: var(--fg);
  box-shadow: var(--shadow-card);
}
.negocio__x:hover { border-color: var(--accent); background: var(--ink-600); }
.negocio__x:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* A capa é a única superfície da ficha que usa a cor da categoria, e de leve: a
   moeda ao lado já é a cor cheia, então repeti-la em bloco brigaria com ela. O
   degradê serve para a página ter começo — antes o nome flutuava no preto e a
   ficha parecia um aviso de erro. */
.negocio__capa {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg);
  border: 1px solid color-mix(in srgb, var(--cat, var(--purple)) 38%, transparent);
  background:
    linear-gradient(150deg, color-mix(in srgb, var(--cat, var(--purple)) 22%, transparent) 0%, transparent 62%),
    var(--surface);
}
.negocio__capaIn {
  position: relative; z-index: 1;
  display: grid; gap: var(--sp-4);
  padding: var(--sp-5) clamp(1rem, 3vw, var(--sp-5));
}
/* Com foto a capa fica alta e o texto desce para o pé dela: nome sobre imagem
   só se lê se houver um degradê escuro embaixo, e a altura é o que faz a foto
   parecer capa e não ícone. A imagem é decorativa (alt vazio) — quem usa leitor
   de tela recebe o nome e a categoria logo abaixo, não a descrição de um JPEG. */
.negocio__capa--foto { min-height: clamp(260px, 38vw, 380px); display: grid; align-items: end; }
.negocio__capaImg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0;
}
/* Único lugar do site que não segue a fase do céu, e de propósito: nas fases
   claras o texto do tema é escuro, e escuro sobre foto não se lê em foto
   nenhuma. A solução é a mesma de qualquer guia com capa — véu escuro fixo e
   texto claro por cima. Os papéis de cor são presos aqui dentro, então tudo o
   que o bloco contém já nasce legível sem regra por elemento. */
.negocio__capa--foto .negocio__capaIn {
  --fg: #faf9fc;
  --fg-muted: #e8e3ee;
  --fg-dim: #c9bed5;
  --gold: #ffbb27;
  --line-strong: rgba(250, 249, 252, 0.45);
  color: var(--fg);
  background: linear-gradient(to top,
    rgba(12, 9, 16, 0.94) 0%, rgba(12, 9, 16, 0.74) 52%, rgba(12, 9, 16, 0.12) 100%);
  padding-top: clamp(3rem, 12vw, 7rem);
}
.negocio__head { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; padding-right: 3.5rem; }
.negocio__coin { width: 68px; height: 68px; }
.negocio__id { display: grid; gap: 0.35rem; min-width: 0; flex: 1 1 260px; }
.negocio__id h2 { font-size: var(--t-d2); margin: 0; }
.negocio__meta { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; font-size: var(--t-sm); color: var(--fg-muted); }
.negocio__meta:empty { display: none; }
.negocio__chip {
  padding: 0.18rem 0.6rem; border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); font-size: var(--t-xs);
}
.negocio__chip--cat {
  background: var(--cat, var(--purple)); color: var(--cat-fg, #fff); border-color: transparent;
  font-weight: 600;
}
/* "Aberto agora" em ouro da marca, não em verde: a paleta do site é roxo, rosa e
   ouro, e um verde de semáforo seria a única cor estranha da página. A palavra
   é que informa — a cor só destaca, e por isso fechado fica apagado em vez de
   vermelho. */
.negocio__chip--aberto { border-color: var(--gold); color: var(--gold); font-weight: 600; }
.negocio__chip--fechado { border-color: var(--line-strong); color: var(--fg-dim); }
.negocio__chip--alerta { border-color: var(--line-strong); color: var(--fg-dim); text-decoration: line-through; }
.negocio__nota { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--t-sm); margin: 0; }
.negocio__estrelas { color: var(--gold); letter-spacing: 0.08em; }
.negocio__horas { display: grid; gap: 0.3rem; margin: 0; padding: 0; list-style: none; font-size: var(--t-sm); }
.negocio__horas li { display: flex; justify-content: space-between; gap: var(--sp-3); }
.negocio__horas span:first-child { color: var(--fg-dim); }
.negocio__horas .is-hoje { font-weight: 600; }
.negocio__horas .is-hoje span { color: var(--fg); }

/* Barra por nota: a proporção se lê sem número, o número confirma. */
.negocio__barras { display: grid; gap: 0.3rem; margin: 0; padding: 0; list-style: none; font-size: var(--t-xs); }
.negocio__barras li { display: grid; grid-template-columns: 2.4rem 1fr auto; gap: var(--sp-2); align-items: center; }
.negocio__barraN { color: var(--gold); }
.negocio__barra { height: 7px; border-radius: var(--r-pill); background: var(--ink-700); overflow: hidden; }
.negocio__barra i { display: block; height: 100%; background: var(--gold); }
.negocio__barraV { color: var(--fg-dim); font-variant-numeric: tabular-nums; }

.negocio__tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.negocio__tags li {
  padding: 0.18rem 0.6rem; border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); font-size: var(--t-xs); color: var(--fg-muted);
}

/* Depoimento com aspas de verdade: é fala de terceiro, e sem a marcação visual
   ele se confunde com texto nosso sobre o lugar. */
.negocio__depo { margin: 0; display: grid; gap: 0.3rem; padding-top: var(--sp-3); border-top: 1px solid var(--line); }
.negocio__depo:first-of-type { padding-top: 0; border-top: 0; }
.negocio__depo blockquote { margin: 0; font-size: var(--t-sm); }
.negocio__depoN { color: var(--gold); letter-spacing: 0.08em; font-size: var(--t-xs); }
.negocio__depo figcaption { font-size: var(--t-xs); color: var(--fg-muted); }

/* Galeria em trilho: as fotos vêm em quantidade variável e tamanhos diferentes,
   e uma grade fixa deixaria buracos quando só três chegam. */
.negocio__galeria {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(150px, 1fr);
  gap: var(--sp-3); margin: 0; padding: 0 0 var(--sp-2); list-style: none;
  overflow-x: auto; scroll-snap-type: x proximity; overscroll-behavior-x: contain;
}
.negocio__galeria li { scroll-snap-align: start; }
.negocio__galeria img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--r-md); border: 1px solid var(--line); display: block;
}
/* align-items: start porque os blocos têm alturas muito diferentes — duas
   etiquetas de acessibilidade ao lado de sete linhas de horário viravam um
   cartão quase todo vazio quando a linha os esticava junto. */
.negocio__grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); align-items: start; }
.negocio__bloco {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: var(--sp-4); display: grid; gap: var(--sp-3); align-content: start;
}
.negocio__bloco h3 { font-size: var(--t-xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-label); font-family: var(--font-display); }
.negocio__bloco dl { display: grid; grid-template-columns: minmax(84px, auto) 1fr; gap: 0.35rem var(--sp-3); font-size: var(--t-sm); margin: 0; }
.negocio__bloco dt { color: var(--fg-dim); }
.negocio__bloco dd { margin: 0; overflow-wrap: anywhere; }
.negocio__bloco--largo { grid-column: 1 / -1; }
.negocio__acoes { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }
/* O que ainda não tem fonte não vira campo vazio nem texto inventado: a ficha
   diz em uma linha o que falta, e os blocos entram quando o dado chegar. */
.negocio__falta { font-size: var(--t-xs); color: var(--fg-dim); }

/* ========================================================= Calendário ===== */
.calendar-tools { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; justify-content: space-between; margin-bottom: var(--sp-4); }
.calendar-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.calendar-actions .btn { min-height: 44px; }
.calendar-modos { display: flex; gap: var(--sp-2); }
.calendar-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; color: var(--fg-dim); font-size: var(--t-xs); margin-bottom: var(--sp-2); }
.calendar-grid { display: grid; gap: var(--sp-2); grid-template-columns: repeat(7, minmax(0, 1fr)); }
.calendar-grid[data-mode='day'] { grid-template-columns: 1fr; }
.calendar-day { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; min-height: 190px; }
.calendar-day.is-today { border: 2px solid var(--accent); }
.calendar-day.is-outside { opacity: 0.45; }
/* O mês é um seletor de datas: células quadradas, sem lista de rolês. */
.calendar-grid[data-mode='month'] .calendar-day {
  aspect-ratio: 1;
  min-height: 0;
}
.calendar-grid[data-mode='month'] .calendar-day__head { height: 100%; place-content: center; text-align: center; }
.calendar-grid[data-mode='month'] .calendar-day__head span { display: none; }
.calendar-grid[data-mode='month'] .calendar-day.has-events { border-color: var(--accent); }
.calendar-day__head { width: 100%; padding: var(--sp-3) var(--sp-2); border: 0; background: transparent; color: var(--fg); text-align: left; display: grid; gap: 0.2rem; cursor: pointer; font: inherit; }
.calendar-day__head span { font-size: var(--t-xs); color: var(--fg-dim); }
.calendar-day__head strong { font-family: var(--font-display); font-size: 1.5rem; }
.calendar-day__body { padding: var(--sp-2); display: grid; gap: var(--sp-2); align-content: start; }
.calendar-day__body p { font-size: var(--t-xs); color: var(--fg-dim); }
.calendar-event { background: var(--surface-2); color: var(--fg); border: 1px solid var(--line); border-radius: var(--r-sm); padding: var(--sp-3); text-align: left; cursor: pointer; font: inherit; font-size: var(--t-sm); overflow-wrap: anywhere; }
.calendar-event:hover { border-color: var(--accent); }
.calendar-event small { display: block; color: var(--fg-dim); font-size: var(--t-xs); margin-top: 0.2rem; }
/* Rolê já salvo. Quem carrega o estado é a estrela, e ela é texto: medida em ouro
   deu 2,9:1 nas fases claras, então herda --fg e passa com 5,0:1 no pior caso.
   A moldura em ouro é só reforço — mede 2,9:1 em aurora, mas a borda normal do
   cartão é --line, que fica abaixo de 1,5:1, então cobrar 3:1 só desta seria
   arbitrário. Medi --line-strong como alternativa e ficou pior: 1,2:1. */
.calendar-event.is-salvo { border-color: var(--gold); }
.calendar-event__salvo { color: var(--fg); margin-right: 0.3rem; }
.calendar-grid[data-mode='month'] .calendar-day__head strong { font-size: 1.05rem; }
.calendar-note { font-size: var(--t-sm); color: var(--fg-dim); margin-top: var(--sp-3); }

/* A agenda abre direto no botão. Sem o título que ocupava esse espaço, o respiro
   de cima da seção virou um vão entre o alternador e "Envie seu rolê"; zerado, o
   botão fica à mesma distância do alternador que o painel do catálogo na vista de
   mapa — quem mede as duas é o respiro de baixo da própria faixa. */
#view-agenda .section { padding-top: 0; }
/* Abaixo do botão valia o respiro de um cabeçalho de seção com título — o dobro
   do que a vista de mapa deixa entre o alternador e o catálogo. Trocar de aba
   mexia o calendário meia altura de botão. */
#view-agenda .section__head { margin-bottom: var(--sp-4); }

/* Ficha do evento, sobreposta ao calendário — não apaga a página. */
.agendawrap { position: relative; }
.calpop {
  position: absolute; inset-inline: 0; bottom: 0; z-index: 6;
  margin-inline: auto; max-width: 520px;
  background: color-mix(in srgb, var(--ink-800) 94%, transparent);
  backdrop-filter: blur(14px);
  border: 1px solid var(--line-strong); border-radius: var(--r-lg);
  padding: var(--sp-4); box-shadow: var(--shadow-card);
  display: grid; gap: var(--sp-3); animation: popin var(--dur) var(--ease-out);
}
.calpop[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .calpop { animation: none; } }
.calpop img { width: 100%; max-height: 300px; object-fit: contain; border-radius: var(--r-md); }

/* Celular: um dia por vez, deslizando com o dedo. */
@media (max-width: 760px) {
  .calendar-weekdays { display: none; }
  .calendar-grid[data-mode='week'] {
    display: flex; gap: var(--sp-3); overflow-x: auto;
    scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none;
    padding-bottom: var(--sp-3);
  }
  .calendar-grid[data-mode='week']::-webkit-scrollbar { display: none; }
  .calendar-grid[data-mode='week'] .calendar-day { flex: 0 0 100%; scroll-snap-align: start; min-height: 300px; }
  .calendar-grid[data-mode='month'] { gap: 3px; }
  .calendar-grid[data-mode='month'] .calendar-day__head { padding: var(--sp-2) 0.2rem; }
}

/* ============================================================== Loja ====== */
.shop { display: grid; gap: var(--sp-4); }
.product {
  display: grid; gap: var(--sp-3);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--sp-4); align-content: start;
}
.product img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--r-md); background: var(--ink-750); }
.product__name { font-family: var(--font-display); font-size: var(--t-d3); margin: 0; }
.product__desc { font-size: var(--t-sm); color: var(--fg-muted); }
.product__foot { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; margin-top: auto; }
.product__price { font-family: var(--font-display); font-size: 1.15rem; }

/* Carrinho flutuante */
.cartbtn {
  position: fixed; right: var(--sp-4); bottom: var(--sp-4); z-index: 40;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 52px; padding: 0.7rem 1.2rem;
  border: 0; border-radius: var(--r-pill);
  background-image: var(--grad-accent); color: var(--accent-ink);
  font: inherit; font-weight: 600; cursor: pointer;
  box-shadow: 0 14px 40px -12px rgba(0, 0, 0, 0.7);
}
.cartbtn__count {
  min-width: 24px; height: 24px; padding-inline: 6px; border-radius: var(--r-pill);
  background: var(--ink-900); color: var(--paper);
  display: grid; place-items: center; font-size: var(--t-xs);
}
.cartpanel {
  position: fixed; right: var(--sp-4); bottom: calc(var(--sp-4) + 64px); z-index: 41;
  width: min(380px, calc(100vw - 2rem)); max-height: 70vh; overflow-y: auto;
  background: var(--ink-800); border: 1px solid var(--line-strong);
  border-radius: var(--r-lg); padding: var(--sp-4);
  box-shadow: var(--shadow-card); display: grid; gap: var(--sp-3);
}
.cartpanel[hidden] { display: none; }
.cartrow { display: grid; grid-template-columns: 52px 1fr auto; gap: var(--sp-3); align-items: center; border-top: 1px solid var(--line); padding-top: var(--sp-3); }
.cartrow img { width: 52px; height: 52px; object-fit: cover; border-radius: var(--r-sm); }
.cartrow__name { font-size: var(--t-sm); }
.qty { display: inline-flex; align-items: center; border: 1px solid var(--line-strong); border-radius: var(--r-pill); }
.qty button { width: 32px; height: 32px; border: 0; background: transparent; color: var(--fg); cursor: pointer; font-size: 1.1rem; line-height: 1; }
.qty output { min-width: 26px; text-align: center; font-size: var(--t-sm); }
.carttotal { display: flex; justify-content: space-between; font-family: var(--font-display); border-top: 1px solid var(--line-strong); padding-top: var(--sp-3); }

/* Popup do Anfitrião: desce do botão da faixa, em todas as páginas. */
.hostpop {
  position: fixed; z-index: 110;
  top: calc(var(--nav-h) + var(--sp-2)); right: clamp(1rem, 4vw, 3rem);
  width: min(380px, calc(100vw - 2rem));
  display: grid; gap: var(--sp-3);
  padding: var(--sp-4);
  border: 1px solid var(--line-strong); border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--ink-800) 96%, transparent);
  backdrop-filter: blur(16px);
  box-shadow: var(--shadow-card);
}
.hostpop[hidden] { display: none; }
.hostpop__head { display: flex; align-items: center; gap: var(--sp-2); }
.hostpop__who { font-family: var(--font-display); font-size: var(--t-sm); font-weight: 500; }
.hostpop__who span { color: var(--fg-label); }
.hostpop__x {
  margin-left: auto; width: 32px; height: 32px; flex: none;
  border: 1px solid var(--line); border-radius: 50%;
  background: transparent; color: var(--fg-muted); cursor: pointer; line-height: 1;
}
.hostpop__x:hover { color: var(--fg); border-color: var(--line-strong); }
.hostpop__body { display: grid; gap: var(--sp-2); }
.hostpop__msg {
  font-size: var(--t-sm); color: var(--fg-muted);
  background: var(--surface-2); border-radius: var(--r-md);
  padding: var(--sp-3);
}
.hostpop__msg--dim { background: transparent; padding: 0 var(--sp-1); color: var(--fg-dim); font-size: var(--t-xs); }
.hostpop__sug { display: grid; gap: var(--sp-1); list-style: none; }
.hostpop__sug li {
  font-size: var(--t-xs); color: var(--fg-muted);
  border: 1px dashed var(--line-strong); border-radius: var(--r-pill);
  padding: 0.4rem 0.7rem;
}
.hostpop__foot { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.hostpop__foot .btn { flex: 1; min-width: 150px; justify-content: center; }

/* ====================================================== Galeria/projeto === */
.shots { --rail-item: 300px; }
.shots img { width: 100%; height: 220px; object-fit: cover; border-radius: var(--r-md); display: block; }
.shots figure { margin: 0; display: grid; gap: var(--sp-2); }
.shots figcaption { font-size: var(--t-xs); color: var(--fg-dim); }
.vframe { width: 100%; max-width: 300px; border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--line-strong); background: var(--ink-750); }
.vframe video, .vframe img { display: block; width: 100%; aspect-ratio: 9 / 16; object-fit: cover; }

.projcard { display: grid; gap: var(--sp-3); align-content: start; }
.projcard img { width: 100%; height: 200px; object-fit: cover; border-radius: var(--r-md); }

[hidden] { display: none !important; }

/* ============================================================ Planos ===== */
/* Três colunas no computador. No celular o mesmo nó vira trilha de carrossel —
   e o carousel.js só mostra setas e pontos quando há transbordo, então a troca
   de layout basta e não existe marcação diferente por largura. */
.planos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-4);
  align-items: stretch;
}
.planos:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: var(--r-md); }

.plano { display: grid; grid-template-rows: auto auto 1fr auto; gap: var(--sp-4); align-content: start; }
.plano--destaque { box-shadow: inset 0 0 0 1px var(--accent), var(--shadow-card); }
/* Rótulo de 11px: o destaque entra na borda, não no fundo. Texto branco sobre o
   extremo claro do degradê de destaque mede 3,63:1 no rosa — abaixo de 4,5:1. */
.plano__selo {
  justify-self: start;
  font-size: var(--t-eyebrow); letter-spacing: 0.14em; text-transform: uppercase;
  /* 11px espaçado tem traço fino: a cor especificada dá 13,9:1, mas o traço
     renderizado mede 3,98:1 porque quase todo pixel é meio-tom. Peso 600 enche
     o traço — é o render, não a cor, que estava falhando. */
  font-weight: 600;
  background: var(--surface-2); color: var(--fg);
  border: 1px solid var(--accent);
  border-radius: var(--r-pill); padding: 0.3rem 0.7rem;
}
.plano__nome { font-family: var(--font-display); font-size: var(--t-d3); margin: 0; }
.plano__preco { display: flex; align-items: baseline; gap: 0.35rem; flex-wrap: wrap; }
.plano__valor { font-family: var(--font-display); font-size: clamp(1.9rem, 4vw, 2.6rem); line-height: 1; }
.plano__ciclo { font-size: var(--t-sm); color: var(--fg-muted); }
.plano__pitch { font-size: var(--t-sm); color: var(--fg-muted); }

.plano__lista { list-style: none; display: grid; gap: var(--sp-2); align-content: start; margin: 0; padding: 0; }
/* Recuo por padding, não por coluna de grade: num li de grade cada trecho solto de
   texto vira célula própria, então `<strong>1 estabelecimento</strong> coberto pelo
   apoio` jogava "coberto pelo apoio" para a coluna de 1,1rem do ✓ e quebrava uma
   palavra por linha. Em fluxo normal o item aceita qualquer mistura de marcação. */
.plano__lista li { position: relative; padding-left: calc(1.1rem + var(--sp-2)); font-size: var(--t-sm); }
.plano__lista li::before { position: absolute; left: 0; top: 0; font-weight: 700; line-height: 1.5; }
/* Marca e ausência se distinguem pelo glifo, não pela cor: ✓ contra —. O destaque
   não serve aqui porque em fase clara ele cai abaixo de 4,5:1 num glifo de 14px. */
.plano__on::before { content: '✓'; color: var(--fg); }
/* O item ausente continua na lista: é o que torna as três colunas comparáveis. */
.plano__item { display: grid; gap: 0.15rem; }
/* O detalhe explica o que o nível entrega — o nome do nível inferior não se repete
   na coluna de cima, então é aqui que a diferença fica dita. */
.plano__det { font-size: var(--t-xs); color: var(--fg-muted); }
.plano__off { color: var(--fg-dim); }
.plano__off::before { content: '—'; color: var(--fg-dim); }

@media (max-width: 1040px) {
  .planos {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    overscroll-behavior-x: contain;
    padding-bottom: var(--sp-4);
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .planos::-webkit-scrollbar { display: none; width: 0; height: 0; }
  .planos > * { flex: 0 0 min(340px, 84%); scroll-snap-align: start; min-width: 0; }
}
/* Entre 700px e 1040px ainda aparece mais de um plano por vez e encostar na borda
   esquerda é o certo. Abaixo de 700px cabe um só, então ele vai ao centro como os
   outros carrosséis. Depois do bloco acima de propósito: mesma especificidade,
   quem vence é a ordem. */
@media (max-width: 700px) {
  .planos {
    --rail-card: min(84vw, 420px);
    padding-inline: calc(50% - var(--rail-card) / 2);
  }
  .planos > * { flex-basis: var(--rail-card); scroll-snap-align: center; }
}

/* ===================================================== Banner de oferta === */
/* Texto fica sobre os tokens da fase, não sobre o degradê: o extremo claro do
   degradê de destaque mede 4,45:1 com texto branco, abaixo do piso de 4,5:1.
   O degradê entra como friso e como número grande, onde o piso é 3:1. */
.promo {
  position: relative; overflow: hidden;
  display: grid; gap: var(--sp-4);
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  padding: var(--sp-5) var(--sp-5) var(--sp-5) calc(var(--sp-5) + 6px);
}
.promo::before { content: ''; position: absolute; inset: 0 auto 0 0; width: 6px; background-image: var(--grad-accent); }
.promo__num { font-family: var(--font-display); font-size: clamp(1.6rem, 4vw, 2.4rem); line-height: 1.05; margin: 0; }
/* Texto cheio, não apagado: no poente o fundo do banner é claro e o tom apagado
   media 4,22:1 contra ele. */
.promo__txt { font-size: var(--t-sm); color: var(--fg); margin-top: var(--sp-2); }
@media (max-width: 720px) {
  .promo { grid-template-columns: 1fr; }
  .promo .btn { justify-self: start; }
}

/* ======================================================== Painéis ======== */
.painel__grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
/* Prefixo `.card` pela especificidade: sem ele `.card p` (0,1,1) vence e o dado
   caía para 14px regular, do mesmo tamanho do rótulo — número e legenda
   empatavam e o cartão deixava de ler como dado. */
.card .painel__num {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2.1rem, 7vw, 2.9rem); line-height: 1;
  letter-spacing: -0.03em; color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.card .painel__rot {
  font-family: var(--font-display); font-size: var(--t-xs); font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase; line-height: 1.45;
  color: var(--fg-muted);
}
.painel__grid .card { gap: var(--sp-2); }

/* Gráfico de barras em CSS. O número aparece em texto ao lado da barra: a
   altura é enfeite, quem lê por leitor de tela recebe o valor. */
.chart { display: grid; gap: var(--sp-3); }
.chart__row { display: grid; grid-template-columns: 4.5rem 1fr auto; gap: var(--sp-3); align-items: center; font-size: var(--t-sm); }
.chart__rot { color: var(--fg-dim); font-size: var(--t-xs); }
.chart__track { height: 12px; border-radius: var(--r-pill); background: var(--surface-2); overflow: hidden; }
.chart__bar { height: 100%; width: var(--v, 0%); border-radius: var(--r-pill); background-image: var(--grad-accent); }
.chart__val { font-family: var(--font-display); min-width: 3.2rem; text-align: right; }

/* ======================================================== Checkout ======= */
.checkout { display: grid; gap: var(--sp-5); grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); align-items: start; }
@media (max-width: 1000px) { .checkout { grid-template-columns: 1fr; } }
.checkout fieldset { border: 0; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.checkout legend { font-family: var(--font-display); font-size: var(--t-d3); padding: 0; margin-bottom: var(--sp-2); }
.campo { display: grid; gap: var(--sp-2); }
.campo > span { font-size: var(--t-xs); color: var(--fg-dim); }
.campo input, .campo select, .campo textarea {
  font: inherit; color: var(--fg); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  padding: 0.7rem 0.9rem; min-height: 44px; width: 100%;
}
.campo textarea { resize: vertical; line-height: 1.5; }
.campo input::placeholder, .campo textarea::placeholder { color: var(--fg-dim); }
.campo input:disabled, .campo select:disabled { opacity: 0.7; cursor: not-allowed; }
.campo [aria-invalid='true'] { border-color: var(--pink-soft); }

/* Número de estabelecimentos do plano de apoio. Vivo de propósito no meio de um
   formulário desativado: é ele que define a mensalidade do resumo. */
.negocios { display: grid; gap: var(--sp-3); padding-bottom: var(--sp-4); border-bottom: 1px solid var(--line); }
.negocios__linha { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-3); font-size: var(--t-sm); }
.stepper { display: inline-flex; align-items: center; gap: 2px; padding: 3px; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-pill); }
.stepper__btn {
  width: 38px; height: 38px; flex: none; border: 0; border-radius: 50%; cursor: pointer;
  background: transparent; color: var(--fg); font: inherit; font-size: 1.15rem; line-height: 1;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.stepper__btn:hover:not([disabled]) { background: var(--surface-2); }
.stepper__btn[disabled] { opacity: 0.35; cursor: not-allowed; }
.stepper__btn:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.stepper__val { min-width: 2.4rem; text-align: center; font-family: var(--font-display); font-weight: 800; font-size: 1.1rem; font-variant-numeric: tabular-nums; }
.negocios__auto { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3); align-items: start; font-size: var(--t-sm); font-weight: 500; color: var(--fg); cursor: pointer; }
.negocios__auto input { width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--accent); cursor: pointer; }

/* =================================================== Envio de rolê ======= */
/* Sobreposição de verdade aqui: é um formulário, precisa do foco preso e de uma
   saída única. Todo o resto do site evita modal — esta é a exceção justificada. */
.envio {
  position: fixed; inset: 0; z-index: 140;
  display: grid; place-items: center;
  padding: var(--sp-4);
  background: rgba(16, 13, 21, 0.72);
  backdrop-filter: blur(6px);
  overflow: auto;
}
.envio[hidden] { display: none; }
.envio__box {
  width: min(760px, 100%);
  display: grid; gap: var(--sp-4);
  padding: clamp(1.25rem, 3vw, 2rem);
  border: 1px solid var(--line-strong); border-radius: var(--r-lg);
  background: var(--ink-800);
  box-shadow: var(--shadow-card);
}
.envio__head { display: flex; align-items: flex-start; gap: var(--sp-3); }
.envio__head > div { display: grid; gap: var(--sp-2); }
.envio__x {
  margin-left: auto; width: 36px; height: 36px; flex: none;
  border: 1px solid var(--line); border-radius: 50%;
  background: transparent; color: var(--fg-muted); cursor: pointer; line-height: 1;
}
.envio__x:hover { color: var(--fg); border-color: var(--line-strong); }
.envio__intro { font-size: var(--t-sm); color: var(--fg-muted); }
.envio__grid { display: grid; gap: var(--sp-3); grid-template-columns: 1fr 1fr; }
.envio__wide { grid-column: 1 / -1; }
@media (max-width: 680px) { .envio__grid { grid-template-columns: 1fr; } }
.envio__erro { font-size: var(--t-sm); color: var(--fg); background: var(--surface-2); border-left: 3px solid var(--pink-soft); padding: var(--sp-3); border-radius: var(--r-sm); }
.envio__erro[hidden] { display: none; }
.envio__foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.envio__nota { flex: 1 1 24ch; font-size: var(--t-xs); color: var(--fg-muted); }
.envio__ok { display: grid; gap: var(--sp-3); justify-items: start; }
.envio__ok h3 { font-size: var(--t-d3); }
.campo--par { grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.resumo { display: grid; gap: var(--sp-3); }
.resumo__linha { display: flex; justify-content: space-between; gap: var(--sp-3); font-size: var(--t-sm); }
.resumo__total { display: flex; justify-content: space-between; gap: var(--sp-3); font-family: var(--font-display); font-size: 1.15rem; border-top: 1px solid var(--line-strong); padding-top: var(--sp-3); }
.resumo__desc { color: var(--fg-muted); }

/* ======================================================= Nota/estrelas === */
.notawrap { display: grid; gap: var(--sp-2); }
.notabox { display: flex; gap: 0.15rem; }
.nota {
  width: 36px; height: 36px; padding: 0; line-height: 1;
  border: 0; background: transparent; cursor: pointer;
  color: var(--fg-dim); font-size: 1.25rem;
}
.nota[aria-pressed='true'] { color: var(--gold); }
.nota:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-sm); }
/* O comentário acompanha a nota, então mora dentro do mesmo bloco e o botão
   fica à esquerda, na largura do texto — não esticado na do cartão. */
.coment { display: grid; gap: var(--sp-2); margin-top: var(--sp-2); }
.coment .btn { justify-self: start; }
.coment textarea { font-size: var(--t-sm); }

/* ===================================================== Segmentado ======== */
/* Grupo de botões mutuamente exclusivos (ciclo de cobrança). O estado marcado
   usa borda de destaque e texto de token, não preenchimento de destaque: texto
   claro sobre `--accent` rosa mede 3,63:1, abaixo do piso de 4,5:1. */
.segmented { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.segmented .btn { min-height: 44px; }
/* Quando o segmento é link em vez de botão, quem diz o estado é aria-current. */
.segmented .btn[aria-pressed='true'], .segmented .btn[aria-current='page'] {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  background: var(--surface-2);
  color: var(--fg);
}

/* ================================================== Tipo de conta ======== */
.conta {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
}
.conta > div:first-child { display: grid; gap: var(--sp-2); max-width: 62ch; }
/* Os dois véus de --surface-2 empilhavam — o da caixa e o do segmento marcado —
   e o texto caía para 4,18:1 no poente. O estado aqui fica só na borda e no anel
   de destaque, que é o que o próprio .segmented diz ser a intenção. */
.conta .segmented .btn[aria-current='page'] { background: transparent; }

/* ================================================== Popup do mapa ======== */
/* O MapLibre entrega o balão branco; sobre ele o --fg do site some. A cor vem de
   --ink-700 em vez de --surface-2 porque aquele é um véu translúcido e aqui o que
   está por baixo é o mapa, não a página.

   O .maplibregl-map na frente não é enfeite: a folha do vendor entra pelo {{styles}}
   da página, depois desta, e no empate de especificidade ela ganhava. */
.maplibregl-map .maplibregl-popup-content {
  background: var(--ink-700); color: var(--fg);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--t-sm); line-height: 1.45;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
}
.maplibregl-map .maplibregl-popup-close-button {
  color: var(--fg); font-size: 1.1rem; padding: 0 .35rem; background: transparent;
}
.maplibregl-map .maplibregl-popup-close-button:hover { color: var(--pink); }
.maplibregl-map [class*='maplibregl-popup-anchor-top'] .maplibregl-popup-tip { border-bottom-color: var(--ink-700); }
.maplibregl-map [class*='maplibregl-popup-anchor-bottom'] .maplibregl-popup-tip { border-top-color: var(--ink-700); }
.maplibregl-map .maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--ink-700); }
.maplibregl-map .maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--ink-700); }

/* O crédito do OpenStreetMap e a escala são obrigatórios e permanentes — a
   licença exige o crédito à vista. Mas eles não são conteúdo: na folha do vendor
   saem em caixa branca opaca, que no canto do mapa noturno virava o elemento mais
   claro da tela. Recuam para rodapé do desenho e voltam ao contraste cheio no
   ponteiro, para quem for ler. */
.maplibregl-map .maplibregl-ctrl-attrib,
.maplibregl-map .maplibregl-ctrl-scale {
  background: color-mix(in srgb, var(--ink-900) 62%, transparent);
  color: var(--fg-dim); opacity: 0.6;
  font-size: 0.6875rem;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.maplibregl-map .maplibregl-ctrl-scale { border-color: var(--line-strong); }
.maplibregl-map .maplibregl-ctrl-attrib a { color: var(--fg-muted); }
.maplibregl-map .maplibregl-ctrl-attrib:hover,
.maplibregl-map .maplibregl-ctrl-attrib:focus-within,
.maplibregl-map .maplibregl-ctrl-scale:hover { opacity: 1; }
/* O botão "i" da versão compacta herda a caixa branca por conta própria. */
.maplibregl-map .maplibregl-ctrl-attrib-button { background-color: transparent; }

/* ============================================ Vista ampla do mapa ========= */
/* O mapa é o conteúdo desta página, então ele toma a altura da janela inteira
   menos a barra de navegação — não entra num .wrap nem num card. A lista fica
   numa coluna que colapsa para zero, e os filtros flutuam sobre o mapa para não
   roubar altura dele. */
.mapaview {
  display: grid;
  grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
  /* `--topo-h` é medido em motion.js: aqui o mapa começa no alto do documento,
     então o que o cobre não é só a barra fixa. Sem JS, o token é o palpite mais
     próximo. */
  height: calc(100svh - var(--topo-h, var(--nav-h)));
  min-height: 420px;
  border-bottom: 1px solid var(--line);
}
.mapaview[data-lista='off'] { grid-template-columns: 0 minmax(0, 1fr); }

.mapaview__lista {
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  border-right: 1px solid var(--line);
  background: color-mix(in srgb, var(--ink-850) 92%, transparent);
}
.mapaview__topo {
  flex: none; padding: var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.mapaview__busca input {
  width: 100%; padding: var(--sp-2) var(--sp-3);
  color: var(--fg); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  font: inherit; font-size: var(--t-sm);
}
.mapaview__busca input::placeholder { color: var(--fg); opacity: 0.55; }
.mapaview__busca input:focus-visible { outline: 2px solid var(--pink); outline-offset: 1px; }
.mapaview__conta { margin: var(--sp-2) 0 0; opacity: 0.7; }

.mapaview__itens { flex: 1 1 auto; overflow-y: auto; margin: 0; padding: var(--sp-2); list-style: none; }
/* O cabeçalho de categoria é o mesmo filtro da faixa sobre o mapa: quem varre a
   lista quer isolar a categoria ali mesmo, sem procurar o chip lá embaixo. */
.mapaview__grupo {
  display: flex; align-items: center; gap: var(--sp-2); width: 100%;
  margin: var(--sp-3) 0 var(--sp-1); padding: var(--sp-1) var(--sp-2);
  font-family: var(--font-display); font-size: 0.7rem; font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.75;
  color: var(--fg); background: transparent; border: 0; border-radius: var(--r-sm);
  text-align: left; cursor: pointer;
}
.mapaview__grupo:hover { background: var(--surface-2); opacity: 1; }
.mapaview__grupo:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
/* Categoria desligada: o cabeçalho apaga junto com os itens que sumiram dela. */
.mapaview__grupo[aria-pressed='false'] { opacity: 0.35; }
.mapaview__grupo::before {
  content: ''; width: 8px; height: 8px; border-radius: 50%;
  background: var(--cat, var(--pink)); flex: none;
}
.mapaview__item {
  display: flex; flex-direction: column; gap: 2px; width: 100%;
  padding: var(--sp-2) var(--sp-3);
  color: var(--fg); text-align: left;
  background: transparent; border: 0; border-radius: var(--r-md);
  border-left: 3px solid transparent;
  font: inherit; cursor: pointer;
}
.mapaview__item:hover { background: var(--surface-2); border-left-color: var(--cat, var(--pink)); }
.mapaview__item[aria-current='true'] {
  background: var(--surface-2); border-left-color: var(--cat, var(--pink));
}
.mapaview__item-nome { font-size: var(--t-sm); font-weight: 600; }
.mapaview__item-sub {
  font-size: 0.78rem; opacity: 0.62;
  /* Descrição do My Maps pode ser longa; duas linhas bastam para reconhecer. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.mapaview__rodape {
  flex: none; margin: 0; padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--line); font-size: 0.78rem; opacity: 0.65;
}

.mapaview__mapa { position: relative; min-width: 0; }
.mapaview__mapa #mapa { position: absolute; inset: 0; }

/* Aba de recolher: fica na borda do mapa, do lado da lista. */
.mapaview__aba {
  position: absolute; top: var(--sp-4); left: var(--sp-3); z-index: 3;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  color: var(--fg); background: color-mix(in srgb, var(--ink-850) 86%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  font-family: var(--font-display); font-size: var(--t-sm); font-weight: 500;
  cursor: pointer;
}
.mapaview__aba:hover { border-color: var(--pink); }
.mapaview[data-lista='off'] .mapaview__aba span:first-child { transform: scaleX(-1); }

/* Filtros sobre o mapa, embaixo. Rolam na horizontal quando não cabem, porque
   encolher a fonte de sete categorias deixaria tudo ilegível. */
.mapaview__filtros {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: var(--sp-4) var(--sp-3) calc(var(--sp-6) + var(--sp-2));
  background: linear-gradient(to top, color-mix(in srgb, var(--ink-900) 80%, transparent), transparent);
  pointer-events: none;
}
/* As sete categorias quebram em linha: a barra de rolagem está escondida, então
   o que passa da borda não parece rolável — parece cortado. Só abaixo de 860px,
   onde quebrar comeria o mapa, a faixa volta a rolar de lado. */
.mapaview__filtros-in {
  display: flex; flex-wrap: wrap; gap: var(--sp-2); padding-bottom: 2px;
  pointer-events: auto;
  scrollbar-width: none;
}
.mapaview__filtros-in::-webkit-scrollbar { display: none; }
.mapaview__filtros-in .chip {
  flex: none;
  background: color-mix(in srgb, var(--ink-850) 86%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
/* O vidro do chip apagado vem daqui e é mais específico que a regra de ligado em
   site.css: sem repetir o preenchimento, o chip ligado ficaria neutro. */
.mapaview__filtros-in .chip[aria-pressed='true'] {
  background: var(--cat, var(--purple)); backdrop-filter: none; -webkit-backdrop-filter: none;
}

/* Na web os filtros só aparecem com a lista recolhida: com a lista aberta, os
   cabeçalhos de categoria dentro dela já acionam o mesmo filtro, e duas faixas do
   mesmo controle na tela disputam a atenção. No celular a lista fica embaixo do
   mapa, não ao lado, então a faixa segue sendo o filtro à vista sobre o mapa. */
.mapaview[data-lista='on'] .mapaview__filtros { display: none; }

/* Os controles do MapLibre precisam subir acima da faixa de filtros. */
.mapaview__mapa .maplibregl-ctrl-bottom-left,
.mapaview__mapa .maplibregl-ctrl-bottom-right { z-index: 4; }

@media (max-width: 860px) {
  /* Em coluna a lista não pode ter altura de janela cheia, senão o mapa some
     abaixo da dobra e a página abre sem mapa nenhum. */
  .mapaview, .mapaview[data-lista='off'] {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 58svh auto;
    height: auto; min-height: 0;
  }
  .mapaview__lista {
    grid-row: 2; border-right: 0; border-top: 1px solid var(--line);
    max-height: 70svh;
  }
  .mapaview[data-lista='off'] .mapaview__lista { display: none; }
  .mapaview__mapa { grid-row: 1; }
  .mapaview__aba { top: auto; bottom: var(--sp-3); right: var(--sp-3); left: auto; }
  .mapaview[data-lista='on'] .mapaview__filtros { display: block; }
  .mapaview__filtros { padding-bottom: var(--sp-6); }
  .mapaview__filtros-in { flex-wrap: nowrap; overflow-x: auto; }
}

/* O rolê abre sobre o próprio mapa; agenda e marcador usam a mesma ficha. */
.rolepop { position:absolute; z-index:8; right:12px; bottom:12px; width:min(380px,calc(100% - 24px)); max-height:calc(100% - 24px); overflow:auto; padding:var(--sp-4); border:1px solid var(--line-strong); border-radius:var(--r-lg); background:var(--bg); color:var(--fg); box-shadow:var(--shadow-card); }
.rolepop[hidden], [data-roles-period][hidden] { display:none; }
.rolepop img { display:block; max-width:100%; height:auto; margin-block:var(--sp-3); }
[data-roles-period] { flex-basis:100%; display:grid; gap:var(--sp-2); }
[data-roles-period] label { display:flex; align-items:center; justify-content:space-between; gap:var(--sp-2); }
[data-roles-period] input { min-width:0; font:inherit; color:var(--fg); background:var(--bg); border:1px solid var(--line-strong); border-radius:var(--r-sm); padding:var(--sp-2); }
