/* ============================================================================
   GRAVIDADE ZERO · AGENTES DE IA — camada de foco, sub-cards, painel
   ----------------------------------------------------------------------------
   O SUB-CARD FALA COMO MÁQUINA, e isso é a Diretriz, não gosto: ela reserva a
   monoespaçada como "voz de máquina" e define a Lima Ácida #A8C838 como a cor
   de relação no neon. Um agente não é uma pessoa menor — é outra categoria de
   coisa, e o material precisa dizer isso antes de o texto dizer. Daí o
   contraste deliberado com o card de gente: sem vidro, sem acento de setor,
   contorno lima e o selo "AI" em mono.

   A COR DO AGENTE NÃO É A DO SETOR DO DONO, de propósito. Herdar o acento faria
   o agente parecer mais um membro daquele setor — e ele não é membro de nada.
   O que ele herda é o setor NO HOLOGRAMA (js/agentes.js monta a pseudo-pessoa
   com o setor do dono), porque ali o que está em jogo é de quem ele é.

   Lima Ácida sobre o palco #080808 dá 11,4:1 — folga larga para o texto
   pequeno em mono, que é justamente onde o Rosa Spray reprovaria.
   ========================================================================== */

/* ============================================================================
   CAMADA DE FOCO — o segundo estado do card
   ========================================================================== */
.foco{
  position:fixed; inset:0; z-index:40;
  display:grid; place-items:center;
  opacity:0; transition:opacity .28s var(--ease-out);
}
.foco.is-aberta{ opacity:1; }

.foco__veu{
  position:absolute; inset:0;
  background:radial-gradient(120% 100% at 50% 45%, rgba(3,4,10,.72), rgba(3,4,10,.93));
  -webkit-backdrop-filter:blur(9px); backdrop-filter:blur(9px);
}

/* O TETO DE ALTURA E A ROLAGEM entraram quando os agentes por pessoa foram de
   três para até seis (o Julio tem seis; nove pessoas têm cinco). Medido em
   900×640, que é a janela em que o @media lá embaixo empilha card e agentes: o
   palco passou a medir 719px de altura numa tela de 640, e a última fileira de
   sub-cards ficava FORA DA TELA sem nenhum jeito de chegar nela — `.foco` é
   `position:fixed` com `place-items:center`, então não havia rolagem para
   alcançar o que transbordou.
   O limite vai no PALCO e não na coluna de agentes de propósito: no layout
   empilhado quem estoura é a soma (card + duas fileiras), e limitar só a coluna
   deixaria a conta passando do teto de novo. Assim resolve nos dois layouts —
   no de linha o palco nunca chega perto do limite e nada muda. */
.foco__palco{
  position:relative; z-index:1;
  display:flex; align-items:center; justify-content:center;
  gap:clamp(20px, 4vw, 56px);
  padding:var(--gz-space-lg);
  max-width:min(1180px, 94vw);
  /* `scroll-padding-block` pela MESMA razão do `.painel__corpo`, que ganhou o
     dele no FIX-M0.3-e: o `:focus-visible` deste projeto pinta 5px FORA da
     caixa (2px de traço + 3px de offset) e o `overflow-y:auto` daqui recorta na
     caixa de padding. Quando o navegador rola o elemento focado até ENCOSTAR na
     borda, o segmento do anel daquele lado some inteiro.

     Achado pela revisão de UX do FIX-M0.3-h (que mediu −5,7px de folga na base
     ao chegar no sub-card de baixo) e A/B REFEITO contra este próprio arquivo,
     porque o número dela é de outro estado — o anel sorteia quem está na frente
     (D016) e o número de sub-cards muda com a pessoa. Medido em 375×812, mesma
     execução, com e sem esta linha: `scrollTop` **32 → 38** e folga da base
     **−25,03 → −19,16**. O ganho é de **5,87px**, que é exatamente o que os 6px
     prometem — a regra entrega o que diz.

     RESSALVA HONESTA: ela não zera a folga neste estado, e não é para isso que
     está aqui. O que sobra é o palco não caber em 375px, que é o transbordo já
     registrado do Marco 2 e não se resolve com padding de rolagem.

     Pré-existente (idêntico na árvore commitada); entrou aqui porque é o anel de
     foco DESTA camada, que é o assunto daquela correção, e porque o irmão dela
     no mesmo arquivo já tinha o remédio. */
  max-height:100vh; overflow-y:auto; overscroll-behavior:contain;
  scroll-padding-block:6px;
  transform:translateY(10px) scale(.985);
  transition:transform .34s var(--ease-out);
}
.foco.is-aberta .foco__palco{ transform:none; }

