/* © 2026 Jose Carvalho. Intel Ceasa. Ver LICENSE. */
/* ============================================================
   Tela "Projetos" (assets/js/telas/projetos.js) — estilo SÓ dela.
   Arquivo próprio, e TODA regra daqui começa com `.proj`. Isso não é capricho: regra de uma tela
   que vaza para a camada compartilhada (`telas.css`, `componentes.css`) é o defeito que outra
   sessão está limpando neste exato momento. Se um seletor daqui não começar com `.proj`, ele
   está no arquivo errado.
   Cor, fonte, raio, sombra e curva de movimento: SEMPRE de `tokens.css`. Nenhuma COR em hex aqui.
   (Há um `#000` no `mask-image` da régua, e ele não é cor: numa máscara o canal lido é a opacidade,
   e `#000` ali quer dizer "opaco". Trocar por um token de cor mudaria a opacidade da máscara.)
   ============================================================ */

/* ---------- a régua de filtros MORREU EM 15/09/2026, e isto é o que ficou no lugar dela ----------
   Eram `.proj-regua` e `.proj-chip`: uma fileira de botões-pílula com "Todos 7 · Esperando você 3 ·
   Andando 3 · Ainda não começou 1 · Mostrar arquivados", que rolava de lado no celular e tinha um
   esmaecido na borda direita para avisar que continuava.
   POR QUE ELA SAIU: a tela virou quadro, e no quadro a COLUNA é o filtro. Os botões passaram a
   repetir, palavra por palavra e número por número, os cabeçalhos das colunas logo abaixo. Numa
   tela cujo pedido escrito era "sem MUITOS TEXTOS", a fileira que dizia duas vezes a mesma coisa
   era o primeiro texto a sair.
   O QUE SOBREVIVEU DELA: o esmaecido da borda direita, que agora é do `.proj-quadro` (mais abaixo),
   ligado pelo mesmo `data-fim` e pela mesma função `avisarQueContinua` em
   assets/js/telas/projetos.js. "Mostrar arquivados" virou um `.btn.vazado` comum na fileira do topo,
   porque é a única coisa que a régua dizia e o quadro não diz: projeto arquivado não tem coluna. */

/* ---------- O QUADRO: uma coluna por situação ----------
   Pedido do Carvalho em 15/09/2026: "estilo o trello, com um kanban simples, mas no mesmo design
   system lá do painel intel". Mesmo design system quer dizer literalmente isto: nenhuma cor em hex,
   nenhuma fonte nova, nenhum raio inventado — tudo de `tokens.css`, como o resto do arquivo.

   UMA REGRA SÓ RESOLVE OS DOIS TAMANHOS DE TELA, e é por isso que não há um `@media` decidindo
   quantas colunas cabem: `flex: 1 1 0` faz as colunas dividirem a largura quando ela sobra (no
   monitor, as cinco cabem e não há rolagem nenhuma), e `min-width` impede que elas encolham abaixo
   do legível — no celular isso força a rolagem de lado sozinho, que é o quadro do Trello. Largura de
   coluna escrita à mão por tamanho de tela é a mesma lista à mão de sempre, só que em pixels. */
.proj-quadro {
  display: flex;
  /* COLUNAS DA MESMA ALTURA, e não cada uma do tamanho do que tem dentro.
     Achado por crítico de contexto limpo em 15/09/2026, medido no celular: com `flex-start`, cada
     coluna ficava do tamanho do seu conteúdo e o quadro ficava do tamanho da MAIOR. Deslizando até
     "Concluído" (vazia), sobravam 251 px de branco — 30 % da tela. Com 18 projetos numa coluna
     (número realista: só o projeto das perguntas tem 38 itens) seriam 1.765 px de branco, duas
     telas de celular. Não parece uma coluna vazia; parece uma página que não carregou.
     Esticadas, a coluna vazia é um painel cinza com "nada aqui" escrito dentro — que é o que ela é.
     É também o que um quadro de verdade faz: no Trello as listas têm todas a mesma altura. */
  align-items: stretch;
  gap: 12px;
  overflow-x: auto;
  /* `contain: paint` FORCA O CLIPE. `overflow-x: auto` sozinho promete rolagem, mas em algumas
     combinacoes de layout os filhos continuam contando para a largura rolavel da PAGINA -- foi o
     que o portao mediu em 17/09/2026: o quadro com caixa de 364px e `scroll=1580`, nenhum elemento
     fora de rolador passando da borda, e mesmo assim `html.scrollWidth=685`. */
  contain: paint;
  /* `min-width: 0` é o que faz o `overflow-x` ACIMA valer alguma coisa. Item de flex ou de grid
     nasce com `min-width: auto`, que é a largura do conteúdo — cinco colunas de 190 px são 950 px,
     e o quadro CRESCE até lá em vez de rolar por dentro, empurrando a página. */
  min-width: 0;
  /* a sangria negativa deixa a primeira e a última coluna encostarem na borda do cartão, para ficar
     claro que a fileira continua além da tela — a mesma ideia da régua, aqui em cima */
  margin-inline: -16px;
  padding: 2px 16px 6px;
  scroll-padding-inline: 16px;
}
/* O ESMAECIDO DA BORDA DIREITA VALE EM QUALQUER LARGURA, e isto é um conserto de 15/09/2026.
   Ele nasceu dentro de `@media (max-width: 619.98px)`, herdado da régua de filtros, e por isso só
   existia no celular. Medido por crítico de contexto limpo, com os 7 projetos de verdade: em
   1.280 px a coluna "Concluído" aparecia com 158 dos 190 px dela; em 1.180 px, com 58 px; em
   1.024 px ela estava INTEIRA fora da tela — e sem esmaecido, sem encaixe e, no macOS, sem barra de
   rolagem visível. 1.024 e 1.180 são iPad deitado. Uma coluna inteira do quadro simplesmente não
   existia para quem olhava, e nada na tela dizia que ela estava ali.
   AGORA A REGRA NÃO OLHA LARGURA NENHUMA: quem liga e desliga é o `data-fim`, que
   `avisarQueContinua` (em assets/js/telas/projetos.js) escreve medindo a rolagem de verdade. Cabendo
   inteiro, `data-fim="1"` e o esmaecido nem acende — conferido em 1440, onde as 5 colunas cabem nos
   1.142 px de conteúdo. É a mesma pista, presa ao fato em vez de a um palpite de tamanho de tela. */
.proj-quadro:not([data-fim="1"]) {
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}
/* 180 PX DESDE 23/09/2026 (tarefa r07): com 190 px as cinco colunas passavam da largura do conteúdo
   em 1280 px (1030 px dentro de 982, medido pelo portão de colisão) e "Concluído" ficava pela metade
   atrás do esmaecido, num monitor comum. 180 fecha em 980 px. Abaixo disso o crachá passou a ter
   linha própria, então o nome continua com a largura inteira do cartão. */
.proj-coluna {
  flex: 1 1 0;
  min-width: 180px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--border);
  /* a faixa de cor da situação, no topo: o olho acha a coluna sem ler o nome dela */
  border-top: 3px solid var(--proj-cor, var(--border));
  border-radius: var(--radius);
  background: var(--muted);
  transition: background var(--rapido) var(--saida), border-color var(--rapido) var(--saida);
}
/* a coluna acesa enquanto o cartão paira sobre ela: sem isto, arrastar é um gesto no escuro — não
   há como saber onde o cartão vai cair antes de soltar */
.proj-coluna.proj-alvo {
  background: var(--accent);
  border-color: var(--proj-cor, var(--ring));
}
.proj-coluna-topo {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.proj-coluna-topo h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.proj-coluna-topo h3 .proj-conta {
  font-family: var(--fonte-numero);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: 13px;
  color: var(--muted-foreground);
}
/* o sinal da situação, logo acima do nome da coluna e alinhado com a primeira letra dele: diz a situação
   SEM PALAVRA NENHUMA, que é o pedido desta tela ("sem MUITOS TEXTOS"), uma vez por coluna.
   NUMA LINHA PRÓPRIA, E NÃO NA MESMA LINHA DO NOME, por medida (r13, 25/09/2026): a coluna tem 158 px de
   miolo de 1024 a 1280 px de tela, e "Ainda não começou" (127 px) com a contagem (8 a 16 px) e o sinal
   (16 + 6 px) pedia de 165 a 174 px. O nome quebrava em duas linhas, e os cartões daquela coluna
   desciam 21 px em relação aos das vizinhas. Numa linha própria o nome continua com a largura inteira. */
.proj-coluna-topo > .proj-sinal {
  margin: 2px 0;
}
.proj-fichas {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* o cartão nunca fica mais largo que a coluna, diga o conteúdo o que disser (r46, ver `.proj-prazo`) */
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  /* `align-content: start` para os cartões ficarem no ALTO da coluna esticada, em vez de
     espalhados pela altura toda: a coluna cresce, os cartões não. */
  align-content: start;
  flex: 1;
}
/* "nada aqui" — a coluna vazia diz que está vazia, e não some.
   POR QUE ELA NÃO SOME, que é o que a lista antiga fazia: num quadro, a coluna que some leva junto
   o lugar onde se SOLTA o cartão, e o desenho muda de forma a cada movimento. Hoje "Parado" e
   "Concluído" estão as duas vazias — e é informação boa: nada parou, nada terminou. */
.proj-coluna-vazia {
  padding: 14px 8px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  text-align: center;
  font-size: 13px;
  color: var(--muted-foreground);
}

/* ---------- o cartão do quadro: nome, uma marca, e um botão ----------
   O CARTÃO ANTIGO tinha 1.198 px de largura, quatro colunas de grade, o desenho do trilho, o nome,
   o resumo, a frase de estado, quatro fatos rotulados e três botões. Era isso que o dono estava
   recusando ao escrever MUITOS TEXTOS em maiúsculas. O que sobrou aqui tem de ser lido em menos de
   um segundo, e o resto mora na janela de detalhe. */
.proj-ficha {
  display: grid;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  /* O FIO DE COR DA SITUAÇÃO SAIU DAQUI em 17/09/2026. Ele repetia, em cor, o que a posição do
     cartão já dizia: o cartão está DENTRO da coluna daquela situação. Gastava as cinco cores do
     quadro numa informação que o olho já tinha, e não sobrava nenhuma para a prioridade — que é
     justamente o que o dono não conseguia ver de longe.
     No celular, onde uma coluna rola sozinha, quem liga o cartão à coluna é o CABEÇALHO dela, que
     acompanha a rolagem. O fio não estava fazendo esse trabalho: ele só existia depois que a
     pessoa já tinha achado o cartão. */
  border-left: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
  box-shadow: var(--sombra-sm);
  /* A ESCADA DE ENTRADA TEM TETO, e o teto é o conserto. Sem o `min()`, `--i` é um contador que
     corre por TODAS as colunas, e o atraso crescia sem fim: medido em 14/09/2026 com 24 projetos,
     os 24 cartões estavam com opacidade abaixo de 0,05 no instante do desenho, e o último só ficava
     legível em 2 segundos numa lista de 40. Numa tela cujo pedido é "abrir e saber em dez segundos
     o que parou", isso entrega um retângulo branco. Agora a escada vai até o sexto cartão e para.
     (Os 240 ms são o ATRASO, não o instante em que dá para ler.) */
  animation: proj-entrar 280ms var(--saida) backwards;
  animation-delay: calc(min(var(--i, 0), 6) * 35ms);
}
/* A ENTRADA COMEÇA EM 85% DE OPACIDADE, e não em zero (regra da skill `motion`, tarefa r07): se a
   animação não rodar, o cartão aparece legível em vez de sumir, e o contraste no meio do caminho
   continua acima do piso. `backwards` e não `both`: segura o primeiro quadro só durante o atraso da
   escada, e no fim o cartão fica no estado dele, sem animação nenhuma presa em cima. */
@keyframes proj-entrar {
  from {
    opacity: 0.85;
    transform: translateY(6px);
  }
}
/* DEPOIS DE MOVER, ARQUIVAR OU ESCREVER a tela é redesenhada inteira, e a entrada não se repete
   (`proximoDesenhoQuieto`, em assets/js/telas/projetos.js): trinta cartões deslizando a cada clique
   é movimento que atrasa o trabalho. */
.proj-quadro--quieto .proj-ficha {
  animation: none;
}
/* o cartão inteiro abre o projeto (r11): a mãozinha diz isso no computador */
.proj-ficha--abre {
  cursor: pointer;
}
/* o cartão sendo arrastado fica translúcido: é o que diz "este é o que está na sua mão" quando a
   imagem de arrasto do navegador passa por cima das outras colunas */
.proj-ficha.proj-arrastando {
  opacity: 0.4;
}
@media (hover: hover) and (pointer: fine) {
  .proj-ficha:hover {
    border-color: var(--ring);
  }
  /* o cursor de mão aberta só aparece onde arrastar existe de verdade: no toque o arrastar-e-soltar
     do HTML não dispara, e um cursor prometendo um gesto que não acontece é uma pista que mente */
  .proj-ficha[draggable="true"] {
    cursor: grab;
  }
  .proj-ficha[draggable="true"]:active {
    cursor: grabbing;
  }
}
/* A LINHA DAS MARCAS: o crachá à esquerda, o ponto de novidade à direita, e NADA MAIS. O nome
   desceu para a linha de baixo em 23/09/2026 (tarefa r07): dividindo a linha com o crachá, sobravam
   87 px para o título na coluna de 1440 px, e "Estacionamento" (104 px) saía partido no meio da
   palavra ("Estacioname / nto"), medido no navegador (achado A5 da auditoria). */
.proj-ficha-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 18px;
}
.proj-ficha h4 {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
  /* `break-word` e não `anywhere`: com `anywhere` o navegador também usa a quebra no meio da palavra
     para calcular o tamanho MÍNIMO da caixa, e é isso que deixava cortar "Estacionamento" mesmo com
     espaço; `break-word` só parte uma palavra que sozinha não cabe na linha inteira. */
  overflow-wrap: break-word;
}
/* O PONTO VERMELHO DA PRIORIDADE MÁXIMA SAIU em 23/09/2026 (tarefa r07): ele repetia o que o crachá
   `!P01`, já vermelho, diz em texto, e cada marca a menos é uma linha a menos na legenda. A regra
   `.proj-urgente` saiu junto, porque regra sem quem a use é pista falsa para o próximo leitor. */

