/* ---------------------------------------------------------------------------
   Escala de leitura (FSD §14.5)

   O corpo é o 1rem do navegador. O piso de 14px vale para o secundário, o botão
   pequeno e o selo; o título é o degrau de cima e o placar é a exceção para
   cima, porque é o número pelo qual a súmula existe.

   Antes disto a folha aplicava `font-size: small` em `*`, o que atingia também
   o `html`: a raiz da página era 13px e tudo descia dela. O corpo saía com
   13px, o botão com 11,375px e o selo do placar com 9,75px — o número mais
   importante da tela era o menor texto dela.
   --------------------------------------------------------------------------- */
:root {
  /* ---------------------------------------------------------------------------
     Design Tokens do Rolaabola (DESIGN.md)
     --------------------------------------------------------------------------- */
  /* Paleta de Cores */
  --color-brand-primary: #00C853;
  --color-brand-primary-hover: #009624;
  --color-brand-secondary: #1A237E;
  --color-brand-secondary-hover: #0D1660;
  --color-bg-base: #F5F7FA;
  --color-surface: #FFFFFF;
  --color-text-main: #212121;
  --color-text-muted: #757575;
  --color-danger: #D32F2F;
  --color-danger-hover: #B71C1C;
  --color-warning: #FFB300;
  /* **Cor do experimento de borda** (pedido): o lime usado na linha abaixo da
     navbar e no contorno dos elementos de fundo escuro. É um token, e não um
     hexadecimal solto na regra, para o experimento poder ser ligado e desligado
     num lugar só. */
  --color-experimental-lime: #87F527;
  --color-experimental-dark: #000000;

  /* **As cores dos pódios do cartão do grupo** (pedido): o ouro, a prata e o
     bronze das medalhas. O ouro é o mesmo amarelo do produto
     (`--color-warning`), que já é o tom da conquista nas telas; a prata e o
     bronze entram aqui porque o produto não tinha metal, e inventar um cinza
     solto no meio do CSS seria uma cor sem nome. */
  --color-medal-gold: #FFB300;
  --color-medal-silver: #9E9E9E;
  --color-medal-bronze: #A1662F;

  /* Tipografia */
  --font-family-base: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-family-display: 'Teko', sans-serif;

  /* Espaçamento (Grid 8px) */
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;

  /* Bordas */
  --border-radius-sm: 4px;
  --border-radius-md: 8px;
  --border-radius-lg: 12px;

  /* Escala de leitura original do portal */
  --rb-text: 1rem;
  --rb-text-small: 0.875rem;
  --rb-text-title: 1.5rem;
  --rb-text-score: 1.25rem;
  /* Teto de largura do conteúdo em tela larga. */
  --rb-largura: 1800px;
}

/* A fonte e cores-base da página. */
body {
  font-family: var(--font-family-base);
  background-color: var(--color-bg-base);
  color: var(--color-text-main);
  /* A página é uma coluna da altura da janela. O que sobra dela vai para a
     folga (`#folga_rodape`), que fica logo acima do rodapé — e é isso que põe o
     rodapé no pé da tela quando o conteúdo é curto, **sem** `position: fixed`,
     que cobriria o que estivesse embaixo dele. Quando o conteúdo passa da
     janela, a folga encolhe até o vão de separação e o rodapé volta a seguir o
     conteúdo: ele rola junto, e nunca esconde nada.

     `100vh` fica ao lado de `100dvh` de propósito: o `dvh` desconta a barra de
     endereço do celular, e o `vh` é o que sobra para o navegador que não o
     conhece. Sem os dois, o pé da página fica uma barra abaixo da janela. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

/* ---------------------------------------------------------------------------
   Classes Utilitárias do Design System (Harness de Vibe Coding)
   Tokens e componentes definidos no DESIGN.md
   --------------------------------------------------------------------------- */
.btn-brand,
.btn-brand-primary {
  background-color: var(--color-brand-primary);
  color: #ffffff;
  text-transform: uppercase;
  font-weight: 600;
  border-radius: var(--border-radius-md);
  border: 1px solid transparent;
  transition: background-color 0.2s ease-in-out, transform 0.1s ease;
}

.btn-brand:hover,
.btn-brand-primary:hover,
.btn-brand:focus-visible,
.btn-brand-primary:focus-visible {
  background-color: var(--color-brand-primary-hover);
  color: #ffffff;
}

.btn-brand-secondary {
  background-color: var(--color-brand-secondary);
  color: #ffffff;
  border-radius: var(--border-radius-md);
  border: 1px solid transparent;
  transition: background-color 0.2s ease-in-out;
}

.btn-brand-secondary:hover,
.btn-brand-secondary:focus-visible {
  background-color: var(--color-brand-secondary-hover);
  color: #ffffff;
}

.card-surface {
  background-color: var(--color-surface);
  border-radius: var(--border-radius-lg);
  border: none;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
}

.font-display,
.font-score,
.text-score {
  font-family: var(--font-family-display);
}

/* O miolo da página: o invólucro do conteúdo (`.miolo` no template), e o vão
   abaixo da barra do topo. A barra é **aderente** (`sticky-top`), então ela ocupa
   o próprio espaço e o conteúdo já nasce abaixo dela — o vão aqui é só respiro,
   e não a compensação de uma barra fora do fluxo. Foi a compensação que errou:
   a barra mede 41 px sem conta conectada e **60 px** com ela no celular, porque
   o `.nav-link` do menu respeita os 44 px de toque, e um número fixo não
   acompanhava os dois casos. */
.miolo {
  padding-top: 0.5rem;
}

/* A folga entre o conteúdo e o rodapé, elástica. `flex: 1 1 auto` faz ela
   absorver tudo o que sobra da janela — quando não sobra nada, ela vale o
   mínimo, que é o vão de separação entre o conteúdo e o rodapé. */
#folga_rodape {
  flex: 1 1 auto;
  min-height: 3rem;
}

/* Na folha de impressão não há folga nem rodapé (os dois são `d-print-none`), e
   a altura da janela não vale: a página é o papel. */
@media print {
  body {
    display: block;
    min-height: auto;
  }

  /* **No papel não existe tema escuro** (pedido: o tema). O `data-bs-theme` mora
     no `<html>`, escrito pelo script do tema antes da primeira pintura, e o
     bloco escuro da folha é `@media screen` — o que falta aqui é devolver ao
     Bootstrap as variáveis que ele mesmo troca no escuro. Sem isto, quem imprime
     no tema escuro levava o fundo preto para a folha, e a súmula, o ranking e o
     estatuto são impressos por todo o grupo. */
  [data-bs-theme="dark"] {
    color-scheme: light;
    --bs-body-color: #212121;
    --bs-body-color-rgb: 33, 33, 33;
    --bs-body-bg: #FFFFFF;
    --bs-emphasis-color: #000000;
    --bs-secondary-color: rgba(33, 37, 41, 0.75);
    --bs-secondary-bg: #E9ECEF;
    --bs-tertiary-bg: #F8F9FA;
    --bs-border-color: #DEE2E6;
    --bs-card-bg: #FFFFFF;
    --bs-card-cap-bg: rgba(33, 37, 41, 0.03);
    --bs-dropdown-bg: #FFFFFF;
    --bs-light-rgb: 248, 249, 250;
    --bs-dark-rgb: 33, 37, 41;
    --bs-danger-text-emphasis: #58151C;
  }

  /* **O card de um jogo da súmula não nasce cortado ao meio** (pedido): sem
     isto, a troca de página do papel podia partir o placar numa folha e a
     escalação na seguinte. O mesmo vale pra linha de uma tabela impressa (o
     ranking). `break-inside` é o nome atual do que `page-break-inside`
     sempre fez — os dois juntos cobrem o navegador que só conhece um deles. */
  [data-pdf="jogo"],
  tr {
    break-inside: avoid;
    page-break-inside: avoid;
  }
}

/* Realce do campo sob o ponteiro. Era `background-color`, e num formulário claro
   isso lê como "desabilitado": o campo piscava cinza à passagem do mouse. */
input:hover {
  border-color: #6c757d;
}

/* Título de tela: o mesmo tamanho em todas as telas e independente da tag. Antes
   o perfil usava `h1.h4` e a súmula `h3.title` — dois níveis de título e dois
   tamanhos para o mesmo papel. */
.title {
  font-size: var(--rb-text-title);
  line-height: 1.25;
}

/* **O nome do grupo, com a sede, em qualquer lugar do produto** (PRD, §9, itens
   100 e 101): o nome e, entre parênteses, bairro, cidade e UF — **tudo o que está
   dentro dos parênteses numa fonte menor**.

   Só o tamanho muda entre as duas partes: o nome herda o de onde ele está (título
   de tela, item de lista, cabeçalho de cartão) e a sede desce para o degrau do
   secundário (`--rb-text-small`, o piso de leitura do produto). Onde a sede é
   mostrada — nas listas e nas buscas —, a linha é uma só, e é uma frase que quebra
   sozinha quando não couber (item 101). Onde ela **espera o toque** (item 110), o
   bloco é uma coluna e a sede desce centralizada abaixo do nome. */
.nome-do-grupo-sede {
  font-size: var(--rb-text-small);
}

/* **A sede aparece quando se toca no nome** (PRD, §9, item 110): o bloco vira uma
   coluna, e a sede desce **centralizada** abaixo do nome. O nome é um `<button>`
   ali — é o que dá o toque e o `Enter` a quem revela o lugar —, e o botão é o
   próprio texto: sem caixa, sem fundo e com a fonte de onde ele está, para o
   título continuar sendo o título. */
.nome-do-grupo-tocavel {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
}

.nome-do-grupo-nome[data-nome-do-grupo] {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
}

.nome-do-grupo-nome[data-nome-do-grupo]:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* **A aba é um rótulo, e não um botão de ação** (PRD, §9, item 96): as pílulas
   nasciam com o respiro do Bootstrap (`.5rem 1rem`) e ficavam com 42 px de altura
   — do tamanho dos botões que **fazem** coisas, e maiores do que o assunto que
   elas abrem. Aqui elas encolhem para o tamanho de um rótulo, com o piso de
   24 px da WCAG 2.2 (2.5.8) preservado.

   Quem manda na altura do **dedo** continua sendo a régua de toque, na faixa de
   `pointer: coarse`: lá as abas seguem com 44 px, porque alvo de polegar não se
   mede em elegância. */
.nav-pills .nav-link {
  padding: 0.25rem 0.6rem;
  font-size: var(--rb-text-small);
  line-height: 1.4;
}

/* **A aba parece uma aba** (PRD, §9, item 112). As pílulas eram retângulos soltos
   com o respiro do `gap` entre eles, e o olho lia uma fileira de botões — não os
   assuntos da mesma tela. Cada aba passa a ser um retângulo **encostado no
   vizinho**, com o canto de cima arredondado e a borda de baixo da barra
   atravessando tudo: a aberta é a que **encosta no conteúdo**, e as outras ficam
   um degrau acima dela.

   A cor da aba aberta é a do fundo da página (`--bs-body-bg`), e não o preto do
   `bg-dark` de antes: o que diz qual está aberta é ela ser a **continuação** da
   tela, e uma pílula preta no meio de cinco claras dizia "esta é a que faz
   coisas" — que é o que o item 96 tirou das abas. Só o desenho mudou: as abas
   continuam ligações, com o `aria-current="page"` na aberta, e o alvo continua
   com o piso de 24 px (44 no dedo). */
.abas {
  align-items: flex-end;
  border-bottom: 2px solid var(--bs-dark);
}

.abas .nav-link {
  border: 1px solid var(--bs-dark);
  border-bottom: 0;
  border-radius: 0.4rem 0.4rem 0 0;
  background: var(--bs-secondary-bg);
  color: var(--bs-body-color);
}

.abas .nav-link.active {
  margin-bottom: -2px;
  border-bottom: 2px solid var(--bs-body-bg);
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  font-weight: 600;
}

.abas .nav-link:hover,
.abas .nav-link:focus-visible {
  background: var(--bs-tertiary-bg);
}

/* **O botão de ajuda é o ícone, e o `<button>` tem o tamanho exato dele**
   (pedido): sem `padding`, sem margem interna e sem o piso de toque que os
   outros botões de ícone usam — o alvo não sobra além do `question-circle-fill`
   em nenhum ponteiro. Sem caixa, sem contorno e sem fundo: o elemento continua
   `<button>`, com o `Tab`, o nome acessível e o `aria-expanded` que o
   `iniciarAjuda` mantém — só o tamanho muda. */
.botao-ajuda {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  color: inherit;
  line-height: 1;
  vertical-align: middle;
  cursor: pointer;
}

/* **O detalhe da tabela é o mesmo desenho** (PRD, §9, item 104): ele abria a
   linha com a caixa do Bootstrap (`btn btn-sm btn-outline-light`), e numa tabela
   já cheia de número a caixa ao lado do desenho era mais uma borda para ler — a
   última da linha clara sobre o fundo escuro. Sem ela, o desenho fica do tamanho
   do resto do que a linha diz, e continua sendo o que era: uma ligação, com o
   nome acessível e o mesmo alvo. */
.botao-detalhe {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  line-height: 1;
  vertical-align: middle;
}

/* **O `?` é o desenho puro, e o que ele abre é um balão preto** (PRD, §9, itens 99
   e 108). O fundo preto do item 106 pesava no meio de um parágrafo cinza, onde o
   botão vive: o `question-circle-fill` já é um círculo cheio, e sem a caixa e sem
   o fundo ele fica do tamanho do resto do que o texto diz. O que dá o sinal de
   que ali se clica é a cor — o ícone escurece no ponteiro, e o anel do foco
   aparece no teclado. */
.botao-ajuda:hover,
.botao-ajuda:focus-visible {
  color: #000;
}

/* **O balão da ajuda é preto, e nasce colado no `?`** (PRD, §9, item 106). Ele
   não ocupa lugar nenhum no documento: é `position: fixed`, posto pelo `portal.js`
   ao lado do botão que o abriu, com o preto do produto e o texto em branco — o
   texto não empurra nada, e o `?` não precisa de uma linha só para ele. O
   `z-index` é o do tooltip do Bootstrap: **acima do modal**, porque o `?` também
   vive dentro de um.

   A largura é a do texto até um teto, e o teto encolhe junto com a janela: em
   telefone o balão é da largura da tela menos o respiro. */
