/* Banner de abertura: foto do candidato com veu roxo por cima, texto branco.
   NUNCA branco solto sobre --laranja (2.73:1, reprova AA, regra numero 1 do
   projeto): a foto e o veu e que destravam o branco, cobrindo o campo laranja
   por inteiro. O veu sai so de --roxo-profundo via color-mix, nunca de hex
   solto, e NAO e uniforme: mais forte onde o texto pousa, mais fraco onde fica
   o rosto do candidato, para ele continuar reconhecivel.
   No mobile o degrade e vertical (texto em cima, rosto revelado embaixo). No
   desktop e horizontal (texto na coluna esquerda, rosto a direita, que e onde
   ele fica com background-position centralizado nesta foto).
   Contraste medido pixel a pixel contra a foto de verdade (Playwright, canvas
   com a mesma matematica de cover/position do CSS), nao contra o veu sozinho:
   o fundo do estudio e quase branco e varia muito ate a camisa clara do
   candidato. Pior pixel sob o texto em 1280 e 390: h1 9.0-9.77:1 (minimo 3:1),
   .prop-sub e .prop-numeros 9.04-9.91:1 (minimo 4.5:1). Medicao nao esta presa
   em teste automatico porque exigiria decodificar JPEG em Node sem lib
   instalada; se a foto, o veu ou o breakpoint mudarem, remeça no navegador. */
.prop-abertura {
  position: relative; overflow: hidden;
  /* Abaixo de 820px usa a variante de 1100px (41 KB): e a faixa que vai de celular a
     tablet retrato, e 1100px cobre ate os 819px do breakpoint com folga de 1.34x sem
     upscaling. O desktop usa o arquivo original de 1600px (90 KB), la embaixo em
     @media (min-width:820px). So compensa gerar variante quando a economia e real:
     aqui e 49 KB por carregamento, medido, nao chute. */
  /* A foto vive numa CAMADA PROPRIA (::after), nao no background da secao. Isso
     existe para poder mascarar a borda dela. Quando a foto era uma camada de
     background com corte seco, a borda de cima aparecia como um risco atravessando
     o banner: o fundo do estudio e quase branco, e o veu por cima e fino demais
     para esconder um corte. Com mascara, a foto se dissolve na cor de fundo e nao
     ha borda nenhuma para enxergar.
     MOBILE: a foto e uma faixa no rodape, com o rosto ABAIXO do bloco de texto. */
  background-color: var(--laranja);
  color: var(--branco);
  padding: 56px 20px 0;
  min-height: 620px;
  display: flex; flex-direction: column; justify-content: flex-start;
}
.prop-abertura-in { max-width: 1400px; margin: 0 auto; width: 100%;
  position: relative; z-index: 1; }
/* O `#000` da mascara NAO e escolha de cor: mask-image so le o canal alfa, entao
   qualquer valor opaco serve. Mesma convencao ja usada na seta do select. */
.prop-abertura::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 58%;
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--laranja) 46%, transparent) 0%,
      color-mix(in srgb, var(--laranja) 20%, transparent) 42%,
      color-mix(in srgb, var(--laranja) 12%, transparent) 100%),
    url("/assets/img/foto-estudio-1-web-1100.jpg");
  background-position: 0 0, 55% bottom;
  background-size: cover, cover;
  background-repeat: no-repeat, no-repeat;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 26%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 26%);
}
.prop-abertura h1 { font-family: "Gilroy", "Arial Black", sans-serif; font-weight: 900;
  text-transform: uppercase; letter-spacing: -.025em; line-height: 1.06;
  font-size: clamp(34px, 7vw, 68px); margin: 0; color: var(--branco); }
.prop-sub { font: 500 clamp(16px, 2.2vw, 20px)/1.45 "Roboto", sans-serif; margin: 14px 0 0; }
.prop-numeros { display: flex; flex-wrap: wrap; gap: 28px; list-style: none;
  margin: 28px 0 0; padding: 0; font: 400 15px "Roboto", sans-serif; }
.prop-numeros strong { font-family: "Gilroy", sans-serif; font-weight: 900;
  font-size: 30px; display: block; line-height: 1; }

