/* ============================================================
   Banke — folha de estilo
   Preto duro, vermelho só como ALARME, aresta viva em tudo.
   Verde existe apenas como STATUS (online).
   ============================================================ */
:root {
  /* O CARTAZ VALE NO APP INTEIRO.
     Entrada e cadastro ja viviam no papel claro e o miolo continuava
     preto: a pessoa trocava de mundo ao terminar o cadastro. Agora a
     paleta do cartaz mora aqui na raiz, e as telas que a definiam
     localmente continuam valendo — resolvem para os mesmos valores.
     Os nomes dos tokens nao mudam, entao nenhuma regra precisou ser
     reescrita: quem lia var(--bg) virou claro sozinho. */
  --papel: #f2efe7;
  --tinta: #12100e;

  --bg: var(--papel);
  --surface: #ffffff;
  --surface-2: #ffffff;
  --border: var(--tinta);
  --border-hover: var(--tinta);
  /* Divisória que precisa ser VISTA, não só insinuada. */
  --divisor: var(--tinta);
  /* Mesma cor do --bg em canais separados: véus de leitura precisam
     do triplete, não do hex. */
  --bg-rgb: 242, 239, 231;
  --surface-rgb: 255, 255, 255;

  --text: var(--tinta);
  --text-muted: rgba(18, 16, 14, .80);
  --text-dim: rgba(18, 16, 14, .62);

  /* VERMELHO DE PREENCHIMENTO. Serve pra fundo cheio com texto branco
     em cima: 4,76:1 medido, passa AA. O vermelho puro da referência
     (#ff2b32) daria só 3,7:1 e reprovaria — por isso este é meio tom
     mais fechado. Escuro assim não vira texto sobre fundo escuro:
     pra isso existe o --accent-claro. */
  /* Medido sobre o creme: 5,3:1, passa AA como texto. Os vermelhos
     antigos (#e02128 / #ff2b32) foram calibrados contra PRETO e dao
     2,6:1 sobre papel — reprovariam. */
  --cad-vermelho: #c4161c;
  --accent: var(--cad-vermelho);
  --accent-hover: #a51217;
  --accent-rgb: 196, 22, 28;
  --accent-claro: var(--cad-vermelho);

  --online: #3fbf6a;
  --danger: #ff5c7a;
  /* Âmbar de "match": jogos em comum. É cor de STATUS, como o verde. */
  --match: #f2b04a;
  --warn: #ffb020;

  /* tipografia — display pesadíssimo e colado, corpo neutro, e uma
     serifada itálica como voz editorial (rótulos e apartes). */
  --font-body: 'Inter', system-ui, -apple-system, sans-serif;
  --font-display: 'Archivo Black', 'Inter', system-ui, sans-serif;
  --font-serif: 'Playfair Display', Georgia, serif;
  --font-mao: 'Caveat Brush', 'Playfair Display', cursive;
  --fs-lede: clamp(15px, 1.3vw, 18px);
  --fs-body: 15px;
  --fs-label: 11px;

  /* espaço e forma — canto vivo em tudo. Nada de raio nesta identidade. */
  --r-card: 0px;
  --r-ctrl: 0px;
  --ease: cubic-bezier(.22, .61, .36, 1);
  /* batida seca, sem quique: é a curva do display pesado */
  --duro: cubic-bezier(.9, 0, .1, 1);

  /* movimento do fundo (60-90s: se der pra seguir uma capa, está rápido) */
  --row-1: 66s;
  --row-2: 86s;
  --row-3: 74s;
  --strip: 52s;   /* cadencia aprovada no preview, com 16 capas */
}

* { box-sizing: border-box; }

/* Qualquer regra nossa de display venceria o atributo hidden do HTML. */
[hidden] { display: none !important; }

html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}
#app { min-height: 100%; }

/* Foco de teclado visível em TODO controle */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Ícones de linha */
.ic { display: block; flex-shrink: 0; }
button .ic, .btn .ic { pointer-events: none; }

/* Barras de rolagem discretas */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: #232733; border-radius: 10px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: #2e3341; background-clip: content-box; }

/* ============================================================
   TROCA DE TELA — fade + subida curta
   ============================================================ */
.screen { display: none; }
/* SÓ opacidade aqui. Se a animação tocar em transform, o fill-mode deixa
   um matrix() na tela — e qualquer transform, mesmo identidade, faz
   position:fixed dos filhos ancorar na tela em vez da janela.
   Era isso que jogava a barra lateral e a marca d'água pra fora do campo. */
.screen.active { display: block; animation: screenFade .3s var(--ease) both; }
@keyframes screenFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* O deslize fica no conteúdo interno, onde não cria containing block. */
@keyframes screenIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   ENTRADA (landing)
   ------------------------------------------------------------
   A tela inteira e governada por UMA unidade, --u: o menor entre uma
   fracao da largura e uma da altura. Como a altura entra na conta, a
   composicao encolhe junto e nunca estoura a dobra — o que aparece no
   monitor grande aparece no pequeno igual, so menor. Quase nada aqui
   e medido em px solto, de proposito.
   ============================================================ */
#screen-login {
  /* Medido, nao chutado: a coluna precisa de ~53,5*u + 187 px de
     altura. Com o coeficiente antigo (1,72vh) num monitor de 980px a
     regua ia pra 18 e o conteudo pedia 1150 — nao cabia e a pagina
     rolava. Em 1,4vh a conta fecha de 800px pra cima com folga. */
  --u: clamp(10.5px, min(1.05vw, 1.4vh), 16px);
}
#screen-login.active {
  position: relative; height: 100dvh; overflow: hidden;
  display: flex; flex-direction: column;
  padding: 0 calc(var(--u) * 2) 0 calc(var(--u) * 5.4);
  /* Sem teto de largura: o cartaz ocupa a janela inteira.
     Havia um max-width aqui pra composicao nao esticar em monitor
     largo, mas o efeito colateral era pior que o problema — num 1920
     a tela parava em ~1394px e sobravam ~260px de vazio de cada lado,
     com a cunha preta e a faixa de capas cortadas no meio do nada.
     Quem segura o esticamento agora e o proprio grid la embaixo, que
     limita a coluna de texto; o fundo e os enfeites sangram ate a
     borda, que e o que um cartaz faz. */
  width: 100%;
}
/* Fixed, e nao absolute: com o max-width acima o trilho ancoraria na
   caixa centralizada e desgrudaria da borda da tela. */
#screen-login .login-trilho { position: fixed; }

/* --- trilho lateral: o nome vazado e repetido, do cartao de visita
   da referencia. Puramente decorativo. --- */
.login-trilho {
  position: absolute; top: 0; left: 0; height: 100%; width: calc(var(--u) * 3.5);
  display: flex; flex-direction: column; justify-content: center; gap: 2px;
  border-right: 1px solid var(--border); z-index: 2;
  overflow: hidden; pointer-events: none; user-select: none;
}
.login-trilho span {
  font-family: var(--font-display); font-size: calc(var(--u) * 2);
  line-height: .86; letter-spacing: -.04em; color: transparent;
  /* Cor própria, e não o token de contorno: este traço é o DESENHO
     da letra, não moldura de caixa. */
  -webkit-text-stroke: 1px #2a2a2a;
  writing-mode: vertical-rl; transform: rotate(180deg);
}
/* Uma so em vermelho: e o acento, nao o padrao. */
.login-trilho span:nth-child(2) { color: var(--accent-claro); -webkit-text-stroke: 0; }

/* --- barra do topo --- */
.login-topo {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  padding-top: calc(var(--u) * 1.4);
  font-size: calc(var(--u) * .8); letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-dim);
}
.login-url {
  font-family: var(--font-serif); font-style: italic;
  font-size: calc(var(--u) * 1.1); letter-spacing: 0; text-transform: none;
  color: var(--text); text-decoration: underline; text-underline-offset: .25em;
}

/* --- as duas colunas --- */
.auth-layout {
  flex: 1; min-height: 0; display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, .85fr);
  gap: calc(var(--u) * 3.4); align-items: start;
  padding: calc(var(--u) * 1.4) 0;
}

/* Leitor de tela e busca ainda enxergam o nome; olho nenhum ve. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.auth-hero { min-width: 0; }
/* Marca da forma de entrar, no mesmo traco dos outros icones. */
.ic-login { display: inline-grid; place-items: center; flex-shrink: 0; }
#screen-login .alt-login {
  margin-top: calc(var(--u) * 1); text-align: center;
  display: flex; justify-content: center; align-items: center; gap: .6em;
  font-size: calc(var(--u) * .82);
}

/* --- a marca --- */
.wordmark {
  position: relative;   /* ancora o risco vermelho da abertura */
  display: flex; align-items: flex-end; gap: calc(var(--u) * 1.4);
  /* max-content: sem isto o <span> do nome estica ate o fim da coluna
     e o selo vai parar longe, no canto direito. */
  width: max-content; max-width: 100%;
  margin: 0; line-height: 1;
}
.mk-selo {
  width: calc(var(--u) * 9.6); aspect-ratio: 1; flex: none; display: block;
  background-color: var(--text);
  -webkit-mask: url('/marca-banke.svg') center / contain no-repeat;
  mask: url('/marca-banke.svg') center / contain no-repeat;
}
.mk-nome b {
  display: block; font-family: var(--font-display); font-weight: 400;
  font-size: calc(var(--u) * 10.5); line-height: .8; letter-spacing: -.045em;
  text-transform: uppercase; color: var(--text);
}
/* Cada letra e um <i> proprio so pra abertura poder subir uma de cada
   vez. Fora dela nao muda nada na tela: inline-block com a mesma
   line-height do pai cai na mesma linha de base, e o letter-spacing
   negativo continua valendo entre elas. */
.mk-nome i { display: inline-block; font-style: normal; }

/* --- a chamada: o contraponto e de VOZ, nao de peso --- */
.hero-lede {
  margin: calc(var(--u) * 5.4) 0 0; font-size: calc(var(--u) * 2);
  font-weight: 700; line-height: 1.12; letter-spacing: -.02em;
  max-width: 19ch; color: var(--text);
}
.hero-lede em {
  font-family: var(--font-serif); font-style: italic; font-weight: 400;
  color: var(--accent-claro);
}

/* --- fatos --- */
.facts {
  list-style: none; margin: calc(var(--u) * 2) 0 0; padding: 0;
  border-top: 1px solid var(--border);
}
.facts li {
  padding: calc(var(--u) * .95) 0; border-bottom: 1px solid var(--border);
  display: grid; gap: .2em;
}
.fact-label {
  font-size: calc(var(--u) * .82); font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--text); margin: 0;
}
/* A seta e o unico vermelho da lista: marca o item sem pintar o texto. */
.fact-label::before { content: "\2192 "; color: var(--accent-claro); }
.fact-desc {
  display: block; color: var(--text-dim);
  font-size: calc(var(--u) * .95); max-width: 54ch; line-height: 1.5;
}

/* --- cartao de entrada --- */
#screen-login .auth-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 0; padding: calc(var(--u) * 1.7);
}
#screen-login .auth-tabs {
  display: flex; gap: 0; border-bottom: 1px solid var(--border);
  margin: calc(var(--u) * -1.7) calc(var(--u) * -1.7) calc(var(--u) * 1.4);
}
#screen-login .auth-tab {
  flex: 1; padding: calc(var(--u) * 1.05) .6em; border: 0; background: transparent;
  color: var(--text-dim); font: inherit; font-weight: 700;
  font-size: calc(var(--u) * .8); letter-spacing: .14em; text-transform: uppercase;
  cursor: pointer; border-bottom: 3px solid transparent; border-radius: 0;
}
#screen-login .auth-tab.selected { color: var(--text); border-bottom-color: var(--accent-claro); }

#screen-login .check {
  display: flex; gap: .6em; align-items: flex-start; margin-bottom: .6em;
  font-size: calc(var(--u) * .87); color: var(--text-dim);
}
#screen-login .check input { accent-color: var(--accent-claro); width: 1.15em; height: 1.15em; margin-top: .1em; flex: none; }
#screen-login .check strong { color: var(--text); }

/* Aresta viva tambem no foco. O offset fica como esta: zera-lo
   encostaria o anel vermelho no botao vermelho e ele sumiria. */
#screen-login :focus-visible { border-radius: 0; }

#screen-login .btn {
  width: 100%; padding: calc(var(--u) * 1); border: 0; border-radius: 0;
  font: inherit; font-weight: 700; font-size: calc(var(--u) * .85);
  letter-spacing: .12em; text-transform: uppercase; margin-top: .6em;
  transition: transform .12s var(--duro), background .2s var(--ease), border-color .2s var(--ease);
}
#screen-login .btn.primary { background: var(--accent); color: #fff; }
#screen-login .btn.outline, #screen-login .btn.ghost {
  background: transparent; color: var(--text); border: 1px solid var(--border);
}

#screen-login .rec-note {
  margin: 0 0 2px; padding: 0; border: 0; background: none;
  font-size: calc(var(--u) * .85); line-height: 1.45; color: var(--text-dim);
}
#screen-login .rec-note p { margin: 0; }
#screen-login .rec-note strong { color: var(--text); }

#screen-login .divider {
  display: flex; align-items: center; gap: .8em;
  margin: calc(var(--u) * 1.1) 0; color: var(--text-dim);
  font-size: inherit; text-transform: none; letter-spacing: 0;
}
#screen-login .divider span {
  font-family: var(--font-serif); font-style: italic;
  font-size: calc(var(--u) * .95); letter-spacing: 0; text-transform: none;
}

#screen-login .field { display: block; margin-bottom: .75em; }
#screen-login .field > span {
  display: block; font-size: calc(var(--u) * .7); font-weight: 700;
  letter-spacing: .15em; text-transform: uppercase; color: var(--text-dim); margin-bottom: .4em;
}
#screen-login .field input, #screen-login input[type=text], #screen-login input[type=password] {
  width: 100%; padding: calc(var(--u) * .85) calc(var(--u) * .9); border-radius: 0;
  background: transparent; color: var(--text); border: 1px solid var(--border);
  font: inherit; font-size: calc(var(--u) * 1);
}

/* Botao que se le como link: usado em "esqueci minha senha" e
   "entrar com apelido". Sem esta regra o navegador desenha caixa de
   botao e eles viram dois retangulos no meio do cartao. */
.linkish {
  background: none; border: none; color: var(--text-dim); font-family: inherit;
  font-size: calc(var(--u, 14px) * .82); cursor: pointer; text-decoration: underline;
  text-underline-offset: 3px; padding: 4px; width: auto; margin: 0;
  letter-spacing: 0; text-transform: none; font-weight: 400; border-radius: 0;
}
.linkish:hover { color: var(--text); }

#screen-login .consent { display: grid; gap: calc(var(--u) * .5); margin-bottom: calc(var(--u) * 1); }

/* ============================================================
   O PORTAO 18+ CHAMANDO ATENCAO PRA SI
   ------------------------------------------------------------
   Quem clicava em "Entrar com Steam" sem marcar as duas caixas so
   via uma linha de erro no pe do cartao — longe do lugar que
   resolve. Aqui o par inteiro treme e a caixa que falta pula: o
   olho vai pro ponto de apertar, sem precisar ler nada.
   Quem ja marcou nao pisca junto — piscar as duas manda a pessoa
   procurar o que, afinal, esta errado.
   ============================================================ */
#screen-login .consent.pede { animation: consentTremor .5s var(--ease); }
@keyframes consentTremor {
  0%, 100% { transform: translateX(0); }
  18% { transform: translateX(-7px); }
  36% { transform: translateX(7px); }
  54% { transform: translateX(-4px); }
  72% { transform: translateX(3px); }
}
#screen-login .check.falta,
#screen-login .check.falta strong { color: var(--accent-claro); }
#screen-login .check.falta input {
  outline: 2px solid var(--accent-claro); outline-offset: 3px;
  animation: caixaPula .62s var(--duro) 3;
}
/* Tres pulos e para. Em looping vira pisca-pisca de banner e a
   pessoa passa a ignorar exatamente o que precisa ver. */
@keyframes caixaPula {
  0%, 58%, 100% { transform: translateY(0) scale(1); }
  24% { transform: translateY(-7px) scale(1.28); }
  42% { transform: translateY(0) scale(.94); }
}
@media (prefers-reduced-motion: reduce) {
  #screen-login .consent.pede,
  #screen-login .check.falta input { animation: none; }
}
/* --- porta de teste ---
   Entrar de teste NAO e a acao principal da tela: fica embaixo de tudo,
   separada por um respiro, e com a nota dizendo o que ela e. Botao de
   contorno, nunca vermelho — vermelho aqui competiria com o Steam. */
#testeBlock {
  margin-top: calc(var(--u) * 1.4); padding-top: calc(var(--u) * 1);
  text-align: center;
}
#screen-login #testeBlock .btn { width: 100%; margin: 0; }
.teste-nota {
  margin: calc(var(--u) * .55) 0 0; color: var(--text-dim);
  font-size: calc(var(--u) * .74); line-height: 1.5;
}
.teste-nota b { color: var(--text-muted); font-weight: 600; }
/* O atalho pro mural entra NA frase, como um "ou". Botão de verdade
   embaixo do outro faria parecer que são duas ações do mesmo peso. */
.teste-nota .link-btn { font-size: inherit; }

/* --- faixa de capas: fica na base, e a prova de que tem jogo dentro --- */
#screen-login .sharp-strip {
  flex: none; position: static; border-top: 1px solid var(--border);
  margin-left: calc(var(--u) * -5.4);
  padding: calc(var(--u) * 1) 0 calc(var(--u) * 1.3);
  overflow: hidden; background: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
/* A faixa anda deslocando metade da largura: como o conteudo e
   duplicado no JS, ao chegar em -50% ela esta identica ao inicio e o
   loop fecha sem emenda. */
@keyframes rowLeft { from { transform: translateX(0); } to { transform: translateX(-50%); } }

#screen-login .strip-track {
  display: flex; gap: calc(var(--u) * .9); width: max-content;
  animation: rowLeft var(--strip) linear infinite; will-change: transform;
}
#screen-login .strip-track img {
  width: calc(var(--u) * 11.5); height: calc(var(--u) * 5.4);
  object-fit: cover; display: block; flex-shrink: 0; border-radius: 0;
  filter: grayscale(1) contrast(1.15); opacity: .5;
  transition: filter .3s var(--duro), opacity .3s var(--duro);
}
#screen-login .strip-track img:hover { filter: grayscale(0) contrast(1); opacity: 1; }

/* --- monitor: o cartao rola DENTRO do proprio quadro ---
   Com Steam e Google ligados o cartao ficou mais alto que a coluna
   em qualquer altura de laptop (medido: sobra 14px a 1440x900, 29px
   a 1280x800, 37px a 1024x700 — e 73/83/80px com o bloco do apelido
   aberto). Como ele tem fundo opaco e a coluna e `flex: 1;
   min-height: 0` sem overflow, o que sobra e DESENHADO POR CIMA das
   capas. A linha da faixa e intocavel: quem rola e o cartao. */
@media (min-width: 901px) {
  #screen-login .auth-layout { grid-auto-rows: 100%; }
  #screen-login .auth-card {
    align-self: start; max-height: 100%;
    overflow-y: auto; overscroll-behavior: contain;
  }
  /* O heroi tambem passa da coluna em tela baixa. Fundo transparente
     faz o estrago ser menor, mas passar por cima da faixa e feio
     igual. */
  #screen-login .auth-hero { max-height: 100%; overflow-y: auto; overscroll-behavior: contain; }
}


/* --- celular: a regua proporcional e abandonada de proposito. Espremer
   duas colunas num telefone daria texto de 4px. Empilha e deixa rolar. --- */
@media (max-width: 900px) {
  #screen-login { --u: 13px; }
  #screen-login.active { height: auto; min-height: 100dvh; overflow: visible; padding: 0 16px 0 58px; }
  .auth-layout { grid-template-columns: 1fr; gap: 26px; }
  /* O selo fica ao LADO do nome, como no monitor. Ele e um SIMBOLO:
     nao precisa ter a altura do nome, so acompanhar a caixa da
     palavra. Medido: a 375px o conjunto da 244px numa coluna de
     335px, e a 280px da 209px em 240px — a coluna so faltaria
     abaixo de ~250px de tela, que nao existe. */
  .wordmark { align-items: flex-end; gap: clamp(8px, 2.6vw, 14px); }
  .mk-selo { width: clamp(38px, 12.5vw, 74px); }
  .mk-nome b { font-size: clamp(44px, 13.5vw, 90px); }
  /* Os -58px eram o espelho de um padding-left de 58px que o bloco
     la de baixo ("No estreito o trilho e a barra do topo saem")
     trocou por 20px. Espelho torto: a faixa nascia 38px FORA da
     tela e sobrava um vao de 78px na direita. Agora ela sangra dos
     dois lados, exatamente o padding que existe de verdade. */
  #screen-login .sharp-strip { margin-left: -20px; margin-right: -20px; }
  .login-topo { display: none; }
}
/* ============================================================
   CADASTRO
   ============================================================ */
/* ============================================================
   TELAS DO CADASTRO
   ------------------------------------------------------------
   Nada de cartao flutuando no meio da tela: o conteudo encosta na
   esquerda e o titulo e a coisa maior da tela, como nas telas da
   referencia (marca no topo, rotulo da secao, e o assunto enorme
   logo abaixo).
   ============================================================ */
#screen-onboarding.active,
#screen-nick.active,
#screen-welcome.active,
#screen-tour.active {
  position: relative; min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(74px, 11vh, 104px) clamp(20px, 4vw, 56px) clamp(40px, 7vh, 72px);
}
/* O de escolher jogos tem grade longa: comeca do topo. */
#screen-onboarding.active { justify-content: flex-start; }

/* --- cabecalho da tela: marca + rotulo da secao --- */
.tela-topo {
  position: absolute; top: clamp(20px, 3.4vh, 30px); left: clamp(20px, 4vw, 56px);
  display: flex; align-items: baseline; gap: .6em;
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--text-dim);
}
.tela-topo b {
  font-family: var(--font-display); font-weight: 400; letter-spacing: -.03em;
  font-size: 20px; color: var(--text); text-transform: uppercase;
}

/* O cartao perde a caixa: vira so o bloco de conteudo. */
#screen-nick .card, #screen-welcome .card,
#screen-onboarding .card, #screen-tour .card {
  background: none; border: 0; padding: 0;
  max-width: min(100%, 980px); width: 100%;
}
#screen-nick .card { max-width: min(100%, 620px); }

/* O titulo e o herói da tela. */
#screen-nick .card h2, #screen-welcome .card h2,
#screen-onboarding .card h2, #screen-tour .card h2 {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(30px, 4.6vw, 58px); line-height: .9; letter-spacing: -.04em;
  text-transform: uppercase; margin: 0 0 10px; color: var(--text);
}
#screen-nick .subtitle, #screen-welcome .subtitle,
#screen-onboarding .subtitle, #screen-tour .subtitle {
  font-size: clamp(14px, 1.3vw, 17px); max-width: 52ch; margin: 0 0 clamp(16px, 3vh, 28px);
}
/* O destaque vira VOZ, nao peso: serifada italica vermelha. */
#screen-nick .subtitle strong, #screen-welcome .subtitle strong,
#screen-onboarding .subtitle strong, #screen-tour .subtitle strong {
  font-family: var(--font-serif); font-style: italic; font-weight: 400;
  color: var(--accent-claro);
}

/* O passo vai pro canto direito, sem pilula: so texto vermelho. */
.wz-step {
  position: absolute; top: clamp(22px, 3.6vh, 32px); right: clamp(20px, 4vw, 56px);
  font-size: 11px; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--accent-claro);
  background: none; border: 0; padding: 0; margin: 0;
}

/* --- Escolha de plataforma --- */
.platform-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 11px; margin: 4px 0 24px;
}
.platform-opt {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 20px 14px; border-radius: var(--r-card); cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  font-family: inherit; font-size: 14px; font-weight: 500;
  transition: border-color .18s var(--ease), background .18s var(--ease), transform .12s var(--ease);
}
.platform-opt .ic { color: var(--text-muted); transition: color .18s var(--ease); }
.platform-opt:hover { border-color: var(--border-hover); transform: translateY(-2px); }
.platform-opt.selected { border-color: var(--accent-claro); background: rgba(var(--accent-rgb), .14); }
.platform-opt.selected .ic { color: var(--accent-claro); }

/* --- Tour: lista de recursos --- */
.tour-list { list-style: none; padding: 0; margin: 6px 0 20px; display: flex; flex-direction: column; gap: 4px; }
.tour-list li { display: flex; gap: 14px; align-items: flex-start; padding: 14px 4px; border-bottom: 1px solid var(--border); }
.tour-list li:last-child { border-bottom: none; }
.tour-ic {
  flex-shrink: 0; width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;
  background: rgba(var(--accent-rgb), .14); color: var(--accent-claro);
}
.tour-list li div { display: flex; flex-direction: column; gap: 3px; }
.tour-list li strong { font-size: 14.5px; font-weight: 600; }
.tour-list li span { font-size: 13px; color: var(--text-dim); line-height: 1.55; }
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: clamp(16px, 3vh, 30px); width: 100%; max-width: 420px;
}
.card.wide { max-width: 860px; }
/* O catálogo tem 60+ jogos: sem isso o "Continuar" fica no fim de uns
   4.500px de rolagem, e quem escolheu os 3 lá em cima tem que varrer a
   lista inteira só pra confirmar. Grudado embaixo, ele acompanha. */
#btnOnboarding {
  position: sticky; bottom: 16px; z-index: 5; margin-top: 18px;
  box-shadow: 0 10px 30px rgba(var(--bg-rgb), .7);
}
.card h2 { font-family: var(--font-display); font-size: 21px; margin: 0 0 6px; font-weight: 400; letter-spacing: -.01em; }
.subtitle { color: var(--text-dim); margin: 0 0 20px; line-height: 1.55; font-size: 14px; }

/* ============================================================
   FORMULÁRIOS
   ============================================================ */
.field { display: block; margin-bottom: clamp(8px, 1.8vh, 16px); }
.field-label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text-muted); margin-bottom: 7px; }
.limit-val { font-weight: 400; color: var(--accent-claro); }
.range { width: 100%; accent-color: var(--accent); cursor: pointer; }
.check-inline { display: inline-flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 13px; color: var(--text-muted); cursor: pointer; }
.check-inline input { accent-color: var(--accent); width: 16px; height: 16px; cursor: pointer; }
.form-error { color: var(--danger); font-size: 13px; min-height: 18px; margin: 6px 0 0; }
.field span { display: block; font-size: 12.5px; color: var(--text-dim); margin-bottom: 7px; }
.field em { font-style: normal; opacity: .7; }

input[type=text], input[type=password], input[type=email], textarea {
  width: 100%; padding: clamp(8px, 1.6vh, 12px) 14px; border-radius: var(--r-ctrl);
  border: 1px solid var(--border); background: var(--surface-2);
  color: var(--text); font-size: 15px; font-family: inherit; outline: none;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
input[type=text]::placeholder, input[type=password]::placeholder,
input[type=email]::placeholder, textarea::placeholder { color: #5a616f; }
input[type=text]:focus, input[type=password]:focus,
input[type=email]:focus, textarea:focus {
  border-color: var(--accent-claro); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15);
}
textarea { min-height: 92px; resize: vertical; }

/* CELULAR: campo de digitar tem que ter no MÍNIMO 16px.
   O Safari do iPhone dá aquele zoom automático ao tocar num campo com
   fonte menor que isso — e depois a tela fica torta. A saída óbvia
   (user-scalable=no na viewport) resolveria, mas tira de todo mundo a
   possibilidade de ampliar a tela, o que atrapalha quem enxerga mal.
   Subir a fonte resolve o zoom sem tirar nada de ninguém.
   Vale por PONTEIRO (dedo), não por largura: pega tablet e celular
   deitado, que uma media query de largura deixaria passar. */
@media (pointer: coarse) {
  input[type=text], input[type=password], input[type=email],
  input[type=search], input[type=number], input[type=tel],
  input[type=url], textarea, select,
  input.search, .composer input {
    font-size: 16px;
  }
}

.search-wrap { position: relative; margin-top: 14px; }
.search-ic { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-dim); pointer-events: none; }
/* "input.search" e não ".search": o seletor input[type=text] acima tem
   especificidade maior e engolia o padding-left, jogando o texto por
   baixo do ícone de busca. */
input.search { width: 100%; padding: 12px 15px 12px 42px; border-radius: var(--r-ctrl);
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
  font-size: 15px; font-family: inherit; outline: none;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease); }
input.search::placeholder { color: #5a616f; }
input.search:focus { border-color: var(--accent-claro); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15); }

/* Checkboxes com o mesmo peso visual */
.check {
  display: flex; gap: 11px; align-items: center;
  font-size: 13.5px; color: var(--text-muted); line-height: 1.45; cursor: pointer;
}
.check input { accent-color: var(--accent); width: 16px; height: 16px; cursor: pointer; flex-shrink: 0; margin: 0; }
.check strong { color: var(--text); font-weight: 600; }
.check a { color: var(--accent-claro); text-decoration: none; }
.check a:hover { text-decoration: underline; }

/* ============================================================
   BOTÕES — com resposta ao toque
   ============================================================ */
.btn {
  border: none; border-radius: var(--r-ctrl); padding: clamp(7px, 1.5vh, 11px) 18px;
  font-size: 14.5px; font-weight: 600; cursor: pointer; color: #fff;
  font-family: inherit; display: inline-flex; align-items: center;
  justify-content: center; gap: 8px;
  transition: transform .12s var(--ease), background .2s var(--ease),
              border-color .2s var(--ease), opacity .2s var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(.985); }
.btn.primary { width: 100%; background: var(--accent); }
.btn.primary:hover { background: var(--accent-hover); }
.btn.btn-lg { padding: clamp(8px, 1.8vh, 13px) 18px; font-size: 15px; }
.btn.outline { width: 100%; background: transparent; border: 1px solid var(--border-hover); color: var(--text); margin-top: 10px; }
.btn.outline:hover { border-color: var(--accent-claro); }
.btn.ghost { background: transparent; border: 1px solid var(--border); color: var(--text-muted); }
.btn.ghost:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-hover); }
/* Nas barras de topo o ghost também perde a moldura — lá em cima a
   fileira de retângulos competia com o título da sala. */
.topbar .btn.ghost, .float-nav .btn.ghost { border-color: transparent; }
.topbar .btn.ghost:hover, .float-nav .btn.ghost:hover { border-color: transparent; background: var(--surface-2); }
.btn.danger { background: var(--danger); }
.btn.small { padding: 7px 12px; font-size: 12.5px; }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }
/* Rótulo curto pra tela estreita — o .btn é inline-flex com gap, então
   partir o texto em dois nós criaria espaço duplo. Dois rótulos inteiros
   e cada tamanho de tela mostra o seu. */
.lbl-curto { display: none; }

.divider { display: flex; align-items: center; gap: 14px; margin: clamp(10px, 2.2vh, 20px) 0 clamp(4px, .9vh, 8px); color: var(--text-dim); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; }
.divider::before, .divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }

.hint { color: var(--text-dim); font-size: 12px; margin-top: 14px; text-align: center; line-height: 1.55; }
.error { color: var(--danger); font-size: 13px; min-height: 18px; margin: 12px 0 0; text-align: center; }
.modal-lede { color: var(--text-dim); font-size: 13.5px; line-height: 1.55; margin: 0 0 18px; }

/* ============================================================
   BARRA SUPERIOR
   ============================================================ */
.topbar {
  display: flex; align-items: center; gap: 10px; padding: 12px 20px;
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.spacer { flex: 1; }
.whoami { color: var(--text-dim); font-size: 13px; }
.room-title { font-family: var(--font-display); font-weight: 400; font-size: 15px; letter-spacing: -.01em; }

.brand-sm { display: inline-flex; align-items: baseline; gap: .16em; }
.bs-the { font-family: var(--font-serif); font-style: italic; font-size: 13px; color: var(--text-dim); }
/* A 15px a groovy vira borrão, então a marca pequena fica na grotesca.
   É o mesmo nome em duas escalas, não duas marcas diferentes. */
.bs-lobby { font-family: var(--font-display); font-weight: 400; font-size: 15px; letter-spacing: -.03em; }

/* Sem caixa em volta: o ícone se defende sozinho, igual à barra lateral
   do lobby. A moldura só empilhava retângulo em cima de retângulo no topo. */
.icon-btn {
  position: relative; background: transparent; border: none;
  color: var(--text-dim); width: 34px; height: 34px; border-radius: var(--r-ctrl);
  cursor: pointer; display: grid; place-items: center;
  transition: background .18s var(--ease), color .18s var(--ease),
              transform .12s var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); transform: translateY(-1px); }
.icon-btn.ativo { color: var(--text); background: var(--surface-2); }
.icon-btn:active { transform: translateY(0) scale(.94); }
.badge-dot {
  position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px;
  border-radius: 20px; background: var(--accent); color: #fff;
  font-size: 10px; font-weight: 600; display: grid; place-items: center;
  padding: 0 4px; border: 2px solid var(--surface);
  animation: pop .3s var(--ease) both;
}
@keyframes pop { from { transform: scale(0); } to { transform: scale(1); } }

/* ============================================================
   TOPO FLUTUANTE (substitui a barra cinza lateral)
   ============================================================ */
#screen-friends.active,
#screen-profile.active,
#screen-admin.active { display: flex; flex-direction: column; min-height: 100vh; }

.float-nav {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 26px; position: sticky; top: 0; z-index: 20;
  background: linear-gradient(180deg, var(--bg) 55%, transparent);
}

/* ============================================================
   O DESKTOP — a tela inicial
   ------------------------------------------------------------
   Aqui morava a barra vertical do lobby. O lobby virou janela e a
   barra virou DOCK, embaixo, no meio.

   A régua visual é a mesma do cartaz do cadastro, e não a de um
   sistema operacional de verdade: papel creme, contorno de tinta e
   SOMBRA DURA (sem desfoque, deslocada). Um ícone de macOS aqui
   dentro pareceria colado de outro programa.
   ============================================================ */
#screen-desktop {
  /* O deslocamento da sombra dura, uma vez só: ícone, dock e janela
     usam a mesma medida, senão cada peça parece iluminada por um sol
     diferente. */
  --salto: 5px;
}
#screen-desktop.active {
  position: relative;
  display: flex; flex-direction: column;
  /* dvh, não vh: no celular a barra do navegador some e volta, e com
     vh o dock ficava escondido atrás dela. */
  height: 100dvh; overflow: hidden;
  /* Desktop não rola. É uma ÁREA, não uma página: rolar embaixo dos
     ícones move o chão e desmancha a ideia de que cada coisa tem um
     lugar fixo. O overscroll trava também o repique do trackpad, que
     no Mac descolava a tela inteira por um instante. */
  overscroll-behavior: none;
  touch-action: none;
}
/* Enquanto o desktop está aberto, a página atrás também não rola. */
body:has(#screen-desktop.active) { overflow: hidden; overscroll-behavior: none; }
/* MENOS no celular. Lá os ícones viram grade e a grade PRECISA rolar
   quando passa de uma tela — travar o toque ali deixaria a metade de
   baixo dos ícones inalcançável. O que não pode rolar é o chão do
   desktop no computador, não a lista do telefone. */
@media (max-width: 900px), (pointer: coarse) {
  #screen-desktop.active { touch-action: auto; }
  .desk-area { touch-action: pan-y; overscroll-behavior: contain; }
}

/* --- a área onde os ícones moram ---
   Os ícones são position:absolute em PERCENTUAL. É por isso que a
   área precisa ser o bloco de referência: sem o position:relative
   aqui, eles se ancorariam na janela e escapariam por baixo do dock. */
.desk-area {
  position: relative; z-index: 1;
  flex: 1; min-height: 0;
  padding: 20px;
}

/* --- o ícone --- */
.desk-icone {
  position: absolute;
  /* --escala é escrita pelo JS e guardada na conta: é ela que deixa o
     jogo da vez grande e o de vez em quando pequeno. Multiplica a
     CAIXA inteira (largura e arte), então o ícone maior realmente
     ocupa mais espaço — não é um zoom por cima. */
  --escala: 1;
  width: calc(108px * var(--escala));
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 8px 4px 6px;
  background: none; border: 0; cursor: pointer;
  color: var(--text); font: inherit; text-align: center;
  /* touch-action: none é o que faz o arrastar existir no trackpad e
     na caneta: sem isto o navegador entende o gesto como rolagem e
     cancela o pointermove no meio. */
  touch-action: none;
  transition: background .16s var(--ease);
}
/* Cinza neutro: clareia sobre o papel e escurece sobre o escuro, sem
   precisar de uma regra por tema. */
.desk-icone:hover, .desk-icone:focus-visible { background: rgba(127, 127, 127, .18); }
.desk-icone:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* A arte: quadrado de papel branco com contorno de tinta e a sombra
   dura. É o mesmo bloco do botão e do campo do cadastro. */
.di-arte {
  position: relative;
  /* Retangular, e não quadrada: a capa que a Steam entrega é 460x215.
     Espremida num quadrado ela era recortada no meio e virava um
     pedaço de letra sem sentido — dava pra ler "STRONE" no lugar de
     Astroneer. */
  width: calc(96px * var(--escala)); height: calc(54px * var(--escala)); flex: none;
  display: grid; place-items: center;
  background: var(--surface); color: var(--text-dim);
  border: 2px solid var(--tinta);
  box-shadow: var(--salto) var(--salto) 0 var(--tinta);
  overflow: hidden;
  transition: transform .14s var(--duro), box-shadow .14s var(--duro);
}
/* user-drag: none é o que impede o navegador de sair carregando a capa
   como se fosse um arquivo. É por isso que o pointerdown do ícone NÃO
   dá preventDefault: se desse, matava junto o clique que abre o mural. */
.di-arte img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  -webkit-user-drag: none; user-select: none; pointer-events: none;
}
/* Atalho de pessoa é redondo; mural é quadrado. A forma já diz o que
   é antes de a pessoa ler o nome. */