.balao-ajuda {
  position: fixed;
  z-index: 1080;
  max-width: 22rem;
  padding: 0.5rem 0.65rem;
  border-radius: 0.35rem;
  background: #000;
  color: #fff;
  font-size: var(--rb-text-small);
  line-height: 1.35;
  white-space: pre-line;
  box-shadow: 0 0.35rem 0.9rem rgba(0, 0, 0, 0.35);
}

/* **O detalhe acende, em vez de escurecer** (item 104): as três tabelas do
   produto são escuras (`table-dark`), e o preto do ponteiro do botão de ajuda
   sumiria com o desenho no fundo escuro. O que muda é a opacidade — o desenho
   está a 75% em repouso, no tom do texto secundário da linha, e chega ao branco
   cheio no ponteiro e no foco. */
.botao-detalhe {
  opacity: 0.75;
}

.botao-detalhe:hover,
.botao-detalhe:focus-visible {
  opacity: 1;
}

/* O `?` colado no que ele explica: um respiro pequeno do texto à esquerda, e
   nada acima nem abaixo, para ele não empurrar a linha. */
.botao-ajuda-acolado {
  margin: 0 0 0 0.3rem;
  vertical-align: middle;
}

.explicacao-texto {
  display: inline;
}

/* O asterisco do campo obrigatório (pedido): um sinal só, na cor de erro que o
   produto já usa para o que impede o salvamento, sem repetir "obrigatório" por
   extenso em cada rótulo. */
.rotulo-obrigatorio::after {
  content: " *";
  color: var(--bs-danger);
}

/* ---------------------------------------------------------------------------
   O evento nasce do nome do atleta (PRD, §9, item 112)

   Com a partida em andamento, o nome de quem está em campo é o botão que registra
   o que aconteceu com ele. Ele **não vira um botão**: o nome continua sendo o
   texto da escalação, e o que o toque acrescenta é um sublinhado pontilhado — a
   mesma pista da marca de troca do quadro. Um botão com caixa em cada nome de uma
   lista de dez transformaria a escalação numa grade de botões, que é o que o item
   104 tirou do quadro.
   --------------------------------------------------------------------------- */
.nome-evento {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  text-decoration: underline dotted;
  text-underline-offset: 0.15em;
}

.nome-evento:hover,
.nome-evento:focus-visible {
  background: var(--bs-secondary-bg);
  border-radius: 0.2rem;
}

/* **A caixa do evento é preta, como o balão da ajuda** — e pelo mesmo motivo: ela
   flutua por cima da escalação sem empurrar o que está embaixo. Fica fora do
   fluxo (`position: fixed`, posta pelo `portal.js`), então nem a rolagem nem o
   `overflow` de um cartão a cortam. O `z-index` é o do balão: as duas são caixas
   do mesmo tipo, e a que abriu por último fica por cima. */
.menu-evento {
  position: fixed;
  z-index: 1080;
  min-width: 11rem;
  max-width: min(22rem, calc(100vw - 1rem));
  max-height: 60vh;
  overflow-y: auto;
  padding: 0.3rem;
  border-radius: 0.4rem;
  background: #000;
  color: #fff;
  font-size: var(--rb-text-small);
  box-shadow: 0 0.35rem 0.9rem rgba(0, 0, 0, 0.35);
}

.menu-evento-titulo {
  padding: 0.15rem 0.45rem 0.3rem;
  color: #adb5bd;
}

/* O bloco de papel da espera ("Goleiros", "Jogadores de linha"): um rótulo, e não
   uma opção — quem aperta é o nome abaixo dele. */
.menu-evento-grupo {
  padding: 0.3rem 0.45rem 0.1rem;
  color: #adb5bd;
  text-transform: uppercase;
  font-size: 0.75em;
  letter-spacing: 0.03em;
}

.menu-evento-opcao {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  min-height: 2rem;
  padding: 0.25rem 0.45rem;
  border: 0;
  border-radius: 0.25rem;
  background: none;
  color: #fff;
  text-align: left;
  line-height: 1.3;
}

.menu-evento-opcao:hover,
.menu-evento-opcao:focus-visible {
  background: #343a40;
}

/* O erro do registro aparece **na caixa que o pediu**: o menu está aberto na
   escalação, e um recado no rodapé do cartão não diria a quem apertou o que fazer.
   O vermelho é claro porque o fundo é preto — o `text-danger` do Bootstrap some. */
.menu-evento-erro {
  margin-top: 0.25rem;
  padding: 0.25rem 0.45rem 0.1rem;
  color: #ff8b8b;
}

/* **O cartão do menu é o desenho do cartão, na cor dele** (PRD, §9, item 112):
   amarelo, azul e vermelho do produto, num retângulo do tamanho de um cartão de
   verdade. Um quadrado cheio diria "a cor é esta"; o retângulo diz **o que** tem
   essa cor, que é o que a opção escolhe. */
.cartao-do-menu {
  flex: 0 0 auto;
  width: 0.7rem;
  height: 1rem;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 0.15rem;
}

.cartao-do-menu.cartao-amarelo {
  background: #ffc107;
}

.cartao-do-menu.cartao-azul {
  background: #0d6efd;
}

.cartao-do-menu.cartao-vermelho {
  background: #dc3545;
}

/* **O tênis da assistência é um SVG, não um emoji** (pedido: "preto de
   verdade"): emoji não aceita `color`, e o SVG precisa do tamanho e do
   alinhamento que o emoji já tinha de graça, herdados da fonte. Só mexe
   com ícones que trazem o próprio `<svg>` — o resto (bola, cartão) continua
   emoji de texto, sem este seletor valer para eles. */
.evento-icone svg {
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.15em;
}

/* **O ícone de cartão na lista de eventos é 10% mais estreito** (pedido): só a
   largura encolhe — a altura continua a do emoji normal, e o `inline-block`
   é o que faz o `transform` valer no emoji, que por padrão é inline. */
.evento-icone-cartao {
  display: inline-block;
  transform: scaleX(0.9);
}

/* **O segundo amarelo é um cartão só** (pedido): o vermelho nasce no mesmo
   lugar do amarelo e desloca 20% da própria largura e altura para baixo e
   para a direita — por cima dele, e não do lado. */
.evento-icone-cartoes-duplo {
  position: relative;
  display: inline-block;
}

.evento-icone-cartoes-duplo .evento-icone-cartao-sobreposto {
  position: absolute;
  left: 20%;
  top: 20%;
}

/* **A lista do menu de grupos rola por dentro** (PRD, §9, item 98): com vinte
   grupos, o menu ficava mais alto do que a tela e levava o campo de busca junto.
   O teto é de 50vh — o campo e as primeiras linhas ficam sempre à vista, e o
   resto se alcança rolando dentro da lista. */
.lista-de-grupos {
  max-height: 50vh;
  overflow-y: auto;
}

/* Selo: placar, situação da pelada, papel do membro, estado do convite. Carrega
   informação, não enfeite — e é **sempre menor que o texto a que se refere**
   (PRD, §9, item 102).

   O tamanho é **relativo** (`0,85em`): o selo do nome de um atleta (16 px) sai com
   13,6 px, e o de uma linha secundária (14 px) sai menor que ela. Antes ele era um
   número fixo — 14 px —, e num bloco de texto secundário ficava **do mesmo
   tamanho** do texto que ele qualifica: a hierarquia sumia justamente onde a
   linha é mais apertada.

   O `max()` é o freio: 12 px é o piso abaixo do qual o selo deixa de ser lido, e
   é o número que o Bootstrap dava por padrão — aqui ele volta como **mínimo**, e
   não como o tamanho de sempre. */
.badge {
  font-size: max(0.75rem, 0.85em);
}

/* Placar. Sobe acima do corpo e usa algarismo de largura fixa, para o número não
   mudar de largura quando vai de 9 para 10: o operador lê isso de relance, em pé
   e no sol.

   Vem depois de `.badge` de propósito: as duas regras têm a mesma
   especificidade, e o placar é um selo — quem manda no tamanho dele é esta. */
.selo-placar {
  font-size: var(--rb-text-score);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

/* **O selo do tempo é menor que o placar** (pedido): ele acompanha o placar na
   mesma linha, e o que se procura ali é o placar. Os dois são **um bloco**
   (`selo-e-placar`): a caixa não se parte, então o tempo nunca fica numa linha e
   o placar noutra — quando não cabe, desce o conjunto.

   Estas duas regras viviam dentro da faixa de celular, e por isso **no
   computador** o selo saía com a fonte do selo comum e a caixa não segurava o
   par na mesma linha: o ajuste existia só abaixo de 576px, que é onde ele menos
   falta. O que é de leitura vale em qualquer largura. */
.selo-e-placar {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: 0.5rem;
}

.selo-tempo {
  font-size: 0.7rem;
  font-weight: 500;
}

/* **Quem saiu numa substituição** (pedido): tachado e vermelho, e sem o botão do
   evento — o que saiu de campo saiu até o fim desta partida. **Quem entrou** fica
   verde: ele está em campo, e recebe evento como qualquer atleta. **Quem foi
   expulso** tem o mesmo desenho de quem saiu, e o motivo no `title`.

   Mesma história do selo: as duas primeiras nasceram dentro da faixa de 576px, e
   no computador — onde o operador confere a partida — os nomes saíam sem marca
   nenhuma. A marca é do **dado**, e não da largura da tela. */
.nome-substituido {
  color: var(--bs-danger);
  text-decoration: line-through;
}

.nome-entrou {
  color: var(--bs-success);
  font-weight: 600;
}

.nome-expulso {
  color: var(--bs-danger);
  text-decoration: line-through;
}

/* Dropdown Content */
.dropdown-content {
  display: none;
  position: absolute;
  top: 99%;
}
  
.dropdown-content a {
  text-decoration: none;
  display: block;
}
  
.dropdown:hover .dropdown-content {
  display: block;
}

/* Input de minutos do apito. No desktop ele é estreito de propósito, para caber
   ao lado do cronômetro; no toque, o bloco de ponteiro o alarga. */
#apito {
  max-width: 30px;
  cursor: pointer;
}

/* ---------------------------------------------------------------------------
   Piso de alvo de toque (WCAG 2.2 AA, 2.5.8)

   O desenho pode ser pequeno; o **alvo** não. No dedo a régua desta casa sobe
   para 44×44 (FSD §14.5) e é a faixa de `pointer: coarse` que a aplica; aqui fica
   o piso que vale em qualquer ponteiro, para um botão de ícone num telefone
   estreito de mouse não ser menor do que o critério pede.

   Medido a 360 px, com ponteiro fino: as setas de ordem nasciam com **23×22** e o
   atalho de impressão da súmula, **31×16** — os dois abaixo dos 24 px do critério.
   --------------------------------------------------------------------------- */
.btn.py-0,
.btn-acao,
.botao-seta {
  min-width: 24px;
  min-height: 24px;
}

/* **O campo da presença tem a altura do botão ao lado** (PRD, §9, item 96): o
   `form-control-sm` do Bootstrap nasce com 31 px e as setas de ordem, com 24 — a
   linha ficava com dois degraus, e o olho lia o campo como o elemento importante
   da linha. O que se lê ali é o **nome**, e o nome não precisa de um campo mais
   alto do que as setas que o movem: o respiro de cima e de baixo sai, e o piso de
   24 px do critério 2.5.8 fica.

   A altura do dedo continua vindo da régua de toque: lá o botão tem 44 px, e o
   campo acompanha (a regra está na faixa de `pointer: coarse`). */
.linha-ordem .form-control {
  min-height: 24px;
  padding-top: 0;
  padding-bottom: 0;
}

/* ---------------------------------------------------------------------------
   Avisos que se fecham (PRD, §9, item 69)

   Mensagem informativa, de atenção ou de erro nasce para ser lida, e sai quando
   quem leu quiser: cada bloco ganha um `×` no canto superior direito. O bloco
   precisa de `position: relative` para o `×` poder encostar no canto, e de uma
   folga à direita para o texto não passar por baixo dele — a folga acompanha a
   largura do alvo do `×`, que tem o piso de 24 px de qualquer ponteiro (é o
   `.btn-close` do Bootstrap, que sozinho desenha 16 px).
   --------------------------------------------------------------------------- */
.aviso-fechavel {
  position: relative;
  padding-right: 2.5rem;
}

.aviso-fechar {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  min-width: 24px;
  min-height: 24px;
}

/* O aviso recebe o foco quando nasce (PRD, §9, item 91), e o anel do foco é
   escondido: quem olha já está lendo a mensagem, e o contorno em volta dela seria
   um segundo desenho dizendo o que a rolagem acabou de dizer. O foco continua no
   lugar para quem lê a tela — é ele que faz o anúncio. */
.alert:focus,
.alert:focus-visible {
  outline: none;
}

/* ---------------------------------------------------------------------------
   Listas ordenáveis (presença, fila de espera, bloco do sorteio e quadro)

   A ordem destas listas é regra: a presença vira a prioridade do sorteio, a fila
   vira a ordem de entrada, e a linha da equipe vira o rodízio do próximo jogo.
   Quem opera arruma essa ordem **com duas setas no fim da linha** (PRD, §9, item
   59) — o arrasto saiu, e com ele a pega: o gesto exigia segurar o dedo parado,
   não existia no teclado, e a pega ocupava a linha inteira com um desenho que não
   dizia para onde a linha ia. Nas **listas** são as setas, e continua sendo: a
   regra é a mesma para trás e para diante — e vale também para o **quadro de
   formação**, onde cada linha e cada nome da espera têm as suas (item 103).

   As setas são **só ícone**, com nome acessível e dica: a palavra "Subir" em cada
   linha empurraria o nome para fora da tela, e numa lista de vinte atletas seriam
   sessenta palavras repetidas. É a mesma exceção declarada do cronômetro
   (§14.6).
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   **A lista da troca: apertar o nome e escolher quem troca** (PRD, §9, item 103)

   O arrasto saiu — ele pedia um gesto que o operador tinha de descobrir ("aperte um
   nome, arraste e solte em cima de outro"), competia com a rolagem da página no
   telefone, e o quadro se mexia no meio do gesto. Agora o toque no nome abre uma
   **lista curta e preta**, colada nele, com os outros atletas da partida e o lugar
   de cada um; escolher um troca os dois.

   A lista é `position: absolute` **do item**, e por isso o item é `relative` — ela
   nasce embaixo do nome que a abriu, e não no fim da página. O fundo é o preto do
   produto (o mesmo do botão de ação), e o texto é branco: é uma lista de escolha, e
   não um cartão de leitura.
   --------------------------------------------------------------------------- */