@media (min-width: 820px) {
  /* DUAS COLUNAS no desktop, a pedido do Jacques. A foto ganha a metade direita
     inteira, e e isso que faz o rosto aparecer INTEIRO: numa coluna de proporcao
     quase quadrada o `cover` mostra a altura toda da foto, em vez de recortar uma
     faixa horizontal como fazia a versao sangrada de ponta a ponta.
     De quebra o contraste deixa de depender da foto: o texto fica sobre roxo
     solido, e branco sobre --roxo-profundo e 11,75:1 fixo, medido no Plano 1. */
  .prop-abertura {
    justify-content: center;
    min-height: clamp(420px, 30vw, 560px);
    padding: 0 20px;
  }
  .prop-abertura-in { padding: 44px 0; }
  /* O teto de 46% segura o texto na metade esquerda mesmo se a copy crescer, e o
     `min` impede que ele estique demais em tela larga. */
  .prop-abertura h1, .prop-sub, .prop-numeros { max-width: min(560px, 46%); }
  .prop-abertura::after {
    left: 50%; right: 0; top: 0; bottom: 0; height: auto;
    background-image:
      linear-gradient(90deg,
        color-mix(in srgb, var(--laranja) 24%, transparent) 0%,
        color-mix(in srgb, var(--laranja) 10%, transparent) 30%,
        color-mix(in srgb, var(--laranja) 8%, transparent) 100%),
      url("/assets/img/foto-estudio-1-web.jpg");
    background-position: 0 0, 42% center;
    background-size: cover, cover;
    /* Aqui a mascara dissolve a borda ESQUERDA, que e onde a foto encosta no roxo.
       Sem ela a divisa entre as duas colunas vira uma linha vertical dura, o mesmo
       defeito que aparecia no topo da faixa no mobile. */
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 16%);
    mask-image: linear-gradient(90deg, transparent 0%, #000 16%);
  }
}

.prop-ferramenta { max-width: 1400px; margin: 0 auto; padding: 36px 20px 72px; }
.prop-grade { display: grid; gap: 32px; }
/* A coluna do mapa e 760px de proposito: e a largura em que o pin de raio 15
   unidades vira uma bolinha de 22,8px e o numero fica com 11,4px, legivel.
   Estreitar isso quebra a legibilidade do mapa, nao e so estetica. */
@media (min-width: 1024px) {
  .prop-grade { grid-template-columns: minmax(0, 760px) minmax(320px, 1fr); align-items: start; }
  .prop-mapa { position: sticky; top: 92px; }
  .prop-lista { max-height: calc(100vh - 120px); overflow-y: auto; }
}

.prop-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.prop-item { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 14px;
  background: var(--branco); border: 1px solid var(--borda); border-radius: var(--r-md);
  padding: 16px 18px; scroll-margin-top: 100px; }
.prop-item.is-ativo { border-color: var(--roxo); box-shadow: var(--sombra-md); }
.prop-item[hidden] { display: none; }
.prop-n { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  background: var(--roxo); color: var(--branco);
  font: 900 15px "Gilroy", "Arial Black", sans-serif; }
.prop-titulo { font: 700 17px/1.3 "Roboto", sans-serif; color: var(--roxo); margin: 4px 0 6px; }
.prop-desc { font: 400 15px/1.55 "Roboto", sans-serif; color: var(--ink); margin: 0; }
.prop-meta { margin: 10px 0 0; display: flex; flex-wrap: wrap; gap: 8px; }
.prop-tag { font: 500 12px "Roboto", sans-serif; color: var(--muted);
  border: 1px solid var(--borda); border-radius: var(--r-pill); padding: 3px 10px; }

.mapa-svg { width: 100%; height: auto; display: block; }

/* A terra NAO tem regra de cor aqui. Desde 2026-08-12 o mapa vem do build ja
   dividido nas 7 mesorregioes, com a escada tonal gravada no atributo `fill` de
   cada regiao. Isso e obrigatorio para a home, que carrega o mesmo arquivo dentro
   de um <img>, onde CSS nao alcanca o interior do SVG. Repetir a escada aqui em
   CSS criaria uma segunda fonte da mesma cor, livre para divergir em silencio.
   As classes .mapa-terra, .mapa-regiao e .mapa-divisas vem do proprio SVG. */