/* ---------- O PONTO DE NOVIDADE: mexeram aqui nas ultimas 24 horas ----------
   Pedido do Carvalho em 19/09/2026: "Coloque so um ponto piscando, e ele para de piscar 24h depois
   da atualizacao recente". Quem decide se ele existe e `pontoDeNovidade`, em
   assets/js/telas/projetos.js; aqui so mora a aparencia dele.

   POR QUE ELE NAO PODE SER CONFUNDIDO COM O CRACHA DE PRIORIDADE MAXIMA, e as tres coisas que os
   separam: COR (`--info`, o unico teal do cartao, contra o `--perigo` do `!P01`),
   LUGAR (`margin-left: auto` prende este na ponta DIREITA da linha, e o vermelho abre a linha pela
   esquerda) e MOVIMENTO (o vermelho e parado). Dois pontos iguais em pontas opostas seriam a mesma
   marca dita duas vezes, e a tela ja pagou por simbolo sem diferenca antes.

   O PISCAR E LENTO E RASO DE PROPOSITO, e o raso e o que importa: o quadro pode ter varios cartaos
   frescos ao mesmo tempo, e um pisca-pisca forte em cinco cartaos e ilegivel. A opacidade cai so
   ate 0,75 porque abaixo disso o ponto perde o contraste de 3:1 que a WCAG 1.4.11 cobra de marca
   que nao e texto. O fundo QUE MANDA NA CONTA nao e o branco do cartao comum: e o rosa do cartao de
   prioridade maxima (`--perigo-fundo`, rgb(251,232,230)), que e o mais claro dos dois e o unico em
   que a conta aperta. Medido em 19/09/2026, no ponto mais fraco do piscar: sobre esse rosa, 0,75 da
   3,25:1 e 0,7 dava 2,97:1 -- reprovado por 1%, e achado por critico de contexto limpo que mediu a
   cor no navegador em vez de supor branco. Sobre o branco, 0,75 da 3,58:1; a 0,35 daria 1,70:1, uma
   marca que some no meio do proprio aviso. Quem faz o movimento ser VISTO e a escala, que nao mexe
   em contraste nenhum porque nao mistura cor com fundo.
   O PORTAO DISSO E O PASSO Q44 de scripts/testar-quadro-projetos.mjs, e ele nao acredita nestes
   numeros: mede a cor do ponto e a do fundo NO NAVEGADOR, nos dois temas, cartao por cartao, e le a
   opacidade minima do proprio `@keyframes` aqui embaixo.
   `ease-in-out` porque o movimento e ciclico e nao tem comeco nem fim: entrar e sair na mesma
   velocidade e o que faz parecer respiracao em vez de alarme. So `opacity` e `transform` entram na
   animacao, as duas propriedades que a GPU resolve sem refazer layout.

   `role="img"` + `aria-label`, no JS, pela mesma razao escrita no ponto vermelho: `aria-label` em
   `<span>` vazio sem `role` e ignorado por parte dos leitores de tela, e a marca sumiria para quem
   nao enxerga a cor. E a cor nunca esta sozinha: o rodape do quadro tem a legenda deste ponto. */
.proj-novo {
  flex: none;
  /* empurra para a ponta direita da linha das marcas, longe do crachá */
  margin-left: auto;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--info);
  animation: proj-novo-piscar 2.4s ease-in-out infinite;
}
@keyframes proj-novo-piscar {
  50% {
    opacity: 0.75;
    transform: scale(0.72);
  }
}
/* MOVIMENTO REDUZIDO: o ponto FICA, o piscar para. A informacao esta na presenca do ponto, nunca
   no movimento -- quem desligou animacao no sistema continua vendo que ha novidade ali. Sem
   `fill-mode`, entao desligar a animacao devolve o quadro em repouso (opacidade 1, escala 1), que e
   o estado legivel; e o motivo de o bloco global de tokens.css nao bastar esta escrito na secao
   "movimento reduzido", mais abaixo. */
@media (prefers-reduced-motion: reduce) {
  .proj-novo {
    animation: none;
  }
}
.proj-ficha-pe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
/* A LETRA DO QUADRO É 13 PX, NO MÍNIMO (tarefa r32, 26/09/2026). A régua da Apple pede 13 px no texto
   de tela de computador, e o CEO mediu 161 de 245 textos do quadro abaixo disso (12 e 12,5 px: os
   nomes, os crachás, os prazos, a legenda e os filtros). O pedido do Carvalho foi subir SEM perder a
   densidade do quadro, e por isso cada regra que subiu segura a altura da linha: onde ela já era em
   pixel (crachá 16 px, prazo 18 px) a caixa não cresce nada, e nos nomes a linha ficou em 17,5 px, que
   é o que 12,5 × 1,4 dava antes. A conta de cartões à vista, antes e depois, é o passo R3 de
   scripts/testar-regua-apple.mjs, que também reprova qualquer texto do quadro abaixo de 13 px.
   A MARCA DE TEMPO: "3 semanas". A coluna já diz "Parado"; o que falta é há quanto tempo. */
.proj-marca {
  font-family: var(--fonte-numero);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
  color: var(--proj-cor, var(--muted-foreground));
  white-space: nowrap;
}
/* O "?" NÃO PODE PARECER ALARME. Ele diz "não dá para contar" — falta de dado, não urgência — e
   pintado na cor da situação (vermelho em "Parado") ele gritaria mais alto que os projetos que
   têm um número de verdade. Em cinza ele ocupa o mesmo lugar, mantém a fileira alinhada e não
   inventa gravidade. */
.proj-marca--duvida {
  color: var(--muted-foreground);
  font-weight: 500;
}
/* o botão "Detalhes" vai para a direita da fileira, sozinho: é a única coisa clicável do cartão e
   não deve ser confundida com as marcas, que só informam */
.proj-ficha-pe .btn {
  margin-left: auto;
}
/* o cartão de uma linha que veio VAZIA do servidor: sem nome, sem marca, só o recado. Ele fica
   visível de propósito — sumir calado com um projeto torto é pior que mostrar que ele existe. */
.proj-ficha--torta {
  border-left-color: var(--muted-foreground);
}
.proj-ficha-recado {
  margin: 0;
  font-size: 12.5px;
  color: var(--muted-foreground);
}

/* ---------- a janela de detalhe: para onde foi tudo o que saiu do cartão ----------
   A casca é a `<dialog class="ficha">` de assets/js/detalhe.js, já estilizada em componentes.css
   (folha colada embaixo no celular, centralizada no monitor). Daqui sai só o MIOLO. */
.proj-detalhe {
  display: grid;
  gap: 10px;
}
/* na janela o sinal abre a frase de estado ("Parado há 3 semanas"), como abre o nome da coluna no
   quadro; o `vertical-align` põe o meio dele no meio das letras minúsculas da frase */
.proj-estado .proj-sinal {
  vertical-align: -3px;
  margin-right: 6px;
}
.proj-detalhe .proj-explica {
  margin: 0;
  font-size: 13px;
  color: var(--muted-foreground);
}
/* "Mover para" + os quatro destinos: é o caminho SEM ARRASTAR, e ele existe em toda tela e em todo
   aparelho — inclusive no celular, onde o arrastar está desligado de propósito. */
.proj-mover {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.proj-mover-rotulo {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted-foreground);
}

/* ---------- TRÊS REGRAS QUE EU MESMO APAGUEI SEM QUERER, E O QUE ISSO ENSINA ----------
   Em 15/09/2026, ao trocar o bloco inteiro do "cartão largo" pelo do quadro, a fatia que substituí
   ia de "um grupo de situação" até esta linha aqui — e ela levava junto `.proj-cabeca`,
   `.proj-resumo` e o grupo do `text-wrap: pretty`, que NÃO eram do cartão largo: são da janela de
   detalhe, que continua desenhando os três.
   PIOR QUE APAGAR FOI COMO EU NÃO PERCEBI: logo depois da troca eu mandei dois `replace` de texto
   para ajustar essas mesmas regras — e os dois eram sobre um texto que a troca já tinha deletado.
   Sem `assert`, os dois não fizeram NADA e não reclamaram. Fui olhar a foto da janela no celular e
   o resumo do projeto estava lá, em preto, onde devia estar cinza; olhei e não vi.
   Quem pegou foi uma varredura burra: toda classe `.proj-*` do CSS contra toda classe emitida pelo
   JavaScript, nos dois sentidos. Três apareceram como "usadas no JavaScript, sem regra no CSS".
   As regras voltam AQUI, na parte da janela de detalhe, que é onde elas moram agora. */
