/*
  Identidade do 180 Gestor.

  Base neutra do shadcn com --primary no indigo da marca (#4D4DFF, o
  mesmo do v1). So token: nenhum componente do kit muda.

  #4D4DFF em oklch e oklch(0.543 0.254 274). Branco sobre ele da 5.5:1,
  acima do minimo AA de 4.5:1 — por isso --primary-foreground e branco.
*/

:root {
  --primary: oklch(0.543 0.254 274);
  --primary-foreground: oklch(0.985 0 0);
  --ring: oklch(0.543 0.254 274);
  --sidebar-primary: oklch(0.543 0.254 274);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-ring: oklch(0.543 0.254 274);

  /*
    VIDRO FOSCO ATRAS DO DIALOGO (Tarefa do dono, 2026-10-02: "borrar o
    fundo, no efeito de vidro translucido para focar 100% na escrita do
    modal").

    E opt-in no kit, que mantem o bg-black/50 seco do registry: o
    desfoque e escolha deste produto, e os formularios daqui sao longos
    (chamado e tarefa tem duas etapas) -- com a tabela do quadro nitida
    atras, o olho fica indo e voltando.

    8px e o ponto em que o texto de tras deixa de ser legivel sem a
    pagina virar uma mancha: abaixo disso ainda da para ler titulo de
    coluna, acima comeca a parecer defeito de renderizacao.
  */
  --dialogo-desfoque: 8px;
}

/*
  Quem pede menos transparencia no sistema pede por um motivo -- e
  geralmente o mesmo motivo que torna texto sobre fundo borrado dificil.
  O preto de 50% sozinho continua separando o dialogo do resto.
*/
@media (prefers-reduced-transparency: reduce) {
  :root { --dialogo-desfoque: 0px; }
}

.escuro {
  /*
    O indigo continua o mesmo no escuro: e a cor da marca, e trocar por
    um tom pastel faria o botao primario parecer de outro produto. So o
    anel de foco clareia, para aparecer sobre o fundo escuro.
  */
  --primary: oklch(0.543 0.254 274);
  --primary-foreground: oklch(0.985 0 0);
  --ring: oklch(0.62 0.20 274);
  --sidebar-primary: oklch(0.543 0.254 274);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-ring: oklch(0.62 0.20 274);
}

/* Marca no topo da sidebar */
.marca-produto {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.375rem 0.5rem;
  border-radius: var(--raio-md);
  transition: background-color var(--duracao-rapida) var(--curva);
}

.marca-produto:hover {
  background-color: var(--sidebar-accent);
}

/*
  O arquivo de logo (assets/img/logo.png) e o brasao completo "180
  Gestor" em 175x37px, branco sobre transparente — nao um icone
  quadrado. Altura fixa e largura livre preservam a proporcao; um
  quadrado de largura==altura com object-fit:contain so encolhia a
  logo a uma tira de ~6px de altura dentro da caixa.

  Por ser branca, a logo tambem some sobre o fundo quase-branco do
  tema claro (--sidebar e --card ficam perto de oklch(0.985 0 0)).
  O filtro brightness(0) a torna preta no claro; no escuro o fundo ja
  e escuro o bastante para a logo branca original aparecer.
*/
.marca-logo {
  flex-shrink: 0;
  height: 1.5rem;
  width: auto;
  object-fit: contain;
  filter: brightness(0);
}

.escuro .marca-logo {
  filter: none;
}

/* Tamanho maior para a tela de login, onde a logo e a unica marca visivel. */
.auth-logo {
  height: 2rem;
}

.seletor-texto {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.2;
}

