/* Hub "Mesa Virtual": uma tela só, sem rolagem, pensada para desktop.
   Estética de interface de jogo retrô: fundo escuro pontilhado, scanlines por cima de tudo,
   molduras retas com sombra dura, tipografia angulosa.
   Abertura: marca grande no centro; ao clicar, ela encolhe para o canto e os cards sobem.
   Nome nenhum: a arte já diz qual é a mesa. Gente online e "Entrar" só no hover. */

@font-face { font-family: "Chakra Petch"; src: url("fontes/chakra-petch-500.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Chakra Petch"; src: url("fontes/chakra-petch-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Chakra Petch"; src: url("fontes/chakra-petch-700-italic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }
@font-face { font-family: "JetBrains Mono"; src: url("fontes/jetbrains-mono-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }

:root {
  --preto: #070709;
  --painel: #0f0f12;
  --borda: #2c303b;
  --branco: #f2f2f2;
  --cinza: #8b90a0;
  --azul: #2222ff;
  --vermelho: #f0122d;
  --no-ar: #2fe37a;
  --fluido: cubic-bezier(.22, 1, .36, 1);     /* desacelera suave no fim */
  --abertura: cubic-bezier(.76, 0, .18, 1);   /* arranca e freia: a marca indo para o canto */
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  position: relative;
  margin: 0;
  display: grid;
  grid-template-rows: 84px 1fr;
  overflow: hidden;
  background: var(--preto);
  color: var(--branco);
  font-family: "Chakra Petch", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
}

a { color: inherit; text-decoration: none; }

/* ---------- fundo ---------- */
.fundos, .fundo { position: absolute; inset: 0; }
.fundos {
  z-index: -1;
  overflow: hidden;
  background: radial-gradient(70% 60% at 50% 45%, #14142a, var(--preto) 75%);
}
/* fundo padrão: malha de pontos azulados que desliza devagar. A malha é uma camada maior que a
   tela e anda por transform (um passo da malha por volta, que emenda sem aparecer): animar a
   posição do fundo redesenhava a tela inteira a cada quadro e fazia as outras animações engasgarem */
.fundos::before {
  content: "";
  position: absolute;
  inset: -52px;
  background: radial-gradient(circle, rgba(70, 80, 255, .42) 0 1.2px, transparent 1.7px) 0 0 / 26px 26px;
  animation: deslizar 6s linear infinite;
  will-change: transform;
}
/* arte da mesa sob o mouse, em pixels grandes e bem escura */
.fundo {
  inset: -3%;
  /* ampliado e puxado para baixo: mostra a cena da arte, não o letreiro do título */
  background: 50% 88% / 150% auto no-repeat;
  image-rendering: pixelated;
  filter: brightness(.3) saturate(.9) contrast(1.05);
  opacity: 0;
  transform: scale(1.04);
  transition: opacity .7s var(--fluido), transform 1.4s var(--fluido);
}
.fundo.ativo { opacity: 1; transform: none; }
.fundos::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(85% 80% at 50% 48%, transparent 25%, rgba(7, 7, 9, .88) 100%);
}

/* scanlines de monitor antigo por cima da página inteira, inclusive das artes */
body::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 20;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .17) 0 1px, transparent 1px 3px);
  pointer-events: none;
}

/* ---------- topo ---------- */
.topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: 36px;
}
.marca {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 0;
  font-size: 22px;
  font-style: italic;
  line-height: 1;
  letter-spacing: -.01em;
  text-transform: uppercase;
  white-space: nowrap;
  user-select: none;   /* o clique triplo no d20 não deve selecionar o texto */
  text-shadow: 2px 2px 0 var(--azul);
  transform-origin: center;
  transition: transform 1s var(--abertura);
}
.marca-dado {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: var(--branco);
  stroke-width: 7;
  stroke-linejoin: miter;
  filter: drop-shadow(2px 2px 0 var(--azul));
  transition: transform 1s var(--abertura);
}

/* botão do mestre: fica fora da página até o clique triplo no d20 */
.mestre {
  padding: 7px 14px;
  border: 1px solid var(--borda);
  background: var(--painel);
  box-shadow: 2px 2px 0 #000;
  color: var(--cinza);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  transition: background .2s, color .2s, border-color .2s;
  animation: surgir .35s var(--fluido);
}
.mestre[hidden] { display: none; }
.mestre:hover,
.mestre:focus-visible { background: var(--branco); border-color: var(--branco); color: var(--preto); outline: none; }

/* ---------- cards ---------- */
.mesas {
  /* largura do card: limitada pela largura e também pela altura da janela,
     para duas linhas de cards sempre caberem sem rolagem */
  --w: min(27vw, 390px, (100dvh - 250px) * 8 / 9);
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  align-items: center;
  justify-content: center;
  gap: 32px;
  width: 100%;
  max-width: calc(3 * var(--w) + 2 * 32px + 72px);   /* cinco ou mais: três por linha */
  margin-inline: auto;
  padding: 0 36px 84px;   /* a base maior compensa o topo e centraliza os cards na tela */
}
/* o tamanho do card acompanha a quantidade de mesas */
.mesas[data-n="1"] { --w: min(44vw, 640px, (100dvh - 200px) * 16 / 9); max-width: none; }
.mesas[data-n="2"] { --w: min(36vw, 520px, (100dvh - 200px) * 16 / 9); max-width: none; }
.mesas[data-n="3"] { --w: min(28vw, 410px, (100dvh - 200px) * 16 / 9); max-width: none; }
.mesas[data-n="4"] { --w: min(32vw, 450px, (100dvh - 250px) * 8 / 9); max-width: calc(2 * var(--w) + 32px + 72px); }   /* 2 x 2 */

/* O card tem duas camadas. ".mesa" é a área do mouse e NUNCA sai do lugar depois da abertura;
   ".quadro", dentro dela, é o que se vê e se mexe (levanta no hover, afunda no clique). Se a
   própria área do mouse andasse, com o cursor na beirada o card fugia dele, perdia o hover,
   voltava, e ficava tremendo. */
.mesa {
  position: relative;
  flex: 0 0 var(--w);
  transition:
    transform .9s var(--fluido) calc(.45s + var(--i, 0) * 90ms),
    opacity .7s var(--fluido) calc(.45s + var(--i, 0) * 90ms);
}
/* largura que dá à arte uma altura em pixels inteiros (múltiplo de 16 por 9) */
@supports (width: round(down, 10px, 16px)) {
  .mesa { flex-basis: calc(round(down, var(--w) - 12px, 16px) + 12px); }
}
/* depois da abertura: o card que volta de apagado espera um instante, para não piscar quando o
   mouse só atravessa o vão entre dois cards */
.pronto .mesa { transition: opacity .35s var(--fluido) .09s; }

/* moldura: painel escuro em volta da arte, com sombra dura deslocada */
.quadro {
  padding: 5px;
  border: 1px solid var(--borda);
  background: var(--painel);
  box-shadow: 5px 5px 0 #000;
  transition:
    transform .32s var(--fluido),
    box-shadow .32s var(--fluido),
    border-color .2s;
}

.arte {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: #000;
}
/* A arte fica sempre um pouco maior que a moldura e sempre numa camada própria (will-change).
   Com a tela do Windows em 125% ou 150%, uma arte do tamanho exato da moldura deixava uma fresta
   na borda, e a camada criada só durante a animação fazia a imagem dar um salto no fim dela. */
.arte img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.02);
  transition: transform .8s var(--fluido);
  will-change: transform;
}

