/* ═══════════════════════════════════════════════════════════════════
   ROSTER — Componentes do produto · v2
   instrumento: LEI (camada de componentes)
   contexto: produto
   governada_por: TRADUCAO.md · valores: tokens.css (nada aqui escreve hex, px de raio ou sombra)
   versao: 0.1 · 2026-09-03
   Cada bloco cita a regra que executa (← U-nn).
   ═══════════════════════════════════════════════════════════════════ */

*{box-sizing:border-box;margin:0;padding:0}
html{background:var(--canvas)}
body{
  background:var(--canvas);color:var(--ink);
  font-family:var(--sans);font-size:var(--text-body);line-height:var(--lead-body);
  font-weight:var(--weight-body);-webkit-font-smoothing:antialiased;
  font-feature-settings:'tnum' 1,'cv05' 1; /* ← U-11 */
}
strong,b{font-weight:var(--weight-strong)}
em,i{font-style:italic} /* ← U-09 */
a{color:var(--ink);text-decoration:underline;text-underline-offset:2px;text-decoration-color:var(--line-mid)}
a:hover{text-decoration-color:var(--ink)} /* ← U-37 */
code{font-family:var(--mono);font-size:.92em;background:var(--flat);padding:1px 5px}
.mono{font-family:var(--mono)}
.num{font-variant-numeric:tabular-nums;text-align:right}
.sr-only{display:block;position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.inner ol:not([class]),.inner ul:not([class]),.window ol:not([class]){padding-left:1.4em;color:var(--ink-2)} /* ← U-32 · lista corrida: o reset zera o recuo; a lei devolve (coerencia.py C5) */
.check + .hint{margin-left:calc(16px + var(--space-2))} /* ← U-22 · hint alinhado ao rótulo do check, não à caixa */

/* Foco ← U-36 */
:focus-visible{outline:var(--focus-ring-width) solid var(--focus-ring);outline-offset:var(--focus-ring-offset)}
h1[tabindex="-1"]:focus-visible,h2[tabindex="-1"]:focus-visible{outline:none} /* ← U-36, 02/10 · o título que a troca de vista foca por programa (alvo do leitor de tela, fora da ordem do Tab) não é controle: o anel nele, ao carregar o login, lia como defeito — uma caixa em volta do "Log in" (teste do Brunno). O próximo Tab desenha o anel no controle seguinte ao título */
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}} /* ← U-33 */

/* ─── Rótulo, valor, chave-valor ← U-22, U-26 ─── */
.k{display:block;font-family:var(--mono);font-size:var(--text-label);font-weight:var(--weight-label);
  letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-4);line-height:var(--lead-label)} /* --ink-4, não --ink-5: rótulo de 10px precisa de 4.5:1 (contraste.py) */
.v{display:block;font-size:var(--text-small);font-weight:500;line-height:var(--lead-small);margin-top:.35em}
.v.warn{color:var(--warning);font-weight:var(--weight-strong)}
.v.bad{color:var(--danger);font-weight:var(--weight-strong)}
.v.ok{color:var(--success);font-weight:var(--weight-strong)}
.kv{display:grid;grid-template-columns:var(--kv-key-width) 1fr;column-gap:var(--space-4);row-gap:var(--space-3);align-items:baseline}
.kv .k{padding-top:.2em}
.kv .val{font-size:var(--text-body);font-variant-numeric:tabular-nums}
.kv .val.mono{font-family:var(--mono);font-size:var(--text-code)}
.kv .val.clip{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} /* ← 02/10 · teste do Brunno, achado 12: o valor que é identidade (o e-mail de entrada) fica numa linha, com reticências e o valor inteiro no `title` — a 390px ele saía cortado na borda da folha */

/* ─── Shell ← U-23, U-24, U-29 ─── */
.app{height:100vh;height:100dvh;display:grid; /* ← 02/10 · `dvh`: no celular, o 100vh conta a barra do navegador recolhida e o <body> ganhava uma rolagem própria */
  grid-template-rows:auto var(--topbar-height) minmax(0,1fr); /* ← 20/09 · a linha da tarja é `auto`: sem tarja (igreja em produção) ela some; com a tarja verde do parceiro em produção, existe */
  grid-template-columns:var(--sidebar-width) 1fr;
  grid-template-areas:"env env" "top top" "side main"}
/* ← U-23 · a moldura SEM barra lateral. O painel interno (a sala de controle) não tem
   navegação de família: a navegação dele são ABAS, dentro do próprio conteúdo, como o
   staff-panel real faz hoje. Sem isto o `main` cairia na segunda coluna e sobraria um vão de
   240px onde a barra estaria. ← decisão Victor 11/09/2026 ("cria o shell interno com as abas") */
.app.solo{grid-template-columns:1fr;grid-template-areas:"env" "top" "main"}
.app.solo .topbar{padding:0 var(--content-padding)}
/* Sem barra lateral não há coluna a alinhar: a conta perde a largura fixa e o fio da direita,
   que existiriam só para casar com a barra. */
.app.solo .account{width:auto;border-right:none;padding-left:0}
.app.solo .main > .tabs{max-width:var(--content-max);margin:0 auto var(--space-6)} /* ← as abas são irmãs do .inner, não abertura do documento; a largura é a mesma */

.env{grid-area:env;background:var(--env-banner-bg);color:var(--env-banner-ink);
  display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);
  padding:0 var(--space-6);height:var(--env-banner-height);overflow:hidden;
  font-family:var(--mono);font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;font-weight:var(--weight-label)}
.env.live{background:var(--success-soft);color:var(--success)} /* ← 20/09 · produção: a mesma tarja, verde, com o caminho de volta à sandbox (Rafael) */
.env.preview{background:var(--neutral-soft);color:var(--ink-2);height:auto;min-height:var(--env-banner-height);padding-top:var(--space-2);padding-bottom:var(--space-2)} /* ← 02/10 · PA-04 (D-P2): a prévia da igreja em produção, enquanto o lançamento está desligado. Neutra: não é ambiente nem sandbox (D-48). A frase é mais longa que a de ambiente, e quebra linha em vez de sumir */
.env .btn{height:24px;padding:0 var(--space-3);font-size:11px}
.topbar{grid-area:top;background:var(--canvas);border-bottom:var(--hair) solid var(--line);
  display:flex;align-items:stretch;justify-content:space-between;gap:var(--space-4);padding:0 var(--space-6) 0 0}
/* ← U-24 · decisão Victor 11/09/2026, contra a referência de layout: à esquerda a CONTA e a
   busca; o rótulo de ambiente em mono caixa-alta ("PRODUCTION") saiu — em sandbox a tarja
   acima já diz o ambiente, e em produção o rótulo anunciava o estado normal. */
.tleft{display:flex;align-items:stretch;gap:0;min-width:0;flex:1}
/* O brasão: símbolo + nome do produto. Era o bloco da esquerda da topbar até 11/09/2026,
   quando a CONTA tomou esse lugar; sobrevive porque a tela de ACESSO (login, cadastro,
   confira o e-mail) o usa como assinatura acima do formulário, onde não há conta para
   mostrar — quem ainda não entrou não tem igreja. ← U-24 */
.brand{display:flex;align-items:center;gap:var(--space-3)}
.brand .mark{display:block;width:28px;height:28px} /* ← U-24 símbolo tinta, 28 */
.brand .wordmark{font-size:var(--text-body);font-weight:var(--weight-strong);color:var(--ink)} /* ← 20/09 · o nome do produto ao lado do símbolo, na topbar dos painéis */
.topbar .brand{width:var(--sidebar-width);flex-shrink:0;padding:0 var(--space-5);border-right:var(--hair) solid var(--line)} /* ← 20/09 · o brasão toma a coluna que era da conta: mesmo eixo da barra */
.brand .envname{font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-4);font-weight:var(--weight-label);padding-left:var(--space-3);border-left:var(--hair) solid var(--line)}

/* ← U-24 · decisão Victor 11/09: "o campo deve estar alinhado à largura da navbar". A conta
   OCUPA a coluna da barra lateral — mesma largura, mesmo fio à direita —, então o símbolo, o
   nome da conta e o primeiro item do menu caem no mesmo eixo vertical. */
.account{display:flex;align-items:center;gap:var(--space-3);min-width:0;width:100%;
  padding:0;border:none;background:transparent;
  font:inherit;font-size:var(--text-body);color:var(--ink);text-align:left}
/* ← 20/09 · a conta desceu para o alto da barra lateral (`.workspace`), com o rótulo do portal
   embaixo; na topbar só sobrevive na sala de controle (`.app.solo`), onde não há barra. */
.topbar .account{width:var(--sidebar-width);flex-shrink:0;padding:0 var(--space-5);border-right:var(--hair) solid var(--line)}
.side .workspace{padding:var(--space-3) var(--space-5) var(--space-2);margin-bottom:var(--space-2)} /* ← 21/09 · Rafael: sem o fio embaixo e sem folga — a conta senta em cima do menu */
.side .workspace .portal{display:block;margin-top:2px;font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-4);font-weight:var(--weight-label)}
.side .workspace .menu{max-width:100%} /* ← 03/10 · teste ponta a ponta: o nome longo da igreja ("Elevation Church Ballantyne") empurrava a barra lateral e abria rolagem de lado */
.side .workspace .account .name{white-space:normal} /* ← 03/10 · na barra lateral o nome quebra em duas linhas: cortado com "…", a igreja não se reconhecia */
.side .workspace .accountwrap .pop{left:0;min-width:100%} /* ← 03/10 · o menu da conta passava da barra e a barra cortava o Church ID — o id que o suporte pede */
.side .workspace .menu .pop .v{overflow-wrap:anywhere} /* ← 03/10 · o id inteiro, em duas linhas se precisar */
.account .mark{display:block;width:28px;height:28px;flex-shrink:0} /* ← U-24 símbolo tinta, 28 */
.account .name{font-weight:var(--weight-strong);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;flex:1}
.account .ico{color:var(--ink-4);flex-shrink:0}
button.account{cursor:pointer}
button.account:hover{background:var(--flat)}
button.account[aria-expanded="true"] .ico{transform:rotate(180deg)}
.topbar .right{display:flex;align-items:center;gap:var(--space-3)}
/* A busca com o ícone dentro, como o .selectwrap faz com a seta ← U-22 */
/* A busca com ícone dentro é PEÇA, não geometria da topbar: o recuo do texto e a posição do
   ícone valem em qualquer lugar (14/09/2026 — a primeira busca fora da topbar, no passo de folha
   do doador, abriu com o texto em cima do ícone porque o recuo estava preso em `.topbar .search`).
   O que é da topbar fica em `.topbar .searchwrap`: o respiro à esquerda que alinha com a coluna
   da conta, a largura e o fundo. */
.searchwrap{position:relative;display:flex;align-items:center;min-width:0}
.searchwrap .ico{position:absolute;left:var(--space-3);color:var(--ink-5);pointer-events:none}
.searchwrap .search{padding-left:calc(var(--space-3) * 2 + var(--ico-size-sm))}
/* `.input:focus` engrossa a borda e compensa com `padding-left: calc(var(--space-3) - .5px)`;
   aqui a borda fica na espessura de sempre e o recuo não muda — o ícone não se move e o que se
   digita começa onde estava o placeholder. Três classes vencem as duas do `.input:focus`. */
.searchwrap .search:focus{border-width:var(--hair);padding-left:calc(var(--space-3) * 2 + var(--ico-size-sm))}
.topbar .searchwrap{padding-left:var(--space-5);flex:1;margin-right:var(--space-6)} /* ← 20/09 · a busca ocupa a largura até perto das ações da direita, com respiro */
.topbar .searchwrap .ico{left:calc(var(--space-5) + var(--space-3))}
.topbar .search{width:100%;background:var(--canvas);border-color:transparent}
.topbar .search::placeholder{color:var(--ink-5)}
/* ← decisão Victor 11/09/2026: a busca da topbar não troca de fundo no hover, e NADA se move
   ao focar. Duas coisas do `.input:focus` geral tinham de ser desfeitas AQUI, e medi as duas
   antes de escrever: ele engrossa a borda de 1px para 1,5px E compensa isso com
   `padding-left: calc(var(--space-3) - .5px)`. Como `.input:focus` vem depois no arquivo com
   a mesma especificidade de `.topbar .search`, o padding de 40px da busca virava 11,5px ao
   focar e o texto caía EM CIMA do ícone. Então esta regra fixa os dois: borda na espessura de
   sempre (zero deslocamento) e o mesmo padding de 40px. O foco é dito pela cor da borda, não
   por anel nem por caixa nova — o ícone não se move e o que se digita começa exatamente onde
   estava o "Search". */
.topbar .search:focus{border-color:var(--sel);background:var(--canvas);outline:none}
/* Ação de conta na topbar: ícone que responde, rótulo opcional ← U-10, U-21 */
.tact{display:inline-flex;align-items:center;gap:var(--space-2);position:relative;padding:var(--space-2);
  border:none;background:transparent;font:inherit;font-size:var(--text-body);color:var(--ink-3);
  text-decoration:none;cursor:pointer;border-radius:var(--radius-control)}
.tact:hover{background:var(--flat);color:var(--ink)}
/* `is-na` na topbar: destino que ainda não existe. Mesma palavra da barra lateral; aqui a ação
   fica apagada e sem resposta, em vez de mudar o fragmento da URL sem fazer nada (I-19). */
.tact.is-na{cursor:not-allowed}
.tact.is-na:hover{background:transparent;color:inherit}
.tact .count{position:absolute;top:0;right:0;min-width:16px;height:16px;padding:0 4px;
  display:grid;place-items:center;border-radius:var(--radius-full);
  background:var(--danger);color:var(--paper);font-size:10px;font-weight:700;line-height:1}
.avatar{width:32px;height:32px;border-radius:var(--radius-full);border:none;color:var(--sel-deep);background:var(--sel-soft);display:grid;place-items:center;
  font-family:var(--mono);font-size:12px;font-weight:700;flex-shrink:0;white-space:nowrap;line-height:1} /* ← 21/09 · Rafael: a bolinha era pequena (28) em toda parte. ← 02/10 · teste do Brunno, achado 12: num flex apertado ela encolhia em elipse e as iniciais empilhavam ("B" sobre "R") — círculo de 32 que não encolhe, iniciais numa linha */
