/* ==========================================================================
   RODA DE CARDS — prefixo wheel-
   Linha do tempo sobre o aro de uma roda-gigante cujo centro está abaixo da
   dobra. Vê-se só a calota de cima: card do topo em pé, vizinhos descendo
   pelas laterais inclinados como raios.

   Tokens usados:
     --display --sans     ano e rótulo (display), painel de texto (sans)
     --ease               curva única do projeto — troca do painel e hover
     --accent             ano do painel, ponto ativo, fio do card ativo
     --dark-rgb           véus de topo e de base sobre a foto
     --light              texto DENTRO da foto (ilha escura, ver abaixo)
     --fg --fg-2          título e linha do painel, herdados do escopo de tom
     --fg-muted --rule --rule-2   botões, pontos apagados, fundo de carregamento
     --radius-media       canto do card
     --radius-pill        disco dos botões e ponto do indicador
     --sec-gap            respiro vertical da dobra (via .sec-pad)

   A GEOMETRIA MORA AQUI, NÃO NO SCRIPT. O cubo da roda é um PONTO, não um
   elemento: fica em (50%, 100% + --wheel-drop) do palco. Cada card é
   absoluto nesse ponto e vai até o aro pelo próprio transform —
   translate(-50%,-50%) põe o centro do card sobre o cubo, rotate() gira em
   volta dele, translateY(-R) lança para fora. O transform-origin fica no
   padrão (centro do card), e é por isso que a ordem das funções importa:
   o translate tem de vir PRIMEIRO, senão o giro acontece em torno de um
   ponto que ainda não é o cubo.

   Efeito colateral bem-vindo: o card sai inclinado no mesmo ângulo em que
   está no aro — tangente ao arco, de graça. Posicionar os cards no aro por
   left/top exigiria seno e cosseno no JS e ainda pediria um segundo
   transform só para inclinar.

   O que o script escreve é só --wheel-radius e --wheel-step (medidos) e
   --wheel-angle (por quadro). Sem JavaScript o arco continua desenhado,
   com os valores padrão abaixo — os cards não empilham num ponto só.

   O CARD É UMA ILHA ESCURA: ano e rótulo vivem dentro da foto e leem
   --light, não --fg. Assim a mesma roda roda numa seção clara sem virar
   texto escuro sobre véu escuro. O que está fora da foto (painel, botões,
   pontos) continua lendo o escopo de tom da seção.
   ========================================================================== */

