/* Página de resultados (Polesportivo), pedido do usuário 2026-09-16.
   Fica no ar só de sábado até segunda (ver inc/evento-fase.php). */

/* Achado real 2026-09-18 (15ª rodada): "essa faixa branca tb tem q
   ajustar" -- <body> é branco por padrão (main.css, pensado pras outras
   páginas do site, mais claras) -- aqui aparecia como uma fresta branca
   fina entre o fim do <main> escuro e o rodapé (gap padrão de
   espaçamento entre blocos do tema), e como uma faixa branca BEM maior
   no final de verdade da página (padding-bottom que o JS de
   site-notices.php reserva pro aviso de cookies fixo não ficar por cima
   do conteúdo -- ver updateBodyPadding()). Corrige na raiz: nessa página
   específica (classe já existente, ver rmg-header-reduzido em
   functions.php), o body escurece igual ao resto do conteúdo -- sem
   precisar caçar/reduzir cada gap um por um. */
body.rmg-header-reduzido { background: var(--black); }

.ranking-page {
  max-width: 720px; margin: 0 auto; padding: 2rem 1rem 1.25rem;
  color: var(--white); font-family: 'Montserrat', sans-serif;
}
.ranking-page__titulo {
  text-align: center; color: var(--white); font-weight: 800;
  font-size: 1.4rem; margin: 0 0 1.5rem;
}
.ranking-page__aviso {
  text-align: center; color: rgba(255,255,255,.6);
  padding: 3rem 1rem; font-size: .95rem;
}

/* Contagem regressiva pra 1ª largada -- pedido do usuário 2026-09-18: a
   página fica acessível desde 6h de sábado, mas a 1ª largada só é 07:30,
   então tem ~1h30 de janela onde "evento rolando agora" seria mentira.
   Reaproveita o MESMO componente/JS de contagem já usado no hero da home
   (assets/js/countdown.js, [data-countdown] + [data-cd-d/h/m/s]) --
   enfileirado sitewide, não precisa de enqueue novo. Compacto de
   propósito (menor que o do hero) porque some rápido (a primeira largada
   é sempre nas primeiras 1-2h da janela). */
.ranking-countdown {
  display: flex; justify-content: center; gap: .6rem; margin: 0 0 1rem;
}
.ranking-countdown > div {
  background: #141414; border: 1px solid rgba(255,204,0,.25);
  border-radius: var(--radius-sm); padding: .4rem .6rem; text-align: center;
  min-width: 46px;
}
.ranking-countdown span { display: block; color: var(--yellow); font-weight: 800; font-size: 1.1rem; }
.ranking-countdown small { display: block; color: rgba(255,255,255,.5); font-size: .58rem; text-transform: uppercase; letter-spacing: .03em; }

/* Teaser -- pedido do usuário 2026-09-18 (8ª rodada): patrocinadores +
   abas ficam escondidos até faltar 30min pra largada, esse espaço ocupa o
   lugar até lá (ver [data-ranking-teaser] em inc/ranking-page.php).
   Achado 2026-09-19 (dia da prova): "Informações" é disparado o link mais
   clicado do menu do site (70% dos cliques, ver análise GA4) -- pedido do
   usuário: em vez de só um texto solto "acompanhe em breve", mostrar as
   acordeões de Informações da Etapa (mesma função já usada na home,
   rmg_etapa_info_section_render()) até o mapa liberar -- quem tá se
   organizando pra chegar no evento aproveita essa espera, quem já chegou
   (depois que libera) não precisa mais dessa info aqui. */
.ranking-page__teaser-texto {
  text-align: center; color: rgba(255,255,255,.45); font-size: .8rem;
  margin: 0 0 1.5rem; padding: 0 1rem;
}
/* A seção de Informações (.section/.wrap) foi pensada pra full-bleed na
   home, com respiro vertical de sobra (--space-xl = 5.5rem em cima E
   embaixo) -- exagero aqui dentro do card compacto da página de
   resultados, além do padding lateral do `.wrap` duplicar com o padding
   do `.ranking-page` (1.5rem + 1rem = 2.5rem de cada lado, estreitando
   demais). Encolhe os dois pra caber igual ao resto do card. */
[data-ranking-teaser] .section { padding: 0; }
[data-ranking-teaser] .section .wrap { padding-left: 0; padding-right: 0; max-width: none; }
/* Título da seção também encolhe -- na home é clamp(1.75rem,3.5vw,2.5rem)
   de propósito grande (título de página inteira); aqui é só mais um
   bloco dentro de um card, precisa ficar discreto. */
[data-ranking-teaser] .section__title { font-size: 1.3rem; }
[data-ranking-teaser] .section__label { margin-bottom: .3rem; }

/* Engajamento -- pedido do usuário 2026-09-18 (3ª rodada): o contador "X
   acompanhando agora" migrou pro header (ver rmg-header-clima__acompanhando
   em main.css), então aqui sobra só o texto de cautela do clima (migrado
   pra cá, "em cima do compartilhar nesse mesmo tamanho") + o botão em si,
   empilhados e centralizados. Fica ACIMA das abas, de propósito: aparece
   independente de qual aba está ativa. */
/* align-items:stretch (não "center") de propósito -- achado ao testar
   2026-09-18: com "center", os filhos encolhiam pro tamanho do próprio
   conteúdo em vez de esticar 100% da largura, e a faixa de patrocinadores
   (.sponsor-footnote, pensada pra ser full-width) estourava a tela
   (logo da Jeep cortado à esquerda, Decathlon à direita, carrossel mobile
   nem rodava direito). Botão compartilhar saiu daqui (6ª rodada, migrou
   pro header, ver .rmg-header-clima__compartilhar em main.css) -- essa
   div hoje só tem a faixa de patrocinadores dentro. */
.ranking-engajamento {
  display: flex; flex-direction: column; align-items: stretch; gap: .6rem;
  margin: 0 0 1rem; text-align: center;
}

/* Link de fotos grátis do evento (Fotop/Cia do Click) -- pedido do
   usuário 2026-09-19: "tem como colocar esse link em algum local
   visivel?". Sempre visível (mesmo lugar dos patrocinadores/compartilhar
   acima), mesma linguagem visual dourada de "destaque real" já usada no
   resto da página (badge/anel de 1º colocado). */
.ranking-page__fotos {
  display: flex; align-items: center; gap: .7rem;
  background: rgba(255,204,0,.1); border: 1px solid rgba(255,204,0,.35);
  border-radius: .6rem; padding: .7rem .9rem; margin: 0 0 1rem;
  text-decoration: none; color: inherit;
}
.ranking-page__fotos-icone { font-size: 1.4rem; line-height: 1; }
.ranking-page__fotos-texto { display: flex; flex-direction: column; line-height: 1.3; }
.ranking-page__fotos-texto b { color: var(--yellow); font-size: .85rem; }
.ranking-page__fotos-texto small { color: rgba(255,255,255,.55); font-size: .72rem; }

/* Patrocinadores compactos -- pedido do usuário 2026-09-18 (5ª rodada):
   "numa linha fina... no maximo 30px de altura... igual está em produção
   na parte de gpx". Fundo branco continua necessário (mesmo motivo já
   documentado no CSS do GPX: a maioria dos logos é pensada pra fundo
   claro, em cima do preto do site ficam quase invisíveis) -- só a altura
   e o padding encolheram bastante. 20px de logo + .25rem de padding
   vertical (8px) fica dentro do limite pedido. */
.sponsor-compacto {
  background: #fff; border-radius: var(--radius-sm);
  padding: .25rem .7rem; margin: 0 0 .8rem;
}
@media (min-width: 1024px) {
  .sponsor-compacto { padding: .6rem 1rem; }
}
.sponsor-compacto__logos {
  position: relative; width: 100%; height: 20px;
  display: flex; align-items: center; justify-content: center;
  /* No mobile o JS agrupa em trincas dentro de .sponsor-compacto__grupo
     (gap próprio, ver abaixo) e esse container fica só como referência de
     posicionamento (position:relative). No desktop (>=1024px) o JS pula
     esse agrupamento de propósito -- pedido do usuário 2026-09-18: "no
     desk não precisa de fade in fade out de logo, pode deixar mostrar
     todos travado" -- então os 9 .sponsor-compacto__item ficam soltos
     AQUI DENTRO, direto, sem nenhum .sponsor-compacto__grupo por cima.
     Achado real: sem gap aqui, ficavam "grudados uns nos outros" nesse
     caminho (o gap só existia no grupo que o desktop nunca chega a
     criar). */
  gap: 1.4rem;
}
.sponsor-compacto__item {
  display: flex; align-items: center; flex-shrink: 0;
}
/* Desktop (JS pula o agrupamento, ver ranking-page.js): altura fixa de
   20px só faz sentido pro grupo de 3 que o mobile mostra por vez -- com
   os 9 logos soltos aqui, se não couberem numa linha só (containers mais
   estreitos que 1024px de largura útil, ex. telas de 1024-1200px reais)
   precisa poder quebrar linha em vez de cortar/espremer os logos. */