.proj-cabeca {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.proj-resumo {
  margin-top: 2px;
  color: var(--muted-foreground);
  overflow-wrap: anywhere;
}
/* `text-wrap: pretty` manda o navegador evitar linha final com uma palavra sozinha. É a única
   correção de viúva que se sustenta em texto que reflui: reescrever a frase acerta um tamanho de
   tela e erra os outros — e foi o que aconteceu quando consertei a viúva de UM grupo e ela
   continuou em quatro outros lugares. Onde o navegador não suporta, o texto quebra como sempre
   quebrou: nada piora. */
.proj-resumo,
.proj-estado,
.proj-ficha h4,
.proj-fatos dd,
.proj-vazio-cartao h3,
.proj-vazio-cartao p,
.proj-campo-rotulo,
.proj-rodape,
.proj-medida {
  text-wrap: pretty;
}

/* a linha mais importante do detalhe: "Parado há 3 semanas" */
.proj-estado {
  margin-top: 10px;
  font-weight: 600;
  color: var(--proj-cor, var(--foreground));
}
/* quando a data não se sabe, a frase fica em cinza: é ausência de dado, não um estado do projeto */
.proj-estado .proj-sem-data {
  font-weight: 400;
  color: var(--muted-foreground);
}

/* os fatos, em duas colunas: rótulo curto à esquerda, conteúdo à direita */
.proj-fatos {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 2px 10px;
  margin: 0;
  align-self: center;
  font-size: 13.5px;
}
/* O ROTULO PODE QUEBRAR EM DUAS LINHAS, e ate 15/09/2026 ele NAO podia -- tinha
   `white-space: nowrap` numa coluna de 96px fixos, sem `overflow` nenhum. Rotulo maior que a
   coluna nao era cortado nem embrulhado: ele vazava para a direita e PINTAVA POR CIMA do proprio
   valor. Enquanto o maior rotulo foi "Ultima novidade", que cabe, ninguem viu. O primeiro rotulo
   mais largo que a coluna ("Quem mexeu por ultimo", 143px medidos contra 96px de coluna) escreveu
   "Quem mexeu por cuadltiastro inicial do painel" nos 7 cartoes, em toda tela de 620px para cima
   -- achado por critico de contexto limpo, com foto, em 15/09/2026.
   No celular nao aparecia: abaixo de 620px a media query empilha em uma coluna so. Ou seja, o
   defeito so existia no computador, que e onde o dono abre o painel.
   A saida NAO e so encurtar o rotulo (isso conserta este caso e deixa a armadilha armada para o
   proximo): sem o `nowrap`, rotulo comprido quebra de linha dentro da propria coluna e o valor
   continua legivel, que e a degradacao certa. O rotulo curto vem junto, por estetica, nao por
   necessidade. */
.proj-fatos dt {
  color: var(--muted-foreground);
  overflow-wrap: anywhere;
}
.proj-fatos dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}
.proj-fatos dd.proj-vazio {
  color: var(--muted-foreground);
  font-style: normal;
}

/* A FRASE DO CRACHÁ NA JANELA DE DETALHE, ao lado do mesmo crachá do cartão. Até 23/09/2026 a
   janela tinha selos próprios ("Prioridade agora", "Pode esperar"), numa língua diferente da do
   cartão (achado B1 da auditoria da r07); as regras `.proj-selo*` saíram junto com eles. */
.proj-cabeca-diz {
  font-size: 13px;
  color: var(--muted-foreground);
}

/* o eco da data por extenso, embaixo do campo: confere o que o navegador entendeu (ver o
   comentário de `campoData` em assets/js/telas/projetos.js). */
.proj-eco-data:not(:empty) {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  color: var(--muted-foreground);
}

/* largura de leitura: a mesma medida que o resto da tela usa (ver .proj-vazio-cartao p). Linha
   muito comprida cansa e faz o olho perder a volta. */
.proj-medida {
  max-width: 62ch;
}
/* respiro ENTRE os parágrafos do cartão de erro. Enquanto cada um cabia numa linha só, a falta de
   margem não aparecia; ao ganharem medida de leitura passaram a quebrar em duas e quatro linhas e
   os quatro recados viraram um bloco corrido — medido, o vão entre eles era 0,0 px. São quatro
   coisas diferentes ("não é lista vazia" / "foi o servidor que disse" / "avise quem cuida"), e
   cada uma precisa se ler sozinha -- são quatro parágrafos, e os três citados acima são os que
   mudam de assunto entre si; o quarto é a frase crua do servidor. */
.proj-medida + .proj-medida {
  margin-top: 10px;
}

/* a frase crua que o servidor devolveu: fica visível porque é o único fio de quem vai consertar,
   mas recuada e em monoespaçada, para ler como "recado de máquina" e não como instrução ao dono. */
.proj-recado-do-servidor {
  font-family: var(--fonte-mono, ui-monospace, monospace);
  font-size: 13px;
  color: var(--muted-foreground);
  padding: 8px 12px;
  border-left: 2px solid var(--border);
  background: var(--muted);
  border-radius: var(--radius-sm);
  overflow-wrap: anywhere;
}

/* ---------- O SINAL DA SITUAÇÃO: 16 px, colado ao nome da coluna (tarefa r13, 25/09/2026) ----------
   SEIS desenhos, e a lista inteira está em `assets/js/telas/projetos.js`, no mapa `SINAIS` da função
   `sinalDaSituacao`: é lá que o SVG é montado, e este comentário não repete a lista de propósito, para
   não haver duas descrições envelhecendo em desacordo. Já aconteceu com o trilho que ele substituiu:
   em 14/09/2026 o gêmeo deste comentário foi corrigido e este, salvo 32 segundos depois, ficou
   descrevendo uma tela que já não existia.
   Aqui mora a pintura. Tudo sai de `currentColor`, e a cor é a da situação: `--proj-cor`, que a
   coluna, a janela de detalhe e cada linha da legenda já carregam. Sem `--proj-cor` (o quadro vazio),
   o cinza do texto de apoio.
   A COR CHEIA, E NÃO A MISTURA DE 75% QUE O TRILHO USAVA. O trilho precisava clarear o pontilhado para
   ele não pesar mais que o nome da coluna; o sinal é pequeno e é UMA figura, e os tokens de situação
   já são cores de texto, com folga contra o fundo da coluna nos dois temas. O passo S4 de
   scripts/testar-sinal-da-situacao.mjs mede cada sinal contra o fundo de verdade da coluna, nos dois
   temas, e reprova abaixo de 3:1, o piso de elemento gráfico da WCAG 1.4.11. */
.proj-sinal {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--proj-cor, var(--muted-foreground));
  overflow: visible;
  /* ilustração, não texto: não entra no que se seleciona ao arrastar o mouse pelo quadro */
  user-select: none;
}
.proj-sinal-traco {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* o círculo do "ainda não começou": oito traços curtos. A conta: a volta mede 2π·6 = 37,70, e cada um
   dos oito pedaços tem 4,712, dos quais 1 é traço (a ponta redonda o alonga em 1,5) e o resto é vão */
.proj-sinal-tracejado {
  stroke-width: 1.5;
  stroke-dasharray: 1 3.712;
}
.proj-sinal-cheio {
  fill: currentColor;
}

/* ---------- o movimento do sinal: só onde ele significa algo, poucas vezes, e para ----------
   DOIS DOS SEIS SE MEXEM, os dois cujo nome é movimento: "andando" (os riscos de velocidade correm
   para trás do ponto) e "esperando você" (o ponto bate duas vezes na cancela, como quem bate na
   porta). Parado, concluído, "ainda não começou" e a situação desconhecida não têm o que mexer: o
   sentido deles é justamente estar quieto.
   POUCAS VEZES, E PARA. Três passadas dos riscos e duas batidas duplas, logo que o quadro aparece, e
   o sinal descansa no desenho parado, que diz o mesmo. Até a r13 o trilho girava sem parar
   (`infinite`), e o pedido foi o contrário: nenhum laço puxando o olho enquanto alguém lê o quadro.
   Por isso a repetição é um NÚMERO, e o passo S2 da bateria reprova qualquer animação de sinal sem fim.
   PEQUENO E CURTO: 2 a 3 px num desenho de 16, e cada gesto dura um instante (a batida vai à cancela
   em 150 ms e volta). O que passa de um segundo é a PAUSA entre um gesto e outro, não um gesto lento.
   `linear` nos riscos porque é movimento constante (um rastro correndo); a batida usa a saída da casa.
   SÓ NO QUADRO. Na legenda e na janela de detalhe o mesmo desenho fica parado: ali ele explica.
   O ÚLTIMO QUADRO DE CADA ANIMAÇÃO É O DESENHO PARADO, então nada salta quando ela acaba, e não há
   `fill-mode`: se a animação não rodar (aba em segundo plano), o sinal já está no lugar certo. */
/* os riscos são finos: o peso do desenho é o ponto */
.proj-sinal-rastro {
  stroke-width: 1.35;
}
/* O GESTO SÓ EXISTE ONDE PODE EXISTIR, e isso está no SELETOR, não numa regra que o desliga depois:
     - `prefers-reduced-motion: no-preference`: com "reduzir movimento" ligado no aparelho, estas
       regras nem se aplicam, e o sinal nasce parado;
     - `.proj-quadro:not(.proj-quadro--quieto)`: só no quadro (a legenda e a janela de detalhe ficam
       fora dele) e nunca no redesenho depois de mover, arquivar ou escrever (`proximoDesenhoQuieto`,
       o mesmo que segura a entrada dos cartões): quem acabou de agir já sabe onde cada coisa está.
   POR QUE NÃO UMA REGRA DE "DESLIGAR" MAIS ABAIXO, que era a primeira versão: ela perdia. Os seletores
   destas animações são mais fortes que `.proj-sinal *`, e a regra de desligar não desligava nada; o
   passo S3 de scripts/testar-sinal-da-situacao.mjs pegou (25/09/2026), porque ele confere o NOME da
   animação com "reduzir movimento" ligado. Sem o passo, ninguém veria: o bloco global de tokens.css
   encurta toda animação para 0,001 ms, e o gesto sumia por acaso, não por regra.
   Os riscos saem um depois do outro, de cima para baixo: juntos piscariam como um bloco, e em escada
   parecem vento passando. */
@media (prefers-reduced-motion: no-preference) {
  .proj-quadro:not(.proj-quadro--quieto) .proj-sinal--andando .proj-sinal-rastro {
    animation: proj-sinal-rastro 1.2s linear 0.5s 3;
  }
  .proj-quadro:not(.proj-quadro--quieto) .proj-sinal--andando .proj-sinal-rastro:nth-child(2) {
    animation-delay: 0.65s;
  }
  .proj-quadro:not(.proj-quadro--quieto) .proj-sinal--andando .proj-sinal-rastro:nth-child(3) {
    animation-delay: 0.8s;
  }
  .proj-quadro:not(.proj-quadro--quieto) .proj-sinal--esperando_voce .proj-sinal-ponto {
    animation: proj-sinal-bater 2.2s var(--saida) 0.7s 2;
  }
}
@keyframes proj-sinal-rastro {
  0% {
    transform: translateX(0);
    opacity: 1;
  }
  50% {
    transform: translateX(-3px);
    opacity: 0;
  }
  50.1% {
    transform: translateX(2px);
    opacity: 0;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}
@keyframes proj-sinal-bater {
  0%,
  26%,
  100% {
    transform: translateX(0);
  }
  7%,
  19% {
    transform: translateX(2px);
  }
  13% {
    transform: translateX(0.5px);
  }
}

/* ---------- estado vazio: o que esta tela mostra ENQUANTO ninguém cadastrou nada ----------
   Não diz "em implantação" e nunca vai dizer: essa frase é justamente a que faz o dono achar que
   o sistema está pela metade. Diz o que É: a tabela está vazia, e como se põe algo nela. */
.proj-vazio-cartao {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: 6px;
  padding: 48px 24px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--muted);
}
.proj-vazio-cartao svg {
  height: auto;
}
.proj-vazio-cartao h3 {
  font-size: 18px;
  font-weight: 700;
}
.proj-vazio-cartao p {
  color: var(--muted-foreground);
  max-width: 46ch;
}
/* o círculo tracejado do "ainda não começou", grande: a mesma figura do quadro, só que sozinha */
.proj-vazio-cartao .proj-sinal {
  width: 44px;
  height: 44px;
  margin-bottom: 4px;
}

/* ---------- formulário de quem escreve (só administrador) ---------- */
.proj-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}
/* a fileira de botões no PÉ da janela de detalhe: o `margin-bottom` de 16 px que a fileira de cima
   usa (onde ela é seguida do formulário) viraria um vão morto contra a borda de baixo da janela.
   A regra que estava aqui — `.proj-cartao .proj-acoes` — morreu junto com o cartão largo em
   15/09/2026: `.proj-cartao` não é emitido por ninguém desde que a tela virou quadro. */