.seletor-nome {
  font-size: 0.875rem;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.seletor-legenda {
  font-size: 0.75rem;
  color: var(--muted-foreground);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.seletor-acao {
  display: inline-flex;
  flex-shrink: 0;
  margin-left: auto;
  color: var(--muted-foreground);
}

.seletor-acao > svg { width: 1rem; height: 1rem; }

.menu-usuario {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.375rem 0.5rem;
  border-radius: var(--raio-md);
  text-align: left;
  transition: background-color var(--duracao-rapida) var(--curva);
}

.menu-usuario:hover { background-color: var(--sidebar-accent); }

.dropdown, .dropdown-gatilho { width: 100%; }

[data-sidebar="colapsada"] .seletor-texto,
[data-sidebar="colapsada"] .seletor-acao { display: none; }

[data-sidebar="colapsada"] .marca-produto,
[data-sidebar="colapsada"] .menu-usuario {
  justify-content: center;
  padding-inline: 0;
}

/*
  Alternador de tema. Os dois icones vivem no mesmo botao e o CSS decide
  qual aparece — sem isso o icone so trocaria com JavaScript, e piscaria
  o icone errado antes do script rodar.
*/
.gatilho-tema .icone-escuro { display: none; }
.escuro .gatilho-tema .icone-claro { display: none; }
.escuro .gatilho-tema .icone-escuro { display: block; }

/* Marcador de nao lidas no sino. O sino saiu do cabecalho por ora; a
   regra fica para quando as notificacoes voltarem. */
.com-marcador { position: relative; }

.com-marcador::after {
  content: "";
  position: absolute;
  top: 0.375rem;
  right: 0.375rem;
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 9999px;
  background-color: var(--destructive);
}

.apenas-celular { display: inline-flex; }
.apenas-desktop { display: none; }

@media (min-width: 768px) {
  .apenas-celular { display: none; }
  .apenas-desktop { display: inline-flex; }
}

.gatilho-sidebar { width: 1.75rem; height: 1.75rem; }

/*
  Alvo de toque no celular. O item de menu tem 2rem (32px) por
  especificacao do shadcn, pensada para ponteiro — o kit ja aumenta
  .sidebar-item para 2.75rem abaixo de 768px (componentes.css). Aqui
  completa o que ficou de fora, o subitem do submenu e o botao que abre
  o drawer: no drawer, quem toca precisa de 44px, o minimo das
  diretrizes de acessibilidade.

  E media query de viewport de proposito, nao de container: alvo de
  toque e sobre o dispositivo de entrada, nao sobre a largura do
  conteudo — nao trocar por @container.
*/
@media (max-width: 767px) {
  .sidebar-subitem {
    min-height: 2.75rem;
  }

  .gatilho-sidebar {
    width: 2.75rem;
    height: 2.75rem;
  }
}

/*
  Barra de busca: campo elastico com os botoes na mesma linha.

  O .campo do kit e display:block com width:100%, que e o certo para um
  formulario empilhado. Dentro de um flex, porem, esse 100% vira a
  largura preferida e empurra os botoes para a linha de baixo. Aqui a
  largura passa a ser elastica, e o min-width:0 de .crescer deixa o campo
  encolher em vez de estourar a linha no celular.

  E composicao de tela, nao componente: por isso mora aqui e nao no kit.
*/
.barra-busca {
  flex-wrap: nowrap;
}

.barra-busca .campo {
  width: auto;
}

/*
  Grade de tres colunas, para listas curtas de cartao (casas noturnas).

  Mede o container, nao a janela, pelo mesmo motivo de .grade-metricas:
  com a sidebar aberta, 1024px de janela sao ~768px de conteudo.
*/
.grade-tres {
  grid-template-columns: minmax(0, 1fr);
}

@container main (min-width: 36rem) {
  .grade-tres {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@container main (min-width: 64rem) {
  .grade-tres {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/*
  Painel de duas colunas (grafico maior, resumo ao lado) e par de
  colunas iguais (duas tabelas lado a lado). Medem o container, nao a
  janela, pelo mesmo motivo de .grade-tres.
*/
.grade-painel,
.grade-dois {
  grid-template-columns: minmax(0, 1fr);
}

@container main (min-width: 56rem) {
  .grade-painel {
    grid-template-columns: 2fr 1fr;
  }

  .grade-dois {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/*
  Um cartao sozinho num par de .grade-dois ocupa a grade inteira, em vez
  de ficar preso a metade da largura com um vao vazio ao lado. A home e
  Financeiro > Visao geral sempre tem os dois cartoes do par, entao a
  regra nunca ativa neles; a ficha do cliente (Tarefa 30) e a primeira
  tela onde um dos dois lados de um par pode faltar (um cliente sem
  contrato, por exemplo).
*/
.grade-dois > *:only-child {
  grid-column: 1 / -1;
}

/*
  Link de volta no topo de uma tela de detalhe. Quem entra por um link
  precisa de uma saida visivel — o item de menu marcado nao serve, porque
  ele aponta para a listagem inteira, nao para o lugar de onde se veio.
*/
.voltar-para {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  align-self: flex-start;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  color: var(--muted-foreground);
  transition: color var(--duracao-rapida) var(--curva);
}

.voltar-para:hover {
  color: var(--foreground);
}

.voltar-para > svg {
  width: 1rem;
  height: 1rem;
}

/* Titulo de celula que vira link para a tela de detalhe. */
.celula-link:hover .celula-titulo {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Celula com titulo e legenda, usada nas listagens de evento */
.celula-evento {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.celula-titulo {
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.celula-legenda {
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
}

/*
  Tarefa 31: nome de cliente como link em coluna SECUNDARIA (nao e o
  titulo da linha, que ja usa .celula-link acima) — faturas, contratos,
  chamados, o card de uma tarefa etc. Mesmo criterio silencioso do
  .celula-link: nunca muda de cor, so sublinha no hover. Uma tabela ja
  densa de badge e link nao pode virar um campo inteiro de texto azul so
  porque toda linha agora aponta para uma ficha.
*/
.link-cliente {
  text-decoration: none;
}

.link-cliente:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Cards de metrica: degrade sutil do dashboard-01 e nota com icone */
.grade-metricas > .card {
  background-image: linear-gradient(
    to top,
    color-mix(in oklab, var(--primary) 5%, transparent),
    var(--card)
  );
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
}

/*
  Nao ha sobrescrita de tipografia aqui de proposito. O rotulo ja e
  .card-descricao (14px no kit) e o numero ja e .card-titulo
  (leading-none, peso 600), exatamente como no dashboard-01. O tamanho do
  numero fica em .metrica-valor, com a container query do shadcn.
*/
.metrica-nota {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
}

.metrica-nota > svg {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
}

/*
  Metricas secundarias: mesma estrutura, card menor. --card-espaco e a
  variavel que .card ja usa para seu proprio padding — reduzi-la aqui
  encolhe o card inteiro sem duplicar as regras de espacamento do kit.
*/
.metrica-compacta {
  --card-espaco: 1rem;
}

/*
  Sobrescreve tanto o tamanho base quanto o salto do @container card do
  kit (que so vale a partir de 250px): a secundaria nunca deve crescer
  tanto quanto a metrica em destaque, mesmo numa coluna larga.
*/
.metrica-valor-compacto {
  font-size: 1.25rem;
}

/* Variacao (alta/baixa) ao lado do rotulo, no cabecalho do card */
.metrica-variacao {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
}

.metrica-variacao > svg {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
}

/*
  Verde fora da paleta shadcn: nenhum token do tema serve para "alta" (o
  --primary e o indigo da marca, nao tem sentido de positivo/negativo).
  Le --cor-ok, o verde de estado do kit (ui/tokens.css), que tem contraste
  equivalente ao vermelho de --destructive e variante para o tema escuro.
*/
.variacao-alta {
  color: var(--cor-ok);
}

.variacao-baixa {
  color: var(--destructive);
}

/*
  Dois campos lado a lado no formulario de criar evento. Empilha no
  celular: dois selects de 36px lado a lado em 390px nao deixam espaco
  para o rotulo nem para a seta.
*/
.grade-dupla {
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 640px) {
  .grade-dupla {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/*
  A regra acima faz todo dropdown ocupar a largura toda, porque o menu do
  usuario na sidebar precisa disso. Numa celula de tabela o gatilho e um
  botao de 36px, e esticar o dropdown esticaria a coluna de acoes junto.
*/
.tabela .dropdown,
.tabela .dropdown-gatilho {
  width: auto;
}

/*
  A direcao "lado" do dropdown abre a direita do gatilho, que e o que o
  menu do usuario da sidebar precisa. Na ultima coluna da tabela o
  gatilho ja esta na borda direita do card: o painel sai por fora do
  .tabela-envolucro, que tem overflow-x: auto e o recortaria — e, mesmo
  fechado, ele ja fazia a tabela ganhar barra de rolagem horizontal.

  Aqui o mesmo menu abre do outro lado, mantendo o alinhamento pela base.
  E uma correcao de posicionamento, nao de medida: o painel continua com
  os mesmos 12rem, raio e sombra do kit.
*/
.tabela .dropdown-painel.dropdown-lado {
  top: auto;
  bottom: 0;
  left: auto;
  right: calc(100% + 0.25rem);
  transform: translateX(4px) scale(0.98);
}

.tabela [data-aberto] > .dropdown-painel.dropdown-lado {
  transform: translateX(0) scale(1);
}

/* ==========================================================================
   Tela de entrada. Medidas do bloco login-03 do shadcn: card de 384px,
   espacamento interno de 24px, cabecalho centrado, titulo 20px/28px
   peso 600 e rodape de termos em 14px com os links sublinhados.
   ========================================================================== */

.tela-auth {
  display: flex;
  min-height: 100svh;
  padding: 1.5rem 1rem;
  padding-top: max(1.5rem, env(safe-area-inset-top));
  padding-bottom: max(1.5rem, env(safe-area-inset-bottom));
  background-color: var(--muted);
}

.auth-centro {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

.auth-caixa {
  width: 100%;
  max-width: 24rem;
}

.auth-caixa > .card {
  --card-espaco: 1.5rem;
}

.auth-caixa .card-cabecalho {
  justify-items: center;
  text-align: center;
  gap: 0.5rem;
}

.auth-caixa .card-titulo {
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 600;
}

.auth-marca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--raio-md);
  background-color: var(--primary);
  color: var(--primary-foreground);
  font-size: 0.75rem;
  font-weight: 600;
}

.auth-divisor {
  position: relative;
  text-align: center;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
}

.auth-divisor::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 1px;
  background-color: var(--border);
}

.auth-divisor > span {
  position: relative;
  padding-inline: 0.5rem;
  background-color: var(--card);
}

.auth-termos {
  font-size: 0.875rem;
  line-height: 1.3125rem;
  text-align: center;
  color: var(--muted-foreground);
}

.auth-termos a {
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* ==========================================================================
   Home ("Painel"). O grafico de receita x despesa e um par de barras por
   mes: .grafico-barra/.grafico-coluna/.grafico-rotulo ja vem do kit, so a
   segunda barra por coluna e as duas cores sao novas.
   ========================================================================== */

/*
  Na grade-painel o card do grafico fica ao lado do funil comercial, que
  costuma ser mais alto (uma linha por etapa). A grade estica os dois
  cards para a mesma altura, entao uma altura fixa aqui sobrava como
  espaco morto abaixo da legenda. As barras crescem para preencher a
  altura disponivel em vez de ficarem presas a 12rem; o piso continua
  em 12rem para o grafico nao ficar baixo demais quando o funil for
  curto.
*/
.card:has(.grafico-par-barras) > .card-conteudo {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}

.grafico-par-barras {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  flex: 1 1 auto;
  min-height: 12rem;
  padding-top: 1rem;
}

.grafico-par-coluna {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
}

/*
  flex: 1 1 auto (em vez de height: 100%) deixa o rotulo abaixo reservar
  sua propria altura primeiro; o que sobra e o que .grafico-barra usa como
  base para o data-altura em porcentagem.
*/
.grafico-par-barras-item {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 0.1875rem;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
}

/* .grafico-barra ja define largura, altura via --altura e raio; so a cor muda. */
.barra-receita {
  width: 40%;
  background-color: var(--primary);
}

.barra-despesa {
  width: 40%;
  background-color: color-mix(in oklab, var(--primary) 28%, var(--muted));
}

.grafico-legenda {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
}

.grafico-legenda-item {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.grafico-legenda-cor {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: var(--raio-sm);
  flex-shrink: 0;
}

.grafico-legenda-cor-receita {
  background-color: var(--primary);
}

.grafico-legenda-cor-despesa {
  background-color: color-mix(in oklab, var(--primary) 28%, var(--muted));
}

/*
  Ocultar valores: mascara todo valor monetario da tela de uma vez, por
  atributo no <html>, e nao elemento a elemento.

  No <html> para o script do <head> poder marcar antes da primeira
  pintura — no <body>, a escolha guardada so valeria depois que a pagina
  ja tivesse mostrado os numeros uma vez.
*/
:root[data-ocultar-valores] .valor-sigiloso {
  color: transparent;
  background-color: var(--muted);
  border-radius: var(--raio-sm);
  user-select: none;
}

/* ==========================================================================
   Agenda. Semana de sete colunas ao lado do painel "Hoje", igual em
   estrutura ao par grafico/funil da home: .grade-painel do kit ja resolve
   o 2fr/1fr e a pilha vertical abaixo de 56rem.

   As quatro cores de tipo (reuniao/ligacao/visita/vencimento) usam os
   tokens de grafico do kit — nunca uma cor nova — porque --chart-1..5 e
   --destructive ja mudam entre os temas claro e escuro sozinhos.
   ========================================================================== */

.agenda-cor-reuniao { --agenda-cor: var(--chart-1); }
.agenda-cor-ligacao { --agenda-cor: var(--chart-2); }
.agenda-cor-visita { --agenda-cor: var(--chart-3); }
.agenda-cor-vencimento { --agenda-cor: var(--destructive); }

/*
  AS SETE FONTES AUTOMATICAS, que entraram em 19/09/2026 quando a agenda
  passou a mostrar o que VENCE e nao so o que foi digitado.

  Mesma regra de cima: nenhuma cor nova, so token de grafico. Fatura e
  proposta dividem o mesmo token de proposito — as duas sao dinheiro
  entrando, e a legenda nomeia cada uma. Despesa fica com --destructive
  porque e a unica que e dinheiro saindo.
*/
.agenda-cor-fatura { --agenda-cor: var(--chart-2); }
.agenda-cor-proposta { --agenda-cor: var(--chart-2); }
.agenda-cor-despesa { --agenda-cor: var(--destructive); }
.agenda-cor-dominio { --agenda-cor: var(--chart-3); }
.agenda-cor-servidor { --agenda-cor: var(--chart-5); }
.agenda-cor-contrato { --agenda-cor: var(--chart-4); }
.agenda-cor-projeto { --agenda-cor: var(--chart-1); }

/* So o chip usa esta: o compromisso digitado chega com o proprio tipo
   (reuniao/lembrete/outro), nunca com 'evento'. Mesma cor de reuniao,
   que e o tipo mais comum dos tres. */
.agenda-cor-evento { --agenda-cor: var(--chart-1); }

.agenda-legenda {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
}

.agenda-legenda-item {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.agenda-legenda-cor {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: var(--raio-sm);
  flex-shrink: 0;
  background-color: var(--agenda-cor);
}

/*
  Sete colunas empilhadas por padrao (lista legivel abaixo de 768px) e
  lado a lado so quando o card tem largura de sobra. Medir main direto,
  como .grade-tres e .grade-painel, mantem a mesma convencao do resto da
  tela — e evita inventar um segundo container nomeado so para isto.
  64rem e o mesmo salto que .grade-tres ja usa para tres colunas; com
  grade-painel em 2fr/1fr a essa largura o card "Semana" ainda sobra
  ~43rem, o bastante para sete colunas legiveis.
*/
.agenda-semana {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

@container main (min-width: 64rem) {
  .agenda-semana {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.5rem;
  }
}

.agenda-coluna {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem;
  border-radius: var(--raio-md);
}

/* Coluna de hoje: fundo sutil e cabecalho mais forte, para o olho pousar nela primeiro. */
.agenda-coluna-hoje {
  background-color: var(--muted);
}

.agenda-coluna-cabecalho {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
}

.agenda-coluna-hoje .agenda-coluna-cabecalho {
  color: var(--foreground);
  font-weight: 600;
}

.agenda-coluna-dia {
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.agenda-coluna-lista {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  min-height: 1.5rem;
}

/*
  Dia sem compromissos: um travessao discreto, nao um estado vazio grande
  do kit. A coluna continua do mesmo tamanho que as vizinhas — colapsar
  faria a grade de sete colunas ficar recortada.
*/
.agenda-coluna-vazia {
  font-size: 0.75rem;
  color: var(--muted-foreground);
}

/*
  Bloco compacto da grade da semana.

  Borda de 1px e sombra de 1px sao o que o .card do kit ja faz (shadow-xs
  do new-york-v4): sem elas o bloco e --card sobre --card e some dentro
  do proprio cartao, sobrando so a barra colorida da esquerda.

  Precisa dos dois. A sombra sozinha resolve o tema claro e desaparece no
  escuro, onde preto sobre fundo escuro nao contrasta; a borda sozinha
  fica dura no claro. Juntas funcionam nos dois.
*/
.agenda-bloco {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--agenda-cor, var(--border));
  border-radius: var(--raio-sm);
  background-color: var(--card);
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
}

.agenda-bloco-hora {
  font-size: 0.6875rem;
  color: var(--muted-foreground);
}

.agenda-bloco-titulo {
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Item do painel "Hoje": mesma borda colorida, com os quatro campos por extenso. */
.agenda-item {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.625rem 0.75rem;
  border-left: 3px solid var(--agenda-cor, var(--border));
  border-radius: var(--raio-sm);
  background-color: color-mix(in oklab, var(--agenda-cor, var(--muted)) 6%, var(--card));
}

.agenda-item-hora {
  font-size: 0.8125rem;
}

.agenda-item-titulo {
  font-size: 0.875rem;
}

/*
  Badge por tipo: borda e texto na cor do tipo sobre um fundo quase
  transparente, em vez de preenchimento solido. --chart-3 no escuro e
  bem claro (oklch L 0.769) — texto branco sobre ele perderia contraste;
  usar a propria cor do token como texto, como .texto-destrutivo ja faz
  no kit, funciona nos dois temas sem checar luminosidade caso a caso.
*/
.agenda-badge {
  border-color: var(--agenda-cor);
  color: var(--agenda-cor);
  background-color: color-mix(in oklab, var(--agenda-cor) 14%, transparent);
}

/*
  Cartao urgente, nos quadros de Tarefas e Chamados
  (recursos/paginas/painel/tarefas.php e chamados.php): tarefa de
  prioridade alta, ou chamado critico (prioridade alta com 'aberto_ha'
  em dias/semanas, nao horas). Borda esquerda vermelha no cartao inteiro,
  o mesmo recurso que .agenda-item ja usa para marcar categoria por cor
  — a urgencia precisa se ver sem abrir o cartao nem ler o badge.
*/
.quadro-cartao-urgente {
  border-left: 3px solid var(--destructive);
}

/*
  Mural de avisos (conhecimento/avisos.php): reaproveita .quadro-cartao
  do kit (borda, raio, sombra) empilhado numa pilha vertical, nao numa
  coluna de quadro — nao ha nada aqui para arrastar entre situacoes. So
  os dois acrescimos abaixo sao vocabulario deste produto.

  Fixado ganha o mesmo friso lateral que .quadro-cartao-urgente ja usa
  para tarefa de prioridade alta (destaque permanente em vez de
  urgencia, cor da marca em vez de destrutiva). Nao lido marca DUAS
  coisas ao mesmo tempo — peso do titulo e um ponto solido antes dele —
  de proposito, o mesmo motivo de .agenda-badge nao depender so de cor:
  nao pode exigir percepcao de cor para notar a diferenca. Lido recua
  com fundo --muted, o mesmo token neutro que .quadro-coluna-corpo ja
  usa para "container de conteudo, nao cartao em destaque".
*/
.aviso-cartao-fixado {
  border-left: 3px solid var(--primary);
}

.aviso-cartao-lido {
  background-color: var(--muted);
}

.aviso-titulo {
  font-weight: 600;
}

.aviso-cartao-lido .aviso-titulo {
  font-weight: 500;
  color: var(--muted-foreground);
}

.aviso-ponto-nao-lido {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  flex-shrink: 0;
  border-radius: 999px;
  background-color: var(--primary);
}

.aviso-pin-icone {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
  color: var(--primary);
}

/*
  Historico de agentes de IA (ia/historico.php, Tarefa 33): um log le-se
  como fluxo, nao como tabela — cada registro e uma linha solta (horario,
  nivel, agente, mensagem), separada da proxima por .separador do kit, em
  vez de tabela(). As duas larguras minimas evitam que a mensagem (o
  campo que importa) fique espremida quando o nome do agente e longo;
  .linha ja tem flex-wrap, entao em telas estreitas os campos quebram
  para a linha de baixo em vez de estourar a largura.
*/
.historico-linha {
  padding-block: 0.625rem;
  align-items: flex-start;
}

.historico-quando {
  flex-shrink: 0;
  min-width: 5.5rem;
}

.historico-agente {
  flex-shrink: 0;
  min-width: 9rem;
}

/* ==========================================================================
   Cartao de Tarefas/Chamados — variante C ("estilo Monday"), escolhida
   pelo dono em /painel/cartoes (dev-only, ver
   recursos/paginas/painel/cartoes.php e
   recursos/componentes/app/cartoes-comparacao.php) e adotada pelos dois
   quadros de produto (recursos/paginas/painel/tarefas.php e
   chamados.php, via cartao_quadro_html() em
   recursos/componentes/app/cartao-quadro.php). As classes abaixo
   (.cartao-comparacao*, .cartao-urgencia*, .cartao-sla*) sao a MESMA
   folha para as duas telas de produto e para a pagina de comparacao —
   nao ha copia paralela; ajustar aqui muda os tres lugares de uma vez.

   Cor de tipo: tokens proprios, --tarefa-cor e --chamado-cor, definidos
   por tema logo abaixo.

   NAO usar --chart-1..5 aqui. Aqueles tokens existem para dar variedade
   dentro de um grafico, e por isso trocam de matiz entre os temas de
   proposito: --chart-5 e ambar (matiz 70) no claro e vermelho (matiz 16)
   no escuro. Como --destructive fica no matiz 22, no tema escuro os dois
   viram a mesma cor a seis graus de distancia — e todo chamado passa a
   parecer urgente, justamente apagando a informacao que a cor deveria
   dar. Medido no navegador antes de trocar.

   As tres variantes da pagina de comparacao compartilham a mesma
   estrutura HTML (cartao_comparacao_render()); so a presenca do
   selo/faixa e as regras abaixo mudam a forma. Os quadros de produto so
   usam a forma C.
*/

/*
  Identidade de tipo. O verde e o ambar precisam continuar verde e ambar
  nos dois temas, e ambos precisam ficar longe do matiz de --destructive
  (~22) para nao competirem com o sinal de urgencia.
*/
:root {
  --tarefa-cor: oklch(0.58 0.13 162);
  --chamado-cor: oklch(0.55 0.14 230);
}

.escuro {
  /* Mais claros para sobreviverem ao fundo escuro; o matiz nao muda. */
  --tarefa-cor: oklch(0.72 0.15 162);
  --chamado-cor: oklch(0.72 0.14 230);
}

/*
  Escala de urgencia da variante C (pedido do dono: seguir as cores do
  Monday.com). NAO copiamos os hex do Monday — por dois motivos, para
  quem for mexer aqui de novo nao reabrir a discussao:

  1. A paleta deles e calibrada contra a superficie neutra deles, nao a
     do shadcn, e nao tem par escuro documentado — importar o hex e
     reproduzir exatamente o bug que --chart-5 causou aqui (matiz que
     muda de tema pra tema e some dentro de --destructive no escuro).
     Ver o comentario grande no topo deste bloco.
  2. Copiar a paleta de marca de um concorrente inteira, sem tocar em
     nada, e uma posicao de design fraca — nao e para fazer calado.

  O que vale copiar e o principio: poucas cores semanticas, saturadas e
  bem separadas, cada uma sempre com o mesmo significado. Como o verde
  (tarefa, matiz 162) e o ambar (chamado, matiz 72-75) do "trio de
  status" do Monday ja estao ocupados por --tarefa-cor/--chamado-cor
  aqui, a escala de urgencia usa uma familia propria — azul ate
  magenta — que fecha em --destructive (vermelho) no degrau mais grave,
  para "vermelho = ruim" continuar significando a mesma coisa em toda a
  tela. Matiz fixo por degrau nos dois temas (so luminosidade/croma
  mudam) e a licao inteira do bug de --chart-5: um selo de urgencia
  clara no claro e escura no escuro seria a mesma cegueira de novo.

  Distancia de matiz (graus, o menor caminho no circulo — calculada, nao
  estimada, porque a conta de cabeca da primeira vez saiu errada):
    baixa (225) - tarefa (162):    63
    baixa (225) - chamado (72-75): 150-153
    baixa (225) - destructive:     157-162
    media (262) - tarefa:          100
    media (262) - chamado:         170-173
    media (262) - destructive:     120-125
    alta  (304) - tarefa:          142
    alta  (304) - chamado:         128-131
    alta  (304) - destructive:     78-83
    baixa - media: 37 · media - alta: 42

  'critica' nao ganha token proprio: usa --destructive direto (mesmo
  vermelho de badge-destrutivo e .quadro-cartao-urgente), porque o pedido
  foi "o degrau mais grave deveria ser o --destructive existente, ou algo
  perceptualmente vizinho" — reusar em vez de duplicar tambem evita um
  quarto vermelho quase-igual para manter sincronizado com o tema.
*/
:root {
  /*
    Rampa de temperatura: cinza frio -> ambar -> laranja -> vermelho. Le-se
    como ordem porque E ordem, do jeito que verde/amarelo/laranja/vermelho
    do Monday se le.

    A escala anterior era azul(225) -> indigo(262) -> roxo(304) -> vermelho.
    Matizes bem separados, mas rotacao nao e severidade: roxo nao diz "pior
    que azul" para ninguem. E pior, o degrau medio caia a 12 graus do
    --primary (274), a cor de todo botao primario do sistema — um badge de
    urgencia ficava com cara de acao.

    O aperto: verde ja e tarefa, vermelho ja e destrutivo, indigo e a
    marca. Chamado era ambar e brigava com o degrau medio da urgencia,
    tambem ambar, a treze graus de distancia e na mesma linha do topo do
    cartao. Chamado virou azul (matiz 230): o tipo fica no frio, a
    urgencia fica com a faixa quente inteira, e cada sinal tem espaco.

    A separacao por saturacao continua valendo entre superficie e selo:
    o tipo tinge o fundo com croma baixo (~0.01) e a urgencia pinta o
    selo com croma alto (~0.14).
  */
  --urgencia-baixa-cor: oklch(0.55 0.03 250);
  --urgencia-media-cor: oklch(0.62 0.14 85);
  --urgencia-alta-cor: oklch(0.60 0.17 50);
}

.escuro {
  /* Mais claros para sobreviverem ao fundo escuro; o matiz nao muda — a
     mesma regra de --tarefa-cor/--chamado-cor acima, agora pros quatro
     degraus de urgencia (--destructive ja segue essa regra por conta
     propria em tokens.css). */
  --urgencia-baixa-cor: oklch(0.70 0.03 250);
  --urgencia-media-cor: oklch(0.80 0.14 85);
  --urgencia-alta-cor: oklch(0.75 0.17 50);
}

/*
   ========================================================================== */

.comparacao-cartoes-grade {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
}

@container main (min-width: 36rem) {
  .comparacao-cartoes-grade {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@container main (min-width: 64rem) {
  .comparacao-cartoes-grade {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.cartao-comparacao--tarefa { --cor-tipo: var(--tarefa-cor); }
.cartao-comparacao--chamado { --cor-tipo: var(--chamado-cor); }

.cartao-comparacao {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--raio-lg);
  background-color: var(--card);
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  overflow: hidden;
}

.cartao-comparacao-cabecalho {
  align-items: flex-start;
}

.cartao-comparacao-titulo {
  font-size: 0.9375rem;
}

/*
  Variante A ("borda"): so a borda esquerda carrega o tipo, o resto do
  cartao fica neutro — sem selo nenhum (cartao_comparacao_render() nem
  desenha .cartao-comparacao-selo para esta variante). E a mesma tecnica
  que .quadro-cartao-urgente ja usa para tarefa/chamado urgente, so que
  a cor muda com o tipo, nao com a urgencia.
*/
.cartao-comparacao--a {
  border-left: 3px solid var(--cor-tipo);
}

/*
  Selo de tipo (variantes B e C): mesma tecnica de .agenda-badge acima —
  texto na cor do tipo sobre fundo quase transparente, nunca fundo solido
  com texto branco. Um --chart-3 claro no escuro (ou qualquer token de
  luminosidade alta) perderia contraste como texto branco; a propria cor
  do token como texto funciona nos dois temas sem checar luminosidade
  caso a caso — o motivo ja documentado ali.
*/
.cartao-comparacao-selo {
  align-self: flex-start;
  display: inline-flex;
  padding: 0.1875rem 0.625rem;
  border-radius: var(--raio-sm);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.25rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--cor-tipo);
  background-color: color-mix(in oklab, var(--cor-tipo) 16%, transparent);
}

/*
  Variante B ("selo dominante"): o selo e o unico sinal de cor do
  cartao (sem faixa, sem superficie tingida), por isso ganha mais peso —
  maior, mais afastado do titulo — para carregar o tipo sozinho.
*/
.cartao-comparacao--b .cartao-comparacao-selo {
  padding: 0.25rem 0.75rem;
  font-size: 0.75rem;
  margin-bottom: 0.125rem;
}

/*
  Variante C ("estilo Monday"): faixa colorida no topo (fora do padding
  do cartao, por isso a margem negativa) mais superficie levemente
  tingida na cor do tipo — a mesma formula de .agenda-item acima,
  6% de mistura para nao competir com o conteudo. O selo aqui e mais
  discreto: a faixa e a superficie ja avisam o tipo antes de qualquer
  texto.
*/
.cartao-comparacao--c {
  padding-top: 0;
  background-color: color-mix(in oklab, var(--cor-tipo) 7%, var(--card));
}

.cartao-comparacao-faixa {
  height: 0.5rem;
  margin: 0 -1rem 0.75rem;
  background-color: var(--cor-tipo);
}

.cartao-comparacao--c .cartao-comparacao-titulo {
  font-size: 1rem;
}

/* Avatar/logo maior so na variante C: "a cor (e a marca) fazendo mais trabalho". */
.cartao-comparacao--c .cartao-comparacao-cabecalho .avatar {
  width: 3rem;
  height: 3rem;
  font-size: 1rem;
}

.cartao-comparacao-meta {
  color: var(--muted-foreground);
}

.cartao-comparacao-tempo {
  align-items: center;
}

.cartao-comparacao-tempo-icone,
.cartao-sla-icone {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
}

/*
  Indicador de SLA (so no cartao de chamado): reaproveita .progresso/
  .progresso-preenchimento do kit (data-altura, a mesma tecnica de
  quebra_por_dimensao_html() em quebra-por-dimensao.php) — so a cor do
  preenchimento e do rotulo muda por estado, e vem so daqui, nunca do
  componente em si. Confortavel usa a mesma cor de tarefa (verde
  tambem funciona como "sem problema" aqui); apertado usa a cor de
  chamado (ambar, "atencao"); estourado usa --destructive (vermelho,
  o mesmo tom que badge-destrutivo e .quadro-cartao-urgente ja usam
  para "isto precisa de acao agora").
*/
.cartao-sla-rotulo {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.cartao-sla--confortavel .cartao-sla-preenchimento { background-color: var(--tarefa-cor); }
.cartao-sla--apertado .cartao-sla-preenchimento { background-color: var(--chamado-cor); }
.cartao-sla--estourado .cartao-sla-preenchimento { background-color: var(--destructive); }

.cartao-sla--confortavel .cartao-sla-rotulo { color: var(--tarefa-cor); }
.cartao-sla--apertado .cartao-sla-rotulo { color: var(--chamado-cor); }
.cartao-sla--estourado .cartao-sla-rotulo { color: var(--destructive); }

/*
  Linha do topo, so na variante C: selo de tipo a esquerda, selo de
  urgencia a direita, os dois na mesma linha (pedido do dono). Nas
  variantes A e B o selo continua sozinho, empilhado acima do titulo —
  so C ganha esta linha (cartao_comparacao_render() so desenha
  .cartao-comparacao-linha-topo quando a variante e 'c').
*/
.cartao-comparacao-linha-topo {
  width: 100%;
}

/*
  Selo de urgencia (variante C): mesma tecnica de .agenda-badge/
  .cartao-comparacao-selo — texto na cor do degrau sobre fundo quase
  transparente, nunca fundo solido com texto branco, para nao precisar
  checar contraste caso a caso nos dois temas. Fica sobre a classe
  'badge' do kit (padding/raio/tipografia); so a cor e o peso da fonte
  saem daqui.
*/
.cartao-urgencia {
  font-weight: 600;
}

.cartao-urgencia--baixa {
  color: var(--urgencia-baixa-cor);
  background-color: color-mix(in oklab, var(--urgencia-baixa-cor) 16%, transparent);
}

.cartao-urgencia--media {
  color: var(--urgencia-media-cor);
  background-color: color-mix(in oklab, var(--urgencia-media-cor) 16%, transparent);
}

.cartao-urgencia--alta {
  color: var(--urgencia-alta-cor);
  background-color: color-mix(in oklab, var(--urgencia-alta-cor) 16%, transparent);
}

.cartao-urgencia--critica {
  color: var(--destructive);
  background-color: color-mix(in oklab, var(--destructive) 16%, transparent);
}

/*
  Chip de SLA (variante C, so no cartao de chamado): mesma tecnica dos
  selos acima, colorido pela escala de urgencia (ver
  cartoes_comparacao_nivel_sla_urgencia() em cartoes-comparacao.php) —
  nunca pela cor de tipo, que aqui ja esta ocupada pela faixa e pelo
  fundo tingido do cartao. So tres classes (baixa/media/critica): o SLA
  sozinho tem tres estados, 'alta' fica reservado para .cartao-urgencia
  acima, que combina SLA com prioridade.
*/
.cartao-sla-chip {
  gap: 0.25rem;
}

.cartao-sla-chip-icone {
  width: 0.75rem;
  height: 0.75rem;
  flex-shrink: 0;
}

.cartao-sla-chip--baixa {
  color: var(--urgencia-baixa-cor);
  background-color: color-mix(in oklab, var(--urgencia-baixa-cor) 16%, transparent);
}

.cartao-sla-chip--media {
  color: var(--urgencia-media-cor);
  background-color: color-mix(in oklab, var(--urgencia-media-cor) 16%, transparent);
}

.cartao-sla-chip--critica {
  color: var(--destructive);
  background-color: color-mix(in oklab, var(--destructive) 16%, transparent);
}

/* Legenda da escala de urgencia, abaixo da descricao da variante C. */
.cartao-urgencia-legenda {
  margin-top: 0.25rem;
}

/* ==========================================================================
   Cronometro manual dos cartoes de tarefa/chamado (Tarefa do dono,
   2026-09-06): o botao no rodape do cartao (cronometro_botao_html(), em
   recursos/componentes/app/cartao-quadro.php) e o indicador persistente
   no cabecalho (recursos/layouts/app.php). Vocabulario deste produto —
   sabe o que e um cartao de tarefa/chamado e o que e "rodando" — por
   isso mora aqui e nunca em componentes.css (kit). O estado em si
   (rodando ou nao, ha quanto tempo) e regra de public/assets/app.js;
   este bloco so desenha o que o script decide.

   Cor: --destructive, o mesmo vermelho que qualquer app de gravacao usa
   para "isto esta ativo agora" (o ponto pulsante e a convencao
   universal de "REC") — reaproveitado de proposito em vez de um token
   novo, e escolhido por ser o unico tom do sistema já associado a
   "chame a atencao para isto", nao por acaso ser tambem a cor de
   chamado aberto: cronometro rodando e tarefa tambem usa este vermelho.
   ========================================================================== */

.cartao-comparacao-tempo-linha {
  min-height: 1.5rem;
}

.cartao-cronometro-botao {
  flex-shrink: 0;
}

.cartao-cronometro-icone {
  width: 0.875rem;
  height: 0.875rem;
}

/* Os dois icones (iniciar/pausar) vivem no mesmo botao; o CSS decide
   qual aparece pelo aria-pressed que o script escreve -- mesma tecnica
   de .gatilho-tema acima (sol/lua), so que a chave e aria-pressed em
   vez de .escuro no <html>. */
.cartao-cronometro-icone--parar {
  display: none;
}

.cartao-cronometro-botao[aria-pressed="true"] .cartao-cronometro-icone--iniciar {
  display: none;
}

.cartao-cronometro-botao[aria-pressed="true"] .cartao-cronometro-icone--parar {
  display: block;
}

/*
  Texto do tempo acumulado enquanto o item esta rodando: ponto pulsante
  antes do texto (o mesmo sinal do indicador do cabecalho, abaixo) e
  peso de fonte mais forte -- sinal visual de "isto esta sendo
  cronometrado agora" que nao depende de ler o numero. app.js liga/
  desliga [data-app-cronometro-rodando] a cada troca de estado; o resto
  do tempo o texto fica exatamente como tempo_acumulado_html() sempre
  desenhou.
*/
[data-app-cronometro-total][data-app-cronometro-rodando] {
  color: var(--destructive);
  font-weight: 500;
}

/* O ponto fica colado no texto (nao no icone de relogio, que abre o
   span) -- por isso mira o filho [data-app-cronometro-texto], nao o
   ::before do proprio span. */
[data-app-cronometro-total][data-app-cronometro-rodando] [data-app-cronometro-texto]::before {
  content: "";
  display: inline-block;
  width: 0.375rem;
  height: 0.375rem;
  margin-inline-end: 0.25rem;
  flex-shrink: 0;
  border-radius: 999px;
  background-color: var(--destructive);
  animation: cronometro-pulso 1.6s ease-in-out infinite;
}

@keyframes cronometro-pulso {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/*
  Indicador persistente no cabecalho (recursos/layouts/app.php): a parte
  "impossivel de esquecer" do cronometro manual, visivel em qualquer
  tela do painel enquanto algo estiver rodando. Comeca com o atributo
  'hidden' no HTML (public/assets/ui/base.css ja forca
  'display: none !important' nele) -- app.js remove/repoe o atributo,
  nunca mexe em display por conta propria.
*/
.cronometro-indicador {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 1;
  min-width: 0;
  max-width: 16rem;
  padding: 0.25rem 0.625rem;
  border-radius: var(--raio-md);
  background-color: color-mix(in oklab, var(--destructive) 12%, transparent);
  color: var(--destructive);
  font-size: 0.75rem;
  font-weight: 500;
}

.cronometro-indicador-ponto {
  flex-shrink: 0;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  background-color: var(--destructive);
  animation: cronometro-pulso 1.6s ease-in-out infinite;
}

.cronometro-indicador-texto {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cronometro-indicador-parar {
  flex-shrink: 0;
  color: inherit;
}

/* Celular: o cabecalho ja aperta (titulo + hamburguer + tema); o
   indicador vira so o ponto e o botao de parar, sem o texto do item. */
@media (max-width: 639px) {
  .cronometro-indicador-texto {
    display: none;
  }

  .cronometro-indicador {
    max-width: none;
  }
}

/* ---------------------------------------------------------------------
   Grafico de entrada diaria (Financeiro > Assinaturas)

   Trinta e uma colunas de largura igual, uma por dia do mes. O par
   receita/despesa da home usa .grafico-par-barras, que reserva espaco
   para DUAS barras por coluna; aqui e uma so, e as colunas sao muito
   mais estreitas — por isso um bloco proprio em vez de reaproveitar
   aquele.

   .grafico-barra (do kit) ja define raio, cor de fundo e a altura por
   --altura; aqui so entram a grade e o trilho. */
.grafico-diario {
  display: grid;
  grid-template-columns: repeat(31, 1fr);
  gap: 2px;
  /* 'stretch' e nao 'end': o rotulo so aparece de cinco em cinco dias,
     entao a coluna sem numero e mais baixa — com 'end' ela descia a
     altura do rotulo e as barras deixavam de compartilhar a mesma base.
     Esticando todas, quem define o chao e o trilho, igual em todas. */
  align-items: stretch;
}

.grafico-diario-coluna {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* justify-content: flex-end joga o conteudo para baixo dentro da
     coluna esticada, e o trilho de altura fixa faz o resto. */
  justify-content: flex-end;
  gap: 0.375rem;
  min-width: 0;
}

/* O trilho ocupa a altura toda e alinha a barra pela base, para barras
   de alturas diferentes crescerem do mesmo chao. */
.grafico-diario-trilho {
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 7.5rem;
}

/* Dia sem entrada nao precisa de tracinho proprio: o separador do trilho
   ja mostra a linha do chao, e o tracinho competia com ele visualmente. */
.grafico-diario .grafico-barra-vazia {
  height: 0;
}

.grafico-diario .grafico-barra {
  width: 100%;
}

/* Dia sem entrada: um fio no chao em vez de nada. Coluna vazia de
   verdade faria parecer que o grafico terminou ali. */
.grafico-barra-vazia {
  height: 2px;
  background: var(--border);
  border-radius: 2px;
  width: 100%;
}

/* Linha dos dias: altura fixa para TODA coluna reservar o mesmo espaco,
   tenha numero ou nao. E o que mantem as barras alinhadas e poe os
   numeros numa faixa propria abaixo do grafico, em vez de no meio dele.
   O separador acima marca o chao das barras. */
.grafico-diario .grafico-rotulo {
  display: block;
  height: 0.875rem;
  line-height: 0.875rem;
  font-size: 0.625rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}

.grafico-diario-trilho {
  border-bottom: 1px solid var(--border);
}

/* ---------------------------------------- receita do cliente, 24 meses */

/*
  Vinte e quatro colunas de largura igual, uma por mes. Irmao do
  .grafico-diario (mesma ideia: uma serie, eixo fixo, zerados visiveis),
  mas com a propria grade porque a contagem de colunas e outra. A barra e
  a .grafico-barra do kit, com a altura por data-altura.
*/
.grafico-receita {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  gap: 2px;
  align-items: stretch;
}

.grafico-receita-coluna {
  display: flex;
  position: relative;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 0.25rem;
  min-width: 0;
}

/* O trilho tem altura fixa e alinha a barra pela base; a linha de baixo marca o chao. */
.grafico-receita-trilho {
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 7.5rem;
  border-bottom: 1px solid var(--border);
}

.grafico-receita .grafico-barra {
  width: 100%;
}

/* Mes zerado: um fio sobre o chao, para o grafico nao parecer ter terminado ali. */
.grafico-receita .grafico-barra-vazia {
  height: 2px;
  min-height: 0;
  background: color-mix(in oklab, var(--muted-foreground) 35%, transparent);
}

/* Rotulo de trimestre pode ser mais largo que a coluna: centralizado, vaza para os dois lados. */
.grafico-receita-rotulo {
  display: flex;
  justify-content: center;
  width: 100%;
  min-width: 0;
  height: 0.875rem;
  line-height: 0.875rem;
  font-size: 0.625rem;
  white-space: nowrap;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}

/* O ponto abaixo do mes liga a coluna a uma linha da legenda; sem legenda, reserva o espaco. */
.grafico-receita-marca {
  width: 0.25rem;
  height: 0.25rem;
  border-radius: 9999px;
}

.grafico-receita-marca-ativa {
  background-color: var(--cor-atencao);
}

/* A dica de mes e valor: nasce escondida e aparece ao passar o mouse na coluna.
   O dinheiro dentro dela leva valor-sigiloso, entao "Ocultar valores" a mascara. */
.grafico-receita-dica {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: none;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--raio-sm);
  background-color: var(--popover);
  color: var(--popover-foreground);
  font-size: 0.75rem;
  line-height: 1rem;
  white-space: nowrap;
  pointer-events: none;
}

.grafico-receita-coluna:hover .grafico-receita-dica {
  display: block;
}

/*
  As colunas das pontas: a dica e centrada na coluna (translateX(-50%)) e nao
  quebra linha, entao numa coluna de 1/24 da largura ela passa da borda do
  card (medido no navegador: 15px para a esquerda na primeira coluna e 33px
  para a direita na ultima, a 1440px de tela). Nas tres primeiras ela nasce
  alinhada a esquerda da coluna, e nas tres ultimas, a direita: em tela
  estreita a coluna encolhe e a segunda e a penultima tambem passam.
*/
.grafico-receita-coluna:nth-child(-n+3) .grafico-receita-dica {
  left: 0;
  transform: none;
}

.grafico-receita-coluna:nth-last-child(-n+3) .grafico-receita-dica {
  left: auto;
  right: 0;
  transform: none;
}

.grafico-receita-nota {
  margin: 0.5rem 0 0;
  font-size: 0.75rem;
  color: var(--muted-foreground);
}

.grafico-receita-legenda {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.75rem;
  color: var(--muted-foreground);
}

.grafico-receita-legenda-mes {
  font-weight: 600;
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------- historico de faturamento */

/*
  A matriz ano x mes. Cada celula carrega --intensidade (0 a 1), escrita
  pelo app.js via CSSOM porque a CSP proibe style inline.

  A cor sai de color-mix sobre o token de fundo, e nao de uma escala de
  cores fixa: assim ela acompanha o tema claro e o escuro sem uma segunda
  paleta para manter em sincronia.
*/
.matriz-ano-mes {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--texto-xs);
}

.matriz-ano-mes th,
.matriz-ano-mes td {
  padding: 0.375rem 0.5rem;
  text-align: right;
  white-space: nowrap;
}

.matriz-ano-mes thead th {
  color: var(--muted-foreground);
  font-weight: 500;
  border-bottom: 1px solid var(--border);
}

.matriz-ano-mes tbody th {
  text-align: left;
  font-weight: 600;
  color: var(--foreground);
}

.matriz-celula {
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius-sm);
  background: color-mix(in oklab, var(--primary) calc(var(--intensidade, 0) * 82%), transparent);
  color: var(--foreground);
}

/* Acima de ~55% o fundo fica escuro demais para texto normal. */
.matriz-celula[data-app-intensidade^="0.6"],
.matriz-celula[data-app-intensidade^="0.7"],
.matriz-celula[data-app-intensidade^="0.8"],
.matriz-celula[data-app-intensidade^="0.9"],
.matriz-celula[data-app-intensidade="1"] {
  color: var(--primary-foreground);
}

.matriz-futuro {
  background: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 3px,
    var(--muted) 3px,
    var(--muted) 4px
  );
  border-radius: var(--radius-sm);
  opacity: 0.5;
}

.matriz-total {
  font-weight: 600;
  border-left: 1px solid var(--border);
}

.matriz-nota {
  font-size: var(--texto-xs);
  font-weight: 400;
  color: var(--muted-foreground);
}

/* --- barras por ano */

.grafico-anos {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0.5rem;
  align-items: stretch;
  min-height: 13rem;
}

.grafico-ano {
  display: grid;
  /* Trilhas explicitas: a barra estica, o resto tem altura propria. */
  grid-template-rows: 1fr auto auto;
  gap: 0.25rem;
  text-align: center;
}

.grafico-ano-parcial {
  opacity: 0.45;
}

.grafico-ano-barras {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  height: 100%;
}

.grafico-ano-barra {
  width: 45%;
  height: var(--altura, 0%);
  min-height: 2px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.grafico-ano-nominal {
  background: color-mix(in oklab, var(--primary) 32%, transparent);
}

.grafico-ano-corrigido {
  background: var(--primary);
}

.grafico-ano-valor {
  font-size: var(--texto-xs);
  font-variant-numeric: tabular-nums;
  color: var(--foreground);
}

.grafico-ano-rotulo {
  font-size: var(--texto-xs);
  color: var(--muted-foreground);
}

/* --- conclusoes */

.lista-conclusoes {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.conclusao {
  display: flex;
  gap: 0.625rem;
  align-items: flex-start;
}

.conclusao-icone {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--radius-sm);
  background: color-mix(in oklab, var(--primary) 12%, transparent);
  color: var(--primary);
}

.conclusao-icone svg {
  width: 0.875rem;
  height: 0.875rem;
}

.conclusao-texto {
  font-size: var(--texto-sm);
  font-weight: 500;
  color: var(--foreground);
}

.conclusao-detalhe {
  font-size: var(--texto-xs);
  color: var(--muted-foreground);
}

.rolagem-x {
  overflow-x: auto;
}

/* --- receita por empresa */

.empresa-linha {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.empresa-trilho {
  height: 0.375rem;
  border-radius: 999px;
  background: var(--muted);
  overflow: hidden;
}

/*
  Barra horizontal: aqui --altura mede LARGURA. O nome vem do kit, que
  usa o mesmo atributo data-altura para barra vertical; trocar o nome
  exigiria um segundo varredor no ui.js para a mesma coisa.
*/
.empresa-barra {
  width: var(--altura, 0%);
  height: 100%;
  border-radius: 999px;
  background: var(--primary);
}

/* --- resultado por unidade */

.tabela-unidades {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--texto-sm);
}

.tabela-unidades th,
.tabela-unidades td {
  padding: 0.5rem 0.625rem;
  text-align: right;
  white-space: nowrap;
}

.tabela-unidades thead th {
  font-size: var(--texto-xs);
  font-weight: 500;
  color: var(--muted-foreground);
  border-bottom: 1px solid var(--border);
}

.tabela-unidades tbody th {
  text-align: left;
  font-weight: 500;
  color: var(--foreground);
}

.tabela-unidades tbody tr + tr th,
.tabela-unidades tbody tr + tr td {
  border-top: 1px solid var(--border);
}

/* --- barra de periodo */

.barra-periodo {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

.barra-periodo-datas {
  align-items: center;
  flex-wrap: wrap;
  margin-top: 0.5rem;
}

.barra-periodo-datas .campo {
  width: auto;
  min-width: 9.5rem;
}

/*
  O grafico de anos preenche a altura do card, em vez de ficar preso a
  13rem. Mesma correcao que .grafico-par-barras ja tinha: na grade de
  duas colunas o card estica para acompanhar o vizinho, e uma altura
  fixa vira vao branco embaixo das barras. Foi o que o dono viu — "ta
  tudo muito desproporcional".
*/
.card:has(.grafico-anos) > .card-conteudo {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}

.card:has(.grafico-anos) .grafico-anos {
  flex: 1 1 auto;
}

/* A tabela de unidades tambem cresce, para o par da linha bater. */
.card:has(.tabela-unidades) > .card-conteudo {
  display: flex;
  flex-direction: column;
}

/*
  As conclusoes em duas colunas quando o card e largo. Cinco itens de
  texto numa coluna so davam 602px de altura e forcavam o card vizinho a
  acompanhar; texto quer largura, nao altura.
*/
@container main (min-width: 56rem) {
  .lista-conclusoes {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.875rem 1.5rem;
  }
}

/* ---------------------------------------------------------------------
   O CARTAO DENTRO DO QUADRO E COMPACTO

   Medido em 08/09/2026: o cartao tinha 312px de altura numa coluna de
   504px — cabiam 1,6 cartoes. O quadro do Trello, que o dono usa de
   referencia, poe 6 a 8 na mesma altura. Uma coluna que mostra um
   cartao e meio nao e um quadro: e uma lista com passos extras.

   NENHUMA INFORMACAO SAI. O pedido foi "deixa as informacoes como estao
   hoje, so precisamos dar uma revisadinha na disposicao depois" — entao
   aqui e so densidade: fonte menor, respiro menor, avatar menor, titulo
   limitado a duas linhas. Trocar linha de texto por icone fica para a
   revisao da disposicao, quando a ficha do cartao existir para receber
   o que sair daqui.

   POR CONTEXTO, e nao por uma variante nova: a regra vale para o cartao
   que esta dentro de .quadro-coluna-corpo. Assim o catalogo em /ui
   continua mostrando a variante C no tamanho em que ela foi calibrada,
   e nenhum PHP muda.
--------------------------------------------------------------------- */

.quadro-coluna-corpo .cartao-comparacao {
  gap: 0.375rem;
  padding: 0.625rem;
  padding-top: 0;
}

/* A faixa vira fita, como a etiqueta do Trello. */
.quadro-coluna-corpo .cartao-comparacao-faixa {
  height: 0.25rem;
  margin: 0 -0.625rem 0.5rem;
}

.quadro-coluna-corpo .cartao-comparacao-cabecalho {
  gap: 0.5rem;
}

.quadro-coluna-corpo .cartao-comparacao--c .cartao-comparacao-cabecalho .avatar {
  width: 1.5rem;
  height: 1.5rem;
  font-size: 0.625rem;
}

/*
  Titulo em DUAS LINHAS no maximo. Sem o limite, um titulo de video de
  YouTube colado numa tarefa ("Criando uma LANDING PAGE 3D ANIMADA COM
  SCROLL...") ocupa quatro linhas sozinho e desmonta a coluna inteira —
  e sao varios assim no roadmap.
*/
.quadro-coluna-corpo .cartao-comparacao--c .cartao-comparacao-titulo {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  font-size: 0.8125rem;
  line-height: 1.25rem;
}

.quadro-coluna-corpo .cartao-comparacao-contexto,
.quadro-coluna-corpo .cartao-comparacao-meta {
  font-size: 0.6875rem;
  line-height: 1rem;
}

/* O contexto tambem cabe numa linha so: nome de cliente longo nao pode
   valer duas. */
.quadro-coluna-corpo .cartao-comparacao-contexto {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.quadro-coluna-corpo .cartao-comparacao-linha-topo,
.quadro-coluna-corpo .cartao-comparacao-rodape,
.quadro-coluna-corpo .cartao-comparacao-tempo-linha {
  gap: 0.25rem;
}

.quadro-coluna-corpo .cartao-comparacao-selo,
.quadro-coluna-corpo .cartao-urgencia {
  padding: 0.0625rem 0.375rem;
  font-size: 0.625rem;
  line-height: 1rem;
}

.quadro-coluna-corpo .cartao-comparacao-tempo {
  font-size: 0.6875rem;
}

/*
  O CABECALHO DO CARTAO NAO QUEBRA LINHA.

  Medido em 08/09/2026: o avatar ficava sozinho na primeira linha e a
  pilha de texto descia para a segunda, custando 32px em todo cartao do
  quadro. Nao era densidade — era defeito.

  A causa e classica de flexbox: um item flex nao encolhe abaixo do
  proprio min-content, e o min-content de um titulo com palavra longa
  ("MULTIMILIONARIOS") passa da largura que sobra ao lado do avatar.
  Sem espaco, .linha quebra. 'min-width: 0' e o que autoriza o encolhimento,
  e 'overflow-wrap: anywhere' e quem entao parte a palavra.
*/
.quadro-coluna-corpo .cartao-comparacao-cabecalho {
  flex-wrap: nowrap;
}

.quadro-coluna-corpo .cartao-comparacao-cabecalho > .pilha {
  min-width: 0;
}

.quadro-coluna-corpo .cartao-comparacao-titulo {
  overflow-wrap: anywhere;
}

/*
  O botao do cronometro tinha 36px de altura para 16px de icone: .btn-icone
  e um quadrado de 2.25rem, medida do kit calibrada para alvo de toque numa
  barra de ferramentas. Dentro do cartao ele e o terceiro elemento de uma
  linha de rodape, e 36px ali eram um quinto da altura do cartao.
*/
.quadro-coluna-corpo .cartao-cronometro-botao {
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  font-size: 0.6875rem;
}

/* ---------------------------------------------------------------------
   A FICHA DO CARTAO (o corpo do dialogo que abre ao clicar num cartao)
--------------------------------------------------------------------- */

/*
  Os atributos em grade auto-fit, e nao em linha: sao seis pares
  rotulo/valor de larguras muito diferentes ("Prioridade: Media" e
  "Cliente: Zilocchi Eletronica"), e numa linha unica eles ou estouram a
  largura ou deixam buraco. A grade acomoda dois ou tres por linha
  conforme o dialogo, sem media query.
*/
.ficha-atributos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.75rem 1rem;
}

.ficha-cartao-titulo {
  /* Titulo de cartao pode ser um paragrafo colado do YouTube. */
  overflow-wrap: anywhere;
}

/*
  O convite "Adicionar descricao" e um link, mas a base zera a cor e o
  sublinhado de todo <a>: sem esta regra ele pareceria texto comum, e o
  bloco vazio existe justamente para dizer que ha o que clicar.
*/
.ficha-convite {
  color: var(--muted-foreground);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.ficha-convite:hover {
  color: var(--foreground);
}

/*
  O ITEM DE CHECKLIST E UM BOTAO DE LARGURA INTEIRA, e nao uma <input
  type=checkbox> com <label>. Marcar um passo e um POST — a caixa nativa
  mudaria de estado na hora e so DEPOIS o servidor responderia, e num erro
  ela ficaria marcada mostrando o contrario do que esta gravado. Com
  botao, o estado que se ve e sempre o que voltou do servidor.

  aria-pressed carrega o estado para o leitor de tela, que e o que a
  caixa nativa dava de graca.
*/
.ficha-itens {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ficha-item-form {
  width: 100%;
}

.ficha-item-botao {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  width: 100%;
  padding: 0.25rem 0.375rem;
  border: 0;
  border-radius: var(--raio-md);
  background: none;
  color: inherit;
  font: inherit;
  font-size: 0.875rem;
  line-height: 1.25rem;
  text-align: left;
  cursor: pointer;
}

.ficha-item-botao:hover {
  background-color: var(--muted);
}

.ficha-item-botao:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

.ficha-item-marca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 1rem;
  height: 1rem;
  margin-top: 0.125rem;
  border: 1px solid var(--border);
  border-radius: var(--raio-sm);
  color: var(--primary-foreground);
}

.ficha-item-marca svg {
  width: 0.75rem;
  height: 0.75rem;
}

.ficha-item-botao--feito .ficha-item-marca {
  border-color: var(--primary);
  background-color: var(--primary);
}

/* Riscado e apagado: o passo feito continua legivel, mas para de
   competir com os que faltam. */
.ficha-item-botao--feito .ficha-item-texto {
  color: var(--muted-foreground);
  text-decoration: line-through;
}

.ficha-item-texto {
  overflow-wrap: anywhere;
}

.ficha-aplicar-modelo .campo-envolucro,
.ficha-aplicar-modelo .selecao-envolucro {
  margin: 0;
}

/*
  HOVER DO CARTAO NO QUADRO, e o lapis do canto — como no Trello.

  O cartao ja era clicavel desde que a ficha existe, e nada na tela dizia
  isso: um cartao que abre algo precisa parecer que abre algo ANTES do
  clique. Fundo levemente elevado, borda marcada e cursor de ponteiro.

  O LAPIS e posicionado, e nao parte do fluxo: fora do hover ele nao
  ocupa espaco nenhum, entao a altura do cartao nao muda quando o mouse
  passa. Um cartao que cresce no hover empurra os de baixo e faz a coluna
  inteira pular.

  Ele aparece tambem no :focus-within, para quem navega por teclado — sem
  isso o lapis seria um recurso exclusivo de quem usa mouse.
*/
/*
  :not([data-arrastando]) NAO E DETALHE. O 'position: relative' daqui
  existe so para ancorar o lapis do canto, mas ele tem a MESMA
  especificidade (0,2,0) da regra de arraste do kit
  '[data-ui-cartao][data-arrastando]', que precisa de 'position: fixed' —
  e marca.css carrega DEPOIS de componentes.css. Empate na
  especificidade, ganha quem vem depois: o relative vencia, o cartao
  arrastado ficava preso no fluxo da coluna e o arraste parecia sem
  animacao nenhuma.

  Sem o transition durante o arraste pelo mesmo motivo: mover um elemento
  com transition de posicao faz ele PERSEGUIR o ponteiro com atraso em
  vez de acompanhar.
*/
.quadro-coluna-corpo .cartao-comparacao:not([data-arrastando]) {
  position: relative;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
}

/* O hover nao vale durante o arraste: o cartao ja tem estilo proprio, e
   pointer-events esta desligado nele de qualquer forma. */
.quadro-coluna-corpo .cartao-comparacao:not([data-arrastando]):hover,
.quadro-coluna-corpo .cartao-comparacao:not([data-arrastando]):focus-within {
  border-color: color-mix(in oklab, var(--cor-tipo) 45%, var(--border));
  background-color: color-mix(in oklab, var(--cor-tipo) 12%, var(--card));
  box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.12);
}

/* Enquanto arrasta, o hover atrapalha: o cartao ja tem estilo proprio. */
.quadro-coluna-corpo .cartao-comparacao[data-arrastando] {
  cursor: grabbing;
}

.cartao-editar {
  position: absolute;
  top: 0.5rem;
  right: 0.375rem;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.375rem;
  height: 1.375rem;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--raio-md);
  background-color: var(--card);
  color: var(--muted-foreground);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease, color 0.12s ease;
}

.cartao-editar svg {
  width: 0.75rem;
  height: 0.75rem;
}

.cartao-comparacao:hover .cartao-editar,
.cartao-comparacao:focus-within .cartao-editar {
  opacity: 1;
}

.cartao-editar:hover {
  color: var(--foreground);
}

.cartao-editar:focus-visible {
  opacity: 1;
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

/*
  Sem hover (celular, tablet), o lapis fica sempre visivel: um botao que
  so aparece ao passar o mouse nao existe para quem toca a tela.
*/
@media (hover: none) {
  .cartao-editar {
    opacity: 1;
  }
}

.ficha-cartao-titulo-linha {
  align-items: flex-start;
}

/*
  ESPACAMENTO DA FICHA.

  O que estava embolado nao era estilo: o container usava 'pilha g-5', e a
  escala de gap do kit vai 1, 2, 3, 4, 6 — nao existe .g-5. A classe nao
  casava com regra nenhuma e o gap ficava em zero, entao "Membros" colava
  em "Aberto em" e "Descricao" colava na lista de atributos. Falha
  silenciosa: nenhum erro, so uma tela apertada.

  Aqui o que sobra e o respiro DENTRO de cada secao — o rotulo pequeno
  ("Membros", "Descricao") precisa colar no proprio conteudo e afastar do
  bloco anterior, senao ele parece rotular o de cima.
*/
.ficha-cartao > .pilha > .texto-xs {
  margin-bottom: 0.125rem;
}

.ficha-cabecalho {
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--border);
}

/* A linha de adicionar lista ocupa a largura inteira: o <select> cresce e
   o botao fica no fim, em vez de os dois se espremerem a direita. */
.ficha-listas-topo {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.ficha-listas-topo form {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.5rem;
  align-items: center;
  width: 100%;
}

/*
  selecao() devolve o <select> dentro de .selecao-envolucro, e esse
  envolucro dentro do .campo-grupo que carrega rotulo e ajuda. Quem
  precisa crescer e o GRUPO — mandar so o envolucro crescer deixaria o
  grupo no tamanho do conteudo e a linha continuaria espremida.
*/
.ficha-listas-topo .campo-grupo,
.ficha-listas-topo .selecao-envolucro {
  /*
    'flex: 1 1 auto' com 'min-width: 0', e NAO 'width: 100%': a largura
    cheia ocupa a linha inteira e empurra o botao "Adicionar" para a
    linha de baixo, porque .linha do kit tem flex-wrap: wrap. Crescer
    para ocupar o que sobra e diferente de ocupar tudo.
  */
  flex: 1 1 auto;
  min-width: 0;
}

.ficha-listas-topo select {
  width: 100%;
}

/* O botao nao encolhe: "Adicionar" nao pode virar "Adic...". */
.ficha-listas-topo .btn {
  flex-shrink: 0;
}

/* --- Membros, anexos e comentarios da ficha -------------------------- */

/*
  O CHIP DE MEMBRO E UM BOTAO de formulario, e nao um badge com um "x"
  ao lado: tirar alguem do cartao e um POST, e um <button> dentro de um
  <form> e o unico jeito de isso funcionar sem JS. Com JS, o app.js
  intercepta e troca so o corpo do dialogo.
*/
.ficha-membros {
  flex-wrap: wrap;
}

.ficha-chip {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  padding: 0.125rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background-color: var(--secondary);
  color: var(--secondary-foreground);
  font: inherit;
  font-size: 0.75rem;
  line-height: 1.25rem;
  cursor: pointer;
}

.ficha-chip:hover {
  border-color: var(--destructive);
  color: var(--destructive);
}

.ficha-chip-x {
  font-size: 0.875rem;
  line-height: 1;
  opacity: 0.6;
}

.ficha-chip:hover .ficha-chip-x {
  opacity: 1;
}

/* A linha de acao (somar membro, anexar): campo cresce, botao nao encolhe. */
.ficha-linha-acao {
  flex-wrap: nowrap;
  width: 100%;
}

.ficha-linha-acao .campo-grupo,
.ficha-linha-acao .selecao-envolucro {
  flex: 1 1 auto;
  min-width: 0;
}

.ficha-linha-acao select,
.ficha-linha-acao input[type="file"] {
  width: 100%;
}

.ficha-linha-acao .btn {
  flex-shrink: 0;
}

/* O <input type=file> nativo com altura de campo: sem isso ele fica
   menor que o botao ao lado e a linha desalinha. */
.ficha-linha-acao input[type="file"] {
  padding-block: 0.3125rem;
}

.ficha-anexos,
.ficha-comentarios {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ficha-anexo {
  padding: 0.25rem 0;
  border-bottom: 1px solid var(--border);
}

.ficha-anexo:last-child {
  border-bottom: 0;
}

.ficha-anexo-nome {
  overflow: hidden;
  color: var(--foreground);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ficha-anexo-nome:hover {
  text-decoration: underline;
}

.ficha-anexo-meta {
  flex-shrink: 0;
}

/* O "x" de apagar: discreto ate o hover, como o lapis do cartao. Apagar
   nao pode ser o botao mais visivel de uma lista. */
.ficha-apagar {
  padding: 0 0.25rem;
  border: 0;
  background: none;
  color: var(--muted-foreground);
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.ficha-apagar:hover {
  color: var(--destructive);
}

.ficha-comentario-texto {
  overflow-wrap: anywhere;
  color: var(--muted-foreground);
}

/*
  A FICHA EM DUAS COLUNAS, a partir de 60rem de janela.

  O cabecalho atravessa as duas; o corpo do cartao fica a esquerda e a
  conversa a direita — o arranjo do Trello. Numa coluna so, o comentario
  cai no fim de tudo, e num cartao com checklist de 20 passos ele nasce
  fora da tela.

  A coluna da conversa tem largura FIXA (20rem) e a do conteudo cresce:
  comentario e texto corrido e nao ganha nada em ficar mais largo, mas a
  descricao e a lista de passos ganham.

  A medida e de viewport de proposito — ver .dialogo--amplo em
  componentes.css.
*/
@media (min-width: 60rem) {
  .ficha-cartao {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: 1.5rem;
    align-items: start;
  }

  .ficha-cabecalho,
  .ficha-cartao > .alerta {
    grid-column: 1 / -1;
  }

  .ficha-lateral {
    padding-left: 1.5rem;
    border-left: 1px solid var(--border);
  }
}

/*
  Abaixo de 60rem a conversa vira mais uma secao empilhada, e ganha uma
  linha em cima para nao colar no bloco anterior — o que a borda da
  esquerda faz no desktop.
*/
@media (max-width: 59.999rem) {
  .ficha-lateral {
    padding-top: 1rem;
    border-top: 1px solid var(--border);
  }
}

/*
  O marcador de tipo do anexo. Largura fixa para os nomes alinharem numa
  coluna so, em vez de comecarem cada um num lugar conforme o tamanho da
  palavra ("PDF" e "Compactado").
*/
.ficha-anexo-tipo {
  flex-shrink: 0;
  width: 5.5rem;
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* O campo de arquivo cresce como o <select> da linha ao lado. */
.ficha-linha-acao .campo-arquivo {
  flex: 1 1 auto;
  min-width: 0;
}

/*
  As duas colunas da ficha nao encolhem abaixo do proprio conteudo sem
  isto: 'min-width: auto' e o padrao de um item flex, e a descricao de um
  cartao costuma ser uma URL de 60 caracteres. Foi exatamente assim que o
  cabecalho do cartao no quadro quebrou linha e custou 32px por cartao —
  ver .quadro-coluna-corpo .cartao-comparacao-cabecalho.
*/
.ficha-principal,
.ficha-lateral {
  min-width: 0;
}

/*
  As duas cores que entraram com a Agenda do banco. `agenda_events.type`
  guarda meeting/reminder/other; 'meeting' ja era 'reuniao'.
*/
.agenda-cor-lembrete { --agenda-cor: var(--chart-4); }
.agenda-cor-outro { --agenda-cor: var(--muted-foreground); }

/* ---------------------------------------------------------------------
   LINHA DO TEMPO DA AGENDA

   E a vista padrao, e a razao e o volume: sao 6 compromissos em 5 meses.
   Uma grade de mes fica com 30 quadros e 1 preenchido — bonita e vazia,
   e vazia todo dia. A lista funciona com 6 e continua funcionando com 60.
--------------------------------------------------------------------- */

.agenda-mes-rotulo {
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
  margin-bottom: 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/*
  Mes passado apagado, e nao escondido: agenda tambem e registro, e "o
  que houve" e uma pergunta legitima. Escondido, ela viraria so uma lista
  de pendencias.
*/
.agenda-mes--passado { opacity: 0.62; }

.agenda-linha-item {
  display: grid;
  grid-template-columns: 2.75rem 0.1875rem 1fr;
  gap: 0.625rem;
  align-items: stretch;
  margin-bottom: 0.5rem;
}

.agenda-linha-dia {
  text-align: center;
  padding-top: 0.375rem;
}

.agenda-linha-numero {
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1;
}

.agenda-linha-semana {
  font-size: 0.625rem;
  color: var(--muted-foreground);
  text-transform: uppercase;
}

/* A fita e a cor do tipo, e e o unico lugar da linha onde ela aparece:
   uma cor por elemento vira arco-iris e para de significar. */
.agenda-linha-fita {
  border-radius: 2px;
  background-color: var(--agenda-cor, var(--muted-foreground));
}

.agenda-linha-corpo {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--raio-md);
  background-color: var(--card);
}

/* ---------------------------------------------------------------------
   CHIPS DE FONTE
--------------------------------------------------------------------- */

/*
  Um chip por fonte presente no periodo, com a contagem. Ele e um LINK,
  e nao um botao de JavaScript: o filtro vive na URL (?fonte=fatura), o
  estado sobrevive ao recarregamento e da para mandar o link para
  alguem.
*/
.agenda-fontes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

.agenda-fonte-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.1875rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 9999px;
  background-color: var(--card);
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
  text-decoration: none;
}

.agenda-fonte-chip:hover { background-color: var(--accent); }

.agenda-fonte-chip[aria-current="true"] {
  border-color: var(--primary);
  background-color: color-mix(in oklab, var(--primary) 10%, var(--card));
  color: var(--foreground);
  font-weight: 600;
}

.agenda-fonte-ponto {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 9999px;
  flex-shrink: 0;
  background-color: var(--agenda-cor, var(--muted-foreground));
}

.agenda-fonte-conta {
  font-variant-numeric: tabular-nums;
  color: var(--muted-foreground);
}

/* ---------------------------------------------------------------------
   GRADE DO MES
--------------------------------------------------------------------- */

.agenda-grade {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.25rem;
}

.agenda-grade-cabecalho {
  font-size: 0.625rem;
  font-weight: 600;
  color: var(--muted-foreground);
  text-align: center;
  text-transform: uppercase;
  padding-bottom: 0.25rem;
}

/*
  O DIA E UM BOTAO, e nao um quadro morto: clicar nele abre "Novo
  compromisso" ja com aquela data. Por isso o reset — um <button> traz
  fonte, alinhamento e fundo proprios do navegador, e sem zerar os tres
  a grade sairia com sete tipografias diferentes das outras telas.
*/
.agenda-grade-dia {
  position: relative;
  display: block;
  width: 100%;
  min-height: 4.5rem;
  padding: 0.25rem 0.3125rem;
  border: 1px solid var(--border);
  border-radius: var(--raio-md);
  background-color: transparent;
  font-family: inherit;
  font-size: 0.75rem;
  text-align: left;
  color: var(--muted-foreground);
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

.agenda-grade-dia:hover {
  border-color: var(--primary);
  background-color: var(--accent);
}

.agenda-grade-dia:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* Dia do mes vizinho: presente para a grade nao ter buraco, apagado
   para nao se confundir com este mes. */
.agenda-grade-dia--fora { opacity: 0.34; }

.agenda-grade-dia--hoje {
  border-color: var(--primary);
  background-color: color-mix(in oklab, var(--primary) 8%, var(--card));
  color: var(--foreground);
  font-weight: 700;
}

.agenda-grade-evento {
  display: block;
  overflow: hidden;
  margin-top: 0.1875rem;
  padding: 0.0625rem 0.25rem;
  border-radius: var(--raio-sm);
  border-left: 3px solid var(--agenda-cor, var(--muted-foreground));
  background-color: var(--muted);
  color: var(--foreground);
  font-size: 0.6875rem;
  line-height: 1rem;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ------------------------------------------------ Notas & Links

  A COR NAO E ESCOLHA DE DESIGN, E DADO. Cada categoria ja tem a sua em
  note_categories.color, no banco do v1, e o v1 usa. A maquete do v2
  ignorava: nao ha cor nova a inventar aqui, ha cor a parar de jogar
  fora.

  Ela chega por data-ui-cor e vira --cor pela CSSOM (ver aplicarCores em
  ui.js). Nunca por atributo style: a CSP bloqueia estilo inline sem
  dizer nada, e a tela so renderiza errado.

  O var(--cor, var(--muted-foreground)) tem reserva de proposito. Uma
  categoria sem cor no banco cai num cinza declarado; sem a reserva ela
  cairia em preto, que nesta tela pareceria uma sétima categoria.
*/
.chip-ponto {
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  background-color: var(--cor, var(--muted-foreground));
}

/*
  auto-fill com minmax, e nao ponto de quebra em @container.

  Aqui o que decide o numero de colunas e a largura MINIMA que um cartao
  precisa para o titulo nao virar tres linhas -- e essa largura nao muda
  com a viewport. Um ponto de quebra teria que ser reencontrado a cada
  mudanca de padding da sidebar, e foi assim que a grade ficou em duas
  colunas num monitor onde cabiam tres (medido: o conteudo dava 1014px,
  e o limite estava em 1024px).
*/
.notas-grade {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.nota-cartao {
  position: relative;
  overflow: hidden;
  /* A fita ocupa o topo; sem isto o titulo encostaria nela. */
  padding-top: 1.25rem;
}

/*
  A FITA E O QUE SE VE DE LONGE, e e por isso que ela existe: 11 das 20
  notas estao em "Outros", e a parede cinza mostra o quanto falta
  organizar sem precisar de numero nenhum.
*/
.nota-cartao::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background-color: var(--cor, var(--muted-foreground));
}

.nota-cartao-titulo {
  font-weight: 600;
  line-height: 1.35;
  /* Titulo longo quebra; nao empurra o cartao para fora da coluna. */
  overflow-wrap: anywhere;
}

.nota-cartao-rodape {
  margin-top: auto;
}

/*
  O dominio e o corpo ocupam a MESMA linha do cartao, e so um dos dois
  aparece: link mostra de onde e, nota mostra como comeca. Reservar a
  altura das duas faria todo cartao ter um buraco.
*/
.nota-cartao-fonte {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/*
  O CARTAO INTEIRO ABRE. Quem recebe o clique e um <button> que cobre o
  cartao, e nao um ouvinte no <article>: assim o teclado alcanca (Tab e
  Enter) e o leitor de tela anuncia "Abrir «titulo»". Um unico elemento
  focavel por cartao — colocar link no titulo E no dominio faria a
  navegacao por teclado parar duas vezes no mesmo cartao.

  O preco e a selecao de texto dentro do cartao, que o botao intercepta.
  Aqui vale: o conteudo util (a url) e curto e esta no dialogo, de onde
  da para copiar.
*/
.nota-cartao-abrir {
  position: absolute;
  inset: 0;
  z-index: 1;
  padding: 0;
  border: 0;
  border-radius: inherit;
  background-color: transparent;
  cursor: pointer;
}

.nota-cartao-abrir:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/*
  O cartao reage antes do clique -- sem isso nada na tela diz que ele
  abre. Mesma ideia do cartao do quadro: sobe um fio e escurece a borda.
*/
.nota-cartao {
  transition: border-color 120ms ease, box-shadow 120ms ease, transform 120ms ease;
}

.nota-cartao:has(.nota-cartao-abrir:hover),
.nota-cartao:has(.nota-cartao-abrir:focus-visible) {
  border-color: var(--muted-foreground);
  box-shadow: 0 4px 10px -2px rgb(0 0 0 / 0.12);
  transform: translateY(-1px);
}

/*
  Quem pediu menos animacao nao quer o cartao pulando. O reforco de
  borda fica, porque ele nao e enfeite: e o que diz que da para clicar.
*/
@media (prefers-reduced-motion: reduce) {
  .nota-cartao { transition: none; }

  .nota-cartao:has(.nota-cartao-abrir:hover),
  .nota-cartao:has(.nota-cartao-abrir:focus-visible) { transform: none; }
}

/* O recado da requisicao anterior, no topo da pagina (ver Aviso.php). */
.avisos-do-painel {
  margin-bottom: 1.5rem;
}

/*
  Tres colunas que viram uma no estreito -- irma de .grade-dupla, usada
  onde os tres campos so fazem sentido lado a lado (cidade, UF, pais).
*/
.grade-tripla {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: 1fr;
}

/*
  @media, e nao @container: estas grades vivem DENTRO de um dialogo, e o
  container 'main' e a pagina inteira. Medindo o container, a grade
  abriria em tres colunas dentro dos 32rem do dialogo so porque a PAGINA
  atras dele e larga. E a mesma medida que .grade-dupla ja usa, pelo
  mesmo motivo.
*/
@media (min-width: 640px) {
  .grade-tripla { grid-template-columns: 2fr 1fr 1.5fr; }
}

/*
  Irma da .grade-tripla, com as tres colunas IGUAIS. A diferenca nao e
  estetica: ali sao cidade, UF e pais, tres campos de tamanhos muito
  diferentes; aqui sao tres seletores do mesmo peso.
*/
.grade-tres-campos {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 640px) {
  .grade-tres-campos { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/*
  O stepper dentro de um dialogo de cadastro.

  A medida do componente e do kit; o que esta tela acrescenta e o
  ESPACO em volta dele. Um passo a passo colado no primeiro campo faz o
  numero do passo e o rotulo do campo virarem um bloco so, e a pessoa
  perde as duas leituras.
*/
.etapas-cabecalho {
  padding-block: 0.25rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

/* Os campos dentro de um passo respiram como qualquer formulario. */
.etapa-painel {
  padding-block-start: 0.25rem;
}

/* ---------------------------------------------- A carteira em cartoes

  QUATRO POR LINHA no largo, e menos conforme aperta. auto-fill com
  minmax, e nao ponto de quebra: o que decide o numero de colunas e a
  largura minima que o cartao precisa para o nome nao virar tres linhas,
  e essa largura nao muda com a viewport.

  O maximo de quatro e explicito. Sem ele, num monitor largo a grade
  abriria seis e sete colunas, e a carteira viraria um mural de
  retangulos pequenos demais para ler o nome.
*/
.clientes-grade {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}

@container main (min-width: 62rem) {
  .clientes-grade { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.cliente-cartao {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0.875rem;
  border: 1px solid var(--border);
  border-radius: var(--raio-xl);
  background-color: var(--card);
  color: var(--card-foreground);
  transition: border-color 120ms ease, box-shadow 120ms ease, transform 120ms ease;
}

/*
  O cartao inteiro abre, e quem abre e um <a> que o cobre -- link de
  verdade, nao um ouvinte de clique: abre em nova aba com o meio do
  mouse, o teclado alcanca e o leitor de tela anuncia o destino.
*/
.cliente-cartao-abrir {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

.cliente-cartao:has(.cliente-cartao-abrir:hover),
.cliente-cartao:has(.cliente-cartao-abrir:focus-visible) {
  border-color: var(--muted-foreground);
  box-shadow: 0 4px 10px -2px rgb(0 0 0 / 0.12);
  transform: translateY(-1px);
}

.cliente-cartao-abrir:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/*
  SEM QUEBRA DE LINHA AQUI. '.linha' do kit tem flex-wrap: wrap, e com
  nome longo ("Ana Carolina lopes Saraiva Bortoletto") o monograma era
  empurrado para uma linha so dele -- o cartao crescia e a grade perdia
  o alinhamento. O nome encolhe e corta; o monograma nunca sai do lugar.
*/
.cliente-cartao-topo {
  flex-wrap: nowrap;
  align-items: center;
  min-width: 0;
}

.cliente-cartao-identidade {
  flex: 1 1 auto;
  min-width: 0;
}

/*
  A COR VEM DO NOME (cor_do_monograma) e chega por data-ui-cor, nunca
  por atributo style -- a CSP bloqueia estilo inline sem dizer nada.
*/
.cliente-monograma {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--raio-md);
  background-color: color-mix(in oklab, var(--cor, var(--muted-foreground)) 16%, transparent);
  color: var(--cor, var(--muted-foreground));
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/*
  Nome longo corta com reticencias, e o title mostra o inteiro ao parar
  o mouse. Quebrar em duas linhas faria os cartoes da mesma linha terem
  alturas diferentes, e a grade perderia o alinhamento que a faz ser
  varrida rapido.
*/
.cliente-cartao-nome {
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cliente-cartao-situacao {
  font-size: 0.6875rem;
  line-height: 1;
  color: var(--muted-foreground);
}

.cliente-cartao-situacao--ativo { color: var(--tarefa-cor); }
.cliente-cartao-situacao--inadimplente { color: var(--destructive); }

.cliente-cartao-numeros {
  margin-top: auto;
  align-items: flex-end;
  padding-top: 0.625rem;
  border-top: 1px solid var(--border);
}

.cliente-cartao-direita {
  text-align: right;
}

@media (prefers-reduced-motion: reduce) {
  .cliente-cartao { transition: none; }

  .cliente-cartao:has(.cliente-cartao-abrir:hover),
  .cliente-cartao:has(.cliente-cartao-abrir:focus-visible) { transform: none; }
}

/* ------------------------------------------------ O cartao de projeto

  Irmao do cartao de cliente: mesma grade (.clientes-grade), mesmo
  alvo clicavel (.cliente-cartao-abrir), mesmo corte de nome. O que muda
  e a FITA DE COR na esquerda, que diz a situacao antes de qualquer
  leitura.
*/
.projeto-cartao {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 0.875rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--muted-foreground);
  background-color: var(--card);
  color: var(--card-foreground);
  transition: border-color 120ms ease, box-shadow 120ms ease, transform 120ms ease;
}

/*
  Sem raio nos cantos: a borda de 3px so na esquerda com canto
  arredondado deixa um degrau visivel entre a fita e a borda fina. E a
  mesma regra que vale para todo acento de um lado so.
*/
.projeto-cartao:has(.cliente-cartao-abrir:hover),
.projeto-cartao:has(.cliente-cartao-abrir:focus-visible) {
  border-color: var(--muted-foreground);
  border-left-color: currentColor;
  box-shadow: 0 4px 10px -2px rgb(0 0 0 / 0.12);
  transform: translateY(-1px);
}

.projeto-cartao-topo {
  align-items: center;
  flex-wrap: nowrap;
  min-width: 0;
}

.projeto-cartao-situacao {
  align-items: center;
  font-size: 0.6875rem;
  line-height: 1;
  white-space: nowrap;
}

.projeto-cartao-icone {
  width: 0.875rem;
  height: 0.875rem;
  flex: none;
}

.projeto-cartao-cliente {
  display: block;
  margin-bottom: 0.25rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.projeto-cartao-trabalho {
  align-items: center;
  flex-wrap: nowrap;
  min-width: 0;
}

.projeto-cartao-contagem {
  align-items: center;
  color: var(--muted-foreground);
  white-space: nowrap;
}

/* Sobrou coisa aberta: e o que faz achar o projeto sem ler numero. */
.projeto-cartao-contagem--aberta {
  color: var(--destructive);
}

.projeto-cartao-anel {
  align-items: center;
  flex: none;
}

.projeto-anel {
  width: 1.125rem;
  height: 1.125rem;
  flex: none;
}

.projeto-anel-trilho { stroke: var(--border); }
.projeto-anel-cheio { stroke: var(--tarefa-cor); }

/*
  A cor da fita por situacao. Os nomes sao os do vocabulario de
  situacoes.php -- nao ha mapa novo aqui, so a cor de cada um.
*/
.projeto-cartao--andamento { border-left-color: var(--tarefa-cor); }
.projeto-cartao--planejamento { border-left-color: var(--chamado-cor); }
.projeto-cartao--revisao { border-left-color: var(--chamado-cor); }
.projeto-cartao--concluido { border-left-color: var(--muted-foreground); }
.projeto-cartao--parado { border-left-color: var(--destructive); }

.projeto-cartao--andamento .projeto-cartao-situacao { color: var(--tarefa-cor); }
.projeto-cartao--planejamento .projeto-cartao-situacao { color: var(--chamado-cor); }
.projeto-cartao--revisao .projeto-cartao-situacao { color: var(--chamado-cor); }
.projeto-cartao--parado .projeto-cartao-situacao { color: var(--destructive); }
.projeto-cartao--concluido .projeto-cartao-situacao { color: var(--muted-foreground); }

@media (prefers-reduced-motion: reduce) {
  .projeto-cartao { transition: none; }

  .projeto-cartao:has(.cliente-cartao-abrir:hover),
  .projeto-cartao:has(.cliente-cartao-abrir:focus-visible) { transform: none; }
}

/* ------------------------------------------ A tabela de projetos agrupada

  Nem lista nem quadro. A lista compara mas nao separa contrato recorrente
  de entrega em curso; o quadro separa mas empilha 41 cartoes numa coluna
  e perde a comparacao. Agrupar da os dois: cada grupo E uma lista, e uma
  lista com 41 linhas rola normalmente -- o que nao funcionava era uma
  COLUNA com 41.
*/
.grupo-projetos {
  margin-bottom: 1.5rem;
}

/*
  <summary> e um elemento com marcador proprio do navegador (um
  triangulo). list-style: none tira o do Firefox/Chrome e o
  ::-webkit-details-marker tira o do Safari -- sem os dois, aparece uma
  seta que nao e a nossa ao lado da que e.
*/
.grupo-projetos-cabecalho {
  display: flex;
  align-items: center;
  margin-bottom: 0.5rem;
  cursor: pointer;
  list-style: none;
}

.grupo-projetos-cabecalho::-webkit-details-marker {
  display: none;
}

.grupo-projetos-seta {
  width: 0.875rem;
  height: 0.875rem;
  flex: none;
  color: var(--muted-foreground);
  transition: transform 120ms ease;
}

.grupo-projetos[open] .grupo-projetos-seta {
  transform: rotate(90deg);
}

/*
  A composicao do grupo continua visivel com o grupo FECHADO -- e o que
  permite ler "41 recorrentes, quase todos de prioridade media" sem
  abrir. Some no estreito, onde o nome e a contagem ja ocupam a linha.
*/
.grupo-projetos-resumo {
  display: none;
  flex: 0 1 8rem;
  margin-left: auto;
}

@media (min-width: 48rem) {
  .grupo-projetos-resumo { display: block; }
}

.grupo-projetos-resumo .barra-empilhada-trilho {
  height: 0.5rem;
  border: 0;
  border-radius: 3px;
}

/*
  A CELULA INTEIRA E O BOTAO. O gatilho ocupa a celula toda para que o
  alvo de clique seja o retangulo colorido, e nao so o texto dentro
  dele -- uma area de 2rem de altura por toda a largura da coluna, que e
  o que torna a troca rapida de verdade.
*/
.celula-pintada-gatilho {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 2.125rem;
  padding: 0;
  border: 0;
  background-color: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.celula-pintada-gatilho:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: -2px;
}

.celula-pintada .dropdown {
  display: block;
}

.dropdown-ponto {
  display: inline-block;
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 3px;
  background-color: var(--cor, var(--muted-foreground));
}

@media (prefers-reduced-motion: reduce) {
  .grupo-projetos-seta { transition: none; }
}

/*
  O nome do grupo herda a cor do grupo, e a faixa lateral do corpo usa a
  mesma. Duas pistas da mesma cor, e nenhuma delas escrita no CSS: vem
  por data-ui-cor (ver aplicarCores em ui.js).
*/
.grupo-projetos-titulo {
  color: var(--cor, var(--foreground));
  font-size: 0.875rem;
  font-weight: 600;
}

/*
  SEM overflow AQUI, e isso e mais importante do que parece.

  A primeira versao tinha 'overflow-x: auto' para a tabela caber no
  estreito. Duas consequencias, as duas ruins:

  1. Definir UM eixo como auto faz o outro, que era 'visible', virar
     'auto' junto (e regra do CSS, nao bug do navegador). Aparecia uma
     barra de rolagem VERTICAL num bloco que nao precisava dela, do nada.

  2. E um bloco com overflow RECORTA o que sai dele -- o menu de
     prioridade, que e posicionado por cima, seria cortado na borda da
     tabela.

  Quem resolve o estreito e a .tabela-responsiva do kit: abaixo de 768px
  a tabela vira lista, lendo o rotulo de cada campo do data-rotulo que as
  celulas ja carregam. Rolagem horizontal em tabela e hostil no toque --
  o kit ja tinha decidido isso, e eu tinha reinventado por cima.
*/
.grupo-projetos-corpo {
  border: 1px solid var(--border);
  border-left: 4px solid var(--cor, var(--border));
  background-color: var(--card);
}

.tabela-agrupada {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}

.tabela-agrupada th {
  padding: 0.5rem 0.75rem;
  background-color: var(--muted);
  color: var(--muted-foreground);
  font-size: 0.6875rem;
  font-weight: 500;
  text-align: left;
}

.tabela-agrupada td {
  padding: 0;
  border-top: 1px solid var(--border);
}

/* Celula de texto respira; a pintada nao, porque a cor vai ate a borda. */
.tabela-agrupada td:not(.celula-pintada) {
  padding: 0.5rem 0.75rem;
}

.tabela-agrupada tbody tr:hover {
  background-color: var(--muted);
}

/*
  A CELULA INTEIRA PINTADA, e nao um badge dentro dela: e o que faz a
  coluna virar uma barra de cor que se le de relance, sem percorrer
  linha por linha. O texto vai em branco porque a rampa de prioridade e
  escura de proposito -- e o tom mais claro dela (#85b7eb) ainda passa
  em contraste com branco.
*/
.celula-pintada {
  height: 2.125rem;
  background-color: var(--cor, transparent);
  color: var(--primary-foreground);
  text-align: center;
  font-size: 0.75rem;
  font-weight: 500;
}

.celula-pintada:not([data-ui-cor]) {
  color: var(--muted-foreground);
}

.tabela-agrupada tfoot td {
  padding: 0.5rem 0.75rem;
  background-color: var(--muted);
}

/* O rodape do grupo mostra so a barra, sem legenda: ela repetiria o que
   as celulas acima ja dizem. */
.tabela-agrupada tfoot .barra-empilhada-trilho {
  height: 0.5rem;
  border: 0;
  border-radius: 3px;
}

.celula-centro { text-align: center; }

/* ---------------------------------------------------------------------
   TELEFONE NA LISTA
--------------------------------------------------------------------- */

/*
  O numero NAO QUEBRA. Sem isto, "+55 (62) 99851-5115" vira tres linhas
  numa coluna estreita ("+55 (62)" / "99851-" / "5115") e o atalho de
  conversa cai para baixo dele — o que parecia uma celula virou um
  paragrafo.

  Telefone e um dado de largura conhecida e fixa: e mais honesto ele
  empurrar a coluna e o e-mail quebrar, porque e-mail quebrado continua
  legivel e numero quebrado nao.
*/
.telefone-celula {
  align-items: center;
  flex-wrap: nowrap;
  white-space: nowrap;
}

/* O atalho nao encolhe nem some quando a coluna aperta: ele e o unico
   jeito de chegar na conversa a partir daqui. */
.telefone-whatsapp {
  flex-shrink: 0;
}

/* ---------------------------------------------------------------------
   AVATAR COM TINTA
--------------------------------------------------------------------- */

/*
  As cinco tintas do circulo de iniciais (ver avatar_contato()).

  POR QUE CLASSE, E NAO data-ui-cor: aquele atributo so aceita
  hexadecimal, e hexadecimal nao muda entre o tema claro e o escuro — o
  circulo ficaria berrante num dos dois. --chart-1..5 o kit ja vira
  sozinho.

  FUNDO LAVADO E TEXTO NA COR CHEIA, nunca o contrario: o circulo precisa
  marcar a pessoa sem competir com o nome ao lado dele, que e a
  informacao de verdade da celula. Com o fundo na cor cheia, uma coluna
  de 31 contatos vira um vitral e o nome some no meio.

  color-mix contra --card, e nao contra branco: no tema escuro o cartao
  e escuro, e misturar com branco devolveria um circulo claro num fundo
  escuro.
*/
/*
  O TEXTO NAO E A COR CRUA DA ESCALA. --chart-4 e um amarelo de
  luminosidade 0.83; duas iniciais nessa cor sobre um fundo lavado da
  MESMA cor ficam quase invisiveis, e a coluna que existe para ajudar a
  achar alguem viraria a que atrapalha.

  Misturar com --foreground puxa a cor para um tom legivel sem perder a
  identidade: continua sendo "a amarela", so que da para ler. E serve os
  dois temas de graca — no escuro --foreground e claro, e a mistura
  clareia em vez de escurecer.
*/
.avatar-tinta {
  background-color: color-mix(in oklab, var(--tinta) 18%, var(--card));
  color: color-mix(in oklab, var(--tinta) 52%, var(--foreground));
  font-weight: 600;
}

.avatar-tinta-1 { --tinta: var(--chart-1); }
.avatar-tinta-2 { --tinta: var(--chart-2); }
.avatar-tinta-3 { --tinta: var(--chart-3); }
.avatar-tinta-4 { --tinta: var(--chart-4); }
.avatar-tinta-5 { --tinta: var(--chart-5); }

/*
  O circulo fica AO LADO do nome, nunca acima dele.

  .linha quebra por padrao (flex-wrap: wrap), e com nome longo — "Dr.
  José Henrique Torres" — o bloco de texto nao cabia junto com o circulo
  e pulava para a linha de baixo. O resultado era um circulo solto em
  cima e o nome embaixo, como se fossem duas coisas.

  Quem cede espaco e o TEXTO (min-width: 0 em .celula-evento, e a
  reticencia de .celula-titulo), nunca o circulo: duas iniciais espremidas
  nao dizem nada, e meio nome ainda diz.
*/
.contato-identidade {
  flex-wrap: nowrap;
}

/* ---------------------------------------------------------------------
   CELULA QUE ABRE
--------------------------------------------------------------------- */

/*
  A linha da tabela abre o formulario, e quem abre e um <button> que
  cobre a celula — nao um onclick na <tr>, que o teclado nao alcanca e o
  leitor de tela nao anuncia. Mesmo contrato de .nota-cartao-abrir.

  Ele cobre so a PRIMEIRA celula, e nao a linha inteira, porque as
  outras tem conteudo proprio: o nome do cliente e um link para a ficha
  dele, e um botao por cima engoliria esse link.
*/
.celula-com-abrir {
  position: relative;
}

.celula-abrir {
  position: absolute;
  inset: 0;
  z-index: 1;
  padding: 0;
  border: 0;
  border-radius: var(--raio-sm);
  background-color: transparent;
  cursor: pointer;
}

.celula-abrir:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* O titulo reage antes do clique: sem isso nada diz que a celula abre. */
.celula-com-abrir:hover .celula-titulo {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ==========================================================================
   VEREDITO E ESCADA DE PRECO (ficha do cliente)

   Componentes do PRODUTO: recursos/componentes/app/veredito.php e
   escada-de-preco.php. Nada daqui vai para o kit.

   Dois tons de veredito e nenhum terceiro: ambar para "precisa de
   atencao"; nao existe vermelho para "esta quebrado" (decisao do dono).
   Os tons (--cor-ok e --cor-atencao) sao tokens do KIT, em ui/tokens.css:
   os mesmos de .barras-de-estado, com o contraste calculado la (ambar 3.7
   no claro, 10.4 no escuro). Esta folha so le, nunca redefine.
   A cor pinta o filete, o icone e um fundo bem diluido; o TEXTO continua
   em --foreground, porque o ambar do claro nao tem contraste de texto.
   ========================================================================== */

.veredito {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border: 1px solid color-mix(in oklab, var(--cor) 30%, var(--border));
  border-left: 4px solid var(--cor);
  border-radius: var(--raio-lg);
  background-color: color-mix(in oklab, var(--cor) 8%, var(--card));
  color: var(--foreground);
}

.veredito-ok { --cor: var(--cor-ok); }
.veredito-atencao { --cor: var(--cor-atencao); }
/* NAO HA .veredito-erro, e a ausencia e deliberada: ver o cabecalho desta
   secao. Eu criei a regra em 23/10/2026 e a desfiz no mesmo dia, depois de
   ler a decisao que ja estava escrita duas linhas acima. */

.veredito-icone {
  display: inline-flex;
  flex-shrink: 0;
  margin-top: 0.125rem;
  color: var(--cor);
}

.veredito-icone > svg {
  width: 1.25rem;
  height: 1.25rem;
}

.veredito-corpo {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

/* A frase e o veredito: e a primeira coisa que se le, no tamanho de um subtitulo. */
.veredito-frase {
  margin: 0;
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 500;
  text-wrap: pretty;
}

.veredito-regra {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
}

/* --------------------------------------------------------------- escada */

.escada-de-preco {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
}

.escada-cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.escada-plano {
  margin: 0;
  min-width: 0;
  overflow: hidden;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Tres degraus lado a lado: hoje, indice, piso. */
.escada-degraus {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.5rem;
  align-items: stretch;
}

.escada-degrau {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 0.25rem;
  min-width: 0;
}

/* O trilho reserva a altura do degrau mais alto e alinha todas as barras pela base. */
.escada-trilho {
  display: flex;
  align-items: flex-end;
  height: 5rem;
  border-bottom: 1px solid var(--border);
}

/* A barra e a .grafico-barra do kit (altura por data-altura); aqui so a cor. */
.escada-barra {
  background-color: color-mix(in oklab, var(--muted-foreground) 45%, transparent);
}

/* O degrau que decidiu o devido ganha a cor da marca. */
.escada-degrau[data-vencedor] .escada-barra {
  background-color: var(--primary);
}

.escada-rotulo {
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
}

.escada-valor {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.escada-nota {
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
  text-wrap: pretty;
}

.escada-devido,
.escada-hoje {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.5rem;
  margin: 0;
}

.escada-devido .escada-valor {
  font-size: 1rem;
  line-height: 1.5rem;
}

/* A perda e a conta do dono: ambar, o mesmo tom do veredito de atencao. */
.escada-perda {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  color: var(--foreground);
}

.escada-perda::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: 0.5rem;
  border-radius: 9999px;
  background-color: var(--cor-atencao);
}

.escada-perda-zero {
  font-weight: 400;
  color: var(--muted-foreground);
}

.escada-perda-zero::before {
  background-color: var(--cor-ok);
}

/* A regra ao lado do numero: de onde veio a data-base, em letra miuda mas legivel. */
.escada-fonte {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--muted-foreground);
  text-wrap: pretty;
}

.escada-sem-base,
.escada-sem-referencia,
.escada-piso-sem-base {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.25rem;
  text-wrap: pretty;
}

.escada-sem-base,
.escada-sem-referencia {
  color: var(--muted-foreground);
}

.escada-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Degrau sem valor (sem indice, ou piso que nao se aplica): o chao fica tracejado, nao some. */
.escada-degrau-vazio .escada-trilho {
  border-bottom-style: dashed;
}

/* ==========================================================================
   FICHA DO CLIENTE (veredito, tres cartoes, blocos)

   Layout e pecas pequenas de recursos/paginas/painel/clientes/ficha.php e de
   recursos/componentes/app/ficha-do-cliente.php. Nada daqui vai para o kit.

   Medidas em rem e cores por token: nenhum valor de cor e escrito aqui, so
   lido (--cor-ok e --cor-atencao moram em ui/tokens.css, e ha teste que
   varre copias).
   ========================================================================== */

.perfil-cabecalho {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem 1rem;
}

.perfil-cabecalho > .dropdown {
  flex: none;
  width: auto;
}

.perfil-identidade {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-width: 0;
}

.perfil-nome {
  min-width: 0;
}

.perfil-titulo {
  flex-wrap: wrap;
}

/* Os numeros de contratos, oportunidades e faturas: cada um e um link para a lista filtrada. */
.perfil-atalhos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.perfil-atalho {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.625rem;
  border: 1px solid var(--border);
  border-radius: 9999px;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--foreground);
}

a.perfil-atalho:hover {
  background-color: var(--accent);
}

.perfil-atalho-alerta {
  border-color: color-mix(in oklab, var(--cor-atencao) 45%, var(--border));
}

/*
  Os tres cartoes lado a lado. O de preco e o mais largo: a escada tem tres
  degraus com valor em dinheiro, e espremida em um terco de tela quebraria o
  numero no meio. Mede o container, nao a janela (mesmo motivo de .grade-tres).
*/
.perfil-cartoes {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
}

@container main (min-width: 64rem) {
  .perfil-cartoes {
    grid-template-columns: minmax(0, 5fr) minmax(0, 4fr) minmax(0, 3fr);
  }
}

/* O embrulho existe para carregar data-cartao / data-bloco; o card dentro enche a altura da linha. */
.perfil-cartao,
.perfil-bloco {
  display: flex;
  align-items: stretch;
  min-width: 0;
}

.perfil-cartao > .card,
.perfil-bloco > .card {
  flex: 1;
  min-width: 0;
}

.perfil-resumo {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.25rem;
  text-wrap: pretty;
}

.perfil-linhas {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.perfil-linha {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
}

.perfil-linha-rotulo {
  color: var(--muted-foreground);
}

.perfil-linha-valor {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.perfil-ligacao {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.perfil-ligacao:hover {
  color: var(--primary);
}

.perfil-contatos,
.perfil-lista {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.perfil-contato {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.perfil-contato-dados {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.perfil-contato-meios {
  display: flex;
  flex-wrap: wrap;
  gap: 0.125rem 0.75rem;
  overflow-wrap: anywhere;
}

.perfil-lista-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  min-width: 0;
}

.perfil-alvo {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* O que ainda nao existe e TEXTO: sem borda, sem fundo, sem cara de botao. */
.perfil-sem-destino {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: var(--muted-foreground);
}

.perfil-sem-destino-rotulo {
  font-weight: 500;
}

/*
  As faixas do uptime. Pintam a tira de barras do kit (.barras-de-estado),
  escopadas nela de proposito: data-estado tem tres sentidos neste projeto
  (etapas.php, ui.js, app.js), e uma regra solta em [data-estado="..."]
  vazaria para os outros. As cores sao as mesmas dos estados do kit, lidas
  dos tokens. "Baixo" e "fora do ar" NAO podem ser a mesma cor: a legenda
  promete quatro faixas, e duas bolinhas identicas seriam uma promessa
  falsa. "Baixo" e um laranja que sai da mistura dos dois tokens de alerta
  (nenhum valor copiado); "fora" e o vermelho puro.
*/
.barras-de-estado [data-estado="uptime-alto"] { --cor: var(--cor-ok); }
.barras-de-estado [data-estado="uptime-medio"] { --cor: var(--cor-atencao); }
.barras-de-estado [data-estado="uptime-baixo"] { --cor: color-mix(in oklab, var(--destructive) 55%, var(--cor-atencao)); }
.barras-de-estado [data-estado="uptime-fora"] { --cor: var(--destructive); }

.perfil-atalhos-nota {
  align-self: center;
}

/* ==========================================================================
   OPORTUNIDADES — o funil comercial
   ========================================================================== */

/*
  O QUADRO DE OPORTUNIDADES CABE NA TELA, e e o unico do produto que cabe.

  O kit faz a coluna ter 16rem com flex-shrink 0, e isso esta certo para
  Tarefas e Chamados: la a coluna e uma FILA DE TRABALHO, e rolar de lado
  para ver mais e barato. Aqui a coluna e uma FASE DO FUNIL -- com
  "Negociacao" fora da tela some a leitura de funil, que e a unica razao
  de a tela existir. O v1 ja resolvia assim, e o dono pediu o mesmo.

  Vai por `atributos` em quadro_inicio(), que e o ponto de extensao do
  proprio kit, e nao por mudanca no kit: as outras telas continuam
  rolando de lado, de proposito.
*/
.quadro-oportunidades > .quadro-coluna {
  flex: 1 1 0;
  width: auto;

  /*
    CABER NA TELA TEM UM PISO. Com as sete colunas dividindo a largura, a
    coluna chegava a ~150px: titulo cortado no meio da palavra e o selo de
    "sem contato" estourando a borda do cartao -- exatamente o que se ve na
    tela do v1. Abaixo de 12rem o quadro volta a rolar de lado, que e o
    comportamento do kit: perder uma fase para a direita e menos ruim que
    sete colunas ilegiveis.
  */
  min-width: 12rem;
}

/*
  Em tela estreita nao da para caber: cinco colunas de 1/5 viram tiras
  ilegiveis. Abaixo do tablet o quadro volta a rolar de lado, que e o
  comportamento do kit.
*/
@media (max-width: 64rem) {
  .quadro-oportunidades > .quadro-coluna {
    flex: 0 0 auto;
    width: var(--sidebar-largura);
  }
}

/*
  O TITULO DO CARTAO NAO PODE EMPURRAR A COLUNA. Com a coluna estreita,
  "Tati Zucareli | Fisioterapeuta Respiratorio e Geriatria Itajuba" virava
  tres linhas e desalinhava o quadro inteiro -- e exatamente o que se ve na
  tela do v1. Duas linhas e o corte, e o resto o popover mostra.
*/
.oportunidade-titulo {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/*
  A LINHA DO CLIENTE E UMA LINHA SO. "Tati Zucareli | Fisioterapeuta
  Respiratoria e Geriatria Itajuba . pessoal da Tati" quebrava em quatro e
  fazia o cartao ficar o dobro dos vizinhos -- com as colunas dividindo a
  largura, um cartao alto desalinha a leitura do funil inteiro. O nome
  completo esta no popover.
*/
.oportunidade-cliente {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A linha de rodape do cartao: valor a esquerda, sinal de contato a direita. */
.oportunidade-rodape {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

/*
  O FUNDO BORRADO DO POPOVER, so neste dialogo.

  O ::backdrop do kit e o `bg-black/50` do shadcn, e assim fica: mexer no
  kit mudaria TODO dialogo do produto e sairia da referencia. Aqui o
  desfoque tem funcao -- o popover abre por cima do quadro, e sem ele o
  olho continua lendo as colunas atras do cartao aberto.
*/
#oportunidade-detalhe-dialogo::backdrop {
  backdrop-filter: blur(3px);
}

/* O cartao inteiro abre o popover, entao precisa parecer clicavel. */
.quadro-cartao[data-app-detalhe] {
  cursor: pointer;
}

.quadro-cartao[data-app-detalhe]:hover {
  border-color: var(--ring);
}

/* ==========================================================================
   LEMBRETE — o aviso de compromisso
   ========================================================================== */

/*
  O sino do modal. Circulo com o ambar de "precisa de atencao": aqui ele
  pinta um ICONE, que e o uso que o tokens.css autoriza -- "serve a
  filete, icone e barra, nunca a letra".
*/
.lembrete-sino {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  color: var(--cor-atencao);
  background: color-mix(in oklab, var(--cor-atencao) 14%, transparent);
}

/*
  O modal do lembrete interrompe: ele aparece sozinho, sem ninguem ter
  clicado. O desfoque separa o aviso do que estava sendo lido, que e o
  mesmo motivo do popover de oportunidade.
*/
#lembrete-dialogo::backdrop {
  backdrop-filter: blur(3px);
}

/* ==========================================================================
   PONTO — o relógio do dia, no cabeçalho
   ========================================================================== */

/*
  Vizinho do indicador do cronômetro, e parecido de propósito: os dois
  são "uma coisa está contando agora". O que os distingue é o rótulo —
  um conta um cartão, o outro conta o dia.
*/
.ponto {
  display: flex;
  align-items: center;
  gap: 0.5rem; /* g-2 */
}

.ponto-tempo {
  font-size: 0.875rem; /* texto-sm */
  font-variant-numeric: tabular-nums;
  color: var(--muted-foreground);
}

/*
  Rodando, o número ganha a cor do texto normal e um ponto pulsando ao
  lado. Parado, fica apagado como legenda: o contraste entre os dois
  estados é o que se lê de relance, sem precisar ler o botão.
*/
.ponto[data-app-ponto-andando] .ponto-tempo {
  color: var(--foreground);
  font-weight: 500;
}

.ponto[data-app-ponto-andando] .ponto-tempo::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-inline-end: 0.375rem;
  border-radius: 999px;
  background: var(--cor-ok);
  animation: ponto-pulsa 2s ease-in-out infinite;
}

@keyframes ponto-pulsa {
  50% { opacity: 0.35; }
}

/* Quem pede para o sistema não animar, não recebe animação. */
@media (prefers-reduced-motion: reduce) {
  .ponto[data-app-ponto-andando] .ponto-tempo::before {
    animation: none;
  }
}

/* Em tela estreita o cabeçalho já está cheio: fica só o número. */
@media (max-width: 48rem) {
  .ponto [data-app-ponto-acao="encerrar"] {
    display: none;
  }
}

/*
  O recado do ponto. Discreto no sucesso ("Ponto registrado."), e com a
  cor destrutiva no erro — que é quando ele mais precisa ser visto, e
  era justamente o caso em que ninguém via nada.
*/
.ponto-recado {
  font-size: 0.8125rem;
  color: var(--muted-foreground);
}

.ponto-recado[data-erro] {
  color: var(--destructive);
}

/* Vazio não ocupa espaço nem deixa buraco no cabeçalho. */
.ponto-recado:empty {
  display: none;
}