@media (min-width: 1024px) {
  .sponsor-compacto__logos { height: auto; min-height: 32px; flex-wrap: wrap; row-gap: .5rem; gap: 2rem; }
}
.sponsor-compacto__item img {
  display: block; height: 20px; width: auto; max-width: 90px; object-fit: contain;
}
/* Desktop maior -- pedido do usuário 2026-09-18 (3ª rodada): "no desk
   pode aumentar um pouco o tamanho da linha, ta muito pequeno os logos".
   20px->32px (60% maior), sem o limite de 30px que valia só pro mobile
   (ver comentário acima, ".sponsor-compacto" -- essa regra é específica
   do card compacto do mobile, nunca se aplicou ao desktop). */
@media (min-width: 1024px) {
  .sponsor-compacto__item img { height: 32px; max-width: 130px; }
}
/* Grupos de 3 revezando com fade -- mesma técnica do carrossel já em
   produção no modal do GPX (rota-interativa.css).
   Achado real 2026-09-18 (2ª rodada, iPhone de verdade): o revezamento
   via setInterval/setTimeout do JS simplesmente não rodava de forma
   confiável no Safari/iOS (mesmo sem "Reduzir Movimento" ativado --
   testado à parte, não é o mesmo bug da 1ª rodada) -- provável
   throttling de timer em segundo plano/energia. Trocado pra animação
   100% CSS (@keyframes gerado dinamicamente + animation-delay negativo
   por grupo, ver ranking-page.js) -- o motor de animação do navegador
   não depende de nenhum timer JS ficar "vivo" depois do setup inicial,
   muito mais robusto no Safari. `opacity:0` aqui é só o estado de base
   antes do JS aplicar o `animation` inline (ou pro fallback sem-JS, que
   mostra os itens soltos ANTES de serem agrupados -- este seletor só
   afeta o .sponsor-compacto__grupo que o JS cria). `pointer-events:none`
   evita que o grupo escondido (ainda ocupando a mesma caixa via
   position:absolute) intercepte clique do logo realmente visível. */
.sponsor-compacto__grupo {
  display: flex; align-items: center; justify-content: center;
  gap: 1.4rem; position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  opacity: 0; pointer-events: none;
  /* will-change -- achado real 2026-09-18 no toast (mais abaixo): nessa
     página com mapa ao vivo se redesenhando o tempo todo, elementos que
     precisam animar por cima/perto dele às vezes não pintavam direito
     sem uma camada de composição própria, mesmo com CSS correto.
     Aplicado aqui por precaução (mesma classe de sintoma: só 3 logos
     fixos, nunca revezando). */
  will-change: opacity;
}
.sponsor-compacto__grupo.is-visivel { opacity: 1; pointer-events: auto; }
/* SEM @media (prefers-reduced-motion: reduce) aqui de propósito -- achado
   real 2026-09-18 (3ª rodada): no iPhone do usuário o revezamento nunca
   rodava, e batia exatamente com esse bloco desativando a animação (Modo
   de Baixo Consumo pode fazer o iOS reportar Reduzir Movimento mesmo sem
   a pessoa ter pedido isso de propósito). Decisão: pro crossfade de logo
   (baixo risco, só opacidade) essa preferência deixou de ser respeitada
   aqui -- ver ranking-page.js pro mesmo achado do lado JS. */

/* Toast avisando pra compartilhar -- pedido do usuário 2026-09-18 (7ª
   rodada), redesenhado na 10ª rodada: "eu digo o botão de compartilhar
   seria o toast abrindo nele apontando q ele serve pra compartilhar" --
   virou um balão pequeno com setinha, posicionado pelo JS (ver
   ranking-page.js) logo abaixo do ícone de compartilhar de verdade no
   header (.rmg-header-clima__compartilhar) -- `top`/`left` setados
   dinamicamente ali, não aqui (a posição do botão-alvo muda com a
   largura da tela). Some no X ou ao clicar no ícone real do header
   (educou, cumpriu o papel). */
.resultados-toast {
  position: fixed; top: 0; left: 0; z-index: 2000;
  transform: translateY(-10px); opacity: 0;
  transition: opacity .3s ease, transform .3s ease;
  /* Achado real 2026-09-18: mesmo com z-index/stacking corretos (topo no
     hit-test), o toast não pintava por cima do mapa Leaflet ao vivo (que
     fica se redesenhando o tempo todo, o ponteiro do pelotão se
     movendo) -- promove camada de composição própria pra garantir que
     entre nessa disputa em pé de igualdade com as camadas do mapa.
     z-index também subiu de 60 -> 2000: os panes internos do Leaflet
     chegam a usar até ~700-1000 (.leaflet-popup-pane etc.). */
  will-change: transform, opacity; backface-visibility: hidden;
  background: #14181f; border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--radius-md, 10px);
  padding: .75rem 2.1rem .75rem .9rem;
  max-width: min(80vw, 250px);
  box-shadow: 0 10px 28px rgba(0,0,0,.45);
}
.resultados-toast.is-visivel { opacity: 1; transform: translateY(0); }
.resultados-toast[hidden] { display: none; }
.resultados-toast__texto {
  margin: 0; color: rgba(255,255,255,.88); font-size: .76rem; line-height: 1.35;
}
/* Setinha apontando pro botão real do header -- `--seta-x` é a posição
   horizontal (em px, dentro do próprio balão) setada via JS conforme o
   centro do botão-alvo, com clamp pra nunca sair da largura do balão. */
.resultados-toast__seta {
  position: absolute; top: -6px; left: var(--seta-x, 50%);
  width: 12px; height: 12px; margin-left: -6px;
  background: #14181f; border-left: 1px solid rgba(255,255,255,.14);
  border-top: 1px solid rgba(255,255,255,.14);
  transform: rotate(45deg);
}
.resultados-toast__fechar {
  position: absolute; top: .45rem; right: .55rem;
  width: 20px; height: 20px; border-radius: 50%; border: none;
  background: rgba(255,255,255,.1); color: rgba(255,255,255,.75);
  font-size: 1rem; line-height: 1; cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center;
}
@media (prefers-reduced-motion: reduce) {
  .resultados-toast { transition: none; }
}

/* Avisos de responsabilidade (estimativa + fonte oficial) -- pedido do
   usuário 2026-09-18 (14ª rodada): 2 botões bem discretos (título curto +
   ícone "i"), chamados no fim das 3 abas (ver rmg_ranking_disclaimers_html()
   em inc/ranking-page.php). Clicar abre .ranking-info-popover (balão com
   seta, mesmo padrão visual do balão do botão compartilhar). */
.ranking-disclaimers {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem .7rem;
  margin: 1.2rem 0 0;
}
.ranking-disclaimers__item {
  display: inline-flex; align-items: center; gap: .3rem;
  background: none; border: none; padding: 0;
  color: rgba(255,255,255,.4); font-size: .7rem; font-weight: 600;
  cursor: pointer; text-decoration: underline; text-decoration-color: rgba(255,255,255,.2);
  text-underline-offset: 2px;
}
.ranking-disclaimers__item:hover,
.ranking-disclaimers__item.is-ativo { color: rgba(255,255,255,.7); }
.ranking-disclaimers__icone { width: 13px; height: 13px; flex-shrink: 0; }

/* Balão do popover -- mesmo padrão visual/técnico do .resultados-toast
   (posição via JS conforme o botão clicado, seta apontando pra ele,
   camada de composição própria pelo mesmo motivo documentado lá: página
   com mapa ao vivo se redesenhando o tempo todo). Fecha no X, clicando
   fora, ou clicando de novo no mesmo botão que abriu. */