.zona-do-quadro li[data-atleta] {
  position: relative;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}

/* **A linha do quadro não tem caixa** (PRD, §9, item 104): cada atleta vinha
   dentro de um retângulo com contorno, e o quadro — que já tem a moldura da zona
   e a do cartão — virava uma grade de caixas dentro de caixas. O que separa um
   atleta do outro é o respiro da linha, e o que diz que ela se mexe é o cursor e
   o anel do foco. A borda sai da folha e do desenho do navegador (a linha que o
   `portal.js` monta usa as mesmas classes).

   **A marca da troca é o que sobra de cor na linha** (item 104): as duas linhas
   que mudaram de lugar ficam com o azul claro do Bootstrap — o mesmo tom de
   informação que o produto já usa —, e a marca fica até a página sair. É ela que
   faz a conferência da formação antes de confirmar o jogo, e é por isso que ela
   é pintada no item, e não na zona. */
.zona-do-quadro li[data-atleta].trocado {
  background-color: #cfe2ff;
  border-radius: 0.2rem;
}

.combo-trocas {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 30;
  margin: 0.15rem 0 0;
  padding: 0.2rem;
  /* **Pequena: do tamanho do que ela oferece.** A lista é uma escolha rápida ao
     lado do nome, não um painel: mede o texto das opções, com piso de `11rem`
     para não ficar espremida quando os nomes são curtos e teto na largura da
     coluna que a abriu — nome comprido encurta na reticência em vez de empurrar
     a caixa para fora da tela. O teto de altura é o que mantém a lista curta com
     a pelada cheia: quem rola é ela, não a página. */
  width: max-content;
  min-width: 11rem;
  max-width: 100%;
  max-height: 40vh;
  overflow-y: auto;
  list-style: none;
  background: #212529;
  border-radius: 0.25rem;
  box-shadow: 0 0.35rem 0.75rem rgba(0, 0, 0, 0.35);
}

/* **A lista abre para cima quando não cabe embaixo** (PRD, §9, item 114): o quadro
   da sugestão vive num modal com rolagem, e a lista de trocas de um atleta do fim
   da área visível caía abaixo da borda do corpo — fora do alcance do dedo. Quem
   decide é o `portal.js`, que mede onde a lista cairia. */
.combo-trocas-acima {
  top: auto;
  bottom: 100%;
  margin: 0 0 0.15rem;
  /* **A altura é do conteúdo, e não do espaço que sobrou.** Com `top: auto` e
     `bottom: 100%`, o navegador calcula a altura disponível **dentro do atleta** —
     a linha do nome, uns 21 px — e a lista subia com a altura da própria borda
     (6 px de respiro, nenhuma opção à vista). O `max-content` diz que o tamanho é o
     do conteúdo; o teto de `40vh` continua mandando com a pelada cheia, e quem rola
     é a lista. */
  height: max-content;
}

.combo-troca {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  padding: 0.2rem 0.4rem;
  border: 0;
  border-radius: 0.2rem;
  background: none;
  color: #fff;
  font-size: var(--rb-text-small);
  text-align: left;
  white-space: nowrap;
}

.combo-nome {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* **A saída do rodízio fica separada das trocas** (PRD, §9, item 104): ela não é
   "trocar de lugar com fulano", é "não joga mais hoje" — e a linha divisória diz
   isso antes de o operador ler a opção. O texto é o que ele procura quando alguém
   avisa no meio da pelada que só jogou aquela. */
.combo-saida {
  margin-bottom: 0.2rem;
  padding-bottom: 0.2rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.25);
}

.combo-troca:hover,
.combo-troca:focus-visible {
  background: rgba(255, 255, 255, 0.16);
}

/* **O que a gravação recusaria aparece apagado** (item 103): um goleiro não joga
   na linha, e o quadro não propõe o que a API não aceita. */
.combo-troca[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
}

.combo-onde {
  font-size: max(0.75rem, 0.85em);
  opacity: 0.75;
}

/* Onde o teclado está: o mesmo anel do resto do produto, para quem navega por
   `Tab` saber em que nome as teclas de Alt vão mexer (PRD, §9, item 88).

   A segunda regra é para o foco que **vem do código**: depois de mover um atleta
   com Alt+seta o foco é posto nele por `focus()`, e o `:focus-visible` do
   navegador não acende sozinho nesse caminho — sem ela, o nome andaria sem
   ninguém saber em quem a próxima tecla vai mexer. */
.zona-do-quadro li[data-atleta]:focus-visible,
.zona-do-quadro li[data-atleta].foco-do-teclado {
  outline: 2px solid #ffc107;
  outline-offset: 1px;
}

.ordem-setas {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  /* As setas ficam no fim da linha, empurradas para lá — é onde o dedo procura
     o que mexe na ordem, e é o que mantém o nome à esquerda. */
  margin-left: auto;
  flex: 0 0 auto;
}

/* **A seta de ordem é o caret puro** (PRD, §9, item 104): sem a caixa e o
   contorno do botão do Bootstrap, que faziam de cada linha uma fileira de
   botões de içar — e a linha tem um atleta, não uma ação. O controle continua
   sendo um `<button>` de verdade, com o `data-mover` que o `portal.js` lê, o
   nome acessível e a dica; o que sai é o desenho da caixa.

   O alvo não encolhe junto: o piso de 24 px do critério 2.5.8 vale aqui como em
   todo controle de ícone, e a régua de toque sobe para 44 no dedo. O sinal de
   que ali se clica é a cor — o caret escurece no ponteiro e o anel do foco
   aparece no teclado, a mesma convenção do botão de ajuda (item 99). */
.botao-seta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font-size: 0.85rem;
  line-height: 1;
}

.botao-seta:hover {
  color: #000;
}

.botao-seta:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 1px;
}

/* **A foto de perfil** (pedido): sempre um círculo, sempre recortada — é a
   API quem já entrega o arquivo quadrado (`object-fit: cover` é só a rede de
   segurança para a imagem antiga, de antes do recorte existir). O ícone
   genérico ocupa o mesmo espaço da foto grande, para o card não pular de
   tamanho quando a conta ganha ou perde a foto. */
.avatar-conta {
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
}

.avatar-conta-grande,
.avatar-conta-icone {
  width: 72px;
  height: 72px;
}

.avatar-conta-icone {
  font-size: 72px;
  line-height: 1;
  color: var(--color-text-muted);
}

/* **A foto aproveita o espaço do botão da conta** (pedido): o alvo já reserva
   44 px no dedo, e 36 px de foto usa bem essa caixa sem estourar a barra de
   60 px que o item anterior deste mesmo backlog corrigiu. */
.avatar-conta-navbar,
.avatar-conta-navbar-icone {
  width: 36px;
  height: 36px;
}

.avatar-conta-navbar-icone {
  font-size: 36px;
  line-height: 1;
}

/* No item do menu há mais respiro ao lado do nome: a foto cresce um pouco. */
.avatar-conta-menu,
.avatar-conta-menu-icone {
  width: 40px;
  height: 40px;
}

.avatar-conta-menu-icone {
  font-size: 40px;
  line-height: 1;
}

/* **A foto ampliada aproveita a tela** (pedido): o lado é o menor entre 70%
   da largura, 60% da altura e 400 px — grande em qualquer aparelho, sem
   estourar a tela deitada nem um monitor enorme. */
.avatar-conta-ampliada,
.avatar-conta-icone-grande {
  width: min(70vw, 60vh, 400px);
  height: min(70vw, 60vh, 400px);
  margin-left: auto;
  margin-right: auto;
}

.avatar-conta-icone-grande {
  font-size: min(70vw, 60vh, 400px);
  line-height: 1;
  color: var(--color-text-muted);
}

/* A linha da presença é campo + setas: o campo ocupa a sobra. */
.linha-ordem > .form-control {
  min-width: 0;
  flex: 1 1 auto;
}

/* A linha do bloco do sorteio é número + nome + setas. */
.linha-ordem {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.linha-ordem > span:not(.ordem-setas) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.linha-ordem > span.ordem,
.linha-ordem > .ordem {
  min-width: 1.25rem;
  flex: 0 0 auto;
  text-align: right;
  overflow: visible;
}

/* **A linha da espera é uma linha só** (PRD, §9, item 105).

   Ela usava o `linha-acao`, que no celular empilha o texto e as ações: cada
   atleta da espera virava **duas** linhas — o nome em cima e as setas embaixo —,
   e uma lista de dez atletas ficava com vinte linhas. Aqui não há o que
   empilhar: o nome e as duas setas cabem na largura de um telefone, e a linha
   fica de pé. O nome trunca com reticências em vez de empurrar a seta para fora
   da tela.

   O que separava um atleta do outro era a `border-bottom` herdada da lista de
   eventos: dentro do cartão da espera, ela virou uma grade de riscos, e o
   respiro da linha já diz onde um atleta acaba e o outro começa. */
.fila-linha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem;
  padding: 0.25rem 0;
}