.desk-friend .di-arte {
  width: calc(60px * var(--escala)); height: calc(60px * var(--escala)); border-radius: 50%;
}
.desk-icone:hover .di-arte {
  transform: translate(calc(var(--salto) * -.4), calc(var(--salto) * -.4));
  box-shadow: calc(var(--salto) * 1.6) calc(var(--salto) * 1.6) 0 var(--tinta);
}
.desk-icone:active .di-arte {
  transform: translate(var(--salto), var(--salto)); box-shadow: none;
}
/* Bolinha de online, encostada na quina da arte. */
/* A bolinha de "tem gente online" saiu daqui a pedido: num desktop
   com dez ícones ela virava dez pontos verdes piscando sobre as
   capas, e competia com a arte em vez de informar. Quem quer saber
   quem está online abre o mural. */
.di-nome {
  /* O nome cresce com o ícone, mas AMORTECIDO. Crescendo na mesma
     proporção, um ícone em 3x viraria um letreiro de 32px que rouba a
     tela do desenho. A conta dá 10,5px em escala 1 e ~17px em 3x. É
     uma reta e não pow(): pow() em CSS é recente demais pra estar na
     base de um layout. O max() é o piso — abaixo de 9,5px não se lê. */
  font-size: max(9.5px, calc(10.5px * (0.7 + var(--escala) * 0.3))); font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; line-height: 1.3; color: var(--text);
  max-width: 100%;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* A alça de tamanho, no canto de baixo à direita do ícone. Só aparece
   quando o mouse chega: em repouso o desktop é limpo, e é a mesma
   ideia do canto de esticar da janela. */
.di-alca {
  position: absolute; right: -2px; bottom: 8px;
  width: 14px; height: 14px; z-index: 2;
  cursor: nwse-resize;
  opacity: 0; transition: opacity .16s var(--ease);
  background: var(--surface);
  border: 1.5px solid var(--tinta);
  box-shadow: 1px 1px 0 var(--tinta);
}
.desk-icone:hover .di-alca, .desk-icone:focus-within .di-alca, .desk-icone.medindo .di-alca { opacity: 1; }
.desk-icone.medindo { z-index: 24; }
.desk-icone.medindo .di-arte { transition: none; }
/* No celular a grade manda no tamanho: alça aqui só atrapalharia o
   dedo, que já não arrasta nada. */
@media (max-width: 900px) { .di-alca { display: none; } }

/* Enquanto arrasta: sai do baralho, cresce um triz e perde a sombra
   (ele está NO AR, não pousado no papel). */
.desk-icone.arrastando {
  z-index: 25; cursor: grabbing;
  transition: none;                  /* seguir o dedo não pode ter atraso */
}
.desk-icone.arrastando .di-arte {
  transform: scale(1.1) rotate(-3deg);
  box-shadow: calc(var(--salto) * 2.4) calc(var(--salto) * 2.4) 0 var(--tinta);
}

/* --- a escolha de modo, na primeira chegada ---
   Encostado no canto de baixo à esquerda, acima do dock: perto da
   porta que ele oferece, e longe do meio, onde ficam a marca e os
   ícones. Não é modal de propósito — quem quiser ignorar, ignora e
   usa o desktop. */
.desk-escolha {
  position: absolute; z-index: 20;
  /* O `bottom` conta a partir da TELA, e o dock mora no pé dela: com
     22px o cartão nascia por baixo da barra e os dois botões ficavam
     metade escondidos (medi 50px sumindo atrás). O --dock-vao é a
     altura que o dock ocupa, declarada junto com ele lá embaixo, pra
     um número só valer nos dois lugares. */
  left: 22px; bottom: calc(22px + var(--dock-vao));
  width: min(320px, calc(100% - 44px));
  padding: 16px 18px 15px;
  background: var(--surface);
  border: 2px solid var(--tinta);
  box-shadow: var(--salto) var(--salto) 0 var(--tinta);
  animation: escolhaEntra .4s var(--duro) .5s both;
}
@keyframes escolhaEntra {
  from { opacity: 0; transform: translateY(14px); }
}
.de-lede { margin: 0 0 4px; font-size: 14px; line-height: 1.45; color: var(--text-dim); }
.de-lede strong { color: var(--text); }
.de-nota {
  margin: 0 0 12px; font-family: var(--font-serif); font-style: italic;
  font-size: 13.5px; color: var(--text-dim);
}
.de-acoes { display: flex; gap: 8px; flex-wrap: wrap; }
.de-acoes .btn { width: auto; flex: 1; min-width: 120px; }
@media (max-width: 900px) {
  /* A barra encolhe aqui, e o vão encolhe com ela. */
  #screen-desktop { --dock-vao: 70px; }
  .desk-escolha { left: 12px; right: 12px; bottom: calc(12px + var(--dock-vao)); width: auto; }
}
@media (prefers-reduced-motion: reduce) { .desk-escolha { animation: none; } }

/* Primeiro acesso sem nada.
   Sobe de z-index 1 pra 3: a marca de parede fica em 1, e com os dois
   empatados o desenho dependia da ordem no HTML. */
.desk-vazio {
  position: absolute; z-index: 3; left: 50%; top: 42%; translate: -50% -50%;
  text-align: center; color: var(--text-dim); max-width: 34ch;
}

/* --- A PAREDE SAI DE CENA QUANDO O RECADO ESTÁ NA TELA ---
   Os dois nascem centralizados, e por isso caíam um em cima do outro:
   a marca gigante atravessava exatamente a linha que explica o que
   fazer — "Abra Procurar no dock e entre num mural" — bem no primeiro
   acesso, que é quando essa frase é a coisa mais importante do site.
   Medido: o recado ocupava de 316 a 391, e a marca de 313 a 432.

   Escurecer não bastava: por mais apagada que ficasse, a letra grande
   continuava cruzando a pequena, e ler texto por cima de curva é
   cansativo mesmo com contraste sobrando.

   A marca é papel de parede — ela existe pra preencher o fundo ATRÁS
   dos ícones. Quando não há ícone nenhum e há um recado no lugar, ela
   não tem função e sai. Volta sozinha no instante em que o primeiro
   ícone aparece. */
#screen-desktop:has(#deskVazio:not([hidden])) .lobby-watermark {
  /* O `animation: none` não é sobra: a parede tem um respiro infinito
     que anima a própria opacidade, e animação ganha de declaração
     comum na cascata. Sem desligar o respiro, o `opacity: 0` abaixo era
     ignorado e a marca continuava acesa por cima do recado. */
  animation: none;
  opacity: 0;
  transition: opacity .4s var(--ease);
}
.desk-vazio p { margin: 0 0 6px; font-size: 14px; line-height: 1.5; }
.desk-vazio strong { color: var(--text); }
.desk-vazio b { color: var(--accent); }

/* ============================================================
   O DOCK
   ============================================================ */
/* O vão que o dock ocupa no pé da tela: a altura da barra mais a
   margem embaixo dela. Vive aqui, ao lado do dock, porque é medida
   DELE — quem posiciona coisa acima do dock lê esta variável em vez de
   repetir o número e esquecer de um dos lugares.
   Medido: 70px de barra + 16 de margem no computador; a barra encolhe
   abaixo de 900px (regra mais adiante) e o valor cai junto. Os poucos
   pixels de folga cobrem o env(safe-area-inset-bottom) do celular, que
   varia de aparelho pra aparelho. */
#screen-desktop { --dock-vao: 92px; }

.desk-dock {
  position: relative; z-index: 30;
  flex: none; align-self: center;
  /* A barra centra o próprio conteúdo: com a bandeja de minimizadas
     entrando e saindo, sem isto o conjunto pendia pra um lado quando
     ela aparecia. */
  justify-content: center;
  margin-bottom: calc(16px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 2px;
  padding: 7px 9px;
  /* Cor por token, e não branco cravado: o app tem tema claro e
     escuro, e um dock branco no escuro come os próprios ícones —
     ícone com a cor do texto sobre fundo branco vira invisível. */
  background: rgba(var(--surface-rgb), .88);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 2px solid var(--tinta);
  box-shadow: var(--salto) var(--salto) 0 var(--tinta);
}
.dock-app {
  position: relative;
  width: 52px; height: 52px;
  /* place-items: center centraliza nos dois eixos, mas o .dock-label
     (o balão) é filho e entrava na conta da grade, empurrando o ícone
     pra cima. Com ele fora do fluxo, o desenho fica no centro de
     verdade. */
  display: grid; place-items: center; place-content: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--text);
  transition: translate .18s var(--ease), background .18s var(--ease), color .18s var(--ease);
}
/* O botão SOBE no hover em vez de acender: é o gesto do dock, e não
   mexe no alvo do clique porque o translate não muda o layout. */
.dock-app:hover, .dock-app:focus-visible { translate: 0 -6px; }
.dock-app:active { translate: 0 -1px; }
.dock-app .badge-dot { top: 9px; right: 9px; border-color: var(--surface); }

/* --- o avatar do perfil, no dock ---
   Esta regra tinha sumido junto com a barra lateral antiga, e sem ela
   o avatar virava o que o JS pinta e mais nada: um QUADRADO na cor
   sorteada pelo apelido, com as iniciais dentro. Era o "TE" verde.
   Aqui ele volta a ser um retrato redondo. */
.dock-avatar-img {
  position: relative; overflow: hidden;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff; font-weight: 700; font-size: 11px; letter-spacing: .02em;
  /* Aro de tinta, não um branco transparente: no dock claro o branco
     desaparecia no fundo e a foto ficava boiando sem borda. */
  box-shadow: 0 0 0 1.5px var(--tinta);
}
.dock-avatar-img img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
/* As iniciais ficam POR BAIXO da foto de propósito: quando o endereço
   da foto morre (CDN fora do ar, conta sem avatar), o <img> some e
   elas reaparecem sozinhas, sem uma linha de JS. */
.js-profile:hover .dock-avatar-img { box-shadow: 0 0 0 2px var(--accent); }

/* O nome aparece ACIMA, num balão de tinta. */
.dock-app .dock-label {
  /* Absoluto: fora do fluxo da grade, senão ele conta como uma segunda
     linha e desloca o ícone do centro. */
  position: absolute; bottom: 100%; left: 50%; right: auto; top: auto;
  translate: -50% 0; margin: 0 0 9px;
  white-space: nowrap;
  background: var(--tinta); color: var(--papel); border: 0; border-radius: 0;
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  padding: 5px 8px;
  opacity: 0; pointer-events: none;
  transition: opacity .16s var(--ease);
}
.dock-app:hover .dock-label, .dock-app:focus-visible .dock-label { opacity: 1; }

.dock-div { width: 2px; height: 30px; background: var(--tinta); opacity: .25; margin: 0 6px; }

/* --- ARRUMAR: o botão discreto ---
   Menor que os outros e sem peso visual: não é coisa de usar todo dia.
   Mas a área de clique continua de botão de verdade (o mesmo 52px de
   altura dos vizinhos), porque alvo pequeno é alvo que se erra. */
.dock-arruma { width: 40px; opacity: .45; }
.dock-arruma:hover, .dock-arruma:focus-visible { opacity: 1; }
/* No hover ele se ARRUMA: o bloco grande cresce um triz e assenta. É o
   próprio gesto do botão, em miniatura — melhor que girar, que não
   quer dizer nada. */
.dock-arruma .ic { transition: scale .28s var(--duro); }
.dock-arruma:hover .ic { scale: 1.14; }
/* Trabalhando: pulsa em vez de girar. Girar sugere "carregando sem
   fim"; pulsar sugere "estou fazendo o que você pediu". */
.dock-arruma.girando .ic { animation: arrumaPulsa .7s var(--ease) infinite; }
@keyframes arrumaPulsa {
  0%, 100% { scale: 1; opacity: 1; }
  50%      { scale: 1.2; opacity: .55; }
}
.dock-arruma:disabled { cursor: default; }

/* Os ícones DESLIZAM até o lugar novo em vez de pularem. A transição
   só existe durante a arrumação: fora dela, arrastar precisa seguir o
   cursor sem atraso nenhum. */
.desk-area.arrumando .desk-icone {
  transition: left .55s var(--ease), top .55s var(--ease), width .55s var(--ease);
}
.desk-area.arrumando .di-arte {
  transition: width .55s var(--ease), height .55s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .desk-area.arrumando .desk-icone, .desk-area.arrumando .di-arte { transition: none; }
  .dock-arruma.girando .ic { animation: none; }
}

/* A lixeira acende quando um ícone está por cima dela. Vermelha e
   maior: a pessoa precisa ter certeza do que vai acontecer ANTES de
   soltar, não depois. */
.dock-lixeira.pronta {
  background: var(--accent); color: #fff;
  translate: 0 -8px; scale: 1.12;
}

/* ============================================================
   AS JANELAS
   ------------------------------------------------------------
   Flutuam sobre o desktop de propósito: dá pra ver os ícones atrás,
   que é o que faz a metáfora se sustentar. Se ocupassem a tela
   inteira, seriam só as telas antigas com outro nome.

   Os três pontinhos da barra NÃO são enfeite: vermelho fecha,
   amarelo minimiza, verde põe em tela cheia — a ordem que todo
   mundo já tem na mão.
   ============================================================ */
.jn-camada {
  position: absolute; z-index: 40;
  inset: 0;
  /* A camada não recebe clique: quem recebe são as janelas dentro
     dela. Sem isto ela viraria um vidro por cima do desktop inteiro e
     nenhum ícone seria clicável com uma janela aberta. */
  pointer-events: none;
}
.jn {
  position: absolute;
  pointer-events: auto;
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 2px solid var(--tinta);
  box-shadow: calc(var(--salto) * 2) calc(var(--salto) * 2) 0 var(--tinta);
  transform-origin: center center;
}
/* A janela da frente ganha a sombra cheia; as de trás recuam. Sem
   isso, três janelas abertas viram uma pilha sem hierarquia. */
.jn:not(.focada) { box-shadow: var(--salto) var(--salto) 0 rgba(127, 127, 127, .45); }
.jn.cheia {
  box-shadow: none;
  transition: left .26s var(--duro), top .26s var(--duro),
              width .26s var(--duro), height .26s var(--duro);
}
/* A volta da tela cheia anima igual à ida. */
.jn:not(.movendo) {
  transition: left .26s var(--duro), top .26s var(--duro),
              width .26s var(--duro), height .26s var(--duro),
              box-shadow .2s var(--ease);
}
/* Enquanto arrasta, transição nenhuma: seguir o cursor com .26s de
   atraso dá a sensação de que a janela está presa na lama. */
.jn.movendo { transition: none; }

.jn-barra {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  background: var(--papel); border-bottom: 2px solid var(--tinta);
  cursor: grab; user-select: none;
}
.jn.movendo .jn-barra { cursor: grabbing; }
.jn.cheia .jn-barra { cursor: default; }

.jn-luzes { display: flex; gap: 5px; flex: none; }

/* OS TRÊS BOTÕES, TODOS IGUAIS: quadrado de contorno de tinta com o
   símbolo dentro. Antes eram bolinhas coloridas ao estilo do sistema,
   com o sinal aparecendo só no hover — o que obriga a decorar qual
   cor faz o quê, e some justamente pra quem está de passagem. Aqui o
   × , o − e o □ estão sempre à mostra e dizem sozinhos o que fazem.
   Sem código de cor: quem informa é o desenho. */
.jn-luz {
  position: relative;
  width: 16px; height: 16px; padding: 0; cursor: pointer;
  border: 1.5px solid var(--tinta); background: transparent;
  transition: background .14s var(--ease), border-color .14s var(--ease);
}
.jn-luz:hover, .jn-luz:focus-visible {
  background: var(--accent); border-color: var(--accent);
}
/* Os traços do símbolo. São dois pseudo-elementos por botão: um só
   não desenha o × nem o quadrado. */
.jn-luz::before, .jn-luz::after {
  content: ''; position: absolute; background: var(--tinta);
  transition: background .14s var(--ease);
}
.jn-luz:hover::before, .jn-luz:hover::after,
.jn-luz:focus-visible::before, .jn-luz:focus-visible::after { background: #fff; }

/* × — duas diagonais cruzadas */
.jn-fechar::before, .jn-fechar::after {
  left: 50%; top: 50%; width: 9px; height: 1.5px; margin: -.75px 0 0 -4.5px;
}
.jn-fechar::before { transform: rotate(45deg); }
.jn-fechar::after  { transform: rotate(-45deg); }

/* − — um traço só, embaixo, como o sinal de minimizar de sempre */
.jn-min::before {
  left: 50%; bottom: 3px; width: 9px; height: 1.5px; margin-left: -4.5px;
}
.jn-min::after { display: none; }

/* □ — o quadrado vazado de tela cheia. Vira um traço com moldura
   quando JÁ está em tela cheia, que é o sinal de "voltar". */
.jn-max::before {
  left: 50%; top: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px;
  background: none; border: 1.5px solid var(--tinta);
  transition: border-color .14s var(--ease);
}
.jn-max:hover::before, .jn-max:focus-visible::before { border-color: #fff; background: none; }
.jn-max::after { display: none; }
.jn.cheia .jn-max::before { height: 4px; margin-top: -2px; }

.jn-titulo {
  font-family: var(--font-display); font-weight: 400;
  font-size: 12.5px; letter-spacing: .02em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.jn-corpo {
  flex: 1; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
  position: relative;
}
/* As oito pegas de redimensionar: quatro lados e quatro cantos.
   Invisíveis — quem avisa que dá pra pegar é o cursor mudando, que é
   como qualquer janela faz. Elas transbordam 5px pra FORA da moldura
   porque mirar exatamente na linha de 2px é frustrante. */
.jn-pega { position: absolute; z-index: 4; }
.jn-pega.n { top: -5px; left: 10px; right: 10px; height: 9px; cursor: ns-resize; }
.jn-pega.s { bottom: -5px; left: 10px; right: 10px; height: 9px; cursor: ns-resize; }
.jn-pega.o { left: -5px; top: 10px; bottom: 10px; width: 9px; cursor: ew-resize; }
.jn-pega.l { right: -5px; top: 10px; bottom: 10px; width: 9px; cursor: ew-resize; }
.jn-pega.no { top: -5px; left: -5px; width: 15px; height: 15px; cursor: nwse-resize; }
.jn-pega.se { bottom: -5px; right: -5px; width: 15px; height: 15px; cursor: nwse-resize; }
.jn-pega.ne { top: -5px; right: -5px; width: 15px; height: 15px; cursor: nesw-resize; }
.jn-pega.so { bottom: -5px; left: -5px; width: 15px; height: 15px; cursor: nesw-resize; }
.jn.cheia .jn-pega { display: none; }
/* O canto de baixo à direita ganha o risquinho de sempre: é o único
   que precisa ser ANUNCIADO, porque é onde as pessoas procuram. */
.jn-pega.se::after {
  content: ''; position: absolute; right: 5px; bottom: 5px; width: 9px; height: 9px;
  background: linear-gradient(-45deg, var(--tinta) 0 1.5px, transparent 1.5px 4px,
                              var(--tinta) 4px 5.5px, transparent 5.5px);
  opacity: .35; transition: opacity .16s var(--ease);
}
.jn:hover .jn-pega.se::after { opacity: .85; }
/* Enquanto se mede, nada de transição: a borda tem que colar no cursor. */
.jn.medindo { transition: none; }

/* --- as telas do app morando dentro da janela ---
   Elas foram desenhadas pra ocupar a janela do navegador inteira:
   position fixed, 100vh, respiro de tela cheia. Aqui dentro tudo isso
   vira "o tamanho do meu pai". */
.jn-corpo > .app-conteudo, .jn-corpo > .screen.hospedada {
  display: flex; flex-direction: column;
  position: static; inset: auto;
  min-height: 0; height: auto; width: 100%;
  padding: 0; margin: 0; max-width: none;
}
.jn-corpo > .screen.hospedada { animation: none; }
.jn-corpo > #screen-room.hospedada { height: 100%; }
.jn-corpo > #screen-friends.hospedada { height: 100%; padding-bottom: 0; }
.jn-corpo .friends-page, .jn-corpo .profile-page { max-width: none; }
.jn-corpo .lobby { max-width: none; margin: 0; padding: 20px 24px 26px; }
.jn-corpo .app-pad { padding: 18px 20px 22px; }
/* O topo flutuante das telas antigas some DE PARTES, não inteiro.
   Escondi ele todo de uma vez e levei junto o "Sair" e o "Moderação",
   que moram ali no perfil e não existem em nenhum outro lugar — quem
   entrava na conta não tinha mais como sair dela. O que é redundante
   dentro da janela é só isto: o botão de voltar (o × da barra faz o
   mesmo), o título (a barra já diz) e o sino e o avatar (moram no
   dock). O resto FICA, porque é ação que não se repete em lugar
   nenhum. */
.jn-corpo .float-nav {
  position: static; background: none;
  padding: 12px 18px 0; min-height: 0;
}
.jn-corpo .float-nav .js-back-lobby,
.jn-corpo .float-nav .page-title,
.jn-corpo .float-nav .js-bell,
.jn-corpo .float-nav .js-profile { display: none; }
/* Sobrando só as ações, elas vão pra direita. */
.jn-corpo .float-nav .spacer { flex: 1; }
/* A barra fica vazia em quem não tem ação nenhuma (amigos): sem isto
   sobra uma faixa de respiro no alto sem nada dentro. */
.jn-corpo .float-nav:not(:has(.btn:not(.js-back-lobby):not([hidden]))) { display: none; }

/* --- animações: abrir, fechar, minimizar, restaurar --- */
/* --- abrir, fechar, minimizar ---
   Nada disso é keyframe fixo, e é essa a diferença. Antes toda janela
   crescia do próprio centro com um fade: bonito uma vez, mas sem
   relação nenhuma com o que você tinha acabado de clicar — a janela
   simplesmente APARECIA, e seu olho tinha que procurar de novo onde
   ela nasceu.

   Agora ela nasce DE ONDE VEIO. O JS mede a caixa do ícone (ou do
   botão do dock) que você clicou, mede a caixa final da janela, e
   anima de uma pra outra. O ícone vira a janela. Fechar faz o
   caminho de volta, e minimizar mira no dock.

   Por isso os valores vivem no JS e não aqui: cada abertura tem uma
   origem diferente, e keyframe não sabe disso. Aqui fica só o que é
   igual pra todas — a curva e o que acontece durante o voo. */
.jn.voando {
  pointer-events: none;
  /* Sombra some no voo: sombra dura acompanhando uma escala fica
     grossa de um lado e fina do outro, e denuncia o truque. */
  box-shadow: none !important;
  /* O conteúdo não deve ser lido durante o movimento: fica um borrão
     de texto esticado que suja a animação inteira. */
  will-change: transform, opacity;
}
.jn.voando .jn-corpo { opacity: .55; }
/* Enquanto a janela voa, a barra fica nítida: é ela que dá a leitura
   de "esta caixa é a janela tal", e é a parte que o olho segue. */
.jn.voando .jn-barra { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .jn, .jn.cheia { transition: none; }
}

/* --- a bandeja de minimizadas, no dock --- */
.dock-bandeja { display: flex; align-items: center; gap: 4px; margin-left: 4px; }
.dock-min {
  max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 7px 10px; cursor: pointer;
  background: var(--papel); color: var(--text);
  border: 1.5px solid var(--tinta); border-radius: 0;
  font: inherit; font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  animation: bandejaEntra .2s var(--duro) both;
}
@keyframes bandejaEntra {
  from { opacity: 0; transform: translateY(6px) scale(.9); }
}
.dock-min:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
/* Aqui havia um ponto vermelho embaixo do app aberto. Saiu: no dock do
   sistema ele funciona porque os apps ficam abertos por horas e o
   ponto é a única pista disso. Aqui a janela está NA TELA, visível,
   um palmo acima do ícone — o ponto não contava nada que os olhos já
   não vissem, e virava mais um vermelho competindo com o aviso do
   sino, que é o único que precisa ser notado. */

/* --- o painel de tela cheia do modo lista ---
   Mesma régua das outras telas cheias: barra no topo com o voltar e o
   nome, e o conteúdo numa coluna com teto de largura. Sem teto, a
   lista de avisos esticaria de ponta a ponta num monitor largo e cada
   linha viraria um fio de dois mil pixels. */
#screen-painel.active { display: flex; flex-direction: column; min-height: 100vh; }
.painel-corpo {
  flex: 1; width: 100%; max-width: 720px; margin: 0 auto;
  padding: 4px 26px 60px;
}
.painel-corpo > .app-conteudo { display: block; }
@media (max-width: 900px) { .painel-corpo { padding: 4px 16px 40px; } }

/* ============================================================
   LIXEIRA — a faxina com seleção
   ============================================================ */
.lx-lede { margin: 0 0 14px; font-size: 13.5px; color: var(--text-dim); line-height: 1.5; }
.lx-lede strong { color: var(--text); }
.lx-grupo { margin-bottom: 18px; }
.lx-grupo h4 {
  margin: 0 0 2px; font-family: var(--font-display); font-weight: 400;
  font-size: 13px; text-transform: uppercase; letter-spacing: .02em;
}
.lx-nota {
  margin: 0 0 8px; font-family: var(--font-serif); font-style: italic;
  font-size: 12.5px; color: var(--text-dim); line-height: 1.45;
}
.lx-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 6px; cursor: pointer;
  border-bottom: 1px solid var(--divisor);
}
.lx-item:hover { background: rgba(127, 127, 127, .12); }
.lx-item input { accent-color: var(--accent); width: 1.05em; height: 1.05em; flex: none; }
.lx-arte {
  width: 46px; height: 26px; flex: none; overflow: hidden;
  border: 1.5px solid var(--tinta); background: var(--surface-2);
  display: grid; place-items: center; color: var(--text-dim);
}
.lx-arte.redonda { width: 26px; border-radius: 50%; }
.lx-arte img { width: 100%; height: 100%; object-fit: cover; }
.lx-nome { font-size: 13.5px; font-weight: 600; }
.lx-rodape {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding-top: 12px; border-top: 2px solid var(--tinta);
  position: sticky; bottom: 0; background: var(--surface);
}
.lx-todos { display: flex; align-items: center; gap: 7px; cursor: pointer; font-size: 13px; }
.lx-todos input { accent-color: var(--accent); }
.lx-rodape .btn { width: auto; }

/* ============================================================
   CELULAR — a arrumação livre vira grade automática
   ------------------------------------------------------------
   Posição livre com o dedo numa tela de 375px briga com a rolagem e
   sai frustrante. Os mesmos ícones, arrumados sozinhos: o JS continua
   escrevendo left/top, e o position:static aqui simplesmente ignora.
   ============================================================ */
@media (max-width: 900px) {
  .lobby-watermark { padding-bottom: 70px; }

  .desk-area {
    display: grid; align-content: start;
    grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
    gap: 16px 4px;
    padding: 18px 10px 10px;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
  }
  .desk-icone { position: static; width: auto; }
  .di-arte { width: 78px; height: 44px; }
  .desk-friend .di-arte { width: 50px; height: 50px; }

  .desk-dock {
    align-self: stretch; margin-bottom: 0;
    justify-content: space-around; gap: 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    box-shadow: none;
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
  }
  .dock-app { width: 56px; height: 48px; }
  /* Sem hover no toque, o balão só atrapalharia. */
  .dock-app .dock-label { display: none; }

  /* A janela toma a tela: não há espaço pra ver o desktop atrás. */
  .desk-janela {
    left: 0; top: 0; translate: none;
    width: 100%; max-height: 100%; height: 100%;
    border: 0; box-shadow: none;
  }
  .jn-corpo .lobby { padding: 16px 14px 22px; }
}

@media (prefers-reduced-motion: reduce) {
  .desk-janela { animation: none; }
  .desk-icone .di-arte, .dock-app { transition: none; }
}
.float-nav .btn { flex-shrink: 0; }
.page-title {
  font-family: var(--font-display); font-size: 16px; font-weight: 400;
  letter-spacing: -.01em; margin-left: 4px;
}

/* Avatar clicável que leva ao perfil */
.avatar-btn {
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--border);
  background: var(--surface-2); cursor: pointer; padding: 0; overflow: hidden;
  display: grid; place-items: center; font-size: 12px; font-weight: 600; color: #fff;
  transition: border-color .18s var(--ease), transform .12s var(--ease);
  flex-shrink: 0;
}
.avatar-btn:hover { border-color: var(--accent-claro); transform: translateY(-1px); }
.avatar-btn:active { transform: scale(.94); }
.avatar-btn img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar-btn { position: relative; }

.lobby-scroll { flex: 1; position: relative; overflow: hidden; }

/* ---- Marca d'água "The LOBBY": bem atrás, com respiro lento ---- */
/* A marca É o fundo do lobby: enorme, atrás dos jogos, mas legível
   o bastante pra se entender que é o nome do app. */
/* Caixa que ocupa a tela e RECORTA o excesso. Sem ela, o texto
   gigante estourava a largura e criava rolagem horizontal. */
/* A marca mora numa FAIXA no topo, onde nada opaco passa por cima.
   Centralizada no meio da tela ela ficava 100% atrás dos cards e só
   apareciam fragmentos nos vãos — parecia sujeira, não o nome do app.
   Aqui ela é lida por inteiro, e os jogos rolam por cima dela. */
/* A caixa cobre a tela toda porque o nome VIAJA: começa no topo e vai
   se encaixar na coluna da esquerda. Com a faixa antiga de 260px ele
   seria cortado no meio do caminho. O overflow segue evitando que o
   texto gigante crie rolagem lateral. */
/* No DESKTOP o papel de parede é a marca escrita de verdade, não o
   nome montado com fonte. O #wmInner continua existindo e sendo
   montado pelo app.js — o warp.js clona o SVG dele pro efeito de
   transição —, só que aqui ele fica invisível e quem aparece é o
   vetor. Assim a parede combina com a marca da telinha sem mexer numa
   linha de JS. */
#screen-desktop .lobby-watermark {
  /* Estava apagada demais pra ser marca — lia como sujeira no fundo.
     Subiu de .10 pra .26 no claro; no escuro sobe mais ainda, logo
     abaixo, porque tinta clara sobre preto sempre pesa menos que
     tinta escura sobre papel. */
  --wm-op: .26;
  /* Respiro próprio, e não o wmBreathe de cima. Aquele vai de .82 a 1
     porque quem desbotava a marca era o .wm-inner, por dentro — e o
     .wm-inner aqui está escondido. Sem esta troca a parede acendia
     inteira e comia os ícones. */
  animation: wmRespiroDesk 22s ease-in-out infinite;
  opacity: var(--wm-op);
}
@keyframes wmRespiroDesk {
  0%, 100% { opacity: calc(var(--wm-op) * .75); }
  50%      { opacity: var(--wm-op); }
}
#screen-desktop .wm-inner { display: none; }

/* --- A PAREDE: a marca vetorizada, parada ---
   Uma máscara e uma cor, e acabou. Branco no escuro, tinta no claro:
   branco cravado nos dois deixaria a marca invisível sobre o papel
   creme, que é a mesma cor pintada por cima da mesma cor. */
#screen-desktop .parede {
  width: min(58vw, 74%); aspect-ratio: 1475 / 339;
  background-color: var(--text);
  -webkit-mask: url('/marca-banke-nome.svg') center / contain no-repeat;
  mask: url('/marca-banke-nome.svg') center / contain no-repeat;
}
html[data-tema="escuro"] #screen-desktop .parede { background-color: #fff; }

@media (max-width: 900px), (pointer: coarse) {
  #screen-desktop .parede { width: min(72vw, 80%); }
}
/* No escuro o mesmo valor some: tinta clara sobre preto pede mais
   presença, do mesmo jeito que o selo da tela de entrada. */
html[data-tema="escuro"] #screen-desktop .lobby-watermark { --wm-op: .55; }
@media (prefers-reduced-motion: reduce) {
  #screen-desktop .lobby-watermark { animation: none; }
}

/* A marca gigante é o PAPEL DE PAREDE do desktop. Ela morava colada no
   topo, que era o respiro do lobby antigo; no desktop é exatamente
   onde nasce a primeira fileira de ícones, e o nome atravessava os
   rótulos. Agora fica no meio da área, atrás de todo mundo, e o
   respiro de baixo reserva a faixa do dock. */
.lobby-watermark {
  position: fixed; inset: 0; z-index: 0;
  display: flex; align-items: center; justify-content: center;
  padding-bottom: 96px;
  overflow: hidden; pointer-events: none; user-select: none;
}
/* O respiro fica no PAI e a rolagem no FILHO.
   Antes os dois disputavam a mesma propriedade no mesmo elemento — e
   animação CSS vence style inline, então o fade da rolagem nunca
   aparecia. Separados, as opacidades se multiplicam e ambos funcionam. */
.lobby-watermark { animation: wmBreathe 22s ease-in-out infinite; }

.wm-inner {
  display: block;
  opacity: .30;   /* valor de primeira pintura; depois quem manda é o scroll */
  transform-origin: center center;
  will-change: opacity, transform;
  /* Suaviza quando a rolagem para, sem atrasar o acompanhamento. */
  transition: opacity .1s linear, transform .1s linear;
  /* O halo mora no container, não em cada letra: um filtro só em vez de
     oito recalculando a cada quadro da rolagem. */
  filter: drop-shadow(0 0 40px rgba(255, 255, 255, .10));
}
/* Largura calibrada pra palavra INTEIRA caber na faixa livre do topo.
   Grande demais e o "Lobby" desce pra trás dos cards; é o que fazia
   só sobrar pedaço do nome aparecendo nos vãos. */
.wm-inner .mk {
  display: block; width: clamp(240px, 40vw, 560px); height: auto;
  overflow: visible;
}
/* A marca d'agua agora e texto, nao caminho: pinta com fill direto. */
.wm-inner .mk-arte text,
.wm-inner .wm-regua {
  font-family: var(--font-display); font-size: 235px; font-weight: 400;
  letter-spacing: -.045em; text-transform: uppercase; fill: var(--text);
  dominant-baseline: alphabetic;
}
/* A regua so existe pra ser medida — nunca deve pintar. */
.wm-inner .wm-regua { visibility: hidden; }

/* Cada letra é solta: ao rolar, escorrega no seu ritmo. Em SVG o eixo
   do transform é o canto do viewBox, não a letra — fill-box devolve o
   giro pro centro de cada desenho. */
.wm-ch {
  transform-box: fill-box; transform-origin: center;
  will-change: transform;
  transition: transform .12s linear;
}
/* Respiro: escala e brilho de leve. Longo o bastante pra não distrair. */
/* Opacidade alta de propósito: os cards são opacos, então a marca só
   aparece nas margens e nos vãos — subir aqui não prejudica a leitura
   de nada, e é o que faz dar pra reconhecer o nome. */