.ficha-pe .proj-acoes {
  margin-bottom: 0;
}
/* ---------- A JANELA DE CRIAR E EDITAR: cinco perguntas à vista (tarefa r11, 24/09/2026) ----------
   O porquê inteiro está em `abrirFormulario`, em assets/js/telas/projetos.js. Aqui mora a aparência:
   as cinco perguntas uma embaixo da outra, cada uma com um rótulo só (sem título de seção nem número
   de passo), os anexos à vista, "Mais detalhes" dobrado, e a PRÉVIA do cartão: numa coluna ao lado no
   computador, presa no alto enquanto a janela rola, e logo acima dos botões no celular.
   A JANELA É A MESMA DO DETALHE (`dialog.ficha`, em componentes.css), mais larga no computador para
   caber a prévia ao lado: 272 px de prévia (a largura de uma coluna do quadro) e o resto para as
   perguntas. `.proj-janela-form.ficha` vale (0,2,0) e ganha do `dialog.ficha` (0,1,1) de lá sem mexer
   no arquivo que as outras telas usam. No celular ela continua sendo a folha que sobe de baixo. */
.proj-janela-form.ficha {
  width: min(940px, 100vw);
}
.proj-form {
  display: grid;
  gap: 14px;
}
.proj-form-corpo {
  display: grid;
  gap: 18px;
  min-width: 0;
}
.proj-form-perguntas {
  display: grid;
  gap: 18px;
  min-width: 0;
}
@media (min-width: 900px) {
  .proj-form-corpo {
    grid-template-columns: minmax(0, 1fr) 272px;
    align-items: start;
  }
  /* a prévia acompanha a rolagem do corpo da janela: o cartão fica à vista enquanto a pessoa
     preenche as perguntas de baixo */
  .proj-previa-bloco {
    position: sticky;
    top: 0;
  }
}
.proj-campo {
  display: grid;
  gap: 5px;
  min-width: 0;
}
.proj-campo-rotulo {
  font-size: 13.5px;
  font-weight: 600;
}
.proj-obrigatorio {
  font-size: 12.5px;
  font-weight: 400;
  color: var(--muted-foreground);
}
.proj-campo-erro {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--perigo);
}
/* OS CAMPOS DE TEXTO DESTA TELA, os dois formulários juntos (a janela de criar e a caixa de escrever
   atualização): as bordas, o raio e o fundo de campo são os mesmos em toda a tela, e copiar a regra
   numa segunda declaração faria a aparência dos dois se separar calada a cada ajuste num deles só.
   40 px de altura: o mesmo tamanho do botão ao lado, para a linha não ficar torta.
   O CAMPO DE ARQUIVO FICA DE FORA (tarefa r11): ele é o `<input type=file>` escondido atrás de cada
   botão de anexo, e com esta regra ele ganhava a largura inteira da janela, invisível, empurrando a
   janela de criar 394 px para o lado (medido pelo portão de caixa encostada em 24/09/2026). */
.proj-form input:not([type="radio"], [type="checkbox"], [type="file"]),
.proj-form select,
.proj-atividade-campo {
  width: 100%;
  min-height: 40px;
  padding: 8px 10px;
  border: 1px solid var(--input);
  border-radius: var(--radius-sm);
  background: var(--background);
  font-family: inherit;
  font-size: 14px;
  transition:
    border-color var(--rapido) ease,
    box-shadow var(--rapido) ease;
}
.proj-form input:focus-visible,
.proj-form select:focus-visible,
.proj-atividade-campo:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}
/* o campo que falta ganha borda de perigo: a cor sozinha não conta (a frase embaixo dele diz o que
   falta), mas ela acha o campo antes de a pessoa ler */
.proj-form [aria-invalid="true"] {
  border-color: var(--perigo);
  box-shadow: 0 0 0 1px var(--perigo);
}
.proj-form-faltas ul {
  margin: 6px 0 0;
  padding-left: 18px;
}
.proj-form-faltas p {
  margin: 4px 0 0;
}
/* UMA PERGUNTA FEITA DE BOTÕES (quem faz, a prioridade) é um `<fieldset>` sem moldura: a `<legend>`
   tem a cara dos rótulos dos outros campos, porque é uma pergunta, e não uma seção */
