/* ============================================================================
   GRAVIDADE ZERO · COMPONENTES — popover de filtro, caixa de seleção, gaveta
   ----------------------------------------------------------------------------
   Os três nasceram de componentes React que os chefes mandaram como referência
   (Radix Popover + originui/checkbox, e o WorkflowBuilderCard do shadcn). Aqui
   eles são DOM puro, porque este projeto não tem build nem rede em runtime — a
   promessa do README é abrir por duplo clique numa palestra, e uma dependência
   de npm quebraria exatamente isso.

   O QUE FOI PRESERVADO de cada original, e o que foi trocado:

     Popover (Radix)     · a mecânica inteira: trigger com aria-expanded, caixa
                           em role="dialog", Esc fecha, clique fora fecha, foco
                           volta para o trigger, animação de entrada por lado.
                         · trocado: o portal. Radix teleporta a caixa para o
                           <body> para escapar de `overflow`; aqui a caixa PODE
                           ficar ancorada porque nenhum ancestral corta — e
                           ficar ancorada é o que a faz acompanhar o fit-scale
                           de js/app.js. Teleportada, ela apareceria em escala
                           1:1 ao lado de uma barra reduzida a 0,8.

     Checkbox (originui) · o <input> real continua lá, só que fora da tela: é
                           ele que dá teclado, leitor de tela e o form. O que
                           se vê é o irmão .cbx__box, controlado por :checked.

     WorkflowBuilderCard · a gaveta. No original o hover expande uma seção com
                           descrição + badges e o card sobe 6px. Aqui a seção
                           não pode empurrar layout (o card vive num slot de
                           altura fixa dentro do cilindro), então ela é
                           absoluta e desce POR CIMA — mesma leitura, custo
                           zero de reflow.
   ========================================================================== */


/* ============================================================================
   POPOVER
   ========================================================================== */
.pop{ position:relative; display:inline-flex; }

.pop__caixa{
  position:absolute; top:calc(100% + 10px); left:50%;
  z-index:60;
  max-height:min(60vh, 460px);
  /* TETO DE LARGURA — a última rede contra o corte. A ancoragem (js/filtro.js)
     escolhe o lado que cabe; quando NENHUM lado cabe, porque a caixa é mais
     larga que a tela inteira, não há lado a escolher e só o teto resolve. Vale
     em telefone deitado e em projetor com zoom alto.
     O `min-width` TAMBÉM tem que ceder, e isso não é simetria decorativa: no
     CSS o mínimo vence o máximo sempre, então um `min-width:15rem` fixo
     anularia o teto justamente na tela em que ele importa — a caixa continuava
     240px numa viewport de 260 e vazava do mesmo jeito. Os dois pisam no mesmo
     limite. */
  min-width:min(15rem, calc(100vw - 24px));
  max-width:calc(100vw - 24px);
  /* ★ O ROLADOR PRINCIPAL DEIXOU DE SER A CAIXA (FIX-M0.3-q) — quem rola é a
     `.pop__lista`, e o porquê está inteiro no comentário do `.pop__rodape`,
     mais abaixo: um rodapé grudado flutua SOBRE a área rolável, e com os alvos
     em 44px o Tab passou a pousar em controle 100% coberto por ele. Título e
     rodapé são irmãos do rolador, não conteúdo dele.

     ★ MAS A CAIXA CONTINUA PODENDO ROLAR, E ISSO É RESGATE — achado CRÍTICO da
     revisão de código, medido. A primeira versão desta meta pôs `overflow:hidden`
     aqui, e numa janela MUITO baixa isso vira armadilha: título e rodapé são
     `flex:0 0 auto`, então quem cede é só a lista, e quando o teto
     `min(60vh,460px)` fica menor que os dois juntos ela ia a ZERO. Medido na
     árvore de então, estado travado: em 812×260 a lista media **altura 0** —
     nenhuma das cinco áreas visível ou clicável — e em 812×220 o "aplicar"
     terminava **15,1px abaixo** da base da caixa, recortado, sem rolagem
     nenhuma para resgatar. Não é hipótese: zoom de página a 200% (WCAG 1.4.4)
     sobre o celular deitado de 812×375 deixa a altura em ~187px de CSS.
     Com o rodapé fora do `sticky`, esta rolagem é inofensiva — ele não flutua
     mais sobre nada, então nada pode se esconder atrás dele. O que impede a
     sobreposição é o rodapé estar em FLUXO, não a caixa estar travada. */
  display:flex; flex-direction:column;
  overflow-y:auto; overflow-x:hidden;
  /* O RECUO LATERAL MORA NOS FILHOS, e não aqui (FIX-M0.3-q). Quando a
     `.pop__lista` virou rolador, o recorte dela passou a ser a caixa de PADDING
     dela — que era zero. A `.cbx__box` é o primeiro item da linha e nasce
     colada nessa borda, então o anel de `:focus-visible` (`outline:2px` com
     `outline-offset:2px`) tinha **os 4px da esquerda cortados**, e o
     `box-shadow:0 0 12px` da caixinha marcada perdia o halo inteiro daquele
     lado. Medido no PIXEL, nas quatro larguras: na árvore anterior x=559 e 560
     traziam o rosa (236,0,140); com o rolador na lista, fundo chapado.
     Com o recuo nos filhos, o rolador tem 14px de folga de cada lado — a mesma
     que o padding da caixa dava antes — e o anel volta inteiro. */
  padding:14px 0;
  border:1px solid var(--vidro-borda);
  border-radius:16px;
  background:rgba(10,9,16,.92);
  -webkit-backdrop-filter:blur(var(--vidro-blur)) saturate(1.2);
  backdrop-filter:blur(var(--vidro-blur)) saturate(1.2);
  /* Modo B: a Diretriz zera --gz-shadow no escuro e libera glow. A sombra
     preta aqui não é decoração de card, é SEPARAÇÃO — sem ela a caixa de vidro
     encosta no palco de vidro e o olho não acha a borda. */
  box-shadow:0 18px 48px rgba(0,0,0,.62), 0 0 0 1px rgba(255,255,255,.04) inset;
  text-align:left;
  /* estado fechado: a mesma animação do Radix (fade + zoom 95% + slide) */
  opacity:0; transform:translateX(-50%) translateY(-8px) scale(.96);
  transform-origin:top center;
  pointer-events:none;
  transition:opacity .16s var(--ease-out), transform .16s var(--ease-out);
}
.pop.is-aberto .pop__caixa{
  opacity:1; transform:translateX(-50%) translateY(0) scale(1);
  pointer-events:auto;
}
/* OS DOIS LADOS. O padrão é centrado sob o gatilho; quando a caixa não cabe
   centrada, js/filtro.js mede na abertura e põe uma destas duas classes. Elas
   NÃO são escritas à mão em lugar nenhum — a barra de controles já mudou de
   ponta três vezes, e cada vez que o lado foi cravado no código ele envelheceu
   junto com a posição da barra.

   `pop--esq` ancora no canto ESQUERDO do gatilho (a caixa cresce para a
   direita); `pop--dir` ancora no DIREITO (cresce para a esquerda). Em ambas a
   origem do zoom vai para o canto ancorado, senão a animação de entrada nasce
   fora da caixa e ela parece deslizar de lado. */
