/* =============================================================================
   Agroonnet · app
   Base compartilhada em ../assets/comum.css. Aqui só a composição das telas.
   ============================================================================= */

/* A navegação inferior é fixa e cobriria o fim da página. Dentro do aparelho
   simulado ela não é fixa, então a folga vira sobra e sai. */
main { padding-bottom: 92px; }
.palco[data-largura] > main { padding-bottom: 0; }
.palco[data-largura] .rodape { padding-bottom: var(--space-6); }

.topo__interno,
.abertura,
.secao,
.anuncios,
.perfil-pagina,
.detalhe,
.campanha,
.sobre,
.topo-da-pagina,
.voltar {
  width: 100%;
  max-width: var(--content-max-marketing);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.carregando {
  padding: var(--space-12) var(--space-4);
  text-align: center;
  color: var(--ink-faint);
}

/* ── Topo ─────────────────────────────────────────────────────────────────── */

.topo {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg-raised) 92%, transparent);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(8px);
}

.topo__interno {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 60px;
  padding-block: 9px;
}

.topo__marca { flex: 0 0 auto; line-height: 0; }
.topo__marca img { width: 124px; height: auto; }

.topo__acoes { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.topo__entrar { display: none; }

/* Atalho para as três páginas de venda. Escondido por padrão e ligado só no
   desktop (bloco @container lá embaixo): no celular o cabeçalho já divide
   espaço entre a marca e os botões de conta, e a barra inferior é o caminho
   natural para navegação por ali.

   A regra precisa vir ANTES do bloco de desktop — as duas têm a mesma
   especificidade, então quem estiver por último vence, e com ela no fim do
   arquivo o atalho ficava invisível em qualquer largura. */
.topo__personas { display: none; }

/* Menu de perfis do celular (msg 287828). O botão some no desktop, onde os três
   atalhos já ficam escritos no cabeçalho. */
/* Sem `margin-left: auto` aqui: quem empurra o grupo da direita é `.topo__acoes`,
   que vem antes desde a inversão de 24/08. Com os dois auto, o segundo abria uma
   folga entre a conta e o hambúrguer — a distância que o Gustavo circulou na
   msg 380982. Agora a separação é só o `gap` do `.topo__interno`. */
.topo__hamburguer {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: var(--radius-button);
  background: var(--bg-raised);
  color: var(--ink);
  cursor: pointer;
}
.topo__hamburguer svg { width: 20px; height: 20px; }
.topo__hamburguer.is-aberto { border-color: var(--brand-600); color: var(--brand-700); }

.personas-painel {
  display: grid;
  padding: var(--space-2) var(--space-4) var(--space-3);
  border-top: 1px solid var(--line-soft);
  background: var(--bg-raised);
}
.personas-painel a {
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
  color: var(--ink);
  font: var(--text-button);
  text-decoration: none;
}
.personas-painel a + a { border-top: 1px solid var(--line-soft); }

/* ── Voltar ───────────────────────────────────────────────────────────────── */

.voltar {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--touch-min);
  margin-top: var(--space-3);
  color: var(--ink-soft);
  font: var(--text-button);
  text-decoration: none;
}
.voltar svg { width: 20px; height: 20px; }
@media (hover: hover) { .voltar:hover { color: var(--brand-700); } }

/* O nome da página na mesma linha da seta de voltar, a pedido do Gustavo
   (461622, com print). Economiza a linha que a etiqueta ocupava sozinha, e o
   título da tela sobe junto. Só a tela de Planos usa por enquanto — se virar
   padrão das outras, é esta regra que passa a vestir todas.

   O `margin-top` sai do `.voltar` e vem para o contêiner, senão o flex
   alinharia a seta e o título por baixas diferentes. */
.topo-da-pagina {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-3);
}
/* Dentro do topo quem carrega a largura e o respiro lateral da página é o
   contêiner, então o `.voltar` volta a medir só o que ele mostra — a seta.
   Sem isto ele mantém o `width: 100%` do grupo de contêineres lá de cima e
   empurra o título para fora da tela. */
.topo-da-pagina .voltar {
  width: auto;
  margin-top: 0;
  /* `margin-inline: 0` e não só o `width`: o grupo de contêineres também dá
     `margin-inline: auto`, e num item de flex a margem `auto` come todo o
     espaço livre da linha — a seta ia parar no meio da tela e o título, na
     borda direita. */
  margin-inline: 0;
  padding-inline: 0;
  /* `min-width` porque o `padding-inline: 0` acima deixava só o <svg> de 20x20
     como área tocável: `.voltar` garante `min-height: var(--touch-min)`, e o
     toque mínimo do projeto acabava valendo só na vertical. `justify-content`
     mantém a seta encostada à esquerda, onde ela sempre esteve — o alvo cresce
     para a direita, sobre espaço que já era vazio. */
  min-width: var(--touch-min);
  justify-content: flex-start;
}
/* O título do topo É a pílula verde que morava no hero, trazida para cá pelo
   print da 462184 (*"é só subir com a etiqueta"*): a flecha dele sai da
   etiqueta e aponta para a linha da seta, onde o texto "Planos" estava
   riscado. Com isso a palavra aparece uma vez só e o hero abre no título. */