/* CONTRA-ESCALA. O JS mede --escala = largura renderizada / largura do viewBox, e
   todo tamanho de pin e escrito como "quantos px de tela eu quero, dividido pela
   escala". Assim a bolinha tem SEMPRE 22px na tela, em qualquer largura e com ou
   sem zoom de regiao. Sem isso, o mesmo codigo da 21,8px em 768 e 10,5px em 390.
   O r=15 do atributo no JS e so o estado antes de o JS medir. */

/* A divisa entra na mesma conta. O atributo do SVG traz 3,2 unidades, calibrado
   para os 300px da home; aqui o mapa vai a 760px e ainda entra em zoom de regiao
   no mobile, onde 3,2 unidades virariam um traco gordo de quase 4px. */
.mapa-divisas { stroke-width: calc(1.2px / var(--escala, .76)); }

.pin-bola { fill: var(--roxo); stroke: var(--roxo);
  r: calc(11px / var(--escala, .76));
  stroke-width: calc(2px / var(--escala, .76)); }
.pin-num { fill: var(--branco); pointer-events: none;
  font-family: "Gilroy", "Arial Black", sans-serif; font-weight: 900;
  font-size: calc(11px / var(--escala, .76)); }
/* Quem separa o pin do mapa e este anel branco, nao o laranja: sobre o tom mais
   claro da escada o laranja sozinho da 1,41:1, e o anel da 3,91:1. */

/* A guia liga o pin deslocado a cidade de verdade. Branca porque e a unica cor
   que passa de 3:1 nos sete tons (3,91:1 no pior deles); o roxo que ela usava
   sumia nas tres regioes escuras. Tracejada para nao ser confundida com a divisa
   entre mesorregioes, que tambem e branca e continua: guia e conector, nao
   fronteira. */
.pin-guia { stroke: var(--roxo);
  stroke-width: calc(1.5px / var(--escala, .76));
  stroke-dasharray: calc(4px / var(--escala, .76)) calc(3px / var(--escala, .76)); }

/* Estado ativo em lima com numero ink: 3,03:1 no tom mais claro da escada e
   13,84:1 do numero contra o lima. O roxo que estava aqui virou invisivel quando
   o mapa passou a ser roxo, e o branco do numero ficaria com 1,28:1 sobre o lima.
   O piso de 3:1 do lima e o que decide ate onde a escada pode clarear, no
   build-mapa.mjs. */
.pin.is-perto .pin-bola, .pin.is-ativo .pin-bola { fill: var(--branco); }
.pin.is-perto .pin-num, .pin.is-ativo .pin-num { fill: var(--roxo); }
.pin:focus-visible { outline: none; }
/* O foco tambem aciona is-ativo, entao a bolinha ja esta lima quando este anel
   aparece: o que marca o foco e o anel branco engrossar de 2px para 5px. */
.pin:focus-visible .pin-bola { stroke: var(--ink); stroke-width: calc(5px / var(--escala, .76)); }

.prop-filtros { display: grid; gap: 12px; margin: 0 0 26px; }
/* Sem esta linha o bloco aparece com o JavaScript desligado. O atributo `hidden`
   do HTML vale por uma regra `[hidden] { display: none }` da folha do navegador,
   que PERDE em especificidade para um seletor de classe, entao o `display: grid`
   acima anula o hidden. Com JS ligado nao da para ver, porque montaFiltros() tira
   o hidden de qualquer jeito, e sem JS sobra um bloco vazio ocupando margem.
   Mesmo motivo da defesa do .prop-item[hidden] la em cima. */
.prop-filtros[hidden] { display: none; }
.filtro-linha { display: flex; flex-wrap: wrap; gap: 8px; }
.filtro-pill { border: 1px solid var(--borda); background: var(--branco); color: var(--roxo);
  border-radius: var(--r-pill); min-height: 40px; padding: 0 16px; cursor: pointer;
  font: 500 14px "Roboto", sans-serif; }