/* ← 21/09 · o botão da navegação no celular. Fora do celular não existe; a caixa é o `sr-only`
   (focável, invisível) e o rótulo é o que se vê. Um ícone por estado: fechado = menu, aberto = x. */
.navtoggle{display:none;width:var(--control-height);height:var(--control-height);place-items:center;border-radius:var(--radius-control);color:var(--ink-2);cursor:pointer;flex-shrink:0}
.navtoggle:hover{background:var(--flat);color:var(--ink)}
.navtoggle-input{display:none} /* ← 01/10 · U-62: fora do celular o rótulo não existe, e o input `.sr-only` era uma parada de Tab invisível e sem efeito; volta com o rótulo no @media */
.navtoggle-input:focus-visible + .navtoggle{outline:2px solid var(--sel);outline-offset:2px}
.navtoggle .ico + .ico{display:none}
.app:has(.navtoggle-input:checked) .navtoggle .ico{display:none}
.app:has(.navtoggle-input:checked) .navtoggle .ico + .ico{display:block}

.side{grid-area:side;background:var(--canvas);border-right:var(--hair) solid var(--line);
  padding:var(--space-5) 0;display:flex;flex-direction:column;overflow:auto;min-height:0} /* o app tem a altura da janela: só o conteúdo rola; tarja, topbar e sidebar (com o identificador no rodapé) ficam parados — Victor, 03/09 */
.side .group{padding:0 var(--space-5);margin-bottom:var(--space-5)}
.side .group .k{margin-bottom:var(--space-2)}
.side nav a{display:flex;align-items:center;padding:7px var(--space-3);margin-left:calc(-1 * var(--space-3));color:var(--ink-2);text-decoration:none;
  border-left:var(--rule) solid transparent;font-size:var(--text-body)}
/* ← U-10 · o ícone da navegação. Era `display:none`: a lei emitia o vão e o escondia, porque
   ícone em item de menu estava proibido até 11/09/2026. Margem em vez de `gap` para a `.soon` e a
   seta manterem o afastamento que já tinham — `gap` valeria entre TODOS os itens do flex. */
.side nav a .ico{margin-right:var(--space-3);color:var(--ink-4)}
.side nav a[aria-current] .ico,.side nav a:hover .ico{color:inherit}
.side nav a.is-na .ico{color:var(--ink-5)}
.side nav a .arrow{margin-left:var(--space-2)} /* o flex come o espaço em branco do template */
.side nav a:hover{background:var(--side-hover)} /* ← U-37 */
.side nav a[aria-current]{color:var(--sel-deep);font-weight:var(--weight-strong);border-left-color:var(--sel)} /* ← U-38 · sem fundo (Victor, 03/09) */
.side nav a.is-na{color:var(--ink-5)}
.side nav a.navsearch{display:none} /* ← 01/10 · D-16 (Rafael): a busca no menu é só do celular, onde o campo da topbar some; fora dele o item não existe — nem parada de Tab */
.side nav a.navmobile{display:none} /* ← 03/10 · Jam: o "Send feedback" do menu é só do celular, onde a topbar esconde o "Feedback?" */
.side nav a.is-na .soon{font-family:var(--mono);font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;margin-left:var(--space-2)}
.side .foot{margin-top:auto;padding:var(--space-4) var(--space-5) 0;font-family:var(--mono);font-size:var(--text-label);letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-5);border-top:var(--hair) solid var(--line-mid)}

.side .foot .disc {
  font-size: var(--text-body);
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink);
}
/* ← 02/10 · teste do Brunno, achado 12: a pessoa no pé da barra. Era `overflow-wrap:anywhere` no
   bloco inteiro, e o e-mail quebrava em três linhas no meio das palavras. Agora: linha 1 o nome
   (peso maior), linha 2 o e-mail menor e cinza — ou, sem nome, o papel e a igreja —, as duas com
   reticências e nunca quebradas. O e-mail inteiro fica no `title` e no topo do menu da seta. */
.who{display:flex;align-items:center;gap:var(--space-3);min-width:0}
.who-lines{display:flex;flex-direction:column;min-width:0;line-height:var(--lead-small)}
.who-name,.who-sub{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.who-name{font-weight:var(--weight-strong);color:var(--ink)}
.who-sub{font-size:var(--text-small);font-weight:var(--weight-body);color:var(--ink-4)}
.who-mail{color:var(--ink-4);overflow-wrap:anywhere;padding-bottom:var(--space-2);border-bottom:var(--hair) solid var(--line)}
/* A seta do menu é o único outro item do resumo: duas colunas, e não as três da `.disc` — a terceira,
   vazia, levava 16px do e-mail. */
.side .foot .disc > summary{grid-template-columns:minmax(0,1fr) auto;column-gap:var(--space-2)}
.side .foot .disc {
  position: relative;
}
.side .foot .disc > .body {
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  background: var(--paper);
  border: var(--hair) solid var(--line);
  border-radius: var(--radius-surface);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.side .foot .disc > summary .caret {
  transform: rotate(180deg);
  grid-column: 2; /* ← 03/10 · aqui o resumo tem duas colunas (a pessoa e a seta) */
}
.side .foot .disc[open] > summary .caret {
  transform: none;
}

.main{grid-area:main;background:var(--paper);padding:var(--space-6) var(--content-padding) var(--space-8);min-width:0;min-height:0;overflow:auto;position:relative} /* ← U-16 · a folha; é a única área que rola. ← 02/10 · teste do Brunno, #05: `position:relative` faz da folha o bloco de contenção de tudo o que é absoluto dentro dela — o input `.sr-only` de um `.check` no fim da revisão escapava para o <body> e criava a segunda barra de rolagem */
.main > .inner{max-width:var(--content-max);margin:0 auto}
.grid{display:grid;grid-template-columns:repeat(12,1fr);column-gap:var(--grid-gap);row-gap:var(--space-5)} /* ← U-02 */
.span-3{grid-column:span 3}.span-4{grid-column:span 4}.span-5{grid-column:span 5}.span-6{grid-column:span 6}
.span-7{grid-column:span 7}.span-8{grid-column:span 8}.span-9{grid-column:span 9}.span-12{grid-column:span 12}
@media (max-width:760px){.grid{grid-template-columns:repeat(4,1fr)}
  .grid > [class*="span-"] {
    grid-column: span 4;
  }}
@media (min-width:761px) and (max-width:1100px){.grid>.span-4,.grid>.span-6,.grid>.span-8{grid-column:span 12}} /* ← 21/09 · só entre o tablet e o desktop: abaixo de 760 a grade tem 4 colunas e `span 12` criava 8 colunas implícitas de 0px — o span-4 ficava cheio e o span-3/5 com 215px */ /* ← 20/09 · entre o tablet e o desktop largo, uma coluna: o chip de URL e a linha de chips cabem */
.grid>*>.card:only-child{height:100%} /* cards irmãos da mesma altura */

/* ─── Cabeçalho de página ← U-24 ─── */
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-5)}
.page-head h1{font-size:var(--text-page);font-weight:var(--weight-page);letter-spacing:var(--track-page);line-height:var(--lead-page);text-wrap:balance;max-width:26em}
.page-head .actions{display:flex;gap:var(--space-2);align-items:center;flex-shrink:0}
.page-head{flex-wrap:wrap;row-gap:var(--space-3)} /* ← 02/10 · teste do Brunno: no celular o seletor do Overview passava da borda e a página rolava de lado; as ações descem para a linha de baixo quando não cabem */
.standfirst{font-size:var(--text-standfirst);line-height:1.5;color:var(--ink-2);max-width:62ch;margin-top:var(--space-3)}
.standfirst strong{color:var(--ink)}
.rule{border-top:var(--rule) solid var(--rule-color);margin-top:var(--space-4)}
.rule.hair{border-top:var(--hair) solid var(--line-mid);margin-top:0}
.meta{display:grid;grid-template-columns:repeat(12,1fr);column-gap:var(--grid-gap);row-gap:var(--space-3);margin-top:var(--space-3);padding-bottom:var(--space-3)}
.meta .f{grid-column:span 3}
@media (max-width:820px){.meta .f{grid-column:span 6}}

/* ─── Linha de estado sob o título ← U-24 · decisão Victor 2026-09-09: a faixa de metadados (.meta + duas
   réguas) saía em quase toda tela com casas preenchidas à força e um fio duplo; no lugar, uma linha só com o
   que MUDA — chips de estado e fatos curtos —, nunca identidade (que mora no rodapé da barra), nunca regra.
   Sem fio: a primeira seção já abre com o dela. ─── */
.status{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-5);margin-top:var(--space-4)}
/* ← 15/10 · o cabeçalho (título, frase, linha de estado) termina com respiro antes do que vem depois — só a seção abria o
   próprio espaço; a grade de KPIs da Churches (TL-C07) e da Gifts (TL-C08) encostava no título (Victor) */
:is(.page-head,.standfirst,.status) + :not(.standfirst,.status,section,.sr-only){margin-top:var(--space-6)}
.status .f{display:inline-flex;align-items:baseline;gap:var(--space-2)}
.status .f .k{display:inline;line-height:inherit}
.status .f .v{display:inline;margin-top:0}

/* ─── Seção com marginália ← U-25 ─── */
section.sec{margin-top:var(--space-7);border-top:var(--sec-rule) solid var(--sec-rule-color);padding-top:var(--space-4)}
section.sec.first{margin-top:var(--space-6)}
.sec-head{display:grid;grid-template-columns:52px 1fr auto;column-gap:var(--space-4);align-items:start;margin-bottom:var(--space-4)}
.sec-head .n{font-family:var(--mono);font-size:12px;font-weight:700;letter-spacing:.04em;padding-top:.45em}
.sec-head h2{font-size:var(--text-section);font-weight:var(--weight-section);letter-spacing:var(--track-section);line-height:var(--lead-section)}
.sec-head p{color:var(--ink-3);margin-top:6px;font-size:var(--text-body);max-width:68ch}
.sec-body{margin-left:calc(52px + var(--space-4))}
.sec-body.flush{margin-left:0}
.sec-head .n:empty{display:none} /* ← U-25 · sem ordem, sem marginália: o título ocupa a coluna */
.sec-head:has(.n:empty){grid-template-columns:1fr auto}
h3{font-size:var(--text-sub);font-weight:var(--weight-sub);letter-spacing:var(--track-sub);line-height:var(--lead-sub)}
@media (max-width:820px){.sec-body{margin-left:0}.sec-head{grid-template-columns:36px 1fr}}

/* ─── Tabela ← U-14 ─── */
.twrap{overflow-x:auto}
table{border-collapse:collapse;width:100%;font-size:var(--text-body)}
th{font-family:var(--mono);font-size:var(--text-th);letter-spacing:var(--track-th);text-transform:uppercase;color:var(--table-header-ink);
  text-align:left;font-weight:var(--weight-th);padding:0 var(--space-4) 8px 0;border-bottom:var(--th-rule) solid var(--th-rule-color);white-space:nowrap;background:var(--table-header-bg)}
td{padding:0 var(--space-4) 0 0;height:var(--row-height);border-bottom:var(--hair) solid var(--table-row-border);vertical-align:middle;color:var(--ink-2)}
tr:last-child td{border-bottom:none}
tbody tr:hover td{background:var(--table-row-hover)}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
td.mono{font-family:var(--mono);font-size:var(--text-code);white-space:nowrap} /* ← 15/10 · Igreja 5: identificador não quebra no hífen ("Content-Type" virava "Content-" / "Type"); a tabela rola (.twrap) */
td .name{color:var(--ink);font-weight:500}
tr[aria-selected="true"] td{background:var(--sel-soft)} /* ← U-38 */
.more{color:var(--ink-4);display:inline-flex;align-items:center}

/* ─── Ícone ← U-10 · decisão Victor 11/09/2026: a lei passa a ter ícone de biblioteca.
   A BIBLIOTECA É A LUCIDE. Entrou como Material Symbols Sharp e virou Lucide no
   mesmo dia — a referência que o Victor mandou inverteu o critério de angularidade —,
   e este comentário ficou para trás. Procedência em packages/ui/src/icons/README.md.
   Tamanho e cor são daqui; forma é do `icon()`. ─── */
.ico{display:inline-block;width:var(--ico-size);height:var(--ico-size);flex-shrink:0;vertical-align:-.18em}
.ico.sm{width:var(--ico-size-sm);height:var(--ico-size-sm)}
.ico.lg{width:var(--ico-size-lg);height:var(--ico-size-lg)}

/* ─── Chips ← U-20 ─── */
/* ← U-20 · decisão Victor 11/09/2026, duas de uma vez: "nas pills, desative o bg, mantenha
   apenas o outline" e "os pills devem ter o formato de pill mesmo". Então o estado passa a ser
   dito por CONTORNO + COR DO TEXTO + PONTO, sobre o papel, numa pílula. O fundo macio
   (`--*-soft`) saiu de todos os tons; o `padding` abriu para `--space-3` porque pílula com
   8px encosta o texto na curva. */
.chip{display:inline-flex;align-items:center;gap:6px;height:var(--chip-height);font-family:var(--mono);font-size:var(--text-chip);font-weight:var(--weight-chip);
  letter-spacing:var(--track-chip);text-transform:uppercase;padding:0 var(--space-3);white-space:nowrap;border-radius:var(--radius-pill);line-height:1;background:transparent}
/* ← U-05, U-20 (emendada 02/10) · a FORMA do ponto diz o estado sem a cor: ● feito · ○ ainda não ·
   ◐ em curso · ◉ requer ação · ■ falhou. Em cinza, "Action needed" saía igual a "Approved" e
   "In review" igual a "Not delivering" (revisão da frente D; o Brunno pediu "uma regra só de cor e
   ícone"). Um ponto só, de forma própria por tom — não é ícone somado ao chip (U-20). O raio sai
   por tom: o quadrado da falha é o único ponto sem ele. */