.pop--esq .pop__caixa{
  left:0; right:auto;
  transform:translateX(0) translateY(-8px) scale(.96);
  transform-origin:top left;
}
.pop--esq.is-aberto .pop__caixa{ transform:translateX(0) translateY(0) scale(1); }
.pop--esq .pop__seta{ left:22px; right:auto; transform:none; }

.pop--dir .pop__caixa{
  left:auto; right:0;
  transform:translateX(0) translateY(-8px) scale(.96);
  transform-origin:top right;
}
.pop--dir.is-aberto .pop__caixa{ transform:translateX(0) translateY(0) scale(1); }
/* a seta acompanha o gatilho, não a caixa: 22px do canto ANCORADO */
.pop--dir .pop__seta{ left:auto; right:22px; transform:none; }

/* a seta some junto com a caixa: ela é filha do transform do pai */
.pop__seta{
  position:absolute; bottom:100%; left:50%; transform:translateX(-50%);
  width:0; height:0;
  border:6px solid transparent;
  border-bottom-color:rgba(10,9,16,.92);
  filter:drop-shadow(0 -1px 0 var(--vidro-borda));
}

/* `flex:0 0 auto` porque a caixa virou uma coluna flex (FIX-M0.3-q): sem ele o
   título é item flexível e ENCOLHE quando a lista pede espaço numa janela
   baixa. Ele é uma linha de 10,56px — encolher aqui é sumir. */
.pop__titulo{
  flex:0 0 auto;
  font-family:var(--gz-font-codigo);
  font-size:.66rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--tx-dim);
  margin:0 14px 11px;
}
/* O VÃO ENTRE AS LINHAS FOI A ZERO, E ISSO É PARTE DO ALVO DE TOQUE
   (FIX-M0.3-q). Ele valia 10px quando a linha media 17 de altura; com a linha
   em 44px (ver `.cbx`, mais abaixo) esses 10px viram ZONA MORTA entre dois
   alvos vizinhos — pixel que parece da lista e não pertence a controle nenhum.
   É o mesmo defeito que o `FIX-M0.6-q` desta sessão mediu em volta do cartão da
   Rede, um nível acima. Com `gap:0` todo pixel da lista pertence a uma linha.

   E O RESPIRO NÃO SE PERDE: ele passa a vir de DENTRO da linha. Com o texto de
   13,44px centrado numa caixa de 44, sobram 15,28px acima e abaixo, contra os
   10 de vão que havia — o branco entre dois rótulos vai de 13,56 para 30,56px.
   A conta também é o que segura o teto da caixa: 5 linhas a 44px com vão de 10
   pediriam 381px de altura contra o `max-height:min(60vh,460px)`; com vão zero
   são 341, e a caixa continua sem rolar em 375×812 e em 1280×800, onde hoje o
   excesso medido é 0. Está preso por teste. */
/* ★ ESTA É A ÚNICA PEÇA QUE ROLA (FIX-M0.3-q). `min-height:0` é obrigatório e
   não é zelo: o padrão de um item flex é `min-height:auto`, que resolve para o
   min-content — a lista se recusaria a encolher abaixo das cinco linhas e quem
   estouraria o teto seria a CAIXA, devolvendo o rodapé para cima do conteúdo.
   É a mesma armadilha que a `FIX-M0.6-p` registrou para `min-width:auto`. */