/* Só opacidade aqui: a escala agora é da rolagem, no filho. */
@keyframes wmBreathe {
  0%, 100% { opacity: .82; }
  50%      { opacity: 1; }
}
.lobby-scroll > .lobby { position: relative; z-index: 1; }

/* Seções do painel de amigos + busca */
.friends-section {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--text-dim); font-weight: 600; margin: 14px 4px 6px;
  display: flex; align-items: center; gap: 8px;
}
.friends-section:first-child { margin-top: 4px; }
.fs-count { background: var(--surface-2); border-radius: 20px; padding: 1px 7px; font-size: 10px; letter-spacing: 0; }
.fi-sub.on { color: #7ce6a0; }
.search-wrap.sm { margin: 0 0 6px; }
.search-wrap.sm .search { padding-top: 9px; padding-bottom: 9px; font-size: 13px; }

/* ============================================================
   SALAS DE JOGO (lobby)
   ============================================================ */
/* padding-right maior: abre espaço pra barra vertical da direita */
/* O respiro de cima é o palco da marca d'água: ela cabe inteira aí,
   em vez de ficar metade escondida atrás dos cards. */
.lobby { max-width: 1080px; margin: 0 auto; padding: 232px 104px 60px 22px; }
.lobby h2 { font-family: var(--font-display); font-size: 24px; margin: 0 0 6px; font-weight: 400; letter-spacing: -.02em; }

.owned-banner {
  margin-top: 15px; padding: 12px 15px; border-radius: var(--r-ctrl); font-size: 13.5px;
  background: var(--surface); border: 1px solid var(--border); color: var(--text-muted);
}
.game-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 16px; margin-top: 18px; }

/* --- Card no estilo vitrine: a arte É o card --- */
.game-card {
  position: relative; cursor: pointer; overflow: hidden;
  border-radius: var(--r-card); border: 1px solid var(--border);
  /* 4/3 e não 16/10: a capa da Steam é larga (2.14) e o logo dela fica
     centralizado na vertical. Card mais alto = logo sobe e sai de cima
     da faixa onde escrevemos o nome. */
  background: var(--surface); aspect-ratio: 4 / 3;
  transition: border-color .22s var(--ease), transform .22s var(--ease);
  animation: cardIn .34s var(--ease) both;
}
@keyframes cardIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* --- O QUE O NAVEGADOR PODE PULAR ---
   A grade tem 63 cards e, numa tela comum, uns 60 estão FORA da vista.
   Cada um deles carrega uma segunda cópia da capa, desfocada em 6px e
   recortada por uma máscara em degradê — o borrão que dá legibilidade
   ao nome. Desfoque e máscara são das contas mais caras que existem
   pro navegador, e ele fazia as 63, inclusive as sessenta que ninguém
   estava vendo. Era isso que engasgava ao abrir a tela clássica: não é
   o JavaScript (medi, nenhuma tarefa longa) — é desenho.

   content-visibility: auto resolve na raiz: o navegador pula estilo,
   layout e pintura do que está fora de vista, e só faz o trabalho
   quando o card chega perto da janela. O desenho continua idêntico.

   O contain-intrinsic-size é obrigatório junto: sem ele o card pulado
   vira altura zero, a página encolhe, a barra de rolagem pula e o
   resto da grade dança na tela. 195x260 é a medida real de um card. */
.game-card {
  content-visibility: auto;
  contain-intrinsic-size: 195px 260px;
}

/* --- Cards que se materializam ao entrar em cena ---
   O card sobe, ganha nitidez e escala. O --atraso escalona por coluna,
   então a fileira parece ser montada da esquerda pra direita. */
/* A transição fica no estado BASE, não no revelado — assim ela vale nos
   dois sentidos e o card também se desfaz ao sair de cena, em vez de
   sumir de estalo. É o que torna o efeito reversível ao subir. */
/* A entrada dos cards, SEM BORRÃO.
   O blur saiu de vez. Tentei amaciar (de 6px pra 3px, chegada mais
   longa, curva desacelerando no fim) e continuava se anunciando: por
   mais suave que fosse a virada, o olho pega o momento em que a
   imagem sai de desfocada pra nítida, porque nitidez é justamente o
   que a vista procura sozinha. Não é questão de calibrar melhor — é o
   efeito errado pra uma grade de capas, onde a capa É a informação.

   Sobrou o essencial: aparecer. Um esmaecer curto e três pixels de
   subida, o bastante pra a fileira não pipocar pronta na tela e leve
   o bastante pra ninguém reparar que existe. */
.game-card.por-revelar {
  opacity: 0;
  transform: translateY(6px);
  animation: none; /* desliga o cardIn: quem revela agora é o observer */
  transition:
    opacity .45s var(--ease) var(--atraso, 0ms),
    transform .45s var(--ease) var(--atraso, 0ms),
    border-color .2s var(--ease);
}
.game-card.por-revelar.revelado {
  opacity: 1;
  transform: none;
}@media (prefers-reduced-motion: reduce) {
  .game-card.por-revelar { opacity: 1; transform: none; filter: none; transition: none; }
}
.game-card:hover { border-color: var(--border-hover); transform: translateY(-4px); }
.game-card.selected { border-color: var(--accent-claro); }
.game-card.selected::after {
  content: ''; position: absolute; inset: 0; z-index: 3;
  border-radius: var(--r-card); box-shadow: inset 0 0 0 2px var(--accent-claro);
}

.game-card .cover { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-dim); background: var(--surface-2); }
.game-card .cover img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .5s var(--ease), filter .3s var(--ease);
  filter: saturate(.92);
}
.game-card:hover .cover img { transform: scale(1.06); filter: saturate(1.05); }

/* ------------------------------------------------------------
   O BORRÃO DA LEITURA
   ------------------------------------------------------------
   O que estava aqui era uma LÂMINA: uma caixa colada no rodapé do
   card, com backdrop-filter pra desfocar a arte por trás. Duas coisas
   davam errado nisso, e as duas pelo mesmo motivo — uma caixa tem
   beirada.

   A primeira era de olho. Onde a caixa começava, o desfoque começava
   TAMBÉM, de uma linha pra outra: em cima nítido, embaixo borrado,
   sem nada no meio. Somado ao fio claro que a lâmina tinha de
   propósito, o resultado era uma régua atravessando a capa do jogo.
   Não dá pra amaciar isso ajustando o blur — por menor que ele fique,
   a virada continua acontecendo num pixel só.

   A segunda era de máquina. backdrop-filter obriga o navegador a
   reler o que está por trás e refiltrar a cada vez que a camada é
   composta, e a grade tem sessenta e tantos cards ao mesmo tempo.
   Enquanto isso é só uma grade parada, passa; mas TODA troca de tela
   aqui atravessa um fade de opacidade (.screen.active), e um fade por
   cima de sessenta desfoques de fundo obriga os sessenta a serem
   refeitos quadro a quadro. Era esse o engasgo ao abrir um mural pela
   lista e ao voltar dele.

   A troca: o borrão deixa de ser um filtro de fundo e vira uma SEGUNDA
   CÓPIA da própria capa, desfocada de uma vez e escondida atrás de uma
   máscara em degradê. Como a máscara é um degradê, a passagem de
   nítido pra borrado acontece ao longo de uns 50 pixels em vez de numa
   linha — não existe mais onde o borrão "começa". E como a cópia é
   imagem parada, o navegador desenha uma vez e guarda: o fade de tela
   volta a custar o que um fade custa.
   ------------------------------------------------------------ */
.game-card .cover img.cover-borrao {
  position: absolute;
  /* Maior que o card de propósito. Desfocar puxa transparência pra
     dentro pelas bordas, e sem essa folga o pé do card ficaria lavado,
     com a capa nítida vazando por baixo justamente onde o borrão devia
     estar mais fechado. A sobra fica escondida pelo overflow do card. */
  left: -10%; top: -10%; width: 120%; height: 120%;
  filter: blur(6px) saturate(1.06);
  /* A máscara é o efeito inteiro. Os degraus não são lineares: sobem
     devagar no começo, correm no meio e assentam no fim — é o que faz
     a chegada do borrão não ter um ponto de partida visível; um
     degradê linear puro deixa a beirada de cima perceptível.
     As porcentagens são da CÓPIA, que é 20% maior que o card — o card
     começa nos 8,3% dela e acaba nos 91,7%. Traduzido pra capa, a
     rampa vai do quinto de cima ao quarto quinto: some antes de
     chegar na arte lá em cima e já está fechada onde o texto senta. */
  -webkit-mask-image: linear-gradient(180deg,
    rgba(0,0,0,0) 27%, rgba(0,0,0,.12) 42%, rgba(0,0,0,.32) 50%,
    rgba(0,0,0,.58) 57%, rgba(0,0,0,.80) 63%, rgba(0,0,0,.94) 70%,
    rgba(0,0,0,1) 77%);
  mask-image: linear-gradient(180deg,
    rgba(0,0,0,0) 27%, rgba(0,0,0,.12) 42%, rgba(0,0,0,.32) 50%,
    rgba(0,0,0,.58) 57%, rgba(0,0,0,.80) 63%, rgba(0,0,0,.94) 70%,
    rgba(0,0,0,1) 77%);
  pointer-events: none;
  /* SÓ transform na transição. A regra genérica logo acima também
     anima filter, e animar filter numa camada desfocada obriga o
     navegador a refazer o desfoque a cada quadro do hover — o
     desenho fica igual e a conta é toda de novo. Movendo, ele
     reaproveita o borrão que já calculou. */
  transition: transform .5s var(--ease);
}
/* Acompanha a aproximação da capa nítida no hover: se só uma das duas
   crescesse, a borrada descolaria da nítida e o card "escorregaria".
   A regra precisa ser mais específica que a do hover genérico logo
   acima, senão aquele filter: saturate() apagaria o desfoque. */
.game-card:hover .cover img.cover-borrao { transform: scale(1.06); filter: blur(6px) saturate(1.06); }
/* Navegador sem máscara mostraria a capa inteira borrada. Melhor não
   ter borrão nenhum: o véu abaixo sozinho já segura a leitura. */
@supports not ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  .game-card .cover img.cover-borrao { display: none; }
}

/* O véu que sobrou é só ESCURECIMENTO, e vai junto com o borrão: os
   dois crescem no mesmo trecho da capa, então lêem como uma coisa só.
   Nada de degrau — os pontos acompanham a mesma subida da máscara. */
.game-card .scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg,
    rgba(var(--bg-rgb),0) 28%,
    rgba(var(--bg-rgb),.04) 40%,
    rgba(var(--bg-rgb),.14) 50%,
    rgba(var(--bg-rgb),.30) 60%,
    rgba(var(--bg-rgb),.46) 70%,
    rgba(var(--bg-rgb),.58) 82%,
    rgba(var(--bg-rgb),.62) 100%);
  transition: background .3s var(--ease);
}
/* No hover fecha um pouco mais, sem nunca chegar no chapado de antes:
   o card cresce e a arte aparece MAIS, não menos. */
.game-card:hover .scrim {
  background: linear-gradient(180deg,
    rgba(var(--bg-rgb),0) 22%,
    rgba(var(--bg-rgb),.06) 36%,
    rgba(var(--bg-rgb),.20) 47%,
    rgba(var(--bg-rgb),.42) 58%,
    rgba(var(--bg-rgb),.62) 69%,
    rgba(var(--bg-rgb),.76) 82%,
    rgba(var(--bg-rgb),.80) 100%);
}

/* Sem lâmina, sem fio de borda, sem fundo próprio: o texto senta
   direto no degradê. Quem segura a legibilidade é o borrão atrás mais
   a sombra do texto, logo abaixo. */
.game-card .body {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0;
  padding: 11px 14px 12px;
}
/* Sem lâmina, o texto tem arte de verdade por trás — borrada, mas
   arte. A sombra é o que o mantém legível sobre qualquer capa, clara
   ou escura, sem precisar encobrir mais nada. */
.game-card .name, .game-card .tag, .game-card .count {
  text-shadow: 0 1px 2px rgba(var(--bg-rgb), .9), 0 0 10px rgba(var(--bg-rgb), .7);
}
/* O texto do card fica sobre um veu que desvanece pro FUNDO DA PAGINA
   (var(--bg)). Quando a pagina era preta, esse texto era branco. Agora
   que o fundo e papel, o veu chega no creme — e branco sobre creme
   some. Por isso a cor aqui segue o token, e nao um #fff cravado. */
.game-card .name {
  font-family: var(--font-display); font-weight: 400; font-size: 15.5px;
  letter-spacing: -.015em; margin: 0 0 3px; color: var(--text);
}
.game-card .tag {
  color: var(--text-dim); font-size: 11.5px; line-height: 1.4; margin: 0;
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
}

/* Sem cápsula em volta: só o ícone + texto direto sobre a arte. A leve
   sombra garante leitura sobre capas claras, sem a borda de pílula. */
/* Os dois números vão pras PONTAS: quantos estão no mural à esquerda,
   quantos estão online agora à direita. Antes eram uma frase só, com
   uma bolinha verde no meio fazendo as vezes de separador — e a
   bolinha lia como enfeite, não como divisão. Com uma ponta em cada
   lado, a separação é o próprio espaço.
   Cor de texto normal nos dois: o verde chamava mais atenção que o
   nome do jogo logo acima. */
.game-card .count {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-top: 7px;
  font-size: 11.5px; font-weight: 600; color: var(--text-muted);
}
.game-card .c-lado { display: inline-flex; align-items: center; gap: 5px; }
.game-card .c-lado .ic { opacity: .7; }
/* Zero online desbota: é informação, mas não é notícia. */
.game-card .c-online { opacity: .5; }
.game-card .c-online.tem { opacity: 1; color: var(--text); }
/* A bolinha verde do meio e o verde da contagem saíram: eram o
   elemento mais chamativo do card, acima do nome do jogo. Quem
   sobrevive é o .live-dot de outros lugares (chamados de squad),
   onde ele é sinal de "acontecendo agora" e não decoração. */
.live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--online); display: inline-block; }

/* As etiquetas ficam no ALTO do card, onde a capa continua nítida —
   ali não há borrão nenhum pra ajudar. Elas tinham um backdrop-filter
   próprio pra isso, e cada um deles é mais uma camada que o navegador
   relê a cada quadro. Trocado por fundo um pouco mais fechado e uma
   sombra no texto: o mesmo contraste, sem custo de composição. */
.game-card .owned-tag, .game-card .soon-tag {
  position: absolute; top: 10px; z-index: 2; font-size: 9.5px; font-weight: 600;
  border-radius: 20px; padding: 4px 9px; letter-spacing: .1em; text-transform: uppercase;
  text-shadow: 0 1px 2px rgba(0,0,0,.55);
}
.game-card .owned-tag { right: 10px; background: rgba(var(--accent-rgb),.62); color: #e6ecff; border: 1px solid rgba(var(--accent-rgb),.72); }
.game-card .soon-tag { left: 10px; background: rgba(122,78,10,.72); color: #ffd88a; border: 1px solid rgba(255,176,32,.5); }

.section-title { font-family: var(--font-display); margin: 38px 0 0; font-size: 16px; font-weight: 400; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.section-hint { font-size: 12px; color: var(--text-dim); font-weight: 400; font-family: var(--font-body); }

/* ============================================================
   SALA
   ============================================================ */
#screen-room.active { display: flex; flex-direction: column; position: fixed; inset: 0; }

/* Ambiência do jogo: capa borrada no topo, apagando pra baixo.
   Fica ATRÁS de tudo (z-index 0) e não recebe clique. O texto do chat
   nunca encosta nela — some bem antes de chegar nas mensagens. */
.room-bg {
  position: absolute; top: 0; left: 0; right: 0; height: 340px; z-index: 0;
  pointer-events: none; opacity: 0;
  background-size: cover; background-position: center;
  filter: blur(46px) saturate(1.15);
  transform: scale(1.15);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,.45) 45%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,.45) 45%, transparent 100%);
  transition: opacity .6s var(--ease);
}
.room-bg.on { opacity: .22; }

#screen-room .topbar,
#screen-room .room { position: relative; z-index: 1; }
/* A barra fica translúcida pra deixar a cor do jogo aparecer por trás.
   Sem desfoque, porém: o que passa atrás dela é a .room-bg, que já
   chega com blur(46px) de fábrica. O backdrop-filter refazia esse
   trabalho a cada composição pra não mudar nada na tela. */
#screen-room .topbar { background: rgba(var(--surface-rgb),.72); }

/* Coluna única: o mural virou painel flutuante e o chat ficou com a
   largura inteira. O position:relative é a âncora desse painel. */
/* minmax(0,1fr) e não 1fr: a trilha de grid tem min-width auto, então
   ela cresceria até caber a faixa de squads e empurraria a sala inteira
   pra fora da tela no celular. */
/* Barra lateral (salas) + chat. minmax(0,…) na coluna do chat pra ele
   poder encolher e não empurrar a barra pra fora. */
/* Uma coluna só: a trilha de salas saiu do fluxo e virou painel que
   abre no botão do topo. A conversa fica com a largura inteira, que é o
   que ela sempre quis — a coluna fixa comia 232px em toda tela, o tempo
   todo, pra uma lista que se olha de vez em quando. */
.room { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); flex: 1; min-height: 0; }
/* O painel de quem está aqui era translúcido com blur(14px). Ele abre
   EM CIMA do chat e da .room-bg — que já é uma capa borrada, mascarada
   em degradê e escalada. Desfocar de novo um fundo que já é um borrão
   obriga o navegador a reler e refiltrar a área inteira a cada
   composição, e era isso que engasgava no clique do botão de pessoas.
   É o mesmo argumento que tirou o backdrop-filter dos cards, lá em
   cima. Opaco ele fica mais legível e não custa nada. */
#screen-room .members { background: var(--surface); }

/* ---- A TELA DE CHEGADA ----
   Ocupa a área da conversa, como a de chamados. Coluna estreita e
   centrada: é uma lista pra escolher UMA coisa, e lista larga demais
   obriga o olho a atravessar a tela pra ligar o nome ao botão. */
.chegada {
  min-height: 0; overflow-y: auto;
  padding: 26px clamp(16px, 4vw, 40px) 40px;
}
.chegada-topo { max-width: 560px; margin: 0 auto 22px; }
.chegada-topo h3 {
  margin: 0 0 6px; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(19px, 2.4vw, 26px); line-height: 1.15;
}
.chegada-sub { margin: 0; color: var(--text-dim); font-size: 14px; line-height: 1.5; }
.chegada-busca { display: block; max-width: 560px; margin: 0 auto 18px; }
.chegada-busca input {
  width: 100%; padding: 11px 13px; border-radius: 0;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--divisor); font: inherit; font-size: 14px;
}
.chegada-busca input::placeholder { color: var(--text-dim); opacity: 1; }
.chegada-busca input:focus { border-color: var(--accent-claro); }
.chegada-secao {
  max-width: 560px; margin: 22px auto 8px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-dim);
}
.chegada-lista { max-width: 560px; margin: 0 auto; display: grid; gap: 8px; }
.chegada-vazio {
  max-width: 560px; margin: 0 auto; padding: 4px 2px;
  color: var(--text-dim); font-size: 13.5px;
}
.chegada-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--border);
}
.chegada-item .ci-ic { flex: none; color: var(--text-dim); display: grid; place-items: center; }
/* flex:1 e min-width:0 juntos: sem os dois o texto colapsa pra zero e
   o botão (que herda width:100% do .btn) come a linha inteira. */
.chegada-item .ci-texto { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
.ci-nome {
  font-weight: 600; font-size: 15px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A informação por extenso, e o "online agora" com a cor de quem está
   acontecendo — é a parte que decide em qual conversa entrar. */
.ci-meta { font-size: 12.5px; color: var(--text-dim); }
.ci-meta b { font-weight: 600; color: var(--online); }
/* Seletor com o pai junto pra ganhar do width:100% do .btn genérico. */
.chegada-item .ci-botao { margin-left: auto; flex: none; width: auto; white-space: nowrap; }

@media (max-width: 560px) {
  /* Numa tela estreita o botão desce pra baixo do nome em vez de
     espremer os dois na mesma linha. */
  .chegada-item { flex-wrap: wrap; }
  .chegada-item .ci-botao { margin-left: 0; width: 100%; }
}

/* ---- O PAINEL DE SALAS ----
   Mesma família visual do painel de "quem está aqui": caixa flutuante,
   fio em volta, sombra funda. Ancorado à DIREITA porque é de lá que ele
   vem — o botão que o abre mora no canto direito da barra de cima, e
   painel que nasce longe do botão faz a pessoa procurar. */
.salas-painel {
  position: absolute; z-index: 21; top: 8px; right: 12px;
  width: min(320px, calc(100% - 24px));
  max-height: min(72vh, 560px);
  display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: 0 24px 60px rgba(0,0,0,.6);
  animation: muralIn .18s var(--ease) both;
}
.sp-titulo {
  flex: none; display: flex; align-items: center; gap: 8px;
  margin: 0; padding: 14px 12px 10px 16px;
  font-family: var(--font-display); font-weight: 400; font-size: 15px;
  text-transform: uppercase; letter-spacing: .04em;
}
.sp-busca { flex: none; display: block; padding: 0 16px 10px; }
.sp-busca input {
  width: 100%; padding: 9px 11px; border-radius: 0;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--divisor); font: inherit; font-size: 13.5px;
}
.sp-busca input::placeholder { color: var(--text-dim); opacity: 1; }
.sp-busca input:focus { border-color: var(--accent-claro); }
.sp-vazio {
  margin: 0; padding: 4px 16px 14px;
  font-size: 13px; color: var(--text-dim);
}

/* O pé do painel: a saída do mural, separada por um fio do resto.
   Fio porque ela não é irmã das outras linhas — as de cima levam a uma
   conversa, esta te tira do jogo. */
.sp-pe {
  flex: none; padding: 10px 16px 14px;
  border-top: 1px solid var(--divisor);
}
.sp-pe .btn { width: 100%; margin: 0; }

/* O que os números querem dizer, escrito. "5 aqui · 1 online" no lugar
   de uma bolinha e dois números soltos. O "online" é o que responde
   "onde tem gente agora", então é ele que leva a cor. */
.ri-meta {
  margin-left: auto; flex: none; padding-left: 10px;
  font-size: 11.5px; color: var(--text-dim); white-space: nowrap;
}
.ri-meta b { font-weight: 600; color: var(--online); }
.rail-item.active .ri-meta { color: rgba(255,255,255,.72); }
.rail-item.active .ri-meta b { color: #fff; }

/* ---- A lista dentro do painel: sempre em pé, em qualquer tamanho ---- */
.room-rail {
  display: flex; flex-direction: column; gap: 4px; min-height: 0;
  padding: 0 10px 12px; overflow-y: auto;
  background: none;
}
.rail-section { margin-bottom: 8px; }
.rail-label {
  display: block; font-size: 10.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .1em; color: var(--text-dim); margin: 6px 8px 6px;
}
.rail-list { display: flex; flex-direction: column; gap: 2px; }
.rail-item {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: none; border: none; color: var(--text-muted); cursor: pointer;
  font-family: inherit; font-size: 13.5px; padding: 8px 10px; border-radius: 8px;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.rail-item .ic { flex-shrink: 0; opacity: .8; }
.rail-item:hover { background: var(--surface-2); color: var(--text); }
.rail-item.active { background: var(--accent); color: #fff; }
.rail-item.active .ic { opacity: 1; }
.ri-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ri-count { font-size: 11px; opacity: .7; flex-shrink: 0; }
/* Chamados com chamado aberto: âmbar chamando atenção. */
.rail-item.highlight:not(.active) { color: var(--text); }
.rail-item.highlight:not(.active) .ri-count {
  background: var(--match); color: #1a1206; border-radius: 10px; padding: 0 6px; font-weight: 700; opacity: 1;
}
.rail-create { margin-top: auto; width: 100%; }

/* ---- Cabeçalho do chat: sala atual + ações ---- */
.chat-header {
  display: flex; align-items: center; gap: 9px; flex-shrink: 0;
  padding: 11px 20px; border-bottom: 1px solid var(--border);
  background: rgba(var(--bg-rgb),.4);
}
.ch-ic { color: var(--text-muted); display: inline-grid; place-items: center; }
.ch-name { font-family: var(--font-display); font-weight: 400; font-size: 15px; }
.ch-meta { font-size: 12px; color: var(--text-dim); }
.chat-header .spacer { flex: 1; }
.chat-header .btn { margin: 0; }
/* Mensagens sobre fundo sólido: legibilidade acima da estética. */
#screen-room .chat { background: transparent; }
#screen-room .messages { background: linear-gradient(180deg, rgba(var(--bg-rgb),.55) 0%, var(--bg) 260px); }

.online-pill { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-muted); }
.online-pill::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--online); }
.online-pill.zero { color: var(--text-dim); }
.online-pill.zero::before { background: #3a3f4c; }

/* Painel suspenso, não mais coluna fixa: sai de baixo do topo, flutua
   por cima da conversa e some ao fechar. A conversa fica com a tela
   inteira quando ninguém pediu pra ver quem está aqui. */
.members {
  position: absolute; z-index: 20; top: 8px; left: 12px;
  width: min(340px, calc(100% - 24px)); max-height: min(60vh, 460px);
  border: 1px solid var(--border); border-radius: var(--r-card);
  padding: 16px; overflow-y: auto;
  background: var(--surface);
  box-shadow: 0 24px 60px rgba(0,0,0,.6);
  animation: muralIn .18s var(--ease) both;
}
@keyframes muralIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.members-title { font-family: var(--font-display); margin: 0 0 6px; display: flex; align-items: center; gap: 9px; font-size: 15px; font-weight: 400; }
.members-title .spacer { flex: 1; }
.members-title .icon-btn { width: 28px; height: 28px; }
#btnLeaveSquad { flex: 0 0 auto; white-space: nowrap; }
.badge { background: var(--accent); color: #fff; border-radius: 20px; padding: 2px 9px; font-size: 11.5px; font-weight: 600; font-family: var(--font-body); }
.members-note { font-size: 11.5px; color: var(--text-dim); line-height: 1.5; margin: 0 0 14px; }

#memberList { list-style: none; padding: 0; margin: 0; }
#memberList li {
  padding: 9px 10px; border-radius: var(--r-ctrl); margin-bottom: 4px;
  display: flex; align-items: center; gap: 11px;
  transition: background .18s var(--ease);
}
#memberList li:hover { background: var(--surface-2); }
#memberList li.m-row { cursor: pointer; }
#memberList li.m-row:focus-visible { background: var(--surface-2); outline: 2px solid var(--accent); outline-offset: -2px; }

/* Squad no celular: são 2 a 10 pessoas, então a lista deita e vira uma
   fileira que rola — o painel não come a conversa inteira. No desktop
   ela continua em pé, que é onde sobra altura. */
#memberList.deitada { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
#memberList.deitada li {
  flex-direction: column; align-items: center; text-align: center;
  gap: 6px; min-width: 84px; margin: 0; padding: 10px 8px;
  background: var(--surface-2);
}
#memberList.deitada .m-info { flex: none; width: 100%; }
#memberList.deitada .m-nick { justify-content: center; font-size: 12px; }
#memberList.deitada .m-since { font-size: 10px; }
#memberList.deitada .row-btn { opacity: 1; padding: 3px; }
@media (min-width: 701px) {
  /* No desktop sobra altura: a lista de squad volta a ficar em pé. */
  #memberList.deitada { display: block; overflow-x: visible; }
  #memberList.deitada li {
    flex-direction: row; align-items: center; text-align: left;
    gap: 11px; min-width: 0; margin-bottom: 4px; padding: 9px 10px;
    background: transparent;
  }
  #memberList.deitada .m-nick { justify-content: flex-start; font-size: 13.5px; }
  #memberList.deitada .m-since { font-size: 11px; }
  #memberList.deitada .row-btn { opacity: 0; padding: 5px; }
  #memberList.deitada li:hover .row-btn { opacity: 1; }
}
#memberList .m-info { flex: 1; min-width: 0; }
#memberList .m-nick { font-weight: 500; font-size: 13.5px; display: flex; align-items: center; gap: 6px; }
#memberList .m-nick .off { color: var(--text-dim); font-weight: 400; font-size: 10.5px; }
#memberList .m-since { font-size: 11px; color: var(--text-dim); margin-top: 1px; }
#memberList .row-btn {
  background: transparent; border: none; color: var(--text-dim); cursor: pointer;
  padding: 5px; border-radius: 6px; opacity: 0;
  transition: opacity .18s var(--ease), color .18s var(--ease), background .18s var(--ease);
  display: grid; place-items: center;
}
#memberList li:hover .row-btn { opacity: 1; }
#memberList .row-btn:focus-visible { opacity: 1; }
#memberList .row-btn:hover { color: var(--text); background: var(--surface-2); }
#memberList .row-btn.report:hover { color: var(--danger); }

/* --- avatares --- */
.avatar {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12.5px; font-weight: 600; color: #fff; position: relative;
}
.avatar.sm { width: 27px; height: 27px; font-size: 11px; }
/* A foto cobre as iniciais em vez de ficar ao lado delas: assim, se o
   CDN não entregar a imagem, o onerror tira o <img> e as iniciais que
   estavam embaixo aparecem sozinhas. */
.avatar img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block;
}
.avatar .dot {
  position: absolute; right: -1px; bottom: -1px; width: 10px; height: 10px;
  border-radius: 50%; background: var(--online); border: 2.5px solid var(--surface);
}
.avatar.sm .dot { width: 8px; height: 8px; }

/* ============================================================
   CHAMADOS DE SQUAD
   ============================================================ */
/* Corpo do Squad na aba Chamados: rola sozinho e ocupa a altura toda,
   no lugar das mensagens. Os cards viram uma grade em vez de fileira
   apertada com rolagem lateral. */
.calls-view { flex: 1; min-height: 0; overflow-y: auto; padding: 20px 24px 24px; }
.calls-view-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; margin-bottom: 18px;
}
.calls-view-head h3 { font-family: var(--font-display); margin: 0; font-size: 18px; font-weight: 400; letter-spacing: -.01em; }
.calls-view-sub { color: var(--text-dim); font-size: 13px; margin: 4px 0 0; }
.calls-view-head .btn { width: auto; margin: 0; flex-shrink: 0; }
.calls-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; align-items: start; }
.calls-grid:empty { display: none; }
.calls-empty { color: var(--text-dim); font-size: 13.5px; line-height: 1.6; margin: 8px 2px 0; max-width: 42ch; }

.call-card {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-card);
  padding: 14px 16px;
  animation: cardIn .3s var(--ease) both;
  transition: border-color .2s var(--ease);
}
.call-card.mine { border-color: var(--accent-claro); }
.call-card.almost { border-color: rgba(255,176,32,.5); }
.call-slots { font-family: var(--font-display); font-size: 27px; font-weight: 400; letter-spacing: -.04em; line-height: 1; }
.call-slots .total { color: var(--text-dim); font-size: 17px; font-weight: 500; }
.call-slots-label { font-size: 10px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .12em; margin-top: 4px; }
.call-owner { font-size: 12.5px; color: var(--text-muted); margin-top: 10px; display: flex; align-items: center; gap: 7px; }
.call-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; }
.call-tag {
  font-size: 10.5px; padding: 3px 8px; border-radius: 20px;
  background: var(--surface); border: 1px solid var(--border); color: var(--text-dim);
  display: inline-flex; align-items: center; gap: 4px;
}
.call-actions { margin-top: 11px; }
.call-actions .btn { width: 100%; margin: 0; padding: 8px; font-size: 13px; }
.call-expires { font-size: 10px; color: var(--text-dim); margin-top: 7px; text-align: center; }

/* Quem está no chamado. O dono vê um X pra tirar alguém. */
.call-people { display: flex; gap: 5px; margin-top: 9px; flex-wrap: wrap; }
.call-person { position: relative; display: inline-flex; }
.kick-btn {
  position: absolute; top: -4px; right: -4px; width: 15px; height: 15px;
  border-radius: 50%; border: none; cursor: pointer;
  background: var(--danger); color: #fff; display: grid; place-items: center;
  opacity: 0; transition: opacity .15s var(--ease), transform .12s var(--ease);
}
.call-person:hover .kick-btn, .kick-btn:focus-visible { opacity: 1; }
.kick-btn:hover { transform: scale(1.12); }

.call-extra { display: flex; gap: 12px; justify-content: center; margin-top: 9px; flex-wrap: wrap; }
.call-extra .linkish { font-size: 11.5px; padding: 2px; }

.invite-list { max-height: 320px; margin-bottom: 4px; }
.invite-list .btn { margin: 0; width: auto; padding: 6px 12px; font-size: 12px; }

/* Aba "Squad" pulsa quando há chamado aberto — pra não passar batido. */
.space-tab.has-calls { border-color: var(--accent-claro); color: var(--text); }
.space-tab.has-calls .rt-count {
  background: var(--accent); color: #fff; border-radius: 20px;
  padding: 1px 7px; font-weight: 700; opacity: 1;
  animation: callPulse 2.4s ease-in-out infinite;
}
@keyframes callPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb),.45); }
  50%      { box-shadow: 0 0 0 6px rgba(var(--accent-rgb),0); }
}

.slot-picker { display: flex; gap: 7px; flex-wrap: wrap; }
.slot-opt {
  width: 42px; height: 42px; border-radius: var(--r-ctrl); cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  font-size: 15px; font-weight: 400; font-family: var(--font-display);
  transition: all .18s var(--ease);
}
.slot-opt:hover { border-color: var(--border-hover); transform: translateY(-1px); }
.slot-opt.selected { background: var(--accent); border-color: var(--accent-claro); }

/* ============================================================
   FAIXA DE SALAS
   ============================================================ */
/* ============================================================
   ALTERNADOR DE ESPAÇO: Geral  x  Squad
   ============================================================ */