.fila-linha > .fila-nome {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* **As ações da linha ficam juntas, na ponta** (pedido): a linha da espera ganhou
   o "tirar do jogo" ao lado das setas de ordem, e as duas têm de ficar coladas —
   com `space-between` na linha e três filhos, as setas iam para o meio. */
.fila-acoes {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  flex: 0 0 auto;
}

/* A linha de fora não tem ordem: só o nome e o caminho de volta. */
.fora-linha {
  color: var(--bs-secondary);
}

/* **A linha do jogo é o que abre e fecha** (PRD, §9, item 106).

   O botão "Ver" saiu da lista de jogos: quem quer ver o jogo por dentro toca na
   linha onde estão o número e a situação dele — que é o que se lê antes de
   querer ver mais. O cabeçalho é um `<button>` de verdade (chega pelo `Tab`,
   abre pelo `Enter`), sem caixa e sem fundo, e a seta gira com o
   `aria-expanded` que o Bootstrap mantém. As ações do jogo — refazer, iniciar,
   encerrar — ficam **fora** dele, na faixa ao lado: elas mexem no jogo, e não no
   que está à vista. */
.jogo-cabecalho {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
}

.jogo-cabecalho:hover,
.jogo-cabecalho:focus-visible {
  color: #000;
}

.jogo-seta {
  flex: 0 0 auto;
  transition: transform 0.15s ease-in-out;
}

.jogo-cabecalho[aria-expanded="true"] .jogo-seta {
  transform: rotate(180deg);
}

/* ---------------------------------------------------------------------------
   As funções do jogo: dois campos pequenos, e fechadas no fim da partida
   (PRD, §9, item 113)

   No telefone o bloco ocupava **246 px** — cada campo virava uma linha inteira do
   cartão, porque o `<select>` de nome de atleta se dimensiona pelo conteúdo (o
   mais longo manda), e os dois empilhavam com o botão e com o texto. Agora os
   dois ficam **lado a lado**, com a largura da coluna e um teto: quem cede é o
   nome, e não a linha do cartão. O `<select>` corta o texto que não couber, que é
   como um `select` se comporta.

   O `<details>` é o que fecha o bloco quando a partida acaba: depois do apito o
   que se faz com as funções é conferir ou corrigir, e dois campos abertos no fim
   da pelada são comprimento de tela sem trabalho. O título é o `summary`, e a
   seta é a mesma do cabeçalho do jogo — girando para baixo quando abre. */
.funcoes-do-jogo {
  min-width: 0;
}

.funcoes-titulo {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
  list-style: none;
}

.funcoes-titulo::-webkit-details-marker {
  display: none;
}

.funcoes-seta {
  flex: 0 0 auto;
  transition: transform 0.15s ease-in-out;
}

.funcoes-do-jogo[open] .funcoes-seta {
  transform: rotate(180deg);
}

/* O teto de largura é o que mantém os dois campos "pequenos" também na tela
   larga: o cartão do jogo da vez é uma coluna inteira no `lg`, e sem ele o campo
   de 12 caracteres viraria uma faixa de 300 px. */
.funcao-do-jogo {
  max-width: 12rem;
}

/* ---------------------------------------------------------------------------
   A linha do evento: o que aconteceu, e as duas ações (PRD, §9, item 113)

   "Corrigir" e "Excluir" escritos em duas caixas ocupavam mais largura do que o
   próprio evento, e a linha empilhava no celular: o recado em cima, os botões
   embaixo. Com dois ícones, os dois cabem ao lado do texto — e o que faz caber é
   o texto ceder, e não a ação encolher. Sem isso, um recado comprido (o gol com
   assistência, que é a linha mais longa do produto) espremia as duas ações até
   elas quebrarem uma embaixo da outra, que é exatamente o desenho que saiu.
   --------------------------------------------------------------------------- */
.evento-acoes {
  flex: 0 0 auto;
}

.texto-do-evento {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------------------
   Botão de ação: o ícone e o nome, no mesmo botão (FSD §14.6)

   O ícone é atalho de quem já conhece a tela, não substituto da palavra: o nome
   vai escrito dentro do botão, e o desenho fica ao lado dele. O `gap` é o que
   separa os dois — sem ele o desenho encosta na primeira letra. O `flex` é o que
   alinha o par no meio do botão, inclusive quando o nome quebra em duas linhas.
   --------------------------------------------------------------------------- */
.btn-acao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  line-height: 1;
}

.btn-acao > i {
  /* O desenho não encolhe quando o botão é estreito: quem cede largura é o
     nome, que quebra em duas linhas. Nenhum botão esconde o rótulo (§14.6). */
  flex: 0 0 auto;
}

/* O número da posição é lido de relance e não pode dançar: algarismo de largura
   fixa, alinhado à direita para as dezenas não empurrarem o nome. */
.ordem {
  display: inline-block;
  min-width: 1.25rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

/* Rodapé. Fica no fluxo, no fim do conteúdo, e **não encolhe**: `flex: 0 0 auto`
   dentro da coluna da página garante que ele apareça inteiro, e não espremido,
   quando a janela é baixa. Era fixo no pé da janela por um teste de altura do
   documento (≤ 2000px) escrito em JS, o que fazia o mesmo elemento mudar de
   comportamento conforme o tamanho da página — e, no celular deitado, consumia
   8% da altura útil com uma linha de copyright. */
.my-footer {
  clear: both;
  flex: 0 0 auto;
  padding: 0;
  text-align: center;
  vertical-align: middle;
  line-height: normal;
  margin: 0;
  width: 100%;
}

/* Estatuto do grupo: o texto digitado é preservado como o grupo escreveu,
   então as quebras de linha dele precisam aparecer na leitura. */
.estatuto-texto {
  white-space: pre-line;
  max-height: 20rem;
  overflow-y: auto;
}

/* A postagem do feed preserva as quebras de linha de quem escreveu, sem o
   teto de altura do estatuto: o texto é curto por natureza (até 500
   caracteres). */
.post-texto {
  white-space: pre-line;
}

/* ---------------------------------------------------------------------------
   Contenção de rolagem: o contêiner de rolagem tem de ser a caixa de contenção

   O `.visually-hidden` do Bootstrap é `position: absolute`. Um elemento assim só
   é recortado pelo contêiner de rolagem se esse contêiner também for a **caixa de
   contenção** dele, e um `overflow` num ancestral `static` não é: o absoluto
   escapa do recorte e vai parar onde ninguém mandou.

   Foi o que aconteceu no histórico e no ranking. O nome acessível do botão "Ver a
   pelada" é um `visually-hidden` dentro da última célula da tabela; ele escapava
   do `.table-responsive` e caía em x=439, alargando a **página** para 440 px num
   telefone de 390 px. O sintoma não parecia ser da tabela: era rolagem lateral na
   página inteira, com o cabeçalho fixo desalinhado do conteúdo, e a impressão de
   que a tabela não rolava quando ela rolava.

   Com `position: relative` o contêiner passa a ser a caixa de contenção, e o
   recorte vale para tudo o que está dentro dele, absoluto inclusive.
   --------------------------------------------------------------------------- */
.table-responsive,
.my-footer,
.estatuto-texto {
  position: relative;
}

/* ---------------------------------------------------------------------------
   Elenco: a linha fecha e a ficha abre (FSD §14.10)

   O grupo de 20 atletas era uma página de 20 fichas abertas, com quatro campos
   cada: quem procurava um nome lia o elenco inteiro para achar a linha. Fechado,
   a lista é uma lista — nome e selos —, e a ficha abre no toque de quem precisa.

   O cabeçalho é um `button` que ocupa a linha inteira: é o que dá o alvo de
   dedo sem inventar um `div` clicável, que o teclado não alcança.
   --------------------------------------------------------------------------- */
/* **O cabeçalho de coluna que explica o campo é clicável** (pedido): o `title`
   respondia só no *hover*, que não existe no dedo. O que ele ganha é o cursor e
   o sublinhado pontilhado — o mesmo sinal de "isto explica algo" que o produto já
   usa —, sem virar uma caixa que compete com o nome da coluna. */
table th.th-ajuda {
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 0.2em;
}

table th.th-ajuda:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* **A linha inteira é o botão que abre a ficha** (pedido): o nome, a capacidade
   e os selos vivem dentro do próprio `<button>` — o toque em qualquer parte da
   linha abre o modal, e não só num botão estreito no fim dela. */
.elenco-item {
  display: flex;
  /* **A linha quebra em vez de empurrar a tela.** Medido em 320 px: sem o
     `wrap`, a linha com nome, selos de papel e selos de vínculo media mais que
     a tela de 320 — e a página inteira passava a rolar de lado, que é o defeito
     de leiaute que o `flex-wrap` evita. Com ele, o selo desce para a linha de
     baixo quando não cabe, e o nome deixa de ser espremido entre eles. */
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
}

/* **O `<button>` da linha não parece um botão do navegador** (pedido): sem
   borda, sem fundo e com o texto alinhado à esquerda, ele herda só o
   `.elenco-item` — o que diz que ali se clica é o cursor e o realce no toque e
   no foco, e não uma caixa em volta da linha inteira. */
.elenco-item-cartao {
  width: 100%;
  border: 0;
  background: none;
  margin: 0;
  text-align: left;
  color: inherit;
  font: inherit;
  cursor: pointer;
  border-radius: var(--border-radius-sm);
}

.elenco-item-cartao:hover {
  background: var(--color-bg-base);
}

.elenco-item-cartao:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* **O nome e os selos dividem a linha; a ação fica com o lugar dela.** Nome e
   selos crescem e quebram entre si (`min-width: 0` deixa o bloco encolher), e o
   botão da ficha não encolhe nem é invadido: quando os selos não cabem ao lado
   dele, eles descem para a linha de baixo. */
.elenco-item > .elenco-nome {
  flex: 0 1 auto;
}

/* **O nome e, abaixo, as estrelas do atleta** (pedido): a coluna é uma só, para
   o par descer junto e os selos continuarem na mesma linha do nome. `min-width:
   0` faz o nome truncar em vez de empurrar a linha — a mesma régua do
   `.elenco-nome`. */
.elenco-identidade {
  display: flex;
  flex-direction: column;
  flex: 0 1 auto;
  min-width: 0;
  gap: 0.1rem;
}

/* **A capacidade em desenho** (pedido): cinco estrelas e um diamante, dourados,
   na mesma linha. O ouro é o token do pódio (`--color-medal-gold`), que já é o
   tom da conquista no produto — a capacidade do atleta é a mesma linguagem.
   As figuras são só leitura: o nome acessível está no `aria-label` do bloco. */
.habilidades {
  display: inline-flex;
  align-items: center;
  gap: 0.1rem;
  color: var(--color-medal-gold);
  font-size: 0.8rem;
  line-height: 1;
}

/* O diamante ganha um respiro do último grupo de estrelas: ele é outro eixo, e
   encostado na quinta estrela leria como uma sexta nota da mesma escala. */
.habilidades-diamante {
  margin-left: 0.15rem;
}

.elenco-selos {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  min-width: 0;
}

/* **A ação é uma coluna só dela** (pedido): o botão da ficha ocupa a **altura da
   linha**, e a coluna é delimitada por uma borda **invisível** — o que separa é o
   respiro, e não um traço. `align-self: stretch` faz a coluna acompanhar a altura
   da linha (o `.elenco-item` centra os itens) e o botão estica com ela; sem isso o
   botão boiava no meio de uma linha alta, com o desenho menor que o alvo. */
.elenco-acao {
  flex: 0 0 auto;
  display: flex;
  align-self: stretch;
  align-items: stretch;
  margin-left: auto;
  padding-left: 0.5rem;
  border-left: 1px solid transparent;
}

/* **Sem a linha entre um atleta e o outro** (pedido): o `list-group-flush` do
   Bootstrap desenha uma borda embaixo de cada item, e numa lista de nomes ela vira
   uma régua por linha — o que se lê ali é a lista, não as divisões. O respiro de
   cada linha já separa o bastante, e o cabeçalho do bloco continua com o traço
   dele. */
.elenco-lista > .list-group-item {
  border: 0;
}

/* **O selo do elenco é menor que o do resto do produto.** Numa linha cabem até
   cinco deles (papel, vínculo, goleiro, arquivado, nome repetido), e no tamanho
   padrão do Bootstrap a linha vira uma fileira de caixas que empurra o nome e o
   botão. Menor, ele continua legível — 0.7rem é o piso do rótulo curto — e
   devolve a largura para quem importa. */
.elenco-selos .badge {
  font-size: 0.7rem;
  font-weight: 500;
  padding: 0.2em 0.45em;
}

/* O nome empurra a seta para a direita e pode truncar: nome de atleta é de 60
   caracteres, e a linha não pode ser empurrada por ele. */
.elenco-nome {
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.elenco-seta {
  margin-left: auto;
  transition: transform 0.15s ease-in-out;
}

/* **A linha do atleta abre o modal, e o bloco abre na lista** (PRD, §9, item
   105): a seta da linha aponta para a direita — o que ela abre vem por cima, e
   não para baixo —, e só a seta do **cabeçalho do bloco** gira para cima quando
   o bloco abre. Antes as duas giravam, e o mesmo desenho dizia duas coisas
   diferentes no mesmo cartão. */
.elenco-grupo[aria-expanded="true"] .elenco-seta {
  transform: rotate(180deg);
}

/* **O cabeçalho de cada recorte do elenco** (PRD, §9, item 96): "Ativos" e
   "Arquivados" abrem e fecham a própria lista, e o desenho é o mesmo da linha do
   atleta — nome à esquerda, selo com o número e a seta que gira —, porque o gesto
   é o mesmo: toque o cabeçalho e o bloco abre. A tarja do vazio e o selo de
   "Arquivado" na linha continuam, mas quem diz o estado agora é o bloco. */
.elenco-grupo {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0 0.25rem;
  border: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  background: none;
  text-align: left;
  color: inherit;
  font-weight: 600;
}

.elenco-grupo:hover,
.elenco-grupo:focus-visible {
  background-color: rgba(0, 0, 0, 0.04);
}

.elenco-grupo[aria-expanded="true"] .elenco-seta {
  transform: rotate(180deg);
}

/* ---------------------------------------------------------------------------
   **O cartão do grupo saiu** (PRD, §9, item 100)

   A tela dos grupos mostrava os grupos em cartões — com o retrato do ranking, a
   sombra sem contorno do item 74 e a alternância com a lista. A lista mostra o
   mesmo (nome com a sede, papel, jogos e atletas) e a visão de cartões saiu com
   ela, junto do `:hover` que subia o cartão e do `.foto-ranking` que ele
   desenhava. O que fica registrado é o motivo de a lista ter vencido: uma vista
   só é uma escolha a menos para quem abre a tela.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   Cronômetro da partida: flutuante, preto e do servidor (PRD, §9, item 58)

   Ele fica **solto sobre a tela** — `position: fixed`, fora do fluxo — porque o
   tempo da partida vale em qualquer aba e o operador precisa vê-lo sem procurar.
   O fundo preto com fonte branca é o que faz o número saltar da página clara, e
   a sombra é o que o separa do conteúdo por baixo.

   A largura é a do conteúdo: o relógio é pequeno, e um cartão de ponta a ponta
   cobriria o campo de quem está olhando a escalação. Recolhido, ele vira uma
   pílula com o tempo à vista — o operador pode tirá-lo da frente sem perder o
   número.
   --------------------------------------------------------------------------- */
.cronometro {
  position: fixed;
  z-index: 1035; /* acima do conteúdo, abaixo dos modais do Bootstrap */
  right: 0.75rem;
  bottom: 0.75rem;
  min-width: 13rem;
  padding: 0.5rem 0.75rem 0.75rem;
  border-radius: 0.75rem;
  background-color: #000;
  color: #fff;
  box-shadow: 0 0.75rem 1.5rem rgba(0, 0, 0, 0.45);
  font-variant-numeric: tabular-nums;
}

/* **O lado é escolha de quem olha**: à direita, ele cobre o canto em que a ação
   principal costuma ficar; à esquerda, o caminho de volta. A escolha é do
   navegador e vale para a próxima visita. */
.cronometro.lado-esquerdo {
  right: auto;
  left: 0.75rem;
}

.cronometro-topo {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.cronometro-titulo {
  flex: 1 1 auto;
  font-size: var(--rb-text-small);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #adb5bd;
}

.cronometro-icone {
  padding: 0 0.25rem;
  border: 0;
  background: none;
  color: #adb5bd;
  font-size: 1.1rem;
  line-height: 1;
}

.cronometro-icone:hover,
.cronometro-icone:focus-visible {
  color: #fff;
}

.cronometro-mostrador {
  display: flex;
  align-items: baseline;
  justify-content: center;
  font-size: 2.25rem;
  font-weight: 700;
  line-height: 1.1;
}

/* A dezena dos milissegundos fica **visível e menor**: ela diz que o relógio
   corre, sem competir com o minuto, que é o número que se lê de longe. */
.cronometro-centesimos {
  font-size: 1rem;
  color: #adb5bd;
  margin-left: 0.15rem;
}

.cronometro-acoes {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.25rem;
}

/* Os três botões são **só ícone** (item 58): é um relógio sobre o campo, e a
   palavra ao lado do desenho ocuparia a tela do jogo. O alvo continua de dedo, e
   o nome vai no `aria-label` e na dica. */
.cronometro-botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 1px solid #495057;
  border-radius: 50%;
  background-color: #212529;
  color: #fff;
  font-size: 1.35rem;
  line-height: 1;
}

.cronometro-botao:hover,
.cronometro-botao:focus-visible {
  background-color: #343a40;
  border-color: #adb5bd;
}

.cronometro-minuto {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  color: #adb5bd;
}

.cronometro-minuto input {
  width: 4.5rem;
  background-color: #212529;
  border-color: #495057;
  color: #fff;
}

.cronometro-aviso {
  margin-top: 0.5rem;
  padding: 0.25rem 0.5rem;
  border-radius: 0.375rem;
  background-color: #ffc107;
  color: #000;
  font-size: var(--rb-text-small);
}

/* Recolhido: fica o **tempo à vista** e os dois botões do topo — é a pílula que
   o operador pode tirar da frente sem perder o número. O que sai são os controles
   e o campo do apito: quem recolheu não está mexendo no relógio. */
.cronometro.recolhido .cronometro-titulo,
.cronometro.recolhido .cronometro-acoes,
.cronometro.recolhido .cronometro-minuto,
.cronometro.recolhido .cronometro-aviso {
  display: none;
}

.cronometro.recolhido {
  min-width: 8rem;
  padding-bottom: 0.5rem;
}

.cronometro.recolhido .cronometro-mostrador {
  font-size: 1.5rem;
}

/* ---------------------------------------------------------------------------
   Menu lateral (FSD §14.8)

   A navegação é uma **gaveta** (`offcanvas` do Bootstrap), e não um dropdown. O
   dropdown crescia para fora da tela com nome de grupo comprido — medido: 29 px
   de vazamento num telefone de 360 — e cabia pouca coisa antes de virar uma
   lista rolável dentro de um menu que já rolava. A gaveta ocupa a altura da
   janela, rola sozinha e fecha no toque fora, no `Esc` e no botão de fechar.
   --------------------------------------------------------------------------- */
.menu-lateral {
  /* A gaveta não toma a tela inteira: ela é navegação, e deixar o conteúdo
     visível atrás é o que faz o toque fora ser um caminho, e não um palpite. */
  --bs-offcanvas-width: min(20rem, 82vw);
}

.menu-lateral .menu-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.5rem;
  border-radius: 0.375rem;
  text-decoration: none;
}

.menu-lateral .menu-item:hover,
.menu-lateral .menu-item:focus-visible {
  background-color: rgba(255, 255, 255, 0.1);
}

/* A tela aberta fica marcada no menu: é o que responde "onde eu estou?" sem
   precisar ler o título. O `aria-current` diz o mesmo ao leitor de tela. */
.menu-lateral .menu-item[aria-current] {
  background-color: rgba(255, 255, 255, 0.16);
  font-weight: 600;
}

/* O rótulo da seção separa blocos dentro da gaveta. */
.menu-lateral .menu-secao {
  margin-top: 1rem;
  padding: 0 0.5rem 0.25rem;
  font-size: var(--rb-text-small);
  text-transform: uppercase;
  color: #adb5bd;
}

/* ---------------------------------------------------------------------------
   Barra do topo: uma linha só, sempre

   A barra é `sticky-top`: ela fica no topo enquanto a página rola e **ocupa o
   próprio espaço** no fluxo — por isso nenhuma tela precisa compensar a altura
   dela, e nenhum conteúdo nasce atrás dela. (Fixa, a altura saía da primeira tela
   e o vão era chutado: 41 px sem conta conectada e 60 px com ela no dedo.)

   Sem `nowrap` o flex do Bootstrap quebrava a linha quando o nome da conta era
   comprido — medido com um nome de 32 caracteres, num telefone de 320 px, a barra
   ia de 41 px para **91 px**, com o botão da conta ocupado por três linhas e a
   marca fora do lugar. O que não cabe passa a truncar, que é o que a marca e o
   nome fazem abaixo.
   --------------------------------------------------------------------------- */
.navbar {
  flex-wrap: nowrap;
  align-items: center;
}

/* As duas faixas laterais medem o **mesmo**: a da direita fica com o que sobra, e
   a busca e a conta continuam encostadas na borda direita.

   A marca vive na faixa da **esquerda** (PRD, §9, item 85). Ela era um bloco
   próprio, centrado, e as duas laterais mediam o mesmo só para manter esse centro
   exato — 43 px de desvio já tinham sido corrigidos por causa disso. Com a marca
   no canto de onde se lê, o centro deixou de ser uma decisão: o que a barra
   precisa é que o nome da conta e a busca fiquem na ponta direita, e que a marca
   fique na ponta esquerda.

   `min-width: 0` é o que permite um item de flex encolher abaixo do próprio
   conteúdo: sem ele o nome comprido empurra a barra em vez de se ajustar. */
.navbar .barra-lado {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  min-width: 0;
}

.navbar .barra-lado-esq {
  justify-content: flex-start;
  /* **A faixa esquerda ganha a altura inteira da fileira** (pedido: o nome do
     grupo do tamanho da barra): o `align-self: stretch` faz a faixa acompanhar
     o item mais alto da linha — hoje o próprio nome do grupo —, em vez de
     ficar do tamanho do seu próprio conteúdo. A marca e o botão de menu
     continuam centrados dentro dela, porque o `align-items: center` de
     `.barra-lado` não muda.

     **Esticar até o padding da `.navbar`, por cima dele, foi cogitado e
     descartado** (margem negativa do tamanho do padding): o truque até
     encosta a faixa na borda exata da barra escura, mas trava a altura num
     valor fixo, calculado **antes** de o nome quebrar linha — e quando o
     nome precisava de duas linhas, a segunda vazava por baixo da barra, sem
     a barra crescer para acompanhar. Sem a margem negativa, a altura da
     faixa (e da barra, com ela) é sempre **a do conteúdo**, e cresce sozinha
     quando o nome quebra (ver `.grupo-na-barra`). */
  align-self: stretch;
}

.navbar .barra-lado-dir {
  justify-content: flex-end;
}

/* **A marca: a logo e o nome, lado a lado e encostados à esquerda.** O vão entre
   os dois é o `gap`, e o respiro à esquerda é o que separa a marca do botão de
   menu — sem ele a logo encosta no ícone e os dois parecem um desenho só. A
   marca é a última a encolher: quem cede largura é o **nome**, que trunca. */
.navbar .marca {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-left: 0.5rem;
  min-width: 0;
}

/* A logo tem altura fixa e largura pelo desenho: ela não estica com a barra nem
   se deforma quando o nome ao lado encolhe. `1.6rem` é o tamanho do nome em
   caixa alta — o par fica com a mesma altura aparente. */
.navbar .marca-logo {
  height: 1.6rem;
  width: auto;
  flex: 0 0 auto;
}

.navbar .marca-nome {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A marca da tela de Entrar (pedido: minimalista, sem a barra do produto —
   referência a facebook.com em tela estreita). Maior que a da barra porque
   aqui ela é a única coisa no topo, e não um item ao lado de outros. */
.entrada-marca {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--color-text-main);
}

.entrada-marca-logo {
  height: 2.75rem;
  width: auto;
}

.entrada-marca-nome {
  font-size: 1.75rem;
  font-weight: 700;
}

/* O carrossel da home (pedido): uma faixa que rola na horizontal sozinha —
   a página, essa, não rola de lado (AGENTS.md, "o que não é defeito": um
   contêiner que rola de propósito, como `.table-responsive`). */
.carrossel-grupos {
  display: flex;
  gap: var(--spacing-md);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--spacing-sm);
}

.carrossel-item {
  flex: 0 0 auto;
  width: 260px;
  scroll-snap-align: start;
}

/* ---------------------------------------------------------------------------
   Os pódios do cartão do grupo (pedido)

   Três listas de três nomes — o ranking, a artilharia e as assistências —, cada
   linha com a medalha da posição, o nome do atleta, o número dele e o **total de
   jogos**. A linha é `flex` e **quebra**: em 320 px o valor desce para baixo do
   nome em vez de empurrar o cartão (AGENTS.md — a linha de lista é o caso que
   mais quebra no telefone).

   O nome **trunca** com reticências: nome de atleta tem 60 caracteres, e o
   cartão tem 260 px. O que cede é o nome, nunca o número — é o número que a
   lista mostra.
   --------------------------------------------------------------------------- */
.podio {
  margin-top: 0.75rem;
}

.podio-titulo {
  margin: 0 0 0.1rem;
  font-size: var(--rb-text-small);
  font-weight: 600;
}

.podio-lista {
  margin: 0;
  padding: 0;
  list-style: none;
}

.podio-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.3rem;
  font-size: var(--rb-text-small);
  line-height: 1.4;
}