.chip .dot{width:6px;height:6px;background:currentColor;flex-shrink:0}
.chip.ok{color:var(--success);border:var(--hair) solid var(--success)}
.chip.ok .dot{border-radius:var(--radius-full);background:var(--success-dot)} /* ● cheio */
.chip.mid{color:var(--neutral);border:var(--hair) solid var(--ink-5)} /* não começado, inativo: neutro */
.chip.mid .dot{border-radius:var(--radius-full);background:transparent;border:var(--hair) solid currentColor} /* ○ oco */
.chip.warn{color:var(--warning);border:var(--hair) solid var(--warning)}
.chip.warn .dot{width:8px;height:8px;border-radius:var(--radius-full);border:var(--hair) solid var(--warning-dot);padding:var(--hair);background:var(--warning-dot);background-clip:content-box} /* ◉ ponto com anel */
.chip.bad{color:var(--danger);border:var(--hair) solid var(--danger)}
.chip.bad .dot{background:var(--danger-dot)} /* ■ quadrado */
.chip.acc{color:var(--acc-deep);border:var(--hair) solid var(--acc)} /* em andamento, em análise (U-20, 02/10); simulado, sugestão, novo */
.chip.acc .dot{border-radius:var(--radius-full);background:transparent;border:var(--hair) solid var(--acc);position:relative;overflow:hidden} /* ◐ meio cheio */
.chip.acc .dot::after{content:"";position:absolute;top:0;bottom:0;left:0;width:50%;background:var(--acc)}
.chip.locked{color:var(--ink-5);border:var(--hair) dashed var(--line-mid)}
.chip.hard{color:var(--ink);border:var(--hair) solid var(--ink)} /* raro: severidade máxima. Era invertido (tinta chapada); sem fundo, o peso vem do contorno em tinta */
.is-na{opacity:var(--disabled-opacity)}

/* ─── Botões ← U-21, U-37 ─── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);height:var(--btn-height);padding:0 var(--control-padding-x);
  font:inherit;font-size:var(--text-body);font-weight:500;line-height:1;cursor:pointer;text-decoration:none;white-space:nowrap;
  border-radius:var(--radius-control);border:1px solid transparent;background:transparent;color:var(--ink);
  text-transform:none;letter-spacing:normal; /* ← U-08, 01/10 · `font:inherit` não desfaz a caixa-alta nem o tracking do contêiner (a tarja `.env` é rótulo) */
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease)}
.btn.primary{background:var(--primary);color:var(--primary-ink);border-width:var(--btn2-border);border-color:var(--primary-border)} /* ← U-21 · contorno na espessura do secundário */
.btn.primary:hover{background:var(--primary-hover);border-color:var(--primary-border)}
.btn.primary.is-disabled,.btn.primary[disabled]{background:var(--primary);color:var(--primary-ink);opacity:var(--disabled-opacity);cursor:default} /* ← 15/10 (DB-12) · com o primário preenchido, desabilitado é o mesmo botão apagado — o "preenche ao desabilitar" de 03/09 só fazia sentido no contorno */
.btn.secondary{border-width:var(--btn2-border);border-color:var(--btn2-color)}
.btn.secondary:hover{background:var(--flat)}
.btn.tertiary{padding:0 var(--space-1);text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--line-mid);height:auto}
.btn.tertiary:hover{text-decoration-color:var(--ink)}
.btn.attention{background:var(--primary);color:var(--primary-ink);border-color:var(--primary-border)} /* alias legado → primary */
.btn.attention:hover{background:var(--primary-hover)}
.btn.danger{border-color:var(--danger);color:var(--danger)}
.btn.danger:hover{background:var(--danger-soft)}
.btn.danger.solid{background:var(--danger);color:var(--paper)}
.btn.sm{height:28px;padding:0 var(--space-3);font-size:var(--text-small)}
.btn.tertiary.sm{padding:0 var(--space-1)} /* ← 02/10 · bug de cascata: o `.btn.sm` vinha depois do `.btn.tertiary` e devolvia os 12px do botão com caixa — o link sublinhado pequeno saía recuado do texto acima ("Need help? Email us", "Change representative") */
.btn.touch{height:var(--control-height-touch)} /* ← U-42 */
.btn[disabled],.btn.is-disabled{opacity:var(--disabled-opacity);cursor:not-allowed}
.btn .arrow{display:inline-flex;align-items:center}

/* ─── Campo ← U-22 ─── */
.field{display:block}
.field + .field{margin-top:var(--space-4)}
.field .k{margin-bottom:6px;color:var(--ink-4)}
.field .k .req{color:var(--ink-5);margin-left:2px}
.input,.select,.textarea{display:block;width:100%;height:var(--control-height);padding:0 var(--space-3);font:inherit;font-size:var(--text-body);color:var(--ink);
  background:var(--control-bg);border:var(--hair) solid var(--control-border);border-radius:var(--radius-control)}
.input.mono{font-family:var(--mono);font-size:var(--text-code)}
.textarea{height:auto;min-height:calc(var(--control-height) * 2.6);padding:var(--space-2) var(--space-3);line-height:var(--lead-body);resize:vertical}
.input::placeholder,.textarea::placeholder{color:var(--ink-5)}
.input:focus,.select:focus,.textarea:focus{outline:none;border:1.5px solid var(--sel);padding-left:calc(var(--space-3) - .5px);background:var(--paper)}
.field.error .input,.field.error .select,.field.error .textarea{border:1.5px solid var(--danger);background:var(--paper)}
.hint{display:block;margin-top:6px;font-size:var(--text-small);color:var(--ink-4);line-height:var(--lead-small)}
.field.error .hint{color:var(--danger);font-family:var(--mono);font-size:11.5px}
.input[disabled]{background:var(--flat);color:var(--ink-5)}
.select{appearance:none;padding-right:calc(var(--space-3) + 1.5em)} /* ← 20/09 · o texto não passa por baixo do caret */
.select.lg{height:36px;font-size:var(--text-body);font-weight:600} /* ← 20/09 · o seletor de vista do Overview, em evidência */
.selectwrap{position:relative}.selectwrap::after{content:"⌄";position:absolute;right:var(--space-3);top:50%;transform:translateY(-60%);font-family:var(--mono);pointer-events:none}
.check{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-body);position:relative} /* ← 02/10 · o input `.sr-only` é absoluto: ancorado aqui, fica junto da caixa em qualquer lugar onde o check apareça */
.check .box{width:16px;height:16px;border:var(--hair) solid var(--ink);border-radius:var(--radius-control);display:grid;place-items:center;flex-shrink:0}
.check .box.on{background:var(--sel);border-color:var(--sel)}
.check .box.on::after{content:"";width:8px;height:4px;border-left:1.5px solid var(--paper);border-bottom:1.5px solid var(--paper);transform:translateY(-1px) rotate(-45deg)}
.check input:focus-visible + .box{outline:var(--focus-ring-width) solid var(--focus-ring);outline-offset:var(--focus-ring-offset)} /* ← U-36, 01/10 · o input é `.sr-only` (1px recortado): o anel vai para a caixa que se vê; vale para o rádio */
.radio .box{border-radius:var(--radius-full)}
.radio .box.on{background:var(--paper)}
.radio .box.on{border-color:var(--sel)}
.radio .box.on::after{content:"";width:8px;height:8px;border:none;border-radius:var(--radius-full);background:var(--sel);transform:none}
.toggle{width:var(--toggle-w);height:var(--toggle-h);border:var(--hair) solid var(--ink);border-radius:var(--toggle-h);position:relative;background:var(--paper);display:inline-block;vertical-align:middle} /* ← U-41 */
.toggle::after{content:"";position:absolute;top:2px;left:2px;width:calc(var(--toggle-h) - 6px);height:calc(var(--toggle-h) - 6px);border-radius:var(--radius-full);background:var(--ink);transition:transform var(--dur) var(--ease)}
.toggle.on{background:var(--sel);border-color:var(--sel)}
.toggle.on::after{background:var(--paper);transform:translateX(calc(var(--toggle-w) - var(--toggle-h)))}

/* ─── Callout ← U-27 ─── */
.callout{background:var(--flat);border:var(--hair) solid var(--line-mid); /* ← U-27 · fio fino ao redor na cor do tom (Victor, 08/09); o fio à esquerda saiu */padding:var(--space-4) var(--space-5);font-size:var(--text-body);border-radius:var(--radius-surface)}
.callout.risk{border-color:var(--warning);background:var(--warning-soft)}
.callout.bad{border-color:var(--danger);background:var(--danger-soft)}
.callout.ok{border-color:var(--success);background:var(--success-soft)}
.callout.info{border-color:var(--acc);background:var(--acc-soft)}
.callout.hard{background:var(--ink);border-color:var(--ink);color:var(--paper)} /* invertido: o fio existe, na cor do fundo, para a caixa não mudar de tamanho entre graus */
.callout.hard strong{color:var(--paper)}
.callout.hard :focus-visible,.proto-bar :focus-visible{outline-color:var(--paper)} /* ← U-36, 01/10 · o anel roxo dava 2,73:1 sobre a tinta — justo no "Show secret" e no "I've stored it" do segredo mostrado uma vez */
.callout .label{display:block;font-family:var(--mono);font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;font-weight:700;color:var(--ink-4);margin-bottom:5px}
.callout.risk .label{color:var(--warning)}
.callout.bad .label{color:var(--danger)}
.callout.ok .label{color:var(--success)}
.callout.info .label{color:var(--acc-deep)}
.callout.hard .label{color:var(--paper-a55)}
.callout.hard .btn.secondary{background:transparent;border-color:var(--paper);color:var(--paper)}
.callout.hard .btn.primary{background:var(--paper);color:var(--ink);border-color:var(--paper)}
.callout.hard .btn.tertiary {
  color: var(--paper);
  text-decoration-color: var(--paper-a55);
}
.callout.hard .btn.secondary:hover{background:var(--paper-a12)}
.callout.hard .code-chip,
.callout.hard .code-chip .btn,
.callout.hard .code .btn {
  color: var(--ink);
  border-color: var(--ink);
} /* ← 20/09 · o chip tem fundo claro; herdar a tinta de papel do aviso invertido apagava a chave e o Copy */
.callout.hard .code-chip :focus-visible,.callout.hard .code :focus-visible{outline-color:var(--focus-ring)} /* ← 01/10 · ilha clara dentro da tinta: o Copy volta ao anel roxo, que o papel apagaria */
/* ← U-27 (08/09) · botão sobre callout de tom: secundário e terciário falam a cor do tom; hover volta ao papel; o primário não entra em callout (é da região) */
/* ← U-27 (09/09) · em repouso o secundário sobre callout tem fundo PAPEL — separa-o do fundo lavado do callout (Victor: "fundo branco, pra diferenciar do callout") */
.callout .btn.secondary{background:var(--paper)}
.callout.risk .btn.secondary{border-color:var(--warning);color:var(--warning)}  .callout.risk .btn.tertiary{color:var(--warning)}
.callout.bad .btn.secondary{border-color:var(--danger);color:var(--danger)}    .callout.bad .btn.tertiary{color:var(--danger)}
.callout.ok .btn.secondary{border-color:var(--success);color:var(--success)}   .callout.ok .btn.tertiary{color:var(--success)}
.callout.info .btn.secondary{border-color:var(--acc-deep);color:var(--acc-deep)} .callout.info .btn.tertiary{color:var(--acc-deep)}
/* ← U-27 (09/09) · hover do secundário sobre callout de tom: ENCHE com a cor do tom e o texto vai ao papel — o fundo branco repetia o lavado do callout (Victor) */
.callout.risk .btn.secondary:hover{background:var(--warning);border-color:var(--warning);color:var(--paper)}
.callout.bad .btn.secondary:hover{background:var(--danger);border-color:var(--danger);color:var(--paper)}
.callout.ok .btn.secondary:hover{background:var(--success);border-color:var(--success);color:var(--paper)}
.callout.info .btn.secondary:hover{background:var(--acc-deep);border-color:var(--acc-deep);color:var(--paper)}
.callout:not(.risk):not(.bad):not(.ok):not(.info):not(.hard) .btn.secondary:hover{background:var(--ink);border-color:var(--ink);color:var(--paper)} /* neutro: o "tom" é a tinta — --flat sobre --flat sumia */
.callout .btn.tertiary{text-decoration-color:currentColor}
/* ← 03/10 · Jam do Rafael: o aviso que se tira da frente tem o `×` no canto — ele clicou quatro vezes no rótulo
   do "Production not released" procurando o fechar. Controle quadrado de 28 (o `.btn.sm`), na cor do tom; o texto
   abre espaço à direita para não correr por baixo dele. Hover é superfície (U-37): o papel sobre o lavado. */
.callout.dismissible{position:relative;padding-right:calc(var(--space-5) + var(--space-6))}
.callout .dismiss{position:absolute;top:var(--space-2);right:var(--space-2);display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:0;border-radius:var(--radius-control);background:transparent;color:var(--ink-3);cursor:pointer}
.callout .dismiss:hover{background:var(--paper)}
.callout.risk .dismiss{color:var(--warning)}
.callout.bad .dismiss{color:var(--danger)}
.callout.ok .dismiss{color:var(--success)}
.callout.info .dismiss{color:var(--acc-deep)}
.callout.hard .dismiss{color:var(--paper)}
.callout.hard .dismiss:hover{background:var(--paper-a12)}
.hot{color:var(--warning);font-weight:var(--weight-strong)}

/* ─── Código ← U-30 ─── */
.code{position:relative;background:var(--code-bg);color:var(--code-ink);padding:var(--space-4) var(--space-5);font-family:var(--mono);font-size:var(--text-code);line-height:var(--lead-code);overflow-x:auto;border-radius:var(--radius-surface)}
.code pre{font:inherit;white-space:pre;padding-right:88px} /* ← 02/10 · teste do Brunno (P03): código numa linha só, rolando no bloco — "rostergivin / g.com" e "$ROS / TER_KEY" pareciam copiados errado */
.code .copy{position:absolute;top:var(--space-3);right:var(--space-3);height:24px;padding:0 var(--space-2);font-size:11px} /* o mesmo Copy do chip */
.code .c{color:var(--code-comment)}.code .bad{color:var(--danger);font-weight:700}.code .ok{color:var(--success);font-weight:700}
.code.locked pre{opacity:var(--disabled-opacity)}
.code-note{margin-top:var(--space-2);font-family:var(--mono);font-size:11.5px;color:var(--ink-4)}

