@charset "UTF-8";
/* ============================================================================
   mv-visual.css — camada de acabamento visual do Matemática Viva
   ----------------------------------------------------------------------------
   Como usar: inclua DEPOIS do style.css, como a última folha do <head>.

       <link rel="stylesheet" href="assets/style.css">
       <link rel="stylesheet" href="assets/mv-visual.css">

   Não renomeia nenhuma classe, não pede mudança no PHP e não remove nada:
   só corrige e reforça o que já existe. Para desligar, é só tirar a linha.

   Cada bloco começa com o problema que ele resolve.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   0. Base
   Os controles nativos (select, scrollbar, autofill) estavam sendo desenhados
   no tema claro do sistema por cima de um site escuro.
   ------------------------------------------------------------------------ */
:root{
  color-scheme: dark;
  --foco: #ffc65c;                 /* anel de foco de teclado */
  --raio: 14px;
}

/* Respeita quem pediu menos movimento no sistema operacional.
   Hoje .btn-xl e .drop-play pulsam infinitamente sem essa guarda. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;
    animation-iteration-count:1!important;
    transition-duration:.001ms!important;
    scroll-behavior:auto!important;
  }
}

/* ---------------------------------------------------------------------------
   1. Foco de teclado
   Só input e select tinham anel de foco. Botões, respostas, abas do ranking e
   links do menu não tinham nenhum — quem navega por teclado ficava perdido.
   ------------------------------------------------------------------------ */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
.answer:focus-visible,
.rank-tabs a:focus-visible,
.trail-dot:focus-visible,
.alg-math-key:focus-visible,
summary:focus-visible{
  outline:3px solid var(--foco);
  outline-offset:3px;
  border-radius:10px;
}

/* ---------------------------------------------------------------------------
   2. Botões
   .btn não tinha :hover, :active nem :focus — clicar não dava retorno nenhum.
   ------------------------------------------------------------------------ */