/* hover: a moldura fica branca e o card se descola da sombra; os outros recuam */
a.mesa:hover,
a.mesa:focus-visible { outline: none; z-index: 2; }
a.mesa:hover .quadro,
a.mesa:focus-visible .quadro {
  transform: translate(-4px, -4px);
  border-color: var(--branco);
  box-shadow: 9px 9px 0 var(--branco);
}
/* a arte cresce e acompanha o mouse dentro da moldura, no sentido contrário, como uma cena vista
   por uma janela (--mx e --my vão de -1 a 1 e vêm do hub.js) */
a.mesa:hover .arte img,
a.mesa:focus-visible .arte img {
  transform: scale(1.08) translate(calc(var(--mx, 0) * -2.4%), calc(var(--my, 0) * -2.4%));
  transition-duration: .5s;
}
.mesas:has(a.mesa:hover) .mesa:not(:hover),
.mesas:has(a.mesa:focus-visible) .mesa:not(:focus-visible) { opacity: .4; transition-delay: 0s; }
/* clique: o card afunda na sombra, como um botão. Ele fica assim até a página trocar: o hub.js
   congela o card no estado em que estiver na hora do clique (ver partir) */
a.mesa[href]:active .quadro {
  transform: translate(2px, 2px);
  box-shadow: 3px 3px 0 var(--branco);
  transition-duration: .08s;
}
.quadro.negado { animation: negar .3s var(--fluido); }

/* faixa da base: só aparece no hover. Passa 2px da moldura nos lados e embaixo (o que sobra é
   cortado) para a arte nunca aparecer numa fresta por baixo dela, e tem camada própria pelo
   mesmo motivo da arte. */
.legenda {
  position: absolute;
  inset: auto -2px -2px -2px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px 10px 14px;
  background: rgba(7, 7, 9, .9);
  transform: translateY(101%);
  transition: transform .36s var(--fluido);
  will-change: transform;
}
.mesa:hover .legenda,
.mesa:focus-visible .legenda { transform: none; }