.pop__lista{
  display:flex; flex-direction:column; gap:0;
  overflow-y:auto; overflow-x:hidden;
  /* O PISO É UMA LINHA INTEIRA, e ele é o outro lado do achado CRÍTICO da
     revisão: sem piso a lista era o único item que cedia e ia a ZERO numa
     janela baixa (medido: altura 0 em 812×260, com as cinco áreas fora de
     alcance). Com 44px ela sempre mostra um alvo inteiro, e o que passar disso
     rola na caixa. Continua PODENDO encolher — `min-height:auto`, o padrão de
     um item flex, é que travaria no min-content das cinco linhas. */
  min-height:44px;
  /* os 14px que saíram da `.pop__caixa`: é a folga que o anel de foco e o halo
     da caixinha marcada precisam para não serem cortados pelo recorte do
     rolador — ver o comentário da caixa */
  padding-inline:14px;
}
.pop__sep{
  height:1px; margin:12px -14px 11px;
  background:var(--hairline);
}
/* O RODAPÉ INTEIRO — nota, separador e ações — FICA COLADO NA BASE QUANDO A
   CAIXA ROLA. Não é enfeite: é conserto de uma regressão medida, em duas
   rodadas.

   PRIMEIRA RODADA. A `.pop__caixa` tem `max-height:min(60vh,460px)`: numa
   janela de 375px de altura (o celular DEITADO) o teto vale 225px, e ali ela já
   rolava 5px ANTES desta meta. A `.pop__nota` do FIX-M0.3-o acrescentou 41px e
   o "aplicar" saía da área visível — o botão ia de `folga +10,5` para `−30,6` e
   o hit-test no pixel dele respondia `SECTION.pc-card`: o dedo que mirasse o
   botão principal acertaria um card atrás. Grudei as AÇÕES.

   SEGUNDA RODADA, e foi a revisão de UX que mediu. Grudar só as ações trocou o
   problema de lugar: no instante em que a trava nasce, com `scrollTop:0`,
   sobravam **9,5px de 31,1** da nota, com `elementFromPoint` no meio dela
   respondendo `DIV.pop__acoes` e o texto fatiado no meio do glifo. Texto
   cortado na horizontal não comunica "há mais abaixo" — comunica quebrado. E
   vale para toda janela mais baixa que ~448px, ou seja **todo celular
   deitado**. Com o rodapé inteiro grudado, a explicação passou a estar sempre
   na tela — e é daí que vem o AGRUPAMENTO, que continua valendo. O GRUDE não:
   ele caiu na rodada seguinte.

   ★ TERCEIRA RODADA, E ELA TIROU O `position:sticky` DAQUI (FIX-M0.3-q). O
   grude resolvia "o aplicar sai de vista" e trazia junto um segundo problema
   que só apareceu quando os alvos cresceram para 44px: um elemento grudado
   FLUTUA SOBRE a área rolável, e o navegador não sabe disso quando rola o foco.
   Medido em 812×375 com Tab de VERDADE, com os alvos já em 44px: a terceira
   parada pousava com 16px atrás do rodapé e a QUARTA com **44 de 44** — o foco
   num controle 100% invisível, `elementFromPoint` no centro dele respondendo
   `DIV.pop__acoes`, e o `scrollTop` ainda em 0, porque geometricamente o alvo
   estava "dentro" do rolador. É a classe do FIX-M0.6-j, nascida aqui.

   AS DUAS SAÍDAS DE ROLAGEM FORAM MEDIDAS E AS DUAS FALHARAM. `scroll-margin`
   no ALVO: **44px de cobertura em TODOS os valores testados** (a altura do
   rodapé e ela mais 8), nos dois estados — o Chrome ignora a margem quando
   decide não rolar. `scroll-padding-bottom` no ROLADOR: funciona, mas o limiar
   que ZERA anda com o estado — **78px** com a nota escondida (rodapé de 70) e
   **140px** com ela visível (rodapé de 113,1). Um número que muda com o
   conteúdo não é piso, é coincidência com data de validade — e a fonte do
   navegador a 200% engorda a nota de novo.

   ENTÃO O ROLADOR MUDOU DE LUGAR, que é a régua do FIX-M0.6-l: **duas caixas em
   fluxo não podem se sobrepor.** Quem rola agora é a `.pop__lista`; o título e
   este rodapé são irmãos dela, fora do rolador. O invariante que o FIX-M0.3-o
   comprou continua de pé com garantia MAIOR — o "aplicar" não sai de vista
   porque ele não rola, ponto — e o alvo que o Tab alcança não pode ficar atrás
   de nada, por construção. Sem número mágico, sem depender do UA.

   A compensação de margem/padding FICA: o pai tem `padding:14px`, e sem ela o
   rodapé não alcançaria as bordas da caixa.

   O FUNDO SÃO TRÊS CAMADAS DA MESMA COR, e a primeira versão tinha UMA — com um
   comentário meu afirmando que 0,92 sobre 0,92 (0,9936) já bastava para ocultar
   o que passa por baixo. **O recorte ampliado em 812×375 me desmentiu: dava
   para LER "palco não pode ficar vazio" atravessando os botões.** Oito por cento
   de um texto que mede 10,36:1 continua legível. Três camadas levam a 0,99949 —
   e a revisão de código mostrou que a justificativa que eu tinha dado para
   manter o rgba É FALSA: 0,99949 deixa passar 0,13/255 por canal, ou seja a
   pilha JÁ é um opaco e apareceria sobre uma estrela igual a um `#0B0911`
   cravado. O rgba fica por consistência de token com a `.pop__caixa`, não por
   preservar translucidez nenhuma.
   ★ E COM O ROLADOR NA LISTA, A RAZÃO DE OCULTAÇÃO ACABOU: nada mais passa por
   baixo deste rodapé. As camadas ficam porque a superfície opaca é o que está
   no ar hoje e trocá-la mexeria no pixel sem pedido de ninguém — a limpeza está
   registrada nas Descobertas do ROADMAP, para a Revisão de Marco triar. */