.space-switch {
  display: flex; gap: 6px; padding: 10px 20px;
  border-bottom: 1px solid var(--border); background: rgba(var(--bg-rgb),.5);
}
.space-tab {
  display: inline-flex; align-items: center; gap: 7px;
  background: transparent; border: 1px solid transparent; color: var(--text-muted);
  border-radius: 20px; padding: 7px 15px; font-size: 13px; font-weight: 500;
  cursor: pointer; font-family: inherit; transition: all .18s var(--ease);
}
.space-tab:hover { color: var(--text); background: var(--surface-2); }
.space-tab.active { background: var(--accent); border-color: var(--accent-claro); color: #fff; }
.space-tab .rt-count {
  background: rgba(255,255,255,.22); border-radius: 20px;
  padding: 1px 7px; font-size: 11px; font-weight: 600;
}
.space-tab:not(.active) .rt-count { background: var(--accent); color: #fff; }

/* ============================================================
   NAV DO SQUAD: uma fileira só — Chamados + os chats de squad.
   Substituiu o painel de chamados + a faixa "seus squads", que
   antes ficavam empilhados um sobre o outro sobre o chat.
   ============================================================ */
.squad-nav {
  display: flex; gap: 7px; align-items: center; overflow-x: auto;
  padding: 10px 20px; border-bottom: 1px solid var(--border);
  background: rgba(var(--bg-rgb),.5);
}
.snav-item {
  display: inline-flex; align-items: center; gap: 7px; flex-shrink: 0;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted);
  border-radius: 20px; padding: 6px 13px; font-size: 12.5px; cursor: pointer;
  white-space: nowrap; font-family: inherit; transition: all .18s var(--ease);
}
.snav-item:hover { border-color: var(--border-hover); color: var(--text); }
.snav-item.active { background: var(--accent); border-color: var(--accent-claro); color: #fff; }
.snav-count {
  font-size: 11px; font-weight: 600; opacity: .8;
  background: rgba(255,255,255,.14); border-radius: 20px; padding: 0 6px;
}
.snav-item.active .snav-count { opacity: 1; }
/* A aba Chamados pulsa quando há chamado aberto, pra não passar batido. */
.snav-calls.has-calls:not(.active) { border-color: var(--accent-claro); color: var(--text); }
.snav-calls.has-calls:not(.active) .snav-count {
  background: var(--accent); color: #fff; opacity: 1;
  animation: callPulse 2.4s ease-in-out infinite;
}

.kind-picker { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.kind-opt {
  text-align: left; padding: 12px; border-radius: var(--r-ctrl); cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  font-family: inherit; transition: all .18s var(--ease);
}
.kind-opt:hover { border-color: var(--border-hover); }
.kind-opt.selected { border-color: var(--accent-claro); }
.kind-opt strong { display: block; font-size: 13.5px; margin-bottom: 3px; font-weight: 600; }
.kind-opt small { color: var(--text-dim); font-size: 11px; line-height: 1.4; display: block; }

.suggest-box { margin-bottom: 6px; }
.suggest-title { font-size: 13px; color: var(--text-muted); margin: 0 0 10px; }
.suggest-item {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; margin-bottom: 6px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-ctrl);
  cursor: pointer; transition: border-color .18s var(--ease), transform .12s var(--ease);
}
.suggest-item:hover { border-color: var(--accent-claro); transform: translateX(2px); }
.suggest-item .si-name { flex: 1; font-size: 13.5px; font-weight: 500; }
.suggest-item .si-count { font-size: 12px; color: var(--text-muted); }

/* ============================================================
   CHAT
   ============================================================ */
.chat { display: flex; flex-direction: column; min-height: 0; background: var(--bg); }
.messages { flex: 1; min-height: 0; overflow-y: auto; padding: 20px 24px 8px; display: flex; flex-direction: column; gap: 2px; }

/* Troca de sala: apaga e volta, pra não trocar o conteúdo no susto. */
.messages { transition: opacity .18s var(--ease); }
.messages.swapping { opacity: 0; }

/* Cada mensagem entra com um leve deslize — sem exagero. */
.msg { max-width: 74%; animation: msgIn .3s var(--ease) both; }
@keyframes msgIn {
  from { opacity: 0; transform: translateY(8px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
/* As minhas nascem do lado direito, as dos outros do esquerdo. */
.msg.mine { animation-name: msgInMine; }
@keyframes msgInMine {
  from { opacity: 0; transform: translateY(8px) translateX(6px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
.day-divider { animation: msgIn .3s var(--ease) both; }

.day-divider {
  display: flex; align-items: center; gap: 14px; margin: 18px 0 12px;
  color: var(--text-dim); font-size: 10.5px; font-weight: 500; text-transform: uppercase; letter-spacing: .14em;
}
.day-divider::before, .day-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }

.msg.system { align-self: center; max-width: 90%; text-align: center; margin: 7px 0; }
.msg.system .m-body {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-dim); font-size: 12px; border-radius: 20px; padding: 5px 14px;
  display: inline-block;
}

.msg-row { display: flex; gap: 10px; align-items: flex-start; }
.msg .m-head { font-size: 12px; color: var(--text-muted); margin-bottom: 4px; font-weight: 500; display: flex; align-items: baseline; gap: 7px; }
.msg .m-time { font-size: 10px; color: var(--text-dim); font-weight: 400; }
.msg .m-body {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 4px 14px 14px 14px; padding: 9px 14px;
  display: inline-block; line-height: 1.45; word-break: break-word; font-size: 14.5px;
}
.msg.grouped { margin-top: 1px; }
.msg.grouped .m-body { border-radius: 14px; }
.msg.grouped .avatar-slot { width: 27px; flex-shrink: 0; }
.msg.mine { align-self: flex-end; }
.msg.mine .m-head { justify-content: flex-end; }
.msg.mine .m-body { background: var(--accent); border-color: transparent; color: #fff; border-radius: 14px 4px 14px 14px; }
.msg.mine.grouped .m-body { border-radius: 14px; }
.msg:not(.grouped) { margin-top: 12px; }

.empty-state { margin: auto; text-align: center; color: var(--text-dim); max-width: 320px; padding: 30px; line-height: 1.6; font-size: 14px; }
.empty-state .es-ic { display: flex; justify-content: center; margin-bottom: 14px; color: var(--border-hover); }

.composer-wrap { padding: 12px 24px 14px; border-top: 1px solid var(--border); background: var(--surface); }
.composer {
  display: flex; gap: 9px; align-items: center;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 26px; padding: 5px 5px 5px 8px;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.composer:focus-within { border-color: var(--accent-claro); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.13); }
.composer input { flex: 1; background: transparent; border: none; padding: 10px 8px; color: var(--text); font-size: 14.5px; outline: none; }
.composer input:focus { border: none; box-shadow: none; }
.send-btn {
  width: 38px; height: 38px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--accent); color: #fff; display: grid; place-items: center; flex-shrink: 0;
  transition: background .2s var(--ease), transform .12s var(--ease);
}
.send-btn:hover { background: var(--accent-hover); transform: scale(1.05); }
.send-btn:active { transform: scale(.92); }
.composer-hint { font-size: 11px; color: var(--text-dim); margin: 8px 4px 0; text-align: center; }

/* ============================================================
   PAINÉIS LATERAIS
   ============================================================ */
.drawer { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.6); z-index: 55; }
.drawer.open { display: block; animation: fadeIn .2s var(--ease) both; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.drawer-box {
  position: absolute; top: 0; right: 0; bottom: 0; width: 380px; max-width: 92vw;
  background: var(--surface); border-left: 1px solid var(--border);
  display: flex; flex-direction: column; padding: 18px;
  animation: slideIn .28s var(--ease) both;
}
@keyframes slideIn { from { transform: translateX(24px); opacity: 0; } to { transform: none; opacity: 1; } }

#friendsView, #dmView { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.drawer-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; flex-shrink: 0; }
.drawer-head h3 { font-family: var(--font-display); margin: 0; font-size: 16px; flex: 1; font-weight: 400; }
.drawer-note { font-size: 11.5px; color: var(--text-dim); line-height: 1.5; margin: 0 0 14px; flex-shrink: 0; }
.drawer-list { flex: 1; overflow-y: auto; min-height: 0; }

.notif-item {
  padding: 12px; border-radius: var(--r-ctrl); margin-bottom: 7px;
  background: var(--surface-2); border: 1px solid var(--border);
  animation: cardIn .28s var(--ease) both;
}
.notif-item.unread { border-color: var(--accent-claro); }
.notif-item .ni-title { font-size: 13.5px; font-weight: 500; }
.notif-item .ni-body { font-size: 12px; color: var(--text-dim); margin-top: 3px; }
.notif-item .ni-time { font-size: 10.5px; color: var(--text-dim); margin-top: 5px; }

.friend-item { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: var(--r-ctrl); transition: background .18s var(--ease); }
.friend-item:hover { background: var(--surface-2); }
.friend-item .fi-info { flex: 1; min-width: 0; }
.friend-item .fi-name { font-size: 13.5px; font-weight: 500; }
.friend-item .fi-sub { font-size: 11px; color: var(--text-dim); }
.friend-item .btn { margin: 0; padding: 6px 10px; font-size: 11.5px; width: auto; }

.dm-actions { display: flex; gap: 8px; margin-bottom: 12px; flex-shrink: 0; }
.dm-actions .btn { margin: 0; width: auto; flex: 1; }
.danger-text { color: var(--danger) !important; }
.dm-messages { flex: 1; overflow-y: auto; min-height: 0; display: flex; flex-direction: column; gap: 7px; padding-bottom: 10px; }
.dm-msg {
  max-width: 82%; position: relative;
  animation: msgIn .24s var(--ease) both;
  cursor: pointer;   /* clicar responde, igual à sala */
}
.dm-msg .m-body {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 13px; padding: 8px 12px; font-size: 13.5px; line-height: 1.45;
  display: inline-block; word-break: break-word;
}
.dm-msg.mine { align-self: flex-end; }
.dm-msg.mine .m-body { background: var(--accent); border-color: transparent; }

/* --- o cabeçalho: quem falou e quando ---
   Estava sem nada disso. Uma conversa sem hora nem dia é um monte de
   frase solta: não dá pra saber se aquilo foi agora ou semana passada,
   nem por que a próxima mensagem está tão longe da anterior. */
.dm-msg .m-head {
  display: flex; align-items: baseline; gap: .5em;
  margin: 0 0 3px 2px;
  font-size: 11.5px; font-weight: 600; color: var(--text-muted);
}
.dm-msg.mine .m-head { justify-content: flex-end; margin-right: 2px; }
.dm-msg .m-time { font-size: 10.5px; font-weight: 400; color: var(--text-dim); }
/* Mensagens seguidas da mesma pessoa viram um bloco: o cabeçalho some
   e elas se aproximam. Repetir nome e hora a cada linha vira ruído. */
.dm-msg.grouped { margin-top: -6px; }

/* --- o trecho citado, quando é resposta --- */
.dm-msg .m-citacao {
  display: block; width: 100%; text-align: left; cursor: pointer;
  margin: 0 0 4px; padding: 5px 9px;
  background: rgba(127, 127, 127, .12);
  border: 0; border-left: 2px solid var(--accent-claro); border-radius: 6px;
  font: inherit; color: var(--text-dim);
}
.dm-msg .m-citacao:hover { background: rgba(127, 127, 127, .2); }
.dm-msg .mc-nick { display: block; font-size: 11px; font-weight: 700; color: var(--accent-claro); }
.dm-msg .mc-body {
  display: block; font-size: 12px; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* O pisca de quem chegou pela citação. */
.dm-msg.piscando .m-body { animation: piscarMsg 1.2s var(--ease); }

.dm-composer { flex-shrink: 0; }

/* --- fixar no desktop, no cabeçalho da conversa --- */
.dm-fixar {
  display: grid; place-items: center; flex: none;
  width: 32px; height: 32px; cursor: pointer;
  background: none; border: 0; border-radius: 8px;
  color: var(--text-dim);
  transition: color .16s var(--ease), background .16s var(--ease);
}
.dm-fixar:hover { color: var(--text); background: rgba(127, 127, 127, .14); }
/* Ligado: vermelho e cheio. O estado tem que ser visto, não deduzido. */
.dm-fixar.ativo { color: #fff; background: var(--accent); }
.dm-fixar.ativo:hover { background: var(--accent-hover); }

/* ============================================================
   ABAS DO CARTÃO DE ENTRADA (entrar / criar conta)
   ============================================================ */
.auth-tabs { display: flex; gap: 4px; margin-bottom: clamp(10px, 2.2vh, 20px); border-bottom: 1px solid var(--border); }
.auth-tab {
  background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--text-dim); font-family: var(--font-display); font-size: 16px;
  font-weight: 500; padding: 8px 12px; cursor: pointer; margin-bottom: -1px;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.auth-tab:hover { color: var(--text); }
.auth-tab.selected { color: var(--text); border-bottom-color: var(--accent-claro); }
.auth-pane { animation: screenIn .22s var(--ease) both; }
.social-block > div + div { margin-top: 0; }
.alt-sep { color: var(--text-dim); margin: 0 4px; }

/* ============================================================
   PÁGINA DE AMIGOS (tela inteira, não painel)
   ============================================================ */
/* ============================================================
   MODERAÇÃO (admin)
   ============================================================ */
.admin-page {
  flex: 1; min-height: 0; overflow-y: auto;
  max-width: 760px; width: 100%; margin: 0 auto; padding: 4px 26px 40px;
}
.admin-intro { color: var(--text-dim); font-size: 13.5px; line-height: 1.6; margin: 0 0 18px; }
.admin-empty { color: var(--text-dim); font-size: 14px; text-align: center; padding: 40px 0; }
.reports-list { display: flex; flex-direction: column; gap: 12px; }
.report-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 15px 16px;
}
.report-card.resolvido { opacity: .6; }
.rc-top { display: flex; align-items: baseline; gap: 8px; }
.rc-top strong { font-size: 14.5px; }
.rc-sub { color: var(--text-dim); font-size: 12px; margin-left: 6px; }
.rc-tag { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; padding: 2px 7px; border-radius: 20px; }
.rc-tag.banido { background: rgba(255,92,122,.16); color: var(--danger); border: 1px solid rgba(255,92,122,.4); }
.rc-reason { color: var(--text-muted); font-size: 13.5px; font-style: italic; margin: 10px 0 0; }
.rc-evidence { margin: 12px 0 0; display: flex; flex-direction: column; gap: 5px; }
.rc-msg {
  background: var(--surface-2); border-left: 2px solid var(--border-hover);
  border-radius: 6px; padding: 7px 11px; font-size: 13px; color: var(--text); line-height: 1.5;
}
.rc-msg.vazio { color: var(--text-dim); font-style: italic; border-left-color: var(--border); }
.rc-actions { margin-top: 14px; display: flex; justify-content: flex-end; }
.rc-actions .btn { width: auto; margin: 0; }

.friends-page {
  flex: 1; min-height: 0; display: grid; grid-template-columns: 320px minmax(0, 1fr);
  gap: 0; max-width: 1020px; width: 100%; margin: 0 auto;
  padding: 4px 26px 26px;
  /* Caixa fechada: sem isso o conteúdo boiava solto na tela larga. */
  border: 1px solid var(--divisor); border-radius: var(--r-card);
  background: rgba(var(--surface-rgb),.5); overflow: hidden;
}
.friends-col {
  border-right: 1px solid var(--divisor); padding: 18px 20px 18px 0;
  display: flex; flex-direction: column; min-height: 0;
}
/* 4 abas em 320px: sem quebrar linha. */
.friends-tabs { display: flex; gap: 2px; flex-wrap: nowrap; margin-bottom: 10px; }
.ftab {
  background: none; border: 1px solid transparent; color: var(--text-dim);
  font-family: inherit; font-size: 12.5px; font-weight: 500; padding: 6px 9px;
  border-radius: 20px; cursor: pointer; white-space: nowrap; flex-shrink: 0;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.ftab:hover { background: var(--surface-2); color: var(--text); }
.ftab.selected { background: var(--surface-2); color: var(--text); }
.ftab-add { color: var(--accent-claro); }
.ftab-add.selected { background: var(--accent); color: #fff; }
.tab-count {
  background: var(--danger); color: #fff; border-radius: 20px;
  padding: 0 5px; font-size: 10px; font-weight: 700; margin-left: 4px;
}
.friends-count {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .12em;
  color: var(--text-dim); margin: 14px 4px 8px; font-weight: 600;
}
.friends-page-list { flex: 1; overflow-y: auto; min-height: 0; }

/* A página inteira precisa caber na tela, não empurrar scroll do body.
   No celular usamos 100dvh: com 100vh o navegador conta a altura como se
   a barra de endereço não existisse, e ao abrir o teclado o campo de
   escrever ficava embaixo dele. O 100vh fica de reserva pros navegadores
   que ainda não entendem dvh. */
#screen-friends.active { height: 100vh; height: 100dvh; padding-bottom: 26px; }

/* Coluna da conversa */
.dm-col { display: flex; flex-direction: column; min-height: 0; padding: 18px 0 18px 22px; }
#dmPanel { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.dm-empty {
  margin: auto; text-align: center; color: var(--text-dim); max-width: 300px; line-height: 1.6;
}
.dm-empty .es-ic { display: flex; justify-content: center; margin-bottom: 14px; color: var(--border-hover); }
.dm-empty-sub { font-size: 12px; margin-top: 6px; }
.dm-head {
  display: flex; align-items: center; gap: 10px; padding-bottom: 14px;
  border-bottom: 1px solid var(--divisor); margin-bottom: 14px; flex-shrink: 0;
}
.dm-name { font-family: var(--font-display); font-size: 16px; font-weight: 400; }
.dm-head .btn { margin: 0; width: auto; }

/* Chamado privado: cadeado junto do nome e borda que o diferencia
   do público sem gritar. */
.call-cadeado { display: inline-flex; vertical-align: -1px; margin-right: 5px; color: var(--accent-claro); }
.call-card.privado { border-color: rgba(126,162,255,.35); }

/* ============================================================
   RESPONDER MENSAGEM
   ============================================================ */
/* Barra "respondendo a", acima do campo de escrever. */
.respondendo {
  display: flex; align-items: center; gap: 10px; margin-bottom: 8px;
  padding: 8px 10px; border-radius: 10px; background: var(--surface-2);
  border: 1px solid var(--border);
}
.resp-linha { width: 3px; align-self: stretch; border-radius: 2px; background: var(--accent-claro); flex-shrink: 0; }
.resp-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.resp-txt strong { font-size: 12.5px; color: var(--accent-claro); }
.resp-txt span { font-size: 13px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.resp-x {
  background: none; border: none; color: var(--text-dim); cursor: pointer;
  padding: 4px; border-radius: 6px; line-height: 0; flex-shrink: 0;
}
.resp-x:hover { background: var(--surface); color: var(--text); }

/* Trecho citado dentro da mensagem. */
.m-citacao {
  display: flex; flex-direction: column; gap: 1px; width: 100%;
  margin: 0 0 5px; padding: 5px 9px; border: none; border-left: 3px solid var(--accent-claro);
  border-radius: 6px; background: rgba(255,255,255,.055);
  font: inherit; text-align: left; cursor: pointer; overflow: hidden;
}
.m-citacao:hover { background: rgba(255,255,255,.09); }
.mc-nick { font-size: 12px; font-weight: 600; color: var(--accent-claro); }
.mc-body { font-size: 12.5px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A citação fica FORA da bolha, sobre o fundo da tela — inclusive nas
   minhas mensagens. Por isso não leva fundo escuro (sumiria no escuro);
   só acompanha o alinhamento à direita da própria mensagem. */
.msg.mine .m-citacao { max-width: 78%; margin-left: auto; }

/* Pulso ao chegar na mensagem citada, pra achar no meio da conversa. */
@keyframes piscarMsg { 0%,100% { background: transparent; } 30% { background: rgba(126,162,255,.22); } }
.msg.piscar { animation: piscarMsg 1.1s var(--ease); border-radius: 10px; }

/* Menu de uma mensagem: posicionado no clique, por isso fixed. */
.msg-menu {
  position: fixed; z-index: 200; min-width: 176px; padding: 6px;
  border-radius: 12px; background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 14px 34px rgba(0,0,0,.5);
}
.msg-menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border: none; border-radius: 8px; background: none;
  color: var(--text); font: inherit; font-size: 14px; cursor: pointer; text-align: left;
}
.msg-menu-item:hover { background: var(--surface-2); }

/* No celular, segurar a mensagem não pode selecionar o texto junto. */
@media (pointer: coarse) {
  .msg .m-body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
}

/* Aviso de "livre / em uso" embaixo do campo de apelido. */
.field-aviso { min-height: 18px; margin: 6px 0 4px; font-size: 13px; color: var(--text-dim); }
.field-aviso.bom { color: #5ad18b; }
.field-aviso.ruim { color: var(--danger); }

/* Avatar dentro da mensagem: clicável, abre o perfil. */
.msg-av { cursor: pointer; border-radius: 999px; display: inline-flex; }
.msg-av:hover { filter: brightness(1.15); }
.msg-av:focus-visible { outline: 2px solid var(--accent-claro); outline-offset: 2px; }

/* Voltar: escondido no computador, onde a lista de amigos está sempre
   à vista do lado. Só aparece quando ela some. */
.dm-voltar {
  display: none; background: none; border: none; padding: 6px; margin-left: -6px;
  color: var(--text-dim); cursor: pointer; border-radius: 8px; line-height: 0;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.dm-voltar:hover { background: var(--surface-2); color: var(--text); }

/* Avatar + nome viram um botão só: é o alvo grande e óbvio pro perfil. */
.dm-pessoa {
  display: flex; align-items: center; gap: 10px; background: none; border: none;
  padding: 4px 8px 4px 4px; margin-left: -4px; border-radius: 999px;
  color: inherit; font: inherit; cursor: pointer; text-align: left;
  transition: background .15s var(--ease);
}
.dm-pessoa:hover { background: var(--surface-2); }

/* Menu de mais opções */
.dm-menu-wrap { position: relative; }
.dm-menu-btn {
  background: none; border: none; padding: 8px; color: var(--text-dim);
  cursor: pointer; border-radius: 8px; line-height: 0;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.dm-menu-btn:hover { background: var(--surface-2); color: var(--text); }
.dm-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30;
  min-width: 178px; padding: 6px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 14px 34px rgba(0,0,0,.45);
}
.dm-menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border: none; border-radius: 8px; background: none;
  color: var(--text); font: inherit; font-size: 14px; cursor: pointer; text-align: left;
}
.dm-menu-item:hover { background: var(--surface-2); }

@media (max-width: 860px) {
  .friends-page { grid-template-columns: 1fr; padding: 0 16px 16px; }
  .friends-col { border-right: none; padding-right: 0; }
  .dm-col { padding-left: 0; border-top: 1px solid var(--divisor); margin-top: 14px; padding-top: 14px; }
  /* No celular, uma coisa por vez: abriu conversa, some a lista. */
  .friends-page.dm-open .friends-col { display: none; }
  .friends-page:not(.dm-open) .dm-col { display: none; }
  /* Aqui a lista some, então o caminho de volta precisa existir. */
  .dm-voltar { display: inline-flex; }
  /* Sem a borda/afastamento herdados do desktop: a conversa é a tela toda. */
  .friends-page.dm-open .dm-col { border-top: none; margin-top: 0; padding-top: 4px; }
}

/* ============================================================
   PÁGINA DE PERFIL E CONFIGURAÇÕES
   ============================================================ */
.profile-page { flex: 1; max-width: 780px; width: 100%; margin: 0 auto; padding: 8px 26px 60px; }

.profile-head { display: flex; align-items: center; gap: 20px; margin-bottom: 28px; flex-wrap: wrap; }
.profile-avatar {
  width: 78px; height: 78px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center; font-size: 26px; font-weight: 700; color: #fff;
  overflow: hidden;
}
.profile-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 50%; }
.profile-id { flex: 1; min-width: 180px; }
.profile-id h2 { font-family: var(--font-display); font-size: 24px; margin: 0 0 4px; font-weight: 400; letter-spacing: -.02em; }
.profile-meta { color: var(--text-dim); font-size: 13px; margin: 0; }
.profile-badges { display: flex; gap: 6px; margin-top: 9px; flex-wrap: wrap; }
.pbadge {
  font-size: 10.5px; padding: 3px 9px; border-radius: 20px; font-weight: 600;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted);
  display: inline-flex; align-items: center; gap: 5px;
}
.pbadge.on { border-color: rgba(var(--accent-rgb),.45); color: #b9cbff; }
.profile-stats { display: flex; gap: 26px; }
.profile-stats div { text-align: center; }
.profile-stats strong { display: block; font-family: var(--font-display); font-size: 22px; font-weight: 400; }
.profile-stats span { font-size: 10.5px; text-transform: uppercase; letter-spacing: .12em; color: var(--text-dim); }

.profile-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 22px; }
.ptab {
  background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--text-dim); font-family: inherit; font-size: 14px; font-weight: 500;
  padding: 9px 14px; cursor: pointer; margin-bottom: -1px;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.ptab:hover { color: var(--text); }
.ptab.selected { color: var(--text); border-bottom-color: var(--accent-claro); }
.profile-pane { animation: screenIn .24s var(--ease) both; }

.setting-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 22px; margin-bottom: 16px;
}
.setting-card h3 { font-family: var(--font-display); font-size: 15.5px; font-weight: 400; margin: 0 0 6px; }
.setting-card .btn { width: auto; margin-top: 4px; }
.setting-note { color: var(--text-dim); font-size: 12.5px; line-height: 1.55; margin: 0 0 14px; }
.setting-list { color: var(--text-muted); font-size: 13px; line-height: 1.8; padding-left: 18px; margin: 0; }
.danger-card { border-color: rgba(255,92,122,.28); }

.linked-list { display: grid; gap: 8px; }
.linked-item {
  display: flex; align-items: center; gap: 10px; padding: 11px 13px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-ctrl);
  font-size: 13.5px;
}
.linked-item .li-name { flex: 1; font-weight: 500; }
.linked-item .li-status { font-size: 11.5px; color: var(--text-dim); }
.linked-item.on .li-status { color: var(--online); }

/* ---- Grade de jogos da Steam (biblioteca e lista de desejos) ---- */
.count-pill {
  font-size: 11px; font-weight: 600; color: var(--text-dim);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 20px; padding: 2px 8px; margin-left: 6px;
  font-family: var(--font-body);
}
.steam-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 10px; }
.steam-grid.sm { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; }
.steam-item {
  position: relative; display: block; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--border); background: var(--surface-2);
  text-decoration: none; color: var(--text);
  transition: border-color .18s var(--ease), transform .16s var(--ease);
}
.steam-item:hover { border-color: var(--accent-claro); transform: translateY(-2px); }
.steam-item img { width: 100%; aspect-ratio: 460/215; object-fit: cover; display: block; }
/* Nem todo appid tem capa nesse caminho: se falhar, some a imagem e
   sobra o nome, em vez de deixar um quadrado quebrado. */
.steam-item.sem-capa img { display: none; }
.steam-item .si-name {
  display: block; padding: 7px 9px 8px; font-size: 11.5px; font-weight: 500;
  line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Sem backdrop-filter: são dezenas de etiquetas numa grade só, e cada
   uma seria mais uma camada relida a cada quadro. O mesmo contraste sai
   de um fundo um pouco mais fechado. */
.steam-item .si-meta {
  position: absolute; top: 6px; right: 6px; font-size: 10px; font-weight: 600;
  background: rgba(var(--bg-rgb),.88);
  border-radius: 20px; padding: 2px 7px; color: var(--text-muted);
}
.steam-item .si-tag {
  position: absolute; top: 6px; left: 6px; font-size: 9px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  background: rgba(var(--accent-rgb),.9); color: #fff; border-radius: 20px; padding: 2px 7px;
}

.profile-tabs .spacer { flex: 1; }
.profile-tabs .btn { margin: 0 0 6px; width: auto; }

/* ---- Perfil público ----
   Vira uma página de gente que joga: capa com a arte de um jogo dela,
   avatar montado por cima, bio destacada e os números logo abaixo. */
/* .modal-box mora mais pra baixo no arquivo e empata em especificidade,
   então o padding dele vencia e a capa nunca encostava nas bordas.
   Dobrar a classe resolve sem depender da ordem. */
.modal-box.public-box {
  max-width: 580px; max-height: 88vh; overflow-y: auto;
  padding: 0 0 24px; overflow-x: hidden;
}
.public-box > *:not(.pub-capa) { margin-left: 26px; margin-right: 26px; }
.pub-capa {
  height: 132px; margin: 0; border-radius: var(--r-card) var(--r-card) 0 0;
  background-size: cover; background-position: center;
  position: relative;
}
/* O véu deixa o avatar e o nome legíveis por cima de qualquer arte. */
.pub-capa::after {
  content: ''; position: absolute; inset: 0;
  border-radius: inherit;
  background: linear-gradient(180deg,
    rgba(var(--bg-rgb),.35) 0%,
    rgba(var(--bg-rgb),.75) 55%,
    var(--surface) 100%);
}
.pub-capa.sem-arte { background: linear-gradient(135deg, rgba(var(--accent-rgb),.32), rgba(var(--bg-rgb),1)); }

.preview-tag {
  display: inline-block; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .1em; color: var(--accent-claro); background: rgba(var(--accent-rgb),.12);
  border: 1px solid rgba(var(--accent-rgb),.4); border-radius: 20px;
  padding: 4px 10px; margin: 16px 0 0;
}
/* Sobe pra montar em cima da capa. */
.public-head {
  display: flex; align-items: flex-end; gap: 16px;
  margin-top: -44px; margin-bottom: 14px; position: relative; z-index: 1;
}
.profile-avatar.grande {
  width: 92px; height: 92px; font-size: 30px; position: relative;
  box-shadow: 0 0 0 4px var(--surface), 0 12px 28px rgba(0,0,0,.5);
}
.public-head .profile-id { padding-bottom: 4px; }
.public-head h3 { margin: 0 0 3px; font-size: 22px; font-family: var(--font-display); font-weight: 400; letter-spacing: -.02em; }
.pt-status { color: var(--text-dim); }
.pt-status.on { color: var(--online); font-weight: 600; }

/* A bio ganha peso de citação em vez de virar mais uma linha cinza. */
.pub-bio {
  color: var(--text); font-size: 14px; margin: 0; line-height: 1.6;
  white-space: pre-wrap;
}

/* Plataformas no cabeçalho do perfil. */
.pub-platforms { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 2px; }
.plat-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 500; padding: 4px 10px; border-radius: 20px;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
}
.plat-chip .ic { color: var(--accent-claro); }

.pub-block { margin-bottom: 22px; }
.pub-block h4 {
  font-family: var(--font-display); font-size: 14px; font-weight: 400;
  margin: 0 0 11px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.total-jogos { font-weight: 600; }
/* "X em comum": destaque âmbar, como um "match" — cor de STATUS, não da
   marca (o azul continua sendo só o que se clica). */
.em-comum-tag {
  font-family: var(--font-body); font-size: 12px; font-weight: 700;
  color: #1a1206; background: var(--match); border-radius: 20px; padding: 3px 10px;
}
.count-pill { font-family: var(--font-body); font-size: 12px; font-weight: 400; color: var(--text-dim); }

/* Fileira de jogos em tiles (capa + nome), rola na horizontal. */
.jogos-row {
  display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px;
  scroll-snap-type: x proximity;
}
.jogo-tile {
  flex: 0 0 132px; scroll-snap-align: start; text-decoration: none; color: inherit;
  display: flex; flex-direction: column; gap: 6px;
}
.jt-capa {
  position: relative; aspect-ratio: 1 / 1; border-radius: 12px; overflow: hidden;
  background: var(--surface-2); border: 1px solid var(--border);
  transition: border-color .18s var(--ease), transform .12s var(--ease);
}
a.jogo-tile:hover .jt-capa { transform: translateY(-2px); border-color: var(--border-hover); }
.jt-capa img { width: 100%; height: 100%; object-fit: cover; display: block; }
.jt-capa.sem-capa img { display: none; }
/* Em comum: anel âmbar grosso, igual ao destaque da referência. */
.jt-capa.comum { border: 2px solid var(--match); box-shadow: 0 0 0 3px rgba(242,176,74,.18); }
.jt-comum {
  position: absolute; left: 6px; bottom: 6px;
  font-size: 10px; font-weight: 700; color: #1a1206; background: var(--match);
  border-radius: 6px; padding: 2px 6px;
}
.jt-nome { font-size: 12.5px; font-weight: 500; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jt-horas { font-size: 11px; color: var(--text-dim); }

.faq { border-top: 1px solid var(--border); padding: 12px 0 4px; }
.faq:first-of-type { border-top: none; }
.faq summary {
  cursor: pointer; font-size: 13.5px; font-weight: 500; color: var(--text);
  list-style: none; padding: 2px 0;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::before { content: '+ '; color: var(--accent-claro); font-weight: 700; }
.faq[open] summary::before { content: '– '; }
.faq p { color: var(--text-dim); font-size: 13px; line-height: 1.65; margin: 8px 0 4px 14px; }

@media (max-width: 700px) {
  .profile-page { padding: 4px 16px 40px; }
  .float-nav { padding: 12px 16px; }
  .profile-stats { width: 100%; justify-content: flex-start; }
}

/* ============================================================
   MODAIS E AVISOS
   ============================================================ */
.modal { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.72); align-items: center; justify-content: center; padding: 20px; z-index: 60; }
.modal.open { display: flex; animation: fadeIn .18s var(--ease) both; }
.modal-box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 28px; max-width: 470px; width: 100%;
  animation: modalIn .26s var(--ease) both;
}
@keyframes modalIn { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: none; } }
.modal-box h3 { font-family: var(--font-display); margin: 0 0 14px; font-size: 18px; font-weight: 400; letter-spacing: -.01em; }
.terms-list { color: var(--text-muted); line-height: 1.7; padding-left: 18px; font-size: 13.5px; }
.modal-box .row { display: flex; gap: 10px; margin-top: 16px; }
.modal-box .row .btn { flex: 1; margin: 0; width: auto; }

.join-box { max-width: 420px; text-align: center; }
.join-cover { width: 100%; aspect-ratio: 460/215; border-radius: var(--r-ctrl); overflow: hidden; background: var(--surface-2); margin-bottom: 18px; display: none; }
.join-cover.has-img { display: block; }
.join-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.join-text { color: var(--text-muted); font-size: 13.5px; line-height: 1.6; margin: 0; }
.join-text strong { color: var(--text); }

.toast {
  position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%) translateY(16px);
  background: var(--surface-2); border: 1px solid var(--border-hover); color: var(--text);
  padding: 12px 20px; border-radius: var(--r-ctrl); opacity: 0;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
  pointer-events: none; z-index: 70; max-width: 90%; font-size: 14px;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.err { border-color: var(--danger); color: #ffd7de; }
/* Na sala o rodapé embaixo é o campo de escrever — o toast caía em cima
   do aviso de segurança. Sobe pra ficar acima do composer. */
body:has(#screen-room.active) .toast { bottom: 112px; }

/* ============================================================
   CELULAR
   ============================================================ */
@media (max-width: 700px) {
  /* No celular a barra lateral deita numa faixa que rola no topo, e a
     conversa fica embaixo com a largura toda. */
  .room { grid-template-columns: minmax(0, 1fr); }
  /* A trilha NÃO deita mais numa faixa rolando de lado. Era isto que
     cortava os nomes no meio e escondia metade das salas: pra achar a
     terceira era preciso arrastar a faixa de lado. Agora ela mora no
     painel, em pé, e cabe inteira. */
  .salas-painel { left: 8px; right: 8px; width: auto; max-height: 68vh; }
  .calls-view { padding: 16px 14px 20px; }
  .calls-grid { grid-template-columns: 1fr; }
  .members { left: 8px; right: 8px; width: auto; max-height: 56vh; padding: 14px; }
  .msg { max-width: 86%; }
  .messages { padding: 14px 14px 6px; }
  .composer-wrap { padding: 10px 14px 12px; }

  /* Topbar numa linha só: nada de "Sair da sala" quebrando em três. */
  #screen-room .topbar { padding: 10px 12px; gap: 8px; flex-wrap: nowrap; }
  /* No celular a barra nao comporta a marca: o nome do jogo e a
     unica pista de onde a pessoa esta e precisa da largura. */
  #screen-room .marca-sala { display: none; }
  #screen-room #whoami2 { display: none; }
  #screen-room .topbar .btn.small { flex: 0 0 auto; white-space: nowrap; padding: 7px 10px; }
  #screen-room .topbar .icon-btn { flex: 0 0 auto; }
  #btnBack .btn-label, .lbl-full { display: none; }
  .lbl-curto { display: inline; }
  .room-title { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* Agora a pílula diz por extenso quantas pessoas do mural estão online,
     e o texto inteiro não cabe ao lado do nome do jogo. Some abaixo de
     560px: o mesmo número está no painel de quem está aqui, e o nome do
     jogo é a única pista de onde a pessoa está. */
  .online-pill { flex: 0 0 auto; white-space: nowrap; }
  @media (max-width: 560px) { .online-pill { display: none; } }

  .lobby { padding: 150px 16px 96px; }
  .game-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
  .kind-picker { grid-template-columns: 1fr; }

  /* Card estreito: a faixa de texto ocupava quase o card inteiro e o
     nome caía na parte transparente do véu, em cima do logo da capa.
     Card mais alto + pills menores devolvem o texto pro fundo sólido. */
  .game-card { aspect-ratio: 3 / 4; }
  .game-card .body { padding: 10px 12px 11px; }
  .game-card .name { font-size: 14px; }
  .game-card .count { margin-top: 6px; font-size: 11px; gap: 5px; white-space: nowrap; }
}

/* ============================================================
   AVISO "RECOMENDADO" DA STEAM (tela de entrada)
   ------------------------------------------------------------
   Antes era um .hint: 12px, cinza e centralizado, do mesmo peso de
   qualquer observação de rodapé. Ninguém lia. Como a escolha do login
   muda o que a pessoa consegue fazer no app (jogos em comum vêm da
   biblioteca da Steam), este aviso precisa de peso próprio.
   ============================================================ */
.rec-note {
  /* Sem caixa e sem fundo: quem chama atencao pro botao e a seta
     desenhada, nao um retangulo colorido competindo com ele. */
  margin: 0 0 2px; padding: 0; border: 0; background: none;
  font-size: 12.5px; line-height: 1.45; color: var(--text-dim);
}
.rec-note p { margin: 0; }
.rec-note strong { color: var(--text); }
.rec-note p { margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--text); }
/* A ressalva ("não é obrigatório") fica um tom abaixo: é importante que
   esteja lá, mas quem bate o olho tem que ler a recomendação primeiro. */
.rec-fraco { color: var(--text-dim); }
.rec-note strong { color: var(--accent-claro); }

.rec-selo {
  display: inline-block; margin-bottom: 7px;
  padding: 3px 8px; border-radius: 999px;
  background: var(--accent-claro); color: #0a1020;
  font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}

/* Brilho que atravessa a caixa umas poucas vezes e para. Serve pra
   puxar o olho na primeira vista; se ficasse em looping viraria
   pisca-pisca e a pessoa passaria a ignorar. */
.rec-note::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,.13) 50%, transparent 65%);
  transform: translateX(-100%);
  animation: recBrilho 2.6s var(--ease) 3;
  pointer-events: none;
}
@keyframes recBrilho { to { transform: translateX(100%); } }

@media (prefers-reduced-motion: reduce) {
  .rec-note::after { animation: none; }
}

/* ============================================================
   SETA DESENHADA APONTANDO PRO BOTÃO DA STEAM
   ------------------------------------------------------------
   Anotação à mão por cima do layout duro — é o gesto da referência,
   onde o manuscrito entra em dose pequena sobre a tipografia pesada.
   Ela se desenha sozinha e depois fica cutucando o botão.
   ============================================================ */
.dica-steam {
  display: flex; align-items: center; gap: 6px;
  margin: clamp(6px, 1.4vh, 14px) 0 -6px; padding-left: 2px;
}
.dica-txt {
  font-family: var(--font-serif); font-style: italic; font-size: 17px;
  color: var(--accent-claro); white-space: nowrap;
}
.dica-seta {
  width: 86px; height: auto; flex: none; overflow: visible;
  fill: none; stroke: var(--accent-claro); stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
  transform: rotate(3deg);
  /* O bezier passa de 1 (1.56) — é o overshoot que dá mola, e não
     um vaivém de metrônomo. */
  animation: cutuca 1.5s cubic-bezier(.34, 1.56, .64, 1) 1.2s infinite;
}
.dica-seta path {
  stroke-dasharray: 130; stroke-dashoffset: 130;
  animation: riscaSeta .55s var(--ease) .35s forwards;
}
.dica-seta path:last-child { animation-delay: .7s; }
@keyframes riscaSeta { to { stroke-dashoffset: 0; } }
@keyframes cutuca {
  0%   { transform: rotate(3deg) translate(0, 0); }
  32%  { transform: rotate(3deg) translate(3px, 10px); }
  62%  { transform: rotate(3deg) translate(-1px, -4px); }
  100% { transform: rotate(3deg) translate(0, 0); }
}

/* Animação infinita + menos movimento: sem cortar a repetição, um
   ciclo de 0,01ms roda pra sempre e queima CPU justamente de quem
   pediu menos movimento. */
@media (prefers-reduced-motion: reduce) {
  .dica-seta { animation-iteration-count: 1 !important; }
}

/* No estreito o trilho e a barra do topo saem: viram ruído. */
@media (max-width: 900px) {
  .login-trilho, .login-topo { display: none; }
  #screen-login.active { padding: 32px 20px 0;
    /* o indicador do iPhone come ~34px: sem isto a faixa fica embaixo dele */
    padding-bottom: env(safe-area-inset-bottom, 0px); }
}

/* ============================================================
   FOTO DE PERFIL
   ============================================================ */
.avatar-edit { display: grid; justify-items: center; gap: 8px; }
.avatar-troca {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border: 1px solid var(--border); background: var(--surface);
  color: var(--text); font: inherit; font-size: 11px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; cursor: pointer;
  transition: border-color .15s var(--ease), color .15s var(--ease);
}
.avatar-troca:hover { border-color: var(--accent-claro); color: var(--accent-claro); }
.avatar-remover {
  font-size: 12px; color: var(--text-dim); background: none; border: 0;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.avatar-remover:hover { color: var(--danger); }
/* A foto preenche o círculo sem distorcer, seja retrato ou paisagem. */
.profile-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ============================================================
   TELA BAIXA: o que cede é a decoração, não o conteúdo
   ------------------------------------------------------------
   Abaixo de ~780px de altura o cartão de entrada não cabe junto
   com a faixa de capas. Em vez de deixar o botão de entrar passar
   por trás da faixa, a seta desenhada sai e a faixa encolhe — as
   duas são apoio visual, e nenhuma delas é necessária pra entrar.
   ============================================================ */
@media (max-height: 780px) and (min-width: 901px) {
  .dica-steam { display: none; }
  .rec-note { font-size: 12px; margin-bottom: 6px; }
  #screen-login .sharp-strip { padding: 10px 0 12px; }
  .strip-track img { width: 128px; height: 58px; }
  .strip-track { gap: 10px; }
  /* Sem padding embaixo: a faixa e o ULTIMO item da coluna flex, entao
     todo padding aqui virava espaco morto DEPOIS dela — a barra
     "subia" e ficava boiando com uma tira preta por baixo. Ela tem
     que encostar na base da tela. */
}
/* Mais baixa ainda: a faixa some de vez. */
@media (max-height: 640px) and (min-width: 901px) {
  #screen-login .sharp-strip { display: none; }
  #screen-login.active { padding-bottom: 28px; }
}

/* ============================================================
   LOBBY: mesma régua tipográfica das telas do cadastro
   ============================================================ */
#screen-lobby h2 {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(30px, 4.4vw, 56px); line-height: .9; letter-spacing: -.04em;
  text-transform: uppercase; margin: 0 0 10px; color: var(--text);
}
#screen-lobby .subtitle {
  font-size: clamp(14px, 1.3vw, 17px); max-width: 52ch; margin: 0 0 22px;
}
/* Destaque por voz, não por peso — igual ao resto da identidade. */
#screen-lobby .subtitle strong {
  font-family: var(--font-serif); font-style: italic; font-weight: 400;
  color: var(--accent-claro);
}
/* O cabeçalho do lobby acompanha a rolagem do conteúdo, então aqui
   ele é estático — ao contrário do das telas do cadastro. */