.foco__pessoa{ flex:0 0 auto; }
/* dentro do foco o card não flutua: ele foi escolhido e está parado */
.foco__pessoa .card{ animation:none !important; }

/* DOIS BLOCOS EMPILHADOS — "agentes próprios" e "agentes da equipe".
   A coluna deixou de ser um flex-wrap de sub-cards e virou uma pilha de
   seções, cada uma com a sua rubrica e a sua grade. Bloco vazio não é
   desenhado (ver js/agentes.js): cabeçalho sobre o nada promete e não entrega. */
.foco__agentes{
  display:flex; flex-direction:column; align-items:flex-start;
  gap:6px;
  max-width:min(640px, 52vw);
}
.foco__rubrica{
  margin:0; font-family:var(--gz-font-codigo);
  font-size:.6rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--tx-dim);
}
.foco__rubrica + .foco__grade{ margin-bottom:8px; }
.foco__grade{
  display:flex; flex-wrap:wrap; align-items:stretch;
  gap:var(--gz-space-sm);
}
/* O AGENTE DA EQUIPE SE PARECE COM O PRÓPRIO, e a diferença é de um fio só —
   contorno tracejado. É de propósito discreto: ele não é de segunda classe, é
   de outra natureza. Quem diz "de quem é" é a rubrica acima; o tracejado só
   sustenta a leitura quando os dois blocos estão na tela juntos, e é a mesma
   convenção que a Rede já usa para aresta estrutural. */
.subcard--equipe{
  border-style:dashed;
  border-color:rgba(255,255,255,.34);
}
.subcard--equipe:hover, .subcard--equipe:focus-visible{
  border-style:solid;
}
/* OS DOIS ESTADOS VAZIOS DO MÓDULO DIVIDEM UMA REGRA SÓ. `.foco__vazio` é a
   camada de foco ("esta pessoa não tem agente nenhum"); `.painel__vazio` é a
   linha do painel de eleição ("não há proposta a eleger"). Os FATOS são
   diferentes e as frases também — o que é igual é a aparência, e copiar as três
   declarações seria a classe de dívida que este projeto rastreia desde a M2.0.

   NÃO DECLARA PESO, e a ausência é medida. O FIX-M0.3-d chegou a declarar
   `font-weight:400` aqui, citando o FIX-M0.4-e e o FIX-M0.6-c — e a revisão
   derrubou os dois motivos. Primeiro, o herdado nunca foi 200: nenhum ancestral
   destas duas classes declara peso (os quatro `font-weight:200` do repositório
   são `.pop__btn`, `.contagem`, `.chip` e `.cena__setor`), o `body` não declara,
   e `<p>` não tem peso de agente de usuário — o computado já era 400, medido com
   e sem a declaração. Segundo, aqueles dois FIX foram sobre `--gz-font-slab`,
   que é fonte VARIÁVEL com eixo 200–900; aqui a família é `--gz-font-codigo`
   (Menlo/monospace), que não tem face 200 nenhuma. A declaração era inerte e a
   justificativa era falsa. */
.foco__vazio, .painel__vazio{
  font-family:var(--gz-font-codigo); font-size:.72rem;
  color:var(--tx-dim); margin:0;
}