.pop__rodape{
  flex:0 0 auto;
  /* a margem lateral negativa SAIU junto com o padding lateral da caixa
     (FIX-M0.3-q): sem padding a compensar, ela puxaria o rodapé para fora */
  margin:0 0 -14px; padding:0 14px 14px;
  background-color:rgba(10,9,16,.92);
  background-image:linear-gradient(rgba(10,9,16,.92), rgba(10,9,16,.92)),
                   linear-gradient(rgba(10,9,16,.92), rgba(10,9,16,.92));
}
.pop__acoes{ display:flex; justify-content:space-between; gap:8px; }

/* botões do rodapé do popover — o "aplicar" é o único cheio da peça inteira */
/* O ALVO DE TOQUE CRESCE PARA BAIXO, SEM MARGEM NEGATIVA (FIX-M0.3-q), e é o
   mesmo desenho de `.painel__acoes .chip` em css/agentes.css: aqui o rodapé é o
   FIM da caixa, então crescer não cobre nada que esteja atrás. Medido antes:
   101 × 27,52px, contra os 44 do item 6 do checklist do PADROES.

   O `display:inline-flex` NÃO É ENFEITE — sem ele o `min-height` é uma promessa
   que depende do default do agente de usuário. `<button>` é `inline-block` por
   default, e num inline não-substituído o navegador IGNORA `min-width` e
   `min-height`: uma única linha trocando o display derrubaria os dois alvos com
   o número 44 intacto no arquivo. Declarado, ele é auditável — e o
   `align-items:center` é quem recentra o rótulo na caixa nova, senão o texto
   ficaria pendurado no topo dos 44px.

   `min-width` NÃO ENTRA, e a ausência é medida, não esquecimento: os botões são
   `flex:1 1 0` dentro de uma caixa de 240px, e cada um mede 101px em 320px de
   viewport. Pela conta do `max-width:calc(100vw - 24px)` da caixa, eles só
   cairiam abaixo de 44px numa janela de menos de ~148px — o produto declara
   320px como o menor tamanho. Um `min-width:44px` aqui seria ramo sem
   consequência, que é a régua da M1.4; o teste cobra a largura pela conta. */
.pop__btn{
  flex:1 1 0;
  display:inline-flex; align-items:center; justify-content:center;
  min-height:44px;
  padding:7px 12px;
  border:1px solid var(--vidro-borda);
  border-radius:var(--gz-radius-pill);
  background:rgba(255,255,255,.04);
  font-family:var(--gz-font-slab); font-weight:200;
  font-size:.72rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--tx-muted); line-height:1;
  cursor:pointer;
  transition:color .2s var(--ease-out), border-color .2s var(--ease-out),
             background .2s var(--ease-out), box-shadow .2s var(--ease-out);
}
.pop__btn:hover{ color:var(--tx); border-color:rgba(255,255,255,.34); }
.pop__btn--forte{
  color:#fff;
  border-color:color-mix(in srgb, var(--gz-rosa-spray) 62%, transparent);
  background:color-mix(in srgb, var(--gz-rosa-spray) 18%, transparent);
}
.pop__btn--forte:hover{
  border-color:var(--gz-rosa-spray);
  box-shadow:0 0 16px rgba(236,0,140,.34);
}


/* ============================================================================
   CAIXA DE SELEÇÃO — o <input> real fica; quem aparece é o irmão
   ========================================================================== */
/* A LINHA INTEIRA É O ALVO, E ELA CRESCE DE VERDADE (FIX-M0.3-q). Medida antes:
   210 × 17px, contra os 44 do item 6 do checklist de acessibilidade do PADROES
   — que nomeia "caixas de seleção" com todas as letras. O `<label>` já cobria a
   largura inteira da lista; o que faltava era altura.

   AQUI NÃO ENTRA A MARGEM NEGATIVA da D036, e a diferença é a razão de ela
   existir. Aquela receita serve para alvo ISOLADO num canto (o ✕ da cena, o da
   camada de foco): a caixa cresce para fora e a margem devolve o lugar, porque
   não há vizinho para atropelar. Estas cinco linhas são EMPILHADAS: crescer com
   `padding` + `margin` negativa de 13,5px daria a cada uma um alvo de 44px com
   passo de 17 — três alvos sobrepostos em cada ponto, e o dedo que mirasse
   "Design" pegaria "Liderança". É o mesmo modo de falha que o `FIX-M0.4-c`
   mediu quando o ✕ de 44px passou a roubar 110 pontos da coluna que rola por
   baixo dele. Num empilhamento, alvo de 44px custa 44px de layout.

   `min-height` E NÃO `height`: o rótulo pode quebrar em duas linhas quando a
   fonte do navegador cresce (a caixa tem 210px de conteúdo e "Inovação &
   Aceleração" é o pior caso), e uma altura fixa cortaria o texto em vez de
   ceder. */