.podio-medalha {
  flex: 0 0 auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  font-size: 0.9rem;
}

.podio-nome {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.podio-valor {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--bs-secondary-color);
  white-space: nowrap;
}

/* A cor diz a posição — o desenho é o mesmo nas três. */
.medalha-ouro {
  color: var(--color-medal-gold);
}

.medalha-prata {
  color: var(--color-medal-silver);
}

.medalha-bronze {
  color: var(--color-medal-bronze);
}

/* O menu da conta abre para dentro da tela.

   O Bootstrap posiciona o `.dropdown-menu` com `left: 0`, e o `right: 0%` que a
   barra declara não cancela esse `left`: com os dois eixos presos e `min-width` de
   10 rem, a caixa fica na borda **esquerda** do botão e cresce 160 px para a
   direita. Como o botão fica no fim da barra, o menu saía pela borda da tela —
   medido, 128 px para fora num telefone de 390 px, com o "Sair" fora do alcance do
   dedo. Com `left: auto` quem manda é o `right`, e o menu abre para dentro. */
.navbar .conta-navbar .dropdown-menu {
  left: auto;
  right: 0;
}

/* O menu da barra não alarga a página.

   O `.dropdown-item` do Bootstrap traz `white-space: nowrap`, e o nome de um
   grupo é texto que o usuário digitou: "Especiais FC (Grajaú) Administrador"
   levava o menu a 382 px num telefone de 360 — medido, **29 px de vazamento
   lateral**, com o item fora do alcance do dedo. O teto passa a ser a largura da
   janela, e o nome **quebra** em vez de sair da tela: duas linhas de nome são
   melhores que uma linha cortada, porque é o nome que diz qual grupo escolher. */
.navbar .dropdown-menu {
  max-width: calc(100vw - 1rem);
}

.navbar .dropdown-menu .dropdown-item,
.navbar .dropdown-menu .dropdown-item-text {
  white-space: normal;
}

/* **No item em foco o subtexto acompanha a cor do item** (medido: 2,55:1).

   O subtexto apagado é cinza **do tema**, e o item em foco pinta o próprio fundo
   com o azul do Bootstrap e o texto de branco: o cinza em cima do azul cai para
   menos da metade do contraste da leitura (4,5:1). Quem está em foco é o item
   inteiro — nome e subtexto —, e é a cor do item que vale para os dois. Isto vale
   nos dois temas: o defeito não é do escuro. */
.dropdown-item.active .text-secondary,
.dropdown-item:active .text-secondary,
.dropdown-item.active .text-body-secondary,
.dropdown-item:active .text-body-secondary {
  color: inherit !important;
}

/* ---------------------------------------------------------------------------
   O grupo desta tela, na barra — e os atalhos dele logo abaixo (item 111)

   A marca diz o produto; o **nome do grupo** ao lado dela diz de qual grupo é a
   tela aberta, e o toque nele troca de grupo. Ele não é o `.nav-link` da barra:
   é texto claro sobre o fundo escuro, sem caixa e sem contorno, e quem diz que
   ali se escolhe é a **setinha** do `dropdown-toggle` do Bootstrap.

   O nome do grupo é digitado pelo usuário e cabe em 60 caracteres: em vez de
   cortar com reticências, a linha **quebra** (pedido) — o nome inteiro aparece
   na barra, em vez de truncado. O `max-width` em `vw` é o que dá a largura da
   coluna em que ele quebra, e a barra toda cresce junto quando o nome precisa
   de uma segunda linha.

   **Sem padding, e do tamanho da fileira em que vive** (pedido): o botão não
   tem margem interna — o alvo clicável é a própria caixa esticada por
   `align-self: stretch` (ver `.barra-lado-esq`), do tamanho do item mais alto
   da linha, e o respiro que separa o texto da borda vem só do
   `align-items: center`, que o centra dentro dela.

   O `align-self: stretch` do botão só funciona porque o `[data-troca-de-grupo]`
   logo abaixo vira flex: o botão não é filho direto de `.barra-lado-esq` — o
   macro `troca_de_grupo` embrulha o `<button>` num `<div class="dropdown">`
   (o menu de grupos abre dele), e `align-self` só vale para filho direto de um
   contêiner flex. Sem esse `display: flex` no embrulho, o botão ficava do
   tamanho do próprio texto, porque `align-self: stretch` nele não tinha efeito
   nenhum — o pai não era flex.

   `min-width: 0` é do item de flex: sem ele o nome comprido empurra a barra em
   vez de se ajustar, que é o mesmo motivo do `.barra-lado`. */
.navbar [data-troca-de-grupo] {
  display: flex;
  align-self: stretch;
  min-width: 0;
}

.navbar .grupo-na-barra {
  display: inline-flex;
  align-items: center;
  align-self: stretch;
  margin-left: 0.75rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--bs-light);
  font-weight: 600;
  max-width: 30vw;
  min-width: 0;
  white-space: normal;
  text-decoration: none;
}

.navbar button.grupo-na-barra:hover,
.navbar button.grupo-na-barra:focus-visible {
  color: #fff;
  text-decoration: underline;
}

/* **A faixa dos atalhos**, centrada e alinhada na horizontal: quatro ícones que
   trocam de assunto dentro do mesmo grupo — a tela do grupo, a súmula, o ranking
   e o histórico. Ela é uma faixa própria, e não um item da barra: a barra rola
   com o toque no telefone, e a faixa fica no fluxo, abaixo dela.

   O ícone do atalho é do tamanho da leitura (`1.25rem`) e o alvo tem o piso da
   WCAG 2.2 (2.5.8); no dedo, a régua de toque da faixa `pointer: coarse` leva o
   alvo a 44 px, como os outros. O que está aberto fica **marcado**: o mesmo
   desenho e o mesmo `aria-current` das outras navegações do produto. */
.atalhos-do-grupo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--bs-border-color);
  background: var(--bs-body-bg);
}

.atalhos-do-grupo .atalho {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  min-height: 2rem;
  padding: 0.25rem 0.6rem;
  border-radius: 0.5rem;
  color: var(--bs-secondary-color);
  font-size: 1.25rem;
  line-height: 1;
  text-decoration: none;
}

.atalhos-do-grupo .atalho:hover,
.atalhos-do-grupo .atalho:focus-visible {
  color: var(--bs-body-color);
  background: var(--bs-secondary-bg);
}

.atalhos-do-grupo .atalho-atual {
  color: var(--bs-body-color);
  background: var(--bs-secondary-bg);
}

/* **O nome da conta não aparece na barra, em tela nenhuma** (pedido): o
   caminho para o perfil é o ícone e o menu da conta, que já tem o nome por
   extenso na primeira linha — repetir o nome na barra era redundante na
   tela larga, e no telefone nunca houve espaço para ele (comentário
   abaixo). O `aria-label` do ícone e o `title` continuam dizendo de quem é a
   conta, para quem usa leitor de tela. */
.navbar .nome-conta,
.navbar .nome-conta-link {
  display: none;
}

/* **O botão de revelar a senha mora dentro do campo** (pedido): ele é daquele
   campo, e não da tela — fora dele, o olho fica longe do que ele mostra, e a
   linha ganha mais um alvo para o dedo errar. O campo ganha respiro à direita
   para o texto não passar por baixo do botão, e o botão não tem caixa nem
   contorno: o que se vê é o desenho, como no botão de ajuda (item 99). */
.campo-senha {
  position: relative;
}

.campo-senha .form-control {
  padding-right: 2.75rem;
}

.botao-senha {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--bs-secondary-color);
}

.botao-senha:hover,
.botao-senha:focus-visible {
  color: var(--bs-body-color);
}