.wheel{
  /* ---- os cinco parafusos da forma ---- */

  /* Largura do card. A altura é derivada e não é aspect-ratio de propósito:
     a conta do cubo precisa da altura em px, e aspect-ratio não é legível
     dentro de calc(). Quem quiser outro recorte troca as duas. */
  --wheel-card:clamp(200px,20vw,300px);
  --wheel-card-h:calc(var(--wheel-card) * 4 / 3);

  /* Altura do palco. Não é a altura da roda — é quanto da descida do aro
     aparece. Subir este valor mostra mais dos cards laterais mergulhando. */
  --wheel-h:clamp(380px,52vh,560px);

  /* Quanto o card do topo fica abaixo da borda do palco. Sem isto ele
     encosta em 0 e o anel de foco da lista passa por cima dele. */
  --wheel-rise:16px;

  /* Vão entre um card e o próximo, medido no aro, como FRAÇÃO da largura do
     card (.1 = 10%). Unitless de propósito: o script lê com parseFloat, e um
     clamp() devolveria só o primeiro número. Como fração, escala junto com o
     card e dispensa override por breakpoint. */
  --wheel-gap:.1;

  /* Raio da roda, em px, ESCRITO PELO SCRIPT a cada medida:
       R = max(largura da seção * --wheel-reach, --wheel-radius-min)
     Os dois parafusos abaixo são números puros (px implícito no segundo),
     porque quem os lê é o parseFloat do script. Raio maior = arco mais raso
     e cards mais em pé; raio menor = roda mais fechada e mais inclinação. */
  --wheel-reach:.9;
  --wheel-radius-min:900;
  --wheel-radius:1100px;      /* fallback sem JS */

  /* Passo angular entre dois cards, ESCRITO PELO SCRIPT:
       passo = 2 * asin((cardW + vão) / (2R))
     Não é 360/N. São oito cards e a roda NÃO fecha: eles ocupam um trecho do
     aro (~98° no padrão de desktop) e o encaixe tem começo e fim. Usar 360/N
     com N=8 daria 45° por card e os vizinhos sairiam da tela. */
  --wheel-step:14deg;

  /* Giro atual da roda. O script escreve na .wheel-list; aqui fica só o
     valor de repouso, que é o primeiro card no topo. */
  --wheel-angle:0deg;

  /* Onde fica o cubo, contado a partir do TOPO do palco. A conta é a
     inversa da posição do card do topo: para o centro do primeiro card cair
     em (altura do card / 2 + --wheel-rise), o cubo tem de estar a
     R - H + h/2 + rise abaixo da base do palco. */
  --wheel-drop:calc(var(--wheel-radius) - var(--wheel-h)
                    + var(--wheel-card-h) / 2 + var(--wheel-rise));

  /* Esmaecimento por distância angular. O script escreve --wheel-k em cada
     card (0 no topo, 1 a um passo de distância) já limitado a 1.45 — sem o
     teto, o card a três passos daria opacity negativa e o encolhimento
     comeria metade da caixa. */
  --wheel-shrink:.05;

  /* Altura reservada para o painel. Existe para os pontos não dançarem
     quando o texto troca de duas linhas para uma. Medido no conteúdo mais
     alto do padrão editorial — 176px em 1440 e 177px em 390, com folga para
     as larguras entre os dois. Subir o limite de caracteres pede subir isto. */
  --wheel-panel-h:186px;
}

/* ---------------------------------------------------------------- cabeçalho */
/* Título à esquerda, botões à direita, alinhados pela base. Não usa
   .sec-head do core de propósito: aquele é cabeçalho CENTRADO, e aqui os
   dois lados precisam se olhar de ponta a ponta da coluna. */
.wheel-head{
  display:flex;align-items:flex-end;justify-content:space-between;
  gap:clamp(18px,4vw,48px);
}
.wheel-head-left{min-width:0}

.wheel-nav{display:flex;align-items:center;gap:12px;flex:0 0 auto;padding-bottom:6px}

/* O disco de ícone é a primitiva .btn-disc do core (core/base.css): forma,
   cor, hover e estado desabilitado vêm de lá, e o markup traz as duas
   classes. Esta pasta escrevia as mesmas seis linhas — eram cinco cópias
   idênticas na biblioteca, e o §6 manda promover na terceira.
   A ponta da linha do tempo usa aria-disabled e não o atributo disabled: o
   botão desabilitado de verdade sai da ordem de tabulação no exato momento
   em que está com o foco, e o foco cai no <body> — quem chegou de teclado é
   jogado para fora da dobra. Esta dobra foi a primeira a precisar disso, e a
   variante foi junto para a primitiva, que atende as duas formas. */
/* ---------------------------------------------------------------- palco */
/* Irmão do .wrap, filho direto da seção: já nasce com a largura da página,
   sem margem negativa e sem 100vw (contrato §4). O overflow é o que corta o
   aro, que continua muito além dos dois lados da tela. */
.wheel-stage{
  position:relative;
  height:var(--wheel-h);
  overflow:hidden;
  margin-block-start:clamp(30px,5vh,52px);
}

/* A LISTA É O QUADRO, NÃO O PIVÔ. Cobre o palco inteiro, não gira, e é o
   único ponto focável da dobra. Um pivô que girasse (um "cubo" elemento com
   rotate) levaria o foco junto: o anel sairia inclinado e, no fim da linha
   do tempo, girado quase 100° para fora do recorte. */
.wheel-list{
  position:absolute;inset:0;
  cursor:grab;
  /* O gesto horizontal é nosso; o vertical continua sendo da página. Sem
     isto, arrastar de lado no celular trava a rolagem. */
  touch-action:pan-y;
  /* Arrastar sobre o ano e o rótulo selecionaria os dois. */
  user-select:none;-webkit-user-select:none;
}
.wheel-list.is-dragging{cursor:grabbing}