.tela-topo-lobby { position: static; margin-bottom: 18px; }

/* ============================================================
   SALA — a linguagem do mural
   ------------------------------------------------------------
   Mesmo vocabulário da tela de entrada: título pesadíssimo, rótulo
   com seta vermelha, mensagem de sistema em serifada itálica, e o
   chamado de squad como a única caixa vermelha da tela.
   ============================================================ */

/* A arte borrada do jogo sai: esta identidade é chapada. */
#screen-room .room-bg { display: none; }

#screen-room .room-title {
  font-family: var(--font-display); font-weight: 400;
  font-size: 20px; letter-spacing: -.03em; text-transform: uppercase;
}

/* Rótulo de seção com a seta, igual aos fatos da entrada. */
.members-title { letter-spacing: .13em; text-transform: uppercase; font-size: 12px !important; }
.members-title::before { content: "\2192 "; color: var(--accent-claro); }

/* --- quem tá aqui: inicial em quadrado, nome, entrou há X, pontinho ---
   Isto aqui já tinha sido tentado mirando .avatar, mas avatarHtml()
   carimba a cor de fundo INLINE e estilo inline ganha de qualquer
   seletor: o círculo colorido continuava lá. Agora o renderMembers()
   escreve .m-quad e .m-pip, e não há mais briga de cascata.
   O seletor .m-av também caiu: essa classe nunca existiu no app. */
#memberList li {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0; margin: 0; border-radius: 0;
  border-bottom: 1px solid var(--border); background: none;
}
#memberList .m-quad {
  width: 30px; height: 30px; flex: none; border-radius: 0;
  background: var(--surface-2); border: 1px solid var(--border);
  display: grid; place-items: center;
  font-weight: 700; font-size: 12px; color: var(--text);
}
/* Status como pontinho solto na direita, e não grudado numa foto.
   Quem carrega o significado em texto é o `.off` do lado do nome. */
#memberList .m-pip {
  width: 7px; height: 7px; flex: none; border-radius: 50%;
  background: var(--border-hover);
}
#memberList .m-pip.on { background: var(--online); }
/* Deitado, cada linha ja e um cartao: a divisoria sobra. */
#memberList.deitada li { border-bottom: 0; }


/* --- o que rolou: fio ao lado da mensagem ---------------------
   O fio marca DE QUEM e a fala: dos outros ele fica a esquerda, na
   sua ele fica a direita, acompanhando o lado em que a mensagem se
   alinha. Antes eu tinha posto border-left em tudo e largura 100% —
   o resultado era um fio solto no canto esquerdo da tela enquanto a
   propria mensagem estava la na direita. --- */
#screen-room .msg {
  max-width: 74%;                       /* nao atravessa a tela */
  border-left: 2px solid var(--border);
  padding: 1px 0 1px 12px;
  background: none;
}
#screen-room .msg.mine {
  border-left: 0;
  border-right: 2px solid var(--accent-claro);
  padding: 1px 12px 1px 0;
}
/* "Fulano entrou" nao e fala de ninguem, e a unica mensagem de
   sistema que existe aqui. Ela tinha largura cheia, alinhamento a
   esquerda e o mesmo fio vermelho das falas — com tres pessoas
   chegando na mesma noite, o meio da conversa virava uma escada de
   avisos com o peso de quem estava conversando.

   Agora ela sai do caminho: centralizada, pequena e sem fio, na mesma
   familia do separador de dia. Serifada italica porque essa e a voz
   do lugar no Banke — o "ou com e-mail" da entrada usa a mesma. Quem
   procura quem esta na sala tem a lista no cabecalho; aqui basta o
   registro de que alguem chegou. (Consecutivas viram uma linha so:
   quem junta e o /app.js, em fraseEntrada.) */
#screen-room .msg.system {
  align-self: center; text-align: center; max-width: 100%;
  border: 0; padding: 0; margin: 10px 0 4px;
  font-family: var(--font-serif); font-style: italic;
  color: var(--text-dim); background: none;
}

/* --- chamado de squad: a única caixa vermelha da tela ---
   Estava mirando duas classes que não existem: .squad-call nunca foi
   escrita em lugar nenhum, e .chamado é do preview. A classe real do
   cartão é .call-card (app.js, renderCalls). Esta regra nunca pegou. */
#screen-room .call-card {
  border: 1px solid var(--accent-claro);
  background: rgba(var(--accent-rgb), .07);
  border-radius: 0; padding: 12px;
}
/* Âmbar aqui é STATUS ("falta 1 pessoa"), não decoração — por isso
   sobrevive à regra de cima, que tem menos especificidade. */
#screen-room .call-card.almost { border-color: var(--match); }
/* Privado tambem e STATUS: o cadeado diz, a borda confirma. */
#screen-room .call-card.privado { border-color: rgba(126,162,255,.55); }
#screen-room .call-card.mine { box-shadow: inset 3px 0 0 var(--accent-claro); }

/* --- a barra de cima: marca, rótulo da tela, e quem você é --- */
.marca-sala {
  display: inline-flex; align-items: baseline; gap: .55em; flex: 0 0 auto;
  padding-right: 12px; border-right: 1px solid var(--border);
}
.marca-sala b {
  font-family: var(--font-display); font-weight: 400; font-size: 16px;
  letter-spacing: -.03em; text-transform: uppercase; color: var(--text);
}
.marca-sala .ms-rot {
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--text-dim);
}
/* O nome de quem está logado: encostado na direita e em alarme, como
   o `.marca-tela .n` do preview. O #ff2b32 sobre a barra da sala mede
   4,95:1 — passa AA. O --accent cheio não serve aqui: é preenchimento. */
#screen-room #whoami2 {
  margin-left: 6px; color: var(--accent-claro);
  font-size: 11px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
}

/* --- o que rolou: sem balão e sem avatar ---
   O filete à esquerda (que o bloco acima já pôs) É a caixa. Nome
   branco e pesado, hora cinza, separados por um ponto médio: é o
   `.cab`/`.cab b` do preview. O fundo do balão morava no .m-body,
   que tinha ficado de fora quando o .msg perdeu o dele. */
#screen-room .msg .m-body {
  background: none; border: 0; border-radius: 0; padding: 0;
  display: block; font-size: 14.5px; line-height: 1.45; color: var(--text);
}
#screen-room .msg .m-head {
  color: var(--text); font-weight: 700; font-size: 12.5px;
  margin-bottom: 2px; gap: 5px;
}
#screen-room .msg .m-time {
  color: var(--text-dim); font-weight: 400; font-size: 11px;
}
/* Na sua mensagem a hora está sozinha no cabeçalho: o ponto ficaria
   pendurado na frente de nada. */
#screen-room .msg:not(.mine) .m-time::before { content: "\00b7\00a0"; }
#screen-room .msg.system .m-body {
  background: none; border: 0; border-radius: 0; padding: 0;
  display: block; text-align: center;
  color: var(--text-dim); font-size: 12.5px; opacity: .8;
}
/* Respiro pelo gap, não por margens que se somam. */
#screen-room .messages { gap: 4px; }
#screen-room .msg.grouped { margin-top: 0; }
#screen-room .msg:not(.grouped) { margin-top: 8px; }

/* --- escrever: campo de aresta viva + ENVIAR por extenso ---
   Tudo escopado em #screen-room porque .composer e .send-btn são
   compartilhados com as mensagens diretas (#btnDmSend), que seguem
   com a pílula arredondada e o botão redondo. */
#screen-room .composer-wrap { background: none; }
#screen-room .composer {
  background: none; border: 0; border-radius: 0; padding: 0;
  gap: 8px; align-items: stretch;
}
#screen-room .composer:focus-within { box-shadow: none; }
#screen-room .composer input {
  border: 1px solid var(--border); border-radius: 0; padding: 11px 12px;
}
#screen-room .composer input:focus {
  outline: 2px solid var(--accent-claro); outline-offset: -1px;
  border-color: transparent;
}
#screen-room .send-btn {
  width: auto; height: auto; border-radius: 0; padding: 11px 22px;
  background: var(--accent); color: #fff;   /* 4,76:1 — passa AA */
  font-family: inherit; font-weight: 700; font-size: 12px;
  letter-spacing: .12em; text-transform: uppercase;
}
#screen-room .send-btn:hover { background: var(--accent-hover); transform: none; }
#screen-room .send-btn:active { transform: none; }
/* Botao cheio e opaco mente sobre estar desligado: .send-btn nao
   e .btn, entao a regra global de :disabled nao alcanca. */
#screen-room .send-btn:disabled { opacity: .5; cursor: not-allowed; background: var(--accent); transform: none; }

/* ============================================================
   TOUR GUIADO (guia-*) — véu, recorte, seta e balão
   ------------------------------------------------------------
   Mora acima de tudo: modal é 60, toast 70, menu de mensagem 200.
   Quem come o clique é o véu; o recorte é só desenho.
   ============================================================ */
.guia-veu { position: fixed; inset: 0; z-index: 300; background: transparent; }

/* O escuro é a SOMBRA do recorte, espalhada até cobrir a janela.
   Assim o alvo continua nítido, sem filtro e sem cópia. */
.guia-recorte {
  position: fixed; top: 0; left: 0; width: 0; height: 0;
  z-index: 301; pointer-events: none;
  border: 2px solid var(--accent-claro); border-radius: var(--r-card);
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .78);
  transition: top .28s var(--ease), left .28s var(--ease),
              width .28s var(--ease), height .28s var(--ease);
}
.guia-recorte::after {
  content: ''; position: absolute; inset: -2px;
  border: 2px solid var(--accent-claro);
  animation: guiaPulso 1.9s var(--ease) infinite;
}
@keyframes guiaPulso {
  0%   { opacity: .85; transform: scale(1); }
  70%, 100% { opacity: 0; transform: scale(1.05); }
}

/* Seta: mesmo desenho, traço e cor da dica "é por aqui" do login.
   riscaSeta já existe neste arquivo — é o mesmo risco. */
.guia-seta {
  position: fixed; z-index: 302; height: auto; pointer-events: none;
  overflow: visible; fill: none; stroke: var(--accent-claro);
  stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
}
.guia-seta path {
  stroke-dasharray: 130; stroke-dashoffset: 130;
  animation: riscaSeta .5s var(--ease) .1s forwards;
}
.guia-seta path:last-child { animation-delay: .4s; }
/* Uma só ponta desenhada, quatro sentidos. */
.guia-seta.p-topo     { transform: rotate(3deg); }
.guia-seta.p-baixo    { transform: rotate(-3deg) scaleY(-1); }
.guia-seta.p-esquerda { transform: rotate(-12deg); }
.guia-seta.p-direita  { transform: rotate(12deg) scaleX(-1); }

.guia-balao {
  position: fixed; z-index: 303; width: min(340px, calc(100vw - 24px));
  max-height: calc(100vh - 24px); overflow: auto;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-top: 3px solid var(--accent);
  border-radius: var(--r-card); padding: 18px 18px 14px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .6);
  transition: top .28s var(--ease), left .28s var(--ease);
}
.guia-balao:focus { outline: none; }
.guia-conta {
  display: block; font-family: var(--font-serif); font-style: italic;
  font-size: 13.5px; color: var(--accent-claro); margin-bottom: 5px;
}
.guia-balao h3 {
  font-family: var(--font-display); font-weight: 400; margin: 0 0 9px;
  font-size: 20px; line-height: .98; letter-spacing: -.03em; text-transform: uppercase;
}
.guia-balao p { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--text-muted); }

.guia-pe { display: flex; align-items: center; gap: 8px; margin-top: 16px; }
.guia-pontos { display: flex; gap: 5px; margin-right: auto; }
.guia-ponto { width: 6px; height: 6px; background: var(--border-hover); }
.guia-ponto.ativo { background: var(--accent-claro); }

/* Botões próprios: .btn.primary aqui viraria largura 100%. */
.guia-btn {
  font-family: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
  padding: 8px 15px; border-radius: var(--r-ctrl);
  background: transparent; border: 1px solid var(--border); color: var(--text-muted);
  transition: background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.guia-btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-hover); }
.guia-btn.cheio { background: var(--accent); border-color: var(--accent); color: #fff; }
.guia-btn.cheio:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.guia-btn:focus-visible { outline: 2px solid var(--accent-claro); outline-offset: 2px; }

/* O subir do dock faria o alvo escapar do próprio recorte do tour. */
body.guia-aberto .dock-app:hover,
body.guia-aberto .dock-app:focus-visible { translate: 0 0; }

/* Dois botões lado a lado na aba Conta. */
.guia-rever-acoes { display: flex; flex-wrap: wrap; gap: 10px; }
.guia-rever-acoes .btn { width: auto; }

/* Revendo as boas-vindas fora do cadastro, "Passo 4 de 4" mente. */
body.revendo-boas-vindas #screen-tour .wz-step { display: none; }

@media (prefers-reduced-motion: reduce) {
  .guia-recorte, .guia-balao { transition: none; }
  .guia-recorte::after { animation: none; opacity: 0; }
  .guia-seta path { animation: none; stroke-dashoffset: 0; }
}
@media (max-width: 560px) {
  .guia-balao { padding: 15px 15px 12px; }
  .guia-balao h3 { font-size: 17px; }
}

/* ============================================================
   ABERTURA DA ENTRADA — o simbolo chega primeiro
   ------------------------------------------------------------
   Tudo aqui depende da classe .intro-abertura, que o /intro.js poe
   no <html> ANTES do primeiro pixel e TIRA sozinho quando acaba.
   E de proposito: nenhum opacity:0 desta tela existe fora desta
   chave. Sem o script (JS desligado, arquivo faltando, sessao ja
   vista, erro) a tela de entrada nasce completa. E mesmo com ele,
   quando a classe cai, quem ficou no meio do caminho aparece.

   Ordem: selo -> luz atravessando -> B-A-N-K-E letra a letra ->
   risco vermelho -> chamada -> fatos -> cartao -> topo -> trilho ->
   faixa. E a mesma ordem do estudo em _preview-login.html, ~1s mais
   curta: la o desenho ainda precisava virar logo na frente da
   pessoa; aqui o simbolo ja e o simbolo.
   Ultima entrada fecha em 2,64s — dentro dos 2,9s do /intro.js.
   ============================================================ */
.intro-abertura #screen-login { --mola: cubic-bezier(.2, .9, .3, 1); }

/* O fade de troca de tela apagaria a graca: ele levanta a tela
   inteira junto. Durante a abertura o preto e preto de verdade. */

/* --- 1. O SELO (0s -> 0,96s), sozinho no preto ---------------
   O selo nao e SVG: e uma <span> onde a FORMA vem da mask do PNG e
   a COR vem do background. Logo, nada de desenhar traco por traco.
   O que da pra fazer e abrir a mascara com clip-path circular: o B
   nasce no centro e o circulo de gente se fecha em volta dele — que
   e literalmente o que a marca conta. Um wipe reto de baixo pra
   cima cortaria a roda com uma reta e brigaria com a geometria;
   mexer em mask-size cresce a forma mas obriga o navegador a
   redesenhar a mascara todo quadro; so escala e pop de MAD, mas nao
   tem o tempo de "carregando" que o pedido pede.

   O 58% e medido, nao chutado: no PNG a arte vive em 63..448 x
   72..438 de 512, entao sua meia-diagonal a partir do centro e
   ~51,8% da caixa. Aos 78% da duracao a arte ja esta inteira na
   tela; os ultimos 22% varrem a margem vazia e existem so como
   seguro caso um dia a arte passe a sangrar ate a borda. */
@keyframes seloAcende { from { opacity: 0; } to { opacity: 1; } }
@keyframes seloAbre {
  0%   { -webkit-clip-path: circle(0% at 50% 50%); clip-path: circle(0% at 50% 50%); }
  78%  { -webkit-clip-path: circle(58% at 50% 50%); clip-path: circle(58% at 50% 50%); }
  100% { -webkit-clip-path: circle(75% at 50% 50%); clip-path: circle(75% at 50% 50%); }
}
/* O passo alem de 1 aos 62% e o que separa "apareceu" de "chegou":
   o selo passa um fio do tamanho final e volta. Sem ele a marca so
   cresce, e crescer sozinho e movimento de carregamento, nao de
   entrada. */
@keyframes seloPousa {
  from { transform: scale(.72) rotate(-26deg); }
  62%  { transform: scale(1.07) rotate(4deg); }
  to   { transform: scale(1) rotate(0deg); }
}

/* A faisca do estudo, traduzida pra mascara: uma lamina vermelha
   por cima do selo que a PROPRIA mascara do pai recorta (mask vale
   pro elemento e todo o conteudo dele, pseudo incluso). O simbolo
   chega em alarme e escorre pra branco — e o vermelho reaparece no
   "the" logo em seguida, que ja e vermelho. Nao precisa de DOM. */
@keyframes seloEsfria { from { transform: translateY(0); } to { transform: translateY(102%); } }

/* --- 2. O NOME (1,12s -> 1,66s) ------------------------------
   clip-path e nao overflow:hidden: a mascara precisa esconder o que
   sobe por baixo mas NUNCA cortar a lateral. Com overflow:hidden um
   nome mais comprido some sem avisar. */
/* Uma letra de cada vez, em escadinha de 70ms. O nome inteiro subindo
   junto e um bloco que aparece; letra a letra e alguem escrevendo, e
   e isso que prende o olho ate o fim da palavra.
   Cada uma nasce vermelha e esfria pra branco na chegada — mesmo
   gesto da lamina que escorre do selo, agora repetido cinco vezes.
   O bezier passa de 1 de proposito: a letra sobe um fio alem da linha
   e assenta. O clip do pai abre .25em pra cima justamente pra caber
   esse excesso sem cortar. */
@keyframes letraSobe {
  0%   { transform: translateY(106%); color: var(--accent-claro); }
  62%  { color: var(--accent-claro); }
  100% { transform: translateY(0); color: var(--text); }
}

/* O risco que sublinha a marca depois da ultima letra: entra pela
   esquerda, atravessa e sai pela esquerda. Nao fica — e a assinatura
   embaixo do nome, e assinatura que permanece vira borda de caixa.
   Como so existe dentro de .intro-abertura, ele some junto com a
   abertura sem precisar de animacao de saida. */
@keyframes riscoVarre {
  0%   { -webkit-clip-path: inset(0 100% 0 0);   clip-path: inset(0 100% 0 0); }
  46%  { -webkit-clip-path: inset(0 0 0 0);      clip-path: inset(0 0 0 0); }
  100% { -webkit-clip-path: inset(0 0 0 100%);   clip-path: inset(0 0 0 100%); }
}

/* Uma luz atravessando a tela inteira uma unica vez, entre o selo
   pousar e o nome subir. Amarra as duas partes: sem ela a marca
   acontece num canto e o resto da pagina so aparece depois, como se
   fossem duas aberturas diferentes. Fica por cima de tudo (o trilho
   e z-index 2) e nao pega clique. */
.intro-abertura #screen-login::before {
  content: ''; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: linear-gradient(100deg, transparent 42%, rgba(255,255,255,.10) 50%, transparent 58%);
  animation: introLuz .9s var(--duro) .12s both;
}
@keyframes introLuz {
  from { transform: translateX(-115%); opacity: 1; }
  72%  { opacity: 1; }
  to   { transform: translateX(115%); opacity: 0; }
}

/* --- A ABERTURA, em ordem de leitura (0,12s -> 1,05s) ---------
   Antes ela comecava com a marca sendo desenhada letra a letra, e o
   resto so entrava aos 1,58s. Com o nome escrito fora da tela, esse
   comeco virou 1,6 segundo de tela PARADA: a pessoa via o papel vazio
   e achava que travou. Os tempos abaixo foram trazidos pro inicio. */
.intro-abertura #screen-login .hero-lede { animation: introSurge .42s var(--ease) .16s both; }
.intro-abertura #screen-login .facts     { animation: introSurge .42s var(--ease) .3s both; }
/* escadinha por dentro: quem controla a opacidade e a lista inteira,
   os itens so assentam. Dois fades sobrepostos deixariam a lista
   cinzenta no meio do caminho. */
.intro-abertura #screen-login .facts li  { animation: introAssenta .42s var(--mola) both; }
.intro-abertura #screen-login .facts li:nth-child(1) { animation-delay: .33s; }
.intro-abertura #screen-login .facts li:nth-child(2) { animation-delay: .41s; }
.intro-abertura #screen-login .facts li:nth-child(3) { animation-delay: .49s; }
/* O cartao entra SO com opacidade. Transform nele viraria containing
   block pro que for position:fixed la dentro — o mesmo problema
   descrito la em cima, na troca de tela. */
.intro-abertura #screen-login .auth-card    { animation: introSurge .45s var(--ease) .24s both; }
.intro-abertura #screen-login .login-topo   { animation: introSurge .4s  var(--ease) .42s both; }
/* Trilho e faixa fecham a composicao vindo da propria borda de onde
   moram — o trilho pela esquerda, a faixa por baixo. Transform aqui e
   seguro: nenhum dos dois tem filho position:fixed dentro. */
.intro-abertura #screen-login .login-trilho {
  animation: introSurge .5s var(--ease) .55s both,
             trilhoEntra .62s var(--duro) 2.02s both;
}
.intro-abertura #screen-login .sharp-strip {
  animation: introSurge .5s var(--ease) .55s both,
             faixaSobe .58s var(--duro) 2.02s both;
}
@keyframes trilhoEntra { from { transform: translateX(-100%); } to { transform: translateX(0); } }
@keyframes faixaSobe   { from { transform: translateY(34px); }  to { transform: translateY(0); } }

@keyframes introSurge   { from { opacity: 0; } to { opacity: 1; } }
@keyframes introAssenta { from { transform: translateY(8px); } to { transform: translateY(0); } }

/* Menos movimento: tudo de uma vez. animation:none, e nao duracao
   0,01ms — ciclo zero rodando pra sempre queima CPU justamente de
   quem pediu menos movimento. A lista e nominal de proposito: um
   `*` aqui tambem zeraria o rotate(180deg) do trilho e a inclinacao
   da seta desenhada, que sao forma, nao animacao. */
@media (prefers-reduced-motion: reduce) {
  .intro-abertura #screen-login .mk-selo,
  .intro-abertura #screen-login .mk-nome,
  .intro-abertura #screen-login .mk-nome b,
  .intro-abertura #screen-login .mk-nome i,
  .intro-abertura #screen-login .hero-lede,
  .intro-abertura #screen-login .facts,
  .intro-abertura #screen-login .facts li,
  .intro-abertura #screen-login .auth-card,
  .intro-abertura #screen-login .login-topo,
  .intro-abertura #screen-login .login-trilho,
  .intro-abertura #screen-login .sharp-strip {
    animation: none; opacity: 1; transform: none; -webkit-clip-path: none; clip-path: none;
  }
  .intro-abertura #screen-login .mk-selo::before,
  .intro-abertura #screen-login .wordmark::after,
  .intro-abertura #screen-login::before { content: none; }

  /* A faixa de capas roda pra sempre e nao depende da abertura: e a
     unica animacao infinita desta tela. */
  #screen-login .strip-track { animation: none; }
}

/* O tabindex novo na mensagem precisa de foco visível, senão trocar o
   avatar focável por nada seria regressão de acessibilidade. */
#screen-room .msg:focus-visible { outline: 2px solid var(--accent-claro); outline-offset: 2px; }

/* A mesma unica unidade da tela de entrada e do preview: a composicao
   encolhe inteira, nunca se desmonta. */
#screen-nick, #screen-welcome, #screen-onboarding, #screen-tour {
  --u: clamp(10.5px, min(1.05vw, 1.72vh), 18px);

  /* O tamanho de cada peça da geometria mora aqui, e não solto dentro
     do background-size, por dois motivos: o celular precisa encolher
     as cunhas (lá embaixo é só reescrever estas seis linhas) e a
     animação de entrada precisa chegar EXATAMENTE nestes valores —
     com número cravado nos dois lugares, mudar um esquecia o outro e
     a geometria dava um pulo no fim do movimento. */
  --geo-xadrez: calc(var(--u) * 2.6);
  --geo-cunha: calc(var(--u) * 12);
  --geo-base-l: calc(var(--u) * 34);
  --geo-base-a: calc(var(--u) * 26);
  --geo-lasca-l: calc(var(--u) * 22);
  --geo-lasca-a: calc(var(--u) * 14);
  --geo-xadrez-x: calc(var(--u) * 6.2);
  --geo-xadrez-y: calc(var(--u) * 3.4);
}
#screen-nick.active, #screen-welcome.active,
#screen-onboarding.active, #screen-tour.active {
  position: relative; min-height: 100dvh;
  display: flex; flex-direction: column; justify-content: flex-start;
  /* SANGRA ATE A BORDA, como a tela de entrada.
     Havia aqui um max-width de 108*u com margin auto. Num monitor de
     1920 a composicao parava em ~1790px e sobravam duas faixas pretas
     do app, uma de cada lado — o cartaz lia como figura recortada e
     colada numa pagina preta, e nao como papel. Agora a secao ocupa a
     janela inteira e quem centraliza a COLUNA DE TEXTO e o respiro
     lateral: ele cresce ate 7*u e para, senao em tela ultralarga o
     "passo N de 4" desgruda do triangulo vermelho do canto. */
  width: 100%;
  padding-block: calc(var(--u) * 2.4);
  padding-inline: clamp(
    calc(var(--u) * 3),
    calc((100% - var(--u) * 102) / 2),
    calc(var(--u) * 7)
  );
}
/* O papel vai ate a borda da janela, igual ao da tela de entrada: sem
   isto o preto do app reaparece no repique do scroll e na troca de
   tela, que e exatamente a moldura que saiu daqui de cima. */
body:has(#screen-nick.active), body:has(#screen-welcome.active),
body:has(#screen-onboarding.active), body:has(#screen-tour.active) { background: #f2efe7; }

/* ============================================================
   TELAS DO CADASTRO — o desenho do _preview-telas.html
   ------------------------------------------------------------
   Tudo aqui e escopado por ID de propósito: .card, .btn, .field,
   .game-card e .tour-list sao compartilhados com o app inteiro.
   ============================================================ */

/* --- cabecalho: marca + rotulo + passo, uma linha so --- */
#screen-nick .tela-topo, #screen-welcome .tela-topo,
#screen-onboarding .tela-topo, #screen-tour .tela-topo {
  /* O inset: auto não é enfeite. O .tela-topo do app nasce
     position:absolute com top e left próprios; aqui ele volta pro
     fluxo, mas o top e o left CONTINUAVAM valendo — e quando a regra
     de empilhamento lá embaixo devolveu position:relative pra ele
     poder ficar acima da geometria, esses dois números voltaram a
     empurrar a linha da marca uns 30px pra baixo e uns 50px pra
     direita. Era isso que colava "BANKE CADASTRO" no título do passo
     4 e deixava o topo desalinhado da coluna de texto. */
  position: static; inset: auto; flex: none;
  display: flex; align-items: baseline; gap: .6em;
  font-size: calc(var(--u) * .78); letter-spacing: .2em;
  text-transform: uppercase; color: var(--text-dim);
  margin-bottom: calc(var(--u) * 2.2);
}
#screen-nick .tela-topo b, #screen-welcome .tela-topo b,
#screen-onboarding .tela-topo b, #screen-tour .tela-topo b {
  font-size: calc(var(--u) * 1.5);
}
#screen-nick .wz-step, #screen-welcome .wz-step,
#screen-onboarding .wz-step, #screen-tour .wz-step {
  position: static; margin-left: auto;
  font-size: calc(var(--u) * .78); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent-claro);
  background: none; border: 0; padding: 0;
}

/* --- o cartao vira so a coluna de conteudo --- */
#screen-nick .card, #screen-welcome .card,
#screen-onboarding .card, #screen-tour .card {
  background: none; border: 0; padding: 0;
  width: 100%; max-width: 100%;
  flex: 1; min-height: 0; display: flex; flex-direction: column;
}
#screen-nick .card { justify-content: center; max-width: calc(var(--u) * 40); }
#screen-welcome .card { justify-content: center; max-width: calc(var(--u) * 64); }
#screen-tour .card { max-width: calc(var(--u) * 82); }

/* O teto de 9.8vw e o que segura o titulo em 375px: sem ele
   "COMO QUEREM" a 3.6u estoura os 297px uteis. */
#screen-nick .card h2, #screen-welcome .card h2,
#screen-onboarding .card h2, #screen-tour .card h2 {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(26px, calc(var(--u) * 3.6), 9.8vw);
  line-height: .9; letter-spacing: -.04em; text-transform: uppercase;
  margin: 0 0 calc(var(--u) * .6); color: var(--text);
}
#screen-nick .subtitle, #screen-welcome .subtitle,
#screen-onboarding .subtitle, #screen-tour .subtitle {
  font-size: calc(var(--u) * 1.25); line-height: 1.45; color: var(--text-dim);
  max-width: 46ch; margin: 0 0 calc(var(--u) * 2);
}

/* --- botao: retangulo seco, versalete espacado, mede o texto --- */
#screen-nick .btn, #screen-welcome .btn,
#screen-onboarding .btn, #screen-tour .btn {
  border-radius: 0; gap: 0;
  padding: calc(var(--u) * 1) calc(var(--u) * 2.4);
  font-size: calc(var(--u) * .85); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
#screen-nick .btn.primary, #screen-welcome .btn.primary,
#screen-onboarding .btn.primary, #screen-tour .btn.primary {
  width: auto; background: var(--accent); color: #fff;
}
#screen-nick .btn.primary:hover, #screen-welcome .btn.primary:hover,
#screen-onboarding .btn.primary:hover, #screen-tour .btn.primary:hover {
  background: var(--accent-hover);
}

/* --- rodape: o .contador do preview --- */
.wz-rodape {
  flex: none; margin-top: auto;
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  gap: calc(var(--u) * 1); flex-wrap: wrap;
  padding: calc(var(--u) * 1.2) 0;
  border-top: 1px solid var(--border);
  background: var(--bg);
}
.wz-conta { margin: 0; display: flex; align-items: baseline; gap: .5em; }
.wz-conta b {
  font-family: var(--font-display); font-weight: 400;
  font-size: calc(var(--u) * 1.8); letter-spacing: -.03em; color: var(--text);
}
.wz-conta .fact-label { font-size: calc(var(--u) * .7); letter-spacing: .18em; color: var(--text-dim); }
/* Espaco duro depois da seta: em linha, o " " do content colapsa. */
.wz-conta .fact-label::before { content: "\2192\00a0"; }
/* So a grade de jogos e longa: la o rodape gruda no pe da janela.
   Nas outras duas ele segue o conteudo. */
#screen-welcome .wz-rodape, #screen-tour .wz-rodape {
  position: static; margin-top: calc(var(--u) * 2);
}