.cbx{
  display:flex; align-items:center; gap:10px;
  /* ★ O `position:relative` É QUEM FAZ O TAB ROLAR A LISTA (FIX-M0.3-q), e ele
     nasceu de um defeito medido. Quem recebe o foco é o `.cbx__input`, que é
     `position:absolute` (fora da tela, ver abaixo) — e um absolute se ancora no
     ancestral POSICIONADO mais próximo, que era a `.pop__caixa`. Enquanto a
     caixa era o rolador, isso funcionava por acidente: input e rolagem viviam
     no mesmo elemento. Com o rolador na `.pop__lista`, o input deixou de
     acompanhar a rolagem — e o navegador, vendo o alvo do foco parado dentro da
     área visível, NÃO ROLAVA NADA. Medido em 812×375 com Tab de verdade:
     `scrollTop` em 0 nas sete paradas, com as áreas 3, 4 e 5 recebendo o foco
     28, 72 e 116px FORA do recorte da lista — quem navega por teclado perdia as
     duas últimas áreas. Ancorado na própria linha, o input rola com ela. */
  position:relative;
  min-height:44px;
  cursor:pointer;
  font-family:var(--gz-font-corpo);
  font-size:.84rem; line-height:1.2;
  color:var(--tx-muted);
  transition:color .2s var(--ease-out);
}
.cbx:hover{ color:var(--tx); }
/* fora da tela, NÃO display:none: escondido assim ele continua focável, e é
   o Tab dentro da caixa que faz este popover ser navegável por teclado */
/* ★ ELE OCUPA A LINHA INTEIRA, e isso é o FIX-M0.3-q — era `width:1px;
   height:1px; margin:-1px`, a técnica `.oculto-visual` da casa. O problema não
   é o esconder, é o TAMANHO: quem recebe o foco é este input, e o navegador
   rola para a caixa DELE. Com 1×1px no meio da linha (medido: 21,5px abaixo do
   topo), rolar para o input não traz os 44px do alvo — em 812×375, com Tab de
   verdade, sobravam **14px da 4ª linha fora do recorte** depois que a lista
   passou a rolar por dentro.
   `inset:0` acaba com a divergência em vez de compensá-la com um número: o que
   recebe o foco passa a ter exatamente a caixa do alvo de toque, e a rolagem do
   Tab traz a linha inteira. Medido, a mesma trilha: pior caso fora do recorte
   **14 → 0**, nas sete paradas. A alternativa medida ao lado — `scroll-margin`
   no input — também zera, mas com dois números escolhidos à mão que descolam da
   altura da linha no dia em que ela mudar.
   CONTINUA INVISÍVEL E CONTINUA FOCÁVEL: quem esconde é o `clip-path`, não o
   tamanho, e ele não tira da ordem de tabulação — é o Tab dentro da caixa que
   faz este popover ser navegável por teclado. E não rouba o ponteiro: o Chrome
   respeita `clip-path` no hit-test, medido nas sete paradas (o centro de cada
   linha responde `LABEL.cbx`/`SPAN.cbx__txt`, como antes). O `clip` legado fica
   como rede para quem não tiver `clip-path`. */
.cbx__input{
  position:absolute; inset:0;
  width:auto; height:auto;
  margin:0; padding:0; border:0;
  clip:rect(0 0 0 0); clip-path:inset(50%);
  overflow:hidden; white-space:nowrap;
}
.cbx__box{
  flex:0 0 auto;
  display:grid; place-items:center;
  width:17px; height:17px;
  border:1px solid rgba(255,255,255,.30);
  border-radius:5px;
  background:rgba(255,255,255,.04);
  transition:background .2s var(--ease-out), border-color .2s var(--ease-out),
             box-shadow .2s var(--ease-out);
}
.cbx__box svg{ width:11px; height:11px; opacity:0; transform:scale(.6);
  transition:opacity .16s var(--ease-out), transform .16s var(--ease-out); }
/* marcada: a cor vem do PRÓPRIO setor (--c), não de um roxo genérico de UI.
   É a mesma cor do ponto que o chip antigo carregava, no mesmo lugar da
   leitura — quem já sabia a cor de "Design" continua sabendo. */