/* O AVISO DE ÓRFÃ NÃO DIVIDE A REGRA DOS ESTADOS VAZIOS, e a primeira versão
   deste conserto dividia — a revisão de UX derrubou, com medida: 13 de 13
   propriedades computadas idênticas entre `.painel__vazio` e `.painel__orfa`,
   os dois empilhados na mesma linha do César, lendo como um bloco só.
   São FATOS DE NATUREZA DIFERENTE: o estado vazio é permanente e é sobre o
   produto ("não há o que eleger aqui"); o aviso é transitório e é sobre os
   DADOS DE QUEM ESTÁ OLHANDO ("a sua escolha foi descartada"). Pintar o
   segundo com a cor do texto inerte de apoio é meio caminho para esconder a
   lacuna, que é justamente o que a D009 proíbe.

   A cor é o token de AVISO do pacote (`--gz-poeira-estrela`), que existia em
   css/tokens.css sem nenhum consumidor no produto. Medido sobre o fundo real
   do painel: **17,87:1**, contra 10,35:1 do `--tx-dim` — os dois passam, e o
   que muda é a hierarquia, não a legibilidade.

   `overflow-wrap` está aqui e não lá porque só este imprime um ID vindo do
   localStorage, que é UMA PALAVRA SÓ, sem espaço. Texto sem espaço não quebra
   sozinho — no FIX-M0.6-a um id assim escondeu 272px de si mesmo pela borda em
   375px, justamente na mensagem que existia para mostrá-lo. */
.painel__orfa, .painel__orfas-resumo{
  font-family:var(--gz-font-codigo); font-size:.72rem;
  color:var(--gz-poeira-estrela); margin:0;
  overflow-wrap:anywhere;
}

/* O TERCEIRO ✕ DA CASA A GANHAR ALVO DE TOQUE, e o último (FIX-M0.3-j). Ele
   media 82,05 × 17px, e os 17 não eram escolha de ninguém: vinham do
   `padding:1px 6px` que o NAVEGADOR põe em todo `<button>`, porque esta regra
   não declarava padding nenhum. É o mesmo diagnóstico do ✕ da cena
   (FIX-M0.4-c/D036) e do ✕ do painel (FIX-M0.3-c) — este ficou de fora das duas
   correções porque nenhuma delas abriu ESTA camada. Agora quem cobra a família
   inteira é uma varredura de fonte, em testes/unidade/foco-fechar.test.js:
   diálogo novo entra nela sozinho.
   AS TRÊS SAÍDAS DA CAMADA são Esc, clique no véu e este ✕. No celular não há
   Esc, e acertar o véu com a camada ocupando a tela inteira é acertar o que
   sobrou — o ✕ é a única saída NOMEADA pelo dedo, e a D024 pôs o celular no
   mesmo nível do desktop.

   O CRESCIMENTO É SÓ VERTICAL, e isso é medida, não economia. A largura já
   passava folgada (82,05 contra o piso de 44), então folga horizontal aqui não
   compraria acessibilidade nenhuma — e custaria caro: em 375px o palco empilha,
   o card da pessoa vai de x=77,5 a x=297,5 enquanto o botão começa em 274,95, e
   cada pixel de largura a mais do botão é um pixel do card coberto. `min-width`
   fica declarado assim mesmo porque é o piso AUDITÁVEL: o número 44 aparece no
   CSS em vez de ser resultado de uma soma que só o navegador faz.

   OS −13,5px SÃO METADE DO CRESCIMENTO, e é isso que segura o glifo: com
   `align-items:center`, `min-height:44px` recentra a linha dentro da caixa
   nova, então a caixa tem de SUBIR (44 − 17) / 2 para o centro do ✕ ficar onde
   estava. Medido no A/B da própria página, nas duas larguras: deslocamento
   (0, 0). O `padding:1px 6px` declarado é exatamente o que o agente de usuário
   dava — o que era acidente virou contrato, e a soma `margin + padding` de cada
   lado horizontal continua valendo os mesmos 6px, que é o que mantém a borda de
   conteúdo (e o glifo) parada.

   O QUE ISTO CUSTA, MEDIDO, porque a D039 já pagou esta conta no ✕ da cena: em
   1280px o alvo novo cobre só o véu (2214 de 2214 pontos da faixa nova), e
   clicar no véu faz o MESMO que o ✕. Em 375px, onde o palco empilha, ele passa
   a cobrir 621 pontos acionáveis do card da pessoa, que hoje abre o holograma —
   e a decisão é ficar com eles, por três razões medidas: os pontos ficam
   colados no glifo (é onde cai quem MIRA o ✕ e erra, e hoje esse erro abre o
   holograma sem querer); o card tem 220 × 306,41px e a faixa perdida tem
   22,55px de largura na borda direita dele; e o caminho explícito, o
   `.pc-cta` "ver holograma", fica 167,38px abaixo da base do botão.
   E O CASO DA D039 NÃO SE REPETE AQUI, mas isso é medida e não intuição, porque
   este palco TAMBÉM rola (`max-height:100vh; overflow-y:auto`, logo acima). A
   revisão de código levantou justamente isso. Medido com o palco no topo, no
   meio e no fim, nas duas orientações: o censo embaixo do botão é IDÊNTICO nas
   três posições (375×812 dá 1012 do card + 2596 do palco; 812×375 dá 3608 de
   véu), e o sub-card mais alto que a rolagem consegue trazer para em 233,7 —
   178,84px abaixo da base do botão. Nenhum sub-card chega debaixo dele em
   posição nenhuma. Na D039 chegavam, e eram o único jeito de abrir aquele
   agente.
   OS NÚMEROS ACIMA SÃO DA CAMADA ASSENTADA, e a ressalva é a armadilha nº 11 do
   ESTADO.md: a entrada é um `scale(.985)`, e medir antes de ela terminar
   devolve o card com 216,7px de largura e um censo de roubo MENOR do que é
   (621 viraram 462 numa leitura por tempo). Espere por condição.
   EM 320px A CONTA É OUTRA, e a revisão de UX mediu: a faixa de sobreposição
   vai de 22,55px para 50,03px e o botão cobre 2200 pontos do card em vez de
   1012 — 3,3% dele. Não há conserto: um alvo de 44px no canto de uma tela de
   320px cobre um card de 220px fixos, dê o que der. Fica registrado no ROADMAP. */