/* ============================================================
   1. APELIDO
   ============================================================ */
#screen-nick .field { margin-bottom: 0; }
#screen-nick .field span {
  font-size: calc(var(--u) * .7); font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-dim);
  margin-bottom: calc(var(--u) * .6);
}
#screen-nick .field span::before { content: "\2192 "; color: var(--accent-claro); }
#screen-nick input[type=text] {
  background: transparent; border: 1px solid var(--border); border-radius: 0;
  padding: calc(var(--u) * 1.1); font-size: calc(var(--u) * 1.3);
}
#screen-nick input[type=text]:focus {
  outline: 2px solid var(--accent-claro); outline-offset: -1px;
  border-color: transparent; box-shadow: none;
}
.aviso-apelido {
  display: flex; align-items: center; gap: .6em;
  margin: calc(var(--u) * .9) 0 0; min-height: calc(var(--u) * 2);
}
/* Mesmo risco a mao da seta da Steam, mas classe propria: .dica-seta ja
   tem dono (a cutucada do botao da Steam na entrada), vem com 86px,
   animacao infinita, e some no celular. O keyframe riscaSeta, esse sim,
   e reaproveitado — ja existe neste arquivo. */
.seta-apelido {
  flex: none; width: calc(var(--u) * 3.6); height: auto; overflow: visible;
  fill: none; stroke: var(--accent-claro); stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
  transition: opacity .18s var(--ease);
}
.seta-apelido path { stroke-dasharray: 130; stroke-dashoffset: 130; animation: riscaSeta .55s var(--ease) forwards; }
.seta-apelido path:last-child { animation-delay: .3s; }
.aviso-apelido:has(.field-aviso:empty) .seta-apelido { opacity: 0; }
#screen-nick .field-aviso {
  display: block; margin: 0; min-height: 0;
  font-family: var(--font-mao); font-size: calc(var(--u) * 1.2);
  line-height: 1.1; color: var(--text-dim);
}
#screen-nick .field-aviso.bom { color: var(--online); }
#screen-nick .field-aviso.ruim { color: var(--accent-claro); }
#screen-nick .linha-btn { display: flex; gap: calc(var(--u) * .7); margin-top: calc(var(--u) * 1.4); }
#screen-nick .setting-note {
  margin: calc(var(--u) * 1.2) 0 0; max-width: 46ch;
  font-size: calc(var(--u) * .82); color: var(--text-dim);
}

/* ============================================================
   2. PLATAFORMA
   ============================================================ */
#screen-welcome .platform-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(calc(var(--u) * 9), 1fr));
  gap: calc(var(--u) * .8); margin: calc(var(--u) * .8) 0 0;
}
#screen-welcome .platform-opt {
  position: relative; border-radius: 0;
  background: transparent; border: 1px solid var(--border);
  padding: calc(var(--u) * 1.4) calc(var(--u) * .8);
  gap: calc(var(--u) * .7);
  font-size: calc(var(--u) * .76); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
#screen-welcome .platform-opt:hover { transform: none; border-color: var(--border-hover); background: var(--surface); }
#screen-welcome .platform-opt.selected {
  border-color: var(--accent-claro); background: rgba(var(--accent-rgb), .07);
  box-shadow: inset 0 0 0 2px var(--accent-claro);
}
/* --accent, nao --accent-claro: aqui e preenchimento com texto branco. */
#screen-welcome .platform-opt.selected::after {
  content: "\2713"; position: absolute;
  top: calc(var(--u) * .4); right: calc(var(--u) * .4);
  width: calc(var(--u) * 1.5); height: calc(var(--u) * 1.5);
  background: var(--accent); color: #fff;
  display: grid; place-items: center; line-height: 1;
  font-size: calc(var(--u) * .9); font-weight: 700; letter-spacing: 0;
}

/* ============================================================
   3. JOGOS — a capa em cinza que volta a cor quando escolhida
   ------------------------------------------------------------
   Tudo escopado em #screen-onboarding: o card do LOBBY continua
   4/3, colorido e com a revelacao por IntersectionObserver.
   ============================================================ */
/* Teto de largura na busca: com o cartaz sangrando de borda a borda,
   sem ele o campo virava uma régua de quase dois mil pixels. O CARTÃO
   continua sem teto de propósito — é ele que leva a grade e a barra do
   rodapé até perto da beirada, como era antes. */
#screen-onboarding .search-wrap { margin: 0 0 calc(var(--u) * 1.2); max-width: calc(var(--u) * 40); }
#screen-onboarding input.search {
  border-radius: 0; background: transparent; border: 1px solid var(--border);
  padding: calc(var(--u) * .85) calc(var(--u) * 1) calc(var(--u) * .85) calc(var(--u) * 2.6);
  font-size: calc(var(--u) * 1.05);
}
#screen-onboarding input.search:focus {
  outline: 2px solid var(--accent-claro); outline-offset: -1px;
  border-color: transparent; box-shadow: none;
}
#screen-onboarding .search-ic { left: calc(var(--u) * .95); }
/* O aviso da biblioteca da Steam e um aparte, nao uma caixa: serifada
   italica com o fio vermelho ao lado, igual a mensagem de sistema. */
#screen-onboarding .owned-banner {
  margin: 0 0 calc(var(--u) * 1); padding: calc(var(--u) * .5) 0 calc(var(--u) * .5) calc(var(--u) * .8);
  border: 0; border-left: 2px solid var(--accent-claro); border-radius: 0;
  background: none; color: var(--text-dim);
  font-family: var(--font-serif); font-style: italic; font-size: calc(var(--u) * 1);
}
#screen-onboarding .game-grid {
  flex: 1; align-content: start; margin: 0;
  gap: calc(var(--u) * .8);
  grid-template-columns: repeat(auto-fill, minmax(calc(var(--u) * 13), 1fr));
}
#screen-onboarding .game-card {
  aspect-ratio: 460 / 215; border-radius: 0; animation: none;
  background: var(--surface-2);
}
#screen-onboarding .game-card:hover { transform: none; border-color: var(--border-hover); }
/* A CAPA FICA COMO NO LOBBY: EM CORES, COM O VIDRO ATRAS DO NOME
   Cada card nasce com duas cópias da capa — a nítida e uma segunda
   borrada atrás de uma máscara em degradê. É a borrada que faz o nome
   ser lido sobre a arte, sem backdrop-filter e sem o engasgo que ele
   trazia numa grade de sessenta cards.
   Aqui havia um `filter: grayscale(1)` com `opacity: .45` por cima das
   duas cópias. Ele fazia duas estragos de uma vez: apagava a arte, e
   como blur também é filtro, levava embora o borrão junto — o vidro
   simplesmente não existia nesta tela.
   Agora não há filtro nenhum: a capa aparece igual à do lobby, e quem
   diz o que está escolhido é a moldura vermelha com a sombra encostada
   e o visto no canto, que gritam mais que um cinza. */
#screen-onboarding .game-card .cover img { transition: transform .2s var(--duro); }
/* O card do cadastro não dá zoom na capa: ele se levanta inteiro, com
   a sombra dura. Duas animações no mesmo gesto brigariam. */
#screen-onboarding .game-card:hover .cover img,
#screen-onboarding .game-card:hover .cover img.cover-borrao { transform: none; }
#screen-onboarding .game-card.selected { border-color: var(--accent-claro); }
#screen-onboarding .game-card.selected::after { border-radius: 0; box-shadow: inset 0 0 0 2px var(--accent-claro); }
#screen-onboarding .game-card.selected::before {
  content: "\2713"; position: absolute; z-index: 4;
  top: calc(var(--u) * .4); right: calc(var(--u) * .4);
  width: calc(var(--u) * 1.5); height: calc(var(--u) * 1.5);
  background: var(--accent); color: #fff;
  display: grid; place-items: center; line-height: 1;
  font-size: calc(var(--u) * .9); font-weight: 700;
}
/* O véu PARA ANTES DE TAPAR, igual ao do lobby.
   Ele terminava em .96/.99 — creme praticamente opaco. Com isso a
   cópia borrada da capa continuava lá embaixo e não se via nada dela:
   o pé do card virava uma tarja branca chapada, com a arte cortada
   numa linha reta. É por isso que o vidro não aparecia aqui.
   Agora fecha em .64, como o do lobby fecha em .62: o suficiente pra
   segurar o nome, pouco o bastante pra arte borrada aparecer através.
   A rampa começa mais embaixo (34% e não 28%) porque este card é baixo
   e largo — a mesma curva do lobby, num card desta altura, subiria
   pela arte toda. */
#screen-onboarding .game-card .scrim,
#screen-onboarding .game-card:hover .scrim {
  background: linear-gradient(180deg,
    rgba(var(--bg-rgb),0) 34%,
    rgba(var(--bg-rgb),.10) 48%,
    rgba(var(--bg-rgb),.28) 58%,
    rgba(var(--bg-rgb),.46) 68%,
    rgba(var(--bg-rgb),.58) 80%,
    rgba(var(--bg-rgb),.64) 100%);
}
#screen-onboarding .game-card .body { padding: calc(var(--u) * .5) calc(var(--u) * .6); }
#screen-onboarding .game-card .name {
  font-family: var(--font-body); font-weight: 700;
  font-size: max(11.5px, calc(var(--u) * .72)); letter-spacing: .04em;
  text-transform: uppercase; margin: 0; line-height: 1.2;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  /* Halo escuro colado nas letras. O véu para em .64 pra deixar o
     borrão aparecer, então em capa clara (Astroneer, Don't Starve) o
     pé fica claro e branco sobre claro some. Tapar mais o véu mataria
     o vidro de novo — quem segura a leitura é a sombra, como manda o
     card original: três camadas, a mais fechada colada na letra. O
     halo ocupa só o contorno; o borrão continua visível em volta. */
  /* Branco, como no lobby: o véu do pé agora fecha no escuro. */
  color: #fff;
  text-shadow:
    0 0 2px rgba(var(--bg-rgb), 1),
    0 0 5px rgba(var(--bg-rgb), .96),
    0 1px 3px rgba(var(--bg-rgb), 1);
}
#screen-onboarding .game-card .tag { display: none; }
/* O visto mora no canto direito, entao as etiquetas mudam de lado. */
#screen-onboarding .game-card .owned-tag {
  left: calc(var(--u) * .4); right: auto; top: calc(var(--u) * .4);
  border-radius: 0; background: var(--surface); border: 1px solid var(--border);
  color: var(--text-dim); backdrop-filter: none;
  font-size: max(9.5px, calc(var(--u) * .55)); padding: calc(var(--u) * .25) calc(var(--u) * .5);
}
#screen-onboarding .game-card .soon-tag {
  left: calc(var(--u) * .4); top: calc(var(--u) * .4);
  border-radius: 0; backdrop-filter: none;
  font-size: max(9.5px, calc(var(--u) * .55)); padding: calc(var(--u) * .25) calc(var(--u) * .5);
}
/* Os dois juntos e raro, mas quando acontece o segundo desce uma linha. */
#screen-onboarding .game-card .owned-tag + .soon-tag { top: calc(var(--u) * 1.9); }
#screen-onboarding #onboardingEmpty { margin: calc(var(--u) * 2) 0; }

/* ============================================================
   4. COMO O BANKE FUNCIONA — a tela que vale rever
   ------------------------------------------------------------
   O algarismo vazado em vermelho vem do trilho da tela de entrada:
   e o mesmo -webkit-text-stroke. Numeracao por contador CSS, entao
   o HTML nao carrega numero nenhum.
   ============================================================ */
#screen-tour .tour-list {
  list-style: none; margin: 0 0 calc(var(--u) * 1.2); padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 calc(var(--u) * 2.6);
  border-top: 1px solid var(--border);
  counter-reset: passo;
}
#screen-tour .tour-list li {
  display: grid; grid-template-columns: calc(var(--u) * 3) calc(var(--u) * 1.8) 1fr;
  gap: calc(var(--u) * .8); align-items: start;
  padding: calc(var(--u) * 1.15) 0;
  border-bottom: 1px solid var(--border);
}
/* Em duas colunas, o ultimo item perder o filete deixa a grade torta. */
#screen-tour .tour-list li:last-child { border-bottom: 1px solid var(--border); }
#screen-tour .tour-list li::before {
  counter-increment: passo;
  content: counter(passo, decimal-leading-zero);
  font-family: var(--font-display); font-weight: 400;
  font-size: calc(var(--u) * 2.1); line-height: .82; letter-spacing: -.04em;
  color: transparent; -webkit-text-stroke: 1px var(--accent-claro);
}
/* A pastilha arredondada sai: aresta viva, icone solto em vermelho. */
#screen-tour .tour-ic {
  width: auto; height: auto; border-radius: 0; background: none;
  color: var(--accent-claro); justify-self: start; margin-top: calc(var(--u) * .1);
}
#screen-tour .tour-list li div { gap: calc(var(--u) * .25); }
#screen-tour .tour-list li strong {
  font-family: var(--font-display); font-weight: 400;
  font-size: calc(var(--u) * 1.15); letter-spacing: -.02em;
  text-transform: uppercase; color: var(--text);
}
#screen-tour .tour-list li span {
  font-size: calc(var(--u) * .92); line-height: 1.5; color: var(--text-dim);
  max-width: 42ch;
}
/* Revendo fora do cadastro, o rotulo conta a verdade. E decorativo
   (aria-hidden), entao trocar por content nao esconde nada de ninguem. */
body.revendo-boas-vindas #screen-tour .tl-rot { font-size: 0; }
body.revendo-boas-vindas #screen-tour .tl-rot::after {
  content: "como funciona"; font-size: calc(var(--u) * .78);
}

/* ============================================================
   O CARTAZ ENTRANDO — o movimento das quatro telas do cadastro
   ------------------------------------------------------------
   Uma gramática só, repetida nos quatro passos: a geometria cresce
   dos cantos como papel sendo recortado, o título é DESCOBERTO de
   cima pra baixo, e o resto sobe em cascata atrás dele. Quem dispara
   é o .active, que o showScreen() tira e põe a cada passo — então o
   movimento acontece na troca de tela e nunca no meio da digitação.

   Tudo mora dentro de um @media (prefers-reduced-motion:
   no-preference). É de propósito: assim quem pediu menos movimento no
   sistema simplesmente não recebe nenhuma destas regras, e não
   precisamos desligar uma por uma lá embaixo — desligar em bloco
   apagaria junto a setinha desenhada do aviso de apelido, que nasce
   invisível e só aparece PORQUE é animada.

   Regra de ouro: fill-mode BACKWARDS, nunca forwards. Animação com
   forwards ganha do :hover e do :active na cascata, e o botão pararia
   de afundar no clique depois da primeira entrada.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {

  /* --- a geometria: as quatro camadas de fundo nascem com tamanho
         zero e abrem ancoradas na quina. As cunhas primeiro; o xadrez
         é o último a pousar, já sobre o vermelho pronto. --- */
  @keyframes cartazGeo {
    0% {
      background-size: 0 0, 0 0, 0 0, 0 0;
    }
    55% {
      background-size:
        0 0,
        var(--geo-cunha) var(--geo-cunha),
        var(--geo-base-l) var(--geo-base-a),
        var(--geo-lasca-l) var(--geo-lasca-a);
    }
    100% {
      background-size:
        var(--geo-xadrez) var(--geo-xadrez),
        var(--geo-cunha) var(--geo-cunha),
        var(--geo-base-l) var(--geo-base-a),
        var(--geo-lasca-l) var(--geo-lasca-a);
    }
  }
  /* O título aparece revelado por um corte que desce, não por fade: é
     o gesto de papel do resto da tela. As sobras negativas no inset
     final existem pro acento do "Ê" e pra perna do "Q" não ficarem
     raspados pela máscara. */
  @keyframes cartazTitulo {
    from { opacity: 0; clip-path: inset(0 0 105% 0); transform: translateY(calc(var(--u) * .4)); }
    to   { opacity: 1; clip-path: inset(-.3em -.3em -.2em -.3em); transform: none; }
  }
  @keyframes cartazTopo  { from { opacity: 0; transform: translateY(calc(var(--u) * -.9)); } }
  @keyframes cartazDaDir { from { opacity: 0; transform: translateX(calc(var(--u) * 1.4)); } }
  @keyframes cartazSobe  { from { opacity: 0; transform: translateY(calc(var(--u) * 1.1)); } }
  /* Bloco com sombra dura: chega deslocado pra cima e pra esquerda,
     SEM sombra, e a sombra nasce no instante em que ele pousa. */
  @keyframes cartazBloco {
    from { opacity: 0; transform: translate(calc(var(--u) * -.55), calc(var(--u) * -.55)); box-shadow: 0 0 0 var(--tinta); }
  }

  #screen-nick.active, #screen-welcome.active,
  #screen-onboarding.active, #screen-tour.active {
    animation: screenFade .3s var(--ease) both,
               cartazGeo .8s var(--duro) backwards;
  }

  /* --- o que é igual nas quatro telas --- */
  #screen-nick.active .tela-topo, #screen-welcome.active .tela-topo,
  #screen-onboarding.active .tela-topo, #screen-tour.active .tela-topo {
    animation: cartazTopo .5s var(--ease) .04s backwards;
  }
  /* O passo entra pelo lado direito, de onde ele mora. */
  #screen-nick.active .wz-step, #screen-welcome.active .wz-step,
  #screen-onboarding.active .wz-step, #screen-tour.active .wz-step {
    animation: cartazDaDir .55s var(--ease) .16s backwards;
  }
  #screen-nick.active .card h2, #screen-welcome.active .card h2,
  #screen-onboarding.active .card h2, #screen-tour.active .card h2 {
    animation: cartazTitulo .66s var(--duro) .1s backwards;
  }
  #screen-nick.active .subtitle, #screen-welcome.active .subtitle,
  #screen-onboarding.active .subtitle, #screen-tour.active .subtitle {
    animation: cartazSobe .5s var(--ease) .24s backwards;
  }
  #screen-welcome.active .wz-rodape, #screen-onboarding.active .wz-rodape,
  #screen-tour.active .wz-rodape {
    animation: cartazSobe .5s var(--ease) .46s backwards;
  }

  /* --- passo 1: apelido --- */
  #screen-nick.active .field   { animation: cartazBloco .5s var(--duro) .32s backwards; }
  #screen-nick.active .aviso-apelido { animation: cartazSobe .45s var(--ease) .42s backwards; }
  #screen-nick.active .linha-btn     { animation: cartazBloco .5s var(--duro) .42s backwards; }
  #screen-nick.active .setting-note  { animation: cartazSobe .45s var(--ease) .52s backwards; }

  /* --- passo 2: plataformas. Cada bloco pousa depois do anterior,
         da esquerda pra direita, como quem enfileira cartão. --- */
  #screen-welcome.active .platform-opt { animation: cartazBloco .46s var(--duro) backwards; }
  #screen-welcome.active .platform-opt:nth-child(1) { animation-delay: .3s; }
  #screen-welcome.active .platform-opt:nth-child(2) { animation-delay: .36s; }
  #screen-welcome.active .platform-opt:nth-child(3) { animation-delay: .42s; }
  #screen-welcome.active .platform-opt:nth-child(4) { animation-delay: .48s; }
  #screen-welcome.active .platform-opt:nth-child(5) { animation-delay: .54s; }

  /* --- passo 3: jogos. A grade entra INTEIRA, e não capa por capa:
         a lista se refaz a cada letra digitada na busca, e uma cascata
         ali piscaria a tela toda a cada tecla. --- */
  #screen-onboarding.active .search-wrap  { animation: cartazBloco .5s var(--duro) .3s backwards; }
  #screen-onboarding.active .owned-banner { animation: cartazSobe .45s var(--ease) .38s backwards; }
  #screen-onboarding.active .game-grid    { animation: cartazSobe .5s var(--ease) .4s backwards; }

  /* --- passo 4: as quatro linhas do tour, uma atrás da outra --- */
  #screen-tour.active .tour-list li { animation: cartazSobe .5s var(--ease) backwards; }
  #screen-tour.active .tour-list li:nth-child(1) { animation-delay: .3s; }
  #screen-tour.active .tour-list li:nth-child(2) { animation-delay: .37s; }
  #screen-tour.active .tour-list li:nth-child(3) { animation-delay: .44s; }
  #screen-tour.active .tour-list li:nth-child(4) { animation-delay: .51s; }
}

/* ============================================================
   CELULAR — a regua proporcional vira px, igual a tela de entrada
   ============================================================ */
@media (max-width: 900px) {
  #screen-nick, #screen-welcome, #screen-onboarding, #screen-tour {
    --u: 13px;
    /* A geometria encolhe junto. Nas medidas do monitor a cunha de
       baixo dava 34*13 = 442px de largura num aparelho de 375: ela
       cobria metade da tela e comia o texto de baixo do campo. */
    --geo-xadrez: calc(var(--u) * 1.8);
    --geo-cunha: calc(var(--u) * 7);
    --geo-base-l: calc(var(--u) * 17);
    --geo-base-a: calc(var(--u) * 13);
    --geo-lasca-l: calc(var(--u) * 11);
    --geo-lasca-a: calc(var(--u) * 7);
    --geo-xadrez-x: calc(var(--u) * 3.4);
    --geo-xadrez-y: calc(var(--u) * 1.9);
  }
  #screen-nick.active, #screen-welcome.active,
  #screen-onboarding.active, #screen-tour.active {
    padding: calc(var(--u) * 2) calc(var(--u) * 1.4) calc(var(--u) * 1.6);
  }
  /* Com a cunha vermelha menor, o respiro reservado pra ela também
     diminui — e é isso que devolve o topo pra UMA linha. Nos 13*u do
     monitor sobravam 170px pra 253px de texto, e "PASSO 1 DE 4"
     quebrava embaixo da marca. */
  #screen-nick .tela-topo, #screen-welcome .tela-topo,
  #screen-onboarding .tela-topo, #screen-tour .tela-topo {
    margin-bottom: calc(var(--u) * 1.6);
    padding-right: calc(var(--u) * 6);
  }
  #screen-nick .wz-step, #screen-welcome .wz-step,
  #screen-onboarding .wz-step, #screen-tour .wz-step { white-space: nowrap; }
  #screen-onboarding .game-grid {
    grid-template-columns: repeat(auto-fill, minmax(calc(var(--u) * 11), 1fr));
  }
  #screen-tour .tour-list { grid-template-columns: 1fr; }
}
/* O @media (pointer: coarse) la de cima usa input[type=text], que perde
   pros seletores com ID daqui. Sem isto, o Safari do iPhone da o zoom. */
@media (pointer: coarse) {
  #screen-nick input[type=text], #screen-onboarding input.search { font-size: 16px; }
}

/* ============================================================
   ENTRADA DAS OUTRAS TELAS (lobby, sala, amigos...)
   ------------------------------------------------------------
   A abertura grande e so da tela de entrada. Quem recarrega ja
   logado cai direto no lobby, e antes disso nao via movimento
   nenhum — a pagina simplesmente aparecia pronta. Esta e uma
   entrada curta, aplicada pelo /intro.js na primeira tela que
   nasce ativa no carregamento (e so nela).
   Curta de proposito: quem recarrega quer usar o app, nao assistir.
   ============================================================ */
.intro-entrada { animation: telaEntra .45s var(--ease) both; }
@keyframes telaEntra {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .intro-entrada { animation: none; }
}


/* ============================================================
   SEM TRAÇOS
   ------------------------------------------------------------
   Todo elemento tinha um fio de 1px em volta: cartão, campo, botão
   fantasma, chip, capa de jogo, aba. Junto, isso virava uma grade de
   caixinhas — dava pra ver na tela de Conta, onde três cartões
   empilhados eram três retângulos riscados um embaixo do outro.
   O contorno saiu; quem separa agora é o FUNDO: a página é preta, o
   cartão é um degrau acima, o campo é outro degrau. Mesma leitura,
   sem riscar nada.
   O token continua existindo (e continua ocupando 1px no layout, então
   nada se mexe de lugar) porque os ESTADOS ainda precisam dele: foco de
   teclado, campo em foco, plataforma marcada, aba selecionada. Esses
   têm cor própria e são justamente o que deve aparecer.
   ============================================================ */
/* >>> REVERTIDO A PEDIDO: sem fio nenhum as telas ficaram pretas e
   vazias, sem estrutura pra guiar o olho. Os degraus de fundo abaixo
   CONTINUAM valendo — fundo e fio agora trabalham juntos, em vez de um
   substituir o outro.
   Os valores sobem um pouco em relacao aos originais porque o fundo
   escureceu de #0b1016 pra #0a0a0a: mantendo a cor antiga, o fio ficava
   em 1,38:1 contra o fundo, praticamente invisivel. */
/* Os degraus de fundo, agora no papel.
   ------------------------------------------------------------
   Este bloco inteiro foi escrito quando o app era preto: fundo de
   campo #232323, veu branco a 6% no botao fantasma, hover #262626.
   No creme nada disso funciona — campo preto vira buraco na pagina e
   veu branco sobre papel e invisivel. Aqui os mesmos degraus sao
   refeitos pro claro: o papel e o fundo, o branco e o degrau acima,
   e quem precisa de peso usa a tinta em transparencia. */
.setting-card { background: #fff; }
input[type=text], input[type=password], input[type=email],
input[type=search], input[type=number], textarea, .composer input {
  background: #fff; border: 1px solid var(--tinta);
}
input[type=text]::placeholder, input[type=password]::placeholder,
input[type=email]::placeholder, textarea::placeholder,
.composer input::placeholder { color: rgba(18, 16, 14, .45); }
.linked-item, .count-pill { background: rgba(18, 16, 14, .06); }

/* Botão fantasma sem moldura viraria texto solto: ganha um fundo de
   leve pra continuar parecendo botão. Nas barras de topo, não — lá o
   projeto já tinha tirado a moldura de propósito. */
.btn.ghost { background: rgba(18, 16, 14, .07); }
.btn.ghost:hover { background: rgba(18, 16, 14, .13); }
.topbar .btn.ghost, .float-nav .btn.ghost { background: transparent; }
.topbar .btn.ghost:hover, .float-nav .btn.ghost:hover { background: rgba(18, 16, 14, .07); }
/* No cartaz nao existe botao de moldura vazia: o secundario e um
   bloco chapado preto, fazendo par com o vermelho do primario. */
.btn.outline { background: var(--tinta); color: #fff; border-color: var(--tinta); }
.btn.outline:hover { background: #000; border-color: #000; }

/* Hover que só acendia o fio agora acende o fundo. */
.snav-item:hover, .kind-opt:hover, .slot-opt:hover, .platform-opt:hover {
  background: rgba(18, 16, 14, .07);
}

/* Aba: fica só o filete vermelho da SELECIONADA — ele diz onde você
   está, e some junto com o resto seria perder a informação. */
.profile-tabs, .auth-tabs { border-bottom-color: var(--divisor); }
#screen-login .btn.outline, #screen-login .btn.ghost {
  background: rgba(255, 255, 255, .07);
}
#screen-login .btn.outline:hover, #screen-login .btn.ghost:hover {
  background: rgba(255, 255, 255, .13);
}
/* Recado do sistema no chat: era uma pílula vazada. Vira pílula cheia,
   de fundo baixo — continua se lendo como "isto não é mensagem de gente". */
.msg.system .m-body { background: rgba(255, 255, 255, .05); }

/* Amigos: a lista e a conversa eram separadas por um fio vertical. Sem
   ele as duas colunas viravam uma mancha só. Quem separa agora é o
   fundo — a coluna da lista fica um degrau acima. */
.friends-col { background: rgba(255, 255, 255, .035); padding: 18px 20px; }


/* ============================================================
   CONTA: TRAVA DO APELIDO, CONTAS CONECTADAS E SUPORTE
   ============================================================ */

/* Campo travado: continua legível (não é erro, é regra), mas some o
   convite pra digitar. O fundo era #191919, de quando a página era
   preta — no papel isso virava um retângulo preto no meio do
   formulário. Agora é um degrau de cinza sobre o creme. */
input.travado, input:disabled {
  color: var(--text-muted); background: rgba(18, 16, 14, .08); cursor: not-allowed;
}

/* O aviso da regra. Serifada itálica é a voz de aparte do projeto —
   é recado, não rótulo de campo. */
.trava-aviso {
  font-family: var(--font-serif); font-style: italic;
  font-size: 13px; line-height: 1.55; color: var(--text-muted);
  margin: -6px 0 14px;
}
/* O cadeado entra NA linha do texto. Os ícones do projeto são
   display:block por padrão (viram bloco próprio), e aqui isso jogava a
   frase pra outra linha no meio da palavra. */
.trava-aviso .ic { display: inline-block; vertical-align: -2px; margin-right: 5px; color: var(--accent-claro); }
.trava-aviso strong { font-style: normal; font-family: var(--font-body); color: var(--text); }

/* Linha de conta conectada: nome à esquerda, situação e ação à direita. */
.linked-item .li-status { text-align: right; }
.linked-item .btn { margin: 0; width: auto; flex-shrink: 0; }
.linked-item .li-ok { display: flex; color: var(--online); }
/* Em tela estreita a linha quebra: e-mail longo não pode espremer o botão. */
@media (max-width: 520px) {
  .linked-item { flex-wrap: wrap; }
  .linked-item .li-name { flex: 1 0 100%; }
  .linked-item .li-status { flex: 1; text-align: left; }
}

/* Por onde responder um chamado de suporte. */
.rc-contato {
  font-size: 12.5px; color: var(--text-dim); margin: 12px 0 0;
}
.rc-contato a { color: var(--accent-claro); }
.rc-contato em { font-style: italic; opacity: .85; }

/* Link dentro de recado e de modal. Sem isto o navegador desenha o azul
   dele, que não existe nesta paleta — e o link de redefinição de senha
   ficava azul-sublinhado no meio do preto e vermelho. */
.setting-note a, .modal-lede a, .drawer-note a {
  color: var(--accent-claro); text-decoration: underline; text-underline-offset: 2px;
}
.setting-note a:hover, .modal-lede a:hover, .drawer-note a:hover { color: var(--accent-hover); }

/* Botão que é link: usado no aviso de "esqueci a senha atual". */
.link-btn {
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: var(--accent-claro); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}

/* Abas da moderação: mesma cara das do perfil, com o contador ao lado. */
.atab .count-pill { margin-left: 4px; }

/* ============================================================
   A TELINHA — boas-vindas no estilo do cartaz de tipografia
   ------------------------------------------------------------
   Um cartaz sangrado de borda a borda: papel creme, tipo preto
   pesado, duas cunhas diagonais, meio-tom e grao. Nao ha aparelho
   nenhum em volta — a tela E o cartaz. Ele entra varrendo, se monta
   na ordem de leitura, e o "press start" varre ele pra fora antes
   de entregar a tela de entrada.

   Sangrar de borda a borda e o motivo de quase tudo aqui ser medido
   em fracao da janela: a mesma composicao tem que fechar num
   monitor deitado e num celular em pe, sem sobra e sem corte. Por
   isso tambem cada cunha tem CAIXA propria ancorada num canto, e o
   poligono desenha dentro dela — um poligono esticado na tela
   inteira ficaria deitado no monitor e em pe no celular.

   O papel e claro DE PROPOSITO: e uma folha acesa no meio do preto
   do app, e a virada pra tela de entrada vira o gesto em vez de um
   detalhe.

   Regra de ouro, a mesma do /intro.js: nasce display:none. Quem
   liga e a classe .ap-aberta no <html>, posta pelo script antes do
   primeiro pixel. Script quebrado, ausente ou bloqueado => o Banke
   abre direto na entrada. Esta telinha nunca tranca ninguem do
   lado de fora.

   O vermelho entra UMA vez, no triangulo do play. Num cartaz preto
   e branco, um acento so grita mais alto do que cinco.
   ============================================================ */
#apresentacao { display: none; }
html.ap-aberta #apresentacao {
  display: block;
  position: fixed; inset: 0; z-index: 400; overflow: hidden;
  /* O preto do app enquanto o cartaz entra: e dele que a folha
     nasce. Na saida ele sai de cena (ver .ap-saindo la embaixo). */
  background: var(--bg);
  /* A unidade do cartaz: tudo aqui dentro encolhe junto, em vez de
     vinte medidas soltas em px. Entra pela MENOR das duas dimensoes
     porque a composicao e alta — numa janela baixa e larga quem
     falta e sempre a altura. */
  --ap: clamp(8px, min(1.15vw, 1.9vh), 20px);
  --papel: #efeae0;
  --tinta: #0d0d0d;
}
html.ap-aberta, html.ap-aberta body { overflow: hidden; }
/* Canto vivo tambem no foco de teclado: o raio padrao do app poria
   um retangulo arredondado no meio de um cartaz que nao tem nenhum. */
#apresentacao :focus-visible { border-radius: 0; outline-offset: 3px; }

/* --- o papel --------------------------------------------------
   Uma folha so, do tamanho da janela. Sem raio e sem borda: e o
   raio que devolveria a moldura por outro caminho. --- */
.ap-tela {
  position: absolute; inset: 0; overflow: hidden;
  background: var(--papel); color: var(--tinta);
  /* Contexto de empilhamento declarado, e nao herdado do clip-path
     da animacao: e ele que garante o z-index -1 do brilho aqui
     embaixo — luz por cima do papel e por BAIXO de tudo o que esta
     impresso nele. */
  z-index: 0;
}
/* O brilho que atravessa de tempos em tempos — o mesmo gesto da
   abertura da entrada. E o que faz a folha parecer viva sem
   precisar da linha de varredura de tubo. Anda em transform, e nao
   em left, pra nao recalcular layout doze vezes por segundo.

   z-index negativo: ele passa POR BAIXO da tinta. Por cima, clareava
   o preto do nome e das cunhas junto com o papel, e o cartaz inteiro
   desbotava por dois segundos a cada volta. */
.ap-tela::after {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  top: -60%; bottom: -60%; left: 0; width: 34%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  /* `backwards` nao e enfeite: sem ele, durante os 2,6s de espera a
     faixa fica parada e visivel no meio da folha, lavando o tipo. */
  animation: apBrilho 11s var(--ease) 2.6s infinite backwards;
}
@keyframes apBrilho {
  0%   { transform: translateX(-160%) rotate(14deg); }
  26%  { transform: translateX(320%)  rotate(14deg); }
  100% { transform: translateX(320%)  rotate(14deg); }
}

/* --- as cunhas ------------------------------------------------
   Poligono e nao rotacao: a borda tem que morrer exatamente na
   aresta da folha, e retangulo girado deixa canto sobrando ou
   faltando. */
.ap-cunha { position: absolute; z-index: 0; }

/* A da esquerda e uma FAIXA na diagonal, nao um triangulo cheio no
   canto: sobra creme embaixo dela, e e nesse creme que a assinatura
   mora. Triangulo cheio comia o canto inteiro.
   A tinta esta nos dois pseudo-elementos, e nao no <span>: clip-path
   no pai cortaria o filho junto, e a faixa e o fio precisam de
   recortes diferentes. */
.ap-cunha-esq {
  left: 0; bottom: 0;
  width: min(30vw, calc(var(--ap) * 32)); height: min(38vh, calc(var(--ap) * 26));
}
.ap-cunha-esq::before, .ap-cunha-esq::after {
  content: ''; position: absolute; inset: 0; background: var(--tinta);
}
.ap-cunha-esq::before {
  -webkit-clip-path: polygon(0 0, 26% 0, 100% 100%, 74% 100%);
  clip-path: polygon(0 0, 26% 0, 100% 100%, 74% 100%);
}
/* O fio paralelo, mais fino, correndo pro canto de baixo. No cartaz
   ele existe, e e ele que amarra a geometria na aresta da folha. */
.ap-cunha-esq::after {
  -webkit-clip-path: polygon(0 42%, 4% 42%, 47% 100%, 43% 100%);
  clip-path: polygon(0 42%, 4% 42%, 47% 100%, 43% 100%);
}
/* A da direita e o peso do cartaz: um triangulo cheio sangrando
   pelas duas bordas do canto. */