/* O anel do core desenha 3px PARA FORA, e o palco corta com overflow:hidden.
   Offset negativo joga o anel para dentro — mesma solução do
   midia/carrossel-perfis. Aumentar o padding do palco não resolveria: o
   palco sangra até a borda da página, e o anel cairia sob o overflow-x do
   <body>. */
.wheel-list:focus-visible{outline-offset:-4px}

/* ---------------------------------------------------------------- card */
/* Ancorado no cubo; quem o leva até o aro é o transform. Ver o cabeçalho. */
.wheel-card{
  --wheel-k:0;
  position:absolute;
  left:50%;
  top:calc(100% + var(--wheel-drop));
  width:var(--wheel-card);
  height:var(--wheel-card-h);
  overflow:hidden;
  border-radius:var(--radius-media);
  background:var(--rule);
  transform:
    translate(-50%,-50%)
    rotate(calc(var(--wheel-angle) + var(--wheel-i) * var(--wheel-step)))
    translateY(calc(-1 * var(--wheel-radius)))
    scale(calc(1 - var(--wheel-k) * var(--wheel-shrink)));
  opacity:calc(1 - var(--wheel-k) * .55);
}

/* will-change SÓ ENQUANTO GIRA, e a diferença é visível. Promovido para
   sempre, cada card vira uma textura rasterizada uma vez e depois só
   transformada pelo compositor: parado, o ano e o rótulo ficam com a borda
   levemente mole. Ligado só durante o gesto, o texto volta a ser rasterizado
   na posição final assim que a roda encaixa, e aí o card do topo — que
   encaixa em rotação exatamente zero — sai nítido. */
.wheel-list.is-spinning .wheel-card{will-change:transform}

/* Fio na cor de marca marcando de quem o painel está falando. Sombra interna
   e não border: border entraria na caixa de 3/4 e comeria 2px da foto. */
.wheel-card[aria-current]{
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent) 58%,transparent);
}

.wheel-img{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;
}

/* Véu de topo: gradiente puro, SEM backdrop-filter. São oito cards girando
   ao mesmo tempo, e cada backdrop-filter obriga o compositor a reler o que
   está atrás a cada quadro. O de baixo pode pagar esse preço porque é onde
   mora o texto corrido; o de cima carrega quatro dígitos em corpo grande e
   contraste alto, e gradiente já basta. */
.wheel-top{
  position:absolute;left:0;right:0;top:0;height:40%;
  z-index:1;pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(var(--dark-rgb),.74) 0%,
    rgba(var(--dark-rgb),.30) 54%,
    transparent 100%);
}

.wheel-stamp{
  position:absolute;top:clamp(12px,1.3vw,18px);left:clamp(12px,1.3vw,18px);
  z-index:2;
  font-family:var(--display);font-weight:700;
  font-size:clamp(20px,1.9vw,28px);line-height:1;letter-spacing:-.02em;
  color:var(--light);
}

/* Rótulo DENTRO da foto, ancorado embaixo, sobre gradiente + blur mascarado
   (contrato §6 — texto sobre imagem). A máscara é o que impede a borda dura
   do backdrop-filter em caixa reta. */
.wheel-cap{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:block;
  padding:44px clamp(12px,1.3vw,18px) clamp(12px,1.3vw,18px);
  pointer-events:none;
  background:linear-gradient(to top,
    rgba(var(--dark-rgb),.90) 0%,
    rgba(var(--dark-rgb),.50) 48%,
    transparent 100%);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.9) 44%,transparent 100%);
  -webkit-mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.9) 44%,transparent 100%);
}

.wheel-label{
  display:block;
  font-family:var(--display);font-weight:700;
  font-size:clamp(11px,1vw,13px);line-height:1.2;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--light);
}

/* ---------------------------------------------------------------- painel */
.wheel-foot{
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(18px,2.6vh,26px);
  margin-block-start:clamp(28px,4.5vh,48px);
}