.ranking-info-popover {
  position: fixed; top: 0; left: 0; z-index: 2000;
  transform: translateY(-10px); opacity: 0; pointer-events: none;
  transition: opacity .25s ease, transform .25s ease;
  will-change: transform, opacity; backface-visibility: hidden;
  background: #14181f; border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--radius-md, 10px);
  padding: .8rem 2rem .8rem .9rem;
  max-width: min(85vw, 300px);
  box-shadow: 0 10px 28px rgba(0,0,0,.45);
}
.ranking-info-popover.is-visivel { opacity: 1; transform: translateY(0); pointer-events: auto; }
.ranking-info-popover[hidden] { display: none; }
.ranking-info-popover__texto {
  margin: 0; color: rgba(255,255,255,.85); font-size: .76rem; line-height: 1.4;
}
.ranking-info-popover__seta {
  position: absolute; top: -6px; left: var(--seta-x, 50%);
  width: 12px; height: 12px; margin-left: -6px;
  background: #14181f; border-left: 1px solid rgba(255,255,255,.14);
  border-top: 1px solid rgba(255,255,255,.14);
  transform: rotate(45deg);
}
.ranking-info-popover--baixo .ranking-info-popover__seta {
  top: auto; bottom: -6px;
  border-left: none; border-top: none;
  border-right: 1px solid rgba(255,255,255,.14);
  border-bottom: 1px solid rgba(255,255,255,.14);
}
.ranking-info-popover__fechar {
  position: absolute; top: .4rem; right: .5rem;
  width: 20px; height: 20px; border-radius: 50%; border: none;
  background: rgba(255,255,255,.1); color: rgba(255,255,255,.75);
  font-size: 1rem; line-height: 1; cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center;
}
@media (prefers-reduced-motion: reduce) {
  .ranking-info-popover { transition: none; }
}

/* Abas (Ao vivo / Vídeo / Buscar) -- pedido do usuário 2026-09-18, testar
   se resolve o aperto de mobile depois de somar vídeo+engajamento+mapa
   numa página só. [hidden] nativo esconde os paineis, sem regra de
   display própria pra não repetir o bug de especificidade já visto 3x
   nesta sessão (ver comentário em ranking-page.js). */
.ranking-tabs {
  display: flex; gap: .4rem; margin: 0 0 1rem; overflow-x: auto;
  scrollbar-width: none;
}
.ranking-tabs::-webkit-scrollbar { display: none; }
.ranking-tabs__botao {
  flex: 1 1 auto; white-space: nowrap; background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.1); border-radius: var(--radius-sm);
  padding: .6rem .8rem; color: rgba(255,255,255,.6); font-size: .76rem;
  font-weight: 700; cursor: pointer; text-align: center;
}
.ranking-tabs__botao.is-ativo {
  background: rgba(255,204,0,.12); border-color: var(--yellow); color: var(--yellow);
}
/* Bolinha piscando no "🏆 Ranking" -- pedido do usuário 2026-09-19, pra
   dar o sinal de "tem gente aqui" (achado via GA4: 0 cliques na aba até
   então). Trocou o badge de número (1ª tentativa) por isso: "pode tirar
   o badge de ranking, só coloca um botao piscando pra chamar a atencao,
   tipo um bolinha piscando". Mesmo halo crescendo já usado no marcador
   do mapa (.ranking-estimativa__pulso), só menor e sem cor por JS. */
.ranking-tabs__dot {
  display: inline-block; position: relative; margin-left: .35rem;
  width: 7px; height: 7px; border-radius: 50%; background: var(--yellow);
  vertical-align: middle;
}
.ranking-tabs__dot::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: var(--yellow); animation: ranking-estimativa-pulso 1.8s ease-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ranking-tabs__dot::after { animation: none; }
}

/* Vídeo (inc/resultados-video.php) -- caixa responsiva 16:9, mesmo padrão
   universal de embed do YouTube. */
.ranking-video__wrap {
  position: relative; width: 100%; padding-top: 56.25%;
  border-radius: var(--radius-md); overflow: hidden; background: #000;
}
.ranking-video__wrap iframe {
  position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;
}

/* Texto de expectativa/cautela do clima (pedido do usuário 2026-09-17,
   ver rmg_ranking_texto_cautela_html em inc/ranking-page.php) -- estático,
   nada de ticker rolando (o ticker amarelo "não funcionou" no mobile,
   segundo o usuário). Rebaixado pra logo abaixo do hero (fora da área
   "sem rolar") na rodada seguinte, no lugar entrou o resumo da largada. */
.ranking-hero__cautela {
  text-align: center; color: rgba(255,255,255,.75);
  font-size: .85rem; line-height: 1.4; margin: 0 0 1.5rem;
}

/* Resumo minimalista da largada atual, pedido do usuário 2026-09-17:
   "coloca numa linha o cronograma de largada bem minimalista, horário e
   modalidades, bem mais simples, não precisa de box em volta" -- fica no
   lugar onde antes tinha o texto de cautela, dentro do hero. O cronograma
   completo (cards com ícone/cronômetro/carrossel) continua mais abaixo,
   sem mudança nenhuma nele. */
.ranking-hero__largada {
  text-align: center; color: rgba(255,255,255,.8);
  font-size: .82rem; font-weight: 600; margin: 0 0 1rem;
}
.ranking-hero__largada-status {
  color: var(--yellow); font-weight: 800; text-transform: uppercase;
  font-size: .68rem; letter-spacing: .03em;
}

/* Hero de 1a tela no mobile, pedido do usuário 2026-09-17: "precisa ficar
   fácil ... já aparecer tudo na primeira tela do celular e ela não
   precisar rolar a página pra ver o mapa". No desktop não muda nada (tem
   espaço de sobra, rolar não é problema) -- só entra em cena na media
   query abaixo. A altura real (.ranking-hero, via JS em ranking-page.js)
   é medida a partir de onde o hero realmente começa na tela, então
   funciona com qualquer altura de header/ticker acima dele. */
@media (max-width: 600px) {
  .ranking-page { padding-top: 1rem; }
  .ranking-page__titulo {
    font-size: .92rem; margin: 0 0 .5rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .02em;
  }
  .ranking-hero__largada { font-size: .76rem; margin: 0 0 .7rem; }

  /* Compacto no mobile -- pedido do usuário 2026-09-18: mesmo com
     countdown/engajamento/abas somados acima do mapa, ainda precisa caber
     na 1ª tela (a medição de altura em ranking-page.js já se adapta
     sozinha ao que sobra, mas dá uma força reduzindo o que dá pra
     reduzir sem perder legibilidade). */
  .ranking-countdown { gap: .4rem; margin-bottom: .7rem; }
  .ranking-countdown > div { padding: .3rem .45rem; min-width: 38px; }
  .ranking-countdown span { font-size: .92rem; }
  .ranking-engajamento { font-size: .7rem; gap: .5rem; margin-bottom: .7rem; }
  .ranking-tabs { margin-bottom: .7rem; }
  .ranking-tabs__botao { padding: .5rem .5rem; font-size: .7rem; }

  /* Pedido do usuário 2026-09-18 (2ª rodada): "os icones tem que ficar na
     horizontal e com swap" -- volta pro comportamento original (rolagem
     horizontal, regra base sem media query) pro seletor de modalidade;
     a tentativa de quebrar em 2 linhas foi revertida. */

  /* Card de 3 colunas (3ª rodada) mais compacto no mobile -- gaps/padding
     menores, mesma estrutura (nunca menos de 3 colunas, só encolhe). */
  .ranking-estimativa__info { gap: .4rem; padding: .55rem; }
  .ranking-estimativa__col--modalidade,
  .ranking-estimativa__col--tempo { padding-right: .4rem; }
  .ranking-estimativa__col-modalidade { font-size: .74rem; }
  .ranking-estimativa__col-sub,
  .ranking-estimativa__col-label { font-size: .58rem; }
  .ranking-estimativa__col-cronometro { font-size: .82rem; }
  .ranking-estimativa__col-status-texto { font-size: .6rem; }
  .ranking-estimativa__col--status { padding: .3rem .35rem; }

  .ranking-hero {
    display: flex; flex-direction: column; min-height: 0;
  }
  .ranking-hero > * { flex: 0 0 auto; }
  .ranking-hero .ranking-estimativa {
    flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column;
  }
  .ranking-hero .ranking-estimativa > * { flex: 0 0 auto; }
  /* Achado 2026-09-18: com o novo .ranking-estimativa__mapa-wrap (pro botão
     "seguir o pino"), o mapa deixou de ser filho DIRETO de .ranking-estimativa
     -- essa regra tinha que mudar de alvo (era ".ranking-estimativa__mapa",
     agora é o wrap) e o wrap precisa virar flex ele mesmo pro mapa de
     dentro esticar até preencher a altura toda, senão o hero volta a
     precisar rolar no mobile (regressão do que já foi resolvido em
     2026-09-17). */
  .ranking-hero .ranking-estimativa__mapa-wrap {
    flex: 1 1 auto; min-height: 120px;
    display: flex; margin-bottom: 0;
  }
  .ranking-hero .ranking-estimativa__mapa-wrap .ranking-estimativa__mapa {
    flex: 1 1 auto; height: auto; min-height: 0;
  }
}
/* .ranking-page__credito* REMOVIDO 2026-09-18 (14ª rodada): "esses 2
   textos podem virar um botão com toast" -- virou par de botões
   discretos (.ranking-disclaimers) chamado nas 3 abas, ver mais abaixo. */