/* ─── Card (só em grade de iguais) ← U-26 ─── */
.card{background:var(--paper);border:var(--hair) solid var(--line-mid);border-radius:var(--radius-surface);padding:var(--space-4) var(--space-5)}
.card .head{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-3);margin-bottom:var(--space-3)}
.card .head h3{font-size:var(--text-body);font-weight:var(--weight-strong)}
.card .foot{display:flex;gap:var(--space-2);margin-top:var(--space-4);padding-top:var(--space-3);border-top:var(--hair) solid var(--line)}

/* ─── Superfície de trabalho (painel branco sobre a mesa) ← U-16 ─── */
.sheet{background:var(--paper);border:var(--hair) solid var(--line-mid);border-radius:var(--radius-surface);padding:var(--space-5) var(--space-6)}

/* ─── KPI e gráfico ← U-31 ─── */
.kpi{border-top:var(--kpi-rule) solid var(--kpi-rule-color);padding-top:var(--space-3)}
.kpi .k{color:var(--kpi-label-ink)}
.kpi.sm .value{font-size:var(--text-kpi-sm)}
.kpi.flush{border-top:0;padding-top:0} /* ← 20/09 · ao lado de um gráfico, alinhado pelo rótulo, sem fio */
.kpis{display:grid;row-gap:var(--space-5)} /* a coluna de KPIs ao lado de um gráfico */
@media (max-width:1100px){.kpis{grid-template-columns:1fr 1fr;column-gap:var(--grid-gap)}.kpis>.kpi{border-top:0;padding-top:0}.kpis>.btn{grid-column:span 2;justify-self:start}}
.kpis.aside{row-gap:0;border-left:var(--hair) solid var(--line);padding-left:var(--space-6);height:100%;align-content:start} /* ← 15/10 · a coluna ao lado do gráfico, com divisor vertical; uma métrica da outra por fio */
.kpis.aside>:not(.btn){padding:var(--space-4) 0;border-top:var(--hair) solid var(--line)}
.kpis.aside>:first-child{border-top:0;padding-top:0}
.kpis.aside>.btn{margin-top:var(--space-4);justify-self:start}
@media (max-width:1100px){.kpis.aside{grid-template-columns:1fr;border-left:0;padding-left:0;margin-top:var(--space-5)}.kpis.aside>.btn{grid-column:auto}}
.kpi .k{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kpi .value{font-size:var(--text-kpi);font-weight:var(--weight-kpi);letter-spacing:var(--track-kpi);line-height:var(--lead-kpi);font-variant-numeric:tabular-nums;margin-top:var(--space-2)}
.kpi .value small{font-size:.5em;font-weight:500;color:var(--ink-4);letter-spacing:0;margin-left:2px}
.kpi .delta{display:block;margin-top:var(--space-2);font-family:var(--mono);font-size:var(--text-small);color:var(--kpi-delta-ink)}
.kpi .delta.up{color:var(--kpi-delta-up)}.kpi .delta.down{color:var(--kpi-delta-down)}
.bars{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;align-items:end;gap:var(--space-2);height:var(--chart-height);
  border-bottom:var(--hair) solid var(--chart-grid)} /* sem linhas de grade: o valor rotula cada barra (U-03); grade seria gradiente (U-07) */
.bars .bar{background:var(--chart-bar);position:relative}
.bars .bar.current{background:var(--chart-bar-current)}
.bars .bar .lbl{position:absolute;top:100%;left:0;right:0;text-align:center;margin-top:6px;font-family:var(--mono);font-size:var(--text-label);letter-spacing:.06em;color:var(--ink-5);text-transform:uppercase}
.bars .bar .val{position:absolute;bottom:100%;left:0;right:0;text-align:center;margin-bottom:4px;font-family:var(--mono);font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* ─── Gráfico + tabela lado a lado ← U-31, U-02: divisor, mesma altura, mesma linha de base ─── */
.split{display:grid;grid-template-columns:7fr 5fr;column-gap:0;align-items:stretch}
.split > .col{display:flex;flex-direction:column;min-width:0}
.split > .col + .col{border-left:var(--hair) solid var(--line-mid);padding-left:var(--space-5)}
.split > .col:first-child{padding-right:var(--space-5)}
.split .colhead{display:flex;justify-content:space-between;align-items:center;min-height:28px}
.split .bars{flex:1;height:auto;min-height:var(--chart-height);margin-top:var(--space-6)}
.split .bars .bar .lbl{margin-top:8px}
.split .barfoot{height:28px}          /* espaço dos rótulos de mês = altura do rodapé da tabela */
.split .twrap{flex:1}
.split .table-foot{height:28px;padding-top:0;align-items:center;border-top:var(--hair) solid var(--line)}

/* ─── Abas ← U-38 ─── */
.tabs{display:flex;gap:var(--space-5);border-bottom:var(--hair) solid var(--line)}
.tabs a{padding:var(--space-2) 0 var(--space-3);color:var(--ink-4);text-decoration:none;border-bottom:var(--rule) solid transparent;margin-bottom:-1px;display:inline-flex;gap:var(--space-2);align-items:center}
.tabs a[aria-current]{color:var(--sel-deep);font-weight:var(--weight-strong);border-bottom-color:var(--sel)}
.tabs .is-na{padding:var(--space-2) 0 var(--space-3);color:var(--ink-5);display:inline-flex;align-items:baseline;cursor:not-allowed}
.tabs .is-na .soon{font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;margin-left:var(--space-2)}
.tabs a .dot{width:6px;height:6px;border-radius:var(--radius-full);background:var(--warning-dot)} /* aba com pendência */

/* ─── Etapas (Setup) ← U-25, U-05 ─── */
.steps{list-style:none}
.steps li,.steps li > button{display:grid;grid-template-columns:28px 1fr;column-gap:var(--space-3);align-items:baseline}
.steps li{padding:var(--space-2) 0;color:var(--ink-4)}
.steps li .n{font-family:var(--mono);font-size:12px;font-weight:700}
/* ← 02/10 · teste do Brunno, #02: o passo abre pela lista. O botão é a linha inteira; o hover é
   superfície (U-37), como o item da barra, e o anel de foco é o de sempre (U-36). */
.steps li:has(> button){display:block;padding:0}
.steps li > button{width:calc(100% + 2 * var(--space-2));margin-left:calc(-1 * var(--space-2));padding:var(--space-2);
  border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;border-radius:var(--radius-control);position:relative}
.steps li > button:hover{background:var(--side-hover)}
.steps li[aria-current],.steps li.current{color:var(--ink);font-weight:var(--weight-strong)}
.steps li[aria-current] .n,.steps li.current .n{color:var(--sel)}
/* ← 02/10 · teste do Brunno, #03 (U-05: estado não é só cor): o feito troca o número pela marca
   `check` da biblioteca (U-10), 16px na coluna de 28 — o glifo de texto quebrava a coluna; o ícone
   não. Em cinza, a marca continua dizendo "feito". */
.steps li.done{color:var(--ink-2)}
.steps li.done .n{color:var(--success)}
.steps li.done .n .ico{vertical-align:-3px}
/* Precisa de atenção: a vez é de quem preenche e algo travou. Número e nota em --warning; a nota
   é a forma (uma linha a mais, que o cinza não apaga) e diz o que conferir. */
.steps li.attention{color:var(--ink)}
.steps li.attention .n{color:var(--warning)}
.steps li .why{display:block;font-size:var(--text-small);font-weight:var(--weight-body);line-height:var(--lead-small);color:var(--warning);margin-top:2px}
.steps li.locked{opacity:var(--disabled-opacity)}

/* ─── Conector da faixa (site → igreja → ChMS) ← U-33 · decisão Victor 2026-09-03:
   trilho no centro vertical das caixas, tocando as bordas; conectado = trilho, bordas e ponto em primária ─── */
.flowwrap{display:flex;align-items:center;height:100%;padding:var(--space-4) var(--space-6) var(--space-4) 0} /* centra o diagrama na altura da linha e afasta do divisor */
.flow{display:grid;grid-template-columns:auto 1fr auto 1fr auto;grid-template-rows:auto auto;column-gap:0;row-gap:var(--space-2);align-items:center;width:100%}
.flow .node{display:contents}
.flow .node .box{grid-row:1;width:56px;height:56px;border:var(--hair) solid var(--line-mid);background:var(--paper);display:grid;place-items:center;color:var(--ink-3);border-radius:var(--radius-surface);position:relative;z-index:1}
.flow .node .box svg{width:24px;height:24px} /* ícone Lucide do ator (site · igreja · ChMS) — decisão Victor 03/09; ícone aqui é pictograma, não decoração (U-10) */
.flow .node.live .box{border:1.5px solid var(--sel);color:var(--sel-deep)}
.flow .node .name{grid-row:2;width:56px;display:flex;justify-content:center;white-space:nowrap;font-weight:var(--weight-strong);font-size:var(--text-body)}
.flow > .node:nth-child(1) > *{grid-column:1}.flow > .link:nth-child(2){grid-column:2}.flow > .node:nth-child(3) > *{grid-column:3}.flow > .link:nth-child(4){grid-column:4}.flow > .node:nth-child(5) > *{grid-column:5}
.flow .link{grid-row:1;position:relative;height:56px;display:grid;align-items:center;margin-inline:-1px}
.flow .link .rail{height:0;border-top:1.5px solid var(--sel)}
.flow .link.open .rail{border-top:var(--hair) dashed var(--ink-5)}
.flow .link .cap{position:absolute;top:calc(50% + 10px);left:0;right:0;text-align:center;white-space:nowrap;font-family:var(--mono);font-size:var(--text-label);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-4)}
.flow .link .cap b{display:block;font-weight:700;color:var(--success);letter-spacing:.04em} /* ← U-20, 02/10 · a palavra do estado fala a língua de status, como os chips ao lado ("Connected" é verde); o trilho e o pulso continuam o roxo do conector ligado (U-19) */
.flow .link.open .cap b{color:var(--neutral)} /* ← U-20, 02/10 · não conectado é neutro (teste do Brunno, #06); o tom do trecho aberto vem da língua de status */
.flow .link.acc .cap b{color:var(--acc-deep)}.flow .link.warn .cap b{color:var(--warning)}.flow .link.bad .cap b{color:var(--danger)}
.flow .link .pulse{position:absolute;top:50%;left:0;width:6px;height:6px;margin-top:-3px;border-radius:var(--radius-full);background:var(--sel);animation:travel 2.4s linear infinite}
.flow .link.open .pulse{display:none}
.flow .link:not(.open) .gap{display:none}
.flow .link.open .gap{position:absolute;top:50%;left:50%;width:18px;height:0;margin:0 -9px;border-top:1.5px solid var(--neutral-dot);transform:rotate(-30deg)}
.flow .link.acc .gap{border-top-color:var(--acc)}.flow .link.warn .gap{border-top-color:var(--warning-dot)}.flow .link.bad .gap{border-top-color:var(--danger-dot)}
.flow .caps{grid-column:1 / -1;display:none}
@media (max-width:600px){.flow{padding-bottom:var(--space-7)}.flow .link .cap{top:calc(100% + var(--space-7));left:calc(-1 * var(--space-5));right:calc(-1 * var(--space-5));white-space:normal;text-wrap:balance}} /* ← 02/10 · no celular o trecho é mais estreito que a legenda ("Not on your site yet", a mesma palavra do chip): a legenda desce para baixo dos nomes, onde pode quebrar sem encostar em nada */
@keyframes travel{0%{left:0;opacity:0}15%{opacity:1}85%{opacity:1}100%{left:calc(100% - 6px);opacity:0}}

/* ─── Trilha: uma progressão que tem POSIÇÃO ← U-33, I-17 · decisão Victor 11/09/2026
   (o "Your path" do parceiro pediu animação "porém ela precisa fazer sentido com a info que
   estamos mostrando, não é somente copiar o componente de lá").

   Por que não é o `.flow`: lá cada elo é uma CONEXÃO independente, e todo elo conectado
   pulsa. Aqui os três são MARCOS em sequência, e a pessoa está num deles. Se todas as pernas
   pulsassem, o movimento diria que três coisas andam ao mesmo tempo — e duas estão travadas.
   Então a regra é: perna atrás do marco atual é cheia e parada (já foi andada); a perna que
   SAI do marco atual é a única que pulsa, na direção do próximo; perna à frente é tracejada e
   inerte. O movimento passa a dizer onde você está e para onde a coisa anda.

   `prefers-reduced-motion` já mata a animação no topo do arquivo (U-33). ─── */
.path{display:grid;grid-template-columns:28px 1fr 28px 1fr auto;grid-template-rows:auto auto auto;column-gap:0;row-gap:var(--space-2);align-items:start}
.path .step{display:contents}
.path .step .box{grid-row:1;width:28px;height:28px;border-radius:var(--radius-full);display:grid;place-items:center;
  border:var(--hair) solid var(--line-mid);background:var(--paper);color:var(--ink-5);
  font-size:var(--text-label);font-weight:var(--weight-label);letter-spacing:0}
.path .step.done .box{border-color:var(--sel);background:var(--sel);color:var(--paper)}
.path .step.now .box{border:1.5px solid var(--sel);color:var(--sel-deep)}
.path .step .name{grid-row:2;width:max-content;font-size:var(--text-body);font-weight:500;max-width:22ch}
.path .step.locked .name{color:var(--ink-5)}
.path .step .foot{grid-row:3;width:max-content;display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;max-width:26ch}
.path .leg{grid-row:1;position:relative;height:28px;display:grid;align-items:center;margin:0 var(--space-3)}
.path .leg .rail{height:0;border-top:var(--hair) dashed var(--line-mid)}
.path .leg.done .rail{border-top:1.5px solid var(--sel)}
.path .leg.now .rail{border-top:1.5px dashed var(--sel)} /* ← 20/09 · o trecho ainda por andar não lê como feito */
.path .leg .pulse{display:none}
.path .leg.now .pulse{display:block;position:absolute;top:50%;left:0;width:6px;height:6px;margin-top:-3px;
  border-radius:var(--radius-full);background:var(--sel);animation:travel 2.4s linear infinite}
.path > .step:nth-child(1) > *{grid-column:1}.path > .leg:nth-child(2){grid-column:2}
.path > .step:nth-child(3) > *{grid-column:3}.path > .leg:nth-child(4){grid-column:4}
.path > .step:nth-child(5) > *{grid-column:5}
@media (max-width:1100px){ /* ← 20/09 · era 820: entre 820 e 1100 as pernas viravam um traço de 4px */
  .path{grid-template-columns:1fr;grid-template-rows:none;row-gap:var(--space-4)}
  .path .step{display:grid;
    grid-template-columns: auto minmax(0, 1fr);align-items:start;
    column-gap: var(--space-3);
    row-gap: var(--space-2)}
  .path .step .box {
    grid-column: 1 !important;
    grid-row: 1 / span 2;
  }
  .path .step .name {
    grid-column: 2 !important;
    grid-row: 1;
  }
  .path .step .foot {
    grid-column: 2 !important;
    grid-row: 2;
  }
  .path .step .name,.path .step .foot{max-width:none;width:auto}
  .path .leg{display:none} /* empilhado, a perna não tem o que ligar */
}

/* ─── Tendência: uma série no tempo, como LINHA ← U-31 · decisão Victor 11/09/2026
   ("transforme num gráfico de linha com visual um pouco mais moderno"). O `.bars` continua
   para comparar categorias lado a lado; linha é para ver a CURVA de uma série.

   O moderno aqui é sobriedade, não efeito: área em tint do acento sob a linha, traço de 1,5
   que NÃO engorda quando o SVG escala (`vector-effect`), fio de base em hairline, e um ponto
   cheio só no último valor — o de agora. Sem sombra, sem gradiente, sem eixo desenhado: a
   régua já é o fio. A geometria vem do DADO, nos atributos do SVG, não em style. ─── */
.trend{width:100%}
.trend svg{display:block;width:100%;height:auto}
.trend .base{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}
.trend .area{fill:var(--acc-tint);stroke:none}
.trend .curve{fill:none;stroke:var(--sel);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.trend .pt{fill:var(--paper);stroke:var(--sel);stroke-width:1.5;vector-effect:non-scaling-stroke}
.trend .pt.now{fill:var(--sel)}
.trend .lbls{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;margin-top:var(--space-2)}
.trend .lbls span{text-align:center;font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-5);font-weight:var(--weight-label)}
.trend .lbls span.now{color:var(--sel-deep)}
.trend .peak{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:var(--space-2)}
.trend .peak .v{font-size:var(--text-sub);font-weight:var(--weight-sub);margin-top:0}
.trend .peak .k{display:inline}

/* ── chart (U-31, 20/09) · séries no tempo com o zero na base: barras lado a lado, empilhadas,
   sobrepostas ou penduradas, e linhas — no eixo da esquerda ou numa porcentagem à direita ── */
.chart{width:100%}
.chart .plot{display:grid;grid-template-columns:3.6em minmax(0,1fr);column-gap:var(--space-2)}
.chart.r .plot{grid-template-columns:3.6em minmax(0,1fr) 3.75em}
.chart svg{display:block;width:100%;height:auto;cursor:crosshair}
.chart .ticks{position:relative;font-family:var(--mono);font-size:var(--text-label);color:var(--ink-4);font-variant-numeric:tabular-nums;text-align:right}
.chart .ticks span{position:absolute;right:0;top:calc(var(--y) * 100%);transform:translateY(-50%);white-space:nowrap}
.chart .ticks.end{text-align:left}.chart .ticks.end span{right:auto;left:0} /* `end`, não `right`: `.right` é utilidade de alinhamento */
.chart .gl{stroke:var(--chart-grid);stroke-width:1;vector-effect:non-scaling-stroke}
.chart .gl.zero{stroke:var(--ink-4)}
.chart .bar.partial,.chart .line.partial,.chart .pt.partial{opacity:var(--chart-partial)} /* o período em curso: mais claro, para não ler como queda */
.chart .hit{fill:transparent}
.chart .hit:hover{fill:var(--acc-tint)} /* a coluna sob o mouse — o <title> dela é a dica */
.chart .bar:hover,.chart .pt:hover{opacity:.8}
.chart .bar.s-sel{fill:var(--sel)}.chart .bar.s-success{fill:var(--success-dot)}.chart .bar.s-danger{fill:var(--danger-dot)}.chart .bar.s-ink{fill:var(--chart-bar)}
.chart .line.halo{stroke:var(--paper);stroke-width:4}
.chart .line{fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.chart .line.s-sel{stroke:var(--sel)}.chart .line.s-success{stroke:var(--success-dot)}.chart .line.s-danger{stroke:var(--danger-dot)}.chart .line.s-ink{stroke:var(--ink-2)}
.chart .area{stroke:none}
.chart .area.s-sel{fill:var(--acc-tint)}.chart .area.s-success{fill:var(--success-soft)}.chart .area.s-danger{fill:var(--danger-soft)}.chart .area.s-ink{fill:var(--flat)}
.chart .pt{fill:var(--paper);stroke-width:1.5;vector-effect:non-scaling-stroke}
.chart .pt.s-sel{stroke:var(--sel)}.chart .pt.s-success{stroke:var(--success-dot)}.chart .pt.s-danger{stroke:var(--danger-dot)}.chart .pt.s-ink{stroke:var(--ink-2);fill:var(--ink-2)}
.chart .lbls{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;margin-top:var(--space-2);margin-left:calc(3.6em + var(--space-2));overflow:hidden}
.chart.r .lbls{margin-right:calc(3.75em + var(--space-2))}
.chart .lbls span{text-align:center;font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-4);font-weight:var(--weight-label);white-space:nowrap} /* os rótulos são amostrados pela função; o contêiner corta o excesso */
.chart .head{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:var(--space-3) var(--space-4);margin-bottom:var(--space-4)}
.chart.tall .head{margin-bottom:var(--space-5)}
.chart .now{display:flex;align-items:baseline;gap:var(--space-2)}
.chart .now .k{display:inline}
.chart .now .v{font-size:var(--text-kpi-sm);font-weight:var(--weight-kpi);letter-spacing:var(--track-kpi);line-height:var(--lead-kpi);font-variant-numeric:tabular-nums}
.chart.tall .now .v{font-size:var(--text-kpi);font-weight:var(--weight-kpi);letter-spacing:var(--track-kpi);line-height:var(--lead-kpi)} /* o gráfico principal da página: o número de agora é o maior da tela */
.chart .legend{display:flex;flex-wrap:wrap;gap:var(--space-4);margin-left:auto;font-size:var(--text-small);color:var(--ink-3)}
.chart .legend span{display:inline-flex;align-items:center;gap:var(--space-2)}
.chart .sw{display:inline-block;width:10px;height:10px;border-radius:var(--radius-control)}
.chart .sw.line{height:2px}.chart .sw.line.s-ink{background:var(--ink-2)}.chart .sw.partial{opacity:var(--chart-partial)}
.chart .sw.s-sel{background:var(--sel)}.chart .sw.s-success{background:var(--success-dot)}.chart .sw.s-danger{background:var(--danger-dot)}.chart .sw.s-ink{background:var(--chart-bar)}
.chart .head .ctl{margin-left:auto} /* ← 15/10 · os controles do período em cima, junto do desenho que mudam */
.chart>.legend{margin:var(--space-4) 0 0 calc(3.6em + var(--space-2))} /* ← 15/10 · com controles, a legenda desce para baixo do eixo: na mesma linha, as duas se acumulavam nas colunas estreitas (Victor) */
.chart .ctl .row{gap:var(--space-2) var(--space-3)}

/* ── kpi-tabs (U-31, 15/10) · abas-indicador: cada aba é um KPI e escolhe a série do gráfico grande abaixo;
   a marcada leva o fio do acento em cima. Botões com aria-pressed, como o fchip ── */
.kpi-tabs{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);border-bottom:var(--hair) solid var(--line);margin-bottom:var(--space-5)}
.kpi-tab{appearance:none;background:none;border:0;border-top:calc(var(--hair) * 2) solid transparent;border-right:var(--hair) solid var(--line);font:inherit;color:inherit;text-align:left;cursor:pointer;padding:var(--space-4) var(--space-5) var(--space-5);display:flex;flex-direction:column;min-width:0}
.kpi-tab:first-child{padding-left:0}
.kpi-tab:last-child{border-right:0}
.kpi-tab:hover{background:var(--flat)}
.kpi-tab:first-child:hover{background:none}
.kpi-tab[aria-pressed="true"]{border-top-color:var(--sel)}
.kpi-tab[aria-pressed="true"] .k{color:var(--sel-deep)}
.kpi-tab:focus-visible{outline:var(--focus-ring-width) solid var(--focus-ring);outline-offset:var(--focus-ring-offset)}
.kpi-tab .k{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--kpi-label-ink)}
.kpi-tab .value{font-size:var(--text-kpi-sm);font-weight:var(--weight-kpi);letter-spacing:var(--track-kpi);line-height:var(--lead-kpi);font-variant-numeric:tabular-nums;margin-top:var(--space-2)}
.kpi-tab .value small{font-size:.5em;font-weight:500;color:var(--ink-4);letter-spacing:0;margin-left:2px}
.kpi-tab .delta{margin-top:var(--space-2);font-family:var(--mono);font-size:var(--text-small);color:var(--kpi-delta-ink)}
.kpi-tab .delta.up{color:var(--kpi-delta-up)}.kpi-tab .delta.down{color:var(--kpi-delta-down)}
@media (max-width:760px){.kpi-tabs{grid-auto-flow:row}.kpi-tab{border-right:0;border-bottom:var(--hair) solid var(--line);padding-left:0}.kpi-tab:last-child{border-bottom:0}}