.topo-da-pagina__titulo {
  margin: 0;
  padding: 6px 16px;
  border-radius: var(--radius-pill);
  background: var(--brand-100);
  color: var(--brand-700);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* ── Abertura ─────────────────────────────────────────────────────────────── */

.abertura { padding-block: var(--space-8) var(--space-4); }
.abertura--compacta { padding-block: var(--space-6) var(--space-4); }

.abertura__titulo {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(26px, 5.2cqi, 40px);
  line-height: 1.15;
  color: var(--ink);
  text-wrap: balance;
}

.abertura__apoio {
  margin: 0 0 var(--space-6);
  max-width: 48ch;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.abertura__controles {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: var(--space-6);
}

/* ── Comércio: o topo ganhou ação, e o vão encurtou ───────────────────────────
   Pedido do Gustavo na msg 457356, com print anotado. Duas coisas na mesma
   tela: um botão "Anunciar aqui" no vazio ao lado do título ("do jeito que está
   ta escondido demais") e o vão entre o filtro e "Principais categorias" ("tire
   aquele espaço grande que tem ali, encurta").

   O vão era a soma de dois espaços que ninguém tinha visto juntos: o
   `margin-bottom` dos controles mais o `padding-top` da seção seguinte. Some
   só aqui, na tela que ele apontou — as outras aberturas seguem iguais. */
.abertura--comercio .abertura__controles { margin-bottom: var(--space-2); }
.abertura--comercio + .secao { padding-top: var(--space-4); }

.abertura__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
/* O título encolhe antes do botão: cortar "Anunciar aqui" ao meio deixaria a
   ação ilegível, e é ela que o pedido veio buscar. */
.abertura__topo .abertura__titulo { flex: 1 1 auto; min-width: 0; margin-bottom: 0; }
.abertura__acao { flex: 0 0 auto; white-space: nowrap; }

/* ── Busca e filtros ──────────────────────────────────────────────────────── */

/* `flex: 1 1 auto` e não uma base em px: em coluna a base do flex é ALTURA, e
   uma base de 260px estica o campo de busca verticalmente. A base horizontal
   entra só no breakpoint em que os controles viram linha. */
.busca { position: relative; flex: 1 1 auto; }

.busca__lupa {
  position: absolute;
  left: 16px; top: 50%;
  transform: translateY(-50%);
  width: 20px; height: 20px;
  color: var(--ink-soft);
  pointer-events: none;
}
.busca input {
  min-height: 54px;
  padding-left: 46px;
  padding-right: 46px;
  box-shadow: var(--shadow-card);
}
.busca input::-webkit-search-cancel-button { display: none; }

.busca__limpar {
  position: absolute;
  right: 8px; top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  border: 0;
  border-radius: 50%;
  background: var(--line-soft);
  color: var(--ink-soft);
  cursor: pointer;
}
.busca__limpar svg { width: 15px; height: 15px; stroke-width: 2.2; }

.uf, .ordem { position: relative; display: flex; align-items: center; flex: 1 1 auto; }
.uf svg {
  position: absolute;
  left: 12px;
  width: 18px; height: 18px;
  color: var(--ink-soft);
  pointer-events: none;
}
.uf select { padding-left: 36px; }
.uf select, .ordem select {
  min-height: 48px;
  font-size: 15px;
  font-weight: 500;
}

.controles { display: flex; flex-direction: column; gap: 10px; margin-bottom: var(--space-4); }
.controles__linha { display: flex; gap: 10px; }

/* Botão que abre o painel de filtros (msg 287839). Mesma altura dos selects ao
   lado, para a linha não ficar torta. O contador é o que permite recolher sem
   esconder: dá para ver que há filtro ligado sem abrir. */
.btn-filtros {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  min-height: 48px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-input);
  background: var(--bg-raised);
  color: var(--ink);
  font: var(--text-button);
  cursor: pointer;
}
.btn-filtros:hover { border-color: var(--brand-500); }
.btn-filtros.is-aberto { border-color: var(--brand-600); color: var(--brand-700); }
.btn-filtros__icone { display: grid; place-items: center; }
.btn-filtros__icone svg { width: 18px; height: 18px; }
.btn-filtros__conta {
  display: grid;
  place-items: center;
  min-width: 22px; height: 22px;
  padding: 0 6px;
  border-radius: var(--radius-pill);
  background: var(--brand-600);
  color: #fff;
  font: var(--text-small);
  font-weight: 700;
}

.painel-filtros {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}

.chips { display: flex; gap: 7px; overflow-x: auto; padding-block: 2px; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }

.chip {
  flex: 0 0 auto;
  min-height: 38px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--bg-raised);
  color: var(--ink-soft);
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .15s ease-out, border-color .15s ease-out, color .15s ease-out;
}
.chip.is-ativo { background: var(--brand-700); border-color: var(--brand-700); color: #fff; }

.contagem { margin: 0 0 var(--space-4); font: var(--text-small); color: var(--ink-faint); }

/* ── Filtros finos: avaliação e tempo de cadastro ─────────────────────────── */

.finos { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.finos__estrelas { display: flex; align-items: center; gap: 7px; }
.finos__rotulo { font-size: 12.5px; font-weight: 600; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .04em; }

.chip--estrela { display: inline-flex; align-items: center; gap: 5px; }
.chip--estrela svg { width: 14px; height: 14px; color: var(--warning); }
.chip--estrela.is-ativo svg { color: #fff; }

.finos__tempo { display: flex; align-items: center; gap: 7px; flex: 1 1 auto; min-width: 190px; }
.finos__tempo select { min-height: 38px; flex: 1 1 auto; font-size: 13.5px; }

/* ── Filtros aplicados ────────────────────────────────────────────────────── */

/* Combinar critérios até a lista sumir é fácil; entender qual deles fez isso,
   não. Cada filtro ligado fica visível e some com um toque. */
.ativos { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }

.ativo {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 34px;
  padding: 0 10px 0 12px;
  border: 1px solid var(--brand-700);
  border-radius: var(--radius-pill);
  background: var(--brand-100);
  color: var(--brand-700);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.ativo__x { font-size: 17px; line-height: 1; opacity: .75; }
.ativo:hover { background: var(--brand-700); color: #fff; }

.ativos__limpar {
  min-height: 34px;
  padding: 0 8px;
  border: 0;
  background: none;
  color: var(--ink-faint);
  font-size: 13px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.ativos__limpar:hover { color: var(--ink); }

.vazio__acoes { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: var(--space-4); }

/* ── Modal e comprovante ──────────────────────────────────────────────────────
   Peso de recibo, não de aviso passageiro: quem se candidata precisa sair da
   tela com certeza de que o pedido chegou. */

.modal {
  width: min(420px, calc(100vw - 32px));
  padding: 0;
  border: 0;
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  color: var(--ink);
  box-shadow: 0 24px 60px rgb(0 0 0 / .28);
}
.modal::backdrop { background: rgb(16 20 15 / .55); }

.modal__caixa { padding: var(--space-6) var(--space-6) var(--space-6); text-align: center; }

.modal__selo {
  width: 62px; height: 62px;
  margin: 0 auto var(--space-4);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--brand-100);
  color: var(--brand-700);
}
.modal__selo svg { width: 34px; height: 34px; stroke-width: 2.4; }

.modal__titulo { margin: 0 0 8px; font: var(--text-h3, 600 20px/1.3 inherit); }
.modal__texto { margin: 0 0 var(--space-4); color: var(--ink-soft); font-size: 14.5px; line-height: 1.55; }

/* Um degrau abaixo do texto do modal: é o aviso de para onde o botão leva, não
   a informação que decide a compra. Mesmo peso da dica de campo. */
.modal__texto--apoio { font: var(--text-small); color: var(--ink-faint); }

/* O campo de documento dentro do modal de assinatura (msg 478626). Herda o
   `.campo` do resto do app; só ganha respiro em cima, para não colar na caixa
   da cláusula, e alinhamento à esquerda, porque o modal centraliza o texto. */
.campo--modal { margin: var(--space-4) 0; text-align: left; }

/* A parte que parece recibo: rótulo à esquerda, valor à direita, linha a linha. */
.comprovante {
  margin: 0 0 var(--space-4);
  padding: var(--space-4);
  border: 1px dashed var(--line);
  border-radius: var(--radius-button);
  background: var(--bg);
  text-align: left;
}
.comprovante > div { display: flex; justify-content: space-between; gap: var(--space-4); padding: 6px 0; }
.comprovante > div + div { border-top: 1px solid var(--line); }
.comprovante dt { flex: 0 0 auto; font-size: 12.5px; font-weight: 600; color: var(--ink-faint); }
.comprovante dd { margin: 0; text-align: right; font-size: 13.5px; font-weight: 600; }

/* Onde a resposta vai chegar. Sem isso a pessoa fica esperando dentro do app
   uma conversa que acontece fora dele. */
.modal__dica {
  margin: 0 0 var(--space-4);
  padding: 12px 14px;
  border-radius: var(--radius-button);
  background: var(--brand-100);
  color: var(--ink);
  font-size: 13.5px;
  line-height: 1.5;
  text-align: left;
}
.modal__dica b { display: block; color: var(--brand-700); }

/* ── Avaliar um perfil (migration 48, msgs 467603 e 467751) ──────────────────
   As estrelas do formulário são botão, não enfeite: 44px de alvo, que é o
   mínimo para o dedo acertar a quarta estrela sem ampliar a tela. As do
   carrossel (.prova__estrela) continuam com 17px porque ali ninguém toca. */
.avaliar-estrelas {
  display: flex;
  justify-content: center;
  gap: var(--space-1);
  margin: 0 0 var(--space-4);
}
.avaliar-estrela {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-button);
  background: none;
  cursor: pointer;
}
.avaliar-estrela svg {
  width: 30px; height: 30px;
  color: var(--line);
  fill: currentColor;
  stroke: none;
  transition: color .12s ease, transform .12s ease;
}
.avaliar-estrela.is-cheia svg { color: #F5B301; }
.avaliar-estrela:hover svg { transform: scale(1.08); }
.avaliar-estrela:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }

.modal__erro {
  margin: var(--space-3) 0 0;
  color: var(--error);
  font-size: 13.5px;
  font-weight: 600;
  text-align: left;
}

/* Fica colado no fim do bloco de Reputação, que é onde a pessoa acabou de ler
   as notas dos outros — e não na capa, longe do assunto. */
.reputacao__avaliar { margin-top: var(--space-4); }

.modal__acoes { display: grid; gap: 8px; margin-top: var(--space-4); }
.modal__caixa--comprovante .modal__acoes { margin-top: 0; }

/* A perda vem antes da explicação: é o que muda a decisão de quem já está com o
   dedo no botão. */
.modal__perda {
  margin: 0 0 var(--space-4);
  padding: 12px 14px;
  border-radius: var(--radius-button);
  background: color-mix(in srgb, var(--perigo, #B3261E) 9%, transparent);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
  text-align: left;
}
.modal__perda b { display: block; color: var(--perigo, #B3261E); font-size: 15px; }

/* A cláusula de WhatsApp que o cliente pediu antes da compra (msg 410452).
   Fundo próprio e não texto solto porque é o trecho que a pessoa precisa
   conseguir apontar depois — "eu autorizei isto aqui". Alinhado à esquerda no
   meio de um modal centralizado, pela mesma razão de `.modal__dica`: lista de
   itens centralizada não se lê. */
.clausula {
  margin: 0 0 var(--space-3);
  padding: 12px 14px;
  border-radius: var(--radius-button);
  background: var(--bg);
  border: 1px solid var(--line-soft);
  text-align: left;
}
.clausula__titulo {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 700;
  color: var(--brand-700);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.clausula__texto { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); }
.clausula__lista {
  margin: 8px 0;
  padding-left: 18px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink);
}

/* O alvo de toque é a linha inteira, não o quadradinho de 16px: no celular,
   errar a caixa e não conseguir habilitar o botão é o jeito mais bobo de perder
   uma assinatura. */
.clausula__aceite {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 0 0 var(--space-2);
  padding: 10px 4px;
  font-size: 14px;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
}
.clausula__aceite input { width: 20px; height: 20px; flex: none; margin-top: 1px; accent-color: var(--brand-700); }

/* Quem exclui a conta tem direito de saber o que sai e o que fica — sobretudo
   que a avaliação que ele deu a outra pessoa não desaparece junto. */
.consequencia { margin: 0 0 var(--space-4); text-align: left; }
.consequencia__titulo {
  margin: var(--space-3) 0 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: .05em;
}
.consequencia__titulo:first-child { margin-top: 0; }
.consequencia ul { margin: 0; padding-left: 18px; }
.consequencia li { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); }

/* A lista do que se perde ao cancelar (msg 478655). Cada item com o cadeado —
   o mesmo ícone que o app usa para "isto é do plano pago" —, porque é
   literalmente o estado para o qual a pessoa está voltando. */
.perde-lista { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.perde-lista li { display: flex; align-items: flex-start; gap: 8px; font-size: 14px; line-height: 1.45; }
.perde-lista li svg { flex: 0 0 auto; width: 15px; height: 15px; margin-top: 2px; color: var(--perigo, #B3261E); }

/* O botão que cancela é o DISCRETO, e só o texto é vermelho: aqui o caminho
   fácil tem que ser ficar. Pintar de vermelho sólido faria da saída a coisa
   mais chamativa da tela — o contrário do que o cliente pediu. */
.btn--perde { color: var(--perigo, #B3261E); }
.btn--perde:hover { background: color-mix(in srgb, var(--perigo, #B3261E) 8%, transparent); }

.btn--perigo { background: var(--perigo, #B3261E); border-color: var(--perigo, #B3261E); color: #fff; }
.btn--perigo:hover { filter: brightness(1.08); }

/* ── Quem se candidatou ───────────────────────────────────────────────────────
   Uma linha por pessoa, com o WhatsApp na ponta — o desenho que o cliente
   mandou em 18/08 (msg 287847). Cabem quatro na primeira tela do celular, onde
   antes cabia um cartão e meio. */

.interessados { display: grid; gap: 2px; margin: var(--space-3) 0 0; padding: 0; list-style: none; }

.interessado {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px 4px;
  border-bottom: 1px solid var(--line-soft);
}
.interessado:last-child { border-bottom: 0; }

.interessado__quem {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 1 1 auto;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.interessado__foto {
  flex: 0 0 auto;
  width: 48px; height: 48px;
  border-radius: var(--radius-pill);
  overflow: hidden;
  background: var(--brand-100);
  color: var(--brand-600);
}
.interessado__foto img,
.interessado__foto svg { width: 100%; height: 100%; object-fit: cover; }

.interessado__texto { display: grid; gap: 1px; min-width: 0; }
.interessado__texto strong { font: var(--text-h3); }
.interessado__texto strong,
.interessado__onde,
.interessado__faz { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.interessado__onde { font: var(--text-small); color: var(--ink-soft); }
.interessado__faz { font: var(--text-small); color: var(--ink-faint); }

.interessado__fim { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.interessado__nota {
  display: flex;
  align-items: center;
  gap: 3px;
  font: var(--text-small);
  font-weight: 700;
  color: var(--ink);
}
.interessado__nota svg { width: 15px; height: 15px; color: var(--warning); fill: var(--warning); }

/* "Status de contratado" (Anexo I §2.3.2). Contorno quando é uma ação a fazer,
   preenchido quando já é um fato — o mesmo botão conta as duas histórias, e o
   produtor lê a lista inteira de relance sem abrir ninguém. */
.interessado__contratar {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--bg-raised);
  color: var(--ink-faint);
  cursor: pointer;
  transition: border-color .15s ease-out, color .15s ease-out, background .15s ease-out;
}
.interessado__contratar svg { width: 20px; height: 20px; }
.interessado__contratar.is-ativo {
  background: var(--brand-700);
  border-color: var(--brand-700);
  color: #fff;
}
@media (hover: hover) {
  .interessado__contratar:hover { border-color: var(--brand-700); color: var(--brand-700); }
  .interessado__contratar.is-ativo:hover { color: #fff; }
}
.interessado__contratar.is-carregando > svg { visibility: hidden; }
.interessado__contratar.is-carregando::after {
  content: "";
  position: absolute;
  width: 16px; height: 16px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: agn-spin .7s linear infinite;
}

.interessado__zap {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--whatsapp);
  color: #05331A;
  cursor: pointer;
}
.interessado__zap svg { width: 22px; height: 22px; }
.interessado__zap.is-carregando > svg { visibility: hidden; }
.interessado__zap.is-carregando::after {
  content: "";
  position: absolute;
  width: 16px; height: 16px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: agn-spin .7s linear infinite;
}

.interessado__seta { display: grid; place-items: center; width: 28px; color: var(--ink-faint); }
.interessado__seta svg { width: 18px; height: 18px; }

.interessados__aviso {
  margin: var(--space-3) 0 0;
  padding: 10px 12px;
  border-radius: var(--radius-button);
  background: var(--brand-100);
  font: var(--text-small);
  color: var(--brand-700);
}

/* Para quem publicou, esta é a primeira coisa da página. */
.bloco--interessados { margin-top: var(--space-4); }

/* ── Contratar: as duas metades ───────────────────────────────────────────────
   "Postar vaga" e "Ver trabalhadores" dividem a barra em dois, com a metade
   ativa preenchida — desenho do app em Bubble (msg 287846). Alvo de 48px em
   cada uma: é barra de troca, tocada com o polegar.

   Mora no cabeçalho da seção, como as outras ações: no celular ocupa a linha
   inteira embaixo do título; a partir do desktop encosta à direita, na mesma
   altura do "Trabalhadores". Quem faz isso é o `.secao__acoes`, e é por isso
   que a barra carrega as duas classes. */

.abas-vaga {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  /* "Muito junto também, dar uma separadinha" — msg 380983. Eram três blocos
     diferentes (gerenciar, abas, trilha de etapas) empilhados com o mesmo
     respiro curto, e o olho lia tudo como um bloco só. */
  gap: var(--space-4);
  flex-wrap: wrap;
}

.abas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* Duas peças soltas, não uma barra segmentada — pedido do Gustavo em 24/08
     (msg 346622), comparando com o app em Bubble: lá "Postar vaga" e "Ver
     trabalhadores" são dois botões próprios, com espaço entre os dois, em vez
     de dividir um mesmo fundo cinza. */
  gap: 8px;
  /* No celular as duas metades tomam a linha inteira. A partir do tablet a
     barra volta a ter largura natural, ao lado do título. */
  flex: 1 1 100%;
  min-width: 0;
}

.aba {
  display: grid;
  place-items: center;
  min-height: 44px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--bg-raised);
  color: var(--ink-soft);
  font: var(--text-button);
  /* Em 320px "Ver trabalhadores" quebrava em duas linhas e a barra ficava
     desencontrada. Uma linha só, sempre: a fonte acompanha a largura do
     container e vai até 11,5px na tela mais estreita que atendemos. */
  white-space: nowrap;
  font-size: clamp(13px, 4cqi, 15px);
  text-align: center;
  text-decoration: none;
}
/* Seletor "Serviços | Produtores" em cima da lista, no lugar da tela de escolha
   que existia antes (msg 380987). Precisa de respiro embaixo para não colar na
   busca, que vem logo em seguida. */
.abas--trabalhar { margin: 0 0 var(--space-4); }

.aba.is-ativa { border-color: var(--brand-700); background: var(--brand-700); color: #fff; box-shadow: var(--shadow-card); }
@media (hover: hover) {
  .aba:not(.is-ativa):hover { border-color: var(--brand-700); color: var(--brand-700); }
}

/* ── Publicar vaga ────────────────────────────────────────────────────────────
   Primeira tela de escrita do app, em três etapas desde 18/08 (msg 287846).
   Uma coluna, campos largos: quem publica costuma estar no meio do serviço,
   com uma mão só. */

/* Trilha das etapas. A linha que liga as bolas nasce da própria bola, com
   ::before, para não depender de um elemento vazio no HTML. */
.passos {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  /* Margem no topo também: a trilha encostava nas abas logo acima e os dois
     viravam uma coisa só (msg 380983). */
  margin: var(--space-4) 0 var(--space-6);
  padding: 0;
  list-style: none;
}

.passos__item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--ink-faint);
  font: var(--text-small);
  text-align: center;
}

.passos__item::before {
  content: "";
  position: absolute;
  top: 15px;
  right: 50%;
  left: -50%;
  height: 2px;
  background: var(--line);
}
.passos__item:first-child::before { display: none; }

.passos__bola {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border-radius: var(--radius-pill);
  background: var(--line-soft);
  color: var(--ink-faint);
  font-weight: 700;
}

.passos__item.is-atual { color: var(--brand-700); font-weight: 600; }
.passos__item.is-atual .passos__bola { background: var(--brand-600); color: #fff; }
.passos__item.is-feito { color: var(--brand-700); }
.passos__item.is-feito .passos__bola { background: var(--brand-100); color: var(--brand-700); }
.passos__item.is-feito::before,
.passos__item.is-atual::before { background: var(--brand-500); }

.passo { display: grid; gap: var(--space-4); margin: 0; padding: 0; border: 0; }

/* `min-width: 0` nos filhos, e é o conserto de dois defeitos que o Luiz
   apontou na mesma mensagem (431305): "os botões de voltar e continuar estão
   muito grandes, nem dá pra ver o que está escrito" e "não consigo rolar para
   o lado para selecionar as outras culturas, nem os outros estados e nem os
   municípios".

   Eram o mesmo bug. Item de grid nasce com `min-width: auto`, que o proíbe de
   ficar menor que o próprio conteúdo — então o `overflow-x: auto` de `.chips`
   nunca entrava em ação: em vez de rolar dentro da faixa, a fileira de chips
   esticava o `.campo`, que esticava o `.passo`, que esticava o formulário para
   além da largura da tela. Os chips ficavam cortados na borda (sem rolagem) e
   os botões `btn--bloco`, que valem 100% do contêiner, esticavam junto — com o
   texto centralizado indo parar fora do campo visível.

   Passou no meu teste porque eu media `documentElement.scrollWidth`, e o
   estouro acontecia dentro do palco, que tem rolagem própria. O print do
   aparelho dele pegou o que a medição errada não pegava. */
.passo > * { min-width: 0; }
.passo__titulo { padding: 0; font: var(--text-h3); color: var(--ink); }

/* Serviços em grade, como no app atual: tudo à vista e alvo grande, em vez de
   uma lista suspensa que esconde onze opções atrás de um toque. */
.grade-servicos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 8px;
}

.servico-op {
  min-height: 72px;
  padding: 8px 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  color: var(--ink);
  font: var(--text-small);
  font-weight: 500;
  line-height: 1.25;
  cursor: pointer;
}
@media (hover: hover) {
  .servico-op:hover { border-color: var(--brand-500); }
}
.servico-op.is-ativo {
  border-color: var(--brand-600);
  background: var(--brand-100);
  color: var(--brand-700);
  font-weight: 700;
}

.form-vaga { display: grid; gap: var(--space-4); }
.form-vaga__linha { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.campo--uf { max-width: 110px; }

.form-vaga textarea {
  min-height: 110px;
  padding: 12px 14px;
  font-family: inherit;
  font-size: 15px;
  line-height: 1.5;
  resize: vertical;
}

.campo__opcional {
  margin-left: 6px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-faint);
  text-transform: none;
  letter-spacing: 0;
}

.form-vaga__acoes { display: grid; gap: 8px; margin-top: var(--space-2); }

.campo__rotulo-solto {
  display: block;
  margin-bottom: 8px;
  font: var(--text-small);
  font-weight: 600;
  color: var(--ink-soft);
}

/* Checkbox de linha única — "só quem tem plano", "repetir todo dia". Alvo de
   44px pro toque, como o resto do app, mesmo sendo só um checkbox nativo. */
/* O "selecionar todos" fica solto acima da grade de chips, não dentro de um
   `.campo` próprio: ele governa a lista logo abaixo, e um campo inteiro entre
   os dois quebraria essa leitura. */
.campo--check-solto { margin-bottom: var(--space-3); }

.campo--check {
  /* `.campo` global já é `display: flex; flex-direction: column` — sem
     redeclarar a direção aqui, o input e o texto empilhavam em vez de ficar
     lado a lado, porque `.campo--check` nunca chegava a disputar essa
     propriedade com a regra genérica. */
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  min-height: var(--touch-min);
  cursor: pointer;
}
.campo--check input { width: 20px; height: 20px; accent-color: var(--brand-600); flex: 0 0 auto; }
.campo--check span { font: var(--text-body); }

/* ── Central de disparo ───────────────────────────────────────────────────── */

.modelos-disparo { display: grid; gap: 8px; }

.modelo-disparo {
  display: grid;
  gap: 6px;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  text-align: left;
  cursor: pointer;
}
.modelo-disparo:disabled {
  cursor: not-allowed;
  opacity: .6;
  background: var(--line-soft);
}
@media (hover: hover) {
  .modelo-disparo:not(:disabled):hover { border-color: var(--brand-500); }
}
.modelo-disparo.is-ativo { border-color: var(--brand-600); background: var(--brand-100); }

.modelo-disparo__cabeca { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.modelo-disparo__corpo { font: var(--text-small); color: var(--ink-soft); }
.modelo-disparo__status { font: var(--text-small); color: var(--warning); font-weight: 600; }

.cartao--disparo .cartao__linha--forte { min-height: 22px; }

.disparo-resumo {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin: var(--space-3) 0;
}
.disparo-resumo__item {
  display: grid;
  gap: 2px;
  padding: var(--space-3);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  text-align: center;
}
.disparo-resumo__item b { font: var(--text-h2); }
.disparo-resumo__item span { font: var(--text-small); color: var(--ink-soft); }
.disparo-resumo__item--erro b { color: var(--error); }

.disparo-previa {
  padding: var(--space-3);
  border-radius: var(--radius-card);
  background: var(--brand-100);
  color: var(--ink);
  font: var(--text-body);
  white-space: pre-wrap;
}

.disparo-contagem {
  margin: var(--space-3) 0;
  padding: 10px 14px;
  border-radius: var(--radius-pill);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  display: inline-block;
  font: var(--text-small);
}

/* ── Minhas vagas ─────────────────────────────────────────────────────────── */

/* Era `var(--space-5)`, token que não existe no conjunto gerado — sem fallback
   o navegador descarta a declaração inteira e a margem virava zero, colando o
   botão na grade. É o "espaçozinho" apontado na demo de 17/08. */
.mais--topo { margin: 0 0 var(--space-6); }

.cartao--vaga.is-encerrada { opacity: .72; }
.cartao--vaga.is-encerrada .cartao__nome { text-decoration: line-through; text-decoration-thickness: 1px; }

.cartao__linha--forte { margin-top: 10px; font-size: 14.5px; }
.cartao__linha--forte b { color: var(--brand-700); }
.cartao__discreto { color: var(--ink-faint); font-size: 13.5px; }

/* Em tela estreita os dois botões do cartão dividem a linha em vez de o
   "Encerrar" ficar espremido num canto. */
.cartao--vaga .cartao__acoes { display: flex; gap: 8px; align-items: center; }
.cartao--vaga .cartao__acoes .btn--bloco { flex: 1 1 auto; }

/* ── Menu por papel ───────────────────────────────────────────────────────── */

.menu-titulo {
  margin: var(--space-6) 0 var(--space-3);
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: .06em;
}
.menu-titulo:first-of-type { margin-top: var(--space-4); }

/* O bloco do papel tem peso maior, mas o resto continua logo abaixo: organizar
   não é esconder. */
.menu-lista--destaque .menu-item { border-color: var(--brand-200, var(--line)); background: var(--brand-100); }
.menu-lista--destaque .menu-item strong { color: var(--brand-700); }

.menu-conta { margin-top: var(--space-3); }
.menu-conta .nota-rodape { margin-top: 8px; text-align: center; }

/* Perfil de quem está logado, no topo. Some antes do nome quando falta largura. */
.topo__conta { display: inline-flex; align-items: center; gap: 7px; }
.topo__perfil {
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--brand-100);
  color: var(--brand-700);
  font-size: 11.5px;
  font-weight: 700;
}
@media (max-width: 400px) { .topo__perfil { display: none; } }

/* ── Região em destaque ───────────────────────────────────────────────────── */

.uf__rotulo {
  position: absolute;
  top: -8px; left: 10px;
  padding: 0 5px;
  background: var(--bg);
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: .05em;
  pointer-events: none;
}
.uf.is-ativo select { border-color: var(--brand-700); color: var(--brand-700); font-weight: 600; }
.uf.is-ativo svg { color: var(--brand-700); }

/* ── Portas por perfil ────────────────────────────────────────────────────── */

.portas { display: grid; gap: 10px; }

.porta {
  --cor: var(--brand-600);
  --cor-bg: var(--brand-100);
  display: grid;
  grid-template-columns: 46px 1fr 20px;
  align-items: center;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  text-decoration: none;
  transition: border-color .18s ease-out, box-shadow .18s ease-out, transform .12s ease-out;
}
.porta[data-perfil="produtor"]    { --cor: var(--track-produtor);    --cor-bg: var(--track-produtor-bg); }
.porta[data-perfil="trabalhador"] { --cor: var(--track-trabalhador); --cor-bg: var(--track-trabalhador-bg); }
.porta[data-perfil="empresa"]     { --cor: var(--track-empresa);     --cor-bg: var(--track-empresa-bg); }

@media (hover: hover) {
  .porta:hover { border-color: var(--cor); box-shadow: var(--shadow-card); }
  .porta:hover .porta__icone { background: var(--cor); color: #fff; }
}
.porta:active { transform: scale(.995); }

.porta__icone {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border-radius: var(--radius-input);
  background: var(--cor-bg);
  color: var(--cor);
  transition: background-color .18s ease-out, color .18s ease-out;
}
.porta__icone svg { width: 25px; height: 25px; }

.porta__texto { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.porta__texto strong { font: var(--text-h3); color: var(--ink); }
.porta__texto span { font: var(--text-small); color: var(--ink-soft); }
.porta__texto b { color: var(--cor); font-weight: 700; }

.porta__seta { color: var(--ink-faint); }
.porta__seta svg { width: 20px; height: 20px; }

/* ── Carrossel de anunciantes ─────────────────────────────────────────────── */

.anuncios { padding-block: var(--space-4) var(--space-6); }

.anuncios__cabeca {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: 8px;
}

.anuncios__marca {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-right: auto;
}

/* "Anuncie aqui seu banner" — texto sublinhado, não botão, a pedido do Gustavo
   (msg 411102). Um botão com a mesma forma dos outros, ao lado de anúncios de
   produto, lia-se como "anuncie um produto". Texto pequeno diz que é outra
   coisa; o sublinhado é o que mantém a pista de que dá para clicar depois de
   tirar a forma de botão. */
.anuncios__cta-texto {
  font-size: 12px;
  font-weight: 600;
  color: var(--brand-700);
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}

.anuncios__marca { margin-right: auto; }
.anuncios__setas { display: none; gap: 6px; }

.anuncios__seta {
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--bg-raised);
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color .15s ease-out, color .15s ease-out;
}
.anuncios__seta svg { width: 18px; height: 18px; }
@media (hover: hover) {
  .anuncios__seta:hover { border-color: var(--brand-700); color: var(--brand-700); }
}

/* Um por vez no celular, três no desktop, avançando sozinho.
   O anunciante paga pela peça inteira, então ela aparece inteira: `contain`
   sobre superfície neutra, nunca `cover`, que corta o telefone e o nome de
   quem anunciou. */
.anuncios__trilho {
  --colunas: 1;
  --vao: 10px;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - (var(--colunas) - 1) * var(--vao)) / var(--colunas));
  gap: var(--vao);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--space-4);
  margin-inline: calc(var(--space-4) * -1);
  padding: 2px var(--space-4);
  scrollbar-width: none;
}
.anuncios__trilho::-webkit-scrollbar { display: none; }

.anuncios__slide {
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  overflow: hidden;
  transition: border-color .2s ease-out, box-shadow .2s ease-out;
}
.anuncios__slide img {
  /* Sem respiro interno — a peça vai até a borda do cartão, só o
     `border-radius` do slide arredonda o canto (apontamento do Gustavo,
     "espaço inútil, diminuir bordas", msg 346618). Com a proporção já
     corrigida acima, a peça preenche a largura inteira sem sobrar padding
     em volta. */
  width: 100%;
  /* As peças reais rodam entre 2:1 e 2.36:1 (checado direto nos arquivos no
     CDN do Bubble) — nunca perto de 3:2. Com 3:2 sobrava borda em cima/embaixo
     de toda peça (apontamento do Gustavo, msg 346618/346628). 2.3:1 fica perto
     da média e ainda cabe a mais estreita sem cortar. */
  aspect-ratio: 2.3 / 1;
  object-fit: contain;
  transition: transform .25s ease-out;
}
/* Só o slide que leva a algum lugar reage ao ponteiro. Os institucionais e o
   aviso de pagamento continuam inertes de propósito. */
@media (hover: hover) {
  .anuncios__slide--clicavel:hover { border-color: var(--brand-700); box-shadow: var(--shadow-card); }
  .anuncios__slide--clicavel:hover img { transform: scale(1.02); }
}

.anuncios__pontos { display: flex; justify-content: center; gap: 0; margin-top: 10px; }
/* O `gap` foi a zero e o respiro voltou pelo `padding-inline` dos próprios
   pontos, para o espaçamento VISUAL continuar o mesmo de antes (6px): crescer o
   alvo não pode redesenhar o que o cliente aprovou. */

/* O ponto continua com 7px de desenho, mas o ALVO passa a ter 44px — o mesmo
   `--touch-min` que este projeto declara e que era desrespeitado justamente
   aqui, no menor alvo do app inteiro (7x7, com 6px de folga). Trocar de banner
   exigia acertar isso com o polegar; errar não fazia nada, ou tocava no slide e
   reabria o anunciante que já estava na tela. O carrossel de anunciante é
   receita declarada pelo cliente (msgs 190384/190403), então o alvo pequeno
   custava impressão dos slides 2 a 5 a quem paga o banner.
   `background-clip: content-box` mantém a bolinha do tamanho de antes: o padding
   cresce a área tocável sem pintar nada. E o `gap` foi a zero porque o padding
   já dá a folga — mantê-lo empilharia 56px entre pontos. */
/* O BOTÃO é só o alvo: 13×44, invisível. Quem desenha a bolinha é o `::before`.
   A primeira tentativa usou `background-clip: content-box` para pintar só os
   7×7 do miolo — mas `border-radius` é calculado sobre a caixa inteira, então a
   curva de 50% de uma caixa 13×44 recortada no miolo virava uma PASTILHA
   VERTICAL. Foi o "trem feio" que o Gustavo apontou em 02/09, com print. Alvo e
   desenho são coisas separadas, e agora estão em elementos separados. */
.anuncios__ponto {
  width: 13px; height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
/* 7px redondos, o desenho que o cliente aprovou. Os 3px de folga de cada lado
   saem da largura do alvo, então o respiro visual entre pontos continua 6px e o
   `gap` da fileira segue zero. */
.anuncios__ponto::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--line);
  transition: background-color .2s ease-out, width .2s ease-out;
}
.anuncios__ponto[aria-selected="true"]::before {
  width: 20px;
  border-radius: var(--radius-pill);
  background: var(--brand-700);
}

/* ── Seções e listas ──────────────────────────────────────────────────────── */

.secao { padding-block: var(--space-6); }
.secao--pagina { padding-top: var(--space-4); }

.secao__topo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: 2px;
}

.secao__titulo { margin: 0; font: var(--text-h2); color: var(--ink); }
.secao__apoio { margin: 0 0 var(--space-4); font: var(--text-small); color: var(--ink-soft); }

/* Cabeçalho de lista com ação (o "Publicar vaga" ao lado de "Trabalhadores").
   No celular os botões descem para baixo do apoio e dividem a largura — ao lado
   do título eles espremeriam a linha em 390px. A partir de 700px sobem para a
   direita do título, que é onde o cliente pediu. */
.secao__topo:has(.secao__acoes) { align-items: flex-start; flex-wrap: wrap; }
.secao__titulos { flex: 1 1 100%; min-width: 0; }
.secao__titulos .apoio { margin-bottom: var(--space-3); }

.secao__acoes {
  display: flex;
  flex: 1 1 100%;
  gap: var(--space-2);
}
.secao__acoes .btn { flex: 1 1 0; }

.trilho {
  /* `position: relative` não é enfeite — é o que faz o recorte do carrossel
     valer. Dentro de cada cartão há um `<span class="sr">` (rótulo só para
     leitor de tela), e `.sr` é `position: absolute`. Um bloco absoluto só é
     recortado pelo scroll container quando esse container é o containing block
     dele; com o trilho `static`, os 40 `.sr` atravessavam o recorte e iam parar
     na área rolável da RAIZ, na posição estática deles — o último em x=2352
     numa tela de 390px.
     Efeito medido em produção: `documentElement.scrollWidth = 2352` com
     `clientWidth = 390`. Numa home feita de carrosséis, o dedo erra o trilho por
     alguns pixels na vertical e arrasta a PÁGINA; em `scrollX = 400` a tela fica
     inteiramente em branco — sem cabeçalho, sem conteúdo e sem a barra de baixo.
     A pessoa fica sem nenhum controle visível.
     Isto fecha o que `overflow: hidden` no próprio trilho não fechava (o recorte
     de um scroll container não alcança descendente absoluto de outro containing
     block) e o que `display: block` só parecia fechar por acidente, matando o
     carrossel. */
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(228px, 72cqi);
  gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--space-4);
  margin-inline: calc(var(--space-4) * -1);
  padding: 4px var(--space-4);
  scrollbar-width: thin;
}
.trilho > * { scroll-snap-align: start; }

.grade {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
  gap: 10px;
}

.mais { display: flex; justify-content: center; margin-top: var(--space-6); }

/* O convite que fecha a lista para quem não entrou. Sólido em vez de tracejado
   como o `.vazio`: aqui não falta conteúdo, tem conteúdo esperando — a forma
   precisa dizer "continua" e não "acabou". */
.muro {
  margin-top: var(--space-6);
  padding: var(--space-6) var(--space-4);
  border: 1px solid var(--brand-700);
  border-radius: var(--radius-card);
  background: var(--brand-100);
  text-align: center;
}
.muro__titulo { margin: 0 0 4px; font: var(--text-h3); color: var(--brand-700); }
.muro__texto {
  margin: 0 auto var(--space-4);
  max-width: 44ch;
  font: var(--text-small);
  color: var(--ink-soft);
}
.muro__acoes { display: flex; flex-direction: column; gap: var(--space-2); }
.muro__acoes .btn { width: 100%; }

.vazio {
  padding: var(--space-8) var(--space-4);
  border: 1px dashed var(--line);
  border-radius: var(--radius-card);
  text-align: center;
}
.vazio__titulo { margin: 0 0 4px; font: var(--text-h3); color: var(--ink); }
.vazio__dica { margin: 0; font: var(--text-small); color: var(--ink-soft); }

.nota-rodape { margin: var(--space-6) 0 0; font: var(--text-small); color: var(--ink-faint); text-align: center; }

/* ── Cartões ──────────────────────────────────────────────────────────────── */

.cartao {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  overflow: hidden;
  transition: border-color .18s ease-out, box-shadow .18s ease-out;
}
@media (hover: hover) { .cartao:hover { box-shadow: var(--shadow-card-hover); } }

.cartao__alvo {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  color: inherit;
  text-decoration: none;
}

.cartao__foto {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--brand-100);
  overflow: hidden;
}
.cartao__foto img { width: 100%; height: 100%; object-fit: cover; }

/* Placeholder de marca, nunca o avatar cinza genérico de hoje (DESIGN.md §9).
   Aparece SÓ quando não há foto: quem subiu foto vê a foto, sempre.

   O avatar com brasão é desenhado a partir da base do quadro, como um retrato:
   cabeça e ombros entrando pelo rodapé, preenchendo a largura toda. */
.cartao__foto--vazia { display: grid; place-items: stretch; color: var(--brand-600); overflow: hidden; }
.cartao__foto--vazia svg { width: 100%; height: 100%; opacity: .95; }

/* Os demais placeholders (empresa, produto) são ícones de linha, e ícone de
   linha esticado vira borrão: continuam centrados e pequenos. */
.cartao__foto--vazia svg:not([preserveAspectRatio]) {
  place-self: center;
  width: 42px; height: 42px;
  stroke-width: 1.4;
  opacity: .6;
}

.cartao__corpo {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 12px 14px 10px;
  flex: 1 1 auto;
}

.cartao__cabeca { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }

.cartao__nome { margin: 0; font: var(--text-h3); color: var(--ink); overflow-wrap: anywhere; }

.cartao__nota {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  flex: 0 0 auto;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--brand-100);
  color: var(--brand-700);
  font-size: 12px;
  font-weight: 700;
}
.cartao__nota svg { width: 12px; height: 12px; }
.cartao__nota small { font-size: 11px; font-weight: 600; opacity: .75; }

.cartao__linha, .cartao__local {
  margin: 0;
  font: var(--text-small);
  line-height: 1.45;
  color: var(--ink-soft);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.cartao__linha b {
  display: block;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.cartao__local {
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--ink-faint);
  -webkit-line-clamp: 1;
}
.cartao__local svg { width: 14px; height: 14px; flex: 0 0 auto; }

.cartao__selos { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 6px; }
.cartao__selos:empty { display: none; }

/* Selos do anúncio sobre a foto, no canto de cima — msg 380991. O container
   segura a foto e as etiquetas na mesma caixa posicionada; sem ele o absolute
   escaparia para o cartão inteiro. */
.cartao__midia { position: relative; }

.cartao__selos--sobre {
  position: absolute;
  inset: 8px 8px auto 8px;
  margin-top: 0;
  padding-top: 0;
  /* Etiqueta de vitrine não intercepta o toque: quem toca quer abrir o anúncio. */
  pointer-events: none;
}
/* Em cima de foto, a pílula precisa de corpo próprio para não sumir num fundo
   claro nem virar mancha num escuro. */
.cartao__selos--sobre .pilula { box-shadow: 0 1px 4px rgb(0 0 0 / .18); }

/* "Novo" em verde, "pra dar uma vida" (msg 380991). Semi-novo e usado seguem
   neutros de propósito: se tudo tem cor, a cor não informa nada. */
.pilula--novo { background: var(--brand-700); color: #fff; }

.cartao__acoes { display: flex; gap: 8px; padding: 0 14px 14px; }
.cartao__acoes .btn { flex: 1 1 auto; }

/* O cartão de "Meus anúncios" ganhou "Editar" (msg 458034) e passou a ter três
   ações. Em 390px os três lado a lado quebravam "Ver anúncio" no meio — um
   botão de duas linhas ao lado de dois de uma. Empilhar os três resolvia e
   deixava o cartão alto demais.

   Então vale a hierarquia que já existe: ver o anúncio é o que a pessoa mais
   faz e fica com a linha inteira; editar e encerrar dividem a de baixo.

   ⚠️ A classe é `--tres` e não `.cartao--produto` porque `cartao--produto` é
   de TRÊS cartões: os dois públicos (componentes.js) e este. Presa ao cartão,
   a regra empurrou o botão de compartilhar do comércio para a linha de baixo,
   sozinho — o Gustavo mandou o print no mesmo minuto (msg 458827): "Os os
   compartilhar foi pra baixo, corriga e coloque como estava antes , ao lado".
   Ele estava certo: ali só existem "Ver anúncio" e o compartilhar, e nada
   justificava quebrar linha. O compartilhar nem é `.btn`, então nem entrava na
   conta do `:not(:first-child)` — só herdava o wrap e caía. */
.cartao__acoes--tres { flex-wrap: wrap; }
.cartao__acoes--tres > .btn:first-child { flex: 1 0 100%; }
.cartao__acoes--tres > .btn:not(:first-child) { flex: 1 1 7rem; }

.cartao__compartilhar {
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-button);
  background: var(--bg-raised);
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color .15s ease-out, color .15s ease-out;
}
.cartao__compartilhar svg { width: 17px; height: 17px; }
@media (hover: hover) {
  .cartao__compartilhar:hover { border-color: var(--brand-700); color: var(--brand-700); }
}

.cartao--vaga .cartao__corpo { padding-top: 14px; }

.cartao__preco { margin: 2px 0 0; font-size: 17px; font-weight: 700; color: var(--ink); }
.cartao__preco small { font-size: 13px; font-weight: 500; color: var(--ink-faint); }
.cartao__preco s { font-size: 13px; font-weight: 500; color: var(--ink-faint); margin-right: 4px; }

/* ── Categorias do comércio ───────────────────────────────────────────────── */

.categorias { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }

/* "um texto pequeno embaixo do grupo das categorias" — msg 409784 do Luiz. É um
   botão, mas com peso de link: ele não disputa com a grade, e quem procura
   roupa ou ração encontra o caminho sem que ele ocupe a primeira tela. */
.categorias__mais {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 10px;
  padding: 4px 0;
  border: 0;
  background: none;
  font: var(--text-small);
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
}
.categorias__mais svg { width: 14px; height: 14px; transition: transform .15s ease-out; }
.categorias__mais.is-aberto svg { transform: rotate(90deg); }
.categorias__mais + .categorias { margin-top: 8px; }
@media (hover: hover) {
  .categorias__mais:hover { color: var(--brand-700); }
}

.categoria {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 88px;
  padding: 12px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  cursor: pointer;
  transition: border-color .15s ease-out, background-color .15s ease-out;
}
.categoria__icone {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--brand-100);
  font-size: 19px;
}
.categoria__nome { font-size: 12.5px; font-weight: 600; color: var(--ink); text-align: center; line-height: 1.25; }
.categoria.is-ativo { border-color: var(--brand-700); background: var(--brand-100); }
.categoria--limpar { min-height: 88px; color: var(--ink-soft); font-size: 13px; font-weight: 600; }
@media (hover: hover) { .categoria:hover { border-color: var(--brand-700); } }

/* ── Campanha ─────────────────────────────────────────────────────────────── */

.campanha {
  position: relative;
  margin-block: var(--space-8);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: #1B2418;
  isolation: isolate;
}

.campanha__foto { position: absolute; inset: 0; }
.campanha__foto img { width: 100%; height: 100%; object-fit: cover; object-position: 70% 50%; }
.campanha__foto::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgb(18 26 18 / .88) 0%, rgb(18 26 18 / .68) 46%, rgb(18 26 18 / .12) 100%);
}

.campanha__texto {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  max-width: 30ch;
  padding: var(--space-8) var(--space-6);
}

.campanha__olho {
  margin: 0;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgb(255 255 255 / .72);
}

.campanha__titulo {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(28px, 6cqi, 46px);
  line-height: 1.05;
  color: #fff;
}
.campanha__titulo span { display: block; font-weight: 500; color: var(--brand-500); }

.campanha__frase { margin: 0 0 6px; font-size: 15px; color: rgb(255 255 255 / .84); }

/* ── Sobre ────────────────────────────────────────────────────────────────── */

/* Faixa que sangra a largura toda; o conteúdo respeita a coluna de leitura. */
.sobre {
  margin-top: var(--space-8);
  padding-block: var(--space-12);
  background: var(--bg-raised);
  border-block: 1px solid var(--line);
  max-width: none;
}
.sobre__interno {
  display: grid;
  gap: var(--space-6);
  width: 100%;
  max-width: var(--content-max-marketing);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.sobre__frase {
  margin: var(--space-6) 0;
  padding-left: var(--space-4);
  border-left: 3px solid var(--brand-700);
  max-width: 22ch;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(20px, 3.2cqi, 28px);
  line-height: 1.25;
  color: var(--ink);
}
.sobre__frase span { color: var(--brand-700); }

.sobre__contato { margin: 0 0 var(--space-3); font-size: 15px; color: var(--ink-soft); }

.sobre__titulo { margin: 0 0 var(--space-3); font: var(--text-h2); color: var(--ink); }

.sobre__texto {
  margin: 0 0 var(--space-4);
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.62;
  color: var(--ink-soft);
  text-wrap: pretty;
}
.sobre__texto strong { color: var(--ink); }

.sobre__acoes { display: flex; flex-wrap: wrap; gap: 10px; }

.sobre__equipe { margin: 0; }
.sobre__equipe img {
  width: 100%;
  border-radius: var(--radius-card);
  aspect-ratio: 21 / 9;
  object-fit: cover;
  object-position: 50% 30%;
}
.sobre__equipe figcaption {
  margin-top: 10px;
  font: var(--text-small);
  color: var(--ink-faint);
}

/* ── Rodapé ───────────────────────────────────────────────────────────────── */

.rodape {
  margin-top: var(--space-8);
  /* Folga extra embaixo: a navegação fixa fica por cima do fim da página. */
  padding-block: var(--space-12) calc(var(--space-6) + 76px);
  background: #1E241C;
  color: #C9CEC4;
}

.rodape__interno,
.rodape__base {
  width: 100%;
  max-width: var(--content-max-marketing);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.rodape__interno { display: grid; gap: var(--space-8); }

.rodape__marca img { width: 148px; height: auto; margin-bottom: var(--space-4); background: var(--bg-raised); padding: 8px 12px; border-radius: var(--radius-button); }
.rodape__marca p { margin: 0 0 var(--space-4); max-width: 44ch; font-size: 14px; line-height: 1.6; color: #A7AD9F; }
.rodape__redes { display: flex; flex-wrap: wrap; gap: 8px; }
.rodape__redes .btn--discreto { background: transparent; border-color: #3D443A; color: #D6DBD1; }

.rodape__colunas { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }

.rodape__titulo {
  margin: 0 0 10px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #8C9186;
}
.rodape__coluna ul { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.rodape__coluna a { color: #D6DBD1; font-size: 14.5px; text-decoration: none; }
@media (hover: hover) { .rodape__coluna a:hover { color: #fff; text-decoration: underline; text-underline-offset: 3px; } }

.rodape__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid #333A30;
  font-size: 13px;
  color: #8C9186;
}
.rodape__base p { margin: 0; }
.rodape__aviso { color: #7E8478; }

/* Documentos legais: alcançáveis de qualquer tela, como as lojas exigem, mas
   sem competir com a navegação — é informação de rodapé, não destino. */
.rodape__legal { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.rodape__legal a { color: #A7AD9F; text-decoration: underline; text-underline-offset: 3px; }
.rodape__legal a:hover { color: var(--text-on-dark, #fff); }

/* ── Perfil ───────────────────────────────────────────────────────────────── */

.perfil-capa {
  --cor: var(--brand-600);
  --cor-bg: var(--brand-100);
  display: grid;
  gap: var(--space-4);
  padding-block: var(--space-4) var(--space-6);
}
.perfil-capa[data-perfil="produtor"], .perfil-capa[data-perfil="colono"] { --cor: var(--track-produtor); --cor-bg: var(--track-produtor-bg); }
.perfil-capa[data-perfil="trabalhador"] { --cor: var(--track-trabalhador); --cor-bg: var(--track-trabalhador-bg); }
.perfil-capa[data-perfil="empresa"] { --cor: var(--track-empresa); --cor-bg: var(--track-empresa-bg); }

.perfil-capa__foto .cartao__foto {
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-card);
  background: var(--cor-bg);
}
.perfil-capa__foto .cartao__foto--vazia { color: var(--cor); }
.perfil-capa__foto .cartao__foto--vazia svg:not([preserveAspectRatio]) { width: 64px; height: 64px; }

.perfil-capa__texto { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.perfil-capa__texto .pilula--trilha { background: var(--cor-bg); color: var(--cor); }
.perfil-capa__texto .pilula svg { width: 14px; height: 14px; }

.perfil-capa__nome {
  margin: 0;
  font: var(--text-h2);
  font-size: clamp(22px, 4cqi, 30px);
  color: var(--ink);
  overflow-wrap: anywhere;
}
.perfil-capa__selos { display: flex; flex-wrap: wrap; gap: 8px; }
.perfil-capa__selos .pilula svg { width: 12px; height: 12px; }

.bloco { padding-block: var(--space-6); border-top: 1px solid var(--line-soft); }
.bloco__titulo { margin: 0 0 var(--space-3); font: var(--text-h3); font-size: 17px; color: var(--ink); }

/* É o motivo de quem publicou abrir a própria vaga — ganha borda e fundo
   próprios, para não se confundir com uma seção qualquer da ficha (pedido do
   Gustavo, msg 346633, 24/08). */
.bloco--interessados {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--brand-700);
  border-radius: var(--radius-card);
  background: var(--brand-100);
}
.bloco--interessados .bloco__titulo { color: var(--brand-700); }
.bloco__texto { margin: 0 0 var(--space-4); max-width: 62ch; font-size: 15px; line-height: 1.6; color: var(--ink-soft); text-wrap: pretty; }
.bloco .trilho { margin-inline: 0; padding-inline: 0; }

.etiquetas { display: flex; flex-wrap: wrap; gap: 7px; }

.contato-bloqueado {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: var(--space-4);
  padding: 14px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-input);
  background: var(--bg);
}
.contato-bloqueado__icone { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: var(--line-soft); color: var(--ink-soft); }
.contato-bloqueado__icone svg { width: 17px; height: 17px; }
.contato-bloqueado__texto { font-size: 14px; font-weight: 600; color: var(--ink-soft); }

/* Contato liberado: o número é o conteúdo, não um detalhe. */
.contato-aberto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: var(--space-4);
  padding: 14px 16px;
  border: 1px solid var(--brand-700);
  border-radius: var(--radius-input);
  background: var(--brand-100);
}

/* A prévia mascarada tem a mesma forma da caixa liberada, em cinza e tracejada:
   a semelhança é o argumento — "é este quadro que você destrava". Os dígitos
   chegam já cortados do banco (migration 12), então não há nada a esconder aqui
   com CSS, e por isso ela pode ser texto normal, selecionável e legível por
   leitor de tela. */
.contato-previa {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--space-3);
  margin-bottom: var(--space-3);
  padding: 14px 16px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-input);
  background: var(--line-soft);
}
.contato-previa__rotulo {
  flex: 1 1 100%;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.contato-previa__numero {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--ink-soft);
}
.contato-previa__zap { font-size: 13px; color: var(--ink-faint); }
.contato-aberto__rotulo {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--brand-700);
}
.contato-aberto__numero {
  font-size: 21px;
  font-weight: 700;
  color: var(--brand-700);
  text-decoration: none;
  letter-spacing: .01em;
}
@media (hover: hover) { .contato-aberto__numero:hover { text-decoration: underline; text-underline-offset: 4px; } }

.bloco--contato .rodape-link { margin-top: 10px; }

.dica-tecnica {
  display: block;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--line-soft);
  font-family: ui-monospace, monospace;
  font-size: 12.5px;
  color: var(--ink-soft);
  overflow-x: auto;
}

/* ── Conta ────────────────────────────────────────────────────────────────── */

.conta-cartao {
  --cor: var(--brand-600);
  --cor-bg: var(--brand-100);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: var(--space-8);
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}
.conta-cartao[data-perfil="produtor"], .conta-cartao[data-perfil="colono"] { --cor: var(--track-produtor); --cor-bg: var(--track-produtor-bg); }
.conta-cartao[data-perfil="trabalhador"] { --cor: var(--track-trabalhador); --cor-bg: var(--track-trabalhador-bg); }
.conta-cartao[data-perfil="empresa"] { --cor: var(--track-empresa); --cor-bg: var(--track-empresa-bg); }

.conta-cartao__topo { display: grid; grid-template-columns: 52px 1fr; align-items: center; gap: 12px; }
.conta-cartao__avatar {
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--cor-bg);
  color: var(--cor);
}
.conta-cartao__avatar svg { width: 26px; height: 26px; }

/* O avatar virou o botão de trocar a foto (msgs 410237/410497). */
.conta-cartao__foto {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: none;
  cursor: pointer;
}
.conta-cartao__avatar--troca { overflow: hidden; }
.conta-cartao__avatar--troca img { width: 100%; height: 100%; object-fit: cover; }

/* O rótulo era uma faixa escura DENTRO do círculo e cobria a foto — o Luiz
   reclamou assim que trocou a dele (msg 412544): "retire o nome dali e coloque
   em baixo bem discreto sem dar ênfase". Então: fora da imagem, cinza claro,
   9px, sem caixa alta e sem fundo. Some da vista de quem não está procurando,
   e continua ali para quem está. */
.conta-cartao__trocar {
  font-size: 11px;
  line-height: 1;
  color: var(--ink-faint);
  /* "Trocar foto" é mais largo que o círculo de 52px e quebrava em duas linhas,
     o que chama mais atenção do que o rótulo inteiro deveria. Em uma linha só,
     centralizado, ele passa despercebido — que é o pedido. */
  white-space: nowrap;
}
.conta-cartao__foto.is-carregando { opacity: 0.5; pointer-events: none; }
.conta-cartao__texto { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* `min-width: 0` no pai impede o flex de esticar, mas não faz o texto quebrar:
   um nome sem espaço nenhum (razão social grudada, que existe no cadastro
   herdado) transbordava o bloco de 245px e era pintado por cima do que estava
   ao lado — medido em 390px, 490px de `scrollWidth` num bloco de 245.
   `anywhere` quebra dentro da palavra só quando não há outro ponto possível. */
.conta-cartao__texto strong { font: var(--text-h3); font-size: 17px; color: var(--ink); overflow-wrap: anywhere; }
.conta-cartao__texto span { font: var(--text-small); color: var(--ink-faint); overflow-wrap: anywhere; }

.conta-cartao__plano {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line-soft);
}

/* Faixa de indicação dentro do cartão da conta. Nasceu de um pedido de socorro
   real: o próprio dono do produto perguntou "como acesso a parte do
   influenciador" (msg 401315) com o atalho escondido na seção Publicar. Se ele
   não achou, o produtor também não acha. */
.conta-cartao__indicar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--brand-700);
  border-radius: var(--radius-card);
  color: var(--ink);
  text-decoration: none;
}
.conta-cartao__indicar-texto { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.conta-cartao__indicar-texto strong { font-size: 14.5px; color: var(--brand-700); }
.conta-cartao__indicar-texto span { font: var(--text-small); color: var(--ink-faint); }
.conta-cartao__indicar svg { flex: 0 0 auto; width: 18px; height: 18px; color: var(--brand-700); }
.conta-cartao__plano .pilula svg { width: 12px; height: 12px; }

/* ── Editar perfil ────────────────────────────────────────────────────────────
   Pedido do Luiz, msg 457337: não havia onde editar o perfil depois do
   cadastro. O link mora dentro do cartão da conta, logo abaixo do nome, que é
   onde a pessoa vai procurar os próprios dados. */
.conta-cartao__editar {
  align-self: flex-start;
  margin-top: 2px;
  font: var(--text-small);
  font-weight: 600;
  color: var(--brand-700);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.perfil-editar__foto { display: flex; justify-content: center; }

.campo__dica {
  margin: 0 0 var(--space-2);
  font: var(--text-small);
  color: var(--ink-faint);
}

/* Os chips do cadastro rolam na horizontal (`.chips`), o que serve para um
   filtro mas não para escolher: quem edita a própria cultura precisa ver todas
   as opções de uma vez, não descobrir por acaso que existe mais coisa à
   direita. Aqui eles quebram linha. */
.chips-edicao {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}
.chips-edicao .chip { white-space: normal; text-align: left; padding-block: 8px; }

.topo__avatar {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  margin-right: 2px;
  border-radius: 50%;
  background: var(--brand-700);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}

.plano.is-meu { border-color: var(--brand-700); box-shadow: inset 0 0 0 1px var(--brand-700); }
.plano__fita--meu { background: var(--brand-600); }

.ficha { display: grid; gap: 0; margin: 0; }
.ficha > div { display: grid; grid-template-columns: 40% 1fr; gap: var(--space-3); padding: 11px 0; border-top: 1px solid var(--line-soft); }
.ficha > div:first-child { border-top: 0; }
.ficha dt { margin: 0; font-size: 14px; color: var(--ink-faint); }
.ficha dd { margin: 0; font-size: 14px; font-weight: 600; color: var(--ink); }

.mini-perfil {
  display: grid;
  grid-template-columns: 54px 1fr 20px;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  text-decoration: none;
  transition: border-color .15s ease-out;
}
@media (hover: hover) { .mini-perfil:hover { border-color: var(--brand-700); } }
.mini-perfil__foto { width: 54px; height: 54px; aspect-ratio: 1; border-radius: var(--radius-input); }
/* Só os ícones de linha encolhem. A silhueta traz `preserveAspectRatio` porque
   é um retrato desenhado a partir da base do quadro: forçada a 26px quadrados
   ela era cortada nas laterais e virava um borrão — "o ícone tá ruim", no print
   que o Luan mandou no grupo em 17/08. Mesma distinção que os cartões já fazem. */
.mini-perfil__foto.cartao__foto--vazia svg:not([preserveAspectRatio]) { width: 26px; height: 26px; }
.mini-perfil__texto { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mini-perfil__texto strong { font: var(--text-h3); color: var(--ink); }
.mini-perfil__texto > span { font: var(--text-small); color: var(--ink-faint); }
.mini-perfil__seta { color: var(--ink-faint); }
.mini-perfil__seta svg { width: 20px; height: 20px; }

/* ── Avaliações ───────────────────────────────────────────────────────────── */

.avaliacoes { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; }

.avaliacao { padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--bg-raised); }
.avaliacao__topo { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: 8px; }
/* Estrela dourada sobre bloco neutro. Antes o conjunto era verde sobre verde e
   a nota se perdia — "tá muito verde, muito verde", na call. */
.estrelas { display: inline-flex; gap: 2px; color: var(--line); }
.estrelas span { display: grid; }
.estrelas svg { width: 15px; height: 15px; }
.estrelas .is-cheia { color: var(--warning); }

/* Resumo legível de relance: o número grande decide, as estrelas confirmam. */
.reputacao {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}
.reputacao__nota { margin: 0; font-size: 38px; font-weight: 700; line-height: 1; letter-spacing: -.02em; }
.reputacao__titulo { margin: 0 0 4px; font-size: 15px; font-weight: 700; }
.reputacao__apoio { margin: 4px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); }

/* Dado que o Bubble não trouxe. Tratado como lacuna do cadastro, não como
   defeito da pessoa — quem lê ainda pode perguntar. */
.sem-dado {
  padding: var(--space-4);
  border: 1px dashed var(--line);
  border-radius: var(--radius-card);
  background: var(--bg);
}
.sem-dado__titulo { margin: 0 0 4px; font-size: 14.5px; font-weight: 600; color: var(--ink-soft); }
.sem-dado__apoio { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-faint); }

/* Cadastro novo não é cadastro ruim: fundo neutro, sem vermelho, sem zero. */
.reputacao--nova { align-items: flex-start; background: var(--bg); border-style: dashed; }
.reputacao__marca { font-size: 26px; line-height: 1; color: var(--brand-600); }
.avaliacao__data { font: var(--text-small); color: var(--ink-faint); }
.avaliacao__texto { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--ink); }
.avaliacao__resposta { margin: 10px 0 0; padding-top: 10px; border-top: 1px solid var(--line-soft); font: var(--text-small); color: var(--ink-soft); }
.avaliacao__resposta b { display: block; color: var(--ink); }

/* ── Detalhe ──────────────────────────────────────────────────────────────── */

.detalhe { padding-block: var(--space-4) var(--space-8); }

.detalhe__selos { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 10px; }

.detalhe__titulo {
  margin: 0 0 8px;
  font: var(--text-h2);
  font-size: clamp(22px, 4cqi, 30px);
  color: var(--ink);
  text-wrap: balance;
}

.detalhe__preco { margin: 10px 0 6px; font-size: 26px; font-weight: 700; color: var(--ink); }
.detalhe__preco small { font-size: 16px; font-weight: 500; color: var(--ink-faint); }
.detalhe__preco s { font-size: 17px; font-weight: 500; color: var(--ink-faint); margin-right: 8px; }

.detalhe__meta { margin: 4px 0 0; font: var(--text-small); color: var(--ink-faint); }

.galeria {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 84%;
  gap: 8px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  margin: 0 calc(var(--space-4) * -1) var(--space-4);
  padding-inline: var(--space-4);
  scrollbar-width: none;
}
.galeria::-webkit-scrollbar { display: none; }
.galeria__item { scroll-snap-align: center; }
.galeria .cartao__foto { aspect-ratio: 4 / 3; border-radius: var(--radius-card); }

.barra-acao { margin-top: var(--space-8); }
/* Os dois caminhos da vaga, um debaixo do outro: falar agora (WhatsApp) e se
   candidatar. Espaço entre eles para ninguém tocar no errado com o polegar. */
.barra-acao__zap { margin-bottom: 10px; }
.barra-acao__nota { margin: 10px 0 0; font: var(--text-small); color: var(--ink-faint); text-align: center; }

/* ── Planos ───────────────────────────────────────────────────────────────── */

.planos { display: grid; gap: 12px; }

.plano {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}
.plano.is-recomendado { border-color: var(--brand-700); box-shadow: inset 0 0 0 1px var(--brand-700); }

.plano__fita {
  position: absolute;
  top: -11px; left: var(--space-6);
  padding: 3px 12px;
  border-radius: var(--radius-pill);
  background: var(--brand-700);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
}

.plano__nome { margin: 0; font: var(--text-h3); font-size: 18px; color: var(--ink); }
.plano__valor { margin: 0; font-size: 30px; font-weight: 700; color: var(--ink); }
.plano__valor small { font-size: 15px; font-weight: 500; color: var(--ink-faint); }

.plano__lista { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.plano__lista li { display: grid; grid-template-columns: 20px 1fr; gap: 10px; align-items: center; font-size: 14.5px; color: var(--ink); }
.plano__lista svg { width: 18px; height: 18px; stroke-width: 2.2; }
.plano__lista .is-tem svg { color: var(--brand-600); }
.plano__lista .is-nao { color: var(--ink-faint); }
.plano__lista .is-nao svg { color: var(--line); }

.plano__economia {
  margin: -4px 0 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--brand-600);
}
.plano__atual {
  padding: 11px 0;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink-faint);
  text-align: center;
}

.nota-perfil { margin: 0 0 var(--space-4); font: var(--text-small); color: var(--ink-faint); }

/* O mote de cada perfil, entre a escolha do tipo de conta e o preço — frase do
   Gustavo (msg 460656): "produtor inteligente usa o Plano agroonnet".

   Fica no verde da marca e um degrau acima do texto comum: é a única linha
   desta faixa que argumenta, e as duas vizinhas (a nota de perfil e o nome do
   plano) são informativas. Sem peso próprio ela seria lida como legenda. */
.planos-mote {
  margin: 0 0 var(--space-4);
  font: var(--text-h3);
  color: var(--brand-700);
  text-align: center;
  text-wrap: balance;
}

/* Fatura em aberto — quem começou a pagar e saiu no meio.

   Cor de atenção (`--warning`), não de erro: nada quebrou, falta terminar. A
   faixa lateral é o que a separa dos cartões de plano logo abaixo, que também
   são brancos e arredondados — sem ela as duas coisas se lêem como uma lista
   só, e a fatura vira "mais um plano".

   Empilha no celular porque o botão precisa da largura inteira para caber
   "Continuar o pagamento" sem quebrar no meio da palavra; a partir de 420px
   sobra espaço para o texto e o botão dividirem a linha. */
.cobranca-aberta {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--warning);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  box-shadow: var(--shadow-card);
}
.cobranca-aberta__icone {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--track-trabalhador-bg);
  color: var(--warning);
}
.cobranca-aberta__icone svg { width: 17px; height: 17px; }
.cobranca-aberta__texto { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cobranca-aberta__texto strong { font: var(--text-h3); color: var(--ink); }
.cobranca-aberta__texto span { font: var(--text-small); color: var(--ink-soft); }
.cobranca-aberta__acao { grid-column: 1 / -1; }

@media (min-width: 420px) {
  .cobranca-aberta { grid-template-columns: auto 1fr auto; }
  .cobranca-aberta__acao { grid-column: auto; white-space: nowrap; }
}

/* ── Cotação e clima ────────────────────────────────────────────────────────
   Dois blocos com a mesma casca do resto do app (cartão branco, borda fina,
   sombra de cartão) porque não são um produto à parte: são mais uma coisa que
   a conta mostra. O que os distingue é a densidade — preço e temperatura são
   número para conferir de relance, então ganham peso e `tabular-nums`, que
   alinha os dígitos em coluna. */
.dia-bloco {
  margin-bottom: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  box-shadow: var(--shadow-card);
}
.dia-bloco--carregando { color: var(--ink-faint); font: var(--text-small); text-align: center; }
.dia-bloco--fechado { text-align: center; }
.dia-bloco--fechado .contato-bloqueado__icone { margin: 0 auto var(--space-2); }
.dia-bloco__titulo { margin: 0 0 var(--space-3); font: var(--text-h2); color: var(--ink); }
.dia-bloco__rotulo {
  margin: var(--space-3) 0 var(--space-2);
  font: var(--text-small);
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.dia-bloco__fonte { margin: var(--space-3) 0 0; font: var(--text-small); color: var(--ink-faint); }

.dia-precos { margin: 0; padding: 0; list-style: none; }
.dia-preco {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 10px 0;
  border-bottom: 1px solid var(--line-soft);
}
.dia-preco:last-child { border-bottom: 0; }
.dia-preco__nome { font: var(--text-body); color: var(--ink); min-width: 0; }
.dia-preco__nome small { display: block; font: var(--text-small); color: var(--ink-soft); }
.dia-preco__valor {
  font: var(--text-h3);
  color: var(--ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.dia-preco__valor small { font: var(--text-small); color: var(--ink-faint); }
/* Verde é alta e vermelho é baixa do ponto de vista de quem VENDE — que é o
   produtor, o dono desta tela. Para quem compra a leitura seria a inversa. */
.dia-preco__var { display: block; font: var(--text-small); font-style: normal; }
.dia-preco__var.is-alta { color: var(--success); }
.dia-preco__var.is-baixa { color: var(--error); }

.dia-clima__resumo { margin: 0 0 var(--space-3); font: var(--text-h3); color: var(--brand-700); }
.dia-clima {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.dia-clima li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 4px;
  border-radius: var(--radius-input);
  background: var(--bg);
  text-align: center;
}
.dia-clima span { font: var(--text-small); color: var(--ink-faint); }
/* `nowrap` e um degrau menor: "28,5 mm" quebrava em duas linhas numa coluna de
   ~78px e desalinhava a fileira inteira. */
.dia-clima strong {
  font: 600 15px/1.3 var(--font-ui);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Seletor de perfil — só aparece para quem não está logado */
.abas-planos {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: var(--space-4);
}
.aba-plano {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  color: var(--ink-faint);
  text-align: center;
  cursor: pointer;
}
.aba-plano strong { font-size: 14px; color: var(--ink); }
.aba-plano span { font-size: 11.5px; }
.aba-plano.is-ativa { border-color: var(--brand-700); box-shadow: inset 0 0 0 1px var(--brand-700); }
.aba-plano.is-ativa strong { color: var(--brand-700); }

/* ── Planos: o topo desenhado pelo Gustavo ────────────────────────────────
   Msgs 413705/413707 (o desenho) e 413955 (o recorte circulado de verde, com
   "quero o mais semelhante possível é esta aí"). O bloco vai da etiqueta
   PLANOS até as abas Grátis/Mensal/Anual, que ficam montadas sobre a barriga
   da foto.

   A foto sangra até as bordas: `.secao` tem padding lateral, então a margem
   negativa devolve exatamente esse espaço. 100vw não serve aqui — o app roda
   dentro do palco simulado, e vw mede a janela, não o aparelho. */

/* O padding de baixo é a faixa reservada para a foto — e precisa ser MAIOR que
   a altura dela. Os três ganhos são o último elemento do fluxo, então terminam
   exatamente onde o padding começa: com a foto mais alta que o padding, ela
   sobe por baixo dos rótulos.

   Foi o que aconteceu na primeira versão, e o Luan pegou na captura: texto
   escuro e ícone verde sobre lavoura verde, ilegíveis. No desenho do Gustavo os
   ícones estão sobre a parte clara e a lavoura entra abaixo deles — que é o que
   estas duas medidas garantem, com 14px de folga entre uma coisa e outra. */
.planos-hero {
  position: relative;
  margin-inline: calc(var(--space-4) * -1);
  padding: var(--space-6) var(--space-4) 186px;
  overflow: hidden;
  isolation: isolate;
}

.planos-hero__foto {
  position: absolute;
  inset: auto 0 0 0;
  z-index: -1;
  width: 100%;
  height: 172px;
  object-fit: cover;
  object-position: center 58%;
}

/* Véu na emenda: a foto nasce de dentro do fundo da página em vez de começar
   numa linha reta, e some ao chegar na lavoura, que fica limpa. */
.planos-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom,
    var(--bg) 0, var(--bg) calc(100% - 172px),
    rgba(247, 247, 247, .72) calc(100% - 156px),
    rgba(247, 247, 247, 0) calc(100% - 112px));
}

/* A trinca de ícones fica fora deste bloco (ver a marcação em telas.js) para
   não herdar nada dele e poder ir ao centro da tela. */
.planos-hero__conteudo { margin-bottom: var(--space-6); }

/* O limite de leitura saiu do bloco e passou a valer só para o parágrafo, a
   pedido do Gustavo (462217, com print): *"Pode espaçar mais titulo ali"* — ele
   circulou o título e desenhou um retângulo no vão que sobrava à direita.

   O 34ch é medida de leitura de texto corrido, e o título não é texto corrido:
   preso a ele, "Menos dor de cabeça, mais dinheiro no seu bolso" quebrava em
   **quatro** linhas estreitas com um vão de 36px ao lado. Solto, cabe em três
   e usa a largura inteira — 38px a menos de altura, e a promessa fica mais
   perto do preço. O parágrafo continua em 34ch, que é onde a medida importa. */
.planos-hero__apoio { max-width: 34ch; }


/* Duas cores no título, como no desenho: a primeira parte no preto do texto,
   a segunda no verde da marca. O <em> carrega o corte, não uma ênfase de
   leitura — daí o font-style normal. */
.planos-hero__titulo {
  margin: 0 0 var(--space-3);
  font: var(--text-display);
  font-size: clamp(30px, 8.5vw, 40px);
  line-height: 1.12;
  color: var(--ink);
}
.planos-hero__titulo em { font-style: normal; color: var(--brand-600); }

.planos-hero__apoio {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* As palavras marcantes do parágrafo, a pedido do Gustavo (461653): *"coloca
   em negrito palavras marcantes como promoções,economizar"*. Além do peso, a
   cor sobe de `--ink-soft` para `--ink`: negrito sobre cinza claro quase não
   se destaca do resto, e o que ele quer é que o olho pare nessas palavras
   antes de ler a frase inteira. */
.planos-hero__apoio b {
  font-weight: 700;
  color: var(--ink);
}

/* Os três motivos, lado a lado como no desenho. Em tela estreita continuam os
   três na linha — são duas palavras cada, e empilhar comeria a foto inteira.

   O `max-width` com `margin-inline: auto` é o pedido do Luiz na msg 430128
   ("colocar esses 03 ícones centralizados no meio da tela"): sem ele o grid
   esticava de borda a borda, e a primeira coluna nascia colada na margem
   esquerda — o que fazia "Mais visibilidade", que é o único rótulo que quebra
   em duas linhas, parecer desalinhado dos outros dois. O título e o texto de
   apoio continuam à esquerda, como no desenho do Gustavo; só a trinca vai para
   o centro. */
.planos-hero__ganhos {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
  max-width: 21rem;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}
.planos-hero__ganhos li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--ink);
}
/* O verde escuro da marca, não o médio: estes três ficam na emenda com a foto,
   onde qualquer verde claro perde o contorno. */
.planos-hero__ganhos svg {
  width: 34px; height: 34px;
  stroke-width: 1.5;
  color: var(--brand-700);
}

/* As abas: cartão branco arredondado, meio dentro e meio fora da foto. O
   translate negativo é o que produz a montagem do desenho. */
.planos-ciclos {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin: -34px 0 var(--space-6);
  padding: 7px;
  border-radius: var(--radius-pill);
  background: var(--bg-raised);
  box-shadow: var(--shadow-card);
}
.planos-ciclos__opcao {
  padding: 12px 4px;
  min-height: var(--touch-min);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--line-soft);
  color: var(--ink-faint);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}
.planos-ciclos__opcao.is-ativa { background: var(--brand-600); color: #fff; }

/* Selo de confiança do pé do cartão (o cadeado do desenho). */
.plano-selo {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: var(--space-2) 0 0;
  font-size: 13.5px;
  line-height: 1.35;
  color: var(--ink-faint);
  text-align: center;
}
.plano-selo svg { flex: none; width: 22px; height: 22px; color: var(--brand-600); }

/* ── Planos no desktop ────────────────────────────────────────────────────
   Fica DEPOIS de todas as regras acima de propósito: `.planos-ciclos` declara
   `margin: -34px 0`, e margin cheio vence margin-inline quando vem por último.
   Na primeira tentativa esta media query estava antes, e o resultado foi o
   que o Luan viu na captura — abas e cartão encostados na borda esquerda,
   com meia tela vazia à direita.

   O desenho do Gustavo é de celular, que é onde este app vive. Em tela larga
   o bloco vai para o centro e a foto ganha altura. */
@media (min-width: 720px) {
  .planos-hero { padding-bottom: 260px; text-align: center; }
  .planos-hero__foto { height: 240px; }
  .planos-hero::after {
    background: linear-gradient(to bottom,
      var(--bg) 0, var(--bg) calc(100% - 240px),
      rgba(247, 247, 247, .72) calc(100% - 222px),
      rgba(247, 247, 247, 0) calc(100% - 170px));
  }
  .planos-hero__conteudo { max-width: 46ch; margin-inline: auto; }
  .planos-hero__ganhos { max-width: 420px; margin-inline: auto; }

  /* margin cheio, não margin-inline: o -34px de cima (a montagem sobre a foto)
     e o auto das laterais precisam sair da MESMA declaração para nenhuma das
     duas anular a outra. */
  .planos-ciclos { max-width: 420px; margin: -34px auto var(--space-6); }
  .nota-perfil { text-align: center; }
  .planos { max-width: 420px; margin-inline: auto; }
  .comparar__rolagem,
  .faq { max-width: 640px; margin-inline: auto; }
  .comparar__titulo,
  .faq__titulo { text-align: center; }
}

/* ── Compare o plano ──────────────────────────────────────────────────────
   Quatro colunas em tela de celular é onde tabela quebra. Aqui a coluna do
   recurso segura o texto e as três de plano ficam estreitas e centradas; se
   ainda assim não couber, a tabela rola dentro da própria caixa em vez de
   empurrar a página inteira para o lado. */
.comparar { margin-top: var(--space-8); }
.comparar__titulo { margin: 0 0 var(--space-4); font: var(--text-h2); color: var(--ink); }

/* `min-width: 0` não é decoração: sem ele a largura mínima da tabela vaza para
   fora da caixa e empurra a PÁGINA para o lado — 39px de rolagem lateral no
   celular, medidos antes desta linha existir. O overflow abaixo só segura o
   conteúdo depois que a caixa aceita ser mais estreita que ele. */
.comparar__rolagem {
  min-width: 0;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}

/* `fixed` reparte a largura por porcentagem em vez de deixar o conteúdo
   decidir: é o que faz as quatro colunas caberem em 390px sem rolar. */
.comparar__tabela {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 13.5px;
}
.comparar__tabela th,
.comparar__tabela td { padding: 11px 6px; text-align: center; }
.comparar__tabela thead th {
  position: sticky; top: 0;
  background: var(--line-soft);
  color: var(--ink);
  font-size: 13px;
  font-weight: 700;
}
.comparar__tabela tbody th {
  width: 34%;
  color: var(--ink-soft);
  font-weight: 500;
  text-align: left;
}
/* 22% e não 19%: com a coluna mais estreita, "Ilimitado" partia no meio da
   palavra ("Ilimitad" / "o"). Aqui a palavra inteira cabe. */
.comparar__tabela thead th:not(:first-child),
.comparar__tabela td { width: 22%; }
.comparar__tabela td small {
  display: block;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-faint);
}
/* Um ponto menor só no preço: "R$ 399,00" é o texto mais largo da tabela e era
   o único que ainda encostava na borda da coluna. */
.comparar__preco { font-size: 12.5px; }
.comparar__tabela thead th:first-child,
.comparar__tabela tbody th { text-align: left; }
.comparar__tabela tbody tr + tr th,
.comparar__tabela tbody tr + tr td { border-top: 1px solid var(--line-soft); }
.comparar__tabela td { color: var(--ink); font-weight: 600; }
.comparar__tabela svg { width: 18px; height: 18px; stroke-width: 2.2; color: var(--brand-600); }
.comparar__nao svg { color: var(--line); }
.comparar__vazia { color: var(--ink-faint); }

/* ── Perguntas frequentes ─────────────────────────────────────────────────
   "Pensei em ter um negocio de perguntas frequentes bem embaixo" (msg 413713).
   <details> nativo: abre sem JavaScript e o leitor de tela já sabe ler. */
/* ── Prova social na tela de planos ───────────────────────────────────────────
   Pedido do Gustavo, msg 457376, a partir de um print do modelo. O conteúdo é
   avaliação real de cliente (ver o comentário em `planos()`), então o cartão
   precisa parecer um depoimento e não um anúncio: fundo de cartão, foto
   redonda, o texto entre aspas e a origem dita embaixo. */
.prova { margin-top: var(--space-8); }
.prova__titulo { margin: 0 0 var(--space-4); font: var(--text-h2); color: var(--ink); }

/* Carrossel: um depoimento por vez, os três passando. "coloca os 3 pontos lá em
   cima e deixe eles passando pro lado depois de alguns segundos" (Gustavo, msg
   457487, mandando olhar o print do modelo de novo).

   O `scroll-snap` faz o arrasto com o dedo funcionar sem JavaScript; o avanço
   automático (em app.js) é camada por cima. Se o script falhar, a pessoa ainda
   navega — e é por isso que a rolagem é o mecanismo, não `transform`. */
.prova__pontos {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-bottom: var(--space-3);
}
.prova__ponto {
  width: 10px; height: 10px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--line);
  cursor: pointer;
  transition: background-color .2s ease-out, transform .2s ease-out;
}
.prova__ponto.is-ativo { background: var(--brand-700); transform: scale(1.15); }
/* Alvo de toque de 10px reprova em qualquer diretriz. O `::after` levava a área
   a 26px — melhor, ainda abaixo dos 44px que este projeto declara em
   `--touch-min`. Agora `-17px` na vertical fecha os 44 (10 + 34), e na
   horizontal o inset fica em `-4px`: os pontos ficam a 8px um do outro, então
   esticar mais invadiria o vizinho e o toque viraria loteria entre dois
   depoimentos. Altura é de graça, largura não. */
.prova__ponto::after {
  content: '';
  position: absolute;
  inset: -17px -4px;
}
.prova__ponto { position: relative; }

.prova__trilho {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  /* O cartão tem borda arredondada e sombra: sem esta folga o snap corta a
     borda do vizinho no meio do arrasto. */
  padding-bottom: 2px;
}
.prova__trilho::-webkit-scrollbar { display: none; }
.prova__slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  min-width: 0;
}
@media (prefers-reduced-motion: reduce) {
  .prova__trilho { scroll-behavior: auto; }
}

.prova__cartao {
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}

.prova__perfil { align-self: flex-start; margin-bottom: 2px; }

/* `flex-wrap: nowrap` porque o wrap era a causa do que o Gustavo apontou na
   msg 470199: com um nome de duas linhas o "Ver perfil" quebrava para baixo,
   sozinho, e ele mandou de volta para cima com uma seta no print. O par
   `min-width: 0` (no quem) + `flex: 0 0 auto` (no link) já garante que o nome
   quebre dentro do próprio bloco em vez de empurrar o botão para fora — o wrap
   só existia como rede, e a rede era o problema.

   `align-items: flex-start` no lugar de `center`: quando o nome ainda ocupa
   duas linhas, o botão centralizado flutua no meio do vazio. Alinhado ao topo
   ele fica na altura da etiqueta do perfil, que é de onde ele nunca devia ter
   saído. */
.prova__cabeca {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: nowrap;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--line-soft);
}
/* `min-width: 0` para o nome longo quebrar dentro do bloco em vez de empurrar
   o botão para fora da tela — a mesma armadilha do cartão da conta. */
.prova__quem { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.prova__nome { font-size: 15.5px; color: var(--ink); overflow-wrap: anywhere; }
.prova__link { flex: 0 0 auto; white-space: nowrap; }

/* "coloque a estrela cheia" (Gustavo, msg 457487) — e ele estava literalmente
   certo: a estrela saía **vazada**, só o contorno.

   O ícone traz `fill="currentColor" stroke="none"` no próprio SVG, mas
   `comum.css` tem um `svg { fill: none; stroke: currentcolor }` global para os
   ícones de traço — e **regra CSS vence atributo de apresentação**, por mais
   específico que o atributo pareça. Medido no navegador: `computedFill` vinha
   `none` e o desenho aparecia como contorno.

   Daí o `fill`/`stroke` explícitos aqui. A cor também mudou: `--warning` é
   #B8863A, um dourado que a 15px lê como marrom apagado ao lado do amarelo do
   modelo dele. O token segue valendo no resto do app; a exceção é deste bloco.

   ⚠️ O mesmo `svg` global explica `.interessado__nota svg`, que já repetia
   `fill` na mão — não é redundância de quem escreveu, é a correção do mesmo
   problema em outra tela. */
.prova__estrelas { display: inline-flex; gap: 1px; }
.prova__estrela svg {
  width: 17px; height: 17px;
  color: var(--line);
  fill: currentColor;
  stroke: none;
}
.prova__estrela.is-cheia svg { color: #F5B301; }

.prova__corpo {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding-top: var(--space-4);
}
.prova__foto {
  flex: 0 0 auto;
  width: 64px; height: 64px;
  overflow: hidden;
  border-radius: 50%;
  background: var(--bg);
}
.prova__foto img { width: 100%; height: 100%; object-fit: cover; }
.prova__foto svg { width: 100%; height: 100%; padding: 14px; color: var(--ink-faint); }

.prova__texto {
  margin: 0;
  min-width: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-soft);
  font-style: italic;
  overflow-wrap: anywhere;
}
.prova__texto::before { content: '“'; }
.prova__texto::after { content: '”'; }

.prova__nota { margin: 8px 0 0; font: var(--text-small); color: var(--ink-faint); }

.faq { margin-top: var(--space-8); }
.faq__titulo { margin: 0 0 var(--space-4); font: var(--text-h2); color: var(--ink); }

.faq__item {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}
.faq__item + .faq__item { margin-top: 8px; }

.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 14px var(--space-4);
  min-height: var(--touch-min);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary svg {
  flex: none;
  width: 18px; height: 18px;
  color: var(--ink-faint);
  transform: rotate(90deg);
  transition: transform .18s ease-out;
}
.faq__item[open] summary svg { transform: rotate(-90deg); }
.faq__item p {
  margin: 0;
  padding: 0 var(--space-4) var(--space-4);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .faq__item summary svg { transition: none; }
}

/* ── Propriedades ─────────────────────────────────────────────────────────── */

.pilulas { display: flex; flex-wrap: wrap; gap: 6px; margin: var(--space-3) 0; }

.preco-grande {
  margin: var(--space-4) 0 2px;
  font-size: 26px;
  font-weight: 700;
  color: var(--ink);
}

/* --space-5 não existe: a escala vai de --space-4 (16px) a --space-6 (24px).
   Enquanto o token faltava, o navegador descartava a declaração inteira e o
   grupo da ficha ficava colado no de cima. */
.ficha__grupo { margin-top: var(--space-6); }
.ficha__rotulo {
  margin: 0 0 6px;
  font: var(--text-small);
  font-weight: 700;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: .04em;
}

/* Dois campos na mesma linha quando cabem — área e preço, cidade e estado são
   pares que a pessoa preenche junto. */
.campo-par { display: grid; grid-template-columns: 1fr; gap: var(--space-3); }
@media (min-width: 480px) { .campo-par { grid-template-columns: 1fr 1fr; } }

/* Mesmo caso da .ficha__grupo: o --space-5 apagava a margem dos grupos do
   formulário, e os blocos de campos encostavam uns nos outros. */
.grupo { margin: var(--space-6) 0; padding: 0; border: 0; }

.caixas { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
@media (min-width: 620px) { .caixas { grid-template-columns: repeat(3, 1fr); } }

.caixa {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  font-size: 14px;
  cursor: pointer;
}
.caixa input { width: 17px; height: 17px; accent-color: var(--brand-700); flex: 0 0 auto; }
.caixa:has(input:checked) { border-color: var(--brand-700); }

/* ── Programa de indicação ────────────────────────────────────────────────── */

.convite {
  padding: var(--space-6);
  border: 1px solid var(--brand-700);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  text-align: center;
}
.convite__rotulo { margin: 0; font: var(--text-small); color: var(--ink-faint); }
.convite__codigo {
  margin: 2px 0 var(--space-4);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 2px;
  color: var(--brand-700);
}
.convite__acoes { display: grid; gap: 8px; }
@media (min-width: 520px) { .convite__acoes { grid-template-columns: 1fr 1fr; } }
.convite__nota { margin: var(--space-4) 0 0; font: var(--text-small); color: var(--ink-faint); }

/* `--space-5` não existe na escala (4, 8, 12, 16, 24, 32, 48) e o navegador
   descartava a declaração inteira — a régua de métricas vinha colada no cartão
   do convite. Achado pelo `checar-tokens.mjs` ao mexer nesta tela. */
.metricas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: var(--space-6);
}
@media (min-width: 720px) { .metricas { grid-template-columns: repeat(4, 1fr); } }

.metrica {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}
.metrica strong { font-size: 22px; font-weight: 700; color: var(--ink); }
.metrica span { font: var(--text-small); color: var(--ink-faint); }
.metrica--destaque { border-color: var(--brand-700); }
.metrica--destaque strong { color: var(--brand-700); }

.evolucao { margin-top: var(--space-6); }
/* 30 dias não cabem em 390px: cada coluna tem piso de 28px (o rótulo "12/08"
   inteiro) e o quadro rola de lado por dentro, sem empurrar a página. No
   desktop o 1fr ainda estica e tudo cabe. app.js abre a rolagem no fim, no
   dia mais recente. */
.evolucao__barras {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(28px, 1fr);
  gap: 6px;
  align-items: end;
  height: 150px;
  padding: var(--space-4) var(--space-3) 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  overflow-x: auto;
  overscroll-behavior-x: contain;
}
/* Barra e rótulo em linhas separadas: antes os dois disputavam os mesmos 100%
   da coluna, e a barra mais alta (100%) passava do teto do quadro. Agora o
   percentual da barra vale só sobre a linha de cima. */
.evolucao__col {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  row-gap: 6px;
  height: 100%;
  min-width: 0;
}
.evolucao__barra {
  position: relative;
  display: flex;
  align-self: end;
  align-items: flex-start;
  justify-content: center;
  border-radius: 6px 6px 0 0;
  background: var(--brand-600);
  min-height: 3px;
  height: 2%; /* piso antes do JS aplicar `data-altura` via CSSOM */
}
/* Mês sem receita não some: vira um traço, que é a diferença entre "zero" e
   "não medido". */
.evolucao__barra.is-vazia { background: var(--line); }
.evolucao__n { padding-top: 3px; font-size: 11px; font-weight: 700; color: #fff; }
.evolucao__rotulo { font-size: 11px; color: var(--ink-faint); text-align: center; }
.evolucao__legenda { margin: 8px 0 0; font: var(--text-small); color: var(--ink-faint); }

/* ── A escada da comissão ──────────────────────────────────────────────────
   Onde a pessoa está no ranqueamento e quanto falta para subir. Barra em CSS
   puro, pelo mesmo motivo do gráfico de evolução logo acima: uma barra não
   justifica biblioteca, e largura em porcentagem já é responsiva de graça. */
.escada {
  margin-top: var(--space-4);
  padding: var(--space-3);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
}

.escada__onde { margin: 0; font: var(--text-body); color: var(--text-body-color); }

.escada__trilho {
  margin-top: var(--space-2);
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--line-soft);
  overflow: hidden;
}

.escada__cheio {
  height: 100%;
  width: 4%; /* piso antes do JS aplicar `data-largura` via CSSOM */
  border-radius: var(--radius-pill);
  background: var(--brand-500);
}

.escada__falta { margin: var(--space-2) 0 0; font: var(--text-small); color: var(--ink-soft); }

/* ── Quem entrou pelo convite ──────────────────────────────────────────────
   Lista nominal dos indicados. Nada de largura fixa e `min-width: 0` nos
   filhos do flex: nome de fazenda é comprido, e foi exatamente um filho de
   grade sem `min-width: 0` que estourou o formulário do disparo para 3022px
   numa tela de 390 (apontamento 431305 do Luiz). */
.indicados__titulo { margin-top: var(--space-6); }

.indicados {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.indicado {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-card);
  padding: var(--space-3);
  background: var(--surface-card);
}

.indicado.is-ativo { border-color: var(--brand-500); }

.indicado__quem {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

.indicado__quem > strong { min-width: 0; overflow-wrap: anywhere; }

/* No painel de métricas nome e dados sempre em linhas separadas: com flex-wrap,
   nome curto puxava os dados para a mesma linha e a lista ficava desalinhada. */
.indicados--metricas .indicado__quem { flex-direction: column; align-items: flex-start; gap: 2px; }

.indicado__onde { font: var(--text-small); color: var(--ink-soft); }

.indicado__estado {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  min-width: 0;
}

.indicado__receita { font: var(--text-small); color: var(--ink-soft); }

.indicado__quando { margin: 6px 0 0; font: var(--text-small); color: var(--ink-faint); }

/* ── Menu ─────────────────────────────────────────────────────────────────── */

.menu-entrar { display: grid; gap: 10px; margin-bottom: var(--space-8); }

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

.menu-item {
  display: grid;
  grid-template-columns: 42px 1fr 20px;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  text-decoration: none;
  transition: border-color .15s ease-out;
}
@media (hover: hover) { .menu-item:hover { border-color: var(--brand-700); } }
.menu-item__icone { display: grid; place-items: center; width: 42px; height: 42px; border-radius: var(--radius-input); background: var(--brand-100); color: var(--brand-700); }
.menu-item__icone svg { width: 22px; height: 22px; }
.menu-item__texto { display: flex; flex-direction: column; gap: 2px; }
.menu-item__texto strong { font: var(--text-h3); color: var(--ink); }
.menu-item__texto > span { font: var(--text-small); color: var(--ink-faint); }
.menu-item__seta { color: var(--ink-faint); }
.menu-item__seta svg { width: 20px; height: 20px; }

/* ── Navegação inferior ───────────────────────────────────────────────────── */

/* Presente em toda tela e em toda largura, como no app publicado nas lojas:
   é a navegação que o usuário já conhece, e some-la no desktop criaria dois
   apps diferentes. */
.nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 25;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  /* Cinto e suspensório do conserto feito no `.palco` (comum.css): o palco é o
     containing block desta barra, então se ele voltar a esticar um dia, as
     quatro colunas se espalhariam para fora da tela e sobraria só "Início".
     Aqui a barra simplesmente não passa da largura da janela. */
  max-width: 100vw;
  background: color-mix(in srgb, var(--bg-raised) 94%, transparent);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}

.nav__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: 60px;
  /* Item inativo em --brand-500, não cinza: pedido do cliente em 01/08 (DESIGN.md §6). */
  color: var(--brand-500);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
}
.nav__item svg { width: 22px; height: 22px; }
.nav__item.is-ativo { color: var(--brand-700); }

/* ── Torrada ──────────────────────────────────────────────────────────────── */

.torrada {
  position: fixed;
  left: 50%; bottom: 84px;
  z-index: 60;
  transform: translate(-50%, 12px);
  max-width: min(420px, calc(100vw - 32px));
  padding: 12px 18px;
  border-radius: var(--radius-button);
  background: #22261F;
  color: #EDEFEA;
  font-size: 14px;
  line-height: 1.45;
  text-align: center;
  box-shadow: 0 10px 30px rgb(20 24 18 / .34);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease-out, transform .2s ease-out;
}
.torrada.is-visivel { opacity: 1; transform: translate(-50%, 0); }

/* ── Tablet ───────────────────────────────────────────────────────────────── */

@container (min-width: 700px) {
  .portas { grid-template-columns: repeat(3, 1fr); }
  .porta { grid-template-columns: 46px 1fr; padding: 16px; }
  .porta__seta { display: none; }
  .topo__entrar { display: inline-flex; }

  .abertura__controles { flex-direction: row; align-items: center; }
  .abertura__controles .busca { flex: 1 1 280px; }
  .uf, .ordem { flex: 0 0 auto; min-width: 190px; }
  .controles { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .controles .busca { flex: 1 1 280px; }
  .controles__linha { flex: 0 0 auto; }
  .chips { flex-basis: 100%; }

  /* Do tablet para cima o cabeçalho não quebra mais: o bloco de títulos
     encolhe (tem `min-width: 0`) e as ações ficam à direita, na mesma altura do
     h1. Sem o `nowrap`, um subtítulo comprido — como o da tela de postar vaga —
     empurrava a barra de abas para debaixo do texto. */
  .secao__topo:has(.secao__acoes) { flex-wrap: nowrap; align-items: flex-start; }
  .secao__titulos { flex: 1 1 auto; }
  .secao__acoes { flex: 0 0 auto; }
  .secao__acoes .btn { flex: 0 0 auto; }

  /* A barra de abas é a única ação que pode ficar larga, então ela é a que
     cede: `0 1 auto` com `min-width: 0`. Sem isso, no tablet ela empurrava a
     página para além da tela — e transbordo horizontal aqui não corta só o
     botão, estica o palco inteiro e desalinha a barra de navegação de baixo
     (o defeito que o Gustavo viu no Galaxy S24). */
  .abas-vaga { flex: 0 1 auto; min-width: 0; }
  .abas { flex: 0 1 auto; min-width: 0; }

  .muro__acoes { flex-direction: row; justify-content: center; }
  .muro__acoes .btn { width: auto; }

  .categorias { grid-template-columns: repeat(6, 1fr); }
  .campanha__texto { padding: var(--space-12) var(--space-8); }
  .anuncios__trilho { --colunas: 2; }
}

/* ── Desktop ──────────────────────────────────────────────────────────────── */

@container (min-width: 1024px) {
  /* Cabe a partir daqui sem espremer a marca nem os botões de conta. */
  /* A barra de duas metades é feita para o polegar: esticada numa tela larga
     vira dois botões gigantes, então para de crescer. */
  .abas { max-width: 420px; }

  /* No desktop os três atalhos são escritos no cabeçalho, então o botão e o
     painel do celular saem de cena. */
  .topo__hamburguer,
  .personas-painel { display: none; }

  .topo__personas {
    display: flex;
    align-items: center;
    gap: var(--space-6);
    margin-left: auto;
    font-size: 14px;
  }
  .topo__personas a { color: var(--ink-soft); font-weight: 600; }
  .topo__personas a:hover { color: var(--brand-700); text-decoration: underline; text-underline-offset: 4px; }

  /* O `margin-left: auto` do nav joga o grupo inteiro para a direita; as ações
     vêm logo depois, então Entrar e Cadastrar continuam na ponta, como antes,
     com os atalhos à esquerda deles. */
  .topo__personas ~ .topo__acoes { margin-left: var(--space-6); }

  .topo__interno,
  .abertura,
  .secao,
  .anuncios,
  .perfil-pagina,
  .detalhe,
  .campanha,
  .topo-da-pagina,
  .voltar { padding-inline: var(--space-8); }

  /* No desktop a barra não se estica de ponta a ponta: os quatro itens ficam
     na mesma coluna de leitura do resto da página. */
  .nav {
    grid-template-columns: repeat(4, minmax(0, 132px));
    justify-content: center;
    gap: var(--space-8);
  }
  .nav__item { flex-direction: row; gap: 8px; min-height: 58px; font-size: 13.5px; }

  .abertura { padding-block: var(--space-12) var(--space-6); }
  .secao { padding-block: var(--space-8); }

  .trilho,
  .anuncios__trilho {
    margin-inline: calc(var(--space-8) * -1);
    padding-inline: var(--space-8);
    scroll-padding-inline: var(--space-8);
  }
  .trilho { grid-auto-columns: minmax(236px, 24cqi); }
  .anuncios__trilho { --colunas: 3; --vao: 12px; }
  .anuncios__setas { display: flex; }

  .grade { grid-template-columns: repeat(auto-fill, minmax(236px, 1fr)); }

  .perfil-capa { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); align-items: center; gap: var(--space-8); }
  .perfil-capa__foto .cartao__foto { aspect-ratio: 1; }

  .rodape__interno { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr); }
  .rodape__colunas { grid-template-columns: repeat(4, 1fr); }
  .rodape__interno, .rodape__base { padding-inline: var(--space-8); }

  .galeria { grid-auto-columns: 42%; margin-inline: calc(var(--space-8) * -1); padding-inline: var(--space-8); }
  .detalhe { max-width: 780px; }
  .perfil-pagina { max-width: 900px; }

  .barra-acao { max-width: 420px; }
  .plano { padding: var(--space-8) var(--space-6); }
}

@container (min-width: 1024px) {
  /* A foto dos fundadores ao lado do texto: ela é apresentação, não
     ilustração, e ganha peso ficando na mesma linha de leitura. */
  .sobre__interno {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    column-gap: var(--space-12);
    padding-inline: var(--space-8);
  }
  .sobre__equipe img { aspect-ratio: 4 / 3; }
}


/* ── Campo de fotos do anúncio (msgs 410237 e 410497) ─────────────────────── */

/* Grade de quadrados que cresce com o que foi escolhido. `auto-fill` e não
   `auto-fit`: com uma foto só, `auto-fit` esticaria a miniatura para a largura
   inteira da tela, e a prévia viraria a coisa mais chamativa do formulário. */
.fotos__grade {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 8px;
  margin-bottom: 10px;
}
.fotos__grade:empty { display: none; }

.fotos__item {
  position: relative;
  margin: 0;
  aspect-ratio: 1;
  border-radius: var(--radius-input);
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
}
.fotos__item img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Qual é a capa tem de dar para ver sem ler a dica — é a única foto que a
   maioria das pessoas vai ver na lista. */
.fotos__capa {
  position: absolute;
  inset: auto 0 0 0;
  padding: 3px 6px;
  background: color-mix(in srgb, var(--brand-700) 88%, transparent);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.03em;
}

/* 28px é menor que o alvo de toque recomendado, e aqui é de propósito: o botão
   fica sobre a foto e o dedo que quer *ver* a foto não pode remover sem querer.
   A área de erro fica na miniatura inteira, que é grande. */
.fotos__tirar {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: color-mix(in srgb, #000 55%, transparent);
  color: #fff;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

/* Retângulo tracejado é a convenção de "solte ou escolha um arquivo aqui" — e
   com `display: flex` a etiqueta inteira vira alvo de toque, não só o texto. */
.fotos__adicionar {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-min, 48px);
  padding: 12px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-input);
  color: var(--brand-700);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.fotos__adicionar[hidden] { display: none; }
.fotos__adicionar span[aria-hidden] { font-size: 18px; }

/* ── Convite de instalação ────────────────────────────────────────────────────
   Mora no `<body>`, fora do palco, pelo mesmo motivo da torrada: `.palco` tem
   `container-type: inline-size`, que aplica `contain: layout` e vira o bloco de
   contenção de qualquer `position: fixed` dentro dele — a barra sumiria no
   celular. Fica abaixo da torrada no empilhamento (60) para um aviso nunca
   ficar escondido atrás do convite. */

.instalar {
  position: fixed;
  left: 50%; bottom: 84px;
  z-index: 55;
  transform: translate(-50%, 12px);
  width: min(460px, calc(100vw - 24px));
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  box-shadow: 0 10px 30px rgb(20 24 18 / .22);
  opacity: 0;
  transition: opacity .2s ease-out, transform .2s ease-out;
}
.instalar.is-visivel { opacity: 1; transform: translate(-50%, 0); }

.instalar__icone { border-radius: 9px; flex: none; }

.instalar__texto { display: grid; gap: 2px; min-width: 0; }
.instalar__texto b    { font-size: 14px; line-height: 1.3; }
.instalar__texto span { font-size: 12.5px; line-height: 1.35; color: var(--ink-faint); }

/* O convite não pode empurrar o botão para fora em tela estreita: o rótulo
   encolhe, o alvo de toque não. */
.instalar__acao { padding-inline: var(--space-4); white-space: nowrap; }

.instalar__fechar {
  /* 44px é o mínimo de alvo de toque; com 32 a pessoa erra o X e acaba
     instalando sem querer — o oposto do que o botão serve para fazer. */
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: transparent;
  color: var(--ink-faint);
  font-size: 22px; line-height: 1;
  cursor: pointer;
}
.instalar__fechar:hover { background: var(--brand-100); }

@media (max-width: 380px) {
  /* Em aparelho estreito o texto de apoio some antes do botão: quem lê "Deixe a
     Agroonnet na tela do celular" já entendeu o suficiente para decidir. */
  .instalar__texto span { display: none; }
}

/* Passos do "como fazer" no iPhone */
.instalar__passos {
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-3);
  text-align: left;
}
.instalar__passos li {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: var(--space-3);
  font-size: 14.5px;
  line-height: 1.45;
}
.instalar__passo-icone {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--brand-100);
  color: var(--brand-700);
}
.instalar__aviso { margin-top: var(--space-4); text-align: left; }