.cbx__input:checked + .cbx__box{
  background:var(--c, var(--gz-rosa-spray));
  border-color:var(--c, var(--gz-rosa-spray));
  box-shadow:0 0 12px color-mix(in srgb, var(--c, #EC008C) 55%, transparent);
}
.cbx__input:checked + .cbx__box svg{ opacity:1; transform:scale(1); }
.cbx__input:focus-visible + .cbx__box{
  outline:2px solid var(--gz-rosa-spray); outline-offset:2px;
}
.cbx__input:checked ~ .cbx__txt{ color:var(--rot, var(--tx)); }
/* O ÚLTIMO LIGADO NÃO DESLIGA: um palco vazio não é filtro, é erro de operação
   no meio de uma apresentação. Fica inerte e visível, não some.

   O RÓTULO NÃO É MAIS APAGADO, e isso é o FIX-M0.3-o. A regra daqui era
   `.cbx__input:disabled ~ .cbx__txt{ opacity:.75 }`, e ela era a ÚNICA
   afordância da trava — medido com tools/rampa.js sobre o PNG do produto, fundo
   passado explicitamente: o pico renderizado caía de rgb(241,71,172) para
   rgb(183,55,134) e a razão sobre o fundo rgb(11,9,17) ia de 5,88:1 para
   **3,68:1**, contra o piso de 4,5:1 do PADROES. A WCAG 1.4.3 isenta componente
   inativo, mas esta linha não é decorativa: é a única que informa qual área
   continua ligada.

   A DISTINÇÃO MUDOU DE SUPORTE — saiu do TEXTO e foi para o CONTROLE, onde não
   há piso de contraste de texto a respeitar. A caixinha travada perde o brilho
   colorido da marcada e troca a borda da cor da área por um branco neutro.

   QUEM CARREGA O SIGNIFICADO É A `.pop__nota`, EM PALAVRAS — a caixinha é
   reforço, e esta linha já disse o contrário. Eu tinha escrito que "lado a lado
   com uma marcada normal a diferença é imediata"; a revisão de UX mostrou que
   esse lado a lado é IMPOSSÍVEL: a trava existe se e somente se há exatamente
   UMA marcada, então nunca há uma marcada normal ao lado para comparar. Sozinha,
   numa caixinha de 17px, a diferença é 1px de borda mais clara e a ausência do
   halo — reforço honesto, sustentação nenhuma.

   A CLASSE VEM DO JS, e não de `:has()`. A regra do cursor era
   `.cbx:has(.cbx__input[aria-disabled="true"])`, e `:has()` só chega ao Firefox
   na **121**, contra o piso de Firefox 113 do PADROES: entre as duas versões a
   regra inteira era descartada e a linha travada continuava com cursor de mão,
   prometendo um clique que não acontece. */
.cbx--travada .cbx__box{
  box-shadow:none;
  border-color:rgba(255,255,255,.55);
}
.cbx--travada{ cursor:default; }

/* a nota que explica a trava. Nasce escondida (`hidden`, escrito pelo JS) e só
   aparece no estado em que é verdade — `[hidden]` já é `display:none` pelo
   agente do usuário, e a regra abaixo não o desfaz. */
.pop__nota{
  margin:10px 0 0;
  font-size:.72rem; line-height:1.35;
  color:var(--tx-dim);
}

.cbx__txt{ transition:color .2s var(--ease-out); }

/* o gatilho do filtro carrega o ícone e a contagem do que está ligado */
.chip--filtro .chip__icone{ width:14px; height:14px; flex:0 0 auto; opacity:.8; }
.chip--filtro .chip__contagem{
  font-family:var(--gz-font-codigo); font-size:.62em;
  padding:2px 6px; border-radius:var(--gz-radius-pill);
  background:rgba(255,255,255,.10); color:var(--tx);
  line-height:1;
}
.chip[aria-expanded="true"]{
  color:var(--tx);
  border-color:color-mix(in srgb, var(--gz-rosa-spray) 62%, transparent);
  background:var(--vidro-bg-forte);
}


/* ============================================================================
   GAVETA — o segundo andar do card quando os AGENTES estão ligados
   ----------------------------------------------------------------------------
   Porte do WorkflowBuilderCard: hover levanta o card e revela descrição, tags
   e um rodapé de avatares. Só existe com o interruptor de agentes ligado
   (:root.gz-agentes) e só em card de gente que TEM agente proposto — daí a
   classe .tem-gaveta, posta por js/agentes.js. Card sem agente não ganha um
   painel vazio: painel vazio é pior que painel nenhum.

   A COR É LIMA, não o acento do setor, pelo mesmo motivo do sub-card: agente é
   outra categoria de coisa, e o material diz isso antes do texto.
   ========================================================================== */
.card__gaveta{
  position:absolute; top:calc(100% - 6px); left:50%;
  /* ★ z-index NEGATIVO, e ele é o conserto do FIX-M0.3-t.

     Aqui morava `z-index:7`, e com ele a gaveta era pintada EM CIMA da base do
     anel de foco do card: o anel focado virava um "∩" — três lados e nenhum
     fundo. Medido em 375×812 com movimento reduzido, card focado por Tab de
     verdade e tiro de controle na MESMA carga, a base dava 1,90:1 contra
     1,93:1 do controle — o mesmo dígito, que é a assinatura de "não há anel
     ali". Escondendo só a gaveta, a mesma faixa dava 3,34:1.

     A CAUSA É ORDEM DE PINTURA. O `outline` do card é pintado na fase de "self
     outline" do próprio elemento, que no Blink acontece DEPOIS dos filhos de
     z-index negativo e ANTES dos filhos posicionados de z-index não-negativo.
     Com 7, a gaveta estava do lado de cima dessa fronteira; com -1, do lado de
     baixo.

     E A ESPECIFICAÇÃO AUTORIZA O QUE O BLINK FAZ — não há navegador "correto"
     em que isto não aconteça. O passo 10 do Apêndice E.2 da CSS 2.1 (pintar os
     outlines por último) é CONDICIONAL: ele vale "for implementations that do
     not draw outlines in the steps above". O Blink desenha nos passos acima, o
     que é permitido. Ou seja esta linha não conserta um desvio de ninguém: ela
     tira a gaveta de um lugar em que a ordem de pintura é ambígua por desenho
     da própria spec.

     E É O QUE UMA GAVETA FAZ: `border-top:none`, o `top:calc(100% - 6px)` aqui
     ao lado e o card subindo 6px ao abrir dizem, os três, "esta superfície sai
     de BAIXO do card". Com 7 ela saía de cima, e os 6px de sobreposição eram
     pintados sobre o card — que é justamente por que o card precisa subir.

     O QUE O -1 CUSTA, MEDIDO: a gaveta passa a ser pintada abaixo do
     `.pc-behind` (o brilho rosa do card, `filter:blur(38px)`, aceso justamente
     nos estados em que ela abre). A/B da região da gaveta abaixo do anel: 3,5%
     dos pixels mudaram, delta máximo 15-16 de 255, mediana idêntica. Não é
     inerte — é barato.
     Preso por testes/unidade/anel-foco-gaveta.test.js. */
  z-index:-1;
  width:calc(var(--pc-w, 220px) * 1.06);
  padding:11px 12px 10px;
  border:1px solid rgba(255,255,255,.34);
  border-top:none;
  border-radius:0 0 14px 14px;
  background:linear-gradient(180deg, rgba(20,20,26,.94), rgba(10,10,14,.96));
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  text-align:left;
  /* fechada: altura zero e sem tinta. `grid-template-rows:0fr → 1fr` é o que
     permite animar para altura AUTOMÁTICA sem cravar pixel — o equivalente CSS
     do `height:auto` do framer-motion, que em JS custaria medir cada card. */
  display:grid; grid-template-rows:0fr;
  opacity:0; pointer-events:none;
  transform:translateX(-50%) translateY(-6px);
  transition:grid-template-rows .3s var(--ease-out),
             opacity .22s var(--ease-out),
             transform .3s var(--ease-out),
             padding .3s var(--ease-out);
  padding-top:0; padding-bottom:0;
}
.card__gaveta > .gaveta__miolo{ overflow:hidden; min-height:0; }

:root.gz-agentes .card.tem-gaveta:hover .card__gaveta,
:root.gz-agentes .card.tem-gaveta:focus-visible .card__gaveta,
:root.gz-agentes .card.tem-gaveta.is-tilt .card__gaveta{
  grid-template-rows:1fr;
  opacity:1; transform:translateX(-50%) translateY(0);
  /* ★ O RECUO DE TOPO RESERVA O ALCANCE DO ANEL DE FOCO — 11px de desenho + os
     5px do anel (FIX-M0.3-t). É a MESMA reserva que a tira do celular já faz no
     padding dela (FIX-M0.3-k): onde o anel do card pode ser desenhado, ninguém
     mais escreve.

     Aqui isso era 11px, e 11 era exatamente o número que fazia a primeira linha
     de texto da gaveta começar NA borda de fora do anel — não é coincidência,
     é aritmética: `top` põe a gaveta 6px acima da base do card, o anel vai de
     +2 a +5, e -6 + 11 = +5. Com a gaveta agora ATRÁS do card, o anel passa a
     ser desenhado ali e encostava no texto: medido na faixa vizinha, 1,87:1
     contra 3,21:1 depois de reservar.

     E a reserva paga uma segunda conta, sem custo: em `prefers-reduced-motion`
     o `.pc-card-shell` NÃO sobe (ver o bloco no fim deste arquivo), então a
     gaveta esconde 6px de si atrás do card — o recuo VISÍVEL vira 16-6 = 10px,
     igual ao de baixo. Sem a reserva ele seria 5px contra 10px.

     Os três números (o -6 do `top`, os 11px do `padding` de desenho e o alcance
     2+3 do anel em css/profile-card.css) são amarrados por
     testes/unidade/anel-foco-gaveta.test.js. Mexeu num, o teste cobra o outro. */
  padding-top:16px; padding-bottom:10px;
}
/* o card sobe 6px junto, como no original. Vai no .pc-card-shell e não no
   .card porque o .card carrega a animação de flutuação em gravidade zero —
   um transform aqui a apagaria. */
:root.gz-agentes .card.tem-gaveta:hover .pc-card-shell,
:root.gz-agentes .card.tem-gaveta.is-tilt .pc-card-shell{
  transform:translateY(-6px);
}
.pc-card-shell{ transition:transform .3s var(--ease-out); }

/* enquanto a cena do holograma ou o painel estão no ar, nenhuma gaveta abre */
:root.gz-cena .card__gaveta, :root.gz-foco .palco .card__gaveta{
  opacity:0 !important; grid-template-rows:0fr !important;
}

.gaveta__topo{
  display:flex; align-items:center; gap:7px;
  font-family:var(--gz-font-codigo);
  font-size:.56rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--tx-dim);
}
.gaveta__ponto{
  width:6px; height:6px; border-radius:50%; flex:0 0 auto;
  background:#fff;
  box-shadow:0 0 8px rgba(255,255,255,.8);
}
.gaveta__desc{
  margin:7px 0 0;
  font-size:.68rem; line-height:1.42; color:var(--tx-muted);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden;
}
.gaveta__tags{ display:flex; flex-wrap:wrap; gap:5px; margin-top:9px; }
.gaveta__tag{
  padding:3px 9px;
  border:1px solid rgba(255,255,255,.40);
  border-radius:var(--gz-radius-pill);
  background:rgba(255,255,255,.10);
  font-family:var(--gz-font-codigo);
  font-size:.55rem; letter-spacing:.08em;
  color:#F2F5FB; line-height:1.4;
  white-space:nowrap; max-width:100%;
  overflow:hidden; text-overflow:ellipsis;
}
.gaveta__rodape{
  display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin-top:11px; padding-top:9px;
  border-top:1px solid rgba(255,255,255,.08);
}
/* avatares empilhados com sobreposição, como no original (-space-x-2) */
.gaveta__avatares{ display:flex; }
.gaveta__avatar{
  position:relative;
  width:21px; height:21px; border-radius:50%;
  border:2px solid rgba(8,8,8,.95);
  margin-left:-7px; overflow:hidden; flex:0 0 auto;
  background:rgba(255,255,255,.16);
  display:grid; place-items:center;
  font-family:var(--gz-font-codigo); font-size:.5rem; color:#F2F5FB;
}
.gaveta__avatar:first-child{ margin-left:0; }
/* o retrato cobre a inicial em vez de dividir a caixa com ela: assim `remove()`
   no erro de carga devolve a letra sem nenhum outro ajuste */
.gaveta__avatar img{
  position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover;
}
.gaveta__acoes{ display:flex; }
.gaveta__acao{
  width:21px; height:21px; border-radius:50%;
  border:2px solid rgba(8,8,8,.95);
  margin-left:-7px; flex:0 0 auto;
  display:grid; place-items:center;
  color:#08120A;
}
.gaveta__acao:first-child{ margin-left:0; }
.gaveta__acao svg{ width:10px; height:10px; }

/* ============================================================================
   CARD DE AGENTE — a mesma peça, outra espécie
   ----------------------------------------------------------------------------
   Desde que a diretoria pediu o organograma híbrido, o agente deixou de ser
   anexo de alguém e virou habitante do palco: card próprio, no mesmo anel, na
   mesma pilha, no mesmo leque. A GEOMETRIA é idêntica de propósito — se o card
   de máquina tivesse outro tamanho, a vista teria que saber qual é qual para
   posicionar, e o motor de vistas voltaria a conhecer o conteúdo.
   O que muda é só a PELE: contorno BRANCO, selo "AI" em monoespaçada, sem
   retrato de gente. Branco é a cor de espécie que a diretoria pediu para o
   agente ("os cards dos agentes passam a ser brancos"), no lugar da lima. Não
   herda a cor do dono — herdá-la faria o agente parecer membro daquele setor,
   e ele não é membro de nada; ele pertence a quem o opera.
   ========================================================================== */
.card--agente .pc-inside{
  background-image:linear-gradient(160deg,
    rgba(255,255,255,.14) 0%, rgba(12,12,16,.92) 62%);
}
.card--agente .pc-card{
  border:1px solid rgba(255,255,255,.42);
}
/* o selo: mesma marca "AI" do sub-card, no canto de cima */
.card--agente .pc-card-shell::before{
  content:"AI";
  position:absolute; top:calc(var(--pc-w) * .05); left:calc(var(--pc-w) * .06);
  z-index:7;
  font-family:var(--gz-font-codigo);
  font-size:calc(var(--pc-w) * .05); letter-spacing:.22em;
  color:#fff;
  text-shadow:0 0 8px rgba(0,0,0,.9);
  pointer-events:none;
}
.card--agente .pc-setor{ color:#fff; }
/* nome e cargo do agente perdem o degradê rosa/violeta do card de gente: a
   cor é a informação de espécie, e um agente com nome em rosa leria como gente */
.card--agente .pc-details h3{
  background-image:linear-gradient(to bottom, #ffffff, #cfd6e2);
}
.card--agente .pc-details p{
  background-image:linear-gradient(to bottom, #f4f6fa, #b7becb);
}
.card--agente .pc-cta::before{ color:#fff; }
.card--agente .pc-inicial{
  color:rgba(255,255,255,.32);
  text-shadow:0 0 calc(var(--pc-w) * .10) rgba(255,255,255,.22);
}

@media (prefers-reduced-motion:reduce){
  .pop__caixa, .card__gaveta, .pc-card-shell, .cbx__box, .cbx__box svg{
    transition:none !important;
  }
  :root.gz-agentes .card.tem-gaveta:hover .pc-card-shell,
  :root.gz-agentes .card.tem-gaveta.is-tilt .pc-card-shell{ transform:none; }
}