/* ─── Painel de conexões (ao lado do conector) ← I-10 · mínimo: nome + estado por linha; detalhes num dropdown ─── */
.conns{border-left:var(--hair) solid var(--line-mid);padding:var(--space-2) 0 var(--space-2) var(--space-6);height:100%;display:flex;flex-direction:column;justify-content:center}
.conns .k{margin-bottom:var(--space-3)}
.conns details{border-top:var(--hair) solid var(--line)}
.conns details:last-of-type{border-bottom:var(--hair) solid var(--line)}
.conns summary{list-style:none;display:flex;align-items:center;gap:var(--space-3);height:var(--row-height);cursor:pointer}
.conns summary::-webkit-details-marker{display:none}
.conns summary .name{font-weight:500;flex:1}
.conns summary .caret{color:var(--ink-4);width:20px;display:inline-flex;justify-content:center;transition:transform var(--dur) var(--ease)}
.conns details[open] summary .caret{transform:rotate(180deg)}
.conns .dbody{display:grid;grid-template-columns:auto 1fr;column-gap:var(--space-4);row-gap:6px;padding:0 0 var(--space-3);font-size:var(--text-small);color:var(--ink-2)}
.conns .dbody .k{margin:0;padding-top:2px}
.conns .dbody .mono{font-size:var(--text-code)}
.conns .dbody .act{grid-column:1 / -1;margin-top:4px;justify-self:start}

/* ─── Janela, drawer, scrim ← U-28 ─── */
/* Camadas: scrim e drawer são fixed e precisam de z-index EXPLÍCITO, senão ficam em auto e qualquer conteúdo com
   z-index:1 (o nó do diagrama .flow .node .box, por exemplo) passa por cima delas — foi o que aconteceu na TL-E06
   (Victor, 04/09/2026): "Your website" e "Your ChMS" brancos sobre o scrim. A escala: conteúdo < 10 ≤ camada < 20 ≤
   flutuante (tooltip, proto-bar), para um tooltip dentro de uma janela ainda aparecer. */
.scrim{position:fixed;inset:0;background:var(--scrim);display:grid;place-items:center;padding:var(--space-6);z-index:10}
.window{background:var(--paper);border:var(--window-border) solid var(--window-color);border-radius:var(--radius-surface);width:min(100%,var(--window-width-md));padding:var(--space-5) var(--space-6);max-height:100%;overflow-y:auto} /* ← 20/09 · janela mais alta que a tela (17 caixas de eventos) rola por dentro; antes o rodapé ficava fora do alcance */
.window.sm{width:min(100%,var(--window-width-sm))}.window.lg{width:min(100%,var(--window-width-lg))}
.window .head{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-4);margin-bottom:var(--space-4)}
.window .head h2{font-size:var(--text-section);font-weight:var(--weight-section);letter-spacing:var(--track-section);line-height:var(--lead-section)}
.window .foot{display:flex;justify-content:space-between;align-items:center;gap:var(--space-2);margin-top:var(--space-5);padding-top:var(--space-4);border-top:var(--hair) solid var(--line)}
/* ─── O modal do doador ← U-28b · decisão Victor 14/09/2026: "obrigatoriamente essa estrutura e proporções",
   as da Socure (DocV) e da Pinwheel (Link), Figma 53:149. Cartão 350×683, raio 8, corpo com ações empilhadas
   no pé, rodapé de 47px "powered by roster". Sem cabeçalho: o fechar é do quadro que o hospeda. ─── */