.ap-cunha-dir {
  right: 0; bottom: 0; background: var(--tinta);
  width: min(38vw, calc(var(--ap) * 42)); height: min(46vh, calc(var(--ap) * 34));
  -webkit-clip-path: polygon(100% 0, 100% 100%, 0 100%);
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

/* A escadinha de pixels que emenda o fim do nome na cunha da
   direita. E o unico lugar do cartaz onde o "pixel" aparece
   literal — por isso ele mora aqui, e nao espalhado. */
.ap-escada {
  position: absolute; right: 10%; top: 52%; z-index: 1;
  width: calc(var(--ap) * 1); height: calc(var(--ap) * 1);
  background: var(--tinta);
  box-shadow:
    calc(var(--ap) * 1)   calc(var(--ap) * 1)   0 var(--tinta),
    calc(var(--ap) * 2)   calc(var(--ap) * 1)   0 var(--tinta),
    calc(var(--ap) * 2)   calc(var(--ap) * 2)   0 var(--tinta),
    calc(var(--ap) * 3)   calc(var(--ap) * 3)   0 var(--tinta);
}

/* O simbolo no alto a direita, no lugar do desenho da casa. */
.ap-simbolo {
  position: absolute; top: calc(var(--ap) * 2.6); right: calc(var(--ap) * 4.4); z-index: 1;
  width: min(calc(var(--ap) * 11), 15vmin); aspect-ratio: 1;
  background-color: var(--tinta);
  -webkit-mask: url('/marca-banke.svg') center / contain no-repeat;
  mask: url('/marca-banke.svg') center / contain no-repeat;
}

/* --- o cartaz -------------------------------------------------- */
.ap-conteudo {
  position: relative; z-index: 2;
  width: 100%; height: 100%;
  padding: calc(var(--ap) * 3.4) calc(var(--ap) * 4.4) calc(var(--ap) * 3);
  display: flex; flex-direction: column; align-items: flex-start;
  text-align: left;
}

/* "MURAL DE COOP ————————" : rotulo e regua na mesma linha, como
   no cartaz. A regua e um <i> vazio que estica pelo que sobrar — e
   o recuo a direita e o buraco onde o simbolo mora. */
.ap-olho {
  margin: 0; display: flex; align-items: center; gap: calc(var(--ap) * 1.1);
  width: 100%; padding-right: min(calc(var(--ap) * 15), 20vmin);
  font-family: 'Archivo', var(--font-body); font-weight: 700;
  font-size: calc(var(--ap) * 1.05); letter-spacing: .18em;
  text-transform: uppercase;
}
.ap-olho i { flex: 1 1 auto; height: 1.5px; background: var(--tinta); }

.ap-acima, .ap-abaixo {
  margin: 0; font-family: 'Archivo', var(--font-body); font-weight: 700;
  font-size: calc(var(--ap) * 2.1); letter-spacing: .005em;
  text-transform: uppercase;
}
/* O bloco do nome fica ALTO na folha, e nao no meio: o que sobra de
   altura vai todo pro vao de baixo, empurrado pelo auto do botao.
   Centralizado, o nome descia em cima das cunhas em janela baixa. */
.ap-acima  { margin-top: max(calc(var(--ap) * 4), 6vh); }
.ap-abaixo { margin-top: calc(var(--ap) * .7); }

.ap-marca { margin: calc(var(--ap) * .3) 0 0; line-height: .82; }
.ap-marca b {
  /* Archivo variavel em wdth 125 / wght 900: mesmo grotesco
     geometrico do cartaz, esticado e no peso maximo. O Archivo Black
     do resto do app e de largura normal — ao lado da referencia ele
     sai estreito e leve demais. Fica de reserva se a variavel nao
     chegar.
     A marca escrita vetorizada foi testada aqui e voltou atras: ela
     mora so na parede do desktop. Aqui o nome e TIPO, e e por isso
     que o apDigita em 5 passos ainda le como alguem digitando. */
  display: block; font-family: 'Archivo', 'Archivo Black', var(--font-display);
  font-weight: 900; font-variation-settings: 'wdth' 125;
  /* Tres tetos: a unidade, a largura e a altura da janela. O de
     largura impede a palavra de furar a lateral em tela estreita; o
     de altura impede o nome de comer a folha inteira numa janela
     baixa e larga. */
  font-size: min(calc(var(--ap) * 14), 17vw, 26vh);
  line-height: .82; letter-spacing: -.045em; text-transform: uppercase;
}

/* --- o botao --------------------------------------------------
   Triangulo solto do lado de fora e caixa de contorno com a sombra
   dura deslocada atras: os tres pedacos vem do cartaz. O recuo a
   esquerda poe o botao no vao de creme entre as duas cunhas — e a
   assimetria que o cartaz pede, e o unico lugar onde ele cabe. */
.ap-acao {
  display: flex; align-items: center; gap: calc(var(--ap) * 1.4);
  margin-top: auto; margin-left: 30%;
}
.ap-play {
  width: 0; height: 0; flex: none;
  border-left: calc(var(--ap) * 1.6) solid var(--accent);
  border-top: calc(var(--ap) * 1) solid transparent;
  border-bottom: calc(var(--ap) * 1) solid transparent;
  animation: apPisca 1.1s steps(1) infinite;
}
@keyframes apPisca { 0%, 62% { opacity: 1; } 63%, 100% { opacity: .15; } }
.ap-start {
  position: relative;
  background: var(--papel); color: var(--tinta);
  border: 2px solid var(--tinta); border-radius: 0; cursor: pointer;
  font-family: 'Press Start 2P', 'Courier New', monospace; font-weight: 400;
  font-size: calc(var(--ap) * 1.3); letter-spacing: .06em;
  padding: calc(var(--ap) * 1.2) calc(var(--ap) * 2.8);
  box-shadow: calc(var(--ap) * .6) calc(var(--ap) * .6) 0 var(--tinta);
  transition: transform .1s var(--duro), box-shadow .1s var(--duro),
              background .18s var(--ease), color .18s var(--ease);
}
.ap-start:hover { background: var(--accent); color: var(--papel); border-color: var(--accent); }
/* Apertar encosta a caixa na sombra: o botao afunda de verdade. */
.ap-start:active {
  transform: translate(calc(var(--ap) * .6), calc(var(--ap) * .6));
  box-shadow: 0 0 0 var(--tinta);
}

/* O meio-tom debaixo do botao. Uma grade de pontos, do jeito que
   impressao velha resolvia meio-tom — e o mesmo truque aqui. Ela
   anda um ponto de lado, devagar: de perto e um respiro, de longe
   ninguem ve. */
.ap-pontos {
  display: block; margin: calc(var(--ap) * 1.3) 0 0 34%;
  width: min(26%, calc(var(--ap) * 26)); height: calc(var(--ap) * 3.4);
  background-image: radial-gradient(var(--tinta) 1px, transparent 1.3px);
  background-size: calc(var(--ap) * 1.1) calc(var(--ap) * 1.1);
  animation: apMeioTom 6s linear infinite;
}
@keyframes apMeioTom {
  from { background-position: 0 0; }
  to   { background-position: calc(var(--ap) * 1.1) 0; }
}

/* A assinatura no pe, empilhada, como no cartaz — vazada dentro da
   cunha da direita. Ela morava no creme do canto esquerdo, mas ali
   a faixa diagonal passa por cima dela em metade dos formatos de
   janela: preto sobre preto, e a assinatura sumia. O canto de baixo
   a direita e o unico pedaco de tinta que existe em TODOS eles. */
.ap-assinatura {
  position: absolute; z-index: 2; margin: 0;
  right: calc(var(--ap) * 4.4); bottom: calc(var(--ap) * 3);
  text-align: right; color: var(--papel);
  font-family: var(--font-display); font-weight: 400;
  font-size: calc(var(--ap) * 1.25); line-height: .96;
  letter-spacing: -.02em; text-transform: uppercase;
}
.ap-assinatura b, .ap-assinatura span { display: block; font-weight: inherit; }

/* --- grao de papel --------------------------------------------
   feTurbulence num data: URI — a CSP libera data: em img-src, que e
   quem manda em background-image. Multiply pra sujar o creme sem
   clarear o preto. */
.ap-grao {
  position: absolute; inset: 0; z-index: 9; pointer-events: none;
  opacity: .3; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: calc(var(--ap) * 13);
}

/* --- o cartaz entrando ----------------------------------------
   A folha varre de uma borda a outra, com aresta dura. E como tinta
   chapada entra numa impressao — e e o mesmo gesto das cunhas, tres
   decimos de segundo depois. */
html.ap-aberta .ap-tela { animation: apEntra .5s var(--duro) both; }
@keyframes apEntra {
  from { -webkit-clip-path: inset(0 100% 0 0); clip-path: inset(0 100% 0 0); }
  to   { -webkit-clip-path: inset(0 0 0 0);    clip-path: inset(0 0 0 0); }
}

/* O cartaz se monta na ordem de leitura: rotulo, regua, a linha de
   cima, o nome, a linha de baixo, e por fim o botao. */
html.ap-aberta .ap-cunha-esq { animation: apCunhaEsq .5s var(--duro) .46s both; }
html.ap-aberta .ap-cunha-dir { animation: apCunhaDir .5s var(--duro) .54s both; }
@keyframes apCunhaEsq { from { transform: translate(-45%, 45%); } to { transform: translate(0, 0); } }
@keyframes apCunhaDir { from { transform: translate(45%, 45%); } to { transform: translate(0, 0); } }
html.ap-aberta .ap-simbolo { animation: apPousa .45s var(--duro) 1.28s both; }
@keyframes apPousa {
  from { opacity: 0; transform: scale(.6) rotate(-16deg); }
  to   { opacity: 1; transform: scale(1) rotate(0deg); }
}
html.ap-aberta .ap-olho span { animation: apSurge .3s var(--ease) .38s both; }
html.ap-aberta .ap-olho i    { animation: apRegua .5s var(--duro) .44s both; }
@keyframes apRegua { from { transform: scaleX(0); transform-origin: left; } to { transform: scaleX(1); } }
html.ap-aberta .ap-acima { animation: apSurge .3s var(--ease) .6s both; }
/* O nome se escreve. clip-path em steps(5) e nao largura em ch: nao
   depende de a fonte ser monoespacada nem de o fallback ter a mesma
   medida — corta em cinco lascas iguais seja qual for a fonte. */
html.ap-aberta .ap-marca b { animation: apDigita .5s steps(5) .72s both; }
@keyframes apDigita {
  from { -webkit-clip-path: inset(0 100% 0 0); clip-path: inset(0 100% 0 0); }
  to   { -webkit-clip-path: inset(0 0 0 0);    clip-path: inset(0 0 0 0); }
}
html.ap-aberta .ap-escada { animation: apSurge .3s steps(1) 1.16s both; }
html.ap-aberta .ap-abaixo { animation: apSurge .3s var(--ease) 1.24s both; }
html.ap-aberta .ap-acao   { animation: apSobe .4s var(--duro) 1.36s both; }
html.ap-aberta .ap-pontos { animation: apSurge .4s var(--ease) 1.52s both; }
html.ap-aberta .ap-assinatura { animation: apSurge .4s var(--ease) 1.62s both; }
@keyframes apSurge { from { opacity: 0; } to { opacity: 1; } }
@keyframes apSobe  { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

/* --- o cartaz saindo ------------------------------------------
   O premio de apertar start: o tipo apaga e a folha varre pra fora
   pelo mesmo lado por onde entrou. O tipo sai ANTES da varredura —
   texto pesado sendo comido por uma aresta fica ilegivel e sujo.

   O fundo vira transparente na saida, e isso e o truque todo: em vez
   de piscar preto entre duas telas, a aresta que varre DESCOBRE a
   tela de entrada, que ja esta ali atras tocando a abertura dela.

   O relogio do /apresentacao.js espera 720ms por este conjunto. Se
   mexer nos tempos aqui, mexa la tambem. */
html.ap-saindo #apresentacao { pointer-events: none; background: transparent; }
html.ap-saindo .ap-conteudo,
html.ap-saindo .ap-cunha,
html.ap-saindo .ap-escada,
html.ap-saindo .ap-simbolo,
html.ap-saindo .ap-assinatura { animation: apApaga .12s linear both; }
@keyframes apApaga { to { opacity: 0; } }
html.ap-saindo .ap-tela { animation: apSai .46s var(--duro) .1s both; }
@keyframes apSai {
  from { -webkit-clip-path: inset(0 0 0 0);    clip-path: inset(0 0 0 0); }
  to   { -webkit-clip-path: inset(0 0 0 100%); clip-path: inset(0 0 0 100%); }
}

/* --- janela em pe ---------------------------------------------
   Vale pro celular E pro tablet de pe: o corte e a PROPORCAO, e nao
   so a largura. Num 768x1024 a regra de largura nao pegava, e o
   cartaz deitado abria meia tela de vazio no meio.

   Aqui a unidade nao pode vir da largura: 1,15vw de 375 da 4px, e o
   cartaz inteiro viraria letra miuda. A composicao tambem
   desencolhe — o botao volta pra margem, porque o vao de creme
   entre as cunhas nao cabe ninguem em pe. */
@media (max-width: 620px), (max-aspect-ratio: 1 / 1) {
  html.ap-aberta #apresentacao { --ap: clamp(9px, 2.7vw, 15px); }
  /* O pe cresce: e nele que a assinatura mora, e num celular ela
     divide o canto de baixo com o botao. */
  .ap-conteudo { padding: calc(var(--ap) * 3) calc(var(--ap) * 2.8) calc(var(--ap) * 7); }
  /* Numa tela em pe o nome desce pro primeiro terco. Colado no alto
     como no monitor, sobrava meia tela de vazio embaixo dele; no
     meio exato, o vazio de cima ficava maior que o de baixo. */
  .ap-acima { margin-top: max(calc(var(--ap) * 4), 15vh); }
  .ap-marca b { font-size: min(calc(var(--ap) * 14), 20vw, 26vh); }
  /* O meio-tom sobe pra cima do botao e os dois voltam pra margem:
     no estreito nao ha vao de creme entre as cunhas pra recuar
     nada, e embaixo do botao ele cairia em cima da assinatura. */
  .ap-pontos { order: 1; margin: auto 0 calc(var(--ap) * 1.6); width: 52%; }
  .ap-acao   { order: 2; margin-top: 0; margin-left: 0; }
  .ap-assinatura { right: calc(var(--ap) * 2.8); bottom: calc(var(--ap) * 2.2); }
  .ap-simbolo { right: calc(var(--ap) * 2.8); }
  /* As cunhas recuam pros cantos: no estreito elas apertavam o
     texto contra a lateral. */
  .ap-cunha-esq { width: 42vw; height: 30vh; }
  .ap-cunha-dir { width: 52vw; height: 34vh; }
  .ap-escada { right: 8%; top: 62%; }
}

/* --- menos movimento ------------------------------------------
   Lista nominal, e nao um `*`: um curinga zeraria tambem o
   clip-path das cunhas, que e FORMA e nao movimento — elas viravam
   dois retangulos pretos cobrindo o cartaz inteiro. Tudo em pe,
   tudo visivel, nada varrendo nem entrando. */
@media (prefers-reduced-motion: reduce) {
  html.ap-aberta .ap-cunha,
  html.ap-aberta .ap-escada,
  html.ap-aberta .ap-simbolo,
  html.ap-aberta .ap-olho span,
  html.ap-aberta .ap-olho i,
  html.ap-aberta .ap-acima,
  html.ap-aberta .ap-abaixo,
  html.ap-aberta .ap-acao,
  html.ap-aberta .ap-play,
  html.ap-aberta .ap-pontos,
  html.ap-aberta .ap-assinatura,
  html.ap-aberta .ap-tela::after,
  html.ap-saindo .ap-conteudo,
  html.ap-saindo .ap-cunha,
  html.ap-saindo .ap-escada,
  html.ap-saindo .ap-simbolo,
  html.ap-saindo .ap-assinatura,
  html.ap-saindo #apresentacao {
    animation: none; opacity: 1; transform: none;
  }
  /* Estes dois animam clip-path: aqui ele volta a ser inteiro. */
  html.ap-aberta .ap-tela,
  html.ap-aberta .ap-marca b,
  html.ap-saindo .ap-tela {
    animation: none; opacity: 1; transform: none;
    -webkit-clip-path: none; clip-path: none;
  }
  html.ap-aberta .ap-tela::after { display: none; }
}


/* ============================================================
   CADASTRO — O CARTAZ
   ------------------------------------------------------------
   As quatro telas do cadastro saem do preto e viram cartaz: papel
   creme, tinta preta pesada e o vermelho da casa. É uma quebra
   PROPOSITAL com o resto do app — o cadastro é um momento à parte,
   acontece uma vez, e a troca de fundo marca isso melhor do que
   qualquer texto explicando.

   Aqui a régua dos traços também muda. No app o contorno saiu porque
   virava uma grade de caixinhas; neste cartaz a linha grossa e a
   sombra dura SÃO o desenho, como no material impresso que serviu de
   referência. Uma coisa não contradiz a outra: são duas linguagens,
   e cada uma vale na sua tela.

   COMO ISTO FUNCIONA: em vez de reescrever .card, .btn, .field,
   .subtitle e companhia, redefinimos os TOKENS de cor dentro destas
   quatro seções. Tudo que já lê var(--text), var(--bg) e var(--border)
   vira claro sozinho. Só o que é específico do cartaz vem escrito.
   ============================================================ */
#screen-nick, #screen-welcome, #screen-onboarding, #screen-tour {
  /* A paleta do papel. */
  --papel: #f2efe7;
  --tinta: #12100e;
  /* Vermelho mais fechado que o do app: o #ff2b32 dá 2,6:1 sobre creme
     e reprovaria. Este mede 5,3:1 — passa AA como texto. */
  --cad-vermelho: #c4161c;

  /* Os tokens compartilhados, reapontados. É isto que faz o resto
     acompanhar sem uma linha a mais. */
  --bg: var(--papel);
  --surface: #ffffff;
  --surface-2: #ffffff;
  --text: var(--tinta);
  --text-muted: rgba(18, 16, 14, .80);
  --text-dim: rgba(18, 16, 14, .62);
  --border: var(--tinta);
  --border-hover: var(--tinta);
  --divisor: var(--tinta);
  --accent-claro: var(--cad-vermelho);
  --bg-rgb: 242, 239, 231;

  /* A sombra dura: sem desfoque, deslocada. É a assinatura do cartaz. */
  --salto: calc(var(--u) * .5);

  color: var(--tinta);
  background-color: var(--papel);
}

/* --- a geometria do fundo ---
   Três triângulos e um xadrez, todos em camadas de background: nenhum
   elemento novo no HTML, e nada disso entra na ordem de leitura.
   O 50.3% em vez de 50% é anti-serrilhado: na diagonal exata o
   navegador desenha um degrau visível na borda. */
#screen-nick.active, #screen-welcome.active,
#screen-onboarding.active, #screen-tour.active {
  background-color: var(--papel);
  background-image:
    /* xadrez, colado no triângulo vermelho */
    repeating-conic-gradient(var(--tinta) 0% 25%, transparent 0% 50%),
    /* triângulo vermelho, canto superior direito */
    linear-gradient(to bottom left, var(--cad-vermelho) 50%, transparent 50.3%),
    /* triângulo de tinta, canto inferior direito */
    linear-gradient(to top left, var(--tinta) 50%, transparent 50.3%),
    /* lasca de tinta, canto inferior esquerdo */
    linear-gradient(to top right, var(--tinta) 50%, transparent 50.3%);
  background-repeat: no-repeat;
  /* border-box, e não o padding-box padrão: com o padrão as formas de
     canto nascem DEPOIS do respiro interno da tela e param de encostar
     na quina — que é justamente o que faz elas lerem como recorte de
     papel, e não como figura solta. */
  background-origin: border-box;
  background-position:
    right var(--geo-xadrez-x) top var(--geo-xadrez-y),
    top right,
    bottom right,
    bottom left;
  background-size:
    var(--geo-xadrez) var(--geo-xadrez),
    var(--geo-cunha) var(--geo-cunha),
    var(--geo-base-l) var(--geo-base-a),
    var(--geo-lasca-l) var(--geo-lasca-a);
  background-attachment: scroll;
}

/* Os olhos que moravam aqui (um ::after com o desenho em SVG, no vazio
   à direita do passo 1) sairam: viravam um rosto olhando de volta pra
   quem estava so escrevendo o apelido. O lado direito fica pro
   triangulo e pro xadrez do cartaz, que ja sustentam a pagina. */

/* O conteúdo passa por cima da geometria. */
#screen-nick .tela-topo, #screen-welcome .tela-topo,
#screen-onboarding .tela-topo, #screen-tour .tela-topo,
#screen-nick .card, #screen-welcome .card,
#screen-onboarding .card, #screen-tour .card {
  position: relative; z-index: 1;
}

/* --- cabeçalho: tudo em tinta, e o passo perde o vermelho ---
   No cartaz o vermelho é do triângulo e do botão. Espalhar mais um
   pedaço vermelho no topo brigaria com os dois. */
#screen-nick .tela-topo, #screen-welcome .tela-topo,
#screen-onboarding .tela-topo, #screen-tour .tela-topo {
  color: var(--tinta); font-weight: 700;
  /* O "PASSO N DE 4" mora no canto direito, e o triângulo vermelho
     também. Sem este respiro o texto some dentro do vermelho — foi
     exatamente o que aconteceu na primeira montagem. A conta: a cunha
     tem 12*u e nasce colada na borda da JANELA, o respiro lateral da
     tela vale no mínimo 3*u, então 9*u já livram o texto e o décimo é
     a folga. Eram 13 antes, medidos quando o cabeçalho ainda vinha
     empurrado 50px pra direita pelo left herdado; com ele no lugar
     certo, 13 largavam o passo boiando longe da cunha. */
  padding-right: calc(var(--u) * 10);
}
#screen-nick .tela-topo b, #screen-welcome .tela-topo b,
#screen-onboarding .tela-topo b, #screen-tour .tela-topo b {
  font-family: var(--font-display); font-weight: 400;
  letter-spacing: -.03em; font-size: calc(var(--u) * 1.7);
}
#screen-nick .wz-step, #screen-welcome .wz-step,
#screen-onboarding .wz-step, #screen-tour .wz-step {
  color: var(--tinta);
}

/* --- o título: maior e mais colado que no app --- */
#screen-nick .card h2, #screen-welcome .card h2,
#screen-onboarding .card h2, #screen-tour .card h2 {
  font-size: clamp(28px, calc(var(--u) * 4.2), 10.4vw);
  letter-spacing: -.045em; color: var(--tinta);
}
/* O destaque continua sendo VOZ: serifada itálica vermelha. */
#screen-nick .subtitle strong, #screen-welcome .subtitle strong,
#screen-onboarding .subtitle strong, #screen-tour .subtitle strong {
  color: var(--cad-vermelho);
}

/* --- campo: caixa branca de contorno grosso, com sombra dura --- */
#screen-nick .field span { color: var(--tinta); }
#screen-nick .field span::before { color: var(--cad-vermelho); }
#screen-nick input[type=text],
#screen-onboarding input.search {
  background: #fff; color: var(--tinta);
  border: 2px solid var(--tinta); border-radius: 0;
  box-shadow: var(--salto) var(--salto) 0 var(--tinta);
}
#screen-nick input[type=text]::placeholder,
#screen-onboarding input.search::placeholder { color: rgba(18, 16, 14, .40); }
/* No foco a caixa "encosta": a sombra encolhe e ela desce junto. Sem
   isso o contorno de foco padrão brigaria com a borda de 2px. */
#screen-nick input[type=text]:focus,
#screen-onboarding input.search:focus {
  outline: none; border-color: var(--cad-vermelho);
  box-shadow: calc(var(--salto) * .5) calc(var(--salto) * .5) 0 var(--cad-vermelho);
  transform: translate(calc(var(--salto) * .5), calc(var(--salto) * .5));
}
#screen-onboarding .search-ic { color: var(--tinta); opacity: .55; }

/* --- botão: bloco vermelho com a sombra dura, e que afunda no clique --- */
#screen-nick .btn.primary, #screen-welcome .btn.primary,
#screen-onboarding .btn.primary, #screen-tour .btn.primary {
  background: var(--cad-vermelho); color: #fff;
  border: 2px solid var(--tinta);
  box-shadow: var(--salto) var(--salto) 0 var(--tinta);
  transition: transform .09s var(--duro), box-shadow .09s var(--duro), background .18s var(--ease);
}
/* No hover o bloco LEVANTA do papel: sobe um triz e a sombra dura
   cresce junto, que é o oposto exato do :active logo abaixo. Antes só
   trocava de vermelho, e num cartaz de sombra chapada isso não lê como
   botão — lê como um retângulo que mudou de cor. */
#screen-nick .btn.primary:hover, #screen-welcome .btn.primary:hover,
#screen-onboarding .btn.primary:hover, #screen-tour .btn.primary:hover {
  background: #d81a21;
  transform: translate(calc(var(--salto) * -.3), calc(var(--salto) * -.3));
  box-shadow: calc(var(--salto) * 1.4) calc(var(--salto) * 1.4) 0 var(--tinta);
}
#screen-nick .btn.primary:active, #screen-welcome .btn.primary:active,
#screen-onboarding .btn.primary:active, #screen-tour .btn.primary:active {
  transform: translate(var(--salto), var(--salto)); box-shadow: none;
}
#screen-nick .btn:disabled, #screen-welcome .btn:disabled,
#screen-onboarding .btn:disabled, #screen-tour .btn:disabled {
  box-shadow: none; transform: none;
}

/* --- rodapé: a régua vira barra de tinta, não fio --- */
.wz-rodape { border-top-width: 2px; }
#screen-nick .wz-rodape, #screen-welcome .wz-rodape,
#screen-onboarding .wz-rodape, #screen-tour .wz-rodape {
  background: var(--papel); border-top-color: var(--tinta);
}
.wz-conta b { color: var(--tinta); }
.wz-conta .fact-label { color: var(--text-dim); }
.wz-conta .fact-label::before { color: var(--cad-vermelho); }

/* ------------------------------------------------------------
   2. PLATAFORMA — cada opção é um bloco de papel
   ------------------------------------------------------------ */
#screen-welcome .platform-opt {
  background: #fff; color: var(--tinta);
  border: 2px solid var(--tinta); border-radius: 0;
  box-shadow: var(--salto) var(--salto) 0 var(--tinta);
  transition: transform .1s var(--duro), box-shadow .1s var(--duro), background .18s var(--ease);
}
#screen-welcome .platform-opt .ic { color: var(--tinta); }
#screen-welcome .platform-opt:hover {
  background: #fff; transform: translate(calc(var(--salto) * -.4), calc(var(--salto) * -.4));
  box-shadow: calc(var(--salto) * 1.4) calc(var(--salto) * 1.4) 0 var(--tinta);
}
/* Marcada = bloco vermelho cheio. O estado tem que ser visto do outro
   lado da sala, não adivinhado por uma borda mais clara. */
#screen-welcome .platform-opt.selected {
  background: var(--cad-vermelho); color: #fff;
  transform: translate(var(--salto), var(--salto)); box-shadow: none;
}
#screen-welcome .platform-opt.selected .ic { color: #fff; }

/* ------------------------------------------------------------
   3. JOGOS — as capas ganham moldura de tinta
   ------------------------------------------------------------ */
#screen-onboarding .game-card {
  border: 2px solid var(--tinta); border-radius: 0;
  background: #fff;
  transition: transform .1s var(--duro), box-shadow .1s var(--duro);
  /* DENTRO do card o fundo volta a ser escuro.
     As telas do cadastro reapontam --bg-rgb pro creme do papel, e o véu
     do pé da capa segue esse token: o borrão desvanecia pro branco e o
     card inteiro lia esbranquiçado, por mais aberto que o véu ficasse.
     No lobby o mesmo véu desvanece pro preto, e é isso que faz a arte
     "mergulhar" em vez de desbotar.
     O card é uma janela pra arte, não um pedaço do papel — então aqui
     dentro o token volta ao escuro do app. O véu, o halo do texto e
     tudo mais que lê --bg-rgb acompanham numa linha só. */
  --bg-rgb: 10, 10, 10;
}
#screen-onboarding .game-card:hover {
  transform: translate(calc(var(--salto) * -.4), calc(var(--salto) * -.4));
  box-shadow: calc(var(--salto) * 1.2) calc(var(--salto) * 1.2) 0 var(--tinta);
}
/* Escolhida: moldura vermelha e a sombra encostada, igual ao botão
   apertado. Some a dúvida de "cliquei ou não". */
#screen-onboarding .game-card.selected {
  border-color: var(--cad-vermelho);
  box-shadow: var(--salto) var(--salto) 0 var(--cad-vermelho);
  transform: none;
}
#screen-onboarding .owned-banner {
  background: #fff; color: var(--tinta);
  border: 2px solid var(--tinta); border-radius: 0;
}
/* "Procurando na Steam..." — o recado que diz que a busca foi ALÉM do
   que já está aqui. Sem ele a grade parece só demorar pra filtrar. */
.busca-aviso {
  margin: calc(var(--u) * .8) 0 0;
  font-family: var(--font-serif); font-style: italic;
  font-size: calc(var(--u) * 1.05); color: var(--cad-vermelho);
}

/* ------------------------------------------------------------
   4. COMO FUNCIONA — a lista perde os fios e ganha numeração
   ------------------------------------------------------------ */
#screen-tour .tour-list li { border-bottom-color: rgba(18, 16, 14, .18); }
#screen-tour .tour-ic { color: var(--cad-vermelho); }
#screen-tour .tour-list strong { color: var(--tinta); }

/* ============================================================
   TELA DE ENTRADA no mesmo cartaz do cadastro
   ------------------------------------------------------------
   O cadastro (apelido, plataforma, jogos, tour) ja vive no papel
   claro. A entrada era a unica que continuava preta, e a pessoa
   trocava de mundo ao apertar "Press Start".
   Aqui ela entra no MESMO sistema: os tokens sao os de la
   (--papel / --tinta / --cad-vermelho), nao uma paleta paralela.
   O que muda e so a composicao — a entrada e um cartaz de duas
   colunas, com a cunha atras do cartao.
   ============================================================ */
#screen-login {
  --papel: #f2efe7;
  --tinta: #12100e;
  /* Medido pela outra tela: 5,3:1 sobre o creme, passa AA como texto.
     O vermelho do app (#ff2b32) daria 2,6:1 e reprovaria. */
  --cad-vermelho: #c4161c;

  --bg: var(--papel);
  --surface: #ffffff;
  --surface-2: #ffffff;
  --text: var(--tinta);
  --text-muted: rgba(18, 16, 14, .80);
  --text-dim: rgba(18, 16, 14, .62);
  --border: var(--tinta);
  --border-hover: var(--tinta);
  --divisor: var(--tinta);
  --accent: var(--cad-vermelho);
  --accent-claro: var(--cad-vermelho);
  --accent-rgb: 196, 22, 28;
  --bg-rgb: 242, 239, 231;
  --salto: calc(var(--u) * .5);

  color: var(--tinta);
  background-color: var(--papel);
}

/* O papel vai ate a borda da janela. Sem isto sobra o preto do app
   em volta da composicao, como se a pagina estivesse emoldurada. */
body:has(#screen-login.active) { background: #f2efe7; }

/* A cunha diagonal que dividia a tela em dois saiu junto com o
   desenho de duas colunas. Na porta nova o fundo é liso de propósito:
   é o vazio que faz o símbolo no meio ser o herói, e uma diagonal
   atravessando ele desmancharia exatamente isso. */

/* O simbolo em marca d'agua: e ele que ocupa a tela agora que o nome
   escrito saiu. Grande, apagado e cortado pela borda de baixo — sinal
   de marca, nao ilustracao a ser olhada. Tem elemento proprio no HTML
   porque a abertura animada ja usa o ::before desta tela. */
.cartaz-selo {
  left: 2%; bottom: -18%;
  width: 46vw; height: 46vw; max-width: 620px; max-height: 620px;
  background-color: var(--tinta);
  -webkit-mask: url('/marca-banke.svg') center / contain no-repeat;
  mask: url('/marca-banke.svg') center / contain no-repeat;
  opacity: .07;
  pointer-events: none;
}
/* No escuro o mesmo valor sumiria: tinta clara sobre fundo preto pede
   um pouco mais de presenca. */
html[data-tema="escuro"] .cartaz-selo { opacity: .09; }

/* Empilhamento. Cada elemento e nomeado de proposito: ja tentei
   #screen-login > * (virou position:relative nos enfeites, que
   sairam do lugar) e a versao com :not() (ganhou do position:fixed
   do trilho, que passou a ocupar 732px e esmagou o layout). */
#screen-login > .login-topo,
#screen-login > .auth-layout,
#screen-login > .sharp-strip { position: relative; z-index: 1; }
#screen-login > .login-trilho { z-index: 2; }
#screen-login > .cartaz-selo { position: absolute; z-index: 0; }

/* --- trilho lateral: contorno, nao texto cheio --- */
#screen-login .login-trilho span {
  color: transparent; -webkit-text-stroke: 1px rgba(18, 16, 14, .38);
}

/* --- argumentos: asterisco vermelho e fios --- */
#screen-login .facts li { border-top: 1px solid var(--divisor); }
#screen-login .facts li:last-child { border-bottom: 1px solid var(--divisor); }
#screen-login .fact-label::before {
  content: '✳'; color: var(--cad-vermelho);
  margin-right: .5em; font-size: 1.05em; line-height: 0;
}

/* --- cartao: papel branco, fio preto e a sombra dura da casa --- */
#screen-login .auth-card {
  background: #fff; border: 1px solid var(--tinta); border-radius: 0;
  box-shadow: var(--salto) var(--salto) 0 var(--tinta);
}

/* --- botoes: vermelho e preto, os dois chapados --- */
#screen-login .btn.primary {
  background: var(--cad-vermelho); color: #fff; border-color: var(--cad-vermelho);
}
#screen-login .btn.primary:hover { background: #a51217; border-color: #a51217; }
/* O "contorno" do Google vira o segundo bloco chapado, em preto: no
   cartaz nao existe botao de moldura vazia. */
#screen-login .btn.outline {
  background: var(--tinta); color: #fff; border-color: var(--tinta);
}
#screen-login .btn.outline:hover { background: #000; }

/* --- faixa de capas: soltas, sem moldura ---
   Antes era uma barra preta atravessando a base — um bloco a mais numa
   tela que ja tinha bloco demais. Agora as capas passam soltas sobre o
   papel, em preto e branco e bem apagadas: viram textura de fundo, nao
   uma faixa a ser lida. A cor volta em quem recebe o cursor. */
#screen-login .sharp-strip {
  background: none; border-top: none;
  padding-left: calc(var(--u) * 5.4);
}
#screen-login .strip-track img {
  filter: grayscale(1) contrast(1.1);
  opacity: .22;
  transition: opacity .3s var(--duro), filter .3s var(--duro);
}
#screen-login .strip-track img:hover { opacity: .6; filter: grayscale(1) contrast(1.1); }
html[data-tema="escuro"] #screen-login .strip-track img { opacity: .3; }

/* ============================================================
   TEMA ESCURO
   ------------------------------------------------------------
   O claro e o padrao (mora no :root la em cima). Aqui vem so o que
   muda no escuro — os MESMOS nomes de token, com outros valores.
   Como todo o app le var(--bg), var(--text) e companhia, trocar o
   atributo no <html> vira a pagina inteira sem tocar em regra.
   Os vermelhos voltam a ser os calibrados contra preto: o #c4161c do
   papel da 2,9:1 sobre o escuro e reprovaria.
   ============================================================ */
html[data-tema="escuro"] {
  --papel: #0a0a0a;
  --tinta: #f2efec;

  --bg: #0a0a0a;
  --surface: #141414;
  --surface-2: #1c1c1c;
  --border: #2a2a2a;
  --border-hover: #3d3d3d;
  --divisor: rgba(255, 255, 255, .16);
  --bg-rgb: 10, 10, 10;
  --surface-rgb: 20, 20, 20;

  --text: #f2efec;
  --text-muted: #9a9a9a;
  --text-dim: #8a8a8a;

  --cad-vermelho: #ff2b32;
  --accent: #e02128;
  --accent-hover: #f5333a;
  --accent-rgb: 224, 33, 40;
  --accent-claro: #ff2b32;
}

/* As telas que declaram a paleta do cartaz localmente precisam ceder
   no escuro, senao continuariam claras no meio do app escuro. */