/* ---------------------------------------------------------------------------
   O tema escuro (pedido)

   O tema é escolhido na tela de perfil, ou pelo botão de ícone do menu da conta,
   e mora no `<html>` (`data-bs-theme`), escrito por um script que roda **antes da
   primeira pintura** (`template.html`) — aplicar depois deixaria a tela piscar
   clara a cada navegação. O que está aqui é o que o `data-bs-theme` do Bootstrap
   **não** resolve sozinho.

   Três grupos, e o motivo de cada um:

   1. **Os tokens do produto** (`--color-bg-base`, `--color-surface`,
      `--color-text-main`, `--color-text-muted`) ganham valor escuro. Eles são o
      fundo da página, o fundo dos cartões e as duas cores de texto: tudo o que o
      produto pinta passa por eles. O fundo da página fica **mais escuro** que a
      superfície (`#14181C` contra os `#212529` do Bootstrap) para o cartão
      continuar sendo o que está por cima.
   2. **As classes que o Bootstrap não troca sozinho.** O `.text-secondary` é um
      cinza **fixo** (`#6c757d`): 3,5:1 sobre o fundo escuro e 4,37:1 sobre o
      claro — os dois abaixo dos 4,5:1 da leitura. `--bs-secondary-color` já
      troca de valor sozinho com o tema (é do Bootstrap), então a correção vale
      nos dois e fica fora do `[data-bs-theme="dark"]` dos outros dois: o
      `.text-bg-light` é um selo branco e o `.text-bg-dark` sumiria sobre o
      cartão escuro, e esses dois só têm problema no escuro mesmo.
   3. **Os botões** que o produto usa como ação principal. O `.btn-dark` é um
      retângulo `#212529`, exatamente o fundo do cartão no escuro — ele
      desapareceria, sobrando texto solto. No escuro ele **inverte**: fundo claro e
      tinta escura, que é o mesmo contraste que ele tem no claro. O
      `.btn-outline-dark` segue o mesmo caminho.

   Tudo isto vive dentro de `@media screen`: no papel não existe tema escuro, e o
   bloco de impressão (no topo da folha) devolve ao Bootstrap as cores do claro. */
@media screen {
  [data-bs-theme="dark"] {
    --color-bg-base: #14181C;
    --color-surface: #212529;
    --color-text-main: #E9ECEF;
    --color-text-muted: #ADB5BD;
  }

  /* Vale nos dois temas (pedido): `--bs-secondary-color` já é o cinza do
     tema certo em cada um, e o `#6c757d` fixo do Bootstrap não passava no
     claro (4,37:1) nem no escuro (3,5:1). */
  .text-secondary {
    color: var(--bs-secondary-color) !important;
  }

  [data-bs-theme="dark"] .text-bg-light {
    background-color: var(--bs-tertiary-bg) !important;
    color: var(--bs-body-color) !important;
  }

  [data-bs-theme="dark"] .text-bg-dark {
    background-color: var(--bs-light) !important;
    color: var(--bs-dark) !important;
  }

  [data-bs-theme="dark"] .btn-dark {
    --bs-btn-color: #212529;
    --bs-btn-bg: #F8F9FA;
    --bs-btn-border-color: #F8F9FA;
    --bs-btn-hover-color: #000000;
    --bs-btn-hover-bg: #FFFFFF;
    --bs-btn-hover-border-color: #FFFFFF;
    --bs-btn-active-color: #000000;
    --bs-btn-active-bg: #E9ECEF;
    --bs-btn-active-border-color: #E9ECEF;
    --bs-btn-disabled-color: #212529;
    --bs-btn-disabled-bg: #F8F9FA;
    --bs-btn-disabled-border-color: #F8F9FA;
  }

  [data-bs-theme="dark"] .btn-outline-dark {
    --bs-btn-color: #F8F9FA;
    --bs-btn-border-color: #F8F9FA;
    --bs-btn-hover-color: #212529;
    --bs-btn-hover-bg: #F8F9FA;
    --bs-btn-hover-border-color: #F8F9FA;
    --bs-btn-active-color: #212529;
    --bs-btn-active-bg: #E9ECEF;
    --bs-btn-active-border-color: #E9ECEF;
    --bs-btn-disabled-color: #F8F9FA;
    --bs-btn-disabled-border-color: #F8F9FA;
  }

  /* O realce do ponteiro é preto no texto claro (`botao-ajuda`, as setas de
     ordem, o cabeçalho do jogo). No escuro quem realça é a cor de ênfase do
     tema — preta no claro, branca aqui. */
  [data-bs-theme="dark"] .botao-ajuda:hover,
  [data-bs-theme="dark"] .botao-ajuda:focus-visible,
  [data-bs-theme="dark"] .botao-seta:hover,
  [data-bs-theme="dark"] .jogo-cabecalho:hover,
  [data-bs-theme="dark"] .jogo-cabecalho:focus-visible {
    color: var(--bs-emphasis-color);
  }

  /* A marca da troca no quadro da formação é o azul-claro do Bootstrap no tema
     claro. No escuro ele viraria texto escuro sobre azul quase branco: o mesmo
     realce passa a sair das variáveis do tema, que já são o azul do escuro. */
  [data-bs-theme="dark"] .zona-do-quadro li[data-atleta].trocado {
    background-color: var(--bs-primary-bg-subtle);
    color: var(--bs-primary-text-emphasis);
  }
}

/* ---------------------------------------------------------------------------
   **O vermelho de perigo no tema escuro** (medido na conferência do ar)

   No **tema claro** nada muda: o vermelho é o do Bootstrap, como sempre foi — o
   produto é do jeito que estava, e o pedido é que continue assim.

   No **escuro** o `#dc3545` do Bootstrap não serve para texto: em 14 px ele dá
   **3,4:1** sobre o cartão escuro, abaixo dos 4,5:1 da leitura — e o botão cheio
   fica com texto branco sobre um vermelho que some no fundo. As duas correções
   usam o que já existe em vez de inventar cor:

   1. **O texto** (`.text-danger` e a tinta do `.btn-outline-danger`) vem de
      `--bs-danger-text-emphasis`, que o Bootstrap define por tema justamente
      para isto (`#ea868f` no escuro). A borda continua no vermelho do Bootstrap:
      traço é elemento gráfico (o critério pede 3:1) e o que precisava mudar era
      a tinta;
   2. **O botão cheio** (`.btn-danger`) passa a usar o vermelho do produto
      (`--color-danger`, o do cartão vermelho do `DESIGN.md`), que com o texto
      branco dá 5,0:1 — e o escurecimento do ponteiro é o `--color-danger-hover`,
      um token como os das outras cores de marca.

   Os tokens do produto (`--color-danger`, `--color-danger-hover`) são os mesmos
   nos dois temas: só o **tema escuro** troca a tinta do texto. */
@media screen {
  [data-bs-theme="dark"] .text-danger {
    color: var(--bs-danger-text-emphasis) !important;
  }

  [data-bs-theme="dark"] .btn-outline-danger {
    --bs-btn-color: var(--bs-danger-text-emphasis);
    --bs-btn-disabled-color: var(--bs-danger-text-emphasis);
  }

  [data-bs-theme="dark"] .btn-danger {
    --bs-btn-bg: var(--color-danger);
    --bs-btn-border-color: var(--color-danger);
    --bs-btn-hover-bg: var(--color-danger-hover);
    --bs-btn-hover-border-color: var(--color-danger-hover);
    --bs-btn-active-bg: var(--color-danger-hover);
    --bs-btn-active-border-color: var(--color-danger-hover);
    --bs-btn-disabled-bg: var(--color-danger);
    --bs-btn-disabled-border-color: var(--color-danger);
  }
}

/* **O desafio do captcha tem a largura da coluna** (medido: 21 px de rolagem de
   lado a 320 px, com o widget de tamanho fixo do provedor). O `data-size` do
   widget resolve o caso comum; esta linha é o piso — um provedor que desenhe
   mais largo que o contêiner para no cartão em vez de empurrar a página. */
.cf-turnstile,
.h-captcha {
  max-width: 100%;
}

/* ---------------------------------------------------------------------------
   Alvo de toque — pelo PONTEIRO, não pela largura (FSD §14.5)

   A régua olhava só a largura (`max-width: 576px`), e por isso o celular
   deitado (740px) e o tablet (820px) recebiam regra de mouse: no tablet eram 64
   controles abaixo do mínimo, com os botões só de ícone em 22px. Os dois são
   aparelhos de dedo. `pointer: coarse` descreve o dedo; a largura descreve o
   espaço, e o espaço é tratado no bloco de 576px, logo abaixo.

   O mínimo de 44×44 é o que a Apple e o Google pedem para o dedo; o critério
   2.5.8 da WCAG 2.2 (AA) pede 24×24. Os dois cabem aqui.
   --------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   EXPERIMENTO VISUAL: a borda lime (pedido)

   A linha abaixo da navbar, a linha acima do rodapé, a linha à direita da
   gaveta lateral e o contorno dos elementos de fundo escuro usam
   `--color-experimental-lime`. O bloco vive isolado antes das faixas de tela,
   para não sobrescrever os ajustes responsivos: reverter o commit devolve o
   desenho anterior inteiro, e remover o token desliga as regras sem tocar no
   resto do CSS (a declaração com `var()` inexistente é ignorada pelo navegador).

   O contorno é `outline` com `outline-offset: -1px`, e não `border`: borda de
   verdade entraria no fluxo e mudaria a largura/altura de botões, selos e
   cartões — o tipo de mudança que estoura a tela de 320 px. O `outline` fica
   dentro da caixa e não desloca nada.

   **No tema claro**, cada verde ganha um contorno escuro em volta, e a navbar,
   o rodapé e a gaveta mostram o par só no lado pedido (abaixo, acima e à
   direita, respectivamente). **No tema escuro**, a navbar, o rodapé e a gaveta
   ficam só com a verde, e os campos e as superfícies amplas mantêm o contorno
   verde. As tabelas saíram do experimento nos dois temas.
   --------------------------------------------------------------------------- */
.navbar.bg-dark {
  box-shadow: inset 0 -2px 0 var(--color-experimental-lime);
}

/* O rodapé, a navbar e a gaveta lateral têm a linha verde só no lado pedido.
   No tema claro, cada uma ganha o contorno escuro em volta; no escuro, fica só
   a verde. */
.my-footer {
  outline: none;
  box-shadow: inset 0 1px 0 var(--color-experimental-lime);
}

.menu-lateral {
  outline: none;
  box-shadow: inset -1px 0 0 var(--color-experimental-lime);
}

/* **Tema claro:** a tabela sai do experimento; os outros fundos escuros ganham
   a verde com o contorno escuro por fora. A navbar, o rodapé e a gaveta ficam
   de fora porque têm as linhas próprias acima. */
:root:not([data-bs-theme="dark"]) .bg-dark:not(.navbar):not(.my-footer):not(.menu-lateral),
:root:not([data-bs-theme="dark"]) .btn-dark,
:root:not([data-bs-theme="dark"]) .text-bg-dark,
:root:not([data-bs-theme="dark"]) .dropdown-menu[data-bs-theme="dark"],
:root:not([data-bs-theme="dark"]) .offcanvas[data-bs-theme="dark"]:not(.menu-lateral),
:root:not([data-bs-theme="dark"]) .modal-content[data-bs-theme="dark"],
:root:not([data-bs-theme="dark"]) .balao-ajuda,
:root:not([data-bs-theme="dark"]) .menu-evento,
:root:not([data-bs-theme="dark"]) .cronometro,
:root:not([data-bs-theme="dark"]) .cronometro-botao,
:root:not([data-bs-theme="dark"]) .cronometro-minuto input {
  outline: 1px solid var(--color-experimental-lime);
  outline-offset: -1px;
  box-shadow: 0 0 0 1px var(--color-experimental-dark);
}

/* O contorno escuro da navbar (abaixo), do rodapé (acima) e da gaveta
   (direita) também é só do tema claro. */
:root:not([data-bs-theme="dark"]) .navbar.bg-dark {
  box-shadow:
    inset 0 -1px 0 var(--color-experimental-dark),
    inset 0 -3px 0 var(--color-experimental-lime),
    inset 0 -4px 0 var(--color-experimental-dark);
}

:root:not([data-bs-theme="dark"]) .my-footer {
  box-shadow:
    inset 0 1px 0 var(--color-experimental-dark),
    inset 0 2px 0 var(--color-experimental-lime),
    inset 0 3px 0 var(--color-experimental-dark);
}

:root:not([data-bs-theme="dark"]) .menu-lateral {
  box-shadow:
    inset -1px 0 0 var(--color-experimental-dark),
    inset -2px 0 0 var(--color-experimental-lime),
    inset -3px 0 0 var(--color-experimental-dark);
}

/* O balão, o menu de evento e o cronômetro já tinham sombra de profundidade;
   o contorno entra na frente dela, sem apagar o desenho. */
:root:not([data-bs-theme="dark"]) .balao-ajuda,
:root:not([data-bs-theme="dark"]) .menu-evento {
  box-shadow:
    0 0 0 1px var(--color-experimental-dark),
    0 0.35rem 0.9rem rgba(0, 0, 0, 0.35);
}

:root:not([data-bs-theme="dark"]) .cronometro {
  box-shadow:
    0 0 0 1px var(--color-experimental-dark),
    0 0.75rem 1.5rem rgba(0, 0, 0, 0.45);
}

/* **Tema escuro:** o `.card` voltou ao padrão anterior, sem contorno (pedido —
   era verde, saiu). Sobram o modal e o offcanvas; os campos perderam o
   contorno verde antes disso (pedido anterior). A gaveta lateral é a exceção:
   ela mantém a verde só à direita. */
[data-bs-theme="dark"] .modal-content,
[data-bs-theme="dark"] .offcanvas:not(.menu-lateral) {
  outline: 1px solid var(--color-experimental-lime);
  outline-offset: -1px;
}