/* Ticker de "como está a pista" MOVIDO pro header (sitewide), pedido do
   usuário 2026-09-16: "precisa estar vinculada ao clima, então pode ser
   no header mesmo, antes da logo" -- ver rmg_weather_ticker_sabado_html()
   em inc/weather.php. Não duplica mais aqui dentro da página. */

/* Estimativa ao vivo (pace mediano real + marcador no mapa), pedido do
   usuário 2026-09-16: "quero ver como vai ficar o ao vivo simulado com o
   pace por modalidade". Nunca mostra "quem está na frente" -- só posição
   estimada do pelotão como um todo, sempre com aviso de que é estimativa. */
.ranking-estimativa {
  background: #141414; border: 1px solid rgba(255,204,0,.25);
  border-radius: var(--radius-md); padding: 1rem 1.1rem 1.2rem;
  margin-bottom: 1.5rem;
}
.ranking-estimativa__titulo {
  display: block; color: var(--yellow); font-size: .68rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: .8rem;
}
/* Reescrito 2026-09-18 (3ª rodada) -- pedido do usuário: "vamos fazer um
   card com a modalidade embaixo início de prova e horário, ao lado
   coloca o tempo de prova embaixo o cronômetro rolando e do lado um card
   que preencha esse espaço rolando agora, pode ser em 3 colunas".
   3 colunas dentro do mesmo card externo: col 1 (modalidade+início) e
   col 2 (tempo de prova+cronômetro) largura pelo conteúdo, col 3
   (status) flex:1 -- "preenche o espaço" que sobra, e vira um card
   PRÓPRIO (fundo/borda coloridos pelo estado) de propósito: usuário já
   avisou que quer empilhar mais informação em cima dela depois (ex.:
   "% dos atletas completaram a prova"). */
.ranking-estimativa__info {
  display: flex; align-items: stretch; gap: .6rem;
  padding: .7rem; margin-bottom: .8rem; border-radius: var(--radius-sm);
  background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.06);
}
/* 6ª vez que esse exato bug aparece nesta sessão -- "display:flex" acima é
   author stylesheet e vence o "[hidden]{display:none}" nativo. Só virou
   bug de verdade agora (2026-09-20) que esta barra passou a ser escondida
   de propósito (ver atualizarInfoBar() em ranking-page.js) -- antes
   sempre ficava visível, então nunca tinha aparecido. */
.ranking-estimativa__info[hidden] { display: none; }
.ranking-estimativa__col {
  display: flex; flex-direction: column; justify-content: center; gap: .15rem;
}
/* 5ª vez que esse exato bug aparece nesta sessão (dashboard, carrossel de
   patrocinadores, cartão de compartilhar, botão seguir-no-mapa, agora
   esta coluna) -- ".ranking-estimativa__col{display:flex}" acima é author
   stylesheet e vence o "[hidden]{display:none}" nativo do navegador (que
   é só UA stylesheet), então a coluna "Tempo de prova" continuava visível
   mesmo com o atributo hidden presente no estado "antes"/"terminado".
   Seletor específico o bastante pra vencer de volta. */
.ranking-estimativa__col[hidden] { display: none; }
.ranking-estimativa__col--modalidade,
.ranking-estimativa__col--tempo {
  flex-shrink: 0; padding-right: .6rem; border-right: 1px solid rgba(255,255,255,.08);
}
.ranking-estimativa__col-modalidade {
  font-size: .82rem; font-weight: 800; color: #fff; white-space: nowrap;
}
.ranking-estimativa__col-sub,
.ranking-estimativa__col-label {
  font-size: .62rem; color: rgba(255,255,255,.45); white-space: nowrap;
}
.ranking-estimativa__col-sub b {
  font-variant-numeric: tabular-nums; font-weight: 800;
  color: rgba(255,255,255,.8); margin-left: .15rem;
}
/* Tempo de prova (cronômetro), pedido do usuário 2026-09-17: "só precisa
   colocar o tempo de prova do lado" -- tempo decorrido desde a largada da
   modalidade selecionada, alimentado pelo cronômetro genérico já usado no
   site (assets/js/ranking-page.js, procura por `[data-cronometro-largada]`).
   Toda a coluna some junto (não só o valor) nos estados "antes"/
   "terminado" -- ver [data-info-tempo] em ranking-page.js. */
.ranking-estimativa__col-cronometro {
  font-variant-numeric: tabular-nums; font-weight: 800; font-size: .95rem;
  color: var(--yellow);
}
/* Coluna 3 (status) -- "preenche o espaço" que sobra, card próprio com
   cor de fundo/borda por estado (mesma paleta que o badge já usava). */