.modal{width:min(100%,var(--modal-width));height:var(--modal-height);background:var(--paper);border:var(--window-border) solid var(--window-color);border-radius:var(--radius-modal);display:flex;flex-direction:column;overflow:hidden}
.modal .body{flex:1;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-6) var(--space-5) var(--space-5)}
.modal .body h2{font-size:var(--text-section);font-weight:var(--weight-section);letter-spacing:var(--track-section);line-height:var(--lead-section)}
.modal .body .hsteps{margin-bottom:var(--space-2)}
.modal .actions{margin-top:auto;padding-top:var(--space-4);display:flex;flex-direction:column;gap:var(--space-2)}
.modal .actions .btn{width:100%;justify-content:center;white-space:normal;height:auto;min-height:var(--btn-height);padding-top:var(--space-2);padding-bottom:var(--space-2);text-align:center;line-height:1.35} /* rótulo longo quebra linha dentro dos 350px, não vaza */
.modal .body.center{justify-content:center;text-align:center;align-items:center}
.modal .body.center .actions{width:100%;margin-top:var(--space-5)}
.modal .ring{width:var(--modal-ring);height:var(--modal-ring);border:2px solid var(--sel);border-radius:var(--radius-full);display:grid;place-items:center;color:var(--sel);margin:0 auto var(--space-4)}
.modal .ring .ico{width:56px;height:56px}
.modal .ring.warn{border-color:var(--warning);color:var(--warning)}.modal .ring.bad{border-color:var(--danger);color:var(--danger)}
.modal .powered{flex:none;height:var(--modal-foot);border-top:var(--hair) solid var(--line-mid);display:flex;align-items:center;justify-content:center;gap:6px;font-size:var(--text-label);color:var(--ink-5)}
.modal .powered .wordmark{display:inline-block;width:45px;height:12px;background:url(marca/roster-wordmark.svg) center/contain no-repeat} /* a única cor de marca do produto entra como imagem da lei, não como <img> no conteúdo (U-56) */
.drawer{position:fixed;top:0;right:0;bottom:0;z-index:10;width:min(100%,var(--drawer-width));background:var(--paper);border-left:var(--window-border) solid var(--window-color);padding:var(--space-5) var(--space-6);overflow:auto;border-radius:var(--radius-surface)}

/* ─── Toast, tooltip, loading ← U-39, U-40 ─── */
.toast{position:fixed;left:var(--space-5);bottom:var(--space-5);z-index:5;background:var(--paper);border:var(--window-border) solid var(--window-color);padding:var(--space-3) var(--space-4);display:flex;gap:var(--space-4);align-items:center;max-width:420px;border-radius:var(--radius-surface)}
.toast .k{color:var(--ink)}
.tip{display:inline-block;background:var(--paper);border:var(--hair) solid var(--window-color);padding:4px 8px;font-size:12px;border-radius:var(--radius-surface)}
/* ── Raio nos componentes que não tinham (Victor, 04/09/2026, ao pedir a direção D): callout, tip, toast,
   drawer, thumb, note e code recebem --radius-surface; code-chip, progress e skel recebem --radius-control.
   Na A continua 0 — nada muda. Na D vira 3px, e a direção passa a valer para TODO componente retangular,
   não só para os que já tinham token. Círculos ficam círculos (avatar, ponto, rádio, toggle, pulso):
   I-14 e U-17. Regiões de página (tarja, barra lateral, topo) e linhas (kpi, abas, rodapé) não são
   componentes com canto e não entram. ── */
/* ── Foto de contexto congregacional (U-34) · `.picture`, não `.shot`: a lei do
   pivot-dizimo já usa `.index .shot` para as miniaturas do índice (colisão de nome) ────────────────────────────────────────────────────────────
   Nada sobre as pessoas: até 02/10/2026 havia aqui `.pick`, uma moldura com alças sobre cada pessoa
   com contracheque. No teste de usabilidade do Brunno ela foi lida como reconhecimento facial
   ("pode passar impressão de vigilância"), na primeira tela que toda igreja e todo parceiro vê — e
   marcar quem tem contracheque é o que a doação discreta evita. Saiu da lei (U-34). O véu é tinta
   chapada com opacidade (U-07 proíbe o gradiente do site).

   .cover-box reproduz a geometria de object-fit:cover em coordenada de IMAGEM, com o ponto de
   recorte (`--pos-x`, `--pos-y`) que cada tela escolhe. `--ar` é a proporção intrínseca do arquivo. */
.picture{position:relative;overflow:hidden}
.picture .cover-wrap{position:absolute;inset:0;overflow:hidden;container-type:size}
.picture .cover-box{position:absolute;left:var(--pos-x,50%);top:var(--pos-y,50%);
  translate:calc(-1 * var(--pos-x,50%)) calc(-1 * var(--pos-y,50%));
  width:max(100cqw,100cqh * var(--ar));height:max(100cqh,100cqw / var(--ar))}
.picture .cover-box > img{display:block;width:100%;height:100%}
.picture .veil{position:absolute;inset:0;background:var(--ink);opacity:var(--picture-veil,.42)}
.picture .body{position:relative}

/* ── Ajuda sob demanda (Victor, 04/09/2026): a explicação sai da tela e entra num `?` que abre o tooltip.
   Reduz a carga de leitura sem apagar a informação — ela continua a um hover ou a um Tab de distância.
   Visual do tooltip é o da U-40 (papel, borda 1px tinta, 12px, sem seta, sem sombra); o `?` é controle,
   então pode ser ícone (U-10). Abre no CLIQUE ou no Tab (:focus-within), nunca no hover: no teste do
   Brunno (02/10, P04) o balão do Glossary abriu sozinho na rolagem e cobriu o texto que ele lia. Fecha
   com clique fora e ao abrir outro (o foco sai); Esc e o segundo clique no `?` são da `bindHelp`.
   É QUADRADO, com o raio de controle — não círculo: a U-17 e o I-14 fecham "círculo só em avatar e
   ponto de estado", e o gatilho de ajuda não é nenhum dos dois. Com `--radius-control` ele herda a
   direção em vez de escapar dela (0 na A, 3px na D). Apontado pela instância do pivot-dizimo, 04/09. ── */
.help{position:relative;display:inline-flex;align-items:center;justify-content:center;width:var(--ico-size-sm);height:var(--ico-size-sm);margin-left:var(--space-2);vertical-align:middle;line-height:1;color:var(--ink-4);cursor:help;user-select:none} /* ← 15/10 · o (i), sem caixa: o `?` quadrado pesava ao lado de cada título (Victor) */
.help:hover,.help:focus-within{color:var(--ink)}
.help .tip{display:none;position:absolute;top:calc(100% + 6px);left:0;z-index:20;width:max-content;max-width:38ch;text-align:left;font-family:var(--sans);font-size:12px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--ink-2);line-height:1.45;border-color:var(--ink);white-space:normal}
.help:focus-within .tip{display:block}
.help[data-closed] .tip{display:none} /* ← 02/10 · Esc ou o segundo clique fecham sem tirar o foco do `?` (WCAG 1.4.13); perder o foco limpa */
/* Linked help opens by click or keyboard, keeping its article link reachable. */
.help.linked{display:block;width:auto;height:auto;border:none;margin-left:0;flex-shrink:0}
.help.linked summary{display:grid;place-items:center;width:var(--ico-size-lg);height:var(--ico-size-lg);list-style:none;color:var(--ink-4);border-radius:var(--radius-control);cursor:pointer} /* a área de toque segue 24px (WCAG 2.5.8); o desenho é o ícone de 16 */
.help.linked summary:hover,.help.linked[open] summary{color:var(--ink)}
.help.linked summary:focus-visible{outline:var(--focus-ring-width) solid var(--focus-ring);outline-offset:var(--focus-ring-offset)}
.help.linked summary::-webkit-details-marker{display:none}
.help.linked .tip{display:none;top:100%;max-width:none;width:32ch;padding:var(--space-4);line-height:var(--lead-body);font-size:var(--text-body)}
.help.linked[open] .tip{display:block}
.help.linked .tip p{margin:0 0 var(--space-3);font-size:inherit;color:var(--ink-2)}
.help.linked .tip a{display:inline-block;color:var(--sel-deep);font-weight:var(--weight-label)}
@media(max-width:700px){.help.linked .tip{position:fixed;top:auto;bottom:var(--space-4);left:var(--space-4);right:var(--space-4);width:auto;max-height:60vh;overflow:auto}}
.loading-line{position:fixed;top:0;left:0;height:var(--rule);width:30%;background:var(--ink);animation:load 1.2s var(--ease) infinite}
@keyframes load{from{left:-30%}to{left:100%}}
.skel{background:var(--flat);height:1em;display:block;border-radius:var(--radius-control)}

/* ─── Estado vazio ← U-13, U-34 ─── */
.empty{padding:var(--space-6) 0;max-width:52ch}
.empty h3{margin-bottom:var(--space-2)}
.empty p{color:var(--ink-3);margin-bottom:var(--space-4)}

/* ─── Utilidades de espaço ─── */
.mt-2{margin-top:var(--space-2)}.mt-3{margin-top:var(--space-3)}.mt-4{margin-top:var(--space-4)}.mt-5{margin-top:var(--space-5)}.mt-6{margin-top:var(--space-6)}
.row{display:flex;align-items:center;gap:var(--space-3)}.row.between{justify-content:space-between}.row.wrap{flex-wrap:wrap}
.muted{color:var(--ink-4)}.small{font-size:var(--text-small)}
.right{margin-left:auto}


/* ═══════════════════════════════════════════════════════════════════
   Componentes adicionados em 2026-09-03 (tarde) para cobrir o inventário do v1
   — ver INVENTARIO.md (v1 → v2, tela onde está aplicado). Mesma lei, nenhum valor cru.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── Menu de linha (⋯) e popover ← U-28, U-40: papel com borda, sem sombra ─── */
.menu{position:relative;display:inline-block}
.menu .pop{position:absolute;right:0;top:calc(100% + 4px);min-width:200px;background:var(--paper);border:var(--hair) solid var(--window-color);padding:var(--space-1) 0;z-index:5;text-align:left}
.menu .pop a{display:block;padding:8px var(--space-4);color:var(--ink);text-decoration:none;font-size:var(--text-body);cursor:pointer} /* ← a mão também sem href (a opção da lista do endereço) */
.search-hits{display:flex;flex-direction:column;margin-top:var(--space-3);max-height:60vh;overflow:auto;min-width:0} /* ← 02/10 · teste do Brunno (P13): resultados em duas linhas, agrupados; antes uma linha só, mais larga que a janela */
.search-group{margin:var(--space-4) 0 var(--space-1)}.search-group:first-child{margin-top:0}
.search-hit{display:block;width:100%;min-width:0;text-align:left;background:none;border:0;border-radius:var(--radius-control);padding:var(--space-2) var(--space-3);color:var(--ink);font:inherit;cursor:pointer}
.search-hit:hover{background:var(--flat)}
.search-hit .t{display:block;font-weight:var(--weight-strong);overflow-wrap:anywhere}
.search-hit .out{color:var(--ink-4);margin-left:var(--space-1)}
.search-hit .d{display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin-top:2px;color:var(--ink-3);font-size:var(--text-small)}
.empty .row>.btn.tertiary{padding-inline:0} /* ← 02/10 · loop 1 de crítica: o terciário que desce de linha no celular começava 5px à direita da margem */
.sec-body>.empty{padding-top:var(--space-2)} /* ← 02/10 · loop 1: dentro de uma seção, o vazio ficava ~48px abaixo do h2 e o título soltava */
.kpis>*{min-width:0} /* ← 02/10 · loop 2: um caminho longo em mono dentro de um KPI empurrava a coluna para fora da tela a 375 */
@media (max-width:600px){.kpis{grid-template-columns:1fr}} /* ← 02/10 · loop 2: "Not measured" em duas colunas de 170px não cabia */
.menu .pop a:hover{background:var(--flat)}
.menu .pop a.is-na{color:var(--ink-5);cursor:not-allowed}
.menu .pop a.is-na:hover{background:transparent}
.menu .pop .sep{border-top:var(--hair) solid var(--line);margin:var(--space-1) 0}
.menu .pop .k{padding:6px var(--space-4) 2px}
.menu .pop .v{padding:0 var(--space-4) 6px;margin-top:0} /* ← U-28 · a linha de fato do dropdown da conta */
/* O dropdown da CONTA abre sob a coluna da barra lateral, não sob um `···` no fim da linha:
   ancora à esquerda e tem a largura da coluna. ← U-24, 11/09/2026 */
.accountwrap{display:flex;align-items:stretch;flex-shrink:0}
.accountwrap .menu{display:flex;align-items:stretch}
.accountwrap .pop{left:var(--space-4);right:auto;min-width:calc(var(--sidebar-width) - var(--space-5))}
/* ─── Avisos da conta: o sino e o painel ← U-28, U-40 · 03/10 · Jam do Rafael ("notificações não estão
   funcionando, gostaria de ter"). O painel é o `.menu .pop` — papel com borda, sem sombra —, na largura de
   uma coluna de leitura; cada aviso é um link: título, o chip do estado quando há, e o detalhe em tom de apoio. */
.notices .pop{width:min(360px,calc(100vw - 2 * var(--space-4)));max-height:min(70vh,560px);overflow-y:auto;padding:0 0 var(--space-1)}
.notices .pop > .k{display:block;padding:var(--space-3) var(--space-4) var(--space-2)}
.notices .pop a.notice{display:grid;row-gap:2px;padding:var(--space-3) var(--space-4);border-top:var(--hair) solid var(--line)}
.notice .notice-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}
.notice .notice-title{font-weight:var(--weight-strong);color:var(--ink);min-width:0}
.notice .notice-head .chip{flex-shrink:0}
.notice .notice-detail{font-size:var(--text-small);line-height:var(--lead-small);color:var(--ink-4);overflow-wrap:anywhere}
.notices .notice-empty{padding:var(--space-2) var(--space-4) var(--space-3);font-size:var(--text-small);color:var(--ink-4)}

/* ─── Ordenação e paginação de tabela ← U-14, U-38 ─── */
th.sort{cursor:pointer}
th.sort .dir{margin-left:4px;color:var(--ink-5);display:inline-flex;vertical-align:middle}
th.sort[aria-sort]{color:var(--ink)}
th.sort[aria-sort] .dir{color:var(--ink)}
.table-foot{display:flex;justify-content:space-between;align-items:center;gap:var(--space-4);padding-top:var(--space-3);border-top:var(--hair) solid var(--line);margin-top:0;font-family:var(--mono);font-size:11.5px;color:var(--ink-4)}
.pager{display:inline-flex;gap:var(--space-1);font-family:var(--mono);font-size:11.5px}
.pager a{display:inline-grid;place-items:center;min-width:28px;height:28px;padding:0 6px;color:var(--ink-4);text-decoration:none;border:var(--hair) solid transparent;border-radius:var(--radius-control)}
.pager a:hover{background:var(--flat)}
.pager a[aria-current]{color:var(--sel-deep);border-color:var(--sel);background:var(--sel-soft);font-weight:700}
.table-empty{padding:var(--space-6) 0;color:var(--ink-4);font-size:var(--text-body);border-bottom:var(--hair) solid var(--line)}