/* ---------------------------------------------------------------------------
   TEMA DE COR DA EQUIPE (pedido)

   `.equipe-tema` pinta o rótulo da equipe (o `data-equipe-secao="nome"`),
   nunca a borda do `.card`/caixa em volta — ela é content-driven (a cor vem
   da escolha do grupo, não da identidade visual do produto), por isso mora
   em variáveis CSS lidas do `style` inline do elemento (`--tema-*`), e não
   em hexadecimal nesta folha. Sem tema, a classe nem entra — zero efeito.

   **Expande até a borda da caixa, como um `card-header`** (pedido): o
   rótulo era um "chip" do tamanho do próprio nome, flutuando dentro da
   caixa com a folga de sempre ao redor — a margem negativa (`-0.5rem`, o
   mesmo tanto do `.p-2` que todas as caixas de equipe usam) cola as bordas
   do rótulo nas bordas da caixa, e o padding por dentro devolve o respiro
   do texto. O `border-radius` vale só nos dois cantos de cima — embaixo a
   caixa continua reta, como o `card-header` real do Bootstrap, que nunca
   arredonda a borda que divide dele para o corpo.

   **Uma borda só, mais grossa — não duas** (pedido): a secundária marca a
   borda, de uma vez, com o dobro da espessura de uma borda comum, em vez do
   anel duplo de antes (duas linhas finas com um vão entre elas). A
   terciária continua sendo um anel simples, mais para dentro. Os dois
   seguem como `box-shadow` em camadas (a mesma técnica do contorno do
   experimento lima, acima): sem secundária/terciária, a camada
   correspondente colapsa de volta pra principal e fica invisível. */
.equipe-tema {
  display: block;
  margin: -0.5rem -0.5rem 0.5rem;
  padding: 0.375rem 0.5rem;
  background-color: var(--tema-principal);
  color: var(--tema-secundaria, var(--tema-contraste));
  border-top-left-radius: var(--border-radius-sm);
  border-top-right-radius: var(--border-radius-sm);
  box-shadow:
    inset 0 0 0 4px var(--tema-secundaria, var(--tema-principal)),
    inset 0 0 0 6px var(--tema-terciaria, var(--tema-principal));
}

/* O seletor de cor do tema (modal de parâmetros do jogo): a linha do
   dropdown é pintada na própria cor via `style` inline (mesmo argumento do
   `.equipe-tema` acima — conteúdo escolhido pelo grupo, não hex inventado
   nesta folha). O menu rola em vez de estourar a tela de 320 px: a paleta
   tem dezenas de tons, e um modal não cabe uma lista dessa altura inteira. */
.seletor-de-cor-menu {
  max-height: 50vh;
  overflow-y: auto;
}

/* O tom da mesma família escolhida pela outra equipe fica desligado (pedido:
   duas equipes não podem ter a principal na mesma família). `opacity` apaga
   visualmente mesmo por cima do `background-color` inline de cada linha —
   uma regra de classe para `color`/`background-color` perderia para o
   `style` inline, que tem especificidade maior. */
.seletor-de-cor-menu .dropdown-item.disabled,
.seletor-de-cor-menu .dropdown-item:disabled {
  opacity: 0.35;
  pointer-events: none;
}

@media (pointer: coarse) {
  /* -- 1. alvo de toque ------------------------------------------------- */
  /* O mínimo vale para o controle, não para o desenho dele. */
  .btn,
  .form-control,
  .form-select {
    min-height: 44px;
  }

  /* Botões de linha continuam compactos na largura, mas não na altura. */
  .btn-sm {
    min-height: 44px;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }

  /* Botão só de ícone (o detalhe das tabelas, o botão de ajuda e as setas de
     ordem): sem `min-width` ele fica com 35 px de largura, e o polegar erra.

     **A altura entra aqui também** (PRD, §9, item 96): o `.btn-sm` desta faixa
     pedia 44 px, mas o piso de 24 da régua comum tem **duas classes** (`.btn.py-0`)
     e ganhava dele — as setas de ordem ficavam 44 de largura por **24 de altura**
     no dedo, e o alvo quadrado que a régua promete não existia. Medido no
     navegador a 360 px, com toque: 24 px de altura antes, 44 depois.

     A seta de ordem entrou nesta lista quando perdeu a classe do Bootstrap
     (item 104): sem `.btn.py-0` ela cairia no piso de 24 px também no dedo. */
  .btn.py-0,
  .botao-seta {
    min-width: 44px;
    min-height: 44px;
  }

  /* E o campo da presença acompanha a altura do dedo (PRD, §9, item 96): os dois
     ficam com 44 px, e a linha não tem degrau em nenhum ponteiro. */
  .linha-ordem .form-control {
    min-height: 44px;
  }

  /* O detalhe da tabela segue o alvo de toque (item 104); o botão de ajuda,
     não — ele fica do tamanho exato do ícone em qualquer ponteiro (pedido). */
  .botao-detalhe {
    min-width: 44px;
    min-height: 44px;
  }

  /* **O nome do atleta no dedo ganha o piso de 24 px** (PRD, §9, item 112), e só
     ele: o nome é **texto dentro de uma frase** — a lista de quem está em campo —,
     e é essa a exceção que o próprio critério 2.5.8 (AA) abre para alvo em linha.
     Os 44 px do polegar valem para o botão, não para a palavra: um nome por linha
     transformaria a escalação num teclado, e o que se lê ali é a equipe. */
  .nome-evento {
    display: inline-block;
    min-height: 24px;
  }

  /* O botão de ação pode ficar só com o ícone onde o nome não cabe (o `rotulo`
     escondido na faixa de celular): sem `min-width` ele nasce do tamanho do
     desenho, e o polegar erra. */
  .btn-acao {
    min-width: 44px;
    min-height: 44px;
  }

  /* O campo do minuto do apito nasceu com `max-width: 30px`, medida de
     desktop: no celular é alvo pequeno e o iOS dá zoom ao focar. */
  #apito {
    max-width: none;
    min-width: 56px;
  }

  /* Navegação: o menu do topo tinha 24px de altura e as abas do ranking, 37px.
     A **largura** entrou junto: medido a 360 px, o ícone de menu media 23 px e a
     lupa, 16 px — os dois com `p-0`, que tira o respiro lateral e deixa o alvo
     do tamanho do desenho. Altura de dedo com largura de ponteiro continua sendo
     alvo que o polegar erra.

     **A régua não ressuscita alvo escondido** (defeito medido a 320 px com
     toque): o `display: flex` daqui vencia o `display: none` da ligação do nome
     da conta — mesma especificidade, e esta regra vem depois. A barra ia de 60
     para **104 px**, com um alvo vazio de 44×44 em cima do ícone da conta. O
     `:not()` deixa a régua fora do que nasce escondido. */
  .navbar .nav-link:not(.nome-conta-link),
  .nav-pills .nav-link {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
  }

  /* O alvo da matriz de permissões não pode encolher com a coluna. A caixa é
     24×24 (o mínimo do critério 2.5.8), e o dedo pede 44: medido a 360 px, o
     rótulo da caixa — que é o alvo — ficava com **40 px** de largura, porque a
     coluna do papel cedia. Três colunas de papel a 58 px mantêm a tabela dentro
     da tela (medido: 332 px de 360). */
  #tabela_permissoes td.text-center {
    min-width: 58px;
  }

  /* Os atalhos do grupo são o caminho de quem está no dedo: o alvo vira 44 px
     (item 111), como o resto da navegação. O `min-width` entra junto porque a
     largura do ícone é 20 px — alvo de dedo com largura de ponteiro é alvo que o
     polegar erra. */
  .atalhos-do-grupo .atalho,
  .navbar .grupo-na-barra {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
  }

  /* O item do menu da conta e o link do rodapé também são alvo de dedo. O
     "Sair" media **32 px** de altura — ele não é `.nav-link`, então ficava fora
     da régua acima —, e os links do rodapé, 19 px: com o rodapé no pé da tela,
     é ali que o polegar descansa. */
  .navbar .dropdown-menu button,
  .navbar .dropdown-menu .dropdown-item,
  .my-footer a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  /* O seletor de cor do tema de equipe é outra lista de dedo: cada linha é
     um tom da paleta, e a régua de toque vale aqui também. */
  .seletor-de-cor-menu .dropdown-item {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  /* Caixa de seleção: o 1em do Bootstrap dá 16px, abaixo dos 24×24 que o
     critério 2.5.8 (AA) pede. O rótulo continua clicável, e a linha inteira
     fica com o mínimo de toque. */
  .form-check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    padding-left: 0;
  }

  /* O seletor precisa empatar em especificidade com o
     `.form-check .form-check-input` do Bootstrap, que é mais específico do que
     `.form-check-input` e traz `float: left` e `margin-left: -1.5em`. Escrito
     solto, o empate não acontece: o `margin` negativo continua valendo e puxa a
     caixa 24px para fora do cartão — rolagem de lado no celular. */
  .form-check .form-check-input {
    float: none;
    width: 1.5rem;
    height: 1.5rem;
    margin: 0;
  }
}

/* ---------------------------------------------------------------------------
   Faixa de celular (até 576px) — aqui o problema é o espaço, não o ponteiro:
   uma coluna, e nada pode empurrar a página de lado, porque rolagem horizontal
   em campo é clique errado.
   --------------------------------------------------------------------------- */