.online {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--cinza);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.online::before {
  content: "";
  width: 7px;
  height: 7px;
  background: var(--cinza);
}
[data-estado="online"] .online { color: var(--branco); }
[data-estado="online"] .online::before { background: var(--no-ar); animation: pulsar 1.6s ease-in-out infinite; }

.entrar {
  padding: 4px 11px 3px;
  background: var(--branco);
  color: var(--preto);
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* fora do ar: arte apagada, quadradinho vermelho, sem "Entrar", sem clique */
[data-estado="offline"] { cursor: default; }
[data-estado="offline"] .arte img { filter: grayscale(1) brightness(.35); }
[data-estado="offline"] .entrar { display: none; }
[data-estado="offline"] .online { color: var(--branco); }
[data-estado="offline"] .online::before { background: var(--vermelho); }

.sem-js { color: var(--branco); text-decoration: underline; }

/* só aparece se o mesas.js estiver com erro de digitação (ver hub.js) */
.aviso {
  margin: 0;
  color: var(--vermelho);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 13px;
  font-weight: 400;
}

/* ---------- abertura ---------- */
/* o botão cobre a tela inteira: qualquer clique começa. O texto fica abaixo da marca. */
.comecar {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  padding: 190px 0 0;
  border: 0;
  background: none;
  color: var(--cinza);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 13px;
  letter-spacing: .28em;
  text-transform: uppercase;
  cursor: pointer;
  animation: respirar 2.2s ease-in-out infinite;
  transition: opacity .35s var(--fluido);
}
.comecar:focus-visible { outline: none; color: var(--branco); }
.comecar[hidden] { display: none; }

/* a marca nasce grande no centro (--dx/--dy são medidos pelo hub.js);
   até a medida e a fonte estarem prontas, ela fica invisível para não aparecer fora do lugar */
.abertura .marca { transform: translate(var(--dx, 0), var(--dy, 0)) scale(3.6); }
.abertura:not(.medido) .marca { visibility: hidden; }
.abertura .marca-dado { transform: rotate(-60deg); }
.abertura .mesa {
  opacity: 0;
  transform: translateY(70px);
  pointer-events: none;
}
.saindo .comecar { opacity: 0; animation: none; pointer-events: none; }

/* ---------- passagem para a mesa ---------- */
/* o hub inteiro escurece até a cor do login da mesa clicada (--destino, que o hub.js lê do mesas.js)
   enquanto as peças do login voam por cima. Fica acima das scanlines: o login não tem scanlines. */
.passagem {
  position: absolute;
  inset: 0;
  z-index: 30;
  background: var(--destino, var(--preto));
  opacity: 0;
  pointer-events: none;
}
.partindo .passagem {
  opacity: 1;
  transition: opacity .3s ease-in;
}

/* palco: as peças da tela de login, montadas no lugar onde vão estar depois da troca de página.
   O hub.js as anima a partir da posição delas dentro do card (ver voar).
   Só existe para mesa com "login" no mesas.js; cada uma tem o seu bloco .palco-<endereco> abaixo. */
.palco {
  position: absolute;
  inset: 0;
  z-index: 31;
  overflow: hidden;
  pointer-events: none;
}
.palco > * {
  position: absolute;
  transform-origin: 0 0;
  background-repeat: no-repeat;
  will-change: transform;
}
/* /coc — espelha a cena e o título de temas/coc/login.css: mudou lá, mudar aqui */
.palco-coc {
  --arte: min(26.31vw, calc(100vh - 370px));
  --titulo-l: min(820px, 74vw);
  --titulo-a: calc(var(--titulo-l) * .1906);
}
.palco-coc .palco-cena {
  inset: 0 0 auto 0;
  height: var(--arte);
  background-size: cover;
  background-position: center top;
  -webkit-mask-image: linear-gradient(#000 66%, rgba(0, 0, 0, .55) 85%, transparent 100%);
          mask-image: linear-gradient(#000 66%, rgba(0, 0, 0, .55) 85%, transparent 100%);
}
.palco-coc .palco-titulo {
  top: calc(var(--arte) - var(--titulo-a) * .5);
  left: calc(50% - var(--titulo-l) / 2);
  width: var(--titulo-l);
  height: var(--titulo-a);
  background-size: contain;
  background-position: center;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .6));
}

/* só mexe na posição: se a animação não rodar, o botão continua visível */
@keyframes surgir {
  from { transform: translateX(14px); }
}
@keyframes deslizar {
  to { transform: translate(26px, 52px); }
}
/* card fora do ar clicado: balança de lado, como quem diz não (soma com a posição do hover) */
@keyframes negar {
  25% { translate: -6px 0; }
  50% { translate: 5px 0; }
  75% { translate: -3px 0; }
}
@keyframes pulsar {
  50% { opacity: .3; }
}
@keyframes respirar {
  50% { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}