.proj-grupo {
  margin: 0;
  padding: 0;
  border: 0;
}
.proj-grupo > .proj-campo-rotulo {
  margin-bottom: 5px;
  padding: 0;
}
/* o controle e o que anda junto com ele, na mesma linha (a data e os atalhos; a posição e a dica) */
.proj-campo-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.proj-form .proj-campo-linha > input {
  flex: 1 1 170px;
  width: auto;
  min-width: 0;
}
/* OS ATALHOS DO PRAZO: pílulas como as de "Quem faz"; a que bate com a data do campo fica acesa */
.proj-atalhos {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.proj-atalho {
  min-height: 36px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  transition:
    background-color var(--rapido) ease,
    border-color var(--rapido) ease,
    transform 160ms var(--saida);
}
.proj-atalho:active {
  transform: scale(0.96);
}
.proj-atalho[aria-pressed="true"] {
  border-color: var(--primary);
  background: var(--accent);
  font-weight: 600;
}
@media (hover: hover) and (pointer: fine) {
  .proj-atalho:hover {
    border-color: var(--primary);
  }
}
.proj-form .proj-campo-linha > input[name="prioridade_maxima"] {
  flex: 0 0 88px;
}
.proj-posicao-dica {
  color: var(--muted-foreground);
  font-size: 12.5px;
}
/* AS QUATRO PRIORIDADES LADO A LADO, cada uma um cartão que se toca inteiro (o `<label>` embrulha o
   botão de rádio); duas por linha no celular. A escolhida fica com a borda e o fundo de destaque; a
   "Urgente" escolhida fica na cor de perigo, a mesma do crachá `!P01` que ela produz. `:has()` porque
   quem sabe que está escolhido é o `<input>` lá dentro; navegador que não conhece `:has()` continua
   mostrando a bolinha marcada, que já diz a mesma coisa. */
.proj-opcoes {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}
@media (max-width: 639.98px) {
  .proj-opcoes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.proj-opcao {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
  cursor: pointer;
  transition:
    border-color var(--rapido) ease,
    background-color var(--rapido) ease,
    transform 160ms var(--saida);
}
.proj-opcao:active {
  transform: scale(0.98);
}
.proj-opcao:has(input:checked) {
  border-color: var(--primary);
  background: var(--accent);
}
.proj-opcao--urgente:has(input:checked) {
  border-color: var(--perigo);
  background: var(--perigo-fundo);
}
.proj-opcao input {
  margin-top: 3px;
  accent-color: var(--primary);
}
.proj-opcao--urgente input {
  accent-color: var(--perigo);
}
.proj-opcao-texto {
  display: grid;
  gap: 2px;
  min-width: 0;
  font-size: 13.5px;
}
.proj-opcao-texto span {
  font-size: 12.5px;
  color: var(--muted-foreground);
}
/* A PRÉVIA DO CARTÃO: o cartão de verdade do quadro (`fichaDoProjeto`), numa moldura tracejada que diz
   "isto ainda não existe". Sem a entrada animada do quadro: ela é redesenhada a cada tecla. */
.proj-previa-bloco {
  display: grid;
  gap: 8px;
  min-width: 0;
  padding: 12px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--muted);
}
.proj-previa-titulo {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12.5px;
  font-weight: 700;
}
.proj-previa-cartao {
  margin: 0;
  padding: 0;
  list-style: none;
}
.proj-previa-cartao .proj-ficha {
  animation: none;
}
/* sem nome ainda, o cartão mostra "Nome do projeto" apagado: é o lugar do nome, não um nome */
.proj-previa-cartao .proj-ficha--sem-nome h4 {
  color: var(--muted-foreground);
  font-weight: 500;
}
.proj-previa-diz {
  margin: 0;
  color: var(--muted-foreground);
  font-size: 12.5px;
}
/* "Mais detalhes": recolhido no projeto novo, aberto quando o projeto já tem um desses três campos */
.proj-mais {
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}
.proj-mais > summary {
  color: var(--primary);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}
.proj-mais-corpo {
  display: grid;
  gap: 10px;
  margin-top: 10px;
}
.proj-outra-empresa {
  margin-top: 6px;
}
/* OS BOTÕES PRESOS AO PÉ DA JANELA enquanto ela rola: seis seções no celular passam de uma tela, e
   "Criar projeto" lá embaixo, fora de vista, é o botão que a pessoa não acha. O `bottom` negativo
   e as margens negativas são o respiro do corpo da janela (`.ficha-corpo`: 16 px dos lados e 18 px
   embaixo), para o pé encostar nas bordas em vez de flutuar dentro delas. */
.proj-form-pe {
  position: sticky;
  bottom: -18px;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 -16px -18px;
  padding: 12px 16px 16px;
  border-top: 1px solid var(--border);
  background: var(--card);
}
.proj-erro {
  color: var(--perigo);
  background: var(--perigo-fundo);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
}

/* ---------- larguras ----------
   NÃO HÁ MAIS NENHUMA REGRA DE LARGURA PARA O QUADRO, e isso é o conserto, não o esquecimento: as
   colunas se dividem sozinhas por `flex: 1 1 0` e passam a rolar de lado sozinhas quando o
   `min-width` delas não cabe mais (ver o comentário de `.proj-quadro`). As três faixas de tamanho
   que o cartão antigo precisava — 1000 px, 620 px e o resto — eram a consequência de uma grade de
   quatro colunas dentro de uma linha larga, e essa linha deixou de existir.
   O que sobra aqui é só o celular: o quadro vira uma coluna por vez, com encaixe. */
/* UMA COLUNA DE CADA VEZ, COM ENCAIXE, EM QUEM USA O DEDO — e a regra pergunta pelo PONTEIRO, não
   pela largura. Ela vivia em `max-width: 619.98px` e por isso o iPad deitado (1.024 e 1.180 px,
   dedo) ficava de fora: colunas de 190 px, sem encaixe, e uma delas fora da tela.
   78 % da largura e não 100: o pedacinho da coluna seguinte que aparece na borda é o que diz, sem
   escrever, que há mais para o lado.
   No computador NÃO há encaixe de propósito: encaixe brigando com a roda do mouse é o tipo de
   "ajuda" que atrapalha quem está só passando o olho. */
@media (pointer: coarse) {
  .proj-quadro {
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .proj-quadro::-webkit-scrollbar {
    display: none;
  }
  .proj-coluna {
    min-width: min(78vw, 300px);
    scroll-snap-align: start;
  }
}

@media (max-width: 619.98px) {
  /* a lista de fatos da janela de detalhe empilha rótulo e valor: em 390 px, uma coluna de 96 px
     para o rótulo deixa o valor com 250 px e quebra "veio no cadastro inicial do painel" em cinco
     linhas */
  .proj-fatos {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .proj-fatos dt {
    margin-top: 6px;
    font-size: 13px;
  }
}

/* ---------- movimento reduzido ----------
   NÃO basta o bloco global de tokens.css. Ele deixa cada animação com 0,001 ms e UMA passada, e o
   elemento termina no quadro que a animação mandar, o que já custou caro aqui: o trilho antigo
   empilhava os três pontos do "andando" na ponta direita, invisíveis, e uma barra de outra tela
   ficou presa em 2% mentindo sobre a proporção (14/09/2026). Aqui as animações são DESLIGADAS, sem
   passada nenhuma. Aqui mora a entrada dos cartões; o gesto do sinal da situação nem chega a existir
   com "reduzir movimento" ligado, porque as regras dele moram dentro de
   `@media (prefers-reduced-motion: no-preference)`, na seção do sinal (o porquê está lá). O sinal
   parado é o mesmo desenho em que cada gesto termina, então ele continua dizendo a mesma coisa. */
@media (prefers-reduced-motion: reduce) {
  .proj-ficha {
    animation: none;
  }
}

/* ---------- O CRACHÁ DA CLASSE: A1, B1, B2, !P01 ----------
   O vocabulário é do GRUPO (slide 6 da apresentação do Projeto Sankhya): a letra diz se o
   desenvolvimento começou, o número diz a prioridade, e o `!` é a marcação adicional de prioridade
   máxima. É TEXTO, e isso é a decisão central deste bloco: crachá escrito informa sem gastar cor,
   sobrevive a qualquer tema, e atende sozinho a WCAG 1.4.1 (informação não pode depender só de
   cor — os pares vermelho×verde e azul×roxo somem para 8% dos homens).
   Números tabulares para "A1" e "B1" ficarem com a mesma largura de "A2" e "B2": crachá que dança
   de tamanho entre um cartão e outro faz a coluna parecer torta. */
/* ---------- O CRACHÁ: `A1`, `B2`, `!P01` ----------
   Pedido do Carvalho em 19/09/2026, olhando o quadro no ar: "os ícones de B1, A1 estão meio
   apagados, dê mais destaque a eles pra ficar mais legível".

   O QUE ESTAVA APAGADO NÃO ERA O TEXTO, e medir antes de mexer mudou o conserto inteiro. O crachá
   era `--muted-foreground` sobre `--muted`, e isso já dava 5,19:1 no tema claro e 7,49:1 no escuro
   — acima dos 4,5:1 da WCAG 1.4.3 nos dois. O que não existia era CONTORNO: a borda `--border`
   contra o fundo do cartão dava 1,05:1 no cartão rosa de prioridade máxima, 1,09:1 no âmbar,
   1,23:1 no branco e 1,13:1 no cinza (e 1,15:1 a 1,41:1 no tema escuro). Uma pílula cinza-clara
   sobre cartão quase branco, com uma borda que ninguém enxerga, em 10 px: o crachá não estava
   fraco de cor, estava sem beirada, flutuando no cartão.

   POR QUE CHIP SÓLIDO, E POR QUE ESTE E NÃO OUTRO. Tentei antes escurecer só o texto e trocar a
   borda por `--input` (o token de contorno de campo, documentado como 3:1 no branco): medido, a
   borda dava 2,53:1 no cartão rosa, 2,64:1 no âmbar, 2,99:1 no branco e 2,75:1 no cinza —
   reprovado nos quatro, porque `--input` foi calibrado contra o BRANCO e os cartões do quadro são
   tintos. Preencher o crachá resolve na raiz: o contorno deixa de depender de uma linha de 1 px e
   passa a ser a própria mancha. `--foreground` sobre os quatro fundos de cartão dá 13,45:1,
   14,04:1, 15,88:1 e 14,57:1 no claro, e 14,34:1, 13,27:1, 16,17:1 e 14,27:1 no escuro.

   E O DESENHO NÃO É NOVO NESTA TELA: é exatamente o tratamento que o botão de filtro ligado já usa
   logo acima (`--foreground` de fundo, `--background` de texto). Padrão que já existe na mesma
   folha é padrão que o painel já ensinou a ler, e não gasta vocabulário visual novo.

   MONOCROMÁTICO DE PROPÓSITO: `A1`, `B1`, `A2`, `B2`, `1` e `2` continuam sem cor. O ganho é
   contraste, peso e tamanho, nunca tinta — a regra do quadro é que só o `!` é colorido, e um
   crachá colorido por classe viraria o arco-íris que esta tela evita desde o começo.

   `line-height` EM PIXEL, E NÃO EM NÚMERO, e isto é a trava que deixa o tamanho subir sem custo: o
   crachá antigo tinha 10 px × 1,5 = 15 px de caixa de texto. Fixando 15 px, o texto sobe para 11 px
   dentro da MESMA caixa, e a altura total do crachá continua 19 px (15 + 2 de respiro + 2 de
   borda). Isso importa porque a altura do cartão é o que decide quantos cabem na coluna, e a
   coluna mostra 10 à vista: crachá 1 px mais alto muda o corte da coluna. O passo Q46 mede a
   altura, não acredita nesta conta. */
/* 12 PX DESDE 23/09/2026 (tarefa r07): o pedido foi "os crachás legíveis", e 11 px ficava abaixo do
   piso de 12 px que a casa usa para qualquer letra (achado B3 da auditoria, 35 crachás medidos). Com
   o crachá numa linha só dele, crescer não empurra mais o nome do projeto. */
.proj-classe {
  flex: none;
  align-self: center;
  padding: 1px 7px;
  border: 1px solid var(--foreground);
  border-radius: 4px;
  font-size: 13px; /* 13 desde a r32 (ver `.proj-marca`); a linha de 16 px segura a altura */
  font-weight: 700;
  line-height: 16px;
  letter-spacing: 0.4px;
  font-variant-numeric: tabular-nums;
  color: var(--background);
  background: var(--foreground);
  white-space: nowrap;
}
/* A ÚNICA COISA COLORIDA DO QUADRO. Duas frentes de dezoito têm `!`; cor rara é cor que informa, e
   é o que o Linear faz (cor só no "Urgente", o resto é forma). A cor vem do token de destaque que
   o painel já usa, não de um vermelho novo: paleta que cresce a cada tela vira arco-íris.

   ESTE BLOCO ESTAVA QUEBRADO NO AR, e o defeito era mudo. Ele pedia `var(--destructive)` e
   `var(--destructive-foreground)`, e NENHUM DOS DOIS existe em assets/css/tokens.css nem em
   qualquer outra folha do painel — são nomes de outro sistema de design, que entraram aqui por
   hábito. Variável que não existe não é erro de sintaxe: o navegador invalida a declaração no
   momento de computar, e cada uma cai no valor INICIAL da propriedade. Então `background` virava
   `transparent` e `border-color` virava `currentcolor`, que ali é o próprio branco do fallback do
   texto. O crachá `!P01` era, na prática, texto branco sem fundo em cima do rosa do cartão:
   1,18:1 no tema claro, medido em 19/09/2026. A marca mais importante do quadro era a única
   ilegível, e nenhuma bateria olhava.
   Os tokens certos são os que o próprio cartão de prioridade máxima já usa: `--perigo` no fundo e
   `--perigo-fundo` no texto. Eles são um par desenhado junto e trocam de papel sozinhos no tema
   escuro, o que resolve os dois temas sem token novo: texto sobre fundo dá 5,48:1 no claro e
   7,22:1 no escuro, e o fundo do crachá contra o rosa do cartão dá os mesmos 5,48:1 e 7,22:1, bem
   acima dos 3:1 que a WCAG 1.4.11 cobra de uma marca se separar do que está atrás dela.
   `#fff` no texto daria 6,46:1 no claro e pareceria melhor — mas no escuro `--perigo` é um salmão
   claro (#f2917f) e o branco cairia para 2,30:1. O par de tokens não tem esse buraco. */
.proj-classe--maxima {
  color: var(--perigo-fundo);
  background: var(--perigo);
  border-color: var(--perigo);
}

/* ---------- A LEGENDA NO ALTO DO QUADRO: "Como ler o cartão" (tarefa r07, 23/09/2026) ----------
   O porquê inteiro está em `legendaDoQuadro`, em assets/js/telas/projetos.js. Até aqui ela morava
   no rodapé, a duas telas do topo (achado A1 da auditoria); agora é a primeira coisa acima das
   colunas.
   É REFERÊNCIA, NÃO AVISO: fundo `--muted` e letra de 12,5 px, nenhuma cor de alerta. Quem destaca é
   o título e são os crachás, desenhados com a mesma classe do cartão.
   TRÊS LINHAS (a marca, o prazo, a cor), cada uma com o rótulo à esquerda no computador e em cima no
   celular. O crachá e o que ele quer dizer andam grudados (`inline-flex`): a quebra de linha nunca
   separa a marca da explicação dela, que é o único jeito de uma legenda ficar ambígua. */
.proj-legenda {
  margin: 0 0 12px;
  padding: 10px 14px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--muted);
}
.proj-legenda--recolhida {
  padding-bottom: 10px;
}
/* o "Esconder/Mostrar" da legenda nao encolhe: com um titulo comprido ele era espremido ate cortar a
   propria palavra (MEDIDO a 360, r38) */
.proj-legenda-alternar {
  flex: none;
}
.proj-legenda-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.proj-legenda-titulo {
  margin: 0;
  color: var(--foreground);
  font-size: 13.5px;
  font-weight: 700;
}
/* TRÊS BLOCOS LADO A LADO (a marca, o prazo, a cor), com a cara das colunas do quadro (tarefa r11): a
   faixa de cor no alto, o título como o de uma coluna e um item por linha, a marca e o que ela quer
   dizer. Um embaixo do outro só no celular: no tablet em pé os três ainda cabem lado a lado. E COMPACTA
   de propósito: no iPad deitado (1024x768) a legenda inteira tem de caber na primeira tela, acima das
   colunas (passo R1 de scripts/testar-quadro-projetos.mjs). */
.proj-legenda-conteudo {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 8px;
}
@media (max-width: 619.98px) {
  .proj-legenda-conteudo {
    grid-template-columns: minmax(0, 1fr);
  }
}
.proj-legenda-bloco {
  display: grid;
  align-content: start;
  gap: 6px;
  min-width: 0;
  padding: 8px 10px 10px;
  border: 1px solid var(--border);
  border-top: 3px solid var(--primary);
  border-radius: var(--radius);
  background: var(--card);
}
.proj-legenda-bloco-titulo {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.proj-legenda-lista {
  display: grid;
  /* 8 px entre as linhas da legenda (era 5): cada linha traz um cracha de exemplo, e a 5 px os crachas
     de uma linha encostavam nos da outra (r38, regra de vao) */
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* a marca e a frase dela, lado a lado, e a frase quebra DEBAIXO DE SI MESMA, nunca embaixo da marca:
   a quebra de linha não separa a marca do que ela quer dizer */
.proj-legenda-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 8px;
}
.proj-legenda-item > :first-child {
  justify-self: start;
}
.proj-legenda-diz {
  font-size: 13px; /* r32, ver `.proj-marca` */
}
/* "sem número" e "número sem letra": marcas que o cartão mostra pela AUSÊNCIA, escritas em palavra */
.proj-legenda-palavra {
  color: var(--muted-foreground);
  font-size: 13px; /* r32, ver `.proj-marca` */
  font-weight: 600;
  white-space: nowrap;
}
/* a amostra da cor do cartão: pintada pela MESMA regra do cartão (ver "a cor do cartão", mais
   abaixo), então a legenda e o quadro não têm como discordar */
.proj-amostra {
  flex: none;
  width: 20px;
  height: 14px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--card);
}
/* o ponto azul da legenda é o mesmo desenho do cartão, parado: na legenda ele explica, não avisa */
.proj-legenda .proj-novo--legenda {
  margin-left: 0;
  animation: none;
}
/* "AS COLUNAS" (r13): o sinal de cada coluna, numa linha embaixo dos três blocos. Uma LINHA e não um
   quarto bloco, e a medida que decidiu isso está em `legendaDoQuadro` (assets/js/telas/projetos.js).
   Cada item é o sinal colado ao nome da coluna, como no quadro, e quebra de linha INTEIRO: o sinal
   nunca fica numa linha e o nome na outra. O título tem a letra dos títulos dos blocos, um pouco menor
   porque aqui ele divide a linha com os itens. */
.proj-legenda-colunas {
  display: flex;
  flex-wrap: wrap;
  /* `center`, e não `baseline`: o item é um sinal de 16 px ao lado de letra de 12,5, e pela linha de
     base o título "As colunas" ficava 2 px abaixo dos nomes (visto na foto de 1440, 25/09/2026) */
  align-items: center;
  gap: 4px 12px;
  margin-top: 8px;
}
.proj-legenda-colunas-titulo {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.proj-legenda-colunas-lista {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.proj-legenda-coluna {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px; /* r32, ver `.proj-marca` */
  white-space: nowrap;
}

/* ---------- QUEM FAZ ----------
   Só os nomes, na altura do olho, logo abaixo do título. Papel e área ficam no detalhe: o cartão
   responde "quem", o detalhe responde "quem faz o quê". */
/* 12,5 px desde a r07: eram 11,5 px, abaixo do piso de 12 px da casa (achado B3 da auditoria) */
.proj-ficha-gente {
  margin: 0;
  font-size: 13px; /* r32, ver `.proj-marca`: a letra sobe, a linha fica nos 17,5 px de antes */
  line-height: 17.5px;
  color: var(--muted-foreground);
}
/* QUEM CRIOU (r25): a mesma letra de "quem faz", logo abaixo dele. Não quebra a palavra no meio, e o
   nome longo desce para a linha de baixo em vez de vazar do cartão. */
.proj-ficha-criado,
.proj-criado-linha {
  margin: 0;
  font-size: 13px; /* r32, ver `.proj-marca` */
  line-height: 17.5px;
  color: var(--muted-foreground);
  overflow-wrap: break-word;
}
.proj-criado-linha {
  font-size: 14px;
}
/* "a confirmar" é a honestidade desta tela: enquanto ninguém confirmou, o nome ali é uma PROPOSTA
   minha, tirada da área de cada pessoa — a apresentação do grupo não amarra pessoa a frente em
   lugar nenhum. Sem esta marca, palpite viraria decisão em silêncio. */
/* 12 px, sem itálico e sem transparência desde a r07: eram 10 px em itálico a 85%, a letra mais
   apagada do quadro, justo na marca que diz que o nome ao lado é palpite (achado B3 da auditoria). E
   ela não quebra no meio ("a / confirmar" saía em duas linhas no celular). */
.proj-a-confirmar {
  display: inline-block;
  margin-left: 6px;
  padding: 0 5px;
  border: 1px dashed var(--input);
  border-radius: 3px;
  font-size: 13px; /* r32, ver `.proj-marca` */
  white-space: nowrap;
}

/* ---------- FILTRAR POR OPERAÇÃO ----------
   Esconde por CSS, sem tirar o cartão do DOM: soltar um projeto arrastado numa coluna continua
   funcionando com o filtro ligado, e o "Ver todos (N)" de cada coluna continua contando a coluna
   inteira — que é o número que ele sempre prometeu.
   O seletor precisa do `[data-operacao]` no quadro E no cartão; sem o primeiro, "Todas" (valor
   vazio) esconderia tudo. */
.proj-filtro {
  display: flex;
  flex-wrap: wrap;
  /* 8 px entre os botoes de operacao (era 6): o piso de vao entre dois objetos (r38, 27/09/2026) */
  gap: 8px;
  margin-bottom: 12px;
  /* `min-width: 0` E `max-width: 100%`: sem os dois, a largura NATURAL desta fileira (todos os
     botões numa linha só, porque a largura natural ignora a quebra) vira o piso do container, e no
     celular a PÁGINA INTEIRA passa a rolar de lado. Medido pelo portão em 17/09/2026, no mesmo
     minuto em que o filtro entrou: `scrollWidth=685px clientWidth=390px`. */
  min-width: 0;
  max-width: 100%;
}
.proj-filtro-botao {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--muted-foreground);
  font: inherit;
  font-size: 13px; /* r32, ver `.proj-marca` */
  cursor: pointer;
}
.proj-filtro-botao:hover {
  border-color: var(--ring);
  color: var(--foreground);
}
/* O ESTADO LIGADO NÃO É SÓ COR: o fundo muda E a borda escurece E o peso do texto sobe. Um botão
   de filtro que só troca de cor some para quem não distingue a cor, e a pessoa não descobre qual
   recorte está vendo (WCAG 1.4.1). */
/* O ESCOLHIDO NA COR DE DESTAQUE DO PAINEL desde a r07 ("botões mais coloridos"): era o preto do
   texto, a mesma mancha escura dos crachás logo abaixo, e os dois se confundiam. A forma continua
   dizendo sozinha qual está escolhido (preenchido contra vazado), para quem não distingue cor. */
.proj-filtro-botao[aria-pressed="true"] {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: 600;
}
.proj-filtro-botao {
  transition:
    background-color var(--rapido) ease,
    border-color var(--rapido) ease,
    transform 160ms var(--saida);
}
.proj-filtro-botao:active {
  transform: scale(0.96);
}
/* sem a transparência de 70% que existia: o número ficava em 3,01:1 no tema claro, abaixo dos 4,5:1
   (medido por crítico de contexto limpo, r07). A diferença para o nome já vem do peso e do tamanho. */
.proj-filtro-conta {
  font-variant-numeric: tabular-nums;
}
/* ESCONDE POR CLASSE, e não por um seletor que compare os dois `data-operacao`: CSS não compara
   atributo com atributo, então a alternativa seria uma regra por operação escrita aqui — a lista
   duplicada ao lado da lista de verdade, que envelhece calada na primeira operação nova que o
   grupo abrir. Quem decide é o JavaScript, que tem os dois valores na mão. */
.proj-ficha--fora-do-filtro {
  display: none;
}

/* ---------- A COR DO CARTÃO É A PRIORIDADE ----------
   Pedido do Carvalho em 17/09/2026: "os cards devem mudar de cor a medida das prioridades".
   A escada usa os tokens que o painel JÁ TEM (`--alerta`, `--perigo` e os fundos deles, com versão
   própria para o modo escuro em tokens.css) — paleta nova por tela é como um painel vira arco-íris.
   A COR NUNCA ESTÁ SOZINHA: o crachá ao lado escreve `!P01`, `A1`, `B2` em texto, e a prioridade
   máxima ainda tem o ponto. É o que a WCAG 1.4.1 exige — informação não pode depender só de cor,
   e os pares vermelho×verde e azul×roxo somem para 8% dos homens.
   RESSALVA MEDIDA, dita ao Carvalho antes de escrever isto: hoje ONZE das dezoito frentes estão em
   prioridade 1, então esta escada pinta 60% do quadro de âmbar. Cor que cobre a maioria para de
   informar (o Linear gasta cor em UM nível só, e o Jira refez os ícones dele porque as prioridades
   "dependiam só de cor"). Isso se resolve quando o dono começar a separar as prioridades de
   verdade — que é o motivo pelo qual ele pediu o campo. */
.proj-ficha[data-prioridade="maxima"],
.proj-amostra[data-prioridade="maxima"] {
  border-color: var(--perigo);
  background: var(--perigo-fundo);
}
.proj-ficha[data-prioridade="1"],
.proj-amostra[data-prioridade="1"] {
  border-color: var(--alerta);
  background: var(--alerta-fundo);
}
/* prioridade 2 é o padrão: cartão normal, sem tinta. Selo em tudo que não tem nada de especial é
   o ruído que ensina o dono a ignorar selo. */
.proj-ficha[data-prioridade="3"],
.proj-amostra[data-prioridade="3"] {
  background: var(--muted);
}
.proj-ficha[data-prioridade="3"] h4 {
  color: var(--muted-foreground);
}

/* ---------- QUEM FAZ: escolher clicando ----------
   Botões, não campo de digitar. O pedido foi "só ele clicar em quem quer incluir no projeto", e o
   motivo é medido: das doze ferramentas pesquisadas em 17/09/2026, nenhuma delega para quem não
   tem login, e o caminho documentado (o próprio suporte do monday.com) é texto solto — que no
   celular vira teclado aberto e erro de digitação num nome que precisa casar EXATO com a conta. */
.proj-gente {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
  max-width: 100%;
}
.proj-gente-par {
  display: inline-flex;
  align-items: stretch;
}
.proj-gente-nome,
.proj-gente-papel {
  font: inherit;
  cursor: pointer;
  /* alvo de toque: 36 px no computador; no celular o bloco de `pointer: coarse`, mais abaixo, sobe
     para os 44 px que o dedo pede */
  min-height: 36px;
  transition:
    background-color var(--rapido) ease,
    border-color var(--rapido) ease,
    color var(--rapido) ease,
    transform 160ms var(--saida);
}
.proj-gente-nome:active,
.proj-gente-papel:active {
  transform: scale(0.96);
}
.proj-gente-nome {
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--foreground);
  font-size: 13px;
}
@media (hover: hover) and (pointer: fine) {
  .proj-gente-nome:hover:not(:disabled) {
    border-color: var(--primary);
  }
}
.proj-gente-par .proj-gente-nome {
  border-radius: 999px 0 0 999px;
  border-right: 0;
}
/* DENTRO NÃO É SÓ COR: o fundo enche E o peso sobe E o papel aparece ao lado. Quem não distingue cor
   continua vendo que a pessoa está no projeto, pela palavra "principal"/"apoio" (WCAG 1.4.1). A cor
   é a de destaque do painel desde a r07 ("botões mais coloridos"); era o preto do texto. */
.proj-gente-nome--dentro {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: 600;
}
.proj-gente-papel {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border: 1px solid var(--primary);
  border-radius: 0 999px 999px 0;
  background: var(--accent);
  color: var(--foreground);
  font-size: 12px;
}
/* quem está com o acesso desligado: continua marcado (tocar tira), e a nota diz por que não recebe
   aviso; depois de tirado, o botão fica apagado e não marca de novo (a rota recusaria) */
/* o desenho de "trocar" ao lado da palavra do papel: diz sem texto que tocar alterna (r11) */
.proj-gente-papel-icone {
  width: 13px;
  height: 13px;
  opacity: 0.75;
}
.proj-gente-nota {
  margin-left: 6px;
  font-size: 12px;
  font-weight: 400;
}
.proj-gente-nome:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.proj-gente-antigo {
  margin: 8px 0 0;
  font-size: 12.5px;
  color: var(--alerta);
}
.proj-gente-vazio {
  margin: 0;
  font-size: 12.5px;
  color: var(--muted-foreground);
}
@media (pointer: coarse) {
  .proj-gente-nome,
  .proj-gente-papel,
  .proj-opcao {
    min-height: 44px;
  }
}

/* ---------- ATIVIDADES RECENTES: o mural de quem fez o quê, dentro da mesma ficha ----------
   Nasceu em 18/09/2026 (`secaoDeAtividades`, assets/js/telas/projetos.js): uma lista de linhas
   escritas por quem pode, com autor e hora que o SERVIDOR carimbou — nunca o que a tela acabou de
   digitar (o `.prepend` de lá é explícito sobre isso). Aqui só o desenho: separar isto do bloco de
   fatos ali em cima, dar um teto de altura pra lista não empurrar o rodapé da janela (Editar /
   Arquivar / Apagar) pra fora da tela, e marcar cada linha como um ponto numa linha do tempo. */
.proj-atividades-bloco {
  /* borda fina em cima + respiro: sem isso a seção colava direto no `.proj-fatos` de cima e virava
     uma continuação confusa dele, em vez de uma seção nova com nome próprio */
  margin-top: 4px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
/* MESMO PESO E TAMANHO DOS OUTROS RÓTULOS da tela — o "Mover para" do rodapé (`.proj-mover-rotulo`,
   mais acima) usa a mesma receita. Um `<h3>` que gritasse tamanho de título ia brigar com o nome do
   projeto no topo da janela, que é o único título que a ficha tem. */
.proj-atividades-titulo {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted-foreground);
}
/* o recado de estado ("Carregando…", "Ninguém escreveu nada aqui ainda…"): texto secundário,
   discreto — do mesmo jeito que o resto da tela trata texto de apoio. */
.proj-atividades-recado {
  margin: 0;
  font-size: 13px;
  color: var(--muted-foreground);
}
/* QUANDO A LEITURA FALHA, `secaoDeAtividades` soma `.proj-erro` NESTA MESMA TAG, e o vermelho tem
   de vencer o cinza de apoio ali em cima — "não deu para ler" é uma frase diferente de "ninguém
   escreveu nada", a mesma separação carregando/vazio/erro que o resto da tela já cobra (Q17).
   `.proj-erro` sozinho e `.proj-atividades-recado` sozinho têm a MESMA especificidade (uma classe
   cada); só a ordem no arquivo decidiria quem ganha, e ordem é frágil — outra edição bem
   intencionada lá em cima inverteria o resultado sem ninguém perceber. Duas classes juntas aqui
   pesam mais que uma, então esta regra vence SEMPRE, não só hoje: `npx biome check` não pega isso,
   quem pega é ler as duas regras e contar classe. */
.proj-atividades-recado.proj-erro {
  color: var(--perigo);
}
/* A LISTA PODE CRESCER — é atualização de projeto, escrita toda semana — e sem um teto de altura
   ela empurra o rodapé da janela pra fora da tela. Rolagem PRÓPRIA aqui, não da janela inteira:
   quem lê continua vendo o título da seção e a caixa de escrever sem ter que descer a ficha toda. */
.proj-atividades {
  display: grid;
  gap: 12px;
  max-height: 280px;
  /* O RESPIRO EMBAIXO existe porque a lista CORTA a última linha no meio (o `max-height` logo
     acima, com rolagem própria): sem ele, o aviso de "Mostrando as 200 mais novas" encostava a
     0 px no pedaço de texto cortado e os dois liam como um bloco colidido -- medido por crítico de
     contexto limpo em 18/09/2026, com a foto. */
  margin: 0 0 8px;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}
/* CADA ITEM É UM PONTO NUMA LINHA DO TEMPO, não um cartão: um traço vertical à esquerda marca a
   sequência sem precisar de um ícone por entrada, e o respiro entre pontos vem do `gap` da lista
   acima — não duplicado aqui. */
.proj-atividade {
  padding-left: 12px;
  border-left: 2px solid var(--border);
}
.proj-atividade-texto {
  margin: 0;
  /* preserva a quebra de linha que a pessoa digitou no textarea E quebra palavra comprida sem
     estourar a largura da janela — as duas juntas, porque `white-space: pre-wrap` sozinho não
     impede uma palavra sem espaço (um link colado, por exemplo) de vazar pra fora da ficha */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.proj-atividade-quem {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--muted-foreground);
}
/* A LINHA QUE ACABOU DE ENTRAR: um realce que esmaece sozinho, pro olho achar rápido o que acabou
   de ser escrito sem precisar de "veja, chegou algo" em texto. Cor do próprio design system
   (`--accent`, o mesmo tom que o resto do painel usa pra destacar sem gritar) — nenhum verde novo
   inventado só pra isto. */
@keyframes proj-atividade-realce {
  from {
    background-color: var(--accent);
  }
  to {
    background-color: transparent;
  }
}
.proj-atividade--nova {
  border-radius: var(--radius-sm);
  animation: proj-atividade-realce 1.8s var(--saida);
}
/* MOVIMENTO REDUZIDO: o bloco global de tokens.css já zera duração e atraso de toda animação, mas
   aqui a duração zerada ainda deixaria a linha presa no ÚLTIMO quadro do keyframe — que é
   `background-color: transparent`, ou seja, sem realce nenhum, o que por acaso é o resultado
   certo. Mesmo assim a regra fica explícita, no mesmo padrão que o resto do arquivo já usa pra
   movimento reduzido (ver o bloco `@media (prefers-reduced-motion: reduce)` da seção "movimento
   reduzido", mais acima): quem lê a folha de estilo não devia precisar ir até tokens.css pra confirmar que
   esta animação em especial está coberta. */
@media (prefers-reduced-motion: reduce) {
  .proj-atividade--nova {
    animation: none;
    background-color: transparent;
  }
}
.proj-atividade-form {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}
.proj-atividade-campo {
  resize: vertical;
}

/* ---------- ANEXOS: documento, foto, vídeo e recado de voz ----------
   O PEDIDO, do Carvalho em 18/09/2026: "Entregue o botão de anexar documentos, imagens e também de
   enviar áudio". Nenhuma cor nova nasce aqui: tudo sai dos tokens que o painel já usa
   (`--border`, `--muted-foreground`, `--perigo`), pela mesma razão do resto deste arquivo. */
.proj-anexos-secao {
  margin-top: 20px;
}
.proj-anexos-secao > h3 {
  margin: 0 0 8px;
  font-size: 14px;
}
.proj-anexos {
  display: grid;
  gap: 12px;
  /* mesma altura e mesma rolagem própria do rastro logo acima: uma frente com dez fotos não pode
     empurrar o rodapé da janela para fora da tela de um celular */
  max-height: 320px;
  margin: 0 0 8px;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}
.proj-anexo {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-start;
  justify-content: space-between;
  padding-left: 12px;
  border-left: 2px solid var(--border);
}
.proj-anexo-corpo {
  /* `min-width: 0` num filho de flex NÃO É DETALHE: sem ele o filho nunca encolhe abaixo do
     conteúdo, e um nome de arquivo comprido empurra os botões para fora da janela em vez de
     quebrar. É a mesma armadilha que o quadro já paga em `.proj-quadro`. */
  flex: 1 1 200px;
  min-width: 0;
}
.proj-anexo-linha {
  margin: 4px 0 0;
  font-size: 13px;
  /* nome de arquivo não tem espaço para quebrar: sem isto, "orcamento-cftv-revisado-final.pdf"
     vaza pela borda da janela */
  overflow-wrap: anywhere;
}
.proj-anexo-peso,
.proj-anexo-quem {
  color: var(--muted-foreground);
  font-size: 12px;
}
.proj-anexo-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.proj-anexo-foto {
  display: block;
  /* a miniatura tem TETO nos dois lados: uma foto de celular em pé mede 3000 px de altura, e sem o
     `max-height` ela ocupa a janela inteira e esconde o resto do projeto */
  max-width: 100%;
  max-height: 180px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  object-fit: contain;
}
.proj-anexo-som {
  width: 100%;
  max-width: 320px;
}
.proj-anexo-fala {
  margin: 4px 0 0;
  font-size: 13px;
  /* a transcrição é o que alguém vai LER para agir em cima do recado: ela preserva a quebra que a
     fala produziu e quebra palavra comprida sem estourar a janela */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.proj-anexo-semfala,
.proj-anexo-semfoto {
  margin: 4px 0 0;
  color: var(--muted-foreground);
  font-size: 12px;
}
.proj-anexos-recado,
.proj-anexos-limite {
  margin: 0 0 8px;
  color: var(--muted-foreground);
  font-size: 12px;
}
.proj-anexos-erro {
  margin: 0 0 8px;
  color: var(--perigo);
  font-size: 13px;
}
.proj-anexos-envio {
  margin-top: 12px;
}
.proj-anexos-barra {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* O `<input type="file">` DE VERDADE FICA ESCONDIDO, e o botão ao lado é quem o aciona. Não é
   `display: none`: um campo assim some da árvore de acessibilidade e de alguns navegadores antigos,
   e o `.click()` programático deixa de funcionar. Ele fica de 1 px, fora de vista e sem ocupar
   espaço, que é a forma que continua clicável por código. */
.proj-anexo-escondido {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.proj-grava-estado,
.proj-grava-fala {
  margin: 8px 0 0;
  font-size: 13px;
}
.proj-grava-fala {
  color: var(--muted-foreground);
  /* o texto vai crescendo enquanto a pessoa fala: sem teto, a janela pula de tamanho a cada frase */
  max-height: 96px;
  overflow-y: auto;
}
/* GRAVANDO: a cor de perigo, que é a convenção universal de "está gravando", e um pulso lento para
   quem não distingue a cor. O pulso respeita movimento reduzido logo abaixo. */
.proj-grava-ligado {
  border-color: var(--perigo);
  color: var(--perigo);
  animation: proj-grava-pulso 1.6s ease-in-out infinite;
}
@keyframes proj-grava-pulso {
  50% {
    opacity: 0.55;
  }
}
@media (prefers-reduced-motion: reduce) {
  .proj-grava-ligado {
    animation: none;
  }
}
/* O ÁUDIO NO ALTO DA JANELA DO PROJETO, com o botão grande de tocar (tarefa r11, 24/09/2026). O
   pedido: "precisa ser fácil a reprodução do áudio quando qualquer um clicar no card". O botão é um
   círculo de 56 px na cor de destaque (o alvo de toque confortável num celular é de 44 px para
   cima), com a duração escrita ao lado; o `<audio>` de verdade não tem `controls` e não aparece. */
.proj-recados {
  margin: 14px 0 4px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--accent);
}
.proj-recados-titulo {
  margin: 0 0 10px;
  font-size: 14px;
}
.proj-recados-lista {
  display: grid;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.proj-recado {
  display: grid;
  gap: 6px;
  min-width: 0;
}
.proj-recado + .proj-recado {
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.proj-recado-linha {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.proj-recado-tocar {
  display: inline-grid;
  flex: 0 0 auto;
  place-items: center;
  width: 56px;
  height: 56px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--primary);
  color: var(--primary-foreground);
  cursor: pointer;
  transition:
    transform 160ms var(--saida),
    background-color var(--rapido) ease;
}
.proj-recado-tocar svg {
  width: 24px;
  height: 24px;
}
/* o triângulo de "tocar" tem o peso à esquerda: 2 px para a direita o põem no centro que o olho vê */
.proj-recado:not(.proj-recado--tocando) .proj-recado-tocar svg {
  transform: translateX(2px);
}
.proj-recado-tocar:active {
  transform: scale(0.94);
}
.proj-recado-tocar:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 3px;
}
.proj-recado-tocar:disabled {
  background: var(--muted);
  color: var(--muted-foreground);
  cursor: not-allowed;
}
.proj-recado-meio {
  display: grid;
  flex: 1 1 auto;
  gap: 4px;
  min-width: 0;
}
.proj-recado-meio .proj-anexo-linha {
  margin: 0;
}
.proj-recado-barra {
  width: 100%;
  margin: 0;
  accent-color: var(--primary);
}
/* NO DEDO A BARRA DO AUDIO TEM 44 PX DE ALTURA DE TOQUE. MEDIDO a 390 (r12,
   scripts/testar-largura-e-celular.mjs): 16 px de altura, e errar a barra por 10 px no celular fazia
   o toque cair no texto de baixo em vez de pular o recado. A trilha continua fina e no meio: o que
   cresce e a area que aceita o dedo. */
@media (pointer: coarse) {
  .proj-recado-barra {
    min-height: 44px;
  }
}
.proj-recado-tempo {
  color: var(--muted-foreground);
  font-family: var(--fonte-numero);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.proj-recado .proj-anexo-fala,
.proj-recado .proj-anexo-semfala {
  margin: 0;
}
/* O VÍDEO: um botão "Assistir ao vídeo" até alguém pedir, depois o próprio vídeo, com teto de altura
   pelo mesmo motivo da miniatura de foto (um vídeo em pé de celular ocuparia a janela inteira) */
.proj-video {
  margin: 4px 0 0;
}
.proj-anexo-filme {
  display: block;
  width: 100%;
  max-width: 420px;
  max-height: 260px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--muted);
}
/* A ÁREA "ANEXOS" DA JANELA NOVO PROJETO: o mesmo bloco das seções (borda, raio e fundo), sem número,
   porque é opcional e não é um passo */
.proj-anexos-bloco {
  display: grid;
  gap: 8px;
  min-width: 0;
  padding: 12px 14px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}
.proj-anexos-titulo {
  margin: 0;
  font-size: 14px;
}
.proj-anexos-form {
  display: grid;
  gap: 8px;
  min-width: 0;
}
.proj-anexos-form .proj-anexos-limite,
.proj-anexos-form .proj-anexos-erro,
.proj-anexos-form .proj-grava-estado,
.proj-anexos-form .proj-grava-fala {
  margin: 0;
}
.proj-anexos--fila {
  margin: 0;
}
/* na lista da janela de criar a prévia é só para conferir o arquivo: menor que na janela do projeto,
   para a área de anexos continuar compacta com um vídeo em pé na lista (crítico de contexto limpo,
   r11: o vídeo ocupava a largura inteira e mais de 170 px de altura) */
.proj-anexos--fila .proj-anexo-filme,
.proj-anexos--fila .proj-anexo-foto {
  width: auto;
  max-width: min(100%, 220px);
  max-height: 124px;
}
/* o andamento do envio, ao lado dos botões presos ao pé da janela */
.proj-form-andamento {
  flex: 1 1 100%;
  margin: 0;
  color: var(--muted-foreground);
  font-size: 13px;
  overflow-wrap: anywhere;
}
/* O QUE NÃO SUBIU AO CRIAR, no alto da janela do projeto, na cor de perigo */
.proj-anexos-falhas {
  margin: 0 0 12px;
}
.proj-falhas-lista {
  display: grid;
  gap: 8px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}
.proj-falha {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  align-items: center;
  justify-content: space-between;
  overflow-wrap: anywhere;
}
.proj-falha-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* ---------- O PRAZO NO CARTÃO E NA JANELA (tarefa r07, 23/09/2026) ----------
   As frases saem de `fraseDoPrazo`, em assets/js/telas/projetos.js; aqui mora a cor de cada uma:
     atrasado  -> chip cheio na cor de perigo (o pedido: "atrasado há N dias", na cor de perigo do
                  painel). O par `--perigo` e `--perigo-fundo` é o mesmo do crachá `!P01`: 5,48:1 no
                  claro e 7,22:1 no escuro, medidos quando aquele crachá foi consertado;
     perto     -> vence em até sete dias: a cor de atenção, contornada, porque o cartão de prioridade
                  1 já é pintado com o fundo de atenção e o chip sumiria nele sem o contorno;
     neutro    -> a data, sem alarme;
     sem       -> "sem prazo", tracejado e em cinza: falta de dado, não urgência. */
.proj-prazo {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 13px; /* r32, ver `.proj-marca`; a linha de 18 px segura a altura do chip */
  font-weight: 600;
  line-height: 18px;
  /* QUEBRA QUANDO NÃO CABE (r46, 28/09/2026): com `nowrap`, um prazo de outro ano ("até 31 de dezembro de
     2099") deixava o cartão mais largo que a coluna a 1440 px, encostado na coluna do lado (o medidor de
     caixa encostada de scripts/testar-passar-etapa.sh pegou, com foto). O prazo curto continua numa linha. */
  max-width: 100%;
  white-space: normal;
}
.proj-prazo--atrasado {
  color: var(--perigo-fundo);
  background: var(--perigo);
  border-color: var(--perigo);
}
.proj-prazo--perto {
  color: var(--alerta);
  background: var(--alerta-fundo);
  border-color: color-mix(in srgb, var(--alerta) 55%, transparent);
}
.proj-prazo--neutro {
  color: var(--muted-foreground);
  background: var(--card);
  border-color: var(--border);
  font-weight: 500;
}
.proj-prazo--sem {
  color: var(--muted-foreground);
  border-color: var(--input);
  border-style: dashed;
  font-weight: 500;
}
/* a linha do prazo na janela de detalhe, logo abaixo da situação */
.proj-prazo-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 0;
  font-size: 14px;
}
.proj-prazo-rotulo {
  color: var(--muted-foreground);
  font-size: 12.5px;
  font-weight: 700;
}
.proj-prazo-linha--atrasado {
  color: var(--perigo);
  font-weight: 600;
}
.proj-prazo-linha--perto {
  color: var(--alerta);
  font-weight: 600;
}
.proj-prazo-linha--sem {
  color: var(--muted-foreground);
}

/* ---------- OS BOTÕES COM COR E MOVIMENTO (tarefa r07, 23/09/2026) ----------
   O PEDIDO, nas palavras do Carvalho: "botões mais coloridos e com animação". E a regra que ele deu
   junto: a cor sai dos tokens que o painel JÁ tem (destaque, e os de bom, atenção e perigo), e o tema
   não muda. Então a cor aqui é SIGNIFICADO, nunca enfeite:
     "Novo projeto" e "Criar projeto"  -> a cor de destaque, cheia (é a ação principal da tela);
     "Mover para ..."                   -> cada destino na cor da SUA coluna (a faixa do alto dela),
                                           com um ponto dessa cor antes da palavra;
     "Editar"                           -> destaque, vazado;
     "Arquivar"                         -> atenção (tira da tela, e volta);
     "Apagar"                           -> perigo (não tem volta).
   O MOVIMENTO: todo botão já encolhe um pouco ao ser apertado (`.btn:active`, em componentes.css:
   `scale(0.97)` em 160 ms); aqui os principais sobem 1 px sob o mouse, e os coloridos enchem a tinta.
   Nada disso é mais longo que 200 ms (princípio V da constituição: interface de trabalho é rápida).
   A ESPECIFICIDADE: `.btn.vazado` (componentes.css) vale (0,2,0) e deixa o fundo transparente; as
   regras daqui somam `.proj-btn-*` a ela para ganhar sem depender da ordem dos arquivos. */
.proj-btn-novo.btn.primario {
  box-shadow: var(--sombra-md);
}
@media (hover: hover) and (pointer: fine) {
  .proj-btn-novo.btn.primario:hover,
  .proj-btn-salvar.btn.primario:hover {
    transform: translateY(-1px);
    box-shadow: var(--sombra-lg);
  }
  .proj-btn-novo.btn.primario:active,
  .proj-btn-salvar.btn.primario:active {
    transform: scale(0.97);
  }
}
.proj-btn-mover.btn.vazado {
  --proj-cor: var(--muted-foreground);
  border-color: color-mix(in srgb, var(--proj-cor) 50%, var(--border));
  background: color-mix(in srgb, var(--proj-cor) 8%, transparent);
  color: var(--proj-cor);
}
.proj-btn-mover.btn::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--proj-cor);
}
.proj-btn-editar.btn.vazado {
  border-color: color-mix(in srgb, var(--primary) 50%, var(--border));
  color: var(--primary);
}
.proj-btn-arquivar.btn.vazado {
  border-color: color-mix(in srgb, var(--alerta) 50%, var(--border));
  color: var(--alerta);
}
.proj-btn-apagar.btn.vazado {
  border-color: color-mix(in srgb, var(--perigo) 50%, var(--border));
  color: var(--perigo);
}
@media (hover: hover) and (pointer: fine) {
  .proj-btn-mover.btn.vazado:hover {
    border-color: var(--proj-cor);
    background: color-mix(in srgb, var(--proj-cor) 16%, transparent);
  }
  .proj-btn-editar.btn.vazado:hover {
    border-color: var(--primary);
    background: var(--accent);
  }
  .proj-btn-arquivar.btn.vazado:hover {
    border-color: var(--alerta);
    background: var(--alerta-fundo);
  }
  .proj-btn-apagar.btn.vazado:hover {
    border-color: var(--perigo);
    background: var(--perigo-fundo);
  }
  .proj-btn-detalhes.btn.vazado:hover {
    border-color: var(--primary);
    color: var(--primary);
  }
}
.proj-acoes--janela {
  margin-bottom: 0;
}
.proj-acoes--topo {
  align-items: center;
}
/* NO CELULAR A FILEIRA DE OPERACOES E UMA LINHA SO, QUE ROLA DE LADO (r38): os 7 botoes quebravam em 3
   linhas desiguais a 390, 375 e 360, a fileira quebrada da foto do Carvalho. E os dois botoes do alto
   (Novo projeto e o de mostrar) ocupam a linha inteira, um embaixo do outro: com a largura de cada um,
   eles caiam em duas linhas com um buraco do lado. */
@media (max-width: 639.98px) {
  .proj-filtro {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .proj-filtro > * {
    flex: none;
  }
  .proj-acoes--topo > * {
    flex: 1 1 100%;
  }
}

/* ---------- O CARTÃO QUE MUDA DE COLUNA (tarefa r07, 23/09/2026) ----------
   `deslizarDeOnde` (assets/js/telas/projetos.js) põe o cartão, já na coluna nova, de volta onde ele
   estava, e esta transição o leva até o lugar novo: o olho vê o cartão ATRAVESSAR o quadro em vez de
   sumir de um lado e aparecer do outro. `ease-in-out` (`--movimento`) porque é movimento de um ponto
   a outro da tela, que acelera e freia; 380 ms porque ele pode cruzar três colunas, e mais rápido que
   isso o trajeto não se lê. Por cima dos outros cartões enquanto anda.
   Com "reduzir movimento" ligado, o bloco global de tokens.css zera a duração, e o cartão só aparece
   no lugar novo: o painel continua como sempre foi nisso (decisão registrada na r07). */
.proj-ficha--deslizando {
  position: relative;
  z-index: 3;
  transition: transform 380ms var(--movimento);
}
/* a borda acende uma vez, na cor da coluna nova (`--proj-cor` vem da coluna), e se apaga sozinha:
   "é este aqui". Também no cartão que acabou de ser criado ou salvo. Mais pesada que a regra do
   quadro quieto, que desliga a entrada de todos os cartões, para esta continuar valendo nele. */
.proj-quadro .proj-ficha.proj-ficha--chegou {
  animation: proj-chegou 1400ms var(--saida);
}
@keyframes proj-chegou {
  0%,
  30% {
    box-shadow:
      0 0 0 3px color-mix(in srgb, var(--proj-cor, var(--ring)) 65%, transparent),
      var(--sombra-md);
  }
  100% {
    box-shadow: var(--sombra-sm);
  }
}

/* O BOTÃO "AVISAR NO GRUPO AGORA" no pé do detalhe (tarefa r19), só na conta do Carvalho: uma fileira
   própria, separada de Editar/Arquivar/Apagar, porque não mexe no projeto: manda uma mensagem. */
.proj-grupo {
  align-items: center;
}
.proj-grupo-nota {
  color: var(--muted-foreground);
  font-size: 12px;
}

/* ---------- A ETAPA: COM QUEM O PROJETO ESTÁ (tarefa r46, 28/09/2026) ----------
   No cartão, uma linha na letra de "quem faz": esperando o aceite na cor de atenção (falta alguém agir),
   devolvida na de perigo (voltou com motivo), aceita na cor normal. Quando é COM VOCÊ, o texto sobe de peso
   e ganha a cor de destaque: a cor nunca está sozinha, a frase diz "com você". */
.proj-ficha-etapa {
  margin: 0;
  font-size: 13px;
  line-height: 17.5px;
  color: var(--muted-foreground);
  overflow-wrap: break-word;
}
.proj-ficha-etapa--esperando {
  color: var(--alerta);
  font-weight: 600;
}
.proj-ficha-etapa--devolvida {
  color: var(--perigo);
  font-weight: 600;
}
.proj-ficha-etapa--comigo {
  color: var(--primary);
  font-weight: 700;
}
/* na janela, um bloco logo abaixo do prazo, com a faixa na cor do estado da etapa */
.proj-etapa {
  display: grid;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-sm);
}
.proj-etapa--esperando {
  border-left-color: var(--alerta);
}
.proj-etapa--devolvida {
  border-left-color: var(--perigo);
}
.proj-etapa-linha {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 0;
  font-size: 14px;
  overflow-wrap: anywhere;
}
.proj-etapa-rotulo {
  color: var(--muted-foreground);
  font-size: 12.5px;
  font-weight: 700;
}
.proj-etapa-recado {
  margin: 0;
  font-size: 13.5px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.proj-etapa-acoes {
  flex-wrap: wrap;
}
.proj-etapa-form {
  display: grid;
  gap: 10px;
}
.proj-etapa-campo {
  display: grid;
  gap: 4px;
}
.proj-etapa-escolha {
  width: 100%;
  min-height: 40px;
}
/* a passagem na linha do tempo: a faixa da esquerda na cor de destaque, para separar do que foi escrito */
.proj-atividade--etapa {
  border-left-color: var(--primary);
}
/* dentro do bloco da etapa o respiro é o `gap` dele; a margem de baixo da fileira comum sobraria */
.proj-etapa .proj-acoes {
  margin-bottom: 0;
}
/* "Comigo" (r46) no celular ocupa a largura toda, como os botões da fileira: o texto fica no meio, igual a eles */
.proj-filtro-comigo {
  justify-content: center;
}