/* min-height reserva o conteúdo mais alto do padrão editorial. Sem ela, uma
   parada de duas linhas seguida de outra de uma faz os pontos subirem e
   descerem a cada troca — e o olho lê isso como defeito, não como conteúdo. */
.wheel-panel{
  max-width:600px;
  min-height:var(--wheel-panel-h);
  text-align:center;
}

/* A animação reinicia por classe, e não por transition, para poder disparar
   sem depender do estado anterior — mesma razão do .ttl do core. Entra com
   blur indo a zero (§5); o repouso fica SEM filter, para não custar quadro. */
.wheel-panel.is-swap{animation:wheelSwap .5s var(--ease)}
@keyframes wheelSwap{
  0%{opacity:.15;filter:blur(10px);transform:translateY(9px)}
  100%{opacity:1;filter:blur(0);transform:none}
}
@media(prefers-reduced-motion:reduce){
  .wheel-panel.is-swap{animation:none}
}

/* O ano é o dado, não o título da dobra — por isso não é a primitiva
   .display-xl do core: aquela é a peça gráfica que enche a coluna e pinta
   --fg. Este é um número em corpo grande, na cor de marca, dentro de um
   painel de 600px. */
.wheel-year{
  font-family:var(--display);font-weight:700;
  font-size:clamp(40px,5.2vw,72px);line-height:1;letter-spacing:-.03em;
  color:var(--accent);
}
.wheel-title{
  font-family:var(--display);font-weight:700;
  font-size:clamp(19px,1.8vw,24px);line-height:1.25;letter-spacing:-.02em;
  color:var(--fg);
  margin-block-start:12px;
}
.wheel-text{
  font-size:clamp(14px,1.15vw,16px);line-height:1.55;
  color:var(--fg-2);
  max-width:56ch;margin-inline:auto;margin-block-start:12px;
}

/* ---------------------------------------------------------------- pontos */
.wheel-dots{display:flex;align-items:center;gap:8px}
.wheel-dot{
  width:6px;height:6px;
  border-radius:var(--radius-pill);
  background:var(--rule-2);
  transition:width .4s var(--ease),background-color .4s var(--ease);
}
.wheel-dot.is-on{width:22px;background:var(--accent)}
@media(prefers-reduced-motion:reduce){
  .wheel-dot{transition:none}
}

/* ---------------------------------------------------------------- toque */
/* Sem ponteiro não existe hover, e o cursor de arrasto não quer dizer nada. */
@media(hover:none){
  .wheel-list{cursor:default}
}

/* ---------------------------------------------------------------- mobile */
@media(max-width:760px){
  .wheel{
    /* Card menor e arco MAIS RASO ao mesmo tempo: --wheel-reach sobe de .9
       para 1.4 porque a largura da tela caiu muito mais que a do card. Com
       .9 num celular o raio ficaria em ~350px, o passo passaria de 40° e os
       vizinhos entrariam quase deitados. */
    --wheel-card:min(58vw,240px);
    /* Palco mais baixo que a proporção do desktop, e não por espaço de tela:
       no celular só o card do topo e duas fatias dos vizinhos aparecem, e os
       vizinhos param de descer aos 373px. Os 440px do desktop deixariam 67px
       de palco vazio embaixo, que o olho lê como buraco entre a roda e o
       painel. */
    --wheel-h:min(54vh,392px);
    --wheel-reach:1.4;
    --wheel-radius-min:420;
  }
  /* Empilha o cabeçalho. Os botões ficam sob o título, e não abaixo do
     painel: movê-los de container entre larguras exigiria dois conjuntos no
     DOM — dois pares de controles anunciados pelo leitor de tela — ou um
     grid que quebraria a conta do .wrap. */
  .wheel-head{flex-direction:column;align-items:flex-start;gap:18px}
  .wheel-nav{padding-bottom:0}
}

@media(max-width:460px){
  .wheel-cap{padding-top:36px}
  .wheel-text{font-size:14px}
}