@media screen and (max-width: 576px) {
  /* -- 1. o cronômetro no dedo ------------------------------------------ */
  /* Ele ocupa a largura da tela menos o respiro: o dedo não acerta três botões
     num cartão estreito, e o relógio é o que se olha de longe. */
  .cronometro {
    right: 0.5rem;
    left: 0.5rem;
    min-width: 0;
  }

  .cronometro.lado-esquerdo {
    left: 0.5rem;
  }

  /* -- 2. legibilidade -------------------------------------------------- */
  /* A legibilidade não se conserta mais aqui: a causa era o
     `* { font-size: small }` da folha, que atingia o `html` e fazia a raiz valer
     13px — nenhuma correção de celular resolvia, porque qualquer tamanho em `rem`
     repetia os 13px. O `*` saiu e a escala do `:root` passou a valer em todas as
     telas; o que sobra nesta faixa é o degrau do título. */

  /* O título desce um degrau: 24px num telefone fazem o cabeçalho competir com
     o nome do grupo e empurram o conteúdo para fora da primeira tela. */
  :root {
    --rb-text-title: 1.25rem;
  }

  /* -- 3. linhas de lista com ação -------------------------------------- */
  /* Texto em cima, ações embaixo: os botões deixam de ser espremidos e passam
     a caber na largura inteira, com quebra quando houver mais de um. */
  .linha-acao {
    flex-direction: column;
    align-items: stretch !important;
    gap: 0.5rem;
  }

  .linha-acao-botoes {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem !important;
    text-align: left !important;
  }

  /* As setas não esticam com a linha. São botões só de desenho, e no eixo cruzado
     quem manda é o `align-items: stretch` do `.linha-acao`: sem isto, a fila de
     espera ficava com uma barra da largura da linha com o desenho no meio,
     enquanto as outras listas mantêm as setas de 44×44 no fim do que se move. */
  .linha-acao > .ordem-setas {
    align-self: flex-start;
  }

  .linha-acao-botoes > .btn {
    flex: 1 1 auto;
  }

  /* Botão só de ícone não cresce: dois deles dividindo a largura da linha
     virariam alvos gigantes de 200 px. Fica no mínimo de toque, e compacto. */
  .linha-acao-botoes > .btn.py-0 {
    flex: 0 0 auto;
  }

  /* -- 4. contenção ----------------------------------------------------- */
  /* Modais ocupam a tela sem vazar para os lados. */
  .modal-dialog {
    margin: 0.5rem;
  }

  /* Cabeçalho de cartão com título e ação em linha: em 360 px o
     `justify-content-between` estourava a largura (a trilha da pelada vazava
     42 px), então o título fica em cima e a ação desce. */
  .card-header.d-flex {
    flex-direction: column;
    align-items: stretch !important;
  }

  /* Formulário de filtro dentro do cabeçalho: ele fica com a largura do cabeçalho.

     Duas armadilhas se somam aqui, e as duas foram medidas no navegador:

     1. `min-width: 0` no campo. Um item de flex nasce com `min-width: auto`, que
        vale o mínimo do conteúdo — e o conteúdo é um `<select>` que se dimensiona
        pela opção mais longa ("game.event.update", 245 px). Sem esta linha o campo
        não encolhe nem com `max-width: 100%`, porque o teto é `100%` de um pai que
        também não encolhia;
     2. `width: 100%` no formulário. O `align-items: stretch` do cabeçalho em
        coluna não esticou este item (medido: 246 px de formulário dentro de um
        cabeçalho de 226 px, com `align-self: auto` e o cabeçalho em `stretch`). Com
        a largura declarada, o formulário passa a medir o conteúdo do cabeçalho —
        194 px — e a página para de vazar.

     O `<select>` corta o texto que não couber, que é como um `select` se comporta. */
  .card-header form.d-flex {
    flex-wrap: wrap;
    width: 100%;
    min-width: 0;
  }

  /* **O `w-auto` é a exceção, e ela tem nome** (PRD, §9, item 131): o
     `form-select` do Bootstrap é `width: 100%`, e a regra do produto é que a
     largura venha **da coluna** — por isso nenhum campo escreve `w-100`, que é o
     padrão. O `w-auto` existe para o único caso em que o campo não ocupa a
     coluna: o **filtro em linha** do histórico, onde ele se dimensiona pelo
     texto da opção escolhida. Aqui ele só ganha o que precisa para não estourar
     a tela: o item de flex nasce com `min-width: auto` (o mínimo do conteúdo), e
     é isso que a primeira linha desarma. */
  .form-select.w-auto,
  .form-control.w-auto {
    min-width: 0;
    max-width: 100%;
  }

  /* As tabelas já rolam dentro de `.table-responsive`; menos respiro na célula
     faz o histórico e o ranking precisarem de menos rolagem lateral. */
  .table > :not(caption) > * > * {
    padding: 0.35rem 0.4rem;
  }

  /* O nome da conta e o link dele já saem escondidos em toda largura (regra
     na base da folha) — nada específico de telefone a repetir aqui. */

  /* **No telefone a marca é a logo, e o nome do grupo fica com o lugar do
     texto** (PRD, §9, item 111). Medido a 360 px com o nome do grupo na barra: a
     faixa da esquerda tem 180 px para o botão de menu (44), a marca e o grupo, e
     o nome do produto truncava até o logo **transbordar** a caixa dele — 26 px de
     desenho numa caixa de 8, por cima do nome do grupo.

     O que sai é o **nome do produto**: a logo continua dizendo de quem é a barra,
     e entre "rolaabola" e o grupo em que se está, quem precisa do lugar é o grupo
     — ele muda de tela para tela. A marca vira `flex: 0 0 auto` porque não sobrou
     texto para truncar: sem isso ela ainda encolheria abaixo do desenho. */
  .navbar .marca-nome {
    display: none;
  }

  .navbar .marca {
    flex: 0 0 auto;
    gap: 0;
    margin-left: 0.35rem;
  }

  /* -- 5. abas ---------------------------------------------------------- */
  /* As abas apertam o respiro lateral onde a largura é escassa.

     Medido a 360 px: os quatro assuntos do grupo somavam **357 px** de pílula num
     espaço útil de 312, e a lista ia para duas linhas — 92 px de altura em vez de
     48, empurrando o conteúdo para baixo sem necessidade.

     A causa é a **largura**, e não o ponteiro: por isso o ajuste vive nesta faixa
     e não na régua de toque. Quem cede é o respiro, e não o alvo — a pílula mais
     estreita ("Sede") fica com 55×44 px, acima do mínimo. */
  .nav-pills .nav-link {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }

  /* **E a barra fica justificada** (PRD, §9, item 112): na largura escassa as
     abas **dividem o espaço** em vez de deixar um vão à direita — é o que faz a
     fileira parecer a barra de abas de uma tela, e não dois ou três botões
     perdidos no começo da linha.

     **Quem cresce é o que sobra, e a conta começa pelo conteúdo** (medido a 320,
     360, 414 e 500 px): a base é **zero**, com o `min-width: auto` do item de flex
     segurando o rótulo inteiro, e é isso que faz a linha caber mais abas em vez de
     esticá-las. Com `flex-basis: auto` — o valor anterior — as abas cresciam até
     encher a linha, e a quinta **não cabia mais**: as cinco do ranking somam 401 px
     de rótulo, e num espaço de 452 px o `auto` esticava as quatro primeiras até
     452 e jogava "Menos vazados" para uma linha só dela, com **226 px** — metade da
     barra, lendo como botão enquanto as quatro de baixo tinham 110.

     O teto de `50%` continua: ele é o que impede a aba sozinha de virar uma faixa
     de ponta a ponta. O `nowrap` é o par do base zero: sem ele o rótulo de duas
     palavras ("Menos vazados") quebraria no meio em vez de segurar a largura
     mínima, e a aba leria como duas linhas de texto. */
  /* **A aba que não coube vai para a fileira de trás** (pedido): a barra quebra
     para **cima**, e não para baixo. O que isso resolve é a leitura: a fileira de
     trás é a que continua, e a da frente — encostada na linha preta — é a que
     começa o conteúdo. Antes, a aba que sobrava caía **depois** da linha, e
     parecia parte do que vem abaixo.

     `wrap-reverse` inverte o empilhamento das linhas: a primeira (as que couberam)
     fica embaixo, e a que sobra sobe. */
  .abas.flex-wrap {
    flex-wrap: wrap-reverse !important;
  }

  .abas .nav-item {
    flex: 1 1 0;
    max-width: 50%;
  }

  /* **Com quatro abas ou mais, a fileira é de três e todas têm a mesma largura**
     (medido a 320, 360, 390, 414 e 500 px): com a barra em duas fileiras de
     tamanhos diferentes, cada aba ficava com a **metade da barra dividida pelo
     número de abas da sua fileira** — 134 px na fileira de duas e 88 px na de
     três, a 320 px. Uma aba 52% mais larga que a vizinha de baixo não lê como a
     mesma barra: lê como botão que sobrou.

     Com o terço fixo, as fileiras passam a ter **o mesmo número de abas** (três),
     e a que sobra — duas, em cinco abas — repete a largura de cima. Quem não cede
     é o rótulo: a base é um terço, mas o `min-width: auto` do item de flex segura
     a palavra inteira, então "Menos vazados" fica com os 113 px que precisa e
     nenhuma aba sai cortada.

     O `flex-grow: 0` é de propósito: crescer é justamente o que esticava a aba
     para preencher a fileira e desmanchava a proporção. O vão que sobra à direita
     fica onde sempre esteve — a barra é uma grade, e a última fileira pode estar
     incompleta.

     A condição é a **quantidade de abas**, e não a largura: com duas ou três abas
     não há fileira incompleta, e a barra continua justificada (`max-width: 50%`).
     Quem não conhece o `:has` — navegador antigo — fica com a barra de antes. */
  .abas:has(.nav-item:nth-child(4)) .nav-item {
    flex: 0 1 calc(33.333% - 0.25rem);
    max-width: none;
  }

  .abas .nav-link {
    text-align: center;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
    white-space: nowrap;
  }

  /* **Quando a barra de abas quebra, a aba que sobra volta para trás** (PRD, §9,
     itens 113, 114 e 115).

     A barra é o que **divide a seção**: as abas que couberam na largura ficam com
     a **base encostada na linha preta** — é o desenho de aba de sempre, e é ele
     que diz onde o conteúdo começa. O que faltava era a aba que **não** coube: ela
     caía numa fileira embaixo das outras, atrás da linha, e ali parecia a aba da
     frente.

     Agora ela **volta para trás**: sobe, fica **flutuando atrás da fileira da
     frente** — a fileira passa 6 px por cima da base dela — e o desenho continua
     sendo o de aba (cantos de cima arredondados, borda em volta, sem base). O que
     mudou foi o **lugar**, e não a forma: nada de aba de cabeça para baixo.

     Para a aba de trás caber, a barra reserva o espaço **em cima**
     (`padding-top`), e o respiro é exatamente a altura da aba menos os 6 px que a
     fileira da frente cobre: assim a aba de trás começa na borda de cima da barra
     e não invade o que está acima dela — a barra encurta, não sobe. A linha preta
     é um `::after` posicionado na base da fileira da frente, e a caixa da barra
     **termina nela**: o conteúdo começa logo abaixo, como numa aba de verdade.

     Quem sabe as medidas é o **navegador** (`iniciarAbasDobradas`, no
     `portal.js`): quais abas sobraram depende da largura e do texto de cada
     rótulo, e a altura da aba muda com o ponteiro (24 a 44 px). Ele mede, marca a
     fileira da frente com `data-aba-linha="1"` e a que sobra com `"2"`, e escreve
     as duas medidas na barra — `--rb-aba-vao` (o respiro de cima) e
     `--rb-aba-linha` (a linha preta). A aba de trás **sai do fluxo**
     (`position: absolute`): presa à borda de cima da barra, ela não empurra mais
     nada, e a barra termina exatamente na linha preta. O desenho só vale quando
     **sobra uma aba só** (`data-abas="dobradas"`): com duas ou três sobrando não
     há um lugar único para guardar tudo atrás, e a barra fica a de sempre. Sem
     JavaScript, ou sem sobra, a barra também é a de sempre. */
  .abas[data-abas="dobradas"] {
    position: relative;
    padding-top: var(--rb-aba-vao, 0);
    border-bottom: 0;
  }

  /* A linha preta atravessa a largura inteira na base da fileira da frente. */
  .abas[data-abas="dobradas"]::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: var(--rb-aba-linha, 0);
    height: 2px;
    background: var(--bs-dark);
  }

  .abas[data-abas="dobradas"] .nav-item,
  .abas[data-abas="varias"] .nav-item {
    position: relative;
  }

  /* Quem encosta na linha preta fica na frente. */
  .abas[data-abas="dobradas"] .nav-item[data-aba-linha="1"],
  .abas[data-abas="varias"] .nav-item[data-aba-linha="1"] {
    z-index: 2;
  }

  /* **A fileira de cima é uma camada atrás** (pedido): quando sobram **duas ou
     mais** abas, a barra fica com duas fileiras cheias e não há um lugar único
     para guardar tudo atrás — não é o caso do desenho dobrado, mas o degrau
     continua valendo. As abas de cima andam um quarto de aba à direita e descem
     2px, com `z-index` menor: a base delas fica por baixo das abas da frente, e
     as duas fileiras leem como duas camadas, e não como duas fileiras soltas.

     O deslocamento é o mesmo do desenho dobrado (`--rb-aba-recuo`, medido no
     `iniciarAbasDobradas`), e o `transform` não mexe no fluxo: nada disto muda a
     altura da barra nem empurra o conteúdo. */
  .abas[data-abas="varias"] .nav-item[data-aba-linha="2"] {
    /* O chão é o vão da grade **mais** os 2px de encosto: só descer 2px deixaria a
       aba de cima 2px **acima** das de baixo, porque o vão da barra é maior que
       isso — medido, 4px. Quem mede é o `iniciarAbasDobradas`. */
    transform: translate(var(--rb-aba-recuo, 0), var(--rb-aba-chao, 6px));
    z-index: 1;
  }

  /* **A aba que sobra fica atrás**: sai do fluxo e sobe até a borda de cima da
     barra — a fileira da frente (que começa no respiro) passa por cima da base
     dela. Fora do fluxo ela não empurra mais nada, e é isso que faz a barra
     terminar na linha preta.

     **A largura é a das abas da frente** (pedido): era `50%`, e a aba de trás
     ficava com o dobro das vizinhas — 226 px contra 110, medido a 500 px —, o que
     lê como botão perdido na fileira de cima, e não como a mesma fileira de abas.
     Quem mede é o `iniciarAbasDobradas` (a média da fileira da frente), e o `50%`
     fica de reserva para o instante antes da medida — sem JavaScript a barra já é
     a de sempre, e o desenho dobrado nem chega a valer.

     O `min-width: min-content` é o que impede o corte: uma aba de trás com a
     palavra mais longa ("Menos vazados") fica com o que precisa, em vez de ser
     espremida na largura da frente. */
  .abas[data-abas="dobradas"] .nav-item[data-aba-linha="2"] {
    position: absolute;
    /* **A camada de trás desce 2px e anda um quarto de aba à direita** (pedido):
       com a base dela fora do lugar e por baixo das abas da frente, a barra lê
       como duas camadas — efeito 3D —, e não como duas fileiras soltas. O `left`
       sai do JS, que é quem mede a largura da aba (`--rb-aba-recuo`); o chão de
       2px é fixo, porque o encosto da fileira da frente é o mesmo em toda tela. */
    top: 2px;
    left: var(--rb-aba-recuo, 0);
    width: var(--rb-aba-largura, 50%);
    min-width: min-content;
    z-index: 1;
  }
}

/* ---------------------------------------------------------------------------
   Tela larga (a partir de 1400px, o `xxl` do Bootstrap)

   Aqui o problema é o inverso do celular: sobra espaço. Duas coisas mudam, e as
   duas foram medidas na infraestrutura real.

   1. O TETO DA PÁGINA. O `.container` do Bootstrap para em 1320px. Num monitor
      de 1920px isso são **300px de margem de cada lado** — 69% de aproveitamento,
      com as listas e as tabelas espremidas no meio de uma área que sobra. O teto
      sobe para `--rb-largura` (1800px, medido: duas colunas de cartão de 854px) e
      o respiro lateral cresce junto, para o conteúdo não encostar na borda da
      janela quando ela é só um pouco maior que o teto.

      **O teto existe de propósito**, e não é uma margem disfarçada: numa tela mais
      larga que ele, é o conteúdo que para de crescer. Um texto de 2.400px de
      largura é ilegível, uma lista de nomes com a ação na outra ponta separa a
      pessoa do botão por um metro, e uma tabela de 20 colunas não fica mais
      legível por ter espaço — fica pior de seguir com o olho. Quem usa a tela
      inteira são os *dados*, e por isso o teto é generoso: 94% num monitor de
      1920px, contra os 69% de antes.

   2. A COLUNA QUE NÃO CRESCE. Duas telas — o perfil e o grupo — põem tudo numa
      coluna de 8/12 (`col-lg-8`), e essa coluna foi pensada para tela de tablet:
      num monitor de 1920px ela deixa o conteúdo em **880px, 46% da tela**. As
      duas são uma pilha de cartões independentes (contatos, nomes, grupos, sede,
      elenco, estatuto, convites), e esticar cada cartão até 1600px não serve — um
      formulário de três campos numa faixa de 1600px lê como vazio, e uma lista de
      nomes com o botão na outra ponta fica com 1400px entre a pessoa e a ação.
      O que resolve é **deixar os cartões fluírem em duas colunas**, cada um com a
      largura de leitura de sempre.

   **Por que `columns` e não uma grade**, que foi a primeira tentativa e foi
   medida antes de ficar: uma grade de duas colunas preenche por **linha**, e uma
   linha com um cartão alto e outro baixo deixa a coluna curta vazia até o fim do
   cartão alto. Na tela do grupo, cujos cartões são Sede (194), Elenco (1172) e
   Estatuto (1063), a grade põe Sede e Elenco na primeira linha — 1172 de altura —
   e o Estatuto sozinho embaixo da Sede: a página ia a **2339px** contra os
   **1469px** do fluxo em colunas. O `columns` preenche por **coluna** e equilibra
   a altura das duas, que é o que interessa numa pilha de cartões. O preço é a
   leitura ser "coluna de cima a baixo, depois a outra", o que aqui não confunde:
   são cartões independentes, na ordem em que já se liam.

   O que **não** muda: título de tela e aviso atravessam as duas colunas
   (`column-span: all`), porque são da tela, e não de um cartão; e um cartão nunca
   é partido entre as duas colunas (`break-inside: avoid`) — meio formulário em
   cada lado seria pior que a margem larga.
   --------------------------------------------------------------------------- */
@media (min-width: 1400px) {
  .container-fluid .container {
    max-width: var(--rb-largura);
    padding-left: 2rem;
    padding-right: 2rem;
  }

  /* A coluna de leitura passa a ocupar a página inteira; quem limita o que
     aparece é o cartão, e não a coluna. */
  .tela-larga {
    width: 100%;
    max-width: none;
  }

  /* A pilha de cartões vira duas colunas equilibradas. */
  .cartoes {
    columns: 2;
    column-gap: 1.75rem;
  }

  .cartoes > * {
    break-inside: avoid;
  }

  /* Título da tela e recado geral são da tela, não de um cartão: atravessam. */
  .cartoes > .cartao-largo {
    column-span: all;
  }

  /* O texto corrido não acompanha a largura da coluna.

     Usar a tela toda é bom para tabela, lista e campo — e ruim para parágrafo:
     acima de ~90 caracteres por linha o olho perde o começo da linha seguinte.
     O estatuto é o único texto longo do produto (o grupo escreve o que quiser,
     até 20.000 caracteres), então é ele que leva a medida de leitura; o resto do
     texto já é curto o bastante para caber em qualquer coluna. */
  .estatuto-texto {
    max-width: 80ch;
  }
}