/* ─── Filtros: busca, chips de filtro, seletor ← U-38, U-22 ─── */
.filters{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap}
.filters .input{width:280px}
.fchips{display:inline-flex;gap:var(--space-1)}
.fchip{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 var(--space-3);font-size:var(--text-small);color:var(--ink-3);text-decoration:none;border:var(--hair) solid var(--line-mid);border-radius:var(--radius-control)}
.fchip:hover{background:var(--flat)}
.fchip[aria-pressed="true"]{color:var(--sel-deep);border-color:var(--sel);background:var(--sel-soft);font-weight:var(--weight-strong)}
.fchip .count{font-family:var(--mono);font-size:10.5px;color:var(--ink-5)}
.fchip[aria-pressed="true"] .count{color:var(--ink-3)}
.badge{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;font-family:var(--mono);font-size:10px;font-weight:700;border:var(--hair) solid var(--ink);border-radius:var(--radius-control);vertical-align:middle}
.badge.acc{border-color:var(--acc);color:var(--acc-deep);background:var(--acc-soft)}
.badge.warn{border-color:var(--warning);color:var(--warning);background:var(--warning-soft)}

/* ─── Dropzone tracejada (Setup 4.6 / 4.8, Branding) — o traço É a affordance ← lo-fi ─── */
.drop{border:var(--hair) dashed var(--ink-5);padding:var(--space-4) var(--space-5);display:grid;grid-template-columns:1fr auto;align-items:center;gap:var(--space-4)}
.drop + .drop{margin-top:var(--space-3)}
.drop .name{font-weight:var(--weight-strong)}
.drop .req{font-family:var(--mono);font-size:11px;color:var(--ink-4);margin-top:2px}
.drop.done{border-style:solid;border-color:var(--success)}
.drop.done .req{color:var(--ink-3)}

/* ─── Stepper horizontal e pontos (Donor Flow) ← U-25, U-31 ─── */
.hsteps{display:flex;align-items:center;gap:var(--space-3);font-family:var(--mono);font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-4)}
.dots{display:inline-flex;gap:6px}
.dots i{width:6px;height:6px;border-radius:var(--radius-full);border:var(--hair) solid var(--ink)}
.dots i.on{background:var(--ink-5);border-color:var(--ink-5)}
.dots i.now{background:var(--sel);border-color:var(--sel)}

/* ─── Progresso determinado e funil ← U-31, U-39 ─── */
.progress{height:var(--rule);background:var(--line);position:relative;border-radius:var(--radius-control)}
.progress i{position:absolute;left:0;top:0;bottom:0;background:var(--sel)}
.progress-label{display:flex;justify-content:space-between;font-family:var(--mono);font-size:11px;color:var(--ink-4);margin-top:6px}
.funnel .row{display:grid;grid-template-columns:200px 1fr 72px;column-gap:var(--space-4);align-items:center;padding:var(--space-2) 0;border-bottom:var(--hair) solid var(--line)}
.funnel .row:last-child{border-bottom:none}
.funnel .bar{height:14px;background:var(--flat);position:relative}
.funnel .bar i{position:absolute;left:0;top:0;bottom:0;background:var(--ink-5)}
.funnel .row.current .bar i{background:var(--sel)}
.funnel .n{font-family:var(--mono);font-size:var(--text-code);text-align:right;font-variant-numeric:tabular-nums}

/* ─── Switch de ambiente (topbar) ← U-29 ─── */
.envswitch{display:inline-flex;align-items:center;gap:var(--space-2);height:28px;padding:0 var(--space-3);border:var(--hair) solid var(--line-mid);border-radius:var(--radius-control);font-family:var(--mono);font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-3);text-decoration:none}
.envswitch .dot{width:6px;height:6px;border-radius:var(--radius-full);background:var(--warning-dot)}
[data-env="production"] .envswitch .dot{background:var(--success-dot)}
.envswitch .caret{font-family:var(--mono)}

/* ─── Promo / referral na topbar ← U-21 (é ação secundária, não atenção) ───
   A borda era `--ink`: a mais forte do sistema, mais escura até que a do
   Primary (`--acc-deep`), num elemento que o comentário acima já chamava de
   secundário. O desenho contradizia a própria regra que citava. Victor
   apontou em 08/09/2026 — agora usa `--btn2-color`, o token do Secondary, que
   é o que a U-21 manda para "as outras ações".

   O componente virou um GRUPO: o convite, o gatilho de ajuda e o fechar. Um
   `<a>` não pode conter outro elemento interativo, então a caixa passa a ser a
   moldura e os três moram dentro dela. A marcação antiga (`<a class="promo">`)
   continua válida e só não ganha os dois novos — é o que as 27 telas do
   pivot-dizimo usam, e elas não quebram. ── */
.promo{display:inline-flex;align-items:center;gap:var(--space-2);padding:var(--space-2);color:var(--acc-deep);font-weight:500;border-radius:var(--radius-control)} /* ← 15/10 (DB-12) · era --primary-ink, que virou branco com o primário preenchido; o roxo profundo é o de sempre */
/* `display` explícito vence o `[hidden]` do navegador. Sem esta linha o botão
   de fechar não fecha — e o defeito é silencioso, porque o atributo entra. */
.promo[hidden]{display:none}
.promo a{color:inherit;text-decoration:none}
.promo .amt{font-weight:inherit} /* ← decisão Victor 11/09: o $500 não precisa de negrito */
.promo:hover{background:var(--flat)}
.promo .help{margin-left:0} /* o gap do grupo já dá o espaço */
.promo .off{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;background:none;border:0;font-family:var(--mono);font-size:13px;line-height:1;color:var(--ink-4);cursor:pointer}
.promo .off:hover{color:var(--ink)}
/* ← U-40 (08/09) · a explicação do convite aparece no hover/foco do próprio convite, como o tooltip do .help; sem (i), sem fechar */
.promo{position:relative}
.promo .tip{display:none;position:absolute;top:calc(100% + 6px);right:0;z-index:20;width:max-content;max-width:38ch;text-align:left;font-family:var(--sans);font-size:12px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--ink-2);line-height:1.45;border-color:var(--ink);white-space:normal}
.promo:hover .tip,.promo:focus-within .tip{display:block}

/* ─── Dashboard simulado: véu + rótulo ← U-30 (opacidade), BRIEF §4 ─── */
.fake{position:relative}
.fake .veil{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none}
.fake .veil .chip{background:var(--paper)}
.fake.is-moving .stage{filter:blur(var(--sample-blur));transition:filter var(--dur) var(--ease)}
.fake .stage{transition:filter var(--dur) var(--ease)}

/* ─── Barra de moderador (?notes=1) e anotações — chrome de protótipo, não do produto ─── */
.proto-bar{position:fixed;left:0;right:0;bottom:0;height:36px;background:var(--ink);color:var(--paper);display:flex;align-items:center;gap:var(--space-4);padding:0 var(--space-5);font-family:var(--mono);font-size:11px;letter-spacing:.04em;z-index:20}
.proto-bar a{color:var(--paper);text-decoration:none;opacity:.7}
.proto-bar a:hover,.proto-bar a[aria-current]{opacity:1;text-decoration:underline;text-underline-offset:3px}
.proto-bar .tag{border:var(--hair) solid var(--paper-a40);padding:1px 6px;text-transform:uppercase}
.note{border:var(--hair) solid var(--acc);background:var(--acc-tint);padding:var(--space-2) var(--space-3);font-size:var(--text-small);color:var(--acc-deep);margin-top:var(--space-3);border-radius:var(--radius-surface)}
.note .k{color:var(--acc-deep)}

/* ─── Fronteira de terceiro (Plaid, Scalar, Broward) — fora do DS, marcada ─── */
.third-party{border:var(--hair) solid var(--line-mid);position:relative;padding:var(--space-5);background:var(--paper);margin-top:var(--space-5)} /* o rótulo do vendor fica acima da moldura: precisa do respiro */
.third-party::before{content:attr(data-vendor) " · third-party UI, rendered as-is";position:absolute;top:calc(-1 * var(--space-4));left:0;font-family:var(--mono);font-size:var(--text-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--ink-5)}
.third-party.quiet::before{content:none} /* ← U-44 · quando o terceiro É a página (docs), o rótulo sobra; a moldura fica */
.third-party.quiet{margin-top:0}
.third-party .ph{background:var(--flat);display:grid;place-items:center;color:var(--ink-5);font-family:var(--mono);font-size:11px;min-height:120px}

/* ─── Banner de conclusão com fotografia ← U-34 ─── */
.done-band{display:grid;grid-template-columns:repeat(12,1fr);column-gap:var(--grid-gap);border-top:var(--rule) solid var(--ink)}
.done-band .photo{grid-column:span 5;background:var(--flat);min-height:280px;position:relative;overflow:hidden}
.done-band .photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block} /* ← U-34 (08/09) · a fotografia ocupa o slot; nada inline na tela */
.done-band .photo .k{z-index:1;color:var(--paper)}
.done-band .photo .k{position:absolute;left:var(--space-4);bottom:var(--space-4)}
.done-band .text{grid-column:span 7;padding:var(--space-6) 0 var(--space-6) var(--space-4)}
.done-band h2{font-size:var(--text-page);font-weight:var(--weight-page);letter-spacing:var(--track-page);line-height:var(--lead-page)}

/* ─── Bloco de chave/valor de revisão (Setup 4.9) e lista de bloqueios (Unlock) ─── */
.review .kv{row-gap:var(--space-2)}
.review .group{padding:var(--space-4) 0;border-bottom:var(--hair) solid var(--line)}
.review .group:last-child{border-bottom:none}
.review .group .row.between{margin-bottom:var(--space-2)}
.locks{list-style:none}
.locks li{display:grid;grid-template-columns:1fr auto;gap:var(--space-4);padding:var(--space-3) 0;border-bottom:var(--hair) solid var(--line);align-items:center}
.locks li:last-child{border-bottom:none}
.locks .name{font-weight:var(--weight-strong)}
.locks .hint{margin-top:2px}

/* ─── Swatch, miniatura, aba de editor (Branding) ← U-26 ─── */
.swatch{display:grid;grid-template-columns:36px 1fr;column-gap:var(--space-3);align-items:center}
.swatch i{width:36px;height:36px;border:var(--hair) solid var(--line-mid);display:block}
.swatch .hex{font-family:var(--mono);font-size:var(--text-code)}
.thumbs{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-4)}
.thumb{border:var(--hair) solid var(--line-mid);padding:var(--space-3);text-decoration:none;color:var(--ink);display:block;border-radius:var(--radius-surface)}
.thumb .box{background:var(--flat);aspect-ratio:4/3;display:grid;place-items:center;font-family:var(--mono);font-size:var(--text-label);letter-spacing:.06em;color:var(--ink-5);text-transform:uppercase;margin-bottom:var(--space-3)}
.thumb[aria-current]{border:1.5px solid var(--sel)}
.thumb .name{font-weight:var(--weight-strong);font-size:var(--text-body)}

/* ─── Chip de código / API key com Copy ← U-30 ─── */
.code-chip{display:inline-flex;max-width:100%;min-width:0;align-items:center;gap:var(--space-3);background:var(--flat);padding:6px var(--space-3);font-family:var(--mono);font-size:var(--text-code);border-radius:var(--radius-control)}
.code-chip .btn{height:24px;padding:0 var(--space-2);font-size:11px;flex-shrink:0}
.code-chip>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap} /* ← 20/09 · a URL longa não estoura o card */
.code-chip .mask{letter-spacing:.15em}

/* ─── Disclosure (2.1b, docs) ← U-25 ─── */
.disc{border-top:var(--hair) solid var(--line)}
.disc:last-child{border-bottom:var(--hair) solid var(--line)}
.disc > summary{list-style:none;display:grid;grid-template-columns:1fr auto auto;column-gap:var(--space-4);align-items:center;padding:var(--space-3) 0;cursor:pointer;font-weight:var(--weight-strong)}
.disc > summary::-webkit-details-marker{display:none}
.disc > summary .caret{display:inline-flex;color:var(--ink-4);transition:transform var(--dur) var(--ease);grid-column:3} /* ← U-10, 01/10 · o caret é `icon()`, não mais o `⌄` em mono. ← 03/10 · Jam do Rafael: a seta mora SEMPRE na terceira coluna — sem o dado do meio ela caía na segunda e ficava 16px fora do alinhamento das outras ("Connect a coding agent", "General customization") */
.disc[open] > summary .caret{transform:rotate(180deg)}
.disc .body{padding:0 0 var(--space-4)}

/* ─── Nós da faixa: variante ampla com painel (7.1 do parceiro) ─── */
.flow.wide .node .box{width:72px;height:72px}

/* ─── Avatar com foto (placeholder marcado) ─── */
.avatar.photo{background:var(--flat);border-color:var(--line-mid);color:var(--ink-5);font-size:9px}
.avatar.lg{width:40px;height:40px}

/* ─── Divisor "or", link de rodapé, rodapé de auth ─── */
.or{display:flex;align-items:center;gap:var(--space-3);margin:var(--space-4) 0}
.or::before,.or::after{content:"";flex:1;border-top:var(--hair) solid var(--line)}
.or .k{color:var(--ink-5)}
.auth-foot{display:flex;gap:var(--space-4);font-family:var(--mono);font-size:var(--text-label);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-5)}
.auth-foot a{color:inherit;text-decoration:none}
.auth-foot a:hover{color:var(--ink)}

/* ─── Índice das explorações (só localhost) ─── */
.index{max-width:var(--content-max);margin:0 auto;padding:var(--space-7) var(--space-6)}
.index .shots{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-5)}
.index .picture{border:var(--hair) solid var(--line-mid);display:block;text-decoration:none;color:var(--ink)}
.index .shot .pic{aspect-ratio:1440/1000;background:var(--flat) center top / cover no-repeat;border-bottom:var(--hair) solid var(--line)}
.index .shot .cap{padding:var(--space-3) var(--space-4);display:flex;justify-content:space-between;gap:var(--space-3);align-items:baseline}
.index .shot .cap b{font-weight:var(--weight-strong)}
.index .shot:hover{border-color:var(--ink)}