.ranking-estimativa__col--status {
  flex: 1 1 auto; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); padding: .4rem .5rem; min-width: 0;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.08);
}
.ranking-estimativa__col-status-texto {
  font-size: .68rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .03em; text-align: center; color: rgba(255,255,255,.5);
}
.ranking-estimativa__col-status--rolando { background: rgba(255,204,0,.14); border-color: rgba(255,204,0,.4); }
.ranking-estimativa__col-status--rolando .ranking-estimativa__col-status-texto { color: var(--yellow); }
.ranking-estimativa__col-status--sem_dado { background: rgba(51,153,255,.14); border-color: rgba(51,153,255,.35); }
.ranking-estimativa__col-status--sem_dado .ranking-estimativa__col-status-texto { color: #6cb6ff; }
.ranking-estimativa__col-status--antes,
.ranking-estimativa__col-status--terminado { background: rgba(255,255,255,.04); }
/* 1º colocado real confirmado (rank_prova=1 da Polesportivo) -- pedido do
   usuário 2026-09-19, mesma linguagem visual de "dado real" (dourado) já
   usada em rolando/anel--real, pra destacar que não é mais estimativa. */
.ranking-estimativa__col-status--primeiro_chegou { background: rgba(255,204,0,.14); border-color: rgba(255,204,0,.4); }
.ranking-estimativa__col-status--primeiro_chegou .ranking-estimativa__col-status-texto { color: var(--yellow); }
/* Texto de cautela do clima -- migrou pra fora deste card (2026-09-18, 3ª
   rodada), agora fica em cima do botão compartilhar (ver .ranking-engajamento
   em ranking-page.css mais abaixo), "nesse mesmo tamanho" (pedido do
   usuário) -- mesma regra, só o container mudou. */
.ranking-estimativa__cautela {
  font-size: .68rem; color: rgba(255,255,255,.5); line-height: 1.35;
  margin: 0 0 .6rem;
}

/* Seletor de modalidade em ícones redondos, pedido do usuário 2026-09-16:
   "quero as modalidades todas em ícones redondos em cima do mapa, qdo
   clica muda pro mapa da modalidade". Rolagem lateral no mobile (9 ícones
   não cabem numa linha só em tela pequena). */
.ranking-estimativa__seletor {
  display: flex; gap: .6rem; overflow-x: auto; padding-bottom: .3rem;
  margin-bottom: .8rem; scrollbar-width: none;
}
.ranking-estimativa__seletor::-webkit-scrollbar { display: none; }
/* Botão inteiro (ícone + nome da modalidade) -- pedido do usuário
   2026-09-17: "precisa colocar em cada ícone a modalidade da prova", o
   nome só existia como title/aria-label (invisível na tela) antes disso. */
.ranking-estimativa__item {
  flex-shrink: 0; width: 60px; background: none; border: none; padding: 0;
  cursor: pointer; color: rgba(255,255,255,.55);
  display: flex; flex-direction: column; align-items: center; gap: .3rem;
}
/* Wrap novo (pedido do usuário 2026-09-18, 6ª rodada: "os icones redondos
   ter servir tipo um relogio com borda preenchendo conforme for
   prosseguindo a prova") -- só existe pra dar position:relative pro anel
   SVG se sobrepor exatamente ao círculo do ícone, do mesmo tamanho. */
.ranking-estimativa__icone-wrap {
  position: relative; width: 42px; height: 42px;
  display: flex; align-items: center; justify-content: center;
}
.ranking-estimativa__icone {
  width: 42px; height: 42px; border-radius: 50%;
  background: rgba(255,255,255,.06); border: 2px solid transparent;
  display: flex; align-items: center; justify-content: center;
  transition: border-color .15s, color .15s, background .15s;
  position: relative; z-index: 1; /* fica por cima do anel */
}
.ranking-estimativa__icone svg { width: 20px; height: 20px; }
.ranking-estimativa__label {
  font-size: .6rem; font-weight: 700; line-height: 1.15; text-align: center;
  color: inherit; white-space: nowrap;
}
.ranking-estimativa__item[data-modalidade-estado="rolando"] { color: var(--yellow); }
.ranking-estimativa__item.is-ativo { color: var(--yellow); }
.ranking-estimativa__item.is-ativo .ranking-estimativa__icone {
  border-color: var(--yellow); background: rgba(255,204,0,.12);
}
/* Anel de progresso -- pedido do usuário 2026-09-18 (6ª rodada). SVG
   sobreposto ao ícone (mesmo tamanho), girado -90deg pra o progresso
   começar às 12h (convenção comum de progress ring) em vez de às 3h
   (0deg é o padrão do SVG). stroke-dasharray/dashoffset calculados 1x no
   PHP (valor inicial) e recalculados ao vivo em ranking-page.js a cada
   tique -- mesma fórmula (circunferência = 2*pi*raio), raio 19 fixo. */
.ranking-estimativa__anel {
  position: absolute; top: 0; left: 0; right: 0; bottom: 0;
  width: 100%; height: 100%; transform: rotate(-90deg);
}
.ranking-estimativa__anel-fundo {
  fill: none; stroke: rgba(255,255,255,.1); stroke-width: 2.5;
}
.ranking-estimativa__anel-progresso {
  fill: none; stroke-width: 2.5; stroke-linecap: round;
  transition: stroke-dashoffset .6s ease, stroke .3s ease;
}
/* Cinza (ainda não largou / sem dado) -- fica praticamente invisível de
   propósito, só o fundo aparece (fracao=0 já deixa o traço "vazio"). */
.ranking-estimativa__anel--cinza .ranking-estimativa__anel-progresso { stroke: rgba(255,255,255,.25); }
/* Azul = pace ASSUMIDO (mesma cor já usada no badge/mapa pra "estimativa,
   ainda sem dado real confirmado desta prova"). */
.ranking-estimativa__anel--assumida .ranking-estimativa__anel-progresso { stroke: #3399ff; }
/* Amarelo = pace REAL confirmado, ou "terminado" (dentro do buffer, ainda
   não reordenado) -- mesma cor de destaque do site inteiro. */
.ranking-estimativa__anel--real .ranking-estimativa__anel-progresso { stroke: var(--yellow); }
/* "encerrada" (amarelo apagado + opacity:.55 no ícone) REMOVIDO -- achado
   real 2026-09-19: o usuário reparou o e-MTB "apagado" na tela e achou
   estranho -- fazia sentido quando essa modalidade reordenava pro fim da
   fila (removido no mesmo dia, ver rmg_ranking_page_render()), sem isso
   só parecia ícone quebrado. "terminado" usa a mesma cor cheia de "real"
   agora (ver .ranking-estimativa__anel--real acima), sem discretização
   nenhuma -- o badge "Prova encerrada" já avisa que acabou. */

/* Mapa real (Leaflet + satélite Esri), pedido do usuário 2026-09-16:
   "quero q mostre o mapa igual o mapa q está online mostrando o lugar via
   satelite" -- mesmo estilo visual do mapa interativo grande do site,
   numa instância própria e independente (ver comentário em
   assets/js/ranking-page.js sobre não mexer no mapa singleton existente). */
/* Wrap novo (pedido do usuário 2026-09-18, botão "seguir o pino") -- só
   existe pra dar position:relative pro botão flutuar no canto do mapa; o
   próprio .ranking-estimativa__mapa mantém toda a aparência (borda,
   raio, fundo) que já tinha, só o margin-bottom migrou pra cá. */
.ranking-estimativa__mapa-wrap {
  position: relative; margin-bottom: .8rem;
}
.ranking-estimativa__mapa {
  width: 100%; height: 280px; border-radius: var(--radius-sm);
  border: 1px solid rgba(255,255,255,.08);
  background: #0d0d0d;
}
.ranking-estimativa__mapa .leaflet-control-attribution {
  background: rgba(0,0,0,.6); color: rgba(255,255,255,.5); font-size: .58rem;
}
.ranking-estimativa__mapa .leaflet-control-attribution a { color: rgba(255,255,255,.7); }

/* Botão "seguir o pino" -- flutua no canto superior direito do mapa,
   mesmo z-index acima dos tiles do Leaflet (que usam z-index próprio). */
.ranking-estimativa__seguir {
  position: absolute; top: .6rem; right: .6rem; z-index: 500;
  display: flex; align-items: center; gap: .35rem;
  background: rgba(13,13,13,.85); border: 1px solid rgba(255,255,255,.15);
  border-radius: 999px; padding: .4rem .7rem; color: #fff;
  font-size: .68rem; font-weight: 700; cursor: pointer;
  backdrop-filter: blur(2px);
}
.ranking-estimativa__seguir svg { width: 15px; height: 15px; flex-shrink: 0; }
.ranking-estimativa__seguir[aria-pressed="true"] {
  background: var(--yellow); border-color: var(--yellow); color: #0d0d0d;
}

/* Legenda das 2 pernas (Duathlon) -- pedido do usuário 2026-09-19: "pode
   ser 1 de uma cor e o outro de outra cor talvez com uma legenda um
   indicativo q um é mtb e o outro trail". Flutua no canto inferior
   esquerdo do mapa, mesmo estilo translúcido do botão "seguir". */
.ranking-estimativa__legenda {
  position: absolute; left: .6rem; bottom: .6rem; z-index: 500;
  display: flex; gap: .7rem;
  background: rgba(13,13,13,.85); border: 1px solid rgba(255,255,255,.15);
  border-radius: var(--radius-sm); padding: .4rem .6rem;
  backdrop-filter: blur(2px);
}
.ranking-estimativa__legenda-item {
  display: flex; align-items: center; gap: .3rem;
  color: #fff; font-size: .66rem; font-weight: 700;
}
.ranking-estimativa__legenda-cor {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
}
/* Vencedores M/F -- pedido do usuário 2026-09-20: "colocar quem chegou
   primeiro na aba como foi tanto masculino como feminino e os detalhes
   de tempo, pace e nas modalidades de bike o km/h". 2 cards lado a lado,
   cada um sozinho pode ficar escondido se só 1 dos 2 sexos já tem
   vencedor confirmado (ver atualizarInfoBar() em ranking-page.js). */
.ranking-estimativa__vencedores {
  /* Mesmo lugar/espaçamento que ".ranking-estimativa__info" ocupava --
     pedido do usuário 2026-09-20 (2ª rodada): "lá em cima nao embaixo do
     mapa", as 2 barras se revezam no mesmo espaço (ver JS). */
  display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; margin-bottom: .8rem;
}
.ranking-estimativa__vencedores[hidden] { display: none; }
.ranking-estimativa__vencedor {
  display: flex; flex-direction: column; gap: .15rem; min-width: 0;
  background: rgba(255,204,0,.08); border: 1px solid rgba(255,204,0,.25);
  border-radius: var(--radius-sm); padding: .6rem .7rem;
}
.ranking-estimativa__vencedor[hidden] { display: none; }
.ranking-estimativa__vencedor-badge {
  font-size: .62rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .03em; color: var(--yellow); opacity: .85;
}
.ranking-estimativa__vencedor-nome {
  font-weight: 800; font-size: .88rem; color: #fff; margin-top: .1rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ranking-estimativa__vencedor-stats {
  /* sem white-space:nowrap de propósito -- achado real 2026-09-20: o pace
     combinado do Duathlon ("9'00"/km · 29,8 km/h") é mais longo que os
     outros e estourava a largura do card; deixa quebrar linha em vez de
     cortar o texto. */
  font-size: .72rem; color: rgba(255,255,255,.6); font-variant-numeric: tabular-nums;
}
.ranking-estimativa__vencedor-sep { color: rgba(255,255,255,.3); margin: 0 .3em; }
/* 4ª vez que esse exato bug aparece nesta sessão (dashboard/mxpress,
   carrossel de patrocinadores, cartão de compartilhar do ranking) --
   dessa vez a origem NEM é um arquivo do tema: é o próprio CSS core do
   WordPress (wp-includes/css/dist/block-library/style.min.css) que
   carrega "svg{display:block}" em toda página de tema de bloco. Author
   stylesheet sempre vence UA stylesheet independente de especificidade,
   então o "[hidden]{display:none}" nativo do navegador perde pro
   "svg{display:block}" do core -- confirmado via getComputedStyle
   (mostrava "block" com o atributo hidden presente). Corrigido com um
   seletor específico o bastante pra vencer os dois ícones ligar/desligar. */
.ranking-estimativa__seguir svg[hidden] { display: none; }

/* Mapa full-width no mobile, pedido do usuário 2026-09-17: "o mapa precisa
   ficar full width na tela do celular ... pra ficar mais fácil pra quem
   quer acompanhar". O card "Estimativa ao vivo" inteiro estoura até a
   borda da tela (cancela o padding de .ranking-page + a própria borda do
   card) -- os elementos de texto/ícones dentro dele ganham de volta o
   respiro lateral via margem própria, só o mapa (e o fundo do card)
   realmente encostam na borda. A ALTURA do mapa não é mais fixa aqui --
   pedido do usuário 2026-09-17 (rodada seguinte): o hero inteiro (H1 +
   cautela + ícones + mapa) precisa caber numa tela só sem rolar, então o
   mapa vira flex:1 dentro de .ranking-hero/.ranking-estimativa (ver bloco
   ".ranking-hero" mais abaixo) e a altura real é medida por JS
   (ranking-page.js), não chutada em vh. */
@media (max-width: 600px) {
  .ranking-estimativa {
    margin-left: -1rem; margin-right: -1rem; padding-left: 0; padding-right: 0;
    border-left: none; border-right: none; border-radius: 0;
  }
  .ranking-estimativa__info,
  .ranking-estimativa__seletor {
    margin-left: 1.1rem; margin-right: 1.1rem;
  }
  .ranking-estimativa__mapa {
    border-left: none; border-right: none; border-radius: 0;
  }
  .ranking-estimativa__mapa-wrap { margin-bottom: 0; }
}

/* Hero full-width no desktop, pedido do usuário 2026-09-18: "no desktop
   assuma o hero inteiro full width" -- hoje o hero (H1 + card "Estimativa
   ao vivo") fica preso no mesmo max-width:720px do resto do texto da
   página (.ranking-page), sobrando bastante espaço vazio nas laterais em
   telas largas (ver screenshot que o usuário mandou).
   .ranking-hero é FILHO de .ranking-page -- um filho em fluxo normal não
   consegue ficar mais largo que o container do pai só ganhando max-width
   maior, ele continua limitado pela caixa de conteúdo de .ranking-page
   (720px). Por isso a técnica aqui é a inversa da usada no mobile acima
   (que cancela o PADDING do pai): larga o PRÓPRIO .ranking-page (o
   container vira 1600px) e "reencolhe" de volta pra 720px centralizado
   só as seções que devem continuar com leitura confortável (aviso,
   textos de clima/estimativa, busca, progresso, crédito) -- o que sobra
   sem reencolher (.ranking-hero) fica naturalmente esticado até a nova
   largura do container. Capado em 1600px pra não esticar um mapa curto e
   larguíssimo em monitor ultra-wide -- continua "full width" em qualquer
   tela até ~1600px, que é a grande maioria dos desktops. */
@media (min-width: 900px) {
  .ranking-page { max-width: 1600px; }

  /* Prefixo ".ranking-page " sobe a especificidade (2 classes em vez de
     1) de propósito: .ranking-estimativa__aviso, por exemplo, tem uma
     regra MAIS ABAIXO no arquivo (linha ~308) com "margin: 0" -- sem o
     prefixo, essa regra posterior vencia o "margin-left/right: auto"
     daqui (mesma especificidade, ordem do arquivo decide), e o texto
     ficava colado na esquerda em vez de centralizado/estreito. */
  .ranking-page .ranking-hero__cautela,
  .ranking-page .ranking-page__aviso,
  .ranking-page .ranking-busca,
  .ranking-page .ranking-disclaimers,
  .ranking-page .ranking-proximo-evento,
  .ranking-page .ranking-countdown,
  .ranking-page .ranking-tabs,
  .ranking-page .ranking-video {
    max-width: 720px; margin-left: auto; margin-right: auto;
  }
  /* .ranking-engajamento saiu dessa lista (2026-09-18, 4ª rodada) -- agora
     tem os patrocínios dentro (9 logos, precisam de full-width pra não
     vazar da caixa branca -- achado real: 720px cortava Jeep/Melhoramentos
     pra fora do card). Só o botão compartilhar (align-self:center, ver
     regra própria) fica centralizado dentro do espaço full-width. */

  .ranking-page__titulo { font-size: 1.9rem; margin-bottom: 2rem; }
  .ranking-estimativa { padding: 1.6rem 2rem 2rem; }
  .ranking-estimativa__mapa { height: 480px; }
  /* Pedido do usuário 2026-09-18: "os icones no desktop serem estarem
     espalhados no espaço horizontal por igual" -- antes ficavam todos
     colados à esquerda (largura do conteúdo bem menor que a largura real
     do hero full-width em desktop, sobrava vazio enorme à direita).
     space-between distribui os 9 ícones pela largura toda do card. */
  .ranking-estimativa__seletor { gap: 0; justify-content: space-between; }
  .ranking-estimativa__item { width: 74px; }
  .ranking-estimativa__icone-wrap { width: 52px; height: 52px; }
  .ranking-estimativa__icone { width: 52px; height: 52px; }
  .ranking-estimativa__icone svg { width: 24px; height: 24px; }
  .ranking-estimativa__label { font-size: .68rem; }
  /* Mesmo pedido de 2026-09-18 ("icones no desktop espalhados no espaço
     horizontal"), agora pro seletor de modalidade do Ranking -- pedido
     do usuário 2026-09-19: "no desk preenche o esapco dos icones". */
  /* Achado real 2026-09-19: diferente do seletor da aba "Ao vivo" (9
     modalidades, cabe em 74px cada dentro do card de 720px com folga),
     esse aqui tem 10 (+ "Todas") -- 74px cada excedia os 720px do card
     (.ranking-busca), quase sem sobrar espaço nenhum pro space-between
     "espalhar" (achava do usuário: "no desk preenche o esapco dos
     icones"). Mantém o tamanho compacto de sempre (sem aumentar), só
     espalha os 10 pela largura toda. */
  .ranking-page__modalidades { justify-content: space-between; }
  .ranking-estimativa__info { padding: 1rem 1.2rem; gap: 1.2rem; }
  .ranking-estimativa__col-modalidade { font-size: 1rem; }
  .ranking-estimativa__col-sub,
  .ranking-estimativa__col-label { font-size: .7rem; }
  .ranking-estimativa__col-cronometro { font-size: 1.15rem; }
  .ranking-estimativa__col-status-texto { font-size: .78rem; }
  .ranking-estimativa__col--modalidade,
  .ranking-estimativa__col--tempo { padding-right: 1.2rem; }
}

/* Destaque azul da largada até o km 1, pedido do usuário 2026-09-17: "dar
   destaque pra faixa de 1km, tipo colocar uma cor azul dessa faixa da
   largada até o km 1 e se der pra piscar suavemente melhor ainda" -- só
   aparece no estado "sem_dado" (já largou, ainda sem gente suficiente
   terminando pra estimar o ritmo), como um substituto visual honesto pra
   "onde os atletas devem estar" antes de existir dado real de pace. */
.ranking-estimativa__linha-largada {
  animation: ranking-estimativa-largada-pisca 2.4s ease-in-out infinite;
}
@keyframes ranking-estimativa-largada-pisca {
  0%, 100% { stroke-opacity: .9; }
  50% { stroke-opacity: .3; }
}
@media (prefers-reduced-motion: reduce) {
  .ranking-estimativa__linha-largada { animation: none; }
}

/* Marcadores de km ao longo da rota, pedido do usuário 2026-09-17: "dá pra
   dar zoom por km?" -- referência fixa pra dar sentido ao zoom (sem isso o
   zoom in não mostra pra que km da prova aquele trecho corresponde). */
.ranking-estimativa__km-label {
  background: rgba(13,13,13,.85); color: #fff; font-size: .62rem; font-weight: 800;
  padding: 1px 5px; border-radius: 3px; border: 1px solid rgba(255,204,0,.5);
  white-space: nowrap;
}

/* Marcador pulsando na posição estimada, mesma técnica de halo crescendo
   já usada em outros pontos do site (ex.: cronograma "rolando agora"). */
.ranking-estimativa__pulso-wrap { display: flex; align-items: center; justify-content: center; }
.ranking-estimativa__pulso {
  display: block; width: 10px; height: 10px; border-radius: 50%;
  background: rgba(255,204,0,.6); /* cor real vem inline por JS, cor do km em andamento */
  animation: ranking-estimativa-pulso 1.8s ease-out infinite;
}
@keyframes ranking-estimativa-pulso {
  0% { transform: scale(1); opacity: .7; }
  100% { transform: scale(3.2); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ranking-estimativa__pulso { animation: none; }
}

/* Pino com o ícone da modalidade (pedido do usuário 2026-09-18) -- badge
   circular com o mesmo SVG do seletor acima, em vez de uma bolinha lisa.
   Fundo = cor do km em andamento (inline via JS, mesma paleta PALETA_KM),
   borda branca pra destacar contra o satélite. */
.ranking-estimativa__pino-wrap { display: flex; align-items: center; justify-content: center; }
.ranking-estimativa__pino {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  border: 2.5px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.5);
  color: #0d0d0d;
}
.ranking-estimativa__pino svg { width: 17px; height: 17px; }

/* .ranking-estimativa__aviso REMOVIDO 2026-09-18 (14ª rodada), mesmo
   motivo acima -- virou botão dentro de .ranking-disclaimers. */

/* Progresso de resultados por modalidade (cruza inscritos reais do Sympla
   com resultados reais da Polesportivo) -- REMOVIDO 2026-09-18 (13ª
   rodada): "se tem isso ainda no codigo pode tirar" -- número exato de
   quem já chegou por modalidade trocado por um percentual geral (ver
   .ranking-page__aviso dentro da aba Ranking, inc/ranking-page.php),
   achado do usuário: número exato demais dá margem pra reclamação de
   atleta ("por que o fulano X apareceu e eu não"), percentual é mais
   neutro. */

/* Mapa da rota reaproveitado do item "Altimetria, Mapa da Rota e GPX"
   (inc/ranking-page.php, rmg_ranking_mapa_html) -- o .rota-gallery/.rota-card
   em si já vem estilizado (assets/css/rota-interativa.css), só o título e o
   espaçamento em volta são daqui. */
.ranking-mapa { margin-bottom: 1.5rem; }
.ranking-mapa__titulo {
  display: block; color: var(--yellow); font-size: .68rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: .8rem;
}
.ranking-mapa p { font-size: .82rem; color: rgba(255,255,255,.7); margin: 0 0 .8rem; }

/* Caixa em volta da busca -- pedido do usuário 2026-09-16: "o form do
   ranking solto não ficou legal, parece sem sentido nenhum" -- mesma
   linguagem visual das outras seções (cronograma/mapa/condição), pra
   parecer parte da página em vez de um formulário perdido. */
.ranking-busca {
  background: #141414; border: 1px solid rgba(255,255,255,.08);
  border-radius: var(--radius-md); padding: 1rem 1.1rem 1.2rem;
  margin-bottom: 1.5rem;
}
.ranking-busca__titulo {
  display: block; color: var(--yellow); font-size: .68rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: .8rem;
}

/* Filtro de modalidade com ícones -- pedido do usuário 2026-09-19: "quero
   ter a opçao de a pessoa conseguir ver por modalidade o ranking, tipo
   igual esta o mapa". Mesmo visual/técnica de scroll horizontal do
   seletor da aba "Ao vivo" (.ranking-estimativa__seletor). */
.ranking-page__modalidades {
  display: flex; gap: .6rem; overflow-x: auto; padding-bottom: .3rem;
  margin-bottom: 1rem; scrollbar-width: none;
}
.ranking-page__modalidades::-webkit-scrollbar { display: none; }
.ranking-page__modalidade-btn {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center;
  gap: .3rem; background: none; border: none; cursor: pointer;
  color: rgba(255,255,255,.5); padding: .2rem;
}
.ranking-page__modalidade-icone {
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid rgba(255,255,255,.15); color: inherit;
}
.ranking-page__modalidade-icone svg { width: 18px; height: 18px; }
.ranking-page__modalidade-label {
  font-size: .62rem; font-weight: 700; white-space: nowrap;
}
.ranking-page__modalidade-btn.is-ativo {
  color: var(--yellow);
}
.ranking-page__modalidade-btn.is-ativo .ranking-page__modalidade-icone {
  border-color: var(--yellow); background: rgba(255,204,0,.12);
}

/* Filtro de gênero -- pedido do usuário 2026-09-19: "um botao separando
   masculino e feminino". Pílulas simples (não ícone redondo como o de
   modalidade -- só 3 opções, não precisa do mesmo peso visual). */
.ranking-page__generos {
  display: flex; gap: .5rem; margin-bottom: 1rem; flex-wrap: wrap;
}
.ranking-page__genero-btn {
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.15);
  border-radius: 999px; padding: .45rem 1rem; color: rgba(255,255,255,.6);
  font-family: inherit; font-size: .74rem; font-weight: 700; cursor: pointer;
}
.ranking-page__genero-btn.is-ativo {
  background: rgba(255,204,0,.12); border-color: var(--yellow); color: var(--yellow);
}

.ranking-page__filtros {
  display: flex; gap: .6rem; margin-bottom: 1.2rem; flex-wrap: wrap;
}
.ranking-page__input {
  flex: 1 1 200px; padding: .85rem 1rem; border-radius: var(--radius-md);
  background: #161616; border: 1px solid rgba(255,255,255,.15);
  color: var(--white); font-size: 1rem; font-family: inherit;
}
.ranking-page__input:focus { outline: none; border-color: var(--yellow); }

.ranking-page__dica {
  text-align: center; color: rgba(255,255,255,.5); font-size: .85rem;
  padding: 1.5rem 0;
}

/* Reforma 2026-09-19: "ajusta isso tudo numa linha bem layoutada, ta bem
   ruim do jeito q tá no mobile e tb no desk [...] coloca o pace tb".
   Antes era 1 CSS Grid de 7 colunas com um override de mobile jogando
   tudo numa coluna empilhada (6-7 linhas por competidor -- lista gigante
   virava parede de texto, e já tinha rendido 2 bugs de auto-placement
   nesta sessão). Agora é flexbox puro, 2 linhas fixas, MESMA estrutura
   em qualquer largura -- só padding/fonte mudam por breakpoint, sem
   recriar aquele bug. Linha 1 ("topo"): o que mais importa pra achar a
   pessoa (ícone + nome + tempo). Linha 2 ("meta"): o resto, texto menor
   (posição, gênero, número, modalidade, pace). */
.ranking-page__item {
  display: flex; flex-direction: column; gap: .3rem; cursor: pointer;
  padding: .7rem .6rem; border-bottom: 1px solid rgba(255,255,255,.08);
  transition: background .15s;
}
.ranking-page__item:hover, .ranking-page__item:focus-visible {
  background: rgba(255,204,0,.06); outline: none;
}
.ranking-page__item-topo {
  display: flex; align-items: center; gap: .5rem;
}
.ranking-page__item-icone {
  flex: 0 0 auto; width: 20px; height: 20px; color: rgba(255,255,255,.4);
  display: flex; align-items: center; justify-content: center;
}
.ranking-page__item-icone svg { width: 16px; height: 16px; }
.ranking-page__item-nome {
  flex: 1 1 auto; min-width: 0; font-weight: 700; font-size: .92rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ranking-page__item-tempo {
  flex: 0 0 auto; font-variant-numeric: tabular-nums; font-weight: 700;
  font-size: .92rem; white-space: nowrap;
}
/* 2ª reforma 2026-09-19: "não curti muito o layout, esse ux ainda ta um
   pouco confuso" -- a linha "meta" tinha 5 informações soltas com o
   mesmo peso visual (posição+categoria, gênero, número, modalidade,
   pace), difícil escanear rápido. A posição GERAL virou um badge (ver
   .ranking-page__item-badge) ao lado do nome, na linha de cima -- é o
   número mais importante pra achar alguém numa lista de ranking. O
   resto virou 2 grupos com espaçamento maior ENTRE eles (gap do flex),
   separando "quem é" (categoria/gênero/número) de "como foi"
   (modalidade/pace) -- só "·" DENTRO de cada grupo, não em tudo. */
.ranking-page__item-badge {
  flex: 0 0 auto; background: rgba(255,204,0,.15); color: var(--yellow);
  font-weight: 800; font-size: .74rem; line-height: 1.3;
  padding: .05rem .4rem; border-radius: 4px; white-space: nowrap;
}
.ranking-page__item-meta {
  display: flex; align-items: baseline; flex-wrap: wrap;
  column-gap: .9rem; row-gap: .15rem; padding-left: 1.7rem; /* alinha com o nome, embaixo do ícone */
  font-size: .72rem; color: rgba(255,255,255,.5);
}
.ranking-page__item-meta-grupo { display: flex; align-items: baseline; gap: .35rem; }
.ranking-page__item-sep { color: rgba(255,255,255,.25); }
.ranking-page__item-cat { color: rgba(255,204,0,.75); font-weight: 700; }
.ranking-page__item-genero { font-weight: 800; }
.ranking-page__item-genero--m { color: #6cb6ff; }
.ranking-page__item-genero--f { color: #ff8fc9; }
.ranking-page__item-numero { font-weight: 700; white-space: nowrap; }
.ranking-page__item-prova { white-space: nowrap; }
/* Pace/velocidade -- pedido do usuário 2026-09-19: "é pra tratar pace
   para trilha e km/h para os esportes de bike, mtb, gravel, emtb" --
   essa diferenciação já era calculada certa no PHP desde 2026-09-16
   (rmg_ranking_calcular_ritmo(), a unidade "/km" ou "km/h" já vem
   embutida em r.pace); a cor própria aqui é só pra esse valor ficar
   fácil de notar em vez de se misturar ao resto do texto cinza. */
.ranking-page__item-pace {
  font-variant-numeric: tabular-nums; font-weight: 700; white-space: nowrap;
  color: #8fd6bd;
}

@media (min-width: 900px) {
  /* Desktop: mais respiro, fonte um pouco maior -- mesma estrutura de 2
     linhas do mobile (pedido do usuário: "tb no desk"), só não precisa
     ficar tão compacto quanto a tela pequena. */
  .ranking-page__item { padding: .85rem .8rem; gap: .35rem; }
  .ranking-page__item-nome, .ranking-page__item-tempo { font-size: 1rem; }
  .ranking-page__item-badge { font-size: .8rem; }
  .ranking-page__item-meta { font-size: .78rem; }
}

/* "Carregar mais" -- pedido do usuário 2026-09-19: "listar 10 nomes e o
   botao carregar mais" (paginação client-side, ver ranking-page.js). */
.ranking-page__carregar-mais {
  display: block; width: 100%; margin-top: .8rem; padding: .75rem;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.12);
  border-radius: var(--radius-sm); color: rgba(255,255,255,.8);
  font-family: inherit; font-size: .8rem; font-weight: 700; cursor: pointer;
}
.ranking-page__carregar-mais:hover { background: rgba(255,204,0,.1); border-color: var(--yellow); color: var(--yellow); }
.ranking-page__carregar-mais[hidden] { display: none; }

/* Cartão pra print/compartilhar, pedido do usuário 2026-09-16: "dar um
   print e compartilhar no story". Overlay simples, sem lib nenhuma.
   O próprio atleta tira o print da tela com o cartão aberto. */
.ranking-card-overlay {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(0,0,0,.85);
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem;
}
/* Achado 2026-09-16 (mesmo padrão já visto no carrossel de patrocinadores
   e no painel mxpress-ga4-dashboard): "display: flex" acima tem a MESMA
   especificidade do [hidden]{display:none} nativo do navegador, e como
   vem depois no cascade, vencia, o cartão nunca ficava escondido de
   verdade (aparecia vazio direto ao carregar a página, e o botão de
   fechar "não funcionava" porque o CSS forçava mostrar de novo mesmo
   com o JS marcando hidden=true corretamente). */
.ranking-card-overlay[hidden] { display: none; }
.ranking-card {
  position: relative; width: 100%; max-width: 360px;
  background: linear-gradient(160deg, #161616, #0a0a0a);
  border: 1px solid rgba(255,204,0,.35); border-radius: var(--radius-lg);
  padding: 2rem 1.5rem 1.6rem; text-align: center;
  font-family: 'Montserrat', sans-serif; color: var(--white);
}
.ranking-card__fechar {
  position: absolute; top: .6rem; right: .6rem;
  width: 32px; height: 32px; border-radius: 50%; border: none;
  background: rgba(255,255,255,.08); color: var(--white); font-size: 1.2rem;
  cursor: pointer;
}
.ranking-card__logo {
  display: block; color: var(--yellow); font-size: .68rem; font-weight: 800;
  letter-spacing: .06em;
}
.ranking-card__etapa {
  display: block; color: rgba(255,255,255,.5); font-size: .7rem; margin-bottom: 1.2rem;
}
.ranking-card__nome { font-size: 1.3rem; font-weight: 800; margin: 0 0 .2rem; }
.ranking-card__prova {
  display: block; color: rgba(255,255,255,.6); font-size: .8rem;
  text-transform: uppercase; letter-spacing: .03em; margin-bottom: 1rem;
}

/* Mini-mapa animado do percurso real, pedido do usuário 2026-09-16: "uma
   animação do percurso que ela fez". Só o traçado (sem satélite/tiles),
   fica leve e limpo o bastante pra print/story -- assets/js/ranking-page.js
   desenha o SVG a partir do mesmo GeoJSON do mapa interativo grande. */
.ranking-card__mapa {
  background: #0d0d0d; border: 1px solid rgba(255,255,255,.08);
  border-radius: var(--radius-sm); margin-bottom: 1.2rem;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.ranking-card__mapa[hidden] { display: none; }
.ranking-card__mapa-svg { width: 100%; height: auto; display: block; }
.ranking-card__mapa-retry {
  background: none; border: none; color: rgba(255,255,255,.5);
  font-size: .78rem; font-family: inherit; text-decoration: underline;
  cursor: pointer; padding: 1.5rem 1rem;
}
.ranking-card__mapa-linha {
  stroke: var(--yellow); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
}
.ranking-card__mapa-linha.is-animando {
  transition: stroke-dashoffset 1.8s ease-out;
}
.ranking-card__mapa-ponto { stroke: #0d0d0d; stroke-width: 2; }
.ranking-card__mapa-ponto--largada { fill: #ffffff; }
.ranking-card__mapa-ponto--chegada { fill: var(--yellow); }
/* Legenda das 2 pernas (Duathlon) -- pedido do usuário 2026-09-19: "pode
   colocar separado por cor mtb e trail". Fica dentro do próprio
   .ranking-card__mapa, abaixo do SVG (container já é flex-column ao
   receber essa div extra). */
.ranking-card__mapa-legenda {
  display: flex; gap: .8rem; padding: 0 0 .6rem;
}
.ranking-card__mapa-legenda-item {
  display: flex; align-items: center; gap: .3rem;
  color: rgba(255,255,255,.65); font-size: .68rem; font-weight: 700;
}
.ranking-card__mapa-legenda-cor {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
}

.ranking-card__grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem;
  padding: 1rem 0; border-top: 1px solid rgba(255,255,255,.1);
  border-bottom: 1px solid rgba(255,255,255,.1); margin-bottom: 1.2rem;
}
.ranking-card__valor {
  display: block; color: var(--yellow); font-weight: 800; font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
}
.ranking-card__label {
  display: block; color: rgba(255,255,255,.45); font-size: .62rem;
  text-transform: uppercase; letter-spacing: .03em; margin-top: 2px;
}
/* Gap pro vizinho de categoria (à frente/atrás) -- pedido do usuário
   2026-09-19: "o quanto a pessoa ficou atras e na frente do atleta em
   relação a posição dela na prova". Fica entre o grid de stats e o
   botão de compartilhar, tom neutro (não é destaque tipo pace/posição,
   é um detalhe a mais). */
.ranking-card__gap {
  display: flex; flex-direction: column; gap: .25rem;
  margin: -.4rem 0 1rem; text-align: center;
}
.ranking-card__gap[hidden] { display: none; }
.ranking-card__gap-linha { font-size: .78rem; color: rgba(255,255,255,.6); }
.ranking-card__dica { color: rgba(255,255,255,.55); font-size: .78rem; margin: 0; }
.ranking-card__compartilhar { width: 100%; margin-bottom: .6rem; }
.ranking-card__compartilhar:disabled { opacity: .6; cursor: default; }

/* "Quero ir pra Campos do Jordão" -- pedido do usuário 2026-09-18 (16ª
   rodada): "quero pensar em algo para a pessoa se cadastrar... algo q
   engaje ela pra querer ir para campos do jordão 14/11". Card discreto,
   fora das abas (ver inc/ranking-page.php) -- fica visível o tempo todo,
   inclusive durante a janela "aguarde" antes de tudo mais liberar. */
.ranking-proximo-evento {
  margin: 2rem 0 0; padding: 1.3rem 1.1rem; text-align: center;
  background: #141414; border: 1px solid rgba(255,204,0,.25);
  border-radius: var(--radius-md);
}
.ranking-proximo-evento__tag {
  display: inline-block; color: var(--yellow); font-size: .66rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .06em; margin-bottom: .4rem;
}
.ranking-proximo-evento__titulo {
  color: var(--white); font-size: 1.05rem; font-weight: 800; margin: 0 0 .5rem;
}
.ranking-proximo-evento__texto {
  color: rgba(255,255,255,.6); font-size: .8rem; line-height: 1.45;
  margin: 0 0 1rem; max-width: 420px; margin-left: auto; margin-right: auto;
}
.ranking-proximo-evento__botao {
  width: 100%; max-width: 320px; justify-content: center;
}
.ranking-proximo-evento__botao.is-confirmado {
  background: rgba(255,255,255,.08); color: rgba(255,255,255,.7);
  box-shadow: none; cursor: default;
}
.ranking-proximo-evento__botao:disabled { opacity: 1; } /* não esmaece -- "confirmado" precisa continuar legível */
.ranking-proximo-evento__contador {
  color: rgba(255,255,255,.5); font-size: .76rem; margin: .9rem 0 0;
  font-variant-numeric: tabular-nums;
}
.ranking-proximo-evento__contador b { color: var(--yellow); font-weight: 800; }