/* ── Painel de métricas (equipe, spec 014) ────────────────────────────────────
   Só o glue de layout dos filtros — os elementos de dentro (`.chip`, `.campo`,
   `.btn`) já são estilo existente. `.metrica`, `.evolucao`, `.pilula` e
   `.bloco` usados na tela também já existem (indicação/comissão e disparo). */
.metricas-filtros { margin-top: var(--space-4); display: grid; gap: var(--space-3); }
.metricas-filtros__linha {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
}
.metricas-filtros__linha .campo { min-width: 140px; flex: 1 1 140px; }
.metricas-filtros__linha .btn { flex: 0 0 auto; }

/* Modificadores que existiam como `style="..."` inline em telas.js — migrados
   por causa da CSP (spec 014, inventário §4-C): style-src fica sem
   'unsafe-inline' e o layout continua idêntico. */
.secao__titulo--espaco { margin-top: var(--space-6); }
.nota-rodape--metricas { text-align: left; margin-top: var(--space-4); }
.nota-rodape--esquerda { text-align: left; }
.indicados--metricas { margin-top: var(--space-4); }
.metrica--herdado {
  margin-top: var(--space-4);
  max-width: 320px;
  border-color: var(--accent-600);
  background: var(--accent-100);
}
.metrica--herdado strong { color: var(--accent-600); }
.pilula--herdado-topo { align-self: flex-start; margin-bottom: 4px; }

/* A altura de `.evolucao__barra` e a largura de `.escada__cheio` são calculadas
   em tempo de execução (não dá pra virar classe fixa) — o template emite
   `data-altura`/`data-largura` (ver telas.js) e quem aplica o valor real ao
   CSSOM (`el.style.height`/`el.style.width`) é `desenhar()` em app.js. CSSOM
   não passa por `style-src`, só o atributo `style="..."` no markup — por isso
   isto não precisa de `'unsafe-inline'` na CSP (spec 014, inventário §4-C).
   O valor abaixo é só o piso visual antes do JS aplicar o real. */