/* U-02: na largura de celular, a navegação ocupa uma linha própria e a folha
   recupera toda a largura. Os mesmos controles permanecem disponíveis. */
@media (max-width:760px){
  /* ← 21/09 · Rafael: "o menu virou um rolo horizontal, é muito ruim". No celular a barra
     lateral some e volta VERTICAL, sob a topbar, pelo botão `.navtoggle`. A topbar fica só com
     o botão, o brasão e o avatar: a busca e as ações "soon" não cabem e não fazem nada ainda. */
  .app{grid-template-columns:minmax(0,1fr);grid-template-rows:auto var(--topbar-height) auto minmax(0,1fr);
    grid-template-areas:"env" "top" "side" "main"}
  .app.solo{grid-template-rows:auto var(--topbar-height) minmax(0,1fr);grid-template-areas:"env" "top" "main"}
  .app .env{height:auto;min-height:var(--env-banner-height);padding:var(--space-2) var(--space-4);flex-wrap:wrap}
  .app .topbar{padding:0 var(--space-4);gap:var(--space-3)}
  .app .tleft{align-items:center;gap:var(--space-2)}
  .app .navtoggle{display:grid}
  .app .navtoggle-input{display:block} /* o mesmo display do `.sr-only`: focável de novo, junto do rótulo */
  .app .topbar .brand{width:auto;padding:0;border-right:none}
  .app .topbar .account{width:auto;padding:0;border-right:none}
  .app .topbar .searchwrap{display:none}
  .app .topbar .right .tact{display:none}
  .app .topbar .right .notices .tact{display:inline-flex} /* ← 03/10 · Jam: o sino agora abre os avisos — fica no celular; o "Feedback?" vai ao menu (`.navmobile`) */
  .app .side{display:none;padding:var(--space-2) 0 var(--space-4);border-right:none;border-bottom:var(--hair) solid var(--line);max-height:min(70vh,560px)}
  .app:has(.navtoggle-input:checked) .side{display:flex}
  .app .side nav a.navsearch{display:flex} /* ← 01/10 · D-16: "pode virar um botão no menu então quando está no celular" — o item abre a mesma busca */
  .app .side nav a.navmobile{display:flex}
  .app .main{padding:var(--space-5) var(--space-4) var(--space-6)}
}

/* Partner donor-flow studio: preview first, configuration beside it. */
.flow-studio {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-8);
  margin-top: var(--space-6);
}
.flow-preview {
  min-width: 0;
  overflow-x: auto; /* ← 01/10 · a prévia não encolhe abaixo do modal mais largo: rola */
}
.flow-preview [data-demo-hint] {
  min-height: calc(2em * var(--lead-body)); /* ← 02/10 · demoPlayer: duas linhas reservadas para a explicação — o quadro não pula entre passos */
}
.flow-preview iframe {
  width: 100%;
  min-width: var(--flow-preview-min-width);
  height: var(--flow-preview-height);
  border: var(--rule) solid var(--line);
  margin-top: var(--space-3);
  background: var(--flat);
}
.flow-controls {
  min-width: 0;
}
.flow-controls > * + * {
  margin-top: var(--space-4);
}
.flow-controls > section.sec.first {
  margin-top: 0; /* ← 02/10 · a coluna abre no topo da demo, como na Donor Flow (o Cancellation descia 32px) */
}
/* ← 03/10 · Jam (Rafael, Donor Flow do parceiro): "consigo clicar em Next aqui enquanto eu vejo
   essa tela". Com a coluna ao lado (`demoPlayer({ aside })`), o passo, Back e Next descem para
   baixo dela, e a tela simulada encolhe (`--flow-preview-scale`). `zoom`, não `transform`: o
   documento do quadro é desenhado de novo no tamanho menor (letra nítida) e a caixa ocupa o
   tamanho que mostra — o `scale` deixava a letra pequena borrada e a largura cheia rolando de
   lado. A borda sai do quadro para a caixa, que não encolhe. A tela e o passo grudam no alto
   (`sticky`): com a personalização aberta, rolar até o Next não leva a tela embora. */
.flow-studio:has(> .flow-steps) {
  grid-template-areas: "preview controls" "preview steps";
  grid-template-rows: auto 1fr;
  row-gap: var(--space-5);
}
.flow-studio:has(> .flow-steps) > .flow-preview {
  grid-area: preview;
  align-self: start;
  position: sticky;
  top: var(--space-5);
  border: var(--rule) solid var(--line);
  background: var(--flat);
}
.flow-studio:has(> .flow-steps) > .flow-preview iframe {
  zoom: var(--flow-preview-scale);
  margin-top: 0;
  border: 0;
}
.flow-studio:has(> .flow-steps) > .flow-controls {
  grid-area: controls;
}
.flow-steps {
  grid-area: steps;
  align-self: start;
  position: sticky;
  top: var(--space-5);
  padding-top: var(--space-5);
  border-top: var(--rule) solid var(--line);
}
.journey-fields {
  display: grid;
  gap: var(--space-3);
}
.journey-map {
  display: flex;
  align-items: center;
  gap: 0;
  min-height: var(--flow-map-height);
  padding-top: var(--space-6);
}
.journey-stage {
  position: relative;
  flex: 1;
  min-width: 0;
}
.journey-stage > .k {
  position: absolute;
  bottom: 100%;
  width: 100%;
  text-align: center;
  margin-bottom: var(--space-4);
}
.journey-choices {
  position: relative;
  display: grid;
  align-items: center;
  justify-items: center;
  grid-auto-rows: 1fr;
  height: var(--flow-map-height);
}
.journey-node {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: var(--control-height-touch);
  min-height: var(--control-height-touch);
  padding: var(--space-2) var(--space-4);
  border: none;
  background: transparent;
  color: var(--ink-3);
  font: inherit;
  cursor: pointer;
}
.journey-node > span:last-child {
  background: var(--paper);
  padding: 0 var(--space-2);
}
.journey-node .journey-dot {
  width: var(--space-5);
  height: var(--space-5);
  background: var(--paper);
  border-color: var(--ink-4);
}
.journey-node[aria-pressed="true"] {
  color: var(--sel-deep);
  font-weight: var(--weight-label);
}
.journey-node[aria-pressed="true"] .journey-dot {
  background: var(--sel);
  border-color: var(--sel);
  outline: var(--space-1) solid var(--sel-soft);
}
.journey-node:focus-visible {
  outline: var(--rule) solid var(--sel);
  outline-offset: var(--space-1);
  border-radius: var(--radius-control);
}
.journey-node:hover .journey-dot {
  border-color: var(--sel);
}
.journey-share {
  font-variant-numeric: tabular-nums;
  font-size: var(--text-body);
  background: var(--paper);
  padding: 0 var(--space-2);
}
.journey-progress {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}
/* ← 02/10 · U-05: o passo diz pela forma, não só pela cor — feito é ponto cheio, o atual é
   cheio com anel, o que falta é oco. Antes, feito e pendente só trocavam a cor do contorno. */
.journey-progress .journey-dot[aria-current="step"] {
  background: var(--sel);
  border-color: var(--sel);
  outline: var(--space-1) solid var(--sel-soft);
}
.journey-progress .journey-dot[data-complete="true"] {
  background: var(--sel);
  border-color: var(--sel);
}
.journey-dot {
  display: inline-block;
  flex-shrink: 0;
  width: var(--space-3);
  height: var(--space-3);
  border: var(--rule) solid var(--ink-4);
  border-radius: var(--radius-full);
}
[aria-pressed="true"] .journey-dot {
  background: var(--sel);
  border-color: var(--sel);
}
.journey-notes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
  padding-top: var(--space-5);
  border-top: var(--rule) solid var(--line);
}
.journey-notes > div {
  min-width: 0;
}
@media (max-width: 1100px) {
  .flow-studio {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* ← 03/10 · com o passo ao lado, as duas colunas só cabem acima de 1320px: abaixo, a coluna da
   tela ficava mais estreita que a tela encolhida (674 × 0,8 + a borda) e rolava de lado. Uma
   coluna: o passo volta para cima da tela, como nas demos da igreja, e nada gruda. */
@media (max-width: 1320px) {
  .flow-studio:has(> .flow-steps) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "steps" "preview" "controls";
    grid-template-rows: none;
    row-gap: var(--space-3);
  }
  .flow-studio:has(> .flow-steps) > .flow-preview,
  .flow-steps {
    position: static;
  }
  .flow-steps {
    padding-top: 0;
    border-top: 0;
  }
  .flow-studio:has(> .flow-steps) > .flow-controls {
    margin-top: var(--space-5);
  }
}
@media (max-width: 760px) {
  /* ← 02/10 · teste do Brunno: no celular a prévia é o celular do doador — o fluxo se
     ajusta à largura (o modal mais largo é coisa de tela grande), em vez de rolar de lado. */
  .flow-preview iframe {
    min-width: 0;
  }
  /* ← 03/10 · no celular a tela simulada não encolhe: ela já é o celular do doador. */
  .flow-studio:has(> .flow-steps) > .flow-preview iframe {
    zoom: initial;
  }
  .journey-map {
    flex-wrap: wrap;
  }
  .journey-node {
    padding-inline: var(--space-1);
  }
  .journey-notes {
    grid-template-columns: 1fr;
  }
}

.journey-edges {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: var(--line-mid);
  stroke-width: var(--hair);
}
.journey-edges path {
  vector-effect: non-scaling-stroke;
}
.journey-edges path[data-selected="true"] {
  stroke: var(--sel);
  stroke-width: calc(var(--hair) + var(--hair));
}

.journey-step-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.journey-step-meta .k {
  white-space: nowrap;
}

.journey-terminal {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
}
.journey-terminal > .small {
  position: absolute;
  top: 100%;
  padding-top: var(--space-3);
  white-space: nowrap;
  color: var(--ink-3);
}
.journey-map > .journey-terminal:first-child {
  margin-left: var(--space-4);
}
.journey-map > .journey-terminal:last-child {
  margin-right: var(--space-4);
}
.journey-choices .journey-node:focus-visible {
  outline-offset: var(--space-2);
}

.journey-terminal > .journey-dot,
.journey-map > .journey-dot {
  background: var(--sel);
  border-color: var(--sel);
}

@media (max-width: 600px) {
  .code {
    padding: var(--space-3);
  }
  .code .copy {
    position: static;
    float: right;
    margin-bottom: var(--space-2);
  }
  .code pre {
    clear: both;
    padding-right: 0;
  }
}

/* Section actions remain reachable on narrow screens. */
@media (max-width: 600px) {
  .sec-head:has(.n:empty) {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-3);
  }
  .sec-head:has(.n:empty) > .btn,
  .sec-head:has(.n:empty) > .row {
    justify-self: start;
    max-width: 100%;
  }
  .sec-head p {
    overflow-wrap: anywhere;
  }
}

.fake[data-motion] > .veil {
  visibility: hidden;
  align-items: start;
  padding-top: var(--sample-label-y, var(--space-6));
}
.fake[data-motion].is-moving > .veil,
.fake[data-motion]:focus-within > .veil {
  visibility: visible;
}
@media (pointer: coarse) {
  .fake[data-motion] > .veil {
    visibility: visible;
    align-items: start;
  }
}
@media (prefers-reduced-motion: reduce) {
  .fake.is-moving .stage {
    filter: none;
    transition: none;
  }
  .fake .stage {
    transition: none;
  }
}

.menu .pop[data-menu-floating] {
  position: fixed;
  inset: auto;
  margin: 0;
  left: var(--menu-left);
  top: var(--menu-top);
  max-width: calc(100vw - var(--space-4));
  max-height: calc(100vh - var(--space-4));
  overflow: auto;
}

/* Column controls stay above horizontal scrolling through the native top layer. */
[data-list] .twrap{max-width:100%;overflow-x:auto}
[data-list] table{width:max-content;min-width:100%}
[data-list] th,[data-list] td{white-space:nowrap}
[data-list] th .btn{font:inherit;letter-spacing:inherit;text-transform:inherit;padding-left:0}
[data-list] .pop[popover]{position:fixed;inset:auto;left:var(--menu-left);top:var(--menu-top);margin:0;padding:var(--space-4);background:var(--paper);border:var(--hair) solid var(--line);border-radius:var(--radius-control);color:var(--ink);text-align:left;text-transform:none;letter-spacing:normal}
[data-list] .pop[popover]:not(:popover-open){display:none}
[data-list] .pop[popover] .btn{display:block;margin-top:var(--space-2)}
[data-list] .table-foot{min-width:0;white-space:nowrap}

/* ─── Impressão ← U-65 (02/10) ───
   A régua é "a Linda imprimiria" (teste do Brunno, revisor de 02/10): sem regra de impressão a
   revisão do setup saía cortada numa página, com a barra lateral e a lista de passos por cima do
   texto. No papel fica só o documento: some a moldura (tarja, barra do topo, barra lateral), a
   navegação da página (a lista de passos, com a coluna dela) e os botões; o `.main` flui em
   quantas páginas precisar; tinta preta em papel — o navegador não imprime fundo, então nada
   depende de fundo para ser lido (o aviso invertido vira tinta sobre papel). */
@media print{
  .app{display:block;height:auto}
  .env,.topbar,.side,.btn,.help,.grid>:has(.steps){display:none}
  .grid>:has(.steps)~*{grid-column:1/-1}
  .main{overflow:visible;padding:0;min-height:0;background:var(--paper);color:var(--ink)}
  .callout.hard,.callout.hard *{color:var(--ink)}
  .chip .dot,.check .box{-webkit-print-color-adjust:exact;print-color-adjust:exact} /* o ponto cheio e a caixa marcada são forma (U-05): sem fundo, ● e ○ — e a declaração marcada e a vazia — sairiam iguais */
  .twrap,[data-list] .twrap{overflow:visible} /* a tabela larga não se corta na margem: no papel não há rolagem */
  table,[data-list] table{width:100%;font-size:var(--text-small)}
  td{padding-right:var(--space-2)}
  .callout,.card,.drop,.kv,.review .group,tr{break-inside:avoid}
  .review .group:last-child{break-after:avoid} /* a declaração não fica sozinha numa página */
}