.foco__fechar{
  position:absolute; top:clamp(16px,3vh,28px); right:clamp(18px,3vw,34px); z-index:2;
  background:none; border:none; cursor:pointer;
  font-family:var(--gz-font-codigo); font-size:.7rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--tx-muted);
  display:inline-flex; align-items:center; gap:8px;
  min-width:44px; min-height:44px;
  padding:1px 6px; margin:-13.5px 0;
  transition:color .3s var(--ease-out);
}
.foco__fechar:hover, .foco__fechar:focus-visible{ color:#fff; }
/* O ANEL DE FOCO É DESENHADO POR DENTRO, mesmo remédio da D037 no ✕ da cena e
   pela mesma causa: o alvo cresceu para cima e encostou no teto da janela. O
   `:focus-visible` global (css/estilo.css) desenha com `outline-offset:3px`,
   ou seja PARA FORA.
   E O PIOR CASO NÃO É NENHUMA DAS DUAS LARGURAS DE PRINT: `top` é
   `clamp(16px,3vh,28px)` e vale 24px numa janela de 800 de altura, mas cai no
   piso de 16px em toda janela mais baixa que 533px — o celular DEITADO, que a
   D024 tornou alvo de primeira classe. Lá a caixa começa em 2,5px e o anel de
   +3px nasceria em −2,5px, com a borda de cima fora da tela. Com offset
   negativo ele nasce em 3,5px e ainda ganha de brinde o que a D037 observou:
   passa a contornar o alvo REAL de toque em vez de só o texto. */
.foco__fechar:focus-visible{ outline-offset:-3px; }

/* ============================================================================
   SUB-CARD DE AGENTE
   ========================================================================== */
.subcard{
  /* BRANCO, não mais lima: a diretoria unificou o acento do agente em branco.
     A variável fica com o mesmo nome para não espalhar a troca pelo arquivo. */
  --lima:#FFFFFF;
  position:relative;
  display:flex; flex-direction:column; justify-content:flex-end; gap:4px;
  width:152px; min-height:174px; padding:13px 13px 14px;
  border:1px solid rgba(255,255,255,.42);
  border-radius:14px;
  /* véu de baixo para cima, não preenchimento de volume: o gradiente aqui
     escurece para o texto ler */
  background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(8,8,8,.72));
  color:var(--tx);
  cursor:pointer; text-align:left; overflow:hidden;
  transition:transform .28s var(--ease-out), border-color .28s var(--ease-out),
             box-shadow .28s var(--ease-out);
}
.subcard:hover, .subcard:focus-visible{
  transform:translateY(-5px);
  border-color:rgba(255,255,255,.85);
  box-shadow:0 0 18px rgba(255,255,255,.24);
}