.filtro-pill:hover { border-color: var(--roxo); }
.filtro-pill[aria-pressed="true"] { background: var(--roxo); color: var(--branco); border-color: var(--roxo); }
.filtro-pill:focus-visible { outline: 3px solid var(--laranja); outline-offset: 2px; }

/* Regiao e tema deixaram de ter o mesmo peso visual (Tarefa 3, revisao do Jacques).
   Regiao continua em chip porque e o eixo principal e comanda o zoom do mapa no
   mobile (Tarefa 11): toque direto, navegacao. Tema virou <select> nativo porque e
   refinamento, nao navegacao, e o select e o controle que menos exige de quem tem
   baixa confianca digital. Ver .filtro-select mais abaixo. */
/* Lado a lado, os dois controles ficam com cerca de 160px em 390, e nem "Todos os
   temas" nem o placeholder da busca cabem: os dois truncam no meio da palavra.
   Empilhados eles pegam a largura inteira e o texto aparece completo. A linha a
   mais custa 54px, contra os 709px que o bloco inteiro tinha antes desta revisao,
   e num publico de baixa confianca digital controle legivel vale mais que a linha
   economizada. Acima de 640px sobra largura e eles voltam a dividir a linha. */
.filtro-refino { display: flex; flex-direction: column; gap: 10px; }
@media (min-width: 640px) {
  .filtro-refino { flex-direction: row; }
  /* So aqui o basis e largura, entao so aqui ele pode existir. O max-width existe
     porque a linha tem 1360px no desktop: sem teto, o select vira uma pill de 597px
     para caber "Agro", e um controle esticado le como descuido, nao como controle.
     O 380 da busca e o mesmo teto que ela ja tinha antes desta revisao. */
  .filtro-select-caixa { flex: 0 1 260px; width: auto; }
  .filtro-input { flex: 0 1 380px; width: auto; }
}
/* Empilhados (abaixo de 640px) os dois ocupam a largura inteira. O `flex` com basis
   fica so na direcao LINHA, mais abaixo: em coluna o flex-basis vira ALTURA, e um
   `flex: 1 1 140px` aqui esticaria o controle para 140px de alto. */
.filtro-select-caixa { position: relative; display: flex; width: 100%; min-width: 0; }
/* Seta desenhada em SVG via mask, nunca caractere unicode (regra 4 do projeto).
   O 'black' dentro do data URI NAO e uma escolha de cor: mask-image so usa o canal
   alfa do SVG, entao qualquer preenchimento opaco serve de mascara. A cor que
   aparece de verdade vem de background-color: var(--ink), o token de marca. Isso
   evita cravar o hex do roxo dentro do SVG, que violaria a regra 3 (nada de cor
   inventada fora de marca.css). */
.filtro-select-caixa::after {
  content: ""; position: absolute; top: 50%; right: 14px; width: 12px; height: 12px;
  transform: translateY(-50%); pointer-events: none;
  background-color: var(--ink);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}
/* appearance:none tira so o CROMO nativo (borda, fundo, seta): o elemento continua
   um <select> de verdade, e o toque continua abrindo o seletor do proprio sistema.
   Altura, raio e borda casados com .filtro-input de proposito, para os dois lerem
   como o MESMO nivel de controle (refinamento), nunca como navegacao. */
.filtro-select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  width: 100%; min-height: 44px; padding: 0 36px 0 14px;
  border: 1px solid var(--borda); border-radius: var(--r-pill);
  background: var(--branco); color: var(--ink);
  font: 400 15px "Roboto", sans-serif; cursor: pointer;
}
.filtro-select:focus-visible { outline: 3px solid var(--laranja); outline-offset: 2px; }
.filtro-input { width: 100%; min-width: 0; min-height: 44px; padding: 0 14px;
  border: 1px solid var(--borda); border-radius: var(--r-pill);
  font: 400 15px "Roboto", sans-serif; color: var(--ink); background: var(--branco); }
/* --muted da 6.46:1 sobre --branco (contraste medido no relatorio da Tarefa 3):
   placeholder nao pode herdar o cinza-claro padrao do navegador, que reprova AA. */