/* AS QUATRO TELAS DO CADASTRO FICAM DE FORA DO TEMA ESCURO.
   Elas são um CARTAZ IMPRESSO: papel creme, tinta preta, vermelho de
   máquina. Papel impresso não tem modo escuro — invertido, o creme
   vira preto e a tinta vira clara, e o que era um cartaz vira uma
   tela comum com um triângulo vermelho no canto. Além disso o
   cadastro é a primeira coisa que alguém vê do Banke, e é ali que a
   identidade precisa chegar inteira.

   Só a tela de entrada continua acompanhando o tema: ela não é
   cartaz, é uma porta preta com o símbolo no meio, e no escuro é
   justamente onde ela fica melhor. */
html[data-tema="escuro"] #screen-login {
  --papel: #0a0a0a;
  --tinta: #f2efec;
  --bg: #0a0a0a;
  --surface: #141414;
  --surface-2: #1c1c1c;
  --border: #2a2a2a;
  --border-hover: #3d3d3d;
  --divisor: rgba(255, 255, 255, .16);
  --text: #f2efec;
  --text-muted: #9a9a9a;
  --text-dim: #8a8a8a;
  --cad-vermelho: #ff2b32;
  --accent: #e02128;
  --accent-claro: #ff2b32;
  --bg-rgb: 10, 10, 10;
  background-color: #0a0a0a;
  color: #f2efec;
}
html[data-tema="escuro"] body:has(#screen-login.active) { background: #0a0a0a; }
/* O body atrás do cadastro continua CREME mesmo no escuro, porque o
   cartaz continua creme. Pintá-lo de preto aqui deixaria uma moldura
   escura em volta do papel no repique do scroll. */

/* Peças que sao pretas de proposito no papel viram claras no escuro. */
html[data-tema="escuro"] .btn.outline {
  background: rgba(255, 255, 255, .08); color: var(--text); border-color: var(--border);
}
html[data-tema="escuro"] .btn.outline:hover { background: rgba(255, 255, 255, .14); }
html[data-tema="escuro"] .btn.ghost { background: rgba(255, 255, 255, .06); }
html[data-tema="escuro"] .btn.ghost:hover { background: rgba(255, 255, 255, .12); }
html[data-tema="escuro"] input[type=text],
html[data-tema="escuro"] input[type=password],
html[data-tema="escuro"] input[type=email],
html[data-tema="escuro"] input[type=search],
html[data-tema="escuro"] textarea,
html[data-tema="escuro"] .composer input { background: #1c1c1c; }
html[data-tema="escuro"] input.travado,
html[data-tema="escuro"] input:disabled { background: #191919; }
html[data-tema="escuro"] .setting-card { background: #141414; }
html[data-tema="escuro"] .game-card { background: #141414; }

/* --- escolha de tema, no perfil --- */
.tema-picker { display: flex; gap: 10px; }
.tema-opt {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 14px; cursor: pointer;
  background: none; border: 1px solid var(--border); border-radius: 0;
  color: var(--text); font: inherit; font-size: 14px;
}
.tema-opt:hover { background: rgba(127, 127, 127, .12); }
/* O selecionado leva o filete vermelho por dentro, igual ao resto do
   cartaz — e nao so uma borda mais clara, que passa despercebida. */
.tema-opt[aria-pressed="true"] {
  border-color: var(--accent-claro);
  box-shadow: inset 0 0 0 2px var(--accent-claro);
}
/* Amostra: mostra a cor do tema, nao so o nome. */
.tema-amostra {
  width: 20px; height: 20px; flex: none; border: 1px solid var(--border);
  display: block;
}
.tema-amostra-claro  { background: linear-gradient(135deg, #f2efe7 50%, #c4161c 50%); }
.tema-amostra-escuro { background: linear-gradient(135deg, #0a0a0a 50%, #ff2b32 50%); }

/* O simbolo em marca d'agua entra primeiro e devagar: e ele que
   ocupa o lugar que era da marca escrita na abertura. Sobe de baixo
   um tico, pra nao ser so um fade parado. */
.intro-abertura #screen-login .cartaz-selo {
  animation: seloDeFundo .9s var(--ease) 0s both;
}
@keyframes seloDeFundo {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: .07; transform: none; }
}
html[data-tema="escuro"] .intro-abertura #screen-login .cartaz-selo {
  animation-name: seloDeFundoEscuro;
}
@keyframes seloDeFundoEscuro {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: .09; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .intro-abertura #screen-login .cartaz-selo { animation: none; }
}


/* ============================================================
   A PORTA — a tela de entrada, enxuta
   ------------------------------------------------------------
   O que havia aqui era a marca, uma chamada, três argumentos com
   parágrafo cada e o formulário inteiro aberto, tudo de uma vez. Não
   se lia nada: batia o olho e procurava onde clicar.

   O desenho agora tem UM assunto por vez. Primeiro a porta — símbolo
   grande no meio, uma linha embaixo, duas saídas. O formulário é a
   segunda etapa e vem num painel, só depois de escolhida uma delas.

   Todo o resto encosta nas bordas de propósito: é o vazio no meio que
   faz o símbolo virar o herói da tela.
   ============================================================ */
#screen-login.active {
  position: relative; height: 100dvh; overflow: hidden;
  display: block; padding: 0;
}

/* --- O SÍMBOLO: gigante, cortado pelo canto, quase invisível ---
   Sai pela borda de propósito. Marca que não cabe na tela lê como
   MARCA; a mesma coisa inteirinha e centralizada lê como ilustração
   esperando ser admirada. E fica no limite do visível: é textura de
   fundo, não conteúdo. */
.porta-selo {
  position: absolute; z-index: 0; pointer-events: none;
  right: -16%; top: -26%;
  width: min(115vh, 90vw); aspect-ratio: 1;
  opacity: .075;
  animation: portaSelo 1.4s var(--ease) both;
}
html[data-tema="escuro"] .porta-selo { opacity: .085; }
.ps-anel, .ps-b {
  position: absolute; inset: 0; display: block;
  background-color: var(--tinta);
}
.ps-anel {
  -webkit-mask: url('/marca-banke-anel.svg') center / contain no-repeat;
  mask: url('/marca-banke-anel.svg') center / contain no-repeat;
  /* Uma volta a cada dois minutos. Devagar assim, ninguém "vê girar" —
     percebe que mudou de lugar ao olhar de novo, que é o efeito certo
     pra uma coisa que fica na tela enquanto se digita uma senha. */
  animation: anelGira 120s linear infinite;
  /* O anel tem o tamanho da janela e uma máscara vetorial em cima.
     Sem esta linha o navegador redesenha a máscara inteira a cada
     quadro pra girar um grau — com ela, ele desenha uma vez e depois
     só gira a camada pronta, que é trabalho de placa de vídeo. É a
     diferença entre a tela de entrada respirar e a tela de entrada
     engasgar em máquina modesta. */
  will-change: transform;
}
.ps-b {
  -webkit-mask: url('/marca-banke-b.svg') center / contain no-repeat;
  mask: url('/marca-banke-b.svg') center / contain no-repeat;
}
@keyframes anelGira { to { rotate: 360deg; } }
@keyframes portaSelo { from { opacity: 0; } }

/* --- A MARCA, sozinha no meio ---
   Havia uma segunda copia dela logo abaixo: a mesma marca deitada pra
   frente com perspectiva, virando um facho vermelho que se abria ate o
   pe da tela. O gesto era bonito e o resultado nao: o facho era MAIOR
   que a marca, e quem chegava lia o borrao vermelho antes do nome.
   Saiu, e com ele saiu o motivo de o nome morar tao alto — ele estava
   la em cima so pra sobrar tela embaixo pro facho crescer.

   Agora o nome fica onde deveria estar desde o comeco: no meio, um
   triz acima do centro geometrico. Um triz, e nao no centro exato,
   porque o rodape tem peso e o olho le como BAIXA uma coisa
   centralizada entre um topo vazio e um pe cheio. */
.porta-marca {
  position: absolute; z-index: 2;
  left: 50%; top: 46%; translate: -50% -50%;
  width: min(42vw, 560px); aspect-ratio: 1475 / 339;
  /* Teto de altura: numa janela baixa a marca crescia pela largura e
     ia sentar em cima do rodape. Com a mascara em `contain`, cortar a
     altura so encolhe o desenho — ele nunca deforma. */
  max-height: 32vh;
  animation: portaSobe .8s var(--ease) .15s both;
}
.pm-nome {
  position: absolute; inset: 0; display: block; z-index: 2;
  background-color: var(--tinta);
  -webkit-mask: url('/marca-banke-nome.svg') center / contain no-repeat;
  mask: url('/marca-banke-nome.svg') center / contain no-repeat;
}

/* O topo da porta (a marca escrita miuda a esquerda, "18+ · coop" a
   direita) saiu tambem. Numa tela cujo assunto e a marca grande no
   meio, o nome repetido no canto era o mesmo recado dito duas vezes; e
   a etiqueta do outro canto puxava o olho pro pedaco mais vazio da
   composicao. Os dois cantos de cima agora sao so tela. */

/* Rodapé: a frase de um lado, as saídas do outro. */
.porta-pe {
  position: absolute; z-index: 3; left: 0; right: 0;
  bottom: clamp(22px, 4vh, 44px);
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: clamp(16px, 4vw, 60px); flex-wrap: wrap;
  padding: 0 clamp(20px, 4vw, 52px);
  animation: portaSobe .7s var(--ease) .42s both;
}
/* A frase do pe cresceu. Em 13px ela era legenda de rodape — e ela e
   a UNICA linha de texto da porta, a que diz o que o Banke faz.
   O maximo em ch e o que segura a quebra nas duas linhas. */
.porta-pe .hero-lede {
  margin: 0; max-width: 24ch;
  font-size: clamp(15px, 1.35vw, 19px); line-height: 1.45;
  color: var(--text-muted); letter-spacing: .01em;
}
.porta-pe .hero-lede em {
  display: block;
  font-family: var(--font-serif); font-style: italic; font-weight: 400;
  font-size: 1.08em;
  color: var(--accent-claro);
}
@keyframes portaSobe { from { opacity: 0; transform: translateY(14px); } }

/* As duas saídas. Retângulo seco e versalete espaçado, como o resto do
   cartaz. A de criar conta é a cheia: é o caminho de quem chega. */
.porta-acoes { display: flex; gap: 10px; flex: none; }
.porta-btn {
  padding: 15px 26px; cursor: pointer;
  background-color: transparent; color: var(--text);
  border: 2px solid var(--tinta); border-radius: 0;
  font: inherit; font-size: 11.5px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  /* O hover TROCA a cor de fundo, e mais nada. Havia aqui um
     preenchimento que subia de baixo, feito com um ::before deslizando
     em z-index negativo: no botao vazado ele funcionava, no cheio ele
     pintava atras da propria cor de fundo e nunca aparecia. O botao
     entao trocava a letra pra cor de um preenchimento que nao vinha, e
     o rotulo sumia dentro dele bem na hora de ser clicado.

     Tentei tambem com imagem de fundo crescendo (background-size), que
     resolve a camada. Mas dois botoes lado a lado, um enchendo e o
     outro invertendo, e uma inconsistencia que se ve; e uma troca de
     cor chapada e o gesto que combina com o resto do cartaz, onde nada
     tem meio-tom. Cor cheia, aresta viva, e acabou. */
  transition: background-color .2s var(--ease), color .2s var(--ease),
              border-color .2s var(--ease), transform .12s var(--duro);
}
.porta-btn:hover, .porta-btn:focus-visible {
  background-color: var(--tinta); color: var(--papel);
}
.porta-btn:active { transform: translateY(2px); }
/* A de criar conta e a cheia: e o caminho de quem chega. Nela o hover
   inverte — o vermelho sai do fundo e vai pra letra. */
.porta-btn.destaque {
  background-color: var(--accent); border-color: var(--accent); color: #fff;
}
.porta-btn.destaque:hover, .porta-btn.destaque:focus-visible {
  background-color: var(--papel); color: var(--accent);
}

/* ------------------------------------------------------------
   O PAINEL — a segunda etapa
   ------------------------------------------------------------
   Era uma gaveta encostada na direita, com a porta atras desfocada.
   Duas coisas estavam erradas nisso.

   A primeira e que travava. O desfoque era feito com backdrop-filter
   na tela inteira MAIS um filter: blur na porta — e a porta tem um
   simbolo do tamanho da janela girando sem parar por baixo. Desfocar
   uma coisa que se mexe obriga o navegador a redesenhar o borrao
   inteiro a cada quadro, e o resultado era a abertura engasgando
   justamente no clique mais importante da tela.

   A segunda e que gaveta lateral e desenho de painel de ajuste, nao
   de porta de entrada. O que se espera aqui e uma caixa no meio, de
   frente. Ela entra com opacidade e escala — as duas coisas que o
   navegador anima de graca — sobre um veu chapado.
   ------------------------------------------------------------ */
#screen-login .auth-layout {
  position: absolute; z-index: 5; inset: 0;
  /* Flex, e nao grid: a .auth-layout de origem e uma grade de DUAS
     colunas (sobra da tela antiga, de duas colunas), e um place-items
     por cima nao apaga o grid-template — a caixa ia parar na coluna da
     esquerda em vez do meio. */
  display: flex; align-items: center; justify-content: center;
  padding: clamp(12px, 3vh, 44px);
  pointer-events: none; opacity: 0;
  /* Veu chapado, sem desfoque nenhum. */
  background: rgba(0, 0, 0, .74);
  transition: opacity .24s var(--ease);
}
#screen-login.auth-aberta .auth-layout { pointer-events: auto; opacity: 1; }

#screen-login .auth-card {
  width: min(440px, 100%); max-height: 100%;
  /* Cabecalho preso em cima, corpo rolando embaixo: quem rola e o
     .auth-corpo, nao o cartao. Com o cartao inteiro rolando, as abas
     e o fechar subiam pra fora no primeiro arrasto — e num celular,
     assim que o teclado abria. */
  display: flex; flex-direction: column; overflow: hidden;
  padding: 0;
  background: var(--surface);
  border: 2px solid var(--tinta); border-radius: 0;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
  opacity: 0; transform: translateY(12px) scale(.985);
  transition: opacity .22s var(--ease), transform .26s var(--duro);
  /* Escondido de verdade enquanto fechado: sem isto o formulário
     continua na ordem do teclado, e o Tab da porta cai dentro dele. */
  visibility: hidden;
}
#screen-login.auth-aberta .auth-card { opacity: 1; transform: none; visibility: visible; }

/* ------------------------------------------------------------
   O PAINEL POR DENTRO
   ------------------------------------------------------------
   Cada medida daqui pra baixo esta em px, de proposito. O formulario
   herdava a regua --u da tela de entrada, que e uma fracao da JANELA:
   num monitor comum ela batia no piso de 10,5px e saia tudo em corpo
   9 — rotulo, botao, campo e aviso, todos ilegiveis, num painel de
   largura FIXA que nao tinha por que encolher com a janela. Era essa
   a origem da tela apertada, e nao o desenho.
   ------------------------------------------------------------ */
/* Cabecalho: as duas abas ocupando a largura e o fechar no canto.
   Antes havia um "← Voltar" numa linha propria acima delas — fazia
   sentido quando o painel era uma gaveta que vinha de algum lugar.
   Numa caixa no meio da tela, o que se procura no canto e o X. */
.auth-topo {
  flex: none; display: flex; align-items: stretch;
  background: var(--surface);
  border-bottom: 1px solid var(--divisor);
}
.auth-corpo {
  flex: 1; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
  padding: 24px 28px 34px;
}

.auth-fechar {
  flex: none; align-self: center;
  width: 44px; height: 44px; margin-right: 6px;
  display: grid; place-items: center; cursor: pointer;
  background: none; border: 0; border-radius: 0;
  color: var(--text-dim); font: inherit; font-size: 26px; line-height: 1;
  transition: color .16s var(--ease);
}
.auth-fechar:hover { color: var(--accent-claro); }

/* As abas: duas metades iguais, com o filete vermelho pousado em cima
   da divisoria do cabecalho. O -1px e o que encosta um no outro; sem
   ele ficam dois riscos paralelos. */
#screen-login .auth-tabs {
  flex: 1; min-width: 0; display: flex; gap: 0; margin: 0; border: 0;
}
#screen-login .auth-tab {
  flex: 1; padding: 20px 6px 16px; margin-bottom: -1px;
  background: none; border: 0; border-bottom: 2px solid transparent;
  border-radius: 0; cursor: pointer;
  font: inherit; font-weight: 700; font-size: 12px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-dim);
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
#screen-login .auth-tab:hover { color: var(--text); }
#screen-login .auth-tab.selected { color: var(--text); border-bottom-color: var(--accent-claro); }

/* O portao 18+: um bloco so, com fio em volta. Soltas no topo do
   painel as duas caixas pareciam sobra de formulario; cercadas, leem
   como a condicao que sao. */
#screen-login .consent {
  display: grid; gap: 13px; margin: 0 0 22px;
  padding: 15px 17px;
  border: 1px solid var(--divisor);
  background: rgba(127, 127, 127, .07);
}
#screen-login .check {
  display: flex; align-items: flex-start; gap: 11px; margin: 0;
  font-size: 14px; line-height: 1.4; color: var(--text-muted);
  cursor: pointer;
}
#screen-login .check input {
  width: 18px; height: 18px; margin: 0; flex: none;
  accent-color: var(--accent-claro); cursor: pointer;
}
#screen-login .check strong { color: var(--text); font-weight: 700; }

/* --- os botoes do painel ---
   Um cheio e um vazado, e so. O vazado era CHAPADO na cor da tinta
   com texto branco por cima: no tema escuro a tinta e clara, e o
   botao virava creme com letra branca — invisivel. Agora ele e
   contorno, que e a mesma peca nos dois temas, e so enche no hover. */
#screen-login .auth-card .btn {
  width: 100%; margin: 0; padding: 16px 18px;
  border: 2px solid transparent; border-radius: 0; cursor: pointer;
  font: inherit; font-weight: 700; font-size: 12.5px;
  letter-spacing: .14em; text-transform: uppercase;
  transition: background .2s var(--ease), color .2s var(--ease),
              border-color .2s var(--ease), filter .2s var(--ease),
              transform .1s var(--duro);
}
#screen-login .auth-card .btn.primary {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
/* Clarear em vez de um segundo hexadecimal: o vermelho do tema claro e
   o do escuro sao diferentes, e um valor fixo acertaria so um deles. */
#screen-login .auth-card .btn.primary:hover { filter: brightness(1.14); }
#screen-login .auth-card .btn.outline,
#screen-login .auth-card .btn.ghost {
  background: none; border-color: var(--tinta); color: var(--text);
}
#screen-login .auth-card .btn.outline:hover,
#screen-login .auth-card .btn.ghost:hover {
  background: var(--tinta); color: var(--papel);
}
#screen-login .auth-card .btn:active { transform: translateY(2px); }

.social-block { display: grid; gap: 10px; }
#screen-login .rec-note {
  margin: 9px 2px 0; padding: 0; border: 0; background: none;
  font-size: 12.5px; line-height: 1.5; color: var(--text-dim);
}

#screen-login .divider {
  margin: 26px 0 22px; font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-dim);
}
#screen-login .divider::before, #screen-login .divider::after { background: var(--divisor); }
#screen-login .divider span {
  font-family: var(--font-serif); font-style: italic;
  font-size: 14px; letter-spacing: 0; text-transform: none;
}

/* --- os campos ---
   Fundo proprio e fio visivel. Transparente com fio de --border, eles
   sumiam dentro do painel: dava pra ver o rotulo e nao a caixa, e o
   placeholder ficava mais escuro que o fundo. */
#screen-login .field { display: block; margin: 0 0 16px; }
#screen-login .field > span {
  display: block; margin-bottom: 8px;
  font-size: 11px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-dim);
}
#screen-login .field > span em {
  font-style: normal; font-weight: 400; letter-spacing: .04em;
  text-transform: none; opacity: .8;
}
#screen-login .auth-card input[type=text],
#screen-login .auth-card input[type=password] {
  width: 100%; padding: 14px 15px; border-radius: 0;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--divisor);
  font: inherit; font-size: 15px;
  transition: border-color .18s var(--ease);
}
#screen-login .auth-card input::placeholder { color: var(--text-dim); opacity: 1; }
#screen-login .auth-card input:focus { border-color: var(--accent-claro); }

/* O botao que fecha o assunto ganha um respiro antes dele: sem isso
   ele encosta no campo de senha e vira parte do formulario. */
#screen-login .auth-pane .btn.primary { margin-top: 20px; }
#screen-login .alt-login {
  margin-top: 14px; text-align: center;
  display: flex; justify-content: center; align-items: center; gap: .6em;
  font-size: 13px;
}
#screen-login .linkish { font-size: 13px; }

#screen-login .hint  { font-size: 12.5px; margin-top: 18px; }
#screen-login .error { font-size: 13.5px; margin-top: 16px; }

/* --- a porta de teste, no rodape ---
   Fio tracejado em cima: e o que diz "daqui pra baixo nao e a tela de
   verdade" sem precisar de rotulo dizendo isso. */
#screen-login #testeBlock {
  margin-top: 28px; padding-top: 22px;
  border-top: 1px dashed var(--divisor);
  display: grid; gap: 8px; text-align: center;
}
#screen-login #testeBlock .btn { width: 100%; margin: 0; }
#screen-login .teste-nota {
  margin: 0 0 6px; color: var(--text-dim);
  font-size: 12px; line-height: 1.5;
}

/* Nao ha escadinha de entrada aqui dentro. Tentei uma: cada bloco do
   formulario subindo com seu proprio atraso. Some tempo de espera com
   uma animacao por elemento e o que se ganha e a impressao de lentidao
   — e ela ainda roubava a animacao do portao 18+, que anima os mesmos
   elementos e e a unica que responde a um clique. O cartao inteiro
   entra de uma vez, e pronto. */

/* A PORTA SE APAGA quando o painel abre. So opacidade: ela chegou a
   ter tambem um recuo com escala e um desfoque de 1px, e era ali que
   a tela travava — desfocar o simbolo gigante que gira por baixo
   custa um redesenho inteiro por quadro.

   E o anel PARA de girar enquanto o painel esta aberto. Ninguem esta
   olhando pra ele nessa hora, e parado ele nao custa nada. */
#screen-login .porta-selo,
#screen-login .porta-marca,
#screen-login .porta-pe {
  transition: opacity .28s var(--ease);
}
#screen-login.auth-aberta .porta-selo,
#screen-login.auth-aberta .porta-marca,
#screen-login.auth-aberta .porta-pe { opacity: .14; }
#screen-login.auth-aberta .ps-anel { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  #screen-login .auth-card { transition: opacity .01s; transform: none; }
  #screen-login.auth-aberta .auth-card { transform: none; }
  .ps-anel { animation: none; }
}

/* A faixa de capas saiu da porta. Numa tela que agora é só marca e
   duas saídas, ela era a única coisa se mexendo sem motivo. */

@media (max-width: 760px) {
  .porta-pe { flex-direction: column; align-items: stretch; gap: 18px; }
  .porta-acoes { width: 100%; }
  .porta-btn { flex: 1; text-align: center; padding: 15px 10px; }
  .porta-selo { right: -34%; top: -14%; width: 150vw; }
  .porta-marca { width: 78vw; top: 42%; }
  /* No celular a caixa vira a tela inteira: sobra de margem em volta
     de um formulario que ja mal cabe e so aperta o que esta dentro. */
  #screen-login .auth-layout { padding: 0; align-items: stretch; }
  #screen-login .auth-card { width: 100%; max-height: none; border: 0; box-shadow: none; }
  .auth-topo  { padding: 16px 20px 0; }
  .auth-corpo { padding: 20px 20px 30px; }
}
/* Janela muito baixa — celular deitado, ou uma janela espremida no
   canto do monitor. Aqui nao ha altura pra composicao inteira: a
   marca encolhe e sobe, e o rodape fica com o que sobra. */
@media (max-height: 480px) {
  .porta-marca { width: min(38vw, 320px); max-height: 24vh; top: 32%; }
}
@media (max-height: 480px) and (max-width: 760px) {
  .porta-marca { width: min(52vw, 320px); }
}

@media (prefers-reduced-motion: reduce) {
  .porta-selo, .porta-pe { animation: none; }
  #screen-login .auth-card { transition: none; }
  #screen-login.auth-aberta .auth-topo,
  #screen-login.auth-aberta .auth-corpo > * { animation: none; }
}

/* --- O DESKTOP NÃO EXISTE NO CELULAR ---
   Ele é uma mesa: ícones que se arrastam, janelas lado a lado, um dock.
   Nada disso cabe num telefone — o ícone fica pequeno demais pro dedo,
   a janela ocupa a tela inteira (então não há "lado a lado"), e o
   arrastar briga com a rolagem. A tela clássica é a mesma informação em
   lista, que é o que funciona ali.

   Some o botão que troca de modo, nos dois lugares onde ele aparece: o
   do dock e o do cabeçalho da lista. O /app.js recusa a troca também,
   pra teclado e leitor de tela não acharem uma porta que não leva a
   lugar nenhum.

   O corte é 900px, o mesmo que este arquivo já usa mais abaixo pra
   virar a área numa grade e os ícones em position:static — o tamanho em
   que arrastar deixa de funcionar. Sem toque na conta: uma janela
   estreita no computador tem o mesmo problema que um celular. */
@media (max-width: 900px) {
  .dock-modo, .cl-modo, .dock-modo + .dock-div { display: none !important; }
}

/* O botão de pôr no desktop, na barra da sala. Aceso = já está lá. */
#btnAoDesktop.ativo { color: var(--accent-claro); }
#btnAoDesktop.ativo .ic { transform: rotate(-20deg); }
#btnAoDesktop .ic { transition: transform .18s var(--duro); }


/* ============================================================
   TELA CLÁSSICA — a saída pra quem não quer desktop
   ------------------------------------------------------------
   Coluna de conversas à esquerda, busca ocupando o resto. É o
   desenho que todo mundo já conhece de outros apps, e existe pra
   quem não quer arrumar ícone numa tela.
   ============================================================ */
#screen-classico.active {
  display: flex; flex-direction: column;
  height: 100dvh; overflow: hidden;
}
.cl-topo {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 12px clamp(14px, 2vw, 24px);
  border-bottom: 2px solid var(--tinta);
  background: var(--bg);
}
.cl-marca { display: flex; align-items: baseline; gap: .6em; }
.cl-marca b {
  font-family: var(--font-display); font-weight: 400; font-size: 18px;
  letter-spacing: -.03em; text-transform: uppercase; color: var(--text);
}
.cl-marca span {
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--text-dim);
}
.cl-topo .spacer { flex: 1; }
.cl-modo {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 14px; cursor: pointer;
  background: none; color: var(--text);
  border: 1.5px solid var(--tinta); border-radius: 0;
  font: inherit; font-size: 10.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  transition: background .16s var(--ease), color .16s var(--ease);
}
.cl-modo:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

.cl-corpo { flex: 1; min-height: 0; display: grid; grid-template-columns: 300px 1fr; }
.cl-coluna {
  min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  border-right: 2px solid var(--tinta);
  padding: 16px 0 20px;
}
.cl-col-topo { padding: 0 16px 12px; }
.cl-col-topo h2 {
  margin: 0 0 3px; font-family: var(--font-display); font-weight: 400;
  font-size: 15px; text-transform: uppercase; letter-spacing: -.01em;
}
.cl-col-nota {
  margin: 0; font-family: var(--font-serif); font-style: italic;
  font-size: 12.5px; color: var(--text-dim);
}
.cl-col-nota b { color: var(--accent-claro); font-style: normal; }

.cl-lista { display: flex; flex-direction: column; }
.cl-item {
  display: flex; align-items: center; gap: 4px;
  padding: 0 8px 0 6px;
  border-bottom: 1px solid var(--divisor);
}
.cl-item:hover { background: rgba(127, 127, 127, .12); }
/* Fixado ganha um filete vermelho na borda: a lista continua uma só,
   sem um cabeçalho "FIXADOS" separando e roubando altura. */
.cl-item.fixado { box-shadow: inset 3px 0 0 var(--accent); }
.cl-abrir {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 4px; cursor: pointer;
  background: none; border: 0; color: inherit; font: inherit; text-align: left;
}
.cl-arte {
  width: 46px; height: 26px; flex: none; overflow: hidden;
  border: 1.5px solid var(--tinta); background: var(--surface-2);
  display: grid; place-items: center; color: var(--text-dim);
}
.cl-arte img { width: 100%; height: 100%; object-fit: cover; }
.cl-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cl-nome {
  font-size: 13.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cl-sub { font-size: 11.5px; color: var(--text-dim); }
.cl-pino {
  flex: none; width: 30px; height: 30px; cursor: pointer;
  display: grid; place-items: center;
  background: none; border: 0; color: var(--text-dim);
  opacity: 0; transition: opacity .16s var(--ease), color .16s var(--ease);
}
/* O alfinete some até o mouse chegar — menos numa já fixada, onde ele
   é o sinal de que ela está presa ali. */
.cl-item:hover .cl-pino, .cl-item:focus-within .cl-pino { opacity: 1; }
.cl-item.fixado .cl-pino { opacity: 1; color: var(--accent-claro); }
.cl-pino:hover { color: var(--accent-claro); }
.cl-vazio { margin: 18px 16px; font-size: 13px; color: var(--text-dim); line-height: 1.5; }

.cl-principal { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.cl-principal .lobby { max-width: 1080px; margin: 0; padding: 22px clamp(16px, 2.4vw, 34px) 40px; }

/* O botão de trocar de modo, no dock. Discreto como o de arrumar. */
.dock-modo { width: 40px; opacity: .45; }
.dock-modo:hover, .dock-modo:focus-visible { opacity: 1; }

@media (max-width: 860px) {
  /* No celular a coluna não cabe ao lado: ela vira a primeira coisa da
     página e a busca vem embaixo. */
  .cl-corpo { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .cl-coluna {
    border-right: 0; border-bottom: 2px solid var(--tinta);
    max-height: 42vh; padding: 12px 0 8px;
  }
  .cl-modo span:not([data-icon]) { display: none; }
  .cl-pino { opacity: 1; }
}


/* ============================================================
   PASTAS DO DESKTOP
   ============================================================ */
/* A prévia: as quatro primeiras capas de dentro, em miniatura. Pasta
   sem prévia é caixa fechada — a pessoa teria que abrir só pra
   lembrar o que pôs lá. */
.di-previa {
  width: 100%; height: 100%;
  display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
  gap: 2px; padding: 4px;
}
.di-previa i {
  display: block; background: rgba(127, 127, 127, .28);
  background-size: cover; background-position: center;
}
.desk-pasta .di-arte { background: var(--surface-2); }

/* O ícone de baixo acende enquanto o de cima paira: a pasta não pode
   nascer de surpresa. */
.desk-icone.alvo .di-arte {
  box-shadow: 0 0 0 3px var(--accent), var(--salto) var(--salto) 0 var(--tinta);
  transform: scale(1.06);
}

.pasta-fundo {
  position: absolute; inset: 0; z-index: 45;
  display: grid; place-items: center;
  background: rgba(var(--bg-rgb), .55);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  animation: pastaFundo .16s var(--ease) both;
}
@keyframes pastaFundo { from { opacity: 0; } }
.pasta-caixa {
  width: min(520px, calc(100% - 40px)); max-height: min(70vh, 520px);
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 2px solid var(--tinta);
  box-shadow: calc(var(--salto) * 2) calc(var(--salto) * 2) 0 var(--tinta);
  animation: pastaAbre .2s var(--duro) both;
}
@keyframes pastaAbre { from { opacity: 0; transform: translateY(-10px) scale(.96); } }
.pasta-caixa:focus { outline: none; }

.pasta-topo {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 10px 10px 10px 12px;
  border-bottom: 2px solid var(--tinta); background: var(--papel);
}
.pasta-nome {
  flex: 1; min-width: 0;
  background: none; border: 1px solid transparent; border-radius: 0;
  padding: 5px 7px; color: var(--text);
  font-family: var(--font-display); font-weight: 400;
  font-size: 14px; letter-spacing: -.01em; text-transform: uppercase;
  transition: border-color .16s var(--ease), background .16s var(--ease);
}
/* O campo só parece campo quando a mão chega perto. Em repouso é só o
   nome da pasta — que é o que ele é 99% do tempo. */
.pasta-nome:hover { border-color: var(--divisor); }
.pasta-nome:focus { outline: none; border-color: var(--accent); background: var(--surface); }
.pasta-acao {
  flex: none; padding: 6px 10px; cursor: pointer;
  background: none; border: 1.5px solid var(--tinta); border-radius: 0;
  color: var(--text-dim); font: inherit; font-size: 10px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  transition: color .16s var(--ease), border-color .16s var(--ease);
}
.pasta-acao:hover { color: var(--accent-claro); border-color: var(--accent-claro); }
.pasta-x {
  flex: none; width: 26px; height: 26px; cursor: pointer;
  display: grid; place-items: center;
  background: none; border: 1.5px solid var(--tinta); color: var(--text);
}
.pasta-x:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

.pasta-grade {
  overflow-y: auto; overscroll-behavior: contain;
  padding: 14px;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px;
}
.pasta-item {
  display: flex; align-items: center; gap: 2px;
  border: 1px solid var(--divisor);
}
.pasta-item:hover { background: rgba(127, 127, 127, .12); }
.pi-abrir {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px;
  padding: 7px 8px; cursor: pointer;
  background: none; border: 0; color: inherit; font: inherit; text-align: left;
}
.pi-arte {
  width: 42px; height: 24px; flex: none; overflow: hidden;
  border: 1.5px solid var(--tinta); background: var(--surface-2);
  display: grid; place-items: center; color: var(--text-dim);
}
.pi-arte.redonda { width: 24px; border-radius: 50%; }
.pi-arte img { width: 100%; height: 100%; object-fit: cover; }
.pi-nome {
  font-size: 12.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pi-tirar {
  flex: none; width: 26px; height: 26px; cursor: pointer;
  display: grid; place-items: center;
  background: none; border: 0; color: var(--text-dim);
  opacity: 0; transition: opacity .16s var(--ease), color .16s var(--ease);
}
.pasta-item:hover .pi-tirar, .pasta-item:focus-within .pi-tirar { opacity: 1; }
.pi-tirar:hover { color: var(--accent-claro); }
#pastaVazia { padding: 0 14px 14px; }

@media (prefers-reduced-motion: reduce) {
  .pasta-fundo, .pasta-caixa { animation: none; }
}

/* ============================================================
   AS REGRAS DA SENHA — a lista que se marca sozinha
   ------------------------------------------------------------
   Fica debaixo de todo campo de senha NOVA (cadastro, redefinição
   pelo link e troca no perfil). Aparece cheia desde a chegada, antes
   da primeira tecla: a regra tem que estar escrita ANTES de ser
   cobrada, senão a pessoa só descobre o requisito errando.

   Três estados, e a diferença entre eles é de propósito:

   - EM ABERTO (cinza, com bolinha). O padrão. É uma lista de tarefas,
     não um erro — ninguém está devendo nada por ainda não ter digitado.
   - CUMPRIDO (verde, com visto). Acende no caractere que fecha a
     regra. É o único movimento aqui, e é o que deixa parar de digitar
     na hora certa em vez de no envio.
   - COBRADO (vermelho). SÓ depois de tentar enviar, e só no que
     faltou. Vermelho enquanto a pessoa digita seria bronca por ela
     não ter terminado de escrever — e um campo de senha já é um
     lugar tenso o bastante.

   O verde é o mesmo do .field-aviso.bom lá de cima: acerto no Banke
   tem uma cor só.
   ============================================================ */
.senha-regras {
  list-style: none;
  margin: -4px 0 clamp(8px, 1.8vh, 16px);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-dim);
}
.senha-regras li {
  display: flex;
  align-items: baseline;
  gap: 6px;
  transition: color .18s var(--ease);
}
/* Largura fixa pra troca de bolinha por visto não empurrar o texto de
   lado. Sem isto a lista inteira tremia a cada regra cumprida. */
.senha-regras .marca {
  flex: none;
  width: 11px;
  text-align: center;
  font-weight: 700;
  transition: color .18s var(--ease);
}
.senha-regras li.feito { color: #5ad18b; }
.senha-regras li.feito .marca { color: #5ad18b; }
/* O que ainda falta, depois de a pessoa ter tentado enviar. */
.senha-regras.cobrando li:not(.feito),
.senha-regras.cobrando li:not(.feito) .marca { color: var(--danger); }

@media (prefers-reduced-motion: reduce) {
  .senha-regras li, .senha-regras .marca { transition: none; }
}