.subcard__marca{
  position:absolute; top:11px; left:13px;
  font-family:var(--gz-font-codigo); font-size:.68rem; letter-spacing:.22em;
  color:var(--lima); opacity:.9;
}
.subcard__nome{
  font-family:var(--gz-font-display); letter-spacing:.03em;
  font-size:1.18rem; line-height:1.05;
}
.subcard__funcao{
  font-family:var(--gz-font-codigo); font-size:.7rem; line-height:1.35;
  letter-spacing:.06em; color:var(--tx-dim);
}
/* Retrato só existe se o agente TIVER um (hoje, só o AIAgent). Entra rebaixado
   e mascarado: o sub-card é um objeto de máquina, e um retrato em cheio o
   faria competir com o card de gente que está do lado. */
.subcard__retrato{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; opacity:.30;
  -webkit-mask:linear-gradient(180deg,#000 0%, transparent 82%);
  mask:linear-gradient(180deg,#000 0%, transparent 82%);
}
.subcard--comFoto .subcard__marca{ text-shadow:0 0 8px rgba(0,0,0,.9); }

/* ============================================================================
   PAINEL DE ELEIÇÃO — 3 propostas por pessoa, 1 eleita
   ========================================================================== */
.painel{ position:fixed; inset:0; z-index:60; display:grid; place-items:center; }
.painel__veu{
  position:absolute; inset:0; background:rgba(3,4,10,.80);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
}
.painel__caixa{
  position:relative; z-index:1;
  display:flex; flex-direction:column;
  width:min(860px, 94vw); max-height:88vh;
  border:1px solid var(--vidro-borda); border-radius:20px;
  background:var(--vidro-bg-forte);
  -webkit-backdrop-filter:blur(var(--vidro-blur)); backdrop-filter:blur(var(--vidro-blur));
}
.painel__topo{
  display:flex; align-items:flex-start; justify-content:space-between; gap:16px;
  padding:18px 22px 14px; border-bottom:1px solid var(--hairline);
}
.painel__titulo{ font-family:var(--gz-font-display); font-size:1.12rem; letter-spacing:.04em; }
.painel__sub{
  font-family:var(--gz-font-codigo); font-size:.62rem; line-height:1.5;
  color:var(--tx-dim); margin-top:4px; max-width:56ch;
}
/* O ALVO DE TOQUE CRESCE PARA FORA, e a receita é a mesma da D036 que o
   `FIX-M0.4-c` derivou para o ✕ da cena: `min-*:44px` engorda a caixa e a
   margem negativa a segura no lugar, para o glifo não andar. Aqui o botão é o
   segundo filho de um `.painel__topo` com `justify-content:space-between` e
   `align-items:flex-start` — sem a margem negativa ele empurraria o bloco de
   título 22,9px para a esquerda e desceria o ✕. Os números vêm de medida: a
   caixa ia de 21,1×24 para 44×44, ou seja +22,9 na largura e +20 na altura, e a
   compensação é metade disso em cada lado. Os 11,46px não são número redondo
   porque a caixa antiga não era: 21,08px = o avanço do glifo (13,08) mais o
   padding de 4 dos dois lados, e (44 − 21,08)/2 = 11,46. Com −11px o A/B na
   própria página acusou o glifo 0,47px à esquerda; com −11,46 ficou em (0,0). */
.painel__fechar{
  background:none; border:none; color:var(--tx-muted); cursor:pointer;
  font-size:1rem; line-height:1;
  display:inline-flex; align-items:center; justify-content:center;
  min-width:44px; min-height:44px;
  padding:4px; margin:-10px -11.46px;
}
/* O TECLADO ACENDE IGUAL AO PONTEIRO, e os dois irmãos desta família já faziam
   isso — `.foco__fechar` e `.cena__fechar` escrevem o mesmo par. Este ficou para
   trás e é o FIX-M0.3-l: quem chegava aqui por Tab via o anel rosa com o glifo
   ainda em `--tx-muted`, ou seja o botão meio aceso.

   `:focus-visible` E NÃO `:focus`, por duas razões conferíveis. O `:focus`
   acenderia no clique de mouse, que é justamente o que o `:hover` já cobre — e
   acenderia também em foco PROGRAMÁTICO, que existe neste mesmo botão: ele é o
   alvo do foco de ENTRADA do painel (js/foco-preso.js), e ali não há teclado
   nenhum envolvido. Acender no `.focus()` de script é dizer "você está aqui"
   para quem não chegou. (Uma versão anterior deste comentário dizia que o
   `:focus` deixaria "o glifo branco preso depois de um clique" — é FALSO neste
   botão: o clique chama `fecharPainel`, que remove o `.painel` inteiro do DOM, e
   não sobra glifo para ficar preso. A revisão de código derrubou.)

   A varredura da família cobra o par em testes/unidade/foco-fechar.test.js —
   e cobra a COR RESOLVIDA, então tokenizar este `#fff` para
   `var(--gz-branco-reserva)` continua passando. Um diálogo novo entra na conta
   sozinho. */
.painel__fechar:hover, .painel__fechar:focus-visible{ color:#fff; }

/* O `scroll-padding-block` existe por causa do ANEL DE FOCO, e o número saiu de
   medida. O anel do projeto é `outline:2px` com `outline-offset:3px`
   (css/estilo.css), ou seja ele desenha até 5px FORA da caixa do botão — e o
   `overflow-y:auto` daqui recorta na caixa de padding. Quando o navegador rola
   o elemento focado até ENCOSTAR na borda do scrollport, o segmento do anel
   daquele lado some inteiro: medido com Tab de verdade, 11 das 70 paradas em
   375px ficavam com o anel decepado (pior folga −5,36px) e 5 em 1280px. Os 6px
   dão folga para os 5px do anel e não mexem em desenho nenhum. */
.painel__corpo{ overflow-y:auto; padding:6px 22px 8px; scroll-padding-block:6px; }
.painel__linha{
  display:flex; align-items:center; gap:16px;
  padding:11px 0; border-bottom:1px solid rgba(255,255,255,.055);
}
.painel__linha:last-child{ border-bottom:none; }
/* o filete de cor é a ÚNICA aparição do acento de setor no painel: serve para
   achar a pessoa na lista, não para classificá-la */
.painel__quem{
  flex:0 0 168px; display:flex; flex-direction:column; gap:2px;
  border-left:3px solid var(--c,#EC008C); padding-left:11px;
}
.painel__quem b{ font-size:.92rem; }
.painel__quem span{ font-size:.68rem; color:var(--tx-dim); line-height:1.25; }

/* `align-items:flex-start` ENTROU COM A REVELAÇÃO, e sem ele os irmãos incham.
   O padrão de um item de flex é `stretch`: quando um botão cresce ao revelar as
   atividades, TODOS os da mesma linha de flex crescem junto e ficam com a caixa
   pela metade vazia. Medido em 1280 com a revelação forçada botão a botão:
   **91 irmãos esticam** sem esta linha, **0** com ela (152 e 0 quando o teto de
   largura sai da conta). No estado final, com uma proposta eleita por pessoa,
   isso ficava permanente — uma caixa cheia ao lado de três caixas altas e vazias,
   que a revisão de UX leu como "carregando" ou "quebrado". */
.painel__opcoes{ display:flex; flex-wrap:wrap; gap:7px; flex:1 1 auto; align-items:flex-start; }
.painel__op{
  display:flex; flex-direction:column; gap:2px;
  padding:7px 11px; min-width:132px;
  border:1px solid var(--vidro-borda); border-radius:11px;
  background:rgba(255,255,255,.035); color:var(--tx-muted);
  cursor:pointer; text-align:left;
  transition:border-color .22s var(--ease-out), color .22s var(--ease-out),
             background .22s var(--ease-out);
}
.painel__op b{ font-size:.78rem; }
.painel__op span{ font-family:var(--gz-font-codigo); font-size:.56rem; letter-spacing:.05em; }

/* ★ AS ATIVIDADES DA PROPOSTA — a terceira linha (FIX-M0.3-i).
   Elas viviam só no atributo `title`, que nenhum navegador mostra no foco de
   teclado. Agora são um nó de verdade, ligado ao botão por `aria-describedby`.

   ESCONDIDA POR PADRÃO, E A CONTA É O MOTIVO: com a linha permanente e o botão
   travado num teto de 216px, o corpo do painel (67 botões, atividades de 110 a
   186 caracteres) vai de 3451px para 8646px em 375px — de 7,5 para 18,7 telas de
   rolagem. Escondida, o repouso fica INTACTO (1636px em 1280 · 3419px em 375,
   os mesmos de antes do conserto), e revelar um botão custa 1731px · 3514px. As
   seis variantes medidas estão em testes/unidade/painel-atividades.test.js.

   ★ `width:0; min-width:100%` É O QUE IMPEDE O BOTÃO DE PISCAR, e nasceu de uma
   REGRESSÃO minha que a revisão de UX pegou. Sem essa trava, a linha revelada
   engorda o botão em até 100px de LARGURA; dentro de um `flex-wrap` isso o faz
   mudar de linha de flex e sair de baixo do ponteiro parado — ele perde o
   `:hover`, encolhe, volta para baixo do ponteiro, expande, e repete a cada
   quadro. Medido, forçando a revelação botão a botão: **10 dos 67 mudavam de
   lugar em 1280 e 19 em 375** (deslocamento de até −463px), e esses eram
   IMPOSSÍVEIS de eleger com mouse ou com o dedo. Com a trava, **0 se movem** nas
   duas larguras e o crescimento de largura é **0**: a caixa do botão continua
   sendo a de repouso e a linha só cresce para baixo. `width:0` zera a
   contribuição dela para a largura intrínseca do botão; `min-width:100%` a faz
   ocupar a largura que o botão já tinha.

   `display:none` E NÃO a técnica de recorte do `.oculto-visual`: aqui o objetivo
   é o inverso do dela. A descrição acessível continua vindo deste nó mesmo
   escondido — nó DIRETAMENTE referenciado por `aria-describedby` é lido ainda
   assim, medido na árvore de acessibilidade do Chrome (`description` = as três
   atividades, com o nó em `display:none`). Já a técnica de recorte deixaria o
   texto no conteúdo do botão, e aí o NOME acessível engordaria com as três
   atividades — que é justamente o que o `aria-labelledby` do JS existe para
   impedir.

   A COR PRÓPRIA VEIO DA REVISÃO DE UX: `.painel__op span` (a regra da linha de
   FUNÇÃO) também alcança este nó, então as duas linhas saíam idênticas — Menlo
   8,96px, mesmo peso, mesma cor — e liam como um parágrafo só. `--tx-dim` dá a
   hierarquia de terceira linha sem perder legibilidade (medido renderizado sobre
   o botão: bem acima do piso de 4,5:1).

   `:focus` e não `:focus-visible`: o segundo é uma heurística do navegador sobre
   "isto veio do teclado", e quem navega com leitor de tela em modo formulário
   move o foco sem passar por ela. Revelar demais aqui não custa nada — a linha
   explica o botão que acabou de receber o foco. */
.painel__op-ativ{
  display:none; width:0; min-width:100%;
  color:var(--tx-dim);
  line-height:var(--gz-leading-corpo); margin-top:var(--gz-space-2xs);
}
.painel__op:hover .painel__op-ativ,
.painel__op:focus .painel__op-ativ,
.painel__op.is-on .painel__op-ativ{ display:block; }

.painel__op:hover{ color:var(--tx); border-color:rgba(255,255,255,.3); }
.painel__op.is-on{
  color:#fff; background:rgba(255,255,255,.10);
  border-color:rgba(255,255,255,.65);
  box-shadow:0 0 14px rgba(255,255,255,.20);
}

.painel__rodape{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:13px 22px 16px; border-top:1px solid var(--hairline);
}
.painel__contador{
  font-family:var(--gz-font-codigo); font-size:.64rem; letter-spacing:.1em;
  color:var(--tx-dim);
}
.painel__contador b{ color:var(--tx); }
.painel__acoes{ display:flex; gap:8px; }
/* `limpar` e `copiar para dados.js` são o alvo mais grave do painel, e a razão é
   comparativa: o ✕ tem Esc e clique no véu, estes dois não têm tecla nem gesto
   nenhum. Ou o dedo acerta o chip, ou não existe como limpar as escolhas nem
   exportar o trecho. Medidos em 30,8px de altura, 13,2px abaixo do piso — e
   aqui não há margem negativa a compensar, porque o rodapé é o fim da caixa e
   crescer para baixo não cobre nada. */
.painel__acoes .chip{ min-width:44px; min-height:44px; justify-content:center; }

/* ---------- chips que a barra de controles ganhou nesta fase -------------- */
.chip--acao{
  color:var(--tx);
  border-color:rgba(255,255,255,.48);
}
.chip--acao:hover:not([disabled]){ box-shadow:0 0 14px rgba(255,255,255,.24); }
.chip--agentes:not(.is-on){ opacity:.6; }

/* com foco ou painel no ar, o palco atrás não recebe ponteiro */
:root.gz-foco .palco, :root.gz-painel .palco{ pointer-events:none; }

/* Dentro da camada de FOCO o card não tem gaveta. A gaveta existe para
   anunciar "esta pessoa tem agentes" antes do clique; aqui os agentes estão
   literalmente do lado, em tamanho cheio. Repetir os nomes num painel que abre
   por cima deles seria a mesma informação duas vezes, uma tapando a outra. */
.foco .card__gaveta{ display:none !important; }

@media (max-width:900px){
  .foco__palco{ flex-direction:column; gap:var(--gz-space-md); }
  .foco__agentes{ max-width:94vw; justify-content:center; }
  .painel__linha{ flex-direction:column; align-items:flex-start; gap:9px; }
  .painel__quem{ flex:0 0 auto; }

  /* O RODAPÉ REFLUI NOS DOIS NÍVEIS, e o segundo é o que a medição acrescentou
     à correção sugerida na revisão. Dar a linha inteira ao grupo de ações não
     resolve: em 375px a linha tem 306,5px e o grupo precisa de 337,7px, porque
     `.chip` é `white-space:nowrap` e os dois chips somados não encolhem. Sem
     `flex-wrap` aqui dentro, o transbordo voltaria — agora de 31,2px — e
     igualmente cortado no meio do rótulo ("COPIAR PARA DA").
     `flex:1 1 auto` é do `.chip--acao` SOZINHO, e a restrição tem motivo: o
     `limpar` apaga as 16 eleições sem confirmação e sem desfazer. Esticando os
     dois, ele ia de 96,88×30,8 para 306,5×44 — 4,5× a área — e ficava com o
     mesmo formato, a mesma largura e a mesma vizinhança do botão primário, a
     8px dele, na zona do polegar. É o irmão exato da armadilha que a trava de
     largura do "copiado ✓" consertou em js/agentes.js: dedo mira o export, pega
     o destrutivo. Esticado fica só o primário; o destrutivo mantém a largura do
     próprio rótulo e continua com os 44px de altura que o piso exige.
     `margin-left:auto` é para a FAIXA DO MEIO, entre ~415 e 539px, onde os dois
     chips já cabem lado a lado mas ainda não cabem na linha do contador: sem
     ele, a linha quebrada resolve para `flex-start` e sobra vazio à direita
     (medido: 5,48px em 414 · 48,72 em 460 · 86,33 em 500 · 122,98 em 539 — e
     430px é a largura de um iPhone 15 Pro Max). É inerte nos outros dois
     regimes, porque lá não sobra espaço livre para distribuir.
     Nada aqui declara `flex-basis:100%` de propósito: isso quebraria a linha do
     rodapé também num painel de 860px, onde sobra espaço. */
  .painel__rodape{ flex-wrap:wrap; }
  .painel__acoes{ flex-wrap:wrap; margin-left:auto; row-gap:12px; }
  .painel__acoes .chip--acao{ flex:1 1 auto; }
}
/* MOVIMENTO REDUZIDO — item 8 do checklist do PADROES, "próprio do projeto e
   não opcional".
   `.painel__op` e `.foco__fechar` ENTRARAM NO FIX-M0.3-i, e os dois estavam de
   fora desde sempre: medido com GZ_REDUZ=1, os 67 botões do painel mantinham
   `transition-duration: 0,22s, 0,22s, 0,22s` sob `prefers-reduced-motion:
   reduce`. A varredura de testes/unidade/painel-atividades.test.js agora reprova
   QUALQUER seletor deste arquivo que declare transição e não apareça aqui — a
   lista à mão é o que deixou estes dois para trás. */
@media (prefers-reduced-motion:reduce){
  .foco, .foco__palco, .subcard, .painel__op, .foco__fechar{ transition:none !important; }
  .foco__palco{ transform:none !important; }
  .subcard:hover, .subcard:focus-visible{ transform:none !important; }
}