.btn{
  transition:transform .12s ease, filter .16s ease, box-shadow .16s ease;
  -webkit-tap-highlight-color:transparent;
}
@media (hover:hover){
  .btn:hover{ filter:brightness(1.08); transform:translateY(-1px) }
}
.btn:active{ transform:translateY(1px) scale(.995); filter:brightness(.96) }
.btn[disabled],.btn[aria-disabled="true"]{
  filter:grayscale(.5) brightness(.75); cursor:not-allowed; transform:none;
}
.ghost{ transition:background .16s ease, border-color .16s ease }
@media (hover:hover){
  .ghost:hover{ background:#ffffff12; border-color:#ffffff45 }
}

/* O halo do CTA principal: o keyframe pulseCTA alterna laranja e azul e, na
   virada, os dois anéis se somam e criam aquele contorno pardo em volta do
   botão. Trocado por um pulso só, na cor da marca, mais discreto. */
@keyframes mvPulse{
  0%   { box-shadow:0 0 0 0 rgba(255,122,26,.42) }
  70%  { box-shadow:0 0 0 14px rgba(255,122,26,0) }
  100% { box-shadow:0 0 0 0 rgba(255,122,26,0) }
}
.btn-xl,.drop-play{ animation:mvPulse 2.8s ease-out infinite }
.btn-xl{ letter-spacing:.01em }

/* ---------------------------------------------------------------------------
   3. Menu no celular
   `@media(max-width:900px){.menu a:not(.btn){display:none}}` escondia Jogos,
   Ranking, Entrar e Minha conta — abaixo de 900px sobrava só o botão laranja e
   não havia como navegar. Aqui eles voltam, como uma linha que quebra.
   ------------------------------------------------------------------------ */
@media (max-width:900px){
  .menu{ gap:10px 14px; justify-content:flex-end }
  .menu a:not(.btn){
    display:inline-flex; align-items:center;
    min-height:40px; padding:6px 4px; font-weight:800;
  }
}
@media (max-width:560px){
  nav{ gap:10px }
  .menu{ width:100%; justify-content:center }
  .menu a:not(.btn){ font-size:.95rem }
}

/* Contraste e estado do menu. Os links ficavam na mesma cor do texto comum,
   sem indicar em que página você está. */
.menu a:not(.btn){ color:#cfdcf0; transition:color .15s ease }
@media (hover:hover){ .menu a:not(.btn):hover{ color:var(--text) } }
.menu a[aria-current],
.menu a.active{
  color:var(--text);
  box-shadow:inset 0 -2px 0 0 var(--fire);
}

/* ---------------------------------------------------------------------------
   4. Setas fantasma entre os passos
   .step-card:not(:last-child)::after posiciona uma seta "→" em right:-24px,
   pensada para os três passos lado a lado da home. Nas páginas de jogo os
   passos ficam empilhados em largura cheia, e a seta sobra flutuando na
   margem direita, apontando para o vazio.

   A container query resolve sem tocar no PHP: cartão estreito significa
   layout em colunas (seta faz sentido); cartão largo significa empilhado
   (seta sai, e entra um fio ligando os números).
   ------------------------------------------------------------------------ */
.steps > .step-card{ container-type:inline-size; position:relative }

/* Um cartão largo só existe quando os passos estão empilhados: nesse caso a
   seta horizontal sai. Regras dentro de @container valem para o conteúdo do
   cartão (inclusive ::before e ::after), nunca para o próprio cartão — um
   elemento não pode se re-estilizar pela container query que ele mesmo cria. */
@container (min-width:560px){
  .step-card:not(:last-child)::after{ content:none }

  /* Fio vertical ligando um passo ao próximo, no lugar da seta. Fica fora do
     alcance da media query de 800px, onde o CSS atual já troca a seta por "↓"
     centralizado — assim os dois nunca aparecem juntos. */
  .step-card:not(:last-child)::before{
    content:"";
    position:absolute;
    left:36px; top:100%;
    width:2px; height:24px;
    background:linear-gradient(#ff7a1a66,#ff7a1a00);
  }

  /* O texto ia até a borda de uma linha de largura cheia. Uma medida de
     leitura confortável encurta a linha sem mexer no layout. */
  .step-card > *{ max-width:74ch }
}
@media (max-width:800px){
  /* abaixo daqui o CSS atual já usa a seta "↓" embaixo; o fio sairia sobrando */
  .step-card:not(:last-child)::before{ content:none }
}

/* ---------------------------------------------------------------------------
   5. Painéis e cartões
   O painel e o fundo da página estavam quase na mesma cor: o cartão não
   descolava. Um pouco mais de contraste na borda e uma luz no topo resolvem
   sem mudar a paleta.
   ------------------------------------------------------------------------ */
.panel,.card{
  border-color:#ffffff26;
  box-shadow:0 1px 0 0 #ffffff12 inset, 0 18px 45px #00000059;
}
/* O efeito de levantar no hover não faz sentido em tela de toque, onde o
   "hover" fica grudado depois do toque. */
@media (hover:none){
  .card:hover{ transform:none }
}
/* O primeiro card do pódio sobe 10px; no hover .card:hover o puxava para -4px,
   ou seja, ele descia ao passar o mouse. */
.podium .card:first-child:hover{ transform:translateY(-14px) }

/* ---------------------------------------------------------------------------
   6. Respostas do quiz
   .answer:nth-child(odd) pinta a borda de laranja e (even) de azul. A cor não
   quer dizer nada — é alternância decorativa — e isso disputa atenção com o
   verde e o vermelho, que são os únicos que precisam significar algo.
   Bordas neutras; a cor volta a ser exclusiva do acerto e do erro.
   ------------------------------------------------------------------------ */
.answers .answer:nth-child(odd),
.answers .answer:nth-child(even){ border-color:#ffffff2e }

.answer{
  min-height:64px;
  transition:background .14s ease, border-color .14s ease, transform .1s ease;
}
@media (hover:hover){
  .answer:hover{ background:#ffffff1c; border-color:#ffffff55; transform:translateY(-2px) }
}
.answer:active{ transform:translateY(0) scale(.99) }

/* Acerto e erro com mais presença, sem depender só da cor — quem não
   distingue verde de vermelho continua lendo o estado pela borda e pelo
   relevo. */
.answer.correct{
  background:#188a43!important;
  border:2px solid var(--green2)!important;
  box-shadow:0 0 0 4px #7fe35d2e, 0 10px 26px #04351566;
}
.answer.wrong{
  background:#a72d44!important;
  border:2px solid #ff9db0!important;
  box-shadow:0 0 0 4px #ff6f832e;
}
@media (prefers-reduced-motion:no-preference){
  .answer.correct{ animation:mvAcerto .34s ease-out }
  .answer.wrong{ animation:mvErro .3s ease-out }
}
@keyframes mvAcerto{ 0%{transform:scale(1)} 45%{transform:scale(1.045)} 100%{transform:scale(1)} }
@keyframes mvErro{ 0%,100%{transform:translateX(0)} 25%{transform:translateX(-6px)} 60%{transform:translateX(4px)} }

.feedback{ font-size:1.15rem; letter-spacing:.01em }

/* No celular as respostas ficavam em duas colunas estreitas; uma coluna com
   alvo de toque cheio erra menos. */
@media (max-width:520px){
  .answers{ grid-template-columns:1fr }
  .answer{ min-height:60px }
}

/* ---------------------------------------------------------------------------
   7. Mapa de fases
   .phase-card.locked usava opacity:.45, que derruba o contraste do texto
   abaixo do mínimo legível. Estado travado passa a ser dito pela cor e por um
   cadeado, mantendo o texto legível.
   ------------------------------------------------------------------------ */
.phase-card.locked{
  opacity:1;
  background:#ffffff05;
  border-color:#ffffff1a;
  color:#8fa0bb;
}
.phase-card.locked .phase-badge{ opacity:.8 }
.phase-card.done{ box-shadow:0 0 0 1px #35d48733 }
.phase-card.current{ box-shadow:0 0 0 3px #ff7a1a26, 0 12px 30px #00000047 }

/* ---------------------------------------------------------------------------
   8. Trilha
   Os pontos tinham 22px — abaixo do mínimo confortável para o dedo.
   ------------------------------------------------------------------------ */
@media (pointer:coarse){
  .trail-dot{ width:30px; height:30px; min-width:30px; font-size:14px }
  .trail-dot.current{ width:40px; height:40px; min-width:40px; font-size:19px }
}

/* ---------------------------------------------------------------------------
   9. Título com gradiente
   .accent interpola do azul ao laranja passando por cinza: no meio da frase
   as palavras perdem cor e contraste. Interpolar em oklab mantém a saturação
   ao longo de todo o texto. A primeira declaração é o que navegador antigo lê.
   ------------------------------------------------------------------------ */
.accent{
  background-image:linear-gradient(92deg,var(--water),var(--fire));
  background-image:linear-gradient(92deg in oklab,var(--water) 8%,var(--fire) 92%);
}

/* ---------------------------------------------------------------------------
   10. Detalhes de leitura
   ------------------------------------------------------------------------ */
h1,h2,h3{ text-wrap:balance }
.card p,.step-card p,.muted{ max-width:74ch }
.hero p.muted{ margin-left:auto; margin-right:auto }

/* Números em coluna param de dançar (ranking, KPIs, placares). */
.pts,.kpi strong,.rank-row span,td,.race-hud span{ font-variant-numeric:tabular-nums }

/* O campo de código da sala cortava o texto do placeholder em 150px. */
.code-entry input{ width:min(190px,42vw) }

/* Imagens nunca estouram a largura da coluna. */
img{ max-width:100%; height:auto }

/* Tabelas largas rolam dentro da própria caixa, não na página inteira. */
.scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch }

/* ---------------------------------------------------------------------------
   11. Menu lateral (partial_nav.php)
   ------------------------------------------------------------------------
   Antes cada página tinha seu próprio <header> escrito à mão, cada uma com
   um subconjunto diferente de links — o Quiz, por exemplo, não aparecia em
   quase nenhuma tela. Agora todo mundo usa partial_nav.php, com a lista
   completa num painel deslizante (funciona em qualquer largura de tela,
   diferente do menu antigo que sumia inteiro abaixo de 900px).
   ------------------------------------------------------------------------ */
.nav-toggle{ font-size:.92rem; padding:11px 16px }

.nav-overlay{
  position:fixed; inset:0; background:#00051566; backdrop-filter:blur(2px);
  opacity:0; visibility:hidden; transition:opacity .2s ease; z-index:39;
}
.nav-overlay.open{ opacity:1; visibility:visible }

.nav-sidebar{
  position:fixed; top:0; right:0; height:100%; width:min(340px,86vw);
  background:linear-gradient(165deg,var(--panel2),#081b3f);
  border-left:1px solid var(--line); box-shadow:-24px 0 60px #00000066;
  z-index:40; padding:18px; overflow-y:auto;
  transform:translateX(100%); transition:transform .28s cubic-bezier(.16,1,.3,1);
}
.nav-sidebar::before{
  content:''; position:absolute; inset:0 auto 0 0; width:3px;
  background:var(--brand); background-size:100% 300%; animation:navGlow 6s ease infinite;
}
@keyframes navGlow{ 0%,100%{ background-position:0 0 } 50%{ background-position:0 100% } }
.nav-sidebar.open{ transform:translateX(0) }
.nav-sidebar-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:20px; padding-bottom:16px; border-bottom:1px solid var(--line); position:relative }
.nav-sidebar-head::after{
  content:''; position:absolute; left:0; right:0; bottom:-1px; height:1px;
  background:linear-gradient(90deg,var(--fire),var(--water),transparent);
}
.nav-sidebar-head .btn{ padding:8px 12px }
.nav-group{ margin-bottom:20px; opacity:0; transform:translateX(10px); animation:navItemIn .35s ease forwards }
.nav-sidebar.open .nav-group{ animation-delay:calc(var(--i,0) * .05s) }
.nav-group:nth-child(2){ --i:1 } .nav-group:nth-child(3){ --i:2 } .nav-group:nth-child(4){ --i:3 }
.nav-group:nth-child(5){ --i:4 } .nav-group:nth-child(6){ --i:5 }
@keyframes navItemIn{ to{ opacity:1; transform:translateX(0) } }
.nav-group h3{
  margin:0 0 10px; font-size:.72rem; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted); display:flex; align-items:center; gap:8px;
}
.nav-group h3::before{
  content:''; width:16px; height:2px; border-radius:2px;
  background:linear-gradient(90deg,var(--fire),var(--water)); flex-shrink:0;
}
.nav-group a{
  display:flex; align-items:center; padding:11px 12px; border-radius:12px; font-weight:800;
  color:var(--text); transition:background .15s ease,transform .15s ease,padding-left .15s ease;
}
.nav-group a:hover{ background:#ffffff14; padding-left:16px }
.nav-group a.active{ background:var(--brand); color:#fff; box-shadow:0 6px 18px #ff7a1a33 }