.filtro-input::placeholder { color: var(--muted); opacity: 1; }
.filtro-input:focus-visible { outline: 3px solid var(--laranja); outline-offset: 2px; }

.filtro-rodape { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.filtro-conta { font: 500 14px "Roboto", sans-serif; color: var(--muted); margin: 0; }
/* Texto discreto de proposito, nao pill: ele nomeia a ACAO (limpar), nao repete o
   ESTADO que ja esta no contador ao lado. min-height segura o alvo de toque de
   44px mesmo sem fundo nem borda grandes. */
.filtro-limpar {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px;
  border: none; background: none; cursor: pointer;
  color: var(--roxo); font: 700 14px "Roboto", sans-serif;
  text-decoration: underline; text-underline-offset: 3px;
}
.filtro-limpar:hover { color: var(--roxo); }
.filtro-limpar:focus-visible { outline: 3px solid var(--laranja); outline-offset: 2px; }
/* Mesma defesa do .prop-filtros[hidden] la em cima, e pelo mesmo motivo: a classe
   declara display: inline-flex, que empata em especificidade com [hidden] e vence
   por ordem de fonte se nao houver este seletor mais especifico. */
.filtro-limpar[hidden] { display: none; }

.pin.is-apagado { opacity: .18; pointer-events: none; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

@media (max-width: 1023px) {
  .prop-mapa { margin: 0 0 18px; }
  .mapa-svg { transition: none; }
  .mapa-svg.is-ilustracao { pointer-events: none; }
  .mapa-svg.is-ilustracao .pin-num { display: none; }
  .mapa-svg.is-ilustracao .pin-guia { display: none; }
  /* Ilustracao: sem numero, a bolinha vira ponto de 10px na tela. Continua
     contra-escalada, so que menor. Note o "px" no valor: `r: 9` sem unidade nao e
     <length> valido, o Chromium aceita por tolerancia mas isso nao e contrato. */
  .mapa-svg.is-ilustracao .pin-bola { r: calc(5px / var(--escala, .76));
    stroke-width: calc(1.5px / var(--escala, .76)); }
  .filtro-pill { min-height: 44px; }

  /* Faixa de regiao de 1 linha so, abaixo de 1024px (Tarefa 3). Acima disso o
     .filtro-linha de cima volta a quebrar linha, sem rolagem, como sempre foi. */
  .filtro-linha[data-grupo="regiao"] {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    /* O padding da direita casa com a largura do degrade de mascara abaixo: sem
       isso, um chip focado pelo teclado perto do fim da faixa para exatamente
       onde a mascara comeca a apagar, e o estado ativo fica ilegivel mesmo
       "visivel" tecnicamente. */
    scroll-padding-inline: 8px 40px;
    -webkit-overflow-scrolling: touch;
    /* A barra de rolagem classica do Chromium desktop come 15px de altura da faixa
       e vem com setinhas nas pontas, que numa fileira de chip parece defeito, nao
       controle. `thin` tira as setas e devolve altura. Em telefone isto nao muda
       nada: la a barra ja e overlay e some sozinha. Nao escondo de todo porque
       abaixo de 1024px tambem existe janela de desktop estreita, e ai a barra e a
       unica pista de rolagem para quem usa mouse e nao ve a mascara como convite. */
    scrollbar-width: thin;
    scrollbar-color: var(--borda) transparent;
    /* Indicacao de que ha mais chip a direita: a faixa se apaga nos ultimos 36px.
       A classe .regiao-fim (JS, ao detectar scrollLeft + clientWidth >= scrollWidth)
       remove a mascara quando nao ha mais nada para rolar. */
    mask-image: linear-gradient(to right, black calc(100% - 36px), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, black calc(100% - 36px), transparent 100%);
  }
  .filtro-linha[data-grupo="regiao"].regiao-fim {
    mask-image: none;
    -webkit-mask-image: none;
  }
  .filtro-linha[data-grupo="regiao"] .filtro-pill {
    flex: 0 0 auto;
    scroll-snap-align: start;
    scroll-margin-inline: 8px;
  }
}
@media (prefers-reduced-motion: no-preference) {
  .mapa-svg { transition: none; }
}
